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

Commit c7a25adf authored by Dan Stoza's avatar Dan Stoza
Browse files

SF: Fix repaint everything logic

This solves the same problem with dirty regions not being updated
as Ia7a3dc15c96626a213c4459dac4f695d91540fb5, but it is better in a
couple of ways:

  1) It no longer updates dirty regions from a binder thread, which was
     likely causing the memory corruption in b/77919748.
  2) It removes the distinction between repaintEverything and
     repaintEverythingLocked, which is not necessary since both
     operations in repaintEverything (updating an atomic and signaling a
     transaction) are threadsafe.

Bug: 77335744
Bug: 77546473
Bug: 77919748
Test: Manual - on an ASAN build, played TouchLatency bouncy ball while
      toggling between GL and HWC composition; doesn't crash whereas it
      would crash in a matter of a couple minutes before

Change-Id: Iecadfecb40e87e400a301de2dcad1664e154982d
parent f0747473
Loading
Loading
Loading
Loading
+4 −15
Original line number Diff line number Diff line
@@ -1387,7 +1387,7 @@ void SurfaceFlinger::onRefreshReceived(int sequenceId,
    if (sequenceId != getBE().mComposerSequenceId) {
        return;
    }
    repaintEverythingLocked();
    repaintEverything();
}

void SurfaceFlinger::setVsyncEnabled(int disp, int enabled) {
@@ -1949,7 +1949,7 @@ void SurfaceFlinger::setUpHWComposer() {
    ALOGV("setUpHWComposer");

    for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) {
        bool dirty = !mDisplays[dpy]->getDirtyRegion(false).isEmpty();
        bool dirty = !mDisplays[dpy]->getDirtyRegion(mRepaintEverything).isEmpty();
        bool empty = mDisplays[dpy]->getVisibleLayersSortedByZ().size() == 0;
        bool wasEmpty = !mDisplays[dpy]->lastCompositionHadVisibleLayers;

@@ -3716,7 +3716,7 @@ void SurfaceFlinger::setPowerModeInternal(const sp<DisplayDevice>& hw,

        mVisibleRegionsDirty = true;
        mHasPoweredOff = true;
        repaintEverythingLocked();
        repaintEverything();

        struct sched_param param = {0};
        param.sched_priority = 1;
@@ -4637,22 +4637,11 @@ status_t SurfaceFlinger::onTransact(
    return err;
}

void SurfaceFlinger::repaintEverythingLocked() {
void SurfaceFlinger::repaintEverything() {
    android_atomic_or(1, &mRepaintEverything);
    for (size_t dpy = 0; dpy < mDisplays.size(); dpy++) {
        const sp<DisplayDevice>& displayDevice(mDisplays[dpy]);
        const Rect bounds(displayDevice->getBounds());
        displayDevice->dirtyRegion.orSelf(Region(bounds));
    }
    signalTransaction();
}

void SurfaceFlinger::repaintEverything() {
    ConditionalLock _l(mStateLock,
            std::this_thread::get_id() != mMainThreadId);
    repaintEverythingLocked();
}

// A simple RAII class to disconnect from an ANativeWindow* when it goes out of scope
class WindowDisconnector {
public:
+0 −2
Original line number Diff line number Diff line
@@ -312,8 +312,6 @@ public:

    // force full composition on all displays
    void repaintEverything();
    // Can only be called from the main thread or with mStateLock held
    void repaintEverythingLocked();

    // returns the default Display
    sp<const DisplayDevice> getDefaultDisplayDevice() const {