[RFC xserver v3 07/11] present: Allow present implementations to wait on fences
Louis-Francis Ratté-Boulianne
lfrb at collabora.com
Mon Nov 6 21:42:56 UTC 2017
Instead of relying on the present module to wait on in-fences,
we added some hooks to allow the drivers/hardware to do the work.
Drivers need to implement can_wait_fence, wait_fence and
flip_with_fence to handle it.
v2: Rename hooks to can_wait_fence and wait_fence
Signed-off-by: Louis-Francis Ratté-Boulianne <lfrb at collabora.com>
---
present/present.c | 48 +++++++++++++++++++++++++++++++++++++++---------
present/present.h | 23 ++++++++++++++++++++++-
present/present_fence.c | 8 ++++++++
present/present_priv.h | 3 +++
4 files changed, 72 insertions(+), 10 deletions(-)
diff --git a/present/present.c b/present/present.c
index f866ea107..a6f85fe59 100644
--- a/present/present.c
+++ b/present/present.c
@@ -194,16 +194,34 @@ present_check_flip(RRCrtcPtr crtc,
}
static Bool
-present_flip(RRCrtcPtr crtc,
- uint64_t event_id,
- uint64_t target_msc,
- PixmapPtr pixmap,
- Bool sync_flip)
+present_flip(present_vblank_ptr vblank)
{
- ScreenPtr screen = crtc->pScreen;
+ ScreenPtr screen = vblank->crtc->pScreen;
present_screen_priv_ptr screen_priv = present_screen_priv(screen);
- return (*screen_priv->info->flip) (crtc, event_id, target_msc, pixmap, sync_flip);
+ if (vblank->wait_fence &&
+ screen_priv->info->flip_with_fence != NULL) {
+ Bool ret;
+
+ ret = (*screen_priv->info->flip_with_fence) (vblank->crtc,
+ vblank->event_id,
+ vblank->target_msc,
+ vblank->pixmap,
+ present_fence_get_fence(vblank->wait_fence),
+ vblank->sync_flip);
+
+ return ret;
+ } else if (vblank->wait_fence) {
+ if (!present_fence_check_triggered(vblank->wait_fence)) {
+ /* The can_wait_fence() hook should have returned FALSE before we
+ * tried to flip with an untriggered wait fence */
+ return FALSE;
+ }
+ }
+
+ return (*screen_priv->info->flip) (vblank->crtc, vblank->event_id,
+ vblank->target_msc, vblank->pixmap,
+ vblank->sync_flip);
}
static void
@@ -678,6 +696,7 @@ present_execute(present_vblank_ptr vblank, uint64_t ust, uint64_t crtc_msc)
ScreenPtr screen = window->drawable.pScreen;
present_screen_priv_ptr screen_priv = present_screen_priv(screen);
uint8_t mode;
+ Bool wait = FALSE;
if (vblank->requeue) {
vblank->requeue = FALSE;
@@ -690,7 +709,11 @@ present_execute(present_vblank_ptr vblank, uint64_t ust, uint64_t crtc_msc)
}
if (vblank->wait_fence) {
- if (!present_fence_check_triggered(vblank->wait_fence)) {
+ /* Check if present implementation can wait for the fence itself */
+ if (screen_priv->info->can_wait_fence &&
+ (*screen_priv->info->can_wait_fence) (vblank->crtc, present_fence_get_fence(vblank->wait_fence))) {
+ wait = TRUE;
+ } else if (!present_fence_check_triggered(vblank->wait_fence)) {
present_fence_set_callback(vblank->wait_fence, present_wait_fence_triggered, vblank);
return;
}
@@ -728,7 +751,7 @@ present_execute(present_vblank_ptr vblank, uint64_t ust, uint64_t crtc_msc)
xorg_list_add(&vblank->event_queue, &present_flip_queue);
/* Try to flip
*/
- if (present_flip(vblank->crtc, vblank->event_id, vblank->target_msc, vblank->pixmap, vblank->sync_flip)) {
+ if (present_flip(vblank)) {
RegionPtr damage;
/* Fix window pixmaps:
@@ -788,6 +811,13 @@ present_execute(present_vblank_ptr vblank, uint64_t ust, uint64_t crtc_msc)
return;
}
+ if (wait) {
+ (*screen_priv->info->wait_fence)(vblank->crtc,
+ present_fence_get_fence(vblank->wait_fence));
+ present_fence_destroy(vblank->wait_fence);
+ vblank->wait_fence = NULL;
+ }
+
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,
diff --git a/present/present.h b/present/present.h
index be41e8412..2c7175f4a 100644
--- a/present/present.h
+++ b/present/present.h
@@ -25,6 +25,7 @@
#include <X11/extensions/presentproto.h>
#include "randrstr.h"
+#include "misync.h"
#include "presentext.h"
#define PresentFlipReasonUnknown 0
@@ -83,6 +84,13 @@ typedef Bool (*present_flip_ptr) (RRCrtcPtr crtc,
PixmapPtr pixmap,
Bool sync_flip);
+typedef Bool (*present_flip_with_fence_ptr) (RRCrtcPtr crtc,
+ uint64_t event_id,
+ uint64_t target_msc,
+ PixmapPtr pixmap,
+ SyncFence *wait_fence,
+ Bool sync_flip);
+
/* "unflip" back to the regular screen scanout buffer
*
* present_event_notify should be called with 'event_id' when the unflip occurs.
@@ -90,7 +98,17 @@ typedef Bool (*present_flip_ptr) (RRCrtcPtr crtc,
typedef void (*present_unflip_ptr) (ScreenPtr screen,
uint64_t event_id);
-#define PRESENT_SCREEN_INFO_VERSION 1
+/* Return whether the fence can be waited upon
+ */
+typedef Bool (*present_can_wait_fence_ptr) (RRCrtcPtr crtc,
+ SyncFence *fence);
+
+/* Wait for the fence to be triggered
+ */
+typedef void (*present_wait_fence_ptr) (RRCrtcPtr crtc,
+ SyncFence *fence);
+
+#define PRESENT_SCREEN_INFO_VERSION 2
typedef struct present_screen_info {
uint32_t version;
@@ -105,6 +123,9 @@ typedef struct present_screen_info {
present_flip_ptr flip;
present_unflip_ptr unflip;
present_check_flip2_ptr check_flip2;
+ present_flip_with_fence_ptr flip_with_fence;
+ present_can_wait_fence_ptr can_wait_fence;
+ present_wait_fence_ptr wait_fence;
} present_screen_info_rec, *present_screen_info_ptr;
diff --git a/present/present_fence.c b/present/present_fence.c
index 87e7e17d8..019d06e09 100644
--- a/present/present_fence.c
+++ b/present/present_fence.c
@@ -91,6 +91,14 @@ present_fence_create(SyncFence *fence)
return present_fence;
}
+SyncFence *
+present_fence_get_fence(struct present_fence *present_fence)
+{
+ if (present_fence)
+ return present_fence->fence;
+ return NULL;
+}
+
void
present_fence_destroy(struct present_fence *present_fence)
{
diff --git a/present/present_priv.h b/present/present_priv.h
index 2fb9a2344..985780d01 100644
--- a/present/present_priv.h
+++ b/present/present_priv.h
@@ -255,6 +255,9 @@ present_fake_queue_init(void);
struct present_fence *
present_fence_create(SyncFence *sync_fence);
+SyncFence *
+present_fence_get_fence(struct present_fence *present_fence);
+
void
present_fence_destroy(struct present_fence *present_fence);
--
2.13.0
More information about the xorg-devel
mailing list