sw_engine raster: code refactoring.

+ blending stages using macro magics.

I know this is a bit bad for code readibility but good for the maintanence
This commit is contained in:
Hermet Park 2021-11-25 19:23:35 +09:00 committed by Hermet Park
parent eddaf615c3
commit 860068301a

View file

@ -1076,7 +1076,7 @@ static bool _transformedRGBAImage(SwSurface* surface, const SwImage* image, cons
/************************************************************************/ /************************************************************************/
static bool _rasterScaledMaskedTranslucentRGBAImage(SwSurface* surface, const SwImage* image, const Matrix* itransform, const SwBBox& region, uint32_t opacity, uint32_t halfScale, uint32_t (*blendMethod)(uint32_t)) static bool _rasterScaledMaskedRGBAImage(SwSurface* surface, const SwImage* image, const Matrix* itransform, const SwBBox& region, uint32_t halfScale, uint32_t (*blendMethod)(uint32_t), TVG_UNUSED uint32_t opacity)
{ {
TVGLOG("SW_ENGINE", "Scaled Masked Image"); TVGLOG("SW_ENGINE", "Scaled Masked Image");
@ -1089,8 +1089,12 @@ static bool _rasterScaledMaskedTranslucentRGBAImage(SwSurface* surface, const Sw
auto cmp = surface->compositor->image.data + (y * surface->compositor->image.stride + region.min.x); auto cmp = surface->compositor->image.data + (y * surface->compositor->image.stride + region.min.x);
auto img = image->data + static_cast<uint32_t>(y * itransform->e22 + itransform->e23) * image->stride; auto img = image->data + static_cast<uint32_t>(y * itransform->e22 + itransform->e23) * image->stride;
for (auto x = region.min.x; x < region.max.x; ++x, ++dst, ++cmp) { for (auto x = region.min.x; x < region.max.x; ++x, ++dst, ++cmp) {
#ifdef RASTER_TRANSLUCENT
auto alpha = _multiplyAlpha(opacity, blendMethod(*cmp)); auto alpha = _multiplyAlpha(opacity, blendMethod(*cmp));
auto src = ALPHA_BLEND(img[static_cast<uint32_t>(x * itransform->e11 + itransform->e13)], alpha); auto src = ALPHA_BLEND(img[static_cast<uint32_t>(x * itransform->e11 + itransform->e13)], alpha);
#else
auto src = ALPHA_BLEND(img[static_cast<uint32_t>(x * itransform->e11 + itransform->e13)], blendMethod(*cmp));
#endif
*dst = src + ALPHA_BLEND(*dst, surface->blender.ialpha(src)); *dst = src + ALPHA_BLEND(*dst, surface->blender.ialpha(src));
} }
} }
@ -1103,77 +1107,12 @@ static bool _rasterScaledMaskedTranslucentRGBAImage(SwSurface* surface, const Sw
auto cmp = surface->compositor->image.data + ((region.min.y + 1) * surface->compositor->image.stride + x); auto cmp = surface->compositor->image.data + ((region.min.y + 1) * surface->compositor->image.stride + x);
auto img = image->data + static_cast<uint32_t>(x * itransform->e11 + itransform->e13); auto img = image->data + static_cast<uint32_t>(x * itransform->e11 + itransform->e13);
for (auto y = region.min.y + 1; y < region.max.y - 1; ++y, dst += surface->stride, cmp += surface->stride) { for (auto y = region.min.y + 1; y < region.max.y - 1; ++y, dst += surface->stride, cmp += surface->stride) {
#ifdef RASTER_TRANSLUCENT
auto alpha = _multiplyAlpha(opacity, blendMethod(*cmp)); auto alpha = _multiplyAlpha(opacity, blendMethod(*cmp));
auto src = ALPHA_BLEND(img[static_cast<uint32_t>(y * itransform->e22 + itransform->e23) * image->stride], alpha); auto src = ALPHA_BLEND(img[static_cast<uint32_t>(y * itransform->e22 + itransform->e23) * image->stride], alpha);
*dst = src + ALPHA_BLEND(*dst, surface->blender.ialpha(src)); #else
}
}
//Center (Down-Scaled)
if (image->scale < DOWN_SCALE_TOLERANCE) {
auto dbuffer = surface->buffer + ((region.min.y + 1) * surface->stride + (region.min.x + 1));
auto cbuffer = surface->compositor->image.data + ((region.min.y + 1) * surface->compositor->image.stride + (region.min.x + 1));
for (auto y = region.min.y + 1; y < region.max.y - 1; ++y) {
auto dst = dbuffer;
auto cmp = cbuffer;
auto sy = static_cast<uint32_t>(y * itransform->e22 + itransform->e23);
for (auto x = region.min.x + 1; x < region.max.x - 1; ++x, ++dst, ++cmp) {
auto alpha = _multiplyAlpha(opacity, blendMethod(*cmp));
auto sx = static_cast<uint32_t>(x * itransform->e11 + itransform->e13);
auto src = ALPHA_BLEND(_interpDownScaler(image->data, image->w, image->h, sx, sy, halfScale), alpha);
*dst = src + ALPHA_BLEND(*dst, surface->blender.ialpha(src));
}
dbuffer += surface->stride;
cbuffer += surface->compositor->image.stride;
}
//Center (Up-Scaled)
} else {
auto dbuffer = surface->buffer + (region.min.y * surface->stride + region.min.x);
auto cbuffer = surface->compositor->image.data + (region.min.y * surface->compositor->image.stride + region.min.x);
for (auto y = region.min.y; y < region.max.y - 1; ++y) {
auto dst = dbuffer;
auto cmp = cbuffer;
auto sy = y * itransform->e22 + itransform->e23;
for (auto x = region.min.x; x < region.max.x - 1; ++x, ++dst, ++cmp) {
auto alpha = _multiplyAlpha(opacity, blendMethod(*cmp));
auto sx = x * itransform->e11 + itransform->e13;
auto src = ALPHA_BLEND(_interpUpScaler(image->data, image->w, image->h, sx, sy), alpha);
*dst = src + ALPHA_BLEND(*dst, surface->blender.ialpha(src));
}
dbuffer += surface->stride;
cbuffer += surface->compositor->image.stride;
}
}
return true;
}
static bool _rasterScaledMaskedRGBAImage(SwSurface* surface, const SwImage* image, const Matrix* itransform, const SwBBox& region, uint32_t halfScale, uint32_t (*blendMethod)(uint32_t))
{
TVGLOG("SW_ENGINE", "Scaled Masked Image");
//Top, Bottom Lines
SwCoord ys[2] = {region.min.y, region.max.y - 1};
for (auto i = 0; i < 2; ++i) {
auto y = ys[i];
auto dst = surface->buffer + (y * surface->stride + region.min.x);
auto cmp = surface->compositor->image.data + (y * surface->compositor->image.stride + region.min.x);
auto img = image->data + static_cast<uint32_t>(y * itransform->e22 + itransform->e23) * image->stride;
for (auto x = region.min.x; x < region.max.x; ++x, ++dst, ++cmp) {
auto src = ALPHA_BLEND(img[static_cast<uint32_t>(x * itransform->e11 + itransform->e13)], blendMethod(*cmp));
*dst = src + ALPHA_BLEND(*dst, surface->blender.ialpha(src));
}
}
//Left, Right Lines
SwCoord xs[2] = {region.min.x, region.max.x - 1};
for (auto i = 0; i < 2; ++i) {
auto x = xs[i];
auto dst = surface->buffer + ((region.min.y + 1) * surface->stride + x);
auto cmp = surface->compositor->image.data + ((region.min.y + 1) * surface->compositor->image.stride + x);
auto img = image->data + static_cast<uint32_t>(x * itransform->e11 + itransform->e13);
for (auto y = region.min.y + 1; y < region.max.y - 1; ++y, dst += surface->stride, cmp += surface->stride) {
auto src = ALPHA_BLEND(img[static_cast<uint32_t>(y * itransform->e22 + itransform->e23) * image->stride], blendMethod(*cmp)); auto src = ALPHA_BLEND(img[static_cast<uint32_t>(y * itransform->e22 + itransform->e23) * image->stride], blendMethod(*cmp));
#endif
*dst = src + ALPHA_BLEND(*dst, surface->blender.ialpha(src)); *dst = src + ALPHA_BLEND(*dst, surface->blender.ialpha(src));
} }
} }
@ -1187,7 +1126,12 @@ static bool _rasterScaledMaskedRGBAImage(SwSurface* surface, const SwImage* imag
auto sy = static_cast<uint32_t>(y * itransform->e22 + itransform->e23); auto sy = static_cast<uint32_t>(y * itransform->e22 + itransform->e23);
for (auto x = region.min.x + 1; x < region.max.x - 1; ++x, ++dst, ++cmp) { for (auto x = region.min.x + 1; x < region.max.x - 1; ++x, ++dst, ++cmp) {
auto sx = static_cast<uint32_t>(x * itransform->e11 + itransform->e13); auto sx = static_cast<uint32_t>(x * itransform->e11 + itransform->e13);
#ifdef RASTER_TRANSLUCENT
auto alpha = _multiplyAlpha(opacity, blendMethod(*cmp));
auto src = ALPHA_BLEND(_interpDownScaler(image->data, image->w, image->h, sx, sy, halfScale), alpha);
#else
auto src = ALPHA_BLEND(_interpDownScaler(image->data, image->w, image->h, sx, sy, halfScale), blendMethod(*cmp)); auto src = ALPHA_BLEND(_interpDownScaler(image->data, image->w, image->h, sx, sy, halfScale), blendMethod(*cmp));
#endif
*dst = src + ALPHA_BLEND(*dst, surface->blender.ialpha(src)); *dst = src + ALPHA_BLEND(*dst, surface->blender.ialpha(src));
} }
dbuffer += surface->stride; dbuffer += surface->stride;
@ -1203,7 +1147,12 @@ static bool _rasterScaledMaskedRGBAImage(SwSurface* surface, const SwImage* imag
auto sy = y * itransform->e22 + itransform->e23; auto sy = y * itransform->e22 + itransform->e23;
for (auto x = region.min.x; x < region.max.x - 1; ++x, ++dst, ++cmp) { for (auto x = region.min.x; x < region.max.x - 1; ++x, ++dst, ++cmp) {
auto sx = x * itransform->e11 + itransform->e13; auto sx = x * itransform->e11 + itransform->e13;
#ifdef RASTER_TRANSLUCENT
auto alpha = _multiplyAlpha(opacity, blendMethod(*cmp));
auto src = ALPHA_BLEND(_interpUpScaler(image->data, image->w, image->h, sx, sy), alpha);
#else
auto src = ALPHA_BLEND(_interpUpScaler(image->data, image->w, image->h, sx, sy), blendMethod(*cmp)); auto src = ALPHA_BLEND(_interpUpScaler(image->data, image->w, image->h, sx, sy), blendMethod(*cmp));
#endif
*dst = src + ALPHA_BLEND(*dst, surface->blender.ialpha(src)); *dst = src + ALPHA_BLEND(*dst, surface->blender.ialpha(src));
} }
dbuffer += surface->stride; dbuffer += surface->stride;
@ -1214,62 +1163,15 @@ static bool _rasterScaledMaskedRGBAImage(SwSurface* surface, const SwImage* imag
} }
static bool _rasterScaledTranslucentRGBAImage(SwSurface* surface, const SwImage* image, const Matrix* itransform, const SwBBox& region, uint32_t opacity, uint32_t halfScale) static bool _rasterScaledMaskedTranslucentRGBAImage(SwSurface* surface, const SwImage* image, const Matrix* itransform, const SwBBox& region, uint32_t halfScale, uint32_t (*blendMethod)(uint32_t), uint32_t opacity)
{ {
//Top, Bottom Lines #define RASTER_TRANSLUCENT
SwCoord ys[2] = {region.min.y, region.max.y - 1}; return _rasterScaledMaskedRGBAImage(surface, image, itransform, region, halfScale, blendMethod, opacity);
#undef RASTER_TRANSLUCENT
for (auto i = 0; i < 2; ++i) {
auto y = ys[i];
auto dst = surface->buffer + (y * surface->stride + region.min.x);
auto img = image->data + static_cast<uint32_t>(y * itransform->e22 + itransform->e23) * image->stride;
for (auto x = region.min.x; x < region.max.x; ++x, ++dst) {
auto src = ALPHA_BLEND(img[static_cast<uint32_t>(x * itransform->e11 + itransform->e13)], opacity);
*dst = src + ALPHA_BLEND(*dst, surface->blender.ialpha(src));
}
}
//Left, Right Lines
SwCoord xs[2] = {region.min.x, region.max.x - 1};
for (auto i = 0; i < 2; ++i) {
auto x = xs[i];
auto dst = surface->buffer + ((region.min.y + 1) * surface->stride + x);
auto img = image->data + static_cast<uint32_t>(x * itransform->e11 + itransform->e13);
for (auto y = region.min.y + 1; y < region.max.y - 1; ++y, dst += surface->stride) {
auto src = ALPHA_BLEND(img[static_cast<uint32_t>(y * itransform->e22 + itransform->e23) * image->stride], opacity);
*dst = src + ALPHA_BLEND(*dst, surface->blender.ialpha(src));
}
}
//Center (Down-Scaled)
if (image->scale < DOWN_SCALE_TOLERANCE) {
auto dbuffer = surface->buffer + ((region.min.y + 1) * surface->stride + (region.min.x + 1));
for (auto y = region.min.y + 1; y < region.max.y - 1; ++y, dbuffer += surface->stride) {
auto sy = static_cast<uint32_t>(y * itransform->e22 + itransform->e23);
auto dst = dbuffer;
for (auto x = region.min.x + 1; x < region.max.x - 1; ++x, ++dst) {
auto sx = static_cast<uint32_t>(x * itransform->e11 + itransform->e13);
auto src = ALPHA_BLEND(_interpDownScaler(image->data, image->w, image->h, sx, sy, halfScale), opacity);
*dst = src + ALPHA_BLEND(*dst, surface->blender.ialpha(src));
}
}
//Center (Up-Scaled)
} else {
auto dbuffer = surface->buffer + (region.min.y * surface->stride + region.min.x);
for (auto y = region.min.y; y < region.max.y - 1; ++y, dbuffer += surface->stride) {
auto sy = y * itransform->e22 + itransform->e23;
auto dst = dbuffer;
for (auto x = region.min.x; x < region.max.x - 1; ++x, ++dst) {
auto sx = x * itransform->e11 + itransform->e13;
auto src = ALPHA_BLEND(_interpUpScaler(image->data, image->w, image->h, sx, sy), opacity);
*dst = src + ALPHA_BLEND(*dst, surface->blender.ialpha(src));
}
}
}
return true;
} }
static bool _rasterScaledRGBAImage(SwSurface* surface, const SwImage* image, const Matrix* itransform, const SwBBox& region, uint32_t halfScale) static bool _rasterScaledRGBAImage(SwSurface* surface, const SwImage* image, const Matrix* itransform, const SwBBox& region, uint32_t halfScale, TVG_UNUSED uint32_t opacity)
{ {
//Top, Bottom Lines //Top, Bottom Lines
SwCoord ys[2] = {region.min.y, region.max.y - 1}; SwCoord ys[2] = {region.min.y, region.max.y - 1};
@ -1279,7 +1181,11 @@ static bool _rasterScaledRGBAImage(SwSurface* surface, const SwImage* image, con
auto dst = surface->buffer + (y * surface->stride + region.min.x); auto dst = surface->buffer + (y * surface->stride + region.min.x);
auto img = image->data + static_cast<uint32_t>((y * itransform->e22 + itransform->e23)) * image->stride; auto img = image->data + static_cast<uint32_t>((y * itransform->e22 + itransform->e23)) * image->stride;
for (auto x = region.min.x; x < region.max.x; ++x, ++dst) { for (auto x = region.min.x; x < region.max.x; ++x, ++dst) {
#ifdef RASTER_TRANSLUCENT
auto src = ALPHA_BLEND(img[static_cast<uint32_t>(x * itransform->e11 + itransform->e13)], opacity);
#else
auto src = img[static_cast<uint32_t>(x * itransform->e11 + itransform->e13)]; auto src = img[static_cast<uint32_t>(x * itransform->e11 + itransform->e13)];
#endif
*dst = src + ALPHA_BLEND(*dst, surface->blender.ialpha(src)); *dst = src + ALPHA_BLEND(*dst, surface->blender.ialpha(src));
} }
} }
@ -1291,7 +1197,11 @@ static bool _rasterScaledRGBAImage(SwSurface* surface, const SwImage* image, con
auto dst = surface->buffer + ((region.min.y + 1) * surface->stride + x); auto dst = surface->buffer + ((region.min.y + 1) * surface->stride + x);
auto img = image->data + static_cast<uint32_t>(x * itransform->e11 + itransform->e13); auto img = image->data + static_cast<uint32_t>(x * itransform->e11 + itransform->e13);
for (auto y = region.min.y + 1; y < region.max.y - 1; ++y, dst += surface->stride) { for (auto y = region.min.y + 1; y < region.max.y - 1; ++y, dst += surface->stride) {
#ifdef RASTER_TRANSLUCENT
auto src = ALPHA_BLEND(img[static_cast<uint32_t>(y * itransform->e22 + itransform->e23) * image->stride], opacity);
#else
auto src = img[static_cast<uint32_t>(y * itransform->e22 + itransform->e23) * image->stride]; auto src = img[static_cast<uint32_t>(y * itransform->e22 + itransform->e23) * image->stride];
#endif
*dst = src + ALPHA_BLEND(*dst, surface->blender.ialpha(src)); *dst = src + ALPHA_BLEND(*dst, surface->blender.ialpha(src));
} }
} }
@ -1303,7 +1213,11 @@ static bool _rasterScaledRGBAImage(SwSurface* surface, const SwImage* image, con
auto dst = dbuffer; auto dst = dbuffer;
for (auto x = region.min.x + 1; x < region.max.x - 1; ++x, ++dst) { for (auto x = region.min.x + 1; x < region.max.x - 1; ++x, ++dst) {
auto sx = static_cast<uint32_t>(x * itransform->e11 + itransform->e13); auto sx = static_cast<uint32_t>(x * itransform->e11 + itransform->e13);
#ifdef RASTER_TRANSLUCENT
auto src = ALPHA_BLEND(_interpDownScaler(image->data, image->w, image->h, sx, sy, halfScale), opacity);
#else
auto src = _interpDownScaler(image->data, image->w, image->h, sx, sy, halfScale); auto src = _interpDownScaler(image->data, image->w, image->h, sx, sy, halfScale);
#endif
*dst = src + ALPHA_BLEND(*dst, surface->blender.ialpha(src)); *dst = src + ALPHA_BLEND(*dst, surface->blender.ialpha(src));
} }
} }
@ -1315,7 +1229,11 @@ static bool _rasterScaledRGBAImage(SwSurface* surface, const SwImage* image, con
auto dst = dbuffer; auto dst = dbuffer;
for (auto x = region.min.x; x < region.max.x - 1; ++x, ++dst) { for (auto x = region.min.x; x < region.max.x - 1; ++x, ++dst) {
auto sx = x * itransform->e11 + itransform->e13; auto sx = x * itransform->e11 + itransform->e13;
#ifdef RASTER_TRANSLUCENT
auto src = ALPHA_BLEND(_interpUpScaler(image->data, image->w, image->h, sx, sy), opacity);
#else
auto src = _interpUpScaler(image->data, image->w, image->h, sx, sy); auto src = _interpUpScaler(image->data, image->w, image->h, sx, sy);
#endif
*dst = src + ALPHA_BLEND(*dst, surface->blender.ialpha(src)); *dst = src + ALPHA_BLEND(*dst, surface->blender.ialpha(src));
} }
} }
@ -1324,6 +1242,14 @@ static bool _rasterScaledRGBAImage(SwSurface* surface, const SwImage* image, con
} }
static bool _rasterScaledTranslucentRGBAImage(SwSurface* surface, const SwImage* image, const Matrix* itransform, const SwBBox& region, uint32_t halfScale, uint32_t opacity)
{
#define RASTER_TRANSLUCENT
return _rasterScaledRGBAImage(surface, image, itransform, region, halfScale, opacity);
#undef RASTER_TRANSLUCENT
}
static bool _scaledRGBAImage(SwSurface* surface, const SwImage* image, const Matrix* transform, const SwBBox& region, uint32_t opacity) static bool _scaledRGBAImage(SwSurface* surface, const SwImage* image, const Matrix* transform, const SwBBox& region, uint32_t opacity)
{ {
Matrix itransform; Matrix itransform;
@ -1334,20 +1260,20 @@ static bool _scaledRGBAImage(SwSurface* surface, const SwImage* image, const Mat
if (_compositing(surface)) { if (_compositing(surface)) {
if (opacity == 255) { if (opacity == 255) {
if (surface->compositor->method == CompositeMethod::AlphaMask) { if (surface->compositor->method == CompositeMethod::AlphaMask) {
return _rasterScaledMaskedRGBAImage(surface, image, &itransform, region, halfScale, surface->blender.alpha); return _rasterScaledMaskedRGBAImage(surface, image, &itransform, region, halfScale, surface->blender.alpha, 255);
} else if (surface->compositor->method == CompositeMethod::InvAlphaMask) { } else if (surface->compositor->method == CompositeMethod::InvAlphaMask) {
return _rasterScaledMaskedRGBAImage(surface, image, &itransform, region, halfScale, surface->blender.ialpha); return _rasterScaledMaskedRGBAImage(surface, image, &itransform, region, halfScale, surface->blender.ialpha, 255);
} }
} else { } else {
if (surface->compositor->method == CompositeMethod::AlphaMask) { if (surface->compositor->method == CompositeMethod::AlphaMask) {
return _rasterScaledMaskedTranslucentRGBAImage(surface, image, &itransform, region, opacity, halfScale, surface->blender.alpha); return _rasterScaledMaskedTranslucentRGBAImage(surface, image, &itransform, region, halfScale, surface->blender.alpha, opacity);
} else if (surface->compositor->method == CompositeMethod::InvAlphaMask) { } else if (surface->compositor->method == CompositeMethod::InvAlphaMask) {
return _rasterScaledMaskedTranslucentRGBAImage(surface, image, &itransform, region, opacity, halfScale, surface->blender.ialpha); return _rasterScaledMaskedTranslucentRGBAImage(surface, image, &itransform, region, halfScale, surface->blender.ialpha, opacity);
} }
} }
} else { } else {
if (opacity == 255) return _rasterScaledRGBAImage(surface, image, &itransform, region, halfScale); if (opacity == 255) return _rasterScaledRGBAImage(surface, image, &itransform, region, halfScale, 255);
else return _rasterScaledTranslucentRGBAImage(surface, image, &itransform, region, opacity, halfScale); else return _rasterScaledTranslucentRGBAImage(surface, image, &itransform, region, halfScale, opacity);
} }
return false; return false;
} }
@ -1357,7 +1283,7 @@ static bool _scaledRGBAImage(SwSurface* surface, const SwImage* image, const Mat
/* Direct RGBA Image */ /* Direct RGBA Image */
/************************************************************************/ /************************************************************************/
static bool _rasterDirectMaskedRGBAImage(SwSurface* surface, const SwImage* image, const SwBBox& region, uint32_t (*blendMethod)(uint32_t)) static bool _rasterDirectMaskedRGBAImage(SwSurface* surface, const SwImage* image, const SwBBox& region, uint32_t (*blendMethod)(uint32_t), TVG_UNUSED uint32_t opacity)
{ {
TVGLOG("SW_ENGINE", "Direct Masked Image"); TVGLOG("SW_ENGINE", "Direct Masked Image");
@ -1373,34 +1299,11 @@ static bool _rasterDirectMaskedRGBAImage(SwSurface* surface, const SwImage* imag
auto cmp = cbuffer; auto cmp = cbuffer;
auto src = sbuffer; auto src = sbuffer;
for (uint32_t x = 0; x < w2; ++x, ++dst, ++src, ++cmp) { for (uint32_t x = 0; x < w2; ++x, ++dst, ++src, ++cmp) {
auto tmp = ALPHA_BLEND(*src, blendMethod(*cmp)); #ifdef RASTER_TRANSLUCENT
*dst = tmp + ALPHA_BLEND(*dst, surface->blender.ialpha(tmp));
}
buffer += surface->stride;
cbuffer += surface->compositor->image.stride;
sbuffer += image->stride;
}
return true;
}
static bool _rasterDirectMaskedTranslucentRGBAImage(SwSurface* surface, const SwImage* image, const SwBBox& region, uint32_t opacity, uint32_t (*blendMethod)(uint32_t))
{
TVGLOG("SW_ENGINE", "Direct Masked Translucent Image");
auto buffer = surface->buffer + (region.min.y * surface->stride) + region.min.x;
auto h2 = static_cast<uint32_t>(region.max.y - region.min.y);
auto w2 = static_cast<uint32_t>(region.max.x - region.min.x);
auto sbuffer = image->data + (region.min.y + image->oy) * image->stride + (region.min.x + image->ox);
auto cbuffer = surface->compositor->image.data + (region.min.y * surface->compositor->image.stride) + region.min.x; //compositor buffer
for (uint32_t y = 0; y < h2; ++y) {
auto dst = buffer;
auto cmp = cbuffer;
auto src = sbuffer;
for (uint32_t x = 0; x < w2; ++x, ++dst, ++src, ++cmp) {
auto tmp = ALPHA_BLEND(*src, _multiplyAlpha(opacity, blendMethod(*cmp))); auto tmp = ALPHA_BLEND(*src, _multiplyAlpha(opacity, blendMethod(*cmp)));
#else
auto tmp = ALPHA_BLEND(*src, blendMethod(*cmp));
#endif
*dst = tmp + ALPHA_BLEND(*dst, surface->blender.ialpha(tmp)); *dst = tmp + ALPHA_BLEND(*dst, surface->blender.ialpha(tmp));
} }
buffer += surface->stride; buffer += surface->stride;
@ -1411,26 +1314,15 @@ static bool _rasterDirectMaskedTranslucentRGBAImage(SwSurface* surface, const Sw
} }
static bool _rasterDirectTranslucentRGBAImage(SwSurface* surface, const SwImage* image, const SwBBox& region, uint32_t opacity) static bool _rasterDirectMaskedTranslucentRGBAImage(SwSurface* surface, const SwImage* image, const SwBBox& region, uint32_t (*blendMethod)(uint32_t), uint32_t opacity)
{ {
auto dbuffer = &surface->buffer[region.min.y * surface->stride + region.min.x]; #define RASTER_TRANSLUCENT
auto sbuffer = image->data + (region.min.y + image->oy) * image->stride + (region.min.x + image->ox); return _rasterDirectMaskedRGBAImage(surface, image, region, blendMethod, opacity);
#undef RASTER_TRANSLUCENT
for (auto y = region.min.y; y < region.max.y; ++y) {
auto dst = dbuffer;
auto src = sbuffer;
for (auto x = region.min.x; x < region.max.x; ++x, ++dst, ++src) {
auto tmp = ALPHA_BLEND(*src, opacity);
*dst = tmp + ALPHA_BLEND(*dst, surface->blender.ialpha(tmp));
}
dbuffer += surface->stride;
sbuffer += image->stride;
}
return true;
} }
static bool _rasterDirectRGBAImage(SwSurface* surface, const SwImage* image, const SwBBox& region) static bool _rasterDirectRGBAImage(SwSurface* surface, const SwImage* image, const SwBBox& region, TVG_UNUSED uint32_t opacity)
{ {
auto dbuffer = &surface->buffer[region.min.y * surface->stride + region.min.x]; auto dbuffer = &surface->buffer[region.min.y * surface->stride + region.min.x];
auto sbuffer = image->data + (region.min.y + image->oy) * image->stride + (region.min.x + image->ox); auto sbuffer = image->data + (region.min.y + image->oy) * image->stride + (region.min.x + image->ox);
@ -1439,7 +1331,12 @@ static bool _rasterDirectRGBAImage(SwSurface* surface, const SwImage* image, con
auto dst = dbuffer; auto dst = dbuffer;
auto src = sbuffer; auto src = sbuffer;
for (auto x = region.min.x; x < region.max.x; x++, dst++, src++) { for (auto x = region.min.x; x < region.max.x; x++, dst++, src++) {
#ifdef RASTER_TRANSLUCENT
auto tmp = ALPHA_BLEND(*src, opacity);
*dst = tmp + ALPHA_BLEND(*dst, surface->blender.ialpha(tmp));
#else
*dst = *src + ALPHA_BLEND(*dst, surface->blender.ialpha(*src)); *dst = *src + ALPHA_BLEND(*dst, surface->blender.ialpha(*src));
#endif
} }
dbuffer += surface->stride; dbuffer += surface->stride;
sbuffer += image->stride; sbuffer += image->stride;
@ -1448,25 +1345,32 @@ static bool _rasterDirectRGBAImage(SwSurface* surface, const SwImage* image, con
} }
//Blenders for the following scenarios: [Composition / Non-Composition] * [Opaque / Translucent] static bool _rasterDirectTranslucentRGBAImage(SwSurface* surface, const SwImage* image, const SwBBox& region, uint32_t opacity)
{
#define RASTER_TRANSLUCENT
return _rasterDirectRGBAImage(surface, image, region, opacity);
#undef RASTER_TRANSLUCENT
}
static bool _directRGBAImage(SwSurface* surface, const SwImage* image, const SwBBox& region, uint32_t opacity) static bool _directRGBAImage(SwSurface* surface, const SwImage* image, const SwBBox& region, uint32_t opacity)
{ {
if (_compositing(surface)) { if (_compositing(surface)) {
if (opacity == 255) { if (opacity == 255) {
if (surface->compositor->method == CompositeMethod::AlphaMask) { if (surface->compositor->method == CompositeMethod::AlphaMask) {
return _rasterDirectMaskedRGBAImage(surface, image, region, surface->blender.alpha); return _rasterDirectMaskedRGBAImage(surface, image, region, surface->blender.alpha, 255);
} else if (surface->compositor->method == CompositeMethod::InvAlphaMask) { } else if (surface->compositor->method == CompositeMethod::InvAlphaMask) {
return _rasterDirectMaskedRGBAImage(surface, image, region, surface->blender.ialpha); return _rasterDirectMaskedRGBAImage(surface, image, region, surface->blender.ialpha, 255);
} }
} else { } else {
if (surface->compositor->method == CompositeMethod::AlphaMask) { if (surface->compositor->method == CompositeMethod::AlphaMask) {
return _rasterDirectMaskedTranslucentRGBAImage(surface, image, region, opacity, surface->blender.alpha); return _rasterDirectMaskedTranslucentRGBAImage(surface, image, region, surface->blender.alpha, opacity);
} else if (surface->compositor->method == CompositeMethod::InvAlphaMask) { } else if (surface->compositor->method == CompositeMethod::InvAlphaMask) {
return _rasterDirectMaskedTranslucentRGBAImage(surface, image, region, opacity, surface->blender.ialpha); return _rasterDirectMaskedTranslucentRGBAImage(surface, image, region, surface->blender.ialpha, opacity);
} }
} }
} else { } else {
if (opacity == 255) return _rasterDirectRGBAImage(surface, image, region); if (opacity == 255) return _rasterDirectRGBAImage(surface, image, region, 255);
else return _rasterDirectTranslucentRGBAImage(surface, image, region, opacity); else return _rasterDirectTranslucentRGBAImage(surface, image, region, opacity);
} }
return false; return false;