sw_engine: optimize rle rendering. 79/237779/2
authorHermet Park <chuneon.park@samsung.com>
Fri, 3 Jul 2020 09:17:43 +0000 (18:17 +0900)
committerHermet Park <chuneon.park@samsung.com>
Fri, 3 Jul 2020 09:32:50 +0000 (18:32 +0900)
we don't need to apply anti-aliasing if stroke is there.
here turns off anti-alias if stroke width is more than 2.
magic number 2 is experimentally confirmed.

Change-Id: I09031dc2a0a84f31c5904651ed1e62004645ba9a

src/lib/sw_engine/tvgSwCommon.h
src/lib/sw_engine/tvgSwRenderer.cpp
src/lib/sw_engine/tvgSwRle.cpp
src/lib/sw_engine/tvgSwShape.cpp
test/testShape.cpp

index 5db4cd7..8d90342 100644 (file)
@@ -265,7 +265,7 @@ SwFixed mathMean(SwFixed angle1, SwFixed angle2);
 void shapeReset(SwShape& shape);
 bool shapeGenOutline(SwShape& shape, const Shape* sdata);
 bool shapePrepare(SwShape& shape, const Shape* sdata, const SwSize& clip, const Matrix* transform);
-bool shapeGenRle(SwShape& shape, const Shape* sdata, const SwSize& clip);
+bool shapeGenRle(SwShape& shape, const Shape* sdata, const SwSize& clip, bool antiAlias);
 void shapeDelOutline(SwShape& shape);
 void shapeResetStroke(SwShape& shape, const Shape* sdata);
 bool shapeGenStrokeRle(SwShape& shape, const Shape* sdata, const SwSize& clip);
@@ -286,7 +286,7 @@ void fillFree(SwFill* fill);
 void fillFetchLinear(const SwFill* fill, uint32_t* dst, uint32_t y, uint32_t x, uint32_t len);
 void fillFetchRadial(const SwFill* fill, uint32_t* dst, uint32_t y, uint32_t x, uint32_t len);
 
-SwRleData* rleRender(const SwOutline* outline, const SwBBox& bbox, const SwSize& clip);
+SwRleData* rleRender(const SwOutline* outline, const SwBBox& bbox, const SwSize& clip, bool antiAlias);
 void rleFree(SwRleData* rle);
 
 bool rasterGradientShape(Surface& surface, SwShape& shape, unsigned id);
index b9ce7c0..adc3e9f 100644 (file)
@@ -109,7 +109,7 @@ void SwRenderer::doRender()
             if (a > 0) rasterSolidShape(surface, task->shape, r, g, b, a);
         }
         task->sdata->strokeColor(&r, &g, &b, &a);
-        if (a > 0) rasterStroke(surface, task->shape, r, g, b, a);
+       if (a > 0) rasterStroke(surface, task->shape, r, g, b, a);
         renderTasks.pop();
     }
 }
