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

Switch box-shadows to be a clip source instead of a picture. #2487

Merged
merged 2 commits into from Mar 7, 2018
Merged
Changes from 1 commit
Commits
File filter...
Filter file types
Jump to…
Jump to file
Failed to load files.

Always

Just for now

Next

Switch box-shadows to be a clip source instead of a picture.

In hindsight, drawing box-shadows as a picture was not a good
abstraction. Instead, we now treat them as a simple clip source
that writes to the primitive clip mask, and is applied to the
box-shadow primitive which is just a solid rectangle.

This has a number of benefits:
 * The code for inset box-shadows is significantly simpler.
 * We remove two shaders (brush_picture and brush_mask) completely.
 * We get better batching, since box-shadows are just a solid rect + clip mask.
 * When we start to cache clip masks, box-shadows will gain this automatically.
 * Both outset and inset box-shadows now correctly use segments, which makes inset shadows significantly faster than previously.
 * Since the code is abstracted from Picture, fixing up how we handle sub-pixel blur radii etc is easier.
  * This is not done in this PR, but is much simpler to do than it would have been previously.

Overview of specific changes:
 * Remove PictureKind::BoxShadow.
 * Add ClipMaskSource::BoxShadow.
 * Use segment rendering to minimize clip mask allocated size and pixels for all box-shadows.
 * Remove brush_picture and brush_mask_rounded_rect shader.
 * Remove scale_factor from blur task - no longer needed.
  * This makes possible some future work to fix up existing drop-shadow bugs.
 * Add cs_clip_box_shadow shader. Can probably be unified with cs_clip_image quite easily.
 * (Initial) support for local-space clip mask generation. Needed for future tasks related to rasterizing animated stacking contexts.
  • Loading branch information
gw3583 committed Mar 6, 2018
commit 81f55acd6bfe391aa2d768498b452856c5c47c2e

This file was deleted.

@@ -53,7 +53,15 @@ ClipVertexInfo write_clip_tile_vertex(RectWithSize local_clip_rect,
ClipArea area) {
vec2 actual_pos = area.screen_origin + aPosition.xy * area.common_data.task_rect.size;

vec4 node_pos = get_node_pos(actual_pos / uDevicePixelRatio, scroll_node);
vec4 node_pos;

// Select the local position, based on whether we are rasterizing this
// clip mask in local- or sccreen-space.
if (area.local_space) {
node_pos = vec4(actual_pos / uDevicePixelRatio, 0.0, 1.0);
} else {
node_pos = get_node_pos(actual_pos / uDevicePixelRatio, scroll_node);
}

// compute the point position inside the scroll node, in CSS space
vec2 vertex_pos = actual_pos +
@@ -24,7 +24,6 @@ in int aBlurDirection;
struct BlurTask {
RenderTaskCommonData common_data;
float blur_radius;
float scale_factor;
vec4 color;
};

@@ -34,7 +33,6 @@ BlurTask fetch_blur_task(int address) {
BlurTask task = BlurTask(
task_data.common_data,
task_data.data1.x,
task_data.data1.y,
task_data.data2
);

@@ -0,0 +1,82 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */

#include shared,prim_shared,clip_shared

varying vec3 vPos;
varying vec2 vUv;
flat varying vec4 vUvBounds;
flat varying float vLayer;
flat varying vec4 vEdge;
flat varying vec4 vUvBounds_NoClamp;
flat varying float vClipMode;

#ifdef WR_VERTEX_SHADER

struct BoxShadowData {
vec2 src_rect_size;
float clip_mode;
RectWithSize dest_rect;
};

BoxShadowData fetch_data(ivec2 address) {
vec4 data[2] = fetch_from_resource_cache_2_direct(address);
RectWithSize dest_rect = RectWithSize(data[1].xy, data[1].zw);
BoxShadowData bs_data = BoxShadowData(data[0].xy, data[0].z, dest_rect);
return bs_data;
}

void main(void) {
ClipMaskInstance cmi = fetch_clip_item();
ClipArea area = fetch_clip_area(cmi.render_task_address);
ClipScrollNode scroll_node = fetch_clip_scroll_node(cmi.scroll_node_id);
BoxShadowData bs_data = fetch_data(cmi.clip_data_address);
ImageResource res = fetch_image_resource_direct(cmi.resource_address);

ClipVertexInfo vi = write_clip_tile_vertex(bs_data.dest_rect,
scroll_node,
area);

vLayer = res.layer;
vPos = vi.local_pos;
vClipMode = bs_data.clip_mode;

vec2 uv0 = res.uv_rect.p0;
vec2 uv1 = res.uv_rect.p1;

vec2 texture_size = vec2(textureSize(sColor0, 0));
vec2 local_pos = vPos.xy / vPos.z;

vEdge.xy = vec2(0.5);
vEdge.zw = (bs_data.dest_rect.size / bs_data.src_rect_size) - vec2(0.5);
vUv = (local_pos - bs_data.dest_rect.p0) / bs_data.src_rect_size;

vUvBounds = vec4(uv0 + vec2(0.5), uv1 - vec2(0.5)) / texture_size.xyxy;
vUvBounds_NoClamp = vec4(uv0, uv1) / texture_size.xyxy;
}
#endif

#ifdef WR_FRAGMENT_SHADER
void main(void) {
vec2 local_pos = vPos.xy / vPos.z;

vec2 uv = clamp(vUv.xy, vec2(0.0), vEdge.xy);
uv += max(vec2(0.0), vUv.xy - vEdge.zw);

uv = mix(vUvBounds_NoClamp.xy, vUvBounds_NoClamp.zw, uv);
uv = clamp(uv, vUvBounds.xy, vUvBounds.zw);

float in_shadow_rect = point_inside_rect(
local_pos,
vLocalBounds.xy,
vLocalBounds.zw
);

float texel = TEX_SAMPLE(sColor0, vec3(uv, vLayer)).r;

float alpha = mix(texel, 1.0 - texel, vClipMode);

oFragColor = vec4(mix(vClipMode, alpha, in_shadow_rect));
}
#endif
@@ -259,7 +259,6 @@ RenderTaskCommonData fetch_render_task_common_data(int index) {

#define PIC_TYPE_IMAGE 1
#define PIC_TYPE_TEXT_SHADOW 2
#define PIC_TYPE_BOX_SHADOW 3

/*
The dynamic picture that this brush exists on. Right now, it
@@ -289,6 +288,7 @@ PictureTask fetch_picture_task(int address) {
struct ClipArea {
RenderTaskCommonData common_data;
vec2 screen_origin;
bool local_space;
};

ClipArea fetch_clip_area(int index) {
@@ -300,11 +300,13 @@ ClipArea fetch_clip_area(int index) {
0.0
);
area.screen_origin = vec2(0.0);
area.local_space = false;
} else {
RenderTaskData task_data = fetch_render_task_data(index);

area.common_data = task_data.common_data;
area.screen_origin = task_data.data1.xy;
area.local_space = task_data.data1.z == 0.0;
}

return area;
@@ -822,7 +824,7 @@ float do_clip() {
vec4(vClipMaskUv.xy, vClipMaskUvBounds.zw));
// check for the dummy bounds, which are given to the opaque objects
return vClipMaskUvBounds.xy == vClipMaskUvBounds.zw ? 1.0:
all(inside) ? texelFetch(sSharedCacheA8, ivec3(vClipMaskUv), 0).r : 0.0;
all(inside) ? texelFetch(sCacheA8, ivec3(vClipMaskUv), 0).r : 0.0;
}

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