renderer: code refactoring

Replaced the transformation with
a strong associated data field.

This helps to reduce the binary size (-1k).
This commit is contained in:
Hermet Park 2024-07-29 18:46:47 +09:00
parent 157e873e83
commit ecabdc5ebc
33 changed files with 214 additions and 324 deletions

View file

@ -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) bool inverse(const Matrix* m, Matrix* out)
{ {
auto det = m->e11 * (m->e22 * m->e33 - m->e32 * m->e23) - auto det = m->e11 * (m->e22 * m->e33 - m->e32 * m->e23) -

View file

@ -75,21 +75,20 @@ static inline bool equal(float a, float b)
void rotate(Matrix* m, float degree); void rotate(Matrix* m, float degree);
bool inverse(const Matrix* m, Matrix* out); bool inverse(const Matrix* m, Matrix* out);
bool identity(const Matrix* m); bool identity(const Matrix* m);
Matrix multiply(const Matrix* lhs, const Matrix* rhs);
Matrix operator*(const Matrix& lhs, const Matrix& rhs); Matrix operator*(const Matrix& lhs, const Matrix& rhs);
bool 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; if (radian < FLOAT_EPSILON || tvg::equal(radian, MATH_PI2) || tvg::equal(radian, MATH_PI)) return true;
return false; 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);
} }

View file

