mirror of
https://github.com/X11Libre/xf86-video-ati.git
synced 2026-03-24 01:24:43 +00:00
Use two HW cursor buffers per CRTC
Switch to the other buffer when xf86_config->cursor changes. Avoids these issues possible when re-using the same buffer: * The HW may intermittently display a mix of the old and new cursor images. * If the hotspot changes, the HW may intermittently display the new cursor image at the location corresponding to the old image's hotspot. Bugzilla: https://bugs.freedesktop.org/108832 (Ported from amdgpu commit 0d60233d26ec70d4e1faa343b438e33829c6d5e4)
This commit is contained in:
committed by
Michel Dänzer
parent
91e557f78a
commit
803f872f7d
@@ -1122,13 +1122,18 @@ drmmode_load_cursor_argb (xf86CrtcPtr crtc, CARD32 *image)
|
||||
ScrnInfoPtr pScrn = crtc->scrn;
|
||||
RADEONInfoPtr info = RADEONPTR(pScrn);
|
||||
drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
|
||||
unsigned id = drmmode_crtc->cursor_id;
|
||||
Bool premultiplied = TRUE;
|
||||
Bool apply_gamma = TRUE;
|
||||
uint32_t argb;
|
||||
uint32_t *ptr;
|
||||
|
||||
if (drmmode_crtc->cursor &&
|
||||
XF86_CRTC_CONFIG_PTR(pScrn)->cursor != drmmode_crtc->cursor)
|
||||
id ^= 1;
|
||||
|
||||
/* cursor should be mapped already */
|
||||
ptr = (uint32_t *)(drmmode_crtc->cursor_bo->ptr);
|
||||
ptr = (uint32_t *)(drmmode_crtc->cursor_bo[id]->ptr);
|
||||
|
||||
if (crtc->scrn->depth != 24 && crtc->scrn->depth != 32)
|
||||
apply_gamma = FALSE;
|
||||
@@ -1170,6 +1175,11 @@ retry:
|
||||
ptr[i] = cpu_to_le32(argb);
|
||||
}
|
||||
}
|
||||
|
||||
if (id != drmmode_crtc->cursor_id) {
|
||||
drmmode_crtc->cursor_id = id;
|
||||
crtc->funcs->show_cursor(crtc);
|
||||
}
|
||||
}
|
||||
|
||||
#if XORG_VERSION_CURRENT >= XORG_VERSION_NUMERIC(1,15,99,903,0)
|
||||
@@ -1195,7 +1205,7 @@ drmmode_hide_cursor (xf86CrtcPtr crtc)
|
||||
|
||||
drmModeSetCursor(pRADEONEnt->fd, drmmode_crtc->mode_crtc->crtc_id, 0,
|
||||
info->cursor_w, info->cursor_h);
|
||||
|
||||
drmmode_crtc->cursor = NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -1212,9 +1222,11 @@ drmmode_show_cursor (xf86CrtcPtr crtc)
|
||||
static Bool use_set_cursor2 = TRUE;
|
||||
struct drm_mode_cursor2 arg;
|
||||
|
||||
drmmode_crtc->cursor = xf86_config->cursor;
|
||||
|
||||
memset(&arg, 0, sizeof(arg));
|
||||
|
||||
arg.handle = drmmode_crtc->cursor_bo->handle;
|
||||
arg.handle = drmmode_crtc->cursor_bo[drmmode_crtc->cursor_id]->handle;
|
||||
arg.flags = DRM_MODE_CURSOR_BO;
|
||||
arg.crtc_id = drmmode_crtc->mode_crtc->crtc_id;
|
||||
arg.width = info->cursor_w;
|
||||
|
||||
@@ -88,11 +88,14 @@ typedef struct {
|
||||
drmModeCrtcPtr mode_crtc;
|
||||
int hw_id;
|
||||
|
||||
CursorPtr cursor;
|
||||
int cursor_x;
|
||||
int cursor_y;
|
||||
int cursor_xhot;
|
||||
int cursor_yhot;
|
||||
struct radeon_bo *cursor_bo;
|
||||
unsigned cursor_id;
|
||||
struct radeon_bo *cursor_bo[2];
|
||||
|
||||
struct drmmode_scanout rotate;
|
||||
struct drmmode_scanout scanout[2];
|
||||
DamagePtr scanout_damage;
|
||||
|
||||
@@ -2755,27 +2755,29 @@ static Bool radeon_setup_kernel_mem(ScreenPtr pScreen)
|
||||
|
||||
{
|
||||
int cursor_size;
|
||||
int c;
|
||||
int c, i;
|
||||
|
||||
cursor_size = info->cursor_w * info->cursor_h * 4;
|
||||
cursor_size = RADEON_ALIGN(cursor_size, RADEON_GPU_PAGE_SIZE);
|
||||
for (c = 0; c < xf86_config->num_crtc; c++) {
|
||||
drmmode_crtc_private_ptr drmmode_crtc = xf86_config->crtc[c]->driver_private;
|
||||
|
||||
if (!drmmode_crtc->cursor_bo) {
|
||||
drmmode_crtc->cursor_bo = radeon_bo_open(info->bufmgr, 0,
|
||||
cursor_size, 0,
|
||||
RADEON_GEM_DOMAIN_VRAM, 0);
|
||||
if (!(drmmode_crtc->cursor_bo)) {
|
||||
ErrorF("Failed to allocate cursor buffer memory\n");
|
||||
return FALSE;
|
||||
}
|
||||
for (i = 0; i < 2; i++) {
|
||||
if (!drmmode_crtc->cursor_bo[i]) {
|
||||
drmmode_crtc->cursor_bo[i] =
|
||||
radeon_bo_open(info->bufmgr, 0, cursor_size, 0,
|
||||
RADEON_GEM_DOMAIN_VRAM, 0);
|
||||
|
||||
if (radeon_bo_map(drmmode_crtc->cursor_bo, 1)) {
|
||||
ErrorF("Failed to map cursor buffer memory\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!(drmmode_crtc->cursor_bo[i])) {
|
||||
ErrorF("Failed to allocate cursor buffer memory\n");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (radeon_bo_map(drmmode_crtc->cursor_bo[i], 1))
|
||||
ErrorF("Failed to map cursor buffer memory\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!info->front_buffer) {
|
||||
@@ -2841,7 +2843,7 @@ void radeon_kms_update_vram_limit(ScrnInfoPtr pScrn, uint32_t new_fb_size)
|
||||
for (c = 0; c < xf86_config->num_crtc; c++) {
|
||||
drmmode_crtc_private_ptr drmmode_crtc = xf86_config->crtc[c]->driver_private;
|
||||
|
||||
if (drmmode_crtc->cursor_bo)
|
||||
if (drmmode_crtc->cursor_bo[0])
|
||||
new_fb_size += (64 * 4 * 64);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user