0030176: Modeling Algorithms - Infinite loop in IntWalk_PWalking::Perform()
[occt.git] / src / OpenGl / OpenGl_GraphicDriver.cxx
CommitLineData
b311480e 1// Created on: 2011-10-20
2// Created by: Sergey ZERCHANINOV
1981cb22 3// Copyright (c) 2011-2013 OPEN CASCADE SAS
b311480e 4//
973c2be1 5// This file is part of Open CASCADE Technology software library.
b311480e 6//
d5f74e42 7// This library is free software; you can redistribute it and/or modify it under
8// the terms of the GNU Lesser General Public License version 2.1 as published
973c2be1 9// by the Free Software Foundation, with special exception defined in the file
10// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
11// distribution for complete text of the license and disclaimer of any warranty.
b311480e 12//
973c2be1 13// Alternatively, this file may be used under the terms of Open CASCADE
14// commercial license or contractual agreement.
b311480e 15
1ce0716b 16#if defined(_WIN32)
17 #include <windows.h>
18#endif
19
2166f0fa 20#include <OpenGl_GraphicDriver.hxx>
f0430952 21#include <OpenGl_Context.hxx>
938d4544 22#include <OpenGl_Flipper.hxx>
a174a3c5 23#include <OpenGl_GraduatedTrihedron.hxx>
24#include <OpenGl_Group.hxx>
2166f0fa 25#include <OpenGl_View.hxx>
a6eb515f 26#include <OpenGl_StencilTest.hxx>
a174a3c5 27#include <OpenGl_Text.hxx>
2166f0fa 28#include <OpenGl_Workspace.hxx>
7fd59977 29
25b97fac 30#include <Aspect_GraphicDeviceDefinitionError.hxx>
c357e426 31#include <Aspect_IdentDefinitionError.hxx>
851dacdb 32#include <Graphic3d_StructureManager.hxx>
25b97fac 33#include <Message_Messenger.hxx>
73192b37 34#include <OSD_Environment.hxx>
a174a3c5 35#include <Standard_NotImplemented.hxx>
36
92efcf78 37IMPLEMENT_STANDARD_RTTIEXT(OpenGl_GraphicDriver,Graphic3d_GraphicDriver)
38
c357e426 39#if defined(_WIN32)
40 #include <WNT_Window.hxx>
41#elif defined(__APPLE__) && !defined(MACOSX_USE_GLX)
42 #include <Cocoa_Window.hxx>
43#else
44 #include <Xw_Window.hxx>
45#endif
46
d8d01f6e 47#if !defined(_WIN32) && !defined(__ANDROID__) && !defined(__QNX__) && (!defined(__APPLE__) || defined(MACOSX_USE_GLX))
73192b37 48 #include <X11/Xlib.h> // XOpenDisplay()
49#endif
50
1ce0716b 51#if defined(HAVE_EGL) || defined(HAVE_GLES2) || defined(OCCT_UWP) || defined(__ANDROID__) || defined(__QNX__)
25b97fac 52 #include <EGL/egl.h>
53#endif
54
2166f0fa
SK
55namespace
56{
5e27df78 57 static const Handle(OpenGl_Context) TheNullGlCtx;
7fd59977 58}
59
65993a95 60// =======================================================================
61// function : OpenGl_GraphicDriver
62// purpose :
63// =======================================================================
25b97fac 64OpenGl_GraphicDriver::OpenGl_GraphicDriver (const Handle(Aspect_DisplayConnection)& theDisp,
05e2200b 65 const Standard_Boolean theToInitialize)
fe9fc669 66: Graphic3d_GraphicDriver (theDisp),
05e2200b 67 myIsOwnContext (Standard_False),
1ce0716b 68#if defined(HAVE_EGL) || defined(HAVE_GLES2) || defined(OCCT_UWP) || defined(__ANDROID__) || defined(__QNX__)
25b97fac 69 myEglDisplay ((Aspect_Display )EGL_NO_DISPLAY),
70 myEglContext ((Aspect_RenderingContext )EGL_NO_CONTEXT),
71 myEglConfig (NULL),
72#endif
65993a95 73 myCaps (new OpenGl_Caps()),
74 myMapOfView (1, NCollection_BaseAllocator::CommonBaseAllocator()),
a521d90d 75 myMapOfStructure (1, NCollection_BaseAllocator::CommonBaseAllocator())
65993a95 76{
d8d01f6e 77#if !defined(_WIN32) && !defined(__ANDROID__) && !defined(__QNX__) && (!defined(__APPLE__) || defined(MACOSX_USE_GLX))
73192b37 78 if (myDisplayConnection.IsNull())
79 {
9775fa61 80 //throw Aspect_GraphicDeviceDefinitionError("OpenGl_GraphicDriver: cannot connect to X server!");
fe9fc669 81 return;
73192b37 82 }
83
73192b37 84 Display* aDisplay = myDisplayConnection->GetDisplay();
85 Bool toSync = ::getenv ("CSF_GraphicSync") != NULL
86 || ::getenv ("CALL_SYNCHRO_X") != NULL;
87 XSynchronize (aDisplay, toSync);
88
1ce0716b 89#if !defined(HAVE_EGL) && !defined(HAVE_GLES2)
73192b37 90 // does the server know about OpenGL & GLX?
91 int aDummy;
92 if (!XQueryExtension (aDisplay, "GLX", &aDummy, &aDummy, &aDummy))
93 {
05e2200b 94 ::Message::DefaultMessenger()->Send ("OpenGl_GraphicDriver, this system doesn't appear to support OpenGL!", Message_Warning);
73192b37 95 }
96#endif
25b97fac 97#endif
05e2200b 98 if (theToInitialize
99 && !InitContext())
100 {
9775fa61 101 throw Aspect_GraphicDeviceDefinitionError("OpenGl_GraphicDriver: default context can not be initialized!");
05e2200b 102 }
c357e426 103
104 // default layers are always presented in display layer sequence it can not be removed
7c3ef2f7 105 {
106 Graphic3d_ZLayerSettings aSettings;
107 aSettings.SetImmediate (Standard_False);
108 aSettings.SetEnvironmentTexture (Standard_False);
109 aSettings.SetEnableDepthTest (Standard_False);
110 aSettings.SetEnableDepthWrite (Standard_False);
111 aSettings.SetClearDepth (Standard_False);
112 aSettings.SetPolygonOffset (Graphic3d_PolygonOffset());
113 myLayerIds.Add (Graphic3d_ZLayerId_BotOSD);
114 myLayerSeq.Append (Graphic3d_ZLayerId_BotOSD);
115 myMapOfZLayerSettings.Bind (Graphic3d_ZLayerId_BotOSD, aSettings);
116 }
117
118 {
119 Graphic3d_ZLayerSettings aSettings;
120 aSettings.SetImmediate (Standard_False);
121 aSettings.SetEnvironmentTexture (Standard_True);
122 aSettings.SetEnableDepthTest (Standard_True);
123 aSettings.SetEnableDepthWrite (Standard_True);
124 aSettings.SetClearDepth (Standard_False);
125 aSettings.SetPolygonOffset (Graphic3d_PolygonOffset());
126 myLayerIds.Add (Graphic3d_ZLayerId_Default);
127 myLayerSeq.Append (Graphic3d_ZLayerId_Default);
128 myMapOfZLayerSettings.Bind (Graphic3d_ZLayerId_Default, aSettings);
129 }
130
131 {
132 Graphic3d_ZLayerSettings aSettings;
133 aSettings.SetImmediate (Standard_True);
134 aSettings.SetEnvironmentTexture (Standard_True);
135 aSettings.SetEnableDepthTest (Standard_True);
136 aSettings.SetEnableDepthWrite (Standard_True);
137 aSettings.SetClearDepth (Standard_False);
138 aSettings.SetPolygonOffset (Graphic3d_PolygonOffset());
139 myLayerIds.Add (Graphic3d_ZLayerId_Top);
140 myLayerSeq.Append (Graphic3d_ZLayerId_Top);
141 myMapOfZLayerSettings.Bind (Graphic3d_ZLayerId_Top, aSettings);
142 }
143
144 {
145 Graphic3d_ZLayerSettings aSettings;
146 aSettings.SetImmediate (Standard_True);
147 aSettings.SetEnvironmentTexture (Standard_True);
148 aSettings.SetEnableDepthTest (Standard_True);
149 aSettings.SetEnableDepthWrite (Standard_True);
150 aSettings.SetClearDepth (Standard_True);
151 aSettings.SetPolygonOffset (Graphic3d_PolygonOffset());
152 myLayerIds.Add (Graphic3d_ZLayerId_Topmost);
153 myLayerSeq.Append (Graphic3d_ZLayerId_Topmost);
154 myMapOfZLayerSettings.Bind (Graphic3d_ZLayerId_Topmost, aSettings);
155 }
156
157 {
158 Graphic3d_ZLayerSettings aSettings;
159 aSettings.SetImmediate (Standard_True);
160 aSettings.SetEnvironmentTexture (Standard_False);
161 aSettings.SetEnableDepthTest (Standard_False);
162 aSettings.SetEnableDepthWrite (Standard_False);
163 aSettings.SetClearDepth (Standard_False);
164 aSettings.SetPolygonOffset (Graphic3d_PolygonOffset());
165 myLayerIds.Add (Graphic3d_ZLayerId_TopOSD);
166 myLayerSeq.Append (Graphic3d_ZLayerId_TopOSD);
167 myMapOfZLayerSettings.Bind (Graphic3d_ZLayerId_TopOSD, aSettings);
168 }
05e2200b 169}
25b97fac 170
05e2200b 171// =======================================================================
172// function : ~OpenGl_GraphicDriver
173// purpose :
174// =======================================================================
175OpenGl_GraphicDriver::~OpenGl_GraphicDriver()
176{
177 ReleaseContext();
178}
179
180// =======================================================================
181// function : ReleaseContext
182// purpose :
183// =======================================================================
184void OpenGl_GraphicDriver::ReleaseContext()
185{
186 Handle(OpenGl_Context) aCtxShared;
c357e426 187 for (NCollection_Map<Handle(OpenGl_View)>::Iterator aViewIter (myMapOfView);
188 aViewIter.More(); aViewIter.Next())
25b97fac 189 {
9775fa61 190 const Handle(OpenGl_View)& aView = aViewIter.Value();
c357e426 191 const Handle(OpenGl_Window)& aWindow = aView->GlWindow();
192 if (aWindow.IsNull())
193 {
194 continue;
195 }
196
197 const Handle(OpenGl_Context)& aCtx = aWindow->GetGlContext();
05e2200b 198 if (aCtx->MakeCurrent()
199 && aCtxShared.IsNull())
25b97fac 200 {
05e2200b 201 aCtxShared = aCtx;
25b97fac 202 }
05e2200b 203 }
204
205 if (!aCtxShared.IsNull())
206 {
207 aCtxShared->MakeCurrent();
208 }
a272ed94 209 for (NCollection_Map<Handle(OpenGl_View)>::Iterator aViewIter (myMapOfView);
05e2200b 210 aViewIter.More(); aViewIter.Next())
211 {
9775fa61 212 const Handle(OpenGl_View)& aView = aViewIter.Value();
05e2200b 213 aView->ReleaseGlResources (aCtxShared);
214 }
215
216 for (NCollection_DataMap<Standard_Integer, OpenGl_Structure*>::Iterator aStructIt (myMapOfStructure);
217 aStructIt.More (); aStructIt.Next())
218 {
219 OpenGl_Structure* aStruct = aStructIt.ChangeValue();
220 aStruct->ReleaseGlResources (aCtxShared);
221 }
05e2200b 222
851dacdb 223 const bool isDeviceLost = !myMapOfStructure.IsEmpty();
c357e426 224 for (NCollection_Map<Handle(OpenGl_View)>::Iterator aViewIter (myMapOfView);
225 aViewIter.More(); aViewIter.Next())
05e2200b 226 {
9775fa61 227 const Handle(OpenGl_View)& aView = aViewIter.Value();
851dacdb 228 if (isDeviceLost)
229 {
230 aView->StructureManager()->SetDeviceLost();
231 }
232
c357e426 233 const Handle(OpenGl_Window)& aWindow = aView->GlWindow();
234 if (aWindow.IsNull())
235 {
236 continue;
237 }
238
239 aWindow->GetGlContext()->forcedRelease();
05e2200b 240 }
25b97fac 241
1ce0716b 242#if defined(HAVE_EGL) || defined(HAVE_GLES2) || defined(OCCT_UWP) || defined(__ANDROID__) || defined(__QNX__)
05e2200b 243 if (myIsOwnContext)
244 {
245 if (myEglContext != (Aspect_RenderingContext )EGL_NO_CONTEXT)
25b97fac 246 {
05e2200b 247 if (eglMakeCurrent ((EGLDisplay )myEglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT) != EGL_TRUE)
248 {
249 ::Message::DefaultMessenger()->Send ("OpenGl_GraphicDriver, FAILED to release OpenGL context!", Message_Warning);
250 }
251 eglDestroyContext ((EGLDisplay )myEglDisplay, (EGLContext )myEglContext);
252 }
25b97fac 253
05e2200b 254 if (myEglDisplay != (Aspect_Display )EGL_NO_DISPLAY)
25b97fac 255 {
05e2200b 256 if (eglTerminate ((EGLDisplay )myEglDisplay) != EGL_TRUE)
257 {
258 ::Message::DefaultMessenger()->Send ("OpenGl_GraphicDriver, EGL, eglTerminate FAILED!", Message_Warning);
259 }
25b97fac 260 }
25b97fac 261 }
262
05e2200b 263 myEglDisplay = (Aspect_Display )EGL_NO_DISPLAY;
264 myEglContext = (Aspect_RenderingContext )EGL_NO_CONTEXT;
265 myEglConfig = NULL;
266#endif
267 myIsOwnContext = Standard_False;
268}
269
270// =======================================================================
271// function : InitContext
272// purpose :
273// =======================================================================
274Standard_Boolean OpenGl_GraphicDriver::InitContext()
275{
276 ReleaseContext();
1ce0716b 277#if defined(HAVE_EGL) || defined(HAVE_GLES2) || defined(OCCT_UWP) || defined(__ANDROID__) || defined(__QNX__)
05e2200b 278
d8d01f6e 279#if !defined(_WIN32) && !defined(__ANDROID__) && !defined(__QNX__) && (!defined(__APPLE__) || defined(MACOSX_USE_GLX))
05e2200b 280 if (myDisplayConnection.IsNull())
281 {
282 return Standard_False;
283 }
284 Display* aDisplay = myDisplayConnection->GetDisplay();
25b97fac 285 myEglDisplay = (Aspect_Display )eglGetDisplay (aDisplay);
286#else
287 myEglDisplay = (Aspect_Display )eglGetDisplay (EGL_DEFAULT_DISPLAY);
288#endif
289 if ((EGLDisplay )myEglDisplay == EGL_NO_DISPLAY)
290 {
05e2200b 291 ::Message::DefaultMessenger()->Send ("Error: no EGL display!", Message_Fail);
292 return Standard_False;
25b97fac 293 }
294
295 EGLint aVerMajor = 0; EGLint aVerMinor = 0;
296 if (eglInitialize ((EGLDisplay )myEglDisplay, &aVerMajor, &aVerMinor) != EGL_TRUE)
297 {
05e2200b 298 ::Message::DefaultMessenger()->Send ("Error: EGL display is unavailable!", Message_Fail);
299 return Standard_False;
25b97fac 300 }
301
05e2200b 302 EGLint aConfigAttribs[] =
25b97fac 303 {
304 EGL_RED_SIZE, 8,
305 EGL_GREEN_SIZE, 8,
306 EGL_BLUE_SIZE, 8,
307 EGL_ALPHA_SIZE, 0,
308 EGL_DEPTH_SIZE, 24,
309 EGL_STENCIL_SIZE, 8,
310 #if defined(GL_ES_VERSION_2_0)
311 EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
312 #else
313 EGL_RENDERABLE_TYPE, EGL_OPENGL_BIT,
314 #endif
315 EGL_NONE
316 };
317
318 EGLint aNbConfigs = 0;
05e2200b 319 if (eglChooseConfig ((EGLDisplay )myEglDisplay, aConfigAttribs, &myEglConfig, 1, &aNbConfigs) != EGL_TRUE
320 || myEglConfig == NULL)
25b97fac 321 {
05e2200b 322 eglGetError();
323 aConfigAttribs[4 * 2 + 1] = 16; // try config with smaller depth buffer
324 if (eglChooseConfig ((EGLDisplay )myEglDisplay, aConfigAttribs, &myEglConfig, 1, &aNbConfigs) != EGL_TRUE
325 || myEglConfig == NULL)
326 {
327 ::Message::DefaultMessenger()->Send ("Error: EGL does not provide compatible configurations!", Message_Fail);
328 return Standard_False;
329 }
25b97fac 330 }
25b97fac 331
332#if defined(GL_ES_VERSION_2_0)
333 EGLint anEglCtxAttribs[] =
334 {
335 EGL_CONTEXT_CLIENT_VERSION, 2,
336 EGL_NONE
337 };
05e2200b 338 if (eglBindAPI (EGL_OPENGL_ES_API) != EGL_TRUE)
339 {
340 ::Message::DefaultMessenger()->Send ("Error: EGL does not provide OpenGL ES client!", Message_Fail);
341 return Standard_False;
342 }
25b97fac 343#else
344 EGLint* anEglCtxAttribs = NULL;
05e2200b 345 if (eglBindAPI (EGL_OPENGL_API) != EGL_TRUE)
346 {
347 ::Message::DefaultMessenger()->Send ("Error: EGL does not provide OpenGL client!", Message_Fail);
348 return Standard_False;
349 }
25b97fac 350#endif
351
352 myEglContext = (Aspect_RenderingContext )eglCreateContext ((EGLDisplay )myEglDisplay, myEglConfig, EGL_NO_CONTEXT, anEglCtxAttribs);
353 if ((EGLContext )myEglContext == EGL_NO_CONTEXT)
354 {
05e2200b 355 ::Message::DefaultMessenger()->Send ("Error: EGL is unable to create OpenGL context!", Message_Fail);
356 return Standard_False;
25b97fac 357 }
1ce0716b 358 // eglMakeCurrent() fails or even crash with EGL_NO_SURFACE on some implementations
359 //if (eglMakeCurrent ((EGLDisplay )myEglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, (EGLContext )myEglContext) != EGL_TRUE)
360 //{
361 // ::Message::DefaultMessenger()->Send ("Error: EGL is unable bind OpenGL context!", Message_Fail);
362 // return Standard_False;
363 //}
25b97fac 364#endif
05e2200b 365 myIsOwnContext = Standard_True;
366 return Standard_True;
73192b37 367}
368
1ce0716b 369#if defined(HAVE_EGL) || defined(HAVE_GLES2) || defined(OCCT_UWP) || defined(__ANDROID__) || defined(__QNX__)
05e2200b 370// =======================================================================
371// function : InitEglContext
372// purpose :
373// =======================================================================
374Standard_Boolean OpenGl_GraphicDriver::InitEglContext (Aspect_Display theEglDisplay,
375 Aspect_RenderingContext theEglContext,
376 void* theEglConfig)
377{
378 ReleaseContext();
d8d01f6e 379#if !defined(_WIN32) && !defined(__ANDROID__) && !defined(__QNX__) && (!defined(__APPLE__) || defined(MACOSX_USE_GLX))
05e2200b 380 if (myDisplayConnection.IsNull())
381 {
382 return Standard_False;
383 }
384#endif
385
386 if ((EGLDisplay )theEglDisplay == EGL_NO_DISPLAY
387 || (EGLContext )theEglContext == EGL_NO_CONTEXT
388 || theEglConfig == NULL)
389 {
390 return Standard_False;
391 }
392 myEglDisplay = theEglDisplay;
393 myEglContext = theEglContext;
394 myEglConfig = theEglConfig;
395 return Standard_True;
396}
397#endif
398
73192b37 399// =======================================================================
3bffef55 400// function : InquireLimit
73192b37 401// purpose :
402// =======================================================================
3bffef55 403Standard_Integer OpenGl_GraphicDriver::InquireLimit (const Graphic3d_TypeOfLimit theType) const
73192b37 404{
73192b37 405 const Handle(OpenGl_Context)& aCtx = GetSharedContext();
3bffef55 406 switch (theType)
407 {
408 case Graphic3d_TypeOfLimit_MaxNbLights:
daf73ab7 409 return Graphic3d_ShaderProgram::THE_MAX_LIGHTS_DEFAULT;
3bffef55 410 case Graphic3d_TypeOfLimit_MaxNbClipPlanes:
411 return !aCtx.IsNull() ? aCtx->MaxClipPlanes() : 0;
412 case Graphic3d_TypeOfLimit_MaxNbViews:
413 return 10000;
414 case Graphic3d_TypeOfLimit_MaxTextureSize:
415 return !aCtx.IsNull() ? aCtx->MaxTextureSize() : 1024;
cc8cbabe 416 case Graphic3d_TypeOfLimit_MaxCombinedTextureUnits:
417 return !aCtx.IsNull() ? aCtx->MaxCombinedTextureUnits() : 1;
3bffef55 418 case Graphic3d_TypeOfLimit_MaxMsaa:
419 return !aCtx.IsNull() ? aCtx->MaxMsaaSamples() : 0;
3a9b5dc8 420 case Graphic3d_TypeOfLimit_HasRayTracing:
421 return (!aCtx.IsNull() && aCtx->HasRayTracing()) ? 1 : 0;
422 case Graphic3d_TypeOfLimit_HasRayTracingTextures:
423 return (!aCtx.IsNull() && aCtx->HasRayTracingTextures()) ? 1 : 0;
424 case Graphic3d_TypeOfLimit_HasRayTracingAdaptiveSampling:
425 return (!aCtx.IsNull() && aCtx->HasRayTracingAdaptiveSampling()) ? 1 : 0;
a1073ae2 426 case Graphic3d_TypeOfLimit_HasBlendedOit:
177781da 427 return (!aCtx.IsNull()
428 && aCtx->hasDrawBuffers != OpenGl_FeatureNotAvailable
429 && (aCtx->hasFloatBuffer != OpenGl_FeatureNotAvailable || aCtx->hasHalfFloatBuffer != OpenGl_FeatureNotAvailable)) ? 1 : 0;
a1073ae2 430 case Graphic3d_TypeOfLimit_HasBlendedOitMsaa:
177781da 431 return (!aCtx.IsNull()
432 && aCtx->hasSampleVariables != OpenGl_FeatureNotAvailable
433 && (InquireLimit (Graphic3d_TypeOfLimit_HasBlendedOit) == 1)) ? 1 : 0;
c39bb31b 434 case Graphic3d_TypeOfLimit_HasFlatShading:
435 return !aCtx.IsNull() && aCtx->hasFlatShading != OpenGl_FeatureNotAvailable ? 1 : 0;
3bffef55 436 case Graphic3d_TypeOfLimit_NB:
437 return 0;
438 }
439 return 0;
73192b37 440}
441
f0430952 442// =======================================================================
5e27df78 443// function : DefaultTextHeight
f0430952 444// purpose :
445// =======================================================================
5e27df78 446Standard_ShortReal OpenGl_GraphicDriver::DefaultTextHeight() const
2166f0fa 447{
5e27df78 448 return 16.;
2166f0fa
SK
449}
450
f0430952 451// =======================================================================
452// function : EnableVBO
453// purpose :
454// =======================================================================
2166f0fa 455void OpenGl_GraphicDriver::EnableVBO (const Standard_Boolean theToTurnOn)
7fd59977 456{
58655684 457 myCaps->vboDisable = !theToTurnOn;
7fd59977 458}
f0430952 459
5e27df78 460// =======================================================================
461// function : GetSharedContext
462// purpose :
463// =======================================================================
464const Handle(OpenGl_Context)& OpenGl_GraphicDriver::GetSharedContext() const
465{
c357e426 466 if (myMapOfView.IsEmpty())
5e27df78 467 {
468 return TheNullGlCtx;
469 }
470
c357e426 471 NCollection_Map<Handle(OpenGl_View)>::Iterator anIter (myMapOfView);
472 for (; anIter.More(); anIter.Next())
473 {
474 Handle(OpenGl_Window) aWindow = anIter.Value()->GlWindow();
475 if (aWindow.IsNull())
476 {
477 continue;
478 }
479
480 return aWindow->GetGlContext();
481 }
482
483 return TheNullGlCtx;
5e27df78 484}
485
f0430952 486// =======================================================================
487// function : MemoryInfo
488// purpose :
489// =======================================================================
490Standard_Boolean OpenGl_GraphicDriver::MemoryInfo (Standard_Size& theFreeBytes,
491 TCollection_AsciiString& theInfo) const
492{
493 // this is extra work (for OpenGl_Context initialization)...
494 OpenGl_Context aGlCtx;
495 if (!aGlCtx.Init())
496 {
497 return Standard_False;
498 }
499 theFreeBytes = aGlCtx.AvailableMemory();
500 theInfo = aGlCtx.MemoryInfo();
501 return !theInfo.IsEmpty();
502}
1981cb22 503
504// =======================================================================
c357e426 505// function : SetBuffersNoSwap
1981cb22 506// purpose :
507// =======================================================================
c357e426 508void OpenGl_GraphicDriver::SetBuffersNoSwap (const Standard_Boolean theIsNoSwap)
1981cb22 509{
c357e426 510 myCaps->buffersNoSwap = theIsNoSwap;
1981cb22 511}
512
a174a3c5 513// =======================================================================
c357e426 514// function : TextSize
a174a3c5 515// purpose :
516// =======================================================================
4b1c8733 517void OpenGl_GraphicDriver::TextSize (const Handle(Graphic3d_CView)& theView,
518 const Standard_CString theText,
519 const Standard_ShortReal theHeight,
520 Standard_ShortReal& theWidth,
521 Standard_ShortReal& theAscent,
522 Standard_ShortReal& theDescent) const
a174a3c5 523{
c357e426 524 const Handle(OpenGl_Context)& aCtx = GetSharedContext();
525 if (aCtx.IsNull())
a174a3c5 526 {
c357e426 527 return;
a174a3c5 528 }
529
c357e426 530 const Standard_ShortReal aHeight = (theHeight < 2.0f) ? DefaultTextHeight() : theHeight;
531 OpenGl_TextParam aTextParam;
532 aTextParam.Height = (int )aHeight;
533 OpenGl_AspectText aTextAspect;
b6472664 534 aTextAspect.Aspect()->SetSpace (0.3);
c357e426 535 TCollection_ExtendedString anExtText = theText;
fb0b0531 536 NCollection_String aText (anExtText.ToExtString());
4b1c8733 537 OpenGl_Text::StringSize(aCtx, aText, aTextAspect, aTextParam, theView->RenderingParams().Resolution, theWidth, theAscent, theDescent);
a174a3c5 538}
539
1593b4ee 540//=======================================================================
541//function : addZLayerIndex
542//purpose :
543//=======================================================================
544void OpenGl_GraphicDriver::addZLayerIndex (const Graphic3d_ZLayerId theLayerId)
545{
546 // remove index
547 for (TColStd_SequenceOfInteger::Iterator aLayerIt (myLayerSeq); aLayerIt.More(); aLayerIt.Next())
548 {
549 if (aLayerIt.Value() == theLayerId)
550 {
551 myLayerSeq.Remove (aLayerIt);
552 break;
553 }
554 }
555
7c3ef2f7 556 if (myMapOfZLayerSettings.Find (theLayerId).IsImmediate())
1593b4ee 557 {
558 myLayerSeq.Append (theLayerId);
559 return;
560 }
561
562 for (TColStd_SequenceOfInteger::Iterator aLayerIt (myLayerSeq); aLayerIt.More(); aLayerIt.Next())
563 {
564 const Graphic3d_ZLayerSettings& aSettings = myMapOfZLayerSettings.Find (aLayerIt.Value());
7c3ef2f7 565 if (aSettings.IsImmediate())
1593b4ee 566 {
567 aLayerIt.Previous();
568 if (aLayerIt.More())
569 {
570 myLayerSeq.InsertAfter (aLayerIt, theLayerId);
571 return;
572 }
573
574 // first non-immediate layer
575 myLayerSeq.Prepend (theLayerId);
576 return;
577 }
578 }
579
580 // no immediate layers
581 myLayerSeq.Append (theLayerId);
582}
583
c357e426 584//=======================================================================
585//function : AddZLayer
586//purpose :
587//=======================================================================
588void OpenGl_GraphicDriver::AddZLayer (const Graphic3d_ZLayerId theLayerId)
a174a3c5 589{
c357e426 590 if (theLayerId < 1)
536d98e2 591 {
c357e426 592 Standard_ASSERT_RAISE (theLayerId > 0,
593 "OpenGl_GraphicDriver::AddZLayer, "
594 "negative and zero IDs are reserved");
536d98e2 595 }
596
1593b4ee 597 myLayerIds.Add (theLayerId);
a174a3c5 598
c357e426 599 // Default z-layer settings
600 myMapOfZLayerSettings.Bind (theLayerId, Graphic3d_ZLayerSettings());
1593b4ee 601 addZLayerIndex (theLayerId);
c357e426 602
603 // Add layer to all views
604 NCollection_Map<Handle(OpenGl_View)>::Iterator aViewIt (myMapOfView);
605 for (; aViewIt.More(); aViewIt.Next())
a174a3c5 606 {
c357e426 607 aViewIt.Value()->AddZLayer (theLayerId);
a174a3c5 608 }
609}
610
c357e426 611//=======================================================================
612//function : RemoveZLayer
613//purpose :
614//=======================================================================
615void OpenGl_GraphicDriver::RemoveZLayer (const Graphic3d_ZLayerId theLayerId)
a174a3c5 616{
c357e426 617 Standard_ASSERT_RAISE (theLayerId > 0,
618 "OpenGl_GraphicDriver::AddZLayer, "
619 "negative and zero IDs are reserved"
620 "and can not be removed");
621
622 Standard_ASSERT_RAISE (myLayerIds.Contains (theLayerId),
623 "OpenGl_GraphicDriver::RemoveZLayer, "
624 "Layer with theLayerId does not exist");
625
626 // Remove layer from all of the views
627 NCollection_Map<Handle(OpenGl_View)>::Iterator aViewIt (myMapOfView);
628 for (; aViewIt.More(); aViewIt.Next())
629 {
630 aViewIt.Value()->RemoveZLayer (theLayerId);
631 }
632
633 // Unset Z layer for all of the structures.
634 NCollection_DataMap<Standard_Integer, OpenGl_Structure*>::Iterator aStructIt (myMapOfStructure);
635 for( ; aStructIt.More (); aStructIt.Next ())
a174a3c5 636 {
c357e426 637 OpenGl_Structure* aStruct = aStructIt.ChangeValue ();
638 if (aStruct->ZLayer() == theLayerId)
639 aStruct->SetZLayer (Graphic3d_ZLayerId_Default);
a174a3c5 640 }
c357e426 641
642 // Remove index
1593b4ee 643 for (TColStd_SequenceOfInteger::Iterator aLayerIt (myLayerSeq); aLayerIt.More(); aLayerIt.Next())
c357e426 644 {
1593b4ee 645 if (aLayerIt.Value() == theLayerId)
c357e426 646 {
1593b4ee 647 myLayerSeq.Remove (aLayerIt);
c357e426 648 break;
649 }
650 }
651
652 myMapOfZLayerSettings.UnBind (theLayerId);
653 myLayerIds.Remove (theLayerId);
a174a3c5 654}
655
c357e426 656//=======================================================================
657//function : ZLayers
658//purpose :
659//=======================================================================
660void OpenGl_GraphicDriver::ZLayers (TColStd_SequenceOfInteger& theLayerSeq) const
a174a3c5 661{
c357e426 662 theLayerSeq.Assign (myLayerSeq);
a174a3c5 663}
664
c357e426 665//=======================================================================
666//function : SetZLayerSettings
667//purpose :
668//=======================================================================
669void OpenGl_GraphicDriver::SetZLayerSettings (const Graphic3d_ZLayerId theLayerId,
670 const Graphic3d_ZLayerSettings& theSettings)
a174a3c5 671{
1593b4ee 672 Graphic3d_ZLayerSettings* aSettings = myMapOfZLayerSettings.ChangeSeek (theLayerId);
673 if (aSettings != NULL)
c357e426 674 {
7c3ef2f7 675 const bool isChanged = (aSettings->IsImmediate() != theSettings.IsImmediate());
1593b4ee 676 *aSettings = theSettings;
677 if (isChanged)
678 {
679 addZLayerIndex (theLayerId);
680 }
c357e426 681 }
682 else
683 {
1593b4ee 684 // abnormal case
c357e426 685 myMapOfZLayerSettings.Bind (theLayerId, theSettings);
1593b4ee 686 addZLayerIndex (theLayerId);
c357e426 687 }
7c3ef2f7 688
689 // Change Z layer settings in all managed views
690 for (NCollection_Map<Handle(OpenGl_View)>::Iterator aViewIt (myMapOfView); aViewIt.More(); aViewIt.Next())
691 {
692 aViewIt.Value()->SetZLayerSettings (theLayerId, theSettings);
693 }
a174a3c5 694}
695
c357e426 696//=======================================================================
697//function : ZLayerSettings
698//purpose :
699//=======================================================================
7c3ef2f7 700const Graphic3d_ZLayerSettings& OpenGl_GraphicDriver::ZLayerSettings (const Graphic3d_ZLayerId theLayerId) const
a174a3c5 701{
c357e426 702 Standard_ASSERT_RAISE (myLayerIds.Contains (theLayerId),
703 "OpenGl_GraphicDriver::ZLayerSettings, "
704 "Layer with theLayerId does not exist");
705
706 return myMapOfZLayerSettings.Find (theLayerId);
a174a3c5 707}
708
709// =======================================================================
c357e426 710// function : Structure
a174a3c5 711// purpose :
712// =======================================================================
c357e426 713Handle(Graphic3d_CStructure) OpenGl_GraphicDriver::CreateStructure (const Handle(Graphic3d_StructureManager)& theManager)
a174a3c5 714{
c357e426 715 Handle(OpenGl_Structure) aStructure = new OpenGl_Structure (theManager);
716 myMapOfStructure.Bind (aStructure->Id, aStructure.operator->());
717 return aStructure;
a174a3c5 718}
719
720// =======================================================================
c357e426 721// function : Structure
a174a3c5 722// purpose :
723// =======================================================================
c357e426 724void OpenGl_GraphicDriver::RemoveStructure (Handle(Graphic3d_CStructure)& theCStructure)
a174a3c5 725{
c357e426 726 OpenGl_Structure* aStructure = NULL;
727 if (!myMapOfStructure.Find (theCStructure->Id, aStructure))
a174a3c5 728 {
c357e426 729 return;
a174a3c5 730 }
c357e426 731
732 myMapOfStructure.UnBind (theCStructure->Id);
733 aStructure->Release (GetSharedContext());
734 theCStructure.Nullify();
a174a3c5 735}
736
737// =======================================================================
c357e426 738// function : View
a174a3c5 739// purpose :
740// =======================================================================
c357e426 741Handle(Graphic3d_CView) OpenGl_GraphicDriver::CreateView (const Handle(Graphic3d_StructureManager)& theMgr)
a174a3c5 742{
851dacdb 743 Handle(OpenGl_View) aView = new OpenGl_View (theMgr, this, myCaps, &myStateCounter);
c357e426 744
745 myMapOfView.Add (aView);
746
747 for (TColStd_SequenceOfInteger::Iterator aLayerIt (myLayerSeq); aLayerIt.More(); aLayerIt.Next())
a174a3c5 748 {
c357e426 749 const Graphic3d_ZLayerId aLayerID = aLayerIt.Value();
750 const Graphic3d_ZLayerSettings& aSettings = myMapOfZLayerSettings.Find (aLayerID);
751 aView->AddZLayer (aLayerID);
752 aView->SetZLayerSettings (aLayerID, aSettings);
a174a3c5 753 }
c357e426 754
755 return aView;
a174a3c5 756}
757
758// =======================================================================
c357e426 759// function : RemoveView
a174a3c5 760// purpose :
761// =======================================================================
c357e426 762void OpenGl_GraphicDriver::RemoveView (const Handle(Graphic3d_CView)& theView)
a174a3c5 763{
c357e426 764 Handle(OpenGl_Context) aCtx = GetSharedContext();
765 Handle(OpenGl_View) aView = Handle(OpenGl_View)::DownCast (theView);
766 if (aView.IsNull())
a174a3c5 767 {
c357e426 768 return;
a174a3c5 769 }
a174a3c5 770
c357e426 771 if (!myMapOfView.Remove (aView))
772 {
773 return;
774 }
775
776 Handle(OpenGl_Window) aWindow = aView->GlWindow();
777 if (!aWindow.IsNull()
778 && aWindow->GetGlContext()->MakeCurrent())
a79f67f8 779 {
c357e426 780 aCtx = aWindow->GetGlContext();
781 }
782 else
783 {
784 // try to hijack another context if any
785 const Handle(OpenGl_Context)& anOtherCtx = GetSharedContext();
786 if (!anOtherCtx.IsNull()
787 && anOtherCtx != aWindow->GetGlContext())
788 {
789 aCtx = anOtherCtx;
790 aCtx->MakeCurrent();
791 }
792 }
793
794 aView->ReleaseGlResources (aCtx);
795 if (myMapOfView.IsEmpty())
796 {
797 // The last view removed but some objects still present.
798 // Release GL resources now without object destruction.
799 for (NCollection_DataMap<Standard_Integer, OpenGl_Structure*>::Iterator aStructIt (myMapOfStructure);
800 aStructIt.More (); aStructIt.Next())
801 {
802 OpenGl_Structure* aStruct = aStructIt.ChangeValue();
803 aStruct->ReleaseGlResources (aCtx);
804 }
851dacdb 805
806 if (!myMapOfStructure.IsEmpty())
807 {
808 aView->StructureManager()->SetDeviceLost();
809 }
a79f67f8 810 }
a174a3c5 811}
62e1beed 812
813// =======================================================================
c357e426 814// function : Window
62e1beed 815// purpose :
816// =======================================================================
c357e426 817Handle(OpenGl_Window) OpenGl_GraphicDriver::CreateRenderWindow (const Handle(Aspect_Window)& theWindow,
818 const Aspect_RenderingContext theContext)
62e1beed 819{
c357e426 820 Handle(OpenGl_Context) aShareCtx = GetSharedContext();
821 Handle(OpenGl_Window) aWindow = new OpenGl_Window (this, theWindow, theContext, myCaps, aShareCtx);
822 return aWindow;
62e1beed 823}
27f85086 824
c357e426 825//=======================================================================
826//function : ViewExists
827//purpose :
828//=======================================================================
829Standard_Boolean OpenGl_GraphicDriver::ViewExists (const Handle(Aspect_Window)& AWindow, Handle(Graphic3d_CView)& theView)
27f85086 830{
c357e426 831 Standard_Boolean isExist = Standard_False;
832
833 // Parse the list of views to find
834 // a view with the specified window
835
1ce0716b 836#if defined(_WIN32) && !defined(OCCT_UWP)
c357e426 837 const Handle(WNT_Window) THEWindow = Handle(WNT_Window)::DownCast (AWindow);
838 Aspect_Handle TheSpecifiedWindowId = THEWindow->HWindow ();
839#elif defined(__APPLE__) && !defined(MACOSX_USE_GLX)
840 const Handle(Cocoa_Window) THEWindow = Handle(Cocoa_Window)::DownCast (AWindow);
841 #if defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE
842 UIView* TheSpecifiedWindowId = THEWindow->HView();
843 #else
844 NSView* TheSpecifiedWindowId = THEWindow->HView();
845 #endif
1ce0716b 846#elif defined(__ANDROID__) || defined(__QNX__) || defined(OCCT_UWP)
20aeeb7b 847 (void )AWindow;
c357e426 848 int TheSpecifiedWindowId = -1;
849#else
850 const Handle(Xw_Window) THEWindow = Handle(Xw_Window)::DownCast (AWindow);
851 int TheSpecifiedWindowId = int (THEWindow->XWindow ());
852#endif
853
854 NCollection_Map<Handle(OpenGl_View)>::Iterator aViewIt (myMapOfView);
855 for(; aViewIt.More(); aViewIt.Next())
27f85086 856 {
c357e426 857 const Handle(OpenGl_View)& aView = aViewIt.Value();
858 if (aView->IsDefined() && aView->IsActive())
859 {
860 const Handle(Aspect_Window) AspectWindow = aView->Window();
861
1ce0716b 862#if defined(_WIN32) && !defined(OCCT_UWP)
c357e426 863 const Handle(WNT_Window) theWindow = Handle(WNT_Window)::DownCast (AspectWindow);
864 Aspect_Handle TheWindowIdOfView = theWindow->HWindow ();
865#elif defined(__APPLE__) && !defined(MACOSX_USE_GLX)
866 const Handle(Cocoa_Window) theWindow = Handle(Cocoa_Window)::DownCast (AspectWindow);
867 #if defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE
868 UIView* TheWindowIdOfView = theWindow->HView();
869 #else
870 NSView* TheWindowIdOfView = theWindow->HView();
871 #endif
1ce0716b 872#elif defined(__ANDROID__) || defined(__QNX__) || defined(OCCT_UWP)
c357e426 873 int TheWindowIdOfView = 0;
874#else
875 const Handle(Xw_Window) theWindow = Handle(Xw_Window)::DownCast (AspectWindow);
876 int TheWindowIdOfView = int (theWindow->XWindow ());
877#endif // WNT
878 // Comparaison on window IDs
879 if (TheWindowIdOfView == TheSpecifiedWindowId)
880 {
881 isExist = Standard_True;
882 theView = aView;
883 }
884 }
27f85086 885 }
886
c357e426 887 return isExist;
27f85086 888}
851dacdb 889
890//=======================================================================
891//function : setDeviceLost
892//purpose :
893//=======================================================================
894void OpenGl_GraphicDriver::setDeviceLost()
895{
896 if (myMapOfStructure.IsEmpty())
897 {
898 return;
899 }
900
901 for (NCollection_Map<Handle(OpenGl_View)>::Iterator aViewIter (myMapOfView); aViewIter.More(); aViewIter.Next())
902 {
903 const Handle(OpenGl_View)& aView = aViewIter.Value();
904 if (aView->myWasRedrawnGL)
905 {
906 aView->StructureManager()->SetDeviceLost();
907 }
908 }
909}