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