diff --git a/src/bindings/wasm/tvgWasmLottieAnimation.cpp b/src/bindings/wasm/tvgWasmLottieAnimation.cpp index 61d1a2f8..48faa174 100644 --- a/src/bindings/wasm/tvgWasmLottieAnimation.cpp +++ b/src/bindings/wasm/tvgWasmLottieAnimation.cpp @@ -188,7 +188,7 @@ struct TvgWgEngine : TvgEngineMethod struct TvgGLEngine : TvgEngineMethod { - uintptr_t context = 0; + EMSCRIPTEN_WEBGL_CONTEXT_HANDLE context = 0; ~TvgGLEngine() override { #ifdef THORVG_GL_RASTER_SUPPORT @@ -227,9 +227,7 @@ struct TvgGLEngine : TvgEngineMethod void resize(Canvas* canvas, int w, int h) override { #ifdef THORVG_GL_RASTER_SUPPORT - emscripten_webgl_make_context_current(context); - - static_cast(canvas)->target(0, w, h, ColorSpace::ABGR8888S); + static_cast(canvas)->target((void*)context, 0, w, h, ColorSpace::ABGR8888S); #endif } }; diff --git a/src/renderer/gl_engine/tvgGlCommon.h b/src/renderer/gl_engine/tvgGlCommon.h index 45e8dc68..1d34c470 100644 --- a/src/renderer/gl_engine/tvgGlCommon.h +++ b/src/renderer/gl_engine/tvgGlCommon.h @@ -44,6 +44,7 @@ #include "tvgMath.h" #ifdef __EMSCRIPTEN__ + #include // query GL Error on WebGL is very slow, so disable it on WebGL #define GL_CHECK(x) x #else diff --git a/src/renderer/gl_engine/tvgGlRenderer.cpp b/src/renderer/gl_engine/tvgGlRenderer.cpp index e8b0030f..32c8df50 100644 --- a/src/renderer/gl_engine/tvgGlRenderer.cpp +++ b/src/renderer/gl_engine/tvgGlRenderer.cpp @@ -74,6 +74,19 @@ void GlRenderer::flush() } +void GlRenderer::currentContext() +{ +#ifdef __EMSCRIPTEN__ + auto targetContext = (EMSCRIPTEN_WEBGL_CONTEXT_HANDLE)mContext; + if (emscripten_webgl_get_current_context() != targetContext) { + emscripten_webgl_make_context_current(targetContext); + } +#else + TVGERR("GL_ENGINE", "Maybe missing MakeCurrent() Call?"); +#endif +} + + GlRenderer::GlRenderer() { } @@ -785,9 +798,12 @@ bool GlRenderer::clear() } -bool GlRenderer::target(int32_t id, uint32_t w, uint32_t h) +bool GlRenderer::target(void* context, int32_t id, uint32_t w, uint32_t h) { - if (id == GL_INVALID_VALUE || w == 0 || h == 0) return false; + //assume the context zero is invalid + if (!context || id == GL_INVALID_VALUE || w == 0 || h == 0) return false; + + currentContext(); flush(); @@ -795,6 +811,7 @@ bool GlRenderer::target(int32_t id, uint32_t w, uint32_t h) surface.w = w; surface.h = h; + mContext = context; mTargetFboId = static_cast(id); mRootTarget.mWidth = surface.w; @@ -811,6 +828,8 @@ bool GlRenderer::sync() //nothing to be done. if (mRenderPassStack.empty()) return true; + currentContext(); + // Blend function for straight alpha GL_CHECK(glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA)); GL_CHECK(glEnable(GL_BLEND)); @@ -860,6 +879,7 @@ RenderRegion GlRenderer::region(RenderData data) bool GlRenderer::preRender() { + currentContext(); if (mPrograms.empty()) initShaders(); mRenderPassStack.push(new GlRenderPass(&mRootTarget)); @@ -1235,6 +1255,7 @@ bool GlRenderer::viewport(const RenderRegion& vp) bool GlRenderer::preUpdate() { + currentContext(); return true; } diff --git a/src/renderer/gl_engine/tvgGlRenderer.h b/src/renderer/gl_engine/tvgGlRenderer.h index a4f745ae..1504710d 100644 --- a/src/renderer/gl_engine/tvgGlRenderer.h +++ b/src/renderer/gl_engine/tvgGlRenderer.h @@ -79,7 +79,7 @@ public: ColorSpace colorSpace() override; const RenderSurface* mainSurface() override; - bool target(int32_t id, uint32_t w, uint32_t h); + bool target(void* context, int32_t id, uint32_t w, uint32_t h); bool sync() override; bool clear() override; @@ -115,7 +115,9 @@ private: void endRenderPass(RenderCompositor* cmp); void flush(); + void currentContext(); + void* mContext = nullptr; RenderSurface surface; GLint mTargetFboId = 0; RenderRegion mViewport; diff --git a/src/renderer/tvgGlCanvas.cpp b/src/renderer/tvgGlCanvas.cpp index f1abecc3..f8099558 100644 --- a/src/renderer/tvgGlCanvas.cpp +++ b/src/renderer/tvgGlCanvas.cpp @@ -54,7 +54,7 @@ Result GlCanvas::target(void* context, int32_t id, uint32_t w, uint32_t h, Color auto renderer = static_cast(pImpl->renderer); if (!renderer) return Result::MemoryCorruption; - if (!renderer->target(id, w, h)) return Result::Unknown; + if (!renderer->target(context, id, w, h)) return Result::Unknown; pImpl->vport = {0, 0, (int32_t)w, (int32_t)h}; renderer->viewport(pImpl->vport);