diff Framework/Viewport/SdlViewport.cpp @ 947:1091b2adeb5a toa2019081001

Fixed animation frame stopping when returning false + big work on the OpenGL objects to make them lost context-safe + debug code to forcefully tag a context as lost + debug macros
author Benjamin Golinvaux <bgo@osimis.io>
date Sat, 10 Aug 2019 13:07:31 +0200
parents 7a7e4e1f558f
children a7351ad54960
line wrap: on
line diff
--- a/Framework/Viewport/SdlViewport.cpp	Tue Aug 06 15:07:23 2019 +0200
+++ b/Framework/Viewport/SdlViewport.cpp	Sat Aug 10 13:07:31 2019 +0200
@@ -31,9 +31,9 @@
                                        unsigned int height,
                                        bool allowDpiScaling) :
     SdlViewport(title),
-    context_(title, width, height, allowDpiScaling),
-    compositor_(context_, GetScene())
+    context_(title, width, height, allowDpiScaling)
   {
+    compositor_.reset(new OpenGLCompositor(context_, GetScene()));
   }
 
   SdlOpenGLViewport::SdlOpenGLViewport(const char* title,
@@ -42,12 +42,97 @@
                                        boost::shared_ptr<Scene2D>& scene,
                                        bool allowDpiScaling) :
     SdlViewport(title, scene),
-    context_(title, width, height, allowDpiScaling),
-    compositor_(context_, GetScene())
+    context_(title, width, height, allowDpiScaling)
+  {
+    compositor_.reset(new OpenGLCompositor(context_, GetScene()));
+  }
+
+  bool SdlOpenGLViewport::OpenGLContextLost()
+  {
+    throw Orthanc::OrthancException(Orthanc::ErrorCode_NotImplemented);
+  }
+
+  void SdlOpenGLViewport::DisableCompositor()
+  {
+    compositor_.reset(NULL);
+  }
+
+  void SdlOpenGLViewport::RestoreCompositor()
+  {
+    // the context must have been restored!
+    ORTHANC_ASSERT(!context_.IsContextLost());
+
+    if (compositor_.get() == NULL)
+    {
+      compositor_.reset(new OpenGLCompositor(context_, GetScene()));
+    }
+    else
+    {
+      std::string windowTitle(SDL_GetWindowTitle(GetWindow().GetObject()));
+      LOG(WARNING) << "RestoreCompositor() called for \"" << windowTitle << "\" while it was NOT lost! Nothing done.";
+    }
+  }
+
+  // extern bool Debug_MustContextBeRestored(std::string title);
+  // extern void Debug_Context_ClearRestoreFlag(std::string title);
+  // extern void Debug_Context_ClearKillFlag(std::string title);
+
+  bool Debug_SdlOpenGLViewport_Refresh_BP = false;
+
+  void SdlOpenGLViewport::Refresh()
   {
+    // <DEBUG CODE USED FOR CONTEXT LOSS RESTORING>
+    // try to restore the context if requested
+    // Debug_Context_ClearRestoreFlag
+    // Debug_SdlOpenGLViewport_Refresh_BP = true;
+    // try
+    // {
+    //   if (Debug_MustContextBeRestored(GetCanvasIdentifier()))
+    //   {
+    //     // to prevent a bug where the context is both labelled as "to be lost" and "to be restored"
+    //     // (occurs when one is hammering away at the keyboard like there's no tomorrow)
+    //     Debug_Context_ClearKillFlag(GetCanvasIdentifier());
+    //     // this is called manually for loss/restore simulation
+    //     context_.RestoreLostContext();
+    //     RestoreCompositor();
+    //     Debug_Context_ClearRestoreFlag(GetCanvasIdentifier());
+    //   }
+    // }
+    // catch (const OpenGLContextLostException& e)
+    // {
+    //   LOG(ERROR) << "OpenGLContextLostException in SdlOpenGLViewport::Refresh() part 1";
+    // }
+    // Debug_SdlOpenGLViewport_Refresh_BP = false;
+    // </DEBUG CODE USED FOR CONTEXT LOSS RESTORING>
+
+    try
+    {
+      // the compositor COULD be dead!
+      if (GetCompositor())
+        GetCompositor()->Refresh();
+    }
+    catch (const OpenGLContextLostException& e)
+    {
+      // we need to wait for the "context restored" callback
+      LOG(WARNING) << "Context " << std::hex << e.context_ << " is lost! Compositor will be disabled.";
+      DisableCompositor();
+
+      // <DEBUG CODE USED FOR CONTEXT LOSS RESTORING>
+      // in case this was externally triggered...
+      //Debug_Context_ClearKillFlag(GetCanvasIdentifier());
+      // </DEBUG CODE USED FOR CONTEXT LOSS RESTORING>
+    }
+    catch (...)
+    {
+      // something else nasty happened
+      throw;
+    }
   }
 
 
+
+
+
   SdlCairoViewport::SdlCairoViewport(const char* title,
                                      unsigned int width,
                                      unsigned int height,
@@ -59,6 +144,15 @@
     UpdateSdlSurfaceSize(width, height);
   }
 
+  void SdlCairoViewport::DisableCompositor()
+  {
+    throw Orthanc::OrthancException(Orthanc::ErrorCode_NotImplemented);
+  }
+  
+  void SdlCairoViewport::RestoreCompositor()
+  {
+    throw Orthanc::OrthancException(Orthanc::ErrorCode_NotImplemented);
+  }
 
   SdlCairoViewport::~SdlCairoViewport()
   {
@@ -67,11 +161,10 @@
       SDL_FreeSurface(sdlSurface_);
     }
   }
-
-
+  
   void SdlCairoViewport::Refresh()
   {
-    GetCompositor().Refresh();
+    GetCompositor()->Refresh();
     window_.Render(sdlSurface_);
   }
 
@@ -82,8 +175,7 @@
     UpdateSdlSurfaceSize(width, height);
     Refresh();
   }
-
-
+  
   void SdlCairoViewport::UpdateSdlSurfaceSize(unsigned int width,
                                               unsigned int height)
   {