[PATCH 2/4] dri3: Track full 64-bit SBC numbers, instead of just 32-bits
Keith Packard
keithp at keithp.com
Mon Nov 25 21:35:53 PST 2013
Tracking the full 64-bit SBC values makes it clearer how those values are
being used, and simplifies the wait_msc code. The only trick is in
re-constructing the full 64-bit value from Present's 32-bit serial number that
we use to pass the SBC value from request to event.
Signed-off-by: Keith Packard <keithp at keithp.com>
---
src/glx/dri3_glx.c | 34 +++++++++++++++++++++-------------
src/glx/dri3_priv.h | 16 +++++++++-------
2 files changed, 30 insertions(+), 20 deletions(-)
diff --git a/src/glx/dri3_glx.c b/src/glx/dri3_glx.c
index 669f0bb..c0915f2 100644
--- a/src/glx/dri3_glx.c
+++ b/src/glx/dri3_glx.c
@@ -364,10 +364,17 @@ dri3_handle_present_event(struct dri3_drawable *priv, xcb_present_generic_event_
case XCB_PRESENT_COMPLETE_NOTIFY: {
xcb_present_complete_notify_event_t *ce = (void *) ge;
- if (ce->kind == XCB_PRESENT_COMPLETE_KIND_PIXMAP)
- priv->present_event_serial = ce->serial;
- else
- priv->present_msc_event_serial = ce->serial;
+ /* Compute the processed SBC number from the received 32-bit serial number merged
+ * with the upper 32-bits of the sent 64-bit serial number while checking for
+ * wrap
+ */
+ if (ce->kind == XCB_PRESENT_COMPLETE_KIND_PIXMAP) {
+ priv->recv_sbc = (priv->send_sbc & 0xffffffff00000000LL) | ce->serial;
+ if (priv->recv_sbc > priv->send_sbc)
+ priv->recv_sbc -= 0x100000000;
+ } else {
+ priv->recv_msc_serial = ce->serial;
+ }
priv->ust = ce->ust;
priv->msc = ce->msc;
break;
@@ -398,12 +405,13 @@ dri3_wait_for_msc(__GLXDRIdrawable *pdraw, int64_t target_msc, int64_t divisor,
struct dri3_drawable *priv = (struct dri3_drawable *) pdraw;
xcb_generic_event_t *ev;
xcb_present_generic_event_t *ge;
+ uint32_t msc_serial;
/* Ask for the an event for the target MSC */
- ++priv->present_msc_request_serial;
+ msc_serial = ++priv->send_msc_serial;
xcb_present_notify_msc(c,
priv->base.xDrawable,
- priv->present_msc_request_serial,
+ msc_serial,
target_msc,
divisor,
remainder);
@@ -412,7 +420,7 @@ dri3_wait_for_msc(__GLXDRIdrawable *pdraw, int64_t target_msc, int64_t divisor,
/* Wait for the event */
if (priv->special_event) {
- while (priv->present_msc_request_serial != priv->present_msc_event_serial) {
+ while ((int32_t) (msc_serial - priv->recv_msc_serial) > 0) {
ev = xcb_wait_for_special_event(c, priv->special_event);
if (!ev)
break;
@@ -423,7 +431,7 @@ dri3_wait_for_msc(__GLXDRIdrawable *pdraw, int64_t target_msc, int64_t divisor,
*ust = priv->ust;
*msc = priv->msc;
- *sbc = priv->sbc;
+ *sbc = priv->recv_sbc;
return 1;
}
@@ -450,7 +458,7 @@ dri3_wait_for_sbc(__GLXDRIdrawable *pdraw, int64_t target_sbc, int64_t *ust,
{
struct dri3_drawable *priv = (struct dri3_drawable *) pdraw;
- while (priv->sbc < target_sbc) {
+ while (priv->send_sbc < target_sbc) {
sleep(1);
}
return dri3_wait_for_msc(pdraw, 0, 0, 0, ust, msc, sbc);
@@ -1282,15 +1290,15 @@ dri3_swap_buffers(__GLXDRIdrawable *pdraw, int64_t target_msc, int64_t divisor,
/* Compute when we want the frame shown by taking the last known successful
* MSC and adding in a swap interval for each outstanding swap request
*/
- ++priv->present_request_serial;
+ ++priv->send_sbc;
if (target_msc == 0)
- target_msc = priv->msc + priv->swap_interval * (priv->present_request_serial - priv->present_event_serial);
+ target_msc = priv->msc + priv->swap_interval * (priv->send_sbc - priv->recv_sbc);
priv->buffers[buf_id]->busy = 1;
xcb_present_pixmap(c,
priv->base.xDrawable,
priv->buffers[buf_id]->pixmap,
- priv->present_request_serial,
+ (uint32_t) priv->send_sbc,
0, /* valid */
0, /* update */
0, /* x_off */
@@ -1302,7 +1310,7 @@ dri3_swap_buffers(__GLXDRIdrawable *pdraw, int64_t target_msc, int64_t divisor,
target_msc,
divisor,
remainder, 0, NULL);
- ret = ++priv->sbc;
+ ret = (int64_t) priv->send_sbc;
/* If there's a fake front, then copy the source back buffer
* to the fake front to keep it up to date. This needs
diff --git a/src/glx/dri3_priv.h b/src/glx/dri3_priv.h
index 34c67a6..f1fec3c 100644
--- a/src/glx/dri3_priv.h
+++ b/src/glx/dri3_priv.h
@@ -183,16 +183,18 @@ struct dri3_drawable {
uint8_t have_fake_front;
uint8_t is_pixmap;
- uint32_t present_request_serial;
- uint32_t present_event_serial;
-
- uint64_t sbc;
+ /* SBC numbers are tracked by using the serial numbers
+ * in the present request and complete events
+ */
+ uint64_t send_sbc;
+ uint64_t recv_sbc;
+ /* Last received UST/MSC values */
uint64_t ust, msc;
- /* For WaitMSC */
- uint32_t present_msc_request_serial;
- uint32_t present_msc_event_serial;
+ /* Serial numbers for tracking wait_for_msc events */
+ uint32_t send_msc_serial;
+ uint32_t recv_msc_serial;
struct dri3_buffer *buffers[DRI3_NUM_BUFFERS];
int cur_back;
--
1.8.4.4
More information about the dri-devel
mailing list