From cbdb7e76b1c3d676d46e0b1ba3d20004ce6d09a2 Mon Sep 17 00:00:00 2001 From: David Rose Date: Mon, 5 Mar 2007 22:07:16 +0000 Subject: [PATCH] fix blue flash, fix offscreen buffer leakage --- panda/src/display/graphicsEngine.cxx | 47 ++++++++++++++++++- panda/src/display/graphicsEngine.h | 1 + panda/src/display/graphicsOutput.I | 8 ++-- panda/src/display/graphicsOutput.cxx | 18 +++++++ panda/src/display/graphicsOutput.h | 6 ++- panda/src/display/parasiteBuffer.cxx | 4 +- panda/src/dxgsg8/wdxGraphicsBuffer8.cxx | 4 +- panda/src/dxgsg8/wdxGraphicsWindow8.cxx | 4 +- panda/src/dxgsg9/wdxGraphicsBuffer9.cxx | 4 +- panda/src/dxgsg9/wdxGraphicsWindow9.cxx | 4 +- panda/src/glstuff/glGraphicsBuffer_src.cxx | 16 ++++++- panda/src/glxdisplay/glxGraphicsBuffer.cxx | 4 +- panda/src/glxdisplay/glxGraphicsWindow.cxx | 4 +- .../src/mesadisplay/osMesaGraphicsBuffer.cxx | 4 +- panda/src/osxdisplay/osxGraphicsBuffer.cxx | 4 +- panda/src/osxdisplay/osxGraphicsWindow.cxx | 4 +- panda/src/wgldisplay/wglGraphicsBuffer.cxx | 4 +- panda/src/wgldisplay/wglGraphicsWindow.cxx | 4 +- 18 files changed, 112 insertions(+), 32 deletions(-) diff --git a/panda/src/display/graphicsEngine.cxx b/panda/src/display/graphicsEngine.cxx index 5e02fc3aa8..6fd15e15af 100644 --- a/panda/src/display/graphicsEngine.cxx +++ b/panda/src/display/graphicsEngine.cxx @@ -117,6 +117,7 @@ GraphicsEngine(Pipeline *pipeline) : _windows_sorted = true; _window_sort_index = 0; + _needs_open_windows = false; set_threading_model(GraphicsThreadingModel(threading_model)); if (!_threading_model.is_default()) { @@ -568,6 +569,15 @@ render_frame() { } #endif + if (_needs_open_windows) { + // Make sure our buffers and windows are fully realized before we + // render a frame. We do this particularly to realize our + // offscreen buffers, so that we don't render a frame before the + // offscreen buffers are ready (which might result in a frame + // going by without some textures having been rendered). + open_windows(); + } + ClockObject *global_clock = ClockObject::get_global_clock(); if (display_cat.is_spam()) { @@ -800,6 +810,8 @@ open_windows() { thread->_cv_mutex.release(); } } + + _needs_open_windows = false; } //////////////////////////////////////////////////////////////////// @@ -1166,6 +1178,8 @@ cull_to_bins(GraphicsOutput *win, DisplayRegion *dr, Thread *current_thread) { //////////////////////////////////////////////////////////////////// void GraphicsEngine:: draw_bins(const GraphicsEngine::Windows &wlist, Thread *current_thread) { + nassertv(wlist.verify_list()); + Windows::const_iterator wi; for (wi = wlist.begin(); wi != wlist.end(); ++wi) { GraphicsOutput *win = (*wi); @@ -1173,7 +1187,11 @@ draw_bins(const GraphicsEngine::Windows &wlist, Thread *current_thread) { PStatTimer timer(win->get_draw_window_pcollector(), current_thread); if (win->begin_frame(GraphicsOutput::FM_render, current_thread)) { win->clear(current_thread); - + + if (display_cat.is_spam()) { + display_cat.spam() + << "Drawing window " << win->get_name() << "\n"; + } int num_display_regions = win->get_num_active_display_regions(); for (int i = 0; i < num_display_regions; ++i) { DisplayRegion *dr = win->get_active_display_region(i); @@ -1195,6 +1213,16 @@ draw_bins(const GraphicsEngine::Windows &wlist, Thread *current_thread) { } } } + } else { + if (display_cat.is_spam()) { + display_cat.spam() + << "Not drawing window " << win->get_name() << "\n"; + } + } + } else { + if (display_cat.is_spam()) { + display_cat.spam() + << "Window " << win->get_name() << " is inactive\n"; } } } @@ -1648,6 +1676,7 @@ do_add_window(GraphicsOutput *window, } window->request_open(); + _needs_open_windows = true; } //////////////////////////////////////////////////////////////////// @@ -1920,6 +1949,8 @@ remove_window(GraphicsOutput *window) { PT(GraphicsOutput) ptwin = window; _cull.erase(ptwin); + _cdraw.erase(ptwin); + _draw.erase(ptwin); Windows::iterator wi; @@ -1969,6 +2000,14 @@ resort_windows() { } display_cat.debug(false) << "\n"; + + for (wi = _draw.begin(); wi != _draw.end(); ++wi) { + GraphicsOutput *win = (*wi); + display_cat.debug(false) + << " " << win->get_name() << "(" << win->get_sort() << ")"; + } + display_cat.debug(false) + << "\n"; } } @@ -2090,12 +2129,18 @@ do_pending(GraphicsEngine *engine, Thread *current_thread) { ReMutexHolder holder(_wl_lock); if (!_pending_close.empty()) { + if (display_cat.is_debug()) { + display_cat.debug() + << "_pending_close.size() = " << _pending_close.size() << "\n"; + } + // Close any windows that were pending closure. Windows::iterator wi; for (wi = _pending_close.begin(); wi != _pending_close.end(); ++wi) { GraphicsOutput *win = (*wi); win->set_close_now(); } + _pending_close.clear(); } } diff --git a/panda/src/display/graphicsEngine.h b/panda/src/display/graphicsEngine.h index 1731e9ce13..01193acadd 100644 --- a/panda/src/display/graphicsEngine.h +++ b/panda/src/display/graphicsEngine.h @@ -316,6 +316,7 @@ private: Windows _windows; bool _windows_sorted; unsigned int _window_sort_index; + bool _needs_open_windows; WindowRenderer _app; typedef pmap Threads; diff --git a/panda/src/display/graphicsOutput.I b/panda/src/display/graphicsOutput.I index 682cf123e6..ffbb36620a 100644 --- a/panda/src/display/graphicsOutput.I +++ b/panda/src/display/graphicsOutput.I @@ -554,10 +554,10 @@ get_draw_window_pcollector() { // Description: Display the spam message associated with begin_frame //////////////////////////////////////////////////////////////////// INLINE void GraphicsOutput:: -begin_frame_spam() { +begin_frame_spam(FrameMode mode) { if (display_cat.is_spam()) { display_cat.spam() - << "begin_frame(): " << get_type() << " " + << "begin_frame(" << mode << "): " << get_type() << " " << get_name() << " " << (void *)this << "\n"; } } @@ -568,10 +568,10 @@ begin_frame_spam() { // Description: Display the spam message associated with end_frame //////////////////////////////////////////////////////////////////// INLINE void GraphicsOutput:: -end_frame_spam() { +end_frame_spam(FrameMode mode) { if (display_cat.is_spam()) { display_cat.spam() - << "end_frame(): " << get_type() << " " + << "end_frame(" << mode << "): " << get_type() << " " << get_name() << " " << (void *)this << "\n"; } } diff --git a/panda/src/display/graphicsOutput.cxx b/panda/src/display/graphicsOutput.cxx index dcd83a586d..e445d6d96e 100644 --- a/panda/src/display/graphicsOutput.cxx +++ b/panda/src/display/graphicsOutput.cxx @@ -1189,3 +1189,21 @@ do_determine_display_regions() { stable_sort(_active_display_regions.begin(), _active_display_regions.end(), IndirectLess()); } +//////////////////////////////////////////////////////////////////// +// Function: GraphicsOutput::FrameMode output operator +// Description: +//////////////////////////////////////////////////////////////////// +ostream & +operator << (ostream &out, GraphicsOutput::FrameMode fm) { + switch (fm) { + case GraphicsOutput::FM_render: + return out << "render"; + case GraphicsOutput::FM_parasite: + return out << "parasite"; + case GraphicsOutput::FM_refresh: + return out << "refresh"; + } + + return out << "(**invalid GraphicsOutput::FrameMode(" << (int)fm << ")**)"; +} + diff --git a/panda/src/display/graphicsOutput.h b/panda/src/display/graphicsOutput.h index 1b23389a8e..e5276915c7 100644 --- a/panda/src/display/graphicsOutput.h +++ b/panda/src/display/graphicsOutput.h @@ -242,8 +242,8 @@ protected: void prepare_for_deletion(); void copy_to_textures(); - INLINE void begin_frame_spam(); - INLINE void end_frame_spam(); + INLINE void begin_frame_spam(FrameMode mode); + INLINE void end_frame_spam(FrameMode mode); INLINE void clear_cube_map_selection(); INLINE void trigger_flip(); @@ -342,6 +342,8 @@ private: friend class DisplayRegion; }; +EXPCL_PANDA ostream &operator << (ostream &out, GraphicsOutput::FrameMode mode); + #include "graphicsOutput.I" #endif /* GRAPHICSOUTPUT_H */ diff --git a/panda/src/display/parasiteBuffer.cxx b/panda/src/display/parasiteBuffer.cxx index a575574a2b..8bc670d4a5 100644 --- a/panda/src/display/parasiteBuffer.cxx +++ b/panda/src/display/parasiteBuffer.cxx @@ -109,7 +109,7 @@ get_host() { //////////////////////////////////////////////////////////////////// bool ParasiteBuffer:: begin_frame(FrameMode mode, Thread *current_thread) { - begin_frame_spam(); + begin_frame_spam(mode); if (!_host->begin_frame(FM_parasite, current_thread)) { return false; @@ -136,7 +136,7 @@ begin_frame(FrameMode mode, Thread *current_thread) { //////////////////////////////////////////////////////////////////// void ParasiteBuffer:: end_frame(FrameMode mode, Thread *current_thread) { - end_frame_spam(); + end_frame_spam(mode); nassertv(_gsg != (GraphicsStateGuardian *)NULL); diff --git a/panda/src/dxgsg8/wdxGraphicsBuffer8.cxx b/panda/src/dxgsg8/wdxGraphicsBuffer8.cxx index 212deaac15..942768ff7b 100644 --- a/panda/src/dxgsg8/wdxGraphicsBuffer8.cxx +++ b/panda/src/dxgsg8/wdxGraphicsBuffer8.cxx @@ -101,7 +101,7 @@ wdxGraphicsBuffer8:: bool wdxGraphicsBuffer8:: begin_frame(FrameMode mode, Thread *current_thread) { - begin_frame_spam(); + begin_frame_spam(mode); if (_gsg == (GraphicsStateGuardian *)NULL) { return false; } @@ -134,7 +134,7 @@ begin_frame(FrameMode mode, Thread *current_thread) { void wdxGraphicsBuffer8:: end_frame(FrameMode mode, Thread *current_thread) { - end_frame_spam(); + end_frame_spam(mode); nassertv(_gsg != (GraphicsStateGuardian *)NULL); if (mode == FM_render) { diff --git a/panda/src/dxgsg8/wdxGraphicsWindow8.cxx b/panda/src/dxgsg8/wdxGraphicsWindow8.cxx index c9a2ea6eee..415502c374 100644 --- a/panda/src/dxgsg8/wdxGraphicsWindow8.cxx +++ b/panda/src/dxgsg8/wdxGraphicsWindow8.cxx @@ -78,7 +78,7 @@ wdxGraphicsWindow8:: //////////////////////////////////////////////////////////////////// bool wdxGraphicsWindow8:: begin_frame(FrameMode mode, Thread *current_thread) { - begin_frame_spam(); + begin_frame_spam(mode); if (_gsg == (GraphicsStateGuardian *)NULL) { return false; } @@ -116,7 +116,7 @@ begin_frame(FrameMode mode, Thread *current_thread) { void wdxGraphicsWindow8:: end_frame(FrameMode mode, Thread *current_thread) { - end_frame_spam(); + end_frame_spam(mode); nassertv(_gsg != (GraphicsStateGuardian *)NULL); if (mode == FM_render) { diff --git a/panda/src/dxgsg9/wdxGraphicsBuffer9.cxx b/panda/src/dxgsg9/wdxGraphicsBuffer9.cxx index 10df6ee795..8ae3c9c8fe 100644 --- a/panda/src/dxgsg9/wdxGraphicsBuffer9.cxx +++ b/panda/src/dxgsg9/wdxGraphicsBuffer9.cxx @@ -94,7 +94,7 @@ wdxGraphicsBuffer9:: bool wdxGraphicsBuffer9:: begin_frame(FrameMode mode, Thread *current_thread) { - begin_frame_spam(); + begin_frame_spam(mode); if (_gsg == (GraphicsStateGuardian *)NULL) { return false; } @@ -127,7 +127,7 @@ begin_frame(FrameMode mode, Thread *current_thread) { void wdxGraphicsBuffer9:: end_frame(FrameMode mode, Thread *current_thread) { - end_frame_spam(); + end_frame_spam(mode); nassertv(_gsg != (GraphicsStateGuardian *)NULL); if (mode == FM_render) { diff --git a/panda/src/dxgsg9/wdxGraphicsWindow9.cxx b/panda/src/dxgsg9/wdxGraphicsWindow9.cxx index 175e2d66a3..c00d1a7d11 100755 --- a/panda/src/dxgsg9/wdxGraphicsWindow9.cxx +++ b/panda/src/dxgsg9/wdxGraphicsWindow9.cxx @@ -96,7 +96,7 @@ make_current() { //////////////////////////////////////////////////////////////////// bool wdxGraphicsWindow9:: begin_frame(FrameMode mode, Thread *current_thread) { - begin_frame_spam(); + begin_frame_spam(mode); if (_gsg == (GraphicsStateGuardian *)NULL) { return false; } @@ -134,7 +134,7 @@ begin_frame(FrameMode mode, Thread *current_thread) { void wdxGraphicsWindow9:: end_frame(FrameMode mode, Thread *current_thread) { - end_frame_spam(); + end_frame_spam(mode); nassertv(_gsg != (GraphicsStateGuardian *)NULL); if (mode == FM_render) { diff --git a/panda/src/glstuff/glGraphicsBuffer_src.cxx b/panda/src/glstuff/glGraphicsBuffer_src.cxx index 2a7357a19a..94d1d86d1b 100644 --- a/panda/src/glstuff/glGraphicsBuffer_src.cxx +++ b/panda/src/glstuff/glGraphicsBuffer_src.cxx @@ -68,11 +68,21 @@ CLP(GraphicsBuffer):: //////////////////////////////////////////////////////////////////// bool CLP(GraphicsBuffer):: begin_frame(FrameMode mode, Thread *current_thread) { + begin_frame_spam(mode); + if (!_is_valid) { + if (GLCAT.is_debug()) { + GLCAT.debug() + << get_name() << " is not valid\n"; + } return false; } if (!_host->begin_frame(FM_parasite, current_thread)) { + if (GLCAT.is_debug()) { + GLCAT.debug() + << get_name() << "'s host is not ready\n"; + } return false; } @@ -81,6 +91,10 @@ begin_frame(FrameMode mode, Thread *current_thread) { rebuild_bitplanes(); clear_cube_map_selection(); if (!check_fbo()) { + if (GLCAT.is_debug()) { + GLCAT.debug() + << get_name() << " check_fbo() returns false\n"; + } return false; } } @@ -401,7 +415,7 @@ generate_mipmaps() { //////////////////////////////////////////////////////////////////// void CLP(GraphicsBuffer):: end_frame(FrameMode mode, Thread *current_thread) { - end_frame_spam(); + end_frame_spam(mode); nassertv(_gsg != (GraphicsStateGuardian *)NULL); if (mode == FM_render) { diff --git a/panda/src/glxdisplay/glxGraphicsBuffer.cxx b/panda/src/glxdisplay/glxGraphicsBuffer.cxx index 00f48c1d2c..e84b8a7c2e 100644 --- a/panda/src/glxdisplay/glxGraphicsBuffer.cxx +++ b/panda/src/glxdisplay/glxGraphicsBuffer.cxx @@ -79,7 +79,7 @@ bool glxGraphicsBuffer:: begin_frame(FrameMode mode, Thread *current_thread) { PStatTimer timer(_make_current_pcollector, current_thread); - begin_frame_spam(); + begin_frame_spam(mode); if (_gsg == (GraphicsStateGuardian *)NULL) { return false; } @@ -112,7 +112,7 @@ begin_frame(FrameMode mode, Thread *current_thread) { //////////////////////////////////////////////////////////////////// void glxGraphicsBuffer:: end_frame(FrameMode mode, Thread *current_thread) { - end_frame_spam(); + end_frame_spam(mode); nassertv(_gsg != (GraphicsStateGuardian *)NULL); if (mode == FM_render) { diff --git a/panda/src/glxdisplay/glxGraphicsWindow.cxx b/panda/src/glxdisplay/glxGraphicsWindow.cxx index 340ff8563f..7968ecbcb8 100644 --- a/panda/src/glxdisplay/glxGraphicsWindow.cxx +++ b/panda/src/glxdisplay/glxGraphicsWindow.cxx @@ -127,7 +127,7 @@ bool glxGraphicsWindow:: begin_frame(FrameMode mode, Thread *current_thread) { PStatTimer timer(_make_current_pcollector, current_thread); - begin_frame_spam(); + begin_frame_spam(mode); if (_gsg == (GraphicsStateGuardian *)NULL) { return false; } @@ -168,7 +168,7 @@ begin_frame(FrameMode mode, Thread *current_thread) { //////////////////////////////////////////////////////////////////// void glxGraphicsWindow:: end_frame(FrameMode mode, Thread *current_thread) { - end_frame_spam(); + end_frame_spam(mode); nassertv(_gsg != (GraphicsStateGuardian *)NULL); if (mode == FM_render) { diff --git a/panda/src/mesadisplay/osMesaGraphicsBuffer.cxx b/panda/src/mesadisplay/osMesaGraphicsBuffer.cxx index c80d06b93b..10bb33c48c 100644 --- a/panda/src/mesadisplay/osMesaGraphicsBuffer.cxx +++ b/panda/src/mesadisplay/osMesaGraphicsBuffer.cxx @@ -62,7 +62,7 @@ OsMesaGraphicsBuffer:: //////////////////////////////////////////////////////////////////// bool OsMesaGraphicsBuffer:: begin_frame(FrameMode mode, Thread *current_thread) { - begin_frame_spam(); + begin_frame_spam(mode); if (_gsg == (GraphicsStateGuardian *)NULL) { return false; } @@ -91,7 +91,7 @@ begin_frame(FrameMode mode, Thread *current_thread) { //////////////////////////////////////////////////////////////////// void OsMesaGraphicsBuffer:: end_frame(FrameMode mode, Thread *current_thread) { - end_frame_spam(); + end_frame_spam(mode); nassertv(_gsg != (GraphicsStateGuardian *)NULL); if (mode == FM_render) { diff --git a/panda/src/osxdisplay/osxGraphicsBuffer.cxx b/panda/src/osxdisplay/osxGraphicsBuffer.cxx index e97149f892..ce654f080c 100644 --- a/panda/src/osxdisplay/osxGraphicsBuffer.cxx +++ b/panda/src/osxdisplay/osxGraphicsBuffer.cxx @@ -67,7 +67,7 @@ bool osxGraphicsBuffer:: begin_frame(FrameMode mode, Thread *current_thread) { PStatTimer timer(_make_current_pcollector); - begin_frame_spam(); + begin_frame_spam(mode); if (_gsg == (GraphicsStateGuardian *)NULL) { return false; } @@ -96,7 +96,7 @@ begin_frame(FrameMode mode, Thread *current_thread) { //////////////////////////////////////////////////////////////////// void osxGraphicsBuffer:: end_frame(FrameMode mode, Thread *current_thread) { - end_frame_spam(); + end_frame_spam(mode); nassertv(_gsg != (GraphicsStateGuardian *)NULL); if (mode == FM_render) diff --git a/panda/src/osxdisplay/osxGraphicsWindow.cxx b/panda/src/osxdisplay/osxGraphicsWindow.cxx index 84e3b95a94..563264fa67 100644 --- a/panda/src/osxdisplay/osxGraphicsWindow.cxx +++ b/panda/src/osxdisplay/osxGraphicsWindow.cxx @@ -687,7 +687,7 @@ bool osxGraphicsWindow::begin_frame(FrameMode mode, Thread *current_thread) { PStatTimer timer(_make_current_pcollector); - begin_frame_spam(); + begin_frame_spam(mode); if (_gsg == (GraphicsStateGuardian *)NULL || (_osx_window == NULL && _is_fullscreen != true)) { // not powered up .. just abort.. @@ -749,7 +749,7 @@ bool osxGraphicsWindow::begin_frame(FrameMode mode, Thread *current_thread) //////////////////////////////////////////////////////////////////// void osxGraphicsWindow::end_frame(FrameMode mode, Thread *current_thread) { - end_frame_spam(); + end_frame_spam(mode); if(mode == FM_render ) { nassertv(_gsg != (GraphicsStateGuardian *)NULL); diff --git a/panda/src/wgldisplay/wglGraphicsBuffer.cxx b/panda/src/wgldisplay/wglGraphicsBuffer.cxx index ba80643dfd..4cd189c401 100644 --- a/panda/src/wgldisplay/wglGraphicsBuffer.cxx +++ b/panda/src/wgldisplay/wglGraphicsBuffer.cxx @@ -72,7 +72,7 @@ wglGraphicsBuffer:: bool wglGraphicsBuffer:: begin_frame(FrameMode mode, Thread *current_thread) { - begin_frame_spam(); + begin_frame_spam(mode); if (_gsg == (GraphicsStateGuardian *)NULL) { return false; } @@ -111,7 +111,7 @@ begin_frame(FrameMode mode, Thread *current_thread) { //////////////////////////////////////////////////////////////////// void wglGraphicsBuffer:: end_frame(FrameMode mode, Thread *current_thread) { - end_frame_spam(); + end_frame_spam(mode); nassertv(_gsg != (GraphicsStateGuardian *)NULL); if (mode == FM_render) { diff --git a/panda/src/wgldisplay/wglGraphicsWindow.cxx b/panda/src/wgldisplay/wglGraphicsWindow.cxx index df339713dd..bc2e239c2f 100644 --- a/panda/src/wgldisplay/wglGraphicsWindow.cxx +++ b/panda/src/wgldisplay/wglGraphicsWindow.cxx @@ -66,7 +66,7 @@ wglGraphicsWindow:: bool wglGraphicsWindow:: begin_frame(FrameMode mode, Thread *current_thread) { - begin_frame_spam(); + begin_frame_spam(mode); if (_gsg == (GraphicsStateGuardian *)NULL) { return false; } @@ -98,7 +98,7 @@ begin_frame(FrameMode mode, Thread *current_thread) { void wglGraphicsWindow:: end_frame(FrameMode mode, Thread *current_thread) { - end_frame_spam(); + end_frame_spam(mode); nassertv(_gsg != (GraphicsStateGuardian *)NULL);