Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add basic infrastructure for caching Pictures, enable for some blurs. #2651

Merged
merged 1 commit into from Apr 15, 2018
Merged
Changes from all commits
Commits
File filter...
Filter file types
Jump to…
Jump to file
Failed to load files.

Always

Just for now

@@ -11,12 +11,12 @@ use clip::{ClipSource, ClipStore, ClipWorkItem};
use clip_scroll_tree::{CoordinateSystemId};
use euclid::{TypedTransform3D, vec3};
use glyph_rasterizer::GlyphFormat;
use gpu_cache::{GpuCache, GpuCacheAddress};
use gpu_cache::{GpuCache, GpuCacheAddress, GpuCacheHandle};
use gpu_types::{BrushFlags, BrushInstance, ClipChainRectIndex, ZBufferId, ZBufferIdGenerator};
use gpu_types::{ClipMaskInstance, ClipScrollNodeIndex, RasterizationSpace};
use gpu_types::{CompositePrimitiveInstance, PrimitiveInstance, SimplePrimitiveInstance};
use internal_types::{FastHashMap, SavedTargetIndex, SourceTexture};
use picture::{PictureCompositeMode, PicturePrimitive};
use picture::{PictureCompositeMode, PicturePrimitive, PictureSurface};
use plane_split::{BspSplitter, Polygon, Splitter};
use prim_store::{CachedGradient, ImageSource, PrimitiveIndex, PrimitiveKind, PrimitiveMetadata, PrimitiveStore};
use prim_store::{BrushPrimitive, BrushKind, DeferredResolve, EdgeAaSegmentMask, PictureIndex, PrimitiveRun};
@@ -514,8 +514,12 @@ impl AlphaBatchBuilder {
let pic = &ctx.prim_store.pictures[brush.get_picture_index().0];
let batch = self.batch_list.get_suitable_batch(key, &pic_metadata.screen_rect.as_ref().expect("bug").clipped);

let render_task_id = pic.surface.expect("BUG: unexpected surface in splitting");
let source_task_address = render_tasks.get_task_address(render_task_id);
let source_task_id = pic
.surface
.as_ref()
.expect("BUG: unexpected surface in splitting")
.resolve_render_task_id();
let source_task_address = render_tasks.get_task_address(source_task_id);
let gpu_address = gpu_handle.as_int(gpu_cache);

let instance = CompositePrimitiveInstance::new(
@@ -669,21 +673,18 @@ impl AlphaBatchBuilder {
match filter {
FilterOp::Blur(..) => {
match picture.surface {
Some(cache_task_id) => {
Some(ref surface) => {
let kind = BatchKind::Brush(
BrushBatchKind::Image(ImageBufferKind::Texture2DArray)
);
let (uv_rect_address, textures) = surface.resolve(render_tasks);
let key = BatchKey::new(
kind,
non_segmented_blend_mode,
BatchTextures::render_target_cache(),
textures,
);
let batch = self.batch_list.get_suitable_batch(key, &task_relative_bounding_rect);

let uv_rect_address = render_tasks[cache_task_id]
.get_texture_handle()
.as_int(gpu_cache);

let instance = BrushInstance {
picture_address: task_address,
prim_address: prim_cache_address,
@@ -695,7 +696,7 @@ impl AlphaBatchBuilder {
edge_flags: EdgeAaSegmentMask::empty(),
brush_flags: BrushFlags::empty(),
user_data: [
uv_rect_address,
uv_rect_address.as_int(gpu_cache),
(BrushImageSourceKind::Color as i32) << 16 |
RasterizationSpace::Screen as i32,
picture.extra_gpu_data_handle.as_int(gpu_cache),
@@ -710,10 +711,10 @@ impl AlphaBatchBuilder {
}
}
FilterOp::DropShadow(..) => {
if let Some(cache_task_id) = picture.surface {
// Draw an instance of the shadow first, following by the content.
// Draw an instance of the shadow first, following by the content.

// Both the shadow and the content get drawn as a brush image.
// Both the shadow and the content get drawn as a brush image.
if let Some(ref surface) = picture.surface {
let kind = BatchKind::Brush(
BrushBatchKind::Image(ImageBufferKind::Texture2DArray),
);
@@ -739,6 +740,7 @@ impl AlphaBatchBuilder {
let content_key = BatchKey::new(kind, non_segmented_blend_mode, content_textures);

// Retrieve the UV rect addresses for shadow/content.
let cache_task_id = surface.resolve_render_task_id();
let shadow_uv_rect_address = render_tasks[cache_task_id]
.get_texture_handle()
.as_int(gpu_cache);
@@ -793,7 +795,7 @@ impl AlphaBatchBuilder {
}
_ => {
match picture.surface {
Some(cache_task_id) => {
Some(ref surface) => {
let key = BatchKey::new(
BatchKind::Brush(BrushBatchKind::Blend),
BlendMode::PremultipliedAlpha,
@@ -837,6 +839,7 @@ impl AlphaBatchBuilder {
}
};

let cache_task_id = surface.resolve_render_task_id();
let cache_task_address = render_tasks.get_task_address(cache_task_id);

let instance = BrushInstance {
@@ -868,7 +871,11 @@ impl AlphaBatchBuilder {
}
}
Some(PictureCompositeMode::MixBlend(mode)) => {
let cache_task_id = picture.surface.expect("bug: no surface allocated");
let cache_task_id = picture
.surface
.as_ref()
.expect("bug: no surface allocated")
.resolve_render_task_id();
let backdrop_id = picture.secondary_render_task_id.expect("no backdrop!?");

let key = BatchKey::new(
@@ -907,8 +914,11 @@ impl AlphaBatchBuilder {
false
}
Some(PictureCompositeMode::Blit) => {
let cache_task_id =
picture.surface.expect("bug: no surface allocated");
let cache_task_id = picture
.surface
.as_ref()
.expect("bug: no surface allocated")
.resolve_render_task_id();
let kind = BatchKind::Brush(
BrushBatchKind::Image(ImageBufferKind::Texture2DArray)
);
@@ -1465,6 +1475,43 @@ impl AlphaBatchHelpers for PrimitiveStore {
}
}

impl PictureSurface {
// Retrieve the uv rect handle, and texture for a picture surface.
fn resolve<'a>(
&'a self,
render_tasks: &'a RenderTaskTree,
) -> (&'a GpuCacheHandle, BatchTextures) {
match *self {
PictureSurface::TextureCache(ref cache_item) => {
(
&cache_item.uv_rect_handle,
BatchTextures::color(cache_item.texture_id),
)
}
PictureSurface::RenderTask(task_id) => {
(
render_tasks[task_id].get_texture_handle(),
BatchTextures::render_target_cache(),
)
}
}
}

// Retrieve the render task id for a picture surface. Should only
// be used where it's known that this picture surface will never
// be persisted in the texture cache.
fn resolve_render_task_id(&self) -> RenderTaskId {
match *self {
PictureSurface::TextureCache(..) => {
panic!("BUG: unexpectedly cached render task");
}
PictureSurface::RenderTask(task_id) => {
task_id
}
}
}
}

pub fn resolve_image(
request: ImageRequest,
resource_cache: &ResourceCache,
@@ -558,6 +558,7 @@ pub struct ClipChain {
pub combined_outer_screen_rect: DeviceIntRect,
pub combined_inner_screen_rect: DeviceIntRect,
pub nodes: ClipChainNodeRef,
pub has_non_root_coord_system: bool,
}

impl ClipChain {
@@ -567,6 +568,7 @@ impl ClipChain {
combined_inner_screen_rect: *screen_rect,
combined_outer_screen_rect: *screen_rect,
nodes: None,
has_non_root_coord_system: false,
}
}

@@ -599,6 +601,8 @@ impl ClipChain {
self.combined_inner_screen_rect.intersection(&new_node.screen_inner_rect)
.unwrap_or_else(DeviceIntRect::zero);

self.has_non_root_coord_system |= new_node.work_item.coordinate_system_id != CoordinateSystemId::root();

self.nodes = Some(Arc::new(new_node));
}
}
@@ -13,6 +13,7 @@ use gpu_cache::GpuCache;
use gpu_types::{ClipChainRectIndex, ClipScrollNodeData};
use hit_test::{HitTester, HitTestingRun};
use internal_types::{FastHashMap};
use picture::PictureSurface;
use prim_store::{CachedGradient, PrimitiveIndex, PrimitiveRun, PrimitiveStore};
use profiler::{FrameProfileCounters, GpuCacheProfileCounters, TextureCacheProfileCounters};
use render_backend::FrameId;
@@ -80,12 +81,14 @@ pub struct PictureContext<'a> {

pub struct PictureState {
pub tasks: Vec<RenderTaskId>,
pub has_non_root_coord_system: bool,
}

impl PictureState {
pub fn new() -> PictureState {
PictureState {
tasks: Vec::new(),
has_non_root_coord_system: false,
}
}
}
@@ -231,7 +234,7 @@ impl FrameBuilder {
);

let render_task_id = frame_state.render_tasks.add(root_render_task);
pic.surface = Some(render_task_id);
pic.surface = Some(PictureSurface::RenderTask(render_task_id));
Some(render_task_id)
}

ProTip! Use n and p to navigate between commits in a pull request.
You can’t perform that action at this time.