Warnings on vc14 were eliminated
[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 bool OpenGl_Context::ResetErrors (const bool theToPrintErrors)
816 {
817   int aPrevErr = 0;
818   int anErr    = ::glGetError();
819   const bool hasError = anErr != GL_NO_ERROR;
820   if (!theToPrintErrors)
821   {
822     for (; anErr != GL_NO_ERROR && aPrevErr != anErr; aPrevErr = anErr, anErr = ::glGetError())
823     {
824       //
825     }
826     return hasError;
827   }
828
829   for (; anErr != GL_NO_ERROR && aPrevErr != anErr; aPrevErr = anErr, anErr = ::glGetError())
830   {
831     TCollection_ExtendedString anErrId;
832     switch (anErr)
833     {
834       case GL_INVALID_ENUM:      anErrId = "GL_INVALID_ENUM";      break;
835       case GL_INVALID_VALUE:     anErrId = "GL_INVALID_VALUE";     break;
836       case GL_INVALID_OPERATION: anErrId = "GL_INVALID_OPERATION"; break;
837     #ifdef GL_STACK_OVERFLOW
838       case GL_STACK_OVERFLOW:    anErrId = "GL_STACK_OVERFLOW";    break;
839       case GL_STACK_UNDERFLOW:   anErrId = "GL_STACK_UNDERFLOW";   break;
840     #endif
841       case GL_OUT_OF_MEMORY:     anErrId = "GL_OUT_OF_MEMORY";     break;
842       case GL_INVALID_FRAMEBUFFER_OPERATION:
843         anErrId = "GL_INVALID_FRAMEBUFFER_OPERATION";
844         break;
845       default:
846         anErrId = TCollection_ExtendedString("#") + anErr;
847         break;
848     }
849
850     const TCollection_ExtendedString aMsg = TCollection_ExtendedString ("Unhandled GL error: ") + anErrId;
851     PushMessage (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_OTHER, 0, GL_DEBUG_SEVERITY_LOW, aMsg);
852   }
853   return hasError;
854 }
855
856 // =======================================================================
857 // function : ReadGlVersion
858 // purpose  :
859 // =======================================================================
860 void OpenGl_Context::ReadGlVersion (Standard_Integer& theGlVerMajor,
861                                     Standard_Integer& theGlVerMinor)
862 {
863   // reset values
864   theGlVerMajor = 0;
865   theGlVerMinor = 0;
866
867 #ifdef GL_MAJOR_VERSION
868   // available since OpenGL 3.0 and OpenGL 3.0 ES
869   GLint aMajor = 0, aMinor = 0;
870   glGetIntegerv (GL_MAJOR_VERSION, &aMajor);
871   glGetIntegerv (GL_MINOR_VERSION, &aMinor);
872   // glGetError() sometimes does not report an error here even if
873   // GL does not know GL_MAJOR_VERSION and GL_MINOR_VERSION constants.
874   // This happens on some renderers like e.g. Cygwin MESA.
875   // Thus checking additionally if GL has put anything to
876   // the output variables.
877   if (::glGetError() == GL_NO_ERROR && aMajor != 0 && aMinor != 0)
878   {
879     theGlVerMajor = aMajor;
880     theGlVerMinor = aMinor;
881     return;
882   }
883   for (GLenum anErr = ::glGetError(), aPrevErr = GL_NO_ERROR;; aPrevErr = anErr, anErr = ::glGetError())
884   {
885     if (anErr == GL_NO_ERROR
886      || anErr == aPrevErr)
887     {
888       break;
889     }
890   }
891 #endif
892
893   // Read version string.
894   // Notice that only first two numbers split by point '2.1 XXXXX' are significant.
895   // Following trash (after space) is vendor-specific.
896   // New drivers also returns micro version of GL like '3.3.0' which has no meaning
897   // and should be considered as vendor-specific too.
898   const char* aVerStr = (const char* )glGetString (GL_VERSION);
899   if (aVerStr == NULL || *aVerStr == '\0')
900   {
901     // invalid GL context
902     return;
903   }
904
905 //#if defined(GL_ES_VERSION_2_0)
906   // skip "OpenGL ES-** " section
907   for (; *aVerStr != '\0'; ++aVerStr)
908   {
909     if (*aVerStr >= '0' && *aVerStr <= '9')
910     {
911       break;
912     }
913   }
914 //#endif
915
916   // parse string for major number
917   char aMajorStr[32];
918   char aMinorStr[32];
919   size_t aMajIter = 0;
920   while (aVerStr[aMajIter] >= '0' && aVerStr[aMajIter] <= '9')
921   {
922     ++aMajIter;
923   }
924   if (aMajIter == 0 || aMajIter >= sizeof(aMajorStr))
925   {
926     return;
927   }
928   memcpy (aMajorStr, aVerStr, aMajIter);
929   aMajorStr[aMajIter] = '\0';
930
931   // parse string for minor number
932   aVerStr += aMajIter + 1;
933   size_t aMinIter = 0;
934   while (aVerStr[aMinIter] >= '0' && aVerStr[aMinIter] <= '9')
935   {
936     ++aMinIter;
937   }
938   if (aMinIter == 0 || aMinIter >= sizeof(aMinorStr))
939   {
940     return;
941   }
942   memcpy (aMinorStr, aVerStr, aMinIter);
943   aMinorStr[aMinIter] = '\0';
944
945   // read numbers
946   theGlVerMajor = atoi (aMajorStr);
947   theGlVerMinor = atoi (aMinorStr);
948
949   if (theGlVerMajor <= 0)
950   {
951     theGlVerMajor = 0;
952     theGlVerMinor = 0;
953   }
954 }
955
956 static Standard_CString THE_DBGMSG_UNKNOWN = "UNKNOWN";
957 static Standard_CString THE_DBGMSG_SOURCES[] =
958 {
959   ".OpenGL",    // GL_DEBUG_SOURCE_API
960   ".WinSystem", // GL_DEBUG_SOURCE_WINDOW_SYSTEM
961   ".GLSL",      // GL_DEBUG_SOURCE_SHADER_COMPILER
962   ".3rdParty",  // GL_DEBUG_SOURCE_THIRD_PARTY
963   "",           // GL_DEBUG_SOURCE_APPLICATION
964   ".Other"      // GL_DEBUG_SOURCE_OTHER
965 };
966
967 static Standard_CString THE_DBGMSG_TYPES[] =
968 {
969   "Error",           // GL_DEBUG_TYPE_ERROR
970   "Deprecated",      // GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR
971   "Undef. behavior", // GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR
972   "Portability",     // GL_DEBUG_TYPE_PORTABILITY
973   "Performance",     // GL_DEBUG_TYPE_PERFORMANCE
974   "Other"            // GL_DEBUG_TYPE_OTHER
975 };
976
977 static Standard_CString THE_DBGMSG_SEV_HIGH   = "High";   // GL_DEBUG_SEVERITY_HIGH
978 static Standard_CString THE_DBGMSG_SEV_MEDIUM = "Medium"; // GL_DEBUG_SEVERITY_MEDIUM
979 static Standard_CString THE_DBGMSG_SEV_LOW    = "Low";    // GL_DEBUG_SEVERITY_LOW
980
981 //! Callback for GL_ARB_debug_output extension
982 static void APIENTRY debugCallbackWrap(unsigned int theSource,
983                                        unsigned int theType,
984                                        unsigned int theId,
985                                        unsigned int theSeverity,
986                                        int          /*theLength*/,
987                                        const char*  theMessage,
988                                        const void*  theUserParam)
989 {
990   OpenGl_Context* aCtx = (OpenGl_Context* )theUserParam;
991   aCtx->PushMessage (theSource, theType, theId, theSeverity, theMessage);
992 }
993
994 // =======================================================================
995 // function : PushMessage
996 // purpose  :
997 // =======================================================================
998 void OpenGl_Context::PushMessage (const unsigned int theSource,
999                                   const unsigned int theType,
1000                                   const unsigned int theId,
1001                                   const unsigned int theSeverity,
1002                                   const TCollection_ExtendedString& theMessage)
1003 {
1004   if (caps->suppressExtraMsg
1005    && theSource >= GL_DEBUG_SOURCE_API
1006    && theSource <= GL_DEBUG_SOURCE_OTHER
1007    && myFilters[theSource - GL_DEBUG_SOURCE_API].Contains (theId))
1008   {
1009     return;
1010   }
1011
1012   Standard_CString& aSrc = (theSource >= GL_DEBUG_SOURCE_API
1013                         && theSource <= GL_DEBUG_SOURCE_OTHER)
1014                          ? THE_DBGMSG_SOURCES[theSource - GL_DEBUG_SOURCE_API]
1015                          : THE_DBGMSG_UNKNOWN;
1016   Standard_CString& aType = (theType >= GL_DEBUG_TYPE_ERROR
1017                          && theType <= GL_DEBUG_TYPE_OTHER)
1018                           ? THE_DBGMSG_TYPES[theType - GL_DEBUG_TYPE_ERROR]
1019                           : THE_DBGMSG_UNKNOWN;
1020   Standard_CString& aSev = theSeverity == GL_DEBUG_SEVERITY_HIGH
1021                          ? THE_DBGMSG_SEV_HIGH
1022                          : (theSeverity == GL_DEBUG_SEVERITY_MEDIUM
1023                           ? THE_DBGMSG_SEV_MEDIUM
1024                           : THE_DBGMSG_SEV_LOW);
1025   Message_Gravity aGrav = theSeverity == GL_DEBUG_SEVERITY_HIGH
1026                         ? Message_Alarm
1027                         : (theSeverity == GL_DEBUG_SEVERITY_MEDIUM
1028                          ? Message_Warning
1029                          : Message_Info);
1030
1031   TCollection_ExtendedString aMsg;
1032   aMsg += "TKOpenGl"; aMsg += aSrc;
1033   aMsg += " | Type: ";        aMsg += aType;
1034   aMsg += " | ID: ";          aMsg += (Standard_Integer )theId;
1035   aMsg += " | Severity: ";    aMsg += aSev;
1036   aMsg += " | Message:\n  ";
1037   aMsg += theMessage;
1038   Messenger()->Send (aMsg, aGrav);
1039 }
1040
1041 // =======================================================================
1042 // function : ExcludeMessage
1043 // purpose  :
1044 // ======================================================================
1045 Standard_Boolean OpenGl_Context::ExcludeMessage (const unsigned int theSource,
1046                                                  const unsigned int theId)
1047 {
1048   return theSource >= GL_DEBUG_SOURCE_API
1049       && theSource <= GL_DEBUG_SOURCE_OTHER
1050       && myFilters[theSource - GL_DEBUG_SOURCE_API].Add (theId);
1051 }
1052
1053 // =======================================================================
1054 // function : IncludeMessage
1055 // purpose  :
1056 // ======================================================================
1057 Standard_Boolean OpenGl_Context::IncludeMessage (const unsigned int theSource,
1058                                                  const unsigned int theId)
1059 {
1060   return theSource >= GL_DEBUG_SOURCE_API
1061       && theSource <= GL_DEBUG_SOURCE_OTHER
1062       && myFilters[theSource - GL_DEBUG_SOURCE_API].Remove (theId);
1063 }
1064
1065 // =======================================================================
1066 // function : checkWrongVersion
1067 // purpose  :
1068 // ======================================================================
1069 void OpenGl_Context::checkWrongVersion (const Standard_Integer theGlVerMajor,
1070                                         const Standard_Integer theGlVerMinor)
1071 {
1072   if (!IsGlGreaterEqual (theGlVerMajor, theGlVerMinor))
1073   {
1074     return;
1075   }
1076
1077   TCollection_ExtendedString aMsg = TCollection_ExtendedString()
1078     + "Error! OpenGL context reports version "
1079     + myGlVerMajor  + "." + myGlVerMinor
1080     + " but does not export required functions for "
1081     + theGlVerMajor + "." + theGlVerMinor;
1082   PushMessage (GL_DEBUG_SOURCE_APPLICATION,
1083                GL_DEBUG_TYPE_ERROR,
1084                0,
1085                GL_DEBUG_SEVERITY_HIGH,
1086                aMsg);
1087 }
1088
1089 // =======================================================================
1090 // function : init
1091 // purpose  :
1092 // =======================================================================
1093 void OpenGl_Context::init (const Standard_Boolean theIsCoreProfile)
1094 {
1095   // read version
1096   myGlVerMajor = 0;
1097   myGlVerMinor = 0;
1098   myMaxMsaaSamples = 0;
1099   ReadGlVersion (myGlVerMajor, myGlVerMinor);
1100   myVendor = (const char* )::glGetString (GL_VENDOR);
1101   if (!caps->ffpEnable
1102    && !IsGlGreaterEqual (2, 0))
1103   {
1104     caps->ffpEnable = true;
1105     TCollection_ExtendedString aMsg =
1106       TCollection_ExtendedString("OpenGL driver is too old! Context info:\n")
1107                                + "    Vendor:   " + (const char* )::glGetString (GL_VENDOR)   + "\n"
1108                                + "    Renderer: " + (const char* )::glGetString (GL_RENDERER) + "\n"
1109                                + "    Version:  " + (const char* )::glGetString (GL_VERSION)  + "\n"
1110                                + "  Fallback using deprecated fixed-function pipeline.\n"
1111                                + "  Visualization might work incorrectly.\n"
1112                                  "  Consider upgrading the graphics driver.";
1113     PushMessage (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_PORTABILITY, 0, GL_DEBUG_SEVERITY_HIGH, aMsg);
1114   }
1115
1116 #if defined(GL_ES_VERSION_2_0)
1117   (void )theIsCoreProfile;
1118   const bool isCoreProfile = false;
1119 #else
1120
1121   if (myVendor.Search ("NVIDIA") != -1)
1122   {
1123     // Buffer detailed info: Buffer object 1 (bound to GL_ARRAY_BUFFER_ARB, usage hint is GL_STATIC_DRAW)
1124     // will use VIDEO memory as the source for buffer object operations.
1125     ExcludeMessage (GL_DEBUG_SOURCE_API, 131185);
1126   }
1127   if (IsGlGreaterEqual (3, 0))
1128   {
1129     // retrieve auxiliary function in advance
1130     FindProc ("glGetStringi", myFuncs->glGetStringi);
1131   }
1132
1133   bool isCoreProfile = false;
1134   if (IsGlGreaterEqual (3, 2))
1135   {
1136     isCoreProfile = (theIsCoreProfile == Standard_True);
1137
1138     // detect Core profile
1139     if (!isCoreProfile)
1140     {
1141       GLint aProfile = 0;
1142       ::glGetIntegerv (GL_CONTEXT_PROFILE_MASK, &aProfile);
1143       isCoreProfile = (aProfile & GL_CONTEXT_CORE_PROFILE_BIT) != 0;
1144     }
1145   }
1146 #endif
1147
1148   core11     = NULL;
1149   if (!isCoreProfile)
1150   {
1151     core11 = (OpenGl_GlCore11* )(&(*myFuncs));
1152   }
1153   core11fwd  = (OpenGl_GlCore11Fwd* )(&(*myFuncs));
1154   core15     = NULL;
1155   core15fwd  = NULL;
1156   core20     = NULL;
1157   core20fwd  = NULL;
1158   core32     = NULL;
1159   core32back = NULL;
1160   core33     = NULL;
1161   core33back = NULL;
1162   core41     = NULL;
1163   core41back = NULL;
1164   core42     = NULL;
1165   core42back = NULL;
1166   core43     = NULL;
1167   core43back = NULL;
1168   core44     = NULL;
1169   core44back = NULL;
1170   arbTBO     = NULL;
1171   arbTboRGB32 = Standard_False;
1172   arbIns     = NULL;
1173   arbDbg     = NULL;
1174   arbFBO     = NULL;
1175   arbFBOBlit = NULL;
1176   extGS      = NULL;
1177   myDefaultVao = 0;
1178
1179 #if defined(GL_ES_VERSION_2_0)
1180
1181   hasTexRGBA8 = IsGlGreaterEqual (3, 0)
1182              || CheckExtension ("GL_OES_rgb8_rgba8");
1183   // NPOT textures has limited support within OpenGL ES 2.0
1184   // which are relaxed by OpenGL ES 3.0 or some extensions
1185   //arbNPTW     = IsGlGreaterEqual (3, 0)
1186   //           || CheckExtension ("GL_OES_texture_npot")
1187   //           || CheckExtension ("GL_NV_texture_npot_2D_mipmap");
1188   arbNPTW     = Standard_True;
1189   arbTexRG    = IsGlGreaterEqual (3, 0)
1190              || CheckExtension ("GL_EXT_texture_rg");
1191   extBgra     = CheckExtension ("GL_EXT_texture_format_BGRA8888");
1192   extAnis = CheckExtension ("GL_EXT_texture_filter_anisotropic");
1193   extPDS  = CheckExtension ("GL_OES_packed_depth_stencil");
1194
1195   core11fwd = (OpenGl_GlCore11Fwd* )(&(*myFuncs));
1196   if (IsGlGreaterEqual (2, 0))
1197   {
1198     // enable compatible functions
1199     core20    = (OpenGl_GlCore20*    )(&(*myFuncs));
1200     core20fwd = (OpenGl_GlCore20Fwd* )(&(*myFuncs));
1201     core15fwd = (OpenGl_GlCore15Fwd* )(&(*myFuncs));
1202     arbFBO    = (OpenGl_ArbFBO*      )(&(*myFuncs));
1203   }
1204   if (IsGlGreaterEqual (3, 0)
1205    && FindProc ("glBlitFramebuffer", myFuncs->glBlitFramebuffer))
1206   {
1207     arbFBOBlit = (OpenGl_ArbFBOBlit* )(&(*myFuncs));
1208   }
1209   extFragDepth = !IsGlGreaterEqual(3, 0)
1210                && CheckExtension ("GL_EXT_frag_depth");
1211   if (IsGlGreaterEqual (3, 1)
1212    && FindProc ("glTexStorage2DMultisample", myFuncs->glTexStorage2DMultisample))
1213   {
1214     // MSAA RenderBuffers have been defined in OpenGL ES 3.0,
1215     // but MSAA Textures - only in OpenGL ES 3.1+
1216     ::glGetIntegerv (GL_MAX_SAMPLES, &myMaxMsaaSamples);
1217   }
1218
1219   hasUintIndex = IsGlGreaterEqual (3, 0)
1220               || CheckExtension ("GL_OES_element_index_uint");
1221   hasHighp     = CheckExtension ("GL_OES_fragment_precision_high");
1222   GLint aRange[2] = {0, 0};
1223   GLint aPrec     = 0;
1224   ::glGetShaderPrecisionFormat (GL_FRAGMENT_SHADER, GL_HIGH_FLOAT, aRange, &aPrec);
1225   if (aPrec != 0)
1226   {
1227     hasHighp = Standard_True;
1228   }
1229
1230   arbTexFloat = IsGlGreaterEqual (3, 0)
1231              && FindProc ("glTexImage3D", myFuncs->glTexImage3D);
1232
1233   const Standard_Boolean hasTexBuffer32  = IsGlGreaterEqual (3, 2) && FindProc ("glTexBuffer", myFuncs->glTexBuffer);
1234   const Standard_Boolean hasExtTexBuffer = CheckExtension ("GL_EXT_texture_buffer") && FindProc ("glTexBufferEXT", myFuncs->glTexBuffer);
1235
1236   if (hasTexBuffer32 || hasExtTexBuffer)
1237   {
1238     arbTBO = reinterpret_cast<OpenGl_ArbTBO*> (myFuncs.get());
1239   }
1240
1241   // initialize debug context extension
1242   if (CheckExtension ("GL_KHR_debug"))
1243   {
1244     // this functionality become a part of OpenGL ES 3.2
1245     arbDbg = NULL;
1246     // According to GL_KHR_debug spec, all functions should have KHR suffix.
1247     // However, some implementations can export these functions without suffix.
1248     if (FindProc ("glDebugMessageControlKHR",  myFuncs->glDebugMessageControl)
1249      && FindProc ("glDebugMessageInsertKHR",   myFuncs->glDebugMessageInsert)
1250      && FindProc ("glDebugMessageCallbackKHR", myFuncs->glDebugMessageCallback)
1251      && FindProc ("glGetDebugMessageLogKHR",   myFuncs->glGetDebugMessageLog))
1252     {
1253       arbDbg = (OpenGl_ArbDbg* )(&(*myFuncs));
1254     }
1255
1256     if (arbDbg != NULL
1257      && caps->contextDebug)
1258     {
1259       // setup default callback
1260       myIsGlDebugCtx = Standard_True;
1261       arbDbg->glDebugMessageCallback (debugCallbackWrap, this);
1262       ::glEnable (GL_DEBUG_OUTPUT);
1263       if (caps->contextSyncDebug)
1264       {
1265         // note that some broken implementations (e.g. simulators) might generate error message on this call
1266         ::glEnable (GL_DEBUG_OUTPUT_SYNCHRONOUS);
1267       }
1268     }
1269   }
1270
1271 #else
1272
1273   myTexClamp = IsGlGreaterEqual (1, 2) ? GL_CLAMP_TO_EDGE : GL_CLAMP;
1274
1275   hasTexRGBA8 = Standard_True;
1276   arbNPTW     = CheckExtension ("GL_ARB_texture_non_power_of_two");
1277   arbTexFloat = IsGlGreaterEqual (3, 0)
1278              || CheckExtension ("GL_ARB_texture_float");
1279   extBgra     = CheckExtension ("GL_EXT_bgra");
1280   extAnis     = CheckExtension ("GL_EXT_texture_filter_anisotropic");
1281   extPDS      = CheckExtension ("GL_EXT_packed_depth_stencil");
1282   atiMem      = CheckExtension ("GL_ATI_meminfo");
1283   nvxMem      = CheckExtension ("GL_NVX_gpu_memory_info");
1284
1285   GLint aStereo = GL_FALSE;
1286   glGetIntegerv (GL_STEREO, &aStereo);
1287   myIsStereoBuffers = aStereo == 1;
1288
1289   // get number of maximum clipping planes
1290   glGetIntegerv (GL_MAX_CLIP_PLANES,  &myMaxClipPlanes);
1291 #endif
1292
1293   glGetIntegerv (GL_MAX_TEXTURE_SIZE, &myMaxTexDim);
1294
1295   if (extAnis)
1296   {
1297     glGetIntegerv (GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &myAnisoMax);
1298   }
1299
1300   myClippingState.Init (myMaxClipPlanes);
1301
1302 #if !defined(GL_ES_VERSION_2_0)
1303
1304   bool has12 = false;
1305   bool has13 = false;
1306   bool has14 = false;
1307   bool has15 = false;
1308   bool has20 = false;
1309   bool has21 = false;
1310   bool has30 = false;
1311   bool has31 = false;
1312   bool has32 = false;
1313   bool has33 = false;
1314   bool has40 = false;
1315   bool has41 = false;
1316   bool has42 = false;
1317   bool has43 = false;
1318   bool has44 = false;
1319
1320   //! Make record shorter to retrieve function pointer using variable with same name
1321   #define FindProcShort(theFunc) FindProc(#theFunc, myFuncs->theFunc)
1322
1323   // retrieve platform-dependent extensions
1324 #if defined(HAVE_EGL)
1325   //
1326 #elif defined(_WIN32)
1327   if (FindProcShort (wglGetExtensionsStringARB))
1328   {
1329     const char* aWglExts = myFuncs->wglGetExtensionsStringARB (wglGetCurrentDC());
1330     if (CheckExtension (aWglExts, "WGL_EXT_swap_control"))
1331     {
1332       FindProcShort (wglSwapIntervalEXT);
1333     }
1334     if (CheckExtension (aWglExts, "WGL_ARB_pixel_format"))
1335     {
1336       FindProcShort (wglChoosePixelFormatARB);
1337     }
1338     if (CheckExtension (aWglExts, "WGL_ARB_create_context_profile"))
1339     {
1340       FindProcShort (wglCreateContextAttribsARB);
1341     }
1342     if (CheckExtension (aWglExts, "WGL_NV_DX_interop"))
1343     {
1344       FindProcShort (wglDXSetResourceShareHandleNV);
1345       FindProcShort (wglDXOpenDeviceNV);
1346       FindProcShort (wglDXCloseDeviceNV);
1347       FindProcShort (wglDXRegisterObjectNV);
1348       FindProcShort (wglDXUnregisterObjectNV);
1349       FindProcShort (wglDXObjectAccessNV);
1350       FindProcShort (wglDXLockObjectsNV);
1351       FindProcShort (wglDXUnlockObjectsNV);
1352     }
1353   }
1354 #elif defined(__APPLE__)
1355     //
1356 #else
1357     const char* aGlxExts = ::glXQueryExtensionsString ((Display* )myDisplay, DefaultScreen ((Display* )myDisplay));
1358     if (CheckExtension (aGlxExts, "GLX_EXT_swap_control"))
1359     {
1360       FindProcShort (glXSwapIntervalEXT);
1361     }
1362     if (CheckExtension (aGlxExts, "GLX_SGI_swap_control"))
1363     {
1364       FindProcShort (glXSwapIntervalSGI);
1365     }
1366     if (CheckExtension (aGlxExts, "GLX_MESA_query_renderer"))
1367     {
1368       FindProcShort (glXQueryRendererIntegerMESA);
1369       FindProcShort (glXQueryCurrentRendererIntegerMESA);
1370       FindProcShort (glXQueryRendererStringMESA);
1371       FindProcShort (glXQueryCurrentRendererStringMESA);
1372     }
1373     //extSwapTear = CheckExtension (aGlxExts, "GLX_EXT_swap_control_tear");
1374 #endif
1375
1376   // load OpenGL 1.2 new functions
1377   has12 = IsGlGreaterEqual (1, 2)
1378        && FindProcShort (glBlendColor)
1379        && FindProcShort (glBlendEquation)
1380        && FindProcShort (glDrawRangeElements)
1381        && FindProcShort (glTexImage3D)
1382        && FindProcShort (glTexSubImage3D)
1383        && FindProcShort (glCopyTexSubImage3D);
1384
1385   // load OpenGL 1.3 new functions
1386   has13 = IsGlGreaterEqual (1, 3)
1387        && FindProcShort (glActiveTexture)
1388        && FindProcShort (glSampleCoverage)
1389        && FindProcShort (glCompressedTexImage3D)
1390        && FindProcShort (glCompressedTexImage2D)
1391        && FindProcShort (glCompressedTexImage1D)
1392        && FindProcShort (glCompressedTexSubImage3D)
1393        && FindProcShort (glCompressedTexSubImage2D)
1394        && FindProcShort (glCompressedTexSubImage1D)
1395        && FindProcShort (glGetCompressedTexImage);
1396
1397   if (!isCoreProfile)
1398   {
1399     has13 = has13
1400        && FindProcShort (glClientActiveTexture)
1401        && FindProcShort (glMultiTexCoord1d)
1402        && FindProcShort (glMultiTexCoord1dv)
1403        && FindProcShort (glMultiTexCoord1f)
1404        && FindProcShort (glMultiTexCoord1fv)
1405        && FindProcShort (glMultiTexCoord1i)
1406        && FindProcShort (glMultiTexCoord1iv)
1407        && FindProcShort (glMultiTexCoord1s)
1408        && FindProcShort (glMultiTexCoord1sv)
1409        && FindProcShort (glMultiTexCoord2d)
1410        && FindProcShort (glMultiTexCoord2dv)
1411        && FindProcShort (glMultiTexCoord2f)
1412        && FindProcShort (glMultiTexCoord2fv)
1413        && FindProcShort (glMultiTexCoord2i)
1414        && FindProcShort (glMultiTexCoord2iv)
1415        && FindProcShort (glMultiTexCoord2s)
1416        && FindProcShort (glMultiTexCoord2sv)
1417        && FindProcShort (glMultiTexCoord3d)
1418        && FindProcShort (glMultiTexCoord3dv)
1419        && FindProcShort (glMultiTexCoord3f)
1420        && FindProcShort (glMultiTexCoord3fv)
1421        && FindProcShort (glMultiTexCoord3i)
1422        && FindProcShort (glMultiTexCoord3iv)
1423        && FindProcShort (glMultiTexCoord3s)
1424        && FindProcShort (glMultiTexCoord3sv)
1425        && FindProcShort (glMultiTexCoord4d)
1426        && FindProcShort (glMultiTexCoord4dv)
1427        && FindProcShort (glMultiTexCoord4f)
1428        && FindProcShort (glMultiTexCoord4fv)
1429        && FindProcShort (glMultiTexCoord4i)
1430        && FindProcShort (glMultiTexCoord4iv)
1431        && FindProcShort (glMultiTexCoord4s)
1432        && FindProcShort (glMultiTexCoord4sv)
1433        && FindProcShort (glLoadTransposeMatrixf)
1434        && FindProcShort (glLoadTransposeMatrixd)
1435        && FindProcShort (glMultTransposeMatrixf)
1436        && FindProcShort (glMultTransposeMatrixd);
1437   }
1438
1439   // load OpenGL 1.4 new functions
1440   has14 = IsGlGreaterEqual (1, 4)
1441        && FindProcShort (glBlendFuncSeparate)
1442        && FindProcShort (glMultiDrawArrays)
1443        && FindProcShort (glMultiDrawElements)
1444        && FindProcShort (glPointParameterf)
1445        && FindProcShort (glPointParameterfv)
1446        && FindProcShort (glPointParameteri)
1447        && FindProcShort (glPointParameteriv);
1448
1449   // load OpenGL 1.5 new functions
1450   has15 = IsGlGreaterEqual (1, 5)
1451        && FindProcShort (glGenQueries)
1452        && FindProcShort (glDeleteQueries)
1453        && FindProcShort (glIsQuery)
1454        && FindProcShort (glBeginQuery)
1455        && FindProcShort (glEndQuery)
1456        && FindProcShort (glGetQueryiv)
1457        && FindProcShort (glGetQueryObjectiv)
1458        && FindProcShort (glGetQueryObjectuiv)
1459        && FindProcShort (glBindBuffer)
1460        && FindProcShort (glDeleteBuffers)
1461        && FindProcShort (glGenBuffers)
1462        && FindProcShort (glIsBuffer)
1463        && FindProcShort (glBufferData)
1464        && FindProcShort (glBufferSubData)
1465        && FindProcShort (glGetBufferSubData)
1466        && FindProcShort (glMapBuffer)
1467        && FindProcShort (glUnmapBuffer)
1468        && FindProcShort (glGetBufferParameteriv)
1469        && FindProcShort (glGetBufferPointerv);
1470
1471   // load OpenGL 2.0 new functions
1472   has20 = IsGlGreaterEqual (2, 0)
1473        && FindProcShort (glBlendEquationSeparate)
1474        && FindProcShort (glDrawBuffers)
1475        && FindProcShort (glStencilOpSeparate)
1476        && FindProcShort (glStencilFuncSeparate)
1477        && FindProcShort (glStencilMaskSeparate)
1478        && FindProcShort (glAttachShader)
1479        && FindProcShort (glBindAttribLocation)
1480        && FindProcShort (glCompileShader)
1481        && FindProcShort (glCreateProgram)
1482        && FindProcShort (glCreateShader)
1483        && FindProcShort (glDeleteProgram)
1484        && FindProcShort (glDeleteShader)
1485        && FindProcShort (glDetachShader)
1486        && FindProcShort (glDisableVertexAttribArray)
1487        && FindProcShort (glEnableVertexAttribArray)
1488        && FindProcShort (glGetActiveAttrib)
1489        && FindProcShort (glGetActiveUniform)
1490        && FindProcShort (glGetAttachedShaders)
1491        && FindProcShort (glGetAttribLocation)
1492        && FindProcShort (glGetProgramiv)
1493        && FindProcShort (glGetProgramInfoLog)
1494        && FindProcShort (glGetShaderiv)
1495        && FindProcShort (glGetShaderInfoLog)
1496        && FindProcShort (glGetShaderSource)
1497        && FindProcShort (glGetUniformLocation)
1498        && FindProcShort (glGetUniformfv)
1499        && FindProcShort (glGetUniformiv)
1500        && FindProcShort (glGetVertexAttribdv)
1501        && FindProcShort (glGetVertexAttribfv)
1502        && FindProcShort (glGetVertexAttribiv)
1503        && FindProcShort (glGetVertexAttribPointerv)
1504        && FindProcShort (glIsProgram)
1505        && FindProcShort (glIsShader)
1506        && FindProcShort (glLinkProgram)
1507        && FindProcShort (glShaderSource)
1508        && FindProcShort (glUseProgram)
1509        && FindProcShort (glUniform1f)
1510        && FindProcShort (glUniform2f)
1511        && FindProcShort (glUniform3f)
1512        && FindProcShort (glUniform4f)
1513        && FindProcShort (glUniform1i)
1514        && FindProcShort (glUniform2i)
1515        && FindProcShort (glUniform3i)
1516        && FindProcShort (glUniform4i)
1517        && FindProcShort (glUniform1fv)
1518        && FindProcShort (glUniform2fv)
1519        && FindProcShort (glUniform3fv)
1520        && FindProcShort (glUniform4fv)
1521        && FindProcShort (glUniform1iv)
1522        && FindProcShort (glUniform2iv)
1523        && FindProcShort (glUniform3iv)
1524        && FindProcShort (glUniform4iv)
1525        && FindProcShort (glUniformMatrix2fv)
1526        && FindProcShort (glUniformMatrix3fv)
1527        && FindProcShort (glUniformMatrix4fv)
1528        && FindProcShort (glValidateProgram)
1529        && FindProcShort (glVertexAttrib1d)
1530        && FindProcShort (glVertexAttrib1dv)
1531        && FindProcShort (glVertexAttrib1f)
1532        && FindProcShort (glVertexAttrib1fv)
1533        && FindProcShort (glVertexAttrib1s)
1534        && FindProcShort (glVertexAttrib1sv)
1535        && FindProcShort (glVertexAttrib2d)
1536        && FindProcShort (glVertexAttrib2dv)
1537        && FindProcShort (glVertexAttrib2f)
1538        && FindProcShort (glVertexAttrib2fv)
1539        && FindProcShort (glVertexAttrib2s)
1540        && FindProcShort (glVertexAttrib2sv)
1541        && FindProcShort (glVertexAttrib3d)
1542        && FindProcShort (glVertexAttrib3dv)
1543        && FindProcShort (glVertexAttrib3f)
1544        && FindProcShort (glVertexAttrib3fv)
1545        && FindProcShort (glVertexAttrib3s)
1546        && FindProcShort (glVertexAttrib3sv)
1547        && FindProcShort (glVertexAttrib4Nbv)
1548        && FindProcShort (glVertexAttrib4Niv)
1549        && FindProcShort (glVertexAttrib4Nsv)
1550        && FindProcShort (glVertexAttrib4Nub)
1551        && FindProcShort (glVertexAttrib4Nubv)
1552        && FindProcShort (glVertexAttrib4Nuiv)
1553        && FindProcShort (glVertexAttrib4Nusv)
1554        && FindProcShort (glVertexAttrib4bv)
1555        && FindProcShort (glVertexAttrib4d)
1556        && FindProcShort (glVertexAttrib4dv)
1557        && FindProcShort (glVertexAttrib4f)
1558        && FindProcShort (glVertexAttrib4fv)
1559        && FindProcShort (glVertexAttrib4iv)
1560        && FindProcShort (glVertexAttrib4s)
1561        && FindProcShort (glVertexAttrib4sv)
1562        && FindProcShort (glVertexAttrib4ubv)
1563        && FindProcShort (glVertexAttrib4uiv)
1564        && FindProcShort (glVertexAttrib4usv)
1565        && FindProcShort (glVertexAttribPointer);
1566
1567   // load OpenGL 2.1 new functions
1568   has21 = IsGlGreaterEqual (2, 1)
1569        && FindProcShort (glUniformMatrix2x3fv)
1570        && FindProcShort (glUniformMatrix3x2fv)
1571        && FindProcShort (glUniformMatrix2x4fv)
1572        && FindProcShort (glUniformMatrix4x2fv)
1573        && FindProcShort (glUniformMatrix3x4fv)
1574        && FindProcShort (glUniformMatrix4x3fv);
1575
1576   // load GL_ARB_framebuffer_object (added to OpenGL 3.0 core)
1577   const bool hasFBO = (IsGlGreaterEqual (3, 0) || CheckExtension ("GL_ARB_framebuffer_object"))
1578        && FindProcShort (glIsRenderbuffer)
1579        && FindProcShort (glBindRenderbuffer)
1580        && FindProcShort (glDeleteRenderbuffers)
1581        && FindProcShort (glGenRenderbuffers)
1582        && FindProcShort (glRenderbufferStorage)
1583        && FindProcShort (glGetRenderbufferParameteriv)
1584        && FindProcShort (glIsFramebuffer)
1585        && FindProcShort (glBindFramebuffer)
1586        && FindProcShort (glDeleteFramebuffers)
1587        && FindProcShort (glGenFramebuffers)
1588        && FindProcShort (glCheckFramebufferStatus)
1589        && FindProcShort (glFramebufferTexture1D)
1590        && FindProcShort (glFramebufferTexture2D)
1591        && FindProcShort (glFramebufferTexture3D)
1592        && FindProcShort (glFramebufferRenderbuffer)
1593        && FindProcShort (glGetFramebufferAttachmentParameteriv)
1594        && FindProcShort (glGenerateMipmap)
1595        && FindProcShort (glBlitFramebuffer)
1596        && FindProcShort (glRenderbufferStorageMultisample)
1597        && FindProcShort (glFramebufferTextureLayer);
1598
1599   // load GL_ARB_vertex_array_object (added to OpenGL 3.0 core)
1600   const bool hasVAO = (IsGlGreaterEqual (3, 0) || CheckExtension ("GL_ARB_vertex_array_object"))
1601        && FindProcShort (glBindVertexArray)
1602        && FindProcShort (glDeleteVertexArrays)
1603        && FindProcShort (glGenVertexArrays)
1604        && FindProcShort (glIsVertexArray);
1605
1606   // load GL_ARB_map_buffer_range (added to OpenGL 3.0 core)
1607   const bool hasMapBufferRange = (IsGlGreaterEqual (3, 0) || CheckExtension ("GL_ARB_map_buffer_range"))
1608        && FindProcShort (glMapBufferRange)
1609        && FindProcShort (glFlushMappedBufferRange);
1610
1611   // load OpenGL 3.0 new functions
1612   has30 = IsGlGreaterEqual (3, 0)
1613        && hasFBO
1614        && hasVAO
1615        && hasMapBufferRange
1616        && FindProcShort (glColorMaski)
1617        && FindProcShort (glGetBooleani_v)
1618        && FindProcShort (glGetIntegeri_v)
1619        && FindProcShort (glEnablei)
1620        && FindProcShort (glDisablei)
1621        && FindProcShort (glIsEnabledi)
1622        && FindProcShort (glBeginTransformFeedback)
1623        && FindProcShort (glEndTransformFeedback)
1624        && FindProcShort (glBindBufferRange)
1625        && FindProcShort (glBindBufferBase)
1626        && FindProcShort (glTransformFeedbackVaryings)
1627        && FindProcShort (glGetTransformFeedbackVarying)
1628        && FindProcShort (glClampColor)
1629        && FindProcShort (glBeginConditionalRender)
1630        && FindProcShort (glEndConditionalRender)
1631        && FindProcShort (glVertexAttribIPointer)
1632        && FindProcShort (glGetVertexAttribIiv)
1633        && FindProcShort (glGetVertexAttribIuiv)
1634        && FindProcShort (glVertexAttribI1i)
1635        && FindProcShort (glVertexAttribI2i)
1636        && FindProcShort (glVertexAttribI3i)
1637        && FindProcShort (glVertexAttribI4i)
1638        && FindProcShort (glVertexAttribI1ui)
1639        && FindProcShort (glVertexAttribI2ui)
1640        && FindProcShort (glVertexAttribI3ui)
1641        && FindProcShort (glVertexAttribI4ui)
1642        && FindProcShort (glVertexAttribI1iv)
1643        && FindProcShort (glVertexAttribI2iv)
1644        && FindProcShort (glVertexAttribI3iv)
1645        && FindProcShort (glVertexAttribI4iv)
1646        && FindProcShort (glVertexAttribI1uiv)
1647        && FindProcShort (glVertexAttribI2uiv)
1648        && FindProcShort (glVertexAttribI3uiv)
1649        && FindProcShort (glVertexAttribI4uiv)
1650        && FindProcShort (glVertexAttribI4bv)
1651        && FindProcShort (glVertexAttribI4sv)
1652        && FindProcShort (glVertexAttribI4ubv)
1653        && FindProcShort (glVertexAttribI4usv)
1654        && FindProcShort (glGetUniformuiv)
1655        && FindProcShort (glBindFragDataLocation)
1656        && FindProcShort (glGetFragDataLocation)
1657        && FindProcShort (glUniform1ui)
1658        && FindProcShort (glUniform2ui)
1659        && FindProcShort (glUniform3ui)
1660        && FindProcShort (glUniform4ui)
1661        && FindProcShort (glUniform1uiv)
1662        && FindProcShort (glUniform2uiv)
1663        && FindProcShort (glUniform3uiv)
1664        && FindProcShort (glUniform4uiv)
1665        && FindProcShort (glTexParameterIiv)
1666        && FindProcShort (glTexParameterIuiv)
1667        && FindProcShort (glGetTexParameterIiv)
1668        && FindProcShort (glGetTexParameterIuiv)
1669        && FindProcShort (glClearBufferiv)
1670        && FindProcShort (glClearBufferuiv)
1671        && FindProcShort (glClearBufferfv)
1672        && FindProcShort (glClearBufferfi)
1673        && FindProcShort (glGetStringi);
1674
1675   // load GL_ARB_uniform_buffer_object (added to OpenGL 3.1 core)
1676   const bool hasUBO = (IsGlGreaterEqual (3, 1) || CheckExtension ("GL_ARB_uniform_buffer_object"))
1677        && FindProcShort (glGetUniformIndices)
1678        && FindProcShort (glGetActiveUniformsiv)
1679        && FindProcShort (glGetActiveUniformName)
1680        && FindProcShort (glGetUniformBlockIndex)
1681        && FindProcShort (glGetActiveUniformBlockiv)
1682        && FindProcShort (glGetActiveUniformBlockName)
1683        && FindProcShort (glUniformBlockBinding);
1684
1685   // load GL_ARB_copy_buffer (added to OpenGL 3.1 core)
1686   const bool hasCopyBufSubData = (IsGlGreaterEqual (3, 1) || CheckExtension ("GL_ARB_copy_buffer"))
1687        && FindProcShort (glCopyBufferSubData);
1688
1689   if (has30)
1690   {
1691     // NPOT textures are required by OpenGL 2.0 specifications
1692     // but doesn't hardware accelerated by some ancient OpenGL 2.1 hardware (GeForce FX, RadeOn 9700 etc.)
1693     arbNPTW  = Standard_True;
1694     arbTexRG = Standard_True;
1695   }
1696
1697   // load OpenGL 3.1 new functions
1698   has31 = IsGlGreaterEqual (3, 1)
1699        && hasUBO
1700        && hasCopyBufSubData
1701        && FindProcShort (glDrawArraysInstanced)
1702        && FindProcShort (glDrawElementsInstanced)
1703        && FindProcShort (glTexBuffer)
1704        && FindProcShort (glPrimitiveRestartIndex);
1705
1706   // load GL_ARB_draw_elements_base_vertex (added to OpenGL 3.2 core)
1707   const bool hasDrawElemsBaseVert = (IsGlGreaterEqual (3, 2) || CheckExtension ("GL_ARB_draw_elements_base_vertex"))
1708        && FindProcShort (glDrawElementsBaseVertex)
1709        && FindProcShort (glDrawRangeElementsBaseVertex)
1710        && FindProcShort (glDrawElementsInstancedBaseVertex)
1711        && FindProcShort (glMultiDrawElementsBaseVertex);
1712
1713   // load GL_ARB_provoking_vertex (added to OpenGL 3.2 core)
1714   const bool hasProvokingVert = (IsGlGreaterEqual (3, 2) || CheckExtension ("GL_ARB_provoking_vertex"))
1715        && FindProcShort (glProvokingVertex);
1716
1717   // load GL_ARB_sync (added to OpenGL 3.2 core)
1718   const bool hasSync = (IsGlGreaterEqual (3, 2) || CheckExtension ("GL_ARB_sync"))
1719        && FindProcShort (glFenceSync)
1720        && FindProcShort (glIsSync)
1721        && FindProcShort (glDeleteSync)
1722        && FindProcShort (glClientWaitSync)
1723        && FindProcShort (glWaitSync)
1724        && FindProcShort (glGetInteger64v)
1725        && FindProcShort (glGetSynciv);
1726
1727   // load GL_ARB_texture_multisample (added to OpenGL 3.2 core)
1728   const bool hasTextureMultisample = (IsGlGreaterEqual (3, 2) || CheckExtension ("GL_ARB_texture_multisample"))
1729        && FindProcShort (glTexImage2DMultisample)
1730        && FindProcShort (glTexImage3DMultisample)
1731        && FindProcShort (glGetMultisamplefv)
1732        && FindProcShort (glSampleMaski);
1733
1734   // load OpenGL 3.2 new functions
1735   has32 = IsGlGreaterEqual (3, 2)
1736        && hasDrawElemsBaseVert
1737        && hasProvokingVert
1738        && hasSync
1739        && hasTextureMultisample
1740        && FindProcShort (glGetInteger64i_v)
1741        && FindProcShort (glGetBufferParameteri64v)
1742        && FindProcShort (glFramebufferTexture);
1743
1744   // load GL_ARB_blend_func_extended (added to OpenGL 3.3 core)
1745   const bool hasBlendFuncExtended = (IsGlGreaterEqual (3, 3) || CheckExtension ("GL_ARB_blend_func_extended"))
1746        && FindProcShort (glBindFragDataLocationIndexed)
1747        && FindProcShort (glGetFragDataIndex);
1748
1749   // load GL_ARB_sampler_objects (added to OpenGL 3.3 core)
1750   const bool hasSamplerObjects = (IsGlGreaterEqual (3, 3) || CheckExtension ("GL_ARB_sampler_objects"))
1751        && FindProcShort (glGenSamplers)
1752        && FindProcShort (glDeleteSamplers)
1753        && FindProcShort (glIsSampler)
1754        && FindProcShort (glBindSampler)
1755        && FindProcShort (glSamplerParameteri)
1756        && FindProcShort (glSamplerParameteriv)
1757        && FindProcShort (glSamplerParameterf)
1758        && FindProcShort (glSamplerParameterfv)
1759        && FindProcShort (glSamplerParameterIiv)
1760        && FindProcShort (glSamplerParameterIuiv)
1761        && FindProcShort (glGetSamplerParameteriv)
1762        && FindProcShort (glGetSamplerParameterIiv)
1763        && FindProcShort (glGetSamplerParameterfv)
1764        && FindProcShort (glGetSamplerParameterIuiv);
1765
1766   // load GL_ARB_timer_query (added to OpenGL 3.3 core)
1767   const bool hasTimerQuery = (IsGlGreaterEqual (3, 3) || CheckExtension ("GL_ARB_timer_query"))
1768        && FindProcShort (glQueryCounter)
1769        && FindProcShort (glGetQueryObjecti64v)
1770        && FindProcShort (glGetQueryObjectui64v);
1771
1772   // load GL_ARB_vertex_type_2_10_10_10_rev (added to OpenGL 3.3 core)
1773   const bool hasVertType21010101rev = (IsGlGreaterEqual (3, 3) || CheckExtension ("GL_ARB_vertex_type_2_10_10_10_rev"))
1774        && FindProcShort (glVertexAttribP1ui)
1775        && FindProcShort (glVertexAttribP1uiv)
1776        && FindProcShort (glVertexAttribP2ui)
1777        && FindProcShort (glVertexAttribP2uiv)
1778        && FindProcShort (glVertexAttribP3ui)
1779        && FindProcShort (glVertexAttribP3uiv)
1780        && FindProcShort (glVertexAttribP4ui)
1781        && FindProcShort (glVertexAttribP4uiv);
1782
1783   if ( hasVertType21010101rev
1784    && !isCoreProfile)
1785   {
1786     // load deprecated functions
1787     const bool hasVertType21010101revExt =
1788           FindProcShort (glVertexP2ui)
1789        && FindProcShort (glVertexP2uiv)
1790        && FindProcShort (glVertexP3ui)
1791        && FindProcShort (glVertexP3uiv)
1792        && FindProcShort (glVertexP4ui)
1793        && FindProcShort (glVertexP4uiv)
1794        && FindProcShort (glTexCoordP1ui)
1795        && FindProcShort (glTexCoordP1uiv)
1796        && FindProcShort (glTexCoordP2ui)
1797        && FindProcShort (glTexCoordP2uiv)
1798        && FindProcShort (glTexCoordP3ui)
1799        && FindProcShort (glTexCoordP3uiv)
1800        && FindProcShort (glTexCoordP4ui)
1801        && FindProcShort (glTexCoordP4uiv)
1802        && FindProcShort (glMultiTexCoordP1ui)
1803        && FindProcShort (glMultiTexCoordP1uiv)
1804        && FindProcShort (glMultiTexCoordP2ui)
1805        && FindProcShort (glMultiTexCoordP2uiv)
1806        && FindProcShort (glMultiTexCoordP3ui)
1807        && FindProcShort (glMultiTexCoordP3uiv)
1808        && FindProcShort (glMultiTexCoordP4ui)
1809        && FindProcShort (glMultiTexCoordP4uiv)
1810        && FindProcShort (glNormalP3ui)
1811        && FindProcShort (glNormalP3uiv)
1812        && FindProcShort (glColorP3ui)
1813        && FindProcShort (glColorP3uiv)
1814        && FindProcShort (glColorP4ui)
1815        && FindProcShort (glColorP4uiv)
1816        && FindProcShort (glSecondaryColorP3ui)
1817        && FindProcShort (glSecondaryColorP3uiv);
1818     (void )hasVertType21010101revExt;
1819   }
1820
1821   // load OpenGL 3.3 extra functions
1822   has33 = IsGlGreaterEqual (3, 3)
1823        && hasBlendFuncExtended
1824        && hasSamplerObjects
1825        && hasTimerQuery
1826        && hasVertType21010101rev
1827        && FindProcShort (glVertexAttribDivisor);
1828
1829   // load GL_ARB_draw_indirect (added to OpenGL 4.0 core)
1830   const bool hasDrawIndirect = (IsGlGreaterEqual (4, 0) || CheckExtension ("GL_ARB_draw_indirect"))
1831        && FindProcShort (glDrawArraysIndirect)
1832        && FindProcShort (glDrawElementsIndirect);
1833
1834   // load GL_ARB_gpu_shader_fp64 (added to OpenGL 4.0 core)
1835   const bool hasShaderFP64 = (IsGlGreaterEqual (4, 0) || CheckExtension ("GL_ARB_gpu_shader_fp64"))
1836        && FindProcShort (glUniform1d)
1837        && FindProcShort (glUniform2d)
1838        && FindProcShort (glUniform3d)
1839        && FindProcShort (glUniform4d)
1840        && FindProcShort (glUniform1dv)
1841        && FindProcShort (glUniform2dv)
1842        && FindProcShort (glUniform3dv)
1843        && FindProcShort (glUniform4dv)
1844        && FindProcShort (glUniformMatrix2dv)
1845        && FindProcShort (glUniformMatrix3dv)
1846        && FindProcShort (glUniformMatrix4dv)
1847        && FindProcShort (glUniformMatrix2x3dv)
1848        && FindProcShort (glUniformMatrix2x4dv)
1849        && FindProcShort (glUniformMatrix3x2dv)
1850        && FindProcShort (glUniformMatrix3x4dv)
1851        && FindProcShort (glUniformMatrix4x2dv)
1852        && FindProcShort (glUniformMatrix4x3dv)
1853        && FindProcShort (glGetUniformdv);
1854
1855   // load GL_ARB_shader_subroutine (added to OpenGL 4.0 core)
1856   const bool hasShaderSubroutine = (IsGlGreaterEqual (4, 0) || CheckExtension ("GL_ARB_shader_subroutine"))
1857        && FindProcShort (glGetSubroutineUniformLocation)
1858        && FindProcShort (glGetSubroutineIndex)
1859        && FindProcShort (glGetActiveSubroutineUniformiv)
1860        && FindProcShort (glGetActiveSubroutineUniformName)
1861        && FindProcShort (glGetActiveSubroutineName)
1862        && FindProcShort (glUniformSubroutinesuiv)
1863        && FindProcShort (glGetUniformSubroutineuiv)
1864        && FindProcShort (glGetProgramStageiv);
1865
1866   // load GL_ARB_tessellation_shader (added to OpenGL 4.0 core)
1867   const bool hasTessellationShader = (IsGlGreaterEqual (4, 0) || CheckExtension ("GL_ARB_tessellation_shader"))
1868        && FindProcShort (glPatchParameteri)
1869        && FindProcShort (glPatchParameterfv);
1870
1871   // load GL_ARB_transform_feedback2 (added to OpenGL 4.0 core)
1872   const bool hasTrsfFeedback2 = (IsGlGreaterEqual (4, 0) || CheckExtension ("GL_ARB_transform_feedback2"))
1873        && FindProcShort (glBindTransformFeedback)
1874        && FindProcShort (glDeleteTransformFeedbacks)
1875        && FindProcShort (glGenTransformFeedbacks)
1876        && FindProcShort (glIsTransformFeedback)
1877        && FindProcShort (glPauseTransformFeedback)
1878        && FindProcShort (glResumeTransformFeedback)
1879        && FindProcShort (glDrawTransformFeedback);
1880
1881   // load GL_ARB_transform_feedback3 (added to OpenGL 4.0 core)
1882   const bool hasTrsfFeedback3 = (IsGlGreaterEqual (4, 0) || CheckExtension ("GL_ARB_transform_feedback3"))
1883        && FindProcShort (glDrawTransformFeedbackStream)
1884        && FindProcShort (glBeginQueryIndexed)
1885        && FindProcShort (glEndQueryIndexed)
1886        && FindProcShort (glGetQueryIndexediv);
1887
1888   // load OpenGL 4.0 new functions
1889   has40 = IsGlGreaterEqual (4, 0)
1890       && hasDrawIndirect
1891       && hasShaderFP64
1892       && hasShaderSubroutine
1893       && hasTessellationShader
1894       && hasTrsfFeedback2
1895       && hasTrsfFeedback3
1896       && FindProcShort (glMinSampleShading)
1897       && FindProcShort (glBlendEquationi)
1898       && FindProcShort (glBlendEquationSeparatei)
1899       && FindProcShort (glBlendFunci)
1900       && FindProcShort (glBlendFuncSeparatei);
1901
1902   // load GL_ARB_ES2_compatibility (added to OpenGL 4.1 core)
1903   const bool hasES2Compatibility = (IsGlGreaterEqual (4, 1) || CheckExtension ("GL_ARB_ES2_compatibility"))
1904        && FindProcShort (glReleaseShaderCompiler)
1905        && FindProcShort (glShaderBinary)
1906        && FindProcShort (glGetShaderPrecisionFormat)
1907        && FindProcShort (glDepthRangef)
1908        && FindProcShort (glClearDepthf);
1909
1910   // load GL_ARB_get_program_binary (added to OpenGL 4.1 core)
1911   const bool hasGetProgramBinary = (IsGlGreaterEqual (4, 1) || CheckExtension ("GL_ARB_get_program_binary"))
1912        && FindProcShort (glGetProgramBinary)
1913        && FindProcShort (glProgramBinary)
1914        && FindProcShort (glProgramParameteri);
1915
1916
1917   // load GL_ARB_separate_shader_objects (added to OpenGL 4.1 core)
1918   const bool hasSeparateShaderObjects = (IsGlGreaterEqual (4, 1) || CheckExtension ("GL_ARB_separate_shader_objects"))
1919        && FindProcShort (glUseProgramStages)
1920        && FindProcShort (glActiveShaderProgram)
1921        && FindProcShort (glCreateShaderProgramv)
1922        && FindProcShort (glBindProgramPipeline)
1923        && FindProcShort (glDeleteProgramPipelines)
1924        && FindProcShort (glGenProgramPipelines)
1925        && FindProcShort (glIsProgramPipeline)
1926        && FindProcShort (glGetProgramPipelineiv)
1927        && FindProcShort (glProgramUniform1i)
1928        && FindProcShort (glProgramUniform1iv)
1929        && FindProcShort (glProgramUniform1f)
1930        && FindProcShort (glProgramUniform1fv)
1931        && FindProcShort (glProgramUniform1d)
1932        && FindProcShort (glProgramUniform1dv)
1933        && FindProcShort (glProgramUniform1ui)
1934        && FindProcShort (glProgramUniform1uiv)
1935        && FindProcShort (glProgramUniform2i)
1936        && FindProcShort (glProgramUniform2iv)
1937        && FindProcShort (glProgramUniform2f)
1938        && FindProcShort (glProgramUniform2fv)
1939        && FindProcShort (glProgramUniform2d)
1940        && FindProcShort (glProgramUniform2dv)
1941        && FindProcShort (glProgramUniform2ui)
1942        && FindProcShort (glProgramUniform2uiv)
1943        && FindProcShort (glProgramUniform3i)
1944        && FindProcShort (glProgramUniform3iv)
1945        && FindProcShort (glProgramUniform3f)
1946        && FindProcShort (glProgramUniform3fv)
1947        && FindProcShort (glProgramUniform3d)
1948        && FindProcShort (glProgramUniform3dv)
1949        && FindProcShort (glProgramUniform3ui)
1950        && FindProcShort (glProgramUniform3uiv)
1951        && FindProcShort (glProgramUniform4i)
1952        && FindProcShort (glProgramUniform4iv)
1953        && FindProcShort (glProgramUniform4f)
1954        && FindProcShort (glProgramUniform4fv)
1955        && FindProcShort (glProgramUniform4d)
1956        && FindProcShort (glProgramUniform4dv)
1957        && FindProcShort (glProgramUniform4ui)
1958        && FindProcShort (glProgramUniform4uiv)
1959        && FindProcShort (glProgramUniformMatrix2fv)
1960        && FindProcShort (glProgramUniformMatrix3fv)
1961        && FindProcShort (glProgramUniformMatrix4fv)
1962        && FindProcShort (glProgramUniformMatrix2dv)
1963        && FindProcShort (glProgramUniformMatrix3dv)
1964        && FindProcShort (glProgramUniformMatrix4dv)
1965        && FindProcShort (glProgramUniformMatrix2x3fv)
1966        && FindProcShort (glProgramUniformMatrix3x2fv)
1967        && FindProcShort (glProgramUniformMatrix2x4fv)
1968        && FindProcShort (glProgramUniformMatrix4x2fv)
1969        && FindProcShort (glProgramUniformMatrix3x4fv)
1970        && FindProcShort (glProgramUniformMatrix4x3fv)
1971        && FindProcShort (glProgramUniformMatrix2x3dv)
1972        && FindProcShort (glProgramUniformMatrix3x2dv)
1973        && FindProcShort (glProgramUniformMatrix2x4dv)
1974        && FindProcShort (glProgramUniformMatrix4x2dv)
1975        && FindProcShort (glProgramUniformMatrix3x4dv)
1976        && FindProcShort (glProgramUniformMatrix4x3dv)
1977        && FindProcShort (glValidateProgramPipeline)
1978        && FindProcShort (glGetProgramPipelineInfoLog);
1979
1980   // load GL_ARB_vertex_attrib_64bit (added to OpenGL 4.1 core)
1981   const bool hasVertAttrib64bit = (IsGlGreaterEqual (4, 1) || CheckExtension ("GL_ARB_vertex_attrib_64bit"))
1982        && FindProcShort (glVertexAttribL1d)
1983        && FindProcShort (glVertexAttribL2d)
1984        && FindProcShort (glVertexAttribL3d)
1985        && FindProcShort (glVertexAttribL4d)
1986        && FindProcShort (glVertexAttribL1dv)
1987        && FindProcShort (glVertexAttribL2dv)
1988        && FindProcShort (glVertexAttribL3dv)
1989        && FindProcShort (glVertexAttribL4dv)
1990        && FindProcShort (glVertexAttribLPointer)
1991        && FindProcShort (glGetVertexAttribLdv);
1992
1993   // load GL_ARB_viewport_array (added to OpenGL 4.1 core)
1994   const bool hasViewportArray = (IsGlGreaterEqual (4, 1) || CheckExtension ("GL_ARB_viewport_array"))
1995        && FindProcShort (glViewportArrayv)
1996        && FindProcShort (glViewportIndexedf)
1997        && FindProcShort (glViewportIndexedfv)
1998        && FindProcShort (glScissorArrayv)
1999        && FindProcShort (glScissorIndexed)
2000        && FindProcShort (glScissorIndexedv)
2001        && FindProcShort (glDepthRangeArrayv)
2002        && FindProcShort (glDepthRangeIndexed)
2003        && FindProcShort (glGetFloati_v)
2004        && FindProcShort (glGetDoublei_v);
2005
2006   has41 = IsGlGreaterEqual (4, 1)
2007        && hasES2Compatibility
2008        && hasGetProgramBinary
2009        && hasSeparateShaderObjects
2010        && hasVertAttrib64bit
2011        && hasViewportArray;
2012
2013   // load GL_ARB_base_instance (added to OpenGL 4.2 core)
2014   const bool hasBaseInstance = (IsGlGreaterEqual (4, 2) || CheckExtension ("GL_ARB_base_instance"))
2015        && FindProcShort (glDrawArraysInstancedBaseInstance)
2016        && FindProcShort (glDrawElementsInstancedBaseInstance)
2017        && FindProcShort (glDrawElementsInstancedBaseVertexBaseInstance);
2018
2019   // load GL_ARB_transform_feedback_instanced (added to OpenGL 4.2 core)
2020   const bool hasTrsfFeedbackInstanced = (IsGlGreaterEqual (4, 2) || CheckExtension ("GL_ARB_transform_feedback_instanced"))
2021        && FindProcShort (glDrawTransformFeedbackInstanced)
2022        && FindProcShort (glDrawTransformFeedbackStreamInstanced);
2023
2024   // load GL_ARB_internalformat_query (added to OpenGL 4.2 core)
2025   const bool hasInternalFormatQuery = (IsGlGreaterEqual (4, 2) || CheckExtension ("GL_ARB_internalformat_query"))
2026        && FindProcShort (glGetInternalformativ);
2027
2028   // load GL_ARB_shader_atomic_counters (added to OpenGL 4.2 core)
2029   const bool hasShaderAtomicCounters = (IsGlGreaterEqual (4, 2) || CheckExtension ("GL_ARB_shader_atomic_counters"))
2030        && FindProcShort (glGetActiveAtomicCounterBufferiv);
2031
2032   // load GL_ARB_shader_image_load_store (added to OpenGL 4.2 core)
2033   const bool hasShaderImgLoadStore = (IsGlGreaterEqual (4, 2) || CheckExtension ("GL_ARB_shader_image_load_store"))
2034        && FindProcShort (glBindImageTexture)
2035        && FindProcShort (glMemoryBarrier);
2036
2037   // load GL_ARB_texture_storage (added to OpenGL 4.2 core)
2038   const bool hasTextureStorage = (IsGlGreaterEqual (4, 2) || CheckExtension ("GL_ARB_texture_storage"))
2039        && FindProcShort (glTexStorage1D)
2040        && FindProcShort (glTexStorage2D)
2041        && FindProcShort (glTexStorage3D);
2042
2043   has42 = IsGlGreaterEqual (4, 2)
2044        && hasBaseInstance
2045        && hasTrsfFeedbackInstanced
2046        && hasInternalFormatQuery
2047        && hasShaderAtomicCounters
2048        && hasShaderImgLoadStore
2049        && hasTextureStorage;
2050
2051   has43 = IsGlGreaterEqual (4, 3)
2052        && FindProcShort (glClearBufferData)
2053        && FindProcShort (glClearBufferSubData)
2054        && FindProcShort (glDispatchCompute)
2055        && FindProcShort (glDispatchComputeIndirect)
2056        && FindProcShort (glCopyImageSubData)
2057        && FindProcShort (glFramebufferParameteri)
2058        && FindProcShort (glGetFramebufferParameteriv)
2059        && FindProcShort (glGetInternalformati64v)
2060        && FindProcShort (glInvalidateTexSubImage)
2061        && FindProcShort (glInvalidateTexImage)
2062        && FindProcShort (glInvalidateBufferSubData)
2063        && FindProcShort (glInvalidateBufferData)
2064        && FindProcShort (glInvalidateFramebuffer)
2065        && FindProcShort (glInvalidateSubFramebuffer)
2066        && FindProcShort (glMultiDrawArraysIndirect)
2067        && FindProcShort (glMultiDrawElementsIndirect)
2068        && FindProcShort (glGetProgramInterfaceiv)
2069        && FindProcShort (glGetProgramResourceIndex)
2070        && FindProcShort (glGetProgramResourceName)
2071        && FindProcShort (glGetProgramResourceiv)
2072        && FindProcShort (glGetProgramResourceLocation)
2073        && FindProcShort (glGetProgramResourceLocationIndex)
2074        && FindProcShort (glShaderStorageBlockBinding)
2075        && FindProcShort (glTexBufferRange)
2076        && FindProcShort (glTexStorage2DMultisample)
2077        && FindProcShort (glTexStorage3DMultisample)
2078        && FindProcShort (glTextureView)
2079        && FindProcShort (glBindVertexBuffer)
2080        && FindProcShort (glVertexAttribFormat)
2081        && FindProcShort (glVertexAttribIFormat)
2082        && FindProcShort (glVertexAttribLFormat)
2083        && FindProcShort (glVertexAttribBinding)
2084        && FindProcShort (glVertexBindingDivisor)
2085        && FindProcShort (glDebugMessageControl)
2086        && FindProcShort (glDebugMessageInsert)
2087        && FindProcShort (glDebugMessageCallback)
2088        && FindProcShort (glGetDebugMessageLog)
2089        && FindProcShort (glPushDebugGroup)
2090        && FindProcShort (glPopDebugGroup)
2091        && FindProcShort (glObjectLabel)
2092        && FindProcShort (glGetObjectLabel)
2093        && FindProcShort (glObjectPtrLabel)
2094        && FindProcShort (glGetObjectPtrLabel);
2095
2096   // load GL_ARB_clear_texture (added to OpenGL 4.4 core)
2097   bool arbTexClear = (IsGlGreaterEqual (4, 4) || CheckExtension ("GL_ARB_clear_texture"))
2098        && FindProcShort (glClearTexImage)
2099        && FindProcShort (glClearTexSubImage);
2100
2101   has44 = IsGlGreaterEqual (4, 4)
2102        && arbTexClear
2103        && FindProcShort (glBufferStorage)
2104        && FindProcShort (glBindBuffersBase)
2105        && FindProcShort (glBindBuffersRange)
2106        && FindProcShort (glBindTextures)
2107        && FindProcShort (glBindSamplers)
2108        && FindProcShort (glBindImageTextures)
2109        && FindProcShort (glBindVertexBuffers);
2110
2111   // initialize debug context extension
2112   if (CheckExtension ("GL_ARB_debug_output"))
2113   {
2114     arbDbg = NULL;
2115     if (has43)
2116     {
2117       arbDbg = (OpenGl_ArbDbg* )(&(*myFuncs));
2118     }
2119     else if (FindProc ("glDebugMessageControlARB",  myFuncs->glDebugMessageControl)
2120           && FindProc ("glDebugMessageInsertARB",   myFuncs->glDebugMessageInsert)
2121           && FindProc ("glDebugMessageCallbackARB", myFuncs->glDebugMessageCallback)
2122           && FindProc ("glGetDebugMessageLogARB",   myFuncs->glGetDebugMessageLog))
2123     {
2124       arbDbg = (OpenGl_ArbDbg* )(&(*myFuncs));
2125     }
2126
2127     if (arbDbg != NULL
2128      && caps->contextDebug)
2129     {
2130       // setup default callback
2131       myIsGlDebugCtx = Standard_True;
2132       arbDbg->glDebugMessageCallback (debugCallbackWrap, this);
2133       if (has43)
2134       {
2135         ::glEnable (GL_DEBUG_OUTPUT);
2136       }
2137       if (caps->contextSyncDebug)
2138       {
2139         ::glEnable (GL_DEBUG_OUTPUT_SYNCHRONOUS);
2140       }
2141     }
2142   }
2143
2144   // initialize TBO extension (ARB)
2145   if (!has31
2146    && CheckExtension ("GL_ARB_texture_buffer_object")
2147    && FindProc ("glTexBufferARB", myFuncs->glTexBuffer))
2148   {
2149     arbTBO = (OpenGl_ArbTBO* )(&(*myFuncs));
2150   }
2151   arbTboRGB32 = CheckExtension ("GL_ARB_texture_buffer_object_rgb32");
2152
2153   // initialize hardware instancing extension (ARB)
2154   if (!has31
2155    && CheckExtension ("GL_ARB_draw_instanced")
2156    && FindProc ("glDrawArraysInstancedARB",   myFuncs->glDrawArraysInstanced)
2157    && FindProc ("glDrawElementsInstancedARB", myFuncs->glDrawElementsInstanced))
2158   {
2159     arbIns = (OpenGl_ArbIns* )(&(*myFuncs));
2160   }
2161
2162   // initialize FBO extension (ARB)
2163   if (hasFBO)
2164   {
2165     arbFBO     = (OpenGl_ArbFBO*     )(&(*myFuncs));
2166     arbFBOBlit = (OpenGl_ArbFBOBlit* )(&(*myFuncs));
2167     extPDS = Standard_True; // extension for EXT, but part of ARB
2168   }
2169
2170   // initialize GS extension (EXT)
2171   if (CheckExtension ("GL_EXT_geometry_shader4")
2172    && FindProcShort (glProgramParameteriEXT))
2173   {
2174     extGS = (OpenGl_ExtGS* )(&(*myFuncs));
2175   }
2176
2177   // initialize bindless texture extension (ARB)
2178   if (CheckExtension ("GL_ARB_bindless_texture")
2179    && FindProcShort (glGetTextureHandleARB)
2180    && FindProcShort (glGetTextureSamplerHandleARB)
2181    && FindProcShort (glMakeTextureHandleResidentARB)
2182    && FindProcShort (glMakeTextureHandleNonResidentARB)
2183    && FindProcShort (glGetImageHandleARB)
2184    && FindProcShort (glMakeImageHandleResidentARB)
2185    && FindProcShort (glMakeImageHandleNonResidentARB)
2186    && FindProcShort (glUniformHandleui64ARB)
2187    && FindProcShort (glUniformHandleui64vARB)
2188    && FindProcShort (glProgramUniformHandleui64ARB)
2189    && FindProcShort (glProgramUniformHandleui64vARB)
2190    && FindProcShort (glIsTextureHandleResidentARB)
2191    && FindProcShort (glIsImageHandleResidentARB)
2192    && FindProcShort (glVertexAttribL1ui64ARB)
2193    && FindProcShort (glVertexAttribL1ui64vARB)
2194    && FindProcShort (glGetVertexAttribLui64vARB))
2195   {
2196     arbTexBindless = (OpenGl_ArbTexBindless* )(&(*myFuncs));
2197   }
2198
2199   if (!has12)
2200   {
2201     checkWrongVersion (1, 2);
2202     myGlVerMajor = 1;
2203     myGlVerMinor = 1;
2204     return;
2205   }
2206   else if (!has13)
2207   {
2208     checkWrongVersion (1, 3);
2209     myGlVerMajor = 1;
2210     myGlVerMinor = 2;
2211     return;
2212   }
2213   else if (!has14)
2214   {
2215     checkWrongVersion (1, 4);
2216     myGlVerMajor = 1;
2217     myGlVerMinor = 3;
2218     return;
2219   }
2220   else if (!has15)
2221   {
2222     checkWrongVersion (1, 5);
2223     myGlVerMajor = 1;
2224     myGlVerMinor = 4;
2225     return;
2226   }
2227   if (!isCoreProfile)
2228   {
2229     core15 = (OpenGl_GlCore15* )(&(*myFuncs));
2230   }
2231   core15fwd = (OpenGl_GlCore15Fwd* )(&(*myFuncs));
2232
2233   if (!has20)
2234   {
2235     checkWrongVersion (2, 0);
2236     myGlVerMajor = 1;
2237     myGlVerMinor = 5;
2238     return;
2239   }
2240
2241   const char* aGlslVer = (const char* )::glGetString (GL_SHADING_LANGUAGE_VERSION);
2242   if (aGlslVer == NULL
2243   || *aGlslVer == '\0')
2244   {
2245     // broken context has been detected
2246     TCollection_ExtendedString aMsg = TCollection_ExtendedString()
2247       + "Error! OpenGL context reports version "
2248       + myGlVerMajor  + "." + myGlVerMinor
2249       + " but reports wrong GLSL version";
2250     PushMessage (GL_DEBUG_SOURCE_APPLICATION,
2251                  GL_DEBUG_TYPE_ERROR,
2252                  0,
2253                  GL_DEBUG_SEVERITY_HIGH,
2254                  aMsg);
2255     myGlVerMajor = 1;
2256     myGlVerMinor = 5;
2257     return;
2258   }
2259
2260   if (!isCoreProfile)
2261   {
2262     core20  = (OpenGl_GlCore20*    )(&(*myFuncs));
2263   }
2264   core20fwd = (OpenGl_GlCore20Fwd* )(&(*myFuncs));
2265
2266   if (!has21)
2267   {
2268     checkWrongVersion (2, 1);
2269     myGlVerMajor = 2;
2270     myGlVerMinor = 0;
2271     return;
2272   }
2273
2274   if (!has30)
2275   {
2276     checkWrongVersion (3, 0);
2277     myGlVerMajor = 2;
2278     myGlVerMinor = 1;
2279     return;
2280   }
2281
2282   // MSAA RenderBuffers have been defined in OpenGL 3.0,
2283   // but MSAA Textures - only in OpenGL 3.2+
2284   if (!has32
2285    && CheckExtension ("GL_ARB_texture_multisample")
2286    && FindProcShort (glTexImage2DMultisample))
2287   {
2288     GLint aNbColorSamples = 0, aNbDepthSamples = 0;
2289     ::glGetIntegerv (GL_MAX_COLOR_TEXTURE_SAMPLES, &aNbColorSamples);
2290     ::glGetIntegerv (GL_MAX_DEPTH_TEXTURE_SAMPLES, &aNbDepthSamples);
2291     myMaxMsaaSamples = Min (aNbColorSamples, aNbDepthSamples);
2292   }
2293   if (!has43
2294    && CheckExtension ("GL_ARB_texture_storage_multisample")
2295    && FindProcShort (glTexStorage2DMultisample))
2296   {
2297     //
2298   }
2299
2300   if (!has31)
2301   {
2302     checkWrongVersion (3, 1);
2303     myGlVerMajor = 3;
2304     myGlVerMinor = 0;
2305     return;
2306   }
2307   arbTBO = (OpenGl_ArbTBO* )(&(*myFuncs));
2308   arbIns = (OpenGl_ArbIns* )(&(*myFuncs));
2309
2310   // check whether ray tracing mode is supported
2311   myHasRayTracing = has31
2312                  && arbTboRGB32
2313                  && arbFBOBlit  != NULL;
2314
2315   // check whether textures in ray tracing mode are supported
2316   myHasRayTracingTextures = myHasRayTracing
2317                          && arbTexBindless != NULL;
2318
2319   // check whether adaptive screen sampling in ray tracing mode is supported
2320   myHasRayTracingAdaptiveSampling = myHasRayTracing
2321                                  && has44
2322                                  && CheckExtension ("GL_NV_shader_atomic_float");
2323
2324   if (!has32)
2325   {
2326     checkWrongVersion (3, 2);
2327     myGlVerMajor = 3;
2328     myGlVerMinor = 1;
2329     return;
2330   }
2331   core32 = (OpenGl_GlCore32* )(&(*myFuncs));
2332   if (isCoreProfile)
2333   {
2334     core32->glGenVertexArrays (1, &myDefaultVao);
2335   }
2336   else
2337   {
2338     core32back = (OpenGl_GlCore32Back* )(&(*myFuncs));
2339   }
2340   ::glGetIntegerv (GL_MAX_SAMPLES, &myMaxMsaaSamples);
2341
2342   if (!has33)
2343   {
2344     checkWrongVersion (3, 3);
2345     myGlVerMajor = 3;
2346     myGlVerMinor = 2;
2347     return;
2348   }
2349   core33 = (OpenGl_GlCore33* )(&(*myFuncs));
2350   if (!isCoreProfile)
2351   {
2352     core33back = (OpenGl_GlCore33Back* )(&(*myFuncs));
2353   }
2354
2355   // initialize sampler object
2356   myTexSampler = new OpenGl_Sampler();
2357   myTexSampler->Init (*this);
2358
2359   if (!has40)
2360   {
2361     checkWrongVersion (4, 0);
2362     myGlVerMajor = 3;
2363     myGlVerMinor = 3;
2364     return;
2365   }
2366   arbTboRGB32 = Standard_True; // in core since OpenGL 4.0
2367
2368   if (!has41)
2369   {
2370     checkWrongVersion (4, 1);
2371     myGlVerMajor = 4;
2372     myGlVerMinor = 0;
2373     return;
2374   }
2375   core41 = (OpenGl_GlCore41* )(&(*myFuncs));
2376   if (!isCoreProfile)
2377   {
2378     core41back = (OpenGl_GlCore41Back* )(&(*myFuncs));
2379   }
2380
2381   if(!has42)
2382   {
2383     checkWrongVersion (4, 2);
2384     myGlVerMajor = 4;
2385     myGlVerMinor = 1;
2386     return;
2387   }
2388   core42 = (OpenGl_GlCore42* )(&(*myFuncs));
2389   if (!isCoreProfile)
2390   {
2391     core42back = (OpenGl_GlCore42Back* )(&(*myFuncs));
2392   }
2393
2394   if (!has43)
2395   {
2396     checkWrongVersion (4, 3);
2397     myGlVerMajor = 4;
2398     myGlVerMinor = 2;
2399     return;
2400   }
2401   core43 = (OpenGl_GlCore43* )(&(*myFuncs));
2402   if (!isCoreProfile)
2403   {
2404     core43back = (OpenGl_GlCore43Back* )(&(*myFuncs));
2405   }
2406
2407   if (!has44)
2408   {
2409     checkWrongVersion (4, 4);
2410     myGlVerMajor = 4;
2411     myGlVerMinor = 3;
2412     return;
2413   }
2414   core44 = (OpenGl_GlCore44* )(&(*myFuncs));
2415   if (!isCoreProfile)
2416   {
2417     core44back = (OpenGl_GlCore44Back* )(&(*myFuncs));
2418   }
2419 #endif
2420 }
2421
2422 // =======================================================================
2423 // function : MemoryInfo
2424 // purpose  :
2425 // =======================================================================
2426 Standard_Size OpenGl_Context::AvailableMemory() const
2427 {
2428 #if !defined(GL_ES_VERSION_2_0)
2429   if (atiMem)
2430   {
2431     // this is actually information for VBO pool
2432     // however because pools are mostly shared
2433     // it can be used for total GPU memory estimations
2434     GLint aMemInfo[4];
2435     aMemInfo[0] = 0;
2436     glGetIntegerv (GL_VBO_FREE_MEMORY_ATI, aMemInfo);
2437     // returned value is in KiB, however this maybe changed in future
2438     return Standard_Size(aMemInfo[0]) * 1024;
2439   }
2440   else if (nvxMem)
2441   {
2442     // current available dedicated video memory (in KiB), currently unused GPU memory
2443     GLint aMemInfo = 0;
2444     glGetIntegerv (GL_GPU_MEMORY_INFO_CURRENT_AVAILABLE_VIDMEM_NVX, &aMemInfo);
2445     return Standard_Size(aMemInfo) * 1024;
2446   }
2447 #endif
2448   return 0;
2449 }
2450
2451 // =======================================================================
2452 // function : MemoryInfo
2453 // purpose  :
2454 // =======================================================================
2455 TCollection_AsciiString OpenGl_Context::MemoryInfo() const
2456 {
2457   TColStd_IndexedDataMapOfStringString aDict;
2458   MemoryInfo (aDict);
2459
2460   TCollection_AsciiString aText;
2461   for (TColStd_IndexedDataMapOfStringString::Iterator anIter (aDict); anIter.More(); anIter.Next())
2462   {
2463     if (!aText.IsEmpty())
2464     {
2465       aText += "\n";
2466     }
2467     aText += TCollection_AsciiString("  ") + anIter.Key() + ": " + anIter.Value();
2468   }
2469   return aText;
2470 }
2471
2472 // =======================================================================
2473 // function : MemoryInfo
2474 // purpose  :
2475 // =======================================================================
2476 void OpenGl_Context::MemoryInfo (TColStd_IndexedDataMapOfStringString& theDict) const
2477 {
2478 #if defined(GL_ES_VERSION_2_0)
2479   (void )theDict;
2480 #elif defined(__APPLE__) && !defined(MACOSX_USE_GLX)
2481   GLint aGlRendId = 0;
2482   CGLGetParameter (CGLGetCurrentContext(), kCGLCPCurrentRendererID, &aGlRendId);
2483
2484   CGLRendererInfoObj  aRendObj = NULL;
2485   CGOpenGLDisplayMask aDispMask = CGDisplayIDToOpenGLDisplayMask (kCGDirectMainDisplay);
2486   GLint aRendNb = 0;
2487   CGLQueryRendererInfo (aDispMask, &aRendObj, &aRendNb);
2488   for (GLint aRendIter = 0; aRendIter < aRendNb; ++aRendIter)
2489   {
2490     GLint aRendId = 0;
2491     if (CGLDescribeRenderer (aRendObj, aRendIter, kCGLRPRendererID, &aRendId) != kCGLNoError
2492      || aRendId != aGlRendId)
2493     {
2494       continue;
2495     }
2496
2497     //kCGLRPVideoMemoryMegabytes   = 131;
2498     //kCGLRPTextureMemoryMegabytes = 132;
2499     GLint aVMem = 0;
2500   #if MAC_OS_X_VERSION_MIN_REQUIRED >= 1070
2501     if (CGLDescribeRenderer(aRendObj, aRendIter, kCGLRPVideoMemoryMegabytes, &aVMem) == kCGLNoError)
2502     {
2503       addInfo (theDict, "GPU memory",         TCollection_AsciiString() + aVMem + " MiB");
2504     }
2505     if (CGLDescribeRenderer(aRendObj, aRendIter, kCGLRPTextureMemoryMegabytes, &aVMem) == kCGLNoError)
2506     {
2507       addInfo (theDict, "GPU Texture memory", TCollection_AsciiString() + aVMem + " MiB");
2508     }
2509   #else
2510     if (CGLDescribeRenderer(aRendObj, aRendIter, kCGLRPVideoMemory, &aVMem) == kCGLNoError)
2511     {
2512       addInfo (theDict, "GPU memory",         TCollection_AsciiString() + (aVMem / (1024 * 1024)) + " MiB");
2513     }
2514     if (CGLDescribeRenderer(aRendObj, aRendIter, kCGLRPTextureMemory, &aVMem) == kCGLNoError)
2515     {
2516       addInfo (theDict, "GPU Texture memory", TCollection_AsciiString() + (aVMem / (1024 * 1024)) + " MiB");
2517     }
2518   #endif
2519   }
2520 #endif
2521
2522 #if !defined(GL_ES_VERSION_2_0)
2523   if (atiMem)
2524   {
2525     GLint aValues[4];
2526     memset (aValues, 0, sizeof(aValues));
2527     glGetIntegerv (GL_VBO_FREE_MEMORY_ATI, aValues);
2528
2529     // total memory free in the pool
2530     addInfo (theDict, "GPU free memory",    TCollection_AsciiString() + (aValues[0] / 1024) + " MiB");
2531
2532     if (aValues[1] != aValues[0])
2533     {
2534       // largest available free block in the pool
2535       addInfo (theDict, "Largest free block", TCollection_AsciiString() + (aValues[1] / 1024) + " MiB");
2536     }
2537     if (aValues[2] != aValues[0])
2538     {
2539       // total auxiliary memory free
2540       addInfo (theDict, "Free auxiliary memory", TCollection_AsciiString() + (aValues[2] / 1024) + " MiB");
2541     }
2542   }
2543   else if (nvxMem)
2544   {
2545     //current available dedicated video memory (in KiB), currently unused GPU memory
2546     GLint aValue = 0;
2547     glGetIntegerv (GL_GPU_MEMORY_INFO_CURRENT_AVAILABLE_VIDMEM_NVX, &aValue);
2548     addInfo (theDict, "GPU free memory", TCollection_AsciiString() + (aValue / 1024) + " MiB");
2549
2550     // dedicated video memory, total size (in KiB) of the GPU memory
2551     GLint aDedicated = 0;
2552     glGetIntegerv (GL_GPU_MEMORY_INFO_DEDICATED_VIDMEM_NVX, &aDedicated);
2553     addInfo (theDict, "GPU memory", TCollection_AsciiString() + (aDedicated / 1024) + " MiB");
2554
2555     // total available memory, total size (in KiB) of the memory available for allocations
2556     glGetIntegerv (GL_GPU_MEMORY_INFO_TOTAL_AVAILABLE_MEMORY_NVX, &aValue);
2557     if (aValue != aDedicated)
2558     {
2559       // different only for special configurations
2560       addInfo (theDict, "Total memory", TCollection_AsciiString() + (aValue / 1024) + " MiB");
2561     }
2562   }
2563 #endif
2564
2565 #if !defined(GL_ES_VERSION_2_0) && !defined(__APPLE__) && !defined(_WIN32)
2566   // GLX_RENDERER_VENDOR_ID_MESA
2567   if (myFuncs->glXQueryCurrentRendererIntegerMESA != NULL)
2568   {
2569     unsigned int aVMemMiB = 0;
2570     if (myFuncs->glXQueryCurrentRendererIntegerMESA (GLX_RENDERER_VIDEO_MEMORY_MESA, &aVMemMiB) != False)
2571     {
2572       addInfo (theDict, "GPU memory", TCollection_AsciiString() + int(aVMemMiB) + " MiB");
2573     }
2574   }
2575 #endif
2576 }
2577
2578 // =======================================================================
2579 // function : DiagnosticInfo
2580 // purpose  :
2581 // =======================================================================
2582 void OpenGl_Context::DiagnosticInformation (TColStd_IndexedDataMapOfStringString& theDict,
2583                                             Graphic3d_DiagnosticInfo theFlags) const
2584 {
2585   if ((theFlags & Graphic3d_DiagnosticInfo_NativePlatform) != 0)
2586   {
2587   #if defined(HAVE_EGL)
2588     addInfo (theDict, "EGLVersion",    ::eglQueryString ((Aspect_Display)myDisplay, EGL_VERSION));
2589     addInfo (theDict, "EGLVendor",     ::eglQueryString ((Aspect_Display)myDisplay, EGL_VENDOR));
2590     addInfo (theDict, "EGLClientAPIs", ::eglQueryString ((Aspect_Display)myDisplay, EGL_CLIENT_APIS));
2591     if ((theFlags & Graphic3d_DiagnosticInfo_Extensions) != 0)
2592     {
2593       addInfo (theDict, "EGLExtensions", ::eglQueryString ((Aspect_Display)myDisplay, EGL_EXTENSIONS));
2594     }
2595   #elif defined(_WIN32)
2596     if ((theFlags & Graphic3d_DiagnosticInfo_Extensions) != 0
2597      && myFuncs->wglGetExtensionsStringARB != NULL)
2598     {
2599       const char* aWglExts = myFuncs->wglGetExtensionsStringARB ((HDC )myWindowDC);
2600       addInfo (theDict, "WGLExtensions", aWglExts);
2601     }
2602   #elif defined(__APPLE__)
2603     //
2604   #else
2605     Display* aDisplay = (Display*)myDisplay;
2606     const int aScreen = DefaultScreen(aDisplay);
2607     addInfo (theDict, "GLXDirectRendering", ::glXIsDirect (aDisplay, (GLXContext )myGContext) ? "Yes" : "No");
2608     addInfo (theDict, "GLXVendor",  ::glXQueryServerString (aDisplay, aScreen, GLX_VENDOR));
2609     addInfo (theDict, "GLXVersion", ::glXQueryServerString (aDisplay, aScreen, GLX_VERSION));
2610     if ((theFlags & Graphic3d_DiagnosticInfo_Extensions) != 0)
2611     {
2612       const char* aGlxExts = ::glXQueryExtensionsString (aDisplay, aScreen);
2613       addInfo(theDict, "GLXExtensions", aGlxExts);
2614     }
2615
2616     addInfo (theDict, "GLXClientVendor",  ::glXGetClientString (aDisplay, GLX_VENDOR));
2617     addInfo (theDict, "GLXClientVersion", ::glXGetClientString (aDisplay, GLX_VERSION));
2618     if ((theFlags & Graphic3d_DiagnosticInfo_Extensions) != 0)
2619     {
2620       addInfo (theDict, "GLXClientExtensions", ::glXGetClientString (aDisplay, GLX_EXTENSIONS));
2621     }
2622   #endif
2623   }
2624
2625   if ((theFlags & Graphic3d_DiagnosticInfo_Device) != 0)
2626   {
2627     addInfo (theDict, "GLvendor",    (const char*)::glGetString (GL_VENDOR));
2628     addInfo (theDict, "GLdevice",    (const char*)::glGetString (GL_RENDERER));
2629     addInfo (theDict, "GLversion",   (const char*)::glGetString (GL_VERSION));
2630     addInfo (theDict, "GLSLversion", (const char*)::glGetString (GL_SHADING_LANGUAGE_VERSION));
2631     if (myIsGlDebugCtx)
2632     {
2633       addInfo (theDict, "GLdebug", "ON");
2634     }
2635   }
2636
2637   if ((theFlags & Graphic3d_DiagnosticInfo_Limits) != 0)
2638   {
2639     addInfo (theDict, "Max texture size", TCollection_AsciiString(myMaxTexDim));
2640     addInfo (theDict, "Max MSAA samples", TCollection_AsciiString(myMaxMsaaSamples));
2641   }
2642
2643   if ((theFlags & Graphic3d_DiagnosticInfo_FrameBuffer) != 0)
2644   {
2645     GLint aViewport[4] = {};
2646     ::glGetIntegerv (GL_VIEWPORT, aViewport);
2647     addInfo (theDict, "Viewport", TCollection_AsciiString() + aViewport[2] + "x" + aViewport[3]);
2648   }
2649
2650   if ((theFlags & Graphic3d_DiagnosticInfo_Memory) != 0)
2651   {
2652     MemoryInfo (theDict);
2653   }
2654
2655   if ((theFlags & Graphic3d_DiagnosticInfo_Extensions) != 0)
2656   {
2657   #if !defined(GL_ES_VERSION_2_0)
2658     if (IsGlGreaterEqual (3, 0)
2659      && myFuncs->glGetStringi != NULL)
2660     {
2661       TCollection_AsciiString anExtList;
2662       GLint anExtNb = 0;
2663       ::glGetIntegerv (GL_NUM_EXTENSIONS, &anExtNb);
2664       for (GLint anIter = 0; anIter < anExtNb; ++anIter)
2665       {
2666         const char* anExtension = (const char*)myFuncs->glGetStringi (GL_EXTENSIONS, (GLuint)anIter);
2667         if (!anExtList.IsEmpty())
2668         {
2669           anExtList += " ";
2670         }
2671         anExtList += anExtension;
2672       }
2673       addInfo(theDict, "GLextensions", anExtList);
2674     }
2675     else
2676   #endif
2677     {
2678       addInfo (theDict, "GLextensions", (const char*)::glGetString (GL_EXTENSIONS));
2679     }
2680   }
2681 }
2682
2683 // =======================================================================
2684 // function : GetResource
2685 // purpose  :
2686 // =======================================================================
2687 const Handle(OpenGl_Resource)& OpenGl_Context::GetResource (const TCollection_AsciiString& theKey) const
2688 {
2689   return mySharedResources->IsBound (theKey) ? mySharedResources->Find (theKey) : NULL_GL_RESOURCE;
2690 }
2691
2692 // =======================================================================
2693 // function : ShareResource
2694 // purpose  :
2695 // =======================================================================
2696 Standard_Boolean OpenGl_Context::ShareResource (const TCollection_AsciiString& theKey,
2697                                                 const Handle(OpenGl_Resource)& theResource)
2698 {
2699   if (theKey.IsEmpty() || theResource.IsNull())
2700   {
2701     return Standard_False;
2702   }
2703   return mySharedResources->Bind (theKey, theResource);
2704 }
2705
2706 // =======================================================================
2707 // function : ReleaseResource
2708 // purpose  :
2709 // =======================================================================
2710 void OpenGl_Context::ReleaseResource (const TCollection_AsciiString& theKey,
2711                                       const Standard_Boolean         theToDelay)
2712 {
2713   if (!mySharedResources->IsBound (theKey))
2714   {
2715     return;
2716   }
2717   auto& aRes = mySharedResources->Find (theKey);
2718   if (aRes->GetRefCount() > 1)
2719   {
2720     return;
2721   }
2722
2723   if (theToDelay)
2724   {
2725     myDelayed->Bind (theKey, 1);
2726   }
2727   else
2728   {
2729     aRes->Release (this);
2730     mySharedResources->UnBind (theKey);
2731   }
2732 }
2733
2734 // =======================================================================
2735 // function : ReleaseDelayed
2736 // purpose  :
2737 // =======================================================================
2738 void OpenGl_Context::ReleaseDelayed()
2739 {
2740   // release queued elements
2741   while (!myUnusedResources->IsEmpty())
2742   {
2743     myUnusedResources->First()->Release (this);
2744     myUnusedResources->RemoveFirst();
2745   }
2746
2747   // release delayed shared resources
2748   NCollection_Vector<TCollection_AsciiString> aDeadList;
2749   for (NCollection_DataMap<TCollection_AsciiString, Standard_Integer>::Iterator anIter (*myDelayed);
2750        anIter.More(); anIter.Next())
2751   {
2752     if (++anIter.ChangeValue() <= 2)
2753     {
2754       continue; // postpone release one more frame to ensure noone use it periodically
2755     }
2756
2757     const TCollection_AsciiString& aKey = anIter.Key();
2758     if (!mySharedResources->IsBound (aKey))
2759     {
2760       // mixed unshared strategy delayed/undelayed was used!
2761       aDeadList.Append (aKey);
2762       continue;
2763     }
2764
2765     auto& aRes = mySharedResources->ChangeFind (aKey);
2766     if (aRes->GetRefCount() > 1)
2767     {
2768       // should be only 1 instance in mySharedResources
2769       // if not - resource was reused again
2770       aDeadList.Append (aKey);
2771       continue;
2772     }
2773
2774     // release resource if no one requiested it more than 2 redraw calls
2775     aRes->Release (this);
2776     mySharedResources->UnBind (aKey);
2777     aDeadList.Append (aKey);
2778   }
2779
2780   for (Standard_Integer anIter = 0; anIter < aDeadList.Length(); ++anIter)
2781   {
2782     myDelayed->UnBind (aDeadList.Value (anIter));
2783   }
2784 }
2785
2786 // =======================================================================
2787 // function : BindProgram
2788 // purpose  :
2789 // =======================================================================
2790 Standard_Boolean OpenGl_Context::BindProgram (const Handle(OpenGl_ShaderProgram)& theProgram)
2791 {
2792   if (core20fwd == NULL)
2793   {
2794     return Standard_False;
2795   }
2796   else if (myActiveProgram == theProgram)
2797   {
2798     return Standard_True;
2799   }
2800
2801   if (theProgram.IsNull()
2802   || !theProgram->IsValid())
2803   {
2804     if (!myActiveProgram.IsNull())
2805     {
2806       core20fwd->glUseProgram (OpenGl_ShaderProgram::NO_PROGRAM);
2807       myActiveProgram.Nullify();
2808     }
2809     return Standard_False;
2810   }
2811
2812   myActiveProgram = theProgram;
2813   core20fwd->glUseProgram (theProgram->ProgramId());
2814   return Standard_True;
2815 }
2816
2817 // =======================================================================
2818 // function : BindDefaultVao
2819 // purpose  :
2820 // =======================================================================
2821 void OpenGl_Context::BindDefaultVao()
2822 {
2823 #if !defined(GL_ES_VERSION_2_0)
2824   if (myDefaultVao == 0
2825    || core32 == NULL)
2826   {
2827     return;
2828   }
2829
2830   core32->glBindVertexArray (myDefaultVao);
2831 #endif
2832 }
2833
2834 // =======================================================================
2835 // function : SetDefaultFrameBuffer
2836 // purpose  :
2837 // =======================================================================
2838 Handle(OpenGl_FrameBuffer) OpenGl_Context::SetDefaultFrameBuffer (const Handle(OpenGl_FrameBuffer)& theFbo)
2839 {
2840   Handle(OpenGl_FrameBuffer) aFbo = myDefaultFbo;
2841   myDefaultFbo = theFbo;
2842   return aFbo;
2843 }
2844
2845 // =======================================================================
2846 // function : SetShadingMaterial
2847 // purpose  :
2848 // =======================================================================
2849 void OpenGl_Context::SetShadingMaterial (const OpenGl_AspectFace* theAspect,
2850                                          const Handle(Graphic3d_PresentationAttributes)& theHighlight,
2851                                          const Standard_Boolean theUseDepthWrite)
2852 {
2853   const Handle(Graphic3d_AspectFillArea3d)& anAspect = (!theHighlight.IsNull() && !theHighlight->BasicFillAreaAspect().IsNull())
2854                                                       ?  theHighlight->BasicFillAreaAspect()
2855                                                       :  theAspect->Aspect();
2856
2857   const bool toDistinguish = anAspect->Distinguish();
2858   const bool toMapTexture  = anAspect->ToMapTexture();
2859   const Graphic3d_MaterialAspect& aMatFrontSrc = anAspect->FrontMaterial();
2860   const Graphic3d_MaterialAspect& aMatBackSrc  = toDistinguish
2861                                                ? anAspect->BackMaterial()
2862                                                : aMatFrontSrc;
2863   const Quantity_Color& aFrontIntColor = anAspect->InteriorColor();
2864   const Quantity_Color& aBackIntColor  = toDistinguish
2865                                        ? anAspect->BackInteriorColor()
2866                                        : aFrontIntColor;
2867
2868   myMatFront.Init (aMatFrontSrc, aFrontIntColor);
2869   if (toDistinguish)
2870   {
2871     myMatBack.Init (aMatBackSrc, aBackIntColor);
2872   }
2873   else
2874   {
2875     myMatBack = myMatFront;
2876   }
2877
2878   // handling transparency
2879   float aTranspFront = aMatFrontSrc.Transparency();
2880   float aTranspBack  = aMatBackSrc .Transparency();
2881   if (!theHighlight.IsNull()
2882     && theHighlight->BasicFillAreaAspect().IsNull())
2883   {
2884     myMatFront.SetColor (theHighlight->ColorRGBA());
2885     myMatBack .SetColor (theHighlight->ColorRGBA());
2886     aTranspFront = theHighlight->Transparency();
2887     aTranspBack  = theHighlight->Transparency();
2888   }
2889   {
2890     GLboolean aDepthMask = GL_TRUE;
2891     if (aTranspFront != 0.0f
2892      || aTranspBack  != 0.0f)
2893     {
2894       // render transparent
2895       myMatFront.Diffuse.a() = 1.0f - aTranspFront;
2896       myMatBack .Diffuse.a() = 1.0f - aTranspBack;
2897       glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
2898       glEnable (GL_BLEND);
2899       aDepthMask = GL_FALSE;
2900     }
2901     else
2902     {
2903       // render opaque
2904       glBlendFunc (GL_ONE, GL_ZERO);
2905       glDisable (GL_BLEND);
2906     }
2907     if (theUseDepthWrite)
2908     {
2909       glDepthMask (aDepthMask);
2910     }
2911   }
2912
2913   // do not update material properties in case of zero reflection mode,
2914   // because GL lighting will be disabled by OpenGl_PrimitiveArray::DrawArray() anyway.
2915   if (theAspect->IsNoLighting())
2916   {
2917     return;
2918   }
2919
2920   if (myMatFront    == myShaderManager->MaterialState().FrontMaterial()
2921    && myMatBack     == myShaderManager->MaterialState().BackMaterial()
2922    && toDistinguish == myShaderManager->MaterialState().ToDistinguish()
2923    && toMapTexture  == myShaderManager->MaterialState().ToMapTexture())
2924   {
2925     return;
2926   }
2927
2928   myShaderManager->UpdateMaterialStateTo (myMatFront, myMatBack, toDistinguish, toMapTexture);
2929 }
2930
2931 // =======================================================================
2932 // function : SetColor4fv
2933 // purpose  :
2934 // =======================================================================
2935 void OpenGl_Context::SetColor4fv (const OpenGl_Vec4& theColor)
2936 {
2937   if (!myActiveProgram.IsNull())
2938   {
2939     myActiveProgram->SetUniform (this, myActiveProgram->GetStateLocation (OpenGl_OCCT_COLOR), theColor);
2940   }
2941 #if !defined(GL_ES_VERSION_2_0)
2942   else if (core11 != NULL)
2943   {
2944     core11->glColor4fv (theColor.GetData());
2945   }
2946 #endif
2947 }
2948
2949 // =======================================================================
2950 // function : SetTypeOfLine
2951 // purpose  :
2952 // =======================================================================
2953 void OpenGl_Context::SetTypeOfLine (const Aspect_TypeOfLine  theType,
2954                                     const Standard_ShortReal theFactor)
2955 {
2956   Standard_Integer aPattern = 0xFFFF;
2957   switch (theType)
2958   {
2959     case Aspect_TOL_DASH:
2960     {
2961       aPattern = 0xFFC0;
2962       break;
2963     }
2964     case Aspect_TOL_DOT:
2965     {
2966       aPattern = 0xCCCC;
2967       break;
2968     }
2969     case Aspect_TOL_DOTDASH:
2970     {
2971       aPattern = 0xFF18;
2972       break;
2973     }
2974     case Aspect_TOL_EMPTY:
2975     case Aspect_TOL_SOLID:
2976     {
2977       aPattern = 0xFFFF;
2978       break;
2979     }
2980     case Aspect_TOL_USERDEFINED:
2981     {
2982       aPattern = 0xFF24;
2983       break;
2984     }
2985   }
2986
2987   if (!myActiveProgram.IsNull())
2988   {
2989     myActiveProgram->SetUniform (this, "uPattern", aPattern);
2990     myActiveProgram->SetUniform (this, "uFactor",  theFactor);
2991     return;
2992   }
2993
2994 #if !defined(GL_ES_VERSION_2_0)
2995   if (aPattern != 0xFFFF)
2996   {
2997   #ifdef HAVE_GL2PS
2998     if (IsFeedback())
2999     {
3000       gl2psEnable (GL2PS_LINE_STIPPLE);
3001     }
3002   #endif
3003
3004     if (core11 != NULL)
3005     {
3006       core11fwd->glEnable (GL_LINE_STIPPLE);
3007
3008       core11->glLineStipple (static_cast<GLint>    (theFactor),
3009                              static_cast<GLushort> (aPattern));
3010     }
3011   }
3012   else
3013   {
3014     if (core11 != NULL)
3015     {
3016       core11fwd->glDisable (GL_LINE_STIPPLE);
3017     }
3018
3019   #ifdef HAVE_GL2PS
3020     if (IsFeedback())
3021     {
3022       gl2psDisable (GL2PS_LINE_STIPPLE);
3023     }
3024   #endif
3025   }
3026 #endif
3027 }
3028
3029 // =======================================================================
3030 // function : SetLineWidth
3031 // purpose  :
3032 // =======================================================================
3033 void OpenGl_Context::SetLineWidth (const Standard_ShortReal theWidth)
3034 {
3035   if (core11 != NULL)
3036   {
3037     // glLineWidth() is still defined within Core Profile, but has no effect with values != 1.0f
3038     core11fwd->glLineWidth (theWidth * myResolutionRatio);
3039   }
3040 #ifdef HAVE_GL2PS
3041   if (IsFeedback())
3042   {
3043     gl2psLineWidth (theWidth);
3044   }
3045 #endif
3046 }
3047
3048 // =======================================================================
3049 // function : SetTextureMatrix
3050 // purpose  :
3051 // =======================================================================
3052 void OpenGl_Context::SetTextureMatrix (const Handle(Graphic3d_TextureParams)& theParams)
3053 {
3054   if (theParams.IsNull())
3055   {
3056     return;
3057   }
3058   else if (!myActiveProgram.IsNull())
3059   {
3060     const GLint aUniLoc = myActiveProgram->GetStateLocation (OpenGl_OCCT_TEXTURE_TRSF2D);
3061     if (aUniLoc == OpenGl_ShaderProgram::INVALID_LOCATION)
3062     {
3063       return;
3064     }
3065
3066     // pack transformation parameters
3067     OpenGl_Vec4 aTrsf[2];
3068     aTrsf[0].xy() = theParams->Translation();
3069     aTrsf[0].zw() = theParams->Scale();
3070     aTrsf[1].x()  = std::sin (-theParams->Rotation() * static_cast<float> (M_PI / 180.0));
3071     aTrsf[1].y()  = std::cos (-theParams->Rotation() * static_cast<float> (M_PI / 180.0));
3072     myActiveProgram->SetUniform (this, aUniLoc, 2, aTrsf);
3073     return;
3074   }
3075
3076 #if !defined(GL_ES_VERSION_2_0)
3077   if (core11 != NULL)
3078   {
3079     GLint aMatrixMode = GL_TEXTURE;
3080     ::glGetIntegerv (GL_MATRIX_MODE, &aMatrixMode);
3081
3082     core11->glMatrixMode (GL_TEXTURE);
3083     OpenGl_Mat4 aTextureMat;
3084     const Graphic3d_Vec2& aScale = theParams->Scale();
3085     const Graphic3d_Vec2& aTrans = theParams->Translation();
3086     Graphic3d_TransformUtils::Scale     (aTextureMat,  aScale.x(),  aScale.y(), 1.0f);
3087     Graphic3d_TransformUtils::Translate (aTextureMat, -aTrans.x(), -aTrans.y(), 0.0f);
3088     Graphic3d_TransformUtils::Rotate    (aTextureMat, -theParams->Rotation(), 0.0f, 0.0f, 1.0f);
3089     core11->glLoadMatrixf (aTextureMat);
3090     core11->glMatrixMode (aMatrixMode);
3091   }
3092 #endif
3093 }
3094
3095 // =======================================================================
3096 // function : SetPointSize
3097 // purpose  :
3098 // =======================================================================
3099 void OpenGl_Context::SetPointSize (const Standard_ShortReal theSize)
3100 {
3101   if (!myActiveProgram.IsNull())
3102   {
3103     myActiveProgram->SetUniform (this, myActiveProgram->GetStateLocation (OpenGl_OCCT_POINT_SIZE), theSize);
3104   #if !defined(GL_ES_VERSION_2_0)
3105     //myContext->core11fwd->glEnable (GL_VERTEX_PROGRAM_POINT_SIZE);
3106   #endif
3107   }
3108 #if !defined(GL_ES_VERSION_2_0)
3109   //else
3110   {
3111     core11fwd->glPointSize (theSize);
3112     if (core20fwd != NULL)
3113     {
3114       //myContext->core11fwd->glDisable (GL_VERTEX_PROGRAM_POINT_SIZE);
3115     }
3116   }
3117 #endif
3118 }
3119
3120 // =======================================================================
3121 // function : SetPointSpriteOrigin
3122 // purpose  :
3123 // =======================================================================
3124 void OpenGl_Context::SetPointSpriteOrigin()
3125 {
3126 #if !defined(GL_ES_VERSION_2_0)
3127   if (core15fwd == NULL)
3128   {
3129     return;
3130   }
3131
3132   const int aNewState = !myActiveProgram.IsNull() ? GL_UPPER_LEFT : GL_LOWER_LEFT;
3133   if (myPointSpriteOrig != aNewState)
3134   {
3135     myPointSpriteOrig = aNewState;
3136     core15fwd->glPointParameteri (GL_POINT_SPRITE_COORD_ORIGIN, aNewState);
3137   }
3138 #endif
3139 }
3140
3141 // =======================================================================
3142 // function : SetGlNormalizeEnabled
3143 // purpose  :
3144 // =======================================================================
3145 Standard_Boolean OpenGl_Context::SetGlNormalizeEnabled (Standard_Boolean isEnabled)
3146 {
3147   if (isEnabled == myIsGlNormalizeEnabled)
3148   {
3149     return myIsGlNormalizeEnabled;
3150   }
3151
3152   Standard_Boolean anOldGlNormalize = myIsGlNormalizeEnabled;
3153
3154   myIsGlNormalizeEnabled = isEnabled;
3155
3156 #if !defined(GL_ES_VERSION_2_0)
3157   if (core11 != NULL)
3158   {
3159     if (isEnabled)
3160     {
3161       ::glEnable  (GL_NORMALIZE);
3162     }
3163     else
3164     {
3165       ::glDisable (GL_NORMALIZE);
3166     }
3167   }
3168 #endif
3169
3170   return anOldGlNormalize;
3171 }
3172
3173 // =======================================================================
3174 // function : SetPolygonMode
3175 // purpose  :
3176 // =======================================================================
3177 Standard_Integer OpenGl_Context::SetPolygonMode (const Standard_Integer theMode)
3178 {
3179   if (myPolygonMode == theMode)
3180   {
3181     return myPolygonMode;
3182   }
3183
3184   const Standard_Integer anOldPolygonMode = myPolygonMode;
3185
3186   myPolygonMode = theMode;
3187
3188 #if !defined(GL_ES_VERSION_2_0)
3189   ::glPolygonMode (GL_FRONT_AND_BACK, (GLenum)theMode);
3190 #endif
3191
3192   return anOldPolygonMode;
3193 }
3194
3195 // =======================================================================
3196 // function : SetPolygonHatchEnabled
3197 // purpose  :
3198 // =======================================================================
3199 bool OpenGl_Context::SetPolygonHatchEnabled (const bool theIsEnabled)
3200 {
3201   if (myHatchStyles.IsNull())
3202   {
3203     return false;
3204   }
3205   else if (myHatchStyles->IsEnabled() == theIsEnabled)
3206   {
3207     return theIsEnabled;
3208   }
3209
3210   return myHatchStyles->SetEnabled (this, theIsEnabled);
3211 }
3212
3213 // =======================================================================
3214 // function : SetPolygonHatchStyle
3215 // purpose  :
3216 // =======================================================================
3217 Standard_Integer OpenGl_Context::SetPolygonHatchStyle (const Handle(Graphic3d_HatchStyle)& theStyle)
3218 {
3219   if (theStyle.IsNull())
3220   {
3221     return 0;
3222   }
3223
3224   if (myHatchStyles.IsNull())
3225   {
3226     if (!GetResource ("OpenGl_LineAttributes", myHatchStyles))
3227     {
3228       // share and register for release once the resource is no longer used
3229       myHatchStyles = new OpenGl_LineAttributes();
3230       ShareResource ("OpenGl_LineAttributes", myHatchStyles);
3231     }
3232   }
3233   if (myHatchStyles->TypeOfHatch() == theStyle->HatchType())
3234   {
3235     return theStyle->HatchType();
3236   }
3237
3238   return myHatchStyles->SetTypeOfHatch (this, theStyle);
3239 }
3240
3241 // =======================================================================
3242 // function : ApplyModelWorldMatrix
3243 // purpose  :
3244 // =======================================================================
3245 void OpenGl_Context::ApplyModelWorldMatrix()
3246 {
3247   if (myShaderManager->ModelWorldState().ModelWorldMatrix() != ModelWorldState.Current())
3248   {
3249     myShaderManager->UpdateModelWorldStateTo (ModelWorldState.Current());
3250   }
3251 }
3252
3253 // =======================================================================
3254 // function : ApplyWorldViewMatrix
3255 // purpose  :
3256 // =======================================================================
3257 void OpenGl_Context::ApplyWorldViewMatrix()
3258 {
3259   if (myShaderManager->ModelWorldState().ModelWorldMatrix() != THE_IDENTITY_MATRIX)
3260   {
3261     myShaderManager->UpdateModelWorldStateTo (THE_IDENTITY_MATRIX);
3262   }
3263   if (myShaderManager->WorldViewState().WorldViewMatrix() != WorldViewState.Current())
3264   {
3265     myShaderManager->UpdateWorldViewStateTo (WorldViewState.Current());
3266   }
3267 }
3268
3269 // =======================================================================
3270 // function : ApplyModelViewMatrix
3271 // purpose  :
3272 // =======================================================================
3273 void OpenGl_Context::ApplyModelViewMatrix()
3274 {
3275   if (myShaderManager->ModelWorldState().ModelWorldMatrix() != ModelWorldState.Current())
3276   {
3277     myShaderManager->UpdateModelWorldStateTo (ModelWorldState.Current());
3278   }
3279   if (myShaderManager->WorldViewState().WorldViewMatrix() != WorldViewState.Current())
3280   {
3281     myShaderManager->UpdateWorldViewStateTo  (WorldViewState.Current());
3282   }
3283 }
3284
3285 // =======================================================================
3286 // function : ApplyProjectionMatrix
3287 // purpose  :
3288 // =======================================================================
3289 void OpenGl_Context::ApplyProjectionMatrix()
3290 {
3291   if (myShaderManager->ProjectionState().ProjectionMatrix() != ProjectionState.Current())
3292   {
3293     myShaderManager->UpdateProjectionStateTo (ProjectionState.Current());
3294   }
3295 }
3296
3297 // =======================================================================
3298 // function : EnableFeatures
3299 // purpose  :
3300 // =======================================================================
3301 void OpenGl_Context::EnableFeatures() const
3302 {
3303   //
3304 }
3305
3306 // =======================================================================
3307 // function : DisableFeatures
3308 // purpose  :
3309 // =======================================================================
3310 void OpenGl_Context::DisableFeatures() const
3311 {
3312 #if !defined(GL_ES_VERSION_2_0)
3313   glPixelTransferi (GL_MAP_COLOR, GL_FALSE);
3314 #endif
3315
3316   /*
3317   * Disable stuff that's likely to slow down glDrawPixels.
3318   * (Omit as much of this as possible, when you know in advance
3319   * that the OpenGL state will already be set correctly.)
3320   */
3321   glDisable(GL_DITHER);
3322   glDisable(GL_BLEND);
3323   glDisable(GL_DEPTH_TEST);
3324   glDisable(GL_TEXTURE_2D);
3325   glDisable(GL_STENCIL_TEST);
3326
3327 #if !defined(GL_ES_VERSION_2_0)
3328   glDisable(GL_LIGHTING);
3329   glDisable(GL_ALPHA_TEST);
3330   glDisable(GL_FOG);
3331   glDisable(GL_LOGIC_OP);
3332   glDisable(GL_TEXTURE_1D);
3333
3334   glPixelTransferi(GL_MAP_COLOR, GL_FALSE);
3335   glPixelTransferi(GL_RED_SCALE, 1);
3336   glPixelTransferi(GL_RED_BIAS, 0);
3337   glPixelTransferi(GL_GREEN_SCALE, 1);
3338   glPixelTransferi(GL_GREEN_BIAS, 0);
3339   glPixelTransferi(GL_BLUE_SCALE, 1);
3340   glPixelTransferi(GL_BLUE_BIAS, 0);
3341   glPixelTransferi(GL_ALPHA_SCALE, 1);
3342   glPixelTransferi(GL_ALPHA_BIAS, 0);
3343
3344   /*
3345   * Disable extensions that could slow down glDrawPixels.
3346   * (Actually, you should check for the presence of the proper
3347   * extension before making these calls.  I've omitted that
3348   * code for simplicity.)
3349   */
3350
3351   if ((myGlVerMajor >= 1) && (myGlVerMinor >= 2))
3352   {
3353 #ifdef GL_EXT_convolution
3354     if (CheckExtension ("GL_CONVOLUTION_1D_EXT"))
3355       glDisable(GL_CONVOLUTION_1D_EXT);
3356
3357     if (CheckExtension ("GL_CONVOLUTION_2D_EXT"))
3358       glDisable(GL_CONVOLUTION_2D_EXT);
3359
3360     if (CheckExtension ("GL_SEPARABLE_2D_EXT"))
3361       glDisable(GL_SEPARABLE_2D_EXT);
3362 #endif
3363
3364 #ifdef GL_EXT_histogram
3365     if (CheckExtension ("GL_SEPARABLE_2D_EXT"))
3366       glDisable(GL_HISTOGRAM_EXT);
3367
3368     if (CheckExtension ("GL_MINMAX_EXT"))
3369       glDisable(GL_MINMAX_EXT);
3370 #endif
3371
3372 #ifdef GL_EXT_texture3D
3373     if (CheckExtension ("GL_TEXTURE_3D_EXT"))
3374       glDisable(GL_TEXTURE_3D_EXT);
3375 #endif
3376   }
3377 #endif
3378 }