diff options
author | Keith Packard <keithp@keithp.com> | 2009-08-25 18:07:00 -0700 |
---|---|---|
committer | Keith Packard <keithp@keithp.com> | 2009-08-25 18:14:19 -0700 |
commit | e7dd1efef408effe52d0bd3d3aa0b5d4ee10ed90 (patch) | |
tree | dccb4b61e30cf7d454a3492a5ceeb391292ad1f9 | |
parent | 1740cda7a37abc7d0a169ab4555b446adaa62211 (diff) |
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>
-rw-r--r-- | dix/dispatch.c | 22 | ||||
-rw-r--r-- | hw/xfree86/modes/xf86Rotate.c | 2 | ||||
-rw-r--r-- | include/dix.h | 6 |
3 files changed, 29 insertions, 1 deletions
diff --git a/dix/dispatch.c b/dix/dispatch.c index 31c69612b..414bd0404 100644 --- a/dix/dispatch.c +++ b/dix/dispatch.c @@ -239,12 +239,13 @@ UpdateCurrentTimeIf(void) Bool SmartScheduleDisable = FALSE; long SmartScheduleSlice = SMART_SCHEDULE_DEFAULT_INTERVAL; long SmartScheduleInterval = SMART_SCHEDULE_DEFAULT_INTERVAL; long SmartScheduleMaxSlice = SMART_SCHEDULE_MAX_SLICE; long SmartScheduleTime; +int SmartScheduleLatencyLimited = 0; static ClientPtr SmartLastClient; static int SmartLastIndex[SMART_MAX_PRIORITY-SMART_MIN_PRIORITY+1]; #ifdef SMART_DEBUG long SmartLastPrint; #endif @@ -309,13 +310,13 @@ SmartScheduleClient (int *clientReady, int nready) pClient->smart_start_tick = now; SmartLastClient = pClient; } /* * Adjust slice */ - if (nready == 1) + if (nready == 1 && SmartScheduleLatencyLimited == 0) { /* * If it's been a long time since another client * has run, bump the slice up to get maximal * performance from a single client */ @@ -329,12 +330,29 @@ SmartScheduleClient (int *clientReady, int nready) { SmartScheduleSlice = SmartScheduleInterval; } 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 void Dispatch(void) { int *clientReady; /* array of request ready clients */ @@ -348,12 +366,13 @@ Dispatch(void) nClients = 0; clientReady = xalloc(sizeof(int) * MaxClients); if (!clientReady) return; + SmartScheduleSlice = SmartScheduleInterval; while (!dispatchException) { if (*icheck[0] != *icheck[1]) { ProcessInputEvents(); FlushIfCriticalOutputPending(); @@ -452,12 +471,13 @@ Dispatch(void) #if defined(DDXBEFORERESET) ddxBeforeReset (); #endif KillAllClients(); xfree(clientReady); dispatchException &= ~DE_RESET; + SmartScheduleLatencyLimited = 0; } #undef MAJOROP static int VendorRelease = VENDOR_RELEASE; static char *VendorString = VENDOR_NAME; diff --git a/hw/xfree86/modes/xf86Rotate.c b/hw/xfree86/modes/xf86Rotate.c index e0ea274a2..d9face1cb 100644 --- a/hw/xfree86/modes/xf86Rotate.c +++ b/hw/xfree86/modes/xf86Rotate.c @@ -225,12 +225,13 @@ xf86RotatePrepare (ScreenPtr pScreen) if (!xf86_config->rotation_damage_registered) { /* Hook damage to screen pixmap */ DamageRegister (&(*pScreen->GetScreenPixmap)(pScreen)->drawable, xf86_config->rotation_damage); xf86_config->rotation_damage_registered = TRUE; + EnableLimitedSchedulingLatency(); } xf86CrtcDamageShadow (crtc); } } } @@ -335,12 +336,13 @@ xf86RotateDestroy (xf86CrtcPtr crtc) /* Free damage structure */ if (xf86_config->rotation_damage_registered) { DamageUnregister (&(*pScreen->GetScreenPixmap)(pScreen)->drawable, xf86_config->rotation_damage); xf86_config->rotation_damage_registered = FALSE; + DisableLimitedSchedulingLatency(); } DamageDestroy (xf86_config->rotation_damage); xf86_config->rotation_damage = NULL; } } diff --git a/include/dix.h b/include/dix.h index e2db6b655..49dfe3774 100644 --- a/include/dix.h +++ b/include/dix.h @@ -226,12 +226,18 @@ extern _X_EXPORT void BlockHandler( pointer /*pReadmask*/); extern _X_EXPORT void WakeupHandler( int /*result*/, pointer /*pReadmask*/); +void +EnableLimitedSchedulingLatency(void); + +void +DisableLimitedSchedulingLatency(void); + typedef void (* WakeupHandlerProcPtr)( pointer /* blockData */, int /* result */, pointer /* pReadmask */); extern _X_EXPORT Bool RegisterBlockAndWakeupHandlers( |