зеркало из https://github.com/mozilla/gecko-dev.git
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:
Родитель
7a98bf47e2
Коммит
51efa36789
|
@ -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(
|
||||
|
|
Загрузка…
Ссылка в новой задаче