Mercurial > hg > orthanc-stone
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(); |