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

Commit 2cbb93eb authored by Brian Lindahl's avatar Brian Lindahl Committed by Android (Google) Code Review
Browse files

Merge changes from topic "clear-buffer-slots"

* changes:
  Maintain the active buffer when clearing buffer slots
  Clear HWC layer buffer slots by assiging a placeholder buffer
parents 8d5aea76 b158a5c5
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -83,7 +83,7 @@ public:
    // If the buffer is already in the cache, the buffer is null to optimize away sending HWC the
    // buffer handle.
    //
    HwcSlotAndBuffer getHwcSlotAndBufferForOverride(const sp<GraphicBuffer>& buffer);
    HwcSlotAndBuffer getOverrideHwcSlotAndBuffer(const sp<GraphicBuffer>& buffer);

    //
    // When a client process discards a buffer, it needs to be purged from the HWC cache.
+3 −0
Original line number Diff line number Diff line
@@ -136,6 +136,9 @@ struct OutputLayerCompositionState {
        // cost of sending reused buffers to the HWC.
        HwcBufferCache hwcBufferCache;

        // The previously-active buffer for this layer.
        uint32_t activeBufferSlot;

        // Set to true when overridden info has been sent to HW composer
        bool stateOverridden = false;

+1 −0
Original line number Diff line number Diff line
@@ -36,6 +36,7 @@ private:
    // sp<StrictMock<LayerFE>>::make()
    friend class sp<LayerFE>;
    friend class testing::StrictMock<LayerFE>;
    friend class testing::NiceMock<LayerFE>;

public:
    virtual ~LayerFE();
+2 −2
Original line number Diff line number Diff line
@@ -22,7 +22,7 @@
namespace android::compositionengine::impl {

HwcBufferCache::HwcBufferCache() {
    for (uint32_t i = 0; i < kMaxLayerBufferCount; i++) {
    for (uint32_t i = kMaxLayerBufferCount; i-- > 0;) {
        mFreeSlots.push(i);
    }
}
@@ -42,7 +42,7 @@ HwcSlotAndBuffer HwcBufferCache::getHwcSlotAndBuffer(const sp<GraphicBuffer>& bu
    return {cache(buffer), buffer};
}

HwcSlotAndBuffer HwcBufferCache::getHwcSlotAndBufferForOverride(const sp<GraphicBuffer>& buffer) {
HwcSlotAndBuffer HwcBufferCache::getOverrideHwcSlotAndBuffer(const sp<GraphicBuffer>& buffer) {
    if (buffer == mLastOverrideBuffer) {
        return {kOverrideBufferSlot, nullptr};
    }
+33 −13
Original line number Diff line number Diff line
@@ -610,16 +610,26 @@ void OutputLayer::writeSidebandStateToHWC(HWC2::Layer* hwcLayer,
    }
}

void OutputLayer::uncacheBuffers(std::vector<uint64_t> const& bufferIdsToUncache) {
void OutputLayer::uncacheBuffers(const std::vector<uint64_t>& bufferIdsToUncache) {
    auto& state = editState();
    // Skip doing this if there is no HWC interface
    if (!state.hwc) {
        return;
    }

    for (auto bufferId : bufferIdsToUncache) {
        state.hwc->hwcBufferCache.uncache(bufferId);
        // TODO(b/258196272): send uncache requests to Composer HAL
    std::vector<uint32_t> slotsToClear;
    for (uint64_t bufferId : bufferIdsToUncache) {
        uint32_t slot = state.hwc->hwcBufferCache.uncache(bufferId);
        if (slot != UINT32_MAX) {
            slotsToClear.push_back(slot);
        }
    }

    hal::Error error =
            state.hwc->hwcLayer->setBufferSlotsToClear(slotsToClear, state.hwc->activeBufferSlot);
    if (error != hal::Error::NONE) {
        ALOGE("[%s] Failed to clear buffer slots: %s (%d)", getLayerFE().getDebugName(),
              to_string(error).c_str(), static_cast<int32_t>(error));
    }
}

@@ -637,17 +647,27 @@ void OutputLayer::writeBufferStateToHWC(HWC2::Layer* hwcLayer,

    HwcSlotAndBuffer hwcSlotAndBuffer;
    sp<Fence> hwcFence;
    {
        // Editing the state only because we update the HWC buffer cache and active buffer.
        auto& state = editState();
        // Override buffers use a special cache slot so that they don't evict client buffers.
    if (getState().overrideInfo.buffer != nullptr && !skipLayer) {
        hwcSlotAndBuffer = editState().hwc->hwcBufferCache.getHwcSlotAndBufferForOverride(
                getState().overrideInfo.buffer->getBuffer());
        hwcFence = getState().overrideInfo.acquireFence;
        if (state.overrideInfo.buffer != nullptr && !skipLayer) {
            hwcSlotAndBuffer = state.hwc->hwcBufferCache.getOverrideHwcSlotAndBuffer(
                    state.overrideInfo.buffer->getBuffer());
            hwcFence = state.overrideInfo.acquireFence;
        } else {
            hwcSlotAndBuffer =
                editState().hwc->hwcBufferCache.getHwcSlotAndBuffer(outputIndependentState.buffer);
                    state.hwc->hwcBufferCache.getHwcSlotAndBuffer(outputIndependentState.buffer);
            hwcFence = outputIndependentState.acquireFence;
        }

        // Keep track of the active buffer slot, so we can restore it after clearing other buffer
        // slots.
        if (hwcSlotAndBuffer.buffer) {
            state.hwc->activeBufferSlot = hwcSlotAndBuffer.slot;
        }
    }

    if (auto error = hwcLayer->setBuffer(hwcSlotAndBuffer.slot, hwcSlotAndBuffer.buffer, hwcFence);
        error != hal::Error::NONE) {
        ALOGE("[%s] Failed to set buffer %p: %s (%d)", getLayerFE().getDebugName(),
Loading