blob: d5d98399540d9a6f53e4c5af52533533503ea564 [file] [log] [blame]
/*
* Copyright 2023 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);
#ifdef @ENABLE_CLIPPING
@OPTIONALLY_FLAT VARYING(1, half, v_clipID);
#endif
#ifdef @ENABLE_CLIP_RECT
NO_PERSPECTIVE VARYING(2, float4, v_clipRect);
#endif
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);
#ifdef @ENABLE_CLIPPING
VARYING_INIT(v_clipID, half);
#endif
#ifdef @ENABLE_CLIP_RECT
VARYING_INIT(v_clipRect, float4);
#endif
float2 vertexPosition =
MUL(make_float2x2(imageDrawUniforms.viewMatrix), @a_position) +
imageDrawUniforms.translate;
v_texCoord = @a_texCoord;
#ifdef @ENABLE_CLIPPING
if (@ENABLE_CLIPPING)
{
v_clipID = id_bits_to_f16(imageDrawUniforms.clipID,
uniforms.pathIDGranularity);
}
#endif
#ifdef @ENABLE_CLIP_RECT
if (@ENABLE_CLIP_RECT)
{
#ifndef @RENDER_MODE_MSAA
v_clipRect = find_clip_rect_coverage_distances(
make_float2x2(imageDrawUniforms.clipRectInverseMatrix),
imageDrawUniforms.clipRectInverseTranslate,
vertexPosition);
#else // RENDER_MODE_MSAA
set_clip_rect_plane_distances(
make_float2x2(imageDrawUniforms.clipRectInverseMatrix),
imageDrawUniforms.clipRectInverseTranslate,
vertexPosition);
#endif // RENDER_MODE_MSAA
}
#endif // ENABLE_CLIP_RECT
float4 pos = RENDER_TARGET_COORD_TO_CLIP_COORD(vertexPosition);
#ifdef @RENDER_MODE_MSAA
pos.z = normalize_z_index(imageDrawUniforms.zIndex);
#endif
VARYING_PACK(v_texCoord);
#ifdef @ENABLE_CLIPPING
VARYING_PACK(v_clipID);
#endif
#ifdef @ENABLE_CLIP_RECT
VARYING_PACK(v_clipRect);
#endif
EMIT_VERTEX(pos);
}
#endif
#ifdef @FRAGMENT
FRAG_TEXTURE_BLOCK_BEGIN
TEXTURE_RGBA8(PER_DRAW_BINDINGS_SET, IMAGE_TEXTURE_IDX, @imageTexture);
#ifdef @RENDER_MODE_MSAA
#ifdef @ENABLE_ADVANCED_BLEND
TEXTURE_RGBA8(PER_FLUSH_BINDINGS_SET, DST_COLOR_TEXTURE_IDX, @dstColorTexture);
#endif
#endif
FRAG_TEXTURE_BLOCK_END
SAMPLER_MIPMAP(IMAGE_TEXTURE_IDX, imageSampler)
FRAG_STORAGE_BUFFER_BLOCK_BEGIN
FRAG_STORAGE_BUFFER_BLOCK_END
#ifndef @RENDER_MODE_MSAA
PLS_BLOCK_BEGIN
PLS_DECL4F(COLOR_PLANE_IDX, colorBuffer);
PLS_DECLUI(CLIP_PLANE_IDX, clipBuffer);
PLS_DECL4F(SCRATCH_COLOR_PLANE_IDX, scratchColorBuffer);
PLS_DECLUI(COVERAGE_PLANE_IDX, coverageCountBuffer);
PLS_BLOCK_END
PLS_MAIN_WITH_IMAGE_UNIFORMS(@drawFragmentMain)
{
VARYING_UNPACK(v_texCoord, float2);
#ifdef @ENABLE_CLIPPING
VARYING_UNPACK(v_clipID, half);
#endif
#ifdef @ENABLE_CLIP_RECT
VARYING_UNPACK(v_clipRect, float4);
#endif
half4 color = TEXTURE_SAMPLE(@imageTexture, imageSampler, v_texCoord);
half coverage = 1.;
#ifdef @ENABLE_CLIP_RECT
if (@ENABLE_CLIP_RECT)
{
half clipRectCoverage = min_value(cast_float4_to_half4(v_clipRect));
coverage = clamp(clipRectCoverage, make_half(.0), coverage);
}
#endif
PLS_INTERLOCK_BEGIN;
#ifdef @ENABLE_CLIPPING
if (@ENABLE_CLIPPING && v_clipID != .0)
{
half2 clipData = unpackHalf2x16(PLS_LOADUI(clipBuffer));
half clipContentID = clipData.g;
half clipCoverage =
clipContentID == v_clipID ? clipData.r : make_half(.0);
coverage = min(coverage, clipCoverage);
}
#endif
// Blend with the framebuffer color.
color.a *= imageDrawUniforms.opacity * coverage;
half4 dstColor = PLS_LOAD4F(colorBuffer);
#ifdef @ENABLE_ADVANCED_BLEND
if (@ENABLE_ADVANCED_BLEND && imageDrawUniforms.blendMode != BLEND_SRC_OVER)
{
color =
advanced_blend(color,
unmultiply(dstColor),
cast_uint_to_ushort(imageDrawUniforms.blendMode));
}
else
#endif
{
color.rgb *= color.a;
color = color + dstColor * (1. - color.a);
}
PLS_STORE4F(colorBuffer, color);
PLS_PRESERVE_UI(clipBuffer);
PLS_PRESERVE_UI(coverageCountBuffer);
PLS_INTERLOCK_END;
EMIT_PLS;
}
#else // RENDER_MODE_MSAA
FRAG_DATA_MAIN(half4, @drawFragmentMain)
{
VARYING_UNPACK(v_texCoord, float2);
half4 color = TEXTURE_SAMPLE(@imageTexture, imageSampler, v_texCoord);
color.a *= imageDrawUniforms.opacity;
#ifdef @ENABLE_ADVANCED_BLEND
if (@ENABLE_ADVANCED_BLEND)
{
half4 dstColor =
TEXEL_FETCH(@dstColorTexture, int2(floor(_fragCoord.xy)));
color = advanced_blend(color,
unmultiply(dstColor),
imageDrawUniforms.blendMode);
}
else
#endif // !ENABLE_ADVANCED_BLEND
{
color = premultiply(color);
}
EMIT_FRAG_DATA(color);
}
#endif // RENDER_MODE_MSAA
#endif // FRAGMENT