From 2a239714afb75fa479286c56f6a8c046cf8db6c1 Mon Sep 17 00:00:00 2001 From: Hermet Park Date: Tue, 13 Oct 2020 16:31:39 +0900 Subject: [PATCH] sw_engine: fix missing shape update issue. It missed to update shape data if visilibity is changed from false to true by alpha. Also, it needs to update engine shape data for every requests. There scenario can be allowed, 1. update shape 2. change shape property 3. update shape 4. draw previously engine could skip step 3, its result was not properly expected. @fix #84 --- src/examples/Stress.cpp | 9 ++++++++- src/lib/sw_engine/tvgSwCommon.h | 1 + src/lib/sw_engine/tvgSwRenderer.cpp | 15 +++++++++++---- src/lib/sw_engine/tvgSwShape.cpp | 6 ++++++ 4 files changed, 26 insertions(+), 5 deletions(-) diff --git a/src/examples/Stress.cpp b/src/examples/Stress.cpp index 5d9eadf3..4019b05a 100644 --- a/src/examples/Stress.cpp +++ b/src/examples/Stress.cpp @@ -8,6 +8,7 @@ #define NUM_PER_LINE 16 #define SIZE 50 +static bool rendered = false; static int count = 0; static int frame = 0; static std::vector pictures; @@ -108,10 +109,14 @@ void drawSwView(void* data, Eo* obj) t4 = ecore_time_get(); printf("[%5d]: total[%fs] update[%fs], render[%fs]\n", ++frame, t4 - t1, t2 - t1, t4 - t3); + + rendered = true; } void transitSwCb(Elm_Transit_Effect *effect, Elm_Transit* transit, double progress) { + if (!rendered) return; + t1 = ecore_time_get(); for (auto picture : pictures) { @@ -124,7 +129,9 @@ void transitSwCb(Elm_Transit_Effect *effect, Elm_Transit* transit, double progre //Update Efl Canvas auto img = (Eo*) effect; evas_object_image_pixels_dirty_set(img, EINA_TRUE); - evas_object_image_data_update_add(img, 0, 0, WIDTH, HEIGHT); + evas_object_image_data_update_add(img, 0, 0, WIDTH, HEIGHT); + + rendered = false; } diff --git a/src/lib/sw_engine/tvgSwCommon.h b/src/lib/sw_engine/tvgSwCommon.h index 47a69154..0bcd5d35 100644 --- a/src/lib/sw_engine/tvgSwCommon.h +++ b/src/lib/sw_engine/tvgSwCommon.h @@ -270,6 +270,7 @@ SwFixed mathMean(SwFixed angle1, SwFixed angle2); void shapeReset(SwShape* shape); bool shapeGenOutline(SwShape* shape, const Shape* sdata, const Matrix* transform); bool shapePrepare(SwShape* shape, const Shape* sdata, const SwSize& clip, const Matrix* transform); +bool shapePrepared(SwShape* shape); bool shapeGenRle(SwShape* shape, const Shape* sdata, const SwSize& clip, bool antiAlias, bool hasComposite); void shapeDelOutline(SwShape* shape); void shapeResetStroke(SwShape* shape, const Shape* sdata, const Matrix* transform); diff --git a/src/lib/sw_engine/tvgSwRenderer.cpp b/src/lib/sw_engine/tvgSwRenderer.cpp index 6b7cb0a7..3f94179f 100644 --- a/src/lib/sw_engine/tvgSwRenderer.cpp +++ b/src/lib/sw_engine/tvgSwRenderer.cpp @@ -49,13 +49,17 @@ struct SwTask : Task SwSize clip = {static_cast(surface->w), static_cast(surface->h)}; + //Invisiable shape turned to visible by alpha. + auto prepareShape = false; + if (!shapePrepared(&shape) && (flags & RenderUpdateFlag::Color)) prepareShape = true; + //Shape - if (flags & (RenderUpdateFlag::Path | RenderUpdateFlag::Transform)) { - shapeReset(&shape); + if (flags & (RenderUpdateFlag::Path | RenderUpdateFlag::Transform) || prepareShape) { uint8_t alpha = 0; sdata->fill(nullptr, nullptr, nullptr, &alpha); bool renderShape = (alpha > 0 || sdata->fill()); if (renderShape || strokeAlpha) { + shapeReset(&shape); if (!shapePrepare(&shape, sdata, clip, transform)) return; if (renderShape) { auto antiAlias = (strokeAlpha > 0 && strokeWidth >= 2) ? false : true; @@ -209,12 +213,15 @@ void* SwRenderer::prepare(const Shape& sdata, void* data, const RenderTransform* if (!task) return nullptr; } - if (flags == RenderUpdateFlag::None || task->valid()) return task; + if (flags == RenderUpdateFlag::None) return task; + + //Finish previous task if it has duplicated request. + if (task->valid()) task->get(); task->sdata = &sdata; if (compList.size() > 0) { - //Gurantee composition targets get ready. + //Guarantee composition targets get ready. for (auto comp : compList) static_cast(comp.edata)->get(); task->compList.assign(compList.begin(), compList.end()); } diff --git a/src/lib/sw_engine/tvgSwShape.cpp b/src/lib/sw_engine/tvgSwShape.cpp index 49166ecf..68b5387b 100644 --- a/src/lib/sw_engine/tvgSwShape.cpp +++ b/src/lib/sw_engine/tvgSwShape.cpp @@ -459,6 +459,12 @@ bool shapePrepare(SwShape* shape, const Shape* sdata, const SwSize& clip, const } +bool shapePrepared(SwShape* shape) +{ + return shape->rle ? true : false; +} + + bool shapeGenRle(SwShape* shape, TVG_UNUSED const Shape* sdata, const SwSize& clip, bool antiAlias, bool hasComposite) { //FIXME: Should we draw it?