Bug 1548405 - Do all resource requests during visibility pass in WR. r=kvark

This builds on earlier patches to move all remaining resource requests
to occur during the visibility pass, and change the block on glyph
rasterization to occur after the visibility pass.

This allows batch generation to occur during the prepare_prims pass,
which is useful for generating a batch set per-dirty-region, while
only doing a single pass of the picture / primitive tree.

Differential Revision: https://phabricator.services.mozilla.com/D29584

--HG--
extra : moz-landing-system : lando
This commit is contained in:
Glenn Watson 2019-05-02 01:54:32 +00:00
Родитель 7a98bf47e2
Коммит 51efa36789
5 изменённых файлов: 160 добавлений и 124 удалений

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

@ -271,6 +271,7 @@ impl ClipNodeInfo {
gpu_cache: &mut GpuCache,
resource_cache: &mut ResourceCache,
clip_scroll_tree: &ClipScrollTree,
request_resources: bool,
) -> ClipNodeInstance {
// Calculate some flags that are required for the segment
// building logic.
@ -341,10 +342,12 @@ impl ClipNodeInfo {
tile_size as i32,
);
for tile in tiles {
resource_cache.request_image(
request.with_tile(tile.offset),
gpu_cache,
);
if request_resources {
resource_cache.request_image(
request.with_tile(tile.offset),
gpu_cache,
);
}
mask_tiles.push(VisibleMaskImageTile {
tile_offset: tile.offset,
tile_rect: tile.rect,
@ -352,7 +355,7 @@ impl ClipNodeInfo {
}
}
visible_tiles = Some(mask_tiles);
} else {
} else if request_resources {
resource_cache.request_image(request, gpu_cache);
}
}
@ -589,6 +592,7 @@ impl ClipStore {
device_pixel_scale: DevicePixelScale,
world_rect: &WorldRect,
clip_data_store: &mut ClipDataStore,
request_resources: bool,
) -> Option<ClipChainInstance> {
let mut local_clip_rect = local_prim_clip_rect;
@ -680,6 +684,7 @@ impl ClipStore {
gpu_cache,
resource_cache,
clip_scroll_tree,
request_resources,
);
// As a special case, a partial accept of a clip rect that is

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

@ -311,6 +311,7 @@ impl FrameBuilder {
surfaces: &mut Vec<SurfaceInfo>,
scratch: &mut PrimitiveScratchBuffer,
debug_flags: DebugFlags,
texture_cache_profile: &mut TextureCacheProfileCounters,
) -> Option<RenderTaskId> {
profile_scope!("cull");
@ -406,6 +407,14 @@ impl FrameBuilder {
);
}
{
profile_marker!("BlockOnResources");
resource_cache.block_until_all_resources_added(gpu_cache,
render_tasks,
texture_cache_profile);
}
let mut frame_state = FrameBuildingState {
render_tasks,
profile_counters,
@ -553,16 +562,9 @@ impl FrameBuilder {
&mut surfaces,
scratch,
debug_flags,
texture_cache_profile,
);
{
profile_marker!("BlockOnResources");
resource_cache.block_until_all_resources_added(gpu_cache,
&mut render_tasks,
texture_cache_profile);
}
let mut passes;
let mut deferred_resolves = vec![];
let mut has_texture_cache_tasks = false;

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

@ -8,7 +8,7 @@ use border::create_border_segments;
use border::NormalBorderAu;
use display_list_flattener::{CreateShadow, IsVisible};
use frame_builder::{FrameBuildingState};
use gpu_cache::GpuDataRequest;
use gpu_cache::{GpuCache, GpuDataRequest};
use intern;
use internal_types::LayoutPrimitiveInfo;
use prim_store::{
@ -17,7 +17,7 @@ use prim_store::{
PrimitiveInstanceKind, PrimitiveOpacity, PrimitiveSceneData,
PrimitiveStore, InternablePrimitive,
};
use resource_cache::ImageRequest;
use resource_cache::{ImageRequest, ResourceCache};
use storage;
#[cfg_attr(feature = "capture", derive(Serialize))]
@ -248,10 +248,6 @@ impl ImageBorderData {
.get_image_properties(self.request.key);
common.opacity = if let Some(image_properties) = image_properties {
frame_state.resource_cache.request_image(
self.request,
frame_state.gpu_cache,
);
PrimitiveOpacity {
is_opaque: image_properties.descriptor.is_opaque,
}
@ -260,6 +256,17 @@ impl ImageBorderData {
}
}
pub fn request_resources(
&mut self,
resource_cache: &mut ResourceCache,
gpu_cache: &mut GpuCache,
) {
resource_cache.request_image(
self.request,
gpu_cache,
);
}
fn write_prim_gpu_blocks(
&self,
request: &mut GpuDataRequest,

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

@ -10,7 +10,7 @@ use api::{
use api::units::*;
use display_list_flattener::{CreateShadow, IsVisible};
use frame_builder::FrameBuildingState;
use gpu_cache::{GpuDataRequest};
use gpu_cache::{GpuCache, GpuDataRequest};
use intern::{Internable, InternDebug, Handle as InternHandle};
use internal_types::LayoutPrimitiveInfo;
use prim_store::{
@ -23,7 +23,7 @@ use render_task::{
BlitSource, RenderTask, RenderTaskCacheEntryHandle, RenderTaskCacheKey,
RenderTaskCacheKeyKind
};
use resource_cache::ImageRequest;
use resource_cache::{ImageRequest, ResourceCache};
use util::pack_as_float;
#[derive(Debug)]
@ -188,7 +188,6 @@ impl ImageData {
};
}
let mut request_source_image = false;
let mut is_opaque = image_properties.descriptor.is_opaque;
let request = ImageRequest {
key: self.key,
@ -231,10 +230,6 @@ impl ImageData {
None,
image_properties.descriptor.is_opaque,
|render_tasks| {
// We need to render the image cache this frame,
// so will need access to the source texture.
request_source_image = true;
// Create a task to blit from the texture cache to
// a normal transient render task surface. This will
// copy only the sub-rect, if specified.
@ -259,17 +254,7 @@ impl ImageData {
}
));
}
ImageSource::Default => {
// Normal images just reference the source texture each frame.
request_source_image = true;
}
}
if request_source_image && !is_tiled {
frame_state.resource_cache.request_image(
request,
frame_state.gpu_cache,
);
ImageSource::Default => {}
}
if is_opaque {
@ -446,20 +431,26 @@ impl YuvImageData {
self.write_prim_gpu_blocks(&mut request);
};
common.opacity = PrimitiveOpacity::translucent();
}
pub fn request_resources(
&mut self,
resource_cache: &mut ResourceCache,
gpu_cache: &mut GpuCache,
) {
let channel_num = self.format.get_plane_num();
debug_assert!(channel_num <= 3);
for channel in 0 .. channel_num {
frame_state.resource_cache.request_image(
resource_cache.request_image(
ImageRequest {
key: self.yuv_key[channel],
rendering: self.image_rendering,
tile: None,
},
frame_state.gpu_cache,
gpu_cache,
);
}
common.opacity = PrimitiveOpacity::translucent();
}
pub fn write_prim_gpu_blocks(&self, request: &mut GpuDataRequest) {

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

@ -1931,6 +1931,7 @@ impl PrimitiveStore {
surface.device_pixel_scale,
&frame_context.screen_world_rect,
&mut frame_state.data_stores.clip,
true,
);
// Ensure the primitive clip is popped
@ -2009,17 +2010,17 @@ impl PrimitiveStore {
}
);
prim_instance.visibility_info = vis_index;
self.request_resources_for_prim(
prim_instance,
surface,
raster_space,
&map_local_to_surface,
frame_context,
frame_state,
);
prim_instance.visibility_info = vis_index;
}
}
let pic = &mut self.pictures[pic_index.0];
@ -2043,9 +2044,10 @@ impl PrimitiveStore {
fn request_resources_for_prim(
&mut self,
prim_instance: &PrimitiveInstance,
prim_instance: &mut PrimitiveInstance,
surface: &SurfaceInfo,
raster_space: RasterSpace,
map_local_to_surface: &SpaceMapper<LayoutPixel, PicturePixel>,
frame_context: &FrameVisibilityContext,
frame_state: &mut FrameVisibilityState,
) {
@ -2076,6 +2078,113 @@ impl PrimitiveStore {
frame_state.scratch,
);
}
PrimitiveInstanceKind::Image { data_handle, image_instance_index, .. } => {
let prim_data = &mut frame_state.data_stores.image[data_handle];
let common_data = &mut prim_data.common;
let image_data = &mut prim_data.kind;
let image_instance = &mut self.images[image_instance_index];
let image_properties = frame_state
.resource_cache
.get_image_properties(image_data.key);
let request = ImageRequest {
key: image_data.key,
rendering: image_data.image_rendering,
tile: None,
};
match image_properties {
Some(ImageProperties { tiling: None, .. }) => {
frame_state.resource_cache.request_image(
request,
frame_state.gpu_cache,
);
}
Some(ImageProperties { descriptor, tiling: Some(tile_size), .. }) => {
image_instance.visible_tiles.clear();
let device_image_rect = DeviceIntRect::from_size(descriptor.size);
// Tighten the clip rect because decomposing the repeated image can
// produce primitives that are partially covering the original image
// rect and we want to clip these extra parts out.
let prim_info = &frame_state.scratch.prim_info[prim_instance.visibility_info.0 as usize];
let prim_rect = LayoutRect::new(
prim_instance.prim_origin,
common_data.prim_size,
);
let tight_clip_rect = prim_info
.combined_local_clip_rect
.intersection(&prim_rect).unwrap();
image_instance.tight_local_clip_rect = tight_clip_rect;
let visible_rect = compute_conservative_visible_rect(
&tight_clip_rect,
map_local_to_surface,
);
let base_edge_flags = edge_flags_for_tile_spacing(&image_data.tile_spacing);
let stride = image_data.stretch_size + image_data.tile_spacing;
let repetitions = ::image::repetitions(
&prim_rect,
&visible_rect,
stride,
);
for Repetition { origin, edge_flags } in repetitions {
let edge_flags = base_edge_flags | edge_flags;
let layout_image_rect = LayoutRect {
origin,
size: image_data.stretch_size,
};
let tiles = ::image::tiles(
&layout_image_rect,
&visible_rect,
&device_image_rect,
tile_size as i32,
);
for tile in tiles {
frame_state.resource_cache.request_image(
request.with_tile(tile.offset),
frame_state.gpu_cache,
);
image_instance.visible_tiles.push(VisibleImageTile {
tile_offset: tile.offset,
edge_flags: tile.edge_flags & edge_flags,
local_rect: tile.rect,
local_clip_rect: tight_clip_rect,
});
}
}
if image_instance.visible_tiles.is_empty() {
// Mark as invisible
prim_instance.visibility_info = PrimitiveVisibilityIndex::INVALID;
}
}
None => {}
}
}
PrimitiveInstanceKind::ImageBorder { data_handle, .. } => {
let prim_data = &mut frame_state.data_stores.image_border[data_handle];
prim_data.kind.request_resources(
frame_state.resource_cache,
frame_state.gpu_cache,
);
}
PrimitiveInstanceKind::YuvImage { data_handle, .. } => {
let prim_data = &mut frame_state.data_stores.yuv_image[data_handle];
prim_data.kind.request_resources(
frame_state.resource_cache,
frame_state.gpu_cache,
);
}
_ => {}
}
}
@ -2709,85 +2818,6 @@ impl PrimitiveStore {
frame_context.scene_properties,
);
image_instance.visible_tiles.clear();
let image_properties = frame_state
.resource_cache
.get_image_properties(image_data.key);
if let Some(ImageProperties { descriptor, tiling: Some(tile_size), .. }) = image_properties {
let device_image_rect = DeviceIntRect::from_size(descriptor.size);
// Tighten the clip rect because decomposing the repeated image can
// produce primitives that are partially covering the original image
// rect and we want to clip these extra parts out.
let prim_info = &scratch.prim_info[prim_instance.visibility_info.0 as usize];
let prim_rect = LayoutRect::new(
prim_instance.prim_origin,
common_data.prim_size,
);
let tight_clip_rect = prim_info
.combined_local_clip_rect
.intersection(&prim_rect).unwrap();
image_instance.tight_local_clip_rect = tight_clip_rect;
let visible_rect = compute_conservative_visible_rect(
&tight_clip_rect,
&pic_state.map_local_to_pic,
);
let base_edge_flags = edge_flags_for_tile_spacing(&image_data.tile_spacing);
let stride = image_data.stretch_size + image_data.tile_spacing;
let repetitions = ::image::repetitions(
&prim_rect,
&visible_rect,
stride,
);
let request = ImageRequest {
key: image_data.key,
rendering: image_data.image_rendering,
tile: None,
};
for Repetition { origin, edge_flags } in repetitions {
let edge_flags = base_edge_flags | edge_flags;
let layout_image_rect = LayoutRect {
origin,
size: image_data.stretch_size,
};
let tiles = ::image::tiles(
&layout_image_rect,
&visible_rect,
&device_image_rect,
tile_size as i32,
);
for tile in tiles {
frame_state.resource_cache.request_image(
request.with_tile(tile.offset),
frame_state.gpu_cache,
);
image_instance.visible_tiles.push(VisibleImageTile {
tile_offset: tile.offset,
edge_flags: tile.edge_flags & edge_flags,
local_rect: tile.rect,
local_clip_rect: tight_clip_rect,
});
}
}
if image_instance.visible_tiles.is_empty() {
// Mark as invisible
prim_instance.visibility_info = PrimitiveVisibilityIndex::INVALID;
}
}
write_segment(
image_instance.segment_instance_index,
frame_state,
@ -3482,6 +3512,7 @@ impl PrimitiveInstance {
device_pixel_scale,
&dirty_world_rect,
&mut data_stores.clip,
false,
);
let clip_mask_kind = segment.update_clip_task(