0024171: Eliminate CLang compiler warning -Wreorder
[occt.git] / src / OpenGl / OpenGl_Context.cxx
index 00f8c2f..09cd4a5 100644 (file)
@@ -1,6 +1,6 @@
 // Created on: 2012-01-26
 // Created by: Kirill GAVRILOV
-// Copyright (c) 2012-2012 OPEN CASCADE SAS
+// Copyright (c) 2012 OPEN CASCADE SAS
 //
 // The content of this file is subject to the Open CASCADE Technology Public
 // License Version 6.5 (the "License"). You may not use the content of this file
@@ -17,8 +17,7 @@
 // purpose or non-infringement. Please see the License for the specific terms
 // and conditions governing the rights and limitations under the License.
 
-
-#if (defined(_WIN32) || defined(__WIN32__))
+#if defined(_WIN32)
   #include <windows.h>
 #endif
 
 #include <OpenGl_ArbVBO.hxx>
 #include <OpenGl_ArbTBO.hxx>
 #include <OpenGl_ArbIns.hxx>
+#include <OpenGl_ArbDbg.hxx>
 #include <OpenGl_ExtFBO.hxx>
+#include <OpenGl_ExtGS.hxx>
 #include <OpenGl_GlCore20.hxx>
 
+#include <NCollection_Vector.hxx>
+
 #include <Standard_ProgramError.hxx>
 
-#if (defined(_WIN32) || defined(__WIN32__))
+#if defined(_WIN32)
   //
 #elif defined(__APPLE__) && !defined(MACOSX_USE_GLX)
   #include <dlfcn.h>
@@ -67,22 +70,31 @@ namespace
 // function : OpenGl_Context
 // purpose  :
 // =======================================================================
-OpenGl_Context::OpenGl_Context()
+OpenGl_Context::OpenGl_Context (const Handle(OpenGl_Caps)& theCaps)
 : core12 (NULL),
   core13 (NULL),
   core14 (NULL),
   core15 (NULL),
   core20 (NULL),
+  caps   (!theCaps.IsNull() ? theCaps : new OpenGl_Caps()),
+  arbNPTW(Standard_False),
   arbVBO (NULL),
   arbTBO (NULL),
   arbIns (NULL),
+  arbDbg (NULL),
   extFBO (NULL),
+  extGS  (NULL),
+  extBgra(Standard_False),
+  extAnis(Standard_False),
   atiMem (Standard_False),
   nvxMem (Standard_False),
   mySharedResources (new OpenGl_ResourcesMap()),
-  myReleaseQueue (new OpenGl_ResourcesQueue()),
+  myDelayed         (new OpenGl_DelayReleaseMap()),
+  myReleaseQueue    (new OpenGl_ResourcesQueue()),
   myGlLibHandle (NULL),
   myGlCore20 (NULL),
+  myAnisoMax   (1),
+  myMaxTexDim  (1024),
   myGlVerMajor (0),
   myGlVerMinor (0),
   myIsFeedback (Standard_False),
@@ -121,10 +133,33 @@ OpenGl_Context::~OpenGl_Context()
     }
   }
   mySharedResources.Nullify();
+  myDelayed.Nullify();
 
   delete myGlCore20;
   delete arbVBO;
+  delete arbTBO;
+  delete arbIns;
+  delete arbDbg;
   delete extFBO;
+  delete extGS;
+}
+
+// =======================================================================
+// function : MaxDegreeOfAnisotropy
+// purpose  :
+// =======================================================================
+Standard_Integer OpenGl_Context::MaxDegreeOfAnisotropy() const
+{
+  return myAnisoMax;
+}
+
+// =======================================================================
+// function : MaxTextureSize
+// purpose  :
+// =======================================================================
+Standard_Integer OpenGl_Context::MaxTextureSize() const
+{
+  return myMaxTexDim;
 }
 
 // =======================================================================
@@ -136,17 +171,20 @@ void OpenGl_Context::Share (const Handle(OpenGl_Context)& theShareCtx)
   if (!theShareCtx.IsNull())
   {
     mySharedResources = theShareCtx->mySharedResources;
+    myDelayed         = theShareCtx->myDelayed;
     myReleaseQueue    = theShareCtx->myReleaseQueue;
   }
 }
 
