changeset 905:88bf49aebc13

introduced ICompositor and allow SdlViewport to work with a CairoCompositor (to run on machines without OpenGL drivers)
author Alain Mazy <alain@mazy.be>
date Wed, 17 Jul 2019 16:56:53 +0200
parents ecdb2ceaa925
children 52b1c6ff10c5 722ee73e6ba2
files Framework/Scene2D/CairoCompositor.h Framework/Scene2D/ICompositor.h Framework/Scene2D/OpenGLCompositor.h Framework/Viewport/IViewport.h Framework/Viewport/SdlViewport.cpp Framework/Viewport/SdlViewport.h Framework/Viewport/ViewportBase.h Framework/Viewport/WebAssemblyViewport.h Resources/CMake/OrthancStoneConfiguration.cmake Samples/Sdl/BasicScene.cpp
diffstat 10 files changed, 253 insertions(+), 75 deletions(-) [+]
line wrap: on
line diff
--- a/Framework/Scene2D/CairoCompositor.h	Wed Jul 17 15:33:34 2019 +0200
+++ b/Framework/Scene2D/CairoCompositor.h	Wed Jul 17 16:56:53 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 <http://www.gnu.org/licenses/>.
  **/
@@ -21,6 +21,7 @@
 
 #pragma once
 
+#include "ICompositor.h"
 #include "../Fonts/GlyphBitmapAlphabet.h"
 #include "../Wrappers/CairoContext.h"
 #include "Internals/CompositorHelper.h"
@@ -29,8 +30,9 @@
 namespace OrthancStone
 {
   class CairoCompositor :
-    private Internals::CompositorHelper::IRendererFactory,
-    private Internals::ICairoContextProvider
+      public ICompositor,
+      private Internals::CompositorHelper::IRendererFactory,
+      private Internals::ICairoContextProvider
   {
   private:
     typedef std::map<size_t, GlyphBitmapAlphabet*>   Fonts;
@@ -51,19 +53,19 @@
                     unsigned int canvasWidth,
                     unsigned int canvasHeight);
     
-    ~CairoCompositor();
+    virtual ~CairoCompositor();
 
     const CairoSurface& GetCanvas() const
     {
       return canvas_;
     }
 
-    unsigned int GetCanvasWidth() const
+    virtual unsigned int GetCanvasWidth() const
     {
       return canvas_.GetWidth();
     }
 
-    unsigned int GetCanvasHeight() const
+    virtual unsigned int GetCanvasHeight() const
     {
       return canvas_.GetHeight();
     }
@@ -72,13 +74,13 @@
                  GlyphBitmapAlphabet* dict);  // Takes ownership
 
 #if ORTHANC_ENABLE_LOCALE == 1
-    void SetFont(size_t index,
-                 Orthanc::EmbeddedResources::FileResourceId resource,
-                 unsigned int fontSize,
-                 Orthanc::Encoding codepage);
+    virtual void SetFont(size_t index,
+                         Orthanc::EmbeddedResources::FileResourceId resource,
+                         unsigned int fontSize,
+                         Orthanc::Encoding codepage);
 #endif
 
-    void Refresh();
+    virtual void Refresh();
 
     Orthanc::ImageAccessor* RenderText(size_t fontIndex,
                                        const std::string& utf8) const;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Framework/Scene2D/ICompositor.h	Wed Jul 17 16:56:53 2019 +0200
@@ -0,0 +1,29 @@
+#pragma once
+
+#include <boost/noncopyable.hpp>
+#include <EmbeddedResources.h>
+#include <Core/Enumerations.h>
+
+namespace OrthancStone
+{
+  class ICompositor : public boost::noncopyable
+  {
+
+  public:
+    virtual ~ICompositor() {}
+
+    virtual unsigned int GetCanvasWidth() const = 0;
+
+    virtual unsigned int GetCanvasHeight() const = 0;
+
+    virtual void Refresh() = 0;
+
+#if ORTHANC_ENABLE_LOCALE == 1
+    virtual void SetFont(size_t index,
+                         Orthanc::EmbeddedResources::FileResourceId resource,
+                         unsigned int fontSize,
+                         Orthanc::Encoding codepage) = 0;
+#endif
+
+  };
+}
--- a/Framework/Scene2D/OpenGLCompositor.h	Wed Jul 17 15:33:34 2019 +0200
+++ b/Framework/Scene2D/OpenGLCompositor.h	Wed Jul 17 16:56:53 2019 +0200
@@ -21,6 +21,7 @@
 
 #pragma once
 
+#include "ICompositor.h"
 #include "Internals/CompositorHelper.h"
 #include "Internals/OpenGLColorTextureProgram.h"
 #include "Internals/OpenGLFloatTextureProgram.h"
@@ -29,7 +30,9 @@
 
 namespace OrthancStone
 {
-  class OpenGLCompositor : private Internals::CompositorHelper::IRendererFactory
+  class OpenGLCompositor :
+      public ICompositor,
+      private Internals::CompositorHelper::IRendererFactory
   {
   private:
     class Font;
@@ -54,9 +57,9 @@
     OpenGLCompositor(OpenGL::IOpenGLContext& context,
                      const Scene2D& scene);
 
-    ~OpenGLCompositor();
+    virtual ~OpenGLCompositor();
 
-    void Refresh();
+    virtual void Refresh();
 
     void SetFont(size_t index,
                  const GlyphBitmapAlphabet& dict);
@@ -68,12 +71,12 @@
                  Orthanc::Encoding codepage);
 #endif
 
-    unsigned int GetCanvasWidth() const
+    virtual unsigned int GetCanvasWidth() const
     {
       return canvasWidth_;
     }
 
-    unsigned int GetCanvasHeight() const
+    virtual unsigned int GetCanvasHeight() const
     {
       return canvasHeight_;
     }
--- a/Framework/Viewport/IViewport.h	Wed Jul 17 15:33:34 2019 +0200
+++ b/Framework/Viewport/IViewport.h	Wed Jul 17 16:56:53 2019 +0200
@@ -20,6 +20,7 @@
 
 #pragma once
 
+#include "../Scene2D/ICompositor.h"
 #include "../Scene2D/Scene2D.h"
 #include "../Scene2D/ScenePoint2D.h"
 
@@ -48,5 +49,13 @@
     virtual const std::string& GetCanvasIdentifier() const = 0;
 
     virtual ScenePoint2D GetPixelCenterCoordinates(int x, int y) const = 0;
+
+    virtual ICompositor& GetCompositor() = 0;
+
+    virtual const ICompositor& GetCompositor() const
+    {
+      IViewport* self = const_cast<IViewport*>(this);
+      return self->GetCompositor();
+    }
   };
 }
