From: Hermet Park Date: Thu, 20 Aug 2020 08:04:32 +0000 (+0900) Subject: common taskscheduler: revise functionalities. X-Git-Tag: accepted/tizen/unified/20200824.134426~1 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=657e6daddb5dfe0aeeb694538f23a26857e0d6cf;p=platform%2Fcore%2Fgraphics%2Ftizenvg.git common taskscheduler: revise functionalities. initialization interfaces has been changed for threads count. if you want to set concrete threads count by system, please specify thread count with it. std threads: tvg::Initializer::init(tvg::CanvasEngine::Sw, std::thread::hardware_concurrency()); if your system provides designed threads info, you can use it. efl: tvg_engine_init(TVG_ENGINE_SW, eina_cpu_count()); I recommend to avoid max threads usage for better performance. Change-Id: I22cfa315768f73fa941be136956cdbb2cf837c20 --- diff --git a/inc/thorvg.h b/inc/thorvg.h index 18013fa..0de9bc0 100644 --- a/inc/thorvg.h +++ b/inc/thorvg.h @@ -366,10 +366,8 @@ public: * * @see ... */ - static Result init(CanvasEngine engine) noexcept; + static Result init(CanvasEngine engine, uint32_t threads) noexcept; static Result term(CanvasEngine engine) noexcept; - static Result threads(uint32_t cnt) noexcept; - static uint32_t threads() noexcept; _TVG_DISABLE_CTOR(Initializer); }; diff --git a/inc/thorvg_capi.h b/inc/thorvg_capi.h index 811c82e..afc294a 100644 --- a/inc/thorvg_capi.h +++ b/inc/thorvg_capi.h @@ -88,7 +88,7 @@ typedef struct /************************************************************************/ /* Engine API */ /************************************************************************/ -TVG_EXPORT Tvg_Result tvg_engine_init(unsigned engine_method); +TVG_EXPORT Tvg_Result tvg_engine_init(unsigned engine_method, unsigned threads); TVG_EXPORT Tvg_Result tvg_engine_term(unsigned engine_method); diff --git a/src/bindings/capi/tvgCapi.cpp b/src/bindings/capi/tvgCapi.cpp index ac8cdcb..0155196 100644 --- a/src/bindings/capi/tvgCapi.cpp +++ b/src/bindings/capi/tvgCapi.cpp @@ -50,13 +50,13 @@ struct _Tvg_Gradient /* Engine API */ /************************************************************************/ -TVG_EXPORT Tvg_Result tvg_engine_init(unsigned engine_method) { +TVG_EXPORT Tvg_Result tvg_engine_init(unsigned engine_method, unsigned threads) { Result ret = Result::Success; - if (engine_method & TVG_ENGINE_SW) ret = tvg::Initializer::init(tvg::CanvasEngine::Sw); + if (engine_method & TVG_ENGINE_SW) ret = tvg::Initializer::init(tvg::CanvasEngine::Sw, threads); if (ret != Result::Success) return (Tvg_Result) ret; - if (engine_method & TVG_ENGINE_GL) ret = tvg::Initializer::init(tvg::CanvasEngine::Gl); + if (engine_method & TVG_ENGINE_GL) ret = tvg::Initializer::init(tvg::CanvasEngine::Gl, threads); return (Tvg_Result) ret; } @@ -64,10 +64,10 @@ TVG_EXPORT Tvg_Result tvg_engine_init(unsigned engine_method) { TVG_EXPORT Tvg_Result tvg_engine_term(unsigned engine_method) { Result ret = Result::Success; - if (engine_method & TVG_ENGINE_SW) ret = tvg::Initializer::init(tvg::CanvasEngine::Sw); + if (engine_method & TVG_ENGINE_SW) ret = tvg::Initializer::term(tvg::CanvasEngine::Sw); if (ret != Result::Success) return (Tvg_Result) ret; - if (engine_method & TVG_ENGINE_GL) ret = tvg::Initializer::init(tvg::CanvasEngine::Gl); + if (engine_method & TVG_ENGINE_GL) ret = tvg::Initializer::term(tvg::CanvasEngine::Gl); return (Tvg_Result) ret; } diff --git a/src/lib/meson.build b/src/lib/meson.build index 503c35e..bc0d959 100644 --- a/src/lib/meson.build +++ b/src/lib/meson.build @@ -21,6 +21,7 @@ source_file = [ 'tvgSceneImpl.h', 'tvgShapePath.h', 'tvgShapeImpl.h', + 'tvgTaskScheduler.h', 'tvgBezier.cpp', 'tvgCanvas.cpp', 'tvgFill.cpp', @@ -35,7 +36,7 @@ source_file = [ 'tvgScene.cpp', 'tvgShape.cpp', 'tvgSwCanvas.cpp', - 'tvgTask.cpp', + 'tvgTaskScheduler.cpp', ] common_dep = declare_dependency( diff --git a/src/lib/tvgCommon.h b/src/lib/tvgCommon.h index 66e08bf..c07a4ca 100644 --- a/src/lib/tvgCommon.h +++ b/src/lib/tvgCommon.h @@ -29,6 +29,9 @@ #include #include #include +#include +#include + #include "thorvg.h" using namespace std; @@ -46,5 +49,6 @@ using namespace tvg; #include "tvgLoaderMgr.h" #include "tvgRender.h" #include "tvgPaint.h" +#include "tvgTaskScheduler.h" #endif //_TVG_COMMON_H_ diff --git a/src/lib/tvgInitializer.cpp b/src/lib/tvgInitializer.cpp index 2185c0f..17b91a0 100644 --- a/src/lib/tvgInitializer.cpp +++ b/src/lib/tvgInitializer.cpp @@ -35,13 +35,12 @@ /* Internal Class Implementation */ /************************************************************************/ -static uint32_t threadCnt = 0; /************************************************************************/ /* External Class Implementation */ /************************************************************************/ -Result Initializer::init(CanvasEngine engine) noexcept +Result Initializer::init(CanvasEngine engine, uint32_t threads) noexcept { auto nonSupport = true; @@ -63,6 +62,8 @@ Result Initializer::init(CanvasEngine engine) noexcept if (!LoaderMgr::init()) return Result::Unknown; + TaskScheduler::init(threads); + return Result::Success; } @@ -87,21 +88,9 @@ Result Initializer::term(CanvasEngine engine) noexcept if (nonSupport) return Result::NonSupport; - if (!LoaderMgr::term()) return Result::Unknown; - - return Result::Success; -} - + TaskScheduler::term(); -Result Initializer::threads(uint32_t cnt) noexcept -{ - threadCnt = cnt; + if (!LoaderMgr::term()) return Result::Unknown; return Result::Success; -} - - -uint32_t Initializer::threads() noexcept -{ - return threadCnt; } \ No newline at end of file diff --git a/src/lib/tvgShapePath.h b/src/lib/tvgShapePath.h index 04934dc..f3e0ae5 100644 --- a/src/lib/tvgShapePath.h +++ b/src/lib/tvgShapePath.h @@ -19,8 +19,8 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ -#ifndef _TVG_SHAPE_PATH_CPP_ -#define _TVG_SHAPE_PATH_CPP_ +#ifndef _TVG_SHAPE_PATH_H_ +#define _TVG_SHAPE_PATH_H_ #include "tvgCommon.h" @@ -139,4 +139,4 @@ struct ShapePath } }; -#endif //_TVG_SHAPE_PATH_CPP_ +#endif //_TVG_SHAPE_PATH_H_ diff --git a/src/lib/tvgTask.cpp b/src/lib/tvgTask.cpp deleted file mode 100644 index 81ce22e..0000000 --- a/src/lib/tvgTask.cpp +++ /dev/null @@ -1,156 +0,0 @@ -/* - * Copyright (c) 2020 Samsung Electronics Co., Ltd All Rights Reserved - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ - -#include - -#include - -template -class TaskQueue { - using lock_t = std::unique_lock; - std::deque _q; - bool _done{false}; - std::mutex _mutex; - std::condition_variable _ready; - -public: - bool try_pop(Task &task) - { - lock_t lock{_mutex, std::try_to_lock}; - if (!lock || _q.empty()) return false; - task = std::move(_q.front()); - _q.pop_front(); - return true; - } - - bool try_push(Task &&task) - { - { - lock_t lock{_mutex, std::try_to_lock}; - if (!lock) return false; - _q.push_back(std::move(task)); - } - _ready.notify_one(); - return true; - } - - void done() - { - { - lock_t lock{_mutex}; - _done = true; - } - _ready.notify_all(); - } - - bool pop(Task &task) - { - lock_t lock{_mutex}; - while (_q.empty() && !_done) _ready.wait(lock); - if (_q.empty()) return false; - task = std::move(_q.front()); - _q.pop_front(); - return true; - } - - void push(Task &&task) - { - { - lock_t lock{_mutex}; - _q.push_back(std::move(task)); - } - _ready.notify_one(); - } - -}; - -#include -#include - -namespace tvg -{ - -class Executor -{ - const unsigned _count{std::thread::hardware_concurrency()}; - std::vector _threads; - std::vector> _q{_count}; - std::atomic _index{0}; - void run(unsigned i) - { - // Task Loop - shared_task task; - while (true) { - bool success = false; - - for (unsigned n = 0; n != _count * 2; ++n) { - if (_q[(i + n) % _count].try_pop(task)) { - success = true; - break; - } - } - - if (!success && !_q[i].pop(task)) break; - - (*task)(); - } - } - - Executor() - { - for (unsigned n = 0; n != _count; ++n) { - _threads.emplace_back([&, n] { run(n); }); - } - } - ~Executor() - { - for (auto &e : _q) e.done(); - - for (auto &e : _threads) e.join(); - } - -public: - - static Executor& instance() { - static Executor singleton; - return singleton; - } - - void post(shared_task task) - { - task->prepare(); - - auto i = _index++; - - for (unsigned n = 0; n != _count; ++n) { - if (_q[(i + n) % _count].try_push(std::move(task))) return; - } - - if (_count > 0) { - _q[i % _count].push(std::move(task)); - } - } -}; - -void async(shared_task task) -{ - Executor::instance().post(std::move(task)); -} - -} - - diff --git a/src/lib/tvgTask.h b/src/lib/tvgTask.h deleted file mode 100644 index 9fb250e..0000000 --- a/src/lib/tvgTask.h +++ /dev/null @@ -1,72 +0,0 @@ -/* - * Copyright (c) 2020 Samsung Electronics Co., Ltd All Rights Reserved - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ -#ifndef _TVG_TASK_H_ -#define _TVG_TASK_H_ - -#include -#include - -namespace tvg -{ - -/* - Task Interface. - Able to run a task in the thread pool. derive from the - task interface and implement run method. - - To get the result call task->get() which will return immidiately if the - task is already finishd otherwise will wait till task completion. - */ - -class Task -{ -public: - virtual ~Task() = default; - void get() { if (_receiver.valid()) _receiver.get(); } - -protected: - virtual void run() = 0; -private: - void operator()() - { - run(); - _sender.set_value(); - } - void prepare() - { - _sender = std::promise(); - _receiver = _sender.get_future(); - } - friend class Executor; - - std::promise _sender; - std::future _receiver; -}; - - -using shared_task = std::shared_ptr; - -/* - async() function takes a shared task and runs it in - a thread pool asyncronously. call get() on the shared_task - to get the ressult out of the shared_task. - */ -void async(shared_task task); - -} - -#endif //_TVG_TASK_H_ \ No newline at end of file diff --git a/src/lib/tvgTaskScheduler.cpp b/src/lib/tvgTaskScheduler.cpp new file mode 100644 index 0000000..31b1e84 --- /dev/null +++ b/src/lib/tvgTaskScheduler.cpp @@ -0,0 +1,189 @@ +/* + * Copyright (c) 2020 Samsung Electronics Co., Ltd. All rights reserved. + + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#include +#include +#include "tvgCommon.h" + +/************************************************************************/ +/* Internal Class Implementation */ +/************************************************************************/ + +namespace tvg { + +struct TaskQueue { + deque> taskDeque; + mutex mtx; + condition_variable ready; + bool done = false; + + bool tryPop(shared_ptr &task) + { + unique_lock lock{mtx, try_to_lock}; + if (!lock || taskDeque.empty()) return false; + task = move(taskDeque.front()); + taskDeque.pop_front(); + + return true; + } + + bool tryPush(shared_ptr &&task) + { + { + unique_lock lock{mtx, try_to_lock}; + if (!lock) return false; + taskDeque.push_back(move(task)); + } + + ready.notify_one(); + + return true; + } + + void complete() + { + { + unique_lock lock{mtx}; + done = true; + } + ready.notify_all(); + } + + bool pop(shared_ptr &task) + { + unique_lock lock{mtx}; + + while (taskDeque.empty() && !done) { + ready.wait(lock); + } + + if (taskDeque.empty()) return false; + + task = move(taskDeque.front()); + taskDeque.pop_front(); + + return true; + } + + void push(shared_ptr &&task) + { + { + unique_lock lock{mtx}; + taskDeque.push_back(move(task)); + } + + ready.notify_one(); + } + +}; + + +class TaskSchedulerImpl +{ +public: + unsigned threadCnt; + vector threads; + vector taskQueues{threadCnt}; + atomic idx{0}; + + TaskSchedulerImpl() + { + for (unsigned i = 0; i < threadCnt; ++i) { + threads.emplace_back([&, i] { run(i); }); + } + } + + ~TaskSchedulerImpl() + { + for (auto& queue : taskQueues) queue.complete(); + for (auto& thread : threads) thread.join(); + } + + void run(unsigned i) + { + shared_ptr task; + + //Thread Loop + while (true) { + auto success = false; + + for (unsigned i = 0; i < threadCnt * 2; ++i) { + if (taskQueues[(i + i) % threadCnt].tryPop(task)) { + success = true; + break; + } + } + + if (!success && !taskQueues[i].pop(task)) break; + + (*task)(); + } + } + + void request(shared_ptr task) + { + //Async + if (threadCnt > 0) { + task->prepare(); + auto i = idx++; + for (unsigned n = 0; n < threadCnt; ++n) { + if (taskQueues[(i + n) % threadCnt].tryPush(move(task))) return; + } + + taskQueues[i % threadCnt].push(move(task)); + + //Sync + } else { + task->run(); + } + } +}; + +} + +static TaskSchedulerImpl* inst = nullptr; + +/************************************************************************/ +/* External Class Implementation */ +/************************************************************************/ + +void TaskScheduler::init(unsigned threads) +{ + if (inst) return; + inst = new TaskSchedulerImpl; + inst->threadCnt = threads; +} + + +void TaskScheduler::term() +{ + if (!inst) return; + delete(inst); + inst = nullptr; +} + + +void TaskScheduler::request(shared_ptr task) +{ + if (inst) { + inst->request(move(task)); + } +} \ No newline at end of file diff --git a/src/lib/tvgTaskScheduler.h b/src/lib/tvgTaskScheduler.h new file mode 100644 index 0000000..4380a9c --- /dev/null +++ b/src/lib/tvgTaskScheduler.h @@ -0,0 +1,72 @@ +/* + * Copyright (c) 2020 Samsung Electronics Co., Ltd. All rights reserved. + + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#ifndef _TVG_TASK_SCHEDULER_H_ +#define _TVG_TASK_SCHEDULER_H_ + +#include "tvgCommon.h" + +namespace tvg +{ + +struct Task +{ +private: + std::promise sender; + std::future receiver; + +public: + virtual ~Task() = default; + + void get() + { + if (receiver.valid()) receiver.get(); + } + +protected: + virtual void run() = 0; + +private: + void operator()() + { + run(); + sender.set_value(); + } + + void prepare() + { + sender = std::promise(); + receiver = sender.get_future(); + } + + friend class TaskSchedulerImpl; +}; + +struct TaskScheduler +{ + static void init(unsigned threads); + static void term(); + static void request(shared_ptr task); +}; + +} + +#endif //_TVG_TASK_SCHEDULER_H_ \ No newline at end of file diff --git a/test/testArc.cpp b/test/testArc.cpp index 1f15812..9c307d4 100644 --- a/test/testArc.cpp +++ b/test/testArc.cpp @@ -148,8 +148,11 @@ int main(int argc, char **argv) cout << "tvg engine: opengl" << endl; } + //Threads Count + auto threads = std::thread::hardware_concurrency(); + //Initialize ThorVG Engine - if (tvg::Initializer::init(tvgEngine) == tvg::Result::Success) { + if (tvg::Initializer::init(tvgEngine, threads) == tvg::Result::Success) { elm_init(argc, argv); diff --git a/test/testAsync.cpp b/test/testAsync.cpp index 608cefb..25e57ba 100644 --- a/test/testAsync.cpp +++ b/test/testAsync.cpp @@ -151,8 +151,11 @@ int main(int argc, char **argv) cout << "tvg engine: opengl" << endl; } + //Threads Count + auto threads = std::thread::hardware_concurrency(); + //Initialize ThorVG Engine - if (tvg::Initializer::init(tvgEngine) == tvg::Result::Success) { + if (tvg::Initializer::init(tvgEngine, threads) == tvg::Result::Success) { elm_init(argc, argv); diff --git a/test/testBlending.cpp b/test/testBlending.cpp index 743b1e0..68623dc 100644 --- a/test/testBlending.cpp +++ b/test/testBlending.cpp @@ -131,8 +131,11 @@ int main(int argc, char **argv) cout << "tvg engine: opengl" << endl; } + //Threads Count + auto threads = std::thread::hardware_concurrency(); + //Initialize ThorVG Engine - if (tvg::Initializer::init(tvgEngine) == tvg::Result::Success) { + if (tvg::Initializer::init(tvgEngine, threads) == tvg::Result::Success) { elm_init(argc, argv); diff --git a/test/testBoundary.cpp b/test/testBoundary.cpp index 3830687..e2ed1c0 100644 --- a/test/testBoundary.cpp +++ b/test/testBoundary.cpp @@ -120,8 +120,11 @@ int main(int argc, char **argv) cout << "tvg engine: opengl" << endl; } + //Threads Count + auto threads = std::thread::hardware_concurrency(); + //Initialize ThorVG Engine - if (tvg::Initializer::init(tvgEngine) == tvg::Result::Success) { + if (tvg::Initializer::init(tvgEngine, threads) == tvg::Result::Success) { elm_init(argc, argv); diff --git a/test/testCapi.c b/test/testCapi.c index c6df396..1b0018d 100644 --- a/test/testCapi.c +++ b/test/testCapi.c @@ -13,7 +13,7 @@ static uint32_t buffer[WIDTH * HEIGHT]; void testCapi() { - tvg_engine_init(TVG_ENGINE_SW | TVG_ENGINE_GL); + tvg_engine_init(TVG_ENGINE_SW | TVG_ENGINE_GL, 0); Tvg_Canvas* canvas = tvg_swcanvas_create(); tvg_swcanvas_set_target(canvas, buffer, WIDTH, WIDTH, HEIGHT, TVG_COLORSPACE_ARGB8888); diff --git a/test/testCommon.h b/test/testCommon.h index 13ac86a..a5f222e 100644 --- a/test/testCommon.h +++ b/test/testCommon.h @@ -1,4 +1,5 @@ #include +#include #include #include diff --git a/test/testCustomTransform.cpp b/test/testCustomTransform.cpp index 9daa6fc..50033f9 100644 --- a/test/testCustomTransform.cpp +++ b/test/testCustomTransform.cpp @@ -176,8 +176,11 @@ int main(int argc, char **argv) cout << "tvg engine: opengl" << endl; } + //Threads Count + auto threads = std::thread::hardware_concurrency(); + //Initialize ThorVG Engine - if (tvg::Initializer::init(tvgEngine) == tvg::Result::Success) { + if (tvg::Initializer::init(tvgEngine, threads) == tvg::Result::Success) { elm_init(argc, argv); diff --git a/test/testDirectUpdate.cpp b/test/testDirectUpdate.cpp index 8dcc474..69105c3 100644 --- a/test/testDirectUpdate.cpp +++ b/test/testDirectUpdate.cpp @@ -139,8 +139,11 @@ int main(int argc, char **argv) cout << "tvg engine: opengl" << endl; } + //Threads Count + auto threads = std::thread::hardware_concurrency(); + //Initialize ThorVG Engine - if (tvg::Initializer::init(tvgEngine) == tvg::Result::Success) { + if (tvg::Initializer::init(tvgEngine, threads) == tvg::Result::Success) { elm_init(argc, argv); diff --git a/test/testGradientTransform.cpp b/test/testGradientTransform.cpp index 77d5f6a..45431e3 100644 --- a/test/testGradientTransform.cpp +++ b/test/testGradientTransform.cpp @@ -204,31 +204,34 @@ int main(int argc, char **argv) cout << "tvg engine: opengl" << endl; } + //Threads Count + auto threads = std::thread::hardware_concurrency(); + //Initialize ThorVG Engine - if (tvg::Initializer::init(tvgEngine) == tvg::Result::Success) { + if (tvg::Initializer::init(tvgEngine, threads) == tvg::Result::Success) { - elm_init(argc, argv); + elm_init(argc, argv); - Elm_Transit *transit = elm_transit_add(); + Elm_Transit *transit = elm_transit_add(); - if (tvgEngine == tvg::CanvasEngine::Sw) { - auto view = createSwView(); - elm_transit_effect_add(transit, transitSwCb, view, nullptr); - } else { - auto view = createGlView(); - elm_transit_effect_add(transit, transitGlCb, view, nullptr); - } + if (tvgEngine == tvg::CanvasEngine::Sw) { + auto view = createSwView(); + elm_transit_effect_add(transit, transitSwCb, view, nullptr); + } else { + auto view = createGlView(); + elm_transit_effect_add(transit, transitGlCb, view, nullptr); + } - elm_transit_duration_set(transit, 2); - elm_transit_repeat_times_set(transit, -1); - elm_transit_auto_reverse_set(transit, EINA_TRUE); - elm_transit_go(transit); + elm_transit_duration_set(transit, 2); + elm_transit_repeat_times_set(transit, -1); + elm_transit_auto_reverse_set(transit, EINA_TRUE); + elm_transit_go(transit); - elm_run(); - elm_shutdown(); + elm_run(); + elm_shutdown(); - //Terminate ThorVG Engine - tvg::Initializer::term(tvgEngine); + //Terminate ThorVG Engine + tvg::Initializer::term(tvgEngine); } else { cout << "engine is not supported" << endl; diff --git a/test/testLinearGradient.cpp b/test/testLinearGradient.cpp index db11682..d1ed5fa 100644 --- a/test/testLinearGradient.cpp +++ b/test/testLinearGradient.cpp @@ -149,8 +149,11 @@ int main(int argc, char **argv) cout << "tvg engine: opengl" << endl; } + //Threads Count + auto threads = std::thread::hardware_concurrency(); + //Initialize ThorVG Engine - if (tvg::Initializer::init(tvgEngine) == tvg::Result::Success) { + if (tvg::Initializer::init(tvgEngine, threads) == tvg::Result::Success) { elm_init(argc, argv); diff --git a/test/testMultiShapes.cpp b/test/testMultiShapes.cpp index 12009bc..3db41b9 100644 --- a/test/testMultiShapes.cpp +++ b/test/testMultiShapes.cpp @@ -109,8 +109,11 @@ int main(int argc, char **argv) cout << "tvg engine: opengl" << endl; } + //Threads Count + auto threads = std::thread::hardware_concurrency(); + //Initialize ThorVG Engine - if (tvg::Initializer::init(tvgEngine) == tvg::Result::Success) { + if (tvg::Initializer::init(tvgEngine, threads) == tvg::Result::Success) { elm_init(argc, argv); diff --git a/test/testPath.cpp b/test/testPath.cpp index de6ef60..a265d03 100644 --- a/test/testPath.cpp +++ b/test/testPath.cpp @@ -126,8 +126,11 @@ int main(int argc, char **argv) cout << "tvg engine: opengl" << endl; } + //Threads Count + auto threads = std::thread::hardware_concurrency(); + //Initialize ThorVG Engine - if (tvg::Initializer::init(tvgEngine) == tvg::Result::Success) { + if (tvg::Initializer::init(tvgEngine, threads) == tvg::Result::Success) { elm_init(argc, argv); diff --git a/test/testPathCopy.cpp b/test/testPathCopy.cpp index fb1080b..b5d97cf 100644 --- a/test/testPathCopy.cpp +++ b/test/testPathCopy.cpp @@ -163,8 +163,11 @@ int main(int argc, char **argv) cout << "tvg engine: opengl" << endl; } + //Threads Count + auto threads = std::thread::hardware_concurrency(); + //Initialize ThorVG Engine - if (tvg::Initializer::init(tvgEngine) == tvg::Result::Success) { + if (tvg::Initializer::init(tvgEngine, threads) == tvg::Result::Success) { elm_init(argc, argv); diff --git a/test/testRadialGradient.cpp b/test/testRadialGradient.cpp index 6e77291..a64e47b 100644 --- a/test/testRadialGradient.cpp +++ b/test/testRadialGradient.cpp @@ -149,8 +149,11 @@ int main(int argc, char **argv) cout << "tvg engine: opengl" << endl; } + //Threads Count + auto threads = std::thread::hardware_concurrency(); + //Initialize ThorVG Engine - if (tvg::Initializer::init(tvgEngine) == tvg::Result::Success) { + if (tvg::Initializer::init(tvgEngine, threads) == tvg::Result::Success) { elm_init(argc, argv); diff --git a/test/testScene.cpp b/test/testScene.cpp index daa5d86..8c46428 100644 --- a/test/testScene.cpp +++ b/test/testScene.cpp @@ -156,8 +156,12 @@ int main(int argc, char **argv) cout << "tvg engine: opengl" << endl; } + //Threads Count + auto threads = std::thread::hardware_concurrency(); + //Initialize ThorVG Engine - if (tvg::Initializer::init(tvgEngine) == tvg::Result::Success) { + if (tvg::Initializer::init(tvgEngine, threads) == tvg::Result::Success) { + elm_init(argc, argv); diff --git a/test/testSceneTransform.cpp b/test/testSceneTransform.cpp index e64fa9a..ef6c157 100644 --- a/test/testSceneTransform.cpp +++ b/test/testSceneTransform.cpp @@ -200,8 +200,11 @@ int main(int argc, char **argv) cout << "tvg engine: opengl" << endl; } + //Threads Count + auto threads = std::thread::hardware_concurrency(); + //Initialize ThorVG Engine - if (tvg::Initializer::init(tvgEngine) == tvg::Result::Success) { + if (tvg::Initializer::init(tvgEngine, threads) == tvg::Result::Success) { elm_init(argc, argv); diff --git a/test/testShape.cpp b/test/testShape.cpp index af4d0c4..56acfd5 100644 --- a/test/testShape.cpp +++ b/test/testShape.cpp @@ -99,8 +99,11 @@ int main(int argc, char **argv) cout << "tvg engine: opengl" << endl; } + //Threads Count + auto threads = std::thread::hardware_concurrency(); + //Initialize ThorVG Engine - if (tvg::Initializer::init(tvgEngine) == tvg::Result::Success) { + if (tvg::Initializer::init(tvgEngine, threads) == tvg::Result::Success) { elm_init(argc, argv); diff --git a/test/testStroke.cpp b/test/testStroke.cpp index 778d7c7..5ac2265 100644 --- a/test/testStroke.cpp +++ b/test/testStroke.cpp @@ -146,8 +146,11 @@ int main(int argc, char **argv) cout << "tvg engine: opengl" << endl; } + //Threads Count + auto threads = std::thread::hardware_concurrency(); + //Initialize ThorVG Engine - if (tvg::Initializer::init(tvgEngine) == tvg::Result::Success) { + if (tvg::Initializer::init(tvgEngine, threads) == tvg::Result::Success) { elm_init(argc, argv); diff --git a/test/testStrokeLine.cpp b/test/testStrokeLine.cpp index 1205bb1..8cc16d0 100644 --- a/test/testStrokeLine.cpp +++ b/test/testStrokeLine.cpp @@ -183,8 +183,12 @@ int main(int argc, char **argv) cout << "tvg engine: opengl" << endl; } + //Threads Count + auto threads = std::thread::hardware_concurrency(); + //Initialize ThorVG Engine - if (tvg::Initializer::init(tvgEngine) == tvg::Result::Success) { + if (tvg::Initializer::init(tvgEngine, threads) == tvg::Result::Success) { + elm_init(argc, argv); diff --git a/test/testSvg.cpp b/test/testSvg.cpp index 06fe350..ad72027 100644 --- a/test/testSvg.cpp +++ b/test/testSvg.cpp @@ -141,8 +141,11 @@ int main(int argc, char **argv) cout << "tvg engine: opengl" << endl; } + //Threads Count + auto threads = std::thread::hardware_concurrency(); + //Initialize ThorVG Engine - if (tvg::Initializer::init(tvgEngine) == tvg::Result::Success) { + if (tvg::Initializer::init(tvgEngine, threads) == tvg::Result::Success) { elm_init(argc, argv); diff --git a/test/testSvg2.cpp b/test/testSvg2.cpp index 2300f21..c859b04 100644 --- a/test/testSvg2.cpp +++ b/test/testSvg2.cpp @@ -124,8 +124,11 @@ int main(int argc, char **argv) cout << "tvg engine: opengl" << endl; } + //Threads Count + auto threads = std::thread::hardware_concurrency(); + //Initialize ThorVG Engine - if (tvg::Initializer::init(tvgEngine) == tvg::Result::Success) { + if (tvg::Initializer::init(tvgEngine, threads) == tvg::Result::Success) { elm_init(argc, argv); diff --git a/test/testTransform.cpp b/test/testTransform.cpp index 5ef33f4..6cd9be6 100644 --- a/test/testTransform.cpp +++ b/test/testTransform.cpp @@ -167,8 +167,11 @@ int main(int argc, char **argv) cout << "tvg engine: opengl" << endl; } + //Threads Count + auto threads = std::thread::hardware_concurrency(); + //Initialize ThorVG Engine - if (tvg::Initializer::init(tvgEngine) == tvg::Result::Success) { + if (tvg::Initializer::init(tvgEngine, threads) == tvg::Result::Success) { elm_init(argc, argv); diff --git a/test/testUpdate.cpp b/test/testUpdate.cpp index 3ff6c24..6df8533 100644 --- a/test/testUpdate.cpp +++ b/test/testUpdate.cpp @@ -128,8 +128,11 @@ int main(int argc, char **argv) cout << "tvg engine: opengl" << endl; } + //Threads Count + auto threads = std::thread::hardware_concurrency(); + //Initialize ThorVG Engine - if (tvg::Initializer::init(tvgEngine) == tvg::Result::Success) { + if (tvg::Initializer::init(tvgEngine, threads) == tvg::Result::Success) { elm_init(argc, argv);