summaryrefslogtreecommitdiffstats
path: root/services
diff options
context:
space:
mode:
authorMathias Agopian <mathias@google.com>2012-04-10 21:04:02 -0700
committerMathias Agopian <mathias@google.com>2012-04-11 15:31:40 -0700
commit22ffb117b0c2a906bd04aef9738a52223cdd1dce (patch)
tree5d5b8915428be715ec6db9ace523f78668f4f50e /services
parentb60314a12f3336b27d73920805ab07cbc498d857 (diff)
downloadframeworks_native-22ffb117b0c2a906bd04aef9738a52223cdd1dce.zip
frameworks_native-22ffb117b0c2a906bd04aef9738a52223cdd1dce.tar.gz
frameworks_native-22ffb117b0c2a906bd04aef9738a52223cdd1dce.tar.bz2
make sure to disable VSYNC while screen is off
Change-Id: If1894c43b0a39a2851e1280a35ae77bccd6d9abd
Diffstat (limited to 'services')
-rw-r--r--services/surfaceflinger/DisplayHardware/HWComposer.cpp3
-rw-r--r--services/surfaceflinger/EventThread.cpp56
-rw-r--r--services/surfaceflinger/EventThread.h12
-rw-r--r--services/surfaceflinger/SurfaceFlinger.cpp8
4 files changed, 57 insertions, 22 deletions
diff --git a/services/surfaceflinger/DisplayHardware/HWComposer.cpp b/services/surfaceflinger/DisplayHardware/HWComposer.cpp
index 6ae03c9..b87e191 100644
--- a/services/surfaceflinger/DisplayHardware/HWComposer.cpp
+++ b/services/surfaceflinger/DisplayHardware/HWComposer.cpp
@@ -205,6 +205,9 @@ status_t HWComposer::commit() const {
status_t HWComposer::release() const {
if (mHwc) {
+ if (mHwc->common.version >= HWC_DEVICE_API_VERSION_0_3) {
+ mHwc->methods->eventControl(mHwc, HWC_EVENT_VSYNC, 0);
+ }
int err = mHwc->set(mHwc, NULL, NULL, NULL);
return (status_t)err;
}
diff --git a/services/surfaceflinger/EventThread.cpp b/services/surfaceflinger/EventThread.cpp
index 5813eef..d86c280 100644
--- a/services/surfaceflinger/EventThread.cpp
+++ b/services/surfaceflinger/EventThread.cpp
@@ -41,6 +41,7 @@ EventThread::EventThread(const sp<SurfaceFlinger>& flinger)
mHw(flinger->graphicPlane(0).editDisplayHardware()),
mLastVSyncTimestamp(0),
mVSyncTimestamp(0),
+ mUseSoftwareVSync(false),
mDeliveredEvents(0),
mDebugVsyncEnabled(false)
{
@@ -55,16 +56,6 @@ sp<EventThread::Connection> EventThread::createEventConnection() const {
return new Connection(const_cast<EventThread*>(this));
}
-nsecs_t EventThread::getLastVSyncTimestamp() const {
- Mutex::Autolock _l(mLock);
- return mLastVSyncTimestamp;
-}
-
-nsecs_t EventThread::getVSyncPeriod() const {
- return mHw.getRefreshPeriod();
-
-}
-
status_t EventThread::registerDisplayEventConnection(
const sp<EventThread::Connection>& connection) {
Mutex::Autolock _l(mLock);
@@ -108,6 +99,24 @@ void EventThread::requestNextVsync(
}
}
+void EventThread::onScreenReleased() {
+ Mutex::Autolock _l(mLock);
+ // wait for an eventual pending vsync to be serviced
+ if (!mUseSoftwareVSync) {
+ while (mVSyncTimestamp) {
+ mCondition.wait(mLock);
+ }
+ }
+ // disable reliance on h/w vsync
+ mUseSoftwareVSync = true;
+}
+
+void EventThread::onScreenAcquired() {
+ Mutex::Autolock _l(mLock);
+ mUseSoftwareVSync = false;
+}
+
+
void EventThread::onVSyncReceived(int, nsecs_t timestamp) {
Mutex::Autolock _l(mLock);
mVSyncTimestamp = timestamp;
@@ -121,7 +130,6 @@ bool EventThread::threadLoop() {
Vector< wp<EventThread::Connection> > displayEventConnections;
do {
-
Mutex::Autolock _l(mLock);
do {
// latch VSYNC event if any
@@ -145,7 +153,7 @@ bool EventThread::threadLoop() {
if (!waitForNextVsync) {
// we received a VSYNC but we have no clients
// don't report it, and disable VSYNC events
- disableVSync();
+ disableVSyncLocked();
} else {
// report VSYNC event
break;
@@ -157,12 +165,21 @@ bool EventThread::threadLoop() {
// disable VSYNC events then.
if (waitForNextVsync) {
// enable
- enableVSync();
+ enableVSyncLocked();
}
}
// wait for something to happen
- mCondition.wait(mLock);
+ if (mUseSoftwareVSync == true) {
+ // h/w vsync cannot be used (screen is off), so we use
+ // a timeout instead. it doesn't matter how imprecise this
+ // is, we just need to make sure to serve the clients
+ if (mCondition.waitRelative(mLock, ms2ns(16)) == TIMED_OUT) {
+ mVSyncTimestamp = systemTime(SYSTEM_TIME_MONOTONIC);
+ }
+ } else {
+ mCondition.wait(mLock);
+ }
} while(true);
// process vsync event
@@ -233,12 +250,15 @@ bool EventThread::threadLoop() {
return true;
}
-void EventThread::enableVSync() {
- mHw.getHwComposer().eventControl(HWComposer::EVENT_VSYNC, true);
+void EventThread::enableVSyncLocked() {
+ if (!mUseSoftwareVSync) {
+ // never enable h/w VSYNC when screen is off
+ mHw.getHwComposer().eventControl(HWComposer::EVENT_VSYNC, true);
+ }
mDebugVsyncEnabled = true;
}
-void EventThread::disableVSync() {
+void EventThread::disableVSyncLocked() {
mHw.getHwComposer().eventControl(HWComposer::EVENT_VSYNC, false);
mDebugVsyncEnabled = false;
}
@@ -252,6 +272,8 @@ void EventThread::dump(String8& result, char* buffer, size_t SIZE) const {
Mutex::Autolock _l(mLock);
result.appendFormat("VSYNC state: %s\n",
mDebugVsyncEnabled?"enabled":"disabled");
+ result.appendFormat(" soft-vsync: %s\n",
+ mUseSoftwareVSync?"enabled":"disabled");
result.appendFormat(" numListeners=%u,\n events-delivered: %u\n",
mDisplayEventConnections.size(), mDeliveredEvents);
for (size_t i=0 ; i<mDisplayEventConnections.size() ; i++) {
diff --git a/services/surfaceflinger/EventThread.h b/services/surfaceflinger/EventThread.h
index 2e237dd..b42cab6 100644
--- a/services/surfaceflinger/EventThread.h
+++ b/services/surfaceflinger/EventThread.h
@@ -72,8 +72,11 @@ public:
void setVsyncRate(uint32_t count, const sp<Connection>& connection);
void requestNextVsync(const sp<Connection>& connection);
- nsecs_t getLastVSyncTimestamp() const;
- nsecs_t getVSyncPeriod() const;
+ // called before the screen is turned off from main thread
+ void onScreenReleased();
+
+ // called after the screen is turned on from main thread
+ void onScreenAcquired();
void dump(String8& result, char* buffer, size_t SIZE) const;
@@ -84,8 +87,8 @@ private:
virtual void onVSyncReceived(int, nsecs_t timestamp);
void removeDisplayEventConnection(const wp<Connection>& connection);
- void enableVSync();
- void disableVSync();
+ void enableVSyncLocked();
+ void disableVSyncLocked();
// constants
sp<SurfaceFlinger> mFlinger;
@@ -98,6 +101,7 @@ private:
SortedVector< wp<Connection> > mDisplayEventConnections;
nsecs_t mLastVSyncTimestamp;
nsecs_t mVSyncTimestamp;
+ bool mUseSoftwareVSync;
// main thread only
size_t mDeliveredEvents;
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index f891b29..ce6c4a0 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -1467,16 +1467,18 @@ uint32_t SurfaceFlinger::setClientStateLocked(
void SurfaceFlinger::onScreenAcquired() {
const DisplayHardware& hw(graphicPlane(0).displayHardware());
hw.acquireScreen();
+ mEventThread->onScreenAcquired();
// this is a temporary work-around, eventually this should be called
// by the power-manager
SurfaceFlinger::turnElectronBeamOn(mElectronBeamAnimationMode);
mDirtyRegion.set(hw.bounds());
- // from this point on, SF will priocess updates again
+ // from this point on, SF will process updates again
}
void SurfaceFlinger::onScreenReleased() {
const DisplayHardware& hw(graphicPlane(0).displayHardware());
if (hw.isScreenAcquired()) {
+ mEventThread->onScreenReleased();
mDirtyRegion.set(hw.bounds());
hw.releaseScreen();
// from this point on, SF will stop drawing
@@ -1883,6 +1885,8 @@ status_t SurfaceFlinger::renderScreenToTexture(DisplayID dpy,
status_t SurfaceFlinger::renderScreenToTextureLocked(DisplayID dpy,
GLuint* textureName, GLfloat* uOut, GLfloat* vOut)
{
+ ATRACE_CALL();
+
if (!GLExtensions::getInstance().haveFramebufferObject())
return INVALID_OPERATION;
@@ -2263,6 +2267,8 @@ status_t SurfaceFlinger::electronBeamOnAnimationImplLocked()
status_t SurfaceFlinger::turnElectronBeamOffImplLocked(int32_t mode)
{
+ ATRACE_CALL();
+
DisplayHardware& hw(graphicPlane(0).editDisplayHardware());
if (!hw.canDraw()) {
// we're already off