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

Commit e7cc1c21 authored by Alec Mouri's avatar Alec Mouri
Browse files

Dedicate a special caching slot for the layer override buffer

By using a special caching slot, this avoids import/freeBuffer churn in
the composer process which can occur when a layer is no longer using an
override buffer. Previously the layer's buffer would have been cached by
a previous setBuffer call, but since the override buffer was clobbering
a caching slot, replacing the override buffer requires re-importing the
buffer.

To resolve this, increase the size of the hwc buffer cache so it's ever
so slightly less tied to buffer queue sizes, which allows for room for
the override buffer which improves caching hit rate. On devices that
don't have layer caching turned on, this is a functional no-op because
those devices will never use the additional caching slot.

Bug: 185570241
Test: libcompositionengine_test
Test: Perfetto trace of opening and closing calculator app shows fewer
import/free buffers in the composer process

Change-Id: I219b1a1f6a31c5405736cb06d4921f300fe4a3ee
parent c1815199
Loading
Loading
Loading
Loading
+5 −1
Original line number Diff line number Diff line
@@ -57,11 +57,15 @@ public:
    void getHwcBuffer(int slot, const sp<GraphicBuffer>& buffer, uint32_t* outSlot,
                      sp<GraphicBuffer>* outBuffer);

    // Special caching slot for the layer caching feature.
    static const constexpr size_t FLATTENER_CACHING_SLOT = BufferQueue::NUM_BUFFER_SLOTS;

