Drivers need to implement flip_with_fence and flush_with_fence to create out-fences.
Signed-off-by: Louis-Francis Ratté-Boulianne <[email protected]> --- configure.ac | 2 +- include/protocol-versions.h | 2 +- present/meson.build | 2 +- present/present.c | 68 +++++++++++++++++++++++++++++++++------------ present/present.h | 10 ++++++- present/present_priv.h | 2 ++ present/present_request.c | 9 +++++- 7 files changed, 73 insertions(+), 22 deletions(-) diff --git a/configure.ac b/configure.ac index 435daf71f..81d18b2e7 100644 --- a/configure.ac +++ b/configure.ac @@ -755,7 +755,7 @@ DAMAGEPROTO="damageproto >= 1.1" XCMISCPROTO="xcmiscproto >= 1.2.0" BIGREQSPROTO="bigreqsproto >= 1.1.0" XTRANS="xtrans >= 1.3.5" -PRESENTPROTO="presentproto >= 1.1" +PRESENTPROTO="presentproto >= 1.2" dnl List of libraries that require a specific version LIBAPPLEWM="applewm >= 1.4" diff --git a/include/protocol-versions.h b/include/protocol-versions.h index 524a630e8..0147c708c 100644 --- a/include/protocol-versions.h +++ b/include/protocol-versions.h @@ -69,7 +69,7 @@ /* Present */ #define SERVER_PRESENT_MAJOR_VERSION 1 -#define SERVER_PRESENT_MINOR_VERSION 1 +#define SERVER_PRESENT_MINOR_VERSION 2 /* RandR */ #define SERVER_RANDR_MAJOR_VERSION 1 diff --git a/present/meson.build b/present/meson.build index cf725302a..66d58bd34 100644 --- a/present/meson.build +++ b/present/meson.build @@ -13,7 +13,7 @@ libxserver_present = static_library('libxserver_present', include_directories: inc, dependencies: [ common_dep, - dependency('presentproto', version: '>= 1.1') + dependency('presentproto', version: '>= 1.2') ], c_args: '-DHAVE_XORG_CONFIG_H' ) diff --git a/present/present.c b/present/present.c index a6f85fe59..694bee890 100644 --- a/present/present.c +++ b/present/present.c @@ -193,24 +193,49 @@ present_check_flip(RRCrtcPtr crtc, return TRUE; } +static void +present_pixmap_idle(PixmapPtr pixmap, WindowPtr window, CARD32 serial, struct present_fence *present_fence) +{ + if (present_fence) + present_fence_set_triggered(present_fence); + if (window) { + DebugPresent(("\ti %08lx\n", pixmap ? pixmap->drawable.id : 0)); + present_send_idle_notify(window, serial, pixmap, present_fence); + } +} + static Bool present_flip(present_vblank_ptr vblank) { ScreenPtr screen = vblank->crtc->pScreen; present_screen_priv_ptr screen_priv = present_screen_priv(screen); - if (vblank->wait_fence && + if ((vblank->notify_fence || vblank->wait_fence) && screen_priv->info->flip_with_fence != NULL) { + SyncFence *idle_fence = NULL; Bool ret; + if (vblank->notify_fence && screen_priv->flip_idle_fence) + idle_fence = present_fence_get_fence(screen_priv->flip_idle_fence); + ret = (*screen_priv->info->flip_with_fence) (vblank->crtc, vblank->event_id, vblank->target_msc, vblank->pixmap, present_fence_get_fence(vblank->wait_fence), + idle_fence, vblank->sync_flip); + if (ret && screen_priv->flip_notify_fence) { + present_pixmap_idle(screen_priv->flip_pixmap, screen_priv->flip_window, + screen_priv->flip_serial, screen_priv->flip_idle_fence); + } + return ret; + } else if (vblank->notify_fence) { + /* The driver shouldn't have advertised support for IdleFence capability + * or the client should have check for it before using the option */ + return FALSE; } else if (vblank->wait_fence) { if (!present_fence_check_triggered(vblank->wait_fence)) { /* The can_wait_fence() hook should have returned FALSE before we @@ -240,17 +265,6 @@ present_vblank_notify(present_vblank_ptr vblank, CARD8 kind, CARD8 mode, uint64_ } } -static void -present_pixmap_idle(PixmapPtr pixmap, WindowPtr window, CARD32 serial, struct present_fence *present_fence) -{ - if (present_fence) - present_fence_set_triggered(present_fence); - if (window) { - DebugPresent(("\ti %08lx\n", pixmap ? pixmap->drawable.id : 0)); - present_send_idle_notify(window, serial, pixmap, present_fence); - } -} - RRCrtcPtr present_get_crtc(WindowPtr window) { @@ -297,8 +311,9 @@ present_get_ust_msc(ScreenPtr screen, RRCrtcPtr crtc, uint64_t *ust, uint64_t *m } static void -present_flush(WindowPtr window) +present_flush(present_vblank_ptr vblank) { + WindowPtr window = vblank->window; ScreenPtr screen = window->drawable.pScreen; present_screen_priv_ptr screen_priv = present_screen_priv(screen); @@ -308,7 +323,12 @@ present_flush(WindowPtr window) if (!screen_priv->info) return; - (*screen_priv->info->flush) (window); + if (vblank->notify_fence && screen_priv->info->flush_with_fence) { + (*screen_priv->info->flush_with_fence) (window, + present_fence_get_fence(vblank->idle_fence)); + } else { + (*screen_priv->info->flush) (window); + } } static int @@ -389,8 +409,10 @@ present_flip_idle(ScreenPtr screen) present_screen_priv_ptr screen_priv = present_screen_priv(screen); if (screen_priv->flip_pixmap) { - present_pixmap_idle(screen_priv->flip_pixmap, screen_priv->flip_window, - screen_priv->flip_serial, screen_priv->flip_idle_fence); + if (!screen_priv->flip_notify_fence) { + present_pixmap_idle(screen_priv->flip_pixmap, screen_priv->flip_window, + screen_priv->flip_serial, screen_priv->flip_idle_fence); + } if (screen_priv->flip_idle_fence) present_fence_destroy(screen_priv->flip_idle_fence); dixDestroyPixmap(screen_priv->flip_pixmap, screen_priv->flip_pixmap->drawable.id); @@ -521,6 +543,7 @@ present_flip_notify(present_vblank_ptr vblank, uint64_t ust, uint64_t crtc_msc) screen_priv->flip_pixmap = vblank->pixmap; screen_priv->flip_sync = vblank->sync_flip; screen_priv->flip_idle_fence = vblank->idle_fence; + screen_priv->flip_notify_fence = vblank->notify_fence; vblank->pixmap = NULL; vblank->idle_fence = NULL; @@ -824,7 +847,7 @@ present_execute(present_vblank_ptr vblank, uint64_t ust, uint64_t crtc_msc) * which is then freed, freeing the region */ vblank->update = NULL; - present_flush(window); + present_flush(vblank); present_pixmap_idle(vblank->pixmap, vblank->window, vblank->serial, vblank->idle_fence); } @@ -1024,6 +1047,17 @@ present_pixmap(WindowPtr window, goto no_mem; } + if (options & PresentOptionIdleFence) { + if (vblank->idle_fence == NULL) { + vblank->notifies = NULL; + present_vblank_destroy(vblank); + return BadValue; + } + if (!(screen_priv->info->capabilities & PresentCapabilityIdleFence)) + return BadValue; + vblank->notify_fence = TRUE; + } + if (pixmap) DebugPresent(("q %lld %p %8lld: %08lx -> %08lx (crtc %p) flip %d vsync %d serial %d\n", vblank->event_id, vblank, target_msc, diff --git a/present/present.h b/present/present.h index 2c7175f4a..af8395ad4 100644 --- a/present/present.h +++ b/present/present.h @@ -59,6 +59,12 @@ typedef void (*present_abort_vblank_ptr) (RRCrtcPtr crtc, uint64_t event_id, uin */ typedef void (*present_flush_ptr) (WindowPtr window); +/* Flush pending drawing on 'window' to the hardware. + * + * 'idle_fence' should return the out-fence + */ +typedef void (*present_flush_with_fence_ptr) (WindowPtr window, SyncFence *idle_fence); + /* Check if 'pixmap' is suitable for flipping to 'window'. */ typedef Bool (*present_check_flip_ptr) (RRCrtcPtr crtc, WindowPtr window, PixmapPtr pixmap, Bool sync_flip); @@ -89,6 +95,7 @@ typedef Bool (*present_flip_with_fence_ptr) (RRCrtcPtr crtc, uint64_t target_msc, PixmapPtr pixmap, SyncFence *wait_fence, + SyncFence *idle_fence, Bool sync_flip); /* "unflip" back to the regular screen scanout buffer @@ -108,7 +115,7 @@ typedef Bool (*present_can_wait_fence_ptr) (RRCrtcPtr crtc, typedef void (*present_wait_fence_ptr) (RRCrtcPtr crtc, SyncFence *fence); -#define PRESENT_SCREEN_INFO_VERSION 2 +#define PRESENT_SCREEN_INFO_VERSION 3 typedef struct present_screen_info { uint32_t version; @@ -126,6 +133,7 @@ typedef struct present_screen_info { present_flip_with_fence_ptr flip_with_fence; present_can_wait_fence_ptr can_wait_fence; present_wait_fence_ptr wait_fence; + present_flush_with_fence_ptr flush_with_fence; } present_screen_info_rec, *present_screen_info_ptr; diff --git a/present/present_priv.h b/present/present_priv.h index 985780d01..1bfeb62ba 100644 --- a/present/present_priv.h +++ b/present/present_priv.h @@ -77,6 +77,7 @@ struct present_vblank { Bool abort_flip; /* aborting this flip */ int reason; /* reason for which flip is not possible */ Bool has_suboptimal; /* whether client can support SuboptimalCopy mode */ + Bool notify_fence; /* send fence with Idle event */ }; typedef struct present_screen_priv { @@ -97,6 +98,7 @@ typedef struct present_screen_priv { PixmapPtr flip_pixmap; present_fence_ptr flip_idle_fence; Bool flip_sync; + Bool flip_notify_fence; present_screen_info_ptr info; } present_screen_priv_rec, *present_screen_priv_ptr; diff --git a/present/present_request.c b/present/present_request.c index c6afe5fa7..4bad47fd2 100644 --- a/present/present_request.c +++ b/present/present_request.c @@ -102,13 +102,20 @@ proc_present_pixmap(ClientPtr client) VERIFY_CRTC_OR_NONE(target_crtc, stuff->target_crtc, client, DixReadAccess); VERIFY_FENCE_OR_NONE(wait_fence, stuff->wait_fence, client, DixReadAccess); - VERIFY_FENCE_OR_NONE(idle_fence, stuff->idle_fence, client, DixWriteAccess); if (stuff->options & ~(PresentAllOptions)) { client->errorValue = stuff->options; return BadValue; } + if (stuff->options & PresentOptionIdleFence) { + LEGAL_NEW_RESOURCE(stuff->idle_fence, client); + ret = SyncCreateFenceFromDMAFenceFD(client, &pixmap->drawable, stuff->idle_fence, -1); + if (ret != Success) + return ret; + } + VERIFY_FENCE_OR_NONE(idle_fence, stuff->idle_fence, client, DixWriteAccess); + /* * Check to see if remainder is sane */ -- 2.13.0 _______________________________________________ [email protected]: X.Org development Archives: http://lists.x.org/archives/xorg-devel Info: https://lists.x.org/mailman/listinfo/xorg-devel
