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

Optimizations to filter effects, blend targets, and batching. #461

Merged
merged 2 commits into from Oct 24, 2016
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

Optimizations to filter effects, blend targets, and batching.

* Switch all filter effects to run through the single source blend shader, instead of composite shader.
* Each render target uses a single alpha batcher now that the batching algorithm is reasonably efficient.
* Change tile size to 256x256. This seems to be a better tradeoff for GPU vs CPU time on all sites I tried.
* Switch blend targets to only allocate the used rect, rather than the entire tile size rect.

Closes #423.
  • Loading branch information
gw3583 committed Oct 24, 2016
commit 15ebf8ffcd65d8ec4610360a8c5bf9d10a168f53
@@ -120,17 +120,17 @@ Layer fetch_layer(int index) {
}

struct Tile {
vec4 actual_rect;
vec4 target_rect;
vec4 screen_origin_task_origin;
vec4 size;
};

Tile fetch_tile(int index) {
Tile tile;

ivec2 uv = get_fetch_uv(index, VECS_PER_TILE);

tile.actual_rect = texelFetchOffset(sRenderTasks, uv, 0, ivec2(0, 0));
tile.target_rect = texelFetchOffset(sRenderTasks, uv, 0, ivec2(1, 0));
tile.screen_origin_task_origin = texelFetchOffset(sRenderTasks, uv, 0, ivec2(0, 0));
tile.size = texelFetchOffset(sRenderTasks, uv, 0, ivec2(1, 0));

return tile;
}
@@ -406,13 +406,13 @@ VertexInfo write_vertex(vec4 instance_rect,
vec2 device_pos = world_pos.xy * uDevicePixelRatio;

vec2 clamped_pos = clamp(device_pos,
vec2(tile.actual_rect.xy),
vec2(tile.actual_rect.xy + tile.actual_rect.zw));
vec2(tile.screen_origin_task_origin.xy),
vec2(tile.screen_origin_task_origin.xy + tile.size.xy));

vec4 local_clamped_pos = layer.inv_transform * vec4(clamped_pos / uDevicePixelRatio, world_pos.z, 1);
local_clamped_pos.xyz /= local_clamped_pos.w;

vec2 final_pos = clamped_pos + vec2(tile.target_rect.xy) - vec2(tile.actual_rect.xy);
vec2 final_pos = clamped_pos + vec2(tile.screen_origin_task_origin.zw) - vec2(tile.screen_origin_task_origin.xy);

gl_Position = uTransform * vec4(final_pos, 0, 1);

@@ -460,20 +460,20 @@ TransformVertexInfo write_transform_vertex(vec4 instance_rect,
vec2 max_pos = max(tp0.xy, max(tp1.xy, max(tp2.xy, tp3.xy)));

vec2 min_pos_clamped = clamp(min_pos * uDevicePixelRatio,
vec2(tile.actual_rect.xy),
vec2(tile.actual_rect.xy + tile.actual_rect.zw));
vec2(tile.screen_origin_task_origin.xy),
vec2(tile.screen_origin_task_origin.xy + tile.size.xy));

vec2 max_pos_clamped = clamp(max_pos * uDevicePixelRatio,
vec2(tile.actual_rect.xy),
vec2(tile.actual_rect.xy + tile.actual_rect.zw));
vec2(tile.screen_origin_task_origin.xy),
vec2(tile.screen_origin_task_origin.xy + tile.size.xy));

vec2 clamped_pos = mix(min_pos_clamped,
max_pos_clamped,
aPosition.xy);

vec3 layer_pos = get_layer_pos(clamped_pos / uDevicePixelRatio, layer);

vec2 final_pos = clamped_pos + vec2(tile.target_rect.xy) - vec2(tile.actual_rect.xy);
vec2 final_pos = clamped_pos + vec2(tile.screen_origin_task_origin.zw) - vec2(tile.screen_origin_task_origin.xy);

