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

Commit 127d99cc authored by Sally Qi's avatar Sally Qi
Browse files

Stop tons of graphics allocation when hdr/sdr ratio overlay is enabled.

- to reduce memory takup, we create 2 square gfx buffers and
  alternatively use one of them to avoid possible tearing.

Bug: 293194007
Test: check SF dumpsys
Change-Id: Ib4d3df480812cc824bcc433566665d915efcc102
parent 3e7eb31b
Loading
Loading
Loading
Loading
+30 −21
Original line number Diff line number Diff line
@@ -42,28 +42,37 @@ void HdrSdrRatioOverlay::drawNumber(float number, int left, SkColor color, SkCan
}

sp<GraphicBuffer> HdrSdrRatioOverlay::draw(float currentHdrSdrRatio, SkColor color,
                                           ui::Transform::RotationFlags rotation) {
                                           ui::Transform::RotationFlags rotation,
                                           sp<GraphicBuffer>& ringBuffer) {
    const int32_t bufferWidth = kBufferWidth;
    const int32_t bufferHeight = kBufferWidth;

    const auto kUsageFlags = static_cast<uint64_t>(
            GRALLOC_USAGE_SW_WRITE_RARELY | GRALLOC_USAGE_HW_COMPOSER | GRALLOC_USAGE_HW_TEXTURE);

    // ring buffers here to do double-buffered rendering to avoid
    // possible tearing and also to reduce memory take-up.
    if (ringBuffer == nullptr) {
        ringBuffer = sp<GraphicBuffer>::make(static_cast<uint32_t>(bufferWidth),
                                             static_cast<uint32_t>(bufferHeight),
                                             HAL_PIXEL_FORMAT_RGBA_8888, 1u, kUsageFlags,
                                             "HdrSdrRatioOverlayBuffer");
    }

    auto& buffer = ringBuffer;

    SkMatrix canvasTransform = SkMatrix();
    const auto [bufferWidth, bufferHeight] = [&]() -> std::pair<int, int> {
    switch (rotation) {
        case ui::Transform::ROT_90:
                canvasTransform.setTranslate(kBufferHeight, 0);
            canvasTransform.setTranslate(bufferHeight, 0);
            canvasTransform.preRotate(90.f);
                return {kBufferHeight, kBufferWidth};
            break;
        case ui::Transform::ROT_270:
                canvasTransform.setRotate(270.f, kBufferWidth / 2.f, kBufferWidth / 2.f);
                return {kBufferHeight, kBufferWidth};
            canvasTransform.setRotate(270.f, bufferWidth / 2.f, bufferWidth / 2.f);
            break;
        default:
                return {kBufferWidth, kBufferHeight};
            break;
    }
    }();

    const auto kUsageFlags = static_cast<uint64_t>(
            GRALLOC_USAGE_SW_WRITE_RARELY | GRALLOC_USAGE_HW_COMPOSER | GRALLOC_USAGE_HW_TEXTURE);
    sp<GraphicBuffer> buffer =
            sp<GraphicBuffer>::make(static_cast<uint32_t>(bufferWidth),
                                    static_cast<uint32_t>(bufferHeight), HAL_PIXEL_FORMAT_RGBA_8888,
                                    1u, kUsageFlags, "HdrSdrRatioOverlay");

    const status_t bufferStatus = buffer->initCheck();
    LOG_ALWAYS_FATAL_IF(bufferStatus != OK, "HdrSdrRatioOverlay: Buffer failed to allocate: %d",
@@ -163,13 +172,13 @@ auto HdrSdrRatioOverlay::getOrCreateBuffers(float currentHdrSdrRatio) -> const s

    const SkColor color = colorBase.toSkColor();

    auto buffer = draw(currentHdrSdrRatio, color, transformHint);
    auto buffer = draw(currentHdrSdrRatio, color, transformHint, mRingBuffer[mIndex]);
    mIndex = (mIndex + 1) % 2;
    return buffer;
}

void HdrSdrRatioOverlay::animate() {
    if (!std::isfinite(mCurrentHdrSdrRatio) || mCurrentHdrSdrRatio < 1.0f) return;

    SurfaceComposerClient::Transaction()
            .setBuffer(mSurfaceControl->get(), getOrCreateBuffers(mCurrentHdrSdrRatio))
            .apply();
+5 −1
Original line number Diff line number Diff line
@@ -35,11 +35,15 @@ public:
private:
    float mCurrentHdrSdrRatio = 1.f;

    static sp<GraphicBuffer> draw(float currentHdrSdrRatio, SkColor, ui::Transform::RotationFlags);
    static sp<GraphicBuffer> draw(float currentHdrSdrRatio, SkColor, ui::Transform::RotationFlags,
                                  sp<GraphicBuffer>& ringBufer);
    static void drawNumber(float number, int left, SkColor, SkCanvas&);

    const sp<GraphicBuffer> getOrCreateBuffers(float currentHdrSdrRatio);

    const std::unique_ptr<SurfaceControlHolder> mSurfaceControl;

    size_t mIndex = 0;
    std::array<sp<GraphicBuffer>, 2> mRingBuffer;
};
} // namespace android