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