private:
    // an array where the index corresponds to a slot and the value corresponds to a (counter,
    // buffer) pair. "counter" is a unique value that indicates the last time this slot was updated
    // or used and allows us to keep track of the least-recently used buffer.
    wp<GraphicBuffer> mBuffers[BufferQueue::NUM_BUFFER_SLOTS];
    static const constexpr size_t kMaxLayerBufferCount = BufferQueue::NUM_BUFFER_SLOTS + 1;
    wp<GraphicBuffer> mBuffers[kMaxLayerBufferCount];
};

} // namespace compositionengine::impl
+1 −1
Original line number Diff line number Diff line
@@ -36,7 +36,7 @@ void HwcBufferCache::getHwcBuffer(int slot, const sp<GraphicBuffer>& buffer, uin
                                  sp<GraphicBuffer>* outBuffer) {
    // default is 0
    if (slot == BufferQueue::INVALID_BUFFER_SLOT || slot < 0 ||
        slot >= BufferQueue::NUM_BUFFER_SLOTS) {
        slot >= static_cast<int32_t>(kMaxLayerBufferCount)) {
        *outSlot = 0;
    } else {
        *outSlot = static_cast<uint32_t>(slot);
+4 −2
Original line number Diff line number Diff line
@@ -18,6 +18,7 @@
#include <compositionengine/DisplayColorProfile.h>
#include <compositionengine/LayerFECompositionState.h>
#include <compositionengine/Output.h>
#include <compositionengine/impl/HwcBufferCache.h>
#include <compositionengine/impl/OutputCompositionState.h>
#include <compositionengine/impl/OutputLayer.h>
#include <compositionengine/impl/OutputLayerCompositionState.h>
@@ -548,9 +549,11 @@ void OutputLayer::writeBufferStateToHWC(HWC2::Layer* hwcLayer,

    sp<GraphicBuffer> buffer = outputIndependentState.buffer;
    sp<Fence> acquireFence = outputIndependentState.acquireFence;
    int slot = outputIndependentState.bufferSlot;
    if (getState().overrideInfo.buffer != nullptr) {
        buffer = getState().overrideInfo.buffer->getBuffer();
        acquireFence = getState().overrideInfo.acquireFence;
        slot = HwcBufferCache::FLATTENER_CACHING_SLOT;
    }

    ALOGV("Writing buffer %p", buffer.get());
@@ -559,8 +562,7 @@ void OutputLayer::writeBufferStateToHWC(HWC2::Layer* hwcLayer,
    sp<GraphicBuffer> hwcBuffer;
    // We need access to the output-dependent state for the buffer cache there,
    // though otherwise the buffer is not output-dependent.
    editState().hwc->hwcBufferCache.getHwcBuffer(outputIndependentState.bufferSlot, buffer,
                                                 &hwcSlot, &hwcBuffer);
    editState().hwc->hwcBufferCache.getHwcBuffer(slot, buffer, &hwcSlot, &hwcBuffer);

    if (auto error = hwcLayer->setBuffer(hwcSlot, hwcBuffer, acquireFence);
        error != hal::Error::NONE) {
+6 −3
Original line number Diff line number Diff line
@@ -14,6 +14,7 @@
 * limitations under the License.
 */

#include <compositionengine/impl/HwcBufferCache.h>
#include <compositionengine/impl/OutputLayer.h>
#include <compositionengine/impl/OutputLayerCompositionState.h>
#include <compositionengine/mock/CompositionEngine.h>
@@ -702,6 +703,7 @@ struct OutputLayerWriteStateToHWCTest : public OutputLayerTest {
    static constexpr ui::Dataspace kOverrideDataspace = static_cast<ui::Dataspace>(72);
    static constexpr int kSupportedPerFrameMetadata = 101;
    static constexpr int kExpectedHwcSlot = 0;
    static constexpr int kOverrideHwcSlot = impl::HwcBufferCache::FLATTENER_CACHING_SLOT;
    static constexpr bool kLayerGenericMetadata1Mandatory = true;
    static constexpr bool kLayerGenericMetadata2Mandatory = true;

@@ -824,10 +826,11 @@ struct OutputLayerWriteStateToHWCTest : public OutputLayerTest {
        EXPECT_CALL(*mHwcLayer, setSidebandStream(kSidebandStreamHandle));
    }

    void expectSetHdrMetadataAndBufferCalls(sp<GraphicBuffer> buffer = kBuffer,
    void expectSetHdrMetadataAndBufferCalls(uint32_t hwcSlot = kExpectedHwcSlot,
                                            sp<GraphicBuffer> buffer = kBuffer,
                                            sp<Fence> fence = kFence) {
        EXPECT_CALL(*mHwcLayer, setPerFrameMetadata(kSupportedPerFrameMetadata, kHdrMetadata));
        EXPECT_CALL(*mHwcLayer, setBuffer(kExpectedHwcSlot, buffer, fence));
        EXPECT_CALL(*mHwcLayer, setBuffer(hwcSlot, buffer, fence));
    }

    void expectGenericLayerMetadataCalls() {
@@ -1060,7 +1063,7 @@ TEST_F(OutputLayerWriteStateToHWCTest, includesOverrideInfoIfPresent) {
                              kOverrideBlendMode, kOverrideAlpha);
    expectPerFrameCommonCalls(SimulateUnsupported::None, kOverrideDataspace, kOverrideVisibleRegion,
                              kOverrideSurfaceDamage);
    expectSetHdrMetadataAndBufferCalls(kOverrideBuffer, kOverrideFence);
    expectSetHdrMetadataAndBufferCalls(kOverrideHwcSlot, kOverrideBuffer, kOverrideFence);
    expectSetCompositionTypeCall(Hwc2::IComposerClient::Composition::DEVICE);
    EXPECT_CALL(*mLayerFE, hasRoundedCorners()).WillOnce(Return(false));

+8 −9
Original line number Diff line number Diff line
@@ -25,7 +25,6 @@
#include "ComposerHal.h"

#include <composer-command-buffer/2.2/ComposerCommandBuffer.h>
#include <gui/BufferQueue.h>
#include <hidl/HidlTransportSupport.h>
#include <hidl/HidlTransportUtils.h>
#include <log/log.h>
@@ -266,7 +265,7 @@ Error Composer::acceptDisplayChanges(Display display)
Error Composer::createLayer(Display display, Layer* outLayer)
{
    Error error = kDefaultError;
    mClient->createLayer(display, BufferQueue::NUM_BUFFER_SLOTS,
    mClient->createLayer(display, kMaxLayerBufferCount,
                         [&](const auto& tmpError, const auto& tmpLayer) {
                             error = tmpError;
                             if (error != Error::NONE) {
Loading