Present: add PresentCapabilitySyncobj and PresentPixmapSynced
Signed-off-by: Erik Kurzinger <ekurzinger@nvidia.com> Part-of: <https://gitlab.freedesktop.org/xorg/xserver/-/merge_requests/967>
This commit is contained in:
parent
0a7b09a041
commit
ac0bc0b3b6
|
@ -74,7 +74,7 @@
|
||||||
* mask is 0xFFFF0000.
|
* mask is 0xFFFF0000.
|
||||||
*/
|
*/
|
||||||
#define ABI_ANSIC_VERSION SET_ABI_VERSION(0, 4)
|
#define ABI_ANSIC_VERSION SET_ABI_VERSION(0, 4)
|
||||||
#define ABI_VIDEODRV_VERSION SET_ABI_VERSION(26, 1)
|
#define ABI_VIDEODRV_VERSION SET_ABI_VERSION(27, 0)
|
||||||
#define ABI_XINPUT_VERSION SET_ABI_VERSION(24, 4)
|
#define ABI_XINPUT_VERSION SET_ABI_VERSION(24, 4)
|
||||||
#define ABI_EXTENSION_VERSION SET_ABI_VERSION(10, 0)
|
#define ABI_EXTENSION_VERSION SET_ABI_VERSION(10, 0)
|
||||||
|
|
||||||
|
|
|
@ -1007,6 +1007,12 @@ xwl_present_pixmap(WindowPtr window,
|
||||||
RRCrtcPtr target_crtc,
|
RRCrtcPtr target_crtc,
|
||||||
SyncFence *wait_fence,
|
SyncFence *wait_fence,
|
||||||
SyncFence *idle_fence,
|
SyncFence *idle_fence,
|
||||||
|
#ifdef DRI3
|
||||||
|
struct dri3_syncobj *acquire_syncobj,
|
||||||
|
struct dri3_syncobj *release_syncobj,
|
||||||
|
uint64_t acquire_point,
|
||||||
|
uint64_t release_point,
|
||||||
|
#endif /* DRI3 */
|
||||||
uint32_t options,
|
uint32_t options,
|
||||||
uint64_t target_window_msc,
|
uint64_t target_window_msc,
|
||||||
uint64_t divisor,
|
uint64_t divisor,
|
||||||
|
@ -1028,6 +1034,11 @@ xwl_present_pixmap(WindowPtr window,
|
||||||
if (!window_priv)
|
if (!window_priv)
|
||||||
return BadAlloc;
|
return BadAlloc;
|
||||||
|
|
||||||
|
#ifdef DRI3
|
||||||
|
if (acquire_syncobj || release_syncobj)
|
||||||
|
return BadValue;
|
||||||
|
#endif /* DRI3 */
|
||||||
|
|
||||||
target_crtc = xwl_present_get_crtc(screen_priv, window);
|
target_crtc = xwl_present_get_crtc(screen_priv, window);
|
||||||
|
|
||||||
ret = xwl_present_get_ust_msc(screen, window, &ust, &crtc_msc);
|
ret = xwl_present_get_ust_msc(screen, window, &ust, &crtc_msc);
|
||||||
|
@ -1077,8 +1088,11 @@ xwl_present_pixmap(WindowPtr window,
|
||||||
|
|
||||||
vblank = &event->vblank;
|
vblank = &event->vblank;
|
||||||
if (!present_vblank_init(vblank, window, pixmap, serial, valid, update, x_off, y_off,
|
if (!present_vblank_init(vblank, window, pixmap, serial, valid, update, x_off, y_off,
|
||||||
target_crtc, wait_fence, idle_fence, options, XWL_PRESENT_CAPS,
|
target_crtc, wait_fence, idle_fence,
|
||||||
notifies, num_notifies, target_msc, crtc_msc)) {
|
#ifdef DRI3
|
||||||
|
acquire_syncobj, release_syncobj, acquire_point, release_point,
|
||||||
|
#endif /* DRI3 */
|
||||||
|
options, XWL_PRESENT_CAPS, notifies, num_notifies, target_msc, crtc_msc)) {
|
||||||
present_vblank_destroy(vblank);
|
present_vblank_destroy(vblank);
|
||||||
return BadAlloc;
|
return BadAlloc;
|
||||||
}
|
}
|
||||||
|
|
|
@ -68,7 +68,11 @@
|
||||||
|
|
||||||
/* Present */
|
/* Present */
|
||||||
#define SERVER_PRESENT_MAJOR_VERSION 1
|
#define SERVER_PRESENT_MAJOR_VERSION 1
|
||||||
#define SERVER_PRESENT_MINOR_VERSION 2
|
#ifdef DRI3
|
||||||
|
#define SERVER_PRESENT_MINOR_VERSION 4
|
||||||
|
#else
|
||||||
|
#define SERVER_PRESENT_MINOR_VERSION 3
|
||||||
|
#endif
|
||||||
|
|
||||||
/* RandR */
|
/* RandR */
|
||||||
#define SERVER_RANDR_MAJOR_VERSION 1
|
#define SERVER_RANDR_MAJOR_VERSION 1
|
||||||
|
|
|
@ -81,7 +81,7 @@ fixesproto_dep = dependency('fixesproto', version: '>= 6.0', fallback: ['xorgpro
|
||||||
damageproto_dep = dependency('damageproto', version: '>= 1.1', fallback: ['xorgproto', 'ext_xorgproto'])
|
damageproto_dep = dependency('damageproto', version: '>= 1.1', fallback: ['xorgproto', 'ext_xorgproto'])
|
||||||
xcmiscproto_dep = dependency('xcmiscproto', version: '>= 1.2.0', fallback: ['xorgproto', 'ext_xorgproto'])
|
xcmiscproto_dep = dependency('xcmiscproto', version: '>= 1.2.0', fallback: ['xorgproto', 'ext_xorgproto'])
|
||||||
bigreqsproto_dep = dependency('bigreqsproto', version: '>= 1.1.0', fallback: ['xorgproto', 'ext_xorgproto'])
|
bigreqsproto_dep = dependency('bigreqsproto', version: '>= 1.1.0', fallback: ['xorgproto', 'ext_xorgproto'])
|
||||||
presentproto_dep = dependency('presentproto', version: '>= 1.3', fallback: ['xorgproto', 'ext_xorgproto'])
|
presentproto_dep = dependency('presentproto', version: '>= 1.4', fallback: ['xorgproto', 'ext_xorgproto'])
|
||||||
xtrans_dep = dependency('xtrans', version: '>= 1.3.5')
|
xtrans_dep = dependency('xtrans', version: '>= 1.3.5')
|
||||||
|
|
||||||
videoproto_dep = dependency('videoproto', fallback: ['xorgproto', 'ext_xorgproto'])
|
videoproto_dep = dependency('videoproto', fallback: ['xorgproto', 'ext_xorgproto'])
|
||||||
|
|
|
@ -230,6 +230,12 @@ present_pixmap(WindowPtr window,
|
||||||
RRCrtcPtr target_crtc,
|
RRCrtcPtr target_crtc,
|
||||||
SyncFence *wait_fence,
|
SyncFence *wait_fence,
|
||||||
SyncFence *idle_fence,
|
SyncFence *idle_fence,
|
||||||
|
#ifdef DRI3
|
||||||
|
struct dri3_syncobj *acquire_syncobj,
|
||||||
|
struct dri3_syncobj *release_syncobj,
|
||||||
|
uint64_t acquire_point,
|
||||||
|
uint64_t release_point,
|
||||||
|
#endif /* DRI3 */
|
||||||
uint32_t options,
|
uint32_t options,
|
||||||
uint64_t window_msc,
|
uint64_t window_msc,
|
||||||
uint64_t divisor,
|
uint64_t divisor,
|
||||||
|
@ -250,6 +256,12 @@ present_pixmap(WindowPtr window,
|
||||||
target_crtc,
|
target_crtc,
|
||||||
wait_fence,
|
wait_fence,
|
||||||
idle_fence,
|
idle_fence,
|
||||||
|
#ifdef DRI3
|
||||||
|
acquire_syncobj,
|
||||||
|
release_syncobj,
|
||||||
|
acquire_point,
|
||||||
|
release_point,
|
||||||
|
#endif /* DRI3 */
|
||||||
options,
|
options,
|
||||||
window_msc,
|
window_msc,
|
||||||
divisor,
|
divisor,
|
||||||
|
@ -272,6 +284,9 @@ present_notify_msc(WindowPtr window,
|
||||||
0, 0,
|
0, 0,
|
||||||
NULL,
|
NULL,
|
||||||
NULL, NULL,
|
NULL, NULL,
|
||||||
|
#ifdef DRI3
|
||||||
|
NULL, NULL, 0, 0,
|
||||||
|
#endif /* DRI3 */
|
||||||
divisor == 0 ? PresentOptionAsync : 0,
|
divisor == 0 ? PresentOptionAsync : 0,
|
||||||
target_msc, divisor, remainder, NULL, 0);
|
target_msc, divisor, remainder, NULL, 0);
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,6 +21,10 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "present_priv.h"
|
#include "present_priv.h"
|
||||||
|
#include <unistd.h>
|
||||||
|
#ifdef DRI3
|
||||||
|
#include <sys/eventfd.h>
|
||||||
|
#endif /* DRI3 */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Called when the wait fence is triggered; just gets the current msc/ust and
|
* Called when the wait fence is triggered; just gets the current msc/ust and
|
||||||
|
@ -37,6 +41,21 @@ present_wait_fence_triggered(void *param)
|
||||||
screen_priv->re_execute(vblank);
|
screen_priv->re_execute(vblank);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef DRI3
|
||||||
|
static void present_syncobj_triggered(int fd, int xevents, void *data)
|
||||||
|
{
|
||||||
|
present_vblank_ptr vblank = data;
|
||||||
|
ScreenPtr screen = vblank->screen;
|
||||||
|
present_screen_priv_ptr screen_priv = present_screen_priv(screen);
|
||||||
|
|
||||||
|
SetNotifyFd(fd, NULL, 0, NULL);
|
||||||
|
close(fd);
|
||||||
|
vblank->efd = -1;
|
||||||
|
|
||||||
|
screen_priv->re_execute(vblank);
|
||||||
|
}
|
||||||
|
#endif /* DRI3 */
|
||||||
|
|
||||||
Bool
|
Bool
|
||||||
present_execute_wait(present_vblank_ptr vblank, uint64_t crtc_msc)
|
present_execute_wait(present_vblank_ptr vblank, uint64_t crtc_msc)
|
||||||
{
|
{
|
||||||
|
@ -58,6 +77,20 @@ present_execute_wait(present_vblank_ptr vblank, uint64_t crtc_msc)
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef DRI3
|
||||||
|
if (vblank->acquire_syncobj &&
|
||||||
|
!vblank->acquire_syncobj->is_signaled(vblank->acquire_syncobj,
|
||||||
|
vblank->acquire_point)) {
|
||||||
|
vblank->efd = eventfd(0, EFD_CLOEXEC);
|
||||||
|
SetNotifyFd(vblank->efd, present_syncobj_triggered, X_NOTIFY_READ, vblank);
|
||||||
|
vblank->acquire_syncobj->signaled_eventfd(vblank->acquire_syncobj,
|
||||||
|
vblank->acquire_point,
|
||||||
|
vblank->efd);
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
#endif /* DRI3 */
|
||||||
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -85,9 +118,17 @@ present_execute_copy(present_vblank_ptr vblank, uint64_t crtc_msc)
|
||||||
* which is then freed, freeing the region
|
* which is then freed, freeing the region
|
||||||
*/
|
*/
|
||||||
vblank->update = NULL;
|
vblank->update = NULL;
|
||||||
|
#ifdef DRI3
|
||||||
|
if (vblank->release_syncobj) {
|
||||||
|
int fence_fd = screen_priv->flush_fenced(window);
|
||||||
|
vblank->release_syncobj->import_fence(vblank->release_syncobj,
|
||||||
|
vblank->release_point, fence_fd);
|
||||||
|
} else
|
||||||
|
#endif /* DRI3 */
|
||||||
|
{
|
||||||
screen_priv->flush(window);
|
screen_priv->flush(window);
|
||||||
|
|
||||||
present_pixmap_idle(vblank->pixmap, vblank->window, vblank->serial, vblank->idle_fence);
|
present_pixmap_idle(vblank->pixmap, vblank->window, vblank->serial, vblank->idle_fence);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
|
@ -36,6 +36,7 @@
|
||||||
#include <xfixes.h>
|
#include <xfixes.h>
|
||||||
#include <randrstr.h>
|
#include <randrstr.h>
|
||||||
#include <inttypes.h>
|
#include <inttypes.h>
|
||||||
|
#include "dri3.h"
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
#define DebugPresent(x) ErrorF x
|
#define DebugPresent(x) ErrorF x
|
||||||
|
@ -90,6 +91,13 @@ struct present_vblank {
|
||||||
Bool abort_flip; /* aborting this flip */
|
Bool abort_flip; /* aborting this flip */
|
||||||
PresentFlipReason reason; /* reason for which flip is not possible */
|
PresentFlipReason reason; /* reason for which flip is not possible */
|
||||||
Bool has_suboptimal; /* whether client can support SuboptimalCopy mode */
|
Bool has_suboptimal; /* whether client can support SuboptimalCopy mode */
|
||||||
|
#ifdef DRI3
|
||||||
|
struct dri3_syncobj *acquire_syncobj;
|
||||||
|
struct dri3_syncobj *release_syncobj;
|
||||||
|
uint64_t acquire_point;
|
||||||
|
uint64_t release_point;
|
||||||
|
int efd;
|
||||||
|
#endif /* DRI3 */
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef struct present_screen_priv present_screen_priv_rec, *present_screen_priv_ptr;
|
typedef struct present_screen_priv present_screen_priv_rec, *present_screen_priv_ptr;
|
||||||
|
@ -124,6 +132,12 @@ typedef int (*present_priv_pixmap_ptr)(WindowPtr window,
|
||||||
RRCrtcPtr target_crtc,
|
RRCrtcPtr target_crtc,
|
||||||
SyncFence *wait_fence,
|
SyncFence *wait_fence,
|
||||||
SyncFence *idle_fence,
|
SyncFence *idle_fence,
|
||||||
|
#ifdef DRI3
|
||||||
|
struct dri3_syncobj *acquire_syncobj,
|
||||||
|
struct dri3_syncobj *release_syncobj,
|
||||||
|
uint64_t acquire_point,
|
||||||
|
uint64_t release_point,
|
||||||
|
#endif /* DRI3 */
|
||||||
uint32_t options,
|
uint32_t options,
|
||||||
uint64_t window_msc,
|
uint64_t window_msc,
|
||||||
uint64_t divisor,
|
uint64_t divisor,
|
||||||
|
@ -137,6 +151,7 @@ typedef int (*present_priv_queue_vblank_ptr)(ScreenPtr screen,
|
||||||
uint64_t event_id,
|
uint64_t event_id,
|
||||||
uint64_t msc);
|
uint64_t msc);
|
||||||
typedef void (*present_priv_flush_ptr)(WindowPtr window);
|
typedef void (*present_priv_flush_ptr)(WindowPtr window);
|
||||||
|
typedef int (*present_priv_flush_fenced_ptr)(WindowPtr window);
|
||||||
typedef void (*present_priv_re_execute_ptr)(present_vblank_ptr vblank);
|
typedef void (*present_priv_re_execute_ptr)(present_vblank_ptr vblank);
|
||||||
|
|
||||||
typedef void (*present_priv_abort_vblank_ptr)(ScreenPtr screen,
|
typedef void (*present_priv_abort_vblank_ptr)(ScreenPtr screen,
|
||||||
|
@ -147,6 +162,7 @@ typedef void (*present_priv_abort_vblank_ptr)(ScreenPtr screen,
|
||||||
typedef void (*present_priv_flip_destroy_ptr)(ScreenPtr screen);
|
typedef void (*present_priv_flip_destroy_ptr)(ScreenPtr screen);
|
||||||
|
|
||||||
struct present_screen_priv {
|
struct present_screen_priv {
|
||||||
|
ScreenPtr pScreen;
|
||||||
CloseScreenProcPtr CloseScreen;
|
CloseScreenProcPtr CloseScreen;
|
||||||
ConfigNotifyProcPtr ConfigNotify;
|
ConfigNotifyProcPtr ConfigNotify;
|
||||||
DestroyWindowProcPtr DestroyWindow;
|
DestroyWindowProcPtr DestroyWindow;
|
||||||
|
@ -180,6 +196,7 @@ struct present_screen_priv {
|
||||||
|
|
||||||
present_priv_queue_vblank_ptr queue_vblank;
|
present_priv_queue_vblank_ptr queue_vblank;
|
||||||
present_priv_flush_ptr flush;
|
present_priv_flush_ptr flush;
|
||||||
|
present_priv_flush_fenced_ptr flush_fenced;
|
||||||
present_priv_re_execute_ptr re_execute;
|
present_priv_re_execute_ptr re_execute;
|
||||||
|
|
||||||
present_priv_abort_vblank_ptr abort_vblank;
|
present_priv_abort_vblank_ptr abort_vblank;
|
||||||
|
@ -290,6 +307,12 @@ present_pixmap(WindowPtr window,
|
||||||
RRCrtcPtr target_crtc,
|
RRCrtcPtr target_crtc,
|
||||||
SyncFence *wait_fence,
|
SyncFence *wait_fence,
|
||||||
SyncFence *idle_fence,
|
SyncFence *idle_fence,
|
||||||
|
#ifdef DRI3
|
||||||
|
struct dri3_syncobj *acquire_syncobj,
|
||||||
|
struct dri3_syncobj *release_syncobj,
|
||||||
|
uint64_t acquire_point,
|
||||||
|
uint64_t release_point,
|
||||||
|
#endif /* DRI3 */
|
||||||
uint32_t options,
|
uint32_t options,
|
||||||
uint64_t target_msc,
|
uint64_t target_msc,
|
||||||
uint64_t divisor,
|
uint64_t divisor,
|
||||||
|
@ -464,6 +487,12 @@ present_vblank_init(present_vblank_ptr vblank,
|
||||||
RRCrtcPtr target_crtc,
|
RRCrtcPtr target_crtc,
|
||||||
SyncFence *wait_fence,
|
SyncFence *wait_fence,
|
||||||
SyncFence *idle_fence,
|
SyncFence *idle_fence,
|
||||||
|
#ifdef DRI3
|
||||||
|
struct dri3_syncobj *acquire_syncobj,
|
||||||
|
struct dri3_syncobj *release_syncobj,
|
||||||
|
uint64_t acquire_point,
|
||||||
|
uint64_t release_point,
|
||||||
|
#endif /* DRI3 */
|
||||||
uint32_t options,
|
uint32_t options,
|
||||||
const uint32_t capabilities,
|
const uint32_t capabilities,
|
||||||
present_notify_ptr notifies,
|
present_notify_ptr notifies,
|
||||||
|
@ -482,6 +511,12 @@ present_vblank_create(WindowPtr window,
|
||||||
RRCrtcPtr target_crtc,
|
RRCrtcPtr target_crtc,
|
||||||
SyncFence *wait_fence,
|
SyncFence *wait_fence,
|
||||||
SyncFence *idle_fence,
|
SyncFence *idle_fence,
|
||||||
|
#ifdef DRI3
|
||||||
|
struct dri3_syncobj *acquire_syncobj,
|
||||||
|
struct dri3_syncobj *release_syncobj,
|
||||||
|
uint64_t acquire_point,
|
||||||
|
uint64_t release_point,
|
||||||
|
#endif /* DRI3 */
|
||||||
uint32_t options,
|
uint32_t options,
|
||||||
const uint32_t capabilities,
|
const uint32_t capabilities,
|
||||||
present_notify_ptr notifies,
|
present_notify_ptr notifies,
|
||||||
|
|
|
@ -79,79 +79,123 @@ proc_present_query_version(ClientPtr client)
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
static int
|
static int
|
||||||
proc_present_pixmap(ClientPtr client)
|
proc_present_pixmap_common(ClientPtr client,
|
||||||
|
Window req_window,
|
||||||
|
Pixmap req_pixmap,
|
||||||
|
CARD32 req_serial,
|
||||||
|
CARD32 req_valid,
|
||||||
|
CARD32 req_update,
|
||||||
|
INT16 req_x_off,
|
||||||
|
INT16 req_y_off,
|
||||||
|
CARD32 req_target_crtc,
|
||||||
|
XSyncFence req_wait_fence,
|
||||||
|
XSyncFence req_idle_fence,
|
||||||
|
#ifdef DRI3
|
||||||
|
struct dri3_syncobj *acquire_syncobj,
|
||||||
|
struct dri3_syncobj *release_syncobj,
|
||||||
|
CARD64 req_acquire_point,
|
||||||
|
CARD64 req_release_point,
|
||||||
|
#endif /* DRI3 */
|
||||||
|
CARD32 req_options,
|
||||||
|
CARD64 req_target_msc,
|
||||||
|
CARD64 req_divisor,
|
||||||
|
CARD64 req_remainder,
|
||||||
|
size_t base_req_size,
|
||||||
|
xPresentNotify *req_notifies)
|
||||||
{
|
{
|
||||||
REQUEST(xPresentPixmapReq);
|
|
||||||
WindowPtr window;
|
WindowPtr window;
|
||||||
PixmapPtr pixmap;
|
PixmapPtr pixmap;
|
||||||
RegionPtr valid = NULL;
|
RegionPtr valid = NULL;
|
||||||
RegionPtr update = NULL;
|
RegionPtr update = NULL;
|
||||||
|
RRCrtcPtr target_crtc;
|
||||||
SyncFence *wait_fence;
|
SyncFence *wait_fence;
|
||||||
SyncFence *idle_fence;
|
SyncFence *idle_fence;
|
||||||
RRCrtcPtr target_crtc;
|
|
||||||
int ret;
|
|
||||||
int nnotifies;
|
int nnotifies;
|
||||||
present_notify_ptr notifies = NULL;
|
present_notify_ptr notifies = NULL;
|
||||||
|
int ret;
|
||||||
|
|
||||||
REQUEST_AT_LEAST_SIZE(xPresentPixmapReq);
|
ret = dixLookupWindow(&window, req_window, client, DixWriteAccess);
|
||||||
ret = dixLookupWindow(&window, stuff->window, client, DixWriteAccess);
|
|
||||||
if (ret != Success)
|
if (ret != Success)
|
||||||
return ret;
|
return ret;
|
||||||
ret = dixLookupResourceByType((void **) &pixmap, stuff->pixmap, RT_PIXMAP, client, DixReadAccess);
|
ret = dixLookupResourceByType((void **) &pixmap, req_pixmap, RT_PIXMAP, client, DixReadAccess);
|
||||||
if (ret != Success)
|
if (ret != Success)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
if (window->drawable.depth != pixmap->drawable.depth)
|
if (window->drawable.depth != pixmap->drawable.depth)
|
||||||
return BadMatch;
|
return BadMatch;
|
||||||
|
|
||||||
VERIFY_REGION_OR_NONE(valid, stuff->valid, client, DixReadAccess);
|
VERIFY_REGION_OR_NONE(valid, req_valid, client, DixReadAccess);
|
||||||
VERIFY_REGION_OR_NONE(update, stuff->update, client, DixReadAccess);
|
VERIFY_REGION_OR_NONE(update, req_update, client, DixReadAccess);
|
||||||
|
|
||||||
VERIFY_CRTC_OR_NONE(target_crtc, stuff->target_crtc, client, DixReadAccess);
|
VERIFY_CRTC_OR_NONE(target_crtc, req_target_crtc, client, DixReadAccess);
|
||||||
|
|
||||||
VERIFY_FENCE_OR_NONE(wait_fence, stuff->wait_fence, client, DixReadAccess);
|
VERIFY_FENCE_OR_NONE(wait_fence, req_wait_fence, client, DixReadAccess);
|
||||||
VERIFY_FENCE_OR_NONE(idle_fence, stuff->idle_fence, client, DixWriteAccess);
|
VERIFY_FENCE_OR_NONE(idle_fence, req_idle_fence, client, DixWriteAccess);
|
||||||
|
|
||||||
if (stuff->options & ~(PresentAllOptions)) {
|
if (req_options & ~(PresentAllOptions)) {
|
||||||
client->errorValue = stuff->options;
|
client->errorValue = req_options;
|
||||||
return BadValue;
|
return BadValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Check to see if remainder is sane
|
* Check to see if remainder is sane
|
||||||
*/
|
*/
|
||||||
if (stuff->divisor == 0) {
|
if (req_divisor == 0) {
|
||||||
if (stuff->remainder != 0) {
|
if (req_remainder != 0) {
|
||||||
client->errorValue = (CARD32) stuff->remainder;
|
client->errorValue = (CARD32)req_remainder;
|
||||||
return BadValue;
|
return BadValue;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (stuff->remainder >= stuff->divisor) {
|
if (req_remainder >= req_divisor) {
|
||||||
client->errorValue = (CARD32) stuff->remainder;
|
client->errorValue = (CARD32)req_remainder;
|
||||||
return BadValue;
|
return BadValue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
nnotifies = (client->req_len << 2) - sizeof (xPresentPixmapReq);
|
nnotifies = (client->req_len << 2) - base_req_size;
|
||||||
if (nnotifies % sizeof (xPresentNotify))
|
if (nnotifies % sizeof (xPresentNotify))
|
||||||
return BadLength;
|
return BadLength;
|
||||||
|
|
||||||
nnotifies /= sizeof (xPresentNotify);
|
nnotifies /= sizeof (xPresentNotify);
|
||||||
if (nnotifies) {
|
if (nnotifies) {
|
||||||
ret = present_create_notifies(client, nnotifies, (xPresentNotify *) (stuff + 1), ¬ifies);
|
ret = present_create_notifies(client, nnotifies, req_notifies, ¬ifies);
|
||||||
if (ret != Success)
|
if (ret != Success)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = present_pixmap(window, pixmap, stuff->serial, valid, update,
|
ret = present_pixmap(window, pixmap, req_serial,
|
||||||
stuff->x_off, stuff->y_off, target_crtc,
|
valid, update, req_x_off, req_y_off, target_crtc,
|
||||||
wait_fence, idle_fence, stuff->options,
|
wait_fence, idle_fence,
|
||||||
stuff->target_msc, stuff->divisor, stuff->remainder, notifies, nnotifies);
|
#ifdef DRI3
|
||||||
|
acquire_syncobj, release_syncobj,
|
||||||
|
req_acquire_point, req_release_point,
|
||||||
|
#endif /* DRI3 */
|
||||||
|
req_options, req_target_msc, req_divisor, req_remainder,
|
||||||
|
notifies, nnotifies);
|
||||||
|
|
||||||
if (ret != Success)
|
if (ret != Success)
|
||||||
present_destroy_notifies(notifies, nnotifies);
|
present_destroy_notifies(notifies, nnotifies);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
proc_present_pixmap(ClientPtr client)
|
||||||
|
{
|
||||||
|
REQUEST(xPresentPixmapReq);
|
||||||
|
REQUEST_AT_LEAST_SIZE(xPresentPixmapReq);
|
||||||
|
return proc_present_pixmap_common(client, stuff->window, stuff->pixmap, stuff->serial,
|
||||||
|
stuff->valid, stuff->update, stuff->x_off, stuff->y_off,
|
||||||
|
stuff->target_crtc,
|
||||||
|
stuff->wait_fence, stuff->idle_fence,
|
||||||
|
#ifdef DRI3
|
||||||
|
None, None, 0, 0,
|
||||||
|
#endif /* DRI3 */
|
||||||
|
stuff->options, stuff->target_msc,
|
||||||
|
stuff->divisor, stuff->remainder,
|
||||||
|
sizeof (xPresentPixmapReq),
|
||||||
|
(xPresentNotify *)(stuff + 1));
|
||||||
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
proc_present_notify_msc(ClientPtr client)
|
proc_present_notify_msc(ClientPtr client)
|
||||||
{
|
{
|
||||||
|
@ -240,12 +284,45 @@ proc_present_query_capabilities (ClientPtr client)
|
||||||
return Success;
|
return Success;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef DRI3
|
||||||
|
static int
|
||||||
|
proc_present_pixmap_synced (ClientPtr client)
|
||||||
|
{
|
||||||
|
REQUEST(xPresentPixmapSyncedReq);
|
||||||
|
struct dri3_syncobj *acquire_syncobj;
|
||||||
|
struct dri3_syncobj *release_syncobj;
|
||||||
|
|
||||||
|
REQUEST_AT_LEAST_SIZE(xPresentPixmapSyncedReq);
|
||||||
|
VERIFY_DRI3_SYNCOBJ(stuff->acquire_syncobj, acquire_syncobj, DixWriteAccess);
|
||||||
|
VERIFY_DRI3_SYNCOBJ(stuff->release_syncobj, release_syncobj, DixWriteAccess);
|
||||||
|
|
||||||
|
if (stuff->acquire_point == 0 || stuff->release_point == 0 ||
|
||||||
|
(stuff->acquire_syncobj == stuff->release_syncobj &&
|
||||||
|
stuff->acquire_point >= stuff->release_point))
|
||||||
|
return BadValue;
|
||||||
|
|
||||||
|
return proc_present_pixmap_common(client, stuff->window, stuff->pixmap, stuff->serial,
|
||||||
|
stuff->valid, stuff->update, stuff->x_off, stuff->y_off,
|
||||||
|
stuff->target_crtc,
|
||||||
|
None, None,
|
||||||
|
acquire_syncobj, release_syncobj,
|
||||||
|
stuff->acquire_point, stuff->release_point,
|
||||||
|
stuff->options, stuff->target_msc,
|
||||||
|
stuff->divisor, stuff->remainder,
|
||||||
|
sizeof (xPresentPixmapSyncedReq),
|
||||||
|
(xPresentNotify *)(stuff + 1));
|
||||||
|
}
|
||||||
|
#endif /* DRI3 */
|
||||||
|
|
||||||
static int (*proc_present_vector[PresentNumberRequests]) (ClientPtr) = {
|
static int (*proc_present_vector[PresentNumberRequests]) (ClientPtr) = {
|
||||||
proc_present_query_version, /* 0 */
|
proc_present_query_version, /* 0 */
|
||||||
proc_present_pixmap, /* 1 */
|
proc_present_pixmap, /* 1 */
|
||||||
proc_present_notify_msc, /* 2 */
|
proc_present_notify_msc, /* 2 */
|
||||||
proc_present_select_input, /* 3 */
|
proc_present_select_input, /* 3 */
|
||||||
proc_present_query_capabilities, /* 4 */
|
proc_present_query_capabilities, /* 4 */
|
||||||
|
#ifdef DRI3
|
||||||
|
proc_present_pixmap_synced, /* 5 */
|
||||||
|
#endif /* DRI3 */
|
||||||
};
|
};
|
||||||
|
|
||||||
int
|
int
|
||||||
|
@ -325,12 +402,51 @@ sproc_present_query_capabilities (ClientPtr client)
|
||||||
return (*proc_present_vector[stuff->presentReqType]) (client);
|
return (*proc_present_vector[stuff->presentReqType]) (client);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef DRI3
|
||||||
|
static int _X_COLD
|
||||||
|
sproc_present_pixmap_synced(ClientPtr client)
|
||||||
|
{
|
||||||
|
REQUEST(xPresentPixmapSyncedReq);
|
||||||
|
REQUEST_AT_LEAST_SIZE(xPresentPixmapSyncedReq);
|
||||||
|
|
||||||
|
swaps(&stuff->length);
|
||||||
|
|
||||||
|
swapl(&stuff->window);
|
||||||
|
|
||||||
|
swapl(&stuff->pixmap);
|
||||||
|
swapl(&stuff->serial);
|
||||||
|
|
||||||
|
swapl(&stuff->valid);
|
||||||
|
swapl(&stuff->update);
|
||||||
|
|
||||||
|
swaps(&stuff->x_off);
|
||||||
|
swaps(&stuff->y_off);
|
||||||
|
swapl(&stuff->target_crtc);
|
||||||
|
|
||||||
|
swapl(&stuff->acquire_syncobj);
|
||||||
|
swapl(&stuff->release_syncobj);
|
||||||
|
swapll(&stuff->acquire_point);
|
||||||
|
swapll(&stuff->release_point);
|
||||||
|
|
||||||
|
swapl(&stuff->options);
|
||||||
|
|
||||||
|
swapll(&stuff->target_msc);
|
||||||
|
swapll(&stuff->divisor);
|
||||||
|
swapll(&stuff->remainder);
|
||||||
|
return (*proc_present_vector[stuff->presentReqType]) (client);
|
||||||
|
}
|
||||||
|
#endif /* DRI3 */
|
||||||
|
|
||||||
static int (*sproc_present_vector[PresentNumberRequests]) (ClientPtr) = {
|
static int (*sproc_present_vector[PresentNumberRequests]) (ClientPtr) = {
|
||||||
sproc_present_query_version, /* 0 */
|
sproc_present_query_version, /* 0 */
|
||||||
sproc_present_pixmap, /* 1 */
|
sproc_present_pixmap, /* 1 */
|
||||||
sproc_present_notify_msc, /* 2 */
|
sproc_present_notify_msc, /* 2 */
|
||||||
sproc_present_select_input, /* 3 */
|
sproc_present_select_input, /* 3 */
|
||||||
sproc_present_query_capabilities, /* 4 */
|
sproc_present_query_capabilities, /* 4 */
|
||||||
|
#ifdef DRI3
|
||||||
|
sproc_present_pixmap_synced, /* 5 */
|
||||||
|
#endif /* DRI3 */
|
||||||
};
|
};
|
||||||
|
|
||||||
int _X_COLD
|
int _X_COLD
|
||||||
|
|
|
@ -738,6 +738,12 @@ present_scmd_pixmap(WindowPtr window,
|
||||||
RRCrtcPtr target_crtc,
|
RRCrtcPtr target_crtc,
|
||||||
SyncFence *wait_fence,
|
SyncFence *wait_fence,
|
||||||
SyncFence *idle_fence,
|
SyncFence *idle_fence,
|
||||||
|
#ifdef DRI3
|
||||||
|
struct dri3_syncobj *acquire_syncobj,
|
||||||
|
struct dri3_syncobj *release_syncobj,
|
||||||
|
uint64_t acquire_point,
|
||||||
|
uint64_t release_point,
|
||||||
|
#endif /* DRI3 */
|
||||||
uint32_t options,
|
uint32_t options,
|
||||||
uint64_t target_window_msc,
|
uint64_t target_window_msc,
|
||||||
uint64_t divisor,
|
uint64_t divisor,
|
||||||
|
@ -754,6 +760,11 @@ present_scmd_pixmap(WindowPtr window,
|
||||||
present_window_priv_ptr window_priv = present_get_window_priv(window, TRUE);
|
present_window_priv_ptr window_priv = present_get_window_priv(window, TRUE);
|
||||||
present_screen_priv_ptr screen_priv = present_screen_priv(screen);
|
present_screen_priv_ptr screen_priv = present_screen_priv(screen);
|
||||||
|
|
||||||
|
#ifdef DRI3
|
||||||
|
if (acquire_syncobj || release_syncobj)
|
||||||
|
return BadValue;
|
||||||
|
#endif /* DRI3 */
|
||||||
|
|
||||||
if (!window_priv)
|
if (!window_priv)
|
||||||
return BadAlloc;
|
return BadAlloc;
|
||||||
|
|
||||||
|
@ -824,6 +835,12 @@ present_scmd_pixmap(WindowPtr window,
|
||||||
target_crtc,
|
target_crtc,
|
||||||
wait_fence,
|
wait_fence,
|
||||||
idle_fence,
|
idle_fence,
|
||||||
|
#ifdef DRI3
|
||||||
|
acquire_syncobj,
|
||||||
|
release_syncobj,
|
||||||
|
acquire_point,
|
||||||
|
release_point,
|
||||||
|
#endif /* DRI3 */
|
||||||
options,
|
options,
|
||||||
screen_priv->info ? screen_priv->info->capabilities : 0,
|
screen_priv->info ? screen_priv->info->capabilities : 0,
|
||||||
notifies,
|
notifies,
|
||||||
|
|
|
@ -187,6 +187,7 @@ present_screen_priv_init(ScreenPtr screen)
|
||||||
wrap(screen_priv, screen, ClipNotify, present_clip_notify);
|
wrap(screen_priv, screen, ClipNotify, present_clip_notify);
|
||||||
|
|
||||||
dixSetPrivate(&screen->devPrivates, &present_screen_private_key, screen_priv);
|
dixSetPrivate(&screen->devPrivates, &present_screen_private_key, screen_priv);
|
||||||
|
screen_priv->pScreen = screen;
|
||||||
|
|
||||||
return screen_priv;
|
return screen_priv;
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,6 +21,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "present_priv.h"
|
#include "present_priv.h"
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
void
|
void
|
||||||
present_vblank_notify(present_vblank_ptr vblank, CARD8 kind, CARD8 mode, uint64_t ust, uint64_t crtc_msc)
|
present_vblank_notify(present_vblank_ptr vblank, CARD8 kind, CARD8 mode, uint64_t ust, uint64_t crtc_msc)
|
||||||
|
@ -55,6 +56,12 @@ present_vblank_init(present_vblank_ptr vblank,
|
||||||
RRCrtcPtr target_crtc,
|
RRCrtcPtr target_crtc,
|
||||||
SyncFence *wait_fence,
|
SyncFence *wait_fence,
|
||||||
SyncFence *idle_fence,
|
SyncFence *idle_fence,
|
||||||
|
#ifdef DRI3
|
||||||
|
struct dri3_syncobj *acquire_syncobj,
|
||||||
|
struct dri3_syncobj *release_syncobj,
|
||||||
|
uint64_t acquire_point,
|
||||||
|
uint64_t release_point,
|
||||||
|
#endif /* DRI3 */
|
||||||
uint32_t options,
|
uint32_t options,
|
||||||
const uint32_t capabilities,
|
const uint32_t capabilities,
|
||||||
present_notify_ptr notifies,
|
present_notify_ptr notifies,
|
||||||
|
@ -135,6 +142,22 @@ present_vblank_init(present_vblank_ptr vblank,
|
||||||
goto no_mem;
|
goto no_mem;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef DRI3
|
||||||
|
vblank->efd = -1;
|
||||||
|
|
||||||
|
if (acquire_syncobj) {
|
||||||
|
vblank->acquire_syncobj = acquire_syncobj;
|
||||||
|
++acquire_syncobj->refcount;
|
||||||
|
vblank->acquire_point = acquire_point;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (release_syncobj) {
|
||||||
|
vblank->release_syncobj = release_syncobj;
|
||||||
|
++release_syncobj->refcount;
|
||||||
|
vblank->release_point = release_point;
|
||||||
|
}
|
||||||
|
#endif /* DRI3 */
|
||||||
|
|
||||||
if (pixmap)
|
if (pixmap)
|
||||||
DebugPresent(("q %" PRIu64 " %p %" PRIu64 ": %08" PRIx32 " -> %08" PRIx32 " (crtc %p) flip %d vsync %d serial %d\n",
|
DebugPresent(("q %" PRIu64 " %p %" PRIu64 ": %08" PRIx32 " -> %08" PRIx32 " (crtc %p) flip %d vsync %d serial %d\n",
|
||||||
vblank->event_id, vblank, target_msc,
|
vblank->event_id, vblank, target_msc,
|
||||||
|
@ -158,6 +181,12 @@ present_vblank_create(WindowPtr window,
|
||||||
RRCrtcPtr target_crtc,
|
RRCrtcPtr target_crtc,
|
||||||
SyncFence *wait_fence,
|
SyncFence *wait_fence,
|
||||||
SyncFence *idle_fence,
|
SyncFence *idle_fence,
|
||||||
|
#ifdef DRI3
|
||||||
|
struct dri3_syncobj *acquire_syncobj,
|
||||||
|
struct dri3_syncobj *release_syncobj,
|
||||||
|
uint64_t acquire_point,
|
||||||
|
uint64_t release_point,
|
||||||
|
#endif /* DRI3 */
|
||||||
uint32_t options,
|
uint32_t options,
|
||||||
const uint32_t capabilities,
|
const uint32_t capabilities,
|
||||||
present_notify_ptr notifies,
|
present_notify_ptr notifies,
|
||||||
|
@ -172,6 +201,10 @@ present_vblank_create(WindowPtr window,
|
||||||
|
|
||||||
if (present_vblank_init(vblank, window, pixmap, serial, valid, update,
|
if (present_vblank_init(vblank, window, pixmap, serial, valid, update,
|
||||||
x_off, y_off, target_crtc, wait_fence, idle_fence,
|
x_off, y_off, target_crtc, wait_fence, idle_fence,
|
||||||
|
#ifdef DRI3
|
||||||
|
acquire_syncobj, release_syncobj,
|
||||||
|
acquire_point, release_point,
|
||||||
|
#endif /* DRI3 */
|
||||||
options, capabilities, notifies, num_notifies,
|
options, capabilities, notifies, num_notifies,
|
||||||
target_msc, crtc_msc))
|
target_msc, crtc_msc))
|
||||||
return vblank;
|
return vblank;
|
||||||
|
@ -229,5 +262,20 @@ present_vblank_destroy(present_vblank_ptr vblank)
|
||||||
if (vblank->notifies)
|
if (vblank->notifies)
|
||||||
present_destroy_notifies(vblank->notifies, vblank->num_notifies);
|
present_destroy_notifies(vblank->notifies, vblank->num_notifies);
|
||||||
|
|
||||||
|
#ifdef DRI3
|
||||||
|
if (vblank->efd >= 0) {
|
||||||
|
SetNotifyFd(vblank->efd, NULL, 0, NULL);
|
||||||
|
close(vblank->efd);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (vblank->acquire_syncobj &&
|
||||||
|
--vblank->acquire_syncobj->refcount == 0)
|
||||||
|
vblank->acquire_syncobj->free(vblank->acquire_syncobj);
|
||||||
|
|
||||||
|
if (vblank->release_syncobj &&
|
||||||
|
--vblank->release_syncobj->refcount == 0)
|
||||||
|
vblank->release_syncobj->free(vblank->release_syncobj);
|
||||||
|
#endif /* DRI3 */
|
||||||
|
|
||||||
free(vblank);
|
free(vblank);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue