diff --git a/panda/src/display/graphicsEngine.cxx b/panda/src/display/graphicsEngine.cxx index ee701a4032..4ce18c754c 100644 --- a/panda/src/display/graphicsEngine.cxx +++ b/panda/src/display/graphicsEngine.cxx @@ -1624,20 +1624,28 @@ process_events(const GraphicsEngine::Windows &wlist, Thread *current_thread) { //////////////////////////////////////////////////////////////////// void GraphicsEngine:: flip_windows(const GraphicsEngine::Windows &wlist, Thread *current_thread) { - Windows::const_iterator wi; - for (wi = wlist.begin(); wi != wlist.end(); ++wi) { - GraphicsOutput *win = (*wi); + size_t num_windows = wlist.size(); + size_t warray_size = num_windows * sizeof(GraphicsOutput *); + size_t warray_count = 0; + GraphicsOutput **warray = (GraphicsOutput **)alloca(warray_size); + + size_t i; + for (i = 0; i < num_windows; ++i) { + GraphicsOutput *win = wlist[i]; if (win->flip_ready()) { + nassertv(warray_count < num_windows); + warray[warray_count] = win; + ++warray_count; + PStatTimer timer(GraphicsEngine::_flip_begin_pcollector, current_thread); win->begin_flip(); } } - for (wi = wlist.begin(); wi != wlist.end(); ++wi) { - GraphicsOutput *win = (*wi); - if (win->flip_ready()) { - PStatTimer timer(GraphicsEngine::_flip_end_pcollector, current_thread); - win->end_flip(); - } + + for (i = 0; i < warray_count; ++i) { + GraphicsOutput *win = warray[i]; + PStatTimer timer(GraphicsEngine::_flip_end_pcollector, current_thread); + win->end_flip(); } } diff --git a/panda/src/egldisplay/eglGraphicsWindow.cxx b/panda/src/egldisplay/eglGraphicsWindow.cxx index 0a48676e1a..9e82bac2e7 100644 --- a/panda/src/egldisplay/eglGraphicsWindow.cxx +++ b/panda/src/egldisplay/eglGraphicsWindow.cxx @@ -212,22 +212,18 @@ end_frame(FrameMode mode, Thread *current_thread) { } //////////////////////////////////////////////////////////////////// -// Function: eglGraphicsWindow::begin_flip +// Function: eglGraphicsWindow::end_flip // Access: Public, Virtual // Description: This function will be called within the draw thread -// after end_frame() has been called on all windows, to -// initiate the exchange of the front and back buffers. +// after begin_flip() has been called on all windows, to +// finish the exchange of the front and back buffers. // -// This should instruct the window to prepare for the -// flip at the next video sync, but it should not wait. -// -// We have the two separate functions, begin_flip() and -// end_flip(), to make it easier to flip all of the -// windows at the same time. +// This should cause the window to wait for the flip, if +// necessary. //////////////////////////////////////////////////////////////////// void eglGraphicsWindow:: -begin_flip() { - if (_gsg != (GraphicsStateGuardian *)NULL) { +end_flip() { + if (_gsg != (GraphicsStateGuardian *)NULL && _flip_ready) { // It doesn't appear to be necessary to ensure the graphics // context is current before flipping the windows, and insisting @@ -238,6 +234,7 @@ begin_flip() { LightReMutexHolder holder(eglGraphicsPipe::_x_mutex); eglSwapBuffers(_egl_display, _egl_surface); } + GraphicsWindow::end_flip(); } //////////////////////////////////////////////////////////////////// diff --git a/panda/src/egldisplay/eglGraphicsWindow.h b/panda/src/egldisplay/eglGraphicsWindow.h index e39ae265bb..d35131cc04 100644 --- a/panda/src/egldisplay/eglGraphicsWindow.h +++ b/panda/src/egldisplay/eglGraphicsWindow.h @@ -41,7 +41,7 @@ public: virtual bool move_pointer(int device, int x, int y); virtual bool begin_frame(FrameMode mode, Thread *current_thread); virtual void end_frame(FrameMode mode, Thread *current_thread); - virtual void begin_flip(); + virtual void end_flip(); virtual void process_events(); virtual void set_properties_now(WindowProperties &properties); diff --git a/panda/src/glxdisplay/glxGraphicsWindow.cxx b/panda/src/glxdisplay/glxGraphicsWindow.cxx index b44110f1c4..9af6aca59f 100644 --- a/panda/src/glxdisplay/glxGraphicsWindow.cxx +++ b/panda/src/glxdisplay/glxGraphicsWindow.cxx @@ -104,22 +104,18 @@ begin_frame(FrameMode mode, Thread *current_thread) { } //////////////////////////////////////////////////////////////////// -// Function: glxGraphicsWindow::begin_flip +// Function: glxGraphicsWindow::end_flip // Access: Public, Virtual // Description: This function will be called within the draw thread -// after end_frame() has been called on all windows, to -// initiate the exchange of the front and back buffers. +// after begin_flip() has been called on all windows, to +// finish the exchange of the front and back buffers. // -// This should instruct the window to prepare for the -// flip at the next video sync, but it should not wait. -// -// We have the two separate functions, begin_flip() and -// end_flip(), to make it easier to flip all of the -// windows at the same time. +// This should cause the window to wait for the flip, if +// necessary. //////////////////////////////////////////////////////////////////// void glxGraphicsWindow:: -begin_flip() { - if (_gsg != (GraphicsStateGuardian *)NULL) { +end_flip() { + if (_gsg != (GraphicsStateGuardian *)NULL && _flip_ready) { // It doesn't appear to be necessary to ensure the graphics // context is current before flipping the windows, and insisting @@ -130,6 +126,7 @@ begin_flip() { LightReMutexHolder holder(glxGraphicsPipe::_x_mutex); glXSwapBuffers(_display, _xwindow); } + GraphicsWindow::end_flip(); } //////////////////////////////////////////////////////////////////// diff --git a/panda/src/glxdisplay/glxGraphicsWindow.h b/panda/src/glxdisplay/glxGraphicsWindow.h index e2406c534e..61c7f4e297 100644 --- a/panda/src/glxdisplay/glxGraphicsWindow.h +++ b/panda/src/glxdisplay/glxGraphicsWindow.h @@ -39,7 +39,7 @@ public: virtual ~glxGraphicsWindow() {}; virtual bool begin_frame(FrameMode mode, Thread *current_thread); - virtual void begin_flip(); + virtual void end_flip(); protected: virtual void close_window(); diff --git a/panda/src/grutil/pfmFile.cxx b/panda/src/grutil/pfmFile.cxx index 22ba44e205..13861f5e18 100755 --- a/panda/src/grutil/pfmFile.cxx +++ b/panda/src/grutil/pfmFile.cxx @@ -602,7 +602,7 @@ merge(const PfmFile &other) { //////////////////////////////////////////////////////////////////// PT(BoundingHexahedron) PfmFile:: compute_planar_bounds(PN_stdfloat point_dist, PN_stdfloat sample_radius) const { - return compute_planar_bounds(LPoint2::zero(), point_dist, sample_radius, false); + return compute_planar_bounds(LPoint2(0.5, 0.5), point_dist, sample_radius, false); } diff --git a/panda/src/tinydisplay/tinySDLGraphicsWindow.cxx b/panda/src/tinydisplay/tinySDLGraphicsWindow.cxx index 39404871be..47631c6321 100644 --- a/panda/src/tinydisplay/tinySDLGraphicsWindow.cxx +++ b/panda/src/tinydisplay/tinySDLGraphicsWindow.cxx @@ -111,21 +111,22 @@ end_frame(FrameMode mode, Thread *current_thread) { } //////////////////////////////////////////////////////////////////// -// Function: TinySDLGraphicsWindow::begin_flip +// Function: TinySDLGraphicsWindow::end_flip // Access: Public, Virtual // Description: This function will be called within the draw thread -// after end_frame() has been called on all windows, to -// initiate the exchange of the front and back buffers. +// after begin_flip() has been called on all windows, to +// finish the exchange of the front and back buffers. // -// This should instruct the window to prepare for the -// flip at the next video sync, but it should not wait. -// -// We have the two separate functions, begin_flip() and -// end_flip(), to make it easier to flip all of the -// windows at the same time. +// This should cause the window to wait for the flip, if +// necessary. //////////////////////////////////////////////////////////////////// void TinySDLGraphicsWindow:: -begin_flip() { +end_flip() { + if (!_flip_ready) { + GraphicsWindow::end_flip(); + return; + } + int fb_xsize = get_fb_x_size(); int fb_ysize = get_fb_y_size(); @@ -154,6 +155,7 @@ begin_flip() { } SDL_Flip(_screen); + GraphicsWindow::end_flip(); } //////////////////////////////////////////////////////////////////// diff --git a/panda/src/tinydisplay/tinySDLGraphicsWindow.h b/panda/src/tinydisplay/tinySDLGraphicsWindow.h index e51914bc23..0250480835 100644 --- a/panda/src/tinydisplay/tinySDLGraphicsWindow.h +++ b/panda/src/tinydisplay/tinySDLGraphicsWindow.h @@ -42,7 +42,7 @@ public: virtual bool begin_frame(FrameMode mode, Thread *current_thread); virtual void end_frame(FrameMode mode, Thread *current_thread); - virtual void begin_flip(); + virtual void end_flip(); virtual void process_events(); virtual void set_properties_now(WindowProperties &properties); diff --git a/panda/src/tinydisplay/tinyWinGraphicsWindow.cxx b/panda/src/tinydisplay/tinyWinGraphicsWindow.cxx index b55a234d2e..b7a508c4ab 100755 --- a/panda/src/tinydisplay/tinyWinGraphicsWindow.cxx +++ b/panda/src/tinydisplay/tinyWinGraphicsWindow.cxx @@ -116,21 +116,22 @@ end_frame(FrameMode mode, Thread *current_thread) { } //////////////////////////////////////////////////////////////////// -// Function: TinyWinGraphicsWindow::begin_flip +// Function: TinyWinGraphicsWindow::end_flip // Access: Public, Virtual // Description: This function will be called within the draw thread -// after end_frame() has been called on all windows, to -// initiate the exchange of the front and back buffers. +// after begin_flip() has been called on all windows, to +// finish the exchange of the front and back buffers. // -// This should instruct the window to prepare for the -// flip at the next video sync, but it should not wait. -// -// We have the two separate functions, begin_flip() and -// end_flip(), to make it easier to flip all of the -// windows at the same time. +// This should cause the window to wait for the flip, if +// necessary. //////////////////////////////////////////////////////////////////// void TinyWinGraphicsWindow:: -begin_flip() { +end_flip() { + if (!_flip_ready) { + GraphicsWindow::end_flip(); + return; + } + HBITMAP bm = CreateCompatibleBitmap(_hdc, _frame_buffer->xsize, _frame_buffer->ysize); HDC bmdc = CreateCompatibleDC(_hdc); SelectObject(bmdc, bm); @@ -155,6 +156,7 @@ begin_flip() { DeleteDC(bmdc); DeleteObject(bm); GdiFlush(); + GraphicsWindow::end_flip(); } //////////////////////////////////////////////////////////////////// diff --git a/panda/src/tinydisplay/tinyWinGraphicsWindow.h b/panda/src/tinydisplay/tinyWinGraphicsWindow.h index af776c5a4c..1f8c1afbdc 100755 --- a/panda/src/tinydisplay/tinyWinGraphicsWindow.h +++ b/panda/src/tinydisplay/tinyWinGraphicsWindow.h @@ -41,7 +41,7 @@ public: virtual bool begin_frame(FrameMode mode, Thread *current_thread); virtual void end_frame(FrameMode mode, Thread *current_thread); - virtual void begin_flip(); + virtual void end_flip(); virtual bool supports_pixel_zoom() const; protected: diff --git a/panda/src/tinydisplay/tinyXGraphicsWindow.cxx b/panda/src/tinydisplay/tinyXGraphicsWindow.cxx index 788d48ef48..99e8e9777e 100644 --- a/panda/src/tinydisplay/tinyXGraphicsWindow.cxx +++ b/panda/src/tinydisplay/tinyXGraphicsWindow.cxx @@ -140,22 +140,19 @@ end_frame(FrameMode mode, Thread *current_thread) { } //////////////////////////////////////////////////////////////////// -// Function: TinyXGraphicsWindow::begin_flip +// Function: TinyXGraphicsWindow::end_flip // Access: Public, Virtual // Description: This function will be called within the draw thread -// after end_frame() has been called on all windows, to -// initiate the exchange of the front and back buffers. +// after begin_flip() has been called on all windows, to +// finish the exchange of the front and back buffers. // -// This should instruct the window to prepare for the -// flip at the next video sync, but it should not wait. -// -// We have the two separate functions, begin_flip() and -// end_flip(), to make it easier to flip all of the -// windows at the same time. +// This should cause the window to wait for the flip, if +// necessary. //////////////////////////////////////////////////////////////////// void TinyXGraphicsWindow:: -begin_flip() { - if (_xwindow == (X11_Window)NULL) { +end_flip() { + if (_xwindow == (X11_Window)NULL || !_flip_ready) { + GraphicsWindow::end_flip(); return; } @@ -177,6 +174,7 @@ begin_flip() { XPutImage(_display, _xwindow, _gc, _ximage, 0, 0, 0, 0, _full_frame_buffer->xsize, _full_frame_buffer->ysize); XFlush(_display); + GraphicsWindow::end_flip(); } //////////////////////////////////////////////////////////////////// diff --git a/panda/src/tinydisplay/tinyXGraphicsWindow.h b/panda/src/tinydisplay/tinyXGraphicsWindow.h index 20fb0c7c4e..e8e1aa9193 100644 --- a/panda/src/tinydisplay/tinyXGraphicsWindow.h +++ b/panda/src/tinydisplay/tinyXGraphicsWindow.h @@ -41,7 +41,7 @@ public: virtual bool begin_frame(FrameMode mode, Thread *current_thread); virtual void end_frame(FrameMode mode, Thread *current_thread); - virtual void begin_flip(); + virtual void end_flip(); virtual bool supports_pixel_zoom() const; virtual void process_events(); diff --git a/panda/src/wgldisplay/wglGraphicsWindow.cxx b/panda/src/wgldisplay/wglGraphicsWindow.cxx index b264b7e308..0ddcdb208a 100644 --- a/panda/src/wgldisplay/wglGraphicsWindow.cxx +++ b/panda/src/wgldisplay/wglGraphicsWindow.cxx @@ -138,19 +138,6 @@ end_frame(FrameMode mode, Thread *current_thread) { //////////////////////////////////////////////////////////////////// void wglGraphicsWindow:: begin_flip() { - if (_hdc) { - // 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. - wglGraphicsStateGuardian *wglgsg; - DCAST_INTO_V(wglgsg, _gsg); - HGLRC context = wglgsg->get_context(_hdc); - nassertv(context); - wglGraphicsPipe::wgl_make_current(_hdc, context, &_make_current_pcollector); - SwapBuffers(_hdc); - } } //////////////////////////////////////////////////////////////////// @@ -184,6 +171,34 @@ ready_flip() { } } +//////////////////////////////////////////////////////////////////// +// Function: wglGraphicsWindow::end_flip +// Access: Public, Virtual +// Description: This function will be called within the draw thread +// after begin_flip() has been called on all windows, to +// finish the exchange of the front and back buffers. +// +// This should cause the window to wait for the flip, if +// necessary. +//////////////////////////////////////////////////////////////////// +void wglGraphicsWindow:: +end_flip() { + if (_hdc != NULL && _flip_ready) { + // 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. + wglGraphicsStateGuardian *wglgsg; + DCAST_INTO_V(wglgsg, _gsg); + HGLRC context = wglgsg->get_context(_hdc); + nassertv(context); + wglGraphicsPipe::wgl_make_current(_hdc, context, &_make_current_pcollector); + SwapBuffers(_hdc); + } + WinGraphicsWindow::end_flip(); +} + //////////////////////////////////////////////////////////////////// // Function: wglGraphicsWindow::close_window // Access: Protected, Virtual diff --git a/panda/src/wgldisplay/wglGraphicsWindow.h b/panda/src/wgldisplay/wglGraphicsWindow.h index 4726243232..15720f06e8 100644 --- a/panda/src/wgldisplay/wglGraphicsWindow.h +++ b/panda/src/wgldisplay/wglGraphicsWindow.h @@ -39,6 +39,7 @@ public: virtual void begin_flip(); virtual void ready_flip(); + virtual void end_flip(); protected: virtual void close_window();