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