0024599: Tools for interacting with DRAW from Visual Studio debugger
[occt.git] / src / OpenGl / OpenGl_Context.cxx
CommitLineData
6aca4d39 1// Created on: 2012-01-26
b311480e 2// Created by: Kirill GAVRILOV
6aca4d39 3// Copyright (c) 2012-2014 OPEN CASCADE SAS
b311480e 4//
973c2be1 5// This file is part of Open CASCADE Technology software library.
b311480e 6//
d5f74e42 7// This library is free software; you can redistribute it and/or modify it under
8// the terms of the GNU Lesser General Public License version 2.1 as published
973c2be1 9// by the Free Software Foundation, with special exception defined in the file
10// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
11// distribution for complete text of the license and disclaimer of any warranty.
b311480e 12//
973c2be1 13// Alternatively, this file may be used under the terms of Open CASCADE
14// commercial license or contractual agreement.
b311480e 15
58655684 16#if defined(_WIN32)
5f8b738e 17 #include <windows.h>
18#endif
19
2166f0fa
SK
20#include <OpenGl_Context.hxx>
21
5f8b738e 22#include <OpenGl_ArbVBO.hxx>
5e27df78 23#include <OpenGl_ArbTBO.hxx>
24#include <OpenGl_ArbIns.hxx>
58655684 25#include <OpenGl_ArbDbg.hxx>
5f8b738e 26#include <OpenGl_ExtFBO.hxx>
37eb4787 27#include <OpenGl_ExtGS.hxx>
5f8b738e 28#include <OpenGl_GlCore20.hxx>
30f0ad28 29#include <OpenGl_ShaderManager.hxx>
5f8b738e 30
cbf18624 31#include <Message_Messenger.hxx>
30f0ad28 32
a174a3c5 33#include <NCollection_Vector.hxx>
34
2bd4c032 35#include <Standard_ProgramError.hxx>
36
58655684 37#if defined(_WIN32)
5f8b738e 38 //
39#elif defined(__APPLE__) && !defined(MACOSX_USE_GLX)
40 #include <dlfcn.h>
41#else
42 #include <GL/glx.h> // glXGetProcAddress()
43#endif
44
f0430952 45// GL_NVX_gpu_memory_info
46#ifndef GL_GPU_MEMORY_INFO_DEDICATED_VIDMEM_NVX
47 enum
48 {
49 GL_GPU_MEMORY_INFO_DEDICATED_VIDMEM_NVX = 0x9047,
50 GL_GPU_MEMORY_INFO_TOTAL_AVAILABLE_MEMORY_NVX = 0x9048,
51 GL_GPU_MEMORY_INFO_CURRENT_AVAILABLE_VIDMEM_NVX = 0x9049,
52 GL_GPU_MEMORY_INFO_EVICTION_COUNT_NVX = 0x904A,
53 GL_GPU_MEMORY_INFO_EVICTED_MEMORY_NVX = 0x904B
54 };
55#endif
56
2166f0fa
SK
57IMPLEMENT_STANDARD_HANDLE (OpenGl_Context, Standard_Transient)
58IMPLEMENT_STANDARD_RTTIEXT(OpenGl_Context, Standard_Transient)
59
5f8b738e 60//! Make record shorter to retrieve function pointer using variable with same name
61#define FindProcShort(theStruct, theFunc) FindProc(#theFunc, theStruct->theFunc)
2166f0fa 62
5e27df78 63namespace
64{
65 static const Handle(OpenGl_Resource) NULL_GL_RESOURCE;
4269bd1b 66 static const GLdouble OpenGl_DefaultPlaneEq[] = {0.0, 0.0, 0.0, 0.0};
5e27df78 67};
68
2166f0fa
SK
69// =======================================================================
70// function : OpenGl_Context
71// purpose :
72// =======================================================================
58655684 73OpenGl_Context::OpenGl_Context (const Handle(OpenGl_Caps)& theCaps)
5f8b738e 74: core12 (NULL),
75 core13 (NULL),
76 core14 (NULL),
77 core15 (NULL),
78 core20 (NULL),
58655684 79 caps (!theCaps.IsNull() ? theCaps : new OpenGl_Caps()),
bf75be98 80 arbNPTW(Standard_False),
5f8b738e 81 arbVBO (NULL),
5e27df78 82 arbTBO (NULL),
83 arbIns (NULL),
58655684 84 arbDbg (NULL),
5f8b738e 85 extFBO (NULL),
37eb4787 86 extGS (NULL),
bf75be98 87 extBgra(Standard_False),
88 extAnis(Standard_False),
30f0ad28 89 extPDS (Standard_False),
f0430952 90 atiMem (Standard_False),
91 nvxMem (Standard_False),
5e27df78 92 mySharedResources (new OpenGl_ResourcesMap()),
a174a3c5 93 myDelayed (new OpenGl_DelayReleaseMap()),
94 myReleaseQueue (new OpenGl_ResourcesQueue()),
4269bd1b 95 myClippingState (),
5f8b738e 96 myGlLibHandle (NULL),
97 myGlCore20 (NULL),
2f6cb3ac 98 myAnisoMax (1),
eafb234b 99 myMaxTexDim (1024),
4269bd1b 100 myMaxClipPlanes (6),
5f8b738e 101 myGlVerMajor (0),
102 myGlVerMinor (0),
b5ac8292 103 myRenderMode (GL_RENDER),
104 myIsInitialized (Standard_False),
105 myIsStereoBuffers (Standard_False),
106 myDrawBuffer (0)
2166f0fa 107{
5f8b738e 108#if defined(MAC_OS_X_VERSION_10_3) && !defined(MACOSX_USE_GLX)
109 // Vendors can not extend functionality on this system
110 // and developers are limited to OpenGL support provided by Mac OS X SDK.
111 // We retrieve function pointers from system library
112 // to generalize extensions support on all platforms.
113 // In this way we also reach binary compatibility benefit between OS releases
114 // if some newest functionality is optionally used.
115 // Notice that GL version / extension availability checks are required
116 // because function pointers may be available but not functionality itself
117 // (depends on renderer).
118 myGlLibHandle = dlopen ("/System/Library/Frameworks/OpenGL.framework/Versions/Current/OpenGL", RTLD_LAZY);
119#endif
30f0ad28 120
121 myShaderManager = new OpenGl_ShaderManager (this);
2166f0fa
SK
122}
123
124// =======================================================================
125// function : ~OpenGl_Context
126// purpose :
127// =======================================================================
128OpenGl_Context::~OpenGl_Context()
129{
5e27df78 130 // release clean up queue
131 ReleaseDelayed();
132
133 // release shared resources if any
134 if (((const Handle(Standard_Transient)& )mySharedResources)->GetRefCount() <= 1)
135 {
392ac980 136 myShaderManager.Nullify();
5e27df78 137 for (NCollection_DataMap<TCollection_AsciiString, Handle(OpenGl_Resource)>::Iterator anIter (*mySharedResources);
138 anIter.More(); anIter.Next())
139 {
140 anIter.Value()->Release (this);
141 }
142 }
392ac980 143 else
144 {
145 myShaderManager->SetContext (NULL);
146 }
5e27df78 147 mySharedResources.Nullify();
a174a3c5 148 myDelayed.Nullify();
5e27df78 149
cbf18624 150 if (arbDbg != NULL
151 && caps->contextDebug)
152 {
153 // reset callback
154 void* aPtr = NULL;
155 glGetPointerv (GL_DEBUG_CALLBACK_USER_PARAM_ARB, &aPtr);
156 if (aPtr == this)
157 {
158 arbDbg->glDebugMessageCallbackARB (NULL, NULL);
159 }
160 }
161
5f8b738e 162 delete myGlCore20;
163 delete arbVBO;
58655684 164 delete arbTBO;
165 delete arbIns;
166 delete arbDbg;
5f8b738e 167 delete extFBO;
37eb4787 168 delete extGS;
5f8b738e 169}
170
bf75be98 171// =======================================================================
172// function : MaxDegreeOfAnisotropy
173// purpose :
174// =======================================================================
175Standard_Integer OpenGl_Context::MaxDegreeOfAnisotropy() const
176{
177 return myAnisoMax;
178}
179
180// =======================================================================
181// function : MaxTextureSize
182// purpose :
183// =======================================================================
184Standard_Integer OpenGl_Context::MaxTextureSize() const
185{
186 return myMaxTexDim;
187}
188
4269bd1b 189// =======================================================================
190// function : MaxClipPlanes
191// purpose :
192// =======================================================================
193Standard_Integer OpenGl_Context::MaxClipPlanes() const
194{
195 return myMaxClipPlanes;
196}
197
b5ac8292 198// =======================================================================
199// function : SetDrawBufferLeft
200// purpose :
201// =======================================================================
202void OpenGl_Context::SetDrawBufferLeft()
203{
204 switch (myDrawBuffer)
205 {
206 case GL_BACK_RIGHT :
207 case GL_BACK :
208 glDrawBuffer (GL_BACK_LEFT);
209 myDrawBuffer = GL_BACK_LEFT;
210 break;
211
212 case GL_FRONT_RIGHT :
213 case GL_FRONT :
214 glDrawBuffer (GL_FRONT_LEFT);
215 myDrawBuffer = GL_FRONT_LEFT;
216 break;
217
218 case GL_FRONT_AND_BACK :
219 case GL_RIGHT :
220 glDrawBuffer (GL_LEFT);
221 myDrawBuffer = GL_LEFT;
222 break;
223 }
224}
225
226// =======================================================================
227// function : SetDrawBufferRight
228// purpose :
229// =======================================================================
230void OpenGl_Context::SetDrawBufferRight()
231{
232 switch (myDrawBuffer)
233 {
234 case GL_BACK_LEFT :
235 case GL_BACK :
236 glDrawBuffer (GL_BACK_RIGHT);
237 myDrawBuffer = GL_BACK_RIGHT;
238 break;
239
240 case GL_FRONT_LEFT :
241 case GL_FRONT :
242 glDrawBuffer (GL_FRONT_RIGHT);
243 myDrawBuffer = GL_FRONT_RIGHT;
244 break;
245
246 case GL_FRONT_AND_BACK :
247 case GL_LEFT :
248 glDrawBuffer (GL_RIGHT);
249 myDrawBuffer = GL_RIGHT;
250 break;
251 }
252}
253
254// =======================================================================
255// function : SetDrawBufferMono
256// purpose :
257// =======================================================================
258void OpenGl_Context::SetDrawBufferMono()
259{
260 switch (myDrawBuffer)
261 {
262 case GL_BACK_LEFT :
263 case GL_BACK_RIGHT :
264 glDrawBuffer (GL_BACK);
265 myDrawBuffer = GL_BACK;
266 break;
267
268 case GL_FRONT_LEFT :
269 case GL_FRONT_RIGHT :
270 glDrawBuffer (GL_FRONT);
271 myDrawBuffer = GL_FRONT;
272 break;
273
274 case GL_LEFT :
275 case GL_RIGHT :
276 glDrawBuffer (GL_FRONT_AND_BACK);
277 myDrawBuffer = GL_FRONT_AND_BACK;
278 break;
279 }
280}
281
282// =======================================================================
283// function : FetchState
284// purpose :
285// =======================================================================
286void OpenGl_Context::FetchState()
287{
288 // cache feedback mode state
289 glGetIntegerv (GL_RENDER_MODE, &myRenderMode);
290
291 // cache draw buffer state
292 glGetIntegerv (GL_DRAW_BUFFER, &myDrawBuffer);
293}
294
5e27df78 295// =======================================================================
296// function : Share
297// purpose :
298// =======================================================================
299void OpenGl_Context::Share (const Handle(OpenGl_Context)& theShareCtx)
300{
301 if (!theShareCtx.IsNull())
302 {
303 mySharedResources = theShareCtx->mySharedResources;
a174a3c5 304 myDelayed = theShareCtx->myDelayed;
5e27df78 305 myReleaseQueue = theShareCtx->myReleaseQueue;
392ac980 306 myShaderManager = theShareCtx->myShaderManager;
5e27df78 307 }
308}
309
4fe56619 310#if !defined(__APPLE__) || defined(MACOSX_USE_GLX)
311
86fa64d9 312// =======================================================================
313// function : IsCurrent
314// purpose :
315// =======================================================================
316Standard_Boolean OpenGl_Context::IsCurrent() const
317{
58655684 318#if defined(_WIN32)
86fa64d9 319 if (myWindowDC == NULL || myGContext == NULL)
320 {
321 return Standard_False;
322 }
323 return (( (HDC )myWindowDC == wglGetCurrentDC())
324 && ((HGLRC )myGContext == wglGetCurrentContext()));
325#else
326 if (myDisplay == NULL || myWindow == 0 || myGContext == 0)
327 {
328 return Standard_False;
329 }
330
331 return ( ((Display* )myDisplay == glXGetCurrentDisplay())
332 && ((GLXContext )myGContext == glXGetCurrentContext())
333 && ((GLXDrawable )myWindow == glXGetCurrentDrawable()));
334#endif
335}
336
2bd4c032 337// =======================================================================
338// function : MakeCurrent
339// purpose :
340// =======================================================================
341Standard_Boolean OpenGl_Context::MakeCurrent()
342{
58655684 343#if defined(_WIN32)
86fa64d9 344 if (myWindowDC == NULL || myGContext == NULL)
2bd4c032 345 {
86fa64d9 346 Standard_ProgramError_Raise_if (myIsInitialized, "OpenGl_Context::Init() should be called before!");
347 return Standard_False;
348 }
349
350 // technically it should be safe to activate already bound GL context
351 // however some drivers (Intel etc.) may FAIL doing this for unknown reason
352 if (IsCurrent())
353 {
392ac980 354 myShaderManager->SetContext (this);
86fa64d9 355 return Standard_True;
356 }
357 else if (wglMakeCurrent ((HDC )myWindowDC, (HGLRC )myGContext) != TRUE)
358 {
359 // notice that glGetError() couldn't be used here!
360 wchar_t* aMsgBuff = NULL;
361 DWORD anErrorCode = GetLastError();
362 FormatMessageW (FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
363 NULL, anErrorCode, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (wchar_t* )&aMsgBuff, 0, NULL);
cbf18624 364 TCollection_ExtendedString aMsg ("wglMakeCurrent() has failed. ");
86fa64d9 365 if (aMsgBuff != NULL)
366 {
cbf18624 367 aMsg += (Standard_ExtString )aMsgBuff;
86fa64d9 368 LocalFree (aMsgBuff);
369 }
cbf18624 370 PushMessage (GL_DEBUG_SOURCE_WINDOW_SYSTEM_ARB, GL_DEBUG_TYPE_ERROR_ARB, (unsigned int )anErrorCode, GL_DEBUG_SEVERITY_HIGH_ARB, aMsg);
fd4a6963 371 myIsInitialized = Standard_False;
2bd4c032 372 return Standard_False;
373 }
374#else
86fa64d9 375 if (myDisplay == NULL || myWindow == 0 || myGContext == 0)
376 {
377 Standard_ProgramError_Raise_if (myIsInitialized, "OpenGl_Context::Init() should be called before!");
378 return Standard_False;
379 }
380
381 if (!glXMakeCurrent ((Display* )myDisplay, (GLXDrawable )myWindow, (GLXContext )myGContext))
2bd4c032 382 {
383 // if there is no current context it might be impossible to use glGetError() correctly
cbf18624 384 PushMessage (GL_DEBUG_SOURCE_WINDOW_SYSTEM_ARB, GL_DEBUG_TYPE_ERROR_ARB, 0, GL_DEBUG_SEVERITY_HIGH_ARB,
385 "glXMakeCurrent() has failed!");
fd4a6963 386 myIsInitialized = Standard_False;
2bd4c032 387 return Standard_False;
388 }
389#endif
392ac980 390 myShaderManager->SetContext (this);
2bd4c032 391 return Standard_True;
392}
393
5e27df78 394// =======================================================================
395// function : SwapBuffers
396// purpose :
397// =======================================================================
398void OpenGl_Context::SwapBuffers()
399{
58655684 400#if defined(_WIN32)
5e27df78 401 if ((HDC )myWindowDC != NULL)
402 {
403 ::SwapBuffers ((HDC )myWindowDC);
404 glFlush();
405 }
406#else
407 if ((Display* )myDisplay != NULL)
408 {
409 glXSwapBuffers ((Display* )myDisplay, (GLXDrawable )myWindow);
410 }
411#endif
412}
413
4fe56619 414#endif // __APPLE__
415
5f8b738e 416// =======================================================================
417// function : findProc
418// purpose :
419// =======================================================================
420void* OpenGl_Context::findProc (const char* theFuncName)
421{
58655684 422#if defined(_WIN32)
5f8b738e 423 return wglGetProcAddress (theFuncName);
424#elif defined(__APPLE__) && !defined(MACOSX_USE_GLX)
425 return (myGlLibHandle != NULL) ? dlsym (myGlLibHandle, theFuncName) : NULL;
426#else
427 return (void* )glXGetProcAddress ((const GLubyte* )theFuncName);
428#endif
2166f0fa
SK
429}
430
431// =======================================================================
432// function : CheckExtension
433// purpose :
434// =======================================================================
2bd4c032 435Standard_Boolean OpenGl_Context::CheckExtension (const char* theExtName) const
2166f0fa 436{
5f8b738e 437 if (theExtName == NULL)
438 {
439 std::cerr << "CheckExtension called with NULL string!\n";
440 return Standard_False;
441 }
5f8b738e 442
443 // available since OpenGL 3.0
444 // and the ONLY way to check extensions with OpenGL 3.1+ core profile
2bd4c032 445 /**if (IsGlGreaterEqual (3, 0))
5f8b738e 446 {
447 GLint anExtNb = 0;
448 glGetIntegerv (GL_NUM_EXTENSIONS, &anExtNb);
449 for (GLint anIter = 0; anIter < anExtNb; ++anIter)
450 {
451 const char* anExtension = (const char* )core30->glGetStringi (GL_EXTENSIONS, (GLuint )anIter);
452 if (anExtension[anExtNameLen] == '\0' &&
453 strncmp (anExtension, theExtName, anExtNameLen) == 0)
454 {
455 return Standard_True;
456 }
457 }
458 return Standard_False;
459 }*/
460
461 // use old way with huge string for all extensions
462 const char* anExtString = (const char* )glGetString (GL_EXTENSIONS);
463 if (anExtString == NULL)
464 {
7e7c2f0b 465 Messenger()->Send ("TKOpenGL: glGetString (GL_EXTENSIONS) has returned NULL! No GL context?", Message_Warning);
2166f0fa
SK
466 return Standard_False;
467 }
58655684 468 return CheckExtension (anExtString, theExtName);
469}
470
471// =======================================================================
472// function : CheckExtension
473// purpose :
474// =======================================================================
475Standard_Boolean OpenGl_Context::CheckExtension (const char* theExtString,
476 const char* theExtName)
477{
478 if (theExtString == NULL)
479 {
480 return Standard_False;
481 }
2166f0fa
SK
482
483 // Search for theExtName in the extensions string.
484 // Use of strstr() is not sufficient because extension names can be prefixes of other extension names.
58655684 485 char* aPtrIter = (char* )theExtString;
486 const char* aPtrEnd = aPtrIter + strlen (theExtString);
487 const size_t anExtNameLen = strlen (theExtName);
2166f0fa
SK
488 while (aPtrIter < aPtrEnd)
489 {
6a7d83c4 490 const size_t n = strcspn (aPtrIter, " ");
5f8b738e 491 if ((n == anExtNameLen) && (strncmp (aPtrIter, theExtName, anExtNameLen) == 0))
492 {
2166f0fa 493 return Standard_True;
5f8b738e 494 }
2166f0fa
SK
495 aPtrIter += (n + 1);
496 }
497 return Standard_False;
498}
499
4fe56619 500#if !defined(__APPLE__) || defined(MACOSX_USE_GLX)
501
2166f0fa
SK
502// =======================================================================
503// function : Init
504// purpose :
505// =======================================================================
f0430952 506Standard_Boolean OpenGl_Context::Init()
2166f0fa 507{
2bd4c032 508 if (myIsInitialized)
5f8b738e 509 {
f0430952 510 return Standard_True;
5f8b738e 511 }
2bd4c032 512
58655684 513#if defined(_WIN32)
2bd4c032 514 myWindowDC = (Aspect_Handle )wglGetCurrentDC();
515 myGContext = (Aspect_RenderingContext )wglGetCurrentContext();
516#else
517 myDisplay = (Aspect_Display )glXGetCurrentDisplay();
518 myGContext = (Aspect_RenderingContext )glXGetCurrentContext();
519 myWindow = (Aspect_Drawable )glXGetCurrentDrawable();
520#endif
f0430952 521 if (myGContext == NULL)
522 {
523 return Standard_False;
524 }
2bd4c032 525
526 init();
527 myIsInitialized = Standard_True;
f0430952 528 return Standard_True;
2bd4c032 529}
530
4fe56619 531#endif // __APPLE__
532
2bd4c032 533// =======================================================================
534// function : Init
535// purpose :
536// =======================================================================
58655684 537#if defined(_WIN32)
f0430952 538Standard_Boolean OpenGl_Context::Init (const Aspect_Handle theWindow,
539 const Aspect_Handle theWindowDC,
540 const Aspect_RenderingContext theGContext)
4fe56619 541#elif defined(__APPLE__) && !defined(MACOSX_USE_GLX)
542Standard_Boolean OpenGl_Context::Init (const void* theGContext)
2bd4c032 543#else
f0430952 544Standard_Boolean OpenGl_Context::Init (const Aspect_Drawable theWindow,
545 const Aspect_Display theDisplay,
546 const Aspect_RenderingContext theGContext)
2bd4c032 547#endif
548{
549 Standard_ProgramError_Raise_if (myIsInitialized, "OpenGl_Context::Init() should be called only once!");
58655684 550#if defined(_WIN32)
2bd4c032 551 myWindow = theWindow;
552 myGContext = theGContext;
2bd4c032 553 myWindowDC = theWindowDC;
4fe56619 554#elif defined(__APPLE__) && !defined(MACOSX_USE_GLX)
555 myGContext = (void* )theGContext;
2bd4c032 556#else
4fe56619 557 myWindow = theWindow;
558 myGContext = theGContext;
2bd4c032 559 myDisplay = theDisplay;
560#endif
86fa64d9 561 if (myGContext == NULL || !MakeCurrent())
f0430952 562 {
563 return Standard_False;
564 }
2bd4c032 565
566 init();
567 myIsInitialized = Standard_True;
f0430952 568 return Standard_True;
5f8b738e 569}
570
571// =======================================================================
572// function : ResetErrors
573// purpose :
574// =======================================================================
575void OpenGl_Context::ResetErrors()
576{
577 while (glGetError() != GL_NO_ERROR)
578 {
579 //
580 }
581}
582
583// =======================================================================
584// function : readGlVersion
585// purpose :
586// =======================================================================
587void OpenGl_Context::readGlVersion()
588{
589 // reset values
590 myGlVerMajor = 0;
591 myGlVerMinor = 0;
592
593 // available since OpenGL 3.0
86325709 594 GLint aMajor = 0, aMinor = 0;
5f8b738e 595 glGetIntegerv (GL_MAJOR_VERSION, &aMajor);
596 glGetIntegerv (GL_MINOR_VERSION, &aMinor);
30f0ad28 597 // glGetError() sometimes does not report an error here even if
86325709 598 // GL does not know GL_MAJOR_VERSION and GL_MINOR_VERSION constants.
599 // This happens on some rendereres like e.g. Cygwin MESA.
600 // Thus checking additionally if GL has put anything to
601 // the output variables.
602 if (glGetError() == GL_NO_ERROR && aMajor != 0 && aMinor != 0)
5f8b738e 603 {
604 myGlVerMajor = aMajor;
605 myGlVerMinor = aMinor;
606 return;
607 }
608 ResetErrors();
609
610 // Read version string.
611 // Notice that only first two numbers splitted by point '2.1 XXXXX' are significant.
612 // Following trash (after space) is vendor-specific.
613 // New drivers also returns micro version of GL like '3.3.0' which has no meaning
614 // and should be considered as vendor-specific too.
615 const char* aVerStr = (const char* )glGetString (GL_VERSION);
616 if (aVerStr == NULL || *aVerStr == '\0')
617 {
618 // invalid GL context
619 return;
620 }
621
622 // parse string for major number
623 char aMajorStr[32];
624 char aMinorStr[32];
625 size_t aMajIter = 0;
626 while (aVerStr[aMajIter] >= '0' && aVerStr[aMajIter] <= '9')
627 {
628 ++aMajIter;
629 }
630 if (aMajIter == 0 || aMajIter >= sizeof(aMajorStr))
631 {
632 return;
633 }
634 memcpy (aMajorStr, aVerStr, aMajIter);
635 aMajorStr[aMajIter] = '\0';
636
637 // parse string for minor number
86325709 638 aVerStr += aMajIter + 1;
639 size_t aMinIter = 0;
5f8b738e 640 while (aVerStr[aMinIter] >= '0' && aVerStr[aMinIter] <= '9')
641 {
642 ++aMinIter;
643 }
86325709 644 if (aMinIter == 0 || aMinIter >= sizeof(aMinorStr))
5f8b738e 645 {
646 return;
647 }
86325709 648 memcpy (aMinorStr, aVerStr, aMinIter);
649 aMinorStr[aMinIter] = '\0';
5f8b738e 650
651 // read numbers
652 myGlVerMajor = atoi (aMajorStr);
653 myGlVerMinor = atoi (aMinorStr);
654
655 if (myGlVerMajor <= 0)
656 {
657 myGlVerMajor = 0;
658 myGlVerMinor = 0;
659 }
660}
661
58655684 662static Standard_CString THE_DBGMSG_UNKNOWN = "UNKNOWN";
663static Standard_CString THE_DBGMSG_SOURCES[] =
664{
cbf18624 665 ".OpenGL", // GL_DEBUG_SOURCE_API_ARB
666 ".WinSystem", // GL_DEBUG_SOURCE_WINDOW_SYSTEM_ARB
667 ".GLSL", // GL_DEBUG_SOURCE_SHADER_COMPILER_ARB
668 ".3rdParty", // GL_DEBUG_SOURCE_THIRD_PARTY_ARB
669 "", // GL_DEBUG_SOURCE_APPLICATION_ARB
670 ".Other" // GL_DEBUG_SOURCE_OTHER_ARB
58655684 671};
672
673static Standard_CString THE_DBGMSG_TYPES[] =
674{
cbf18624 675 "Error", // GL_DEBUG_TYPE_ERROR_ARB
676 "Deprecated", // GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR_ARB
677 "Undef. behavior", // GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR_ARB
678 "Portability", // GL_DEBUG_TYPE_PORTABILITY_ARB
679 "Performance", // GL_DEBUG_TYPE_PERFORMANCE_ARB
680 "Other" // GL_DEBUG_TYPE_OTHER_ARB
58655684 681};
682
683static Standard_CString THE_DBGMSG_SEV_HIGH = "High"; // GL_DEBUG_SEVERITY_HIGH_ARB
684static Standard_CString THE_DBGMSG_SEV_MEDIUM = "Medium"; // GL_DEBUG_SEVERITY_MEDIUM_ARB
685static Standard_CString THE_DBGMSG_SEV_LOW = "Low"; // GL_DEBUG_SEVERITY_LOW_ARB
686
cbf18624 687//! Callback for GL_ARB_debug_output extension
58655684 688static void APIENTRY debugCallbackWrap(unsigned int theSource,
689 unsigned int theType,
690 unsigned int theId,
691 unsigned int theSeverity,
692 int /*theLength*/,
693 const char* theMessage,
9293178b 694 const void* theUserParam)
cbf18624 695{
696 OpenGl_Context* aCtx = (OpenGl_Context* )theUserParam;
697 aCtx->PushMessage (theSource, theType, theId, theSeverity, theMessage);
698}
699
700// =======================================================================
701// function : PushMessage
702// purpose :
703// =======================================================================
704void OpenGl_Context::PushMessage (const unsigned int theSource,
705 const unsigned int theType,
706 const unsigned int theId,
707 const unsigned int theSeverity,
708 const TCollection_ExtendedString& theMessage)
58655684 709{
710 //OpenGl_Context* aCtx = (OpenGl_Context* )theUserParam;
711 Standard_CString& aSrc = (theSource >= GL_DEBUG_SOURCE_API_ARB
712 && theSource <= GL_DEBUG_SOURCE_OTHER_ARB)
713 ? THE_DBGMSG_SOURCES[theSource - GL_DEBUG_SOURCE_API_ARB]
714 : THE_DBGMSG_UNKNOWN;
715 Standard_CString& aType = (theType >= GL_DEBUG_TYPE_ERROR_ARB
716 && theType <= GL_DEBUG_TYPE_OTHER_ARB)
717 ? THE_DBGMSG_TYPES[theType - GL_DEBUG_TYPE_ERROR_ARB]
718 : THE_DBGMSG_UNKNOWN;
719 Standard_CString& aSev = theSeverity == GL_DEBUG_SEVERITY_HIGH_ARB
720 ? THE_DBGMSG_SEV_HIGH
721 : (theSeverity == GL_DEBUG_SEVERITY_MEDIUM_ARB
722 ? THE_DBGMSG_SEV_MEDIUM
723 : THE_DBGMSG_SEV_LOW);
cbf18624 724 Message_Gravity aGrav = theSeverity == GL_DEBUG_SEVERITY_HIGH_ARB
725 ? Message_Alarm
726 : (theSeverity == GL_DEBUG_SEVERITY_MEDIUM_ARB
727 ? Message_Warning
728 : Message_Info);
729
730 TCollection_ExtendedString aMsg;
731 aMsg += "TKOpenGl"; aMsg += aSrc;
732 aMsg += " | Type: "; aMsg += aType;
733 aMsg += " | ID: "; aMsg += (Standard_Integer )theId;
734 aMsg += " | Severity: "; aMsg += aSev;
735 aMsg += " | Message:\n ";
736 aMsg += theMessage;
737
7e7c2f0b 738 Messenger()->Send (aMsg, aGrav);
58655684 739}
740
5f8b738e 741// =======================================================================
742// function : init
743// purpose :
744// =======================================================================
745void OpenGl_Context::init()
746{
747 // read version
748 readGlVersion();
749
bf75be98 750 arbNPTW = CheckExtension ("GL_ARB_texture_non_power_of_two");
751 extBgra = CheckExtension ("GL_EXT_bgra");
752 extAnis = CheckExtension ("GL_EXT_texture_filter_anisotropic");
b859a34d 753 extPDS = CheckExtension ("GL_EXT_packed_depth_stencil");
bf75be98 754 atiMem = CheckExtension ("GL_ATI_meminfo");
755 nvxMem = CheckExtension ("GL_NVX_gpu_memory_info");
756
4269bd1b 757 // get number of maximum clipping planes
758 glGetIntegerv (GL_MAX_CLIP_PLANES, &myMaxClipPlanes);
bf75be98 759 glGetIntegerv (GL_MAX_TEXTURE_SIZE, &myMaxTexDim);
b5ac8292 760
761 GLint aStereo;
762 glGetIntegerv (GL_STEREO, &aStereo);
763 myIsStereoBuffers = aStereo == 1;
764
bf75be98 765 if (extAnis)
766 {
767 glGetIntegerv (GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &myAnisoMax);
768 }
f0430952 769
4269bd1b 770 myClippingState.Init (myMaxClipPlanes);
771
58655684 772 // initialize debug context extension
773 if (CheckExtension ("GL_ARB_debug_output"))
774 {
775 arbDbg = new OpenGl_ArbDbg();
776 memset (arbDbg, 0, sizeof(OpenGl_ArbDbg)); // nullify whole structure
777 if (!FindProcShort (arbDbg, glDebugMessageControlARB)
778 || !FindProcShort (arbDbg, glDebugMessageInsertARB)
779 || !FindProcShort (arbDbg, glDebugMessageCallbackARB)
780 || !FindProcShort (arbDbg, glGetDebugMessageLogARB))
781 {
782 delete arbDbg;
783 arbDbg = NULL;
784 }
785 if (arbDbg != NULL
786 && caps->contextDebug)
787 {
788 // setup default callback
789 arbDbg->glDebugMessageCallbackARB (debugCallbackWrap, this);
fcdbe201 790 #ifdef DEB
58655684 791 glEnable (GL_DEBUG_OUTPUT_SYNCHRONOUS_ARB);
fcdbe201 792 #endif
58655684 793 }
794 }
795
5f8b738e 796 // initialize VBO extension (ARB)
797 if (CheckExtension ("GL_ARB_vertex_buffer_object"))
2166f0fa
SK
798 {
799 arbVBO = new OpenGl_ArbVBO();
5f8b738e 800 memset (arbVBO, 0, sizeof(OpenGl_ArbVBO)); // nullify whole structure
801 if (!FindProcShort (arbVBO, glGenBuffersARB)
802 || !FindProcShort (arbVBO, glBindBufferARB)
803 || !FindProcShort (arbVBO, glBufferDataARB)
804 || !FindProcShort (arbVBO, glDeleteBuffersARB))
2166f0fa
SK
805 {
806 delete arbVBO;
807 arbVBO = NULL;
808 }
809 }
810
5e27df78 811 // initialize TBO extension (ARB)
812 if (CheckExtension ("GL_ARB_texture_buffer_object"))
813 {
814 arbTBO = new OpenGl_ArbTBO();
815 memset (arbTBO, 0, sizeof(OpenGl_ArbTBO)); // nullify whole structure
816 if (!FindProcShort (arbTBO, glTexBufferARB))
817 {
818 delete arbTBO;
819 arbTBO = NULL;
820 }
821 }
822
823 // initialize hardware instancing extension (ARB)
824 if (CheckExtension ("GL_ARB_draw_instanced"))
825 {
826 arbIns = new OpenGl_ArbIns();
827 memset (arbIns, 0, sizeof(OpenGl_ArbIns)); // nullify whole structure
828 if (!FindProcShort (arbIns, glDrawArraysInstancedARB)
829 || !FindProcShort (arbIns, glDrawElementsInstancedARB))
830 {
831 delete arbIns;
832 arbIns = NULL;
833 }
834 }
835
5f8b738e 836 // initialize FBO extension (EXT)
837 if (CheckExtension ("GL_EXT_framebuffer_object"))
2166f0fa
SK
838 {
839 extFBO = new OpenGl_ExtFBO();
5f8b738e 840 memset (extFBO, 0, sizeof(OpenGl_ExtFBO)); // nullify whole structure
841 if (!FindProcShort (extFBO, glGenFramebuffersEXT)
842 || !FindProcShort (extFBO, glDeleteFramebuffersEXT)
843 || !FindProcShort (extFBO, glBindFramebufferEXT)
844 || !FindProcShort (extFBO, glFramebufferTexture2DEXT)
845 || !FindProcShort (extFBO, glCheckFramebufferStatusEXT)
846 || !FindProcShort (extFBO, glGenRenderbuffersEXT)
847 || !FindProcShort (extFBO, glDeleteRenderbuffersEXT)
848 || !FindProcShort (extFBO, glBindRenderbufferEXT)
849 || !FindProcShort (extFBO, glRenderbufferStorageEXT)
1a7dfdb7 850 || !FindProcShort (extFBO, glFramebufferRenderbufferEXT)
851 || !FindProcShort (extFBO, glGenerateMipmapEXT))
2166f0fa
SK
852 {
853 delete extFBO;
854 extFBO = NULL;
855 }
856 }
5f8b738e 857
37eb4787 858 // initialize GS extension (EXT)
859 if (CheckExtension ("GL_EXT_geometry_shader4"))
860 {
861 extGS = new OpenGl_ExtGS();
862 memset (extGS, 0, sizeof(OpenGl_ExtGS)); // nullify whole structure
863 if (!FindProcShort (extGS, glProgramParameteriEXT))
864 {
865 delete extGS;
866 extGS = NULL;
867 }
868 }
869
5f8b738e 870 myGlCore20 = new OpenGl_GlCore20();
871 memset (myGlCore20, 0, sizeof(OpenGl_GlCore20)); // nullify whole structure
872
86325709 873 // Check if OpenGL 1.2 core functionality is actually present
874 Standard_Boolean hasGlCore12 = IsGlGreaterEqual (1, 2)
875 && FindProcShort (myGlCore20, glBlendColor)
876 && FindProcShort (myGlCore20, glBlendEquation)
877 && FindProcShort (myGlCore20, glDrawRangeElements)
878 && FindProcShort (myGlCore20, glTexImage3D)
879 && FindProcShort (myGlCore20, glTexSubImage3D)
880 && FindProcShort (myGlCore20, glCopyTexSubImage3D);
881
882 // Check if OpenGL 1.3 core functionality is actually present
883 Standard_Boolean hasGlCore13 = IsGlGreaterEqual (1, 3)
884 && FindProcShort (myGlCore20, glActiveTexture)
885 && FindProcShort (myGlCore20, glSampleCoverage)
886 && FindProcShort (myGlCore20, glCompressedTexImage3D)
887 && FindProcShort (myGlCore20, glCompressedTexImage2D)
888 && FindProcShort (myGlCore20, glCompressedTexImage1D)
889 && FindProcShort (myGlCore20, glCompressedTexSubImage3D)
890 && FindProcShort (myGlCore20, glCompressedTexSubImage2D)
891 && FindProcShort (myGlCore20, glCompressedTexSubImage1D)
892 && FindProcShort (myGlCore20, glGetCompressedTexImage)
893 // deprecated
894 && FindProcShort (myGlCore20, glClientActiveTexture)
895 && FindProcShort (myGlCore20, glMultiTexCoord1d)
896 && FindProcShort (myGlCore20, glMultiTexCoord1dv)
897 && FindProcShort (myGlCore20, glMultiTexCoord1f)
898 && FindProcShort (myGlCore20, glMultiTexCoord1fv)
899 && FindProcShort (myGlCore20, glMultiTexCoord1i)
900 && FindProcShort (myGlCore20, glMultiTexCoord1iv)
901 && FindProcShort (myGlCore20, glMultiTexCoord1s)
902 && FindProcShort (myGlCore20, glMultiTexCoord1sv)
903 && FindProcShort (myGlCore20, glMultiTexCoord2d)
904 && FindProcShort (myGlCore20, glMultiTexCoord2dv)
905 && FindProcShort (myGlCore20, glMultiTexCoord2f)
906 && FindProcShort (myGlCore20, glMultiTexCoord2fv)
907 && FindProcShort (myGlCore20, glMultiTexCoord2i)
908 && FindProcShort (myGlCore20, glMultiTexCoord2iv)
909 && FindProcShort (myGlCore20, glMultiTexCoord2s)
910 && FindProcShort (myGlCore20, glMultiTexCoord2sv)
911 && FindProcShort (myGlCore20, glMultiTexCoord3d)
912 && FindProcShort (myGlCore20, glMultiTexCoord3dv)
913 && FindProcShort (myGlCore20, glMultiTexCoord3f)
914 && FindProcShort (myGlCore20, glMultiTexCoord3fv)
915 && FindProcShort (myGlCore20, glMultiTexCoord3i)
916 && FindProcShort (myGlCore20, glMultiTexCoord3iv)
917 && FindProcShort (myGlCore20, glMultiTexCoord3s)
918 && FindProcShort (myGlCore20, glMultiTexCoord3sv)
919 && FindProcShort (myGlCore20, glMultiTexCoord4d)
920 && FindProcShort (myGlCore20, glMultiTexCoord4dv)
921 && FindProcShort (myGlCore20, glMultiTexCoord4f)
922 && FindProcShort (myGlCore20, glMultiTexCoord4fv)
923 && FindProcShort (myGlCore20, glMultiTexCoord4i)
924 && FindProcShort (myGlCore20, glMultiTexCoord4iv)
925 && FindProcShort (myGlCore20, glMultiTexCoord4s)
926 && FindProcShort (myGlCore20, glMultiTexCoord4sv)
927 && FindProcShort (myGlCore20, glLoadTransposeMatrixf)
928 && FindProcShort (myGlCore20, glLoadTransposeMatrixd)
929 && FindProcShort (myGlCore20, glMultTransposeMatrixf)
930 && FindProcShort (myGlCore20, glMultTransposeMatrixd);
30f0ad28 931
86325709 932 // Check if OpenGL 1.4 core functionality is actually present
933 Standard_Boolean hasGlCore14 = IsGlGreaterEqual (1, 4)
934 && FindProcShort (myGlCore20, glBlendFuncSeparate)
935 && FindProcShort (myGlCore20, glMultiDrawArrays)
936 && FindProcShort (myGlCore20, glMultiDrawElements)
937 && FindProcShort (myGlCore20, glPointParameterf)
938 && FindProcShort (myGlCore20, glPointParameterfv)
939 && FindProcShort (myGlCore20, glPointParameteri)
940 && FindProcShort (myGlCore20, glPointParameteriv);
941
942 // Check if OpenGL 1.5 core functionality is actually present
943 Standard_Boolean hasGlCore15 = IsGlGreaterEqual (1, 5)
944 && FindProcShort (myGlCore20, glGenQueries)
945 && FindProcShort (myGlCore20, glDeleteQueries)
946 && FindProcShort (myGlCore20, glIsQuery)
947 && FindProcShort (myGlCore20, glBeginQuery)
948 && FindProcShort (myGlCore20, glEndQuery)
949 && FindProcShort (myGlCore20, glGetQueryiv)
950 && FindProcShort (myGlCore20, glGetQueryObjectiv)
951 && FindProcShort (myGlCore20, glGetQueryObjectuiv)
952 && FindProcShort (myGlCore20, glBindBuffer)
953 && FindProcShort (myGlCore20, glDeleteBuffers)
954 && FindProcShort (myGlCore20, glGenBuffers)
955 && FindProcShort (myGlCore20, glIsBuffer)
956 && FindProcShort (myGlCore20, glBufferData)
957 && FindProcShort (myGlCore20, glBufferSubData)
958 && FindProcShort (myGlCore20, glGetBufferSubData)
959 && FindProcShort (myGlCore20, glMapBuffer)
960 && FindProcShort (myGlCore20, glUnmapBuffer)
961 && FindProcShort (myGlCore20, glGetBufferParameteriv)
962 && FindProcShort (myGlCore20, glGetBufferPointerv);
963
964 // Check if OpenGL 2.0 core functionality is actually present
965 Standard_Boolean hasGlCore20 = IsGlGreaterEqual (2, 0)
966 && FindProcShort (myGlCore20, glBlendEquationSeparate)
967 && FindProcShort (myGlCore20, glDrawBuffers)
968 && FindProcShort (myGlCore20, glStencilOpSeparate)
969 && FindProcShort (myGlCore20, glStencilFuncSeparate)
970 && FindProcShort (myGlCore20, glStencilMaskSeparate)
971 && FindProcShort (myGlCore20, glAttachShader)
972 && FindProcShort (myGlCore20, glBindAttribLocation)
973 && FindProcShort (myGlCore20, glCompileShader)
974 && FindProcShort (myGlCore20, glCreateProgram)
975 && FindProcShort (myGlCore20, glCreateShader)
976 && FindProcShort (myGlCore20, glDeleteProgram)
977 && FindProcShort (myGlCore20, glDeleteShader)
978 && FindProcShort (myGlCore20, glDetachShader)
979 && FindProcShort (myGlCore20, glDisableVertexAttribArray)
980 && FindProcShort (myGlCore20, glEnableVertexAttribArray)
981 && FindProcShort (myGlCore20, glGetActiveAttrib)
982 && FindProcShort (myGlCore20, glGetActiveUniform)
983 && FindProcShort (myGlCore20, glGetAttachedShaders)
984 && FindProcShort (myGlCore20, glGetAttribLocation)
985 && FindProcShort (myGlCore20, glGetProgramiv)
986 && FindProcShort (myGlCore20, glGetProgramInfoLog)
987 && FindProcShort (myGlCore20, glGetShaderiv)
988 && FindProcShort (myGlCore20, glGetShaderInfoLog)
989 && FindProcShort (myGlCore20, glGetShaderSource)
990 && FindProcShort (myGlCore20, glGetUniformLocation)
991 && FindProcShort (myGlCore20, glGetUniformfv)
992 && FindProcShort (myGlCore20, glGetUniformiv)
993 && FindProcShort (myGlCore20, glGetVertexAttribdv)
994 && FindProcShort (myGlCore20, glGetVertexAttribfv)
995 && FindProcShort (myGlCore20, glGetVertexAttribiv)
996 && FindProcShort (myGlCore20, glGetVertexAttribPointerv)
997 && FindProcShort (myGlCore20, glIsProgram)
998 && FindProcShort (myGlCore20, glIsShader)
999 && FindProcShort (myGlCore20, glLinkProgram)
1000 && FindProcShort (myGlCore20, glShaderSource)
1001 && FindProcShort (myGlCore20, glUseProgram)
1002 && FindProcShort (myGlCore20, glUniform1f)
1003 && FindProcShort (myGlCore20, glUniform2f)
1004 && FindProcShort (myGlCore20, glUniform3f)
1005 && FindProcShort (myGlCore20, glUniform4f)
1006 && FindProcShort (myGlCore20, glUniform1i)
1007 && FindProcShort (myGlCore20, glUniform2i)
1008 && FindProcShort (myGlCore20, glUniform3i)
1009 && FindProcShort (myGlCore20, glUniform4i)
1010 && FindProcShort (myGlCore20, glUniform1fv)
1011 && FindProcShort (myGlCore20, glUniform2fv)
1012 && FindProcShort (myGlCore20, glUniform3fv)
1013 && FindProcShort (myGlCore20, glUniform4fv)
1014 && FindProcShort (myGlCore20, glUniform1iv)
1015 && FindProcShort (myGlCore20, glUniform2iv)
1016 && FindProcShort (myGlCore20, glUniform3iv)
1017 && FindProcShort (myGlCore20, glUniform4iv)
1018 && FindProcShort (myGlCore20, glUniformMatrix2fv)
1019 && FindProcShort (myGlCore20, glUniformMatrix3fv)
1020 && FindProcShort (myGlCore20, glUniformMatrix4fv)
1021 && FindProcShort (myGlCore20, glValidateProgram)
1022 && FindProcShort (myGlCore20, glVertexAttrib1d)
1023 && FindProcShort (myGlCore20, glVertexAttrib1dv)
1024 && FindProcShort (myGlCore20, glVertexAttrib1f)
1025 && FindProcShort (myGlCore20, glVertexAttrib1fv)
1026 && FindProcShort (myGlCore20, glVertexAttrib1s)
1027 && FindProcShort (myGlCore20, glVertexAttrib1sv)
1028 && FindProcShort (myGlCore20, glVertexAttrib2d)
1029 && FindProcShort (myGlCore20, glVertexAttrib2dv)
1030 && FindProcShort (myGlCore20, glVertexAttrib2f)
1031 && FindProcShort (myGlCore20, glVertexAttrib2fv)
1032 && FindProcShort (myGlCore20, glVertexAttrib2s)
1033 && FindProcShort (myGlCore20, glVertexAttrib2sv)
1034 && FindProcShort (myGlCore20, glVertexAttrib3d)
1035 && FindProcShort (myGlCore20, glVertexAttrib3dv)
1036 && FindProcShort (myGlCore20, glVertexAttrib3f)
1037 && FindProcShort (myGlCore20, glVertexAttrib3fv)
1038 && FindProcShort (myGlCore20, glVertexAttrib3s)
1039 && FindProcShort (myGlCore20, glVertexAttrib3sv)
1040 && FindProcShort (myGlCore20, glVertexAttrib4Nbv)
1041 && FindProcShort (myGlCore20, glVertexAttrib4Niv)
1042 && FindProcShort (myGlCore20, glVertexAttrib4Nsv)
1043 && FindProcShort (myGlCore20, glVertexAttrib4Nub)
1044 && FindProcShort (myGlCore20, glVertexAttrib4Nubv)
1045 && FindProcShort (myGlCore20, glVertexAttrib4Nuiv)
1046 && FindProcShort (myGlCore20, glVertexAttrib4Nusv)
1047 && FindProcShort (myGlCore20, glVertexAttrib4bv)
1048 && FindProcShort (myGlCore20, glVertexAttrib4d)
1049 && FindProcShort (myGlCore20, glVertexAttrib4dv)
1050 && FindProcShort (myGlCore20, glVertexAttrib4f)
1051 && FindProcShort (myGlCore20, glVertexAttrib4fv)
1052 && FindProcShort (myGlCore20, glVertexAttrib4iv)
1053 && FindProcShort (myGlCore20, glVertexAttrib4s)
1054 && FindProcShort (myGlCore20, glVertexAttrib4sv)
1055 && FindProcShort (myGlCore20, glVertexAttrib4ubv)
1056 && FindProcShort (myGlCore20, glVertexAttrib4uiv)
1057 && FindProcShort (myGlCore20, glVertexAttrib4usv)
1058 && FindProcShort (myGlCore20, glVertexAttribPointer);
1059
1060 if (!hasGlCore12)
1061 {
1062 myGlVerMajor = 1;
1063 myGlVerMinor = 1;
1064 return;
5f8b738e 1065 }
86325709 1066 else
5f8b738e 1067 {
86325709 1068 core12 = myGlCore20;
5f8b738e 1069 }
86325709 1070 if (!hasGlCore13)
5f8b738e 1071 {
86325709 1072 myGlVerMajor = 1;
1073 myGlVerMinor = 2;
1074 return;
5f8b738e 1075 }
86325709 1076 else
1077 {
1078 core13 = myGlCore20;
5f8b738e 1079 }
86325709 1080 if(!hasGlCore14)
1081 {
1082 myGlVerMajor = 1;
1083 myGlVerMinor = 3;
1084 return;
5f8b738e 1085 }
86325709 1086 else
5f8b738e 1087 {
5f8b738e 1088 core14 = myGlCore20;
86325709 1089 }
1090 if(!hasGlCore15)
1091 {
1092 myGlVerMajor = 1;
1093 myGlVerMinor = 4;
1094 return;
1095 }
1096 else
1097 {
5f8b738e 1098 core15 = myGlCore20;
86325709 1099 }
1100 if(!hasGlCore20)
1101 {
1102 myGlVerMajor = 1;
1103 myGlVerMinor = 5;
1104 }
1105 else
1106 {
5f8b738e 1107 core20 = myGlCore20;
1108 }
2166f0fa 1109}
f0430952 1110
1111// =======================================================================
1112// function : MemoryInfo
1113// purpose :
1114// =======================================================================
1115Standard_Size OpenGl_Context::AvailableMemory() const
1116{
1117 if (atiMem)
1118 {
1119 // this is actually information for VBO pool
1120 // however because pools are mostly shared
1121 // it can be used for total GPU memory estimations
1122 GLint aMemInfo[4];
1123 aMemInfo[0] = 0;
1124 glGetIntegerv (GL_VBO_FREE_MEMORY_ATI, aMemInfo);
1125 // returned value is in KiB, however this maybe changed in future
1126 return Standard_Size(aMemInfo[0]) * 1024;
1127 }
1128 else if (nvxMem)
1129 {
1130 // current available dedicated video memory (in KiB), currently unused GPU memory
1131 GLint aMemInfo = 0;
1132 glGetIntegerv (GL_GPU_MEMORY_INFO_CURRENT_AVAILABLE_VIDMEM_NVX, &aMemInfo);
1133 return Standard_Size(aMemInfo) * 1024;
1134 }
1135 return 0;
1136}
1137
1138// =======================================================================
1139// function : MemoryInfo
1140// purpose :
1141// =======================================================================
1142TCollection_AsciiString OpenGl_Context::MemoryInfo() const
1143{
1144 TCollection_AsciiString anInfo;
1145 if (atiMem)
1146 {
1147 GLint aValues[4];
1148 memset (aValues, 0, sizeof(aValues));
1149 glGetIntegerv (GL_VBO_FREE_MEMORY_ATI, aValues);
1150
1151 // total memory free in the pool
1152 anInfo += TCollection_AsciiString (" GPU free memory: ") + (aValues[0] / 1024) + " MiB\n";
1153
1154 // largest available free block in the pool
1155 anInfo += TCollection_AsciiString (" Largest free block: ") + (aValues[1] / 1024) + " MiB\n";
1156 if (aValues[2] != aValues[0])
1157 {
1158 // total auxiliary memory free
1159 anInfo += TCollection_AsciiString (" Free memory: ") + (aValues[2] / 1024) + " MiB\n";
1160 }
1161 }
1162 else if (nvxMem)
1163 {
1164 //current available dedicated video memory (in KiB), currently unused GPU memory
1165 GLint aValue = 0;
1166 glGetIntegerv (GL_GPU_MEMORY_INFO_CURRENT_AVAILABLE_VIDMEM_NVX, &aValue);
1167 anInfo += TCollection_AsciiString (" GPU free memory: ") + (aValue / 1024) + " MiB\n";
1168
1169 // dedicated video memory, total size (in KiB) of the GPU memory
1170 GLint aDedicated = 0;
1171 glGetIntegerv (GL_GPU_MEMORY_INFO_DEDICATED_VIDMEM_NVX, &aDedicated);
1172 anInfo += TCollection_AsciiString (" GPU memory: ") + (aDedicated / 1024) + " MiB\n";
1173
1174 // total available memory, total size (in KiB) of the memory available for allocations
1175 glGetIntegerv (GL_GPU_MEMORY_INFO_TOTAL_AVAILABLE_MEMORY_NVX, &aValue);
1176 if (aValue != aDedicated)
1177 {
1178 // different only for special configurations
1179 anInfo += TCollection_AsciiString (" Total memory: ") + (aValue / 1024) + " MiB\n";
1180 }
1181 }
1182 return anInfo;
1183}
5e27df78 1184
1185
1186// =======================================================================
1187// function : GetResource
1188// purpose :
1189// =======================================================================
1190const Handle(OpenGl_Resource)& OpenGl_Context::GetResource (const TCollection_AsciiString& theKey) const
1191{
1192 return mySharedResources->IsBound (theKey) ? mySharedResources->Find (theKey) : NULL_GL_RESOURCE;
1193}
1194
1195// =======================================================================
1196// function : ShareResource
1197// purpose :
1198// =======================================================================
1199Standard_Boolean OpenGl_Context::ShareResource (const TCollection_AsciiString& theKey,
1200 const Handle(OpenGl_Resource)& theResource)
1201{
1202 if (theKey.IsEmpty() || theResource.IsNull())
1203 {
1204 return Standard_False;
1205 }
1206 return mySharedResources->Bind (theKey, theResource);
1207}
1208
1209// =======================================================================
1210// function : ReleaseResource
1211// purpose :
1212// =======================================================================
a174a3c5 1213void OpenGl_Context::ReleaseResource (const TCollection_AsciiString& theKey,
1214 const Standard_Boolean theToDelay)
5e27df78 1215{
1216 if (!mySharedResources->IsBound (theKey))
1217 {
1218 return;
1219 }
1220 const Handle(OpenGl_Resource)& aRes = mySharedResources->Find (theKey);
1221 if (aRes->GetRefCount() > 1)
1222 {
1223 return;
1224 }
1225
a174a3c5 1226 if (theToDelay)
1227 {
1228 myDelayed->Bind (theKey, 1);
1229 }
1230 else
1231 {
1232 aRes->Release (this);
1233 mySharedResources->UnBind (theKey);
1234 }
5e27df78 1235}
1236
1237// =======================================================================
1238// function : DelayedRelease
1239// purpose :
1240// =======================================================================
1241void OpenGl_Context::DelayedRelease (Handle(OpenGl_Resource)& theResource)
1242{
1243 myReleaseQueue->Push (theResource);
1244 theResource.Nullify();
1245}
1246
1247// =======================================================================
1248// function : ReleaseDelayed
1249// purpose :
1250// =======================================================================
1251void OpenGl_Context::ReleaseDelayed()
1252{
a174a3c5 1253 // release queued elements
5e27df78 1254 while (!myReleaseQueue->IsEmpty())
1255 {
1256 myReleaseQueue->Front()->Release (this);
1257 myReleaseQueue->Pop();
1258 }
a174a3c5 1259
265d4508 1260 // release delayed shared resources
a174a3c5 1261 NCollection_Vector<TCollection_AsciiString> aDeadList;
1262 for (NCollection_DataMap<TCollection_AsciiString, Standard_Integer>::Iterator anIter (*myDelayed);
1263 anIter.More(); anIter.Next())
1264 {
1265 if (++anIter.ChangeValue() <= 2)
1266 {
1267 continue; // postpone release one more frame to ensure noone use it periodically
1268 }
1269
1270 const TCollection_AsciiString& aKey = anIter.Key();
1271 if (!mySharedResources->IsBound (aKey))
1272 {
1273 // mixed unshared strategy delayed/undelayed was used!
1274 aDeadList.Append (aKey);
1275 continue;
1276 }
1277
1278 Handle(OpenGl_Resource)& aRes = mySharedResources->ChangeFind (aKey);
1279 if (aRes->GetRefCount() > 1)
1280 {
1281 // should be only 1 instance in mySharedResources
1282 // if not - resource was reused again
1283 aDeadList.Append (aKey);
1284 continue;
1285 }
1286
1287 // release resource if no one requiested it more than 2 redraw calls
1288 aRes->Release (this);
1289 mySharedResources->UnBind (aKey);
1290 aDeadList.Append (aKey);
1291 }
1292
1293 for (Standard_Integer anIter = 0; anIter < aDeadList.Length(); ++anIter)
1294 {
1295 myDelayed->UnBind (aDeadList.Value (anIter));
1296 }
5e27df78 1297}