diff --git a/.gitignore b/.gitignore index 53a53b5b..0234166a 100644 --- a/.gitignore +++ b/.gitignore @@ -23,3 +23,4 @@ testSvg2 testAsync testCapi testArc +testMultiCanvas diff --git a/src/lib/gl_engine/tvgGlRenderer.cpp b/src/lib/gl_engine/tvgGlRenderer.cpp index f6b31d41..9e9f8efc 100644 --- a/src/lib/gl_engine/tvgGlRenderer.cpp +++ b/src/lib/gl_engine/tvgGlRenderer.cpp @@ -28,8 +28,15 @@ /************************************************************************/ /* Internal Class Implementation */ /************************************************************************/ +static bool initEngine = false; +static uint32_t rendererCnt = 0; -static RenderInitializer renderInit; +static void _termEngine() +{ + if (rendererCnt > 0) return; + + //TODO: Clean up global resources +} /************************************************************************/ /* External Class Implementation */ @@ -160,36 +167,44 @@ void* GlRenderer::prepare(const Shape& shape, void* data, TVG_UNUSED const Rende int GlRenderer::init() { - return RenderInitializer::init(renderInit, new GlRenderer); + if (rendererCnt > 0) return false; + if (initEngine) return true; + + //TODO: + + initEngine = true; + + return true; } int GlRenderer::term() { - if (inst()->mColorProgram.get()) + if (!initEngine) return true; + + initEngine = false; + + _termEngine(); + + return true; +} + + +GlRenderer* GlRenderer::gen() +{ + return new GlRenderer(); +} + + +GlRenderer::~GlRenderer() +{ + if (mColorProgram.get()) { - inst()->mColorProgram.reset(nullptr); + mColorProgram.reset(nullptr); } - return RenderInitializer::term(renderInit); -} - -uint32_t GlRenderer::unref() -{ - return RenderInitializer::unref(renderInit); -} - - -uint32_t GlRenderer::ref() -{ - return RenderInitializer::ref(renderInit); -} - - -GlRenderer* GlRenderer::inst() -{ - //We know renderer type, avoid dynamic_cast for performance. - return static_cast(RenderInitializer::inst(renderInit)); + --rendererCnt; + if (!initEngine) _termEngine(); } diff --git a/src/lib/gl_engine/tvgGlRenderer.h b/src/lib/gl_engine/tvgGlRenderer.h index 9a86bae1..a0f57152 100644 --- a/src/lib/gl_engine/tvgGlRenderer.h +++ b/src/lib/gl_engine/tvgGlRenderer.h @@ -40,16 +40,14 @@ public: bool target(uint32_t* buffer, uint32_t stride, uint32_t w, uint32_t h); bool flush() override; bool clear() override; - uint32_t ref() override; - uint32_t unref() override; - static GlRenderer* inst(); + static GlRenderer* gen(); static int init(); static int term(); private: GlRenderer(){}; - ~GlRenderer(){}; + ~GlRenderer(); void initShaders(); void drawPrimitive(GlGeometry& geometry, float r, float g, float b, float a, uint32_t primitiveIndex, RenderUpdateFlag flag); diff --git a/src/lib/sw_engine/tvgSwRenderer.cpp b/src/lib/sw_engine/tvgSwRenderer.cpp index 24b5a16f..e69aaa4e 100644 --- a/src/lib/sw_engine/tvgSwRenderer.cpp +++ b/src/lib/sw_engine/tvgSwRenderer.cpp @@ -25,7 +25,8 @@ /************************************************************************/ /* Internal Class Implementation */ /************************************************************************/ -static RenderInitializer renderInit; +static bool initEngine = false; +static uint32_t rendererCnt = 0; struct SwTask : Task { @@ -84,6 +85,13 @@ struct SwTask : Task } }; +static void _termEngine() +{ + if (rendererCnt > 0) return; + + //TODO: Clean up global resources +} + /************************************************************************/ /* External Class Implementation */ @@ -91,8 +99,12 @@ struct SwTask : Task SwRenderer::~SwRenderer() { - flush(); + clear(); + if (surface) delete(surface); + + --rendererCnt; + if (!initEngine) _termEngine(); } @@ -101,15 +113,6 @@ bool SwRenderer::clear() for (auto task : tasks) task->get(); tasks.clear(); - return flush(); -} - - -bool SwRenderer::flush() -{ - for (auto task : tasks) task->get(); - tasks.clear(); - return true; } @@ -202,32 +205,32 @@ void* SwRenderer::prepare(const Shape& sdata, void* data, const RenderTransform* } -int SwRenderer::init() +bool SwRenderer::init() { - return RenderInitializer::init(renderInit, new SwRenderer); + if (rendererCnt > 0) return false; + if (initEngine) return true; + + //TODO: + + initEngine = true; + + return true; } -int SwRenderer::term() +bool SwRenderer::term() { - return RenderInitializer::term(renderInit); + if (!initEngine) return true; + + initEngine = false; + + _termEngine(); + + return true; } - -uint32_t SwRenderer::unref() +SwRenderer* SwRenderer::gen() { - return RenderInitializer::unref(renderInit); -} - - -uint32_t SwRenderer::ref() -{ - return RenderInitializer::ref(renderInit); -} - - -SwRenderer* SwRenderer::inst() -{ - //We know renderer type, avoid dynamic_cast for performance. - return static_cast(RenderInitializer::inst(renderInit)); + ++rendererCnt; + return new SwRenderer(); } diff --git a/src/lib/sw_engine/tvgSwRenderer.h b/src/lib/sw_engine/tvgSwRenderer.h index 8f4abab7..35fce30f 100644 --- a/src/lib/sw_engine/tvgSwRenderer.h +++ b/src/lib/sw_engine/tvgSwRenderer.h @@ -36,13 +36,10 @@ public: bool preRender() override; bool target(uint32_t* buffer, uint32_t stride, uint32_t w, uint32_t h, uint32_t cs); bool clear() override; - bool flush() override; - uint32_t ref() override; - uint32_t unref() override; - static SwRenderer* inst(); - static int init(); - static int term(); + static SwRenderer* gen(); + static bool init(); + static bool term(); private: SwSurface* surface = nullptr; diff --git a/src/lib/tvgCanvasImpl.h b/src/lib/tvgCanvasImpl.h index 4e15acea..d5b1b767 100644 --- a/src/lib/tvgCanvasImpl.h +++ b/src/lib/tvgCanvasImpl.h @@ -35,14 +35,12 @@ struct Canvas::Impl Impl(RenderMethod* pRenderer):renderer(pRenderer) { - renderer->ref(); } ~Impl() { - renderer->flush(); //make it sur async engine working finished. clear(); - renderer->unref(); + delete(renderer); } Result push(unique_ptr paint) diff --git a/src/lib/tvgGlCanvas.cpp b/src/lib/tvgGlCanvas.cpp index 7f267a44..235bacbb 100644 --- a/src/lib/tvgGlCanvas.cpp +++ b/src/lib/tvgGlCanvas.cpp @@ -46,7 +46,7 @@ struct GlCanvas::Impl /************************************************************************/ #ifdef THORVG_GL_RASTER_SUPPORT -GlCanvas::GlCanvas() : Canvas(GlRenderer::inst()), pImpl(make_unique()) +GlCanvas::GlCanvas() : Canvas(GlRenderer::gen()), pImpl(make_unique()) #else GlCanvas::GlCanvas() : Canvas(nullptr), pImpl(make_unique()) #endif diff --git a/src/lib/tvgRender.h b/src/lib/tvgRender.h index c379d0e4..9beb72b6 100644 --- a/src/lib/tvgRender.h +++ b/src/lib/tvgRender.h @@ -64,63 +64,6 @@ public: virtual bool postRender() { return true; } virtual bool clear() { return true; } virtual bool flush() { return true; } - virtual uint32_t ref() { return 0; } - virtual uint32_t unref() { return 0; } -}; - -struct RenderInitializer -{ - RenderMethod* pInst = nullptr; - uint32_t refCnt = 0; - bool initialized = false; - - static bool init(RenderInitializer& renderInit, RenderMethod* engine) - { - if (renderInit.pInst || renderInit.refCnt > 0) return false; - renderInit.pInst = engine; - renderInit.refCnt = 0; - renderInit.initialized = true; - return true; - } - - static bool term(RenderInitializer& renderInit) - { - if (!renderInit.pInst || !renderInit.initialized) return false; - - renderInit.initialized = false; - - //Still it's refered.... - if (renderInit.refCnt > 0) return true; - delete(renderInit.pInst); - renderInit.pInst = nullptr; - - return true; - } - - static uint32_t unref(RenderInitializer& renderInit) - { - --renderInit.refCnt; - - //engine has been requested to termination - if (!renderInit.initialized && renderInit.refCnt == 0) { - if (renderInit.pInst) { - delete(renderInit.pInst); - renderInit.pInst = nullptr; - } - } - return renderInit.refCnt; - } - - static RenderMethod* inst(RenderInitializer& renderInit) - { - return renderInit.pInst; - } - - static uint32_t ref(RenderInitializer& renderInit) - { - return ++renderInit.refCnt; - } - }; } diff --git a/src/lib/tvgSwCanvas.cpp b/src/lib/tvgSwCanvas.cpp index b56beb46..5e6af449 100644 --- a/src/lib/tvgSwCanvas.cpp +++ b/src/lib/tvgSwCanvas.cpp @@ -46,7 +46,7 @@ struct SwCanvas::Impl /************************************************************************/ #ifdef THORVG_SW_RASTER_SUPPORT -SwCanvas::SwCanvas() : Canvas(SwRenderer::inst()), pImpl(make_unique()) +SwCanvas::SwCanvas() : Canvas(SwRenderer::gen()), pImpl(make_unique()) #else SwCanvas::SwCanvas() : Canvas(nullptr), pImpl(make_unique()) #endif diff --git a/test/makefile b/test/makefile index f48278d4..2bdd5499 100644 --- a/test/makefile +++ b/test/makefile @@ -20,4 +20,5 @@ all: gcc -o testSvg2 testSvg2.cpp -g -lstdc++ `pkg-config --cflags --libs elementary thorvg` gcc -o testAsync testAsync.cpp -g -lstdc++ `pkg-config --cflags --libs elementary thorvg` gcc -o testArc testArc.cpp -g -lstdc++ `pkg-config --cflags --libs elementary thorvg` + gcc -o testMultiCanvas testMultiCanvas.cpp -g -lstdc++ `pkg-config --cflags --libs elementary thorvg` gcc -o testCapi testCapi.c -g `pkg-config --cflags --libs elementary thorvg` diff --git a/test/testCommon.h b/test/testCommon.h index a5f222ef..5dd70cd1 100644 --- a/test/testCommon.h +++ b/test/testCommon.h @@ -50,7 +50,7 @@ void drawGLview(Evas_Object *obj); static Eo* createGlView() { - elm_config_accel_preference_set("gl"); + elm_config_accel_preference_set("gl"); Eo* win = elm_win_util_standard_add(NULL, "ThorVG Test"); evas_object_smart_callback_add(win, "delete,request", win_del, 0);