From d3d085de154961a867c8f5f2102d72733ab5f05e Mon Sep 17 00:00:00 2001 From: Hermet Park Date: Wed, 20 Nov 2024 17:23:25 +0900 Subject: [PATCH] renderer: code refactoring - introduced RenderColor - internal name changes to avoid conflicts --- src/renderer/gl_engine/tvgGlRenderer.cpp | 27 ++--- src/renderer/gl_engine/tvgGlRenderer.h | 2 +- src/renderer/sw_engine/tvgSwCommon.h | 4 +- src/renderer/sw_engine/tvgSwRaster.cpp | 124 ++++++++++---------- src/renderer/sw_engine/tvgSwRasterAvx.h | 20 ++-- src/renderer/sw_engine/tvgSwRasterC.h | 20 ++-- src/renderer/sw_engine/tvgSwRasterNeon.h | 20 ++-- src/renderer/sw_engine/tvgSwRenderer.cpp | 23 ++-- src/renderer/tvgRender.h | 28 +++-- src/renderer/tvgShape.cpp | 8 +- src/renderer/tvgShape.h | 17 +-- src/renderer/wg_engine/tvgWgRenderData.cpp | 8 +- src/renderer/wg_engine/tvgWgRenderData.h | 2 +- src/renderer/wg_engine/tvgWgRenderer.cpp | 2 +- src/renderer/wg_engine/tvgWgShaderTypes.cpp | 12 +- src/renderer/wg_engine/tvgWgShaderTypes.h | 4 +- 16 files changed, 154 insertions(+), 167 deletions(-) diff --git a/src/renderer/gl_engine/tvgGlRenderer.cpp b/src/renderer/gl_engine/tvgGlRenderer.cpp index 7e6887a0..c1d211a4 100644 --- a/src/renderer/gl_engine/tvgGlRenderer.cpp +++ b/src/renderer/gl_engine/tvgGlRenderer.cpp @@ -119,7 +119,7 @@ void GlRenderer::initShaders() } -void GlRenderer::drawPrimitive(GlShape& sdata, uint8_t r, uint8_t g, uint8_t b, uint8_t a, RenderUpdateFlag flag, int32_t depth) +void GlRenderer::drawPrimitive(GlShape& sdata, const RenderColor& c, RenderUpdateFlag flag, int32_t depth) { auto vp = currentPass()->getViewport(); auto bbox = sdata.geometry->getViewport(); @@ -159,7 +159,7 @@ void GlRenderer::drawPrimitive(GlShape& sdata, uint8_t r, uint8_t g, uint8_t b, stencilTask->setDrawDepth(depth); } - a = MULTIPLY(a, sdata.opacity); + auto a = MULTIPLY(c.a, sdata.opacity); if (flag & RenderUpdateFlag::Stroke) { float strokeWidth = sdata.rshape->strokeWidth() * sdata.geometry->getTransformMatrix().e11; @@ -195,7 +195,7 @@ void GlRenderer::drawPrimitive(GlShape& sdata, uint8_t r, uint8_t g, uint8_t b, } // color - float color[4] = {r / 255.f, g / 255.f, b / 255.f, a / 255.f}; + float color[] = {c.r / 255.f, c.g / 255.f, c.b / 255.f, c.a / 255.f}; task->addBindResource(GlBindingResource{ 1, @@ -1104,7 +1104,6 @@ bool GlRenderer::renderShape(RenderData data) if (bbox.w <= 0 || bbox.h <= 0) return true; - uint8_t r = 0, g = 0, b = 0, a = 0; int32_t drawDepth1 = 0, drawDepth2 = 0; size_t flags = static_cast(sdata->updateFlag); @@ -1122,13 +1121,7 @@ bool GlRenderer::renderShape(RenderData data) { auto gradient = sdata->rshape->fill; if (gradient) drawPrimitive(*sdata, gradient, RenderUpdateFlag::Gradient, drawDepth1); - else { - sdata->rshape->fillColor(&r, &g, &b, &a); - if (a > 0) - { - drawPrimitive(*sdata, r, g, b, a, RenderUpdateFlag::Color, drawDepth1); - } - } + else if (sdata->rshape->color.a > 0) drawPrimitive(*sdata, sdata->rshape->color, RenderUpdateFlag::Color, drawDepth1); } if (flags & (RenderUpdateFlag::Stroke | RenderUpdateFlag::GradientStroke)) @@ -1136,11 +1129,8 @@ bool GlRenderer::renderShape(RenderData data) auto gradient = sdata->rshape->strokeFill(); if (gradient) { drawPrimitive(*sdata, gradient, RenderUpdateFlag::GradientStroke, drawDepth2); - } else { - if (sdata->rshape->strokeFill(&r, &g, &b, &a) && a > 0) - { - drawPrimitive(*sdata, r, g, b, a, RenderUpdateFlag::Stroke, drawDepth2); - } + } else if (sdata->rshape->stroke && sdata->rshape->stroke->color.a > 0) { + drawPrimitive(*sdata, sdata->rshape->stroke->color, RenderUpdateFlag::Stroke, drawDepth2); } } @@ -1236,9 +1226,8 @@ RenderData GlRenderer::prepare(const RenderShape& rshape, RenderData data, const sdata->opacity = opacity; //invisible? - uint8_t alphaF = 0, alphaS = 0; - rshape.fillColor(nullptr, nullptr, nullptr, &alphaF); - rshape.strokeFill(nullptr, nullptr, nullptr, &alphaS); + auto alphaF = rshape.color.a; + auto alphaS = rshape.stroke ? rshape.stroke->color.a : 0; if ( ((flags & RenderUpdateFlag::Gradient) == 0) && ((flags & RenderUpdateFlag::Color) && alphaF == 0) && diff --git a/src/renderer/gl_engine/tvgGlRenderer.h b/src/renderer/gl_engine/tvgGlRenderer.h index 26100e3a..f814f1e0 100644 --- a/src/renderer/gl_engine/tvgGlRenderer.h +++ b/src/renderer/gl_engine/tvgGlRenderer.h @@ -99,7 +99,7 @@ private: ~GlRenderer(); void initShaders(); - void drawPrimitive(GlShape& sdata, uint8_t r, uint8_t g, uint8_t b, uint8_t a, RenderUpdateFlag flag, int32_t depth); + void drawPrimitive(GlShape& sdata, const RenderColor& c, RenderUpdateFlag flag, int32_t depth); void drawPrimitive(GlShape& sdata, const Fill* fill, RenderUpdateFlag flag, int32_t depth); void drawClip(Array& clips); diff --git a/src/renderer/sw_engine/tvgSwCommon.h b/src/renderer/sw_engine/tvgSwCommon.h index 825bf3cf..f7cdf444 100644 --- a/src/renderer/sw_engine/tvgSwCommon.h +++ b/src/renderer/sw_engine/tvgSwCommon.h @@ -558,9 +558,9 @@ void mpoolRetDashOutline(SwMpool* mpool, unsigned idx); bool rasterCompositor(SwSurface* surface); bool rasterGradientShape(SwSurface* surface, SwShape* shape, const Fill* fdata, uint8_t opacity); -bool rasterShape(SwSurface* surface, SwShape* shape, uint8_t r, uint8_t g, uint8_t b, uint8_t a); +bool rasterShape(SwSurface* surface, SwShape* shape, RenderColor& c); bool rasterImage(SwSurface* surface, SwImage* image, const Matrix& transform, const SwBBox& bbox, uint8_t opacity); -bool rasterStroke(SwSurface* surface, SwShape* shape, uint8_t r, uint8_t g, uint8_t b, uint8_t a); +bool rasterStroke(SwSurface* surface, SwShape* shape, RenderColor& c); bool rasterGradientStroke(SwSurface* surface, SwShape* shape, const Fill* fdata, uint8_t opacity); bool rasterClear(SwSurface* surface, uint32_t x, uint32_t y, uint32_t w, uint32_t h, pixel_t val = 0); void rasterPixel32(uint32_t *dst, uint32_t val, uint32_t offset, int32_t len); diff --git a/src/renderer/sw_engine/tvgSwRaster.cpp b/src/renderer/sw_engine/tvgSwRaster.cpp index 944a361c..b556bb8e 100644 --- a/src/renderer/sw_engine/tvgSwRaster.cpp +++ b/src/renderer/sw_engine/tvgSwRaster.cpp @@ -324,7 +324,7 @@ static uint32_t _interpDownScaler(const uint32_t *img, uint32_t stride, uint32_t /* Rect */ /************************************************************************/ -static bool _rasterCompositeMaskedRect(SwSurface* surface, const SwBBox& region, SwMask maskOp, uint8_t r, uint8_t g, uint8_t b, uint8_t a) +static bool _rasterCompositeMaskedRect(SwSurface* surface, const SwBBox& region, SwMask maskOp, uint8_t a) { auto w = static_cast(region.max.x - region.min.x); auto h = static_cast(region.max.y - region.min.y); @@ -343,7 +343,7 @@ static bool _rasterCompositeMaskedRect(SwSurface* surface, const SwBBox& region, } -static bool _rasterDirectMaskedRect(SwSurface* surface, const SwBBox& region, SwMask maskOp, uint8_t r, uint8_t g, uint8_t b, uint8_t a) +static bool _rasterDirectMaskedRect(SwSurface* surface, const SwBBox& region, SwMask maskOp, uint8_t a) { auto w = static_cast(region.max.x - region.min.x); auto h = static_cast(region.max.y - region.min.y); @@ -364,7 +364,7 @@ static bool _rasterDirectMaskedRect(SwSurface* surface, const SwBBox& region, Sw } -static bool _rasterMaskedRect(SwSurface* surface, const SwBBox& region, uint8_t r, uint8_t g, uint8_t b, uint8_t a) +static bool _rasterMaskedRect(SwSurface* surface, const SwBBox& region, const RenderColor& c) { //8bit masking channels composition if (surface->channelSize != sizeof(uint8_t)) return false; @@ -372,13 +372,13 @@ static bool _rasterMaskedRect(SwSurface* surface, const SwBBox& region, uint8_t TVGLOG("SW_ENGINE", "Masked(%d) Rect [Region: %lu %lu %lu %lu]", (int)surface->compositor->method, region.min.x, region.min.y, region.max.x - region.min.x, region.max.y - region.min.y); auto maskOp = _getMaskOp(surface->compositor->method); - if (_direct(surface->compositor->method)) return _rasterDirectMaskedRect(surface, region, maskOp, r, g, b, a); - else return _rasterCompositeMaskedRect(surface, region, maskOp, r, g, b, a); + if (_direct(surface->compositor->method)) return _rasterDirectMaskedRect(surface, region, maskOp, c.a); + else return _rasterCompositeMaskedRect(surface, region, maskOp, c.a); return false; } -static bool _rasterMattedRect(SwSurface* surface, const SwBBox& region, uint8_t r, uint8_t g, uint8_t b, uint8_t a) +static bool _rasterMattedRect(SwSurface* surface, const SwBBox& region, const RenderColor& c) { auto w = static_cast(region.max.x - region.min.x); auto h = static_cast(region.max.y - region.min.y); @@ -390,7 +390,7 @@ static bool _rasterMattedRect(SwSurface* surface, const SwBBox& region, uint8_t //32bits channels if (surface->channelSize == sizeof(uint32_t)) { - auto color = surface->join(r, g, b, a); + auto color = surface->join(c.r, c.g, c.b, c.a); auto buffer = surface->buf32 + (region.min.y * surface->stride) + region.min.x; for (uint32_t y = 0; y < h; ++y) { auto dst = &buffer[y * surface->stride]; @@ -407,7 +407,7 @@ static bool _rasterMattedRect(SwSurface* surface, const SwBBox& region, uint8_t auto dst = &buffer[y * surface->stride]; auto cmp = &cbuffer[y * surface->compositor->image.stride * csize]; for (uint32_t x = 0; x < w; ++x, ++dst, cmp += csize) { - *dst = INTERPOLATE8(a, *dst, alpha(cmp)); + *dst = INTERPOLATE8(c.a, *dst, alpha(cmp)); } } } @@ -415,13 +415,13 @@ static bool _rasterMattedRect(SwSurface* surface, const SwBBox& region, uint8_t } -static bool _rasterBlendingRect(SwSurface* surface, const SwBBox& region, uint8_t r, uint8_t g, uint8_t b, uint8_t a) +static bool _rasterBlendingRect(SwSurface* surface, const SwBBox& region, const RenderColor& c) { if (surface->channelSize != sizeof(uint32_t)) return false; auto w = static_cast(region.max.x - region.min.x); auto h = static_cast(region.max.y - region.min.y); - auto color = surface->join(r, g, b, a); + auto color = surface->join(c.r, c.g, c.b, c.a); auto buffer = surface->buf32 + (region.min.y * surface->stride) + region.min.x; for (uint32_t y = 0; y < h; ++y) { @@ -434,26 +434,26 @@ static bool _rasterBlendingRect(SwSurface* surface, const SwBBox& region, uint8_ } -static bool _rasterTranslucentRect(SwSurface* surface, const SwBBox& region, uint8_t r, uint8_t g, uint8_t b, uint8_t a) +static bool _rasterTranslucentRect(SwSurface* surface, const SwBBox& region, const RenderColor& c) { #if defined(THORVG_AVX_VECTOR_SUPPORT) - return avxRasterTranslucentRect(surface, region, r, g, b, a); + return avxRasterTranslucentRect(surface, region, c); #elif defined(THORVG_NEON_VECTOR_SUPPORT) - return neonRasterTranslucentRect(surface, region, r, g, b, a); + return neonRasterTranslucentRect(surface, region, c); #else - return cRasterTranslucentRect(surface, region, r, g, b, a); + return cRasterTranslucentRect(surface, region, c); #endif } -static bool _rasterSolidRect(SwSurface* surface, const SwBBox& region, uint8_t r, uint8_t g, uint8_t b) +static bool _rasterSolidRect(SwSurface* surface, const SwBBox& region, const RenderColor& c) { auto w = static_cast(region.max.x - region.min.x); auto h = static_cast(region.max.y - region.min.y); //32bits channels if (surface->channelSize == sizeof(uint32_t)) { - auto color = surface->join(r, g, b, 255); + auto color = surface->join(c.r, c.g, c.b, 255); auto buffer = surface->buf32 + (region.min.y * surface->stride); for (uint32_t y = 0; y < h; ++y) { rasterPixel32(buffer + y * surface->stride, color, region.min.x, w); @@ -471,16 +471,16 @@ static bool _rasterSolidRect(SwSurface* surface, const SwBBox& region, uint8_t r } -static bool _rasterRect(SwSurface* surface, const SwBBox& region, uint8_t r, uint8_t g, uint8_t b, uint8_t a) +static bool _rasterRect(SwSurface* surface, const SwBBox& region, const RenderColor& c) { if (_compositing(surface)) { - if (_matting(surface)) return _rasterMattedRect(surface, region, r, g, b, a); - else return _rasterMaskedRect(surface, region, r, g, b, a); + if (_matting(surface)) return _rasterMattedRect(surface, region, c); + else return _rasterMaskedRect(surface, region, c); } else if (_blending(surface)) { - return _rasterBlendingRect(surface, region, r, g, b, a); + return _rasterBlendingRect(surface, region, c); } else { - if (a == 255) return _rasterSolidRect(surface, region, r, g, b); - else return _rasterTranslucentRect(surface, region, r, g, b, a); + if (c.a == 255) return _rasterSolidRect(surface, region, c); + else return _rasterTranslucentRect(surface, region, c); } return false; } @@ -490,7 +490,7 @@ static bool _rasterRect(SwSurface* surface, const SwBBox& region, uint8_t r, uin /* Rle */ /************************************************************************/ -static bool _rasterCompositeMaskedRle(SwSurface* surface, SwRle* rle, SwMask maskOp, uint8_t r, uint8_t g, uint8_t b, uint8_t a) +static bool _rasterCompositeMaskedRle(SwSurface* surface, SwRle* rle, SwMask maskOp, uint8_t a) { auto span = rle->spans; auto cbuffer = surface->compositor->image.buf8; @@ -510,7 +510,7 @@ static bool _rasterCompositeMaskedRle(SwSurface* surface, SwRle* rle, SwMask mas } -static bool _rasterDirectMaskedRle(SwSurface* surface, SwRle* rle, SwMask maskOp, uint8_t r, uint8_t g, uint8_t b, uint8_t a) +static bool _rasterDirectMaskedRle(SwSurface* surface, SwRle* rle, SwMask maskOp, uint8_t a) { auto span = rle->spans; auto cbuffer = surface->compositor->image.buf8; @@ -531,7 +531,7 @@ static bool _rasterDirectMaskedRle(SwSurface* surface, SwRle* rle, SwMask maskOp } -static bool _rasterMaskedRle(SwSurface* surface, SwRle* rle, uint8_t r, uint8_t g, uint8_t b, uint8_t a) +static bool _rasterMaskedRle(SwSurface* surface, SwRle* rle, const RenderColor& c) { TVGLOG("SW_ENGINE", "Masked(%d) Rle", (int)surface->compositor->method); @@ -539,13 +539,13 @@ static bool _rasterMaskedRle(SwSurface* surface, SwRle* rle, uint8_t r, uint8_t if (surface->channelSize != sizeof(uint8_t)) return false; auto maskOp = _getMaskOp(surface->compositor->method); - if (_direct(surface->compositor->method)) return _rasterDirectMaskedRle(surface, rle, maskOp, r, g, b, a); - else return _rasterCompositeMaskedRle(surface, rle, maskOp, r, g, b, a); + if (_direct(surface->compositor->method)) return _rasterDirectMaskedRle(surface, rle, maskOp, c.a); + else return _rasterCompositeMaskedRle(surface, rle, maskOp, c.a); return false; } -static bool _rasterMattedRle(SwSurface* surface, SwRle* rle, uint8_t r, uint8_t g, uint8_t b, uint8_t a) +static bool _rasterMattedRle(SwSurface* surface, SwRle* rle, const RenderColor& c) { TVGLOG("SW_ENGINE", "Matted(%d) Rle", (int)surface->compositor->method); @@ -557,7 +557,7 @@ static bool _rasterMattedRle(SwSurface* surface, SwRle* rle, uint8_t r, uint8_t //32bit channels if (surface->channelSize == sizeof(uint32_t)) { uint32_t src; - auto color = surface->join(r, g, b, a); + auto color = surface->join(c.r, c.g, c.b, c.a); for (uint32_t i = 0; i < rle->size; ++i, ++span) { auto dst = &surface->buf32[span->y * surface->stride + span->x]; auto cmp = &cbuffer[(span->y * surface->compositor->image.stride + span->x) * csize]; @@ -574,8 +574,8 @@ static bool _rasterMattedRle(SwSurface* surface, SwRle* rle, uint8_t r, uint8_t for (uint32_t i = 0; i < rle->size; ++i, ++span) { auto dst = &surface->buf8[span->y * surface->stride + span->x]; auto cmp = &cbuffer[(span->y * surface->compositor->image.stride + span->x) * csize]; - if (span->coverage == 255) src = a; - else src = MULTIPLY(a, span->coverage); + if (span->coverage == 255) src = c.a; + else src = MULTIPLY(c.a, span->coverage); for (uint32_t x = 0; x < span->len; ++x, ++dst, cmp += csize) { *dst = INTERPOLATE8(src, *dst, alpha(cmp)); } @@ -585,12 +585,12 @@ static bool _rasterMattedRle(SwSurface* surface, SwRle* rle, uint8_t r, uint8_t } -static bool _rasterBlendingRle(SwSurface* surface, const SwRle* rle, uint8_t r, uint8_t g, uint8_t b, uint8_t a) +static bool _rasterBlendingRle(SwSurface* surface, const SwRle* rle, const RenderColor& c) { if (surface->channelSize != sizeof(uint32_t)) return false; auto span = rle->spans; - auto color = surface->join(r, g, b, a); + auto color = surface->join(c.r, c.g, c.b, c.a); for (uint32_t i = 0; i < rle->size; ++i, ++span) { auto dst = &surface->buf32[span->y * surface->stride + span->x]; @@ -609,25 +609,25 @@ static bool _rasterBlendingRle(SwSurface* surface, const SwRle* rle, uint8_t r, } -static bool _rasterTranslucentRle(SwSurface* surface, const SwRle* rle, uint8_t r, uint8_t g, uint8_t b, uint8_t a) +static bool _rasterTranslucentRle(SwSurface* surface, const SwRle* rle, const RenderColor& c) { #if defined(THORVG_AVX_VECTOR_SUPPORT) - return avxRasterTranslucentRle(surface, rle, r, g, b, a); + return avxRasterTranslucentRle(surface, rle, c); #elif defined(THORVG_NEON_VECTOR_SUPPORT) - return neonRasterTranslucentRle(surface, rle, r, g, b, a); + return neonRasterTranslucentRle(surface, rle, c); #else - return cRasterTranslucentRle(surface, rle, r, g, b, a); + return cRasterTranslucentRle(surface, rle, c); #endif } -static bool _rasterSolidRle(SwSurface* surface, const SwRle* rle, uint8_t r, uint8_t g, uint8_t b) +static bool _rasterSolidRle(SwSurface* surface, const SwRle* rle, const RenderColor& c) { auto span = rle->spans; //32bit channels if (surface->channelSize == sizeof(uint32_t)) { - auto color = surface->join(r, g, b, 255); + auto color = surface->join(c.r, c.g, c.b, 255); for (uint32_t i = 0; i < rle->size; ++i, ++span) { if (span->coverage == 255) { rasterPixel32(surface->buf32 + span->y * surface->stride, color, span->x, span->len); @@ -658,18 +658,18 @@ static bool _rasterSolidRle(SwSurface* surface, const SwRle* rle, uint8_t r, uin } -static bool _rasterRle(SwSurface* surface, SwRle* rle, uint8_t r, uint8_t g, uint8_t b, uint8_t a) +static bool _rasterRle(SwSurface* surface, SwRle* rle, const RenderColor& c) { if (!rle) return false; if (_compositing(surface)) { - if (_matting(surface)) return _rasterMattedRle(surface, rle, r, g, b, a); - else return _rasterMaskedRle(surface, rle, r, g, b, a); + if (_matting(surface)) return _rasterMattedRle(surface, rle, c); + else return _rasterMaskedRle(surface, rle, c); } else if (_blending(surface)) { - return _rasterBlendingRle(surface, rle, r, g, b, a); + return _rasterBlendingRle(surface, rle, c); } else { - if (a == 255) return _rasterSolidRle(surface, rle, r, g, b); - else return _rasterTranslucentRle(surface, rle, r, g, b, a); + if (c.a == 255) return _rasterSolidRle(surface, rle, c); + else return _rasterTranslucentRle(surface, rle, c); } return false; } @@ -1724,7 +1724,8 @@ bool rasterGradientShape(SwSurface* surface, SwShape* shape, const Fill* fdata, if (auto color = fillFetchSolid(shape->fill, fdata)) { auto a = MULTIPLY(color->a, opacity); - return a > 0 ? rasterShape(surface, shape, color->r, color->g, color->b, a) : true; + RenderColor c = {color->r, color->g, color->b, a}; + return a > 0 ? rasterShape(surface, shape, c) : true; } auto type = fdata->type(); @@ -1744,8 +1745,9 @@ bool rasterGradientStroke(SwSurface* surface, SwShape* shape, const Fill* fdata, if (!shape->stroke || !shape->stroke->fill || !shape->strokeRle) return false; if (auto color = fillFetchSolid(shape->stroke->fill, fdata)) { - auto a = MULTIPLY(color->a, opacity); - return a > 0 ? rasterStroke(surface, shape, color->r, color->g, color->b, a) : true; + RenderColor c = {color->r, color->g, color->b, color->a}; + c.a = MULTIPLY(c.a, opacity); + return c.a > 0 ? rasterStroke(surface, shape, c) : true; } auto type = fdata->type(); @@ -1756,27 +1758,27 @@ bool rasterGradientStroke(SwSurface* surface, SwShape* shape, const Fill* fdata, } -bool rasterShape(SwSurface* surface, SwShape* shape, uint8_t r, uint8_t g, uint8_t b, uint8_t a) +bool rasterShape(SwSurface* surface, SwShape* shape, RenderColor& c) { - if (a < 255) { - r = MULTIPLY(r, a); - g = MULTIPLY(g, a); - b = MULTIPLY(b, a); + if (c.a < 255) { + c.r = MULTIPLY(c.r, c.a); + c.g = MULTIPLY(c.g, c.a); + c.b = MULTIPLY(c.b, c.a); } - if (shape->fastTrack) return _rasterRect(surface, shape->bbox, r, g, b, a); - else return _rasterRle(surface, shape->rle, r, g, b, a); + if (shape->fastTrack) return _rasterRect(surface, shape->bbox, c); + else return _rasterRle(surface, shape->rle, c); } -bool rasterStroke(SwSurface* surface, SwShape* shape, uint8_t r, uint8_t g, uint8_t b, uint8_t a) +bool rasterStroke(SwSurface* surface, SwShape* shape, RenderColor& c) { - if (a < 255) { - r = MULTIPLY(r, a); - g = MULTIPLY(g, a); - b = MULTIPLY(b, a); + if (c.a < 255) { + c.r = MULTIPLY(c.r, c.a); + c.g = MULTIPLY(c.g, c.a); + c.b = MULTIPLY(c.b, c.a); } - return _rasterRle(surface, shape->strokeRle, r, g, b, a); + return _rasterRle(surface, shape->strokeRle, c); } diff --git a/src/renderer/sw_engine/tvgSwRasterAvx.h b/src/renderer/sw_engine/tvgSwRasterAvx.h index 79cab043..bade3a55 100644 --- a/src/renderer/sw_engine/tvgSwRasterAvx.h +++ b/src/renderer/sw_engine/tvgSwRasterAvx.h @@ -99,17 +99,17 @@ static void avxRasterPixel32(uint32_t *dst, uint32_t val, uint32_t offset, int32 } -static bool avxRasterTranslucentRect(SwSurface* surface, const SwBBox& region, uint8_t r, uint8_t g, uint8_t b, uint8_t a) +static bool avxRasterTranslucentRect(SwSurface* surface, const SwBBox& region, const RenderColor& c) { auto h = static_cast(region.max.y - region.min.y); auto w = static_cast(region.max.x - region.min.x); //32bits channels if (surface->channelSize == sizeof(uint32_t)) { - auto color = surface->join(r, g, b, a); + auto color = surface->join(c.r, c.g, c.b, c.a); auto buffer = surface->buf32 + (region.min.y * surface->stride) + region.min.x; - uint32_t ialpha = 255 - a; + uint32_t ialpha = 255 - c.a; auto avxColor = _mm_set1_epi32(color); auto avxIalpha = _mm_set1_epi8(ialpha); @@ -146,11 +146,11 @@ static bool avxRasterTranslucentRect(SwSurface* surface, const SwBBox& region, u } else if (surface->channelSize == sizeof(uint8_t)) { TVGLOG("SW_ENGINE", "Require AVX Optimization, Channel Size = %d", surface->channelSize); auto buffer = surface->buf8 + (region.min.y * surface->stride) + region.min.x; - auto ialpha = ~a; + auto ialpha = ~c.a; for (uint32_t y = 0; y < h; ++y) { auto dst = &buffer[y * surface->stride]; for (uint32_t x = 0; x < w; ++x, ++dst) { - *dst = a + MULTIPLY(*dst, ialpha); + *dst = c.a + MULTIPLY(*dst, ialpha); } } } @@ -158,13 +158,13 @@ static bool avxRasterTranslucentRect(SwSurface* surface, const SwBBox& region, u } -static bool avxRasterTranslucentRle(SwSurface* surface, const SwRle* rle, uint8_t r, uint8_t g, uint8_t b, uint8_t a) +static bool avxRasterTranslucentRle(SwSurface* surface, const SwRle* rle, const RenderColor& c) { auto span = rle->spans; //32bit channels if (surface->channelSize == sizeof(uint32_t)) { - auto color = surface->join(r, g, b, a); + auto color = surface->join(c.r, c.g, c.b, c.a); uint32_t src; for (uint32_t i = 0; i < rle->size; ++i) { @@ -215,9 +215,9 @@ static bool avxRasterTranslucentRle(SwSurface* surface, const SwRle* rle, uint8_ uint8_t src; for (uint32_t i = 0; i < rle->size; ++i, ++span) { auto dst = &surface->buf8[span->y * surface->stride + span->x]; - if (span->coverage < 255) src = MULTIPLY(span->coverage, a); - else src = a; - auto ialpha = ~a; + if (span->coverage < 255) src = MULTIPLY(span->coverage, c.a); + else src = c.a; + auto ialpha = ~c.a; for (uint32_t x = 0; x < span->len; ++x, ++dst) { *dst = src + MULTIPLY(*dst, ialpha); } diff --git a/src/renderer/sw_engine/tvgSwRasterC.h b/src/renderer/sw_engine/tvgSwRasterC.h index 8bea1b13..260f7ce7 100644 --- a/src/renderer/sw_engine/tvgSwRasterC.h +++ b/src/renderer/sw_engine/tvgSwRasterC.h @@ -92,13 +92,13 @@ static void inline cRasterPixels(PIXEL_T* dst, PIXEL_T val, uint32_t offset, int } -static bool inline cRasterTranslucentRle(SwSurface* surface, const SwRle* rle, uint8_t r, uint8_t g, uint8_t b, uint8_t a) +static bool inline cRasterTranslucentRle(SwSurface* surface, const SwRle* rle, const RenderColor& c) { auto span = rle->spans; //32bit channels if (surface->channelSize == sizeof(uint32_t)) { - auto color = surface->join(r, g, b, a); + auto color = surface->join(c.r, c.g, c.b, c.a); uint32_t src; for (uint32_t i = 0; i < rle->size; ++i, ++span) { auto dst = &surface->buf32[span->y * surface->stride + span->x]; @@ -114,9 +114,9 @@ static bool inline cRasterTranslucentRle(SwSurface* surface, const SwRle* rle, u uint8_t src; for (uint32_t i = 0; i < rle->size; ++i, ++span) { auto dst = &surface->buf8[span->y * surface->stride + span->x]; - if (span->coverage < 255) src = MULTIPLY(span->coverage, a); - else src = a; - auto ialpha = ~a; + if (span->coverage < 255) src = MULTIPLY(span->coverage, c.a); + else src = c.a; + auto ialpha = ~c.a; for (uint32_t x = 0; x < span->len; ++x, ++dst) { *dst = src + MULTIPLY(*dst, ialpha); } @@ -126,16 +126,16 @@ static bool inline cRasterTranslucentRle(SwSurface* surface, const SwRle* rle, u } -static bool inline cRasterTranslucentRect(SwSurface* surface, const SwBBox& region, uint8_t r, uint8_t g, uint8_t b, uint8_t a) +static bool inline cRasterTranslucentRect(SwSurface* surface, const SwBBox& region, const RenderColor& c) { auto h = static_cast(region.max.y - region.min.y); auto w = static_cast(region.max.x - region.min.x); //32bits channels if (surface->channelSize == sizeof(uint32_t)) { - auto color = surface->join(r, g, b, a); + auto color = surface->join(c.r, c.g, c.b, c.a); auto buffer = surface->buf32 + (region.min.y * surface->stride) + region.min.x; - auto ialpha = 255 - a; + auto ialpha = 255 - c.a; for (uint32_t y = 0; y < h; ++y) { auto dst = &buffer[y * surface->stride]; for (uint32_t x = 0; x < w; ++x, ++dst) { @@ -145,11 +145,11 @@ static bool inline cRasterTranslucentRect(SwSurface* surface, const SwBBox& regi //8bit grayscale } else if (surface->channelSize == sizeof(uint8_t)) { auto buffer = surface->buf8 + (region.min.y * surface->stride) + region.min.x; - auto ialpha = ~a; + auto ialpha = ~c.a; for (uint32_t y = 0; y < h; ++y) { auto dst = &buffer[y * surface->stride]; for (uint32_t x = 0; x < w; ++x, ++dst) { - *dst = a + MULTIPLY(*dst, ialpha); + *dst = c.a + MULTIPLY(*dst, ialpha); } } } diff --git a/src/renderer/sw_engine/tvgSwRasterNeon.h b/src/renderer/sw_engine/tvgSwRasterNeon.h index fe693b7f..5dbdd6f7 100644 --- a/src/renderer/sw_engine/tvgSwRasterNeon.h +++ b/src/renderer/sw_engine/tvgSwRasterNeon.h @@ -89,13 +89,13 @@ static void neonRasterPixel32(uint32_t *dst, uint32_t val, uint32_t offset, int3 } -static bool neonRasterTranslucentRle(SwSurface* surface, const SwRle* rle, uint8_t r, uint8_t g, uint8_t b, uint8_t a) +static bool neonRasterTranslucentRle(SwSurface* surface, const SwRle* rle, const RenderColor& c) { auto span = rle->spans; //32bit channels if (surface->channelSize == sizeof(uint32_t)) { - auto color = surface->join(r, g, b, a); + auto color = surface->join(c.r, c.g, c.b, c.a); uint32_t src; uint8x8_t *vDst = nullptr; uint16_t align; @@ -134,9 +134,9 @@ static bool neonRasterTranslucentRle(SwSurface* surface, const SwRle* rle, uint8 uint8_t src; for (uint32_t i = 0; i < rle->size; ++i, ++span) { auto dst = &surface->buf8[span->y * surface->stride + span->x]; - if (span->coverage < 255) src = MULTIPLY(span->coverage, a); - else src = a; - auto ialpha = ~a; + if (span->coverage < 255) src = MULTIPLY(span->coverage, c.a); + else src = c.a; + auto ialpha = ~c.a; for (uint32_t x = 0; x < span->len; ++x, ++dst) { *dst = src + MULTIPLY(*dst, ialpha); } @@ -146,16 +146,16 @@ static bool neonRasterTranslucentRle(SwSurface* surface, const SwRle* rle, uint8 } -static bool neonRasterTranslucentRect(SwSurface* surface, const SwBBox& region, uint8_t r, uint8_t g, uint8_t b, uint8_t a) +static bool neonRasterTranslucentRect(SwSurface* surface, const SwBBox& region, const RenderColor& c) { auto h = static_cast(region.max.y - region.min.y); auto w = static_cast(region.max.x - region.min.x); //32bits channels if (surface->channelSize == sizeof(uint32_t)) { - auto color = surface->join(r, g, b, a); + auto color = surface->join(c.r, c.g, c.b, c.a); auto buffer = surface->buf32 + (region.min.y * surface->stride) + region.min.x; - auto ialpha = 255 - a; + auto ialpha = 255 - c.a; auto vColor = vdup_n_u32(color); auto vIalpha = vdup_n_u8((uint8_t) ialpha); @@ -186,11 +186,11 @@ static bool neonRasterTranslucentRect(SwSurface* surface, const SwBBox& region, } else if (surface->channelSize == sizeof(uint8_t)) { TVGLOG("SW_ENGINE", "Require Neon Optimization, Channel Size = %d", surface->channelSize); auto buffer = surface->buf8 + (region.min.y * surface->stride) + region.min.x; - auto ialpha = ~a; + auto ialpha = ~c.a; for (uint32_t y = 0; y < h; ++y) { auto dst = &buffer[y * surface->stride]; for (uint32_t x = 0; x < w; ++x, ++dst) { - *dst = a + MULTIPLY(*dst, ialpha); + *dst = c.a + MULTIPLY(*dst, ialpha); } } } diff --git a/src/renderer/sw_engine/tvgSwRenderer.cpp b/src/renderer/sw_engine/tvgSwRenderer.cpp index 5d778ca6..b6e8177a 100644 --- a/src/renderer/sw_engine/tvgSwRenderer.cpp +++ b/src/renderer/sw_engine/tvgSwRenderer.cpp @@ -85,7 +85,7 @@ struct SwShapeTask : SwTask Additionally, the stroke style should not be dashed. */ bool antialiasing(float strokeWidth) { - return strokeWidth < 2.0f || rshape->stroke->dashCnt > 0 || rshape->stroke->strokeFirst || rshape->strokeTrim() || rshape->stroke->color[3] < 255;; + return strokeWidth < 2.0f || rshape->stroke->dashCnt > 0 || rshape->stroke->strokeFirst || rshape->strokeTrim() || rshape->stroke->color.a < 255; } float validStrokeWidth() @@ -95,7 +95,7 @@ struct SwShapeTask : SwTask auto width = rshape->stroke->width; if (tvg::zero(width)) return 0.0f; - if (!rshape->stroke->fill && (MULTIPLY(rshape->stroke->color[3], opacity) == 0)) return 0.0f; + if (!rshape->stroke->fill && (MULTIPLY(rshape->stroke->color.a, opacity) == 0)) return 0.0f; if (tvg::zero(rshape->stroke->trim.begin - rshape->stroke->trim.end)) return 0.0f; return (width * sqrt(transform.e11 * transform.e11 + transform.e12 * transform.e12)); @@ -128,8 +128,7 @@ struct SwShapeTask : SwTask //Shape if (flags & (RenderUpdateFlag::Path | RenderUpdateFlag::Transform) || prepareShape) { - uint8_t alpha = 0; - rshape->fillColor(nullptr, nullptr, nullptr, &alpha); + auto alpha = rshape->color.a; alpha = MULTIPLY(alpha, opacity); visibleFill = (alpha > 0 || rshape->fill); shapeReset(&shape); @@ -270,25 +269,25 @@ static void _termEngine() static void _renderFill(SwShapeTask* task, SwSurface* surface, uint8_t opacity) { - uint8_t r, g, b, a; if (auto fill = task->rshape->fill) { rasterGradientShape(surface, &task->shape, fill, opacity); } else { - task->rshape->fillColor(&r, &g, &b, &a); - a = MULTIPLY(opacity, a); - if (a > 0) rasterShape(surface, &task->shape, r, g, b, a); + RenderColor c; + task->rshape->fillColor(&c.r, &c.g, &c.b, &c.a); + c.a = MULTIPLY(opacity, c.a); + if (c.a > 0) rasterShape(surface, &task->shape, c); } } static void _renderStroke(SwShapeTask* task, SwSurface* surface, uint8_t opacity) { - uint8_t r, g, b, a; if (auto strokeFill = task->rshape->strokeFill()) { rasterGradientStroke(surface, &task->shape, strokeFill, opacity); } else { - if (task->rshape->strokeFill(&r, &g, &b, &a)) { - a = MULTIPLY(opacity, a); - if (a > 0) rasterStroke(surface, &task->shape, r, g, b, a); + RenderColor c; + if (task->rshape->strokeFill(&c.r, &c.g, &c.b, &c.a)) { + c.a = MULTIPLY(opacity, c.a); + if (c.a > 0) rasterStroke(surface, &task->shape, c); } } } diff --git a/src/renderer/tvgRender.h b/src/renderer/tvgRender.h index bc0e56fb..d73248fd 100644 --- a/src/renderer/tvgRender.h +++ b/src/renderer/tvgRender.h @@ -67,6 +67,11 @@ struct RenderSurface } }; +struct RenderColor +{ + uint8_t r, g, b, a; +}; + struct RenderCompositor { MaskMethod method; @@ -90,7 +95,7 @@ struct RenderRegion struct RenderStroke { float width = 0.0f; - uint8_t color[4] = {0, 0, 0, 0}; + RenderColor color{}; Fill *fill = nullptr; float* dashPattern = nullptr; uint32_t dashCnt = 0; @@ -109,8 +114,7 @@ struct RenderStroke void operator=(const RenderStroke& rhs) { width = rhs.width; - - memcpy(color, rhs.color, sizeof(color)); + color = rhs.color; delete(fill); if (rhs.fill) fill = rhs.fill->duplicate(); @@ -173,7 +177,7 @@ struct RenderShape } path; Fill *fill = nullptr; - uint8_t color[4] = {0, 0, 0, 0}; //r, g, b, a + RenderColor color{}; RenderStroke *stroke = nullptr; FillRule rule = FillRule::Winding; @@ -185,10 +189,10 @@ struct RenderShape void fillColor(uint8_t* r, uint8_t* g, uint8_t* b, uint8_t* a) const { - if (r) *r = color[0]; - if (g) *g = color[1]; - if (b) *b = color[2]; - if (a) *a = color[3]; + if (r) *r = color.r; + if (g) *g = color.g; + if (b) *b = color.b; + if (a) *a = color.a; } float strokeWidth() const @@ -209,10 +213,10 @@ struct RenderShape { if (!stroke) return false; - if (r) *r = stroke->color[0]; - if (g) *g = stroke->color[1]; - if (b) *b = stroke->color[2]; - if (a) *a = stroke->color[3]; + if (r) *r = stroke->color.r; + if (g) *g = stroke->color.g; + if (b) *b = stroke->color.b; + if (a) *a = stroke->color.a; return true; } diff --git a/src/renderer/tvgShape.cpp b/src/renderer/tvgShape.cpp index 38f10d2b..addcf0d7 100644 --- a/src/renderer/tvgShape.cpp +++ b/src/renderer/tvgShape.cpp @@ -198,12 +198,10 @@ Result Shape::fill(uint8_t r, uint8_t g, uint8_t b, uint8_t a) noexcept pImpl->flag |= RenderUpdateFlag::Gradient; } - if (r == pImpl->rs.color[0] && g == pImpl->rs.color[1] && b == pImpl->rs.color[2] && a == pImpl->rs.color[3]) return Result::Success; + if (r == pImpl->rs.color.r && g == pImpl->rs.color.g && b == pImpl->rs.color.b && a == pImpl->rs.color.a) return Result::Success; + + pImpl->rs.color = {r, g, b, a}; - pImpl->rs.color[0] = r; - pImpl->rs.color[1] = g; - pImpl->rs.color[2] = b; - pImpl->rs.color[3] = a; pImpl->flag |= RenderUpdateFlag::Color; return Result::Success; diff --git a/src/renderer/tvgShape.h b/src/renderer/tvgShape.h index e18125ea..c42bea70 100644 --- a/src/renderer/tvgShape.h +++ b/src/renderer/tvgShape.h @@ -72,8 +72,8 @@ struct Shape::Impl if (opacity == 0) return false; //Shape composition is only necessary when stroking & fill are valid. - if (!rs.stroke || rs.stroke->width < FLOAT_EPSILON || (!rs.stroke->fill && rs.stroke->color[3] == 0)) return false; - if (!rs.fill && rs.color[3] == 0) return false; + if (!rs.stroke || rs.stroke->width < FLOAT_EPSILON || (!rs.stroke->fill && rs.stroke->color.a == 0)) return false; + if (!rs.fill && rs.color.a == 0) return false; //translucent fill & stroke if (opacity < 255) return true; @@ -270,10 +270,7 @@ struct Shape::Impl flag |= RenderUpdateFlag::GradientStroke; } - rs.stroke->color[0] = r; - rs.stroke->color[1] = g; - rs.stroke->color[2] = b; - rs.stroke->color[3] = a; + rs.stroke->color = {r, g, b, a}; flag |= RenderUpdateFlag::Stroke; } @@ -285,7 +282,7 @@ struct Shape::Impl if (!rs.stroke) rs.stroke = new RenderStroke(); if (rs.stroke->fill && rs.stroke->fill != f) delete(rs.stroke->fill); rs.stroke->fill = f; - rs.stroke->color[3] = 0; + rs.stroke->color.a = 0; flag |= RenderUpdateFlag::Stroke; flag |= RenderUpdateFlag::GradientStroke; @@ -358,9 +355,7 @@ struct Shape::Impl //Default Properties dup->flag = RenderUpdateFlag::All; dup->rs.rule = rs.rule; - - //Color - memcpy(dup->rs.color, rs.color, sizeof(rs.color)); + dup->rs.color = rs.color; //Path dup->rs.path.cmds.push(rs.path.cmds); @@ -388,7 +383,7 @@ struct Shape::Impl rs.path.cmds.clear(); rs.path.pts.clear(); - rs.color[3] = 0; + rs.color.a = 0; rs.rule = FillRule::Winding; delete(rs.stroke); diff --git a/src/renderer/wg_engine/tvgWgRenderData.cpp b/src/renderer/wg_engine/tvgWgRenderData.cpp index 2eebf159..8f96494b 100755 --- a/src/renderer/wg_engine/tvgWgRenderData.cpp +++ b/src/renderer/wg_engine/tvgWgRenderData.cpp @@ -233,7 +233,7 @@ void WgImageData::release(WgContext& context) // WgRenderSettings //*********************************************************************** -void WgRenderSettings::update(WgContext& context, const Fill* fill, const uint8_t* color, const RenderUpdateFlag flags) +void WgRenderSettings::update(WgContext& context, const Fill* fill, const RenderColor& c, const RenderUpdateFlag flags) { // setup fill properties if ((flags & (RenderUpdateFlag::Gradient)) && fill) { @@ -270,15 +270,15 @@ void WgRenderSettings::update(WgContext& context, const Fill* fill, const uint8_ sampler, texViewGradient, bufferGroupGradient, bufferGroupTransfromGrad); } skip = false; - } else if ((flags & (RenderUpdateFlag::Color)) && !fill) { + } else if ((flags & RenderUpdateFlag::Color) && !fill) { rasterType = WgRenderRasterType::Solid; - WgShaderTypeSolidColor solidColor(color); + WgShaderTypeSolidColor solidColor(c); if (context.allocateBufferUniform(bufferGroupSolid, &solidColor, sizeof(solidColor))) { context.pipelines->layouts.releaseBindGroup(bindGroupSolid); bindGroupSolid = context.pipelines->layouts.createBindGroupBuffer1Un(bufferGroupSolid); } fillType = WgRenderSettingsType::Solid; - skip = (color[3] == 0); + skip = (c.a == 0); } }; diff --git a/src/renderer/wg_engine/tvgWgRenderData.h b/src/renderer/wg_engine/tvgWgRenderData.h index 5b34db08..79ee1ece 100755 --- a/src/renderer/wg_engine/tvgWgRenderData.h +++ b/src/renderer/wg_engine/tvgWgRenderData.h @@ -90,7 +90,7 @@ struct WgRenderSettings WgRenderRasterType rasterType{}; bool skip{}; - void update(WgContext& context, const Fill* fill, const uint8_t* color, const RenderUpdateFlag flags); + void update(WgContext& context, const Fill* fill, const RenderColor& c, const RenderUpdateFlag flags); void release(WgContext& context); }; diff --git a/src/renderer/wg_engine/tvgWgRenderer.cpp b/src/renderer/wg_engine/tvgWgRenderer.cpp index 3c9e6cd4..cb4d02fd 100755 --- a/src/renderer/wg_engine/tvgWgRenderer.cpp +++ b/src/renderer/wg_engine/tvgWgRenderer.cpp @@ -369,7 +369,7 @@ bool WgRenderer::beginComposite(RenderCompositor* cmp, MaskMethod method, uint8_ mRenderStorageStack.push(storage); // begin newly added render pass WGPUColor color{}; - if ((method == MaskMethod::None) && (opacity != 255)) color = { 1.0, 1.0, 1.0, 0.0 }; + if ((method == MaskMethod::None) && (opacity != 255)) color = {1.0f, 1.0f, 1.0f, 0.0f}; mCompositor.beginRenderPass(mCommandEncoder, mRenderStorageStack.last(), true, color); return true; } diff --git a/src/renderer/wg_engine/tvgWgShaderTypes.cpp b/src/renderer/wg_engine/tvgWgShaderTypes.cpp index 6177063b..1a0f31cc 100755 --- a/src/renderer/wg_engine/tvgWgShaderTypes.cpp +++ b/src/renderer/wg_engine/tvgWgShaderTypes.cpp @@ -99,18 +99,18 @@ void WgShaderTypeBlendSettings::update(const ColorSpace colorSpace, uint8_t o) } -WgShaderTypeSolidColor::WgShaderTypeSolidColor(const uint8_t* c) +WgShaderTypeSolidColor::WgShaderTypeSolidColor(const RenderColor& c) { update(c); } -void WgShaderTypeSolidColor::update(const uint8_t* c) +void WgShaderTypeSolidColor::update(const RenderColor& c) { - color[0] = c[0] / 255.0f; // red - color[1] = c[1] / 255.0f; // green - color[2] = c[2] / 255.0f; // blue - color[3] = c[3] / 255.0f; // alpha + color[0] = c.r / 255.0f; // red + color[1] = c.g / 255.0f; // green + color[2] = c.b / 255.0f; // blue + color[3] = c.a / 255.0f; // alpha } diff --git a/src/renderer/wg_engine/tvgWgShaderTypes.h b/src/renderer/wg_engine/tvgWgShaderTypes.h index d0341a83..716aebb0 100755 --- a/src/renderer/wg_engine/tvgWgShaderTypes.h +++ b/src/renderer/wg_engine/tvgWgShaderTypes.h @@ -57,8 +57,8 @@ struct WgShaderTypeSolidColor { float color[4]{}; - WgShaderTypeSolidColor(const uint8_t* c); - void update(const uint8_t* c); + WgShaderTypeSolidColor(const RenderColor& c); + void update(const RenderColor& c); }; // sampler, texture, vec4f