bc7ecf8bb8054d01bd4f19db2e7d64b6b9fb7673
[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_FrameBuffer.hxx>
30 #include <OpenGl_Sampler.hxx>
31 #include <OpenGl_ShaderManager.hxx>
32 #include <OpenGl_Workspace.hxx>
33 #include <OpenGl_AspectFace.hxx>
34 #include <Graphic3d_TransformUtils.hxx>
35
36 #include <Message_Messenger.hxx>
37
38 #include <NCollection_Vector.hxx>
39
40 #include <Standard_ProgramError.hxx>
41
42 IMPLEMENT_STANDARD_RTTIEXT(OpenGl_Context,Standard_Transient)
43
44 #if defined(HAVE_EGL)
45   #include <EGL/egl.h>
46   #ifdef _MSC_VER
47     #pragma comment(lib, "libEGL.lib")
48   #endif
49 #elif defined(_WIN32)
50   //
51 #elif defined(__APPLE__) && !defined(MACOSX_USE_GLX)
52   #include <dlfcn.h>
53   #if defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE
54     //
55   #else
56     #include <OpenGL/OpenGL.h>
57     #include <CoreGraphics/CoreGraphics.h>
58   #endif
59 #else
60   #include <GL/glx.h> // glXGetProcAddress()
61 #endif
62
63 #ifdef HAVE_GL2PS
64   #include <gl2ps.h>
65   #ifdef _MSC_VER
66     #pragma comment (lib, "gl2ps.lib")
67   #endif
68 #endif
69
70
71 namespace
72 {
73   static const Handle(OpenGl_Resource) NULL_GL_RESOURCE;
74   static const OpenGl_Mat4 THE_IDENTITY_MATRIX;
75
76   //! Add key-value pair to the dictionary.
77   static void addInfo (TColStd_IndexedDataMapOfStringString& theDict,
78                        const TCollection_AsciiString& theKey,
79                        const TCollection_AsciiString& theValue)
80   {
81     theDict.ChangeFromIndex (theDict.Add (theKey, theValue)) = theValue;
82   }
83
84   //! Add key-value pair to the dictionary.
85   static void addInfo (TColStd_IndexedDataMapOfStringString& theDict,
86                        const TCollection_AsciiString& theKey,
87                        const char* theValue)
88   {
89     TCollection_AsciiString aValue (theValue != NULL ? theValue : "");
90     theDict.ChangeFromIndex (theDict.Add (theKey, aValue)) = aValue;
91   }
92 }
93
94 // =======================================================================
95 // function : OpenGl_Context
96 // purpose  :
97 // =======================================================================
98 OpenGl_Context::OpenGl_Context (const Handle(OpenGl_Caps)& theCaps)
99 : core11     (NULL),
100   core11fwd  (NULL),
101   core15     (NULL),
102   core15fwd  (NULL),
103   core20     (NULL),
104   core20fwd  (NULL),
105   core32     (NULL),
106   core32back (NULL),
107   core33     (NULL),
108   core33back (NULL),
109   core41     (NULL),
110   core41back (NULL),
111   core42     (NULL),
112   core42back (NULL),
113   core43     (NULL),
114   core43back (NULL),
115   core44     (NULL),
116   core44back (NULL),
117   caps   (!theCaps.IsNull() ? theCaps : new OpenGl_Caps()),
118 #if defined(GL_ES_VERSION_2_0)
119   hasHighp   (Standard_False),
120   hasUintIndex(Standard_False),
121   hasTexRGBA8(Standard_False),
122 #else
123   hasHighp   (Standard_True),
124   hasUintIndex(Standard_True),
125   hasTexRGBA8(Standard_True),
126 #endif
127   arbNPTW  (Standard_False),
128   arbTexRG (Standard_False),
129   arbTexFloat (Standard_False),
130   arbTexBindless (NULL),
131   arbTBO (NULL),
132   arbTboRGB32 (Standard_False),
133   arbIns (NULL),
134   arbDbg (NULL),
135   arbFBO (NULL),
136   arbFBOBlit (NULL),
137   extFragDepth (Standard_False),
138   extGS  (NULL),
139   extBgra(Standard_False),
140   extAnis(Standard_False),
141   extPDS (Standard_False),
142   atiMem (Standard_False),
143   nvxMem (Standard_False),
144   mySharedResources (new OpenGl_ResourcesMap()),
145   myDelayed         (new OpenGl_DelayReleaseMap()),
146   myUnusedResources (new OpenGl_ResourcesStack()),
147   myClippingState (),
148   myGlLibHandle (NULL),
149   myFuncs (new OpenGl_GlFunctions()),
150   myAnisoMax   (1),
151   myTexClamp   (GL_CLAMP_TO_EDGE),
152   myMaxTexDim  (1024),
153   myMaxClipPlanes (6),
154   myMaxMsaaSamples(0),
155   myGlVerMajor (0),
156   myGlVerMinor (0),
157   myIsInitialized (Standard_False),
158   myIsStereoBuffers (Standard_False),
159   myIsGlNormalizeEnabled (Standard_False),
160   myHasRayTracing (Standard_False),
161   myHasRayTracingTextures (Standard_False),
162   myHasRayTracingAdaptiveSampling (Standard_False),
163 #if !defined(GL_ES_VERSION_2_0)
164   myPointSpriteOrig (GL_UPPER_LEFT),
165   myRenderMode (GL_RENDER),
166   myPolygonMode (GL_FILL),
167 #else
168   myPointSpriteOrig (0),
169   myRenderMode (0),
170   myPolygonMode (0),
171 #endif
172   myToCullBackFaces (false),
173   myReadBuffer (0),
174   myDrawBuffer (0),
175   myDefaultVao (0),
176   myIsGlDebugCtx (Standard_False),
177   myResolutionRatio (1.0f)
178 {
179   myViewport[0] = 0;
180   myViewport[1] = 0;
181   myViewport[2] = 0;
182   myViewport[3] = 0;
183
184   // system-dependent fields
185 #if defined(HAVE_EGL)
186   myDisplay  = (Aspect_Display          )EGL_NO_DISPLAY;
187   myWindow   = (Aspect_Drawable         )EGL_NO_SURFACE;
188   myGContext = (Aspect_RenderingContext )EGL_NO_CONTEXT;
189 #elif defined(_WIN32)
190   myWindow   = NULL;
191   myWindowDC = NULL;
192   myGContext = NULL;
193 #elif defined(__APPLE__) && !defined(MACOSX_USE_GLX)
194   // Vendors can not extend functionality on this system
195   // and developers are limited to OpenGL support provided by Mac OS X SDK.
196   // We retrieve function pointers from system library
197   // to generalize extensions support on all platforms.
198   // In this way we also reach binary compatibility benefit between OS releases
199   // if some newest functionality is optionally used.
200   // Notice that GL version / extension availability checks are required
201   // because function pointers may be available but not functionality itself
202   // (depends on renderer).
203 #if defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE
204   myGContext    = NULL;
205   myGlLibHandle = dlopen ("/System/Library/Frameworks/OpenGLES.framework/OpenGLES", RTLD_LAZY);
206 #else
207   myGContext    = NULL;
208   myGlLibHandle = dlopen ("/System/Library/Frameworks/OpenGL.framework/Versions/Current/OpenGL", RTLD_LAZY);
209 #endif
210 #else
211   myDisplay =  NULL;
212   myWindow   = 0;
213   myGContext = 0;
214 #endif
215
216   memset (myFuncs.operator->(), 0, sizeof(OpenGl_GlFunctions));
217   myShaderManager = new OpenGl_ShaderManager (this);
218 }
219
220 // =======================================================================
221 // function : ~OpenGl_Context
222 // purpose  :
223 // =======================================================================
224 OpenGl_Context::~OpenGl_Context()
225 {
226   // release clean up queue
227   ReleaseDelayed();
228
229 #if !defined(GL_ES_VERSION_2_0)
230   // release default VAO
231   if (myDefaultVao != 0
232    && IsValid()
233    && core32 != NULL)
234   {
235     core32->glDeleteVertexArrays (1, &myDefaultVao);
236   }
237   myDefaultVao = 0;
238 #endif
239
240   // release default FBO
241   if (!myDefaultFbo.IsNull())
242   {
243     myDefaultFbo->Release (this);
244     myDefaultFbo.Nullify();
245   }
246
247   // release shared resources if any
248   if (mySharedResources->GetRefCount() <= 1)
249   {
250     myShaderManager.Nullify();
251     for (NCollection_DataMap<TCollection_AsciiString, Handle(OpenGl_Resource)>::Iterator anIter (*mySharedResources);
252          anIter.More(); anIter.Next())
253     {
254       anIter.Value()->Release (this);
255     }
256
257     // release delayed resources added during deletion of shared resources
258     while (!myUnusedResources->IsEmpty())
259     {
260       myUnusedResources->First()->Release (this);
261       myUnusedResources->RemoveFirst();
262     }
263   }
264   else if (myShaderManager->IsSameContext (this))
265   {
266     myShaderManager->SetContext (NULL);
267   }
268   mySharedResources.Nullify();
269   myDelayed.Nullify();
270
271   // release sampler object
272   if (!myTexSampler.IsNull())
273   {
274     myTexSampler->Release (this);
275   }
276
277   if (arbDbg != NULL
278    && myIsGlDebugCtx
279    && IsValid())
280   {
281     // reset callback
282   #if !defined(GL_ES_VERSION_2_0)
283     void* aPtr = NULL;
284     glGetPointerv (GL_DEBUG_CALLBACK_USER_PARAM, &aPtr);
285     if (aPtr == this)
286   #endif
287     {
288       arbDbg->glDebugMessageCallback (NULL, NULL);
289     }
290     myIsGlDebugCtx = Standard_False;
291   }
292 }
293
294 // =======================================================================
295 // function : forcedRelease
296 // purpose  :
297 // =======================================================================
298 void OpenGl_Context::forcedRelease()
299 {
300   ReleaseDelayed();
301   for (NCollection_DataMap<TCollection_AsciiString, Handle(OpenGl_Resource)>::Iterator anIter (*mySharedResources);
302        anIter.More(); anIter.Next())
303   {
304     anIter.Value()->Release (this);
305   }
306   mySharedResources->Clear();
307   myShaderManager->clear();
308   myShaderManager->SetContext (NULL);
309
310   // release delayed resources added during deletion of shared resources
311   while (!myUnusedResources->IsEmpty())
312   {
313     myUnusedResources->First()->Release (this);
314     myUnusedResources->RemoveFirst();
315   }
316 }
317
318 // =======================================================================
319 // function : ResizeViewport
320 // purpose  :
321 // =======================================================================
322 void OpenGl_Context::ResizeViewport (const Standard_Integer* theRect)
323 {
324   core11fwd->glViewport (theRect[0], theRect[1], theRect[2], theRect[3]);
325   myViewport[0] = theRect[0];
326   myViewport[1] = theRect[1];
327   myViewport[2] = theRect[2];
328   myViewport[3] = theRect[3];
329 }
330
331 #if !defined(GL_ES_VERSION_2_0)
332 inline Standard_Integer stereoToMonoBuffer (const Standard_Integer theBuffer)
333 {
334   switch (theBuffer)
335   {
336     case GL_BACK_LEFT:
337     case GL_BACK_RIGHT:
338       return GL_BACK;
339     case GL_FRONT_LEFT:
340     case GL_FRONT_RIGHT:
341       return GL_FRONT;
342     default:
343       return theBuffer;
344   }
345 }
346 #endif
347
348 // =======================================================================
349 // function : SetReadBuffer
350 // purpose  :
351 // =======================================================================
352 void OpenGl_Context::SetReadBuffer (const Standard_Integer theReadBuffer)
353 {
354 #if !defined(GL_ES_VERSION_2_0)
355   myReadBuffer = !myIsStereoBuffers ? stereoToMonoBuffer (theReadBuffer) : theReadBuffer;
356   if (myReadBuffer < GL_COLOR_ATTACHMENT0
357    && arbFBO != NULL)
358   {
359     arbFBO->glBindFramebuffer (GL_FRAMEBUFFER, OpenGl_FrameBuffer::NO_FRAMEBUFFER);
360   }
361   ::glReadBuffer (myReadBuffer);
362 #else
363   (void )theReadBuffer;
364 #endif
365 }
366
367 // =======================================================================
368 // function : SetDrawBuffer
369 // purpose  :
370 // =======================================================================
371 void OpenGl_Context::SetDrawBuffer (const Standard_Integer theDrawBuffer)
372 {
373 #if !defined(GL_ES_VERSION_2_0)
374   myDrawBuffer = !myIsStereoBuffers ? stereoToMonoBuffer (theDrawBuffer) : theDrawBuffer;
375   if (myDrawBuffer < GL_COLOR_ATTACHMENT0
376    && arbFBO != NULL)
377   {
378     arbFBO->glBindFramebuffer (GL_FRAMEBUFFER, OpenGl_FrameBuffer::NO_FRAMEBUFFER);
379   }
380   ::glDrawBuffer (myDrawBuffer);
381 #else
382   (void )theDrawBuffer;
383 #endif
384 }
385
386 // =======================================================================
387 // function : SetCullBackFaces
388 // purpose  :
389 // =======================================================================
390 void OpenGl_Context::SetCullBackFaces (bool theToEnable)
391 {
392   if (myToCullBackFaces == theToEnable)
393   {
394     return;
395   }
396
397   myToCullBackFaces = theToEnable;
398   if (theToEnable)
399   {
400     //glCullFace (GL_BACK); GL_BACK by default
401     core11fwd->glEnable (GL_CULL_FACE);
402   }
403   else
404   {
405     core11fwd->glDisable (GL_CULL_FACE);
406   }
407 }
408
409 // =======================================================================
410 // function : FetchState
411 // purpose  :
412 // =======================================================================
413 void OpenGl_Context::FetchState()
414 {
415 #if !defined(GL_ES_VERSION_2_0)
416   // cache feedback mode state
417   if (core11 != NULL)
418   {
419     ::glGetIntegerv (GL_RENDER_MODE, &myRenderMode);
420   }
421
422   // cache buffers state
423   ::glGetIntegerv (GL_READ_BUFFER, &myReadBuffer);
424   ::glGetIntegerv (GL_DRAW_BUFFER, &myDrawBuffer);
425 #endif
426 }
427
428 // =======================================================================
429 // function : Share
430 // purpose  :
431 // =======================================================================
432 void OpenGl_Context::Share (const Handle(OpenGl_Context)& theShareCtx)
433 {
434   if (!theShareCtx.IsNull())
435   {
436     mySharedResources = theShareCtx->mySharedResources;
437     myDelayed         = theShareCtx->myDelayed;
438     myUnusedResources = theShareCtx->myUnusedResources;
439     myShaderManager   = theShareCtx->myShaderManager;
440   }
441 }
442
443 #if !defined(__APPLE__) || defined(MACOSX_USE_GLX)
444
445 // =======================================================================
446 // function : IsCurrent
447 // purpose  :
448 // =======================================================================
449 Standard_Boolean OpenGl_Context::IsCurrent() const
450 {
451 #if defined(HAVE_EGL)
452   if ((EGLDisplay )myDisplay  == EGL_NO_DISPLAY
453    || (EGLSurface )myWindow   == EGL_NO_SURFACE
454    || (EGLContext )myGContext == EGL_NO_CONTEXT)
455   {
456     return Standard_False;
457   }
458
459   return (((EGLDisplay )myDisplay  == eglGetCurrentDisplay())
460        && ((EGLContext )myGContext == eglGetCurrentContext())
461        && ((EGLSurface )myWindow   == eglGetCurrentSurface (EGL_DRAW)));
462 #elif defined(_WIN32)
463   if (myWindowDC == NULL || myGContext == NULL)
464   {
465     return Standard_False;
466   }
467   return (( (HDC )myWindowDC == wglGetCurrentDC())
468       && ((HGLRC )myGContext == wglGetCurrentContext()));
469 #else
470   if (myDisplay == NULL || myWindow == 0 || myGContext == 0)
471   {
472     return Standard_False;
473   }
474
475   return (   ((Display* )myDisplay  == glXGetCurrentDisplay())
476        &&  ((GLXContext )myGContext == glXGetCurrentContext())
477        && ((GLXDrawable )myWindow   == glXGetCurrentDrawable()));
478 #endif
479 }
480
481 // =======================================================================
482 // function : MakeCurrent
483 // purpose  :
484 // =======================================================================
485 Standard_Boolean OpenGl_Context::MakeCurrent()
486 {
487 #if defined(HAVE_EGL)
488   if ((EGLDisplay )myDisplay  == EGL_NO_DISPLAY
489    || (EGLSurface )myWindow   == EGL_NO_SURFACE
490    || (EGLContext )myGContext == EGL_NO_CONTEXT)
491   {
492     Standard_ProgramError_Raise_if (myIsInitialized, "OpenGl_Context::Init() should be called before!");
493     return Standard_False;
494   }
495
496   if (eglMakeCurrent ((EGLDisplay )myDisplay, (EGLSurface )myWindow, (EGLSurface )myWindow, (EGLContext )myGContext) != EGL_TRUE)
497   {
498     // if there is no current context it might be impossible to use glGetError() correctly
499     PushMessage (GL_DEBUG_SOURCE_WINDOW_SYSTEM, GL_DEBUG_TYPE_ERROR, 0, GL_DEBUG_SEVERITY_HIGH,
500                  "eglMakeCurrent() has failed!");
501     myIsInitialized = Standard_False;
502     return Standard_False;
503   }
504 #elif defined(_WIN32)
505   if (myWindowDC == NULL || myGContext == NULL)
506   {
507     Standard_ProgramError_Raise_if (myIsInitialized, "OpenGl_Context::Init() should be called before!");
508     return Standard_False;
509   }
510
511   // technically it should be safe to activate already bound GL context
512   // however some drivers (Intel etc.) may FAIL doing this for unknown reason
513   if (IsCurrent())
514   {
515     myShaderManager->SetContext (this);
516     return Standard_True;
517   }
518   else if (wglMakeCurrent ((HDC )myWindowDC, (HGLRC )myGContext) != TRUE)
519   {
520     // notice that glGetError() couldn't be used here!
521     wchar_t* aMsgBuff = NULL;
522     DWORD anErrorCode = GetLastError();
523     FormatMessageW (FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
524                     NULL, anErrorCode, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (wchar_t* )&aMsgBuff, 0, NULL);
525     TCollection_ExtendedString aMsg ("wglMakeCurrent() has failed. ");
526     if (aMsgBuff != NULL)
527     {
528       aMsg += (Standard_ExtString )aMsgBuff;
529       LocalFree (aMsgBuff);
530     }
531     PushMessage (GL_DEBUG_SOURCE_WINDOW_SYSTEM, GL_DEBUG_TYPE_ERROR, (unsigned int )anErrorCode, GL_DEBUG_SEVERITY_HIGH, aMsg);
532     myIsInitialized = Standard_False;
533     return Standard_False;
534   }
535 #else
536   if (myDisplay == NULL || myWindow == 0 || myGContext == 0)
537   {
538     Standard_ProgramError_Raise_if (myIsInitialized, "OpenGl_Context::Init() should be called before!");
539     return Standard_False;
540   }
541
542   if (!glXMakeCurrent ((Display* )myDisplay, (GLXDrawable )myWindow, (GLXContext )myGContext))
543   {
544     // if there is no current context it might be impossible to use glGetError() correctly
545     PushMessage (GL_DEBUG_SOURCE_WINDOW_SYSTEM, GL_DEBUG_TYPE_ERROR, 0, GL_DEBUG_SEVERITY_HIGH,
546                  "glXMakeCurrent() has failed!");
547     myIsInitialized = Standard_False;
548     return Standard_False;
549   }
550 #endif
551   myShaderManager->SetContext (this);
552   return Standard_True;
553 }
554
555 // =======================================================================
556 // function : SwapBuffers
557 // purpose  :
558 // =======================================================================
559 void OpenGl_Context::SwapBuffers()
560 {
561 #if defined(HAVE_EGL)
562   if ((EGLSurface )myWindow != EGL_NO_SURFACE)
563   {
564     eglSwapBuffers ((EGLDisplay )myDisplay, (EGLSurface )myWindow);
565   }
566 #elif defined(_WIN32)
567   if ((HDC )myWindowDC != NULL)
568   {
569     ::SwapBuffers ((HDC )myWindowDC);
570     glFlush();
571   }
572 #else
573   if ((Display* )myDisplay != NULL)
574   {
575     glXSwapBuffers ((Display* )myDisplay, (GLXDrawable )myWindow);
576   }
577 #endif
578 }
579
580 #endif // __APPLE__
581
582 // =======================================================================
583 // function : SetSwapInterval
584 // purpose  :
585 // =======================================================================
586 Standard_Boolean OpenGl_Context::SetSwapInterval (const Standard_Integer theInterval)
587 {
588 #if defined(HAVE_EGL)
589   if (::eglSwapInterval ((EGLDisplay )myDisplay, theInterval) == EGL_TRUE)
590   {
591     return Standard_True;
592   }
593 #elif defined(_WIN32)
594   if (myFuncs->wglSwapIntervalEXT != NULL)
595   {
596     myFuncs->wglSwapIntervalEXT (theInterval);
597     return Standard_True;
598   }
599 #elif defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE
600   //
601 #elif defined(__APPLE__)
602   if (::CGLSetParameter (CGLGetCurrentContext(), kCGLCPSwapInterval, &theInterval) == kCGLNoError)
603   {
604     return Standard_True;
605   }
606 #else
607   if (theInterval == -1
608    && myFuncs->glXSwapIntervalEXT != NULL)
609   {
610     typedef int (*glXSwapIntervalEXT_t_x)(Display* theDisplay, GLXDrawable theDrawable, int theInterval);
611     glXSwapIntervalEXT_t_x aFuncPtr = (glXSwapIntervalEXT_t_x )myFuncs->glXSwapIntervalEXT;
612     aFuncPtr ((Display* )myDisplay, (GLXDrawable )myWindow, theInterval);
613     return Standard_True;
614   }
615   else if (myFuncs->glXSwapIntervalSGI != NULL)
616   {
617     myFuncs->glXSwapIntervalSGI (theInterval);
618     return Standard_True;
619   }
620 #endif
621   return Standard_False;
622 }
623
624 // =======================================================================
625 // function : findProc
626 // purpose  :
627 // =======================================================================
628 void* OpenGl_Context::findProc (const char* theFuncName)
629 {
630 #if defined(HAVE_EGL)
631   return (void* )eglGetProcAddress (theFuncName);
632 #elif defined(_WIN32)
633   return (void* )wglGetProcAddress (theFuncName);
634 #elif defined(__APPLE__) && !defined(MACOSX_USE_GLX)
635   return (myGlLibHandle != NULL) ? dlsym (myGlLibHandle, theFuncName) : NULL;
636 #else
637   return (void* )glXGetProcAddress ((const GLubyte* )theFuncName);
638 #endif
639 }
640
641 // =======================================================================
642 // function : CheckExtension
643 // purpose  :
644 // =======================================================================
645 Standard_Boolean OpenGl_Context::CheckExtension (const char* theExtName) const
646 {
647   if (theExtName  == NULL)
648   {
649 #ifdef OCCT_DEBUG
650     std::cerr << "CheckExtension called with NULL string!\n";
651 #endif
652     return Standard_False;
653   }
654
655 #if !defined(GL_ES_VERSION_2_0)
656   // available since OpenGL 3.0
657   // and the ONLY way to check extensions with OpenGL 3.1+ core profile
658   if (IsGlGreaterEqual (3, 0)
659    && myFuncs->glGetStringi != NULL)
660   {
661     GLint anExtNb = 0;
662     ::glGetIntegerv (GL_NUM_EXTENSIONS, &anExtNb);
663     const size_t anExtNameLen = strlen (theExtName);
664     for (GLint anIter = 0; anIter < anExtNb; ++anIter)
665     {
666       const char* anExtension = (const char* )myFuncs->glGetStringi (GL_EXTENSIONS, (GLuint )anIter);
667       const size_t aTestExtNameLen = strlen (anExtension);
668       if (aTestExtNameLen == anExtNameLen
669        && strncmp (anExtension, theExtName, anExtNameLen) == 0)
670       {
671         return Standard_True;
672       }
673     }
674     return Standard_False;
675   }
676 #endif
677
678   // use old way with huge string for all extensions
679   const char* anExtString = (const char* )glGetString (GL_EXTENSIONS);
680   if (anExtString == NULL)
681   {
682     Messenger()->Send ("TKOpenGL: glGetString (GL_EXTENSIONS) has returned NULL! No GL context?", Message_Warning);
683     return Standard_False;
684   }
685   return CheckExtension (anExtString, theExtName);
686 }
687
688 // =======================================================================
689 // function : CheckExtension
690 // purpose  :
691 // =======================================================================
692 Standard_Boolean OpenGl_Context::CheckExtension (const char* theExtString,
693                                                  const char* theExtName)
694 {
695   if (theExtString == NULL)
696   {
697     return Standard_False;
698   }
699
700   // Search for theExtName in the extensions string.
701   // Use of strstr() is not sufficient because extension names can be prefixes of other extension names.
702   char* aPtrIter = (char* )theExtString;
703   const char*  aPtrEnd      = aPtrIter + strlen (theExtString);
704   const size_t anExtNameLen = strlen (theExtName);
705   while (aPtrIter < aPtrEnd)
706   {
707     const size_t n = strcspn (aPtrIter, " ");
708     if ((n == anExtNameLen) && (strncmp (aPtrIter, theExtName, anExtNameLen) == 0))
709     {
710       return Standard_True;
711     }
712     aPtrIter += (n + 1);
713   }
714   return Standard_False;
715 }
716
717 #if !defined(__APPLE__) || defined(MACOSX_USE_GLX)
718
719 // =======================================================================
720 // function : Init
721 // purpose  :
722 // =======================================================================
723 Standard_Boolean OpenGl_Context::Init (const Standard_Boolean theIsCoreProfile)
724 {
725   if (myIsInitialized)
726   {
727     return Standard_True;
728   }
729
730 #if defined(HAVE_EGL)
731   myDisplay  = (Aspect_Display )eglGetCurrentDisplay();
732   myGContext = (Aspect_RenderingContext )eglGetCurrentContext();
733   myWindow   = (Aspect_Drawable )eglGetCurrentSurface(EGL_DRAW);
734 #elif defined(_WIN32)
735   myWindowDC = (Aspect_Handle )wglGetCurrentDC();
736   myGContext = (Aspect_RenderingContext )wglGetCurrentContext();
737 #else
738   myDisplay  = (Aspect_Display )glXGetCurrentDisplay();
739   myGContext = (Aspect_RenderingContext )glXGetCurrentContext();
740   myWindow   = (Aspect_Drawable )glXGetCurrentDrawable();
741 #endif
742   if (myGContext == NULL)
743   {
744     return Standard_False;
745   }
746
747   init (theIsCoreProfile);
748   myIsInitialized = Standard_True;
749   return Standard_True;
750 }
751
752 #endif // __APPLE__
753
754 // =======================================================================
755 // function : Init
756 // purpose  :
757 // =======================================================================
758 #if defined(HAVE_EGL)
759 Standard_Boolean OpenGl_Context::Init (const Aspect_Drawable         theEglSurface,
760                                        const Aspect_Display          theEglDisplay,
761                                        const Aspect_RenderingContext theEglContext,
762                                        const Standard_Boolean        theIsCoreProfile)
763 #elif defined(_WIN32)
764 Standard_Boolean OpenGl_Context::Init (const Aspect_Handle           theWindow,
765                                        const Aspect_Handle           theWindowDC,
766                                        const Aspect_RenderingContext theGContext,
767                                        const Standard_Boolean        theIsCoreProfile)
768 #elif defined(__APPLE__) && !defined(MACOSX_USE_GLX)
769
770 #if defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE
771 Standard_Boolean OpenGl_Context::Init (EAGLContext*                  theGContext,
772                                        const Standard_Boolean        theIsCoreProfile)
773 #else
774 Standard_Boolean OpenGl_Context::Init (NSOpenGLContext*              theGContext,
775                                        const Standard_Boolean        theIsCoreProfile)
776 #endif
777
778 #else
779 Standard_Boolean OpenGl_Context::Init (const Aspect_Drawable         theWindow,
780                                        const Aspect_Display          theDisplay,
781                                        const Aspect_RenderingContext theGContext,
782                                        const Standard_Boolean        theIsCoreProfile)
783 #endif
784 {
785   Standard_ProgramError_Raise_if (myIsInitialized, "OpenGl_Context::Init() should be called only once!");
786 #if defined(HAVE_EGL)
787   myWindow   = theEglSurface;
788   myGContext = theEglContext;
789   myDisplay  = theEglDisplay;
790 #elif defined(_WIN32)
791   myWindow   = theWindow;
792   myGContext = theGContext;
793   myWindowDC = theWindowDC;
794 #elif defined(__APPLE__) && !defined(MACOSX_USE_GLX)
795   myGContext = theGContext;
796 #else
797   myWindow   = theWindow;
798   myGContext = theGContext;
799   myDisplay  = theDisplay;
800 #endif
801   if (myGContext == NULL || !MakeCurrent())
802   {
803     return Standard_False;
804   }
805
806   init (theIsCoreProfile);
807   myIsInitialized = Standard_True;
808   return Standard_True;
809 }
810
811 // =======================================================================
812 // function : ResetErrors
813 // purpose  :
814 // =======================================================================
815 void OpenGl_Context::ResetErrors (const bool theToPrintErrors)
816 {
817   int aPrevErr = 0;
818   int anErr    = ::glGetError();
819   if (!theToPrintErrors)
820   {
821     for (; anErr != GL_NO_ERROR && aPrevErr != anErr; aPrevErr = anErr, anErr = ::glGetError())
822     {
823       //
824     }
825     return;
826   }
827
828   for (; anErr != GL_NO_ERROR && aPrevErr != anErr; aPrevErr = anErr, anErr = ::glGetError())
829   {
830     TCollection_ExtendedString anErrId;
831     switch (anErr)
832     {
833       case GL_INVALID_ENUM:      anErrId = "GL_INVALID_ENUM";      break;
834       case GL_INVALID_VALUE:     anErrId = "GL_INVALID_VALUE";     break;
835       case GL_INVALID_OPERATION: anErrId = "GL_INVALID_OPERATION"; break;
836     #ifdef GL_STACK_OVERFLOW
837       case GL_STACK_OVERFLOW:    anErrId = "GL_STACK_OVERFLOW";    break;
838       case GL_STACK_UNDERFLOW:   anErrId = "GL_STACK_UNDERFLOW";   break;
839     #endif
840       case GL_OUT_OF_MEMORY:     anErrId = "GL_OUT_OF_MEMORY";     break;
841       case GL_INVALID_FRAMEBUFFER_OPERATION:
842         anErrId = "GL_INVALID_FRAMEBUFFER_OPERATION";
843         break;
844       default:
845         anErrId = TCollection_ExtendedString("#") + anErr;
846         break;
847     }
848
849     const TCollection_ExtendedString aMsg = TCollection_ExtendedString ("Unhandled GL error: ") + anErrId;
850     PushMessage (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_OTHER, 0, GL_DEBUG_SEVERITY_LOW, aMsg);
851   }
852 }
853
854 // =======================================================================
855 // function : ReadGlVersion
856 // purpose  :
857 // =======================================================================
858 void OpenGl_Context::ReadGlVersion (Standard_Integer& theGlVerMajor,
859                                     Standard_Integer& theGlVerMinor)
860 {
861   // reset values
862   theGlVerMajor = 0;
863   theGlVerMinor = 0;
864
865 #ifdef GL_MAJOR_VERSION
866   // available since OpenGL 3.0 and OpenGL 3.0 ES
867   GLint aMajor = 0, aMinor = 0;
868   glGetIntegerv (GL_MAJOR_VERSION, &aMajor);
869   glGetIntegerv (GL_MINOR_VERSION, &aMinor);
870   // glGetError() sometimes does not report an error here even if
871   // GL does not know GL_MAJOR_VERSION and GL_MINOR_VERSION constants.
872   // This happens on some renderers like e.g. Cygwin MESA.
873   // Thus checking additionally if GL has put anything to
874   // the output variables.
875   if (::glGetError() == GL_NO_ERROR && aMajor != 0 && aMinor != 0)
876   {
877     theGlVerMajor = aMajor;
878     theGlVerMinor = aMinor;
879     return;
880   }
881   for (GLenum anErr = ::glGetError(), aPrevErr = GL_NO_ERROR;; aPrevErr = anErr, anErr = ::glGetError())
882   {
883     if (anErr == GL_NO_ERROR
884      || anErr == aPrevErr)
885     {
886       break;
887     }
888   }
889 #endif
890
891   // Read version string.
892   // Notice that only first two numbers split by point '2.1 XXXXX' are significant.
893   // Following trash (after space) is vendor-specific.
894   // New drivers also returns micro version of GL like '3.3.0' which has no meaning
895   // and should be considered as vendor-specific too.
896   const char* aVerStr = (const char* )glGetString (GL_VERSION);
897   if (aVerStr == NULL || *aVerStr == '\0')
898   {
899     // invalid GL context
900     return;
901   }
902
903 //#if defined(GL_ES_VERSION_2_0)
904   // skip "OpenGL ES-** " section
905   for (; *aVerStr != '\0'; ++aVerStr)
906   {
907     if (*aVerStr >= '0' && *aVerStr <= '9')
908     {
909       break;
910     }
911   }
912 //#endif
913
914   // parse string for major number
915   char aMajorStr[32];
916   char aMinorStr[32];
917   size_t aMajIter = 0;
918   while (aVerStr[aMajIter] >= '0' && aVerStr[aMajIter] <= '9')
919   {
920     ++aMajIter;
921   }
922   if (aMajIter == 0 || aMajIter >= sizeof(aMajorStr))
923   {
924     return;
925   }
926   memcpy (aMajorStr, aVerStr, aMajIter);
927   aMajorStr[aMajIter] = '\0';
928
929   // parse string for minor number
930   aVerStr += aMajIter + 1;
931   size_t aMinIter = 0;
932   while (aVerStr[aMinIter] >= '0' && aVerStr[aMinIter] <= '9')
933   {
934     ++aMinIter;
935   }
936   if (aMinIter == 0 || aMinIter >= sizeof(aMinorStr))
937   {
938     return;
939   }
940   memcpy (aMinorStr, aVerStr, aMinIter);
941   aMinorStr[aMinIter] = '\0';
942
943   // read numbers
944   theGlVerMajor = atoi (aMajorStr);
945   theGlVerMinor = atoi (aMinorStr);
946
947   if (theGlVerMajor <= 0)
948   {
949     theGlVerMajor = 0;
950     theGlVerMinor = 0;
951   }
952 }
953
954 static Standard_CString THE_DBGMSG_UNKNOWN = "UNKNOWN";
955 static Standard_CString THE_DBGMSG_SOURCES[] =
956 {
957   ".OpenGL",    // GL_DEBUG_SOURCE_API
958   ".WinSystem", // GL_DEBUG_SOURCE_WINDOW_SYSTEM
959   ".GLSL",      // GL_DEBUG_SOURCE_SHADER_COMPILER
960   ".3rdParty",  // GL_DEBUG_SOURCE_THIRD_PARTY
961   "",           // GL_DEBUG_SOURCE_APPLICATION
962   ".Other"      // GL_DEBUG_SOURCE_OTHER
963 };
964
965 static Standard_CString THE_DBGMSG_TYPES[] =
966 {
967   "Error",           // GL_DEBUG_TYPE_ERROR
968   "Deprecated",      // GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR
969   "Undef. behavior", // GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR
970   "Portability",     // GL_DEBUG_TYPE_PORTABILITY
971   "Performance",     // GL_DEBUG_TYPE_PERFORMANCE
972   "Other"            // GL_DEBUG_TYPE_OTHER
973 };
974
975 static Standard_CString THE_DBGMSG_SEV_HIGH   = "High";   // GL_DEBUG_SEVERITY_HIGH
976 static Standard_CString THE_DBGMSG_SEV_MEDIUM = "Medium"; // GL_DEBUG_SEVERITY_MEDIUM
977 static Standard_CString THE_DBGMSG_SEV_LOW    = "Low";    // GL_DEBUG_SEVERITY_LOW
978
979 //! Callback for GL_ARB_debug_output extension
980 static void APIENTRY debugCallbackWrap(unsigned int theSource,
981                                        unsigned int theType,
982                                        unsigned int theId,
983                                        unsigned int theSeverity,
984                                        int          /*theLength*/,
985                                        const char*  theMessage,
986                                        const void*  theUserParam)
987 {
988   OpenGl_Context* aCtx = (OpenGl_Context* )theUserParam;
989   aCtx->PushMessage (theSource, theType, theId, theSeverity, theMessage);
990 }
991
992 // =======================================================================
993 // function : PushMessage
994 // purpose  :
995 // =======================================================================
996 void OpenGl_Context::PushMessage (const unsigned int theSource,
997                                   const unsigned int theType,
998                                   const unsigned int theId,
999                                   const unsigned int theSeverity,
1000                                   const TCollection_ExtendedString& theMessage)
1001 {
1002   if (caps->suppressExtraMsg
1003    && theSource >= GL_DEBUG_SOURCE_API
1004    && theSource <= GL_DEBUG_SOURCE_OTHER
1005    && myFilters[theSource - GL_DEBUG_SOURCE_API].Contains (theId))
1006   {
1007     return;
1008   }
1009
1010   Standard_CString& aSrc = (theSource >= GL_DEBUG_SOURCE_API
1011                         && theSource <= GL_DEBUG_SOURCE_OTHER)
1012                          ? THE_DBGMSG_SOURCES[theSource - GL_DEBUG_SOURCE_API]
1013                          : THE_DBGMSG_UNKNOWN;
1014   Standard_CString& aType = (theType >= GL_DEBUG_TYPE_ERROR
1015                          && theType <= GL_DEBUG_TYPE_OTHER)
1016                           ? THE_DBGMSG_TYPES[theType - GL_DEBUG_TYPE_ERROR]
1017                           : THE_DBGMSG_UNKNOWN;
1018   Standard_CString& aSev = theSeverity == GL_DEBUG_SEVERITY_HIGH
1019                          ? THE_DBGMSG_SEV_HIGH
1020                          : (theSeverity == GL_DEBUG_SEVERITY_MEDIUM
1021                           ? THE_DBGMSG_SEV_MEDIUM
1022                           : THE_DBGMSG_SEV_LOW);
1023   Message_Gravity aGrav = theSeverity == GL_DEBUG_SEVERITY_HIGH
1024                         ? Message_Alarm
1025                         : (theSeverity == GL_DEBUG_SEVERITY_MEDIUM
1026                          ? Message_Warning
1027                          : Message_Info);
1028
1029   TCollection_ExtendedString aMsg;
1030   aMsg += "TKOpenGl"; aMsg += aSrc;
1031   aMsg += " | Type: ";        aMsg += aType;
1032   aMsg += " | ID: ";          aMsg += (Standard_Integer )theId;
1033   aMsg += " | Severity: ";    aMsg += aSev;
1034   aMsg += " | Message:\n  ";
1035   aMsg += theMessage;
1036   Messenger()->Send (aMsg, aGrav);
1037 }
1038
1039 // =======================================================================
1040 // function : ExcludeMessage
1041 // purpose  :
1042 // ======================================================================
1043 Standard_Boolean OpenGl_Context::ExcludeMessage (const unsigned int theSource,
1044                                                  const unsigned int theId)
1045 {
1046   return theSource >= GL_DEBUG_SOURCE_API
1047       && theSource <= GL_DEBUG_SOURCE_OTHER
1048       && myFilters[theSource - GL_DEBUG_SOURCE_API].Add (theId);
1049 }
1050
1051 // =======================================================================
1052 // function : IncludeMessage
1053 // purpose  :
1054 // ======================================================================
1055 Standard_Boolean OpenGl_Context::IncludeMessage (const unsigned int theSource,
1056                                                  const unsigned int theId)
1057 {
1058   return theSource >= GL_DEBUG_SOURCE_API
1059       && theSource <= GL_DEBUG_SOURCE_OTHER
1060       && myFilters[theSource - GL_DEBUG_SOURCE_API].Remove (theId);
1061 }
1062
1063 // =======================================================================
1064 // function : checkWrongVersion
1065 // purpose  :
1066 // ======================================================================
1067 void OpenGl_Context::checkWrongVersion (const Standard_Integer theGlVerMajor,
1068                                         const Standard_Integer theGlVerMinor)
1069 {
1070   if (!IsGlGreaterEqual (theGlVerMajor, theGlVerMinor))
1071   {
1072     return;
1073   }
1074
1075   TCollection_ExtendedString aMsg = TCollection_ExtendedString()
1076     + "Error! OpenGL context reports version "
1077     + myGlVerMajor  + "." + myGlVerMinor
1078     + " but does not export required functions for "
1079     + theGlVerMajor + "." + theGlVerMinor;
1080   PushMessage (GL_DEBUG_SOURCE_APPLICATION,
1081                GL_DEBUG_TYPE_ERROR,
1082                0,
1083                GL_DEBUG_SEVERITY_HIGH,
1084                aMsg);
1085 }
1086
1087 // =======================================================================
1088 // function : init
1089 // purpose  :
1090 // =======================================================================
1091 void OpenGl_Context::init (const Standard_Boolean theIsCoreProfile)
1092 {
1093   // read version
1094   myGlVerMajor = 0;
1095   myGlVerMinor = 0;
1096   myMaxMsaaSamples = 0;
1097   ReadGlVersion (myGlVerMajor, myGlVerMinor);
1098   myVendor = (const char* )::glGetString (GL_VENDOR);
1099   if (!caps->ffpEnable
1100    && !IsGlGreaterEqual (2, 0))
1101   {
1102     caps->ffpEnable = true;
1103     TCollection_ExtendedString aMsg =
1104       TCollection_ExtendedString("OpenGL driver is too old! Context info:\n")
1105                                + "    Vendor:   " + (const char* )::glGetString (GL_VENDOR)   + "\n"
1106                                + "    Renderer: " + (const char* )::glGetString (GL_RENDERER) + "\n"
1107                                + "    Version:  " + (const char* )::glGetString (GL_VERSION)  + "\n"
1108                                + "  Fallback using deprecated fixed-function pipeline.\n"
1109                                + "  Visualization might work incorrectly.\n"
1110                                  "  Consider upgrading the graphics driver.";
1111     PushMessage (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_PORTABILITY, 0, GL_DEBUG_SEVERITY_HIGH, aMsg);
1112   }
1113
1114 #if defined(GL_ES_VERSION_2_0)
1115   (void )theIsCoreProfile;
1116   const bool isCoreProfile = false;
1117 #else
1118
1119   if (myVendor.Search ("NVIDIA") != -1)
1120   {
1121     // Buffer detailed info: Buffer object 1 (bound to GL_ARRAY_BUFFER_ARB, usage hint is GL_STATIC_DRAW)
1122     // will use VIDEO memory as the source for buffer object operations.
1123     ExcludeMessage (GL_DEBUG_SOURCE_API, 131185);
1124   }
1125   if (IsGlGreaterEqual (3, 0))
1126   {
1127     // retrieve auxiliary function in advance
1128     FindProc ("glGetStringi", myFuncs->glGetStringi);
1129   }
1130
1131   bool isCoreProfile = false;
1132   if (IsGlGreaterEqual (3, 2))
1133   {
1134     isCoreProfile = (theIsCoreProfile == Standard_True);
1135
1136     // detect Core profile
1137     if (!isCoreProfile)
1138     {
1139       GLint aProfile = 0;
1140       ::glGetIntegerv (GL_CONTEXT_PROFILE_MASK, &aProfile);
1141       isCoreProfile = (aProfile & GL_CONTEXT_CORE_PROFILE_BIT) != 0;
1142     }
1143   }
1144 #endif
1145
1146   core11     = NULL;
1147   if (!isCoreProfile)
1148   {
1149     core11 = (OpenGl_GlCore11* )(&(*myFuncs));
1150   }
1151   core11fwd  = (OpenGl_GlCore11Fwd* )(&(*myFuncs));
1152   core15     = NULL;
1153   core15fwd  = NULL;
1154   core20     = NULL;
1155   core20fwd  = NULL;
1156   core32     = NULL;
1157   core32back = NULL;
1158   core33     = NULL;
1159   core33back = NULL;
1160   core41     = NULL;
1161   core41back = NULL;
1162   core42     = NULL;
1163   core42back = NULL;
1164   core43     = NULL;
1165   core43back = NULL;
1166   core44     = NULL;
1167   core44back = NULL;
1168   arbTBO     = NULL;
1169   arbTboRGB32 = Standard_False;
1170   arbIns     = NULL;
1171   arbDbg     = NULL;
1172   arbFBO     = NULL;
1173   arbFBOBlit = NULL;
1174   extGS      = NULL;
1175   myDefaultVao = 0;
1176
1177 #if defined(GL_ES_VERSION_2_0)
1178
1179   hasTexRGBA8 = IsGlGreaterEqual (3, 0)
1180              || CheckExtension ("GL_OES_rgb8_rgba8");
1181   // NPOT textures has limited support within OpenGL ES 2.0
1182   // which are relaxed by OpenGL ES 3.0 or some extensions
1183   //arbNPTW     = IsGlGreaterEqual (3, 0)
1184   //           || CheckExtension ("GL_OES_texture_npot")
1185   //           || CheckExtension ("GL_NV_texture_npot_2D_mipmap");
1186   arbNPTW     = Standard_True;
1187   arbTexRG    = IsGlGreaterEqual (3, 0)
1188              || CheckExtension ("GL_EXT_texture_rg");
1189   extBgra     = CheckExtension ("GL_EXT_texture_format_BGRA8888");
1190   extAnis = CheckExtension ("GL_EXT_texture_filter_anisotropic");
1191   extPDS  = CheckExtension ("GL_OES_packed_depth_stencil");
1192
1193   core11fwd = (OpenGl_GlCore11Fwd* )(&(*myFuncs));
1194   if (IsGlGreaterEqual (2, 0))
1195   {
1196     // enable compatible functions
1197     core20    = (OpenGl_GlCore20*    )(&(*myFuncs));
1198     core20fwd = (OpenGl_GlCore20Fwd* )(&(*myFuncs));
1199     core15fwd = (OpenGl_GlCore15Fwd* )(&(*myFuncs));
1200     arbFBO    = (OpenGl_ArbFBO*      )(&(*myFuncs));
1201   }
1202   if (IsGlGreaterEqual (3, 0)
1203    && FindProc ("glBlitFramebuffer", myFuncs->glBlitFramebuffer))
1204   {
1205     arbFBOBlit = (OpenGl_ArbFBOBlit* )(&(*myFuncs));
1206   }
1207   extFragDepth = !IsGlGreaterEqual(3, 0)
1208                && CheckExtension ("GL_EXT_frag_depth");
1209   if (IsGlGreaterEqual (3, 1)
1210    && FindProc ("glTexStorage2DMultisample", myFuncs->glTexStorage2DMultisample))
1211   {
1212     // MSAA RenderBuffers have been defined in OpenGL ES 3.0,
1213     // but MSAA Textures - only in OpenGL ES 3.1+
1214     ::glGetIntegerv (GL_MAX_SAMPLES, &myMaxMsaaSamples);
1215   }
1216
1217   hasUintIndex = IsGlGreaterEqual (3, 0)
1218               || CheckExtension ("GL_OES_element_index_uint");
1219   hasHighp     = CheckExtension ("GL_OES_fragment_precision_high");
1220   GLint aRange[2] = {0, 0};
1221   GLint aPrec     = 0;
1222   ::glGetShaderPrecisionFormat (GL_FRAGMENT_SHADER, GL_HIGH_FLOAT, aRange, &aPrec);
1223   if (aPrec != 0)
1224   {
1225     hasHighp = Standard_True;
1226   }
1227
1228   arbTexFloat = IsGlGreaterEqual (3, 0)
1229              && FindProc ("glTexImage3D", myFuncs->glTexImage3D);
1230
1231   const Standard_Boolean hasTexBuffer32  = IsGlGreaterEqual (3, 2) && FindProc ("glTexBuffer", myFuncs->glTexBuffer);
1232   const Standard_Boolean hasExtTexBuffer = CheckExtension ("GL_EXT_texture_buffer") && FindProc ("glTexBufferEXT", myFuncs->glTexBuffer);
1233
1234   if (hasTexBuffer32 || hasExtTexBuffer)
1235   {
1236     arbTBO = reinterpret_cast<OpenGl_ArbTBO*> (myFuncs.get());
1237   }
1238
1239   // initialize debug context extension
1240   if (CheckExtension ("GL_KHR_debug"))
1241   {
1242     // this functionality become a part of OpenGL ES 3.2
1243     arbDbg = NULL;
1244     // According to GL_KHR_debug spec, all functions should have KHR suffix.
1245     // However, some implementations can export these functions without suffix.
1246     if (FindProc ("glDebugMessageControlKHR",  myFuncs->glDebugMessageControl)
1247      && FindProc ("glDebugMessageInsertKHR",   myFuncs->glDebugMessageInsert)
1248      && FindProc ("glDebugMessageCallbackKHR", myFuncs->glDebugMessageCallback)
1249      && FindProc ("glGetDebugMessageLogKHR",   myFuncs->glGetDebugMessageLog))
1250     {
1251       arbDbg = (OpenGl_ArbDbg* )(&(*myFuncs));
1252     }
1253
1254     if (arbDbg != NULL
1255      && caps->contextDebug)
1256     {
1257       // setup default callback
1258       myIsGlDebugCtx = Standard_True;
1259       arbDbg->glDebugMessageCallback (debugCallbackWrap, this);
1260       ::glEnable (GL_DEBUG_OUTPUT);
1261       if (caps->contextSyncDebug)
1262       {
1263         // note that some broken implementations (e.g. simulators) might generate error message on this call
1264         ::glEnable (GL_DEBUG_OUTPUT_SYNCHRONOUS);
1265       }
1266     }
1267   }
1268
1269 #else
1270
1271   myTexClamp = IsGlGreaterEqual (1, 2) ? GL_CLAMP_TO_EDGE : GL_CLAMP;
1272
1273   hasTexRGBA8 = Standard_True;
1274   arbNPTW     = CheckExtension ("GL_ARB_texture_non_power_of_two");
1275   arbTexFloat = IsGlGreaterEqual (3, 0)
1276              || CheckExtension ("GL_ARB_texture_float");
1277   extBgra     = CheckExtension ("GL_EXT_bgra");
1278   extAnis     = CheckExtension ("GL_EXT_texture_filter_anisotropic");
1279   extPDS      = CheckExtension ("GL_EXT_packed_depth_stencil");
1280   atiMem      = CheckExtension ("GL_ATI_meminfo");
1281   nvxMem      = CheckExtension ("GL_NVX_gpu_memory_info");
1282
1283   GLint aStereo = GL_FALSE;
1284   glGetIntegerv (GL_STEREO, &aStereo);
1285   myIsStereoBuffers = aStereo == 1;
1286
1287   // get number of maximum clipping planes
1288   glGetIntegerv (GL_MAX_CLIP_PLANES,  &myMaxClipPlanes);
1289 #endif
1290
1291   glGetIntegerv (GL_MAX_TEXTURE_SIZE, &myMaxTexDim);
1292
1293   if (extAnis)
1294   {
1295     glGetIntegerv (GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &myAnisoMax);
1296   }
1297
1298   myClippingState.Init (myMaxClipPlanes);
1299
1300 #if !defined(GL_ES_VERSION_2_0)
1301
1302   bool has12 = false;
1303   bool has13 = false;
1304   bool has14 = false;
1305   bool has15 = false;
1306   bool has20 = false;
1307   bool has21 = false;
1308   bool has30 = false;
1309   bool has31 = false;
1310   bool has32 = false;
1311   bool has33 = false;
1312   bool has40 = false;
1313   bool has41 = false;
1314   bool has42 = false;
1315   bool has43 = false;
1316   bool has44 = false;
1317
1318   //! Make record shorter to retrieve function pointer using variable with same name
1319   #define FindProcShort(theFunc) FindProc(#theFunc, myFuncs->theFunc)
1320
1321   // retrieve platform-dependent extensions
1322 #if defined(HAVE_EGL)
1323   //
1324 #elif defined(_WIN32)
1325   if (FindProcShort (wglGetExtensionsStringARB))
1326   {
1327     const char* aWglExts = myFuncs->wglGetExtensionsStringARB (wglGetCurrentDC());
1328     if (CheckExtension (aWglExts, "WGL_EXT_swap_control"))
1329     {
1330       FindProcShort (wglSwapIntervalEXT);
1331     }
1332     if (CheckExtension (aWglExts, "WGL_ARB_pixel_format"))
1333     {
1334       FindProcShort (wglChoosePixelFormatARB);
1335     }
1336     if (CheckExtension (aWglExts, "WGL_ARB_create_context_profile"))
1337     {
1338       FindProcShort (wglCreateContextAttribsARB);
1339     }
1340     if (CheckExtension (aWglExts, "WGL_NV_DX_interop"))
1341     {
1342       FindProcShort (wglDXSetResourceShareHandleNV);
1343       FindProcShort (wglDXOpenDeviceNV);
1344       FindProcShort (wglDXCloseDeviceNV);
1345       FindProcShort (wglDXRegisterObjectNV);
1346       FindProcShort (wglDXUnregisterObjectNV);
1347       FindProcShort (wglDXObjectAccessNV);
1348       FindProcShort (wglDXLockObjectsNV);
1349       FindProcShort (wglDXUnlockObjectsNV);
1350     }
1351   }
1352 #elif defined(__APPLE__)
1353     //
1354 #else
1355     const char* aGlxExts = ::glXQueryExtensionsString ((Display* )myDisplay, DefaultScreen ((Display* )myDisplay));
1356     if (CheckExtension (aGlxExts, "GLX_EXT_swap_control"))
1357     {
1358       FindProcShort (glXSwapIntervalEXT);
1359     }
1360     if (CheckExtension (aGlxExts, "GLX_SGI_swap_control"))
1361     {
1362       FindProcShort (glXSwapIntervalSGI);
1363     }
1364     if (CheckExtension (aGlxExts, "GLX_MESA_query_renderer"))
1365     {
1366       FindProcShort (glXQueryRendererIntegerMESA);
1367       FindProcShort (glXQueryCurrentRendererIntegerMESA);
1368       FindProcShort (glXQueryRendererStringMESA);
1369       FindProcShort (glXQueryCurrentRendererStringMESA);
1370     }
1371     //extSwapTear = CheckExtension (aGlxExts, "GLX_EXT_swap_control_tear");
1372 #endif
1373
1374   // load OpenGL 1.2 new functions
1375   has12 = IsGlGreaterEqual (1, 2)
1376        && FindProcShort (glBlendColor)
1377        && FindProcShort (glBlendEquation)
1378        && FindProcShort (glDrawRangeElements)
1379        && FindProcShort (glTexImage3D)
1380        && FindProcShort (glTexSubImage3D)
1381        && FindProcShort (glCopyTexSubImage3D);
1382
1383   // load OpenGL 1.3 new functions
1384   has13 = IsGlGreaterEqual (1, 3)
1385        && FindProcShort (glActiveTexture)
1386        && FindProcShort (glSampleCoverage)
1387        && FindProcShort (glCompressedTexImage3D)
1388        && FindProcShort (glCompressedTexImage2D)
1389        && FindProcShort (glCompressedTexImage1D)
1390        && FindProcShort (glCompressedTexSubImage3D)
1391        && FindProcShort (glCompressedTexSubImage2D)
1392        && FindProcShort (glCompressedTexSubImage1D)
1393        && FindProcShort (glGetCompressedTexImage);
1394
1395   if (!isCoreProfile)
1396   {
1397     has13 = has13
1398        && FindProcShort (glClientActiveTexture)
1399        && FindProcShort (glMultiTexCoord1d)
1400        && FindProcShort (glMultiTexCoord1dv)
1401        && FindProcShort (glMultiTexCoord1f)
1402        && FindProcShort (glMultiTexCoord1fv)
1403        && FindProcShort (glMultiTexCoord1i)
1404        && FindProcShort (glMultiTexCoord1iv)
1405        && FindProcShort (glMultiTexCoord1s)
1406        && FindProcShort (glMultiTexCoord1sv)
1407        && FindProcShort (glMultiTexCoord2d)
1408        && FindProcShort (glMultiTexCoord2dv)
1409        && FindProcShort (glMultiTexCoord2f)
1410        && FindProcShort (glMultiTexCoord2fv)
1411        && FindProcShort (glMultiTexCoord2i)
1412        && FindProcShort (glMultiTexCoord2iv)
1413        && FindProcShort (glMultiTexCoord2s)
1414        && FindProcShort (glMultiTexCoord2sv)
1415        && FindProcShort (glMultiTexCoord3d)
1416        && FindProcShort (glMultiTexCoord3dv)
1417        && FindProcShort (glMultiTexCoord3f)
1418        && FindProcShort (glMultiTexCoord3fv)
1419        && FindProcShort (glMultiTexCoord3i)
1420        && FindProcShort (glMultiTexCoord3iv)
1421        && FindProcShort (glMultiTexCoord3s)
1422        && FindProcShort (glMultiTexCoord3sv)
1423        && FindProcShort (glMultiTexCoord4d)
1424        && FindProcShort (glMultiTexCoord4dv)
1425        && FindProcShort (glMultiTexCoord4f)
1426        && FindProcShort (glMultiTexCoord4fv)
1427        && FindProcShort (glMultiTexCoord4i)
1428        && FindProcShort (glMultiTexCoord4iv)
1429        && FindProcShort (glMultiTexCoord4s)
1430        && FindProcShort (glMultiTexCoord4sv)
1431        && FindProcShort (glLoadTransposeMatrixf)
1432        && FindProcShort (glLoadTransposeMatrixd)
1433        && FindProcShort (glMultTransposeMatrixf)
1434        && FindProcShort (glMultTransposeMatrixd);
1435   }
1436
1437   // load OpenGL 1.4 new functions
1438   has14 = IsGlGreaterEqual (1, 4)
1439        && FindProcShort (glBlendFuncSeparate)
1440        && FindProcShort (glMultiDrawArrays)
1441        && FindProcShort (glMultiDrawElements)
1442        && FindProcShort (glPointParameterf)
1443        && FindProcShort (glPointParameterfv)
1444        && FindProcShort (glPointParameteri)
1445        && FindProcShort (glPointParameteriv);
1446
1447   // load OpenGL 1.5 new functions
1448   has15 = IsGlGreaterEqual (1, 5)
1449        && FindProcShort (glGenQueries)
1450        && FindProcShort (glDeleteQueries)
1451        && FindProcShort (glIsQuery)
1452        && FindProcShort (glBeginQuery)
1453        && FindProcShort (glEndQuery)
1454        && FindProcShort (glGetQueryiv)
1455        && FindProcShort (glGetQueryObjectiv)
1456        && FindProcShort (glGetQueryObjectuiv)
1457        && FindProcShort (glBindBuffer)
1458        && FindProcShort (glDeleteBuffers)
1459        && FindProcShort (glGenBuffers)
1460        && FindProcShort (glIsBuffer)
1461        && FindProcShort (glBufferData)
1462        && FindProcShort (glBufferSubData)
1463        && FindProcShort (glGetBufferSubData)
1464        && FindProcShort (glMapBuffer)
1465        && FindProcShort (glUnmapBuffer)
1466        && FindProcShort (glGetBufferParameteriv)
1467        && FindProcShort (glGetBufferPointerv);
1468
1469   // load OpenGL 2.0 new functions
1470   has20 = IsGlGreaterEqual (2, 0)
1471        && FindProcShort (glBlendEquationSeparate)
1472        && FindProcShort (glDrawBuffers)
1473        && FindProcShort (glStencilOpSeparate)
1474        && FindProcShort (glStencilFuncSeparate)
1475        && FindProcShort (glStencilMaskSeparate)
1476        && FindProcShort (glAttachShader)
1477        && FindProcShort (glBindAttribLocation)
1478        && FindProcShort (glCompileShader)
1479        && FindProcShort (glCreateProgram)
1480        && FindProcShort (glCreateShader)
1481        && FindProcShort (glDeleteProgram)
1482        && FindProcShort (glDeleteShader)
1483        && FindProcShort (glDetachShader)
1484        && FindProcShort (glDisableVertexAttribArray)
1485        && FindProcShort (glEnableVertexAttribArray)
1486        && FindProcShort (glGetActiveAttrib)
1487        && FindProcShort (glGetActiveUniform)
1488        && FindProcShort (glGetAttachedShaders)
1489        && FindProcShort (glGetAttribLocation)
1490        && FindProcShort (glGetProgramiv)
1491        && FindProcShort (glGetProgramInfoLog)
1492        && FindProcShort (glGetShaderiv)
1493        && FindProcShort (glGetShaderInfoLog)
1494        && FindProcShort (glGetShaderSource)
1495        && FindProcShort (glGetUniformLocation)
1496        && FindProcShort (glGetUniformfv)
1497        && FindProcShort (glGetUniformiv)
1498        && FindProcShort (glGetVertexAttribdv)
1499        && FindProcShort (glGetVertexAttribfv)
1500        && FindProcShort (glGetVertexAttribiv)
1501        && FindProcShort (glGetVertexAttribPointerv)
1502        && FindProcShort (glIsProgram)
1503        && FindProcShort (glIsShader)
1504        && FindProcShort (glLinkProgram)
1505        && FindProcShort (glShaderSource)
1506        && FindProcShort (glUseProgram)
1507        && FindProcShort (glUniform1f)
1508        && FindProcShort (glUniform2f)
1509        && FindProcShort (glUniform3f)
1510        && FindProcShort (glUniform4f)
1511        && FindProcShort (glUniform1i)
1512        && FindProcShort (glUniform2i)
1513        && FindProcShort (glUniform3i)
1514        && FindProcShort (glUniform4i)
1515        && FindProcShort (glUniform1fv)
1516        && FindProcShort (glUniform2fv)
1517        && FindProcShort (glUniform3fv)
1518        && FindProcShort (glUniform4fv)
1519        && FindProcShort (glUniform1iv)
1520        && FindProcShort (glUniform2iv)
1521        && FindProcShort (glUniform3iv)
1522        && FindProcShort (glUniform4iv)
1523        && FindProcShort (glUniformMatrix2fv)
1524        && FindProcShort (glUniformMatrix3fv)
1525        && FindProcShort (glUniformMatrix4fv)
1526        && FindProcShort (glValidateProgram)
1527        && FindProcShort (glVertexAttrib1d)
1528        && FindProcShort (glVertexAttrib1dv)
1529        && FindProcShort (glVertexAttrib1f)
1530        && FindProcShort (glVertexAttrib1fv)
1531        && FindProcShort (glVertexAttrib1s)
1532        && FindProcShort (glVertexAttrib1sv)
1533        && FindProcShort (glVertexAttrib2d)
1534        && FindProcShort (glVertexAttrib2dv)
1535        && FindProcShort (glVertexAttrib2f)
1536        && FindProcShort (glVertexAttrib2fv)
1537        && FindProcShort (glVertexAttrib2s)
1538        && FindProcShort (glVertexAttrib2sv)
1539        && FindProcShort (glVertexAttrib3d)
1540        && FindProcShort (glVertexAttrib3dv)
1541        && FindProcShort (glVertexAttrib3f)
1542        && FindProcShort (glVertexAttrib3fv)
1543        && FindProcShort (glVertexAttrib3s)
1544        && FindProcShort (glVertexAttrib3sv)
1545        && FindProcShort (glVertexAttrib4Nbv)
1546        && FindProcShort (glVertexAttrib4Niv)
1547        && FindProcShort (glVertexAttrib4Nsv)
1548        && FindProcShort (glVertexAttrib4Nub)
1549        && FindProcShort (glVertexAttrib4Nubv)
1550        && FindProcShort (glVertexAttrib4Nuiv)
1551        && FindProcShort (glVertexAttrib4Nusv)
1552        && FindProcShort (glVertexAttrib4bv)
1553        && FindProcShort (glVertexAttrib4d)
1554        && FindProcShort (glVertexAttrib4dv)
1555        && FindProcShort (glVertexAttrib4f)
1556        && FindProcShort (glVertexAttrib4fv)
1557        && FindProcShort (glVertexAttrib4iv)
1558        && FindProcShort (glVertexAttrib4s)
1559        && FindProcShort (glVertexAttrib4sv)
1560        && FindProcShort (glVertexAttrib4ubv)
1561        && FindProcShort (glVertexAttrib4uiv)
1562        && FindProcShort (glVertexAttrib4usv)
1563        && FindProcShort (glVertexAttribPointer);
1564
1565   // load OpenGL 2.1 new functions
1566   has21 = IsGlGreaterEqual (2, 1)
1567        && FindProcShort (glUniformMatrix2x3fv)
1568        && FindProcShort (glUniformMatrix3x2fv)
1569        && FindProcShort (glUniformMatrix2x4fv)
1570        && FindProcShort (glUniformMatrix4x2fv)
1571        && FindProcShort (glUniformMatrix3x4fv)
1572        && FindProcShort (glUniformMatrix4x3fv);
1573
1574   // load GL_ARB_framebuffer_object (added to OpenGL 3.0 core)
1575   const bool hasFBO = (IsGlGreaterEqual (3, 0) || CheckExtension ("GL_ARB_framebuffer_object"))
1576        && FindProcShort (glIsRenderbuffer)
1577        && FindProcShort (glBindRenderbuffer)
1578        && FindProcShort (glDeleteRenderbuffers)
1579        && FindProcShort (glGenRenderbuffers)
1580        && FindProcShort (glRenderbufferStorage)
1581        && FindProcShort (glGetRenderbufferParameteriv)
1582        && FindProcShort (glIsFramebuffer)
1583        && FindProcShort (glBindFramebuffer)
1584        && FindProcShort (glDeleteFramebuffers)
1585        && FindProcShort (glGenFramebuffers)
1586        && FindProcShort (glCheckFramebufferStatus)
1587        && FindProcShort (glFramebufferTexture1D)
1588        && FindProcShort (glFramebufferTexture2D)
1589        && FindProcShort (glFramebufferTexture3D)
1590        && FindProcShort (glFramebufferRenderbuffer)
1591        && FindProcShort (glGetFramebufferAttachmentParameteriv)
1592        && FindProcShort (glGenerateMipmap)
1593        && FindProcShort (glBlitFramebuffer)
1594        && FindProcShort (glRenderbufferStorageMultisample)
1595        && FindProcShort (glFramebufferTextureLayer);
1596
1597   // load GL_ARB_vertex_array_object (added to OpenGL 3.0 core)
1598   const bool hasVAO = (IsGlGreaterEqual (3, 0) || CheckExtension ("GL_ARB_vertex_array_object"))
1599        && FindProcShort (glBindVertexArray)
1600        && FindProcShort (glDeleteVertexArrays)
1601        && FindProcShort (glGenVertexArrays)
1602        && FindProcShort (glIsVertexArray);
1603
1604   // load GL_ARB_map_buffer_range (added to OpenGL 3.0 core)
1605   const bool hasMapBufferRange = (IsGlGreaterEqual (3, 0) || CheckExtension ("GL_ARB_map_buffer_range"))
1606        && FindProcShort (glMapBufferRange)
1607        && FindProcShort (glFlushMappedBufferRange);
1608
1609   // load OpenGL 3.0 new functions
1610   has30 = IsGlGreaterEqual (3, 0)
1611        && hasFBO
1612        && hasVAO
1613        && hasMapBufferRange
1614        && FindProcShort (glColorMaski)
1615        && FindProcShort (glGetBooleani_v)
1616        && FindProcShort (glGetIntegeri_v)
1617        && FindProcShort (glEnablei)
1618        && FindProcShort (glDisablei)
1619        && FindProcShort (glIsEnabledi)
1620        && FindProcShort (glBeginTransformFeedback)
1621        && FindProcShort (glEndTransformFeedback)
1622        && FindProcShort (glBindBufferRange)
1623        && FindProcShort (glBindBufferBase)
1624        && FindProcShort (glTransformFeedbackVaryings)
1625        && FindProcShort (glGetTransformFeedbackVarying)
1626        && FindProcShort (glClampColor)
1627        && FindProcShort (glBeginConditionalRender)
1628        && FindProcShort (glEndConditionalRender)
1629        && FindProcShort (glVertexAttribIPointer)
1630        && FindProcShort (glGetVertexAttribIiv)
1631        && FindProcShort (glGetVertexAttribIuiv)
1632        && FindProcShort (glVertexAttribI1i)
1633        && FindProcShort (glVertexAttribI2i)
1634        && FindProcShort (glVertexAttribI3i)
1635        && FindProcShort (glVertexAttribI4i)
1636        && FindProcShort (glVertexAttribI1ui)
1637        && FindProcShort (glVertexAttribI2ui)
1638        && FindProcShort (glVertexAttribI3ui)
1639        && FindProcShort (glVertexAttribI4ui)
1640        && FindProcShort (glVertexAttribI1iv)
1641        && FindProcShort (glVertexAttribI2iv)
1642        && FindProcShort (glVertexAttribI3iv)
1643        && FindProcShort (glVertexAttribI4iv)
1644        && FindProcShort (glVertexAttribI1uiv)
1645        && FindProcShort (glVertexAttribI2uiv)
1646        && FindProcShort (glVertexAttribI3uiv)
1647        && FindProcShort (glVertexAttribI4uiv)
1648        && FindProcShort (glVertexAttribI4bv)
1649        && FindProcShort (glVertexAttribI4sv)
1650        && FindProcShort (glVertexAttribI4ubv)
1651        && FindProcShort (glVertexAttribI4usv)
1652        && FindProcShort (glGetUniformuiv)
1653        && FindProcShort (glBindFragDataLocation)
1654        && FindProcShort (glGetFragDataLocation)
1655        && FindProcShort (glUniform1ui)
1656        && FindProcShort (glUniform2ui)
1657        && FindProcShort (glUniform3ui)
1658        && FindProcShort (glUniform4ui)
1659        && FindProcShort (glUniform1uiv)
1660        && FindProcShort (glUniform2uiv)
1661        && FindProcShort (glUniform3uiv)
1662        && FindProcShort (glUniform4uiv)
1663        && FindProcShort (glTexParameterIiv)
1664        && FindProcShort (glTexParameterIuiv)
1665        && FindProcShort (glGetTexParameterIiv)
1666        && FindProcShort (glGetTexParameterIuiv)
1667        && FindProcShort (glClearBufferiv)
1668        && FindProcShort (glClearBufferuiv)
1669        && FindProcShort (glClearBufferfv)
1670        && FindProcShort (glClearBufferfi)
1671        && FindProcShort (glGetStringi);
1672
1673   // load GL_ARB_uniform_buffer_object (added to OpenGL 3.1 core)
1674   const bool hasUBO = (IsGlGreaterEqual (3, 1) || CheckExtension ("GL_ARB_uniform_buffer_object"))
1675        && FindProcShort (glGetUniformIndices)
1676        && FindProcShort (glGetActiveUniformsiv)
1677        && FindProcShort (glGetActiveUniformName)
1678        && FindProcShort (glGetUniformBlockIndex)
1679        && FindProcShort (glGetActiveUniformBlockiv)
1680        && FindProcShort (glGetActiveUniformBlockName)
1681        && FindProcShort (glUniformBlockBinding);
1682
1683   // load GL_ARB_copy_buffer (added to OpenGL 3.1 core)
1684   const bool hasCopyBufSubData = (IsGlGreaterEqual (3, 1) || CheckExtension ("GL_ARB_copy_buffer"))
1685        && FindProcShort (glCopyBufferSubData);
1686
1687   if (has30)
1688   {
1689     // NPOT textures are required by OpenGL 2.0 specifications
1690     // but doesn't hardware accelerated by some ancient OpenGL 2.1 hardware (GeForce FX, RadeOn 9700 etc.)
1691     arbNPTW  = Standard_True;
1692     arbTexRG = Standard_True;
1693   }
1694
1695   // load OpenGL 3.1 new functions
1696   has31 = IsGlGreaterEqual (3, 1)
1697        && hasUBO
1698        && hasCopyBufSubData
1699        && FindProcShort (glDrawArraysInstanced)
1700        && FindProcShort (glDrawElementsInstanced)
1701        && FindProcShort (glTexBuffer)
1702        && FindProcShort (glPrimitiveRestartIndex);
1703
1704   // load GL_ARB_draw_elements_base_vertex (added to OpenGL 3.2 core)
1705   const bool hasDrawElemsBaseVert = (IsGlGreaterEqual (3, 2) || CheckExtension ("GL_ARB_draw_elements_base_vertex"))
1706        && FindProcShort (glDrawElementsBaseVertex)
1707        && FindProcShort (glDrawRangeElementsBaseVertex)
1708        && FindProcShort (glDrawElementsInstancedBaseVertex)
1709        && FindProcShort (glMultiDrawElementsBaseVertex);
1710
1711   // load GL_ARB_provoking_vertex (added to OpenGL 3.2 core)
1712   const bool hasProvokingVert = (IsGlGreaterEqual (3, 2) || CheckExtension ("GL_ARB_provoking_vertex"))
1713        && FindProcShort (glProvokingVertex);
1714
1715   // load GL_ARB_sync (added to OpenGL 3.2 core)
1716   const bool hasSync = (IsGlGreaterEqual (3, 2) || CheckExtension ("GL_ARB_sync"))
1717        && FindProcShort (glFenceSync)
1718        && FindProcShort (glIsSync)
1719        && FindProcShort (glDeleteSync)
1720        && FindProcShort (glClientWaitSync)
1721        && FindProcShort (glWaitSync)
1722        && FindProcShort (glGetInteger64v)
1723        && FindProcShort (glGetSynciv);
1724
1725   // load GL_ARB_texture_multisample (added to OpenGL 3.2 core)
1726   const bool hasTextureMultisample = (IsGlGreaterEqual (3, 2) || CheckExtension ("GL_ARB_texture_multisample"))
1727        && FindProcShort (glTexImage2DMultisample)
1728        && FindProcShort (glTexImage3DMultisample)
1729        && FindProcShort (glGetMultisamplefv)
1730        && FindProcShort (glSampleMaski);
1731
1732   // load OpenGL 3.2 new functions
1733   has32 = IsGlGreaterEqual (3, 2)
1734        && hasDrawElemsBaseVert
1735        && hasProvokingVert
1736        && hasSync
1737        && hasTextureMultisample
1738        && FindProcShort (glGetInteger64i_v)
1739        && FindProcShort (glGetBufferParameteri64v)
1740        && FindProcShort (glFramebufferTexture);
1741
1742   // load GL_ARB_blend_func_extended (added to OpenGL 3.3 core)
1743   const bool hasBlendFuncExtended = (IsGlGreaterEqual (3, 3) || CheckExtension ("GL_ARB_blend_func_extended"))
1744        && FindProcShort (glBindFragDataLocationIndexed)
1745        && FindProcShort (glGetFragDataIndex);
1746
1747   // load GL_ARB_sampler_objects (added to OpenGL 3.3 core)
1748   const bool hasSamplerObjects = (IsGlGreaterEqual (3, 3) || CheckExtension ("GL_ARB_sampler_objects"))
1749        && FindProcShort (glGenSamplers)
1750        && FindProcShort (glDeleteSamplers)
1751        && FindProcShort (glIsSampler)
1752        && FindProcShort (glBindSampler)
1753        && FindProcShort (glSamplerParameteri)
1754        && FindProcShort (glSamplerParameteriv)
1755        && FindProcShort (glSamplerParameterf)
1756        && FindProcShort (glSamplerParameterfv)
1757        && FindProcShort (glSamplerParameterIiv)
1758        && FindProcShort (glSamplerParameterIuiv)
1759        && FindProcShort (glGetSamplerParameteriv)
1760        && FindProcShort (glGetSamplerParameterIiv)
1761        && FindProcShort (glGetSamplerParameterfv)
1762        && FindProcShort (glGetSamplerParameterIuiv);
1763
1764   // load GL_ARB_timer_query (added to OpenGL 3.3 core)
1765   const bool hasTimerQuery = (IsGlGreaterEqual (3, 3) || CheckExtension ("GL_ARB_timer_query"))
1766        && FindProcShort (glQueryCounter)
1767        && FindProcShort (glGetQueryObjecti64v)
1768        && FindProcShort (glGetQueryObjectui64v);
1769
1770   // load GL_ARB_vertex_type_2_10_10_10_rev (added to OpenGL 3.3 core)
1771   const bool hasVertType21010101rev = (IsGlGreaterEqual (3, 3) || CheckExtension ("GL_ARB_vertex_type_2_10_10_10_rev"))
1772        && FindProcShort (glVertexAttribP1ui)
1773        && FindProcShort (glVertexAttribP1uiv)
1774        && FindProcShort (glVertexAttribP2ui)
1775        && FindProcShort (glVertexAttribP2uiv)
1776        && FindProcShort (glVertexAttribP3ui)
1777        && FindProcShort (glVertexAttribP3uiv)
1778        && FindProcShort (glVertexAttribP4ui)
1779        && FindProcShort (glVertexAttribP4uiv);
1780
1781   if ( hasVertType21010101rev
1782    && !isCoreProfile)
1783   {
1784     // load deprecated functions
1785     const bool hasVertType21010101revExt =
1786           FindProcShort (glVertexP2ui)
1787        && FindProcShort (glVertexP2uiv)
1788        && FindProcShort (glVertexP3ui)
1789        && FindProcShort (glVertexP3uiv)
1790        && FindProcShort (glVertexP4ui)
1791        && FindProcShort (glVertexP4uiv)
1792        && FindProcShort (glTexCoordP1ui)
1793        && FindProcShort (glTexCoordP1uiv)
1794        && FindProcShort (glTexCoordP2ui)
1795        && FindProcShort (glTexCoordP2uiv)
1796        && FindProcShort (glTexCoordP3ui)
1797        && FindProcShort (glTexCoordP3uiv)
1798        && FindProcShort (glTexCoordP4ui)
1799        && FindProcShort (glTexCoordP4uiv)
1800        && FindProcShort (glMultiTexCoordP1ui)
1801        && FindProcShort (glMultiTexCoordP1uiv)
1802        && FindProcShort (glMultiTexCoordP2ui)
1803        && FindProcShort (glMultiTexCoordP2uiv)
1804        && FindProcShort (glMultiTexCoordP3ui)
1805        && FindProcShort (glMultiTexCoordP3uiv)
1806        && FindProcShort (glMultiTexCoordP4ui)
1807        && FindProcShort (glMultiTexCoordP4uiv)
1808        && FindProcShort (glNormalP3ui)
1809        && FindProcShort (glNormalP3uiv)
1810        && FindProcShort (glColorP3ui)
1811        && FindProcShort (glColorP3uiv)
1812        && FindProcShort (glColorP4ui)
1813        && FindProcShort (glColorP4uiv)
1814        && FindProcShort (glSecondaryColorP3ui)
1815        && FindProcShort (glSecondaryColorP3uiv);
1816     (void )hasVertType21010101revExt;
1817   }
1818
1819   // load OpenGL 3.3 extra functions
1820   has33 = IsGlGreaterEqual (3, 3)
1821        && hasBlendFuncExtended
1822        && hasSamplerObjects
1823        && hasTimerQuery
1824        && hasVertType21010101rev
1825        && FindProcShort (glVertexAttribDivisor);
1826
1827   // load GL_ARB_draw_indirect (added to OpenGL 4.0 core)
1828   const bool hasDrawIndirect = (IsGlGreaterEqual (4, 0) || CheckExtension ("GL_ARB_draw_indirect"))
1829        && FindProcShort (glDrawArraysIndirect)
1830        && FindProcShort (glDrawElementsIndirect);
1831
1832   // load GL_ARB_gpu_shader_fp64 (added to OpenGL 4.0 core)
1833   const bool hasShaderFP64 = (IsGlGreaterEqual (4, 0) || CheckExtension ("GL_ARB_gpu_shader_fp64"))
1834        && FindProcShort (glUniform1d)
1835        && FindProcShort (glUniform2d)
1836        && FindProcShort (glUniform3d)
1837        && FindProcShort (glUniform4d)
1838        && FindProcShort (glUniform1dv)
1839        && FindProcShort (glUniform2dv)
1840        && FindProcShort (glUniform3dv)
1841        && FindProcShort (glUniform4dv)
1842        && FindProcShort (glUniformMatrix2dv)
1843        && FindProcShort (glUniformMatrix3dv)
1844        && FindProcShort (glUniformMatrix4dv)
1845        && FindProcShort (glUniformMatrix2x3dv)
1846        && FindProcShort (glUniformMatrix2x4dv)
1847        && FindProcShort (glUniformMatrix3x2dv)
1848        && FindProcShort (glUniformMatrix3x4dv)
1849        && FindProcShort (glUniformMatrix4x2dv)
1850        && FindProcShort (glUniformMatrix4x3dv)
1851        && FindProcShort (glGetUniformdv);
1852
1853   // load GL_ARB_shader_subroutine (added to OpenGL 4.0 core)
1854   const bool hasShaderSubroutine = (IsGlGreaterEqual (4, 0) || CheckExtension ("GL_ARB_shader_subroutine"))
1855        && FindProcShort (glGetSubroutineUniformLocation)
1856        && FindProcShort (glGetSubroutineIndex)
1857        && FindProcShort (glGetActiveSubroutineUniformiv)
1858        && FindProcShort (glGetActiveSubroutineUniformName)
1859        && FindProcShort (glGetActiveSubroutineName)
1860        && FindProcShort (glUniformSubroutinesuiv)
1861        && FindProcShort (glGetUniformSubroutineuiv)
1862        && FindProcShort (glGetProgramStageiv);
1863
1864   // load GL_ARB_tessellation_shader (added to OpenGL 4.0 core)
1865   const bool hasTessellationShader = (IsGlGreaterEqual (4, 0) || CheckExtension ("GL_ARB_tessellation_shader"))
1866        && FindProcShort (glPatchParameteri)
1867        && FindProcShort (glPatchParameterfv);
1868
1869   // load GL_ARB_transform_feedback2 (added to OpenGL 4.0 core)
1870   const bool hasTrsfFeedback2 = (IsGlGreaterEqual (4, 0) || CheckExtension ("GL_ARB_transform_feedback2"))
1871        && FindProcShort (glBindTransformFeedback)
1872        && FindProcShort (glDeleteTransformFeedbacks)
1873        && FindProcShort (glGenTransformFeedbacks)
1874        && FindProcShort (glIsTransformFeedback)
1875        && FindProcShort (glPauseTransformFeedback)
1876        && FindProcShort (glResumeTransformFeedback)
1877        && FindProcShort (glDrawTransformFeedback);
1878
1879   // load GL_ARB_transform_feedback3 (added to OpenGL 4.0 core)
1880   const bool hasTrsfFeedback3 = (IsGlGreaterEqual (4, 0) || CheckExtension ("GL_ARB_transform_feedback3"))
1881        && FindProcShort (glDrawTransformFeedbackStream)
1882        && FindProcShort (glBeginQueryIndexed)
1883        && FindProcShort (glEndQueryIndexed)
1884        && FindProcShort (glGetQueryIndexediv);
1885
1886   // load OpenGL 4.0 new functions
1887   has40 = IsGlGreaterEqual (4, 0)
1888       && hasDrawIndirect
1889       && hasShaderFP64
1890       && hasShaderSubroutine
1891       && hasTessellationShader
1892       && hasTrsfFeedback2
1893       && hasTrsfFeedback3
1894       && FindProcShort (glMinSampleShading)
1895       && FindProcShort (glBlendEquationi)
1896       && FindProcShort (glBlendEquationSeparatei)
1897       && FindProcShort (glBlendFunci)
1898       && FindProcShort (glBlendFuncSeparatei);
1899
1900   // load GL_ARB_ES2_compatibility (added to OpenGL 4.1 core)
1901   const bool hasES2Compatibility = (IsGlGreaterEqual (4, 1) || CheckExtension ("GL_ARB_ES2_compatibility"))
1902        && FindProcShort (glReleaseShaderCompiler)
1903        && FindProcShort (glShaderBinary)
1904        && FindProcShort (glGetShaderPrecisionFormat)
1905        && FindProcShort (glDepthRangef)
1906        && FindProcShort (glClearDepthf);
1907
1908   // load GL_ARB_get_program_binary (added to OpenGL 4.1 core)
1909   const bool hasGetProgramBinary = (IsGlGreaterEqual (4, 1) || CheckExtension ("GL_ARB_get_program_binary"))
1910        && FindProcShort (glGetProgramBinary)
1911        && FindProcShort (glProgramBinary)
1912        && FindProcShort (glProgramParameteri);
1913
1914
1915   // load GL_ARB_separate_shader_objects (added to OpenGL 4.1 core)
1916   const bool hasSeparateShaderObjects = (IsGlGreaterEqual (4, 1) || CheckExtension ("GL_ARB_separate_shader_objects"))
1917        && FindProcShort (glUseProgramStages)
1918        && FindProcShort (glActiveShaderProgram)
1919        && FindProcShort (glCreateShaderProgramv)
1920        && FindProcShort (glBindProgramPipeline)
1921        && FindProcShort (glDeleteProgramPipelines)
1922        && FindProcShort (glGenProgramPipelines)
1923        && FindProcShort (glIsProgramPipeline)
1924        && FindProcShort (glGetProgramPipelineiv)
1925        && FindProcShort (glProgramUniform1i)
1926        && FindProcShort (glProgramUniform1iv)
1927        && FindProcShort (glProgramUniform1f)
1928        && FindProcShort (glProgramUniform1fv)
1929        && FindProcShort (glProgramUniform1d)
1930        && FindProcShort (glProgramUniform1dv)
1931        && FindProcShort (glProgramUniform1ui)
1932        && FindProcShort (glProgramUniform1uiv)
1933        && FindProcShort (glProgramUniform2i)
1934        && FindProcShort (glProgramUniform2iv)
1935        && FindProcShort (glProgramUniform2f)
1936        && FindProcShort (glProgramUniform2fv)
1937        && FindProcShort (glProgramUniform2d)
1938        && FindProcShort (glProgramUniform2dv)
1939        && FindProcShort (glProgramUniform2ui)
1940        && FindProcShort (glProgramUniform2uiv)
1941        && FindProcShort (glProgramUniform3i)
1942        && FindProcShort (glProgramUniform3iv)
1943        && FindProcShort (glProgramUniform3f)
1944        && FindProcShort (glProgramUniform3fv)
1945        && FindProcShort (glProgramUniform3d)
1946        && FindProcShort (glProgramUniform3dv)
1947        && FindProcShort (glProgramUniform3ui)
1948        && FindProcShort (glProgramUniform3uiv)
1949        && FindProcShort (glProgramUniform4i)
1950        && FindProcShort (glProgramUniform4iv)
1951        && FindProcShort (glProgramUniform4f)
1952        && FindProcShort (glProgramUniform4fv)
1953        && FindProcShort (glProgramUniform4d)
1954        && FindProcShort (glProgramUniform4dv)
1955        && FindProcShort (glProgramUniform4ui)
1956        && FindProcShort (glProgramUniform4uiv)
1957        && FindProcShort (glProgramUniformMatrix2fv)
1958        && FindProcShort (glProgramUniformMatrix3fv)
1959        && FindProcShort (glProgramUniformMatrix4fv)
1960        && FindProcShort (glProgramUniformMatrix2dv)
1961        && FindProcShort (glProgramUniformMatrix3dv)
1962        && FindProcShort (glProgramUniformMatrix4dv)
1963        && FindProcShort (glProgramUniformMatrix2x3fv)
1964        && FindProcShort (glProgramUniformMatrix3x2fv)
1965        && FindProcShort (glProgramUniformMatrix2x4fv)
1966        && FindProcShort (glProgramUniformMatrix4x2fv)
1967        && FindProcShort (glProgramUniformMatrix3x4fv)
1968        && FindProcShort (glProgramUniformMatrix4x3fv)
1969        && FindProcShort (glProgramUniformMatrix2x3dv)
1970        && FindProcShort (glProgramUniformMatrix3x2dv)
1971        && FindProcShort (glProgramUniformMatrix2x4dv)
1972        && FindProcShort (glProgramUniformMatrix4x2dv)
1973        && FindProcShort (glProgramUniformMatrix3x4dv)
1974        && FindProcShort (glProgramUniformMatrix4x3dv)
1975        && FindProcShort (glValidateProgramPipeline)
1976        && FindProcShort (glGetProgramPipelineInfoLog);
1977
1978   // load GL_ARB_vertex_attrib_64bit (added to OpenGL 4.1 core)
1979   const bool hasVertAttrib64bit = (IsGlGreaterEqual (4, 1) || CheckExtension ("GL_ARB_vertex_attrib_64bit"))
1980        && FindProcShort (glVertexAttribL1d)
1981        && FindProcShort (glVertexAttribL2d)
1982        && FindProcShort (glVertexAttribL3d)
1983        && FindProcShort (glVertexAttribL4d)
1984        && FindProcShort (glVertexAttribL1dv)
1985        && FindProcShort (glVertexAttribL2dv)
1986        && FindProcShort (glVertexAttribL3dv)
1987        && FindProcShort (glVertexAttribL4dv)
1988        && FindProcShort (glVertexAttribLPointer)
1989        && FindProcShort (glGetVertexAttribLdv);
1990
1991   // load GL_ARB_viewport_array (added to OpenGL 4.1 core)
1992   const bool hasViewportArray = (IsGlGreaterEqual (4, 1) || CheckExtension ("GL_ARB_viewport_array"))
1993        && FindProcShort (glViewportArrayv)
1994        && FindProcShort (glViewportIndexedf)
1995        && FindProcShort (glViewportIndexedfv)
1996        && FindProcShort (glScissorArrayv)
1997        && FindProcShort (glScissorIndexed)
1998        && FindProcShort (glScissorIndexedv)
1999        && FindProcShort (glDepthRangeArrayv)
2000        && FindProcShort (glDepthRangeIndexed)
2001        && FindProcShort (glGetFloati_v)
2002        && FindProcShort (glGetDoublei_v);
2003
2004   has41 = IsGlGreaterEqual (4, 1)
2005        && hasES2Compatibility
2006        && hasGetProgramBinary
2007        && hasSeparateShaderObjects
2008        && hasVertAttrib64bit
2009        && hasViewportArray;
2010
2011   // load GL_ARB_base_instance (added to OpenGL 4.2 core)
2012   const bool hasBaseInstance = (IsGlGreaterEqual (4, 2) || CheckExtension ("GL_ARB_base_instance"))
2013        && FindProcShort (glDrawArraysInstancedBaseInstance)
2014        && FindProcShort (glDrawElementsInstancedBaseInstance)
2015        && FindProcShort (glDrawElementsInstancedBaseVertexBaseInstance);
2016
2017   // load GL_ARB_transform_feedback_instanced (added to OpenGL 4.2 core)
2018   const bool hasTrsfFeedbackInstanced = (IsGlGreaterEqual (4, 2) || CheckExtension ("GL_ARB_transform_feedback_instanced"))
2019        && FindProcShort (glDrawTransformFeedbackInstanced)
2020        && FindProcShort (glDrawTransformFeedbackStreamInstanced);
2021
2022   // load GL_ARB_internalformat_query (added to OpenGL 4.2 core)
2023   const bool hasInternalFormatQuery = (IsGlGreaterEqual (4, 2) || CheckExtension ("GL_ARB_internalformat_query"))
2024        && FindProcShort (glGetInternalformativ);
2025
2026   // load GL_ARB_shader_atomic_counters (added to OpenGL 4.2 core)
2027   const bool hasShaderAtomicCounters = (IsGlGreaterEqual (4, 2) || CheckExtension ("GL_ARB_shader_atomic_counters"))
2028        && FindProcShort (glGetActiveAtomicCounterBufferiv);
2029
2030   // load GL_ARB_shader_image_load_store (added to OpenGL 4.2 core)
2031   const bool hasShaderImgLoadStore = (IsGlGreaterEqual (4, 2) || CheckExtension ("GL_ARB_shader_image_load_store"))
2032        && FindProcShort (glBindImageTexture)
2033        && FindProcShort (glMemoryBarrier);
2034
2035   // load GL_ARB_texture_storage (added to OpenGL 4.2 core)
2036   const bool hasTextureStorage = (IsGlGreaterEqual (4, 2) || CheckExtension ("GL_ARB_texture_storage"))
2037        && FindProcShort (glTexStorage1D)
2038        && FindProcShort (glTexStorage2D)
2039        && FindProcShort (glTexStorage3D);
2040
2041   has42 = IsGlGreaterEqual (4, 2)
2042        && hasBaseInstance
2043        && hasTrsfFeedbackInstanced
2044        && hasInternalFormatQuery
2045        && hasShaderAtomicCounters
2046        && hasShaderImgLoadStore
2047        && hasTextureStorage;
2048
2049   has43 = IsGlGreaterEqual (4, 3)
2050        && FindProcShort (glClearBufferData)
2051        && FindProcShort (glClearBufferSubData)
2052        && FindProcShort (glDispatchCompute)
2053        && FindProcShort (glDispatchComputeIndirect)
2054        && FindProcShort (glCopyImageSubData)
2055        && FindProcShort (glFramebufferParameteri)
2056        && FindProcShort (glGetFramebufferParameteriv)
2057        && FindProcShort (glGetInternalformati64v)
2058        && FindProcShort (glInvalidateTexSubImage)
2059        && FindProcShort (glInvalidateTexImage)
2060        && FindProcShort (glInvalidateBufferSubData)
2061        && FindProcShort (glInvalidateBufferData)
2062        && FindProcShort (glInvalidateFramebuffer)
2063        && FindProcShort (glInvalidateSubFramebuffer)
2064        && FindProcShort (glMultiDrawArraysIndirect)
2065        && FindProcShort (glMultiDrawElementsIndirect)
2066        && FindProcShort (glGetProgramInterfaceiv)
2067        && FindProcShort (glGetProgramResourceIndex)
2068        && FindProcShort (glGetProgramResourceName)
2069        && FindProcShort (glGetProgramResourceiv)
2070        && FindProcShort (glGetProgramResourceLocation)
2071        && FindProcShort (glGetProgramResourceLocationIndex)
2072        && FindProcShort (glShaderStorageBlockBinding)
2073        && FindProcShort (glTexBufferRange)
2074        && FindProcShort (glTexStorage2DMultisample)
2075        && FindProcShort (glTexStorage3DMultisample)
2076        && FindProcShort (glTextureView)
2077        && FindProcShort (glBindVertexBuffer)
2078        && FindProcShort (glVertexAttribFormat)
2079        && FindProcShort (glVertexAttribIFormat)
2080        && FindProcShort (glVertexAttribLFormat)
2081        && FindProcShort (glVertexAttribBinding)
2082        && FindProcShort (glVertexBindingDivisor)
2083        && FindProcShort (glDebugMessageControl)
2084        && FindProcShort (glDebugMessageInsert)
2085        && FindProcShort (glDebugMessageCallback)
2086        && FindProcShort (glGetDebugMessageLog)
2087        && FindProcShort (glPushDebugGroup)
2088        && FindProcShort (glPopDebugGroup)
2089        && FindProcShort (glObjectLabel)
2090        && FindProcShort (glGetObjectLabel)
2091        && FindProcShort (glObjectPtrLabel)
2092        && FindProcShort (glGetObjectPtrLabel);
2093
2094   // load GL_ARB_clear_texture (added to OpenGL 4.4 core)
2095   bool arbTexClear = (IsGlGreaterEqual (4, 4) || CheckExtension ("GL_ARB_clear_texture"))
2096        && FindProcShort (glClearTexImage)
2097        && FindProcShort (glClearTexSubImage);
2098
2099   has44 = IsGlGreaterEqual (4, 4)
2100        && arbTexClear
2101        && FindProcShort (glBufferStorage)
2102        && FindProcShort (glBindBuffersBase)
2103        && FindProcShort (glBindBuffersRange)
2104        && FindProcShort (glBindTextures)
2105        && FindProcShort (glBindSamplers)
2106        && FindProcShort (glBindImageTextures)
2107        && FindProcShort (glBindVertexBuffers);
2108
2109   // initialize debug context extension
2110   if (CheckExtension ("GL_ARB_debug_output"))
2111   {
2112     arbDbg = NULL;
2113     if (has43)
2114     {
2115       arbDbg = (OpenGl_ArbDbg* )(&(*myFuncs));
2116     }
2117     else if (FindProc ("glDebugMessageControlARB",  myFuncs->glDebugMessageControl)
2118           && FindProc ("glDebugMessageInsertARB",   myFuncs->glDebugMessageInsert)
2119           && FindProc ("glDebugMessageCallbackARB", myFuncs->glDebugMessageCallback)
2120           && FindProc ("glGetDebugMessageLogARB",   myFuncs->glGetDebugMessageLog))
2121     {
2122       arbDbg = (OpenGl_ArbDbg* )(&(*myFuncs));
2123     }
2124
2125     if (arbDbg != NULL
2126      && caps->contextDebug)
2127     {
2128       // setup default callback
2129       myIsGlDebugCtx = Standard_True;
2130       arbDbg->glDebugMessageCallback (debugCallbackWrap, this);
2131       if (has43)
2132       {
2133         ::glEnable (GL_DEBUG_OUTPUT);
2134       }
2135       if (caps->contextSyncDebug)
2136       {
2137         ::glEnable (GL_DEBUG_OUTPUT_SYNCHRONOUS);
2138       }
2139     }
2140   }
2141
2142   // initialize TBO extension (ARB)
2143   if (!has31
2144    && CheckExtension ("GL_ARB_texture_buffer_object")
2145    && FindProc ("glTexBufferARB", myFuncs->glTexBuffer))
2146   {
2147     arbTBO = (OpenGl_ArbTBO* )(&(*myFuncs));
2148   }
2149   arbTboRGB32 = CheckExtension ("GL_ARB_texture_buffer_object_rgb32");
2150
2151   // initialize hardware instancing extension (ARB)
2152   if (!has31
2153    && CheckExtension ("GL_ARB_draw_instanced")
2154    && FindProc ("glDrawArraysInstancedARB",   myFuncs->glDrawArraysInstanced)
2155    && FindProc ("glDrawElementsInstancedARB", myFuncs->glDrawElementsInstanced))
2156   {
2157     arbIns = (OpenGl_ArbIns* )(&(*myFuncs));
2158   }
2159
2160   // initialize FBO extension (ARB)
2161   if (hasFBO)
2162   {
2163     arbFBO     = (OpenGl_ArbFBO*     )(&(*myFuncs));
2164     arbFBOBlit = (OpenGl_ArbFBOBlit* )(&(*myFuncs));
2165     extPDS = Standard_True; // extension for EXT, but part of ARB
2166   }
2167
2168   // initialize GS extension (EXT)
2169   if (CheckExtension ("GL_EXT_geometry_shader4")
2170    && FindProcShort (glProgramParameteriEXT))
2171   {
2172     extGS = (OpenGl_ExtGS* )(&(*myFuncs));
2173   }
2174
2175   // initialize bindless texture extension (ARB)
2176   if (CheckExtension ("GL_ARB_bindless_texture")
2177    && FindProcShort (glGetTextureHandleARB)
2178    && FindProcShort (glGetTextureSamplerHandleARB)
2179    && FindProcShort (glMakeTextureHandleResidentARB)
2180    && FindProcShort (glMakeTextureHandleNonResidentARB)
2181    && FindProcShort (glGetImageHandleARB)
2182    && FindProcShort (glMakeImageHandleResidentARB)
2183    && FindProcShort (glMakeImageHandleNonResidentARB)
2184    && FindProcShort (glUniformHandleui64ARB)
2185    && FindProcShort (glUniformHandleui64vARB)
2186    && FindProcShort (glProgramUniformHandleui64ARB)
2187    && FindProcShort (glProgramUniformHandleui64vARB)
2188    && FindProcShort (glIsTextureHandleResidentARB)
2189    && FindProcShort (glIsImageHandleResidentARB)
2190    && FindProcShort (glVertexAttribL1ui64ARB)
2191    && FindProcShort (glVertexAttribL1ui64vARB)
2192    && FindProcShort (glGetVertexAttribLui64vARB))
2193   {
2194     arbTexBindless = (OpenGl_ArbTexBindless* )(&(*myFuncs));
2195   }
2196
2197   if (!has12)
2198   {
2199     checkWrongVersion (1, 2);
2200     myGlVerMajor = 1;
2201     myGlVerMinor = 1;
2202     return;
2203   }
2204   else if (!has13)
2205   {
2206     checkWrongVersion (1, 3);
2207     myGlVerMajor = 1;
2208     myGlVerMinor = 2;
2209     return;
2210   }
2211   else if (!has14)
2212   {
2213     checkWrongVersion (1, 4);
2214     myGlVerMajor = 1;
2215     myGlVerMinor = 3;
2216     return;
2217   }
2218   else if (!has15)
2219   {
2220     checkWrongVersion (1, 5);
2221     myGlVerMajor = 1;
2222     myGlVerMinor = 4;
2223     return;
2224   }
2225   if (!isCoreProfile)
2226   {
2227     core15 = (OpenGl_GlCore15* )(&(*myFuncs));
2228   }
2229   core15fwd = (OpenGl_GlCore15Fwd* )(&(*myFuncs));
2230
2231   if (!has20)
2232   {
2233     checkWrongVersion (2, 0);
2234     myGlVerMajor = 1;
2235     myGlVerMinor = 5;
2236     return;
2237   }
2238
2239   const char* aGlslVer = (const char* )::glGetString (GL_SHADING_LANGUAGE_VERSION);
2240   if (aGlslVer == NULL
2241   || *aGlslVer == '\0')
2242   {
2243     // broken context has been detected
2244     TCollection_ExtendedString aMsg = TCollection_ExtendedString()
2245       + "Error! OpenGL context reports version "
2246       + myGlVerMajor  + "." + myGlVerMinor
2247       + " but reports wrong GLSL version";
2248     PushMessage (GL_DEBUG_SOURCE_APPLICATION,
2249                  GL_DEBUG_TYPE_ERROR,
2250                  0,
2251                  GL_DEBUG_SEVERITY_HIGH,
2252                  aMsg);
2253     myGlVerMajor = 1;
2254     myGlVerMinor = 5;
2255     return;
2256   }
2257
2258   if (!isCoreProfile)
2259   {
2260     core20  = (OpenGl_GlCore20*    )(&(*myFuncs));
2261   }
2262   core20fwd = (OpenGl_GlCore20Fwd* )(&(*myFuncs));
2263
2264   if (!has21)
2265   {
2266     checkWrongVersion (2, 1);
2267     myGlVerMajor = 2;
2268     myGlVerMinor = 0;
2269     return;
2270   }
2271
2272   if (!has30)
2273   {
2274     checkWrongVersion (3, 0);
2275     myGlVerMajor = 2;
2276     myGlVerMinor = 1;
2277     return;
2278   }
2279
2280   // MSAA RenderBuffers have been defined in OpenGL 3.0,
2281   // but MSAA Textures - only in OpenGL 3.2+
2282   if (!has32
2283    && CheckExtension ("GL_ARB_texture_multisample")
2284    && FindProcShort (glTexImage2DMultisample))
2285   {
2286     GLint aNbColorSamples = 0, aNbDepthSamples = 0;
2287     ::glGetIntegerv (GL_MAX_COLOR_TEXTURE_SAMPLES, &aNbColorSamples);
2288     ::glGetIntegerv (GL_MAX_DEPTH_TEXTURE_SAMPLES, &aNbDepthSamples);
2289     myMaxMsaaSamples = Min (aNbColorSamples, aNbDepthSamples);
2290   }
2291   if (!has43
2292    && CheckExtension ("GL_ARB_texture_storage_multisample")
2293    && FindProcShort (glTexStorage2DMultisample))
2294   {
2295     //
2296   }
2297
2298   if (!has31)
2299   {
2300     checkWrongVersion (3, 1);
2301     myGlVerMajor = 3;
2302     myGlVerMinor = 0;
2303     return;
2304   }
2305   arbTBO = (OpenGl_ArbTBO* )(&(*myFuncs));
2306   arbIns = (OpenGl_ArbIns* )(&(*myFuncs));
2307
2308   // check whether ray tracing mode is supported
2309   myHasRayTracing = has31
2310                  && arbTboRGB32
2311                  && arbFBOBlit  != NULL;
2312
2313   // check whether textures in ray tracing mode are supported
2314   myHasRayTracingTextures = myHasRayTracing
2315                          && arbTexBindless != NULL;
2316
2317   // check whether adaptive screen sampling in ray tracing mode is supported
2318   myHasRayTracingAdaptiveSampling = myHasRayTracing
2319                                  && has44
2320                                  && CheckExtension ("GL_NV_shader_atomic_float");
2321
2322   if (!has32)
2323   {
2324     checkWrongVersion (3, 2);
2325     myGlVerMajor = 3;
2326     myGlVerMinor = 1;
2327     return;
2328   }
2329   core32 = (OpenGl_GlCore32* )(&(*myFuncs));
2330   if (isCoreProfile)
2331   {
2332     core32->glGenVertexArrays (1, &myDefaultVao);
2333   }
2334   else
2335   {
2336     core32back = (OpenGl_GlCore32Back* )(&(*myFuncs));
2337   }
2338   ::glGetIntegerv (GL_MAX_SAMPLES, &myMaxMsaaSamples);
2339
2340   if (!has33)
2341   {
2342     checkWrongVersion (3, 3);
2343     myGlVerMajor = 3;
2344     myGlVerMinor = 2;
2345     return;
2346   }
2347   core33 = (OpenGl_GlCore33* )(&(*myFuncs));
2348   if (!isCoreProfile)
2349   {
2350     core33back = (OpenGl_GlCore33Back* )(&(*myFuncs));
2351   }
2352
2353   // initialize sampler object
2354   myTexSampler = new OpenGl_Sampler();
2355   myTexSampler->Init (*this);
2356
2357   if (!has40)
2358   {
2359     checkWrongVersion (4, 0);
2360     myGlVerMajor = 3;
2361     myGlVerMinor = 3;
2362     return;
2363   }
2364   arbTboRGB32 = Standard_True; // in core since OpenGL 4.0
2365
2366   if (!has41)
2367   {
2368     checkWrongVersion (4, 1);
2369     myGlVerMajor = 4;
2370     myGlVerMinor = 0;
2371     return;
2372   }
2373   core41 = (OpenGl_GlCore41* )(&(*myFuncs));
2374   if (!isCoreProfile)
2375   {
2376     core41back = (OpenGl_GlCore41Back* )(&(*myFuncs));
2377   }
2378
2379   if(!has42)
2380   {
2381     checkWrongVersion (4, 2);
2382     myGlVerMajor = 4;
2383     myGlVerMinor = 1;
2384     return;
2385   }
2386   core42 = (OpenGl_GlCore42* )(&(*myFuncs));
2387   if (!isCoreProfile)
2388   {
2389     core42back = (OpenGl_GlCore42Back* )(&(*myFuncs));
2390   }
2391
2392   if (!has43)
2393   {
2394     checkWrongVersion (4, 3);
2395     myGlVerMajor = 4;
2396     myGlVerMinor = 2;
2397     return;
2398   }
2399   core43 = (OpenGl_GlCore43* )(&(*myFuncs));
2400   if (!isCoreProfile)
2401   {
2402     core43back = (OpenGl_GlCore43Back* )(&(*myFuncs));
2403   }
2404
2405   if (!has44)
2406   {
2407     checkWrongVersion (4, 4);
2408     myGlVerMajor = 4;
2409     myGlVerMinor = 3;
2410     return;
2411   }
2412   core44 = (OpenGl_GlCore44* )(&(*myFuncs));
2413   if (!isCoreProfile)
2414   {
2415     core44back = (OpenGl_GlCore44Back* )(&(*myFuncs));
2416   }
2417 #endif
2418 }
2419
2420 // =======================================================================
2421 // function : MemoryInfo
2422 // purpose  :
2423 // =======================================================================
2424 Standard_Size OpenGl_Context::AvailableMemory() const
2425 {
2426 #if !defined(GL_ES_VERSION_2_0)
2427   if (atiMem)
2428   {
2429     // this is actually information for VBO pool
2430     // however because pools are mostly shared
2431     // it can be used for total GPU memory estimations
2432     GLint aMemInfo[4];
2433     aMemInfo[0] = 0;
2434     glGetIntegerv (GL_VBO_FREE_MEMORY_ATI, aMemInfo);
2435     // returned value is in KiB, however this maybe changed in future
2436     return Standard_Size(aMemInfo[0]) * 1024;
2437   }
2438   else if (nvxMem)
2439   {
2440     // current available dedicated video memory (in KiB), currently unused GPU memory
2441     GLint aMemInfo = 0;
2442     glGetIntegerv (GL_GPU_MEMORY_INFO_CURRENT_AVAILABLE_VIDMEM_NVX, &aMemInfo);
2443     return Standard_Size(aMemInfo) * 1024;
2444   }
2445 #endif
2446   return 0;
2447 }
2448
2449 // =======================================================================
2450 // function : MemoryInfo
2451 // purpose  :
2452 // =======================================================================
2453 TCollection_AsciiString OpenGl_Context::MemoryInfo() const
2454 {
2455   TColStd_IndexedDataMapOfStringString aDict;
2456   MemoryInfo (aDict);
2457
2458   TCollection_AsciiString aText;
2459   for (TColStd_IndexedDataMapOfStringString::Iterator anIter (aDict); anIter.More(); anIter.Next())
2460   {
2461     if (!aText.IsEmpty())
2462     {
2463       aText += "\n";
2464     }
2465     aText += TCollection_AsciiString("  ") + anIter.Key() + ": " + anIter.Value();
2466   }
2467   return aText;
2468 }
2469
2470 // =======================================================================
2471 // function : MemoryInfo
2472 // purpose  :
2473 // =======================================================================
2474 void OpenGl_Context::MemoryInfo (TColStd_IndexedDataMapOfStringString& theDict) const
2475 {
2476 #if defined(GL_ES_VERSION_2_0)
2477   (void )theDict;
2478 #elif defined(__APPLE__) && !defined(MACOSX_USE_GLX)
2479   GLint aGlRendId = 0;
2480   CGLGetParameter (CGLGetCurrentContext(), kCGLCPCurrentRendererID, &aGlRendId);
2481
2482   CGLRendererInfoObj  aRendObj = NULL;
2483   CGOpenGLDisplayMask aDispMask = CGDisplayIDToOpenGLDisplayMask (kCGDirectMainDisplay);
2484   GLint aRendNb = 0;
2485   CGLQueryRendererInfo (aDispMask, &aRendObj, &aRendNb);
2486   for (GLint aRendIter = 0; aRendIter < aRendNb; ++aRendIter)
2487   {
2488     GLint aRendId = 0;
2489     if (CGLDescribeRenderer (aRendObj, aRendIter, kCGLRPRendererID, &aRendId) != kCGLNoError
2490      || aRendId != aGlRendId)
2491     {
2492       continue;
2493     }
2494
2495     //kCGLRPVideoMemoryMegabytes   = 131;
2496     //kCGLRPTextureMemoryMegabytes = 132;
2497     GLint aVMem = 0;
2498   #if MAC_OS_X_VERSION_MIN_REQUIRED >= 1070
2499     if (CGLDescribeRenderer(aRendObj, aRendIter, kCGLRPVideoMemoryMegabytes, &aVMem) == kCGLNoError)
2500     {
2501       addInfo (theDict, "GPU memory",         TCollection_AsciiString() + aVMem + " MiB");
2502     }
2503     if (CGLDescribeRenderer(aRendObj, aRendIter, kCGLRPTextureMemoryMegabytes, &aVMem) == kCGLNoError)
2504     {
2505       addInfo (theDict, "GPU Texture memory", TCollection_AsciiString() + aVMem + " MiB");
2506     }
2507   #else
2508     if (CGLDescribeRenderer(aRendObj, aRendIter, kCGLRPVideoMemory, &aVMem) == kCGLNoError)
2509     {
2510       addInfo (theDict, "GPU memory",         TCollection_AsciiString() + (aVMem / (1024 * 1024)) + " MiB");
2511     }
2512     if (CGLDescribeRenderer(aRendObj, aRendIter, kCGLRPTextureMemory, &aVMem) == kCGLNoError)
2513     {
2514       addInfo (theDict, "GPU Texture memory", TCollection_AsciiString() + (aVMem / (1024 * 1024)) + " MiB");
2515     }
2516   #endif
2517   }
2518 #endif
2519
2520 #if !defined(GL_ES_VERSION_2_0)
2521   if (atiMem)
2522   {
2523     GLint aValues[4];
2524     memset (aValues, 0, sizeof(aValues));
2525     glGetIntegerv (GL_VBO_FREE_MEMORY_ATI, aValues);
2526
2527     // total memory free in the pool
2528     addInfo (theDict, "GPU free memory",    TCollection_AsciiString() + (aValues[0] / 1024) + " MiB");
2529
2530     if (aValues[1] != aValues[0])
2531     {
2532       // largest available free block in the pool
2533       addInfo (theDict, "Largest free block", TCollection_AsciiString() + (aValues[1] / 1024) + " MiB");
2534     }
2535     if (aValues[2] != aValues[0])
2536     {
2537       // total auxiliary memory free
2538       addInfo (theDict, "Free auxiliary memory", TCollection_AsciiString() + (aValues[2] / 1024) + " MiB");
2539     }
2540   }
2541   else if (nvxMem)
2542   {
2543     //current available dedicated video memory (in KiB), currently unused GPU memory
2544     GLint aValue = 0;
2545     glGetIntegerv (GL_GPU_MEMORY_INFO_CURRENT_AVAILABLE_VIDMEM_NVX, &aValue);
2546     addInfo (theDict, "GPU free memory", TCollection_AsciiString() + (aValue / 1024) + " MiB");
2547
2548     // dedicated video memory, total size (in KiB) of the GPU memory
2549     GLint aDedicated = 0;
2550     glGetIntegerv (GL_GPU_MEMORY_INFO_DEDICATED_VIDMEM_NVX, &aDedicated);
2551     addInfo (theDict, "GPU memory", TCollection_AsciiString() + (aDedicated / 1024) + " MiB");
2552
2553     // total available memory, total size (in KiB) of the memory available for allocations
2554     glGetIntegerv (GL_GPU_MEMORY_INFO_TOTAL_AVAILABLE_MEMORY_NVX, &aValue);
2555     if (aValue != aDedicated)
2556     {
2557       // different only for special configurations
2558       addInfo (theDict, "Total memory", TCollection_AsciiString() + (aValue / 1024) + " MiB");
2559     }
2560   }
2561 #endif
2562
2563 #if !defined(GL_ES_VERSION_2_0) && !defined(__APPLE__) && !defined(_WIN32)
2564   // GLX_RENDERER_VENDOR_ID_MESA
2565   if (myFuncs->glXQueryCurrentRendererIntegerMESA != NULL)
2566   {
2567     unsigned int aVMemMiB = 0;
2568     if (myFuncs->glXQueryCurrentRendererIntegerMESA (GLX_RENDERER_VIDEO_MEMORY_MESA, &aVMemMiB) != False)
2569     {
2570       addInfo (theDict, "GPU memory", TCollection_AsciiString() + int(aVMemMiB) + " MiB");
2571     }
2572   }
2573 #endif
2574 }
2575
2576 // =======================================================================
2577 // function : DiagnosticInfo
2578 // purpose  :
2579 // =======================================================================
2580 void OpenGl_Context::DiagnosticInformation (TColStd_IndexedDataMapOfStringString& theDict,
2581                                             Graphic3d_DiagnosticInfo theFlags) const
2582 {
2583   if ((theFlags & Graphic3d_DiagnosticInfo_NativePlatform) != 0)
2584   {
2585   #if defined(HAVE_EGL)
2586     addInfo (theDict, "EGLVersion",    ::eglQueryString ((Aspect_Display)myDisplay, EGL_VERSION));
2587     addInfo (theDict, "EGLVendor",     ::eglQueryString ((Aspect_Display)myDisplay, EGL_VENDOR));
2588     addInfo (theDict, "EGLClientAPIs", ::eglQueryString ((Aspect_Display)myDisplay, EGL_CLIENT_APIS));
2589     if ((theFlags & Graphic3d_DiagnosticInfo_Extensions) != 0)
2590     {
2591       addInfo (theDict, "EGLExtensions", ::eglQueryString ((Aspect_Display)myDisplay, EGL_EXTENSIONS));
2592     }
2593   #elif defined(_WIN32)
2594     if ((theFlags & Graphic3d_DiagnosticInfo_Extensions) != 0
2595      && myFuncs->wglGetExtensionsStringARB != NULL)
2596     {
2597       const char* aWglExts = myFuncs->wglGetExtensionsStringARB ((HDC )myWindowDC);
2598       addInfo (theDict, "WGLExtensions", aWglExts);
2599     }
2600   #elif defined(__APPLE__)
2601     //
2602   #else
2603     Display* aDisplay = (Display*)myDisplay;
2604     const int aScreen = DefaultScreen(aDisplay);
2605     addInfo (theDict, "GLXDirectRendering", ::glXIsDirect (aDisplay, (GLXContext )myGContext) ? "Yes" : "No");
2606     addInfo (theDict, "GLXVendor",  ::glXQueryServerString (aDisplay, aScreen, GLX_VENDOR));
2607     addInfo (theDict, "GLXVersion", ::glXQueryServerString (aDisplay, aScreen, GLX_VERSION));
2608     if ((theFlags & Graphic3d_DiagnosticInfo_Extensions) != 0)
2609     {
2610       const char* aGlxExts = ::glXQueryExtensionsString (aDisplay, aScreen);
2611       addInfo(theDict, "GLXExtensions", aGlxExts);
2612     }
2613
2614     addInfo (theDict, "GLXClientVendor",  ::glXGetClientString (aDisplay, GLX_VENDOR));
2615     addInfo (theDict, "GLXClientVersion", ::glXGetClientString (aDisplay, GLX_VERSION));
2616     if ((theFlags & Graphic3d_DiagnosticInfo_Extensions) != 0)
2617     {
2618       addInfo (theDict, "GLXClientExtensions", ::glXGetClientString (aDisplay, GLX_EXTENSIONS));
2619     }
2620   #endif
2621   }
2622
2623   if ((theFlags & Graphic3d_DiagnosticInfo_Device) != 0)
2624   {
2625     addInfo (theDict, "GLvendor",    (const char*)::glGetString (GL_VENDOR));
2626     addInfo (theDict, "GLdevice",    (const char*)::glGetString (GL_RENDERER));
2627     addInfo (theDict, "GLversion",   (const char*)::glGetString (GL_VERSION));
2628     addInfo (theDict, "GLSLversion", (const char*)::glGetString (GL_SHADING_LANGUAGE_VERSION));
2629     if (myIsGlDebugCtx)
2630     {
2631       addInfo (theDict, "GLdebug", "ON");
2632     }
2633   }
2634
2635   if ((theFlags & Graphic3d_DiagnosticInfo_Limits) != 0)
2636   {
2637     addInfo (theDict, "Max texture size", TCollection_AsciiString(myMaxTexDim));
2638     addInfo (theDict, "Max MSAA samples", TCollection_AsciiString(myMaxMsaaSamples));
2639   }
2640
2641   if ((theFlags & Graphic3d_DiagnosticInfo_FrameBuffer) != 0)
2642   {
2643     GLint aViewport[4] = {};
2644     ::glGetIntegerv (GL_VIEWPORT, aViewport);
2645     addInfo (theDict, "Viewport", TCollection_AsciiString() + aViewport[2] + "x" + aViewport[3]);
2646   }
2647
2648   if ((theFlags & Graphic3d_DiagnosticInfo_Memory) != 0)
2649   {
2650     MemoryInfo (theDict);
2651   }
2652
2653   if ((theFlags & Graphic3d_DiagnosticInfo_Extensions) != 0)
2654   {
2655   #if !defined(GL_ES_VERSION_2_0)
2656     if (IsGlGreaterEqual (3, 0)
2657      && myFuncs->glGetStringi != NULL)
2658     {
2659       TCollection_AsciiString anExtList;
2660       GLint anExtNb = 0;
2661       ::glGetIntegerv (GL_NUM_EXTENSIONS, &anExtNb);
2662       for (GLint anIter = 0; anIter < anExtNb; ++anIter)
2663       {
2664         const char* anExtension = (const char*)myFuncs->glGetStringi (GL_EXTENSIONS, (GLuint)anIter);
2665         if (!anExtList.IsEmpty())
2666         {
2667           anExtList += " ";
2668         }
2669         anExtList += anExtension;
2670       }
2671       addInfo(theDict, "GLextensions", anExtList);
2672     }
2673     else
2674   #endif
2675     {
2676       addInfo (theDict, "GLextensions", (const char*)::glGetString (GL_EXTENSIONS));
2677     }
2678   }
2679 }
2680
2681 // =======================================================================
2682 // function : GetResource
2683 // purpose  :
2684 // =======================================================================
2685 const Handle(OpenGl_Resource)& OpenGl_Context::GetResource (const TCollection_AsciiString& theKey) const
2686 {
2687   return mySharedResources->IsBound (theKey) ? mySharedResources->Find (theKey) : NULL_GL_RESOURCE;
2688 }
2689
2690 // =======================================================================
2691 // function : ShareResource
2692 // purpose  :
2693 // =======================================================================
2694 Standard_Boolean OpenGl_Context::ShareResource (const TCollection_AsciiString& theKey,
2695                                                 const Handle(OpenGl_Resource)& theResource)
2696 {
2697   if (theKey.IsEmpty() || theResource.IsNull())
2698   {
2699     return Standard_False;
2700   }
2701   return mySharedResources->Bind (theKey, theResource);
2702 }
2703
2704 // =======================================================================
2705 // function : ReleaseResource
2706 // purpose  :
2707 // =======================================================================
2708 void OpenGl_Context::ReleaseResource (const TCollection_AsciiString& theKey,
2709                                       const Standard_Boolean         theToDelay)
2710 {
2711   if (!mySharedResources->IsBound (theKey))
2712   {
2713     return;
2714   }
2715   auto& aRes = mySharedResources->Find (theKey);
2716   if (aRes->GetRefCount() > 1)
2717   {
2718     return;
2719   }
2720
2721   if (theToDelay)
2722   {
2723     myDelayed->Bind (theKey, 1);
2724   }
2725   else
2726   {
2727     aRes->Release (this);
2728     mySharedResources->UnBind (theKey);
2729   }
2730 }
2731
2732 // =======================================================================
2733 // function : ReleaseDelayed
2734 // purpose  :
2735 // =======================================================================
2736 void OpenGl_Context::ReleaseDelayed()
2737 {
2738   // release queued elements
2739   while (!myUnusedResources->IsEmpty())
2740   {
2741     myUnusedResources->First()->Release (this);
2742     myUnusedResources->RemoveFirst();
2743   }
2744
2745   // release delayed shared resources
2746   NCollection_Vector<TCollection_AsciiString> aDeadList;
2747   for (NCollection_DataMap<TCollection_AsciiString, Standard_Integer>::Iterator anIter (*myDelayed);
2748        anIter.More(); anIter.Next())
2749   {
2750     if (++anIter.ChangeValue() <= 2)
2751     {
2752       continue; // postpone release one more frame to ensure noone use it periodically
2753     }
2754
2755     const TCollection_AsciiString& aKey = anIter.Key();
2756     if (!mySharedResources->IsBound (aKey))
2757     {
2758       // mixed unshared strategy delayed/undelayed was used!
2759       aDeadList.Append (aKey);
2760       continue;
2761     }
2762
2763     auto& aRes = mySharedResources->ChangeFind (aKey);
2764     if (aRes->GetRefCount() > 1)
2765     {
2766       // should be only 1 instance in mySharedResources
2767       // if not - resource was reused again
2768       aDeadList.Append (aKey);
2769       continue;
2770     }
2771
2772     // release resource if no one requiested it more than 2 redraw calls
2773     aRes->Release (this);
2774     mySharedResources->UnBind (aKey);
2775     aDeadList.Append (aKey);
2776   }
2777
2778   for (Standard_Integer anIter = 0; anIter < aDeadList.Length(); ++anIter)
2779   {
2780     myDelayed->UnBind (aDeadList.Value (anIter));
2781   }
2782 }
2783
2784 // =======================================================================
2785 // function : BindProgram
2786 // purpose  :
2787 // =======================================================================
2788 Standard_Boolean OpenGl_Context::BindProgram (const Handle(OpenGl_ShaderProgram)& theProgram)
2789 {
2790   if (core20fwd == NULL)
2791   {
2792     return Standard_False;
2793   }
2794
2795   if (theProgram.IsNull()
2796   || !theProgram->IsValid())
2797   {
2798     if (!myActiveProgram.IsNull())
2799     {
2800       core20fwd->glUseProgram (OpenGl_ShaderProgram::NO_PROGRAM);
2801       myActiveProgram.Nullify();
2802     }
2803     return Standard_False;
2804   }
2805
2806   myActiveProgram = theProgram;
2807   core20fwd->glUseProgram (theProgram->ProgramId());
2808   return Standard_True;
2809 }
2810
2811 // =======================================================================
2812 // function : BindDefaultVao
2813 // purpose  :
2814 // =======================================================================
2815 void OpenGl_Context::BindDefaultVao()
2816 {
2817 #if !defined(GL_ES_VERSION_2_0)
2818   if (myDefaultVao == 0
2819    || core32 == NULL)
2820   {
2821     return;
2822   }
2823
2824   core32->glBindVertexArray (myDefaultVao);
2825 #endif
2826 }
2827
2828 // =======================================================================
2829 // function : SetDefaultFrameBuffer
2830 // purpose  :
2831 // =======================================================================
2832 Handle(OpenGl_FrameBuffer) OpenGl_Context::SetDefaultFrameBuffer (const Handle(OpenGl_FrameBuffer)& theFbo)
2833 {
2834   Handle(OpenGl_FrameBuffer) aFbo = myDefaultFbo;
2835   myDefaultFbo = theFbo;
2836   return aFbo;
2837 }
2838
2839 // =======================================================================
2840 // function : SetShadingMaterial
2841 // purpose  :
2842 // =======================================================================
2843 void OpenGl_Context::SetShadingMaterial (const OpenGl_AspectFace* theAspect,
2844                                          const OpenGl_Vec4* theHighlightColor)
2845 {
2846   if (!myActiveProgram.IsNull())
2847   {
2848     myActiveProgram->SetUniform (this,
2849                                  myActiveProgram->GetStateLocation (OpenGl_OCCT_TEXTURE_ENABLE),
2850                                  theAspect->Aspect()->ToMapTexture() ? 1 : 0);
2851     myActiveProgram->SetUniform (this,
2852                                  myActiveProgram->GetStateLocation (OpenGl_OCCT_DISTINGUISH_MODE),
2853                                  theAspect->Aspect()->Distinguish() ? 1 : 0);
2854
2855     OpenGl_Material aParams;
2856     for (Standard_Integer anIndex = 0; anIndex < 2; ++anIndex)
2857     {
2858       const GLint aLoc = myActiveProgram->GetStateLocation (anIndex == 0
2859                                                           ? OpenGl_OCCT_FRONT_MATERIAL
2860                                                           : OpenGl_OCCT_BACK_MATERIAL);
2861       if (aLoc == OpenGl_ShaderProgram::INVALID_LOCATION)
2862       {
2863         continue;
2864       }
2865
2866       if (anIndex == 0 || !theAspect->Aspect()->Distinguish())
2867       {
2868         const Graphic3d_MaterialAspect& aSrcMat      = theAspect->Aspect()->FrontMaterial();
2869         const Quantity_Color&           aSrcIntColor = theAspect->Aspect()->InteriorColor();
2870         aParams.Init (aSrcMat, aSrcIntColor);
2871         aParams.Diffuse.a() = 1.0f - (float )aSrcMat.Transparency();
2872       }
2873       else
2874       {
2875         const Graphic3d_MaterialAspect& aSrcMat      = theAspect->Aspect()->BackMaterial();
2876         const Quantity_Color&           aSrcIntColor = theAspect->Aspect()->BackInteriorColor();
2877         aParams.Init (aSrcMat, aSrcIntColor);
2878         aParams.Diffuse.a() = 1.0f - (float )aSrcMat.Transparency();
2879       }
2880       if (theHighlightColor != NULL)
2881       {
2882         aParams.SetColor (*theHighlightColor);
2883         aParams.Diffuse.a() = theHighlightColor->a();
2884       }
2885
2886       myActiveProgram->SetUniform (this, aLoc, OpenGl_Material::NbOfVec4(),
2887                                    aParams.Packed());
2888     }
2889   }
2890 }
2891
2892 // =======================================================================
2893 // function : SetColor4fv
2894 // purpose  :
2895 // =======================================================================
2896 void OpenGl_Context::SetColor4fv (const OpenGl_Vec4& theColor)
2897 {
2898   if (!myActiveProgram.IsNull())
2899   {
2900     myActiveProgram->SetUniform (this, myActiveProgram->GetStateLocation (OpenGl_OCCT_COLOR), theColor);
2901   }
2902 #if !defined(GL_ES_VERSION_2_0)
2903   else if (core11 != NULL)
2904   {
2905     core11->glColor4fv (theColor.GetData());
2906   }
2907 #endif
2908 }
2909
2910 // =======================================================================
2911 // function : SetTypeOfLine
2912 // purpose  :
2913 // =======================================================================
2914 void OpenGl_Context::SetTypeOfLine (const Aspect_TypeOfLine  theType,
2915                                     const Standard_ShortReal theFactor)
2916 {
2917   Standard_Integer aPattern = 0xFFFF;
2918   switch (theType)
2919   {
2920     case Aspect_TOL_DASH:
2921     {
2922       aPattern = 0xFFC0;
2923       break;
2924     }
2925     case Aspect_TOL_DOT:
2926     {
2927       aPattern = 0xCCCC;
2928       break;
2929     }
2930     case Aspect_TOL_DOTDASH:
2931     {
2932       aPattern = 0xFF18;
2933       break;
2934     }
2935     case Aspect_TOL_SOLID:
2936     {
2937       aPattern = 0xFFFF;
2938       break;
2939     }
2940     case Aspect_TOL_USERDEFINED:
2941     {
2942       aPattern = 0xFF24;
2943       break;
2944     }
2945   }
2946
2947   if (!myActiveProgram.IsNull())
2948   {
2949     myActiveProgram->SetUniform (this, "uPattern", aPattern);
2950     myActiveProgram->SetUniform (this, "uFactor",  theFactor);
2951     return;
2952   }
2953
2954 #if !defined(GL_ES_VERSION_2_0)
2955   if (theType != Aspect_TOL_SOLID)
2956   {
2957   #ifdef HAVE_GL2PS
2958     if (IsFeedback())
2959     {
2960       gl2psEnable (GL2PS_LINE_STIPPLE);
2961     }
2962   #endif
2963
2964     if (core11 != NULL)
2965     {
2966       core11fwd->glEnable (GL_LINE_STIPPLE);
2967
2968       core11->glLineStipple (static_cast<GLint>    (theFactor),
2969                              static_cast<GLushort> (aPattern));
2970     }
2971   }
2972   else
2973   {
2974     if (core11 != NULL)
2975     {
2976       core11fwd->glDisable (GL_LINE_STIPPLE);
2977     }
2978
2979   #ifdef HAVE_GL2PS
2980     if (IsFeedback())
2981     {
2982       gl2psDisable (GL2PS_LINE_STIPPLE);
2983     }
2984   #endif
2985   }
2986 #endif
2987 }
2988
2989 // =======================================================================
2990 // function : SetLineWidth
2991 // purpose  :
2992 // =======================================================================
2993 void OpenGl_Context::SetLineWidth (const Standard_ShortReal theWidth)
2994 {
2995   if (core11 != NULL)
2996   {
2997     // glLineWidth() is still defined within Core Profile, but has no effect with values != 1.0f
2998     core11fwd->glLineWidth (theWidth * myResolutionRatio);
2999   }
3000 #ifdef HAVE_GL2PS
3001   if (IsFeedback())
3002   {
3003     gl2psLineWidth (theWidth);
3004   }
3005 #endif
3006 }
3007
3008 // =======================================================================
3009 // function : SetTextureMatrix
3010 // purpose  :
3011 // =======================================================================
3012 void OpenGl_Context::SetTextureMatrix (const Handle(Graphic3d_TextureParams)& theParams)
3013 {
3014   if (theParams.IsNull())
3015   {
3016     return;
3017   }
3018   else if (!myActiveProgram.IsNull())
3019   {
3020     const GLint aUniLoc = myActiveProgram->GetStateLocation (OpenGl_OCCT_TEXTURE_TRSF2D);
3021     if (aUniLoc == OpenGl_ShaderProgram::INVALID_LOCATION)
3022     {
3023       return;
3024     }
3025
3026     // pack transformation parameters
3027     OpenGl_Vec4 aTrsf[2];
3028     aTrsf[0].xy() = theParams->Translation();
3029     aTrsf[0].zw() = theParams->Scale();
3030     aTrsf[1].x()  = std::sin (-theParams->Rotation() * static_cast<float> (M_PI / 180.0));
3031     aTrsf[1].y()  = std::cos (-theParams->Rotation() * static_cast<float> (M_PI / 180.0));
3032     myActiveProgram->SetUniform (this, aUniLoc, 2, aTrsf);
3033     return;
3034   }
3035
3036 #if !defined(GL_ES_VERSION_2_0)
3037   if (core11 != NULL)
3038   {
3039     GLint aMatrixMode = GL_TEXTURE;
3040     ::glGetIntegerv (GL_MATRIX_MODE, &aMatrixMode);
3041
3042     core11->glMatrixMode (GL_TEXTURE);
3043     OpenGl_Mat4 aTextureMat;
3044     const Graphic3d_Vec2& aScale = theParams->Scale();
3045     const Graphic3d_Vec2& aTrans = theParams->Translation();
3046     Graphic3d_TransformUtils::Scale     (aTextureMat,  aScale.x(),  aScale.y(), 1.0f);
3047     Graphic3d_TransformUtils::Translate (aTextureMat, -aTrans.x(), -aTrans.y(), 0.0f);
3048     Graphic3d_TransformUtils::Rotate    (aTextureMat, -theParams->Rotation(), 0.0f, 0.0f, 1.0f);
3049     core11->glLoadMatrixf (aTextureMat);
3050     core11->glMatrixMode (aMatrixMode);
3051   }
3052 #endif
3053 }
3054
3055 // =======================================================================
3056 // function : SetPointSize
3057 // purpose  :
3058 // =======================================================================
3059 void OpenGl_Context::SetPointSize (const Standard_ShortReal theSize)
3060 {
3061   if (!myActiveProgram.IsNull())
3062   {
3063     myActiveProgram->SetUniform (this, myActiveProgram->GetStateLocation (OpenGl_OCCT_POINT_SIZE), theSize);
3064   #if !defined(GL_ES_VERSION_2_0)
3065     //myContext->core11fwd->glEnable (GL_VERTEX_PROGRAM_POINT_SIZE);
3066   #endif
3067   }
3068 #if !defined(GL_ES_VERSION_2_0)
3069   //else
3070   {
3071     core11fwd->glPointSize (theSize);
3072     if (core20fwd != NULL)
3073     {
3074       //myContext->core11fwd->glDisable (GL_VERTEX_PROGRAM_POINT_SIZE);
3075     }
3076   }
3077 #endif
3078 }
3079
3080 // =======================================================================
3081 // function : SetPointSpriteOrigin
3082 // purpose  :
3083 // =======================================================================
3084 void OpenGl_Context::SetPointSpriteOrigin()
3085 {
3086 #if !defined(GL_ES_VERSION_2_0)
3087   if (core15fwd == NULL)
3088   {
3089     return;
3090   }
3091
3092   const int aNewState = !myActiveProgram.IsNull() ? GL_UPPER_LEFT : GL_LOWER_LEFT;
3093   if (myPointSpriteOrig != aNewState)
3094   {
3095     myPointSpriteOrig = aNewState;
3096     core15fwd->glPointParameteri (GL_POINT_SPRITE_COORD_ORIGIN, aNewState);
3097   }
3098 #endif
3099 }
3100
3101 // =======================================================================
3102 // function : SetGlNormalizeEnabled
3103 // purpose  :
3104 // =======================================================================
3105 Standard_Boolean OpenGl_Context::SetGlNormalizeEnabled (Standard_Boolean isEnabled)
3106 {
3107   if (isEnabled == myIsGlNormalizeEnabled)
3108   {
3109     return myIsGlNormalizeEnabled;
3110   }
3111
3112   Standard_Boolean anOldGlNormalize = myIsGlNormalizeEnabled;
3113
3114   myIsGlNormalizeEnabled = isEnabled;
3115
3116 #if !defined(GL_ES_VERSION_2_0)
3117   if (core11 != NULL)
3118   {
3119     if (isEnabled)
3120     {
3121       ::glEnable  (GL_NORMALIZE);
3122     }
3123     else
3124     {
3125       ::glDisable (GL_NORMALIZE);
3126     }
3127   }
3128 #endif
3129
3130   return anOldGlNormalize;
3131 }
3132
3133 // =======================================================================
3134 // function : SetPolygonMode
3135 // purpose  :
3136 // =======================================================================
3137 Standard_Integer OpenGl_Context::SetPolygonMode (const Standard_Integer theMode)
3138 {
3139   if (myPolygonMode == theMode)
3140   {
3141     return myPolygonMode;
3142   }
3143
3144   const Standard_Integer anOldPolygonMode = myPolygonMode;
3145
3146   myPolygonMode = theMode;
3147
3148 #if !defined(GL_ES_VERSION_2_0)
3149   ::glPolygonMode (GL_FRONT_AND_BACK, (GLenum)theMode);
3150 #endif
3151
3152   return anOldPolygonMode;
3153 }
3154
3155 // =======================================================================
3156 // function : SetPolygonHatchEnabled
3157 // purpose  :
3158 // =======================================================================
3159 bool OpenGl_Context::SetPolygonHatchEnabled (const bool theIsEnabled)
3160 {
3161   if (myHatchStyles.IsNull())
3162   {
3163     return false;
3164   }
3165   else if (myHatchStyles->IsEnabled() == theIsEnabled)
3166   {
3167     return theIsEnabled;
3168   }
3169
3170   return myHatchStyles->SetEnabled (this, theIsEnabled);
3171 }
3172
3173 // =======================================================================
3174 // function : SetPolygonHatchStyle
3175 // purpose  :
3176 // =======================================================================
3177 Standard_Integer OpenGl_Context::SetPolygonHatchStyle (const Standard_Integer theType)
3178 {
3179   if (myHatchStyles.IsNull())
3180   {
3181     if (!GetResource ("OpenGl_LineAttributes", myHatchStyles))
3182     {
3183       // share and register for release once the resource is no longer used
3184       myHatchStyles = new OpenGl_LineAttributes();
3185       ShareResource ("OpenGl_LineAttributes", myHatchStyles);
3186       myHatchStyles->Init (this);
3187     }
3188   }
3189   if (myHatchStyles->TypeOfHatch() == theType)
3190   {
3191     return theType;
3192   }
3193
3194   return myHatchStyles->SetTypeOfHatch (this, theType);
3195 }
3196
3197 // =======================================================================
3198 // function : ApplyModelWorldMatrix
3199 // purpose  :
3200 // =======================================================================
3201 void OpenGl_Context::ApplyModelWorldMatrix()
3202 {
3203 #if !defined(GL_ES_VERSION_2_0)
3204   if (core11 != NULL)
3205   {
3206     core11->glMatrixMode (GL_MODELVIEW);
3207     core11->glLoadMatrixf (ModelWorldState.Current());
3208   }
3209 #endif
3210
3211   if (!myShaderManager->IsEmpty())
3212   {
3213     myShaderManager->UpdateModelWorldStateTo (ModelWorldState.Current());
3214   }
3215 }
3216
3217 // =======================================================================
3218 // function : ApplyWorldViewMatrix
3219 // purpose  :
3220 // =======================================================================
3221 void OpenGl_Context::ApplyWorldViewMatrix()
3222 {
3223 #if !defined(GL_ES_VERSION_2_0)
3224   if (core11 != NULL)
3225   {
3226     core11->glMatrixMode (GL_MODELVIEW);
3227     core11->glLoadMatrixf (WorldViewState.Current());
3228   }
3229 #endif
3230
3231   if (!myShaderManager->IsEmpty())
3232   {
3233     myShaderManager->UpdateModelWorldStateTo (THE_IDENTITY_MATRIX);
3234     myShaderManager->UpdateWorldViewStateTo (WorldViewState.Current());
3235   }
3236 }
3237
3238 // =======================================================================
3239 // function : ApplyModelViewMatrix
3240 // purpose  :
3241 // =======================================================================
3242 void OpenGl_Context::ApplyModelViewMatrix()
3243 {
3244 #if !defined(GL_ES_VERSION_2_0)
3245   if (core11 != NULL)
3246   {
3247     OpenGl_Mat4 aModelView = WorldViewState.Current() * ModelWorldState.Current();
3248     core11->glMatrixMode (GL_MODELVIEW);
3249     core11->glLoadMatrixf (aModelView.GetData());
3250   }
3251 #endif
3252
3253   if (!myShaderManager->IsEmpty())
3254   {
3255     myShaderManager->UpdateModelWorldStateTo (ModelWorldState.Current());
3256     myShaderManager->UpdateWorldViewStateTo (WorldViewState.Current());
3257   }
3258 }
3259
3260 // =======================================================================
3261 // function : ApplyProjectionMatrix
3262 // purpose  :
3263 // =======================================================================
3264 void OpenGl_Context::ApplyProjectionMatrix()
3265 {
3266 #if !defined(GL_ES_VERSION_2_0)
3267   if (core11 != NULL)
3268   {
3269     core11->glMatrixMode (GL_PROJECTION);
3270     core11->glLoadMatrixf (ProjectionState.Current().GetData());
3271   }
3272 #endif
3273
3274   if (!myShaderManager->IsEmpty())
3275   {
3276     myShaderManager->UpdateProjectionStateTo (ProjectionState.Current());
3277   }
3278 }
3279
3280
3281 // =======================================================================
3282 // function : EnableFeatures
3283 // purpose  :
3284 // =======================================================================
3285 void OpenGl_Context::EnableFeatures() const
3286 {
3287   //
3288 }
3289
3290 // =======================================================================
3291 // function : DisableFeatures
3292 // purpose  :
3293 // =======================================================================
3294 void OpenGl_Context::DisableFeatures() const
3295 {
3296 #if !defined(GL_ES_VERSION_2_0)
3297   glPixelTransferi (GL_MAP_COLOR, GL_FALSE);
3298 #endif
3299
3300   /*
3301   * Disable stuff that's likely to slow down glDrawPixels.
3302   * (Omit as much of this as possible, when you know in advance
3303   * that the OpenGL state will already be set correctly.)
3304   */
3305   glDisable(GL_DITHER);
3306   glDisable(GL_BLEND);
3307   glDisable(GL_DEPTH_TEST);
3308   glDisable(GL_TEXTURE_2D);
3309   glDisable(GL_STENCIL_TEST);
3310
3311 #if !defined(GL_ES_VERSION_2_0)
3312   glDisable(GL_LIGHTING);
3313   glDisable(GL_ALPHA_TEST);
3314   glDisable(GL_FOG);
3315   glDisable(GL_LOGIC_OP);
3316   glDisable(GL_TEXTURE_1D);
3317
3318   glPixelTransferi(GL_MAP_COLOR, GL_FALSE);
3319   glPixelTransferi(GL_RED_SCALE, 1);
3320   glPixelTransferi(GL_RED_BIAS, 0);
3321   glPixelTransferi(GL_GREEN_SCALE, 1);
3322   glPixelTransferi(GL_GREEN_BIAS, 0);
3323   glPixelTransferi(GL_BLUE_SCALE, 1);
3324   glPixelTransferi(GL_BLUE_BIAS, 0);
3325   glPixelTransferi(GL_ALPHA_SCALE, 1);
3326   glPixelTransferi(GL_ALPHA_BIAS, 0);
3327
3328   /*
3329   * Disable extensions that could slow down glDrawPixels.
3330   * (Actually, you should check for the presence of the proper
3331   * extension before making these calls.  I've omitted that
3332   * code for simplicity.)
3333   */
3334
3335   if ((myGlVerMajor >= 1) && (myGlVerMinor >= 2))
3336   {
3337 #ifdef GL_EXT_convolution
3338     if (CheckExtension ("GL_CONVOLUTION_1D_EXT"))
3339       glDisable(GL_CONVOLUTION_1D_EXT);
3340
3341     if (CheckExtension ("GL_CONVOLUTION_2D_EXT"))
3342       glDisable(GL_CONVOLUTION_2D_EXT);
3343
3344     if (CheckExtension ("GL_SEPARABLE_2D_EXT"))
3345       glDisable(GL_SEPARABLE_2D_EXT);
3346 #endif
3347
3348 #ifdef GL_EXT_histogram
3349     if (CheckExtension ("GL_SEPARABLE_2D_EXT"))
3350       glDisable(GL_HISTOGRAM_EXT);
3351
3352     if (CheckExtension ("GL_MINMAX_EXT"))
3353       glDisable(GL_MINMAX_EXT);
3354 #endif
3355
3356 #ifdef GL_EXT_texture3D
3357     if (CheckExtension ("GL_TEXTURE_3D_EXT"))
3358       glDisable(GL_TEXTURE_3D_EXT);
3359 #endif
3360   }
3361 #endif
3362 }