From 36c76ca73ca4791ee1d42d14dde16dda3f4f4b9f Mon Sep 17 00:00:00 2001 From: Hermet Park Date: Tue, 23 Jun 2020 20:12:39 +0900 Subject: [PATCH] sw_engine: threading optimization make it prepare step asynchronously. Change-Id: Ifb85f01d579cf1c111558842496b93fcaef74cd9 --- src/lib/sw_engine/tvgSwCommon.h | 32 +++++--- src/lib/sw_engine/tvgSwFill.cpp | 22 +++--- src/lib/sw_engine/tvgSwRenderer.cpp | 109 +++++++++++++++------------- src/lib/sw_engine/tvgSwShape.cpp | 67 ++++++++--------- src/lib/sw_engine/tvgSwStroke.cpp | 10 ++- src/lib/tvgCanvasImpl.h | 10 +-- src/meson.build | 3 +- test/testBlending.cpp | 3 +- test/testBoundary.cpp | 3 +- test/testCustomTransform.cpp | 3 +- test/testGlShape.cpp | 15 ++-- test/testGradientTransform.cpp | 3 +- test/testLinearGradient.cpp | 3 +- test/testMultiShapes.cpp | 3 +- test/testPath.cpp | 3 +- test/testPathCopy.cpp | 3 +- test/testRadialGradient.cpp | 3 +- test/testScene.cpp | 3 +- test/testSceneTransform.cpp | 3 +- test/testShape.cpp | 3 +- test/testStress.cpp | 48 ++++++------ test/testStroke.cpp | 4 +- test/testStrokeLine.cpp | 3 +- test/testSvg.cpp | 3 +- test/testTransform.cpp | 3 +- test/testUpdate.cpp | 3 +- 26 files changed, 186 insertions(+), 182 deletions(-) diff --git a/src/lib/sw_engine/tvgSwCommon.h b/src/lib/sw_engine/tvgSwCommon.h index 71af7df8..9c540888 100644 --- a/src/lib/sw_engine/tvgSwCommon.h +++ b/src/lib/sw_engine/tvgSwCommon.h @@ -17,6 +17,8 @@ #ifndef _TVG_SW_COMMON_H_ #define _TVG_SW_COMMON_H_ +#include +#include #include "tvgCommon.h" #if 0 @@ -201,6 +203,16 @@ struct SwShape }; +struct SwTask +{ + SwShape shape; + const Shape* sdata; + SwSize clip; + const Matrix* transform; + RenderUpdateFlag flags; + future prepared; +}; + static inline SwPoint TO_SWPOINT(const Point* pt) { return {SwCoord(pt->x * 64), SwCoord(pt->y * 64)}; @@ -261,24 +273,24 @@ bool mathSmallCubic(SwPoint* base, SwFixed& angleIn, SwFixed& angleMid, SwFixed& SwFixed mathMean(SwFixed angle1, SwFixed angle2); void shapeReset(SwShape& shape); -bool shapeGenOutline(SwShape& shape, const Shape& sdata); -bool shapeGenRle(SwShape& shape, const Shape& sdata, const SwSize& clip, const RenderTransform* transform); +bool shapeGenOutline(SwShape& shape, const Shape* sdata); +bool shapeGenRle(SwShape& shape, const Shape* sdata, const SwSize& clip, const Matrix* transform); void shapeDelOutline(SwShape& shape); -void shapeResetStroke(SwShape& shape, const Shape& sdata); -bool shapeGenStrokeRle(SwShape& shape, const Shape& sdata, const SwSize& clip); -void shapeFree(SwShape* shape); +void shapeResetStroke(SwShape& shape, const Shape* sdata); +bool shapeGenStrokeRle(SwShape& shape, const Shape* sdata, const SwSize& clip); +void shapeFree(SwShape& shape); void shapeDelStroke(SwShape& shape); -bool shapeGenFillColors(SwShape& shape, const Fill* fill, const RenderTransform* transform, bool ctable); -void shapeResetFill(SwShape& shape, const Fill* fill); +bool shapeGenFillColors(SwShape& shape, const Fill* fill, const Matrix* transform, bool ctable); +void shapeResetFill(SwShape& shape); void shapeDelFill(SwShape& shape); -void strokeReset(SwStroke& stroke, const Shape& shape); +void strokeReset(SwStroke& stroke, const Shape* shape); bool strokeParseOutline(SwStroke& stroke, const SwOutline& outline); SwOutline* strokeExportOutline(SwStroke& stroke); void strokeFree(SwStroke* stroke); -bool fillGenColorTable(SwFill* fill, const Fill* fdata, const RenderTransform* transform, bool ctable); -void fillReset(SwFill* fill, const Fill* fdata); +bool fillGenColorTable(SwFill* fill, const Fill* fdata, const Matrix* transform, bool ctable); +void fillReset(SwFill* fill); 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); diff --git a/src/lib/sw_engine/tvgSwFill.cpp b/src/lib/sw_engine/tvgSwFill.cpp index 2a9ba698..5992bcaa 100644 --- a/src/lib/sw_engine/tvgSwFill.cpp +++ b/src/lib/sw_engine/tvgSwFill.cpp @@ -88,7 +88,7 @@ static bool _updateColorTable(SwFill* fill, const Fill* fdata) } -bool _prepareLinear(SwFill* fill, const LinearGradient* linear, const RenderTransform* transform) +bool _prepareLinear(SwFill* fill, const LinearGradient* linear, const Matrix* transform) { assert(fill && linear); @@ -100,12 +100,12 @@ bool _prepareLinear(SwFill* fill, const LinearGradient* linear, const RenderTran auto cy = (y2 - y1) * 0.5f + y1; auto dx = x1 - cx; auto dy = y1 - cy; - x1 = dx * transform->m.e11 + dy * transform->m.e12 + transform->m.e31; - y1 = dx * transform->m.e21 + dy * transform->m.e22 + transform->m.e32; + x1 = dx * transform->e11 + dy * transform->e12 + transform->e31; + y1 = dx * transform->e21 + dy * transform->e22 + transform->e32; dx = x2 - cx; dy = y2 - cy; - x2 = dx * transform->m.e11 + dy * transform->m.e12 + transform->m.e31; - y2 = dx * transform->m.e21 + dy * transform->m.e22 + transform->m.e32; + x2 = dx * transform->e11 + dy * transform->e12 + transform->e31; + y2 = dx * transform->e21 + dy * transform->e22 + transform->e32; } fill->linear.dx = x2 - x1; @@ -122,7 +122,7 @@ bool _prepareLinear(SwFill* fill, const LinearGradient* linear, const RenderTran } -bool _prepareRadial(SwFill* fill, const RadialGradient* radial, const RenderTransform* transform) +bool _prepareRadial(SwFill* fill, const RadialGradient* radial, const Matrix* transform) { assert(fill && radial); @@ -131,11 +131,11 @@ bool _prepareRadial(SwFill* fill, const RadialGradient* radial, const RenderTran if (radius < FLT_EPSILON) return true; if (transform) { - auto tx = fill->radial.cx * transform->m.e11 + fill->radial.cy * transform->m.e12 + transform->m.e31; - auto ty = fill->radial.cx * transform->m.e21 + fill->radial.cy * transform->m.e22 + transform->m.e32; + auto tx = fill->radial.cx * transform->e11 + fill->radial.cy * transform->e12 + transform->e31; + auto ty = fill->radial.cx * transform->e21 + fill->radial.cy * transform->e22 + transform->e32; fill->radial.cx = tx; fill->radial.cy = ty; - radius *= transform->m.e33; + radius *= transform->e33; } fill->radial.a = radius * radius; @@ -248,7 +248,7 @@ void fillFetchLinear(const SwFill* fill, uint32_t* dst, uint32_t y, uint32_t x, } -bool fillGenColorTable(SwFill* fill, const Fill* fdata, const RenderTransform* transform, bool ctable) +bool fillGenColorTable(SwFill* fill, const Fill* fdata, const Matrix* transform, bool ctable) { if (!fill) return false; @@ -272,7 +272,7 @@ bool fillGenColorTable(SwFill* fill, const Fill* fdata, const RenderTransform* t } -void fillReset(SwFill* fill, const Fill* fdata) +void fillReset(SwFill* fill) { if (fill->ctable) { free(fill->ctable); diff --git a/src/lib/sw_engine/tvgSwRenderer.cpp b/src/lib/sw_engine/tvgSwRenderer.cpp index 9a5db51e..8c59029c 100644 --- a/src/lib/sw_engine/tvgSwRenderer.cpp +++ b/src/lib/sw_engine/tvgSwRenderer.cpp @@ -36,6 +36,7 @@ bool SwRenderer::clear() return rasterClear(surface); } + bool SwRenderer::target(uint32_t* buffer, uint32_t stride, uint32_t w, uint32_t h) { if (!buffer || stride == 0 || w == 0 || h == 0) return false; @@ -48,22 +49,25 @@ bool SwRenderer::target(uint32_t* buffer, uint32_t stride, uint32_t w, uint32_t return true; } + bool SwRenderer::render(const Shape& sdata, void *data) { - SwShape* shape = static_cast(data); - if (!shape) return false; + auto task = static_cast(data); + if (!task) return false; + + if (task->prepared.valid()) task->prepared.get(); uint8_t r, g, b, a; if (auto fill = sdata.fill()) { - rasterGradientShape(surface, *shape, fill->id()); + rasterGradientShape(surface, task->shape, fill->id()); } else { sdata.fill(&r, &g, &b, &a); - if (a > 0) rasterSolidShape(surface, *shape, r, g, b, a); + if (a > 0) rasterSolidShape(surface, task->shape, r, g, b, a); } sdata.strokeColor(&r, &g, &b, &a); - if (a > 0) rasterStroke(surface, *shape, r, g, b, a); + if (a > 0) rasterStroke(surface, task->shape, r, g, b, a); return true; } @@ -71,67 +75,74 @@ bool SwRenderer::render(const Shape& sdata, void *data) bool SwRenderer::dispose(const Shape& sdata, void *data) { - auto shape = static_cast(data); - if (!shape) return true; - shapeFree(shape); + auto task = static_cast(data); + if (!task) return true; + if (task->prepared.valid()) task->prepared.wait(); + shapeFree(task->shape); + free(task); return true; } void* SwRenderer::prepare(const Shape& sdata, void* data, const RenderTransform* transform, RenderUpdateFlag flags) { - //prepare shape data - auto shape = static_cast(data); - if (!shape) { - shape = static_cast(calloc(1, sizeof(SwShape))); - assert(shape); + //prepare task + auto task = static_cast(data); + if (!task) { + task = static_cast(calloc(1, sizeof(SwTask))); + if (!task) return nullptr; } - if (flags == RenderUpdateFlag::None) return shape; + if (flags == RenderUpdateFlag::None || task->prepared.valid()) return task; - //TODO: Threading + task->sdata = &sdata; + task->clip = {static_cast(surface.w), static_cast(surface.h)}; - SwSize clip = {static_cast(surface.w), static_cast(surface.h)}; + if (transform) task->transform = &transform->m; + else task->transform = nullptr; - //Shape - if (flags & (RenderUpdateFlag::Path | RenderUpdateFlag::Transform)) { - shapeReset(*shape); - uint8_t alpha = 0; - sdata.fill(nullptr, nullptr, nullptr, &alpha); - if (alpha > 0 || sdata.fill()) { - if (!shapeGenRle(*shape, sdata, clip, transform)) return shape; - } - } + task->flags = flags; - //Fill - if (flags & (RenderUpdateFlag::Gradient | RenderUpdateFlag::Transform)) { - auto fill = sdata.fill(); - if (fill) { - auto ctable = (flags & RenderUpdateFlag::Gradient) ? true : false; - if (ctable) shapeResetFill(*shape, fill); - if (!shapeGenFillColors(*shape, fill, transform, ctable)) return shape; - } else { - shapeDelFill(*shape); - } - } - - //Stroke - if (flags & (RenderUpdateFlag::Stroke | RenderUpdateFlag::Transform)) { - if (sdata.strokeWidth() > FLT_EPSILON) { - shapeResetStroke(*shape, sdata); + auto asyncTask = [](SwTask* task) { + //Shape + if (task->flags & (RenderUpdateFlag::Path | RenderUpdateFlag::Transform)) { + shapeReset(task->shape); uint8_t alpha = 0; - sdata.strokeColor(nullptr, nullptr, nullptr, &alpha); - if (alpha > 0) { - if (!shapeGenStrokeRle(*shape, sdata, clip)) return shape; + task->sdata->fill(nullptr, nullptr, nullptr, &alpha); + if (alpha > 0 || task->sdata->fill()) { + if (!shapeGenRle(task->shape, task->sdata, task->clip, task->transform)) return; } - } else { - shapeDelStroke(*shape); } - } + //Fill + if (task->flags & (RenderUpdateFlag::Gradient | RenderUpdateFlag::Transform)) { + auto fill = task->sdata->fill(); + if (fill) { + auto ctable = (task->flags & RenderUpdateFlag::Gradient) ? true : false; + if (ctable) shapeResetFill(task->shape); + if (!shapeGenFillColors(task->shape, fill, task->transform, ctable)) return; + } else { + shapeDelFill(task->shape); + } + } + //Stroke + if (task->flags & (RenderUpdateFlag::Stroke | RenderUpdateFlag::Transform)) { + if (task->sdata->strokeWidth() > FLT_EPSILON) { + shapeResetStroke(task->shape, task->sdata); + uint8_t alpha = 0; + task->sdata->strokeColor(nullptr, nullptr, nullptr, &alpha); + if (alpha > 0) { + if (!shapeGenStrokeRle(task->shape, task->sdata, task->clip)) return; + } + } else { + shapeDelStroke(task->shape); + } + } + shapeDelOutline(task->shape); + }; - shapeDelOutline(*shape); + task->prepared = async((launch::async | launch::deferred), asyncTask, task); - return shape; + return task; } diff --git a/src/lib/sw_engine/tvgSwShape.cpp b/src/lib/sw_engine/tvgSwShape.cpp index 22fed2c1..d9a4e816 100644 --- a/src/lib/sw_engine/tvgSwShape.cpp +++ b/src/lib/sw_engine/tvgSwShape.cpp @@ -231,17 +231,17 @@ static bool _checkValid(const SwOutline* outline, const SwBBox& bbox, const SwSi } -static void _transformOutline(SwOutline* outline, const RenderTransform* transform) +static void _transformOutline(SwOutline* outline, const Matrix* transform) { - assert(outline); - if (!transform) return; + assert(outline); + for(uint32_t i = 0; i < outline->ptsCnt; ++i) { auto dx = static_cast(outline->pts[i].x >> 6); auto dy = static_cast(outline->pts[i].y >> 6); - auto tx = dx * transform->m.e11 + dy * transform->m.e12 + transform->m.e31; - auto ty = dx * transform->m.e21 + dy * transform->m.e22 + transform->m.e32; + auto tx = dx * transform->e11 + dy * transform->e12 + transform->e31; + auto ty = dx * transform->e21 + dy * transform->e22 + transform->e32; auto pt = Point{tx, ty}; outline->pts[i] = TO_SWPOINT(&pt); } @@ -340,13 +340,15 @@ static void _dashCubicTo(SwDashStroke& dash, const Point* ctrl1, const Point* ct } -SwOutline* _genDashOutline(const Shape& shape) +SwOutline* _genDashOutline(const Shape* sdata) { + assert(sdata); + const PathCommand* cmds = nullptr; - auto cmdCnt = shape.pathCommands(&cmds); + auto cmdCnt = sdata->pathCommands(&cmds); const Point* pts = nullptr; - auto ptsCnt = shape.pathCoords(&pts); + auto ptsCnt = sdata->pathCoords(&pts); //No actual shape data if (cmdCnt == 0 || ptsCnt == 0) return nullptr; @@ -359,7 +361,7 @@ SwOutline* _genDashOutline(const Shape& shape) dash.curOpGap = false; const float* pattern; - dash.cnt = shape.strokeDash(&pattern); + dash.cnt = sdata->strokeDash(&pattern); assert(dash.cnt > 0 && pattern); //Is it safe to mutual exclusive? @@ -440,7 +442,7 @@ SwOutline* _genDashOutline(const Shape& shape) /* External Class Implementation */ /************************************************************************/ -bool shapeGenRle(SwShape& shape, const Shape& sdata, const SwSize& clip, const RenderTransform* transform) +bool shapeGenRle(SwShape& shape, const Shape* sdata, const SwSize& clip, const Matrix* transform) { if (!shapeGenOutline(shape, sdata)) return false; @@ -474,13 +476,15 @@ void shapeReset(SwShape& shape) } -bool shapeGenOutline(SwShape& shape, const Shape& sdata) +bool shapeGenOutline(SwShape& shape, const Shape* sdata) { + assert(sdata); + const PathCommand* cmds = nullptr; - auto cmdCnt = sdata.pathCommands(&cmds); + auto cmdCnt = sdata->pathCommands(&cmds); const Point* pts = nullptr; - auto ptsCnt = sdata.pathCoords(&pts); + auto ptsCnt = sdata->pathCoords(&pts); //No actual shape data if (cmdCnt == 0 || ptsCnt == 0) return false; @@ -559,19 +563,15 @@ bool shapeGenOutline(SwShape& shape, const Shape& sdata) } -void shapeFree(SwShape* shape) +void shapeFree(SwShape& shape) { - assert(shape); + shapeDelOutline(shape); + rleFree(shape.rle); - shapeDelOutline(*shape); - rleFree(shape->rle); - - if (shape->stroke) { - rleFree(shape->strokeRle); - strokeFree(shape->stroke); + if (shape.stroke) { + rleFree(shape.strokeRle); + strokeFree(shape.stroke); } - - free(shape); } @@ -585,7 +585,7 @@ void shapeDelStroke(SwShape& shape) } -void shapeResetStroke(SwShape& shape, const Shape& sdata) +void shapeResetStroke(SwShape& shape, const Shape* sdata) { if (!shape.stroke) shape.stroke = static_cast(calloc(1, sizeof(SwStroke))); auto stroke = shape.stroke; @@ -598,12 +598,14 @@ void shapeResetStroke(SwShape& shape, const Shape& sdata) } -bool shapeGenStrokeRle(SwShape& shape, const Shape& sdata, const SwSize& clip) +bool shapeGenStrokeRle(SwShape& shape, const Shape* sdata, const SwSize& clip) { + assert(sdata); + SwOutline* shapeOutline = nullptr; //Dash Style Stroke - if (sdata.strokeDash(nullptr) > 0) { + if (sdata->strokeDash(nullptr) > 0) { shapeOutline = _genDashOutline(sdata); if (!shapeOutline) return false; @@ -633,23 +635,18 @@ bool shapeGenStrokeRle(SwShape& shape, const Shape& sdata, const SwSize& clip) } -bool shapeGenFillColors(SwShape& shape, const Fill* fill, const RenderTransform* transform, bool ctable) +bool shapeGenFillColors(SwShape& shape, const Fill* fill, const Matrix* transform, bool ctable) { - assert(fill); - - fillGenColorTable(shape.fill, fill, transform, ctable); - return true; + return fillGenColorTable(shape.fill, fill, transform, ctable); } -void shapeResetFill(SwShape& shape, const Fill* fill) +void shapeResetFill(SwShape& shape) { - assert(fill); - if (!shape.fill) shape.fill = static_cast(calloc(1, sizeof(SwFill))); assert(shape.fill); - fillReset(shape.fill, fill); + fillReset(shape.fill); } diff --git a/src/lib/sw_engine/tvgSwStroke.cpp b/src/lib/sw_engine/tvgSwStroke.cpp index 94a25370..6ccfb7dc 100644 --- a/src/lib/sw_engine/tvgSwStroke.cpp +++ b/src/lib/sw_engine/tvgSwStroke.cpp @@ -816,13 +816,15 @@ void strokeFree(SwStroke* stroke) } -void strokeReset(SwStroke& stroke, const Shape& shape) +void strokeReset(SwStroke& stroke, const Shape* sdata) { - stroke.width = TO_SWCOORD(shape.strokeWidth() * 0.5); - stroke.cap = shape.strokeCap(); + assert(sdata); + + stroke.width = TO_SWCOORD(sdata->strokeWidth() * 0.5); + stroke.cap = sdata->strokeCap(); //Save line join: it can be temporarily changed when stroking curves... - stroke.joinSaved = stroke.join = shape.strokeJoin(); + stroke.joinSaved = stroke.join = sdata->strokeJoin(); stroke.borders[0].ptsCnt = 0; stroke.borders[0].start = -1; diff --git a/src/lib/tvgCanvasImpl.h b/src/lib/tvgCanvasImpl.h index 42cf4707..ae0ce3c0 100644 --- a/src/lib/tvgCanvasImpl.h +++ b/src/lib/tvgCanvasImpl.h @@ -42,7 +42,7 @@ struct Canvas::Impl Result push(unique_ptr paint) { auto p = paint.release(); - assert(p); + if (!p) return Result::MemoryCorruption; paints.push_back(p); return update(p); @@ -50,7 +50,7 @@ struct Canvas::Impl Result clear() { - assert(renderer); + if (!renderer) return Result::InsufficientCondition; for (auto paint : paints) { if (paint->id() == PAINT_ID_SCENE) { @@ -70,7 +70,7 @@ struct Canvas::Impl Result update() { - assert(renderer); + if (!renderer) return Result::InsufficientCondition; for(auto paint: paints) { if (paint->id() == PAINT_ID_SCENE) { @@ -87,7 +87,7 @@ struct Canvas::Impl Result update(Paint* paint) { - assert(renderer); + if (!renderer) return Result::InsufficientCondition; if (paint->id() == PAINT_ID_SCENE) { //We know renderer type, avoid dynamic_cast for performance. @@ -102,7 +102,7 @@ struct Canvas::Impl Result draw() { - assert(renderer); + if (!renderer) return Result::InsufficientCondition; //Clear render target before drawing if (!renderer->clear()) return Result::InsufficientCondition; diff --git a/src/meson.build b/src/meson.build index e49c9a0d..b5000bc5 100644 --- a/src/meson.build +++ b/src/meson.build @@ -5,10 +5,11 @@ subdir('loaders') subdir('examples') m_dep = meson.get_compiler('cpp').find_library('m') +thread_dep = meson.get_compiler('cpp').find_library('pthread') egl_dep = meson.get_compiler('cpp').find_library('EGL') gles_dep = meson.get_compiler('cpp').find_library('GLESv2') -tizenvg_lib_dep = [ src_dep, swengine_dep, glengine_dep, m_dep, egl_dep, gles_dep, svgloader_dep] +tizenvg_lib_dep = [ src_dep, swengine_dep, glengine_dep, m_dep, egl_dep, gles_dep, svgloader_dep, thread_dep] tizenvg_lib = library( diff --git a/test/testBlending.cpp b/test/testBlending.cpp index a5559d49..ebb3e67f 100644 --- a/test/testBlending.cpp +++ b/test/testBlending.cpp @@ -66,8 +66,7 @@ void tvgtest() tvg::Initializer::term(tvg::CanvasEngine::Sw); } -void -win_del(void *data, Evas_Object *o, void *ev) +void win_del(void *data, Evas_Object *o, void *ev) { elm_exit(); } diff --git a/test/testBoundary.cpp b/test/testBoundary.cpp index 701bb840..a71374a4 100644 --- a/test/testBoundary.cpp +++ b/test/testBoundary.cpp @@ -56,8 +56,7 @@ void tvgtest() tvg::Initializer::term(tvg::CanvasEngine::Sw); } -void -win_del(void *data, Evas_Object *o, void *ev) +void win_del(void *data, Evas_Object *o, void *ev) { elm_exit(); } diff --git a/test/testCustomTransform.cpp b/test/testCustomTransform.cpp index ae3d7c83..cc0c8bbe 100644 --- a/test/testCustomTransform.cpp +++ b/test/testCustomTransform.cpp @@ -96,8 +96,7 @@ void transit_cb(Elm_Transit_Effect *effect, Elm_Transit* transit, double progres evas_object_image_data_update_add(img, 0, 0, WIDTH, HEIGHT); } -void -win_del(void *data, Evas_Object *o, void *ev) +void win_del(void *data, Evas_Object *o, void *ev) { elm_exit(); } diff --git a/test/testGlShape.cpp b/test/testGlShape.cpp index 3ff4a33c..8ad43ae0 100644 --- a/test/testGlShape.cpp +++ b/test/testGlShape.cpp @@ -9,8 +9,7 @@ using namespace std; static Evas_GL_API *glapi; static unique_ptr canvas; -static void -tvgtest() +void tvgtest() { //Create a Canvas canvas = tvg::GlCanvas::gen(); @@ -33,8 +32,7 @@ tvgtest() canvas->push(move(shape1)); } -static void -init_gl(Evas_Object *obj) +void init_gl(Evas_Object *obj) { //Initialize TizenVG Engine tvg::Initializer::init(tvg::CanvasEngine::Gl); @@ -42,15 +40,13 @@ init_gl(Evas_Object *obj) tvgtest(); } -static void -del_gl(Evas_Object *obj) +void del_gl(Evas_Object *obj) { //Terminate TizenVG Engine tvg::Initializer::term(tvg::CanvasEngine::Gl); } -static void -draw_gl(Evas_Object *obj) +void draw_gl(Evas_Object *obj) { Evas_GL_API *gl = elm_glview_gl_api_get(obj); int w, h; @@ -66,8 +62,7 @@ draw_gl(Evas_Object *obj) canvas->sync(); } -void -win_del(void *data, Evas_Object *o, void *ev) +void win_del(void *data, Evas_Object *o, void *ev) { elm_exit(); } diff --git a/test/testGradientTransform.cpp b/test/testGradientTransform.cpp index 90fab168..428acc51 100644 --- a/test/testGradientTransform.cpp +++ b/test/testGradientTransform.cpp @@ -126,8 +126,7 @@ void transit_cb(Elm_Transit_Effect *effect, Elm_Transit* transit, double progres evas_object_image_data_update_add(img, 0, 0, WIDTH, HEIGHT); } -void -win_del(void *data, Evas_Object *o, void *ev) +void win_del(void *data, Evas_Object *o, void *ev) { elm_exit(); } diff --git a/test/testLinearGradient.cpp b/test/testLinearGradient.cpp index decf263d..8016a451 100644 --- a/test/testLinearGradient.cpp +++ b/test/testLinearGradient.cpp @@ -84,8 +84,7 @@ void tvgtest() tvg::Initializer::term(tvg::CanvasEngine::Sw); } -void -win_del(void *data, Evas_Object *o, void *ev) +void win_del(void *data, Evas_Object *o, void *ev) { elm_exit(); } diff --git a/test/testMultiShapes.cpp b/test/testMultiShapes.cpp index e6db3bb7..9fff6f05 100644 --- a/test/testMultiShapes.cpp +++ b/test/testMultiShapes.cpp @@ -44,8 +44,7 @@ void tvgtest() tvg::Initializer::term(tvg::CanvasEngine::Sw); } -void -win_del(void *data, Evas_Object *o, void *ev) +void win_del(void *data, Evas_Object *o, void *ev) { elm_exit(); } diff --git a/test/testPath.cpp b/test/testPath.cpp index 3d520037..efb784fd 100644 --- a/test/testPath.cpp +++ b/test/testPath.cpp @@ -59,8 +59,7 @@ void tvgtest() tvg::Initializer::term(tvg::CanvasEngine::Sw); } -void -win_del(void *data, Evas_Object *o, void *ev) +void win_del(void *data, Evas_Object *o, void *ev) { elm_exit(); } diff --git a/test/testPathCopy.cpp b/test/testPathCopy.cpp index 8ce33c3c..4ba5941d 100644 --- a/test/testPathCopy.cpp +++ b/test/testPathCopy.cpp @@ -99,8 +99,7 @@ void tvgtest() tvg::Initializer::term(tvg::CanvasEngine::Sw); } -void -win_del(void *data, Evas_Object *o, void *ev) +void win_del(void *data, Evas_Object *o, void *ev) { elm_exit(); } diff --git a/test/testRadialGradient.cpp b/test/testRadialGradient.cpp index b50204b8..e10be472 100644 --- a/test/testRadialGradient.cpp +++ b/test/testRadialGradient.cpp @@ -84,8 +84,7 @@ void tvgtest() tvg::Initializer::term(tvg::CanvasEngine::Sw); } -void -win_del(void *data, Evas_Object *o, void *ev) +void win_del(void *data, Evas_Object *o, void *ev) { elm_exit(); } diff --git a/test/testScene.cpp b/test/testScene.cpp index e134237f..db6fd53d 100644 --- a/test/testScene.cpp +++ b/test/testScene.cpp @@ -90,8 +90,7 @@ void tvgtest() tvg::Initializer::term(tvg::CanvasEngine::Sw); } -void -win_del(void *data, Evas_Object *o, void *ev) +void win_del(void *data, Evas_Object *o, void *ev) { elm_exit(); } diff --git a/test/testSceneTransform.cpp b/test/testSceneTransform.cpp index 11dade09..1e411fe2 100644 --- a/test/testSceneTransform.cpp +++ b/test/testSceneTransform.cpp @@ -120,8 +120,7 @@ void transit_cb(Elm_Transit_Effect *effect, Elm_Transit* transit, double progres evas_object_image_data_update_add(img, 0, 0, WIDTH, HEIGHT); } -void -win_del(void *data, Evas_Object *o, void *ev) +void win_del(void *data, Evas_Object *o, void *ev) { elm_exit(); } diff --git a/test/testShape.cpp b/test/testShape.cpp index 16fc1a0e..4cc1f7fe 100644 --- a/test/testShape.cpp +++ b/test/testShape.cpp @@ -38,8 +38,7 @@ void tvgtest() tvg::Initializer::term(tvg::CanvasEngine::Sw); } -void -win_del(void *data, Evas_Object *o, void *ev) +void win_del(void *data, Evas_Object *o, void *ev) { elm_exit(); } diff --git a/test/testStress.cpp b/test/testStress.cpp index 2c1020e3..870742ed 100644 --- a/test/testStress.cpp +++ b/test/testStress.cpp @@ -3,12 +3,14 @@ using namespace std; -#define WIDTH 800 -#define HEIGHT 800 +#define WIDTH 1920 +#define HEIGHT 1080 #define COUNT 50 static uint32_t buffer[WIDTH * HEIGHT]; unique_ptr canvas = nullptr; +static double t1, t2, t3, t4; +static unsigned cnt = 0; void tvgtest() { @@ -19,20 +21,18 @@ void tvgtest() Eina_Bool anim_cb(void *data) { - static unsigned cnt = 0; - //Explicitly clear all retained paint nodes. - double t1 = ecore_time_get(); + t1 = ecore_time_get(); canvas->clear(); - double t2 = ecore_time_get(); + t2 = ecore_time_get(); for (int i = 0; i < COUNT; i++) { auto shape = tvg::Shape::gen(); - float x = rand() % 400; - float y = rand() % 400; - float w = 1 + rand() % 600; - float h = 1 + rand() % 600; + float x = rand() % (WIDTH/2); + float y = rand() % (HEIGHT/2); + float w = 1 + rand() % 1200; + float h = 1 + rand() % 800; shape->appendRect(x, y, w, h, rand() % 400); @@ -61,25 +61,28 @@ Eina_Bool anim_cb(void *data) canvas->push(move(shape)); } - double t3 = ecore_time_get(); - - //Draw Next frames - canvas->draw(); - canvas->sync(); - - double t4 = ecore_time_get(); - - printf("[%5d]: total[%fms] = clear[%fms] + update[%fms] + render[%fms]\n", ++cnt, t4 - t1, t2 - t1, t3 - t2, t4 - t3); - //Update Efl Canvas Eo* img = (Eo*) data; + evas_object_image_pixels_dirty_set(img, EINA_TRUE); evas_object_image_data_update_add(img, 0, 0, WIDTH, HEIGHT); return ECORE_CALLBACK_RENEW; } -void -win_del(void *data, Evas_Object *o, void *ev) +void render_cb(void* data, Eo* obj) +{ + t3 = ecore_time_get(); + + //Draw Next frames + canvas->draw(); + canvas->sync(); + + t4 = ecore_time_get(); + + printf("[%5d]: total[%fms] = clear[%fms], update[%fms], render[%fms]\n", ++cnt, t4 - t1, t2 - t1, t3 - t2, t4 - t3); +} + +void win_del(void *data, Evas_Object *o, void *ev) { elm_exit(); } @@ -100,6 +103,7 @@ int main(int argc, char **argv) Eo* img = evas_object_image_filled_add(evas_object_evas_get(win)); evas_object_image_size_set(img, WIDTH, HEIGHT); evas_object_image_data_set(img, buffer); + evas_object_image_pixels_get_callback_set(img, render_cb, nullptr); evas_object_size_hint_weight_set(img, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); evas_object_show(img); diff --git a/test/testStroke.cpp b/test/testStroke.cpp index a7ae5d09..68bffa2c 100644 --- a/test/testStroke.cpp +++ b/test/testStroke.cpp @@ -83,13 +83,11 @@ void tvgtest() tvg::Initializer::term(tvg::CanvasEngine::Sw); } -void -win_del(void *data, Evas_Object *o, void *ev) +void win_del(void *data, Evas_Object *o, void *ev) { elm_exit(); } - int main(int argc, char **argv) { tvgtest(); diff --git a/test/testStrokeLine.cpp b/test/testStrokeLine.cpp index 61e035e5..3b6cc9df 100644 --- a/test/testStrokeLine.cpp +++ b/test/testStrokeLine.cpp @@ -119,8 +119,7 @@ void tvgtest() tvg::Initializer::term(tvg::CanvasEngine::Sw); } -void -win_del(void *data, Evas_Object *o, void *ev) +void win_del(void *data, Evas_Object *o, void *ev) { elm_exit(); } diff --git a/test/testSvg.cpp b/test/testSvg.cpp index e9189023..cad2f1b7 100644 --- a/test/testSvg.cpp +++ b/test/testSvg.cpp @@ -29,8 +29,7 @@ void tvgtest() tvg::Initializer::term(tvg::CanvasEngine::Sw); } -void -win_del(void *data, Evas_Object *o, void *ev) +void win_del(void *data, Evas_Object *o, void *ev) { elm_exit(); } diff --git a/test/testTransform.cpp b/test/testTransform.cpp index a99708d0..52227439 100644 --- a/test/testTransform.cpp +++ b/test/testTransform.cpp @@ -89,8 +89,7 @@ void transit_cb(Elm_Transit_Effect *effect, Elm_Transit* transit, double progres evas_object_image_data_update_add(img, 0, 0, WIDTH, HEIGHT); } -void -win_del(void *data, Evas_Object *o, void *ev) +void win_del(void *data, Evas_Object *o, void *ev) { elm_exit(); } diff --git a/test/testUpdate.cpp b/test/testUpdate.cpp index 0ee9412d..7111b21b 100644 --- a/test/testUpdate.cpp +++ b/test/testUpdate.cpp @@ -50,8 +50,7 @@ void transit_cb(Elm_Transit_Effect *effect, Elm_Transit* transit, double progres evas_object_image_data_update_add(img, 0, 0, WIDTH, HEIGHT); } -void -win_del(void *data, Evas_Object *o, void *ev) +void win_del(void *data, Evas_Object *o, void *ev) { elm_exit(); }