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