mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-02-17 06:09:19 +00:00
Bug 1922323 - Make it possible to conditionally cache render tasks. r=gfx-reviewers,gw
This will be needed by some quad rendering optimizations and the view-transition snapshotting infrastructure. The main change in this patch is that ResourceCache::request_render_task now takes an optional cache key and only creates a cached render task if the cache key is supplied. The patch ballooned into including a few cosmetic changes: - user_data was always None so the parameter was removed - the closure is not generic anymore - arguments were shuffled a bit to put parameters at the beginning and the &mut builders together at the end. Differential Revision: https://phabricator.services.mozilla.com/D224446
This commit is contained in:
parent
3f27ff750f
commit
68b9bb0f07
@ -403,18 +403,17 @@ fn prepare_interned_prim_for_render(
|
||||
// happens, we can use the cache handle immediately, and not need
|
||||
// to temporarily store it in the primitive instance.
|
||||
*render_task = Some(frame_state.resource_cache.request_render_task(
|
||||
RenderTaskCacheKey {
|
||||
Some(RenderTaskCacheKey {
|
||||
size: task_size,
|
||||
kind: RenderTaskCacheKeyKind::LineDecoration(cache_key.clone()),
|
||||
},
|
||||
}),
|
||||
false,
|
||||
RenderTaskParent::Surface,
|
||||
frame_state.gpu_cache,
|
||||
&mut frame_state.frame_gpu_data.f32,
|
||||
frame_state.rg_builder,
|
||||
None,
|
||||
false,
|
||||
RenderTaskParent::Surface,
|
||||
&mut frame_state.surface_builder,
|
||||
|rg_builder, _| {
|
||||
&mut |rg_builder, _| {
|
||||
rg_builder.add().init(RenderTask::new_dynamic(
|
||||
task_size,
|
||||
RenderTaskKind::new_line_decoration(
|
||||
@ -561,15 +560,14 @@ fn prepare_interned_prim_for_render(
|
||||
};
|
||||
|
||||
handles.push(frame_state.resource_cache.request_render_task(
|
||||
cache_key,
|
||||
Some(cache_key),
|
||||
false, // TODO(gw): We don't calculate opacity for borders yet!
|
||||
RenderTaskParent::Surface,
|
||||
frame_state.gpu_cache,
|
||||
&mut frame_state.frame_gpu_data.f32,
|
||||
frame_state.rg_builder,
|
||||
None,
|
||||
false, // TODO(gw): We don't calculate opacity for borders yet!
|
||||
RenderTaskParent::Surface,
|
||||
&mut frame_state.surface_builder,
|
||||
|rg_builder, _| {
|
||||
&mut |rg_builder, _| {
|
||||
rg_builder.add().init(RenderTask::new_dynamic(
|
||||
cache_size,
|
||||
RenderTaskKind::new_border_segment(
|
||||
|
@ -283,18 +283,17 @@ impl ConicGradientTemplate {
|
||||
};
|
||||
|
||||
let task_id = frame_state.resource_cache.request_render_task(
|
||||
RenderTaskCacheKey {
|
||||
Some(RenderTaskCacheKey {
|
||||
size: self.task_size,
|
||||
kind: RenderTaskCacheKeyKind::ConicGradient(cache_key),
|
||||
},
|
||||
}),
|
||||
false,
|
||||
RenderTaskParent::Surface,
|
||||
frame_state.gpu_cache,
|
||||
&mut frame_state.frame_gpu_data.f32,
|
||||
frame_state.rg_builder,
|
||||
None,
|
||||
false,
|
||||
RenderTaskParent::Surface,
|
||||
&mut frame_state.surface_builder,
|
||||
|rg_builder, gpu_buffer_builder| {
|
||||
&mut |rg_builder, gpu_buffer_builder| {
|
||||
let stops = GradientGpuBlockBuilder::build(
|
||||
false,
|
||||
gpu_buffer_builder,
|
||||
@ -472,4 +471,4 @@ pub fn conic_gradient_pattern(
|
||||
base_color: ColorF::WHITE,
|
||||
is_opaque,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -515,18 +515,17 @@ impl LinearGradientTemplate {
|
||||
};
|
||||
|
||||
frame_state.resource_cache.request_render_task(
|
||||
RenderTaskCacheKey {
|
||||
Some(RenderTaskCacheKey {
|
||||
size: self.task_size,
|
||||
kind: RenderTaskCacheKeyKind::FastLinearGradient(gradient),
|
||||
},
|
||||
}),
|
||||
false,
|
||||
RenderTaskParent::Surface,
|
||||
frame_state.gpu_cache,
|
||||
&mut frame_state.frame_gpu_data.f32,
|
||||
frame_state.rg_builder,
|
||||
None,
|
||||
false,
|
||||
RenderTaskParent::Surface,
|
||||
&mut frame_state.surface_builder,
|
||||
|rg_builder, _| {
|
||||
&mut |rg_builder, _| {
|
||||
rg_builder.add().init(RenderTask::new_dynamic(
|
||||
self.task_size,
|
||||
RenderTaskKind::FastLinearGradient(gradient),
|
||||
@ -545,18 +544,17 @@ impl LinearGradientTemplate {
|
||||
};
|
||||
|
||||
frame_state.resource_cache.request_render_task(
|
||||
RenderTaskCacheKey {
|
||||
Some(RenderTaskCacheKey {
|
||||
size: self.task_size,
|
||||
kind: RenderTaskCacheKeyKind::LinearGradient(cache_key),
|
||||
},
|
||||
}),
|
||||
false,
|
||||
RenderTaskParent::Surface,
|
||||
frame_state.gpu_cache,
|
||||
&mut frame_state.frame_gpu_data.f32,
|
||||
frame_state.rg_builder,
|
||||
None,
|
||||
false,
|
||||
RenderTaskParent::Surface,
|
||||
&mut frame_state.surface_builder,
|
||||
|rg_builder, gpu_buffer_builder| {
|
||||
&mut |rg_builder, gpu_buffer_builder| {
|
||||
let stops = Some(GradientGpuBlockBuilder::build(
|
||||
self.reverse_stops,
|
||||
gpu_buffer_builder,
|
||||
|
@ -249,18 +249,17 @@ impl RadialGradientTemplate {
|
||||
};
|
||||
|
||||
let task_id = frame_state.resource_cache.request_render_task(
|
||||
RenderTaskCacheKey {
|
||||
Some(RenderTaskCacheKey {
|
||||
size: task_size,
|
||||
kind: RenderTaskCacheKeyKind::RadialGradient(cache_key),
|
||||
},
|
||||
}),
|
||||
false,
|
||||
RenderTaskParent::Surface,
|
||||
frame_state.gpu_cache,
|
||||
&mut frame_state.frame_gpu_data.f32,
|
||||
frame_state.rg_builder,
|
||||
None,
|
||||
false,
|
||||
RenderTaskParent::Surface,
|
||||
&mut frame_state.surface_builder,
|
||||
|rg_builder, gpu_buffer_builder| {
|
||||
&mut |rg_builder, gpu_buffer_builder| {
|
||||
let stops = GradientGpuBlockBuilder::build(
|
||||
false,
|
||||
gpu_buffer_builder,
|
||||
@ -605,4 +604,4 @@ pub fn radial_gradient_pattern(
|
||||
base_color: ColorF::WHITE,
|
||||
is_opaque,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -250,18 +250,17 @@ impl ImageData {
|
||||
|
||||
// Request a pre-rendered image task.
|
||||
let cached_task_handle = frame_state.resource_cache.request_render_task(
|
||||
RenderTaskCacheKey {
|
||||
Some(RenderTaskCacheKey {
|
||||
size,
|
||||
kind: RenderTaskCacheKeyKind::Image(image_cache_key),
|
||||
},
|
||||
}),
|
||||
descriptor.is_opaque(),
|
||||
RenderTaskParent::Surface,
|
||||
frame_state.gpu_cache,
|
||||
&mut frame_state.frame_gpu_data.f32,
|
||||
frame_state.rg_builder,
|
||||
None,
|
||||
descriptor.is_opaque(),
|
||||
RenderTaskParent::Surface,
|
||||
&mut frame_state.surface_builder,
|
||||
|rg_builder, _| {
|
||||
&mut |rg_builder, _| {
|
||||
// Create a task to blit from the texture cache to
|
||||
// a normal transient render task surface.
|
||||
// TODO: figure out if/when we can do a blit instead.
|
||||
|
@ -667,18 +667,17 @@ impl RenderTaskKind {
|
||||
// Request a cacheable render task with a blurred, minimal
|
||||
// sized box-shadow rect.
|
||||
source.render_task = Some(resource_cache.request_render_task(
|
||||
RenderTaskCacheKey {
|
||||
Some(RenderTaskCacheKey {
|
||||
size: cache_size,
|
||||
kind: RenderTaskCacheKeyKind::BoxShadow(cache_key),
|
||||
},
|
||||
}),
|
||||
false,
|
||||
RenderTaskParent::RenderTask(clip_task_id),
|
||||
gpu_cache,
|
||||
gpu_buffer_builder,
|
||||
rg_builder,
|
||||
None,
|
||||
false,
|
||||
RenderTaskParent::RenderTask(clip_task_id),
|
||||
surface_builder,
|
||||
|rg_builder, _| {
|
||||
&mut |rg_builder, _| {
|
||||
let clip_data = ClipData::rounded_rect(
|
||||
source.minimal_shadow_rect.size(),
|
||||
&source.shadow_radius,
|
||||
|
@ -222,22 +222,71 @@ impl RenderTaskCache {
|
||||
};
|
||||
}
|
||||
|
||||
pub fn request_render_task<F>(
|
||||
pub fn request_render_task(
|
||||
&mut self,
|
||||
key: Option<RenderTaskCacheKey>,
|
||||
texture_cache: &mut TextureCache,
|
||||
is_opaque: bool,
|
||||
parent: RenderTaskParent,
|
||||
gpu_cache: &mut GpuCache,
|
||||
gpu_buffer_builder: &mut GpuBufferBuilderF,
|
||||
rg_builder: &mut RenderTaskGraphBuilder,
|
||||
surface_builder: &mut SurfaceBuilder,
|
||||
f: &mut dyn FnMut(&mut RenderTaskGraphBuilder, &mut GpuBufferBuilderF) -> RenderTaskId,
|
||||
) -> RenderTaskId {
|
||||
// If this render task cache is being drawn this frame, ensure we hook up the
|
||||
// render task for it as a dependency of any render task that uses this as
|
||||
// an input source.
|
||||
let (task_id, rendered_this_frame) = match key {
|
||||
None => (f(rg_builder, gpu_buffer_builder), true),
|
||||
Some(key) => self.request_render_task_impl(
|
||||
key,
|
||||
is_opaque,
|
||||
texture_cache,
|
||||
gpu_cache,
|
||||
gpu_buffer_builder,
|
||||
rg_builder,
|
||||
f
|
||||
)
|
||||
};
|
||||
|
||||
if rendered_this_frame {
|
||||
match parent {
|
||||
RenderTaskParent::Surface => {
|
||||
// If parent is a surface, use helper fn to add this dependency,
|
||||
// which correctly takes account of the render task configuration
|
||||
// of the surface.
|
||||
surface_builder.add_child_render_task(
|
||||
task_id,
|
||||
rg_builder,
|
||||
);
|
||||
}
|
||||
RenderTaskParent::RenderTask(parent_render_task_id) => {
|
||||
// For render tasks, just add it as a direct dependency on the
|
||||
// task graph builder.
|
||||
rg_builder.add_dependency(
|
||||
parent_render_task_id,
|
||||
task_id,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
task_id
|
||||
}
|
||||
|
||||
/// Returns the render task id and a boolean indicating whether the
|
||||
/// task was rendered this frame (was not already in cache).
|
||||
fn request_render_task_impl(
|
||||
&mut self,
|
||||
key: RenderTaskCacheKey,
|
||||
is_opaque: bool,
|
||||
texture_cache: &mut TextureCache,
|
||||
gpu_cache: &mut GpuCache,
|
||||
gpu_buffer_builder: &mut GpuBufferBuilderF,
|
||||
rg_builder: &mut RenderTaskGraphBuilder,
|
||||
user_data: Option<[f32; 4]>,
|
||||
is_opaque: bool,
|
||||
parent: RenderTaskParent,
|
||||
surface_builder: &mut SurfaceBuilder,
|
||||
f: F,
|
||||
) -> Result<RenderTaskId, ()>
|
||||
where
|
||||
F: FnOnce(&mut RenderTaskGraphBuilder, &mut GpuBufferBuilderF) -> Result<RenderTaskId, ()>,
|
||||
{
|
||||
f: &mut dyn FnMut(&mut RenderTaskGraphBuilder, &mut GpuBufferBuilderF) -> RenderTaskId,
|
||||
) -> (RenderTaskId, bool) {
|
||||
let frame_id = self.frame_id;
|
||||
let size = key.size;
|
||||
// Get the texture cache handle for this cache key,
|
||||
@ -246,7 +295,7 @@ impl RenderTaskCache {
|
||||
let entry_handle = self.map.entry(key).or_insert_with(|| {
|
||||
let entry = RenderTaskCacheEntry {
|
||||
handle: TextureCacheHandle::invalid(),
|
||||
user_data,
|
||||
user_data: None,
|
||||
target_kind: RenderTargetKind::Color, // will be set below.
|
||||
is_opaque,
|
||||
frame_id,
|
||||
@ -261,9 +310,9 @@ impl RenderTaskCache {
|
||||
if texture_cache.request(&cache_entry.handle, gpu_cache) {
|
||||
// Invoke user closure to get render task chain
|
||||
// to draw this into the texture cache.
|
||||
let render_task_id = f(rg_builder, gpu_buffer_builder)?;
|
||||
let render_task_id = f(rg_builder, gpu_buffer_builder);
|
||||
|
||||
cache_entry.user_data = user_data;
|
||||
cache_entry.user_data = None;
|
||||
cache_entry.is_opaque = is_opaque;
|
||||
cache_entry.render_task_id = Some(render_task_id);
|
||||
|
||||
@ -282,31 +331,8 @@ impl RenderTaskCache {
|
||||
);
|
||||
}
|
||||
|
||||
// If this render task cache is being drawn this frame, ensure we hook up the
|
||||
// render task for it as a dependency of any render task that uses this as
|
||||
// an input source.
|
||||
if let Some(render_task_id) = cache_entry.render_task_id {
|
||||
match parent {
|
||||
RenderTaskParent::Surface => {
|
||||
// If parent is a surface, use helper fn to add this dependency,
|
||||
// which correctly takes account of the render task configuration
|
||||
// of the surface.
|
||||
surface_builder.add_child_render_task(
|
||||
render_task_id,
|
||||
rg_builder,
|
||||
);
|
||||
}
|
||||
RenderTaskParent::RenderTask(parent_render_task_id) => {
|
||||
// For render tasks, just add it as a direct dependency on the
|
||||
// task graph builder.
|
||||
rg_builder.add_dependency(
|
||||
parent_render_task_id,
|
||||
render_task_id,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return Ok(render_task_id);
|
||||
return (render_task_id, true);
|
||||
}
|
||||
|
||||
let target_kind = cache_entry.target_kind;
|
||||
@ -319,7 +345,7 @@ impl RenderTaskCache {
|
||||
task.mark_cached(entry_handle.weak());
|
||||
let render_task_id = rg_builder.add().init(task);
|
||||
|
||||
Ok(render_task_id)
|
||||
(render_task_id, false)
|
||||
}
|
||||
|
||||
pub fn get_cache_entry(
|
||||
|
@ -576,38 +576,39 @@ impl ResourceCache {
|
||||
}
|
||||
}
|
||||
|
||||
// Request the texture cache item for a cacheable render
|
||||
// task. If the item is already cached, the texture cache
|
||||
// handle will be returned. Otherwise, the user supplied
|
||||
// closure will be invoked to generate the render task
|
||||
// chain that is required to draw this task.
|
||||
pub fn request_render_task<F>(
|
||||
/// Request an optionally cacheable render task.
|
||||
///
|
||||
/// If the render task cache key is None, the render task is
|
||||
/// not cached.
|
||||
/// Otherwise, if the item is already cached, the texture cache
|
||||
/// handle will be returned. Otherwise, the user supplied
|
||||
/// closure will be invoked to generate the render task
|
||||
/// chain that is required to draw this task.
|
||||
///
|
||||
/// This function takes care of adding the render task as a
|
||||
/// dependency to its parent task or surface.
|
||||
pub fn request_render_task(
|
||||
&mut self,
|
||||
key: RenderTaskCacheKey,
|
||||
key: Option<RenderTaskCacheKey>,
|
||||
is_opaque: bool,
|
||||
parent: RenderTaskParent,
|
||||
gpu_cache: &mut GpuCache,
|
||||
gpu_buffer_builder: &mut GpuBufferBuilderF,
|
||||
rg_builder: &mut RenderTaskGraphBuilder,
|
||||
user_data: Option<[f32; 4]>,
|
||||
is_opaque: bool,
|
||||
parent: RenderTaskParent,
|
||||
surface_builder: &mut SurfaceBuilder,
|
||||
f: F,
|
||||
) -> RenderTaskId
|
||||
where
|
||||
F: FnOnce(&mut RenderTaskGraphBuilder, &mut GpuBufferBuilderF) -> RenderTaskId,
|
||||
{
|
||||
f: &mut dyn FnMut(&mut RenderTaskGraphBuilder, &mut GpuBufferBuilderF) -> RenderTaskId,
|
||||
) -> RenderTaskId {
|
||||
self.cached_render_tasks.request_render_task(
|
||||
key,
|
||||
&mut self.texture_cache,
|
||||
is_opaque,
|
||||
parent,
|
||||
gpu_cache,
|
||||
gpu_buffer_builder,
|
||||
rg_builder,
|
||||
user_data,
|
||||
is_opaque,
|
||||
parent,
|
||||
surface_builder,
|
||||
|render_graph, gpu_buffer_builder| Ok(f(render_graph, gpu_buffer_builder))
|
||||
).expect("Failed to request a render task from the resource cache!")
|
||||
f
|
||||
)
|
||||
}
|
||||
|
||||
pub fn post_scene_building_update(
|
||||
|
Loading…
x
Reference in New Issue
Block a user