Skip to main content

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_list;
51mod font;
52mod gradient_builder;
53mod image;
54mod tile_pool;
55pub mod units;
56
57pub use crate::color::*;
58pub use crate::display_item::*;
59pub use crate::display_list::*;
60pub use crate::font::*;
61pub use crate::gradient_builder::*;
62pub use crate::image::*;
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
122impl IdNamespace {
123    pub const DEBUGGER: IdNamespace = IdNamespace(!0);
124}
125
126/// A key uniquely identifying a WebRender document.
127///
128/// Instances can manage one or several documents (using the same render backend thread).
129/// Each document will internally correspond to a single scene, and scenes are made of
130/// one or several pipelines.
131#[repr(C)]
132#[derive(Clone, Copy, Debug, Deserialize, Eq, Hash, MallocSizeOf, PartialEq, Serialize, PeekPoke)]
133pub struct DocumentId {
134    ///
135    pub namespace_id: IdNamespace,
136    ///
137    pub id: u32,
138}
139
140impl DocumentId {
141    ///
142    pub fn new(namespace_id: IdNamespace, id: u32) -> Self {
143        DocumentId {
144            namespace_id,
145            id,
146        }
147    }
148
149    ///
150    pub const INVALID: DocumentId = DocumentId { namespace_id: IdNamespace(0), id: 0 };
151}
152
153/// This type carries no valuable semantics for WR. However, it reflects the fact that
154/// clients (Servo) may generate pipelines by different semi-independent sources.
155/// These pipelines still belong to the same `IdNamespace` and the same `DocumentId`.
156/// Having this extra Id field enables them to generate `PipelineId` without collision.
157pub type PipelineSourceId = u32;
158
159/// From the point of view of WR, `PipelineId` is completely opaque and generic as long as
160/// it's clonable, serializable, comparable, and hashable.
161#[repr(C)]
162#[derive(Clone, Copy, Debug, Deserialize, Eq, Hash, MallocSizeOf, PartialEq, Serialize, PeekPoke)]
163pub struct PipelineId(pub PipelineSourceId, pub u32);
164
165impl Default for PipelineId {
166    fn default() -> Self {
167        PipelineId::dummy()
168    }
169}
170
171impl PipelineId {
172    ///
173    pub fn dummy() -> Self {
174        PipelineId(!0, !0)
175    }
176
177    pub const INVALID: Self = PipelineId(!0, !0);
178}
179
180#[repr(C)]
181#[derive(Clone, Copy, Debug, PartialEq, PartialOrd)]
182pub struct FramePublishId(pub u64);
183
184impl FramePublishId {
185    /// Returns a FramePublishId corresponding to the first frame.
186    ///
187    /// Note that we use 0 as the internal id here because the current code
188    /// increments the frame publish id just before ResultMsg::PublishDocument,
189    /// and we want the first id to be 1.
190    pub fn first() -> Self {
191        FramePublishId(0)
192    }
193
194    /// Advances this FramePublishId to the next.
195    pub fn advance(&mut self) {
196        self.0 += 1;
197    }
198
199    /// An invalid sentinel FramePublishId, which will always compare less than
200    /// any valid FrameId.
201    pub const INVALID: Self = FramePublishId(0);
202}
203
204impl Default for FramePublishId {
205    fn default() -> Self {
206        FramePublishId::INVALID
207    }
208}
209
210/// An opaque pointer-sized value.
211#[repr(C)]
212#[derive(Clone)]
213pub struct ExternalEvent {
214    raw: usize,
215}
216
217unsafe impl Send for ExternalEvent {}
218
219impl ExternalEvent {
220    /// Creates the event from an opaque pointer-sized value.
221    pub fn from_raw(raw: usize) -> Self {
222        ExternalEvent { raw }
223    }
224    /// Consumes self to make it obvious that the event should be forwarded only once.
225    pub fn unwrap(self) -> usize {
226        self.raw
227    }
228}
229
230pub type APZScrollGeneration = u64;
231#[repr(C)]
232#[derive(Clone, Copy, Debug, Deserialize, PartialEq, Serialize, Default)]
233pub struct SampledScrollOffset {
234    pub offset: LayoutVector2D,
235    pub generation: APZScrollGeneration,
236}
237
238/// A flag in each scrollable frame to represent whether the owner of the frame document
239/// has any scroll-linked effect.
240/// See https://firefox-source-docs.mozilla.org/performance/scroll-linked_effects.html
241/// for a definition of scroll-linked effect.
242#[repr(u8)]
243#[derive(Clone, Copy, Debug, Default, Deserialize, PartialEq, Serialize, PeekPoke)]
244pub enum HasScrollLinkedEffect {
245    Yes,
246    #[default]
247    No,
248}
249
250#[repr(C)]
251pub struct MinimapData {
252  pub is_root_content: bool,
253  // All rects in local coords relative to the scrolled content's origin.
254  pub visual_viewport: LayoutRect,
255  pub layout_viewport: LayoutRect,
256  pub scrollable_rect: LayoutRect,
257  pub displayport: LayoutRect,
258  // Populated for root content nodes only, otherwise the identity
259  pub zoom_transform: LayoutTransform,
260  // Populated for nodes in the subtree of a root content node
261  // (outside such subtrees we'll have `root_content_scroll_id == 0`).
262  // Stores the enclosing root content node's ExternalScrollId.
263  pub root_content_pipeline_id: PipelineId,
264  pub root_content_scroll_id: u64
265}
266
267#[repr(C)]
268pub struct FrameReadyParams {
269    pub present: bool,
270    pub render: bool,
271    pub scrolled: bool,
272    /// Firefox uses this to indicate that the frame does not participate
273    /// in the frame throttling mechanism.
274    /// Frames from off-screen transactions are not tracked.
275    pub tracked: bool,
276}
277
278/// A handler to integrate WebRender with the thread that contains the `Renderer`.
279pub trait RenderNotifier: Send {
280    ///
281    fn clone(&self) -> Box<dyn RenderNotifier>;
282    /// Wake the thread containing the `Renderer` up (after updates have been put
283    /// in the renderer's queue).
284    fn wake_up(
285        &self,
286        composite_needed: bool,
287    );
288    /// Notify the thread containing the `Renderer` that a new frame is ready.
289    fn new_frame_ready(&self, _: DocumentId, publish_id: FramePublishId, params: &FrameReadyParams);
290    /// A Gecko-specific notification mechanism to get some code executed on the
291    /// `Renderer`'s thread, mostly replaced by `NotificationHandler`. You should
292    /// probably use the latter instead.
293    fn external_event(&self, _evt: ExternalEvent) {
294        unimplemented!()
295    }
296    /// Notify the thread containing the `Renderer` that the render backend has been
297    /// shut down.
298    fn shut_down(&self) {}
299}
300
301/// A stage of the rendering pipeline.
302#[repr(u32)]
303#[derive(Copy, Clone, Debug, PartialEq, Eq)]
304pub enum Checkpoint {
305    ///
306    SceneBuilt,
307    ///
308    FrameBuilt,
309    ///
310    FrameTexturesUpdated,
311    ///
312    FrameRendered,
313    /// NotificationRequests get notified with this if they get dropped without having been
314    /// notified. This provides the guarantee that if a request is created it will get notified.
315    TransactionDropped,
316}
317
318/// A handler to notify when a transaction reaches certain stages of the rendering
319/// pipeline.
320pub trait NotificationHandler : Send + Sync {
321    /// Entry point of the handler to implement. Invoked by WebRender.
322    fn notify(&self, when: Checkpoint);
323}
324
325/// A request to notify a handler when the transaction reaches certain stages of the
326/// rendering pipeline.
327///
328/// The request is guaranteed to be notified once and only once, even if the transaction
329/// is dropped before the requested check-point.
330pub struct NotificationRequest {
331    handler: Option<Box<dyn NotificationHandler>>,
332    when: Checkpoint,
333}
334
335impl NotificationRequest {
336    /// Constructor.
337    pub fn new(when: Checkpoint, handler: Box<dyn NotificationHandler>) -> Self {
338        NotificationRequest {
339            handler: Some(handler),
340            when,
341        }
342    }
343
344    /// The specified stage at which point the handler should be notified.
345    pub fn when(&self) -> Checkpoint { self.when }
346
347    /// Called by WebRender at specified stages to notify the registered handler.
348    pub fn notify(mut self) {
349        if let Some(handler) = self.handler.take() {
350            handler.notify(self.when);
351        }
352    }
353}
354
355/// An object that can perform hit-testing without doing synchronous queries to
356/// the RenderBackendThread.
357pub trait ApiHitTester: Send + Sync {
358    /// Does a hit test on display items in the specified document, at the given
359    /// point. The vector of hit results will contain all display items that match,
360    /// ordered from front to back.
361    fn hit_test(&self, point: WorldPoint) -> HitTestResult;
362}
363
364/// A hit tester requested to the render backend thread but not necessarily ready yet.
365///
366/// The request should be resolved as late as possible to reduce the likelihood of blocking.
367pub struct HitTesterRequest {
368    #[doc(hidden)]
369    pub rx: Receiver<Arc<dyn ApiHitTester>>,
370}
371
372impl HitTesterRequest {
373    /// Block until the hit tester is available and return it, consuming teh request.
374    pub fn resolve(self) -> Arc<dyn ApiHitTester> {
375        self.rx.recv().unwrap()
376    }
377}
378
379/// Describe an item that matched a hit-test query.
380#[derive(Clone, Debug, Deserialize, PartialEq, Serialize)]
381pub struct HitTestResultItem {
382    /// The pipeline that the display item that was hit belongs to.
383    pub pipeline: PipelineId,
384
385    /// The tag of the hit display item.
386    pub tag: ItemTag,
387
388    /// The animation id from the stacking context.
389    pub animation_id: u64,
390
391    /// The hit point in the coordinate space of the "viewport" of the display item. The
392    /// viewport is the scroll node formed by the root reference frame of the display item's
393    /// pipeline.
394    pub point_in_viewport: LayoutPoint,
395}
396
397/// Returned by `RenderApi::hit_test`.
398#[derive(Clone, Debug, Default, Deserialize, Serialize)]
399pub struct HitTestResult {
400    /// List of items that are match the hit-test query.
401    pub items: Vec<HitTestResultItem>,
402}
403
404impl Drop for NotificationRequest {
405    fn drop(&mut self) {
406        if let Some(ref mut handler) = self.handler {
407            handler.notify(Checkpoint::TransactionDropped);
408        }
409    }
410}
411
412// This Clone impl yields an "empty" request because we don't want the requests
413// to be notified twice so the request is owned by only one of the API messages
414// (the original one) after the clone.
415// This works in practice because the notifications requests are used for
416// synchronization so we don't need to include them in the recording mechanism
417// in wrench that clones the messages.
418impl Clone for NotificationRequest {
419    fn clone(&self) -> Self {
420        NotificationRequest {
421            when: self.when,
422            handler: None,
423        }
424    }
425}
426
427
428/// A key to identify an animated property binding.
429#[repr(C)]
430#[derive(Clone, Copy, Debug, Default, Deserialize, MallocSizeOf, PartialEq, Serialize, Eq, Hash, PeekPoke)]
431pub struct PropertyBindingId {
432    pub namespace: IdNamespace,
433    pub uid: u32,
434}
435
436impl PropertyBindingId {
437    /// Constructor.
438    pub fn new(value: u64) -> Self {
439        PropertyBindingId {
440            namespace: IdNamespace((value >> 32) as u32),
441            uid: value as u32,
442        }
443    }
444
445    /// Decompose the ID back into the raw integer.
446    pub fn to_u64(&self) -> u64 {
447        ((self.namespace.0 as u64) << 32) | self.uid as u64
448    }
449}
450
451/// A unique key that is used for connecting animated property
452/// values to bindings in the display list.
453#[repr(C)]
454#[derive(Clone, Copy, Debug, Default, Deserialize, Eq, Hash, MallocSizeOf, PartialEq, Serialize, PeekPoke)]
455pub struct PropertyBindingKey<T> {
456    ///
457    pub id: PropertyBindingId,
458    #[doc(hidden)]
459    pub _phantom: PhantomData<T>,
460}
461
462/// Construct a property value from a given key and value.
463impl<T: Copy> PropertyBindingKey<T> {
464    ///
465    pub fn with(self, value: T) -> PropertyValue<T> {
466        PropertyValue { key: self, value }
467    }
468}
469
470impl<T> Into<u64> for PropertyBindingKey<T> {
471    fn into(self) -> u64 {
472        self.id.to_u64()
473    }
474}
475
476impl<T> PropertyBindingKey<T> {
477    /// Constructor.
478    pub fn new(value: u64) -> Self {
479        PropertyBindingKey {
480            id: PropertyBindingId::new(value),
481            _phantom: PhantomData,
482        }
483    }
484}
485
486/// A binding property can either be a specific value
487/// (the normal, non-animated case) or point to a binding location
488/// to fetch the current value from.
489/// Note that Binding has also a non-animated value, the value is
490/// used for the case where the animation is still in-delay phase
491/// (i.e. the animation doesn't produce any animation values).
492#[repr(C)]
493#[derive(Clone, Copy, Debug, Deserialize, Eq, Hash, MallocSizeOf, PartialEq, Serialize, PeekPoke)]
494pub enum PropertyBinding<T> {
495    /// Non-animated value.
496    Value(T),
497    /// Animated binding.
498    Binding(PropertyBindingKey<T>, T),
499}
500
501impl<T: Default> Default for PropertyBinding<T> {
502    fn default() -> Self {
503        PropertyBinding::Value(Default::default())
504    }
505}
506
507impl<T> From<T> for PropertyBinding<T> {
508    fn from(value: T) -> PropertyBinding<T> {
509        PropertyBinding::Value(value)
510    }
511}
512
513impl From<PropertyBindingKey<ColorF>> for PropertyBindingKey<ColorU> {
514    fn from(key: PropertyBindingKey<ColorF>) -> PropertyBindingKey<ColorU> {
515        PropertyBindingKey {
516            id: key.id,
517            _phantom: PhantomData,
518        }
519    }
520}
521
522impl From<PropertyBindingKey<ColorU>> for PropertyBindingKey<ColorF> {
523    fn from(key: PropertyBindingKey<ColorU>) -> PropertyBindingKey<ColorF> {
524        PropertyBindingKey {
525            id: key.id,
526            _phantom: PhantomData,
527        }
528    }
529}
530
531impl From<PropertyBinding<ColorF>> for PropertyBinding<ColorU> {
532    fn from(value: PropertyBinding<ColorF>) -> PropertyBinding<ColorU> {
533        match value {
534            PropertyBinding::Value(value) => PropertyBinding::Value(value.into()),
535            PropertyBinding::Binding(k, v) => {
536                PropertyBinding::Binding(k.into(), v.into())
537            }
538        }
539    }
540}
541
542impl From<PropertyBinding<ColorU>> for PropertyBinding<ColorF> {
543    fn from(value: PropertyBinding<ColorU>) -> PropertyBinding<ColorF> {
544        match value {
545            PropertyBinding::Value(value) => PropertyBinding::Value(value.into()),
546            PropertyBinding::Binding(k, v) => {
547                PropertyBinding::Binding(k.into(), v.into())
548            }
549        }
550    }
551}
552
553/// The current value of an animated property. This is
554/// supplied by the calling code.
555#[derive(Clone, Copy, Debug, Deserialize, Serialize, PartialEq)]
556pub struct PropertyValue<T> {
557    ///
558    pub key: PropertyBindingKey<T>,
559    ///
560    pub value: T,
561}
562
563/// When using `generate_frame()`, a list of `PropertyValue` structures
564/// can optionally be supplied to provide the current value of any
565/// animated properties.
566#[derive(Clone, Deserialize, Serialize, Debug, PartialEq, Default)]
567pub struct DynamicProperties {
568    /// transform list
569    pub transforms: Vec<PropertyValue<LayoutTransform>>,
570    /// opacity
571    pub floats: Vec<PropertyValue<f32>>,
572    /// background color
573    pub colors: Vec<PropertyValue<ColorF>>,
574}
575
576impl DynamicProperties {
577    /// Extend the properties.
578    pub fn extend(&mut self, other: Self) {
579        self.transforms.extend(other.transforms);
580        self.floats.extend(other.floats);
581        self.colors.extend(other.colors);
582    }
583}
584
585/// A C function that takes a pointer to a heap allocation and returns its size.
586///
587/// This is borrowed from the malloc_size_of crate, upon which we want to avoid
588/// a dependency from WebRender.
589pub type VoidPtrToSizeFn = unsafe extern "C" fn(ptr: *const c_void) -> usize;
590
591/// A configuration option that can be changed at runtime.
592///
593/// # Adding a new configuration option
594///
595///  - Add a new enum variant here.
596///  - Add the entry in WR_BOOL_PARAMETER_LIST in gfxPlatform.cpp.
597///  - React to the parameter change anywhere in WebRender where a SetParam message is received.
598#[derive(Copy, Clone, Debug, PartialEq)]
599pub enum Parameter {
600    Bool(BoolParameter, bool),
601    Int(IntParameter, i32),
602    Float(FloatParameter, f32),
603}
604
605/// Boolean configuration option.
606#[derive(Copy, Clone, Debug, PartialEq, Eq)]
607#[repr(u32)]
608pub enum BoolParameter {
609    PboUploads = 0,
610    Multithreading = 1,
611    BatchedUploads = 2,
612    DrawCallsForTextureCopy = 3,
613}
614
615/// Integer configuration option.
616#[derive(Copy, Clone, Debug, PartialEq, Eq)]
617#[repr(u32)]
618pub enum IntParameter {
619    BatchedUploadThreshold = 0,
620}
621
622/// Floating point configuration option.
623#[derive(Copy, Clone, Debug, PartialEq, Eq)]
624#[repr(u32)]
625pub enum FloatParameter {
626    /// The minimum time for the CPU portion of a frame to be considered slow
627    SlowCpuFrameThreshold = 0,
628}
629
630/// Flags to track why we are rendering.
631#[repr(C)]
632#[derive(Copy, PartialEq, Eq, Clone, PartialOrd, Ord, Hash, Default, Deserialize, MallocSizeOf, Serialize)]
633pub struct RenderReasons(u32);
634
635bitflags! {
636    impl RenderReasons: u32 {
637        /// Equivalent of empty() for the C++ side.
638        const NONE                          = 0;
639        const SCENE                         = 1 << 0;
640        const ANIMATED_PROPERTY             = 1 << 1;
641        const RESOURCE_UPDATE               = 1 << 2;
642        const ASYNC_IMAGE                   = 1 << 3;
643        const CLEAR_RESOURCES               = 1 << 4;
644        const APZ                           = 1 << 5;
645        /// Window resize
646        const RESIZE                        = 1 << 6;
647        /// Various widget-related reasons
648        const WIDGET                        = 1 << 7;
649        /// See Frame::must_be_drawn
650        const TEXTURE_CACHE_FLUSH           = 1 << 8;
651        const SNAPSHOT                      = 1 << 9;
652        const POST_RESOURCE_UPDATES_HOOK    = 1 << 10;
653        const CONFIG_CHANGE                 = 1 << 11;
654        const CONTENT_SYNC                  = 1 << 12;
655        const FLUSH                         = 1 << 13;
656        const TESTING                       = 1 << 14;
657        const OTHER                         = 1 << 15;
658        /// Vsync isn't actually "why" we render but it can be useful
659        /// to see which frames were driven by the vsync scheduler so
660        /// we store a bit for it.
661        const VSYNC                         = 1 << 16;
662        const SKIPPED_COMPOSITE             = 1 << 17;
663        /// Gecko does some special things when it starts observing vsync
664        /// so it can be useful to know what frames are associated with it.
665        const START_OBSERVING_VSYNC         = 1 << 18;
666        const ASYNC_IMAGE_COMPOSITE_UNTIL   = 1 << 19;
667    }
668}
669
670impl core::fmt::Debug for RenderReasons {
671    fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
672        if self.is_empty() {
673            write!(f, "{:#x}", Self::empty().bits())
674        } else {
675            bitflags::parser::to_writer(self, f)
676        }
677    }
678}
679
680impl RenderReasons {
681    pub const NUM_BITS: u32 = 17;
682}
683
684/// Flags to enable/disable various builtin debugging tools.
685#[repr(C)]
686#[derive(Copy, PartialEq, Eq, Clone, PartialOrd, Ord, Hash, Default, Deserialize, MallocSizeOf, Serialize)]
687pub struct DebugFlags(u64);
688
689bitflags! {
690    impl DebugFlags: u64 {
691        /// Display the frame profiler on screen.
692        const PROFILER_DBG          = 1 << 0;
693        /// Display intermediate render targets on screen.
694        const RENDER_TARGET_DBG     = 1 << 1;
695        /// Display all texture cache pages on screen.
696        const TEXTURE_CACHE_DBG     = 1 << 2;
697        /// Display GPU timing results.
698        const GPU_TIME_QUERIES      = 1 << 3;
699        /// Query the number of pixels that pass the depth test divided and show it
700        /// in the profiler as a percentage of the number of pixels in the screen
701        /// (window width times height).
702        const GPU_SAMPLE_QUERIES    = 1 << 4;
703        /// Render each quad with their own draw call.
704        ///
705        /// Terrible for performance but can help with understanding the drawing
706        /// order when inspecting renderdoc or apitrace recordings.
707        const DISABLE_BATCHING      = 1 << 5;
708        /// Display the pipeline epochs.
709        const EPOCHS                = 1 << 6;
710        /// Print driver messages to stdout.
711        const ECHO_DRIVER_MESSAGES  = 1 << 7;
712        /// Show an overlay displaying overdraw amount.
713        const SHOW_OVERDRAW         = 1 << 8;
714        /// Display the contents of GPU cache.
715        const GPU_CACHE_DBG         = 1 << 9;
716        /// Clear evicted parts of the texture cache for debugging purposes.
717        const TEXTURE_CACHE_DBG_CLEAR_EVICTED = 1 << 10;
718        /// Show picture caching debug overlay
719        const PICTURE_CACHING_DBG   = 1 << 11;
720        /// Draw a zoom widget showing part of the framebuffer zoomed in.
721        const ZOOM_DBG = 1 << 13;
722        /// Scale the debug renderer down for a smaller screen. This will disrupt
723        /// any mapping between debug display items and page content, so shouldn't
724        /// be used with overlays like the picture caching or primitive display.
725        const SMALL_SCREEN = 1 << 14;
726        /// Disable various bits of the WebRender pipeline, to help narrow
727        /// down where slowness might be coming from.
728        const DISABLE_OPAQUE_PASS = 1 << 15;
729        ///
730        const DISABLE_ALPHA_PASS = 1 << 16;
731        ///
732        const DISABLE_CLIP_MASKS = 1 << 17;
733        ///
734        const DISABLE_TEXT_PRIMS = 1 << 18;
735        ///
736        const DISABLE_GRADIENT_PRIMS = 1 << 19;
737        ///
738        const OBSCURE_IMAGES = 1 << 20;
739        /// Taint the transparent area of the glyphs with a random opacity to easily
740        /// see when glyphs are re-rasterized.
741        const GLYPH_FLASHING = 1 << 21;
742        /// The profiler only displays information that is out of the ordinary.
743        const SMART_PROFILER        = 1 << 22;
744        /// If set, dump picture cache invalidation debug to console.
745        const INVALIDATION_DBG = 1 << 23;
746        /// Collect and dump profiler statistics to captures.
747        const PROFILER_CAPTURE = 1 << 25;
748        /// Invalidate picture tiles every frames (useful when inspecting GPU work in external tools).
749        const FORCE_PICTURE_INVALIDATION = 1 << 26;
750        /// Display window visibility on screen.
751        const WINDOW_VISIBILITY_DBG     = 1 << 27;
752        /// Render large blobs with at a smaller size (incorrectly). This is a temporary workaround for
753        /// fuzzing.
754        const RESTRICT_BLOB_SIZE        = 1 << 28;
755        /// Enable surface promotion logging.
756        const SURFACE_PROMOTION_LOGGING = 1 << 29;
757        /// Show picture caching debug overlay.
758        const PICTURE_BORDERS           = 1 << 30;
759        /// Panic when a attempting to display a missing stacking context snapshot.
760        const MISSING_SNAPSHOT_PANIC    = (1 as u64) << 31; // need "as u32" until we have cbindgen#556
761        /// Panic when a attempting to display a missing stacking context snapshot.
762        const MISSING_SNAPSHOT_PINK     = (1 as u64) << 32;
763        /// Highlight backdrop filters
764        const HIGHLIGHT_BACKDROP_FILTERS = (1 as u64) << 33;
765        /// Show external composite border rects in debug overlay.
766        /// TODO: Add native compositor support
767        const EXTERNAL_COMPOSITE_BORDERS = (1 as u64) << 34;
768        /// Dump the frame spatial tree to stderr.
769        const DUMP_SPATIAL_TREE = (1 as u64) << 35;
770    }
771}
772
773impl core::fmt::Debug for DebugFlags {
774    fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
775        if self.is_empty() {
776            write!(f, "{:#x}", Self::empty().bits())
777        } else {
778            bitflags::parser::to_writer(self, f)
779        }
780    }
781}
782
783///
784#[derive(Clone, Copy, Debug)]
785pub enum ScrollLocation {
786    /// Scroll by a certain amount.
787    Delta(LayoutVector2D),
788    /// Scroll to very top of element.
789    Start,
790    /// Scroll to very bottom of element.
791    End,
792}
793
794/// Crash annotations included in crash reports.
795#[repr(C)]
796#[derive(Clone, Copy)]
797pub enum CrashAnnotation {
798    CompileShader = 0,
799    DrawShader = 1,
800    FontFile = 2,
801}
802
803/// Handler to expose support for annotating crash reports.
804pub trait CrashAnnotator : Send {
805    fn set(&self, annotation: CrashAnnotation, value: &std::ffi::CStr);
806    fn clear(&self, annotation: CrashAnnotation);
807    fn box_clone(&self) -> Box<dyn CrashAnnotator>;
808}
809
810impl Clone for Box<dyn CrashAnnotator> {
811    fn clone(&self) -> Box<dyn CrashAnnotator> {
812        self.box_clone()
813    }
814}
815
816/// Guard to add a crash annotation at creation, and clear it at destruction.
817pub struct CrashAnnotatorGuard<'a> {
818    annotator: &'a Option<Box<dyn CrashAnnotator>>,
819    annotation: CrashAnnotation,
820}
821
822impl<'a> CrashAnnotatorGuard<'a> {
823    pub fn new(
824        annotator: &'a Option<Box<dyn CrashAnnotator>>,
825        annotation: CrashAnnotation,
826        value: &std::ffi::CStr,
827    ) -> Self {
828        if let Some(ref annotator) = annotator {
829            annotator.set(annotation, value);
830        }
831        Self {
832            annotator,
833            annotation,
834        }
835    }
836}
837
838impl<'a> Drop for CrashAnnotatorGuard<'a> {
839    fn drop(&mut self) {
840        if let Some(ref annotator) = self.annotator {
841            annotator.clear(self.annotation);
842        }
843    }
844}
845
846/// A little bit of extra information to make memory reports more useful
847#[derive(Copy, Clone, Debug, Eq, PartialEq)]
848#[cfg_attr(feature = "serialize", derive(Serialize))]
849#[cfg_attr(feature = "deserialize", derive(Deserialize))]
850pub enum TextureCacheCategory {
851    Atlas,
852    Standalone,
853    PictureTile,
854    RenderTarget,
855}
856
857/// For debugging purposes
858#[derive(Clone, Debug)]
859#[cfg_attr(feature = "serialize", derive(Serialize))]
860#[cfg_attr(feature = "deserialize", derive(Deserialize))]
861pub enum RenderCommandInfo {
862    RenderTarget { kind: String, size: DeviceIntSize },
863    DrawCall { shader: String, instances: u32 },
864}