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