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

Commit 628cff4c authored by Brian Lindahl's avatar Brian Lindahl
Browse files

Allow apps to associate a change in picture profiles alongside a buffer

What picture processing a buffer looks best with is often dependent on
the buffer contents itself. It is often necessary for a change in
picture profile to be tightly coupled to a change in buffer.

Bug: 337330263
Test: build
Test: atest BufferQueueTest
Flag: com.android.graphics.libgui.flags.apply_picture_profiles
Change-Id: I8bd3468519fb28a234f6853531638e348b1c5274
parent 07dcd497
Loading
Loading
Loading
Loading
+17 −1
Original line number Diff line number Diff line
@@ -286,18 +286,23 @@ void BLASTBufferQueue::update(const sp<SurfaceControl>& surface, uint32_t width,
    if (surfaceControlChanged && mSurfaceControl != nullptr) {
        BQA_LOGD("Updating SurfaceControl without recreating BBQ");
    }
    bool applyTransaction = false;

    // Always update the native object even though they might have the same layer handle, so we can
    // get the updated transform hint from WM.
    mSurfaceControl = surface;
    SurfaceComposerClient::Transaction t;
    bool applyTransaction = false;
    if (surfaceControlChanged) {
#if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(BUFFER_RELEASE_CHANNEL)
        updateBufferReleaseProducer();
#endif
        t.setFlags(mSurfaceControl, layer_state_t::eEnableBackpressure,
                   layer_state_t::eEnableBackpressure);
        // Migrate the picture profile handle to the new surface control.
        if (com_android_graphics_libgui_flags_apply_picture_profiles() &&
            mPictureProfileHandle.has_value()) {
            t.setPictureProfileHandle(mSurfaceControl, *mPictureProfileHandle);
        }
        applyTransaction = true;
    }
    mTransformHint = mSurfaceControl->getTransformHint();
@@ -679,6 +684,17 @@ status_t BLASTBufferQueue::acquireNextBufferLocked(
    if (!bufferItem.mIsAutoTimestamp) {
        t->setDesiredPresentTime(bufferItem.mTimestamp);
    }
    if (com_android_graphics_libgui_flags_apply_picture_profiles() &&
        bufferItem.mPictureProfileHandle.has_value()) {
        t->setPictureProfileHandle(mSurfaceControl, *bufferItem.mPictureProfileHandle);
        // The current picture profile must be maintained in case the BBQ gets its
        // SurfaceControl switched out.
        mPictureProfileHandle = bufferItem.mPictureProfileHandle;
        // Clear out the picture profile if the requestor has asked for it to be cleared
        if (mPictureProfileHandle == PictureProfileHandle::NONE) {
            mPictureProfileHandle = std::nullopt;
        }
    }

    // Drop stale frame timeline infos
    while (!mPendingFrameTimelines.empty() &&
+45 −20
Original line number Diff line number Diff line
@@ -38,8 +38,8 @@ static inline constexpr T to64(const uint32_t lo, const uint32_t hi) {
    return static_cast<T>(static_cast<uint64_t>(hi)<<32 | lo);
}

BufferItem::BufferItem() :
    mGraphicBuffer(nullptr),
BufferItem::BufferItem()
      : mGraphicBuffer(nullptr),
        mFence(nullptr),
        mCrop(Rect::INVALID_RECT),
        mTransform(0),
@@ -56,8 +56,7 @@ BufferItem::BufferItem() :
        mAutoRefresh(false),
        mQueuedBuffer(true),
        mIsStale(false),
    mApi(0) {
}
        mApi(0) {}

BufferItem::~BufferItem() {}

@@ -76,6 +75,11 @@ size_t BufferItem::getPodSize() const {
    addAligned(size, high32(mTimestamp));
    addAligned(size, mIsAutoTimestamp);
    addAligned(size, mDataSpace);
#if COM_ANDROID_GRAPHICS_LIBUI_FLAGS_APPLY_PICTURE_PROFILES
    addAligned(size, mPictureProfileHandle.has_value());
    addAligned(size, low32(PictureProfileHandle::NONE.getId()));
    addAligned(size, high32(PictureProfileHandle::NONE.getId()));
#endif // COM_ANDROID_GRAPHICS_LIBUI_FLAGS_APPLY_PICTURE_PROFILES
    addAligned(size, low32(mFrameNumber));
    addAligned(size, high32(mFrameNumber));
    addAligned(size, mSlot);
@@ -170,6 +174,16 @@ status_t BufferItem::flatten(
    writeAligned(buffer, size, high32(mTimestamp));
    writeAligned(buffer, size, mIsAutoTimestamp);
    writeAligned(buffer, size, mDataSpace);
#if COM_ANDROID_GRAPHICS_LIBUI_FLAGS_APPLY_PICTURE_PROFILES
    writeAligned(buffer, size, mPictureProfileHandle.has_value());
    if (mPictureProfileHandle.has_value()) {
        writeAligned(buffer, size, low32(mPictureProfileHandle->getId()));
        writeAligned(buffer, size, high32(mPictureProfileHandle->getId()));
    } else {
        writeAligned(buffer, size, low32(PictureProfileHandle::NONE.getId()));
        writeAligned(buffer, size, high32(PictureProfileHandle::NONE.getId()));
    }
#endif // COM_ANDROID_GRAPHICS_LIBUI_FLAGS_APPLY_PICTURE_PROFILES
    writeAligned(buffer, size, low32(mFrameNumber));
    writeAligned(buffer, size, high32(mFrameNumber));
    writeAligned(buffer, size, mSlot);
@@ -231,6 +245,7 @@ status_t BufferItem::unflatten(

    uint32_t timestampLo = 0, timestampHi = 0;
    uint32_t frameNumberLo = 0, frameNumberHi = 0;
    int32_t pictureProfileIdLo = 0, pictureProfileIdHi = 0;

    readAligned(buffer, size, mCrop);
    readAligned(buffer, size, mTransform);
@@ -240,6 +255,16 @@ status_t BufferItem::unflatten(
    mTimestamp = to64<int64_t>(timestampLo, timestampHi);
    readAligned(buffer, size, mIsAutoTimestamp);
    readAligned(buffer, size, mDataSpace);
#if COM_ANDROID_GRAPHICS_LIBUI_FLAGS_APPLY_PICTURE_PROFILES
    bool hasPictureProfileHandle;
    readAligned(buffer, size, hasPictureProfileHandle);
    readAligned(buffer, size, pictureProfileIdLo);
    readAligned(buffer, size, pictureProfileIdHi);
    mPictureProfileHandle = hasPictureProfileHandle
            ? std::optional(PictureProfileHandle(
                      to64<PictureProfileId>(pictureProfileIdLo, pictureProfileIdHi)))
            : std::nullopt;
#endif // COM_ANDROID_GRAPHICS_LIBUI_FLAGS_APPLY_PICTURE_PROFILES
    readAligned(buffer, size, frameNumberLo);
    readAligned(buffer, size, frameNumberHi);
    mFrameNumber = to64<uint64_t>(frameNumberLo, frameNumberHi);
+3 −0
Original line number Diff line number Diff line
@@ -938,6 +938,8 @@ status_t BufferQueueProducer::queueBuffer(int slot,
            &getFrameTimestamps);
    const Region& surfaceDamage = input.getSurfaceDamage();
    const HdrMetadata& hdrMetadata = input.getHdrMetadata();
    const std::optional<PictureProfileHandle>& pictureProfileHandle =
            input.getPictureProfileHandle();

    if (acquireFence == nullptr) {
        BQ_LOGE("queueBuffer: fence is NULL");
@@ -1044,6 +1046,7 @@ status_t BufferQueueProducer::queueBuffer(int slot,
        item.mIsAutoTimestamp = isAutoTimestamp;
        item.mDataSpace = dataSpace;
        item.mHdrMetadata = hdrMetadata;
        item.mPictureProfileHandle = pictureProfileHandle;
        item.mFrameNumber = currentFrameNumber;
        item.mSlot = slot;
        item.mFence = acquireFence;
+25 −12
Original line number Diff line number Diff line
@@ -20,21 +20,19 @@
namespace android {

constexpr size_t IGraphicBufferProducer::QueueBufferInput::minFlattenedSize() {
    return sizeof(timestamp) +
            sizeof(isAutoTimestamp) +
            sizeof(dataSpace) +
            sizeof(crop) +
            sizeof(scalingMode) +
            sizeof(transform) +
            sizeof(stickyTransform) +
            sizeof(getFrameTimestamps) +
            sizeof(slot);
    return sizeof(timestamp) + sizeof(isAutoTimestamp) + sizeof(dataSpace) + sizeof(crop) +
            sizeof(scalingMode) + sizeof(transform) + sizeof(stickyTransform) +
            sizeof(getFrameTimestamps) + sizeof(slot) +
#if COM_ANDROID_GRAPHICS_LIBUI_FLAGS_APPLY_PICTURE_PROFILES
            sizeof(decltype(pictureProfileHandle.has_value())) +
            sizeof(decltype(pictureProfileHandle.getId()));
#else
            0;
#endif // COM_ANDROID_GRAPHICS_LIBUI_FLAGS_APPLY_PICTURE_PROFILES
}

size_t IGraphicBufferProducer::QueueBufferInput::getFlattenedSize() const {
    return minFlattenedSize() +
            fence->getFlattenedSize() +
            surfaceDamage.getFlattenedSize() +
    return minFlattenedSize() + fence->getFlattenedSize() + surfaceDamage.getFlattenedSize() +
            hdrMetadata.getFlattenedSize();
}

@@ -57,6 +55,12 @@ status_t IGraphicBufferProducer::QueueBufferInput::flatten(
    FlattenableUtils::write(buffer, size, transform);
    FlattenableUtils::write(buffer, size, stickyTransform);
    FlattenableUtils::write(buffer, size, getFrameTimestamps);
#if COM_ANDROID_GRAPHICS_LIBUI_FLAGS_APPLY_PICTURE_PROFILES
    FlattenableUtils::write(buffer, size, pictureProfileHandle.has_value());
    FlattenableUtils::write(buffer, size,
                            pictureProfileHandle.has_value() ? pictureProfileHandle->getId()
                                                             : PictureProfileHandle::NONE.getId());
#endif // COM_ANDROID_GRAPHICS_LIBUI_FLAGS_APPLY_PICTURE_PROFILES

    status_t result = fence->flatten(buffer, size, fds, count);
    if (result != NO_ERROR) {
@@ -91,6 +95,15 @@ status_t IGraphicBufferProducer::QueueBufferInput::unflatten(
    FlattenableUtils::read(buffer, size, transform);
    FlattenableUtils::read(buffer, size, stickyTransform);
    FlattenableUtils::read(buffer, size, getFrameTimestamps);
#if COM_ANDROID_GRAPHICS_LIBUI_FLAGS_APPLY_PICTURE_PROFILES
    bool hasPictureProfileHandle;
    FlattenableUtils::read(buffer, size, hasPictureProfileHandle);
    PictureProfileId pictureProfileId;
    FlattenableUtils::read(buffer, size, pictureProfileId);
    pictureProfileHandle = hasPictureProfileHandle
            ? std::optional(PictureProfileHandle(pictureProfileId))
            : std::nullopt;
#endif // COM_ANDROID_GRAPHICS_LIBUI_FLAGS_APPLY_PICTURE_PROFILES

    fence = new Fence();
    status_t result = fence->unflatten(buffer, size, fds, count);
+7 −2
Original line number Diff line number Diff line
@@ -17,7 +17,9 @@
#ifndef ANDROID_GUI_BLAST_BUFFER_QUEUE_H
#define ANDROID_GUI_BLAST_BUFFER_QUEUE_H

#include <com_android_graphics_libgui_flags.h>
#include <optional>
#include <queue>

#include <gui/BufferItem.h>
#include <gui/BufferItemConsumer.h>
#include <gui/IGraphicBufferConsumer.h>
@@ -29,7 +31,6 @@
#include <utils/RefBase.h>

#include <system/window.h>
#include <queue>

#include <com_android_graphics_libgui_flags.h>

@@ -222,6 +223,10 @@ private:
    ui::Size mRequestedSize GUARDED_BY(mMutex);
    int32_t mFormat GUARDED_BY(mMutex);

    // Keep a copy of the current picture profile handle, so it can be moved to a new
    // SurfaceControl when BBQ migrates via ::update.
    std::optional<PictureProfileHandle> mPictureProfileHandle;

    struct BufferInfo {
        bool hasBuffer = false;
        uint32_t width;
Loading