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(
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
74/// Defined here for cbindgen
75pub const MAX_RENDER_TASK_SIZE: i32 = 16384;
76
77/// Width and height in device pixels of image tiles.
78pub type TileSize = u16;
79
80/// Various settings that the caller can select based on desired tradeoffs
81/// between rendering quality and performance / power usage.
82#[derive(Copy, Clone, Deserialize, Serialize)]
83pub struct QualitySettings {
84    /// If true, disable creating separate picture cache slices when the
85    /// scroll root changes. This gives maximum opportunity to find an
86    /// opaque background, which enables subpixel AA. However, it is
87    /// usually significantly more expensive to render when scrolling.
88    pub force_subpixel_aa_where_possible: bool,
89}
90
91impl Default for QualitySettings {
92    fn default() -> Self {
93        QualitySettings {
94            // Prefer performance over maximum subpixel AA quality, since WR
95            // already enables subpixel AA in more situations than other browsers.
96            force_subpixel_aa_where_possible: false,
97        }
98    }
99}
100
101/// An epoch identifies the state of a pipeline in time.
102///
103/// This is mostly used as a synchronization mechanism to observe how/when particular pipeline
104/// updates propagate through WebRender and are applied at various stages.
105#[repr(C)]
106#[derive(Clone, Copy, Debug, Deserialize, Eq, Hash, MallocSizeOf, Ord, PartialEq, PartialOrd, Serialize)]
107pub struct Epoch(pub u32);
108
109impl Epoch {
110    /// Magic invalid epoch value.
111    pub fn invalid() -> Epoch {
112        Epoch(u32::MAX)
113    }
114}
115
116/// ID namespaces uniquely identify different users of WebRender's API.
117///
118/// For example in Gecko each content process uses a separate id namespace.
119#[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/// A key uniquely identifying a WebRender document.
129///
130/// Instances can manage one or several documents (using the same render backend thread).
131/// Each document will internally correspond to a single scene, and scenes are made of
132/// one or several pipelines.
133#[repr(C)]
134#[derive(Clone, Copy, Debug, Deserialize, Eq, Hash, MallocSizeOf, PartialEq, Serialize, PeekPoke)]
135pub struct DocumentId {
136    ///
137    pub namespace_id: IdNamespace,
138    ///
139    pub id: u32,
140}
141
142impl DocumentId {
143    ///
144    pub fn new(namespace_id: IdNamespace, id: u32) -> Self {
145        DocumentId {
146            namespace_id,
147            id,
148        }
149    }
150
151    ///
152    pub const INVALID: DocumentId = DocumentId { namespace_id: IdNamespace(0), id: 0 };
153}
154
155/// This type carries no valuable semantics for WR. However, it reflects the fact that
156/// clients (Servo) may generate pipelines by different semi-independent sources.
157/// These pipelines still belong to the same `IdNamespace` and the same `DocumentId`.
158/// Having this extra Id field enables them to generate `PipelineId` without collision.
159pub type PipelineSourceId = u32;
160
161/// From the point of view of WR, `PipelineId` is completely opaque and generic as long as
162/// it's clonable, serializable, comparable, and hashable.
163#[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    ///
175    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    /// Returns a FramePublishId corresponding to the first frame.
188    ///
189    /// Note that we use 0 as the internal id here because the current code
190    /// increments the frame publish id just before ResultMsg::PublishDocument,
191    /// and we want the first id to be 1.
192    pub fn first() -> Self {
193        FramePublishId(0)
194    }
195
196    /// Advances this FramePublishId to the next.
197    pub fn advance(&mut self) {
198        self.0 += 1;
199    }
200
201    /// An invalid sentinel FramePublishId, which will always compare less than
202    /// any valid FrameId.
203    pub const INVALID: Self = FramePublishId(0);
204}
205
206impl Default for FramePublishId {
207    fn default() -> Self {
208        FramePublishId::INVALID
209    }
210}
211
212/// An opaque pointer-sized value.
213#[repr(C)]
214#[derive(Clone)]
215pub struct ExternalEvent {
216    raw: usize,
217}
218
219unsafe impl Send for ExternalEvent {}
220
221impl ExternalEvent {
222    /// Creates the event from an opaque pointer-sized value.
223    pub fn from_raw(raw: usize) -> Self {
224        ExternalEvent { raw }
225    }
226    /// Consumes self to make it obvious that the event should be forwarded only once.
227    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/// A flag in each scrollable frame to represent whether the owner of the frame document
241/// has any scroll-linked effect.
242/// See https://firefox-source-docs.mozilla.org/performance/scroll-linked_effects.html
243/// for a definition of scroll-linked effect.
244#[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  // All rects in local coords relative to the scrolled content's origin.
256  pub visual_viewport: LayoutRect,
257  pub layout_viewport: LayoutRect,
258  pub scrollable_rect: LayoutRect,
259  pub displayport: LayoutRect,
260  // Populated for root content nodes only, otherwise the identity
261  pub zoom_transform: LayoutTransform,
262  // Populated for nodes in the subtree of a root content node
263  // (outside such subtrees we'll have `root_content_scroll_id == 0`).
264  // Stores the enclosing root content node's ExternalScrollId.
265  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    /// Firefox uses this to indicate that the frame does not participate
275    /// in the frame throttling mechanism.
276    /// Frames from off-screen transactions are not tracked.
277    pub tracked: bool,
278}
279
280/// A handler to integrate WebRender with the thread that contains the `Renderer`.
281pub trait RenderNotifier: Send {
282    ///
283    fn clone(&self) -> Box<dyn RenderNotifier>;
284    /// Wake the thread containing the `Renderer` up (after updates have been put
285    /// in the renderer's queue).
286    fn wake_up(
287        &self,
288        composite_needed: bool,
289    );
290    /// Notify the thread containing the `Renderer` that a new frame is ready.
291    fn new_frame_ready(&self, _: DocumentId, publish_id: FramePublishId, params: &FrameReadyParams);
292    /// A Gecko-specific notification mechanism to get some code executed on the
293    /// `Renderer`'s thread, mostly replaced by `NotificationHandler`. You should
294    /// probably use the latter instead.
295    fn external_event(&self, _evt: ExternalEvent) {
296        unimplemented!()
297    }
298    /// Notify the thread containing the `Renderer` that the render backend has been
299    /// shut down.
300    fn shut_down(&self) {}
301}
302
303/// A stage of the rendering pipeline.
304#[repr(u32)]
305#[derive(Copy, Clone, Debug, PartialEq, Eq)]
306pub enum Checkpoint {
307    ///
308    SceneBuilt,
309    ///
310    FrameBuilt,
311    ///
312    FrameTexturesUpdated,
313    ///
314    FrameRendered,
315    /// NotificationRequests get notified with this if they get dropped without having been
316    /// notified. This provides the guarantee that if a request is created it will get notified.
317    TransactionDropped,
318}
319
320/// A handler to notify when a transaction reaches certain stages of the rendering
321/// pipeline.
322pub trait NotificationHandler : Send + Sync {
323    /// Entry point of the handler to implement. Invoked by WebRender.
324    fn notify(&self, when: Checkpoint);
325}
326
327/// A request to notify a handler when the transaction reaches certain stages of the
328/// rendering pipeline.
329///
330/// The request is guaranteed to be notified once and only once, even if the transaction
331/// is dropped before the requested check-point.
332pub struct NotificationRequest {
333    handler: Option<Box<dyn NotificationHandler>>,
334    when: Checkpoint,
335}
336
337impl NotificationRequest {
338    /// Constructor.
339    pub fn new(when: Checkpoint, handler: Box<dyn NotificationHandler>) -> Self {
340        NotificationRequest {
341            handler: Some(handler),
342            when,
343        }
344    }
345
346    /// The specified stage at which point the handler should be notified.
347    pub fn when(&self) -> Checkpoint { self.when }
348
349    /// Called by WebRender at specified stages to notify the registered handler.
350    pub fn notify(mut self) {
351        if let Some(handler) = self.handler.take() {
352            handler.notify(self.when);
353        }
354    }
355}
356
357/// An object that can perform hit-testing without doing synchronous queries to
358/// the RenderBackendThread.
359pub trait ApiHitTester: Send + Sync {
360    /// Does a hit test on display items in the specified document, at the given
361    /// point. The vector of hit results will contain all display items that match,
362    /// ordered from front to back.
363    fn hit_test(&self, point: WorldPoint) -> HitTestResult;
364}
365
366/// A hit tester requested to the render backend thread but not necessarily ready yet.
367///
368/// The request should be resolved as late as possible to reduce the likelihood of blocking.
369pub struct HitTesterRequest {
370    #[doc(hidden)]
371    pub rx: Receiver<Arc<dyn ApiHitTester>>,
372}
373
374impl HitTesterRequest {
375    /// Block until the hit tester is available and return it, consuming teh request.
376    pub fn resolve(self) -> Arc<dyn ApiHitTester> {
377        self.rx.recv().unwrap()
378    }
379}
380
381/// Describe an item that matched a hit-test query.
382#[derive(Clone, Debug, Deserialize, PartialEq, Serialize)]
383pub struct HitTestResultItem {
384    /// The pipeline that the display item that was hit belongs to.
385    pub pipeline: PipelineId,
386
387    /// The tag of the hit display item.
388    pub tag: ItemTag,
389
390    /// The animation id from the stacking context.
391    pub animation_id: u64,
392
393    /// The hit point in the coordinate space of the "viewport" of the display item. The
394    /// viewport is the scroll node formed by the root reference frame of the display item's
395    /// pipeline.
396    pub point_in_viewport: LayoutPoint,
397}
398
399/// Returned by `RenderApi::hit_test`.
400#[derive(Clone, Debug, Default, Deserialize, Serialize)]
401pub struct HitTestResult {
402    /// List of items that are match the hit-test query.
403    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
414// This Clone impl yields an "empty" request because we don't want the requests
415// to be notified twice so the request is owned by only one of the API messages
416// (the original one) after the clone.
417// This works in practice because the notifications requests are used for
418// synchronization so we don't need to include them in the recording mechanism
419// in wrench that clones the messages.
420impl Clone for NotificationRequest {
421    fn clone(&self) -> Self {
422        NotificationRequest {
423            when: self.when,
424            handler: None,
425        }
426    }
427}
428
429
430/// A key to identify an animated property binding.
431#[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    /// Constructor.
440    pub fn new(value: u64) -> Self {
441        PropertyBindingId {
442            namespace: IdNamespace((value >> 32) as u32),
443            uid: value as u32,
444        }
445    }
446
447    /// Decompose the ID back into the raw integer.
448    pub fn to_u64(&self) -> u64 {
449        ((self.namespace.0 as u64) << 32) | self.uid as u64
450    }
451}
452
453/// A unique key that is used for connecting animated property
454/// values to bindings in the display list.
455#[repr(C)]
456#[derive(Clone, Copy, Debug, Default, Deserialize, Eq, Hash, MallocSizeOf, PartialEq, Serialize, PeekPoke)]
457pub struct PropertyBindingKey<T> {
458    ///
459    pub id: PropertyBindingId,
460    #[doc(hidden)]
461    pub _phantom: PhantomData<T>,
462}
463
464/// Construct a property value from a given key and value.
465impl<T: Copy> PropertyBindingKey<T> {
466    ///
467    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    /// Constructor.
480    pub fn new(value: u64) -> Self {
481        PropertyBindingKey {
482            id: PropertyBindingId::new(value),
483            _phantom: PhantomData,
484        }
485    }
486}
487
488/// A binding property can either be a specific value
489/// (the normal, non-animated case) or point to a binding location
490/// to fetch the current value from.
491/// Note that Binding has also a non-animated value, the value is
492/// used for the case where the animation is still in-delay phase
493/// (i.e. the animation doesn't produce any animation values).
494#[repr(C)]
495#[derive(Clone, Copy, Debug, Deserialize, Eq, Hash, MallocSizeOf, PartialEq, Serialize, PeekPoke)]
496pub enum PropertyBinding<T> {
497    /// Non-animated value.
498    Value(T),
499    /// Animated binding.
500    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/// The current value of an animated property. This is
556/// supplied by the calling code.
557#[derive(Clone, Copy, Debug, Deserialize, Serialize, PartialEq)]
558pub struct PropertyValue<T> {
559    ///
560    pub key: PropertyBindingKey<T>,
561    ///
562    pub value: T,
563}
564
565/// When using `generate_frame()`, a list of `PropertyValue` structures
566/// can optionally be supplied to provide the current value of any
567/// animated properties.
568#[derive(Clone, Deserialize, Serialize, Debug, PartialEq, Default)]
569pub struct DynamicProperties {
570    /// transform list
571    pub transforms: Vec<PropertyValue<LayoutTransform>>,
572    /// opacity
573    pub floats: Vec<PropertyValue<f32>>,
574    /// background color
575    pub colors: Vec<PropertyValue<ColorF>>,
576}
577
578impl DynamicProperties {
579    /// Extend the properties.
580    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
587/// A C function that takes a pointer to a heap allocation and returns its size.
588///
589/// This is borrowed from the malloc_size_of crate, upon which we want to avoid
590/// a dependency from WebRender.
591pub type VoidPtrToSizeFn = unsafe extern "C" fn(ptr: *const c_void) -> usize;
592
593/// A configuration option that can be changed at runtime.
594///
595/// # Adding a new configuration option
596///
597///  - Add a new enum variant here.
598///  - Add the entry in WR_BOOL_PARAMETER_LIST in gfxPlatform.cpp.
599///  - React to the parameter change anywhere in WebRender where a SetParam message is received.
600#[derive(Copy, Clone, Debug, PartialEq)]
601pub enum Parameter {
602    Bool(BoolParameter, bool),
603    Int(IntParameter, i32),
604    Float(FloatParameter, f32),
605}
606
607/// Boolean configuration option.
608#[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/// Integer configuration option.
618#[derive(Copy, Clone, Debug, PartialEq, Eq)]
619#[repr(u32)]
620pub enum IntParameter {
621    BatchedUploadThreshold = 0,
622}
623
624/// Floating point configuration option.
625#[derive(Copy, Clone, Debug, PartialEq, Eq)]
626#[repr(u32)]
627pub enum FloatParameter {
628    /// The minimum time for the CPU portion of a frame to be considered slow
629    SlowCpuFrameThreshold = 0,
630}
631
632/// Flags to track why we are rendering.
633#[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        /// Equivalent of empty() for the C++ side.
640        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        /// Window resize
648        const RESIZE                        = 1 << 6;
649        /// Various widget-related reasons
650        const WIDGET                        = 1 << 7;
651        /// See Frame::must_be_drawn
652        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        /// Vsync isn't actually "why" we render but it can be useful
661        /// to see which frames were driven by the vsync scheduler so
662        /// we store a bit for it.
663        const VSYNC                         = 1 << 16;
664        const SKIPPED_COMPOSITE             = 1 << 17;
665        /// Gecko does some special things when it starts observing vsync
666        /// so it can be useful to know what frames are associated with it.
667        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/// Flags to enable/disable various builtin debugging tools.
687#[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        /// Display the frame profiler on screen.
694        const PROFILER_DBG          = 1 << 0;
695        /// Display intermediate render targets on screen.
696        const RENDER_TARGET_DBG     = 1 << 1;
697        /// Display all texture cache pages on screen.
698        const TEXTURE_CACHE_DBG     = 1 << 2;
699        /// Display GPU timing results.
700        const GPU_TIME_QUERIES      = 1 << 3;
701        /// Query the number of pixels that pass the depth test divided and show it
702        /// in the profiler as a percentage of the number of pixels in the screen
703        /// (window width times height).
704        const GPU_SAMPLE_QUERIES    = 1 << 4;
705        /// Render each quad with their own draw call.
706        ///
707        /// Terrible for performance but can help with understanding the drawing
708        /// order when inspecting renderdoc or apitrace recordings.
709        const DISABLE_BATCHING      = 1 << 5;
710        /// Display the pipeline epochs.
711        const EPOCHS                = 1 << 6;
712        /// Print driver messages to stdout.
713        const ECHO_DRIVER_MESSAGES  = 1 << 7;
714        /// Show an overlay displaying overdraw amount.
715        const SHOW_OVERDRAW         = 1 << 8;
716        /// Display the contents of GPU cache.
717        const GPU_CACHE_DBG         = 1 << 9;
718        /// Clear evicted parts of the texture cache for debugging purposes.
719        const TEXTURE_CACHE_DBG_CLEAR_EVICTED = 1 << 10;
720        /// Show picture caching debug overlay
721        const PICTURE_CACHING_DBG   = 1 << 11;
722        /// Highlight all primitives with colors based on kind.
723        const PRIMITIVE_DBG = 1 << 12;
724        /// Draw a zoom widget showing part of the framebuffer zoomed in.
725        const ZOOM_DBG = 1 << 13;
726        /// Scale the debug renderer down for a smaller screen. This will disrupt
727        /// any mapping between debug display items and page content, so shouldn't
728        /// be used with overlays like the picture caching or primitive display.
729        const SMALL_SCREEN = 1 << 14;
730        /// Disable various bits of the WebRender pipeline, to help narrow
731        /// down where slowness might be coming from.
732        const DISABLE_OPAQUE_PASS = 1 << 15;
733        ///
734        const DISABLE_ALPHA_PASS = 1 << 16;
735        ///
736        const DISABLE_CLIP_MASKS = 1 << 17;
737        ///
738        const DISABLE_TEXT_PRIMS = 1 << 18;
739        ///
740        const DISABLE_GRADIENT_PRIMS = 1 << 19;
741        ///
742        const OBSCURE_IMAGES = 1 << 20;
743        /// Taint the transparent area of the glyphs with a random opacity to easily
744        /// see when glyphs are re-rasterized.
745        const GLYPH_FLASHING = 1 << 21;
746        /// The profiler only displays information that is out of the ordinary.
747        const SMART_PROFILER        = 1 << 22;
748        /// If set, dump picture cache invalidation debug to console.
749        const INVALIDATION_DBG = 1 << 23;
750        /// Collect and dump profiler statistics to captures.
751        const PROFILER_CAPTURE = 1 << 25;
752        /// Invalidate picture tiles every frames (useful when inspecting GPU work in external tools).
753        const FORCE_PICTURE_INVALIDATION = 1 << 26;
754        /// Display window visibility on screen.
755        const WINDOW_VISIBILITY_DBG     = 1 << 27;
756        /// Render large blobs with at a smaller size (incorrectly). This is a temporary workaround for
757        /// fuzzing.
758        const RESTRICT_BLOB_SIZE        = 1 << 28;
759        /// Enable surface promotion logging.
760        const SURFACE_PROMOTION_LOGGING = 1 << 29;
761        /// Show picture caching debug overlay.
762        const PICTURE_BORDERS           = 1 << 30;
763        /// Panic when a attempting to display a missing stacking context snapshot.
764        const MISSING_SNAPSHOT_PANIC    = (1 as u64) << 31; // need "as u32" until we have cbindgen#556
765        /// Panic when a attempting to display a missing stacking context snapshot.
766        const MISSING_SNAPSHOT_PINK     = (1 as u64) << 32;
767        /// Highlight backdrop filters
768        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/// Information specific to a primitive type that
783/// uniquely identifies a primitive template by key.
784#[derive(Debug, Clone, Eq, MallocSizeOf, PartialEq, Hash, Serialize, Deserialize)]
785pub enum PrimitiveKeyKind {
786    /// Clear an existing rect, used for special effects on some platforms.
787    Clear,
788    ///
789    Rectangle {
790        ///
791        color: PropertyBinding<ColorU>,
792    },
793}
794
795///
796#[derive(Clone, Copy, Debug)]
797pub enum ScrollLocation {
798    /// Scroll by a certain amount.
799    Delta(LayoutVector2D),
800    /// Scroll to very top of element.
801    Start,
802    /// Scroll to very bottom of element.
803    End,
804}
805
806/// Crash annotations included in crash reports.
807#[repr(C)]
808#[derive(Clone, Copy)]
809pub enum CrashAnnotation {
810    CompileShader = 0,
811    DrawShader = 1,
812}
813
814/// Handler to expose support for annotating crash reports.
815pub 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
827/// Guard to add a crash annotation at creation, and clear it at destruction.
828pub 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}