Skip to content

Commit 1f58723

Browse files
committed
Demo - improve the OpenGL interop demo with more performance details
1 parent 5744eb4 commit 1f58723

File tree

1 file changed

+50
-8
lines changed

1 file changed

+50
-8
lines changed

tutorials/32_gl_interop/main.cpp

Lines changed: 50 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@
4444
#define WINDOW_WIDTH 800
4545
#define WINDOW_HEIGHT 600
4646

47+
void Display();
4748

4849
class GuiRenderImpl
4950
{
@@ -97,9 +98,17 @@ float g_camera_posY = 5.0;
9798
int g_lastMouseDownUpdateX = -1;
9899
int g_lastMouseDownUpdateY = -1;
99100
GuiRenderImpl::Update g_update;
101+
const std::chrono::steady_clock::time_point g_invalidTime = std::chrono::time_point<std::chrono::high_resolution_clock>::max();
102+
int g_benchmark_numberOfRenderIteration = 0;
103+
std::chrono::steady_clock::time_point g_benchmark_start = g_invalidTime;
100104

101105

102-
// thread rendering 1 iteration
106+
// High batch size will increase the RPR performance ( rendering iteration per second ), but lower the render feedback FPS on the OpenGL viewer.
107+
// Note that for better OpenGL FPS (and decreased RPR render quality), API user can also tune the `RPR_CONTEXT_PREVIEW` value.
108+
const int g_batchSize = 30;
109+
110+
111+
// thread rendering 'g_batchSize' iteration(s)
103112
void renderJob( rpr_context ctxt, GuiRenderImpl::Update* update )
104113
{
105114
CHECK( rprContextRender( ctxt ) );
@@ -108,9 +117,27 @@ void renderJob( rpr_context ctxt, GuiRenderImpl::Update* update )
108117
}
109118

110119

111-
112120
void Update()
113121
{
122+
auto timeUpdateStarts = std::chrono::high_resolution_clock::now();
123+
124+
125+
//
126+
// print render stats every ~100 iterations.
127+
//
128+
if ( g_benchmark_start == g_invalidTime )
129+
g_benchmark_start = timeUpdateStarts;
130+
if ( g_benchmark_numberOfRenderIteration >= 100 )
131+
{
132+
double elapsed_time_ms = std::chrono::duration<double, std::milli>(timeUpdateStarts - g_benchmark_start).count();
133+
double renderPerSecond = (double)g_benchmark_numberOfRenderIteration * 1000.0 / elapsed_time_ms;
134+
std::cout<<renderPerSecond<<" iterations per second."<<std::endl;
135+
g_benchmark_numberOfRenderIteration = 0;
136+
g_benchmark_start = timeUpdateStarts;
137+
138+
}
139+
140+
114141
// clear state
115142
g_update.clear();
116143

@@ -146,15 +173,19 @@ void Update()
146173
// clear the update flag
147174
g_update.m_hasUpdate = false;
148175
}
149-
150-
// Request a new Display call.
176+
177+
// Request a new OpenGL Display call.
178+
// Note from documentation: "Multiple calls to glutPostRedisplay before the next display callback opportunity generates only a single redisplay callback".
179+
// So we are not actually doing the OpenGL render in this Update loop. It would be a bad design as it would stress this thread and may reduce performance of the
180+
// `renderJob` thread which is the most important here.
151181
glutPostRedisplay();
152-
182+
153183
}
154184

155185
// wait the end of the rendering thread
156186
t.join();
157187

188+
g_benchmark_numberOfRenderIteration += g_batchSize;
158189

159190
return;
160191
}
@@ -234,7 +265,6 @@ void OnKeyboardEvent(unsigned char key, int xmouse, int ymouse)
234265

235266
void Display()
236267
{
237-
238268
// Clear backbuffer
239269
glClear(GL_COLOR_BUFFER_BIT);
240270

@@ -489,8 +519,9 @@ int main(int argc, char** argv)
489519
// Set framebuffer for the context
490520
CHECK(rprContextSetAOV(g_context, RPR_AOV_COLOR, g_frame_buffer));
491521

492-
// this line can be added for faster RPR rendering.
493-
// the higher RPR_CONTEXT_PREVIEW, the faster RPR rendering, ( but more pixelated )
522+
// This line can be added for faster RPR rendering.
523+
// The higher RPR_CONTEXT_PREVIEW, the faster RPR rendering, ( but more pixelated ).
524+
// 0 = disabled (defaut value)
494525
//CHECK( rprContextSetParameterByKey1u(g_context,RPR_CONTEXT_PREVIEW, 1u ) );
495526

496527
// Set framebuffer for the context
@@ -502,6 +533,17 @@ int main(int argc, char** argv)
502533
CHECK(rprContextSetParameterByKeyPtr(g_context, RPR_CONTEXT_RENDER_UPDATE_CALLBACK_FUNC, (void*)GuiRenderImpl::notifyUpdate));
503534
CHECK(rprContextSetParameterByKeyPtr(g_context, RPR_CONTEXT_RENDER_UPDATE_CALLBACK_DATA, &g_update));
504535

536+
537+
// do a first rendering iteration, just for to force scene/cache building.
538+
std::cout << "Cache and scene building... ";
539+
CHECK(rprContextSetParameterByKey1u(g_context,RPR_CONTEXT_ITERATIONS,1));
540+
CHECK( rprContextRender( g_context ) );
541+
std::cout << "done\n";
542+
543+
// each rprContextRender call will do `g_batchSize` iterations.
544+
// Note that calling rprContextRender 1 time with RPR_CONTEXT_ITERATIONS = `g_batchSize` is faster than calling rprContextRender `g_batchSize` times with RPR_CONTEXT_ITERATIONS = 1
545+
CHECK(rprContextSetParameterByKey1u(g_context,RPR_CONTEXT_ITERATIONS,g_batchSize));
546+
505547
// allocate the data that will be used the read RPR framebuffer, and give it to OpenGL.
506548
g_fbdata = new float[WINDOW_WIDTH * WINDOW_HEIGHT * 4];
507549

0 commit comments

Comments
 (0)