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 tile_pool;
52pub mod units;
53
54pub use crate::color::*;
55pub use crate::display_item::*;
56pub use crate::display_item_cache::DisplayItemCache;
57pub use crate::display_list::*;
58pub use crate::font::*;
59pub use crate::gradient_builder::*;
60pub use crate::image::*;
61pub use crate::tile_pool::*;
62
63use crate::units::*;
64use crate::channel::Receiver;
65use std::marker::PhantomData;
66use std::sync::Arc;
67use std::os::raw::c_void;
68use peek_poke::PeekPoke;
69
70pub const MAX_RENDER_TASK_SIZE: i32 = 16384;
72
73pub type TileSize = u16;
75
76#[derive(Copy, Clone, Deserialize, Serialize)]
79pub struct QualitySettings {
80 pub force_subpixel_aa_where_possible: bool,
85}
86
87impl Default for QualitySettings {
88 fn default() -> Self {
89 QualitySettings {
90 force_subpixel_aa_where_possible: false,
93 }
94 }
95}
96
97#[repr(C)]
102#[derive(Clone, Copy, Debug, Deserialize, Eq, Hash, Ord, PartialEq, PartialOrd, Serialize)]
103pub struct Epoch(pub u32);
104
105impl Epoch {
106 pub fn invalid() -> Epoch {
108 Epoch(u32::MAX)
109 }
110}
111
112#[repr(C)]
116#[derive(Clone, Copy, Debug, Default, Eq, MallocSizeOf, PartialEq, Hash, Ord, PartialOrd, PeekPoke)]
117#[derive(Deserialize, Serialize)]
118pub struct IdNamespace(pub u32);
119
120#[repr(C)]
126#[derive(Clone, Copy, Debug, Deserialize, Eq, Hash, MallocSizeOf, PartialEq, Serialize, PeekPoke)]
127pub struct DocumentId {
128 pub namespace_id: IdNamespace,
130 pub id: u32,
132}
133
134impl DocumentId {
135 pub fn new(namespace_id: IdNamespace, id: u32) -> Self {
137 DocumentId {
138 namespace_id,
139 id,
140 }
141 }
142
143 pub const INVALID: DocumentId = DocumentId { namespace_id: IdNamespace(0), id: 0 };
145}
146
147pub type PipelineSourceId = u32;
152
153#[repr(C)]
156#[derive(Clone, Copy, Debug, Deserialize, Eq, Hash, MallocSizeOf, PartialEq, Serialize, PeekPoke)]
157pub struct PipelineId(pub PipelineSourceId, pub u32);
158
159impl Default for PipelineId {
160 fn default() -> Self {
161 PipelineId::dummy()
162 }
163}
164
165impl PipelineId {
166 pub fn dummy() -> Self {
168 PipelineId(!0, !0)
169 }
170
171 pub const INVALID: Self = PipelineId(!0, !0);
172}
173
174#[repr(C)]
175#[derive(Clone, Copy, Debug, PartialEq, PartialOrd)]
176pub struct FramePublishId(pub u64);
177
178impl FramePublishId {
179 pub fn first() -> Self {
185 FramePublishId(0)
186 }
187
188 pub fn advance(&mut self) {
190 self.0 += 1;
191 }
192
193 pub const INVALID: Self = FramePublishId(0);
196}
197
198impl Default for FramePublishId {
199 fn default() -> Self {
200 FramePublishId::INVALID
201 }
202}
203
204#[repr(C)]
206#[derive(Clone)]
207pub struct ExternalEvent {
208 raw: usize,
209}
210
211unsafe impl Send for ExternalEvent {}
212
213impl ExternalEvent {
214 pub fn from_raw(raw: usize) -> Self {
216 ExternalEvent { raw }
217 }
218 pub fn unwrap(self) -> usize {
220 self.raw
221 }
222}
223
224pub type APZScrollGeneration = u64;
225#[repr(C)]
226#[derive(Clone, Copy, Debug, Deserialize, PartialEq, Serialize, Default)]
227pub struct SampledScrollOffset {
228 pub offset: LayoutVector2D,
229 pub generation: APZScrollGeneration,
230}
231
232#[repr(u8)]
237#[derive(Clone, Copy, Debug, Default, Deserialize, PartialEq, Serialize, PeekPoke)]
238pub enum HasScrollLinkedEffect {
239 Yes,
240 #[default]
241 No,
242}
243
244#[repr(C)]
245pub struct MinimapData {
246 pub is_root_content: bool,
247 pub visual_viewport: LayoutRect,
249 pub layout_viewport: LayoutRect,
250 pub scrollable_rect: LayoutRect,
251 pub displayport: LayoutRect,
252 pub zoom_transform: LayoutTransform,
254 pub root_content_pipeline_id: PipelineId,
258 pub root_content_scroll_id: u64
259}
260
261#[repr(C)]
262pub struct FrameReadyParams {
263 pub present: bool,
264 pub render: bool,
265 pub scrolled: bool,
266}
267
268pub trait RenderNotifier: Send {
270 fn clone(&self) -> Box<dyn RenderNotifier>;
272 fn wake_up(
275 &self,
276 composite_needed: bool,
277 );
278 fn new_frame_ready(&self, _: DocumentId, publish_id: FramePublishId, params: &FrameReadyParams);
280 fn external_event(&self, _evt: ExternalEvent) {
284 unimplemented!()
285 }
286 fn shut_down(&self) {}
289}
290
291#[repr(u32)]
293#[derive(Copy, Clone, Debug, PartialEq, Eq)]
294pub enum Checkpoint {
295 SceneBuilt,
297 FrameBuilt,
299 FrameTexturesUpdated,
301 FrameRendered,
303 TransactionDropped,
306}
307
308pub trait NotificationHandler : Send + Sync {
311 fn notify(&self, when: Checkpoint);
313}
314
315pub struct NotificationRequest {
321 handler: Option<Box<dyn NotificationHandler>>,
322 when: Checkpoint,
323}
324
325impl NotificationRequest {
326 pub fn new(when: Checkpoint, handler: Box<dyn NotificationHandler>) -> Self {
328 NotificationRequest {
329 handler: Some(handler),
330 when,
331 }
332 }
333
334 pub fn when(&self) -> Checkpoint { self.when }
336
337 pub fn notify(mut self) {
339 if let Some(handler) = self.handler.take() {
340 handler.notify(self.when);
341 }
342 }
343}
344
345pub trait ApiHitTester: Send + Sync {
348 fn hit_test(&self, point: WorldPoint) -> HitTestResult;
352}
353
354pub struct HitTesterRequest {
358 #[doc(hidden)]
359 pub rx: Receiver<Arc<dyn ApiHitTester>>,
360}
361
362impl HitTesterRequest {
363 pub fn resolve(self) -> Arc<dyn ApiHitTester> {
365 self.rx.recv().unwrap()
366 }
367}
368
369#[derive(Clone, Debug, Deserialize, PartialEq, Serialize)]
371pub struct HitTestResultItem {
372 pub pipeline: PipelineId,
374
375 pub tag: ItemTag,
377
378 pub animation_id: u64,
380}
381
382#[derive(Clone, Debug, Default, Deserialize, Serialize)]
384pub struct HitTestResult {
385 pub items: Vec<HitTestResultItem>,
387}
388
389impl Drop for NotificationRequest {
390 fn drop(&mut self) {
391 if let Some(ref mut handler) = self.handler {
392 handler.notify(Checkpoint::TransactionDropped);
393 }
394 }
395}
396
397impl Clone for NotificationRequest {
404 fn clone(&self) -> Self {
405 NotificationRequest {
406 when: self.when,
407 handler: None,
408 }
409 }
410}
411
412
413#[repr(C)]
415#[derive(Clone, Copy, Debug, Default, Deserialize, MallocSizeOf, PartialEq, Serialize, Eq, Hash, PeekPoke)]
416pub struct PropertyBindingId {
417 pub namespace: IdNamespace,
418 pub uid: u32,
419}
420
421impl PropertyBindingId {
422 pub fn new(value: u64) -> Self {
424 PropertyBindingId {
425 namespace: IdNamespace((value >> 32) as u32),
426 uid: value as u32,
427 }
428 }
429
430 pub fn to_u64(&self) -> u64 {
432 ((self.namespace.0 as u64) << 32) | self.uid as u64
433 }
434}
435
436#[repr(C)]
439#[derive(Clone, Copy, Debug, Default, Deserialize, Eq, Hash, MallocSizeOf, PartialEq, Serialize, PeekPoke)]
440pub struct PropertyBindingKey<T> {
441 pub id: PropertyBindingId,
443 #[doc(hidden)]
444 pub _phantom: PhantomData<T>,
445}
446
447impl<T: Copy> PropertyBindingKey<T> {
449 pub fn with(self, value: T) -> PropertyValue<T> {
451 PropertyValue { key: self, value }
452 }
453}
454
455impl<T> Into<u64> for PropertyBindingKey<T> {
456 fn into(self) -> u64 {
457 self.id.to_u64()
458 }
459}
460
461impl<T> PropertyBindingKey<T> {
462 pub fn new(value: u64) -> Self {
464 PropertyBindingKey {
465 id: PropertyBindingId::new(value),
466 _phantom: PhantomData,
467 }
468 }
469}
470
471#[repr(C)]
478#[derive(Clone, Copy, Debug, Deserialize, Eq, Hash, MallocSizeOf, PartialEq, Serialize, PeekPoke)]
479pub enum PropertyBinding<T> {
480 Value(T),
482 Binding(PropertyBindingKey<T>, T),
484}
485
486impl<T: Default> Default for PropertyBinding<T> {
487 fn default() -> Self {
488 PropertyBinding::Value(Default::default())
489 }
490}
491
492impl<T> From<T> for PropertyBinding<T> {
493 fn from(value: T) -> PropertyBinding<T> {
494 PropertyBinding::Value(value)
495 }
496}
497
498impl From<PropertyBindingKey<ColorF>> for PropertyBindingKey<ColorU> {
499 fn from(key: PropertyBindingKey<ColorF>) -> PropertyBindingKey<ColorU> {
500 PropertyBindingKey {
501 id: key.id,
502 _phantom: PhantomData,
503 }
504 }
505}
506
507impl From<PropertyBindingKey<ColorU>> for PropertyBindingKey<ColorF> {
508 fn from(key: PropertyBindingKey<ColorU>) -> PropertyBindingKey<ColorF> {
509 PropertyBindingKey {
510 id: key.id,
511 _phantom: PhantomData,
512 }
513 }
514}
515
516impl From<PropertyBinding<ColorF>> for PropertyBinding<ColorU> {
517 fn from(value: PropertyBinding<ColorF>) -> PropertyBinding<ColorU> {
518 match value {
519 PropertyBinding::Value(value) => PropertyBinding::Value(value.into()),
520 PropertyBinding::Binding(k, v) => {
521 PropertyBinding::Binding(k.into(), v.into())
522 }
523 }
524 }
525}
526
527impl From<PropertyBinding<ColorU>> for PropertyBinding<ColorF> {
528 fn from(value: PropertyBinding<ColorU>) -> PropertyBinding<ColorF> {
529 match value {
530 PropertyBinding::Value(value) => PropertyBinding::Value(value.into()),
531 PropertyBinding::Binding(k, v) => {
532 PropertyBinding::Binding(k.into(), v.into())
533 }
534 }
535 }
536}
537
538#[derive(Clone, Copy, Debug, Deserialize, Serialize, PartialEq)]
541pub struct PropertyValue<T> {
542 pub key: PropertyBindingKey<T>,
544 pub value: T,
546}
547
548#[derive(Clone, Deserialize, Serialize, Debug, PartialEq, Default)]
552pub struct DynamicProperties {
553 pub transforms: Vec<PropertyValue<LayoutTransform>>,
555 pub floats: Vec<PropertyValue<f32>>,
557 pub colors: Vec<PropertyValue<ColorF>>,
559}
560
561impl DynamicProperties {
562 pub fn extend(&mut self, other: Self) {
564 self.transforms.extend(other.transforms);
565 self.floats.extend(other.floats);
566 self.colors.extend(other.colors);
567 }
568}
569
570pub type VoidPtrToSizeFn = unsafe extern "C" fn(ptr: *const c_void) -> usize;
575
576#[derive(Copy, Clone, Debug, PartialEq)]
584pub enum Parameter {
585 Bool(BoolParameter, bool),
586 Int(IntParameter, i32),
587 Float(FloatParameter, f32),
588}
589
590#[derive(Copy, Clone, Debug, PartialEq, Eq)]
592#[repr(u32)]
593pub enum BoolParameter {
594 PboUploads = 0,
595 Multithreading = 1,
596 BatchedUploads = 2,
597 DrawCallsForTextureCopy = 3,
598}
599
600#[derive(Copy, Clone, Debug, PartialEq, Eq)]
602#[repr(u32)]
603pub enum IntParameter {
604 BatchedUploadThreshold = 0,
605}
606
607#[derive(Copy, Clone, Debug, PartialEq, Eq)]
609#[repr(u32)]
610pub enum FloatParameter {
611 SlowCpuFrameThreshold = 0,
613}
614
615#[repr(C)]
617#[derive(Copy, PartialEq, Eq, Clone, PartialOrd, Ord, Hash, Default, Deserialize, MallocSizeOf, Serialize)]
618pub struct RenderReasons(u32);
619
620bitflags! {
621 impl RenderReasons: u32 {
622 const NONE = 0;
624 const SCENE = 1 << 0;
625 const ANIMATED_PROPERTY = 1 << 1;
626 const RESOURCE_UPDATE = 1 << 2;
627 const ASYNC_IMAGE = 1 << 3;
628 const CLEAR_RESOURCES = 1 << 4;
629 const APZ = 1 << 5;
630 const RESIZE = 1 << 6;
632 const WIDGET = 1 << 7;
634 const TEXTURE_CACHE_FLUSH = 1 << 8;
636 const SNAPSHOT = 1 << 9;
637 const POST_RESOURCE_UPDATES_HOOK = 1 << 10;
638 const CONFIG_CHANGE = 1 << 11;
639 const CONTENT_SYNC = 1 << 12;
640 const FLUSH = 1 << 13;
641 const TESTING = 1 << 14;
642 const OTHER = 1 << 15;
643 const VSYNC = 1 << 16;
647 const SKIPPED_COMPOSITE = 1 << 17;
648 const START_OBSERVING_VSYNC = 1 << 18;
651 const ASYNC_IMAGE_COMPOSITE_UNTIL = 1 << 19;
652 }
653}
654
655impl core::fmt::Debug for RenderReasons {
656 fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
657 if self.is_empty() {
658 write!(f, "{:#x}", Self::empty().bits())
659 } else {
660 bitflags::parser::to_writer(self, f)
661 }
662 }
663}
664
665impl RenderReasons {
666 pub const NUM_BITS: u32 = 17;
667}
668
669#[repr(C)]
671#[derive(Copy, PartialEq, Eq, Clone, PartialOrd, Ord, Hash, Default, Deserialize, MallocSizeOf, Serialize)]
672pub struct DebugFlags(u64);
673
674bitflags! {
675 impl DebugFlags: u64 {
676 const PROFILER_DBG = 1 << 0;
678 const RENDER_TARGET_DBG = 1 << 1;
680 const TEXTURE_CACHE_DBG = 1 << 2;
682 const GPU_TIME_QUERIES = 1 << 3;
684 const GPU_SAMPLE_QUERIES = 1 << 4;
688 const DISABLE_BATCHING = 1 << 5;
693 const EPOCHS = 1 << 6;
695 const ECHO_DRIVER_MESSAGES = 1 << 7;
697 const SHOW_OVERDRAW = 1 << 8;
699 const GPU_CACHE_DBG = 1 << 9;
701 const TEXTURE_CACHE_DBG_CLEAR_EVICTED = 1 << 10;
703 const PICTURE_CACHING_DBG = 1 << 11;
705 const PRIMITIVE_DBG = 1 << 12;
707 const ZOOM_DBG = 1 << 13;
709 const SMALL_SCREEN = 1 << 14;
713 const DISABLE_OPAQUE_PASS = 1 << 15;
716 const DISABLE_ALPHA_PASS = 1 << 16;
718 const DISABLE_CLIP_MASKS = 1 << 17;
720 const DISABLE_TEXT_PRIMS = 1 << 18;
722 const DISABLE_GRADIENT_PRIMS = 1 << 19;
724 const OBSCURE_IMAGES = 1 << 20;
726 const GLYPH_FLASHING = 1 << 21;
729 const SMART_PROFILER = 1 << 22;
731 const INVALIDATION_DBG = 1 << 23;
733 const PROFILER_CAPTURE = 1 << 25;
735 const FORCE_PICTURE_INVALIDATION = 1 << 26;
737 const WINDOW_VISIBILITY_DBG = 1 << 27;
739 const RESTRICT_BLOB_SIZE = 1 << 28;
742 const SURFACE_PROMOTION_LOGGING = 1 << 29;
744 const PICTURE_BORDERS = 1 << 30;
746 const MISSING_SNAPSHOT_PANIC = (1 as u64) << 31; const MISSING_SNAPSHOT_PINK = (1 as u64) << 32;
750 const HIGHLIGHT_BACKDROP_FILTERS = (1 as u64) << 33;
752 }
753}
754
755impl core::fmt::Debug for DebugFlags {
756 fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
757 if self.is_empty() {
758 write!(f, "{:#x}", Self::empty().bits())
759 } else {
760 bitflags::parser::to_writer(self, f)
761 }
762 }
763}
764
765#[derive(Debug, Clone, Eq, MallocSizeOf, PartialEq, Hash, Serialize, Deserialize)]
768pub enum PrimitiveKeyKind {
769 Clear,
771 Rectangle {
773 color: PropertyBinding<ColorU>,
775 },
776}
777
778#[derive(Clone, Copy, Debug)]
780pub enum ScrollLocation {
781 Delta(LayoutVector2D),
783 Start,
785 End,
787}
788
789#[repr(C)]
791#[derive(Clone, Copy)]
792pub enum CrashAnnotation {
793 CompileShader = 0,
794 DrawShader = 1,
795}
796
797pub trait CrashAnnotator : Send {
799 fn set(&self, annotation: CrashAnnotation, value: &std::ffi::CStr);
800 fn clear(&self, annotation: CrashAnnotation);
801 fn box_clone(&self) -> Box<dyn CrashAnnotator>;
802}
803
804impl Clone for Box<dyn CrashAnnotator> {
805 fn clone(&self) -> Box<dyn CrashAnnotator> {
806 self.box_clone()
807 }
808}
809
810pub struct CrashAnnotatorGuard<'a> {
812 annotator: &'a Option<Box<dyn CrashAnnotator>>,
813 annotation: CrashAnnotation,
814}
815
816impl<'a> CrashAnnotatorGuard<'a> {
817 pub fn new(
818 annotator: &'a Option<Box<dyn CrashAnnotator>>,
819 annotation: CrashAnnotation,
820 value: &std::ffi::CStr,
821 ) -> Self {
822 if let Some(ref annotator) = annotator {
823 annotator.set(annotation, value);
824 }
825 Self {
826 annotator,
827 annotation,
828 }
829 }
830}
831
832impl<'a> Drop for CrashAnnotatorGuard<'a> {
833 fn drop(&mut self) {
834 if let Some(ref annotator) = self.annotator {
835 annotator.clear(self.annotation);
836 }
837 }
838}