diff --git a/src/lib/gl_engine/tvgGlRenderer.cpp b/src/lib/gl_engine/tvgGlRenderer.cpp index e05bc615..8ea9539f 100644 --- a/src/lib/gl_engine/tvgGlRenderer.cpp +++ b/src/lib/gl_engine/tvgGlRenderer.cpp @@ -235,7 +235,7 @@ RenderData GlRenderer::prepare(const Shape& shape, RenderData data, const Render RenderRegion GlRenderer::viewport() { - return {0, 0, UINT32_MAX, UINT32_MAX}; + return {0, 0, INT32_MAX, INT32_MAX}; } diff --git a/src/lib/sw_engine/tvgSwRenderer.cpp b/src/lib/sw_engine/tvgSwRenderer.cpp index e1d5d2a5..61c9156e 100644 --- a/src/lib/sw_engine/tvgSwRenderer.cpp +++ b/src/lib/sw_engine/tvgSwRenderer.cpp @@ -287,8 +287,7 @@ RenderRegion SwRenderer::viewport() bool SwRenderer::viewport(const RenderRegion& vp) { - this->vport = vp; - + vport = vp; return true; } @@ -456,9 +455,11 @@ Compositor* SwRenderer::target(const RenderRegion& region) auto y = region.y; auto w = region.w; auto h = region.h; + auto sw = static_cast(surface->w); + auto sh = static_cast(surface->h); //Out of boundary - if (x > surface->w || y > surface->h) return nullptr; + if (x > sw || y > sh) return nullptr; SwSurface* cmp = nullptr; @@ -488,8 +489,8 @@ Compositor* SwRenderer::target(const RenderRegion& region) } //Boundary Check - if (x + w > surface->w) w = (surface->w - x); - if (y + h > surface->h) h = (surface->h - y); + if (x + w > sw) w = (sw - x); + if (y + h > sh) h = (sh - y); TVGLOG("SW_ENGINE", "Using intermediate composition [Region: %d %d %d %d]", x, y, w, h); diff --git a/src/lib/tvgPaint.cpp b/src/lib/tvgPaint.cpp index 609bfdb4..3ea05aae 100644 --- a/src/lib/tvgPaint.cpp +++ b/src/lib/tvgPaint.cpp @@ -19,8 +19,6 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ -#include -#include #include "tvgMath.h" #include "tvgPaint.h" @@ -40,7 +38,7 @@ static bool _compFastTrack(Paint* cmpTarget, const RenderTransform* pTransform, if (rTransform) rTransform->update(); - //No Rotation? + //No rotational. if (pTransform && !mathRightAngle(&pTransform->m)) return false; if (rTransform && !mathRightAngle(&rTransform->m)) return false; @@ -53,32 +51,39 @@ static bool _compFastTrack(Paint* cmpTarget, const RenderTransform* pTransform, if ((mathEqual(pt1->x, pt2->x) && mathEqual(pt2->y, pt3->y) && mathEqual(pt3->x, pt4->x) && mathEqual(pt1->y, pt4->y)) || (mathEqual(pt2->x, pt3->x) && mathEqual(pt1->y, pt2->y) && mathEqual(pt1->x, pt4->x) && mathEqual(pt3->y, pt4->y))) { - auto x1 = pt1->x; - auto y1 = pt1->y; - auto x2 = pt3->x; - auto y2 = pt3->y; + auto v1 = *pt1; + auto v2 = *pt3; if (rTransform) { - x1 = x1 * rTransform->m.e11 + rTransform->m.e13; - y1 = y1 * rTransform->m.e22 + rTransform->m.e23; - x2 = x2 * rTransform->m.e11 + rTransform->m.e13; - y2 = y2 * rTransform->m.e22 + rTransform->m.e23; + mathMultiply(&v1, &rTransform->m); + mathMultiply(&v2, &rTransform->m); } if (pTransform) { - x1 = x1 * pTransform->m.e11 + pTransform->m.e13; - y1 = y1 * pTransform->m.e22 + pTransform->m.e23; - x2 = x2 * pTransform->m.e11 + pTransform->m.e13; - y2 = y2 * pTransform->m.e22 + pTransform->m.e23; + mathMultiply(&v1, &pTransform->m); + mathMultiply(&v2, &pTransform->m); } - if (x1 < 0.0f) x1 = 0.0f; - if (y1 < 0.0f) y1 = 0.0f; + //sorting + if (v1.x > v2.x) { + auto tmp = v2.x; + v2.x = v1.x; + v1.x = tmp; + } - viewport.x = static_cast(x1); - viewport.y = static_cast(y1); - viewport.w = static_cast(x2 - x1 < 0 ? 0 : roundf(x2 - x1 + 0.5f)); - viewport.h = static_cast(y2 - y1 < 0 ? 0 : roundf(y2 - y1 + 0.5f)); + if (v1.y > v2.y) { + auto tmp = v2.y; + v2.y = v1.y; + v1.y = tmp; + } + + viewport.x = static_cast(v1.x); + viewport.y = static_cast(v1.y); + viewport.w = static_cast(v2.x - v1.x + 0.5f); + viewport.h = static_cast(v2.y - v1.y + 0.5f); + + if (viewport.w < 0) viewport.w = 0; + if (viewport.h < 0) viewport.h = 0; return true; } @@ -197,6 +202,8 @@ void* Paint::Impl::update(RenderMethod& renderer, const RenderTransform* pTransf bool cmpFastTrack = false; if (cmpTarget) { + cmpTarget->pImpl->ctxFlag = ContextFlag::Invalid; //reset + /* 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; @@ -214,8 +221,6 @@ void* Paint::Impl::update(RenderMethod& renderer, const RenderTransform* pTransf viewport2.intersect(viewport); renderer.viewport(viewport2); cmpTarget->pImpl->ctxFlag |= ContextFlag::FastTrack; - } else { - cmpTarget->pImpl->ctxFlag &= ~ContextFlag::FastTrack; } } if (!cmpFastTrack) { diff --git a/src/lib/tvgRender.h b/src/lib/tvgRender.h index a1a86848..671370e5 100644 --- a/src/lib/tvgRender.h +++ b/src/lib/tvgRender.h @@ -49,7 +49,7 @@ struct Compositor struct RenderRegion { - uint32_t x, y, w, h; + int32_t x, y, w, h; void intersect(const RenderRegion& rhs) { @@ -62,6 +62,9 @@ struct RenderRegion y = (y > rhs.y) ? y : rhs.y; w = ((x1 < x2) ? x1 : x2) - x; h = ((y1 < y2) ? y1 : y2) - y; + + if (w < 0) w = 0; + if (h < 0) h = 0; } }; diff --git a/src/lib/tvgSceneImpl.h b/src/lib/tvgSceneImpl.h index fb979ae5..5e8ce3d9 100644 --- a/src/lib/tvgSceneImpl.h +++ b/src/lib/tvgSceneImpl.h @@ -131,10 +131,10 @@ struct Scene::Impl { if (paints.count == 0) return {0, 0, 0, 0}; - uint32_t x1 = UINT32_MAX; - uint32_t y1 = UINT32_MAX; - uint32_t x2 = 0; - uint32_t y2 = 0; + int32_t x1 = INT32_MAX; + int32_t y1 = INT32_MAX; + int32_t x2 = 0; + int32_t y2 = 0; for (auto paint = paints.data; paint < (paints.data + paints.count); ++paint) { auto region = (*paint)->pImpl->bounds(renderer);