1 /*=========================================================================
2
3 Program: Visualization Toolkit
4 Module: vtkEGLRenderWindow.cxx
5
6 Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
7 All rights reserved.
8 See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
9
10 This software is distributed WITHOUT ANY WARRANTY; without even
11 the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
12 PURPOSE. See the above copyright notice for more information.
13
14 =========================================================================*/
15
16 #include "vtkEGLRenderWindow.h"
17
18 #include "vtkAtomicTypes.h"
19 #include "vtkCommand.h"
20 #include "vtkIdList.h"
21 #include "vtkObjectFactory.h"
22 #include "vtkOpenGLRenderer.h"
23 #include "vtkRenderWindowInteractor.h"
24 #include "vtkRendererCollection.h"
25 #include "vtkToolkits.h"
26 #include "vtk_glew.h"
27 #include "vtksys/SystemTools.hxx"
28
29 #include <cassert>
30 #include <sstream>
31 #include <EGL/egl.h>
32
33 #ifdef ANDROID
34 #include <android/native_window.h>
35 #endif
36
37 namespace
38 {
39 typedef void* EGLDeviceEXT;
40 typedef EGLBoolean (*EGLQueryDevicesType)(EGLint,EGLDeviceEXT*,EGLint*);
41 typedef EGLDisplay (*EGLGetPlatformDisplayType)(EGLenum, void *, const EGLint *);
42 const EGLenum EGL_PLATFORM_DEVICE_EXT = 0x313F;
43
44 /**
45 * EGLDisplay provided by eglGetDisplay() call can be same handle for multiple
46 * instances of vtkEGLRenderWindow. In which case, while it's safe to call
47 * eglInitialize() repeatedly, eglTerminate() should only be called once after
48 * the final instance of the window is destroyed. This class helps us do
49 * that. See paraview/paraview#16928.
50 */
51 class vtkEGLDisplayInitializationHelper
52 {
53 static std::map<EGLDisplay, vtkAtomicInt64> DisplayUsageCounts;
54 public:
Initialize(EGLDisplay dpy,EGLint * major,EGLint * minor)55 static EGLBoolean Initialize(EGLDisplay dpy, EGLint *major, EGLint *minor)
56 {
57 ++DisplayUsageCounts[dpy];
58 return eglInitialize(dpy, major, minor);
59 }
Terminate(EGLDisplay dpy)60 static EGLBoolean Terminate(EGLDisplay dpy)
61 {
62 assert(DisplayUsageCounts.find(dpy) != DisplayUsageCounts.end());
63 if (--DisplayUsageCounts[dpy] == 0)
64 {
65 DisplayUsageCounts.erase(dpy);
66 return eglTerminate(dpy);
67 }
68 return EGL_TRUE;
69 }
70 };
71
72 std::map<EGLDisplay, vtkAtomicInt64>
73 vtkEGLDisplayInitializationHelper::DisplayUsageCounts;
74
75 struct vtkEGLDeviceExtensions
76 {
GetInstance__anoneb67c53f0111::vtkEGLDeviceExtensions77 static vtkEGLDeviceExtensions* GetInstance()
78 {
79 static vtkEGLDeviceExtensions* instance = nullptr;
80 if (instance == nullptr)
81 {
82 instance = new vtkEGLDeviceExtensions();
83 }
84 return instance;
85 }
Available__anoneb67c53f0111::vtkEGLDeviceExtensions86 bool Available()
87 {
88 return this->Available_;
89 }
90 bool Available_;
91 EGLQueryDevicesType eglQueryDevices;
92 EGLGetPlatformDisplayType eglGetPlatformDisplay;
93
94 private:
vtkEGLDeviceExtensions__anoneb67c53f0111::vtkEGLDeviceExtensions95 vtkEGLDeviceExtensions()
96 {
97 this->Available_ = false;
98 this->eglQueryDevices = nullptr;
99 this->eglGetPlatformDisplay = nullptr;
100 const char* s = eglQueryString(EGL_NO_DISPLAY, EGL_EXTENSIONS);
101 std::string platformExtensions(s);
102 if (platformExtensions.find("EGL_EXT_device_base") != std::string::npos &&
103 platformExtensions.find("EGL_EXT_platform_device") != std::string::npos &&
104 platformExtensions.find("EGL_EXT_platform_base") != std::string::npos)
105 {
106 this->eglQueryDevices = (EGLQueryDevicesType)eglGetProcAddress("eglQueryDevicesEXT");
107 this->eglGetPlatformDisplay = (EGLGetPlatformDisplayType)
108 eglGetProcAddress("eglGetPlatformDisplayEXT");
109 if(this->eglQueryDevices && this->eglGetPlatformDisplay)
110 {
111 this->Available_ = true;
112 }
113 }
114 }
115 };
116 };
117
118
119
120
121 vtkStandardNewMacro(vtkEGLRenderWindow);
122
123 struct vtkEGLRenderWindow::vtkInternals
124 {
125 EGLNativeWindowType Window;
126 EGLDisplay Display;
127 EGLSurface Surface;
128 EGLContext Context;
vtkInternalsvtkEGLRenderWindow::vtkInternals129 vtkInternals() : Window((EGLNativeWindowType)0),
130 Display(EGL_NO_DISPLAY),
131 Surface(EGL_NO_SURFACE),
132 Context(EGL_NO_CONTEXT)
133 {
134 }
135 };
136
vtkEGLRenderWindow()137 vtkEGLRenderWindow::vtkEGLRenderWindow()
138 {
139 this->Internals = new vtkInternals();
140 this->OwnWindow = 1;
141 this->ScreenSize[0] = 1920;
142 this->ScreenSize[1] = 1080;
143
144 // this is initialized in vtkRenderWindow
145 // so we don't need to initialize on else
146 #ifdef VTK_USE_OFFSCREEN_EGL
147 this->DeviceIndex = VTK_DEFAULT_EGL_DEVICE_INDEX;
148 #endif
149
150 // Use an environment variable to set the default device index
151 char *EGLDefaultDeviceIndexEnv = std::getenv("VTK_DEFAULT_EGL_DEVICE_INDEX");
152 if (EGLDefaultDeviceIndexEnv)
153 {
154 // If parsing the environment variable fails and throws an exception we
155 // can safely ignore it since a default is already set above.
156 try
157 {
158 this->DeviceIndex = atoi(EGLDefaultDeviceIndexEnv);
159 }
160 catch(const std::out_of_range&)
161 {
162 }
163 catch(const std::invalid_argument&)
164 {
165 }
166 }
167
168
169 #ifdef ANDROID
170 this->OffScreenRendering = false;
171 #else
172 // this is an offscreen-only window otherwise.
173 this->OffScreenRendering = true;
174 #endif
175
176 this->IsPointSpriteBugTested = false;
177 this->IsPointSpriteBugPresent_ = false;
178 }
179
180 // free up memory & close the window
~vtkEGLRenderWindow()181 vtkEGLRenderWindow::~vtkEGLRenderWindow()
182 {
183 // close-down all system-specific drawing resources
184 this->Finalize();
185
186 vtkRenderer *ren;
187 vtkCollectionSimpleIterator rit;
188 this->Renderers->InitTraversal(rit);
189 while ( (ren = this->Renderers->GetNextRenderer(rit)) )
190 {
191 ren->SetRenderWindow(nullptr);
192 }
193 delete this->Internals;
194 }
195
196 // End the rendering process and display the image.
Frame()197 void vtkEGLRenderWindow::Frame()
198 {
199 vtkInternals* impl = this->Internals;
200 this->MakeCurrent();
201 if (this->OwnWindow)
202 {
203 if (!this->AbortRender && this->DoubleBuffer && this->SwapBuffers
204 && impl->Display != EGL_NO_DISPLAY)
205 {
206 eglSwapBuffers(impl->Display, impl->Surface);
207 vtkDebugMacro(<< " eglSwapBuffers\n");
208 }
209 }
210 else
211 {
212 if (!this->AbortRender && this->DoubleBuffer && this->SwapBuffers)
213 {
214 eglSwapBuffers( eglGetCurrentDisplay(), eglGetCurrentSurface( EGL_DRAW ) );
215 vtkDebugMacro(<< " eglSwapBuffers\n");
216 }
217 }
218 }
219
220 //
221 // Set the variable that indicates that we want a stereo capable window
222 // be created. This method can only be called before a window is realized.
223 //
SetStereoCapableWindow(vtkTypeBool capable)224 void vtkEGLRenderWindow::SetStereoCapableWindow(vtkTypeBool capable)
225 {
226 vtkInternals* impl = this->Internals;
227 if (impl->Display == EGL_NO_DISPLAY)
228 {
229 vtkOpenGLRenderWindow::SetStereoCapableWindow(capable);
230 }
231 else
232 {
233 vtkWarningMacro(<< "Requesting a StereoCapableWindow must be performed "
234 << "before the window is realized, i.e. before a render.");
235 }
236 }
237
238
CreateAWindow()239 void vtkEGLRenderWindow::CreateAWindow()
240 {
241 int s[2];
242 if (this->Size[0] != 0 && this->Size[1] != 0)
243 {
244 s[0] = this->Size[0];
245 s[1] = this->Size[1];
246 }
247 else
248 {
249 s[0] = this->ScreenSize[0];
250 s[1] = this->ScreenSize[1];
251 }
252 this->ResizeWindow(s[0], s[1]);
253 }
254
255
GetNumberOfDevices()256 int vtkEGLRenderWindow::GetNumberOfDevices()
257 {
258 vtkEGLDeviceExtensions* ext = vtkEGLDeviceExtensions::GetInstance();
259 if (ext->Available())
260 {
261 EGLint num_devices = 0;
262 ext->eglQueryDevices(num_devices, nullptr, &num_devices);
263 return num_devices;
264 }
265 vtkWarningMacro("Getting the number of devices (graphics cards) on a system require "
266 "EGL_EXT_device_base, EGL_EXT_platform_device and EGL_EXT_platform_base extensions");
267 return 0;
268 }
269
270
SetDeviceAsDisplay(int deviceIndex)271 void vtkEGLRenderWindow::SetDeviceAsDisplay(int deviceIndex)
272 {
273 vtkInternals* impl = this->Internals;
274 vtkEGLDeviceExtensions* ext = vtkEGLDeviceExtensions::GetInstance();
275 if (ext->Available())
276 {
277 EGLint num_devices = 0;
278 ext->eglQueryDevices(num_devices, nullptr, &num_devices);
279 if (deviceIndex >= num_devices)
280 {
281 vtkWarningMacro("EGL device index: " << deviceIndex << " is greater than "
282 "the number of supported deviced in the system: " << num_devices <<
283 ". Using device 0 ...");
284 return;
285 }
286 EGLDeviceEXT* devices = new EGLDeviceEXT[num_devices];
287 ext->eglQueryDevices(num_devices, devices, &num_devices);
288 impl->Display =
289 ext->eglGetPlatformDisplay(EGL_PLATFORM_DEVICE_EXT, devices[deviceIndex], nullptr);
290 delete[] devices;
291 return;
292 }
293 vtkWarningMacro("Setting an EGL display to device index: " << deviceIndex << " require "
294 "EGL_EXT_device_base EGL_EXT_platform_device EGL_EXT_platform_base extensions");
295 }
296
297
ResizeWindow(int width,int height)298 void vtkEGLRenderWindow::ResizeWindow(int width, int height)
299 {
300 vtkInternals* impl = this->Internals;
301 /*
302 * Here specify the attributes of the desired configuration.
303 * Below, we select an EGLConfig with at least 8 bits per color
304 * component compatible with on-screen windows
305 */
306 EGLint surfaceType, clientAPI;
307 const EGLint* contextAttribs;
308 if (this->OffScreenRendering)
309 {
310 surfaceType = EGL_PBUFFER_BIT;
311 clientAPI = EGL_OPENGL_BIT;
312 contextAttribs = nullptr;
313 }
314 else
315 {
316 surfaceType = EGL_WINDOW_BIT;
317 clientAPI = EGL_OPENGL_ES2_BIT;
318 const EGLint contextES2[] =
319 {
320 EGL_CONTEXT_CLIENT_VERSION, 2,
321 EGL_NONE
322 };
323 contextAttribs = contextES2;
324 }
325 const EGLint configs[] = {
326 EGL_SURFACE_TYPE, surfaceType,
327 EGL_BLUE_SIZE, 8,
328 EGL_GREEN_SIZE, 8,
329 EGL_RED_SIZE, 8,
330 EGL_ALPHA_SIZE, 8,
331 EGL_DEPTH_SIZE, 8,
332 EGL_RENDERABLE_TYPE, clientAPI,
333 EGL_NONE
334 };
335
336 const EGLint surface_attribs[] = {
337 EGL_WIDTH, width,
338 EGL_HEIGHT, height,
339 EGL_NONE
340 };
341
342
343 EGLint numConfigs = 0;
344 EGLConfig config;
345
346 if (impl->Display == EGL_NO_DISPLAY)
347 {
348 // eglGetDisplay(EGL_DEFAULT_DISPLAY) does not seem to work
349 // if there are several cards on a system.
350 this->SetDeviceAsDisplay(this->DeviceIndex);
351 // try to use the default display
352 if (impl->Display == EGL_NO_DISPLAY)
353 {
354 impl->Display = eglGetDisplay(EGL_DEFAULT_DISPLAY);
355 }
356 EGLint major = 0, minor = 0;
357 vtkEGLDisplayInitializationHelper::Initialize(impl->Display, &major, &minor);
358 if (this->OffScreenRendering)
359 {
360 if (major <= 1 && minor < 4)
361 {
362 vtkErrorMacro("Only EGL 1.4 and greater allows OpenGL as client API. "
363 "See eglBindAPI for more information.");
364 return;
365 }
366 eglBindAPI(EGL_OPENGL_API);
367 }
368 }
369
370
371 /* Here, the application chooses the configuration it desires. In this
372 * sample, we have a very simplified selection process, where we pick
373 * the first EGLConfig that matches our criteria */
374 eglChooseConfig(impl->Display, configs, &config, 1, &numConfigs);
375 if (numConfigs == 0)
376 {
377 vtkErrorMacro("No matching EGL configuration found.");
378 return;
379 }
380
381 #ifdef ANDROID
382 EGLint format = 0;
383 /* EGL_NATIVE_VISUAL_ID is an attribute of the EGLConfig that is
384 * guaranteed to be accepted by ANativeWindow_setBuffersGeometry().
385 * As soon as we picked a EGLConfig, we can safely reconfigure the
386 * ANativeWindow buffers to match, using EGL_NATIVE_VISUAL_ID. */
387 eglGetConfigAttrib(impl->Display, config, EGL_NATIVE_VISUAL_ID, &format);
388
389 ANativeWindow_setBuffersGeometry(impl->Window, 0, 0, format);
390 #endif
391
392
393 if (impl->Context == EGL_NO_CONTEXT)
394 {
395 impl->Context = eglCreateContext(impl->Display, config, EGL_NO_CONTEXT, contextAttribs);
396 }
397
398 if (impl->Surface != EGL_NO_SURFACE)
399 {
400 eglDestroySurface(impl->Display, impl->Surface);
401 }
402 impl->Surface = this->OffScreenRendering ?
403 eglCreatePbufferSurface(impl->Display, config, surface_attribs):
404 eglCreateWindowSurface(impl->Display, config, impl->Window, nullptr);
405 this->Mapped = 1;
406 this->OwnWindow = 1;
407
408 this->MakeCurrent();
409
410 EGLint w, h;
411 eglQuerySurface(impl->Display, impl->Surface, EGL_WIDTH, &w);
412 eglQuerySurface(impl->Display, impl->Surface, EGL_HEIGHT, &h);
413 this->Size[0] = w;
414 this->Size[1] = h;
415 }
416
DestroyWindow()417 void vtkEGLRenderWindow::DestroyWindow()
418 {
419 vtkInternals* impl = this->Internals;
420 this->ReleaseGraphicsResources(this);
421 if (this->OwnWindow && this->Mapped && impl->Display != EGL_NO_DISPLAY)
422 {
423 // make sure all other code knows we're not mapped anymore
424 this->Mapped = 0;
425 eglMakeCurrent(impl->Display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
426 if (impl->Context != EGL_NO_CONTEXT)
427 {
428 eglDestroyContext(impl->Display, impl->Context);
429 impl->Context = EGL_NO_CONTEXT;
430 }
431 if (impl->Surface != EGL_NO_SURFACE)
432 {
433 eglDestroySurface(impl->Display, impl->Surface);
434 impl->Surface = EGL_NO_SURFACE;
435 }
436 vtkEGLDisplayInitializationHelper::Terminate(impl->Display);
437 impl->Display = EGL_NO_DISPLAY;
438 }
439 }
440
441 // Initialize the window for rendering.
WindowInitialize(void)442 void vtkEGLRenderWindow::WindowInitialize (void)
443 {
444 vtkInternals* impl = this->Internals;
445 if (this->OwnWindow)
446 {
447 this->CreateAWindow();
448 }
449 else if (impl->Context == EGL_NO_CONTEXT)
450 {
451 // Get our current context from the EGL current context
452 impl->Context = eglGetCurrentContext();
453 }
454
455 this->MakeCurrent();
456
457 // tell our renderers about us
458 vtkRenderer* ren;
459 for (this->Renderers->InitTraversal();
460 (ren = this->Renderers->GetNextItem());)
461 {
462 ren->SetRenderWindow(0);
463 ren->SetRenderWindow(this);
464 }
465
466 this->OpenGLInit();
467
468 // for offscreen EGL always turn on point sprites
469 if (this->OffScreenRendering)
470 {
471 #ifdef GL_POINT_SPRITE
472 glEnable(GL_POINT_SPRITE);
473 #endif
474 }
475 }
476
477 // Initialize the rendering window.
Initialize(void)478 void vtkEGLRenderWindow::Initialize (void)
479 {
480 vtkInternals* impl = this->Internals;
481 if (impl->Context == EGL_NO_CONTEXT)
482 {
483 this->WindowInitialize();
484 }
485 else if( this->OwnWindow )
486 {
487 // We only need to resize the window if we own it
488 int w, h;
489 this->GetEGLSurfaceSize(&w, &h);
490 if (w != this->Size[0] || h != this->Size[1])
491 {
492 this->ResizeWindow(this->Size[0], this->Size[1]);
493 }
494 }
495 this->Initialized = true;
496 }
497
Finalize(void)498 void vtkEGLRenderWindow::Finalize (void)
499 {
500 // clean and destroy window
501 this->DestroyWindow();
502 }
503
504 // Change the window to fill the entire screen.
SetFullScreen(vtkTypeBool vtkNotUsed (arg))505 void vtkEGLRenderWindow::SetFullScreen(vtkTypeBool vtkNotUsed(arg))
506 {
507 // window is always full screen
508 }
509
510 // Set the preferred window size to full screen.
PrefFullScreen()511 void vtkEGLRenderWindow::PrefFullScreen()
512 {
513 // don't show borders
514 this->Borders = 0;
515 }
516
517 // Resize the window.
WindowRemap()518 void vtkEGLRenderWindow::WindowRemap()
519 {
520 // shut everything down
521 this->Finalize();
522
523 // set everything up again
524 this->Initialize();
525 }
526
527 // Begin the rendering process.
Start(void)528 void vtkEGLRenderWindow::Start(void)
529 {
530 this->Initialize();
531
532 // set the current window
533 this->MakeCurrent();
534 }
535
536 // Specify the size of the rendering window.
SetSize(int width,int height)537 void vtkEGLRenderWindow::SetSize(int width, int height)
538 {
539 if ((this->Size[0] != width)||(this->Size[1] != height))
540 {
541 this->Size[0] = width;
542 this->Size[1] = height;
543 this->Modified();
544 }
545 }
546
GetEGLSurfaceSize(int * width,int * height)547 void vtkEGLRenderWindow::GetEGLSurfaceSize(int* width, int* height)
548 {
549 vtkInternals* impl = this->Internals;
550 if(impl->Display != EGL_NO_DISPLAY && impl->Surface != EGL_NO_SURFACE)
551 {
552 EGLint w, h;
553 eglQuerySurface(impl->Display, impl->Surface, EGL_WIDTH, &w);
554 eglQuerySurface(impl->Display, impl->Surface, EGL_HEIGHT, &h);
555 *width = w;
556 *height = h;
557 }
558 else
559 {
560 *width = 0;
561 *height = 0;
562 }
563 }
564
565
566
567
PrintSelf(ostream & os,vtkIndent indent)568 void vtkEGLRenderWindow::PrintSelf(ostream& os, vtkIndent indent)
569 {
570 vtkInternals* impl = this->Internals;
571 this->Superclass::PrintSelf(os,indent);
572
573 os << indent << "Context: " << impl->Context << "\n";
574 os << indent << "Display: " << impl->Display << "\n";
575 os << indent << "Surface: " << impl->Surface << "\n";
576 }
577
MakeCurrent()578 void vtkEGLRenderWindow::MakeCurrent()
579 {
580 vtkInternals* impl = this->Internals;
581 if(this->Mapped &&
582 impl->Display != EGL_NO_DISPLAY &&
583 impl->Context != EGL_NO_CONTEXT &&
584 impl->Surface != EGL_NO_SURFACE)
585 {
586 if (eglMakeCurrent(impl->Display, impl->Surface, impl->Surface, impl->Context) == EGL_FALSE)
587 {
588 vtkWarningMacro("Unable to eglMakeCurrent: " << eglGetError());
589 return;
590 }
591 }
592 }
593
594 // ----------------------------------------------------------------------------
595 // Description:
596 // Tells if this window is the current OpenGL context for the calling thread.
IsCurrent()597 bool vtkEGLRenderWindow::IsCurrent()
598 {
599 return true;
600 }
601
602 // Get the size of the screen in pixels
GetScreenSize()603 int *vtkEGLRenderWindow::GetScreenSize()
604 {
605 return this->ScreenSize;
606 }
607
608 // Get the position in screen coordinates (pixels) of the window.
GetPosition(void)609 int *vtkEGLRenderWindow::GetPosition(void)
610 {
611 return this->Position;
612 }
613
614 // Move the window to a new position on the display.
SetPosition(int x,int y)615 void vtkEGLRenderWindow::SetPosition(int x, int y)
616 {
617 if ((this->Position[0] != x)||(this->Position[1] != y))
618 {
619 this->Modified();
620 }
621 this->Position[0] = x;
622 this->Position[1] = y;
623 }
624
625 // Set this RenderWindow to a pre-existing window.
SetWindowInfo(const char *)626 void vtkEGLRenderWindow::SetWindowInfo(const char *)
627 {
628 this->OwnWindow = 0;
629 this->Mapped = 1;
630 }
631
SetWindowName(const char * name)632 void vtkEGLRenderWindow::SetWindowName(const char *name)
633 {
634 vtkOpenGLRenderWindow::SetWindowName( name );
635 }
636
Render()637 void vtkEGLRenderWindow::Render()
638 {
639 // Now do the superclass stuff
640 this->vtkOpenGLRenderWindow::Render();
641 }
642
643 //----------------------------------------------------------------------------
HideCursor()644 void vtkEGLRenderWindow::HideCursor()
645 {
646 }
647
648 //----------------------------------------------------------------------------
ShowCursor()649 void vtkEGLRenderWindow::ShowCursor()
650 {
651 }
652
653 //----------------------------------------------------------------------------
GetGenericDisplayId()654 void *vtkEGLRenderWindow::GetGenericDisplayId()
655 {
656 vtkInternals* impl = this->Internals;
657 return impl->Display;
658 }
659
660 //----------------------------------------------------------------------------
GetGenericContext()661 void* vtkEGLRenderWindow::GetGenericContext()
662 {
663 vtkInternals* impl = this->Internals;
664 return impl->Context;
665 }
666
667 //----------------------------------------------------------------------------
SetOffScreenRendering(vtkTypeBool)668 void vtkEGLRenderWindow::SetOffScreenRendering (vtkTypeBool)
669 {
670 // this is determined at compile time: ANDROID -> 0, otherwise -> 1
671 }
672
673 //----------------------------------------------------------------------------
GetOffScreenRendering()674 vtkTypeBool vtkEGLRenderWindow::GetOffScreenRendering ()
675 {
676 return this->OffScreenRendering;
677 }
678
679 //----------------------------------------------------------------------------
IsPointSpriteBugPresent()680 bool vtkEGLRenderWindow::IsPointSpriteBugPresent()
681 {
682 // eventually we'll want to check with the NVIDIA EGL version to see if the
683 // point sprite bug is fixed but we don't know yet when it will be fixed
684 // but we do know that it's present in both the 355 and 358 drivers. for
685 // now do the safe thing and just assume the bug isn't fixed until we
686 // find a driver version where it is fixed.
687 this->IsPointSpriteBugTested = true;
688 this->IsPointSpriteBugPresent_ = true;
689 // if (! this->IsPointSpriteBugTested)
690 // {
691 // this->IsPointSpriteBugTested = true;
692 // this->IsPointSpriteBugPresent_ =
693 // (strcmp(reinterpret_cast<const char*>(glGetString(GL_VERSION)), "4.5.0 NVIDIA 355.11") == 0) ||
694 // (strcmp(reinterpret_cast<const char*>(glGetString(GL_VERSION)), "4.5.0 NVIDIA 358.16") == 0);
695 // }
696 return this->IsPointSpriteBugPresent_;
697 }
698
699 //----------------------------------------------------------------------------
SetWindowId(void * window)700 void vtkEGLRenderWindow::SetWindowId(void *window)
701 {
702 vtkInternals* impl = this->Internals;
703 impl->Window = reinterpret_cast<EGLNativeWindowType>(window);
704 }
705