/* RLE Transformed RGBA Image */
/************************************************************************/
-static bool _rasterTransformedMaskedRleRGBAImage(SwSurface* surface, const SwImage* image, const Matrix* itransform, uint32_t opacity, uint32_t (*blendMethod)(uint32_t))
+static bool _rasterTransformedMaskedTranslucentRleRGBAImage(SwSurface* surface, const SwImage* image, const Matrix* itransform, uint32_t opacity, uint32_t (*blendMethod)(uint32_t))
{
- TVGLOG("SW_ENGINE", "Transformed Masked Rle Image");
+ TVGLOG("SW_ENGINE", "Transformed Masked Translucent Rle Image");
auto span = image->rle->spans;
auto img = image->data;
auto dst = &surface->buffer[span->y * surface->stride + span->x];
auto cmp = &cbuffer[span->y * surface->compositor->image.stride + span->x];
auto alpha = _multiplyAlpha(span->coverage, opacity);
- if (alpha == 255) {
+ for (uint32_t x = 0; x < span->len; ++x, ++dst, ++cmp) {
+ auto rX = static_cast<uint32_t>(roundf((span->x + x) * itransform->e11 + ey1));
+ auto rY = static_cast<uint32_t>(roundf((span->x + x) * itransform->e21 + ey2));
+ if (rX >= w || rY >= h) continue;
+ auto src = ALPHA_BLEND(img[rY * image->stride + rX], alpha);
+ auto tmp = ALPHA_BLEND(src, blendMethod(*cmp));
+ *dst = tmp + ALPHA_BLEND(*dst, surface->blender.ialpha(tmp));
+ }
+ }
+ return true;
+}
+
+
+static bool _rasterTransformedMaskedRleRGBAImage(SwSurface* surface, const SwImage* image, const Matrix* itransform, uint32_t (*blendMethod)(uint32_t))
+{
+ TVGLOG("SW_ENGINE", "Transformed Masked Rle Image");
+
+ auto span = image->rle->spans;
+ auto img = image->data;
+ auto w = image->w;
+ auto h = image->h;
+ auto cbuffer = surface->compositor->image.data;
+
+ for (uint32_t i = 0; i < image->rle->size; ++i, ++span) {
+ auto ey1 = span->y * itransform->e12 + itransform->e13;
+ auto ey2 = span->y * itransform->e22 + itransform->e23;
+ auto dst = &surface->buffer[span->y * surface->stride + span->x];
+ auto cmp = &cbuffer[span->y * surface->compositor->image.stride + span->x];
+ if (span->coverage == 255) {
for (uint32_t x = 0; x < span->len; ++x, ++dst, ++cmp) {
auto rX = static_cast<uint32_t>(roundf((span->x + x) * itransform->e11 + ey1));
auto rY = static_cast<uint32_t>(roundf((span->x + x) * itransform->e21 + ey2));
auto rX = static_cast<uint32_t>(roundf((span->x + x) * itransform->e11 + ey1));
auto rY = static_cast<uint32_t>(roundf((span->x + x) * itransform->e21 + ey2));
if (rX >= w || rY >= h) continue;
- auto src = ALPHA_BLEND(img[rY * image->stride + rX], alpha);
+ auto src = ALPHA_BLEND(img[rY * image->stride + rX], span->coverage);
auto tmp = ALPHA_BLEND(src, blendMethod(*cmp));
*dst = tmp + ALPHA_BLEND(*dst, surface->blender.ialpha(tmp));
}
}
-static bool _rasterDownScaledMaskedRleRGBAImage(SwSurface* surface, const SwImage* image, const Matrix* itransform, uint32_t opacity, uint32_t halfScale, uint32_t (*blendMethod)(uint32_t))
+static bool _rasterDownScaledMaskedTranslucentRleRGBAImage(SwSurface* surface, const SwImage* image, const Matrix* itransform, uint32_t opacity, uint32_t halfScale, uint32_t (*blendMethod)(uint32_t))
{
- TVGLOG("SW_ENGINE", "Down Scaled Masked Rle Image");
+ TVGLOG("SW_ENGINE", "Down Scaled Masked Translucent Rle Image");
auto span = image->rle->spans;
auto img = image->data;
auto dst = &surface->buffer[span->y * surface->stride + span->x];
auto cmp = &cbuffer[span->y * surface->compositor->image.stride + span->x];
auto alpha = _multiplyAlpha(span->coverage, opacity);
+ for (uint32_t x = 0; x < span->len; ++x, ++dst, ++cmp) {
+ auto rX = static_cast<uint32_t>(roundf((span->x + x) * itransform->e11 + ey1));
+ auto rY = static_cast<uint32_t>(roundf((span->x + x) * itransform->e21 + ey2));
+ if (rX >= w || rY >= h) continue;
+ uint32_t src;
+ if (rX < halfScale || rY < halfScale || rX >= w - halfScale || rY >= h - halfScale) src = ALPHA_BLEND(img[rY * image->stride + rX], alpha);
+ else src = ALPHA_BLEND(_interpDownScaler(img, image->stride, h, rX, rY, halfScale), alpha);
+ auto tmp = ALPHA_BLEND(src, _multiplyAlpha(alpha, blendMethod(*cmp)));
+ *dst = tmp + ALPHA_BLEND(*dst, surface->blender.ialpha(tmp));
+ }
+ }
+ return true;
+}
- if (alpha == 255) {
+
+static bool _rasterDownScaledMaskedRleRGBAImage(SwSurface* surface, const SwImage* image, const Matrix* itransform, uint32_t halfScale, uint32_t (*blendMethod)(uint32_t))
+{
+ TVGLOG("SW_ENGINE", "Down Scaled Masked Rle Image");
+
+ auto span = image->rle->spans;
+ auto img = image->data;
+ auto w = image->w;
+ auto h = image->h;
+ auto cbuffer = surface->compositor->image.data;
+
+ for (uint32_t i = 0; i < image->rle->size; ++i, ++span) {
+ auto ey1 = span->y * itransform->e12 + itransform->e13;
+ auto ey2 = span->y * itransform->e22 + itransform->e23;
+ auto dst = &surface->buffer[span->y * surface->stride + span->x];
+ auto cmp = &cbuffer[span->y * surface->compositor->image.stride + span->x];
+ if (span->coverage == 255) {
for (uint32_t x = 0; x < span->len; ++x, ++dst, ++cmp) {
auto rX = static_cast<uint32_t>(roundf((span->x + x) * itransform->e11 + ey1));
auto rY = static_cast<uint32_t>(roundf((span->x + x) * itransform->e21 + ey2));
auto rY = static_cast<uint32_t>(roundf((span->x + x) * itransform->e21 + ey2));
if (rX >= w || rY >= h) continue;
uint32_t src;
- if (rX < halfScale || rY < halfScale || rX >= w - halfScale || rY >= h - halfScale) src = ALPHA_BLEND(img[rY * image->stride + rX], alpha);
- else src = ALPHA_BLEND(_interpDownScaler(img, image->stride, h, rX, rY, halfScale), alpha);
- auto tmp = ALPHA_BLEND(src, _multiplyAlpha(alpha, blendMethod(*cmp)));
+ if (rX < halfScale || rY < halfScale || rX >= w - halfScale || rY >= h - halfScale) src = ALPHA_BLEND(img[rY * image->stride + rX], span->coverage);
+ else src = ALPHA_BLEND(_interpDownScaler(img, image->stride, h, rX, rY, halfScale), span->coverage);
+ auto tmp = ALPHA_BLEND(src, _multiplyAlpha(span->coverage, blendMethod(*cmp)));
*dst = tmp + ALPHA_BLEND(*dst, surface->blender.ialpha(tmp));
}
}
}
-static bool _rasterUpScaledMaskedRleRGBAImage(SwSurface* surface, const SwImage* image, const Matrix* itransform, uint32_t opacity, uint32_t (*blendMethod)(uint32_t))
+static bool _rasterUpScaledMaskedTranslucentRleRGBAImage(SwSurface* surface, const SwImage* image, const Matrix* itransform, uint32_t opacity, uint32_t (*blendMethod)(uint32_t))
{
- TVGLOG("SW_ENGINE", "Up Scaled Masked Rle Image");
+ TVGLOG("SW_ENGINE", "Up Scaled Masked Translucent Rle Image");
auto span = image->rle->spans;
auto img = image->data;
auto dst = &surface->buffer[span->y * surface->stride + span->x];
auto cmp = &cbuffer[span->y * surface->compositor->image.stride + span->x];
auto alpha = _multiplyAlpha(span->coverage, opacity);
- if (alpha == 255) {
+ for (uint32_t x = 0; x < span->len; ++x, ++dst, ++cmp) {
+ auto fX = (span->x + x) * itransform->e11 + ey1;
+ auto fY = (span->x + x) * itransform->e21 + ey2;
+ auto rX = static_cast<uint32_t>(roundf(fX));
+ auto rY = static_cast<uint32_t>(roundf(fY));
+ if (rX >= w || rY >= h) continue;
+ uint32_t src;
+ if (rX == w - 1 || rY == h - 1) src = ALPHA_BLEND(img[rY * image->stride + rX], alpha);
+ else src = ALPHA_BLEND(_interpUpScaler(img, image->stride, h, fX, fY), alpha);
+ auto tmp = ALPHA_BLEND(src, _multiplyAlpha(alpha, blendMethod(*cmp)));
+ *dst = tmp + ALPHA_BLEND(*dst, surface->blender.ialpha(tmp));
+ }
+ }
+ return true;
+}
+
+
+static bool _rasterUpScaledMaskedRleRGBAImage(SwSurface* surface, const SwImage* image, const Matrix* itransform, uint32_t (*blendMethod)(uint32_t))
+{
+ TVGLOG("SW_ENGINE", "Up Scaled Masked Rle Image");
+
+ auto span = image->rle->spans;
+ auto img = image->data;
+ auto w = image->w;
+ auto h = image->h;
+ auto cbuffer = surface->compositor->image.data;
+
+ for (uint32_t i = 0; i < image->rle->size; ++i, ++span) {
+ auto ey1 = span->y * itransform->e12 + itransform->e13;
+ auto ey2 = span->y * itransform->e22 + itransform->e23;
+ auto dst = &surface->buffer[span->y * surface->stride + span->x];
+ auto cmp = &cbuffer[span->y * surface->compositor->image.stride + span->x];
+ if (span->coverage == 255) {
for (uint32_t x = 0; x < span->len; ++x, ++dst, ++cmp) {
auto fX = (span->x + x) * itransform->e11 + ey1;
auto fY = (span->x + x) * itransform->e21 + ey2;
auto rY = static_cast<uint32_t>(roundf(fY));
if (rX >= w || rY >= h) continue;
uint32_t src;
- if (rX == w - 1 || rY == h - 1) src = ALPHA_BLEND(img[rY * image->stride + rX], alpha);
- else src = ALPHA_BLEND(_interpUpScaler(img, image->stride, h, fX, fY), alpha);
- auto tmp = ALPHA_BLEND(src, _multiplyAlpha(alpha, blendMethod(*cmp)));
+ if (rX == w - 1 || rY == h - 1) src = ALPHA_BLEND(img[rY * image->stride + rX], span->coverage);
+ else src = ALPHA_BLEND(_interpUpScaler(img, image->stride, h, fX, fY), span->coverage);
+ auto tmp = ALPHA_BLEND(src, _multiplyAlpha(span->coverage, blendMethod(*cmp)));
*dst = tmp + ALPHA_BLEND(*dst, surface->blender.ialpha(tmp));
}
}
static bool _transformedRleRGBAImage(SwSurface* surface, const SwImage* image, const Matrix* transform, uint32_t opacity)
{
- auto halfScale = _halfScale(image->scale);
-
Matrix itransform;
if (transform && !mathInverse(transform, &itransform)) return false;
- if (_translucent(surface, opacity)) {
- //TODO: Blenders for the following scenarios: [Opacity / Composition / Opacity + Composition]
- //Transformed
- if (mathEqual(image->scale, 1.0f)) {
- if (surface->compositor) {
+ auto halfScale = _halfScale(image->scale);
+
+ if (_compositing(surface)) {
+ if (opacity == 255) {
+ //Transformed
+ if (mathEqual(image->scale, 1.0f)) {
if (surface->compositor->method == CompositeMethod::AlphaMask) {
- return _rasterTransformedMaskedRleRGBAImage(surface, image, &itransform, opacity, surface->blender.alpha);
+ return _rasterTransformedMaskedRleRGBAImage(surface, image, &itransform, surface->blender.alpha);
} else if (surface->compositor->method == CompositeMethod::InvAlphaMask) {
- return _rasterTransformedMaskedRleRGBAImage(surface, image, &itransform, opacity, surface->blender.ialpha);
- }
- }
- return _rasterTransformedTranslucentRleRGBAImage(surface, image, &itransform, opacity);
- //Transformed + Down Scaled
- } else if (image->scale < DOWN_SCALE_TOLERANCE) {
- if (surface->compositor) {
+ return _rasterTransformedMaskedRleRGBAImage(surface, image, &itransform, surface->blender.ialpha);
+ }
+ //Transformed + Down Scaled
+ } else if (image->scale < DOWN_SCALE_TOLERANCE) {
if (surface->compositor->method == CompositeMethod::AlphaMask) {
- return _rasterDownScaledMaskedRleRGBAImage(surface, image, &itransform, opacity, halfScale, surface->blender.alpha);
+ return _rasterDownScaledMaskedRleRGBAImage(surface, image, &itransform, halfScale, surface->blender.alpha);
} else if (surface->compositor->method == CompositeMethod::InvAlphaMask) {
- return _rasterDownScaledMaskedRleRGBAImage(surface, image, &itransform, opacity, halfScale, surface->blender.ialpha);
+ return _rasterDownScaledMaskedRleRGBAImage(surface, image, &itransform, halfScale, surface->blender.ialpha);
}
+
+ //Transformed + Up Scaled
+ } else {
+ if (surface->compositor->method == CompositeMethod::AlphaMask) {
+ return _rasterUpScaledMaskedRleRGBAImage(surface, image, &itransform, surface->blender.alpha);
+ } else if (surface->compositor->method == CompositeMethod::InvAlphaMask) {
+ return _rasterUpScaledMaskedRleRGBAImage(surface, image, &itransform, surface->blender.ialpha);
+ }
}
- return _rasterDownScaledTranslucentRleRGBAImage(surface, image, &itransform, opacity, halfScale);
- //Transformed + Up Scaled
} else {
- if (surface->compositor) {
+ //Transformed
+ if (mathEqual(image->scale, 1.0f)) {
if (surface->compositor->method == CompositeMethod::AlphaMask) {
- return _rasterUpScaledMaskedRleRGBAImage(surface, image, &itransform, opacity, surface->blender.alpha);
+ return _rasterTransformedMaskedTranslucentRleRGBAImage(surface, image, &itransform, opacity, surface->blender.alpha);
} else if (surface->compositor->method == CompositeMethod::InvAlphaMask) {
- return _rasterUpScaledMaskedRleRGBAImage(surface, image, &itransform, opacity, surface->blender.ialpha);
+ return _rasterTransformedMaskedTranslucentRleRGBAImage(surface, image, &itransform, opacity, surface->blender.ialpha);
+ }
+ //Transformed + Down Scaled
+ } else if (image->scale < DOWN_SCALE_TOLERANCE) {
+ if (surface->compositor->method == CompositeMethod::AlphaMask) {
+ return _rasterDownScaledMaskedTranslucentRleRGBAImage(surface, image, &itransform, opacity, halfScale, surface->blender.alpha);
+ } else if (surface->compositor->method == CompositeMethod::InvAlphaMask) {
+ return _rasterDownScaledMaskedTranslucentRleRGBAImage(surface, image, &itransform, opacity, halfScale, surface->blender.ialpha);
}
+
+ //Transformed + Up Scaled
+ } else {
+ if (surface->compositor->method == CompositeMethod::AlphaMask) {
+ return _rasterUpScaledMaskedTranslucentRleRGBAImage(surface, image, &itransform, opacity, surface->blender.alpha);
+ } else if (surface->compositor->method == CompositeMethod::InvAlphaMask) {
+ return _rasterUpScaledMaskedTranslucentRleRGBAImage(surface, image, &itransform, opacity, surface->blender.ialpha);
+ }
}
- return _rasterUpScaledTranslucentRleRGBAImage(surface, image, &itransform, opacity);
}
} else {
- //TODO: Blenders for the following scenarios: [No Composition / Composition]
- if (mathEqual(image->scale, 1.0f)) return _rasterTransformedRleRGBAImage(surface, image, &itransform);
- else if (image->scale < DOWN_SCALE_TOLERANCE) return _rasterDownScaledRleRGBAImage(surface, image, &itransform, halfScale);
- else return _rasterUpScaledRleRGBAImage(surface, image, &itransform);
+ if (opacity == 255) {
+ if (mathEqual(image->scale, 1.0f)) return _rasterTransformedRleRGBAImage(surface, image, &itransform);
+ else if (image->scale < DOWN_SCALE_TOLERANCE) return _rasterDownScaledRleRGBAImage(surface, image, &itransform, halfScale);
+ else return _rasterUpScaledRleRGBAImage(surface, image, &itransform);
+ } else {
+ if (mathEqual(image->scale, 1.0f)) return _rasterTransformedTranslucentRleRGBAImage(surface, image, &itransform, opacity);
+ else if (image->scale < DOWN_SCALE_TOLERANCE) return _rasterDownScaledTranslucentRleRGBAImage(surface, image, &itransform, opacity, halfScale);
+ else return _rasterUpScaledTranslucentRleRGBAImage(surface, image, &itransform, opacity);
+ }
}
+ return false;
}
/************************************************************************/
static bool _rasterScaledMaskedTranslucentRleRGBAImage(SwSurface* surface, const SwImage* image, const Matrix* itransform, const SwBBox& region, uint32_t opacity, uint32_t halfScale, uint32_t (*blendMethod)(uint32_t))
{
+ TVGLOG("SW_ENGINE", "Scaled Masked Translucent Rle Image");
+
auto span = image->rle->spans;
//Center (Down-Scaled)
static bool _rasterScaledMaskedRleRGBAImage(SwSurface* surface, const SwImage* image, const Matrix* itransform, const SwBBox& region, uint32_t halfScale, uint32_t (*blendMethod)(uint32_t))
{
+ TVGLOG("SW_ENGINE", "Scaled Masked Rle Image");
+
auto span = image->rle->spans;
//Center (Down-Scaled)