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

Commit dad39514 authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "SF: Avoid allocation on hot path to IF"

parents 800cef44 9f410f0a
Loading
Loading
Loading
Loading
+6 −3
Original line number Diff line number Diff line
@@ -141,7 +141,7 @@ uint32_t DisplayDevice::getPageFlipCount() const {
    return mCompositionDisplay->getRenderSurface()->getPageFlipCount();
}

std::pair<gui::DisplayInfo, ui::Transform> DisplayDevice::getInputInfo() const {
auto DisplayDevice::getInputInfo() const -> InputInfo {
    gui::DisplayInfo info;
    info.displayId = getLayerStack().id;

@@ -166,10 +166,13 @@ std::pair<gui::DisplayInfo, ui::Transform> DisplayDevice::getInputInfo() const {

    info.logicalWidth = getLayerStackSpaceRect().width();
    info.logicalHeight = getLayerStackSpaceRect().height();
    return {info, displayTransform};

    return {.info = info,
            .transform = displayTransform,
            .receivesInput = receivesInput(),
            .isSecure = isSecure()};
}

// ----------------------------------------------------------------------------
void DisplayDevice::setPowerMode(hal::PowerMode mode) {
    mPowerMode = mode;
    getCompositionDisplay()->setCompositionEnabled(mPowerMode != hal::PowerMode::OFF);
+8 −3
Original line number Diff line number Diff line
@@ -174,9 +174,14 @@ public:
        return mDeviceProductInfo;
    }

    // Get the DisplayInfo that will be sent to InputFlinger, and the display transform that should
    // be applied to all the input windows on the display.
    std::pair<gui::DisplayInfo, ui::Transform> getInputInfo() const;
    struct InputInfo {
        gui::DisplayInfo info;
        ui::Transform transform;
        bool receivesInput;
        bool isSecure;
    };

    InputInfo getInputInfo() const;

    /* ------------------------------------------------------------------------
     * Display power mode management.
+27 −38
Original line number Diff line number Diff line
@@ -50,6 +50,7 @@
#include <cutils/compiler.h>
#include <cutils/properties.h>
#include <ftl/future.h>
#include <ftl/small_map.h>
#include <gui/BufferQueue.h>
#include <gui/DebugEGLImageTracker.h>
#include <gui/IProducerListener.h>
@@ -3258,60 +3259,48 @@ void SurfaceFlinger::persistDisplayBrightness(bool needsComposite) {

void SurfaceFlinger::buildWindowInfos(std::vector<WindowInfo>& outWindowInfos,
                                      std::vector<DisplayInfo>& outDisplayInfos) {
    struct Details {
        Details(bool receivesInput, bool isSecure, const ui::Transform& transform,
                const DisplayInfo& info)
              : receivesInput(receivesInput),
                isSecure(isSecure),
                transform(std::move(transform)),
                info(std::move(info)) {}
        bool receivesInput;
        bool isSecure;
        ui::Transform transform;
        DisplayInfo info;
    };
    std::unordered_map<uint32_t /*layerStackId*/, Details> inputDisplayDetails;
    ftl::SmallMap<ui::LayerStack, DisplayDevice::InputInfo, 4> displayInputInfos;

    for (const auto& [_, display] : ON_MAIN_THREAD(mDisplays)) {
        const uint32_t layerStackId = display->getLayerStack().id;
        const auto& [info, transform] = display->getInputInfo();
        const auto& [it, emplaced] =
                inputDisplayDetails.try_emplace(layerStackId, display->receivesInput(),
                                                display->isSecure(), transform, info);
        const auto layerStack = display->getLayerStack();
        const auto info = display->getInputInfo();

        const auto [it, emplaced] = displayInputInfos.try_emplace(layerStack, info);
        if (emplaced) {
            continue;
        }

        // There is more than one display for the layerStack. In this case, the first display that
        // is configured to receive input takes precedence.
        auto& details = it->second;
        if (details.receivesInput) {
        // If the layer stack is mirrored on multiple displays, the first display that is configured
        // to receive input takes precedence.
        auto& otherInfo = it->second;
        if (otherInfo.receivesInput) {
            ALOGW_IF(display->receivesInput(),
                     "Multiple displays claim to accept input for the same layer stack: %u",
                     layerStackId);
            continue;
                     layerStack.id);
        } else {
            otherInfo = info;
        }
        details.receivesInput = display->receivesInput();
        details.isSecure = display->isSecure();
        details.transform = std::move(transform);
        details.info = std::move(info);
    }

    static size_t sNumWindowInfos = 0;
    outWindowInfos.reserve(sNumWindowInfos);
    sNumWindowInfos = 0;

    mDrawingState.traverseInReverseZOrder([&](Layer* layer) {
        if (!layer->needsInputInfo()) return;

        const uint32_t layerStackId = layer->getLayerStack().id;
        const auto it = inputDisplayDetails.find(layerStackId);
        if (it == inputDisplayDetails.end()) {
        // Do not create WindowInfos for windows on displays that cannot receive input.
            return;
        if (const auto opt = displayInputInfos.get(layer->getLayerStack())) {
            const auto& info = opt->get();
            outWindowInfos.push_back(layer->fillInputInfo(info.transform, info.isSecure));
        }

        const auto& details = it->second;
        outWindowInfos.push_back(layer->fillInputInfo(details.transform, details.isSecure));
    });

    for (const auto& [_, details] : inputDisplayDetails) {
        outDisplayInfos.push_back(std::move(details.info));
    sNumWindowInfos = outWindowInfos.size();

    outDisplayInfos.reserve(displayInputInfos.size());
    for (const auto& [_, info] : displayInputInfos) {
        outDisplayInfos.push_back(info.info);
    }
}

+11 −12
Original line number Diff line number Diff line
@@ -14,10 +14,11 @@
 * limitations under the License.
 */

#include "WindowInfosListenerInvoker.h"
#include <ftl/small_vector.h>
#include <gui/ISurfaceComposer.h>
#include <unordered_set>

#include "SurfaceFlinger.h"
#include "WindowInfosListenerInvoker.h"

namespace android {

@@ -41,18 +42,17 @@ WindowInfosListenerInvoker::WindowInfosListenerInvoker(SurfaceFlinger& flinger)
      : mFlinger(flinger),
        mWindowInfosReportedListener(sp<WindowInfosReportedListener>::make(*this)) {}

void WindowInfosListenerInvoker::addWindowInfosListener(
        const sp<IWindowInfosListener>& windowInfosListener) {
    sp<IBinder> asBinder = IInterface::asBinder(windowInfosListener);

void WindowInfosListenerInvoker::addWindowInfosListener(sp<IWindowInfosListener> listener) {
    sp<IBinder> asBinder = IInterface::asBinder(listener);
    asBinder->linkToDeath(this);

    std::scoped_lock lock(mListenersMutex);
    mWindowInfosListeners.emplace(asBinder, windowInfosListener);
    mWindowInfosListeners.try_emplace(asBinder, std::move(listener));
}

void WindowInfosListenerInvoker::removeWindowInfosListener(
        const sp<IWindowInfosListener>& windowInfosListener) {
    sp<IBinder> asBinder = IInterface::asBinder(windowInfosListener);
        const sp<IWindowInfosListener>& listener) {
    sp<IBinder> asBinder = IInterface::asBinder(listener);

    std::scoped_lock lock(mListenersMutex);
    asBinder->unlinkToDeath(this);
@@ -67,12 +67,11 @@ void WindowInfosListenerInvoker::binderDied(const wp<IBinder>& who) {
void WindowInfosListenerInvoker::windowInfosChanged(const std::vector<WindowInfo>& windowInfos,
                                                    const std::vector<DisplayInfo>& displayInfos,
                                                    bool shouldSync) {
    std::unordered_set<sp<IWindowInfosListener>, SpHash<IWindowInfosListener>> windowInfosListeners;

    ftl::SmallVector<const sp<IWindowInfosListener>, kStaticCapacity> windowInfosListeners;
    {
        std::scoped_lock lock(mListenersMutex);
        for (const auto& [_, listener] : mWindowInfosListeners) {
            windowInfosListeners.insert(listener);
            windowInfosListeners.push_back(listener);
        }
    }

+6 −5
Original line number Diff line number Diff line
@@ -20,10 +20,8 @@
#include <android/gui/IWindowInfosListener.h>
#include <android/gui/IWindowInfosReportedListener.h>
#include <binder/IBinder.h>
#include <ftl/small_map.h>
#include <utils/Mutex.h>
#include <unordered_map>

#include "WpHash.h"

namespace android {

@@ -33,7 +31,7 @@ class WindowInfosListenerInvoker : public IBinder::DeathRecipient {
public:
    explicit WindowInfosListenerInvoker(SurfaceFlinger&);

    void addWindowInfosListener(const sp<gui::IWindowInfosListener>& windowInfosListener);
    void addWindowInfosListener(sp<gui::IWindowInfosListener>);
    void removeWindowInfosListener(const sp<gui::IWindowInfosListener>& windowInfosListener);

    void windowInfosChanged(const std::vector<gui::WindowInfo>&,
@@ -48,8 +46,11 @@ private:

    SurfaceFlinger& mFlinger;
    std::mutex mListenersMutex;
    std::unordered_map<wp<IBinder>, const sp<gui::IWindowInfosListener>, WpHash>

    static constexpr size_t kStaticCapacity = 3;
    ftl::SmallMap<wp<IBinder>, const sp<gui::IWindowInfosListener>, kStaticCapacity>
            mWindowInfosListeners GUARDED_BY(mListenersMutex);

    sp<gui::IWindowInfosReportedListener> mWindowInfosReportedListener;
    std::atomic<size_t> mCallbacksPending{0};
};