Bug 1615613 - Integrate the text shader in the brush infrastructure. r=gw

As a strating point for the vertex shader, this patch isolates the parts that are common to both shaders: the code that fetches various piece of data, adding a branching point between the text shader and other brushes just after having fetched most of the data. Hopefully we can devise ways to further unify the vertex shaders in followups.

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

--HG--
extra : moz-landing-system : lando
This commit is contained in:
Nicolas Silva 2020-03-17 12:49:10 +00:00
parent 343cdb154c
commit 5670c32118
4 changed files with 147 additions and 48 deletions

View File

@ -92,6 +92,17 @@ FWD_DECLARE_VS_FUNCTION(radial_gradient_brush_vs)
FWD_DECLARE_VS_FUNCTION(conic_gradient_brush_vs)
FWD_DECLARE_VS_FUNCTION(yuv_brush_vs)
FWD_DECLARE_VS_FUNCTION(opacity_brush_vs)
FWD_DECLARE_VS_FUNCTION(text_brush_vs)
// Forward-declare the text vertex shader entry point which is currently
// different from other brushes.
void text_shader_main(
Instance instance,
PrimitiveHeader ph,
Transform transform,
PictureTask task,
ClipArea clip_area
);
void multi_brush_vs(
VertexInfo vi,
@ -120,12 +131,15 @@ void multi_brush_vs(
#define INVALID_SEGMENT_INDEX 0xffff
void main(void) {
// Load the brush instance from vertex attributes.
Instance instance = decode_instance_attributes();
void brush_shader_main_vs(
Instance instance,
PrimitiveHeader ph,
Transform transform,
PictureTask pic_task,
ClipArea clip_area
) {
int edge_flags = instance.flags & 0xff;
int brush_flags = (instance.flags >> 8) & 0xff;
PrimitiveHeader ph = fetch_prim_header(instance.prim_header_address);
// Fetch the segment of this brush primitive we are drawing.
vec4 segment_data;
@ -156,12 +170,6 @@ void main(void) {
VertexInfo vi;
// Fetch the dynamic picture that we are drawing on.
PictureTask pic_task = fetch_picture_task(instance.picture_task_address);
ClipArea clip_area = fetch_clip_area(instance.clip_address);
Transform transform = fetch_transform(ph.transform_id);
// Write the normal vertex information out.
if (transform.is_axis_aligned) {
@ -245,8 +253,25 @@ void main(void) {
}
#ifndef WR_VERTEX_SHADER_MAIN_FUNCTION
// If the entry-point was not overridden before including the brush shader,
// use the default one.
#define WR_VERTEX_SHADER_MAIN_FUNCTION brush_shader_main_vs
#endif
void main(void) {
Instance instance = decode_instance_attributes();
PrimitiveHeader ph = fetch_prim_header(instance.prim_header_address);
Transform transform = fetch_transform(ph.transform_id);
PictureTask task = fetch_picture_task(instance.picture_task_address);
ClipArea clip_area = fetch_clip_area(instance.clip_address);
WR_VERTEX_SHADER_MAIN_FUNCTION(instance, ph, transform, task, clip_area);
}
#endif // WR_VERTEX_SHADER
#ifdef WR_FRAGMENT_SHADER
// Foward-declare all brush entry-points.

View File

@ -7,7 +7,7 @@
// This type of uber-shader comes at a cost so the goal for this is to
// provide opportunities for aggressive batching when the number of draw
// calls so high that reducing the number of draw calls is worth the
// cost of this "über-shader".
// cost of this "uber-shader".
#define WR_FEATURE_MULTI_BRUSH
@ -26,8 +26,30 @@
int vecs_per_brush(int brush_kind);
#ifdef WR_FEATURE_TEXT_BRUSH
// Before including the brush source, if we need support for text we override
// the vertex shader's main entry point with one that can call into the text
// shader or the regular brush shaders.
// Foward-declare the new entry point.
void multi_brush_main_vs(
Instance instance,
PrimitiveHeader ph,
Transform transform,
PictureTask pic_task,
ClipArea clip_area
);
// Override the default entry point.
#define WR_VERTEX_SHADER_MAIN_FUNCTION multi_brush_main_vs
#endif
#include shared,prim_shared,brush
#ifdef WR_FEATURE_IMAGE_BRUSH
#include brush_image
#endif
@ -88,6 +110,30 @@ int vecs_per_brush(int brush_kind);
#include brush_opacity
#endif
#undef VECS_PER_SPECIFIC_BRUSH
#undef WR_BRUSH_VS_FUNCTION
#undef WR_BRUSH_FS_FUNCTION
#ifdef WR_FEATURE_TEXT_BRUSH
#include ps_text_run
// Special entry point when text support is needed.
void multi_brush_main_vs(
Instance instance,
PrimitiveHeader ph,
Transform transform,
PictureTask pic_task,
ClipArea clip_area
) {
if (instance.brush_kind == BRUSH_SHADER_KIND_TEXT) {
text_shader_main(instance, ph, transform, task, clip_area);
} else {
brush_shader_main(instance, ph, transform, task, clip_area);
}
}
#endif
int vecs_per_brush(int brush_kind) {
switch (brush_kind) {
// The default arm should never be taken, we let it point to whichever shader
@ -240,6 +286,10 @@ Fragment multi_brush_fs(int brush_kind) {
#ifdef WR_FEATURE_OPACITY_BRUSH
case BRUSH_KIND_OPACITY: return opacity_brush_fs();
#endif
#ifdef WR_FEATURE_TEXT_BRUSH
case BRUSH_KIND_TEXT: return text_brush_fs();
#endif
}
}

View File

@ -2,19 +2,28 @@
* 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/. */
#define WR_VERTEX_SHADER_MAIN_FUNCTION text_shader_main_vs
#define WR_BRUSH_FS_FUNCTION text_brush_fs
#define WR_BRUSH_VS_FUNCTION text_brush_vs
// The text brush shader doesn't use this but the macro must be defined
// to compile the brush infrastructure.
#define VECS_PER_SPECIFIC_BRUSH 0
#include shared,prim_shared
// A few varying slots for the brushes to use.
// Using these instead of adding dedicated varyings avoids using a high
// number of varyings in the multi-brush shader.
//
// TODO: This is duplicated from the brush shader code and will be merged
// back once text runs use the brush infrastructure.
flat varying vec4 flat_varying_vec4_0;
flat varying vec4 flat_varying_vec4_1;
flat varying vec4 flat_varying_vec4_2;
varying vec4 varying_vec4_0;
varying vec4 varying_vec4_1;
#ifdef WR_VERTEX_SHADER
// Forward-declare the text vertex shader's main entry-point before including
// the brush shader.
void text_shader_main_vs(
Instance instance,
PrimitiveHeader ph,
Transform transform,
PictureTask task,
ClipArea clip_area
);
#endif
#include brush
#define V_COLOR flat_varying_vec4_0
#define V_MASK_SWIZZLE flat_varying_vec4_1.xy
@ -112,18 +121,17 @@ vec2 get_snap_bias(int subpx_dir) {
}
}
void main(void) {
Instance instance = decode_instance_attributes();
void text_shader_main_vs(
Instance instance,
PrimitiveHeader ph,
Transform transform,
PictureTask task,
ClipArea clip_area
) {
int glyph_index = instance.segment_index;
int subpx_dir = (instance.flags >> 8) & 0xff;
int color_mode = instance.flags & 0xff;
PrimitiveHeader ph = fetch_prim_header(instance.prim_header_address);
Transform transform = fetch_transform(ph.transform_id);
ClipArea clip_area = fetch_clip_area(instance.clip_address);
PictureTask task = fetch_picture_task(instance.picture_task_address);
// Note that the reference frame relative offset is stored in the prim local
// rect size during batching, instead of the actual size of the primitive.
TextRun text = fetch_text_run(ph.specific_prim_address);
@ -272,7 +280,27 @@ void main(void) {
V_LAYER = res.layer;
V_UV_BOUNDS = (res.uv_rect + vec4(0.5, 0.5, -0.5, -0.5)) / texture_size.xyxy;
}
#endif
void text_brush_vs(
VertexInfo vi,
int prim_address,
RectWithSize prim_rect,
RectWithSize segment_rect,
ivec4 prim_user_data,
int specific_resource_address,
mat4 transform,
PictureTask pic_task,
int brush_flags,
vec4 segment_data
) {
// This function is empty and unused for now. It has to be defined to build the shader
// as a brush, but the brush shader currently branches into text_shader_main_vs earlier
// instead of using the regular brush vertex interface for text.
// In the future we should strive to further unify text and brushes, and actually make
// use of this function.
}
#endif // WR_VERTEX_SHADER
#ifdef WR_FRAGMENT_SHADER
@ -296,20 +324,12 @@ Fragment text_brush_fs(void) {
return frag;
}
void main(void) {
Fragment frag = text_brush_fs();
float clip_mask = do_clip();
frag.color *= clip_mask;
#if defined(WR_FEATURE_DEBUG_OVERDRAW)
oFragColor = WR_DEBUG_OVERDRAW_COLOR;
#elif defined(WR_FEATURE_DUAL_SOURCE_BLENDING)
oFragColor = frag.color;
oFragBlend = frag.blend * clip_mask;
#else
write_output(frag.color);
#endif
}
#endif // WR_FRAGMENT_SHADER
// Undef macro names that could be re-defined by other shaders.
#undef V_COLOR
#undef V_MASK_SWIZZLE
#undef V_UV_BOUNDS
#undef V_UV
#undef V_LAYER
#undef V_UV_CLIP

View File

@ -421,16 +421,20 @@ impl TextShader {
features: &[&'static str],
precache_flags: ShaderPrecacheFlags,
) -> Result<Self, ShaderError> {
let mut simple_features = features.to_vec();
simple_features.push("ALPHA_PASS");
let simple = LazilyCompiledShader::new(
ShaderKind::Text,
name,
features,
&simple_features,
device,
precache_flags,
)?;
let mut glyph_transform_features = features.to_vec();
glyph_transform_features.push("GLYPH_TRANSFORM");
glyph_transform_features.push("ALPHA_PASS");
let glyph_transform = LazilyCompiledShader::new(
ShaderKind::Text,