chore: Move clockwiseAtomic shaders to the new system (#11388) 85c5519c6e

With clockwise mode, we introduced ".vert" and ".frag" files and started
sharing the main vertex shaders with multiple fragment shaders. This PR
is a cleanup that removes redundant code and moves the clockwiseAtomic
shaders to that same system. clockwiseAtomic shaders also work out paint
colors via varyings now instead of storage buffers, which seems better
but doesn't register a difference in performance.

Co-authored-by: Chris Dalton <99840794+csmartdalton@users.noreply.github.com>
This commit is contained in:
csmartdalton
2026-01-07 22:50:26 +00:00
parent ff65727994
commit efd202ff5c
25 changed files with 137 additions and 351 deletions

View File

@@ -1 +1 @@
209e1b6d961f6bc44f1e69f7e2eb6146251f66d9
85c5519c6ec1b73ef7b9cf149084eb16779f771f

View File

@@ -126,9 +126,11 @@ rive::Span<const uint32_t> loadNewShaderFileData()
riveSpirvPath / "draw_clockwise_atomic_interior_triangles.vert.spirv",
riveSpirvPath / "draw_clockwise_atomic_interior_triangles.frag.spirv",
riveSpirvPath / "draw_clockwise_atomic_atlas_blit.vert.spirv",
riveSpirvPath / "draw_clockwise_atomic_atlas_blit.frag.spirv",
riveSpirvPath /
"draw_clockwise_atomic_atlas_blit.fixedcolor_frag.spirv",
riveSpirvPath / "draw_clockwise_atomic_image_mesh.vert.spirv",
riveSpirvPath / "draw_clockwise_atomic_image_mesh.frag.spirv",
riveSpirvPath /
"draw_clockwise_atomic_image_mesh.fixedcolor_frag.spirv",
riveSpirvPath / "draw_msaa_path.vert.spirv",
riveSpirvPath / "draw_msaa_path.noclipdistance_vert.spirv",

View File

@@ -13,7 +13,7 @@
#include "generated/shaders/constants.glsl.hpp"
#include "generated/shaders/common.glsl.hpp"
#include "generated/shaders/draw_image_mesh.vert.hpp"
#include "generated/shaders/draw_raster_order_mesh.frag.hpp"
#include "generated/shaders/draw_mesh.frag.hpp"
#include "generated/shaders/draw_path_common.glsl.hpp"
#include "generated/shaders/draw_path.vert.hpp"
#include "generated/shaders/draw_raster_order_path.frag.hpp"
@@ -131,11 +131,11 @@ static std::string build_shader(DrawType drawType,
case DrawType::atlasBlit:
s << glsl::draw_path_common << '\n';
s << glsl::draw_path_vert << '\n';
s << glsl::draw_raster_order_mesh_frag << '\n';
s << glsl::draw_mesh_frag << '\n';
break;
case DrawType::imageMesh:
s << glsl::draw_image_mesh_vert << '\n';
s << glsl::draw_raster_order_mesh_frag << '\n';
s << glsl::draw_mesh_frag << '\n';
break;
case DrawType::imageRect:
case DrawType::renderPassResolve:

View File

@@ -22,7 +22,7 @@
#include "generated/shaders/draw_clockwise_path.frag.hpp"
#include "generated/shaders/draw_clockwise_clip.frag.hpp"
#include "generated/shaders/draw_image_mesh.vert.hpp"
#include "generated/shaders/draw_raster_order_mesh.frag.hpp"
#include "generated/shaders/draw_mesh.frag.hpp"
#include "generated/shaders/draw_msaa_object.frag.hpp"
#include "generated/shaders/bezier_utils.glsl.hpp"
#include "generated/shaders/tessellate.glsl.hpp"
@@ -1207,11 +1207,11 @@ RenderContextGLImpl::DrawShader::DrawShader(
case gpu::DrawType::atlasBlit:
sources.push_back(gpu::glsl::draw_path_common);
sources.push_back(gpu::glsl::draw_path_vert);
sources.push_back(gpu::glsl::draw_raster_order_mesh_frag);
sources.push_back(gpu::glsl::draw_mesh_frag);
break;
case gpu::DrawType::imageMesh:
sources.push_back(gpu::glsl::draw_image_mesh_vert);
sources.push_back(gpu::glsl::draw_raster_order_mesh_frag);
sources.push_back(gpu::glsl::draw_mesh_frag);
break;
case gpu::DrawType::imageRect:
case gpu::DrawType::msaaStrokes:

View File

@@ -12,7 +12,7 @@
#include "generated/shaders/draw_path.vert.hpp"
#include "generated/shaders/draw_raster_order_path.frag.hpp"
#include "generated/shaders/draw_image_mesh.vert.hpp"
#include "generated/shaders/draw_raster_order_mesh.frag.hpp"
#include "generated/shaders/draw_mesh.frag.hpp"
#ifndef RIVE_IOS
// iOS doesn't need the atomic shaders; every non-simulated iOS device supports
@@ -233,16 +233,12 @@ void BackgroundShaderCompiler::threadMain()
case DrawType::atlasBlit:
[source appendFormat:@"%s\n", gpu::glsl::draw_path_common];
[source appendFormat:@"%s\n", gpu::glsl::draw_path_vert];
[source
appendFormat:@"%s\n",
gpu::glsl::draw_raster_order_mesh_frag];
[source appendFormat:@"%s\n", gpu::glsl::draw_mesh_frag];
break;
case DrawType::imageMesh:
[source
appendFormat:@"%s\n", gpu::glsl::draw_image_mesh_vert];
[source
appendFormat:@"%s\n",
gpu::glsl::draw_raster_order_mesh_frag];
[source appendFormat:@"%s\n", gpu::glsl::draw_mesh_frag];
break;
case DrawType::imageRect:
case DrawType::msaaStrokes:

View File

@@ -170,6 +170,8 @@ SPIRV_FIXEDCOLOR_FRAG_INPUTS := \
spirv/draw_clockwise_interior_triangles_clip.main \
spirv/draw_clockwise_atlas_blit.main \
spirv/draw_clockwise_image_mesh.main \
spirv/draw_clockwise_atomic_atlas_blit.main \
spirv/draw_clockwise_atomic_image_mesh.main \
spirv/draw_msaa_atlas_blit.main \
spirv/draw_msaa_image_mesh.main \
spirv/draw_msaa_path.main \
@@ -188,8 +190,9 @@ spirv_out_filename_no_ext = $(OUT)/$(call spirv_typed_filename,$1,$2)
spirv_type = $(lastword $(subst _, ,$2))
spirv_is_vert = $(findstring vert,$(spirv_type))
spirv_is_webgpu = $(findstring webgpu,$2)
spirv_is_atomic = $(findstring atomic,$1)
spirv_is_clockwise = $(findstring clockwise,$1)
spirv_is_not_clockwise_atomic = $(ifeq $(findstring clockwise_atomic,$1),)
spirv_is_atomic = $(and $(findstring atomic,$1),spirv_is_not_clockwise_atomic)
spirv_is_clockwise = $(and $(findstring clockwise,$1),spirv_is_not_clockwise_atomic)
## SPIR-V Optimizer settings

View File

@@ -1,69 +0,0 @@
/*
* Copyright 2024 Rive
*/
#ifdef @VERTEX
ATTR_BLOCK_BEGIN(PositionAttr)
ATTR(0, float2, @a_position);
ATTR_BLOCK_END
ATTR_BLOCK_BEGIN(UVAttr)
ATTR(1, float2, @a_texCoord);
ATTR_BLOCK_END
#endif
VARYING_BLOCK_BEGIN
NO_PERSPECTIVE VARYING(0, float2, v_texCoord);
VARYING_BLOCK_END
#ifdef @VERTEX
VERTEX_TEXTURE_BLOCK_BEGIN
VERTEX_TEXTURE_BLOCK_END
IMAGE_MESH_VERTEX_MAIN(@drawVertexMain,
PositionAttr,
position,
UVAttr,
uv,
_vertexID)
{
ATTR_UNPACK(_vertexID, position, @a_position, float2);
ATTR_UNPACK(_vertexID, uv, @a_texCoord, float2);
VARYING_INIT(v_texCoord, float2);
float2 vertexPosition =
MUL(make_float2x2(imageDrawUniforms.viewMatrix), @a_position) +
imageDrawUniforms.translate;
v_texCoord = @a_texCoord;
float4 pos = RENDER_TARGET_COORD_TO_CLIP_COORD(vertexPosition);
VARYING_PACK(v_texCoord);
EMIT_VERTEX(pos);
}
#endif
#ifdef @FRAGMENT
FRAG_TEXTURE_BLOCK_BEGIN
TEXTURE_RGBA8(PER_DRAW_BINDINGS_SET, IMAGE_TEXTURE_IDX, @imageTexture);
FRAG_TEXTURE_BLOCK_END
DYNAMIC_SAMPLER_BLOCK_BEGIN
SAMPLER_DYNAMIC(PER_DRAW_BINDINGS_SET, IMAGE_SAMPLER_IDX, imageSampler)
DYNAMIC_SAMPLER_BLOCK_END
FRAG_STORAGE_BUFFER_BLOCK_BEGIN
FRAG_STORAGE_BUFFER_BLOCK_END
FRAG_DATA_MAIN(half4, @drawFragmentMain)
{
VARYING_UNPACK(v_texCoord, float2);
half4 meshColor =
TEXTURE_SAMPLE_DYNAMIC(@imageTexture, imageSampler, v_texCoord);
meshColor = make_half4(unmultiply_rgb(meshColor),
meshColor.a * imageDrawUniforms.opacity);
EMIT_FRAG_DATA(meshColor);
}
#endif // FRAGMENT

View File

@@ -2,138 +2,8 @@
* Copyright 2023 Rive
*/
#ifdef @DRAW_PATH
#ifdef @VERTEX
ATTR_BLOCK_BEGIN(Attrs)
// [localVertexID, outset, fillCoverage, vertexType]
ATTR(0, float4, @a_patchVertexData);
ATTR(1, float4, @a_mirroredVertexData);
ATTR_BLOCK_END
#endif
VARYING_BLOCK_BEGIN
FLAT VARYING(0, ushort, v_pathID);
NO_PERSPECTIVE VARYING(1, float4, v_coverages);
NO_PERSPECTIVE VARYING(2, float2, v_atlasCoord);
FLAT VARYING(3, uint2, v_coveragePlacement);
VARYING(4, float2, v_coverageCoord);
VARYING_BLOCK_END
#ifdef @VERTEX
VERTEX_MAIN(@drawVertexMain, Attrs, attrs, _vertexID, _instanceID)
{
ATTR_UNPACK(_vertexID, attrs, @a_patchVertexData, float4);
ATTR_UNPACK(_vertexID, attrs, @a_mirroredVertexData, float4);
VARYING_INIT(v_pathID, ushort);
VARYING_INIT(v_coverages, float4);
VARYING_INIT(v_coveragePlacement, uint2);
VARYING_INIT(v_coverageCoord, float2);
float4 pos;
uint pathID;
float2 vertexPosition;
if (unpack_tessellated_path_vertex(@a_patchVertexData,
@a_mirroredVertexData,
_instanceID,
pathID,
vertexPosition,
v_coverages VERTEX_CONTEXT_UNPACK))
{
uint4 coverageData =
STORAGE_BUFFER_LOAD4(@pathBuffer, pathID * 4u + 3u);
v_pathID = pathID;
v_coveragePlacement = coverageData.xy;
v_coverageCoord = vertexPosition + uintBitsToFloat(coverageData.zw);
pos = RENDER_TARGET_COORD_TO_CLIP_COORD(vertexPosition);
}
else
{
pos = float4(uniforms.vertexDiscardValue,
uniforms.vertexDiscardValue,
uniforms.vertexDiscardValue,
uniforms.vertexDiscardValue);
}
VARYING_PACK(v_pathID);
VARYING_PACK(v_coverages);
VARYING_PACK(v_coveragePlacement);
VARYING_PACK(v_coverageCoord);
EMIT_VERTEX(pos);
}
#endif // VERTEX
#endif // DRAW_PATH
#ifdef @DRAW_INTERIOR_TRIANGLES
#ifdef @VERTEX
ATTR_BLOCK_BEGIN(Attrs)
ATTR(0, packed_float3, @a_triangleVertex);
ATTR_BLOCK_END
#endif
VARYING_BLOCK_BEGIN
FLAT VARYING(0, ushort, v_pathID);
#ifdef @ATLAS_BLIT
NO_PERSPECTIVE VARYING(1, float2, v_atlasCoord);
#else
@OPTIONALLY_FLAT VARYING(1, half, v_windingWeight);
FLAT VARYING(2, uint2, v_coveragePlacement);
VARYING(3, float2, v_coverageCoord);
#endif
VARYING_BLOCK_END
#ifdef @VERTEX
VERTEX_MAIN(@drawVertexMain, Attrs, attrs, _vertexID, _instanceID)
{
ATTR_UNPACK(_vertexID, attrs, @a_triangleVertex, float3);
#ifdef @ATLAS_BLIT
VARYING_INIT(v_atlasCoord, float2);
#else
#endif
VARYING_INIT(v_pathID, ushort);
#ifdef @ATLAS_BLIT
VARYING_INIT(v_atlasCoord, float2);
#else
VARYING_INIT(v_windingWeight, half);
VARYING_INIT(v_coveragePlacement, uint2);
VARYING_INIT(v_coverageCoord, float2);
#endif
uint pathID;
float2 vertexPosition;
#ifdef @ATLAS_BLIT
vertexPosition =
unpack_atlas_coverage_vertex(@a_triangleVertex,
pathID,
v_atlasCoord VERTEX_CONTEXT_UNPACK);
#else
vertexPosition =
unpack_interior_triangle_vertex(@a_triangleVertex,
pathID,
v_windingWeight VERTEX_CONTEXT_UNPACK);
uint4 coverageData = STORAGE_BUFFER_LOAD4(@pathBuffer, pathID * 4u + 3u);
v_coveragePlacement = coverageData.xy;
v_coverageCoord = vertexPosition + uintBitsToFloat(coverageData.zw);
#endif
v_pathID = cast_uint_to_ushort(pathID);
float4 pos = RENDER_TARGET_COORD_TO_CLIP_COORD(vertexPosition);
VARYING_PACK(v_pathID);
#ifdef @ATLAS_BLIT
VARYING_PACK(v_atlasCoord);
#else
VARYING_PACK(v_windingWeight);
VARYING_PACK(v_coveragePlacement);
VARYING_PACK(v_coverageCoord);
#endif
EMIT_VERTEX(pos);
}
#endif // VERTEX
#endif // DRAW_INTERIOR_TRIANGLES
#ifdef @FRAGMENT
FRAG_STORAGE_BUFFER_BLOCK_BEGIN
STORAGE_BUFFER_U32x2(PAINT_BUFFER_IDX, PaintBuffer, @paintBuffer);
STORAGE_BUFFER_F32x4(PAINT_AUX_BUFFER_IDX, PaintAuxBuffer, @paintAuxBuffer);
@@ -304,59 +174,31 @@ INLINE void apply_fill_coverage(INOUT(float) paintAlpha,
FRAG_DATA_MAIN(half4, @drawFragmentMain)
{
VARYING_UNPACK(v_pathID, ushort);
#ifdef DRAW_PATH
VARYING_UNPACK(v_coverages, float4);
#elif defined(@ATLAS_BLIT)
VARYING_UNPACK(v_atlasCoord, float2);
VARYING_UNPACK(v_paint, float4);
#ifdef @DRAW_INTERIOR_TRIANGLES
VARYING_INIT(v_windingWeight, half);
#else
VARYING_UNPACK(v_windingWeight, half);
VARYING_INIT(v_coverages, COVERAGE_TYPE);
#endif //@DRAW_INTERIOR_TRIANGLES
VARYING_UNPACK(v_pathID, half);
#ifdef @ENABLE_CLIPPING
VARYING_UNPACK(v_clipIDs, half2);
#endif
#ifdef @ENABLE_CLIP_RECT
VARYING_UNPACK(v_clipRect, float4);
#endif
#ifdef @ENABLE_ADVANCED_BLEND
VARYING_UNPACK(v_blendMode, half);
#endif
#ifndef @ATLAS_BLIT
VARYING_UNPACK(v_coveragePlacement, uint2);
VARYING_UNPACK(v_coverageCoord, float2);
#endif
half4 paintColor;
uint pathID = v_pathID;
uint2 paintData = STORAGE_BUFFER_LOAD2(@paintBuffer, pathID);
uint paintType = paintData.x & 0xfu;
if (paintType <= SOLID_COLOR_PAINT_TYPE) // CLIP_UPDATE_PAINT_TYPE or
// SOLID_COLOR_PAINT_TYPE
#if defined(@DRAW_INTERIOR_TRIANGLES) && defined(@BORROWED_COVERAGE_PASS)
if (!@BORROWED_COVERAGE_PASS)
#endif
{
paintColor = unpackUnorm4x8(paintData.y);
}
else // LINEAR_GRADIENT_PAINT_TYPE,
// RADIAL_GRADIENT_PAINT_TYPE, or
// IMAGE_PAINT_TYPE
{
float2x2 M =
make_float2x2(STORAGE_BUFFER_LOAD4(@paintAuxBuffer, pathID * 4u));
float4 translate =
STORAGE_BUFFER_LOAD4(@paintAuxBuffer, pathID * 4u + 1u);
float2 paintCoord = MUL(M, _fragCoord) + translate.xy;
if (paintType != IMAGE_PAINT_TYPE)
{
float t = paintType == LINEAR_GRADIENT_PAINT_TYPE
? /*linear*/ paintCoord.x
: /*radial*/ length(paintCoord);
t = clamp(t, .0, 1.);
float x = t * translate.z + translate.w;
float y = uintBitsToFloat(paintData.y);
paintColor =
TEXTURE_SAMPLE_LOD(@gradTexture, gradSampler, float2(x, y), .0);
}
else
{
float opacity = uintBitsToFloat(paintData.y);
float lod = translate.z;
paintColor = TEXTURE_SAMPLE_LOD(@imageTexture,
imageSampler,
paintCoord,
lod);
paintColor =
make_half4(unmultiply_rgb(paintColor), paintColor.a * opacity);
}
paintColor = find_paint_color(v_paint, 1. FRAGMENT_CONTEXT_UNPACK);
}
if (paintColor.a == .0)
@@ -364,11 +206,13 @@ FRAG_DATA_MAIN(half4, @drawFragmentMain)
discard;
}
#ifdef @ATLAS_BLIT
paintColor.a *= filter_feather_atlas(
v_atlasCoord,
uniforms.atlasTextureInverseSize TEXTURE_CONTEXT_FORWARD);
half fragCoverage =
#ifdef @DRAW_INTERIOR_TRIANGLES
v_windingWeight;
#else
find_frag_coverage(v_coverages);
#endif
// Swizzle the coverage buffer in a tiled format, starting with 32x32
// row-major tiles.
uint coverageIndex = v_coveragePlacement.x;
@@ -385,24 +229,7 @@ FRAG_DATA_MAIN(half4, @drawFragmentMain)
#ifdef @BORROWED_COVERAGE_PASS
if (@BORROWED_COVERAGE_PASS)
{
#ifdef @DRAW_INTERIOR_TRIANGLES
half borrowedCoverage = -v_windingWeight;
#else
half fragCoverage;
#ifdef @ENABLE_FEATHER
if (@ENABLE_FEATHER && is_feathered_fill(v_coverages))
{
fragCoverage =
eval_feathered_fill(v_coverages TEXTURE_CONTEXT_FORWARD);
}
else
#endif
{
fragCoverage = v_coverages.x;
}
half borrowedCoverage = max(-fragCoverage, .0);
#endif
apply_borrowed_coverage(borrowedCoverage, coverageIndex);
apply_borrowed_coverage(-fragCoverage, coverageIndex);
discard;
}
#endif // BORROWED_COVERAGE_PASS
@@ -410,45 +237,16 @@ FRAG_DATA_MAIN(half4, @drawFragmentMain)
#ifndef @DRAW_INTERIOR_TRIANGLES
if (is_stroke(v_coverages))
{
half fragCoverage;
#ifdef @ENABLE_FEATHER
if (@ENABLE_FEATHER && is_feathered_stroke(v_coverages))
{
fragCoverage =
eval_feathered_stroke(v_coverages TEXTURE_CONTEXT_FORWARD);
}
else
#endif
{
fragCoverage = min(v_coverages.x, v_coverages.y);
}
fragCoverage = clamp(fragCoverage, .0, 1.);
apply_stroke_coverage(paintColor.a, fragCoverage, coverageIndex);
}
else // It's a fill.
#endif // !DRAW_INTERIOR_TRIANGLES
#endif // !DRAW_INTERIOR_TRIANGLES
{
#ifdef @DRAW_INTERIOR_TRIANGLES
half fragCoverage = v_windingWeight;
#else
half fragCoverage;
#ifdef @ENABLE_FEATHER
if (@ENABLE_FEATHER && is_feathered_fill(v_coverages))
{
fragCoverage =
eval_feathered_fill(v_coverages TEXTURE_CONTEXT_FORWARD);
}
else
#endif
{
fragCoverage = v_coverages.x;
}
fragCoverage = clamp(fragCoverage, .0, 1.);
#endif
apply_fill_coverage(paintColor.a, fragCoverage, coverageIndex);
}
#endif // @ATLAS_BLIT
EMIT_FRAG_DATA(paintColor);
}
#endif // FRAGMENT

View File

@@ -4,13 +4,20 @@
#ifdef @FRAGMENT
#if defined(@FIXED_FUNCTION_COLOR_OUTPUT) && !defined(@ENABLE_CLIPPING)
// This is a basic fragment shader for non-msaa, non-path objects, e.g., image
// meshes, atlas blits.
// These objects are simple in that they can write their fragments out directly,
// without having to cooperate with overlapping fragments to work out coverage.
#if (defined(@FIXED_FUNCTION_COLOR_OUTPUT) && !defined(@ENABLE_CLIPPING)) || \
defined(@RENDER_MODE_CLOCKWISE_ATOMIC)
// @FIXED_FUNCTION_COLOR_OUTPUT without clipping can skip the interlock.
#undef NEEDS_INTERLOCK
#else
#define NEEDS_INTERLOCK
#endif
#ifndef @RENDER_MODE_CLOCKWISE_ATOMIC
PLS_BLOCK_BEGIN
#ifndef @FIXED_FUNCTION_COLOR_OUTPUT
PLS_DECL4F(COLOR_PLANE_IDX, colorBuffer);
@@ -21,6 +28,7 @@ PLS_DECL4F(SCRATCH_COLOR_PLANE_IDX, scratchColorBuffer);
#endif
PLS_DECLUI(COVERAGE_PLANE_IDX, coverageBuffer);
PLS_BLOCK_END
#endif // !@RENDER_MODE_CLOCKWISE_ATOMIC
// ATLAS_BLIT includes draw_path_common.glsl, which declares the textures &
// samplers, so we only need to declare these for image meshes.
@@ -97,7 +105,7 @@ PLS_MAIN(@drawFragmentMain)
PLS_INTERLOCK_BEGIN;
#endif
#ifdef @ENABLE_CLIPPING
#if defined(@ENABLE_CLIPPING) && !defined(@RENDER_MODE_CLOCKWISE_ATOMIC)
if (@ENABLE_CLIPPING && v_clipID != .0)
{
half2 clipData = unpackHalf2x16(PLS_LOADUI(clipBuffer));
@@ -114,7 +122,8 @@ PLS_MAIN(@drawFragmentMain)
coverage *= imageDrawUniforms.opacity;
#endif
#ifndef @FIXED_FUNCTION_COLOR_OUTPUT
#if !defined(@FIXED_FUNCTION_COLOR_OUTPUT) && \
!defined(@RENDER_MODE_CLOCKWISE_ATOMIC)
half4 dstColorPremul = PLS_LOAD4F(colorBuffer);
#ifdef @ENABLE_ADVANCED_BLEND
if (@ENABLE_ADVANCED_BLEND)
@@ -162,10 +171,12 @@ PLS_MAIN(@drawFragmentMain)
#endif
PLS_STORE4F(colorBuffer, dstColorPremul * (1. - color.a) + color);
#endif // !@FIXED_FUNCTION_COLOR_OUTPUT
#endif // !@FIXED_FUNCTION_COLOR_OUTPUT && !@RENDER_MODE_CLOCKWISE_ATOMIC
#ifndef @RENDER_MODE_CLOCKWISE_ATOMIC
PLS_PRESERVE_UI(clipBuffer);
PLS_PRESERVE_UI(coverageBuffer);
#endif
#ifdef NEEDS_INTERLOCK
PLS_INTERLOCK_END;
#endif

View File

@@ -5,7 +5,12 @@
// undef GENERATE_PREMULTIPLIED_PAINT_COLORS first because this file gets
// included multiple times with different defines in the Metal library.
#undef GENERATE_PREMULTIPLIED_PAINT_COLORS
#ifdef @ENABLE_ADVANCED_BLEND
#ifdef @NEVER_GENERATE_PREMULTIPLIED_PAINT_COLORS
// The specific fragment shader we're being compiled for expects un-multiplied
// paint colors all the time.
#define GENERATE_PREMULTIPLIED_PAINT_COLORS false
#elif defined(@ENABLE_ADVANCED_BLEND)
// If advanced blend is enabled, we generate unmultiplied paint colors in the
// shader. Otherwise we would have to just turn around and unmultiply them in
// order to run the blend equation.
@@ -65,6 +70,12 @@ NO_PERSPECTIVE VARYING(5, float4, v_clipRect);
#ifdef @ENABLE_ADVANCED_BLEND
@OPTIONALLY_FLAT VARYING(6, half, v_blendMode);
#endif
#ifdef @RENDER_MODE_CLOCKWISE_ATOMIC
FLAT VARYING(7, uint2, v_coveragePlacement);
VARYING(8, float2, v_coverageCoord);
#endif
VARYING_BLOCK_END
#ifdef @VERTEX
@@ -103,6 +114,10 @@ VERTEX_MAIN(@drawVertexMain, Attrs, attrs, _vertexID, _instanceID)
#ifdef @ENABLE_ADVANCED_BLEND
VARYING_INIT(v_blendMode, half);
#endif
#ifdef @RENDER_MODE_CLOCKWISE_ATOMIC
VARYING_INIT(v_coveragePlacement, uint2);
VARYING_INIT(v_coverageCoord, float2);
#endif
bool shouldDiscardVertex = false;
uint pathID;
@@ -308,6 +323,11 @@ VERTEX_MAIN(@drawVertexMain, Attrs, attrs, _vertexID, _instanceID)
#endif
#ifdef @RENDER_MODE_MSAA
pos.z = normalize_z_index(pathZIndex);
#elif defined(@RENDER_MODE_CLOCKWISE_ATOMIC)
uint4 coverageData =
STORAGE_BUFFER_LOAD4(@pathBuffer, pathID * 4u + 3u);
v_coveragePlacement = coverageData.xy;
v_coverageCoord = vertexPosition + uintBitsToFloat(coverageData.zw);
#endif
}
else
@@ -342,6 +362,10 @@ VERTEX_MAIN(@drawVertexMain, Attrs, attrs, _vertexID, _instanceID)
#endif
#ifdef @ENABLE_ADVANCED_BLEND
VARYING_PACK(v_blendMode);
#endif
#ifdef @RENDER_MODE_CLOCKWISE_ATOMIC
VARYING_PACK(v_coveragePlacement);
VARYING_PACK(v_coverageCoord);
#endif
EMIT_VERTEX(pos);
}

View File

@@ -90,7 +90,7 @@ def emit_shader(out, shader_type, draw_type, fill_type, feature_set):
out.write('{\n')
out.write('#include "draw_path.minified.vert"\n')
if ATLAS_BLIT in feature_set:
out.write('#include "draw_raster_order_mesh.minified.frag"\n')
out.write('#include "draw_mesh.minified.frag"\n')
else:
out.write('#include "draw_raster_order_path.minified.frag"\n')
out.write('}\n')
@@ -101,7 +101,7 @@ def emit_shader(out, shader_type, draw_type, fill_type, feature_set):
out.write('namespace m%s\n' % ''.join(namespace_id))
out.write('{\n')
out.write('#include "draw_image_mesh.minified.vert"\n')
out.write('#include "draw_raster_order_mesh.minified.frag"\n')
out.write('#include "draw_mesh.minified.frag"\n')
out.write('}\n')
out.write('#undef DRAW_IMAGE_MESH\n')
out.write('#undef DRAW_IMAGE\n')

View File

@@ -10,4 +10,4 @@
#include "draw_path_common.minified.glsl"
#include "advanced_blend.minified.glsl"
#include "draw_path.minified.vert"
#include "draw_raster_order_mesh.minified.frag"
#include "draw_mesh.minified.frag"

View File

@@ -11,4 +11,4 @@
#include "draw_path_common.minified.glsl"
#include "advanced_blend.minified.glsl"
#include "draw_path.minified.vert"
#include "draw_raster_order_mesh.minified.frag"
#include "draw_mesh.minified.frag"

View File

@@ -1,13 +1,15 @@
#version 460
#extension GL_GOOGLE_include_directive : require
#extension GL_EXT_samplerless_texture_functions : require
#define ENABLE_INSTANCE_INDEX
#define OPTIONALLY_FLAT flat
#define DRAW_INTERIOR_TRIANGLES
#define ATLAS_BLIT
#define RENDER_MODE_CLOCKWISE_ATOMIC
#include "glsl.minified.glsl"
#include "constants.minified.glsl"
#include "specialization.minified.glsl"
#include "common.minified.glsl"
#include "draw_path_common.minified.glsl"
#include "advanced_blend.minified.glsl"
#include "draw_clockwise_atomic_path.minified.glsl"
#include "draw_path.minified.vert"
#include "draw_mesh.minified.frag"

View File

@@ -4,9 +4,12 @@
#define ENABLE_INSTANCE_INDEX
#define OPTIONALLY_FLAT flat
#define DRAW_IMAGE
#define DRAW_IMAGE_MESH
#define RENDER_MODE_CLOCKWISE_ATOMIC
#include "glsl.minified.glsl"
#include "constants.minified.glsl"
#include "specialization.minified.glsl"
#include "common.minified.glsl"
#include "advanced_blend.minified.glsl"
#include "draw_clockwise_atomic_image_mesh.minified.glsl"
#include "draw_image_mesh.minified.vert"
#include "draw_mesh.minified.frag"

View File

@@ -3,10 +3,13 @@
#extension GL_EXT_samplerless_texture_functions : require
#define OPTIONALLY_FLAT flat
#define DRAW_INTERIOR_TRIANGLES
#define RENDER_MODE_CLOCKWISE_ATOMIC
#define NEVER_GENERATE_PREMULTIPLIED_PAINT_COLORS
#include "glsl.minified.glsl"
#include "constants.minified.glsl"
#include "specialization.minified.glsl"
#include "common.minified.glsl"
#include "draw_path_common.minified.glsl"
#include "advanced_blend.minified.glsl"
#include "draw_clockwise_atomic_path.minified.glsl"
#include "draw_path.minified.vert"
#include "draw_clockwise_atomic_path.minified.frag"

View File

@@ -4,10 +4,13 @@
#define ENABLE_INSTANCE_INDEX
#define OPTIONALLY_FLAT flat
#define DRAW_PATH
#define RENDER_MODE_CLOCKWISE_ATOMIC
#define NEVER_GENERATE_PREMULTIPLIED_PAINT_COLORS
#include "glsl.minified.glsl"
#include "constants.minified.glsl"
#include "specialization.minified.glsl"
#include "common.minified.glsl"
#include "draw_path_common.minified.glsl"
#include "advanced_blend.minified.glsl"
#include "draw_clockwise_atomic_path.minified.glsl"
#include "draw_path.minified.vert"
#include "draw_clockwise_atomic_path.minified.frag"

View File

@@ -10,4 +10,4 @@
#include "common.minified.glsl"
#include "advanced_blend.minified.glsl"
#include "draw_image_mesh.minified.vert"
#include "draw_raster_order_mesh.minified.frag"
#include "draw_mesh.minified.frag"

View File

@@ -10,4 +10,4 @@
#include "common.minified.glsl"
#include "advanced_blend.minified.glsl"
#include "draw_image_mesh.minified.vert"
#include "draw_raster_order_mesh.minified.frag"
#include "draw_mesh.minified.frag"

View File

@@ -15,4 +15,4 @@
#include "Generated/common.minified.ush"
#include "Generated/advanced_blend.minified.ush"
#include "Generated/draw_image_mesh.minified.vert.ush"
#include "Generated/draw_raster_order_mesh.minified.frag.ush"
#include "Generated/draw_mesh.minified.frag.ush"

View File

@@ -71,7 +71,6 @@ static VkBlendOp vk_blend_op(gpu::BlendEquation equation)
{
case gpu::BlendEquation::none:
case gpu::BlendEquation::srcOver:
return VK_BLEND_OP_ADD;
case gpu::BlendEquation::plus:
return VK_BLEND_OP_ADD;
case gpu::BlendEquation::max:
@@ -357,7 +356,12 @@ DrawPipelineVulkan::DrawPipelineVulkan(
{
// Forward coverage clockwise draws are all unmultiplied src-over.
blendEquation = gpu::BlendEquation::srcOver;
blendEquationPremultiplied = false;
// FIXME: clockwiseAtomic paths should be updated to use
// premultiplied alpha.
const bool isClockwiseAtomicPathDraw =
!gpu::DrawTypeIsImageDraw(props.drawType) &&
props.drawType != gpu::DrawType::atlasBlit;
blendEquationPremultiplied = !isClockwiseAtomicPathDraw;
}
}

View File

@@ -239,12 +239,14 @@ DrawShaderVulkan::DrawShaderVulkan(Type type,
case DrawType::atlasBlit:
vertCode = spirv::draw_clockwise_atomic_atlas_blit_vert;
fragCode = spirv::draw_clockwise_atomic_atlas_blit_frag;
fragCode =
spirv::draw_clockwise_atomic_atlas_blit_fixedcolor_frag;
break;
case DrawType::imageMesh:
vertCode = spirv::draw_clockwise_atomic_image_mesh_vert;
fragCode = spirv::draw_clockwise_atomic_image_mesh_frag;
fragCode =
spirv::draw_clockwise_atomic_image_mesh_fixedcolor_frag;
break;
case DrawType::imageRect:

View File

@@ -77,9 +77,9 @@ namespace embedded
#include "generated/shaders/spirv/draw_clockwise_atomic_interior_triangles.vert.h"
#include "generated/shaders/spirv/draw_clockwise_atomic_interior_triangles.frag.h"
#include "generated/shaders/spirv/draw_clockwise_atomic_atlas_blit.vert.h"
#include "generated/shaders/spirv/draw_clockwise_atomic_atlas_blit.frag.h"
#include "generated/shaders/spirv/draw_clockwise_atomic_atlas_blit.fixedcolor_frag.h"
#include "generated/shaders/spirv/draw_clockwise_atomic_image_mesh.vert.h"
#include "generated/shaders/spirv/draw_clockwise_atomic_image_mesh.frag.h"
#include "generated/shaders/spirv/draw_clockwise_atomic_image_mesh.fixedcolor_frag.h"
// InterlockMode::msaa shaders.
#include "generated/shaders/spirv/draw_msaa_path.vert.h"
@@ -228,12 +228,12 @@ rive::Span<const uint32_t> draw_clockwise_atomic_interior_triangles_frag =
rive::make_span(embedded::draw_clockwise_atomic_interior_triangles_frag);
rive::Span<const uint32_t> draw_clockwise_atomic_atlas_blit_vert =
rive::make_span(embedded::draw_clockwise_atomic_atlas_blit_vert);
rive::Span<const uint32_t> draw_clockwise_atomic_atlas_blit_frag =
rive::make_span(embedded::draw_clockwise_atomic_atlas_blit_frag);
rive::Span<const uint32_t> draw_clockwise_atomic_atlas_blit_fixedcolor_frag =
rive::make_span(embedded::draw_clockwise_atomic_atlas_blit_fixedcolor_frag);
rive::Span<const uint32_t> draw_clockwise_atomic_image_mesh_vert =
rive::make_span(embedded::draw_clockwise_atomic_image_mesh_vert);
rive::Span<const uint32_t> draw_clockwise_atomic_image_mesh_frag =
rive::make_span(embedded::draw_clockwise_atomic_image_mesh_frag);
rive::Span<const uint32_t> draw_clockwise_atomic_image_mesh_fixedcolor_frag =
rive::make_span(embedded::draw_clockwise_atomic_image_mesh_fixedcolor_frag);
// InterlockMode::msaa shaders.
rive::Span<const uint32_t> draw_msaa_path_vert =
@@ -352,9 +352,11 @@ void hotload_shaders(rive::Span<const uint32_t> spirvData)
spirv::draw_clockwise_atomic_interior_triangles_frag =
readNextBytecodeSpan();
spirv::draw_clockwise_atomic_atlas_blit_vert = readNextBytecodeSpan();
spirv::draw_clockwise_atomic_atlas_blit_frag = readNextBytecodeSpan();
spirv::draw_clockwise_atomic_atlas_blit_fixedcolor_frag =
readNextBytecodeSpan();
spirv::draw_clockwise_atomic_image_mesh_vert = readNextBytecodeSpan();
spirv::draw_clockwise_atomic_image_mesh_frag = readNextBytecodeSpan();
spirv::draw_clockwise_atomic_image_mesh_fixedcolor_frag =
readNextBytecodeSpan();
spirv::draw_msaa_path_vert = readNextBytecodeSpan();
spirv::draw_msaa_path_noclipdistance_vert = readNextBytecodeSpan();

View File

@@ -79,9 +79,11 @@ extern rive::Span<const uint32_t> draw_clockwise_atomic_path_frag;
extern rive::Span<const uint32_t> draw_clockwise_atomic_interior_triangles_vert;
extern rive::Span<const uint32_t> draw_clockwise_atomic_interior_triangles_frag;
extern rive::Span<const uint32_t> draw_clockwise_atomic_atlas_blit_vert;
extern rive::Span<const uint32_t> draw_clockwise_atomic_atlas_blit_frag;
extern rive::Span<const uint32_t>
draw_clockwise_atomic_atlas_blit_fixedcolor_frag;
extern rive::Span<const uint32_t> draw_clockwise_atomic_image_mesh_vert;
extern rive::Span<const uint32_t> draw_clockwise_atomic_image_mesh_frag;
extern rive::Span<const uint32_t>
draw_clockwise_atomic_image_mesh_fixedcolor_frag;
// InterlockMode::msaa shaders.
extern rive::Span<const uint32_t> draw_msaa_path_vert;

View File

@@ -232,7 +232,7 @@ static wgpu::ShaderModule compile_shader_module_spirv(wgpu::Device device,
#include "generated/shaders/draw_clockwise_path.frag.hpp"
#include "generated/shaders/draw_clockwise_clip.frag.hpp"
#include "generated/shaders/draw_image_mesh.vert.hpp"
#include "generated/shaders/draw_raster_order_mesh.frag.hpp"
#include "generated/shaders/draw_mesh.frag.hpp"
// When compiling "glslRaw" shaders, the WebGPU driver will automatically search
// for a uniform with this name and update its value when draw commands have a
@@ -1054,11 +1054,11 @@ public:
case DrawType::atlasBlit:
glsl << gpu::glsl::draw_path_common << '\n';
glsl << gpu::glsl::draw_path_vert << '\n';
glsl << gpu::glsl::draw_raster_order_mesh_frag << '\n';
glsl << gpu::glsl::draw_mesh_frag << '\n';
break;
case DrawType::imageMesh:
glsl << gpu::glsl::draw_image_mesh_vert << '\n';
glsl << gpu::glsl::draw_raster_order_mesh_frag << '\n';
glsl << gpu::glsl::draw_mesh_frag << '\n';
break;
case DrawType::imageRect:
case DrawType::msaaStrokes: