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 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