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