0025158: Visualization, OpenGl_Context - support EGL as alternative to WGL and GLX
[occt.git] / src / OpenGl / OpenGl_Context.cxx
1 // Created on: 2012-01-26
2 // Created by: Kirill GAVRILOV
3 // Copyright (c) 2012-2014 OPEN CASCADE SAS
4 //
5 // This file is part of Open CASCADE Technology software library.
6 //
7 // This library is free software; you can redistribute it and/or modify it under
8 // the terms of the GNU Lesser General Public License version 2.1 as published
9 // by the Free Software Foundation, with special exception defined in the file
10 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
11 // distribution for complete text of the license and disclaimer of any warranty.
12 //
13 // Alternatively, this file may be used under the terms of Open CASCADE
14 // commercial license or contractual agreement.
15
16 #if defined(_WIN32)
17   #include <windows.h>
18 #endif
19
20 #include <OpenGl_Context.hxx>
21
22 #include <OpenGl_ArbTBO.hxx>
23 #include <OpenGl_ArbIns.hxx>
24 #include <OpenGl_ArbDbg.hxx>
25 #include <OpenGl_ArbFBO.hxx>
26 #include <OpenGl_ExtGS.hxx>
27 #include <OpenGl_GlCore20.hxx>
28 #include <OpenGl_ShaderManager.hxx>
29
30 #include <Message_Messenger.hxx>
31
32 #include <NCollection_Vector.hxx>
33
34 #include <Standard_ProgramError.hxx>
35
36 #if defined(HAVE_EGL)
37   #include <EGL/egl.h>
38   #ifdef _MSC_VER
39     #pragma comment(lib, "libEGL.lib")
40   #endif
41 #elif defined(_WIN32)
42   //
43 #elif defined(__APPLE__) && !defined(MACOSX_USE_GLX)
44   #include <dlfcn.h>
45 #else
46   #include <GL/glx.h> // glXGetProcAddress()
47 #endif
48
49 // GL_NVX_gpu_memory_info
50 #ifndef GL_GPU_MEMORY_INFO_DEDICATED_VIDMEM_NVX
51   enum
52   {
53     GL_GPU_MEMORY_INFO_DEDICATED_VIDMEM_NVX         = 0x9047,
54     GL_GPU_MEMORY_INFO_TOTAL_AVAILABLE_MEMORY_NVX   = 0x9048,
55     GL_GPU_MEMORY_INFO_CURRENT_AVAILABLE_VIDMEM_NVX = 0x9049,
56     GL_GPU_MEMORY_INFO_EVICTION_COUNT_NVX           = 0x904A,
57     GL_GPU_MEMORY_INFO_EVICTED_MEMORY_NVX           = 0x904B
58   };
59 #endif
60
61 IMPLEMENT_STANDARD_HANDLE (OpenGl_Context, Standard_Transient)
62 IMPLEMENT_STANDARD_RTTIEXT(OpenGl_Context, Standard_Transient)
63
64 namespace
65 {
66   static const Handle(OpenGl_Resource) NULL_GL_RESOURCE;
67 }
68
69 // =======================================================================
70 // function : OpenGl_Context
71 // purpose  :
72 // =======================================================================
73 OpenGl_Context::OpenGl_Context (const Handle(OpenGl_Caps)& theCaps)
74 : core11     (NULL),
75   core11fwd  (NULL),
76   core15     (NULL),
77   core15fwd  (NULL),
78   core20     (NULL),
79   core20fwd  (NULL),
80   core32     (NULL),
81   core32back (NULL),
82   core41     (NULL),
83   core41back (NULL),
84   core42     (NULL),
85   core42back (NULL),
86   core43     (NULL),
87   core43back (NULL),
88   core44     (NULL),
89   core44back (NULL),
90   caps   (!theCaps.IsNull() ? theCaps : new OpenGl_Caps()),
91   arbNPTW(Standard_False),
92   arbTBO (NULL),
93   arbIns (NULL),
94   arbDbg (NULL),
95   arbFBO (NULL),
96   extGS  (NULL),
97   extBgra(Standard_False),
98   extAnis(Standard_False),
99   extPDS (Standard_False),
100   atiMem (Standard_False),
101   nvxMem (Standard_False),
102   mySharedResources (new OpenGl_ResourcesMap()),
103   myDelayed         (new OpenGl_DelayReleaseMap()),
104   myUnusedResources (new OpenGl_ResourcesStack()),
105   myClippingState (),
106   myGlLibHandle (NULL),
107   myFuncs (new OpenGl_GlFunctions()),
108   myAnisoMax   (1),
109   myMaxTexDim  (1024),
110   myMaxClipPlanes (6),
111   myGlVerMajor (0),
112   myGlVerMinor (0),
113   myRenderMode (GL_RENDER),
114   myIsInitialized (Standard_False),
115   myIsStereoBuffers (Standard_False),
116   myDrawBuffer (0)
117 {
118 #if defined(MAC_OS_X_VERSION_10_3) && !defined(MACOSX_USE_GLX)
119   // Vendors can not extend functionality on this system
120   // and developers are limited to OpenGL support provided by Mac OS X SDK.
121   // We retrieve function pointers from system library
122   // to generalize extensions support on all platforms.
123   // In this way we also reach binary compatibility benefit between OS releases
124   // if some newest functionality is optionally used.
125   // Notice that GL version / extension availability checks are required
126   // because function pointers may be available but not functionality itself
127   // (depends on renderer).
128   myGlLibHandle = dlopen ("/System/Library/Frameworks/OpenGL.framework/Versions/Current/OpenGL", RTLD_LAZY);
129 #endif
130   memset (myFuncs.operator->(), 0, sizeof(OpenGl_GlFunctions));
131   myShaderManager = new OpenGl_ShaderManager (this);
132 }
133
134 // =======================================================================
135 // function : ~OpenGl_Context
136 // purpose  :
137 // =======================================================================
138 OpenGl_Context::~OpenGl_Context()
139 {
140   // release clean up queue
141   ReleaseDelayed();
142
143   // release shared resources if any
144   if (((const Handle(Standard_Transient)& )mySharedResources)->GetRefCount() <= 1)
145   {
146     myShaderManager.Nullify();
147     for (NCollection_DataMap<TCollection_AsciiString, Handle(OpenGl_Resource)>::Iterator anIter (*mySharedResources);
148          anIter.More(); anIter.Next())
149     {
150       anIter.Value()->Release (this);
151     }
152   }
153   else
154   {
155     myShaderManager->SetContext (NULL);
156   }
157   mySharedResources.Nullify();
158   myDelayed.Nullify();
159
160   if (arbDbg != NULL
161    && caps->contextDebug
162    && IsValid())
163   {
164     // reset callback
165     void* aPtr = NULL;
166     glGetPointerv (GL_DEBUG_CALLBACK_USER_PARAM_ARB, &aPtr);
167     if (aPtr == this)
168     {
169       arbDbg->glDebugMessageCallbackARB (NULL, NULL);
170     }
171   }
172 }
173
174 // =======================================================================
175 // function : MaxDegreeOfAnisotropy
176 // purpose  :
177 // =======================================================================
178 Standard_Integer OpenGl_Context::MaxDegreeOfAnisotropy() const
179 {
180   return myAnisoMax;
181 }
182
183 // =======================================================================
184 // function : MaxTextureSize
185 // purpose  :
186 // =======================================================================
187 Standard_Integer OpenGl_Context::MaxTextureSize() const
188 {
189   return myMaxTexDim;
190 }
191
192 // =======================================================================
193 // function : MaxClipPlanes
194 // purpose  :
195 // =======================================================================
196 Standard_Integer OpenGl_Context::MaxClipPlanes() const
197 {
198   return myMaxClipPlanes;
199 }
200
201 // =======================================================================
202 // function : SetDrawBufferLeft
203 // purpose  :
204 // =======================================================================
205 void OpenGl_Context::SetDrawBufferLeft()
206 {
207   switch (myDrawBuffer)
208   {
209     case GL_BACK_RIGHT :
210     case GL_BACK :
211       glDrawBuffer (GL_BACK_LEFT);
212       myDrawBuffer = GL_BACK_LEFT;
213       break;
214
215     case GL_FRONT_RIGHT :
216     case GL_FRONT :
217       glDrawBuffer (GL_FRONT_LEFT);
218       myDrawBuffer = GL_FRONT_LEFT;
219       break;
220
221     case GL_FRONT_AND_BACK :
222     case GL_RIGHT :
223       glDrawBuffer (GL_LEFT);
224       myDrawBuffer = GL_LEFT;
225       break;
226   }
227 }
228
229 // =======================================================================
230 // function : SetDrawBufferRight
231 // purpose  :
232 // =======================================================================
233 void OpenGl_Context::SetDrawBufferRight()
234 {
235   switch (myDrawBuffer)
236   {
237     case GL_BACK_LEFT :
238     case GL_BACK :
239       glDrawBuffer (GL_BACK_RIGHT);
240       myDrawBuffer = GL_BACK_RIGHT;
241       break;
242
243     case GL_FRONT_LEFT :
244     case GL_FRONT :
245       glDrawBuffer (GL_FRONT_RIGHT);
246       myDrawBuffer = GL_FRONT_RIGHT;
247       break;
248
249     case GL_FRONT_AND_BACK :
250     case GL_LEFT :
251       glDrawBuffer (GL_RIGHT);
252       myDrawBuffer = GL_RIGHT;
253       break;
254   }
255 }
256
257 // =======================================================================
258 // function : SetDrawBufferMono
259 // purpose  :
260 // =======================================================================
261 void OpenGl_Context::SetDrawBufferMono()
262 {
263   switch (myDrawBuffer)
264   {
265     case GL_BACK_LEFT :
266     case GL_BACK_RIGHT :
267       glDrawBuffer (GL_BACK);
268       myDrawBuffer = GL_BACK;
269       break;
270
271     case GL_FRONT_LEFT :
272     case GL_FRONT_RIGHT :
273       glDrawBuffer (GL_FRONT);
274       myDrawBuffer = GL_FRONT;
275       break;
276
277     case GL_LEFT :
278     case GL_RIGHT :
279       glDrawBuffer (GL_FRONT_AND_BACK);
280       myDrawBuffer = GL_FRONT_AND_BACK;
281       break;
282   }
283 }
284
285 // =======================================================================
286 // function : FetchState
287 // purpose  :
288 // =======================================================================
289 void OpenGl_Context::FetchState()
290 {
291   // cache feedback mode state
292   glGetIntegerv (GL_RENDER_MODE, &myRenderMode);
293
294   // cache draw buffer state
295   glGetIntegerv (GL_DRAW_BUFFER, &myDrawBuffer);
296 }
297
298 // =======================================================================
299 // function : Share
300 // purpose  :
301 // =======================================================================
302 void OpenGl_Context::Share (const Handle(OpenGl_Context)& theShareCtx)
303 {
304   if (!theShareCtx.IsNull())
305   {
306     mySharedResources = theShareCtx->mySharedResources;
307     myDelayed         = theShareCtx->myDelayed;
308     myUnusedResources = theShareCtx->myUnusedResources;
309     myShaderManager   = theShareCtx->myShaderManager;
310   }
311 }
312
313 #if !defined(__APPLE__) || defined(MACOSX_USE_GLX)
314
315 // =======================================================================
316 // function : IsCurrent
317 // purpose  :
318 // =======================================================================
319 Standard_Boolean OpenGl_Context::IsCurrent() const
320 {
321 #if defined(HAVE_EGL)
322   if ((EGLDisplay )myDisplay  == EGL_NO_DISPLAY
323    || (EGLSurface )myWindow   == EGL_NO_SURFACE
324    || (EGLContext )myGContext == EGL_NO_CONTEXT)
325   {
326     return Standard_False;
327   }
328
329   return (((EGLDisplay )myDisplay  == eglGetCurrentDisplay())
330        && ((EGLContext )myGContext == eglGetCurrentContext())
331        && ((EGLSurface )myWindow   == eglGetCurrentSurface (EGL_DRAW)));
332 #elif defined(_WIN32)
333   if (myWindowDC == NULL || myGContext == NULL)
334   {
335     return Standard_False;
336   }
337   return (( (HDC )myWindowDC == wglGetCurrentDC())
338       && ((HGLRC )myGContext == wglGetCurrentContext()));
339 #else
340   if (myDisplay == NULL || myWindow == 0 || myGContext == 0)
341   {
342     return Standard_False;
343   }
344
345   return (   ((Display* )myDisplay  == glXGetCurrentDisplay())
346        &&  ((GLXContext )myGContext == glXGetCurrentContext())
347        && ((GLXDrawable )myWindow   == glXGetCurrentDrawable()));
348 #endif
349 }
350
351 // =======================================================================
352 // function : MakeCurrent
353 // purpose  :
354 // =======================================================================
355 Standard_Boolean OpenGl_Context::MakeCurrent()
356 {
357 #if defined(HAVE_EGL)
358   if ((EGLDisplay )myDisplay  == EGL_NO_DISPLAY
359    || (EGLSurface )myWindow   == EGL_NO_SURFACE
360    || (EGLContext )myGContext == EGL_NO_CONTEXT)
361   {
362     Standard_ProgramError_Raise_if (myIsInitialized, "OpenGl_Context::Init() should be called before!");
363     return Standard_False;
364   }
365
366   if (eglMakeCurrent ((EGLDisplay )myDisplay, (EGLSurface )myWindow, (EGLSurface )myWindow, (EGLContext )myGContext) != EGL_TRUE)
367   {
368     // if there is no current context it might be impossible to use glGetError() correctly
369     PushMessage (GL_DEBUG_SOURCE_WINDOW_SYSTEM_ARB, GL_DEBUG_TYPE_ERROR_ARB, 0, GL_DEBUG_SEVERITY_HIGH_ARB,
370                  "eglMakeCurrent() has failed!");
371     myIsInitialized = Standard_False;
372     return Standard_False;
373   }
374 #elif defined(_WIN32)
375   if (myWindowDC == NULL || myGContext == NULL)
376   {
377     Standard_ProgramError_Raise_if (myIsInitialized, "OpenGl_Context::Init() should be called before!");
378     return Standard_False;
379   }
380
381   // technically it should be safe to activate already bound GL context
382   // however some drivers (Intel etc.) may FAIL doing this for unknown reason
383   if (IsCurrent())
384   {
385     myShaderManager->SetContext (this);
386     return Standard_True;
387   }
388   else if (wglMakeCurrent ((HDC )myWindowDC, (HGLRC )myGContext) != TRUE)
389   {
390     // notice that glGetError() couldn't be used here!
391     wchar_t* aMsgBuff = NULL;
392     DWORD anErrorCode = GetLastError();
393     FormatMessageW (FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
394                     NULL, anErrorCode, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (wchar_t* )&aMsgBuff, 0, NULL);
395     TCollection_ExtendedString aMsg ("wglMakeCurrent() has failed. ");
396     if (aMsgBuff != NULL)
397     {
398       aMsg += (Standard_ExtString )aMsgBuff;
399       LocalFree (aMsgBuff);
400     }
401     PushMessage (GL_DEBUG_SOURCE_WINDOW_SYSTEM_ARB, GL_DEBUG_TYPE_ERROR_ARB, (unsigned int )anErrorCode, GL_DEBUG_SEVERITY_HIGH_ARB, aMsg);
402     myIsInitialized = Standard_False;
403     return Standard_False;
404   }
405 #else
406   if (myDisplay == NULL || myWindow == 0 || myGContext == 0)
407   {
408     Standard_ProgramError_Raise_if (myIsInitialized, "OpenGl_Context::Init() should be called before!");
409     return Standard_False;
410   }
411
412   if (!glXMakeCurrent ((Display* )myDisplay, (GLXDrawable )myWindow, (GLXContext )myGContext))
413   {
414     // if there is no current context it might be impossible to use glGetError() correctly
415     PushMessage (GL_DEBUG_SOURCE_WINDOW_SYSTEM_ARB, GL_DEBUG_TYPE_ERROR_ARB, 0, GL_DEBUG_SEVERITY_HIGH_ARB,
416                  "glXMakeCurrent() has failed!");
417     myIsInitialized = Standard_False;
418     return Standard_False;
419   }
420 #endif
421   myShaderManager->SetContext (this);
422   return Standard_True;
423 }
424
425 // =======================================================================
426 // function : SwapBuffers
427 // purpose  :
428 // =======================================================================
429 void OpenGl_Context::SwapBuffers()
430 {
431 #if defined(HAVE_EGL)
432   if ((EGLSurface )myWindow != EGL_NO_SURFACE)
433   {
434     eglSwapBuffers ((EGLDisplay )myDisplay, (EGLSurface )myWindow);
435   }
436 #elif defined(_WIN32)
437   if ((HDC )myWindowDC != NULL)
438   {
439     ::SwapBuffers ((HDC )myWindowDC);
440     glFlush();
441   }
442 #else
443   if ((Display* )myDisplay != NULL)
444   {
445     glXSwapBuffers ((Display* )myDisplay, (GLXDrawable )myWindow);
446   }
447 #endif
448 }
449
450 #endif // __APPLE__
451
452 // =======================================================================
453 // function : findProc
454 // purpose  :
455 // =======================================================================
456 void* OpenGl_Context::findProc (const char* theFuncName)
457 {
458 #if defined(HAVE_EGL)
459   return (void* )eglGetProcAddress (theFuncName);
460 #elif defined(_WIN32)
461   return wglGetProcAddress (theFuncName);
462 #elif defined(__APPLE__) && !defined(MACOSX_USE_GLX)
463   return (myGlLibHandle != NULL) ? dlsym (myGlLibHandle, theFuncName) : NULL;
464 #else
465   return (void* )glXGetProcAddress ((const GLubyte* )theFuncName);
466 #endif
467 }
468
469 // =======================================================================
470 // function : CheckExtension
471 // purpose  :
472 // =======================================================================
473 Standard_Boolean OpenGl_Context::CheckExtension (const char* theExtName) const
474 {
475   if (theExtName  == NULL)
476   {
477     std::cerr << "CheckExtension called with NULL string!\n";
478     return Standard_False;
479   }
480
481   // available since OpenGL 3.0
482   // and the ONLY way to check extensions with OpenGL 3.1+ core profile
483   /**if (IsGlGreaterEqual (3, 0))
484   {
485     GLint anExtNb = 0;
486     glGetIntegerv (GL_NUM_EXTENSIONS, &anExtNb);
487     for (GLint anIter = 0; anIter < anExtNb; ++anIter)
488     {
489       const char* anExtension = (const char* )core30->glGetStringi (GL_EXTENSIONS, (GLuint )anIter);
490       if (anExtension[anExtNameLen] == '\0' &&
491           strncmp (anExtension, theExtName, anExtNameLen) == 0)
492       {
493         return Standard_True;
494       }
495     }
496     return Standard_False;
497   }*/
498
499   // use old way with huge string for all extensions
500   const char* anExtString = (const char* )glGetString (GL_EXTENSIONS);
501   if (anExtString == NULL)
502   {
503     Messenger()->Send ("TKOpenGL: glGetString (GL_EXTENSIONS) has returned NULL! No GL context?", Message_Warning);
504     return Standard_False;
505   }
506   return CheckExtension (anExtString, theExtName);
507 }
508
509 // =======================================================================
510 // function : CheckExtension
511 // purpose  :
512 // =======================================================================
513 Standard_Boolean OpenGl_Context::CheckExtension (const char* theExtString,
514                                                  const char* theExtName)
515 {
516   if (theExtString == NULL)
517   {
518     return Standard_False;
519   }
520
521   // Search for theExtName in the extensions string.
522   // Use of strstr() is not sufficient because extension names can be prefixes of other extension names.
523   char* aPtrIter = (char* )theExtString;
524   const char*  aPtrEnd      = aPtrIter + strlen (theExtString);
525   const size_t anExtNameLen = strlen (theExtName);
526   while (aPtrIter < aPtrEnd)
527   {
528     const size_t n = strcspn (aPtrIter, " ");
529     if ((n == anExtNameLen) && (strncmp (aPtrIter, theExtName, anExtNameLen) == 0))
530     {
531       return Standard_True;
532     }
533     aPtrIter += (n + 1);
534   }
535   return Standard_False;
536 }
537
538 #if !defined(__APPLE__) || defined(MACOSX_USE_GLX)
539
540 // =======================================================================
541 // function : Init
542 // purpose  :
543 // =======================================================================
544 Standard_Boolean OpenGl_Context::Init()
545 {
546   if (myIsInitialized)
547   {
548     return Standard_True;
549   }
550
551 #if defined(HAVE_EGL)
552   myDisplay  = (Aspect_Display )eglGetCurrentDisplay();
553   myGContext = (Aspect_RenderingContext )eglGetCurrentContext();
554   myWindow   = (Aspect_Drawable )eglGetCurrentSurface(EGL_DRAW);
555 #elif defined(_WIN32)
556   myWindowDC = (Aspect_Handle )wglGetCurrentDC();
557   myGContext = (Aspect_RenderingContext )wglGetCurrentContext();
558 #else
559   myDisplay  = (Aspect_Display )glXGetCurrentDisplay();
560   myGContext = (Aspect_RenderingContext )glXGetCurrentContext();
561   myWindow   = (Aspect_Drawable )glXGetCurrentDrawable();
562 #endif
563   if (myGContext == NULL)
564   {
565     return Standard_False;
566   }
567
568   init();
569   myIsInitialized = Standard_True;
570   return Standard_True;
571 }
572
573 #endif // __APPLE__
574
575 // =======================================================================
576 // function : Init
577 // purpose  :
578 // =======================================================================
579 #if defined(HAVE_EGL)
580 Standard_Boolean OpenGl_Context::Init (const Aspect_Drawable         theEglSurface,
581                                        const Aspect_Display          theEglDisplay,
582                                        const Aspect_RenderingContext theEglContext)
583 #elif defined(_WIN32)
584 Standard_Boolean OpenGl_Context::Init (const Aspect_Handle           theWindow,
585                                        const Aspect_Handle           theWindowDC,
586                                        const Aspect_RenderingContext theGContext)
587 #elif defined(__APPLE__) && !defined(MACOSX_USE_GLX)
588 Standard_Boolean OpenGl_Context::Init (const void*                   theGContext)
589 #else
590 Standard_Boolean OpenGl_Context::Init (const Aspect_Drawable         theWindow,
591                                        const Aspect_Display          theDisplay,
592                                        const Aspect_RenderingContext theGContext)
593 #endif
594 {
595   Standard_ProgramError_Raise_if (myIsInitialized, "OpenGl_Context::Init() should be called only once!");
596 #if defined(HAVE_EGL)
597   myWindow   = theEglSurface;
598   myGContext = theEglContext;
599   myDisplay  = theEglDisplay;
600 #elif defined(_WIN32)
601   myWindow   = theWindow;
602   myGContext = theGContext;
603   myWindowDC = theWindowDC;
604 #elif defined(__APPLE__) && !defined(MACOSX_USE_GLX)
605   myGContext = (void* )theGContext;
606 #else
607   myWindow   = theWindow;
608   myGContext = theGContext;
609   myDisplay  = theDisplay;
610 #endif
611   if (myGContext == NULL || !MakeCurrent())
612   {
613     return Standard_False;
614   }
615
616   init();
617   myIsInitialized = Standard_True;
618   return Standard_True;
619 }
620
621 // =======================================================================
622 // function : ResetErrors
623 // purpose  :
624 // =======================================================================
625 void OpenGl_Context::ResetErrors()
626 {
627   while (glGetError() != GL_NO_ERROR)
628   {
629     //
630   }
631 }
632
633 // =======================================================================
634 // function : readGlVersion
635 // purpose  :
636 // =======================================================================
637 void OpenGl_Context::readGlVersion()
638 {
639   // reset values
640   myGlVerMajor = 0;
641   myGlVerMinor = 0;
642
643   // available since OpenGL 3.0
644   GLint aMajor = 0, aMinor = 0;
645   glGetIntegerv (GL_MAJOR_VERSION, &aMajor);
646   glGetIntegerv (GL_MINOR_VERSION, &aMinor);
647   // glGetError() sometimes does not report an error here even if
648   // GL does not know GL_MAJOR_VERSION and GL_MINOR_VERSION constants.
649   // This happens on some rendereres like e.g. Cygwin MESA.
650   // Thus checking additionally if GL has put anything to
651   // the output variables.
652   if (glGetError() == GL_NO_ERROR && aMajor != 0 && aMinor != 0)
653   {
654     myGlVerMajor = aMajor;
655     myGlVerMinor = aMinor;
656     return;
657   }
658   ResetErrors();
659
660   // Read version string.
661   // Notice that only first two numbers splitted by point '2.1 XXXXX' are significant.
662   // Following trash (after space) is vendor-specific.
663   // New drivers also returns micro version of GL like '3.3.0' which has no meaning
664   // and should be considered as vendor-specific too.
665   const char* aVerStr = (const char* )glGetString (GL_VERSION);
666   if (aVerStr == NULL || *aVerStr == '\0')
667   {
668     // invalid GL context
669     return;
670   }
671
672   // parse string for major number
673   char aMajorStr[32];
674   char aMinorStr[32];
675   size_t aMajIter = 0;
676   while (aVerStr[aMajIter] >= '0' && aVerStr[aMajIter] <= '9')
677   {
678     ++aMajIter;
679   }
680   if (aMajIter == 0 || aMajIter >= sizeof(aMajorStr))
681   {
682     return;
683   }
684   memcpy (aMajorStr, aVerStr, aMajIter);
685   aMajorStr[aMajIter] = '\0';
686
687   // parse string for minor number
688   aVerStr += aMajIter + 1;
689   size_t aMinIter = 0;
690   while (aVerStr[aMinIter] >= '0' && aVerStr[aMinIter] <= '9')
691   {
692     ++aMinIter;
693   }
694   if (aMinIter == 0 || aMinIter >= sizeof(aMinorStr))
695   {
696     return;
697   }
698   memcpy (aMinorStr, aVerStr, aMinIter);
699   aMinorStr[aMinIter] = '\0';
700
701   // read numbers
702   myGlVerMajor = atoi (aMajorStr);
703   myGlVerMinor = atoi (aMinorStr);
704
705   if (myGlVerMajor <= 0)
706   {
707     myGlVerMajor = 0;
708     myGlVerMinor = 0;
709   }
710 }
711
712 static Standard_CString THE_DBGMSG_UNKNOWN = "UNKNOWN";
713 static Standard_CString THE_DBGMSG_SOURCES[] =
714 {
715   ".OpenGL",    // GL_DEBUG_SOURCE_API_ARB
716   ".WinSystem", // GL_DEBUG_SOURCE_WINDOW_SYSTEM_ARB
717   ".GLSL",      // GL_DEBUG_SOURCE_SHADER_COMPILER_ARB
718   ".3rdParty",  // GL_DEBUG_SOURCE_THIRD_PARTY_ARB
719   "",           // GL_DEBUG_SOURCE_APPLICATION_ARB
720   ".Other"      // GL_DEBUG_SOURCE_OTHER_ARB
721 };
722
723 static Standard_CString THE_DBGMSG_TYPES[] =
724 {
725   "Error",           // GL_DEBUG_TYPE_ERROR_ARB
726   "Deprecated",      // GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR_ARB
727   "Undef. behavior", // GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR_ARB
728   "Portability",     // GL_DEBUG_TYPE_PORTABILITY_ARB
729   "Performance",     // GL_DEBUG_TYPE_PERFORMANCE_ARB
730   "Other"            // GL_DEBUG_TYPE_OTHER_ARB
731 };
732
733 static Standard_CString THE_DBGMSG_SEV_HIGH   = "High";   // GL_DEBUG_SEVERITY_HIGH_ARB
734 static Standard_CString THE_DBGMSG_SEV_MEDIUM = "Medium"; // GL_DEBUG_SEVERITY_MEDIUM_ARB
735 static Standard_CString THE_DBGMSG_SEV_LOW    = "Low";    // GL_DEBUG_SEVERITY_LOW_ARB
736
737 //! Callback for GL_ARB_debug_output extension
738 static void APIENTRY debugCallbackWrap(unsigned int theSource,
739                                        unsigned int theType,
740                                        unsigned int theId,
741                                        unsigned int theSeverity,
742                                        int          /*theLength*/,
743                                        const char*  theMessage,
744                                        const void*  theUserParam)
745 {
746   OpenGl_Context* aCtx = (OpenGl_Context* )theUserParam;
747   aCtx->PushMessage (theSource, theType, theId, theSeverity, theMessage);
748 }
749
750 // =======================================================================
751 // function : PushMessage
752 // purpose  :
753 // =======================================================================
754 void OpenGl_Context::PushMessage (const unsigned int theSource,
755                                   const unsigned int theType,
756                                   const unsigned int theId,
757                                   const unsigned int theSeverity,
758                                   const TCollection_ExtendedString& theMessage)
759 {
760   //OpenGl_Context* aCtx = (OpenGl_Context* )theUserParam;
761   Standard_CString& aSrc = (theSource >= GL_DEBUG_SOURCE_API_ARB
762                         && theSource <= GL_DEBUG_SOURCE_OTHER_ARB)
763                          ? THE_DBGMSG_SOURCES[theSource - GL_DEBUG_SOURCE_API_ARB]
764                          : THE_DBGMSG_UNKNOWN;
765   Standard_CString& aType = (theType >= GL_DEBUG_TYPE_ERROR_ARB
766                          && theType <= GL_DEBUG_TYPE_OTHER_ARB)
767                           ? THE_DBGMSG_TYPES[theType - GL_DEBUG_TYPE_ERROR_ARB]
768                           : THE_DBGMSG_UNKNOWN;
769   Standard_CString& aSev = theSeverity == GL_DEBUG_SEVERITY_HIGH_ARB
770                          ? THE_DBGMSG_SEV_HIGH
771                          : (theSeverity == GL_DEBUG_SEVERITY_MEDIUM_ARB
772                           ? THE_DBGMSG_SEV_MEDIUM
773                           : THE_DBGMSG_SEV_LOW);
774   Message_Gravity aGrav = theSeverity == GL_DEBUG_SEVERITY_HIGH_ARB
775                         ? Message_Alarm
776                         : (theSeverity == GL_DEBUG_SEVERITY_MEDIUM_ARB
777                          ? Message_Warning
778                          : Message_Info);
779
780   TCollection_ExtendedString aMsg;
781   aMsg += "TKOpenGl"; aMsg += aSrc;
782   aMsg += " | Type: ";        aMsg += aType;
783   aMsg += " | ID: ";          aMsg += (Standard_Integer )theId;
784   aMsg += " | Severity: ";    aMsg += aSev;
785   aMsg += " | Message:\n  ";
786   aMsg += theMessage;
787
788   Messenger()->Send (aMsg, aGrav);
789 }
790
791 // =======================================================================
792 // function : init
793 // purpose  :
794 // =======================================================================
795 void OpenGl_Context::init()
796 {
797   // read version
798   readGlVersion();
799
800   core11     = (OpenGl_GlCore11*    )(&(*myFuncs));
801   core11fwd  = (OpenGl_GlCore11Fwd* )(&(*myFuncs));
802   core15     = NULL;
803   core15fwd  = NULL;
804   core20     = NULL;
805   core20fwd  = NULL;
806   core32     = NULL;
807   core32back = NULL;
808   core41     = NULL;
809   core41back = NULL;
810   core42     = NULL;
811   core42back = NULL;
812   core43     = NULL;
813   core43back = NULL;
814   core44     = NULL;
815   core44back = NULL;
816   arbTBO     = NULL;
817   arbIns     = NULL;
818   arbDbg     = NULL;
819   arbFBO     = NULL;
820   extGS      = NULL;
821
822   arbNPTW = CheckExtension ("GL_ARB_texture_non_power_of_two");
823   extBgra = CheckExtension ("GL_EXT_bgra");
824   extAnis = CheckExtension ("GL_EXT_texture_filter_anisotropic");
825   extPDS  = CheckExtension ("GL_EXT_packed_depth_stencil");
826   atiMem  = CheckExtension ("GL_ATI_meminfo");
827   nvxMem  = CheckExtension ("GL_NVX_gpu_memory_info");
828
829   // get number of maximum clipping planes
830   glGetIntegerv (GL_MAX_CLIP_PLANES, &myMaxClipPlanes);
831   glGetIntegerv (GL_MAX_TEXTURE_SIZE, &myMaxTexDim);
832
833   GLint aStereo;
834   glGetIntegerv (GL_STEREO, &aStereo);
835   myIsStereoBuffers = aStereo == 1;
836
837   if (extAnis)
838   {
839     glGetIntegerv (GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &myAnisoMax);
840   }
841
842   myClippingState.Init (myMaxClipPlanes);
843
844   bool has12 = false;
845   bool has13 = false;
846   bool has14 = false;
847   bool has15 = false;
848   bool has20 = false;
849   bool has21 = false;
850   bool has30 = false;
851   bool has31 = false;
852   bool has32 = false;
853   bool has33 = false;
854   bool has40 = false;
855   bool has41 = false;
856   bool has42 = false;
857   bool has43 = false;
858   bool has44 = false;
859
860   //! Make record shorter to retrieve function pointer using variable with same name
861   #define FindProcShort(theFunc) FindProc(#theFunc, myFuncs->theFunc)
862
863     // retrieve platform-dependent extensions
864 #if defined(_WIN32) && !defined(HAVE_EGL)
865   if (FindProcShort (wglGetExtensionsStringARB))
866   {
867     const char* aWglExts = myFuncs->wglGetExtensionsStringARB (wglGetCurrentDC());
868     if (CheckExtension (aWglExts, "WGL_EXT_swap_control"))
869     {
870       FindProcShort (wglSwapIntervalEXT);
871     }
872     if (CheckExtension (aWglExts, "WGL_ARB_pixel_format"))
873     {
874       FindProcShort (wglChoosePixelFormatARB);
875     }
876     if (CheckExtension (aWglExts, "WGL_ARB_create_context_profile"))
877     {
878       FindProcShort (wglCreateContextAttribsARB);
879     }
880     if (CheckExtension (aWglExts, "WGL_NV_DX_interop"))
881     {
882       FindProcShort (wglDXSetResourceShareHandleNV);
883       FindProcShort (wglDXOpenDeviceNV);
884       FindProcShort (wglDXCloseDeviceNV);
885       FindProcShort (wglDXRegisterObjectNV);
886       FindProcShort (wglDXUnregisterObjectNV);
887       FindProcShort (wglDXObjectAccessNV);
888       FindProcShort (wglDXLockObjectsNV);
889       FindProcShort (wglDXUnlockObjectsNV);
890     }
891   }
892 #endif
893
894   // initialize debug context extension
895   if (CheckExtension ("GL_ARB_debug_output"))
896   {
897     arbDbg = NULL;
898     if (FindProcShort (glDebugMessageControlARB)
899      && FindProcShort (glDebugMessageInsertARB)
900      && FindProcShort (glDebugMessageCallbackARB)
901      && FindProcShort (glGetDebugMessageLogARB))
902     {
903       arbDbg = (OpenGl_ArbDbg* )(&(*myFuncs));
904     }
905     if (arbDbg != NULL
906      && caps->contextDebug)
907     {
908       // setup default callback
909       arbDbg->glDebugMessageCallbackARB (debugCallbackWrap, this);
910     #ifdef DEB
911       glEnable (GL_DEBUG_OUTPUT_SYNCHRONOUS_ARB);
912     #endif
913     }
914   }
915
916   // load OpenGL 1.2 new functions
917   has12 = IsGlGreaterEqual (1, 2)
918        && FindProcShort (glBlendColor)
919        && FindProcShort (glBlendEquation)
920        && FindProcShort (glDrawRangeElements)
921        && FindProcShort (glTexImage3D)
922        && FindProcShort (glTexSubImage3D)
923        && FindProcShort (glCopyTexSubImage3D);
924
925   // load OpenGL 1.3 new functions
926   has13 = IsGlGreaterEqual (1, 3)
927        && FindProcShort (glActiveTexture)
928        && FindProcShort (glSampleCoverage)
929        && FindProcShort (glCompressedTexImage3D)
930        && FindProcShort (glCompressedTexImage2D)
931        && FindProcShort (glCompressedTexImage1D)
932        && FindProcShort (glCompressedTexSubImage3D)
933        && FindProcShort (glCompressedTexSubImage2D)
934        && FindProcShort (glCompressedTexSubImage1D)
935        && FindProcShort (glGetCompressedTexImage)
936        && FindProcShort (glClientActiveTexture)
937        && FindProcShort (glMultiTexCoord1d)
938        && FindProcShort (glMultiTexCoord1dv)
939        && FindProcShort (glMultiTexCoord1f)
940        && FindProcShort (glMultiTexCoord1fv)
941        && FindProcShort (glMultiTexCoord1i)
942        && FindProcShort (glMultiTexCoord1iv)
943        && FindProcShort (glMultiTexCoord1s)
944        && FindProcShort (glMultiTexCoord1sv)
945        && FindProcShort (glMultiTexCoord2d)
946        && FindProcShort (glMultiTexCoord2dv)
947        && FindProcShort (glMultiTexCoord2f)
948        && FindProcShort (glMultiTexCoord2fv)
949        && FindProcShort (glMultiTexCoord2i)
950        && FindProcShort (glMultiTexCoord2iv)
951        && FindProcShort (glMultiTexCoord2s)
952        && FindProcShort (glMultiTexCoord2sv)
953        && FindProcShort (glMultiTexCoord3d)
954        && FindProcShort (glMultiTexCoord3dv)
955        && FindProcShort (glMultiTexCoord3f)
956        && FindProcShort (glMultiTexCoord3fv)
957        && FindProcShort (glMultiTexCoord3i)
958        && FindProcShort (glMultiTexCoord3iv)
959        && FindProcShort (glMultiTexCoord3s)
960        && FindProcShort (glMultiTexCoord3sv)
961        && FindProcShort (glMultiTexCoord4d)
962        && FindProcShort (glMultiTexCoord4dv)
963        && FindProcShort (glMultiTexCoord4f)
964        && FindProcShort (glMultiTexCoord4fv)
965        && FindProcShort (glMultiTexCoord4i)
966        && FindProcShort (glMultiTexCoord4iv)
967        && FindProcShort (glMultiTexCoord4s)
968        && FindProcShort (glMultiTexCoord4sv)
969        && FindProcShort (glLoadTransposeMatrixf)
970        && FindProcShort (glLoadTransposeMatrixd)
971        && FindProcShort (glMultTransposeMatrixf)
972        && FindProcShort (glMultTransposeMatrixd);
973
974   // load OpenGL 1.4 new functions
975   has14 = IsGlGreaterEqual (1, 4)
976        && FindProcShort (glBlendFuncSeparate)
977        && FindProcShort (glMultiDrawArrays)
978        && FindProcShort (glMultiDrawElements)
979        && FindProcShort (glPointParameterf)
980        && FindProcShort (glPointParameterfv)
981        && FindProcShort (glPointParameteri)
982        && FindProcShort (glPointParameteriv);
983
984   // load OpenGL 1.5 new functions
985   has15 = IsGlGreaterEqual (1, 5)
986        && FindProcShort (glGenQueries)
987        && FindProcShort (glDeleteQueries)
988        && FindProcShort (glIsQuery)
989        && FindProcShort (glBeginQuery)
990        && FindProcShort (glEndQuery)
991        && FindProcShort (glGetQueryiv)
992        && FindProcShort (glGetQueryObjectiv)
993        && FindProcShort (glGetQueryObjectuiv)
994        && FindProcShort (glBindBuffer)
995        && FindProcShort (glDeleteBuffers)
996        && FindProcShort (glGenBuffers)
997        && FindProcShort (glIsBuffer)
998        && FindProcShort (glBufferData)
999        && FindProcShort (glBufferSubData)
1000        && FindProcShort (glGetBufferSubData)
1001        && FindProcShort (glMapBuffer)
1002        && FindProcShort (glUnmapBuffer)
1003        && FindProcShort (glGetBufferParameteriv)
1004        && FindProcShort (glGetBufferPointerv);
1005
1006   // load OpenGL 2.0 new functions
1007   has20 = IsGlGreaterEqual (2, 0)
1008        && FindProcShort (glBlendEquationSeparate)
1009        && FindProcShort (glDrawBuffers)
1010        && FindProcShort (glStencilOpSeparate)
1011        && FindProcShort (glStencilFuncSeparate)
1012        && FindProcShort (glStencilMaskSeparate)
1013        && FindProcShort (glAttachShader)
1014        && FindProcShort (glBindAttribLocation)
1015        && FindProcShort (glCompileShader)
1016        && FindProcShort (glCreateProgram)
1017        && FindProcShort (glCreateShader)
1018        && FindProcShort (glDeleteProgram)
1019        && FindProcShort (glDeleteShader)
1020        && FindProcShort (glDetachShader)
1021        && FindProcShort (glDisableVertexAttribArray)
1022        && FindProcShort (glEnableVertexAttribArray)
1023        && FindProcShort (glGetActiveAttrib)
1024        && FindProcShort (glGetActiveUniform)
1025        && FindProcShort (glGetAttachedShaders)
1026        && FindProcShort (glGetAttribLocation)
1027        && FindProcShort (glGetProgramiv)
1028        && FindProcShort (glGetProgramInfoLog)
1029        && FindProcShort (glGetShaderiv)
1030        && FindProcShort (glGetShaderInfoLog)
1031        && FindProcShort (glGetShaderSource)
1032        && FindProcShort (glGetUniformLocation)
1033        && FindProcShort (glGetUniformfv)
1034        && FindProcShort (glGetUniformiv)
1035        && FindProcShort (glGetVertexAttribdv)
1036        && FindProcShort (glGetVertexAttribfv)
1037        && FindProcShort (glGetVertexAttribiv)
1038        && FindProcShort (glGetVertexAttribPointerv)
1039        && FindProcShort (glIsProgram)
1040        && FindProcShort (glIsShader)
1041        && FindProcShort (glLinkProgram)
1042        && FindProcShort (glShaderSource)
1043        && FindProcShort (glUseProgram)
1044        && FindProcShort (glUniform1f)
1045        && FindProcShort (glUniform2f)
1046        && FindProcShort (glUniform3f)
1047        && FindProcShort (glUniform4f)
1048        && FindProcShort (glUniform1i)
1049        && FindProcShort (glUniform2i)
1050        && FindProcShort (glUniform3i)
1051        && FindProcShort (glUniform4i)
1052        && FindProcShort (glUniform1fv)
1053        && FindProcShort (glUniform2fv)
1054        && FindProcShort (glUniform3fv)
1055        && FindProcShort (glUniform4fv)
1056        && FindProcShort (glUniform1iv)
1057        && FindProcShort (glUniform2iv)
1058        && FindProcShort (glUniform3iv)
1059        && FindProcShort (glUniform4iv)
1060        && FindProcShort (glUniformMatrix2fv)
1061        && FindProcShort (glUniformMatrix3fv)
1062        && FindProcShort (glUniformMatrix4fv)
1063        && FindProcShort (glValidateProgram)
1064        && FindProcShort (glVertexAttrib1d)
1065        && FindProcShort (glVertexAttrib1dv)
1066        && FindProcShort (glVertexAttrib1f)
1067        && FindProcShort (glVertexAttrib1fv)
1068        && FindProcShort (glVertexAttrib1s)
1069        && FindProcShort (glVertexAttrib1sv)
1070        && FindProcShort (glVertexAttrib2d)
1071        && FindProcShort (glVertexAttrib2dv)
1072        && FindProcShort (glVertexAttrib2f)
1073        && FindProcShort (glVertexAttrib2fv)
1074        && FindProcShort (glVertexAttrib2s)
1075        && FindProcShort (glVertexAttrib2sv)
1076        && FindProcShort (glVertexAttrib3d)
1077        && FindProcShort (glVertexAttrib3dv)
1078        && FindProcShort (glVertexAttrib3f)
1079        && FindProcShort (glVertexAttrib3fv)
1080        && FindProcShort (glVertexAttrib3s)
1081        && FindProcShort (glVertexAttrib3sv)
1082        && FindProcShort (glVertexAttrib4Nbv)
1083        && FindProcShort (glVertexAttrib4Niv)
1084        && FindProcShort (glVertexAttrib4Nsv)
1085        && FindProcShort (glVertexAttrib4Nub)
1086        && FindProcShort (glVertexAttrib4Nubv)
1087        && FindProcShort (glVertexAttrib4Nuiv)
1088        && FindProcShort (glVertexAttrib4Nusv)
1089        && FindProcShort (glVertexAttrib4bv)
1090        && FindProcShort (glVertexAttrib4d)
1091        && FindProcShort (glVertexAttrib4dv)
1092        && FindProcShort (glVertexAttrib4f)
1093        && FindProcShort (glVertexAttrib4fv)
1094        && FindProcShort (glVertexAttrib4iv)
1095        && FindProcShort (glVertexAttrib4s)
1096        && FindProcShort (glVertexAttrib4sv)
1097        && FindProcShort (glVertexAttrib4ubv)
1098        && FindProcShort (glVertexAttrib4uiv)
1099        && FindProcShort (glVertexAttrib4usv)
1100        && FindProcShort (glVertexAttribPointer);
1101
1102   // load OpenGL 2.1 new functions
1103   has21 = IsGlGreaterEqual (2, 1)
1104        && FindProcShort (glUniformMatrix2x3fv)
1105        && FindProcShort (glUniformMatrix3x2fv)
1106        && FindProcShort (glUniformMatrix2x4fv)
1107        && FindProcShort (glUniformMatrix4x2fv)
1108        && FindProcShort (glUniformMatrix3x4fv)
1109        && FindProcShort (glUniformMatrix4x3fv);
1110
1111   // load GL_ARB_framebuffer_object (added to OpenGL 3.0 core)
1112   const bool hasFBO = (IsGlGreaterEqual (3, 0) || CheckExtension ("GL_ARB_framebuffer_object"))
1113        && FindProcShort (glIsRenderbuffer)
1114        && FindProcShort (glBindRenderbuffer)
1115        && FindProcShort (glDeleteRenderbuffers)
1116        && FindProcShort (glGenRenderbuffers)
1117        && FindProcShort (glRenderbufferStorage)
1118        && FindProcShort (glGetRenderbufferParameteriv)
1119        && FindProcShort (glIsFramebuffer)
1120        && FindProcShort (glBindFramebuffer)
1121        && FindProcShort (glDeleteFramebuffers)
1122        && FindProcShort (glGenFramebuffers)
1123        && FindProcShort (glCheckFramebufferStatus)
1124        && FindProcShort (glFramebufferTexture1D)
1125        && FindProcShort (glFramebufferTexture2D)
1126        && FindProcShort (glFramebufferTexture3D)
1127        && FindProcShort (glFramebufferRenderbuffer)
1128        && FindProcShort (glGetFramebufferAttachmentParameteriv)
1129        && FindProcShort (glGenerateMipmap)
1130        && FindProcShort (glBlitFramebuffer)
1131        && FindProcShort (glRenderbufferStorageMultisample)
1132        && FindProcShort (glFramebufferTextureLayer);
1133
1134   // load GL_ARB_vertex_array_object (added to OpenGL 3.0 core)
1135   const bool hasVAO = (IsGlGreaterEqual (3, 0) || CheckExtension ("GL_ARB_vertex_array_object"))
1136        && FindProcShort (glBindVertexArray)
1137        && FindProcShort (glDeleteVertexArrays)
1138        && FindProcShort (glGenVertexArrays)
1139        && FindProcShort (glIsVertexArray);
1140
1141   // load GL_ARB_map_buffer_range (added to OpenGL 3.0 core)
1142   const bool hasMapBufferRange = (IsGlGreaterEqual (3, 0) || CheckExtension ("GL_ARB_map_buffer_range"))
1143        && FindProcShort (glMapBufferRange)
1144        && FindProcShort (glFlushMappedBufferRange);
1145
1146   // load OpenGL 3.0 new functions
1147   has30 = IsGlGreaterEqual (3, 0)
1148        && hasFBO
1149        && hasVAO
1150        && hasMapBufferRange
1151        && FindProcShort (glColorMaski)
1152        && FindProcShort (glGetBooleani_v)
1153        && FindProcShort (glGetIntegeri_v)
1154        && FindProcShort (glEnablei)
1155        && FindProcShort (glDisablei)
1156        && FindProcShort (glIsEnabledi)
1157        && FindProcShort (glBeginTransformFeedback)
1158        && FindProcShort (glEndTransformFeedback)
1159        && FindProcShort (glBindBufferRange)
1160        && FindProcShort (glBindBufferBase)
1161        && FindProcShort (glTransformFeedbackVaryings)
1162        && FindProcShort (glGetTransformFeedbackVarying)
1163        && FindProcShort (glClampColor)
1164        && FindProcShort (glBeginConditionalRender)
1165        && FindProcShort (glEndConditionalRender)
1166        && FindProcShort (glVertexAttribIPointer)
1167        && FindProcShort (glGetVertexAttribIiv)
1168        && FindProcShort (glGetVertexAttribIuiv)
1169        && FindProcShort (glVertexAttribI1i)
1170        && FindProcShort (glVertexAttribI2i)
1171        && FindProcShort (glVertexAttribI3i)
1172        && FindProcShort (glVertexAttribI4i)
1173        && FindProcShort (glVertexAttribI1ui)
1174        && FindProcShort (glVertexAttribI2ui)
1175        && FindProcShort (glVertexAttribI3ui)
1176        && FindProcShort (glVertexAttribI4ui)
1177        && FindProcShort (glVertexAttribI1iv)
1178        && FindProcShort (glVertexAttribI2iv)
1179        && FindProcShort (glVertexAttribI3iv)
1180        && FindProcShort (glVertexAttribI4iv)
1181        && FindProcShort (glVertexAttribI1uiv)
1182        && FindProcShort (glVertexAttribI2uiv)
1183        && FindProcShort (glVertexAttribI3uiv)
1184        && FindProcShort (glVertexAttribI4uiv)
1185        && FindProcShort (glVertexAttribI4bv)
1186        && FindProcShort (glVertexAttribI4sv)
1187        && FindProcShort (glVertexAttribI4ubv)
1188        && FindProcShort (glVertexAttribI4usv)
1189        && FindProcShort (glGetUniformuiv)
1190        && FindProcShort (glBindFragDataLocation)
1191        && FindProcShort (glGetFragDataLocation)
1192        && FindProcShort (glUniform1ui)
1193        && FindProcShort (glUniform2ui)
1194        && FindProcShort (glUniform3ui)
1195        && FindProcShort (glUniform4ui)
1196        && FindProcShort (glUniform1uiv)
1197        && FindProcShort (glUniform2uiv)
1198        && FindProcShort (glUniform3uiv)
1199        && FindProcShort (glUniform4uiv)
1200        && FindProcShort (glTexParameterIiv)
1201        && FindProcShort (glTexParameterIuiv)
1202        && FindProcShort (glGetTexParameterIiv)
1203        && FindProcShort (glGetTexParameterIuiv)
1204        && FindProcShort (glClearBufferiv)
1205        && FindProcShort (glClearBufferuiv)
1206        && FindProcShort (glClearBufferfv)
1207        && FindProcShort (glClearBufferfi)
1208        && FindProcShort (glGetStringi);
1209
1210   // load GL_ARB_uniform_buffer_object (added to OpenGL 3.1 core)
1211   const bool hasUBO = (IsGlGreaterEqual (3, 1) || CheckExtension ("GL_ARB_uniform_buffer_object"))
1212        && FindProcShort (glGetUniformIndices)
1213        && FindProcShort (glGetActiveUniformsiv)
1214        && FindProcShort (glGetActiveUniformName)
1215        && FindProcShort (glGetUniformBlockIndex)
1216        && FindProcShort (glGetActiveUniformBlockiv)
1217        && FindProcShort (glGetActiveUniformBlockName)
1218        && FindProcShort (glUniformBlockBinding);
1219
1220   // load GL_ARB_copy_buffer (added to OpenGL 3.1 core)
1221   const bool hasCopyBufSubData = (IsGlGreaterEqual (3, 1) || CheckExtension ("GL_ARB_copy_buffer"))
1222        && FindProcShort (glCopyBufferSubData);
1223
1224   if (has30)
1225   {
1226     // NPOT textures are required by OpenGL 2.0 specifications
1227     // but doesn't hardware accelerated by some ancient OpenGL 2.1 hardware (GeForce FX, RadeOn 9700 etc.)
1228     arbNPTW  = Standard_True;
1229     arbTexRG = Standard_True;
1230   }
1231
1232   // load OpenGL 3.1 new functions
1233   has31 = IsGlGreaterEqual (3, 1)
1234        && hasUBO
1235        && hasCopyBufSubData
1236        && FindProcShort (glDrawArraysInstanced)
1237        && FindProcShort (glDrawElementsInstanced)
1238        && FindProcShort (glTexBuffer)
1239        && FindProcShort (glPrimitiveRestartIndex);
1240
1241   // load GL_ARB_draw_elements_base_vertex (added to OpenGL 3.2 core)
1242   const bool hasDrawElemsBaseVert = (IsGlGreaterEqual (3, 2) || CheckExtension ("GL_ARB_draw_elements_base_vertex"))
1243        && FindProcShort (glDrawElementsBaseVertex)
1244        && FindProcShort (glDrawRangeElementsBaseVertex)
1245        && FindProcShort (glDrawElementsInstancedBaseVertex)
1246        && FindProcShort (glMultiDrawElementsBaseVertex);
1247
1248   // load GL_ARB_provoking_vertex (added to OpenGL 3.2 core)
1249   const bool hasProvokingVert = (IsGlGreaterEqual (3, 2) || CheckExtension ("GL_ARB_provoking_vertex"))
1250        && FindProcShort (glProvokingVertex);
1251
1252   // load GL_ARB_sync (added to OpenGL 3.2 core)
1253   const bool hasSync = (IsGlGreaterEqual (3, 2) || CheckExtension ("GL_ARB_sync"))
1254        && FindProcShort (glFenceSync)
1255        && FindProcShort (glIsSync)
1256        && FindProcShort (glDeleteSync)
1257        && FindProcShort (glClientWaitSync)
1258        && FindProcShort (glWaitSync)
1259        && FindProcShort (glGetInteger64v)
1260        && FindProcShort (glGetSynciv);
1261
1262   // load GL_ARB_texture_multisample (added to OpenGL 3.2 core)
1263   const bool hasTextureMultisample = (IsGlGreaterEqual (3, 2) || CheckExtension ("GL_ARB_texture_multisample"))
1264        && FindProcShort (glTexImage2DMultisample)
1265        && FindProcShort (glTexImage3DMultisample)
1266        && FindProcShort (glGetMultisamplefv)
1267        && FindProcShort (glSampleMaski);
1268
1269   // load OpenGL 3.2 new functions
1270   has32 = IsGlGreaterEqual (3, 2)
1271        && hasDrawElemsBaseVert
1272        && hasProvokingVert
1273        && hasSync
1274        && hasTextureMultisample
1275        && FindProcShort (glGetInteger64i_v)
1276        && FindProcShort (glGetBufferParameteri64v)
1277        && FindProcShort (glFramebufferTexture);
1278
1279   // load GL_ARB_blend_func_extended (added to OpenGL 3.3 core)
1280   const bool hasBlendFuncExtended = (IsGlGreaterEqual (3, 3) || CheckExtension ("GL_ARB_blend_func_extended"))
1281        && FindProcShort (glBindFragDataLocationIndexed)
1282        && FindProcShort (glGetFragDataIndex);
1283
1284   // load GL_ARB_sampler_objects (added to OpenGL 3.3 core)
1285   const bool hasSamplerObjects = (IsGlGreaterEqual (3, 3) || CheckExtension ("GL_ARB_sampler_objects"))
1286        && FindProcShort (glGenSamplers)
1287        && FindProcShort (glDeleteSamplers)
1288        && FindProcShort (glIsSampler)
1289        && FindProcShort (glBindSampler)
1290        && FindProcShort (glSamplerParameteri)
1291        && FindProcShort (glSamplerParameteriv)
1292        && FindProcShort (glSamplerParameterf)
1293        && FindProcShort (glSamplerParameterfv)
1294        && FindProcShort (glSamplerParameterIiv)
1295        && FindProcShort (glSamplerParameterIuiv)
1296        && FindProcShort (glGetSamplerParameteriv)
1297        && FindProcShort (glGetSamplerParameterIiv)
1298        && FindProcShort (glGetSamplerParameterfv)
1299        && FindProcShort (glGetSamplerParameterIuiv);
1300
1301   // load GL_ARB_timer_query (added to OpenGL 3.3 core)
1302   const bool hasTimerQuery = (IsGlGreaterEqual (3, 3) || CheckExtension ("GL_ARB_timer_query"))
1303        && FindProcShort (glQueryCounter)
1304        && FindProcShort (glGetQueryObjecti64v)
1305        && FindProcShort (glGetQueryObjectui64v);
1306
1307   // load GL_ARB_vertex_type_2_10_10_10_rev (added to OpenGL 3.3 core)
1308   const bool hasVertType21010101rev = (IsGlGreaterEqual (3, 3) || CheckExtension ("GL_ARB_vertex_type_2_10_10_10_rev"))
1309        && FindProcShort (glVertexP2ui)
1310        && FindProcShort (glVertexP2uiv)
1311        && FindProcShort (glVertexP3ui)
1312        && FindProcShort (glVertexP3uiv)
1313        && FindProcShort (glVertexP4ui)
1314        && FindProcShort (glVertexP4uiv)
1315        && FindProcShort (glTexCoordP1ui)
1316        && FindProcShort (glTexCoordP1uiv)
1317        && FindProcShort (glTexCoordP2ui)
1318        && FindProcShort (glTexCoordP2uiv)
1319        && FindProcShort (glTexCoordP3ui)
1320        && FindProcShort (glTexCoordP3uiv)
1321        && FindProcShort (glTexCoordP4ui)
1322        && FindProcShort (glTexCoordP4uiv)
1323        && FindProcShort (glMultiTexCoordP1ui)
1324        && FindProcShort (glMultiTexCoordP1uiv)
1325        && FindProcShort (glMultiTexCoordP2ui)
1326        && FindProcShort (glMultiTexCoordP2uiv)
1327        && FindProcShort (glMultiTexCoordP3ui)
1328        && FindProcShort (glMultiTexCoordP3uiv)
1329        && FindProcShort (glMultiTexCoordP4ui)
1330        && FindProcShort (glMultiTexCoordP4uiv)
1331        && FindProcShort (glNormalP3ui)
1332        && FindProcShort (glNormalP3uiv)
1333        && FindProcShort (glColorP3ui)
1334        && FindProcShort (glColorP3uiv)
1335        && FindProcShort (glColorP4ui)
1336        && FindProcShort (glColorP4uiv)
1337        && FindProcShort (glSecondaryColorP3ui)
1338        && FindProcShort (glSecondaryColorP3uiv)
1339        && FindProcShort (glVertexAttribP1ui)
1340        && FindProcShort (glVertexAttribP1uiv)
1341        && FindProcShort (glVertexAttribP2ui)
1342        && FindProcShort (glVertexAttribP2uiv)
1343        && FindProcShort (glVertexAttribP3ui)
1344        && FindProcShort (glVertexAttribP3uiv)
1345        && FindProcShort (glVertexAttribP4ui)
1346        && FindProcShort (glVertexAttribP4uiv);
1347
1348   // load OpenGL 3.3 extra functions
1349   has33 = IsGlGreaterEqual (3, 3)
1350        && hasBlendFuncExtended
1351        && hasSamplerObjects
1352        && hasTimerQuery
1353        && hasVertType21010101rev
1354        && FindProcShort (glVertexAttribDivisor);
1355
1356   // load GL_ARB_draw_indirect (added to OpenGL 4.0 core)
1357   const bool hasDrawIndirect = (IsGlGreaterEqual (4, 0) || CheckExtension ("GL_ARB_draw_indirect"))
1358        && FindProcShort (glDrawArraysIndirect)
1359        && FindProcShort (glDrawElementsIndirect);
1360
1361   // load GL_ARB_gpu_shader_fp64 (added to OpenGL 4.0 core)
1362   const bool hasShaderFP64 = (IsGlGreaterEqual (4, 0) || CheckExtension ("GL_ARB_gpu_shader_fp64"))
1363        && FindProcShort (glUniform1d)
1364        && FindProcShort (glUniform2d)
1365        && FindProcShort (glUniform3d)
1366        && FindProcShort (glUniform4d)
1367        && FindProcShort (glUniform1dv)
1368        && FindProcShort (glUniform2dv)
1369        && FindProcShort (glUniform3dv)
1370        && FindProcShort (glUniform4dv)
1371        && FindProcShort (glUniformMatrix2dv)
1372        && FindProcShort (glUniformMatrix3dv)
1373        && FindProcShort (glUniformMatrix4dv)
1374        && FindProcShort (glUniformMatrix2x3dv)
1375        && FindProcShort (glUniformMatrix2x4dv)
1376        && FindProcShort (glUniformMatrix3x2dv)
1377        && FindProcShort (glUniformMatrix3x4dv)
1378        && FindProcShort (glUniformMatrix4x2dv)
1379        && FindProcShort (glUniformMatrix4x3dv)
1380        && FindProcShort (glGetUniformdv);
1381
1382   // load GL_ARB_shader_subroutine (added to OpenGL 4.0 core)
1383   const bool hasShaderSubroutine = (IsGlGreaterEqual (4, 0) || CheckExtension ("GL_ARB_shader_subroutine"))
1384        && FindProcShort (glGetSubroutineUniformLocation)
1385        && FindProcShort (glGetSubroutineIndex)
1386        && FindProcShort (glGetActiveSubroutineUniformiv)
1387        && FindProcShort (glGetActiveSubroutineUniformName)
1388        && FindProcShort (glGetActiveSubroutineName)
1389        && FindProcShort (glUniformSubroutinesuiv)
1390        && FindProcShort (glGetUniformSubroutineuiv)
1391        && FindProcShort (glGetProgramStageiv);
1392
1393   // load GL_ARB_tessellation_shader (added to OpenGL 4.0 core)
1394   const bool hasTessellationShader = (IsGlGreaterEqual (4, 0) || CheckExtension ("GL_ARB_tessellation_shader"))
1395        && FindProcShort (glPatchParameteri)
1396        && FindProcShort (glPatchParameterfv);
1397
1398   // load GL_ARB_transform_feedback2 (added to OpenGL 4.0 core)
1399   const bool hasTrsfFeedback2 = (IsGlGreaterEqual (4, 0) || CheckExtension ("GL_ARB_transform_feedback2"))
1400        && FindProcShort (glBindTransformFeedback)
1401        && FindProcShort (glDeleteTransformFeedbacks)
1402        && FindProcShort (glGenTransformFeedbacks)
1403        && FindProcShort (glIsTransformFeedback)
1404        && FindProcShort (glPauseTransformFeedback)
1405        && FindProcShort (glResumeTransformFeedback)
1406        && FindProcShort (glDrawTransformFeedback);
1407
1408   // load GL_ARB_transform_feedback3 (added to OpenGL 4.0 core)
1409   const bool hasTrsfFeedback3 = (IsGlGreaterEqual (4, 0) || CheckExtension ("GL_ARB_transform_feedback3"))
1410        && FindProcShort (glDrawTransformFeedbackStream)
1411        && FindProcShort (glBeginQueryIndexed)
1412        && FindProcShort (glEndQueryIndexed)
1413        && FindProcShort (glGetQueryIndexediv);
1414
1415   // load OpenGL 4.0 new functions
1416   has40 = IsGlGreaterEqual (4, 0)
1417       && hasDrawIndirect
1418       && hasShaderFP64
1419       && hasShaderSubroutine
1420       && hasTessellationShader
1421       && hasTrsfFeedback2
1422       && hasTrsfFeedback3
1423       && FindProcShort (glMinSampleShading)
1424       && FindProcShort (glBlendEquationi)
1425       && FindProcShort (glBlendEquationSeparatei)
1426       && FindProcShort (glBlendFunci)
1427       && FindProcShort (glBlendFuncSeparatei);
1428
1429   // load GL_ARB_ES2_compatibility (added to OpenGL 4.1 core)
1430   const bool hasES2Compatibility = (IsGlGreaterEqual (4, 1) || CheckExtension ("GL_ARB_ES2_compatibility"))
1431        && FindProcShort (glReleaseShaderCompiler)
1432        && FindProcShort (glShaderBinary)
1433        && FindProcShort (glGetShaderPrecisionFormat)
1434        && FindProcShort (glDepthRangef)
1435        && FindProcShort (glClearDepthf);
1436
1437   // load GL_ARB_get_program_binary (added to OpenGL 4.1 core)
1438   const bool hasGetProgramBinary = (IsGlGreaterEqual (4, 1) || CheckExtension ("GL_ARB_get_program_binary"))
1439        && FindProcShort (glGetProgramBinary)
1440        && FindProcShort (glProgramBinary)
1441        && FindProcShort (glProgramParameteri);
1442
1443
1444   // load GL_ARB_separate_shader_objects (added to OpenGL 4.1 core)
1445   const bool hasSeparateShaderObjects = (IsGlGreaterEqual (4, 1) || CheckExtension ("GL_ARB_separate_shader_objects"))
1446        && FindProcShort (glUseProgramStages)
1447        && FindProcShort (glActiveShaderProgram)
1448        && FindProcShort (glCreateShaderProgramv)
1449        && FindProcShort (glBindProgramPipeline)
1450        && FindProcShort (glDeleteProgramPipelines)
1451        && FindProcShort (glGenProgramPipelines)
1452        && FindProcShort (glIsProgramPipeline)
1453        && FindProcShort (glGetProgramPipelineiv)
1454        && FindProcShort (glProgramUniform1i)
1455        && FindProcShort (glProgramUniform1iv)
1456        && FindProcShort (glProgramUniform1f)
1457        && FindProcShort (glProgramUniform1fv)
1458        && FindProcShort (glProgramUniform1d)
1459        && FindProcShort (glProgramUniform1dv)
1460        && FindProcShort (glProgramUniform1ui)
1461        && FindProcShort (glProgramUniform1uiv)
1462        && FindProcShort (glProgramUniform2i)
1463        && FindProcShort (glProgramUniform2iv)
1464        && FindProcShort (glProgramUniform2f)
1465        && FindProcShort (glProgramUniform2fv)
1466        && FindProcShort (glProgramUniform2d)
1467        && FindProcShort (glProgramUniform2dv)
1468        && FindProcShort (glProgramUniform2ui)
1469        && FindProcShort (glProgramUniform2uiv)
1470        && FindProcShort (glProgramUniform3i)
1471        && FindProcShort (glProgramUniform3iv)
1472        && FindProcShort (glProgramUniform3f)
1473        && FindProcShort (glProgramUniform3fv)
1474        && FindProcShort (glProgramUniform3d)
1475        && FindProcShort (glProgramUniform3dv)
1476        && FindProcShort (glProgramUniform3ui)
1477        && FindProcShort (glProgramUniform3uiv)
1478        && FindProcShort (glProgramUniform4i)
1479        && FindProcShort (glProgramUniform4iv)
1480        && FindProcShort (glProgramUniform4f)
1481        && FindProcShort (glProgramUniform4fv)
1482        && FindProcShort (glProgramUniform4d)
1483        && FindProcShort (glProgramUniform4dv)
1484        && FindProcShort (glProgramUniform4ui)
1485        && FindProcShort (glProgramUniform4uiv)
1486        && FindProcShort (glProgramUniformMatrix2fv)
1487        && FindProcShort (glProgramUniformMatrix3fv)
1488        && FindProcShort (glProgramUniformMatrix4fv)
1489        && FindProcShort (glProgramUniformMatrix2dv)
1490        && FindProcShort (glProgramUniformMatrix3dv)
1491        && FindProcShort (glProgramUniformMatrix4dv)
1492        && FindProcShort (glProgramUniformMatrix2x3fv)
1493        && FindProcShort (glProgramUniformMatrix3x2fv)
1494        && FindProcShort (glProgramUniformMatrix2x4fv)
1495        && FindProcShort (glProgramUniformMatrix4x2fv)
1496        && FindProcShort (glProgramUniformMatrix3x4fv)
1497        && FindProcShort (glProgramUniformMatrix4x3fv)
1498        && FindProcShort (glProgramUniformMatrix2x3dv)
1499        && FindProcShort (glProgramUniformMatrix3x2dv)
1500        && FindProcShort (glProgramUniformMatrix2x4dv)
1501        && FindProcShort (glProgramUniformMatrix4x2dv)
1502        && FindProcShort (glProgramUniformMatrix3x4dv)
1503        && FindProcShort (glProgramUniformMatrix4x3dv)
1504        && FindProcShort (glValidateProgramPipeline)
1505        && FindProcShort (glGetProgramPipelineInfoLog);
1506
1507   // load GL_ARB_vertex_attrib_64bit (added to OpenGL 4.1 core)
1508   const bool hasVertAttrib64bit = (IsGlGreaterEqual (4, 1) || CheckExtension ("GL_ARB_vertex_attrib_64bit"))
1509        && FindProcShort (glVertexAttribL1d)
1510        && FindProcShort (glVertexAttribL2d)
1511        && FindProcShort (glVertexAttribL3d)
1512        && FindProcShort (glVertexAttribL4d)
1513        && FindProcShort (glVertexAttribL1dv)
1514        && FindProcShort (glVertexAttribL2dv)
1515        && FindProcShort (glVertexAttribL3dv)
1516        && FindProcShort (glVertexAttribL4dv)
1517        && FindProcShort (glVertexAttribLPointer)
1518        && FindProcShort (glGetVertexAttribLdv);
1519
1520   // load GL_ARB_viewport_array (added to OpenGL 4.1 core)
1521   const bool hasViewportArray = (IsGlGreaterEqual (4, 1) || CheckExtension ("GL_ARB_viewport_array"))
1522        && FindProcShort (glViewportArrayv)
1523        && FindProcShort (glViewportIndexedf)
1524        && FindProcShort (glViewportIndexedfv)
1525        && FindProcShort (glScissorArrayv)
1526        && FindProcShort (glScissorIndexed)
1527        && FindProcShort (glScissorIndexedv)
1528        && FindProcShort (glDepthRangeArrayv)
1529        && FindProcShort (glDepthRangeIndexed)
1530        && FindProcShort (glGetFloati_v)
1531        && FindProcShort (glGetDoublei_v);
1532
1533   has41 = IsGlGreaterEqual (4, 1)
1534        && hasES2Compatibility
1535        && hasGetProgramBinary
1536        && hasSeparateShaderObjects
1537        && hasVertAttrib64bit
1538        && hasViewportArray;
1539
1540   // load GL_ARB_base_instance (added to OpenGL 4.2 core)
1541   const bool hasBaseInstance = (IsGlGreaterEqual (4, 2) || CheckExtension ("GL_ARB_base_instance"))
1542        && FindProcShort (glDrawArraysInstancedBaseInstance)
1543        && FindProcShort (glDrawElementsInstancedBaseInstance)
1544        && FindProcShort (glDrawElementsInstancedBaseVertexBaseInstance);
1545
1546   // load GL_ARB_transform_feedback_instanced (added to OpenGL 4.2 core)
1547   const bool hasTrsfFeedbackInstanced = (IsGlGreaterEqual (4, 2) || CheckExtension ("GL_ARB_transform_feedback_instanced"))
1548        && FindProcShort (glDrawTransformFeedbackInstanced)
1549        && FindProcShort (glDrawTransformFeedbackStreamInstanced);
1550
1551   // load GL_ARB_internalformat_query (added to OpenGL 4.2 core)
1552   const bool hasInternalFormatQuery = (IsGlGreaterEqual (4, 2) || CheckExtension ("GL_ARB_internalformat_query"))
1553        && FindProcShort (glGetInternalformativ);
1554
1555   // load GL_ARB_shader_atomic_counters (added to OpenGL 4.2 core)
1556   const bool hasShaderAtomicCounters = (IsGlGreaterEqual (4, 2) || CheckExtension ("GL_ARB_shader_atomic_counters"))
1557        && FindProcShort (glGetActiveAtomicCounterBufferiv);
1558
1559   // load GL_ARB_shader_image_load_store (added to OpenGL 4.2 core)
1560   const bool hasShaderImgLoadStore = (IsGlGreaterEqual (4, 2) || CheckExtension ("GL_ARB_shader_image_load_store"))
1561        && FindProcShort (glBindImageTexture)
1562        && FindProcShort (glMemoryBarrier);
1563
1564   // load GL_ARB_texture_storage (added to OpenGL 4.2 core)
1565   const bool hasTextureStorage = (IsGlGreaterEqual (4, 2) || CheckExtension ("GL_ARB_texture_storage"))
1566        && FindProcShort (glTexStorage1D)
1567        && FindProcShort (glTexStorage2D)
1568        && FindProcShort (glTexStorage3D)
1569        && FindProcShort (glTextureStorage1DEXT)
1570        && FindProcShort (glTextureStorage2DEXT)
1571        && FindProcShort (glTextureStorage3DEXT);
1572
1573   has42 = IsGlGreaterEqual (4, 2)
1574        && hasBaseInstance
1575        && hasTrsfFeedbackInstanced
1576        && hasInternalFormatQuery
1577        && hasShaderAtomicCounters
1578        && hasShaderImgLoadStore
1579        && hasTextureStorage;
1580
1581   has43 = IsGlGreaterEqual (4, 3)
1582        && FindProcShort (glClearBufferData)
1583        && FindProcShort (glClearBufferSubData)
1584        && FindProcShort (glDispatchCompute)
1585        && FindProcShort (glDispatchComputeIndirect)
1586        && FindProcShort (glCopyImageSubData)
1587        && FindProcShort (glFramebufferParameteri)
1588        && FindProcShort (glGetFramebufferParameteriv)
1589        && FindProcShort (glGetInternalformati64v)
1590        && FindProcShort (glInvalidateTexSubImage)
1591        && FindProcShort (glInvalidateTexImage)
1592        && FindProcShort (glInvalidateBufferSubData)
1593        && FindProcShort (glInvalidateBufferData)
1594        && FindProcShort (glInvalidateFramebuffer)
1595        && FindProcShort (glInvalidateSubFramebuffer)
1596        && FindProcShort (glMultiDrawArraysIndirect)
1597        && FindProcShort (glMultiDrawElementsIndirect)
1598        && FindProcShort (glGetProgramInterfaceiv)
1599        && FindProcShort (glGetProgramResourceIndex)
1600        && FindProcShort (glGetProgramResourceName)
1601        && FindProcShort (glGetProgramResourceiv)
1602        && FindProcShort (glGetProgramResourceLocation)
1603        && FindProcShort (glGetProgramResourceLocationIndex)
1604        && FindProcShort (glShaderStorageBlockBinding)
1605        && FindProcShort (glTexBufferRange)
1606        && FindProcShort (glTexStorage2DMultisample)
1607        && FindProcShort (glTexStorage3DMultisample)
1608        && FindProcShort (glTextureView)
1609        && FindProcShort (glBindVertexBuffer)
1610        && FindProcShort (glVertexAttribFormat)
1611        && FindProcShort (glVertexAttribIFormat)
1612        && FindProcShort (glVertexAttribLFormat)
1613        && FindProcShort (glVertexAttribBinding)
1614        && FindProcShort (glVertexBindingDivisor)
1615        && FindProcShort (glDebugMessageControl)
1616        && FindProcShort (glDebugMessageInsert)
1617        && FindProcShort (glDebugMessageCallback)
1618        && FindProcShort (glGetDebugMessageLog)
1619        && FindProcShort (glPushDebugGroup)
1620        && FindProcShort (glPopDebugGroup)
1621        && FindProcShort (glObjectLabel)
1622        && FindProcShort (glGetObjectLabel)
1623        && FindProcShort (glObjectPtrLabel)
1624        && FindProcShort (glGetObjectPtrLabel);
1625
1626   // load GL_ARB_clear_texture (added to OpenGL 4.4 core)
1627   bool arbTexClear = (IsGlGreaterEqual (4, 4) || CheckExtension ("GL_ARB_clear_texture"))
1628        && FindProcShort (glClearTexImage)
1629        && FindProcShort (glClearTexSubImage);
1630
1631   has44 = IsGlGreaterEqual (4, 4)
1632        && arbTexClear
1633        && FindProcShort (glBufferStorage)
1634        && FindProcShort (glBindBuffersBase)
1635        && FindProcShort (glBindBuffersRange)
1636        && FindProcShort (glBindTextures)
1637        && FindProcShort (glBindSamplers)
1638        && FindProcShort (glBindImageTextures)
1639        && FindProcShort (glBindVertexBuffers);
1640
1641   // initialize TBO extension (ARB)
1642   if (!has31
1643    && CheckExtension ("GL_ARB_texture_buffer_object")
1644    && FindProc ("glTexBufferARB", myFuncs->glTexBuffer))
1645   {
1646     arbTBO = (OpenGl_ArbTBO* )(&(*myFuncs));
1647   }
1648
1649   // initialize hardware instancing extension (ARB)
1650   if (!has31
1651    && CheckExtension ("GL_ARB_draw_instanced")
1652    && FindProc ("glDrawArraysInstancedARB",   myFuncs->glDrawArraysInstanced)
1653    && FindProc ("glDrawElementsInstancedARB", myFuncs->glDrawElementsInstanced))
1654   {
1655     arbIns = (OpenGl_ArbIns* )(&(*myFuncs));
1656   }
1657
1658   // initialize FBO extension (ARB)
1659   if (hasFBO)
1660   {
1661     arbFBO = (OpenGl_ArbFBO* )(&(*myFuncs));
1662     extPDS = Standard_True; // extension for EXT, but part of ARB
1663   }
1664
1665   // initialize GS extension (EXT)
1666   if (CheckExtension ("GL_EXT_geometry_shader4")
1667    && FindProcShort (glProgramParameteriEXT))
1668   {
1669     extGS = (OpenGl_ExtGS* )(&(*myFuncs));
1670   }
1671
1672   if (!has12)
1673   {
1674     myGlVerMajor = 1;
1675     myGlVerMinor = 1;
1676     return;
1677   }
1678   else if (!has13)
1679   {
1680     myGlVerMajor = 1;
1681     myGlVerMinor = 2;
1682     return;
1683   }
1684   else if (!has14)
1685   {
1686     myGlVerMajor = 1;
1687     myGlVerMinor = 3;
1688     return;
1689   }
1690   else if (!has15)
1691   {
1692     myGlVerMajor = 1;
1693     myGlVerMinor = 4;
1694     return;
1695   }
1696   core15    = (OpenGl_GlCore15*    )(&(*myFuncs));
1697   core15fwd = (OpenGl_GlCore15Fwd* )(&(*myFuncs));
1698
1699   if (!has20)
1700   {
1701     myGlVerMajor = 1;
1702     myGlVerMinor = 5;
1703     return;
1704   }
1705
1706   core20    = (OpenGl_GlCore20*    )(&(*myFuncs));
1707   core20fwd = (OpenGl_GlCore20Fwd* )(&(*myFuncs));
1708
1709   if (!has21)
1710   {
1711     myGlVerMajor = 2;
1712     myGlVerMinor = 0;
1713     return;
1714   }
1715
1716   if (!has30)
1717   {
1718     myGlVerMajor = 2;
1719     myGlVerMinor = 1;
1720     return;
1721   }
1722
1723   if (!has31)
1724   {
1725     myGlVerMajor = 3;
1726     myGlVerMinor = 0;
1727     return;
1728   }
1729   arbTBO = (OpenGl_ArbTBO* )(&(*myFuncs));
1730   arbIns = (OpenGl_ArbIns* )(&(*myFuncs));
1731
1732   if (!has32)
1733   {
1734     myGlVerMajor = 3;
1735     myGlVerMinor = 1;
1736     return;
1737   }
1738   core32     = (OpenGl_GlCore32*     )(&(*myFuncs));
1739   core32back = (OpenGl_GlCore32Back* )(&(*myFuncs));
1740
1741   if (!has33)
1742   {
1743     myGlVerMajor = 3;
1744     myGlVerMinor = 2;
1745     return;
1746   }
1747
1748   if (!has40)
1749   {
1750     myGlVerMajor = 3;
1751     myGlVerMinor = 3;
1752     return;
1753   }
1754
1755   if (!has41)
1756   {
1757     myGlVerMajor = 4;
1758     myGlVerMinor = 0;
1759     return;
1760   }
1761   core41     = (OpenGl_GlCore41*     )(&(*myFuncs));
1762   core41back = (OpenGl_GlCore41Back* )(&(*myFuncs));
1763
1764   if(!has42)
1765   {
1766     myGlVerMajor = 4;
1767     myGlVerMinor = 1;
1768     return;
1769   }
1770   core42     = (OpenGl_GlCore42*     )(&(*myFuncs));
1771   core42back = (OpenGl_GlCore42Back* )(&(*myFuncs));
1772
1773   if(!has43)
1774   {
1775     myGlVerMajor = 4;
1776     myGlVerMinor = 2;
1777     return;
1778   }
1779   core43     = (OpenGl_GlCore43*     )(&(*myFuncs));
1780   core43back = (OpenGl_GlCore43Back* )(&(*myFuncs));
1781
1782   if (!has44)
1783   {
1784     myGlVerMajor = 4;
1785     myGlVerMinor = 3;
1786     return;
1787   }
1788   core44     = (OpenGl_GlCore44*     )(&(*myFuncs));
1789   core44back = (OpenGl_GlCore44Back* )(&(*myFuncs));
1790 }
1791
1792 // =======================================================================
1793 // function : MemoryInfo
1794 // purpose  :
1795 // =======================================================================
1796 Standard_Size OpenGl_Context::AvailableMemory() const
1797 {
1798   if (atiMem)
1799   {
1800     // this is actually information for VBO pool
1801     // however because pools are mostly shared
1802     // it can be used for total GPU memory estimations
1803     GLint aMemInfo[4];
1804     aMemInfo[0] = 0;
1805     glGetIntegerv (GL_VBO_FREE_MEMORY_ATI, aMemInfo);
1806     // returned value is in KiB, however this maybe changed in future
1807     return Standard_Size(aMemInfo[0]) * 1024;
1808   }
1809   else if (nvxMem)
1810   {
1811     // current available dedicated video memory (in KiB), currently unused GPU memory
1812     GLint aMemInfo = 0;
1813     glGetIntegerv (GL_GPU_MEMORY_INFO_CURRENT_AVAILABLE_VIDMEM_NVX, &aMemInfo);
1814     return Standard_Size(aMemInfo) * 1024;
1815   }
1816   return 0;
1817 }
1818
1819 // =======================================================================
1820 // function : MemoryInfo
1821 // purpose  :
1822 // =======================================================================
1823 TCollection_AsciiString OpenGl_Context::MemoryInfo() const
1824 {
1825   TCollection_AsciiString anInfo;
1826   if (atiMem)
1827   {
1828     GLint aValues[4];
1829     memset (aValues, 0, sizeof(aValues));
1830     glGetIntegerv (GL_VBO_FREE_MEMORY_ATI, aValues);
1831
1832     // total memory free in the pool
1833     anInfo += TCollection_AsciiString ("  GPU free memory:    ") + (aValues[0] / 1024) + " MiB\n";
1834
1835     // largest available free block in the pool
1836     anInfo += TCollection_AsciiString ("  Largest free block: ") + (aValues[1] / 1024) + " MiB\n";
1837     if (aValues[2] != aValues[0])
1838     {
1839       // total auxiliary memory free
1840       anInfo += TCollection_AsciiString ("  Free memory:        ") + (aValues[2] / 1024) + " MiB\n";
1841     }
1842   }
1843   else if (nvxMem)
1844   {
1845     //current available dedicated video memory (in KiB), currently unused GPU memory
1846     GLint aValue = 0;
1847     glGetIntegerv (GL_GPU_MEMORY_INFO_CURRENT_AVAILABLE_VIDMEM_NVX, &aValue);
1848     anInfo += TCollection_AsciiString ("  GPU free memory:    ") + (aValue / 1024) + " MiB\n";
1849
1850     // dedicated video memory, total size (in KiB) of the GPU memory
1851     GLint aDedicated = 0;
1852     glGetIntegerv (GL_GPU_MEMORY_INFO_DEDICATED_VIDMEM_NVX, &aDedicated);
1853     anInfo += TCollection_AsciiString ("  GPU memory:         ") + (aDedicated / 1024) + " MiB\n";
1854
1855     // total available memory, total size (in KiB) of the memory available for allocations
1856     glGetIntegerv (GL_GPU_MEMORY_INFO_TOTAL_AVAILABLE_MEMORY_NVX, &aValue);
1857     if (aValue != aDedicated)
1858     {
1859       // different only for special configurations
1860       anInfo += TCollection_AsciiString ("  Total memory:       ") + (aValue / 1024) + " MiB\n";
1861     }
1862   }
1863   return anInfo;
1864 }
1865
1866
1867 // =======================================================================
1868 // function : GetResource
1869 // purpose  :
1870 // =======================================================================
1871 const Handle(OpenGl_Resource)& OpenGl_Context::GetResource (const TCollection_AsciiString& theKey) const
1872 {
1873   return mySharedResources->IsBound (theKey) ? mySharedResources->Find (theKey) : NULL_GL_RESOURCE;
1874 }
1875
1876 // =======================================================================
1877 // function : ShareResource
1878 // purpose  :
1879 // =======================================================================
1880 Standard_Boolean OpenGl_Context::ShareResource (const TCollection_AsciiString& theKey,
1881                                                 const Handle(OpenGl_Resource)& theResource)
1882 {
1883   if (theKey.IsEmpty() || theResource.IsNull())
1884   {
1885     return Standard_False;
1886   }
1887   return mySharedResources->Bind (theKey, theResource);
1888 }
1889
1890 // =======================================================================
1891 // function : ReleaseResource
1892 // purpose  :
1893 // =======================================================================
1894 void OpenGl_Context::ReleaseResource (const TCollection_AsciiString& theKey,
1895                                       const Standard_Boolean         theToDelay)
1896 {
1897   if (!mySharedResources->IsBound (theKey))
1898   {
1899     return;
1900   }
1901   const Handle(OpenGl_Resource)& aRes = mySharedResources->Find (theKey);
1902   if (aRes->GetRefCount() > 1)
1903   {
1904     return;
1905   }
1906
1907   if (theToDelay)
1908   {
1909     myDelayed->Bind (theKey, 1);
1910   }
1911   else
1912   {
1913     aRes->Release (this);
1914     mySharedResources->UnBind (theKey);
1915   }
1916 }
1917
1918 // =======================================================================
1919 // function : DelayedRelease
1920 // purpose  :
1921 // =======================================================================
1922 void OpenGl_Context::DelayedRelease (Handle(OpenGl_Resource)& theResource)
1923 {
1924   myUnusedResources->Prepend (theResource);
1925   theResource.Nullify();
1926 }
1927
1928 // =======================================================================
1929 // function : ReleaseDelayed
1930 // purpose  :
1931 // =======================================================================
1932 void OpenGl_Context::ReleaseDelayed()
1933 {
1934   // release queued elements
1935   while (!myUnusedResources->IsEmpty())
1936   {
1937     myUnusedResources->First()->Release (this);
1938     myUnusedResources->RemoveFirst();
1939   }
1940
1941   // release delayed shared resources
1942   NCollection_Vector<TCollection_AsciiString> aDeadList;
1943   for (NCollection_DataMap<TCollection_AsciiString, Standard_Integer>::Iterator anIter (*myDelayed);
1944        anIter.More(); anIter.Next())
1945   {
1946     if (++anIter.ChangeValue() <= 2)
1947     {
1948       continue; // postpone release one more frame to ensure noone use it periodically
1949     }
1950
1951     const TCollection_AsciiString& aKey = anIter.Key();
1952     if (!mySharedResources->IsBound (aKey))
1953     {
1954       // mixed unshared strategy delayed/undelayed was used!
1955       aDeadList.Append (aKey);
1956       continue;
1957     }
1958
1959     Handle(OpenGl_Resource)& aRes = mySharedResources->ChangeFind (aKey);
1960     if (aRes->GetRefCount() > 1)
1961     {
1962       // should be only 1 instance in mySharedResources
1963       // if not - resource was reused again
1964       aDeadList.Append (aKey);
1965       continue;
1966     }
1967
1968     // release resource if no one requiested it more than 2 redraw calls
1969     aRes->Release (this);
1970     mySharedResources->UnBind (aKey);
1971     aDeadList.Append (aKey);
1972   }
1973
1974   for (Standard_Integer anIter = 0; anIter < aDeadList.Length(); ++anIter)
1975   {
1976     myDelayed->UnBind (aDeadList.Value (anIter));
1977   }
1978 }