diff --git a/src/renderer/gl_engine/tvgGlRenderer.cpp b/src/renderer/gl_engine/tvgGlRenderer.cpp index 1f8eb394..7a1713bc 100644 --- a/src/renderer/gl_engine/tvgGlRenderer.cpp +++ b/src/renderer/gl_engine/tvgGlRenderer.cpp @@ -20,6 +20,7 @@ * SOFTWARE. */ +#include #include "tvgGlCommon.h" #include "tvgGlRenderer.h" #include "tvgGlGpuBuffer.h" @@ -33,8 +34,8 @@ #define NOISE_LEVEL 0.5f -static int32_t initEngineCnt = false; -static int32_t rendererCnt = 0; +static atomic initEngineCnt{}; +static atomic rendererCnt{}; static void _termEngine() @@ -1285,7 +1286,7 @@ bool GlRenderer::postUpdate() } -int GlRenderer::init(uint32_t threads) +bool GlRenderer::init(uint32_t threads) { if ((initEngineCnt++) > 0) return true; @@ -1301,7 +1302,7 @@ int32_t GlRenderer::init() } -int GlRenderer::term() +bool GlRenderer::term() { if ((--initEngineCnt) > 0) return true; diff --git a/src/renderer/gl_engine/tvgGlRenderer.h b/src/renderer/gl_engine/tvgGlRenderer.h index eb51beae..edcc16af 100644 --- a/src/renderer/gl_engine/tvgGlRenderer.h +++ b/src/renderer/gl_engine/tvgGlRenderer.h @@ -93,9 +93,9 @@ public: void dispose(TVG_UNUSED RenderEffect* effect) override; static GlRenderer* gen(); - static int init(TVG_UNUSED uint32_t threads); + static bool init(TVG_UNUSED uint32_t threads); static int32_t init(); - static int term(); + static bool term(); private: GlRenderer(); diff --git a/src/renderer/sw_engine/tvgSwRenderer.cpp b/src/renderer/sw_engine/tvgSwRenderer.cpp index de123530..faa44524 100644 --- a/src/renderer/sw_engine/tvgSwRenderer.cpp +++ b/src/renderer/sw_engine/tvgSwRenderer.cpp @@ -24,6 +24,7 @@ #include #endif #include +#include #include "tvgMath.h" #include "tvgSwCommon.h" #include "tvgTaskScheduler.h" @@ -32,8 +33,8 @@ /************************************************************************/ /* Internal Class Implementation */ /************************************************************************/ -static int32_t initEngineCnt = false; -static int32_t rendererCnt = 0; +static atomic initEngineCnt{}; +static atomic rendererCnt{}; static SwMpool* globalMpool = nullptr; static uint32_t threadsCnt = 0; diff --git a/src/renderer/tvgSwCanvas.cpp b/src/renderer/tvgSwCanvas.cpp index a1c782cd..a8ccbbb9 100644 --- a/src/renderer/tvgSwCanvas.cpp +++ b/src/renderer/tvgSwCanvas.cpp @@ -76,7 +76,7 @@ Result SwCanvas::target(uint32_t* buffer, uint32_t stride, uint32_t w, uint32_t auto renderer = static_cast(pImpl->renderer); if (!renderer) return Result::MemoryCorruption; - if (!renderer->target(buffer, stride, w, h, static_cast(cs))) return Result::InvalidArguments; + if (!renderer->target(buffer, stride, w, h, cs)) return Result::InvalidArguments; pImpl->vport = {0, 0, (int32_t)w, (int32_t)h}; renderer->viewport(pImpl->vport); diff --git a/src/renderer/tvgWgCanvas.cpp b/src/renderer/tvgWgCanvas.cpp index 58ce1d29..18a30ba7 100644 --- a/src/renderer/tvgWgCanvas.cpp +++ b/src/renderer/tvgWgCanvas.cpp @@ -74,6 +74,7 @@ Result WgCanvas::target(void* device, void* instance, void* target, uint32_t w, WgCanvas* WgCanvas::gen() noexcept { #ifdef THORVG_WG_RASTER_SUPPORT + if (WgRenderer::init() <= 0) return nullptr; return new WgCanvas; #endif return nullptr; diff --git a/src/renderer/wg_engine/tvgWgRenderer.cpp b/src/renderer/wg_engine/tvgWgRenderer.cpp index dfc12209..419deb10 100755 --- a/src/renderer/wg_engine/tvgWgRenderer.cpp +++ b/src/renderer/wg_engine/tvgWgRenderer.cpp @@ -20,21 +20,23 @@ * SOFTWARE. */ +#include #include "tvgWgRenderer.h" -WgRenderer::WgRenderer() + +/************************************************************************/ +/* Internal Class Implementation */ +/************************************************************************/ + +static atomic initEngineCnt{}; +static atomic rendererCnt{}; + + +static void _termEngine() { -} + if (rendererCnt > 0) return; - -WgRenderer::~WgRenderer() -{ - release(); -} - - -void WgRenderer::initialize() -{ + //TODO: } @@ -84,6 +86,58 @@ void WgRenderer::disposeObjects() } +void WgRenderer::releaseSurfaceTexture() +{ + if (surfaceTexture.texture) { + wgpuTextureRelease(surfaceTexture.texture); + surfaceTexture.texture = nullptr; + } +} + + +void WgRenderer::clearTargets() +{ + releaseSurfaceTexture(); + if (surface) wgpuSurfaceUnconfigure(surface); + targetTexture = nullptr; + surface = nullptr; + mTargetSurface.stride = 0; + mTargetSurface.w = 0; + mTargetSurface.h = 0; + +} + + +bool WgRenderer::surfaceConfigure(WGPUSurface surface, WgContext& context, uint32_t width, uint32_t height) +{ + // store target surface properties + this->surface = surface; + if (width == 0 || height == 0 || !surface) return false; + + // setup surface configuration + WGPUSurfaceConfiguration surfaceConfiguration { + .device = context.device, + .format = context.preferredFormat, + .usage = WGPUTextureUsage_RenderAttachment, + #ifdef __EMSCRIPTEN__ + .alphaMode = WGPUCompositeAlphaMode_Premultiplied, + #endif + .width = width, + .height = height, + #ifndef __EMSCRIPTEN__ + .presentMode = WGPUPresentMode_Fifo, + #endif + }; + wgpuSurfaceConfigure(surface, &surfaceConfiguration); + return true; +} + + +/************************************************************************/ +/* External Class Implementation */ +/************************************************************************/ + + RenderData WgRenderer::prepare(const RenderShape& rshape, RenderData data, const Matrix& transform, Array& clips, uint8_t opacity, RenderUpdateFlag flags, bool clipper) { // get or create render data shape @@ -254,15 +308,6 @@ bool WgRenderer::clear() } -void WgRenderer::releaseSurfaceTexture() -{ - if (surfaceTexture.texture) { - wgpuTextureRelease(surfaceTexture.texture); - surfaceTexture.texture = nullptr; - } -} - - bool WgRenderer::sync() { disposeObjects(); @@ -368,41 +413,18 @@ bool WgRenderer::target(WGPUDevice device, WGPUInstance instance, void* target, } -void WgRenderer::clearTargets() +WgRenderer::WgRenderer() { - releaseSurfaceTexture(); - if (surface) wgpuSurfaceUnconfigure(surface); - targetTexture = nullptr; - surface = nullptr; - mTargetSurface.stride = 0; - mTargetSurface.w = 0; - mTargetSurface.h = 0; - } -bool WgRenderer::surfaceConfigure(WGPUSurface surface, WgContext& context, uint32_t width, uint32_t height) +WgRenderer::~WgRenderer() { - // store target surface properties - this->surface = surface; - if (width == 0 || height == 0 || !surface) return false; + release(); - // setup surface configuration - WGPUSurfaceConfiguration surfaceConfiguration { - .device = context.device, - .format = context.preferredFormat, - .usage = WGPUTextureUsage_RenderAttachment, - #ifdef __EMSCRIPTEN__ - .alphaMode = WGPUCompositeAlphaMode_Premultiplied, - #endif - .width = width, - .height = height, - #ifndef __EMSCRIPTEN__ - .presentMode = WGPUPresentMode_Fifo, - #endif - }; - wgpuSurfaceConfigure(surface, &surfaceConfiguration); - return true; + --rendererCnt; + + if (rendererCnt == 0 && initEngineCnt == 0) _termEngine(); } @@ -559,19 +581,36 @@ bool WgRenderer::postUpdate() } -WgRenderer* WgRenderer::gen() +bool WgRenderer::init(TVG_UNUSED uint32_t threads) { - return new WgRenderer(); + if ((initEngineCnt++) > 0) return true; + + //TODO: global engine init + + return true; } -bool WgRenderer::init(TVG_UNUSED uint32_t threads) +int32_t WgRenderer::init() { - return true; + return initEngineCnt; } bool WgRenderer::term() { + if ((--initEngineCnt) > 0) return true; + + initEngineCnt = 0; + + _termEngine(); + return true; } + + +WgRenderer* WgRenderer::gen() +{ + ++rendererCnt; + return new WgRenderer(); +} \ No newline at end of file diff --git a/src/renderer/wg_engine/tvgWgRenderer.h b/src/renderer/wg_engine/tvgWgRenderer.h index 654e1956..f246d5e8 100755 --- a/src/renderer/wg_engine/tvgWgRenderer.h +++ b/src/renderer/wg_engine/tvgWgRenderer.h @@ -60,12 +60,12 @@ public: static WgRenderer* gen(); static bool init(uint32_t threads); + static int32_t init(); static bool term(); private: WgRenderer(); ~WgRenderer(); - void initialize(); void release(); void disposeObjects(); void releaseSurfaceTexture();