فهرست منبع

redefine GraphicsEngine::auto_flip; define more pstats collectors

David Rose 22 سال پیش
والد
کامیت
be0f50c6fb

+ 3 - 5
panda/src/display/graphicsEngine.I

@@ -22,11 +22,9 @@
 //       Access: Published
 //  Description: Set this flag true to indicate the GraphicsEngine
 //               should automatically cause windows to sync and flip
-//               at the end of render_frame().
-//
-//               This only applies to a single-threaded rendering
-//               model.  In the presence of threading, the windows are
-//               never auto-flipped, regardless of this flag.
+//               as soon as they have finished drawing, rather than
+//               waiting for all of the windows to finish drawing
+//               first so they can flip together.
 //
 //               This only affects the timing of when the flip occurs.
 //               If this is true (the default), the flip occurs before

+ 31 - 8
panda/src/display/graphicsEngine.cxx

@@ -47,6 +47,8 @@ PStatCollector GraphicsEngine::_cull_pcollector("Cull");
 PStatCollector GraphicsEngine::_draw_pcollector("Draw");
 PStatCollector GraphicsEngine::_sync_pcollector("Draw:Sync");
 PStatCollector GraphicsEngine::_flip_pcollector("Draw:Flip");
+PStatCollector GraphicsEngine::_flip_begin_pcollector("Draw:Flip:Begin");
+PStatCollector GraphicsEngine::_flip_end_pcollector("Draw:Flip:End");
 PStatCollector GraphicsEngine::_transform_states_pcollector("TransformStates");
 PStatCollector GraphicsEngine::_transform_states_unused_pcollector("TransformStates:Unused");
 PStatCollector GraphicsEngine::_render_states_pcollector("RenderStates");
@@ -492,13 +494,7 @@ render_frame() {
 
   // Some threads may still be drawing, so indicate that we have to
   // wait for those threads before we can flip.
-  _flip_state = FS_draw;
-
-  // But if we don't have any threads, go ahead and flip the frame
-  // now.  No point in waiting if we're single-threaded.
-  if (_threads.empty() && _auto_flip) {
-    do_flip_frame();
-  }
+  _flip_state = _auto_flip ? FS_flip : FS_draw;
 
   if (yield_timeslice) { 
     // Nap for a moment to yield the timeslice, to be polite to other
@@ -706,6 +702,19 @@ cull_and_draw_together(const GraphicsEngine::Windows &wlist) {
           cull_and_draw_together(win->get_gsg(), dr);
         }
         win->end_frame();
+
+        if (_auto_flip) {
+          if (win->flip_ready()) {
+            {
+              PStatTimer timer(GraphicsEngine::_flip_begin_pcollector);
+              win->begin_flip();
+            }
+            {
+              PStatTimer timer(GraphicsEngine::_flip_end_pcollector);
+              win->end_flip();
+            }
+          }
+        }
       }
     }
   }
@@ -762,8 +771,20 @@ cull_bin_draw(const GraphicsEngine::Windows &wlist) {
           DisplayRegion *dr = win->get_display_region(i);
           cull_bin_draw(win->get_gsg(), dr);
         }
-
         win->end_frame();
+
+        if (_auto_flip) {
+          if (win->flip_ready()) {
+            {
+              PStatTimer timer(GraphicsEngine::_flip_begin_pcollector);
+              win->begin_flip();
+            }
+            {
+              PStatTimer timer(GraphicsEngine::_flip_end_pcollector);
+              win->end_flip();
+            }
+          }
+        }
       }
     }
   }
