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