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