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

Correctly handle blend primitives, where the contents are clipped. #2477

Merged
merged 1 commit into from Feb 28, 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

Correctly handle blend primitives, where the contents are clipped.

In some situations, the items within a filter stacking context will
have clips applied. In this case, we minimize the allocated size
of the intermediate surface, to avoid drawing redundant information
that won't be seen.

However, if the stacking context itself does not have the same clip
applied, then we need to ensure that when we draw the blend primitive,
we don't sample outside the smaller region of the intermediate
surface that was rendered.

Ideally, the stacking context should have a clip applied to it so
that we don't waste time drawing transparent pixels. Adding a clip
to the stacking context here would provide an optimization win in
many cases. However, even without one present, we should still
ensure correct rendering, thus this fix is required.

Also fix a case where brush primitives with segments were not setting
the correct bounding rect for a render task. This wasn't causing a
problem here, but may have caused other issues.
  • Loading branch information
gw3583 committed Feb 28, 2018
commit 69814e7c0e2f4d3e9c899f912f053a8b71413368
@@ -13,6 +13,7 @@ flat varying float vAmount;
flat varying int vOp;
flat varying mat4 vColorMat;
flat varying vec4 vColorOffset;
flat varying vec4 vUvClipBounds;

#ifdef WR_VERTEX_SHADER

@@ -30,6 +31,10 @@ void brush_vs(
src_task.content_origin;
vUv = vec3(uv / texture_size, src_task.common_data.texture_layer_index);

vec2 uv0 = src_task.common_data.task_rect.p0;
vec2 uv1 = uv0 + src_task.common_data.task_rect.size;
vUvClipBounds = vec4(uv0, uv1) / texture_size.xyxy;

vOp = user_data.y;

float lumR = 0.2126;
@@ -142,6 +147,10 @@ vec4 brush_fs() {
color = vColorMat * Cs + vColorOffset;
}

// Fail-safe to ensure that we don't sample outside the rendered
// portion of a blend source.
color.a *= point_inside_rect(vUv.xy, vUvClipBounds.xy, vUvClipBounds.zw);

// Pre-multiply the alpha into the output value.
color.rgb *= color.a;

@@ -46,3 +46,8 @@ bool rect_inside_rect(RectWithSize little, RectWithSize big) {
return all(lessThanEqual(vec4(big.p0, little.p0 + little.size),
vec4(little.p0, big.p0 + big.size)));
}

float point_inside_rect(vec2 p, vec2 p0, vec2 p1) {
vec2 s = step(p0, p) - step(p1, p);
return s.x * s.y;
}
@@ -301,12 +301,19 @@ impl BatchList {
}
}

fn add_bounding_rect(
&mut self,
task_relative_bounding_rect: &DeviceIntRect,
) {
self.combined_bounding_rect = self.combined_bounding_rect.union(task_relative_bounding_rect);
}

pub fn get_suitable_batch(
&mut self,
key: BatchKey,
task_relative_bounding_rect: &DeviceIntRect,
) -> &mut Vec<PrimitiveInstance> {
self.combined_bounding_rect = self.combined_bounding_rect.union(task_relative_bounding_rect);
self.add_bounding_rect(task_relative_bounding_rect);

match key.blend_mode {
BlendMode::None => {
@@ -1242,6 +1249,8 @@ impl AlphaBatchBuilder {
user_data,
};

self.batch_list.add_bounding_rect(task_relative_bounding_rect);

match brush.segment_desc {
Some(ref segment_desc) => {
let alpha_batch_key = BatchKey {
Binary file not shown.
@@ -0,0 +1,110 @@
---
root:
items:
-
type: "stacking-context"
items:
-
bounds: [0, 0, 1887, 2081]
"clip-rect": [0, 0, 1887, 2081]
"clip-and-scroll": 0
"backface-visible": true
type: clip
id: 1
"content-size": [1887, 2081]
-
bounds: [0, 111, 1887, 1970]
"clip-rect": [0, 111, 1887, 1970]
"clip-and-scroll": 0
"backface-visible": true
type: clip
id: 2
"content-size": [1887, 1970]
-
bounds: [0, 111, 1887, 1971]
"clip-rect": [0, 111, 1887, 1971]
"clip-and-scroll": 2
"backface-visible": true
type: iframe
id: [1, 3]
id: [1, 1]
pipelines:
-
id: [1, 3]
items:
-
type: "stacking-context"
items:
-
bounds: [0, 0, 1887, 1971]
"clip-rect": [0, 0, 1887, 1971]
"clip-and-scroll": 0
type: clip
id: 1
"content-size": [1887, 1971]
-
"clip-rect": [0, 0, 1887, 1971]
"clip-and-scroll": 1
type: "scroll-frame"
id: 2
"content-size": [1887, 1971]
bounds: [0, 0, 1887, 1971]
-
bounds: [0, 0, 1887, 1971]
"clip-rect": [0, 0, 1887, 1971]
"clip-and-scroll": 2
type: clip
id: 3
"content-size": [1887, 1971]
-
"clip-and-scroll": 3
type: "stacking-context"
items:
-
bounds: [0, -186, 1887, 239]
"clip-rect": [0, -186, 1887, 239]
"clip-and-scroll": 3
"backface-visible": true
type: clip
id: 4
"content-size": [1887, 239]
-
bounds: [-660.45, -186, 0, 0]
"clip-rect": [-660.45, -186, 0, 0]
"clip-and-scroll": 4
type: "stacking-context"
transform: [1, 0, 0, 0, -0.57735026, 1, 0, 0, 0, 0, 1, 0, 68.849, 0, 0, 1]
items:
-
"clip-and-scroll": 4
type: "stacking-context"
filters:
- opacity(0.8)
items:
-
bounds: [0, 0, 1887, 239]
"clip-rect": [0, 0, 1887, 239]
"clip-and-scroll": 4
type: clip
id: 5
"content-size": [1887, 239]
-
bounds: [0, 0, 1887, 239]
"clip-rect": [0, 0, 1887, 239]
"clip-and-scroll": 5
"backface-visible": true
type: gradient
start: [943.5, -0.00000000000005684342]
end: [943.5, 238.5]
"tile-size": [1887, 238.5]
"tile-spacing": [0, 0]
stops:
- 0
- 0 153 204.00002 1.0000
- 0.3
- 0 153 204.00002 1.0000
- 0.6
- 7.0000005 137 194.00002 1.0000
- 1
- 0 91 137 1.0000
repeat: false
@@ -32,3 +32,5 @@
== filter-long-chain.yaml filter-long-chain.png
== filter-drop-shadow.yaml filter-drop-shadow.png
== filter-drop-shadow-on-viewport-edge.yaml filter-drop-shadow-on-viewport-edge.png
== blend-clipped.yaml blend-clipped.png

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