better frame management

This commit is contained in:
David Rose 2009-07-16 19:18:37 +00:00
parent 47d28ae37b
commit 7c1c75805b
3 changed files with 29 additions and 8 deletions

View File

@ -92,6 +92,14 @@ ConfigVariableBool yield_timeslice
PRC_DESC("Set this true to yield the timeslice at the end of the frame to be "
"more polite to other applications that are trying to run."));
ConfigVariableDouble subprocess_window_max_wait
("subprocess-window-max-wait", 0.2,
PRC_DESC("This is the amount of time, in seconds, that the SubprocessWindow will "
"wait in begin_flip for the parent process to remove the previously-rendered "
"frame. When this time is exceeded, the next frame will be rendered without "
"having flipped the previous one. This is designed to allow the Python "
"process some time to run even when the parent window is offscreen or minimized."));
ConfigVariableString screenshot_filename
("screenshot-filename", "%~p-%a-%b-%d-%H-%M-%S-%Y-%~f.%~e",
PRC_DESC("This specifies the filename pattern to be used to generate "

View File

@ -41,6 +41,7 @@ extern EXPCL_PANDA_DISPLAY ConfigVariableBool allow_nonpipeline_threads;
extern EXPCL_PANDA_DISPLAY ConfigVariableBool auto_flip;
extern EXPCL_PANDA_DISPLAY ConfigVariableBool sync_flip;
extern EXPCL_PANDA_DISPLAY ConfigVariableBool yield_timeslice;
extern EXPCL_PANDA_DISPLAY ConfigVariableDouble subprocess_window_max_wait;
extern EXPCL_PANDA_DISPLAY ConfigVariableString screenshot_filename;
extern EXPCL_PANDA_DISPLAY ConfigVariableString screenshot_extension;

View File

@ -17,6 +17,7 @@
#ifdef SUPPORT_SUBPROCESS_WINDOW
#include "graphicsEngine.h"
#include "config_display.h"
TypeHandle SubprocessWindow::_type_handle;
@ -153,13 +154,6 @@ begin_frame(FrameMode mode, Thread *current_thread) {
return false;
}
if (!_swbuffer->ready_for_write()) {
// The other end hasn't removed a frame lately; don't bother to
// render.
Thread::force_yield();
return false;
}
bool result = _buffer->begin_frame(mode, current_thread);
return result;
}
@ -212,7 +206,25 @@ begin_flip() {
size_t framebuffer_size = _swbuffer->get_framebuffer_size();
nassertv(image.size() == framebuffer_size);
// Now copy the image to our shared framebuffer.
if (!_swbuffer->ready_for_write()) {
// We have to wait for the other end to remove the last frame we
// rendered. We only wait so long before we give up, so we
// don't completely starve the Python process just because the
// render window is offscreen or something.
ClockObject *clock = ClockObject::get_global_clock();
double start = clock->get_real_time();
while (!_swbuffer->ready_for_write()) {
Thread::force_yield();
double now = clock->get_real_time();
if (now - start > subprocess_window_max_wait) {
// Never mind.
return;
}
}
}
// We're ready to go. Copy the image to our shared framebuffer.
void *target = _swbuffer->open_write_framebuffer();
memcpy(target, image.p(), framebuffer_size);
_swbuffer->close_write_framebuffer();