vtkEGLRenderWindow.cxx 18.4 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
/*=========================================================================

  Program:   Visualization Toolkit
  Module:    vtkEGLRenderWindow.cxx

  Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
  All rights reserved.
  See Copyright.txt or http://www.kitware.com/Copyright.htm for details.

     This software is distributed WITHOUT ANY WARRANTY; without even
     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
     PURPOSE.  See the above copyright notice for more information.

=========================================================================*/

#include "vtkEGLRenderWindow.h"

18
#include "vtkAtomicTypes.h"
19
20
21
#include "vtkCommand.h"
#include "vtkIdList.h"
#include "vtkObjectFactory.h"
22
#include "vtkOpenGLRenderer.h"
23
#include "vtkRenderWindowInteractor.h"
24
#include "vtkRendererCollection.h"
25
26
#include "vtkToolkits.h"
#include "vtk_glew.h"
27
#include "vtksys/SystemTools.hxx"
28

29
#include <cassert>
30
#include <sstream>
31
32
#include <EGL/egl.h>

33
#ifdef ANDROID
34
35
#include <android/native_window.h>
#endif
36
37
38
39
40
41
42
43

namespace
{
  typedef void* EGLDeviceEXT;
  typedef EGLBoolean (*EGLQueryDevicesType)(EGLint,EGLDeviceEXT*,EGLint*);
  typedef EGLDisplay (*EGLGetPlatformDisplayType)(EGLenum, void *, const EGLint *);
  const EGLenum EGL_PLATFORM_DEVICE_EXT = 0x313F;

44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
  /**
   * EGLDisplay provided by eglGetDisplay() call can be same handle for multiple
   * instances of vtkEGLRenderWindow. In which case, while it's safe to call
   * eglInitialize() repeatedly, eglTerminate() should only be called once after
   * the final instance of the window is destroyed. This class helps us do
   * that. See paraview/paraview#16928.
   */
  class vtkEGLDisplayInitializationHelper
  {
    static std::map<EGLDisplay, vtkAtomicInt64> DisplayUsageCounts;
public:
    static EGLBoolean Initialize(EGLDisplay dpy, EGLint *major, EGLint *minor)
    {
      ++DisplayUsageCounts[dpy];
      return eglInitialize(dpy, major, minor);
    }
    static EGLBoolean Terminate(EGLDisplay dpy)
    {
      assert(DisplayUsageCounts.find(dpy) != DisplayUsageCounts.end());
      if (--DisplayUsageCounts[dpy] == 0)
      {
        DisplayUsageCounts.erase(dpy);
        return eglTerminate(dpy);
      }
      return EGL_TRUE;
    }
  };

  std::map<EGLDisplay, vtkAtomicInt64>
    vtkEGLDisplayInitializationHelper::DisplayUsageCounts;

75
76
77
78
  struct vtkEGLDeviceExtensions
  {
    static vtkEGLDeviceExtensions* GetInstance()
    {
79
80
      static vtkEGLDeviceExtensions* instance = nullptr;
      if (instance == nullptr)
81
      {
82
        instance = new vtkEGLDeviceExtensions();
83
      }
84
85
86
87
88
89
      return instance;
    }
    bool Available()
    {
      return this->Available_;
    }
Andrew Bauer's avatar
Andrew Bauer committed
90
91
92
    bool Available_;
    EGLQueryDevicesType eglQueryDevices;
    EGLGetPlatformDisplayType eglGetPlatformDisplay;
93
94
95
96
97

  private:
    vtkEGLDeviceExtensions()
    {
      this->Available_ = false;
98
99
      this->eglQueryDevices = nullptr;
      this->eglGetPlatformDisplay = nullptr;
100
101
102
103
104
      const char* s = eglQueryString(EGL_NO_DISPLAY, EGL_EXTENSIONS);
      std::string platformExtensions(s);
      if (platformExtensions.find("EGL_EXT_device_base") != std::string::npos &&
          platformExtensions.find("EGL_EXT_platform_device") != std::string::npos &&
          platformExtensions.find("EGL_EXT_platform_base") != std::string::npos)
105
      {
106
107
108
109
        this->eglQueryDevices = (EGLQueryDevicesType)eglGetProcAddress("eglQueryDevicesEXT");
        this->eglGetPlatformDisplay = (EGLGetPlatformDisplayType)
            eglGetProcAddress("eglGetPlatformDisplayEXT");
        if(this->eglQueryDevices && this->eglGetPlatformDisplay)
110
        {
111
112
          this->Available_ = true;
        }
113
      }
114
115
116
117
118
    }
  };
};


