mirror of
https://github.com/X11Libre/xserver.git
synced 2026-03-24 03:44:06 +00:00
modesetting: handle pitch when painting the hardware cursor
The cursor pitch can depend on crtc. Since we only use the sizes reported by SIZE_HINTS, we can allocate a small cache for pitches in each crtc. Signed-off-by: stefan11111 <stefan11111@shitposting.expert>
This commit is contained in:
committed by
Enrico Weigelt
parent
56c4d68140
commit
b11c28b13e
@@ -1830,6 +1830,66 @@ drmmode_set_cursor(xf86CrtcPtr crtc, int width, int height)
|
|||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
drmmode_cursor_get_pitch(drmmode_crtc_private_ptr drmmode_crtc, int idx)
|
||||||
|
{
|
||||||
|
drmmode_ptr drmmode = drmmode_crtc->drmmode;
|
||||||
|
drmmode_cursor_ptr drmmode_cursor = &drmmode_crtc->cursor;
|
||||||
|
|
||||||
|
int width = drmmode_cursor->dimensions[idx].width;
|
||||||
|
int height = drmmode_cursor->dimensions[idx].height;
|
||||||
|
|
||||||
|
int num_pitches = drmmode_cursor->num_dimensions;
|
||||||
|
|
||||||
|
if (!drmmode_crtc->cursor_pitches) {
|
||||||
|
drmmode_crtc->cursor_pitches = calloc(num_pitches, sizeof(int));
|
||||||
|
if (!drmmode_crtc->cursor_pitches) {
|
||||||
|
/* we couldn't allocate memory for the cache, so we don't cache the result */
|
||||||
|
int ret;
|
||||||
|
struct dumb_bo *bo = dumb_bo_create(drmmode->fd, width, height, drmmode->kbpp);
|
||||||
|
if (!bo) {
|
||||||
|
/* We couldn't allocate a bo, so we try to guess the pitch */
|
||||||
|
return width > 64 ? width : 64;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = bo->pitch / drmmode->cpp;
|
||||||
|
|
||||||
|
dumb_bo_destroy(drmmode->fd, bo);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (drmmode_crtc->cursor_pitches[idx]) {
|
||||||
|
/* return the cached pitch */
|
||||||
|
return drmmode_crtc->cursor_pitches[idx];
|
||||||
|
}
|
||||||
|
|
||||||
|
struct dumb_bo *bo = dumb_bo_create(drmmode->fd, width, height, drmmode->kbpp);
|
||||||
|
if (!bo) {
|
||||||
|
/* We couldn't allocate a bo, so we try to guess the pitch */
|
||||||
|
return width > 64 ? width : 64;
|
||||||
|
}
|
||||||
|
|
||||||
|
drmmode_crtc->cursor_pitches[idx] = bo->pitch / drmmode->cpp;
|
||||||
|
|
||||||
|
dumb_bo_destroy(drmmode->fd, bo);
|
||||||
|
return drmmode_crtc->cursor_pitches[idx];
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
drmmode_paint_cursor(CARD32 * restrict cursor, int cursor_pitch, int cursor_width, int cursor_height,
|
||||||
|
const CARD32 * restrict image, int image_width, int image_height)
|
||||||
|
{
|
||||||
|
if (cursor_width == image_width && cursor_pitch == cursor_width) {
|
||||||
|
/* we can speed things up in this case */
|
||||||
|
memcpy(cursor, image, cursor_width * cursor_height * sizeof(*cursor));
|
||||||
|
} else {
|
||||||
|
for (int i = 0; i < cursor_height; i++) {
|
||||||
|
memcpy(cursor + i * cursor_pitch, image + i * image_width, cursor_width * sizeof(*cursor)); /* cpu_to_le32(image[i]); */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void drmmode_hide_cursor(xf86CrtcPtr crtc);
|
static void drmmode_hide_cursor(xf86CrtcPtr crtc);
|
||||||
|
|
||||||
static inline int
|
static inline int
|
||||||
@@ -1857,12 +1917,8 @@ drmmode_load_cursor_argb_check(xf86CrtcPtr crtc, CARD32 *image)
|
|||||||
drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
|
drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
|
||||||
CursorPtr cursor = xf86CurrentCursor(crtc->scrn->pScreen);
|
CursorPtr cursor = xf86CurrentCursor(crtc->scrn->pScreen);
|
||||||
drmmode_cursor_rec drmmode_cursor = drmmode_crtc->cursor;
|
drmmode_cursor_rec drmmode_cursor = drmmode_crtc->cursor;
|
||||||
int width, height, x, y, i;
|
int width, height, i;
|
||||||
int max_width, max_height;
|
int max_width, max_height;
|
||||||
uint32_t *ptr;
|
|
||||||
|
|
||||||
/* cursor should be mapped already */
|
|
||||||
ptr = (uint32_t *) (drmmode_cursor.bo->ptr);
|
|
||||||
|
|
||||||
/* We need to know what our limit is for HW cursors. */
|
/* We need to know what our limit is for HW cursors. */
|
||||||
max_width = get_maximum_cursor_width(drmmode_cursor);
|
max_width = get_maximum_cursor_width(drmmode_cursor);
|
||||||
@@ -1882,16 +1938,11 @@ drmmode_load_cursor_argb_check(xf86CrtcPtr crtc, CARD32 *image)
|
|||||||
width = drmmode_cursor.dimensions[i].width;
|
width = drmmode_cursor.dimensions[i].width;
|
||||||
height = drmmode_cursor.dimensions[i].height;
|
height = drmmode_cursor.dimensions[i].height;
|
||||||
|
|
||||||
/* Copy the cursor image over. */
|
const int cursor_pitch = drmmode_cursor_get_pitch(drmmode_crtc, i);
|
||||||
i = 0;
|
|
||||||
for (y = 0; y < height; y++) {
|
|
||||||
for (x = 0; x < width; x++)
|
|
||||||
ptr[i++] = image[y * max_width + x];
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Clear the remainder for good measure. */
|
/* cursor should be mapped already */
|
||||||
for (; i < max_width * max_height; i++)
|
drmmode_paint_cursor(drmmode_cursor.bo->ptr, cursor_pitch, width, height,
|
||||||
ptr[i++] = 0;
|
image, max_width, max_height);
|
||||||
|
|
||||||
/* set cursor width and height here for drmmode_show_cursor */
|
/* set cursor width and height here for drmmode_show_cursor */
|
||||||
drmmode_crtc->cursor_width = width;
|
drmmode_crtc->cursor_width = width;
|
||||||
@@ -2274,6 +2325,7 @@ drmmode_crtc_destroy(xf86CrtcPtr crtc)
|
|||||||
|
|
||||||
/* Used even without atomic modesetting */
|
/* Used even without atomic modesetting */
|
||||||
free(drmmode_crtc->cursor.dimensions);
|
free(drmmode_crtc->cursor.dimensions);
|
||||||
|
free(drmmode_crtc->cursor_pitches);
|
||||||
|
|
||||||
if (!ms->atomic_modeset)
|
if (!ms->atomic_modeset)
|
||||||
return;
|
return;
|
||||||
|
|||||||
@@ -245,6 +245,8 @@ typedef struct {
|
|||||||
|
|
||||||
Bool vrr_enabled;
|
Bool vrr_enabled;
|
||||||
Bool use_gamma_lut;
|
Bool use_gamma_lut;
|
||||||
|
|
||||||
|
int* cursor_pitches;
|
||||||
} drmmode_crtc_private_rec, *drmmode_crtc_private_ptr;
|
} drmmode_crtc_private_rec, *drmmode_crtc_private_ptr;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
|||||||
Reference in New Issue
Block a user