TVGLOG("SW_ENGINE", "Translucent Masked Rect");
- auto cbuffer = surface->compositor->image.data + (region.min.y * surface->stride) + region.min.x; //compositor buffer
+ auto cbuffer = surface->compositor->image.data + (region.min.y * surface->compositor->image.stride) + region.min.x; //compositor buffer
for (uint32_t y = 0; y < h; ++y) {
auto dst = &buffer[y * surface->stride];
for (uint32_t i = 0; i < rle->size; ++i) {
auto dst = &surface->buffer[span->y * surface->stride + span->x];
- auto cmp = &cbuffer[span->y * surface->stride + span->x];
+ auto cmp = &cbuffer[span->y * surface->compositor->image.stride + span->x];
if (span->coverage < 255) src = ALPHA_BLEND(color, span->coverage);
else src = color;
for (uint32_t x = 0; x < span->len; ++x) {
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->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 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->stride + span->x];
+ auto cmp = &cbuffer[span->y * surface->compositor->image.stride + span->x];
auto alpha = _multiplyAlpha(span->coverage, opacity);
if (alpha == 255) {
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->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 sy = static_cast<uint32_t>(span->y * itransform->e22 + itransform->e23);
if (sy >= image->h) continue;
auto dst = &surface->buffer[span->y * surface->stride + span->x];
- auto cmp = &surface->compositor->image.data[span->y * surface->stride + span->x];
+ auto cmp = &surface->compositor->image.data[span->y * surface->compositor->image.stride + span->x];
auto alpha = _multiplyAlpha(span->coverage, opacity);
if (alpha == 255) {
for (uint32_t x = span->x; x < ((uint32_t)span->x) + span->len; ++x, ++dst, ++cmp) {
auto sy = static_cast<uint32_t>(span->y * itransform->e22 + itransform->e23);
if (sy >= image->h) continue;
auto dst = &surface->buffer[span->y * surface->stride + span->x];
- auto cmp = &surface->compositor->image.data[span->y * surface->stride + span->x];
+ auto cmp = &surface->compositor->image.data[span->y * surface->compositor->image.stride + span->x];
auto alpha = _multiplyAlpha(span->coverage, opacity);
if (alpha == 255) {
for (uint32_t x = span->x; x < ((uint32_t)span->x) + span->len; ++x, ++dst, ++cmp) {
/* RLE Direct RGBA Image */
/************************************************************************/
-static bool _rasterDirectMaskedRleRGBAImage(SwSurface* surface, const SwImage* image, uint32_t opacity, uint32_t (*blendMethod)(uint32_t))
+static bool _rasterDirectMaskedTranslucentRleRGBAImage(SwSurface* surface, const SwImage* image, uint32_t opacity, uint32_t (*blendMethod)(uint32_t))
{
TVGLOG("SW_ENGINE", "Direct Masked Rle Image");
for (uint32_t i = 0; i < image->rle->size; ++i, ++span) {
auto dst = &surface->buffer[span->y * surface->stride + span->x];
- auto cmp = &cbuffer[span->y * surface->stride + span->x];
+ auto cmp = &cbuffer[span->y * surface->compositor->image.stride + span->x];
auto img = image->data + (span->y + image->oy) * image->stride + (span->x + image->ox);
auto alpha = _multiplyAlpha(span->coverage, opacity);
if (alpha == 255) {
}
+static bool _rasterDirectMaskedRleRGBAImage(SwSurface* surface, const SwImage* image, uint32_t (*blendMethod)(uint32_t))
+{
+ TVGLOG("SW_ENGINE", "Direct Masked Rle Image");
+
+ auto span = image->rle->spans;
+ auto cbuffer = surface->compositor->image.data;
+
+ for (uint32_t i = 0; i < image->rle->size; ++i, ++span) {
+ auto dst = &surface->buffer[span->y * surface->stride + span->x];
+ auto cmp = &cbuffer[span->y * surface->compositor->image.stride + span->x];
+ auto img = image->data + (span->y + image->oy) * image->stride + (span->x + image->ox);
+ if (span->coverage == 255) {
+ for (uint32_t x = 0; x < span->len; ++x, ++dst, ++cmp, ++img) {
+ auto tmp = ALPHA_BLEND(*img, blendMethod(*cmp));
+ *dst = tmp + ALPHA_BLEND(*dst, surface->blender.ialpha(tmp));
+ }
+ } else {
+ for (uint32_t x = 0; x < span->len; ++x, ++dst, ++cmp, ++img) {
+ auto tmp = ALPHA_BLEND(*img, _multiplyAlpha(span->coverage, blendMethod(*cmp)));
+ *dst = tmp + ALPHA_BLEND(*dst, surface->blender.ialpha(tmp));
+ }
+ }
+ }
+ return true;
+}
+
+
static bool _rasterDirectTranslucentRleRGBAImage(SwSurface* surface, const SwImage* image, uint32_t opacity)
{
auto span = image->rle->spans;
static bool _directRleRGBAImage(SwSurface* surface, const SwImage* image, uint32_t opacity)
{
- if (_translucent(surface, opacity)) {
- //TODO: Blenders for the following scenarios: [Opacity / Composition / Opacity + Composition]
- if (surface->compositor) {
+ if (_compositing(surface)) {
+ if (opacity == 255) {
+ if (surface->compositor->method == CompositeMethod::AlphaMask) {
+ return _rasterDirectMaskedRleRGBAImage(surface, image, surface->blender.alpha);
+ } else if (surface->compositor->method == CompositeMethod::InvAlphaMask) {
+ return _rasterDirectMaskedRleRGBAImage(surface, image, surface->blender.ialpha);
+ }
+ } else {
if (surface->compositor->method == CompositeMethod::AlphaMask) {
- return _rasterDirectMaskedRleRGBAImage(surface, image, opacity, surface->blender.alpha);
+ return _rasterDirectMaskedTranslucentRleRGBAImage(surface, image, opacity, surface->blender.alpha);
} else if (surface->compositor->method == CompositeMethod::InvAlphaMask) {
- return _rasterDirectMaskedRleRGBAImage(surface, image, opacity, surface->blender.ialpha);
+ return _rasterDirectMaskedTranslucentRleRGBAImage(surface, image, opacity, surface->blender.ialpha);
}
}
- return _rasterDirectTranslucentRleRGBAImage(surface, image, opacity);
} else {
- //TODO: Blenders for the following scenarios: [No Composition / Composition]
- return _rasterDirectRleRGBAImage(surface, image);
+ if (opacity == 255) return _rasterDirectRleRGBAImage(surface, image);
+ else return _rasterDirectTranslucentRleRGBAImage(surface, image, opacity);
}
+ return false;
}
auto w = image->w;
auto h = image->h;
auto dbuffer = &surface->buffer[region.min.y * surface->stride + region.min.x];
- auto cbuffer = &surface->compositor->image.data[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; ++y) {
auto dst = dbuffer;
auto w = image->w;
auto h = image->h;
auto dbuffer = &surface->buffer[region.min.y * surface->stride + region.min.x];
- auto cbuffer = &surface->compositor->image.data[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; ++y) {
auto dst = dbuffer;
auto w = image->w;
auto h = image->h;
auto dbuffer = &surface->buffer[region.min.y * surface->stride + region.min.x];
- auto cbuffer = &surface->compositor->image.data[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; ++y) {
auto dst = dbuffer;
auto w = image->w;
auto h = image->h;
auto dbuffer = &surface->buffer[region.min.y * surface->stride + region.min.x];
- auto cbuffer = &surface->compositor->image.data[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; ++y) {
auto dst = dbuffer;
auto w = image->w;
auto h = image->h;
auto dbuffer = &surface->buffer[region.min.y * surface->stride + region.min.x];
- auto cbuffer = &surface->compositor->image.data[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; ++y) {
auto dst = dbuffer;
auto w = image->w;
auto h = image->h;
auto dbuffer = &surface->buffer[region.min.y * surface->stride + region.min.x];
- auto cbuffer = &surface->compositor->image.data[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; ++y) {
auto dst = dbuffer;
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->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 alpha = _multiplyAlpha(opacity, blendMethod(*cmp));
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->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 alpha = _multiplyAlpha(opacity, blendMethod(*cmp));
//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->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;
//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->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;
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->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));
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->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));
//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->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;
//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->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 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->stride) + region.min.x; //compositor buffer
+ 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 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->stride) + region.min.x; //compositor buffer
+ 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 buffer = surface->buffer + (region.min.y * surface->stride) + region.min.x;
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 cbuffer = surface->compositor->image.data + (region.min.y * surface->stride) + region.min.x;
+ auto cbuffer = surface->compositor->image.data + (region.min.y * surface->compositor->image.stride) + region.min.x;
auto sbuffer = static_cast<uint32_t*>(alloca(w * sizeof(uint32_t)));
if (!sbuffer) return false;
for (uint32_t i = 0; i < rle->size; ++i, ++span) {
fillFetchLinear(fill, buffer, span->y, span->x, span->len);
auto dst = &surface->buffer[span->y * surface->stride + span->x];
- auto cmp = &cbuffer[span->y * surface->stride + span->x];
+ auto cmp = &cbuffer[span->y * surface->compositor->image.stride + span->x];
auto src = buffer;
if (span->coverage == 255) {
for (uint32_t x = 0; x < span->len; ++x, ++dst, ++cmp, ++src) {
auto buffer = surface->buffer + (region.min.y * surface->stride) + region.min.x;
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 cbuffer = surface->compositor->image.data + (region.min.y * surface->stride) + region.min.x;
+ auto cbuffer = surface->compositor->image.data + (region.min.y * surface->compositor->image.stride) + region.min.x;
auto sbuffer = static_cast<uint32_t*>(alloca(w * sizeof(uint32_t)));
if (!sbuffer) return false;
for (uint32_t i = 0; i < rle->size; ++i, ++span) {
fillFetchRadial(fill, buffer, span->y, span->x, span->len);
auto dst = &surface->buffer[span->y * surface->stride + span->x];
- auto cmp = &cbuffer[span->y * surface->stride + span->x];
+ auto cmp = &cbuffer[span->y * surface->compositor->image.stride + span->x];
auto src = buffer;
if (span->coverage == 255) {
for (uint32_t x = 0; x < span->len; ++x, ++dst, ++cmp, ++src) {