diff options
Diffstat (limited to '3rdparty/bgfx/src/glcontext_html5.cpp')
-rw-r--r-- | 3rdparty/bgfx/src/glcontext_html5.cpp | 107 |
1 files changed, 64 insertions, 43 deletions
diff --git a/3rdparty/bgfx/src/glcontext_html5.cpp b/3rdparty/bgfx/src/glcontext_html5.cpp index c9f15922e4c..a884ab7b35f 100644 --- a/3rdparty/bgfx/src/glcontext_html5.cpp +++ b/3rdparty/bgfx/src/glcontext_html5.cpp @@ -1,5 +1,5 @@ /* - * Copyright 2011-2019 Branimir Karadzic. All rights reserved. + * Copyright 2011-2021 Branimir Karadzic. All rights reserved. * License: https://github.com/bkaradzic/bgfx#license-bsd-2-clause */ @@ -10,8 +10,7 @@ # if BGFX_USE_HTML5 -#include <emscripten/emscripten.h> -#include <emscripten/html5.h> +# include "emscripten.h" // from emscripten gl.c, because we're not going to go // through egl @@ -45,13 +44,13 @@ namespace bgfx { namespace gl ~SwapChainGL() { - emscripten_webgl_destroy_context(m_context); + EMSCRIPTEN_CHECK(emscripten_webgl_destroy_context(m_context) ); BX_FREE(g_allocator, m_canvas); } void makeCurrent() { - emscripten_webgl_make_context_current(m_context); + EMSCRIPTEN_CHECK(emscripten_webgl_make_context_current(m_context) ); } void swapBuffers() @@ -70,12 +69,15 @@ namespace bgfx { namespace gl if (m_primary != NULL) return; - const char* canvas = (const char*) g_platformData.nwh; // if 0, Module.canvas is used + const char* canvas = (const char*) g_platformData.nwh; m_primary = createSwapChain((void*)canvas); - if (_width && _height) - emscripten_set_canvas_element_size(canvas, (int)_width, (int)_height); + if (0 != _width + && 0 != _height) + { + EMSCRIPTEN_CHECK(emscripten_set_canvas_element_size(canvas, (int)_width, (int)_height) ); + } makeCurrent(m_primary); } @@ -101,44 +103,46 @@ namespace bgfx { namespace gl return; } - emscripten_set_canvas_element_size(m_primary->m_canvas, (int) _width, (int) _height); + EMSCRIPTEN_CHECK(emscripten_set_canvas_element_size(m_primary->m_canvas, (int) _width, (int) _height) ); } SwapChainGL* GlContext::createSwapChain(void* _nwh) { emscripten_webgl_init_context_attributes(&s_attrs); - s_attrs.alpha = false; - s_attrs.depth = true; - s_attrs.stencil = true; + // Work around bug https://bugs.chromium.org/p/chromium/issues/detail?id=1045643 in Chrome + // by having alpha always enabled. + s_attrs.alpha = true; + s_attrs.premultipliedAlpha = false; + s_attrs.depth = true; + s_attrs.stencil = true; s_attrs.enableExtensionsByDefault = true; + s_attrs.antialias = false; - // let emscripten figure out the best WebGL context to create - s_attrs.majorVersion = 0; - s_attrs.majorVersion = 0; - + s_attrs.minorVersion = 0; const char* canvas = (const char*) _nwh; + int error = 0; - int context = emscripten_webgl_create_context(canvas, &s_attrs); - - if (context <= 0) + for (int version = 2; version >= 1; --version) { - BX_TRACE("Failed to create WebGL context. (Canvas handle: '%s', error %d)", canvas, (int)context); - return NULL; - } + s_attrs.majorVersion = version; + EMSCRIPTEN_WEBGL_CONTEXT_HANDLE context = emscripten_webgl_create_context(canvas, &s_attrs); - int result = emscripten_webgl_make_context_current(context); - if (EMSCRIPTEN_RESULT_SUCCESS != result) - { - BX_TRACE("emscripten_webgl_make_context_current failed (%d)", result); - return NULL; - } + if (context > 0) + { + EMSCRIPTEN_CHECK(emscripten_webgl_make_context_current(context) ); + + SwapChainGL* swapChain = BX_NEW(g_allocator, SwapChainGL)(context, canvas); - SwapChainGL* swapChain = BX_NEW(g_allocator, SwapChainGL)(context, canvas); + import(version); - import(1); + return swapChain; + } + error = (int) context; + } - return swapChain; + BX_TRACE("Failed to create WebGL context. (Canvas handle: '%s', last attempt error %d)", canvas, error); + return NULL; } uint64_t GlContext::getCaps() const @@ -175,22 +179,39 @@ namespace bgfx { namespace gl } } - void GlContext::import(int webGLVersion) + template<typename Fn> + static Fn getProcAddress(int _version, const char* _name) + { + Fn func = reinterpret_cast<Fn>(emscripten_webgl1_get_proc_address(_name) ); + if (NULL == func && _version >= 2) + { + func = reinterpret_cast<Fn>(emscripten_webgl2_get_proc_address(_name) ); + } + + return func; + } + + void GlContext::import(int _webGLVersion) { BX_TRACE("Import:"); -# define GL_EXTENSION(_optional, _proto, _func, _import) \ - { \ - if (NULL == _func) \ - { \ - _func = (_proto)emscripten_webgl1_get_proc_address(#_import); \ - if (!_func && webGLVersion >= 2) \ - _func = (_proto)emscripten_webgl2_get_proc_address(#_import); \ - BX_TRACE("\t%p " #_func " (" #_import ")", _func); \ - BGFX_FATAL(_optional || NULL != _func, Fatal::UnableToInitialize, "Failed to create WebGL/OpenGLES context. GetProcAddress(\"%s\")", #_import); \ - } \ - } + +# define GL_EXTENSION(_optional, _proto, _func, _import) \ + { \ + if (NULL == _func) \ + { \ + _func = getProcAddress<_proto>(_webGLVersion, #_import); \ + BX_TRACE("\t%p " #_func " (" #_import ")", _func); \ + BGFX_FATAL(_optional || NULL != _func, Fatal::UnableToInitialize \ + , "Failed to create WebGL/OpenGLES context. GetProcAddress(\"%s\")" \ + , #_import \ + ); \ + } \ + } # include "glimports.h" + +# undef GL_EXTENSION + } } /* namespace gl */ } // namespace bgfx |