1#![cfg_attr(feature = "nightly", feature(nonzero))]
15#![allow(
16 clippy::float_cmp,
17 clippy::too_many_arguments,
18 clippy::unreadable_literal,
19 clippy::new_without_default,
20 clippy::empty_docs,
21 clippy::manual_range_contains,
22 unknown_lints,
23 mismatched_lifetime_syntaxes,
24)]
25
26
27pub extern crate crossbeam_channel;
28pub extern crate euclid;
29
30extern crate app_units;
31#[macro_use]
32extern crate bitflags;
33extern crate byteorder;
34#[cfg(feature = "nightly")]
35extern crate core;
36#[macro_use]
37extern crate malloc_size_of_derive;
38extern crate serde;
39#[macro_use]
40extern crate serde_derive;
41
42extern crate malloc_size_of;
43extern crate peek_poke;
44
45pub mod channel;
46mod color;
47#[cfg(feature = "debugger")]
48pub mod debugger;
49mod display_item;
50mod display_item_cache;
51mod display_list;
52mod font;
53mod gradient_builder;
54mod image;
55mod tile_pool;
56pub mod units;
57
58pub use crate::color::*;
59pub use crate::display_item::*;
60pub use crate::display_item_cache::DisplayItemCache;
61pub use crate::display_list::*;
62pub use crate::font::*;
63pub use crate::gradient_builder::*;
64pub use crate::image::*;
65pub use crate::tile_pool::*;
66
67use crate::units::*;
68use crate::channel::Receiver;
69use std::marker::PhantomData;
70use std::sync::Arc;
71use std::os::raw::c_void;
72use peek_poke::PeekPoke;
73
74pub const MAX_RENDER_TASK_SIZE: i32 = 16384;
76
77pub type TileSize = u16;
79
80#[derive(Copy, Clone, Deserialize, Serialize)]
83pub struct QualitySettings {
84 pub force_subpixel_aa_where_possible: bool,
89}
90
91impl Default for QualitySettings {
92 fn default() -> Self {
93 QualitySettings {
94 force_subpixel_aa_where_possible: false,
97 }
98 }
99}
100
101#[repr(C)]
106#[derive(Clone, Copy, Debug, Deserialize, Eq, Hash, MallocSizeOf, Ord, PartialEq, PartialOrd, Serialize)]
107pub struct Epoch(pub u32);
108
109impl Epoch {
110 pub fn invalid() -> Epoch {
112 Epoch(u32::MAX)
113 }
114}
115
116#[repr(C)]
120#[derive(Clone, Copy, Debug, Default, Eq, MallocSizeOf, PartialEq, Hash, Ord, PartialOrd, PeekPoke)]
121#[derive(Deserialize, Serialize)]
122pub struct IdNamespace(pub u32);
123
124impl IdNamespace {
125 pub const DEBUGGER: IdNamespace = IdNamespace(!0);
126}
127
128#[repr(C)]
134#[derive(Clone, Copy, Debug, Deserialize, Eq, Hash, MallocSizeOf, PartialEq, Serialize, PeekPoke)]
135pub struct DocumentId {
136 pub namespace_id: IdNamespace,
138 pub id: u32,
140}
141
142impl DocumentId {
143 pub fn new(namespace_id: IdNamespace, id: u32) -> Self {
145 DocumentId {
146 namespace_id,
147 id,
148 }
149 }
150
151 pub const INVALID: DocumentId = DocumentId { namespace_id: IdNamespace(0), id: 0 };
153}
154
155pub type PipelineSourceId = u32;
160
161#[repr(C)]
164#[derive(Clone, Copy, Debug, Deserialize, Eq, Hash, MallocSizeOf, PartialEq, Serialize, PeekPoke)]
165pub struct PipelineId(pub PipelineSourceId, pub u32);
166
167impl Default for PipelineId {
168 fn default() -> Self {
169 PipelineId::dummy()
170 }
171}
172
173impl PipelineId {
174 pub fn dummy() -> Self {
176 PipelineId(!0, !0)
177 }
178
179 pub const INVALID: Self = PipelineId(!0, !0);
180}
181
182#[repr(C)]
183#[derive(Clone, Copy, Debug, PartialEq, PartialOrd)]
184pub struct FramePublishId(pub u64);
185
186impl FramePublishId {
187 pub fn first() -> Self {
193 FramePublishId(0)
194 }
195
196 pub fn advance(&mut self) {
198 self.0 += 1;
199 }
200
201 pub const INVALID: Self = FramePublishId(0);
204}
205
206impl Default for FramePublishId {
207 fn default() -> Self {
208 FramePublishId::INVALID
209 }
210}
211
212#[repr(C)]
214#[derive(Clone)]
215pub struct ExternalEvent {
216 raw: usize,
217}
218
219unsafe impl Send for ExternalEvent {}
220
221impl ExternalEvent {
222 pub fn from_raw(raw: usize) -> Self {
224 ExternalEvent { raw }
225 }
226 pub fn unwrap(self) -> usize {
228 self.raw
229 }
230}
231
232pub type APZScrollGeneration = u64;
233#[repr(C)]
234#[derive(Clone, Copy, Debug, Deserialize, PartialEq, Serialize, Default)]
235pub struct SampledScrollOffset {
236 pub offset: LayoutVector2D,
237 pub generation: APZScrollGeneration,
238}
239
240#[repr(u8)]
245#[derive(Clone, Copy, Debug, Default, Deserialize, PartialEq, Serialize, PeekPoke)]
246pub enum HasScrollLinkedEffect {
247 Yes,
248 #[default]
249 No,
250}
251
252#[repr(C)]
253pub struct MinimapData {
254 pub is_root_content: bool,
255 pub visual_viewport: LayoutRect,
257 pub layout_viewport: LayoutRect,
258 pub scrollable_rect: LayoutRect,
259 pub displayport: LayoutRect,
260 pub zoom_transform: LayoutTransform,
262 pub root_content_pipeline_id: PipelineId,
266 pub root_content_scroll_id: u64
267}
268
269#[repr(C)]
270pub struct FrameReadyParams {
271 pub present: bool,
272 pub render: bool,
273 pub scrolled: bool,
274 pub tracked: bool,
278}
279
280pub trait RenderNotifier: Send {
282 fn clone(&self) -> Box<dyn RenderNotifier>;
284 fn wake_up(
287 &self,
288 composite_needed: bool,
289 );
290 fn new_frame_ready(&self, _: DocumentId, publish_id: FramePublishId, params: &FrameReadyParams);
292 fn external_event(&self, _evt: ExternalEvent) {
296 unimplemented!()
297 }
298 fn shut_down(&self) {}
301}
302
303#[repr(u32)]
305#[derive(Copy, Clone, Debug, PartialEq, Eq)]
306pub enum Checkpoint {
307 SceneBuilt,
309 FrameBuilt,
311 FrameTexturesUpdated,
313 FrameRendered,
315 TransactionDropped,
318}
319
320pub trait NotificationHandler : Send + Sync {
323 fn notify(&self, when: Checkpoint);
325}
326
327pub struct NotificationRequest {
333 handler: Option<Box<dyn NotificationHandler>>,
334 when: Checkpoint,
335}
336
337impl NotificationRequest {
338 pub fn new(when: Checkpoint, handler: Box<dyn NotificationHandler>) -> Self {
340 NotificationRequest {
341 handler: Some(handler),
342 when,
343 }
344 }
345
346 pub fn when(&self) -> Checkpoint { self.when }
348
349 pub fn notify(mut self) {
351 if let Some(handler) = self.handler.take() {
352 handler.notify(self.when);
353 }
354 }
355}
356
357pub trait ApiHitTester: Send + Sync {
360 fn hit_test(&self, point: WorldPoint) -> HitTestResult;
364}
365
366pub struct HitTesterRequest {
370 #[doc(hidden)]
371 pub rx: Receiver<Arc<dyn ApiHitTester>>,
372}
373
374impl HitTesterRequest {
375 pub fn resolve(self) -> Arc<dyn ApiHitTester> {
377 self.rx.recv().unwrap()
378 }
379}
380
381#[derive(Clone, Debug, Deserialize, PartialEq, Serialize)]
383pub struct HitTestResultItem {
384 pub pipeline: PipelineId,
386
387 pub tag: ItemTag,
389
390 pub animation_id: u64,
392}
393
394#[derive(Clone, Debug, Default, Deserialize, Serialize)]
396pub struct HitTestResult {
397 pub items: Vec<HitTestResultItem>,
399}
400
401impl Drop for NotificationRequest {
402 fn drop(&mut self) {
403 if let Some(ref mut handler) = self.handler {
404 handler.notify(Checkpoint::TransactionDropped);
405 }
406 }
407}
408
409impl Clone for NotificationRequest {
416 fn clone(&self) -> Self {
417 NotificationRequest {
418 when: self.when,
419 handler: None,
420 }
421 }
422}
423
424
425#[repr(C)]
427#[derive(Clone, Copy, Debug, Default, Deserialize, MallocSizeOf, PartialEq, Serialize, Eq, Hash, PeekPoke)]
428pub struct PropertyBindingId {
429 pub namespace: IdNamespace,
430 pub uid: u32,
431}
432
433impl PropertyBindingId {
434 pub fn new(value: u64) -> Self {
436 PropertyBindingId {
437 namespace: IdNamespace((value >> 32) as u32),
438 uid: value as u32,
439 }
440 }
441
442 pub fn to_u64(&self) -> u64 {
444 ((self.namespace.0 as u64) << 32) | self.uid as u64
445 }
446}
447
448#[repr(C)]
451#[derive(Clone, Copy, Debug, Default, Deserialize, Eq, Hash, MallocSizeOf, PartialEq, Serialize, PeekPoke)]
452pub struct PropertyBindingKey<T> {
453 pub id: PropertyBindingId,
455 #[doc(hidden)]
456 pub _phantom: PhantomData<T>,
457}
458
459impl<T: Copy> PropertyBindingKey<T> {
461 pub fn with(self, value: T) -> PropertyValue<T> {
463 PropertyValue { key: self, value }
464 }
465}
466
467impl<T> Into<u64> for PropertyBindingKey<T> {
468 fn into(self) -> u64 {
469 self.id.to_u64()
470 }
471}
472
473impl<T> PropertyBindingKey<T> {
474 pub fn new(value: u64) -> Self {
476 PropertyBindingKey {
477 id: PropertyBindingId::new(value),
478 _phantom: PhantomData,
479 }
480 }
481}
482
483#[repr(C)]
490#[derive(Clone, Copy, Debug, Deserialize, Eq, Hash, MallocSizeOf, PartialEq, Serialize, PeekPoke)]
491pub enum PropertyBinding<T> {
492 Value(T),
494 Binding(PropertyBindingKey<T>, T),
496}
497
498impl<T: Default> Default for PropertyBinding<T> {
499 fn default() -> Self {
500 PropertyBinding::Value(Default::default())
501 }
502}
503
504impl<T> From<T> for PropertyBinding<T> {
505 fn from(value: T) -> PropertyBinding<T> {
506 PropertyBinding::Value(value)
507 }
508}
509
510impl From<PropertyBindingKey<ColorF>> for PropertyBindingKey<ColorU> {
511 fn from(key: PropertyBindingKey<ColorF>) -> PropertyBindingKey<ColorU> {
512 PropertyBindingKey {
513 id: key.id,
514 _phantom: PhantomData,
515 }
516 }
517}
518
519impl From<PropertyBindingKey<ColorU>> for PropertyBindingKey<ColorF> {
520 fn from(key: PropertyBindingKey<ColorU>) -> PropertyBindingKey<ColorF> {
521 PropertyBindingKey {
522 id: key.id,
523 _phantom: PhantomData,
524 }
525 }
526}
527
528impl From<PropertyBinding<ColorF>> for PropertyBinding<ColorU> {
529 fn from(value: PropertyBinding<ColorF>) -> PropertyBinding<ColorU> {
530 match value {
531 PropertyBinding::Value(value) => PropertyBinding::Value(value.into()),
532 PropertyBinding::Binding(k, v) => {
533 PropertyBinding::Binding(k.into(), v.into())
534 }
535 }
536 }
537}
538
539impl From<PropertyBinding<ColorU>> for PropertyBinding<ColorF> {
540 fn from(value: PropertyBinding<ColorU>) -> PropertyBinding<ColorF> {
541 match value {
542 PropertyBinding::Value(value) => PropertyBinding::Value(value.into()),
543 PropertyBinding::Binding(k, v) => {
544 PropertyBinding::Binding(k.into(), v.into())
545 }
546 }
547 }
548}
549
550#[derive(Clone, Copy, Debug, Deserialize, Serialize, PartialEq)]
553pub struct PropertyValue<T> {
554 pub key: PropertyBindingKey<T>,
556 pub value: T,
558}
559
560#[derive(Clone, Deserialize, Serialize, Debug, PartialEq, Default)]
564pub struct DynamicProperties {
565 pub transforms: Vec<PropertyValue<LayoutTransform>>,
567 pub floats: Vec<PropertyValue<f32>>,
569 pub colors: Vec<PropertyValue<ColorF>>,
571}
572
573impl DynamicProperties {
574 pub fn extend(&mut self, other: Self) {
576 self.transforms.extend(other.transforms);
577 self.floats.extend(other.floats);
578 self.colors.extend(other.colors);
579 }
580}
581
582pub type VoidPtrToSizeFn = unsafe extern "C" fn(ptr: *const c_void) -> usize;
587
588#[derive(Copy, Clone, Debug, PartialEq)]
596pub enum Parameter {
597 Bool(BoolParameter, bool),
598 Int(IntParameter, i32),
599 Float(FloatParameter, f32),
600}
601
602#[derive(Copy, Clone, Debug, PartialEq, Eq)]
604#[repr(u32)]
605pub enum BoolParameter {
606 PboUploads = 0,
607 Multithreading = 1,
608 BatchedUploads = 2,
609 DrawCallsForTextureCopy = 3,
610}
611
612#[derive(Copy, Clone, Debug, PartialEq, Eq)]
614#[repr(u32)]
615pub enum IntParameter {
616 BatchedUploadThreshold = 0,
617}
618
619#[derive(Copy, Clone, Debug, PartialEq, Eq)]
621#[repr(u32)]
622pub enum FloatParameter {
623 SlowCpuFrameThreshold = 0,
625}
626
627#[repr(C)]
629#[derive(Copy, PartialEq, Eq, Clone, PartialOrd, Ord, Hash, Default, Deserialize, MallocSizeOf, Serialize)]
630pub struct RenderReasons(u32);
631
632bitflags! {
633 impl RenderReasons: u32 {
634 const NONE = 0;
636 const SCENE = 1 << 0;
637 const ANIMATED_PROPERTY = 1 << 1;
638 const RESOURCE_UPDATE = 1 << 2;
639 const ASYNC_IMAGE = 1 << 3;
640 const CLEAR_RESOURCES = 1 << 4;
641 const APZ = 1 << 5;
642 const RESIZE = 1 << 6;
644 const WIDGET = 1 << 7;
646 const TEXTURE_CACHE_FLUSH = 1 << 8;
648 const SNAPSHOT = 1 << 9;
649 const POST_RESOURCE_UPDATES_HOOK = 1 << 10;
650 const CONFIG_CHANGE = 1 << 11;
651 const CONTENT_SYNC = 1 << 12;
652 const FLUSH = 1 << 13;
653 const TESTING = 1 << 14;
654 const OTHER = 1 << 15;
655 const VSYNC = 1 << 16;
659 const SKIPPED_COMPOSITE = 1 << 17;
660 const START_OBSERVING_VSYNC = 1 << 18;
663 const ASYNC_IMAGE_COMPOSITE_UNTIL = 1 << 19;
664 }
665}
666
667impl core::fmt::Debug for RenderReasons {
668 fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
669 if self.is_empty() {
670 write!(f, "{:#x}", Self::empty().bits())
671 } else {
672 bitflags::parser::to_writer(self, f)
673 }
674 }
675}
676
677impl RenderReasons {
678 pub const NUM_BITS: u32 = 17;
679}
680
681#[repr(C)]
683#[derive(Copy, PartialEq, Eq, Clone, PartialOrd, Ord, Hash, Default, Deserialize, MallocSizeOf, Serialize)]
684pub struct DebugFlags(u64);
685
686bitflags! {
687 impl DebugFlags: u64 {
688 const PROFILER_DBG = 1 << 0;
690 const RENDER_TARGET_DBG = 1 << 1;
692 const TEXTURE_CACHE_DBG = 1 << 2;
694 const GPU_TIME_QUERIES = 1 << 3;
696 const GPU_SAMPLE_QUERIES = 1 << 4;
700 const DISABLE_BATCHING = 1 << 5;
705 const EPOCHS = 1 << 6;
707 const ECHO_DRIVER_MESSAGES = 1 << 7;
709 const SHOW_OVERDRAW = 1 << 8;
711 const GPU_CACHE_DBG = 1 << 9;
713 const TEXTURE_CACHE_DBG_CLEAR_EVICTED = 1 << 10;
715 const PICTURE_CACHING_DBG = 1 << 11;
717 const ZOOM_DBG = 1 << 13;
719 const SMALL_SCREEN = 1 << 14;
723 const DISABLE_OPAQUE_PASS = 1 << 15;
726 const DISABLE_ALPHA_PASS = 1 << 16;
728 const DISABLE_CLIP_MASKS = 1 << 17;
730 const DISABLE_TEXT_PRIMS = 1 << 18;
732 const DISABLE_GRADIENT_PRIMS = 1 << 19;
734 const OBSCURE_IMAGES = 1 << 20;
736 const GLYPH_FLASHING = 1 << 21;
739 const SMART_PROFILER = 1 << 22;
741 const INVALIDATION_DBG = 1 << 23;
743 const PROFILER_CAPTURE = 1 << 25;
745 const FORCE_PICTURE_INVALIDATION = 1 << 26;
747 const WINDOW_VISIBILITY_DBG = 1 << 27;
749 const RESTRICT_BLOB_SIZE = 1 << 28;
752 const SURFACE_PROMOTION_LOGGING = 1 << 29;
754 const PICTURE_BORDERS = 1 << 30;
756 const MISSING_SNAPSHOT_PANIC = (1 as u64) << 31; const MISSING_SNAPSHOT_PINK = (1 as u64) << 32;
760 const HIGHLIGHT_BACKDROP_FILTERS = (1 as u64) << 33;
762 const EXTERNAL_COMPOSITE_BORDERS = (1 as u64) << 34;
765 }
766}
767
768impl core::fmt::Debug for DebugFlags {
769 fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
770 if self.is_empty() {
771 write!(f, "{:#x}", Self::empty().bits())
772 } else {
773 bitflags::parser::to_writer(self, f)
774 }
775 }
776}
777
778#[derive(Debug, Clone, Eq, MallocSizeOf, PartialEq, Hash, Serialize, Deserialize)]
781pub enum PrimitiveKeyKind {
782 Clear,
784 Rectangle {
786 color: PropertyBinding<ColorU>,
788 },
789}
790
791#[derive(Clone, Copy, Debug)]
793pub enum ScrollLocation {
794 Delta(LayoutVector2D),
796 Start,
798 End,
800}
801
802#[repr(C)]
804#[derive(Clone, Copy)]
805pub enum CrashAnnotation {
806 CompileShader = 0,
807 DrawShader = 1,
808}
809
810pub trait CrashAnnotator : Send {
812 fn set(&self, annotation: CrashAnnotation, value: &std::ffi::CStr);
813 fn clear(&self, annotation: CrashAnnotation);
814 fn box_clone(&self) -> Box<dyn CrashAnnotator>;
815}
816
817impl Clone for Box<dyn CrashAnnotator> {
818 fn clone(&self) -> Box<dyn CrashAnnotator> {
819 self.box_clone()
820 }
821}
822
823pub struct CrashAnnotatorGuard<'a> {
825 annotator: &'a Option<Box<dyn CrashAnnotator>>,
826 annotation: CrashAnnotation,
827}
828
829impl<'a> CrashAnnotatorGuard<'a> {
830 pub fn new(
831 annotator: &'a Option<Box<dyn CrashAnnotator>>,
832 annotation: CrashAnnotation,
833 value: &std::ffi::CStr,
834 ) -> Self {
835 if let Some(ref annotator) = annotator {
836 annotator.set(annotation, value);
837 }
838 Self {
839 annotator,
840 annotation,
841 }
842 }
843}
844
845impl<'a> Drop for CrashAnnotatorGuard<'a> {
846 fn drop(&mut self) {
847 if let Some(ref annotator) = self.annotator {
848 annotator.clear(self.annotation);
849 }
850 }
851}
852
853#[derive(Copy, Clone, Debug, Eq, PartialEq)]
855#[cfg_attr(feature = "serialize", derive(Serialize))]
856#[cfg_attr(feature = "deserialize", derive(Deserialize))]
857pub enum TextureCacheCategory {
858 Atlas,
859 Standalone,
860 PictureTile,
861 RenderTarget,
862}