119

Ken Martin's avatar
Ken Martin committed
120

121
122
vtkStandardNewMacro(vtkEGLRenderWindow);

123
124
struct vtkEGLRenderWindow::vtkInternals
{
125
  EGLNativeWindowType Window;
126
127
128
  EGLDisplay Display;
  EGLSurface Surface;
  EGLContext Context;
129
130
  vtkInternals() : Window((EGLNativeWindowType)0),
                   Display(EGL_NO_DISPLAY),
Andrew Bauer's avatar
Andrew Bauer committed
131
132
                   Surface(EGL_NO_SURFACE),
                   Context(EGL_NO_CONTEXT)
133
134
  {
  }
135
136
};

137
138
vtkEGLRenderWindow::vtkEGLRenderWindow()
{
139
  this->Internals = new vtkInternals();
140
  this->OwnWindow = 1;
141
142
143
144
  this->ScreenSize[0] = 1920;
  this->ScreenSize[1] = 1080;
  // this is initialized in vtkRenderWindow
  // so we don't need to initialize on else
145
#ifdef VTK_USE_OFFSCREEN_EGL
146
  this->DeviceIndex = VTK_DEFAULT_EGL_DEVICE_INDEX;
147
#endif
148

149
#ifdef ANDROID
150
  this->OffScreenRendering = false;
151
#else
152
  // this is an offscreen-only window otherwise.
153
  this->OffScreenRendering = true;
154
#endif
155

156
157
  this->IsPointSpriteBugTested = false;
  this->IsPointSpriteBugPresent_ = false;
158
159
160
161
162
163
164
165
166
167
168
169
}

// free up memory & close the window
vtkEGLRenderWindow::~vtkEGLRenderWindow()
{
  // close-down all system-specific drawing resources
  this->Finalize();

  vtkRenderer *ren;
  vtkCollectionSimpleIterator rit;
  this->Renderers->InitTraversal(rit);
  while ( (ren = this->Renderers->GetNextRenderer(rit)) )
170
  {
171
    ren->SetRenderWindow(nullptr);
172
  }
173
  delete this->Internals;
174
175
176
177
178
}

// End the rendering process and display the image.
void vtkEGLRenderWindow::Frame()
{
179
  vtkInternals* impl = this->Internals;
180
  this->MakeCurrent();
181
  if (this->OwnWindow)
182
  {
183
    if (!this->AbortRender && this->DoubleBuffer && this->SwapBuffers
184
        && impl->Display != EGL_NO_DISPLAY)
185
    {
186
      eglSwapBuffers(impl->Display, impl->Surface);
187
      vtkDebugMacro(<< " eglSwapBuffers\n");
188
    }
189
  }
190
  else
191
  {
192
    if (!this->AbortRender && this->DoubleBuffer && this->SwapBuffers)
193
    {
194
195
      eglSwapBuffers( eglGetCurrentDisplay(), eglGetCurrentSurface( EGL_DRAW ) );
      vtkDebugMacro(<< " eglSwapBuffers\n");
196
    }
197
  }
198
199
200
201
202
203
204
205
}

//
// Set the variable that indicates that we want a stereo capable window
// be created. This method can only be called before a window is realized.
//
void vtkEGLRenderWindow::SetStereoCapableWindow(int capable)
{
206
207
  vtkInternals* impl = this->Internals;
  if (impl->Display == EGL_NO_DISPLAY)
208
  {
209
    vtkOpenGLRenderWindow::SetStereoCapableWindow(capable);
210
  }
211
  else
212
  {
213
214
    vtkWarningMacro(<< "Requesting a StereoCapableWindow must be performed "
                    << "before the window is realized, i.e. before a render.");
215
  }
216
217
}

218

219
220
void vtkEGLRenderWindow::CreateAWindow()
{
221
222
  int s[2];
  if (this->Size[0] != 0 && this->Size[1] != 0)
223
  {
224
225
    s[0] = this->Size[0];
    s[1] = this->Size[1];
226
  }
227
  else
228
  {
229
230
    s[0] = this->ScreenSize[0];
    s[1] = this->ScreenSize[1];
231
  }
232
233
234
235
236
237
238
239
  this->ResizeWindow(s[0], s[1]);
}


