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