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

Commit 22ffb117 authored by Mathias Agopian's avatar Mathias Agopian
Browse files

make sure to disable VSYNC while screen is off

Change-Id: If1894c43b0a39a2851e1280a35ae77bccd6d9abd
parent b60314a1
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -205,6 +205,9 @@ status_t HWComposer::commit() const {

status_t HWComposer::release() const {
    if (mHwc) {
        if (mHwc->common.version >= HWC_DEVICE_API_VERSION_0_3) {
            mHwc->methods->eventControl(mHwc, HWC_EVENT_VSYNC, 0);
        }
        int err = mHwc->set(mHwc, NULL, NULL, NULL);
        return (status_t)err;
    }
+39 −17
Original line number Diff line number Diff line
@@ -41,6 +41,7 @@ EventThread::EventThread(const sp<SurfaceFlinger>& flinger)
      mHw(flinger->graphicPlane(0).editDisplayHardware()),
      mLastVSyncTimestamp(0),
      mVSyncTimestamp(0),
      mUseSoftwareVSync(false),
      mDeliveredEvents(0),
      mDebugVsyncEnabled(false)
{
@@ -55,16 +56,6 @@ sp<EventThread::Connection> EventThread::createEventConnection() const {
    return new Connection(const_cast<EventThread*>(this));
}

nsecs_t EventThread::getLastVSyncTimestamp() const {
    Mutex::Autolock _l(mLock);
    return mLastVSyncTimestamp;
}

nsecs_t EventThread::getVSyncPeriod() const {
    return mHw.getRefreshPeriod();

}

status_t EventThread::registerDisplayEventConnection(
        const sp<EventThread::Connection>& connection) {
    Mutex::Autolock _l(mLock);
@@ -108,6 +99,24 @@ void EventThread::requestNextVsync(
    }
}

void EventThread::onScreenReleased() {
    Mutex::Autolock _l(mLock);
    // wait for an eventual pending vsync to be serviced
    if (!mUseSoftwareVSync) {
        while (mVSyncTimestamp) {
            mCondition.wait(mLock);
        }
    }
    // disable reliance on h/w vsync
    mUseSoftwareVSync = true;
}

void EventThread::onScreenAcquired() {
    Mutex::Autolock _l(mLock);
    mUseSoftwareVSync = false;
}


void EventThread::onVSyncReceived(int, nsecs_t timestamp) {
    Mutex::Autolock _l(mLock);
    mVSyncTimestamp = timestamp;
@@ -121,7 +130,6 @@ bool EventThread::threadLoop() {
    Vector< wp<EventThread::Connection> > displayEventConnections;

    do {

        Mutex::Autolock _l(mLock);
        do {
            // latch VSYNC event if any
@@ -145,7 +153,7 @@ bool EventThread::threadLoop() {
                if (!waitForNextVsync) {
                    // we received a VSYNC but we have no clients
                    // don't report it, and disable VSYNC events
                    disableVSync();
                    disableVSyncLocked();
                } else {
                    // report VSYNC event
                    break;
@@ -157,12 +165,21 @@ bool EventThread::threadLoop() {
                // disable VSYNC events then.
                if (waitForNextVsync) {
                    // enable
                    enableVSync();
                    enableVSyncLocked();
                }
            }

            // wait for something to happen
            if (mUseSoftwareVSync == true) {
                // h/w vsync cannot be used (screen is off), so we use
                // a  timeout instead. it doesn't matter how imprecise this
                // is, we just need to make sure to serve the clients
                if (mCondition.waitRelative(mLock, ms2ns(16)) == TIMED_OUT) {
                    mVSyncTimestamp = systemTime(SYSTEM_TIME_MONOTONIC);
                }
            } else {
                mCondition.wait(mLock);
            }
        } while(true);

        // process vsync event
@@ -233,12 +250,15 @@ bool EventThread::threadLoop() {
    return true;
}

void EventThread::enableVSync() {
void EventThread::enableVSyncLocked() {
    if (!mUseSoftwareVSync) {
        // never enable h/w VSYNC when screen is off
        mHw.getHwComposer().eventControl(HWComposer::EVENT_VSYNC, true);
    }
    mDebugVsyncEnabled = true;
}

void EventThread::disableVSync() {
void EventThread::disableVSyncLocked() {
    mHw.getHwComposer().eventControl(HWComposer::EVENT_VSYNC, false);
    mDebugVsyncEnabled = false;
}
@@ -252,6 +272,8 @@ void EventThread::dump(String8& result, char* buffer, size_t SIZE) const {
    Mutex::Autolock _l(mLock);
    result.appendFormat("VSYNC state: %s\n",
            mDebugVsyncEnabled?"enabled":"disabled");
    result.appendFormat("  soft-vsync: %s\n",
            mUseSoftwareVSync?"enabled":"disabled");
    result.appendFormat("  numListeners=%u,\n  events-delivered: %u\n",
            mDisplayEventConnections.size(), mDeliveredEvents);
    for (size_t i=0 ; i<mDisplayEventConnections.size() ; i++) {
+8 −4
Original line number Diff line number Diff line
@@ -72,8 +72,11 @@ public:
    void setVsyncRate(uint32_t count, const sp<Connection>& connection);
    void requestNextVsync(const sp<Connection>& connection);

    nsecs_t getLastVSyncTimestamp() const;
    nsecs_t getVSyncPeriod() const;
    // called before the screen is turned off from main thread
    void onScreenReleased();

    // called after the screen is turned on from main thread
    void onScreenAcquired();

    void dump(String8& result, char* buffer, size_t SIZE) const;

@@ -84,8 +87,8 @@ private:
    virtual void        onVSyncReceived(int, nsecs_t timestamp);

    void removeDisplayEventConnection(const wp<Connection>& connection);
    void enableVSync();
    void disableVSync();
    void enableVSyncLocked();
    void disableVSyncLocked();

    // constants
    sp<SurfaceFlinger> mFlinger;
@@ -98,6 +101,7 @@ private:
    SortedVector< wp<Connection> > mDisplayEventConnections;
    nsecs_t mLastVSyncTimestamp;
    nsecs_t mVSyncTimestamp;
    bool mUseSoftwareVSync;

    // main thread only
    size_t mDeliveredEvents;
+7 −1
Original line number Diff line number Diff line
@@ -1467,16 +1467,18 @@ uint32_t SurfaceFlinger::setClientStateLocked(
void SurfaceFlinger::onScreenAcquired() {
    const DisplayHardware& hw(graphicPlane(0).displayHardware());
    hw.acquireScreen();
    mEventThread->onScreenAcquired();
    // this is a temporary work-around, eventually this should be called
    // by the power-manager
    SurfaceFlinger::turnElectronBeamOn(mElectronBeamAnimationMode);
    mDirtyRegion.set(hw.bounds());
    // from this point on, SF will priocess updates again
    // from this point on, SF will process updates again
}

void SurfaceFlinger::onScreenReleased() {
    const DisplayHardware& hw(graphicPlane(0).displayHardware());
    if (hw.isScreenAcquired()) {
        mEventThread->onScreenReleased();
        mDirtyRegion.set(hw.bounds());
        hw.releaseScreen();
        // from this point on, SF will stop drawing
@@ -1883,6 +1885,8 @@ status_t SurfaceFlinger::renderScreenToTexture(DisplayID dpy,
status_t SurfaceFlinger::renderScreenToTextureLocked(DisplayID dpy,
        GLuint* textureName, GLfloat* uOut, GLfloat* vOut)
{
    ATRACE_CALL();

    if (!GLExtensions::getInstance().haveFramebufferObject())
        return INVALID_OPERATION;

@@ -2263,6 +2267,8 @@ status_t SurfaceFlinger::electronBeamOnAnimationImplLocked()

status_t SurfaceFlinger::turnElectronBeamOffImplLocked(int32_t mode)
{
    ATRACE_CALL();

    DisplayHardware& hw(graphicPlane(0).editDisplayHardware());
    if (!hw.canDraw()) {
        // we're already off