int vtkEGLRenderWindow::GetNumberOfDevices()
{
  vtkEGLDeviceExtensions* ext = vtkEGLDeviceExtensions::GetInstance();
  if (ext->Available())
240
  {
241
      EGLint num_devices = 0;
242
      ext->eglQueryDevices(num_devices, nullptr, &num_devices);
243
      return num_devices;
244
  }
245
246
247
248
249
250
251
252
253
254
255
  vtkWarningMacro("Getting the number of devices (graphics cards) on a system require "
                  "EGL_EXT_device_base, EGL_EXT_platform_device and EGL_EXT_platform_base extensions");
  return 0;
}


void vtkEGLRenderWindow::SetDeviceAsDisplay(int deviceIndex)
{
  vtkInternals* impl = this->Internals;
  vtkEGLDeviceExtensions* ext = vtkEGLDeviceExtensions::GetInstance();
  if (ext->Available())
256
  {
257
    EGLint num_devices = 0;
258
    ext->eglQueryDevices(num_devices, nullptr, &num_devices);
259
    if (deviceIndex >= num_devices)
260
    {
261
262
263
264
      vtkWarningMacro("EGL device index: " << deviceIndex << " is greater than "
                      "the number of supported deviced in the system: " << num_devices <<
                      ". Using device 0 ...");
      return;
265
    }
266
267
268
    EGLDeviceEXT* devices = new EGLDeviceEXT[num_devices];
    ext->eglQueryDevices(num_devices, devices, &num_devices);
    impl->Display =
269
      ext->eglGetPlatformDisplay(EGL_PLATFORM_DEVICE_EXT, devices[deviceIndex], nullptr);
270
271
    delete[] devices;
    return;
272
  }
273
274
275
276
277
278
279
280
  vtkWarningMacro("Setting an EGL display to device index: " << deviceIndex << " require "
                  "EGL_EXT_device_base EGL_EXT_platform_device EGL_EXT_platform_base extensions");
}


