0027606: Visualization - view is blocking when MSAA has been overridden in graphics...
authorkgv <kgv@opencascade.com>
Thu, 16 Jun 2016 09:58:05 +0000 (12:58 +0300)
committerbugmaster <bugmaster@opencascade.com>
Thu, 23 Jun 2016 15:14:14 +0000 (18:14 +0300)
OpenGl_View::blitBuffers() - try disabling MSAA on glBlitFramebuffer() failure

src/OpenGl/OpenGl_View.cxx
src/OpenGl/OpenGl_View.hxx
src/OpenGl/OpenGl_View_Redraw.cxx

index 3e1a7da..c054675 100644 (file)
@@ -81,6 +81,7 @@ OpenGl_View::OpenGl_View (const Handle(Graphic3d_StructureManager)& theMgr,
   myToFlipOutput         (Standard_False),
   myFrameCounter         (0),
   myHasFboBlit           (Standard_True),
+  myToDisableMSAA        (Standard_False),
   myTransientDrawToFront (Standard_True),
   myBackBufferRestored   (Standard_False),
   myIsImmediateDrawn     (Standard_False),
index 97484a4..3005cd1 100644 (file)
@@ -616,7 +616,8 @@ protected: //! @name Rendering properties
   OpenGl_VertexBuffer        myFullScreenQuadFlip;
   Standard_Boolean           myToFlipOutput;          //!< Flag to draw result image upside-down
   unsigned int               myFrameCounter;          //!< redraw counter, for debugging
-  Standard_Boolean           myHasFboBlit;
+  Standard_Boolean           myHasFboBlit;            //!< disable FBOs on failure
+  Standard_Boolean           myToDisableMSAA;         //!< disable MSAA after failure
   Standard_Boolean           myTransientDrawToFront; //!< optimization flag for immediate mode (to render directly to the front buffer)
   Standard_Boolean           myBackBufferRestored;
   Standard_Boolean           myIsImmediateDrawn;     //!< flag indicates that immediate mode buffer contains some data
index d46965f..2fbe654 100644 (file)
@@ -250,6 +250,8 @@ void OpenGl_View::drawBackground (const Handle(OpenGl_Workspace)& theWorkspace)
 //=======================================================================
 void OpenGl_View::Redraw()
 {
+  const Standard_Boolean wasDisabledMSAA = myToDisableMSAA;
+  const Standard_Boolean hadFboBlit      = myHasFboBlit;
   if (myRenderParams.Method == Graphic3d_RM_RAYTRACING
   && !myCaps->vboDisable
   && !myCaps->keepArrayData)
@@ -292,7 +294,9 @@ void OpenGl_View::Redraw()
   Standard_Integer aSizeY = aFrameBuffer != NULL ? aFrameBuffer->GetVPSizeY() : myWindow->Height();
 
   // determine multisampling parameters
-  Standard_Integer aNbSamples = Max (Min (myRenderParams.NbMsaaSamples, aCtx->MaxMsaaSamples()), 0);
+  Standard_Integer aNbSamples = !myToDisableMSAA
+                              ? Max (Min (myRenderParams.NbMsaaSamples, aCtx->MaxMsaaSamples()), 0)
+                              : 0;
   if (aNbSamples != 0)
   {
     aNbSamples = OpenGl_Context::GetPowerOfTwo (aNbSamples, aCtx->MaxMsaaSamples());
@@ -480,6 +484,13 @@ void OpenGl_View::Redraw()
   // bind default FBO
   bindDefaultFbo();
 
+  if (wasDisabledMSAA != myToDisableMSAA
+   || hadFboBlit      != myHasFboBlit)
+  {
+    // retry on error
+    Redraw();
+  }
+
   // Swap the buffers
   if (toSwap)
   {
@@ -1497,6 +1508,32 @@ bool OpenGl_View::blitBuffers (OpenGl_FrameBuffer*    theReadFbo,
     aCtx->arbFBOBlit->glBlitFramebuffer (0, 0, theReadFbo->GetVPSizeX(), theReadFbo->GetVPSizeY(),
                                          0, 0, theReadFbo->GetVPSizeX(), theReadFbo->GetVPSizeY(),
                                          aCopyMask, GL_NEAREST);
+    const int anErr = ::glGetError();
+    if (anErr != GL_NO_ERROR)
+    {
+      // glBlitFramebuffer() might fail in several cases:
+      // - Both FBOs have MSAA and they are samples number does not match.
+      //   OCCT checks that this does not happen,
+      //   however some graphics drivers provide an option for overriding MSAA.
+      //   In this case window MSAA might be non-zero (and application can not check it)
+      //   and might not match MSAA of our offscreen FBOs.
+      // - Pixel formats of FBOs do not match.
+      //   This also might happen with window has pixel format,
+      //   e.g. Mesa fails blitting RGBA8 -> RGB8 while other drivers support this conversion.
+      TCollection_ExtendedString aMsg = TCollection_ExtendedString() + "FBO blitting has failed [Error #" + anErr + "]\n"
+                                      + "  Please check your graphics driver settings or try updating driver.";
+      if (theReadFbo->NbSamples() != 0)
+      {
+        myToDisableMSAA = true;
+        aMsg += "\n  MSAA settings should not be overridden by driver!";
+      }
+      aCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION,
+                         GL_DEBUG_TYPE_ERROR,
+                         0,
+                         GL_DEBUG_SEVERITY_HIGH,
+                         aMsg);
+    }
+
     if (theDrawFbo != NULL
      && theDrawFbo->IsValid())
     {