diff options
-rw-r--r-- | src/drmmode_display.c | 41 | ||||
-rw-r--r-- | src/drmmode_driver.h | 12 | ||||
-rw-r--r-- | src/drmmode_exynos/drmmode_exynos.c | 36 | ||||
-rw-r--r-- | src/drmmode_pl111/drmmode_pl111.c | 97 | ||||
-rw-r--r-- | src/drmmode_template/drmmode_template.c | 6 |
5 files changed, 42 insertions, 150 deletions
diff --git a/src/drmmode_display.c b/src/drmmode_display.c index ffd9dd1..9d0d242 100644 --- a/src/drmmode_display.c +++ b/src/drmmode_display.c @@ -517,6 +517,41 @@ drmmode_set_cursor_position(xf86CrtcPtr crtc, int x, int y) drmmode_show_cursor_image(crtc, FALSE); } +/* + * The cursor format is ARGB so the image can be copied straight over. + * Columns of CURSORPAD blank pixels are maintained down either side + * of the destination image. This is a workaround for a bug causing + * corruption when the cursor reaches the screen edges in some DRM + * drivers. + */ +static void set_cursor_image(xf86CrtcPtr crtc, uint32_t *d, CARD32 *s) +{ + ScrnInfoPtr pScrn = crtc->scrn; + struct ARMSOCRec *pARMSOC = ARMSOCPTR(pScrn); + int row; + void *dst; + const char *src_row; + char *dst_row; + uint32_t cursorh = pARMSOC->drmmode_interface->cursor_height; + uint32_t cursorw = pARMSOC->drmmode_interface->cursor_width; + uint32_t cursorpad = pARMSOC->drmmode_interface->cursor_padding; + + dst = d; + for (row = 0; row < cursorh; row += 1) { + /* we're operating with ARGB data (4 bytes per pixel) */ + src_row = (const char *)s + row * 4 * cursorw; + dst_row = (char *)dst + row * 4 * (cursorw + 2 * cursorpad); + + /* set first CURSORPAD pixels in row to 0 */ + memset(dst_row, 0, (4 * cursorpad)); + /* copy cursor image pixel row across */ + memcpy(dst_row + (4 * cursorpad), src_row, 4 * cursorw); + /* set last CURSORPAD pixels in row to 0 */ + memset(dst_row + 4 * (cursorpad + cursorw), + 0, (4 * cursorpad)); + } +} + static void drmmode_load_cursor_argb(xf86CrtcPtr crtc, CARD32 *image) { @@ -525,8 +560,6 @@ drmmode_load_cursor_argb(xf86CrtcPtr crtc, CARD32 *image) struct drmmode_rec *drmmode = drmmode_crtc->drmmode; struct drmmode_cursor_rec *cursor = drmmode->cursor; int visible; - ScrnInfoPtr pScrn = crtc->scrn; - struct ARMSOCRec *pARMSOC = ARMSOCPTR(pScrn); if (!cursor) return; @@ -545,9 +578,7 @@ drmmode_load_cursor_argb(xf86CrtcPtr crtc, CARD32 *image) return; } - /* set_cursor_image is a mandatory function */ - assert(pARMSOC->drmmode_interface->set_cursor_image); - pARMSOC->drmmode_interface->set_cursor_image(crtc, d, image); + set_cursor_image(crtc, d, image); if (visible) drmmode_show_cursor_image(crtc, TRUE); diff --git a/src/drmmode_driver.h b/src/drmmode_driver.h index f9d8897..0e802b9 100644 --- a/src/drmmode_driver.h +++ b/src/drmmode_driver.h @@ -70,18 +70,6 @@ struct drmmode_interface { */ int (*init_plane_for_cursor)(int drm_fd, uint32_t plane_id); - /* (Mandatory) Set the cursor image from an ARGB image - * - * If the cursor image is ARGB this is a straight copy, otherwise - * it must perform any necessary conversion from ARGB to the - * cursor format. - * - * @param crtc The CRTC in use - * @param [out] d Pointer to the destination cursor image - * @param [in] s Pointer to the source for the cursor image - */ - void (*set_cursor_image)(xf86CrtcPtr crtc, uint32_t *d, CARD32 *s); - /* Boolean value indicating whether the DRM supports * vblank timestamp query */ diff --git a/src/drmmode_exynos/drmmode_exynos.c b/src/drmmode_exynos/drmmode_exynos.c index 3e541ff..f1fa033 100644 --- a/src/drmmode_exynos/drmmode_exynos.c +++ b/src/drmmode_exynos/drmmode_exynos.c @@ -41,7 +41,12 @@ struct drm_exynos_plane_set_zpos { */ #define CURSORW (64) #define CURSORH (64) -#define CURSORPAD (16) /* Padding added down each side of cursor image */ + +/* + * Padding added down each side of cursor image. This is a workaround for a bug + * causing corruption when the cursor reaches the screen edges. + */ +#define CURSORPAD (16) #define DRM_EXYNOS_PLANE_SET_ZPOS 0x06 #define DRM_IOCTL_EXYNOS_PLANE_SET_ZPOS DRM_IOWR(DRM_COMMAND_BASE + \ @@ -93,34 +98,6 @@ static int init_plane_for_cursor(int drm_fd, uint32_t plane_id) return res; } -/* The cursor format is ARGB so the image can be copied straight over. - * Columns of CURSORPAD blank pixels are maintained down either side - * of the destination image. This is a workaround for a bug causing - * corruption when the cursor reaches the screen edges. - */ -static void set_cursor_image(xf86CrtcPtr crtc, uint32_t *d, CARD32 *s) -{ - int row; - void *dst; - const char *src_row; - char *dst_row; - - dst = d; - for (row = 0; row < CURSORH; row += 1) { - /* we're operating with ARGB data (4 bytes per pixel) */ - src_row = (const char *)s + row * 4 * CURSORW; - dst_row = (char *)dst + row * 4 * (CURSORW + 2 * CURSORPAD); - - /* set first CURSORPAD pixels in row to 0 */ - memset(dst_row, 0, (4 * CURSORPAD)); - /* copy cursor image pixel row across */ - memcpy(dst_row + (4 * CURSORPAD), src_row, 4 * CURSORW); - /* set last CURSORPAD pixels in row to 0 */ - memset(dst_row + 4 * (CURSORPAD + CURSORW), - 0, (4 * CURSORPAD)); - } -} - static int create_custom_gem(int fd, struct armsoc_create_gem *create_gem) { struct drm_mode_create_dumb create_dumb; @@ -160,7 +137,6 @@ struct drmmode_interface exynos_interface = { CURSORPAD /* cursor padding */, HWCURSOR_API_PLANE /* cursor_api */, init_plane_for_cursor /* init_plane_for_cursor */, - set_cursor_image /* set cursor image */, 0 /* vblank_query_supported */, create_custom_gem /* create_custom_gem */, }; diff --git a/src/drmmode_pl111/drmmode_pl111.c b/src/drmmode_pl111/drmmode_pl111.c index 34f1d8c..3b9f92f 100644 --- a/src/drmmode_pl111/drmmode_pl111.c +++ b/src/drmmode_pl111/drmmode_pl111.c @@ -37,105 +37,9 @@ /* Padding added down each side of cursor image */ #define CURSORPAD (0) -/* un-comment to enable cursor format conversion debugging.*/ -/* #define ARGB_LBBP_CONVERSION_DEBUG */ - -#define LBBP_BACKGROUND (0x0) -#define LBBP_FOREGROUND (0x1) -#define LBBP_TRANSPARENT (0x2) -#define LBBP_INVERSE (0x3) - -#define ARGB_ALPHA (0xff000000) -#define ARGB_RGB (~ARGB_ALPHA) - -#define LBBP_WORDS_PER_LINE (4) -#define LBBP_PIXELS_PER_WORD (16) - #define PL111_SCANOUT_FLAGS 0x00000001 #define PL111_NON_SCANOUT_FLAGS 0x00000000 -/* shift required to locate pixel into the correct position in - * a cursor LBBP word, indexed by x mod 16. - */ -const unsigned char x_mod_16_to_value_shift[LBBP_PIXELS_PER_WORD] = { - 6, 4, 2, 0, 14, 12, 10, 8, 22, 20, 18, 16, 30, 28, 26, 24 -}; - -/* Pack the pixel value into its correct position in the buffer as specified - * for LBBP */ -static inline void -set_lbbp_pixel(uint32_t *buffer, unsigned int x, unsigned int y, - uint32_t value) -{ - uint32_t *p; - uint32_t shift; - - assert((x < CURSORW) && (y < CURSORH)); - - shift = x_mod_16_to_value_shift[x % LBBP_PIXELS_PER_WORD]; - - /* Get the word containing this pixel */ - p = buffer + (x >> LBBP_WORDS_PER_LINE) + (y << 2); - - /* Clear data for this pixel in the buffer and apply the new data */ - *p &= ~(LBBP_INVERSE << shift); - *p |= value << shift; -} - -/* - * The PL111 hardware cursor supports only LBBP which is a 2bpp format but - * there are no drm fourcc formats that are compatible with this so instead - * the PL111 DRM reports (to DRM core) that it supports only - * DRM_FORMAT_ARGB8888 and expects the DDX to supply an LBPP image in the - * first 1/16th of the buffer, the rest being unused. - * Ideally we would want to receive the image in this format from X, but - * currently the X cursor image is 32bpp ARGB so we need to convert - * to LBBP here. - */ -static void set_cursor_image(xf86CrtcPtr crtc, uint32_t *d, CARD32 *s) -{ -#ifdef ARGB_LBBP_CONVERSION_DEBUG - /* Add 1 on width to insert trailing NULL */ - char string_cursor[CURSORW+1]; -#endif /* ARGB_LBBP_CONVERSION_DEBUG */ - unsigned int x; - unsigned int y; - - for (y = 0; y < CURSORH ; y++) { - for (x = 0; x < CURSORW ; x++) { - uint32_t value = LBBP_TRANSPARENT; - /* If pixel visible foreground/background */ - if ((*s & ARGB_ALPHA) != 0) { - /* Any color set then just convert to - * foreground for now - */ - if ((*s & ARGB_RGB) != 0) - value = LBBP_FOREGROUND; - else - value = LBBP_BACKGROUND; - } -#ifdef ARGB_LBBP_CONVERSION_DEBUG - if (value == LBBP_TRANSPARENT) - string_cursor[x] = 'T'; - else if (value == LBBP_FOREGROUND) - string_cursor[x] = 'F'; - else if (value == LBBP_INVERSE) - string_cursor[x] = 'I'; - else - string_cursor[x] = 'B'; - -#endif /* ARGB_LBBP_CONVERSION_DEBUG */ - set_lbbp_pixel(d, x, y, value); - ++s; - } -#ifdef ARGB_LBBP_CONVERSION_DEBUG - string_cursor[CURSORW] = '\0'; - xf86DrvMsg(crtc->scrn->scrnIndex, X_INFO, "%s\n", - string_cursor); -#endif /* ARGB_LBBP_CONVERSION_DEBUG */ - } -} - /* TODO MIDEGL-1718: this should be included * from kernel headers when pl111 is mainline */ struct drm_pl111_gem_create { @@ -193,7 +97,6 @@ struct drmmode_interface pl111_interface = { CURSORPAD /* cursor padding */, HWCURSOR_API_STANDARD /* cursor_api */, NULL /* init_plane_for_cursor */, - set_cursor_image /* set cursor image */, 0 /* vblank_query_supported */, create_custom_gem /* create_custom_gem */, }; diff --git a/src/drmmode_template/drmmode_template.c b/src/drmmode_template/drmmode_template.c index a42d7fe..ccac344 100644 --- a/src/drmmode_template/drmmode_template.c +++ b/src/drmmode_template/drmmode_template.c @@ -43,11 +43,6 @@ static int init_plane_for_cursor(int drm_fd, uint32_t plane_id) return 0; } -static void set_cursor_image(xf86CrtcPtr crtc, uint32_t *d, CARD32 *s) -{ - /* provide a method of setting the cursor image here */ -} - static int create_custom_gem(int fd, struct armsoc_create_gem *create_gem) { /* @@ -64,7 +59,6 @@ struct drmmode_interface template_interface = { CURSORPAD /* cursor padding */, HWCURSOR_API_STANDARD /* cursor_api */, init_plane_for_cursor /* init_plane_for_cursor */, - set_cursor_image /* set cursor image */, 0 /* vblank_query_supported */, create_custom_gem /* create_custom_gem */, }; |