redisplay is now also on the work list instead of handled separately

git-svn-id: https://svn.code.sf.net/p/freeglut/code/trunk@1614 7f0cb862-5218-0410-a997-914c9d46530a
This commit is contained in:
dcnieho 2013-04-07 08:04:46 +00:00
parent 28539c8e95
commit 5658b01337
8 changed files with 61 additions and 59 deletions

View File

@ -495,6 +495,8 @@ void fgPlatformProcessWork(SFG_Window *window)
/* Now clear it so that any callback generated by the actions below can set work again */ /* Now clear it so that any callback generated by the actions below can set work again */
window->State.WorkMask = 0; window->State.WorkMask = 0;
if (workMask&~GLUT_DISPLAY_WORK) /* Display work is the common case, skip all the below at once */
{
/* This is before the first display callback: call a few callbacks to inform user of window size, position, etc /* This is before the first display callback: call a few callbacks to inform user of window size, position, etc
* we know this is before the first display callback of a window as for all windows GLUT_INIT_WORK is set when * we know this is before the first display callback of a window as for all windows GLUT_INIT_WORK is set when
* they are opened, and work is done before displaying in the mainloop. * they are opened, and work is done before displaying in the mainloop.
@ -562,5 +564,15 @@ void fgPlatformProcessWork(SFG_Window *window)
break; break;
} }
} }
}
if (workMask & GLUT_DISPLAY_WORK)
{
if( window->State.Visible )
fghRedrawWindow ( window );
/* Strip out display work that might have ended up on work list now as some of the above genereates callbacks */
window->State.WorkMask &= ~GLUT_DISPLAY_WORK;
}
} }

View File

@ -47,7 +47,7 @@ void FGAPIENTRY glutPostRedisplay( void )
" with no current window defined.", "glutPostRedisplay" ) ; " with no current window defined.", "glutPostRedisplay" ) ;
} }
fgStructure.CurrentWindow->State.Redisplay = GL_TRUE; fgStructure.CurrentWindow->State.WorkMask |= GLUT_DISPLAY_WORK;
} }
/* /*
@ -98,7 +98,7 @@ void FGAPIENTRY glutPostWindowRedisplay( int windowID )
FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutPostWindowRedisplay" ); FREEGLUT_EXIT_IF_NOT_INITIALISED ( "glutPostWindowRedisplay" );
window = fgWindowByID( windowID ); window = fgWindowByID( windowID );
freeglut_return_if_fail( window ); freeglut_return_if_fail( window );
window->State.Redisplay = GL_TRUE; window->State.WorkMask |= GLUT_DISPLAY_WORK;
} }
/*** END OF FILE ***/ /*** END OF FILE ***/

View File

@ -392,6 +392,7 @@ struct tagSFG_Context
#define GLUT_SIZE_WORK (1<<3) #define GLUT_SIZE_WORK (1<<3)
#define GLUT_ZORDER_WORK (1<<4) #define GLUT_ZORDER_WORK (1<<4)
#define GLUT_FULL_SCREEN_WORK (1<<5) #define GLUT_FULL_SCREEN_WORK (1<<5)
#define GLUT_DISPLAY_WORK (1<<6)
/* /*
* An enumeration containing the state of the GLUT execution: * An enumeration containing the state of the GLUT execution:
@ -457,12 +458,8 @@ struct tagSFG_WindowState /* as per notes above, sizes always refer to the cli
int DesiredZOrder; /* desired window Z Order position */ int DesiredZOrder; /* desired window Z Order position */
fgDesiredVisibility DesiredVisibility;/* desired visibility (hidden, iconic, shown/normal) */ fgDesiredVisibility DesiredVisibility;/* desired visibility (hidden, iconic, shown/normal) */
SFG_PlatformWindowState pWState; /* Window width/height (X11) or rectangle/style (Windows) from before a resize, and other stuff only needed on specific platforms */ SFG_PlatformWindowState pWState; /* Window width/height (X11) or rectangle/style (Windows) from before a resize, and other stuff only needed on specific platforms */
GLboolean Redisplay; /* Do we have to redisplay? */
long JoystickPollRate; /* The joystick polling rate */ long JoystickPollRate; /* The joystick polling rate */
fg_time_t JoystickLastPoll; /* When the last poll happened */ fg_time_t JoystickLastPoll; /* When the last poll happened */

View File

