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