+#if !defined(__APPLE__) || defined(MACOSX_USE_GLX)
+
 // =======================================================================
 // function : IsCurrent
 // purpose  :
 // =======================================================================
 Standard_Boolean OpenGl_Context::IsCurrent() const
 {
-#if (defined(_WIN32) || defined(__WIN32__))
+#if defined(_WIN32)
   if (myWindowDC == NULL || myGContext == NULL)
   {
     return Standard_False;
@@ -171,7 +209,7 @@ Standard_Boolean OpenGl_Context::IsCurrent() const
 // =======================================================================
 Standard_Boolean OpenGl_Context::MakeCurrent()
 {
-#if (defined(_WIN32) || defined(__WIN32__))
+#if defined(_WIN32)
   if (myWindowDC == NULL || myGContext == NULL)
   {
     Standard_ProgramError_Raise_if (myIsInitialized, "OpenGl_Context::Init() should be called before!");
@@ -225,7 +263,7 @@ Standard_Boolean OpenGl_Context::MakeCurrent()
 // =======================================================================
 void OpenGl_Context::SwapBuffers()
 {
-#if (defined(_WIN32) || defined(__WIN32__))
+#if defined(_WIN32)
   if ((HDC )myWindowDC != NULL)
   {
     ::SwapBuffers ((HDC )myWindowDC);
@@ -239,13 +277,15 @@ void OpenGl_Context::SwapBuffers()
 #endif
 }
 
+#endif // __APPLE__
+
 // =======================================================================
 // function : findProc
 // purpose  :
 // =======================================================================
 void* OpenGl_Context::findProc (const char* theFuncName)
 {
-#if (defined(_WIN32) || defined(__WIN32__))
+#if defined(_WIN32)
   return wglGetProcAddress (theFuncName);
 #elif defined(__APPLE__) && !defined(MACOSX_USE_GLX)
   return (myGlLibHandle != NULL) ? dlsym (myGlLibHandle, theFuncName) : NULL;
@@ -265,7 +305,6 @@ Standard_Boolean OpenGl_Context::CheckExtension (const char* theExtName) const
     std::cerr << "CheckExtension called with NULL string!\n";
     return Standard_False;
   }
-  int anExtNameLen = strlen (theExtName);
 
   // available since OpenGL 3.0
   // and the ONLY way to check extensions with OpenGL 3.1+ core profile
@@ -292,14 +331,29 @@ Standard_Boolean OpenGl_Context::CheckExtension (const char* theExtName) const
     std::cerr << "glGetString (GL_EXTENSIONS) returns NULL! No GL context?\n";
     return Standard_False;
   }
+  return CheckExtension (anExtString, theExtName);
+}
+
+// =======================================================================
+// function : CheckExtension
+// purpose  :
+// =======================================================================
+Standard_Boolean OpenGl_Context::CheckExtension (const char* theExtString,
+                                                 const char* theExtName)
+{
+  if (theExtString == NULL)
+  {
+    return Standard_False;
+  }
 
   // Search for theExtName in the extensions string.
   // Use of strstr() is not sufficient because extension names can be prefixes of other extension names.
-  char* aPtrIter = (char* )anExtString;
-  const char* aPtrEnd = aPtrIter + strlen (anExtString);
+  char* aPtrIter = (char* )theExtString;
+  const char*  aPtrEnd      = aPtrIter + strlen (theExtString);
+  const size_t anExtNameLen = strlen (theExtName);
   while (aPtrIter < aPtrEnd)
   {
-    int n = strcspn (aPtrIter, " ");
+    const size_t n = strcspn (aPtrIter, " ");
     if ((n == anExtNameLen) && (strncmp (aPtrIter, theExtName, anExtNameLen) == 0))
     {
       return Standard_True;
@@ -309,6 +363,8 @@ Standard_Boolean OpenGl_Context::CheckExtension (const char* theExtName) const
   return Standard_False;
 }
 
+#if !defined(__APPLE__) || defined(MACOSX_USE_GLX)
+
 // =======================================================================
 // function : Init
 // purpose  :
@@ -320,7 +376,7 @@ Standard_Boolean OpenGl_Context::Init()
     return Standard_True;
   }
 
-#if (defined(_WIN32) || defined(__WIN32__))
+#if defined(_WIN32)
   myWindowDC = (Aspect_Handle )wglGetCurrentDC();
   myGContext = (Aspect_RenderingContext )wglGetCurrentContext();
 #else
@@ -338,14 +394,18 @@ Standard_Boolean OpenGl_Context::Init()
   return Standard_True;
 }
 
+#endif // __APPLE__
+
 // =======================================================================
 // function : Init
 // purpose  :
 // =======================================================================
-#if (defined(_WIN32) || defined(__WIN32__))
+#if defined(_WIN32)
 Standard_Boolean OpenGl_Context::Init (const Aspect_Handle           theWindow,
                                        const Aspect_Handle           theWindowDC,
                                        const Aspect_RenderingContext theGContext)
+#elif defined(__APPLE__) && !defined(MACOSX_USE_GLX)
+Standard_Boolean OpenGl_Context::Init (const void*                   theGContext)
 #else
 Standard_Boolean OpenGl_Context::Init (const Aspect_Drawable         theWindow,
                                        const Aspect_Display          theDisplay,
@@ -353,12 +413,15 @@ Standard_Boolean OpenGl_Context::Init (const Aspect_Drawable         theWindow,
 #endif
 {
   Standard_ProgramError_Raise_if (myIsInitialized, "OpenGl_Context::Init() should be called only once!");
-
+#if defined(_WIN32)
   myWindow   = theWindow;
   myGContext = theGContext;
-#if (defined(_WIN32) || defined(__WIN32__))
   myWindowDC = theWindowDC;
+#elif defined(__APPLE__) && !defined(MACOSX_USE_GLX)
+  myGContext = (void* )theGContext;
 #else
+  myWindow   = theWindow;
+  myGContext = theGContext;
   myDisplay  = theDisplay;
 #endif
   if (myGContext == NULL || !MakeCurrent())
@@ -394,10 +457,15 @@ void OpenGl_Context::readGlVersion()
   myGlVerMinor = 0;
 
   // available since OpenGL 3.0
-  GLint aMajor, aMinor;
+  GLint aMajor = 0, aMinor = 0;
   glGetIntegerv (GL_MAJOR_VERSION, &aMajor);
   glGetIntegerv (GL_MINOR_VERSION, &aMinor);
-  if (glGetError() == GL_NO_ERROR)
+  // glGetError() sometimes does not report an error here even if 
+  // GL does not know GL_MAJOR_VERSION and GL_MINOR_VERSION constants.
+  // This happens on some rendereres like e.g. Cygwin MESA.
+  // Thus checking additionally if GL has put anything to
+  // the output variables.
+  if (glGetError() == GL_NO_ERROR && aMajor != 0 && aMinor != 0)
   {
     myGlVerMajor = aMajor;
     myGlVerMinor = aMinor;
@@ -433,18 +501,18 @@ void OpenGl_Context::readGlVersion()
   aMajorStr[aMajIter] = '\0';
 
   // parse string for minor number
-  size_t aMinIter = aMajIter + 1;
+  aVerStr += aMajIter + 1;
+  size_t aMinIter = 0;
   while (aVerStr[aMinIter] >= '0' && aVerStr[aMinIter] <= '9')
   {
     ++aMinIter;
   }
-  size_t aMinLen = aMinIter - aMajIter - 1;
-  if (aMinLen == 0 || aMinLen >= sizeof(aMinorStr))
+  if (aMinIter == 0 || aMinIter >= sizeof(aMinorStr))
   {
     return;
   }
-  memcpy (aMinorStr, aVerStr, aMinLen);
-  aMinorStr[aMinLen] = '\0';
+  memcpy (aMinorStr, aVerStr, aMinIter);
+  aMinorStr[aMinIter] = '\0';
 
   // read numbers
   myGlVerMajor = atoi (aMajorStr);
@@ -457,6 +525,60 @@ void OpenGl_Context::readGlVersion()
   }
 }
 
+static Standard_CString THE_DBGMSG_UNKNOWN = "UNKNOWN";
+static Standard_CString THE_DBGMSG_SOURCES[] =
+{
+  "OpenGL",          // GL_DEBUG_SOURCE_API_ARB
+  "Window System",   // GL_DEBUG_SOURCE_WINDOW_SYSTEM_ARB
+  "Shader Compiler", // GL_DEBUG_SOURCE_SHADER_COMPILER_ARB
+  "Third Party",     // GL_DEBUG_SOURCE_THIRD_PARTY_ARB
+  "Application",     // GL_DEBUG_SOURCE_APPLICATION_ARB
+  "Other"            // GL_DEBUG_SOURCE_OTHER_ARB
+};
+
+static Standard_CString THE_DBGMSG_TYPES[] =
+{
+  "Error",              // GL_DEBUG_TYPE_ERROR_ARB
+  "Deprecated",         // GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR_ARB
+  "Undefined behavior", // GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR_ARB
+  "Portability",        // GL_DEBUG_TYPE_PORTABILITY_ARB
+  "Performance",        // GL_DEBUG_TYPE_PERFORMANCE_ARB
+  "Other"               // GL_DEBUG_TYPE_OTHER_ARB
+};
+
+static Standard_CString THE_DBGMSG_SEV_HIGH   = "High";   // GL_DEBUG_SEVERITY_HIGH_ARB
+static Standard_CString THE_DBGMSG_SEV_MEDIUM = "Medium"; // GL_DEBUG_SEVERITY_MEDIUM_ARB
+static Standard_CString THE_DBGMSG_SEV_LOW    = "Low";    // GL_DEBUG_SEVERITY_LOW_ARB
+
+static void APIENTRY debugCallbackWrap(unsigned int theSource,
+                                       unsigned int theType,
+                                       unsigned int theId,
+                                       unsigned int theSeverity,
+                                       int          /*theLength*/,
+                                       const char*  theMessage,
+                                       void*        /*theUserParam*/)
+{
+  //OpenGl_Context* aCtx = (OpenGl_Context* )theUserParam;
+  Standard_CString& aSrc = (theSource >= GL_DEBUG_SOURCE_API_ARB
+                         && theSource <= GL_DEBUG_SOURCE_OTHER_ARB)
+                         ? THE_DBGMSG_SOURCES[theSource - GL_DEBUG_SOURCE_API_ARB]
+                         : THE_DBGMSG_UNKNOWN;
+  Standard_CString& aType = (theType >= GL_DEBUG_TYPE_ERROR_ARB
+                          && theType <= GL_DEBUG_TYPE_OTHER_ARB)
+                          ? THE_DBGMSG_TYPES[theType - GL_DEBUG_TYPE_ERROR_ARB]
+                          : THE_DBGMSG_UNKNOWN;
+  Standard_CString& aSev = theSeverity == GL_DEBUG_SEVERITY_HIGH_ARB
+                         ? THE_DBGMSG_SEV_HIGH
+                         : (theSeverity == GL_DEBUG_SEVERITY_MEDIUM_ARB
+                          ? THE_DBGMSG_SEV_MEDIUM
+                          : THE_DBGMSG_SEV_LOW);
+  std::cerr << "Source:"  << aSrc
+            << " | Type:" << aType
+            << " | ID:"   << theId
+            << " | Severity:" << aSev
+            << " | Message:\n  " << theMessage << "\n";
+}
+
 // =======================================================================
 // function : init
 // purpose  :
@@ -466,8 +588,39 @@ void OpenGl_Context::init()
   // read version
   readGlVersion();
 
-  atiMem = CheckExtension ("GL_ATI_meminfo");
-  nvxMem = CheckExtension ("GL_NVX_gpu_memory_info");
+  arbNPTW = CheckExtension ("GL_ARB_texture_non_power_of_two");
+  extBgra = CheckExtension ("GL_EXT_bgra");
+  extAnis = CheckExtension ("GL_EXT_texture_filter_anisotropic");
+  atiMem  = CheckExtension ("GL_ATI_meminfo");
+  nvxMem  = CheckExtension ("GL_NVX_gpu_memory_info");
+
+  glGetIntegerv (GL_MAX_TEXTURE_SIZE, &myMaxTexDim);
+  if (extAnis)
+  {
+    glGetIntegerv (GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &myAnisoMax);
+  }
+
+  // initialize debug context extension
+  if (CheckExtension ("GL_ARB_debug_output"))
+  {
+    arbDbg = new OpenGl_ArbDbg();
+    memset (arbDbg, 0, sizeof(OpenGl_ArbDbg)); // nullify whole structure
+    if (!FindProcShort (arbDbg, glDebugMessageControlARB)
+     || !FindProcShort (arbDbg, glDebugMessageInsertARB)
+     || !FindProcShort (arbDbg, glDebugMessageCallbackARB)
+     || !FindProcShort (arbDbg, glGetDebugMessageLogARB))
+    {
+      delete arbDbg;
+      arbDbg = NULL;
+    }
+    if (arbDbg != NULL
+     && caps->contextDebug)
+    {
+      // setup default callback
+      arbDbg->glDebugMessageCallbackARB (debugCallbackWrap, this);
+      glEnable (GL_DEBUG_OUTPUT_SYNCHRONOUS_ARB);
+    }
+  }
 
   // initialize VBO extension (ARB)
   if (CheckExtension ("GL_ARB_vertex_buffer_object"))
@@ -523,249 +676,263 @@ void OpenGl_Context::init()
      || !FindProcShort (extFBO, glDeleteRenderbuffersEXT)
      || !FindProcShort (extFBO, glBindRenderbufferEXT)
      || !FindProcShort (extFBO, glRenderbufferStorageEXT)
-     || !FindProcShort (extFBO, glFramebufferRenderbufferEXT))
+     || !FindProcShort (extFBO, glFramebufferRenderbufferEXT)
+     || !FindProcShort (extFBO, glGenerateMipmapEXT))
     {
       delete extFBO;
       extFBO = NULL;
     }
   }
 
-  myGlCore20 = new OpenGl_GlCore20();
-  memset (myGlCore20, 0, sizeof(OpenGl_GlCore20)); // nullify whole structure
-
-  // initialize OpenGL 1.2 core functionality
-  if (IsGlGreaterEqual (1, 2))
+  // initialize GS extension (EXT)
+  if (CheckExtension ("GL_EXT_geometry_shader4"))
   {
-    if (!FindProcShort (myGlCore20, glBlendColor)
-     || !FindProcShort (myGlCore20, glBlendEquation)
-     || !FindProcShort (myGlCore20, glDrawRangeElements)
-     || !FindProcShort (myGlCore20, glTexImage3D)
-     || !FindProcShort (myGlCore20, glTexSubImage3D)
-     || !FindProcShort (myGlCore20, glCopyTexSubImage3D))
+    extGS = new OpenGl_ExtGS();
+    memset (extGS, 0, sizeof(OpenGl_ExtGS)); // nullify whole structure
+    if (!FindProcShort (extGS, glProgramParameteriEXT))
     {
-      myGlVerMajor = 1;
-      myGlVerMinor = 1;
+      delete extGS;
+      extGS = NULL;
     }
   }
 
-  // initialize OpenGL 1.3 core functionality
-  if (IsGlGreaterEqual (1, 3))
-  {
-    if (!FindProcShort (myGlCore20, glActiveTexture)
-     || !FindProcShort (myGlCore20, glSampleCoverage)
-     || !FindProcShort (myGlCore20, glCompressedTexImage3D)
-     || !FindProcShort (myGlCore20, glCompressedTexImage2D)
-     || !FindProcShort (myGlCore20, glCompressedTexImage1D)
-     || !FindProcShort (myGlCore20, glCompressedTexSubImage3D)
-     || !FindProcShort (myGlCore20, glCompressedTexSubImage2D)
-     || !FindProcShort (myGlCore20, glCompressedTexSubImage1D)
-     || !FindProcShort (myGlCore20, glGetCompressedTexImage)
-     // deprecated
-     || !FindProcShort (myGlCore20, glClientActiveTexture)
-     || !FindProcShort (myGlCore20, glMultiTexCoord1d)
-     || !FindProcShort (myGlCore20, glMultiTexCoord1dv)
-     || !FindProcShort (myGlCore20, glMultiTexCoord1f)
-     || !FindProcShort (myGlCore20, glMultiTexCoord1fv)
-     || !FindProcShort (myGlCore20, glMultiTexCoord1i)
-     || !FindProcShort (myGlCore20, glMultiTexCoord1iv)
-     || !FindProcShort (myGlCore20, glMultiTexCoord1s)
-     || !FindProcShort (myGlCore20, glMultiTexCoord1sv)
-     || !FindProcShort (myGlCore20, glMultiTexCoord2d)
-     || !FindProcShort (myGlCore20, glMultiTexCoord2dv)
-     || !FindProcShort (myGlCore20, glMultiTexCoord2f)
-     || !FindProcShort (myGlCore20, glMultiTexCoord2fv)
-     || !FindProcShort (myGlCore20, glMultiTexCoord2i)
-     || !FindProcShort (myGlCore20, glMultiTexCoord2iv)
-     || !FindProcShort (myGlCore20, glMultiTexCoord2s)
-     || !FindProcShort (myGlCore20, glMultiTexCoord2sv)
-     || !FindProcShort (myGlCore20, glMultiTexCoord3d)
-     || !FindProcShort (myGlCore20, glMultiTexCoord3dv)
-     || !FindProcShort (myGlCore20, glMultiTexCoord3f)
-     || !FindProcShort (myGlCore20, glMultiTexCoord3fv)
-     || !FindProcShort (myGlCore20, glMultiTexCoord3i)
-     || !FindProcShort (myGlCore20, glMultiTexCoord3iv)
-     || !FindProcShort (myGlCore20, glMultiTexCoord3s)
-     || !FindProcShort (myGlCore20, glMultiTexCoord3sv)
-     || !FindProcShort (myGlCore20, glMultiTexCoord4d)
-     || !FindProcShort (myGlCore20, glMultiTexCoord4dv)
-     || !FindProcShort (myGlCore20, glMultiTexCoord4f)
-     || !FindProcShort (myGlCore20, glMultiTexCoord4fv)
-     || !FindProcShort (myGlCore20, glMultiTexCoord4i)
-     || !FindProcShort (myGlCore20, glMultiTexCoord4iv)
-     || !FindProcShort (myGlCore20, glMultiTexCoord4s)
-     || !FindProcShort (myGlCore20, glMultiTexCoord4sv)
-     || !FindProcShort (myGlCore20, glLoadTransposeMatrixf)
-     || !FindProcShort (myGlCore20, glLoadTransposeMatrixd)
-     || !FindProcShort (myGlCore20, glMultTransposeMatrixf)
-     || !FindProcShort (myGlCore20, glMultTransposeMatrixd))
-    {
-      myGlVerMajor = 1;
-      myGlVerMinor = 2;
-      core12 = myGlCore20;
-    }
-  }
+  myGlCore20 = new OpenGl_GlCore20();
+  memset (myGlCore20, 0, sizeof(OpenGl_GlCore20)); // nullify whole structure
 
-  // initialize OpenGL 1.4 core functionality
-  if (IsGlGreaterEqual (1, 4))
+  // Check if OpenGL 1.2 core functionality is actually present
+  Standard_Boolean hasGlCore12 = IsGlGreaterEqual (1, 2)
+    && FindProcShort (myGlCore20, glBlendColor)
+    && FindProcShort (myGlCore20, glBlendEquation)
+    && FindProcShort (myGlCore20, glDrawRangeElements)
+    && FindProcShort (myGlCore20, glTexImage3D)
+    && FindProcShort (myGlCore20, glTexSubImage3D)
+    && FindProcShort (myGlCore20, glCopyTexSubImage3D);
+
+  // Check if OpenGL 1.3 core functionality is actually present
+  Standard_Boolean hasGlCore13 = IsGlGreaterEqual (1, 3)
+    && FindProcShort (myGlCore20, glActiveTexture)
+    && FindProcShort (myGlCore20, glSampleCoverage)
+    && FindProcShort (myGlCore20, glCompressedTexImage3D)
+    && FindProcShort (myGlCore20, glCompressedTexImage2D)
+    && FindProcShort (myGlCore20, glCompressedTexImage1D)
+    && FindProcShort (myGlCore20, glCompressedTexSubImage3D)
+    && FindProcShort (myGlCore20, glCompressedTexSubImage2D)
+    && FindProcShort (myGlCore20, glCompressedTexSubImage1D)
+    && FindProcShort (myGlCore20, glGetCompressedTexImage)
+     // deprecated
+    && FindProcShort (myGlCore20, glClientActiveTexture)
+    && FindProcShort (myGlCore20, glMultiTexCoord1d)
+    && FindProcShort (myGlCore20, glMultiTexCoord1dv)
+    && FindProcShort (myGlCore20, glMultiTexCoord1f)
+    && FindProcShort (myGlCore20, glMultiTexCoord1fv)
+    && FindProcShort (myGlCore20, glMultiTexCoord1i)
+    && FindProcShort (myGlCore20, glMultiTexCoord1iv)
+    && FindProcShort (myGlCore20, glMultiTexCoord1s)
+    && FindProcShort (myGlCore20, glMultiTexCoord1sv)
+    && FindProcShort (myGlCore20, glMultiTexCoord2d)
+    && FindProcShort (myGlCore20, glMultiTexCoord2dv)
+    && FindProcShort (myGlCore20, glMultiTexCoord2f)
+    && FindProcShort (myGlCore20, glMultiTexCoord2fv)
+    && FindProcShort (myGlCore20, glMultiTexCoord2i)
+    && FindProcShort (myGlCore20, glMultiTexCoord2iv)
+    && FindProcShort (myGlCore20, glMultiTexCoord2s)
+    && FindProcShort (myGlCore20, glMultiTexCoord2sv)
+    && FindProcShort (myGlCore20, glMultiTexCoord3d)
+    && FindProcShort (myGlCore20, glMultiTexCoord3dv)
+    && FindProcShort (myGlCore20, glMultiTexCoord3f)
+    && FindProcShort (myGlCore20, glMultiTexCoord3fv)
+    && FindProcShort (myGlCore20, glMultiTexCoord3i)
+    && FindProcShort (myGlCore20, glMultiTexCoord3iv)
+    && FindProcShort (myGlCore20, glMultiTexCoord3s)
+    && FindProcShort (myGlCore20, glMultiTexCoord3sv)
+    && FindProcShort (myGlCore20, glMultiTexCoord4d)
+    && FindProcShort (myGlCore20, glMultiTexCoord4dv)
+    && FindProcShort (myGlCore20, glMultiTexCoord4f)
+    && FindProcShort (myGlCore20, glMultiTexCoord4fv)
+    && FindProcShort (myGlCore20, glMultiTexCoord4i)
+    && FindProcShort (myGlCore20, glMultiTexCoord4iv)
+    && FindProcShort (myGlCore20, glMultiTexCoord4s)
+    && FindProcShort (myGlCore20, glMultiTexCoord4sv)
+    && FindProcShort (myGlCore20, glLoadTransposeMatrixf)
+    && FindProcShort (myGlCore20, glLoadTransposeMatrixd)
+    && FindProcShort (myGlCore20, glMultTransposeMatrixf)
+    && FindProcShort (myGlCore20, glMultTransposeMatrixd);
+  
+  // Check if OpenGL 1.4 core functionality is actually present
+  Standard_Boolean hasGlCore14 = IsGlGreaterEqual (1, 4)
+    && FindProcShort (myGlCore20, glBlendFuncSeparate)
+    && FindProcShort (myGlCore20, glMultiDrawArrays)
+    && FindProcShort (myGlCore20, glMultiDrawElements)
+    && FindProcShort (myGlCore20, glPointParameterf)
+    && FindProcShort (myGlCore20, glPointParameterfv)
+    && FindProcShort (myGlCore20, glPointParameteri)
+    && FindProcShort (myGlCore20, glPointParameteriv);
+
+  // Check if OpenGL 1.5 core functionality is actually present
+  Standard_Boolean hasGlCore15 = IsGlGreaterEqual (1, 5)
+    && FindProcShort (myGlCore20, glGenQueries)
+    && FindProcShort (myGlCore20, glDeleteQueries)
+    && FindProcShort (myGlCore20, glIsQuery)
+    && FindProcShort (myGlCore20, glBeginQuery)
+    && FindProcShort (myGlCore20, glEndQuery)
+    && FindProcShort (myGlCore20, glGetQueryiv)
+    && FindProcShort (myGlCore20, glGetQueryObjectiv)
+    && FindProcShort (myGlCore20, glGetQueryObjectuiv)
+    && FindProcShort (myGlCore20, glBindBuffer)
+    && FindProcShort (myGlCore20, glDeleteBuffers)
+    && FindProcShort (myGlCore20, glGenBuffers)
+    && FindProcShort (myGlCore20, glIsBuffer)
+    && FindProcShort (myGlCore20, glBufferData)
+    && FindProcShort (myGlCore20, glBufferSubData)
+    && FindProcShort (myGlCore20, glGetBufferSubData)
+    && FindProcShort (myGlCore20, glMapBuffer)
+    && FindProcShort (myGlCore20, glUnmapBuffer)
+    && FindProcShort (myGlCore20, glGetBufferParameteriv)
+    && FindProcShort (myGlCore20, glGetBufferPointerv);
+
+  // Check if OpenGL 2.0 core functionality is actually present
+  Standard_Boolean hasGlCore20 = IsGlGreaterEqual (2, 0)
+    && FindProcShort (myGlCore20, glBlendEquationSeparate)
+    && FindProcShort (myGlCore20, glDrawBuffers)
+    && FindProcShort (myGlCore20, glStencilOpSeparate)
+    && FindProcShort (myGlCore20, glStencilFuncSeparate)
+    && FindProcShort (myGlCore20, glStencilMaskSeparate)
+    && FindProcShort (myGlCore20, glAttachShader)
+    && FindProcShort (myGlCore20, glBindAttribLocation)
+    && FindProcShort (myGlCore20, glCompileShader)
+    && FindProcShort (myGlCore20, glCreateProgram)
+    && FindProcShort (myGlCore20, glCreateShader)
+    && FindProcShort (myGlCore20, glDeleteProgram)
+    && FindProcShort (myGlCore20, glDeleteShader)
+    && FindProcShort (myGlCore20, glDetachShader)
+    && FindProcShort (myGlCore20, glDisableVertexAttribArray)
+    && FindProcShort (myGlCore20, glEnableVertexAttribArray)
+    && FindProcShort (myGlCore20, glGetActiveAttrib)
+    && FindProcShort (myGlCore20, glGetActiveUniform)
+    && FindProcShort (myGlCore20, glGetAttachedShaders)
+    && FindProcShort (myGlCore20, glGetAttribLocation)
+    && FindProcShort (myGlCore20, glGetProgramiv)
+    && FindProcShort (myGlCore20, glGetProgramInfoLog)
+    && FindProcShort (myGlCore20, glGetShaderiv)
+    && FindProcShort (myGlCore20, glGetShaderInfoLog)
+    && FindProcShort (myGlCore20, glGetShaderSource)
+    && FindProcShort (myGlCore20, glGetUniformLocation)
+    && FindProcShort (myGlCore20, glGetUniformfv)
+    && FindProcShort (myGlCore20, glGetUniformiv)
+    && FindProcShort (myGlCore20, glGetVertexAttribdv)
+    && FindProcShort (myGlCore20, glGetVertexAttribfv)
+    && FindProcShort (myGlCore20, glGetVertexAttribiv)
+    && FindProcShort (myGlCore20, glGetVertexAttribPointerv)
+    && FindProcShort (myGlCore20, glIsProgram)
+    && FindProcShort (myGlCore20, glIsShader)
+    && FindProcShort (myGlCore20, glLinkProgram)
+    && FindProcShort (myGlCore20, glShaderSource)
+    && FindProcShort (myGlCore20, glUseProgram)
+    && FindProcShort (myGlCore20, glUniform1f)
+    && FindProcShort (myGlCore20, glUniform2f)
+    && FindProcShort (myGlCore20, glUniform3f)
+    && FindProcShort (myGlCore20, glUniform4f)
+    && FindProcShort (myGlCore20, glUniform1i)
+    && FindProcShort (myGlCore20, glUniform2i)
+    && FindProcShort (myGlCore20, glUniform3i)
+    && FindProcShort (myGlCore20, glUniform4i)
+    && FindProcShort (myGlCore20, glUniform1fv)
+    && FindProcShort (myGlCore20, glUniform2fv)
+    && FindProcShort (myGlCore20, glUniform3fv)
+    && FindProcShort (myGlCore20, glUniform4fv)
+    && FindProcShort (myGlCore20, glUniform1iv)
+    && FindProcShort (myGlCore20, glUniform2iv)
+    && FindProcShort (myGlCore20, glUniform3iv)
+    && FindProcShort (myGlCore20, glUniform4iv)
+    && FindProcShort (myGlCore20, glUniformMatrix2fv)
+    && FindProcShort (myGlCore20, glUniformMatrix3fv)
+    && FindProcShort (myGlCore20, glUniformMatrix4fv)
+    && FindProcShort (myGlCore20, glValidateProgram)
+    && FindProcShort (myGlCore20, glVertexAttrib1d)
+    && FindProcShort (myGlCore20, glVertexAttrib1dv)
+    && FindProcShort (myGlCore20, glVertexAttrib1f)
+    && FindProcShort (myGlCore20, glVertexAttrib1fv)
+    && FindProcShort (myGlCore20, glVertexAttrib1s)
+    && FindProcShort (myGlCore20, glVertexAttrib1sv)
+    && FindProcShort (myGlCore20, glVertexAttrib2d)
+    && FindProcShort (myGlCore20, glVertexAttrib2dv)
+    && FindProcShort (myGlCore20, glVertexAttrib2f)
+    && FindProcShort (myGlCore20, glVertexAttrib2fv)
+    && FindProcShort (myGlCore20, glVertexAttrib2s)
+    && FindProcShort (myGlCore20, glVertexAttrib2sv)
+    && FindProcShort (myGlCore20, glVertexAttrib3d)
+    && FindProcShort (myGlCore20, glVertexAttrib3dv)
+    && FindProcShort (myGlCore20, glVertexAttrib3f)
+    && FindProcShort (myGlCore20, glVertexAttrib3fv)
+    && FindProcShort (myGlCore20, glVertexAttrib3s)
+    && FindProcShort (myGlCore20, glVertexAttrib3sv)
+    && FindProcShort (myGlCore20, glVertexAttrib4Nbv)
+    && FindProcShort (myGlCore20, glVertexAttrib4Niv)
+    && FindProcShort (myGlCore20, glVertexAttrib4Nsv)
+    && FindProcShort (myGlCore20, glVertexAttrib4Nub)
+    && FindProcShort (myGlCore20, glVertexAttrib4Nubv)
+    && FindProcShort (myGlCore20, glVertexAttrib4Nuiv)
+    && FindProcShort (myGlCore20, glVertexAttrib4Nusv)
+    && FindProcShort (myGlCore20, glVertexAttrib4bv)
+    && FindProcShort (myGlCore20, glVertexAttrib4d)
+    && FindProcShort (myGlCore20, glVertexAttrib4dv)
+    && FindProcShort (myGlCore20, glVertexAttrib4f)
+    && FindProcShort (myGlCore20, glVertexAttrib4fv)
+    && FindProcShort (myGlCore20, glVertexAttrib4iv)
+    && FindProcShort (myGlCore20, glVertexAttrib4s)
+    && FindProcShort (myGlCore20, glVertexAttrib4sv)
+    && FindProcShort (myGlCore20, glVertexAttrib4ubv)
+    && FindProcShort (myGlCore20, glVertexAttrib4uiv)
+    && FindProcShort (myGlCore20, glVertexAttrib4usv)
+    && FindProcShort (myGlCore20, glVertexAttribPointer);
+
+  if (!hasGlCore12)
   {
-    if (!FindProcShort (myGlCore20, glBlendFuncSeparate)
-     || !FindProcShort (myGlCore20, glMultiDrawArrays)
-     || !FindProcShort (myGlCore20, glMultiDrawElements)
-     || !FindProcShort (myGlCore20, glPointParameterf)
-     || !FindProcShort (myGlCore20, glPointParameterfv)
-     || !FindProcShort (myGlCore20, glPointParameteri)
-     || !FindProcShort (myGlCore20, glPointParameteriv))
-    {
-      myGlVerMajor = 1;
-      myGlVerMinor = 3;
-      core12 = myGlCore20;
-      core13 = myGlCore20;
-    }
+    myGlVerMajor = 1;
+    myGlVerMinor = 1;
+    return;
   }
-
-  // initialize OpenGL 1.5 core functionality
-  if (IsGlGreaterEqual (1, 5))
-  {
-    if (!FindProcShort (myGlCore20, glGenQueries)
-     || !FindProcShort (myGlCore20, glDeleteQueries)
-     || !FindProcShort (myGlCore20, glIsQuery)
-     || !FindProcShort (myGlCore20, glBeginQuery)
-     || !FindProcShort (myGlCore20, glEndQuery)
-     || !FindProcShort (myGlCore20, glGetQueryiv)
-     || !FindProcShort (myGlCore20, glGetQueryObjectiv)
-     || !FindProcShort (myGlCore20, glGetQueryObjectuiv)
-     || !FindProcShort (myGlCore20, glBindBuffer)
-     || !FindProcShort (myGlCore20, glDeleteBuffers)
-     || !FindProcShort (myGlCore20, glGenBuffers)
-     || !FindProcShort (myGlCore20, glIsBuffer)
-     || !FindProcShort (myGlCore20, glBufferData)
-     || !FindProcShort (myGlCore20, glBufferSubData)
-     || !FindProcShort (myGlCore20, glGetBufferSubData)
-     || !FindProcShort (myGlCore20, glMapBuffer)
-     || !FindProcShort (myGlCore20, glUnmapBuffer)
-     || !FindProcShort (myGlCore20, glGetBufferParameteriv)
-     || !FindProcShort (myGlCore20, glGetBufferPointerv))
-    {
-      myGlVerMajor = 1;
-      myGlVerMinor = 4;
-      core12 = myGlCore20;
-      core13 = myGlCore20;
-      core14 = myGlCore20;
-    }
+  else
+  {
+    core12 = myGlCore20;
   }
-
-  // initialize OpenGL 2.0 core functionality
-  if (IsGlGreaterEqual (2, 0))
-  {
-    if (!FindProcShort (myGlCore20, glBlendEquationSeparate)
-     || !FindProcShort (myGlCore20, glDrawBuffers)
-     || !FindProcShort (myGlCore20, glStencilOpSeparate)
-     || !FindProcShort (myGlCore20, glStencilFuncSeparate)
-     || !FindProcShort (myGlCore20, glStencilMaskSeparate)
-     || !FindProcShort (myGlCore20, glAttachShader)
-     || !FindProcShort (myGlCore20, glBindAttribLocation)
-     || !FindProcShort (myGlCore20, glCompileShader)
-     || !FindProcShort (myGlCore20, glCreateProgram)
-     || !FindProcShort (myGlCore20, glCreateShader)
-     || !FindProcShort (myGlCore20, glDeleteProgram)
-     || !FindProcShort (myGlCore20, glDeleteShader)
-     || !FindProcShort (myGlCore20, glDetachShader)
-     || !FindProcShort (myGlCore20, glDisableVertexAttribArray)
-     || !FindProcShort (myGlCore20, glEnableVertexAttribArray)
-     || !FindProcShort (myGlCore20, glGetActiveAttrib)
-     || !FindProcShort (myGlCore20, glGetActiveUniform)
-     || !FindProcShort (myGlCore20, glGetAttachedShaders)
-     || !FindProcShort (myGlCore20, glGetAttribLocation)
-     || !FindProcShort (myGlCore20, glGetProgramiv)
-     || !FindProcShort (myGlCore20, glGetProgramInfoLog)
-     || !FindProcShort (myGlCore20, glGetShaderiv)
-     || !FindProcShort (myGlCore20, glGetShaderInfoLog)
-     || !FindProcShort (myGlCore20, glGetShaderSource)
-     || !FindProcShort (myGlCore20, glGetUniformLocation)
-     || !FindProcShort (myGlCore20, glGetUniformfv)
-     || !FindProcShort (myGlCore20, glGetUniformiv)
-     || !FindProcShort (myGlCore20, glGetVertexAttribdv)
-     || !FindProcShort (myGlCore20, glGetVertexAttribfv)
-     || !FindProcShort (myGlCore20, glGetVertexAttribiv)
-     || !FindProcShort (myGlCore20, glGetVertexAttribPointerv)
-     || !FindProcShort (myGlCore20, glIsProgram)
-     || !FindProcShort (myGlCore20, glIsShader)
-     || !FindProcShort (myGlCore20, glLinkProgram)
-     || !FindProcShort (myGlCore20, glShaderSource)
-     || !FindProcShort (myGlCore20, glUseProgram)
-     || !FindProcShort (myGlCore20, glUniform1f)
-     || !FindProcShort (myGlCore20, glUniform2f)
-     || !FindProcShort (myGlCore20, glUniform3f)
-     || !FindProcShort (myGlCore20, glUniform4f)
-     || !FindProcShort (myGlCore20, glUniform1i)
-     || !FindProcShort (myGlCore20, glUniform2i)
-     || !FindProcShort (myGlCore20, glUniform3i)
-     || !FindProcShort (myGlCore20, glUniform4i)
-     || !FindProcShort (myGlCore20, glUniform1fv)
-     || !FindProcShort (myGlCore20, glUniform2fv)
-     || !FindProcShort (myGlCore20, glUniform3fv)
-     || !FindProcShort (myGlCore20, glUniform4fv)
-     || !FindProcShort (myGlCore20, glUniform1iv)
-     || !FindProcShort (myGlCore20, glUniform2iv)
-     || !FindProcShort (myGlCore20, glUniform3iv)
-     || !FindProcShort (myGlCore20, glUniform4iv)
-     || !FindProcShort (myGlCore20, glUniformMatrix2fv)
-     || !FindProcShort (myGlCore20, glUniformMatrix3fv)
-     || !FindProcShort (myGlCore20, glUniformMatrix4fv)
-     || !FindProcShort (myGlCore20, glValidateProgram)
-     || !FindProcShort (myGlCore20, glVertexAttrib1d)
-     || !FindProcShort (myGlCore20, glVertexAttrib1dv)
-     || !FindProcShort (myGlCore20, glVertexAttrib1f)
-     || !FindProcShort (myGlCore20, glVertexAttrib1fv)
-     || !FindProcShort (myGlCore20, glVertexAttrib1s)
-     || !FindProcShort (myGlCore20, glVertexAttrib1sv)
-     || !FindProcShort (myGlCore20, glVertexAttrib2d)
-     || !FindProcShort (myGlCore20, glVertexAttrib2dv)
-     || !FindProcShort (myGlCore20, glVertexAttrib2f)
-     || !FindProcShort (myGlCore20, glVertexAttrib2fv)
-     || !FindProcShort (myGlCore20, glVertexAttrib2s)
-     || !FindProcShort (myGlCore20, glVertexAttrib2sv)
-     || !FindProcShort (myGlCore20, glVertexAttrib3d)
-     || !FindProcShort (myGlCore20, glVertexAttrib3dv)
-     || !FindProcShort (myGlCore20, glVertexAttrib3f)
-     || !FindProcShort (myGlCore20, glVertexAttrib3fv)
-     || !FindProcShort (myGlCore20, glVertexAttrib3s)
-     || !FindProcShort (myGlCore20, glVertexAttrib3sv)
-     || !FindProcShort (myGlCore20, glVertexAttrib4Nbv)
-     || !FindProcShort (myGlCore20, glVertexAttrib4Niv)
-     || !FindProcShort (myGlCore20, glVertexAttrib4Nsv)
-     || !FindProcShort (myGlCore20, glVertexAttrib4Nub)
-     || !FindProcShort (myGlCore20, glVertexAttrib4Nubv)
-     || !FindProcShort (myGlCore20, glVertexAttrib4Nuiv)
-     || !FindProcShort (myGlCore20, glVertexAttrib4Nusv)
-     || !FindProcShort (myGlCore20, glVertexAttrib4bv)
-     || !FindProcShort (myGlCore20, glVertexAttrib4d)
-     || !FindProcShort (myGlCore20, glVertexAttrib4dv)
-     || !FindProcShort (myGlCore20, glVertexAttrib4f)
-     || !FindProcShort (myGlCore20, glVertexAttrib4fv)
-     || !FindProcShort (myGlCore20, glVertexAttrib4iv)
-     || !FindProcShort (myGlCore20, glVertexAttrib4s)
-     || !FindProcShort (myGlCore20, glVertexAttrib4sv)
-     || !FindProcShort (myGlCore20, glVertexAttrib4ubv)
-     || !FindProcShort (myGlCore20, glVertexAttrib4uiv)
-     || !FindProcShort (myGlCore20, glVertexAttrib4usv)
-     || !FindProcShort (myGlCore20, glVertexAttribPointer))
-    {
-      myGlVerMajor = 1;
-      myGlVerMinor = 5;
-      core12 = myGlCore20;
-      core13 = myGlCore20;
-      core14 = myGlCore20;
-      core15 = myGlCore20;
-    }
+  if (!hasGlCore13)
+  {
+    myGlVerMajor = 1;
+    myGlVerMinor = 2;
+    return;
   }
-
-  if (IsGlGreaterEqual (2, 0))
+  else
   {
-    core12 = myGlCore20;
     core13 = myGlCore20;
+  }
+  if(!hasGlCore14)
+  {
+    myGlVerMajor = 1;
+    myGlVerMinor = 3;
+    return;
+  }
+  else
+  {
     core14 = myGlCore20;
+  }
+  if(!hasGlCore15)
+  {
+    myGlVerMajor = 1;
+    myGlVerMinor = 4;
+    return;
+  }
+  else
+  {
     core15 = myGlCore20;
+  }
+  if(!hasGlCore20)
+  {
+    myGlVerMajor = 1;
+    myGlVerMinor = 5;
+  }
+  else
+  {
     core20 = myGlCore20;
   }
 }
@@ -889,7 +1056,8 @@ Standard_Boolean OpenGl_Context::ShareResource (const TCollection_AsciiString& t
 // function : ReleaseResource
 // purpose  :
 // =======================================================================
-void OpenGl_Context::ReleaseResource (const TCollection_AsciiString& theKey)
+void OpenGl_Context::ReleaseResource (const TCollection_AsciiString& theKey,
+                                      const Standard_Boolean         theToDelay)
 {
   if (!mySharedResources->IsBound (theKey))
   {
@@ -901,8 +1069,15 @@ void OpenGl_Context::ReleaseResource (const TCollection_AsciiString& theKey)
     return;
   }
 
-  aRes->Release (this);
-  mySharedResources->UnBind (theKey);
+  if (theToDelay)
+  {
+    myDelayed->Bind (theKey, 1);
+  }
+  else
+  {
+    aRes->Release (this);
+    mySharedResources->UnBind (theKey);
+  }
 }
 
 // =======================================================================
@@ -921,9 +1096,48 @@ void OpenGl_Context::DelayedRelease (Handle(OpenGl_Resource)& theResource)
 // =======================================================================
 void OpenGl_Context::ReleaseDelayed()
 {
+  // release queued elements
   while (!myReleaseQueue->IsEmpty())
   {
     myReleaseQueue->Front()->Release (this);
     myReleaseQueue->Pop();
   }
+
+  // release delayed shared resoruces
+  NCollection_Vector<TCollection_AsciiString> aDeadList;
+  for (NCollection_DataMap<TCollection_AsciiString, Standard_Integer>::Iterator anIter (*myDelayed);
+       anIter.More(); anIter.Next())
+  {
+    if (++anIter.ChangeValue() <= 2)
+    {
+      continue; // postpone release one more frame to ensure noone use it periodically
+    }
+
+    const TCollection_AsciiString& aKey = anIter.Key();
+    if (!mySharedResources->IsBound (aKey))
+    {
+      // mixed unshared strategy delayed/undelayed was used!
+      aDeadList.Append (aKey);
+      continue;
+    }
+
+    Handle(OpenGl_Resource)& aRes = mySharedResources->ChangeFind (aKey);
+    if (aRes->GetRefCount() > 1)
+    {
+      // should be only 1 instance in mySharedResources
+      // if not - resource was reused again
+      aDeadList.Append (aKey);
+      continue;
+    }
+
+    // release resource if no one requiested it more than 2 redraw calls
+    aRes->Release (this);
+    mySharedResources->UnBind (aKey);
+    aDeadList.Append (aKey);
+  }
+
+  for (Standard_Integer anIter = 0; anIter < aDeadList.Length(); ++anIter)
+  {
+    myDelayed->UnBind (aDeadList.Value (anIter));
+  }
 }