diff Framework/Viewport/SdlViewport.cpp @ 1205:6009c59d8676 broker

fix to sdl
author Sebastien Jodogne <s.jodogne@gmail.com>
date Mon, 02 Dec 2019 14:32:05 +0100
parents f3bb9a6dd949
children d10d2acb8a02
line wrap: on
line diff
--- a/Framework/Viewport/SdlViewport.cpp	Fri Nov 29 21:24:29 2019 +0100
+++ b/Framework/Viewport/SdlViewport.cpp	Mon Dec 02 14:32:05 2019 +0100
@@ -24,6 +24,26 @@
 
 namespace OrthancStone
 {
+  SdlViewport::SdlViewport()
+  {
+    refreshEvent_ = SDL_RegisterEvents(1);
+    
+    if (refreshEvent_ == static_cast<uint32_t>(-1))
+    {
+      throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError);
+    }
+  }
+
+
+  void SdlViewport::SendRefreshEvent()
+  {
+    SDL_Event event;
+    SDL_memset(&event, 0, sizeof(event));
+    event.type = refreshEvent_;
+    SDL_PushEvent(&event);  // This function is thread-safe, and can be called from other threads safely.
+  }
+
+  
   SdlOpenGLViewport::SdlOpenGLViewport(const char* title,
                                        unsigned int width,
                                        unsigned int height,
@@ -33,7 +53,12 @@
     compositor_.reset(new OpenGLCompositor(context_, GetScene()));
   }
 
-  void SdlOpenGLViewport::Refresh()
+  void SdlOpenGLViewport::Invalidate()
+  {
+    SendRefreshEvent();
+  }
+
+  void SdlOpenGLViewport::Paint()
   {
     boost::mutex::scoped_lock lock(mutex_);
     compositor_->Refresh();
@@ -45,9 +70,9 @@
                                      unsigned int height,
                                      bool allowDpiScaling) :
     window_(title, width, height, false /* enable OpenGL */, allowDpiScaling),
-    compositor_(GetScene(), width, height)
+    compositor_(GetScene(), width, height),
+    sdlSurface_(NULL)
   {
-    UpdateSdlSurfaceSize(width, height);
   }
 
   SdlCairoViewport::~SdlCairoViewport()
@@ -58,16 +83,30 @@
     }
   }
   
-  void SdlCairoViewport::RefreshInternal()  // Assumes that the mutex is locked
+  void SdlCairoViewport::InvalidateInternal()  // Assumes that the mutex is locked
   {
     compositor_.Refresh();
-    window_.Render(sdlSurface_);
+    CreateSdlSurfaceFromCompositor();
   }
 
-  void SdlCairoViewport::Refresh()
+  void SdlCairoViewport::Paint()
   {
     boost::mutex::scoped_lock lock(mutex_);
-    RefreshInternal();
+    
+    if (sdlSurface_ != NULL)
+    {
+      window_.Render(sdlSurface_);
+    }    
+  }
+
+  void SdlCairoViewport::Invalidate()
+  {
+    {
+      boost::mutex::scoped_lock lock(mutex_);
+      InvalidateInternal();
+    }
+
+    SendRefreshEvent();
   }
 
   void SdlCairoViewport::UpdateSize(unsigned int width,
@@ -75,17 +114,34 @@
   {
     boost::mutex::scoped_lock lock(mutex_);
     compositor_.UpdateSize(width, height);
-    UpdateSdlSurfaceSize(width, height);
-    RefreshInternal();
+    InvalidateInternal();
   }
   
-  void SdlCairoViewport::UpdateSdlSurfaceSize(unsigned int width,
-                                              unsigned int height)  // Assumes that the mutex is locked
+  void SdlCairoViewport::CreateSdlSurfaceFromCompositor()  // Assumes that the mutex is locked
   {
     static const uint32_t rmask = 0x00ff0000;
     static const uint32_t gmask = 0x0000ff00;
     static const uint32_t bmask = 0x000000ff;
 
+    const unsigned int width = compositor_.GetCanvas().GetWidth();
+    const unsigned int height = compositor_.GetCanvas().GetHeight();
+    
+    if (sdlSurface_ != NULL)
+    {
+      if (sdlSurface_->pixels == compositor_.GetCanvas().GetBuffer() &&
+          sdlSurface_->w == static_cast<int>(width) &&
+          sdlSurface_->h == static_cast<int>(height) &&
+          sdlSurface_->pitch == static_cast<int>(compositor_.GetCanvas().GetPitch()))
+      {
+        // The image from the compositor has not changed, no need to update the surface
+        return;
+      }
+      else
+      {
+        SDL_FreeSurface(sdlSurface_);
+      }
+    }
+
     sdlSurface_ = SDL_CreateRGBSurfaceFrom((void*)(compositor_.GetCanvas().GetBuffer()), width, height, 32,
                                            compositor_.GetCanvas().GetPitch(), rmask, gmask, bmask, 0);
     if (!sdlSurface_)