Skip to content

Commit d0af3e2

Browse files
committed
modesetting: Initialize the cursor image with the smallest size supported by all CRTCs.
We try to find the smallest size we can use for the cursor image. Signed-off-by: stefan11111 <[email protected]>
1 parent 8dde500 commit d0af3e2

File tree

4 files changed

+42
-86
lines changed

4 files changed

+42
-86
lines changed

hw/xfree86/drivers/video/modesetting/driver.c

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2001,17 +2001,12 @@ ScreenInit(ScreenPtr pScreen, int argc, char **argv)
20012001
PointPriv->spriteFuncs = &drmmode_sprite_funcs;
20022002
}
20032003

2004-
/* Get the maximum cursor size. */
2005-
drmmode_cursor_dim_rec cursor_dim = { 0 };
2006-
if (!drmmode_get_largest_cursor(pScrn, &cursor_dim))
2007-
return FALSE;
2008-
20092004
/* Need to extend HWcursor support to handle mask interleave */
20102005
if (!ms->drmmode.sw_cursor) {
20112006
/* XXX Is there any spec that says we should interleave the cursor bits? XXX */
20122007
int interleave = modesetting_get_cursor_interleave(pScrn->scrnIndex);
20132008

2014-
xf86_cursors_init(pScreen, cursor_dim.width, cursor_dim.height,
2009+
xf86_cursors_init(pScreen, ms->cursor_image_width, ms->cursor_image_height,
20152010
interleave |
20162011
HARDWARE_CURSOR_UPDATE_UNHIDDEN |
20172012
HARDWARE_CURSOR_ARGB);

hw/xfree86/drivers/video/modesetting/driver.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,9 @@ typedef struct _modesettingRec {
131131
DamagePtr damage;
132132
Bool dirty_enabled;
133133

134+
uint32_t cursor_image_width;
135+
uint32_t cursor_image_height;
136+
134137
Bool has_queue_sequence;
135138
Bool tried_queue_sequence;
136139

hw/xfree86/drivers/video/modesetting/drmmode_display.c

Lines changed: 36 additions & 76 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@
5959

6060
#include "driver.h"
6161

62+
#define MIN(a,b) ((a) < (b) ? (a) : (b))
6263
#define MAX(a,b) ((a) > (b) ? (a) : (b))
6364

6465
static Bool drmmode_xf86crtc_resize(ScrnInfoPtr scrn, int width, int height);
@@ -1889,6 +1890,11 @@ drmmode_paint_cursor(struct dumb_bo *cursor_bo, int cursor_pitch, int cursor_wid
18891890

18901891
CARD32 *cursor = cursor_bo->ptr;
18911892

1893+
/*
1894+
* The image buffer can be smaller than the cursor buffer.
1895+
* This means that we can't clear the cursor by copying '\0' bytes
1896+
* from the image buffer, because we might read out of bounds.
1897+
*/
18921898
if (drmmode_crtc->cursor_glyph_width == 0 &&
18931899
drmmode_crtc->cursor_glyph_height == 0) {
18941900
/* If this is the first time we paint the cursor, assume the entire cursor buffer is dirty */
@@ -1911,18 +1917,6 @@ drmmode_paint_cursor(struct dumb_bo *cursor_bo, int cursor_pitch, int cursor_wid
19111917

19121918
static void drmmode_hide_cursor(xf86CrtcPtr crtc);
19131919

1914-
static inline int
1915-
get_maximum_cursor_width(drmmode_cursor_rec cursor)
1916-
{
1917-
return cursor.dimensions[cursor.num_dimensions - 1].width;
1918-
}
1919-
1920-
static inline int
1921-
get_maximum_cursor_height(drmmode_cursor_rec cursor)
1922-
{
1923-
return cursor.dimensions[cursor.num_dimensions - 1].height;
1924-
}
1925-
19261920
/*
19271921
* The load_cursor_argb_check driver hook.
19281922
*
@@ -1934,14 +1928,10 @@ static Bool
19341928
drmmode_load_cursor_argb_check(xf86CrtcPtr crtc, CARD32 *image)
19351929
{
19361930
drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
1931+
modesettingPtr ms = modesettingPTR(crtc->scrn);
19371932
CursorPtr cursor = xf86CurrentCursor(crtc->scrn->pScreen);
19381933
drmmode_cursor_rec drmmode_cursor = drmmode_crtc->cursor;
1939-
int width, height, i;
1940-
int max_width, max_height;
1941-
1942-
/* We need to know what our limit is for HW cursors. */
1943-
max_width = get_maximum_cursor_width(drmmode_cursor);
1944-
max_height = get_maximum_cursor_height(drmmode_cursor);
1934+
int i;
19451935

19461936
/* Find the most compatiable size. */
19471937
for (i = 0; i < drmmode_cursor.num_dimensions; i++)
@@ -1952,34 +1942,28 @@ drmmode_load_cursor_argb_check(xf86CrtcPtr crtc, CARD32 *image)
19521942
dimensions.height >= cursor->bits->height) {
19531943
break;
19541944
}
1955-
1956-
if (dimensions.width > max_width ||
1957-
dimensions.height > max_height) {
1958-
1959-
/* If this ever happens, i should not be 0, but check for good measure */
1960-
if (i > 0) {
1961-
i--;
1962-
}
1963-
break;
1964-
}
19651945
}
19661946

1947+
const int cursor_pitch = drmmode_cursor_get_pitch(drmmode_crtc, i);
1948+
19671949
/* Get the resolution of the cursor. */
1968-
width = drmmode_cursor.dimensions[i].width;
1969-
height = drmmode_cursor.dimensions[i].height;
1950+
int cursor_width = drmmode_cursor.dimensions[i].width;
1951+
int cursor_height = drmmode_cursor.dimensions[i].height;
19701952

1971-
const int cursor_pitch = drmmode_cursor_get_pitch(drmmode_crtc, i);
1953+
/* Get the size of the cursor image buffer */
1954+
int image_width = ms->cursor_image_width;
1955+
int image_height = ms->cursor_image_height;
19721956

19731957
/* cursor should be mapped already */
1974-
drmmode_paint_cursor(drmmode_cursor.bo, cursor_pitch, width, height,
1975-
image, max_width, max_height,
1958+
drmmode_paint_cursor(drmmode_cursor.bo, cursor_pitch, cursor_width, cursor_height,
1959+
image, image_width, image_height,
19761960
drmmode_crtc, cursor->bits->width, cursor->bits->height);
19771961

19781962
/* set cursor width and height here for drmmode_show_cursor */
1979-
drmmode_crtc->cursor_width = width;
1980-
drmmode_crtc->cursor_height = height;
1963+
drmmode_crtc->cursor_width = cursor_width;
1964+
drmmode_crtc->cursor_height = cursor_height;
19811965

1982-
return drmmode_crtc->cursor_up ? drmmode_set_cursor(crtc, width, height) : TRUE;
1966+
return drmmode_crtc->cursor_up ? drmmode_set_cursor(crtc, cursor_width, cursor_height) : TRUE;
19831967
}
19841968

19851969
static void
@@ -4659,22 +4643,20 @@ drmmode_create_initial_bos(ScrnInfoPtr pScrn, drmmode_ptr drmmode)
46594643
{
46604644
modesettingPtr ms = modesettingPTR(pScrn);
46614645
xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
4662-
int width;
4663-
int height;
46644646
int bpp = ms->drmmode.kbpp;
4665-
int i;
46664647
int cpp = (bpp + 7) / 8;
46674648

4649+
int width, height;
4650+
uint32_t min_width = 1 << 30, min_height = 1 << 30;
4651+
46684652
width = pScrn->virtualX;
46694653
height = pScrn->virtualY;
46704654

46714655
if (!drmmode_create_bo(drmmode, &drmmode->front_bo, width, height, bpp))
46724656
return FALSE;
46734657
pScrn->displayWidth = drmmode_bo_get_pitch(&drmmode->front_bo) / cpp;
46744658

4675-
bpp = 32;
4676-
4677-
for (i = 0; i < xf86_config->num_crtc; i++) {
4659+
for (int i = 0; i < xf86_config->num_crtc; i++) {
46784660
xf86CrtcPtr crtc = xf86_config->crtc[i];
46794661
drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
46804662
drmmode_cursor_rec cursor = drmmode_crtc->cursor;
@@ -4683,13 +4665,22 @@ drmmode_create_initial_bos(ScrnInfoPtr pScrn, drmmode_ptr drmmode)
46834665
* something has gone terribly wrong. */
46844666
assert(cursor.num_dimensions);
46854667

4686-
/* Use the maximum available size. */
4687-
width = get_maximum_cursor_width(cursor);
4688-
height = get_maximum_cursor_height(cursor);
4668+
/* Use the minimum available size. */
4669+
width = cursor.dimensions[0].width;
4670+
height = cursor.dimensions[0].height;
4671+
4672+
/* We take the minimum of the sizes here
4673+
* so that we don't get a cursor glyph larger
4674+
* that a crtc's cursor buffer */
4675+
min_width = MIN(width, min_width);
4676+
min_height = MIN(height, min_height);
46894677

46904678
drmmode_crtc->cursor.bo = dumb_bo_create(drmmode->fd, width, height, bpp);
46914679
}
46924680

4681+
ms->cursor_image_width = min_width;
4682+
ms->cursor_image_height = min_height;
4683+
46934684
return TRUE;
46944685
}
46954686

@@ -4824,37 +4815,6 @@ drmmode_crtc_set_vrr(xf86CrtcPtr crtc, Bool enabled)
48244815
drmmode_crtc->vrr_enabled = enabled;
48254816
}
48264817

4827-
Bool drmmode_get_largest_cursor(ScrnInfoPtr pScrn, drmmode_cursor_dim_ptr cursor_lim)
4828-
{
4829-
xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
4830-
4831-
int max_width = 0, max_height = 0;
4832-
4833-
if (!cursor_lim)
4834-
return FALSE;
4835-
4836-
for (int i = 0; i < xf86_config->num_crtc; i++) {
4837-
xf86CrtcPtr crtc = xf86_config->crtc[i];
4838-
drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
4839-
drmmode_cursor_rec cursor = drmmode_crtc->cursor;
4840-
4841-
/* Get the largest cursor available. */
4842-
drmmode_cursor_dim_rec largest = cursor.dimensions[cursor.num_dimensions - 1];
4843-
4844-
int width = largest.width;
4845-
int height = largest.height;
4846-
4847-
/* Future work:
4848-
* - We should only let sizes that all CRTCs support. */
4849-
max_width = MAX(width, max_width);
4850-
max_height = MAX(height, max_height);
4851-
}
4852-
4853-
cursor_lim->width = max_width;
4854-
cursor_lim->height = max_height;
4855-
return TRUE;
4856-
}
4857-
48584818
/*
48594819
* We hook the screen's cursor-sprite (swcursor) functions to see if a swcursor
48604820
* is active. When a swcursor is active we disable page-flipping.

hw/xfree86/drivers/video/modesetting/drmmode_display.h

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -235,7 +235,8 @@ typedef struct {
235235

236236
uint64_t next_msc;
237237

238-
int cursor_width, cursor_height;
238+
int cursor_width;
239+
int cursor_height;
239240

240241
Bool need_modeset;
241242
struct xorg_list mode_list;
@@ -359,7 +360,4 @@ Bool drmmode_crtc_get_fb_id(xf86CrtcPtr crtc, uint32_t *fb_id, int *x, int *y);
359360

360361
void drmmode_set_dpms(ScrnInfoPtr scrn, int PowerManagementMode, int flags);
361362
void drmmode_crtc_set_vrr(xf86CrtcPtr crtc, Bool enabled);
362-
363-
Bool drmmode_get_largest_cursor(ScrnInfoPtr pScrn, drmmode_cursor_dim_ptr cursor_lim);
364-
365363
#endif

0 commit comments

Comments
 (0)