--- a/Framework/Viewport/SdlViewport.cpp	Wed Jul 17 15:33:34 2019 +0200
+++ b/Framework/Viewport/SdlViewport.cpp	Wed Jul 17 16:56:53 2019 +0200
@@ -26,24 +26,105 @@
 
 namespace OrthancStone
 {
-  SdlViewport::SdlViewport(const char* title,
-                           unsigned int width,
-                           unsigned int height,
-                           bool allowDpiScaling) :
-    ViewportBase(title),
+  SdlOpenGLViewport::SdlOpenGLViewport(const char* title,
+                                       unsigned int width,
+                                       unsigned int height,
+                                       bool allowDpiScaling) :
+    SdlViewport(title),
+    context_(title, width, height, allowDpiScaling),
+    compositor_(context_, GetScene())
+  {
+  }
+
+  SdlOpenGLViewport::SdlOpenGLViewport(const char* title,
+                                       unsigned int width,
+                                       unsigned int height,
+                                       boost::shared_ptr<Scene2D>& scene,
+                                       bool allowDpiScaling) :
+    SdlViewport(title, scene),
     context_(title, width, height, allowDpiScaling),
     compositor_(context_, GetScene())
   {
   }
 
-  SdlViewport::SdlViewport(const char* title,
-                           unsigned int width,
-                           unsigned int height,
-                           boost::shared_ptr<Scene2D>& scene,
-                           bool allowDpiScaling) :
-    ViewportBase(title, scene),
-    context_(title, width, height, allowDpiScaling),
-    compositor_(context_, GetScene())
+
+  SdlCairoViewport::SdlCairoViewport(const char* title,
+                                     unsigned int width,
+                                     unsigned int height,
+                                     bool allowDpiScaling) :
+    SdlViewport(title),
+    window_(title, width, height, false /* enable OpenGL */, allowDpiScaling),
+    compositor_(GetScene(), width, height)
+  {
+    static const uint32_t rmask = 0x00ff0000;
+    static const uint32_t gmask = 0x0000ff00;
+    static const uint32_t bmask = 0x000000ff;
+
+    sdlSurface_ = SDL_CreateRGBSurfaceFrom((void*)(compositor_.GetCanvas().GetBuffer()), width, height, 32,
+                                           compositor_.GetCanvas().GetPitch(), rmask, gmask, bmask, 0);
+    if (!sdlSurface_)
+    {
+      LOG(ERROR) << "Cannot create a SDL surface from a Cairo surface";
+      throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError);
+    }
+  }
+
+
+  SdlCairoViewport::~SdlCairoViewport()
   {
+    if (sdlSurface_)
+    {
+      SDL_FreeSurface(sdlSurface_);
+    }
   }
+
+//  void SdlCairoViewport::SetSize(unsigned int width,
+//                                 unsigned int height)
+//  {
+    //    if (cairoSurface_.get() == NULL ||
+    //        cairoSurface_->GetWidth() != width ||
+    //        cairoSurface_->GetHeight() != height)
+    //    {
+    //      cairoSurface_.reset(new CairoSurface(width, height, false /* no alpha */));
+
+    //      // TODO Big endian?
+    //      static const uint32_t rmask = 0x00ff0000;
+    //      static const uint32_t gmask = 0x0000ff00;
+    //      static const uint32_t bmask = 0x000000ff;
+
+    //      if (sdlSurface_)
+    //      {
+    //        SDL_FreeSurface(sdlSurface_);
+    //      }
+
+    //      sdlSurface_ = SDL_CreateRGBSurfaceFrom(cairoSurface_->GetBuffer(), width, height, 32,
+    //                                             cairoSurface_->GetPitch(), rmask, gmask, bmask, 0);
+    //      if (!sdlSurface_)
+    //      {
+    //        LOG(ERROR) << "Cannot create a SDL surface from a Cairo surface";
+    //        throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError);
+    //      }
+    //    }
+//  }
+
+
+  void SdlCairoViewport::Refresh()
+  {
+    GetCompositor().Refresh();
+    window_.Render(sdlSurface_);
+  }
+
+
+  //  void SdlCairoViewport::Render()
+  //  {
+  //    Orthanc::ImageAccessor target;
+  //    compositor_.GetCanvas() cairoSurface_->GetWriteableAccessor(target);
+
+  //    if (viewport.Render(target))
+  //    {
+  //      window_.Render(sdlSurface_);
+  //    }
+  //  }
+
+
 }
--- a/Framework/Viewport/SdlViewport.h	Wed Jul 17 15:33:34 2019 +0200
+++ b/Framework/Viewport/SdlViewport.h	Wed Jul 17 16:56:53 2019 +0200
@@ -38,51 +38,96 @@
 
 #include "../../Applications/Sdl/SdlOpenGLContext.h"
 #include "../Scene2D/OpenGLCompositor.h"
