# HG changeset patch # User Benjamin Golinvaux # Date 1565000847 -7200 # Node ID 685c9a2d115f833228e67fb3da7c694682a0d802 # Parent ab90628e70d910a646635715d7095e9376a5ccab Added missing ORTHANC_OVERRIDE + preparation for lost GL context handling + stubs for GL context event handlers diff -r ab90628e70d9 -r 685c9a2d115f Framework/OpenGL/WebAssemblyOpenGLContext.cpp --- a/Framework/OpenGL/WebAssemblyOpenGLContext.cpp Wed Jul 31 11:29:08 2019 +0200 +++ b/Framework/OpenGL/WebAssemblyOpenGLContext.cpp Mon Aug 05 12:27:27 2019 +0200 @@ -24,6 +24,8 @@ #include #include +#include + #include namespace OrthancStone @@ -70,6 +72,13 @@ void MakeCurrent() { + if (emscripten_is_webgl_context_lost(context_)) + { + LOG(ERROR) << "OpenGL context has been lost! for canvas: " << canvas_; + throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError, + "OpenGL context has been lost!"); + } + if (emscripten_webgl_make_context_current(context_) != EMSCRIPTEN_RESULT_SUCCESS) { throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError, diff -r ab90628e70d9 -r 685c9a2d115f Framework/Scene2D/CairoCompositor.h --- a/Framework/Scene2D/CairoCompositor.h Wed Jul 31 11:29:08 2019 +0200 +++ b/Framework/Scene2D/CairoCompositor.h Mon Aug 05 12:27:27 2019 +0200 @@ -44,9 +44,9 @@ // Only valid during a call to "Refresh()" std::auto_ptr context_; - virtual cairo_t* GetCairoContext(); + virtual cairo_t* GetCairoContext() ORTHANC_OVERRIDE; - virtual Internals::CompositorHelper::ILayerRenderer* Create(const ISceneLayer& layer); + virtual Internals::CompositorHelper::ILayerRenderer* Create(const ISceneLayer& layer) ORTHANC_OVERRIDE; public: CairoCompositor(const Scene2D& scene, @@ -60,27 +60,27 @@ return canvas_; } - virtual unsigned int GetCanvasWidth() const + virtual unsigned int GetCanvasWidth() const ORTHANC_OVERRIDE { return canvas_.GetWidth(); } - virtual unsigned int GetCanvasHeight() const + virtual unsigned int GetCanvasHeight() const ORTHANC_OVERRIDE { return canvas_.GetHeight(); } void SetFont(size_t index, - GlyphBitmapAlphabet* dict); // Takes ownership + GlyphBitmapAlphabet* dict); // Takes ownership #if ORTHANC_ENABLE_LOCALE == 1 virtual void SetFont(size_t index, Orthanc::EmbeddedResources::FileResourceId resource, unsigned int fontSize, - Orthanc::Encoding codepage); + Orthanc::Encoding codepage) ORTHANC_OVERRIDE; #endif - virtual void Refresh(); + virtual void Refresh() ORTHANC_OVERRIDE; void UpdateSize(unsigned int canvasWidth, unsigned int canvasHeight); diff -r ab90628e70d9 -r 685c9a2d115f Framework/Scene2D/OpenGLCompositor.cpp --- a/Framework/Scene2D/OpenGLCompositor.cpp Wed Jul 31 11:29:08 2019 +0200 +++ b/Framework/Scene2D/OpenGLCompositor.cpp Mon Aug 05 12:27:27 2019 +0200 @@ -18,7 +18,6 @@ * along with this program. If not, see . **/ - #include "OpenGLCompositor.h" #include "Internals/OpenGLAdvancedPolylineRenderer.h" @@ -60,7 +59,6 @@ } }; - const OpenGLCompositor::Font* OpenGLCompositor::GetFont(size_t fontIndex) const { Fonts::const_iterator found = fonts_.find(fontIndex); @@ -76,7 +74,6 @@ } } - Internals::CompositorHelper::ILayerRenderer* OpenGLCompositor::Create(const ISceneLayer& layer) { switch (layer.GetType()) @@ -122,7 +119,6 @@ } } - OpenGLCompositor::OpenGLCompositor(OpenGL::IOpenGLContext& context, const Scene2D& scene) : context_(context), @@ -136,7 +132,6 @@ { } - OpenGLCompositor::~OpenGLCompositor() { for (Fonts::iterator it = fonts_.begin(); it != fonts_.end(); ++it) @@ -146,7 +141,6 @@ } } - void OpenGLCompositor::Refresh() { context_.MakeCurrent(); @@ -163,7 +157,6 @@ context_.SwapBuffer(); } - void OpenGLCompositor::SetFont(size_t index, const GlyphBitmapAlphabet& dict) { @@ -185,7 +178,6 @@ found->second = font.release(); } } - #if ORTHANC_ENABLE_LOCALE == 1 void OpenGLCompositor::SetFont(size_t index, diff -r ab90628e70d9 -r 685c9a2d115f Framework/Scene2D/OpenGLCompositor.h --- a/Framework/Scene2D/OpenGLCompositor.h Wed Jul 31 11:29:08 2019 +0200 +++ b/Framework/Scene2D/OpenGLCompositor.h Mon Aug 05 12:27:27 2019 +0200 @@ -30,9 +30,7 @@ namespace OrthancStone { - class OpenGLCompositor : - public ICompositor, - private Internals::CompositorHelper::IRendererFactory + class OpenGLCompositor : public ICompositor, private Internals::CompositorHelper::IRendererFactory { private: class Font; @@ -51,7 +49,7 @@ const Font* GetFont(size_t fontIndex) const; - virtual Internals::CompositorHelper::ILayerRenderer* Create(const ISceneLayer& layer); + virtual Internals::CompositorHelper::ILayerRenderer* Create(const ISceneLayer& layer) ORTHANC_OVERRIDE; public: OpenGLCompositor(OpenGL::IOpenGLContext& context, @@ -59,7 +57,7 @@ virtual ~OpenGLCompositor(); - virtual void Refresh(); + virtual void Refresh() ORTHANC_OVERRIDE; void SetFont(size_t index, const GlyphBitmapAlphabet& dict); @@ -68,15 +66,15 @@ void SetFont(size_t index, Orthanc::EmbeddedResources::FileResourceId resource, unsigned int fontSize, - Orthanc::Encoding codepage); + Orthanc::Encoding codepage) ORTHANC_OVERRIDE; #endif - virtual unsigned int GetCanvasWidth() const + virtual unsigned int GetCanvasWidth() const ORTHANC_OVERRIDE { return canvasWidth_; } - virtual unsigned int GetCanvasHeight() const + virtual unsigned int GetCanvasHeight() const ORTHANC_OVERRIDE { return canvasHeight_; } diff -r ab90628e70d9 -r 685c9a2d115f Framework/Scene2D/Scene2D.cpp --- a/Framework/Scene2D/Scene2D.cpp Wed Jul 31 11:29:08 2019 +0200 +++ b/Framework/Scene2D/Scene2D.cpp Mon Aug 05 12:27:27 2019 +0200 @@ -199,8 +199,7 @@ return layer.release(); } } - - + void Scene2D::Apply(IVisitor& visitor) const { for (Content::const_iterator it = content_.begin(); diff -r ab90628e70d9 -r 685c9a2d115f Framework/Scene2DViewport/ViewportController.h --- a/Framework/Scene2DViewport/ViewportController.h Wed Jul 31 11:29:08 2019 +0200 +++ b/Framework/Scene2DViewport/ViewportController.h Mon Aug 05 12:27:27 2019 +0200 @@ -170,11 +170,6 @@ /** forwarded to the UndoStack */ bool CanRedo() const; - IViewport& GetViewport() - { - return viewport_; - } - Scene2D& GetScene() { return viewport_.GetScene(); diff -r ab90628e70d9 -r 685c9a2d115f Framework/Viewport/IViewport.h --- a/Framework/Viewport/IViewport.h Wed Jul 31 11:29:08 2019 +0200 +++ b/Framework/Viewport/IViewport.h Mon Aug 05 12:27:27 2019 +0200 @@ -50,6 +50,14 @@ virtual ScenePoint2D GetPixelCenterCoordinates(int x, int y) const = 0; +#if ORTHANC_ENABLE_LOCALE == 1 + virtual void SetFont(size_t index, + Orthanc::EmbeddedResources::FileResourceId resource, + unsigned int fontSize, + Orthanc::Encoding codepage) = 0; +#endif + + protected: virtual ICompositor& GetCompositor() = 0; virtual const ICompositor& GetCompositor() const diff -r ab90628e70d9 -r 685c9a2d115f Framework/Viewport/SdlViewport.h --- a/Framework/Viewport/SdlViewport.h Wed Jul 31 11:29:08 2019 +0200 +++ b/Framework/Viewport/SdlViewport.h Mon Aug 05 12:27:27 2019 +0200 @@ -81,22 +81,21 @@ boost::shared_ptr& scene, bool allowDpiScaling = true); - - virtual ICompositor& GetCompositor() - { - return compositor_; - } - - virtual SdlWindow& GetWindow() + virtual SdlWindow& GetWindow() ORTHANC_OVERRIDE { return context_.GetWindow(); } - virtual void UpdateSize(unsigned int width, - unsigned int height) + virtual void UpdateSize(unsigned int width, unsigned int height) ORTHANC_OVERRIDE { // nothing to do in OpenGL, the OpenGLCompositor::UpdateSize will be called automatically } + + protected: + virtual ICompositor& GetCompositor() ORTHANC_OVERRIDE + { + return compositor_; + } }; @@ -121,20 +120,20 @@ ~SdlCairoViewport(); - virtual ICompositor& GetCompositor() - { - return compositor_; - } - - virtual SdlWindow& GetWindow() + virtual SdlWindow& GetWindow() ORTHANC_OVERRIDE { return window_; } - virtual void Refresh(); + virtual void Refresh() ORTHANC_OVERRIDE; virtual void UpdateSize(unsigned int width, - unsigned int height); + unsigned int height) ORTHANC_OVERRIDE; + protected: + virtual ICompositor& GetCompositor() ORTHANC_OVERRIDE + { + return compositor_; + } private: void UpdateSdlSurfaceSize(unsigned int width, diff -r ab90628e70d9 -r 685c9a2d115f Framework/Viewport/ViewportBase.h --- a/Framework/Viewport/ViewportBase.h Wed Jul 31 11:29:08 2019 +0200 +++ b/Framework/Viewport/ViewportBase.h Mon Aug 05 12:27:27 2019 +0200 @@ -38,32 +38,41 @@ ViewportBase(const std::string& identifier, boost::shared_ptr& scene); - virtual Scene2D& GetScene() + virtual Scene2D& GetScene() ORTHANC_OVERRIDE { return *scene_; } - virtual const std::string& GetCanvasIdentifier() const + virtual const std::string& GetCanvasIdentifier() const ORTHANC_OVERRIDE { return identifier_; } - virtual ScenePoint2D GetPixelCenterCoordinates(int x, int y) const; + virtual ScenePoint2D GetPixelCenterCoordinates(int x, int y) const ORTHANC_OVERRIDE; - virtual void Refresh() + virtual void Refresh() ORTHANC_OVERRIDE { GetCompositor().Refresh(); } - virtual unsigned int GetCanvasWidth() const + virtual unsigned int GetCanvasWidth() const ORTHANC_OVERRIDE { return GetCompositor().GetCanvasWidth(); } - virtual unsigned int GetCanvasHeight() const + virtual unsigned int GetCanvasHeight() const ORTHANC_OVERRIDE { return GetCompositor().GetCanvasHeight(); } +#if ORTHANC_ENABLE_LOCALE == 1 + virtual void SetFont(size_t index, + Orthanc::EmbeddedResources::FileResourceId resource, + unsigned int fontSize, + Orthanc::Encoding codepage) ORTHANC_OVERRIDE + { + return GetCompositor().SetFont(index, resource, fontSize, codepage); + } +#endif }; } diff -r ab90628e70d9 -r 685c9a2d115f Framework/Viewport/WebAssemblyViewport.cpp --- a/Framework/Viewport/WebAssemblyViewport.cpp Wed Jul 31 11:29:08 2019 +0200 +++ b/Framework/Viewport/WebAssemblyViewport.cpp Mon Aug 05 12:27:27 2019 +0200 @@ -13,7 +13,7 @@ * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Affero General Public License for more details. - * + * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see . **/ @@ -26,27 +26,94 @@ { WebAssemblyOpenGLViewport::WebAssemblyOpenGLViewport(const std::string& canvas) : WebAssemblyViewport(canvas), - context_(canvas), - compositor_(context_, GetScene()) + context_(canvas) { + compositor_.reset(new OpenGLCompositor(context_, GetScene())); + RegisterContextCallbacks(); } - WebAssemblyOpenGLViewport::WebAssemblyOpenGLViewport(const std::string& canvas, - boost::shared_ptr& scene) : + boost::shared_ptr& scene) : WebAssemblyViewport(canvas, scene), - context_(canvas), - compositor_(context_, GetScene()) + context_(canvas) { + compositor_.reset(new OpenGLCompositor(context_, GetScene())); + RegisterContextCallbacks(); } - void WebAssemblyOpenGLViewport::UpdateSize() { context_.UpdateSize(); // First read the size of the canvas - compositor_.Refresh(); // Then refresh the content of the canvas + compositor_->Refresh(); // Then refresh the content of the canvas + } + + /* + typedef EM_BOOL (*em_webgl_context_callback)(int eventType, const void *reserved, void *userData); + + EMSCRIPTEN_EVENT_WEBGLCONTEXTLOST EMSCRIPTEN_EVENT_WEBGLCONTEXTRESTORED + + EMSCRIPTEN_RESULT emscripten_set_webglcontextlost_callback( + const char *target, void *userData, EM_BOOL useCapture, em_webgl_context_callback callback) + + EMSCRIPTEN_RESULT emscripten_set_webglcontextrestored_callback( + const char *target, void *userData, EM_BOOL useCapture, em_webgl_context_callback callback) + + */ + + EM_BOOL WebAssemblyOpenGLViewport_OpenGLContextLost_callback( + int eventType, const void* reserved, void* userData) + { + ORTHANC_ASSERT(eventType == EMSCRIPTEN_EVENT_WEBGLCONTEXTLOST); + WebAssemblyOpenGLViewport* viewport = reinterpret_cast(userData); + return viewport->OpenGLContextLost(); + } + + EM_BOOL WebAssemblyOpenGLViewport_OpenGLContextRestored_callback( + int eventType, const void* reserved, void* userData) + { + ORTHANC_ASSERT(eventType == EMSCRIPTEN_EVENT_WEBGLCONTEXTRESTORED); + WebAssemblyOpenGLViewport* viewport = reinterpret_cast(userData); + return viewport->OpenGLContextRestored(); } + void WebAssemblyOpenGLViewport::RegisterContextCallbacks() + { + // TODO: what's the impact of userCapture=true ? + const char* canvasId = GetCanvasIdentifier().c_str(); + void* that = reinterpret_cast(this); + EMSCRIPTEN_RESULT status = EMSCRIPTEN_RESULT_SUCCESS; + + status = emscripten_set_webglcontextlost_callback(canvasId, that, true, WebAssemblyOpenGLViewport_OpenGLContextLost_callback); + if (status != EMSCRIPTEN_RESULT_SUCCESS) + { + std::stringstream ss; + ss << "Error while calling emscripten_set_webglcontextlost_callback for: \"" << GetCanvasIdentifier() << "\""; + std::string msg = ss.str(); + LOG(ERROR) << msg; + ORTHANC_ASSERT(false, msg.c_str()); + } + status = emscripten_set_webglcontextrestored_callback(canvasId, that, true, WebAssemblyOpenGLViewport_OpenGLContextRestored_callback); + if (status != EMSCRIPTEN_RESULT_SUCCESS) + { + std::stringstream ss; + ss << "Error while calling emscripten_set_webglcontextrestored_callback for: \"" << GetCanvasIdentifier() << "\""; + std::string msg = ss.str(); + LOG(ERROR) << msg; + ORTHANC_ASSERT(false, msg.c_str()); + } + } + + bool WebAssemblyOpenGLViewport::OpenGLContextLost() + { + LOG(ERROR) << "WebAssemblyOpenGLViewport::OpenGLContextLost() for canvas: " << GetCanvasIdentifier(); + return false; + } + + bool WebAssemblyOpenGLViewport::OpenGLContextRestored() + { + LOG(ERROR) << "WebAssemblyOpenGLViewport::OpenGLContextRestored() for canvas: " << GetCanvasIdentifier(); + return false; + } WebAssemblyCairoViewport::WebAssemblyCairoViewport(const std::string& canvas) : WebAssemblyViewport(canvas), @@ -55,16 +122,14 @@ { } - WebAssemblyCairoViewport::WebAssemblyCairoViewport(const std::string& canvas, - boost::shared_ptr& scene) : + boost::shared_ptr& scene) : WebAssemblyViewport(canvas, scene), canvas_(canvas), compositor_(GetScene(), 1024, 768) { } - void WebAssemblyCairoViewport::UpdateSize() { LOG(INFO) << "updating cairo viewport size"; @@ -84,7 +149,7 @@ unsigned int canvasHeight = 0; if (w > 0 || - h > 0) + h > 0) { canvasWidth = static_cast(boost::math::iround(w)); canvasHeight = static_cast(boost::math::iround(h)); diff -r ab90628e70d9 -r 685c9a2d115f Framework/Viewport/WebAssemblyViewport.h --- a/Framework/Viewport/WebAssemblyViewport.h Wed Jul 31 11:29:08 2019 +0200 +++ b/Framework/Viewport/WebAssemblyViewport.h Mon Aug 05 12:27:27 2019 +0200 @@ -47,7 +47,7 @@ { private: OpenGL::WebAssemblyOpenGLContext context_; - OpenGLCompositor compositor_; + std::auto_ptr compositor_; public: WebAssemblyOpenGLViewport(const std::string& canvas); @@ -60,8 +60,14 @@ virtual ICompositor& GetCompositor() { - return compositor_; + return *compositor_; } + + bool OpenGLContextLost(); + bool OpenGLContextRestored(); + + private: + void RegisterContextCallbacks(); }; class WebAssemblyCairoViewport : public WebAssemblyViewport