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