VSYNC handling cleanup

Change-Id: I1376bf864c4e03c11fb6d1333a8b7cfdda08c9e4
This commit is contained in:
Mathias Agopian 2012-04-08 15:13:32 -07:00
parent d94d3b890a
commit 2965b26022
3 changed files with 64 additions and 52 deletions

View File

@ -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);
}
@ -244,5 +248,59 @@ 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

View File

@ -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;
};

View File

@ -167,8 +167,6 @@ bool EventThread::threadLoop() {
} while(true);
// process vsync event
ATRACE_INT("VSYNC", mDeliveredEvents&1);
mDeliveredEvents++;
mLastVSyncTimestamp = timestamp;