1 // Created on: 2012-01-26
2 // Created by: Kirill GAVRILOV
3 // Copyright (c) 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.
24 #include <OpenGl_Context.hxx>
26 #include <OpenGl_ArbVBO.hxx>
27 #include <OpenGl_ArbTBO.hxx>
28 #include <OpenGl_ArbIns.hxx>
29 #include <OpenGl_ArbDbg.hxx>
30 #include <OpenGl_ExtFBO.hxx>
31 #include <OpenGl_ExtGS.hxx>
32 #include <OpenGl_GlCore20.hxx>
34 #include <NCollection_Vector.hxx>
36 #include <Standard_ProgramError.hxx>
40 #elif defined(__APPLE__) && !defined(MACOSX_USE_GLX)
43 #include <GL/glx.h> // glXGetProcAddress()
46 // GL_NVX_gpu_memory_info
47 #ifndef GL_GPU_MEMORY_INFO_DEDICATED_VIDMEM_NVX
50 GL_GPU_MEMORY_INFO_DEDICATED_VIDMEM_NVX = 0x9047,
51 GL_GPU_MEMORY_INFO_TOTAL_AVAILABLE_MEMORY_NVX = 0x9048,
52 GL_GPU_MEMORY_INFO_CURRENT_AVAILABLE_VIDMEM_NVX = 0x9049,
53 GL_GPU_MEMORY_INFO_EVICTION_COUNT_NVX = 0x904A,
54 GL_GPU_MEMORY_INFO_EVICTED_MEMORY_NVX = 0x904B
58 IMPLEMENT_STANDARD_HANDLE (OpenGl_Context, Standard_Transient)
59 IMPLEMENT_STANDARD_RTTIEXT(OpenGl_Context, Standard_Transient)
61 //! Make record shorter to retrieve function pointer using variable with same name
62 #define FindProcShort(theStruct, theFunc) FindProc(#theFunc, theStruct->theFunc)
66 static const Handle(OpenGl_Resource) NULL_GL_RESOURCE;
67 static const GLdouble OpenGl_DefaultPlaneEq[] = {0.0, 0.0, 0.0, 0.0};
70 // =======================================================================
71 // function : OpenGl_Context
73 // =======================================================================
74 OpenGl_Context::OpenGl_Context (const Handle(OpenGl_Caps)& theCaps)
80 caps (!theCaps.IsNull() ? theCaps : new OpenGl_Caps()),
81 arbNPTW(Standard_False),
88 extBgra(Standard_False),
89 extAnis(Standard_False),
90 atiMem (Standard_False),
91 nvxMem (Standard_False),
92 mySharedResources (new OpenGl_ResourcesMap()),
93 myDelayed (new OpenGl_DelayReleaseMap()),
94 myReleaseQueue (new OpenGl_ResourcesQueue()),
103 myIsFeedback (Standard_False),
104 myIsInitialized (Standard_False)
106 #if defined(MAC_OS_X_VERSION_10_3) && !defined(MACOSX_USE_GLX)
107 // Vendors can not extend functionality on this system
108 // and developers are limited to OpenGL support provided by Mac OS X SDK.
109 // We retrieve function pointers from system library
110 // to generalize extensions support on all platforms.
111 // In this way we also reach binary compatibility benefit between OS releases
112 // if some newest functionality is optionally used.
113 // Notice that GL version / extension availability checks are required
114 // because function pointers may be available but not functionality itself
115 // (depends on renderer).
116 myGlLibHandle = dlopen ("/System/Library/Frameworks/OpenGL.framework/Versions/Current/OpenGL", RTLD_LAZY);
120 // =======================================================================
121 // function : ~OpenGl_Context
123 // =======================================================================
124 OpenGl_Context::~OpenGl_Context()
126 // release clean up queue
129 // release shared resources if any
130 if (((const Handle(Standard_Transient)& )mySharedResources)->GetRefCount() <= 1)
132 for (NCollection_DataMap<TCollection_AsciiString, Handle(OpenGl_Resource)>::Iterator anIter (*mySharedResources);
133 anIter.More(); anIter.Next())
135 anIter.Value()->Release (this);
138 mySharedResources.Nullify();
150 // =======================================================================
151 // function : MaxDegreeOfAnisotropy
153 // =======================================================================
154 Standard_Integer OpenGl_Context::MaxDegreeOfAnisotropy() const
159 // =======================================================================
160 // function : MaxTextureSize
162 // =======================================================================
163 Standard_Integer OpenGl_Context::MaxTextureSize() const
168 // =======================================================================
169 // function : MaxClipPlanes
171 // =======================================================================
172 Standard_Integer OpenGl_Context::MaxClipPlanes() const
174 return myMaxClipPlanes;
177 // =======================================================================
180 // =======================================================================
181 void OpenGl_Context::Share (const Handle(OpenGl_Context)& theShareCtx)
183 if (!theShareCtx.IsNull())
185 mySharedResources = theShareCtx->mySharedResources;
186 myDelayed = theShareCtx->myDelayed;
187 myReleaseQueue = theShareCtx->myReleaseQueue;
191 #if !defined(__APPLE__) || defined(MACOSX_USE_GLX)
193 // =======================================================================
194 // function : IsCurrent
196 // =======================================================================
197 Standard_Boolean OpenGl_Context::IsCurrent() const
200 if (myWindowDC == NULL || myGContext == NULL)
202 return Standard_False;
204 return (( (HDC )myWindowDC == wglGetCurrentDC())
205 && ((HGLRC )myGContext == wglGetCurrentContext()));
207 if (myDisplay == NULL || myWindow == 0 || myGContext == 0)
209 return Standard_False;
212 return ( ((Display* )myDisplay == glXGetCurrentDisplay())
213 && ((GLXContext )myGContext == glXGetCurrentContext())
214 && ((GLXDrawable )myWindow == glXGetCurrentDrawable()));
218 // =======================================================================
219 // function : MakeCurrent
221 // =======================================================================
222 Standard_Boolean OpenGl_Context::MakeCurrent()
225 if (myWindowDC == NULL || myGContext == NULL)
227 Standard_ProgramError_Raise_if (myIsInitialized, "OpenGl_Context::Init() should be called before!");
228 return Standard_False;
231 // technically it should be safe to activate already bound GL context
232 // however some drivers (Intel etc.) may FAIL doing this for unknown reason
235 return Standard_True;
237 else if (wglMakeCurrent ((HDC )myWindowDC, (HGLRC )myGContext) != TRUE)
239 // notice that glGetError() couldn't be used here!
240 wchar_t* aMsgBuff = NULL;
241 DWORD anErrorCode = GetLastError();
242 FormatMessageW (FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
243 NULL, anErrorCode, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (wchar_t* )&aMsgBuff, 0, NULL);
244 if (aMsgBuff != NULL)
246 std::wcerr << L"OpenGL interface: wglMakeCurrent() failed. " << aMsgBuff << L" (" << int(anErrorCode) << L")\n";
247 LocalFree (aMsgBuff);
251 std::wcerr << L"OpenGL interface: wglMakeCurrent() failed with #" << int(anErrorCode) << L" error code\n";
253 return Standard_False;
256 if (myDisplay == NULL || myWindow == 0 || myGContext == 0)
258 Standard_ProgramError_Raise_if (myIsInitialized, "OpenGl_Context::Init() should be called before!");
259 return Standard_False;
262 if (!glXMakeCurrent ((Display* )myDisplay, (GLXDrawable )myWindow, (GLXContext )myGContext))
264 // if there is no current context it might be impossible to use glGetError() correctly
265 //std::cerr << "glXMakeCurrent() failed!\n";
266 return Standard_False;
269 return Standard_True;
272 // =======================================================================
273 // function : SwapBuffers
275 // =======================================================================
276 void OpenGl_Context::SwapBuffers()
279 if ((HDC )myWindowDC != NULL)
281 ::SwapBuffers ((HDC )myWindowDC);
285 if ((Display* )myDisplay != NULL)
287 glXSwapBuffers ((Display* )myDisplay, (GLXDrawable )myWindow);
294 // =======================================================================
295 // function : findProc
297 // =======================================================================
298 void* OpenGl_Context::findProc (const char* theFuncName)
301 return wglGetProcAddress (theFuncName);
302 #elif defined(__APPLE__) && !defined(MACOSX_USE_GLX)
303 return (myGlLibHandle != NULL) ? dlsym (myGlLibHandle, theFuncName) : NULL;
305 return (void* )glXGetProcAddress ((const GLubyte* )theFuncName);
309 // =======================================================================
310 // function : CheckExtension
312 // =======================================================================
313 Standard_Boolean OpenGl_Context::CheckExtension (const char* theExtName) const
315 if (theExtName == NULL)
317 std::cerr << "CheckExtension called with NULL string!\n";
318 return Standard_False;
321 // available since OpenGL 3.0
322 // and the ONLY way to check extensions with OpenGL 3.1+ core profile
323 /**if (IsGlGreaterEqual (3, 0))
326 glGetIntegerv (GL_NUM_EXTENSIONS, &anExtNb);
327 for (GLint anIter = 0; anIter < anExtNb; ++anIter)
329 const char* anExtension = (const char* )core30->glGetStringi (GL_EXTENSIONS, (GLuint )anIter);
330 if (anExtension[anExtNameLen] == '\0' &&
331 strncmp (anExtension, theExtName, anExtNameLen) == 0)
333 return Standard_True;
336 return Standard_False;
339 // use old way with huge string for all extensions
340 const char* anExtString = (const char* )glGetString (GL_EXTENSIONS);
341 if (anExtString == NULL)
343 std::cerr << "glGetString (GL_EXTENSIONS) returns NULL! No GL context?\n";
344 return Standard_False;
346 return CheckExtension (anExtString, theExtName);
349 // =======================================================================
350 // function : CheckExtension
352 // =======================================================================
353 Standard_Boolean OpenGl_Context::CheckExtension (const char* theExtString,
354 const char* theExtName)
356 if (theExtString == NULL)
358 return Standard_False;
361 // Search for theExtName in the extensions string.
362 // Use of strstr() is not sufficient because extension names can be prefixes of other extension names.
363 char* aPtrIter = (char* )theExtString;
364 const char* aPtrEnd = aPtrIter + strlen (theExtString);
365 const size_t anExtNameLen = strlen (theExtName);
366 while (aPtrIter < aPtrEnd)
368 const size_t n = strcspn (aPtrIter, " ");
369 if ((n == anExtNameLen) && (strncmp (aPtrIter, theExtName, anExtNameLen) == 0))
371 return Standard_True;
375 return Standard_False;
378 #if !defined(__APPLE__) || defined(MACOSX_USE_GLX)
380 // =======================================================================
383 // =======================================================================
384 Standard_Boolean OpenGl_Context::Init()
388 return Standard_True;
392 myWindowDC = (Aspect_Handle )wglGetCurrentDC();
393 myGContext = (Aspect_RenderingContext )wglGetCurrentContext();
395 myDisplay = (Aspect_Display )glXGetCurrentDisplay();
396 myGContext = (Aspect_RenderingContext )glXGetCurrentContext();
397 myWindow = (Aspect_Drawable )glXGetCurrentDrawable();
399 if (myGContext == NULL)
401 return Standard_False;
405 myIsInitialized = Standard_True;
406 return Standard_True;
411 // =======================================================================
414 // =======================================================================
416 Standard_Boolean OpenGl_Context::Init (const Aspect_Handle theWindow,
417 const Aspect_Handle theWindowDC,
418 const Aspect_RenderingContext theGContext)
419 #elif defined(__APPLE__) && !defined(MACOSX_USE_GLX)
420 Standard_Boolean OpenGl_Context::Init (const void* theGContext)
422 Standard_Boolean OpenGl_Context::Init (const Aspect_Drawable theWindow,
423 const Aspect_Display theDisplay,
424 const Aspect_RenderingContext theGContext)
427 Standard_ProgramError_Raise_if (myIsInitialized, "OpenGl_Context::Init() should be called only once!");
429 myWindow = theWindow;
430 myGContext = theGContext;
431 myWindowDC = theWindowDC;
432 #elif defined(__APPLE__) && !defined(MACOSX_USE_GLX)
433 myGContext = (void* )theGContext;
435 myWindow = theWindow;
436 myGContext = theGContext;
437 myDisplay = theDisplay;
439 if (myGContext == NULL || !MakeCurrent())
441 return Standard_False;
445 myIsInitialized = Standard_True;
446 return Standard_True;
449 // =======================================================================
450 // function : ResetErrors
452 // =======================================================================
453 void OpenGl_Context::ResetErrors()
455 while (glGetError() != GL_NO_ERROR)
461 // =======================================================================
462 // function : readGlVersion
464 // =======================================================================
465 void OpenGl_Context::readGlVersion()
471 // available since OpenGL 3.0
472 GLint aMajor = 0, aMinor = 0;
473 glGetIntegerv (GL_MAJOR_VERSION, &aMajor);
474 glGetIntegerv (GL_MINOR_VERSION, &aMinor);
475 // glGetError() sometimes does not report an error here even if
476 // GL does not know GL_MAJOR_VERSION and GL_MINOR_VERSION constants.
477 // This happens on some rendereres like e.g. Cygwin MESA.
478 // Thus checking additionally if GL has put anything to
479 // the output variables.
480 if (glGetError() == GL_NO_ERROR && aMajor != 0 && aMinor != 0)
482 myGlVerMajor = aMajor;
483 myGlVerMinor = aMinor;
488 // Read version string.
489 // Notice that only first two numbers splitted by point '2.1 XXXXX' are significant.
490 // Following trash (after space) is vendor-specific.
491 // New drivers also returns micro version of GL like '3.3.0' which has no meaning
492 // and should be considered as vendor-specific too.
493 const char* aVerStr = (const char* )glGetString (GL_VERSION);
494 if (aVerStr == NULL || *aVerStr == '\0')
496 // invalid GL context
500 // parse string for major number
504 while (aVerStr[aMajIter] >= '0' && aVerStr[aMajIter] <= '9')
508 if (aMajIter == 0 || aMajIter >= sizeof(aMajorStr))
512 memcpy (aMajorStr, aVerStr, aMajIter);
513 aMajorStr[aMajIter] = '\0';
515 // parse string for minor number
516 aVerStr += aMajIter + 1;
518 while (aVerStr[aMinIter] >= '0' && aVerStr[aMinIter] <= '9')
522 if (aMinIter == 0 || aMinIter >= sizeof(aMinorStr))
526 memcpy (aMinorStr, aVerStr, aMinIter);
527 aMinorStr[aMinIter] = '\0';
530 myGlVerMajor = atoi (aMajorStr);
531 myGlVerMinor = atoi (aMinorStr);
533 if (myGlVerMajor <= 0)
540 static Standard_CString THE_DBGMSG_UNKNOWN = "UNKNOWN";
541 static Standard_CString THE_DBGMSG_SOURCES[] =
543 "OpenGL", // GL_DEBUG_SOURCE_API_ARB
544 "Window System", // GL_DEBUG_SOURCE_WINDOW_SYSTEM_ARB
545 "Shader Compiler", // GL_DEBUG_SOURCE_SHADER_COMPILER_ARB
546 "Third Party", // GL_DEBUG_SOURCE_THIRD_PARTY_ARB
547 "Application", // GL_DEBUG_SOURCE_APPLICATION_ARB
548 "Other" // GL_DEBUG_SOURCE_OTHER_ARB
551 static Standard_CString THE_DBGMSG_TYPES[] =
553 "Error", // GL_DEBUG_TYPE_ERROR_ARB
554 "Deprecated", // GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR_ARB
555 "Undefined behavior", // GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR_ARB
556 "Portability", // GL_DEBUG_TYPE_PORTABILITY_ARB
557 "Performance", // GL_DEBUG_TYPE_PERFORMANCE_ARB
558 "Other" // GL_DEBUG_TYPE_OTHER_ARB
561 static Standard_CString THE_DBGMSG_SEV_HIGH = "High"; // GL_DEBUG_SEVERITY_HIGH_ARB
562 static Standard_CString THE_DBGMSG_SEV_MEDIUM = "Medium"; // GL_DEBUG_SEVERITY_MEDIUM_ARB
563 static Standard_CString THE_DBGMSG_SEV_LOW = "Low"; // GL_DEBUG_SEVERITY_LOW_ARB
565 static void APIENTRY debugCallbackWrap(unsigned int theSource,
566 unsigned int theType,
568 unsigned int theSeverity,
570 const char* theMessage,
571 void* /*theUserParam*/)
573 //OpenGl_Context* aCtx = (OpenGl_Context* )theUserParam;
574 Standard_CString& aSrc = (theSource >= GL_DEBUG_SOURCE_API_ARB
575 && theSource <= GL_DEBUG_SOURCE_OTHER_ARB)
576 ? THE_DBGMSG_SOURCES[theSource - GL_DEBUG_SOURCE_API_ARB]
577 : THE_DBGMSG_UNKNOWN;
578 Standard_CString& aType = (theType >= GL_DEBUG_TYPE_ERROR_ARB
579 && theType <= GL_DEBUG_TYPE_OTHER_ARB)
580 ? THE_DBGMSG_TYPES[theType - GL_DEBUG_TYPE_ERROR_ARB]
581 : THE_DBGMSG_UNKNOWN;
582 Standard_CString& aSev = theSeverity == GL_DEBUG_SEVERITY_HIGH_ARB
583 ? THE_DBGMSG_SEV_HIGH
584 : (theSeverity == GL_DEBUG_SEVERITY_MEDIUM_ARB
585 ? THE_DBGMSG_SEV_MEDIUM
586 : THE_DBGMSG_SEV_LOW);
587 std::cerr << "Source:" << aSrc
588 << " | Type:" << aType
590 << " | Severity:" << aSev
591 << " | Message:\n " << theMessage << "\n";
594 // =======================================================================
597 // =======================================================================
598 void OpenGl_Context::init()
603 arbNPTW = CheckExtension ("GL_ARB_texture_non_power_of_two");
604 extBgra = CheckExtension ("GL_EXT_bgra");
605 extAnis = CheckExtension ("GL_EXT_texture_filter_anisotropic");
606 atiMem = CheckExtension ("GL_ATI_meminfo");
607 nvxMem = CheckExtension ("GL_NVX_gpu_memory_info");
609 // get number of maximum clipping planes
610 glGetIntegerv (GL_MAX_CLIP_PLANES, &myMaxClipPlanes);
611 glGetIntegerv (GL_MAX_TEXTURE_SIZE, &myMaxTexDim);
614 glGetIntegerv (GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &myAnisoMax);
617 myClippingState.Init (myMaxClipPlanes);
619 // initialize debug context extension
620 if (CheckExtension ("GL_ARB_debug_output"))
622 arbDbg = new OpenGl_ArbDbg();
623 memset (arbDbg, 0, sizeof(OpenGl_ArbDbg)); // nullify whole structure
624 if (!FindProcShort (arbDbg, glDebugMessageControlARB)
625 || !FindProcShort (arbDbg, glDebugMessageInsertARB)
626 || !FindProcShort (arbDbg, glDebugMessageCallbackARB)
627 || !FindProcShort (arbDbg, glGetDebugMessageLogARB))
633 && caps->contextDebug)
635 // setup default callback
636 arbDbg->glDebugMessageCallbackARB (debugCallbackWrap, this);
637 glEnable (GL_DEBUG_OUTPUT_SYNCHRONOUS_ARB);
641 // initialize VBO extension (ARB)
642 if (CheckExtension ("GL_ARB_vertex_buffer_object"))
644 arbVBO = new OpenGl_ArbVBO();
645 memset (arbVBO, 0, sizeof(OpenGl_ArbVBO)); // nullify whole structure
646 if (!FindProcShort (arbVBO, glGenBuffersARB)
647 || !FindProcShort (arbVBO, glBindBufferARB)
648 || !FindProcShort (arbVBO, glBufferDataARB)
649 || !FindProcShort (arbVBO, glDeleteBuffersARB))
656 // initialize TBO extension (ARB)
657 if (CheckExtension ("GL_ARB_texture_buffer_object"))
659 arbTBO = new OpenGl_ArbTBO();
660 memset (arbTBO, 0, sizeof(OpenGl_ArbTBO)); // nullify whole structure
661 if (!FindProcShort (arbTBO, glTexBufferARB))
668 // initialize hardware instancing extension (ARB)
669 if (CheckExtension ("GL_ARB_draw_instanced"))
671 arbIns = new OpenGl_ArbIns();
672 memset (arbIns, 0, sizeof(OpenGl_ArbIns)); // nullify whole structure
673 if (!FindProcShort (arbIns, glDrawArraysInstancedARB)
674 || !FindProcShort (arbIns, glDrawElementsInstancedARB))
681 // initialize FBO extension (EXT)
682 if (CheckExtension ("GL_EXT_framebuffer_object"))
684 extFBO = new OpenGl_ExtFBO();
685 memset (extFBO, 0, sizeof(OpenGl_ExtFBO)); // nullify whole structure
686 if (!FindProcShort (extFBO, glGenFramebuffersEXT)
687 || !FindProcShort (extFBO, glDeleteFramebuffersEXT)
688 || !FindProcShort (extFBO, glBindFramebufferEXT)
689 || !FindProcShort (extFBO, glFramebufferTexture2DEXT)
690 || !FindProcShort (extFBO, glCheckFramebufferStatusEXT)
691 || !FindProcShort (extFBO, glGenRenderbuffersEXT)
692 || !FindProcShort (extFBO, glDeleteRenderbuffersEXT)
693 || !FindProcShort (extFBO, glBindRenderbufferEXT)
694 || !FindProcShort (extFBO, glRenderbufferStorageEXT)
695 || !FindProcShort (extFBO, glFramebufferRenderbufferEXT)
696 || !FindProcShort (extFBO, glGenerateMipmapEXT))
703 // initialize GS extension (EXT)
704 if (CheckExtension ("GL_EXT_geometry_shader4"))
706 extGS = new OpenGl_ExtGS();
707 memset (extGS, 0, sizeof(OpenGl_ExtGS)); // nullify whole structure
708 if (!FindProcShort (extGS, glProgramParameteriEXT))
715 myGlCore20 = new OpenGl_GlCore20();
716 memset (myGlCore20, 0, sizeof(OpenGl_GlCore20)); // nullify whole structure
718 // Check if OpenGL 1.2 core functionality is actually present
719 Standard_Boolean hasGlCore12 = IsGlGreaterEqual (1, 2)
720 && FindProcShort (myGlCore20, glBlendColor)
721 && FindProcShort (myGlCore20, glBlendEquation)
722 && FindProcShort (myGlCore20, glDrawRangeElements)
723 && FindProcShort (myGlCore20, glTexImage3D)
724 && FindProcShort (myGlCore20, glTexSubImage3D)
725 && FindProcShort (myGlCore20, glCopyTexSubImage3D);
727 // Check if OpenGL 1.3 core functionality is actually present
728 Standard_Boolean hasGlCore13 = IsGlGreaterEqual (1, 3)
729 && FindProcShort (myGlCore20, glActiveTexture)
730 && FindProcShort (myGlCore20, glSampleCoverage)
731 && FindProcShort (myGlCore20, glCompressedTexImage3D)
732 && FindProcShort (myGlCore20, glCompressedTexImage2D)
733 && FindProcShort (myGlCore20, glCompressedTexImage1D)
734 && FindProcShort (myGlCore20, glCompressedTexSubImage3D)
735 && FindProcShort (myGlCore20, glCompressedTexSubImage2D)
736 && FindProcShort (myGlCore20, glCompressedTexSubImage1D)
737 && FindProcShort (myGlCore20, glGetCompressedTexImage)
739 && FindProcShort (myGlCore20, glClientActiveTexture)
740 && FindProcShort (myGlCore20, glMultiTexCoord1d)
741 && FindProcShort (myGlCore20, glMultiTexCoord1dv)
742 && FindProcShort (myGlCore20, glMultiTexCoord1f)
743 && FindProcShort (myGlCore20, glMultiTexCoord1fv)
744 && FindProcShort (myGlCore20, glMultiTexCoord1i)
745 && FindProcShort (myGlCore20, glMultiTexCoord1iv)
746 && FindProcShort (myGlCore20, glMultiTexCoord1s)
747 && FindProcShort (myGlCore20, glMultiTexCoord1sv)
748 && FindProcShort (myGlCore20, glMultiTexCoord2d)
749 && FindProcShort (myGlCore20, glMultiTexCoord2dv)
750 && FindProcShort (myGlCore20, glMultiTexCoord2f)
751 && FindProcShort (myGlCore20, glMultiTexCoord2fv)
752 && FindProcShort (myGlCore20, glMultiTexCoord2i)
753 && FindProcShort (myGlCore20, glMultiTexCoord2iv)
754 && FindProcShort (myGlCore20, glMultiTexCoord2s)
755 && FindProcShort (myGlCore20, glMultiTexCoord2sv)
756 && FindProcShort (myGlCore20, glMultiTexCoord3d)
757 && FindProcShort (myGlCore20, glMultiTexCoord3dv)
758 && FindProcShort (myGlCore20, glMultiTexCoord3f)
759 && FindProcShort (myGlCore20, glMultiTexCoord3fv)
760 && FindProcShort (myGlCore20, glMultiTexCoord3i)
761 && FindProcShort (myGlCore20, glMultiTexCoord3iv)
762 && FindProcShort (myGlCore20, glMultiTexCoord3s)
763 && FindProcShort (myGlCore20, glMultiTexCoord3sv)
764 && FindProcShort (myGlCore20, glMultiTexCoord4d)
765 && FindProcShort (myGlCore20, glMultiTexCoord4dv)
766 && FindProcShort (myGlCore20, glMultiTexCoord4f)
767 && FindProcShort (myGlCore20, glMultiTexCoord4fv)
768 && FindProcShort (myGlCore20, glMultiTexCoord4i)
769 && FindProcShort (myGlCore20, glMultiTexCoord4iv)
770 && FindProcShort (myGlCore20, glMultiTexCoord4s)
771 && FindProcShort (myGlCore20, glMultiTexCoord4sv)
772 && FindProcShort (myGlCore20, glLoadTransposeMatrixf)
773 && FindProcShort (myGlCore20, glLoadTransposeMatrixd)
774 && FindProcShort (myGlCore20, glMultTransposeMatrixf)
775 && FindProcShort (myGlCore20, glMultTransposeMatrixd);
777 // Check if OpenGL 1.4 core functionality is actually present
778 Standard_Boolean hasGlCore14 = IsGlGreaterEqual (1, 4)
779 && FindProcShort (myGlCore20, glBlendFuncSeparate)
780 && FindProcShort (myGlCore20, glMultiDrawArrays)
781 && FindProcShort (myGlCore20, glMultiDrawElements)
782 && FindProcShort (myGlCore20, glPointParameterf)
783 && FindProcShort (myGlCore20, glPointParameterfv)
784 && FindProcShort (myGlCore20, glPointParameteri)
785 && FindProcShort (myGlCore20, glPointParameteriv);
787 // Check if OpenGL 1.5 core functionality is actually present
788 Standard_Boolean hasGlCore15 = IsGlGreaterEqual (1, 5)
789 && FindProcShort (myGlCore20, glGenQueries)
790 && FindProcShort (myGlCore20, glDeleteQueries)
791 && FindProcShort (myGlCore20, glIsQuery)
792 && FindProcShort (myGlCore20, glBeginQuery)
793 && FindProcShort (myGlCore20, glEndQuery)
794 && FindProcShort (myGlCore20, glGetQueryiv)
795 && FindProcShort (myGlCore20, glGetQueryObjectiv)
796 && FindProcShort (myGlCore20, glGetQueryObjectuiv)
797 && FindProcShort (myGlCore20, glBindBuffer)
798 && FindProcShort (myGlCore20, glDeleteBuffers)
799 && FindProcShort (myGlCore20, glGenBuffers)
800 && FindProcShort (myGlCore20, glIsBuffer)
801 && FindProcShort (myGlCore20, glBufferData)
802 && FindProcShort (myGlCore20, glBufferSubData)
803 && FindProcShort (myGlCore20, glGetBufferSubData)
804 && FindProcShort (myGlCore20, glMapBuffer)
805 && FindProcShort (myGlCore20, glUnmapBuffer)
806 && FindProcShort (myGlCore20, glGetBufferParameteriv)
807 && FindProcShort (myGlCore20, glGetBufferPointerv);
809 // Check if OpenGL 2.0 core functionality is actually present
810 Standard_Boolean hasGlCore20 = IsGlGreaterEqual (2, 0)
811 && FindProcShort (myGlCore20, glBlendEquationSeparate)
812 && FindProcShort (myGlCore20, glDrawBuffers)
813 && FindProcShort (myGlCore20, glStencilOpSeparate)
814 && FindProcShort (myGlCore20, glStencilFuncSeparate)
815 && FindProcShort (myGlCore20, glStencilMaskSeparate)
816 && FindProcShort (myGlCore20, glAttachShader)
817 && FindProcShort (myGlCore20, glBindAttribLocation)
818 && FindProcShort (myGlCore20, glCompileShader)
819 && FindProcShort (myGlCore20, glCreateProgram)
820 && FindProcShort (myGlCore20, glCreateShader)
821 && FindProcShort (myGlCore20, glDeleteProgram)
822 && FindProcShort (myGlCore20, glDeleteShader)
823 && FindProcShort (myGlCore20, glDetachShader)
824 && FindProcShort (myGlCore20, glDisableVertexAttribArray)
825 && FindProcShort (myGlCore20, glEnableVertexAttribArray)
826 && FindProcShort (myGlCore20, glGetActiveAttrib)
827 && FindProcShort (myGlCore20, glGetActiveUniform)
828 && FindProcShort (myGlCore20, glGetAttachedShaders)
829 && FindProcShort (myGlCore20, glGetAttribLocation)
830 && FindProcShort (myGlCore20, glGetProgramiv)
831 && FindProcShort (myGlCore20, glGetProgramInfoLog)
832 && FindProcShort (myGlCore20, glGetShaderiv)
833 && FindProcShort (myGlCore20, glGetShaderInfoLog)
834 && FindProcShort (myGlCore20, glGetShaderSource)
835 && FindProcShort (myGlCore20, glGetUniformLocation)
836 && FindProcShort (myGlCore20, glGetUniformfv)
837 && FindProcShort (myGlCore20, glGetUniformiv)
838 && FindProcShort (myGlCore20, glGetVertexAttribdv)
839 && FindProcShort (myGlCore20, glGetVertexAttribfv)
840 && FindProcShort (myGlCore20, glGetVertexAttribiv)
841 && FindProcShort (myGlCore20, glGetVertexAttribPointerv)
842 && FindProcShort (myGlCore20, glIsProgram)
843 && FindProcShort (myGlCore20, glIsShader)
844 && FindProcShort (myGlCore20, glLinkProgram)
845 && FindProcShort (myGlCore20, glShaderSource)
846 && FindProcShort (myGlCore20, glUseProgram)
847 && FindProcShort (myGlCore20, glUniform1f)
848 && FindProcShort (myGlCore20, glUniform2f)
849 && FindProcShort (myGlCore20, glUniform3f)
850 && FindProcShort (myGlCore20, glUniform4f)
851 && FindProcShort (myGlCore20, glUniform1i)
852 && FindProcShort (myGlCore20, glUniform2i)
853 && FindProcShort (myGlCore20, glUniform3i)
854 && FindProcShort (myGlCore20, glUniform4i)
855 && FindProcShort (myGlCore20, glUniform1fv)
856 && FindProcShort (myGlCore20, glUniform2fv)
857 && FindProcShort (myGlCore20, glUniform3fv)
858 && FindProcShort (myGlCore20, glUniform4fv)
859 && FindProcShort (myGlCore20, glUniform1iv)
860 && FindProcShort (myGlCore20, glUniform2iv)
861 && FindProcShort (myGlCore20, glUniform3iv)
862 && FindProcShort (myGlCore20, glUniform4iv)
863 && FindProcShort (myGlCore20, glUniformMatrix2fv)
864 && FindProcShort (myGlCore20, glUniformMatrix3fv)
865 && FindProcShort (myGlCore20, glUniformMatrix4fv)
866 && FindProcShort (myGlCore20, glValidateProgram)
867 && FindProcShort (myGlCore20, glVertexAttrib1d)
868 && FindProcShort (myGlCore20, glVertexAttrib1dv)
869 && FindProcShort (myGlCore20, glVertexAttrib1f)
870 && FindProcShort (myGlCore20, glVertexAttrib1fv)
871 && FindProcShort (myGlCore20, glVertexAttrib1s)
872 && FindProcShort (myGlCore20, glVertexAttrib1sv)
873 && FindProcShort (myGlCore20, glVertexAttrib2d)
874 && FindProcShort (myGlCore20, glVertexAttrib2dv)
875 && FindProcShort (myGlCore20, glVertexAttrib2f)
876 && FindProcShort (myGlCore20, glVertexAttrib2fv)
877 && FindProcShort (myGlCore20, glVertexAttrib2s)
878 && FindProcShort (myGlCore20, glVertexAttrib2sv)
879 && FindProcShort (myGlCore20, glVertexAttrib3d)
880 && FindProcShort (myGlCore20, glVertexAttrib3dv)
881 && FindProcShort (myGlCore20, glVertexAttrib3f)
882 && FindProcShort (myGlCore20, glVertexAttrib3fv)
883 && FindProcShort (myGlCore20, glVertexAttrib3s)
884 && FindProcShort (myGlCore20, glVertexAttrib3sv)
885 && FindProcShort (myGlCore20, glVertexAttrib4Nbv)
886 && FindProcShort (myGlCore20, glVertexAttrib4Niv)
887 && FindProcShort (myGlCore20, glVertexAttrib4Nsv)
888 && FindProcShort (myGlCore20, glVertexAttrib4Nub)
889 && FindProcShort (myGlCore20, glVertexAttrib4Nubv)
890 && FindProcShort (myGlCore20, glVertexAttrib4Nuiv)
891 && FindProcShort (myGlCore20, glVertexAttrib4Nusv)
892 && FindProcShort (myGlCore20, glVertexAttrib4bv)
893 && FindProcShort (myGlCore20, glVertexAttrib4d)
894 && FindProcShort (myGlCore20, glVertexAttrib4dv)
895 && FindProcShort (myGlCore20, glVertexAttrib4f)
896 && FindProcShort (myGlCore20, glVertexAttrib4fv)
897 && FindProcShort (myGlCore20, glVertexAttrib4iv)
898 && FindProcShort (myGlCore20, glVertexAttrib4s)
899 && FindProcShort (myGlCore20, glVertexAttrib4sv)
900 && FindProcShort (myGlCore20, glVertexAttrib4ubv)
901 && FindProcShort (myGlCore20, glVertexAttrib4uiv)
902 && FindProcShort (myGlCore20, glVertexAttrib4usv)
903 && FindProcShort (myGlCore20, glVertexAttribPointer);
955 // =======================================================================
956 // function : IsFeedback
958 // =======================================================================
959 Standard_Boolean OpenGl_Context::IsFeedback() const
964 // =======================================================================
965 // function : SetFeedback
967 // =======================================================================
968 void OpenGl_Context::SetFeedback (const Standard_Boolean theFeedbackOn)
970 myIsFeedback = theFeedbackOn;
973 // =======================================================================
974 // function : MemoryInfo
976 // =======================================================================
977 Standard_Size OpenGl_Context::AvailableMemory() const
981 // this is actually information for VBO pool
982 // however because pools are mostly shared
983 // it can be used for total GPU memory estimations
986 glGetIntegerv (GL_VBO_FREE_MEMORY_ATI, aMemInfo);
987 // returned value is in KiB, however this maybe changed in future
988 return Standard_Size(aMemInfo[0]) * 1024;
992 // current available dedicated video memory (in KiB), currently unused GPU memory
994 glGetIntegerv (GL_GPU_MEMORY_INFO_CURRENT_AVAILABLE_VIDMEM_NVX, &aMemInfo);
995 return Standard_Size(aMemInfo) * 1024;
1000 // =======================================================================
1001 // function : MemoryInfo
1003 // =======================================================================
1004 TCollection_AsciiString OpenGl_Context::MemoryInfo() const
1006 TCollection_AsciiString anInfo;
1010 memset (aValues, 0, sizeof(aValues));
1011 glGetIntegerv (GL_VBO_FREE_MEMORY_ATI, aValues);
1013 // total memory free in the pool
1014 anInfo += TCollection_AsciiString (" GPU free memory: ") + (aValues[0] / 1024) + " MiB\n";
1016 // largest available free block in the pool
1017 anInfo += TCollection_AsciiString (" Largest free block: ") + (aValues[1] / 1024) + " MiB\n";
1018 if (aValues[2] != aValues[0])
1020 // total auxiliary memory free
1021 anInfo += TCollection_AsciiString (" Free memory: ") + (aValues[2] / 1024) + " MiB\n";
1026 //current available dedicated video memory (in KiB), currently unused GPU memory
1028 glGetIntegerv (GL_GPU_MEMORY_INFO_CURRENT_AVAILABLE_VIDMEM_NVX, &aValue);
1029 anInfo += TCollection_AsciiString (" GPU free memory: ") + (aValue / 1024) + " MiB\n";
1031 // dedicated video memory, total size (in KiB) of the GPU memory
1032 GLint aDedicated = 0;
1033 glGetIntegerv (GL_GPU_MEMORY_INFO_DEDICATED_VIDMEM_NVX, &aDedicated);
1034 anInfo += TCollection_AsciiString (" GPU memory: ") + (aDedicated / 1024) + " MiB\n";
1036 // total available memory, total size (in KiB) of the memory available for allocations
1037 glGetIntegerv (GL_GPU_MEMORY_INFO_TOTAL_AVAILABLE_MEMORY_NVX, &aValue);
1038 if (aValue != aDedicated)
1040 // different only for special configurations
1041 anInfo += TCollection_AsciiString (" Total memory: ") + (aValue / 1024) + " MiB\n";
1048 // =======================================================================
1049 // function : GetResource
1051 // =======================================================================
1052 const Handle(OpenGl_Resource)& OpenGl_Context::GetResource (const TCollection_AsciiString& theKey) const
1054 return mySharedResources->IsBound (theKey) ? mySharedResources->Find (theKey) : NULL_GL_RESOURCE;
1057 // =======================================================================
1058 // function : ShareResource
1060 // =======================================================================
1061 Standard_Boolean OpenGl_Context::ShareResource (const TCollection_AsciiString& theKey,
1062 const Handle(OpenGl_Resource)& theResource)
1064 if (theKey.IsEmpty() || theResource.IsNull())
1066 return Standard_False;
1068 return mySharedResources->Bind (theKey, theResource);
1071 // =======================================================================
1072 // function : ReleaseResource
1074 // =======================================================================
1075 void OpenGl_Context::ReleaseResource (const TCollection_AsciiString& theKey,
1076 const Standard_Boolean theToDelay)
1078 if (!mySharedResources->IsBound (theKey))
1082 const Handle(OpenGl_Resource)& aRes = mySharedResources->Find (theKey);
1083 if (aRes->GetRefCount() > 1)
1090 myDelayed->Bind (theKey, 1);
1094 aRes->Release (this);
1095 mySharedResources->UnBind (theKey);
1099 // =======================================================================
1100 // function : DelayedRelease
1102 // =======================================================================
1103 void OpenGl_Context::DelayedRelease (Handle(OpenGl_Resource)& theResource)
1105 myReleaseQueue->Push (theResource);
1106 theResource.Nullify();
1109 // =======================================================================
1110 // function : ReleaseDelayed
1112 // =======================================================================
1113 void OpenGl_Context::ReleaseDelayed()
1115 // release queued elements
1116 while (!myReleaseQueue->IsEmpty())
1118 myReleaseQueue->Front()->Release (this);
1119 myReleaseQueue->Pop();
1122 // release delayed shared resoruces
1123 NCollection_Vector<TCollection_AsciiString> aDeadList;
1124 for (NCollection_DataMap<TCollection_AsciiString, Standard_Integer>::Iterator anIter (*myDelayed);
1125 anIter.More(); anIter.Next())
1127 if (++anIter.ChangeValue() <= 2)
1129 continue; // postpone release one more frame to ensure noone use it periodically
1132 const TCollection_AsciiString& aKey = anIter.Key();
1133 if (!mySharedResources->IsBound (aKey))
1135 // mixed unshared strategy delayed/undelayed was used!
1136 aDeadList.Append (aKey);
1140 Handle(OpenGl_Resource)& aRes = mySharedResources->ChangeFind (aKey);
1141 if (aRes->GetRefCount() > 1)
1143 // should be only 1 instance in mySharedResources
1144 // if not - resource was reused again
1145 aDeadList.Append (aKey);
1149 // release resource if no one requiested it more than 2 redraw calls
1150 aRes->Release (this);
1151 mySharedResources->UnBind (aKey);
1152 aDeadList.Append (aKey);
1155 for (Standard_Integer anIter = 0; anIter < aDeadList.Length(); ++anIter)
1157 myDelayed->UnBind (aDeadList.Value (anIter));