@@ -178,7 +178,8 @@ void* SwRenderer::prepare(const Shape& sdata, void* data, const RenderTransform*
 
         //Valid Stroking?
         uint8_t strokeAlpha = 0;
-        if (task->sdata->strokeWidth() > FLT_EPSILON) {
+        auto strokeWidth = task->sdata->strokeWidth();
+        if (strokeWidth > FLT_EPSILON) {
             task->sdata->strokeColor(nullptr, nullptr, nullptr, &strokeAlpha);
         }
 
@@ -188,10 +189,11 @@ void* SwRenderer::prepare(const Shape& sdata, void* data, const RenderTransform*
             uint8_t alpha = 0;
             task->sdata->fill(nullptr, nullptr, nullptr, &alpha);
             bool renderShape = (alpha > 0 || task->sdata->fill());
-            if (renderShape || strokeAlpha > 0) {
+            if (renderShape || strokeAlpha) {
                 if (!shapePrepare(task->shape, task->sdata, task->clip, task->transform)) return;
                 if (renderShape) {
-                    if (!shapeGenRle(task->shape, task->sdata, task->clip)) return;
+                    auto antiAlias = (strokeAlpha > 0 && strokeWidth >= 2) ? false : true;
+                    if (!shapeGenRle(task->shape, task->sdata, task->clip, antiAlias)) return;
                 }
             }
         }
index 5bb3a31..6ee6f7c 100644 (file)
@@ -87,6 +87,7 @@ struct RleWorker
     SwSize clip;
 
     bool invalid;
+    bool antiAlias;
 };
 
 
@@ -196,6 +197,7 @@ static void _horizLine(RleWorker& rw, SwCoord x, SwCoord y, SwCoord area, SwCoor
     }
 
     if (coverage > 0) {
+        if (!rw.antiAlias) coverage = 255;
         auto count = rw.spansCnt;
         auto span = rw.spans + count - 1;
         assert(span);
@@ -261,22 +263,16 @@ static void _sweep(RleWorker& rw)
 
         while (cell) {
 
-            if (cell->x > x && cover != 0)
-                _horizLine(rw, x, y, cover * (ONE_PIXEL * 2), cell->x - x);
-
+            if (cell->x > x && cover != 0) _horizLine(rw, x, y, cover * (ONE_PIXEL * 2), cell->x - x);
             cover += cell->cover;
             auto area = cover * (ONE_PIXEL * 2) - cell->area;
-
-            //OPTIMIZE ME: This occurs 1 length span data.
-            if (area != 0 && cell->x >= 0)
-                _horizLine(rw, cell->x, y, area, 1);
+            if (area != 0 && cell->x >= 0) _horizLine(rw, cell->x, y, area, 1);
 
             x = cell->x + 1;
             cell = cell->next;
         }
 
-        if (cover != 0)
-            _horizLine(rw, x, y, cover * (ONE_PIXEL * 2), rw.cellXCnt - x);
+        if (cover != 0) _horizLine(rw, x, y, cover * (ONE_PIXEL * 2), rw.cellXCnt - x);
     }
 
     if (rw.spansCnt > 0) _genSpan(rw.rle, rw.spans, rw.spansCnt);
@@ -648,7 +644,7 @@ static bool _genRle(RleWorker& rw)
 /* External Class Implementation                                        */
 /************************************************************************/
 
-SwRleData* rleRender(const SwOutline* outline, const SwBBox& bbox, const SwSize& clip)
+SwRleData* rleRender(const SwOutline* outline, const SwBBox& bbox, const SwSize& clip, bool antiAlias)
 {
     //Please adjust when you out of cell memory (default: 16384L)
     constexpr auto RENDER_POOL_SIZE = 163840L * 2;
@@ -681,6 +677,7 @@ SwRleData* rleRender(const SwOutline* outline, const SwBBox& bbox, const SwSize&
     rw.bandSize = rw.bufferSize / (sizeof(Cell) * 8);  //bandSize: 64
     rw.bandShoot = 0;
     rw.clip = clip;
+    rw.antiAlias = antiAlias;
     rw.rle = reinterpret_cast<SwRleData*>(calloc(1, sizeof(SwRleData)));
     assert(rw.rle);
 
index dbdfb6a..a2ca5c6 100644 (file)
@@ -477,7 +477,7 @@ bool shapePrepare(SwShape& shape, const Shape* sdata, const SwSize& clip, const
 }
 
 
-bool shapeGenRle(SwShape& shape, const Shape* sdata, const SwSize& clip)
+bool shapeGenRle(SwShape& shape, const Shape* sdata, const SwSize& clip, bool antiAlias)
 {
     //FIXME: Should we draw it?
     //Case: Stroke Line
@@ -486,7 +486,7 @@ bool shapeGenRle(SwShape& shape, const Shape* sdata, const SwSize& clip)
     //Case A: Fast Track Rectangle Drawing
     if ((shape.rect = _fastTrack(shape.outline))) return true;
     //Case B: Normale Shape RLE Drawing
-    if ((shape.rle = rleRender(shape.outline, shape.bbox, clip))) return true;
+    if ((shape.rle = rleRender(shape.outline, shape.bbox, clip, antiAlias))) return true;
 
     return false;
 }
@@ -667,7 +667,7 @@ bool shapeGenStrokeRle(SwShape& shape, const Shape* sdata, const SwSize& clip)
 
     if (!_checkValid(strokeOutline, bbox, clip)) return false;
 
-    shape.strokeRle = rleRender(strokeOutline, bbox, clip);
+    shape.strokeRle = rleRender(strokeOutline, bbox, clip, true);
 
     _delOutline(strokeOutline);
 
index 5bf9e65..617d024 100644 (file)
@@ -119,4 +119,4 @@ int main(int argc, char **argv)
 
     //Terminate ThorVG Engine
     tvg::Initializer::term(tvgEngine);
-}
\ No newline at end of file
+}