mirror of
https://github.com/X11Libre/xf86-video-amdgpu.git
synced 2026-03-24 01:24:31 +00:00
Simplify tracking of PRIME scanout pixmap
Remember the shared pixmap passed to drmmode_set_scanout_pixmap for each CRTC, and just compare against that. Fixes leaving stale entries in ScreenRec::pixmap_dirty_list under some circumstances, which would usually result in use-after-free and a crash down the line. (Ported from radeon commit 7dc68e26755466f9056f8c72195ab8690660693d) Reviewed-by: Alex Deucher <alexander.deucher@amd.com>
This commit is contained in:
committed by
Michel Dänzer
parent
8cb41b962e
commit
2ea2d4d827
@@ -562,8 +562,7 @@ amdgpu_prime_dirty_to_crtc(PixmapDirtyUpdatePtr dirty)
|
||||
xf86CrtcPtr xf86_crtc = xf86_config->crtc[c];
|
||||
drmmode_crtc_private_ptr drmmode_crtc = xf86_crtc->driver_private;
|
||||
|
||||
if (drmmode_crtc->scanout[0].pixmap == dirty->slave_dst ||
|
||||
drmmode_crtc->scanout[1].pixmap == dirty->slave_dst)
|
||||
if (drmmode_crtc->prime_scanout_pixmap == dirty->src)
|
||||
return xf86_crtc;
|
||||
}
|
||||
|
||||
@@ -576,13 +575,11 @@ amdgpu_prime_scanout_do_update(xf86CrtcPtr crtc, unsigned scanout_id)
|
||||
ScrnInfoPtr scrn = crtc->scrn;
|
||||
ScreenPtr screen = scrn->pScreen;
|
||||
drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
|
||||
PixmapPtr scanoutpix = crtc->randr_crtc->scanout_pixmap;
|
||||
PixmapDirtyUpdatePtr dirty;
|
||||
Bool ret = FALSE;
|
||||
|
||||
xorg_list_for_each_entry(dirty, &screen->pixmap_dirty_list, ent) {
|
||||
if (dirty->src == scanoutpix && dirty->slave_dst ==
|
||||
drmmode_crtc->scanout[scanout_id ^ drmmode_crtc->tear_free].pixmap) {
|
||||
if (dirty->src == drmmode_crtc->prime_scanout_pixmap) {
|
||||
RegionPtr region;
|
||||
|
||||
if (master_has_sync_shared_pixmap(scrn, dirty))
|
||||
|
||||
@@ -681,9 +681,7 @@ drmmode_crtc_prime_scanout_update(xf86CrtcPtr crtc, DisplayModePtr mode,
|
||||
|
||||
xorg_list_for_each_entry(dirty, &screen->pixmap_dirty_list,
|
||||
ent) {
|
||||
if (dirty->src == crtc->randr_crtc->scanout_pixmap &&
|
||||
dirty->slave_dst ==
|
||||
drmmode_crtc->scanout[drmmode_crtc->scanout_id].pixmap) {
|
||||
if (dirty->src == drmmode_crtc->prime_scanout_pixmap) {
|
||||
dirty->slave_dst =
|
||||
drmmode_crtc->scanout[scanout_id].pixmap;
|
||||
break;
|
||||
@@ -838,7 +836,7 @@ drmmode_set_mode_major(xf86CrtcPtr crtc, DisplayModePtr mode,
|
||||
|
||||
fb_id = drmmode->fb_id;
|
||||
#ifdef AMDGPU_PIXMAP_SHARING
|
||||
if (crtc->randr_crtc && crtc->randr_crtc->scanout_pixmap) {
|
||||
if (drmmode_crtc->prime_scanout_pixmap) {
|
||||
drmmode_crtc_prime_scanout_update(crtc, mode, scanout_id,
|
||||
&fb_id, &x, &y);
|
||||
} else
|
||||
@@ -1242,14 +1240,15 @@ static Bool drmmode_set_scanout_pixmap(xf86CrtcPtr crtc, PixmapPtr ppix)
|
||||
PixmapDirtyUpdatePtr dirty;
|
||||
|
||||
xorg_list_for_each_entry(dirty, &screen->pixmap_dirty_list, ent) {
|
||||
if (dirty->slave_dst != drmmode_crtc->scanout[scanout_id].pixmap)
|
||||
continue;
|
||||
|
||||
PixmapStopDirtyTracking(dirty->src, dirty->slave_dst);
|
||||
drmmode_crtc_scanout_free(drmmode_crtc);
|
||||
break;
|
||||
if (dirty->src == drmmode_crtc->prime_scanout_pixmap) {
|
||||
PixmapStopDirtyTracking(dirty->src, dirty->slave_dst);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
drmmode_crtc_scanout_free(drmmode_crtc);
|
||||
drmmode_crtc->prime_scanout_pixmap = NULL;
|
||||
|
||||
if (!ppix)
|
||||
return TRUE;
|
||||
|
||||
@@ -1266,6 +1265,8 @@ static Bool drmmode_set_scanout_pixmap(xf86CrtcPtr crtc, PixmapPtr ppix)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
drmmode_crtc->prime_scanout_pixmap = ppix;
|
||||
|
||||
#ifdef HAS_DIRTYTRACKING_ROTATION
|
||||
PixmapStartDirtyTracking(ppix, drmmode_crtc->scanout[scanout_id].pixmap,
|
||||
0, 0, 0, 0, RR_Rotate_0);
|
||||
|
||||
@@ -83,6 +83,9 @@ typedef struct {
|
||||
unsigned scanout_id;
|
||||
Bool scanout_update_pending;
|
||||
Bool tear_free;
|
||||
|
||||
PixmapPtr prime_scanout_pixmap;
|
||||
|
||||
int dpms_mode;
|
||||
/* For when a flip is pending when DPMS off requested */
|
||||
int pending_dpms_mode;
|
||||
|
||||
Reference in New Issue
Block a user