]> OCCT Git - occt-copy.git/commitdiff
0025897: Visualization, TKOpenGl - disable FBO blitting after first failure on broken...
authorkgv <kgv@opencascade.com>
Thu, 5 Mar 2015 15:05:58 +0000 (18:05 +0300)
committerbugmaster <bugmaster@opencascade.com>
Thu, 12 Mar 2015 09:23:56 +0000 (12:23 +0300)
OpenGl_Context::init() - detect OpenGL 2.0+ broken context by wrong GLSL version string.
Emit error messages when OpenGL context reports version higher than actually exported.

Improve logic of methods drawing Immediate presentations and swapping the Buffers.
OpenGl_Workspace::myTransientDrawToFront - repair functionality of this flag
to always render Immediate Objects into Back Buffer.
OpenGl_Workspace::myHasFboBlit - add new flag to disable FBO blitting after first failure.

src/OpenGl/OpenGl_Context.cxx
src/OpenGl/OpenGl_Context.hxx
src/OpenGl/OpenGl_Workspace.cxx
src/OpenGl/OpenGl_Workspace.hxx
src/OpenGl/OpenGl_Workspace_2.cxx
src/OpenGl/OpenGl_Workspace_Raytrace.cxx

index 77eb19c7dc03310e752155115a278e0069a30996..d5a428b77cfef8a0e12262808af35757bfb051bd 100644 (file)
@@ -894,6 +894,30 @@ void OpenGl_Context::PushMessage (const unsigned int theSource,
   Messenger()->Send (aMsg, aGrav);
 }
 
+// =======================================================================
+// function : checkWrongVersion
+// purpose  :
+// ======================================================================
+void OpenGl_Context::checkWrongVersion (const Standard_Integer theGlVerMajor,
+                                        const Standard_Integer theGlVerMinor)
+{
+  if (!IsGlGreaterEqual (theGlVerMajor, theGlVerMinor))
+  {
+    return;
+  }
+
+  TCollection_ExtendedString aMsg = TCollection_ExtendedString()
+    + "Error! OpenGL context reports version "
+    + myGlVerMajor  + "." + myGlVerMinor
+    + " but does not export required functions for "
+    + theGlVerMajor + "." + theGlVerMinor;
+  PushMessage (GL_DEBUG_SOURCE_APPLICATION_ARB,
+               GL_DEBUG_TYPE_ERROR_ARB,
+               0,
+               GL_DEBUG_SEVERITY_HIGH_ARB,
+               aMsg);
+}
+
 // =======================================================================
 // function : init
 // purpose  :
