diff options
author | Ruchi Kandoi <kandoiruchi@google.com> | 2014-04-02 12:50:06 -0700 |
---|---|---|
committer | Ruchi Kandoi <kandoiruchi@google.com> | 2014-04-04 20:22:31 +0000 |
commit | d469a1c3285b974cf2637517cc25727da8f82668 (patch) | |
tree | 5480df5943f7242e7c37fb3a4e8c46a83ad3a983 /services | |
parent | 9ae71b00601a346e91d9264fda2e00b1e4284dbb (diff) | |
download | frameworks_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.mk | 3 | ||||
-rw-r--r-- | services/surfaceflinger/DisplayHardware/PowerHAL.cpp | 40 | ||||
-rw-r--r-- | services/surfaceflinger/DisplayHardware/PowerHAL.h | 10 | ||||
-rw-r--r-- | services/surfaceflinger/EventThread.cpp | 39 | ||||
-rw-r--r-- | services/surfaceflinger/EventThread.h | 5 |
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; }; // --------------------------------------------------------------------------- |