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

Commit ea0c6c93 authored by Mathias Agopian's avatar Mathias Agopian Committed by Android (Google) Code Review
Browse files

Merge "make sure to disable VSYNC while screen is off"

parents ceb8c193 22ffb117
Loading
Loading
Loading
Loading
+3 −0
Original line number Original line Diff line number Diff line
@@ -205,6 +205,9 @@ status_t HWComposer::commit() const {


status_t HWComposer::release() const {
status_t HWComposer::release() const {
    if (mHwc) {
    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);
        int err = mHwc->set(mHwc, NULL, NULL, NULL);
        return (status_t)err;
        return (status_t)err;
    }
    }
+39 −17
Original line number Original line Diff line number Diff line
@@ -41,6 +41,7 @@ EventThread::EventThread(const sp<SurfaceFlinger>& flinger)
      mHw(flinger->graphicPlane(0).editDisplayHardware()),
      mHw(flinger->graphicPlane(0).editDisplayHardware()),
      mLastVSyncTimestamp(0),
      mLastVSyncTimestamp(0),
      mVSyncTimestamp(0),
      mVSyncTimestamp(0),
      mUseSoftwareVSync(false),
      mDeliveredEvents(0),
      mDeliveredEvents(0),
      mDebugVsyncEnabled(false)
      mDebugVsyncEnabled(false)
{
{
@@ -55,16 +56,6 @@ sp<EventThread::Connection> EventThread::createEventConnection() const {
    return new Connection(const_cast<EventThread*>(this));
    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(
status_t EventThread::registerDisplayEventConnection(
        const sp<EventThread::Connection>& connection) {
        const sp<EventThread::Connection>& connection) {
    Mutex::Autolock _l(mLock);
    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) {
void EventThread::onVSyncReceived(int, nsecs_t timestamp) {
    Mutex::Autolock _l(mLock);
    Mutex::Autolock _l(mLock);
    mVSyncTimestamp = timestamp;
    mVSyncTimestamp = timestamp;
@@ -121,7 +130,6 @@ bool EventThread::threadLoop() {
    Vector< wp<EventThread::Connection> > displayEventConnections;
    Vector< wp<EventThread::Connection> > displayEventConnections;


    do {
    do {

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


            // wait for something to happen
            // 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);
                mCondition.wait(mLock);
            }
        } while(true);
        } while(true);


        // process vsync event
        // process vsync event
@@ -233,12 +250,15 @@ bool EventThread::threadLoop() {
    return true;
    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);
        mHw.getHwComposer().eventControl(HWComposer::EVENT_VSYNC, true);
    }
    mDebugVsyncEnabled = true;
    mDebugVsyncEnabled = true;
}
}


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


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

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


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


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


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


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


    // main thread only
    // main thread only
    size_t mDeliveredEvents;
    size_t mDeliveredEvents;
+7 −1
Original line number Original line Diff line number Diff line
@@ -1467,16 +1467,18 @@ uint32_t SurfaceFlinger::setClientStateLocked(
void SurfaceFlinger::onScreenAcquired() {
void SurfaceFlinger::onScreenAcquired() {
    const DisplayHardware& hw(graphicPlane(0).displayHardware());
    const DisplayHardware& hw(graphicPlane(0).displayHardware());
    hw.acquireScreen();
    hw.acquireScreen();
    mEventThread->onScreenAcquired();
    // this is a temporary work-around, eventually this should be called
    // this is a temporary work-around, eventually this should be called
    // by the power-manager
    // by the power-manager
    SurfaceFlinger::turnElectronBeamOn(mElectronBeamAnimationMode);
    SurfaceFlinger::turnElectronBeamOn(mElectronBeamAnimationMode);
    mDirtyRegion.set(hw.bounds());
    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() {
void SurfaceFlinger::onScreenReleased() {
    const DisplayHardware& hw(graphicPlane(0).displayHardware());
    const DisplayHardware& hw(graphicPlane(0).displayHardware());
    if (hw.isScreenAcquired()) {
    if (hw.isScreenAcquired()) {
        mEventThread->onScreenReleased();
        mDirtyRegion.set(hw.bounds());
        mDirtyRegion.set(hw.bounds());
        hw.releaseScreen();
        hw.releaseScreen();
        // from this point on, SF will stop drawing
        // from this point on, SF will stop drawing
@@ -1883,6 +1885,8 @@ status_t SurfaceFlinger::renderScreenToTexture(DisplayID dpy,
status_t SurfaceFlinger::renderScreenToTextureLocked(DisplayID dpy,
status_t SurfaceFlinger::renderScreenToTextureLocked(DisplayID dpy,
        GLuint* textureName, GLfloat* uOut, GLfloat* vOut)
        GLuint* textureName, GLfloat* uOut, GLfloat* vOut)
{
{
    ATRACE_CALL();

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


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


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

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