0023081: This is desirable to retrieve GPU memory information from graphic driver
[occt.git] / src / OpenGl / OpenGl_Context.cxx
1 // Created on: 2012-01-26
2 // Created by: Kirill GAVRILOV
3 // Copyright (c) 2012-2012 OPEN CASCADE SAS
4 //
5 // The content of this file is subject to the Open CASCADE Technology Public
6 // License Version 6.5 (the "License"). You may not use the content of this file
7 // except in compliance with the License. Please obtain a copy of the License
8 // at http://www.opencascade.org and read it completely before using this file.
9 //
10 // The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
11 // main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
12 //
13 // The Original Code and all software distributed under the License is
14 // distributed on an "AS IS" basis, without warranty of any kind, and the
15 // Initial Developer hereby disclaims all such warranties, including without
16 // limitation, any warranties of merchantability, fitness for a particular
17 // purpose or non-infringement. Please see the License for the specific terms
18 // and conditions governing the rights and limitations under the License.
19
20
21 #if (defined(_WIN32) || defined(__WIN32__))
22   #include <windows.h>
23 #endif
24
25 #include <OpenGl_Context.hxx>
26
27 #include <OpenGl_ArbVBO.hxx>
28 #include <OpenGl_ExtFBO.hxx>
29 #include <OpenGl_GlCore20.hxx>
30
31 #include <Standard_ProgramError.hxx>
32
33 #if (defined(_WIN32) || defined(__WIN32__))
34   //
35 #elif defined(__APPLE__) && !defined(MACOSX_USE_GLX)
36   #include <dlfcn.h>
37 #else
38   #include <GL/glx.h> // glXGetProcAddress()
39 #endif
40
41 // GL_NVX_gpu_memory_info
42 #ifndef GL_GPU_MEMORY_INFO_DEDICATED_VIDMEM_NVX
43   enum
44   {
45     GL_GPU_MEMORY_INFO_DEDICATED_VIDMEM_NVX         = 0x9047,
46     GL_GPU_MEMORY_INFO_TOTAL_AVAILABLE_MEMORY_NVX   = 0x9048,
47     GL_GPU_MEMORY_INFO_CURRENT_AVAILABLE_VIDMEM_NVX = 0x9049,
48     GL_GPU_MEMORY_INFO_EVICTION_COUNT_NVX           = 0x904A,
49     GL_GPU_MEMORY_INFO_EVICTED_MEMORY_NVX           = 0x904B
50   };
51 #endif
52
53 IMPLEMENT_STANDARD_HANDLE (OpenGl_Context, Standard_Transient)
54 IMPLEMENT_STANDARD_RTTIEXT(OpenGl_Context, Standard_Transient)
55
56 //! Make record shorter to retrieve function pointer using variable with same name
57 #define FindProcShort(theStruct, theFunc) FindProc(#theFunc, theStruct->theFunc)
58
59 // =======================================================================
60 // function : OpenGl_Context
61 // purpose  :
62 // =======================================================================
63 OpenGl_Context::OpenGl_Context()
64 : core12 (NULL),
65   core13 (NULL),
66   core14 (NULL),
67   core15 (NULL),
68   core20 (NULL),
69   arbVBO (NULL),
70   extFBO (NULL),
71   atiMem (Standard_False),
72   nvxMem (Standard_False),
73   myGlLibHandle (NULL),
74   myGlCore20 (NULL),
75   myGlVerMajor (0),
76   myGlVerMinor (0),
77   myIsFeedback (Standard_False),
78   myIsInitialized (Standard_False)
79 {
80 #if defined(MAC_OS_X_VERSION_10_3) && !defined(MACOSX_USE_GLX)
81   // Vendors can not extend functionality on this system
82   // and developers are limited to OpenGL support provided by Mac OS X SDK.
83   // We retrieve function pointers from system library
84   // to generalize extensions support on all platforms.
85   // In this way we also reach binary compatibility benefit between OS releases
86   // if some newest functionality is optionally used.
87   // Notice that GL version / extension availability checks are required
88   // because function pointers may be available but not functionality itself
89   // (depends on renderer).
90   myGlLibHandle = dlopen ("/System/Library/Frameworks/OpenGL.framework/Versions/Current/OpenGL", RTLD_LAZY);
91 #endif
92 }
93
94 // =======================================================================
95 // function : ~OpenGl_Context
96 // purpose  :
97 // =======================================================================
98 OpenGl_Context::~OpenGl_Context()
99 {
100   delete myGlCore20;
101   delete arbVBO;
102   delete extFBO;
103 }
104
105 // =======================================================================
106 // function : MakeCurrent
107 // purpose  :
108 // =======================================================================
109 Standard_Boolean OpenGl_Context::MakeCurrent()
110 {
111 #if (defined(_WIN32) || defined(__WIN32__))
112   if (myWindowDC == NULL || myGContext == NULL ||
113       !wglMakeCurrent ((HDC )myWindowDC, (HGLRC )myGContext))
114   {
115     //GLenum anErrCode = glGetError();
116     //const GLubyte* anErrorString = gluErrorString (anErrCode);
117     //std::cerr << "wglMakeCurrent() failed: " << anErrCode << " " << anErrorString << "\n";
118     return Standard_False;
119   }
120 #else
121   if (myDisplay == NULL || myWindow == 0 || myGContext == 0 ||
122       !glXMakeCurrent ((Display* )myDisplay, (GLXDrawable )myWindow, (GLXContext )myGContext))
123   {
124     // if there is no current context it might be impossible to use glGetError() correctly
125     //std::cerr << "glXMakeCurrent() failed!\n";
126     return Standard_False;
127   }
128 #endif
129   return Standard_True;
130 }
131
132 // =======================================================================
133 // function : findProc
134 // purpose  :
135 // =======================================================================
136 void* OpenGl_Context::findProc (const char* theFuncName)
137 {
138 #if (defined(_WIN32) || defined(__WIN32__))
139   return wglGetProcAddress (theFuncName);
140 #elif defined(__APPLE__) && !defined(MACOSX_USE_GLX)
141   return (myGlLibHandle != NULL) ? dlsym (myGlLibHandle, theFuncName) : NULL;
142 #else
143   return (void* )glXGetProcAddress ((const GLubyte* )theFuncName);
144 #endif
145 }
146
147 // =======================================================================
148 // function : CheckExtension
149 // purpose  :
150 // =======================================================================
151 Standard_Boolean OpenGl_Context::CheckExtension (const char* theExtName) const
152 {
153   if (theExtName  == NULL)
154   {
155     std::cerr << "CheckExtension called with NULL string!\n";
156     return Standard_False;
157   }
158   int anExtNameLen = strlen (theExtName);
159
160   // available since OpenGL 3.0
161   // and the ONLY way to check extensions with OpenGL 3.1+ core profile
162   /**if (IsGlGreaterEqual (3, 0))
163   {
164     GLint anExtNb = 0;
165     glGetIntegerv (GL_NUM_EXTENSIONS, &anExtNb);
166     for (GLint anIter = 0; anIter < anExtNb; ++anIter)
167     {
168       const char* anExtension = (const char* )core30->glGetStringi (GL_EXTENSIONS, (GLuint )anIter);
169       if (anExtension[anExtNameLen] == '\0' &&
170           strncmp (anExtension, theExtName, anExtNameLen) == 0)
171       {
172         return Standard_True;
173       }
174     }
175     return Standard_False;
176   }*/
177
178   // use old way with huge string for all extensions
179   const char* anExtString = (const char* )glGetString (GL_EXTENSIONS);
180   if (anExtString == NULL)
181   {
182     std::cerr << "glGetString (GL_EXTENSIONS) returns NULL! No GL context?\n";
183     return Standard_False;
184   }
185
186   // Search for theExtName in the extensions string.
187   // Use of strstr() is not sufficient because extension names can be prefixes of other extension names.
188   char* aPtrIter = (char* )anExtString;
189   const char* aPtrEnd = aPtrIter + strlen (anExtString);
190   while (aPtrIter < aPtrEnd)
191   {
192     int n = strcspn (aPtrIter, " ");
193     if ((n == anExtNameLen) && (strncmp (aPtrIter, theExtName, anExtNameLen) == 0))
194     {
195       return Standard_True;
196     }
197     aPtrIter += (n + 1);
198   }
199   return Standard_False;
200 }
201
202 // =======================================================================
203 // function : Init
204 // purpose  :
205 // =======================================================================
206 Standard_Boolean OpenGl_Context::Init()
207 {
208   if (myIsInitialized)
209   {
210     return Standard_True;
211   }
212
213 #if (defined(_WIN32) || defined(__WIN32__))
214   myWindowDC = (Aspect_Handle )wglGetCurrentDC();
215   myGContext = (Aspect_RenderingContext )wglGetCurrentContext();
216 #else
217   myDisplay  = (Aspect_Display )glXGetCurrentDisplay();
218   myGContext = (Aspect_RenderingContext )glXGetCurrentContext();
219   myWindow   = (Aspect_Drawable )glXGetCurrentDrawable();
220 #endif
221   if (myGContext == NULL)
222   {
223     return Standard_False;
224   }
225
226   init();
227   myIsInitialized = Standard_True;
228   return Standard_True;
229 }
230
231 // =======================================================================
232 // function : Init
233 // purpose  :
234 // =======================================================================
235 #if (defined(_WIN32) || defined(__WIN32__))
236 Standard_Boolean OpenGl_Context::Init (const Aspect_Handle           theWindow,
237                                        const Aspect_Handle           theWindowDC,
238                                        const Aspect_RenderingContext theGContext)
239 #else
240 Standard_Boolean OpenGl_Context::Init (const Aspect_Drawable         theWindow,
241                                        const Aspect_Display          theDisplay,
242                                        const Aspect_RenderingContext theGContext)
243 #endif
244 {
245   Standard_ProgramError_Raise_if (myIsInitialized, "OpenGl_Context::Init() should be called only once!");
246
247   myWindow   = theWindow;
248   myGContext = theGContext;
249 #if (defined(_WIN32) || defined(__WIN32__))
250   myWindowDC = theWindowDC;
251 #else
252   myDisplay  = theDisplay;
253 #endif
254   if (myGContext == NULL)
255   {
256     return Standard_False;
257   }
258
259   init();
260   myIsInitialized = Standard_True;
261   return Standard_True;
262 }
263
264 // =======================================================================
265 // function : ResetErrors
266 // purpose  :
267 // =======================================================================
268 void OpenGl_Context::ResetErrors()
269 {
270   while (glGetError() != GL_NO_ERROR)
271   {
272     //
273   }
274 }
275
276 // =======================================================================
277 // function : readGlVersion
278 // purpose  :
279 // =======================================================================
280 void OpenGl_Context::readGlVersion()
281 {
282   // reset values
283   myGlVerMajor = 0;
284   myGlVerMinor = 0;
285
286   // available since OpenGL 3.0
287   GLint aMajor, aMinor;
288   glGetIntegerv (GL_MAJOR_VERSION, &aMajor);
289   glGetIntegerv (GL_MINOR_VERSION, &aMinor);
290   if (glGetError() == GL_NO_ERROR)
291   {
292     myGlVerMajor = aMajor;
293     myGlVerMinor = aMinor;
294     return;
295   }
296   ResetErrors();
297
298   // Read version string.
299   // Notice that only first two numbers splitted by point '2.1 XXXXX' are significant.
300   // Following trash (after space) is vendor-specific.
301   // New drivers also returns micro version of GL like '3.3.0' which has no meaning
302   // and should be considered as vendor-specific too.
303   const char* aVerStr = (const char* )glGetString (GL_VERSION);
304   if (aVerStr == NULL || *aVerStr == '\0')
305   {
306     // invalid GL context
307     return;
308   }
309
310   // parse string for major number
311   char aMajorStr[32];
312   char aMinorStr[32];
313   size_t aMajIter = 0;
314   while (aVerStr[aMajIter] >= '0' && aVerStr[aMajIter] <= '9')
315   {
316     ++aMajIter;
317   }
318   if (aMajIter == 0 || aMajIter >= sizeof(aMajorStr))
319   {
320     return;
321   }
322   memcpy (aMajorStr, aVerStr, aMajIter);
323   aMajorStr[aMajIter] = '\0';
324
325   // parse string for minor number
326   size_t aMinIter = aMajIter + 1;
327   while (aVerStr[aMinIter] >= '0' && aVerStr[aMinIter] <= '9')
328   {
329     ++aMinIter;
330   }
331   size_t aMinLen = aMinIter - aMajIter - 1;
332   if (aMinLen == 0 || aMinLen >= sizeof(aMinorStr))
333   {
334     return;
335   }
336   memcpy (aMinorStr, aVerStr, aMinLen);
337   aMinorStr[aMinLen] = '\0';
338
339   // read numbers
340   myGlVerMajor = atoi (aMajorStr);
341   myGlVerMinor = atoi (aMinorStr);
342
343   if (myGlVerMajor <= 0)
344   {
345     myGlVerMajor = 0;
346     myGlVerMinor = 0;
347   }
348 }
349
350 // =======================================================================
351 // function : init
352 // purpose  :
353 // =======================================================================
354 void OpenGl_Context::init()
355 {
356   // read version
357   readGlVersion();
358
359   atiMem = CheckExtension ("GL_ATI_meminfo");
360   nvxMem = CheckExtension ("GL_NVX_gpu_memory_info");
361
362   // initialize VBO extension (ARB)
363   if (CheckExtension ("GL_ARB_vertex_buffer_object"))
364   {
365     arbVBO = new OpenGl_ArbVBO();
366     memset (arbVBO, 0, sizeof(OpenGl_ArbVBO)); // nullify whole structure
367     if (!FindProcShort (arbVBO, glGenBuffersARB)
368      || !FindProcShort (arbVBO, glBindBufferARB)
369      || !FindProcShort (arbVBO, glBufferDataARB)
370      || !FindProcShort (arbVBO, glDeleteBuffersARB))
371     {
372       delete arbVBO;
373       arbVBO = NULL;
374     }
375   }
376
377   // initialize FBO extension (EXT)
378   if (CheckExtension ("GL_EXT_framebuffer_object"))
379   {
380     extFBO = new OpenGl_ExtFBO();
381     memset (extFBO, 0, sizeof(OpenGl_ExtFBO)); // nullify whole structure
382     if (!FindProcShort (extFBO, glGenFramebuffersEXT)
383      || !FindProcShort (extFBO, glDeleteFramebuffersEXT)
384      || !FindProcShort (extFBO, glBindFramebufferEXT)
385      || !FindProcShort (extFBO, glFramebufferTexture2DEXT)
386      || !FindProcShort (extFBO, glCheckFramebufferStatusEXT)
387      || !FindProcShort (extFBO, glGenRenderbuffersEXT)
388      || !FindProcShort (extFBO, glDeleteRenderbuffersEXT)
389      || !FindProcShort (extFBO, glBindRenderbufferEXT)
390      || !FindProcShort (extFBO, glRenderbufferStorageEXT)
391      || !FindProcShort (extFBO, glFramebufferRenderbufferEXT))
392     {
393       delete extFBO;
394       extFBO = NULL;
395     }
396   }
397
398   myGlCore20 = new OpenGl_GlCore20();
399   memset (myGlCore20, 0, sizeof(OpenGl_GlCore20)); // nullify whole structure
400
401   // initialize OpenGL 1.2 core functionality
402   if (IsGlGreaterEqual (1, 2))
403   {
404     if (!FindProcShort (myGlCore20, glBlendColor)
405      || !FindProcShort (myGlCore20, glBlendEquation)
406      || !FindProcShort (myGlCore20, glDrawRangeElements)
407      || !FindProcShort (myGlCore20, glTexImage3D)
408      || !FindProcShort (myGlCore20, glTexSubImage3D)
409      || !FindProcShort (myGlCore20, glCopyTexSubImage3D))
410     {
411       myGlVerMajor = 1;
412       myGlVerMinor = 1;
413     }
414   }
415
416   // initialize OpenGL 1.3 core functionality
417   if (IsGlGreaterEqual (1, 3))
418   {
419     if (!FindProcShort (myGlCore20, glActiveTexture)
420      || !FindProcShort (myGlCore20, glSampleCoverage)
421      || !FindProcShort (myGlCore20, glCompressedTexImage3D)
422      || !FindProcShort (myGlCore20, glCompressedTexImage2D)
423      || !FindProcShort (myGlCore20, glCompressedTexImage1D)
424      || !FindProcShort (myGlCore20, glCompressedTexSubImage3D)
425      || !FindProcShort (myGlCore20, glCompressedTexSubImage2D)
426      || !FindProcShort (myGlCore20, glCompressedTexSubImage1D)
427      || !FindProcShort (myGlCore20, glGetCompressedTexImage)
428      // deprecated
429      || !FindProcShort (myGlCore20, glClientActiveTexture)
430      || !FindProcShort (myGlCore20, glMultiTexCoord1d)
431      || !FindProcShort (myGlCore20, glMultiTexCoord1dv)
432      || !FindProcShort (myGlCore20, glMultiTexCoord1f)
433      || !FindProcShort (myGlCore20, glMultiTexCoord1fv)
434      || !FindProcShort (myGlCore20, glMultiTexCoord1i)
435      || !FindProcShort (myGlCore20, glMultiTexCoord1iv)
436      || !FindProcShort (myGlCore20, glMultiTexCoord1s)
437      || !FindProcShort (myGlCore20, glMultiTexCoord1sv)
438      || !FindProcShort (myGlCore20, glMultiTexCoord2d)
439      || !FindProcShort (myGlCore20, glMultiTexCoord2dv)
440      || !FindProcShort (myGlCore20, glMultiTexCoord2f)
441      || !FindProcShort (myGlCore20, glMultiTexCoord2fv)
442      || !FindProcShort (myGlCore20, glMultiTexCoord2i)
443      || !FindProcShort (myGlCore20, glMultiTexCoord2iv)
444      || !FindProcShort (myGlCore20, glMultiTexCoord2s)
445      || !FindProcShort (myGlCore20, glMultiTexCoord2sv)
446      || !FindProcShort (myGlCore20, glMultiTexCoord3d)
447      || !FindProcShort (myGlCore20, glMultiTexCoord3dv)
448      || !FindProcShort (myGlCore20, glMultiTexCoord3f)
449      || !FindProcShort (myGlCore20, glMultiTexCoord3fv)
450      || !FindProcShort (myGlCore20, glMultiTexCoord3i)
451      || !FindProcShort (myGlCore20, glMultiTexCoord3iv)
452      || !FindProcShort (myGlCore20, glMultiTexCoord3s)
453      || !FindProcShort (myGlCore20, glMultiTexCoord3sv)
454      || !FindProcShort (myGlCore20, glMultiTexCoord4d)
455      || !FindProcShort (myGlCore20, glMultiTexCoord4dv)
456      || !FindProcShort (myGlCore20, glMultiTexCoord4f)
457      || !FindProcShort (myGlCore20, glMultiTexCoord4fv)
458      || !FindProcShort (myGlCore20, glMultiTexCoord4i)
459      || !FindProcShort (myGlCore20, glMultiTexCoord4iv)
460      || !FindProcShort (myGlCore20, glMultiTexCoord4s)
461      || !FindProcShort (myGlCore20, glMultiTexCoord4sv)
462      || !FindProcShort (myGlCore20, glLoadTransposeMatrixf)
463      || !FindProcShort (myGlCore20, glLoadTransposeMatrixd)
464      || !FindProcShort (myGlCore20, glMultTransposeMatrixf)
465      || !FindProcShort (myGlCore20, glMultTransposeMatrixd))
466     {
467       myGlVerMajor = 1;
468       myGlVerMinor = 2;
469       core12 = myGlCore20;
470     }
471   }
472
473   // initialize OpenGL 1.4 core functionality
474   if (IsGlGreaterEqual (1, 4))
475   {
476     if (!FindProcShort (myGlCore20, glBlendFuncSeparate)
477      || !FindProcShort (myGlCore20, glMultiDrawArrays)
478      || !FindProcShort (myGlCore20, glMultiDrawElements)
479      || !FindProcShort (myGlCore20, glPointParameterf)
480      || !FindProcShort (myGlCore20, glPointParameterfv)
481      || !FindProcShort (myGlCore20, glPointParameteri)
482      || !FindProcShort (myGlCore20, glPointParameteriv))
483     {
484       myGlVerMajor = 1;
485       myGlVerMinor = 3;
486       core12 = myGlCore20;
487       core13 = myGlCore20;
488     }
489   }
490
491   // initialize OpenGL 1.5 core functionality
492   if (IsGlGreaterEqual (1, 5))
493   {
494     if (!FindProcShort (myGlCore20, glGenQueries)
495      || !FindProcShort (myGlCore20, glDeleteQueries)
496      || !FindProcShort (myGlCore20, glIsQuery)
497      || !FindProcShort (myGlCore20, glBeginQuery)
498      || !FindProcShort (myGlCore20, glEndQuery)
499      || !FindProcShort (myGlCore20, glGetQueryiv)
500      || !FindProcShort (myGlCore20, glGetQueryObjectiv)
501      || !FindProcShort (myGlCore20, glGetQueryObjectuiv)
502      || !FindProcShort (myGlCore20, glBindBuffer)
503      || !FindProcShort (myGlCore20, glDeleteBuffers)
504      || !FindProcShort (myGlCore20, glGenBuffers)
505      || !FindProcShort (myGlCore20, glIsBuffer)
506      || !FindProcShort (myGlCore20, glBufferData)
507      || !FindProcShort (myGlCore20, glBufferSubData)
508      || !FindProcShort (myGlCore20, glGetBufferSubData)
509      || !FindProcShort (myGlCore20, glMapBuffer)
510      || !FindProcShort (myGlCore20, glUnmapBuffer)
511      || !FindProcShort (myGlCore20, glGetBufferParameteriv)
512      || !FindProcShort (myGlCore20, glGetBufferPointerv))
513     {
514       myGlVerMajor = 1;
515       myGlVerMinor = 4;
516       core12 = myGlCore20;
517       core13 = myGlCore20;
518       core14 = myGlCore20;
519     }
520   }
521
522   // initialize OpenGL 2.0 core functionality
523   if (IsGlGreaterEqual (2, 0))
524   {
525     if (!FindProcShort (myGlCore20, glBlendEquationSeparate)
526      || !FindProcShort (myGlCore20, glDrawBuffers)
527      || !FindProcShort (myGlCore20, glStencilOpSeparate)
528      || !FindProcShort (myGlCore20, glStencilFuncSeparate)
529      || !FindProcShort (myGlCore20, glStencilMaskSeparate)
530      || !FindProcShort (myGlCore20, glAttachShader)
531      || !FindProcShort (myGlCore20, glBindAttribLocation)
532      || !FindProcShort (myGlCore20, glCompileShader)
533      || !FindProcShort (myGlCore20, glCreateProgram)
534      || !FindProcShort (myGlCore20, glCreateShader)
535      || !FindProcShort (myGlCore20, glDeleteProgram)
536      || !FindProcShort (myGlCore20, glDeleteShader)
537      || !FindProcShort (myGlCore20, glDetachShader)
538      || !FindProcShort (myGlCore20, glDisableVertexAttribArray)
539      || !FindProcShort (myGlCore20, glEnableVertexAttribArray)
540      || !FindProcShort (myGlCore20, glGetActiveAttrib)
541      || !FindProcShort (myGlCore20, glGetActiveUniform)
542      || !FindProcShort (myGlCore20, glGetAttachedShaders)
543      || !FindProcShort (myGlCore20, glGetAttribLocation)
544      || !FindProcShort (myGlCore20, glGetProgramiv)
545      || !FindProcShort (myGlCore20, glGetProgramInfoLog)
546      || !FindProcShort (myGlCore20, glGetShaderiv)
547      || !FindProcShort (myGlCore20, glGetShaderInfoLog)
548      || !FindProcShort (myGlCore20, glGetShaderSource)
549      || !FindProcShort (myGlCore20, glGetUniformLocation)
550      || !FindProcShort (myGlCore20, glGetUniformfv)
551      || !FindProcShort (myGlCore20, glGetUniformiv)
552      || !FindProcShort (myGlCore20, glGetVertexAttribdv)
553      || !FindProcShort (myGlCore20, glGetVertexAttribfv)
554      || !FindProcShort (myGlCore20, glGetVertexAttribiv)
555      || !FindProcShort (myGlCore20, glGetVertexAttribPointerv)
556      || !FindProcShort (myGlCore20, glIsProgram)
557      || !FindProcShort (myGlCore20, glIsShader)
558      || !FindProcShort (myGlCore20, glLinkProgram)
559      || !FindProcShort (myGlCore20, glShaderSource)
560      || !FindProcShort (myGlCore20, glUseProgram)
561      || !FindProcShort (myGlCore20, glUniform1f)
562      || !FindProcShort (myGlCore20, glUniform2f)
563      || !FindProcShort (myGlCore20, glUniform3f)
564      || !FindProcShort (myGlCore20, glUniform4f)
565      || !FindProcShort (myGlCore20, glUniform1i)
566      || !FindProcShort (myGlCore20, glUniform2i)
567      || !FindProcShort (myGlCore20, glUniform3i)
568      || !FindProcShort (myGlCore20, glUniform4i)
569      || !FindProcShort (myGlCore20, glUniform1fv)
570      || !FindProcShort (myGlCore20, glUniform2fv)
571      || !FindProcShort (myGlCore20, glUniform3fv)
572      || !FindProcShort (myGlCore20, glUniform4fv)
573      || !FindProcShort (myGlCore20, glUniform1iv)
574      || !FindProcShort (myGlCore20, glUniform2iv)
575      || !FindProcShort (myGlCore20, glUniform3iv)
576      || !FindProcShort (myGlCore20, glUniform4iv)
577      || !FindProcShort (myGlCore20, glUniformMatrix2fv)
578      || !FindProcShort (myGlCore20, glUniformMatrix3fv)
579      || !FindProcShort (myGlCore20, glUniformMatrix4fv)
580      || !FindProcShort (myGlCore20, glValidateProgram)
581      || !FindProcShort (myGlCore20, glVertexAttrib1d)
582      || !FindProcShort (myGlCore20, glVertexAttrib1dv)
583      || !FindProcShort (myGlCore20, glVertexAttrib1f)
584      || !FindProcShort (myGlCore20, glVertexAttrib1fv)
585      || !FindProcShort (myGlCore20, glVertexAttrib1s)
586      || !FindProcShort (myGlCore20, glVertexAttrib1sv)
587      || !FindProcShort (myGlCore20, glVertexAttrib2d)
588      || !FindProcShort (myGlCore20, glVertexAttrib2dv)
589      || !FindProcShort (myGlCore20, glVertexAttrib2f)
590      || !FindProcShort (myGlCore20, glVertexAttrib2fv)
591      || !FindProcShort (myGlCore20, glVertexAttrib2s)
592      || !FindProcShort (myGlCore20, glVertexAttrib2sv)
593      || !FindProcShort (myGlCore20, glVertexAttrib3d)
594      || !FindProcShort (myGlCore20, glVertexAttrib3dv)
595      || !FindProcShort (myGlCore20, glVertexAttrib3f)
596      || !FindProcShort (myGlCore20, glVertexAttrib3fv)
597      || !FindProcShort (myGlCore20, glVertexAttrib3s)
598      || !FindProcShort (myGlCore20, glVertexAttrib3sv)
599      || !FindProcShort (myGlCore20, glVertexAttrib4Nbv)
600      || !FindProcShort (myGlCore20, glVertexAttrib4Niv)
601      || !FindProcShort (myGlCore20, glVertexAttrib4Nsv)
602      || !FindProcShort (myGlCore20, glVertexAttrib4Nub)
603      || !FindProcShort (myGlCore20, glVertexAttrib4Nubv)
604      || !FindProcShort (myGlCore20, glVertexAttrib4Nuiv)
605      || !FindProcShort (myGlCore20, glVertexAttrib4Nusv)
606      || !FindProcShort (myGlCore20, glVertexAttrib4bv)
607      || !FindProcShort (myGlCore20, glVertexAttrib4d)
608      || !FindProcShort (myGlCore20, glVertexAttrib4dv)
609      || !FindProcShort (myGlCore20, glVertexAttrib4f)
610      || !FindProcShort (myGlCore20, glVertexAttrib4fv)
611      || !FindProcShort (myGlCore20, glVertexAttrib4iv)
612      || !FindProcShort (myGlCore20, glVertexAttrib4s)
613      || !FindProcShort (myGlCore20, glVertexAttrib4sv)
614      || !FindProcShort (myGlCore20, glVertexAttrib4ubv)
615      || !FindProcShort (myGlCore20, glVertexAttrib4uiv)
616      || !FindProcShort (myGlCore20, glVertexAttrib4usv)
617      || !FindProcShort (myGlCore20, glVertexAttribPointer))
618     {
619       myGlVerMajor = 1;
620       myGlVerMinor = 5;
621       core12 = myGlCore20;
622       core13 = myGlCore20;
623       core14 = myGlCore20;
624       core15 = myGlCore20;
625     }
626   }
627
628   if (IsGlGreaterEqual (2, 0))
629   {
630     core12 = myGlCore20;
631     core13 = myGlCore20;
632     core14 = myGlCore20;
633     core15 = myGlCore20;
634     core20 = myGlCore20;
635   }
636 }
637 // =======================================================================
638 // function : IsFeedback
639 // purpose  :
640 // =======================================================================
641 Standard_Boolean OpenGl_Context::IsFeedback() const
642 {
643   return myIsFeedback;
644 }
645
646 // =======================================================================
647 // function : SetFeedback
648 // purpose  :
649 // =======================================================================
650 void OpenGl_Context::SetFeedback (const Standard_Boolean theFeedbackOn)
651 {
652   myIsFeedback = theFeedbackOn;
653 }
654
655 // =======================================================================
656 // function : MemoryInfo
657 // purpose  :
658 // =======================================================================
659 Standard_Size OpenGl_Context::AvailableMemory() const
660 {
661   if (atiMem)
662   {
663     // this is actually information for VBO pool
664     // however because pools are mostly shared
665     // it can be used for total GPU memory estimations
666     GLint aMemInfo[4];
667     aMemInfo[0] = 0;
668     glGetIntegerv (GL_VBO_FREE_MEMORY_ATI, aMemInfo);
669     // returned value is in KiB, however this maybe changed in future
670     return Standard_Size(aMemInfo[0]) * 1024;
671   }
672   else if (nvxMem)
673   {
674     // current available dedicated video memory (in KiB), currently unused GPU memory
675     GLint aMemInfo = 0;
676     glGetIntegerv (GL_GPU_MEMORY_INFO_CURRENT_AVAILABLE_VIDMEM_NVX, &aMemInfo);
677     return Standard_Size(aMemInfo) * 1024;
678   }
679   return 0;
680 }
681
682 // =======================================================================
683 // function : MemoryInfo
684 // purpose  :
685 // =======================================================================
686 TCollection_AsciiString OpenGl_Context::MemoryInfo() const
687 {
688   TCollection_AsciiString anInfo;
689   if (atiMem)
690   {
691     GLint aValues[4];
692     memset (aValues, 0, sizeof(aValues));
693     glGetIntegerv (GL_VBO_FREE_MEMORY_ATI, aValues);
694
695     // total memory free in the pool
696     anInfo += TCollection_AsciiString ("  GPU free memory:    ") + (aValues[0] / 1024) + " MiB\n";
697
698     // largest available free block in the pool
699     anInfo += TCollection_AsciiString ("  Largest free block: ") + (aValues[1] / 1024) + " MiB\n";
700     if (aValues[2] != aValues[0])
701     {
702       // total auxiliary memory free
703       anInfo += TCollection_AsciiString ("  Free memory:        ") + (aValues[2] / 1024) + " MiB\n";
704     }
705   }
706   else if (nvxMem)
707   {
708     //current available dedicated video memory (in KiB), currently unused GPU memory
709     GLint aValue = 0;
710     glGetIntegerv (GL_GPU_MEMORY_INFO_CURRENT_AVAILABLE_VIDMEM_NVX, &aValue);
711     anInfo += TCollection_AsciiString ("  GPU free memory:    ") + (aValue / 1024) + " MiB\n";
712
713     // dedicated video memory, total size (in KiB) of the GPU memory
714     GLint aDedicated = 0;
715     glGetIntegerv (GL_GPU_MEMORY_INFO_DEDICATED_VIDMEM_NVX, &aDedicated);
716     anInfo += TCollection_AsciiString ("  GPU memory:         ") + (aDedicated / 1024) + " MiB\n";
717
718     // total available memory, total size (in KiB) of the memory available for allocations
719     glGetIntegerv (GL_GPU_MEMORY_INFO_TOTAL_AVAILABLE_MEMORY_NVX, &aValue);
720     if (aValue != aDedicated)
721     {
722       // different only for special configurations
723       anInfo += TCollection_AsciiString ("  Total memory:       ") + (aValue / 1024) + " MiB\n";
724     }
725   }
726   return anInfo;
727 }