---
src/drmmode_display.c | 29 +++++++++++++++++--
src/nouveau_hw.h | 17 +++++++++++
src/nv_cursor.c | 74 ++++++++++++++++++++++++------------------------
src/nv_proto.h | 2 +
4 files changed, 82 insertions(+), 40 deletions(-)
diff --git a/src/drmmode_display.c b/src/drmmode_display.c
index f2fe0e8..7acddf1 100644
--- a/src/drmmode_display.c
+++ b/src/drmmode_display.c
@@ -333,7 +333,14 @@ done:
static void
drmmode_set_cursor_colors (xf86CrtcPtr crtc, int bg, int fg)
{
+ NVPtr pNv = NVPTR(crtc->scrn);
+ drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
+ struct nouveau_bo *bo = drmmode_crtc->cursor;
+ nouveau_bo_map(bo, NOUVEAU_BO_WR);
+ nv_cursor_convert_cursor(pNv->curImage, bo->map, nv_cursor_width(pNv),
+ 64, 32, fg | (0xff << 24), bg | (0xff << 24));
+ nouveau_bo_unmap(bo);
}
static void
@@ -346,6 +353,24 @@ drmmode_set_cursor_position (xf86CrtcPtr crtc, int x, int
y)
}
static void
+drmmode_load_cursor_image (xf86CrtcPtr crtc, CARD8 *image)
+{
+ NVPtr pNv = NVPTR(crtc->scrn);
+ xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(crtc->scrn);
+ drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
+ struct nouveau_bo *bo = drmmode_crtc->cursor;
+
+ /* save copy of image for colour changes */
+ memcpy(pNv->curImage, image, nv_cursor_pixels(pNv)/4);
+
+ nouveau_bo_map(bo, NOUVEAU_BO_WR);
+ nv_cursor_convert_cursor(pNv->curImage, bo->map, nv_cursor_width(pNv),
+ 64, 32, config->cursor_fg | (0xff << 24),
+ config->cursor_bg | (0xff << 24));
+ nouveau_bo_unmap(bo);
+}
+
+static void
drmmode_load_cursor_argb (xf86CrtcPtr crtc, CARD32 *image)
{
drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
@@ -505,14 +530,12 @@ static const xf86CrtcFuncsRec drmmode_crtc_funcs = {
.set_cursor_position = drmmode_set_cursor_position,
.show_cursor = drmmode_show_cursor,
.hide_cursor = drmmode_hide_cursor,
+ .load_cursor_image = drmmode_load_cursor_image,
.load_cursor_argb = drmmode_load_cursor_argb,
.shadow_create = drmmode_crtc_shadow_create,
.shadow_allocate = drmmode_crtc_shadow_allocate,
.shadow_destroy = drmmode_crtc_shadow_destroy,
.gamma_set = drmmode_gamma_set,
-#if 0
- .set_cursor_colors = drmmode_crtc_set_cursor_colors,
-#endif
.destroy = NULL, /* XXX */
};
diff --git a/src/nouveau_hw.h b/src/nouveau_hw.h
index a548a4c..aa2a3b4 100644
--- a/src/nouveau_hw.h
+++ b/src/nouveau_hw.h
@@ -287,6 +287,23 @@ static inline bool NVLockVgaCrtcs(NVPtr pNv, bool lock)
return waslocked;
}
+/* nv04 cursor max dimensions of 32x32 (A1R5G5B5) */
+#define NV04_CURSOR_SIZE 32
+/* limit nv10 cursors to 64x64 (ARGB8) (we could go to 64x255) */
+#define NV10_CURSOR_SIZE 64
+
+static inline int nv_cursor_width(NVPtr pNv)
+{
+ return pNv->NVArch >= 0x10 ? NV10_CURSOR_SIZE : NV04_CURSOR_SIZE;
+}
+
+static inline int nv_cursor_pixels(NVPtr pNv)
+{
+ int width = nv_cursor_width(pNv);
+
+ return width * width;
+}
+
static inline void nv_fix_nv40_hw_cursor(NVPtr pNv, int head)
{
/* on some nv40 (such as the "true" (in the NV_PFB_BOOT_0 sense)
nv40,
diff --git a/src/nv_cursor.c b/src/nv_cursor.c
index 22db9e6..b9320c5 100644
--- a/src/nv_cursor.c
+++ b/src/nv_cursor.c
@@ -30,44 +30,43 @@
((c & 0xf8) >> 3 )) /* Blue */
#define TO_ARGB8888(c) (0xff000000 | c)
-/* nv04 cursor max dimensions of 32x32 (A1R5G5B5) */
-#define NV04_CURSOR_SIZE 32
-#define NV04_CURSOR_PIXELS (NV04_CURSOR_SIZE * NV04_CURSOR_SIZE)
-
-/* limit nv10 cursors to 64x64 (ARGB8) (we could go to 64x255) */
-#define NV10_CURSOR_SIZE 64
-#define NV10_CURSOR_PIXELS (NV10_CURSOR_SIZE * NV10_CURSOR_SIZE)
-
#define SOURCE_MASK_INTERLEAVE 32
#define TRANSPARENT_PIXEL 0
-static void
-nv_cursor_convert_cursor(int px, uint32_t *src, uint16_t *dst, int bpp,
uint32_t fg, uint32_t bg)
+void
+nv_cursor_convert_cursor(uint32_t *src, void *dst, int src_stride, int
dst_stride,
+ int bpp, uint32_t fg, uint32_t bg)
{
+ int width = min(src_stride, dst_stride);
uint32_t b, m, pxval;
- int i, j;
+ int i, j, k;
+
+ for (i = 0; i < width; i++) {
+ for (j = 0; j < width / SOURCE_MASK_INTERLEAVE; j++) {
+ int src_off = i*src_stride/SOURCE_MASK_INTERLEAVE + j;
+ int dst_off = i*dst_stride + j*SOURCE_MASK_INTERLEAVE;
+
+ b = src[2*src_off];
+ m = src[2*src_off + 1];
- for (i = 0; i < px / SOURCE_MASK_INTERLEAVE; i++) {
- b = *src++;
- m = *src++;
- for (j = 0; j < SOURCE_MASK_INTERLEAVE; j++) {
- pxval = TRANSPARENT_PIXEL;
+ for (k = 0; k < SOURCE_MASK_INTERLEAVE; k++) {
+ pxval = TRANSPARENT_PIXEL;
#if X_BYTE_ORDER == X_BIG_ENDIAN
- if (m & 0x80000000)
- pxval = (b & 0x80000000) ? fg : bg;
- b <<= 1;
- m <<= 1;
+ if (m & 0x80000000)
+ pxval = (b & 0x80000000) ? fg : bg;
+ b <<= 1;
+ m <<= 1;
#else
- if (m & 1)
- pxval = (b & 1) ? fg : bg;
- b >>= 1;
- m >>= 1;
+ if (m & 1)
+ pxval = (b & 1) ? fg : bg;
+ b >>= 1;
+ m >>= 1;
#endif
- if (bpp == 32) {
- *(uint32_t *)dst = pxval;
- dst += 2;
- } else
- *dst++ = pxval;
+ if (bpp == 32)
+ ((uint32_t *)dst)[dst_off + k] = pxval;
+ else
+ ((uint16_t *)dst)[dst_off + k] = pxval;
+ }
}
}
}
@@ -76,14 +75,16 @@ static void nv_cursor_transform_cursor(NVPtr pNv, struct
nouveau_crtc *nv_crtc)
{
uint16_t *tmp;
struct nouveau_bo *cursor = NULL;
- int px = pNv->NVArch >= 0x10 ? NV10_CURSOR_PIXELS : NV04_CURSOR_PIXELS;
+ int px = nv_cursor_pixels(pNv);
+ int width = nv_cursor_width(pNv);
if (!(tmp = xcalloc(px, 4)))
return;
/* convert to colour cursor */
- nv_cursor_convert_cursor(px, pNv->curImage, tmp, pNv->alphaCursor ? 32 :
16,
- nv_crtc->cursor_fg, nv_crtc->cursor_bg);
+ nv_cursor_convert_cursor(pNv->curImage, tmp, width, width,
+ pNv->alphaCursor ? 32 : 16, nv_crtc->cursor_fg,
+ nv_crtc->cursor_bg);
nouveau_bo_ref(nv_crtc->head ? pNv->Cursor2 : pNv->Cursor,
&cursor);
nouveau_bo_map(cursor, NOUVEAU_BO_WR);
@@ -126,10 +127,9 @@ void nv_crtc_set_cursor_colors(xf86CrtcPtr crtc, int bg,
int fg)
void nv_crtc_load_cursor_image(xf86CrtcPtr crtc, CARD8 *image)
{
NVPtr pNv = NVPTR(crtc->scrn);
- int sz = (pNv->NVArch >= 0x10 ? NV10_CURSOR_PIXELS : NV04_CURSOR_PIXELS)
/ 4;
/* save copy of image for colour changes */
- memcpy(pNv->curImage, image, sz);
+ memcpy(pNv->curImage, image, nv_cursor_pixels(pNv) / 4);
nv_cursor_transform_cursor(pNv, to_nouveau_crtc(crtc));
}
@@ -151,7 +151,7 @@ void nv_crtc_load_cursor_argb(xf86CrtcPtr crtc, CARD32
*image)
* NPM mode needs NV_PCRTC_CURSOR_CONFIG_ALPHA_BLEND set and is what the
* blob uses, however we get given PM cursors so we use PM mode
*/
- for (i = 0; i < NV10_CURSOR_PIXELS; i++) {
+ for (i = 0; i < nv_cursor_pixels(pNv); i++) {
/* hw gets unhappy if alpha <= rgb values. for a PM image "less
* than" shouldn't happen; fix "equal to" case by adding
one to
* alpha channel (slightly inaccurate, but so is attempting to
@@ -202,10 +202,10 @@ void nv_crtc_set_cursor_position(xf86CrtcPtr crtc, int x,
int y)
Bool NVCursorInitRandr12(ScreenPtr pScreen)
{
NVPtr pNv = NVPTR(xf86Screens[pScreen->myNum]);
- int size = pNv->NVArch >= 0x10 ? NV10_CURSOR_SIZE : NV04_CURSOR_SIZE;
+ int width = nv_cursor_width(pNv);
int flags = HARDWARE_CURSOR_TRUECOLOR_AT_8BPP |
HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_32 |
(pNv->alphaCursor ? HARDWARE_CURSOR_ARGB : 0);
- return xf86_cursors_init(pScreen, size, size, flags);
+ return xf86_cursors_init(pScreen, width, width, flags);
}
diff --git a/src/nv_proto.h b/src/nv_proto.h
index 7c917cc..4a0cbf4 100644
--- a/src/nv_proto.h
+++ b/src/nv_proto.h
@@ -48,6 +48,8 @@ void nv_crtc_set_cursor_position(xf86CrtcPtr crtc, int x, int
y);
void nv_crtc_set_cursor_colors(xf86CrtcPtr crtc, int bg, int fg);
void nv_crtc_load_cursor_image(xf86CrtcPtr crtc, CARD8 *image);
void nv_crtc_load_cursor_argb(xf86CrtcPtr crtc, CARD32 *image);
+void nv_cursor_convert_cursor(uint32_t *src, void *dst, int src_stride,
+ int dst_stride, int bpp, uint32_t fg, uint32_t bg);
/* in nv_dma.c */
void NVSync(ScrnInfoPtr pScrn);
--
1.6.3.3
Francisco Jerez
2009-Aug-17 18:09 UTC
[Nouveau] [PATCH] drm/nouveau: Implement <nv11 hardware cursor.
Signed-off-by: Francisco Jerez <currojerez at riseup.net>
---
drivers/gpu/drm/nouveau/nouveau_hw.h | 10 ++++
drivers/gpu/drm/nouveau/nv04_crtc.c | 96 +++++++++++++++++++++++-----------
2 files changed, 75 insertions(+), 31 deletions(-)
diff --git a/drivers/gpu/drm/nouveau/nouveau_hw.h
b/drivers/gpu/drm/nouveau/nouveau_hw.h
index 9d86461..129345e 100644
--- a/drivers/gpu/drm/nouveau/nouveau_hw.h
+++ b/drivers/gpu/drm/nouveau/nouveau_hw.h
@@ -379,6 +379,16 @@ NVLockVgaCrtcs(struct drm_device *dev, bool lock)
return waslocked;
}
+/* nv04 cursor max dimensions of 32x32 (A1R5G5B5) */
+#define NV04_CURSOR_SIZE 32
+/* limit nv10 cursors to 64x64 (ARGB8) (we could go to 64x255) */
+#define NV10_CURSOR_SIZE 64
+
+static inline int nv_cursor_width(struct drm_device *dev)
+{
+ return nv_arch(dev) >= NV_10 ? NV10_CURSOR_SIZE : NV04_CURSOR_SIZE;
+}
+
static inline void
nv_fix_nv40_hw_cursor(struct drm_device *dev, int head)
{
diff --git a/drivers/gpu/drm/nouveau/nv04_crtc.c
b/drivers/gpu/drm/nouveau/nv04_crtc.c
index dfe9003..e4910ea 100644
--- a/drivers/gpu/drm/nouveau/nv04_crtc.c
+++ b/drivers/gpu/drm/nouveau/nv04_crtc.c
@@ -839,6 +839,64 @@ nv04_crtc_mode_set_base(struct drm_crtc *crtc, int x, int
y,
return 0;
}
+static void nv04_cursor_upload(struct drm_device *dev, uint32_t *src, uint16_t
*dst)
+{
+ int width = nv_cursor_width(dev);
+ uint32_t pixel;
+ int i, j;
+
+ for (i = 0; i < width; i++) {
+ for (j = 0; j < width; j++) {
+ pixel = src[i*64 + j];
+
+ dst[i*width + j] = (pixel & 0x80000000) >> 16
+ | (pixel & 0xf80000) >> 9
+ | (pixel & 0xf800) >> 6
+ | (pixel & 0xf8) >> 3;
+ }
+ }
+}
+
+static void nv11_cursor_upload(struct drm_device *dev, uint32_t *src, uint32_t
*dst)
+{
+ uint32_t pixel;
+ int alpha, i;
+
+ /* nv11+ supports premultiplied (PM), or non-premultiplied (NPM) alpha
+ * cursors (though NPM in combination with fp dithering may not work on
+ * nv11, from "nv" driver history)
+ * NPM mode needs NV_PCRTC_CURSOR_CONFIG_ALPHA_BLEND set and is what the
+ * blob uses, however we get given PM cursors so we use PM mode
+ */
+ for (i = 0; i < 64 * 64; i++) {
+ pixel = *src++;
+
+ /* hw gets unhappy if alpha <= rgb values. for a PM image "less
+ * than" shouldn't happen; fix "equal to" case by adding
one to
+ * alpha channel (slightly inaccurate, but so is attempting to
+ * get back to NPM images, due to limits of integer precision)
+ */
+ alpha = pixel >> 24;
+ if (alpha > 0 && alpha < 255)
+ pixel = (pixel & 0x00ffffff) | ((alpha + 1) << 24);
+
+#ifdef __BIG_ENDIAN
+ {
+ struct drm_nouveau_private *dev_priv = dev->dev_private;
+
+ if (dev_priv->chipset == 0x11) {
+ pixel = ((pixel & 0x000000ff) << 24) |
+ ((pixel & 0x0000ff00) << 8) |
+ ((pixel & 0x00ff0000) >> 8) |
+ ((pixel & 0xff000000) >> 24);
+ }
+ }
+#endif
+
+ *dst++ = pixel;
+ }
+}
+
static int
nv04_crtc_cursor_set(struct drm_crtc *crtc, struct drm_file *file_priv,
uint32_t buffer_handle, uint32_t width, uint32_t height)
@@ -848,8 +906,8 @@ nv04_crtc_cursor_set(struct drm_crtc *crtc, struct drm_file
*file_priv,
struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc);
struct nouveau_bo *cursor = NULL;
struct drm_gem_object *gem;
- uint32_t *src, *dst, pixel;
- int ret = 0, alpha, i;
+ void *src, *dst;
+ int ret = 0;
if (width != 64 || height != 64)
return -EINVAL;
@@ -867,38 +925,14 @@ nv04_crtc_cursor_set(struct drm_crtc *crtc, struct
drm_file *file_priv,
ret = nouveau_bo_map(cursor);
if (ret)
goto out;
+
src = cursor->kmap.virtual;
dst = nv_crtc->cursor.nvbo->kmap.virtual;
- /* nv11+ supports premultiplied (PM), or non-premultiplied (NPM) alpha
- * cursors (though NPM in combination with fp dithering may not work on
- * nv11, from "nv" driver history)
- * NPM mode needs NV_PCRTC_CURSOR_CONFIG_ALPHA_BLEND set and is what the
- * blob uses, however we get given PM cursors so we use PM mode
- */
- for (i = 0; i < 64 * 64; i++) {
- pixel = *src++;
-
- /* hw gets unhappy if alpha <= rgb values. for a PM image "less
- * than" shouldn't happen; fix "equal to" case by adding
one to
- * alpha channel (slightly inaccurate, but so is attempting to
- * get back to NPM images, due to limits of integer precision)
- */
- alpha = pixel >> 24;
- if (alpha > 0 && alpha < 255)
- pixel = (pixel & 0x00ffffff) | ((alpha + 1) << 24);
-
-#ifdef __BIG_ENDIAN
- if (dev_priv->chipset == 0x11) {
- pixel = ((pixel & 0x000000ff) << 24) |
- ((pixel & 0x0000ff00) << 8) |
- ((pixel & 0x00ff0000) >> 8) |
- ((pixel & 0xff000000) >> 24);
- }
-#endif
-
- *dst++ = pixel;
- }
+ if (dev_priv->chipset >= 0x11)
+ nv11_cursor_upload(dev, src, dst);
+ else
+ nv04_cursor_upload(dev, src, dst);
nouveau_bo_unmap(cursor);
nv_crtc->cursor.offset = nv_crtc->cursor.nvbo->bo.offset;
--
1.6.3.3
Signed-off-by: Francisco Jerez <currojerez at riseup.net>
---
src/drmmode_display.c | 29 ++++++++++++++++--
src/nouveau_hw.h | 17 ++++++++++
src/nv_cursor.c | 79 ++++++++++++++++++++++++++-----------------------
src/nv_proto.h | 2 +
4 files changed, 87 insertions(+), 40 deletions(-)
diff --git a/src/drmmode_display.c b/src/drmmode_display.c
index f2fe0e8..7acddf1 100644
--- a/src/drmmode_display.c
+++ b/src/drmmode_display.c
@@ -333,7 +333,14 @@ done:
static void
drmmode_set_cursor_colors (xf86CrtcPtr crtc, int bg, int fg)
{
+ NVPtr pNv = NVPTR(crtc->scrn);
+ drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
+ struct nouveau_bo *bo = drmmode_crtc->cursor;
+ nouveau_bo_map(bo, NOUVEAU_BO_WR);
+ nv_cursor_convert_cursor(pNv->curImage, bo->map, nv_cursor_width(pNv),
+ 64, 32, fg | (0xff << 24), bg | (0xff << 24));
+ nouveau_bo_unmap(bo);
}
static void
@@ -346,6 +353,24 @@ drmmode_set_cursor_position (xf86CrtcPtr crtc, int x, int
y)
}
static void
+drmmode_load_cursor_image (xf86CrtcPtr crtc, CARD8 *image)
+{
+ NVPtr pNv = NVPTR(crtc->scrn);
+ xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(crtc->scrn);
+ drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
+ struct nouveau_bo *bo = drmmode_crtc->cursor;
+
+ /* save copy of image for colour changes */
+ memcpy(pNv->curImage, image, nv_cursor_pixels(pNv)/4);
+
+ nouveau_bo_map(bo, NOUVEAU_BO_WR);
+ nv_cursor_convert_cursor(pNv->curImage, bo->map, nv_cursor_width(pNv),
+ 64, 32, config->cursor_fg | (0xff << 24),
+ config->cursor_bg | (0xff << 24));
+ nouveau_bo_unmap(bo);
+}
+
+static void
drmmode_load_cursor_argb (xf86CrtcPtr crtc, CARD32 *image)
{
drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
@@ -505,14 +530,12 @@ static const xf86CrtcFuncsRec drmmode_crtc_funcs = {
.set_cursor_position = drmmode_set_cursor_position,
.show_cursor = drmmode_show_cursor,
.hide_cursor = drmmode_hide_cursor,
+ .load_cursor_image = drmmode_load_cursor_image,
.load_cursor_argb = drmmode_load_cursor_argb,
.shadow_create = drmmode_crtc_shadow_create,
.shadow_allocate = drmmode_crtc_shadow_allocate,
.shadow_destroy = drmmode_crtc_shadow_destroy,
.gamma_set = drmmode_gamma_set,
-#if 0
- .set_cursor_colors = drmmode_crtc_set_cursor_colors,
-#endif
.destroy = NULL, /* XXX */
};
diff --git a/src/nouveau_hw.h b/src/nouveau_hw.h
index a548a4c..aa2a3b4 100644
--- a/src/nouveau_hw.h
+++ b/src/nouveau_hw.h
@@ -287,6 +287,23 @@ static inline bool NVLockVgaCrtcs(NVPtr pNv, bool lock)
return waslocked;
}
+/* nv04 cursor max dimensions of 32x32 (A1R5G5B5) */
+#define NV04_CURSOR_SIZE 32
+/* limit nv10 cursors to 64x64 (ARGB8) (we could go to 64x255) */
+#define NV10_CURSOR_SIZE 64
+
+static inline int nv_cursor_width(NVPtr pNv)
+{
+ return pNv->NVArch >= 0x10 ? NV10_CURSOR_SIZE : NV04_CURSOR_SIZE;
+}
+
+static inline int nv_cursor_pixels(NVPtr pNv)
+{
+ int width = nv_cursor_width(pNv);
+
+ return width * width;
+}
+
static inline void nv_fix_nv40_hw_cursor(NVPtr pNv, int head)
{
/* on some nv40 (such as the "true" (in the NV_PFB_BOOT_0 sense)
nv40,
diff --git a/src/nv_cursor.c b/src/nv_cursor.c
index 22db9e6..3df1539 100644
--- a/src/nv_cursor.c
+++ b/src/nv_cursor.c
@@ -30,44 +30,48 @@
((c & 0xf8) >> 3 )) /* Blue */
#define TO_ARGB8888(c) (0xff000000 | c)
-/* nv04 cursor max dimensions of 32x32 (A1R5G5B5) */
-#define NV04_CURSOR_SIZE 32
-#define NV04_CURSOR_PIXELS (NV04_CURSOR_SIZE * NV04_CURSOR_SIZE)
-
-/* limit nv10 cursors to 64x64 (ARGB8) (we could go to 64x255) */
-#define NV10_CURSOR_SIZE 64
-#define NV10_CURSOR_PIXELS (NV10_CURSOR_SIZE * NV10_CURSOR_SIZE)
-
#define SOURCE_MASK_INTERLEAVE 32
#define TRANSPARENT_PIXEL 0
-static void
-nv_cursor_convert_cursor(int px, uint32_t *src, uint16_t *dst, int bpp,
uint32_t fg, uint32_t bg)
+/*
+ * Convert a source/mask bitmap cursor to an ARGB cursor, clipping or
+ * padding as necessary. source/mask are assumed to be alternated each
+ * SOURCE_MASK_INTERLEAVE bits.
+ */
+void
+nv_cursor_convert_cursor(uint32_t *src, void *dst, int src_stride, int
dst_stride,
+ int bpp, uint32_t fg, uint32_t bg)
{
+ int width = min(src_stride, dst_stride);
uint32_t b, m, pxval;
- int i, j;
+ int i, j, k;
+
+ for (i = 0; i < width; i++) {
+ for (j = 0; j < width / SOURCE_MASK_INTERLEAVE; j++) {
+ int src_off = i*src_stride/SOURCE_MASK_INTERLEAVE + j;
+ int dst_off = i*dst_stride + j*SOURCE_MASK_INTERLEAVE;
+
+ b = src[2*src_off];
+ m = src[2*src_off + 1];
- for (i = 0; i < px / SOURCE_MASK_INTERLEAVE; i++) {
- b = *src++;
- m = *src++;
- for (j = 0; j < SOURCE_MASK_INTERLEAVE; j++) {
- pxval = TRANSPARENT_PIXEL;
+ for (k = 0; k < SOURCE_MASK_INTERLEAVE; k++) {
+ pxval = TRANSPARENT_PIXEL;
#if X_BYTE_ORDER == X_BIG_ENDIAN
- if (m & 0x80000000)
- pxval = (b & 0x80000000) ? fg : bg;
- b <<= 1;
- m <<= 1;
+ if (m & 0x80000000)
+ pxval = (b & 0x80000000) ? fg : bg;
+ b <<= 1;
+ m <<= 1;
#else
- if (m & 1)
- pxval = (b & 1) ? fg : bg;
- b >>= 1;
- m >>= 1;
+ if (m & 1)
+ pxval = (b & 1) ? fg : bg;
+ b >>= 1;
+ m >>= 1;
#endif
- if (bpp == 32) {
- *(uint32_t *)dst = pxval;
- dst += 2;
- } else
- *dst++ = pxval;
+ if (bpp == 32)
+ ((uint32_t *)dst)[dst_off + k] = pxval;
+ else
+ ((uint16_t *)dst)[dst_off + k] = pxval;
+ }
}
}
}
@@ -76,14 +80,16 @@ static void nv_cursor_transform_cursor(NVPtr pNv, struct
nouveau_crtc *nv_crtc)
{
uint16_t *tmp;
struct nouveau_bo *cursor = NULL;
- int px = pNv->NVArch >= 0x10 ? NV10_CURSOR_PIXELS : NV04_CURSOR_PIXELS;
+ int px = nv_cursor_pixels(pNv);
+ int width = nv_cursor_width(pNv);
if (!(tmp = xcalloc(px, 4)))
return;
/* convert to colour cursor */
- nv_cursor_convert_cursor(px, pNv->curImage, tmp, pNv->alphaCursor ? 32 :
16,
- nv_crtc->cursor_fg, nv_crtc->cursor_bg);
+ nv_cursor_convert_cursor(pNv->curImage, tmp, width, width,
+ pNv->alphaCursor ? 32 : 16, nv_crtc->cursor_fg,
+ nv_crtc->cursor_bg);
nouveau_bo_ref(nv_crtc->head ? pNv->Cursor2 : pNv->Cursor,
&cursor);
nouveau_bo_map(cursor, NOUVEAU_BO_WR);
@@ -126,10 +132,9 @@ void nv_crtc_set_cursor_colors(xf86CrtcPtr crtc, int bg,
int fg)
void nv_crtc_load_cursor_image(xf86CrtcPtr crtc, CARD8 *image)
{
NVPtr pNv = NVPTR(crtc->scrn);
- int sz = (pNv->NVArch >= 0x10 ? NV10_CURSOR_PIXELS : NV04_CURSOR_PIXELS)
/ 4;
/* save copy of image for colour changes */
- memcpy(pNv->curImage, image, sz);
+ memcpy(pNv->curImage, image, nv_cursor_pixels(pNv) / 4);
nv_cursor_transform_cursor(pNv, to_nouveau_crtc(crtc));
}
@@ -151,7 +156,7 @@ void nv_crtc_load_cursor_argb(xf86CrtcPtr crtc, CARD32
*image)
* NPM mode needs NV_PCRTC_CURSOR_CONFIG_ALPHA_BLEND set and is what the
* blob uses, however we get given PM cursors so we use PM mode
*/
- for (i = 0; i < NV10_CURSOR_PIXELS; i++) {
+ for (i = 0; i < nv_cursor_pixels(pNv); i++) {
/* hw gets unhappy if alpha <= rgb values. for a PM image "less
* than" shouldn't happen; fix "equal to" case by adding
one to
* alpha channel (slightly inaccurate, but so is attempting to
@@ -202,10 +207,10 @@ void nv_crtc_set_cursor_position(xf86CrtcPtr crtc, int x,
int y)
Bool NVCursorInitRandr12(ScreenPtr pScreen)
{
NVPtr pNv = NVPTR(xf86Screens[pScreen->myNum]);
- int size = pNv->NVArch >= 0x10 ? NV10_CURSOR_SIZE : NV04_CURSOR_SIZE;
+ int width = nv_cursor_width(pNv);
int flags = HARDWARE_CURSOR_TRUECOLOR_AT_8BPP |
HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_32 |
(pNv->alphaCursor ? HARDWARE_CURSOR_ARGB : 0);
- return xf86_cursors_init(pScreen, size, size, flags);
+ return xf86_cursors_init(pScreen, width, width, flags);
}
diff --git a/src/nv_proto.h b/src/nv_proto.h
index 7c917cc..4a0cbf4 100644
--- a/src/nv_proto.h
+++ b/src/nv_proto.h
@@ -48,6 +48,8 @@ void nv_crtc_set_cursor_position(xf86CrtcPtr crtc, int x, int
y);
void nv_crtc_set_cursor_colors(xf86CrtcPtr crtc, int bg, int fg);
void nv_crtc_load_cursor_image(xf86CrtcPtr crtc, CARD8 *image);
void nv_crtc_load_cursor_argb(xf86CrtcPtr crtc, CARD32 *image);
+void nv_cursor_convert_cursor(uint32_t *src, void *dst, int src_stride,
+ int dst_stride, int bpp, uint32_t fg, uint32_t bg);
/* in nv_dma.c */
void NVSync(ScrnInfoPtr pScrn);
--
1.6.3.3