summaryrefslogtreecommitdiffstats
path: root/services/surfaceflinger/DisplayHardware/DisplayHardware.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'services/surfaceflinger/DisplayHardware/DisplayHardware.cpp')
-rw-r--r--services/surfaceflinger/DisplayHardware/DisplayHardware.cpp51
1 files changed, 47 insertions, 4 deletions
diff --git a/services/surfaceflinger/DisplayHardware/DisplayHardware.cpp b/services/surfaceflinger/DisplayHardware/DisplayHardware.cpp
index 61096e5..986aec5 100644
--- a/services/surfaceflinger/DisplayHardware/DisplayHardware.cpp
+++ b/services/surfaceflinger/DisplayHardware/DisplayHardware.cpp
@@ -140,6 +140,7 @@ void DisplayHardware::init(uint32_t dpy)
mDpiX = mNativeWindow->xdpi;
mDpiY = mNativeWindow->ydpi;
mRefreshRate = fbDev->fps;
+ mNextFakeVSync = 0;
/* FIXME: this is a temporary HACK until we are able to report the refresh rate
@@ -152,6 +153,8 @@ void DisplayHardware::init(uint32_t dpy)
#warning "refresh rate set via makefile to REFRESH_RATE"
#endif
+ mRefreshPeriod = nsecs_t(1e9 / mRefreshRate);
+
EGLint w, h, dummy;
EGLint numConfigs=0;
EGLSurface surface;
@@ -346,12 +349,52 @@ uint32_t DisplayHardware::getPageFlipCount() const {
return mPageFlipCount;
}
-status_t DisplayHardware::compositionComplete() const {
- return mNativeWindow->compositionComplete();
+// this needs to be thread safe
+nsecs_t DisplayHardware::waitForRefresh() const {
+ nsecs_t timestamp;
+ if (mVSync.wait(&timestamp) < 0) {
+ // vsync not supported!
+ usleep( getDelayToNextVSyncUs(&timestamp) );
+ }
+ mLastHwVSync = timestamp; // FIXME: Not thread safe
+ return timestamp;
+}
+
+nsecs_t DisplayHardware::getRefreshTimestamp() const {
+ // this returns the last refresh timestamp.
+ // if the last one is not available, we estimate it based on
+ // the refresh period and whatever closest timestamp we have.
+ nsecs_t now = systemTime();
+ return now - ((now - mLastHwVSync) % mRefreshPeriod);
+}
+
+nsecs_t DisplayHardware::getRefreshPeriod() const {
+ return mRefreshPeriod;
}
-int DisplayHardware::getCurrentBufferIndex() const {
- return mNativeWindow->getCurrentBufferIndex();
+int32_t DisplayHardware::getDelayToNextVSyncUs(nsecs_t* timestamp) const {
+ Mutex::Autolock _l(mFakeVSyncMutex);
+ const nsecs_t period = mRefreshPeriod;
+ const nsecs_t now = systemTime(CLOCK_MONOTONIC);
+ nsecs_t next_vsync = mNextFakeVSync;
+ nsecs_t sleep = next_vsync - now;
+ if (sleep < 0) {
+ // we missed, find where the next vsync should be
+ sleep = (period - ((now - next_vsync) % period));
+ next_vsync = now + sleep;
+ }
+ mNextFakeVSync = next_vsync + period;
+ timestamp[0] = next_vsync;
+
+ // round to next microsecond
+ int32_t sleep_us = (sleep + 999LL) / 1000LL;
+
+ // guaranteed to be > 0
+ return sleep_us;
+}
+
+status_t DisplayHardware::compositionComplete() const {
+ return mNativeWindow->compositionComplete();
}
void DisplayHardware::flip(const Region& dirty) const