sw_engine: unify RenderRegion and SwBBox

refactored for smoother data flow through the rendering pipeline.
This commit is contained in:
Hermet Park 2025-05-26 23:17:33 +09:00 committed by Hermet Park
parent 8a35f02105
commit cc72eda465
12 changed files with 153 additions and 245 deletions

View file

@ -126,16 +126,6 @@ struct SwRle
uint32_t size;
};
struct SwBBox
{
SwPoint min, max;
void reset()
{
min.x = min.y = max.x = max.y = 0;
}
};
struct SwFill
{
struct SwLinear {
@ -210,14 +200,14 @@ struct SwDashStroke
struct SwShape
{
SwOutline* outline = nullptr;
SwStroke* stroke = nullptr;
SwFill* fill = nullptr;
SwRle* rle = nullptr;
SwRle* strokeRle = nullptr;
SwBBox bbox; //Keep it boundary without stroke region. Using for optimal filling.
SwOutline* outline = nullptr;
SwStroke* stroke = nullptr;
SwFill* fill = nullptr;
SwRle* rle = nullptr;
SwRle* strokeRle = nullptr;
RenderRegion bbox; //Keep it boundary without stroke region. Using for optimal filling.
bool fastTrack = false; //Fast Track: axis-aligned rectangle without any clips?
bool fastTrack = false; //Fast Track: axis-aligned rectangle without any clips?
};
struct SwImage
@ -279,7 +269,7 @@ struct SwCompositor : RenderCompositor
SwSurface* recoverSfc; //Recover surface when composition is started
SwCompositor* recoverCmp; //Recover compositor when composition is done
SwImage image;
SwBBox bbox;
RenderRegion bbox;
bool valid;
};
@ -499,16 +489,15 @@ SwFixed mathLength(const SwPoint& pt);
int mathCubicAngle(const SwPoint* base, SwFixed& angleIn, SwFixed& angleMid, SwFixed& angleOut);
SwFixed mathMean(SwFixed angle1, SwFixed angle2);
SwPoint mathTransform(const Point* to, const Matrix& transform);
bool mathUpdateOutlineBBox(const SwOutline* outline, const SwBBox& clipRegion, SwBBox& renderRegion, bool fastTrack);
bool mathClipBBox(const SwBBox& clipper, SwBBox& clippee);
bool mathUpdateOutlineBBox(const SwOutline* outline, const RenderRegion& clipRegion, RenderRegion& renderRegion, bool fastTrack);
void shapeReset(SwShape* shape);
bool shapePrepare(SwShape* shape, const RenderShape* rshape, const Matrix& transform, const SwBBox& clipRegion, SwBBox& renderRegion, SwMpool* mpool, unsigned tid, bool hasComposite);
bool shapePrepare(SwShape* shape, const RenderShape* rshape, const Matrix& transform, const RenderRegion& clipRegion, RenderRegion& renderRegion, SwMpool* mpool, unsigned tid, bool hasComposite);
bool shapePrepared(const SwShape* shape);
bool shapeGenRle(SwShape* shape, const RenderShape* rshape, bool antiAlias);
void shapeDelOutline(SwShape* shape, SwMpool* mpool, uint32_t tid);
void shapeResetStroke(SwShape* shape, const RenderShape* rshape, const Matrix& transform);
bool shapeGenStrokeRle(SwShape* shape, const RenderShape* rshape, const Matrix& transform, const SwBBox& clipRegion, SwBBox& renderRegion, SwMpool* mpool, unsigned tid);
bool shapeGenStrokeRle(SwShape* shape, const RenderShape* rshape, const Matrix& transform, const RenderRegion& clipRegion, RenderRegion& renderRegion, SwMpool* mpool, unsigned tid);
void shapeFree(SwShape* shape);
void shapeDelStroke(SwShape* shape);
bool shapeGenFillColors(SwShape* shape, const Fill* fill, const Matrix& transform, SwSurface* surface, uint8_t opacity, bool ctable);
@ -523,8 +512,8 @@ bool strokeParseOutline(SwStroke* stroke, const SwOutline& outline);
SwOutline* strokeExportOutline(SwStroke* stroke, SwMpool* mpool, unsigned tid);
void strokeFree(SwStroke* stroke);
bool imagePrepare(SwImage* image, const Matrix& transform, const SwBBox& clipRegion, SwBBox& renderRegion, SwMpool* mpool, unsigned tid);
bool imageGenRle(SwImage* image, const SwBBox& renderRegion, bool antiAlias);
bool imagePrepare(SwImage* image, const Matrix& transform, const RenderRegion& clipRegion, RenderRegion& renderRegion, SwMpool* mpool, unsigned tid);
bool imageGenRle(SwImage* image, const RenderRegion& renderRegion, bool antiAlias);
void imageDelOutline(SwImage* image, SwMpool* mpool, uint32_t tid);
void imageReset(SwImage* image);
void imageFree(SwImage* image);
@ -547,13 +536,13 @@ void fillRadial(const SwFill* fill, uint32_t* dst, uint32_t y, uint32_t x, uint3
void fillRadial(const SwFill* fill, uint32_t* dst, uint32_t y, uint32_t x, uint32_t len, SwBlender op, SwBlender op2, uint8_t a); //blending + BlendingMethod(op2) ver.
void fillRadial(const SwFill* fill, uint32_t* dst, uint32_t y, uint32_t x, uint32_t len, uint8_t* cmp, SwAlpha alpha, uint8_t csize, uint8_t opacity); //matting ver.
SwRle* rleRender(SwRle* rle, const SwOutline* outline, const SwBBox& renderRegion, bool antiAlias);
SwRle* rleRender(const SwBBox* bbox);
SwRle* rleRender(SwRle* rle, const SwOutline* outline, const RenderRegion& renderRegion, bool antiAlias);
SwRle* rleRender(const RenderRegion* bbox);
void rleFree(SwRle* rle);
void rleReset(SwRle* rle);
void rleMerge(SwRle* rle, SwRle* clip1, SwRle* clip2);
bool rleClip(SwRle* rle, const SwRle* clip);
bool rleClip(SwRle* rle, const SwBBox* clip);
bool rleClip(SwRle* rle, const RenderRegion* clip);
SwMpool* mpoolInit(uint32_t threads);
bool mpoolTerm(SwMpool* mpool);
@ -568,7 +557,7 @@ 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, RenderColor& c);
bool rasterImage(SwSurface* surface, SwImage* image, const Matrix& transform, const SwBBox& bbox, uint8_t opacity);
bool rasterImage(SwSurface* surface, SwImage* image, const Matrix& transform, const RenderRegion& bbox, uint8_t opacity);
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);
@ -576,7 +565,7 @@ void rasterPixel32(uint32_t *dst, uint32_t val, uint32_t offset, int32_t len);
void rasterTranslucentPixel32(uint32_t* dst, uint32_t* src, uint32_t len, uint8_t opacity);
void rasterPixel32(uint32_t* dst, uint32_t* src, uint32_t len, uint8_t opacity);
void rasterGrayscale8(uint8_t *dst, uint8_t val, uint32_t offset, int32_t len);
void rasterXYFlip(uint32_t* src, uint32_t* dst, int32_t stride, int32_t w, int32_t h, const SwBBox& bbox, bool flipped);
void rasterXYFlip(uint32_t* src, uint32_t* dst, int32_t stride, int32_t w, int32_t h, const RenderRegion& bbox, bool flipped);
void rasterUnpremultiply(RenderSurface* surface);
void rasterPremultiply(RenderSurface* surface);
bool rasterConvertCS(RenderSurface* surface, ColorSpace to);

