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_list;
51mod font;
52mod gradient_builder;
53mod image;
54mod tile_pool;
55pub mod units;
56
57pub use crate::color::*;
58pub use crate::display_item::*;
59pub use crate::display_list::*;
60pub use crate::font::*;
61pub use crate::gradient_builder::*;
62pub use crate::image::*;
63pub use crate::tile_pool::*;
64
65use crate::units::*;
66use crate::channel::Receiver;
67use std::marker::PhantomData;
68use std::sync::Arc;
69use std::os::raw::c_void;
70use peek_poke::PeekPoke;
71
72pub const MAX_RENDER_TASK_SIZE: i32 = 16384;
74
75pub type TileSize = u16;
77
78#[derive(Copy, Clone, Deserialize, Serialize)]
81pub struct QualitySettings {
82 pub force_subpixel_aa_where_possible: bool,
87}
88
89impl Default for QualitySettings {
90 fn default() -> Self {
91 QualitySettings {
92 force_subpixel_aa_where_possible: false,
95 }
96 }
97}
98
99#[repr(C)]
104#[derive(Clone, Copy, Debug, Deserialize, Eq, Hash, MallocSizeOf, Ord, PartialEq, PartialOrd, Serialize)]
105pub struct Epoch(pub u32);
106
107impl Epoch {
108 pub fn invalid() -> Epoch {
110 Epoch(u32::MAX)
111 }
112}
113
114#[repr(C)]
118#[derive(Clone, Copy, Debug, Default, Eq, MallocSizeOf, PartialEq, Hash, Ord, PartialOrd, PeekPoke)]
119#[derive(Deserialize, Serialize)]
120pub struct IdNamespace(pub u32);
121
122impl IdNamespace {
123 pub const DEBUGGER: IdNamespace = IdNamespace(!0);
124}
125
126#[repr(C)]
132#[derive(Clone, Copy, Debug, Deserialize, Eq, Hash, MallocSizeOf, PartialEq, Serialize, PeekPoke)]
133pub struct DocumentId {
134 pub namespace_id: IdNamespace,
136 pub id: u32,
138}
139
140impl DocumentId {
141 pub fn new(namespace_id: IdNamespace, id: u32) -> Self {
143 DocumentId {
144 namespace_id,
145 id,
146 }
147 }
148
149 pub const INVALID: DocumentId = DocumentId { namespace_id: IdNamespace(0), id: 0 };
151}
152
153pub type PipelineSourceId = u32;
158
159#[repr(C)]
162#[derive(Clone, Copy, Debug, Deserialize, Eq, Hash, MallocSizeOf, PartialEq, Serialize, PeekPoke)]
163pub struct PipelineId(pub PipelineSourceId, pub u32);
164
165impl Default for PipelineId {
166 fn default() -> Self {
167 PipelineId::dummy()
168 }
169}
170
171impl PipelineId {
172 pub fn dummy() -> Self {
174 PipelineId(!0, !0)
175 }
176
177 pub const INVALID: Self = PipelineId(!0, !0);
178}
179
180#[repr(C)]
181#[derive(Clone, Copy, Debug, PartialEq, PartialOrd)]
182pub struct FramePublishId(pub u64);
183
184impl FramePublishId {
185 pub fn first() -> Self {
191 FramePublishId(0)
192 }
193
194 pub fn advance(&mut self) {
196 self.0 += 1;
197 }
198
199 pub const INVALID: Self = FramePublishId(0);
202}
203
204impl Default for FramePublishId {
205 fn default() -> Self {
206 FramePublishId::INVALID
207 }
208}
209
210#[repr(C)]
212#[derive(Clone)]
213pub struct ExternalEvent {
214 raw: usize,
215}
216
217unsafe impl Send for ExternalEvent {}
218
219impl ExternalEvent {
220 pub fn from_raw(raw: usize) -> Self {
222 ExternalEvent { raw }
223 }
224 pub fn unwrap(self) -> usize {
226 self.raw
227 }
228}
229
230pub type APZScrollGeneration = u64;
231#[repr(C)]
232#[derive(Clone, Copy, Debug, Deserialize, PartialEq, Serialize, Default)]
233pub struct SampledScrollOffset {
234 pub offset: LayoutVector2D,
235 pub generation: APZScrollGeneration,
236}
237
238#[repr(u8)]
243#[derive(Clone, Copy, Debug, Default, Deserialize, PartialEq, Serialize, PeekPoke)]
244pub enum HasScrollLinkedEffect {
245 Yes,
246 #[default]
247 No,
248}
249
250#[repr(C)]
251pub struct MinimapData {
252 pub is_root_content: bool,
253 pub visual_viewport: LayoutRect,
255 pub layout_viewport: LayoutRect,
256 pub scrollable_rect: LayoutRect,
257 pub displayport: LayoutRect,
258 pub zoom_transform: LayoutTransform,
260 pub root_content_pipeline_id: PipelineId,
264 pub root_content_scroll_id: u64
265}
266
267#[repr(C)]
268pub struct FrameReadyParams {
269 pub present: bool,
270 pub render: bool,
271 pub scrolled: bool,
272 pub tracked: bool,
276}
277
278pub trait RenderNotifier: Send {
280 fn clone(&self) -> Box<dyn RenderNotifier>;
282 fn wake_up(
285 &self,
286 composite_needed: bool,
287 );
288 fn new_frame_ready(&self, _: DocumentId, publish_id: FramePublishId, params: &FrameReadyParams);
290 fn external_event(&self, _evt: ExternalEvent) {
294 unimplemented!()
295 }
296 fn shut_down(&self) {}
299}
300
301#[repr(u32)]
303#[derive(Copy, Clone, Debug, PartialEq, Eq)]
304pub enum Checkpoint {
305 SceneBuilt,
307 FrameBuilt,
309 FrameTexturesUpdated,
311 FrameRendered,
313 TransactionDropped,
316}
317
318pub trait NotificationHandler : Send + Sync {
321 fn notify(&self, when: Checkpoint);
323}
324
325pub struct NotificationRequest {
331 handler: Option<Box<dyn NotificationHandler>>,
332 when: Checkpoint,
333}
334
335impl NotificationRequest {
336 pub fn new(when: Checkpoint, handler: Box<dyn NotificationHandler>) -> Self {
338 NotificationRequest {
339 handler: Some(handler),
340 when,
341 }
342 }
343
344 pub fn when(&self) -> Checkpoint { self.when }
346
347 pub fn notify(mut self) {
349 if let Some(handler) = self.handler.take() {
350 handler.notify(self.when);
351 }
352 }
353}
354
355pub trait ApiHitTester: Send + Sync {
358 fn hit_test(&self, point: WorldPoint) -> HitTestResult;
362}
363
364pub struct HitTesterRequest {
368 #[doc(hidden)]
369 pub rx: Receiver<Arc<dyn ApiHitTester>>,
370}
371
372impl HitTesterRequest {
373 pub fn resolve(self) -> Arc<dyn ApiHitTester> {
375 self.rx.recv().unwrap()
376 }
377}
378
379#[derive(Clone, Debug, Deserialize, PartialEq, Serialize)]
381pub struct HitTestResultItem {
382 pub pipeline: PipelineId,
384
385 pub tag: ItemTag,
387
388 pub animation_id: u64,
390
391 pub point_in_viewport: LayoutPoint,
395}
396
397#[derive(Clone, Debug, Default, Deserialize, Serialize)]
399pub struct HitTestResult {
400 pub items: Vec<HitTestResultItem>,
402}
403
404impl Drop for NotificationRequest {
405 fn drop(&mut self) {
406 if let Some(ref mut handler) = self.handler {
407 handler.notify(Checkpoint::TransactionDropped);
408 }
409 }
410}
411
412impl Clone for NotificationRequest {
419 fn clone(&self) -> Self {
420 NotificationRequest {
421 when: self.when,
422 handler: None,
423 }
424 }
425}
426
427
428#[repr(C)]
430#[derive(Clone, Copy, Debug, Default, Deserialize, MallocSizeOf, PartialEq, Serialize, Eq, Hash, PeekPoke)]
431pub struct PropertyBindingId {
432 pub namespace: IdNamespace,
433 pub uid: u32,
434}
435
436impl PropertyBindingId {
437 pub fn new(value: u64) -> Self {
439 PropertyBindingId {
440 namespace: IdNamespace((value >> 32) as u32),
441 uid: value as u32,
442 }
443 }
444
445 pub fn to_u64(&self) -> u64 {
447 ((self.namespace.0 as u64) << 32) | self.uid as u64
448 }
449}
450
451#[repr(C)]
454#[derive(Clone, Copy, Debug, Default, Deserialize, Eq, Hash, MallocSizeOf, PartialEq, Serialize, PeekPoke)]
455pub struct PropertyBindingKey<T> {
456 pub id: PropertyBindingId,
458 #[doc(hidden)]
459 pub _phantom: PhantomData<T>,
460}
461
462impl<T: Copy> PropertyBindingKey<T> {
464 pub fn with(self, value: T) -> PropertyValue<T> {
466 PropertyValue { key: self, value }
467 }
468}
469
470impl<T> Into<u64> for PropertyBindingKey<T> {
471 fn into(self) -> u64 {
472 self.id.to_u64()
473 }
474}
475
476impl<T> PropertyBindingKey<T> {
477 pub fn new(value: u64) -> Self {
479 PropertyBindingKey {
480 id: PropertyBindingId::new(value),
481 _phantom: PhantomData,
482 }
483 }
484}
485
486#[repr(C)]
493#[derive(Clone, Copy, Debug, Deserialize, Eq, Hash, MallocSizeOf, PartialEq, Serialize, PeekPoke)]
494pub enum PropertyBinding<T> {
495 Value(T),
497 Binding(PropertyBindingKey<T>, T),
499}
500
501impl<T: Default> Default for PropertyBinding<T> {
502 fn default() -> Self {
503 PropertyBinding::Value(Default::default())
504 }
505}
506
507impl<T> From<T> for PropertyBinding<T> {
508 fn from(value: T) -> PropertyBinding<T> {
509 PropertyBinding::Value(value)
510 }
511}
512
513impl From<PropertyBindingKey<ColorF>> for PropertyBindingKey<ColorU> {
514 fn from(key: PropertyBindingKey<ColorF>) -> PropertyBindingKey<ColorU> {
515 PropertyBindingKey {
516 id: key.id,
517 _phantom: PhantomData,
518 }
519 }
520}
521
522impl From<PropertyBindingKey<ColorU>> for PropertyBindingKey<ColorF> {
523 fn from(key: PropertyBindingKey<ColorU>) -> PropertyBindingKey<ColorF> {
524 PropertyBindingKey {
525 id: key.id,
526 _phantom: PhantomData,
527 }
528 }
529}
530
531impl From<PropertyBinding<ColorF>> for PropertyBinding<ColorU> {
532 fn from(value: PropertyBinding<ColorF>) -> PropertyBinding<ColorU> {
533 match value {
534 PropertyBinding::Value(value) => PropertyBinding::Value(value.into()),
535 PropertyBinding::Binding(k, v) => {
536 PropertyBinding::Binding(k.into(), v.into())
537 }
538 }
539 }
540}
541
542impl From<PropertyBinding<ColorU>> for PropertyBinding<ColorF> {
543 fn from(value: PropertyBinding<ColorU>) -> PropertyBinding<ColorF> {
544 match value {
545 PropertyBinding::Value(value) => PropertyBinding::Value(value.into()),
546 PropertyBinding::Binding(k, v) => {
547 PropertyBinding::Binding(k.into(), v.into())
548 }
549 }
550 }
551}
552
553#[derive(Clone, Copy, Debug, Deserialize, Serialize, PartialEq)]
556pub struct PropertyValue<T> {
557 pub key: PropertyBindingKey<T>,
559 pub value: T,
561}
562
563#[derive(Clone, Deserialize, Serialize, Debug, PartialEq, Default)]
567pub struct DynamicProperties {
568 pub transforms: Vec<PropertyValue<LayoutTransform>>,
570 pub floats: Vec<PropertyValue<f32>>,
572 pub colors: Vec<PropertyValue<ColorF>>,
574}
575
576impl DynamicProperties {
577 pub fn extend(&mut self, other: Self) {
579 self.transforms.extend(other.transforms);
580 self.floats.extend(other.floats);
581 self.colors.extend(other.colors);
582 }
583}
584
585pub type VoidPtrToSizeFn = unsafe extern "C" fn(ptr: *const c_void) -> usize;
590
591#[derive(Copy, Clone, Debug, PartialEq)]
599pub enum Parameter {
600 Bool(BoolParameter, bool),
601 Int(IntParameter, i32),
602 Float(FloatParameter, f32),
603}
604
605#[derive(Copy, Clone, Debug, PartialEq, Eq)]
607#[repr(u32)]
608pub enum BoolParameter {
609 PboUploads = 0,
610 Multithreading = 1,
611 BatchedUploads = 2,
612 DrawCallsForTextureCopy = 3,
613}
614
615#[derive(Copy, Clone, Debug, PartialEq, Eq)]
617#[repr(u32)]
618pub enum IntParameter {
619 BatchedUploadThreshold = 0,
620}
621
622#[derive(Copy, Clone, Debug, PartialEq, Eq)]
624#[repr(u32)]
625pub enum FloatParameter {
626 SlowCpuFrameThreshold = 0,
628}
629
630#[repr(C)]
632#[derive(Copy, PartialEq, Eq, Clone, PartialOrd, Ord, Hash, Default, Deserialize, MallocSizeOf, Serialize)]
633pub struct RenderReasons(u32);
634
635bitflags! {
636 impl RenderReasons: u32 {
637 const NONE = 0;
639 const SCENE = 1 << 0;
640 const ANIMATED_PROPERTY = 1 << 1;
641 const RESOURCE_UPDATE = 1 << 2;
642 const ASYNC_IMAGE = 1 << 3;
643 const CLEAR_RESOURCES = 1 << 4;
644 const APZ = 1 << 5;
645 const RESIZE = 1 << 6;
647 const WIDGET = 1 << 7;
649 const TEXTURE_CACHE_FLUSH = 1 << 8;
651 const SNAPSHOT = 1 << 9;
652 const POST_RESOURCE_UPDATES_HOOK = 1 << 10;
653 const CONFIG_CHANGE = 1 << 11;
654 const CONTENT_SYNC = 1 << 12;
655 const FLUSH = 1 << 13;
656 const TESTING = 1 << 14;
657 const OTHER = 1 << 15;
658 const VSYNC = 1 << 16;
662 const SKIPPED_COMPOSITE = 1 << 17;
663 const START_OBSERVING_VSYNC = 1 << 18;
666 const ASYNC_IMAGE_COMPOSITE_UNTIL = 1 << 19;
667 }
668}
669
670impl core::fmt::Debug for RenderReasons {
671 fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
672 if self.is_empty() {
673 write!(f, "{:#x}", Self::empty().bits())
674 } else {
675 bitflags::parser::to_writer(self, f)
676 }
677 }
678}
679
680impl RenderReasons {
681 pub const NUM_BITS: u32 = 17;
682}
683
684#[repr(C)]
686#[derive(Copy, PartialEq, Eq, Clone, PartialOrd, Ord, Hash, Default, Deserialize, MallocSizeOf, Serialize)]
687pub struct DebugFlags(u64);
688
689bitflags! {
690 impl DebugFlags: u64 {
691 const PROFILER_DBG = 1 << 0;
693 const RENDER_TARGET_DBG = 1 << 1;
695 const TEXTURE_CACHE_DBG = 1 << 2;
697 const GPU_TIME_QUERIES = 1 << 3;
699 const GPU_SAMPLE_QUERIES = 1 << 4;
703 const DISABLE_BATCHING = 1 << 5;
708 const EPOCHS = 1 << 6;
710 const ECHO_DRIVER_MESSAGES = 1 << 7;
712 const SHOW_OVERDRAW = 1 << 8;
714 const GPU_CACHE_DBG = 1 << 9;
716 const TEXTURE_CACHE_DBG_CLEAR_EVICTED = 1 << 10;
718 const PICTURE_CACHING_DBG = 1 << 11;
720 const ZOOM_DBG = 1 << 13;
722 const SMALL_SCREEN = 1 << 14;
726 const DISABLE_OPAQUE_PASS = 1 << 15;
729 const DISABLE_ALPHA_PASS = 1 << 16;
731 const DISABLE_CLIP_MASKS = 1 << 17;
733 const DISABLE_TEXT_PRIMS = 1 << 18;
735 const DISABLE_GRADIENT_PRIMS = 1 << 19;
737 const OBSCURE_IMAGES = 1 << 20;
739 const GLYPH_FLASHING = 1 << 21;
742 const SMART_PROFILER = 1 << 22;
744 const INVALIDATION_DBG = 1 << 23;
746 const PROFILER_CAPTURE = 1 << 25;
748 const FORCE_PICTURE_INVALIDATION = 1 << 26;
750 const WINDOW_VISIBILITY_DBG = 1 << 27;
752 const RESTRICT_BLOB_SIZE = 1 << 28;
755 const SURFACE_PROMOTION_LOGGING = 1 << 29;
757 const PICTURE_BORDERS = 1 << 30;
759 const MISSING_SNAPSHOT_PANIC = (1 as u64) << 31; const MISSING_SNAPSHOT_PINK = (1 as u64) << 32;
763 const HIGHLIGHT_BACKDROP_FILTERS = (1 as u64) << 33;
765 const EXTERNAL_COMPOSITE_BORDERS = (1 as u64) << 34;
768 const DUMP_SPATIAL_TREE = (1 as u64) << 35;
770 }
771}
772
773impl core::fmt::Debug for DebugFlags {
774 fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
775 if self.is_empty() {
776 write!(f, "{:#x}", Self::empty().bits())
777 } else {
778 bitflags::parser::to_writer(self, f)
779 }
780 }
781}
782
783#[derive(Clone, Copy, Debug)]
785pub enum ScrollLocation {
786 Delta(LayoutVector2D),
788 Start,
790 End,
792}
793
794#[repr(C)]
796#[derive(Clone, Copy)]
797pub enum CrashAnnotation {
798 CompileShader = 0,
799 DrawShader = 1,
800 FontFile = 2,
801}
802
803pub trait CrashAnnotator : Send {
805 fn set(&self, annotation: CrashAnnotation, value: &std::ffi::CStr);
806 fn clear(&self, annotation: CrashAnnotation);
807 fn box_clone(&self) -> Box<dyn CrashAnnotator>;
808}
809
810impl Clone for Box<dyn CrashAnnotator> {
811 fn clone(&self) -> Box<dyn CrashAnnotator> {
812 self.box_clone()
813 }
814}
815
816pub struct CrashAnnotatorGuard<'a> {
818 annotator: &'a Option<Box<dyn CrashAnnotator>>,
819 annotation: CrashAnnotation,
820}
821
822impl<'a> CrashAnnotatorGuard<'a> {
823 pub fn new(
824 annotator: &'a Option<Box<dyn CrashAnnotator>>,
825 annotation: CrashAnnotation,
826 value: &std::ffi::CStr,
827 ) -> Self {
828 if let Some(ref annotator) = annotator {
829 annotator.set(annotation, value);
830 }
831 Self {
832 annotator,
833 annotation,
834 }
835 }
836}
837
838impl<'a> Drop for CrashAnnotatorGuard<'a> {
839 fn drop(&mut self) {
840 if let Some(ref annotator) = self.annotator {
841 annotator.clear(self.annotation);
842 }
843 }
844}
845
846#[derive(Copy, Clone, Debug, Eq, PartialEq)]
848#[cfg_attr(feature = "serialize", derive(Serialize))]
849#[cfg_attr(feature = "deserialize", derive(Deserialize))]
850pub enum TextureCacheCategory {
851 Atlas,
852 Standalone,
853 PictureTile,
854 RenderTarget,
855}
856
857#[derive(Clone, Debug)]
859#[cfg_attr(feature = "serialize", derive(Serialize))]
860#[cfg_attr(feature = "deserialize", derive(Deserialize))]
861pub enum RenderCommandInfo {
862 RenderTarget { kind: String, size: DeviceIntSize },
863 DrawCall { shader: String, instances: u32 },
864}