renderer: code refactoring

- introduced RenderColor
- internal name changes to avoid conflicts
This commit is contained in:
Hermet Park 2024-11-20 17:23:25 +09:00 committed by Hermet Park
parent a67f30de65
commit d3d085de15
16 changed files with 154 additions and 167 deletions

View file

@ -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 vp = currentPass()->getViewport();
auto bbox = sdata.geometry->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); stencilTask->setDrawDepth(depth);
} }
a = MULTIPLY(a, sdata.opacity); auto a = MULTIPLY(c.a, sdata.opacity);
if (flag & RenderUpdateFlag::Stroke) { if (flag & RenderUpdateFlag::Stroke) {
float strokeWidth = sdata.rshape->strokeWidth() * sdata.geometry->getTransformMatrix().e11; 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 // 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{ task->addBindResource(GlBindingResource{
1, 1,
@ -1104,7 +1104,6 @@ bool GlRenderer::renderShape(RenderData data)
if (bbox.w <= 0 || bbox.h <= 0) return true; 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; int32_t drawDepth1 = 0, drawDepth2 = 0;
size_t flags = static_cast<size_t>(sdata->updateFlag); size_t flags = static_cast<size_t>(sdata->updateFlag);
@ -1122,13 +1121,7 @@ bool GlRenderer::renderShape(RenderData data)
{ {
auto gradient = sdata->rshape->fill; auto gradient = sdata->rshape->fill;
if (gradient) drawPrimitive(*sdata, gradient, RenderUpdateFlag::Gradient, drawDepth1); if (gradient) drawPrimitive(*sdata, gradient, RenderUpdateFlag::Gradient, drawDepth1);
else { else if (sdata->rshape->color.a > 0) drawPrimitive(*sdata, sdata->rshape->color, RenderUpdateFlag::Color, drawDepth1);
sdata->rshape->fillColor(&r, &g, &b, &a);
if (a > 0)
{
drawPrimitive(*sdata, r, g, b, a, RenderUpdateFlag::Color, drawDepth1);
}
}
} }
if (flags & (RenderUpdateFlag::Stroke | RenderUpdateFlag::GradientStroke)) if (flags & (RenderUpdateFlag::Stroke | RenderUpdateFlag::GradientStroke))
@ -1136,11 +1129,8 @@ bool GlRenderer::renderShape(RenderData data)
auto gradient = sdata->rshape->strokeFill(); auto gradient = sdata->rshape->strokeFill();
if (gradient) { if (gradient) {
drawPrimitive(*sdata, gradient, RenderUpdateFlag::GradientStroke, drawDepth2); drawPrimitive(*sdata, gradient, RenderUpdateFlag::GradientStroke, drawDepth2);
} else { } else if (sdata->rshape->stroke && sdata->rshape->stroke->color.a > 0) {
if (sdata->rshape->strokeFill(&r, &g, &b, &a) && a > 0) drawPrimitive(*sdata, sdata->rshape->stroke->color, RenderUpdateFlag::Stroke, drawDepth2);
{
drawPrimitive(*sdata, r, g, b, a, RenderUpdateFlag::Stroke, drawDepth2);
}
} }
} }
@ -1236,9 +1226,8 @@ RenderData GlRenderer::prepare(const RenderShape& rshape, RenderData data, const
sdata->opacity = opacity; sdata->opacity = opacity;
//invisible? //invisible?
uint8_t alphaF = 0, alphaS = 0; auto alphaF = rshape.color.a;
rshape.fillColor(nullptr, nullptr, nullptr, &alphaF); auto alphaS = rshape.stroke ? rshape.stroke->color.a : 0;
rshape.strokeFill(nullptr, nullptr, nullptr, &alphaS);
if ( ((flags & RenderUpdateFlag::Gradient) == 0) && if ( ((flags & RenderUpdateFlag::Gradient) == 0) &&
((flags & RenderUpdateFlag::Color) && alphaF == 0) && ((flags & RenderUpdateFlag::Color) && alphaF == 0) &&

View file

@ -99,7 +99,7 @@ private:
~GlRenderer(); ~GlRenderer();
void initShaders(); 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 drawPrimitive(GlShape& sdata, const Fill* fill, RenderUpdateFlag flag, int32_t depth);
void drawClip(Array<RenderData>& clips); void drawClip(Array<RenderData>& clips);

View file

@ -558,9 +558,9 @@ void mpoolRetDashOutline(SwMpool* mpool, unsigned idx);
bool rasterCompositor(SwSurface* surface); bool rasterCompositor(SwSurface* surface);
bool rasterGradientShape(SwSurface* surface, SwShape* shape, const Fill* fdata, uint8_t opacity); 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 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 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); 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); void rasterPixel32(uint32_t *dst, uint32_t val, uint32_t offset, int32_t len);

View file

@ -324,7 +324,7 @@ static uint32_t _interpDownScaler(const uint32_t *img, uint32_t stride, uint32_t
/* Rect */ /* 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<uint32_t>(region.max.x - region.min.x); auto w = static_cast<uint32_t>(region.max.x - region.min.x);
auto h = static_cast<uint32_t>(region.max.y - region.min.y); auto h = static_cast<uint32_t>(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<uint32_t>(region.max.x - region.min.x); auto w = static_cast<uint32_t>(region.max.x - region.min.x);
auto h = static_cast<uint32_t>(region.max.y - region.min.y); auto h = static_cast<uint32_t>(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 //8bit masking channels composition
if (surface->channelSize != sizeof(uint8_t)) return false; 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); 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); auto maskOp = _getMaskOp(surface->compositor->method);
if (_direct(surface->compositor->method)) return _rasterDirectMaskedRect(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, r, g, b, a); else return _rasterCompositeMaskedRect(surface, region, maskOp, c.a);
return false; 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<uint32_t>(region.max.x - region.min.x); auto w = static_cast<uint32_t>(region.max.x - region.min.x);
auto h = static_cast<uint32_t>(region.max.y - region.min.y); auto h = static_cast<uint32_t>(region.max.y - region.min.y);
@ -390,7 +390,7 @@ static bool _rasterMattedRect(SwSurface* surface, const SwBBox& region, uint8_t
//32bits channels //32bits channels
if (surface->channelSize == sizeof(uint32_t)) { 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 buffer = surface->buf32 + (region.min.y * surface->stride) + region.min.x;
for (uint32_t y = 0; y < h; ++y) { for (uint32_t y = 0; y < h; ++y) {
auto dst = &buffer[y * surface->stride]; 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 dst = &buffer[y * surface->stride];
auto cmp = &cbuffer[y * surface->compositor->image.stride * csize]; auto cmp = &cbuffer[y * surface->compositor->image.stride * csize];
for (uint32_t x = 0; x < w; ++x, ++dst, cmp += 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; if (surface->channelSize != sizeof(uint32_t)) return false;
auto w = static_cast<uint32_t>(region.max.x - region.min.x); auto w = static_cast<uint32_t>(region.max.x - region.min.x);
auto h = static_cast<uint32_t>(region.max.y - region.min.y); auto h = static_cast<uint32_t>(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; auto buffer = surface->buf32 + (region.min.y * surface->stride) + region.min.x;
for (uint32_t y = 0; y < h; ++y) { 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) #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) #elif defined(THORVG_NEON_VECTOR_SUPPORT)
return neonRasterTranslucentRect(surface, region, r, g, b, a); return neonRasterTranslucentRect(surface, region, c);
#else #else
return cRasterTranslucentRect(surface, region, r, g, b, a); return cRasterTranslucentRect(surface, region, c);
#endif #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<uint32_t>(region.max.x - region.min.x); auto w = static_cast<uint32_t>(region.max.x - region.min.x);
auto h = static_cast<uint32_t>(region.max.y - region.min.y); auto h = static_cast<uint32_t>(region.max.y - region.min.y);
//32bits channels //32bits channels
if (surface->channelSize == sizeof(uint32_t)) { 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); auto buffer = surface->buf32 + (region.min.y * surface->stride);
for (uint32_t y = 0; y < h; ++y) { for (uint32_t y = 0; y < h; ++y) {
rasterPixel32(buffer + y * surface->stride, color, region.min.x, w); 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 (_compositing(surface)) {
if (_matting(surface)) return _rasterMattedRect(surface, region, r, g, b, a); if (_matting(surface)) return _rasterMattedRect(surface, region, c);
else return _rasterMaskedRect(surface, region, r, g, b, a); else return _rasterMaskedRect(surface, region, c);
} else if (_blending(surface)) { } else if (_blending(surface)) {
return _rasterBlendingRect(surface, region, r, g, b, a); return _rasterBlendingRect(surface, region, c);
} else { } else {
if (a == 255) return _rasterSolidRect(surface, region, r, g, b); if (c.a == 255) return _rasterSolidRect(surface, region, c);
else return _rasterTranslucentRect(surface, region, r, g, b, a); else return _rasterTranslucentRect(surface, region, c);
} }
return false; return false;
} }
@ -490,7 +490,7 @@ static bool _rasterRect(SwSurface* surface, const SwBBox& region, uint8_t r, uin
/* Rle */ /* 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 span = rle->spans;
auto cbuffer = surface->compositor->image.buf8; 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 span = rle->spans;
auto cbuffer = surface->compositor->image.buf8; 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); 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; if (surface->channelSize != sizeof(uint8_t)) return false;
auto maskOp = _getMaskOp(surface->compositor->method); auto maskOp = _getMaskOp(surface->compositor->method);
if (_direct(surface->compositor->method)) return _rasterDirectMaskedRle(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, r, g, b, a); else return _rasterCompositeMaskedRle(surface, rle, maskOp, c.a);
return false; 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); 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 //32bit channels
if (surface->channelSize == sizeof(uint32_t)) { if (surface->channelSize == sizeof(uint32_t)) {
uint32_t src; 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) { for (uint32_t i = 0; i < rle->size; ++i, ++span) {
auto dst = &surface->buf32[span->y * surface->stride + span->x]; auto dst = &surface->buf32[span->y * surface->stride + span->x];
auto cmp = &cbuffer[(span->y * surface->compositor->image.stride + span->x) * csize]; 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) { for (uint32_t i = 0; i < rle->size; ++i, ++span) {
auto dst = &surface->buf8[span->y * surface->stride + span->x]; auto dst = &surface->buf8[span->y * surface->stride + span->x];
auto cmp = &cbuffer[(span->y * surface->compositor->image.stride + span->x) * csize]; auto cmp = &cbuffer[(span->y * surface->compositor->image.stride + span->x) * csize];
if (span->coverage == 255) src = a; if (span->coverage == 255) src = c.a;
else src = MULTIPLY(a, span->coverage); else src = MULTIPLY(c.a, span->coverage);
for (uint32_t x = 0; x < span->len; ++x, ++dst, cmp += csize) { for (uint32_t x = 0; x < span->len; ++x, ++dst, cmp += csize) {
*dst = INTERPOLATE8(src, *dst, alpha(cmp)); *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; if (surface->channelSize != sizeof(uint32_t)) return false;
auto span = rle->spans; 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) { for (uint32_t i = 0; i < rle->size; ++i, ++span) {
auto dst = &surface->buf32[span->y * surface->stride + span->x]; 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) #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) #elif defined(THORVG_NEON_VECTOR_SUPPORT)
return neonRasterTranslucentRle(surface, rle, r, g, b, a); return neonRasterTranslucentRle(surface, rle, c);
#else #else
return cRasterTranslucentRle(surface, rle, r, g, b, a); return cRasterTranslucentRle(surface, rle, c);
#endif #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; auto span = rle->spans;
//32bit channels //32bit channels
if (surface->channelSize == sizeof(uint32_t)) { 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) { for (uint32_t i = 0; i < rle->size; ++i, ++span) {
if (span->coverage == 255) { if (span->coverage == 255) {
rasterPixel32(surface->buf32 + span->y * surface->stride, color, span->x, span->len); 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 (!rle) return false;
if (_compositing(surface)) { if (_compositing(surface)) {
if (_matting(surface)) return _rasterMattedRle(surface, rle, r, g, b, a); if (_matting(surface)) return _rasterMattedRle(surface, rle, c);
else return _rasterMaskedRle(surface, rle, r, g, b, a); else return _rasterMaskedRle(surface, rle, c);
} else if (_blending(surface)) { } else if (_blending(surface)) {
return _rasterBlendingRle(surface, rle, r, g, b, a); return _rasterBlendingRle(surface, rle, c);
} else { } else {
if (a == 255) return _rasterSolidRle(surface, rle, r, g, b); if (c.a == 255) return _rasterSolidRle(surface, rle, c);
else return _rasterTranslucentRle(surface, rle, r, g, b, a); else return _rasterTranslucentRle(surface, rle, c);
} }
return false; return false;
} }
@ -1724,7 +1724,8 @@ bool rasterGradientShape(SwSurface* surface, SwShape* shape, const Fill* fdata,
if (auto color = fillFetchSolid(shape->fill, fdata)) { if (auto color = fillFetchSolid(shape->fill, fdata)) {
auto a = MULTIPLY(color->a, opacity); 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(); 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 (!shape->stroke || !shape->stroke->fill || !shape->strokeRle) return false;
if (auto color = fillFetchSolid(shape->stroke->fill, fdata)) { if (auto color = fillFetchSolid(shape->stroke->fill, fdata)) {
auto a = MULTIPLY(color->a, opacity); RenderColor c = {color->r, color->g, color->b, color->a};
return a > 0 ? rasterStroke(surface, shape, color->r, color->g, color->b, a) : true; c.a = MULTIPLY(c.a, opacity);
return c.a > 0 ? rasterStroke(surface, shape, c) : true;
} }
auto type = fdata->type(); 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) { if (c.a < 255) {
r = MULTIPLY(r, a); c.r = MULTIPLY(c.r, c.a);
g = MULTIPLY(g, a); c.g = MULTIPLY(c.g, c.a);
b = MULTIPLY(b, a); c.b = MULTIPLY(c.b, c.a);
} }
if (shape->fastTrack) return _rasterRect(surface, shape->bbox, r, g, b, a); if (shape->fastTrack) return _rasterRect(surface, shape->bbox, c);
else return _rasterRle(surface, shape->rle, r, g, b, a); 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) { if (c.a < 255) {
r = MULTIPLY(r, a); c.r = MULTIPLY(c.r, c.a);
g = MULTIPLY(g, a); c.g = MULTIPLY(c.g, c.a);
b = MULTIPLY(b, a); c.b = MULTIPLY(c.b, c.a);
} }
return _rasterRle(surface, shape->strokeRle, r, g, b, a); return _rasterRle(surface, shape->strokeRle, c);
} }

View file

@ -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<uint32_t>(region.max.y - region.min.y); auto h = static_cast<uint32_t>(region.max.y - region.min.y);
auto w = static_cast<uint32_t>(region.max.x - region.min.x); auto w = static_cast<uint32_t>(region.max.x - region.min.x);
//32bits channels //32bits channels
if (surface->channelSize == sizeof(uint32_t)) { 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 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 avxColor = _mm_set1_epi32(color);
auto avxIalpha = _mm_set1_epi8(ialpha); 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)) { } else if (surface->channelSize == sizeof(uint8_t)) {
TVGLOG("SW_ENGINE", "Require AVX Optimization, Channel Size = %d", surface->channelSize); TVGLOG("SW_ENGINE", "Require AVX Optimization, Channel Size = %d", surface->channelSize);
auto buffer = surface->buf8 + (region.min.y * surface->stride) + region.min.x; 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) { for (uint32_t y = 0; y < h; ++y) {
auto dst = &buffer[y * surface->stride]; auto dst = &buffer[y * surface->stride];
for (uint32_t x = 0; x < w; ++x, ++dst) { 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; auto span = rle->spans;
//32bit channels //32bit channels
if (surface->channelSize == sizeof(uint32_t)) { 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; uint32_t src;
for (uint32_t i = 0; i < rle->size; ++i) { 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; uint8_t src;
for (uint32_t i = 0; i < rle->size; ++i, ++span) { for (uint32_t i = 0; i < rle->size; ++i, ++span) {
auto dst = &surface->buf8[span->y * surface->stride + span->x]; auto dst = &surface->buf8[span->y * surface->stride + span->x];
if (span->coverage < 255) src = MULTIPLY(span->coverage, a); if (span->coverage < 255) src = MULTIPLY(span->coverage, c.a);
else src = a; else src = c.a;
auto ialpha = ~a; auto ialpha = ~c.a;
for (uint32_t x = 0; x < span->len; ++x, ++dst) { for (uint32_t x = 0; x < span->len; ++x, ++dst) {
*dst = src + MULTIPLY(*dst, ialpha); *dst = src + MULTIPLY(*dst, ialpha);
} }

View file

@ -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; auto span = rle->spans;
//32bit channels //32bit channels
if (surface->channelSize == sizeof(uint32_t)) { 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; uint32_t src;
for (uint32_t i = 0; i < rle->size; ++i, ++span) { for (uint32_t i = 0; i < rle->size; ++i, ++span) {
auto dst = &surface->buf32[span->y * surface->stride + span->x]; 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; uint8_t src;
for (uint32_t i = 0; i < rle->size; ++i, ++span) { for (uint32_t i = 0; i < rle->size; ++i, ++span) {
auto dst = &surface->buf8[span->y * surface->stride + span->x]; auto dst = &surface->buf8[span->y * surface->stride + span->x];
if (span->coverage < 255) src = MULTIPLY(span->coverage, a); if (span->coverage < 255) src = MULTIPLY(span->coverage, c.a);
else src = a; else src = c.a;
auto ialpha = ~a; auto ialpha = ~c.a;
for (uint32_t x = 0; x < span->len; ++x, ++dst) { for (uint32_t x = 0; x < span->len; ++x, ++dst) {
*dst = src + MULTIPLY(*dst, ialpha); *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<uint32_t>(region.max.y - region.min.y); auto h = static_cast<uint32_t>(region.max.y - region.min.y);
auto w = static_cast<uint32_t>(region.max.x - region.min.x); auto w = static_cast<uint32_t>(region.max.x - region.min.x);
//32bits channels //32bits channels
if (surface->channelSize == sizeof(uint32_t)) { 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 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) { for (uint32_t y = 0; y < h; ++y) {
auto dst = &buffer[y * surface->stride]; auto dst = &buffer[y * surface->stride];
for (uint32_t x = 0; x < w; ++x, ++dst) { for (uint32_t x = 0; x < w; ++x, ++dst) {
@ -145,11 +145,11 @@ static bool inline cRasterTranslucentRect(SwSurface* surface, const SwBBox& regi
//8bit grayscale //8bit grayscale
} else if (surface->channelSize == sizeof(uint8_t)) { } else if (surface->channelSize == sizeof(uint8_t)) {
auto buffer = surface->buf8 + (region.min.y * surface->stride) + region.min.x; 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) { for (uint32_t y = 0; y < h; ++y) {
auto dst = &buffer[y * surface->stride]; auto dst = &buffer[y * surface->stride];
for (uint32_t x = 0; x < w; ++x, ++dst) { for (uint32_t x = 0; x < w; ++x, ++dst) {
*dst = a + MULTIPLY(*dst, ialpha); *dst = c.a + MULTIPLY(*dst, ialpha);
} }
} }
} }

View file

@ -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; auto span = rle->spans;
//32bit channels //32bit channels
if (surface->channelSize == sizeof(uint32_t)) { 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; uint32_t src;
uint8x8_t *vDst = nullptr; uint8x8_t *vDst = nullptr;
uint16_t align; uint16_t align;
@ -134,9 +134,9 @@ static bool neonRasterTranslucentRle(SwSurface* surface, const SwRle* rle, uint8
uint8_t src; uint8_t src;
for (uint32_t i = 0; i < rle->size; ++i, ++span) { for (uint32_t i = 0; i < rle->size; ++i, ++span) {
auto dst = &surface->buf8[span->y * surface->stride + span->x]; auto dst = &surface->buf8[span->y * surface->stride + span->x];
if (span->coverage < 255) src = MULTIPLY(span->coverage, a); if (span->coverage < 255) src = MULTIPLY(span->coverage, c.a);
else src = a; else src = c.a;
auto ialpha = ~a; auto ialpha = ~c.a;
for (uint32_t x = 0; x < span->len; ++x, ++dst) { for (uint32_t x = 0; x < span->len; ++x, ++dst) {
*dst = src + MULTIPLY(*dst, ialpha); *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<uint32_t>(region.max.y - region.min.y); auto h = static_cast<uint32_t>(region.max.y - region.min.y);
auto w = static_cast<uint32_t>(region.max.x - region.min.x); auto w = static_cast<uint32_t>(region.max.x - region.min.x);
//32bits channels //32bits channels
if (surface->channelSize == sizeof(uint32_t)) { 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 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 vColor = vdup_n_u32(color);
auto vIalpha = vdup_n_u8((uint8_t) ialpha); 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)) { } else if (surface->channelSize == sizeof(uint8_t)) {
TVGLOG("SW_ENGINE", "Require Neon Optimization, Channel Size = %d", surface->channelSize); TVGLOG("SW_ENGINE", "Require Neon Optimization, Channel Size = %d", surface->channelSize);
auto buffer = surface->buf8 + (region.min.y * surface->stride) + region.min.x; 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) { for (uint32_t y = 0; y < h; ++y) {
auto dst = &buffer[y * surface->stride]; auto dst = &buffer[y * surface->stride];
for (uint32_t x = 0; x < w; ++x, ++dst) { for (uint32_t x = 0; x < w; ++x, ++dst) {
*dst = a + MULTIPLY(*dst, ialpha); *dst = c.a + MULTIPLY(*dst, ialpha);
} }
} }
} }

View file

@ -85,7 +85,7 @@ struct SwShapeTask : SwTask
Additionally, the stroke style should not be dashed. */ Additionally, the stroke style should not be dashed. */
bool antialiasing(float strokeWidth) 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() float validStrokeWidth()
@ -95,7 +95,7 @@ struct SwShapeTask : SwTask
auto width = rshape->stroke->width; auto width = rshape->stroke->width;
if (tvg::zero(width)) return 0.0f; 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; 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)); return (width * sqrt(transform.e11 * transform.e11 + transform.e12 * transform.e12));
@ -128,8 +128,7 @@ struct SwShapeTask : SwTask
//Shape //Shape
if (flags & (RenderUpdateFlag::Path | RenderUpdateFlag::Transform) || prepareShape) { if (flags & (RenderUpdateFlag::Path | RenderUpdateFlag::Transform) || prepareShape) {
uint8_t alpha = 0; auto alpha = rshape->color.a;
rshape->fillColor(nullptr, nullptr, nullptr, &alpha);
alpha = MULTIPLY(alpha, opacity); alpha = MULTIPLY(alpha, opacity);
visibleFill = (alpha > 0 || rshape->fill); visibleFill = (alpha > 0 || rshape->fill);
shapeReset(&shape); shapeReset(&shape);
@ -270,25 +269,25 @@ static void _termEngine()
static void _renderFill(SwShapeTask* task, SwSurface* surface, uint8_t opacity) static void _renderFill(SwShapeTask* task, SwSurface* surface, uint8_t opacity)
{ {
uint8_t r, g, b, a;
if (auto fill = task->rshape->fill) { if (auto fill = task->rshape->fill) {
rasterGradientShape(surface, &task->shape, fill, opacity); rasterGradientShape(surface, &task->shape, fill, opacity);
} else { } else {
task->rshape->fillColor(&r, &g, &b, &a); RenderColor c;
a = MULTIPLY(opacity, a); task->rshape->fillColor(&c.r, &c.g, &c.b, &c.a);
if (a > 0) rasterShape(surface, &task->shape, r, g, b, 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) static void _renderStroke(SwShapeTask* task, SwSurface* surface, uint8_t opacity)
{ {
uint8_t r, g, b, a;
if (auto strokeFill = task->rshape->strokeFill()) { if (auto strokeFill = task->rshape->strokeFill()) {
rasterGradientStroke(surface, &task->shape, strokeFill, opacity); rasterGradientStroke(surface, &task->shape, strokeFill, opacity);
} else { } else {
if (task->rshape->strokeFill(&r, &g, &b, &a)) { RenderColor c;
a = MULTIPLY(opacity, a); if (task->rshape->strokeFill(&c.r, &c.g, &c.b, &c.a)) {
if (a > 0) rasterStroke(surface, &task->shape, r, g, b, a); c.a = MULTIPLY(opacity, c.a);
if (c.a > 0) rasterStroke(surface, &task->shape, c);
} }
} }
} }

View file

@ -67,6 +67,11 @@ struct RenderSurface
} }
}; };
struct RenderColor
{
uint8_t r, g, b, a;
};
struct RenderCompositor struct RenderCompositor
{ {
MaskMethod method; MaskMethod method;
@ -90,7 +95,7 @@ struct RenderRegion
struct RenderStroke struct RenderStroke
{ {
float width = 0.0f; float width = 0.0f;
uint8_t color[4] = {0, 0, 0, 0}; RenderColor color{};
Fill *fill = nullptr; Fill *fill = nullptr;
float* dashPattern = nullptr; float* dashPattern = nullptr;
uint32_t dashCnt = 0; uint32_t dashCnt = 0;
@ -109,8 +114,7 @@ struct RenderStroke
void operator=(const RenderStroke& rhs) void operator=(const RenderStroke& rhs)
{ {
width = rhs.width; width = rhs.width;
color = rhs.color;
memcpy(color, rhs.color, sizeof(color));
delete(fill); delete(fill);
if (rhs.fill) fill = rhs.fill->duplicate(); if (rhs.fill) fill = rhs.fill->duplicate();
@ -173,7 +177,7 @@ struct RenderShape
} path; } path;
Fill *fill = nullptr; Fill *fill = nullptr;
uint8_t color[4] = {0, 0, 0, 0}; //r, g, b, a RenderColor color{};
RenderStroke *stroke = nullptr; RenderStroke *stroke = nullptr;
FillRule rule = FillRule::Winding; 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 void fillColor(uint8_t* r, uint8_t* g, uint8_t* b, uint8_t* a) const
{ {
if (r) *r = color[0]; if (r) *r = color.r;
if (g) *g = color[1]; if (g) *g = color.g;
if (b) *b = color[2]; if (b) *b = color.b;
if (a) *a = color[3]; if (a) *a = color.a;
} }
float strokeWidth() const float strokeWidth() const
@ -209,10 +213,10 @@ struct RenderShape
{ {
if (!stroke) return false; if (!stroke) return false;
if (r) *r = stroke->color[0]; if (r) *r = stroke->color.r;
if (g) *g = stroke->color[1]; if (g) *g = stroke->color.g;
if (b) *b = stroke->color[2]; if (b) *b = stroke->color.b;
if (a) *a = stroke->color[3]; if (a) *a = stroke->color.a;
return true; return true;
} }

View file

@ -198,12 +198,10 @@ Result Shape::fill(uint8_t r, uint8_t g, uint8_t b, uint8_t a) noexcept
pImpl->flag |= RenderUpdateFlag::Gradient; 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; pImpl->flag |= RenderUpdateFlag::Color;
return Result::Success; return Result::Success;

View file

@ -72,8 +72,8 @@ struct Shape::Impl
if (opacity == 0) return false; if (opacity == 0) return false;
//Shape composition is only necessary when stroking & fill are valid. //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.stroke || rs.stroke->width < FLOAT_EPSILON || (!rs.stroke->fill && rs.stroke->color.a == 0)) return false;
if (!rs.fill && rs.color[3] == 0) return false; if (!rs.fill && rs.color.a == 0) return false;
//translucent fill & stroke //translucent fill & stroke
if (opacity < 255) return true; if (opacity < 255) return true;
@ -270,10 +270,7 @@ struct Shape::Impl
flag |= RenderUpdateFlag::GradientStroke; flag |= RenderUpdateFlag::GradientStroke;
} }
rs.stroke->color[0] = r; rs.stroke->color = {r, g, b, a};
rs.stroke->color[1] = g;
rs.stroke->color[2] = b;
rs.stroke->color[3] = a;
flag |= RenderUpdateFlag::Stroke; flag |= RenderUpdateFlag::Stroke;
} }
@ -285,7 +282,7 @@ struct Shape::Impl
if (!rs.stroke) rs.stroke = new RenderStroke(); if (!rs.stroke) rs.stroke = new RenderStroke();
if (rs.stroke->fill && rs.stroke->fill != f) delete(rs.stroke->fill); if (rs.stroke->fill && rs.stroke->fill != f) delete(rs.stroke->fill);
rs.stroke->fill = f; rs.stroke->fill = f;
rs.stroke->color[3] = 0; rs.stroke->color.a = 0;
flag |= RenderUpdateFlag::Stroke; flag |= RenderUpdateFlag::Stroke;
flag |= RenderUpdateFlag::GradientStroke; flag |= RenderUpdateFlag::GradientStroke;
@ -358,9 +355,7 @@ struct Shape::Impl
//Default Properties //Default Properties
dup->flag = RenderUpdateFlag::All; dup->flag = RenderUpdateFlag::All;
dup->rs.rule = rs.rule; dup->rs.rule = rs.rule;
dup->rs.color = rs.color;
//Color
memcpy(dup->rs.color, rs.color, sizeof(rs.color));
//Path //Path
dup->rs.path.cmds.push(rs.path.cmds); dup->rs.path.cmds.push(rs.path.cmds);
@ -388,7 +383,7 @@ struct Shape::Impl
rs.path.cmds.clear(); rs.path.cmds.clear();
rs.path.pts.clear(); rs.path.pts.clear();
rs.color[3] = 0; rs.color.a = 0;
rs.rule = FillRule::Winding; rs.rule = FillRule::Winding;
delete(rs.stroke); delete(rs.stroke);

View file

@ -233,7 +233,7 @@ void WgImageData::release(WgContext& context)
// WgRenderSettings // 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 // setup fill properties
if ((flags & (RenderUpdateFlag::Gradient)) && fill) { if ((flags & (RenderUpdateFlag::Gradient)) && fill) {
@ -270,15 +270,15 @@ void WgRenderSettings::update(WgContext& context, const Fill* fill, const uint8_
sampler, texViewGradient, bufferGroupGradient, bufferGroupTransfromGrad); sampler, texViewGradient, bufferGroupGradient, bufferGroupTransfromGrad);
} }
skip = false; skip = false;
} else if ((flags & (RenderUpdateFlag::Color)) && !fill) { } else if ((flags & RenderUpdateFlag::Color) && !fill) {
rasterType = WgRenderRasterType::Solid; rasterType = WgRenderRasterType::Solid;
WgShaderTypeSolidColor solidColor(color); WgShaderTypeSolidColor solidColor(c);
if (context.allocateBufferUniform(bufferGroupSolid, &solidColor, sizeof(solidColor))) { if (context.allocateBufferUniform(bufferGroupSolid, &solidColor, sizeof(solidColor))) {
context.pipelines->layouts.releaseBindGroup(bindGroupSolid); context.pipelines->layouts.releaseBindGroup(bindGroupSolid);
bindGroupSolid = context.pipelines->layouts.createBindGroupBuffer1Un(bufferGroupSolid); bindGroupSolid = context.pipelines->layouts.createBindGroupBuffer1Un(bufferGroupSolid);
} }
fillType = WgRenderSettingsType::Solid; fillType = WgRenderSettingsType::Solid;
skip = (color[3] == 0); skip = (c.a == 0);
} }
}; };

