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