aboutsummaryrefslogtreecommitdiffstats
path: root/src/glx
diff options
context:
space:
mode:
authorKeith Packard <[email protected]>2013-11-25 21:14:55 -0800
committerEric Anholt <[email protected]>2014-01-30 16:35:00 -0800
commit71d614250ed1f83d8da3adb8e855ee00201c70da (patch)
treeadae5edc4621fae18680b5511f37038598734db1 /src/glx
parent34a8a0820fa08037acd0e4fbc368d72c1a6209f1 (diff)
dri3: Track full 64-bit SBC numbers, instead of just 32-bits
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 <[email protected]> Reviewed-by: Eric Anholt <[email protected]>
Diffstat (limited to 'src/glx')
-rw-r--r--src/glx/dri3_glx.c34
-rw-r--r--src/glx/dri3_priv.h16
2 files changed, 30 insertions, 20 deletions
diff --git a/src/glx/dri3_glx.c b/src/glx/dri3_glx.c
index 2a9f0b7353c..7b78cd13ae2 100644
--- a/src/glx/dri3_glx.c
+++ b/src/glx/dri3_glx.c
@@ -365,10 +365,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;
@@ -399,12 +406,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);
@@ -413,7 +421,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;
@@ -424,7 +432,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;
}
@@ -451,7 +459,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 682849386ab..9d142cf5137 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;