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