Skip to content

Commit

Permalink
Remove gpu_location from PrimitiveInstance.
Browse files Browse the repository at this point in the history
It's not used by interned primitives, and it's a performance win
on talos whenever we can reduce the size of PrimitiveInstance.
  • Loading branch information
gw3583 committed Nov 12, 2018
1 parent 83f135e commit 6599760
Show file tree
Hide file tree
Showing 3 changed files with 127 additions and 130 deletions.
42 changes: 21 additions & 21 deletions webrender/src/batch.rs
Original file line number Diff line number Diff line change
Expand Up @@ -797,7 +797,7 @@ impl AlphaBatchBuilder {
PrimitiveInstanceKind::Picture { pic_index } => {
let picture = &ctx.prim_store.pictures[pic_index.0];
let non_segmented_blend_mode = BlendMode::PremultipliedAlpha;
let prim_cache_address = gpu_cache.get_address(&prim_instance.gpu_location);
let prim_cache_address = gpu_cache.get_address(&picture.gpu_location);

let prim_header = PrimitiveHeader {
local_rect: picture.local_rect,
Expand Down Expand Up @@ -1225,28 +1225,8 @@ impl AlphaBatchBuilder {
}
};

let prim_cache_address = if is_multiple_primitives {
GpuCacheAddress::invalid()
} else {
gpu_cache.get_address(&prim_instance.gpu_location)
};

let specified_blend_mode = prim_instance.get_blend_mode(&prim.details);

let prim_header = PrimitiveHeader {
local_rect: prim.local_rect,
local_clip_rect: prim_instance.combined_local_clip_rect,
task_address,
specific_prim_address: prim_cache_address,
clip_task_address,
transform_id,
};

if prim_instance.is_chased() {
println!("\ttask target {:?}", self.target_rect);
println!("\t{:?}", prim_header);
}

match prim.details {
PrimitiveDetails::Brush(ref brush) => {
let non_segmented_blend_mode = if !brush.opacity.is_opaque ||
Expand All @@ -1258,6 +1238,26 @@ impl AlphaBatchBuilder {
BlendMode::None
};

let prim_cache_address = if is_multiple_primitives {
GpuCacheAddress::invalid()
} else {
gpu_cache.get_address(&brush.gpu_location)
};

let prim_header = PrimitiveHeader {
local_rect: prim.local_rect,
local_clip_rect: prim_instance.combined_local_clip_rect,
task_address,
specific_prim_address: prim_cache_address,
clip_task_address,
transform_id,
};

if prim_instance.is_chased() {
println!("\ttask target {:?}", self.target_rect);
println!("\t{:?}", prim_header);
}

match brush.kind {
BrushKind::Image { alpha_type, request, ref opacity_binding, ref visible_tiles, .. } if !visible_tiles.is_empty() => {
for tile in visible_tiles {
Expand Down
7 changes: 7 additions & 0 deletions webrender/src/picture.rs
Original file line number Diff line number Diff line change
Expand Up @@ -407,6 +407,8 @@ pub struct PicturePrimitive {

/// A descriptor for this surface that can be used as a cache key.
surface_desc: Option<SurfaceDescriptor>,

pub gpu_location: GpuCacheHandle,
}

impl PicturePrimitive {
Expand Down Expand Up @@ -485,6 +487,7 @@ impl PicturePrimitive {
spatial_node_index,
local_rect: LayoutRect::zero(),
local_clip_rect,
gpu_location: GpuCacheHandle::new(),
}
}

Expand Down Expand Up @@ -615,6 +618,10 @@ impl PicturePrimitive {
let local_rect_changed = local_rect != self.local_rect;
self.local_rect = local_rect;

if local_rect_changed {
frame_state.gpu_cache.invalidate(&mut self.gpu_location);
}

(local_rect_changed, Some(frame_state.clip_store.pop_surface()))
}
None => {
Expand Down
208 changes: 99 additions & 109 deletions webrender/src/prim_store.rs
Original file line number Diff line number Diff line change
Expand Up @@ -932,6 +932,7 @@ pub struct BrushPrimitive {
pub kind: BrushKind,
pub opacity: PrimitiveOpacity,
pub segment_desc: Option<BrushSegmentDescriptor>,
pub gpu_location: GpuCacheHandle,
}

impl BrushPrimitive {
Expand All @@ -943,80 +944,101 @@ impl BrushPrimitive {
kind,
opacity: PrimitiveOpacity::translucent(),
segment_desc,
gpu_location: GpuCacheHandle::new(),
}
}

fn write_gpu_blocks(
&self,
request: &mut GpuDataRequest,
fn write_gpu_blocks_if_required(
&mut self,
local_rect: LayoutRect,
gpu_cache: &mut GpuCache,
) {
// has to match VECS_PER_SPECIFIC_BRUSH
match self.kind {
BrushKind::Border { .. } => {
// Border primitives currently used for
// image borders, and run through the
// normal brush_image shader.
request.push(PremultipliedColorF::WHITE);
request.push(PremultipliedColorF::WHITE);
request.push([
local_rect.size.width,
local_rect.size.height,
0.0,
0.0,
]);
}
BrushKind::YuvImage { color_depth, .. } => {
request.push([
color_depth.rescaling_factor(),
0.0,
0.0,
0.0
]);
}
// Images are drawn as a white color, modulated by the total
// opacity coming from any collapsed property bindings.
BrushKind::Image { stretch_size, tile_spacing, color, .. } => {
request.push(color.premultiplied());
request.push(PremultipliedColorF::WHITE);
request.push([
stretch_size.width + tile_spacing.width,
stretch_size.height + tile_spacing.height,
0.0,
0.0,
]);
}
// Solid rects also support opacity collapsing.
BrushKind::Solid { ref color, .. } => {
request.push(color.premultiplied());
}
BrushKind::LinearGradient { stretch_size, start_point, end_point, extend_mode, .. } => {
request.push([
start_point.x,
start_point.y,
end_point.x,
end_point.y,
]);
request.push([
pack_as_float(extend_mode as u32),
stretch_size.width,
stretch_size.height,
0.0,
]);
}
BrushKind::RadialGradient { stretch_size, center, start_radius, end_radius, ratio_xy, extend_mode, .. } => {
request.push([
center.x,
center.y,
start_radius,
end_radius,
]);
request.push([
ratio_xy,
pack_as_float(extend_mode as u32),
stretch_size.width,
stretch_size.height,
]);
if let Some(mut request) = gpu_cache.request(&mut self.gpu_location) {
// has to match VECS_PER_SPECIFIC_BRUSH
match self.kind {
BrushKind::Border { .. } => {
// Border primitives currently used for
// image borders, and run through the
// normal brush_image shader.
request.push(PremultipliedColorF::WHITE);
request.push(PremultipliedColorF::WHITE);
request.push([
local_rect.size.width,
local_rect.size.height,
0.0,
0.0,
]);
}
BrushKind::YuvImage { color_depth, .. } => {
request.push([
color_depth.rescaling_factor(),
0.0,
0.0,
0.0
]);
}
// Images are drawn as a white color, modulated by the total
// opacity coming from any collapsed property bindings.
BrushKind::Image { stretch_size, tile_spacing, color, .. } => {
request.push(color.premultiplied());
request.push(PremultipliedColorF::WHITE);
request.push([
stretch_size.width + tile_spacing.width,
stretch_size.height + tile_spacing.height,
0.0,
0.0,
]);
}
// Solid rects also support opacity collapsing.
BrushKind::Solid { ref color, .. } => {
request.push(color.premultiplied());
}
BrushKind::LinearGradient { stretch_size, start_point, end_point, extend_mode, .. } => {
request.push([
start_point.x,
start_point.y,
end_point.x,
end_point.y,
]);
request.push([
pack_as_float(extend_mode as u32),
stretch_size.width,
stretch_size.height,
0.0,
]);
}
BrushKind::RadialGradient { stretch_size, center, start_radius, end_radius, ratio_xy, extend_mode, .. } => {
request.push([
center.x,
center.y,
start_radius,
end_radius,
]);
request.push([
ratio_xy,
pack_as_float(extend_mode as u32),
stretch_size.width,
stretch_size.height,
]);
}
}

match self.segment_desc {
Some(ref segment_desc) => {
for segment in &segment_desc.segments {
// has to match VECS_PER_SEGMENT
request.write_segment(
segment.local_rect,
segment.extra_data,
);
}
}
None => {
request.write_segment(
local_rect,
[0.0; 4],
);
}
}
}
}
Expand Down Expand Up @@ -1854,13 +1876,6 @@ pub struct PrimitiveInstance {
/// a list of clip task ids (one per segment).
pub clip_task_index: ClipTaskIndex,

/// The main GPU cache handle that this primitive uses to
/// store data accessible to shaders. This should be moved
/// into the interned data in order to retain this between
/// display list changes, but needs to be split into shared
/// and per-instance data.
pub gpu_location: GpuCacheHandle,

/// ID of the clip chain that this primitive is clipped by.
pub clip_chain_id: ClipChainId,

Expand All @@ -1887,7 +1902,6 @@ impl PrimitiveInstance {
prepared_frame_id: FrameId::INVALID,
#[cfg(debug_assertions)]
id: PrimitiveDebugId(NEXT_PRIM_ID.fetch_add(1, Ordering::Relaxed)),
gpu_location: GpuCacheHandle::new(),
clip_task_index: ClipTaskIndex::INVALID,
clip_chain_id,
spatial_node_index,
Expand Down Expand Up @@ -2195,10 +2209,7 @@ impl PrimitiveStore {
frame_state,
);

if local_rect_changed {
frame_state.gpu_cache.invalidate(&mut prim_instance.gpu_location);
pic_state.local_rect_changed = true;
}
pic_state.local_rect_changed |= local_rect_changed;

(is_passthrough, clip_node_collector)
}
Expand Down Expand Up @@ -2370,7 +2381,7 @@ impl PrimitiveStore {
prim_instance.clipped_world_rect = None;
}

if let Some(mut request) = frame_state.gpu_cache.request(&mut prim_instance.gpu_location) {
if let Some(mut request) = frame_state.gpu_cache.request(&mut pic.gpu_location) {
request.push(PremultipliedColorF::WHITE);
request.push(PremultipliedColorF::WHITE);
request.push([
Expand Down Expand Up @@ -3458,33 +3469,12 @@ impl PrimitiveInstance {
}

// Mark this GPU resource as required for this frame.
let is_chased = self.is_chased();
if let Some(mut request) = frame_state.gpu_cache.request(&mut self.gpu_location) {
match *prim_details {
PrimitiveDetails::Brush(ref mut brush) => {
brush.write_gpu_blocks(&mut request, prim_local_rect);

match brush.segment_desc {
Some(ref segment_desc) => {
for segment in &segment_desc.segments {
if is_chased {
println!("\t\t{:?}", segment);
}
// has to match VECS_PER_SEGMENT
request.write_segment(
segment.local_rect,
segment.extra_data,
);
}
}
None => {
request.write_segment(
prim_local_rect,
[0.0; 4],
);
}
}
}
match *prim_details {
PrimitiveDetails::Brush(ref mut brush) => {
brush.write_gpu_blocks_if_required(
prim_local_rect,
frame_state.gpu_cache,
);
}
}
}
Expand Down

0 comments on commit 6599760

Please sign in to comment.