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