@ -92,7 +92,7 @@ void fghOnReshapeNotify(SFG_Window *window, int width, int height, GLboolean for
* window. * window.
* DN: Hmm.. the above sounds like a concern only in single buffered mode... * DN: Hmm.. the above sounds like a concern only in single buffered mode...
*/ */
glutPostRedisplay( ); window->State.WorkMask |= GLUT_DISPLAY_WORK;
if( window->IsMenu ) if( window->IsMenu )
fgSetWindow( saved_window ); fgSetWindow( saved_window );
} }
@ -179,33 +179,6 @@ static void fghProcessWork( void )
fgEnumWindows( fghcbProcessWork, &enumerator ); fgEnumWindows( fghcbProcessWork, &enumerator );
} }
static void fghcbDisplayWindow( SFG_Window *window,
SFG_Enumerator *enumerator )
{
if( window->State.Redisplay &&
window->State.Visible )
{
window->State.Redisplay = GL_FALSE;
fghRedrawWindow ( window );
}
fgEnumSubWindows( window, fghcbDisplayWindow, enumerator );
}
/*
* Make all windows perform a display call
*/
static void fghDisplayAll( void )
{
SFG_Enumerator enumerator;
enumerator.found = GL_FALSE;
enumerator.data = NULL;
fgEnumWindows( fghcbDisplayWindow, &enumerator );
}
/* /*
* Window enumerator callback to check for the joystick polling code * Window enumerator callback to check for the joystick polling code
*/ */
@ -357,29 +330,28 @@ void fgWarning( const char *fmt, ... )
/* /*
* Indicates whether a redisplay is pending for ANY window. * Indicates whether work is pending for ANY window.
* *
* The current mechanism is to walk all of the windows and ask if * The current mechanism is to walk all of the windows and ask if
* a redisplay is pending. We have a short-circuit early * work is pending. We have a short-circuit early return if we find any.
* return if we find any.
*/ */
static void fghHavePendingRedisplaysCallback( SFG_Window* w, SFG_Enumerator* e) static void fghHavePendingWorkCallback( SFG_Window* w, SFG_Enumerator* e)
{ {
if( w->State.Redisplay && w->State.Visible ) if( w->State.WorkMask )
{ {
e->found = GL_TRUE; e->found = GL_TRUE;
e->data = w; e->data = w;
return; return;
} }
fgEnumSubWindows( w, fghHavePendingRedisplaysCallback, e ); fgEnumSubWindows( w, fghHavePendingWorkCallback, e );
} }
static int fghHavePendingRedisplays (void) static int fghHavePendingWork (void)
{ {
SFG_Enumerator enumerator; SFG_Enumerator enumerator;
enumerator.found = GL_FALSE; enumerator.found = GL_FALSE;
enumerator.data = NULL; enumerator.data = NULL;
fgEnumWindows( fghHavePendingRedisplaysCallback, &enumerator ); fgEnumWindows( fghHavePendingWorkCallback, &enumerator );
return !!enumerator.data; return !!enumerator.data;
} }
@ -405,7 +377,7 @@ static void fghSleepForEvents( void )
{ {
fg_time_t msec; fg_time_t msec;
if( fghHavePendingRedisplays( ) ) if( fghHavePendingWork( ) )
return; return;
msec = fghNextTimer( ); msec = fghNextTimer( );
@ -433,12 +405,9 @@ void FGAPIENTRY glutMainLoopEvent( void )
if (fgState.NumActiveJoysticks>0) /* If zero, don't poll joysticks */ if (fgState.NumActiveJoysticks>0) /* If zero, don't poll joysticks */
fghCheckJoystickPolls( ); fghCheckJoystickPolls( );
/* Perform work on the window (position, reshape, etc) */ /* Perform work on the window (position, reshape, display, etc) */
fghProcessWork( ); fghProcessWork( );
/* Display */
fghDisplayAll( );
fgCloseWindows( ); fgCloseWindows( );
} }

View File

