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