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