Skip to content

Store clip node templates in local space. #3383

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

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
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
6 changes: 6 additions & 0 deletions webrender/res/clip_shared.glsl
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ in int aClipTransformId;
in int aPrimTransformId;
in int aClipSegment;
in ivec4 aClipDataResourceAddress;
in vec2 aClipLocalPos;
in vec4 aClipTileRect;

struct ClipMaskInstance {
int render_task_address;
Expand All @@ -25,6 +27,8 @@ struct ClipMaskInstance {
int segment;
ivec2 clip_data_address;
ivec2 resource_address;
vec2 local_pos;
RectWithSize tile_rect;
};

ClipMaskInstance fetch_clip_item() {
Expand All @@ -36,6 +40,8 @@ ClipMaskInstance fetch_clip_item() {
cmi.segment = aClipSegment;
cmi.clip_data_address = aClipDataResourceAddress.xy;
cmi.resource_address = aClipDataResourceAddress.zw;
cmi.local_pos = aClipLocalPos;
cmi.tile_rect = RectWithSize(aClipTileRect.xy, aClipTileRect.zw);

return cmi;
}
Expand Down
17 changes: 10 additions & 7 deletions webrender/res/cs_clip_box_shadow.glsl
Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,11 @@ void main(void) {
BoxShadowData bs_data = fetch_data(cmi.clip_data_address);
ImageResource res = fetch_image_resource_direct(cmi.resource_address);

RectWithSize dest_rect = bs_data.dest_rect;
dest_rect.p0 += cmi.local_pos;

ClipVertexInfo vi = write_clip_tile_vertex(
bs_data.dest_rect,
dest_rect,
prim_transform,
clip_transform,
area
Expand All @@ -65,29 +68,29 @@ void main(void) {
switch (bs_data.stretch_mode_x) {
case MODE_STRETCH: {
vEdge.x = 0.5;
vEdge.z = (bs_data.dest_rect.size.x / bs_data.src_rect_size.x) - 0.5;
vUv.x = (local_pos.x - bs_data.dest_rect.p0.x) / bs_data.src_rect_size.x;
vEdge.z = (dest_rect.size.x / bs_data.src_rect_size.x) - 0.5;
vUv.x = (local_pos.x - dest_rect.p0.x) / bs_data.src_rect_size.x;
break;
}
case MODE_SIMPLE:
default: {
vEdge.xz = vec2(1.0);
vUv.x = (local_pos.x - bs_data.dest_rect.p0.x) / bs_data.dest_rect.size.x;
vUv.x = (local_pos.x - dest_rect.p0.x) / dest_rect.size.x;
break;
}
}

switch (bs_data.stretch_mode_y) {
case MODE_STRETCH: {
vEdge.y = 0.5;
vEdge.w = (bs_data.dest_rect.size.y / bs_data.src_rect_size.y) - 0.5;
vUv.y = (local_pos.y - bs_data.dest_rect.p0.y) / bs_data.src_rect_size.y;
vEdge.w = (dest_rect.size.y / bs_data.src_rect_size.y) - 0.5;
vUv.y = (local_pos.y - dest_rect.p0.y) / bs_data.src_rect_size.y;
break;
}
case MODE_SIMPLE:
default: {
vEdge.yw = vec2(1.0);
vUv.y = (local_pos.y - bs_data.dest_rect.p0.y) / bs_data.dest_rect.size.y;
vUv.y = (local_pos.y - dest_rect.p0.y) / dest_rect.size.y;
break;
}
}
Expand Down
13 changes: 5 additions & 8 deletions webrender/res/cs_clip_image.glsl
Original file line number Diff line number Diff line change
Expand Up @@ -13,15 +13,12 @@ flat varying float vLayer;

#ifdef WR_VERTEX_SHADER
struct ImageMaskData {
RectWithSize local_mask_rect;
RectWithSize local_tile_rect;
vec2 local_mask_size;
};

ImageMaskData fetch_mask_data(ivec2 address) {
vec4 data[2] = fetch_from_gpu_cache_2_direct(address);
RectWithSize mask_rect = RectWithSize(data[0].xy, data[0].zw);
RectWithSize tile_rect = RectWithSize(data[1].xy, data[1].zw);
ImageMaskData mask_data = ImageMaskData(mask_rect, tile_rect);
vec4 data = fetch_from_gpu_cache_1_direct(address);
ImageMaskData mask_data = ImageMaskData(data.xy);
return mask_data;
}

Expand All @@ -31,7 +28,7 @@ void main(void) {
Transform clip_transform = fetch_transform(cmi.clip_transform_id);
Transform prim_transform = fetch_transform(cmi.prim_transform_id);
ImageMaskData mask = fetch_mask_data(cmi.clip_data_address);
RectWithSize local_rect = mask.local_mask_rect;
RectWithSize local_rect = RectWithSize(cmi.local_pos, mask.local_mask_size);
ImageResource res = fetch_image_resource_direct(cmi.resource_address);

ClipVertexInfo vi = write_clip_tile_vertex(
Expand All @@ -42,7 +39,7 @@ void main(void) {
);
vLocalPos = vi.local_pos.xy / vi.local_pos.z;
vLayer = res.layer;
vClipMaskImageUv = (vLocalPos - mask.local_tile_rect.p0) / mask.local_tile_rect.size;
vClipMaskImageUv = (vLocalPos - cmi.tile_rect.p0) / cmi.tile_rect.size;
vec2 texture_size = vec2(textureSize(sColor0, 0));
vClipMaskUvRect = vec4(res.uv_rect.p0, res.uv_rect.p1 - res.uv_rect.p0) / texture_size.xyxy;
// applying a half-texel offset to the UV boundaries to prevent linear samples from the outside
Expand Down
2 changes: 2 additions & 0 deletions webrender/res/cs_clip_rectangle.glsl
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,9 @@ void main(void) {
Transform clip_transform = fetch_transform(cmi.clip_transform_id);
Transform prim_transform = fetch_transform(cmi.prim_transform_id);
ClipData clip = fetch_clip(cmi.clip_data_address);

RectWithSize local_rect = clip.rect.rect;
local_rect.p0 = cmi.local_pos;

ClipVertexInfo vi = write_clip_tile_vertex(
local_rect,
Expand Down
27 changes: 18 additions & 9 deletions webrender/src/batch.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2442,6 +2442,7 @@ impl ClipBatcher {
&mut self,
task_address: RenderTaskAddress,
clip_data_address: GpuCacheAddress,
local_pos: LayoutPoint,
) {
let instance = ClipMaskInstance {
render_task_address: task_address,
Expand All @@ -2450,6 +2451,8 @@ impl ClipBatcher {
segment: 0,
clip_data_address,
resource_address: GpuCacheAddress::invalid(),
local_pos,
tile_rect: LayoutRect::zero(),
};

self.rectangles.push(instance);
Expand Down Expand Up @@ -2490,21 +2493,27 @@ impl ClipBatcher {
segment: 0,
clip_data_address: GpuCacheAddress::invalid(),
resource_address: GpuCacheAddress::invalid(),
local_pos: clip_instance.local_pos,
tile_rect: LayoutRect::zero(),
};

match clip_node.item {
ClipItem::Image { ref mask, ref visible_tiles } => {
ClipItem::Image { image, size, .. } => {
let request = ImageRequest {
key: mask.image,
key: image,
rendering: ImageRendering::Auto,
tile: None,
};
let mut add_image = |request: ImageRequest, clip_data_address: GpuCacheAddress| {

let clip_data_address =
gpu_cache.get_address(&clip_node.gpu_cache_handle);

let mut add_image = |request: ImageRequest, local_tile_rect: LayoutRect| {
let cache_item = match resource_cache.get_cached_image(request) {
Ok(item) => item,
Err(..) => {
warn!("Warnings: skip a image mask");
debug!("Mask: {:?}, request: {:?}", mask, request);
debug!("request: {:?}", request);
return;
}
};
Expand All @@ -2514,23 +2523,23 @@ impl ClipBatcher {
.push(ClipMaskInstance {
clip_data_address,
resource_address: gpu_cache.get_address(&cache_item.uv_rect_handle),
tile_rect: local_tile_rect,
..instance
});
};

match *visible_tiles {
match clip_instance.visible_tiles {
Some(ref tiles) => {
for tile in tiles {
add_image(
request.with_tile(tile.tile_offset),
gpu_cache.get_address(&tile.handle),
tile.tile_rect,
)
}
}
None => {
let gpu_address =
gpu_cache.get_address(&clip_node.gpu_cache_handle);
add_image(request, gpu_address)
let mask_rect = LayoutRect::new(clip_instance.local_pos, size);
add_image(request, mask_rect)
}
}
}
Expand Down
20 changes: 10 additions & 10 deletions webrender/src/border.rs
Original file line number Diff line number Diff line change
Expand Up @@ -171,7 +171,7 @@ pub struct BorderSegmentCacheKey {

pub fn ensure_no_corner_overlap(
radius: &mut BorderRadius,
rect: &LayoutRect,
size: LayoutSize,
) {
let mut ratio = 1.0;
let top_left_radius = &mut radius.top_left;
Expand All @@ -180,23 +180,23 @@ pub fn ensure_no_corner_overlap(
let bottom_left_radius = &mut radius.bottom_left;

let sum = top_left_radius.width + top_right_radius.width;
if rect.size.width < sum {
ratio = f32::min(ratio, rect.size.width / sum);
if size.width < sum {
ratio = f32::min(ratio, size.width / sum);
}

let sum = bottom_left_radius.width + bottom_right_radius.width;
if rect.size.width < sum {
ratio = f32::min(ratio, rect.size.width / sum);
if size.width < sum {
ratio = f32::min(ratio, size.width / sum);
}

let sum = top_left_radius.height + bottom_left_radius.height;
if rect.size.height < sum {
ratio = f32::min(ratio, rect.size.height / sum);
if size.height < sum {
ratio = f32::min(ratio, size.height / sum);
}

let sum = top_right_radius.height + bottom_right_radius.height;
if rect.size.height < sum {
ratio = f32::min(ratio, rect.size.height / sum);
if size.height < sum {
ratio = f32::min(ratio, size.height / sum);
}

if ratio < 1. {
Expand All @@ -223,7 +223,7 @@ impl<'a> DisplayListFlattener<'a> {
clip_and_scroll: ScrollNodeAndClipChain,
) {
let mut border = *border;
ensure_no_corner_overlap(&mut border.radius, &info.rect);
ensure_no_corner_overlap(&mut border.radius, info.rect.size);

self.add_primitive(
clip_and_scroll,
Expand Down
76 changes: 53 additions & 23 deletions webrender/src/box_shadow.rs
Original file line number Diff line number Diff line change
Expand Up @@ -117,32 +117,47 @@ impl<'a> DisplayListFlattener<'a> {
}

// TODO(gw): Add a fast path for ClipOut + zero border radius!
clips.push(ClipItemKey::rounded_rect(
prim_info.rect,
border_radius,
ClipMode::ClipOut,
));
clips.push(
(
prim_info.rect.origin,
ClipItemKey::rounded_rect(
prim_info.rect.size,
border_radius,
ClipMode::ClipOut,
),
)
);

(shadow_rect, shadow_radius)
}
BoxShadowClipMode::Inset => {
if shadow_rect.is_well_formed_and_nonempty() {
clips.push(ClipItemKey::rounded_rect(
shadow_rect,
shadow_radius,
ClipMode::ClipOut,
));
clips.push(
(
shadow_rect.origin,
ClipItemKey::rounded_rect(
shadow_rect.size,
shadow_radius,
ClipMode::ClipOut,
),
)
);
}

(prim_info.rect, border_radius)
}
};

clips.push(ClipItemKey::rounded_rect(
final_prim_rect,
clip_radius,
ClipMode::Clip,
));
clips.push(
(
final_prim_rect.origin,
ClipItemKey::rounded_rect(
final_prim_rect.size,
clip_radius,
ClipMode::Clip,
),
)
);

self.add_primitive(
clip_and_scroll,
Expand All @@ -159,11 +174,16 @@ impl<'a> DisplayListFlattener<'a> {

// Add a normal clip mask to clip out the contents
// of the surrounding primitive.
extra_clips.push(ClipItemKey::rounded_rect(
prim_info.rect,
border_radius,
prim_clip_mode,
));
extra_clips.push(
(
prim_info.rect.origin,
ClipItemKey::rounded_rect(
prim_info.rect.size,
border_radius,
prim_clip_mode,
),
)
);

// Get the local rect of where the shadow will be drawn,
// expanded to include room for the blurred region.
Expand All @@ -179,7 +199,7 @@ impl<'a> DisplayListFlattener<'a> {
let shadow_clip_source = ClipItemKey::box_shadow(
shadow_rect,
shadow_radius,
dest_rect,
dest_rect.translate(&LayoutVector2D::new(-prim_info.rect.origin.x, -prim_info.rect.origin.y)),
blur_radius,
clip_mode,
);
Expand All @@ -192,7 +212,12 @@ impl<'a> DisplayListFlattener<'a> {
}

// Add the box-shadow clip source.
extra_clips.push(shadow_clip_source);
extra_clips.push(
(
prim_info.rect.origin,
shadow_clip_source,
),
);

// Outset shadows are expanded by the shadow
// region from the original primitive.
Expand All @@ -212,7 +237,12 @@ impl<'a> DisplayListFlattener<'a> {
// inset shadow rect becomes invalid (they will
// just look like a solid rectangle).
if shadow_rect.is_well_formed_and_nonempty() {
extra_clips.push(shadow_clip_source);
extra_clips.push(
(
prim_info.rect.origin,
shadow_clip_source,
),
);
}

// Inset shadows draw inside the original primitive.
Expand Down
Loading