зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1692250 - Simplify blit render tasks. r=gw
Blit render tasks have special code to read from the texture cache. This isn't necessary anymore now that texture cache items can be used as nodes of the frame graph. Blits can be simplified into reading from any render task without knowing how it was produced. Differential Revision: https://phabricator.services.mozilla.com/D105746
This commit is contained in:
Родитель
5573fc71ec
Коммит
98e0a77b54
|
@ -800,7 +800,6 @@ pub fn build_render_pass(
|
|||
render_tasks,
|
||||
clip_store,
|
||||
transforms,
|
||||
deferred_resolves,
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -822,7 +821,6 @@ pub fn build_render_pass(
|
|||
render_tasks,
|
||||
clip_store,
|
||||
transforms,
|
||||
deferred_resolves,
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
@ -21,7 +21,7 @@ use crate::prim_store::{
|
|||
SizeKey, InternablePrimitive,
|
||||
};
|
||||
use crate::render_target::RenderTargetKind;
|
||||
use crate::render_task::{BlitSource, RenderTask};
|
||||
use crate::render_task::RenderTask;
|
||||
use crate::render_task_cache::{
|
||||
RenderTaskCacheKey, RenderTaskCacheKeyKind, RenderTaskParent
|
||||
};
|
||||
|
@ -177,16 +177,16 @@ impl ImageData {
|
|||
frame_state.gpu_cache,
|
||||
);
|
||||
|
||||
let task_id = frame_state.rg_builder.add().init(
|
||||
RenderTask::new_image(size, request)
|
||||
);
|
||||
|
||||
// Every frame, for cached items, we need to request the render
|
||||
// task cache item. The closure will be invoked on the first
|
||||
// time through, and any time the render task output has been
|
||||
// evicted from the texture cache.
|
||||
if self.tile_spacing == LayoutSize::zero() {
|
||||
// Most common case.
|
||||
let task_id = frame_state.rg_builder.add().init(
|
||||
RenderTask::new_image(size, request)
|
||||
);
|
||||
|
||||
image_instance.src_color = ImageSourceHandle::RenderTask(task_id);
|
||||
} else {
|
||||
let padding = DeviceIntSideOffsets::new(
|
||||
|
@ -227,11 +227,10 @@ impl ImageData {
|
|||
frame_state.surfaces,
|
||||
|rg_builder| {
|
||||
// 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.
|
||||
// a normal transient render task surface.
|
||||
// TODO: figure out if/when we can do a blit instead.
|
||||
let cache_to_target_task_id = RenderTask::new_scaling_with_padding(
|
||||
BlitSource::Image { key: image_cache_key },
|
||||
task_id,
|
||||
rg_builder,
|
||||
target_kind,
|
||||
size,
|
||||
|
@ -243,9 +242,7 @@ impl ImageData {
|
|||
// render target cache.
|
||||
RenderTask::new_blit(
|
||||
size,
|
||||
BlitSource::RenderTask {
|
||||
task_id: cache_to_target_task_id,
|
||||
},
|
||||
cache_to_target_task_id,
|
||||
rg_builder,
|
||||
)
|
||||
}
|
||||
|
|
|
@ -14,17 +14,16 @@ use crate::frame_builder::{FrameGlobalResources};
|
|||
use crate::gpu_cache::{GpuCache, GpuCacheAddress};
|
||||
use crate::gpu_types::{BorderInstance, SvgFilterInstance, BlurDirection, BlurInstance, PrimitiveHeaders, ScalingInstance};
|
||||
use crate::gpu_types::{TransformPalette, ZBufferIdGenerator};
|
||||
use crate::internal_types::{FastHashMap, TextureSource, LayerIndex, Swizzle, CacheTextureId};
|
||||
use crate::internal_types::{FastHashMap, TextureSource, CacheTextureId};
|
||||
use crate::picture::{SliceId, SurfaceInfo, ResolvedSurfaceTexture, TileCacheInstance};
|
||||
use crate::prim_store::{PrimitiveStore, DeferredResolve, PrimitiveScratchBuffer};
|
||||
use crate::prim_store::gradient::GRADIENT_FP_STOPS;
|
||||
use crate::render_backend::DataStores;
|
||||
use crate::render_task::{RenderTaskKind, RenderTaskAddress, BlitSource};
|
||||
use crate::render_task::{RenderTaskKind, RenderTaskAddress};
|
||||
use crate::render_task::{RenderTask, ScalingTask, SvgFilterInfo};
|
||||
use crate::render_task_graph::{RenderTaskGraph, RenderTaskId};
|
||||
use crate::resource_cache::ResourceCache;
|
||||
use crate::visibility::PrimitiveVisibilityMask;
|
||||
use crate::image_source::resolve_image;
|
||||
|
||||
const STYLE_SOLID: i32 = ((BorderStyle::Solid as i32) << 8) | ((BorderStyle::Solid as i32) << 16);
|
||||
const STYLE_MASK: i32 = 0x00FF_FF00;
|
||||
|
@ -115,7 +114,6 @@ pub trait RenderTarget {
|
|||
render_tasks: &RenderTaskGraph,
|
||||
clip_store: &ClipStore,
|
||||
transforms: &mut TransformPalette,
|
||||
deferred_resolves: &mut Vec<DeferredResolve>,
|
||||
);
|
||||
|
||||
fn needs_depth(&self) -> bool;
|
||||
|
@ -358,12 +356,11 @@ impl RenderTarget for ColorRenderTarget {
|
|||
fn add_task(
|
||||
&mut self,
|
||||
task_id: RenderTaskId,
|
||||
ctx: &RenderTargetContext,
|
||||
_ctx: &RenderTargetContext,
|
||||
gpu_cache: &mut GpuCache,
|
||||
render_tasks: &RenderTaskGraph,
|
||||
_: &ClipStore,
|
||||
_: &mut TransformPalette,
|
||||
deferred_resolves: &mut Vec<DeferredResolve>,
|
||||
) {
|
||||
profile_scope!("add_task");
|
||||
let task = &render_tasks[task_id];
|
||||
|
@ -416,52 +413,14 @@ impl RenderTarget for ColorRenderTarget {
|
|||
&mut self.scalings,
|
||||
task,
|
||||
task.children.first().map(|&child| &render_tasks[child]),
|
||||
ctx.resource_cache,
|
||||
gpu_cache,
|
||||
deferred_resolves,
|
||||
);
|
||||
}
|
||||
RenderTaskKind::Blit(ref task_info) => {
|
||||
let source = match task_info.source {
|
||||
BlitSource::Image { key } => {
|
||||
// Get the cache item for the source texture.
|
||||
let cache_item = resolve_image(
|
||||
key.request,
|
||||
ctx.resource_cache,
|
||||
gpu_cache,
|
||||
deferred_resolves,
|
||||
);
|
||||
|
||||
// Work out a source rect to copy from the texture, depending on whether
|
||||
// a sub-rect is present or not.
|
||||
let source_rect = key.texel_rect.map_or(cache_item.uv_rect.to_i32(), |sub_rect| {
|
||||
DeviceIntRect::new(
|
||||
DeviceIntPoint::new(
|
||||
cache_item.uv_rect.origin.x as i32 + sub_rect.origin.x,
|
||||
cache_item.uv_rect.origin.y as i32 + sub_rect.origin.y,
|
||||
),
|
||||
sub_rect.size,
|
||||
)
|
||||
});
|
||||
|
||||
// Store the blit job for the renderer to execute, including
|
||||
// the allocated destination rect within this target.
|
||||
BlitJobSource::Texture(
|
||||
cache_item.texture_id,
|
||||
cache_item.texture_layer,
|
||||
source_rect,
|
||||
)
|
||||
}
|
||||
BlitSource::RenderTask { task_id } => {
|
||||
BlitJobSource::RenderTask(task_id)
|
||||
}
|
||||
};
|
||||
|
||||
let target_rect = task
|
||||
.get_target_rect()
|
||||
.0;
|
||||
self.blits.push(BlitJob {
|
||||
source,
|
||||
source: task_info.source,
|
||||
target_rect,
|
||||
});
|
||||
}
|
||||
|
@ -524,7 +483,6 @@ impl RenderTarget for AlphaRenderTarget {
|
|||
render_tasks: &RenderTaskGraph,
|
||||
clip_store: &ClipStore,
|
||||
transforms: &mut TransformPalette,
|
||||
deferred_resolves: &mut Vec<DeferredResolve>,
|
||||
) {
|
||||
profile_scope!("add_task");
|
||||
let task = &render_tasks[task_id];
|
||||
|
@ -604,9 +562,6 @@ impl RenderTarget for AlphaRenderTarget {
|
|||
&mut self.scalings,
|
||||
task,
|
||||
task.children.first().map(|&child| &render_tasks[child]),
|
||||
ctx.resource_cache,
|
||||
gpu_cache,
|
||||
deferred_resolves,
|
||||
);
|
||||
}
|
||||
#[cfg(test)]
|
||||
|
@ -692,22 +647,13 @@ impl TextureCacheRenderTarget {
|
|||
);
|
||||
}
|
||||
RenderTaskKind::Blit(ref task_info) => {
|
||||
match task_info.source {
|
||||
BlitSource::Image { .. } => {
|
||||
// reading/writing from the texture cache at the same time
|
||||
// is undefined behavior.
|
||||
panic!("bug: a single blit cannot be to/from texture cache");
|
||||
}
|
||||
BlitSource::RenderTask { task_id } => {
|
||||
// Add a blit job to copy from an existing render
|
||||
// task to this target.
|
||||
self.blits.push(BlitJob {
|
||||
source: BlitJobSource::RenderTask(task_id),
|
||||
source: task_info.source,
|
||||
target_rect: target_rect.0,
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
RenderTaskKind::Border(ref task_info) => {
|
||||
self.clears.push(target_rect.0);
|
||||
|
||||
|
@ -792,9 +738,6 @@ fn add_scaling_instances(
|
|||
instances: &mut FastHashMap<TextureSource, Vec<ScalingInstance>>,
|
||||
target_task: &RenderTask,
|
||||
source_task: Option<&RenderTask>,
|
||||
resource_cache: &ResourceCache,
|
||||
gpu_cache: &mut GpuCache,
|
||||
deferred_resolves: &mut Vec<DeferredResolve>,
|
||||
) {
|
||||
let target_rect = target_task
|
||||
.get_target_rect()
|
||||
|
@ -802,45 +745,9 @@ fn add_scaling_instances(
|
|||
.inner_rect(task.padding)
|
||||
.to_f32();
|
||||
|
||||
let (source, (source_rect, source_layer)) = match task.image {
|
||||
Some(key) => {
|
||||
assert!(source_task.is_none());
|
||||
let source = source_task.unwrap().get_texture_source();
|
||||
|
||||
// Get the cache item for the source texture.
|
||||
let cache_item = resolve_image(
|
||||
key.request,
|
||||
resource_cache,
|
||||
gpu_cache,
|
||||
deferred_resolves,
|
||||
);
|
||||
|
||||
// Work out a source rect to copy from the texture, depending on whether
|
||||
// a sub-rect is present or not.
|
||||
let source_rect = key.texel_rect.map_or(cache_item.uv_rect, |sub_rect| {
|
||||
DeviceIntRect::new(
|
||||
DeviceIntPoint::new(
|
||||
cache_item.uv_rect.origin.x + sub_rect.origin.x,
|
||||
cache_item.uv_rect.origin.y + sub_rect.origin.y,
|
||||
),
|
||||
sub_rect.size,
|
||||
)
|
||||
});
|
||||
|
||||
(
|
||||
cache_item.texture_id,
|
||||
(source_rect, cache_item.texture_layer as LayerIndex),
|
||||
)
|
||||
}
|
||||
None => {
|
||||
(
|
||||
TextureSource::TextureCache(
|
||||
source_task.unwrap().get_target_texture(),
|
||||
Swizzle::default(),
|
||||
),
|
||||
source_task.unwrap().location.to_source_rect(),
|
||||
)
|
||||
}
|
||||
};
|
||||
let (source_rect, source_layer) = source_task.unwrap().location.to_source_rect();
|
||||
|
||||
instances
|
||||
.entry(source)
|
||||
|
@ -943,19 +850,11 @@ fn add_svg_filter_instances(
|
|||
instances.push((textures, vec![instance]));
|
||||
}
|
||||
|
||||
// Defines where the source data for a blit job can be found.
|
||||
#[cfg_attr(feature = "capture", derive(Serialize))]
|
||||
#[cfg_attr(feature = "replay", derive(Deserialize))]
|
||||
pub enum BlitJobSource {
|
||||
Texture(TextureSource, i32, DeviceIntRect),
|
||||
RenderTask(RenderTaskId),
|
||||
}
|
||||
|
||||
// Information required to do a blit from a source to a target.
|
||||
#[cfg_attr(feature = "capture", derive(Serialize))]
|
||||
#[cfg_attr(feature = "replay", derive(Deserialize))]
|
||||
pub struct BlitJob {
|
||||
pub source: BlitJobSource,
|
||||
pub source: RenderTaskId,
|
||||
pub target_rect: DeviceIntRect,
|
||||
}
|
||||
|
||||
|
|
|
@ -15,7 +15,6 @@ use crate::gpu_types::{BorderInstance, ImageSource, UvRectKind};
|
|||
use crate::internal_types::{CacheTextureId, FastHashMap, LayerIndex, TextureSource, Swizzle};
|
||||
use crate::picture::{ResolvedSurfaceTexture, SurfaceInfo};
|
||||
use crate::prim_store::{ClipData, PictureIndex};
|
||||
use crate::prim_store::image::ImageCacheKey;
|
||||
use crate::prim_store::gradient::{GRADIENT_FP_STOPS, GradientStopKey};
|
||||
#[cfg(feature = "debugger")]
|
||||
use crate::print_tree::{PrintTreePrinter};
|
||||
|
@ -229,23 +228,9 @@ impl BlurTask {
|
|||
#[cfg_attr(feature = "replay", derive(Deserialize))]
|
||||
pub struct ScalingTask {
|
||||
pub target_kind: RenderTargetKind,
|
||||
pub image: Option<ImageCacheKey>,
|
||||
pub padding: DeviceIntSideOffsets,
|
||||
}
|
||||
|
||||
// Where the source data for a blit task can be found.
|
||||
#[derive(Debug)]
|
||||
#[cfg_attr(feature = "capture", derive(Serialize))]
|
||||
#[cfg_attr(feature = "replay", derive(Deserialize))]
|
||||
pub enum BlitSource {
|
||||
Image {
|
||||
key: ImageCacheKey,
|
||||
},
|
||||
RenderTask {
|
||||
task_id: RenderTaskId,
|
||||
},
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
#[cfg_attr(feature = "capture", derive(Serialize))]
|
||||
#[cfg_attr(feature = "replay", derive(Deserialize))]
|
||||
|
@ -257,7 +242,7 @@ pub struct BorderTask {
|
|||
#[cfg_attr(feature = "capture", derive(Serialize))]
|
||||
#[cfg_attr(feature = "replay", derive(Deserialize))]
|
||||
pub struct BlitTask {
|
||||
pub source: BlitSource,
|
||||
pub source: RenderTaskId,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
|
@ -867,7 +852,7 @@ impl RenderTask {
|
|||
|
||||
pub fn new_blit(
|
||||
size: DeviceIntSize,
|
||||
source: BlitSource,
|
||||
source: RenderTaskId,
|
||||
rg_builder: &mut RenderTaskGraphBuilder,
|
||||
) -> RenderTaskId {
|
||||
// If this blit uses a render task as a source,
|
||||
|
@ -875,21 +860,13 @@ impl RenderTask {
|
|||
// ensure it gets allocated in the correct pass
|
||||
// and made available as an input when this task
|
||||
// executes.
|
||||
let child_id = match source {
|
||||
BlitSource::RenderTask { task_id } => Some(task_id),
|
||||
BlitSource::Image { .. } => None,
|
||||
};
|
||||
|
||||
let blit_task_id = rg_builder.add().init(RenderTask::new_dynamic(
|
||||
size,
|
||||
RenderTaskKind::Blit(BlitTask {
|
||||
source,
|
||||
}),
|
||||
RenderTaskKind::Blit(BlitTask { source }),
|
||||
));
|
||||
|
||||
if let Some(child_id) = child_id {
|
||||
rg_builder.add_dependency(blit_task_id, child_id);
|
||||
}
|
||||
rg_builder.add_dependency(blit_task_id, source);
|
||||
|
||||
blit_task_id
|
||||
}
|
||||
|
@ -1009,7 +986,7 @@ impl RenderTask {
|
|||
size: DeviceIntSize,
|
||||
) -> RenderTaskId {
|
||||
Self::new_scaling_with_padding(
|
||||
BlitSource::RenderTask { task_id: src_task_id },
|
||||
src_task_id,
|
||||
rg_builder,
|
||||
target_kind,
|
||||
size,
|
||||
|
@ -1018,31 +995,25 @@ impl RenderTask {
|
|||
}
|
||||
|
||||
pub fn new_scaling_with_padding(
|
||||
source: BlitSource,
|
||||
source: RenderTaskId,
|
||||
rg_builder: &mut RenderTaskGraphBuilder,
|
||||
target_kind: RenderTargetKind,
|
||||
padded_size: DeviceIntSize,
|
||||
padding: DeviceIntSideOffsets,
|
||||
) -> RenderTaskId {
|
||||
let (uv_rect_kind, child, image) = match source {
|
||||
BlitSource::RenderTask { task_id } => (rg_builder.get_task(task_id).uv_rect_kind(), Some(task_id), None),
|
||||
BlitSource::Image { key } => (UvRectKind::Rect, None, Some(key)),
|
||||
};
|
||||
let uv_rect_kind = rg_builder.get_task(source).uv_rect_kind();
|
||||
|
||||
let task_id = rg_builder.add().init(
|
||||
RenderTask::new_dynamic(
|
||||
padded_size,
|
||||
RenderTaskKind::Scaling(ScalingTask {
|
||||
target_kind,
|
||||
image,
|
||||
padding,
|
||||
}),
|
||||
).with_uv_rect_kind(uv_rect_kind)
|
||||
);
|
||||
|
||||
if let Some(child_id) = child {
|
||||
rg_builder.add_dependency(task_id, child_id);
|
||||
}
|
||||
rg_builder.add_dependency(task_id, source);
|
||||
|
||||
task_id
|
||||
}
|
||||
|
|
|
@ -90,7 +90,7 @@ use crate::scene_builder_thread::{SceneBuilderThread, SceneBuilderThreadChannels
|
|||
use crate::screen_capture::AsyncScreenshotGrabber;
|
||||
use crate::render_target::{AlphaRenderTarget, ColorRenderTarget, PictureCacheTarget};
|
||||
use crate::render_target::{RenderTarget, TextureCacheRenderTarget};
|
||||
use crate::render_target::{RenderTargetKind, BlitJob, BlitJobSource};
|
||||
use crate::render_target::{RenderTargetKind, BlitJob};
|
||||
use crate::texture_cache::{TextureCache, TextureCacheConfig};
|
||||
use crate::tile_cache::PictureCacheDebugInfo;
|
||||
use crate::util::drain_filter;
|
||||
|
@ -2643,23 +2643,15 @@ impl Renderer {
|
|||
// TODO(gw): For now, we don't bother batching these by source texture.
|
||||
// If if ever shows up as an issue, we can easily batch them.
|
||||
for blit in blits {
|
||||
let (source, layer, source_rect) = match blit.source {
|
||||
BlitJobSource::Texture(texture_id, layer, source_rect) => {
|
||||
// A blit from a texture into this target.
|
||||
(texture_id, layer as usize, source_rect)
|
||||
}
|
||||
BlitJobSource::RenderTask(task_id) => {
|
||||
let (source, layer, source_rect) = {
|
||||
// A blit from the child render task into this target.
|
||||
// TODO(gw): Support R8 format here once we start
|
||||
// creating mips for alpha masks.
|
||||
let source = &render_tasks[task_id];
|
||||
let (source_rect, layer) = source.get_target_rect();
|
||||
let source_texture = TextureSource::TextureCache(
|
||||
source.get_target_texture(),
|
||||
Swizzle::default(),
|
||||
);
|
||||
let task = &render_tasks[blit.source];
|
||||
let (source_rect, layer) = task.get_target_rect();
|
||||
let source_texture = task.get_texture_source();
|
||||
|
||||
(source_texture, layer.0, source_rect)
|
||||
}
|
||||
};
|
||||
|
||||
debug_assert_eq!(source_rect.size, blit.target_rect.size);
|
||||
|
|
Загрузка…
Ссылка в новой задаче