diff --git a/src/common/tvgMath.cpp b/src/common/tvgMath.cpp index 37da754b..6c738e29 100644 --- a/src/common/tvgMath.cpp +++ b/src/common/tvgMath.cpp @@ -114,17 +114,6 @@ float atan2(float y, float x) } -Matrix multiply(const Matrix* lhs, const Matrix* rhs) -{ - Matrix out; - if (lhs && rhs) out = *lhs * *rhs; - else if (lhs) out = *lhs; - else if (rhs) out = *rhs; - else identity(&out); - return out; -} - - bool inverse(const Matrix* m, Matrix* out) { auto det = m->e11 * (m->e22 * m->e33 - m->e32 * m->e23) - diff --git a/src/common/tvgMath.h b/src/common/tvgMath.h index 1ce51c32..fa8ef706 100644 --- a/src/common/tvgMath.h +++ b/src/common/tvgMath.h @@ -75,21 +75,20 @@ static inline bool equal(float a, float b) void rotate(Matrix* m, float degree); bool inverse(const Matrix* m, Matrix* out); bool identity(const Matrix* m); -Matrix multiply(const Matrix* lhs, const Matrix* rhs); Matrix operator*(const Matrix& lhs, const Matrix& rhs); bool operator==(const Matrix& lhs, const Matrix& rhs); -static inline bool rightAngle(const Matrix* m) +static inline bool rightAngle(const Matrix& m) { - auto radian = fabsf(tvg::atan2(m->e21, m->e11)); + auto radian = fabsf(tvg::atan2(m.e21, m.e11)); if (radian < FLOAT_EPSILON || tvg::equal(radian, MATH_PI2) || tvg::equal(radian, MATH_PI)) return true; return false; } -static inline bool skewed(const Matrix* m) +static inline bool skewed(const Matrix& m) { - return !tvg::zero(m->e21 + m->e12); + return !tvg::zero(m.e21 + m.e12); } diff --git a/src/loaders/lottie/tvgLottieBuilder.cpp b/src/loaders/lottie/tvgLottieBuilder.cpp index 0fb4c0d2..c2892fcd 100644 --- a/src/loaders/lottie/tvgLottieBuilder.cpp +++ b/src/loaders/lottie/tvgLottieBuilder.cpp @@ -252,8 +252,7 @@ static void _updateTransform(LottieGroup* parent, LottieObject** child, float fr Matrix matrix; if (!_updateTransform(transform, frameNo, false, matrix, opacity, exps)) return; - auto pmatrix = PP(ctx->propagator)->transform(); - ctx->propagator->transform(pmatrix ? (*pmatrix * matrix) : matrix); + ctx->propagator->transform(PP(ctx->propagator)->transform() * matrix); ctx->propagator->opacity(MULTIPLY(opacity, PP(ctx->propagator)->opacity)); //FIXME: preserve the stroke width. too workaround, need a better design. @@ -418,14 +417,9 @@ static void _repeat(LottieGroup* parent, Shape* path, RenderContext* ctx) translateR(&m, -repeater->anchor.x, -repeater->anchor.y); m = repeater->transform * m; - auto pm = PP(shape)->transform(); - if (pm) { - Matrix m; - inverse(&repeater->transform, &m); - *pm = m * *pm; - } - - shape->transform(pm ? m * *pm : m); + Matrix inv; + inverse(&repeater->transform, &inv); + shape->transform(m * (inv * PP(shape)->transform())); shapes.push(shape); } } @@ -928,8 +922,7 @@ static void _updateRepeater(TVG_UNUSED LottieGroup* parent, LottieObject** child RenderRepeater r; r.cnt = static_cast(repeater->copies(frameNo, exps)); - if (auto tr = PP(ctx->propagator)->transform()) r.transform = *tr; - else identity(&r.transform); + r.transform = PP(ctx->propagator)->transform(); r.offset = repeater->offset(frameNo, exps); r.position = repeater->position(frameNo, exps); r.anchor = repeater->anchor(frameNo, exps); diff --git a/src/renderer/gl_engine/tvgGlGeometry.cpp b/src/renderer/gl_engine/tvgGlGeometry.cpp index bdf4e771..11d68076 100644 --- a/src/renderer/gl_engine/tvgGlGeometry.cpp +++ b/src/renderer/gl_engine/tvgGlGeometry.cpp @@ -215,27 +215,30 @@ bool GlGeometry::draw(GlRenderTask* task, GlStageBuffer* gpuBuffer, RenderUpdate } -void GlGeometry::updateTransform(const Matrix* m) +void GlGeometry::updateTransform(const Matrix& m) { - if (m) mMatrix = *m; - else tvg::identity(&mMatrix); + mMatrix = m; } + void GlGeometry::setViewport(const RenderRegion& viewport) { this->viewport = viewport; } + const RenderRegion& GlGeometry::getViewport() { return viewport; } + const Matrix& GlGeometry::getTransformMatrix() { return mMatrix; } + GlStencilMode GlGeometry::getStencilMode(RenderUpdateFlag flag) { if (flag & RenderUpdateFlag::Stroke) return GlStencilMode::Stroke; @@ -248,6 +251,7 @@ GlStencilMode GlGeometry::getStencilMode(RenderUpdateFlag flag) return GlStencilMode::None; } + RenderRegion GlGeometry::getBounds() const { if (identity(&mMatrix)) { diff --git a/src/renderer/gl_engine/tvgGlGeometry.h b/src/renderer/gl_engine/tvgGlGeometry.h index a04e175a..5e74d92b 100644 --- a/src/renderer/gl_engine/tvgGlGeometry.h +++ b/src/renderer/gl_engine/tvgGlGeometry.h @@ -193,7 +193,7 @@ public: bool tesselate(const Surface* image, const RenderMesh* mesh, RenderUpdateFlag flag); void disableVertex(uint32_t location); bool draw(GlRenderTask* task, GlStageBuffer* gpuBuffer, RenderUpdateFlag flag); - void updateTransform(const Matrix* m); + void updateTransform(const Matrix& m); void setViewport(const RenderRegion& viewport); const RenderRegion& getViewport(); const Matrix& getTransformMatrix(); diff --git a/src/renderer/gl_engine/tvgGlRenderer.cpp b/src/renderer/gl_engine/tvgGlRenderer.cpp index c6421055..d9b6ab11 100644 --- a/src/renderer/gl_engine/tvgGlRenderer.cpp +++ b/src/renderer/gl_engine/tvgGlRenderer.cpp @@ -1099,7 +1099,7 @@ static GLuint _genTexture(Surface* image) } -RenderData GlRenderer::prepare(Surface* image, const RenderMesh* mesh, RenderData data, const Matrix* transform, Array& clips, uint8_t opacity, RenderUpdateFlag flags) +RenderData GlRenderer::prepare(Surface* image, const RenderMesh* mesh, RenderData data, const Matrix& transform, Array& clips, uint8_t opacity, RenderUpdateFlag flags) { if (flags == RenderUpdateFlag::None) return data; @@ -1130,14 +1130,14 @@ RenderData GlRenderer::prepare(Surface* image, const RenderMesh* mesh, RenderDat } -RenderData GlRenderer::prepare(TVG_UNUSED const Array& scene, TVG_UNUSED RenderData data, TVG_UNUSED const Matrix* transform, TVG_UNUSED Array& clips, TVG_UNUSED uint8_t opacity, TVG_UNUSED RenderUpdateFlag flags) +RenderData GlRenderer::prepare(TVG_UNUSED const Array& scene, TVG_UNUSED RenderData data, TVG_UNUSED const Matrix& transform, TVG_UNUSED Array& clips, TVG_UNUSED uint8_t opacity, TVG_UNUSED RenderUpdateFlag flags) { //TODO: return nullptr; } -RenderData GlRenderer::prepare(const RenderShape& rshape, RenderData data, const Matrix* transform, Array& clips, uint8_t opacity, RenderUpdateFlag flags, bool clipper) +RenderData GlRenderer::prepare(const RenderShape& rshape, RenderData data, const Matrix& transform, Array& clips, uint8_t opacity, RenderUpdateFlag flags, bool clipper) { // If prepare for clip, only path is meaningful. if (clipper) flags = RenderUpdateFlag::Path; diff --git a/src/renderer/gl_engine/tvgGlRenderer.h b/src/renderer/gl_engine/tvgGlRenderer.h index de3f27f3..2b6f95db 100644 --- a/src/renderer/gl_engine/tvgGlRenderer.h +++ b/src/renderer/gl_engine/tvgGlRenderer.h @@ -53,9 +53,9 @@ public: RT_None, }; - RenderData prepare(const RenderShape& rshape, RenderData data, const Matrix* transform, Array& clips, uint8_t opacity, RenderUpdateFlag flags, bool clipper) override; - RenderData prepare(const Array& scene, RenderData data, const Matrix* transform, Array& clips, uint8_t opacity, RenderUpdateFlag flags) override; - RenderData prepare(Surface* surface, const RenderMesh* mesh, RenderData data, const Matrix* transform, Array& clips, uint8_t opacity, RenderUpdateFlag flags) override; + RenderData prepare(const RenderShape& rshape, RenderData data, const Matrix& transform, Array& clips, uint8_t opacity, RenderUpdateFlag flags, bool clipper) override; + RenderData prepare(const Array& scene, RenderData data, const Matrix& transform, Array& clips, uint8_t opacity, RenderUpdateFlag flags) override; + RenderData prepare(Surface* surface, const RenderMesh* mesh, RenderData data, const Matrix& transform, Array& clips, uint8_t opacity, RenderUpdateFlag flags) override; bool preRender() override; bool renderShape(RenderData data) override; bool renderImage(RenderData data) override; diff --git a/src/renderer/sw_engine/tvgSwCommon.h b/src/renderer/sw_engine/tvgSwCommon.h index f846ab4e..ea81e92b 100644 --- a/src/renderer/sw_engine/tvgSwCommon.h +++ b/src/renderer/sw_engine/tvgSwCommon.h @@ -493,38 +493,38 @@ SwFixed mathDiff(SwFixed angle1, SwFixed angle2); SwFixed mathLength(const SwPoint& pt); bool mathSmallCubic(const SwPoint* base, SwFixed& angleIn, SwFixed& angleMid, SwFixed& angleOut); SwFixed mathMean(SwFixed angle1, SwFixed angle2); -SwPoint mathTransform(const Point* to, const Matrix* transform); +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); 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 SwBBox& clipRegion, SwBBox& 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); +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); 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); -bool shapeGenStrokeFillColors(SwShape* shape, const Fill* fill, const Matrix* transform, SwSurface* surface, uint8_t opacity, bool ctable); +bool shapeGenFillColors(SwShape* shape, const Fill* fill, const Matrix& transform, SwSurface* surface, uint8_t opacity, bool ctable); +bool shapeGenStrokeFillColors(SwShape* shape, const Fill* fill, const Matrix& transform, SwSurface* surface, uint8_t opacity, bool ctable); void shapeResetFill(SwShape* shape); void shapeResetStrokeFill(SwShape* shape); void shapeDelFill(SwShape* shape); void shapeDelStrokeFill(SwShape* shape); -void strokeReset(SwStroke* stroke, const RenderShape* shape, const Matrix* transform); +void strokeReset(SwStroke* stroke, const RenderShape* shape, const Matrix& transform); bool strokeParseOutline(SwStroke* stroke, const SwOutline& outline); SwOutline* strokeExportOutline(SwStroke* stroke, SwMpool* mpool, unsigned tid); void strokeFree(SwStroke* stroke); -bool imagePrepare(SwImage* image, const RenderMesh* mesh, const Matrix* transform, const SwBBox& clipRegion, SwBBox& renderRegion, SwMpool* mpool, unsigned tid); +bool imagePrepare(SwImage* image, const RenderMesh* mesh, const Matrix& transform, const SwBBox& clipRegion, SwBBox& renderRegion, SwMpool* mpool, unsigned tid); bool imageGenRle(SwImage* image, const SwBBox& renderRegion, bool antiAlias); void imageDelOutline(SwImage* image, SwMpool* mpool, uint32_t tid); void imageReset(SwImage* image); void imageFree(SwImage* image); -bool fillGenColorTable(SwFill* fill, const Fill* fdata, const Matrix* transform, SwSurface* surface, uint8_t opacity, bool ctable); +bool fillGenColorTable(SwFill* fill, const Fill* fdata, const Matrix& transform, SwSurface* surface, uint8_t opacity, bool ctable); void fillReset(SwFill* fill); void fillFree(SwFill* fill); @@ -562,7 +562,7 @@ void mpoolRetDashOutline(SwMpool* mpool, unsigned idx); bool rasterCompositor(SwSurface* surface); bool rasterGradientShape(SwSurface* surface, SwShape* shape, Type type); bool rasterShape(SwSurface* surface, SwShape* shape, uint8_t r, uint8_t g, uint8_t b, uint8_t a); -bool rasterImage(SwSurface* surface, SwImage* image, const RenderMesh* mesh, const Matrix* transform, const SwBBox& bbox, uint8_t opacity); +bool rasterImage(SwSurface* surface, SwImage* image, const RenderMesh* mesh, const Matrix& transform, const SwBBox& bbox, uint8_t opacity); bool rasterStroke(SwSurface* surface, SwShape* shape, uint8_t r, uint8_t g, uint8_t b, uint8_t a); bool rasterGradientStroke(SwSurface* surface, SwShape* shape, Type type); bool rasterClear(SwSurface* surface, uint32_t x, uint32_t y, uint32_t w, uint32_t h); diff --git a/src/renderer/sw_engine/tvgSwFill.cpp b/src/renderer/sw_engine/tvgSwFill.cpp index 2388247b..14d26e45 100644 --- a/src/renderer/sw_engine/tvgSwFill.cpp +++ b/src/renderer/sw_engine/tvgSwFill.cpp @@ -205,7 +205,7 @@ static bool _updateColorTable(SwFill* fill, const Fill* fdata, const SwSurface* } -bool _prepareLinear(SwFill* fill, const LinearGradient* linear, const Matrix* transform) +bool _prepareLinear(SwFill* fill, const LinearGradient* linear, const Matrix& transform) { float x1, x2, y1, y2; if (linear->linear(&x1, &y1, &x2, &y2) != Result::Success) return false; @@ -224,9 +224,9 @@ bool _prepareLinear(SwFill* fill, const LinearGradient* linear, const Matrix* tr bool isTransformation = !identity((const Matrix*)(&gradTransform)); if (isTransformation) { - if (transform) gradTransform = *transform * gradTransform; - } else if (transform) { - gradTransform = *transform; + gradTransform = transform * gradTransform; + } else { + gradTransform = transform; isTransformation = true; } @@ -245,7 +245,7 @@ bool _prepareLinear(SwFill* fill, const LinearGradient* linear, const Matrix* tr } -bool _prepareRadial(SwFill* fill, const RadialGradient* radial, const Matrix* transform) +bool _prepareRadial(SwFill* fill, const RadialGradient* radial, const Matrix& transform) { auto cx = P(radial)->cx; auto cy = P(radial)->cy; @@ -287,12 +287,10 @@ bool _prepareRadial(SwFill* fill, const RadialGradient* radial, const Matrix* tr auto gradTransform = radial->transform(); bool isTransformation = !identity((const Matrix*)(&gradTransform)); - if (transform) { - if (isTransformation) gradTransform = *transform * gradTransform; - else { - gradTransform = *transform; - isTransformation = true; - } + if (isTransformation) gradTransform = transform * gradTransform; + else { + gradTransform = transform; + isTransformation = true; } if (isTransformation) { @@ -814,7 +812,7 @@ void fillLinear(const SwFill* fill, uint32_t* dst, uint32_t y, uint32_t x, uint3 } -bool fillGenColorTable(SwFill* fill, const Fill* fdata, const Matrix* transform, SwSurface* surface, uint8_t opacity, bool ctable) +bool fillGenColorTable(SwFill* fill, const Fill* fdata, const Matrix& transform, SwSurface* surface, uint8_t opacity, bool ctable) { if (!fill) return false; diff --git a/src/renderer/sw_engine/tvgSwImage.cpp b/src/renderer/sw_engine/tvgSwImage.cpp index f351e232..488f3ff3 100644 --- a/src/renderer/sw_engine/tvgSwImage.cpp +++ b/src/renderer/sw_engine/tvgSwImage.cpp @@ -27,14 +27,14 @@ /* Internal Class Implementation */ /************************************************************************/ -static inline bool _onlyShifted(const Matrix* m) +static inline bool _onlyShifted(const Matrix& m) { - if (tvg::equal(m->e11, 1.0f) && tvg::equal(m->e22, 1.0f) && tvg::zero(m->e12) && tvg::zero(m->e21)) return true; + if (tvg::equal(m.e11, 1.0f) && tvg::equal(m.e22, 1.0f) && tvg::zero(m.e12) && tvg::zero(m.e21)) return true; return false; } -static bool _genOutline(SwImage* image, const RenderMesh* mesh, const Matrix* transform, SwMpool* mpool, unsigned tid) +static bool _genOutline(SwImage* image, const RenderMesh* mesh, const Matrix& transform, SwMpool* mpool, unsigned tid) { image->outline = mpoolReqOutline(mpool, tid); auto outline = image->outline; @@ -108,21 +108,21 @@ static bool _genOutline(SwImage* image, const RenderMesh* mesh, const Matrix* tr /* External Class Implementation */ /************************************************************************/ -bool imagePrepare(SwImage* image, const RenderMesh* mesh, const Matrix* transform, const SwBBox& clipRegion, SwBBox& renderRegion, SwMpool* mpool, unsigned tid) +bool imagePrepare(SwImage* image, const RenderMesh* mesh, const Matrix& transform, const SwBBox& clipRegion, SwBBox& renderRegion, SwMpool* mpool, unsigned tid) { image->direct = _onlyShifted(transform); //Fast track: Non-transformed image but just shifted. if (image->direct) { - image->ox = -static_cast(nearbyint(transform->e13)); - image->oy = -static_cast(nearbyint(transform->e23)); + image->ox = -static_cast(nearbyint(transform.e13)); + image->oy = -static_cast(nearbyint(transform.e23)); //Figure out the scale factor by transform matrix } else { - auto scaleX = sqrtf((transform->e11 * transform->e11) + (transform->e21 * transform->e21)); - auto scaleY = sqrtf((transform->e22 * transform->e22) + (transform->e12 * transform->e12)); + auto scaleX = sqrtf((transform.e11 * transform.e11) + (transform.e21 * transform.e21)); + auto scaleY = sqrtf((transform.e22 * transform.e22) + (transform.e12 * transform.e12)); image->scale = (fabsf(scaleX - scaleY) > 0.01f) ? 1.0f : scaleX; - if (tvg::zero(transform->e12) && tvg::zero(transform->e21)) image->scaled = true; + if (tvg::zero(transform.e12) && tvg::zero(transform.e21)) image->scaled = true; else image->scaled = false; } diff --git a/src/renderer/sw_engine/tvgSwMath.cpp b/src/renderer/sw_engine/tvgSwMath.cpp index 58da05d9..1093edd6 100644 --- a/src/renderer/sw_engine/tvgSwMath.cpp +++ b/src/renderer/sw_engine/tvgSwMath.cpp @@ -254,12 +254,10 @@ SwFixed mathDiff(SwFixed angle1, SwFixed angle2) } -SwPoint mathTransform(const Point* to, const Matrix* transform) +SwPoint mathTransform(const Point* to, const Matrix& transform) { - if (!transform) return {TO_SWCOORD(to->x), TO_SWCOORD(to->y)}; - - auto tx = to->x * transform->e11 + to->y * transform->e12 + transform->e13; - auto ty = to->x * transform->e21 + to->y * transform->e22 + transform->e23; + auto tx = to->x * transform.e11 + to->y * transform.e12 + transform.e13; + auto ty = to->x * transform.e21 + to->y * transform.e22 + transform.e23; return {TO_SWCOORD(tx), TO_SWCOORD(ty)}; } diff --git a/src/renderer/sw_engine/tvgSwRaster.cpp b/src/renderer/sw_engine/tvgSwRaster.cpp index 1665d367..674deb35 100644 --- a/src/renderer/sw_engine/tvgSwRaster.cpp +++ b/src/renderer/sw_engine/tvgSwRaster.cpp @@ -832,7 +832,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 SwBBox& region, uint8_t opacity) { if (surface->channelSize == sizeof(uint8_t)) { TVGERR("SW_ENGINE", "Not supported scaled rle image!"); @@ -841,9 +841,7 @@ static bool _scaledRleImage(SwSurface* surface, const SwImage* image, const Matr Matrix itransform; - if (transform) { - if (!inverse(transform, &itransform)) return true; - } else identity(&itransform); + if (!inverse(&transform, &itransform)) return true; if (_compositing(surface)) { if (_matting(surface)) return _rasterScaledMattedRleImage(surface, image, &itransform, region, opacity); @@ -1197,13 +1195,11 @@ 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 SwBBox& region, uint8_t opacity) { Matrix itransform; - if (transform) { - if (!inverse(transform, &itransform)) return true; - } else identity(&itransform); + if (!inverse(&transform, &itransform)) return true; if (_compositing(surface)) { if (_matting(surface)) return _rasterScaledMattedImage(surface, image, &itransform, region, opacity); @@ -1449,7 +1445,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 SwBBox& region, uint8_t opacity) { //RLE Image if (image->rle) { @@ -1966,7 +1962,7 @@ bool rasterStroke(SwSurface* surface, SwShape* shape, uint8_t r, uint8_t g, uint } -bool rasterImage(SwSurface* surface, SwImage* image, const RenderMesh* mesh, const Matrix* transform, const SwBBox& bbox, uint8_t opacity) +bool rasterImage(SwSurface* surface, SwImage* image, const RenderMesh* mesh, const Matrix& transform, const SwBBox& 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; diff --git a/src/renderer/sw_engine/tvgSwRasterTexmap.h b/src/renderer/sw_engine/tvgSwRasterTexmap.h index 41f1698b..c1241534 100644 --- a/src/renderer/sw_engine/tvgSwRasterTexmap.h +++ b/src/renderer/sw_engine/tvgSwRasterTexmap.h @@ -1084,7 +1084,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 SwBBox* region, uint8_t opacity) { if (surface->channelSize == sizeof(uint8_t)) { TVGERR("SW_ENGINE", "Not supported grayscale Textmap polygon!"); @@ -1104,7 +1104,7 @@ static bool _rasterTexmapPolygon(SwSurface* surface, const SwImage* image, const float ys = FLT_MAX, ye = -1.0f; for (int i = 0; i < 4; i++) { - if (transform) vertices[i].pt *= *transform; + vertices[i].pt *= transform; if (vertices[i].pt.y < ys) ys = vertices[i].pt.y; if (vertices[i].pt.y > ye) ye = vertices[i].pt.y; } @@ -1150,7 +1150,7 @@ static bool _rasterTexmapPolygon(SwSurface* surface, const SwImage* image, const Should provide two Polygons, one for each triangle. // TODO: region? */ -static bool _rasterTexmapPolygonMesh(SwSurface* surface, const SwImage* image, const RenderMesh* mesh, const Matrix* transform, const SwBBox* region, uint8_t opacity) +static bool _rasterTexmapPolygonMesh(SwSurface* surface, const SwImage* image, const RenderMesh* mesh, const Matrix& transform, const SwBBox* region, uint8_t opacity) { if (surface->channelSize == sizeof(uint8_t)) { TVGERR("SW_ENGINE", "Not supported grayscale Textmap polygon mesh!"); @@ -1165,9 +1165,9 @@ static bool _rasterTexmapPolygonMesh(SwSurface* surface, const SwImage* image, c float ys = FLT_MAX, ye = -1.0f; for (uint32_t i = 0; i < mesh->triangleCnt; i++) { transformedTris[i] = mesh->triangles[i]; - transformedTris[i].vertex[0].pt *= *transform; - transformedTris[i].vertex[1].pt *= *transform; - transformedTris[i].vertex[2].pt *= *transform; + transformedTris[i].vertex[0].pt *= transform; + transformedTris[i].vertex[1].pt *= transform; + transformedTris[i].vertex[2].pt *= transform; if (transformedTris[i].vertex[0].pt.y < ys) ys = transformedTris[i].vertex[0].pt.y; else if (transformedTris[i].vertex[0].pt.y > ye) ye = transformedTris[i].vertex[0].pt.y; diff --git a/src/renderer/sw_engine/tvgSwRenderer.cpp b/src/renderer/sw_engine/tvgSwRenderer.cpp index a0614cf4..5f9c8365 100644 --- a/src/renderer/sw_engine/tvgSwRenderer.cpp +++ b/src/renderer/sw_engine/tvgSwRenderer.cpp @@ -39,7 +39,7 @@ struct SwTask : Task SwSurface* surface = nullptr; SwMpool* mpool = nullptr; SwBBox bbox = {{0, 0}, {0, 0}}; //Whole Rendering Region - Matrix* transform = nullptr; + Matrix transform; Array clips; RenderUpdateFlag flags = RenderUpdateFlag::None; uint8_t opacity; @@ -68,10 +68,7 @@ struct SwTask : Task virtual bool clip(SwRle* target) = 0; virtual SwRle* rle() = 0; - virtual ~SwTask() - { - free(transform); - } + virtual ~SwTask() {} }; @@ -100,8 +97,7 @@ struct SwShapeTask : SwTask if (!rshape->stroke->fill && (MULTIPLY(rshape->stroke->color[3], opacity) == 0)) return 0.0f; if (tvg::zero(rshape->stroke->trim.begin - rshape->stroke->trim.end)) return 0.0f; - if (transform) return (width * sqrt(transform->e11 * transform->e11 + transform->e12 * transform->e12)); - else return width; + return (width * sqrt(transform.e11 * transform.e11 + transform.e12 * transform.e12)); } @@ -688,7 +684,8 @@ bool SwRenderer::endComposite(Compositor* cmp) //Default is alpha blending if (p->method == CompositeMethod::None) { - return rasterImage(surface, &p->image, nullptr, nullptr, p->bbox, p->opacity); + Matrix m = {1, 0, 0, 0, 1, 0, 0, 0, 1}; + return rasterImage(surface, &p->image, nullptr, m, p->bbox, p->opacity); } return true; @@ -714,7 +711,7 @@ void SwRenderer::dispose(RenderData data) } -void* SwRenderer::prepareCommon(SwTask* task, const Matrix* transform, const Array& clips, uint8_t opacity, RenderUpdateFlag flags) +void* SwRenderer::prepareCommon(SwTask* task, const Matrix& transform, const Array& clips, uint8_t opacity, RenderUpdateFlag flags) { if (!surface) return task; if (flags == RenderUpdateFlag::None) return task; @@ -727,20 +724,11 @@ void* SwRenderer::prepareCommon(SwTask* task, const Matrix* transform, const Arr } task->clips = clips; - - if (transform) { - if (!task->transform) task->transform = static_cast(malloc(sizeof(Matrix))); - *task->transform = *transform; - } else { - if (task->transform) free(task->transform); - task->transform = nullptr; - } - + task->transform = transform; + //zero size? - if (task->transform) { - if (task->transform->e11 == 0.0f && task->transform->e12 == 0.0f) return task; //zero width - if (task->transform->e21 == 0.0f && task->transform->e22 == 0.0f) return task; //zero height - } + if (task->transform.e11 == 0.0f && task->transform.e12 == 0.0f) return task; //zero width + if (task->transform.e21 == 0.0f && task->transform.e22 == 0.0f) return task; //zero height task->opacity = opacity; task->surface = surface; @@ -762,7 +750,7 @@ void* SwRenderer::prepareCommon(SwTask* task, const Matrix* transform, const Arr } -RenderData SwRenderer::prepare(Surface* surface, const RenderMesh* mesh, RenderData data, const Matrix* transform, Array& clips, uint8_t opacity, RenderUpdateFlag flags) +RenderData SwRenderer::prepare(Surface* surface, const RenderMesh* mesh, RenderData data, const Matrix& transform, Array& clips, uint8_t opacity, RenderUpdateFlag flags) { //prepare task auto task = static_cast(data); @@ -776,7 +764,7 @@ RenderData SwRenderer::prepare(Surface* surface, const RenderMesh* mesh, RenderD } -RenderData SwRenderer::prepare(const Array& scene, RenderData data, const Matrix* transform, Array& clips, uint8_t opacity, RenderUpdateFlag flags) +RenderData SwRenderer::prepare(const Array& scene, RenderData data, const Matrix& transform, Array& clips, uint8_t opacity, RenderUpdateFlag flags) { //prepare task auto task = static_cast(data); @@ -796,7 +784,7 @@ RenderData SwRenderer::prepare(const Array& scene, RenderData data, } -RenderData SwRenderer::prepare(const RenderShape& rshape, RenderData data, const Matrix* transform, Array& clips, uint8_t opacity, RenderUpdateFlag flags, bool clipper) +RenderData SwRenderer::prepare(const RenderShape& rshape, RenderData data, const Matrix& transform, Array& clips, uint8_t opacity, RenderUpdateFlag flags, bool clipper) { //prepare task auto task = static_cast(data); diff --git a/src/renderer/sw_engine/tvgSwRenderer.h b/src/renderer/sw_engine/tvgSwRenderer.h index d101527d..2ee46208 100644 --- a/src/renderer/sw_engine/tvgSwRenderer.h +++ b/src/renderer/sw_engine/tvgSwRenderer.h @@ -36,9 +36,9 @@ namespace tvg class SwRenderer : public RenderMethod { public: - RenderData prepare(const RenderShape& rshape, RenderData data, const Matrix* transform, Array& clips, uint8_t opacity, RenderUpdateFlag flags, bool clipper) override; - RenderData prepare(const Array& scene, RenderData data, const Matrix* transform, Array& clips, uint8_t opacity, RenderUpdateFlag flags) override; - RenderData prepare(Surface* surface, const RenderMesh* mesh, RenderData data, const Matrix* transform, Array& clips, uint8_t opacity, RenderUpdateFlag flags) override; + RenderData prepare(const RenderShape& rshape, RenderData data, const Matrix& transform, Array& clips, uint8_t opacity, RenderUpdateFlag flags, bool clipper) override; + RenderData prepare(const Array& scene, RenderData data, const Matrix& transform, Array& clips, uint8_t opacity, RenderUpdateFlag flags) override; + RenderData prepare(Surface* surface, const RenderMesh* mesh, RenderData data, const Matrix& transform, Array& clips, uint8_t opacity, RenderUpdateFlag flags) override; bool preRender() override; bool renderShape(RenderData data) override; bool renderImage(RenderData data) override; @@ -77,7 +77,7 @@ private: SwRenderer(); ~SwRenderer(); - RenderData prepareCommon(SwTask* task, const Matrix* transform, const Array& clips, uint8_t opacity, RenderUpdateFlag flags); + RenderData prepareCommon(SwTask* task, const Matrix& transform, const Array& clips, uint8_t opacity, RenderUpdateFlag flags); }; } diff --git a/src/renderer/sw_engine/tvgSwShape.cpp b/src/renderer/sw_engine/tvgSwShape.cpp index 317504bc..535258bc 100644 --- a/src/renderer/sw_engine/tvgSwShape.cpp +++ b/src/renderer/sw_engine/tvgSwShape.cpp @@ -48,7 +48,7 @@ static bool _outlineEnd(SwOutline& outline) } -static bool _outlineMoveTo(SwOutline& outline, const Point* to, const Matrix* transform, bool closed = false) +static bool _outlineMoveTo(SwOutline& outline, const Point* to, const Matrix& transform, bool closed = false) { //make it a contour, if the last contour is not closed yet. if (!closed) _outlineEnd(outline); @@ -59,14 +59,14 @@ static bool _outlineMoveTo(SwOutline& outline, const Point* to, const Matrix* tr } -static void _outlineLineTo(SwOutline& outline, const Point* to, const Matrix* transform) +static void _outlineLineTo(SwOutline& outline, const Point* to, const Matrix& transform) { outline.pts.push(mathTransform(to, transform)); outline.types.push(SW_CURVE_TYPE_POINT); } -static void _outlineCubicTo(SwOutline& outline, const Point* ctrl1, const Point* ctrl2, const Point* to, const Matrix* transform) +static void _outlineCubicTo(SwOutline& outline, const Point* ctrl1, const Point* ctrl2, const Point* to, const Matrix& transform) { outline.pts.push(mathTransform(ctrl1, transform)); outline.types.push(SW_CURVE_TYPE_CUBIC); @@ -98,7 +98,7 @@ static bool _outlineClose(SwOutline& outline) } -static void _dashLineTo(SwDashStroke& dash, const Point* to, const Matrix* transform) +static void _dashLineTo(SwDashStroke& dash, const Point* to, const Matrix& transform) { Line cur = {dash.ptCur, *to}; auto len = cur.length(); @@ -159,7 +159,7 @@ static void _dashLineTo(SwDashStroke& dash, const Point* to, const Matrix* trans } -static void _dashCubicTo(SwDashStroke& dash, const Point* ctrl1, const Point* ctrl2, const Point* to, const Matrix* transform) +static void _dashCubicTo(SwDashStroke& dash, const Point* ctrl1, const Point* ctrl2, const Point* to, const Matrix& transform) { Bezier cur = {dash.ptCur, *ctrl1, *ctrl2, *to}; auto len = cur.length(); @@ -220,7 +220,7 @@ static void _dashCubicTo(SwDashStroke& dash, const Point* ctrl1, const Point* ct } -static void _dashClose(SwDashStroke& dash, const Matrix* transform) +static void _dashClose(SwDashStroke& dash, const Matrix& transform) { _dashLineTo(dash, &dash.ptStart, transform); } @@ -323,7 +323,7 @@ static float _outlineLength(const RenderShape* rshape, uint32_t shiftPts, uint32 } -static SwOutline* _genDashOutline(const RenderShape* rshape, const Matrix* transform, bool trimmed, SwMpool* mpool, unsigned tid) +static SwOutline* _genDashOutline(const RenderShape* rshape, const Matrix& transform, bool trimmed, SwMpool* mpool, unsigned tid) { const PathCommand* cmds = rshape->path.cmds.data; auto cmdCnt = rshape->path.cmds.count; @@ -435,7 +435,7 @@ static bool _axisAlignedRect(const SwOutline* outline) } -static bool _genOutline(SwShape* shape, const RenderShape* rshape, const Matrix* transform, SwMpool* mpool, unsigned tid, bool hasComposite) +static bool _genOutline(SwShape* shape, const RenderShape* rshape, const Matrix& transform, SwMpool* mpool, unsigned tid, bool hasComposite) { const PathCommand* cmds = rshape->path.cmds.data; auto cmdCnt = rshape->path.cmds.count; @@ -491,7 +491,7 @@ static bool _genOutline(SwShape* shape, const RenderShape* rshape, const Matrix* /* 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 SwBBox& clipRegion, SwBBox& renderRegion, SwMpool* mpool, unsigned tid, bool hasComposite) { if (!_genOutline(shape, rshape, transform, mpool, tid, hasComposite)) return false; if (!mathUpdateOutlineBBox(shape->outline, clipRegion, renderRegion, shape->fastTrack)) return false; @@ -574,7 +574,7 @@ void shapeDelStroke(SwShape* shape) } -void shapeResetStroke(SwShape* shape, const RenderShape* rshape, const Matrix* transform) +void shapeResetStroke(SwShape* shape, const RenderShape* rshape, const Matrix& transform) { if (!shape->stroke) shape->stroke = static_cast(calloc(1, sizeof(SwStroke))); auto stroke = shape->stroke; @@ -585,7 +585,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 SwBBox& clipRegion, SwBBox& renderRegion, SwMpool* mpool, unsigned tid) { SwOutline* shapeOutline = nullptr; SwOutline* strokeOutline = nullptr; @@ -628,13 +628,13 @@ clear: } -bool shapeGenFillColors(SwShape* shape, const Fill* fill, const Matrix* transform, SwSurface* surface, uint8_t opacity, bool ctable) +bool shapeGenFillColors(SwShape* shape, const Fill* fill, const Matrix& transform, SwSurface* surface, uint8_t opacity, bool ctable) { return fillGenColorTable(shape->fill, fill, transform, surface, opacity, ctable); } -bool shapeGenStrokeFillColors(SwShape* shape, const Fill* fill, const Matrix* transform, SwSurface* surface, uint8_t opacity, bool ctable) +bool shapeGenStrokeFillColors(SwShape* shape, const Fill* fill, const Matrix& transform, SwSurface* surface, uint8_t opacity, bool ctable) { return fillGenColorTable(shape->stroke->fill, fill, transform, surface, opacity, ctable); } diff --git a/src/renderer/sw_engine/tvgSwStroke.cpp b/src/renderer/sw_engine/tvgSwStroke.cpp index 441606a8..575d1295 100644 --- a/src/renderer/sw_engine/tvgSwStroke.cpp +++ b/src/renderer/sw_engine/tvgSwStroke.cpp @@ -805,15 +805,10 @@ void strokeFree(SwStroke* stroke) } -void strokeReset(SwStroke* stroke, const RenderShape* rshape, const Matrix* transform) +void strokeReset(SwStroke* stroke, const RenderShape* rshape, const Matrix& transform) { - if (transform) { - stroke->sx = sqrtf(powf(transform->e11, 2.0f) + powf(transform->e21, 2.0f)); - stroke->sy = sqrtf(powf(transform->e12, 2.0f) + powf(transform->e22, 2.0f)); - } else { - stroke->sx = stroke->sy = 1.0f; - } - + stroke->sx = sqrtf(powf(transform.e11, 2.0f) + powf(transform.e21, 2.0f)); + stroke->sy = sqrtf(powf(transform.e12, 2.0f) + powf(transform.e22, 2.0f)); stroke->width = HALF_STROKE(rshape->strokeWidth()); stroke->cap = rshape->strokeCap(); stroke->miterlimit = static_cast(rshape->strokeMiterlimit() * 65536.0f); diff --git a/src/renderer/tvgCanvas.h b/src/renderer/tvgCanvas.h index a3dfb160..c5d2127f 100644 --- a/src/renderer/tvgCanvas.h +++ b/src/renderer/tvgCanvas.h @@ -93,11 +93,13 @@ struct Canvas::Impl auto flag = RenderUpdateFlag::None; if (status == Status::Damaged || force) flag = RenderUpdateFlag::All; + auto m = Matrix{1, 0, 0, 0, 1, 0, 0, 0, 1}; + if (paint) { - paint->pImpl->update(renderer, nullptr, clips, 255, flag); + paint->pImpl->update(renderer, m, clips, 255, flag); } else { for (auto paint : paints) { - paint->pImpl->update(renderer, nullptr, clips, 255, flag); + paint->pImpl->update(renderer, m, clips, 255, flag); } } status = Status::Updating; diff --git a/src/renderer/tvgPaint.cpp b/src/renderer/tvgPaint.cpp index 5b81b075..d8cc230b 100644 --- a/src/renderer/tvgPaint.cpp +++ b/src/renderer/tvgPaint.cpp @@ -41,7 +41,7 @@ } -static Result _clipRect(RenderMethod* renderer, const Point* pts, const Matrix* pm, const Matrix* rm, RenderRegion& before) +static Result _clipRect(RenderMethod* renderer, const Point* pts, const Matrix& pm, const Matrix& rm, RenderRegion& before) { //sorting Point tmp[4]; @@ -50,8 +50,8 @@ static Result _clipRect(RenderMethod* renderer, const Point* pts, const Matrix* for (int i = 0; i < 4; ++i) { tmp[i] = pts[i]; - if (rm) tmp[i] *= *rm; - if (pm) tmp[i] *= *pm; + tmp[i] *= rm; + tmp[i] *= pm; if (tmp[i].x < min.x) min.x = tmp[i].x; if (tmp[i].x > max.x) max.x = tmp[i].x; if (tmp[i].y < min.y) min.y = tmp[i].y; @@ -73,7 +73,7 @@ static Result _clipRect(RenderMethod* renderer, const Point* pts, const Matrix* } -static Result _compFastTrack(RenderMethod* renderer, Paint* cmpTarget, const Matrix* pm, RenderRegion& before) +static Result _compFastTrack(RenderMethod* renderer, Paint* cmpTarget, const Matrix& pm, RenderRegion& before) { /* Access Shape class by Paint is bad... but it's ok still it's an internal usage. */ auto shape = static_cast(cmpTarget); @@ -86,18 +86,13 @@ static Result _compFastTrack(RenderMethod* renderer, Paint* cmpTarget, const Mat if (ptsCnt == 0) return Result::InvalidArguments; if (ptsCnt != 4) return Result::InsufficientCondition; - Matrix* rm = nullptr; - - if (P(cmpTarget)->rTransform && (P(cmpTarget)->renderFlag & RenderUpdateFlag::Transform)) { - P(cmpTarget)->rTransform->update(); - rm = &P(cmpTarget)->rTransform->m; - } + auto& rm = P(cmpTarget)->transform(); //No rotation and no skewing, still can try out clipping the rect region. auto tryClip = false; - if (pm && (!rightAngle(pm) || skewed(pm))) tryClip = true; - if (rm && (!rightAngle(rm) || skewed(rm))) tryClip = true; + if ((!rightAngle(pm) || skewed(pm))) tryClip = true; + if ((!rightAngle(rm) || skewed(rm))) tryClip = true; if (tryClip) return _clipRect(renderer, pts, pm, rm, before); @@ -114,16 +109,10 @@ static Result _compFastTrack(RenderMethod* renderer, Paint* cmpTarget, const Mat auto v1 = *pt1; auto v2 = *pt3; - - if (rm) { - v1 *= *rm; - v2 *= *rm; - } - - if (pm) { - v1 *= *pm; - v2 *= *pm; - } + v1 *= rm; + v2 *= rm; + v1 *= pm; + v2 *= pm; //sorting if (v1.x > v2.x) std::swap(v1.x, v2.x); @@ -169,16 +158,8 @@ Paint* Paint::Impl::duplicate(Paint* ret) PAINT_METHOD(ret, duplicate(ret)); //duplicate Transform - if (rTransform) { - if (!ret->pImpl->rTransform) { - ret->pImpl->rTransform = new RenderTransform(); - } - *ret->pImpl->rTransform = *rTransform; - ret->pImpl->renderFlag |= RenderUpdateFlag::Transform; - } else { - delete(ret->pImpl->rTransform); - ret->pImpl->rTransform = nullptr; - } + ret->pImpl->tr = tr; + ret->pImpl->renderFlag |= RenderUpdateFlag::Transform; ret->pImpl->opacity = opacity; @@ -190,14 +171,9 @@ Paint* Paint::Impl::duplicate(Paint* ret) bool Paint::Impl::rotate(float degree) { - if (rTransform) { - if (rTransform->overriding) return false; - if (tvg::equal(degree, rTransform->degree)) return true; - } else { - if (tvg::zero(degree)) return true; - rTransform = new RenderTransform(); - } - rTransform->degree = degree; + if (tr.overriding) return false; + if (tvg::equal(degree, tr.degree)) return true; + tr.degree = degree; renderFlag |= RenderUpdateFlag::Transform; return true; @@ -206,14 +182,9 @@ bool Paint::Impl::rotate(float degree) bool Paint::Impl::scale(float factor) { - if (rTransform) { - if (rTransform->overriding) return false; - if (tvg::equal(factor, rTransform->scale)) return true; - } else { - if (tvg::equal(factor, 1.0f)) return true; - rTransform = new RenderTransform(); - } - rTransform->scale = factor; + if (tr.overriding) return false; + if (tvg::equal(factor, tr.scale)) return true; + tr.scale = factor; renderFlag |= RenderUpdateFlag::Transform; return true; @@ -222,15 +193,10 @@ bool Paint::Impl::scale(float factor) bool Paint::Impl::translate(float x, float y) { - if (rTransform) { - if (rTransform->overriding) return false; - if (tvg::equal(x, rTransform->m.e13) && tvg::equal(y, rTransform->m.e23)) return true; - } else { - if (tvg::zero(x) && tvg::zero(y)) return true; - rTransform = new RenderTransform(); - } - rTransform->m.e13 = x; - rTransform->m.e23 = y; + if (tr.overriding) return false; + if (tvg::equal(x, tr.m.e13) && tvg::equal(y, tr.m.e23)) return true; + tr.m.e13 = x; + tr.m.e23 = y; renderFlag |= RenderUpdateFlag::Transform; return true; @@ -270,7 +236,7 @@ bool Paint::Impl::render(RenderMethod* renderer) } -RenderData Paint::Impl::update(RenderMethod* renderer, const Matrix* pm, Array& clips, uint8_t opacity, RenderUpdateFlag pFlag, bool clipper) +RenderData Paint::Impl::update(RenderMethod* renderer, const Matrix& pm, Array& clips, uint8_t opacity, RenderUpdateFlag pFlag, bool clipper) { if (this->renderer != renderer) { if (this->renderer) TVGERR("RENDERER", "paint's renderer has been changed!"); @@ -278,7 +244,7 @@ RenderData Paint::Impl::update(RenderMethod* renderer, const Matrix* pm, Arrayrenderer = renderer; } - if (renderFlag & RenderUpdateFlag::Transform) rTransform->update(); + if (renderFlag & RenderUpdateFlag::Transform) tr.update(); /* 1. Composition Pre Processing */ RenderData trd = nullptr; //composite target render data @@ -326,8 +292,8 @@ RenderData Paint::Impl::update(RenderMethod* renderer, const Matrix* pm, Arrayopacity); RenderData rd = nullptr; - Matrix om = multiply(pm, rTransform ? &rTransform->m : nullptr); - PAINT_METHOD(rd, update(renderer, &om, clips, opacity, newFlag, clipper)); + auto m = pm * tr.m; + PAINT_METHOD(rd, update(renderer, m, clips, opacity, newFlag, clipper)); /* 3. Composition Post Processing */ if (compFastTrack == Result::Success) renderer->viewport(viewport); @@ -339,11 +305,11 @@ RenderData Paint::Impl::update(RenderMethod* renderer, const Matrix* pm, Arraytransform(); //Case: No transformed, quick return! - if (!transformed || !(m = this->transform())) { + if (!transformed || identity(&m)) { PAINT_METHOD(ret, bounds(x, y, w, h, stroking)); return ret; } @@ -367,7 +333,7 @@ bool Paint::Impl::bounds(float* x, float* y, float* w, float* h, bool transforme //Compute the AABB after transformation for (int i = 0; i < 4; i++) { - pt[i] *= *m; + pt[i] *= m; if (pt[i].x < x1) x1 = pt[i].x; if (pt[i].x > x2) x2 = pt[i].x; @@ -429,9 +395,7 @@ Result Paint::transform(const Matrix& m) noexcept Matrix Paint::transform() noexcept { - auto pTransform = pImpl->transform(); - if (pTransform) return *pTransform; - return {1, 0, 0, 0, 1, 0, 0, 0, 1}; + return pImpl->transform(); } diff --git a/src/renderer/tvgPaint.h b/src/renderer/tvgPaint.h index 46139ee5..0d0882f4 100644 --- a/src/renderer/tvgPaint.h +++ b/src/renderer/tvgPaint.h @@ -48,16 +48,38 @@ namespace tvg struct Paint::Impl { Paint* paint = nullptr; - RenderTransform* rTransform = nullptr; Composite* compData = nullptr; RenderMethod* renderer = nullptr; BlendMethod blendMethod = BlendMethod::Normal; //uint8_t + struct { + Matrix m; + float degree = 0.0f; //rotation degree + float scale = 1.0f; //scale factor + bool overriding = false; //user transform? + + void update() + { + if (overriding) return; + m.e11 = 1.0f; + m.e12 = 0.0f; + m.e21 = 0.0f; + m.e22 = 1.0f; + m.e31 = 0.0f; + m.e32 = 0.0f; + m.e33 = 1.0f; + tvg::scale(&m, scale, scale); + tvg::rotate(&m, degree); + } + } tr; uint8_t renderFlag = RenderUpdateFlag::None; uint8_t ctxFlag = ContextFlag::Invalid; uint8_t opacity = 255; uint8_t refCnt = 0; //reference count - Impl(Paint* pnt) : paint(pnt) {} + Impl(Paint* pnt) : paint(pnt) + { + identity(&tr.m); + } ~Impl() { @@ -65,7 +87,6 @@ namespace tvg if (P(compData->target)->unref() == 0) delete(compData->target); free(compData); } - delete(rTransform); if (renderer && (renderer->unref() == 0)) delete(renderer); } @@ -83,23 +104,18 @@ namespace tvg bool transform(const Matrix& m) { - if (!rTransform) { - if (identity(&m)) return true; - rTransform = new RenderTransform(); - } - rTransform->override(m); + tr.m = m; + tr.overriding = true; renderFlag |= RenderUpdateFlag::Transform; return true; } - Matrix* transform() + Matrix& transform() { - if (rTransform) { - if (renderFlag & RenderUpdateFlag::Transform) rTransform->update(); - return &rTransform->m; - } - return nullptr; + //update transform + if (renderFlag & RenderUpdateFlag::Transform) tr.update(); + return tr.m; } bool composite(Paint* source, Paint* target, CompositeMethod method) @@ -135,7 +151,7 @@ namespace tvg bool scale(float factor); bool translate(float x, float y); bool bounds(float* x, float* y, float* w, float* h, bool transformed, bool stroking); - RenderData update(RenderMethod* renderer, const Matrix* pm, Array& clips, uint8_t opacity, RenderUpdateFlag pFlag, bool clipper = false); + RenderData update(RenderMethod* renderer, const Matrix& pm, Array& clips, uint8_t opacity, RenderUpdateFlag pFlag, bool clipper = false); bool render(RenderMethod* renderer); Paint* duplicate(Paint* ret = nullptr); }; diff --git a/src/renderer/tvgPicture.cpp b/src/renderer/tvgPicture.cpp index 02fedc84..df8ecff1 100644 --- a/src/renderer/tvgPicture.cpp +++ b/src/renderer/tvgPicture.cpp @@ -104,20 +104,6 @@ RenderRegion Picture::Impl::bounds(RenderMethod* renderer) } -Matrix Picture::Impl::resizeTransform(const Matrix* pm) -{ - //Overriding Transformation by the desired image size - auto sx = w / loader->w; - auto sy = h / loader->h; - auto scale = sx < sy ? sx : sy; - - auto tmp = Matrix{scale, 0, 0, 0, scale, 0, 0, 0, 1}; - - if (!pm) return tmp; - return *pm * tmp; -} - - Result Picture::Impl::load(ImageLoader* loader) { //Same resource has been loaded. diff --git a/src/renderer/tvgPicture.h b/src/renderer/tvgPicture.h index bad508a0..092686d8 100644 --- a/src/renderer/tvgPicture.h +++ b/src/renderer/tvgPicture.h @@ -68,7 +68,6 @@ struct Picture::Impl bool resizing = false; bool needComp = false; //need composition - Matrix resizeTransform(const Matrix* m); bool needComposition(uint8_t opacity); bool render(RenderMethod* renderer); bool size(float w, float h); @@ -90,14 +89,20 @@ struct Picture::Impl delete(paint); } - RenderData update(RenderMethod* renderer, const Matrix* transform, Array& clips, uint8_t opacity, RenderUpdateFlag pFlag, bool clipper) + RenderData update(RenderMethod* renderer, const Matrix& transform, Array& clips, uint8_t opacity, RenderUpdateFlag pFlag, bool clipper) { auto flag = static_cast(pFlag | load()); if (surface) { if (flag == RenderUpdateFlag::None) return rd; - auto om = resizeTransform(transform); - rd = renderer->prepare(surface, &rm, rd, &om, clips, opacity, flag); + + //Overriding Transformation by the desired image size + auto sx = w / loader->w; + auto sy = h / loader->h; + auto scale = sx < sy ? sx : sy; + auto m = transform * Matrix{scale, 0, 0, 0, scale, 0, 0, 0, 1}; + + rd = renderer->prepare(surface, &rm, rd, m, clips, opacity, flag); } else if (paint) { if (resizing) { loader->resize(paint, w, h); diff --git a/src/renderer/tvgRender.cpp b/src/renderer/tvgRender.cpp index 5db9399c..0ad85031 100644 --- a/src/renderer/tvgRender.cpp +++ b/src/renderer/tvgRender.cpp @@ -46,32 +46,6 @@ uint32_t RenderMethod::unref() } -void RenderTransform::override(const Matrix& m) -{ - this->m = m; - overriding = true; -} - - -void RenderTransform::update() -{ - if (overriding) return; - - m.e11 = 1.0f; - m.e12 = 0.0f; - - m.e21 = 0.0f; - m.e22 = 1.0f; - - m.e31 = 0.0f; - m.e32 = 0.0f; - m.e33 = 1.0f; - - tvg::scale(&m, scale, scale); - rotate(&m, degree); -} - - void RenderRegion::intersect(const RenderRegion& rhs) { auto x1 = x + w; diff --git a/src/renderer/tvgRender.h b/src/renderer/tvgRender.h index 08192dbf..00cb1211 100644 --- a/src/renderer/tvgRender.h +++ b/src/renderer/tvgRender.h @@ -110,21 +110,6 @@ struct RenderRegion } }; -struct RenderTransform -{ - Matrix m; - float degree = 0.0f; //rotation degree - float scale = 1.0f; //scale factor - bool overriding = false; //user transform? - - void update(); - void override(const Matrix& m); - - RenderTransform() - { - m.e13 = m.e23 = 0.0f; - } -}; struct RenderStroke { @@ -275,9 +260,9 @@ public: uint32_t unref(); virtual ~RenderMethod() {} - virtual RenderData prepare(const RenderShape& rshape, RenderData data, const Matrix* transform, Array& clips, uint8_t opacity, RenderUpdateFlag flags, bool clipper) = 0; - virtual RenderData prepare(const Array& scene, RenderData data, const Matrix* transform, Array& clips, uint8_t opacity, RenderUpdateFlag flags) = 0; - virtual RenderData prepare(Surface* surface, const RenderMesh* mesh, RenderData data, const Matrix* transform, Array& clips, uint8_t opacity, RenderUpdateFlag flags) = 0; + virtual RenderData prepare(const RenderShape& rshape, RenderData data, const Matrix& transform, Array& clips, uint8_t opacity, RenderUpdateFlag flags, bool clipper) = 0; + virtual RenderData prepare(const Array& scene, RenderData data, const Matrix& transform, Array& clips, uint8_t opacity, RenderUpdateFlag flags) = 0; + virtual RenderData prepare(Surface* surface, const RenderMesh* mesh, RenderData data, const Matrix& transform, Array& clips, uint8_t opacity, RenderUpdateFlag flags) = 0; virtual bool preRender() = 0; virtual bool renderShape(RenderData data) = 0; virtual bool renderImage(RenderData data) = 0; diff --git a/src/renderer/tvgScene.h b/src/renderer/tvgScene.h index 69401d82..7965bd5b 100644 --- a/src/renderer/tvgScene.h +++ b/src/renderer/tvgScene.h @@ -101,7 +101,7 @@ struct Scene::Impl return true; } - RenderData update(RenderMethod* renderer, const Matrix* transform, Array& clips, uint8_t opacity, RenderUpdateFlag flag, bool clipper) + RenderData update(RenderMethod* renderer, const Matrix& transform, Array& clips, uint8_t opacity, RenderUpdateFlag flag, bool clipper) { if ((needComp = needComposition(opacity))) { /* Overriding opacity value. If this scene is half-translucent, diff --git a/src/renderer/tvgShape.h b/src/renderer/tvgShape.h index 8b6b3f00..ef290fde 100644 --- a/src/renderer/tvgShape.h +++ b/src/renderer/tvgShape.h @@ -96,7 +96,7 @@ struct Shape::Impl return true; } - RenderData update(RenderMethod* renderer, const Matrix* transform, Array& clips, uint8_t opacity, RenderUpdateFlag pFlag, bool clipper) + RenderData update(RenderMethod* renderer, const Matrix& transform, Array& clips, uint8_t opacity, RenderUpdateFlag pFlag, bool clipper) { if (static_cast(pFlag | flag) == RenderUpdateFlag::None) return rd; diff --git a/src/renderer/tvgText.h b/src/renderer/tvgText.h index 82adae49..02c9ddf0 100644 --- a/src/renderer/tvgText.h +++ b/src/renderer/tvgText.h @@ -120,7 +120,7 @@ struct Text::Impl return false; } - RenderData update(RenderMethod* renderer, const Matrix* transform, Array& clips, uint8_t opacity, RenderUpdateFlag pFlag, bool clipper) + RenderData update(RenderMethod* renderer, const Matrix& transform, Array& clips, uint8_t opacity, RenderUpdateFlag pFlag, bool clipper) { if (!load()) return nullptr; diff --git a/src/renderer/wg_engine/tvgWgRenderData.cpp b/src/renderer/wg_engine/tvgWgRenderData.cpp index e573f338..f20386dd 100644 --- a/src/renderer/wg_engine/tvgWgRenderData.cpp +++ b/src/renderer/wg_engine/tvgWgRenderData.cpp @@ -286,7 +286,7 @@ void WgRenderDataShape::updateBBox(WgPoint pmin, WgPoint pmax) } -void WgRenderDataShape::updateMeshes(WgContext &context, const RenderShape &rshape, const Matrix* rt) +void WgRenderDataShape::updateMeshes(WgContext &context, const RenderShape &rshape, const Matrix& rt) { releaseMeshes(context); strokeFirst = rshape.stroke ? rshape.stroke->strokeFirst : false; @@ -310,10 +310,10 @@ void WgRenderDataShape::updateMeshes(WgContext &context, const RenderShape &rsha polyline.close(); } else if (cmd == PathCommand::CubicTo) { assert(polyline.pts.count > 0); - WgPoint pt0 = polyline.pts.last().trans(*rt); - WgPoint pt1 = WgPoint(rshape.path.pts[pntIndex + 0]).trans(*rt); - WgPoint pt2 = WgPoint(rshape.path.pts[pntIndex + 1]).trans(*rt); - WgPoint pt3 = WgPoint(rshape.path.pts[pntIndex + 2]).trans(*rt); + WgPoint pt0 = polyline.pts.last().trans(rt); + WgPoint pt1 = WgPoint(rshape.path.pts[pntIndex + 0]).trans(rt); + WgPoint pt2 = WgPoint(rshape.path.pts[pntIndex + 1]).trans(rt); + WgPoint pt3 = WgPoint(rshape.path.pts[pntIndex + 2]).trans(rt); uint32_t nsegs = (uint32_t)(pt0.dist(pt1) + pt1.dist(pt2) + pt2.dist(pt3)); polyline.appendCubic( rshape.path.pts[pntIndex + 0], diff --git a/src/renderer/wg_engine/tvgWgRenderData.h b/src/renderer/wg_engine/tvgWgRenderData.h index 37d62dc4..7eeef3eb 100644 --- a/src/renderer/wg_engine/tvgWgRenderData.h +++ b/src/renderer/wg_engine/tvgWgRenderData.h @@ -112,7 +112,7 @@ struct WgRenderDataShape: public WgRenderDataPaint FillRule fillRule{}; void updateBBox(WgPoint pmin, WgPoint pmax); - void updateMeshes(WgContext& context, const RenderShape& rshape, const Matrix* rt); + void updateMeshes(WgContext& context, const RenderShape& rshape, const Matrix& rt); void updateMeshes(WgContext& context, const WgPolyline* polyline, const RenderStroke* rstroke); void releaseMeshes(WgContext& context); void release(WgContext& context) override; diff --git a/src/renderer/wg_engine/tvgWgRenderer.cpp b/src/renderer/wg_engine/tvgWgRenderer.cpp index 3eae3773..4640a506 100644 --- a/src/renderer/wg_engine/tvgWgRenderer.cpp +++ b/src/renderer/wg_engine/tvgWgRenderer.cpp @@ -93,7 +93,7 @@ void WgRenderer::clearDisposes() /* External Class Implementation */ /************************************************************************/ -RenderData WgRenderer::prepare(const RenderShape& rshape, RenderData data, const Matrix* transform, Array& clips, uint8_t opacity, RenderUpdateFlag flags, bool clipper) +RenderData WgRenderer::prepare(const RenderShape& rshape, RenderData data, const Matrix& transform, Array& clips, uint8_t opacity, RenderUpdateFlag flags, bool clipper) { // get or create render data shape auto renderDataShape = (WgRenderDataShape*)data; @@ -127,13 +127,13 @@ RenderData WgRenderer::prepare(const RenderShape& rshape, RenderData data, const } -RenderData WgRenderer::prepare(TVG_UNUSED const Array& scene, TVG_UNUSED RenderData data, TVG_UNUSED const Matrix* transform, TVG_UNUSED Array& clips, TVG_UNUSED uint8_t opacity, TVG_UNUSED RenderUpdateFlag flags) +RenderData WgRenderer::prepare(TVG_UNUSED const Array& scene, TVG_UNUSED RenderData data, TVG_UNUSED const Matrix& transform, TVG_UNUSED Array& clips, TVG_UNUSED uint8_t opacity, TVG_UNUSED RenderUpdateFlag flags) { return nullptr; } -RenderData WgRenderer::prepare(Surface* surface, const RenderMesh* mesh, RenderData data, const Matrix* transform, Array& clips, uint8_t opacity, RenderUpdateFlag flags) +RenderData WgRenderer::prepare(Surface* surface, const RenderMesh* mesh, RenderData data, const Matrix& transform, Array& clips, uint8_t opacity, RenderUpdateFlag flags) { // get or create render data shape auto renderDataPicture = (WgRenderDataPicture*)data; diff --git a/src/renderer/wg_engine/tvgWgRenderer.h b/src/renderer/wg_engine/tvgWgRenderer.h index b019be5e..193872d4 100644 --- a/src/renderer/wg_engine/tvgWgRenderer.h +++ b/src/renderer/wg_engine/tvgWgRenderer.h @@ -28,9 +28,9 @@ class WgRenderer : public RenderMethod { public: - RenderData prepare(const RenderShape& rshape, RenderData data, const Matrix* transform, Array& clips, uint8_t opacity, RenderUpdateFlag flags, bool clipper) override; - RenderData prepare(const Array& scene, RenderData data, const Matrix* transform, Array& clips, uint8_t opacity, RenderUpdateFlag flags) override; - RenderData prepare(Surface* surface, const RenderMesh* mesh, RenderData data, const Matrix* transform, Array& clips, uint8_t opacity, RenderUpdateFlag flags) override; + RenderData prepare(const RenderShape& rshape, RenderData data, const Matrix& transform, Array& clips, uint8_t opacity, RenderUpdateFlag flags, bool clipper) override; + RenderData prepare(const Array& scene, RenderData data, const Matrix& transform, Array& clips, uint8_t opacity, RenderUpdateFlag flags) override; + RenderData prepare(Surface* surface, const RenderMesh* mesh, RenderData data, const Matrix& transform, Array& clips, uint8_t opacity, RenderUpdateFlag flags) override; bool preRender() override; bool renderShape(RenderData data) override; bool renderImage(RenderData data) override; diff --git a/src/renderer/wg_engine/tvgWgShaderTypes.cpp b/src/renderer/wg_engine/tvgWgShaderTypes.cpp index da7ba05a..cc109f4c 100644 --- a/src/renderer/wg_engine/tvgWgShaderTypes.cpp +++ b/src/renderer/wg_engine/tvgWgShaderTypes.cpp @@ -32,7 +32,7 @@ WgShaderTypeMat4x4f::WgShaderTypeMat4x4f() } -WgShaderTypeMat4x4f::WgShaderTypeMat4x4f(const Matrix* transform) +WgShaderTypeMat4x4f::WgShaderTypeMat4x4f(const Matrix& transform) { update(transform); } @@ -53,27 +53,25 @@ WgShaderTypeMat4x4f::WgShaderTypeMat4x4f(size_t w, size_t h) } -void WgShaderTypeMat4x4f::update(const Matrix* transform) +void WgShaderTypeMat4x4f::update(const Matrix& transform) { - identity(); - if (transform) { - mat[0] = transform->e11; - mat[1] = transform->e21; - mat[2] = 0.0f; - mat[3] = transform->e31; - mat[4] = transform->e12; - mat[5] = transform->e22; - mat[6] = 0.0f; - mat[7] = transform->e32; - mat[8] = 0.0f; - mat[9] = 0.0f; - mat[10] = 1.0f; - mat[11] = 0.0f; - mat[12] = transform->e13; - mat[13] = transform->e23; - mat[14] = 0.0f; - mat[15] = transform->e33; - }; + + mat[0] = transform.e11; + mat[1] = transform.e21; + mat[2] = 0.0f; + mat[3] = transform.e31; + mat[4] = transform.e12; + mat[5] = transform.e22; + mat[6] = 0.0f; + mat[7] = transform.e32; + mat[8] = 0.0f; + mat[9] = 0.0f; + mat[10] = 1.0f; + mat[11] = 0.0f; + mat[12] = transform.e13; + mat[13] = transform.e23; + mat[14] = 0.0f; + mat[15] = transform.e33; } diff --git a/src/renderer/wg_engine/tvgWgShaderTypes.h b/src/renderer/wg_engine/tvgWgShaderTypes.h index 93d96ee0..3c033533 100644 --- a/src/renderer/wg_engine/tvgWgShaderTypes.h +++ b/src/renderer/wg_engine/tvgWgShaderTypes.h @@ -35,10 +35,10 @@ struct WgShaderTypeMat4x4f float mat[16]{}; WgShaderTypeMat4x4f(); - WgShaderTypeMat4x4f(const Matrix* transform); + WgShaderTypeMat4x4f(const Matrix& transform); WgShaderTypeMat4x4f(size_t w, size_t h); void identity(); - void update(const Matrix* transform); + void update(const Matrix& transform); void update(size_t w, size_t h); };