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}