sw_engine image: optimized image rendering.
authorHermet Park <chuneon.park@samsung.com>
Fri, 12 Nov 2021 05:55:04 +0000 (14:55 +0900)
committerJunsuChoi <jsuya.choi@samsung.com>
Tue, 16 Nov 2021 08:37:47 +0000 (17:37 +0900)
Applied the fast-track routine for axis-aligned images.
This helps to remove outline generation if no clips.

src/lib/sw_engine/tvgSwCommon.h
src/lib/sw_engine/tvgSwImage.cpp
src/lib/sw_engine/tvgSwMath.cpp
src/lib/sw_engine/tvgSwRenderer.cpp
src/lib/tvgMath.h

index 31b6e3b..3dad781 100644 (file)
@@ -300,6 +300,7 @@ bool mathSmallCubic(const SwPoint* base, SwFixed& angleIn, SwFixed& angleMid, Sw
 SwFixed mathMean(SwFixed angle1, SwFixed angle2);
 SwPoint mathTransform(const Point* to, const Matrix* transform);
 bool mathUpdateOutlineBBox(const SwOutline* outline, const SwBBox& clipRegion, SwBBox& renderRegion, bool fastTrack);
+bool mathClipBBox(const SwBBox& clipper, SwBBox& clipee);
 
 void shapeReset(SwShape* shape);
 bool shapePrepare(SwShape* shape, const Shape* sdata, const Matrix* transform, const SwBBox& clipRegion, SwBBox& renderRegion, SwMpool* mpool, unsigned tid, bool hasComposite);
@@ -322,7 +323,7 @@ bool strokeParseOutline(SwStroke* stroke, const SwOutline& outline);
 SwOutline* strokeExportOutline(SwStroke* stroke, SwMpool* mpool, unsigned tid);
 void strokeFree(SwStroke* stroke);
 
-bool imagePrepare(SwImage* image, const Matrix* transform, const SwBBox& clipRegion, SwBBox& renderRegion, SwMpool* mpool, unsigned tid);
+bool imagePrepare(SwImage* image, const Matrix* transform, const SwBBox& clipRegion, SwBBox& renderRegion, SwMpool* mpool, unsigned tid, bool outline);
 bool imageGenRle(SwImage* image, TVG_UNUSED const Picture* pdata, const SwBBox& renderRegion, bool antiAlias);
 void imageDelOutline(SwImage* image, SwMpool* mpool, uint32_t tid);
 void imageReset(SwImage* image);
index 2ef024d..2233f7e 100644 (file)
@@ -19,7 +19,7 @@
  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  * SOFTWARE.
  */
-#include <algorithm>
+#include "tvgMath.h"
 #include "tvgSwCommon.h"
 
 /************************************************************************/
@@ -72,10 +72,19 @@ static bool _genOutline(SwImage* image, const Matrix* transform, SwMpool* mpool,
 /************************************************************************/
 
 
-bool imagePrepare(SwImage* image, const Matrix* transform, const SwBBox& clipRegion, SwBBox& renderRegion, SwMpool* mpool, unsigned tid)
+bool imagePrepare(SwImage* image, const Matrix* transform, const SwBBox& clipRegion, SwBBox& renderRegion, SwMpool* mpool, unsigned tid, bool outline)
 {
-    if (!_genOutline(image, transform, mpool, tid)) return false;
-    return mathUpdateOutlineBBox(image->outline, clipRegion, renderRegion, false);
+    if (outline || mathRotated(transform)) {
+        if (!_genOutline(image, transform, mpool, tid)) return false;
+        return mathUpdateOutlineBBox(image->outline, clipRegion, renderRegion, false);
+    //Fast Track, don't need outlines.
+    } else {
+        renderRegion.min.x = static_cast<SwCoord>(round(transform->e13));
+        renderRegion.max.x = renderRegion.min.x + static_cast<SwCoord>(image->w);
+        renderRegion.min.y = static_cast<SwCoord>(round(transform->e23));
+        renderRegion.max.y= renderRegion.min.y + static_cast<SwCoord>(image->h);
+        return mathClipBBox(clipRegion, renderRegion);
+    }
 }
 
 
index 22bc97f..e7470c7 100644 (file)
@@ -442,6 +442,24 @@ SwPoint mathTransform(const Point* to, const Matrix* transform)
 }
 
 
+bool mathClipBBox(const SwBBox& clipper, SwBBox& clipee)
+{
+    clipee.max.x = (clipee.max.x < clipper.max.x) ? clipee.max.x : clipper.max.x;
+    clipee.max.y = (clipee.max.y < clipper.max.y) ? clipee.max.y : clipper.max.y;
+    clipee.min.x = (clipee.min.x > clipper.min.x) ? clipee.min.x : clipper.min.x;
+    clipee.min.y = (clipee.min.y > clipper.min.y) ? clipee.min.y : clipper.min.y;
+
+    //Check valid region
+    if (clipee.max.x - clipee.min.x < 1 && clipee.max.y - clipee.min.y < 1) return false;
+
+    //Check boundary
+    if (clipee.min.x >= clipper.max.x || clipee.min.y >= clipper.max.y ||
+        clipee.max.x <= clipper.min.x || clipee.max.y <= clipper.min.y) return false;
+
+    return true;
+}
+
+
 bool mathUpdateOutlineBBox(const SwOutline* outline, const SwBBox& clipRegion, SwBBox& renderRegion, bool fastTrack)
 {
     if (!outline) return false;
@@ -466,7 +484,6 @@ bool mathUpdateOutlineBBox(const SwOutline* outline, const SwBBox& clipRegion, S
         if (yMin > pt->y) yMin = pt->y;
         if (yMax < pt->y) yMax = pt->y;
     }
-
     //Since no antialiasing is applied in the Fast Track case,
     //the rasterization region has to be rearranged.
     //https://github.com/Samsung/thorvg/issues/916
@@ -481,18 +498,5 @@ bool mathUpdateOutlineBBox(const SwOutline* outline, const SwBBox& clipRegion, S
         renderRegion.min.y = yMin >> 6;
         renderRegion.max.y = (yMax + 63) >> 6;
     }
-
-    renderRegion.max.x = (renderRegion.max.x < clipRegion.max.x) ? renderRegion.max.x : clipRegion.max.x;
-    renderRegion.max.y = (renderRegion.max.y < clipRegion.max.y) ? renderRegion.max.y : clipRegion.max.y;
-    renderRegion.min.x = (renderRegion.min.x > clipRegion.min.x) ? renderRegion.min.x : clipRegion.min.x;
-    renderRegion.min.y = (renderRegion.min.y > clipRegion.min.y) ? renderRegion.min.y : clipRegion.min.y;
-
-    //Check valid region
-    if (renderRegion.max.x - renderRegion.min.x < 1 && renderRegion.max.y - renderRegion.min.y < 1) return false;
-
-    //Check boundary
-    if (renderRegion.min.x >= clipRegion.max.x || renderRegion.min.y >= clipRegion.max.y ||
-        renderRegion.max.x <= clipRegion.min.x || renderRegion.max.y <= clipRegion.min.y) return false;
-
-    return true;
+    return mathClipBBox(clipRegion, renderRegion);
 }
\ No newline at end of file
index b50aa62..8cc0b8e 100644 (file)
@@ -192,10 +192,11 @@ struct SwImageTask : SwTask
             if (!image.data || image.w == 0 || image.h == 0) goto end;
             image.stride = image.w;     //same, pixel buffer size.
 
-            if (!imagePrepare(&image, transform, clipRegion, bbox, mpool, tid)) goto end;
+            auto clipPath = (clips.count > 0) ? true : false;
 
-            //Clip Path?
-            if (clips.count > 0) {
+            if (!imagePrepare(&image, transform, clipRegion, bbox, mpool, tid, clipPath)) goto end;
+
+            if (clipPath) {
                 if (!imageGenRle(&image, pdata, bbox, false)) goto end;
                 if (image.rle) {
                     for (auto clip = clips.data; clip < (clips.data + clips.count); ++clip) {
index 363fd30..b9a0488 100644 (file)
 #include <math.h>
 #include "tvgCommon.h"
 
+static inline bool mathRotated(const Matrix* m)
+{
+    if (fabs(m->e12) > FLT_EPSILON || fabs(m->e21 > FLT_EPSILON)) return true;
+    else return false;
+}
+
 
 static inline bool mathIdentity(const Matrix* m)
 {