summaryrefslogtreecommitdiff
path: root/hw
diff options
context:
space:
mode:
authorAlex Goins <agoins@nvidia.com>2016-06-16 20:06:49 -0700
committerAdam Jackson <ajax@redhat.com>2016-06-28 12:56:21 -0400
commitf4c37eeee7953df1fe0e3196eda452acf0078e61 (patch)
treec4ef0ee3eee49cc130fc202f7a3cc47915341aa0 /hw
parent1bdbc7e764ed7bf7c1ae46287dec368aa7c7e80d (diff)
modesetting: Internal storage of scanout pixmaps
modesetting relied on randr_crtc->scanout_pixmap being consistent with calls to SetScanoutPixmap, which is very fragile and makes a lot of assumptions about the caller's behavior. For example, RRReplaceScanoutPixmap(), when dropping off with !size_fits, will set randr_crtc->scanout_pixmap = NULL and then call SetScanoutPixmap. Without this patch, drmmode_set_scanout_pixmap_(cpu/gpu) will think that there is no scanout pixmap to tear down, because it's already been set to NULL. By keeping track of the scanout pixmap in its internal state, modesetting can avoid these types of bugs and reduce constraints on calling conventions. v1: N/A v2: N/A v3: N/A v4: N/A v5: Initial commit v6: Rebase onto ToT v7: Unchanged Reviewed-by: Dave Airlie <airlied@redhat.com> Signed-off-by: Alex Goins <agoins@nvidia.com>
Diffstat (limited to 'hw')
-rw-r--r--hw/xfree86/drivers/modesetting/driver.c9
-rw-r--r--hw/xfree86/drivers/modesetting/drmmode_display.c22
-rw-r--r--hw/xfree86/drivers/modesetting/drmmode_display.h3
3 files changed, 22 insertions, 12 deletions
diff --git a/hw/xfree86/drivers/modesetting/driver.c b/hw/xfree86/drivers/modesetting/driver.c
index 1604044b2..0059e563c 100644
--- a/hw/xfree86/drivers/modesetting/driver.c
+++ b/hw/xfree86/drivers/modesetting/driver.c
@@ -532,10 +532,10 @@ static void
dispatch_dirty_crtc(ScrnInfoPtr scrn, xf86CrtcPtr crtc)
{
modesettingPtr ms = modesettingPTR(scrn);
- PixmapPtr pixmap = crtc->randr_crtc->scanout_pixmap;
- msPixmapPrivPtr ppriv = msGetPixmapPriv(&ms->drmmode, pixmap);
drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
+ PixmapPtr pixmap = drmmode_crtc->prime_pixmap;
DamagePtr damage = drmmode_crtc->slave_damage;
+ msPixmapPrivPtr ppriv = msGetPixmapPriv(&ms->drmmode, pixmap);
int fb_id = ppriv->fb_id;
int ret;
@@ -554,10 +554,11 @@ dispatch_slave_dirty(ScreenPtr pScreen)
for (c = 0; c < xf86_config->num_crtc; c++) {
xf86CrtcPtr crtc = xf86_config->crtc[c];
+ drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
- if (!crtc->randr_crtc)
+ if (!drmmode_crtc)
continue;
- if (!crtc->randr_crtc->scanout_pixmap)
+ if (!drmmode_crtc->prime_pixmap)
continue;
dispatch_dirty_crtc(scrn, crtc);
diff --git a/hw/xfree86/drivers/modesetting/drmmode_display.c b/hw/xfree86/drivers/modesetting/drmmode_display.c
index 7e5901a71..89c468b34 100644
--- a/hw/xfree86/drivers/modesetting/drmmode_display.c
+++ b/hw/xfree86/drivers/modesetting/drmmode_display.c
@@ -454,10 +454,10 @@ drmmode_set_mode_major(xf86CrtcPtr crtc, DisplayModePtr mode,
drmmode_ConvertToKMode(crtc->scrn, &kmode, mode);
fb_id = drmmode->fb_id;
- if (crtc->randr_crtc->scanout_pixmap) {
+ if (drmmode_crtc->prime_pixmap) {
if (!drmmode->reverse_prime_offload_mode) {
msPixmapPrivPtr ppriv =
- msGetPixmapPriv(drmmode, crtc->randr_crtc->scanout_pixmap);
+ msGetPixmapPriv(drmmode, drmmode_crtc->prime_pixmap);
fb_id = ppriv->fb_id;
x = 0;
} else
@@ -639,8 +639,8 @@ drmmode_set_scanout_pixmap_gpu(xf86CrtcPtr crtc, PixmapPtr ppix)
int c, total_width = 0, max_height = 0, this_x = 0;
if (!ppix) {
- if (crtc->randr_crtc->scanout_pixmap) {
- PixmapStopDirtyTracking(crtc->randr_crtc->scanout_pixmap, screenpix);
+ if (drmmode_crtc->prime_pixmap) {
+ PixmapStopDirtyTracking(drmmode_crtc->prime_pixmap, screenpix);
if (drmmode->fb_id) {
drmModeRmFB(drmmode->fd, drmmode->fb_id);
drmmode->fb_id = 0;
@@ -690,8 +690,8 @@ drmmode_set_scanout_pixmap_cpu(xf86CrtcPtr crtc, PixmapPtr ppix)
void *ptr;
if (!ppix) {
- if (crtc->randr_crtc->scanout_pixmap) {
- ppriv = msGetPixmapPriv(drmmode, crtc->randr_crtc->scanout_pixmap);
+ if (drmmode_crtc->prime_pixmap) {
+ ppriv = msGetPixmapPriv(drmmode, drmmode_crtc->prime_pixmap);
drmModeRmFB(drmmode->fd, ppriv->fb_id);
ppriv->fb_id = 0;
}
@@ -727,13 +727,19 @@ drmmode_set_scanout_pixmap_cpu(xf86CrtcPtr crtc, PixmapPtr ppix)
static Bool
drmmode_set_scanout_pixmap(xf86CrtcPtr crtc, PixmapPtr ppix)
{
+ Bool ret;
drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
drmmode_ptr drmmode = drmmode_crtc->drmmode;
if (drmmode->reverse_prime_offload_mode)
- return drmmode_set_scanout_pixmap_gpu(crtc, ppix);
+ ret = drmmode_set_scanout_pixmap_gpu(crtc, ppix);
else
- return drmmode_set_scanout_pixmap_cpu(crtc, ppix);
+ ret = drmmode_set_scanout_pixmap_cpu(crtc, ppix);
+
+ if (ret)
+ drmmode_crtc->prime_pixmap = ppix;
+
+ return ret;
}
static void *
diff --git a/hw/xfree86/drivers/modesetting/drmmode_display.h b/hw/xfree86/drivers/modesetting/drmmode_display.h
index 6b94641a4..36c6e919a 100644
--- a/hw/xfree86/drivers/modesetting/drmmode_display.h
+++ b/hw/xfree86/drivers/modesetting/drmmode_display.h
@@ -103,7 +103,10 @@ typedef struct {
drmmode_bo rotate_bo;
unsigned rotate_fb_id;
+
+ PixmapPtr prime_pixmap;
unsigned prime_pixmap_x;
+
/**
* @{ MSC (vblank count) handling for the PRESENT extension.
*