Skip to content

Use segments when drawing clip masks, decouple from tiles. #696

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

Merged
merged 1 commit into from
Jan 10, 2017
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
55 changes: 46 additions & 9 deletions webrender/res/clip_shared.glsl
Original file line number Diff line number Diff line change
@@ -5,16 +5,22 @@

#ifdef WR_VERTEX_SHADER

#define SEGMENT_ALL 0
#define SEGMENT_CORNER_TL 1
#define SEGMENT_CORNER_TR 2
#define SEGMENT_CORNER_BL 3
#define SEGMENT_CORNER_BR 4

in int aClipRenderTaskIndex;
in int aClipLayerIndex;
in int aClipDataIndex;
in int aClipBaseTaskIndex;
in int aClipSegmentIndex;

struct CacheClipInstance {
int render_task_index;
int layer_index;
int data_index;
int base_task_index;
int segment_index;
};

CacheClipInstance fetch_clip_item(int index) {
@@ -23,7 +29,7 @@ CacheClipInstance fetch_clip_item(int index) {
cci.render_task_index = aClipRenderTaskIndex;
cci.layer_index = aClipLayerIndex;
cci.data_index = aClipDataIndex;
cci.base_task_index = aClipBaseTaskIndex;
cci.segment_index = aClipSegmentIndex;

return cci;
}
@@ -32,23 +38,54 @@ CacheClipInstance fetch_clip_item(int index) {
// which is the intersection of all clip instances of a given primitive
TransformVertexInfo write_clip_tile_vertex(vec4 local_clip_rect,
Layer layer,
ClipArea area) {
ClipArea area,
int segment_index) {
vec2 lp0_base = local_clip_rect.xy;
vec2 lp1_base = local_clip_rect.xy + local_clip_rect.zw;

vec2 lp0 = clamp_rect(lp0_base, layer.local_clip_rect);
vec2 lp1 = clamp_rect(lp1_base, layer.local_clip_rect);
vec4 clipped_local_rect = vec4(lp0, lp1 - lp0);

vec2 final_pos = mix(area.task_bounds.xy, area.task_bounds.zw, aPosition.xy);
vec2 outer_p0 = area.screen_origin_target_index.xy;
vec2 outer_p1 = outer_p0 + area.task_bounds.zw - area.task_bounds.xy;
vec2 inner_p0 = area.inner_rect.xy;
vec2 inner_p1 = area.inner_rect.zw;

vec2 p0, p1;
switch (segment_index) {
case SEGMENT_ALL:
p0 = outer_p0;
p1 = outer_p1;
break;
case SEGMENT_CORNER_TL:
p0 = outer_p0;
p1 = inner_p0;
break;
case SEGMENT_CORNER_BL:
p0 = vec2(outer_p0.x, outer_p1.y);
p1 = vec2(inner_p0.x, inner_p1.y);
break;
case SEGMENT_CORNER_TR:
p0 = vec2(outer_p1.x, outer_p1.y);
p1 = vec2(inner_p1.x, inner_p1.y);
break;
case SEGMENT_CORNER_BR:
p0 = vec2(outer_p1.x, outer_p0.y);
p1 = vec2(inner_p1.x, inner_p0.y);
break;
}

vec2 actual_pos = mix(p0, p1, aPosition.xy);

vec4 layer_pos = get_layer_pos(actual_pos / uDevicePixelRatio, layer);

// compute the point position in side the layer, in CSS space
vec2 clamped_pos = final_pos + area.screen_origin_target_index.xy - area.task_bounds.xy;
vec4 layer_pos = get_layer_pos(clamped_pos / uDevicePixelRatio, layer);
vec2 vertex_pos = actual_pos + area.task_bounds.xy - area.screen_origin_target_index.xy;

gl_Position = uTransform * vec4(final_pos, 0.0, 1);
gl_Position = uTransform * vec4(vertex_pos, 0.0, 1);

return TransformVertexInfo(layer_pos.xyw, clamped_pos, clipped_local_rect);
return TransformVertexInfo(layer_pos.xyw, actual_pos, clipped_local_rect);
}

#endif //WR_VERTEX_SHADER
8 changes: 0 additions & 8 deletions webrender/res/cs_clip_copy.fs.glsl

This file was deleted.

19 changes: 0 additions & 19 deletions webrender/res/cs_clip_copy.vs.glsl

This file was deleted.

3 changes: 2 additions & 1 deletion webrender/res/cs_clip_image.vs.glsl
Original file line number Diff line number Diff line change
@@ -28,7 +28,8 @@ void main(void) {

TransformVertexInfo vi = write_clip_tile_vertex(local_rect,
layer,
area);
area,
cci.segment_index);
vLocalRect = vi.clipped_local_rect;
vPos = vi.local_pos;

3 changes: 2 additions & 1 deletion webrender/res/cs_clip_rectangle.vs.glsl
Original file line number Diff line number Diff line change
@@ -65,7 +65,8 @@ void main(void) {

TransformVertexInfo vi = write_clip_tile_vertex(local_rect,
layer,
area);
area,
cci.segment_index);
vLocalRect = vi.clipped_local_rect;
vPos = vi.local_pos;

7 changes: 6 additions & 1 deletion webrender/res/prim_shared.glsl
Original file line number Diff line number Diff line change
@@ -38,7 +38,7 @@ varying vec3 vClipMaskUv;
#ifdef WR_VERTEX_SHADER

#define VECS_PER_LAYER 13
#define VECS_PER_RENDER_TASK 2
#define VECS_PER_RENDER_TASK 3
#define VECS_PER_PRIM_GEOM 2

#define GRADIENT_HORIZONTAL 0
@@ -128,6 +128,7 @@ Layer fetch_layer(int index) {
struct RenderTaskData {
vec4 data0;
vec4 data1;
vec4 data2;
};

RenderTaskData fetch_render_task(int index) {
@@ -137,6 +138,7 @@ RenderTaskData fetch_render_task(int index) {

task.data0 = texelFetchOffset(sRenderTasks, uv, 0, ivec2(0, 0));
task.data1 = texelFetchOffset(sRenderTasks, uv, 0, ivec2(1, 0));
task.data2 = texelFetchOffset(sRenderTasks, uv, 0, ivec2(2, 0));

return task;
}
@@ -159,6 +161,7 @@ Tile fetch_tile(int index) {
struct ClipArea {
vec4 task_bounds;
vec4 screen_origin_target_index;
vec4 inner_rect;
};

ClipArea fetch_clip_area(int index) {
@@ -167,10 +170,12 @@ ClipArea fetch_clip_area(int index) {
if (index == 0x7FFFFFFF) { //special sentinel task index
area.task_bounds = vec4(0.0, 0.0, 0.0, 0.0);
area.screen_origin_target_index = vec4(0.0, 0.0, 0.0, 0.0);
area.inner_rect = vec4(0.0);
} else {
RenderTaskData task = fetch_render_task(index);
area.task_bounds = task.data0;
area.screen_origin_target_index = task.data1;
area.inner_rect = task.data2;
}

return area;
4 changes: 2 additions & 2 deletions webrender/src/device.rs
Original file line number Diff line number Diff line change
@@ -268,7 +268,7 @@ impl VertexFormat {
for (i, &attrib) in [ClipAttribute::RenderTaskIndex,
ClipAttribute::LayerIndex,
ClipAttribute::DataIndex,
ClipAttribute::BaseTaskIndex,
ClipAttribute::SegmentIndex,
].into_iter().enumerate() {
gl::enable_vertex_attrib_array(attrib as gl::GLuint);
gl::vertex_attrib_divisor(attrib as gl::GLuint, 1);
@@ -401,7 +401,7 @@ impl Program {
gl::bind_attrib_location(self.id, ClipAttribute::RenderTaskIndex as gl::GLuint, "aClipRenderTaskIndex");
gl::bind_attrib_location(self.id, ClipAttribute::LayerIndex as gl::GLuint, "aClipLayerIndex");
gl::bind_attrib_location(self.id, ClipAttribute::DataIndex as gl::GLuint, "aClipDataIndex");
gl::bind_attrib_location(self.id, ClipAttribute::BaseTaskIndex as gl::GLuint, "aClipBaseTaskIndex");
gl::bind_attrib_location(self.id, ClipAttribute::SegmentIndex as gl::GLuint, "aClipSegmentIndex");

gl::link_program(self.id);
if gl::get_program_iv(self.id, gl::LINK_STATUS) == (0 as gl::GLint) {
2 changes: 1 addition & 1 deletion webrender/src/internal_types.rs
Original file line number Diff line number Diff line change
@@ -266,7 +266,7 @@ pub enum ClipAttribute {
RenderTaskIndex,
LayerIndex,
DataIndex,
BaseTaskIndex,
SegmentIndex,
}

#[derive(Debug, Clone, Copy)]
8 changes: 8 additions & 0 deletions webrender/src/prim_store.rs
Original file line number Diff line number Diff line change
@@ -112,6 +112,7 @@ pub struct PrimitiveMetadata {
// that implements a 2-pass separable blur on a
// text run.
pub render_task: Option<RenderTask>,
pub clip_task: Option<RenderTask>,
}

#[derive(Debug, Clone)]
@@ -490,6 +491,7 @@ impl PrimitiveStore {
gpu_data_address: GpuStoreAddress(0),
gpu_data_count: 0,
render_task: None,
clip_task: None,
};

metadata
@@ -509,6 +511,7 @@ impl PrimitiveStore {
gpu_data_address: gpu_glyphs_address,
gpu_data_count: text_cpu.glyph_range.length as i32,
render_task: None,
clip_task: None,
};

self.cpu_text_runs.push(text_cpu);
@@ -529,6 +532,7 @@ impl PrimitiveStore {
gpu_data_address: GpuStoreAddress(0),
gpu_data_count: 0,
render_task: None,
clip_task: None,
};

self.cpu_images.push(image_cpu);
@@ -547,6 +551,7 @@ impl PrimitiveStore {
gpu_data_address: GpuStoreAddress(0),
gpu_data_count: 0,
render_task: None,
clip_task: None,
};

self.cpu_yuv_images.push(image_cpu);
@@ -565,6 +570,7 @@ impl PrimitiveStore {
gpu_data_address: GpuStoreAddress(0),
gpu_data_count: 0,
render_task: None,
clip_task: None,
};

self.cpu_borders.push(border_cpu);
@@ -584,6 +590,7 @@ impl PrimitiveStore {
gpu_data_address: gpu_stops_address,
gpu_data_count: gradient_cpu.stops_range.length as i32,
render_task: None,
clip_task: None,
};

self.cpu_gradients.push(gradient_cpu);
@@ -628,6 +635,7 @@ impl PrimitiveStore {
gpu_data_address: gpu_data_address,
gpu_data_count: instance_rects.len() as i32,
render_task: Some(render_task),
clip_task: None,
};

for rect in instance_rects {
21 changes: 2 additions & 19 deletions webrender/src/renderer.rs
Original file line number Diff line number Diff line change
@@ -288,7 +288,6 @@ pub struct Renderer {
/// These are "cache clip shaders". These shaders are used to
/// draw clip instances into the cached clip mask. The results
/// of these shaders are also used by the primitive shaders.
cs_clip_copy: LazilyCompiledShader,
cs_clip_rectangle: LazilyCompiledShader,
cs_clip_image: LazilyCompiledShader,

@@ -421,11 +420,6 @@ impl Renderer {
&mut device,
options.precache_shaders);

let cs_clip_copy = LazilyCompiledShader::new(ShaderKind::ClipCache,
"cs_clip_copy",
&[],
&mut device,
options.precache_shaders);
let cs_clip_rectangle = LazilyCompiledShader::new(ShaderKind::ClipCache,
"cs_clip_rectangle",
&[],
@@ -619,7 +613,6 @@ impl Renderer {
cs_box_shadow: cs_box_shadow,
cs_text_run: cs_text_run,
cs_blur: cs_blur,
cs_clip_copy: cs_clip_copy,
cs_clip_rectangle: cs_clip_rectangle,
cs_clip_image: cs_clip_image,
ps_rectangle: ps_rectangle,
@@ -1060,7 +1053,7 @@ impl Renderer {
// tasks can assume that pixels are transparent if not
// rendered. (This is relied on by the compositing support
// for mix-blend-mode etc).
[1.0, 0.0, 0.0, 0.0],
[1.0, 1.0, 1.0, 0.0],
Matrix4D::ortho(0.0,
target_size.width,
0.0,
@@ -1137,17 +1130,7 @@ impl Renderer {
{
let _gm = self.gpu_profile.add_marker(GPU_TAG_CACHE_CLIP);
let vao = self.clip_vao_id;
// Optionally, copy the contents from another task
if !target.clip_batcher.copies.is_empty() {
self.device.set_blend(false);
let shader = self.cs_clip_copy.get(&mut self.device);
self.draw_instanced_batch(&target.clip_batcher.copies,
vao,
shader,
&BatchTextures::no_texture(),
&projection);
}
// now switch to multiplicative blending
// switch to multiplicative blending
self.device.set_blend(true);
self.device.set_blend_mode_multiply();
// draw rounded cornered rectangles
3 changes: 1 addition & 2 deletions webrender/src/scene.rs
Original file line number Diff line number Diff line change
@@ -7,8 +7,7 @@ use std::collections::HashMap;
use std::hash::BuildHasherDefault;
use tiling::AuxiliaryListsMap;
use webrender_traits::{AuxiliaryLists, BuiltDisplayList, PipelineId, Epoch, ColorF};
use webrender_traits::{DisplayItem, SpecificDisplayItem, StackingContext};
use webrender_traits::LayerSize;
use webrender_traits::{DisplayItem, LayerSize};

/// A representation of the layout within the display port for a given document or iframe.
#[derive(Debug)]
Loading