Ensure that rotation updates happen frequently

The smart scheduler is designed to minimize scheduler overhead by
increasing the interval between WaitForSomething calls when a single
client is running. However, the software rotation code depends on
its BlockHandler being invoked for screen updates; the long delays
caused by the smart scheduler optimizations means that screen updates
can be delayed a long time as well.

The change is simple -- prevent the smart scheduler from increasing
the scheduling interval while any screen is using software rotation.

Signed-off-by: Keith Packard <keithp@keithp.com>
This commit is contained in:
Keith Packard 2009-08-25 18:07:00 -07:00
parent 1740cda7a3
commit e7dd1efef4
3 changed files with 29 additions and 1 deletions

View File

@ -242,6 +242,7 @@ long SmartScheduleSlice = SMART_SCHEDULE_DEFAULT_INTERVAL;
long SmartScheduleInterval = SMART_SCHEDULE_DEFAULT_INTERVAL; long SmartScheduleInterval = SMART_SCHEDULE_DEFAULT_INTERVAL;
long SmartScheduleMaxSlice = SMART_SCHEDULE_MAX_SLICE; long SmartScheduleMaxSlice = SMART_SCHEDULE_MAX_SLICE;
long SmartScheduleTime; long SmartScheduleTime;
int SmartScheduleLatencyLimited = 0;
static ClientPtr SmartLastClient; static ClientPtr SmartLastClient;
static int SmartLastIndex[SMART_MAX_PRIORITY-SMART_MIN_PRIORITY+1]; static int SmartLastIndex[SMART_MAX_PRIORITY-SMART_MIN_PRIORITY+1];
@ -312,7 +313,7 @@ SmartScheduleClient (int *clientReady, int nready)
/* /*
* Adjust slice * Adjust slice
*/ */
if (nready == 1) if (nready == 1 && SmartScheduleLatencyLimited == 0)
{ {
/* /*
* If it's been a long time since another client * If it's been a long time since another client
@ -332,6 +333,23 @@ SmartScheduleClient (int *clientReady, int nready)
return best; return best;
} }
void
EnableLimitedSchedulingLatency(void)
{
++SmartScheduleLatencyLimited;
SmartScheduleSlice = SmartScheduleInterval;
}
void
DisableLimitedSchedulingLatency(void)
{
--SmartScheduleLatencyLimited;
/* protect against bugs */
if (SmartScheduleLatencyLimited < 0)
SmartScheduleLatencyLimited = 0;
}
#define MAJOROP ((xReq *)client->requestBuffer)->reqType #define MAJOROP ((xReq *)client->requestBuffer)->reqType
void void
@ -351,6 +369,7 @@ Dispatch(void)
if (!clientReady) if (!clientReady)
return; return;
SmartScheduleSlice = SmartScheduleInterval;
while (!dispatchException) while (!dispatchException)
{ {
if (*icheck[0] != *icheck[1]) if (*icheck[0] != *icheck[1])
@ -455,6 +474,7 @@ Dispatch(void)
KillAllClients(); KillAllClients();
xfree(clientReady); xfree(clientReady);
dispatchException &= ~DE_RESET; dispatchException &= ~DE_RESET;
SmartScheduleLatencyLimited = 0;
} }
#undef MAJOROP #undef MAJOROP

View File

@ -228,6 +228,7 @@ xf86RotatePrepare (ScreenPtr pScreen)
DamageRegister (&(*pScreen->GetScreenPixmap)(pScreen)->drawable, DamageRegister (&(*pScreen->GetScreenPixmap)(pScreen)->drawable,
xf86_config->rotation_damage); xf86_config->rotation_damage);
xf86_config->rotation_damage_registered = TRUE; xf86_config->rotation_damage_registered = TRUE;
EnableLimitedSchedulingLatency();
} }
xf86CrtcDamageShadow (crtc); xf86CrtcDamageShadow (crtc);
@ -338,6 +339,7 @@ xf86RotateDestroy (xf86CrtcPtr crtc)
DamageUnregister (&(*pScreen->GetScreenPixmap)(pScreen)->drawable, DamageUnregister (&(*pScreen->GetScreenPixmap)(pScreen)->drawable,
xf86_config->rotation_damage); xf86_config->rotation_damage);
xf86_config->rotation_damage_registered = FALSE; xf86_config->rotation_damage_registered = FALSE;
DisableLimitedSchedulingLatency();
} }
DamageDestroy (xf86_config->rotation_damage); DamageDestroy (xf86_config->rotation_damage);
xf86_config->rotation_damage = NULL; xf86_config->rotation_damage = NULL;

View File

@ -229,6 +229,12 @@ extern _X_EXPORT void WakeupHandler(
int /*result*/, int /*result*/,
pointer /*pReadmask*/); pointer /*pReadmask*/);
void
EnableLimitedSchedulingLatency(void);
void
DisableLimitedSchedulingLatency(void);
typedef void (* WakeupHandlerProcPtr)( typedef void (* WakeupHandlerProcPtr)(
pointer /* blockData */, pointer /* blockData */,
int /* result */, int /* result */,