/* 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
* 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;
}
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];
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;
}
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. */
{
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);
}
crtcp->drm_crtc = drm_crtc;
+ crtcp->box.pixmap = NULL;
+ WSBMINITLISTHEAD(&crtcp->box.scanout_head);
crtc->driver_private = crtcp;
}
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: */
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;
if (!vmwgfx_pixmap_create_gmr(vsaa, pixmap))
goto out_err;
+
/*
* FIXME: Cliprects may not overlap screen boundaries.
*/
*new_pitch = ((w * bpp + FB_MASK) >> FB_SHIFT) * sizeof(FbBits);
WSBMINITLISTHEAD(&vpix->sync_x_head);
+ WSBMINITLISTHEAD(&vpix->scanout_list);
+
return TRUE;
}
*/
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);
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;
}
* 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;
vmwgfx_pixmap_remove_present(vpix);
vmwgfx_pixmap_remove_damage(pixmap);
}
+
+ box->pixmap = NULL;
+ pixmap->drawable.pScreen->DestroyPixmap(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 *
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);