View file

@ -90,7 +90,7 @@ struct WgRenderSettings
WgRenderRasterType rasterType{}; WgRenderRasterType rasterType{};
bool skip{}; 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); void release(WgContext& context);
}; };

View file

@ -369,7 +369,7 @@ bool WgRenderer::beginComposite(RenderCompositor* cmp, MaskMethod method, uint8_
mRenderStorageStack.push(storage); mRenderStorageStack.push(storage);
// begin newly added render pass // begin newly added render pass
WGPUColor color{}; 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); mCompositor.beginRenderPass(mCommandEncoder, mRenderStorageStack.last(), true, color);
return true; return true;
} }

View file

@ -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); update(c);
} }
void WgShaderTypeSolidColor::update(const uint8_t* c) void WgShaderTypeSolidColor::update(const RenderColor& c)
{ {
color[0] = c[0] / 255.0f; // red color[0] = c.r / 255.0f; // red
color[1] = c[1] / 255.0f; // green color[1] = c.g / 255.0f; // green
color[2] = c[2] / 255.0f; // blue color[2] = c.b / 255.0f; // blue
color[3] = c[3] / 255.0f; // alpha color[3] = c.a / 255.0f; // alpha
} }

View file

@ -57,8 +57,8 @@ struct WgShaderTypeSolidColor
{ {
float color[4]{}; float color[4]{};
WgShaderTypeSolidColor(const uint8_t* c); WgShaderTypeSolidColor(const RenderColor& c);
void update(const uint8_t* c); void update(const RenderColor& c);
}; };
// sampler, texture, vec4f // sampler, texture, vec4f