From 7d9023ac5cfa8002785372e1146ab9e32461f600 Mon Sep 17 00:00:00 2001 From: Hermet Park Date: Fri, 25 Dec 2020 20:44:07 +0900 Subject: [PATCH] common sw_engine: code refactoring Renamed internal interfaces. We need both blender & compositor interfaces. Renamed SwCompositor -> SwBlender which is for pixel joining methods. Added (SwCompositor, Compositor) which is designed for compositing images. --- src/lib/gl_engine/tvgGlRenderer.cpp | 8 +- src/lib/gl_engine/tvgGlRenderer.h | 8 +- src/lib/sw_engine/tvgSwCommon.h | 4 +- src/lib/sw_engine/tvgSwFill.cpp | 4 +- src/lib/sw_engine/tvgSwRaster.cpp | 38 ++++---- src/lib/sw_engine/tvgSwRenderer.cpp | 130 ++++++++++++++-------------- src/lib/sw_engine/tvgSwRenderer.h | 20 ++--- src/lib/tvgPaint.h | 34 ++++---- src/lib/tvgRender.h | 16 ++-- src/lib/tvgSceneImpl.h | 6 +- 10 files changed, 137 insertions(+), 131 deletions(-) diff --git a/src/lib/gl_engine/tvgGlRenderer.cpp b/src/lib/gl_engine/tvgGlRenderer.cpp index bae6e4f6..b5bbb880 100644 --- a/src/lib/gl_engine/tvgGlRenderer.cpp +++ b/src/lib/gl_engine/tvgGlRenderer.cpp @@ -102,27 +102,27 @@ bool GlRenderer::postRender() } -void* GlRenderer::addCompositor(TVG_UNUSED CompositeMethod method, TVG_UNUSED uint32_t x, TVG_UNUSED uint32_t y, TVG_UNUSED uint32_t w, TVG_UNUSED uint32_t h, TVG_UNUSED uint32_t opacity) +Compositor* GlRenderer::addCompositor(TVG_UNUSED uint32_t x, TVG_UNUSED uint32_t y, TVG_UNUSED uint32_t w, TVG_UNUSED uint32_t h) { //TODO: Prepare frameBuffer & Setup render target for composition return nullptr; } -bool GlRenderer::delCompositor(TVG_UNUSED void* cmp) +bool GlRenderer::delCompositor(TVG_UNUSED Compositor* cmp) { //TODO: delete the given compositor and restore the context return false; } -bool GlRenderer::renderImage(TVG_UNUSED void* data, TVG_UNUSED void* cmp) +bool GlRenderer::renderImage(TVG_UNUSED void* data, TVG_UNUSED Compositor* cmp) { return false; } -bool GlRenderer::renderShape(RenderData data, TVG_UNUSED void* cmp) +bool GlRenderer::renderShape(RenderData data, TVG_UNUSED Compositor* cmp) { auto sdata = static_cast(data); if (!sdata) return false; diff --git a/src/lib/gl_engine/tvgGlRenderer.h b/src/lib/gl_engine/tvgGlRenderer.h index d1da960c..19413997 100644 --- a/src/lib/gl_engine/tvgGlRenderer.h +++ b/src/lib/gl_engine/tvgGlRenderer.h @@ -33,11 +33,11 @@ public: RenderData prepare(const Shape& shape, RenderData data, const RenderTransform* transform, uint32_t opacity, Array& clips, RenderUpdateFlag flags) override; RenderData prepare(const Picture& picture, RenderData data, const RenderTransform* transform, uint32_t opacity, Array& clips, RenderUpdateFlag flags) override; bool dispose(RenderData data) override; - void* addCompositor(CompositeMethod method, uint32_t x, uint32_t y, uint32_t w, uint32_t h, uint32_t opacity) override; - bool delCompositor(void* cmp) override; + Compositor* addCompositor(uint32_t x, uint32_t y, uint32_t w, uint32_t h) override; + bool delCompositor(Compositor* cmp) override; bool preRender() override; - bool renderShape(RenderData data, void* cmp) override; - bool renderImage(RenderData data, void* cmp) override; + bool renderShape(RenderData data, Compositor* cmp) override; + bool renderImage(RenderData data, Compositor* cmp) override; bool postRender() override; bool renderRegion(RenderData data, uint32_t* x, uint32_t* y, uint32_t* w, uint32_t* h) override; bool target(uint32_t* buffer, uint32_t stride, uint32_t w, uint32_t h); diff --git a/src/lib/sw_engine/tvgSwCommon.h b/src/lib/sw_engine/tvgSwCommon.h index 8ae73957..ef46bee1 100644 --- a/src/lib/sw_engine/tvgSwCommon.h +++ b/src/lib/sw_engine/tvgSwCommon.h @@ -220,7 +220,7 @@ struct SwImage uint32_t w, h; }; -struct SwCompositor +struct SwBlender { uint32_t (*join)(uint8_t r, uint8_t g, uint8_t b, uint8_t a); uint32_t (*alpha)(uint32_t rgba); @@ -228,7 +228,7 @@ struct SwCompositor struct SwSurface : Surface { - SwCompositor comp; + SwBlender blender; }; static inline SwCoord TO_SWCOORD(float val) diff --git a/src/lib/sw_engine/tvgSwFill.cpp b/src/lib/sw_engine/tvgSwFill.cpp index 6e90764c..ba2b420b 100644 --- a/src/lib/sw_engine/tvgSwFill.cpp +++ b/src/lib/sw_engine/tvgSwFill.cpp @@ -52,7 +52,7 @@ static bool _updateColorTable(SwFill* fill, const Fill* fdata, SwSurface* surfac auto g = ALPHA_MULTIPLY(pColors->g, pColors->a); auto b = ALPHA_MULTIPLY(pColors->b, pColors->a); - auto rgba = surface->comp.join(r, g, b, pColors->a); + auto rgba = surface->blender.join(r, g, b, pColors->a); auto inc = 1.0f / static_cast(GRADIENT_STOP_SIZE); auto pos = 1.5f * inc; uint32_t i = 0; @@ -75,7 +75,7 @@ static bool _updateColorTable(SwFill* fill, const Fill* fdata, SwSurface* surfac auto g = ALPHA_MULTIPLY(next->g, next->a); auto b = ALPHA_MULTIPLY(next->b, next->a); - auto rgba2 = surface->comp.join(r, g, b, next->a); + auto rgba2 = surface->blender.join(r, g, b, next->a); while (pos < next->offset && i < GRADIENT_STOP_SIZE) { auto t = (pos - curr->offset) * delta; diff --git a/src/lib/sw_engine/tvgSwRaster.cpp b/src/lib/sw_engine/tvgSwRaster.cpp index c65a2cb6..791186ac 100644 --- a/src/lib/sw_engine/tvgSwRaster.cpp +++ b/src/lib/sw_engine/tvgSwRaster.cpp @@ -97,7 +97,7 @@ static bool _rasterTranslucentRect(SwSurface* surface, const SwBBox& region, uin auto buffer = surface->buffer + (region.min.y * surface->stride) + region.min.x; auto h = static_cast(region.max.y - region.min.y); auto w = static_cast(region.max.x - region.min.x); - auto ialpha = 255 - surface->comp.alpha(color); + auto ialpha = 255 - surface->blender.alpha(color); for (uint32_t y = 0; y < h; ++y) { auto dst = &buffer[y * surface->stride]; @@ -133,7 +133,7 @@ static bool _rasterTranslucentRle(SwSurface* surface, SwRleData* rle, uint32_t c auto dst = &surface->buffer[span->y * surface->stride + span->x]; if (span->coverage < 255) src = ALPHA_BLEND(color, span->coverage); else src = color; - auto ialpha = 255 - surface->comp.alpha(src); + auto ialpha = 255 - surface->blender.alpha(src); for (uint32_t i = 0; i < span->len; ++i) { dst[i] = src + ALPHA_BLEND(dst[i], ialpha); } @@ -157,7 +157,7 @@ static bool _rasterTranslucentImageRle(SwSurface* surface, SwRleData* rle, uint3 if (rX >= w || rY >= h) continue; auto alpha = ALPHA_MULTIPLY(span->coverage, opacity); auto src = ALPHA_BLEND(img[rY * w + rX], alpha); //TODO: need to use image's stride - *dst = src + ALPHA_BLEND(*dst, 255 - surface->comp.alpha(src)); + *dst = src + ALPHA_BLEND(*dst, 255 - surface->blender.alpha(src)); } ++span; } @@ -178,7 +178,7 @@ static bool _rasterImageRle(SwSurface* surface, SwRleData* rle, uint32_t *img, u auto rY = static_cast(roundf((span->x + x) * invTransform->e21 + ey2)); if (rX >= w || rY >= h) continue; auto src = ALPHA_BLEND(img[rY * w + rX], span->coverage); //TODO: need to use image's stride - *dst = src + ALPHA_BLEND(*dst, 255 - surface->comp.alpha(src)); + *dst = src + ALPHA_BLEND(*dst, 255 - surface->blender.alpha(src)); } ++span; } @@ -197,7 +197,7 @@ static bool _rasterTranslucentImage(SwSurface* surface, uint32_t *img, uint32_t auto rY = static_cast(roundf(x * invTransform->e21 + ey2)); if (rX >= w || rY >= h) continue; auto src = ALPHA_BLEND(img[rX + (rY * w)], opacity); //TODO: need to use image's stride - *dst = src + ALPHA_BLEND(*dst, 255 - surface->comp.alpha(src)); + *dst = src + ALPHA_BLEND(*dst, 255 - surface->blender.alpha(src)); } } return true; @@ -210,7 +210,7 @@ static bool _rasterImage(SwSurface* surface, uint32_t *img, uint32_t w, uint32_t auto dst = &surface->buffer[y * surface->stride + region.min.x]; auto src = img + region.min.x + (y * w); //TODO: need to use image's stride for (auto x = region.min.x; x < region.max.x; x++, dst++, src++) { - *dst = *src + ALPHA_BLEND(*dst, 255 - surface->comp.alpha(*src)); + *dst = *src + ALPHA_BLEND(*dst, 255 - surface->blender.alpha(*src)); } } return true; @@ -228,7 +228,7 @@ static bool _rasterImage(SwSurface* surface, uint32_t *img, uint32_t w, uint32_t auto rY = static_cast(roundf(x * invTransform->e21 + ey2)); if (rX >= w || rY >= h) continue; auto src = img[rX + (rY * w)]; //TODO: need to use image's stride - *dst = src + ALPHA_BLEND(*dst, 255 - surface->comp.alpha(src)); + *dst = src + ALPHA_BLEND(*dst, 255 - surface->blender.alpha(src)); } } return true; @@ -276,7 +276,7 @@ static bool _rasterLinearGradientRect(SwSurface* surface, const SwBBox& region, auto dst = &buffer[y * surface->stride]; fillFetchLinear(fill, tmpBuf, region.min.y + y, region.min.x, 0, w); for (uint32_t x = 0; x < w; ++x) { - dst[x] = tmpBuf[x] + ALPHA_BLEND(dst[x], 255 - surface->comp.alpha(tmpBuf[x])); + dst[x] = tmpBuf[x] + ALPHA_BLEND(dst[x], 255 - surface->blender.alpha(tmpBuf[x])); } } //Opaque Gradient @@ -307,7 +307,7 @@ static bool _rasterRadialGradientRect(SwSurface* surface, const SwBBox& region, auto dst = &buffer[y * surface->stride]; fillFetchRadial(fill, tmpBuf, region.min.y + y, region.min.x, w); for (uint32_t x = 0; x < w; ++x) { - dst[x] = tmpBuf[x] + ALPHA_BLEND(dst[x], 255 - surface->comp.alpha(tmpBuf[x])); + dst[x] = tmpBuf[x] + ALPHA_BLEND(dst[x], 255 - surface->blender.alpha(tmpBuf[x])); } } //Opaque Gradient @@ -337,12 +337,12 @@ static bool _rasterLinearGradientRle(SwSurface* surface, SwRleData* rle, const S fillFetchLinear(fill, buf, span->y, span->x, 0, span->len); if (span->coverage == 255) { for (uint32_t i = 0; i < span->len; ++i) { - dst[i] = buf[i] + ALPHA_BLEND(dst[i], 255 - surface->comp.alpha(buf[i])); + dst[i] = buf[i] + ALPHA_BLEND(dst[i], 255 - surface->blender.alpha(buf[i])); } } else { for (uint32_t i = 0; i < span->len; ++i) { auto tmp = ALPHA_BLEND(buf[i], span->coverage); - dst[i] = tmp + ALPHA_BLEND(dst[i], 255 - surface->comp.alpha(tmp)); + dst[i] = tmp + ALPHA_BLEND(dst[i], 255 - surface->blender.alpha(tmp)); } } ++span; @@ -383,12 +383,12 @@ static bool _rasterRadialGradientRle(SwSurface* surface, SwRleData* rle, const S fillFetchRadial(fill, buf, span->y, span->x, span->len); if (span->coverage == 255) { for (uint32_t i = 0; i < span->len; ++i) { - dst[i] = buf[i] + ALPHA_BLEND(dst[i], 255 - surface->comp.alpha(buf[i])); + dst[i] = buf[i] + ALPHA_BLEND(dst[i], 255 - surface->blender.alpha(buf[i])); } } else { for (uint32_t i = 0; i < span->len; ++i) { auto tmp = ALPHA_BLEND(buf[i], span->coverage); - dst[i] = tmp + ALPHA_BLEND(dst[i], 255 - surface->comp.alpha(tmp)); + dst[i] = tmp + ALPHA_BLEND(dst[i], 255 - surface->blender.alpha(tmp)); } } ++span; @@ -420,11 +420,11 @@ static bool _rasterRadialGradientRle(SwSurface* surface, SwRleData* rle, const S bool rasterCompositor(SwSurface* surface) { if (surface->cs == SwCanvas::ABGR8888) { - surface->comp.alpha = _colorAlpha; - surface->comp.join = _abgrJoin; + surface->blender.alpha = _colorAlpha; + surface->blender.join = _abgrJoin; } else if (surface->cs == SwCanvas::ARGB8888) { - surface->comp.alpha = _colorAlpha; - surface->comp.join = _argbJoin; + surface->blender.alpha = _colorAlpha; + surface->blender.join = _argbJoin; } else { //What Color Space ??? return false; @@ -455,7 +455,7 @@ bool rasterSolidShape(SwSurface* surface, SwShape* shape, uint8_t r, uint8_t g, g = ALPHA_MULTIPLY(g, a); b = ALPHA_MULTIPLY(b, a); - auto color = surface->comp.join(r, g, b, a); + auto color = surface->blender.join(r, g, b, a); //Fast Track if (shape->rect) { @@ -476,7 +476,7 @@ bool rasterStroke(SwSurface* surface, SwShape* shape, uint8_t r, uint8_t g, uint g = ALPHA_MULTIPLY(g, a); b = ALPHA_MULTIPLY(b, a); - auto color = surface->comp.join(r, g, b, a); + auto color = surface->blender.join(r, g, b, a); if (a == 255) return _rasterSolidRle(surface, shape->strokeRle, color); return _rasterTranslucentRle(surface, shape->strokeRle, color); diff --git a/src/lib/sw_engine/tvgSwRenderer.cpp b/src/lib/sw_engine/tvgSwRenderer.cpp index cbb51dcf..c5e899bc 100644 --- a/src/lib/sw_engine/tvgSwRenderer.cpp +++ b/src/lib/sw_engine/tvgSwRenderer.cpp @@ -30,14 +30,12 @@ static bool initEngine = false; static uint32_t rendererCnt = 0; -struct SwComposite +struct SwCompositor : Compositor { SwSurface surface; - SwComposite* recover; + SwCompositor* recover; SwImage image; SwBBox bbox; - CompositeMethod method; - uint32_t opacity; bool valid; }; @@ -67,7 +65,7 @@ struct SwShapeTask : SwTask { SwShape shape; const Shape* sdata = nullptr; - bool compStroking; + bool cmpStroking; void run(unsigned tid) override { @@ -134,23 +132,23 @@ struct SwShapeTask : SwTask } //Clip Path - for (auto comp = clips.data; comp < (clips.data + clips.count); ++comp) { - auto compShape = &static_cast(*comp)->shape; + for (auto clip = clips.data; clip < (clips.data + clips.count); ++clip) { + auto clipper = &static_cast(*clip)->shape; //Clip shape rle if (shape.rle) { - if (compShape->rect) rleClipRect(shape.rle, &compShape->bbox); - else if (compShape->rle) rleClipPath(shape.rle, compShape->rle); + if (clipper->rect) rleClipRect(shape.rle, &clipper->bbox); + else if (clipper->rle) rleClipPath(shape.rle, clipper->rle); } //Clip stroke rle if (shape.strokeRle) { - if (compShape->rect) rleClipRect(shape.strokeRle, &compShape->bbox); - else if (compShape->rle) rleClipPath(shape.strokeRle, compShape->rle); + if (clipper->rect) rleClipRect(shape.strokeRle, &clipper->bbox); + else if (clipper->rle) rleClipPath(shape.strokeRle, clipper->rle); } } end: shapeDelOutline(&shape, tid); - if (addStroking == 2 && opacity < 255) compStroking = true; - else compStroking = false; + if (addStroking == 2 && opacity < 255) cmpStroking = true; + else cmpStroking = false; } bool dispose() override @@ -182,10 +180,10 @@ struct SwImageTask : SwTask if (clips.count > 0) { if (!imageGenRle(&image, pdata, clip, bbox, false, true)) goto end; if (image.rle) { - for (auto comp = clips.data; comp < (clips.data + clips.count); ++comp) { - auto compShape = &static_cast(*comp)->shape; - if (compShape->rect) rleClipRect(image.rle, &compShape->bbox); - else if (compShape->rle) rleClipPath(image.rle, compShape->rle); + for (auto clip = clips.data; clip < (clips.data + clips.count); ++clip) { + auto clipper = &static_cast(*clip)->shape; + if (clipper->rect) rleClipRect(image.rle, &clipper->bbox); + else if (clipper->rle) rleClipPath(image.rle, clipper->rle); } } } @@ -282,7 +280,7 @@ bool SwRenderer::postRender() } -bool SwRenderer::renderImage(RenderData data, TVG_UNUSED void* cmp) +bool SwRenderer::renderImage(RenderData data, TVG_UNUSED Compositor* cmp) { auto task = static_cast(data); task->done(); @@ -293,7 +291,7 @@ bool SwRenderer::renderImage(RenderData data, TVG_UNUSED void* cmp) } -bool SwRenderer::renderShape(RenderData data, TVG_UNUSED void* cmp) +bool SwRenderer::renderShape(RenderData data, TVG_UNUSED Compositor* cmp) { auto task = static_cast(data); task->done(); @@ -301,15 +299,17 @@ bool SwRenderer::renderShape(RenderData data, TVG_UNUSED void* cmp) if (task->opacity == 0) return true; uint32_t opacity; - void *cmp2 = nullptr; + Compositor* cmp2 = nullptr; //Do Composition - if (task->compStroking) { + if (task->cmpStroking) { uint32_t x, y, w, h; task->bounds(&x, &y, &w, &h); opacity = 255; //CompositeMethod::None is used for a default alpha blending - cmp2 = addCompositor(CompositeMethod::None, x, y, w, h, opacity); + cmp2 = addCompositor(x, y, w, h); + cmp2->method = CompositeMethod::None; + cmp2->opacity = opacity; //No Composition } else { opacity = task->opacity; @@ -332,7 +332,7 @@ bool SwRenderer::renderShape(RenderData data, TVG_UNUSED void* cmp) if (a > 0) rasterStroke(surface, &task->shape, r, g, b, a); //Composition (Shape + Stroke) stage - if (task->compStroking) delCompositor(cmp2); + if (task->cmpStroking) delCompositor(cmp2); return true; } @@ -345,92 +345,90 @@ bool SwRenderer::renderRegion(RenderData data, uint32_t* x, uint32_t* y, uint32_ } -void* SwRenderer::addCompositor(CompositeMethod method, uint32_t x, uint32_t y, uint32_t w, uint32_t h, uint32_t opacity) +Compositor* SwRenderer::addCompositor(uint32_t x, uint32_t y, uint32_t w, uint32_t h) { - SwComposite* comp = nullptr; + SwCompositor* cmp = nullptr; //Use cached data for (auto p = compositors.data; p < (compositors.data + compositors.count); ++p) { if ((*p)->valid) { - comp = *p; + cmp = *p; break; } } //New Composition - if (!comp) { - comp = new SwComposite; - if (!comp) return nullptr; + if (!cmp) { + cmp = new SwCompositor; + if (!cmp) 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); + cmp->image.data = (uint32_t*) malloc(sizeof(uint32_t) * surface->w * surface->h); + if (!cmp->image.data) { + delete(cmp); return nullptr; } - compositors.push(comp); + compositors.push(cmp); } - comp->valid = false; - comp->method = method; - comp->opacity = opacity; + cmp->valid = false; //Boundary Check if (x + w > surface->w) w = (surface->w - x); if (y + h > surface->h) h = (surface->h - y); #ifdef THORVG_LOG_ENABLED - printf("SW_ENGINE: Using intermediate composition [Method: %d][Region: %d %d %d %d]\n", (int)method, x, y, w, h); + printf("SW_ENGINE: Using intermediate composition [Region: %d %d %d %d]\n", x, y, w, h); #endif - comp->bbox.min.x = x; - comp->bbox.min.y = y; - comp->bbox.max.x = x + w; - comp->bbox.max.y = y + h; - comp->image.w = surface->w; - comp->image.h = surface->h; + cmp->bbox.min.x = x; + cmp->bbox.min.y = y; + cmp->bbox.max.x = x + w; + cmp->bbox.max.y = y + h; + cmp->image.w = surface->w; + cmp->image.h = surface->h; //Inherits attributes from main surface - comp->surface.comp = surface->comp; - comp->surface.stride = surface->w; - comp->surface.cs = surface->cs; + cmp->surface.blender = surface->blender; + cmp->surface.stride = surface->w; + cmp->surface.cs = surface->cs; //We know partial clear region - comp->surface.buffer = comp->image.data + (comp->surface.stride * y + x); - comp->surface.w = w; - comp->surface.h = h; + cmp->surface.buffer = cmp->image.data + (cmp->surface.stride * y + x); + cmp->surface.w = w; + cmp->surface.h = h; - rasterClear(&comp->surface); + rasterClear(&cmp->surface); //Recover context - comp->surface.buffer = comp->image.data; - comp->surface.w = comp->image.w; - comp->surface.h = comp->image.h; + cmp->surface.buffer = cmp->image.data; + cmp->surface.w = cmp->image.w; + cmp->surface.h = cmp->image.h; //Switch active compositor - comp->recover = compositor; //Backup current compositor - compositor = comp; + cmp->recover = compositor; //Backup current compositor + compositor = cmp; //Switch render target - surface = &comp->surface; + surface = &cmp->surface; - return comp; + return cmp; } -bool SwRenderer::delCompositor(void* ctx) +bool SwRenderer::delCompositor(Compositor* cmp) { - if (!ctx) return false; + if (!cmp) return false; - auto comp = static_cast(ctx); - comp->valid = true; + auto p = static_cast(cmp); + p->valid = true; //Recover Context - compositor = comp->recover; + compositor = p->recover; surface = compositor ? &compositor->surface : mainSurface; //Default is alpha blending - if (comp->method == CompositeMethod::None) { - return rasterImage(surface, &comp->image, nullptr, comp->bbox, comp->opacity); + if (p->method == CompositeMethod::None) { + return rasterImage(surface, &p->image, nullptr, p->bbox, p->opacity); } return true; @@ -460,8 +458,8 @@ void* SwRenderer::prepareCommon(SwTask* task, const RenderTransform* transform, if (clips.count > 0) { //Guarantee composition targets get ready. - for (auto comp = clips.data; comp < (clips.data + clips.count); ++comp) { - static_cast(*comp)->done(); + for (auto clip = clips.data; clip < (clips.data + clips.count); ++clip) { + static_cast(*clip)->done(); } task->clips = clips; } diff --git a/src/lib/sw_engine/tvgSwRenderer.h b/src/lib/sw_engine/tvgSwRenderer.h index 5c252ee7..82b9259c 100644 --- a/src/lib/sw_engine/tvgSwRenderer.h +++ b/src/lib/sw_engine/tvgSwRenderer.h @@ -26,7 +26,7 @@ struct SwSurface; struct SwTask; -struct SwComposite; +struct SwCompositor; namespace tvg { @@ -36,15 +36,15 @@ class SwRenderer : public RenderMethod public: RenderData prepare(const Shape& shape, RenderData data, const RenderTransform* transform, uint32_t opacity, Array& clips, RenderUpdateFlag flags) override; RenderData prepare(const Picture& picture, RenderData data, const RenderTransform* transform, uint32_t opacity, Array& clips, RenderUpdateFlag flags) override; - void* addCompositor(CompositeMethod method, uint32_t x, uint32_t y, uint32_t w, uint32_t h, uint32_t opacity) override; - bool delCompositor(void* cmp) override; + Compositor* addCompositor(uint32_t x, uint32_t y, uint32_t w, uint32_t h) override; + bool delCompositor(Compositor* cmp) override; bool dispose(RenderData data) override; bool preRender() override; bool postRender() override; bool renderRegion(RenderData data, uint32_t* x, uint32_t* y, uint32_t* w, uint32_t* h) override; bool clear() override; - bool renderShape(RenderData data, void* cmp) override; - bool renderImage(RenderData data, void* cmp) override; + bool renderShape(RenderData data, Compositor* cmp) override; + bool renderImage(RenderData data, Compositor* cmp) override; bool sync() override; bool target(uint32_t* buffer, uint32_t stride, uint32_t w, uint32_t h, uint32_t cs); @@ -53,11 +53,11 @@ public: static bool term(); private: - SwSurface* surface = nullptr; //active surface - SwComposite* compositor = nullptr; //active compositor - SwSurface* mainSurface = nullptr; //main (default) surface - Array tasks; //async task list - Array compositors; //compositor cache list + SwSurface* surface = nullptr; //active surface + SwCompositor* compositor = nullptr; //active compositor + SwSurface* mainSurface = nullptr; //main (default) surface + Array tasks; //async task list + Array compositors; //compositor cache list SwRenderer(){}; ~SwRenderer(); diff --git a/src/lib/tvgPaint.h b/src/lib/tvgPaint.h index 91adb68a..ceeb0c56 100644 --- a/src/lib/tvgPaint.h +++ b/src/lib/tvgPaint.h @@ -47,13 +47,13 @@ namespace tvg RenderTransform *rTransform = nullptr; uint32_t flag = RenderUpdateFlag::None; - Paint* compTarget = nullptr; - CompositeMethod compMethod = CompositeMethod::None; + Paint* cmpTarget = nullptr; + CompositeMethod cmpMethod = CompositeMethod::None; uint8_t opacity = 255; ~Impl() { - if (compTarget) delete(compTarget); + if (cmpTarget) delete(cmpTarget); if (smethod) delete(smethod); if (rTransform) delete(rTransform); } @@ -133,7 +133,7 @@ namespace tvg bool dispose(RenderMethod& renderer) { - if (compTarget) compTarget->pImpl->dispose(renderer); + if (cmpTarget) cmpTarget->pImpl->dispose(renderer); return smethod->dispose(renderer); } @@ -147,11 +147,11 @@ namespace tvg } } - void *compdata = nullptr; + void *cmpData = nullptr; - if (compTarget) { - compdata = compTarget->pImpl->update(renderer, pTransform, opacity, clips, pFlag); - if (compMethod == CompositeMethod::ClipPath) clips.push(compdata); + if (cmpTarget) { + cmpData = cmpTarget->pImpl->update(renderer, pTransform, opacity, clips, pFlag); + if (cmpMethod == CompositeMethod::ClipPath) clips.push(cmpData); } void *edata = nullptr; @@ -167,21 +167,23 @@ namespace tvg edata = smethod->update(renderer, outTransform, opacity, clips, newFlag); } - if (compdata) clips.pop(); + if (cmpData) clips.pop(); return edata; } bool render(RenderMethod& renderer) { - void* cmp = nullptr; + Compositor* cmp = nullptr; /* Note: only ClipPath is processed in update() step */ - if (compTarget && compMethod != CompositeMethod::ClipPath) { + if (cmpTarget && cmpMethod != CompositeMethod::ClipPath) { uint32_t x, y, w, h; - if (!compTarget->pImpl->bounds(renderer, &x, &y, &w, &h)) return false; - cmp = renderer.addCompositor(compMethod, x, y, w, h, 255); - compTarget->pImpl->render(renderer); + if (!cmpTarget->pImpl->bounds(renderer, &x, &y, &w, &h)) return false; + cmp = renderer.addCompositor(x, y, w, h); + cmp->method = CompositeMethod::None; + cmp->opacity = 255; + cmpTarget->pImpl->render(renderer); } auto ret = smethod->render(renderer); @@ -213,8 +215,8 @@ namespace tvg { if (!target && method != CompositeMethod::None) return false; if (target && method == CompositeMethod::None) return false; - compTarget = target; - compMethod = method; + cmpTarget = target; + cmpMethod = method; return true; } }; diff --git a/src/lib/tvgRender.h b/src/lib/tvgRender.h index 681d4500..befbf90b 100644 --- a/src/lib/tvgRender.h +++ b/src/lib/tvgRender.h @@ -39,6 +39,11 @@ struct Surface using RenderData = void*; +struct Compositor { + CompositeMethod method; + uint32_t opacity; +}; + enum RenderUpdateFlag {None = 0, Path = 1, Color = 2, Gradient = 4, Stroke = 8, Transform = 16, Image = 32, All = 64}; struct RenderTransform @@ -57,18 +62,17 @@ struct RenderTransform RenderTransform(const RenderTransform* lhs, const RenderTransform* rhs); }; -class RenderMethod +struct RenderMethod { -public: virtual ~RenderMethod() {} virtual RenderData prepare(const Shape& shape, RenderData data, const RenderTransform* transform, uint32_t opacity, Array& clips, RenderUpdateFlag flags) = 0; virtual RenderData prepare(const Picture& picture, RenderData data, const RenderTransform* transform, uint32_t opacity, Array& clips, RenderUpdateFlag flags) = 0; - virtual void* addCompositor(CompositeMethod method, uint32_t x, uint32_t y, uint32_t w, uint32_t h, uint32_t opacity) = 0; - virtual bool delCompositor(void* cmp) = 0; + virtual Compositor* addCompositor(uint32_t x, uint32_t y, uint32_t w, uint32_t h) = 0; + virtual bool delCompositor(Compositor* cmp) = 0; virtual bool dispose(RenderData data) = 0; virtual bool preRender() = 0; - virtual bool renderShape(RenderData data, void* cmp) = 0; - virtual bool renderImage(RenderData data, void* cmp) = 0; + virtual bool renderShape(RenderData data, Compositor* cmp) = 0; + virtual bool renderImage(RenderData data, Compositor* cmp) = 0; virtual bool postRender() = 0; virtual bool renderRegion(RenderData data, uint32_t* x, uint32_t* y, uint32_t* w, uint32_t* h) = 0; virtual bool clear() = 0; diff --git a/src/lib/tvgSceneImpl.h b/src/lib/tvgSceneImpl.h index fc293641..047bb908 100644 --- a/src/lib/tvgSceneImpl.h +++ b/src/lib/tvgSceneImpl.h @@ -63,14 +63,16 @@ struct Scene::Impl bool render(RenderMethod& renderer) { - void* cmp = nullptr; + Compositor* cmp = nullptr; //Half translucent. This condition requires intermediate composition. if (opacity < 255 && opacity > 0 && (paints.count > 1)) { uint32_t x, y, w, h; if (!bounds(renderer, &x, &y, &w, &h)) return false; //CompositeMethod::None is used for a default alpha blending - cmp = renderer.addCompositor(CompositeMethod::None, x, y, w, h, opacity); + cmp = renderer.addCompositor(x, y, w, h); + cmp->method = CompositeMethod::None; + cmp->opacity = opacity; } for (auto paint = paints.data; paint < (paints.data + paints.count); ++paint) {