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 pub point_in_viewport: LayoutPoint,
397}
398
399#[derive(Clone, Debug, Default, Deserialize, Serialize)]
401pub struct HitTestResult {
402 pub items: Vec<HitTestResultItem>,
404}
405
406impl Drop for NotificationRequest {
407 fn drop(&mut self) {
408 if let Some(ref mut handler) = self.handler {
409 handler.notify(Checkpoint::TransactionDropped);
410 }
411 }
412}
413
414impl Clone for NotificationRequest {
421 fn clone(&self) -> Self {
422 NotificationRequest {
423 when: self.when,
424 handler: None,
425 }
426 }
427}
428
429
430#[repr(C)]
432#[derive(Clone, Copy, Debug, Default, Deserialize, MallocSizeOf, PartialEq, Serialize, Eq, Hash, PeekPoke)]
433pub struct PropertyBindingId {
434 pub namespace: IdNamespace,
435 pub uid: u32,
436}
437
438impl PropertyBindingId {
439 pub fn new(value: u64) -> Self {
441 PropertyBindingId {
442 namespace: IdNamespace((value >> 32) as u32),
443 uid: value as u32,
444 }
445 }
446
447 pub fn to_u64(&self) -> u64 {
449 ((self.namespace.0 as u64) << 32) | self.uid as u64
450 }
451}
452
453#[repr(C)]
456#[derive(Clone, Copy, Debug, Default, Deserialize, Eq, Hash, MallocSizeOf, PartialEq, Serialize, PeekPoke)]
457pub struct PropertyBindingKey<T> {
458 pub id: PropertyBindingId,
460 #[doc(hidden)]
461 pub _phantom: PhantomData<T>,
462}
463
464impl<T: Copy> PropertyBindingKey<T> {
466 pub fn with(self, value: T) -> PropertyValue<T> {
468 PropertyValue { key: self, value }
469 }
470}
471
472impl<T> Into<u64> for PropertyBindingKey<T> {
473 fn into(self) -> u64 {
474 self.id.to_u64()
475 }
476}
477
478impl<T> PropertyBindingKey<T> {
479 pub fn new(value: u64) -> Self {
481 PropertyBindingKey {
482 id: PropertyBindingId::new(value),
483 _phantom: PhantomData,
484 }
485 }
486}
487
488#[repr(C)]
495#[derive(Clone, Copy, Debug, Deserialize, Eq, Hash, MallocSizeOf, PartialEq, Serialize, PeekPoke)]
496pub enum PropertyBinding<T> {
497 Value(T),
499 Binding(PropertyBindingKey<T>, T),
501}
502
503impl<T: Default> Default for PropertyBinding<T> {
504 fn default() -> Self {
505 PropertyBinding::Value(Default::default())
506 }
507}
508
509impl<T> From<T> for PropertyBinding<T> {
510 fn from(value: T) -> PropertyBinding<T> {
511 PropertyBinding::Value(value)
512 }
513}
514
515impl From<PropertyBindingKey<ColorF>> for PropertyBindingKey<ColorU> {
516 fn from(key: PropertyBindingKey<ColorF>) -> PropertyBindingKey<ColorU> {
517 PropertyBindingKey {
518 id: key.id,
519 _phantom: PhantomData,
520 }
521 }
522}
523
524impl From<PropertyBindingKey<ColorU>> for PropertyBindingKey<ColorF> {
525 fn from(key: PropertyBindingKey<ColorU>) -> PropertyBindingKey<ColorF> {
526 PropertyBindingKey {
527 id: key.id,
528 _phantom: PhantomData,
529 }
530 }
531}
532
533impl From<PropertyBinding<ColorF>> for PropertyBinding<ColorU> {
534 fn from(value: PropertyBinding<ColorF>) -> PropertyBinding<ColorU> {
535 match value {
536 PropertyBinding::Value(value) => PropertyBinding::Value(value.into()),
537 PropertyBinding::Binding(k, v) => {
538 PropertyBinding::Binding(k.into(), v.into())
539 }
540 }
541 }
542}
543
544impl From<PropertyBinding<ColorU>> for PropertyBinding<ColorF> {
545 fn from(value: PropertyBinding<ColorU>) -> PropertyBinding<ColorF> {
546 match value {
547 PropertyBinding::Value(value) => PropertyBinding::Value(value.into()),
548 PropertyBinding::Binding(k, v) => {
549 PropertyBinding::Binding(k.into(), v.into())
550 }
551 }
552 }
553}
554
555#[derive(Clone, Copy, Debug, Deserialize, Serialize, PartialEq)]
558pub struct PropertyValue<T> {
559 pub key: PropertyBindingKey<T>,
561 pub value: T,
563}
564
565#[derive(Clone, Deserialize, Serialize, Debug, PartialEq, Default)]
569pub struct DynamicProperties {
570 pub transforms: Vec<PropertyValue<LayoutTransform>>,
572 pub floats: Vec<PropertyValue<f32>>,
574 pub colors: Vec<PropertyValue<ColorF>>,
576}
577
578impl DynamicProperties {
579 pub fn extend(&mut self, other: Self) {
581 self.transforms.extend(other.transforms);
582 self.floats.extend(other.floats);
583 self.colors.extend(other.colors);
584 }
585}
586
587pub type VoidPtrToSizeFn = unsafe extern "C" fn(ptr: *const c_void) -> usize;
592
593#[derive(Copy, Clone, Debug, PartialEq)]
601pub enum Parameter {
602 Bool(BoolParameter, bool),
603 Int(IntParameter, i32),
604 Float(FloatParameter, f32),
605}
606
607#[derive(Copy, Clone, Debug, PartialEq, Eq)]
609#[repr(u32)]
610pub enum BoolParameter {
611 PboUploads = 0,
612 Multithreading = 1,
613 BatchedUploads = 2,
614 DrawCallsForTextureCopy = 3,
615}
616
617#[derive(Copy, Clone, Debug, PartialEq, Eq)]
619#[repr(u32)]
620pub enum IntParameter {
621 BatchedUploadThreshold = 0,
622}
623
624#[derive(Copy, Clone, Debug, PartialEq, Eq)]
626#[repr(u32)]
627pub enum FloatParameter {
628 SlowCpuFrameThreshold = 0,
630}
631
632#[repr(C)]
634#[derive(Copy, PartialEq, Eq, Clone, PartialOrd, Ord, Hash, Default, Deserialize, MallocSizeOf, Serialize)]
635pub struct RenderReasons(u32);
636
637bitflags! {
638 impl RenderReasons: u32 {
639 const NONE = 0;
641 const SCENE = 1 << 0;
642 const ANIMATED_PROPERTY = 1 << 1;
643 const RESOURCE_UPDATE = 1 << 2;
644 const ASYNC_IMAGE = 1 << 3;
645 const CLEAR_RESOURCES = 1 << 4;
646 const APZ = 1 << 5;
647 const RESIZE = 1 << 6;
649 const WIDGET = 1 << 7;
651 const TEXTURE_CACHE_FLUSH = 1 << 8;
653 const SNAPSHOT = 1 << 9;
654 const POST_RESOURCE_UPDATES_HOOK = 1 << 10;
655 const CONFIG_CHANGE = 1 << 11;
656 const CONTENT_SYNC = 1 << 12;
657 const FLUSH = 1 << 13;
658 const TESTING = 1 << 14;
659 const OTHER = 1 << 15;
660 const VSYNC = 1 << 16;
664 const SKIPPED_COMPOSITE = 1 << 17;
665 const START_OBSERVING_VSYNC = 1 << 18;
668 const ASYNC_IMAGE_COMPOSITE_UNTIL = 1 << 19;
669 }
670}
671
672impl core::fmt::Debug for RenderReasons {
673 fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
674 if self.is_empty() {
675 write!(f, "{:#x}", Self::empty().bits())
676 } else {
677 bitflags::parser::to_writer(self, f)
678 }
679 }
680}
681
682impl RenderReasons {
683 pub const NUM_BITS: u32 = 17;
684}
685
686#[repr(C)]
688#[derive(Copy, PartialEq, Eq, Clone, PartialOrd, Ord, Hash, Default, Deserialize, MallocSizeOf, Serialize)]
689pub struct DebugFlags(u64);
690
691bitflags! {
692 impl DebugFlags: u64 {
693 const PROFILER_DBG = 1 << 0;
695 const RENDER_TARGET_DBG = 1 << 1;
697 const TEXTURE_CACHE_DBG = 1 << 2;
699 const GPU_TIME_QUERIES = 1 << 3;
701 const GPU_SAMPLE_QUERIES = 1 << 4;
705 const DISABLE_BATCHING = 1 << 5;
710 const EPOCHS = 1 << 6;
712 const ECHO_DRIVER_MESSAGES = 1 << 7;
714 const SHOW_OVERDRAW = 1 << 8;
716 const GPU_CACHE_DBG = 1 << 9;
718 const TEXTURE_CACHE_DBG_CLEAR_EVICTED = 1 << 10;
720 const PICTURE_CACHING_DBG = 1 << 11;
722 const PRIMITIVE_DBG = 1 << 12;
724 const ZOOM_DBG = 1 << 13;
726 const SMALL_SCREEN = 1 << 14;
730 const DISABLE_OPAQUE_PASS = 1 << 15;
733 const DISABLE_ALPHA_PASS = 1 << 16;
735 const DISABLE_CLIP_MASKS = 1 << 17;
737 const DISABLE_TEXT_PRIMS = 1 << 18;
739 const DISABLE_GRADIENT_PRIMS = 1 << 19;
741 const OBSCURE_IMAGES = 1 << 20;
743 const GLYPH_FLASHING = 1 << 21;
746 const SMART_PROFILER = 1 << 22;
748 const INVALIDATION_DBG = 1 << 23;
750 const PROFILER_CAPTURE = 1 << 25;
752 const FORCE_PICTURE_INVALIDATION = 1 << 26;
754 const WINDOW_VISIBILITY_DBG = 1 << 27;
756 const RESTRICT_BLOB_SIZE = 1 << 28;
759 const SURFACE_PROMOTION_LOGGING = 1 << 29;
761 const PICTURE_BORDERS = 1 << 30;
763 const MISSING_SNAPSHOT_PANIC = (1 as u64) << 31; const MISSING_SNAPSHOT_PINK = (1 as u64) << 32;
767 const HIGHLIGHT_BACKDROP_FILTERS = (1 as u64) << 33;
769 }
770}
771
772impl core::fmt::Debug for DebugFlags {
773 fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
774 if self.is_empty() {
775 write!(f, "{:#x}", Self::empty().bits())
776 } else {
777 bitflags::parser::to_writer(self, f)
778 }
779 }
780}
781
782#[derive(Debug, Clone, Eq, MallocSizeOf, PartialEq, Hash, Serialize, Deserialize)]
785pub enum PrimitiveKeyKind {
786 Clear,
788 Rectangle {
790 color: PropertyBinding<ColorU>,
792 },
793}
794
795#[derive(Clone, Copy, Debug)]
797pub enum ScrollLocation {
798 Delta(LayoutVector2D),
800 Start,
802 End,
804}
805
806#[repr(C)]
808#[derive(Clone, Copy)]
809pub enum CrashAnnotation {
810 CompileShader = 0,
811 DrawShader = 1,
812}
813
814pub trait CrashAnnotator : Send {
816 fn set(&self, annotation: CrashAnnotation, value: &std::ffi::CStr);
817 fn clear(&self, annotation: CrashAnnotation);
818 fn box_clone(&self) -> Box<dyn CrashAnnotator>;
819}
820
821impl Clone for Box<dyn CrashAnnotator> {
822 fn clone(&self) -> Box<dyn CrashAnnotator> {
823 self.box_clone()
824 }
825}
826
827pub struct CrashAnnotatorGuard<'a> {
829 annotator: &'a Option<Box<dyn CrashAnnotator>>,
830 annotation: CrashAnnotation,
831}
832
833impl<'a> CrashAnnotatorGuard<'a> {
834 pub fn new(
835 annotator: &'a Option<Box<dyn CrashAnnotator>>,
836 annotation: CrashAnnotation,
837 value: &std::ffi::CStr,
838 ) -> Self {
839 if let Some(ref annotator) = annotator {
840 annotator.set(annotation, value);
841 }
842 Self {
843 annotator,
844 annotation,
845 }
846 }
847}
848
849impl<'a> Drop for CrashAnnotatorGuard<'a> {
850 fn drop(&mut self) {
851 if let Some(ref annotator) = self.annotator {
852 annotator.clear(self.annotation);
853 }
854 }
855}