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)
{
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);
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);
}

View file

@ -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<int>(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);

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;
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)) {

View file

@ -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();

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;
@ -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:
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 (clipper) flags = RenderUpdateFlag::Path;

View file

@ -53,9 +53,9 @@ public:
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 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(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(Surface* surface, const RenderMesh* mesh, RenderData data, const Matrix& transform, Array<RenderData>& clips, uint8_t opacity, RenderUpdateFlag flags) override;
bool preRender() override;
bool renderShape(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);
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);

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;
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,13 +287,11 @@ 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;
if (isTransformation) gradTransform = transform * gradTransform;
else {
gradTransform = *transform;
gradTransform = transform;
isTransformation = true;
}
}
if (isTransformation) {
Matrix invTransform;
@ -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;

View file

@ -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<int32_t>(nearbyint(transform->e13));
image->oy = -static_cast<int32_t>(nearbyint(transform->e23));
image->ox = -static_cast<int32_t>(nearbyint(transform.e13));
image->oy = -static_cast<int32_t>(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;
}

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)};
}

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)) {
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<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
*/
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;

View file

@ -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<RenderData> 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<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 (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<Matrix*>(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<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
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
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
auto task = static_cast<SwShapeTask*>(data);

View file

@ -36,9 +36,9 @@ namespace tvg
class SwRenderer : public RenderMethod
{
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 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(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(Surface* surface, const RenderMesh* mesh, RenderData data, const Matrix& transform, Array<RenderData>& 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<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.
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<SwStroke*>(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);
}

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->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<SwFixed>(rshape->strokeMiterlimit() * 65536.0f);

View file

@ -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;

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
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<Shape*>(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->tr = tr;
ret->pImpl->renderFlag |= RenderUpdateFlag::Transform;
} else {
delete(ret->pImpl->rTransform);
ret->pImpl->rTransform = nullptr;
}
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<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) 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;
}
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, Array<R
opacity = MULTIPLY(opacity, this->opacity);
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, Array<R
bool Paint::Impl::bounds(float* x, float* y, float* w, float* h, bool transformed, bool stroking)
{
Matrix* m = nullptr;
bool ret;
const auto& m = this->transform();
//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();
}

View file

@ -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<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);
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)
{
//Same resource has been loaded.

View file

@ -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<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());
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);

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)
{
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
{
@ -275,9 +260,9 @@ public:
uint32_t unref();
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 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(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(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 renderShape(RenderData data) = 0;
virtual bool renderImage(RenderData data) = 0;

View file

@ -101,7 +101,7 @@ struct Scene::Impl
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))) {
/* Overriding opacity value. If this scene is half-translucent,

View file

@ -96,7 +96,7 @@ struct Shape::Impl
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;

View file

@ -120,7 +120,7 @@ struct Text::Impl
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;

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);
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],

View file

@ -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;

View file

@ -93,7 +93,7 @@ void WgRenderer::clearDisposes()
/* 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
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;
}
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
auto renderDataPicture = (WgRenderDataPicture*)data;

View file

@ -28,9 +28,9 @@
class WgRenderer : public RenderMethod
{
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 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(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(Surface* surface, const RenderMesh* mesh, RenderData data, const Matrix& transform, Array<RenderData>& clips, uint8_t opacity, RenderUpdateFlag flags) override;
bool preRender() override;
bool renderShape(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);
}
@ -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[0] = transform.e11;
mat[1] = transform.e21;
mat[2] = 0.0f;
mat[3] = transform->e31;
mat[4] = transform->e12;
mat[5] = transform->e22;
mat[3] = transform.e31;
mat[4] = transform.e12;
mat[5] = transform.e22;
mat[6] = 0.0f;
mat[7] = transform->e32;
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[12] = transform.e13;
mat[13] = transform.e23;
mat[14] = 0.0f;
mat[15] = transform->e33;
};
mat[15] = transform.e33;
}

View file

@ -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);
};