+#include "../Scene2D/CairoCompositor.h"
 #include "ViewportBase.h"
 
 namespace OrthancStone
 {
   class SdlViewport : public ViewportBase
   {
+  public:
+    SdlViewport(const std::string& identifier)
+      : ViewportBase(identifier)
+    {}
+
+    SdlViewport(const std::string& identifier,
+                boost::shared_ptr<Scene2D>& scene)
+      : ViewportBase(identifier, scene)
+    {
+
+    }
+
+
+    virtual SdlWindow& GetWindow() = 0;
+  };
+
+  class SdlOpenGLViewport : public SdlViewport
+  {
   private:
     SdlOpenGLContext  context_;
     OpenGLCompositor  compositor_;
 
   public:
-    SdlViewport(const char* title,
-                unsigned int width,
-                unsigned int height,
-                bool allowDpiScaling = true);
-
-    SdlViewport(const char* title,
-                unsigned int width,
-                unsigned int height,
-                boost::shared_ptr<Scene2D>& scene,
-                bool allowDpiScaling = true);
+    SdlOpenGLViewport(const char* title,
+                      unsigned int width,
+                      unsigned int height,
+                      bool allowDpiScaling = true);
 
-    virtual void Refresh()
-    {
-      compositor_.Refresh();
-    }
+    SdlOpenGLViewport(const char* title,
+                      unsigned int width,
+                      unsigned int height,
+                      boost::shared_ptr<Scene2D>& scene,
+                      bool allowDpiScaling = true);
 
-    virtual unsigned int GetCanvasWidth() const
-    {
-      return compositor_.GetCanvasWidth();
-    }
 
-    virtual unsigned int GetCanvasHeight() const
-    {
-      return compositor_.GetCanvasHeight();
-    }
-
-    OpenGLCompositor& GetCompositor()
+    virtual ICompositor& GetCompositor()
     {
       return compositor_;
     }
 
-    SdlOpenGLContext& GetContext()
+    virtual SdlWindow& GetWindow()
     {
-      return context_;
+      return context_.GetWindow();
     }
+    //    SdlOpenGLContext& GetContext()
+    //    {
+    //      return context_;
+    //    }
+  };
+
+
+  class SdlCairoViewport : public SdlViewport
+  {
+  private:
+    SdlWindow         window_;
+    CairoCompositor   compositor_;
+    SDL_Surface*      sdlSurface_;
+
+  public:
+    SdlCairoViewport(const char* title,
+                     unsigned int width,
+                     unsigned int height,
+                     bool allowDpiScaling = true);
+
+    SdlCairoViewport(const char* title,
+                     unsigned int width,
+                     unsigned int height,
+                     boost::shared_ptr<Scene2D>& scene,
+                     bool allowDpiScaling = true);
+
+    ~SdlCairoViewport();
+
+    virtual ICompositor& GetCompositor()
+    {
+      return compositor_;
+    }
+
+    virtual SdlWindow& GetWindow()
+    {
+      return window_;
+    }
+
+    virtual void Refresh();
+
   };
 }
--- a/Framework/Viewport/ViewportBase.h	Wed Jul 17 15:33:34 2019 +0200
+++ b/Framework/Viewport/ViewportBase.h	Wed Jul 17 16:56:53 2019 +0200
@@ -49,5 +49,21 @@
     }
 
     virtual ScenePoint2D GetPixelCenterCoordinates(int x, int y) const;
+
+    virtual void Refresh()
+    {
+      GetCompositor().Refresh();
+    }
+
+    virtual unsigned int GetCanvasWidth() const
+    {
+      return GetCompositor().GetCanvasWidth();
+    }
+
+    virtual unsigned int GetCanvasHeight() const
+    {
+      return GetCompositor().GetCanvasHeight();
+    }
+
   };
 }
--- a/Framework/Viewport/WebAssemblyViewport.h	Wed Jul 17 15:33:34 2019 +0200
+++ b/Framework/Viewport/WebAssemblyViewport.h	Wed Jul 17 16:56:53 2019 +0200
@@ -39,25 +39,10 @@
     WebAssemblyViewport(const std::string& canvas,
                         boost::shared_ptr<Scene2D>& scene);
     
