Skip to content

Commit

Permalink
Bug 1674396 - Implement SWGL fast-path for box shadows. r=jrmuizel
Browse files Browse the repository at this point in the history
This adds a span shader that tries to treat the box shadow as a nine-patch
and intersect with the various sectors of it. This allows committing entire
contiguous spans of texture from the source box shadow rather than doing
slower per-fragment processing.

Differential Revision: https://phabricator.services.mozilla.com/D115113

[ghsync] From https://hg.mozilla.org/mozilla-central/rev/ec2f0492da8aceb5f2fc68a4b12cd69215db80da
  • Loading branch information
lsalzman committed May 18, 2021
1 parent 1df4a3f commit 984512d
Show file tree
Hide file tree
Showing 7 changed files with 341 additions and 136 deletions.
201 changes: 81 additions & 120 deletions glsl-to-cxx/src/hir.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2337,18 +2337,28 @@ fn translate_expression(state: &mut State, e: &syntax::Expr) -> Expr {
}
match &state.sym(sym).decl {
SymDecl::NativeFunction(fn_ty, _, _) => {
// Search for a signature where all parameter types are
// compatible. If there are many compatible signatures,
// then choose the one with the most exact matches.
let mut ret = None;
for sig in &fn_ty.signatures {
let mut matching = true;
let mut best_score = 0;
'next_sig: for sig in &fn_ty.signatures {
let mut score = 0;
for (e, p) in params.iter().zip(sig.params.iter()) {
if !compatible_type(&e.ty, p) {
matching = false;
break;
if e.ty == *p {
score += 1;
} else if !compatible_type(&e.ty, p) {
continue 'next_sig;
}
}
if matching {
if score >= best_score {
ret = Some(sig.ret.clone());
break;
best_score = score;
// If all parameters match exactly, then there
// is no need to search for other matches.
if best_score >= params.len() {
break;
}
}
}
ret_ty = match ret {
Expand Down Expand Up @@ -3250,77 +3260,38 @@ pub fn ast_to_hir(state: &mut State, tu: &syntax::TranslationUnit) -> Translatio
Type::new(Float),
vec![Type::new(Vec2), Type::new(Vec2)],
);
declare_function(
state,
"min",
None,
Type::new(Float),
vec![Type::new(Float), Type::new(Float)],
);
declare_function(
state,
"min",
None,
Type::new(Vec2),
vec![Type::new(Vec2), Type::new(Vec2)],
);
declare_function(
state,
"min",
None,
Type::new(Vec2),
vec![Type::new(Vec2), Type::new(Float)],
);
declare_function(
state,
"min",
None,
Type::new(Vec3),
vec![Type::new(Vec3), Type::new(Vec3)],
);
declare_function(
state,
"min",
None,
Type::new(Vec3),
vec![Type::new(Vec3), Type::new(Float)],
);

declare_function(
state,
"max",
None,
Type::new(Float),
vec![Type::new(Float), Type::new(Float)],
);
declare_function(
state,
"max",
None,
Type::new(Vec2),
vec![Type::new(Vec2), Type::new(Vec2)],
);
declare_function(
state,
"max",
None,
Type::new(Vec2),
vec![Type::new(Vec2), Type::new(Float)],
);
declare_function(
state,
"max",
None,
Type::new(Vec3),
vec![Type::new(Vec3), Type::new(Vec3)],
);
declare_function(
state,
"max",
None,
Type::new(Vec3),
vec![Type::new(Vec3), Type::new(Float)],
);
for t in &[Vec2, Vec3, Vec4] {
declare_function(
state,
"min",
None,
Type::new(*t),
vec![Type::new(*t), Type::new(Float)],
);
declare_function(
state,
"max",
None,
Type::new(*t),
vec![Type::new(*t), Type::new(Float)],
);
}
for t in &[Int, Float, Vec2, Vec3, Vec4] {
declare_function(
state,
"min",
None,
Type::new(*t),
vec![Type::new(*t), Type::new(*t)],
);
declare_function(
state,
"max",
None,
Type::new(*t),
vec![Type::new(*t), Type::new(*t)],
);
}

declare_function(
state,
Expand Down Expand Up @@ -3465,48 +3436,24 @@ pub fn ast_to_hir(state: &mut State, tu: &syntax::TranslationUnit) -> Translatio
declare_function(state, "tan", None, Type::new(Float), vec![Type::new(Float)]);
declare_function(state, "atan", None, Type::new(Float), vec![Type::new(Float)]);
declare_function(state, "atan", None, Type::new(Float), vec![Type::new(Float), Type::new(Float)]);
declare_function(
state,
"clamp",
None,
Type::new(Vec3),
vec![Type::new(Vec3), Type::new(Float), Type::new(Float)],
);
declare_function(
state,
"clamp",
None,
Type::new(Float),
vec![Type::new(Float), Type::new(Float), Type::new(Float)],
);
declare_function(
state,
"clamp",
None,
Type::new(Vec2),
vec![Type::new(Vec2), Type::new(Vec2), Type::new(Vec2)],
);
declare_function(
state,
"clamp",
None,
Type::new(Vec3),
vec![Type::new(Vec3), Type::new(Vec3), Type::new(Vec3)],
);
declare_function(
state,
"clamp",
None,
Type::new(Vec4),
vec![Type::new(Vec4), Type::new(Vec4), Type::new(Vec4)],
);
declare_function(
state,
"clamp",
None,
Type::new(Vec4),
vec![Type::new(Vec4), Type::new(Float), Type::new(Float)],
);
for t in &[Vec2, Vec3, Vec4] {
declare_function(
state,
"clamp",
None,
Type::new(*t),
vec![Type::new(*t), Type::new(Float), Type::new(Float)],
);
}
for t in &[Float, Vec2, Vec3, Vec4] {
declare_function(
state,
"clamp",
None,
Type::new(*t),
vec![Type::new(*t), Type::new(*t), Type::new(*t)],
);
}
declare_function(
state,
"length",
Expand Down Expand Up @@ -3994,6 +3941,20 @@ pub fn ast_to_hir(state: &mut State, tu: &syntax::TranslationUnit) -> Translatio
Type::new(Void),
vec![Type::new(*s), Type::new(Vec2), Type::new(Vec4)],
);
declare_function(
state,
"swgl_commitPartialTextureLinearR8",
None,
Type::new(Void),
vec![Type::new(Int), Type::new(*s), Type::new(Vec2), Type::new(Vec4)],
);
declare_function(
state,
"swgl_commitPartialTextureLinearInvertR8",
None,
Type::new(Void),
vec![Type::new(Int), Type::new(*s), Type::new(Vec2), Type::new(Vec4)],
);
declare_function(
state,
"swgl_commitTextureLinearColorRGBA8",
Expand Down
8 changes: 8 additions & 0 deletions swgl/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,9 @@ void swgl_commitTextureColorRGBA8(sampler, vec2 uv, vec4 uv_bounds, vec4|float c
void swgl_commitTextureRepeatRGBA8(sampler, vec2 uv, vec2 tile_repeat, vec4 uv_repeat, vec4 uv_bounds);
void swgl_commitTextureRepeatColorRGBA8(sampler, vec2 uv, vec2 tile_repeat, vec4 uv_repeat, vec4 uv_bounds, vec4|float color);
void swgl_commitPartialTextureLinearR8(int len, sampler, vec2 uv, vec4 uv_bounds);
void swgl_commitPartialTextureLinearInvertR8(int len, sampler, vec2 uv, vec4 uv_bounds);
```

Samples and commits an entire span of texture starting at the given uv and
Expand All @@ -193,6 +196,11 @@ range 0 to 1. For NearestRepeat variations, it is assumed the repeat rect is
always within the bounds. The tile repeat limit, if non-zero, specifies the
maximum number of repetitions allowed.

The Partial variations allow committing only a sub-span rather the entire
remaining span. These are currently only implemented in linear R8 variants
for optimizing clip shaders in WebRender. The Invert variant of these is
useful for implementing clip-out modes by inverting the source texture value.

```
// Premultiplied alpha over blend, but with source color set to source alpha modulated with a constant color.
void swgl_blendDropShadow(vec4 color);
Expand Down
13 changes: 13 additions & 0 deletions swgl/src/blend.h
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,13 @@ static ALWAYS_INLINE P applyColor(P src, NoColor) {
return src;
}

struct InvertColor {};

template <typename P>
static ALWAYS_INLINE P applyColor(P src, InvertColor) {
return 255 - src;
}

template <typename P>
static ALWAYS_INLINE P applyColor(P src, P color) {
return muldiv256(src, color);
Expand All @@ -170,6 +177,12 @@ static ALWAYS_INLINE NoColor packColor(UNUSED P* buf, NoColor noColor) {
return noColor;
}

template <typename P>
static ALWAYS_INLINE InvertColor packColor(UNUSED P* buf,
InvertColor invertColor) {
return invertColor;
}

// Single argument variation that takes an explicit destination buffer type.
template <typename P, typename C>
static ALWAYS_INLINE auto packColor(C color) {
Expand Down
28 changes: 28 additions & 0 deletions swgl/src/glsl.h
Original file line number Diff line number Diff line change
Expand Up @@ -2063,6 +2063,10 @@ SI vec4_scalar if_then_else(int32_t c, vec4_scalar t, vec4_scalar e) {
return c ? t : e;
}

SI vec2 clamp(vec2 a, Float minVal, Float maxVal) {
return vec2(clamp(a.x, minVal, maxVal), clamp(a.y, minVal, maxVal));
}

SI vec2 clamp(vec2 a, vec2 minVal, vec2 maxVal) {
return vec2(clamp(a.x, minVal.x, maxVal.x), clamp(a.y, minVal.y, maxVal.y));
}
Expand All @@ -2072,6 +2076,10 @@ SI vec2_scalar clamp(vec2_scalar a, vec2_scalar minVal, vec2_scalar maxVal) {
clamp(a.y, minVal.y, maxVal.y)};
}

SI vec2_scalar clamp(vec2_scalar a, float minVal, float maxVal) {
return vec2_scalar{clamp(a.x, minVal, maxVal), clamp(a.y, minVal, maxVal)};
}

SI I32 clamp(I32 a, I32 minVal, I32 maxVal) {
a = if_then_else(a < minVal, minVal, a);
return if_then_else(a > maxVal, maxVal, a);
Expand All @@ -2087,6 +2095,11 @@ SI vec3 clamp(vec3 a, vec3 minVal, vec3 maxVal) {
clamp(a.z, minVal.z, maxVal.z));
}

SI vec4 clamp(vec4 a, Float minVal, Float maxVal) {
return vec4(clamp(a.x, minVal, maxVal), clamp(a.y, minVal, maxVal),
clamp(a.z, minVal, maxVal), clamp(a.w, minVal, maxVal));
}

SI vec4 clamp(vec4 a, vec4 minVal, vec4 maxVal) {
return vec4(clamp(a.x, minVal.x, maxVal.x), clamp(a.y, minVal.y, maxVal.y),
clamp(a.z, minVal.z, maxVal.z), clamp(a.w, minVal.w, maxVal.w));
Expand All @@ -2098,6 +2111,11 @@ SI vec4_scalar clamp(vec4_scalar a, vec4_scalar minVal, vec4_scalar maxVal) {
clamp(a.z, minVal.z, maxVal.z), clamp(a.w, minVal.w, maxVal.w)};
}

SI vec4_scalar clamp(vec4_scalar a, float minVal, float maxVal) {
return vec4_scalar{clamp(a.x, minVal, maxVal), clamp(a.y, minVal, maxVal),
clamp(a.z, minVal, maxVal), clamp(a.w, minVal, maxVal)};
}

vec4 step(vec4 edge, vec4 x) {
return vec4(step(edge.x, x.x), step(edge.y, x.y), step(edge.z, x.z),
step(edge.w, x.w));
Expand Down Expand Up @@ -2579,6 +2597,16 @@ SI T mix(T x, T y, float a) {
return (y - x) * a + x;
}

template <typename T>
SI T mix(T x, T y, vec2_scalar a) {
return T{mix(x.x, y.x, a.x), mix(x.y, y.y, a.y)};
}

template <typename T>
SI T mix(T x, T y, vec3_scalar a) {
return T{mix(x.x, y.x, a.x), mix(x.y, y.y, a.y), mix(x.z, y.z, a.z)};
}

template <typename T>
SI T mix(T x, T y, vec4_scalar a) {
return T{mix(x.x, y.x, a.x), mix(x.y, y.y, a.y), mix(x.z, y.z, a.z),
Expand Down
Loading

0 comments on commit 984512d

Please sign in to comment.