summaryrefslogtreecommitdiff
path: root/src/sna/sna_dri2.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/sna/sna_dri2.c')
-rw-r--r--src/sna/sna_dri2.c136
1 files changed, 75 insertions, 61 deletions
diff --git a/src/sna/sna_dri2.c b/src/sna/sna_dri2.c
index 829e5bad..8aef88d1 100644
--- a/src/sna/sna_dri2.c
+++ b/src/sna/sna_dri2.c
@@ -112,11 +112,6 @@ struct sna_dri2_frame_event {
struct sna_dri2_frame_event *chain;
- struct {
- struct kgem_bo *bo;
- uint32_t name;
- } scanout[2];
-
struct list cache;
int mode;
@@ -130,15 +125,15 @@ sna_dri2_get_back(struct sna *sna, struct sna_dri2_frame_event *info)
DBG(("%s: scanout=(%d, %d), back=%d, cache?=%d\n",
__FUNCTION__,
- info->scanout[0].bo ? info->scanout[0].bo->handle : 0,
- info->scanout[1].bo ? info->scanout[1].bo->handle : 0,
+ sna->dri2.scanout[0].bo ? sna->dri2.scanout[0].bo->handle : 0,
+ sna->dri2.scanout[1].bo ? sna->dri2.scanout[1].bo->handle : 0,
get_private(info->back)->bo->handle,
!list_is_empty(&info->cache)));
bo = get_private(info->back)->bo;
assert(bo->refcnt);
assert(bo->flush);
- if (!(bo == info->scanout[0].bo || bo == info->scanout[1].bo)) {
+ if (!(bo == sna->dri2.scanout[0].bo || bo == sna->dri2.scanout[1].bo)) {
DBG(("%s: reuse unattached back\n", __FUNCTION__));
return;
}
@@ -173,15 +168,15 @@ sna_dri2_get_back(struct sna *sna, struct sna_dri2_frame_event *info)
}
}
- assert(!(bo == info->scanout[0].bo || bo == info->scanout[1].bo));
+ assert(!(bo == sna->dri2.scanout[0].bo || bo == sna->dri2.scanout[1].bo));
assert(name);
unref(get_private(info->back)->bo);
get_private(info->back)->bo = bo;
info->back->name = name;
- assert(get_private(info->back)->bo != info->scanout[0].bo);
- assert(get_private(info->back)->bo != info->scanout[1].bo);
+ assert(get_private(info->back)->bo != sna->dri2.scanout[0].bo);
+ assert(get_private(info->back)->bo != sna->dri2.scanout[1].bo);
assert(bo->refcnt == 1);
assert(bo->flush);
@@ -247,6 +242,9 @@ sna_dri2_reuse_buffer(DrawablePtr draw, DRI2BufferPtr buffer)
DBG(("%s: replacing back buffer\n", __FUNCTION__));
sna_dri2_get_back(to_sna_from_drawable(draw), info);
}
+
+ assert(get_private(buffer)->bo != to_sna_from_drawable(draw)->dri2.scanout[0].bo);
+ assert(get_private(buffer)->bo != to_sna_from_drawable(draw)->dri2.scanout[1].bo);
}
}
@@ -1192,13 +1190,6 @@ sna_dri2_frame_event_info_free(struct sna *sna,
_sna_dri2_destroy_buffer(sna, info->front);
_sna_dri2_destroy_buffer(sna, info->back);
- assert(info->scanout[1].bo == NULL);
-
- if (info->scanout[0].bo) {
- assert(info->scanout[0].bo->scanout);
- kgem_bo_destroy(&sna->kgem, info->scanout[0].bo);
- }
-
while (!list_is_empty(&info->cache)) {
struct dri_bo *c;
@@ -1254,6 +1245,25 @@ void sna_dri2_destroy_window(WindowPtr win)
free(priv);
}
+static void
+update_scanout(struct sna *sna, struct sna_dri2_frame_event *info, struct kgem_bo *bo, int name)
+{
+ assert(sna->dri2.scanout[1].bo == NULL);
+ assert(sna->dri2.scanout[0].bo->scanout);
+ assert(sna->dri2.scanout[0].bo->refcnt);
+ sna->dri2.scanout[1] = sna->dri2.scanout[0];
+ sna->dri2.scanout[0].bo = ref(bo);
+ sna->dri2.scanout[0].name = name;
+ assert(sna->dri2.scanout[0].bo->scanout);
+
+ DBG(("%s: pending scanout handle=%d, active scanout handle=%d\n",
+ __FUNCTION__, sna->dri2.scanout[0].bo->handle, sna->dri2.scanout[1].bo->handle));
+ assert(sna->dri2.scanout[0].bo->handle != sna->dri2.scanout[1].bo->handle);
+
+ assert(sna->dri2.flip_pending == NULL || sna->dri2.flip_pending == info);
+ sna->dri2.flip_pending = info;
+}
+
static bool
sna_dri2_page_flip(struct sna *sna, struct sna_dri2_frame_event *info)
{
@@ -1264,29 +1274,22 @@ sna_dri2_page_flip(struct sna *sna, struct sna_dri2_frame_event *info)
assert(sna_pixmap_get_buffer(sna->front) == info->front);
assert(get_drawable_pixmap(info->draw)->drawable.height * bo->pitch <= kgem_bo_size(bo));
- assert(info->scanout[0].bo);
- assert(info->scanout[0].bo->scanout);
- assert(info->scanout[1].bo == NULL);
+ assert(sna->dri2.scanout[0].bo);
+ assert(sna->dri2.scanout[0].bo->scanout);
+ assert(sna->dri2.scanout[1].bo == NULL);
assert(bo->refcnt);
info->count = sna_page_flip(sna, bo, info, info->pipe);
if (!info->count)
return false;
- DBG(("%s: mark handle=%d as scanout, swap front (handle=%d, name=%d) and back (handle=%d, name=%d)\n",
+ update_scanout(sna, info, bo, info->back->name);
+
+ DBG(("%s: marked handle=%d as scanout, swap front (handle=%d, name=%d) and back (handle=%d, name=%d)\n",
__FUNCTION__, bo->handle,
get_private(info->front)->bo->handle, info->front->name,
get_private(info->back)->bo->handle, info->back->name));
- info->scanout[1] = info->scanout[0];
- info->scanout[0].bo = ref(bo);
- info->scanout[0].name = info->back->name;
- assert(info->scanout[0].bo->scanout);
-
- DBG(("%s: pending scanout handle=%d, active scanout handle=%d\n",
- __FUNCTION__, info->scanout[0].bo->handle, info->scanout[1].bo->handle));
- assert(info->scanout[0].bo->handle != info->scanout[1].bo->handle);
-
tmp.bo = get_private(info->front)->bo;
tmp.name = info->front->name;
@@ -1298,8 +1301,6 @@ sna_dri2_page_flip(struct sna *sna, struct sna_dri2_frame_event *info)
info->back->name = tmp.name;
get_private(info->back)->bo = tmp.bo;
- sna->dri2.flip_pending = info;
-
info->queued = true;
return true;
}
@@ -1773,23 +1774,18 @@ sna_dri2_flip_continue(struct sna *sna, struct sna_dri2_frame_event *info)
DBG(("%s(mode=%d)\n", __FUNCTION__, info->mode));
if (info->mode > 0){
+ struct kgem_bo *bo =get_private(info->front)->bo;
+
info->type = info->mode;
- if (get_private(info->front)->bo != sna_pixmap(sna->front)->gpu_bo)
+ if (bo != sna_pixmap(sna->front)->gpu_bo)
return false;
- info->count = sna_page_flip(sna,
- get_private(info->front)->bo,
- info, info->pipe);
+ info->count = sna_page_flip(sna, bo, info, info->pipe);
if (!info->count)
return false;
- assert(info->scanout[0].bo->scanout);
- info->scanout[1] = info->scanout[0];
- info->scanout[0].bo = ref(get_private(info->front)->bo);
- info->scanout[0].name = info->front->name;
- assert(info->scanout[0].bo->scanout);
- sna->dri2.flip_pending = info;
+ update_scanout(sna, info, bo, info->front->name);
} else {
info->type = -info->mode;
@@ -1870,18 +1866,18 @@ static void sna_dri2_flip_event(struct sna *sna,
assert(!sna->mode.shadow_flip);
- if (flip->scanout[1].bo) {
+ if (sna->dri2.scanout[1].bo) {
struct dri_bo *c = NULL;
DBG(("%s: retiring previous scanout handle=%d, name=%d, refcnt=%d (current scanout handle=%d)\n",
__FUNCTION__,
- flip->scanout[1].bo->handle,
- flip->scanout[1].name,
- flip->scanout[1].bo->refcnt,
- flip->scanout[0].bo->handle));
+ sna->dri2.scanout[1].bo->handle,
+ sna->dri2.scanout[1].name,
+ sna->dri2.scanout[1].bo->refcnt,
+ sna->dri2.scanout[0].bo->handle));
- if (flip->scanout[1].bo != flip->scanout[0].bo &&
- flip->scanout[1].bo->refcnt == 1) {
+ if (sna->dri2.scanout[1].bo != sna->dri2.scanout[0].bo &&
+ sna->dri2.scanout[1].bo->refcnt == 1) {
DBG(("%s: adding old scanout to flip cache\n", __FUNCTION__));
if (!list_is_empty(&flip->cache))
c = list_last_entry(&flip->cache, struct dri_bo, link);
@@ -1894,19 +1890,19 @@ static void sna_dri2_flip_event(struct sna *sna,
if (c == NULL)
c = malloc(sizeof(*c));
if (c != NULL) {
- c->bo = flip->scanout[1].bo;
- c->name = flip->scanout[1].name;
+ c->bo = sna->dri2.scanout[1].bo;
+ c->name = sna->dri2.scanout[1].name;
list_add(&c->link, &flip->cache);
}
}
if (c == NULL) {
DBG(("%s: not caching old scanout handle=%d, still busy\n",
- __FUNCTION__, flip->scanout[1].bo->handle));
- kgem_bo_destroy(&sna->kgem, flip->scanout[1].bo);
+ __FUNCTION__, sna->dri2.scanout[1].bo->handle));
+ kgem_bo_destroy(&sna->kgem, sna->dri2.scanout[1].bo);
}
- flip->scanout[1].bo = NULL;
+ sna->dri2.scanout[1].bo = NULL;
}
if (sna->dri2.flip_pending == flip)
@@ -2114,9 +2110,12 @@ sna_dri2_schedule_flip(ClientPtr client, DrawablePtr draw, xf86CrtcPtr crtc,
info->front = sna_dri2_reference_buffer(front);
info->back = sna_dri2_reference_buffer(back);
- info->scanout[0].bo = ref(get_private(front)->bo);
- info->scanout[0].name = info->front->name;
- assert(info->scanout[0].bo->scanout);
+ if (sna->dri2.scanout[0].bo == NULL) {
+ sna->dri2.scanout[0].bo = ref(get_private(front)->bo);
+ sna->dri2.scanout[0].name = info->front->name;
+ }
+ assert(sna->dri2.scanout[0].bo == get_private(front)->bo);
+ assert(sna->dri2.scanout[0].bo->scanout);
if (sna->dri2.flip_pending) {
/* We need to first wait (one vblank) for the
@@ -2161,9 +2160,12 @@ out:
info->front = sna_dri2_reference_buffer(front);
info->back = sna_dri2_reference_buffer(back);
- info->scanout[0].bo = ref(get_private(front)->bo);
- info->scanout[0].name = info->front->name;
- assert(info->scanout[0].bo->scanout);
+ if (sna->dri2.scanout[0].bo == NULL) {
+ sna->dri2.scanout[0].bo = ref(get_private(front)->bo);
+ sna->dri2.scanout[0].name = info->front->name;
+ }
+ assert(sna->dri2.scanout[0].bo == get_private(front)->bo);
+ assert(sna->dri2.scanout[0].bo->scanout);
/*
* If divisor is zero, or current_msc is smaller than target_msc
@@ -2675,6 +2677,18 @@ bool sna_dri2_open(struct sna *sna, ScreenPtr screen)
return DRI2ScreenInit(screen, &info);
}
+void sna_dri2_reset_scanout(struct sna *sna)
+{
+ if (sna->dri2.scanout[1].bo != NULL) {
+ kgem_bo_destroy(&sna->kgem, sna->dri2.scanout[1].bo);
+ sna->dri2.scanout[1].bo = NULL;
+ }
+ if (sna->dri2.scanout[0].bo != NULL) {
+ kgem_bo_destroy(&sna->kgem, sna->dri2.scanout[0].bo);
+ sna->dri2.scanout[0].bo = NULL;
+ }
+}
+
void sna_dri2_close(struct sna *sna, ScreenPtr screen)
{
DBG(("%s()\n", __FUNCTION__));