0027607: Visualization - Implement adaptive screen space sampling in path tracing
[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>
28#include <OpenGl_Trihedron.hxx>
2166f0fa 29#include <OpenGl_Workspace.hxx>
7fd59977 30
25b97fac 31#include <Aspect_GraphicDeviceDefinitionError.hxx>
c357e426 32#include <Aspect_IdentDefinitionError.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
f0430952 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 {
73192b37 80 //Aspect_GraphicDeviceDefinitionError::Raise ("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 {
101 Aspect_GraphicDeviceDefinitionError::Raise ("OpenGl_GraphicDriver: default context can not be initialized!");
102 }
c357e426 103
104 // default layers are always presented in display layer sequence it can not be removed
105 Graphic3d_ZLayerSettings anUnderlaySettings;
106 anUnderlaySettings.Flags = 0;
107 anUnderlaySettings.IsImmediate = false;
83da37b1 108 anUnderlaySettings.UseEnvironmentTexture = false;
c357e426 109 myLayerIds.Add (Graphic3d_ZLayerId_BotOSD);
110 myLayerSeq.Append (Graphic3d_ZLayerId_BotOSD);
111 myMapOfZLayerSettings.Bind (Graphic3d_ZLayerId_BotOSD, anUnderlaySettings);
112
113 Graphic3d_ZLayerSettings aDefSettings;
114 aDefSettings.Flags = Graphic3d_ZLayerDepthTest
115 | Graphic3d_ZLayerDepthWrite;
116 aDefSettings.IsImmediate = false;
117 myLayerIds.Add (Graphic3d_ZLayerId_Default);
118 myLayerSeq.Append (Graphic3d_ZLayerId_Default);
119 myMapOfZLayerSettings.Bind (Graphic3d_ZLayerId_Default, aDefSettings);
120
121 Graphic3d_ZLayerSettings aTopSettings;
122 aTopSettings.Flags = Graphic3d_ZLayerDepthTest
123 | Graphic3d_ZLayerDepthWrite;
124 aTopSettings.IsImmediate = true;
125 myLayerIds.Add (Graphic3d_ZLayerId_Top);
126 myLayerSeq.Append (Graphic3d_ZLayerId_Top);
127 myMapOfZLayerSettings.Bind (Graphic3d_ZLayerId_Top, aTopSettings);
128
129 Graphic3d_ZLayerSettings aTopmostSettings;
130 aTopmostSettings.Flags = Graphic3d_ZLayerDepthTest
131 | Graphic3d_ZLayerDepthWrite
132 | Graphic3d_ZLayerDepthClear;
133 aTopmostSettings.IsImmediate = true;
134 myLayerIds.Add (Graphic3d_ZLayerId_Topmost);
135 myLayerSeq.Append (Graphic3d_ZLayerId_Topmost);
136 myMapOfZLayerSettings.Bind (Graphic3d_ZLayerId_Topmost, aTopmostSettings);
137
138 Graphic3d_ZLayerSettings anOsdSettings;
139 anOsdSettings.Flags = 0;
140 anOsdSettings.IsImmediate = true;
83da37b1 141 anOsdSettings.UseEnvironmentTexture = false;
c357e426 142 myLayerIds.Add (Graphic3d_ZLayerId_TopOSD);
143 myLayerSeq.Append (Graphic3d_ZLayerId_TopOSD);
144 myMapOfZLayerSettings.Bind (Graphic3d_ZLayerId_TopOSD, anOsdSettings);
05e2200b 145}
25b97fac 146
05e2200b 147// =======================================================================
148// function : ~OpenGl_GraphicDriver
149// purpose :
150// =======================================================================
151OpenGl_GraphicDriver::~OpenGl_GraphicDriver()
152{
153 ReleaseContext();
154}
155
156// =======================================================================
157// function : ReleaseContext
158// purpose :
159// =======================================================================
160void OpenGl_GraphicDriver::ReleaseContext()
161{
162 Handle(OpenGl_Context) aCtxShared;
c357e426 163 for (NCollection_Map<Handle(OpenGl_View)>::Iterator aViewIter (myMapOfView);
164 aViewIter.More(); aViewIter.Next())
25b97fac 165 {
c357e426 166 const Handle(OpenGl_View)& aView = aViewIter.ChangeValue();
167 const Handle(OpenGl_Window)& aWindow = aView->GlWindow();
168 if (aWindow.IsNull())
169 {
170 continue;
171 }
172
173 const Handle(OpenGl_Context)& aCtx = aWindow->GetGlContext();
05e2200b 174 if (aCtx->MakeCurrent()
175 && aCtxShared.IsNull())
25b97fac 176 {
05e2200b 177 aCtxShared = aCtx;
25b97fac 178 }
05e2200b 179 }
180
181 if (!aCtxShared.IsNull())
182 {
183 aCtxShared->MakeCurrent();
184 }
a272ed94 185 for (NCollection_Map<Handle(OpenGl_View)>::Iterator aViewIter (myMapOfView);
05e2200b 186 aViewIter.More(); aViewIter.Next())
187 {
188 const Handle(OpenGl_View)& aView = aViewIter.ChangeValue();
189 aView->ReleaseGlResources (aCtxShared);
190 }
191
192 for (NCollection_DataMap<Standard_Integer, OpenGl_Structure*>::Iterator aStructIt (myMapOfStructure);
193 aStructIt.More (); aStructIt.Next())
194 {
195 OpenGl_Structure* aStruct = aStructIt.ChangeValue();
196 aStruct->ReleaseGlResources (aCtxShared);
197 }
05e2200b 198 myDeviceLostFlag = myDeviceLostFlag || !myMapOfStructure.IsEmpty();
199
c357e426 200 for (NCollection_Map<Handle(OpenGl_View)>::Iterator aViewIter (myMapOfView);
201 aViewIter.More(); aViewIter.Next())
05e2200b 202 {
c357e426 203 const Handle(OpenGl_View)& aView = aViewIter.ChangeValue();
204 const Handle(OpenGl_Window)& aWindow = aView->GlWindow();
205 if (aWindow.IsNull())
206 {
207 continue;
208 }
209
210 aWindow->GetGlContext()->forcedRelease();
05e2200b 211 }
25b97fac 212
1ce0716b 213#if defined(HAVE_EGL) || defined(HAVE_GLES2) || defined(OCCT_UWP) || defined(__ANDROID__) || defined(__QNX__)
05e2200b 214 if (myIsOwnContext)
215 {
216 if (myEglContext != (Aspect_RenderingContext )EGL_NO_CONTEXT)
25b97fac 217 {
05e2200b 218 if (eglMakeCurrent ((EGLDisplay )myEglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT) != EGL_TRUE)
219 {
220 ::Message::DefaultMessenger()->Send ("OpenGl_GraphicDriver, FAILED to release OpenGL context!", Message_Warning);
221 }
222 eglDestroyContext ((EGLDisplay )myEglDisplay, (EGLContext )myEglContext);
223 }
25b97fac 224
05e2200b 225 if (myEglDisplay != (Aspect_Display )EGL_NO_DISPLAY)
25b97fac 226 {
05e2200b 227 if (eglTerminate ((EGLDisplay )myEglDisplay) != EGL_TRUE)
228 {
229 ::Message::DefaultMessenger()->Send ("OpenGl_GraphicDriver, EGL, eglTerminate FAILED!", Message_Warning);
230 }
25b97fac 231 }
25b97fac 232 }
233
05e2200b 234 myEglDisplay = (Aspect_Display )EGL_NO_DISPLAY;
235 myEglContext = (Aspect_RenderingContext )EGL_NO_CONTEXT;
236 myEglConfig = NULL;
237#endif
238 myIsOwnContext = Standard_False;
239}
240
241// =======================================================================
242// function : InitContext
243// purpose :
244// =======================================================================
245Standard_Boolean OpenGl_GraphicDriver::InitContext()
246{
247 ReleaseContext();
1ce0716b 248#if defined(HAVE_EGL) || defined(HAVE_GLES2) || defined(OCCT_UWP) || defined(__ANDROID__) || defined(__QNX__)
05e2200b 249
d8d01f6e 250#if !defined(_WIN32) && !defined(__ANDROID__) && !defined(__QNX__) && (!defined(__APPLE__) || defined(MACOSX_USE_GLX))
05e2200b 251 if (myDisplayConnection.IsNull())
252 {
253 return Standard_False;
254 }
255 Display* aDisplay = myDisplayConnection->GetDisplay();
25b97fac 256 myEglDisplay = (Aspect_Display )eglGetDisplay (aDisplay);
257#else
258 myEglDisplay = (Aspect_Display )eglGetDisplay (EGL_DEFAULT_DISPLAY);
259#endif
260 if ((EGLDisplay )myEglDisplay == EGL_NO_DISPLAY)
261 {
05e2200b 262 ::Message::DefaultMessenger()->Send ("Error: no EGL display!", Message_Fail);
263 return Standard_False;
25b97fac 264 }
265
266 EGLint aVerMajor = 0; EGLint aVerMinor = 0;
267 if (eglInitialize ((EGLDisplay )myEglDisplay, &aVerMajor, &aVerMinor) != EGL_TRUE)
268 {
05e2200b 269 ::Message::DefaultMessenger()->Send ("Error: EGL display is unavailable!", Message_Fail);
270 return Standard_False;
25b97fac 271 }
272
05e2200b 273 EGLint aConfigAttribs[] =
25b97fac 274 {
275 EGL_RED_SIZE, 8,
276 EGL_GREEN_SIZE, 8,
277 EGL_BLUE_SIZE, 8,
278 EGL_ALPHA_SIZE, 0,
279 EGL_DEPTH_SIZE, 24,
280 EGL_STENCIL_SIZE, 8,
281 #if defined(GL_ES_VERSION_2_0)
282 EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
283 #else
284 EGL_RENDERABLE_TYPE, EGL_OPENGL_BIT,
285 #endif
286 EGL_NONE
287 };
288
289 EGLint aNbConfigs = 0;
05e2200b 290 if (eglChooseConfig ((EGLDisplay )myEglDisplay, aConfigAttribs, &myEglConfig, 1, &aNbConfigs) != EGL_TRUE
291 || myEglConfig == NULL)
25b97fac 292 {
05e2200b 293 eglGetError();
294 aConfigAttribs[4 * 2 + 1] = 16; // try config with smaller depth buffer
295 if (eglChooseConfig ((EGLDisplay )myEglDisplay, aConfigAttribs, &myEglConfig, 1, &aNbConfigs) != EGL_TRUE
296 || myEglConfig == NULL)
297 {
298 ::Message::DefaultMessenger()->Send ("Error: EGL does not provide compatible configurations!", Message_Fail);
299 return Standard_False;
300 }
25b97fac 301 }
25b97fac 302
303#if defined(GL_ES_VERSION_2_0)
304 EGLint anEglCtxAttribs[] =
305 {
306 EGL_CONTEXT_CLIENT_VERSION, 2,
307 EGL_NONE
308 };
05e2200b 309 if (eglBindAPI (EGL_OPENGL_ES_API) != EGL_TRUE)
310 {
311 ::Message::DefaultMessenger()->Send ("Error: EGL does not provide OpenGL ES client!", Message_Fail);
312 return Standard_False;
313 }
25b97fac 314#else
315 EGLint* anEglCtxAttribs = NULL;
05e2200b 316 if (eglBindAPI (EGL_OPENGL_API) != EGL_TRUE)
317 {
318 ::Message::DefaultMessenger()->Send ("Error: EGL does not provide OpenGL client!", Message_Fail);
319 return Standard_False;
320 }
25b97fac 321#endif
322
323 myEglContext = (Aspect_RenderingContext )eglCreateContext ((EGLDisplay )myEglDisplay, myEglConfig, EGL_NO_CONTEXT, anEglCtxAttribs);
324 if ((EGLContext )myEglContext == EGL_NO_CONTEXT)
325 {
05e2200b 326 ::Message::DefaultMessenger()->Send ("Error: EGL is unable to create OpenGL context!", Message_Fail);
327 return Standard_False;
25b97fac 328 }
1ce0716b 329 // eglMakeCurrent() fails or even crash with EGL_NO_SURFACE on some implementations
330 //if (eglMakeCurrent ((EGLDisplay )myEglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, (EGLContext )myEglContext) != EGL_TRUE)
331 //{
332 // ::Message::DefaultMessenger()->Send ("Error: EGL is unable bind OpenGL context!", Message_Fail);
333 // return Standard_False;
334 //}
25b97fac 335#endif
05e2200b 336 myIsOwnContext = Standard_True;
337 return Standard_True;
73192b37 338}
339
1ce0716b 340#if defined(HAVE_EGL) || defined(HAVE_GLES2) || defined(OCCT_UWP) || defined(__ANDROID__) || defined(__QNX__)
05e2200b 341// =======================================================================
342// function : InitEglContext
343// purpose :
344// =======================================================================
345Standard_Boolean OpenGl_GraphicDriver::InitEglContext (Aspect_Display theEglDisplay,
346 Aspect_RenderingContext theEglContext,
347 void* theEglConfig)
348{
349 ReleaseContext();
d8d01f6e 350#if !defined(_WIN32) && !defined(__ANDROID__) && !defined(__QNX__) && (!defined(__APPLE__) || defined(MACOSX_USE_GLX))
05e2200b 351 if (myDisplayConnection.IsNull())
352 {
353 return Standard_False;
354 }
355#endif
356
357 if ((EGLDisplay )theEglDisplay == EGL_NO_DISPLAY
358 || (EGLContext )theEglContext == EGL_NO_CONTEXT
359 || theEglConfig == NULL)
360 {
361 return Standard_False;
362 }
363 myEglDisplay = theEglDisplay;
364 myEglContext = theEglContext;
365 myEglConfig = theEglConfig;
366 return Standard_True;
367}
368#endif
369
73192b37 370// =======================================================================
3bffef55 371// function : InquireLimit
73192b37 372// purpose :
373// =======================================================================
3bffef55 374Standard_Integer OpenGl_GraphicDriver::InquireLimit (const Graphic3d_TypeOfLimit theType) const
73192b37 375{
73192b37 376 const Handle(OpenGl_Context)& aCtx = GetSharedContext();
3bffef55 377 switch (theType)
378 {
379 case Graphic3d_TypeOfLimit_MaxNbLights:
380 return OpenGLMaxLights;
381 case Graphic3d_TypeOfLimit_MaxNbClipPlanes:
382 return !aCtx.IsNull() ? aCtx->MaxClipPlanes() : 0;
383 case Graphic3d_TypeOfLimit_MaxNbViews:
384 return 10000;
385 case Graphic3d_TypeOfLimit_MaxTextureSize:
386 return !aCtx.IsNull() ? aCtx->MaxTextureSize() : 1024;
387 case Graphic3d_TypeOfLimit_MaxMsaa:
388 return !aCtx.IsNull() ? aCtx->MaxMsaaSamples() : 0;
3a9b5dc8 389 case Graphic3d_TypeOfLimit_HasRayTracing:
390 return (!aCtx.IsNull() && aCtx->HasRayTracing()) ? 1 : 0;
391 case Graphic3d_TypeOfLimit_HasRayTracingTextures:
392 return (!aCtx.IsNull() && aCtx->HasRayTracingTextures()) ? 1 : 0;
393 case Graphic3d_TypeOfLimit_HasRayTracingAdaptiveSampling:
394 return (!aCtx.IsNull() && aCtx->HasRayTracingAdaptiveSampling()) ? 1 : 0;
3bffef55 395 case Graphic3d_TypeOfLimit_NB:
396 return 0;
397 }
398 return 0;
73192b37 399}
400
401// =======================================================================
5e27df78 402// function : DefaultTextHeight
f0430952 403// purpose :
404// =======================================================================
5e27df78 405Standard_ShortReal OpenGl_GraphicDriver::DefaultTextHeight() const
2166f0fa 406{
5e27df78 407 return 16.;
2166f0fa
SK
408}
409
f0430952 410// =======================================================================
f0430952 411// function : EnableVBO
412// purpose :
413// =======================================================================
2166f0fa 414void OpenGl_GraphicDriver::EnableVBO (const Standard_Boolean theToTurnOn)
7fd59977 415{
58655684 416 myCaps->vboDisable = !theToTurnOn;
7fd59977 417}
f0430952 418
419// =======================================================================
5e27df78 420// function : GetSharedContext
421// purpose :
422// =======================================================================
423const Handle(OpenGl_Context)& OpenGl_GraphicDriver::GetSharedContext() const
424{
c357e426 425 if (myMapOfView.IsEmpty())
5e27df78 426 {
427 return TheNullGlCtx;
428 }
429
c357e426 430 NCollection_Map<Handle(OpenGl_View)>::Iterator anIter (myMapOfView);
431 for (; anIter.More(); anIter.Next())
432 {
433 Handle(OpenGl_Window) aWindow = anIter.Value()->GlWindow();
434 if (aWindow.IsNull())
435 {
436 continue;
437 }
438
439 return aWindow->GetGlContext();
440 }
441
442 return TheNullGlCtx;
5e27df78 443}
444
445// =======================================================================
f0430952 446// function : MemoryInfo
447// purpose :
448// =======================================================================
449Standard_Boolean OpenGl_GraphicDriver::MemoryInfo (Standard_Size& theFreeBytes,
450 TCollection_AsciiString& theInfo) const
451{
452 // this is extra work (for OpenGl_Context initialization)...
453 OpenGl_Context aGlCtx;
454 if (!aGlCtx.Init())
455 {
456 return Standard_False;
457 }
458 theFreeBytes = aGlCtx.AvailableMemory();
459 theInfo = aGlCtx.MemoryInfo();
460 return !theInfo.IsEmpty();
461}
1981cb22 462
463// =======================================================================
c357e426 464// function : SetBuffersNoSwap
1981cb22 465// purpose :
466// =======================================================================
c357e426 467void OpenGl_GraphicDriver::SetBuffersNoSwap (const Standard_Boolean theIsNoSwap)
1981cb22 468{
c357e426 469 myCaps->buffersNoSwap = theIsNoSwap;
1981cb22 470}
471
472// =======================================================================
c357e426 473// function : TextSize
a174a3c5 474// purpose :
475// =======================================================================
4b1c8733 476void OpenGl_GraphicDriver::TextSize (const Handle(Graphic3d_CView)& theView,
477 const Standard_CString theText,
478 const Standard_ShortReal theHeight,
479 Standard_ShortReal& theWidth,
480 Standard_ShortReal& theAscent,
481 Standard_ShortReal& theDescent) const
a174a3c5 482{
c357e426 483 const Handle(OpenGl_Context)& aCtx = GetSharedContext();
484 if (aCtx.IsNull())
a174a3c5 485 {
c357e426 486 return;
a174a3c5 487 }
488
c357e426 489 const Standard_ShortReal aHeight = (theHeight < 2.0f) ? DefaultTextHeight() : theHeight;
490 OpenGl_TextParam aTextParam;
491 aTextParam.Height = (int )aHeight;
492 OpenGl_AspectText aTextAspect;
b6472664 493 aTextAspect.Aspect()->SetSpace (0.3);
c357e426 494 TCollection_ExtendedString anExtText = theText;
fb0b0531 495 NCollection_String aText (anExtText.ToExtString());
4b1c8733 496 OpenGl_Text::StringSize(aCtx, aText, aTextAspect, aTextParam, theView->RenderingParams().Resolution, theWidth, theAscent, theDescent);
a174a3c5 497}
498
c357e426 499//=======================================================================
1593b4ee 500//function : addZLayerIndex
501//purpose :
502//=======================================================================
503void OpenGl_GraphicDriver::addZLayerIndex (const Graphic3d_ZLayerId theLayerId)
504{
505 // remove index
506 for (TColStd_SequenceOfInteger::Iterator aLayerIt (myLayerSeq); aLayerIt.More(); aLayerIt.Next())
507 {
508 if (aLayerIt.Value() == theLayerId)
509 {
510 myLayerSeq.Remove (aLayerIt);
511 break;
512 }
513 }
514
515 if (myMapOfZLayerSettings.Find (theLayerId).IsImmediate)
516 {
517 myLayerSeq.Append (theLayerId);
518 return;
519 }
520
521 for (TColStd_SequenceOfInteger::Iterator aLayerIt (myLayerSeq); aLayerIt.More(); aLayerIt.Next())
522 {
523 const Graphic3d_ZLayerSettings& aSettings = myMapOfZLayerSettings.Find (aLayerIt.Value());
524 if (aSettings.IsImmediate)
525 {
526 aLayerIt.Previous();
527 if (aLayerIt.More())
528 {
529 myLayerSeq.InsertAfter (aLayerIt, theLayerId);
530 return;
531 }
532
533 // first non-immediate layer
534 myLayerSeq.Prepend (theLayerId);
535 return;
536 }
537 }
538
539 // no immediate layers
540 myLayerSeq.Append (theLayerId);
541}
542
543//=======================================================================
c357e426 544//function : AddZLayer
545//purpose :
546//=======================================================================
547void OpenGl_GraphicDriver::AddZLayer (const Graphic3d_ZLayerId theLayerId)
a174a3c5 548{
c357e426 549 if (theLayerId < 1)
536d98e2 550 {
c357e426 551 Standard_ASSERT_RAISE (theLayerId > 0,
552 "OpenGl_GraphicDriver::AddZLayer, "
553 "negative and zero IDs are reserved");
536d98e2 554 }
555
1593b4ee 556 myLayerIds.Add (theLayerId);
a174a3c5 557
c357e426 558 // Default z-layer settings
559 myMapOfZLayerSettings.Bind (theLayerId, Graphic3d_ZLayerSettings());
1593b4ee 560 addZLayerIndex (theLayerId);
c357e426 561
562 // Add layer to all views
563 NCollection_Map<Handle(OpenGl_View)>::Iterator aViewIt (myMapOfView);
564 for (; aViewIt.More(); aViewIt.Next())
a174a3c5 565 {
c357e426 566 aViewIt.Value()->AddZLayer (theLayerId);
a174a3c5 567 }
568}
569
c357e426 570//=======================================================================
571//function : RemoveZLayer
572//purpose :
573//=======================================================================
574void OpenGl_GraphicDriver::RemoveZLayer (const Graphic3d_ZLayerId theLayerId)
a174a3c5 575{
c357e426 576 Standard_ASSERT_RAISE (theLayerId > 0,
577 "OpenGl_GraphicDriver::AddZLayer, "
578 "negative and zero IDs are reserved"
579 "and can not be removed");
580
581 Standard_ASSERT_RAISE (myLayerIds.Contains (theLayerId),
582 "OpenGl_GraphicDriver::RemoveZLayer, "
583 "Layer with theLayerId does not exist");
584
585 // Remove layer from all of the views
586 NCollection_Map<Handle(OpenGl_View)>::Iterator aViewIt (myMapOfView);
587 for (; aViewIt.More(); aViewIt.Next())
588 {
589 aViewIt.Value()->RemoveZLayer (theLayerId);
590 }
591
592 // Unset Z layer for all of the structures.
593 NCollection_DataMap<Standard_Integer, OpenGl_Structure*>::Iterator aStructIt (myMapOfStructure);
594 for( ; aStructIt.More (); aStructIt.Next ())
a174a3c5 595 {
c357e426 596 OpenGl_Structure* aStruct = aStructIt.ChangeValue ();
597 if (aStruct->ZLayer() == theLayerId)
598 aStruct->SetZLayer (Graphic3d_ZLayerId_Default);
a174a3c5 599 }
c357e426 600
601 // Remove index
1593b4ee 602 for (TColStd_SequenceOfInteger::Iterator aLayerIt (myLayerSeq); aLayerIt.More(); aLayerIt.Next())
c357e426 603 {
1593b4ee 604 if (aLayerIt.Value() == theLayerId)
c357e426 605 {
1593b4ee 606 myLayerSeq.Remove (aLayerIt);
c357e426 607 break;
608 }
609 }
610
611 myMapOfZLayerSettings.UnBind (theLayerId);
612 myLayerIds.Remove (theLayerId);
a174a3c5 613}
614
c357e426 615//=======================================================================
616//function : ZLayers
617//purpose :
618//=======================================================================
619void OpenGl_GraphicDriver::ZLayers (TColStd_SequenceOfInteger& theLayerSeq) const
a174a3c5 620{
c357e426 621 theLayerSeq.Assign (myLayerSeq);
a174a3c5 622}
623
c357e426 624//=======================================================================
625//function : SetZLayerSettings
626//purpose :
627//=======================================================================
628void OpenGl_GraphicDriver::SetZLayerSettings (const Graphic3d_ZLayerId theLayerId,
629 const Graphic3d_ZLayerSettings& theSettings)
a174a3c5 630{
c357e426 631 // Change Z layer settings in all managed views
632 NCollection_Map<Handle(OpenGl_View)>::Iterator aViewIt (myMapOfView);
633 for (; aViewIt.More(); aViewIt.Next())
a174a3c5 634 {
c357e426 635 aViewIt.Value()->SetZLayerSettings (theLayerId, theSettings);
a174a3c5 636 }
637
1593b4ee 638 Graphic3d_ZLayerSettings* aSettings = myMapOfZLayerSettings.ChangeSeek (theLayerId);
639 if (aSettings != NULL)
c357e426 640 {
1593b4ee 641 const bool isChanged = (aSettings->IsImmediate != theSettings.IsImmediate);
642 *aSettings = theSettings;
643 if (isChanged)
644 {
645 addZLayerIndex (theLayerId);
646 }
c357e426 647 }
648 else
649 {
1593b4ee 650 // abnormal case
c357e426 651 myMapOfZLayerSettings.Bind (theLayerId, theSettings);
1593b4ee 652 addZLayerIndex (theLayerId);
c357e426 653 }
a174a3c5 654}
655
c357e426 656//=======================================================================
657//function : ZLayerSettings
658//purpose :
659//=======================================================================
660Graphic3d_ZLayerSettings OpenGl_GraphicDriver::ZLayerSettings (const Graphic3d_ZLayerId theLayerId)
a174a3c5 661{
c357e426 662 Standard_ASSERT_RAISE (myLayerIds.Contains (theLayerId),
663 "OpenGl_GraphicDriver::ZLayerSettings, "
664 "Layer with theLayerId does not exist");
665
666 return myMapOfZLayerSettings.Find (theLayerId);
a174a3c5 667}
668
669// =======================================================================
c357e426 670// function : Structure
a174a3c5 671// purpose :
672// =======================================================================
c357e426 673Handle(Graphic3d_CStructure) OpenGl_GraphicDriver::CreateStructure (const Handle(Graphic3d_StructureManager)& theManager)
a174a3c5 674{
c357e426 675 Handle(OpenGl_Structure) aStructure = new OpenGl_Structure (theManager);
676 myMapOfStructure.Bind (aStructure->Id, aStructure.operator->());
677 return aStructure;
a174a3c5 678}
679
680// =======================================================================
c357e426 681// function : Structure
a174a3c5 682// purpose :
683// =======================================================================
c357e426 684void OpenGl_GraphicDriver::RemoveStructure (Handle(Graphic3d_CStructure)& theCStructure)
a174a3c5 685{
c357e426 686 OpenGl_Structure* aStructure = NULL;
687 if (!myMapOfStructure.Find (theCStructure->Id, aStructure))
a174a3c5 688 {
c357e426 689 return;
a174a3c5 690 }
c357e426 691
692 myMapOfStructure.UnBind (theCStructure->Id);
693 aStructure->Release (GetSharedContext());
694 theCStructure.Nullify();
a174a3c5 695}
696
697// =======================================================================
c357e426 698// function : View
a174a3c5 699// purpose :
700// =======================================================================
c357e426 701Handle(Graphic3d_CView) OpenGl_GraphicDriver::CreateView (const Handle(Graphic3d_StructureManager)& theMgr)
a174a3c5 702{
c357e426 703 Handle(OpenGl_View) aView = new OpenGl_View (theMgr, this, myCaps, myDeviceLostFlag, &myStateCounter);
704
705 myMapOfView.Add (aView);
706
707 for (TColStd_SequenceOfInteger::Iterator aLayerIt (myLayerSeq); aLayerIt.More(); aLayerIt.Next())
a174a3c5 708 {
c357e426 709 const Graphic3d_ZLayerId aLayerID = aLayerIt.Value();
710 const Graphic3d_ZLayerSettings& aSettings = myMapOfZLayerSettings.Find (aLayerID);
711 aView->AddZLayer (aLayerID);
712 aView->SetZLayerSettings (aLayerID, aSettings);
a174a3c5 713 }
c357e426 714
715 return aView;
a174a3c5 716}
717
718// =======================================================================
c357e426 719// function : RemoveView
a174a3c5 720// purpose :
721// =======================================================================
c357e426 722void OpenGl_GraphicDriver::RemoveView (const Handle(Graphic3d_CView)& theView)
a174a3c5 723{
c357e426 724 Handle(OpenGl_Context) aCtx = GetSharedContext();
725 Handle(OpenGl_View) aView = Handle(OpenGl_View)::DownCast (theView);
726 if (aView.IsNull())
a174a3c5 727 {
c357e426 728 return;
a174a3c5 729 }
a174a3c5 730
c357e426 731 if (!myMapOfView.Remove (aView))
732 {
733 return;
734 }
735
736 Handle(OpenGl_Window) aWindow = aView->GlWindow();
737 if (!aWindow.IsNull()
738 && aWindow->GetGlContext()->MakeCurrent())
a79f67f8 739 {
c357e426 740 aCtx = aWindow->GetGlContext();
741 }
742 else
743 {
744 // try to hijack another context if any
745 const Handle(OpenGl_Context)& anOtherCtx = GetSharedContext();
746 if (!anOtherCtx.IsNull()
747 && anOtherCtx != aWindow->GetGlContext())
748 {
749 aCtx = anOtherCtx;
750 aCtx->MakeCurrent();
751 }
752 }
753
754 aView->ReleaseGlResources (aCtx);
755 if (myMapOfView.IsEmpty())
756 {
757 // The last view removed but some objects still present.
758 // Release GL resources now without object destruction.
759 for (NCollection_DataMap<Standard_Integer, OpenGl_Structure*>::Iterator aStructIt (myMapOfStructure);
760 aStructIt.More (); aStructIt.Next())
761 {
762 OpenGl_Structure* aStruct = aStructIt.ChangeValue();
763 aStruct->ReleaseGlResources (aCtx);
764 }
765 myDeviceLostFlag = !myMapOfStructure.IsEmpty();
a79f67f8 766 }
a174a3c5 767}
62e1beed 768
769// =======================================================================
c357e426 770// function : Window
62e1beed 771// purpose :
772// =======================================================================
c357e426 773Handle(OpenGl_Window) OpenGl_GraphicDriver::CreateRenderWindow (const Handle(Aspect_Window)& theWindow,
774 const Aspect_RenderingContext theContext)
62e1beed 775{
c357e426 776 Handle(OpenGl_Context) aShareCtx = GetSharedContext();
777 Handle(OpenGl_Window) aWindow = new OpenGl_Window (this, theWindow, theContext, myCaps, aShareCtx);
778 return aWindow;
62e1beed 779}
27f85086 780
c357e426 781//=======================================================================
782//function : ViewExists
783//purpose :
784//=======================================================================
785Standard_Boolean OpenGl_GraphicDriver::ViewExists (const Handle(Aspect_Window)& AWindow, Handle(Graphic3d_CView)& theView)
27f85086 786{
c357e426 787 Standard_Boolean isExist = Standard_False;
788
789 // Parse the list of views to find
790 // a view with the specified window
791
1ce0716b 792#if defined(_WIN32) && !defined(OCCT_UWP)
c357e426 793 const Handle(WNT_Window) THEWindow = Handle(WNT_Window)::DownCast (AWindow);
794 Aspect_Handle TheSpecifiedWindowId = THEWindow->HWindow ();
795#elif defined(__APPLE__) && !defined(MACOSX_USE_GLX)
796 const Handle(Cocoa_Window) THEWindow = Handle(Cocoa_Window)::DownCast (AWindow);
797 #if defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE
798 UIView* TheSpecifiedWindowId = THEWindow->HView();
799 #else
800 NSView* TheSpecifiedWindowId = THEWindow->HView();
801 #endif
1ce0716b 802#elif defined(__ANDROID__) || defined(__QNX__) || defined(OCCT_UWP)
20aeeb7b 803 (void )AWindow;
c357e426 804 int TheSpecifiedWindowId = -1;
805#else
806 const Handle(Xw_Window) THEWindow = Handle(Xw_Window)::DownCast (AWindow);
807 int TheSpecifiedWindowId = int (THEWindow->XWindow ());
808#endif
809
810 NCollection_Map<Handle(OpenGl_View)>::Iterator aViewIt (myMapOfView);
811 for(; aViewIt.More(); aViewIt.Next())
27f85086 812 {
c357e426 813 const Handle(OpenGl_View)& aView = aViewIt.Value();
814 if (aView->IsDefined() && aView->IsActive())
815 {
816 const Handle(Aspect_Window) AspectWindow = aView->Window();
817
1ce0716b 818#if defined(_WIN32) && !defined(OCCT_UWP)
c357e426 819 const Handle(WNT_Window) theWindow = Handle(WNT_Window)::DownCast (AspectWindow);
820 Aspect_Handle TheWindowIdOfView = theWindow->HWindow ();
821#elif defined(__APPLE__) && !defined(MACOSX_USE_GLX)
822 const Handle(Cocoa_Window) theWindow = Handle(Cocoa_Window)::DownCast (AspectWindow);
823 #if defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE
824 UIView* TheWindowIdOfView = theWindow->HView();
825 #else
826 NSView* TheWindowIdOfView = theWindow->HView();
827 #endif
1ce0716b 828#elif defined(__ANDROID__) || defined(__QNX__) || defined(OCCT_UWP)
c357e426 829 int TheWindowIdOfView = 0;
830#else
831 const Handle(Xw_Window) theWindow = Handle(Xw_Window)::DownCast (AspectWindow);
832 int TheWindowIdOfView = int (theWindow->XWindow ());
833#endif // WNT
834 // Comparaison on window IDs
835 if (TheWindowIdOfView == TheSpecifiedWindowId)
836 {
837 isExist = Standard_True;
838 theView = aView;
839 }
840 }
27f85086 841 }
842
c357e426 843 return isExist;
27f85086 844}