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

Commit 29c2351c authored by Lloyd Pique's avatar Lloyd Pique Committed by Android (Google) Code Review
Browse files

Merge changes from topic "surfaceflinger-arc"

* changes:
  SF: Cleanups to use std::atomic/std::mutex
  SF: Allow SurfaceFlinger creation to be altered
parents d8c5b511 f1c675b3
Loading
Loading
Loading
Loading
+38 −32
Original line number Diff line number Diff line
@@ -4,6 +4,7 @@ cc_defaults {
        "-DLOG_TAG=\"SurfaceFlinger\"",
        "-Wall",
        "-Werror",
        "-Wformat",
        "-Wthread-safety",
        "-Wunused",
        "-Wunreachable-code",
@@ -18,6 +19,10 @@ cc_defaults {
        "-DGL_GLEXT_PROTOTYPES",
        "-DEGL_EGLEXT_PROTOTYPES",
    ],
    include_dirs: [
        "frameworks/native/vulkan/vkjson",
        "frameworks/native/vulkan/include",
    ],
    shared_libs: [
        "android.frameworks.vr.composer@1.0",
        "android.hardware.configstore-utils",
@@ -84,6 +89,18 @@ cc_defaults {
    ],
}

cc_defaults {
    name: "libsurfaceflinger_production_defaults",
    defaults: ["libsurfaceflinger_defaults"],
    cflags: [
        "-fvisibility=hidden",
        "-fwhole-program-vtables", // requires ThinLTO
    ],
    lto: {
        thin: true,
    },
}

cc_library_headers {
    name: "libsurfaceflinger_headers",
    export_include_dirs: ["."],
@@ -137,33 +154,23 @@ filegroup {
}

cc_library_shared {
    // Please use libsurfaceflinger_defaults to configure how the sources are
    // built, so the same settings can be used elsewhere.
    name: "libsurfaceflinger",
    defaults: ["libsurfaceflinger_defaults"],
    cflags: [
        "-fvisibility=hidden",
        "-Werror=format",
    ],
    defaults: ["libsurfaceflinger_production_defaults"],
    srcs: [
        ":libsurfaceflinger_sources",

        // Note: SurfaceFlingerFactory is not in the default sources so that it
        // can be easily replaced.
        "SurfaceFlingerFactory.cpp",
    ],
    logtags: ["EventLog/EventLogTags.logtags"],
    include_dirs: [
        "frameworks/native/vulkan/vkjson",
        "frameworks/native/vulkan/include",
    ],
    cppflags: [
        "-fwhole-program-vtables", // requires ThinLTO
    ],
    lto: {
        thin: true,
    },
}

cc_binary {
    name: "surfaceflinger",
cc_defaults {
    name: "libsurfaceflinger_binary",
    defaults: ["surfaceflinger_defaults"],
    init_rc: ["surfaceflinger.rc"],
    srcs: ["main_surfaceflinger.cpp"],
    whole_static_libs: [
        "libsigchain",
    ],
@@ -180,7 +187,6 @@ cc_binary {
        "libhidltransport",
        "liblayers_proto",
        "liblog",
        "libsurfaceflinger",
        "libtimestats_proto",
        "libutils",
    ],
@@ -189,19 +195,19 @@ cc_binary {
        "libtrace_proto",
    ],
    ldflags: ["-Wl,--export-dynamic"],
}

    // TODO(b/71715793): These version-scripts are required due to the use of
    // whole_static_libs to pull in libsigchain. To work, the files had to be
    // locally duplicated from their original location
    // $ANDROID_ROOT/art/sigchainlib/
    multilib: {
        lib32: {
            version_script: "version-script32.txt",
        },
        lib64: {
            version_script: "version-script64.txt",
        },
    },
filegroup {
    name: "surfaceflinger_binary_sources",
    srcs: ["main_surfaceflinger.cpp"],
}

cc_binary {
    name: "surfaceflinger",
    defaults: ["libsurfaceflinger_binary"],
    init_rc: ["surfaceflinger.rc"],
    srcs: [":surfaceflinger_binary_sources"],
    shared_libs: ["libsurfaceflinger"],
}

cc_library_shared {
+12 −18
Original line number Diff line number Diff line
@@ -18,46 +18,40 @@
#define ANDROID_BARRIER_H

#include <stdint.h>
#include <sys/types.h>
#include <utils/threads.h>
#include <condition_variable>
#include <mutex>

namespace android {

class Barrier
{
public:
    inline Barrier() : state(CLOSED) { }
    inline ~Barrier() { }

    // Release any threads waiting at the Barrier.
    // Provides release semantics: preceding loads and stores will be visible
    // to other threads before they wake up.
    void open() {
        Mutex::Autolock _l(lock);
        state = OPENED;
        cv.broadcast();
        std::lock_guard<std::mutex> lock(mMutex);
        mIsOpen = true;
        mCondition.notify_all();
    }

    // Reset the Barrier, so wait() will block until open() has been called.
    void close() {
        Mutex::Autolock _l(lock);
        state = CLOSED;
        std::lock_guard<std::mutex> lock(mMutex);
        mIsOpen = false;
    }

    // Wait until the Barrier is OPEN.
    // Provides acquire semantics: no subsequent loads or stores will occur
    // until wait() returns.
    void wait() const {
        Mutex::Autolock _l(lock);
        while (state == CLOSED) {
            cv.wait(lock);
        }
        std::unique_lock<std::mutex> lock(mMutex);
        mCondition.wait(lock, [this]() NO_THREAD_SAFETY_ANALYSIS { return mIsOpen; });
    }
private:
    enum { OPENED, CLOSED };
    mutable     Mutex       lock;
    mutable     Condition   cv;
    volatile    int         state;
    mutable std::mutex mMutex;
    mutable std::condition_variable mCondition;
    int mIsOpen GUARDED_BY(mMutex){false};
};

}; // namespace android
+11 −9
Original line number Diff line number Diff line
@@ -207,8 +207,9 @@ bool BufferQueueLayer::getSidebandStreamChanged() const {
}

std::optional<Region> BufferQueueLayer::latchSidebandStream(bool& recomputeVisibleRegions) {
    if (android_atomic_acquire_cas(true, false, &mSidebandStreamChanged) == 0) {
        // mSidebandStreamChanged was true
    bool sidebandStreamChanged = true;
    if (mSidebandStreamChanged.compare_exchange_strong(sidebandStreamChanged, false)) {
        // mSidebandStreamChanged was changed to false
        // replicated in LayerBE until FE/BE is ready to be synchronized
        getBE().compositionInfo.hwc.sidebandStream = mConsumer->getSidebandStream();
        if (getBE().compositionInfo.hwc.sidebandStream != nullptr) {
@@ -259,7 +260,7 @@ status_t BufferQueueLayer::updateTexImage(bool& recomputeVisibleRegions, nsecs_t
            Mutex::Autolock lock(mQueueItemLock);
            mTimeStats.removeTimeRecord(getName().c_str(), mQueueItems[0].mFrameNumber);
            mQueueItems.removeAt(0);
            android_atomic_dec(&mQueuedFrames);
            mQueuedFrames--;
        }
        return BAD_VALUE;
    } else if (updateResult != NO_ERROR || mUpdateTexImageFailed) {
@@ -270,7 +271,7 @@ status_t BufferQueueLayer::updateTexImage(bool& recomputeVisibleRegions, nsecs_t
        if (queuedBuffer) {
            Mutex::Autolock lock(mQueueItemLock);
            mQueueItems.clear();
            android_atomic_and(0, &mQueuedFrames);
            mQueuedFrames = 0;
            mTimeStats.clearLayerRecord(getName().c_str());
        }

@@ -294,7 +295,7 @@ status_t BufferQueueLayer::updateTexImage(bool& recomputeVisibleRegions, nsecs_t
        while (mQueueItems[0].mFrameNumber != currentFrameNumber) {
            mTimeStats.removeTimeRecord(getName().c_str(), mQueueItems[0].mFrameNumber);
            mQueueItems.removeAt(0);
            android_atomic_dec(&mQueuedFrames);
            mQueuedFrames--;
        }

        const std::string layerName(getName().c_str());
@@ -306,7 +307,7 @@ status_t BufferQueueLayer::updateTexImage(bool& recomputeVisibleRegions, nsecs_t

    // Decrement the queued-frames count.  Signal another event if we
    // have more frames pending.
    if ((queuedBuffer && android_atomic_dec(&mQueuedFrames) > 1) || mAutoRefresh) {
    if ((queuedBuffer && mQueuedFrames.fetch_sub(1) > 1) || mAutoRefresh) {
        mFlinger->signalLayerUpdate();
    }

@@ -367,7 +368,7 @@ void BufferQueueLayer::onFrameAvailable(const BufferItem& item) {
        }

        mQueueItems.push_back(item);
        android_atomic_inc(&mQueuedFrames);
        mQueuedFrames++;

        // Wake up any pending callbacks
        mLastFrameNumberReceived = item.mFrameNumber;
@@ -404,8 +405,9 @@ void BufferQueueLayer::onFrameReplaced(const BufferItem& item) {
}

void BufferQueueLayer::onSidebandStreamChanged() {
    if (android_atomic_release_cas(false, true, &mSidebandStreamChanged) == 0) {
        // mSidebandStreamChanged was false
    bool sidebandStreamChanged = false;
    if (mSidebandStreamChanged.compare_exchange_strong(sidebandStreamChanged, true)) {
        // mSidebandStreamChanged was changed to true
        mFlinger->signalLayerUpdate();
    }
}
+2 −2
Original line number Diff line number Diff line
@@ -137,8 +137,8 @@ private:
    int mActiveBufferSlot;

    // thread-safe
    volatile int32_t mQueuedFrames;
    volatile int32_t mSidebandStreamChanged; // used like an atomic boolean
    std::atomic<int32_t> mQueuedFrames{0};
    std::atomic<bool> mSidebandStreamChanged{false};
};

} // namespace android
+3 −4
Original line number Diff line number Diff line
@@ -62,12 +62,11 @@

namespace android {

int32_t Layer::sSequence = 1;
std::atomic<int32_t> Layer::sSequence{1};

Layer::Layer(SurfaceFlinger* flinger, const sp<Client>& client, const String8& name, uint32_t w,
             uint32_t h, uint32_t flags)
      : contentDirty(false),
        sequence(uint32_t(android_atomic_inc(&sSequence))),
        mFlinger(flinger),
        mPremultipliedAlpha(true),
        mName(name),
@@ -1019,11 +1018,11 @@ void Layer::commitTransaction(const State& stateToCommit) {
}

uint32_t Layer::getTransactionFlags(uint32_t flags) {
    return android_atomic_and(~flags, &mTransactionFlags) & flags;
    return mTransactionFlags.fetch_and(~flags) & flags;
}

uint32_t Layer::setTransactionFlags(uint32_t flags) {
    return android_atomic_or(flags, &mTransactionFlags);
    return mTransactionFlags.fetch_or(flags);
}

bool Layer::setPosition(float x, float y, bool immediate) {
Loading