@ -207,7 +207,7 @@ static GLboolean fghCheckMenuStatus( SFG_Menu* menu )
if( menuEntry != menu->ActiveEntry ) if( menuEntry != menu->ActiveEntry )
{ {
menu->Window->State.Redisplay = GL_TRUE; menu->Window->State.WorkMask |= GLUT_DISPLAY_WORK;
if( menu->ActiveEntry ) if( menu->ActiveEntry )
menu->ActiveEntry->IsActive = GL_FALSE; menu->ActiveEntry->IsActive = GL_FALSE;
} }
@ -277,7 +277,7 @@ static GLboolean fghCheckMenuStatus( SFG_Menu* menu )
( !menu->ActiveEntry->SubMenu || ( !menu->ActiveEntry->SubMenu ||
!menu->ActiveEntry->SubMenu->IsActive ) ) !menu->ActiveEntry->SubMenu->IsActive ) )
{ {
menu->Window->State.Redisplay = GL_TRUE; menu->Window->State.WorkMask |= GLUT_DISPLAY_WORK;
menu->ActiveEntry->IsActive = GL_FALSE; menu->ActiveEntry->IsActive = GL_FALSE;
menu->ActiveEntry = NULL; menu->ActiveEntry = NULL;
} }

View File

@ -295,7 +295,7 @@ void FGAPIENTRY glutShowWindow( void )
fgStructure.CurrentWindow->State.WorkMask |= GLUT_VISIBILITY_WORK; fgStructure.CurrentWindow->State.WorkMask |= GLUT_VISIBILITY_WORK;
fgStructure.CurrentWindow->State.DesiredVisibility = DesireNormalState; fgStructure.CurrentWindow->State.DesiredVisibility = DesireNormalState;
fgStructure.CurrentWindow->State.Redisplay = GL_TRUE; fgStructure.CurrentWindow->State.WorkMask |= GLUT_DISPLAY_WORK;
} }
/* /*
@ -309,7 +309,7 @@ void FGAPIENTRY glutHideWindow( void )
fgStructure.CurrentWindow->State.WorkMask |= GLUT_VISIBILITY_WORK; fgStructure.CurrentWindow->State.WorkMask |= GLUT_VISIBILITY_WORK;
fgStructure.CurrentWindow->State.DesiredVisibility = DesireHiddenState; fgStructure.CurrentWindow->State.DesiredVisibility = DesireHiddenState;
fgStructure.CurrentWindow->State.Redisplay = GL_FALSE; fgStructure.CurrentWindow->State.WorkMask &= ~GLUT_DISPLAY_WORK;
} }
/* /*
@ -323,7 +323,7 @@ void FGAPIENTRY glutIconifyWindow( void )
fgStructure.CurrentWindow->State.WorkMask |= GLUT_VISIBILITY_WORK; fgStructure.CurrentWindow->State.WorkMask |= GLUT_VISIBILITY_WORK;
fgStructure.CurrentWindow->State.DesiredVisibility = DesireIconicState; fgStructure.CurrentWindow->State.DesiredVisibility = DesireIconicState;
fgStructure.CurrentWindow->State.Redisplay = GL_FALSE; fgStructure.CurrentWindow->State.WorkMask &= ~GLUT_DISPLAY_WORK;
} }
/* /*

View File

@ -893,9 +893,9 @@ LRESULT CALLBACK fgPlatformWindowProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPAR
* force redisplay so display keeps running during dragging. * force redisplay so display keeps running during dragging.
* Screen still wont update when not moving the cursor though... * Screen still wont update when not moving the cursor though...
*/ */
/* PRECT prect = (PRECT) lParam; */
RECT rect; RECT rect;
/* printf("WM_SIZING: nc-area: %i,%i\n",prect->right-prect->left,prect->bottom-prect->top); */ /* PRECT prect = (PRECT) lParam;
printf("WM_SIZING: nc-area: %i,%i\n",prect->right-prect->left,prect->bottom-prect->top); */
/* Get client area, the rect in lParam is including non-client area. */ /* Get client area, the rect in lParam is including non-client area. */
fghGetClientArea(&rect,window,FALSE); fghGetClientArea(&rect,window,FALSE);
@ -1066,12 +1066,12 @@ LRESULT CALLBACK fgPlatformWindowProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPAR
if (wParam) if (wParam)
{ {
fghPlatformOnWindowStatusNotify(window, GL_TRUE, GL_FALSE); fghPlatformOnWindowStatusNotify(window, GL_TRUE, GL_FALSE);
window->State.Redisplay = GL_TRUE; window->State.WorkMask |= GLUT_DISPLAY_WORK;
} }
else else
{ {
fghPlatformOnWindowStatusNotify(window, GL_FALSE, GL_FALSE); fghPlatformOnWindowStatusNotify(window, GL_FALSE, GL_FALSE);
window->State.Redisplay = GL_FALSE; window->State.WorkMask &= ~GLUT_DISPLAY_WORK;
} }
break; break;
@ -1092,7 +1092,7 @@ LRESULT CALLBACK fgPlatformWindowProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPAR
BeginPaint( hWnd, &ps ); BeginPaint( hWnd, &ps );
EndPaint( hWnd, &ps ); EndPaint( hWnd, &ps );
window->State.Redisplay = GL_TRUE; window->State.WorkMask |= GLUT_DISPLAY_WORK;
} }
lRet = 0; /* As per docs, should return 0 */ lRet = 0; /* As per docs, should return 0 */
} }
@ -1384,7 +1384,7 @@ LRESULT CALLBACK fgPlatformWindowProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPAR
#if !defined(_WIN32_WCE) #if !defined(_WIN32_WCE)
case WM_SYNCPAINT: /* 0x0088 */ case WM_SYNCPAINT: /* 0x0088 */
/* Another window has moved, need to update this one */ /* Another window has moved, need to update this one */
window->State.Redisplay = GL_TRUE; window->State.WorkMask |= GLUT_DISPLAY_WORK;
lRet = DefWindowProc( hWnd, uMsg, wParam, lParam ); lRet = DefWindowProc( hWnd, uMsg, wParam, lParam );
/* Help screen says this message must be passed to "DefWindowProc" */ /* Help screen says this message must be passed to "DefWindowProc" */
break; break;
@ -1548,6 +1548,8 @@ void fgPlatformProcessWork(SFG_Window *window)
/* Now clear it so that any callback generated by the actions below can set work again */ /* Now clear it so that any callback generated by the actions below can set work again */
window->State.WorkMask = 0; window->State.WorkMask = 0;
if (workMask&~GLUT_DISPLAY_WORK) /* Display work is the common case, skip all the below at once */
{
/* This is before the first display callback: call a few callbacks to inform user of window size, position, etc /* This is before the first display callback: call a few callbacks to inform user of window size, position, etc
* we know this is before the first display callback of a window as for all windows GLUT_INIT_WORK is set when * we know this is before the first display callback of a window as for all windows GLUT_INIT_WORK is set when
* they are opened, and work is done before displaying in the mainloop. * they are opened, and work is done before displaying in the mainloop.
@ -1776,4 +1778,14 @@ void fgPlatformProcessWork(SFG_Window *window)
ShowWindow( win->Window.Handle, cmdShow ); ShowWindow( win->Window.Handle, cmdShow );
} }
}
if (workMask & GLUT_DISPLAY_WORK)
{
if( window->State.Visible )
fghRedrawWindow ( window );
/* Strip out display work that might have ended up on work list now as some of the above genereates callbacks */
window->State.WorkMask &= ~GLUT_DISPLAY_WORK;
}
} }

