Skip to content

Commit 363d99b

Browse files
committed
add ability to share data between render windows
This topic adds a capability to share some data between render windows. Basically it is implemented shared context data in OpenGL such as with wglShareLists or the similar functionality on glX or Cocoa. Right now only the VBO cache makes use of the shared space but in the future shader programs, textures, etc could also be shared.
1 parent 3e9e0ff commit 363d99b

11 files changed

+225
-11
lines changed

Rendering/Core/vtkRenderWindow.cxx

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,12 +81,14 @@ vtkRenderWindow::vtkRenderWindow()
8181
this->OffScreenRendering = 1;
8282
#endif
8383
this->DeviceIndex = 0;
84+
this->SharedRenderWindow = nullptr;
8485
}
8586

8687
//----------------------------------------------------------------------------
8788
vtkRenderWindow::~vtkRenderWindow()
8889
{
8990
this->SetInteractor(nullptr);
91+
this->SetSharedRenderWindow(nullptr);
9092

9193
delete [] this->AccumulationBuffer;
9294
this->AccumulationBuffer = nullptr;
@@ -121,6 +123,26 @@ vtkRenderWindowInteractor *vtkRenderWindow::MakeRenderWindowInteractor()
121123
return this->Interactor;
122124
}
123125

126+
void vtkRenderWindow::SetSharedRenderWindow(vtkRenderWindow *val)
127+
{
128+
if (this->SharedRenderWindow == val)
129+
{
130+
return;
131+
}
132+
133+
if (this->SharedRenderWindow)
134+
{
135+
// this->ReleaseGraphicsResources();
136+
this->SharedRenderWindow->UnRegister(this);
137+
}
138+
this->SharedRenderWindow = val;
139+
if (val)
140+
{
141+
val->Register(this);
142+
}
143+
return;
144+
}
145+
124146
//----------------------------------------------------------------------------
125147
// Set the interactor that will work with this renderer.
126148
void vtkRenderWindow::SetInteractor(vtkRenderWindowInteractor *rwi)

Rendering/Core/vtkRenderWindow.h

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -566,6 +566,19 @@ class VTKRENDERINGCORE_EXPORT vtkRenderWindow : public vtkWindow
566566
*/
567567
virtual bool InitializeFromCurrentContext() { return false; };
568568

569+
//@{
570+
/**
571+
* Set/Get an already existing window that this window should
572+
* share data with if possible. This must be set
573+
* after the shared render window has been created and initialized
574+
* but before this window has been initialized. Not all platforms
575+
* support data sharing.
576+
*/
577+
virtual void SetSharedRenderWindow(vtkRenderWindow *);
578+
vtkGetObjectMacro(SharedRenderWindow, vtkRenderWindow);
579+
virtual bool GetPlatformSupportsRenderWindowSharing() { return false; };
580+
//@}
581+
569582
/**
570583
* Attempt to make this window the current graphics context for the calling
571584
* thread.
@@ -723,6 +736,8 @@ class VTKRENDERINGCORE_EXPORT vtkRenderWindow : public vtkWindow
723736
*/
724737
double AbortCheckTime;
725738

739+
vtkRenderWindow *SharedRenderWindow;
740+
726741
private:
727742
vtkRenderWindow(const vtkRenderWindow&) = delete;
728743
void operator=(const vtkRenderWindow&) = delete;

