mirror of
https://github.com/thorvg/thorvg.git
synced 2025-06-08 13:43:43 +00:00
sw_engine renderer: optimize composition data usage.
Use cache mechanism for composition data so that we don't reallocate composition memory several times in one frame rendering. @Issues: 168
This commit is contained in:
parent
1523446a20
commit
e3eff97fac
2 changed files with 58 additions and 35 deletions
|
@ -30,11 +30,12 @@
|
||||||
static bool initEngine = false;
|
static bool initEngine = false;
|
||||||
static uint32_t rendererCnt = 0;
|
static uint32_t rendererCnt = 0;
|
||||||
|
|
||||||
struct CompositeCtx
|
struct SwComposite
|
||||||
{
|
{
|
||||||
SwSurface surface;
|
SwSurface surface;
|
||||||
SwSurface* recover;
|
SwSurface* recover;
|
||||||
SwImage image;
|
SwImage image;
|
||||||
|
bool valid;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -262,6 +263,13 @@ bool SwRenderer::postRender()
|
||||||
{
|
{
|
||||||
tasks.clear();
|
tasks.clear();
|
||||||
|
|
||||||
|
//Free Composite Caches
|
||||||
|
for (auto comp = composites.data; comp < (composites.data + composites.count); ++comp) {
|
||||||
|
free((*comp)->image.data);
|
||||||
|
delete(*comp);
|
||||||
|
}
|
||||||
|
composites.reset();
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -277,16 +285,31 @@ bool SwRenderer::render(TVG_UNUSED const Picture& picture, void *data)
|
||||||
|
|
||||||
void* SwRenderer::beginComposite(uint32_t x, uint32_t y, uint32_t w, uint32_t h)
|
void* SwRenderer::beginComposite(uint32_t x, uint32_t y, uint32_t w, uint32_t h)
|
||||||
{
|
{
|
||||||
auto ctx = new CompositeCtx;
|
SwComposite* comp = nullptr;
|
||||||
if (!ctx) return nullptr;
|
|
||||||
|
|
||||||
//SwImage, Optimize Me: Surface size from MainSurface(WxH) to Parameter W x H
|
//Use cached data
|
||||||
ctx->image.data = (uint32_t*) malloc(sizeof(uint32_t) * surface->w * surface->h);
|
for (auto p = composites.data; p < (composites.data + composites.count); ++p) {
|
||||||
if (!ctx->image.data) {
|
if ((*p)->valid) {
|
||||||
delete(ctx);
|
comp = *p;
|
||||||
return nullptr;
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//New Composition
|
||||||
|
if (!comp) {
|
||||||
|
comp = new SwComposite;
|
||||||
|
if (!comp) return nullptr;
|
||||||
|
//SwImage, Optimize Me: Surface size from MainSurface(WxH) to Parameter W x H
|
||||||
|
comp->image.data = (uint32_t*) malloc(sizeof(uint32_t) * surface->w * surface->h);
|
||||||
|
if (!comp->image.data) {
|
||||||
|
delete(comp);
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
composites.push(comp);
|
||||||
|
}
|
||||||
|
|
||||||
|
comp->valid = false;
|
||||||
|
|
||||||
//Boundary Check
|
//Boundary Check
|
||||||
if (x < 0) x = 0;
|
if (x < 0) x = 0;
|
||||||
if (y < 0) y = 0;
|
if (y < 0) y = 0;
|
||||||
|
@ -299,51 +322,49 @@ void* SwRenderer::beginComposite(uint32_t x, uint32_t y, uint32_t w, uint32_t h)
|
||||||
w = surface->w;
|
w = surface->w;
|
||||||
h = surface->h;
|
h = surface->h;
|
||||||
|
|
||||||
ctx->image.bbox.min.x = x;
|
comp->image.bbox.min.x = x;
|
||||||
ctx->image.bbox.min.y = y;
|
comp->image.bbox.min.y = y;
|
||||||
ctx->image.bbox.max.x = x + w;
|
comp->image.bbox.max.x = x + w;
|
||||||
ctx->image.bbox.max.y = y + h;
|
comp->image.bbox.max.y = y + h;
|
||||||
ctx->image.w = surface->w;
|
comp->image.w = surface->w;
|
||||||
ctx->image.h = surface->h;
|
comp->image.h = surface->h;
|
||||||
|
|
||||||
//Inherits attributes from main surface
|
//Inherits attributes from main surface
|
||||||
ctx->surface.comp = surface->comp;
|
comp->surface.comp = surface->comp;
|
||||||
ctx->surface.stride = surface->w;
|
comp->surface.stride = surface->w;
|
||||||
ctx->surface.cs = surface->cs;
|
comp->surface.cs = surface->cs;
|
||||||
|
|
||||||
//We know partial clear region
|
//We know partial clear region
|
||||||
ctx->surface.buffer = ctx->image.data + (ctx->surface.stride * y + x);
|
comp->surface.buffer = comp->image.data + (comp->surface.stride * y + x);
|
||||||
ctx->surface.w = w;
|
comp->surface.w = w;
|
||||||
ctx->surface.h = h;
|
comp->surface.h = h;
|
||||||
|
|
||||||
rasterClear(&ctx->surface);
|
rasterClear(&comp->surface);
|
||||||
|
|
||||||
//Recover context
|
//Recover context
|
||||||
ctx->surface.buffer = ctx->image.data;
|
comp->surface.buffer = comp->image.data;
|
||||||
ctx->surface.w = ctx->image.w;
|
comp->surface.w = comp->image.w;
|
||||||
ctx->surface.h = ctx->image.h;
|
comp->surface.h = comp->image.h;
|
||||||
|
|
||||||
//Switch render target
|
//Switch render target
|
||||||
ctx->recover = surface;
|
comp->recover = surface;
|
||||||
surface = &ctx->surface;
|
surface = &comp->surface;
|
||||||
|
|
||||||
return ctx;
|
return comp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool SwRenderer::endComposite(void* p, uint32_t opacity)
|
bool SwRenderer::endComposite(void* p, uint32_t opacity)
|
||||||
{
|
{
|
||||||
if (!p) return false;
|
if (!p) return false;
|
||||||
auto ctx = static_cast<CompositeCtx*>(p);
|
auto comp = static_cast<SwComposite*>(p);
|
||||||
|
|
||||||
//Recover render target
|
//Recover render target
|
||||||
surface = ctx->recover;
|
surface = comp->recover;
|
||||||
|
|
||||||
auto ret = rasterImage(surface, &ctx->image, nullptr, opacity);
|
auto ret = rasterImage(surface, &comp->image, nullptr, opacity);
|
||||||
|
|
||||||
//Free resources
|
comp->valid = true;
|
||||||
free(ctx->image.data);
|
|
||||||
delete(ctx);
|
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,6 +28,7 @@ struct SwSurface;
|
||||||
struct SwTask;
|
struct SwTask;
|
||||||
struct SwShapeTask;
|
struct SwShapeTask;
|
||||||
struct SwImage;
|
struct SwImage;
|
||||||
|
struct SwComposite;
|
||||||
|
|
||||||
namespace tvg
|
namespace tvg
|
||||||
{
|
{
|
||||||
|
@ -53,8 +54,9 @@ public:
|
||||||
static bool term();
|
static bool term();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
SwSurface* surface = nullptr;
|
SwSurface* surface = nullptr;
|
||||||
Array<SwTask*> tasks;
|
Array<SwTask*> tasks;
|
||||||
|
Array<SwComposite*> composites;
|
||||||
|
|
||||||
SwRenderer(){};
|
SwRenderer(){};
|
||||||
~SwRenderer();
|
~SwRenderer();
|
||||||
|
|
Loading…
Add table
Reference in a new issue