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