zng_webrender_api/
lib.rs

1/* This Source Code Form is subject to the terms of the Mozilla Public
2 * License, v. 2.0. If a copy of the MPL was not distributed with this
3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
4
5//! The `webrender_api` crate contains an assortment types and functions used
6//! by WebRender consumers as well as, in many cases, WebRender itself.
7//!
8//! This separation allows Servo to parallelize compilation across `webrender`
9//! and other crates that depend on `webrender_api`. So in practice, we put
10//! things in this crate when Servo needs to use them. Firefox depends on the
11//! `webrender` crate directly, and so this distinction is not really relevant
12//! there.
13
14#![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
63/// Defined here for cbindgen
64pub const MAX_RENDER_TASK_SIZE: i32 = 16384;
65
66/// Width and height in device pixels of image tiles.
67pub type TileSize = u16;
68
69/// Various settings that the caller can select based on desired tradeoffs
70/// between rendering quality and performance / power usage.
71#[derive(Copy, Clone, Deserialize, Serialize)]
72pub struct QualitySettings {
73    /// If true, disable creating separate picture cache slices when the
74    /// scroll root changes. This gives maximum opportunity to find an
75    /// opaque background, which enables subpixel AA. However, it is
76    /// usually significantly more expensive to render when scrolling.
77    pub force_subpixel_aa_where_possible: bool,
78}
79
80impl Default for QualitySettings {
81    fn default() -> Self {
82        QualitySettings {
83            // Prefer performance over maximum subpixel AA quality, since WR
84            // already enables subpixel AA in more situations than other browsers.
85            force_subpixel_aa_where_possible: false,
86        }
87    }
88}
89
90/// An epoch identifies the state of a pipeline in time.
91///
92/// This is mostly used as a synchronization mechanism to observe how/when particular pipeline
93/// updates propagate through WebRender and are applied at various stages.
94#[repr(C)]
95#[derive(Clone, Copy, Debug, Deserialize, Eq, Hash, Ord, PartialEq, PartialOrd, Serialize)]
96pub struct Epoch(pub u32);
97
98impl Epoch {
99    /// Magic invalid epoch value.
100    pub fn invalid() -> Epoch {
101        Epoch(u32::MAX)
102    }
103}
104
105/// ID namespaces uniquely identify different users of WebRender's API.
106///
107/// For example in Gecko each content process uses a separate id namespace.
108#[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/// A key uniquely identifying a WebRender document.
114///
115/// Instances can manage one or several documents (using the same render backend thread).
116/// Each document will internally correspond to a single scene, and scenes are made of
117/// one or several pipelines.
118#[repr(C)]
119#[derive(Clone, Copy, Debug, Deserialize, Eq, Hash, MallocSizeOf, PartialEq, Serialize, PeekPoke)]
120pub struct DocumentId {
121    ///
122    pub namespace_id: IdNamespace,
123    ///
124    pub id: u32,
125}
126
127impl DocumentId {
128    ///
129    pub fn new(namespace_id: IdNamespace, id: u32) -> Self {
130        DocumentId {
131            namespace_id,
132            id,
133        }
134    }
135
136    ///
137    pub const INVALID: DocumentId = DocumentId { namespace_id: IdNamespace(0), id: 0 };
138}
139
140/// This type carries no valuable semantics for WR. However, it reflects the fact that
141/// clients (Servo) may generate pipelines by different semi-independent sources.
142/// These pipelines still belong to the same `IdNamespace` and the same `DocumentId`.
143/// Having this extra Id field enables them to generate `PipelineId` without collision.
144pub type PipelineSourceId = u32;
145
146/// From the point of view of WR, `PipelineId` is completely opaque and generic as long as
147/// it's clonable, serializable, comparable, and hashable.
148#[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    ///
160    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    /// Returns a FramePublishId corresponding to the first frame.
173    ///
174    /// Note that we use 0 as the internal id here because the current code
175    /// increments the frame publish id just before ResultMsg::PublishDocument,
176    /// and we want the first id to be 1.
177    pub fn first() -> Self {
178        FramePublishId(0)
179    }
180
181    /// Advances this FramePublishId to the next.
182    pub fn advance(&mut self) {
183        self.0 += 1;
184    }
185
186    /// An invalid sentinel FramePublishId, which will always compare less than
187    /// any valid FrameId.
188    pub const INVALID: Self = FramePublishId(0);
189}
190
191impl Default for FramePublishId {
192    fn default() -> Self {
193        FramePublishId::INVALID
194    }
195}
196
197/// An opaque pointer-sized value.
198#[repr(C)]
199#[derive(Clone)]
200pub struct ExternalEvent {
201    raw: usize,
202}
203
204unsafe impl Send for ExternalEvent {}
205
206impl ExternalEvent {
207    /// Creates the event from an opaque pointer-sized value.
208    pub fn from_raw(raw: usize) -> Self {
209        ExternalEvent { raw }
210    }
211    /// Consumes self to make it obvious that the event should be forwarded only once.
212    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/// A flag in each scrollable frame to represent whether the owner of the frame document
226/// has any scroll-linked effect.
227/// See https://firefox-source-docs.mozilla.org/performance/scroll-linked_effects.html
228/// for a definition of scroll-linked effect.
229#[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  // All rects in local coords relative to the scrolled content's origin.
246  pub visual_viewport: LayoutRect,
247  pub layout_viewport: LayoutRect,
248  pub scrollable_rect: LayoutRect,
249  pub displayport: LayoutRect,
250  // Populated for root content nodes only, otherwise the identity
251  pub zoom_transform: LayoutTransform,
252  // Populated for nodes in the subtree of a root content node
253  // (outside such subtrees we'll have `root_content_scroll_id == 0`).
254  // Stores the enclosing root content node's ExternalScrollId.
255  pub root_content_pipeline_id: PipelineId,
256  pub root_content_scroll_id: u64
257}
258
259/// A handler to integrate WebRender with the thread that contains the `Renderer`.
260pub trait RenderNotifier: Send {
261    ///
262    fn clone(&self) -> Box<dyn RenderNotifier>;
263    /// Wake the thread containing the `Renderer` up (after updates have been put
264    /// in the renderer's queue).
265    fn wake_up(
266        &self,
267        composite_needed: bool,
268    );
269    /// Notify the thread containing the `Renderer` that a new frame is ready.
270    fn new_frame_ready(&self, _: DocumentId, scrolled: bool, composite_needed: bool, frame_publish_id: FramePublishId);
271    /// A Gecko-specific notification mechanism to get some code executed on the
272    /// `Renderer`'s thread, mostly replaced by `NotificationHandler`. You should
273    /// probably use the latter instead.
274    fn external_event(&self, _evt: ExternalEvent) {
275        unimplemented!()
276    }
277    /// Notify the thread containing the `Renderer` that the render backend has been
278    /// shut down.
279    fn shut_down(&self) {}
280}
281
282/// A stage of the rendering pipeline.
283#[repr(u32)]
284#[derive(Copy, Clone, Debug, PartialEq, Eq)]
285pub enum Checkpoint {
286    ///
287    SceneBuilt,
288    ///
289    FrameBuilt,
290    ///
291    FrameTexturesUpdated,
292    ///
293    FrameRendered,
294    /// NotificationRequests get notified with this if they get dropped without having been
295    /// notified. This provides the guarantee that if a request is created it will get notified.
296    TransactionDropped,
297}
298
299/// A handler to notify when a transaction reaches certain stages of the rendering
300/// pipeline.
301pub trait NotificationHandler : Send + Sync {
302    /// Entry point of the handler to implement. Invoked by WebRender.
303    fn notify(&self, when: Checkpoint);
304}
305
306/// A request to notify a handler when the transaction reaches certain stages of the
307/// rendering pipeline.
308///
309/// The request is guaranteed to be notified once and only once, even if the transaction
310/// is dropped before the requested check-point.
311pub struct NotificationRequest {
312    handler: Option<Box<dyn NotificationHandler>>,
313    when: Checkpoint,
314}
315
316impl NotificationRequest {
317    /// Constructor.
318    pub fn new(when: Checkpoint, handler: Box<dyn NotificationHandler>) -> Self {
319        NotificationRequest {
320            handler: Some(handler),
321            when,
322        }
323    }
324
325    /// The specified stage at which point the handler should be notified.
326    pub fn when(&self) -> Checkpoint { self.when }
327
328    /// Called by WebRender at specified stages to notify the registered handler.
329    pub fn notify(mut self) {
330        if let Some(handler) = self.handler.take() {
331            handler.notify(self.when);
332        }
333    }
334}
335
336/// An object that can perform hit-testing without doing synchronous queries to
337/// the RenderBackendThread.
338pub trait ApiHitTester: Send + Sync {
339    /// Does a hit test on display items in the specified document, at the given
340    /// point. The vector of hit results will contain all display items that match,
341    /// ordered from front to back.
342    fn hit_test(&self, point: WorldPoint) -> HitTestResult;
343}
344
345/// A hit tester requested to the render backend thread but not necessarily ready yet.
346///
347/// The request should be resolved as late as possible to reduce the likelihood of blocking.
348pub struct HitTesterRequest {
349    #[doc(hidden)]
350    pub rx: Receiver<Arc<dyn ApiHitTester>>,
351}
352
353impl HitTesterRequest {
354    /// Block until the hit tester is available and return it, consuming teh request.
355    pub fn resolve(self) -> Arc<dyn ApiHitTester> {
356        self.rx.recv().unwrap()
357    }
358}
359
360/// Describe an item that matched a hit-test query.
361#[derive(Clone, Debug, Deserialize, PartialEq, Serialize)]
362pub struct HitTestResultItem {
363    /// The pipeline that the display item that was hit belongs to.
364    pub pipeline: PipelineId,
365
366    /// The tag of the hit display item.
367    pub tag: ItemTag,
368
369    /// The animation id from the stacking context.
370    pub animation_id: u64,
371}
372
373/// Returned by `RenderApi::hit_test`.
374#[derive(Clone, Debug, Default, Deserialize, Serialize)]
375pub struct HitTestResult {
376    /// List of items that are match the hit-test query.
377    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
388// This Clone impl yields an "empty" request because we don't want the requests
389// to be notified twice so the request is owned by only one of the API messages
390// (the original one) after the clone.
391// This works in practice because the notifications requests are used for
392// synchronization so we don't need to include them in the recording mechanism
393// in wrench that clones the messages.
394impl Clone for NotificationRequest {
395    fn clone(&self) -> Self {
396        NotificationRequest {
397            when: self.when,
398            handler: None,
399        }
400    }
401}
402
403
404/// A key to identify an animated property binding.
405#[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    /// Constructor.
414    pub fn new(value: u64) -> Self {
415        PropertyBindingId {
416            namespace: IdNamespace((value >> 32) as u32),
417            uid: value as u32,
418        }
419    }
420
421    /// Decompose the ID back into the raw integer.
422    pub fn to_u64(&self) -> u64 {
423        ((self.namespace.0 as u64) << 32) | self.uid as u64
424    }
425}
426
427/// A unique key that is used for connecting animated property
428/// values to bindings in the display list.
429#[repr(C)]
430#[derive(Clone, Copy, Debug, Default, Deserialize, Eq, Hash, MallocSizeOf, PartialEq, Serialize, PeekPoke)]
431pub struct PropertyBindingKey<T> {
432    ///
433    pub id: PropertyBindingId,
434    #[doc(hidden)]
435    pub _phantom: PhantomData<T>,
436}
437
438/// Construct a property value from a given key and value.
439impl<T: Copy> PropertyBindingKey<T> {
440    ///
441    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    /// Constructor.
454    pub fn new(value: u64) -> Self {
455        PropertyBindingKey {
456            id: PropertyBindingId::new(value),
457            _phantom: PhantomData,
458        }
459    }
460}
461
462/// A binding property can either be a specific value
463/// (the normal, non-animated case) or point to a binding location
464/// to fetch the current value from.
465/// Note that Binding has also a non-animated value, the value is
466/// used for the case where the animation is still in-delay phase
467/// (i.e. the animation doesn't produce any animation values).
468#[repr(C)]
469#[derive(Clone, Copy, Debug, Deserialize, Eq, Hash, MallocSizeOf, PartialEq, Serialize, PeekPoke)]
470pub enum PropertyBinding<T> {
471    /// Non-animated value.
472    Value(T),
473    /// Animated binding.
474    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/// The current value of an animated property. This is
530/// supplied by the calling code.
531#[derive(Clone, Copy, Debug, Deserialize, Serialize, PartialEq)]
532pub struct PropertyValue<T> {
533    ///
534    pub key: PropertyBindingKey<T>,
535    ///
536    pub value: T,
537}
538
539/// When using `generate_frame()`, a list of `PropertyValue` structures
540/// can optionally be supplied to provide the current value of any
541/// animated properties.
542#[derive(Clone, Deserialize, Serialize, Debug, PartialEq, Default)]
543pub struct DynamicProperties {
544    /// transform list
545    pub transforms: Vec<PropertyValue<LayoutTransform>>,
546    /// opacity
547    pub floats: Vec<PropertyValue<f32>>,
548    /// background color
549    pub colors: Vec<PropertyValue<ColorF>>,
550}
551
552impl DynamicProperties {
553    /// Extend the properties.
554    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
561/// A C function that takes a pointer to a heap allocation and returns its size.
562///
563/// This is borrowed from the malloc_size_of crate, upon which we want to avoid
564/// a dependency from WebRender.
565pub type VoidPtrToSizeFn = unsafe extern "C" fn(ptr: *const c_void) -> usize;
566
567/// A configuration option that can be changed at runtime.
568///
569/// # Adding a new configuration option
570///
571///  - Add a new enum variant here.
572///  - Add the entry in WR_BOOL_PARAMETER_LIST in gfxPlatform.cpp.
573///  - React to the parameter change anywhere in WebRender where a SetParam message is received.
574#[derive(Copy, Clone, Debug, PartialEq)]
575pub enum Parameter {
576    Bool(BoolParameter, bool),
577    Int(IntParameter, i32),
578    Float(FloatParameter, f32),
579}
580
581/// Boolean configuration option.
582#[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/// Integer configuration option.
592#[derive(Copy, Clone, Debug, PartialEq, Eq)]
593#[repr(u32)]
594pub enum IntParameter {
595    BatchedUploadThreshold = 0,
596}
597
598/// Floating point configuration option.
599#[derive(Copy, Clone, Debug, PartialEq, Eq)]
600#[repr(u32)]
601pub enum FloatParameter {
602    /// The minimum time for the CPU portion of a frame to be considered slow
603    SlowCpuFrameThreshold = 0,
604}
605
606/// Flags to track why we are rendering.
607#[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        /// Equivalent of empty() for the C++ side.
614        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        /// Window resize
622        const RESIZE                        = 1 << 6;
623        /// Various widget-related reasons
624        const WIDGET                        = 1 << 7;
625        /// See Frame::must_be_drawn
626        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        /// Vsync isn't actually "why" we render but it can be useful
635        /// to see which frames were driven by the vsync scheduler so
636        /// we store a bit for it.
637        const VSYNC                         = 1 << 16;
638        const SKIPPED_COMPOSITE             = 1 << 17;
639        /// Gecko does some special things when it starts observing vsync
640        /// so it can be useful to know what frames are associated with it.
641        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/// Flags to enable/disable various builtin debugging tools.
661#[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        /// Display the frame profiler on screen.
668        const PROFILER_DBG          = 1 << 0;
669        /// Display intermediate render targets on screen.
670        const RENDER_TARGET_DBG     = 1 << 1;
671        /// Display all texture cache pages on screen.
672        const TEXTURE_CACHE_DBG     = 1 << 2;
673        /// Display GPU timing results.
674        const GPU_TIME_QUERIES      = 1 << 3;
675        /// Query the number of pixels that pass the depth test divided and show it
676        /// in the profiler as a percentage of the number of pixels in the screen
677        /// (window width times height).
678        const GPU_SAMPLE_QUERIES    = 1 << 4;
679        /// Render each quad with their own draw call.
680        ///
681        /// Terrible for performance but can help with understanding the drawing
682        /// order when inspecting renderdoc or apitrace recordings.
683        const DISABLE_BATCHING      = 1 << 5;
684        /// Display the pipeline epochs.
685        const EPOCHS                = 1 << 6;
686        /// Print driver messages to stdout.
687        const ECHO_DRIVER_MESSAGES  = 1 << 7;
688        /// Show an overlay displaying overdraw amount.
689        const SHOW_OVERDRAW         = 1 << 8;
690        /// Display the contents of GPU cache.
691        const GPU_CACHE_DBG         = 1 << 9;
692        /// Clear evicted parts of the texture cache for debugging purposes.
693        const TEXTURE_CACHE_DBG_CLEAR_EVICTED = 1 << 10;
694        /// Show picture caching debug overlay
695        const PICTURE_CACHING_DBG   = 1 << 11;
696        /// Highlight all primitives with colors based on kind.
697        const PRIMITIVE_DBG = 1 << 12;
698        /// Draw a zoom widget showing part of the framebuffer zoomed in.
699        const ZOOM_DBG = 1 << 13;
700        /// Scale the debug renderer down for a smaller screen. This will disrupt
701        /// any mapping between debug display items and page content, so shouldn't
702        /// be used with overlays like the picture caching or primitive display.
703        const SMALL_SCREEN = 1 << 14;
704        /// Disable various bits of the WebRender pipeline, to help narrow
705        /// down where slowness might be coming from.
706        const DISABLE_OPAQUE_PASS = 1 << 15;
707        ///
708        const DISABLE_ALPHA_PASS = 1 << 16;
709        ///
710        const DISABLE_CLIP_MASKS = 1 << 17;
711        ///
712        const DISABLE_TEXT_PRIMS = 1 << 18;
713        ///
714        const DISABLE_GRADIENT_PRIMS = 1 << 19;
715        ///
716        const OBSCURE_IMAGES = 1 << 20;
717        /// Taint the transparent area of the glyphs with a random opacity to easily
718        /// see when glyphs are re-rasterized.
719        const GLYPH_FLASHING = 1 << 21;
720        /// The profiler only displays information that is out of the ordinary.
721        const SMART_PROFILER        = 1 << 22;
722        /// If set, dump picture cache invalidation debug to console.
723        const INVALIDATION_DBG = 1 << 23;
724        /// Collect and dump profiler statistics to captures.
725        const PROFILER_CAPTURE = (1 as u32) << 25; // need "as u32" until we have cbindgen#556
726        /// Invalidate picture tiles every frames (useful when inspecting GPU work in external tools).
727        const FORCE_PICTURE_INVALIDATION = (1 as u32) << 26;
728        /// Display window visibility on screen.
729        const WINDOW_VISIBILITY_DBG     = 1 << 27;
730        /// Render large blobs with at a smaller size (incorrectly). This is a temporary workaround for
731        /// fuzzing.
732        const RESTRICT_BLOB_SIZE        = 1 << 28;
733        /// Enable surface promotion logging.
734        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/// Information specific to a primitive type that
749/// uniquely identifies a primitive template by key.
750#[derive(Debug, Clone, Eq, MallocSizeOf, PartialEq, Hash, Serialize, Deserialize)]
751pub enum PrimitiveKeyKind {
752    /// Clear an existing rect, used for special effects on some platforms.
753    Clear,
754    ///
755    Rectangle {
756        ///
757        color: PropertyBinding<ColorU>,
758    },
759}
760
761///
762#[derive(Clone, Copy, Debug)]
763pub enum ScrollLocation {
764    /// Scroll by a certain amount.
765    Delta(LayoutVector2D),
766    /// Scroll to very top of element.
767    Start,
768    /// Scroll to very bottom of element.
769    End,
770}
771
772/// Crash annotations included in crash reports.
773#[repr(C)]
774#[derive(Clone, Copy)]
775pub enum CrashAnnotation {
776    CompileShader = 0,
777    DrawShader = 1,
778}
779
780/// Handler to expose support for annotating crash reports.
781pub 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
793/// Guard to add a crash annotation at creation, and clear it at destruction.
794pub 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}