0023546: Test report failure in Debug mode due to debug messages
[occt.git] / src / OpenGl / OpenGl_Context.cxx
CommitLineData
b311480e 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
2166f0fa 20
5f8b738e 21#if (defined(_WIN32) || defined(__WIN32__))
22 #include <windows.h>
23#endif
24
2166f0fa
SK
25#include <OpenGl_Context.hxx>
26
5f8b738e 27#include <OpenGl_ArbVBO.hxx>
5e27df78 28#include <OpenGl_ArbTBO.hxx>
29#include <OpenGl_ArbIns.hxx>
5f8b738e 30#include <OpenGl_ExtFBO.hxx>
37eb4787 31#include <OpenGl_ExtGS.hxx>
5f8b738e 32#include <OpenGl_GlCore20.hxx>
33
2bd4c032 34#include <Standard_ProgramError.hxx>
35
5f8b738e 36#if (defined(_WIN32) || defined(__WIN32__))
37 //
38#elif defined(__APPLE__) && !defined(MACOSX_USE_GLX)
39 #include <dlfcn.h>
40#else
41 #include <GL/glx.h> // glXGetProcAddress()
42#endif
43
f0430952 44// GL_NVX_gpu_memory_info
45#ifndef GL_GPU_MEMORY_INFO_DEDICATED_VIDMEM_NVX
46 enum
47 {
48 GL_GPU_MEMORY_INFO_DEDICATED_VIDMEM_NVX = 0x9047,
49 GL_GPU_MEMORY_INFO_TOTAL_AVAILABLE_MEMORY_NVX = 0x9048,
50 GL_GPU_MEMORY_INFO_CURRENT_AVAILABLE_VIDMEM_NVX = 0x9049,
51 GL_GPU_MEMORY_INFO_EVICTION_COUNT_NVX = 0x904A,
52 GL_GPU_MEMORY_INFO_EVICTED_MEMORY_NVX = 0x904B
53 };
54#endif
55
2166f0fa
SK
56IMPLEMENT_STANDARD_HANDLE (OpenGl_Context, Standard_Transient)
57IMPLEMENT_STANDARD_RTTIEXT(OpenGl_Context, Standard_Transient)
58
5f8b738e 59//! Make record shorter to retrieve function pointer using variable with same name
60#define FindProcShort(theStruct, theFunc) FindProc(#theFunc, theStruct->theFunc)
2166f0fa 61
5e27df78 62namespace
63{
64 static const Handle(OpenGl_Resource) NULL_GL_RESOURCE;
65};
66
2166f0fa
SK
67// =======================================================================
68// function : OpenGl_Context
69// purpose :
70// =======================================================================
71OpenGl_Context::OpenGl_Context()
5f8b738e 72: core12 (NULL),
73 core13 (NULL),
74 core14 (NULL),
75 core15 (NULL),
76 core20 (NULL),
77 arbVBO (NULL),
5e27df78 78 arbTBO (NULL),
79 arbIns (NULL),
5f8b738e 80 extFBO (NULL),
37eb4787 81 extGS (NULL),
f0430952 82 atiMem (Standard_False),
83 nvxMem (Standard_False),
5e27df78 84 mySharedResources (new OpenGl_ResourcesMap()),
85 myReleaseQueue (new OpenGl_ResourcesQueue()),
5f8b738e 86 myGlLibHandle (NULL),
87 myGlCore20 (NULL),
88 myGlVerMajor (0),
89 myGlVerMinor (0),
664cae74 90 myIsFeedback (Standard_False),
5f8b738e 91 myIsInitialized (Standard_False)
2166f0fa 92{
5f8b738e 93#if defined(MAC_OS_X_VERSION_10_3) && !defined(MACOSX_USE_GLX)
94 // Vendors can not extend functionality on this system
95 // and developers are limited to OpenGL support provided by Mac OS X SDK.
96 // We retrieve function pointers from system library
97 // to generalize extensions support on all platforms.
98 // In this way we also reach binary compatibility benefit between OS releases
99 // if some newest functionality is optionally used.
100 // Notice that GL version / extension availability checks are required
101 // because function pointers may be available but not functionality itself
102 // (depends on renderer).
103 myGlLibHandle = dlopen ("/System/Library/Frameworks/OpenGL.framework/Versions/Current/OpenGL", RTLD_LAZY);
104#endif
2166f0fa
SK
105}
106
107// =======================================================================
108// function : ~OpenGl_Context
109// purpose :
110// =======================================================================
111OpenGl_Context::~OpenGl_Context()
112{
5e27df78 113 // release clean up queue
114 ReleaseDelayed();
115
116 // release shared resources if any
117 if (((const Handle(Standard_Transient)& )mySharedResources)->GetRefCount() <= 1)
118 {
119 for (NCollection_DataMap<TCollection_AsciiString, Handle(OpenGl_Resource)>::Iterator anIter (*mySharedResources);
120 anIter.More(); anIter.Next())
121 {
122 anIter.Value()->Release (this);
123 }
124 }
125 mySharedResources.Nullify();
126
5f8b738e 127 delete myGlCore20;
128 delete arbVBO;
129 delete extFBO;
37eb4787 130 delete extGS;
5f8b738e 131}
132
133// =======================================================================
5e27df78 134// function : Share
135// purpose :
136// =======================================================================
137void OpenGl_Context::Share (const Handle(OpenGl_Context)& theShareCtx)
138{
139 if (!theShareCtx.IsNull())
140 {
141 mySharedResources = theShareCtx->mySharedResources;
142 myReleaseQueue = theShareCtx->myReleaseQueue;
143 }
144}
145
146// =======================================================================
86fa64d9 147// function : IsCurrent
148// purpose :
149// =======================================================================
150Standard_Boolean OpenGl_Context::IsCurrent() const
151{
152#if (defined(_WIN32) || defined(__WIN32__))
153 if (myWindowDC == NULL || myGContext == NULL)
154 {
155 return Standard_False;
156 }
157 return (( (HDC )myWindowDC == wglGetCurrentDC())
158 && ((HGLRC )myGContext == wglGetCurrentContext()));
159#else
160 if (myDisplay == NULL || myWindow == 0 || myGContext == 0)
161 {
162 return Standard_False;
163 }
164
165 return ( ((Display* )myDisplay == glXGetCurrentDisplay())
166 && ((GLXContext )myGContext == glXGetCurrentContext())
167 && ((GLXDrawable )myWindow == glXGetCurrentDrawable()));
168#endif
169}
170
171// =======================================================================
2bd4c032 172// function : MakeCurrent
173// purpose :
174// =======================================================================
175Standard_Boolean OpenGl_Context::MakeCurrent()
176{
177#if (defined(_WIN32) || defined(__WIN32__))
86fa64d9 178 if (myWindowDC == NULL || myGContext == NULL)
2bd4c032 179 {
86fa64d9 180 Standard_ProgramError_Raise_if (myIsInitialized, "OpenGl_Context::Init() should be called before!");
181 return Standard_False;
182 }
183
184 // technically it should be safe to activate already bound GL context
185 // however some drivers (Intel etc.) may FAIL doing this for unknown reason
186 if (IsCurrent())
187 {
188 return Standard_True;
189 }
190 else if (wglMakeCurrent ((HDC )myWindowDC, (HGLRC )myGContext) != TRUE)
191 {
192 // notice that glGetError() couldn't be used here!
193 wchar_t* aMsgBuff = NULL;
194 DWORD anErrorCode = GetLastError();
195 FormatMessageW (FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
196 NULL, anErrorCode, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (wchar_t* )&aMsgBuff, 0, NULL);
197 if (aMsgBuff != NULL)
198 {
199 std::wcerr << L"OpenGL interface: wglMakeCurrent() failed. " << aMsgBuff << L" (" << int(anErrorCode) << L")\n";
200 LocalFree (aMsgBuff);
201 }
202 else
203 {
204 std::wcerr << L"OpenGL interface: wglMakeCurrent() failed with #" << int(anErrorCode) << L" error code\n";
205 }
2bd4c032 206 return Standard_False;
207 }
208#else
86fa64d9 209 if (myDisplay == NULL || myWindow == 0 || myGContext == 0)
210 {
211 Standard_ProgramError_Raise_if (myIsInitialized, "OpenGl_Context::Init() should be called before!");
212 return Standard_False;
213 }
214
215 if (!glXMakeCurrent ((Display* )myDisplay, (GLXDrawable )myWindow, (GLXContext )myGContext))
2bd4c032 216 {
217 // if there is no current context it might be impossible to use glGetError() correctly
218 //std::cerr << "glXMakeCurrent() failed!\n";
219 return Standard_False;
220 }
221#endif
222 return Standard_True;
223}
224
225// =======================================================================
5e27df78 226// function : SwapBuffers
227// purpose :
228// =======================================================================
229void OpenGl_Context::SwapBuffers()
230{
231#if (defined(_WIN32) || defined(__WIN32__))
232 if ((HDC )myWindowDC != NULL)
233 {
234 ::SwapBuffers ((HDC )myWindowDC);
235 glFlush();
236 }
237#else
238 if ((Display* )myDisplay != NULL)
239 {
240 glXSwapBuffers ((Display* )myDisplay, (GLXDrawable )myWindow);
241 }
242#endif
243}
244
245// =======================================================================
5f8b738e 246// function : findProc
247// purpose :
248// =======================================================================
249void* OpenGl_Context::findProc (const char* theFuncName)
250{
251#if (defined(_WIN32) || defined(__WIN32__))
252 return wglGetProcAddress (theFuncName);
253#elif defined(__APPLE__) && !defined(MACOSX_USE_GLX)
254 return (myGlLibHandle != NULL) ? dlsym (myGlLibHandle, theFuncName) : NULL;
255#else
256 return (void* )glXGetProcAddress ((const GLubyte* )theFuncName);
257#endif
2166f0fa
SK
258}
259
260// =======================================================================
261// function : CheckExtension
262// purpose :
263// =======================================================================
2bd4c032 264Standard_Boolean OpenGl_Context::CheckExtension (const char* theExtName) const
2166f0fa 265{
5f8b738e 266 if (theExtName == NULL)
267 {
268 std::cerr << "CheckExtension called with NULL string!\n";
269 return Standard_False;
270 }
271 int anExtNameLen = strlen (theExtName);
272
273 // available since OpenGL 3.0
274 // and the ONLY way to check extensions with OpenGL 3.1+ core profile
2bd4c032 275 /**if (IsGlGreaterEqual (3, 0))
5f8b738e 276 {
277 GLint anExtNb = 0;
278 glGetIntegerv (GL_NUM_EXTENSIONS, &anExtNb);
279 for (GLint anIter = 0; anIter < anExtNb; ++anIter)
280 {
281 const char* anExtension = (const char* )core30->glGetStringi (GL_EXTENSIONS, (GLuint )anIter);
282 if (anExtension[anExtNameLen] == '\0' &&
283 strncmp (anExtension, theExtName, anExtNameLen) == 0)
284 {
285 return Standard_True;
286 }
287 }
288 return Standard_False;
289 }*/
290
291 // use old way with huge string for all extensions
292 const char* anExtString = (const char* )glGetString (GL_EXTENSIONS);
293 if (anExtString == NULL)
294 {
295 std::cerr << "glGetString (GL_EXTENSIONS) returns NULL! No GL context?\n";
2166f0fa
SK
296 return Standard_False;
297 }
298
299 // Search for theExtName in the extensions string.
300 // Use of strstr() is not sufficient because extension names can be prefixes of other extension names.
5f8b738e 301 char* aPtrIter = (char* )anExtString;
302 const char* aPtrEnd = aPtrIter + strlen (anExtString);
2166f0fa
SK
303 while (aPtrIter < aPtrEnd)
304 {
305 int n = strcspn (aPtrIter, " ");
5f8b738e 306 if ((n == anExtNameLen) && (strncmp (aPtrIter, theExtName, anExtNameLen) == 0))
307 {
2166f0fa 308 return Standard_True;
5f8b738e 309 }
2166f0fa
SK
310 aPtrIter += (n + 1);
311 }
312 return Standard_False;
313}
314
315// =======================================================================
316// function : Init
317// purpose :
318// =======================================================================
f0430952 319Standard_Boolean OpenGl_Context::Init()
2166f0fa 320{
2bd4c032 321 if (myIsInitialized)
5f8b738e 322 {
f0430952 323 return Standard_True;
5f8b738e 324 }
2bd4c032 325
326#if (defined(_WIN32) || defined(__WIN32__))
327 myWindowDC = (Aspect_Handle )wglGetCurrentDC();
328 myGContext = (Aspect_RenderingContext )wglGetCurrentContext();
329#else
330 myDisplay = (Aspect_Display )glXGetCurrentDisplay();
331 myGContext = (Aspect_RenderingContext )glXGetCurrentContext();
332 myWindow = (Aspect_Drawable )glXGetCurrentDrawable();
333#endif
f0430952 334 if (myGContext == NULL)
335 {
336 return Standard_False;
337 }
2bd4c032 338
339 init();
340 myIsInitialized = Standard_True;
f0430952 341 return Standard_True;
2bd4c032 342}
343
344// =======================================================================
345// function : Init
346// purpose :
347// =======================================================================
348#if (defined(_WIN32) || defined(__WIN32__))
f0430952 349Standard_Boolean OpenGl_Context::Init (const Aspect_Handle theWindow,
350 const Aspect_Handle theWindowDC,
351 const Aspect_RenderingContext theGContext)
2bd4c032 352#else
f0430952 353Standard_Boolean OpenGl_Context::Init (const Aspect_Drawable theWindow,
354 const Aspect_Display theDisplay,
355 const Aspect_RenderingContext theGContext)
2bd4c032 356#endif
357{
358 Standard_ProgramError_Raise_if (myIsInitialized, "OpenGl_Context::Init() should be called only once!");
359
360 myWindow = theWindow;
361 myGContext = theGContext;
362#if (defined(_WIN32) || defined(__WIN32__))
363 myWindowDC = theWindowDC;
364#else
365 myDisplay = theDisplay;
366#endif
86fa64d9 367 if (myGContext == NULL || !MakeCurrent())
f0430952 368 {
369 return Standard_False;
370 }
2bd4c032 371
372 init();
373 myIsInitialized = Standard_True;
f0430952 374 return Standard_True;
5f8b738e 375}
376
377// =======================================================================
378// function : ResetErrors
379// purpose :
380// =======================================================================
381void OpenGl_Context::ResetErrors()
382{
383 while (glGetError() != GL_NO_ERROR)
384 {
385 //
386 }
387}
388
389// =======================================================================
390// function : readGlVersion
391// purpose :
392// =======================================================================
393void OpenGl_Context::readGlVersion()
394{
395 // reset values
396 myGlVerMajor = 0;
397 myGlVerMinor = 0;
398
399 // available since OpenGL 3.0
86325709 400 GLint aMajor = 0, aMinor = 0;
5f8b738e 401 glGetIntegerv (GL_MAJOR_VERSION, &aMajor);
402 glGetIntegerv (GL_MINOR_VERSION, &aMinor);
86325709 403 // glGetError() sometimes does not report an error here even if
404 // GL does not know GL_MAJOR_VERSION and GL_MINOR_VERSION constants.
405 // This happens on some rendereres like e.g. Cygwin MESA.
406 // Thus checking additionally if GL has put anything to
407 // the output variables.
408 if (glGetError() == GL_NO_ERROR && aMajor != 0 && aMinor != 0)
5f8b738e 409 {
410 myGlVerMajor = aMajor;
411 myGlVerMinor = aMinor;
412 return;
413 }
414 ResetErrors();
415
416 // Read version string.
417 // Notice that only first two numbers splitted by point '2.1 XXXXX' are significant.
418 // Following trash (after space) is vendor-specific.
419 // New drivers also returns micro version of GL like '3.3.0' which has no meaning
420 // and should be considered as vendor-specific too.
421 const char* aVerStr = (const char* )glGetString (GL_VERSION);
422 if (aVerStr == NULL || *aVerStr == '\0')
423 {
424 // invalid GL context
425 return;
426 }
427
428 // parse string for major number
429 char aMajorStr[32];
430 char aMinorStr[32];
431 size_t aMajIter = 0;
432 while (aVerStr[aMajIter] >= '0' && aVerStr[aMajIter] <= '9')
433 {
434 ++aMajIter;
435 }
436 if (aMajIter == 0 || aMajIter >= sizeof(aMajorStr))
437 {
438 return;
439 }
440 memcpy (aMajorStr, aVerStr, aMajIter);
441 aMajorStr[aMajIter] = '\0';
442
443 // parse string for minor number
86325709 444 aVerStr += aMajIter + 1;
445 size_t aMinIter = 0;
5f8b738e 446 while (aVerStr[aMinIter] >= '0' && aVerStr[aMinIter] <= '9')
447 {
448 ++aMinIter;
449 }
86325709 450 if (aMinIter == 0 || aMinIter >= sizeof(aMinorStr))
5f8b738e 451 {
452 return;
453 }
86325709 454 memcpy (aMinorStr, aVerStr, aMinIter);
455 aMinorStr[aMinIter] = '\0';
5f8b738e 456
457 // read numbers
458 myGlVerMajor = atoi (aMajorStr);
459 myGlVerMinor = atoi (aMinorStr);
460
461 if (myGlVerMajor <= 0)
462 {
463 myGlVerMajor = 0;
464 myGlVerMinor = 0;
465 }
466}
467
468// =======================================================================
469// function : init
470// purpose :
471// =======================================================================
472void OpenGl_Context::init()
473{
474 // read version
475 readGlVersion();
476
f0430952 477 atiMem = CheckExtension ("GL_ATI_meminfo");
478 nvxMem = CheckExtension ("GL_NVX_gpu_memory_info");
479
5f8b738e 480 // initialize VBO extension (ARB)
481 if (CheckExtension ("GL_ARB_vertex_buffer_object"))
2166f0fa
SK
482 {
483 arbVBO = new OpenGl_ArbVBO();
5f8b738e 484 memset (arbVBO, 0, sizeof(OpenGl_ArbVBO)); // nullify whole structure
485 if (!FindProcShort (arbVBO, glGenBuffersARB)
486 || !FindProcShort (arbVBO, glBindBufferARB)
487 || !FindProcShort (arbVBO, glBufferDataARB)
488 || !FindProcShort (arbVBO, glDeleteBuffersARB))
2166f0fa
SK
489 {
490 delete arbVBO;
491 arbVBO = NULL;
492 }
493 }
494
5e27df78 495 // initialize TBO extension (ARB)
496 if (CheckExtension ("GL_ARB_texture_buffer_object"))
497 {
498 arbTBO = new OpenGl_ArbTBO();
499 memset (arbTBO, 0, sizeof(OpenGl_ArbTBO)); // nullify whole structure
500 if (!FindProcShort (arbTBO, glTexBufferARB))
501 {
502 delete arbTBO;
503 arbTBO = NULL;
504 }
505 }
506
507 // initialize hardware instancing extension (ARB)
508 if (CheckExtension ("GL_ARB_draw_instanced"))
509 {
510 arbIns = new OpenGl_ArbIns();
511 memset (arbIns, 0, sizeof(OpenGl_ArbIns)); // nullify whole structure
512 if (!FindProcShort (arbIns, glDrawArraysInstancedARB)
513 || !FindProcShort (arbIns, glDrawElementsInstancedARB))
514 {
515 delete arbIns;
516 arbIns = NULL;
517 }
518 }
519
5f8b738e 520 // initialize FBO extension (EXT)
521 if (CheckExtension ("GL_EXT_framebuffer_object"))
2166f0fa
SK
522 {
523 extFBO = new OpenGl_ExtFBO();
5f8b738e 524 memset (extFBO, 0, sizeof(OpenGl_ExtFBO)); // nullify whole structure
525 if (!FindProcShort (extFBO, glGenFramebuffersEXT)
526 || !FindProcShort (extFBO, glDeleteFramebuffersEXT)
527 || !FindProcShort (extFBO, glBindFramebufferEXT)
528 || !FindProcShort (extFBO, glFramebufferTexture2DEXT)
529 || !FindProcShort (extFBO, glCheckFramebufferStatusEXT)
530 || !FindProcShort (extFBO, glGenRenderbuffersEXT)
531 || !FindProcShort (extFBO, glDeleteRenderbuffersEXT)
532 || !FindProcShort (extFBO, glBindRenderbufferEXT)
533 || !FindProcShort (extFBO, glRenderbufferStorageEXT)
534 || !FindProcShort (extFBO, glFramebufferRenderbufferEXT))
2166f0fa
SK
535 {
536 delete extFBO;
537 extFBO = NULL;
538 }
539 }
5f8b738e 540
37eb4787 541 // initialize GS extension (EXT)
542 if (CheckExtension ("GL_EXT_geometry_shader4"))
543 {
544 extGS = new OpenGl_ExtGS();
545 memset (extGS, 0, sizeof(OpenGl_ExtGS)); // nullify whole structure
546 if (!FindProcShort (extGS, glProgramParameteriEXT))
547 {
548 delete extGS;
549 extGS = NULL;
550 }
551 }
552
5f8b738e 553 myGlCore20 = new OpenGl_GlCore20();
554 memset (myGlCore20, 0, sizeof(OpenGl_GlCore20)); // nullify whole structure
555
86325709 556 // Check if OpenGL 1.2 core functionality is actually present
557 Standard_Boolean hasGlCore12 = IsGlGreaterEqual (1, 2)
558 && FindProcShort (myGlCore20, glBlendColor)
559 && FindProcShort (myGlCore20, glBlendEquation)
560 && FindProcShort (myGlCore20, glDrawRangeElements)
561 && FindProcShort (myGlCore20, glTexImage3D)
562 && FindProcShort (myGlCore20, glTexSubImage3D)
563 && FindProcShort (myGlCore20, glCopyTexSubImage3D);
564
565 // Check if OpenGL 1.3 core functionality is actually present
566 Standard_Boolean hasGlCore13 = IsGlGreaterEqual (1, 3)
567 && FindProcShort (myGlCore20, glActiveTexture)
568 && FindProcShort (myGlCore20, glSampleCoverage)
569 && FindProcShort (myGlCore20, glCompressedTexImage3D)
570 && FindProcShort (myGlCore20, glCompressedTexImage2D)
571 && FindProcShort (myGlCore20, glCompressedTexImage1D)
572 && FindProcShort (myGlCore20, glCompressedTexSubImage3D)
573 && FindProcShort (myGlCore20, glCompressedTexSubImage2D)
574 && FindProcShort (myGlCore20, glCompressedTexSubImage1D)
575 && FindProcShort (myGlCore20, glGetCompressedTexImage)
576 // deprecated
577 && FindProcShort (myGlCore20, glClientActiveTexture)
578 && FindProcShort (myGlCore20, glMultiTexCoord1d)
579 && FindProcShort (myGlCore20, glMultiTexCoord1dv)
580 && FindProcShort (myGlCore20, glMultiTexCoord1f)
581 && FindProcShort (myGlCore20, glMultiTexCoord1fv)
582 && FindProcShort (myGlCore20, glMultiTexCoord1i)
583 && FindProcShort (myGlCore20, glMultiTexCoord1iv)
584 && FindProcShort (myGlCore20, glMultiTexCoord1s)
585 && FindProcShort (myGlCore20, glMultiTexCoord1sv)
586 && FindProcShort (myGlCore20, glMultiTexCoord2d)
587 && FindProcShort (myGlCore20, glMultiTexCoord2dv)
588 && FindProcShort (myGlCore20, glMultiTexCoord2f)
589 && FindProcShort (myGlCore20, glMultiTexCoord2fv)
590 && FindProcShort (myGlCore20, glMultiTexCoord2i)
591 && FindProcShort (myGlCore20, glMultiTexCoord2iv)
592 && FindProcShort (myGlCore20, glMultiTexCoord2s)
593 && FindProcShort (myGlCore20, glMultiTexCoord2sv)
594 && FindProcShort (myGlCore20, glMultiTexCoord3d)
595 && FindProcShort (myGlCore20, glMultiTexCoord3dv)
596 && FindProcShort (myGlCore20, glMultiTexCoord3f)
597 && FindProcShort (myGlCore20, glMultiTexCoord3fv)
598 && FindProcShort (myGlCore20, glMultiTexCoord3i)
599 && FindProcShort (myGlCore20, glMultiTexCoord3iv)
600 && FindProcShort (myGlCore20, glMultiTexCoord3s)
601 && FindProcShort (myGlCore20, glMultiTexCoord3sv)
602 && FindProcShort (myGlCore20, glMultiTexCoord4d)
603 && FindProcShort (myGlCore20, glMultiTexCoord4dv)
604 && FindProcShort (myGlCore20, glMultiTexCoord4f)
605 && FindProcShort (myGlCore20, glMultiTexCoord4fv)
606 && FindProcShort (myGlCore20, glMultiTexCoord4i)
607 && FindProcShort (myGlCore20, glMultiTexCoord4iv)
608 && FindProcShort (myGlCore20, glMultiTexCoord4s)
609 && FindProcShort (myGlCore20, glMultiTexCoord4sv)
610 && FindProcShort (myGlCore20, glLoadTransposeMatrixf)
611 && FindProcShort (myGlCore20, glLoadTransposeMatrixd)
612 && FindProcShort (myGlCore20, glMultTransposeMatrixf)
613 && FindProcShort (myGlCore20, glMultTransposeMatrixd);
614
615 // Check if OpenGL 1.4 core functionality is actually present
616 Standard_Boolean hasGlCore14 = IsGlGreaterEqual (1, 4)
617 && FindProcShort (myGlCore20, glBlendFuncSeparate)
618 && FindProcShort (myGlCore20, glMultiDrawArrays)
619 && FindProcShort (myGlCore20, glMultiDrawElements)
620 && FindProcShort (myGlCore20, glPointParameterf)
621 && FindProcShort (myGlCore20, glPointParameterfv)
622 && FindProcShort (myGlCore20, glPointParameteri)
623 && FindProcShort (myGlCore20, glPointParameteriv);
624
625 // Check if OpenGL 1.5 core functionality is actually present
626 Standard_Boolean hasGlCore15 = IsGlGreaterEqual (1, 5)
627 && FindProcShort (myGlCore20, glGenQueries)
628 && FindProcShort (myGlCore20, glDeleteQueries)
629 && FindProcShort (myGlCore20, glIsQuery)
630 && FindProcShort (myGlCore20, glBeginQuery)
631 && FindProcShort (myGlCore20, glEndQuery)
632 && FindProcShort (myGlCore20, glGetQueryiv)
633 && FindProcShort (myGlCore20, glGetQueryObjectiv)
634 && FindProcShort (myGlCore20, glGetQueryObjectuiv)
635 && FindProcShort (myGlCore20, glBindBuffer)
636 && FindProcShort (myGlCore20, glDeleteBuffers)
637 && FindProcShort (myGlCore20, glGenBuffers)
638 && FindProcShort (myGlCore20, glIsBuffer)
639 && FindProcShort (myGlCore20, glBufferData)
640 && FindProcShort (myGlCore20, glBufferSubData)
641 && FindProcShort (myGlCore20, glGetBufferSubData)
642 && FindProcShort (myGlCore20, glMapBuffer)
643 && FindProcShort (myGlCore20, glUnmapBuffer)
644 && FindProcShort (myGlCore20, glGetBufferParameteriv)
645 && FindProcShort (myGlCore20, glGetBufferPointerv);
646
647 // Check if OpenGL 2.0 core functionality is actually present
648 Standard_Boolean hasGlCore20 = IsGlGreaterEqual (2, 0)
649 && FindProcShort (myGlCore20, glBlendEquationSeparate)
650 && FindProcShort (myGlCore20, glDrawBuffers)
651 && FindProcShort (myGlCore20, glStencilOpSeparate)
652 && FindProcShort (myGlCore20, glStencilFuncSeparate)
653 && FindProcShort (myGlCore20, glStencilMaskSeparate)
654 && FindProcShort (myGlCore20, glAttachShader)
655 && FindProcShort (myGlCore20, glBindAttribLocation)
656 && FindProcShort (myGlCore20, glCompileShader)
657 && FindProcShort (myGlCore20, glCreateProgram)
658 && FindProcShort (myGlCore20, glCreateShader)
659 && FindProcShort (myGlCore20, glDeleteProgram)
660 && FindProcShort (myGlCore20, glDeleteShader)
661 && FindProcShort (myGlCore20, glDetachShader)
662 && FindProcShort (myGlCore20, glDisableVertexAttribArray)
663 && FindProcShort (myGlCore20, glEnableVertexAttribArray)
664 && FindProcShort (myGlCore20, glGetActiveAttrib)
665 && FindProcShort (myGlCore20, glGetActiveUniform)
666 && FindProcShort (myGlCore20, glGetAttachedShaders)
667 && FindProcShort (myGlCore20, glGetAttribLocation)
668 && FindProcShort (myGlCore20, glGetProgramiv)
669 && FindProcShort (myGlCore20, glGetProgramInfoLog)
670 && FindProcShort (myGlCore20, glGetShaderiv)
671 && FindProcShort (myGlCore20, glGetShaderInfoLog)
672 && FindProcShort (myGlCore20, glGetShaderSource)
673 && FindProcShort (myGlCore20, glGetUniformLocation)
674 && FindProcShort (myGlCore20, glGetUniformfv)
675 && FindProcShort (myGlCore20, glGetUniformiv)
676 && FindProcShort (myGlCore20, glGetVertexAttribdv)
677 && FindProcShort (myGlCore20, glGetVertexAttribfv)
678 && FindProcShort (myGlCore20, glGetVertexAttribiv)
679 && FindProcShort (myGlCore20, glGetVertexAttribPointerv)
680 && FindProcShort (myGlCore20, glIsProgram)
681 && FindProcShort (myGlCore20, glIsShader)
682 && FindProcShort (myGlCore20, glLinkProgram)
683 && FindProcShort (myGlCore20, glShaderSource)
684 && FindProcShort (myGlCore20, glUseProgram)
685 && FindProcShort (myGlCore20, glUniform1f)
686 && FindProcShort (myGlCore20, glUniform2f)
687 && FindProcShort (myGlCore20, glUniform3f)
688 && FindProcShort (myGlCore20, glUniform4f)
689 && FindProcShort (myGlCore20, glUniform1i)
690 && FindProcShort (myGlCore20, glUniform2i)
691 && FindProcShort (myGlCore20, glUniform3i)
692 && FindProcShort (myGlCore20, glUniform4i)
693 && FindProcShort (myGlCore20, glUniform1fv)
694 && FindProcShort (myGlCore20, glUniform2fv)
695 && FindProcShort (myGlCore20, glUniform3fv)
696 && FindProcShort (myGlCore20, glUniform4fv)
697 && FindProcShort (myGlCore20, glUniform1iv)
698 && FindProcShort (myGlCore20, glUniform2iv)
699 && FindProcShort (myGlCore20, glUniform3iv)
700 && FindProcShort (myGlCore20, glUniform4iv)
701 && FindProcShort (myGlCore20, glUniformMatrix2fv)
702 && FindProcShort (myGlCore20, glUniformMatrix3fv)
703 && FindProcShort (myGlCore20, glUniformMatrix4fv)
704 && FindProcShort (myGlCore20, glValidateProgram)
705 && FindProcShort (myGlCore20, glVertexAttrib1d)
706 && FindProcShort (myGlCore20, glVertexAttrib1dv)
707 && FindProcShort (myGlCore20, glVertexAttrib1f)
708 && FindProcShort (myGlCore20, glVertexAttrib1fv)
709 && FindProcShort (myGlCore20, glVertexAttrib1s)
710 && FindProcShort (myGlCore20, glVertexAttrib1sv)
711 && FindProcShort (myGlCore20, glVertexAttrib2d)
712 && FindProcShort (myGlCore20, glVertexAttrib2dv)
713 && FindProcShort (myGlCore20, glVertexAttrib2f)
714 && FindProcShort (myGlCore20, glVertexAttrib2fv)
715 && FindProcShort (myGlCore20, glVertexAttrib2s)
716 && FindProcShort (myGlCore20, glVertexAttrib2sv)
717 && FindProcShort (myGlCore20, glVertexAttrib3d)
718 && FindProcShort (myGlCore20, glVertexAttrib3dv)
719 && FindProcShort (myGlCore20, glVertexAttrib3f)
720 && FindProcShort (myGlCore20, glVertexAttrib3fv)
721 && FindProcShort (myGlCore20, glVertexAttrib3s)
722 && FindProcShort (myGlCore20, glVertexAttrib3sv)
723 && FindProcShort (myGlCore20, glVertexAttrib4Nbv)
724 && FindProcShort (myGlCore20, glVertexAttrib4Niv)
725 && FindProcShort (myGlCore20, glVertexAttrib4Nsv)
726 && FindProcShort (myGlCore20, glVertexAttrib4Nub)
727 && FindProcShort (myGlCore20, glVertexAttrib4Nubv)
728 && FindProcShort (myGlCore20, glVertexAttrib4Nuiv)
729 && FindProcShort (myGlCore20, glVertexAttrib4Nusv)
730 && FindProcShort (myGlCore20, glVertexAttrib4bv)
731 && FindProcShort (myGlCore20, glVertexAttrib4d)
732 && FindProcShort (myGlCore20, glVertexAttrib4dv)
733 && FindProcShort (myGlCore20, glVertexAttrib4f)
734 && FindProcShort (myGlCore20, glVertexAttrib4fv)
735 && FindProcShort (myGlCore20, glVertexAttrib4iv)
736 && FindProcShort (myGlCore20, glVertexAttrib4s)
737 && FindProcShort (myGlCore20, glVertexAttrib4sv)
738 && FindProcShort (myGlCore20, glVertexAttrib4ubv)
739 && FindProcShort (myGlCore20, glVertexAttrib4uiv)
740 && FindProcShort (myGlCore20, glVertexAttrib4usv)
741 && FindProcShort (myGlCore20, glVertexAttribPointer);
742
743 if (!hasGlCore12)
744 {
745 myGlVerMajor = 1;
746 myGlVerMinor = 1;
747 return;
5f8b738e 748 }
86325709 749 else
5f8b738e 750 {
86325709 751 core12 = myGlCore20;
5f8b738e 752 }
86325709 753 if (!hasGlCore13)
5f8b738e 754 {
86325709 755 myGlVerMajor = 1;
756 myGlVerMinor = 2;
757 return;
5f8b738e 758 }
86325709 759 else
760 {
761 core13 = myGlCore20;
5f8b738e 762 }
86325709 763 if(!hasGlCore14)
764 {
765 myGlVerMajor = 1;
766 myGlVerMinor = 3;
767 return;
5f8b738e 768 }
86325709 769 else
5f8b738e 770 {
5f8b738e 771 core14 = myGlCore20;
86325709 772 }
773 if(!hasGlCore15)
774 {
775 myGlVerMajor = 1;
776 myGlVerMinor = 4;
777 return;
778 }
779 else
780 {
5f8b738e 781 core15 = myGlCore20;
86325709 782 }
783 if(!hasGlCore20)
784 {
785 myGlVerMajor = 1;
786 myGlVerMinor = 5;
787 }
788 else
789 {
5f8b738e 790 core20 = myGlCore20;
791 }
2166f0fa 792}
664cae74 793// =======================================================================
794// function : IsFeedback
795// purpose :
796// =======================================================================
797Standard_Boolean OpenGl_Context::IsFeedback() const
798{
799 return myIsFeedback;
800}
801
802// =======================================================================
803// function : SetFeedback
804// purpose :
805// =======================================================================
806void OpenGl_Context::SetFeedback (const Standard_Boolean theFeedbackOn)
807{
808 myIsFeedback = theFeedbackOn;
809}
f0430952 810
811// =======================================================================
812// function : MemoryInfo
813// purpose :
814// =======================================================================
815Standard_Size OpenGl_Context::AvailableMemory() const
816{
817 if (atiMem)
818 {
819 // this is actually information for VBO pool
820 // however because pools are mostly shared
821 // it can be used for total GPU memory estimations
822 GLint aMemInfo[4];
823 aMemInfo[0] = 0;
824 glGetIntegerv (GL_VBO_FREE_MEMORY_ATI, aMemInfo);
825 // returned value is in KiB, however this maybe changed in future
826 return Standard_Size(aMemInfo[0]) * 1024;
827 }
828 else if (nvxMem)
829 {
830 // current available dedicated video memory (in KiB), currently unused GPU memory
831 GLint aMemInfo = 0;
832 glGetIntegerv (GL_GPU_MEMORY_INFO_CURRENT_AVAILABLE_VIDMEM_NVX, &aMemInfo);
833 return Standard_Size(aMemInfo) * 1024;
834 }
835 return 0;
836}
837
838// =======================================================================
839// function : MemoryInfo
840// purpose :
841// =======================================================================
842TCollection_AsciiString OpenGl_Context::MemoryInfo() const
843{
844 TCollection_AsciiString anInfo;
845 if (atiMem)
846 {
847 GLint aValues[4];
848 memset (aValues, 0, sizeof(aValues));
849 glGetIntegerv (GL_VBO_FREE_MEMORY_ATI, aValues);
850
851 // total memory free in the pool
852 anInfo += TCollection_AsciiString (" GPU free memory: ") + (aValues[0] / 1024) + " MiB\n";
853
854 // largest available free block in the pool
855 anInfo += TCollection_AsciiString (" Largest free block: ") + (aValues[1] / 1024) + " MiB\n";
856 if (aValues[2] != aValues[0])
857 {
858 // total auxiliary memory free
859 anInfo += TCollection_AsciiString (" Free memory: ") + (aValues[2] / 1024) + " MiB\n";
860 }
861 }
862 else if (nvxMem)
863 {
864 //current available dedicated video memory (in KiB), currently unused GPU memory
865 GLint aValue = 0;
866 glGetIntegerv (GL_GPU_MEMORY_INFO_CURRENT_AVAILABLE_VIDMEM_NVX, &aValue);
867 anInfo += TCollection_AsciiString (" GPU free memory: ") + (aValue / 1024) + " MiB\n";
868
869 // dedicated video memory, total size (in KiB) of the GPU memory
870 GLint aDedicated = 0;
871 glGetIntegerv (GL_GPU_MEMORY_INFO_DEDICATED_VIDMEM_NVX, &aDedicated);
872 anInfo += TCollection_AsciiString (" GPU memory: ") + (aDedicated / 1024) + " MiB\n";
873
874 // total available memory, total size (in KiB) of the memory available for allocations
875 glGetIntegerv (GL_GPU_MEMORY_INFO_TOTAL_AVAILABLE_MEMORY_NVX, &aValue);
876 if (aValue != aDedicated)
877 {
878 // different only for special configurations
879 anInfo += TCollection_AsciiString (" Total memory: ") + (aValue / 1024) + " MiB\n";
880 }
881 }
882 return anInfo;
883}
5e27df78 884
885
886// =======================================================================
887// function : GetResource
888// purpose :
889// =======================================================================
890const Handle(OpenGl_Resource)& OpenGl_Context::GetResource (const TCollection_AsciiString& theKey) const
891{
892 return mySharedResources->IsBound (theKey) ? mySharedResources->Find (theKey) : NULL_GL_RESOURCE;
893}
894
895// =======================================================================
896// function : ShareResource
897// purpose :
898// =======================================================================
899Standard_Boolean OpenGl_Context::ShareResource (const TCollection_AsciiString& theKey,
900 const Handle(OpenGl_Resource)& theResource)
901{
902 if (theKey.IsEmpty() || theResource.IsNull())
903 {
904 return Standard_False;
905 }
906 return mySharedResources->Bind (theKey, theResource);
907}
908
909// =======================================================================
910// function : ReleaseResource
911// purpose :
912// =======================================================================
913void OpenGl_Context::ReleaseResource (const TCollection_AsciiString& theKey)
914{
915 if (!mySharedResources->IsBound (theKey))
916 {
917 return;
918 }
919 const Handle(OpenGl_Resource)& aRes = mySharedResources->Find (theKey);
920 if (aRes->GetRefCount() > 1)
921 {
922 return;
923 }
924
925 aRes->Release (this);
926 mySharedResources->UnBind (theKey);
927}
928
929// =======================================================================
930// function : DelayedRelease
931// purpose :
932// =======================================================================
933void OpenGl_Context::DelayedRelease (Handle(OpenGl_Resource)& theResource)
934{
935 myReleaseQueue->Push (theResource);
936 theResource.Nullify();
937}
938
939// =======================================================================
940// function : ReleaseDelayed
941// purpose :
942// =======================================================================
943void OpenGl_Context::ReleaseDelayed()
944{
945 while (!myReleaseQueue->IsEmpty())
946 {
947 myReleaseQueue->Front()->Release (this);
948 myReleaseQueue->Pop();
949 }
950}