Rendering/OpenGL2/Testing/Cxx/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ vtk_add_test_cxx(vtkRenderingOpenGL2CxxTests tests
3434
TestSetZBuffer.cxx
3535
TestShadowMapBakerPass.cxx
3636
TestShadowMapPass.cxx
37+
TestSharedRenderWindow.cxx
3738
TestSimpleMotionBlur.cxx
3839
TestSobelGradientMagnitudePass.cxx
3940
TestSphereMap.cxx
Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
/*=========================================================================
2+
3+
Program: Visualization Toolkit
4+
5+
Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
6+
All rights reserved.
7+
See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
8+
9+
This software is distributed WITHOUT ANY WARRANTY; without even
10+
the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
11+
PURPOSE. See the above copyright notice for more information.
12+
13+
=========================================================================*/
14+
15+
#include "vtkCamera.h"
16+
#include "vtkRenderer.h"
17+
#include "vtkOpenGLRenderWindow.h"
18+
#include "vtkActor.h"
19+
#include "vtkPolyDataMapper.h"
20+
#include "vtkNew.h"
21+
#include "vtkProperty.h"
22+
#include "vtkSphereSource.h"
23+
#include "vtkRegressionTestImage.h"
24+
#include "vtkTestUtilities.h"
25+
#include "vtkLight.h"
26+
27+
#include "vtkRenderWindowInteractor.h"
28+
29+
#include "vtkOpenGLRenderWindow.h"
30+
31+
//----------------------------------------------------------------------------
32+
int TestSharedRenderWindow(int argc, char *argv[])
33+
{
34+
vtkNew<vtkRenderer> renderer;
35+
renderer->SetBackground(0.0, 0.0, 0.0);
36+
vtkNew<vtkRenderWindow> renderWindow;
37+
renderWindow->SetSize(300, 300);
38+
renderWindow->AddRenderer(renderer);
39+
vtkNew<vtkRenderWindowInteractor> iren;
40+
iren->SetRenderWindow(renderWindow);
41+
42+
vtkNew<vtkSphereSource> sphere;
43+
sphere->SetThetaResolution(16);
44+
sphere->SetPhiResolution(16);
45+
sphere->SetEndTheta(270.0);
46+
47+
vtkNew<vtkPolyDataMapper> mapper;
48+
mapper->SetInputConnection(sphere->GetOutputPort());
49+
vtkNew<vtkActor> actor;
50+
renderer->AddActor(actor);
51+
actor->SetMapper(mapper);
52+
actor->GetProperty()->SetDiffuseColor(0.4, 1.0, 1.0);
53+
54+
renderWindow->SetMultiSamples(0);
55+
renderer->ResetCamera();
56+
renderer->GetActiveCamera()->Elevation(-45);
57+
renderer->GetActiveCamera()->OrthogonalizeViewUp();
58+
renderer->GetActiveCamera()->Zoom(1.5);
59+
renderer->ResetCameraClippingRange();
60+
renderWindow->Render();
61+
62+
vtkNew<vtkRenderer> renderer2;
63+
renderer2->SetBackground(0.0, 0.0, 1.0);
64+
vtkNew<vtkRenderWindow> renderWindow2;
65+
renderWindow2->SetSize(300, 300);
66+
renderWindow2->AddRenderer(renderer2);
67+
vtkNew<vtkRenderWindowInteractor> iren2;
68+
iren2->SetRenderWindow(renderWindow2);
69+
renderWindow2->SetSharedRenderWindow(renderWindow);
70+
71+
vtkNew<vtkPolyDataMapper> mapper2;
72+
mapper2->SetInputConnection(sphere->GetOutputPort());
73+
vtkNew<vtkActor> actor2;
74+
renderer2->AddActor(actor2);
75+
actor2->SetMapper(mapper2);
76+
actor2->GetProperty()->SetDiffuseColor(1.0, 1.0, 0.4);
77+
78+
renderWindow2->SetMultiSamples(0);
79+
renderer2->ResetCamera();
80+
renderer2->GetActiveCamera()->Elevation(-45);
81+
renderer2->GetActiveCamera()->OrthogonalizeViewUp();
82+
renderer2->GetActiveCamera()->Zoom(1.5);
83+
renderer2->ResetCameraClippingRange();
84+
renderWindow2->Render();
85+
86+
int retVal = vtkRegressionTestImage( renderWindow2 );
87+
if ( retVal == vtkRegressionTester::DO_INTERACTOR)
88+
{
89+
iren->Start();
90+
}
91+
92+
return !retVal;
93+
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
9084d37af6fb7ccbc23e0ad58e2935fb

Rendering/OpenGL2/vtkCocoaRenderWindow.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -178,6 +178,11 @@ class VTKRENDERINGOPENGL2_EXPORT vtkCocoaRenderWindow : public vtkOpenGLRenderWi
178178
*/
179179
bool InitializeFromCurrentContext() override;
180180

181+
/**
182+
* Does this platform support render window data sharing.
183+
*/
184+
bool GetPlatformSupportsRenderWindowSharing() override { return true; };
185+
181186
/**
182187
* Prescribe that the window be created in a stereo-capable mode. This
183188
* method must be called before the window is realized. This method

Rendering/OpenGL2/vtkCocoaRenderWindow.mm

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121

2222
#import "vtkOpenGL.h"
2323
#import "vtkCocoaRenderWindow.h"
24+
#import "vtkOpenGLVertexBufferObjectCache.h"
2425
#import "vtkRenderWindowInteractor.h"
2526
#import "vtkCommand.h"
2627
#import "vtkIdList.h"
@@ -1019,11 +1020,26 @@ - (void)viewFrameDidChange:(NSNotification *)aNotification
10191020
}
10201021
}
10211022

1023+
// do we have a shared render window?
1024+
NSOpenGLContext *sharedContext = nil;
1025+
if (this->SharedRenderWindow)
1026+
{
1027+
vtkCocoaRenderWindow *renWin =
1028+
vtkCocoaRenderWindow::SafeDownCast(this->SharedRenderWindow);
1029+
if (renWin && renWin->GetContextId())
1030+
{
1031+
sharedContext = (NSOpenGLContext*)renWin->GetContextId();
1032+
this->VBOCache->Delete();
1033+
this->VBOCache = renWin->VBOCache;
1034+
this->VBOCache->Register(this);
1035+
}
1036+
}
1037+
10221038
NSOpenGLContext *context = nil;
10231039
if (pixelFormat)
10241040
{
10251041
context = [[NSOpenGLContext alloc] initWithFormat:pixelFormat
1026-
shareContext:nil];
1042+
shareContext:sharedContext];
10271043

10281044
// This syncs the OpenGL context to the VBL to prevent tearing
10291045
GLint one = 1;

Rendering/OpenGL2/vtkWin32OpenGLRenderWindow.cxx

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ PURPOSE. See the above copyright notice for more information.
2222
#include "vtkOpenGLRenderWindow.h"
2323
#include "vtkOpenGLError.h"
2424
#include "vtkOpenGLShaderCache.h"
25+
#include "vtkOpenGLVertexBufferObjectCache.h"
2526
#include "vtkRendererCollection.h"
2627
#include "vtkStringOutputWindow.h"
2728
#include "vtkWin32RenderWindowInteractor.h"
@@ -1081,6 +1082,22 @@ void vtkWin32OpenGLRenderWindow::Initialize (void)
10811082
this->CreateOffScreenWindow(width,height);
10821083
}
10831084
}
1085+
1086+
if (this->SharedRenderWindow)
1087+
{
1088+
vtkWin32OpenGLRenderWindow *renWin =
1089+
vtkWin32OpenGLRenderWindow::SafeDownCast(this->SharedRenderWindow);
1090+
if (renWin && renWin->Initialized)
1091+
{
1092+
bool result = wglShareLists( renWin->ContextId, this->ContextId) == TRUE;
1093+
if (result)
1094+
{
1095+
this->VBOCache->Delete();
1096+
this->VBOCache = renWin->VBOCache;
1097+
this->VBOCache->Register(this);
1098+
}
1099+
}
1100+
}
10841101
}
10851102

10861103
void vtkWin32OpenGLRenderWindow::Finalize (void)

Rendering/OpenGL2/vtkWin32OpenGLRenderWindow.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -162,6 +162,11 @@ class VTKRENDERINGOPENGL2_EXPORT vtkWin32OpenGLRenderWindow : public vtkOpenGLRe
162162
*/
163163
bool InitializeFromCurrentContext() override;
164164

165+
/**
166+
* Does this platform support render window data sharing.
167+
*/
168+
bool GetPlatformSupportsRenderWindowSharing() override { return true; };
169+
165170
//@{
166171
/**
167172
* Set the window's parent id to a pre-existing window.

Rendering/OpenGL2/vtkXOpenGLRenderWindow.cxx

Lines changed: 44 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ typedef ptrdiff_t GLsizeiptr;
5151
#include "vtkNew.h"
5252
#include "vtkObjectFactory.h"
5353
#include "vtkOpenGLShaderCache.h"
54+
#include "vtkOpenGLVertexBufferObjectCache.h"
5455
#include "vtkRendererCollection.h"
5556
#include "vtkRenderTimerLog.h"
5657
#include "vtkRenderWindowInteractor.h"
@@ -570,25 +571,59 @@ void vtkXOpenGLRenderWindow::CreateAWindow()
570571

571572
if (glXCreateContextAttribsARB)
572573
{
574+
// do we have a shared render window?
575+
GLXContext sharedContext = nullptr;
576+
vtkXOpenGLRenderWindow *renWin = nullptr;
577+
if (this->SharedRenderWindow)
578+
{
579+
renWin =
580+
vtkXOpenGLRenderWindow::SafeDownCast(this->SharedRenderWindow);
581+
if (renWin && renWin->Internal->ContextId)
582+
{
583+
sharedContext = renWin->Internal->ContextId;
584+
}
585+
}
586+
573587
XErrorHandler previousHandler = XSetErrorHandler(vtkXOGLContextCreationErrorHandler);
574588
this->Internal->ContextId = nullptr;
589+
575590
// we believe that these later versions are all compatible with
576591
// OpenGL 3.2 so get a more recent context if we can.
577592
int attemptedVersions[] = {4,5, 4,4, 4,3, 4,2, 4,1, 4,0, 3,3, 3,2};
578-
for (int i = 0; i < 8 && !this->Internal->ContextId; i++)
593+
594+
// try shared context first, the fallback to not shared
595+
bool done = false;
596+
while (!done)
579597
{
580-
context_attribs[1] = attemptedVersions[i*2];
581-
context_attribs[3] = attemptedVersions[i*2+1];
582-
this->Internal->ContextId =
583-
glXCreateContextAttribsARB( this->DisplayId,
584-
this->Internal->FBConfig, nullptr,
585-
GL_TRUE, context_attribs );
586-
// Sync to ensure any errors generated are processed.
587-
XSync( this->DisplayId, False );
598+
for (int i = 0; i < 8 && !this->Internal->ContextId; i++)
599+
{
600+
context_attribs[1] = attemptedVersions[i*2];
601+
context_attribs[3] = attemptedVersions[i*2+1];
602+
this->Internal->ContextId =
603+
glXCreateContextAttribsARB( this->DisplayId,
604+
this->Internal->FBConfig, sharedContext,
605+
GL_TRUE, context_attribs );
606+
// Sync to ensure any errors generated are processed.
607+
XSync( this->DisplayId, False );
608+
}
609+
if ( !this->Internal->ContextId && sharedContext)
610+
{
611+
sharedContext = nullptr;
612+
}
613+
else
614+
{
615+
done = true;
616+
}
588617
}
589618
XSetErrorHandler(previousHandler);
590619
if ( this->Internal->ContextId )
591620
{
621+
if (sharedContext)
622+
{
623+
this->VBOCache->Delete();
624+
this->VBOCache = renWin->VBOCache;
625+
this->VBOCache->Register(this);
626+
}
592627
this->SetContextSupportsOpenGL32(true);
593628
}
594629
}
@@ -952,7 +987,6 @@ void vtkXOpenGLRenderWindow::Start(void)
952987
this->MakeCurrent();
953988
}
954989

955-
956990
// Specify the size of the rendering window.
957991
void vtkXOpenGLRenderWindow::SetSize(int width,int height)
958992
{

0 commit comments

Comments
 (0)