summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKeith Packard <keithp@keithp.com>2009-08-25 18:07:00 -0700
committerKeith Packard <keithp@keithp.com>2009-08-25 18:14:19 -0700
commite7dd1efef408effe52d0bd3d3aa0b5d4ee10ed90 (patch)
treedccb4b61e30cf7d454a3492a5ceeb391292ad1f9
parent1740cda7a37abc7d0a169ab4555b446adaa62211 (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.c22
-rw-r--r--hw/xfree86/modes/xf86Rotate.c2
-rw-r--r--include/dix.h6
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(