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 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<size_t>(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) &&

View file

@ -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<RenderData>& clips);

View file

@ -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);

View file

@ -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<uint32_t>(region.max.x - region.min.x);
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 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
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<uint32_t>(region.max.x - region.min.x);
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
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<uint32_t>(region.max.x - region.min.x);
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;
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<uint32_t>(region.max.x - region.min.x);
auto h = static_cast<uint32_t>(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);
}

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 w = static_cast<uint32_t>(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);
}

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;
//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<uint32_t>(region.max.y - region.min.y);
auto w = static_cast<uint32_t>(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);
}
}
}

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;
//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<uint32_t>(region.max.y - region.min.y);
auto w = static_cast<uint32_t>(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);
}
}
}

View file

@ -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);
}
}
}

View file

@ -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;
}

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;
}
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;

View file

@ -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);

View file

@ -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);
}
};

View file

@ -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);
};

View file

@ -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;
}

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);
}
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
}

View file

@ -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