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
This commit is contained in:
parent
9ae71b0060
commit
d469a1c328
|
@ -96,7 +96,8 @@ LOCAL_SHARED_LIBRARIES := \
|
|||
libGLESv2 \
|
||||
libbinder \
|
||||
libui \
|
||||
libgui
|
||||
libgui \
|
||||
libpowermanager
|
||||
|
||||
LOCAL_MODULE:= libsurfaceflinger
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
return NO_ERROR;
|
||||
status_t status = mPowerManager->powerHint(POWER_HINT_VSYNC, enabled ? 1 : 0);
|
||||
if(status == DEAD_OBJECT) {
|
||||
mPowerManager = NULL;
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
|
Loading…
Reference in New Issue