gl_Position = uTransform * vec4(final_pos, 0, 1);

@@ -550,30 +550,28 @@ BoxShadow fetch_boxshadow(int index) {
}

struct Blend {
ivec4 src_id_target_id_opacity;
ivec4 src_id_target_id_op_amount;
};

Blend fetch_blend(int index) {
Blend blend;

int offset = index * 1;
blend.src_id_target_id_opacity = int_data[offset + 0];
blend.src_id_target_id_op_amount = int_data[offset + 0];

return blend;
}

struct Composite {
ivec4 src0_src1_target_id;
ivec4 info_amount;
ivec4 src0_src1_target_id_op;
};

Composite fetch_composite(int index) {
Composite composite;

int offset = index * 2;
int offset = index * 1;

composite.src0_src1_target_id = int_data[offset + 0];
composite.info_amount = int_data[offset + 1];
composite.src0_src1_target_id_op = int_data[offset + 0];

return composite;
}
@@ -4,7 +4,134 @@

uniform sampler2D sCache;

vec3 rgbToHsv(vec3 c) {
float value = max(max(c.r, c.g), c.b);

float chroma = value - min(min(c.r, c.g), c.b);
if (chroma == 0.0) {
return vec3(0.0);
}
float saturation = chroma / value;

float hue;
if (c.r == value)
hue = (c.g - c.b) / chroma;
else if (c.g == value)
hue = 2.0 + (c.b - c.r) / chroma;
else // if (c.b == value)
hue = 4.0 + (c.r - c.g) / chroma;

hue *= 1.0/6.0;
if (hue < 0.0)
hue += 1.0;
return vec3(hue, saturation, value);
}

vec3 hsvToRgb(vec3 c) {
if (c.s == 0.0) {
return vec3(c.z);
}

float hue = c.x * 6.0;
int sector = int(hue);
float residualHue = hue - float(sector);

vec3 pqt = c.z * vec3(1.0 - c.y, 1.0 - c.y * residualHue, 1.0 - c.y * (1.0 - residualHue));
if (sector == 0)
return vec3(c.z, pqt.z, pqt.x);
if (sector == 1)
return vec3(pqt.y, c.z, pqt.x);
if (sector == 2)
return vec3(pqt.x, c.z, pqt.z);
if (sector == 3)
return vec3(pqt.x, pqt.y, c.z);
if (sector == 4)
return vec3(pqt.z, pqt.x, c.z);
return vec3(c.z, pqt.x, pqt.y);
}

vec4 Blur(float radius, vec2 direction) {
// TODO(gw): Support blur in WR2!
return vec4(1, 1, 1, 1);
}

vec4 Contrast(vec4 Cs, float amount) {
return vec4(Cs.rgb * amount - 0.5 * amount + 0.5, 1.0);
}

vec4 Grayscale(vec4 Cs, float amount) {
float ia = 1.0 - amount;
return mat4(vec4(0.2126 + 0.7874 * ia, 0.2126 - 0.2126 * ia, 0.2126 - 0.2126 * ia, 0.0),
vec4(0.7152 - 0.7152 * ia, 0.7152 + 0.2848 * ia, 0.7152 - 0.7152 * ia, 0.0),
vec4(0.0722 - 0.0722 * ia, 0.0722 - 0.0722 * ia, 0.0722 + 0.9278 * ia, 0.0),
vec4(0.0, 0.0, 0.0, 1.0)) * Cs;
}

vec4 HueRotate(vec4 Cs, float amount) {
vec3 CsHsv = rgbToHsv(Cs.rgb);
CsHsv.x = mod(CsHsv.x + amount / 6.283185307179586, 1.0);
return vec4(hsvToRgb(CsHsv), Cs.a);
}

vec4 Invert(vec4 Cs, float amount) {
return mix(Cs, vec4(1.0, 1.0, 1.0, Cs.a) - vec4(Cs.rgb, 0.0), amount);
}

