Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit ef472ec4 authored by Ruchi Kandoi's avatar Ruchi Kandoi
Browse files

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: Ia5a839ab3c857cffae7089f810b4315d4ed23fcf
parent a317f27b
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
@@ -93,7 +93,8 @@ LOCAL_SHARED_LIBRARIES := \
	libGLESv2 \
	libbinder \
	libui \
	libgui
	libgui \
	libpowermanager

LOCAL_MODULE:= libsurfaceflinger

+16 −24
Original line number Diff line number Diff line
@@ -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;
}

// ---------------------------------------------------------------------------
+4 −6
Original line number Diff line number Diff line
@@ -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;
};

// ---------------------------------------------------------------------------
+36 −3
Original line number Diff line number Diff line
@@ -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;
    }
}
+5 −0
Original line number Diff line number Diff line
@@ -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;
};

// ---------------------------------------------------------------------------