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