VSYNC handling cleanup
Change-Id: I1376bf864c4e03c11fb6d1333a8b7cfdda08c9e4
This commit is contained in:
parent
d94d3b890a
commit
2965b26022
@ -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
|
||||
|
@ -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;
|
||||
};
|
||||
|
||||
|
@ -167,8 +167,6 @@ bool EventThread::threadLoop() {
|
||||
} while(true);
|
||||
|
||||
// process vsync event
|
||||
|
||||
ATRACE_INT("VSYNC", mDeliveredEvents&1);
|
||||
mDeliveredEvents++;
|
||||
mLastVSyncTimestamp = timestamp;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user