Zbigniew Jędrzejewski-Szmek 62fe94
From aec3f44651998211d559b474bb830aad65680a62 Mon Sep 17 00:00:00 2001
Zbigniew Jędrzejewski-Szmek 62fe94
From: David Herrmann <dh.herrmann@gmail.com>
Zbigniew Jędrzejewski-Szmek 62fe94
Date: Thu, 2 Oct 2014 17:59:26 +0200
Zbigniew Jędrzejewski-Szmek 62fe94
Subject: [PATCH] terminal/drm: provide pipe->target() callback
Zbigniew Jędrzejewski-Szmek 62fe94
Zbigniew Jędrzejewski-Szmek 62fe94
Instead of looking for available back-buffers on each operation, set it to
Zbigniew Jędrzejewski-Szmek 62fe94
NULL and wait for the next frame request. It will call back into the pipe
Zbigniew Jędrzejewski-Szmek 62fe94
to request the back-buffer via ->target(), where we can do the same and
Zbigniew Jędrzejewski-Szmek 62fe94
look for an available backbuffer.
Zbigniew Jędrzejewski-Szmek 62fe94
Zbigniew Jędrzejewski-Szmek 62fe94
This simplifies the code and avoids double lookups if we run short of
Zbigniew Jędrzejewski-Szmek 62fe94
buffers.
Zbigniew Jędrzejewski-Szmek 62fe94
---
Zbigniew Jędrzejewski-Szmek 62fe94
 src/libsystemd-terminal/grdev-drm.c | 98 ++++++++++++++++---------------------
Zbigniew Jędrzejewski-Szmek 62fe94
 src/libsystemd-terminal/grdev.c     |  2 +
Zbigniew Jędrzejewski-Szmek 62fe94
 2 files changed, 44 insertions(+), 56 deletions(-)
Zbigniew Jędrzejewski-Szmek 62fe94
Zbigniew Jędrzejewski-Szmek 62fe94
diff --git a/src/libsystemd-terminal/grdev-drm.c b/src/libsystemd-terminal/grdev-drm.c
Zbigniew Jędrzejewski-Szmek 62fe94
index 6b130116d7..57b930bc0f 100644
Zbigniew Jędrzejewski-Szmek 62fe94
--- a/src/libsystemd-terminal/grdev-drm.c
Zbigniew Jędrzejewski-Szmek 62fe94
+++ b/src/libsystemd-terminal/grdev-drm.c
Zbigniew Jędrzejewski-Szmek 62fe94
@@ -1095,19 +1095,19 @@ static void grdrm_crtc_expose(grdrm_crtc *crtc) {
Zbigniew Jędrzejewski-Szmek 62fe94
         grdev_pipe_ready(&crtc->pipe->base, true);
Zbigniew Jędrzejewski-Szmek 62fe94
 }
Zbigniew Jędrzejewski-Szmek 62fe94
 