View File

@ -698,7 +698,7 @@ void fgPlatformProcessSingleEvent ( void )
if( event.xexpose.count == 0 ) if( event.xexpose.count == 0 )
{ {
GETWINDOW( xexpose ); GETWINDOW( xexpose );
window->State.Redisplay = GL_TRUE; window->State.WorkMask |= GLUT_DISPLAY_WORK;
} }
break; break;
@ -1085,6 +1085,8 @@ void fgPlatformProcessWork(SFG_Window *window)
/* Now clear it so that any callback generated by the actions below can set work again */ /* Now clear it so that any callback generated by the actions below can set work again */
window->State.WorkMask = 0; window->State.WorkMask = 0;
if (workMask&~GLUT_DISPLAY_WORK) /* Display work is the common case, skip all the below at once */
{
/* This is before the first display callback: call a few callbacks to inform user of window size, position, etc /* This is before the first display callback: call a few callbacks to inform user of window size, position, etc
* we know this is before the first display callback of a window as for all windows GLUT_INIT_WORK is set when * we know this is before the first display callback of a window as for all windows GLUT_INIT_WORK is set when
* they are opened, and work is done before displaying in the mainloop. * they are opened, and work is done before displaying in the mainloop.
@ -1144,5 +1146,15 @@ void fgPlatformProcessWork(SFG_Window *window)
break; break;
} }
} }
}
if (workMask & GLUT_DISPLAY_WORK)
{
if( window->State.Visible )
fghRedrawWindow ( window );
/* Strip out display work that might have ended up on work list now as some of the above genereates callbacks */
window->State.WorkMask &= ~GLUT_DISPLAY_WORK;
}
} }