зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1888628 - Extract the texture sampling logic out of ps_quad.glsl. r=gw
This simplifies the common infrastructure, removes two varyings from the common set and will allow other patterns to handle sampling differently if they need it (for example an upcoming repeating pattern). In addition: - the color parameter is always passed to the fragment shader (it used to be only when no uv_rect was passed). - v_flags was reorganized a bit so that w is used by the common infrastructure and xyz are available for patterns to use. Differential Revision: https://phabricator.services.mozilla.com/D206098
This commit is contained in:
Родитель
30e937eddd
Коммит
b4a0426fbf
|
@ -37,12 +37,9 @@
|
|||
#include shared,rect,transform,render_task,gpu_buffer
|
||||
|
||||
flat varying mediump vec4 v_color;
|
||||
flat varying mediump vec4 v_uv_sample_bounds;
|
||||
// x: (in ps_quad_textured) has edge flags
|
||||
// y: has uv rect
|
||||
// z: (in ps_quad_textured) sample as mask
|
||||
// w: has edge flags
|
||||
// x,y,z are avaible for patterns to use.
|
||||
flat varying lowp ivec4 v_flags;
|
||||
varying highp vec2 v_uv;
|
||||
|
||||
#ifndef SWGL_ANTIALIAS
|
||||
varying highp vec2 vLocalPos;
|
||||
|
@ -74,22 +71,24 @@ varying highp vec2 vLocalPos;
|
|||
|
||||
PER_INSTANCE in ivec4 aData;
|
||||
|
||||
struct QuadSegment {
|
||||
RectWithEndpoint rect;
|
||||
RectWithEndpoint uv_rect;
|
||||
};
|
||||
|
||||
struct PrimitiveInfo {
|
||||
vec2 local_pos;
|
||||
|
||||
RectWithEndpoint local_prim_rect;
|
||||
RectWithEndpoint local_clip_rect;
|
||||
|
||||
QuadSegment segment;
|
||||
|
||||
int edge_flags;
|
||||
int quad_flags;
|
||||
ivec2 pattern_input;
|
||||
};
|
||||
|
||||
struct QuadSegment {
|
||||
RectWithEndpoint rect;
|
||||
vec4 uv_rect;
|
||||
};
|
||||
|
||||
struct QuadPrimitive {
|
||||
RectWithEndpoint bounds;
|
||||
RectWithEndpoint clip;
|
||||
|
@ -102,7 +101,7 @@ QuadSegment fetch_segment(int base, int index) {
|
|||
vec4 texels[2] = fetch_from_gpu_buffer_2f(base + 3 + index * 2);
|
||||
|
||||
seg.rect = RectWithEndpoint(texels[0].xy, texels[0].zw);
|
||||
seg.uv_rect = texels[1];
|
||||
seg.uv_rect = RectWithEndpoint(texels[1].xy, texels[1].zw);
|
||||
|
||||
return seg;
|
||||
}
|
||||
|
@ -232,7 +231,7 @@ PrimitiveInfo quad_primive_info(void) {
|
|||
QuadSegment seg;
|
||||
if (qi.segment_index == INVALID_SEGMENT_INDEX) {
|
||||
seg.rect = prim.bounds;
|
||||
seg.uv_rect = vec4(0.0);
|
||||
seg.uv_rect = RectWithEndpoint(vec2(0.0), vec2(0.0));
|
||||
} else {
|
||||
seg = fetch_segment(qi.prim_address_f, qi.segment_index);
|
||||
}
|
||||
|
@ -325,35 +324,13 @@ PrimitiveInfo quad_primive_info(void) {
|
|||
qi.quad_flags
|
||||
);
|
||||
|
||||
if (seg.uv_rect.xy == seg.uv_rect.zw) {
|
||||
v_color = prim.color;
|
||||
v_flags.y = 0;
|
||||
} else {
|
||||
v_color = vec4(1.0);
|
||||
v_flags.y = 1;
|
||||
|
||||
vec2 f = (vi.local_pos - seg.rect.p0) / (seg.rect.p1 - seg.rect.p0);
|
||||
|
||||
vec2 uv = mix(
|
||||
seg.uv_rect.xy,
|
||||
seg.uv_rect.zw,
|
||||
f
|
||||
);
|
||||
|
||||
vec2 texture_size = vec2(TEX_SIZE(sColor0));
|
||||
|
||||
v_uv = uv / texture_size;
|
||||
|
||||
v_uv_sample_bounds = vec4(
|
||||
seg.uv_rect.xy + vec2(0.5),
|
||||
seg.uv_rect.zw - vec2(0.5)
|
||||
) / texture_size.xyxy;
|
||||
}
|
||||
v_color = prim.color;
|
||||
|
||||
return PrimitiveInfo(
|
||||
vi.local_pos,
|
||||
prim.bounds,
|
||||
prim.clip,
|
||||
seg,
|
||||
qi.edge_flags,
|
||||
qi.quad_flags,
|
||||
qh.pattern_input
|
||||
|
@ -372,9 +349,9 @@ void antialiasing_vertex(PrimitiveInfo prim) {
|
|||
vLocalPos = prim.local_pos;
|
||||
|
||||
if (prim.edge_flags == 0) {
|
||||
v_flags.x = 0;
|
||||
v_flags.w = 0;
|
||||
} else {
|
||||
v_flags.x = 1;
|
||||
v_flags.w = 1;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
@ -392,7 +369,7 @@ vec4 pattern_fragment(vec4 base_color);
|
|||
float antialiasing_fragment() {
|
||||
float alpha = 1.0;
|
||||
#ifndef SWGL_ANTIALIAS
|
||||
if (v_flags.x != 0) {
|
||||
if (v_flags.w != 0) {
|
||||
alpha = init_transform_fs(vLocalPos);
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -4,24 +4,42 @@
|
|||
|
||||
/// This shader renders solid colors or simple images in a color or alpha target.
|
||||
|
||||
#include ps_quad
|
||||
#include ps_quad,sample_color0
|
||||
|
||||
#define v_flags_textured v_flags.x
|
||||
#define v_flags_sample_as_mask v_flags.y
|
||||
|
||||
#ifdef WR_VERTEX_SHADER
|
||||
|
||||
void pattern_vertex(PrimitiveInfo info) {
|
||||
if ((info.quad_flags & QF_SAMPLE_AS_MASK) != 0) {
|
||||
v_flags.z = 1;
|
||||
// Note: Since the uv rect is passed via segments, This shader cannot sample from a
|
||||
// texture if no segments are provided
|
||||
if (info.segment.uv_rect.p0 != info.segment.uv_rect.p1) {
|
||||
// Textured
|
||||
v_flags_textured = 1;
|
||||
|
||||
vec2 f = (info.local_pos - info.segment.rect.p0) / rect_size(info.segment.rect);
|
||||
vs_init_sample_color0(f, info.segment.uv_rect);
|
||||
} else {
|
||||
v_flags.z = 0;
|
||||
// Solid color
|
||||
v_flags_textured = 0;
|
||||
}
|
||||
|
||||
if ((info.quad_flags & QF_SAMPLE_AS_MASK) != 0) {
|
||||
v_flags_sample_as_mask = 1;
|
||||
} else {
|
||||
v_flags_sample_as_mask = 0;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef WR_FRAGMENT_SHADER
|
||||
|
||||
vec4 pattern_fragment(vec4 color) {
|
||||
if (v_flags.y != 0) {
|
||||
vec2 uv = clamp(v_uv, v_uv_sample_bounds.xy, v_uv_sample_bounds.zw);
|
||||
vec4 texel = TEX_SAMPLE(sColor0, uv);
|
||||
if (v_flags.z != 0) {
|
||||
if (v_flags_textured != 0) {
|
||||
vec4 texel = fs_sample_color0();
|
||||
if (v_flags_sample_as_mask != 0) {
|
||||
texel = texel.rrrr;
|
||||
}
|
||||
color *= texel;
|
||||
|
@ -32,12 +50,12 @@ vec4 pattern_fragment(vec4 color) {
|
|||
|
||||
#if defined(SWGL_DRAW_SPAN)
|
||||
void swgl_drawSpanRGBA8() {
|
||||
if (v_flags.y != 0) {
|
||||
if (v_flags.z != 0) {
|
||||
if (v_flags_textured != 0) {
|
||||
if (v_flags_sample_as_mask != 0) {
|
||||
// Fall back to fragment shader as we don't specialize for mask yet. Perhaps
|
||||
// we can use an existing swgl commit or add a new one though?
|
||||
} else {
|
||||
swgl_commitTextureLinearColorRGBA8(sColor0, v_uv, v_uv_sample_bounds, v_color);
|
||||
swgl_commitTextureLinearColorRGBA8(sColor0, v_uv0, v_uv0_sample_bounds, v_color);
|
||||
}
|
||||
} else {
|
||||
swgl_commitSolidRGBA8(v_color);
|
||||
|
|
|
@ -0,0 +1,41 @@
|
|||
/* 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/. */
|
||||
|
||||
/// This file provides the boilerplate for sampling from sColor0 with strict sample bounds.
|
||||
|
||||
#include shared
|
||||
|
||||
flat varying mediump vec4 v_uv0_sample_bounds;
|
||||
varying highp vec2 v_uv0;
|
||||
|
||||
#ifdef WR_VERTEX_SHADER
|
||||
|
||||
/// sample_pos is in 0..1 normalized coordinates
|
||||
/// uv_rect is in pixel.
|
||||
void vs_init_sample_color0(vec2 sample_pos, RectWithEndpoint uv_rect) {
|
||||
vec2 uv = mix(uv_rect.p0, uv_rect.p1, sample_pos);
|
||||
|
||||
vec2 texture_size = vec2(TEX_SIZE(sColor0));
|
||||
|
||||
v_uv0 = uv / texture_size;
|
||||
|
||||
v_uv0_sample_bounds = vec4(
|
||||
uv_rect.p0 + vec2(0.5),
|
||||
uv_rect.p1 - vec2(0.5)
|
||||
) / texture_size.xyxy;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef WR_FRAGMENT_SHADER
|
||||
|
||||
/// The vertex shader must have called vs_init_sample_color0
|
||||
vec4 fs_sample_color0() {
|
||||
vec2 uv = clamp(v_uv0, v_uv0_sample_bounds.xy, v_uv0_sample_bounds.zw);
|
||||
vec4 texel = TEX_SAMPLE(sColor0, uv);
|
||||
|
||||
return texel;
|
||||
}
|
||||
|
||||
#endif
|
|
@ -62,7 +62,7 @@ impl Pattern {
|
|||
Pattern {
|
||||
kind: PatternKind::ColorOrTexture,
|
||||
shader_input: PatternShaderInput::default(),
|
||||
base_color: PremultipliedColorF::BLACK,
|
||||
base_color: PremultipliedColorF::WHITE,
|
||||
is_opaque: false,
|
||||
}
|
||||
}
|
||||
|
|
|
@ -616,7 +616,7 @@ fn add_composite_prim(
|
|||
&mut frame_state.frame_gpu_data.f32,
|
||||
rect,
|
||||
rect,
|
||||
pattern.base_color,
|
||||
PremultipliedColorF::WHITE,
|
||||
segments,
|
||||
);
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче