common engine: code refactoring

Introduce the RenderMesh structure to reduce the number of required parameters.
This commit is contained in:
Hermet Park 2023-04-26 18:46:13 +09:00
parent 6d08586883
commit 84012651cc
12 changed files with 68 additions and 59 deletions

View file

@ -1239,15 +1239,15 @@ public:
* @param[in] triangles An array of Polygons(triangles) that make up the mesh, or null to remove the mesh. * @param[in] triangles An array of Polygons(triangles) that make up the mesh, or null to remove the mesh.
* @param[in] triangleCnt The number of Polygons(triangles) provided, or 0 to remove the mesh. * @param[in] triangleCnt The number of Polygons(triangles) provided, or 0 to remove the mesh.
* *
* @retval Result::Success When succeed. * @return Result::Success When succeed.
* @retval Result::Unknown If fails * @return Result::Unknown If fails
* *
* @note The Polygons are copied internally, so modifying them after calling Mesh::mesh has no affect. * @note The Polygons are copied internally, so modifying them after calling Mesh::mesh has no affect.
* @warning Please do not use it, this API is not official one. It could be modified in the next version. * @warning Please do not use it, this API is not official one. It could be modified in the next version.
* *
* @BETA_API * @BETA_API
*/ */
Result mesh(const Polygon* triangles, const uint32_t triangleCnt) noexcept; Result mesh(const Polygon* triangles, uint32_t triangleCnt) noexcept;
/** /**
* @brief Return the number of triangles in the mesh, and optionally get a pointer to the array of triangles in the mesh. * @brief Return the number of triangles in the mesh, and optionally get a pointer to the array of triangles in the mesh.

View file

@ -189,7 +189,7 @@ bool GlRenderer::dispose(RenderData data)
} }
RenderData GlRenderer::prepare(TVG_UNUSED Surface* image, TVG_UNUSED Polygon* triangles, TVG_UNUSED uint32_t triangleCnt, TVG_UNUSED RenderData data, TVG_UNUSED const RenderTransform* transform, TVG_UNUSED uint32_t opacity, TVG_UNUSED Array<RenderData>& clips, TVG_UNUSED RenderUpdateFlag flags) RenderData GlRenderer::prepare(TVG_UNUSED Surface* image, TVG_UNUSED const RenderMesh* mesh, TVG_UNUSED RenderData data, TVG_UNUSED const RenderTransform* transform, TVG_UNUSED uint32_t opacity, TVG_UNUSED Array<RenderData>& clips, TVG_UNUSED RenderUpdateFlag flags)
{ {
//TODO: //TODO:
return nullptr; return nullptr;

View file

@ -32,7 +32,7 @@ public:
RenderData prepare(const RenderShape& rshape, RenderData data, const RenderTransform* transform, uint32_t opacity, Array<RenderData>& clips, RenderUpdateFlag flags, bool clipper) override; RenderData prepare(const RenderShape& rshape, RenderData data, const RenderTransform* transform, uint32_t opacity, Array<RenderData>& clips, RenderUpdateFlag flags, bool clipper) override;
RenderData prepare(const Array<RenderData>& scene, RenderData data, const RenderTransform* transform, uint32_t opacity, Array<RenderData>& clips, RenderUpdateFlag flags) override; RenderData prepare(const Array<RenderData>& scene, RenderData data, const RenderTransform* transform, uint32_t opacity, Array<RenderData>& clips, RenderUpdateFlag flags) override;
RenderData prepare(Surface* image, Polygon* triangles, uint32_t triangleCnt, RenderData data, const RenderTransform* transform, uint32_t opacity, Array<RenderData>& clips, RenderUpdateFlag flags) override; RenderData prepare(Surface* image, const RenderMesh* mesh, RenderData data, const RenderTransform* transform, uint32_t opacity, Array<RenderData>& clips, 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

@ -322,7 +322,7 @@ 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, Polygon* triangles, uint32_t triangleCount, 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);
@ -353,7 +353,7 @@ void mpoolRetStrokeOutline(SwMpool* mpool, unsigned idx);
bool rasterCompositor(SwSurface* surface); bool rasterCompositor(SwSurface* surface);
bool rasterGradientShape(SwSurface* surface, SwShape* shape, unsigned id); bool rasterGradientShape(SwSurface* surface, SwShape* shape, unsigned id);
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 Polygon* triangles, uint32_t triangleCount, const Matrix* transform, const SwBBox& bbox, uint32_t opacity); bool rasterImage(SwSurface* surface, SwImage* image, const RenderMesh* mesh, const Matrix* transform, const SwBBox& bbox, uint32_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, unsigned id); bool rasterGradientStroke(SwSurface* surface, SwShape* shape, unsigned id);
bool rasterClear(SwSurface* surface); bool rasterClear(SwSurface* surface);

View file

@ -34,7 +34,7 @@ static inline bool _onlyShifted(const Matrix* m)
} }
static bool _genOutline(SwImage* image, Polygon* triangles, uint32_t triangleCount, 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;
@ -53,7 +53,7 @@ static bool _genOutline(SwImage* image, Polygon* triangles, uint32_t triangleCou
} }
Point to[4]; Point to[4];
if (triangleCount > 0) { if (mesh->triangleCnt > 0) {
// TODO: Optimise me. We appear to calculate this exact min/max bounding area in multiple // TODO: Optimise me. We appear to calculate this exact min/max bounding area in multiple
// places. We should be able to re-use one we have already done? Also see: // places. We should be able to re-use one we have already done? Also see:
// tvgPictureImpl.h --> bounds // tvgPictureImpl.h --> bounds
@ -63,10 +63,11 @@ static bool _genOutline(SwImage* image, Polygon* triangles, uint32_t triangleCou
// i.e. copy tvgSwShape.capp -> _genOutline? // i.e. copy tvgSwShape.capp -> _genOutline?
// //
// TODO: Cntrs? // TODO: Cntrs?
Point min = { triangles[0].vertex[0].pt.x, triangles[0].vertex[0].pt.y }; auto triangles = mesh->triangles;
Point max = { triangles[0].vertex[0].pt.x, triangles[0].vertex[0].pt.y }; auto min = triangles[0].vertex[0].pt;
auto max = triangles[0].vertex[0].pt;
for (uint32_t i = 0; i < triangleCount; ++i) { for (uint32_t i = 0; i < mesh->triangleCnt; ++i) {
if (triangles[i].vertex[0].pt.x < min.x) min.x = triangles[i].vertex[0].pt.x; if (triangles[i].vertex[0].pt.x < min.x) min.x = triangles[i].vertex[0].pt.x;
else if (triangles[i].vertex[0].pt.x > max.x) max.x = triangles[i].vertex[0].pt.x; else if (triangles[i].vertex[0].pt.x > max.x) max.x = triangles[i].vertex[0].pt.x;
if (triangles[i].vertex[0].pt.y < min.y) min.y = triangles[i].vertex[0].pt.y; if (triangles[i].vertex[0].pt.y < min.y) min.y = triangles[i].vertex[0].pt.y;
@ -82,7 +83,6 @@ static bool _genOutline(SwImage* image, Polygon* triangles, uint32_t triangleCou
if (triangles[i].vertex[2].pt.y < min.y) min.y = triangles[i].vertex[2].pt.y; if (triangles[i].vertex[2].pt.y < min.y) min.y = triangles[i].vertex[2].pt.y;
else if (triangles[i].vertex[2].pt.y > max.y) max.y = triangles[i].vertex[2].pt.y; else if (triangles[i].vertex[2].pt.y > max.y) max.y = triangles[i].vertex[2].pt.y;
} }
to[0] = {min.x, min.y}; to[0] = {min.x, min.y};
to[1] = {max.x, min.y}; to[1] = {max.x, min.y};
to[2] = {max.x, max.y}; to[2] = {max.x, max.y};
@ -95,6 +95,7 @@ static bool _genOutline(SwImage* image, Polygon* triangles, uint32_t triangleCou
to[2] = {w, h}; to[2] = {w, h};
to[3] = {0, h}; to[3] = {0, h};
} }
for (int i = 0; i < 4; i++) { for (int i = 0; i < 4; i++) {
outline->pts[outline->ptsCnt] = mathTransform(&to[i], transform); outline->pts[outline->ptsCnt] = mathTransform(&to[i], transform);
outline->types[outline->ptsCnt] = SW_CURVE_TYPE_POINT; outline->types[outline->ptsCnt] = SW_CURVE_TYPE_POINT;
@ -118,7 +119,7 @@ static bool _genOutline(SwImage* image, Polygon* triangles, uint32_t triangleCou
/* External Class Implementation */ /* External Class Implementation */
/************************************************************************/ /************************************************************************/
bool imagePrepare(SwImage* image, Polygon* triangles, uint32_t triangleCount, 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);
@ -136,7 +137,7 @@ bool imagePrepare(SwImage* image, Polygon* triangles, uint32_t triangleCount, co
else image->scaled = false; else image->scaled = false;
} }
if (!_genOutline(image, triangles, triangleCount, transform, mpool, tid)) return false; if (!_genOutline(image, mesh, transform, mpool, tid)) return false;
return mathUpdateOutlineBBox(image->outline, clipRegion, renderRegion, image->direct); return mathUpdateOutlineBBox(image->outline, clipRegion, renderRegion, image->direct);
} }

View file

@ -687,18 +687,18 @@ static bool _transformedRGBAImage(SwSurface* surface, const SwImage* image, cons
return false; return false;
} }
static bool _transformedRGBAImageMesh(SwSurface* surface, const SwImage* image, const Polygon* triangles, const uint32_t count, const Matrix* transform, const SwBBox* region, uint32_t opacity) static bool _transformedRGBAImageMesh(SwSurface* surface, const SwImage* image, const RenderMesh* mesh, const Matrix* transform, const SwBBox* region, uint32_t opacity)
{ {
if (_compositing(surface)) { if (_compositing(surface)) {
if (surface->compositor->method == CompositeMethod::AlphaMask) { if (surface->compositor->method == CompositeMethod::AlphaMask) {
return _rasterTexmapPolygonMesh(surface, image, triangles, count, transform, region, opacity, _alpha); return _rasterTexmapPolygonMesh(surface, image, mesh, transform, region, opacity, _alpha);
} else if (surface->compositor->method == CompositeMethod::InvAlphaMask) { } else if (surface->compositor->method == CompositeMethod::InvAlphaMask) {
return _rasterTexmapPolygonMesh(surface, image, triangles, count, transform, region, opacity, _ialpha); return _rasterTexmapPolygonMesh(surface, image, mesh, transform, region, opacity, _ialpha);
} else if (surface->compositor->method == CompositeMethod::LumaMask) { } else if (surface->compositor->method == CompositeMethod::LumaMask) {
return _rasterTexmapPolygonMesh(surface, image, triangles, count, transform, region, opacity, surface->blender.lumaValue); return _rasterTexmapPolygonMesh(surface, image, mesh, transform, region, opacity, surface->blender.lumaValue);
} }
} else { } else {
return _rasterTexmapPolygonMesh(surface, image, triangles, count, transform, region, opacity, nullptr); return _rasterTexmapPolygonMesh(surface, image, mesh, transform, region, opacity, nullptr);
} }
return false; return false;
} }
@ -1561,7 +1561,7 @@ bool rasterStroke(SwSurface* surface, SwShape* shape, uint8_t r, uint8_t g, uint
} }
bool rasterImage(SwSurface* surface, SwImage* image, const Polygon* triangles, uint32_t triangleCnt, const Matrix* transform, const SwBBox& bbox, uint32_t opacity) bool rasterImage(SwSurface* surface, SwImage* image, const RenderMesh* mesh, const Matrix* transform, const SwBBox& bbox, uint32_t opacity)
{ {
//Verify Boundary //Verify Boundary
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 false; 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 false;
@ -1570,6 +1570,6 @@ bool rasterImage(SwSurface* surface, SwImage* image, const Polygon* triangles, u
//TODO: case: _rasterRGBImageMesh() //TODO: case: _rasterRGBImageMesh()
//TODO: case: _rasterGrayscaleImageMesh() //TODO: case: _rasterGrayscaleImageMesh()
//TODO: case: _rasterAlphaImageMesh() //TODO: case: _rasterAlphaImageMesh()
if (triangles) return _transformedRGBAImageMesh(surface, image, triangles, triangleCnt, transform, &bbox, opacity); if (mesh && mesh->triangleCnt > 0) return _transformedRGBAImageMesh(surface, image, mesh, transform, &bbox, opacity);
else return _rasterRGBAImage(surface, image, transform, bbox, opacity); else return _rasterRGBAImage(surface, image, transform, bbox, opacity);
} }

View file

@ -602,16 +602,16 @@ 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 Polygon* triangles, const uint32_t triangleCount, const Matrix* transform, const SwBBox* region, uint32_t opacity, uint32_t (*blendMethod)(uint32_t)) static bool _rasterTexmapPolygonMesh(SwSurface* surface, const SwImage* image, const RenderMesh* mesh, const Matrix* transform, const SwBBox* region, uint32_t opacity, uint32_t (*blendMethod)(uint32_t))
{ {
//Exceptions: No dedicated drawing area? //Exceptions: No dedicated drawing area?
if ((!image->rle && !region) || (image->rle && image->rle->size == 0)) return false; if ((!image->rle && !region) || (image->rle && image->rle->size == 0)) return false;
// Step polygons once to transform // Step polygons once to transform
auto transformedTris = (Polygon*)malloc(sizeof(Polygon) * triangleCount); auto transformedTris = (Polygon*)malloc(sizeof(Polygon) * mesh->triangleCnt);
float ys = FLT_MAX, ye = -1.0f; float ys = FLT_MAX, ye = -1.0f;
for (uint32_t i = 0; i < triangleCount; i++) { for (uint32_t i = 0; i < mesh->triangleCnt; i++) {
transformedTris[i] = triangles[i]; transformedTris[i] = mesh->triangles[i];
mathMultiply(&transformedTris[i].vertex[0].pt, transform); mathMultiply(&transformedTris[i].vertex[0].pt, transform);
mathMultiply(&transformedTris[i].vertex[1].pt, transform); mathMultiply(&transformedTris[i].vertex[1].pt, transform);
mathMultiply(&transformedTris[i].vertex[2].pt, transform); mathMultiply(&transformedTris[i].vertex[2].pt, transform);
@ -635,7 +635,7 @@ static bool _rasterTexmapPolygonMesh(SwSurface* surface, const SwImage* image, c
// Get AA spans and step polygons again to draw // Get AA spans and step polygons again to draw
auto aaSpans = _AASpans(ys, ye, image, region); auto aaSpans = _AASpans(ys, ye, image, region);
if (aaSpans) { if (aaSpans) {
for (uint32_t i = 0; i < triangleCount; i++) { for (uint32_t i = 0; i < mesh->triangleCnt; i++) {
_rasterPolygonImage(surface, image, region, opacity, transformedTris[i], blendMethod, aaSpans); _rasterPolygonImage(surface, image, region, opacity, transformedTris[i], blendMethod, aaSpans);
} }
// Apply to surface (note: frees the AA spans) // Apply to surface (note: frees the AA spans)

View file

@ -258,8 +258,7 @@ struct SwSceneTask : SwTask
struct SwImageTask : SwTask struct SwImageTask : SwTask
{ {
SwImage image; SwImage image;
Polygon* triangles = nullptr; const RenderMesh* mesh = nullptr; //Should be valid ptr in action
uint32_t triangleCnt = 0;
bool clip(SwRleData* target) override bool clip(SwRleData* target) override
{ {
@ -282,10 +281,10 @@ struct SwImageTask : SwTask
imageReset(&image); imageReset(&image);
if (!image.data || image.w == 0 || image.h == 0) goto end; if (!image.data || image.w == 0 || image.h == 0) goto end;
if (!imagePrepare(&image, triangles, triangleCnt, transform, clipRegion, bbox, mpool, tid)) goto end; if (!imagePrepare(&image, mesh, transform, clipRegion, bbox, mpool, tid)) goto end;
// TODO: How do we clip the triangle mesh? Only clip non-meshed images for now // TODO: How do we clip the triangle mesh? Only clip non-meshed images for now
if (triangleCnt == 0 && clips.count > 0) { if (mesh->triangleCnt == 0 && clips.count > 0) {
if (!imageGenRle(&image, bbox, false)) goto end; if (!imageGenRle(&image, bbox, false)) goto end;
if (image.rle) { if (image.rle) {
for (auto clip = clips.data; clip < (clips.data + clips.count); ++clip) { for (auto clip = clips.data; clip < (clips.data + clips.count); ++clip) {
@ -469,7 +468,7 @@ bool SwRenderer::renderImage(RenderData data)
if (task->opacity == 0) return true; if (task->opacity == 0) return true;
return rasterImage(surface, &task->image, task->triangles, task->triangleCnt, task->transform, task->bbox, task->opacity); return rasterImage(surface, &task->image, task->mesh, task->transform, task->bbox, task->opacity);
} }
@ -651,7 +650,7 @@ 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, 0, nullptr, p->bbox, p->opacity); return rasterImage(surface, &p->image, nullptr, nullptr, p->bbox, p->opacity);
} }
return true; return true;
@ -710,7 +709,7 @@ void* SwRenderer::prepareCommon(SwTask* task, const RenderTransform* transform,
} }
RenderData SwRenderer::prepare(Surface* image, Polygon* triangles, uint32_t triangleCnt, RenderData data, const RenderTransform* transform, uint32_t opacity, Array<RenderData>& clips, RenderUpdateFlag flags) RenderData SwRenderer::prepare(Surface* image, const RenderMesh* mesh, RenderData data, const RenderTransform* transform, uint32_t opacity, Array<RenderData>& clips, RenderUpdateFlag flags)
{ {
//prepare task //prepare task
auto task = static_cast<SwImageTask*>(data); auto task = static_cast<SwImageTask*>(data);
@ -720,8 +719,7 @@ RenderData SwRenderer::prepare(Surface* image, Polygon* triangles, uint32_t tria
task->image.w = image->w; task->image.w = image->w;
task->image.h = image->h; task->image.h = image->h;
task->image.stride = image->stride; task->image.stride = image->stride;
task->triangles = triangles; task->mesh = mesh;
task->triangleCnt = triangleCnt;
} }
return prepareCommon(task, transform, opacity, clips, flags); return prepareCommon(task, transform, opacity, clips, flags);
} }

View file

@ -38,7 +38,7 @@ class SwRenderer : public RenderMethod
public: public:
RenderData prepare(const RenderShape& rshape, RenderData data, const RenderTransform* transform, uint32_t opacity, Array<RenderData>& clips, RenderUpdateFlag flags, bool clipper) override; RenderData prepare(const RenderShape& rshape, RenderData data, const RenderTransform* transform, uint32_t opacity, Array<RenderData>& clips, RenderUpdateFlag flags, bool clipper) override;
RenderData prepare(const Array<RenderData>& scene, RenderData data, const RenderTransform* transform, uint32_t opacity, Array<RenderData>& clips, RenderUpdateFlag flags) override; RenderData prepare(const Array<RenderData>& scene, RenderData data, const RenderTransform* transform, uint32_t opacity, Array<RenderData>& clips, RenderUpdateFlag flags) override;
RenderData prepare(Surface* image, Polygon* triangles, uint32_t triangleCnt, RenderData data, const RenderTransform* transform, uint32_t opacity, Array<RenderData>& clips, RenderUpdateFlag flags) override; RenderData prepare(Surface* image, const RenderMesh* mesh, RenderData data, const RenderTransform* transform, uint32_t opacity, Array<RenderData>& clips, 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

@ -121,7 +121,7 @@ const uint32_t* Picture::data(uint32_t* w, uint32_t* h) const noexcept
} }
Result Picture::mesh(const Polygon* triangles, const uint32_t triangleCnt) noexcept Result Picture::mesh(const Polygon* triangles, uint32_t triangleCnt) noexcept
{ {
if (!triangles && triangleCnt > 0) return Result::InvalidArguments; if (!triangles && triangleCnt > 0) return Result::InvalidArguments;
if (triangles && triangleCnt == 0) return Result::InvalidArguments; if (triangles && triangleCnt == 0) return Result::InvalidArguments;
@ -133,6 +133,6 @@ Result Picture::mesh(const Polygon* triangles, const uint32_t triangleCnt) noexc
uint32_t Picture::mesh(const Polygon** triangles) const noexcept uint32_t Picture::mesh(const Polygon** triangles) const noexcept
{ {
if (triangles) *triangles = pImpl->triangles; if (triangles) *triangles = pImpl->rm.triangles;
return pImpl->triangleCnt; return pImpl->rm.triangleCnt;
} }

View file

@ -64,17 +64,15 @@ struct Picture::Impl
Paint* paint = nullptr; //vector picture uses Paint* paint = nullptr; //vector picture uses
Surface* surface = nullptr; //bitmap picture uses Surface* surface = nullptr; //bitmap picture uses
Polygon* triangles = nullptr; //mesh data
uint32_t triangleCnt = 0; //mesh triangle count
RenderData rd = nullptr; //engine data RenderData rd = nullptr; //engine data
float w = 0, h = 0; float w = 0, h = 0;
uint32_t rendererColorSpace = 0; uint32_t rendererColorSpace = 0;
RenderMesh rm; //mesh data
bool resizing = false; bool resizing = false;
~Impl() ~Impl()
{ {
if (paint) delete(paint); if (paint) delete(paint);
free(triangles);
free(surface); free(surface);
} }
@ -136,7 +134,7 @@ struct Picture::Impl
if (surface) { if (surface) {
auto transform = resizeTransform(pTransform); auto transform = resizeTransform(pTransform);
rd = renderer.prepare(surface, triangles, triangleCnt, rd, &transform, opacity, clips, static_cast<RenderUpdateFlag>(pFlag | flag)); rd = renderer.prepare(surface, &rm, rd, &transform, opacity, clips, static_cast<RenderUpdateFlag>(pFlag | flag));
} else if (paint) { } else if (paint) {
if (resizing) { if (resizing) {
loader->resize(paint, w, h); loader->resize(paint, w, h);
@ -174,11 +172,12 @@ struct Picture::Impl
bool bounds(float* x, float* y, float* w, float* h) bool bounds(float* x, float* y, float* w, float* h)
{ {
if (triangleCnt > 0) { if (rm.triangleCnt > 0) {
Point min = { triangles[0].vertex[0].pt.x, triangles[0].vertex[0].pt.y }; auto triangles = rm.triangles;
Point max = { triangles[0].vertex[0].pt.x, triangles[0].vertex[0].pt.y }; auto min = triangles[0].vertex[0].pt;
auto max = triangles[0].vertex[0].pt;
for (uint32_t i = 0; i < triangleCnt; ++i) { for (uint32_t i = 0; i < rm.triangleCnt; ++i) {
if (triangles[i].vertex[0].pt.x < min.x) min.x = triangles[i].vertex[0].pt.x; if (triangles[i].vertex[0].pt.x < min.x) min.x = triangles[i].vertex[0].pt.x;
else if (triangles[i].vertex[0].pt.x > max.x) max.x = triangles[i].vertex[0].pt.x; else if (triangles[i].vertex[0].pt.x > max.x) max.x = triangles[i].vertex[0].pt.x;
if (triangles[i].vertex[0].pt.y < min.y) min.y = triangles[i].vertex[0].pt.y; if (triangles[i].vertex[0].pt.y < min.y) min.y = triangles[i].vertex[0].pt.y;
@ -256,13 +255,13 @@ struct Picture::Impl
void mesh(const Polygon* triangles, const uint32_t triangleCnt) void mesh(const Polygon* triangles, const uint32_t triangleCnt)
{ {
if (triangles && triangleCnt > 0) { if (triangles && triangleCnt > 0) {
this->triangleCnt = triangleCnt; this->rm.triangleCnt = triangleCnt;
this->triangles = (Polygon*)malloc(sizeof(Polygon) * triangleCnt); this->rm.triangles = (Polygon*)malloc(sizeof(Polygon) * triangleCnt);
memcpy(this->triangles, triangles, sizeof(Polygon) * triangleCnt); memcpy(this->rm.triangles, triangles, sizeof(Polygon) * triangleCnt);
} else { } else {
free(this->triangles); free(this->rm.triangles);
this->triangles = nullptr; this->rm.triangles = nullptr;
this->triangleCnt = 0; this->rm.triangleCnt = 0;
} }
} }
@ -284,10 +283,10 @@ struct Picture::Impl
dup->h = h; dup->h = h;
dup->resizing = resizing; dup->resizing = resizing;
if (triangleCnt > 0) { if (rm.triangleCnt > 0) {
dup->triangleCnt = triangleCnt; dup->rm.triangleCnt = rm.triangleCnt;
dup->triangles = (Polygon*)malloc(sizeof(Polygon) * triangleCnt); dup->rm.triangles = (Polygon*)malloc(sizeof(Polygon) * rm.triangleCnt);
memcpy(dup->triangles, triangles, sizeof(Polygon) * triangleCnt); memcpy(dup->rm.triangles, rm.triangles, sizeof(Polygon) * rm.triangleCnt);
} }
return ret.release(); return ret.release();

View file

@ -48,6 +48,17 @@ struct Compositor
uint32_t opacity; uint32_t opacity;
}; };
struct RenderMesh
{
Polygon* triangles = nullptr;
uint32_t triangleCnt = 0;
~RenderMesh()
{
free(triangles);
}
};
struct RenderRegion struct RenderRegion
{ {
int32_t x, y, w, h; int32_t x, y, w, h;
@ -188,7 +199,7 @@ public:
virtual ~RenderMethod() {} virtual ~RenderMethod() {}
virtual RenderData prepare(const RenderShape& rshape, RenderData data, const RenderTransform* transform, uint32_t opacity, Array<RenderData>& clips, RenderUpdateFlag flags, bool clipper) = 0; virtual RenderData prepare(const RenderShape& rshape, RenderData data, const RenderTransform* transform, uint32_t opacity, Array<RenderData>& clips, RenderUpdateFlag flags, bool clipper) = 0;
virtual RenderData prepare(const Array<RenderData>& scene, RenderData data, const RenderTransform* transform, uint32_t opacity, Array<RenderData>& clips, RenderUpdateFlag flags) = 0; virtual RenderData prepare(const Array<RenderData>& scene, RenderData data, const RenderTransform* transform, uint32_t opacity, Array<RenderData>& clips, RenderUpdateFlag flags) = 0;
virtual RenderData prepare(Surface* image, Polygon* triangles, uint32_t triangleCnt, RenderData data, const RenderTransform* transform, uint32_t opacity, Array<RenderData>& clips, RenderUpdateFlag flags) = 0; virtual RenderData prepare(Surface* image, const RenderMesh* mesh, RenderData data, const RenderTransform* transform, uint32_t opacity, Array<RenderData>& clips, 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;