Accumulated cursor fixes from upstream repository. Should fix a cursor

corruption issues. Bump PKGREVISION.
This commit is contained in:
hasso 2009-06-11 07:00:31 +00:00
parent f4c13dcb21
commit 988ebf04a7
3 changed files with 364 additions and 3 deletions

View file

@ -1,8 +1,8 @@
# $NetBSD: Makefile,v 1.13 2009/06/07 11:24:37 wiz Exp $
# $NetBSD: Makefile,v 1.14 2009/06/11 07:00:31 hasso Exp $
#
DISTNAME= xf86-video-radeonhd-1.2.5
PKGREVISION= 1
PKGREVISION= 2
CATEGORIES= x11
MASTER_SITES= ${MASTER_SITE_XORG:=driver/}
EXTRACT_SUFX= .tar.bz2

View file

@ -1,5 +1,6 @@
$NetBSD: distinfo,v 1.9 2009/05/07 13:32:08 tnn Exp $
$NetBSD: distinfo,v 1.10 2009/06/11 07:00:31 hasso Exp $
SHA1 (xf86-video-radeonhd-1.2.5.tar.bz2) = 64fc0eb5209adba5479396bafe53b50ded6c0940
RMD160 (xf86-video-radeonhd-1.2.5.tar.bz2) = e30a896cd08e82b8a1bbc73e6f0ab862fe564a8a
Size (xf86-video-radeonhd-1.2.5.tar.bz2) = 751941 bytes
SHA1 (patch-aa) = de3176186b4780be2ae68b3eeb070f3262f0afcf

View file

