summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--services/surfaceflinger/DisplayHardware/HWComposer.cpp60
-rw-r--r--services/surfaceflinger/DisplayHardware/HWComposer.h54
-rw-r--r--services/surfaceflinger/EventThread.cpp2
3 files changed, 64 insertions, 52 deletions
diff --git a/services/surfaceflinger/DisplayHardware/HWComposer.cpp b/services/surfaceflinger/DisplayHardware/HWComposer.cpp
index a6804da..d42153c 100644
--- a/services/surfaceflinger/DisplayHardware/HWComposer.cpp
+++ b/services/surfaceflinger/DisplayHardware/HWComposer.cpp
@@ -14,6 +14,8 @@
* limitations under the License.
*/
+#define ATRACE_TAG ATRACE_TAG_GRAPHICS
+
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
@@ -23,6 +25,7 @@
#include <utils/Errors.h>
#include <utils/String8.h>
#include <utils/Thread.h>
+#include <utils/Trace.h>
#include <utils/Vector.h>
#include <hardware/hardware.h>
@@ -48,7 +51,7 @@ HWComposer::HWComposer(
mNumOVLayers(0), mNumFBLayers(0),
mDpy(EGL_NO_DISPLAY), mSur(EGL_NO_SURFACE),
mEventHandler(handler),
- mRefreshPeriod(refreshPeriod)
+ mRefreshPeriod(refreshPeriod), mVSyncCount(0)
{
int err = hw_get_module(HWC_HARDWARE_MODULE_ID, &mModule);
ALOGW_IF(err, "%s module not found", HWC_HARDWARE_MODULE_ID);
@@ -100,6 +103,7 @@ void HWComposer::invalidate() {
}
void HWComposer::vsync(int dpy, int64_t timestamp) {
+ ATRACE_INT("VSYNC", ++mVSyncCount&1);
mEventHandler.onVSyncReceived(dpy, timestamp);
}
@@ -245,4 +249,58 @@ void HWComposer::dump(String8& result, char* buffer, size_t SIZE,
}
// ---------------------------------------------------------------------------
+
+HWComposer::VSyncThread::VSyncThread(HWComposer& hwc)
+ : mHwc(hwc), mEnabled(false),
+ mNextFakeVSync(0),
+ mRefreshPeriod(hwc.mRefreshPeriod)
+{
+}
+
+void HWComposer::VSyncThread::setEnabled(bool enabled) {
+ Mutex::Autolock _l(mLock);
+ mEnabled = enabled;
+ mCondition.signal();
+}
+
+void HWComposer::VSyncThread::onFirstRef() {
+ run("VSyncThread", PRIORITY_URGENT_DISPLAY + PRIORITY_MORE_FAVORABLE);
+}
+
+bool HWComposer::VSyncThread::threadLoop() {
+ { // scope for lock
+ Mutex::Autolock _l(mLock);
+ while (!mEnabled) {
+ mCondition.wait(mLock);
+ }
+ }
+
+ 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;
+
+ struct timespec spec;
+ spec.tv_sec = next_vsync / 1000000000;
+ spec.tv_nsec = next_vsync % 1000000000;
+
+ int err;
+ do {
+ err = clock_nanosleep(CLOCK_MONOTONIC, TIMER_ABSTIME, &spec, NULL);
+ } while (err<0 && errno == EINTR);
+
+ if (err == 0) {
+ mHwc.mEventHandler.onVSyncReceived(0, next_vsync);
+ }
+
+ return true;
+}
+
+// ---------------------------------------------------------------------------
}; // namespace android
diff --git a/services/surfaceflinger/DisplayHardware/HWComposer.h b/services/surfaceflinger/DisplayHardware/HWComposer.h
index 60a6367..7814594 100644
--- a/services/surfaceflinger/DisplayHardware/HWComposer.h
+++ b/services/surfaceflinger/DisplayHardware/HWComposer.h
@@ -97,56 +97,11 @@ public:
bool mEnabled;
mutable nsecs_t mNextFakeVSync;
nsecs_t mRefreshPeriod;
-
- virtual void onFirstRef() {
- run("VSyncThread",
- PRIORITY_URGENT_DISPLAY + PRIORITY_MORE_FAVORABLE);
- }
-
- virtual bool threadLoop() {
- { // scope for lock
- Mutex::Autolock _l(mLock);
- while (!mEnabled) {
- mCondition.wait(mLock);
- }
- }
-
- 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;
-
- struct timespec spec;
- spec.tv_sec = next_vsync / 1000000000;
- spec.tv_nsec = next_vsync % 1000000000;
-
- // NOTE: EINTR can happen with clock_nanosleep(), in case of
- // any error (including EINTR) we go through the condition's
- // test -- this is always correct and easy.
- if (::clock_nanosleep(CLOCK_MONOTONIC,
- TIMER_ABSTIME, &spec, NULL) == 0) {
- mHwc.mEventHandler.onVSyncReceived(0, next_vsync);
- }
- return true;
- }
-
+ virtual void onFirstRef();
+ virtual bool threadLoop();
public:
- VSyncThread(HWComposer& hwc) :
- mHwc(hwc), mEnabled(false),
- mNextFakeVSync(0),
- mRefreshPeriod(hwc.mRefreshPeriod) {
- }
- void setEnabled(bool enabled) {
- Mutex::Autolock _l(mLock);
- mEnabled = enabled;
- mCondition.signal();
- }
+ VSyncThread(HWComposer& hwc);
+ void setEnabled(bool enabled);
};
friend class VSyncThread;
@@ -187,6 +142,7 @@ private:
cb_context mCBContext;
EventHandler& mEventHandler;
nsecs_t mRefreshPeriod;
+ size_t mVSyncCount;
sp<VSyncThread> mVSyncThread;
};
diff --git a/services/surfaceflinger/EventThread.cpp b/services/surfaceflinger/EventThread.cpp
index 016d7ac..cc44186 100644
--- a/services/surfaceflinger/EventThread.cpp
+++ b/services/surfaceflinger/EventThread.cpp
@@ -167,8 +167,6 @@ bool EventThread::threadLoop() {
} while(true);
// process vsync event
-
- ATRACE_INT("VSYNC", mDeliveredEvents&1);
mDeliveredEvents++;
mLastVSyncTimestamp = timestamp;