@ -252,8 +252,7 @@ static void _updateTransform(LottieGroup* parent, LottieObject** child, float fr
Matrix matrix; Matrix matrix;
if (!_updateTransform(transform, frameNo, false, matrix, opacity, exps)) return; if (!_updateTransform(transform, frameNo, false, matrix, opacity, exps)) return;
auto pmatrix = PP(ctx->propagator)->transform(); ctx->propagator->transform(PP(ctx->propagator)->transform() * matrix);
ctx->propagator->transform(pmatrix ? (*pmatrix * matrix) : matrix);
ctx->propagator->opacity(MULTIPLY(opacity, PP(ctx->propagator)->opacity)); ctx->propagator->opacity(MULTIPLY(opacity, PP(ctx->propagator)->opacity));
//FIXME: preserve the stroke width. too workaround, need a better design. //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); translateR(&m, -repeater->anchor.x, -repeater->anchor.y);
m = repeater->transform * m; m = repeater->transform * m;
auto pm = PP(shape)->transform(); Matrix inv;
if (pm) { inverse(&repeater->transform, &inv);
Matrix m; shape->transform(m * (inv * PP(shape)->transform()));
inverse(&repeater->transform, &m);
*pm = m * *pm;
}
shape->transform(pm ? m * *pm : m);
shapes.push(shape); shapes.push(shape);
} }
} }
@ -928,8 +922,7 @@ static void _updateRepeater(TVG_UNUSED LottieGroup* parent, LottieObject** child
RenderRepeater r; RenderRepeater r;
r.cnt = static_cast<int>(repeater->copies(frameNo, exps)); r.cnt = static_cast<int>(repeater->copies(frameNo, exps));
if (auto tr = PP(ctx->propagator)->transform()) r.transform = *tr; r.transform = PP(ctx->propagator)->transform();
else identity(&r.transform);
r.offset = repeater->offset(frameNo, exps); r.offset = repeater->offset(frameNo, exps);
r.position = repeater->position(frameNo, exps); r.position = repeater->position(frameNo, exps);
r.anchor = repeater->anchor(frameNo, exps); r.anchor = repeater->anchor(frameNo, exps);

View file

@ -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; mMatrix = m;
else tvg::identity(&mMatrix);
} }
void GlGeometry::setViewport(const RenderRegion& viewport) void GlGeometry::setViewport(const RenderRegion& viewport)
{ {
this->viewport = viewport; this->viewport = viewport;
} }
const RenderRegion& GlGeometry::getViewport() const RenderRegion& GlGeometry::getViewport()
{ {
return viewport; return viewport;
} }
const Matrix& GlGeometry::getTransformMatrix() const Matrix& GlGeometry::getTransformMatrix()
{ {
return mMatrix; return mMatrix;
} }
GlStencilMode GlGeometry::getStencilMode(RenderUpdateFlag flag) GlStencilMode GlGeometry::getStencilMode(RenderUpdateFlag flag)
{ {
if (flag & RenderUpdateFlag::Stroke) return GlStencilMode::Stroke; if (flag & RenderUpdateFlag::Stroke) return GlStencilMode::Stroke;
@ -248,6 +251,7 @@ GlStencilMode GlGeometry::getStencilMode(RenderUpdateFlag flag)
return GlStencilMode::None; return GlStencilMode::None;
} }
RenderRegion GlGeometry::getBounds() const RenderRegion GlGeometry::getBounds() const
{ {
if (identity(&mMatrix)) { if (identity(&mMatrix)) {

View file

@ -193,7 +193,7 @@ public:
bool tesselate(const Surface* image, const RenderMesh* mesh, RenderUpdateFlag flag); bool tesselate(const Surface* image, const RenderMesh* mesh, RenderUpdateFlag flag);
void disableVertex(uint32_t location); void disableVertex(uint32_t location);
bool draw(GlRenderTask* task, GlStageBuffer* gpuBuffer, RenderUpdateFlag flag); bool draw(GlRenderTask* task, GlStageBuffer* gpuBuffer, RenderUpdateFlag flag);
void updateTransform(const Matrix* m); void updateTransform(const Matrix& m);
void setViewport(const RenderRegion& viewport); void setViewport(const RenderRegion& viewport);
const RenderRegion& getViewport(); const RenderRegion& getViewport();
const Matrix& getTransformMatrix(); const Matrix& getTransformMatrix();

View file

@ -1099,7 +1099,7 @@ static GLuint _genTexture(Surface* image)
} }
RenderData GlRenderer::prepare(Surface* image, const RenderMesh* mesh, RenderData data, const Matrix* transform, Array<RenderData>& clips, uint8_t opacity, RenderUpdateFlag flags) RenderData GlRenderer::prepare(Surface* image, const RenderMesh* mesh, RenderData data, const Matrix& transform, Array<RenderData>& clips, uint8_t opacity, RenderUpdateFlag flags)
{ {
if (flags == RenderUpdateFlag::None) return data; 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<RenderData>& scene, TVG_UNUSED RenderData data, TVG_UNUSED const Matrix* transform, TVG_UNUSED Array<RenderData>& clips, TVG_UNUSED uint8_t opacity, TVG_UNUSED RenderUpdateFlag flags) RenderData GlRenderer::prepare(TVG_UNUSED const Array<RenderData>& scene, TVG_UNUSED RenderData data, TVG_UNUSED const Matrix& transform, TVG_UNUSED Array<RenderData>& clips, TVG_UNUSED uint8_t opacity, TVG_UNUSED RenderUpdateFlag flags)
{ {
//TODO: //TODO:
return nullptr; return nullptr;
} }
RenderData GlRenderer::prepare(const RenderShape& rshape, RenderData data, const Matrix* transform, Array<RenderData>& clips, uint8_t opacity, RenderUpdateFlag flags, bool clipper) RenderData GlRenderer::prepare(const RenderShape& rshape, RenderData data, const Matrix& transform, Array<RenderData>& clips, uint8_t opacity, RenderUpdateFlag flags, bool clipper)
{ {
// If prepare for clip, only path is meaningful. // If prepare for clip, only path is meaningful.
if (clipper) flags = RenderUpdateFlag::Path; if (clipper) flags = RenderUpdateFlag::Path;

View file

@ -53,9 +53,9 @@ public:
RT_None, RT_None,
}; };
RenderData prepare(const RenderShape& rshape, RenderData data, const Matrix* transform, Array<RenderData>& clips, uint8_t opacity, RenderUpdateFlag flags, bool clipper) override; RenderData prepare(const RenderShape& rshape, RenderData data, const Matrix& transform, Array<RenderData>& clips, uint8_t opacity, RenderUpdateFlag flags, bool clipper) override;
RenderData prepare(const Array<RenderData>& scene, RenderData data, const Matrix* transform, Array<RenderData>& clips, uint8_t opacity, RenderUpdateFlag flags) override; RenderData prepare(const Array<RenderData>& scene, RenderData data, const Matrix& transform, Array<RenderData>& clips, uint8_t opacity, RenderUpdateFlag flags) override;
RenderData prepare(Surface* surface, const RenderMesh* mesh, RenderData data, const Matrix* transform, Array<RenderData>& clips, uint8_t opacity, RenderUpdateFlag flags) override; RenderData prepare(Surface* surface, const RenderMesh* mesh, RenderData data, const Matrix& transform, Array<RenderData>& clips, uint8_t opacity, RenderUpdateFlag flags) override;
bool preRender() override; bool preRender() override;
bool renderShape(RenderData data) override; bool renderShape(RenderData data) override;
bool renderImage(RenderData data) override; bool renderImage(RenderData data) override;

View file

@ -493,38 +493,38 @@ SwFixed mathDiff(SwFixed angle1, SwFixed angle2);
SwFixed mathLength(const SwPoint& pt); SwFixed mathLength(const SwPoint& pt);
bool mathSmallCubic(const SwPoint* base, SwFixed& angleIn, SwFixed& angleMid, SwFixed& angleOut); bool mathSmallCubic(const SwPoint* base, SwFixed& angleIn, SwFixed& angleMid, SwFixed& angleOut);
SwFixed mathMean(SwFixed angle1, SwFixed angle2); 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 mathUpdateOutlineBBox(const SwOutline* outline, const SwBBox& clipRegion, SwBBox& renderRegion, bool fastTrack);
bool mathClipBBox(const SwBBox& clipper, SwBBox& clippee); bool mathClipBBox(const SwBBox& clipper, SwBBox& clippee);
void shapeReset(SwShape* shape); 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 shapePrepared(const SwShape* shape);
bool shapeGenRle(SwShape* shape, const RenderShape* rshape, bool antiAlias); bool shapeGenRle(SwShape* shape, const RenderShape* rshape, bool antiAlias);
void shapeDelOutline(SwShape* shape, SwMpool* mpool, uint32_t tid); void shapeDelOutline(SwShape* shape, SwMpool* mpool, uint32_t tid);
void shapeResetStroke(SwShape* shape, const RenderShape* rshape, const Matrix* transform); 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 SwBBox& clipRegion, SwBBox& renderRegion, SwMpool* mpool, unsigned tid);
void shapeFree(SwShape* shape); void shapeFree(SwShape* shape);
void shapeDelStroke(SwShape* shape); void shapeDelStroke(SwShape* shape);
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);
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);
void shapeResetFill(SwShape* shape); void shapeResetFill(SwShape* shape);
void shapeResetStrokeFill(SwShape* shape); void shapeResetStrokeFill(SwShape* shape);
void shapeDelFill(SwShape* shape); void shapeDelFill(SwShape* shape);
void shapeDelStrokeFill(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); bool strokeParseOutline(SwStroke* stroke, const SwOutline& outline);
SwOutline* strokeExportOutline(SwStroke* stroke, SwMpool* mpool, unsigned tid); SwOutline* strokeExportOutline(SwStroke* stroke, SwMpool* mpool, unsigned tid);
void strokeFree(SwStroke* stroke); 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); bool imageGenRle(SwImage* image, const SwBBox& renderRegion, bool antiAlias);
void imageDelOutline(SwImage* image, SwMpool* mpool, uint32_t tid); void imageDelOutline(SwImage* image, SwMpool* mpool, uint32_t tid);
void imageReset(SwImage* image); void imageReset(SwImage* image);
void imageFree(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 fillReset(SwFill* fill);
void fillFree(SwFill* fill); void fillFree(SwFill* fill);
@ -562,7 +562,7 @@ void mpoolRetDashOutline(SwMpool* mpool, unsigned idx);
bool rasterCompositor(SwSurface* surface); bool rasterCompositor(SwSurface* surface);
bool rasterGradientShape(SwSurface* surface, SwShape* shape, Type type); 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 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 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 rasterGradientStroke(SwSurface* surface, SwShape* shape, Type type);
bool rasterClear(SwSurface* surface, uint32_t x, uint32_t y, uint32_t w, uint32_t h); bool rasterClear(SwSurface* surface, uint32_t x, uint32_t y, uint32_t w, uint32_t h);

View file

@ -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; float x1, x2, y1, y2;
if (linear->linear(&x1, &y1, &x2, &y2) != Result::Success) return false; 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)); bool isTransformation = !identity((const Matrix*)(&gradTransform));
if (isTransformation) { if (isTransformation) {
if (transform) gradTransform = *transform * gradTransform; gradTransform = transform * gradTransform;
} else if (transform) { } else {
gradTransform = *transform; gradTransform = transform;
isTransformation = true; 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 cx = P(radial)->cx;
auto cy = P(radial)->cy; auto cy = P(radial)->cy;
@ -287,12 +287,10 @@ bool _prepareRadial(SwFill* fill, const RadialGradient* radial, const Matrix* tr
auto gradTransform = radial->transform(); auto gradTransform = radial->transform();
bool isTransformation = !identity((const Matrix*)(&gradTransform)); bool isTransformation = !identity((const Matrix*)(&gradTransform));
if (transform) { if (isTransformation) gradTransform = transform * gradTransform;
if (isTransformation) gradTransform = *transform * gradTransform; else {
else { gradTransform = transform;
gradTransform = *transform; isTransformation = true;
isTransformation = true;
}
} }
if (isTransformation) { 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; if (!fill) return false;

View file

@ -27,14 +27,14 @@
/* Internal Class Implementation */ /* 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; 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); image->outline = mpoolReqOutline(mpool, tid);
auto outline = image->outline; auto outline = image->outline;
@ -108,21 +108,21 @@ static bool _genOutline(SwImage* image, const RenderMesh* mesh, const Matrix* tr
/* External Class Implementation */ /* 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); image->direct = _onlyShifted(transform);
//Fast track: Non-transformed image but just shifted. //Fast track: Non-transformed image but just shifted.
if (image->direct) { if (image->direct) {
image->ox = -static_cast<int32_t>(nearbyint(transform->e13)); image->ox = -static_cast<int32_t>(nearbyint(transform.e13));
image->oy = -static_cast<int32_t>(nearbyint(transform->e23)); image->oy = -static_cast<int32_t>(nearbyint(transform.e23));
//Figure out the scale factor by transform matrix //Figure out the scale factor by transform matrix
} else { } else {
auto scaleX = sqrtf((transform->e11 * transform->e11) + (transform->e21 * transform->e21)); auto scaleX = sqrtf((transform.e11 * transform.e11) + (transform.e21 * transform.e21));
auto scaleY = sqrtf((transform->e22 * transform->e22) + (transform->e12 * transform->e12)); auto scaleY = sqrtf((transform.e22 * transform.e22) + (transform.e12 * transform.e12));
image->scale = (fabsf(scaleX - scaleY) > 0.01f) ? 1.0f : scaleX; 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; else image->scaled = false;
} }

View file

@ -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)}; return {TO_SWCOORD(tx), TO_SWCOORD(ty)};
} }

View file

@ -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)) { if (surface->channelSize == sizeof(uint8_t)) {
TVGERR("SW_ENGINE", "Not supported scaled rle image!"); TVGERR("SW_ENGINE", "Not supported scaled rle image!");
@ -841,9 +841,7 @@ static bool _scaledRleImage(SwSurface* surface, const SwImage* image, const Matr
Matrix itransform; Matrix itransform;
if (transform) { if (!inverse(&transform, &itransform)) return true;
if (!inverse(transform, &itransform)) return true;
} else identity(&itransform);
if (_compositing(surface)) { if (_compositing(surface)) {
if (_matting(surface)) return _rasterScaledMattedRleImage(surface, image, &itransform, region, opacity); 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; Matrix itransform;
if (transform) { if (!inverse(&transform, &itransform)) return true;
if (!inverse(transform, &itransform)) return true;
} else identity(&itransform);
if (_compositing(surface)) { if (_compositing(surface)) {
if (_matting(surface)) return _rasterScaledMattedImage(surface, image, &itransform, region, opacity); 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] //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 //RLE Image
if (image->rle) { 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 //Outside of the viewport, skip the rendering
if (bbox.max.x < 0 || bbox.max.y < 0 || bbox.min.x >= static_cast<SwCoord>(surface->w) || bbox.min.y >= static_cast<SwCoord>(surface->h)) return true; if (bbox.max.x < 0 || bbox.max.y < 0 || bbox.min.x >= static_cast<SwCoord>(surface->w) || bbox.min.y >= static_cast<SwCoord>(surface->h)) return true;

View file

@ -1084,7 +1084,7 @@ static bool _apply(SwSurface* surface, AASpans* aaSpans)
| / | | / |
3 -- 2 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)) { if (surface->channelSize == sizeof(uint8_t)) {
TVGERR("SW_ENGINE", "Not supported grayscale Textmap polygon!"); 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; float ys = FLT_MAX, ye = -1.0f;
for (int i = 0; i < 4; i++) { 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 < ys) ys = vertices[i].pt.y;
if (vertices[i].pt.y > ye) ye = 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. Should provide two Polygons, one for each triangle.
// TODO: region? // 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)) { if (surface->channelSize == sizeof(uint8_t)) {
TVGERR("SW_ENGINE", "Not supported grayscale Textmap polygon mesh!"); 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; float ys = FLT_MAX, ye = -1.0f;
for (uint32_t i = 0; i < mesh->triangleCnt; i++) { for (uint32_t i = 0; i < mesh->triangleCnt; i++) {
transformedTris[i] = mesh->triangles[i]; transformedTris[i] = mesh->triangles[i];
transformedTris[i].vertex[0].pt *= *transform; transformedTris[i].vertex[0].pt *= transform;
transformedTris[i].vertex[1].pt *= *transform; transformedTris[i].vertex[1].pt *= transform;
transformedTris[i].vertex[2].pt *= *transform; transformedTris[i].vertex[2].pt *= transform;
if (transformedTris[i].vertex[0].pt.y < ys) ys = transformedTris[i].vertex[0].pt.y; 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; else if (transformedTris[i].vertex[0].pt.y > ye) ye = transformedTris[i].vertex[0].pt.y;

View file

@ -39,7 +39,7 @@ struct SwTask : Task
SwSurface* surface = nullptr; SwSurface* surface = nullptr;
SwMpool* mpool = nullptr; SwMpool* mpool = nullptr;
SwBBox bbox = {{0, 0}, {0, 0}}; //Whole Rendering Region SwBBox bbox = {{0, 0}, {0, 0}}; //Whole Rendering Region
Matrix* transform = nullptr; Matrix transform;
Array<RenderData> clips; Array<RenderData> clips;
RenderUpdateFlag flags = RenderUpdateFlag::None; RenderUpdateFlag flags = RenderUpdateFlag::None;
uint8_t opacity; uint8_t opacity;
@ -68,10 +68,7 @@ struct SwTask : Task
virtual bool clip(SwRle* target) = 0; virtual bool clip(SwRle* target) = 0;
virtual SwRle* rle() = 0; virtual SwRle* rle() = 0;
virtual ~SwTask() virtual ~SwTask() {}
{
free(transform);
}
}; };
@ -100,8 +97,7 @@ struct SwShapeTask : SwTask
if (!rshape->stroke->fill && (MULTIPLY(rshape->stroke->color[3], opacity) == 0)) return 0.0f; 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 (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)); return (width * sqrt(transform.e11 * transform.e11 + transform.e12 * transform.e12));
else return width;
} }
@ -688,7 +684,8 @@ bool SwRenderer::endComposite(Compositor* cmp)
//Default is alpha blending //Default is alpha blending
if (p->method == CompositeMethod::None) { 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; return true;
@ -714,7 +711,7 @@ void SwRenderer::dispose(RenderData data)
} }
void* SwRenderer::prepareCommon(SwTask* task, const Matrix* transform, const Array<RenderData>& clips, uint8_t opacity, RenderUpdateFlag flags) void* SwRenderer::prepareCommon(SwTask* task, const Matrix& transform, const Array<RenderData>& clips, uint8_t opacity, RenderUpdateFlag flags)
{ {
if (!surface) return task; if (!surface) return task;
if (flags == RenderUpdateFlag::None) 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; task->clips = clips;
task->transform = transform;
if (transform) {
if (!task->transform) task->transform = static_cast<Matrix*>(malloc(sizeof(Matrix)));
*task->transform = *transform;
} else {
if (task->transform) free(task->transform);
task->transform = nullptr;
}
//zero size? //zero size?
if (task->transform) { if (task->transform.e11 == 0.0f && task->transform.e12 == 0.0f) return task; //zero width
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->e21 == 0.0f && task->transform->e22 == 0.0f) return task; //zero height
}
task->opacity = opacity; task->opacity = opacity;
task->surface = surface; 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<RenderData>& clips, uint8_t opacity, RenderUpdateFlag flags) RenderData SwRenderer::prepare(Surface* surface, const RenderMesh* mesh, RenderData data, const Matrix& transform, Array<RenderData>& clips, uint8_t opacity, RenderUpdateFlag flags)
{ {
//prepare task //prepare task
auto task = static_cast<SwImageTask*>(data); auto task = static_cast<SwImageTask*>(data);
@ -776,7 +764,7 @@ RenderData SwRenderer::prepare(Surface* surface, const RenderMesh* mesh, RenderD
} }
RenderData SwRenderer::prepare(const Array<RenderData>& scene, RenderData data, const Matrix* transform, Array<RenderData>& clips, uint8_t opacity, RenderUpdateFlag flags) RenderData SwRenderer::prepare(const Array<RenderData>& scene, RenderData data, const Matrix& transform, Array<RenderData>& clips, uint8_t opacity, RenderUpdateFlag flags)
{ {
//prepare task //prepare task
auto task = static_cast<SwSceneTask*>(data); auto task = static_cast<SwSceneTask*>(data);
@ -796,7 +784,7 @@ RenderData SwRenderer::prepare(const Array<RenderData>& scene, RenderData data,
} }
RenderData SwRenderer::prepare(const RenderShape& rshape, RenderData data, const Matrix* transform, Array<RenderData>& clips, uint8_t opacity, RenderUpdateFlag flags, bool clipper) RenderData SwRenderer::prepare(const RenderShape& rshape, RenderData data, const Matrix& transform, Array<RenderData>& clips, uint8_t opacity, RenderUpdateFlag flags, bool clipper)
{ {
//prepare task //prepare task
auto task = static_cast<SwShapeTask*>(data); auto task = static_cast<SwShapeTask*>(data);

View file

@ -36,9 +36,9 @@ namespace tvg
class SwRenderer : public RenderMethod class SwRenderer : public RenderMethod
{ {
public: public:
RenderData prepare(const RenderShape& rshape, RenderData data, const Matrix* transform, Array<RenderData>& clips, uint8_t opacity, RenderUpdateFlag flags, bool clipper) override; RenderData prepare(const RenderShape& rshape, RenderData data, const Matrix& transform, Array<RenderData>& clips, uint8_t opacity, RenderUpdateFlag flags, bool clipper) override;
RenderData prepare(const Array<RenderData>& scene, RenderData data, const Matrix* transform, Array<RenderData>& clips, uint8_t opacity, RenderUpdateFlag flags) override; RenderData prepare(const Array<RenderData>& scene, RenderData data, const Matrix& transform, Array<RenderData>& clips, uint8_t opacity, RenderUpdateFlag flags) override;
RenderData prepare(Surface* surface, const RenderMesh* mesh, RenderData data, const Matrix* transform, Array<RenderData>& clips, uint8_t opacity, RenderUpdateFlag flags) override; RenderData prepare(Surface* surface, const RenderMesh* mesh, RenderData data, const Matrix& transform, Array<RenderData>& clips, uint8_t opacity, RenderUpdateFlag flags) override;
bool preRender() override; bool preRender() override;
bool renderShape(RenderData data) override; bool renderShape(RenderData data) override;
bool renderImage(RenderData data) override; bool renderImage(RenderData data) override;
@ -77,7 +77,7 @@ private:
SwRenderer(); SwRenderer();
~SwRenderer(); ~SwRenderer();
RenderData prepareCommon(SwTask* task, const Matrix* transform, const Array<RenderData>& clips, uint8_t opacity, RenderUpdateFlag flags); RenderData prepareCommon(SwTask* task, const Matrix& transform, const Array<RenderData>& clips, uint8_t opacity, RenderUpdateFlag flags);
}; };
} }

View file

@ -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. //make it a contour, if the last contour is not closed yet.
if (!closed) _outlineEnd(outline); 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.pts.push(mathTransform(to, transform));
outline.types.push(SW_CURVE_TYPE_POINT); 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.pts.push(mathTransform(ctrl1, transform));
outline.types.push(SW_CURVE_TYPE_CUBIC); 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}; Line cur = {dash.ptCur, *to};
auto len = cur.length(); 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}; Bezier cur = {dash.ptCur, *ctrl1, *ctrl2, *to};
auto len = cur.length(); 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); _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; const PathCommand* cmds = rshape->path.cmds.data;
auto cmdCnt = rshape->path.cmds.count; 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; const PathCommand* cmds = rshape->path.cmds.data;
auto cmdCnt = rshape->path.cmds.count; auto cmdCnt = rshape->path.cmds.count;
@ -491,7 +491,7 @@ static bool _genOutline(SwShape* shape, const RenderShape* rshape, const Matrix*
/* External Class Implementation */ /* 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 (!_genOutline(shape, rshape, transform, mpool, tid, hasComposite)) return false;
if (!mathUpdateOutlineBBox(shape->outline, clipRegion, renderRegion, shape->fastTrack)) 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<SwStroke*>(calloc(1, sizeof(SwStroke))); if (!shape->stroke) shape->stroke = static_cast<SwStroke*>(calloc(1, sizeof(SwStroke)));
auto stroke = shape->stroke; 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* shapeOutline = nullptr;
SwOutline* strokeOutline = 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); 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); return fillGenColorTable(shape->stroke->fill, fill, transform, surface, opacity, ctable);
} }

View file

@ -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->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->sy = sqrtf(powf(transform->e12, 2.0f) + powf(transform->e22, 2.0f));
} else {
stroke->sx = stroke->sy = 1.0f;
}
stroke->width = HALF_STROKE(rshape->strokeWidth()); stroke->width = HALF_STROKE(rshape->strokeWidth());
stroke->cap = rshape->strokeCap(); stroke->cap = rshape->strokeCap();
stroke->miterlimit = static_cast<SwFixed>(rshape->strokeMiterlimit() * 65536.0f); stroke->miterlimit = static_cast<SwFixed>(rshape->strokeMiterlimit() * 65536.0f);

View file

@ -93,11 +93,13 @@ struct Canvas::Impl
auto flag = RenderUpdateFlag::None; auto flag = RenderUpdateFlag::None;
if (status == Status::Damaged || force) flag = RenderUpdateFlag::All; if (status == Status::Damaged || force) flag = RenderUpdateFlag::All;
auto m = Matrix{1, 0, 0, 0, 1, 0, 0, 0, 1};
if (paint) { if (paint) {
paint->pImpl->update(renderer, nullptr, clips, 255, flag); paint->pImpl->update(renderer, m, clips, 255, flag);
} else { } else {
for (auto paint : paints) { for (auto paint : paints) {
paint->pImpl->update(renderer, nullptr, clips, 255, flag); paint->pImpl->update(renderer, m, clips, 255, flag);
} }
} }
status = Status::Updating; status = Status::Updating;

View file

@ -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 //sorting
Point tmp[4]; Point tmp[4];
@ -50,8 +50,8 @@ static Result _clipRect(RenderMethod* renderer, const Point* pts, const Matrix*
for (int i = 0; i < 4; ++i) { for (int i = 0; i < 4; ++i) {
tmp[i] = pts[i]; tmp[i] = pts[i];
if (rm) tmp[i] *= *rm; tmp[i] *= rm;
if (pm) tmp[i] *= *pm; tmp[i] *= pm;
if (tmp[i].x < min.x) min.x = tmp[i].x; 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].x > max.x) max.x = tmp[i].x;
if (tmp[i].y < min.y) min.y = tmp[i].y; 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. */ /* Access Shape class by Paint is bad... but it's ok still it's an internal usage. */
auto shape = static_cast<Shape*>(cmpTarget); auto shape = static_cast<Shape*>(cmpTarget);
@ -86,18 +86,13 @@ static Result _compFastTrack(RenderMethod* renderer, Paint* cmpTarget, const Mat
if (ptsCnt == 0) return Result::InvalidArguments; if (ptsCnt == 0) return Result::InvalidArguments;
if (ptsCnt != 4) return Result::InsufficientCondition; if (ptsCnt != 4) return Result::InsufficientCondition;
Matrix* rm = nullptr; auto& rm = P(cmpTarget)->transform();
if (P(cmpTarget)->rTransform && (P(cmpTarget)->renderFlag & RenderUpdateFlag::Transform)) {
P(cmpTarget)->rTransform->update();
rm = &P(cmpTarget)->rTransform->m;
}
//No rotation and no skewing, still can try out clipping the rect region. //No rotation and no skewing, still can try out clipping the rect region.
auto tryClip = false; auto tryClip = false;
if (pm && (!rightAngle(pm) || skewed(pm))) tryClip = true; if ((!rightAngle(pm) || skewed(pm))) tryClip = true;
if (rm && (!rightAngle(rm) || skewed(rm))) tryClip = true; if ((!rightAngle(rm) || skewed(rm))) tryClip = true;
if (tryClip) return _clipRect(renderer, pts, pm, rm, before); 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 v1 = *pt1;
auto v2 = *pt3; auto v2 = *pt3;
v1 *= rm;
if (rm) { v2 *= rm;
v1 *= *rm; v1 *= pm;
v2 *= *rm; v2 *= pm;
}
if (pm) {
v1 *= *pm;
v2 *= *pm;
}
//sorting //sorting
if (v1.x > v2.x) std::swap(v1.x, v2.x); 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)); PAINT_METHOD(ret, duplicate(ret));
//duplicate Transform //duplicate Transform
if (rTransform) { ret->pImpl->tr = tr;
if (!ret->pImpl->rTransform) { ret->pImpl->renderFlag |= RenderUpdateFlag::Transform;
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->opacity = opacity; ret->pImpl->opacity = opacity;
@ -190,14 +171,9 @@ Paint* Paint::Impl::duplicate(Paint* ret)
bool Paint::Impl::rotate(float degree) bool Paint::Impl::rotate(float degree)
{ {
if (rTransform) { if (tr.overriding) return false;
if (rTransform->overriding) return false; if (tvg::equal(degree, tr.degree)) return true;
if (tvg::equal(degree, rTransform->degree)) return true; tr.degree = degree;
} else {
if (tvg::zero(degree)) return true;
rTransform = new RenderTransform();
}
rTransform->degree = degree;
renderFlag |= RenderUpdateFlag::Transform; renderFlag |= RenderUpdateFlag::Transform;
return true; return true;
@ -206,14 +182,9 @@ bool Paint::Impl::rotate(float degree)
bool Paint::Impl::scale(float factor) bool Paint::Impl::scale(float factor)
{ {
if (rTransform) { if (tr.overriding) return false;
if (rTransform->overriding) return false; if (tvg::equal(factor, tr.scale)) return true;
if (tvg::equal(factor, rTransform->scale)) return true; tr.scale = factor;
} else {
if (tvg::equal(factor, 1.0f)) return true;
rTransform = new RenderTransform();
}
rTransform->scale = factor;
renderFlag |= RenderUpdateFlag::Transform; renderFlag |= RenderUpdateFlag::Transform;
return true; return true;
@ -222,15 +193,10 @@ bool Paint::Impl::scale(float factor)
bool Paint::Impl::translate(float x, float y) bool Paint::Impl::translate(float x, float y)
{ {
if (rTransform) { if (tr.overriding) return false;
if (rTransform->overriding) return false; if (tvg::equal(x, tr.m.e13) && tvg::equal(y, tr.m.e23)) return true;
if (tvg::equal(x, rTransform->m.e13) && tvg::equal(y, rTransform->m.e23)) return true; tr.m.e13 = x;
} else { tr.m.e23 = y;
if (tvg::zero(x) && tvg::zero(y)) return true;
rTransform = new RenderTransform();
}
rTransform->m.e13 = x;
rTransform->m.e23 = y;
renderFlag |= RenderUpdateFlag::Transform; renderFlag |= RenderUpdateFlag::Transform;
return true; return true;
@ -270,7 +236,7 @@ bool Paint::Impl::render(RenderMethod* renderer)
} }
RenderData Paint::Impl::update(RenderMethod* renderer, const Matrix* pm, Array<RenderData>& clips, uint8_t opacity, RenderUpdateFlag pFlag, bool clipper) RenderData Paint::Impl::update(RenderMethod* renderer, const Matrix& pm, Array<RenderData>& clips, uint8_t opacity, RenderUpdateFlag pFlag, bool clipper)
{ {
if (this->renderer != renderer) { if (this->renderer != renderer) {
if (this->renderer) TVGERR("RENDERER", "paint's renderer has been changed!"); if (this->renderer) TVGERR("RENDERER", "paint's renderer has been changed!");
@ -278,7 +244,7 @@ RenderData Paint::Impl::update(RenderMethod* renderer, const Matrix* pm, Array<R
this->renderer = renderer; this->renderer = renderer;
} }
if (renderFlag & RenderUpdateFlag::Transform) rTransform->update(); if (renderFlag & RenderUpdateFlag::Transform) tr.update();
/* 1. Composition Pre Processing */ /* 1. Composition Pre Processing */
RenderData trd = nullptr; //composite target render data RenderData trd = nullptr; //composite target render data
@ -326,8 +292,8 @@ RenderData Paint::Impl::update(RenderMethod* renderer, const Matrix* pm, Array<R
opacity = MULTIPLY(opacity, this->opacity); opacity = MULTIPLY(opacity, this->opacity);
RenderData rd = nullptr; RenderData rd = nullptr;
Matrix om = multiply(pm, rTransform ? &rTransform->m : nullptr); auto m = pm * tr.m;
PAINT_METHOD(rd, update(renderer, &om, clips, opacity, newFlag, clipper)); PAINT_METHOD(rd, update(renderer, m, clips, opacity, newFlag, clipper));
/* 3. Composition Post Processing */ /* 3. Composition Post Processing */
if (compFastTrack == Result::Success) renderer->viewport(viewport); if (compFastTrack == Result::Success) renderer->viewport(viewport);
@ -339,11 +305,11 @@ RenderData Paint::Impl::update(RenderMethod* renderer, const Matrix* pm, Array<R
bool Paint::Impl::bounds(float* x, float* y, float* w, float* h, bool transformed, bool stroking) bool Paint::Impl::bounds(float* x, float* y, float* w, float* h, bool transformed, bool stroking)
{ {
Matrix* m = nullptr;
bool ret; bool ret;
const auto& m = this->transform();
//Case: No transformed, quick return! //Case: No transformed, quick return!
if (!transformed || !(m = this->transform())) { if (!transformed || identity(&m)) {
PAINT_METHOD(ret, bounds(x, y, w, h, stroking)); PAINT_METHOD(ret, bounds(x, y, w, h, stroking));
return ret; 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 //Compute the AABB after transformation
for (int i = 0; i < 4; i++) { 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 < x1) x1 = pt[i].x;
if (pt[i].x > x2) x2 = 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 Matrix Paint::transform() noexcept
{ {
auto pTransform = pImpl->transform(); return pImpl->transform();
if (pTransform) return *pTransform;
return {1, 0, 0, 0, 1, 0, 0, 0, 1};
} }

View file

@ -48,16 +48,38 @@ namespace tvg
struct Paint::Impl struct Paint::Impl
{ {
Paint* paint = nullptr; Paint* paint = nullptr;
RenderTransform* rTransform = nullptr;
Composite* compData = nullptr; Composite* compData = nullptr;
RenderMethod* renderer = nullptr; RenderMethod* renderer = nullptr;
BlendMethod blendMethod = BlendMethod::Normal; //uint8_t 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 renderFlag = RenderUpdateFlag::None;
uint8_t ctxFlag = ContextFlag::Invalid; uint8_t ctxFlag = ContextFlag::Invalid;
uint8_t opacity = 255; uint8_t opacity = 255;
uint8_t refCnt = 0; //reference count uint8_t refCnt = 0; //reference count
Impl(Paint* pnt) : paint(pnt) {} Impl(Paint* pnt) : paint(pnt)
{
identity(&tr.m);
}
~Impl() ~Impl()
{ {
@ -65,7 +87,6 @@ namespace tvg
if (P(compData->target)->unref() == 0) delete(compData->target); if (P(compData->target)->unref() == 0) delete(compData->target);
free(compData); free(compData);
} }
delete(rTransform);
if (renderer && (renderer->unref() == 0)) delete(renderer); if (renderer && (renderer->unref() == 0)) delete(renderer);
} }
@ -83,23 +104,18 @@ namespace tvg
bool transform(const Matrix& m) bool transform(const Matrix& m)
{ {
if (!rTransform) { tr.m = m;
if (identity(&m)) return true; tr.overriding = true;
rTransform = new RenderTransform();
}
rTransform->override(m);
renderFlag |= RenderUpdateFlag::Transform; renderFlag |= RenderUpdateFlag::Transform;
return true; return true;
} }
Matrix* transform() Matrix& transform()
{ {
if (rTransform) { //update transform
if (renderFlag & RenderUpdateFlag::Transform) rTransform->update(); if (renderFlag & RenderUpdateFlag::Transform) tr.update();
return &rTransform->m; return tr.m;
}
return nullptr;
} }
bool composite(Paint* source, Paint* target, CompositeMethod method) bool composite(Paint* source, Paint* target, CompositeMethod method)
@ -135,7 +151,7 @@ namespace tvg
bool scale(float factor); bool scale(float factor);
bool translate(float x, float y); bool translate(float x, float y);
bool bounds(float* x, float* y, float* w, float* h, bool transformed, bool stroking); bool bounds(float* x, float* y, float* w, float* h, bool transformed, bool stroking);
RenderData update(RenderMethod* renderer, const Matrix* pm, Array<RenderData>& clips, uint8_t opacity, RenderUpdateFlag pFlag, bool clipper = false); RenderData update(RenderMethod* renderer, const Matrix& pm, Array<RenderData>& clips, uint8_t opacity, RenderUpdateFlag pFlag, bool clipper = false);
bool render(RenderMethod* renderer); bool render(RenderMethod* renderer);
Paint* duplicate(Paint* ret = nullptr); Paint* duplicate(Paint* ret = nullptr);
}; };

View file

@ -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) Result Picture::Impl::load(ImageLoader* loader)
{ {
//Same resource has been loaded. //Same resource has been loaded.

View file

@ -68,7 +68,6 @@ struct Picture::Impl
bool resizing = false; bool resizing = false;
bool needComp = false; //need composition bool needComp = false; //need composition
Matrix resizeTransform(const Matrix* m);
bool needComposition(uint8_t opacity); bool needComposition(uint8_t opacity);
bool render(RenderMethod* renderer); bool render(RenderMethod* renderer);
bool size(float w, float h); bool size(float w, float h);
@ -90,14 +89,20 @@ struct Picture::Impl
delete(paint); delete(paint);
} }
RenderData update(RenderMethod* renderer, const Matrix* transform, Array<RenderData>& clips, uint8_t opacity, RenderUpdateFlag pFlag, bool clipper) RenderData update(RenderMethod* renderer, const Matrix& transform, Array<RenderData>& clips, uint8_t opacity, RenderUpdateFlag pFlag, bool clipper)
{ {
auto flag = static_cast<RenderUpdateFlag>(pFlag | load()); auto flag = static_cast<RenderUpdateFlag>(pFlag | load());
if (surface) { if (surface) {
if (flag == RenderUpdateFlag::None) return rd; 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) { } else if (paint) {
if (resizing) { if (resizing) {
loader->resize(paint, w, h); loader->resize(paint, w, h);

View file

@ -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) void RenderRegion::intersect(const RenderRegion& rhs)
{ {
auto x1 = x + w; auto x1 = x + w;

View file

@ -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 struct RenderStroke
{ {
@ -275,9 +260,9 @@ public:
uint32_t unref(); uint32_t unref();
virtual ~RenderMethod() {} virtual ~RenderMethod() {}
virtual RenderData prepare(const RenderShape& rshape, RenderData data, const Matrix* transform, Array<RenderData>& clips, uint8_t opacity, RenderUpdateFlag flags, bool clipper) = 0; virtual RenderData prepare(const RenderShape& rshape, RenderData data, const Matrix& transform, Array<RenderData>& clips, uint8_t opacity, RenderUpdateFlag flags, bool clipper) = 0;
virtual RenderData prepare(const Array<RenderData>& scene, RenderData data, const Matrix* transform, Array<RenderData>& clips, uint8_t opacity, RenderUpdateFlag flags) = 0; virtual RenderData prepare(const Array<RenderData>& scene, RenderData data, const Matrix& transform, Array<RenderData>& clips, uint8_t opacity, RenderUpdateFlag flags) = 0;
virtual RenderData prepare(Surface* surface, const RenderMesh* mesh, RenderData data, const Matrix* transform, Array<RenderData>& clips, uint8_t opacity, RenderUpdateFlag flags) = 0; virtual RenderData prepare(Surface* surface, const RenderMesh* mesh, RenderData data, const Matrix& transform, Array<RenderData>& clips, uint8_t opacity, RenderUpdateFlag flags) = 0;
virtual bool preRender() = 0; virtual bool preRender() = 0;
virtual bool renderShape(RenderData data) = 0; virtual bool renderShape(RenderData data) = 0;
virtual bool renderImage(RenderData data) = 0; virtual bool renderImage(RenderData data) = 0;

View file

@ -101,7 +101,7 @@ struct Scene::Impl
return true; return true;
} }
RenderData update(RenderMethod* renderer, const Matrix* transform, Array<RenderData>& clips, uint8_t opacity, RenderUpdateFlag flag, bool clipper) RenderData update(RenderMethod* renderer, const Matrix& transform, Array<RenderData>& clips, uint8_t opacity, RenderUpdateFlag flag, bool clipper)
{ {
if ((needComp = needComposition(opacity))) { if ((needComp = needComposition(opacity))) {
/* Overriding opacity value. If this scene is half-translucent, /* Overriding opacity value. If this scene is half-translucent,

View file

@ -96,7 +96,7 @@ struct Shape::Impl
return true; return true;
} }
RenderData update(RenderMethod* renderer, const Matrix* transform, Array<RenderData>& clips, uint8_t opacity, RenderUpdateFlag pFlag, bool clipper) RenderData update(RenderMethod* renderer, const Matrix& transform, Array<RenderData>& clips, uint8_t opacity, RenderUpdateFlag pFlag, bool clipper)
{ {
if (static_cast<RenderUpdateFlag>(pFlag | flag) == RenderUpdateFlag::None) return rd; if (static_cast<RenderUpdateFlag>(pFlag | flag) == RenderUpdateFlag::None) return rd;

View file

@ -120,7 +120,7 @@ struct Text::Impl
return false; return false;
} }
RenderData update(RenderMethod* renderer, const Matrix* transform, Array<RenderData>& clips, uint8_t opacity, RenderUpdateFlag pFlag, bool clipper) RenderData update(RenderMethod* renderer, const Matrix& transform, Array<RenderData>& clips, uint8_t opacity, RenderUpdateFlag pFlag, bool clipper)
{ {
if (!load()) return nullptr; if (!load()) return nullptr;

View file

@ -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); releaseMeshes(context);
strokeFirst = rshape.stroke ? rshape.stroke->strokeFirst : false; strokeFirst = rshape.stroke ? rshape.stroke->strokeFirst : false;
@ -310,10 +310,10 @@ void WgRenderDataShape::updateMeshes(WgContext &context, const RenderShape &rsha
polyline.close(); polyline.close();
} else if (cmd == PathCommand::CubicTo) { } else if (cmd == PathCommand::CubicTo) {
assert(polyline.pts.count > 0); assert(polyline.pts.count > 0);
WgPoint pt0 = polyline.pts.last().trans(*rt); WgPoint pt0 = polyline.pts.last().trans(rt);
WgPoint pt1 = WgPoint(rshape.path.pts[pntIndex + 0]).trans(*rt); WgPoint pt1 = WgPoint(rshape.path.pts[pntIndex + 0]).trans(rt);
WgPoint pt2 = WgPoint(rshape.path.pts[pntIndex + 1]).trans(*rt); WgPoint pt2 = WgPoint(rshape.path.pts[pntIndex + 1]).trans(rt);
WgPoint pt3 = WgPoint(rshape.path.pts[pntIndex + 2]).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)); uint32_t nsegs = (uint32_t)(pt0.dist(pt1) + pt1.dist(pt2) + pt2.dist(pt3));
polyline.appendCubic( polyline.appendCubic(
rshape.path.pts[pntIndex + 0], rshape.path.pts[pntIndex + 0],

View file

@ -112,7 +112,7 @@ struct WgRenderDataShape: public WgRenderDataPaint
FillRule fillRule{}; FillRule fillRule{};
void updateBBox(WgPoint pmin, WgPoint pmax); 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 updateMeshes(WgContext& context, const WgPolyline* polyline, const RenderStroke* rstroke);
void releaseMeshes(WgContext& context); void releaseMeshes(WgContext& context);
void release(WgContext& context) override; void release(WgContext& context) override;

View file

@ -93,7 +93,7 @@ void WgRenderer::clearDisposes()
/* External Class Implementation */ /* External Class Implementation */
/************************************************************************/ /************************************************************************/
RenderData WgRenderer::prepare(const RenderShape& rshape, RenderData data, const Matrix* transform, Array<RenderData>& clips, uint8_t opacity, RenderUpdateFlag flags, bool clipper) RenderData WgRenderer::prepare(const RenderShape& rshape, RenderData data, const Matrix& transform, Array<RenderData>& clips, uint8_t opacity, RenderUpdateFlag flags, bool clipper)
{ {
// get or create render data shape // get or create render data shape
auto renderDataShape = (WgRenderDataShape*)data; auto renderDataShape = (WgRenderDataShape*)data;
@ -127,13 +127,13 @@ RenderData WgRenderer::prepare(const RenderShape& rshape, RenderData data, const
} }
RenderData WgRenderer::prepare(TVG_UNUSED const Array<RenderData>& scene, TVG_UNUSED RenderData data, TVG_UNUSED const Matrix* transform, TVG_UNUSED Array<RenderData>& clips, TVG_UNUSED uint8_t opacity, TVG_UNUSED RenderUpdateFlag flags) RenderData WgRenderer::prepare(TVG_UNUSED const Array<RenderData>& scene, TVG_UNUSED RenderData data, TVG_UNUSED const Matrix& transform, TVG_UNUSED Array<RenderData>& clips, TVG_UNUSED uint8_t opacity, TVG_UNUSED RenderUpdateFlag flags)
{ {
return nullptr; return nullptr;
} }
RenderData WgRenderer::prepare(Surface* surface, const RenderMesh* mesh, RenderData data, const Matrix* transform, Array<RenderData>& clips, uint8_t opacity, RenderUpdateFlag flags) RenderData WgRenderer::prepare(Surface* surface, const RenderMesh* mesh, RenderData data, const Matrix& transform, Array<RenderData>& clips, uint8_t opacity, RenderUpdateFlag flags)
{ {
// get or create render data shape // get or create render data shape
auto renderDataPicture = (WgRenderDataPicture*)data; auto renderDataPicture = (WgRenderDataPicture*)data;

View file

@ -28,9 +28,9 @@
class WgRenderer : public RenderMethod class WgRenderer : public RenderMethod
{ {
public: public:
RenderData prepare(const RenderShape& rshape, RenderData data, const Matrix* transform, Array<RenderData>& clips, uint8_t opacity, RenderUpdateFlag flags, bool clipper) override; RenderData prepare(const RenderShape& rshape, RenderData data, const Matrix& transform, Array<RenderData>& clips, uint8_t opacity, RenderUpdateFlag flags, bool clipper) override;
RenderData prepare(const Array<RenderData>& scene, RenderData data, const Matrix* transform, Array<RenderData>& clips, uint8_t opacity, RenderUpdateFlag flags) override; RenderData prepare(const Array<RenderData>& scene, RenderData data, const Matrix& transform, Array<RenderData>& clips, uint8_t opacity, RenderUpdateFlag flags) override;
RenderData prepare(Surface* surface, const RenderMesh* mesh, RenderData data, const Matrix* transform, Array<RenderData>& clips, uint8_t opacity, RenderUpdateFlag flags) override; RenderData prepare(Surface* surface, const RenderMesh* mesh, RenderData data, const Matrix& transform, Array<RenderData>& clips, uint8_t opacity, RenderUpdateFlag flags) override;
bool preRender() override; bool preRender() override;
bool renderShape(RenderData data) override; bool renderShape(RenderData data) override;
bool renderImage(RenderData data) override; bool renderImage(RenderData data) override;

View file

@ -32,7 +32,7 @@ WgShaderTypeMat4x4f::WgShaderTypeMat4x4f()
} }
WgShaderTypeMat4x4f::WgShaderTypeMat4x4f(const Matrix* transform) WgShaderTypeMat4x4f::WgShaderTypeMat4x4f(const Matrix& transform)
{ {
update(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[0] = transform->e11; mat[1] = transform.e21;
mat[1] = transform->e21; mat[2] = 0.0f;
mat[2] = 0.0f; mat[3] = transform.e31;
mat[3] = transform->e31; mat[4] = transform.e12;
mat[4] = transform->e12; mat[5] = transform.e22;
mat[5] = transform->e22; mat[6] = 0.0f;
mat[6] = 0.0f; mat[7] = transform.e32;
mat[7] = transform->e32; mat[8] = 0.0f;
mat[8] = 0.0f; mat[9] = 0.0f;
mat[9] = 0.0f; mat[10] = 1.0f;
mat[10] = 1.0f; mat[11] = 0.0f;
mat[11] = 0.0f; mat[12] = transform.e13;
mat[12] = transform->e13; mat[13] = transform.e23;
mat[13] = transform->e23; mat[14] = 0.0f;
mat[14] = 0.0f; mat[15] = transform.e33;
mat[15] = transform->e33;
};
} }

View file

@ -35,10 +35,10 @@ struct WgShaderTypeMat4x4f
float mat[16]{}; float mat[16]{};
WgShaderTypeMat4x4f(); WgShaderTypeMat4x4f();
WgShaderTypeMat4x4f(const Matrix* transform); WgShaderTypeMat4x4f(const Matrix& transform);
WgShaderTypeMat4x4f(size_t w, size_t h); WgShaderTypeMat4x4f(size_t w, size_t h);
void identity(); void identity();
void update(const Matrix* transform); void update(const Matrix& transform);
void update(size_t w, size_t h); void update(size_t w, size_t h);
}; };