summaryrefslogtreecommitdiffstats
path: root/services/surfaceflinger/DisplayHardware
diff options
context:
space:
mode:
authorMathias Agopian <mathias@google.com>2012-04-08 15:13:32 -0700
committerMathias Agopian <mathias@google.com>2012-04-08 20:54:47 -0700
commit2965b26022f95051f65b09d7eac47cbe923855c9 (patch)
tree7d17c24cdafba9852b23c95cfb7f030e9b200bfc /services/surfaceflinger/DisplayHardware
parentd94d3b890ac3d5731bd0397874d32aa4bc74bd61 (diff)
downloadframeworks_native-2965b26022f95051f65b09d7eac47cbe923855c9.zip
frameworks_native-2965b26022f95051f65b09d7eac47cbe923855c9.tar.gz
frameworks_native-2965b26022f95051f65b09d7eac47cbe923855c9.tar.bz2
VSYNC handling cleanup
Change-Id: I1376bf864c4e03c11fb6d1333a8b7cfdda08c9e4
Diffstat (limited to 'services/surfaceflinger/DisplayHardware')
-rw-r--r--services/surfaceflinger/DisplayHardware/HWComposer.cpp60
-rw-r--r--services/surfaceflinger/DisplayHardware/HWComposer.h54
2 files changed, 64 insertions, 50 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;
};