comparison Framework/OpenGL/WebAssemblyOpenGLContext.cpp @ 947:1091b2adeb5a toa2019081001

Fixed animation frame stopping when returning false + big work on the OpenGL objects to make them lost context-safe + debug code to forcefully tag a context as lost + debug macros
author Benjamin Golinvaux <bgo@osimis.io>
date Sat, 10 Aug 2019 13:07:31 +0200
parents 2db3ef713664
children a7351ad54960
comparison
equal deleted inserted replaced
946:dbe3e1e47019 947:1091b2adeb5a
19 **/ 19 **/
20 20
21 21
22 #include "WebAssemblyOpenGLContext.h" 22 #include "WebAssemblyOpenGLContext.h"
23 23
24 #include "../StoneException.h"
25
24 #include <Core/OrthancException.h> 26 #include <Core/OrthancException.h>
25 27
26 #include <emscripten/html5.h> 28 #include <emscripten/html5.h>
27 #include <emscripten/em_asm.h> 29 #include <emscripten/em_asm.h>
28 30
33 namespace OpenGL 35 namespace OpenGL
34 { 36 {
35 class WebAssemblyOpenGLContext::PImpl 37 class WebAssemblyOpenGLContext::PImpl
36 { 38 {
37 private: 39 private:
38 std::string canvas_; 40 std::string canvas_;
39 EMSCRIPTEN_WEBGL_CONTEXT_HANDLE context_; 41 EMSCRIPTEN_WEBGL_CONTEXT_HANDLE context_;
40 unsigned int canvasWidth_; 42 unsigned int canvasWidth_;
41 unsigned int canvasHeight_; 43 unsigned int canvasHeight_;
44 bool isContextLost_;
42 45
43 public: 46 public:
44 PImpl(const std::string& canvas) : 47 PImpl(const std::string& canvas)
45 canvas_(canvas) 48 : canvas_(canvas)
49 , isContextLost_(false)
46 { 50 {
47 // Context configuration 51 // Context configuration
48 EmscriptenWebGLContextAttributes attr; 52 EmscriptenWebGLContextAttributes attr;
49 emscripten_webgl_init_context_attributes(&attr); 53 emscripten_webgl_init_context_attributes(&attr);
50 54
58 } 62 }
59 63
60 UpdateSize(); 64 UpdateSize();
61 } 65 }
62 66
67 void* DebugGetInternalContext() const
68 {
69 return reinterpret_cast<void*>(context_);
70 }
71
72 bool IsContextLost() const
73 {
74 bool apiFlag = (emscripten_is_webgl_context_lost(context_) != 0);
75 bool ownFlag = isContextLost_;
76 if (ownFlag != apiFlag)
77 {
78 LOG(WARNING) << "Context loss, according to emscripten, is: " << apiFlag << " | while, according to internal state, is: " << ownFlag;
79 }
80 return ownFlag | apiFlag;
81 }
82
83 void SetLostContext()
84 {
85 isContextLost_ = true;
86 }
87
63 ~PImpl() 88 ~PImpl()
64 { 89 {
65 emscripten_webgl_destroy_context(context_); 90 emscripten_webgl_destroy_context(context_);
66 } 91 }
67 92
70 return canvas_; 95 return canvas_;
71 } 96 }
72 97
73 void MakeCurrent() 98 void MakeCurrent()
74 { 99 {
100 if (IsContextLost())
101 {
102 LOG(ERROR) << "MakeCurrent() called on lost context " << context_;
103 throw OpenGLContextLostException(reinterpret_cast<void*>(context_));
104 }
105
75 if (emscripten_is_webgl_context_lost(context_)) 106 if (emscripten_is_webgl_context_lost(context_))
76 { 107 {
77 LOG(ERROR) << "OpenGL context has been lost! for canvas: " << canvas_; 108 LOG(ERROR) << "OpenGL context has been lost for canvas: " << canvas_;
78 throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError, 109 SetLostContext();
79 "OpenGL context has been lost!"); 110 throw OpenGLContextLostException(reinterpret_cast<void*>(context_));
80 } 111 }
81 112
82 if (emscripten_webgl_make_context_current(context_) != EMSCRIPTEN_RESULT_SUCCESS) 113 if (emscripten_webgl_make_context_current(context_) != EMSCRIPTEN_RESULT_SUCCESS)
83 { 114 {
84 throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError, 115 throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError,
144 WebAssemblyOpenGLContext::WebAssemblyOpenGLContext(const std::string& canvas) : 175 WebAssemblyOpenGLContext::WebAssemblyOpenGLContext(const std::string& canvas) :
145 pimpl_(new PImpl(canvas)) 176 pimpl_(new PImpl(canvas))
146 { 177 {
147 } 178 }
148 179
180 bool WebAssemblyOpenGLContext::IsContextLost() const
181 {
182 return pimpl_->IsContextLost();
183 }
184
185 void WebAssemblyOpenGLContext::RestoreLostContext()
186 {
187 throw Orthanc::OrthancException(Orthanc::ErrorCode_NotImplemented);
188 }
189
190 void WebAssemblyOpenGLContext::SetLostContext()
191 {
192 pimpl_->SetLostContext();
193 }
194
195 void* WebAssemblyOpenGLContext::DebugGetInternalContext() const
196 {
197 return pimpl_->DebugGetInternalContext();
198 }
199
149 void WebAssemblyOpenGLContext::MakeCurrent() 200 void WebAssemblyOpenGLContext::MakeCurrent()
150 { 201 {
151 assert(pimpl_.get() != NULL); 202 assert(pimpl_.get() != NULL);
152 pimpl_->MakeCurrent(); 203 pimpl_->MakeCurrent();
153 } 204 }
154
155 205
156 void WebAssemblyOpenGLContext::SwapBuffer() 206 void WebAssemblyOpenGLContext::SwapBuffer()
157 { 207 {
158 assert(pimpl_.get() != NULL); 208 assert(pimpl_.get() != NULL);
159 pimpl_->SwapBuffer(); 209 pimpl_->SwapBuffer();