From ff3eb052d1950ae3d91cd7f427a6ba9a1ada1049 Mon Sep 17 00:00:00 2001 From: Hermet Park Date: Mon, 26 May 2025 23:17:33 +0900 Subject: [PATCH] sw_engine: unify RenderRegion and SwBBox refactored for smoother data flow through the rendering pipeline. --- src/renderer/sw_engine/tvgSwCommon.h | 47 ++--- src/renderer/sw_engine/tvgSwImage.cpp | 4 +- src/renderer/sw_engine/tvgSwMath.cpp | 34 +--- src/renderer/sw_engine/tvgSwPostEffect.cpp | 6 +- src/renderer/sw_engine/tvgSwRaster.cpp | 193 +++++++++------------ src/renderer/sw_engine/tvgSwRasterAvx.h | 6 +- src/renderer/sw_engine/tvgSwRasterC.h | 13 +- src/renderer/sw_engine/tvgSwRasterNeon.h | 6 +- src/renderer/sw_engine/tvgSwRasterTexmap.h | 14 +- src/renderer/sw_engine/tvgSwRenderer.cpp | 55 ++---- src/renderer/sw_engine/tvgSwRle.cpp | 16 +- src/renderer/sw_engine/tvgSwShape.cpp | 4 +- 12 files changed, 153 insertions(+), 245 deletions(-) diff --git a/src/renderer/sw_engine/tvgSwCommon.h b/src/renderer/sw_engine/tvgSwCommon.h index 5b65f978..6e13c25a 100644 --- a/src/renderer/sw_engine/tvgSwCommon.h +++ b/src/renderer/sw_engine/tvgSwCommon.h @@ -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); diff --git a/src/renderer/sw_engine/tvgSwImage.cpp b/src/renderer/sw_engine/tvgSwImage.cpp index f76ebaef..11cc0f22 100644 --- a/src/renderer/sw_engine/tvgSwImage.cpp +++ b/src/renderer/sw_engine/tvgSwImage.cpp @@ -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; diff --git a/src/renderer/sw_engine/tvgSwMath.cpp b/src/renderer/sw_engine/tvgSwMath.cpp index 31a2c3eb..76b39671 100644 --- a/src/renderer/sw_engine/tvgSwMath.cpp +++ b/src/renderer/sw_engine/tvgSwMath.cpp @@ -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(round(xMin / 64.0f)); - renderRegion.max.x = static_cast(round(xMax / 64.0f)); - renderRegion.min.y = static_cast(round(yMin / 64.0f)); - renderRegion.max.y = static_cast(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(); +} \ No newline at end of file diff --git a/src/renderer/sw_engine/tvgSwPostEffect.cpp b/src/renderer/sw_engine/tvgSwPostEffect.cpp index 410b3f5a..1a1c8db8 100644 --- a/src/renderer/sw_engine/tvgSwPostEffect.cpp +++ b/src/renderer/sw_engine/tvgSwPostEffect.cpp @@ -61,7 +61,7 @@ static inline int _gaussianRemap(int end, int idx) //TODO: SIMD OPTIMIZATION? template -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); diff --git a/src/renderer/sw_engine/tvgSwRaster.cpp b/src/renderer/sw_engine/tvgSwRaster.cpp index 6e6741be..4ea1f783 100644 --- a/src/renderer/sw_engine/tvgSwRaster.cpp +++ b/src/renderer/sw_engine/tvgSwRaster.cpp @@ -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(region.max.x - region.min.x); - auto h = static_cast(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(region.max.x - region.min.x); - auto h = static_cast(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(region.max.x - region.min.x); - auto h = static_cast(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(region.max.x - region.min.x); - auto h = static_cast(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(region.max.x - region.min.x); - auto h = static_cast(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(region.max.y - region.min.y); - auto w = static_cast(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(region.max.y - region.min.y); - auto w = static_cast(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 -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(region.max.y - region.min.y); - auto w = static_cast(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 -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(region.max.y - region.min.y); - auto w = static_cast(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 -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 -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(region.max.y - region.min.y); - auto w = static_cast(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 -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(region.max.x - region.min.x); - auto h = static_cast(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 -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(region.max.y - region.min.y); - auto w = static_cast(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 -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(region.max.x - region.min.x); - auto h = static_cast(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(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(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(surface->w) || bbox.min.y >= static_cast(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 diff --git a/src/renderer/sw_engine/tvgSwRasterAvx.h b/src/renderer/sw_engine/tvgSwRasterAvx.h index db9e1d84..103f7dc5 100644 --- a/src/renderer/sw_engine/tvgSwRasterAvx.h +++ b/src/renderer/sw_engine/tvgSwRasterAvx.h @@ -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(region.max.y - region.min.y); - auto w = static_cast(region.max.x - region.min.x); + auto h = region.h(); + auto w = region.w(); //32bits channels if (surface->channelSize == sizeof(uint32_t)) { diff --git a/src/renderer/sw_engine/tvgSwRasterC.h b/src/renderer/sw_engine/tvgSwRasterC.h index 9f3ef076..7d00929a 100644 --- a/src/renderer/sw_engine/tvgSwRasterC.h +++ b/src/renderer/sw_engine/tvgSwRasterC.h @@ -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(region.max.y - region.min.y); - auto w = static_cast(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); } } diff --git a/src/renderer/sw_engine/tvgSwRasterNeon.h b/src/renderer/sw_engine/tvgSwRasterNeon.h index 63e47ccf..37596250 100644 --- a/src/renderer/sw_engine/tvgSwRasterNeon.h +++ b/src/renderer/sw_engine/tvgSwRasterNeon.h @@ -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(region.max.y - region.min.y); - auto w = static_cast(region.max.x - region.min.x); + auto h = region.h(); + auto w = region.w(); //32bits channels if (surface->channelSize == sizeof(uint32_t)) { diff --git a/src/renderer/sw_engine/tvgSwRasterTexmap.h b/src/renderer/sw_engine/tvgSwRasterTexmap.h index 138020ee..c9264798 100644 --- a/src/renderer/sw_engine/tvgSwRasterTexmap.h +++ b/src/renderer/sw_engine/tvgSwRasterTexmap.h @@ -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(ymin); auto yEnd = static_cast(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!"); diff --git a/src/renderer/sw_engine/tvgSwRenderer.cpp b/src/renderer/sw_engine/tvgSwRenderer.cpp index b7cc684b..f85e817a 100644 --- a/src/renderer/sw_engine/tvgSwRenderer.cpp +++ b/src/renderer/sw_engine/tvgSwRenderer.cpp @@ -40,7 +40,7 @@ struct SwTask : Task { SwSurface* surface = nullptr; SwMpool* mpool = nullptr; - SwBBox bbox; //Rendering Region + RenderRegion bbox; //Rendering Region Matrix transform; Array 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(surface->w); - auto sh = static_cast(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(*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(0), static_cast(vport.min.x)); - task->bbox.min.y = std::max(static_cast(0), static_cast(vport.min.y)); - task->bbox.max.x = std::min(static_cast(surface->w), static_cast(vport.max.x)); - task->bbox.max.y = std::min(static_cast(surface->h), static_cast(vport.max.y)); if (!task->pushed) { task->pushed = true; diff --git a/src/renderer/sw_engine/tvgSwRle.cpp b/src/renderer/sw_engine/tvgSwRle.cpp index 82a9bdf2..82d5ae23 100644 --- a/src/renderer/sw_engine/tvgSwRle.cpp +++ b/src/renderer/sw_engine/tvgSwRle.cpp @@ -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(outline); @@ -961,10 +961,10 @@ error: } -SwRle* rleRender(const SwBBox* bbox) +SwRle* rleRender(const RenderRegion* bbox) { - auto width = static_cast(bbox->max.x - bbox->min.x); - auto height = static_cast(bbox->max.y - bbox->min.y); + auto width = static_cast(bbox->w()); + auto height = static_cast(bbox->h()); auto rle = tvg::malloc(sizeof(SwRle)); rle->spans = tvg::malloc(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(sizeof(SwSpan) * (rle->size)); diff --git a/src/renderer/sw_engine/tvgSwShape.cpp b/src/renderer/sw_engine/tvgSwShape.cpp index 71d9884a..44bd9a98 100644 --- a/src/renderer/sw_engine/tvgSwShape.cpp +++ b/src/renderer/sw_engine/tvgSwShape.cpp @@ -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;