The driver is at liberty to modify the Screen Pixmap, for example if it creates a new ordinary Pixmap for use as a shadow scanout buffer, and so the cached registration of the damage may become stale and lead to an eventual crash.
Signed-off-by: Chris Wilson <[email protected]> --- hw/xfree86/modes/xf86Crtc.h | 2 +- hw/xfree86/modes/xf86Rotate.c | 43 +++++++++++++++++++++++++--------------- 2 files changed, 28 insertions(+), 17 deletions(-) diff --git a/hw/xfree86/modes/xf86Crtc.h b/hw/xfree86/modes/xf86Crtc.h index 68a968c..db94e98 100644 --- a/hw/xfree86/modes/xf86Crtc.h +++ b/hw/xfree86/modes/xf86Crtc.h @@ -647,7 +647,7 @@ typedef struct _xf86CrtcConfig { /* For crtc-based rotation */ DamagePtr rotation_damage; - Bool rotation_damage_registered; + DrawablePtr rotation_damage_registered; /* DGA */ unsigned int dga_flags; diff --git a/hw/xfree86/modes/xf86Rotate.c b/hw/xfree86/modes/xf86Rotate.c index c378391..da8a8f4 100644 --- a/hw/xfree86/modes/xf86Rotate.c +++ b/hw/xfree86/modes/xf86Rotate.c @@ -194,9 +194,10 @@ xf86RotatePrepare (ScreenPtr pScreen) if (!xf86_config->rotation_damage_registered) { /* Hook damage to screen pixmap */ - DamageRegister (&(*pScreen->GetScreenPixmap)(pScreen)->drawable, + xf86_config->rotation_damage_registered = + &(*pScreen->GetScreenPixmap)(pScreen)->drawable; + DamageRegister (xf86_config->rotation_damage_registered, xf86_config->rotation_damage); - xf86_config->rotation_damage_registered = TRUE; EnableLimitedSchedulingLatency(); } @@ -304,9 +305,9 @@ xf86RotateDestroy (xf86CrtcPtr crtc) /* Free damage structure */ if (xf86_config->rotation_damage_registered) { - DamageUnregister (&(*pScreen->GetScreenPixmap)(pScreen)->drawable, + DamageUnregister (xf86_config->rotation_damage_registered, xf86_config->rotation_damage); - xf86_config->rotation_damage_registered = FALSE; + xf86_config->rotation_damage_registered = NULL; DisableLimitedSchedulingLatency(); } DamageDestroy (xf86_config->rotation_damage); @@ -450,20 +451,30 @@ xf86CrtcRotate (xf86CrtcPtr crtc) damage = TRUE; } - if (!xf86_config->rotation_damage) + if (xf86_config->rotation_damage) { - /* Create damage structure */ - xf86_config->rotation_damage = DamageCreate (NULL, NULL, - DamageReportNone, - TRUE, pScreen, pScreen); - if (!xf86_config->rotation_damage) - goto bail2; - - /* Wrap block handler */ - if (!xf86_config->BlockHandler) { - xf86_config->BlockHandler = pScreen->BlockHandler; - pScreen->BlockHandler = xf86RotateBlockHandler; + /* Free damage structure */ + if (xf86_config->rotation_damage_registered) + { + DamageUnregister (xf86_config->rotation_damage_registered, + xf86_config->rotation_damage); + xf86_config->rotation_damage_registered = NULL; + DisableLimitedSchedulingLatency(); } + DamageDestroy (xf86_config->rotation_damage); + } + + /* Create damage structure */ + xf86_config->rotation_damage = DamageCreate (NULL, NULL, + DamageReportNone, + TRUE, pScreen, pScreen); + if (!xf86_config->rotation_damage) + goto bail2; + + /* Wrap block handler */ + if (!xf86_config->BlockHandler) { + xf86_config->BlockHandler = pScreen->BlockHandler; + pScreen->BlockHandler = xf86RotateBlockHandler; } #ifdef RANDR_12_INTERFACE if (transform) -- 1.7.5.4 _______________________________________________ [email protected]: X.Org development Archives: http://lists.x.org/archives/xorg-devel Info: http://lists.x.org/mailman/listinfo/xorg-devel