Zbigniew Jędrzejewski-Szmek 62fe94
-static void grdrm_crtc_commit_deep(grdrm_crtc *crtc, grdev_fb **slot) {
Zbigniew Jędrzejewski-Szmek 62fe94
+static void grdrm_crtc_commit_deep(grdrm_crtc *crtc, grdev_fb *basefb) {
Zbigniew Jędrzejewski-Szmek 62fe94
         struct drm_mode_crtc set_crtc = { .crtc_id = crtc->object.id };
Zbigniew Jędrzejewski-Szmek 62fe94
         grdrm_card *card = crtc->object.card;
Zbigniew Jędrzejewski-Szmek 62fe94
         grdrm_pipe *pipe = crtc->pipe;
Zbigniew Jędrzejewski-Szmek 62fe94
-        grdrm_fb *fb = fb_from_base(*slot);
Zbigniew Jędrzejewski-Szmek 62fe94
-        size_t i;
Zbigniew Jędrzejewski-Szmek 62fe94
+        grdrm_fb *fb;
Zbigniew Jędrzejewski-Szmek 62fe94
         int r;
Zbigniew Jędrzejewski-Szmek 62fe94
 
Zbigniew Jędrzejewski-Szmek 62fe94
         assert(crtc);
Zbigniew Jędrzejewski-Szmek 62fe94
-        assert(slot);
Zbigniew Jędrzejewski-Szmek 62fe94
-        assert(*slot);
Zbigniew Jędrzejewski-Szmek 62fe94
+        assert(basefb);
Zbigniew Jędrzejewski-Szmek 62fe94
         assert(pipe);
Zbigniew Jędrzejewski-Szmek 62fe94
 
Zbigniew Jędrzejewski-Szmek 62fe94
+        fb = fb_from_base(basefb);
Zbigniew Jędrzejewski-Szmek 62fe94
+
Zbigniew Jędrzejewski-Szmek 62fe94
         set_crtc.set_connectors_ptr = PTR_TO_UINT64(crtc->set.connectors);
Zbigniew Jędrzejewski-Szmek 62fe94
         set_crtc.count_connectors = crtc->set.n_connectors;
Zbigniew Jędrzejewski-Szmek 62fe94
         set_crtc.fb_id = fb->id;
Zbigniew Jędrzejewski-Szmek 62fe94
@@ -1132,7 +1132,7 @@ static void grdrm_crtc_commit_deep(grdrm_crtc *crtc, grdev_fb **slot) {
Zbigniew Jędrzejewski-Szmek 62fe94
                 crtc->applied = true;
Zbigniew Jędrzejewski-Szmek 62fe94
         }
Zbigniew Jędrzejewski-Szmek 62fe94
 
Zbigniew Jędrzejewski-Szmek 62fe94
-        *slot = NULL;
Zbigniew Jędrzejewski-Szmek 62fe94
+        pipe->base.back = NULL;
Zbigniew Jędrzejewski-Szmek 62fe94
         pipe->base.front = &fb->base;
Zbigniew Jędrzejewski-Szmek 62fe94
         fb->flipid = 0;
Zbigniew Jędrzejewski-Szmek 62fe94
         ++pipe->counter;
Zbigniew Jędrzejewski-Szmek 62fe94
@@ -1144,40 +1144,25 @@ static void grdrm_crtc_commit_deep(grdrm_crtc *crtc, grdev_fb **slot) {
Zbigniew Jędrzejewski-Szmek 62fe94
          * To avoid duplicating that everywhere, we schedule our own
Zbigniew Jędrzejewski-Szmek 62fe94
          * timer and raise a fake FRAME event when it fires. */
Zbigniew Jędrzejewski-Szmek 62fe94
         grdev_pipe_schedule(&pipe->base, 1);
Zbigniew Jędrzejewski-Szmek 62fe94
-
Zbigniew Jędrzejewski-Szmek 62fe94
-        if (!pipe->base.back) {
Zbigniew Jędrzejewski-Szmek 62fe94
-                for (i = 0; i < pipe->base.max_fbs; ++i) {
Zbigniew Jędrzejewski-Szmek 62fe94
-                        if (!pipe->base.fbs[i])
Zbigniew Jędrzejewski-Szmek 62fe94
-                                continue;
Zbigniew Jędrzejewski-Szmek 62fe94
-
Zbigniew Jędrzejewski-Szmek 62fe94
-                        fb = fb_from_base(pipe->base.fbs[i]);
Zbigniew Jędrzejewski-Szmek 62fe94
-                        if (&fb->base == pipe->base.front)
Zbigniew Jędrzejewski-Szmek 62fe94
-                                continue;
Zbigniew Jędrzejewski-Szmek 62fe94
-
Zbigniew Jędrzejewski-Szmek 62fe94
-                        fb->flipid = 0;
Zbigniew Jędrzejewski-Szmek 62fe94
-                        pipe->base.back = &fb->base;
Zbigniew Jędrzejewski-Szmek 62fe94
-                        break;
Zbigniew Jędrzejewski-Szmek 62fe94
-                }
Zbigniew Jędrzejewski-Szmek 62fe94
-        }
Zbigniew Jędrzejewski-Szmek 62fe94
 }
Zbigniew Jędrzejewski-Szmek 62fe94
 
Zbigniew Jędrzejewski-Szmek 62fe94
-static int grdrm_crtc_commit_flip(grdrm_crtc *crtc, grdev_fb **slot) {
Zbigniew Jędrzejewski-Szmek 62fe94
+static int grdrm_crtc_commit_flip(grdrm_crtc *crtc, grdev_fb *basefb) {
Zbigniew Jędrzejewski-Szmek 62fe94
         struct drm_mode_crtc_page_flip page_flip = { .crtc_id = crtc->object.id };
Zbigniew Jędrzejewski-Szmek 62fe94
         grdrm_card *card = crtc->object.card;
Zbigniew Jędrzejewski-Szmek 62fe94
         grdrm_pipe *pipe = crtc->pipe;
Zbigniew Jędrzejewski-Szmek 62fe94
-        grdrm_fb *fb = fb_from_base(*slot);
Zbigniew Jędrzejewski-Szmek 62fe94
+        grdrm_fb *fb;
Zbigniew Jędrzejewski-Szmek 62fe94
         uint32_t cnt;
Zbigniew Jędrzejewski-Szmek 62fe94
-        size_t i;
Zbigniew Jędrzejewski-Szmek 62fe94
         int r;
Zbigniew Jędrzejewski-Szmek 62fe94
 
Zbigniew Jędrzejewski-Szmek 62fe94
         assert(crtc);
Zbigniew Jędrzejewski-Szmek 62fe94
-        assert(slot);
Zbigniew Jędrzejewski-Szmek 62fe94
-        assert(*slot);
Zbigniew Jędrzejewski-Szmek 62fe94
+        assert(basefb);
Zbigniew Jędrzejewski-Szmek 62fe94
         assert(pipe);
Zbigniew Jędrzejewski-Szmek 62fe94
 
Zbigniew Jędrzejewski-Szmek 62fe94
         if (!crtc->applied && !grdrm_modes_compatible(&crtc->kern.mode, &crtc->set.mode))
Zbigniew Jędrzejewski-Szmek 62fe94
                 return 0;
Zbigniew Jędrzejewski-Szmek 62fe94
 
Zbigniew Jędrzejewski-Szmek 62fe94
+        fb = fb_from_base(basefb);
Zbigniew Jędrzejewski-Szmek 62fe94
+
Zbigniew Jędrzejewski-Szmek 62fe94
         cnt = ++pipe->counter ? : ++pipe->counter;
Zbigniew Jędrzejewski-Szmek 62fe94
         page_flip.fb_id = fb->id;
Zbigniew Jędrzejewski-Szmek 62fe94
         page_flip.flags = DRM_MODE_PAGE_FLIP_EVENT;
Zbigniew Jędrzejewski-Szmek 62fe94
@@ -1209,29 +1194,13 @@ static int grdrm_crtc_commit_flip(grdrm_crtc *crtc, grdev_fb **slot) {
Zbigniew Jędrzejewski-Szmek 62fe94
         pipe->base.flip = false;
Zbigniew Jędrzejewski-Szmek 62fe94
         pipe->counter = cnt;
Zbigniew Jędrzejewski-Szmek 62fe94
         fb->flipid = cnt;
Zbigniew Jędrzejewski-Szmek 62fe94
-        *slot = NULL;
Zbigniew Jędrzejewski-Szmek 62fe94
+        pipe->base.back = NULL;
Zbigniew Jędrzejewski-Szmek 62fe94
 
Zbigniew Jędrzejewski-Szmek 62fe94
         /* Raise fake FRAME event if it takes longer than 2
Zbigniew Jędrzejewski-Szmek 62fe94
          * frames to receive the pageflip event. We assume the
Zbigniew Jędrzejewski-Szmek 62fe94
          * queue ran over or some other error happened. */
Zbigniew Jędrzejewski-Szmek 62fe94
         grdev_pipe_schedule(&pipe->base, 2);
Zbigniew Jędrzejewski-Szmek 62fe94
 
Zbigniew Jędrzejewski-Szmek 62fe94
-        if (!pipe->base.back) {
Zbigniew Jędrzejewski-Szmek 62fe94
-                for (i = 0; i < pipe->base.max_fbs; ++i) {
Zbigniew Jędrzejewski-Szmek 62fe94
-                        if (!pipe->base.fbs[i])
Zbigniew Jędrzejewski-Szmek 62fe94
-                                continue;
Zbigniew Jędrzejewski-Szmek 62fe94
-
Zbigniew Jędrzejewski-Szmek 62fe94
-                        fb = fb_from_base(pipe->base.fbs[i]);
Zbigniew Jędrzejewski-Szmek 62fe94
-                        if (&fb->base == pipe->base.front)
Zbigniew Jędrzejewski-Szmek 62fe94
-                                continue;
Zbigniew Jędrzejewski-Szmek 62fe94
-                        if (fb->flipid)
Zbigniew Jędrzejewski-Szmek 62fe94
-                                continue;
Zbigniew Jędrzejewski-Szmek 62fe94
-
Zbigniew Jędrzejewski-Szmek 62fe94
-                        pipe->base.back = &fb->base;
Zbigniew Jędrzejewski-Szmek 62fe94
-                        break;
Zbigniew Jędrzejewski-Szmek 62fe94
-                }
Zbigniew Jędrzejewski-Szmek 62fe94
-        }
Zbigniew Jędrzejewski-Szmek 62fe94
-
Zbigniew Jędrzejewski-Szmek 62fe94
         return 1;
Zbigniew Jędrzejewski-Szmek 62fe94
 }
Zbigniew Jędrzejewski-Szmek 62fe94
 
Zbigniew Jędrzejewski-Szmek 62fe94
@@ -1239,7 +1208,7 @@ static void grdrm_crtc_commit(grdrm_crtc *crtc) {
Zbigniew Jędrzejewski-Szmek 62fe94
         struct drm_mode_crtc set_crtc = { .crtc_id = crtc->object.id };
Zbigniew Jędrzejewski-Szmek 62fe94
         grdrm_card *card = crtc->object.card;
Zbigniew Jędrzejewski-Szmek 62fe94
         grdrm_pipe *pipe;
Zbigniew Jędrzejewski-Szmek 62fe94
-        grdev_fb **slot;
Zbigniew Jędrzejewski-Szmek 62fe94
+        grdev_fb *fb;
Zbigniew Jędrzejewski-Szmek 62fe94
         int r;
Zbigniew Jędrzejewski-Szmek 62fe94
 
Zbigniew Jędrzejewski-Szmek 62fe94
         assert(crtc);
Zbigniew Jędrzejewski-Szmek 62fe94
@@ -1280,19 +1249,19 @@ static void grdrm_crtc_commit(grdrm_crtc *crtc) {
Zbigniew Jędrzejewski-Szmek 62fe94
         assert(crtc->set.n_connectors > 0);
Zbigniew Jędrzejewski-Szmek 62fe94
 
Zbigniew Jędrzejewski-Szmek 62fe94
         if (pipe->base.flip)
Zbigniew Jędrzejewski-Szmek 62fe94
-                slot = &pipe->base.back;
Zbigniew Jędrzejewski-Szmek 62fe94
+                fb = pipe->base.back;
Zbigniew Jędrzejewski-Szmek 62fe94
         else if (!crtc->applied)
Zbigniew Jędrzejewski-Szmek 62fe94
-                slot = &pipe->base.front;
Zbigniew Jędrzejewski-Szmek 62fe94
+                fb = pipe->base.front;
Zbigniew Jędrzejewski-Szmek 62fe94
         else
Zbigniew Jędrzejewski-Szmek 62fe94
                 return;
Zbigniew Jędrzejewski-Szmek 62fe94
 
Zbigniew Jędrzejewski-Szmek 62fe94
-        if (!*slot)
Zbigniew Jędrzejewski-Szmek 62fe94
+        if (!fb)
Zbigniew Jędrzejewski-Szmek 62fe94
                 return;
Zbigniew Jędrzejewski-Szmek 62fe94
 
Zbigniew Jędrzejewski-Szmek 62fe94
-        r = grdrm_crtc_commit_flip(crtc, slot);
Zbigniew Jędrzejewski-Szmek 62fe94
+        r = grdrm_crtc_commit_flip(crtc, fb);
Zbigniew Jędrzejewski-Szmek 62fe94
         if (r == 0) {
Zbigniew Jędrzejewski-Szmek 62fe94
                 /* in case we couldn't page-flip, perform deep modeset */
Zbigniew Jędrzejewski-Szmek 62fe94
-                grdrm_crtc_commit_deep(crtc, slot);
Zbigniew Jędrzejewski-Szmek 62fe94
+                grdrm_crtc_commit_deep(crtc, fb);
Zbigniew Jędrzejewski-Szmek 62fe94
         }
Zbigniew Jędrzejewski-Szmek 62fe94
 }
Zbigniew Jędrzejewski-Szmek 62fe94
 
Zbigniew Jędrzejewski-Szmek 62fe94
@@ -1335,7 +1304,6 @@ static void grdrm_crtc_restore(grdrm_crtc *crtc) {
Zbigniew Jędrzejewski-Szmek 62fe94
 static void grdrm_crtc_flip_complete(grdrm_crtc *crtc, uint32_t counter, struct drm_event_vblank *event) {
Zbigniew Jędrzejewski-Szmek 62fe94
         bool flipped = false;
Zbigniew Jędrzejewski-Szmek 62fe94
         grdrm_pipe *pipe;
Zbigniew Jędrzejewski-Szmek 62fe94
-        grdrm_fb *back = NULL;
Zbigniew Jędrzejewski-Szmek 62fe94
         size_t i;
Zbigniew Jędrzejewski-Szmek 62fe94
 
Zbigniew Jędrzejewski-Szmek 62fe94
         assert(crtc);
Zbigniew Jędrzejewski-Szmek 62fe94
@@ -1366,15 +1334,9 @@ static void grdrm_crtc_flip_complete(grdrm_crtc *crtc, uint32_t counter, struct
Zbigniew Jędrzejewski-Szmek 62fe94
                         flipped = true;
Zbigniew Jędrzejewski-Szmek 62fe94
                 } else if (counter - fb->flipid < UINT16_MAX) {
Zbigniew Jędrzejewski-Szmek 62fe94
                         fb->flipid = 0;
Zbigniew Jędrzejewski-Szmek 62fe94
-                        back = fb;
Zbigniew Jędrzejewski-Szmek 62fe94
-                } else if (fb->flipid == 0) {
Zbigniew Jędrzejewski-Szmek 62fe94
-                        back = fb;
Zbigniew Jędrzejewski-Szmek 62fe94
                 }
Zbigniew Jędrzejewski-Szmek 62fe94
         }
Zbigniew Jędrzejewski-Szmek 62fe94
 
Zbigniew Jędrzejewski-Szmek 62fe94
-        if (!pipe->base.back && back)
Zbigniew Jędrzejewski-Szmek 62fe94
-                pipe->base.back = &back->base;
Zbigniew Jędrzejewski-Szmek 62fe94
-
Zbigniew Jędrzejewski-Szmek 62fe94
         if (flipped) {
Zbigniew Jędrzejewski-Szmek 62fe94
                 crtc->pipe->base.flipping = false;
Zbigniew Jędrzejewski-Szmek 62fe94
                 grdev_pipe_frame(&pipe->base);
Zbigniew Jędrzejewski-Szmek 62fe94
@@ -1561,8 +1523,32 @@ static void grdrm_pipe_free(grdev_pipe *basepipe) {
Zbigniew Jędrzejewski-Szmek 62fe94
         free(pipe);
Zbigniew Jędrzejewski-Szmek 62fe94
 }
Zbigniew Jędrzejewski-Szmek 62fe94
 
Zbigniew Jędrzejewski-Szmek 62fe94
+static grdev_fb *grdrm_pipe_target(grdev_pipe *basepipe) {
Zbigniew Jędrzejewski-Szmek 62fe94
+        grdrm_fb *fb;
Zbigniew Jędrzejewski-Szmek 62fe94
+        size_t i;
Zbigniew Jędrzejewski-Szmek 62fe94
+
Zbigniew Jędrzejewski-Szmek 62fe94
+        if (!basepipe->back) {
Zbigniew Jędrzejewski-Szmek 62fe94
+                for (i = 0; i < basepipe->max_fbs; ++i) {
Zbigniew Jędrzejewski-Szmek 62fe94
+                        if (!basepipe->fbs[i])
Zbigniew Jędrzejewski-Szmek 62fe94
+                                continue;
Zbigniew Jędrzejewski-Szmek 62fe94
+
Zbigniew Jędrzejewski-Szmek 62fe94
+                        fb = fb_from_base(basepipe->fbs[i]);
Zbigniew Jędrzejewski-Szmek 62fe94
+                        if (&fb->base == basepipe->front)
Zbigniew Jędrzejewski-Szmek 62fe94
+                                continue;
Zbigniew Jędrzejewski-Szmek 62fe94
+                        if (basepipe->flipping && fb->flipid)
Zbigniew Jędrzejewski-Szmek 62fe94
+                                continue;
Zbigniew Jędrzejewski-Szmek 62fe94
+
Zbigniew Jędrzejewski-Szmek 62fe94
+                        basepipe->back = &fb->base;
Zbigniew Jędrzejewski-Szmek 62fe94
+                        break;
Zbigniew Jędrzejewski-Szmek 62fe94
+                }
Zbigniew Jędrzejewski-Szmek 62fe94
+        }
Zbigniew Jędrzejewski-Szmek 62fe94
+
Zbigniew Jędrzejewski-Szmek 62fe94
+        return basepipe->back;
Zbigniew Jędrzejewski-Szmek 62fe94
+}
Zbigniew Jędrzejewski-Szmek 62fe94
+
Zbigniew Jędrzejewski-Szmek 62fe94
 static const grdev_pipe_vtable grdrm_pipe_vtable = {
Zbigniew Jędrzejewski-Szmek 62fe94
         .free                   = grdrm_pipe_free,
Zbigniew Jędrzejewski-Szmek 62fe94
+        .target                 = grdrm_pipe_target,
Zbigniew Jędrzejewski-Szmek 62fe94
 };
Zbigniew Jędrzejewski-Szmek 62fe94
 
Zbigniew Jędrzejewski-Szmek 62fe94
 /*
Zbigniew Jędrzejewski-Szmek 62fe94
diff --git a/src/libsystemd-terminal/grdev.c b/src/libsystemd-terminal/grdev.c
Zbigniew Jędrzejewski-Szmek 62fe94
index aaac06ec34..bbc45afad4 100644
Zbigniew Jędrzejewski-Szmek 62fe94
--- a/src/libsystemd-terminal/grdev.c
Zbigniew Jędrzejewski-Szmek 62fe94
+++ b/src/libsystemd-terminal/grdev.c
Zbigniew Jędrzejewski-Szmek 62fe94
@@ -382,6 +382,8 @@ const grdev_display_target *grdev_display_next_target(grdev_display *display, co
Zbigniew Jędrzejewski-Szmek 62fe94
                 if (!(fb = pipe->back)) {
Zbigniew Jędrzejewski-Szmek 62fe94
                         if (!pipe->vtable->target || !(fb = pipe->vtable->target(pipe)))
Zbigniew Jędrzejewski-Szmek 62fe94
                                 continue;
Zbigniew Jędrzejewski-Szmek 62fe94
+
Zbigniew Jędrzejewski-Szmek 62fe94
+                        assert(fb == pipe->back);
Zbigniew Jędrzejewski-Szmek 62fe94
                 }
Zbigniew Jędrzejewski-Szmek 62fe94
 
Zbigniew Jędrzejewski-Szmek 62fe94
                 /* if back-buffer is up-to-date, schedule flip */