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 Original line Diff line number Diff line
@@ -93,7 +93,8 @@ LOCAL_SHARED_LIBRARIES := \
	libGLESv2 \
	libGLESv2 \
	libbinder \
	libbinder \
	libui \
	libui \
	libgui
	libgui \
	libpowermanager


LOCAL_MODULE:= libsurfaceflinger
LOCAL_MODULE:= libsurfaceflinger


+16 −24
Original line number Original line Diff line number Diff line
@@ -20,38 +20,30 @@
#include <cutils/log.h>
#include <cutils/log.h>
#include <utils/Errors.h>
#include <utils/Errors.h>


#include <binder/IServiceManager.h>
#include <powermanager/IPowerManager.h>
#include <powermanager/PowerManager.h>

#include "PowerHAL.h"
#include "PowerHAL.h"


namespace android {
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) {
status_t PowerHAL::vsyncHint(bool enabled) {
    if (!mPowerModule) {
    Mutex::Autolock _l(mlock);
        return NO_INIT;
    if (mPowerManager == NULL) {
    }
        const String16 serviceName("power");
    if (mPowerModule->common.module_api_version >= POWER_MODULE_API_VERSION_0_2) {
        sp<IBinder> bs = defaultServiceManager()->checkService(serviceName);
        if (mPowerModule->powerHint) {
        if (bs == NULL) {
            if (mVSyncHintEnabled != bool(enabled)) {
            return NAME_NOT_FOUND;
                mPowerModule->powerHint(mPowerModule,
                        POWER_HINT_VSYNC, (void*)enabled);
                mVSyncHintEnabled = bool(enabled);
        }
        }
        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 Original line Diff line number Diff line
@@ -19,7 +19,9 @@


#include <stdint.h>
#include <stdint.h>
#include <sys/types.h>
#include <sys/types.h>
#include <utils/Mutex.h>


#include <powermanager/IPowerManager.h>
#include <hardware/power.h>
#include <hardware/power.h>


namespace android {
namespace android {
@@ -28,15 +30,11 @@ namespace android {
class PowerHAL
class PowerHAL
{
{
public:
public:
    PowerHAL();
    ~PowerHAL();

    status_t initCheck() const;
    status_t vsyncHint(bool enabled);
    status_t vsyncHint(bool enabled);


private:
private:
    power_module_t*   mPowerModule;
    sp<IPowerManager> mPowerManager;
    bool mVSyncHintEnabled;
    Mutex mlock;
};
};


// ---------------------------------------------------------------------------
// ---------------------------------------------------------------------------
+36 −3
Original line number Original line Diff line number Diff line
@@ -35,12 +35,21 @@
// ---------------------------------------------------------------------------
// ---------------------------------------------------------------------------
namespace android {
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)
EventThread::EventThread(const sp<VSyncSource>& src)
    : mVSyncSource(src),
    : mVSyncSource(src),
      mUseSoftwareVSync(false),
      mUseSoftwareVSync(false),
      mVsyncEnabled(false),
      mVsyncEnabled(false),
      mDebugVsyncEnabled(false) {
      mDebugVsyncEnabled(false),
      mVsyncHintSent(false) {


    for (int32_t i=0 ; i<DisplayDevice::NUM_BUILTIN_DISPLAY_TYPES ; i++) {
    for (int32_t i=0 ; i<DisplayDevice::NUM_BUILTIN_DISPLAY_TYPES ; i++) {
        mVSyncEvent[i].header.type = DisplayEventReceiver::DISPLAY_EVENT_VSYNC;
        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].header.timestamp = 0;
        mVSyncEvent[i].vsync.count =  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() {
void EventThread::onFirstRef() {
@@ -307,17 +341,16 @@ void EventThread::enableVSyncLocked() {
            mVsyncEnabled = true;
            mVsyncEnabled = true;
            mVSyncSource->setCallback(static_cast<VSyncSource::Callback*>(this));
            mVSyncSource->setCallback(static_cast<VSyncSource::Callback*>(this));
            mVSyncSource->setVSyncEnabled(true);
            mVSyncSource->setVSyncEnabled(true);
            mPowerHAL.vsyncHint(true);
        }
        }
    }
    }
    mDebugVsyncEnabled = true;
    mDebugVsyncEnabled = true;
    sendVsyncHintOnLocked();
}
}


void EventThread::disableVSyncLocked() {
void EventThread::disableVSyncLocked() {
    if (mVsyncEnabled) {
    if (mVsyncEnabled) {
        mVsyncEnabled = false;
        mVsyncEnabled = false;
        mVSyncSource->setVSyncEnabled(false);
        mVSyncSource->setVSyncEnabled(false);
        mPowerHAL.vsyncHint(false);
        mDebugVsyncEnabled = false;
        mDebugVsyncEnabled = false;
    }
    }
}
}
+5 −0
Original line number Original line Diff line number Diff line
@@ -97,6 +97,7 @@ public:
            DisplayEventReceiver::Event* event);
            DisplayEventReceiver::Event* event);


    void dump(String8& result) const;
    void dump(String8& result) const;
    void sendVsyncHintOff();


private:
private:
    virtual bool        threadLoop();
    virtual bool        threadLoop();
@@ -107,6 +108,7 @@ private:
    void removeDisplayEventConnection(const wp<Connection>& connection);
    void removeDisplayEventConnection(const wp<Connection>& connection);
    void enableVSyncLocked();
    void enableVSyncLocked();
    void disableVSyncLocked();
    void disableVSyncLocked();
    void sendVsyncHintOnLocked();


    // constants
    // constants
    sp<VSyncSource> mVSyncSource;
    sp<VSyncSource> mVSyncSource;
@@ -124,6 +126,9 @@ private:


    // for debugging
    // for debugging
    bool mDebugVsyncEnabled;
    bool mDebugVsyncEnabled;

    bool mVsyncHintSent;
    timer_t mTimerId;
};
};


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