summaryrefslogtreecommitdiff
path: root/vmwgfx
diff options
context:
space:
mode:
authorThomas Hellstrom <thellstrom@vmware.com>2011-06-20 09:58:44 +0200
committerThomas Hellstrom <thellstrom@vmware.com>2011-06-22 22:34:43 +0200
commitf6a4690832143b01d419b52a4cb74350cdfa38bf (patch)
tree55888f9feb63c3d8dcea17e1eb92a19ec8a6b045 /vmwgfx
parenteea0e6e242a604b1f4d85d947cf2b3f9f4977533 (diff)
vmwgfx: Make a list of scanout bounding boxes available to each scanout pixmap
This info is needed for present readback. Signed-off-by: Thomas Hellstrom <thellstrom@vmware.com>
Diffstat (limited to 'vmwgfx')
-rw-r--r--vmwgfx/vmwgfx_crtc.c46
-rw-r--r--vmwgfx/vmwgfx_saa.c30
-rw-r--r--vmwgfx/vmwgfx_saa.h12
3 files changed, 55 insertions, 33 deletions
diff --git a/vmwgfx/vmwgfx_crtc.c b/vmwgfx/vmwgfx_crtc.c
index 49e84e8..8f8ced4 100644
--- a/vmwgfx/vmwgfx_crtc.c
+++ b/vmwgfx/vmwgfx_crtc.c
@@ -58,9 +58,11 @@ struct crtc_private
/* hwcursor */
struct vmwgfx_dmabuf *cursor_bo;
- PixmapPtr scanout;
uint32_t scanout_id;
unsigned cursor_handle;
+
+ /* Scanout info for pixmaps */
+ struct vmwgfx_screen_box box;
};
static void
@@ -87,14 +89,8 @@ crtc_dpms(xf86CrtcPtr crtc, int mode)
* the crtc may be turned on again by
* another dpms call, so don't release the scanout pixmap ref.
*/
- if (!crtc->enabled && crtcp->scanout) {
- PixmapPtr pixmap = crtcp->scanout;
- ScreenPtr pScreen = pixmap->drawable.pScreen;
-
- vmwgfx_scanout_unref(pixmap);
- pScreen->DestroyPixmap(pixmap);
- crtcp->scanout = NULL;
- crtcp->scanout_id = -1;
+ if (!crtc->enabled && crtcp->box.pixmap) {
+ vmwgfx_scanout_unref(&crtcp->box);
}
break;
}
@@ -138,6 +134,7 @@ crtc_set_mode_major(xf86CrtcPtr crtc, DisplayModePtr mode,
int i, ret;
unsigned int connector_id;
PixmapPtr pixmap;
+ BoxPtr screen_box;
for (i = 0; i < config->num_output; output = NULL, i++) {
output = config->output[i];
@@ -188,17 +185,13 @@ crtc_set_mode_major(xf86CrtcPtr crtc, DisplayModePtr mode,
else
pixmap = pScreen->GetScreenPixmap(pScreen);
- if (crtcp->scanout != pixmap) {
- if (crtcp->scanout) {
- vmwgfx_scanout_unref(crtcp->scanout);
- pScreen->DestroyPixmap(crtcp->scanout);
- }
- crtcp->scanout_id = vmwgfx_scanout_ref(pixmap);
- if (crtcp->scanout_id != -1) {
- pixmap->refcnt += 1;
- crtcp->scanout = pixmap;
- } else {
- crtcp->scanout = NULL;
+ if (crtcp->box.pixmap != pixmap) {
+ if (crtcp->box.pixmap)
+ vmwgfx_scanout_unref(&crtcp->box);
+
+ crtcp->box.pixmap = pixmap;
+ crtcp->scanout_id = vmwgfx_scanout_ref(&crtcp->box);
+ if (crtcp->scanout_id == -1) {
LogMessage(X_ERROR, "Failed to convert pixmap to scanout.\n");
return FALSE;
}
@@ -208,6 +201,12 @@ crtc_set_mode_major(xf86CrtcPtr crtc, DisplayModePtr mode,
if (ret)
return FALSE;
+ screen_box = &crtcp->box.box;
+ screen_box->x1 = crtc->x;
+ screen_box->y1 = crtc->y;
+ screen_box->x2 = screen_box->x1 + mode->HDisplay;
+ screen_box->y2 = screen_box->y1 + mode->VDisplay;
+
vmwgfx_scanout_refresh(pixmap);
/* Only set gamma when needed, to avoid unneeded delays. */
@@ -379,6 +378,9 @@ crtc_destroy(xf86CrtcPtr crtc)
{
struct crtc_private *crtcp = crtc->driver_private;
+ if (!WSBMLISTEMPTY(&crtcp->box.scanout_head))
+ vmwgfx_scanout_unref(&crtcp->box);
+
xorg_crtc_cursor_destroy(crtc);
drmModeFreeCrtc(crtcp->drm_crtc);
@@ -438,6 +440,8 @@ xorg_crtc_init(ScrnInfoPtr pScrn)
}
crtcp->drm_crtc = drm_crtc;
+ crtcp->box.pixmap = NULL;
+ WSBMINITLISTHEAD(&crtcp->box.scanout_head);
crtc->driver_private = crtcp;
}
@@ -450,7 +454,7 @@ PixmapPtr
crtc_get_scanout(xf86CrtcPtr crtc)
{
struct crtc_private *crtcp = crtc->driver_private;
- return crtcp->scanout;
+ return crtcp->box.pixmap;
}
/* vim: set sw=4 ts=8 sts=4: */
diff --git a/vmwgfx/vmwgfx_saa.c b/vmwgfx/vmwgfx_saa.c
index f733328..55b5fea 100644
--- a/vmwgfx/vmwgfx_saa.c
+++ b/vmwgfx/vmwgfx_saa.c
@@ -246,7 +246,6 @@ vmwgfx_pixmap_present_readback(struct vmwgfx_saa *vsaa,
struct vmwgfx_saa_pixmap *vpix = to_vmwgfx_saa_pixmap(spix);
RegionRec intersection;
-
if (!spix->damage || !REGION_NOTEMPTY(vsaa->pScreen, &spix->dirty_hw) ||
!vpix->dirty_present)
return TRUE;
@@ -266,6 +265,7 @@ vmwgfx_pixmap_present_readback(struct vmwgfx_saa *vsaa,
if (!vmwgfx_pixmap_create_gmr(vsaa, pixmap))
goto out_err;
+
/*
* FIXME: Cliprects may not overlap screen boundaries.
*/
@@ -431,6 +431,8 @@ vmwgfx_create_pixmap(struct saa_driver *driver, struct saa_pixmap *spix,
*new_pitch = ((w * bpp + FB_MASK) >> FB_SHIFT) * sizeof(FbBits);
WSBMINITLISTHEAD(&vpix->sync_x_head);
+ WSBMINITLISTHEAD(&vpix->scanout_list);
+
return TRUE;
}
@@ -1126,14 +1128,15 @@ vmwgfx_scanout_refresh(PixmapPtr pixmap)
*/
uint32_t
-vmwgfx_scanout_ref(PixmapPtr pixmap)
+vmwgfx_scanout_ref(struct vmwgfx_screen_box *box)
{
+ PixmapPtr pixmap = box->pixmap;
struct vmwgfx_saa *vsaa =
to_vmwgfx_saa(saa_get_driver(pixmap->drawable.pScreen));
struct vmwgfx_saa_pixmap *vpix = vmwgfx_saa_pixmap(pixmap);
int ret;
- if (vpix->scanout_refcnt++ == 0) {
+ if (WSBMLISTEMPTY(&vpix->scanout_list)) {
ret = !vmwgfx_pixmap_create_gmr(vsaa, pixmap);
if (!ret)
ret = !vmwgfx_pixmap_add_present(pixmap);
@@ -1146,14 +1149,17 @@ vmwgfx_scanout_ref(PixmapPtr pixmap)
pixmap->devKind,
vpix->gmr->handle,
&vpix->fb_id);
- if (!ret) {
-// vmwgfx_scanout_refresh(pixmap);
- }
if (ret) {
+ box->pixmap = NULL;
vpix->fb_id = -1;
- --vpix->scanout_refcnt;
+ goto out_err;
}
+
}
+ pixmap->refcnt += 1;
+ WSBMLISTADDTAIL(&box->scanout_head, &vpix->scanout_list);
+
+ out_err:
return vpix->fb_id;
}
@@ -1163,17 +1169,20 @@ vmwgfx_scanout_ref(PixmapPtr pixmap)
* damage tracking and kms fbs.
*/
void
-vmwgfx_scanout_unref(PixmapPtr pixmap)
+vmwgfx_scanout_unref(struct vmwgfx_screen_box *box)
{
struct vmwgfx_saa *vsaa;
struct vmwgfx_saa_pixmap *vpix;
+ PixmapPtr pixmap = box->pixmap;
if (!pixmap)
return;
vsaa = to_vmwgfx_saa(saa_get_driver(pixmap->drawable.pScreen));
vpix = vmwgfx_saa_pixmap(pixmap);
- if (--vpix->scanout_refcnt == 0) {
+ WSBMLISTDELINIT(&box->scanout_head);
+
+ if (WSBMLISTEMPTY(&vpix->scanout_list)) {
REGION_EMPTY(vsaa->pScreen, vpix->pending_update);
drmModeRmFB(vsaa->drm_fd, vpix->fb_id);
vpix->fb_id = -1;
@@ -1181,4 +1190,7 @@ vmwgfx_scanout_unref(PixmapPtr pixmap)
vmwgfx_pixmap_remove_present(vpix);
vmwgfx_pixmap_remove_damage(pixmap);
}
+
+ box->pixmap = NULL;
+ pixmap->drawable.pScreen->DestroyPixmap(pixmap);
}
diff --git a/vmwgfx/vmwgfx_saa.h b/vmwgfx/vmwgfx_saa.h
index c7aae79..90fa728 100644
--- a/vmwgfx/vmwgfx_saa.h
+++ b/vmwgfx/vmwgfx_saa.h
@@ -49,10 +49,16 @@ struct vmwgfx_saa_pixmap {
void *malloc;
struct vmwgfx_dmabuf *gmr;
struct xa_surface *hw;
- int scanout_refcnt;
uint32_t fb_id;
int hw_is_dri2_fronts;
struct _WsbmListHead sync_x_head;
+ struct _WsbmListHead scanout_list;
+};
+
+struct vmwgfx_screen_box {
+ BoxRec box;
+ struct _WsbmListHead scanout_head;
+ PixmapPtr pixmap;
};
static inline struct vmwgfx_saa_pixmap *
@@ -77,10 +83,10 @@ vmwgfx_saa_init(ScreenPtr pScreen, int drm_fd, struct xa_tracker *xat,
void (*present_flush)(ScreenPtr pScreen));
extern uint32_t
-vmwgfx_scanout_ref(PixmapPtr pixmap);
+vmwgfx_scanout_ref(struct vmwgfx_screen_box *box);
extern void
-vmwgfx_scanout_unref(PixmapPtr pixmap);
+vmwgfx_scanout_unref(struct vmwgfx_screen_box *box);
extern void
vmwgfx_scanout_refresh(PixmapPtr pixmap);