common sw_engine: applied colorspace format size.

Now backend engines know which channel size is required for
compositions.

@Issue: https://github.com/thorvg/thorvg/issues/976
This commit is contained in:
Hermet Park 2023-05-01 22:42:41 +09:00 committed by Hermet Park
parent e3f363fea7
commit 527b1af926
13 changed files with 56 additions and 11 deletions

View file

@ -102,7 +102,7 @@ bool GlRenderer::postRender()
}
Compositor* GlRenderer::target(TVG_UNUSED const RenderRegion& region)
Compositor* GlRenderer::target(TVG_UNUSED const RenderRegion& region, TVG_UNUSED ColorSpace cs)
{
//TODO: Prepare frameBuffer & Setup render target for composition
return nullptr;

View file

@ -47,7 +47,7 @@ public:
bool sync() override;
bool clear() override;
Compositor* target(const RenderRegion& region) override;
Compositor* target(const RenderRegion& region, ColorSpace cs) override;
bool beginComposite(Compositor* cmp, CompositeMethod method, uint32_t opacity) override;
bool endComposite(Compositor* cmp) override;

View file

@ -228,6 +228,7 @@ struct SwImage
int32_t ox = 0; //offset x
int32_t oy = 0; //offset y
float scale;
uint8_t channelSize;
bool direct = false; //draw image directly (with offset)
bool scaled = false; //draw scaled image

View file

@ -289,6 +289,7 @@ struct SwImageTask : SwTask
image.w = source->w;
image.h = source->h;
image.stride = source->stride;
image.channelSize = source->channelSize;
//Invisible shape turned to visible by alpha.
if ((flags & (RenderUpdateFlag::Image | RenderUpdateFlag::Transform | RenderUpdateFlag::Color)) && (opacity > 0)) {
@ -434,6 +435,7 @@ bool SwRenderer::target(uint32_t* buffer, uint32_t stride, uint32_t w, uint32_t
surface->w = w;
surface->h = h;
surface->cs = cs;
surface->channelSize = CHANNEL_SIZE(cs);
surface->premultiplied = true;
surface->owner = true;
@ -505,7 +507,7 @@ bool SwRenderer::renderShape(RenderData data)
//Do Stroking Composition
if (task->cmpStroking) {
opacity = 255;
cmp = target(task->bounds());
cmp = target(task->bounds(), colorSpace());
beginComposite(cmp, CompositeMethod::None, task->opacity);
//No Stroking Composition
} else {
@ -571,7 +573,7 @@ bool SwRenderer::mempool(bool shared)
}
Compositor* SwRenderer::target(const RenderRegion& region)
Compositor* SwRenderer::target(const RenderRegion& region, ColorSpace cs)
{
auto x = region.x;
auto y = region.y;
@ -585,9 +587,11 @@ Compositor* SwRenderer::target(const RenderRegion& region)
SwSurface* cmp = nullptr;
auto reqChannelSize = CHANNEL_SIZE(cs);
//Use cached data
for (auto p = compositors.data; p < (compositors.data + compositors.count); ++p) {
if ((*p)->compositor->valid) {
if ((*p)->compositor->valid && (*p)->compositor->image.channelSize == reqChannelSize) {
cmp = *p;
break;
}
@ -602,8 +606,10 @@ Compositor* SwRenderer::target(const RenderRegion& region)
cmp->compositor = new SwCompositor;
//SwImage, Optimize Me: Surface size from MainSurface(WxH) to Parameter W x H
cmp->compositor->image.data = (uint32_t*) malloc(sizeof(uint32_t) * surface->stride * surface->h);
//TODO: We can optimize compositor surface size from (surface->stride x surface->h) to Parameter(w x h)
cmp->compositor->image.data = (uint32_t*) malloc(reqChannelSize * surface->stride * surface->h);
cmp->channelSize = cmp->compositor->image.channelSize = reqChannelSize;
compositors.push(cmp);
}

View file

@ -54,7 +54,7 @@ public:
bool target(uint32_t* buffer, uint32_t stride, uint32_t w, uint32_t h, ColorSpace cs);
bool mempool(bool shared);
Compositor* target(const RenderRegion& region) override;
Compositor* target(const RenderRegion& region, ColorSpace cs) override;
bool beginComposite(Compositor* cmp, CompositeMethod method, uint32_t opacity) override;
bool endComposite(Compositor* cmp) override;
void clearCompositors();

View file

@ -167,7 +167,8 @@ bool Paint::Impl::render(RenderMethod& renderer)
if (compData && compData->method != CompositeMethod::ClipPath && !(compData->target->pImpl->ctxFlag & ContextFlag::FastTrack)) {
auto region = smethod->bounds(renderer);
if (region.w == 0 || region.h == 0) return true;
cmp = renderer.target(region);
//cmp = renderer.target(region, COMPOSITE_TO_COLORSPACE(renderer, compData->method));
cmp = renderer.target(region, renderer.colorSpace());
if (renderer.beginComposite(cmp, CompositeMethod::None, 255)) {
compData->target->pImpl->render(renderer);
}

View file

@ -51,6 +51,7 @@ struct Surface
uint32_t stride;
uint32_t w, h;
ColorSpace cs;
uint8_t channelSize;
bool premultiplied; //Alpha-premultiplied
bool owner; //Only owner could modify the buffer
@ -227,11 +228,42 @@ public:
virtual bool clear() = 0;
virtual bool sync() = 0;
virtual Compositor* target(const RenderRegion& region) = 0;
virtual Compositor* target(const RenderRegion& region, ColorSpace cs) = 0;
virtual bool beginComposite(Compositor* cmp, CompositeMethod method, uint32_t opacity) = 0;
virtual bool endComposite(Compositor* cmp) = 0;
};
static inline uint8_t CHANNEL_SIZE(ColorSpace cs)
{
switch(cs) {
case ColorSpace::ABGR8888:
case ColorSpace::ABGR8888S:
case ColorSpace::ARGB8888:
case ColorSpace::ARGB8888S:
return sizeof(uint32_t);
case ColorSpace::Grayscale8:
return sizeof(uint8_t);
case ColorSpace::Unsupported:
default:
TVGERR("SW_ENGINE", "Unsupported Channel Size! = %d", (int)cs);
return 0;
}
}
static inline ColorSpace COMPOSITE_TO_COLORSPACE(RenderMethod& renderer, CompositeMethod method)
{
switch(method) {
case CompositeMethod::AlphaMask:
case CompositeMethod::InvAlphaMask:
return ColorSpace::Grayscale8;
case CompositeMethod::LumaMask:
return renderer.colorSpace();
default:
TVGERR("COMMON", "Unsupported Composite Size! = %d", (int)method);
return ColorSpace::Unsupported;
}
}
}
#endif //_TVG_RENDER_H_

View file

@ -135,7 +135,7 @@ struct Scene::Impl
Compositor* cmp = nullptr;
if (needComposition(opacity)) {
cmp = renderer.target(bounds(renderer));
cmp = renderer.target(bounds(renderer), renderer.colorSpace());
renderer.beginComposite(cmp, CompositeMethod::None, opacity);
}

View file

@ -165,6 +165,7 @@ unique_ptr<Surface> JpgLoader::bitmap()
surface->w = w;
surface->h = h;
surface->cs = cs;
surface->channelSize = sizeof(uint32_t);
surface->premultiplied = true;
surface->owner = true;

View file

@ -111,6 +111,7 @@ unique_ptr<Surface> PngLoader::bitmap()
surface->w = w;
surface->h = h;
surface->cs = cs;
surface->channelSize = sizeof(uint32_t);
surface->owner = true;
surface->premultiplied = false;

View file

@ -125,6 +125,7 @@ unique_ptr<Surface> JpgLoader::bitmap()
surface->w = static_cast<uint32_t>(w);
surface->h = static_cast<uint32_t>(h);
surface->cs = cs;
surface->channelSize = sizeof(uint32_t);
surface->premultiplied = true;
surface->owner = true;

View file

@ -161,6 +161,7 @@ unique_ptr<Surface> PngLoader::bitmap()
surface->w = static_cast<uint32_t>(w);
surface->h = static_cast<uint32_t>(h);
surface->cs = cs;
surface->channelSize = sizeof(uint32_t);
surface->premultiplied = false;
surface->owner = true;

View file

@ -87,6 +87,7 @@ unique_ptr<Surface> RawLoader::bitmap()
surface->w = static_cast<uint32_t>(w);
surface->h = static_cast<uint32_t>(h);
surface->cs = cs;
surface->channelSize = sizeof(uint32_t);
surface->premultiplied = true;
surface->owner = true;