GraphicsWindow::_unexposed_draw

This commit is contained in:
David Rose 2012-01-15 20:13:16 +00:00
parent 38a73900f1
commit 6f5fd1525d
14 changed files with 130 additions and 11 deletions

View File

@ -585,7 +585,7 @@ class ShowBase(DirectObject.DirectObject):
def openWindow(self, props = None, fbprops = None, pipe = None, gsg = None,
type = None, name = None, size = None, aspectRatio = None,
makeCamera = True, keepCamera = False,
scene = None, stereo = None,
scene = None, stereo = None, unexposedDraw = None,
callbackWindowDict = None, requireWindow = None):
"""
Creates a window and adds it to the list of windows that are
@ -601,6 +601,9 @@ class ShowBase(DirectObject.DirectObject):
If keepCamera is false but makeCamera is true, a new camera is
set up to render into the new window.
If unexposedDraw is not None, it specifies the initial value
of GraphicsWindow.setUnexposedDraw().
If callbackWindowDict is not None, a CallbackGraphicWindow is
created instead, which allows the caller to create the actual
window with its own OpenGL context, and direct Panda's
@ -618,7 +621,7 @@ class ShowBase(DirectObject.DirectObject):
props = props, fbprops = fbprops, pipe = pipe, gsg = gsg,
type = type, name = name, size = size, aspectRatio = aspectRatio,
makeCamera = makeCamera, keepCamera = keepCamera,
scene = scene, stereo = stereo,
scene = scene, stereo = stereo, unexposedDraw = unexposedDraw,
callbackWindowDict = callbackWindowDict)
if self.win:
@ -678,7 +681,7 @@ class ShowBase(DirectObject.DirectObject):
def _doOpenWindow(self, props = None, fbprops = None, pipe = None, gsg = None,
type = None, name = None, size = None, aspectRatio = None,
makeCamera = True, keepCamera = False,
scene = None, stereo = None,
scene = None, stereo = None, unexposedDraw = None,
callbackWindowDict = None):
if pipe == None:
pipe = self.pipe
@ -745,6 +748,9 @@ class ShowBase(DirectObject.DirectObject):
# Couldn't create a window!
return None
if unexposedDraw is not None and hasattr(win, 'setUnexposedDraw'):
win.setUnexposedDraw(unexposedDraw)
if callbackWindowDict:
# If we asked for (and received) a CallbackGraphicsWindow,
# we now have to assign the callbacks, before we start

View File

@ -40,7 +40,8 @@ class EmbeddedPandaWindow(wx.Window):
# only happen on 32-bit Windows.
wp.setParentWindow(self.GetHandle() & 0xffffffff)
self.win = base.openWindow(props = wp, gsg = gsg, type = 'onscreen')
self.win = base.openWindow(props = wp, gsg = gsg, type = 'onscreen',
unexposedDraw = False)
self.Bind(wx.EVT_SIZE, self.onSize)
# This doesn't actually do anything, since wx won't call

View File

@ -336,6 +336,11 @@ ConfigVariableInt parent_window_handle
"an HWND on Windows, or the NSWindow pointer or XWindow pointer "
"converted to an integer, on OSX and X11."));
ConfigVariableBool win_unexposed_draw
("win-unexposed-draw", true,
PRC_DESC("Specifies the default setting of GraphicsWindow::set_unexposed_draw(). "
"See that method for more information."));
ConfigVariableFilename subprocess_window
("subprocess-window", "",
PRC_DESC("The filename of a SubprocessWindowBuffer's temporary mmap file, "

View File

@ -78,6 +78,7 @@ extern EXPCL_PANDA_DISPLAY ConfigVariableFilename cursor_filename;
extern EXPCL_PANDA_DISPLAY ConfigVariableEnum<WindowProperties::ZOrder> z_order;
extern EXPCL_PANDA_DISPLAY ConfigVariableString window_title;
extern EXPCL_PANDA_DISPLAY ConfigVariableInt parent_window_handle;
extern EXPCL_PANDA_DISPLAY ConfigVariableBool win_unexposed_draw;
extern EXPCL_PANDA_DISPLAY ConfigVariableFilename subprocess_window;
extern EXPCL_PANDA_DISPLAY ConfigVariableString framebuffer_mode;

View File

@ -845,8 +845,10 @@ clear_cube_map_selection() {
////////////////////////////////////////////////////////////////////
// Function: GraphicsOutput::trigger_flip
// Access: Public
// Description: Set the flip_ready flag, only if legal to do so.
// Access: Protected
// Description: To be called at the end of the frame, after the
// window has successfully been drawn and is ready to be
// flipped (if appropriate).
////////////////////////////////////////////////////////////////////
INLINE void GraphicsOutput::
trigger_flip() {

View File

@ -92,12 +92,13 @@ GraphicsOutput(GraphicsEngine *engine, GraphicsPipe *pipe,
_creation_flags = flags;
_x_size = _y_size = 0;
_has_size = win_prop.has_size();
_is_nonzero_size = false;
if (_has_size) {
_x_size = win_prop.get_x_size();
_y_size = win_prop.get_y_size();
_is_nonzero_size = (_x_size > 0 && _y_size > 0);
}
_is_valid = false;
_is_nonzero_size = false;
_flip_ready = false;
_cube_map_index = -1;
_cube_map_dr = NULL;

View File

@ -40,6 +40,36 @@ is_fullscreen() const {
return _properties.get_fullscreen();
}
////////////////////////////////////////////////////////////////////
// Function: GraphicsWindow::set_unexposed_draw
// Access: Published
// Description: If this flag is false, the window is redrawn only
// after it has received a recent "unexpose" or "draw"
// event from the underlying windowing systme. If this
// flag is true, the window is redrawn every frame
// regardless. Setting this false may prevent the
// window from redrawing unnecessarily when it is
// hidden, and may play nicer with other windows on the
// desktop, but may adversely affect frame rate even
// when the window is fully visible; setting it true will
// ensure that the window contents are always current.
////////////////////////////////////////////////////////////////////
INLINE void GraphicsWindow::
set_unexposed_draw(bool unexposed_draw) {
_unexposed_draw = unexposed_draw;
}
////////////////////////////////////////////////////////////////////
// Function: GraphicsWindow::get_unexposed_draw
// Access: Published
// Description: See set_unexposed_draw().
////////////////////////////////////////////////////////////////////
INLINE bool GraphicsWindow::
get_unexposed_draw() const {
return _unexposed_draw;
}
////////////////////////////////////////////////////////////////////
// Function: GraphicsWindow::get_window_handle
// Access: Published

View File

@ -62,6 +62,8 @@ GraphicsWindow(GraphicsEngine *engine, GraphicsPipe *pipe,
request_properties(win_prop);
_window_event = "window-event";
_got_expose_event = false;
_unexposed_draw = win_unexposed_draw;
set_pixel_zoom(pixel_zoom);
}

View File

@ -71,6 +71,9 @@ PUBLISHED:
void set_close_request_event(const string &close_request_event);
string get_close_request_event() const;
INLINE void set_unexposed_draw(bool unexposed_draw);
INLINE bool get_unexposed_draw() const;
INLINE WindowHandle *get_window_handle() const;
// Mouse and keyboard routines
@ -151,6 +154,8 @@ protected:
PT(WindowHandle) _window_handle;
PT(WindowHandle) _parent_window_handle;
bool _got_expose_event;
private:
LightReMutex _properties_lock;
// protects _requested_properties, _rejected_properties, and
@ -160,6 +165,7 @@ private:
WindowProperties _rejected_properties;
string _window_event;
string _close_request_event;
bool _unexposed_draw;
#ifdef HAVE_PYTHON
typedef pset<PythonGraphicsWindowProc*> PythonWinProcClasses;

View File

@ -97,6 +97,14 @@ begin_frame(FrameMode mode, Thread *current_thread) {
return false;
}
if (!get_unexposed_draw() && !_got_expose_event) {
if (wdxdisplay9_cat.is_spam()) {
wdxdisplay9_cat.spam()
<< "Not drawing " << this << ": unexposed.\n";
}
return false;
}
if (_awaiting_restore) {
// The fullscreen window was recently restored; we can't continue
// until the GSG says we can.
@ -129,7 +137,6 @@ begin_frame(FrameMode mode, Thread *current_thread) {
////////////////////////////////////////////////////////////////////
void wdxGraphicsWindow9::
end_frame(FrameMode mode, Thread *current_thread) {
end_frame_spam(mode);
nassertv(_gsg != (GraphicsStateGuardian *)NULL);
@ -160,7 +167,7 @@ end_flip() {
if (_dxgsg != (DXGraphicsStateGuardian9 *)NULL && is_active()) {
_dxgsg->show_frame();
}
GraphicsWindow::end_flip();
WinGraphicsWindow::end_flip();
}
////////////////////////////////////////////////////////////////////

View File

@ -72,6 +72,14 @@ begin_frame(FrameMode mode, Thread *current_thread) {
return false;
}
if (!get_unexposed_draw() && !_got_expose_event) {
if (tinydisplay_cat.is_spam()) {
tinydisplay_cat.spam()
<< "Not drawing " << this << ": unexposed.\n";
}
return false;
}
TinyGraphicsStateGuardian *tinygsg;
DCAST_INTO_R(tinygsg, _gsg, false);

View File

@ -66,6 +66,19 @@ begin_frame(FrameMode mode, Thread *current_thread) {
if (_gsg == (GraphicsStateGuardian *)NULL) {
return false;
}
if (!get_unexposed_draw() && !_got_expose_event) {
if (wgldisplay_cat.is_spam()) {
wgldisplay_cat.spam()
<< "Not drawing " << this << ": unexposed.\n";
}
return false;
}
if (wgldisplay_cat.is_spam()) {
wgldisplay_cat.spam()
<< "Drawing " << this << ": exposed.\n";
}
wglGraphicsStateGuardian *wglgsg;
DCAST_INTO_R(wglgsg, _gsg, false);
@ -93,7 +106,6 @@ begin_frame(FrameMode mode, Thread *current_thread) {
////////////////////////////////////////////////////////////////////
void wglGraphicsWindow::
end_frame(FrameMode mode, Thread *current_thread) {
end_frame_spam(mode);
nassertv(_gsg != (GraphicsStateGuardian *)NULL);

View File

@ -364,6 +364,30 @@ set_properties_now(WindowProperties &properties) {
}
}
////////////////////////////////////////////////////////////////////
// Function: WinGraphicsWindow::trigger_flip
// Access: Protected
// Description: To be called at the end of the frame, after the
// window has successfully been drawn and is ready to be
// flipped (if appropriate).
////////////////////////////////////////////////////////////////////
void WinGraphicsWindow::
trigger_flip() {
GraphicsWindow::trigger_flip();
if (!get_unexposed_draw()) {
// Now that we've drawn or whatever, invalidate the rectangle so
// we won't redraw again until we get the WM_PAINT message.
InvalidateRect(_hWnd, NULL, FALSE);
_got_expose_event = false;
if (windisplay_cat.is_spam()) {
windisplay_cat.spam()
<< "InvalidateRect: " << this << "\n";
}
}
}
////////////////////////////////////////////////////////////////////
// Function: WinGraphicsWindow::close_window
@ -1450,7 +1474,7 @@ window_proc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) {
handle_reshape();
}
break;
case WM_EXITSIZEMOVE:
handle_reshape();
break;
@ -1458,6 +1482,19 @@ window_proc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) {
case WM_WINDOWPOSCHANGED:
adjust_z_order();
break;
case WM_PAINT:
// In response to WM_PAINT, we check to see if there are any
// update regions at all; if there are, we declare the window
// exposed. This is used to implement !_unexposed_draw.
if (GetUpdateRect(_hWnd, NULL, false)) {
if (windisplay_cat.is_spam()) {
windisplay_cat.spam()
<< "Got update regions: " << this << "\n";
}
_got_expose_event = true;
}
break;
case WM_LBUTTONDOWN:
if (_lost_keypresses) {

View File

@ -88,6 +88,7 @@ public:
virtual TouchInfo get_touch_info(int index);
protected:
void trigger_flip();
virtual void close_window();
virtual bool open_window();
virtual void fullscreen_minimized(WindowProperties &properties);