vec4 Saturate(vec4 Cs, float amount) {
return vec4(hsvToRgb(min(vec3(1.0, amount, 1.0) * rgbToHsv(Cs.rgb), vec3(1.0))), Cs.a);
}

vec4 Sepia(vec4 Cs, float amount) {
float ia = 1.0 - amount;
return mat4(vec4(0.393 + 0.607 * ia, 0.349 - 0.349 * ia, 0.272 - 0.272 * ia, 0.0),
vec4(0.769 - 0.769 * ia, 0.686 + 0.314 * ia, 0.534 - 0.534 * ia, 0.0),
vec4(0.189 - 0.189 * ia, 0.168 - 0.168 * ia, 0.131 + 0.869 * ia, 0.0),
vec4(0.0, 0.0, 0.0, 1.0)) * Cs;
}

vec4 Brightness(vec4 Cs, float amount) {
return vec4(Cs.rgb * amount, Cs.a);
}

vec4 Opacity(vec4 Cs, float amount) {
return vec4(Cs.rgb, Cs.a * amount);
}

void main(void) {
vec4 color = texture(sCache, vUv);
oFragColor = vec4(color.rgb * vBrightnessOpacity.x, color.a * vBrightnessOpacity.y);
vec4 Cs = texture(sCache, vUv);

if (Cs.a == 0.0) {
discard;
}

switch (vOp) {
case 0:
// Gaussian blur is specially handled:
oFragColor = Cs;// Blur(vAmount, vec2(0,0));
break;
case 1:
oFragColor = Contrast(Cs, vAmount);
break;
case 2:
oFragColor = Grayscale(Cs, vAmount);
break;
case 3:
oFragColor = HueRotate(Cs, vAmount);
break;
case 4:
oFragColor = Invert(Cs, vAmount);
break;
case 5:
oFragColor = Saturate(Cs, vAmount);
break;
case 6:
oFragColor = Sepia(Cs, vAmount);
break;
case 7:
oFragColor = Brightness(Cs, vAmount);
break;
case 8:
oFragColor = Opacity(Cs, vAmount);
break;
}
}
@@ -3,4 +3,5 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */

varying vec2 vUv;
varying vec2 vBrightnessOpacity;
flat varying float vAmount;
flat varying int vOp;
@@ -5,17 +5,23 @@

void main(void) {
Blend blend = fetch_blend(gl_InstanceID);
Tile src = fetch_tile(blend.src_id_target_id_opacity.x);
Tile dest = fetch_tile(blend.src_id_target_id_opacity.y);
Tile src = fetch_tile(blend.src_id_target_id_op_amount.x);
Tile dest = fetch_tile(blend.src_id_target_id_op_amount.y);

vec2 local_pos = mix(vec2(dest.target_rect.xy),
vec2(dest.target_rect.xy + dest.target_rect.zw),
vec2 dest_origin = dest.screen_origin_task_origin.zw -
dest.screen_origin_task_origin.xy +
src.screen_origin_task_origin.xy;

vec2 local_pos = mix(dest_origin,
dest_origin + src.size.xy,
aPosition.xy);

vec2 st0 = vec2(src.target_rect.xy) / 2048.0;
vec2 st1 = vec2(src.target_rect.xy + src.target_rect.zw) / 2048.0;
vec2 st0 = vec2(src.screen_origin_task_origin.zw) / 2048.0;
vec2 st1 = vec2(src.screen_origin_task_origin.zw + src.size.xy) / 2048.0;
vUv = mix(st0, st1, aPosition.xy);
vBrightnessOpacity = blend.src_id_target_id_opacity.zw / 65535.0;

vOp = blend.src_id_target_id_op_amount.z;
vAmount = blend.src_id_target_id_op_amount.w / 65535.0;

gl_Position = uTransform * vec4(local_pos, 0, 1);
}
ProTip! Use n and p to navigate between commits in a pull request.
You can’t perform that action at this time.