Don't wedge when rotating more than one CRTC.

Rotation block handler was re-registering the rotation damage structure,
creating an infinite loop in the damage code. Track registration of the
damage structure to avoid this.
(cherry picked from commit b14f003b0e)
This commit is contained in:
Keith Packard 2007-03-15 16:16:16 -07:00
parent 9562b6abe1
commit 3bffb28126
2 changed files with 20 additions and 14 deletions

View File

@ -529,7 +529,8 @@ typedef struct _xf86CrtcConfig {
int maxWidth, maxHeight; int maxWidth, maxHeight;
/* For crtc-based rotation */ /* For crtc-based rotation */
DamagePtr rotationDamage; DamagePtr rotation_damage;
Bool rotation_damage_registered;
/* DGA */ /* DGA */
unsigned int dga_flags; unsigned int dga_flags;

View File

@ -251,9 +251,13 @@ xf86RotatePrepare (ScreenPtr pScreen)
crtc->rotatedData, crtc->rotatedData,
crtc->mode.HDisplay, crtc->mode.HDisplay,
crtc->mode.VDisplay); crtc->mode.VDisplay);
if (!xf86_config->rotation_damage_registered)
{
/* Hook damage to screen pixmap */ /* Hook damage to screen pixmap */
DamageRegister (&(*pScreen->GetScreenPixmap)(pScreen)->drawable, DamageRegister (&(*pScreen->GetScreenPixmap)(pScreen)->drawable,
xf86_config->rotationDamage); xf86_config->rotation_damage);
xf86_config->rotation_damage_registered = TRUE;
}
xf86CrtcDamageShadow (crtc); xf86CrtcDamageShadow (crtc);
} }
@ -265,7 +269,7 @@ xf86RotateRedisplay(ScreenPtr pScreen)
{ {
ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn); xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
DamagePtr damage = xf86_config->rotationDamage; DamagePtr damage = xf86_config->rotation_damage;
RegionPtr region; RegionPtr region;
if (!damage) if (!damage)
@ -334,13 +338,14 @@ xf86CrtcRotate (xf86CrtcPtr crtc, DisplayModePtr mode, Rotation rotation)
crtc->rotatedData = NULL; crtc->rotatedData = NULL;
} }
if (xf86_config->rotationDamage) if (xf86_config->rotation_damage)
{ {
/* Free damage structure */ /* Free damage structure */
DamageUnregister (&(*pScreen->GetScreenPixmap)(pScreen)->drawable, DamageUnregister (&(*pScreen->GetScreenPixmap)(pScreen)->drawable,
xf86_config->rotationDamage); xf86_config->rotation_damage);
DamageDestroy (xf86_config->rotationDamage); xf86_config->rotation_damage_registered = FALSE;
xf86_config->rotationDamage = NULL; DamageDestroy (xf86_config->rotation_damage);
xf86_config->rotation_damage = NULL;
/* Free block/wakeup handler */ /* Free block/wakeup handler */
RemoveBlockAndWakeupHandlers (xf86RotateBlockHandler, RemoveBlockAndWakeupHandlers (xf86RotateBlockHandler,
xf86RotateWakeupHandler, xf86RotateWakeupHandler,
@ -382,13 +387,13 @@ xf86CrtcRotate (xf86CrtcPtr crtc, DisplayModePtr mode, Rotation rotation)
xf86CrtcDamageShadow (crtc); xf86CrtcDamageShadow (crtc);
} }
if (!xf86_config->rotationDamage) if (!xf86_config->rotation_damage)
{ {
/* Create damage structure */ /* Create damage structure */
xf86_config->rotationDamage = DamageCreate (NULL, NULL, xf86_config->rotation_damage = DamageCreate (NULL, NULL,
DamageReportNone, DamageReportNone,
TRUE, pScreen, pScreen); TRUE, pScreen, pScreen);
if (!xf86_config->rotationDamage) if (!xf86_config->rotation_damage)
goto bail2; goto bail2;
/* Assign block/wakeup handler */ /* Assign block/wakeup handler */
@ -402,8 +407,8 @@ xf86CrtcRotate (xf86CrtcPtr crtc, DisplayModePtr mode, Rotation rotation)
if (0) if (0)
{ {
bail3: bail3:
DamageDestroy (xf86_config->rotationDamage); DamageDestroy (xf86_config->rotation_damage);
xf86_config->rotationDamage = NULL; xf86_config->rotation_damage = NULL;
bail2: bail2:
if (shadow || shadowData) if (shadow || shadowData)