The buffer flip should be performed in end_flip(), not in begin_flip(). This long-existing mistake caused double-flips with parasite buffers in effect.
This commit is contained in:
parent
c9138166fa
commit
d743dc8a55
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
|
|||
|
|
@ -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:
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -39,6 +39,7 @@ public:
|
|||
|
||||
virtual void begin_flip();
|
||||
virtual void ready_flip();
|
||||
virtual void end_flip();
|
||||
|
||||
protected:
|
||||
virtual void close_window();
|
||||
|
|
|
|||
Loading…
Reference in New Issue