diff --git a/src/lib/tvgPaint.cpp b/src/lib/tvgPaint.cpp index 18f261f5..a8f6e5ea 100644 --- a/src/lib/tvgPaint.cpp +++ b/src/lib/tvgPaint.cpp @@ -34,7 +34,7 @@ static inline bool FLT_SAME(float a, float b) } -static bool _clipPathFastTrack(Paint* cmpTarget, const RenderTransform* pTransform, RenderTransform* rTransform, RenderRegion& viewport) +static bool _compFastTrack(Paint* cmpTarget, const RenderTransform* pTransform, RenderTransform* rTransform, RenderRegion& viewport) { /* Access Shape class by Paint is bad... but it's ok still it's an internal usage. */ auto shape = static_cast(cmpTarget); @@ -164,9 +164,11 @@ bool Paint::Impl::render(RenderMethod& renderer) { Compositor* cmp = nullptr; + //OPTIMIZE_ME: Can we replace the simple AlphaMasking with ClipPath? + /* Note: only ClipPath is processed in update() step. Create a composition image. */ - if (cmpTarget && cmpMethod != CompositeMethod::ClipPath) { + if (cmpTarget && cmpMethod != CompositeMethod::ClipPath && !(cmpTarget->pImpl->ctxFlag & ContextFlag::FastTrack)) { auto region = smethod->bounds(renderer); if (region.w == 0 || region.h == 0) return false; cmp = renderer.target(region); @@ -200,17 +202,27 @@ void* Paint::Impl::update(RenderMethod& renderer, const RenderTransform* pTransf bool cmpFastTrack = false; if (cmpTarget) { - /* If transform has no rotation factors && ClipPath is a simple rectangle, - we can avoid regular ClipPath sequence but use viewport for performance */ - if (cmpMethod == CompositeMethod::ClipPath) { + /* If transform has no rotation factors && ClipPath / AlphaMasking is a simple rectangle, + we can avoid regular ClipPath / AlphaMasking sequence but use viewport for performance */ + auto tryFastTrack = false; + if (cmpMethod == CompositeMethod::ClipPath) tryFastTrack = true; + else if (cmpMethod == CompositeMethod::AlphaMask) { + auto shape = static_cast(cmpTarget); + uint8_t a; + shape->fillColor(nullptr, nullptr, nullptr, &a); + if (a == 255 && shape->opacity() == 255 && !shape->fill()) tryFastTrack = true; + } + if (tryFastTrack) { RenderRegion viewport2; - if ((cmpFastTrack = _clipPathFastTrack(cmpTarget, pTransform, cmpTarget->pImpl->rTransform, viewport2))) { + if ((cmpFastTrack = _compFastTrack(cmpTarget, pTransform, cmpTarget->pImpl->rTransform, viewport2))) { viewport = renderer.viewport(); viewport2.intersect(viewport); renderer.viewport(viewport2); + cmpTarget->pImpl->ctxFlag |= ContextFlag::FastTrack; + } else { + cmpTarget->pImpl->ctxFlag &= ~ContextFlag::FastTrack; } } - if (!cmpFastTrack) { cmpData = cmpTarget->pImpl->update(renderer, pTransform, 255, clips, pFlag); if (cmpMethod == CompositeMethod::ClipPath) clips.push(cmpData); diff --git a/src/lib/tvgPaint.h b/src/lib/tvgPaint.h index f2b681a1..5b9e0db7 100644 --- a/src/lib/tvgPaint.h +++ b/src/lib/tvgPaint.h @@ -27,6 +27,8 @@ namespace tvg { + enum ContextFlag {Invalid = 0, FastTrack = 1}; + struct Iterator { virtual ~Iterator() {} @@ -51,10 +53,11 @@ namespace tvg struct Paint::Impl { StrategyMethod* smethod = nullptr; - RenderTransform *rTransform = nullptr; + RenderTransform* rTransform = nullptr; uint32_t renderFlag = RenderUpdateFlag::None; Paint* cmpTarget = nullptr; CompositeMethod cmpMethod = CompositeMethod::None; + uint32_t ctxFlag = ContextFlag::Invalid; uint8_t opacity = 255; ~Impl() {