View file

@ -72,7 +72,7 @@ static bool _genOutline(SwImage* image, const Matrix& transform, SwMpool* mpool,
/* External Class Implementation */
/************************************************************************/
bool imagePrepare(SwImage* image, const Matrix& transform, const SwBBox& clipRegion, SwBBox& renderRegion, SwMpool* mpool, unsigned tid)
bool imagePrepare(SwImage* image, const Matrix& transform, const RenderRegion& clipRegion, RenderRegion& renderRegion, SwMpool* mpool, unsigned tid)
{
image->direct = _onlyShifted(transform);
@ -95,7 +95,7 @@ bool imagePrepare(SwImage* image, const Matrix& transform, const SwBBox& clipReg
}
bool imageGenRle(SwImage* image, const SwBBox& renderRegion, bool antiAlias)
bool imageGenRle(SwImage* image, const RenderRegion& renderRegion, bool antiAlias)
{
if ((image->rle = rleRender(image->rle, image->outline, renderRegion, antiAlias))) return true;

View file

@ -271,22 +271,7 @@ SwPoint mathTransform(const Point* to, const Matrix& transform)
}
bool mathClipBBox(const SwBBox& clipper, SwBBox& clippee)
{
clippee.max.x = (clippee.max.x < clipper.max.x) ? clippee.max.x : clipper.max.x;
clippee.max.y = (clippee.max.y < clipper.max.y) ? clippee.max.y : clipper.max.y;
clippee.min.x = (clippee.min.x > clipper.min.x) ? clippee.min.x : clipper.min.x;
clippee.min.y = (clippee.min.y > clipper.min.y) ? clippee.min.y : clipper.min.y;
//Check boundary
if (clippee.min.x >= clipper.max.x || clippee.min.y >= clipper.max.y ||
clippee.max.x <= clipper.min.x || clippee.max.y <= clipper.min.y) return false;
return true;
}
bool mathUpdateOutlineBBox(const SwOutline* outline, const SwBBox& clipRegion, SwBBox& renderRegion, bool fastTrack)
bool mathUpdateOutlineBBox(const SwOutline* outline, const RenderRegion& clipRegion, RenderRegion& renderRegion, bool fastTrack)
{
if (!outline) return false;
@ -310,16 +295,13 @@ bool mathUpdateOutlineBBox(const SwOutline* outline, const SwBBox& clipRegion, S
}
if (fastTrack) {
renderRegion.min.x = static_cast<SwCoord>(round(xMin / 64.0f));
renderRegion.max.x = static_cast<SwCoord>(round(xMax / 64.0f));
renderRegion.min.y = static_cast<SwCoord>(round(yMin / 64.0f));
renderRegion.max.y = static_cast<SwCoord>(round(yMax / 64.0f));
renderRegion.min = {int32_t(round(xMin / 64.0f)), int32_t(round(yMin / 64.0f))};
renderRegion.max = {int32_t(round(xMax / 64.0f)), int32_t(round(yMax / 64.0f))};
} else {
renderRegion.min.x = xMin >> 6;
renderRegion.max.x = (xMax + 63) >> 6;
renderRegion.min.y = yMin >> 6;
renderRegion.max.y = (yMax + 63) >> 6;
renderRegion.min = {xMin >> 6, yMin >> 6};
renderRegion.max = {(xMax + 63) >> 6, (yMax + 63) >> 6};
}
return mathClipBBox(clipRegion, renderRegion);
}
renderRegion.intersect(clipRegion);
return renderRegion.valid();
}

View file

@ -61,7 +61,7 @@ static inline int _gaussianRemap(int end, int idx)
//TODO: SIMD OPTIMIZATION?
template<int border = 0>
static void _gaussianFilter(uint8_t* dst, uint8_t* src, int32_t stride, int32_t w, int32_t h, const SwBBox& bbox, int32_t dimension, bool flipped)
static void _gaussianFilter(uint8_t* dst, uint8_t* src, int32_t stride, int32_t w, int32_t h, const RenderRegion& bbox, int32_t dimension, bool flipped)
{
if (flipped) {
src += (bbox.min.x * stride + bbox.min.y) << 2;
@ -230,7 +230,7 @@ struct SwDropShadow : SwGaussianBlur
//TODO: SIMD OPTIMIZATION?
static void _dropShadowFilter(uint32_t* dst, uint32_t* src, int stride, int w, int h, const SwBBox& bbox, int32_t dimension, uint32_t color, bool flipped)
static void _dropShadowFilter(uint32_t* dst, uint32_t* src, int stride, int w, int h, const RenderRegion& bbox, int32_t dimension, uint32_t color, bool flipped)
{
if (flipped) {
src += (bbox.min.x * stride + bbox.min.y);
@ -267,7 +267,7 @@ static void _dropShadowFilter(uint32_t* dst, uint32_t* src, int stride, int w, i
}
static void _dropShadowShift(uint32_t* dst, uint32_t* src, int dstride, int sstride, SwBBox& region, SwPoint& offset, uint8_t opacity, bool direct)
static void _dropShadowShift(uint32_t* dst, uint32_t* src, int dstride, int sstride, RenderRegion& region, SwPoint& offset, uint8_t opacity, bool direct)
{
src += (region.min.y * sstride + region.min.x);
dst += (region.min.y * dstride + region.min.x);

View file

@ -220,7 +220,7 @@ static inline SwMask _getMaskOp(MaskMethod method)
}
static bool _compositeMaskImage(SwSurface* surface, const SwImage* image, const SwBBox& region)
static bool _compositeMaskImage(SwSurface* surface, const SwImage* image, const RenderRegion& region)
{
auto dbuffer = &surface->buf8[region.min.y * surface->stride + region.min.x];
auto sbuffer = image->buf8 + (region.min.y + image->oy) * image->stride + (region.min.x + image->ox);
@ -317,17 +317,15 @@ 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 a)
static bool _rasterCompositeMaskedRect(SwSurface* surface, const RenderRegion& 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);
auto cstride = surface->compositor->image.stride;
auto cbuffer = surface->compositor->image.buf8 + (region.min.y * cstride + region.min.x); //compositor buffer
auto ialpha = 255 - a;
for (uint32_t y = 0; y < h; ++y) {
for (uint32_t y = 0; y < region.h(); ++y) {
auto cmp = cbuffer;
for (uint32_t x = 0; x < w; ++x, ++cmp) {
for (uint32_t x = 0; x < region.w(); ++x, ++cmp) {
*cmp = maskOp(a, *cmp, ialpha);
}
cbuffer += cstride;
@ -336,17 +334,15 @@ static bool _rasterCompositeMaskedRect(SwSurface* surface, const SwBBox& region,
}
static bool _rasterDirectMaskedRect(SwSurface* surface, const SwBBox& region, SwMask maskOp, uint8_t a)
static bool _rasterDirectMaskedRect(SwSurface* surface, const RenderRegion& 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);
auto cbuffer = surface->compositor->image.buf8 + (region.min.y * surface->compositor->image.stride + region.min.x); //compositor buffer
auto dbuffer = surface->buf8 + (region.min.y * surface->stride + region.min.x); //destination buffer
for (uint32_t y = 0; y < h; ++y) {
for (uint32_t y = 0; y < region.h(); ++y) {
auto cmp = cbuffer;
auto dst = dbuffer;
for (uint32_t x = 0; x < w; ++x, ++cmp, ++dst) {
for (uint32_t x = 0; x < region.w(); ++x, ++cmp, ++dst) {
auto tmp = maskOp(a, *cmp, 0); //not use alpha.
*dst = tmp + MULTIPLY(*dst, ~tmp);
}
@ -357,7 +353,7 @@ static bool _rasterDirectMaskedRect(SwSurface* surface, const SwBBox& region, Sw
}
static bool _rasterMaskedRect(SwSurface* surface, const SwBBox& region, const RenderColor& c)
static bool _rasterMaskedRect(SwSurface* surface, const RenderRegion& region, const RenderColor& c)
{
//8bit masking channels composition
if (surface->channelSize != sizeof(uint8_t)) return false;
@ -371,24 +367,22 @@ static bool _rasterMaskedRect(SwSurface* surface, const SwBBox& region, const Re
}
static bool _rasterMattedRect(SwSurface* surface, const SwBBox& region, const RenderColor& c)
static bool _rasterMattedRect(SwSurface* surface, const RenderRegion& 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);
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 alpha = surface->alpha(surface->compositor->method);
TVGLOG("SW_ENGINE", "Matted(%d) Rect [Region: %d %d %u %u]", (int)surface->compositor->method, region.min.x, region.min.y, w, h);
TVGLOG("SW_ENGINE", "Matted(%d) Rect [Region: %u %u %u %u]", (int)surface->compositor->method, region.x(), region.y(), region.w(), region.h());
//32bits channels
if (surface->channelSize == sizeof(uint32_t)) {
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) {
for (uint32_t y = 0; y < region.h(); ++y) {
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) {
for (uint32_t x = 0; x < region.w(); ++x, ++dst, cmp += csize) {
auto tmp = ALPHA_BLEND(color, alpha(cmp));
*dst = tmp + ALPHA_BLEND(*dst, IA(tmp));
}
@ -396,10 +390,10 @@ static bool _rasterMattedRect(SwSurface* surface, const SwBBox& region, const Re
//8bits grayscale
} else if (surface->channelSize == sizeof(uint8_t)) {
auto buffer = surface->buf8 + (region.min.y * surface->stride) + region.min.x;
for (uint32_t y = 0; y < h; ++y) {
for (uint32_t y = 0; y < region.h(); ++y) {
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) {
for (uint32_t x = 0; x < region.w(); ++x, ++dst, cmp += csize) {
*dst = INTERPOLATE8(c.a, *dst, alpha(cmp));
}
}
@ -408,18 +402,16 @@ static bool _rasterMattedRect(SwSurface* surface, const SwBBox& region, const Re
}
static bool _rasterBlendingRect(SwSurface* surface, const SwBBox& region, const RenderColor& c)
static bool _rasterBlendingRect(SwSurface* surface, const RenderRegion& 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(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) {
for (uint32_t y = 0; y < region.h(); ++y) {
auto dst = &buffer[y * surface->stride];
for (uint32_t x = 0; x < w; ++x, ++dst) {
for (uint32_t x = 0; x < region.w(); ++x, ++dst) {
*dst = surface->blender(color, *dst, 255);
}
}
@ -427,7 +419,7 @@ static bool _rasterBlendingRect(SwSurface* surface, const SwBBox& region, const
}
static bool _rasterTranslucentRect(SwSurface* surface, const SwBBox& region, const RenderColor& c)
static bool _rasterTranslucentRect(SwSurface* surface, const RenderRegion& region, const RenderColor& c)
{
#if defined(THORVG_AVX_VECTOR_SUPPORT)
return avxRasterTranslucentRect(surface, region, c);
@ -439,24 +431,21 @@ static bool _rasterTranslucentRect(SwSurface* surface, const SwBBox& region, con
}
static bool _rasterSolidRect(SwSurface* surface, const SwBBox& region, const RenderColor& c)
static bool _rasterSolidRect(SwSurface* surface, const RenderRegion& 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(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);
for (uint32_t y = 0; y < region.h(); ++y) {
rasterPixel32(buffer + y * surface->stride, color, region.min.x, region.w());
}
return true;
}
//8bits grayscale
if (surface->channelSize == sizeof(uint8_t)) {
for (uint32_t y = 0; y < h; ++y) {
rasterGrayscale8(surface->buf8, 255, (y + region.min.y) * surface->stride + region.min.x, w);
for (uint32_t y = 0; y < region.h(); ++y) {
rasterGrayscale8(surface->buf8, 255, (y + region.min.y) * surface->stride + region.min.x, region.w());
}
return true;
}
@ -464,7 +453,7 @@ static bool _rasterSolidRect(SwSurface* surface, const SwBBox& region, const Ren
}
static bool _rasterRect(SwSurface* surface, const SwBBox& region, const RenderColor& c)
static bool _rasterRect(SwSurface* surface, const RenderRegion& region, const RenderColor& c)
{
if (_compositing(surface)) {
if (_matting(surface)) return _rasterMattedRect(surface, region, c);
@ -687,14 +676,14 @@ static bool _rasterRle(SwSurface* surface, SwRle* rle, const RenderColor& c)
auto sx = (x) * itransform->e11 + itransform->e13 - 0.49f; \
if (sx <= -0.5f || (uint32_t)(sx + 0.5f) >= image->w) continue; \
static bool _rasterScaledMaskedRleImage(SwSurface* surface, const SwImage* image, const Matrix* itransform, const SwBBox& region, uint8_t opacity)
static bool _rasterScaledMaskedRleImage(SwSurface* surface, const SwImage* image, const Matrix* itransform, const RenderRegion& region, uint8_t opacity)
{
TVGERR("SW_ENGINE", "Not Supported Scaled Masked(%d) Rle Image", (int)surface->compositor->method);
return false;
}
static bool _rasterScaledMattedRleImage(SwSurface* surface, const SwImage* image, const Matrix* itransform, const SwBBox& region, uint8_t opacity)
static bool _rasterScaledMattedRleImage(SwSurface* surface, const SwImage* image, const Matrix* itransform, const RenderRegion& region, uint8_t opacity)
{
TVGLOG("SW_ENGINE", "Scaled Matted(%d) Rle Image", (int)surface->compositor->method);
@ -721,7 +710,7 @@ static bool _rasterScaledMattedRleImage(SwSurface* surface, const SwImage* image
}
static bool _rasterScaledBlendingRleImage(SwSurface* surface, const SwImage* image, const Matrix* itransform, const SwBBox& region, uint8_t opacity)
static bool _rasterScaledBlendingRleImage(SwSurface* surface, const SwImage* image, const Matrix* itransform, const RenderRegion& region, uint8_t opacity)
{
auto span = image->rle->spans;
auto scaleMethod = image->scale < DOWN_SCALE_TOLERANCE ? _interpDownScaler : _interpUpScaler;
@ -752,7 +741,7 @@ static bool _rasterScaledBlendingRleImage(SwSurface* surface, const SwImage* ima
}
static bool _rasterScaledRleImage(SwSurface* surface, const SwImage* image, const Matrix* itransform, const SwBBox& region, uint8_t opacity)
static bool _rasterScaledRleImage(SwSurface* surface, const SwImage* image, const Matrix* itransform, const RenderRegion& region, uint8_t opacity)
{
auto span = image->rle->spans;
auto scaleMethod = image->scale < DOWN_SCALE_TOLERANCE ? _interpDownScaler : _interpUpScaler;
@ -774,7 +763,7 @@ static bool _rasterScaledRleImage(SwSurface* surface, const SwImage* image, cons
}
static bool _scaledRleImage(SwSurface* surface, const SwImage* image, const Matrix& transform, const SwBBox& region, uint8_t opacity)
static bool _scaledRleImage(SwSurface* surface, const SwImage* image, const Matrix& transform, const RenderRegion& region, uint8_t opacity)
{
if (surface->channelSize == sizeof(uint8_t)) {
TVGERR("SW_ENGINE", "Not supported scaled rle image!");
@ -898,14 +887,14 @@ static bool _directRleImage(SwSurface* surface, const SwImage* image, uint8_t op
/*Scaled Image */
/************************************************************************/
static bool _rasterScaledMaskedImage(SwSurface* surface, const SwImage* image, const Matrix* itransform, const SwBBox& region, uint8_t opacity)
static bool _rasterScaledMaskedImage(SwSurface* surface, const SwImage* image, const Matrix* itransform, const RenderRegion& region, uint8_t opacity)
{
TVGERR("SW_ENGINE", "Not Supported Scaled Masked Image!");
return false;
}
static bool _rasterScaledMattedImage(SwSurface* surface, const SwImage* image, const Matrix* itransform, const SwBBox& region, uint8_t opacity)
static bool _rasterScaledMattedImage(SwSurface* surface, const SwImage* image, const Matrix* itransform, const RenderRegion& region, uint8_t opacity)
{
if (surface->channelSize == sizeof(uint8_t)) {
TVGERR("SW_ENGINE", "Not supported grayscale scaled matted image!");
@ -940,7 +929,7 @@ static bool _rasterScaledMattedImage(SwSurface* surface, const SwImage* image, c
}
static bool _rasterScaledBlendingImage(SwSurface* surface, const SwImage* image, const Matrix* itransform, const SwBBox& region, uint8_t opacity)
static bool _rasterScaledBlendingImage(SwSurface* surface, const SwImage* image, const Matrix* itransform, const RenderRegion& region, uint8_t opacity)
{
if (surface->channelSize == sizeof(uint8_t)) {
TVGERR("SW_ENGINE", "Not supported grayscale scaled blending image!");
@ -966,7 +955,7 @@ static bool _rasterScaledBlendingImage(SwSurface* surface, const SwImage* image,
}
static bool _rasterScaledImage(SwSurface* surface, const SwImage* image, const Matrix* itransform, const SwBBox& region, uint8_t opacity)
static bool _rasterScaledImage(SwSurface* surface, const SwImage* image, const Matrix* itransform, const RenderRegion& region, uint8_t opacity)
{
auto scaleMethod = image->scale < DOWN_SCALE_TOLERANCE ? _interpDownScaler : _interpUpScaler;
auto sampleSize = _sampleSize(image->scale);
@ -1001,7 +990,7 @@ static bool _rasterScaledImage(SwSurface* surface, const SwImage* image, const M
}
static bool _scaledImage(SwSurface* surface, const SwImage* image, const Matrix& transform, const SwBBox& region, uint8_t opacity)
static bool _scaledImage(SwSurface* surface, const SwImage* image, const Matrix& transform, const RenderRegion& region, uint8_t opacity)
{
Matrix itransform;
@ -1023,38 +1012,36 @@ static bool _scaledImage(SwSurface* surface, const SwImage* image, const Matrix&
/* Direct Image */
/************************************************************************/
static bool _rasterDirectMaskedImage(SwSurface* surface, const SwImage* image, const SwBBox& region, uint8_t opacity)
static bool _rasterDirectMaskedImage(SwSurface* surface, const SwImage* image, const RenderRegion& region, uint8_t opacity)
{
TVGERR("SW_ENGINE", "Not Supported: Direct Masked Image");
return false;
}
static bool _rasterDirectMattedImage(SwSurface* surface, const SwImage* image, const SwBBox& region, uint8_t opacity)
static bool _rasterDirectMattedImage(SwSurface* surface, const SwImage* image, const RenderRegion& region, uint8_t opacity)
{
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 csize = surface->compositor->image.channelSize;
auto alpha = surface->alpha(surface->compositor->method);
auto sbuffer = image->buf32 + (region.min.y + image->oy) * image->stride + (region.min.x + image->ox);
auto cbuffer = surface->compositor->image.buf8 + (region.min.y * surface->compositor->image.stride + region.min.x) * csize; //compositor buffer
TVGLOG("SW_ENGINE", "Direct Matted(%d) Image [Region: %d %d %u %u]", (int)surface->compositor->method, region.min.x, region.min.y, w, h);
TVGLOG("SW_ENGINE", "Direct Matted(%d) Image [Region: %u %u %u %u]", (int)surface->compositor->method, region.x(), region.y(), region.w(), region.h());
//32 bits
if (surface->channelSize == sizeof(uint32_t)) {
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 < region.h(); ++y) {
auto dst = buffer;
auto cmp = cbuffer;
auto src = sbuffer;
if (opacity == 255) {
for (uint32_t x = 0; x < w; ++x, ++dst, ++src, cmp += csize) {
for (uint32_t x = 0; x < region.w(); ++x, ++dst, ++src, cmp += csize) {
auto tmp = ALPHA_BLEND(*src, alpha(cmp));
*dst = tmp + ALPHA_BLEND(*dst, IA(tmp));
}
} else {
for (uint32_t x = 0; x < w; ++x, ++dst, ++src, cmp += csize) {
for (uint32_t x = 0; x < region.w(); ++x, ++dst, ++src, cmp += csize) {
auto tmp = ALPHA_BLEND(*src, MULTIPLY(opacity, alpha(cmp)));
*dst = tmp + ALPHA_BLEND(*dst, IA(tmp));
}
@ -1066,17 +1053,17 @@ static bool _rasterDirectMattedImage(SwSurface* surface, const SwImage* image, c
//8 bits
} else if (surface->channelSize == sizeof(uint8_t)) {
auto buffer = surface->buf8 + (region.min.y * surface->stride) + region.min.x;
for (uint32_t y = 0; y < h; ++y) {
for (uint32_t y = 0; y < region.h(); ++y) {
auto dst = buffer;
auto cmp = cbuffer;
auto src = sbuffer;
if (opacity == 255) {
for (uint32_t x = 0; x < w; ++x, ++dst, ++src, cmp += csize) {
for (uint32_t x = 0; x < region.w(); ++x, ++dst, ++src, cmp += csize) {
auto tmp = MULTIPLY(A(*src), alpha(cmp));
*dst = tmp + MULTIPLY(*dst, 255 - tmp);
}
} else {
for (uint32_t x = 0; x < w; ++x, ++dst, ++src, cmp += csize) {
for (uint32_t x = 0; x < region.w(); ++x, ++dst, ++src, cmp += csize) {
auto tmp = MULTIPLY(A(*src), MULTIPLY(opacity, alpha(cmp)));
*dst = tmp + MULTIPLY(*dst, 255 - tmp);
}
@ -1090,7 +1077,7 @@ static bool _rasterDirectMattedImage(SwSurface* surface, const SwImage* image, c
}
static bool _rasterDirectBlendingImage(SwSurface* surface, const SwImage* image, const SwBBox& region, uint8_t opacity)
static bool _rasterDirectBlendingImage(SwSurface* surface, const SwImage* image, const RenderRegion& region, uint8_t opacity)
{
if (surface->channelSize == sizeof(uint8_t)) {
TVGERR("SW_ENGINE", "Not supported grayscale image!");
@ -1121,7 +1108,7 @@ static bool _rasterDirectBlendingImage(SwSurface* surface, const SwImage* image,
}
static bool _rasterDirectImage(SwSurface* surface, const SwImage* image, const SwBBox& region, uint8_t opacity)
static bool _rasterDirectImage(SwSurface* surface, const SwImage* image, const RenderRegion& region, uint8_t opacity)
{
auto sbuffer = image->buf32 + (region.min.y + image->oy) * image->stride + (region.min.x + image->ox);
@ -1154,32 +1141,30 @@ static bool _rasterDirectImage(SwSurface* surface, const SwImage* image, const S
}
static bool _rasterDirectMattedBlendingImage(SwSurface* surface, const SwImage* image, const SwBBox& region, uint8_t opacity)
static bool _rasterDirectMattedBlendingImage(SwSurface* surface, const SwImage* image, const RenderRegion& region, uint8_t opacity)
{
if (surface->channelSize == sizeof(uint8_t)) {
TVGERR("SW_ENGINE", "Not supported grayscale image!");
return false;
}
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 csize = surface->compositor->image.channelSize;
auto alpha = surface->alpha(surface->compositor->method);
auto sbuffer = image->buf32 + (region.min.y + image->oy) * image->stride + (region.min.x + image->ox);
auto cbuffer = surface->compositor->image.buf8 + (region.min.y * surface->compositor->image.stride + region.min.x) * csize; //compositor buffer
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 < region.h(); ++y) {
auto dst = buffer;
auto cmp = cbuffer;
auto src = sbuffer;
if (opacity == 255) {
for (uint32_t x = 0; x < w; ++x, ++dst, ++src, cmp += csize) {
for (uint32_t x = 0; x < region.w(); ++x, ++dst, ++src, cmp += csize) {
auto tmp = ALPHA_BLEND(*src, alpha(cmp));
*dst = INTERPOLATE(surface->blender(tmp, *dst, 255), *dst, A(tmp));
}
} else {
for (uint32_t x = 0; x < w; ++x, ++dst, ++src, cmp += csize) {
for (uint32_t x = 0; x < region.w(); ++x, ++dst, ++src, cmp += csize) {
auto tmp = ALPHA_BLEND(*src, alpha(cmp));
*dst = INTERPOLATE(surface->blender(tmp, *dst, 255), *dst, MULTIPLY(opacity, A(tmp)));
}
@ -1193,7 +1178,7 @@ static bool _rasterDirectMattedBlendingImage(SwSurface* surface, const SwImage*
//Blenders for the following scenarios: [Composition / Non-Composition] * [Opaque / Translucent]
static bool _directImage(SwSurface* surface, const SwImage* image, const SwBBox& region, uint8_t opacity)
static bool _directImage(SwSurface* surface, const SwImage* image, const RenderRegion& region, uint8_t opacity)
{
if (_compositing(surface)) {
if (_matting(surface)) {
@ -1210,7 +1195,7 @@ static bool _directImage(SwSurface* surface, const SwImage* image, const SwBBox&
//Blenders for the following scenarios: [RLE / Whole] * [Direct / Scaled / Transformed]
static bool _rasterImage(SwSurface* surface, SwImage* image, const Matrix& transform, const SwBBox& region, uint8_t opacity)
static bool _rasterImage(SwSurface* surface, SwImage* image, const Matrix& transform, const RenderRegion& region, uint8_t opacity)
{
//RLE Image
if (image->rle) {
@ -1231,15 +1216,13 @@ static bool _rasterImage(SwSurface* surface, SwImage* image, const Matrix& trans
/************************************************************************/
template<typename fillMethod>
static bool _rasterCompositeGradientMaskedRect(SwSurface* surface, const SwBBox& region, const SwFill* fill, SwMask maskOp)
static bool _rasterCompositeGradientMaskedRect(SwSurface* surface, const RenderRegion& region, const SwFill* fill, SwMask maskOp)
{
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 cstride = surface->compositor->image.stride;
auto cbuffer = surface->compositor->image.buf8 + (region.min.y * cstride + region.min.x);
for (uint32_t y = 0; y < h; ++y) {
fillMethod()(fill, cbuffer, region.min.y + y, region.min.x, w, maskOp, 255);
for (uint32_t y = 0; y < region.h(); ++y) {
fillMethod()(fill, cbuffer, region.min.y + y, region.min.x, region.w(), maskOp, 255);
cbuffer += surface->stride;
}
return _compositeMaskImage(surface, &surface->compositor->image, surface->compositor->bbox);
@ -1247,16 +1230,14 @@ static bool _rasterCompositeGradientMaskedRect(SwSurface* surface, const SwBBox&
template<typename fillMethod>
static bool _rasterDirectGradientMaskedRect(SwSurface* surface, const SwBBox& region, const SwFill* fill, SwMask maskOp)
static bool _rasterDirectGradientMaskedRect(SwSurface* surface, const RenderRegion& region, const SwFill* fill, SwMask maskOp)
{
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 cstride = surface->compositor->image.stride;
auto cbuffer = surface->compositor->image.buf8 + (region.min.y * cstride + region.min.x);
auto dbuffer = surface->buf8 + (region.min.y * surface->stride + region.min.x);
for (uint32_t y = 0; y < h; ++y) {
fillMethod()(fill, dbuffer, region.min.y + y, region.min.x, w, cbuffer, maskOp, 255);
for (uint32_t y = 0; y < region.h(); ++y) {
fillMethod()(fill, dbuffer, region.min.y + y, region.min.x, region.w(), cbuffer, maskOp, 255);
cbuffer += cstride;
dbuffer += surface->stride;
}
@ -1265,7 +1246,7 @@ static bool _rasterDirectGradientMaskedRect(SwSurface* surface, const SwBBox& re
template<typename fillMethod>
static bool _rasterGradientMaskedRect(SwSurface* surface, const SwBBox& region, const SwFill* fill)
static bool _rasterGradientMaskedRect(SwSurface* surface, const RenderRegion& region, const SwFill* fill)
{
auto method = surface->compositor->method;
@ -1281,19 +1262,17 @@ static bool _rasterGradientMaskedRect(SwSurface* surface, const SwBBox& region,
template<typename fillMethod>
static bool _rasterGradientMattedRect(SwSurface* surface, const SwBBox& region, const SwFill* fill)
static bool _rasterGradientMattedRect(SwSurface* surface, const RenderRegion& region, const SwFill* fill)
{
auto buffer = surface->buf32 + (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 csize = surface->compositor->image.channelSize;
auto cbuffer = surface->compositor->image.buf8 + (region.min.y * surface->compositor->image.stride + region.min.x) * csize;
auto alpha = surface->alpha(surface->compositor->method);
TVGLOG("SW_ENGINE", "Matted(%d) Gradient [Region: %d %d %u %u]", (int)surface->compositor->method, region.min.x, region.min.y, w, h);
TVGLOG("SW_ENGINE", "Matted(%d) Gradient [Region: %u %u %u %u]", (int)surface->compositor->method, region.x(), region.y(), region.w(), region.h());
for (uint32_t y = 0; y < h; ++y) {
fillMethod()(fill, buffer, region.min.y + y, region.min.x, w, cbuffer, alpha, csize, 255);
for (uint32_t y = 0; y < region.h(); ++y) {
fillMethod()(fill, buffer, region.min.y + y, region.min.x, region.w(), cbuffer, alpha, csize, 255);
buffer += surface->stride;
cbuffer += surface->stride * csize;
}
@ -1302,42 +1281,37 @@ static bool _rasterGradientMattedRect(SwSurface* surface, const SwBBox& region,
template<typename fillMethod>
static bool _rasterBlendingGradientRect(SwSurface* surface, const SwBBox& region, const SwFill* fill)
static bool _rasterBlendingGradientRect(SwSurface* surface, const RenderRegion& region, const SwFill* fill)
{
auto buffer = surface->buf32 + (region.min.y * surface->stride) + region.min.x;
auto w = static_cast<uint32_t>(region.max.x - region.min.x);
auto h = static_cast<uint32_t>(region.max.y - region.min.y);
if (fill->translucent) {
for (uint32_t y = 0; y < h; ++y) {
fillMethod()(fill, buffer + y * surface->stride, region.min.y + y, region.min.x, w, opBlendPreNormal, surface->blender, 255);
for (uint32_t y = 0; y < region.h(); ++y) {
fillMethod()(fill, buffer + y * surface->stride, region.min.y + y, region.min.x, region.w(), opBlendPreNormal, surface->blender, 255);
}
} else {
for (uint32_t y = 0; y < h; ++y) {
fillMethod()(fill, buffer + y * surface->stride, region.min.y + y, region.min.x, w, opBlendSrcOver, surface->blender, 255);
for (uint32_t y = 0; y < region.h(); ++y) {
fillMethod()(fill, buffer + y * surface->stride, region.min.y + y, region.min.x, region.w(), opBlendSrcOver, surface->blender, 255);
}
}
return true;
}
template<typename fillMethod>
static bool _rasterTranslucentGradientRect(SwSurface* surface, const SwBBox& region, const SwFill* fill)
static bool _rasterTranslucentGradientRect(SwSurface* surface, const RenderRegion& region, const SwFill* fill)
{
auto h = static_cast<uint32_t>(region.max.y - region.min.y);
auto w = static_cast<uint32_t>(region.max.x - region.min.x);
//32 bits
if (surface->channelSize == sizeof(uint32_t)) {
auto buffer = surface->buf32 + (region.min.y * surface->stride) + region.min.x;
for (uint32_t y = 0; y < h; ++y) {
fillMethod()(fill, buffer, region.min.y + y, region.min.x, w, opBlendPreNormal, 255);
for (uint32_t y = 0; y < region.h(); ++y) {
fillMethod()(fill, buffer, region.min.y + y, region.min.x, region.w(), opBlendPreNormal, 255);
buffer += surface->stride;
}
//8 bits
} else if (surface->channelSize == sizeof(uint8_t)) {
auto buffer = surface->buf8 + (region.min.y * surface->stride) + region.min.x;
for (uint32_t y = 0; y < h; ++y) {
fillMethod()(fill, buffer, region.min.y + y, region.min.x, w, _opMaskAdd, 255);
for (uint32_t y = 0; y < region.h(); ++y) {
fillMethod()(fill, buffer, region.min.y + y, region.min.x, region.w(), _opMaskAdd, 255);
buffer += surface->stride;
}
}
@ -1346,23 +1320,20 @@ static bool _rasterTranslucentGradientRect(SwSurface* surface, const SwBBox& reg
template<typename fillMethod>
static bool _rasterSolidGradientRect(SwSurface* surface, const SwBBox& region, const SwFill* fill)
static bool _rasterSolidGradientRect(SwSurface* surface, const RenderRegion& region, const SwFill* fill)
{
auto w = static_cast<uint32_t>(region.max.x - region.min.x);
auto h = static_cast<uint32_t>(region.max.y - region.min.y);
//32 bits
if (surface->channelSize == sizeof(uint32_t)) {
auto buffer = surface->buf32 + (region.min.y * surface->stride) + region.min.x;
for (uint32_t y = 0; y < h; ++y) {
fillMethod()(fill, buffer, region.min.y + y, region.min.x, w, opBlendSrcOver, 255);
for (uint32_t y = 0; y < region.h(); ++y) {
fillMethod()(fill, buffer, region.min.y + y, region.min.x, region.w(), opBlendSrcOver, 255);
buffer += surface->stride;
}
//8 bits
} else if (surface->channelSize == sizeof(uint8_t)) {
auto buffer = surface->buf8 + (region.min.y * surface->stride) + region.min.x;
for (uint32_t y = 0; y < h; ++y) {
fillMethod()(fill, buffer, region.min.y + y, region.min.x, w, _opMaskNone, 255);
for (uint32_t y = 0; y < region.h(); ++y) {
fillMethod()(fill, buffer, region.min.y + y, region.min.x, region.w(), _opMaskNone, 255);
buffer += surface->stride;
}
}
@ -1370,7 +1341,7 @@ static bool _rasterSolidGradientRect(SwSurface* surface, const SwBBox& region, c
}
static bool _rasterLinearGradientRect(SwSurface* surface, const SwBBox& region, const SwFill* fill)
static bool _rasterLinearGradientRect(SwSurface* surface, const RenderRegion& region, const SwFill* fill)
{
if (_compositing(surface)) {
if (_matting(surface)) return _rasterGradientMattedRect<FillLinear>(surface, region, fill);
@ -1385,7 +1356,7 @@ static bool _rasterLinearGradientRect(SwSurface* surface, const SwBBox& region,
}
static bool _rasterRadialGradientRect(SwSurface* surface, const SwBBox& region, const SwFill* fill)
static bool _rasterRadialGradientRect(SwSurface* surface, const RenderRegion& region, const SwFill* fill)
{
if (_compositing(surface)) {
if (_matting(surface)) return _rasterGradientMattedRect<FillRadial>(surface, region, fill);
@ -1777,7 +1748,7 @@ bool rasterStroke(SwSurface* surface, SwShape* shape, RenderColor& c)
}
bool rasterImage(SwSurface* surface, SwImage* image, const Matrix& transform, const SwBBox& bbox, uint8_t opacity)
bool rasterImage(SwSurface* surface, SwImage* image, const Matrix& transform, const RenderRegion& bbox, uint8_t opacity)
{
//Outside of the viewport, skip the rendering
if (bbox.max.x < 0 || bbox.max.y < 0 || bbox.min.x >= static_cast<SwCoord>(surface->w) || bbox.min.y >= static_cast<SwCoord>(surface->h)) return true;
@ -1807,7 +1778,7 @@ bool rasterConvertCS(RenderSurface* surface, ColorSpace to)
//TODO: SIMD OPTIMIZATION?
void rasterXYFlip(uint32_t* src, uint32_t* dst, int32_t stride, int32_t w, int32_t h, const SwBBox& bbox, bool flipped)
void rasterXYFlip(uint32_t* src, uint32_t* dst, int32_t stride, int32_t w, int32_t h, const RenderRegion& bbox, bool flipped)
{
constexpr int32_t BLOCK = 8; //experimental decision

View file

@ -99,10 +99,10 @@ static void avxRasterPixel32(uint32_t *dst, uint32_t val, uint32_t offset, int32
}
static bool avxRasterTranslucentRect(SwSurface* surface, const SwBBox& region, const RenderColor& c)
static bool avxRasterTranslucentRect(SwSurface* surface, const RenderRegion& 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);
auto h = region.h();
auto w = region.w();
//32bits channels
if (surface->channelSize == sizeof(uint32_t)) {

View file

@ -126,19 +126,16 @@ static bool inline cRasterTranslucentRle(SwSurface* surface, const SwRle* rle, c
}
static bool inline cRasterTranslucentRect(SwSurface* surface, const SwBBox& region, const RenderColor& c)
static bool inline cRasterTranslucentRect(SwSurface* surface, const RenderRegion& 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(c.r, c.g, c.b, c.a);
auto buffer = surface->buf32 + (region.min.y * surface->stride) + region.min.x;
auto ialpha = 255 - c.a;
for (uint32_t y = 0; y < h; ++y) {
for (uint32_t y = 0; y < region.h(); ++y) {
auto dst = &buffer[y * surface->stride];
for (uint32_t x = 0; x < w; ++x, ++dst) {
for (uint32_t x = 0; x < region.w(); ++x, ++dst) {
*dst = color + ALPHA_BLEND(*dst, ialpha);
}
}
@ -146,9 +143,9 @@ static bool inline cRasterTranslucentRect(SwSurface* surface, const SwBBox& regi
} else if (surface->channelSize == sizeof(uint8_t)) {
auto buffer = surface->buf8 + (region.min.y * surface->stride) + region.min.x;
auto ialpha = ~c.a;
for (uint32_t y = 0; y < h; ++y) {
for (uint32_t y = 0; y < region.h(); ++y) {
auto dst = &buffer[y * surface->stride];
for (uint32_t x = 0; x < w; ++x, ++dst) {
for (uint32_t x = 0; x < region.w(); ++x, ++dst) {
*dst = c.a + MULTIPLY(*dst, ialpha);
}
}

View file

@ -146,10 +146,10 @@ static bool neonRasterTranslucentRle(SwSurface* surface, const SwRle* rle, const
}
static bool neonRasterTranslucentRect(SwSurface* surface, const SwBBox& region, const RenderColor& c)
static bool neonRasterTranslucentRect(SwSurface* surface, const RenderRegion& 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);
auto h = region.h();
auto w = region.w();
//32bits channels
if (surface->channelSize == sizeof(uint32_t)) {

View file

@ -52,7 +52,7 @@ static float xa, xb, ua, va;
//Y Range exception handling
static bool _arrange(const SwImage* image, const SwBBox* region, int& yStart, int& yEnd)
static bool _arrange(const SwImage* image, const RenderRegion* region, int& yStart, int& yEnd)
{
int32_t regionTop, regionBottom;
@ -71,14 +71,14 @@ static bool _arrange(const SwImage* image, const SwBBox* region, int& yStart, in
}
static bool _rasterMaskedPolygonImageSegment(SwSurface* surface, const SwImage* image, const SwBBox* region, int yStart, int yEnd, AASpans* aaSpans, uint8_t opacity, uint8_t dirFlag = 0)
static bool _rasterMaskedPolygonImageSegment(SwSurface* surface, const SwImage* image, const RenderRegion* region, int yStart, int yEnd, AASpans* aaSpans, uint8_t opacity, uint8_t dirFlag = 0)
{
TVGERR("SW_ENGINE", "TODO: _rasterMaskedPolygonImageSegment()");
return false;
}
static void _rasterBlendingPolygonImageSegment(SwSurface* surface, const SwImage* image, const SwBBox* region, int yStart, int yEnd, AASpans* aaSpans, uint8_t opacity)
static void _rasterBlendingPolygonImageSegment(SwSurface* surface, const SwImage* image, const RenderRegion* region, int yStart, int yEnd, AASpans* aaSpans, uint8_t opacity)
{
float _dudx = dudx, _dvdx = dvdx;
float _dxdya = dxdya, _dxdyb = dxdyb, _dudya = dudya, _dvdya = dvdya;
@ -206,7 +206,7 @@ static void _rasterBlendingPolygonImageSegment(SwSurface* surface, const SwImage
}
static void _rasterPolygonImageSegment(SwSurface* surface, const SwImage* image, const SwBBox* region, int yStart, int yEnd, AASpans* aaSpans, uint8_t opacity, bool matting)
static void _rasterPolygonImageSegment(SwSurface* surface, const SwImage* image, const RenderRegion* region, int yStart, int yEnd, AASpans* aaSpans, uint8_t opacity, bool matting)
{
float _dudx = dudx, _dvdx = dvdx;
float _dxdya = dxdya, _dxdyb = dxdyb, _dudya = dudya, _dvdya = dvdya;
@ -399,7 +399,7 @@ static void _rasterPolygonImageSegment(SwSurface* surface, const SwImage* image,
/* This mapping algorithm is based on Mikael Kalms's. */
static void _rasterPolygonImage(SwSurface* surface, const SwImage* image, const SwBBox* region, Polygon& polygon, AASpans* aaSpans, uint8_t opacity)
static void _rasterPolygonImage(SwSurface* surface, const SwImage* image, const RenderRegion* region, Polygon& polygon, AASpans* aaSpans, uint8_t opacity)
{
float x[3] = {polygon.vertex[0].pt.x, polygon.vertex[1].pt.x, polygon.vertex[2].pt.x};
float y[3] = {polygon.vertex[0].pt.y, polygon.vertex[1].pt.y, polygon.vertex[2].pt.y};
@ -576,7 +576,7 @@ static void _rasterPolygonImage(SwSurface* surface, const SwImage* image, const
}
static AASpans* _AASpans(float ymin, float ymax, const SwImage* image, const SwBBox* region)
static AASpans* _AASpans(float ymin, float ymax, const SwImage* image, const RenderRegion* region)
{
auto yStart = static_cast<int>(ymin);
auto yEnd = static_cast<int>(ymax);
@ -863,7 +863,7 @@ static bool _apply(SwSurface* surface, AASpans* aaSpans)
| / |
3 -- 2
*/
static bool _rasterTexmapPolygon(SwSurface* surface, const SwImage* image, const Matrix& transform, const SwBBox* region, uint8_t opacity)
static bool _rasterTexmapPolygon(SwSurface* surface, const SwImage* image, const Matrix& transform, const RenderRegion* region, uint8_t opacity)
{
if (surface->channelSize == sizeof(uint8_t)) {
TVGERR("SW_ENGINE", "Not supported grayscale Textmap polygon!");

View file

@ -40,7 +40,7 @@ struct SwTask : Task
{
SwSurface* surface = nullptr;
SwMpool* mpool = nullptr;
SwBBox bbox; //Rendering Region
RenderRegion bbox; //Rendering Region
Matrix transform;
Array<RenderData> clips;
RenderUpdateFlag flags = RenderUpdateFlag::None;
@ -48,18 +48,11 @@ struct SwTask : Task
bool pushed = false; //Pushed into task list?
bool disposed = false; //Disposed task?
RenderRegion bounds()
const RenderRegion& bounds()
{
//Can we skip the synchronization?
done();
RenderRegion region;
region.min.x = bbox.min.x > 0 ? bbox.min.x : 0;
region.min.y = bbox.min.y > 0 ? bbox.min.y : 0;
region.max.x = bbox.max.x > bbox.min.x ? bbox.max.x : bbox.min.x;
region.max.y = bbox.max.y > bbox.min.y ? bbox.max.y : bbox.min.y;
return region;
return bbox;
}
virtual void dispose() = 0;
@ -113,7 +106,7 @@ struct SwShapeTask : SwTask
}
auto strokeWidth = validStrokeWidth(clipper);
SwBBox renderRegion{};
RenderRegion renderRegion{};
auto updateShape = flags & (RenderUpdateFlag::Path | RenderUpdateFlag::Transform | RenderUpdateFlag::Clip);
auto updateFill = false;
@ -566,40 +559,19 @@ SwSurface* SwRenderer::request(int channelSize, bool square)
RenderCompositor* SwRenderer::target(const RenderRegion& region, ColorSpace cs, CompositionFlag flags)
{
auto min = region.min;
auto max = region.max;
auto sw = static_cast<int32_t>(surface->w);
auto sh = static_cast<int32_t>(surface->h);
//Out of boundary
if (min.x >= sw || min.y >= sh || max.x < 0 || max.y < 0) return nullptr;
auto bbox = RenderRegion::intersect(region, {{0, 0}, {int32_t(surface->w), int32_t(surface->h)}});
if (bbox.invalid()) return nullptr;
auto cmp = request(CHANNEL_SIZE(cs), (flags & CompositionFlag::PostProcessing));
//Boundary Check
if (min.x < 0) min.x = 0;
if (min.y < 0) min.y = 0;
if (max.x > sw) max.x = (sw - min.x);
if (max.y > sh) max.y = (sh - min.y);
auto w = max.x - min.x;
auto h = max.y - min.y;
if (w == 0 || h == 0) return nullptr;
cmp->compositor->recoverSfc = surface;
cmp->compositor->recoverCmp = surface->compositor;
cmp->compositor->valid = false;
cmp->compositor->bbox.min.x = min.x;
cmp->compositor->bbox.min.y = min.y;
cmp->compositor->bbox.max.x = max.x;
cmp->compositor->bbox.max.y = max.y;
cmp->compositor->bbox = bbox;
/* TODO: Currently, only blending might work.
Blending and composition must be handled together. */
auto color = (surface->blender && !surface->compositor) ? 0x00ffffff : 0x00000000;
rasterClear(cmp, min.x, min.y, w, h, color);
rasterClear(cmp, bbox.x(), bbox.y(), bbox.w(), bbox.h(), color);
//Switch render target
surface = cmp;
@ -729,16 +701,13 @@ void* SwRenderer::prepareCommon(SwTask* task, const Matrix& transform, const Arr
static_cast<SwTask*>(*p)->done();
}
task->clips = clips;
task->transform = transform;
task->opacity = opacity;
task->surface = surface;
task->mpool = mpool;
task->bbox = RenderRegion::intersect(vport, {{0, 0}, {int32_t(surface->w), int32_t(surface->h)}});
task->transform = transform;
task->clips = clips;
task->opacity = opacity;
task->flags = flags;
task->bbox.min.x = std::max(static_cast<SwCoord>(0), static_cast<SwCoord>(vport.min.x));
task->bbox.min.y = std::max(static_cast<SwCoord>(0), static_cast<SwCoord>(vport.min.y));
task->bbox.max.x = std::min(static_cast<SwCoord>(surface->w), static_cast<SwCoord>(vport.max.x));
task->bbox.max.y = std::min(static_cast<SwCoord>(surface->h), static_cast<SwCoord>(vport.max.y));
if (!task->pushed) {
task->pushed = true;

View file

@ -793,7 +793,7 @@ static SwSpan* _intersectSpansRegion(const SwRle *clip, const SwRle *target, SwS
}
static SwSpan* _intersectSpansRect(const SwBBox *bbox, const SwRle *targetRle, SwSpan *outSpans, uint32_t outSpansCnt)
static SwSpan* _intersectSpansRect(const RenderRegion *bbox, const SwRle *targetRle, SwSpan *outSpans, uint32_t outSpansCnt)
{
auto out = outSpans;
auto spans = targetRle->spans;
@ -844,7 +844,7 @@ void _replaceClipSpan(SwRle *rle, SwSpan* clippedSpans, uint32_t size)
/* External Class Implementation */
/************************************************************************/
SwRle* rleRender(SwRle* rle, const SwOutline* outline, const SwBBox& renderRegion, bool antiAlias)
SwRle* rleRender(SwRle* rle, const SwOutline* outline, const RenderRegion& renderRegion, bool antiAlias)
{
if (!outline) return nullptr;
@ -865,8 +865,8 @@ SwRle* rleRender(SwRle* rle, const SwOutline* outline, const SwBBox& renderRegio
rw.area = 0;
rw.cover = 0;
rw.invalid = true;
rw.cellMin = renderRegion.min;
rw.cellMax = renderRegion.max;
rw.cellMin = {renderRegion.min.x, renderRegion.min.y};
rw.cellMax = {renderRegion.max.x, renderRegion.max.y};
rw.cellXCnt = rw.cellMax.x - rw.cellMin.x;
rw.cellYCnt = rw.cellMax.y - rw.cellMin.y;
rw.outline = const_cast<SwOutline*>(outline);
@ -961,10 +961,10 @@ error:
}
SwRle* rleRender(const SwBBox* bbox)
SwRle* rleRender(const RenderRegion* bbox)
{
auto width = static_cast<uint16_t>(bbox->max.x - bbox->min.x);
auto height = static_cast<uint16_t>(bbox->max.y - bbox->min.y);
auto width = static_cast<uint16_t>(bbox->w());
auto height = static_cast<uint16_t>(bbox->h());
auto rle = tvg::malloc<SwRle*>(sizeof(SwRle));
rle->spans = tvg::malloc<SwSpan*>(sizeof(SwSpan) * height);
@ -1013,7 +1013,7 @@ bool rleClip(SwRle *rle, const SwRle *clip)
}
bool rleClip(SwRle *rle, const SwBBox* clip)
bool rleClip(SwRle *rle, const RenderRegion* clip)
{
if (rle->size == 0) return false;
auto spans = tvg::malloc<SwSpan*>(sizeof(SwSpan) * (rle->size));

View file

@ -419,7 +419,7 @@ static SwOutline* _genOutline(SwShape* shape, const RenderShape* rshape, const M
/* External Class Implementation */
/************************************************************************/
bool shapePrepare(SwShape* shape, const RenderShape* rshape, const Matrix& transform, const SwBBox& clipRegion, SwBBox& renderRegion, SwMpool* mpool, unsigned tid, bool hasComposite)
bool shapePrepare(SwShape* shape, const RenderShape* rshape, const Matrix& transform, const RenderRegion& clipRegion, RenderRegion& renderRegion, SwMpool* mpool, unsigned tid, bool hasComposite)
{
if (auto out = _genOutline(shape, rshape, transform, mpool, tid, hasComposite, rshape->trimpath())) shape->outline = out;
else return false;
@ -500,7 +500,7 @@ void shapeResetStroke(SwShape* shape, const RenderShape* rshape, const Matrix& t
}
bool shapeGenStrokeRle(SwShape* shape, const RenderShape* rshape, const Matrix& transform, const SwBBox& clipRegion, SwBBox& renderRegion, SwMpool* mpool, unsigned tid)
bool shapeGenStrokeRle(SwShape* shape, const RenderShape* rshape, const Matrix& transform, const RenderRegion& clipRegion, RenderRegion& renderRegion, SwMpool* mpool, unsigned tid)
{
SwOutline* shapeOutline = nullptr;
SwOutline* strokeOutline = nullptr;