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

Clip stack collapse path #595

Merged
merged 5 commits into from Nov 28, 2016

Extended clip batcher to combine the first clear+rect into a single c…

…all.

Fixed the needs_clipping flag to avoid blending where not necessary.
  • Loading branch information
kvark committed Nov 28, 2016
commit 4e2e8b7c1e43ed29a52439e6f1424ce7395e802a
@@ -1187,6 +1187,17 @@ impl Renderer {
max_prim_items,
&projection);
}
// the fast path for clear + rect, which is just the rectangle without blending
if !target.clip_batcher.rectangles_noblend.is_empty() {
let shader = self.cs_clip_rectangle.get(&mut self.device);
let max_prim_items = self.max_clip_instances;
self.draw_ubo_batch(&target.clip_batcher.rectangles_noblend,
shader,
1,
&BatchTextures::no_texture(),
max_prim_items,
&projection);
}
// now switch to multiplicative blending
self.device.set_blend(true);
self.device.set_blend_mode_multiply();
@@ -539,7 +539,8 @@ impl AlphaBatcher {
let layer = &ctx.layer_store[sc_index.0];
let prim_metadata = ctx.prim_store.get_metadata(prim_index);
let transform_kind = layer.xf_rect.as_ref().unwrap().kind;
let needs_clipping = prim_metadata.clip_cache_info.is_some() || true; //TODO
let needs_clipping = prim_metadata.clip_cache_info.is_some() ||
ctx.layer_masks_tasks.get(&(task.tile_id, sc_index)).is_some();
let needs_blending = transform_kind == TransformedRectKind::Complex ||
!prim_metadata.is_opaque ||
needs_clipping;
@@ -634,6 +635,8 @@ pub struct ClipBatcher {
pub clears: Vec<CacheClipInstance>,
/// Copy draws get the existing mask from a parent layer.
pub copies: Vec<CacheClipInstance>,
/// A fast path for masks that only have clear + rectangle.
pub rectangles_noblend: Vec<CacheClipInstance>,
/// Rectangle draws fill up the rectangles with rounded corners.
pub rectangles: Vec<CacheClipInstance>,
/// Image draws apply the image masking.
@@ -645,6 +648,7 @@ impl ClipBatcher {
ClipBatcher {
clears: Vec::new(),
copies: Vec::new(),
rectangles_noblend: Vec::new(),
rectangles: Vec::new(),
images: HashMap::new(),
}
@@ -656,6 +660,7 @@ impl ClipBatcher {
key: &MaskCacheKey,
image: Option<SourceTexture>) {

let mut start_rect_id = 0;
// TODO: don't draw clipping instances covering the whole tile
if let Some(layer_task_id) = base_task_index {
self.copies.push(CacheClipInstance {
@@ -664,6 +669,16 @@ impl ClipBatcher {
address: GpuStoreAddress(0),
base_task_id: layer_task_id.0 as i32,
});
} else if key.clip_range.item_count > 0 {
// draw the first rectangle without blending in order
// to avoid clearing the area first
start_rect_id = 1;
self.rectangles_noblend.push(CacheClipInstance {
task_id: task_index.0 as i32,
layer_index: key.layer_id.0 as i32,
address: key.clip_range.start,
base_task_id: 0,
})
} else {
self.clears.push(CacheClipInstance {
task_id: task_index.0 as i32,
@@ -673,7 +688,7 @@ impl ClipBatcher {
});
}

self.rectangles.extend((0 .. key.clip_range.item_count as usize)
self.rectangles.extend((start_rect_id .. key.clip_range.item_count as usize)
.map(|region_id| {
let offset = key.clip_range.start.0 + ((CLIP_DATA_GPU_SIZE * region_id) as i32);
CacheClipInstance {
@@ -1041,7 +1056,7 @@ impl RenderTask {

fn new_mask(actual_rect: DeviceIntRect,
cache_info: &MaskCacheInfo,
dependant: Option<&RenderTask>,
dependent: Option<&RenderTask>,
tile_id: TileUniqueId)
-> MaskResult {
let task_rect = match actual_rect.intersection(&cache_info.outer_rect) {
@@ -1051,15 +1066,15 @@ impl RenderTask {
};
MaskResult::Inside(RenderTask {
id: RenderTaskId::Dynamic(RenderTaskKey::CacheMask(cache_info.key, tile_id)),
children: match dependant {
children: match dependent {
Some(task) => vec![task.clone()],
None => Vec::new(),
},
location: RenderTaskLocation::Dynamic(None, task_rect.size),
kind: RenderTaskKind::CacheMask(CacheMaskTask {
actual_rect: task_rect,
image: cache_info.image.map(|mask| mask.image),
base_task_id: dependant.map(|task| task.id),
base_task_id: dependent.map(|task| task.id),
}),
})
}
ProTip! Use n and p to navigate between commits in a pull request.
You can’t perform that action at this time.