@@ -850,12 +871,14 @@ flip_windows(const GraphicsEngine::Windows &wlist) {
   for (wi = wlist.begin(); wi != wlist.end(); ++wi) {
     GraphicsOutput *win = (*wi);
     if (win->flip_ready()) {
+      PStatTimer timer(GraphicsEngine::_flip_begin_pcollector);
       win->begin_flip();
     }
   }
   for (wi = wlist.begin(); wi != wlist.end(); ++wi) {
     GraphicsOutput *win = (*wi);
     if (win->flip_ready()) {
+      PStatTimer timer(GraphicsEngine::_flip_end_pcollector);
       win->end_flip();
     }
   }

+ 2 - 0
panda/src/display/graphicsEngine.h

@@ -241,6 +241,8 @@ private:
   static PStatCollector _draw_pcollector;
   static PStatCollector _sync_pcollector;
   static PStatCollector _flip_pcollector;
+  static PStatCollector _flip_begin_pcollector;
+  static PStatCollector _flip_end_pcollector;
   static PStatCollector _transform_states_pcollector;
   static PStatCollector _transform_states_unused_pcollector;
   static PStatCollector _render_states_pcollector;

+ 3 - 0
panda/src/display/graphicsOutput.cxx

@@ -23,11 +23,13 @@
 #include "mutexHolder.h"
 #include "hardwareChannel.h"
 #include "renderBuffer.h"
+#include "pStatTimer.h"
 
 TypeHandle GraphicsOutput::_type_handle;
 
 #ifndef CPPPARSER
 PStatCollector GraphicsOutput::_make_current_pcollector("Draw:Make current");
+PStatCollector GraphicsOutput::_copy_texture_pcollector("Draw:Copy texture");
 #endif  // CPPPARSER
 
 ////////////////////////////////////////////////////////////////////
@@ -560,6 +562,7 @@ end_frame() {
   // directly into texture memory don't need to do this; they will set
   // _copy_texture to false.
   if (_copy_texture) {
+    PStatTimer timer(_copy_texture_pcollector);
     nassertv(has_texture());
     DisplayRegion dr(this, _x_size, _y_size);
     RenderBuffer buffer = _gsg->get_render_buffer(get_draw_buffer_type());

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

@@ -179,6 +179,7 @@ protected:
   bool _is_valid;
 
   static PStatCollector _make_current_pcollector;
+  static PStatCollector _copy_texture_pcollector;
   
 public:
   static TypeHandle get_class_type() {

+ 1 - 0
panda/src/display/graphicsStateGuardian.cxx

@@ -60,6 +60,7 @@ PStatCollector GraphicsStateGuardian::_texture_state_pcollector("State changes:T
 PStatCollector GraphicsStateGuardian::_other_state_pcollector("State changes:Other");
 PStatCollector GraphicsStateGuardian::_draw_primitive_pcollector("Draw:Primitive");
 PStatCollector GraphicsStateGuardian::_clear_pcollector("Draw:Clear");
+PStatCollector GraphicsStateGuardian::_flush_pcollector("Draw:Flush");
 
 #endif
 

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

@@ -295,6 +295,7 @@ public:
   static PStatCollector _other_state_pcollector;
   static PStatCollector _draw_primitive_pcollector;
   static PStatCollector _clear_pcollector;
+  static PStatCollector _flush_pcollector;
 
 private:
   class LightInfo {

+ 8 - 5
panda/src/glstuff/glGraphicsStateGuardian_src.cxx

@@ -627,11 +627,14 @@ void CLP(GraphicsStateGuardian)::
 end_frame() {
   GraphicsStateGuardian::end_frame();
 
-  // Calling glFlush() at the end of the frame is particularly
-  // necessary if this is a single-buffered visual, so that the frame
-  // will be finished drawing before we return to the application.
-  // It's not clear what effect this has on our total frame time.
-  GLP(Flush)();
+  {
+    PStatTimer timer(_flush_pcollector);
+    // Calling glFlush() at the end of the frame is particularly
+    // necessary if this is a single-buffered visual, so that the frame
+    // will be finished drawing before we return to the application.
+    // It's not clear what effect this has on our total frame time.
+    GLP(Flush)();
+  }
 
   report_my_gl_errors();
 }

+ 4 - 0
panda/src/pstatclient/pStatProperties.cxx

@@ -123,9 +123,13 @@ static TimeCollectorProperties time_properties[] = {
   { 1, "Cull:Bins",                        { 0.3, 0.6, 0.3 } },
   { 1, "Draw",                             { 1.0, 0.0, 0.0 },  1.0 / 30.0 },
   { 1, "Draw:Make current",                { 0.4, 0.2, 0.6 } },
+  { 1, "Draw:Copy texture",                { 0.2, 0.6, 0.4 } },
   { 1, "Draw:Clear",                       { 0.0, 0.8, 0.6 } },
+  { 1, "Draw:Flush",                       { 0.9, 0.2, 0.7 } },
   { 1, "Draw:Sync",                        { 0.5, 0.7, 0.7 } },
   { 1, "Draw:Flip",                        { 1.0, 0.6, 0.3 } },
+  { 1, "Draw:Flip:Begin",                  { 0.3, 0.3, 0.9 } },
+  { 1, "Draw:Flip:End",                    { 0.9, 0.3, 0.6 } },
   { 1, "Draw:Bins",                        { 0.3, 0.6, 0.0 } },
   { 0, "Draw:Primitive",                   { 0.0, 0.0, 0.5 } },
   { 0, NULL }

+ 6 - 9
panda/src/wgldisplay/wglGraphicsWindow.cxx

@@ -224,15 +224,12 @@ release_gsg() {
 void wglGraphicsWindow::
 begin_flip() {
   if (_hdc) {
-    // It turns out that if we don't call make_current() before
-    // calling SwapBuffers() on a Matrix card, we crash a horrible
-    // death.  This is a pity since make_current() seems unnecessary
-    // on other cards, and does incur some performance overhead.
-
-    // Let's see if this is still necessary now that we guarantee
-    // begin_flip() is not called until end_frame() has successfully
-    // rendered.
-    //make_current();
+    // The documentation on SwapBuffers() is not at all clear on
+    // whether the GL context needs to be current before it can be
+    // called.  Empirically, it appears that it is not necessary in
+    // many cases, but it definitely is necessary at least in the case
+    // of Mesa on Windows.
+    make_current();
 
     SwapBuffers(_hdc);
   }