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)]
23
24
25pub extern crate crossbeam_channel;
26pub extern crate euclid;
27
28extern crate app_units;
29#[macro_use]
30extern crate bitflags;
31extern crate byteorder;
32#[cfg(feature = "nightly")]
33extern crate core;
34#[macro_use]
35extern crate malloc_size_of_derive;
36extern crate serde;
37#[macro_use]
38extern crate serde_derive;
39
40extern crate malloc_size_of;
41extern crate peek_poke;
42
43pub mod channel;
44mod color;
45mod display_item;
46mod display_item_cache;
47mod display_list;
48mod font;
49mod gradient_builder;
50mod image;
51mod precise_time_ns;
52mod tile_pool;
53pub mod units;
54
55pub use crate::color::*;
56pub use crate::display_item::*;
57pub use crate::display_item_cache::DisplayItemCache;
58pub use crate::display_list::*;
59pub use crate::font::*;
60pub use crate::gradient_builder::*;
61pub use crate::image::*;
62pub use crate::precise_time_ns::precise_time_ns;
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
122#[repr(C)]
128#[derive(Clone, Copy, Debug, Deserialize, Eq, Hash, MallocSizeOf, PartialEq, Serialize, PeekPoke)]
129pub struct DocumentId {
130 pub namespace_id: IdNamespace,
132 pub id: u32,
134}
135
136impl DocumentId {
137 pub fn new(namespace_id: IdNamespace, id: u32) -> Self {
139 DocumentId {
140 namespace_id,
141 id,
142 }
143 }
144
145 pub const INVALID: DocumentId = DocumentId { namespace_id: IdNamespace(0), id: 0 };
147}
148
149pub type PipelineSourceId = u32;
154
155#[repr(C)]
158#[derive(Clone, Copy, Debug, Deserialize, Eq, Hash, MallocSizeOf, PartialEq, Serialize, PeekPoke)]
159pub struct PipelineId(pub PipelineSourceId, pub u32);
160
161impl Default for PipelineId {
162 fn default() -> Self {
163 PipelineId::dummy()
164 }
165}
166
167impl PipelineId {
168 pub fn dummy() -> Self {
170 PipelineId(!0, !0)
171 }
172
173 pub const INVALID: Self = PipelineId(!0, !0);
174}
175
176#[repr(C)]
177#[derive(Clone, Copy, Debug, PartialEq, PartialOrd)]
178pub struct FramePublishId(pub u64);
179
180impl FramePublishId {
181 pub fn first() -> Self {
187 FramePublishId(0)
188 }
189
190 pub fn advance(&mut self) {
192 self.0 += 1;
193 }
194
195 pub const INVALID: Self = FramePublishId(0);
198}
199
200impl Default for FramePublishId {
201 fn default() -> Self {
202 FramePublishId::INVALID
203 }
204}
205
206#[repr(C)]
208#[derive(Clone)]
209pub struct ExternalEvent {
210 raw: usize,
211}
212
213unsafe impl Send for ExternalEvent {}
214
215impl ExternalEvent {
216 pub fn from_raw(raw: usize) -> Self {
218 ExternalEvent { raw }
219 }
220 pub fn unwrap(self) -> usize {
222 self.raw
223 }
224}
225
226pub type APZScrollGeneration = u64;
227#[repr(C)]
228#[derive(Clone, Copy, Debug, Deserialize, PartialEq, Serialize, Default)]
229pub struct SampledScrollOffset {
230 pub offset: LayoutVector2D,
231 pub generation: APZScrollGeneration,
232}
233
234#[repr(u8)]
239#[derive(Clone, Copy, Debug, Default, Deserialize, PartialEq, Serialize, PeekPoke)]
240pub enum HasScrollLinkedEffect {
241 Yes,
242 #[default]
243 No,
244}
245
246#[repr(C)]
247pub struct MinimapData {
248 pub is_root_content: bool,
249 pub visual_viewport: LayoutRect,
251 pub layout_viewport: LayoutRect,
252 pub scrollable_rect: LayoutRect,
253 pub displayport: LayoutRect,
254 pub zoom_transform: LayoutTransform,
256 pub root_content_pipeline_id: PipelineId,
260 pub root_content_scroll_id: u64
261}
262
263#[repr(C)]
264pub struct FrameReadyParams {
265 pub present: bool,
266 pub render: bool,
267 pub scrolled: bool,
268}
269
270pub trait RenderNotifier: Send {
272 fn clone(&self) -> Box<dyn RenderNotifier>;
274 fn wake_up(
277 &self,
278 composite_needed: bool,
279 );
280 fn new_frame_ready(&self, _: DocumentId, publish_id: FramePublishId, params: &FrameReadyParams);
282 fn external_event(&self, _evt: ExternalEvent) {
286 unimplemented!()
287 }
288 fn shut_down(&self) {}
291}
292
293#[repr(u32)]
295#[derive(Copy, Clone, Debug, PartialEq, Eq)]
296pub enum Checkpoint {
297 SceneBuilt,
299 FrameBuilt,
301 FrameTexturesUpdated,
303 FrameRendered,
305 TransactionDropped,
308}
309
310pub trait NotificationHandler : Send + Sync {
313 fn notify(&self, when: Checkpoint);
315}
316
317pub struct NotificationRequest {
323 handler: Option<Box<dyn NotificationHandler>>,
324 when: Checkpoint,
325}
326
327impl NotificationRequest {
328 pub fn new(when: Checkpoint, handler: Box<dyn NotificationHandler>) -> Self {
330 NotificationRequest {
331 handler: Some(handler),
332 when,
333 }
334 }
335
336 pub fn when(&self) -> Checkpoint { self.when }
338
339 pub fn notify(mut self) {
341 if let Some(handler) = self.handler.take() {
342 handler.notify(self.when);
343 }
344 }
345}
346
347pub trait ApiHitTester: Send + Sync {
350 fn hit_test(&self, pipeline_id: Option<PipelineId>, point: WorldPoint, flags: HitTestFlags) -> HitTestResult;
356}
357
358pub struct HitTesterRequest {
362 #[doc(hidden)]
363 pub rx: Receiver<Arc<dyn ApiHitTester>>,
364}
365
366impl HitTesterRequest {
367 pub fn resolve(self) -> Arc<dyn ApiHitTester> {
369 self.rx.recv().unwrap()
370 }
371}
372
373#[derive(Clone, Debug, Deserialize, PartialEq, Serialize)]
375pub struct HitTestResultItem {
376 pub pipeline: PipelineId,
378
379 pub tag: ItemTag,
381
382 pub animation_id: u64,
384
385 pub point_in_viewport: LayoutPoint,
389
390 pub point_relative_to_item: LayoutPoint,
393}
394
395#[derive(Clone, Debug, Default, Deserialize, Serialize)]
397pub struct HitTestResult {
398 pub items: Vec<HitTestResultItem>,
400}
401
402bitflags! {
403 #[derive(Deserialize, Serialize)]
404 pub struct HitTestFlags: u8 {
406 const FIND_ALL = 0b00000001;
408 const POINT_RELATIVE_TO_PIPELINE_VIEWPORT = 0b00000010;
410 }
411}
412
413impl Drop for NotificationRequest {
414 fn drop(&mut self) {
415 if let Some(ref mut handler) = self.handler {
416 handler.notify(Checkpoint::TransactionDropped);
417 }
418 }
419}
420
421impl Clone for NotificationRequest {
428 fn clone(&self) -> Self {
429 NotificationRequest {
430 when: self.when,
431 handler: None,
432 }
433 }
434}
435
436
437#[repr(C)]
439#[derive(Clone, Copy, Debug, Default, Deserialize, MallocSizeOf, PartialEq, Serialize, Eq, Hash, PeekPoke)]
440pub struct PropertyBindingId {
441 pub namespace: IdNamespace,
442 pub uid: u32,
443}
444
445impl PropertyBindingId {
446 pub fn new(value: u64) -> Self {
448 PropertyBindingId {
449 namespace: IdNamespace((value >> 32) as u32),
450 uid: value as u32,
451 }
452 }
453
454 pub fn to_u64(&self) -> u64 {
456 ((self.namespace.0 as u64) << 32) | self.uid as u64
457 }
458}
459
460#[repr(C)]
463#[derive(Clone, Copy, Debug, Default, Deserialize, Eq, Hash, MallocSizeOf, PartialEq, Serialize, PeekPoke)]
464pub struct PropertyBindingKey<T> {
465 pub id: PropertyBindingId,
467 #[doc(hidden)]
468 pub _phantom: PhantomData<T>,
469}
470
471impl<T: Copy> PropertyBindingKey<T> {
473 pub fn with(self, value: T) -> PropertyValue<T> {
475 PropertyValue { key: self, value }
476 }
477}
478
479impl<T> Into<u64> for PropertyBindingKey<T> {
480 fn into(self) -> u64 {
481 self.id.to_u64()
482 }
483}
484
485impl<T> PropertyBindingKey<T> {
486 pub fn new(value: u64) -> Self {
488 PropertyBindingKey {
489 id: PropertyBindingId::new(value),
490 _phantom: PhantomData,
491 }
492 }
493}
494
495#[repr(C)]
502#[derive(Clone, Copy, Debug, Deserialize, Eq, Hash, MallocSizeOf, PartialEq, Serialize, PeekPoke)]
503pub enum PropertyBinding<T> {
504 Value(T),
506 Binding(PropertyBindingKey<T>, T),
508}
509
510impl<T: Default> Default for PropertyBinding<T> {
511 fn default() -> Self {
512 PropertyBinding::Value(Default::default())
513 }
514}
515
516impl<T> From<T> for PropertyBinding<T> {
517 fn from(value: T) -> PropertyBinding<T> {
518 PropertyBinding::Value(value)
519 }
520}
521
522impl From<PropertyBindingKey<ColorF>> for PropertyBindingKey<ColorU> {
523 fn from(key: PropertyBindingKey<ColorF>) -> PropertyBindingKey<ColorU> {
524 PropertyBindingKey {
525 id: key.id,
526 _phantom: PhantomData,
527 }
528 }
529}
530
531impl From<PropertyBindingKey<ColorU>> for PropertyBindingKey<ColorF> {
532 fn from(key: PropertyBindingKey<ColorU>) -> PropertyBindingKey<ColorF> {
533 PropertyBindingKey {
534 id: key.id,
535 _phantom: PhantomData,
536 }
537 }
538}
539
540impl From<PropertyBinding<ColorF>> for PropertyBinding<ColorU> {
541 fn from(value: PropertyBinding<ColorF>) -> PropertyBinding<ColorU> {
542 match value {
543 PropertyBinding::Value(value) => PropertyBinding::Value(value.into()),
544 PropertyBinding::Binding(k, v) => {
545 PropertyBinding::Binding(k.into(), v.into())
546 }
547 }
548 }
549}
550
551impl From<PropertyBinding<ColorU>> for PropertyBinding<ColorF> {
552 fn from(value: PropertyBinding<ColorU>) -> PropertyBinding<ColorF> {
553 match value {
554 PropertyBinding::Value(value) => PropertyBinding::Value(value.into()),
555 PropertyBinding::Binding(k, v) => {
556 PropertyBinding::Binding(k.into(), v.into())
557 }
558 }
559 }
560}
561
562#[derive(Clone, Copy, Debug, Deserialize, Serialize, PartialEq)]
565pub struct PropertyValue<T> {
566 pub key: PropertyBindingKey<T>,
568 pub value: T,
570}
571
572#[derive(Clone, Deserialize, Serialize, Debug, PartialEq, Default)]
576pub struct DynamicProperties {
577 pub transforms: Vec<PropertyValue<LayoutTransform>>,
579 pub floats: Vec<PropertyValue<f32>>,
581 pub colors: Vec<PropertyValue<ColorF>>,
583}
584
585impl DynamicProperties {
586 pub fn extend(&mut self, other: Self) {
588 self.transforms.extend(other.transforms);
589 self.floats.extend(other.floats);
590 self.colors.extend(other.colors);
591 }
592}
593
594pub type VoidPtrToSizeFn = unsafe extern "C" fn(ptr: *const c_void) -> usize;
599
600#[derive(Copy, Clone, Debug, PartialEq)]
608pub enum Parameter {
609 Bool(BoolParameter, bool),
610 Int(IntParameter, i32),
611 Float(FloatParameter, f32),
612}
613
614#[derive(Copy, Clone, Debug, PartialEq, Eq)]
616#[repr(u32)]
617pub enum BoolParameter {
618 PboUploads = 0,
619 Multithreading = 1,
620 BatchedUploads = 2,
621 DrawCallsForTextureCopy = 3,
622}
623
624#[derive(Copy, Clone, Debug, PartialEq, Eq)]
626#[repr(u32)]
627pub enum IntParameter {
628 BatchedUploadThreshold = 0,
629}
630
631#[derive(Copy, Clone, Debug, PartialEq, Eq)]
633#[repr(u32)]
634pub enum FloatParameter {
635 SlowCpuFrameThreshold = 0,
637}
638
639#[repr(C)]
641#[derive(Copy, PartialEq, Eq, Clone, PartialOrd, Ord, Hash, Default, Deserialize, MallocSizeOf, Serialize)]
642pub struct RenderReasons(u32);
643
644bitflags! {
645 impl RenderReasons: u32 {
646 const NONE = 0;
648 const SCENE = 1 << 0;
649 const ANIMATED_PROPERTY = 1 << 1;
650 const RESOURCE_UPDATE = 1 << 2;
651 const ASYNC_IMAGE = 1 << 3;
652 const CLEAR_RESOURCES = 1 << 4;
653 const APZ = 1 << 5;
654 const RESIZE = 1 << 6;
656 const WIDGET = 1 << 7;
658 const TEXTURE_CACHE_FLUSH = 1 << 8;
660 const SNAPSHOT = 1 << 9;
661 const POST_RESOURCE_UPDATES_HOOK = 1 << 10;
662 const CONFIG_CHANGE = 1 << 11;
663 const CONTENT_SYNC = 1 << 12;
664 const FLUSH = 1 << 13;
665 const TESTING = 1 << 14;
666 const OTHER = 1 << 15;
667 const VSYNC = 1 << 16;
671 const SKIPPED_COMPOSITE = 1 << 17;
672 const START_OBSERVING_VSYNC = 1 << 18;
675 const ASYNC_IMAGE_COMPOSITE_UNTIL = 1 << 19;
676 }
677}
678
679impl core::fmt::Debug for RenderReasons {
680 fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
681 if self.is_empty() {
682 write!(f, "{:#x}", Self::empty().bits())
683 } else {
684 bitflags::parser::to_writer(self, f)
685 }
686 }
687}
688
689impl RenderReasons {
690 pub const NUM_BITS: u32 = 17;
691}
692
693#[repr(C)]
695#[derive(Copy, PartialEq, Eq, Clone, PartialOrd, Ord, Hash, Default, Deserialize, MallocSizeOf, Serialize)]
696pub struct DebugFlags(u64);
697
698bitflags! {
699 impl DebugFlags: u64 {
700 const PROFILER_DBG = 1 << 0;
702 const RENDER_TARGET_DBG = 1 << 1;
704 const TEXTURE_CACHE_DBG = 1 << 2;
706 const GPU_TIME_QUERIES = 1 << 3;
708 const GPU_SAMPLE_QUERIES = 1 << 4;
712 const DISABLE_BATCHING = 1 << 5;
717 const EPOCHS = 1 << 6;
719 const ECHO_DRIVER_MESSAGES = 1 << 7;
721 const SHOW_OVERDRAW = 1 << 8;
723 const GPU_CACHE_DBG = 1 << 9;
725 const TEXTURE_CACHE_DBG_CLEAR_EVICTED = 1 << 10;
727 const PICTURE_CACHING_DBG = 1 << 11;
729 const PRIMITIVE_DBG = 1 << 12;
731 const ZOOM_DBG = 1 << 13;
733 const SMALL_SCREEN = 1 << 14;
737 const DISABLE_OPAQUE_PASS = 1 << 15;
740 const DISABLE_ALPHA_PASS = 1 << 16;
742 const DISABLE_CLIP_MASKS = 1 << 17;
744 const DISABLE_TEXT_PRIMS = 1 << 18;
746 const DISABLE_GRADIENT_PRIMS = 1 << 19;
748 const OBSCURE_IMAGES = 1 << 20;
750 const GLYPH_FLASHING = 1 << 21;
753 const SMART_PROFILER = 1 << 22;
755 const INVALIDATION_DBG = 1 << 23;
757 const PROFILER_CAPTURE = 1 << 25;
759 const FORCE_PICTURE_INVALIDATION = 1 << 26;
761 const WINDOW_VISIBILITY_DBG = 1 << 27;
763 const RESTRICT_BLOB_SIZE = 1 << 28;
766 const SURFACE_PROMOTION_LOGGING = 1 << 29;
768 const PICTURE_BORDERS = 1 << 30;
770 const MISSING_SNAPSHOT_PANIC = (1 as u64) << 31; const MISSING_SNAPSHOT_PINK = (1 as u64) << 32;
774 }
775}
776
777impl core::fmt::Debug for DebugFlags {
778 fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
779 if self.is_empty() {
780 write!(f, "{:#x}", Self::empty().bits())
781 } else {
782 bitflags::parser::to_writer(self, f)
783 }
784 }
785}
786
787#[derive(Debug, Clone, Eq, MallocSizeOf, PartialEq, Hash, Serialize, Deserialize)]
790pub enum PrimitiveKeyKind {
791 Clear,
793 Rectangle {
795 color: PropertyBinding<ColorU>,
797 },
798}
799
800#[derive(Clone, Copy, Debug)]
802pub enum ScrollLocation {
803 Delta(LayoutVector2D),
805 Start,
807 End,
809}
810
811#[repr(C)]
813#[derive(Clone, Copy)]
814pub enum CrashAnnotation {
815 CompileShader = 0,
816 DrawShader = 1,
817}
818
819pub trait CrashAnnotator : Send {
821 fn set(&self, annotation: CrashAnnotation, value: &std::ffi::CStr);
822 fn clear(&self, annotation: CrashAnnotation);
823 fn box_clone(&self) -> Box<dyn CrashAnnotator>;
824}
825
826impl Clone for Box<dyn CrashAnnotator> {
827 fn clone(&self) -> Box<dyn CrashAnnotator> {
828 self.box_clone()
829 }
830}
831
832pub struct CrashAnnotatorGuard<'a> {
834 annotator: &'a Option<Box<dyn CrashAnnotator>>,
835 annotation: CrashAnnotation,
836}
837
838impl<'a> CrashAnnotatorGuard<'a> {
839 pub fn new(
840 annotator: &'a Option<Box<dyn CrashAnnotator>>,
841 annotation: CrashAnnotation,
842 value: &std::ffi::CStr,
843 ) -> Self {
844 if let Some(ref annotator) = annotator {
845 annotator.set(annotation, value);
846 }
847 Self {
848 annotator,
849 annotation,
850 }
851 }
852}
853
854impl<'a> Drop for CrashAnnotatorGuard<'a> {
855 fn drop(&mut self) {
856 if let Some(ref annotator) = self.annotator {
857 annotator.clear(self.annotation);
858 }
859 }
860}