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