зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1526856 - Reduce GPU cache uploads a bit. r=kvark,nical
By retaining a global GPU cache handle for a dummy image block, we can reduce the per-frame GPU cache uploads quite a bit, which helps with compositor time. Differential Revision: https://phabricator.services.mozilla.com/D19326 --HG-- extra : moz-landing-system : lando
This commit is contained in:
Родитель
a33f679ae0
Коммит
56ceb5073a
|
@ -962,7 +962,7 @@ impl AlphaBatchBuilder {
|
|||
PrimitiveInstanceKind::Picture { pic_index, .. } => {
|
||||
let picture = &ctx.prim_store.pictures[pic_index.0];
|
||||
let non_segmented_blend_mode = BlendMode::PremultipliedAlpha;
|
||||
let prim_cache_address = gpu_cache.get_address(&picture.gpu_location);
|
||||
let prim_cache_address = gpu_cache.get_address(&ctx.globals.default_image_handle);
|
||||
|
||||
let prim_header = PrimitiveHeader {
|
||||
local_rect: picture.local_rect,
|
||||
|
@ -1906,7 +1906,7 @@ impl AlphaBatchBuilder {
|
|||
image_data.alpha_type,
|
||||
get_shader_opacity(opacity_binding),
|
||||
) {
|
||||
let prim_cache_address = gpu_cache.get_address(&tile.handle);
|
||||
let prim_cache_address = gpu_cache.get_address(&ctx.globals.default_image_handle);
|
||||
let prim_header = PrimitiveHeader {
|
||||
specific_prim_address: prim_cache_address,
|
||||
local_rect: tile.local_rect,
|
||||
|
|
|
@ -3,12 +3,12 @@
|
|||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
use api::{ColorF, DeviceIntPoint, DevicePixelScale, LayoutPixel, PicturePixel, RasterPixel};
|
||||
use api::{DeviceIntRect, DeviceIntSize, DocumentLayer, FontRenderMode, DebugFlags};
|
||||
use api::{DeviceIntRect, DeviceIntSize, DocumentLayer, FontRenderMode, DebugFlags, PremultipliedColorF};
|
||||
use api::{LayoutPoint, LayoutRect, LayoutSize, PipelineId, RasterSpace, WorldPoint, WorldRect, WorldPixel};
|
||||
use clip::{ClipDataStore, ClipStore, ClipChainStack};
|
||||
use clip_scroll_tree::{ClipScrollTree, ROOT_SPATIAL_NODE_INDEX, SpatialNodeIndex};
|
||||
use display_list_flattener::{DisplayListFlattener};
|
||||
use gpu_cache::GpuCache;
|
||||
use gpu_cache::{GpuCache, GpuCacheHandle};
|
||||
use gpu_types::{PrimitiveHeaders, TransformPalette, UvRectKind, ZBufferIdGenerator};
|
||||
use hit_test::{HitTester, HitTestingRun};
|
||||
use internal_types::{FastHashMap, PlaneSplitter};
|
||||
|
@ -57,6 +57,39 @@ pub struct FrameBuilderConfig {
|
|||
pub testing: bool,
|
||||
}
|
||||
|
||||
/// A set of common / global resources that are retained between
|
||||
/// new display lists, such that any GPU cache handles can be
|
||||
/// persisted even when a new display list arrives.
|
||||
pub struct FrameGlobalResources {
|
||||
/// The image shader block for the most common / default
|
||||
/// set of image parameters (color white, stretch == rect.size).
|
||||
pub default_image_handle: GpuCacheHandle,
|
||||
}
|
||||
|
||||
impl FrameGlobalResources {
|
||||
pub fn empty() -> Self {
|
||||
FrameGlobalResources {
|
||||
default_image_handle: GpuCacheHandle::new(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn update(
|
||||
&mut self,
|
||||
gpu_cache: &mut GpuCache,
|
||||
) {
|
||||
if let Some(mut request) = gpu_cache.request(&mut self.default_image_handle) {
|
||||
request.push(PremultipliedColorF::WHITE);
|
||||
request.push(PremultipliedColorF::WHITE);
|
||||
request.push([
|
||||
-1.0, // -ve means use prim rect for stretch size
|
||||
0.0,
|
||||
0.0,
|
||||
0.0,
|
||||
]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// A builder structure for `tiling::Frame`
|
||||
#[cfg_attr(feature = "capture", derive(Serialize))]
|
||||
pub struct FrameBuilder {
|
||||
|
@ -72,6 +105,7 @@ pub struct FrameBuilder {
|
|||
#[cfg_attr(feature = "capture", serde(skip))] //TODO
|
||||
pub hit_testing_runs: Vec<HitTestingRun>,
|
||||
pub config: FrameBuilderConfig,
|
||||
pub globals: FrameGlobalResources,
|
||||
}
|
||||
|
||||
pub struct FrameVisibilityContext<'a> {
|
||||
|
@ -193,6 +227,7 @@ impl FrameBuilder {
|
|||
background_color: None,
|
||||
root_pic_index: PictureIndex(0),
|
||||
pending_retained_tiles: RetainedTiles::new(),
|
||||
globals: FrameGlobalResources::empty(),
|
||||
config: FrameBuilderConfig {
|
||||
default_font_render_mode: FontRenderMode::Mono,
|
||||
dual_source_blending_is_enabled: true,
|
||||
|
@ -207,12 +242,14 @@ impl FrameBuilder {
|
|||
/// Provide any cached surface tiles from the previous frame builder
|
||||
/// to a new frame builder. These will be consumed or dropped the
|
||||
/// first time a new frame builder creates a frame.
|
||||
pub fn set_retained_tiles(
|
||||
pub fn set_retained_resources(
|
||||
&mut self,
|
||||
retained_tiles: RetainedTiles,
|
||||
globals: FrameGlobalResources,
|
||||
) {
|
||||
debug_assert!(self.pending_retained_tiles.tiles.is_empty());
|
||||
self.pending_retained_tiles = retained_tiles;
|
||||
self.globals = globals;
|
||||
}
|
||||
|
||||
pub fn with_display_list_flattener(
|
||||
|
@ -231,6 +268,7 @@ impl FrameBuilder {
|
|||
window_size,
|
||||
pending_retained_tiles: RetainedTiles::new(),
|
||||
config: flattener.config,
|
||||
globals: FrameGlobalResources::empty(),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -240,7 +278,7 @@ impl FrameBuilder {
|
|||
self,
|
||||
retained_tiles: &mut RetainedTiles,
|
||||
clip_scroll_tree: &ClipScrollTree,
|
||||
) {
|
||||
) -> FrameGlobalResources {
|
||||
self.prim_store.destroy(
|
||||
retained_tiles,
|
||||
clip_scroll_tree,
|
||||
|
@ -255,6 +293,8 @@ impl FrameBuilder {
|
|||
// avoid this, if there are still pending tiles, include them in
|
||||
// the retained tiles passed to the next frame builder.
|
||||
retained_tiles.merge(self.pending_retained_tiles);
|
||||
|
||||
self.globals
|
||||
}
|
||||
|
||||
/// Compute the contribution (bounding rectangles, and resources) of layers and their
|
||||
|
@ -474,6 +514,8 @@ impl FrameBuilder {
|
|||
resource_cache.begin_frame(stamp);
|
||||
gpu_cache.begin_frame(stamp);
|
||||
|
||||
self.globals.update(gpu_cache);
|
||||
|
||||
let mut transform_palette = TransformPalette::new();
|
||||
clip_scroll_tree.update_tree(
|
||||
pan,
|
||||
|
@ -557,6 +599,7 @@ impl FrameBuilder {
|
|||
surfaces: &surfaces,
|
||||
scratch,
|
||||
screen_world_rect,
|
||||
globals: &self.globals,
|
||||
};
|
||||
|
||||
pass.build(
|
||||
|
|
|
@ -1524,18 +1524,20 @@ impl TileCache {
|
|||
// every frame, which is wasteful.
|
||||
if tile.same_frames >= FRAMES_BEFORE_PICTURE_CACHING {
|
||||
// Ensure that this texture is allocated.
|
||||
resource_cache.texture_cache.update(
|
||||
&mut tile.handle,
|
||||
descriptor,
|
||||
TextureFilter::Linear,
|
||||
None,
|
||||
[0.0; 3],
|
||||
DirtyRect::All,
|
||||
gpu_cache,
|
||||
None,
|
||||
UvRectKind::Rect,
|
||||
Eviction::Eager,
|
||||
);
|
||||
if !resource_cache.texture_cache.is_allocated(&tile.handle) {
|
||||
resource_cache.texture_cache.update(
|
||||
&mut tile.handle,
|
||||
descriptor,
|
||||
TextureFilter::Linear,
|
||||
None,
|
||||
[0.0; 3],
|
||||
DirtyRect::All,
|
||||
gpu_cache,
|
||||
None,
|
||||
UvRectKind::Rect,
|
||||
Eviction::Eager,
|
||||
);
|
||||
}
|
||||
|
||||
let cache_item = resource_cache
|
||||
.get_texture_cache_item(&tile.handle);
|
||||
|
@ -2191,8 +2193,6 @@ pub struct PicturePrimitive {
|
|||
/// Local clip rect for this picture.
|
||||
pub local_clip_rect: LayoutRect,
|
||||
|
||||
pub gpu_location: GpuCacheHandle,
|
||||
|
||||
/// If Some(..) the tile cache that is associated with this picture.
|
||||
#[cfg_attr(feature = "capture", serde(skip))] //TODO
|
||||
pub tile_cache: Option<TileCache>,
|
||||
|
@ -2306,7 +2306,6 @@ impl PicturePrimitive {
|
|||
spatial_node_index,
|
||||
local_rect: LayoutRect::zero(),
|
||||
local_clip_rect,
|
||||
gpu_location: GpuCacheHandle::new(),
|
||||
tile_cache,
|
||||
options,
|
||||
}
|
||||
|
@ -2800,7 +2799,6 @@ impl PicturePrimitive {
|
|||
// stretch size from the segment rect in the shaders, we can
|
||||
// remove this invalidation here completely.
|
||||
if self.local_rect != surface_rect {
|
||||
gpu_cache.invalidate(&self.gpu_location);
|
||||
if let PictureCompositeMode::Filter(FilterOp::DropShadow(..)) = raster_config.composite_mode {
|
||||
gpu_cache.invalidate(&self.extra_gpu_data_handle);
|
||||
}
|
||||
|
|
|
@ -10,7 +10,7 @@ use api::{
|
|||
use api::ImageKey as ApiImageKey;
|
||||
use display_list_flattener::{AsInstanceKind, CreateShadow, IsVisible};
|
||||
use frame_builder::FrameBuildingState;
|
||||
use gpu_cache::{GpuCacheHandle, GpuDataRequest};
|
||||
use gpu_cache::{GpuDataRequest};
|
||||
use intern::{Internable, InternDebug};
|
||||
use intern_types;
|
||||
use prim_store::{
|
||||
|
@ -31,7 +31,6 @@ use util::pack_as_float;
|
|||
#[cfg_attr(feature = "replay", derive(Deserialize))]
|
||||
pub struct VisibleImageTile {
|
||||
pub tile_offset: TileOffset,
|
||||
pub handle: GpuCacheHandle,
|
||||
pub edge_flags: EdgeAaSegmentMask,
|
||||
pub local_rect: LayoutRect,
|
||||
pub local_clip_rect: LayoutRect,
|
||||
|
|
|
@ -2350,17 +2350,6 @@ impl PrimitiveStore {
|
|||
} else {
|
||||
prim_instance.visibility_info = PrimitiveVisibilityIndex::INVALID;
|
||||
}
|
||||
|
||||
if let Some(mut request) = frame_state.gpu_cache.request(&mut pic.gpu_location) {
|
||||
request.push(PremultipliedColorF::WHITE);
|
||||
request.push(PremultipliedColorF::WHITE);
|
||||
request.push([
|
||||
-1.0, // -ve means use prim rect for stretch size
|
||||
0.0,
|
||||
0.0,
|
||||
0.0,
|
||||
]);
|
||||
}
|
||||
}
|
||||
PrimitiveInstanceKind::TextRun { .. } |
|
||||
PrimitiveInstanceKind::Clear { .. } |
|
||||
|
@ -2769,16 +2758,8 @@ impl PrimitiveStore {
|
|||
frame_state.gpu_cache,
|
||||
);
|
||||
|
||||
let mut handle = GpuCacheHandle::new();
|
||||
if let Some(mut request) = frame_state.gpu_cache.request(&mut handle) {
|
||||
request.push(PremultipliedColorF::WHITE);
|
||||
request.push(PremultipliedColorF::WHITE);
|
||||
request.push([tile.rect.size.width, tile.rect.size.height, 0.0, 0.0]);
|
||||
}
|
||||
|
||||
image_instance.visible_tiles.push(VisibleImageTile {
|
||||
tile_offset: tile.offset,
|
||||
handle,
|
||||
edge_flags: tile.edge_flags & edge_flags,
|
||||
local_rect: tile.rect,
|
||||
local_clip_rect: tight_clip_rect,
|
||||
|
|
|
@ -611,15 +611,18 @@ impl Document {
|
|||
// surface tiles, that can be provided to the next frame builder.
|
||||
let mut retained_tiles = RetainedTiles::new();
|
||||
if let Some(frame_builder) = self.frame_builder.take() {
|
||||
frame_builder.destroy(
|
||||
let globals = frame_builder.destroy(
|
||||
&mut retained_tiles,
|
||||
&self.clip_scroll_tree,
|
||||
);
|
||||
}
|
||||
|
||||
// Provide any cached tiles from the previous frame builder to
|
||||
// the newly built one.
|
||||
built_scene.frame_builder.set_retained_tiles(retained_tiles);
|
||||
// Provide any cached tiles from the previous frame builder to
|
||||
// the newly built one.
|
||||
built_scene.frame_builder.set_retained_resources(
|
||||
retained_tiles,
|
||||
globals,
|
||||
);
|
||||
}
|
||||
|
||||
self.frame_builder = Some(built_scene.frame_builder);
|
||||
|
||||
|
|
|
@ -12,6 +12,7 @@ use debug_render::DebugItem;
|
|||
use device::{Texture};
|
||||
#[cfg(feature = "pathfinder")]
|
||||
use euclid::{TypedPoint2D, TypedVector2D};
|
||||
use frame_builder::FrameGlobalResources;
|
||||
use gpu_cache::{GpuCache};
|
||||
use gpu_types::{BorderInstance, BlurDirection, BlurInstance, PrimitiveHeaders, ScalingInstance};
|
||||
use gpu_types::{TransformData, TransformPalette, ZBufferIdGenerator};
|
||||
|
@ -58,6 +59,7 @@ pub struct RenderTargetContext<'a, 'rc> {
|
|||
pub surfaces: &'a [SurfaceInfo],
|
||||
pub scratch: &'a PrimitiveScratchBuffer,
|
||||
pub screen_world_rect: WorldRect,
|
||||
pub globals: &'a FrameGlobalResources,
|
||||
}
|
||||
|
||||
/// Represents a number of rendering operations on a surface.
|
||||
|
|
Загрузка…
Ссылка в новой задаче