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