/* This Source Code Form is subject to the terms of the Mozilla Public *License,v.2.0.IfacopyoftheMPLwasnotdistributedwiththis
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
//! The `webrender_api` crate contains an assortment types and functions used //! by WebRender consumers as well as, in many cases, WebRender itself. //! //! This separation allows Servo to parallelize compilation across `webrender` //! and other crates that depend on `webrender_api`. So in practice, we put //! things in this crate when Servo needs to use them. Firefox depends on the //! `webrender` crate directly, and so this distinction is not really relevant //! there.
pubmod channel; mod color; #[cfg(feature = "debugger")] pubmod debugger; mod display_item; mod display_list; mod font; mod gradient_builder; mod image; mod tile_pool; pubmod units;
usecrate::units::*; usecrate::channel::Receiver; use std::marker::PhantomData; use std::sync::Arc; use std::os::raw::c_void; use peek_poke::PeekPoke;
/// Defined here for cbindgen pubconst MAX_RENDER_TASK_SIZE: i32 = 16384;
/// Width and height in device pixels of image tiles. pubtype TileSize = u16;
/// Various settings that the caller can select based on desired tradeoffs /// between rendering quality and performance / power usage. #[derive(Copy, Clone, Deserialize, Serialize)] pubstruct QualitySettings { /// If true, disable creating separate picture cache slices when the /// scroll root changes. This gives maximum opportunity to find an /// opaque background, which enables subpixel AA. However, it is /// usually significantly more expensive to render when scrolling. pub force_subpixel_aa_where_possible: bool,
}
impl Default for QualitySettings { fn default() -> Self {
QualitySettings { // Prefer performance over maximum subpixel AA quality, since WR // already enables subpixel AA in more situations than other browsers.
force_subpixel_aa_where_possible: false,
}
}
}
/// An epoch identifies the state of a pipeline in time. /// /// This is mostly used as a synchronization mechanism to observe how/when particular pipeline /// updates propagate through WebRender and are applied at various stages. #[repr(C)] #[derive(Clone, Copy, Debug, Deserialize, Eq, Hash, MallocSizeOf, Ord, PartialEq, PartialOrd, Serialize)] pubstruct Epoch(pub u32);
/// ID namespaces uniquely identify different users of WebRender's API. /// /// For example in Gecko each content process uses a separate id namespace. #[repr(C)] #[derive(Clone, Copy, Debug, Default, Eq, MallocSizeOf, PartialEq, Hash, Ord, PartialOrd, PeekPoke)] #[derive(Deserialize, Serialize)] pubstruct IdNamespace(pub u32);
/// A key uniquely identifying a WebRender document. /// /// Instances can manage one or several documents (using the same render backend thread). /// Each document will internally correspond to a single scene, and scenes are made of /// one or several pipelines. #[repr(C)] #[derive(Clone, Copy, Debug, Deserialize, Eq, Hash, MallocSizeOf, PartialEq, Serialize, PeekPoke)] pubstruct DocumentId { /// pub namespace_id: IdNamespace, /// pub id: u32,
}
/// This type carries no valuable semantics for WR. However, it reflects the fact that /// clients (Servo) may generate pipelines by different semi-independent sources. /// These pipelines still belong to the same `IdNamespace` and the same `DocumentId`. /// Having this extra Id field enables them to generate `PipelineId` without collision. pubtype PipelineSourceId = u32;
/// From the point of view of WR, `PipelineId` is completely opaque and generic as long as /// it's clonable, serializable, comparable, and hashable. #[repr(C)] #[derive(Clone, Copy, Debug, Deserialize, Eq, Hash, MallocSizeOf, PartialEq, Serialize, PeekPoke)] pubstruct PipelineId(pub PipelineSourceId, pub u32);
impl FramePublishId { /// Returns a FramePublishId corresponding to the first frame. /// /// Note that we use 0 as the internal id here because the current code /// increments the frame publish id just before ResultMsg::PublishDocument, /// and we want the first id to be 1. pubfn first() -> Self {
FramePublishId(0)
}
/// Advances this FramePublishId to the next. pubfn advance(&mutself) { self.0 += 1;
}
/// An invalid sentinel FramePublishId, which will always compare less than /// any valid FrameId. pubconst INVALID: Self = FramePublishId(0);
}
impl ExternalEvent { /// Creates the event from an opaque pointer-sized value. pubfn from_raw(raw: usize) -> Self {
ExternalEvent { raw }
} /// Consumes self to make it obvious that the event should be forwarded only once. pubfn unwrap(self) -> usize { self.raw
}
}
/// A flag in each scrollable frame to represent whether the owner of the frame document /// has any scroll-linked effect. /// See https://firefox-source-docs.mozilla.org/performance/scroll-linked_effects.html /// for a definition of scroll-linked effect. #[repr(u8)] #[derive(Clone, Copy, Debug, Default, Deserialize, PartialEq, Serialize, PeekPoke)] pubenum HasScrollLinkedEffect {
Yes, #[default]
No,
}
#[repr(C)] pubstruct MinimapData { pub is_root_content: bool, // All rects in local coords relative to the scrolled content's origin. pub visual_viewport: LayoutRect, pub layout_viewport: LayoutRect, pub scrollable_rect: LayoutRect, pub displayport: LayoutRect, // Populated for root content nodes only, otherwise the identity pub zoom_transform: LayoutTransform, // Populated for nodes in the subtree of a root content node // (outside such subtrees we'll have `root_content_scroll_id == 0`). // Stores the enclosing root content node's ExternalScrollId. pub root_content_pipeline_id: PipelineId, pub root_content_scroll_id: u64
}
#[repr(C)] pubstruct FrameReadyParams { pub present: bool, pub render: bool, pub scrolled: bool, /// Firefox uses this to indicate that the frame does not participate /// in the frame throttling mechanism. /// Frames from off-screen transactions are not tracked. pub tracked: bool,
}
/// A handler to integrate WebRender with the thread that contains the `Renderer`. pubtrait RenderNotifier: Send { /// fn clone(&self) -> Box<dyn RenderNotifier>; /// Wake the thread containing the `Renderer` up (after updates have been put /// in the renderer's queue). fn wake_up(
&self,
composite_needed: bool,
); /// Notify the thread containing the `Renderer` that a new frame is ready. fn new_frame_ready(&self, _: DocumentId, publish_id: FramePublishId, params: &FrameReadyParams); /// A Gecko-specific notification mechanism to get some code executed on the /// `Renderer`'s thread, mostly replaced by `NotificationHandler`. You should /// probably use the latter instead. fn external_event(&self, _evt: ExternalEvent) {
unimplemented!()
} /// Notify the thread containing the `Renderer` that the render backend has been /// shut down. fn shut_down(&self) {}
}
/// A stage of the rendering pipeline. #[repr(u32)] #[derive(Copy, Clone, Debug, PartialEq, Eq)] pubenum Checkpoint { ///
SceneBuilt, ///
FrameBuilt, ///
FrameTexturesUpdated, ///
FrameRendered, /// NotificationRequests get notified with this if they get dropped without having been /// notified. This provides the guarantee that if a request is created it will get notified.
TransactionDropped,
}
/// A handler to notify when a transaction reaches certain stages of the rendering /// pipeline. pubtrait NotificationHandler : Send + Sync { /// Entry point of the handler to implement. Invoked by WebRender. fn notify(&self, when: Checkpoint);
}
/// A request to notify a handler when the transaction reaches certain stages of the /// rendering pipeline. /// /// The request is guaranteed to be notified once and only once, even if the transaction /// is dropped before the requested check-point. pubstruct NotificationRequest {
handler: Option<Box<dyn NotificationHandler>>,
when: Checkpoint,
}
/// The specified stage at which point the handler should be notified. pubfn when(&self) -> Checkpoint { self.when }
/// Called by WebRender at specified stages to notify the registered handler. pubfn notify(mutself) { iflet Some(handler) = self.handler.take() {
handler.notify(self.when);
}
}
}
/// An object that can perform hit-testing without doing synchronous queries to /// the RenderBackendThread. pubtrait ApiHitTester: Send + Sync { /// Does a hit test on display items in the specified document, at the given /// point. The vector of hit results will contain all display items that match, /// ordered from front to back. fn hit_test(&self, point: WorldPoint) -> HitTestResult;
}
/// A hit tester requested to the render backend thread but not necessarily ready yet. /// /// The request should be resolved as late as possible to reduce the likelihood of blocking. pubstruct HitTesterRequest { #[doc(hidden)] pub rx: Receiver<Arc<dyn ApiHitTester>>,
}
impl HitTesterRequest { /// Block until the hit tester is available and return it, consuming teh request. pubfn resolve(self) -> Arc<dyn ApiHitTester> { self.rx.recv().unwrap()
}
}
/// Describe an item that matched a hit-test query. #[derive(Clone, Debug, Deserialize, PartialEq, Serialize)] pubstruct HitTestResultItem { /// The pipeline that the display item that was hit belongs to. pub pipeline: PipelineId,
/// The tag of the hit display item. pub tag: ItemTag,
/// The animation id from the stacking context. pub animation_id: u64,
}
/// Returned by `RenderApi::hit_test`. #[derive(Clone, Debug, Default, Deserialize, Serialize)] pubstruct HitTestResult { /// List of items that are match the hit-test query. pub items: Vec<HitTestResultItem>,
}
impl Drop for NotificationRequest { fn drop(&mutself) { iflet Some(refmut handler) = self.handler {
handler.notify(Checkpoint::TransactionDropped);
}
}
}
// This Clone impl yields an "empty" request because we don't want the requests // to be notified twice so the request is owned by only one of the API messages // (the original one) after the clone. // This works in practice because the notifications requests are used for // synchronization so we don't need to include them in the recording mechanism // in wrench that clones the messages. impl Clone for NotificationRequest { fn clone(&self) -> Self {
NotificationRequest {
when: self.when,
handler: None,
}
}
}
impl PropertyBindingId { /// Constructor. pubfn new(value: u64) -> Self {
PropertyBindingId {
namespace: IdNamespace((value >> 32) as u32),
uid: value as u32,
}
}
/// Decompose the ID back into the raw integer. pubfn to_u64(&self) -> u64 {
((self.namespace.0as u64) << 32) | self.uid as u64
}
}
/// A unique key that is used for connecting animated property /// values to bindings in the display list. #[repr(C)] #[derive(Clone, Copy, Debug, Default, Deserialize, Eq, Hash, MallocSizeOf, PartialEq, Serialize, PeekPoke)] pubstruct PropertyBindingKey<T> { /// pub id: PropertyBindingId, #[doc(hidden)] pub _phantom: PhantomData<T>,
}
/// Construct a property value from a given key and value. impl<T: Copy> PropertyBindingKey<T> { /// pubfn with(self, value: T) -> PropertyValue<T> {
PropertyValue { key: self, value }
}
}
/// A binding property can either be a specific value /// (the normal, non-animated case) or point to a binding location /// to fetch the current value from. /// Note that Binding has also a non-animated value, the value is /// used for the case where the animation is still in-delay phase /// (i.e. the animation doesn't produce any animation values). #[repr(C)] #[derive(Clone, Copy, Debug, Deserialize, Eq, Hash, MallocSizeOf, PartialEq, Serialize, PeekPoke)] pubenum PropertyBinding<T> { /// Non-animated value.
Value(T), /// Animated binding.
Binding(PropertyBindingKey<T>, T),
}
impl From<PropertyBinding<ColorF>> for PropertyBinding<ColorU> { fn from(value: PropertyBinding<ColorF>) -> PropertyBinding<ColorU> { match value {
PropertyBinding::Value(value) => PropertyBinding::Value(value.into()),
PropertyBinding::Binding(k, v) => {
PropertyBinding::Binding(k.into(), v.into())
}
}
}
}
impl From<PropertyBinding<ColorU>> for PropertyBinding<ColorF> { fn from(value: PropertyBinding<ColorU>) -> PropertyBinding<ColorF> { match value {
PropertyBinding::Value(value) => PropertyBinding::Value(value.into()),
PropertyBinding::Binding(k, v) => {
PropertyBinding::Binding(k.into(), v.into())
}
}
}
}
/// The current value of an animated property. This is /// supplied by the calling code. #[derive(Clone, Copy, Debug, Deserialize, Serialize, PartialEq)] pubstruct PropertyValue<T> { /// pub key: PropertyBindingKey<T>, /// pub value: T,
}
/// When using `generate_frame()`, a list of `PropertyValue` structures /// can optionally be supplied to provide the current value of any /// animated properties. #[derive(Clone, Deserialize, Serialize, Debug, PartialEq, Default)] pubstruct DynamicProperties { /// transform list pub transforms: Vec<PropertyValue<LayoutTransform>>, /// opacity pub floats: Vec<PropertyValue<f32>>, /// background color pub colors: Vec<PropertyValue<ColorF>>,
}
/// A C function that takes a pointer to a heap allocation and returns its size. /// /// This is borrowed from the malloc_size_of crate, upon which we want to avoid /// a dependency from WebRender. pubtype VoidPtrToSizeFn = unsafeextern"C"fn(ptr: *const c_void) -> usize;
/// A configuration option that can be changed at runtime. /// /// # Adding a new configuration option /// /// - Add a new enum variant here. /// - Add the entry in WR_BOOL_PARAMETER_LIST in gfxPlatform.cpp. /// - React to the parameter change anywhere in WebRender where a SetParam message is received. #[derive(Copy, Clone, Debug, PartialEq)] pubenum Parameter {
Bool(BoolParameter, bool),
Int(IntParameter, i32),
Float(FloatParameter, f32),
}
/// Floating point configuration option. #[derive(Copy, Clone, Debug, PartialEq, Eq)] #[repr(u32)] pubenum FloatParameter { /// The minimum time for the CPU portion of a frame to be considered slow
SlowCpuFrameThreshold = 0,
}
/// Flags to track why we are rendering. #[repr(C)] #[derive(Copy, PartialEq, Eq, Clone, PartialOrd, Ord, Hash, Default, Deserialize, MallocSizeOf, Serialize)] pubstruct RenderReasons(u32);
bitflags! { impl RenderReasons: u32 { /// Equivalent of empty() for the C++ side. const NONE = 0; const SCENE = 1 << 0; const ANIMATED_PROPERTY = 1 << 1; const RESOURCE_UPDATE = 1 << 2; const ASYNC_IMAGE = 1 << 3; const CLEAR_RESOURCES = 1 << 4; const APZ = 1 << 5; /// Window resize const RESIZE = 1 << 6; /// Various widget-related reasons const WIDGET = 1 << 7; /// See Frame::must_be_drawn const TEXTURE_CACHE_FLUSH = 1 << 8; const SNAPSHOT = 1 << 9; const POST_RESOURCE_UPDATES_HOOK = 1 << 10; const CONFIG_CHANGE = 1 << 11; const CONTENT_SYNC = 1 << 12; const FLUSH = 1 << 13; const TESTING = 1 << 14; const OTHER = 1 << 15; /// Vsync isn't actually "why" we render but it can be useful /// to see which frames were driven by the vsync scheduler so /// we store a bit for it. const VSYNC = 1 << 16; const SKIPPED_COMPOSITE = 1 << 17; /// Gecko does some special things when it starts observing vsync /// so it can be useful to know what frames are associated with it. const START_OBSERVING_VSYNC = 1 << 18; const ASYNC_IMAGE_COMPOSITE_UNTIL = 1 << 19;
}
}
bitflags! { impl DebugFlags: u64 { /// Display the frame profiler on screen. const PROFILER_DBG = 1 << 0; /// Display intermediate render targets on screen. const RENDER_TARGET_DBG = 1 << 1; /// Display all texture cache pages on screen. const TEXTURE_CACHE_DBG = 1 << 2; /// Display GPU timing results. const GPU_TIME_QUERIES = 1 << 3; /// Query the number of pixels that pass the depth test divided and show it /// in the profiler as a percentage of the number of pixels in the screen /// (window width times height). const GPU_SAMPLE_QUERIES = 1 << 4; /// Render each quad with their own draw call. /// /// Terrible for performance but can help with understanding the drawing /// order when inspecting renderdoc or apitrace recordings. const DISABLE_BATCHING = 1 << 5; /// Display the pipeline epochs. const EPOCHS = 1 << 6; /// Print driver messages to stdout. const ECHO_DRIVER_MESSAGES = 1 << 7; /// Show an overlay displaying overdraw amount. const SHOW_OVERDRAW = 1 << 8; /// Display the contents of GPU cache. const GPU_CACHE_DBG = 1 << 9; /// Clear evicted parts of the texture cache for debugging purposes. const TEXTURE_CACHE_DBG_CLEAR_EVICTED = 1 << 10; /// Show picture caching debug overlay const PICTURE_CACHING_DBG = 1 << 11; /// Draw a zoom widget showing part of the framebuffer zoomed in. const ZOOM_DBG = 1 << 13; /// Scale the debug renderer down for a smaller screen. This will disrupt /// any mapping between debug display items and page content, so shouldn't /// be used with overlays like the picture caching or primitive display. const SMALL_SCREEN = 1 << 14; /// Disable various bits of the WebRender pipeline, to help narrow /// down where slowness might be coming from. const DISABLE_OPAQUE_PASS = 1 << 15; /// const DISABLE_ALPHA_PASS = 1 << 16; /// const DISABLE_CLIP_MASKS = 1 << 17; /// const DISABLE_TEXT_PRIMS = 1 << 18; /// const DISABLE_GRADIENT_PRIMS = 1 << 19; /// const OBSCURE_IMAGES = 1 << 20; /// Taint the transparent area of the glyphs with a random opacity to easily /// see when glyphs are re-rasterized. const GLYPH_FLASHING = 1 << 21; /// The profiler only displays information that is out of the ordinary. const SMART_PROFILER = 1 << 22; /// If set, dump picture cache invalidation debug to console. const INVALIDATION_DBG = 1 << 23; /// Collect and dump profiler statistics to captures. const PROFILER_CAPTURE = 1 << 25; /// Invalidate picture tiles every frames (useful when inspecting GPU work in external tools). const FORCE_PICTURE_INVALIDATION = 1 << 26; /// Display window visibility on screen. const WINDOW_VISIBILITY_DBG = 1 << 27; /// Render large blobs with at a smaller size (incorrectly). This is a temporary workaround for /// fuzzing. const RESTRICT_BLOB_SIZE = 1 << 28; /// Enable surface promotion logging. const SURFACE_PROMOTION_LOGGING = 1 << 29; /// Show picture caching debug overlay. const PICTURE_BORDERS = 1 << 30; /// Panic when a attempting to display a missing stacking context snapshot. const MISSING_SNAPSHOT_PANIC = (1as u64) << 31; // need "as u32" until we have cbindgen#556 /// Panic when a attempting to display a missing stacking context snapshot. const MISSING_SNAPSHOT_PINK = (1as u64) << 32; /// Highlight backdrop filters const HIGHLIGHT_BACKDROP_FILTERS = (1as u64) << 33; /// Show external composite border rects in debug overlay. /// TODO: Add native compositor support const EXTERNAL_COMPOSITE_BORDERS = (1as u64) << 34; /// Dump the frame spatial tree to stderr. const DUMP_SPATIAL_TREE = (1as u64) << 35;
}
}
/// #[derive(Clone, Copy, Debug)] pubenum ScrollLocation { /// Scroll by a certain amount.
Delta(LayoutVector2D), /// Scroll to very top of element.
Start, /// Scroll to very bottom of element.
End,
}
/// Guard to add a crash annotation at creation, and clear it at destruction. pubstruct CrashAnnotatorGuard<'a> {
annotator: &'a Option<Box<dyn CrashAnnotator>>,
annotation: CrashAnnotation,
}
impl<'a> Drop for CrashAnnotatorGuard<'a> { fn drop(&mutself) { iflet Some(ref annotator) = self.annotator {
annotator.clear(self.annotation);
}
}
}
/// A little bit of extra information to make memory reports more useful #[derive(Copy, Clone, Debug, Eq, PartialEq)] #[cfg_attr(feature = "serialize", derive(Serialize))] #[cfg_attr(feature = "deserialize", derive(Deserialize))] pubenum TextureCacheCategory {
Atlas,
Standalone,
PictureTile,
RenderTarget,
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.