mirror of
https://github.com/thorvg/thorvg.git
synced 2025-06-08 13:43:43 +00:00
sw_engine: code refactoring
Removed the fake blender structure. Unified matting and join as Surface methods.
This commit is contained in:
parent
814d87626c
commit
b60a291edc
5 changed files with 33 additions and 38 deletions
|
@ -242,10 +242,13 @@ struct SwImage
|
||||||
typedef uint32_t(*SwJoin)(uint8_t r, uint8_t g, uint8_t b, uint8_t a); //color channel join
|
typedef uint32_t(*SwJoin)(uint8_t r, uint8_t g, uint8_t b, uint8_t a); //color channel join
|
||||||
typedef uint8_t(*SwAlpha)(uint8_t*); //blending alpha
|
typedef uint8_t(*SwAlpha)(uint8_t*); //blending alpha
|
||||||
|
|
||||||
struct SwBlender
|
struct SwCompositor;
|
||||||
|
|
||||||
|
struct SwSurface : Surface
|
||||||
{
|
{
|
||||||
SwJoin join;
|
SwJoin join;
|
||||||
SwAlpha alphas[4]; //Alpha:2, InvAlpha:3, Luma:4, InvLuma:5
|
SwAlpha alphas[4]; //Alpha:2, InvAlpha:3, Luma:4, InvLuma:5
|
||||||
|
SwCompositor* compositor = nullptr; //compositor (optional)
|
||||||
|
|
||||||
SwAlpha alpha(CompositeMethod method)
|
SwAlpha alpha(CompositeMethod method)
|
||||||
{
|
{
|
||||||
|
@ -254,14 +257,6 @@ struct SwBlender
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
struct SwCompositor;
|
|
||||||
|
|
||||||
struct SwSurface : Surface
|
|
||||||
{
|
|
||||||
SwBlender blender; //mandatory
|
|
||||||
SwCompositor* compositor = nullptr; //compositor (optional)
|
|
||||||
};
|
|
||||||
|
|
||||||
struct SwCompositor : Compositor
|
struct SwCompositor : Compositor
|
||||||
{
|
{
|
||||||
SwSurface* recoverSfc; //Recover surface when composition is started
|
SwSurface* recoverSfc; //Recover surface when composition is started
|
||||||
|
|
|
@ -52,7 +52,7 @@ static bool _updateColorTable(SwFill* fill, const Fill* fdata, const SwSurface*
|
||||||
auto r = pColors->r;
|
auto r = pColors->r;
|
||||||
auto g = pColors->g;
|
auto g = pColors->g;
|
||||||
auto b = pColors->b;
|
auto b = pColors->b;
|
||||||
auto rgba = surface->blender.join(r, g, b, a);
|
auto rgba = surface->join(r, g, b, a);
|
||||||
|
|
||||||
auto inc = 1.0f / static_cast<float>(GRADIENT_STOP_SIZE);
|
auto inc = 1.0f / static_cast<float>(GRADIENT_STOP_SIZE);
|
||||||
auto pos = 1.5f * inc;
|
auto pos = 1.5f * inc;
|
||||||
|
@ -73,7 +73,7 @@ static bool _updateColorTable(SwFill* fill, const Fill* fdata, const SwSurface*
|
||||||
auto a2 = MULTIPLY(next->a, opacity);
|
auto a2 = MULTIPLY(next->a, opacity);
|
||||||
if (!fill->translucent && a2 < 255) fill->translucent = true;
|
if (!fill->translucent && a2 < 255) fill->translucent = true;
|
||||||
|
|
||||||
auto rgba2 = surface->blender.join(next->r, next->g, next->b, a2);
|
auto rgba2 = surface->join(next->r, next->g, next->b, a2);
|
||||||
|
|
||||||
while (pos < next->offset && i < GRADIENT_STOP_SIZE) {
|
while (pos < next->offset && i < GRADIENT_STOP_SIZE) {
|
||||||
auto t = (pos - curr->offset) * delta;
|
auto t = (pos - curr->offset) * delta;
|
||||||
|
|
|
@ -275,7 +275,7 @@ static void _rasterMaskedRectDup(SwSurface* surface, const SwBBox& region, uint8
|
||||||
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 cbuffer = surface->compositor->image.buf32 + (region.min.y * surface->compositor->image.stride + region.min.x); //compositor buffer
|
auto cbuffer = surface->compositor->image.buf32 + (region.min.y * surface->compositor->image.stride + region.min.x); //compositor buffer
|
||||||
auto cstride = surface->compositor->image.stride;
|
auto cstride = surface->compositor->image.stride;
|
||||||
auto color = surface->blender.join(r, g, b, a);
|
auto color = surface->join(r, g, b, a);
|
||||||
auto ialpha = 255 - a;
|
auto ialpha = 255 - a;
|
||||||
|
|
||||||
for (uint32_t y = 0; y < h; ++y) {
|
for (uint32_t y = 0; y < h; ++y) {
|
||||||
|
@ -348,13 +348,13 @@ static bool _rasterMattedRect(SwSurface* surface, const SwBBox& region, uint8_t
|
||||||
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 csize = surface->compositor->image.channelSize;
|
auto csize = surface->compositor->image.channelSize;
|
||||||
auto cbuffer = surface->compositor->image.buf8 + ((region.min.y * surface->compositor->image.stride + region.min.x) * csize); //compositor buffer
|
auto cbuffer = surface->compositor->image.buf8 + ((region.min.y * surface->compositor->image.stride + region.min.x) * csize); //compositor buffer
|
||||||
auto alpha = surface->blender.alpha(surface->compositor->method);
|
auto alpha = surface->alpha(surface->compositor->method);
|
||||||
|
|
||||||
TVGLOG("SW_ENGINE", "Matted(%d) Rect [Region: %lu %lu %u %u]", (int)surface->compositor->method, region.min.x, region.min.y, w, h);
|
TVGLOG("SW_ENGINE", "Matted(%d) Rect [Region: %lu %lu %u %u]", (int)surface->compositor->method, region.min.x, region.min.y, w, h);
|
||||||
|
|
||||||
//32bits channels
|
//32bits channels
|
||||||
if (surface->channelSize == sizeof(uint32_t)) {
|
if (surface->channelSize == sizeof(uint32_t)) {
|
||||||
auto color = surface->blender.join(r, g, b, a);
|
auto color = surface->join(r, g, b, 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];
|
||||||
|
@ -385,7 +385,7 @@ static bool _rasterSolidRect(SwSurface* surface, const SwBBox& region, uint8_t r
|
||||||
|
|
||||||
//32bits channels
|
//32bits channels
|
||||||
if (surface->channelSize == sizeof(uint32_t)) {
|
if (surface->channelSize == sizeof(uint32_t)) {
|
||||||
auto color = surface->blender.join(r, g, b, 255);
|
auto color = surface->join(r, g, 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) {
|
||||||
rasterRGBA32(buffer + y * surface->stride, color, region.min.x, w);
|
rasterRGBA32(buffer + y * surface->stride, color, region.min.x, w);
|
||||||
|
@ -435,7 +435,7 @@ static void _rasterMaskedRleDup(SwSurface* surface, SwRleData* rle, uint8_t r, u
|
||||||
auto span = rle->spans;
|
auto span = rle->spans;
|
||||||
auto cbuffer = surface->compositor->image.buf32;
|
auto cbuffer = surface->compositor->image.buf32;
|
||||||
auto cstride = surface->compositor->image.stride;
|
auto cstride = surface->compositor->image.stride;
|
||||||
auto color = surface->blender.join(r, g, b, a);
|
auto color = surface->join(r, g, b, 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) {
|
||||||
|
@ -455,7 +455,7 @@ static void _rasterMaskedRleInt(SwSurface* surface, SwRleData* rle, uint8_t r, u
|
||||||
auto span = rle->spans;
|
auto span = rle->spans;
|
||||||
auto cbuffer = surface->compositor->image.buf32;
|
auto cbuffer = surface->compositor->image.buf32;
|
||||||
auto cstride = surface->compositor->image.stride;
|
auto cstride = surface->compositor->image.stride;
|
||||||
auto color = surface->blender.join(r, g, b, a);
|
auto color = surface->join(r, g, b, a);
|
||||||
uint32_t src;
|
uint32_t src;
|
||||||
|
|
||||||
for (uint32_t y = surface->compositor->bbox.min.y; y < surface->compositor->bbox.max.y; ++y) {
|
for (uint32_t y = surface->compositor->bbox.min.y; y < surface->compositor->bbox.max.y; ++y) {
|
||||||
|
@ -507,12 +507,12 @@ static bool _rasterMattedRle(SwSurface* surface, SwRleData* rle, uint8_t r, uint
|
||||||
auto span = rle->spans;
|
auto span = rle->spans;
|
||||||
auto cbuffer = surface->compositor->image.buf8;
|
auto cbuffer = surface->compositor->image.buf8;
|
||||||
auto csize = surface->compositor->image.channelSize;
|
auto csize = surface->compositor->image.channelSize;
|
||||||
auto alpha = surface->blender.alpha(surface->compositor->method);
|
auto alpha = surface->alpha(surface->compositor->method);
|
||||||
|
|
||||||
//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->blender.join(r, g, b, a);
|
auto color = surface->join(r, g, b, 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];
|
||||||
|
@ -548,7 +548,7 @@ static bool _rasterSolidRle(SwSurface* surface, const SwRleData* rle, uint8_t r,
|
||||||
|
|
||||||
//32bit channels
|
//32bit channels
|
||||||
if (surface->channelSize == sizeof(uint32_t)) {
|
if (surface->channelSize == sizeof(uint32_t)) {
|
||||||
auto color = surface->blender.join(r, g, b, 255);
|
auto color = surface->join(r, g, 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) {
|
||||||
rasterRGBA32(surface->buf32 + span->y * surface->stride, color, span->x, span->len);
|
rasterRGBA32(surface->buf32 + span->y * surface->stride, color, span->x, span->len);
|
||||||
|
@ -709,7 +709,7 @@ static bool _rasterScaledMattedRleRGBAImage(SwSurface* surface, const SwImage* i
|
||||||
|
|
||||||
auto span = image->rle->spans;
|
auto span = image->rle->spans;
|
||||||
auto csize = surface->compositor->image.channelSize;
|
auto csize = surface->compositor->image.channelSize;
|
||||||
auto alpha = surface->blender.alpha(surface->compositor->method);
|
auto alpha = surface->alpha(surface->compositor->method);
|
||||||
|
|
||||||
auto scaleMethod = image->scale < DOWN_SCALE_TOLERANCE ? _interpDownScaler : _interpUpScaler;
|
auto scaleMethod = image->scale < DOWN_SCALE_TOLERANCE ? _interpDownScaler : _interpUpScaler;
|
||||||
|
|
||||||
|
@ -878,7 +878,7 @@ static bool _rasterDirectMattedRleRGBAImage(SwSurface* surface, const SwImage* i
|
||||||
auto span = image->rle->spans;
|
auto span = image->rle->spans;
|
||||||
auto csize = surface->compositor->image.channelSize;
|
auto csize = surface->compositor->image.channelSize;
|
||||||
auto cbuffer = surface->compositor->image.buf8;
|
auto cbuffer = surface->compositor->image.buf8;
|
||||||
auto alpha = surface->blender.alpha(surface->compositor->method);
|
auto alpha = surface->alpha(surface->compositor->method);
|
||||||
|
|
||||||
for (uint32_t i = 0; i < image->rle->size; ++i, ++span) {
|
for (uint32_t i = 0; i < image->rle->size; ++i, ++span) {
|
||||||
auto dst = &surface->buf32[span->y * surface->stride + span->x];
|
auto dst = &surface->buf32[span->y * surface->stride + span->x];
|
||||||
|
@ -1068,7 +1068,7 @@ static bool _rasterScaledMattedRGBAImage(SwSurface* surface, const SwImage* imag
|
||||||
auto dbuffer = surface->buf32 + (region.min.y * surface->stride + region.min.x);
|
auto dbuffer = surface->buf32 + (region.min.y * surface->stride + region.min.x);
|
||||||
auto csize = surface->compositor->image.channelSize;
|
auto csize = surface->compositor->image.channelSize;
|
||||||
auto cbuffer = surface->compositor->image.buf8 + (region.min.y * surface->compositor->image.stride + region.min.x) * csize;
|
auto cbuffer = surface->compositor->image.buf8 + (region.min.y * surface->compositor->image.stride + region.min.x) * csize;
|
||||||
auto alpha = surface->blender.alpha(surface->compositor->method);
|
auto alpha = surface->alpha(surface->compositor->method);
|
||||||
|
|
||||||
TVGLOG("SW_ENGINE", "Scaled Matted(%d) Image [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", "Scaled Matted(%d) Image [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);
|
||||||
|
|
||||||
|
@ -1251,7 +1251,7 @@ static bool _rasterDirectMattedRGBAImage(SwSurface* surface, const SwImage* imag
|
||||||
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);
|
||||||
auto csize = surface->compositor->image.channelSize;
|
auto csize = surface->compositor->image.channelSize;
|
||||||
auto alpha = surface->blender.alpha(surface->compositor->method);
|
auto alpha = surface->alpha(surface->compositor->method);
|
||||||
|
|
||||||
TVGLOG("SW_ENGINE", "Direct Matted(%d) Image [Region: %lu %lu %u %u]", (int)surface->compositor->method, region.min.x, region.min.y, w, h);
|
TVGLOG("SW_ENGINE", "Direct Matted(%d) Image [Region: %lu %lu %u %u]", (int)surface->compositor->method, region.min.x, region.min.y, w, h);
|
||||||
|
|
||||||
|
@ -1416,7 +1416,7 @@ static bool _rasterGradientMattedRect(SwSurface* surface, const SwBBox& region,
|
||||||
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 csize = surface->compositor->image.channelSize;
|
auto csize = surface->compositor->image.channelSize;
|
||||||
auto cbuffer = surface->compositor->image.buf8 + (region.min.y * surface->compositor->image.stride + region.min.x) * csize;
|
auto cbuffer = surface->compositor->image.buf8 + (region.min.y * surface->compositor->image.stride + region.min.x) * csize;
|
||||||
auto alpha = surface->blender.alpha(surface->compositor->method);
|
auto alpha = surface->alpha(surface->compositor->method);
|
||||||
|
|
||||||
TVGLOG("SW_ENGINE", "Matted(%d) Gradient [Region: %lu %lu %u %u]", (int)surface->compositor->method, region.min.x, region.min.y, w, h);
|
TVGLOG("SW_ENGINE", "Matted(%d) Gradient [Region: %lu %lu %u %u]", (int)surface->compositor->method, region.min.x, region.min.y, w, h);
|
||||||
|
|
||||||
|
@ -1557,7 +1557,7 @@ static bool _rasterGradientMattedRle(SwSurface* surface, const SwRleData* rle, c
|
||||||
auto span = rle->spans;
|
auto span = rle->spans;
|
||||||
auto csize = surface->compositor->image.channelSize;
|
auto csize = surface->compositor->image.channelSize;
|
||||||
auto cbuffer = surface->compositor->image.buf8;
|
auto cbuffer = surface->compositor->image.buf8;
|
||||||
auto alpha = surface->blender.alpha(surface->compositor->method);
|
auto alpha = surface->alpha(surface->compositor->method);
|
||||||
|
|
||||||
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];
|
||||||
|
@ -1644,17 +1644,17 @@ void rasterRGBA32(uint32_t *dst, uint32_t val, uint32_t offset, int32_t len)
|
||||||
bool rasterCompositor(SwSurface* surface)
|
bool rasterCompositor(SwSurface* surface)
|
||||||
{
|
{
|
||||||
//See CompositeMethod, Alpha:3, InvAlpha:4, Luma:5, InvLuma:6
|
//See CompositeMethod, Alpha:3, InvAlpha:4, Luma:5, InvLuma:6
|
||||||
surface->blender.alphas[0] = ALPHA;
|
surface->alphas[0] = ALPHA;
|
||||||
surface->blender.alphas[1] = IALPHA;
|
surface->alphas[1] = IALPHA;
|
||||||
|
|
||||||
if (surface->cs == ColorSpace::ABGR8888 || surface->cs == ColorSpace::ABGR8888S) {
|
if (surface->cs == ColorSpace::ABGR8888 || surface->cs == ColorSpace::ABGR8888S) {
|
||||||
surface->blender.join = _abgrJoin;
|
surface->join = _abgrJoin;
|
||||||
surface->blender.alphas[2] = _abgrLuma;
|
surface->alphas[2] = _abgrLuma;
|
||||||
surface->blender.alphas[3] = _abgrInvLuma;
|
surface->alphas[3] = _abgrInvLuma;
|
||||||
} else if (surface->cs == ColorSpace::ARGB8888 || surface->cs == ColorSpace::ARGB8888S) {
|
} else if (surface->cs == ColorSpace::ARGB8888 || surface->cs == ColorSpace::ARGB8888S) {
|
||||||
surface->blender.join = _argbJoin;
|
surface->join = _argbJoin;
|
||||||
surface->blender.alphas[2] = _argbLuma;
|
surface->alphas[2] = _argbLuma;
|
||||||
surface->blender.alphas[3] = _argbInvLuma;
|
surface->alphas[3] = _argbInvLuma;
|
||||||
} else {
|
} else {
|
||||||
TVGERR("SW_ENGINE", "Unsupported Colorspace(%d) is expected!", surface->cs);
|
TVGERR("SW_ENGINE", "Unsupported Colorspace(%d) is expected!", surface->cs);
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -68,7 +68,7 @@ static bool inline cRasterTranslucentRle(SwSurface* surface, const SwRleData* rl
|
||||||
|
|
||||||
//32bit channels
|
//32bit channels
|
||||||
if (surface->channelSize == sizeof(uint32_t)) {
|
if (surface->channelSize == sizeof(uint32_t)) {
|
||||||
auto color = surface->blender.join(r, g, b, a);
|
auto color = surface->join(r, g, b, 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];
|
||||||
|
@ -103,7 +103,7 @@ static bool inline cRasterTranslucentRect(SwSurface* surface, const SwBBox& regi
|
||||||
|
|
||||||
//32bits channels
|
//32bits channels
|
||||||
if (surface->channelSize == sizeof(uint32_t)) {
|
if (surface->channelSize == sizeof(uint32_t)) {
|
||||||
auto color = surface->blender.join(r, g, b, a);
|
auto color = surface->join(r, g, b, 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 = IALPHA(color);
|
auto ialpha = IALPHA(color);
|
||||||
for (uint32_t y = 0; y < h; ++y) {
|
for (uint32_t y = 0; y < h; ++y) {
|
||||||
|
|
|
@ -450,7 +450,7 @@ static void _rasterPolygonImageSegment(SwSurface* surface, const SwImage* image,
|
||||||
|
|
||||||
//for matting(composition)
|
//for matting(composition)
|
||||||
auto csize = matting ? surface->compositor->image.channelSize: 0;
|
auto csize = matting ? surface->compositor->image.channelSize: 0;
|
||||||
auto alpha = matting ? surface->blender.alpha(surface->compositor->method) : nullptr;
|
auto alpha = matting ? surface->alpha(surface->compositor->method) : nullptr;
|
||||||
uint8_t* cmp = nullptr;
|
uint8_t* cmp = nullptr;
|
||||||
|
|
||||||
if (!_arrange(image, region, yStart, yEnd)) return;
|
if (!_arrange(image, region, yStart, yEnd)) return;
|
||||||
|
|
Loading…
Add table
Reference in a new issue