1 // Created on: 2012-01-26
2 // Created by: Kirill GAVRILOV
3 // Copyright (c) 2012-2012 OPEN CASCADE SAS
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.
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.
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.
21 #if (defined(_WIN32) || defined(__WIN32__))
25 #include <OpenGl_Context.hxx>
27 #include <OpenGl_ArbVBO.hxx>
28 #include <OpenGl_ArbTBO.hxx>
29 #include <OpenGl_ArbIns.hxx>
30 #include <OpenGl_ExtFBO.hxx>
31 #include <OpenGl_GlCore20.hxx>
33 #include <Standard_ProgramError.hxx>
35 #if (defined(_WIN32) || defined(__WIN32__))
37 #elif defined(__APPLE__) && !defined(MACOSX_USE_GLX)
40 #include <GL/glx.h> // glXGetProcAddress()
43 // GL_NVX_gpu_memory_info
44 #ifndef GL_GPU_MEMORY_INFO_DEDICATED_VIDMEM_NVX
47 GL_GPU_MEMORY_INFO_DEDICATED_VIDMEM_NVX = 0x9047,
48 GL_GPU_MEMORY_INFO_TOTAL_AVAILABLE_MEMORY_NVX = 0x9048,
49 GL_GPU_MEMORY_INFO_CURRENT_AVAILABLE_VIDMEM_NVX = 0x9049,
50 GL_GPU_MEMORY_INFO_EVICTION_COUNT_NVX = 0x904A,
51 GL_GPU_MEMORY_INFO_EVICTED_MEMORY_NVX = 0x904B
55 IMPLEMENT_STANDARD_HANDLE (OpenGl_Context, Standard_Transient)
56 IMPLEMENT_STANDARD_RTTIEXT(OpenGl_Context, Standard_Transient)
58 //! Make record shorter to retrieve function pointer using variable with same name
59 #define FindProcShort(theStruct, theFunc) FindProc(#theFunc, theStruct->theFunc)
63 static const Handle(OpenGl_Resource) NULL_GL_RESOURCE;
66 // =======================================================================
67 // function : OpenGl_Context
69 // =======================================================================
70 OpenGl_Context::OpenGl_Context()
80 atiMem (Standard_False),
81 nvxMem (Standard_False),
82 mySharedResources (new OpenGl_ResourcesMap()),
83 myReleaseQueue (new OpenGl_ResourcesQueue()),
88 myIsFeedback (Standard_False),
89 myIsInitialized (Standard_False)
91 #if defined(MAC_OS_X_VERSION_10_3) && !defined(MACOSX_USE_GLX)
92 // Vendors can not extend functionality on this system
93 // and developers are limited to OpenGL support provided by Mac OS X SDK.
94 // We retrieve function pointers from system library
95 // to generalize extensions support on all platforms.
96 // In this way we also reach binary compatibility benefit between OS releases
97 // if some newest functionality is optionally used.
98 // Notice that GL version / extension availability checks are required
99 // because function pointers may be available but not functionality itself
100 // (depends on renderer).
101 myGlLibHandle = dlopen ("/System/Library/Frameworks/OpenGL.framework/Versions/Current/OpenGL", RTLD_LAZY);
105 // =======================================================================
106 // function : ~OpenGl_Context
108 // =======================================================================
109 OpenGl_Context::~OpenGl_Context()
111 // release clean up queue
114 // release shared resources if any
115 if (((const Handle(Standard_Transient)& )mySharedResources)->GetRefCount() <= 1)
117 for (NCollection_DataMap<TCollection_AsciiString, Handle(OpenGl_Resource)>::Iterator anIter (*mySharedResources);
118 anIter.More(); anIter.Next())
120 anIter.Value()->Release (this);
123 mySharedResources.Nullify();
130 // =======================================================================
133 // =======================================================================
134 void OpenGl_Context::Share (const Handle(OpenGl_Context)& theShareCtx)
136 if (!theShareCtx.IsNull())
138 mySharedResources = theShareCtx->mySharedResources;
139 myReleaseQueue = theShareCtx->myReleaseQueue;
143 // =======================================================================
144 // function : IsCurrent
146 // =======================================================================
147 Standard_Boolean OpenGl_Context::IsCurrent() const
149 #if (defined(_WIN32) || defined(__WIN32__))
150 if (myWindowDC == NULL || myGContext == NULL)
152 return Standard_False;
154 return (( (HDC )myWindowDC == wglGetCurrentDC())
155 && ((HGLRC )myGContext == wglGetCurrentContext()));
157 if (myDisplay == NULL || myWindow == 0 || myGContext == 0)
159 return Standard_False;
162 return ( ((Display* )myDisplay == glXGetCurrentDisplay())
163 && ((GLXContext )myGContext == glXGetCurrentContext())
164 && ((GLXDrawable )myWindow == glXGetCurrentDrawable()));
168 // =======================================================================
169 // function : MakeCurrent
171 // =======================================================================
172 Standard_Boolean OpenGl_Context::MakeCurrent()
174 #if (defined(_WIN32) || defined(__WIN32__))
175 if (myWindowDC == NULL || myGContext == NULL)
177 Standard_ProgramError_Raise_if (myIsInitialized, "OpenGl_Context::Init() should be called before!");
178 return Standard_False;
181 // technically it should be safe to activate already bound GL context
182 // however some drivers (Intel etc.) may FAIL doing this for unknown reason
185 return Standard_True;
187 else if (wglMakeCurrent ((HDC )myWindowDC, (HGLRC )myGContext) != TRUE)
189 // notice that glGetError() couldn't be used here!
190 wchar_t* aMsgBuff = NULL;
191 DWORD anErrorCode = GetLastError();
192 FormatMessageW (FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
193 NULL, anErrorCode, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (wchar_t* )&aMsgBuff, 0, NULL);
194 if (aMsgBuff != NULL)
196 std::wcerr << L"OpenGL interface: wglMakeCurrent() failed. " << aMsgBuff << L" (" << int(anErrorCode) << L")\n";
197 LocalFree (aMsgBuff);
201 std::wcerr << L"OpenGL interface: wglMakeCurrent() failed with #" << int(anErrorCode) << L" error code\n";
203 return Standard_False;
206 if (myDisplay == NULL || myWindow == 0 || myGContext == 0)
208 Standard_ProgramError_Raise_if (myIsInitialized, "OpenGl_Context::Init() should be called before!");
209 return Standard_False;
212 if (!glXMakeCurrent ((Display* )myDisplay, (GLXDrawable )myWindow, (GLXContext )myGContext))
214 // if there is no current context it might be impossible to use glGetError() correctly
215 //std::cerr << "glXMakeCurrent() failed!\n";
216 return Standard_False;
219 return Standard_True;
222 // =======================================================================
223 // function : SwapBuffers
225 // =======================================================================
226 void OpenGl_Context::SwapBuffers()
228 #if (defined(_WIN32) || defined(__WIN32__))
229 if ((HDC )myWindowDC != NULL)
231 ::SwapBuffers ((HDC )myWindowDC);
235 if ((Display* )myDisplay != NULL)
237 glXSwapBuffers ((Display* )myDisplay, (GLXDrawable )myWindow);
242 // =======================================================================
243 // function : findProc
245 // =======================================================================
246 void* OpenGl_Context::findProc (const char* theFuncName)
248 #if (defined(_WIN32) || defined(__WIN32__))
249 return wglGetProcAddress (theFuncName);
250 #elif defined(__APPLE__) && !defined(MACOSX_USE_GLX)
251 return (myGlLibHandle != NULL) ? dlsym (myGlLibHandle, theFuncName) : NULL;
253 return (void* )glXGetProcAddress ((const GLubyte* )theFuncName);
257 // =======================================================================
258 // function : CheckExtension
260 // =======================================================================
261 Standard_Boolean OpenGl_Context::CheckExtension (const char* theExtName) const
263 if (theExtName == NULL)
265 std::cerr << "CheckExtension called with NULL string!\n";
266 return Standard_False;
268 int anExtNameLen = strlen (theExtName);
270 // available since OpenGL 3.0
271 // and the ONLY way to check extensions with OpenGL 3.1+ core profile
272 /**if (IsGlGreaterEqual (3, 0))
275 glGetIntegerv (GL_NUM_EXTENSIONS, &anExtNb);
276 for (GLint anIter = 0; anIter < anExtNb; ++anIter)
278 const char* anExtension = (const char* )core30->glGetStringi (GL_EXTENSIONS, (GLuint )anIter);
279 if (anExtension[anExtNameLen] == '\0' &&
280 strncmp (anExtension, theExtName, anExtNameLen) == 0)
282 return Standard_True;
285 return Standard_False;
288 // use old way with huge string for all extensions
289 const char* anExtString = (const char* )glGetString (GL_EXTENSIONS);
290 if (anExtString == NULL)
292 std::cerr << "glGetString (GL_EXTENSIONS) returns NULL! No GL context?\n";
293 return Standard_False;
296 // Search for theExtName in the extensions string.
297 // Use of strstr() is not sufficient because extension names can be prefixes of other extension names.
298 char* aPtrIter = (char* )anExtString;
299 const char* aPtrEnd = aPtrIter + strlen (anExtString);
300 while (aPtrIter < aPtrEnd)
302 int n = strcspn (aPtrIter, " ");
303 if ((n == anExtNameLen) && (strncmp (aPtrIter, theExtName, anExtNameLen) == 0))
305 return Standard_True;
309 return Standard_False;
312 // =======================================================================
315 // =======================================================================
316 Standard_Boolean OpenGl_Context::Init()
320 return Standard_True;
323 #if (defined(_WIN32) || defined(__WIN32__))
324 myWindowDC = (Aspect_Handle )wglGetCurrentDC();
325 myGContext = (Aspect_RenderingContext )wglGetCurrentContext();
327 myDisplay = (Aspect_Display )glXGetCurrentDisplay();
328 myGContext = (Aspect_RenderingContext )glXGetCurrentContext();
329 myWindow = (Aspect_Drawable )glXGetCurrentDrawable();
331 if (myGContext == NULL)
333 return Standard_False;
337 myIsInitialized = Standard_True;
338 return Standard_True;
341 // =======================================================================
344 // =======================================================================
345 #if (defined(_WIN32) || defined(__WIN32__))
346 Standard_Boolean OpenGl_Context::Init (const Aspect_Handle theWindow,
347 const Aspect_Handle theWindowDC,
348 const Aspect_RenderingContext theGContext)
350 Standard_Boolean OpenGl_Context::Init (const Aspect_Drawable theWindow,
351 const Aspect_Display theDisplay,
352 const Aspect_RenderingContext theGContext)
355 Standard_ProgramError_Raise_if (myIsInitialized, "OpenGl_Context::Init() should be called only once!");
357 myWindow = theWindow;
358 myGContext = theGContext;
359 #if (defined(_WIN32) || defined(__WIN32__))
360 myWindowDC = theWindowDC;
362 myDisplay = theDisplay;
364 if (myGContext == NULL || !MakeCurrent())
366 return Standard_False;
370 myIsInitialized = Standard_True;
371 return Standard_True;
374 // =======================================================================
375 // function : ResetErrors
377 // =======================================================================
378 void OpenGl_Context::ResetErrors()
380 while (glGetError() != GL_NO_ERROR)
386 // =======================================================================
387 // function : readGlVersion
389 // =======================================================================
390 void OpenGl_Context::readGlVersion()
396 // available since OpenGL 3.0
397 GLint aMajor, aMinor;
398 glGetIntegerv (GL_MAJOR_VERSION, &aMajor);
399 glGetIntegerv (GL_MINOR_VERSION, &aMinor);
400 if (glGetError() == GL_NO_ERROR)
402 myGlVerMajor = aMajor;
403 myGlVerMinor = aMinor;
408 // Read version string.
409 // Notice that only first two numbers splitted by point '2.1 XXXXX' are significant.
410 // Following trash (after space) is vendor-specific.
411 // New drivers also returns micro version of GL like '3.3.0' which has no meaning
412 // and should be considered as vendor-specific too.
413 const char* aVerStr = (const char* )glGetString (GL_VERSION);
414 if (aVerStr == NULL || *aVerStr == '\0')
416 // invalid GL context
420 // parse string for major number
424 while (aVerStr[aMajIter] >= '0' && aVerStr[aMajIter] <= '9')
428 if (aMajIter == 0 || aMajIter >= sizeof(aMajorStr))
432 memcpy (aMajorStr, aVerStr, aMajIter);
433 aMajorStr[aMajIter] = '\0';
435 // parse string for minor number
436 size_t aMinIter = aMajIter + 1;
437 while (aVerStr[aMinIter] >= '0' && aVerStr[aMinIter] <= '9')
441 size_t aMinLen = aMinIter - aMajIter - 1;
442 if (aMinLen == 0 || aMinLen >= sizeof(aMinorStr))
446 memcpy (aMinorStr, aVerStr, aMinLen);
447 aMinorStr[aMinLen] = '\0';
450 myGlVerMajor = atoi (aMajorStr);
451 myGlVerMinor = atoi (aMinorStr);
453 if (myGlVerMajor <= 0)
460 // =======================================================================
463 // =======================================================================
464 void OpenGl_Context::init()
469 atiMem = CheckExtension ("GL_ATI_meminfo");
470 nvxMem = CheckExtension ("GL_NVX_gpu_memory_info");
472 // initialize VBO extension (ARB)
473 if (CheckExtension ("GL_ARB_vertex_buffer_object"))
475 arbVBO = new OpenGl_ArbVBO();
476 memset (arbVBO, 0, sizeof(OpenGl_ArbVBO)); // nullify whole structure
477 if (!FindProcShort (arbVBO, glGenBuffersARB)
478 || !FindProcShort (arbVBO, glBindBufferARB)
479 || !FindProcShort (arbVBO, glBufferDataARB)
480 || !FindProcShort (arbVBO, glDeleteBuffersARB))
487 // initialize TBO extension (ARB)
488 if (CheckExtension ("GL_ARB_texture_buffer_object"))
490 arbTBO = new OpenGl_ArbTBO();
491 memset (arbTBO, 0, sizeof(OpenGl_ArbTBO)); // nullify whole structure
492 if (!FindProcShort (arbTBO, glTexBufferARB))
499 // initialize hardware instancing extension (ARB)
500 if (CheckExtension ("GL_ARB_draw_instanced"))
502 arbIns = new OpenGl_ArbIns();
503 memset (arbIns, 0, sizeof(OpenGl_ArbIns)); // nullify whole structure
504 if (!FindProcShort (arbIns, glDrawArraysInstancedARB)
505 || !FindProcShort (arbIns, glDrawElementsInstancedARB))
512 // initialize FBO extension (EXT)
513 if (CheckExtension ("GL_EXT_framebuffer_object"))
515 extFBO = new OpenGl_ExtFBO();
516 memset (extFBO, 0, sizeof(OpenGl_ExtFBO)); // nullify whole structure
517 if (!FindProcShort (extFBO, glGenFramebuffersEXT)
518 || !FindProcShort (extFBO, glDeleteFramebuffersEXT)
519 || !FindProcShort (extFBO, glBindFramebufferEXT)
520 || !FindProcShort (extFBO, glFramebufferTexture2DEXT)
521 || !FindProcShort (extFBO, glCheckFramebufferStatusEXT)
522 || !FindProcShort (extFBO, glGenRenderbuffersEXT)
523 || !FindProcShort (extFBO, glDeleteRenderbuffersEXT)
524 || !FindProcShort (extFBO, glBindRenderbufferEXT)
525 || !FindProcShort (extFBO, glRenderbufferStorageEXT)
526 || !FindProcShort (extFBO, glFramebufferRenderbufferEXT))
533 myGlCore20 = new OpenGl_GlCore20();
534 memset (myGlCore20, 0, sizeof(OpenGl_GlCore20)); // nullify whole structure
536 // initialize OpenGL 1.2 core functionality
537 if (IsGlGreaterEqual (1, 2))
539 if (!FindProcShort (myGlCore20, glBlendColor)
540 || !FindProcShort (myGlCore20, glBlendEquation)
541 || !FindProcShort (myGlCore20, glDrawRangeElements)
542 || !FindProcShort (myGlCore20, glTexImage3D)
543 || !FindProcShort (myGlCore20, glTexSubImage3D)
544 || !FindProcShort (myGlCore20, glCopyTexSubImage3D))
551 // initialize OpenGL 1.3 core functionality
552 if (IsGlGreaterEqual (1, 3))
554 if (!FindProcShort (myGlCore20, glActiveTexture)
555 || !FindProcShort (myGlCore20, glSampleCoverage)
556 || !FindProcShort (myGlCore20, glCompressedTexImage3D)
557 || !FindProcShort (myGlCore20, glCompressedTexImage2D)
558 || !FindProcShort (myGlCore20, glCompressedTexImage1D)
559 || !FindProcShort (myGlCore20, glCompressedTexSubImage3D)
560 || !FindProcShort (myGlCore20, glCompressedTexSubImage2D)
561 || !FindProcShort (myGlCore20, glCompressedTexSubImage1D)
562 || !FindProcShort (myGlCore20, glGetCompressedTexImage)
564 || !FindProcShort (myGlCore20, glClientActiveTexture)
565 || !FindProcShort (myGlCore20, glMultiTexCoord1d)
566 || !FindProcShort (myGlCore20, glMultiTexCoord1dv)
567 || !FindProcShort (myGlCore20, glMultiTexCoord1f)
568 || !FindProcShort (myGlCore20, glMultiTexCoord1fv)
569 || !FindProcShort (myGlCore20, glMultiTexCoord1i)
570 || !FindProcShort (myGlCore20, glMultiTexCoord1iv)
571 || !FindProcShort (myGlCore20, glMultiTexCoord1s)
572 || !FindProcShort (myGlCore20, glMultiTexCoord1sv)
573 || !FindProcShort (myGlCore20, glMultiTexCoord2d)
574 || !FindProcShort (myGlCore20, glMultiTexCoord2dv)
575 || !FindProcShort (myGlCore20, glMultiTexCoord2f)
576 || !FindProcShort (myGlCore20, glMultiTexCoord2fv)
577 || !FindProcShort (myGlCore20, glMultiTexCoord2i)
578 || !FindProcShort (myGlCore20, glMultiTexCoord2iv)
579 || !FindProcShort (myGlCore20, glMultiTexCoord2s)
580 || !FindProcShort (myGlCore20, glMultiTexCoord2sv)
581 || !FindProcShort (myGlCore20, glMultiTexCoord3d)
582 || !FindProcShort (myGlCore20, glMultiTexCoord3dv)
583 || !FindProcShort (myGlCore20, glMultiTexCoord3f)
584 || !FindProcShort (myGlCore20, glMultiTexCoord3fv)
585 || !FindProcShort (myGlCore20, glMultiTexCoord3i)
586 || !FindProcShort (myGlCore20, glMultiTexCoord3iv)
587 || !FindProcShort (myGlCore20, glMultiTexCoord3s)
588 || !FindProcShort (myGlCore20, glMultiTexCoord3sv)
589 || !FindProcShort (myGlCore20, glMultiTexCoord4d)
590 || !FindProcShort (myGlCore20, glMultiTexCoord4dv)
591 || !FindProcShort (myGlCore20, glMultiTexCoord4f)
592 || !FindProcShort (myGlCore20, glMultiTexCoord4fv)
593 || !FindProcShort (myGlCore20, glMultiTexCoord4i)
594 || !FindProcShort (myGlCore20, glMultiTexCoord4iv)
595 || !FindProcShort (myGlCore20, glMultiTexCoord4s)
596 || !FindProcShort (myGlCore20, glMultiTexCoord4sv)
597 || !FindProcShort (myGlCore20, glLoadTransposeMatrixf)
598 || !FindProcShort (myGlCore20, glLoadTransposeMatrixd)
599 || !FindProcShort (myGlCore20, glMultTransposeMatrixf)
600 || !FindProcShort (myGlCore20, glMultTransposeMatrixd))
608 // initialize OpenGL 1.4 core functionality
609 if (IsGlGreaterEqual (1, 4))
611 if (!FindProcShort (myGlCore20, glBlendFuncSeparate)
612 || !FindProcShort (myGlCore20, glMultiDrawArrays)
613 || !FindProcShort (myGlCore20, glMultiDrawElements)
614 || !FindProcShort (myGlCore20, glPointParameterf)
615 || !FindProcShort (myGlCore20, glPointParameterfv)
616 || !FindProcShort (myGlCore20, glPointParameteri)
617 || !FindProcShort (myGlCore20, glPointParameteriv))
626 // initialize OpenGL 1.5 core functionality
627 if (IsGlGreaterEqual (1, 5))
629 if (!FindProcShort (myGlCore20, glGenQueries)
630 || !FindProcShort (myGlCore20, glDeleteQueries)
631 || !FindProcShort (myGlCore20, glIsQuery)
632 || !FindProcShort (myGlCore20, glBeginQuery)
633 || !FindProcShort (myGlCore20, glEndQuery)
634 || !FindProcShort (myGlCore20, glGetQueryiv)
635 || !FindProcShort (myGlCore20, glGetQueryObjectiv)
636 || !FindProcShort (myGlCore20, glGetQueryObjectuiv)
637 || !FindProcShort (myGlCore20, glBindBuffer)
638 || !FindProcShort (myGlCore20, glDeleteBuffers)
639 || !FindProcShort (myGlCore20, glGenBuffers)
640 || !FindProcShort (myGlCore20, glIsBuffer)
641 || !FindProcShort (myGlCore20, glBufferData)
642 || !FindProcShort (myGlCore20, glBufferSubData)
643 || !FindProcShort (myGlCore20, glGetBufferSubData)
644 || !FindProcShort (myGlCore20, glMapBuffer)
645 || !FindProcShort (myGlCore20, glUnmapBuffer)
646 || !FindProcShort (myGlCore20, glGetBufferParameteriv)
647 || !FindProcShort (myGlCore20, glGetBufferPointerv))
657 // initialize OpenGL 2.0 core functionality
658 if (IsGlGreaterEqual (2, 0))
660 if (!FindProcShort (myGlCore20, glBlendEquationSeparate)
661 || !FindProcShort (myGlCore20, glDrawBuffers)
662 || !FindProcShort (myGlCore20, glStencilOpSeparate)
663 || !FindProcShort (myGlCore20, glStencilFuncSeparate)
664 || !FindProcShort (myGlCore20, glStencilMaskSeparate)
665 || !FindProcShort (myGlCore20, glAttachShader)
666 || !FindProcShort (myGlCore20, glBindAttribLocation)
667 || !FindProcShort (myGlCore20, glCompileShader)
668 || !FindProcShort (myGlCore20, glCreateProgram)
669 || !FindProcShort (myGlCore20, glCreateShader)
670 || !FindProcShort (myGlCore20, glDeleteProgram)
671 || !FindProcShort (myGlCore20, glDeleteShader)
672 || !FindProcShort (myGlCore20, glDetachShader)
673 || !FindProcShort (myGlCore20, glDisableVertexAttribArray)
674 || !FindProcShort (myGlCore20, glEnableVertexAttribArray)
675 || !FindProcShort (myGlCore20, glGetActiveAttrib)
676 || !FindProcShort (myGlCore20, glGetActiveUniform)
677 || !FindProcShort (myGlCore20, glGetAttachedShaders)
678 || !FindProcShort (myGlCore20, glGetAttribLocation)
679 || !FindProcShort (myGlCore20, glGetProgramiv)
680 || !FindProcShort (myGlCore20, glGetProgramInfoLog)
681 || !FindProcShort (myGlCore20, glGetShaderiv)
682 || !FindProcShort (myGlCore20, glGetShaderInfoLog)
683 || !FindProcShort (myGlCore20, glGetShaderSource)
684 || !FindProcShort (myGlCore20, glGetUniformLocation)
685 || !FindProcShort (myGlCore20, glGetUniformfv)
686 || !FindProcShort (myGlCore20, glGetUniformiv)
687 || !FindProcShort (myGlCore20, glGetVertexAttribdv)
688 || !FindProcShort (myGlCore20, glGetVertexAttribfv)
689 || !FindProcShort (myGlCore20, glGetVertexAttribiv)
690 || !FindProcShort (myGlCore20, glGetVertexAttribPointerv)
691 || !FindProcShort (myGlCore20, glIsProgram)
692 || !FindProcShort (myGlCore20, glIsShader)
693 || !FindProcShort (myGlCore20, glLinkProgram)
694 || !FindProcShort (myGlCore20, glShaderSource)
695 || !FindProcShort (myGlCore20, glUseProgram)
696 || !FindProcShort (myGlCore20, glUniform1f)
697 || !FindProcShort (myGlCore20, glUniform2f)
698 || !FindProcShort (myGlCore20, glUniform3f)
699 || !FindProcShort (myGlCore20, glUniform4f)
700 || !FindProcShort (myGlCore20, glUniform1i)
701 || !FindProcShort (myGlCore20, glUniform2i)
702 || !FindProcShort (myGlCore20, glUniform3i)
703 || !FindProcShort (myGlCore20, glUniform4i)
704 || !FindProcShort (myGlCore20, glUniform1fv)
705 || !FindProcShort (myGlCore20, glUniform2fv)
706 || !FindProcShort (myGlCore20, glUniform3fv)
707 || !FindProcShort (myGlCore20, glUniform4fv)
708 || !FindProcShort (myGlCore20, glUniform1iv)
709 || !FindProcShort (myGlCore20, glUniform2iv)
710 || !FindProcShort (myGlCore20, glUniform3iv)
711 || !FindProcShort (myGlCore20, glUniform4iv)
712 || !FindProcShort (myGlCore20, glUniformMatrix2fv)
713 || !FindProcShort (myGlCore20, glUniformMatrix3fv)
714 || !FindProcShort (myGlCore20, glUniformMatrix4fv)
715 || !FindProcShort (myGlCore20, glValidateProgram)
716 || !FindProcShort (myGlCore20, glVertexAttrib1d)
717 || !FindProcShort (myGlCore20, glVertexAttrib1dv)
718 || !FindProcShort (myGlCore20, glVertexAttrib1f)
719 || !FindProcShort (myGlCore20, glVertexAttrib1fv)
720 || !FindProcShort (myGlCore20, glVertexAttrib1s)
721 || !FindProcShort (myGlCore20, glVertexAttrib1sv)
722 || !FindProcShort (myGlCore20, glVertexAttrib2d)
723 || !FindProcShort (myGlCore20, glVertexAttrib2dv)
724 || !FindProcShort (myGlCore20, glVertexAttrib2f)
725 || !FindProcShort (myGlCore20, glVertexAttrib2fv)
726 || !FindProcShort (myGlCore20, glVertexAttrib2s)
727 || !FindProcShort (myGlCore20, glVertexAttrib2sv)
728 || !FindProcShort (myGlCore20, glVertexAttrib3d)
729 || !FindProcShort (myGlCore20, glVertexAttrib3dv)
730 || !FindProcShort (myGlCore20, glVertexAttrib3f)
731 || !FindProcShort (myGlCore20, glVertexAttrib3fv)
732 || !FindProcShort (myGlCore20, glVertexAttrib3s)
733 || !FindProcShort (myGlCore20, glVertexAttrib3sv)
734 || !FindProcShort (myGlCore20, glVertexAttrib4Nbv)
735 || !FindProcShort (myGlCore20, glVertexAttrib4Niv)
736 || !FindProcShort (myGlCore20, glVertexAttrib4Nsv)
737 || !FindProcShort (myGlCore20, glVertexAttrib4Nub)
738 || !FindProcShort (myGlCore20, glVertexAttrib4Nubv)
739 || !FindProcShort (myGlCore20, glVertexAttrib4Nuiv)
740 || !FindProcShort (myGlCore20, glVertexAttrib4Nusv)
741 || !FindProcShort (myGlCore20, glVertexAttrib4bv)
742 || !FindProcShort (myGlCore20, glVertexAttrib4d)
743 || !FindProcShort (myGlCore20, glVertexAttrib4dv)
744 || !FindProcShort (myGlCore20, glVertexAttrib4f)
745 || !FindProcShort (myGlCore20, glVertexAttrib4fv)
746 || !FindProcShort (myGlCore20, glVertexAttrib4iv)
747 || !FindProcShort (myGlCore20, glVertexAttrib4s)
748 || !FindProcShort (myGlCore20, glVertexAttrib4sv)
749 || !FindProcShort (myGlCore20, glVertexAttrib4ubv)
750 || !FindProcShort (myGlCore20, glVertexAttrib4uiv)
751 || !FindProcShort (myGlCore20, glVertexAttrib4usv)
752 || !FindProcShort (myGlCore20, glVertexAttribPointer))
763 if (IsGlGreaterEqual (2, 0))
772 // =======================================================================
773 // function : IsFeedback
775 // =======================================================================
776 Standard_Boolean OpenGl_Context::IsFeedback() const
781 // =======================================================================
782 // function : SetFeedback
784 // =======================================================================
785 void OpenGl_Context::SetFeedback (const Standard_Boolean theFeedbackOn)
787 myIsFeedback = theFeedbackOn;
790 // =======================================================================
791 // function : MemoryInfo
793 // =======================================================================
794 Standard_Size OpenGl_Context::AvailableMemory() const
798 // this is actually information for VBO pool
799 // however because pools are mostly shared
800 // it can be used for total GPU memory estimations
803 glGetIntegerv (GL_VBO_FREE_MEMORY_ATI, aMemInfo);
804 // returned value is in KiB, however this maybe changed in future
805 return Standard_Size(aMemInfo[0]) * 1024;
809 // current available dedicated video memory (in KiB), currently unused GPU memory
811 glGetIntegerv (GL_GPU_MEMORY_INFO_CURRENT_AVAILABLE_VIDMEM_NVX, &aMemInfo);
812 return Standard_Size(aMemInfo) * 1024;
817 // =======================================================================
818 // function : MemoryInfo
820 // =======================================================================
821 TCollection_AsciiString OpenGl_Context::MemoryInfo() const
823 TCollection_AsciiString anInfo;
827 memset (aValues, 0, sizeof(aValues));
828 glGetIntegerv (GL_VBO_FREE_MEMORY_ATI, aValues);
830 // total memory free in the pool
831 anInfo += TCollection_AsciiString (" GPU free memory: ") + (aValues[0] / 1024) + " MiB\n";
833 // largest available free block in the pool
834 anInfo += TCollection_AsciiString (" Largest free block: ") + (aValues[1] / 1024) + " MiB\n";
835 if (aValues[2] != aValues[0])
837 // total auxiliary memory free
838 anInfo += TCollection_AsciiString (" Free memory: ") + (aValues[2] / 1024) + " MiB\n";
843 //current available dedicated video memory (in KiB), currently unused GPU memory
845 glGetIntegerv (GL_GPU_MEMORY_INFO_CURRENT_AVAILABLE_VIDMEM_NVX, &aValue);
846 anInfo += TCollection_AsciiString (" GPU free memory: ") + (aValue / 1024) + " MiB\n";
848 // dedicated video memory, total size (in KiB) of the GPU memory
849 GLint aDedicated = 0;
850 glGetIntegerv (GL_GPU_MEMORY_INFO_DEDICATED_VIDMEM_NVX, &aDedicated);
851 anInfo += TCollection_AsciiString (" GPU memory: ") + (aDedicated / 1024) + " MiB\n";
853 // total available memory, total size (in KiB) of the memory available for allocations
854 glGetIntegerv (GL_GPU_MEMORY_INFO_TOTAL_AVAILABLE_MEMORY_NVX, &aValue);
855 if (aValue != aDedicated)
857 // different only for special configurations
858 anInfo += TCollection_AsciiString (" Total memory: ") + (aValue / 1024) + " MiB\n";
865 // =======================================================================
866 // function : GetResource
868 // =======================================================================
869 const Handle(OpenGl_Resource)& OpenGl_Context::GetResource (const TCollection_AsciiString& theKey) const
871 return mySharedResources->IsBound (theKey) ? mySharedResources->Find (theKey) : NULL_GL_RESOURCE;
874 // =======================================================================
875 // function : ShareResource
877 // =======================================================================
878 Standard_Boolean OpenGl_Context::ShareResource (const TCollection_AsciiString& theKey,
879 const Handle(OpenGl_Resource)& theResource)
881 if (theKey.IsEmpty() || theResource.IsNull())
883 return Standard_False;
885 return mySharedResources->Bind (theKey, theResource);
888 // =======================================================================
889 // function : ReleaseResource
891 // =======================================================================
892 void OpenGl_Context::ReleaseResource (const TCollection_AsciiString& theKey)
894 if (!mySharedResources->IsBound (theKey))
898 const Handle(OpenGl_Resource)& aRes = mySharedResources->Find (theKey);
899 if (aRes->GetRefCount() > 1)
904 aRes->Release (this);
905 mySharedResources->UnBind (theKey);
908 // =======================================================================
909 // function : DelayedRelease
911 // =======================================================================
912 void OpenGl_Context::DelayedRelease (Handle(OpenGl_Resource)& theResource)
914 myReleaseQueue->Push (theResource);
915 theResource.Nullify();
918 // =======================================================================
919 // function : ReleaseDelayed
921 // =======================================================================
922 void OpenGl_Context::ReleaseDelayed()
924 while (!myReleaseQueue->IsEmpty())
926 myReleaseQueue->Front()->Release (this);
927 myReleaseQueue->Pop();