0023243: Adapt OpenGL viewer for using in Cocoa applications on Mac OS X
[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
bf75be98 137// =======================================================================
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
5e27df78 155// =======================================================================
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
86fa64d9 170// =======================================================================
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
2bd4c032 195// =======================================================================
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
5e27df78 249// =======================================================================
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
5f8b738e 271// =======================================================================
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)
578 || !FindProcShort (extFBO, glFramebufferRenderbufferEXT))
2166f0fa
SK
579 {
580 delete extFBO;
581 extFBO = NULL;
582 }
583 }
5f8b738e 584
37eb4787 585 // initialize GS extension (EXT)
586 if (CheckExtension ("GL_EXT_geometry_shader4"))
587 {
588 extGS = new OpenGl_ExtGS();
589 memset (extGS, 0, sizeof(OpenGl_ExtGS)); // nullify whole structure
590 if (!FindProcShort (extGS, glProgramParameteriEXT))
591 {
592 delete extGS;
593 extGS = NULL;
594 }
595 }
596
5f8b738e 597 myGlCore20 = new OpenGl_GlCore20();
598 memset (myGlCore20, 0, sizeof(OpenGl_GlCore20)); // nullify whole structure
599
86325709 600 // Check if OpenGL 1.2 core functionality is actually present
601 Standard_Boolean hasGlCore12 = IsGlGreaterEqual (1, 2)
602 && FindProcShort (myGlCore20, glBlendColor)
603 && FindProcShort (myGlCore20, glBlendEquation)
604 && FindProcShort (myGlCore20, glDrawRangeElements)
605 && FindProcShort (myGlCore20, glTexImage3D)
606 && FindProcShort (myGlCore20, glTexSubImage3D)
607 && FindProcShort (myGlCore20, glCopyTexSubImage3D);
608
609 // Check if OpenGL 1.3 core functionality is actually present
610 Standard_Boolean hasGlCore13 = IsGlGreaterEqual (1, 3)
611 && FindProcShort (myGlCore20, glActiveTexture)
612 && FindProcShort (myGlCore20, glSampleCoverage)
613 && FindProcShort (myGlCore20, glCompressedTexImage3D)
614 && FindProcShort (myGlCore20, glCompressedTexImage2D)
615 && FindProcShort (myGlCore20, glCompressedTexImage1D)
616 && FindProcShort (myGlCore20, glCompressedTexSubImage3D)
617 && FindProcShort (myGlCore20, glCompressedTexSubImage2D)
618 && FindProcShort (myGlCore20, glCompressedTexSubImage1D)
619 && FindProcShort (myGlCore20, glGetCompressedTexImage)
620 // deprecated
621 && FindProcShort (myGlCore20, glClientActiveTexture)
622 && FindProcShort (myGlCore20, glMultiTexCoord1d)
623 && FindProcShort (myGlCore20, glMultiTexCoord1dv)
624 && FindProcShort (myGlCore20, glMultiTexCoord1f)
625 && FindProcShort (myGlCore20, glMultiTexCoord1fv)
626 && FindProcShort (myGlCore20, glMultiTexCoord1i)
627 && FindProcShort (myGlCore20, glMultiTexCoord1iv)
628 && FindProcShort (myGlCore20, glMultiTexCoord1s)
629 && FindProcShort (myGlCore20, glMultiTexCoord1sv)
630 && FindProcShort (myGlCore20, glMultiTexCoord2d)
631 && FindProcShort (myGlCore20, glMultiTexCoord2dv)
632 && FindProcShort (myGlCore20, glMultiTexCoord2f)
633 && FindProcShort (myGlCore20, glMultiTexCoord2fv)
634 && FindProcShort (myGlCore20, glMultiTexCoord2i)
635 && FindProcShort (myGlCore20, glMultiTexCoord2iv)
636 && FindProcShort (myGlCore20, glMultiTexCoord2s)
637 && FindProcShort (myGlCore20, glMultiTexCoord2sv)
638 && FindProcShort (myGlCore20, glMultiTexCoord3d)
639 && FindProcShort (myGlCore20, glMultiTexCoord3dv)
640 && FindProcShort (myGlCore20, glMultiTexCoord3f)
641 && FindProcShort (myGlCore20, glMultiTexCoord3fv)
642 && FindProcShort (myGlCore20, glMultiTexCoord3i)
643 && FindProcShort (myGlCore20, glMultiTexCoord3iv)
644 && FindProcShort (myGlCore20, glMultiTexCoord3s)
645 && FindProcShort (myGlCore20, glMultiTexCoord3sv)
646 && FindProcShort (myGlCore20, glMultiTexCoord4d)
647 && FindProcShort (myGlCore20, glMultiTexCoord4dv)
648 && FindProcShort (myGlCore20, glMultiTexCoord4f)
649 && FindProcShort (myGlCore20, glMultiTexCoord4fv)
650 && FindProcShort (myGlCore20, glMultiTexCoord4i)
651 && FindProcShort (myGlCore20, glMultiTexCoord4iv)
652 && FindProcShort (myGlCore20, glMultiTexCoord4s)
653 && FindProcShort (myGlCore20, glMultiTexCoord4sv)
654 && FindProcShort (myGlCore20, glLoadTransposeMatrixf)
655 && FindProcShort (myGlCore20, glLoadTransposeMatrixd)
656 && FindProcShort (myGlCore20, glMultTransposeMatrixf)
657 && FindProcShort (myGlCore20, glMultTransposeMatrixd);
658
659 // Check if OpenGL 1.4 core functionality is actually present
660 Standard_Boolean hasGlCore14 = IsGlGreaterEqual (1, 4)
661 && FindProcShort (myGlCore20, glBlendFuncSeparate)
662 && FindProcShort (myGlCore20, glMultiDrawArrays)
663 && FindProcShort (myGlCore20, glMultiDrawElements)
664 && FindProcShort (myGlCore20, glPointParameterf)
665 && FindProcShort (myGlCore20, glPointParameterfv)
666 && FindProcShort (myGlCore20, glPointParameteri)
667 && FindProcShort (myGlCore20, glPointParameteriv);
668
669 // Check if OpenGL 1.5 core functionality is actually present
670 Standard_Boolean hasGlCore15 = IsGlGreaterEqual (1, 5)
671 && FindProcShort (myGlCore20, glGenQueries)
672 && FindProcShort (myGlCore20, glDeleteQueries)
673 && FindProcShort (myGlCore20, glIsQuery)
674 && FindProcShort (myGlCore20, glBeginQuery)
675 && FindProcShort (myGlCore20, glEndQuery)
676 && FindProcShort (myGlCore20, glGetQueryiv)
677 && FindProcShort (myGlCore20, glGetQueryObjectiv)
678 && FindProcShort (myGlCore20, glGetQueryObjectuiv)
679 && FindProcShort (myGlCore20, glBindBuffer)
680 && FindProcShort (myGlCore20, glDeleteBuffers)
681 && FindProcShort (myGlCore20, glGenBuffers)
682 && FindProcShort (myGlCore20, glIsBuffer)
683 && FindProcShort (myGlCore20, glBufferData)
684 && FindProcShort (myGlCore20, glBufferSubData)
685 && FindProcShort (myGlCore20, glGetBufferSubData)
686 && FindProcShort (myGlCore20, glMapBuffer)
687 && FindProcShort (myGlCore20, glUnmapBuffer)
688 && FindProcShort (myGlCore20, glGetBufferParameteriv)
689 && FindProcShort (myGlCore20, glGetBufferPointerv);
690
691 // Check if OpenGL 2.0 core functionality is actually present
692 Standard_Boolean hasGlCore20 = IsGlGreaterEqual (2, 0)
693 && FindProcShort (myGlCore20, glBlendEquationSeparate)
694 && FindProcShort (myGlCore20, glDrawBuffers)
695 && FindProcShort (myGlCore20, glStencilOpSeparate)
696 && FindProcShort (myGlCore20, glStencilFuncSeparate)
697 && FindProcShort (myGlCore20, glStencilMaskSeparate)
698 && FindProcShort (myGlCore20, glAttachShader)
699 && FindProcShort (myGlCore20, glBindAttribLocation)
700 && FindProcShort (myGlCore20, glCompileShader)
701 && FindProcShort (myGlCore20, glCreateProgram)
702 && FindProcShort (myGlCore20, glCreateShader)
703 && FindProcShort (myGlCore20, glDeleteProgram)
704 && FindProcShort (myGlCore20, glDeleteShader)
705 && FindProcShort (myGlCore20, glDetachShader)
706 && FindProcShort (myGlCore20, glDisableVertexAttribArray)
707 && FindProcShort (myGlCore20, glEnableVertexAttribArray)
708 && FindProcShort (myGlCore20, glGetActiveAttrib)
709 && FindProcShort (myGlCore20, glGetActiveUniform)
710 && FindProcShort (myGlCore20, glGetAttachedShaders)
711 && FindProcShort (myGlCore20, glGetAttribLocation)
712 && FindProcShort (myGlCore20, glGetProgramiv)
713 && FindProcShort (myGlCore20, glGetProgramInfoLog)
714 && FindProcShort (myGlCore20, glGetShaderiv)
715 && FindProcShort (myGlCore20, glGetShaderInfoLog)
716 && FindProcShort (myGlCore20, glGetShaderSource)
717 && FindProcShort (myGlCore20, glGetUniformLocation)
718 && FindProcShort (myGlCore20, glGetUniformfv)
719 && FindProcShort (myGlCore20, glGetUniformiv)
720 && FindProcShort (myGlCore20, glGetVertexAttribdv)
721 && FindProcShort (myGlCore20, glGetVertexAttribfv)
722 && FindProcShort (myGlCore20, glGetVertexAttribiv)
723 && FindProcShort (myGlCore20, glGetVertexAttribPointerv)
724 && FindProcShort (myGlCore20, glIsProgram)
725 && FindProcShort (myGlCore20, glIsShader)
726 && FindProcShort (myGlCore20, glLinkProgram)
727 && FindProcShort (myGlCore20, glShaderSource)
728 && FindProcShort (myGlCore20, glUseProgram)
729 && FindProcShort (myGlCore20, glUniform1f)
730 && FindProcShort (myGlCore20, glUniform2f)
731 && FindProcShort (myGlCore20, glUniform3f)
732 && FindProcShort (myGlCore20, glUniform4f)
733 && FindProcShort (myGlCore20, glUniform1i)
734 && FindProcShort (myGlCore20, glUniform2i)
735 && FindProcShort (myGlCore20, glUniform3i)
736 && FindProcShort (myGlCore20, glUniform4i)
737 && FindProcShort (myGlCore20, glUniform1fv)
738 && FindProcShort (myGlCore20, glUniform2fv)
739 && FindProcShort (myGlCore20, glUniform3fv)
740 && FindProcShort (myGlCore20, glUniform4fv)
741 && FindProcShort (myGlCore20, glUniform1iv)
742 && FindProcShort (myGlCore20, glUniform2iv)
743 && FindProcShort (myGlCore20, glUniform3iv)
744 && FindProcShort (myGlCore20, glUniform4iv)
745 && FindProcShort (myGlCore20, glUniformMatrix2fv)
746 && FindProcShort (myGlCore20, glUniformMatrix3fv)
747 && FindProcShort (myGlCore20, glUniformMatrix4fv)
748 && FindProcShort (myGlCore20, glValidateProgram)
749 && FindProcShort (myGlCore20, glVertexAttrib1d)
750 && FindProcShort (myGlCore20, glVertexAttrib1dv)
751 && FindProcShort (myGlCore20, glVertexAttrib1f)
752 && FindProcShort (myGlCore20, glVertexAttrib1fv)
753 && FindProcShort (myGlCore20, glVertexAttrib1s)
754 && FindProcShort (myGlCore20, glVertexAttrib1sv)
755 && FindProcShort (myGlCore20, glVertexAttrib2d)
756 && FindProcShort (myGlCore20, glVertexAttrib2dv)
757 && FindProcShort (myGlCore20, glVertexAttrib2f)
758 && FindProcShort (myGlCore20, glVertexAttrib2fv)
759 && FindProcShort (myGlCore20, glVertexAttrib2s)
760 && FindProcShort (myGlCore20, glVertexAttrib2sv)
761 && FindProcShort (myGlCore20, glVertexAttrib3d)
762 && FindProcShort (myGlCore20, glVertexAttrib3dv)
763 && FindProcShort (myGlCore20, glVertexAttrib3f)
764 && FindProcShort (myGlCore20, glVertexAttrib3fv)
765 && FindProcShort (myGlCore20, glVertexAttrib3s)
766 && FindProcShort (myGlCore20, glVertexAttrib3sv)
767 && FindProcShort (myGlCore20, glVertexAttrib4Nbv)
768 && FindProcShort (myGlCore20, glVertexAttrib4Niv)
769 && FindProcShort (myGlCore20, glVertexAttrib4Nsv)
770 && FindProcShort (myGlCore20, glVertexAttrib4Nub)
771 && FindProcShort (myGlCore20, glVertexAttrib4Nubv)
772 && FindProcShort (myGlCore20, glVertexAttrib4Nuiv)
773 && FindProcShort (myGlCore20, glVertexAttrib4Nusv)
774 && FindProcShort (myGlCore20, glVertexAttrib4bv)
775 && FindProcShort (myGlCore20, glVertexAttrib4d)
776 && FindProcShort (myGlCore20, glVertexAttrib4dv)
777 && FindProcShort (myGlCore20, glVertexAttrib4f)
778 && FindProcShort (myGlCore20, glVertexAttrib4fv)
779 && FindProcShort (myGlCore20, glVertexAttrib4iv)
780 && FindProcShort (myGlCore20, glVertexAttrib4s)
781 && FindProcShort (myGlCore20, glVertexAttrib4sv)
782 && FindProcShort (myGlCore20, glVertexAttrib4ubv)
783 && FindProcShort (myGlCore20, glVertexAttrib4uiv)
784 && FindProcShort (myGlCore20, glVertexAttrib4usv)
785 && FindProcShort (myGlCore20, glVertexAttribPointer);
786
787 if (!hasGlCore12)
788 {
789 myGlVerMajor = 1;
790 myGlVerMinor = 1;
791 return;
5f8b738e 792 }
86325709 793 else
5f8b738e 794 {
86325709 795 core12 = myGlCore20;
5f8b738e 796 }
86325709 797 if (!hasGlCore13)
5f8b738e 798 {
86325709 799 myGlVerMajor = 1;
800 myGlVerMinor = 2;
801 return;
5f8b738e 802 }
86325709 803 else
804 {
805 core13 = myGlCore20;
5f8b738e 806 }
86325709 807 if(!hasGlCore14)
808 {
809 myGlVerMajor = 1;
810 myGlVerMinor = 3;
811 return;
5f8b738e 812 }
86325709 813 else
5f8b738e 814 {
5f8b738e 815 core14 = myGlCore20;
86325709 816 }
817 if(!hasGlCore15)
818 {
819 myGlVerMajor = 1;
820 myGlVerMinor = 4;
821 return;
822 }
823 else
824 {
5f8b738e 825 core15 = myGlCore20;
86325709 826 }
827 if(!hasGlCore20)
828 {
829 myGlVerMajor = 1;
830 myGlVerMinor = 5;
831 }
832 else
833 {
5f8b738e 834 core20 = myGlCore20;
835 }
2166f0fa 836}
664cae74 837// =======================================================================
838// function : IsFeedback
839// purpose :
840// =======================================================================
841Standard_Boolean OpenGl_Context::IsFeedback() const
842{
843 return myIsFeedback;
844}
845
846// =======================================================================
847// function : SetFeedback
848// purpose :
849// =======================================================================
850void OpenGl_Context::SetFeedback (const Standard_Boolean theFeedbackOn)
851{
852 myIsFeedback = theFeedbackOn;
853}
f0430952 854
855// =======================================================================
856// function : MemoryInfo
857// purpose :
858// =======================================================================
859Standard_Size OpenGl_Context::AvailableMemory() const
860{
861 if (atiMem)
862 {
863 // this is actually information for VBO pool
864 // however because pools are mostly shared
865 // it can be used for total GPU memory estimations
866 GLint aMemInfo[4];
867 aMemInfo[0] = 0;
868 glGetIntegerv (GL_VBO_FREE_MEMORY_ATI, aMemInfo);
869 // returned value is in KiB, however this maybe changed in future
870 return Standard_Size(aMemInfo[0]) * 1024;
871 }
872 else if (nvxMem)
873 {
874 // current available dedicated video memory (in KiB), currently unused GPU memory
875 GLint aMemInfo = 0;
876 glGetIntegerv (GL_GPU_MEMORY_INFO_CURRENT_AVAILABLE_VIDMEM_NVX, &aMemInfo);
877 return Standard_Size(aMemInfo) * 1024;
878 }
879 return 0;
880}
881
882// =======================================================================
883// function : MemoryInfo
884// purpose :
885// =======================================================================
886TCollection_AsciiString OpenGl_Context::MemoryInfo() const
887{
888 TCollection_AsciiString anInfo;
889 if (atiMem)
890 {
891 GLint aValues[4];
892 memset (aValues, 0, sizeof(aValues));
893 glGetIntegerv (GL_VBO_FREE_MEMORY_ATI, aValues);
894
895 // total memory free in the pool
896 anInfo += TCollection_AsciiString (" GPU free memory: ") + (aValues[0] / 1024) + " MiB\n";
897
898 // largest available free block in the pool
899 anInfo += TCollection_AsciiString (" Largest free block: ") + (aValues[1] / 1024) + " MiB\n";
900 if (aValues[2] != aValues[0])
901 {
902 // total auxiliary memory free
903 anInfo += TCollection_AsciiString (" Free memory: ") + (aValues[2] / 1024) + " MiB\n";
904 }
905 }
906 else if (nvxMem)
907 {
908 //current available dedicated video memory (in KiB), currently unused GPU memory
909 GLint aValue = 0;
910 glGetIntegerv (GL_GPU_MEMORY_INFO_CURRENT_AVAILABLE_VIDMEM_NVX, &aValue);
911 anInfo += TCollection_AsciiString (" GPU free memory: ") + (aValue / 1024) + " MiB\n";
912
913 // dedicated video memory, total size (in KiB) of the GPU memory
914 GLint aDedicated = 0;
915 glGetIntegerv (GL_GPU_MEMORY_INFO_DEDICATED_VIDMEM_NVX, &aDedicated);
916 anInfo += TCollection_AsciiString (" GPU memory: ") + (aDedicated / 1024) + " MiB\n";
917
918 // total available memory, total size (in KiB) of the memory available for allocations
919 glGetIntegerv (GL_GPU_MEMORY_INFO_TOTAL_AVAILABLE_MEMORY_NVX, &aValue);
920 if (aValue != aDedicated)
921 {
922 // different only for special configurations
923 anInfo += TCollection_AsciiString (" Total memory: ") + (aValue / 1024) + " MiB\n";
924 }
925 }
926 return anInfo;
927}
5e27df78 928
929
930// =======================================================================
931// function : GetResource
932// purpose :
933// =======================================================================
934const Handle(OpenGl_Resource)& OpenGl_Context::GetResource (const TCollection_AsciiString& theKey) const
935{
936 return mySharedResources->IsBound (theKey) ? mySharedResources->Find (theKey) : NULL_GL_RESOURCE;
937}
938
939// =======================================================================
940// function : ShareResource
941// purpose :
942// =======================================================================
943Standard_Boolean OpenGl_Context::ShareResource (const TCollection_AsciiString& theKey,
944 const Handle(OpenGl_Resource)& theResource)
945{
946 if (theKey.IsEmpty() || theResource.IsNull())
947 {
948 return Standard_False;
949 }
950 return mySharedResources->Bind (theKey, theResource);
951}
952
953// =======================================================================
954// function : ReleaseResource
955// purpose :
956// =======================================================================
957void OpenGl_Context::ReleaseResource (const TCollection_AsciiString& theKey)
958{
959 if (!mySharedResources->IsBound (theKey))
960 {
961 return;
962 }
963 const Handle(OpenGl_Resource)& aRes = mySharedResources->Find (theKey);
964 if (aRes->GetRefCount() > 1)
965 {
966 return;
967 }
968
969 aRes->Release (this);
970 mySharedResources->UnBind (theKey);
971}
972
973// =======================================================================
974// function : DelayedRelease
975// purpose :
976// =======================================================================
977void OpenGl_Context::DelayedRelease (Handle(OpenGl_Resource)& theResource)
978{
979 myReleaseQueue->Push (theResource);
980 theResource.Nullify();
981}
982
983// =======================================================================
984// function : ReleaseDelayed
985// purpose :
986// =======================================================================
987void OpenGl_Context::ReleaseDelayed()
988{
989 while (!myReleaseQueue->IsEmpty())
990 {
991 myReleaseQueue->Front()->Release (this);
992 myReleaseQueue->Pop();
993 }
994}