mirror of
https://github.com/X11Libre/xserver.git
synced 2026-04-14 17:18:09 +00:00
hw/modesetting: Fix up cursor size probing.
modesetting has a sort of broken concept of getting the cursor dimensions since 1f41320e1c, which causes issues on virtual machines and older AMD hardware. Our solution is to use SIZE_HINTS which is available in i915 since 2023 otherwise fallback to getting the cursor size provided by the driver, if a driver wants to have a more optimal cursor size, it is more than welcome to implement SIZE_HINTS in it's DRM interface.
Taken from my own fork of Xorg.
v2: Fix some bugs in the implemenation.
This commit is contained in:
committed by
Enrico Weigelt
parent
e7455f48a3
commit
e6c980f08e
@@ -1228,17 +1228,6 @@ PreInit(ScrnInfoPtr pScrn, int flags)
|
||||
ms->drmmode.sw_cursor = TRUE;
|
||||
}
|
||||
|
||||
ms->max_cursor_width = 64;
|
||||
ms->max_cursor_height = 64;
|
||||
ret = drmGetCap(ms->fd, DRM_CAP_CURSOR_WIDTH, &value);
|
||||
if (!ret) {
|
||||
ms->max_cursor_width = value;
|
||||
}
|
||||
ret = drmGetCap(ms->fd, DRM_CAP_CURSOR_HEIGHT, &value);
|
||||
if (!ret) {
|
||||
ms->max_cursor_height = value;
|
||||
}
|
||||
|
||||
try_enable_glamor(pScrn);
|
||||
|
||||
if (!ms->drmmode.glamor) {
|
||||
@@ -1964,9 +1953,14 @@ ScreenInit(ScreenPtr pScreen, int argc, char **argv)
|
||||
PointPriv->spriteFuncs = &drmmode_sprite_funcs;
|
||||
}
|
||||
|
||||
/* Get the maximum cursor size. */
|
||||
drmmode_cursor_dim_rec cursor_dim = { 0 };
|
||||
if (!drmmode_get_largest_cursor(pScrn, &cursor_dim))
|
||||
return FALSE;
|
||||
|
||||
/* Need to extend HWcursor support to handle mask interleave */
|
||||
if (!ms->drmmode.sw_cursor)
|
||||
xf86_cursors_init(pScreen, ms->max_cursor_width, ms->max_cursor_height,
|
||||
xf86_cursors_init(pScreen, cursor_dim.width, cursor_dim.height,
|
||||
HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_64 |
|
||||
HARDWARE_CURSOR_UPDATE_UNHIDDEN |
|
||||
HARDWARE_CURSOR_ARGB);
|
||||
|
||||
@@ -131,9 +131,6 @@ typedef struct _modesettingRec {
|
||||
DamagePtr damage;
|
||||
Bool dirty_enabled;
|
||||
|
||||
uint32_t min_cursor_width, min_cursor_height;
|
||||
uint32_t max_cursor_width, max_cursor_height;
|
||||
|
||||
Bool has_queue_sequence;
|
||||
Bool tried_queue_sequence;
|
||||
|
||||
|
||||
@@ -1795,7 +1795,7 @@ drmmode_set_cursor(xf86CrtcPtr crtc, int width, int height)
|
||||
{
|
||||
drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
|
||||
drmmode_ptr drmmode = drmmode_crtc->drmmode;
|
||||
uint32_t handle = drmmode_crtc->cursor_bo->handle;
|
||||
uint32_t handle = drmmode_crtc->cursor.bo->handle;
|
||||
CursorPtr cursor = xf86CurrentCursor(crtc->scrn->pScreen);
|
||||
int ret = -EINVAL;
|
||||
|
||||
@@ -1835,6 +1835,18 @@ drmmode_set_cursor(xf86CrtcPtr crtc, int width, int height)
|
||||
|
||||
static void drmmode_hide_cursor(xf86CrtcPtr crtc);
|
||||
|
||||
static inline int
|
||||
get_maximum_cursor_width(drmmode_cursor_rec cursor)
|
||||
{
|
||||
return cursor.dimensions[cursor.num_dimensions - 1].width;
|
||||
}
|
||||
|
||||
static inline int
|
||||
get_maximum_cursor_height(drmmode_cursor_rec cursor)
|
||||
{
|
||||
return cursor.dimensions[cursor.num_dimensions - 1].height;
|
||||
}
|
||||
|
||||
/*
|
||||
* The load_cursor_argb_check driver hook.
|
||||
*
|
||||
@@ -1845,45 +1857,49 @@ static void drmmode_hide_cursor(xf86CrtcPtr crtc);
|
||||
static Bool
|
||||
drmmode_load_cursor_argb_check(xf86CrtcPtr crtc, CARD32 *image)
|
||||
{
|
||||
modesettingPtr ms = modesettingPTR(crtc->scrn);
|
||||
CursorPtr cursor = xf86CurrentCursor(crtc->scrn->pScreen);
|
||||
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 max_width, max_height;
|
||||
uint32_t *ptr;
|
||||
|
||||
/* cursor should be mapped already */
|
||||
ptr = (uint32_t *) (drmmode_crtc->cursor_bo->ptr);
|
||||
ptr = (uint32_t *) (drmmode_cursor.bo->ptr);
|
||||
|
||||
/* FIXME deal with rotation */
|
||||
if (crtc->rotation == RR_Rotate_0) {
|
||||
for (width = ms->min_cursor_width; width < cursor->bits->width; )
|
||||
width *= 2;
|
||||
for (height = ms->min_cursor_height; height < cursor->bits->height; )
|
||||
height *= 2;
|
||||
/* We need to know what our limit is for HW cursors. */
|
||||
max_width = get_maximum_cursor_width(drmmode_cursor);
|
||||
max_height = get_maximum_cursor_height(drmmode_cursor);
|
||||
|
||||
/* assume only square works for now */
|
||||
width = height = max(width, height);
|
||||
/* Find the most compatiable size. */
|
||||
for (i = 0; i < drmmode_cursor.num_dimensions; i++)
|
||||
{
|
||||
drmmode_cursor_dim_rec dimensions = drmmode_cursor.dimensions[i];
|
||||
|
||||
/* if the max limits aren't square+POT we may have gone a bit over */
|
||||
width = min(width, ms->max_cursor_width);
|
||||
height = min(height, ms->max_cursor_height);
|
||||
} else {
|
||||
width = ms->max_cursor_width;
|
||||
height = ms->max_cursor_height;
|
||||
if (dimensions.width > cursor->bits->width &&
|
||||
dimensions.height > cursor->bits->height)
|
||||
break;
|
||||
}
|
||||
|
||||
/* Get the resolution of the cursor. */
|
||||
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 * ms->max_cursor_width + x]; // cpu_to_le32(image[i]);
|
||||
ptr[i++] = image[y * max_width + x];
|
||||
}
|
||||
/* clear the remainder for good measure */
|
||||
for (; i < ms->max_cursor_width * ms->max_cursor_height; i++)
|
||||
|
||||
/* Clear the remainder for good measure. */
|
||||
for (; i < max_width * max_height; i++)
|
||||
ptr[i++] = 0;
|
||||
|
||||
if (drmmode_crtc->cursor_up)
|
||||
return drmmode_set_cursor(crtc, width, height);
|
||||
return TRUE;
|
||||
else
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -2262,6 +2278,7 @@ drmmode_crtc_destroy(xf86CrtcPtr crtc)
|
||||
return;
|
||||
|
||||
drmmode_prop_info_free(drmmode_crtc->props_plane, DRMMODE_PLANE__COUNT);
|
||||
free(drmmode_crtc->cursor.dimensions);
|
||||
xorg_list_for_each_entry_safe(iterator, next, &drmmode_crtc->mode_list, entry) {
|
||||
drm_mode_destroy(crtc, iterator);
|
||||
}
|
||||
@@ -2372,6 +2389,152 @@ populate_format_modifiers(xf86CrtcPtr crtc, const drmModePlane *kplane,
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
#ifdef LIBDRM_PLANE_SIZE_HINTS
|
||||
static void
|
||||
populate_cursor_sizes(drmmode_ptr drmmode, drmmode_crtc_private_ptr drmmode_crtc, int size_hints_blob)
|
||||
{
|
||||
drmModePropertyBlobRes *blob;
|
||||
|
||||
if (!drmmode_crtc)
|
||||
return;
|
||||
|
||||
if (!size_hints_blob)
|
||||
return;
|
||||
|
||||
blob = drmModeGetPropertyBlob(drmmode->fd, size_hints_blob);
|
||||
|
||||
if (!blob)
|
||||
return;
|
||||
|
||||
if (!blob->length)
|
||||
goto fail;
|
||||
|
||||
const struct drm_plane_size_hint *size_hints = blob->data;
|
||||
size_t size_hints_len = blob->length / sizeof(size_hints[0]);
|
||||
|
||||
if (!size_hints_len)
|
||||
goto fail;
|
||||
|
||||
drmmode_crtc->cursor.num_dimensions = size_hints_len;
|
||||
drmmode_crtc->cursor.dimensions = xnfrealloc(drmmode_crtc->cursor.dimensions, size_hints_len * sizeof(drmmode_cursor_dim_rec));
|
||||
|
||||
for (int idx = 0; idx < size_hints_len; idx++)
|
||||
{
|
||||
struct drm_plane_size_hint size_hint = size_hints[idx];
|
||||
|
||||
drmmode_crtc->cursor.dimensions[idx].width = size_hint.width;
|
||||
drmmode_crtc->cursor.dimensions[idx].height = size_hint.height;
|
||||
}
|
||||
fail:
|
||||
drmModeFreePropertyBlob(blob);
|
||||
}
|
||||
|
||||
static void
|
||||
drmmode_crtc_probe_size_hint(xf86CrtcPtr crtc, int num)
|
||||
{
|
||||
drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
|
||||
drmmode_ptr drmmode = drmmode_crtc->drmmode;
|
||||
drmModePlaneRes *kplane_res;
|
||||
drmModeObjectProperties *props;
|
||||
drmModePlane *kplane = NULL;
|
||||
uint32_t i, type;
|
||||
|
||||
static drmmode_prop_enum_info_rec plane_type_enums[] = {
|
||||
[DRMMODE_PLANE_TYPE_PRIMARY] = {
|
||||
.name = "Primary",
|
||||
},
|
||||
[DRMMODE_PLANE_TYPE_OVERLAY] = {
|
||||
.name = "Overlay",
|
||||
},
|
||||
[DRMMODE_PLANE_TYPE_CURSOR] = {
|
||||
.name = "Cursor",
|
||||
},
|
||||
};
|
||||
static const drmmode_prop_info_rec plane_props[] = {
|
||||
[DRMMODE_PLANE_TYPE] = {
|
||||
.name = "type",
|
||||
.enum_values = plane_type_enums,
|
||||
.num_enum_values = DRMMODE_PLANE_TYPE__COUNT,
|
||||
},
|
||||
[DRMMODE_PLANE_FB_ID] = { .name = "FB_ID", },
|
||||
[DRMMODE_PLANE_CRTC_ID] = { .name = "CRTC_ID", },
|
||||
[DRMMODE_PLANE_IN_FORMATS] = { .name = "IN_FORMATS", },
|
||||
[DRMMODE_PLANE_SRC_X] = { .name = "SRC_X", },
|
||||
[DRMMODE_PLANE_SRC_Y] = { .name = "SRC_Y", },
|
||||
[DRMMODE_PLANE_SRC_W] = { .name = "SRC_W", },
|
||||
[DRMMODE_PLANE_SRC_H] = { .name = "SRC_H", },
|
||||
[DRMMODE_PLANE_CRTC_X] = { .name = "CRTC_X", },
|
||||
[DRMMODE_PLANE_CRTC_Y] = { .name = "CRTC_Y", },
|
||||
[DRMMODE_PLANE_CRTC_W] = { .name = "CRTC_W", },
|
||||
[DRMMODE_PLANE_CRTC_H] = { .name = "CRTC_H", },
|
||||
[DRMMODE_PLANE_SIZE_HINTS] = { .name = "SIZE_HINTS" }
|
||||
};
|
||||
drmmode_prop_info_rec tmp_props[DRMMODE_PLANE__COUNT];
|
||||
|
||||
if (!drmmode_prop_info_copy(tmp_props, plane_props, DRMMODE_PLANE__COUNT, 0)) {
|
||||
xf86DrvMsg(drmmode->scrn->scrnIndex, X_ERROR,
|
||||
"failed to copy plane property info\n");
|
||||
drmmode_prop_info_free(tmp_props, DRMMODE_PLANE__COUNT);
|
||||
return;
|
||||
}
|
||||
|
||||
kplane_res = drmModeGetPlaneResources(drmmode->fd);
|
||||
if (!kplane_res) {
|
||||
xf86DrvMsg(drmmode->scrn->scrnIndex, X_ERROR,
|
||||
"failed to get plane resources: %s\n", strerror(errno));
|
||||
drmmode_prop_info_free(tmp_props, DRMMODE_PLANE__COUNT);
|
||||
return;
|
||||
}
|
||||
|
||||
for (i = 0; i < kplane_res->count_planes; i++) {
|
||||
int plane_id;
|
||||
|
||||
kplane = drmModeGetPlane(drmmode->fd, kplane_res->planes[i]);
|
||||
if (!kplane)
|
||||
continue;
|
||||
|
||||
if (!(kplane->possible_crtcs & (1 << num)) ||
|
||||
is_plane_assigned(drmmode->scrn, kplane->plane_id)) {
|
||||
drmModeFreePlane(kplane);
|
||||
continue;
|
||||
}
|
||||
|
||||
plane_id = kplane->plane_id;
|
||||
|
||||
props = drmModeObjectGetProperties(drmmode->fd, plane_id,
|
||||
DRM_MODE_OBJECT_PLANE);
|
||||
if (!props) {
|
||||
xf86DrvMsg(drmmode->scrn->scrnIndex, X_ERROR,
|
||||
"couldn't get plane properties\n");
|
||||
drmModeFreePlane(kplane);
|
||||
continue;
|
||||
}
|
||||
|
||||
drmmode_prop_info_update(drmmode, tmp_props, DRMMODE_PLANE__COUNT, props);
|
||||
|
||||
/* We need cursor planes only. */
|
||||
type = drmmode_prop_get_value(&tmp_props[DRMMODE_PLANE_TYPE],
|
||||
props, DRMMODE_PLANE_TYPE__COUNT);
|
||||
|
||||
if (type != DRMMODE_PLANE_TYPE_CURSOR) {
|
||||
drmModeFreePlane(kplane);
|
||||
drmModeFreeObjectProperties(props);
|
||||
continue;
|
||||
}
|
||||
|
||||
int size_hint = drmmode_prop_get_value(&tmp_props[DRMMODE_PLANE_SIZE_HINTS], props, 0);
|
||||
populate_cursor_sizes(drmmode, drmmode_crtc, size_hint);
|
||||
|
||||
drmModeFreePlane(kplane);
|
||||
drmModeFreeObjectProperties(props);
|
||||
break;
|
||||
}
|
||||
|
||||
drmmode_prop_info_free(tmp_props, DRMMODE_PLANE__COUNT);
|
||||
drmModeFreePlaneResources(kplane_res);
|
||||
}
|
||||
#endif
|
||||
|
||||
static void
|
||||
drmmode_crtc_create_planes(xf86CrtcPtr crtc, int num)
|
||||
{
|
||||
@@ -2411,6 +2574,7 @@ drmmode_crtc_create_planes(xf86CrtcPtr crtc, int num)
|
||||
[DRMMODE_PLANE_CRTC_Y] = { .name = "CRTC_Y", },
|
||||
[DRMMODE_PLANE_CRTC_W] = { .name = "CRTC_W", },
|
||||
[DRMMODE_PLANE_CRTC_H] = { .name = "CRTC_H", },
|
||||
[DRMMODE_PLANE_SIZE_HINTS] = { .name = "SIZE_HINTS" }
|
||||
};
|
||||
drmmode_prop_info_rec tmp_props[DRMMODE_PLANE__COUNT];
|
||||
|
||||
@@ -2458,6 +2622,7 @@ drmmode_crtc_create_planes(xf86CrtcPtr crtc, int num)
|
||||
/* Only primary planes are important for atomic page-flipping */
|
||||
type = drmmode_prop_get_value(&tmp_props[DRMMODE_PLANE_TYPE],
|
||||
props, DRMMODE_PLANE_TYPE__COUNT);
|
||||
|
||||
if (type != DRMMODE_PLANE_TYPE_PRIMARY) {
|
||||
drmModeFreePlane(kplane);
|
||||
drmModeFreeObjectProperties(props);
|
||||
@@ -2560,7 +2725,7 @@ drmmode_crtc_vrr_init(int drm_fd, xf86CrtcPtr crtc)
|
||||
}
|
||||
|
||||
static unsigned int
|
||||
drmmode_crtc_init(ScrnInfoPtr pScrn, drmmode_ptr drmmode, drmModeResPtr mode_res, int num)
|
||||
drmmode_crtc_init(ScrnInfoPtr pScrn, drmmode_ptr drmmode, drmModeResPtr mode_res, drmmode_cursor_dim_rec fallback, int num)
|
||||
{
|
||||
xf86CrtcPtr crtc;
|
||||
drmmode_crtc_private_ptr drmmode_crtc;
|
||||
@@ -2587,6 +2752,13 @@ drmmode_crtc_init(ScrnInfoPtr pScrn, drmmode_ptr drmmode, drmModeResPtr mode_res
|
||||
xorg_list_init(&drmmode_crtc->tearfree.dri_flip_list);
|
||||
drmmode_crtc->next_msc = UINT64_MAX;
|
||||
|
||||
/* Setup the fallback cursor immediately. */
|
||||
drmmode_crtc->cursor.num_dimensions = 1;
|
||||
drmmode_crtc->cursor.dimensions = xnfalloc(sizeof(drmmode_cursor_dim_rec));
|
||||
|
||||
drmmode_crtc->cursor.dimensions[0].width = fallback.width;
|
||||
drmmode_crtc->cursor.dimensions[0].height = fallback.height;
|
||||
|
||||
props = drmModeObjectGetProperties(drmmode->fd, mode_res->crtcs[num],
|
||||
DRM_MODE_OBJECT_CRTC);
|
||||
if (!props || !drmmode_prop_info_copy(drmmode_crtc->props, crtc_props,
|
||||
@@ -2600,6 +2772,11 @@ drmmode_crtc_init(ScrnInfoPtr pScrn, drmmode_ptr drmmode, drmModeResPtr mode_res
|
||||
drmModeFreeObjectProperties(props);
|
||||
drmmode_crtc_create_planes(crtc, num);
|
||||
|
||||
#ifdef LIBDRM_PLANE_SIZE_HINTS
|
||||
/* Get the SIZE_HINT dimensions, if supported. */
|
||||
drmmode_crtc_probe_size_hint(crtc, num);
|
||||
#endif
|
||||
|
||||
/* Hide any cursors which may be active from previous users */
|
||||
drmModeSetCursor(drmmode->fd, drmmode_crtc->mode_crtc->crtc_id, 0, 0, 0);
|
||||
|
||||
@@ -3905,12 +4082,29 @@ drmmode_pre_init(ScrnInfoPtr pScrn, drmmode_ptr drmmode, int cpp)
|
||||
xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, MS_LOGLEVEL_DEBUG,
|
||||
"Up to %d crtcs needed for screen.\n", crtcs_needed);
|
||||
|
||||
/* This is the safest fallback value as
|
||||
* it is the default value that KMS uses. */
|
||||
drmmode_cursor_dim_rec fallback = {
|
||||
.width = 64,
|
||||
.height = 64,
|
||||
};
|
||||
|
||||
ret = drmGetCap(drmmode->fd, DRM_CAP_CURSOR_WIDTH, &value);
|
||||
if (!ret) {
|
||||
fallback.width = value;
|
||||
}
|
||||
|
||||
ret = drmGetCap(drmmode->fd, DRM_CAP_CURSOR_HEIGHT, &value);
|
||||
if (!ret) {
|
||||
fallback.height = value;
|
||||
}
|
||||
|
||||
xf86CrtcSetSizeRange(pScrn, 320, 200, mode_res->max_width,
|
||||
mode_res->max_height);
|
||||
for (i = 0; i < mode_res->count_crtcs; i++)
|
||||
if (!xf86IsEntityShared(pScrn->entityList[0]) ||
|
||||
(crtcs_needed && !(ms_ent->assigned_crtcs & (1 << i))))
|
||||
crtcs_needed -= drmmode_crtc_init(pScrn, drmmode, mode_res, i);
|
||||
crtcs_needed -= drmmode_crtc_init(pScrn, drmmode, mode_res, fallback, i);
|
||||
|
||||
/* All ZaphodHeads outputs provided with matching crtcs? */
|
||||
if (xf86IsEntityShared(pScrn->entityList[0]) && (crtcs_needed > 0))
|
||||
@@ -4378,55 +4572,6 @@ drmmode_uevent_fini(ScrnInfoPtr scrn, drmmode_ptr drmmode)
|
||||
#endif
|
||||
}
|
||||
|
||||
static void drmmode_probe_cursor_size(xf86CrtcPtr crtc)
|
||||
{
|
||||
modesettingPtr ms = modesettingPTR(crtc->scrn);
|
||||
drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
|
||||
uint32_t handle = drmmode_crtc->cursor_bo->handle;
|
||||
drmmode_ptr drmmode = drmmode_crtc->drmmode;
|
||||
int width, height, size;
|
||||
|
||||
ms->min_cursor_width = ms->max_cursor_width;
|
||||
ms->min_cursor_height = ms->max_cursor_height;
|
||||
|
||||
/* probe square min first */
|
||||
for (size = 1; size <= ms->max_cursor_width &&
|
||||
size <= ms->max_cursor_height; size *= 2) {
|
||||
int ret;
|
||||
|
||||
ret = drmModeSetCursor2(drmmode->fd, drmmode_crtc->mode_crtc->crtc_id,
|
||||
handle, size, size, 0, 0);
|
||||
if (ret == 0)
|
||||
break;
|
||||
}
|
||||
|
||||
/* check if smaller width works with non-square */
|
||||
for (width = 1; width <= size; width *= 2) {
|
||||
int ret;
|
||||
|
||||
ret = drmModeSetCursor2(drmmode->fd, drmmode_crtc->mode_crtc->crtc_id,
|
||||
handle, width, size, 0, 0);
|
||||
if (ret == 0) {
|
||||
ms->min_cursor_width = width;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* check if smaller height works with non-square */
|
||||
for (height = 1; height <= size; height *= 2) {
|
||||
int ret;
|
||||
|
||||
ret = drmModeSetCursor2(drmmode->fd, drmmode_crtc->mode_crtc->crtc_id,
|
||||
handle, size, height, 0, 0);
|
||||
if (ret == 0) {
|
||||
ms->min_cursor_height = height;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
drmModeSetCursor2(drmmode->fd, drmmode_crtc->mode_crtc->crtc_id, 0, 0, 0, 0, 0);
|
||||
}
|
||||
|
||||
/* create front and cursor BOs */
|
||||
Bool
|
||||
drmmode_create_initial_bos(ScrnInfoPtr pScrn, drmmode_ptr drmmode)
|
||||
@@ -4446,24 +4591,24 @@ drmmode_create_initial_bos(ScrnInfoPtr pScrn, drmmode_ptr drmmode)
|
||||
return FALSE;
|
||||
pScrn->displayWidth = drmmode_bo_get_pitch(&drmmode->front_bo) / cpp;
|
||||
|
||||
width = ms->max_cursor_width;
|
||||
height = ms->max_cursor_height;
|
||||
bpp = 32;
|
||||
|
||||
for (i = 0; i < xf86_config->num_crtc; i++) {
|
||||
xf86CrtcPtr crtc = xf86_config->crtc[i];
|
||||
drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
|
||||
drmmode_cursor_rec cursor = drmmode_crtc->cursor;
|
||||
|
||||
/* If we don't have any dimensions then
|
||||
* something has gone terribly wrong. */
|
||||
assert(cursor.num_dimensions);
|
||||
|
||||
drmmode_crtc->cursor_bo =
|
||||
dumb_bo_create(drmmode->fd, width, height, bpp);
|
||||
/* Use the maximum available size. */
|
||||
width = get_maximum_cursor_width(cursor);
|
||||
height = get_maximum_cursor_height(cursor);
|
||||
|
||||
drmmode_crtc->cursor.bo = dumb_bo_create(drmmode->fd, width, height, bpp);
|
||||
}
|
||||
|
||||
drmmode_probe_cursor_size(xf86_config->crtc[0]);
|
||||
|
||||
xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, MS_LOGLEVEL_DEBUG,
|
||||
"Supported cursor sizes %dx%d -> %dx%d\n",
|
||||
ms->min_cursor_width, ms->min_cursor_height,
|
||||
ms->max_cursor_width, ms->max_cursor_height);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@@ -4498,7 +4643,7 @@ drmmode_map_cursor_bos(ScrnInfoPtr pScrn, drmmode_ptr drmmode)
|
||||
xf86CrtcPtr crtc = xf86_config->crtc[i];
|
||||
drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
|
||||
|
||||
ret = dumb_bo_map(drmmode->fd, drmmode_crtc->cursor_bo);
|
||||
ret = dumb_bo_map(drmmode->fd, drmmode_crtc->cursor.bo);
|
||||
if (ret)
|
||||
return FALSE;
|
||||
}
|
||||
@@ -4522,7 +4667,7 @@ drmmode_free_bos(ScrnInfoPtr pScrn, drmmode_ptr drmmode)
|
||||
xf86CrtcPtr crtc = xf86_config->crtc[i];
|
||||
drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
|
||||
|
||||
dumb_bo_destroy(drmmode->fd, drmmode_crtc->cursor_bo);
|
||||
dumb_bo_destroy(drmmode->fd, drmmode_crtc->cursor.bo);
|
||||
drmmode_destroy_tearfree_shadow(crtc);
|
||||
}
|
||||
}
|
||||
@@ -4598,7 +4743,7 @@ drmmode_crtc_set_vrr(xf86CrtcPtr crtc, Bool enabled)
|
||||
drmmode_crtc->vrr_enabled = enabled;
|
||||
}
|
||||
|
||||
Bool drmmode_get_cursor_limit(ScrnInfoPtr pScrn, drmmode_cursor_dim_ptr cursor_lim)
|
||||
Bool drmmode_get_largest_cursor(ScrnInfoPtr pScrn, drmmode_cursor_dim_ptr cursor_lim)
|
||||
{
|
||||
xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
|
||||
int max_width = 0, max_height = 0, i;
|
||||
@@ -4611,15 +4756,14 @@ Bool drmmode_get_cursor_limit(ScrnInfoPtr pScrn, drmmode_cursor_dim_ptr cursor_l
|
||||
drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
|
||||
drmmode_cursor_rec cursor = drmmode_crtc->cursor;
|
||||
|
||||
/* Very ugly. */
|
||||
/* Get the largest cursor available. */
|
||||
drmmode_cursor_dim_rec largest = cursor.dimensions[cursor.num_dimensions - 1];
|
||||
|
||||
int width = largest.width;
|
||||
int height = largest.height;
|
||||
|
||||
/**
|
||||
* TODO: We should only let sizes that all CRTCs support.
|
||||
*/
|
||||
/* Future work:
|
||||
* - We should only let sizes that all CRTCs support. */
|
||||
if (width > max_width && height > max_height)
|
||||
{
|
||||
max_width = width;
|
||||
|
||||
@@ -191,6 +191,7 @@ typedef struct {
|
||||
typedef struct {
|
||||
uint16_t num_dimensions;
|
||||
|
||||
/* Sorted from smallest to largest. */
|
||||
drmmode_cursor_dim_rec* dimensions;
|
||||
struct dumb_bo *bo;
|
||||
} drmmode_cursor_rec, *drmmode_cursor_ptr;
|
||||
@@ -200,7 +201,7 @@ typedef struct {
|
||||
drmModeCrtcPtr mode_crtc;
|
||||
uint32_t vblank_pipe;
|
||||
int dpms_mode;
|
||||
struct dumb_bo *cursor_bo;
|
||||
drmmode_cursor_rec cursor;
|
||||
Bool cursor_up;
|
||||
uint16_t lut_r[256], lut_g[256], lut_b[256];
|
||||
|
||||
@@ -355,6 +356,6 @@ Bool drmmode_crtc_get_fb_id(xf86CrtcPtr crtc, uint32_t *fb_id, int *x, int *y);
|
||||
void drmmode_set_dpms(ScrnInfoPtr scrn, int PowerManagementMode, int flags);
|
||||
void drmmode_crtc_set_vrr(xf86CrtcPtr crtc, Bool enabled);
|
||||
|
||||
Bool drmmode_get_cursor_limit(ScrnInfoPtr pScrn, drmmode_cursor_dim_ptr cursor_lim);
|
||||
Bool drmmode_get_largest_cursor(ScrnInfoPtr pScrn, drmmode_cursor_dim_ptr cursor_lim);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -101,6 +101,7 @@ conf_data.set('CONFIG_WSCONS', host_machine.system() in ['openbsd', 'netbsd'] ?
|
||||
|
||||
conf_data.set('HAVE_XSHMFENCE', xshmfence_dep.found() ? '1' : false)
|
||||
conf_data.set('WITH_LIBDRM', libdrm_required ? '1' : false)
|
||||
conf_data.set('LIBDRM_PLANE_SIZE_HINTS', libdrm_required ? libdrm_dep.version().version_compare('>= 2.4.122') : false)
|
||||
conf_data.set('GLAMOR_HAS_EGL_QUERY_DMABUF',
|
||||
epoxy_dep.found() and epoxy_dep.version().version_compare('>= 1.4.4') ? '1' : false)
|
||||
conf_data.set('GLAMOR_HAS_EGL_QUERY_DRIVER',
|
||||
|
||||
Reference in New Issue
Block a user