Use Screen block handler for rotation to draw under DRI lock.

DRI uses a non-screen block/wakeup handler which will be executed after the
screen block handler finishes. To ensure that the rotation block handler is
executed under the DRI lock, dynamically wrap the screen block handler for
rotation.
This commit is contained in:
Keith Packard 2007-05-17 20:24:18 -07:00
parent 915563eba5
commit 076d070e18
2 changed files with 23 additions and 25 deletions

View File

@ -562,6 +562,10 @@ typedef struct _xf86CrtcConfig {
OptionInfoPtr options; OptionInfoPtr options;
Bool debug_modes; Bool debug_modes;
/* wrap screen BlockHandler for rotation */
ScreenBlockHandlerProcPtr BlockHandler;
} xf86CrtcConfigRec, *xf86CrtcConfigPtr; } xf86CrtcConfigRec, *xf86CrtcConfigPtr;
extern int xf86CrtcConfigPrivateIndex; extern int xf86CrtcConfigPrivateIndex;

View File

@ -264,7 +264,7 @@ xf86RotatePrepare (ScreenPtr pScreen)
} }
} }
static void static Bool
xf86RotateRedisplay(ScreenPtr pScreen) xf86RotateRedisplay(ScreenPtr pScreen)
{ {
ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
@ -273,7 +273,7 @@ xf86RotateRedisplay(ScreenPtr pScreen)
RegionPtr region; RegionPtr region;
if (!damage) if (!damage)
return; return FALSE;
xf86RotatePrepare (pScreen); xf86RotatePrepare (pScreen);
region = DamageRegion(damage); region = DamageRegion(damage);
if (REGION_NOTEMPTY(pScreen, region)) if (REGION_NOTEMPTY(pScreen, region))
@ -317,19 +317,25 @@ xf86RotateRedisplay(ScreenPtr pScreen)
pScreen->SourceValidate = SourceValidate; pScreen->SourceValidate = SourceValidate;
DamageEmpty(damage); DamageEmpty(damage);
} }
return TRUE;
} }
static void static void
xf86RotateBlockHandler(pointer data, OSTimePtr pTimeout, pointer pRead) xf86RotateBlockHandler(int screenNum, pointer blockData,
pointer pTimeout, pointer pReadmask)
{ {
ScreenPtr pScreen = (ScreenPtr) data; ScreenPtr pScreen = screenInfo.screens[screenNum];
ScrnInfoPtr pScrn = xf86Screens[screenNum];
xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
xf86RotateRedisplay(pScreen); pScreen->BlockHandler = xf86_config->BlockHandler;
} (*pScreen->BlockHandler) (screenNum, blockData, pTimeout, pReadmask);
if (xf86RotateRedisplay(pScreen))
static void {
xf86RotateWakeupHandler(pointer data, int i, pointer LastSelectMask) /* Re-wrap if rotation is still happening */
{ xf86_config->BlockHandler = pScreen->BlockHandler;
pScreen->BlockHandler = xf86RotateBlockHandler;
}
} }
static void static void
@ -367,10 +373,6 @@ xf86RotateDestroy (xf86CrtcPtr crtc)
} }
DamageDestroy (xf86_config->rotation_damage); DamageDestroy (xf86_config->rotation_damage);
xf86_config->rotation_damage = NULL; xf86_config->rotation_damage = NULL;
/* Free block/wakeup handler */
RemoveBlockAndWakeupHandlers (xf86RotateBlockHandler,
xf86RotateWakeupHandler,
(pointer) pScreen);
} }
} }
@ -440,20 +442,12 @@ xf86CrtcRotate (xf86CrtcPtr crtc, DisplayModePtr mode, Rotation rotation)
if (!xf86_config->rotation_damage) if (!xf86_config->rotation_damage)
goto bail2; goto bail2;
/* Assign block/wakeup handler */ /* Wrap block handler */
if (!RegisterBlockAndWakeupHandlers (xf86RotateBlockHandler, xf86_config->BlockHandler = pScreen->BlockHandler;
xf86RotateWakeupHandler, pScreen->BlockHandler = xf86RotateBlockHandler;
(pointer) pScreen))
{
goto bail3;
}
} }
if (0) if (0)
{ {
bail3:
DamageDestroy (xf86_config->rotation_damage);
xf86_config->rotation_damage = NULL;
bail2: bail2:
if (shadow || shadowData) if (shadow || shadowData)
{ {