Browse Source

better frame management

David Rose 16 years ago
parent
commit
7c1c75805b

+ 8 - 0
panda/src/display/config_display.cxx

@@ -92,6 +92,14 @@ ConfigVariableBool yield_timeslice
  PRC_DESC("Set this true to yield the timeslice at the end of the frame to be "
  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."));
           "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
 ConfigVariableString screenshot_filename
 ("screenshot-filename", "%~p-%a-%b-%d-%H-%M-%S-%Y-%~f.%~e",
 ("screenshot-filename", "%~p-%a-%b-%d-%H-%M-%S-%Y-%~f.%~e",
  PRC_DESC("This specifies the filename pattern to be used to generate "
  PRC_DESC("This specifies the filename pattern to be used to generate "

+ 1 - 0
panda/src/display/config_display.h

@@ -41,6 +41,7 @@ extern EXPCL_PANDA_DISPLAY ConfigVariableBool allow_nonpipeline_threads;
 extern EXPCL_PANDA_DISPLAY ConfigVariableBool auto_flip;
 extern EXPCL_PANDA_DISPLAY ConfigVariableBool auto_flip;
 extern EXPCL_PANDA_DISPLAY ConfigVariableBool sync_flip;
 extern EXPCL_PANDA_DISPLAY ConfigVariableBool sync_flip;
 extern EXPCL_PANDA_DISPLAY ConfigVariableBool yield_timeslice;
 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_filename;
 extern EXPCL_PANDA_DISPLAY ConfigVariableString screenshot_extension;
 extern EXPCL_PANDA_DISPLAY ConfigVariableString screenshot_extension;

+ 20 - 8
panda/src/display/subprocessWindow.cxx

@@ -17,6 +17,7 @@
 #ifdef SUPPORT_SUBPROCESS_WINDOW
 #ifdef SUPPORT_SUBPROCESS_WINDOW
 
 
 #include "graphicsEngine.h"
 #include "graphicsEngine.h"
+#include "config_display.h"
 
 
 TypeHandle SubprocessWindow::_type_handle;
 TypeHandle SubprocessWindow::_type_handle;
 
 
@@ -153,13 +154,6 @@ begin_frame(FrameMode mode, Thread *current_thread) {
     return false;
     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);
   bool result = _buffer->begin_frame(mode, current_thread);
   return result;
   return result;
 }
 }
@@ -212,7 +206,25 @@ begin_flip() {
     size_t framebuffer_size = _swbuffer->get_framebuffer_size();
     size_t framebuffer_size = _swbuffer->get_framebuffer_size();
     nassertv(image.size() == 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();
     void *target = _swbuffer->open_write_framebuffer();
     memcpy(target, image.p(), framebuffer_size);
     memcpy(target, image.p(), framebuffer_size);
     _swbuffer->close_write_framebuffer();
     _swbuffer->close_write_framebuffer();