@@ -1898,24 +1922,28 @@ void OpenGl_Context::init (const Standard_Boolean theIsCoreProfile)
 
   if (!has12)
   {
+    checkWrongVersion (1, 2);
     myGlVerMajor = 1;
     myGlVerMinor = 1;
     return;
   }
   else if (!has13)
   {
+    checkWrongVersion (1, 3);
     myGlVerMajor = 1;
     myGlVerMinor = 2;
     return;
   }
   else if (!has14)
   {
+    checkWrongVersion (1, 4);
     myGlVerMajor = 1;
     myGlVerMinor = 3;
     return;
   }
   else if (!has15)
   {
+    checkWrongVersion (1, 5);
     myGlVerMajor = 1;
     myGlVerMinor = 4;
     return;
@@ -1928,6 +1956,26 @@ void OpenGl_Context::init (const Standard_Boolean theIsCoreProfile)
 
   if (!has20)
   {
+    checkWrongVersion (2, 0);
+    myGlVerMajor = 1;
+    myGlVerMinor = 5;
+    return;
+  }
+
+  const char* aGlslVer = (const char* )::glGetString (GL_SHADING_LANGUAGE_VERSION);
+  if (aGlslVer == NULL
+  || *aGlslVer == '\0')
+  {
+    // broken context has been detected
+    TCollection_ExtendedString aMsg = TCollection_ExtendedString()
+      + "Error! OpenGL context reports version "
+      + myGlVerMajor  + "." + myGlVerMinor
+      + " but reports wrong GLSL version";
+    PushMessage (GL_DEBUG_SOURCE_APPLICATION_ARB,
+                 GL_DEBUG_TYPE_ERROR_ARB,
+                 0,
+                 GL_DEBUG_SEVERITY_HIGH_ARB,
+                 aMsg);
     myGlVerMajor = 1;
     myGlVerMinor = 5;
     return;
@@ -1941,6 +1989,7 @@ void OpenGl_Context::init (const Standard_Boolean theIsCoreProfile)
 
   if (!has21)
   {
+    checkWrongVersion (2, 1);
     myGlVerMajor = 2;
     myGlVerMinor = 0;
     return;
@@ -1948,6 +1997,7 @@ void OpenGl_Context::init (const Standard_Boolean theIsCoreProfile)
 
   if (!has30)
   {
+    checkWrongVersion (3, 0);
     myGlVerMajor = 2;
     myGlVerMinor = 1;
     return;
@@ -1955,6 +2005,7 @@ void OpenGl_Context::init (const Standard_Boolean theIsCoreProfile)
 
   if (!has31)
   {
+    checkWrongVersion (3, 1);
     myGlVerMajor = 3;
     myGlVerMinor = 0;
     return;
@@ -1964,6 +2015,7 @@ void OpenGl_Context::init (const Standard_Boolean theIsCoreProfile)
 
   if (!has32)
   {
+    checkWrongVersion (3, 2);
     myGlVerMajor = 3;
     myGlVerMinor = 1;
     return;
@@ -1980,6 +2032,7 @@ void OpenGl_Context::init (const Standard_Boolean theIsCoreProfile)
 
   if (!has33)
   {
+    checkWrongVersion (3, 3);
     myGlVerMajor = 3;
     myGlVerMinor = 2;
     return;
@@ -1996,6 +2049,7 @@ void OpenGl_Context::init (const Standard_Boolean theIsCoreProfile)
 
   if (!has40)
   {
+    checkWrongVersion (4, 0);
     myGlVerMajor = 3;
     myGlVerMinor = 3;
     return;
@@ -2004,6 +2058,7 @@ void OpenGl_Context::init (const Standard_Boolean theIsCoreProfile)
 
   if (!has41)
   {
+    checkWrongVersion (4, 1);
     myGlVerMajor = 4;
     myGlVerMinor = 0;
     return;
@@ -2016,6 +2071,7 @@ void OpenGl_Context::init (const Standard_Boolean theIsCoreProfile)
 
   if(!has42)
   {
+    checkWrongVersion (4, 2);
     myGlVerMajor = 4;
     myGlVerMinor = 1;
     return;
@@ -2028,6 +2084,7 @@ void OpenGl_Context::init (const Standard_Boolean theIsCoreProfile)
 
   if (!has43)
   {
+    checkWrongVersion (4, 3);
     myGlVerMajor = 4;
     myGlVerMinor = 2;
     return;
@@ -2040,6 +2097,7 @@ void OpenGl_Context::init (const Standard_Boolean theIsCoreProfile)
 
   if (!has44)
   {
+    checkWrongVersion (4, 4);
     myGlVerMajor = 4;
     myGlVerMinor = 3;
     return;
index 0cf2591be164105daa9598e720cd29a2f09a6154..ecb3c36ae08e8cdfe0c544ca4c064d9f6454a06e 100644 (file)
@@ -512,6 +512,13 @@ private:
   //! Wrapper to system function to retrieve GL function pointer by name.
   Standard_EXPORT void* findProc (const char* theFuncName);
 
+  //! Print error if not all functions have been exported by context for reported version.
+  //! Note that this will never happen when using GLX, since returned functions can not be validated.
+  //! @param theGlVerMajor the OpenGL major version with missing functions
+  //! @param theGlVerMinor the OpenGL minor version with missing functions
+  Standard_EXPORT void checkWrongVersion (const Standard_Integer theGlVerMajor,
+                                          const Standard_Integer theGlVerMinor);
+
   //! Private initialization function that should be called only once.
   Standard_EXPORT void init (const Standard_Boolean theIsCoreProfile);
 
index 556d66a7990beabffa3f3db2f232429ccbc07ddb..22337cafebcca2b351de247527dd62cc24c2e700 100644 (file)
@@ -149,6 +149,7 @@ OpenGl_Workspace::OpenGl_Workspace (const Handle(OpenGl_GraphicDriver)& theDrive
   myComputeInitStatus (OpenGl_RT_NONE),
   myIsRaytraceDataValid (Standard_False),
   myIsRaytraceWarnTextures (Standard_False),
+  myHasFboBlit (Standard_True),
   myViewModificationStatus (0),
   myLayersModificationStatus (0),
   //
@@ -677,45 +678,51 @@ void OpenGl_Workspace::Redraw (const Graphic3d_CView& theCView,
   myIsCullingEnabled = theCView.IsCullingEnabled;
 
   // release pending GL resources
-  Handle(OpenGl_Context) aGlCtx = GetGlContext();
-  aGlCtx->ReleaseDelayed();
+  myGlContext->ReleaseDelayed();
 
   // fetch OpenGl context state
-  aGlCtx->FetchState();
+  myGlContext->FetchState();
 
-  Tint toSwap = (aGlCtx->IsRender() && !aGlCtx->caps->buffersNoSwap) ? 1 : 0; // swap buffers
   OpenGl_FrameBuffer* aFrameBuffer = (OpenGl_FrameBuffer* )theCView.ptrFBO;
   if (aFrameBuffer != NULL)
   {
-    aFrameBuffer->SetupViewport (aGlCtx);
-    toSwap = 0; // no need to swap buffers
+    aFrameBuffer->SetupViewport (myGlContext);
   }
   else
   {
-    aGlCtx->core11fwd->glViewport (0, 0, myWidth, myHeight);
+    myGlContext->core11fwd->glViewport (0, 0, myWidth, myHeight);
   }
+  bool toSwap = myGlContext->IsRender()
+            && !myGlContext->caps->buffersNoSwap
+            &&  aFrameBuffer == NULL;
 
   Standard_Integer aSizeX = aFrameBuffer != NULL ? aFrameBuffer->GetVPSizeX() : myWidth;
   Standard_Integer aSizeY = aFrameBuffer != NULL ? aFrameBuffer->GetVPSizeY() : myHeight;
 
-  if (myResultFBO->GetVPSizeX() != aSizeX
-   || myResultFBO->GetVPSizeY() != aSizeY)
+  if (myHasFboBlit
+   && myTransientDrawToFront)
   {
-    // prepare FBOs containing main scene
-    // for further blitting and rendering immediate presentations on top
-    if (aGlCtx->core20fwd != NULL)
+    if (myResultFBO->GetVPSizeX() != aSizeX
+     || myResultFBO->GetVPSizeY() != aSizeY)
     {
-      myResultFBO->Init (aGlCtx, aSizeX, aSizeY);
+      // prepare FBOs containing main scene
+      // for further blitting and rendering immediate presentations on top
+      if (myGlContext->core20fwd != NULL)
+      {
+        myResultFBO->Init (myGlContext, aSizeX, aSizeY);
+      }
+    }
+
+    if (myResultFBO->IsValid())
+    {
+      myResultFBO->SetupViewport (myGlContext);
     }
   }
-  if (myResultFBO->IsValid())
+  else
   {
-    myResultFBO->SetupViewport (aGlCtx);
+    myResultFBO->Release (myGlContext.operator->());
   }
 
-  const Standard_Boolean isImmediate = myView->HasImmediateStructures()
-                                    || myResultFBO->IsValid();
-
   myToRedrawGL = Standard_True;
   if (theCView.RenderParams.Method == Graphic3d_RM_RAYTRACING
    && myComputeInitStatus != OpenGl_RT_FAIL)
@@ -736,7 +743,7 @@ void OpenGl_Workspace::Redraw (const Graphic3d_CView& theCView,
       if (myOpenGlFBO->GetVPSizeX() != aSizeX
        || myOpenGlFBO->GetVPSizeY() != aSizeY)
       {
-        myOpenGlFBO->Init (aGlCtx, aSizeX, aSizeY);
+        myOpenGlFBO->Init (myGlContext, aSizeX, aSizeY);
       }
 
       // OverLayer and UnderLayer shouldn't be drawn by OpenGL.
@@ -744,17 +751,18 @@ void OpenGl_Workspace::Redraw (const Graphic3d_CView& theCView,
       Aspect_CLayer2d anEmptyCLayer;
       anEmptyCLayer.ptrLayer = NULL;
 
-      myOpenGlFBO->BindBuffer (aGlCtx);
-      redraw1 (theCView, anEmptyCLayer, anEmptyCLayer, 0);
-      myOpenGlFBO->UnbindBuffer (aGlCtx);
+      myOpenGlFBO->BindBuffer (myGlContext);
+      redraw1 (theCView, anEmptyCLayer, anEmptyCLayer);
+      myOpenGlFBO->UnbindBuffer (myGlContext);
 
-      Raytrace (theCView, aSizeX, aSizeY, isImmediate ? 0 : toSwap,
+      Raytrace (theCView, aSizeX, aSizeY,
                 theCOverLayer, theCUnderLayer,
                 myResultFBO->IsValid() ? myResultFBO.operator->() : aFrameBuffer);
-
-      if (isImmediate)
+      myBackBufferRestored = Standard_True;
+      myIsImmediateDrawn   = Standard_False;
+      if (!redrawImmediate (theCView, theCOverLayer, theCUnderLayer, aFrameBuffer))
       {
-        RedrawImmediate (theCView, theCUnderLayer, theCOverLayer, Standard_True, aFrameBuffer);
+        toSwap = false;
       }
 
       SetRenderFilter (aRenderFilter);
@@ -768,17 +776,19 @@ void OpenGl_Workspace::Redraw (const Graphic3d_CView& theCView,
     // draw entire frame using normal OpenGL pipeline
     if (myResultFBO->IsValid())
     {
-      myResultFBO->BindBuffer (aGlCtx);
+      myResultFBO->BindBuffer (myGlContext);
     }
     else if (aFrameBuffer != NULL)
     {
-      aFrameBuffer->BindBuffer (aGlCtx);
+      aFrameBuffer->BindBuffer (myGlContext);
     }
 
-    redraw1 (theCView, theCUnderLayer, theCOverLayer, isImmediate ? 0 : toSwap);
-    if (isImmediate)
+    redraw1 (theCView, theCUnderLayer, theCOverLayer);
+    myBackBufferRestored = Standard_True;
+    myIsImmediateDrawn   = Standard_False;
+    if (!redrawImmediate (theCView, theCOverLayer, theCUnderLayer, aFrameBuffer))
     {
-      RedrawImmediate (theCView, theCUnderLayer, theCOverLayer, Standard_True, aFrameBuffer);
+      toSwap = false;
     }
 
     theCView.WasRedrawnGL = Standard_True;
@@ -786,9 +796,9 @@ void OpenGl_Workspace::Redraw (const Graphic3d_CView& theCView,
 
   if (aFrameBuffer != NULL)
   {
-    aFrameBuffer->UnbindBuffer (aGlCtx);
+    aFrameBuffer->UnbindBuffer (myGlContext);
     // move back original viewport
-    aGlCtx->core11fwd->glViewport (0, 0, myWidth, myHeight);
+    myGlContext->core11fwd->glViewport (0, 0, myWidth, myHeight);
   }
 
 #if defined(_WIN32) && defined(HAVE_VIDEOCAPTURE)
@@ -809,8 +819,22 @@ void OpenGl_Workspace::Redraw (const Graphic3d_CView& theCView,
   }
 #endif
 
+  // Swap the buffers
+  if (toSwap)
+  {
+    GetGlContext()->SwapBuffers();
+    if (!myResultFBO->IsValid())
+    {
+      myBackBufferRestored = Standard_False;
+    }
+  }
+  else
+  {
+    myGlContext->core11fwd->glFlush();
+  }
+
   // reset render mode state
-  aGlCtx->FetchState();
+  myGlContext->FetchState();
 }
 
 // =======================================================================
@@ -819,8 +843,7 @@ void OpenGl_Workspace::Redraw (const Graphic3d_CView& theCView,
 // =======================================================================
 void OpenGl_Workspace::redraw1 (const Graphic3d_CView& theCView,
                                 const Aspect_CLayer2d& theCUnderLayer,
-                                const Aspect_CLayer2d& theCOverLayer,
-                                const int              theToSwap)
+                                const Aspect_CLayer2d& theCOverLayer)
 {
   if (myView.IsNull())
   {
@@ -879,20 +902,6 @@ void OpenGl_Workspace::redraw1 (const Graphic3d_CView& theCView,
 
   Handle(OpenGl_Workspace) aWS (this);
   myView->Render (myPrintContext, aWS, theCView, theCUnderLayer, theCOverLayer, Standard_False);
-
-  // swap the buffers
-  if (theToSwap)
-  {
-    GetGlContext()->SwapBuffers();
-    myBackBufferRestored = Standard_False;
-    myIsImmediateDrawn   = Standard_False;
-  }
-  else
-  {
-    glFlush(); //
-    myBackBufferRestored = Standard_True;//
-    myIsImmediateDrawn   = Standard_False;//
-  }
 }
 
 // =======================================================================
@@ -963,51 +972,49 @@ void OpenGl_Workspace::DisplayCallback (const Graphic3d_CView& theCView,
 // =======================================================================
 void OpenGl_Workspace::RedrawImmediate (const Graphic3d_CView& theCView,
                                         const Aspect_CLayer2d& theCUnderLayer,
-                                        const Aspect_CLayer2d& theCOverLayer,
-                                        const Standard_Boolean theToForce,
-                                        OpenGl_FrameBuffer*    theTargetFBO)
+                                        const Aspect_CLayer2d& theCOverLayer)
 {
-  if (!Activate())
+  if (!myTransientDrawToFront
+   || !myBackBufferRestored
+   || (myGlContext->caps->buffersNoSwap && !myResultFBO->IsValid()))
   {
+    Redraw (theCView, theCUnderLayer, theCOverLayer);
     return;
   }
-
-  GLboolean isDoubleBuffer = GL_FALSE;
-#if !defined(GL_ES_VERSION_2_0)
-  glGetBooleanv (GL_DOUBLEBUFFER, &isDoubleBuffer);
-#endif
-  if (!myView->HasImmediateStructures()
-   && !myResultFBO->IsValid())
+  else if (!Activate())
   {
-    if (theToForce
-     || !myIsImmediateDrawn)
-    {
-      myIsImmediateDrawn = Standard_False;
-      return;
-    }
-
-    if (myBackBufferRestored
-     && isDoubleBuffer)
-    {
-      copyBackToFront();
-      glFlush();
-    }
-    else
-    {
-      Redraw (theCView, theCUnderLayer, theCOverLayer);
-    }
     return;
   }
 
-  if (myResultFBO->IsValid()
-   && myGlContext->IsRender())
+  if (redrawImmediate (theCView, theCUnderLayer, theCOverLayer, NULL, Standard_True))
   {
-    if (!myBackBufferRestored)
-    {
-      Redraw (theCView, theCUnderLayer, theCOverLayer);
-      return;
-    }
+    myGlContext->SwapBuffers();
+  }
+  else
+  {
+    myGlContext->core11fwd->glFlush();
+    MakeBackBufCurrent();
+  }
+}
 
+// =======================================================================
+// function : redrawImmediate
+// purpose  :
+// =======================================================================
+bool OpenGl_Workspace::redrawImmediate (const Graphic3d_CView& theCView,
+                                        const Aspect_CLayer2d& theCUnderLayer,
+                                        const Aspect_CLayer2d& theCOverLayer,
+                                        OpenGl_FrameBuffer*    theTargetFBO,
+                                        const Standard_Boolean theIsPartialUpdate)
+{
+  GLboolean toCopyBackToFront = GL_FALSE;
+  if (!myTransientDrawToFront)
+  {
+    myBackBufferRestored = Standard_False;
+  }
+  else if (myResultFBO->IsValid()
+        && myGlContext->IsRender())
+  {
     // clear destination before blitting
     if (theTargetFBO != NULL)
     {
@@ -1084,17 +1091,41 @@ void OpenGl_Workspace::RedrawImmediate (const Graphic3d_CView& theCView,
         myResultFBO->DepthStencilTexture()->Unbind (myGlContext, GL_TEXTURE0 + 1);
         myResultFBO->ColorTexture()       ->Unbind (myGlContext, GL_TEXTURE0 + 0);
       }
+      else
+      {
+        TCollection_ExtendedString aMsg = TCollection_ExtendedString()
+          + "Error! FBO blitting has failed";
+        myGlContext->PushMessage (GL_DEBUG_SOURCE_APPLICATION_ARB,
+                                  GL_DEBUG_TYPE_ERROR_ARB,
+                                  0,
+                                  GL_DEBUG_SEVERITY_HIGH_ARB,
+                                  aMsg);
+        myHasFboBlit = Standard_False;
+        myResultFBO->Release (myGlContext.operator->());
+        return true;
+      }
     }
   }
-  else if (isDoubleBuffer && myTransientDrawToFront)
+  else if (theTargetFBO == NULL)
   {
-    if (!myBackBufferRestored)
+  #if !defined(GL_ES_VERSION_2_0)
+    myGlContext->core11fwd->glGetBooleanv (GL_DOUBLEBUFFER, &toCopyBackToFront);
+  #endif
+    if (toCopyBackToFront)
     {
-      Redraw (theCView, theCUnderLayer, theCOverLayer);
-      return;
+      if (!myView->HasImmediateStructures()
+       && !theIsPartialUpdate)
+      {
+        // prefer Swap Buffers within Redraw in compatibility mode (without FBO)
+        return true;
+      }
+      copyBackToFront();
+      MakeFrontBufCurrent();
+    }
+    else
+    {
+      myBackBufferRestored = Standard_False;
     }
-    copyBackToFront();
-    MakeFrontBufCurrent();
   }
   else
   {
@@ -1145,18 +1176,10 @@ void OpenGl_Workspace::RedrawImmediate (const Graphic3d_CView& theCView,
     aStructure->Render (aWS);
   }
 
-  if (myResultFBO->IsValid())
-  {
-    if (theTargetFBO == NULL
-    &&  myGlContext->IsRender()
-    && !myGlContext->caps->buffersNoSwap)
-    {
-      myGlContext->SwapBuffers();
-    }
-  }
-  else if (isDoubleBuffer && myTransientDrawToFront)
+  if (toCopyBackToFront)
   {
-    glFlush();
     MakeBackBufCurrent();
+    return false;
   }
+  return true;
 }
index 4b36fc4d7fea076234e66c8745db3e06372d9ec3..5f74ef3971dccddc17c1e940cc634cb01df27726 100644 (file)
@@ -159,9 +159,7 @@ public:
   Standard_Boolean SetImmediateModeDrawToFront (const Standard_Boolean theDrawToFrontBuffer);
   void RedrawImmediate (const Graphic3d_CView& theCView,
                         const Aspect_CLayer2d& theCUnderLayer,
-                        const Aspect_CLayer2d& theCOverLayer,
-                        const Standard_Boolean theToForce = Standard_False,
-                        OpenGl_FrameBuffer*    theTargetFBO = NULL);
+                        const Aspect_CLayer2d& theCOverLayer);
 
   void Invalidate (const Graphic3d_CView& /*theCView*/)
   {
@@ -273,8 +271,21 @@ protected:
 
   void redraw1 (const Graphic3d_CView& theCView,
                 const Aspect_CLayer2d& theCUnderLayer,
-                const Aspect_CLayer2d& theCOverLayer,
-                const int              theToSwap);
+                const Aspect_CLayer2d& theCOverLayer);
+
+  //! Blit snapshot containing main scene (myResultFBO or BackBuffer)
+  //! into presentation buffer (myResultFBO->offscreen FBO or myResultFBO->BackBuffer or BackBuffer->FrontBuffer),
+  //! and redraw immediate structures on top.
+  //!
+  //! When scene caching is disabled (myTransientDrawToFront, no double buffer in window, etc.),
+  //! the first step (blitting) will be skipped.
+  //!
+  //! @return false if immediate structures has been rendered directly into FrontBuffer and Buffer Swap should not be called.
+  bool redrawImmediate (const Graphic3d_CView& theCView,
+                        const Aspect_CLayer2d& theCUnderLayer,
+                        const Aspect_CLayer2d& theCOverLayer,
+                        OpenGl_FrameBuffer*    theTargetFBO,
+                        const Standard_Boolean theIsPartialUpdate = Standard_False);
 
   void updateMaterial (const int theFlag);
 
@@ -560,7 +571,6 @@ protected: //! @name methods related to ray-tracing
   Standard_Boolean Raytrace (const Graphic3d_CView& theCView,
                              const Standard_Integer theSizeX,
                              const Standard_Integer theSizeY,
-                             const Standard_Boolean theToSwap,
                              const Aspect_CLayer2d& theCOverLayer,
                              const Aspect_CLayer2d& theCUnderLayer,
                              OpenGl_FrameBuffer*    theFrameBuffer);
@@ -637,6 +647,8 @@ protected: //! @name fields related to ray-tracing
 
   //! Framebuffer stores cached main presentation of the view (without presentation of immediate layers).
   Handle(OpenGl_FrameBuffer) myResultFBO;
+  //! Special flag which is invalidated when myResultFBO can not be blitted for some reason (e.g. driver bugs).
+  Standard_Boolean           myHasFboBlit;
 
   //! Vertices for full-screen quad rendering.
   OpenGl_VertexBuffer        myFullScreenQuad;
index 2195f7831047951cbd8bdf92c2a2a1780c4f3a96..2bf1720f41adcb29854945c4ac5568bfe0709ffb 100644 (file)
@@ -569,11 +569,15 @@ Standard_Boolean OpenGl_Workspace::Print
     myPrintContext->SetScale ((GLfloat )aFrameWidth /viewWidth,
                               (GLfloat )aFrameHeight/viewHeight);
     aFrameBuffer->SetupViewport (GetGlContext());
-    redraw1 (ACView, ACUnderLayer, ACOverLayer, 0);
+    redraw1 (ACView, ACUnderLayer, ACOverLayer);
     if (!myTransientDrawToFront)
     {
       // render to FBO only if allowed to render to back buffer
-      RedrawImmediate (ACView, ACUnderLayer, ACOverLayer, Standard_True);
+      myBackBufferRestored = Standard_True;
+      myIsImmediateDrawn   = Standard_False;
+      redrawImmediate (ACView, ACUnderLayer, ACOverLayer, aFrameBuffer);
+      myBackBufferRestored = Standard_False;
+      myIsImmediateDrawn   = Standard_False;
     }
     glReadPixels (0, 0, aFrameWidth, aFrameHeight,
                   GL_BGR_EXT, GL_UNSIGNED_BYTE, (GLvoid* )aViewBuffer);
@@ -680,11 +684,15 @@ Standard_Boolean OpenGl_Workspace::Print
 
         // draw to the offscreen buffer and capture the result
         aFrameBuffer->SetupViewport (GetGlContext());
-        redraw1 (ACView, ACUnderLayer, ACOverLayer, 0);
+        redraw1 (ACView, ACUnderLayer, ACOverLayer);
         if (!myTransientDrawToFront)
         {
           // render to FBO only if forces to render to back buffer
-          RedrawImmediate (ACView, ACUnderLayer, ACOverLayer, Standard_True);
+          myBackBufferRestored = Standard_True;
+          myIsImmediateDrawn   = Standard_False;
+          redrawImmediate (ACView, ACUnderLayer, ACOverLayer, aFrameBuffer);
+          myBackBufferRestored = Standard_False;
+          myIsImmediateDrawn   = Standard_False;
         }
         glReadPixels (0, 0, aFrameWidth, aFrameHeight,
                       GL_BGR_EXT, GL_UNSIGNED_BYTE, (GLvoid* )aViewBuffer);
index 33435e67b848b21538b3768a92c4476787b0831c..ef54ab9c348100baf1a29b481acd5cc8ea524475 100644 (file)
@@ -2307,7 +2307,6 @@ Standard_Boolean OpenGl_Workspace::RunRaytraceShaders (const Graphic3d_CView& th
 Standard_Boolean OpenGl_Workspace::Raytrace (const Graphic3d_CView& theCView,
                                              const Standard_Integer theSizeX,
                                              const Standard_Integer theSizeY,
-                                             const Standard_Boolean theToSwap,
                                              const Aspect_CLayer2d& theCOverLayer,
                                              const Aspect_CLayer2d& theCUnderLayer,
                                              OpenGl_FrameBuffer*    theFrameBuffer)
@@ -2435,18 +2434,6 @@ Standard_Boolean OpenGl_Workspace::Raytrace (const Graphic3d_CView& theCView,
   DisplayCallback (theCView, (aMode | OCC_PRE_OVERLAY));
   myView->RedrawLayer2d (myPrintContext, this, theCView, theCOverLayer);
   DisplayCallback (theCView, aMode);
-
-  // Swap the buffers
-  if (theToSwap)
-  {
-    GetGlContext()->SwapBuffers();
-    myBackBufferRestored = Standard_False;
-  }
-  else
-  {
-    glFlush();
-  }
-
   return Standard_True;
 }