common paint: fix the wrong fast track logic.
authorHermet Park <chuneon.park@samsung.com>
Mon, 22 Nov 2021 03:31:23 +0000 (12:31 +0900)
committerJunsuChoi <jsuya.choi@samsung.com>
Thu, 25 Nov 2021 00:34:37 +0000 (09:34 +0900)
There was a missing sorting between the left-top & right-bottom corner.
that results in the negative values of the viewport...

Now fixed it.

+ refactored to use math functions...
+ still it's a buggy, sometimes no draw at 90' in stress. don't know reason. :(

src/lib/gl_engine/tvgGlRenderer.cpp
src/lib/sw_engine/tvgSwRenderer.cpp
src/lib/tvgPaint.cpp
src/lib/tvgRender.h
src/lib/tvgSceneImpl.h

index e05bc61..8ea9539 100644 (file)
@@ -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};
 }
 
 
index e1d5d2a..61c9156 100644 (file)
@@ -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<int32_t>(surface->w);
+    auto sh = static_cast<int32_t>(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);
 
index 609bfdb..3ea05aa 100644 (file)
@@ -19,8 +19,6 @@
  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  * SOFTWARE.
  */
-#include <float.h>
-#include <math.h>
 #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;
+        }
+
+        if (v1.y > v2.y) {
+            auto tmp = v2.y;
+            v2.y = v1.y;
+            v1.y = tmp;
+        }
 
-        viewport.x = static_cast<uint32_t>(x1);
-        viewport.y = static_cast<uint32_t>(y1);
-        viewport.w = static_cast<uint32_t>(x2 - x1 < 0 ? 0 : roundf(x2 - x1 + 0.5f));
-        viewport.h = static_cast<uint32_t>(y2 - y1 < 0 ? 0 : roundf(y2 - y1 + 0.5f));
+        viewport.x = static_cast<int32_t>(v1.x);
+        viewport.y = static_cast<int32_t>(v1.y);
+        viewport.w = static_cast<int32_t>(v2.x - v1.x + 0.5f);
+        viewport.h = static_cast<int32_t>(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) {
index a1a8684..671370e 100644 (file)
@@ -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;
     }
 };
 
index fb979ae..5e8ce3d 100644 (file)
@@ -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);