void vtkEGLRenderWindow::ResizeWindow(int width, int height)
{
  vtkInternals* impl = this->Internals;
281
282
283
284
285
  /*
   * Here specify the attributes of the desired configuration.
   * Below, we select an EGLConfig with at least 8 bits per color
   * component compatible with on-screen windows
   */
286
287
  EGLint surfaceType, clientAPI;
  const EGLint* contextAttribs;
288
  if (this->OffScreenRendering)
289
  {
290
291
    surfaceType = EGL_PBUFFER_BIT;
    clientAPI = EGL_OPENGL_BIT;
292
    contextAttribs = nullptr;
293
  }
294
  else
295
  {
296
297
    surfaceType = EGL_WINDOW_BIT;
    clientAPI = EGL_OPENGL_ES2_BIT;
298
    const EGLint contextES2[] =
299
300
301
302
      {
      EGL_CONTEXT_CLIENT_VERSION, 2,
      EGL_NONE
      };
303
    contextAttribs = contextES2;
304
  }
305
306
307
308
309
310
  const EGLint configs[] = {
    EGL_SURFACE_TYPE, surfaceType,
    EGL_BLUE_SIZE, 8,
    EGL_GREEN_SIZE, 8,
    EGL_RED_SIZE, 8,
    EGL_ALPHA_SIZE, 8,
311
    EGL_DEPTH_SIZE, 8,
312
313
    EGL_RENDERABLE_TYPE, clientAPI,
    EGL_NONE
314
  };
315
316
317
318
319

  const EGLint surface_attribs[] = {
    EGL_WIDTH, width,
    EGL_HEIGHT, height,
    EGL_NONE
320
321
  };

322

Andrew Bauer's avatar
Andrew Bauer committed
323
  EGLint numConfigs = 0;
324
325
  EGLConfig config;

326
  if (impl->Display == EGL_NO_DISPLAY)
327
  {
328
329
330
331
      // eglGetDisplay(EGL_DEFAULT_DISPLAY) does not seem to work
      // if there are several cards on a system.
      this->SetDeviceAsDisplay(this->DeviceIndex);
      // try to use the default display
332
      if (impl->Display == EGL_NO_DISPLAY)
333
      {
334
        impl->Display = eglGetDisplay(EGL_DEFAULT_DISPLAY);
335
      }
336
    EGLint major = 0, minor = 0;
337
    vtkEGLDisplayInitializationHelper::Initialize(impl->Display, &major, &minor);
338
    if (this->OffScreenRendering)
339
    {
340
      if (major <= 1 && minor < 4)
341
      {
342
343
344
345
        vtkErrorMacro("Only EGL 1.4 and greater allows OpenGL as client API. "
                      "See eglBindAPI for more information.");
        return;
      }
346
      eglBindAPI(EGL_OPENGL_API);
347
    }
348
  }
349
350
351
352
353


  /* Here, the application chooses the configuration it desires. In this
   * sample, we have a very simplified selection process, where we pick
   * the first EGLConfig that matches our criteria */
354
355
  eglChooseConfig(impl->Display, configs, &config, 1, &numConfigs);
  if (numConfigs == 0)
356
  {
357
358
      vtkErrorMacro("No matching EGL configuration found.");
      return;
359
  }
360

361
#ifdef ANDROID
Andrew Bauer's avatar
Andrew Bauer committed
362
  EGLint format = 0;
363
364
365
366
  /* EGL_NATIVE_VISUAL_ID is an attribute of the EGLConfig that is
   * guaranteed to be accepted by ANativeWindow_setBuffersGeometry().
   * As soon as we picked a EGLConfig, we can safely reconfigure the
   * ANativeWindow buffers to match, using EGL_NATIVE_VISUAL_ID. */
367
  eglGetConfigAttrib(impl->Display, config, EGL_NATIVE_VISUAL_ID, &format);
368

369
  ANativeWindow_setBuffersGeometry(impl->Window, 0, 0, format);
370
#endif
371
372


373
  if (impl->Context == EGL_NO_CONTEXT)
374
  {
375
    impl->Context = eglCreateContext(impl->Display, config, EGL_NO_CONTEXT, contextAttribs);
376
  }
377
378

  if (impl->Surface != EGL_NO_SURFACE)
379
  {
380
      eglDestroySurface(impl->Display, impl->Surface);
381
  }
382
383
  impl->Surface = this->OffScreenRendering ?
    eglCreatePbufferSurface(impl->Display, config, surface_attribs):
384
    eglCreateWindowSurface(impl->Display, config, impl->Window, nullptr);
385
  this->Mapped = 1;
Ken Martin's avatar
Ken Martin committed
386
  this->OwnWindow = 1;
387
388
389

  this->MakeCurrent();

390
391
392
  EGLint w, h;
  eglQuerySurface(impl->Display, impl->Surface, EGL_WIDTH, &w);
  eglQuerySurface(impl->Display, impl->Surface, EGL_HEIGHT, &h);
393
394
395
396
397
398
  this->Size[0] = w;
  this->Size[1] = h;
}

