summaryrefslogtreecommitdiffstats
path: root/services
diff options
context:
space:
mode:
authorRuchi Kandoi <kandoiruchi@google.com>2014-04-02 12:50:06 -0700
committerRuchi Kandoi <kandoiruchi@google.com>2014-04-04 20:22:31 +0000
commitd469a1c3285b974cf2637517cc25727da8f82668 (patch)
tree5480df5943f7242e7c37fb3a4e8c46a83ad3a983 /services
parent9ae71b00601a346e91d9264fda2e00b1e4284dbb (diff)
downloadframeworks_native-d469a1c3285b974cf2637517cc25727da8f82668.zip
frameworks_native-d469a1c3285b974cf2637517cc25727da8f82668.tar.gz
frameworks_native-d469a1c3285b974cf2637517cc25727da8f82668.tar.bz2
SurfaceFlinger: send VSYNC power hints to IPowerManager
VSYNC power hints are now sent via binder to IPowerManager. SurfaceFlinger no longer loads a second copy of the PowerHAL. VSYNC power hints are sent in batches and not on per frame basis. Change-Id: Icc2eee5df56135bd24dc244a84e7c12dd5511fec
Diffstat (limited to 'services')
-rw-r--r--services/surfaceflinger/Android.mk3
-rw-r--r--services/surfaceflinger/DisplayHardware/PowerHAL.cpp40
-rw-r--r--services/surfaceflinger/DisplayHardware/PowerHAL.h10
-rw-r--r--services/surfaceflinger/EventThread.cpp39
-rw-r--r--services/surfaceflinger/EventThread.h5
5 files changed, 63 insertions, 34 deletions
diff --git a/services/surfaceflinger/Android.mk b/services/surfaceflinger/Android.mk
index 0834c80..8141b99 100644
--- a/services/surfaceflinger/Android.mk
+++ b/services/surfaceflinger/Android.mk
@@ -96,7 +96,8 @@ LOCAL_SHARED_LIBRARIES := \
libGLESv2 \
libbinder \
libui \
- libgui
+ libgui \
+ libpowermanager
LOCAL_MODULE:= libsurfaceflinger
diff --git a/services/surfaceflinger/DisplayHardware/PowerHAL.cpp b/services/surfaceflinger/DisplayHardware/PowerHAL.cpp
index e41fbbc..bd50b4a 100644
--- a/services/surfaceflinger/DisplayHardware/PowerHAL.cpp
+++ b/services/surfaceflinger/DisplayHardware/PowerHAL.cpp
@@ -20,38 +20,30 @@
#include <cutils/log.h>
#include <utils/Errors.h>
+#include <binder/IServiceManager.h>
+#include <powermanager/IPowerManager.h>
+#include <powermanager/PowerManager.h>
+
#include "PowerHAL.h"
namespace android {
// ---------------------------------------------------------------------------
-PowerHAL::PowerHAL() : mPowerModule(0), mVSyncHintEnabled(false) {
- int err = hw_get_module(POWER_HARDWARE_MODULE_ID,
- (const hw_module_t **)&mPowerModule);
- ALOGW_IF(err, "%s module not found", POWER_HARDWARE_MODULE_ID);
-}
-
-PowerHAL::~PowerHAL() {
-}
-
-status_t PowerHAL::initCheck() const {
- return mPowerModule ? NO_ERROR : NO_INIT;
-}
-
status_t PowerHAL::vsyncHint(bool enabled) {
- if (!mPowerModule) {
- return NO_INIT;
- }
- if (mPowerModule->common.module_api_version >= POWER_MODULE_API_VERSION_0_2) {
- if (mPowerModule->powerHint) {
- if (mVSyncHintEnabled != bool(enabled)) {
- mPowerModule->powerHint(mPowerModule,
- POWER_HINT_VSYNC, (void*)enabled);
- mVSyncHintEnabled = bool(enabled);
- }
+ Mutex::Autolock _l(mlock);
+ if (mPowerManager == NULL) {
+ const String16 serviceName("power");
+ sp<IBinder> bs = defaultServiceManager()->checkService(serviceName);
+ if (bs == NULL) {
+ return NAME_NOT_FOUND;
}
+ mPowerManager = interface_cast<IPowerManager>(bs);
+ }
+ status_t status = mPowerManager->powerHint(POWER_HINT_VSYNC, enabled ? 1 : 0);
+ if(status == DEAD_OBJECT) {
+ mPowerManager = NULL;
}
- return NO_ERROR;
+ return status;
}
// ---------------------------------------------------------------------------
diff --git a/services/surfaceflinger/DisplayHardware/PowerHAL.h b/services/surfaceflinger/DisplayHardware/PowerHAL.h
index ef67b8f..e5f82a9 100644
--- a/services/surfaceflinger/DisplayHardware/PowerHAL.h
+++ b/services/surfaceflinger/DisplayHardware/PowerHAL.h
@@ -19,7 +19,9 @@
#include <stdint.h>
#include <sys/types.h>
+#include <utils/Mutex.h>
+#include <powermanager/IPowerManager.h>
#include <hardware/power.h>
namespace android {
@@ -28,15 +30,11 @@ namespace android {
class PowerHAL
{
public:
- PowerHAL();
- ~PowerHAL();
-
- status_t initCheck() const;
status_t vsyncHint(bool enabled);
private:
- power_module_t* mPowerModule;
- bool mVSyncHintEnabled;
+ sp<IPowerManager> mPowerManager;
+ Mutex mlock;
};
// ---------------------------------------------------------------------------
diff --git a/services/surfaceflinger/EventThread.cpp b/services/surfaceflinger/EventThread.cpp
index d868f32..9b6360e 100644
--- a/services/surfaceflinger/EventThread.cpp
+++ b/services/surfaceflinger/EventThread.cpp
@@ -35,12 +35,21 @@
// ---------------------------------------------------------------------------
namespace android {
// ---------------------------------------------------------------------------
+// time to wait between VSYNC requests before sending a VSYNC OFF power hint: 40msec.
+const long vsyncHintOffDelay = 40000000;
+
+static void vsyncOffCallback(union sigval val) {
+ EventThread *ev = (EventThread *)val.sival_ptr;
+ ev->sendVsyncHintOff();
+ return;
+}
EventThread::EventThread(const sp<VSyncSource>& src)
: mVSyncSource(src),
mUseSoftwareVSync(false),
mVsyncEnabled(false),
- mDebugVsyncEnabled(false) {
+ mDebugVsyncEnabled(false),
+ mVsyncHintSent(false) {
for (int32_t i=0 ; i<DisplayDevice::NUM_BUILTIN_DISPLAY_TYPES ; i++) {
mVSyncEvent[i].header.type = DisplayEventReceiver::DISPLAY_EVENT_VSYNC;
@@ -48,6 +57,31 @@ EventThread::EventThread(const sp<VSyncSource>& src)
mVSyncEvent[i].header.timestamp = 0;
mVSyncEvent[i].vsync.count = 0;
}
+ struct sigevent se;
+ se.sigev_notify = SIGEV_THREAD;
+ se.sigev_value.sival_ptr = this;
+ se.sigev_notify_function = vsyncOffCallback;
+ se.sigev_notify_attributes = NULL;
+ timer_create(CLOCK_MONOTONIC, &se, &mTimerId);
+}
+
+void EventThread::sendVsyncHintOff() {
+ Mutex::Autolock _l(mLock);
+ mPowerHAL.vsyncHint(false);
+ mVsyncHintSent = false;
+}
+
+void EventThread::sendVsyncHintOnLocked() {
+ struct itimerspec ts;
+ if(!mVsyncHintSent) {
+ mPowerHAL.vsyncHint(true);
+ mVsyncHintSent = true;
+ }
+ ts.it_value.tv_sec = 0;
+ ts.it_value.tv_nsec = vsyncHintOffDelay;
+ ts.it_interval.tv_sec = 0;
+ ts.it_interval.tv_nsec = 0;
+ timer_settime(mTimerId, 0, &ts, NULL);
}
void EventThread::onFirstRef() {
@@ -307,17 +341,16 @@ void EventThread::enableVSyncLocked() {
mVsyncEnabled = true;
mVSyncSource->setCallback(static_cast<VSyncSource::Callback*>(this));
mVSyncSource->setVSyncEnabled(true);
- mPowerHAL.vsyncHint(true);
}
}
mDebugVsyncEnabled = true;
+ sendVsyncHintOnLocked();
}
void EventThread::disableVSyncLocked() {
if (mVsyncEnabled) {
mVsyncEnabled = false;
mVSyncSource->setVSyncEnabled(false);
- mPowerHAL.vsyncHint(false);
mDebugVsyncEnabled = false;
}
}
diff --git a/services/surfaceflinger/EventThread.h b/services/surfaceflinger/EventThread.h
index f6ab4a7..d1c4fcd 100644
--- a/services/surfaceflinger/EventThread.h
+++ b/services/surfaceflinger/EventThread.h
@@ -97,6 +97,7 @@ public:
DisplayEventReceiver::Event* event);
void dump(String8& result) const;
+ void sendVsyncHintOff();
private:
virtual bool threadLoop();
@@ -107,6 +108,7 @@ private:
void removeDisplayEventConnection(const wp<Connection>& connection);
void enableVSyncLocked();
void disableVSyncLocked();
+ void sendVsyncHintOnLocked();
// constants
sp<VSyncSource> mVSyncSource;
@@ -124,6 +126,9 @@ private:
// for debugging
bool mDebugVsyncEnabled;
+
+ bool mVsyncHintSent;
+ timer_t mTimerId;
};
// ---------------------------------------------------------------------------