# HG changeset patch # User Sebastien Jodogne # Date 1600958430 -7200 # Node ID 92fca2b3ba3dc6be72972fc9d68c692cdd6c052e # Parent e4a52cbbdd70e15b2f3f78275b2805d47098aa6e sanitizing the handling of canvas size diff -r e4a52cbbdd70 -r 92fca2b3ba3d Applications/Samples/Sdl/RtViewer/RtViewerSdl.cpp --- a/Applications/Samples/Sdl/RtViewer/RtViewerSdl.cpp Wed Sep 23 17:25:25 2020 +0200 +++ b/Applications/Samples/Sdl/RtViewer/RtViewerSdl.cpp Thu Sep 24 16:40:30 2020 +0200 @@ -327,7 +327,11 @@ views, sdlEvent.window.windowID); boost::shared_ptr sdlViewport = boost::dynamic_pointer_cast(view->GetViewport()); - sdlViewport->Paint(); + + { + std::unique_ptr lock(sdlViewport->Lock()); + lock->RefreshCanvasSize(); + } } else if (sdlEvent.type == SDL_KEYDOWN && sdlEvent.key.repeat == 0 /* Ignore key bounce */) diff -r e4a52cbbdd70 -r 92fca2b3ba3d Applications/Samples/Sdl/SingleFrameViewer/SdlSimpleViewer.cpp --- a/Applications/Samples/Sdl/SingleFrameViewer/SdlSimpleViewer.cpp Wed Sep 23 17:25:25 2020 +0200 +++ b/Applications/Samples/Sdl/SingleFrameViewer/SdlSimpleViewer.cpp Thu Sep 24 16:40:30 2020 +0200 @@ -176,7 +176,8 @@ (event.window.event == SDL_WINDOWEVENT_SHOWN || event.window.event == SDL_WINDOWEVENT_EXPOSED)) { - paint = true; + std::unique_ptr lock(viewport->Lock()); + lock->RefreshCanvasSize(); } else if (event.type == SDL_KEYDOWN && event.key.repeat == 0 /* Ignore key bounce */) diff -r e4a52cbbdd70 -r 92fca2b3ba3d Applications/StoneWebViewer/WebAssembly/StoneWebViewer.cpp --- a/Applications/StoneWebViewer/WebAssembly/StoneWebViewer.cpp Wed Sep 23 17:25:25 2020 +0200 +++ b/Applications/StoneWebViewer/WebAssembly/StoneWebViewer.cpp Thu Sep 24 16:40:30 2020 +0200 @@ -1466,7 +1466,7 @@ if (fitNextContent_) { - lock->GetCompositor().RefreshCanvasSize(); + lock->RefreshCanvasSize(); lock->GetCompositor().FitContent(scene); fitNextContent_ = false; } @@ -1750,7 +1750,7 @@ void UpdateSize(bool fitContent) { std::unique_ptr lock(viewport_->Lock()); - lock->GetCompositor().RefreshCanvasSize(); + lock->RefreshCanvasSize(); if (fitContent) { diff -r e4a52cbbdd70 -r 92fca2b3ba3d OrthancStone/Sources/OpenGL/IOpenGLContext.h --- a/OrthancStone/Sources/OpenGL/IOpenGLContext.h Wed Sep 23 17:25:25 2020 +0200 +++ b/OrthancStone/Sources/OpenGL/IOpenGLContext.h Thu Sep 24 16:40:30 2020 +0200 @@ -39,15 +39,6 @@ virtual void MakeCurrent() = 0; virtual void SwapBuffer() = 0; - - virtual unsigned int GetCanvasWidth() const = 0; - - virtual unsigned int GetCanvasHeight() const = 0; - - // Getting the size of the canvas can be expensive, especially - // in WebAssembly => avoid calling this method too often - // (e.g. on each refresh) - virtual void RefreshCanvasSize() = 0; }; } } diff -r e4a52cbbdd70 -r 92fca2b3ba3d OrthancStone/Sources/OpenGL/SdlOpenGLContext.h --- a/OrthancStone/Sources/OpenGL/SdlOpenGLContext.h Wed Sep 23 17:25:25 2020 +0200 +++ b/OrthancStone/Sources/OpenGL/SdlOpenGLContext.h Thu Sep 24 16:40:30 2020 +0200 @@ -63,19 +63,14 @@ virtual void SwapBuffer() ORTHANC_OVERRIDE; - virtual unsigned int GetCanvasWidth() const ORTHANC_OVERRIDE; + unsigned int GetCanvasWidth() const; - virtual unsigned int GetCanvasHeight() const ORTHANC_OVERRIDE; + unsigned int GetCanvasHeight() const; void ToggleMaximize() { window_.ToggleMaximize(); } - - virtual void RefreshCanvasSize() ORTHANC_OVERRIDE - { - // Nothing to do for SDL - } }; } diff -r e4a52cbbdd70 -r 92fca2b3ba3d OrthancStone/Sources/OpenGL/WebAssemblyOpenGLContext.cpp --- a/OrthancStone/Sources/OpenGL/WebAssemblyOpenGLContext.cpp Wed Sep 23 17:25:25 2020 +0200 +++ b/OrthancStone/Sources/OpenGL/WebAssemblyOpenGLContext.cpp Thu Sep 24 16:40:30 2020 +0200 @@ -39,8 +39,6 @@ private: std::string canvasSelector_; EMSCRIPTEN_WEBGL_CONTEXT_HANDLE context_; - unsigned int canvasWidth_; - unsigned int canvasHeight_; bool isContextLost_; public: @@ -52,7 +50,7 @@ EmscriptenWebGLContextAttributes attr; emscripten_webgl_init_context_attributes(&attr); -#if 0 +#if 1 // The next line might be necessary to print on Firefox 71 // using WebGL. Sometimes, if set to "false" (the default // value), the canvas was rendered as a fully white or black @@ -69,8 +67,6 @@ LOG(ERROR) << message; throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError, message); } - - UpdateSize(); } void* DebugGetInternalContext() const @@ -161,46 +157,6 @@ * "explicitSwapControl" option were set to "true". **/ } - - unsigned int GetCanvasWidth() const - { - return canvasWidth_; - } - - unsigned int GetCanvasHeight() const - { - return canvasHeight_; - } - - void UpdateSize() - { - double w, h; - emscripten_get_element_css_size(canvasSelector_.c_str(), &w, &h); - - /** - * Emscripten has the function emscripten_get_element_css_size() - * to query the width and height of a named HTML element. I'm - * calling this first to get the initial size of the canvas DOM - * element, and then call emscripten_set_canvas_size() to - * initialize the framebuffer size of the canvas to the same - * size as its DOM element. - * https://floooh.github.io/2017/02/22/emsc-html.html - **/ - - if (w <= 0 || - h <= 0) - { - canvasWidth_ = 0; - canvasHeight_ = 0; - } - else - { - canvasWidth_ = static_cast(boost::math::iround(w)); - canvasHeight_ = static_cast(boost::math::iround(h)); - } - - emscripten_set_canvas_element_size(canvasSelector_.c_str(), canvasWidth_, canvasHeight_); - } }; @@ -236,40 +192,6 @@ pimpl_->SwapBuffer(); } - unsigned int WebAssemblyOpenGLContext::GetCanvasWidth() const - { - assert(pimpl_.get() != NULL); - return pimpl_->GetCanvasWidth(); - } - - unsigned int WebAssemblyOpenGLContext::GetCanvasHeight() const - { - assert(pimpl_.get() != NULL); - return pimpl_->GetCanvasHeight(); - } - - void WebAssemblyOpenGLContext::RefreshCanvasSize() - { - assert(pimpl_.get() != NULL); - - try - { - pimpl_->UpdateSize(); - } - catch (const StoneException& e) - { - // Ignore problems about the loss of the WebGL context (edge case) - if (e.GetErrorCode() == ErrorCode_WebGLContextLost) - { - return; - } - else - { - throw; - } - } - } - const std::string& WebAssemblyOpenGLContext::GetCanvasSelector() const { assert(pimpl_.get() != NULL); diff -r e4a52cbbdd70 -r 92fca2b3ba3d OrthancStone/Sources/OpenGL/WebAssemblyOpenGLContext.h --- a/OrthancStone/Sources/OpenGL/WebAssemblyOpenGLContext.h Wed Sep 23 17:25:25 2020 +0200 +++ b/OrthancStone/Sources/OpenGL/WebAssemblyOpenGLContext.h Thu Sep 24 16:40:30 2020 +0200 @@ -62,17 +62,11 @@ virtual void SwapBuffer() ORTHANC_OVERRIDE; - virtual unsigned int GetCanvasWidth() const ORTHANC_OVERRIDE; - - virtual unsigned int GetCanvasHeight() const ORTHANC_OVERRIDE; - /** Returns true if the underlying context has been successfully recreated */ //bool TryRecreate(); - virtual void RefreshCanvasSize() ORTHANC_OVERRIDE; - const std::string& GetCanvasSelector() const; diff -r e4a52cbbdd70 -r 92fca2b3ba3d OrthancStone/Sources/Scene2D/CairoCompositor.cpp --- a/OrthancStone/Sources/Scene2D/CairoCompositor.cpp Wed Sep 23 17:25:25 2020 +0200 +++ b/OrthancStone/Sources/Scene2D/CairoCompositor.cpp Thu Sep 24 16:40:30 2020 +0200 @@ -89,11 +89,11 @@ unsigned int canvasHeight) { ResetScene(); - UpdateSize(canvasWidth, canvasHeight); + canvas_.SetSize(canvasWidth, canvasHeight, false); } - void CairoCompositor::UpdateSize(unsigned int canvasWidth, - unsigned int canvasHeight) + void CairoCompositor::SetCanvasSize(unsigned int canvasWidth, + unsigned int canvasHeight) { canvas_.SetSize(canvasWidth, canvasHeight, false); } diff -r e4a52cbbdd70 -r 92fca2b3ba3d OrthancStone/Sources/Scene2D/CairoCompositor.h --- a/OrthancStone/Sources/Scene2D/CairoCompositor.h Wed Sep 23 17:25:25 2020 +0200 +++ b/OrthancStone/Sources/Scene2D/CairoCompositor.h Thu Sep 24 16:40:30 2020 +0200 @@ -59,11 +59,8 @@ return canvas_; } - virtual void RefreshCanvasSize() ORTHANC_OVERRIDE - { - // The canvas size is constant in Cairo, except if - // "UpdateSize()" is called - } + virtual void SetCanvasSize(unsigned int canvasWidth, + unsigned int canvasHeight) ORTHANC_OVERRIDE; virtual unsigned int GetCanvasWidth() const ORTHANC_OVERRIDE { @@ -92,9 +89,6 @@ helper_.reset(new Internals::CompositorHelper(*this)); } - void UpdateSize(unsigned int canvasWidth, - unsigned int canvasHeight); - Orthanc::ImageAccessor* RenderText(size_t fontIndex, const std::string& utf8) const; }; diff -r e4a52cbbdd70 -r 92fca2b3ba3d OrthancStone/Sources/Scene2D/ICompositor.h --- a/OrthancStone/Sources/Scene2D/ICompositor.h Wed Sep 23 17:25:25 2020 +0200 +++ b/OrthancStone/Sources/Scene2D/ICompositor.h Thu Sep 24 16:40:30 2020 +0200 @@ -33,8 +33,8 @@ { } - // This function can be expensive (notably in wasm) - virtual void RefreshCanvasSize() = 0; + virtual void SetCanvasSize(unsigned int canvasWidth, + unsigned int canvasHeight) = 0; virtual unsigned int GetCanvasWidth() const = 0; diff -r e4a52cbbdd70 -r 92fca2b3ba3d OrthancStone/Sources/Scene2D/Internals/OpenGLAdvancedPolylineRenderer.h --- a/OrthancStone/Sources/Scene2D/Internals/OpenGLAdvancedPolylineRenderer.h Wed Sep 23 17:25:25 2020 +0200 +++ b/OrthancStone/Sources/Scene2D/Internals/OpenGLAdvancedPolylineRenderer.h Thu Sep 24 16:40:30 2020 +0200 @@ -49,7 +49,7 @@ { if (!context_.IsContextLost()) { - program_.Apply(*data_, transform, true, true); + program_.Apply(*data_, transform, canvasWidth, canvasHeight, true, true); } } diff -r e4a52cbbdd70 -r 92fca2b3ba3d OrthancStone/Sources/Scene2D/Internals/OpenGLColorTextureProgram.cpp --- a/OrthancStone/Sources/Scene2D/Internals/OpenGLColorTextureProgram.cpp Wed Sep 23 17:25:25 2020 +0200 +++ b/OrthancStone/Sources/Scene2D/Internals/OpenGLColorTextureProgram.cpp Thu Sep 24 16:40:30 2020 +0200 @@ -45,11 +45,13 @@ void OpenGLColorTextureProgram::Apply(OpenGL::OpenGLTexture& texture, const AffineTransform2D& transform, + unsigned int canvasWidth, + unsigned int canvasHeight, bool useAlpha) { if (!context_.IsContextLost()) { - OpenGLTextureProgram::Execution execution(program_, texture, transform); + OpenGLTextureProgram::Execution execution(program_, texture, transform, canvasWidth, canvasHeight); if (useAlpha) { diff -r e4a52cbbdd70 -r 92fca2b3ba3d OrthancStone/Sources/Scene2D/Internals/OpenGLColorTextureProgram.h --- a/OrthancStone/Sources/Scene2D/Internals/OpenGLColorTextureProgram.h Wed Sep 23 17:25:25 2020 +0200 +++ b/OrthancStone/Sources/Scene2D/Internals/OpenGLColorTextureProgram.h Thu Sep 24 16:40:30 2020 +0200 @@ -38,6 +38,8 @@ void Apply(OpenGL::OpenGLTexture& texture, const AffineTransform2D& transform, + unsigned int canvasWidth, + unsigned int canvasHeight, bool useAlpha); }; } diff -r e4a52cbbdd70 -r 92fca2b3ba3d OrthancStone/Sources/Scene2D/Internals/OpenGLColorTextureRenderer.cpp --- a/OrthancStone/Sources/Scene2D/Internals/OpenGLColorTextureRenderer.cpp Wed Sep 23 17:25:25 2020 +0200 +++ b/OrthancStone/Sources/Scene2D/Internals/OpenGLColorTextureRenderer.cpp Thu Sep 24 16:40:30 2020 +0200 @@ -53,7 +53,8 @@ { if (!context_.IsContextLost() && texture_.get() != NULL) { - program_.Apply(*texture_, AffineTransform2D::Combine(transform, layerTransform_), true); + program_.Apply(*texture_, AffineTransform2D::Combine(transform, layerTransform_), + canvasWidth, canvasHeight, true); } } diff -r e4a52cbbdd70 -r 92fca2b3ba3d OrthancStone/Sources/Scene2D/Internals/OpenGLFloatTextureProgram.cpp --- a/OrthancStone/Sources/Scene2D/Internals/OpenGLFloatTextureProgram.cpp Wed Sep 23 17:25:25 2020 +0200 +++ b/OrthancStone/Sources/Scene2D/Internals/OpenGLFloatTextureProgram.cpp Thu Sep 24 16:40:30 2020 +0200 @@ -141,13 +141,16 @@ void OpenGLFloatTextureProgram::Apply(Data& data, const AffineTransform2D& transform, + unsigned int canvasWidth, + unsigned int canvasHeight, float windowCenter, float windowWidth, bool invert) { if (!context_.IsContextLost()) { - OpenGLTextureProgram::Execution execution(program_, data.GetTexture(), transform); + OpenGLTextureProgram::Execution execution( + program_, data.GetTexture(), transform, canvasWidth, canvasHeight); glUniform1f(execution.GetUniformLocation("u_slope"), data.GetSlope()); glUniform1f(execution.GetUniformLocation("u_offset"), data.GetOffset()); diff -r e4a52cbbdd70 -r 92fca2b3ba3d OrthancStone/Sources/Scene2D/Internals/OpenGLFloatTextureProgram.h --- a/OrthancStone/Sources/Scene2D/Internals/OpenGLFloatTextureProgram.h Wed Sep 23 17:25:25 2020 +0200 +++ b/OrthancStone/Sources/Scene2D/Internals/OpenGLFloatTextureProgram.h Thu Sep 24 16:40:30 2020 +0200 @@ -66,6 +66,8 @@ void Apply(Data& data, const AffineTransform2D& transform, + unsigned int canvasWidth, + unsigned int canvasHeight, float windowCenter, float windowWidth, bool invert); diff -r e4a52cbbdd70 -r 92fca2b3ba3d OrthancStone/Sources/Scene2D/Internals/OpenGLFloatTextureRenderer.cpp --- a/OrthancStone/Sources/Scene2D/Internals/OpenGLFloatTextureRenderer.cpp Wed Sep 23 17:25:25 2020 +0200 +++ b/OrthancStone/Sources/Scene2D/Internals/OpenGLFloatTextureRenderer.cpp Thu Sep 24 16:40:30 2020 +0200 @@ -67,8 +67,8 @@ { if (!context_.IsContextLost() && texture_.get() != NULL) { - program_.Apply(*texture_, AffineTransform2D::Combine(transform, layerTransform_), - windowCenter_, windowWidth_, invert_); + program_.Apply(*texture_, AffineTransform2D::Combine(transform, layerTransform_), + canvasWidth, canvasHeight, windowCenter_, windowWidth_, invert_); } } diff -r e4a52cbbdd70 -r 92fca2b3ba3d OrthancStone/Sources/Scene2D/Internals/OpenGLInfoPanelRenderer.cpp --- a/OrthancStone/Sources/Scene2D/Internals/OpenGLInfoPanelRenderer.cpp Wed Sep 23 17:25:25 2020 +0200 +++ b/OrthancStone/Sources/Scene2D/Internals/OpenGLInfoPanelRenderer.cpp Thu Sep 24 16:40:30 2020 +0200 @@ -110,7 +110,7 @@ translation1); } - program_.Apply(*texture_, actualTransform, true); + program_.Apply(*texture_, actualTransform, canvasWidth, canvasHeight, true); } } } diff -r e4a52cbbdd70 -r 92fca2b3ba3d OrthancStone/Sources/Scene2D/Internals/OpenGLLinesProgram.cpp --- a/OrthancStone/Sources/Scene2D/Internals/OpenGLLinesProgram.cpp Wed Sep 23 17:25:25 2020 +0200 +++ b/OrthancStone/Sources/Scene2D/Internals/OpenGLLinesProgram.cpp Thu Sep 24 16:40:30 2020 +0200 @@ -415,6 +415,8 @@ void OpenGLLinesProgram::Apply(const Data& data, const AffineTransform2D& transform, + unsigned int canvasWidth, + unsigned int canvasHeight, bool antialiasing, bool scaleIndependantThickness) { @@ -428,7 +430,7 @@ GLint locationColor = program_->GetAttributeLocation("a_color"); float m[16]; - transform.ConvertToOpenGLMatrix(m, context_.GetCanvasWidth(), context_.GetCanvasHeight()); + transform.ConvertToOpenGLMatrix(m, canvasWidth, canvasHeight); glUniformMatrix4fv(program_->GetUniformLocation("u_matrix"), 1, GL_FALSE, m); diff -r e4a52cbbdd70 -r 92fca2b3ba3d OrthancStone/Sources/Scene2D/Internals/OpenGLLinesProgram.h --- a/OrthancStone/Sources/Scene2D/Internals/OpenGLLinesProgram.h Wed Sep 23 17:25:25 2020 +0200 +++ b/OrthancStone/Sources/Scene2D/Internals/OpenGLLinesProgram.h Thu Sep 24 16:40:30 2020 +0200 @@ -82,6 +82,8 @@ void Apply(const Data& data, const AffineTransform2D& transform, + unsigned int canvasWidth, + unsigned int canvasHeight, bool antialiasing, bool scaleIndependantThickness); }; diff -r e4a52cbbdd70 -r 92fca2b3ba3d OrthancStone/Sources/Scene2D/Internals/OpenGLLookupTableTextureRenderer.cpp --- a/OrthancStone/Sources/Scene2D/Internals/OpenGLLookupTableTextureRenderer.cpp Wed Sep 23 17:25:25 2020 +0200 +++ b/OrthancStone/Sources/Scene2D/Internals/OpenGLLookupTableTextureRenderer.cpp Thu Sep 24 16:40:30 2020 +0200 @@ -75,7 +75,7 @@ program_.Apply( *glTexture_, AffineTransform2D::Combine(transform, layerTransform_), - true); + canvasWidth, canvasHeight, true); } } diff -r e4a52cbbdd70 -r 92fca2b3ba3d OrthancStone/Sources/Scene2D/Internals/OpenGLTextProgram.cpp --- a/OrthancStone/Sources/Scene2D/Internals/OpenGLTextProgram.cpp Wed Sep 23 17:25:25 2020 +0200 +++ b/OrthancStone/Sources/Scene2D/Internals/OpenGLTextProgram.cpp Thu Sep 24 16:40:30 2020 +0200 @@ -181,7 +181,9 @@ void OpenGLTextProgram::Apply(OpenGL::OpenGLTexture& fontTexture, const Data& data, - const AffineTransform2D& transform) + const AffineTransform2D& transform, + unsigned int canvasWidth, + unsigned int canvasHeight) { if (!context_.IsContextLost() && !data.IsEmpty()) { @@ -200,7 +202,7 @@ const AffineTransform2D t = AffineTransform2D::CreateOffset(x + dx, y + dy); float m[16]; - t.ConvertToOpenGLMatrix(m, context_.GetCanvasWidth(), context_.GetCanvasHeight()); + t.ConvertToOpenGLMatrix(m, canvasWidth, canvasHeight); fontTexture.Bind(program_->GetUniformLocation("u_texture")); glUniformMatrix4fv(program_->GetUniformLocation("u_matrix"), 1, GL_FALSE, m); diff -r e4a52cbbdd70 -r 92fca2b3ba3d OrthancStone/Sources/Scene2D/Internals/OpenGLTextProgram.h --- a/OrthancStone/Sources/Scene2D/Internals/OpenGLTextProgram.h Wed Sep 23 17:25:25 2020 +0200 +++ b/OrthancStone/Sources/Scene2D/Internals/OpenGLTextProgram.h Thu Sep 24 16:40:30 2020 +0200 @@ -131,7 +131,9 @@ void Apply(OpenGL::OpenGLTexture& fontTexture, const Data& data, - const AffineTransform2D& transform); + const AffineTransform2D& transform, + unsigned int canvasWidth, + unsigned int canvasHeight); }; } } diff -r e4a52cbbdd70 -r 92fca2b3ba3d OrthancStone/Sources/Scene2D/Internals/OpenGLTextRenderer.cpp --- a/OrthancStone/Sources/Scene2D/Internals/OpenGLTextRenderer.cpp Wed Sep 23 17:25:25 2020 +0200 +++ b/OrthancStone/Sources/Scene2D/Internals/OpenGLTextRenderer.cpp Thu Sep 24 16:40:30 2020 +0200 @@ -54,7 +54,7 @@ { if (!context_.IsContextLost() && data_.get() != NULL) { - program_.Apply(texture_, *data_, transform); + program_.Apply(texture_, *data_, transform, canvasWidth, canvasHeight); } } diff -r e4a52cbbdd70 -r 92fca2b3ba3d OrthancStone/Sources/Scene2D/Internals/OpenGLTextureProgram.cpp --- a/OrthancStone/Sources/Scene2D/Internals/OpenGLTextureProgram.cpp Wed Sep 23 17:25:25 2020 +0200 +++ b/OrthancStone/Sources/Scene2D/Internals/OpenGLTextureProgram.cpp Thu Sep 24 16:40:30 2020 +0200 @@ -45,7 +45,9 @@ namespace Internals { void OpenGLTextureProgram::InitializeExecution(OpenGL::OpenGLTexture& texture, - const AffineTransform2D& transform) + const AffineTransform2D& transform, + unsigned int canvasWidth, + unsigned int canvasHeight) { if (!context_.IsContextLost()) { @@ -58,7 +60,7 @@ AffineTransform2D t = AffineTransform2D::Combine(transform, scale); float m[16]; - t.ConvertToOpenGLMatrix(m, context_.GetCanvasWidth(), context_.GetCanvasHeight()); + t.ConvertToOpenGLMatrix(m, canvasWidth, canvasHeight); texture.Bind(program_->GetUniformLocation("u_texture")); glUniformMatrix4fv(program_->GetUniformLocation("u_matrix"), 1, GL_FALSE, m); diff -r e4a52cbbdd70 -r 92fca2b3ba3d OrthancStone/Sources/Scene2D/Internals/OpenGLTextureProgram.h --- a/OrthancStone/Sources/Scene2D/Internals/OpenGLTextureProgram.h Wed Sep 23 17:25:25 2020 +0200 +++ b/OrthancStone/Sources/Scene2D/Internals/OpenGLTextureProgram.h Thu Sep 24 16:40:30 2020 +0200 @@ -42,7 +42,9 @@ GLuint buffers_[2]; void InitializeExecution(OpenGL::OpenGLTexture& texture, - const AffineTransform2D& transform); + const AffineTransform2D& transform, + unsigned int canvasWidth, + unsigned int canvasHeight); void FinalizeExecution(); @@ -60,10 +62,12 @@ public: Execution(OpenGLTextureProgram& that, OpenGL::OpenGLTexture& texture, - const AffineTransform2D& transform) : + const AffineTransform2D& transform, + unsigned int canvasWidth, + unsigned int canvasHeight) : that_(that) { - that_.InitializeExecution(texture, transform); + that_.InitializeExecution(texture, transform, canvasWidth, canvasHeight); } ~Execution() diff -r e4a52cbbdd70 -r 92fca2b3ba3d OrthancStone/Sources/Scene2D/OpenGLCompositor.cpp --- a/OrthancStone/Sources/Scene2D/OpenGLCompositor.cpp Wed Sep 23 17:25:25 2020 +0200 +++ b/OrthancStone/Sources/Scene2D/OpenGLCompositor.cpp Thu Sep 24 16:40:30 2020 +0200 @@ -137,12 +137,6 @@ canvasWidth_(0), canvasHeight_(0) { - if (!context_.IsContextLost()) - { - canvasWidth_ = context_.GetCanvasWidth(); - canvasHeight_ = context_.GetCanvasHeight(); - } - ResetScene(); } @@ -187,8 +181,6 @@ if (!context_.IsContextLost()) { context_.MakeCurrent(); // this can throw if context lost! - canvasWidth_ = context_.GetCanvasWidth(); - canvasHeight_ = context_.GetCanvasHeight(); glViewport(0, 0, canvasWidth_, canvasHeight_); glClearColor(0, 0, 0, 1); @@ -245,14 +237,10 @@ #endif - void OpenGLCompositor::RefreshCanvasSize() + void OpenGLCompositor::SetCanvasSize(unsigned int canvasWidth, + unsigned int canvasHeight) { - if (!context_.IsContextLost()) - { - context_.MakeCurrent(); // this can throw if context lost! - context_.RefreshCanvasSize(); // Difference with Refresh(scene) - canvasWidth_ = context_.GetCanvasWidth(); - canvasHeight_ = context_.GetCanvasHeight(); - } + canvasWidth_ = canvasWidth; + canvasHeight_ = canvasHeight; } } diff -r e4a52cbbdd70 -r 92fca2b3ba3d OrthancStone/Sources/Scene2D/OpenGLCompositor.h --- a/OrthancStone/Sources/Scene2D/OpenGLCompositor.h Wed Sep 23 17:25:25 2020 +0200 +++ b/OrthancStone/Sources/Scene2D/OpenGLCompositor.h Thu Sep 24 16:40:30 2020 +0200 @@ -72,7 +72,8 @@ Orthanc::Encoding codepage) ORTHANC_OVERRIDE; #endif - virtual void RefreshCanvasSize() ORTHANC_OVERRIDE; + virtual void SetCanvasSize(unsigned int canvasWidth, + unsigned int canvasHeight) ORTHANC_OVERRIDE; virtual unsigned int GetCanvasWidth() const ORTHANC_OVERRIDE { diff -r e4a52cbbdd70 -r 92fca2b3ba3d OrthancStone/Sources/Scene2DViewport/CreateLineMeasureTracker.cpp --- a/OrthancStone/Sources/Scene2DViewport/CreateLineMeasureTracker.cpp Wed Sep 23 17:25:25 2020 +0200 +++ b/OrthancStone/Sources/Scene2DViewport/CreateLineMeasureTracker.cpp Thu Sep 24 16:40:30 2020 +0200 @@ -64,9 +64,10 @@ //LOG(TRACE) << "scenePos.GetX() = " << scenePos.GetX() << " " << // "scenePos.GetY() = " << scenePos.GetY(); - CreateLineMeasureTracker* concreteThis = + /*CreateLineMeasureTracker* concreteThis = dynamic_cast(this); - assert(concreteThis != NULL); + assert(concreteThis != NULL);*/ + GetCommand()->SetEnd(scenePos); } diff -r e4a52cbbdd70 -r 92fca2b3ba3d OrthancStone/Sources/Scene2DViewport/MeasureTool.cpp --- a/OrthancStone/Sources/Scene2DViewport/MeasureTool.cpp Wed Sep 23 17:25:25 2020 +0200 +++ b/OrthancStone/Sources/Scene2DViewport/MeasureTool.cpp Thu Sep 24 16:40:30 2020 +0200 @@ -47,12 +47,10 @@ return enabled_; } - MeasureTool::MeasureTool( - boost::shared_ptr viewport) - : viewport_(viewport) - , enabled_(true) + MeasureTool::MeasureTool(boost::shared_ptr viewport) : + enabled_(true), + viewport_(viewport) { - } void MeasureTool::PostConstructor() @@ -78,7 +76,4 @@ { RefreshScene(); } - - } - diff -r e4a52cbbdd70 -r 92fca2b3ba3d OrthancStone/Sources/Scene2DViewport/MeasureTool.h --- a/OrthancStone/Sources/Scene2DViewport/MeasureTool.h Wed Sep 23 17:25:25 2020 +0200 +++ b/OrthancStone/Sources/Scene2DViewport/MeasureTool.h Thu Sep 24 16:40:30 2020 +0200 @@ -43,6 +43,39 @@ private: bool enabled_; + + protected: + explicit MeasureTool(boost::shared_ptr viewport); + + void PostConstructor(); + + /** + The measuring tool may exist in a standalone fashion, without any available + scene (because the controller is dead or dying). This call allows to check + before accessing the scene. + */ + bool IsSceneAlive() const; + + /** + This is the meat of the tool: this method must [create (if needed) and] + update the layers and their data according to the measure tool kind and + current state. This is repeatedly called during user interaction + */ + virtual void RefreshScene() = 0; + + /** + enabled_ is not accessible by subclasses because there is a state machine + that we do not wanna mess with + */ + bool IsEnabled() const; + + /** + Protected to allow sub-classes to use this weak pointer in factory methods + (pass them to created objects) + */ + boost::shared_ptr viewport_; + + public: virtual ~MeasureTool() { @@ -114,37 +147,6 @@ A description of the measuring tool, useful in debug logs */ virtual std::string GetDescription() = 0; - - protected: - explicit MeasureTool(boost::shared_ptr viewport); - - void PostConstructor(); - - /** - The measuring tool may exist in a standalone fashion, without any available - scene (because the controller is dead or dying). This call allows to check - before accessing the scene. - */ - bool IsSceneAlive() const; - - /** - This is the meat of the tool: this method must [create (if needed) and] - update the layers and their data according to the measure tool kind and - current state. This is repeatedly called during user interaction - */ - virtual void RefreshScene() = 0; - - /** - enabled_ is not accessible by subclasses because there is a state machine - that we do not wanna mess with - */ - bool IsEnabled() const; - - /** - Protected to allow sub-classes to use this weak pointer in factory methods - (pass them to created objects) - */ - boost::shared_ptr viewport_; }; class MeasureToolMemento diff -r e4a52cbbdd70 -r 92fca2b3ba3d OrthancStone/Sources/Viewport/IViewport.h --- a/OrthancStone/Sources/Viewport/IViewport.h Wed Sep 23 17:25:25 2020 +0200 +++ b/OrthancStone/Sources/Viewport/IViewport.h Thu Sep 24 16:40:30 2020 +0200 @@ -62,6 +62,14 @@ virtual ViewportController& GetController() = 0; virtual void Invalidate() = 0; + + + /** + * This function must be called when the layout has changed, and + * thus the size of the canvas must be re-computed. Avoid + * calling this method too often for performance. + **/ + virtual void RefreshCanvasSize() = 0; }; virtual ~IViewport() diff -r e4a52cbbdd70 -r 92fca2b3ba3d OrthancStone/Sources/Viewport/SdlViewport.cpp --- a/OrthancStone/Sources/Viewport/SdlViewport.cpp Wed Sep 23 17:25:25 2020 +0200 +++ b/OrthancStone/Sources/Viewport/SdlViewport.cpp Thu Sep 24 16:40:30 2020 +0200 @@ -52,6 +52,7 @@ compositor_.reset(compositor); } + SdlViewport::SdlViewport() { refreshEvent_ = SDL_RegisterEvents(1); @@ -76,6 +77,14 @@ } + void SdlViewport::UpdateSize(unsigned int width, unsigned int height) + { + SdlLock lock(*this); + lock.GetCompositor().SetCanvasSize(width, height); + lock.Invalidate(); + } + + SdlOpenGLViewport::SdlOpenGLViewport(const std::string& title, unsigned int width, unsigned int height, @@ -85,6 +94,13 @@ AcquireCompositor(new OpenGLCompositor(context_)); // (*) } + + void SdlOpenGLViewport::RefreshCanvasSize() + { + UpdateSize(context_.GetCanvasWidth(), context_.GetCanvasHeight()); + } + + boost::shared_ptr SdlOpenGLViewport::Create( const std::string& title, unsigned int width, @@ -120,14 +136,6 @@ } - void SdlOpenGLViewport::UpdateSize(unsigned int width, unsigned int height) - { - // nothing to do in OpenGL, the OpenGLCompositor::UpdateSize will be called automatically - SdlLock lock(*this); - lock.Invalidate(); - } - - void SdlOpenGLViewport::ToggleMaximize() { // No need to call "Invalidate()" here, as "UpdateSize()" will @@ -138,6 +146,11 @@ + void SdlCairoViewport::RefreshCanvasSize() + { + UpdateSize(window_.GetWidth(), window_.GetHeight()); + } + SdlCairoViewport::SdlCairoViewport(const char* title, unsigned int width, unsigned int height, @@ -177,15 +190,6 @@ } - void SdlCairoViewport::UpdateSize(unsigned int width, - unsigned int height) - { - SdlLock lock(*this); - dynamic_cast(lock.GetCompositor()).UpdateSize(width, height); - lock.Invalidate(); - } - - void SdlCairoViewport::ToggleMaximize() { // No need to call "Invalidate()" here, as "UpdateSize()" will diff -r e4a52cbbdd70 -r 92fca2b3ba3d OrthancStone/Sources/Viewport/SdlViewport.h --- a/OrthancStone/Sources/Viewport/SdlViewport.h Wed Sep 23 17:25:25 2020 +0200 +++ b/OrthancStone/Sources/Viewport/SdlViewport.h Thu Sep 24 16:40:30 2020 +0200 @@ -95,6 +95,11 @@ { that_.SendRefreshEvent(); } + + virtual void RefreshCanvasSize() ORTHANC_OVERRIDE + { + that_.RefreshCanvasSize(); + } }; void ClearCompositor() @@ -104,12 +109,14 @@ void AcquireCompositor(ICompositor* compositor /* takes ownership */); + virtual void RefreshCanvasSize() = 0; + protected: SdlViewport(); + void PostConstructor(); public: - bool IsRefreshEvent(const SDL_Event& event) const { return (event.type == refreshEvent_); @@ -122,8 +129,8 @@ virtual uint32_t GetSdlWindowId() = 0; - virtual void UpdateSize(unsigned int width, - unsigned int height) = 0; + void UpdateSize(unsigned int width, + unsigned int height); virtual void ToggleMaximize() = 0; @@ -137,11 +144,14 @@ private: SdlOpenGLContext context_; - private: SdlOpenGLViewport(const std::string& title, unsigned int width, unsigned int height, bool allowDpiScaling = true); + + protected: + virtual void RefreshCanvasSize() ORTHANC_OVERRIDE; + public: static boost::shared_ptr Create(const std::string&, unsigned int width, @@ -155,9 +165,6 @@ virtual void Paint() ORTHANC_OVERRIDE; - virtual void UpdateSize(unsigned int width, - unsigned int height) ORTHANC_OVERRIDE; - virtual void ToggleMaximize() ORTHANC_OVERRIDE; }; @@ -170,11 +177,14 @@ void CreateSdlSurfaceFromCompositor(const CairoCompositor& compositor); - private: SdlCairoViewport(const char* title, unsigned int width, unsigned int height, bool allowDpiScaling = true); + + protected: + virtual void RefreshCanvasSize() ORTHANC_OVERRIDE; + public: static boost::shared_ptr Create(const char* title, unsigned int width, @@ -188,9 +198,6 @@ virtual void Paint() ORTHANC_OVERRIDE; - virtual void UpdateSize(unsigned int width, - unsigned int height) ORTHANC_OVERRIDE; - virtual void ToggleMaximize() ORTHANC_OVERRIDE; }; } diff -r e4a52cbbdd70 -r 92fca2b3ba3d OrthancStone/Sources/Viewport/WebAssemblyCairoViewport.cpp --- a/OrthancStone/Sources/Viewport/WebAssemblyCairoViewport.cpp Wed Sep 23 17:25:25 2020 +0200 +++ b/OrthancStone/Sources/Viewport/WebAssemblyCairoViewport.cpp Thu Sep 24 16:40:30 2020 +0200 @@ -34,39 +34,8 @@ #include -#include - namespace OrthancStone { - void WebAssemblyCairoViewport::GetCanvasSize(unsigned int& width, - unsigned int& height) - { - double w, h; - emscripten_get_element_css_size(GetCanvasCssSelector().c_str(), &w, &h); - - /** - * Emscripten has the function emscripten_get_element_css_size() - * to query the width and height of a named HTML element. I'm - * calling this first to get the initial size of the canvas DOM - * element, and then call emscripten_set_canvas_size() to - * initialize the framebuffer size of the canvas to the same - * size as its DOM element. - * https://floooh.github.io/2017/02/22/emsc-html.html - **/ - if (w > 0 && - h > 0) - { - width = static_cast(boost::math::iround(w)); - height = static_cast(boost::math::iround(h)); - } - else - { - width = 0; - height = 0; - } - } - - void WebAssemblyCairoViewport::Paint(ICompositor& compositor, ViewportController& controller) { @@ -123,25 +92,12 @@ } - void WebAssemblyCairoViewport::UpdateSize(ICompositor& compositor) - { - unsigned int width, height; - GetCanvasSize(width, height); - emscripten_set_canvas_element_size(GetCanvasCssSelector().c_str(), width, height); - - dynamic_cast(compositor).UpdateSize(width, height); - } - - WebAssemblyCairoViewport::WebAssemblyCairoViewport(const std::string& canvasId, bool enableEmscriptenMouseEvents) : WebAssemblyViewport(canvasId,enableEmscriptenMouseEvents) { - unsigned int width, height; - GetCanvasSize(width, height); - emscripten_set_canvas_element_size(GetCanvasCssSelector().c_str(), width, height); - - AcquireCompositor(new CairoCompositor(width, height)); + RefreshCanvasSize(); + AcquireCompositor(new CairoCompositor(GetCanvasWidth(), GetCanvasHeight())); } diff -r e4a52cbbdd70 -r 92fca2b3ba3d OrthancStone/Sources/Viewport/WebAssemblyCairoViewport.h --- a/OrthancStone/Sources/Viewport/WebAssemblyCairoViewport.h Wed Sep 23 17:25:25 2020 +0200 +++ b/OrthancStone/Sources/Viewport/WebAssemblyCairoViewport.h Thu Sep 24 16:40:30 2020 +0200 @@ -30,9 +30,6 @@ private: std::unique_ptr javascript_; - void GetCanvasSize(unsigned int& width, - unsigned int& height); - WebAssemblyCairoViewport(const std::string& canvasId, bool enableEmscriptenMouseEvents); @@ -40,8 +37,6 @@ virtual void Paint(ICompositor& compositor, ViewportController& controller) ORTHANC_OVERRIDE; - virtual void UpdateSize(ICompositor& compositor) ORTHANC_OVERRIDE; - public: static boost::shared_ptr Create(const std::string& canvasId, bool enableEmscriptenMouseEvents = true); diff -r e4a52cbbdd70 -r 92fca2b3ba3d OrthancStone/Sources/Viewport/WebAssemblyViewport.cpp --- a/OrthancStone/Sources/Viewport/WebAssemblyViewport.cpp Wed Sep 23 17:25:25 2020 +0200 +++ b/OrthancStone/Sources/Viewport/WebAssemblyViewport.cpp Thu Sep 24 16:40:30 2020 +0200 @@ -38,6 +38,7 @@ #include #include +#include namespace OrthancStone { @@ -112,6 +113,11 @@ { that_.Invalidate(); } + + virtual void RefreshCanvasSize() ORTHANC_OVERRIDE + { + that_.RefreshCanvasSize(); + } }; @@ -137,7 +143,7 @@ if (that->compositor_.get() != NULL) { - that->UpdateSize(*that->compositor_); + that->RefreshCanvasSize(); that->Invalidate(); } @@ -215,7 +221,7 @@ if (compositor_.get() != NULL && controller_ /* should always be true */) { - UpdateSize(*compositor_); + RefreshCanvasSize(); compositor_->FitContent(controller_->GetScene()); OnRequestAnimationFrame(0, reinterpret_cast(this)); } @@ -248,7 +254,9 @@ canvasCssSelector_(canvasId), #endif interactor_(new DefaultViewportInteractor), - enableEmscriptenMouseEvents_(enableEmscriptenMouseEvents) + enableEmscriptenMouseEvents_(enableEmscriptenMouseEvents), + canvasWidth_(0), + canvasHeight_(0) { } @@ -312,7 +320,7 @@ void WebAssemblyViewport::UpdateCanvasSize() { - UpdateSize(*compositor_); + RefreshCanvasSize(); } WebAssemblyViewport::~WebAssemblyViewport() @@ -358,4 +366,39 @@ interactor_.reset(interactor); } } + + + void WebAssemblyViewport::RefreshCanvasSize() + { + double w, h; + emscripten_get_element_css_size(GetCanvasCssSelector().c_str(), &w, &h); + + /** + * Emscripten has the function emscripten_get_element_css_size() + * to query the width and height of a named HTML element. I'm + * calling this first to get the initial size of the canvas DOM + * element, and then call emscripten_set_canvas_size() to + * initialize the framebuffer size of the canvas to the same + * size as its DOM element. + * https://floooh.github.io/2017/02/22/emsc-html.html + **/ + if (w > 0 && + h > 0) + { + canvasWidth_ = static_cast(boost::math::iround(w)); + canvasHeight_ = static_cast(boost::math::iround(h)); + } + else + { + canvasWidth_ = 0; + canvasHeight_ = 0; + } + + emscripten_set_canvas_element_size(GetCanvasCssSelector().c_str(), canvasWidth_, canvasHeight_); + + if (compositor_.get() != NULL) + { + compositor_->SetCanvasSize(canvasWidth_, canvasHeight_); + } + } } diff -r e4a52cbbdd70 -r 92fca2b3ba3d OrthancStone/Sources/Viewport/WebAssemblyViewport.h --- a/OrthancStone/Sources/Viewport/WebAssemblyViewport.h Wed Sep 23 17:25:25 2020 +0200 +++ b/OrthancStone/Sources/Viewport/WebAssemblyViewport.h Thu Sep 24 16:40:30 2020 +0200 @@ -58,6 +58,8 @@ std::unique_ptr controller_; std::unique_ptr interactor_; bool enableEmscriptenMouseEvents_; + unsigned int canvasWidth_; + unsigned int canvasHeight_; static EM_BOOL OnRequestAnimationFrame(double time, void *userData); @@ -87,8 +89,6 @@ virtual void Paint(ICompositor& compositor, ViewportController& controller) = 0; - virtual void UpdateSize(ICompositor& compositor) = 0; - /** The second argument is temporary and should be deleted once the migration to interactors is finished. It should be set to "true" for new applications. @@ -124,6 +124,19 @@ return canvasCssSelector_; } + + void RefreshCanvasSize(); + + unsigned int GetCanvasWidth() const + { + return canvasWidth_; + } + + unsigned int GetCanvasHeight() + { + return canvasHeight_; + } + void FitForPrint(); // TODO - REMOVE }; } diff -r e4a52cbbdd70 -r 92fca2b3ba3d OrthancStone/Sources/Viewport/WebGLViewport.h --- a/OrthancStone/Sources/Viewport/WebGLViewport.h Wed Sep 23 17:25:25 2020 +0200 +++ b/OrthancStone/Sources/Viewport/WebGLViewport.h Thu Sep 24 16:40:30 2020 +0200 @@ -38,11 +38,6 @@ virtual void Paint(ICompositor& compositor, ViewportController& controller) ORTHANC_OVERRIDE; - virtual void UpdateSize(ICompositor& compositor) ORTHANC_OVERRIDE - { - context_.RefreshCanvasSize(); - } - public: static boost::shared_ptr Create(const std::string& canvasId, bool enableEmscriptenMouseEvents = true);