void vtkEGLRenderWindow::DestroyWindow()
{
399
  vtkInternals* impl = this->Internals;
400
  this->ReleaseGraphicsResources(this);
401
  if (this->OwnWindow && this->Mapped && impl->Display != EGL_NO_DISPLAY)
402
  {
403
404
    // make sure all other code knows we're not mapped anymore
    this->Mapped = 0;
405
406
    eglMakeCurrent(impl->Display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
    if (impl->Context != EGL_NO_CONTEXT)
407
    {
408
409
      eglDestroyContext(impl->Display, impl->Context);
      impl->Context = EGL_NO_CONTEXT;
410
    }
411
    if (impl->Surface != EGL_NO_SURFACE)
412
    {
413
414
      eglDestroySurface(impl->Display, impl->Surface);
      impl->Surface = EGL_NO_SURFACE;
415
    }
416
    vtkEGLDisplayInitializationHelper::Terminate(impl->Display);
417
    impl->Display = EGL_NO_DISPLAY;
418
  }
419
420
421
422
423
}

// Initialize the window for rendering.
void vtkEGLRenderWindow::WindowInitialize (void)
{
424
  vtkInternals* impl = this->Internals;
Ken Martin's avatar
Ken Martin committed
425
  if (this->OwnWindow)
426
  {
Ken Martin's avatar
Ken Martin committed
427
    this->CreateAWindow();
428
429
430
431
432
    }
  else if (impl->Context == EGL_NO_CONTEXT)
  {
    // Get our current context from the EGL current context
    impl->Context = eglGetCurrentContext();
433
  }
434
435
436
437
438
439
440

  this->MakeCurrent();

  // tell our renderers about us
  vtkRenderer* ren;
  for (this->Renderers->InitTraversal();
       (ren = this->Renderers->GetNextItem());)
441
  {
442
443
    ren->SetRenderWindow(0);
    ren->SetRenderWindow(this);
444
  }
445
446

  this->OpenGLInit();
447
448

  // for offscreen EGL always turn on point sprites
449
450
  if (this->OffScreenRendering)
  {
451
#ifdef GL_POINT_SPRITE
452
    glEnable(GL_POINT_SPRITE);
453
#endif
454
  }
455
456
457
458
459
}

// Initialize the rendering window.
void vtkEGLRenderWindow::Initialize (void)
{
460
  vtkInternals* impl = this->Internals;
461
  if (impl->Context == EGL_NO_CONTEXT)
462
  {
463
    this->WindowInitialize();
464
  }
465
  else if( this->OwnWindow )
466
  {
467
    // We only need to resize the window if we own it
468
469
470
    int w, h;
    this->GetEGLSurfaceSize(&w, &h);
    if (w != this->Size[0] || h != this->Size[1])
471
    {
472
473
      this->ResizeWindow(this->Size[0], this->Size[1]);
    }
474
  }
475
  this->Initialized = true;
476
477
478
479
480
481
482
483
484
}

void vtkEGLRenderWindow::Finalize (void)
{
  // clean and destroy window
  this->DestroyWindow();
}

// Change the window to fill the entire screen.
Andrew Bauer's avatar
Andrew Bauer committed
485
void vtkEGLRenderWindow::SetFullScreen(int vtkNotUsed(arg))
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
{
  // window is always full screen
}

// Set the preferred window size to full screen.
void vtkEGLRenderWindow::PrefFullScreen()
{
  // don't show borders
  this->Borders = 0;
}

// Resize the window.
void vtkEGLRenderWindow::WindowRemap()
{
  // shut everything down
  this->Finalize();

  // set everything up again
  this->Initialize();
}

// Begin the rendering process.
void vtkEGLRenderWindow::Start(void)
{
  this->Initialize();

  // set the current window
  this->MakeCurrent();
}

// Specify the size of the rendering window.
517
void vtkEGLRenderWindow::SetSize(int width, int height)
518
{
519
  if ((this->Size[0] != width)||(this->Size[1] != height))
520
  {
521
522
523
    this->Size[0] = width;
    this->Size[1] = height;
    this->Modified();
524
  }
525
526
}

527
528
529
530
void vtkEGLRenderWindow::GetEGLSurfaceSize(int* width, int* height)
{
  vtkInternals* impl = this->Internals;
  if(impl->Display != EGL_NO_DISPLAY && impl->Surface != EGL_NO_SURFACE)
531
  {
532
533
534
535
536
    EGLint w, h;
    eglQuerySurface(impl->Display, impl->Surface, EGL_WIDTH, &w);
    eglQuerySurface(impl->Display, impl->Surface, EGL_HEIGHT, &h);
    *width = w;
    *height = h;
537
  }
538
  else
539
  {
540
541
      *width = 0;
      *height = 0;
542
  }
543
544
545
546
547
}




548
549
void vtkEGLRenderWindow::PrintSelf(ostream& os, vtkIndent indent)
{
550
  vtkInternals* impl = this->Internals;
551
552
  this->Superclass::PrintSelf(os,indent);

553
554
555
  os << indent << "Context: " << impl->Context << "\n";
  os << indent << "Display: " << impl->Display << "\n";
  os << indent << "Surface: " << impl->Surface << "\n";
556
557
558
559
}

void vtkEGLRenderWindow::MakeCurrent()
{
560
  vtkInternals* impl = this->Internals;
561
562
  if(this->Mapped &&
     impl->Display != EGL_NO_DISPLAY &&
563
564
     impl->Context != EGL_NO_CONTEXT &&
     impl->Surface != EGL_NO_SURFACE)
565
  {
566
    if (eglMakeCurrent(impl->Display, impl->Surface, impl->Surface, impl->Context) == EGL_FALSE)
567
    {
568
      vtkWarningMacro("Unable to eglMakeCurrent: " << eglGetError());
569
570
      return;
    }
571
  }
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
}

// ----------------------------------------------------------------------------
// Description:
// Tells if this window is the current OpenGL context for the calling thread.
bool vtkEGLRenderWindow::IsCurrent()
{
  return true;
}

// Get the size of the screen in pixels
int *vtkEGLRenderWindow::GetScreenSize()
{
  return this->ScreenSize;
}

// Get the position in screen coordinates (pixels) of the window.
int *vtkEGLRenderWindow::GetPosition(void)
{
  return this->Position;
}

// Move the window to a new position on the display.
void vtkEGLRenderWindow::SetPosition(int x, int y)
{
597
  if ((this->Position[0] != x)||(this->Position[1] != y))
598
  {
599
    this->Modified();
600
  }
601
602
  this->Position[0] = x;
  this->Position[1] = y;
603
604
}

Ken Martin's avatar
Ken Martin committed
605
// Set this RenderWindow to a pre-existing window.
606
void vtkEGLRenderWindow::SetWindowInfo(char *)
Ken Martin's avatar
Ken Martin committed
607
608
{
  this->OwnWindow = 0;
Ken Martin's avatar
Ken Martin committed
609
  this->Mapped = 1;
Ken Martin's avatar
Ken Martin committed
610
611
}

612
void vtkEGLRenderWindow::SetWindowName(const char *name)
613
{
614
  vtkOpenGLRenderWindow::SetWindowName( name );
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
}

void vtkEGLRenderWindow::Render()
{
  // Now do the superclass stuff
  this->vtkOpenGLRenderWindow::Render();
}

//----------------------------------------------------------------------------
void vtkEGLRenderWindow::HideCursor()
{
}

//----------------------------------------------------------------------------
void vtkEGLRenderWindow::ShowCursor()
{
}

633
634
635
636
637
638
639
640
641
642
643
644
645
646
//----------------------------------------------------------------------------
void *vtkEGLRenderWindow::GetGenericDisplayId()
{
  vtkInternals* impl = this->Internals;
  return impl->Display;
}

//----------------------------------------------------------------------------
void* vtkEGLRenderWindow::GetGenericContext()
{
  vtkInternals* impl = this->Internals;
  return impl->Context;
}

647
648
649
//----------------------------------------------------------------------------
void vtkEGLRenderWindow::SetOffScreenRendering (int)
{
650
  // this is determined at compile time: ANDROID -> 0, otherwise -> 1
651
652
653
654
655
656
657
658
}

//----------------------------------------------------------------------------
int vtkEGLRenderWindow::GetOffScreenRendering ()
{
  return this->OffScreenRendering;
}

659
660
661
//----------------------------------------------------------------------------
bool vtkEGLRenderWindow::IsPointSpriteBugPresent()
{
662
663
664
665
666
667
668
669
670
671
672
673
674
675
  // eventually we'll want to check with the NVIDIA EGL version to see if the
  // point sprite bug is fixed but we don't know yet when it will be fixed
  // but we do know that it's present in both the 355 and 358 drivers. for
  // now do the safe thing and just assume the bug isn't fixed until we
  // find a driver version where it is fixed.
  this->IsPointSpriteBugTested = true;
  this->IsPointSpriteBugPresent_ = true;
  // if (! this->IsPointSpriteBugTested)
  //   {
  //   this->IsPointSpriteBugTested = true;
  //   this->IsPointSpriteBugPresent_ =
  //     (strcmp(reinterpret_cast<const char*>(glGetString(GL_VERSION)), "4.5.0 NVIDIA 355.11") == 0) ||
  //     (strcmp(reinterpret_cast<const char*>(glGetString(GL_VERSION)), "4.5.0 NVIDIA 358.16") == 0);
  //   }
676
677
  return this->IsPointSpriteBugPresent_;
}
678
679
680
681
682
683
684

//----------------------------------------------------------------------------
void vtkEGLRenderWindow::SetWindowId(void *window)
{
  vtkInternals* impl = this->Internals;
  impl->Window = reinterpret_cast<EGLNativeWindowType>(window);
}