comparison OrthancStone/Sources/OpenGL/WebAssemblyOpenGLContext.cpp @ 1576:92fca2b3ba3d

sanitizing the handling of canvas size
author Sebastien Jodogne <s.jodogne@gmail.com>
date Thu, 24 Sep 2020 16:40:30 +0200
parents e4a52cbbdd70
children 1f812f4c95be
comparison
equal deleted inserted replaced
1575:e4a52cbbdd70 1576:92fca2b3ba3d
37 class WebAssemblyOpenGLContext::PImpl 37 class WebAssemblyOpenGLContext::PImpl
38 { 38 {
39 private: 39 private:
40 std::string canvasSelector_; 40 std::string canvasSelector_;
41 EMSCRIPTEN_WEBGL_CONTEXT_HANDLE context_; 41 EMSCRIPTEN_WEBGL_CONTEXT_HANDLE context_;
42 unsigned int canvasWidth_;
43 unsigned int canvasHeight_;
44 bool isContextLost_; 42 bool isContextLost_;
45 43
46 public: 44 public:
47 explicit PImpl(const std::string& canvasSelector) : 45 explicit PImpl(const std::string& canvasSelector) :
48 canvasSelector_(canvasSelector), 46 canvasSelector_(canvasSelector),
50 { 48 {
51 // Context configuration 49 // Context configuration
52 EmscriptenWebGLContextAttributes attr; 50 EmscriptenWebGLContextAttributes attr;
53 emscripten_webgl_init_context_attributes(&attr); 51 emscripten_webgl_init_context_attributes(&attr);
54 52
55 #if 0 53 #if 1
56 // The next line might be necessary to print on Firefox 71 54 // The next line might be necessary to print on Firefox 71
57 // using WebGL. Sometimes, if set to "false" (the default 55 // using WebGL. Sometimes, if set to "false" (the default
58 // value), the canvas was rendered as a fully white or black 56 // value), the canvas was rendered as a fully white or black
59 // area. UNCONFIRMED, so disabled. 57 // area. UNCONFIRMED, so disabled.
60 attr.preserveDrawingBuffer = true; 58 attr.preserveDrawingBuffer = true;
67 message += canvasSelector; 65 message += canvasSelector;
68 message += "\" Please make sure the -s DISABLE_DEPRECATED_FIND_EVENT_TARGET_BEHAVIOR=1 flag has been passed to Emscripten when building."; 66 message += "\" Please make sure the -s DISABLE_DEPRECATED_FIND_EVENT_TARGET_BEHAVIOR=1 flag has been passed to Emscripten when building.";
69 LOG(ERROR) << message; 67 LOG(ERROR) << message;
70 throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError, message); 68 throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError, message);
71 } 69 }
72
73 UpdateSize();
74 } 70 }
75 71
76 void* DebugGetInternalContext() const 72 void* DebugGetInternalContext() const
77 { 73 {
78 return reinterpret_cast<void*>(context_); 74 return reinterpret_cast<void*>(context_);
159 * 155 *
160 * Could call "emscripten_webgl_commit_frame()" if 156 * Could call "emscripten_webgl_commit_frame()" if
161 * "explicitSwapControl" option were set to "true". 157 * "explicitSwapControl" option were set to "true".
162 **/ 158 **/
163 } 159 }
164
165 unsigned int GetCanvasWidth() const
166 {
167 return canvasWidth_;
168 }
169
170 unsigned int GetCanvasHeight() const
171 {
172 return canvasHeight_;
173 }
174
175 void UpdateSize()
176 {
177 double w, h;
178 emscripten_get_element_css_size(canvasSelector_.c_str(), &w, &h);
179
180 /**
181 * Emscripten has the function emscripten_get_element_css_size()
182 * to query the width and height of a named HTML element. I'm
183 * calling this first to get the initial size of the canvas DOM
184 * element, and then call emscripten_set_canvas_size() to
185 * initialize the framebuffer size of the canvas to the same
186 * size as its DOM element.
187 * https://floooh.github.io/2017/02/22/emsc-html.html
188 **/
189
190 if (w <= 0 ||
191 h <= 0)
192 {
193 canvasWidth_ = 0;
194 canvasHeight_ = 0;
195 }
196 else
197 {
198 canvasWidth_ = static_cast<unsigned int>(boost::math::iround(w));
199 canvasHeight_ = static_cast<unsigned int>(boost::math::iround(h));
200 }
201
202 emscripten_set_canvas_element_size(canvasSelector_.c_str(), canvasWidth_, canvasHeight_);
203 }
204 }; 160 };
205 161
206 162
207 WebAssemblyOpenGLContext::WebAssemblyOpenGLContext(const std::string& canvasSelector) : 163 WebAssemblyOpenGLContext::WebAssemblyOpenGLContext(const std::string& canvasSelector) :
208 pimpl_(new PImpl(canvasSelector)) 164 pimpl_(new PImpl(canvasSelector))
234 { 190 {
235 assert(pimpl_.get() != NULL); 191 assert(pimpl_.get() != NULL);
236 pimpl_->SwapBuffer(); 192 pimpl_->SwapBuffer();
237 } 193 }
238 194
239 unsigned int WebAssemblyOpenGLContext::GetCanvasWidth() const
240 {
241 assert(pimpl_.get() != NULL);
242 return pimpl_->GetCanvasWidth();
243 }
244
245 unsigned int WebAssemblyOpenGLContext::GetCanvasHeight() const
246 {
247 assert(pimpl_.get() != NULL);
248 return pimpl_->GetCanvasHeight();
249 }
250
251 void WebAssemblyOpenGLContext::RefreshCanvasSize()
252 {
253 assert(pimpl_.get() != NULL);
254
255 try
256 {
257 pimpl_->UpdateSize();
258 }
259 catch (const StoneException& e)
260 {
261 // Ignore problems about the loss of the WebGL context (edge case)
262 if (e.GetErrorCode() == ErrorCode_WebGLContextLost)
263 {
264 return;
265 }
266 else
267 {
268 throw;
269 }
270 }
271 }
272
273 const std::string& WebAssemblyOpenGLContext::GetCanvasSelector() const 195 const std::string& WebAssemblyOpenGLContext::GetCanvasSelector() const
274 { 196 {
275 assert(pimpl_.get() != NULL); 197 assert(pimpl_.get() != NULL);
276 return pimpl_->GetCanvasSelector(); 198 return pimpl_->GetCanvasSelector();
277 } 199 }