I need images to be displayed in a constant frame rate, so I use two threads, one for rendering with VSYNC on, one for computing using CUDA, which may takes long time. I want computing thread running in rendering thread interval(after swap buffer, before next frame start rendering).
I have two problems here:
- How can I know when the image are exactly drawn on screen, then I can awake rending thread. After
glutSwapBuffers()
, the image may not be actually displayed on screen. I have not found a API to notify display completing. - How can I stop computing thread when it's time to render, I have tried
this_thread::yield()
but it often still runs computing thread. I am not familiar with multiple threads programming.
I use C++11 for multiple thread, CUDA for computing, OpenGL for rendering.
Update:
As computing takes long time, but rendering must be performed at 60Hz, so I have to separate into two threads.
I have just resolved this problem by using condition_variable
, it is similar to 'producer-consumer' problem. And there is no need to know when the image are actually drawn on screen, you can just let it computes all the time, and CUDA computing thread seems won't interrupt OpenGL rendering thread in one GPU, they are parallel.
Here is the code:
compute Thread:
void update(){
while(1){
unique_lock<mutex> locker(buffer_mutex);
buffCond.wait(locker, []{return !updateFlag;});
runSolver(d_x);// compute next several images, d_x point to the images buffer
updateFlag = true;
locker.unlock();
buffCond.notify_one();
}
}
rendering thread:
void render(){
initGL();
glutMainLoop();
}
void display(){
if(updateFlag){
unique_lock<mutex> locker(buffer_mutex);
updateBuffer(d_x);
updateFlag = false;
locker.unlock();
buffCond.notify_one();
}
.../* OpenGL rendering*/
glutSwapBuffers();
}