зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1921980 - Retain snapshotted pictures in the resource cache. r=gw
Differential Revision: https://phabricator.services.mozilla.com/D225227
This commit is contained in:
Родитель
b58d15506b
Коммит
c0c13f6ff1
|
@ -94,12 +94,12 @@
|
|||
//! blend the overlay tile (this is not always optimal right now, but will be
|
||||
//! improved as a follow up).
|
||||
|
||||
use api::{MixBlendMode, PremultipliedColorF, FilterPrimitiveKind, SVGFE_GRAPH_MAX};
|
||||
use api::{FilterPrimitiveKind, MixBlendMode, PremultipliedColorF, SVGFE_GRAPH_MAX};
|
||||
use api::{PropertyBinding, PropertyBindingId, FilterPrimitive, FilterOpGraphPictureBufferId, RasterSpace};
|
||||
use api::{DebugFlags, ImageKey, ColorF, ColorU, PrimitiveFlags};
|
||||
use api::{DebugFlags, ImageKey, ColorF, ColorU, PrimitiveFlags, SnapshotInfo};
|
||||
use api::{ImageRendering, ColorDepth, YuvRangedColorSpace, YuvFormat, AlphaType};
|
||||
use api::units::*;
|
||||
use crate::command_buffer::PrimitiveCommand;
|
||||
use crate::{command_buffer::PrimitiveCommand, render_task_graph::RenderTaskGraphBuilder, renderer::GpuBufferBuilderF};
|
||||
use crate::box_shadow::BLUR_SAMPLE_SCALE;
|
||||
use crate::clip::{ClipStore, ClipChainInstance, ClipLeafId, ClipNodeId, ClipTreeBuilder};
|
||||
use crate::profiler::{self, TransactionProfile};
|
||||
|
@ -3533,7 +3533,7 @@ impl TileCacheInstance {
|
|||
PrimitiveInstanceKind::TextRun { .. } => {
|
||||
// These don't contribute dependencies
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
self.maybe_report_promotion_failure(promotion_result, pic_coverage_rect, &mut promotion_failure_reported);
|
||||
|
||||
|
@ -4209,6 +4209,8 @@ bitflags! {
|
|||
const PRESERVE3D = 4;
|
||||
/// A backdrop that is reused which requires a surface.
|
||||
const BACKDROP = 8;
|
||||
/// We may need to render the picture into an image and cache it.
|
||||
const SNAPSHOT = 16;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -5061,6 +5063,10 @@ pub struct PicturePrimitive {
|
|||
/// picture, to be ignored when clipping those primitives and applied
|
||||
/// later when compositing the picture.
|
||||
pub clip_root: Option<ClipNodeId>,
|
||||
|
||||
/// If provided, cache the content of this picture into an image
|
||||
/// associated with the image key.
|
||||
pub snapshot: Option<SnapshotInfo>,
|
||||
}
|
||||
|
||||
impl PicturePrimitive {
|
||||
|
@ -5132,6 +5138,7 @@ impl PicturePrimitive {
|
|||
spatial_node_index: SpatialNodeIndex,
|
||||
raster_space: RasterSpace,
|
||||
flags: PictureFlags,
|
||||
snapshot: Option<SnapshotInfo>,
|
||||
) -> Self {
|
||||
PicturePrimitive {
|
||||
prim_list,
|
||||
|
@ -5149,6 +5156,7 @@ impl PicturePrimitive {
|
|||
raster_space,
|
||||
flags,
|
||||
clip_root: None,
|
||||
snapshot,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -5911,15 +5919,23 @@ impl PicturePrimitive {
|
|||
).with_uv_rect_kind(uv_rect_kind)
|
||||
);
|
||||
|
||||
let blur_render_task_id = RenderTask::new_blur(
|
||||
blur_std_deviation,
|
||||
picture_task_id,
|
||||
frame_state.rg_builder,
|
||||
RenderTargetKind::Color,
|
||||
None,
|
||||
original_size.to_i32(),
|
||||
);
|
||||
|
||||
let blur_render_task_id = request_render_task(
|
||||
frame_state,
|
||||
&self.snapshot,
|
||||
&surface_rects,
|
||||
false,
|
||||
&mut|rg_builder, _, _| {
|
||||
RenderTask::new_blur(
|
||||
blur_std_deviation,
|
||||
picture_task_id,
|
||||
rg_builder,
|
||||
RenderTargetKind::Color,
|
||||
None,
|
||||
original_size.to_i32(),
|
||||
)
|
||||
}
|
||||
);
|
||||
primary_render_task_id = blur_render_task_id;
|
||||
|
||||
surface_descriptor = SurfaceDescriptor::new_chained(
|
||||
|
@ -5978,6 +5994,8 @@ impl PicturePrimitive {
|
|||
);
|
||||
}
|
||||
|
||||
// TODO: Ensure that snapshots bake their shadow.
|
||||
|
||||
// Add this content picture as a dependency of the parent surface, to
|
||||
// ensure it isn't free'd after the shadow uses it as an input.
|
||||
frame_state.surface_builder.add_picture_render_task(picture_task_id);
|
||||
|
@ -6075,23 +6093,32 @@ impl PicturePrimitive {
|
|||
|
||||
let cmd_buffer_index = frame_state.cmd_buffers.create_cmd_buffer();
|
||||
|
||||
let render_task_id = frame_state.rg_builder.add().init(
|
||||
RenderTask::new_dynamic(
|
||||
task_size,
|
||||
RenderTaskKind::new_picture(
|
||||
task_size,
|
||||
surface_rects.needs_scissor_rect,
|
||||
surface_rects.clipped.min,
|
||||
surface_spatial_node_index,
|
||||
raster_spatial_node_index,
|
||||
device_pixel_scale,
|
||||
None,
|
||||
None,
|
||||
None,
|
||||
cmd_buffer_index,
|
||||
can_use_shared_surface,
|
||||
let is_opaque = false; // TODO
|
||||
let render_task_id = request_render_task(
|
||||
frame_state,
|
||||
&self.snapshot,
|
||||
&surface_rects,
|
||||
is_opaque,
|
||||
&mut|rg_builder, _, _| {
|
||||
rg_builder.add().init(
|
||||
RenderTask::new_dynamic(
|
||||
task_size,
|
||||
RenderTaskKind::new_picture(
|
||||
task_size,
|
||||
surface_rects.needs_scissor_rect,
|
||||
surface_rects.clipped.min,
|
||||
surface_spatial_node_index,
|
||||
raster_spatial_node_index,
|
||||
device_pixel_scale,
|
||||
None,
|
||||
None,
|
||||
None,
|
||||
cmd_buffer_index,
|
||||
can_use_shared_surface,
|
||||
)
|
||||
).with_uv_rect_kind(surface_rects.uv_rect_kind)
|
||||
)
|
||||
).with_uv_rect_kind(surface_rects.uv_rect_kind)
|
||||
}
|
||||
);
|
||||
|
||||
primary_render_task_id = render_task_id;
|
||||
|
@ -6104,23 +6131,32 @@ impl PicturePrimitive {
|
|||
PictureCompositeMode::Filter(..) => {
|
||||
let cmd_buffer_index = frame_state.cmd_buffers.create_cmd_buffer();
|
||||
|
||||
let render_task_id = frame_state.rg_builder.add().init(
|
||||
RenderTask::new_dynamic(
|
||||
surface_rects.task_size,
|
||||
RenderTaskKind::new_picture(
|
||||
surface_rects.task_size,
|
||||
surface_rects.needs_scissor_rect,
|
||||
surface_rects.clipped.min,
|
||||
surface_spatial_node_index,
|
||||
raster_spatial_node_index,
|
||||
device_pixel_scale,
|
||||
None,
|
||||
None,
|
||||
None,
|
||||
cmd_buffer_index,
|
||||
can_use_shared_surface,
|
||||
let is_opaque = false; // TODO
|
||||
let render_task_id = request_render_task(
|
||||
frame_state,
|
||||
&self.snapshot,
|
||||
&surface_rects,
|
||||
is_opaque,
|
||||
&mut|rg_builder, _, _| {
|
||||
rg_builder.add().init(
|
||||
RenderTask::new_dynamic(
|
||||
surface_rects.task_size,
|
||||
RenderTaskKind::new_picture(
|
||||
surface_rects.task_size,
|
||||
surface_rects.needs_scissor_rect,
|
||||
surface_rects.clipped.min,
|
||||
surface_spatial_node_index,
|
||||
raster_spatial_node_index,
|
||||
device_pixel_scale,
|
||||
None,
|
||||
None,
|
||||
None,
|
||||
cmd_buffer_index,
|
||||
can_use_shared_surface,
|
||||
)
|
||||
).with_uv_rect_kind(surface_rects.uv_rect_kind)
|
||||
)
|
||||
).with_uv_rect_kind(surface_rects.uv_rect_kind)
|
||||
},
|
||||
);
|
||||
|
||||
primary_render_task_id = render_task_id;
|
||||
|
@ -6133,23 +6169,32 @@ impl PicturePrimitive {
|
|||
PictureCompositeMode::ComponentTransferFilter(..) => {
|
||||
let cmd_buffer_index = frame_state.cmd_buffers.create_cmd_buffer();
|
||||
|
||||
let render_task_id = frame_state.rg_builder.add().init(
|
||||
RenderTask::new_dynamic(
|
||||
surface_rects.task_size,
|
||||
RenderTaskKind::new_picture(
|
||||
surface_rects.task_size,
|
||||
surface_rects.needs_scissor_rect,
|
||||
surface_rects.clipped.min,
|
||||
surface_spatial_node_index,
|
||||
raster_spatial_node_index,
|
||||
device_pixel_scale,
|
||||
None,
|
||||
None,
|
||||
None,
|
||||
cmd_buffer_index,
|
||||
can_use_shared_surface,
|
||||
let is_opaque = false; // TODO
|
||||
let render_task_id = request_render_task(
|
||||
frame_state,
|
||||
&self.snapshot,
|
||||
&surface_rects,
|
||||
is_opaque,
|
||||
&mut|rg_builder, _, _| {
|
||||
rg_builder.add().init(
|
||||
RenderTask::new_dynamic(
|
||||
surface_rects.task_size,
|
||||
RenderTaskKind::new_picture(
|
||||
surface_rects.task_size,
|
||||
surface_rects.needs_scissor_rect,
|
||||
surface_rects.clipped.min,
|
||||
surface_spatial_node_index,
|
||||
raster_spatial_node_index,
|
||||
device_pixel_scale,
|
||||
None,
|
||||
None,
|
||||
None,
|
||||
cmd_buffer_index,
|
||||
can_use_shared_surface,
|
||||
)
|
||||
).with_uv_rect_kind(surface_rects.uv_rect_kind)
|
||||
)
|
||||
).with_uv_rect_kind(surface_rects.uv_rect_kind)
|
||||
}
|
||||
);
|
||||
|
||||
primary_render_task_id = render_task_id;
|
||||
|
@ -6163,23 +6208,32 @@ impl PicturePrimitive {
|
|||
PictureCompositeMode::Blit(_) => {
|
||||
let cmd_buffer_index = frame_state.cmd_buffers.create_cmd_buffer();
|
||||
|
||||
let render_task_id = frame_state.rg_builder.add().init(
|
||||
RenderTask::new_dynamic(
|
||||
surface_rects.task_size,
|
||||
RenderTaskKind::new_picture(
|
||||
surface_rects.task_size,
|
||||
surface_rects.needs_scissor_rect,
|
||||
surface_rects.clipped.min,
|
||||
surface_spatial_node_index,
|
||||
raster_spatial_node_index,
|
||||
device_pixel_scale,
|
||||
None,
|
||||
None,
|
||||
None,
|
||||
cmd_buffer_index,
|
||||
can_use_shared_surface,
|
||||
let is_opaque = false; // TODO
|
||||
let render_task_id = request_render_task(
|
||||
frame_state,
|
||||
&self.snapshot,
|
||||
&surface_rects,
|
||||
is_opaque,
|
||||
&mut|rg_builder, _, _| {
|
||||
rg_builder.add().init(
|
||||
RenderTask::new_dynamic(
|
||||
surface_rects.task_size,
|
||||
RenderTaskKind::new_picture(
|
||||
surface_rects.task_size,
|
||||
surface_rects.needs_scissor_rect,
|
||||
surface_rects.clipped.min,
|
||||
surface_spatial_node_index,
|
||||
raster_spatial_node_index,
|
||||
device_pixel_scale,
|
||||
None,
|
||||
None,
|
||||
None,
|
||||
cmd_buffer_index,
|
||||
can_use_shared_surface,
|
||||
)
|
||||
).with_uv_rect_kind(surface_rects.uv_rect_kind)
|
||||
)
|
||||
).with_uv_rect_kind(surface_rects.uv_rect_kind)
|
||||
}
|
||||
);
|
||||
|
||||
primary_render_task_id = render_task_id;
|
||||
|
@ -6198,23 +6252,32 @@ impl PicturePrimitive {
|
|||
// match cases (they used to be quite different).
|
||||
let cmd_buffer_index = frame_state.cmd_buffers.create_cmd_buffer();
|
||||
|
||||
let render_task_id = frame_state.rg_builder.add().init(
|
||||
RenderTask::new_dynamic(
|
||||
surface_rects.task_size,
|
||||
RenderTaskKind::new_picture(
|
||||
surface_rects.task_size,
|
||||
surface_rects.needs_scissor_rect,
|
||||
surface_rects.clipped.min,
|
||||
surface_spatial_node_index,
|
||||
raster_spatial_node_index,
|
||||
device_pixel_scale,
|
||||
None,
|
||||
None,
|
||||
None,
|
||||
cmd_buffer_index,
|
||||
can_use_shared_surface,
|
||||
let is_opaque = false; // TODO
|
||||
let render_task_id = request_render_task(
|
||||
frame_state,
|
||||
&self.snapshot,
|
||||
&surface_rects,
|
||||
is_opaque,
|
||||
&mut|rg_builder, _, _| {
|
||||
rg_builder.add().init(
|
||||
RenderTask::new_dynamic(
|
||||
surface_rects.task_size,
|
||||
RenderTaskKind::new_picture(
|
||||
surface_rects.task_size,
|
||||
surface_rects.needs_scissor_rect,
|
||||
surface_rects.clipped.min,
|
||||
surface_spatial_node_index,
|
||||
raster_spatial_node_index,
|
||||
device_pixel_scale,
|
||||
None,
|
||||
None,
|
||||
None,
|
||||
cmd_buffer_index,
|
||||
can_use_shared_surface,
|
||||
)
|
||||
).with_uv_rect_kind(surface_rects.uv_rect_kind)
|
||||
)
|
||||
).with_uv_rect_kind(surface_rects.uv_rect_kind)
|
||||
}
|
||||
);
|
||||
|
||||
primary_render_task_id = render_task_id;
|
||||
|
@ -6246,14 +6309,23 @@ impl PicturePrimitive {
|
|||
).with_uv_rect_kind(surface_rects.uv_rect_kind)
|
||||
);
|
||||
|
||||
let filter_task_id = RenderTask::new_svg_filter(
|
||||
primitives,
|
||||
filter_datas,
|
||||
frame_state.rg_builder,
|
||||
surface_rects.clipped.size().to_i32(),
|
||||
surface_rects.uv_rect_kind,
|
||||
picture_task_id,
|
||||
device_pixel_scale,
|
||||
let is_opaque = false; // TODO
|
||||
let filter_task_id = request_render_task(
|
||||
frame_state,
|
||||
&self.snapshot,
|
||||
&surface_rects,
|
||||
is_opaque,
|
||||
&mut|rg_builder, _, _| {
|
||||
RenderTask::new_svg_filter(
|
||||
primitives,
|
||||
filter_datas,
|
||||
rg_builder,
|
||||
surface_rects.clipped.size().to_i32(),
|
||||
surface_rects.uv_rect_kind,
|
||||
picture_task_id,
|
||||
device_pixel_scale,
|
||||
)
|
||||
}
|
||||
);
|
||||
|
||||
primary_render_task_id = filter_task_id;
|
||||
|
@ -6304,18 +6376,26 @@ impl PicturePrimitive {
|
|||
|
||||
// Produce the target pixels, this is the result of the
|
||||
// composite op
|
||||
let filter_task_id = RenderTask::new_svg_filter_graph(
|
||||
filters,
|
||||
&mut frame_state.rg_builder,
|
||||
&mut frame_state.gpu_cache,
|
||||
data_stores,
|
||||
surface_rects.uv_rect_kind,
|
||||
picture_task_id,
|
||||
source_subregion.cast_unit(),
|
||||
target_subregion.cast_unit(),
|
||||
prim_subregion.cast_unit(),
|
||||
surface_rects.clipped.cast_unit(),
|
||||
surface_rects.clipped_local.cast_unit(),
|
||||
let filter_task_id = request_render_task(
|
||||
frame_state,
|
||||
&self.snapshot,
|
||||
&surface_rects,
|
||||
false,
|
||||
&mut|rg_builder, _, gpu_cache| {
|
||||
RenderTask::new_svg_filter_graph(
|
||||
filters,
|
||||
rg_builder,
|
||||
gpu_cache,
|
||||
data_stores,
|
||||
surface_rects.uv_rect_kind,
|
||||
picture_task_id,
|
||||
source_subregion.cast_unit(),
|
||||
target_subregion.cast_unit(),
|
||||
prim_subregion.cast_unit(),
|
||||
surface_rects.clipped.cast_unit(),
|
||||
surface_rects.clipped_local.cast_unit(),
|
||||
)
|
||||
}
|
||||
);
|
||||
|
||||
primary_render_task_id = filter_task_id;
|
||||
|
@ -7047,7 +7127,7 @@ impl PicturePrimitive {
|
|||
thickness,
|
||||
color,
|
||||
ColorF::TRANSPARENT,
|
||||
);
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -7445,7 +7525,7 @@ impl TileNode {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// Calculate the four child rects for a given node
|
||||
fn get_child_rects(
|
||||
rect: &PictureBox2D,
|
||||
|
@ -8243,3 +8323,46 @@ fn test_drop_filter_dirty_region_outside_prim() {
|
|||
).expect("No surface rect");
|
||||
assert_eq!(info.task_size, DeviceIntSize::new(432, 578));
|
||||
}
|
||||
|
||||
fn request_render_task(
|
||||
frame_state: &mut FrameBuildingState,
|
||||
snapshot: &Option<SnapshotInfo>,
|
||||
surface_rects: &SurfaceAllocInfo,
|
||||
is_opaque: bool,
|
||||
f: &mut dyn FnMut(&mut RenderTaskGraphBuilder, &mut GpuBufferBuilderF, &mut GpuCache) -> RenderTaskId,
|
||||
) -> RenderTaskId {
|
||||
|
||||
let task_id = match snapshot {
|
||||
Some(info) => {
|
||||
let task_id = frame_state.resource_cache.render_as_image(
|
||||
info.key.as_image(),
|
||||
surface_rects.task_size,
|
||||
frame_state.rg_builder,
|
||||
&mut frame_state.frame_gpu_data.f32,
|
||||
frame_state.gpu_cache,
|
||||
is_opaque,
|
||||
f
|
||||
);
|
||||
|
||||
// TODO(bug 1929809): adding the dependency in the other branch causes
|
||||
// a panic in reftests/blend/backdrop-filter-blend-container.yaml.
|
||||
// Presumably if we use backdrop filters with snapshotting it will
|
||||
// trigger the panic as well.
|
||||
frame_state.surface_builder.add_child_render_task(
|
||||
task_id,
|
||||
frame_state.rg_builder,
|
||||
);
|
||||
|
||||
task_id
|
||||
}
|
||||
None => {
|
||||
f(
|
||||
frame_state.rg_builder,
|
||||
&mut frame_state.frame_gpu_data.f32,
|
||||
frame_state.gpu_cache
|
||||
)
|
||||
}
|
||||
};
|
||||
|
||||
task_id
|
||||
}
|
||||
|
|
|
@ -413,7 +413,7 @@ fn prepare_interned_prim_for_render(
|
|||
&mut frame_state.frame_gpu_data.f32,
|
||||
frame_state.rg_builder,
|
||||
&mut frame_state.surface_builder,
|
||||
&mut |rg_builder, _| {
|
||||
&mut |rg_builder, _, _| {
|
||||
rg_builder.add().init(RenderTask::new_dynamic(
|
||||
task_size,
|
||||
RenderTaskKind::new_line_decoration(
|
||||
|
@ -567,7 +567,7 @@ fn prepare_interned_prim_for_render(
|
|||
&mut frame_state.frame_gpu_data.f32,
|
||||
frame_state.rg_builder,
|
||||
&mut frame_state.surface_builder,
|
||||
&mut |rg_builder, _| {
|
||||
&mut |rg_builder, _, _| {
|
||||
rg_builder.add().init(RenderTask::new_dynamic(
|
||||
cache_size,
|
||||
RenderTaskKind::new_border_segment(
|
||||
|
|
|
@ -293,7 +293,7 @@ impl ConicGradientTemplate {
|
|||
&mut frame_state.frame_gpu_data.f32,
|
||||
frame_state.rg_builder,
|
||||
&mut frame_state.surface_builder,
|
||||
&mut |rg_builder, gpu_buffer_builder| {
|
||||
&mut |rg_builder, gpu_buffer_builder, _| {
|
||||
let stops = GradientGpuBlockBuilder::build(
|
||||
false,
|
||||
gpu_buffer_builder,
|
||||
|
|
|
@ -525,7 +525,7 @@ impl LinearGradientTemplate {
|
|||
&mut frame_state.frame_gpu_data.f32,
|
||||
frame_state.rg_builder,
|
||||
&mut frame_state.surface_builder,
|
||||
&mut |rg_builder, _| {
|
||||
&mut |rg_builder, _, _| {
|
||||
rg_builder.add().init(RenderTask::new_dynamic(
|
||||
self.task_size,
|
||||
RenderTaskKind::FastLinearGradient(gradient),
|
||||
|
@ -554,7 +554,7 @@ impl LinearGradientTemplate {
|
|||
&mut frame_state.frame_gpu_data.f32,
|
||||
frame_state.rg_builder,
|
||||
&mut frame_state.surface_builder,
|
||||
&mut |rg_builder, gpu_buffer_builder| {
|
||||
&mut |rg_builder, gpu_buffer_builder, _| {
|
||||
let stops = Some(GradientGpuBlockBuilder::build(
|
||||
self.reverse_stops,
|
||||
gpu_buffer_builder,
|
||||
|
|
|
@ -259,7 +259,7 @@ impl RadialGradientTemplate {
|
|||
&mut frame_state.frame_gpu_data.f32,
|
||||
frame_state.rg_builder,
|
||||
&mut frame_state.surface_builder,
|
||||
&mut |rg_builder, gpu_buffer_builder| {
|
||||
&mut |rg_builder, gpu_buffer_builder, _| {
|
||||
let stops = GradientGpuBlockBuilder::build(
|
||||
false,
|
||||
gpu_buffer_builder,
|
||||
|
|
|
@ -260,7 +260,7 @@ impl ImageData {
|
|||
&mut frame_state.frame_gpu_data.f32,
|
||||
frame_state.rg_builder,
|
||||
&mut frame_state.surface_builder,
|
||||
&mut |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.
|
||||
|
|
|
@ -677,7 +677,7 @@ impl RenderTaskKind {
|
|||
gpu_buffer_builder,
|
||||
rg_builder,
|
||||
surface_builder,
|
||||
&mut |rg_builder, _| {
|
||||
&mut |rg_builder, _, _| {
|
||||
let clip_data = ClipData::rounded_rect(
|
||||
source.minimal_shadow_rect.size(),
|
||||
&source.shadow_radius,
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
|
||||
use api::{ImageDescriptor, ImageDescriptorFlags, DirtyRect};
|
||||
use api::{DirtyRect, ImageDescriptor, ImageDescriptorFlags, SnapshotImageKey};
|
||||
use api::units::*;
|
||||
use crate::border::BorderSegmentCacheKey;
|
||||
use crate::box_shadow::{BoxShadowCacheKey};
|
||||
|
@ -52,6 +52,7 @@ pub enum RenderTaskCacheKeyKind {
|
|||
LinearGradient(LinearGradientCacheKey),
|
||||
RadialGradient(RadialGradientCacheKey),
|
||||
ConicGradient(ConicGradientCacheKey),
|
||||
Snapshot(SnapshotImageKey),
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Hash, PartialEq, Eq)]
|
||||
|
@ -232,13 +233,13 @@ impl RenderTaskCache {
|
|||
gpu_buffer_builder: &mut GpuBufferBuilderF,
|
||||
rg_builder: &mut RenderTaskGraphBuilder,
|
||||
surface_builder: &mut SurfaceBuilder,
|
||||
f: &mut dyn FnMut(&mut RenderTaskGraphBuilder, &mut GpuBufferBuilderF) -> RenderTaskId,
|
||||
f: &mut dyn FnMut(&mut RenderTaskGraphBuilder, &mut GpuBufferBuilderF, &mut GpuCache) -> 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),
|
||||
None => (f(rg_builder, gpu_buffer_builder, gpu_cache), true),
|
||||
Some(key) => self.request_render_task_impl(
|
||||
key,
|
||||
is_opaque,
|
||||
|
@ -285,7 +286,7 @@ impl RenderTaskCache {
|
|||
gpu_cache: &mut GpuCache,
|
||||
gpu_buffer_builder: &mut GpuBufferBuilderF,
|
||||
rg_builder: &mut RenderTaskGraphBuilder,
|
||||
f: &mut dyn FnMut(&mut RenderTaskGraphBuilder, &mut GpuBufferBuilderF) -> RenderTaskId,
|
||||
f: &mut dyn FnMut(&mut RenderTaskGraphBuilder, &mut GpuBufferBuilderF, &mut GpuCache) -> RenderTaskId,
|
||||
) -> (RenderTaskId, bool) {
|
||||
let frame_id = self.frame_id;
|
||||
let size = key.size;
|
||||
|
@ -310,7 +311,7 @@ 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, gpu_cache);
|
||||
|
||||
cache_entry.user_data = None;
|
||||
cache_entry.is_opaque = is_opaque;
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
use api::{BlobImageRequest, RasterizedBlobImage, ImageFormat, ImageDescriptorFlags};
|
||||
use api::{BlobImageRequest, ImageDescriptorFlags, ImageFormat, RasterizedBlobImage};
|
||||
use api::{DebugFlags, FontInstanceKey, FontKey, FontTemplate, GlyphIndex};
|
||||
use api::{ExternalImageData, ExternalImageType, ExternalImageId, BlobImageResult};
|
||||
use api::{DirtyRect, GlyphDimensions, IdNamespace, DEFAULT_TILE_SIZE};
|
||||
|
@ -115,6 +115,11 @@ pub enum CachedImageData {
|
|||
///
|
||||
/// The commands are stored elsewhere and this variant is used as a placeholder.
|
||||
Blob,
|
||||
/// A stacking context for which a snapshot has been requested.
|
||||
///
|
||||
/// The snapshot is grabbed from GPU-side rasterized pixels so there is no
|
||||
/// CPU-side data to store here.
|
||||
Snapshot,
|
||||
/// An image owned by the embedding, and referenced by WebRender. This may
|
||||
/// take the form of a texture or a heap-allocated buffer.
|
||||
External(ExternalImageData),
|
||||
|
@ -139,6 +144,14 @@ impl CachedImageData {
|
|||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn is_snapshot(&self) -> bool {
|
||||
match *self {
|
||||
CachedImageData::Snapshot => true,
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns true if this variant of CachedImageData should go through the texture
|
||||
/// cache.
|
||||
#[inline]
|
||||
|
@ -150,6 +163,7 @@ impl CachedImageData {
|
|||
},
|
||||
CachedImageData::Blob => true,
|
||||
CachedImageData::Raw(_) => true,
|
||||
CachedImageData::Snapshot => true,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -575,6 +589,7 @@ impl ResourceCache {
|
|||
// not make sense to tile them into smaller ones.
|
||||
info.image_type == ExternalImageType::Buffer && size_check
|
||||
}
|
||||
CachedImageData::Snapshot => false,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -598,10 +613,10 @@ impl ResourceCache {
|
|||
gpu_buffer_builder: &mut GpuBufferBuilderF,
|
||||
rg_builder: &mut RenderTaskGraphBuilder,
|
||||
surface_builder: &mut SurfaceBuilder,
|
||||
f: &mut dyn FnMut(&mut RenderTaskGraphBuilder, &mut GpuBufferBuilderF) -> RenderTaskId,
|
||||
f: &mut dyn FnMut(&mut RenderTaskGraphBuilder, &mut GpuBufferBuilderF, &mut GpuCache) -> RenderTaskId,
|
||||
) -> RenderTaskId {
|
||||
self.cached_render_tasks.request_render_task(
|
||||
key,
|
||||
key.clone(),
|
||||
&mut self.texture_cache,
|
||||
is_opaque,
|
||||
parent,
|
||||
|
@ -748,11 +763,25 @@ impl ResourceCache {
|
|||
ResourceUpdate::DeleteBlobImage(img) => {
|
||||
self.delete_image_template(img.as_image());
|
||||
}
|
||||
ResourceUpdate::AddSnapshotImage(_img) => {
|
||||
// TODO
|
||||
ResourceUpdate::AddSnapshotImage(img) => {
|
||||
let format = self.texture_cache.shared_color_expected_format();
|
||||
self.add_image_template(
|
||||
img.key.as_image(),
|
||||
ImageDescriptor {
|
||||
format,
|
||||
// We'll know about the size when creating the render task.
|
||||
size: DeviceIntSize::zero(),
|
||||
stride: None,
|
||||
offset: 0,
|
||||
flags: ImageDescriptorFlags::empty(),
|
||||
},
|
||||
CachedImageData::Snapshot,
|
||||
&DeviceIntRect::zero(),
|
||||
None,
|
||||
);
|
||||
}
|
||||
ResourceUpdate::DeleteSnapshotImage(_img) => {
|
||||
// TODO
|
||||
ResourceUpdate::DeleteSnapshotImage(img) => {
|
||||
self.delete_image_template(img.as_image());
|
||||
}
|
||||
ResourceUpdate::DeleteFont(font) => {
|
||||
if let Some(shared_key) = self.resources.fonts.font_keys.delete_key(&font) {
|
||||
|
@ -1333,7 +1362,10 @@ impl ResourceCache {
|
|||
ExternalImageType::Buffer => None,
|
||||
},
|
||||
// raw and blob image are all using resource_cache.
|
||||
CachedImageData::Raw(..) | CachedImageData::Blob => None,
|
||||
CachedImageData::Raw(..)
|
||||
| CachedImageData::Blob
|
||||
| CachedImageData::Snapshot
|
||||
=> None,
|
||||
};
|
||||
|
||||
ImageProperties {
|
||||
|
@ -1437,7 +1469,11 @@ impl ResourceCache {
|
|||
let mut updates: SmallVec<[(CachedImageData, Option<DeviceIntRect>); 1]> = SmallVec::new();
|
||||
|
||||
match image_template.data {
|
||||
CachedImageData::Raw(..) | CachedImageData::External(..) => {
|
||||
CachedImageData::Snapshot => {
|
||||
// The update is done in ResourceCache::render_as_image.
|
||||
}
|
||||
CachedImageData::Raw(..)
|
||||
| CachedImageData::External(..) => {
|
||||
// Safe to clone here since the Raw image data is an
|
||||
// Arc, and the external image data is small.
|
||||
updates.push((image_template.data.clone(), None));
|
||||
|
@ -1517,11 +1553,14 @@ impl ResourceCache {
|
|||
}
|
||||
};
|
||||
|
||||
let eviction = if image_template.data.is_blob() {
|
||||
entry.manual_eviction = true;
|
||||
Eviction::Manual
|
||||
} else {
|
||||
Eviction::Auto
|
||||
let eviction = match &image_template.data {
|
||||
CachedImageData::Blob | CachedImageData::Snapshot => {
|
||||
entry.manual_eviction = true;
|
||||
Eviction::Manual
|
||||
}
|
||||
_ => {
|
||||
Eviction::Auto
|
||||
}
|
||||
};
|
||||
|
||||
//Note: at this point, the dirty rectangle is local to the descriptor space
|
||||
|
@ -1788,7 +1827,9 @@ impl ResourceCache {
|
|||
for (_, image) in self.resources.image_templates.images.iter() {
|
||||
report.images += match image.data {
|
||||
CachedImageData::Raw(ref v) => unsafe { op(v.as_ptr() as *const c_void) },
|
||||
CachedImageData::Blob | CachedImageData::External(..) => 0,
|
||||
CachedImageData::Blob
|
||||
| CachedImageData::External(..)
|
||||
| CachedImageData::Snapshot => 0,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2131,6 +2172,9 @@ impl ResourceCache {
|
|||
.unwrap();
|
||||
other_paths.insert(key, short_path);
|
||||
}
|
||||
CachedImageData::Snapshot => {
|
||||
unimplemented!();
|
||||
}
|
||||
CachedImageData::External(ref ext) => {
|
||||
let short_path = format!("externals/{}", external_images.len() + 1);
|
||||
other_paths.insert(key, short_path.clone());
|
||||
|
|
|
@ -35,7 +35,7 @@
|
|||
//! - backdrop filters (see add_backdrop_filter)
|
||||
//!
|
||||
|
||||
use api::{AlphaType, BorderDetails, BorderDisplayItem, BuiltDisplayListIter, BuiltDisplayList, PrimitiveFlags};
|
||||
use api::{AlphaType, BorderDetails, BorderDisplayItem, BuiltDisplayList, BuiltDisplayListIter, PrimitiveFlags, SnapshotInfo};
|
||||
use api::{ClipId, ColorF, CommonItemProperties, ComplexClipRegion, ComponentTransferFuncType, RasterSpace};
|
||||
use api::{DebugFlags, DisplayItem, DisplayItemRef, ExtendMode, ExternalScrollId, FilterData};
|
||||
use api::{FilterOp, FilterPrimitive, FontInstanceKey, FontSize, GlyphInstance, GlyphOptions, GradientStop};
|
||||
|
@ -152,6 +152,7 @@ pub struct CompositeOps {
|
|||
pub filters: Vec<Filter>,
|
||||
pub filter_datas: Vec<FilterData>,
|
||||
pub filter_primitives: Vec<FilterPrimitive>,
|
||||
pub snapshot: Option<SnapshotInfo>,
|
||||
|
||||
// Requires two source textures (e.g. mix-blend-mode)
|
||||
pub mix_blend_mode: Option<MixBlendMode>,
|
||||
|
@ -162,20 +163,23 @@ impl CompositeOps {
|
|||
filters: Vec<Filter>,
|
||||
filter_datas: Vec<FilterData>,
|
||||
filter_primitives: Vec<FilterPrimitive>,
|
||||
mix_blend_mode: Option<MixBlendMode>
|
||||
mix_blend_mode: Option<MixBlendMode>,
|
||||
snapshot: Option<SnapshotInfo>,
|
||||
) -> Self {
|
||||
CompositeOps {
|
||||
filters,
|
||||
filter_datas,
|
||||
filter_primitives,
|
||||
mix_blend_mode,
|
||||
snapshot,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn is_empty(&self) -> bool {
|
||||
self.filters.is_empty() &&
|
||||
self.filter_primitives.is_empty() &&
|
||||
self.mix_blend_mode.is_none()
|
||||
self.mix_blend_mode.is_none() &&
|
||||
self.snapshot.is_none()
|
||||
}
|
||||
|
||||
/// Returns true if this CompositeOps contains any filters that affect
|
||||
|
@ -332,6 +336,7 @@ impl PictureChainBuilder {
|
|||
self.spatial_node_index,
|
||||
self.raster_space,
|
||||
flags,
|
||||
None,
|
||||
))
|
||||
);
|
||||
|
||||
|
@ -364,6 +369,7 @@ impl PictureChainBuilder {
|
|||
interners: &mut Interners,
|
||||
prim_store: &mut PrimitiveStore,
|
||||
clip_tree_builder: &mut ClipTreeBuilder,
|
||||
snapshot: Option<SnapshotInfo>,
|
||||
) -> PrimitiveInstance {
|
||||
let mut flags = PictureFlags::empty();
|
||||
if self.establishes_sub_graph {
|
||||
|
@ -373,7 +379,9 @@ impl PictureChainBuilder {
|
|||
match self.current {
|
||||
PictureSource::WrappedPicture { instance } => {
|
||||
let pic_index = instance.kind.as_pic();
|
||||
prim_store.pictures[pic_index.0].flags |= flags;
|
||||
let picture = &mut prim_store.pictures[pic_index.0];
|
||||
picture.flags |= flags;
|
||||
picture.snapshot = snapshot;
|
||||
|
||||
instance
|
||||
}
|
||||
|
@ -395,6 +403,7 @@ impl PictureChainBuilder {
|
|||
self.spatial_node_index,
|
||||
self.raster_space,
|
||||
flags,
|
||||
snapshot,
|
||||
))
|
||||
);
|
||||
|
||||
|
@ -937,6 +946,7 @@ impl<'a> SceneBuilder<'a> {
|
|||
filter_datas_for_compositing(item.filter_datas()),
|
||||
filter_primitives_for_compositing(item.filter_primitives()),
|
||||
info.stacking_context.mix_blend_mode_for_compositing(),
|
||||
info.snapshot,
|
||||
);
|
||||
|
||||
let sc_info = self.push_stacking_context(
|
||||
|
@ -2245,6 +2255,11 @@ impl<'a> SceneBuilder<'a> {
|
|||
// clip node doesn't affect the stacking context rect.
|
||||
let mut blit_reason = BlitReason::empty();
|
||||
|
||||
// Stacking context snapshots are offscreen syrfaces.
|
||||
if composite_ops.snapshot.is_some() {
|
||||
blit_reason = BlitReason::SNAPSHOT;
|
||||
}
|
||||
|
||||
// If this stacking context has any complex clips, we need to draw it
|
||||
// to an off-screen surface.
|
||||
if let Some(clip_chain_id) = clip_chain_id {
|
||||
|
@ -2393,6 +2408,7 @@ impl<'a> SceneBuilder<'a> {
|
|||
stacking_context.spatial_node_index,
|
||||
stacking_context.raster_space,
|
||||
PictureFlags::empty(),
|
||||
None,
|
||||
))
|
||||
);
|
||||
|
||||
|
@ -2437,6 +2453,7 @@ impl<'a> SceneBuilder<'a> {
|
|||
stacking_context.spatial_node_index,
|
||||
stacking_context.raster_space,
|
||||
PictureFlags::empty(),
|
||||
None,
|
||||
))
|
||||
);
|
||||
|
||||
|
@ -2468,6 +2485,7 @@ impl<'a> SceneBuilder<'a> {
|
|||
&mut self.interners,
|
||||
&mut self.prim_store,
|
||||
&mut self.clip_tree_builder,
|
||||
None,
|
||||
);
|
||||
|
||||
prims.push(ExtendedPrimitiveInstance {
|
||||
|
@ -2541,6 +2559,7 @@ impl<'a> SceneBuilder<'a> {
|
|||
stacking_context.spatial_node_index,
|
||||
stacking_context.raster_space,
|
||||
PictureFlags::empty(),
|
||||
None,
|
||||
))
|
||||
);
|
||||
|
||||
|
@ -2609,6 +2628,7 @@ impl<'a> SceneBuilder<'a> {
|
|||
&mut self.interners,
|
||||
&mut self.prim_store,
|
||||
&mut self.clip_tree_builder,
|
||||
stacking_context.composite_ops.snapshot,
|
||||
);
|
||||
|
||||
// The primitive instance for the remainder of flat children of this SC
|
||||
|
@ -3020,6 +3040,7 @@ impl<'a> SceneBuilder<'a> {
|
|||
pending_shadow.spatial_node_index,
|
||||
raster_space,
|
||||
PictureFlags::empty(),
|
||||
None,
|
||||
))
|
||||
);
|
||||
|
||||
|
@ -3742,6 +3763,7 @@ impl<'a> SceneBuilder<'a> {
|
|||
&mut self.interners,
|
||||
&mut self.prim_store,
|
||||
&mut self.clip_tree_builder,
|
||||
None,
|
||||
);
|
||||
|
||||
// Extract the pic index for the intermediate surface. We need to
|
||||
|
@ -4576,6 +4598,7 @@ impl FlattenedStackingContext {
|
|||
self.spatial_node_index,
|
||||
self.raster_space,
|
||||
PictureFlags::empty(),
|
||||
None
|
||||
))
|
||||
);
|
||||
|
||||
|
@ -4760,7 +4783,7 @@ fn read_gradient_stops(stops: ItemRange<GradientStop>) -> Vec<GradientStopKey> {
|
|||
|
||||
/// A helper for reusing the scene builder's memory allocations and dropping
|
||||
/// scene allocations on the scene builder thread to avoid lock contention in
|
||||
/// jemalloc.
|
||||
/// jemalloc.
|
||||
pub struct SceneRecycler {
|
||||
pub tx: Sender<BuiltScene>,
|
||||
rx: Receiver<BuiltScene>,
|
||||
|
@ -4829,7 +4852,7 @@ impl SceneRecycler {
|
|||
self.clip_store = scene.clip_store;
|
||||
// We currently retain top-level allocations but don't attempt to retain leaf
|
||||
// allocations in the prim store and clip store. We don't have to reset it here
|
||||
// but doing so avoids dropping the leaf allocations in the
|
||||
// but doing so avoids dropping the leaf allocations in the
|
||||
self.prim_store.reset();
|
||||
self.clip_store.reset();
|
||||
self.hit_testing_scene = Arc::try_unwrap(scene.hit_testing_scene).ok();
|
||||
|
|
|
@ -1574,6 +1574,9 @@ impl TextureCacheUpdate {
|
|||
dirty_rect: &ImageDirtyRect,
|
||||
) -> TextureCacheUpdate {
|
||||
let source = match data {
|
||||
CachedImageData::Snapshot => {
|
||||
panic!("Snapshots should not do texture uploads");
|
||||
}
|
||||
CachedImageData::Blob => {
|
||||
panic!("The vector image should have been rasterized.");
|
||||
}
|
||||
|
|
|
@ -638,6 +638,7 @@ fn create_tile_cache(
|
|||
scroll_root,
|
||||
RasterSpace::Screen,
|
||||
PictureFlags::empty(),
|
||||
None,
|
||||
));
|
||||
|
||||
tile_cache_pictures.push(PictureIndex(pic_index));
|
||||
|
|
Загрузка…
Ссылка в новой задаче