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