[PATCH 2/3] present: Create helper functions for the copy and idle steps

Keith Packard keithp at keithp.com
Sat Dec 13 00:32:30 PST 2014


There were two instances of calls that cleaned up after a vblank was
done with the pixmap and related idle_fence, one invoked after the
copy was performed and the other when the vblank was skipped because a
newer operation was queued. Now these two shared the
present_vblank_idle helper function, which idles the pixmap, destroys
the fence and resets the vblank state.

Some of this work wasn't done in the old copy version because it would
also happen when the vblank was destroyed soon after the copy was
performed, but we'll want to clean up the pixmap-related objects right
after the copy when the compositor improvements are added next.

Signed-off-by: Keith Packard <keithp at keithp.com>
---
 present/present.c      | 57 ++++++++++++++++++++++++++++++++++++--------------
 present/present_priv.h |  1 +
 2 files changed, 42 insertions(+), 16 deletions(-)

diff --git a/present/present.c b/present/present.c
index 6a414c2..06def61 100644
--- a/present/present.c
+++ b/present/present.c
@@ -571,6 +571,45 @@ present_wait_fence_triggered(void *param)
 }
 
 /*
+ * All client objects related to this presentation are no longer in use, so
+ * mark the pixmap as idle and clean up the idle fence
+ */
+static void
+present_vblank_idle(present_vblank_ptr vblank)
+{
+        present_pixmap_idle(vblank->pixmap, vblank->window, vblank->serial, vblank->idle_fence);
+        present_fence_destroy(vblank->idle_fence);
+        dixDestroyPixmap(vblank->pixmap, vblank->pixmap->drawable.id);
+
+        vblank->pixmap = NULL;
+        vblank->idle_fence = NULL;
+}
+
+/*
+ * Execute the present copy operation if it hasn't been done yet, then mark the
+ * related objects as completed
+ */
+static void
+present_copy(present_vblank_ptr vblank)
+{
+    if (!vblank->copied) {
+        WindowPtr       window = vblank->window;
+
+        vblank->copied = TRUE;
+
+        present_copy_region(&window->drawable, vblank->pixmap, vblank->update, vblank->x_off, vblank->y_off);
+
+        /* present_copy_region sticks the region into a scratch GC,
+         * which is then freed, freeing the region
+         */
+        vblank->update = NULL;
+        present_flush(window);
+
+        present_vblank_idle(vblank);
+    }
+}
+
+/*
  * Once the required MSC has been reached, execute the pending request.
  *
  * For requests to actually present something, either blt contents to
@@ -669,15 +708,7 @@ present_execute(present_vblank_ptr vblank, uint64_t ust, uint64_t crtc_msc)
             if (window == screen_priv->flip_window)
                 present_unflip(screen);
         }
-        present_copy_region(&window->drawable, vblank->pixmap, vblank->update, vblank->x_off, vblank->y_off);
-
-        /* present_copy_region sticks the region into a scratch GC,
-         * which is then freed, freeing the region
-         */
-        vblank->update = NULL;
-        present_flush(window);
-
-        present_pixmap_idle(vblank->pixmap, vblank->window, vblank->serial, vblank->idle_fence);
+        present_copy(vblank);
     }
 
     present_vblank_notify(vblank, ust, crtc_msc);
@@ -776,14 +807,8 @@ present_pixmap(WindowPtr window,
                           vblank->pixmap->drawable.id, vblank->window->drawable.id,
                           vblank->crtc));
 
-            present_pixmap_idle(vblank->pixmap, vblank->window, vblank->serial, vblank->idle_fence);
-            present_fence_destroy(vblank->idle_fence);
-            dixDestroyPixmap(vblank->pixmap, vblank->pixmap->drawable.id);
-
-            vblank->pixmap = NULL;
-            vblank->idle_fence = NULL;
+            present_vblank_idle(vblank);
             vblank->mode = PresentCompleteModeSkip;
-
             if (vblank->flip_ready)
                 present_re_execute(vblank);
         }
diff --git a/present/present_priv.h b/present/present_priv.h
index 1046952..23fe88b 100644
--- a/present/present_priv.h
+++ b/present/present_priv.h
@@ -74,6 +74,7 @@ struct present_vblank {
     Bool                flip_ready;     /* wants to flip, but waiting for previous flip or unflip */
     Bool                sync_flip;      /* do flip synchronous to vblank */
     Bool                abort_flip;     /* aborting this flip */
+    Bool                copied;         /* copy has been performed */
 };
 
 typedef struct present_screen_priv {
-- 
2.1.3



More information about the xorg-devel mailing list