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