summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/common_drm.c71
1 files changed, 63 insertions, 8 deletions
diff --git a/src/common_drm.c b/src/common_drm.c
index 8cf277e..92700ce 100644
--- a/src/common_drm.c
+++ b/src/common_drm.c
@@ -18,6 +18,7 @@
#include "xf86.h"
#include "boxutil.h"
+#include "pixmaputil.h"
#include "common_drm.h"
#include "common_drm_helper.h"
@@ -69,6 +70,10 @@ static DevPrivateKeyRec pixmap_key;
struct common_pixmap {
uint32_t handle;
void *data;
+ xf86CrtcPtr crtc;
+ uint64_t last_ust;
+ uint64_t last_msc;
+ int64_t delta_msc;
};
static struct common_pixmap *common_drm_pixmap(PixmapPtr pixmap)
@@ -1443,14 +1448,45 @@ _X_EXPORT
int common_drm_get_drawable_msc(xf86CrtcPtr crtc, DrawablePtr pDraw,
uint64_t *ust, uint64_t *msc)
{
- /* Drawable not displayed, make up a value */
- if (!crtc) {
- *ust = 0;
- *msc = 0;
+ struct common_pixmap *drawc;
+ int ret = Success;
+
+ if (!pDraw && !crtc) {
+ *ust = *msc = 0;
return Success;
}
- return common_drm_get_msc(crtc, ust, msc);
+ if (!pDraw)
+ return common_drm_get_msc(crtc, ust, msc);
+
+ drawc = common_drm_pixmap(drawable_pixmap(pDraw));
+
+ if (drawc->crtc) {
+ uint64_t old_ust, old_msc;
+
+ ret = common_drm_get_msc(drawc->crtc, &old_ust, &old_msc);
+ if (ret == Success) {
+ drawc->last_ust = old_ust;
+ drawc->last_msc = old_msc + drawc->delta_msc;
+ }
+ }
+
+ if (drawc->crtc != crtc) {
+ uint64_t new_ust, new_msc;
+
+ drawc->crtc = crtc;
+
+ if (crtc) {
+ ret = common_drm_get_msc(crtc, &new_ust, &new_msc);
+ if (ret == Success)
+ drawc->delta_msc = drawc->last_msc - new_msc;
+ }
+ }
+
+ *ust = drawc->last_ust;
+ *msc = drawc->last_msc;
+
+ return ret;
}
_X_EXPORT
@@ -1483,11 +1519,30 @@ int common_drm_queue_msc_event(ScrnInfoPtr pScrn, xf86CrtcPtr crtc,
_X_EXPORT
int common_drm_queue_drawable_msc_event(ScrnInfoPtr pScrn, xf86CrtcPtr crtc,
- DrawablePtr pDraw, uint64_t *msc, const char *func, Bool nextonmiss,
+ DrawablePtr pDraw, uint64_t *pmsc, const char *func, Bool nextonmiss,
struct common_drm_event *event)
{
- return common_drm_queue_msc_event(pScrn, crtc, msc, func, nextonmiss,
- event);
+ struct common_pixmap *drawc;
+ uint64_t msc = *pmsc;
+ int64_t delta = 0;
+ int ret;
+
+ /*
+ * If we have a drawable, we need to correct the MSC for the
+ * drawable delta.
+ */
+ if (pDraw) {
+ drawc = common_drm_pixmap(drawable_pixmap(pDraw));
+ delta = drawc->delta_msc;
+ msc -= delta;
+ }
+
+ ret = common_drm_queue_msc_event(pScrn, crtc, &msc, func, nextonmiss,
+ event);
+
+ *pmsc = msc + delta;
+
+ return ret;
}
_X_EXPORT