1#![cfg_attr(feature = "nightly", feature(nonzero))]
15#![allow(clippy::float_cmp, clippy::too_many_arguments)]
16#![allow(clippy::unreadable_literal, clippy::new_without_default)]
17
18pub extern crate crossbeam_channel;
19pub extern crate euclid;
20
21extern crate app_units;
22#[macro_use]
23extern crate bitflags;
24extern crate byteorder;
25#[cfg(feature = "nightly")]
26extern crate core;
27#[macro_use]
28extern crate malloc_size_of_derive;
29extern crate serde;
30#[macro_use]
31extern crate serde_derive;
32
33extern crate malloc_size_of;
34extern crate peek_poke;
35
36pub mod channel;
37mod color;
38mod display_item;
39mod display_item_cache;
40mod display_list;
41mod font;
42mod gradient_builder;
43mod image;
44mod tile_pool;
45pub mod units;
46
47pub use crate::color::*;
48pub use crate::display_item::*;
49pub use crate::display_item_cache::DisplayItemCache;
50pub use crate::display_list::*;
51pub use crate::font::*;
52pub use crate::gradient_builder::*;
53pub use crate::image::*;
54pub use crate::tile_pool::*;
55
56use crate::units::*;
57use crate::channel::Receiver;
58use std::marker::PhantomData;
59use std::sync::Arc;
60use std::os::raw::c_void;
61use peek_poke::PeekPoke;
62
63pub const MAX_RENDER_TASK_SIZE: i32 = 16384;
65
66pub type TileSize = u16;
68
69#[derive(Copy, Clone, Deserialize, Serialize)]
72pub struct QualitySettings {
73 pub force_subpixel_aa_where_possible: bool,
78}
79
80impl Default for QualitySettings {
81 fn default() -> Self {
82 QualitySettings {
83 force_subpixel_aa_where_possible: false,
86 }
87 }
88}
89
90#[repr(C)]
95#[derive(Clone, Copy, Debug, Deserialize, Eq, Hash, Ord, PartialEq, PartialOrd, Serialize)]
96pub struct Epoch(pub u32);
97
98impl Epoch {
99 pub fn invalid() -> Epoch {
101 Epoch(u32::MAX)
102 }
103}
104
105#[repr(C)]
109#[derive(Clone, Copy, Debug, Default, Eq, MallocSizeOf, PartialEq, Hash, Ord, PartialOrd, PeekPoke)]
110#[derive(Deserialize, Serialize)]
111pub struct IdNamespace(pub u32);
112
113#[repr(C)]
119#[derive(Clone, Copy, Debug, Deserialize, Eq, Hash, MallocSizeOf, PartialEq, Serialize, PeekPoke)]
120pub struct DocumentId {
121 pub namespace_id: IdNamespace,
123 pub id: u32,
125}
126
127impl DocumentId {
128 pub fn new(namespace_id: IdNamespace, id: u32) -> Self {
130 DocumentId {
131 namespace_id,
132 id,
133 }
134 }
135
136 pub const INVALID: DocumentId = DocumentId { namespace_id: IdNamespace(0), id: 0 };
138}
139
140pub type PipelineSourceId = u32;
145
146#[repr(C)]
149#[derive(Clone, Copy, Debug, Deserialize, Eq, Hash, MallocSizeOf, PartialEq, Serialize, PeekPoke)]
150pub struct PipelineId(pub PipelineSourceId, pub u32);
151
152impl Default for PipelineId {
153 fn default() -> Self {
154 PipelineId::dummy()
155 }
156}
157
158impl PipelineId {
159 pub fn dummy() -> Self {
161 PipelineId(!0, !0)
162 }
163
164 pub const INVALID: Self = PipelineId(!0, !0);
165}
166
167#[repr(C)]
168#[derive(Clone, Copy, Debug, PartialEq, PartialOrd)]
169pub struct FramePublishId(pub u64);
170
171impl FramePublishId {
172 pub fn first() -> Self {
178 FramePublishId(0)
179 }
180
181 pub fn advance(&mut self) {
183 self.0 += 1;
184 }
185
186 pub const INVALID: Self = FramePublishId(0);
189}
190
191impl Default for FramePublishId {
192 fn default() -> Self {
193 FramePublishId::INVALID
194 }
195}
196
197#[repr(C)]
199#[derive(Clone)]
200pub struct ExternalEvent {
201 raw: usize,
202}
203
204unsafe impl Send for ExternalEvent {}
205
206impl ExternalEvent {
207 pub fn from_raw(raw: usize) -> Self {
209 ExternalEvent { raw }
210 }
211 pub fn unwrap(self) -> usize {
213 self.raw
214 }
215}
216
217pub type APZScrollGeneration = u64;
218#[repr(C)]
219#[derive(Clone, Copy, Debug, Deserialize, PartialEq, Serialize, Default)]
220pub struct SampledScrollOffset {
221 pub offset: LayoutVector2D,
222 pub generation: APZScrollGeneration,
223}
224
225#[repr(u8)]
230#[derive(Clone, Copy, Debug, Deserialize, PartialEq, Serialize, PeekPoke)]
231pub enum HasScrollLinkedEffect {
232 Yes,
233 No,
234}
235
236impl Default for HasScrollLinkedEffect {
237 fn default() -> Self {
238 HasScrollLinkedEffect::No
239 }
240}
241
242#[repr(C)]
243pub struct MinimapData {
244 pub is_root_content: bool,
245 pub visual_viewport: LayoutRect,
247 pub layout_viewport: LayoutRect,
248 pub scrollable_rect: LayoutRect,
249 pub displayport: LayoutRect,
250 pub zoom_transform: LayoutTransform,
252 pub root_content_pipeline_id: PipelineId,
256 pub root_content_scroll_id: u64
257}
258
259pub trait RenderNotifier: Send {
261 fn clone(&self) -> Box<dyn RenderNotifier>;
263 fn wake_up(
266 &self,
267 composite_needed: bool,
268 );
269 fn new_frame_ready(&self, _: DocumentId, scrolled: bool, composite_needed: bool, frame_publish_id: FramePublishId);
271 fn external_event(&self, _evt: ExternalEvent) {
275 unimplemented!()
276 }
277 fn shut_down(&self) {}
280}
281
282#[repr(u32)]
284#[derive(Copy, Clone, Debug, PartialEq, Eq)]
285pub enum Checkpoint {
286 SceneBuilt,
288 FrameBuilt,
290 FrameTexturesUpdated,
292 FrameRendered,
294 TransactionDropped,
297}
298
299pub trait NotificationHandler : Send + Sync {
302 fn notify(&self, when: Checkpoint);
304}
305
306pub struct NotificationRequest {
312 handler: Option<Box<dyn NotificationHandler>>,
313 when: Checkpoint,
314}
315
316impl NotificationRequest {
317 pub fn new(when: Checkpoint, handler: Box<dyn NotificationHandler>) -> Self {
319 NotificationRequest {
320 handler: Some(handler),
321 when,
322 }
323 }
324
325 pub fn when(&self) -> Checkpoint { self.when }
327
328 pub fn notify(mut self) {
330 if let Some(handler) = self.handler.take() {
331 handler.notify(self.when);
332 }
333 }
334}
335
336pub trait ApiHitTester: Send + Sync {
339 fn hit_test(&self, point: WorldPoint) -> HitTestResult;
343}
344
345pub struct HitTesterRequest {
349 #[doc(hidden)]
350 pub rx: Receiver<Arc<dyn ApiHitTester>>,
351}
352
353impl HitTesterRequest {
354 pub fn resolve(self) -> Arc<dyn ApiHitTester> {
356 self.rx.recv().unwrap()
357 }
358}
359
360#[derive(Clone, Debug, Deserialize, PartialEq, Serialize)]
362pub struct HitTestResultItem {
363 pub pipeline: PipelineId,
365
366 pub tag: ItemTag,
368
369 pub animation_id: u64,
371}
372
373#[derive(Clone, Debug, Default, Deserialize, Serialize)]
375pub struct HitTestResult {
376 pub items: Vec<HitTestResultItem>,
378}
379
380impl Drop for NotificationRequest {
381 fn drop(&mut self) {
382 if let Some(ref mut handler) = self.handler {
383 handler.notify(Checkpoint::TransactionDropped);
384 }
385 }
386}
387
388impl Clone for NotificationRequest {
395 fn clone(&self) -> Self {
396 NotificationRequest {
397 when: self.when,
398 handler: None,
399 }
400 }
401}
402
403
404#[repr(C)]
406#[derive(Clone, Copy, Debug, Default, Deserialize, MallocSizeOf, PartialEq, Serialize, Eq, Hash, PeekPoke)]
407pub struct PropertyBindingId {
408 pub namespace: IdNamespace,
409 pub uid: u32,
410}
411
412impl PropertyBindingId {
413 pub fn new(value: u64) -> Self {
415 PropertyBindingId {
416 namespace: IdNamespace((value >> 32) as u32),
417 uid: value as u32,
418 }
419 }
420
421 pub fn to_u64(&self) -> u64 {
423 ((self.namespace.0 as u64) << 32) | self.uid as u64
424 }
425}
426
427#[repr(C)]
430#[derive(Clone, Copy, Debug, Default, Deserialize, Eq, Hash, MallocSizeOf, PartialEq, Serialize, PeekPoke)]
431pub struct PropertyBindingKey<T> {
432 pub id: PropertyBindingId,
434 #[doc(hidden)]
435 pub _phantom: PhantomData<T>,
436}
437
438impl<T: Copy> PropertyBindingKey<T> {
440 pub fn with(self, value: T) -> PropertyValue<T> {
442 PropertyValue { key: self, value }
443 }
444}
445
446impl<T> Into<u64> for PropertyBindingKey<T> {
447 fn into(self) -> u64 {
448 self.id.to_u64()
449 }
450}
451
452impl<T> PropertyBindingKey<T> {
453 pub fn new(value: u64) -> Self {
455 PropertyBindingKey {
456 id: PropertyBindingId::new(value),
457 _phantom: PhantomData,
458 }
459 }
460}
461
462#[repr(C)]
469#[derive(Clone, Copy, Debug, Deserialize, Eq, Hash, MallocSizeOf, PartialEq, Serialize, PeekPoke)]
470pub enum PropertyBinding<T> {
471 Value(T),
473 Binding(PropertyBindingKey<T>, T),
475}
476
477impl<T: Default> Default for PropertyBinding<T> {
478 fn default() -> Self {
479 PropertyBinding::Value(Default::default())
480 }
481}
482
483impl<T> From<T> for PropertyBinding<T> {
484 fn from(value: T) -> PropertyBinding<T> {
485 PropertyBinding::Value(value)
486 }
487}
488
489impl From<PropertyBindingKey<ColorF>> for PropertyBindingKey<ColorU> {
490 fn from(key: PropertyBindingKey<ColorF>) -> PropertyBindingKey<ColorU> {
491 PropertyBindingKey {
492 id: key.id.clone(),
493 _phantom: PhantomData,
494 }
495 }
496}
497
498impl From<PropertyBindingKey<ColorU>> for PropertyBindingKey<ColorF> {
499 fn from(key: PropertyBindingKey<ColorU>) -> PropertyBindingKey<ColorF> {
500 PropertyBindingKey {
501 id: key.id.clone(),
502 _phantom: PhantomData,
503 }
504 }
505}
506
507impl From<PropertyBinding<ColorF>> for PropertyBinding<ColorU> {
508 fn from(value: PropertyBinding<ColorF>) -> PropertyBinding<ColorU> {
509 match value {
510 PropertyBinding::Value(value) => PropertyBinding::Value(value.into()),
511 PropertyBinding::Binding(k, v) => {
512 PropertyBinding::Binding(k.into(), v.into())
513 }
514 }
515 }
516}
517
518impl From<PropertyBinding<ColorU>> for PropertyBinding<ColorF> {
519 fn from(value: PropertyBinding<ColorU>) -> PropertyBinding<ColorF> {
520 match value {
521 PropertyBinding::Value(value) => PropertyBinding::Value(value.into()),
522 PropertyBinding::Binding(k, v) => {
523 PropertyBinding::Binding(k.into(), v.into())
524 }
525 }
526 }
527}
528
529#[derive(Clone, Copy, Debug, Deserialize, Serialize, PartialEq)]
532pub struct PropertyValue<T> {
533 pub key: PropertyBindingKey<T>,
535 pub value: T,
537}
538
539#[derive(Clone, Deserialize, Serialize, Debug, PartialEq, Default)]
543pub struct DynamicProperties {
544 pub transforms: Vec<PropertyValue<LayoutTransform>>,
546 pub floats: Vec<PropertyValue<f32>>,
548 pub colors: Vec<PropertyValue<ColorF>>,
550}
551
552impl DynamicProperties {
553 pub fn extend(&mut self, other: Self) {
555 self.transforms.extend(other.transforms);
556 self.floats.extend(other.floats);
557 self.colors.extend(other.colors);
558 }
559}
560
561pub type VoidPtrToSizeFn = unsafe extern "C" fn(ptr: *const c_void) -> usize;
566
567#[derive(Copy, Clone, Debug, PartialEq)]
575pub enum Parameter {
576 Bool(BoolParameter, bool),
577 Int(IntParameter, i32),
578 Float(FloatParameter, f32),
579}
580
581#[derive(Copy, Clone, Debug, PartialEq, Eq)]
583#[repr(u32)]
584pub enum BoolParameter {
585 PboUploads = 0,
586 Multithreading = 1,
587 BatchedUploads = 2,
588 DrawCallsForTextureCopy = 3,
589}
590
591#[derive(Copy, Clone, Debug, PartialEq, Eq)]
593#[repr(u32)]
594pub enum IntParameter {
595 BatchedUploadThreshold = 0,
596}
597
598#[derive(Copy, Clone, Debug, PartialEq, Eq)]
600#[repr(u32)]
601pub enum FloatParameter {
602 SlowCpuFrameThreshold = 0,
604}
605
606#[repr(C)]
608#[derive(Copy, PartialEq, Eq, Clone, PartialOrd, Ord, Hash, Default, Deserialize, MallocSizeOf, Serialize)]
609pub struct RenderReasons(u32);
610
611bitflags! {
612 impl RenderReasons: u32 {
613 const NONE = 0;
615 const SCENE = 1 << 0;
616 const ANIMATED_PROPERTY = 1 << 1;
617 const RESOURCE_UPDATE = 1 << 2;
618 const ASYNC_IMAGE = 1 << 3;
619 const CLEAR_RESOURCES = 1 << 4;
620 const APZ = 1 << 5;
621 const RESIZE = 1 << 6;
623 const WIDGET = 1 << 7;
625 const TEXTURE_CACHE_FLUSH = 1 << 8;
627 const SNAPSHOT = 1 << 9;
628 const POST_RESOURCE_UPDATES_HOOK = 1 << 10;
629 const CONFIG_CHANGE = 1 << 11;
630 const CONTENT_SYNC = 1 << 12;
631 const FLUSH = 1 << 13;
632 const TESTING = 1 << 14;
633 const OTHER = 1 << 15;
634 const VSYNC = 1 << 16;
638 const SKIPPED_COMPOSITE = 1 << 17;
639 const START_OBSERVING_VSYNC = 1 << 18;
642 const ASYNC_IMAGE_COMPOSITE_UNTIL = 1 << 19;
643 }
644}
645
646impl core::fmt::Debug for RenderReasons {
647 fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
648 if self.is_empty() {
649 write!(f, "{:#x}", Self::empty().bits())
650 } else {
651 bitflags::parser::to_writer(self, f)
652 }
653 }
654}
655
656impl RenderReasons {
657 pub const NUM_BITS: u32 = 17;
658}
659
660#[repr(C)]
662#[derive(Copy, PartialEq, Eq, Clone, PartialOrd, Ord, Hash, Default, Deserialize, MallocSizeOf, Serialize)]
663pub struct DebugFlags(u32);
664
665bitflags! {
666 impl DebugFlags: u32 {
667 const PROFILER_DBG = 1 << 0;
669 const RENDER_TARGET_DBG = 1 << 1;
671 const TEXTURE_CACHE_DBG = 1 << 2;
673 const GPU_TIME_QUERIES = 1 << 3;
675 const GPU_SAMPLE_QUERIES = 1 << 4;
679 const DISABLE_BATCHING = 1 << 5;
684 const EPOCHS = 1 << 6;
686 const ECHO_DRIVER_MESSAGES = 1 << 7;
688 const SHOW_OVERDRAW = 1 << 8;
690 const GPU_CACHE_DBG = 1 << 9;
692 const TEXTURE_CACHE_DBG_CLEAR_EVICTED = 1 << 10;
694 const PICTURE_CACHING_DBG = 1 << 11;
696 const PRIMITIVE_DBG = 1 << 12;
698 const ZOOM_DBG = 1 << 13;
700 const SMALL_SCREEN = 1 << 14;
704 const DISABLE_OPAQUE_PASS = 1 << 15;
707 const DISABLE_ALPHA_PASS = 1 << 16;
709 const DISABLE_CLIP_MASKS = 1 << 17;
711 const DISABLE_TEXT_PRIMS = 1 << 18;
713 const DISABLE_GRADIENT_PRIMS = 1 << 19;
715 const OBSCURE_IMAGES = 1 << 20;
717 const GLYPH_FLASHING = 1 << 21;
720 const SMART_PROFILER = 1 << 22;
722 const INVALIDATION_DBG = 1 << 23;
724 const PROFILER_CAPTURE = (1 as u32) << 25; const FORCE_PICTURE_INVALIDATION = (1 as u32) << 26;
728 const WINDOW_VISIBILITY_DBG = 1 << 27;
730 const RESTRICT_BLOB_SIZE = 1 << 28;
733 const SURFACE_PROMOTION_LOGGING = 1 << 29;
735 }
736}
737
738impl core::fmt::Debug for DebugFlags {
739 fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
740 if self.is_empty() {
741 write!(f, "{:#x}", Self::empty().bits())
742 } else {
743 bitflags::parser::to_writer(self, f)
744 }
745 }
746}
747
748#[derive(Debug, Clone, Eq, MallocSizeOf, PartialEq, Hash, Serialize, Deserialize)]
751pub enum PrimitiveKeyKind {
752 Clear,
754 Rectangle {
756 color: PropertyBinding<ColorU>,
758 },
759}
760
761#[derive(Clone, Copy, Debug)]
763pub enum ScrollLocation {
764 Delta(LayoutVector2D),
766 Start,
768 End,
770}
771
772#[repr(C)]
774#[derive(Clone, Copy)]
775pub enum CrashAnnotation {
776 CompileShader = 0,
777 DrawShader = 1,
778}
779
780pub trait CrashAnnotator : Send {
782 fn set(&self, annotation: CrashAnnotation, value: &std::ffi::CStr);
783 fn clear(&self, annotation: CrashAnnotation);
784 fn box_clone(&self) -> Box<dyn CrashAnnotator>;
785}
786
787impl Clone for Box<dyn CrashAnnotator> {
788 fn clone(&self) -> Box<dyn CrashAnnotator> {
789 self.box_clone()
790 }
791}
792
793pub struct CrashAnnotatorGuard<'a> {
795 annotator: &'a Option<Box<dyn CrashAnnotator>>,
796 annotation: CrashAnnotation,
797}
798
799impl<'a> CrashAnnotatorGuard<'a> {
800 pub fn new(
801 annotator: &'a Option<Box<dyn CrashAnnotator>>,
802 annotation: CrashAnnotation,
803 value: &std::ffi::CStr,
804 ) -> Self {
805 if let Some(ref annotator) = annotator {
806 annotator.set(annotation, value);
807 }
808 Self {
809 annotator,
810 annotation,
811 }
812 }
813}
814
815impl<'a> Drop for CrashAnnotatorGuard<'a> {
816 fn drop(&mut self) {
817 if let Some(ref annotator) = self.annotator {
818 annotator.clear(self.annotation);
819 }
820 }
821}