@ -0,0 +1,360 @@
$NetBSD: patch-aa,v 1.7 2009/06/11 07:00:31 hasso Exp $
Accumulated cursor fixes from upstream repository. Should fix cursor
corruption issues:
http://cgit.freedesktop.org/xorg/driver/xf86-video-radeonhd/commit/?id=f668cc06
http://cgit.freedesktop.org/xorg/driver/xf86-video-radeonhd/commit/?id=6f378a0d
http://cgit.freedesktop.org/xorg/driver/xf86-video-radeonhd/commit/?id=669e0bef
http://cgit.freedesktop.org/xorg/driver/xf86-video-radeonhd/commit/?id=4be5f715
http://cgit.freedesktop.org/xorg/driver/xf86-video-radeonhd/commit/?id=dd287015
http://cgit.freedesktop.org/xorg/driver/xf86-video-radeonhd/commit/?id=08461642
http://cgit.freedesktop.org/xorg/driver/xf86-video-radeonhd/commit/?id=23d25fe7
--- src/rhd_cursor.c.oorig 2009-06-10 22:02:08 +0300
+++ src/rhd_cursor.c 2009-06-10 22:02:47 +0300
@@ -62,13 +62,16 @@
static void
lockCursor(struct rhdCursor *Cursor, Bool Lock)
{
- /* Double Buffering: Set _UPDATE_LOCK bit */
+ /* Locking disables double buffering of HW cursor registers.
+ * Set D*CURSOR_UPDATE_LOCK bit to 1 to lock.
+ * We want *_DISABLE_MULTIPLE_UPDATE to always be 0, and since all other
+ * meaningful bits are read-only for D*CUR_UPDATE registers, it is safe
+ * to use RHDRegWrite() instead of RHDRegMask(); the latter is slower.
+ */
if (Lock)
- RHDRegMask(Cursor, Cursor->RegOffset + D1CUR_UPDATE,
- 0x00010000, 0x00010000);
+ RHDRegWrite(Cursor, Cursor->RegOffset + D1CUR_UPDATE, 0x00010000);
else
- RHDRegMask(Cursor, Cursor->RegOffset + D1CUR_UPDATE,
- 0x00000000, 0x00010000);
+ RHDRegWrite(Cursor, Cursor->RegOffset + D1CUR_UPDATE, 0x00000000);
}
/* RadeonHD has hardware support for hotspots, but doesn't allow negative
@@ -89,13 +92,23 @@ setCursorPos(struct rhdCursor *Cursor, C
}
static void
+setCursorSize(struct rhdCursor *Cursor, CARD32 width, CARD32 height)
+{
+ ASSERT ((width > 0) && (width <= MAX_CURSOR_WIDTH));
+ ASSERT ((height > 0) && (height <= MAX_CURSOR_HEIGHT));
+ RHDRegWrite(Cursor, Cursor->RegOffset + D1CUR_SIZE,
+ (width - 1) << 16 | (height - 1));
+}
+
+static void
enableCursor(struct rhdCursor *Cursor, Bool Enable)
{
+ /* Make sure mode stays the same even when disabled; bug #13405 */
if (Enable)
/* pre-multiplied ARGB, Enable */
RHDRegWrite(Cursor, Cursor->RegOffset + D1CUR_CONTROL, 0x00000201);
else
- RHDRegWrite(Cursor, Cursor->RegOffset + D1CUR_CONTROL, 0);
+ RHDRegWrite(Cursor, Cursor->RegOffset + D1CUR_CONTROL, 0x00000200);
}
/* Activate already uploaded cursor image. */
@@ -106,10 +119,6 @@ setCursorImage(struct rhdCursor *Cursor)
RHDRegWrite(Cursor, Cursor->RegOffset + D1CUR_SURFACE_ADDRESS,
rhdPtr->FbIntAddress + Cursor->Base);
- ASSERT ((Cursor->Width > 0) && (Cursor->Width <= MAX_CURSOR_WIDTH));
- ASSERT ((Cursor->Height > 0) && (Cursor->Height <= MAX_CURSOR_HEIGHT));
- RHDRegWrite(Cursor, Cursor->RegOffset + D1CUR_SIZE,
- (Cursor->Width - 1) << 16 | (Cursor->Height - 1));
}
/* Upload image.
@@ -121,7 +130,7 @@ uploadCursorImage(struct rhdCursor *Curs
RHDPtr rhdPtr = RHDPTRI(Cursor);
memcpy(((CARD8 *) rhdPtr->FbBase + Cursor->Base), img,
- MAX_CURSOR_WIDTH * Cursor->Height * 4);
+ MAX_CURSOR_WIDTH * MAX_CURSOR_HEIGHT * 4);
}
static void
@@ -192,6 +201,8 @@ convertBitsToARGB(struct rhd_Cursor_Bits
CARD8 *mask = src + srcPitch * bits->height;
int x, y;
+ memset(dest, 0, MAX_CURSOR_WIDTH * MAX_CURSOR_HEIGHT * 4);
+
for (y = 0; y < bits->height; y++) {
CARD8 *s = src, *m = mask;
CARD32 *d = dest;
@@ -210,41 +221,24 @@ convertBitsToARGB(struct rhd_Cursor_Bits
}
}
-/* Enable/disable cursor according to visibility, and set cursor pos */
-static void
-displayCursor(struct rhdCrtc *Crtc)
+/*
+ * Returns if CRTC has a visible cursor
+ */
+static Bool
+hasVisibleCursor(struct rhdCrtc *Crtc)
{
struct rhdCursor *Cursor = Crtc->Cursor;
+ if (Cursor->X >= Crtc->X - MAX_CURSOR_WIDTH &&
+ Cursor->X < Crtc->X + Crtc->Width &&
+ Cursor->Y >= Crtc->Y - MAX_CURSOR_HEIGHT &&
+ Cursor->Y < Crtc->Y + Crtc->Height) {
- /* Hardware doesn't allow negative cursor pos. Use hardware
- * hotspot support for that. Cannot exceed width, but cursor is
- * not visible in this case. */
-
- /* xorg bug#13405: Cursor corruptions
- * With both CRTC enabled but HW cursor active only on one, the reported
- * corruption is seen. If HW cursor for both CRTC is forced to stay on, then no
- * corruption occurs. */
-#if 0
- if (Cursor->X >= Crtc->X - Cursor->Width &&
- Cursor->X < Crtc->X + Crtc->Width &&
- Cursor->Y >= Crtc->Y - Cursor->Height &&
- Cursor->Y < Crtc->Y + Crtc->Height) {
-#endif
- int X, Y, HotX, HotY;
-
- X = Cursor->X >= 0 ? Cursor->X : 0;
- Y = Cursor->Y >= 0 ? Cursor->Y : 0;
- HotX = Cursor->X >= 0 ? 0 : -Cursor->X;
- HotY = Cursor->Y >= 0 ? 0 : -Cursor->Y;
-
- enableCursor(Cursor, TRUE);
- setCursorPos(Cursor, X, Y, HotX, HotY);
-#if 0
+ return TRUE;
} else
- enableCursor(Cursor, FALSE);
-#endif
+ return FALSE;
}
+
/*
* Internal Driver + Xorg Interface
*/
@@ -258,12 +252,10 @@ rhdShowCursor(ScrnInfoPtr pScrn)
for (i = 0; i < 2; i++) {
struct rhdCrtc *Crtc = rhdPtr->Crtc[i];
- if (Crtc->Active && Crtc->scrnIndex == pScrn->scrnIndex) {
- struct rhdCursor *Cursor = Crtc->Cursor;
+ if (Crtc->Active && Crtc->scrnIndex == pScrn->scrnIndex
+ && hasVisibleCursor(Crtc)) {
- lockCursor (Cursor, TRUE);
- displayCursor(Crtc);
- lockCursor (Cursor, FALSE);
+ rhdCrtcShowCursor(Crtc);
}
}
}
@@ -278,11 +270,7 @@ rhdHideCursor(ScrnInfoPtr pScrn)
struct rhdCrtc *Crtc = rhdPtr->Crtc[i];
if (Crtc->Active && Crtc->scrnIndex == pScrn->scrnIndex) {
- struct rhdCursor *Cursor = Crtc->Cursor;
-
- lockCursor (Cursor, TRUE);
- enableCursor(Cursor, FALSE);
- lockCursor (Cursor, FALSE);
+ rhdCrtcHideCursor(Crtc);
}
}
}
@@ -339,14 +327,7 @@ rhdReloadCursor(ScrnInfoPtr pScrn)
struct rhdCrtc *Crtc = rhdPtr->Crtc[i];
if (Crtc->scrnIndex == pScrn->scrnIndex) {
- struct rhdCursor *Cursor = Crtc->Cursor;
-
- lockCursor (Cursor, TRUE);
- uploadCursorImage(Cursor, rhdPtr->CursorImage);
- setCursorImage (Cursor);
- if (Crtc->Active)
- displayCursor(Crtc);
- lockCursor (Cursor, FALSE);
+ rhdCrtcLoadCursorARGB(Crtc, rhdPtr->CursorImage);
}
}
}
@@ -363,16 +344,11 @@ rhdSetCursorPosition(ScrnInfoPtr pScrn,
for (i = 0; i < 2; i++) {
struct rhdCrtc *Crtc = rhdPtr->Crtc[i];
- if (Crtc->Active && Crtc->scrnIndex == pScrn->scrnIndex) {
- struct rhdCursor *Cursor = Crtc->Cursor;
+ if (Crtc->Active && Crtc->scrnIndex == pScrn->scrnIndex
+ && hasVisibleCursor(Crtc)) {
/* Given cursor pos is always relative to frame - make absolute */
- Cursor->X = x + pScrn->frameX0;
- Cursor->Y = y + pScrn->frameY0;
-
- lockCursor (Cursor, TRUE);
- displayCursor(Crtc);
- lockCursor (Cursor, FALSE);
+ rhdCrtcSetCursorPosition(Crtc, x+pScrn->frameX0, y+pScrn->frameY0);
}
}
}
@@ -397,12 +373,7 @@ rhdSetCursorColors(ScrnInfoPtr pScrn, in
struct rhdCrtc *Crtc = rhdPtr->Crtc[i];
if (Crtc->scrnIndex == pScrn->scrnIndex) {
- struct rhdCursor *Cursor = Crtc->Cursor;
-
- lockCursor (Cursor, TRUE);
- uploadCursorImage(Cursor, rhdPtr->CursorImage);
- setCursorImage (Cursor);
- lockCursor (Cursor, FALSE);
+ rhdCrtcLoadCursorARGB(Crtc, rhdPtr->CursorImage);
}
}
}
@@ -422,15 +393,7 @@ rhdLoadCursorImage(ScrnInfoPtr pScrn, un
struct rhdCrtc *Crtc = rhdPtr->Crtc[i];
if (Crtc->scrnIndex == pScrn->scrnIndex) {
- struct rhdCursor *Cursor = Crtc->Cursor;
-
- Cursor->Width = bits->width;
- Cursor->Height = bits->height;
-
- lockCursor (Cursor, TRUE);
- uploadCursorImage(Cursor, rhdPtr->CursorImage);
- setCursorImage (Cursor);
- lockCursor (Cursor, FALSE);
+ rhdCrtcLoadCursorARGB(Crtc, rhdPtr->CursorImage);
}
}
}
@@ -455,24 +418,19 @@ rhdLoadCursorARGB(ScrnInfoPtr pScrn, Cur
rhdPtr->CursorBits = NULL;
/* Hardware only supports 64-wide cursor images. */
- for (i = 0; i < cur->bits->height; i++)
- memcpy(rhdPtr->CursorImage + MAX_CURSOR_WIDTH*i,
+ memset(rhdPtr->CursorImage, 0, MAX_CURSOR_WIDTH * MAX_CURSOR_HEIGHT * 4);
+ for (i = 0; i < cur->bits->height; i++) {
+ CARD32 *img = rhdPtr->CursorImage + MAX_CURSOR_WIDTH*i;
+ memcpy(img,
cur->bits->argb + cur->bits->width*i,
cur->bits->width*4);
+ }
for (i = 0; i < 2; i++) {
struct rhdCrtc *Crtc = rhdPtr->Crtc[i];
if (Crtc->scrnIndex == pScrn->scrnIndex) {
- struct rhdCursor *Cursor = Crtc->Cursor;
-
- Cursor->Width = cur->bits->width;
- Cursor->Height = cur->bits->height;
-
- lockCursor (Cursor, TRUE);
- uploadCursorImage(Cursor, rhdPtr->CursorImage);
- setCursorImage (Cursor);
- lockCursor (Cursor, FALSE);
+ rhdCrtcLoadCursorARGB(Crtc, rhdPtr->CursorImage);
}
}
}
@@ -588,10 +546,9 @@ void
rhdCrtcShowCursor(struct rhdCrtc *Crtc)
{
struct rhdCursor *Cursor = Crtc->Cursor;
-
- lockCursor (Cursor, TRUE);
- displayCursor(Crtc);
- lockCursor (Cursor, FALSE);
+ lockCursor (Cursor, TRUE);
+ enableCursor(Cursor, TRUE);
+ lockCursor (Cursor, FALSE);
}
/*
@@ -613,12 +570,58 @@ rhdCrtcHideCursor(struct rhdCrtc *Crtc)
void
rhdCrtcSetCursorPosition(struct rhdCrtc *Crtc, int x, int y)
{
+ RHDPtr rhdPtr = RHDPTRI(Crtc);
struct rhdCursor *Cursor = Crtc->Cursor;
+ int hotx, hoty, width, cursor_end, frame_end;
+
Cursor->X = x;
Cursor->Y = y;
+ hotx = 0;
+ hoty = 0;
+
+ /* Hardware doesn't allow negative cursor pos; compensate using hotspot */
+ if (x < 0) {
+ hotx = -x;
+ x = 0;
+ }
+ if (y < 0) {
+ hoty = -y;
+ y = 0;
+ }
+
lockCursor (Cursor, TRUE);
- displayCursor(Crtc);
+
+ /* Work around rare corruption cases by adjusting cursor size;
+ * related to bug #13405
+ * For dual-screen:
+ * - Cursor's right-edge must not end on multiples of 128px.
+ * - For panning, cursor image cannot horizontally extend past end of viewport.
+ */
+ if (rhdPtr->Crtc[0]->Active && rhdPtr->Crtc[1]->Active) {
+ width = MAX_CURSOR_WIDTH;
+ cursor_end = x + width;
+ frame_end = Crtc->X + Crtc->Width;
+
+ if (cursor_end > frame_end) {
+ width -= cursor_end - frame_end;
+ cursor_end = x + width;
+ }
+ if (! (cursor_end & 0x7f)) {
+ width--;
+ }
+ /* If the cursor is effectively invisible, move it out of visible area */
+ if (width <= 0) {
+ width = 1;
+ x = 0;
+ y = Crtc->Y + Crtc->Height;
+ hotx = 0;
+ hoty = 0;
+ }
+ setCursorSize(Cursor, width, MAX_CURSOR_HEIGHT);
+ }
+
+ setCursorPos (Cursor, x, y, hotx, hoty);
lockCursor (Cursor, FALSE);
}
@@ -642,12 +645,10 @@ rhdCrtcLoadCursorARGB(struct rhdCrtc *Cr
{
struct rhdCursor *Cursor = Crtc->Cursor;
- Cursor->Width = MAX_CURSOR_WIDTH;
- Cursor->Height = MAX_CURSOR_HEIGHT;
-
lockCursor (Cursor, TRUE);
uploadCursorImage(Cursor, Image);
setCursorImage (Cursor);
+ setCursorSize (Cursor, MAX_CURSOR_WIDTH, MAX_CURSOR_HEIGHT);
lockCursor (Cursor, FALSE);
}