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