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:
Hermet Park 2020-12-10 19:21:31 +09:00 committed by Hermet Park
parent 1523446a20
commit e3eff97fac
2 changed files with 58 additions and 35 deletions

View file

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

View file

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