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