-    virtual void Refresh()
-    {
-      compositor_.Refresh();
-    }
-
-    virtual unsigned int GetCanvasWidth() const
-    {
-      return context_.GetCanvasWidth();
-    }
-
-    virtual unsigned int GetCanvasHeight() const
-    {
-      return context_.GetCanvasHeight();
-    }
-
     // This function must be called each time the browser window is resized
     void UpdateSize();
 
-    OpenGLCompositor& GetCompositor()
+    ICompositor& GetCompositor()
     {
       return compositor_;
     }
--- a/Resources/CMake/OrthancStoneConfiguration.cmake	Wed Jul 17 15:33:34 2019 +0200
+++ b/Resources/CMake/OrthancStoneConfiguration.cmake	Wed Jul 17 16:56:53 2019 +0200
@@ -444,6 +444,7 @@
   ${ORTHANC_STONE_ROOT}/Framework/Scene2D/ColorTextureSceneLayer.cpp
   ${ORTHANC_STONE_ROOT}/Framework/Scene2D/FloatTextureSceneLayer.cpp
   ${ORTHANC_STONE_ROOT}/Framework/Scene2D/GrayscaleStyleConfigurator.cpp
+  ${ORTHANC_STONE_ROOT}/Framework/Scene2D/ICompositor.h
   ${ORTHANC_STONE_ROOT}/Framework/Scene2D/InfoPanelSceneLayer.cpp
   ${ORTHANC_STONE_ROOT}/Framework/Scene2D/Internals/CairoColorTextureRenderer.cpp
   ${ORTHANC_STONE_ROOT}/Framework/Scene2D/Internals/CairoFloatTextureRenderer.cpp
--- a/Samples/Sdl/BasicScene.cpp	Wed Jul 17 15:33:34 2019 +0200
+++ b/Samples/Sdl/BasicScene.cpp	Wed Jul 17 16:56:53 2019 +0200
@@ -48,6 +48,7 @@
 static const unsigned int FONT_SIZE = 32;
 static const int LAYER_POSITION = 150;
 
+#define OPENGL_ENABLED 0
 
 void PrepareScene(OrthancStone::Scene2D& scene)
 {
@@ -259,7 +260,7 @@
   }
 }
 
-
+#if OPENGL_ENABLED==1
 static void GLAPIENTRY
 OpenGLMessageCallback(GLenum source,
                       GLenum type,
@@ -276,7 +277,7 @@
             type, severity, message );
   }
 }
-
+#endif
 
 void Run(OrthancStone::MessageBroker& broker,
          OrthancStone::SdlViewport& viewport)
@@ -286,8 +287,10 @@
   boost::shared_ptr<ViewportController> controller(
     new ViewportController(boost::make_shared<UndoStack>(), broker, viewport));
   
+#if OPENGL_ENABLED==1
   glEnable(GL_DEBUG_OUTPUT);
   glDebugMessageCallback(OpenGLMessageCallback, 0);
+#endif
 
   boost::shared_ptr<IFlexiblePointerTracker> tracker;
 
@@ -356,7 +359,7 @@
         switch (event.key.keysym.sym)
         {
           case SDLK_f:
-            viewport.GetContext().GetWindow().ToggleMaximize();
+            viewport.GetWindow().ToggleMaximize();
             break;
               
           case SDLK_q:
@@ -390,7 +393,11 @@
 
   try
   {
-    OrthancStone::SdlViewport viewport("Hello", 1024, 768);
+#if OPENGL_ENABLED==1
+    OrthancStone::SdlOpenGLViewport viewport("Hello", 1024, 768);
+#else
+    OrthancStone::SdlCairoViewport viewport("Hello", 1024, 768);
+#endif
     PrepareScene(viewport.GetScene());
 
     viewport.GetCompositor().SetFont(0, Orthanc::EmbeddedResources::UBUNTU_FONT,