Skip to content

Commit de36727

Browse files
authored
Merge pull request #305 from allywarner/viewer_race_condition
Viewer race condition
2 parents 6f6e77c + 9d00e6d commit de36727

1 file changed

Lines changed: 73 additions & 32 deletions

File tree

src/Core/RenderResources/RenderResources.cc

Lines changed: 73 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,10 @@
2727
*/
2828

2929
#include <GL/glew.h>
30+
#include <atomic>
31+
#include <chrono>
32+
#include <boost/logic/tribool.hpp>
33+
#include <boost/logic/tribool_io.hpp>
3034

3135
#ifdef _WIN32
3236
#include <Windows.h>
@@ -54,9 +58,13 @@ class RenderResourcesPrivate
5458
// initialize_gl:
5559
// Initialize GLEW and check required OpenGL version and extensions.
5660
void initialize_gl();
61+
62+
//Error checking for GL initialization.
63+
void initialize_gl_log_error(const std::string&);
5764

5865
// Query available video memory size.
5966
void query_video_memory_size();
67+
std::atomic<bool> videoDone_{ false };
6068

6169
// A Handle to resource that generated the contexts
6270
RenderResourcesContextHandle resources_context_;
@@ -75,37 +83,48 @@ class RenderResourcesPrivate
7583
boost::mutex thread_mutex_;
7684
boost::condition_variable thread_condition_variable_;
7785

78-
bool gl_capable_;
86+
std::atomic<boost::tribool> gl_capable_{ boost::logic::indeterminate };
7987
unsigned long vram_size_;
88+
89+
bool wait_for_render_resources()
90+
{
91+
return boost::logic::indeterminate(gl_capable_) || !videoDone_;
92+
}
93+
8094
};
81-
95+
96+
void RenderResourcesPrivate::initialize_gl_log_error(const std::string& error_string)
97+
{
98+
this->gl_capable_ = false;
99+
CORE_LOG_ERROR(error_string);
100+
}
101+
82102
void RenderResourcesPrivate::initialize_gl()
83103
{
84-
this->gl_capable_ = true;
85-
86-
int err = glewInit();
87-
if ( err != GLEW_OK )
88-
{
89-
this->gl_capable_ = false;
90-
CORE_LOG_ERROR( "glewInit failed with error code " + Core::ExportToString( err ) );
91-
}
92-
93-
// Check OpenGL capabilities
94-
if ( !GLEW_VERSION_2_0 )
95-
{
96-
this->gl_capable_ = false;
97-
CORE_LOG_ERROR( "OpenGL 2.0 required but not found." );
98-
}
99-
if ( !GLEW_EXT_framebuffer_object )
100-
{
101-
this->gl_capable_ = false;
102-
CORE_LOG_ERROR( "GL_EXT_framebuffer_object required but not found." );
103-
}
104-
if ( !GLEW_ARB_pixel_buffer_object )
105-
{
106-
this->gl_capable_ = false;
107-
CORE_LOG_ERROR( "GL_ARB_pixel_buffer_object required but not found." );
108-
}
104+
//refactor error checks into a function to avoid misuse
105+
int err = glewInit();
106+
if (err != GLEW_OK)
107+
{
108+
initialize_gl_log_error("glewInit failed with error code " + Core::ExportToString(err));
109+
}
110+
111+
// Check OpenGL capabilities
112+
else if (!GLEW_VERSION_2_0)
113+
{
114+
initialize_gl_log_error("OpenGL 2.0 required but not found.");
115+
}
116+
else if (!GLEW_EXT_framebuffer_object)
117+
{
118+
initialize_gl_log_error("GL_EXT_framebuffer_object required but not found.");
119+
}
120+
else if (!GLEW_ARB_pixel_buffer_object)
121+
{
122+
initialize_gl_log_error("GL_ARB_pixel_buffer_object required but not found.");
123+
}
124+
else
125+
{
126+
this->gl_capable_ = true;
127+
}
109128
}
110129

111130
void RenderResourcesPrivate::query_video_memory_size()
@@ -214,12 +233,14 @@ void RenderResourcesPrivate::query_video_memory_size()
214233
{
215234
CORE_LOG_MESSAGE( "Video Memory Size: " + ExportToString( vram_size_MB ) + " MB." );
216235
}
236+
237+
videoDone_ = true;
217238
}
218239

219240
RenderResources::RenderResources() :
220241
private_( new RenderResourcesPrivate )
221242
{
222-
this->private_->gl_capable_ = false;
243+
223244
}
224245

225246
RenderResources::~RenderResources()
@@ -280,12 +301,32 @@ void RenderResources::install_resources_context( RenderResourcesContextHandle re
280301
this->initialize_on_event_thread();
281302
}
282303

304+
//#define LOG_RENDER_RESOURCE_INIT
305+
283306
bool RenderResources::valid_render_resources()
284307
{
285-
return ( this->private_->resources_context_ &&
286-
this->private_->resources_context_->valid_render_resources() &&
287-
this->private_->delete_context_ &&
288-
this->private_->gl_capable_ );
308+
if (!this->private_->gl_capable_)
309+
{
310+
return false;
311+
}
312+
313+
while (this->private_->wait_for_render_resources())
314+
{
315+
#ifdef LOG_RENDER_RESOURCE_INIT
316+
std::cout << "Waiting..." << std::endl;
317+
std::cout << std::boolalpha << "resources context: " << (this->private_->resources_context_ != nullptr) << " "
318+
<< "valid render resources: " << this->private_->resources_context_->valid_render_resources() << " "
319+
<< "delete context: " << (this->private_->delete_context_ != nullptr) << " "
320+
<< "GL capable: " << this->private_->gl_capable_ << std::endl;
321+
#endif
322+
323+
boost::this_thread::sleep_for(boost::chrono::milliseconds(100));
324+
}
325+
326+
return (this->private_->resources_context_ &&
327+
this->private_->resources_context_->valid_render_resources() &&
328+
this->private_->delete_context_ &&
329+
this->private_->gl_capable_);
289330
}
290331

291332
void RenderResources::initialize_on_event_thread()

0 commit comments

Comments
 (0)