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:
Glenn Watson 2019-02-11 20:44:57 +00:00
Родитель a33f679ae0
Коммит 56ceb5073a
7 изменённых файлов: 74 добавлений и 48 удалений

Просмотреть файл

@ -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.