# HG changeset patch # User Sebastien Jodogne # Date 1575474441 -3600 # Node ID d10d2acb8a02bbc9b9a7ee8a6513026ad2499270 # Parent 644baa70373d6ff0030a89df8090fedf2a0e35df compositors do not keep a reference to the scene anymore diff -r 644baa70373d -r d10d2acb8a02 Framework/Scene2D/CairoCompositor.cpp --- a/Framework/Scene2D/CairoCompositor.cpp Wed Dec 04 16:13:10 2019 +0100 +++ b/Framework/Scene2D/CairoCompositor.cpp Wed Dec 04 16:47:21 2019 +0100 @@ -85,11 +85,10 @@ } - CairoCompositor::CairoCompositor(const Scene2D& scene, - unsigned int canvasWidth, - unsigned int canvasHeight) : - helper_(scene, *this) + CairoCompositor::CairoCompositor(unsigned int canvasWidth, + unsigned int canvasHeight) { + ResetScene(); UpdateSize(canvasWidth, canvasHeight); } @@ -154,7 +153,7 @@ #endif - void CairoCompositor::Refresh() + void CairoCompositor::Refresh(const Scene2D& scene) { context_.reset(new CairoContext(canvas_)); @@ -162,7 +161,7 @@ cairo_set_source_rgba(context_->GetObject(), 0, 0, 0, 255); cairo_paint(context_->GetObject()); - helper_.Refresh(canvas_.GetWidth(), canvas_.GetHeight()); + helper_->Refresh(scene, canvas_.GetWidth(), canvas_.GetHeight()); context_.reset(); } diff -r 644baa70373d -r d10d2acb8a02 Framework/Scene2D/CairoCompositor.h --- a/Framework/Scene2D/CairoCompositor.h Wed Dec 04 16:13:10 2019 +0100 +++ b/Framework/Scene2D/CairoCompositor.h Wed Dec 04 16:47:21 2019 +0100 @@ -37,7 +37,7 @@ private: typedef std::map Fonts; - Internals::CompositorHelper helper_; + std::auto_ptr helper_; CairoSurface canvas_; Fonts fonts_; @@ -49,8 +49,7 @@ virtual Internals::CompositorHelper::ILayerRenderer* Create(const ISceneLayer& layer) ORTHANC_OVERRIDE; public: - CairoCompositor(const Scene2D& scene, - unsigned int canvasWidth, + CairoCompositor(unsigned int canvasWidth, unsigned int canvasHeight); virtual ~CairoCompositor(); @@ -80,7 +79,12 @@ Orthanc::Encoding codepage) ORTHANC_OVERRIDE; #endif - virtual void Refresh() ORTHANC_OVERRIDE; + virtual void Refresh(const Scene2D& scene) ORTHANC_OVERRIDE; + + virtual void ResetScene() ORTHANC_OVERRIDE + { + helper_.reset(new Internals::CompositorHelper(*this)); + } void UpdateSize(unsigned int canvasWidth, unsigned int canvasHeight); diff -r 644baa70373d -r d10d2acb8a02 Framework/Scene2D/ICompositor.h --- a/Framework/Scene2D/ICompositor.h Wed Dec 04 16:13:10 2019 +0100 +++ b/Framework/Scene2D/ICompositor.h Wed Dec 04 16:47:21 2019 +0100 @@ -1,8 +1,8 @@ #pragma once -#include +#include "Scene2D.h" + #include -#include namespace OrthancStone { @@ -17,7 +17,14 @@ virtual unsigned int GetCanvasHeight() const = 0; - virtual void Refresh() = 0; + /** + * WARNING: "Refresh()" must always be called with the same + * scene. If the scene changes, a call to "ResetScene()" must be + * done to reset the tracking of the revisions of the layers. + **/ + virtual void Refresh(const Scene2D& scene) = 0; + + virtual void ResetScene() = 0; #if ORTHANC_ENABLE_LOCALE == 1 virtual void SetFont(size_t index, diff -r 644baa70373d -r d10d2acb8a02 Framework/Scene2D/Internals/CompositorHelper.cpp --- a/Framework/Scene2D/Internals/CompositorHelper.cpp Wed Dec 04 16:13:10 2019 +0100 +++ b/Framework/Scene2D/Internals/CompositorHelper.cpp Wed Dec 04 16:47:21 2019 +0100 @@ -80,12 +80,13 @@ }; - void CompositorHelper::Visit(const ISceneLayer& layer, + void CompositorHelper::Visit(const Scene2D& scene, + const ISceneLayer& layer, uint64_t layerIdentifier, int depth) { // "Visit()" is only applied to layers existing in the scene - assert(scene_.HasLayer(depth)); + assert(scene.HasLayer(depth)); Content::iterator found = content_.find(depth); @@ -141,18 +142,34 @@ } - void CompositorHelper::Refresh(unsigned int canvasWidth, + void CompositorHelper::Refresh(const Scene2D& scene, + unsigned int canvasWidth, unsigned int canvasHeight) { + /** + * Safeguard mechanism to enforce the fact that the same scene + * is always used with the compositor. Note that the safeguard + * is not 100% bullet-proof, as a new scene might reuse the same + * address as a previous scene. + **/ + if (lastScene_ != NULL && + lastScene_ != &scene) + { + throw Orthanc::OrthancException(Orthanc::ErrorCode_BadSequenceOfCalls, + "ICompositor::ResetScene() should have been called"); + } + + lastScene_ = &scene; + // Bring coordinate (0,0) to the center of the canvas AffineTransform2D offset = AffineTransform2D::CreateOffset( static_cast(canvasWidth) / 2.0, static_cast(canvasHeight) / 2.0); - sceneTransform_ = AffineTransform2D::Combine(offset, scene_.GetSceneToCanvasTransform()); + sceneTransform_ = AffineTransform2D::Combine(offset, scene.GetSceneToCanvasTransform()); canvasWidth_ = canvasWidth; canvasHeight_ = canvasHeight; - scene_.Apply(*this); + scene.Apply(*this); } } } diff -r 644baa70373d -r d10d2acb8a02 Framework/Scene2D/Internals/CompositorHelper.h --- a/Framework/Scene2D/Internals/CompositorHelper.h Wed Dec 04 16:13:10 2019 +0100 +++ b/Framework/Scene2D/Internals/CompositorHelper.h Wed Dec 04 16:47:21 2019 +0100 @@ -64,9 +64,9 @@ typedef std::map Content; - const Scene2D& scene_; IRendererFactory& factory_; Content content_; + const Scene2D* lastScene_; // This is only a safeguard, don't use it! // Only valid during a call to Refresh() AffineTransform2D sceneTransform_; @@ -74,21 +74,22 @@ unsigned int canvasHeight_; protected: - virtual void Visit(const ISceneLayer& layer, + virtual void Visit(const Scene2D& scene, + const ISceneLayer& layer, uint64_t layerIdentifier, int depth); public: - CompositorHelper(const Scene2D& scene, - IRendererFactory& factory) : - scene_(scene), - factory_(factory) + CompositorHelper(IRendererFactory& factory) : + factory_(factory), + lastScene_(NULL) { } ~CompositorHelper(); - void Refresh(unsigned int canvasWidth, + void Refresh(const Scene2D& scene, + unsigned int canvasWidth, unsigned int canvasHeight); }; } diff -r 644baa70373d -r d10d2acb8a02 Framework/Scene2D/OpenGLCompositor.cpp --- a/Framework/Scene2D/OpenGLCompositor.cpp Wed Dec 04 16:13:10 2019 +0100 +++ b/Framework/Scene2D/OpenGLCompositor.cpp Wed Dec 04 16:47:21 2019 +0100 @@ -128,10 +128,8 @@ } } - OpenGLCompositor::OpenGLCompositor(OpenGL::IOpenGLContext& context, - const Scene2D& scene) : + OpenGLCompositor::OpenGLCompositor(OpenGL::IOpenGLContext& context) : context_(context), - helper_(scene, *this), colorTextureProgram_(context), floatTextureProgram_(context), linesProgram_(context), @@ -139,6 +137,7 @@ canvasWidth_(0), canvasHeight_(0) { + ResetScene(); } OpenGLCompositor::~OpenGLCompositor() @@ -154,7 +153,7 @@ } } - void OpenGLCompositor::Refresh() + void OpenGLCompositor::Refresh(const Scene2D& scene) { if (!context_.IsContextLost()) { @@ -167,11 +166,10 @@ glClearColor(0, 0, 0, 1); glClear(GL_COLOR_BUFFER_BIT); - helper_.Refresh(canvasWidth_, canvasHeight_); + helper_->Refresh(scene, canvasWidth_, canvasHeight_); context_.SwapBuffer(); } - } void OpenGLCompositor::SetFont(size_t index, diff -r 644baa70373d -r d10d2acb8a02 Framework/Scene2D/OpenGLCompositor.h --- a/Framework/Scene2D/OpenGLCompositor.h Wed Dec 04 16:13:10 2019 +0100 +++ b/Framework/Scene2D/OpenGLCompositor.h Wed Dec 04 16:47:21 2019 +0100 @@ -37,27 +37,31 @@ typedef std::map Fonts; - OpenGL::IOpenGLContext& context_; - Fonts fonts_; - Internals::CompositorHelper helper_; - Internals::OpenGLColorTextureProgram colorTextureProgram_; - Internals::OpenGLFloatTextureProgram floatTextureProgram_; - Internals::OpenGLLinesProgram linesProgram_; - Internals::OpenGLTextProgram textProgram_; - unsigned int canvasWidth_; - unsigned int canvasHeight_; + OpenGL::IOpenGLContext& context_; + Fonts fonts_; + std::auto_ptr helper_; + Internals::OpenGLColorTextureProgram colorTextureProgram_; + Internals::OpenGLFloatTextureProgram floatTextureProgram_; + Internals::OpenGLLinesProgram linesProgram_; + Internals::OpenGLTextProgram textProgram_; + unsigned int canvasWidth_; + unsigned int canvasHeight_; const Font* GetFont(size_t fontIndex) const; virtual Internals::CompositorHelper::ILayerRenderer* Create(const ISceneLayer& layer) ORTHANC_OVERRIDE; public: - OpenGLCompositor(OpenGL::IOpenGLContext& context, - const Scene2D& scene); + OpenGLCompositor(OpenGL::IOpenGLContext& context); virtual ~OpenGLCompositor(); - virtual void Refresh() ORTHANC_OVERRIDE; + virtual void Refresh(const Scene2D& scene) ORTHANC_OVERRIDE; + + virtual void ResetScene() ORTHANC_OVERRIDE + { + helper_.reset(new Internals::CompositorHelper(*this)); + } void SetFont(size_t index, const GlyphBitmapAlphabet& dict); diff -r 644baa70373d -r d10d2acb8a02 Framework/Scene2D/Scene2D.cpp --- a/Framework/Scene2D/Scene2D.cpp Wed Dec 04 16:13:10 2019 +0100 +++ b/Framework/Scene2D/Scene2D.cpp Wed Dec 04 16:47:21 2019 +0100 @@ -208,7 +208,7 @@ it != content_.end(); ++it) { assert(it->second != NULL); - visitor.Visit(it->second->GetLayer(), it->second->GetIdentifier(), it->first); + visitor.Visit(*this, it->second->GetLayer(), it->second->GetIdentifier(), it->first); } } diff -r 644baa70373d -r d10d2acb8a02 Framework/Scene2D/Scene2D.h --- a/Framework/Scene2D/Scene2D.h Wed Dec 04 16:13:10 2019 +0100 +++ b/Framework/Scene2D/Scene2D.h Wed Dec 04 16:47:21 2019 +0100 @@ -40,7 +40,8 @@ { } - virtual void Visit(const ISceneLayer& layer, + virtual void Visit(const Scene2D& scene, + const ISceneLayer& layer, uint64_t layerIdentifier, int depth) = 0; }; diff -r 644baa70373d -r d10d2acb8a02 Framework/Viewport/SdlViewport.cpp --- a/Framework/Viewport/SdlViewport.cpp Wed Dec 04 16:13:10 2019 +0100 +++ b/Framework/Viewport/SdlViewport.cpp Wed Dec 04 16:47:21 2019 +0100 @@ -50,7 +50,7 @@ bool allowDpiScaling) : context_(title, width, height, allowDpiScaling) { - compositor_.reset(new OpenGLCompositor(context_, GetScene())); + compositor_.reset(new OpenGLCompositor(context_)); } void SdlOpenGLViewport::Invalidate() @@ -61,7 +61,7 @@ void SdlOpenGLViewport::Paint() { boost::mutex::scoped_lock lock(mutex_); - compositor_->Refresh(); + compositor_->Refresh(GetScene()); } @@ -70,7 +70,7 @@ unsigned int height, bool allowDpiScaling) : window_(title, width, height, false /* enable OpenGL */, allowDpiScaling), - compositor_(GetScene(), width, height), + compositor_(width, height), sdlSurface_(NULL) { } @@ -85,7 +85,7 @@ void SdlCairoViewport::InvalidateInternal() // Assumes that the mutex is locked { - compositor_.Refresh(); + compositor_.Refresh(GetScene()); CreateSdlSurfaceFromCompositor(); }