azul_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#![cfg_attr(feature = "cargo-clippy", allow(clippy::float_cmp, clippy::too_many_arguments))]
16#![cfg_attr(feature = "cargo-clippy", allow(clippy::unreadable_literal, clippy::new_without_default))]
17
18pub extern crate crossbeam_channel;
19pub extern crate euclid;
20
21extern crate app_units;
22#[macro_use]
23extern crate bitflags;
24extern crate byteorder;
25#[cfg(feature = "nightly")]
26extern crate core;
27#[cfg(target_os = "macos")]
28extern crate core_foundation;
29#[cfg(target_os = "macos")]
30extern crate core_graphics;
31extern crate derive_more;
32#[macro_use]
33extern crate malloc_size_of_derive;
34extern crate serde;
35#[macro_use]
36extern crate serde_derive;
37extern crate time;
38
39extern crate malloc_size_of;
40extern crate peek_poke;
41
42pub mod channel;
43mod color;
44mod display_item;
45mod display_item_cache;
46mod display_list;
47mod font;
48mod gradient_builder;
49mod image;
50pub mod units;
51
52pub use crate::color::*;
53pub use crate::display_item::*;
54pub use crate::display_item_cache::DisplayItemCache;
55pub use crate::display_list::*;
56pub use crate::font::*;
57pub use crate::gradient_builder::*;
58pub use crate::image::*;
59
60use crate::units::*;
61use crate::channel::Receiver;
62use std::marker::PhantomData;
63use std::sync::Arc;
64use std::os::raw::c_void;
65use peek_poke::PeekPoke;
66
67/// Width and height in device pixels of image tiles.
68pub type TileSize = u16;
69
70/// Various settings that the caller can select based on desired tradeoffs
71/// between rendering quality and performance / power usage.
72#[derive(Copy, Clone, Deserialize, Serialize)]
73pub struct QualitySettings {
74    /// If true, disable creating separate picture cache slices when the
75    /// scroll root changes. This gives maximum opportunity to find an
76    /// opaque background, which enables subpixel AA. However, it is
77    /// usually significantly more expensive to render when scrolling.
78    pub force_subpixel_aa_where_possible: bool,
79}
80
81impl Default for QualitySettings {
82    fn default() -> Self {
83        QualitySettings {
84            // Prefer performance over maximum subpixel AA quality, since WR
85            // already enables subpixel AA in more situations than other browsers.
86            force_subpixel_aa_where_possible: false,
87        }
88    }
89}
90
91/// An epoch identifies the state of a pipeline in time.
92///
93/// This is mostly used as a synchronization mechanism to observe how/when particular pipeline
94/// updates propagate through WebRender and are applied at various stages.
95#[repr(C)]
96#[derive(Clone, Copy, Debug, Deserialize, Eq, Hash, Ord, PartialEq, PartialOrd, Serialize)]
97pub struct Epoch(pub u32);
98
99impl Epoch {
100    /// Magic invalid epoch value.
101    pub fn invalid() -> Epoch {
102        Epoch(u32::MAX)
103    }
104}
105
106/// ID namespaces uniquely identify different users of WebRender's API.
107///
108/// For example in Gecko each content process uses a separate id namespace.
109#[repr(C)]
110#[derive(Clone, Copy, Debug, Default, Eq, MallocSizeOf, PartialEq, Hash, Ord, PartialOrd, PeekPoke)]
111#[derive(Deserialize, Serialize)]
112pub struct IdNamespace(pub u32);
113
114/// A key uniquely identifying a WebRender document.
115///
116/// Instances can manage one or several documents (using the same render backend thread).
117/// Each document will internally correspond to a single scene, and scenes are made of
118/// one or several pipelines.
119#[repr(C)]
120#[derive(Clone, Copy, Debug, Deserialize, Eq, Hash, MallocSizeOf, PartialEq, Serialize, PeekPoke)]
121pub struct DocumentId {
122    ///
123    pub namespace_id: IdNamespace,
124    ///
125    pub id: u32,
126}
127
128impl DocumentId {
129    ///
130    pub fn new(namespace_id: IdNamespace, id: u32) -> Self {
131        DocumentId {
132            namespace_id,
133            id,
134        }
135    }
136
137    ///
138    pub const INVALID: DocumentId = DocumentId { namespace_id: IdNamespace(0), id: 0 };
139}
140
141/// This type carries no valuable semantics for WR. However, it reflects the fact that
142/// clients (Servo) may generate pipelines by different semi-independent sources.
143/// These pipelines still belong to the same `IdNamespace` and the same `DocumentId`.
144/// Having this extra Id field enables them to generate `PipelineId` without collision.
145pub type PipelineSourceId = u32;
146
147/// From the point of view of WR, `PipelineId` is completely opaque and generic as long as
148/// it's clonable, serializable, comparable, and hashable.
149#[repr(C)]
150#[derive(Clone, Copy, Debug, Deserialize, Eq, Hash, MallocSizeOf, PartialEq, Serialize, PeekPoke)]
151pub struct PipelineId(pub PipelineSourceId, pub u32);
152
153impl Default for PipelineId {
154    fn default() -> Self {
155        PipelineId::dummy()
156    }
157}
158
159impl PipelineId {
160    ///
161    pub fn dummy() -> Self {
162        PipelineId(!0, !0)
163    }
164}
165
166
167/// An opaque pointer-sized value.
168#[repr(C)]
169#[derive(Clone)]
170pub struct ExternalEvent {
171    raw: usize,
172}
173
174unsafe impl Send for ExternalEvent {}
175
176impl ExternalEvent {
177    /// Creates the event from an opaque pointer-sized value.
178    pub fn from_raw(raw: usize) -> Self {
179        ExternalEvent { raw }
180    }
181    /// Consumes self to make it obvious that the event should be forwarded only once.
182    pub fn unwrap(self) -> usize {
183        self.raw
184    }
185}
186
187/// Describe whether or not scrolling should be clamped by the content bounds.
188#[derive(Clone, Deserialize, Serialize)]
189pub enum ScrollClamping {
190    ///
191    ToContentBounds,
192    ///
193    NoClamping,
194}
195
196/// A handler to integrate WebRender with the thread that contains the `Renderer`.
197pub trait RenderNotifier: Send {
198    ///
199    fn clone(&self) -> Box<dyn RenderNotifier>;
200    /// Wake the thread containing the `Renderer` up (after updates have been put
201    /// in the renderer's queue).
202    fn wake_up(
203        &self,
204        composite_needed: bool,
205    );
206    /// Notify the thread containing the `Renderer` that a new frame is ready.
207    fn new_frame_ready(&self, _: DocumentId, scrolled: bool, composite_needed: bool, render_time_ns: Option<u64>);
208    /// A Gecko-specific notification mechanism to get some code executed on the
209    /// `Renderer`'s thread, mostly replaced by `NotificationHandler`. You should
210    /// probably use the latter instead.
211    fn external_event(&self, _evt: ExternalEvent) {
212        unimplemented!()
213    }
214    /// Notify the thread containing the `Renderer` that the render backend has been
215    /// shut down.
216    fn shut_down(&self) {}
217}
218
219/// A stage of the rendering pipeline.
220#[repr(u32)]
221#[derive(Copy, Clone, Debug, PartialEq, Eq)]
222pub enum Checkpoint {
223    ///
224    SceneBuilt,
225    ///
226    FrameBuilt,
227    ///
228    FrameTexturesUpdated,
229    ///
230    FrameRendered,
231    /// NotificationRequests get notified with this if they get dropped without having been
232    /// notified. This provides the guarantee that if a request is created it will get notified.
233    TransactionDropped,
234}
235
236/// A handler to notify when a transaction reaches certain stages of the rendering
237/// pipeline.
238pub trait NotificationHandler : Send + Sync {
239    /// Entry point of the handler to implement. Invoked by WebRender.
240    fn notify(&self, when: Checkpoint);
241}
242
243/// A request to notify a handler when the transaction reaches certain stages of the
244/// rendering pipeline.
245///
246/// The request is guaranteed to be notified once and only once, even if the transaction
247/// is dropped before the requested check-point.
248pub struct NotificationRequest {
249    handler: Option<Box<dyn NotificationHandler>>,
250    when: Checkpoint,
251}
252
253impl NotificationRequest {
254    /// Constructor.
255    pub fn new(when: Checkpoint, handler: Box<dyn NotificationHandler>) -> Self {
256        NotificationRequest {
257            handler: Some(handler),
258            when,
259        }
260    }
261
262    /// The specified stage at which point the handler should be notified.
263    pub fn when(&self) -> Checkpoint { self.when }
264
265    /// Called by WebRender at specified stages to notify the registered handler.
266    pub fn notify(mut self) {
267        if let Some(handler) = self.handler.take() {
268            handler.notify(self.when);
269        }
270    }
271}
272
273/// An object that can perform hit-testing without doing synchronous queries to
274/// the RenderBackendThread.
275pub trait ApiHitTester: Send + Sync {
276    /// Does a hit test on display items in the specified document, at the given
277    /// point. If a pipeline_id is specified, it is used to further restrict the
278    /// hit results so that only items inside that pipeline are matched. The vector
279    /// of hit results will contain all display items that match, ordered from
280    /// front to back.
281    fn hit_test(&self, pipeline_id: Option<PipelineId>, point: WorldPoint) -> HitTestResult;
282}
283
284/// A hit tester requested to the render backend thread but not necessarily ready yet.
285///
286/// The request should be resolved as late as possible to reduce the likelihood of blocking.
287pub struct HitTesterRequest {
288    #[doc(hidden)]
289    pub rx: Receiver<Arc<dyn ApiHitTester>>,
290}
291
292impl HitTesterRequest {
293    /// Block until the hit tester is available and return it, consuming teh request.
294    pub fn resolve(self) -> Arc<dyn ApiHitTester> {
295        self.rx.recv().unwrap()
296    }
297}
298
299/// Describe an item that matched a hit-test query.
300#[derive(Clone, Debug, Deserialize, PartialEq, Serialize)]
301pub struct HitTestItem {
302    /// The pipeline that the display item that was hit belongs to.
303    pub pipeline: PipelineId,
304
305    /// The tag of the hit display item.
306    pub tag: ItemTag,
307
308    /// The hit point in the coordinate space of the "viewport" of the display item. The
309    /// viewport is the scroll node formed by the root reference frame of the display item's
310    /// pipeline.
311    pub point_in_viewport: LayoutPoint,
312
313    /// The coordinates of the original hit test point relative to the origin of this item.
314    /// This is useful for calculating things like text offsets in the client.
315    pub point_relative_to_item: LayoutPoint,
316}
317
318/// Returned by `RenderApi::hit_test`.
319#[derive(Clone, Debug, Default, Deserialize, Serialize)]
320pub struct HitTestResult {
321    /// List of items that are match the hit-test query.
322    pub items: Vec<HitTestItem>,
323}
324
325impl Drop for NotificationRequest {
326    fn drop(&mut self) {
327        if let Some(ref mut handler) = self.handler {
328            handler.notify(Checkpoint::TransactionDropped);
329        }
330    }
331}
332
333// This Clone impl yields an "empty" request because we don't want the requests
334// to be notified twice so the request is owned by only one of the API messages
335// (the original one) after the clone.
336// This works in practice because the notifications requests are used for
337// synchronization so we don't need to include them in the recording mechanism
338// in wrench that clones the messages.
339impl Clone for NotificationRequest {
340    fn clone(&self) -> Self {
341        NotificationRequest {
342            when: self.when,
343            handler: None,
344        }
345    }
346}
347
348
349/// A key to identify an animated property binding.
350#[repr(C)]
351#[derive(Clone, Copy, Debug, Default, Deserialize, MallocSizeOf, PartialEq, Serialize, Eq, Hash, PeekPoke)]
352pub struct PropertyBindingId {
353    pub namespace: IdNamespace,
354    pub uid: u32,
355}
356
357impl PropertyBindingId {
358    /// Constructor.
359    pub fn new(value: u64) -> Self {
360        PropertyBindingId {
361            namespace: IdNamespace((value >> 32) as u32),
362            uid: value as u32,
363        }
364    }
365}
366
367/// A unique key that is used for connecting animated property
368/// values to bindings in the display list.
369#[repr(C)]
370#[derive(Clone, Copy, Debug, Default, Deserialize, Eq, Hash, MallocSizeOf, PartialEq, Serialize, PeekPoke)]
371pub struct PropertyBindingKey<T> {
372    ///
373    pub id: PropertyBindingId,
374    #[doc(hidden)]
375    pub _phantom: PhantomData<T>,
376}
377
378/// Construct a property value from a given key and value.
379impl<T: Copy> PropertyBindingKey<T> {
380    ///
381    pub fn with(self, value: T) -> PropertyValue<T> {
382        PropertyValue { key: self, value }
383    }
384}
385
386impl<T> PropertyBindingKey<T> {
387    /// Constructor.
388    pub fn new(value: u64) -> Self {
389        PropertyBindingKey {
390            id: PropertyBindingId::new(value),
391            _phantom: PhantomData,
392        }
393    }
394}
395
396/// A binding property can either be a specific value
397/// (the normal, non-animated case) or point to a binding location
398/// to fetch the current value from.
399/// Note that Binding has also a non-animated value, the value is
400/// used for the case where the animation is still in-delay phase
401/// (i.e. the animation doesn't produce any animation values).
402#[repr(C)]
403#[derive(Clone, Copy, Debug, Deserialize, Eq, Hash, MallocSizeOf, PartialEq, Serialize, PeekPoke)]
404pub enum PropertyBinding<T> {
405    /// Non-animated value.
406    Value(T),
407    /// Animated binding.
408    Binding(PropertyBindingKey<T>, T),
409}
410
411impl<T: Default> Default for PropertyBinding<T> {
412    fn default() -> Self {
413        PropertyBinding::Value(Default::default())
414    }
415}
416
417impl<T> From<T> for PropertyBinding<T> {
418    fn from(value: T) -> PropertyBinding<T> {
419        PropertyBinding::Value(value)
420    }
421}
422
423impl From<PropertyBindingKey<ColorF>> for PropertyBindingKey<ColorU> {
424    fn from(key: PropertyBindingKey<ColorF>) -> PropertyBindingKey<ColorU> {
425        PropertyBindingKey {
426            id: key.id.clone(),
427            _phantom: PhantomData,
428        }
429    }
430}
431
432impl From<PropertyBindingKey<ColorU>> for PropertyBindingKey<ColorF> {
433    fn from(key: PropertyBindingKey<ColorU>) -> PropertyBindingKey<ColorF> {
434        PropertyBindingKey {
435            id: key.id.clone(),
436            _phantom: PhantomData,
437        }
438    }
439}
440
441impl From<PropertyBinding<ColorF>> for PropertyBinding<ColorU> {
442    fn from(value: PropertyBinding<ColorF>) -> PropertyBinding<ColorU> {
443        match value {
444            PropertyBinding::Value(value) => PropertyBinding::Value(value.into()),
445            PropertyBinding::Binding(k, v) => {
446                PropertyBinding::Binding(k.into(), v.into())
447            }
448        }
449    }
450}
451
452impl From<PropertyBinding<ColorU>> for PropertyBinding<ColorF> {
453    fn from(value: PropertyBinding<ColorU>) -> PropertyBinding<ColorF> {
454        match value {
455            PropertyBinding::Value(value) => PropertyBinding::Value(value.into()),
456            PropertyBinding::Binding(k, v) => {
457                PropertyBinding::Binding(k.into(), v.into())
458            }
459        }
460    }
461}
462
463/// The current value of an animated property. This is
464/// supplied by the calling code.
465#[derive(Clone, Copy, Debug, Deserialize, Serialize, PartialEq)]
466pub struct PropertyValue<T> {
467    ///
468    pub key: PropertyBindingKey<T>,
469    ///
470    pub value: T,
471}
472
473/// When using `generate_frame()`, a list of `PropertyValue` structures
474/// can optionally be supplied to provide the current value of any
475/// animated properties.
476#[derive(Clone, Deserialize, Serialize, Debug, PartialEq, Default)]
477pub struct DynamicProperties {
478    ///
479    pub transforms: Vec<PropertyValue<LayoutTransform>>,
480    /// opacity
481    pub floats: Vec<PropertyValue<f32>>,
482    /// background color
483    pub colors: Vec<PropertyValue<ColorF>>,
484}
485
486/// A C function that takes a pointer to a heap allocation and returns its size.
487///
488/// This is borrowed from the malloc_size_of crate, upon which we want to avoid
489/// a dependency from WebRender.
490pub type VoidPtrToSizeFn = unsafe extern "C" fn(ptr: *const c_void) -> usize;
491
492bitflags! {
493    /// Flags to enable/disable various builtin debugging tools.
494    #[repr(C)]
495    #[derive(Default, Deserialize, MallocSizeOf, Serialize)]
496    pub struct DebugFlags: u32 {
497        /// Display the frame profiler on screen.
498        const PROFILER_DBG          = 1 << 0;
499        /// Display intermediate render targets on screen.
500        const RENDER_TARGET_DBG     = 1 << 1;
501        /// Display all texture cache pages on screen.
502        const TEXTURE_CACHE_DBG     = 1 << 2;
503        /// Display GPU timing results.
504        const GPU_TIME_QUERIES      = 1 << 3;
505        /// Query the number of pixels that pass the depth test divided and show it
506        /// in the profiler as a percentage of the number of pixels in the screen
507        /// (window width times height).
508        const GPU_SAMPLE_QUERIES    = 1 << 4;
509        /// Render each quad with their own draw call.
510        ///
511        /// Terrible for performance but can help with understanding the drawing
512        /// order when inspecting renderdoc or apitrace recordings.
513        const DISABLE_BATCHING      = 1 << 5;
514        /// Display the pipeline epochs.
515        const EPOCHS                = 1 << 6;
516        /// Print driver messages to stdout.
517        const ECHO_DRIVER_MESSAGES  = 1 << 7;
518        /// Show an overlay displaying overdraw amount.
519        const SHOW_OVERDRAW         = 1 << 8;
520        /// Display the contents of GPU cache.
521        const GPU_CACHE_DBG         = 1 << 9;
522        /// Clear evicted parts of the texture cache for debugging purposes.
523        const TEXTURE_CACHE_DBG_CLEAR_EVICTED = 1 << 10;
524        /// Show picture caching debug overlay
525        const PICTURE_CACHING_DBG   = 1 << 11;
526        /// Highlight all primitives with colors based on kind.
527        const PRIMITIVE_DBG = 1 << 12;
528        /// Draw a zoom widget showing part of the framebuffer zoomed in.
529        const ZOOM_DBG = 1 << 13;
530        /// Scale the debug renderer down for a smaller screen. This will disrupt
531        /// any mapping between debug display items and page content, so shouldn't
532        /// be used with overlays like the picture caching or primitive display.
533        const SMALL_SCREEN = 1 << 14;
534        /// Disable various bits of the WebRender pipeline, to help narrow
535        /// down where slowness might be coming from.
536        const DISABLE_OPAQUE_PASS = 1 << 15;
537        ///
538        const DISABLE_ALPHA_PASS = 1 << 16;
539        ///
540        const DISABLE_CLIP_MASKS = 1 << 17;
541        ///
542        const DISABLE_TEXT_PRIMS = 1 << 18;
543        ///
544        const DISABLE_GRADIENT_PRIMS = 1 << 19;
545        ///
546        const OBSCURE_IMAGES = 1 << 20;
547        /// Taint the transparent area of the glyphs with a random opacity to easily
548        /// see when glyphs are re-rasterized.
549        const GLYPH_FLASHING = 1 << 21;
550        /// The profiler only displays information that is out of the ordinary.
551        const SMART_PROFILER        = 1 << 22;
552        /// If set, dump picture cache invalidation debug to console.
553        const INVALIDATION_DBG = 1 << 23;
554        /// Log tile cache to memory for later saving as part of wr-capture
555        const TILE_CACHE_LOGGING_DBG   = 1 << 24;
556        /// Collect and dump profiler statistics to captures.
557        const PROFILER_CAPTURE = (1 as u32) << 25; // need "as u32" until we have cbindgen#556
558        /// Invalidate picture tiles every frames (useful when inspecting GPU work in external tools).
559        const FORCE_PICTURE_INVALIDATION = (1 as u32) << 26;
560        const USE_BATCHED_TEXTURE_UPLOADS = (1 as u32) << 27;
561        const USE_DRAW_CALLS_FOR_TEXTURE_COPY = (1 as u32) << 28;
562    }
563}
564
565/// Information specific to a primitive type that
566/// uniquely identifies a primitive template by key.
567#[derive(Debug, Clone, Eq, MallocSizeOf, PartialEq, Hash, Serialize, Deserialize)]
568pub enum PrimitiveKeyKind {
569    /// Clear an existing rect, used for special effects on some platforms.
570    Clear,
571    ///
572    Rectangle {
573        ///
574        color: PropertyBinding<ColorU>,
575    },
576}
577
578///
579#[derive(Clone)]
580pub struct ScrollNodeState {
581    ///
582    pub id: ExternalScrollId,
583    ///
584    pub scroll_offset: LayoutVector2D,
585}
586
587///
588#[derive(Clone, Copy, Debug)]
589pub enum ScrollLocation {
590    /// Scroll by a certain amount.
591    Delta(LayoutVector2D),
592    /// Scroll to very top of element.
593    Start,
594    /// Scroll to very bottom of element.
595    End,
596}
597
598/// Crash annotations included in crash reports.
599#[repr(C)]
600#[derive(Clone, Copy)]
601pub enum CrashAnnotation {
602    CompileShader = 0,
603    DrawShader = 1,
604}
605
606/// Handler to expose support for annotating crash reports.
607pub trait CrashAnnotator : Send {
608    fn set(&self, annotation: CrashAnnotation, value: &std::ffi::CStr);
609    fn clear(&self, annotation: CrashAnnotation);
610    fn box_clone(&self) -> Box<dyn CrashAnnotator>;
611}
612
613impl Clone for Box<dyn CrashAnnotator> {
614    fn clone(&self) -> Box<dyn CrashAnnotator> {
615        self.box_clone()
616    }
617}
618
619/// Guard to add a crash annotation at creation, and clear it at destruction.
620pub struct CrashAnnotatorGuard<'a> {
621    annotator: &'a Option<Box<dyn CrashAnnotator>>,
622    annotation: CrashAnnotation,
623}
624
625impl<'a> CrashAnnotatorGuard<'a> {
626    pub fn new(
627        annotator: &'a Option<Box<dyn CrashAnnotator>>,
628        annotation: CrashAnnotation,
629        value: &std::ffi::CStr,
630    ) -> Self {
631        if let Some(ref annotator) = annotator {
632            annotator.set(annotation, value);
633        }
634        Self {
635            annotator,
636            annotation,
637        }
638    }
639}
640
641impl<'a> Drop for CrashAnnotatorGuard<'a> {
642    fn drop(&mut self) {
643        if let Some(ref annotator) = self.annotator {
644            annotator.clear(self.annotation);
645        }
646    }
647}