Skip to main content

webrender/invalidation/
mod.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//! Invalidation tracking and dirty region management
6//!
7//! This module contains types and logic for tracking dirty regions and
8//! dependencies used to determine what needs to be redrawn each frame.
9
10pub mod compare;
11pub mod quadtree;
12pub mod cached_surface;
13pub mod vert_buffer;
14
15use api::units::*;
16use crate::spatial_tree::{SpatialTree, SpatialNodeIndex};
17use crate::space::SpaceMapper;
18use crate::util::MaxRect;
19
20/// Represents the dirty region of a tile cache picture, relative to a
21/// "visibility" spatial node. At the moment the visibility node is
22/// world space, but the plan is to switch to raster space.
23///
24/// The plan is to move away from these world space representation and
25/// compute dirty regions in raster space instead.
26#[derive(Clone)]
27pub struct DirtyRegion {
28    /// The overall dirty rect, a combination of dirty_rects
29    pub combined: VisRect,
30
31    /// The corrdinate space used to do clipping, visibility, and
32    /// dirty rect calculations.
33    pub visibility_spatial_node: SpatialNodeIndex,
34    /// Spatial node of the picture this region represents.
35    local_spatial_node: SpatialNodeIndex,
36}
37
38impl DirtyRegion {
39    /// Construct a new dirty region tracker.
40    pub fn new(
41        visibility_spatial_node: SpatialNodeIndex,
42        local_spatial_node: SpatialNodeIndex,
43    ) -> Self {
44        DirtyRegion {
45            combined: VisRect::zero(),
46            visibility_spatial_node,
47            local_spatial_node,
48        }
49    }
50
51    /// Reset the dirty regions back to empty
52    pub fn reset(
53        &mut self,
54        visibility_spatial_node: SpatialNodeIndex,
55        local_spatial_node: SpatialNodeIndex,
56    ) {
57        self.combined = VisRect::zero();
58        self.visibility_spatial_node = visibility_spatial_node;
59        self.local_spatial_node = local_spatial_node;
60    }
61
62    /// Add a dirty region to the tracker. Returns the visibility mask that corresponds to
63    /// this region in the tracker.
64    pub fn add_dirty_region(
65        &mut self,
66        rect_in_pic_space: PictureRect,
67        spatial_tree: &SpatialTree,
68    ) {
69        let map_pic_to_raster = SpaceMapper::new_with_target(
70            self.visibility_spatial_node,
71            self.local_spatial_node,
72            VisRect::max_rect(),
73            spatial_tree,
74        );
75
76        let raster_rect = map_pic_to_raster
77            .map(&rect_in_pic_space)
78            .expect("bug");
79
80        // Include this in the overall dirty rect
81        self.combined = self.combined.union(&raster_rect);
82    }
83}
84
85/// Debugging information about why a tile was invalidated
86#[derive(Debug,Clone)]
87#[cfg_attr(feature = "capture", derive(Serialize))]
88#[cfg_attr(feature = "replay", derive(Deserialize))]
89pub enum InvalidationReason {
90    /// The background color changed
91    BackgroundColor,
92    /// The opaque state of the backing native surface changed
93    SurfaceOpacityChanged,
94    /// There was no backing texture (evicted or never rendered)
95    NoTexture,
96    /// There was no backing native surface (never rendered, or recreated)
97    NoSurface,
98    /// The primitive count in the dependency list was different
99    PrimCount,
100    /// The content of one of the primitives was different
101    Content,
102    // The compositor type changed
103    CompositorKindChanged,
104    // The valid region of the tile changed
105    ValidRectChanged,
106    // The overall scale of the picture cache changed
107    ScaleChanged,
108    // The content of the sampling surface changed
109    SurfaceContentChanged,
110}
111
112/// The result of a primitive dependency comparison. Size is a u8
113/// since this is a hot path in the code, and keeping the data small
114/// is a performance win.
115#[derive(Debug, Copy, Clone, PartialEq)]
116#[cfg_attr(feature = "capture", derive(Serialize))]
117#[cfg_attr(feature = "replay", derive(Deserialize))]
118#[repr(u8)]
119pub enum PrimitiveCompareResult {
120    /// Primitives match
121    Equal,
122    /// Something in the PrimitiveDescriptor was different
123    Descriptor,
124    /// A clip corner changed (vert range values differ)
125    Clip,
126    /// An image dependency was dirty
127    Image,
128    /// The value of an opacity binding changed
129    OpacityBinding,
130    /// The value of a color binding changed
131    ColorBinding,
132}