mirror of
https://github.com/thorvg/thorvg.git
synced 2025-06-13 19:44:28 +00:00
sw_engine: supports the color space conversion.
Currently implements only the necessary functions for converting between ARGB and ABGR. Now conversion can be accelerated by the backend engines.
This commit is contained in:
parent
a4b2699f86
commit
b733030357
9 changed files with 63 additions and 9 deletions
|
@ -189,7 +189,7 @@ bool GlRenderer::dispose(RenderData data)
|
|||
}
|
||||
|
||||
|
||||
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)
|
||||
RenderData GlRenderer::prepare(TVG_UNUSED Surface* surface, 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:
|
||||
return nullptr;
|
||||
|
|
|
@ -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 Array<RenderData>& scene, 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;
|
||||
RenderData prepare(Surface* surface, const RenderMesh* mesh, RenderData data, const RenderTransform* transform, uint32_t opacity, Array<RenderData>& clips, RenderUpdateFlag flags) override;
|
||||
bool preRender() override;
|
||||
bool renderShape(RenderData data) override;
|
||||
bool renderImage(RenderData data) override;
|
||||
|
|
|
@ -359,5 +359,6 @@ bool rasterGradientStroke(SwSurface* surface, SwShape* shape, unsigned id);
|
|||
bool rasterClear(SwSurface* surface);
|
||||
void rasterRGBA32(uint32_t *dst, uint32_t val, uint32_t offset, int32_t len);
|
||||
void rasterUnpremultiply(SwSurface* surface);
|
||||
bool rasterConvertCS(Surface* surface, ColorSpace to);
|
||||
|
||||
#endif /* _TVG_SW_COMMON_H_ */
|
||||
|
|
|
@ -1572,4 +1572,22 @@ bool rasterImage(SwSurface* surface, SwImage* image, const RenderMesh* mesh, con
|
|||
//TODO: case: _rasterAlphaImageMesh()
|
||||
if (mesh && mesh->triangleCnt > 0) return _transformedRGBAImageMesh(surface, image, mesh, transform, &bbox, opacity);
|
||||
else return _rasterRGBAImage(surface, image, transform, bbox, opacity);
|
||||
}
|
||||
|
||||
|
||||
bool rasterConvertCS(Surface* surface, ColorSpace to)
|
||||
{
|
||||
//TOOD: Support SIMD accelerations
|
||||
auto from = surface->cs;
|
||||
|
||||
if ((from == ColorSpace::ABGR8888 && to == ColorSpace::ARGB8888) || (from == ColorSpace::ABGR8888S && to == ColorSpace::ARGB8888S)) {
|
||||
return cRasterABGRtoARGB(surface);
|
||||
}
|
||||
if ((from == ColorSpace::ARGB8888 && to == ColorSpace::ABGR8888) || (from == ColorSpace::ARGB8888S && to == ColorSpace::ABGR8888S)) {
|
||||
return cRasterARGBtoABGR(surface);
|
||||
}
|
||||
|
||||
surface->cs = to;
|
||||
|
||||
return false;
|
||||
}
|
|
@ -61,3 +61,27 @@ static bool inline cRasterTranslucentRect(SwSurface* surface, const SwBBox& regi
|
|||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
static bool inline cRasterABGRtoARGB(Surface* surface)
|
||||
{
|
||||
TVGLOG("SW_ENGINE", "Convert ColorSpace ABGR - ARGB");
|
||||
|
||||
auto buffer = surface->buffer;
|
||||
for (uint32_t y = 0; y < surface->h; ++y, buffer += surface->stride) {
|
||||
auto dst = buffer;
|
||||
for (uint32_t x = 0; x < surface->w; ++x, ++dst) {
|
||||
auto c = *dst;
|
||||
//flip Blue, Red channels
|
||||
*dst = (c & 0xff000000) + ((c & 0x00ff0000) >> 16) + (c & 0x0000ff00) + ((c & 0x000000ff) << 16);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
static bool inline cRasterARGBtoABGR(Surface* surface)
|
||||
{
|
||||
//exactly same with ABGRtoARGB
|
||||
return cRasterABGRtoARGB(surface);
|
||||
}
|
|
@ -258,6 +258,7 @@ struct SwSceneTask : SwTask
|
|||
struct SwImageTask : SwTask
|
||||
{
|
||||
SwImage image;
|
||||
Surface* source; //Image source
|
||||
const RenderMesh* mesh = nullptr; //Should be valid ptr in action
|
||||
|
||||
bool clip(SwRleData* target) override
|
||||
|
@ -276,6 +277,14 @@ struct SwImageTask : SwTask
|
|||
{
|
||||
auto clipRegion = bbox;
|
||||
|
||||
//Convert colorspace if it's not aligned.
|
||||
if (surface->cs != source->cs) rasterConvertCS(source, surface->cs);
|
||||
|
||||
image.data = source->buffer;
|
||||
image.w = source->w;
|
||||
image.h = source->h;
|
||||
image.stride = source->stride;
|
||||
|
||||
//Invisible shape turned to visible by alpha.
|
||||
if ((flags & (RenderUpdateFlag::Image | RenderUpdateFlag::Transform | RenderUpdateFlag::Color)) && (opacity > 0)) {
|
||||
imageReset(&image);
|
||||
|
@ -709,16 +718,13 @@ void* SwRenderer::prepareCommon(SwTask* task, const RenderTransform* transform,
|
|||
}
|
||||
|
||||
|
||||
RenderData SwRenderer::prepare(Surface* image, const RenderMesh* mesh, RenderData data, const RenderTransform* transform, uint32_t opacity, Array<RenderData>& clips, RenderUpdateFlag flags)
|
||||
RenderData SwRenderer::prepare(Surface* surface, const RenderMesh* mesh, RenderData data, const RenderTransform* transform, uint32_t opacity, Array<RenderData>& clips, RenderUpdateFlag flags)
|
||||
{
|
||||
//prepare task
|
||||
auto task = static_cast<SwImageTask*>(data);
|
||||
if (!task) task = new SwImageTask;
|
||||
if (flags & RenderUpdateFlag::Image) {
|
||||
task->image.data = image->buffer;
|
||||
task->image.w = image->w;
|
||||
task->image.h = image->h;
|
||||
task->image.stride = image->stride;
|
||||
task->source = surface;
|
||||
task->mesh = mesh;
|
||||
}
|
||||
return prepareCommon(task, transform, opacity, clips, flags);
|
||||
|
|
|
@ -38,7 +38,7 @@ class SwRenderer : public RenderMethod
|
|||
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 Array<RenderData>& scene, 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;
|
||||
RenderData prepare(Surface* surface, const RenderMesh* mesh, RenderData data, const RenderTransform* transform, uint32_t opacity, Array<RenderData>& clips, RenderUpdateFlag flags) override;
|
||||
bool preRender() override;
|
||||
bool renderShape(RenderData data) override;
|
||||
bool renderImage(RenderData data) override;
|
||||
|
|
|
@ -278,6 +278,11 @@ struct Picture::Impl
|
|||
if (surface) {
|
||||
dup->surface = static_cast<Surface*>(malloc(sizeof(Surface)));
|
||||
*dup->surface = *surface;
|
||||
//TODO: It needs a better design...
|
||||
//Backend engines might try to align the colorspace.
|
||||
//Since it shares the bitmap, duplications should not touch the data.
|
||||
//Only the owner could manage it.
|
||||
dup->surface->cs = ColorSpace::Unsupported;
|
||||
}
|
||||
dup->w = w;
|
||||
dup->h = h;
|
||||
|
|
|
@ -210,7 +210,7 @@ public:
|
|||
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 Array<RenderData>& scene, 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 RenderData prepare(Surface* surface, const RenderMesh* mesh, RenderData data, const RenderTransform* transform, uint32_t opacity, Array<RenderData>& clips, RenderUpdateFlag flags) = 0;
|
||||
virtual bool preRender() = 0;
|
||||
virtual bool renderShape(RenderData data) = 0;
|
||||
virtual bool renderImage(RenderData data) = 0;
|
||||
|
|
Loading…
Add table
Reference in a new issue