mirror of
https://github.com/X11Libre/xserver.git
synced 2026-03-24 01:34:11 +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;
|
||||
}
|
||||
|
||||
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 inline int
|
||||
@@ -1857,12 +1917,8 @@ drmmode_load_cursor_argb_check(xf86CrtcPtr crtc, CARD32 *image)
|
||||
drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
|
||||
CursorPtr cursor = xf86CurrentCursor(crtc->scrn->pScreen);
|
||||
drmmode_cursor_rec drmmode_cursor = drmmode_crtc->cursor;
|
||||
int width, height, x, y, i;
|
||||
int width, height, i;
|
||||
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. */
|
||||
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;
|
||||
height = drmmode_cursor.dimensions[i].height;
|
||||
|
||||
/* Copy the cursor image over. */
|
||||
i = 0;
|
||||
for (y = 0; y < height; y++) {
|
||||
for (x = 0; x < width; x++)
|
||||
ptr[i++] = image[y * max_width + x];
|
||||
}
|
||||
const int cursor_pitch = drmmode_cursor_get_pitch(drmmode_crtc, i);
|
||||
|
||||
/* Clear the remainder for good measure. */
|
||||
for (; i < max_width * max_height; i++)
|
||||
ptr[i++] = 0;
|
||||
/* cursor should be mapped already */
|
||||
drmmode_paint_cursor(drmmode_cursor.bo->ptr, cursor_pitch, width, height,
|
||||
image, max_width, max_height);
|
||||
|
||||
/* set cursor width and height here for drmmode_show_cursor */
|
||||
drmmode_crtc->cursor_width = width;
|
||||
@@ -2274,6 +2325,7 @@ drmmode_crtc_destroy(xf86CrtcPtr crtc)
|
||||
|
||||
/* Used even without atomic modesetting */
|
||||
free(drmmode_crtc->cursor.dimensions);
|
||||
free(drmmode_crtc->cursor_pitches);
|
||||
|
||||
if (!ms->atomic_modeset)
|
||||
return;
|
||||
|
||||
@@ -245,6 +245,8 @@ typedef struct {
|
||||
|
||||
Bool vrr_enabled;
|
||||
Bool use_gamma_lut;
|
||||
|
||||
int* cursor_pitches;
|
||||
} drmmode_crtc_private_rec, *drmmode_crtc_private_ptr;
|
||||
|
||||
typedef struct {
|
||||
|
||||
Reference in New Issue
Block a user