0028741: Visualization, TKOpenGl - eliminate GL errors within Core Profile in OpenGl_...
authorakz <akz@opencascade.com>
Thu, 11 May 2017 10:52:18 +0000 (13:52 +0300)
committerbugmaster <bugmaster@opencascade.com>
Thu, 18 May 2017 09:03:04 +0000 (12:03 +0300)
src/D3DHost/D3DHost_FrameBuffer.cxx
src/OpenGl/OpenGl_Context.cxx
src/OpenGl/OpenGl_FrameBuffer.cxx
src/OpenGl/OpenGl_FrameBuffer.hxx
src/OpenGl/OpenGl_View.hxx
src/OpenGl/OpenGl_View_Redraw.cxx

index dc4f97d..c3200ea 100644 (file)
@@ -98,6 +98,8 @@ Standard_Boolean D3DHost_FrameBuffer::Init (const Handle(OpenGl_Context)& theCtx
 
   myVPSizeX = theSizeX;
   myVPSizeY = theSizeY;
+  myInitVPSizeX = theSizeX;
+  myInitVPSizeY = theSizeY;
   const Standard_Integer aSizeX = theSizeX > 0 ? theSizeX : 2;
   const Standard_Integer aSizeY = theSizeY > 0 ? theSizeY : 2;
 
index 65f1d78..eba5e19 100644 (file)
@@ -3491,27 +3491,25 @@ void OpenGl_Context::EnableFeatures() const
 // =======================================================================
 void OpenGl_Context::DisableFeatures() const
 {
-#if !defined(GL_ES_VERSION_2_0)
-  glPixelTransferi (GL_MAP_COLOR, GL_FALSE);
-#endif
-
-  /*
-  * Disable stuff that's likely to slow down glDrawPixels.
-  * (Omit as much of this as possible, when you know in advance
-  * that the OpenGL state will already be set correctly.)
-  */
+  // Disable stuff that's likely to slow down glDrawPixels.
   glDisable(GL_DITHER);
   glDisable(GL_BLEND);
   glDisable(GL_DEPTH_TEST);
-  glDisable(GL_TEXTURE_2D);
   glDisable(GL_STENCIL_TEST);
 
 #if !defined(GL_ES_VERSION_2_0)
+  if (core11 == NULL)
+  {
+    return;
+  }
+
+  glDisable(GL_TEXTURE_1D);
+  glDisable(GL_TEXTURE_2D);
+
   glDisable(GL_LIGHTING);
   glDisable(GL_ALPHA_TEST);
   glDisable(GL_FOG);
   glDisable(GL_LOGIC_OP);
-  glDisable(GL_TEXTURE_1D);
 
   glPixelTransferi(GL_MAP_COLOR, GL_FALSE);
   glPixelTransferi(GL_RED_SCALE, 1);
@@ -3523,16 +3521,8 @@ void OpenGl_Context::DisableFeatures() const
   glPixelTransferi(GL_ALPHA_SCALE, 1);
   glPixelTransferi(GL_ALPHA_BIAS, 0);
 
-  /*
-  * Disable extensions that could slow down glDrawPixels.
-  * (Actually, you should check for the presence of the proper
-  * extension before making these calls.  I've omitted that
-  * code for simplicity.)
-  */
-
   if ((myGlVerMajor >= 1) && (myGlVerMinor >= 2))
   {
-#ifdef GL_EXT_convolution
     if (CheckExtension ("GL_CONVOLUTION_1D_EXT"))
       glDisable(GL_CONVOLUTION_1D_EXT);
 
@@ -3541,20 +3531,15 @@ void OpenGl_Context::DisableFeatures() const
 
     if (CheckExtension ("GL_SEPARABLE_2D_EXT"))
       glDisable(GL_SEPARABLE_2D_EXT);
-#endif
 
-#ifdef GL_EXT_histogram
     if (CheckExtension ("GL_SEPARABLE_2D_EXT"))
       glDisable(GL_HISTOGRAM_EXT);
 
     if (CheckExtension ("GL_MINMAX_EXT"))
       glDisable(GL_MINMAX_EXT);
-#endif
 
-#ifdef GL_EXT_texture3D
     if (CheckExtension ("GL_TEXTURE_3D_EXT"))
       glDisable(GL_TEXTURE_3D_EXT);
-#endif
   }
 #endif
 }
index 4572949..c18551c 100644 (file)
@@ -133,7 +133,9 @@ namespace
 // purpose  :
 // =======================================================================
 OpenGl_FrameBuffer::OpenGl_FrameBuffer()
-: myVPSizeX (0),
+: myInitVPSizeX (0),
+  myInitVPSizeY (0),
+  myVPSizeX (0),
   myVPSizeY (0),
   myNbSamples (0),
   myDepthFormat (GL_DEPTH24_STENCIL8),
@@ -326,6 +328,8 @@ Standard_Boolean OpenGl_FrameBuffer::Init (const Handle(OpenGl_Context)& theGlCo
 
   myDepthFormat = theDepthFormat;
   myNbSamples   = theNbSamples;
+  myInitVPSizeX = theSizeX;
+  myInitVPSizeY = theSizeY;
   if (theGlContext->arbFBO == NULL)
   {
     return Standard_False;
@@ -535,6 +539,8 @@ Standard_Boolean OpenGl_FrameBuffer::InitWithRB (const Handle(OpenGl_Context)& t
 
   myDepthFormat = theDepthFormat;
   myNbSamples   = 0;
+  myInitVPSizeX = theSizeX;
+  myInitVPSizeY = theSizeY;
   if (theGlCtx->arbFBO == NULL)
   {
     return Standard_False;
index 1ef79d0..9d6ead1 100644 (file)
@@ -97,6 +97,18 @@ public:
     return myVPSizeY;
   }
 
+  //! Viewport width.
+  GLsizei GetInitVPSizeX() const
+  {
+    return myInitVPSizeX;
+  }
+
+  //! Viewport height.
+  GLsizei GetInitVPSizeY() const
+  {
+    return myInitVPSizeY;
+  }
+
   //! Returns true if current object was initialized
   Standard_Boolean IsValid() const
   {
@@ -246,6 +258,8 @@ protected:
 
 protected:
 
+  GLsizei                myInitVPSizeX;         //!< viewport width  specified during initialization (kept even on failure)
+  GLsizei                myInitVPSizeY;         //!< viewport height specified during initialization (kept even on failure)
   GLsizei                myVPSizeX;             //!< viewport width  (should be <= texture width)
   GLsizei                myVPSizeY;             //!< viewport height (should be <= texture height)
   GLsizei                myNbSamples;           //!< number of MSAA samples
index 1d5adcc..8ed3c5d 100644 (file)
@@ -444,7 +444,7 @@ private:
 private:
 
   //! Copy content of Back buffer to the Front buffer.
-  void copyBackToFront();
+  bool copyBackToFront();
 
   //! Initialize blit quad.
   OpenGl_VertexBuffer* initBlitQuad (const Standard_Boolean theToFlip);
index 703d127..0c4aa80 100644 (file)
 #include <OpenGl_Structure.hxx>
 #include <OpenGl_ArbFBO.hxx>
 
+namespace
+{
+  //! Format Frame Buffer format for logging messages.
+  static TCollection_AsciiString printFboFormat (const Handle(OpenGl_FrameBuffer)& theFbo)
+  {
+    return TCollection_AsciiString() + theFbo->GetInitVPSizeX() + "x" + theFbo->GetInitVPSizeY() + "@" + theFbo->NbSamples();
+  }
+
+  //! Return TRUE if Frame Buffer initialized has failed with the same parameters.
+  static bool checkWasFailedFbo (const Handle(OpenGl_FrameBuffer)& theFboToCheck,
+                                 Standard_Integer theSizeX,
+                                 Standard_Integer theSizeY,
+                                 Standard_Integer theNbSamples)
+  {
+    return !theFboToCheck->IsValid()
+        &&  theFboToCheck->GetInitVPSizeX() == theSizeX
+        &&  theFboToCheck->GetInitVPSizeY() == theSizeY
+        &&  theFboToCheck->NbSamples()      == theNbSamples;
+  }
+
+  //! Return TRUE if Frame Buffer initialized has failed with the same parameters.
+  static bool checkWasFailedFbo (const Handle(OpenGl_FrameBuffer)& theFboToCheck,
+                                 const Handle(OpenGl_FrameBuffer)& theFboRef)
+  {
+    return checkWasFailedFbo (theFboToCheck, theFboRef->GetVPSizeX(), theFboRef->GetVPSizeY(), theFboRef->NbSamples());
+  }
+}
+
 //=======================================================================
 //function : drawBackground
 //purpose  :
@@ -198,12 +226,26 @@ void OpenGl_View::Redraw()
       // for further blitting and rendering immediate presentations on top
       if (aCtx->core20fwd != NULL)
       {
-        myMainSceneFbos[0]->Init (aCtx, aRendSizeX, aRendSizeY, myFboColorFormat, myFboDepthFormat, aNbSamples);
+        const bool wasFailedMain0 = checkWasFailedFbo (myMainSceneFbos[0], aRendSizeX, aRendSizeY, aNbSamples);
+        if (!myMainSceneFbos[0]->Init (aCtx, aRendSizeX, aRendSizeY, myFboColorFormat, myFboDepthFormat, aNbSamples)
+         && !wasFailedMain0)
+        {
+          TCollection_ExtendedString aMsg = TCollection_ExtendedString() + "Error! Main FBO "
+                                          + printFboFormat (myMainSceneFbos[0]) + " initialization has failed";
+          aCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_ERROR, 0, GL_DEBUG_SEVERITY_HIGH, aMsg);
+        }
       }
     }
     if (myMainSceneFbos[0]->IsValid() && (toInitImmediateFbo || myImmediateSceneFbos[0]->IsValid()))
     {
-      myImmediateSceneFbos[0]->InitLazy (aCtx, *myMainSceneFbos[0]);
+      const bool wasFailedImm0 = checkWasFailedFbo (myImmediateSceneFbos[0], myMainSceneFbos[0]);
+      if (!myImmediateSceneFbos[0]->InitLazy (aCtx, *myMainSceneFbos[0])
+       && !wasFailedImm0)
+      {
+        TCollection_ExtendedString aMsg = TCollection_ExtendedString() + "Error! Immediate FBO "
+                                        + printFboFormat (myImmediateSceneFbos[0]) + " initialization has failed";
+        aCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_ERROR, 0, GL_DEBUG_SEVERITY_HIGH, aMsg);
+      }
     }
   }
   else
@@ -221,7 +263,14 @@ void OpenGl_View::Redraw()
   if (aProjectType == Graphic3d_Camera::Projection_Stereo
    && myMainSceneFbos[0]->IsValid())
   {
-    myMainSceneFbos[1]->InitLazy (aCtx, *myMainSceneFbos[0]);
+    const bool wasFailedMain1 = checkWasFailedFbo (myMainSceneFbos[1], myMainSceneFbos[0]);
+    if (!myMainSceneFbos[1]->InitLazy (aCtx, *myMainSceneFbos[0])
+     && !wasFailedMain1)
+    {
+      TCollection_ExtendedString aMsg = TCollection_ExtendedString() + "Error! Main FBO (second) "
+                                      + printFboFormat (myMainSceneFbos[1]) + " initialization has failed";
+      aCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_ERROR, 0, GL_DEBUG_SEVERITY_HIGH, aMsg);
+    }
     if (!myMainSceneFbos[1]->IsValid())
     {
       // no enough memory?
@@ -233,8 +282,22 @@ void OpenGl_View::Redraw()
     }
     else if (!aCtx->HasStereoBuffers() || aStereoMode != Graphic3d_StereoMode_QuadBuffer)
     {
-      myImmediateSceneFbos[0]->InitLazy (aCtx, *myMainSceneFbos[0]);
-      myImmediateSceneFbos[1]->InitLazy (aCtx, *myMainSceneFbos[0]);
+      const bool wasFailedImm0 = checkWasFailedFbo (myImmediateSceneFbos[0], myMainSceneFbos[0]);
+      const bool wasFailedImm1 = checkWasFailedFbo (myImmediateSceneFbos[1], myMainSceneFbos[0]);
+      if (!myImmediateSceneFbos[0]->InitLazy (aCtx, *myMainSceneFbos[0])
+       && !wasFailedImm0)
+      {
+        TCollection_ExtendedString aMsg = TCollection_ExtendedString() + "Error! Immediate FBO (first) "
+                                        + printFboFormat (myImmediateSceneFbos[0]) + " initialization has failed";
+        aCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_ERROR, 0, GL_DEBUG_SEVERITY_HIGH, aMsg);
+      }
+      if (!myImmediateSceneFbos[1]->InitLazy (aCtx, *myMainSceneFbos[0])
+       && !wasFailedImm1)
+      {
+        TCollection_ExtendedString aMsg = TCollection_ExtendedString() + "Error! Immediate FBO (first) "
+                                        + printFboFormat (myImmediateSceneFbos[1]) + " initialization has failed";
+        aCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_ERROR, 0, GL_DEBUG_SEVERITY_HIGH, aMsg);
+      }
       if (!myImmediateSceneFbos[0]->IsValid()
        || !myImmediateSceneFbos[1]->IsValid())
       {
@@ -746,7 +809,11 @@ bool OpenGl_View::redrawImmediate (const Graphic3d_Camera::Projection theProject
         // prefer Swap Buffers within Redraw in compatibility mode (without FBO)
         return true;
       }
-      copyBackToFront();
+      if (!copyBackToFront())
+      {
+        toCopyBackToFront    = GL_FALSE;
+        myBackBufferRestored = Standard_False;
+      }
     }
     else
     {
@@ -1548,17 +1615,21 @@ void OpenGl_View::drawStereoPair (OpenGl_FrameBuffer* theDrawFbo)
 // function : copyBackToFront
 // purpose  :
 // =======================================================================
-void OpenGl_View::copyBackToFront()
+bool OpenGl_View::copyBackToFront()
 {
+  myIsImmediateDrawn = Standard_False;
 #if !defined(GL_ES_VERSION_2_0)
+  const Handle(OpenGl_Context)& aCtx = myWorkspace->GetGlContext();
+  if (aCtx->core11 == NULL)
+  {
+    return false;
+  }
 
   OpenGl_Mat4 aProjectMat;
   Graphic3d_TransformUtils::Ortho2D (aProjectMat,
                                      0.0f, static_cast<GLfloat> (myWindow->Width()),
                                      0.0f, static_cast<GLfloat> (myWindow->Height()));
 
-  const Handle(OpenGl_Context)& aCtx = myWorkspace->GetGlContext();
-
   aCtx->WorldViewState.Push();
   aCtx->ProjectionState.Push();
 
@@ -1595,9 +1666,9 @@ void OpenGl_View::copyBackToFront()
     }
   }
 
-  glRasterPos2i (0, 0);
-  glCopyPixels  (0, 0, myWindow->Width() + 1, myWindow->Height() + 1, GL_COLOR);
-  //glCopyPixels  (0, 0, myWidth + 1, myHeight + 1, GL_DEPTH);
+  aCtx->core11->glRasterPos2i (0, 0);
+  aCtx->core11->glCopyPixels  (0, 0, myWindow->Width() + 1, myWindow->Height() + 1, GL_COLOR);
+  //aCtx->core11->glCopyPixels  (0, 0, myWidth + 1, myHeight + 1, GL_DEPTH);
 
   aCtx->EnableFeatures();
 
@@ -1607,8 +1678,10 @@ void OpenGl_View::copyBackToFront()
 
   // read/write from front buffer now
   aCtx->SetReadBuffer (aCtx->DrawBuffer());
+  return true;
+#else
+  return false;
 #endif
-  myIsImmediateDrawn = Standard_False;
 }
 
 // =======================================================================