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 //TODO: Prepare frameBuffer & Setup render target for composition
return nullptr; return nullptr;

View file

@ -47,7 +47,7 @@ public:
bool sync() override; bool sync() override;
bool clear() 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 beginComposite(Compositor* cmp, CompositeMethod method, uint32_t opacity) override;
bool endComposite(Compositor* cmp) override; bool endComposite(Compositor* cmp) override;

View file

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

View file

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

View file

@ -51,6 +51,7 @@ struct Surface
uint32_t stride; uint32_t stride;
uint32_t w, h; uint32_t w, h;
ColorSpace cs; ColorSpace cs;
uint8_t channelSize;
bool premultiplied; //Alpha-premultiplied bool premultiplied; //Alpha-premultiplied
bool owner; //Only owner could modify the buffer bool owner; //Only owner could modify the buffer
@ -227,11 +228,42 @@ public:
virtual bool clear() = 0; virtual bool clear() = 0;
virtual bool sync() = 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 beginComposite(Compositor* cmp, CompositeMethod method, uint32_t opacity) = 0;
virtual bool endComposite(Compositor* cmp) = 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_ #endif //_TVG_RENDER_H_

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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