zng_webrender_api/
lib.rs

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