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