Skip to content

Commit b3131e4

Browse files
Brian3031Android (Google) Code Review
authored andcommitted
Merge "Allow apps to associate a change in picture profiles alongside a buffer" into main
2 parents 1a824fd + 628cff4 commit b3131e4

8 files changed

Lines changed: 173 additions & 35 deletions

libs/gui/BLASTBufferQueue.cpp

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -286,18 +286,23 @@ void BLASTBufferQueue::update(const sp<SurfaceControl>& surface, uint32_t width,
286286
if (surfaceControlChanged && mSurfaceControl != nullptr) {
287287
BQA_LOGD("Updating SurfaceControl without recreating BBQ");
288288
}
289-
bool applyTransaction = false;
290289

291290
// Always update the native object even though they might have the same layer handle, so we can
292291
// get the updated transform hint from WM.
293292
mSurfaceControl = surface;
294293
SurfaceComposerClient::Transaction t;
294+
bool applyTransaction = false;
295295
if (surfaceControlChanged) {
296296
#if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(BUFFER_RELEASE_CHANNEL)
297297
updateBufferReleaseProducer();
298298
#endif
299299
t.setFlags(mSurfaceControl, layer_state_t::eEnableBackpressure,
300300
layer_state_t::eEnableBackpressure);
301+
// Migrate the picture profile handle to the new surface control.
302+
if (com_android_graphics_libgui_flags_apply_picture_profiles() &&
303+
mPictureProfileHandle.has_value()) {
304+
t.setPictureProfileHandle(mSurfaceControl, *mPictureProfileHandle);
305+
}
301306
applyTransaction = true;
302307
}
303308
mTransformHint = mSurfaceControl->getTransformHint();
@@ -679,6 +684,17 @@ status_t BLASTBufferQueue::acquireNextBufferLocked(
679684
if (!bufferItem.mIsAutoTimestamp) {
680685
t->setDesiredPresentTime(bufferItem.mTimestamp);
681686
}
687+
if (com_android_graphics_libgui_flags_apply_picture_profiles() &&
688+
bufferItem.mPictureProfileHandle.has_value()) {
689+
t->setPictureProfileHandle(mSurfaceControl, *bufferItem.mPictureProfileHandle);
690+
// The current picture profile must be maintained in case the BBQ gets its
691+
// SurfaceControl switched out.
692+
mPictureProfileHandle = bufferItem.mPictureProfileHandle;
693+
// Clear out the picture profile if the requestor has asked for it to be cleared
694+
if (mPictureProfileHandle == PictureProfileHandle::NONE) {
695+
mPictureProfileHandle = std::nullopt;
696+
}
697+
}
682698

683699
// Drop stale frame timeline infos
684700
while (!mPendingFrameTimelines.empty() &&

libs/gui/BufferItem.cpp

Lines changed: 45 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -38,26 +38,25 @@ static inline constexpr T to64(const uint32_t lo, const uint32_t hi) {
3838
return static_cast<T>(static_cast<uint64_t>(hi)<<32 | lo);
3939
}
4040

41-
BufferItem::BufferItem() :
42-
mGraphicBuffer(nullptr),
43-
mFence(nullptr),
44-
mCrop(Rect::INVALID_RECT),
45-
mTransform(0),
46-
mScalingMode(NATIVE_WINDOW_SCALING_MODE_FREEZE),
47-
mTimestamp(0),
48-
mIsAutoTimestamp(false),
49-
mDataSpace(HAL_DATASPACE_UNKNOWN),
50-
mFrameNumber(0),
51-
mSlot(INVALID_BUFFER_SLOT),
52-
mIsDroppable(false),
53-
mAcquireCalled(false),
54-
mTransformToDisplayInverse(false),
55-
mSurfaceDamage(),
56-
mAutoRefresh(false),
57-
mQueuedBuffer(true),
58-
mIsStale(false),
59-
mApi(0) {
60-
}
41+
BufferItem::BufferItem()
42+
: mGraphicBuffer(nullptr),
43+
mFence(nullptr),
44+
mCrop(Rect::INVALID_RECT),
45+
mTransform(0),
46+
mScalingMode(NATIVE_WINDOW_SCALING_MODE_FREEZE),
47+
mTimestamp(0),
48+
mIsAutoTimestamp(false),
49+
mDataSpace(HAL_DATASPACE_UNKNOWN),
50+
mFrameNumber(0),
51+
mSlot(INVALID_BUFFER_SLOT),
52+
mIsDroppable(false),
53+
mAcquireCalled(false),
54+
mTransformToDisplayInverse(false),
55+
mSurfaceDamage(),
56+
mAutoRefresh(false),
57+
mQueuedBuffer(true),
58+
mIsStale(false),
59+
mApi(0) {}
6160

6261
BufferItem::~BufferItem() {}
6362

@@ -76,6 +75,11 @@ size_t BufferItem::getPodSize() const {
7675
addAligned(size, high32(mTimestamp));
7776
addAligned(size, mIsAutoTimestamp);
7877
addAligned(size, mDataSpace);
78+
#if COM_ANDROID_GRAPHICS_LIBUI_FLAGS_APPLY_PICTURE_PROFILES
79+
addAligned(size, mPictureProfileHandle.has_value());
80+
addAligned(size, low32(PictureProfileHandle::NONE.getId()));
81+
addAligned(size, high32(PictureProfileHandle::NONE.getId()));
82+
#endif // COM_ANDROID_GRAPHICS_LIBUI_FLAGS_APPLY_PICTURE_PROFILES
7983
addAligned(size, low32(mFrameNumber));
8084
addAligned(size, high32(mFrameNumber));
8185
addAligned(size, mSlot);
@@ -170,6 +174,16 @@ status_t BufferItem::flatten(
170174
writeAligned(buffer, size, high32(mTimestamp));
171175
writeAligned(buffer, size, mIsAutoTimestamp);
172176
writeAligned(buffer, size, mDataSpace);
177+
#if COM_ANDROID_GRAPHICS_LIBUI_FLAGS_APPLY_PICTURE_PROFILES
178+
writeAligned(buffer, size, mPictureProfileHandle.has_value());
179+
if (mPictureProfileHandle.has_value()) {
180+
writeAligned(buffer, size, low32(mPictureProfileHandle->getId()));
181+
writeAligned(buffer, size, high32(mPictureProfileHandle->getId()));
182+
} else {
183+
writeAligned(buffer, size, low32(PictureProfileHandle::NONE.getId()));
184+
writeAligned(buffer, size, high32(PictureProfileHandle::NONE.getId()));
185+
}
186+
#endif // COM_ANDROID_GRAPHICS_LIBUI_FLAGS_APPLY_PICTURE_PROFILES
173187
writeAligned(buffer, size, low32(mFrameNumber));
174188
writeAligned(buffer, size, high32(mFrameNumber));
175189
writeAligned(buffer, size, mSlot);
@@ -231,6 +245,7 @@ status_t BufferItem::unflatten(
231245

232246
uint32_t timestampLo = 0, timestampHi = 0;
233247
uint32_t frameNumberLo = 0, frameNumberHi = 0;
248+
int32_t pictureProfileIdLo = 0, pictureProfileIdHi = 0;
234249

235250
readAligned(buffer, size, mCrop);
236251
readAligned(buffer, size, mTransform);
@@ -240,6 +255,16 @@ status_t BufferItem::unflatten(
240255
mTimestamp = to64<int64_t>(timestampLo, timestampHi);
241256
readAligned(buffer, size, mIsAutoTimestamp);
242257
readAligned(buffer, size, mDataSpace);
258+
#if COM_ANDROID_GRAPHICS_LIBUI_FLAGS_APPLY_PICTURE_PROFILES
259+
bool hasPictureProfileHandle;
260+
readAligned(buffer, size, hasPictureProfileHandle);
261+
readAligned(buffer, size, pictureProfileIdLo);
262+
readAligned(buffer, size, pictureProfileIdHi);
263+
mPictureProfileHandle = hasPictureProfileHandle
264+
? std::optional(PictureProfileHandle(
265+
to64<PictureProfileId>(pictureProfileIdLo, pictureProfileIdHi)))
266+
: std::nullopt;
267+
#endif // COM_ANDROID_GRAPHICS_LIBUI_FLAGS_APPLY_PICTURE_PROFILES
243268
readAligned(buffer, size, frameNumberLo);
244269
readAligned(buffer, size, frameNumberHi);
245270
mFrameNumber = to64<uint64_t>(frameNumberLo, frameNumberHi);

libs/gui/BufferQueueProducer.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -938,6 +938,8 @@ status_t BufferQueueProducer::queueBuffer(int slot,
938938
&getFrameTimestamps);
939939
const Region& surfaceDamage = input.getSurfaceDamage();
940940
const HdrMetadata& hdrMetadata = input.getHdrMetadata();
941+
const std::optional<PictureProfileHandle>& pictureProfileHandle =
942+
input.getPictureProfileHandle();
941943

942944
if (acquireFence == nullptr) {
943945
BQ_LOGE("queueBuffer: fence is NULL");
@@ -1044,6 +1046,7 @@ status_t BufferQueueProducer::queueBuffer(int slot,
10441046
item.mIsAutoTimestamp = isAutoTimestamp;
10451047
item.mDataSpace = dataSpace;
10461048
item.mHdrMetadata = hdrMetadata;
1049+
item.mPictureProfileHandle = pictureProfileHandle;
10471050
item.mFrameNumber = currentFrameNumber;
10481051
item.mSlot = slot;
10491052
item.mFence = acquireFence;

libs/gui/IGraphicBufferProducerFlattenables.cpp

Lines changed: 25 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -20,21 +20,19 @@
2020
namespace android {
2121

2222
constexpr size_t IGraphicBufferProducer::QueueBufferInput::minFlattenedSize() {
23-
return sizeof(timestamp) +
24-
sizeof(isAutoTimestamp) +
25-
sizeof(dataSpace) +
26-
sizeof(crop) +
27-
sizeof(scalingMode) +
28-
sizeof(transform) +
29-
sizeof(stickyTransform) +
30-
sizeof(getFrameTimestamps) +
31-
sizeof(slot);
23+
return sizeof(timestamp) + sizeof(isAutoTimestamp) + sizeof(dataSpace) + sizeof(crop) +
24+
sizeof(scalingMode) + sizeof(transform) + sizeof(stickyTransform) +
25+
sizeof(getFrameTimestamps) + sizeof(slot) +
26+
#if COM_ANDROID_GRAPHICS_LIBUI_FLAGS_APPLY_PICTURE_PROFILES
27+
sizeof(decltype(pictureProfileHandle.has_value())) +
28+
sizeof(decltype(pictureProfileHandle.getId()));
29+
#else
30+
0;
31+
#endif // COM_ANDROID_GRAPHICS_LIBUI_FLAGS_APPLY_PICTURE_PROFILES
3232
}
3333

3434
size_t IGraphicBufferProducer::QueueBufferInput::getFlattenedSize() const {
35-
return minFlattenedSize() +
36-
fence->getFlattenedSize() +
37-
surfaceDamage.getFlattenedSize() +
35+
return minFlattenedSize() + fence->getFlattenedSize() + surfaceDamage.getFlattenedSize() +
3836
hdrMetadata.getFlattenedSize();
3937
}
4038

@@ -57,6 +55,12 @@ status_t IGraphicBufferProducer::QueueBufferInput::flatten(
5755
FlattenableUtils::write(buffer, size, transform);
5856
FlattenableUtils::write(buffer, size, stickyTransform);
5957
FlattenableUtils::write(buffer, size, getFrameTimestamps);
58+
#if COM_ANDROID_GRAPHICS_LIBUI_FLAGS_APPLY_PICTURE_PROFILES
59+
FlattenableUtils::write(buffer, size, pictureProfileHandle.has_value());
60+
FlattenableUtils::write(buffer, size,
61+
pictureProfileHandle.has_value() ? pictureProfileHandle->getId()
62+
: PictureProfileHandle::NONE.getId());
63+
#endif // COM_ANDROID_GRAPHICS_LIBUI_FLAGS_APPLY_PICTURE_PROFILES
6064

6165
status_t result = fence->flatten(buffer, size, fds, count);
6266
if (result != NO_ERROR) {
@@ -91,6 +95,15 @@ status_t IGraphicBufferProducer::QueueBufferInput::unflatten(
9195
FlattenableUtils::read(buffer, size, transform);
9296
FlattenableUtils::read(buffer, size, stickyTransform);
9397
FlattenableUtils::read(buffer, size, getFrameTimestamps);
98+
#if COM_ANDROID_GRAPHICS_LIBUI_FLAGS_APPLY_PICTURE_PROFILES
99+
bool hasPictureProfileHandle;
100+
FlattenableUtils::read(buffer, size, hasPictureProfileHandle);
101+
PictureProfileId pictureProfileId;
102+
FlattenableUtils::read(buffer, size, pictureProfileId);
103+
pictureProfileHandle = hasPictureProfileHandle
104+
? std::optional(PictureProfileHandle(pictureProfileId))
105+
: std::nullopt;
106+
#endif // COM_ANDROID_GRAPHICS_LIBUI_FLAGS_APPLY_PICTURE_PROFILES
94107

95108
fence = new Fence();
96109
status_t result = fence->unflatten(buffer, size, fds, count);

libs/gui/include/gui/BLASTBufferQueue.h

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,9 @@
1717
#ifndef ANDROID_GUI_BLAST_BUFFER_QUEUE_H
1818
#define ANDROID_GUI_BLAST_BUFFER_QUEUE_H
1919

20-
#include <com_android_graphics_libgui_flags.h>
20+
#include <optional>
21+
#include <queue>
22+
2123
#include <gui/BufferItem.h>
2224
#include <gui/BufferItemConsumer.h>
2325
#include <gui/IGraphicBufferConsumer.h>
@@ -29,7 +31,6 @@
2931
#include <utils/RefBase.h>
3032

3133
#include <system/window.h>
32-
#include <queue>
3334

3435
#include <com_android_graphics_libgui_flags.h>
3536

@@ -222,6 +223,10 @@ class BLASTBufferQueue : public ConsumerBase::FrameAvailableListener {
222223
ui::Size mRequestedSize GUARDED_BY(mMutex);
223224
int32_t mFormat GUARDED_BY(mMutex);
224225

226+
// Keep a copy of the current picture profile handle, so it can be moved to a new
227+
// SurfaceControl when BBQ migrates via ::update.
228+
std::optional<PictureProfileHandle> mPictureProfileHandle;
229+
225230
struct BufferInfo {
226231
bool hasBuffer = false;
227232
uint32_t width;

libs/gui/include/gui/BufferItem.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,12 @@
1717
#ifndef ANDROID_GUI_BUFFERITEM_H
1818
#define ANDROID_GUI_BUFFERITEM_H
1919

20+
#include <optional>
21+
2022
#include <gui/HdrMetadata.h>
2123

2224
#include <ui/FenceTime.h>
25+
#include <ui/PictureProfileHandle.h>
2326
#include <ui/Rect.h>
2427
#include <ui/Region.h>
2528

@@ -91,6 +94,10 @@ class BufferItem : public Flattenable<BufferItem> {
9194
// mHdrMetadata is the HDR metadata associated with this buffer slot.
9295
HdrMetadata mHdrMetadata;
9396

97+
// mPictureProfileHandle is a handle that points to a set of parameters that configure picture
98+
// processing hardware to enhance the quality of buffer contents.
99+
std::optional<PictureProfileHandle> mPictureProfileHandle;
100+
94101
// mFrameNumber is the number of the queued frame for this slot.
95102
uint64_t mFrameNumber;
96103

libs/gui/include/gui/IGraphicBufferProducer.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919

2020
#include <stdint.h>
2121
#include <sys/types.h>
22+
#include <optional>
2223

2324
#include <utils/Errors.h>
2425
#include <utils/RefBase.h>
@@ -28,6 +29,7 @@
2829
#include <ui/BufferQueueDefs.h>
2930
#include <ui/Fence.h>
3031
#include <ui/GraphicBuffer.h>
32+
#include <ui/PictureProfileHandle.h>
3133
#include <ui/Rect.h>
3234
#include <ui/Region.h>
3335

@@ -365,6 +367,14 @@ class IGraphicBufferProducer : public RefBase {
365367
const HdrMetadata& getHdrMetadata() const { return hdrMetadata; }
366368
void setHdrMetadata(const HdrMetadata& metadata) { hdrMetadata = metadata; }
367369

370+
const std::optional<PictureProfileHandle>& getPictureProfileHandle() const {
371+
return pictureProfileHandle;
372+
}
373+
void setPictureProfileHandle(const PictureProfileHandle& profile) {
374+
pictureProfileHandle = profile;
375+
}
376+
void clearPictureProfileHandle() { pictureProfileHandle = std::nullopt; }
377+
368378
int64_t timestamp{0};
369379
int isAutoTimestamp{0};
370380
android_dataspace dataSpace{HAL_DATASPACE_UNKNOWN};
@@ -377,6 +387,7 @@ class IGraphicBufferProducer : public RefBase {
377387
bool getFrameTimestamps{false};
378388
int slot{-1};
379389
HdrMetadata hdrMetadata;
390+
std::optional<PictureProfileHandle> pictureProfileHandle;
380391
};
381392

382393
struct QueueBufferOutput : public Flattenable<QueueBufferOutput> {

libs/gui/tests/BufferQueue_test.cpp

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
#include <gui/Surface.h>
2828

2929
#include <ui/GraphicBuffer.h>
30+
#include <ui/PictureProfileHandle.h>
3031

3132
#include <android-base/properties.h>
3233

@@ -1569,4 +1570,61 @@ TEST_F(BufferQueueTest, TestAdditionalOptions) {
15691570
EXPECT_EQ(ADATASPACE_UNKNOWN, dataSpace);
15701571
}
15711572

1573+
TEST_F(BufferQueueTest, PassesThroughPictureProfileHandle) {
1574+
createBufferQueue();
1575+
sp<MockConsumer> mc(new MockConsumer);
1576+
mConsumer->consumerConnect(mc, false);
1577+
1578+
IGraphicBufferProducer::QueueBufferOutput qbo;
1579+
mProducer->connect(new StubProducerListener, NATIVE_WINDOW_API_CPU, false, &qbo);
1580+
mProducer->setMaxDequeuedBufferCount(2);
1581+
mConsumer->setMaxAcquiredBufferCount(2);
1582+
1583+
// First try to pass a valid picture profile handle
1584+
{
1585+
int slot;
1586+
sp<Fence> fence;
1587+
sp<GraphicBuffer> buf;
1588+
IGraphicBufferProducer::QueueBufferInput qbi(0, false, HAL_DATASPACE_UNKNOWN,
1589+
Rect(0, 0, 1, 1),
1590+
NATIVE_WINDOW_SCALING_MODE_FREEZE, 0,
1591+
Fence::NO_FENCE);
1592+
qbi.setPictureProfileHandle(PictureProfileHandle(1));
1593+
1594+
EXPECT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION,
1595+
mProducer->dequeueBuffer(&slot, &fence, 1, 1, 0, GRALLOC_USAGE_SW_READ_OFTEN,
1596+
nullptr, nullptr));
1597+
EXPECT_EQ(OK, mProducer->requestBuffer(slot, &buf));
1598+
EXPECT_EQ(OK, mProducer->queueBuffer(slot, qbi, &qbo));
1599+
1600+
BufferItem item;
1601+
EXPECT_EQ(OK, mConsumer->acquireBuffer(&item, 0));
1602+
1603+
ASSERT_TRUE(item.mPictureProfileHandle.has_value());
1604+
ASSERT_EQ(item.mPictureProfileHandle, PictureProfileHandle(1));
1605+
}
1606+
1607+
// Then validate that the picture profile handle isn't sticky and is reset for the next buffer
1608+
{
1609+
int slot;
1610+
sp<Fence> fence;
1611+
sp<GraphicBuffer> buf;
1612+
IGraphicBufferProducer::QueueBufferInput qbi(0, false, HAL_DATASPACE_UNKNOWN,
1613+
Rect(0, 0, 1, 1),
1614+
NATIVE_WINDOW_SCALING_MODE_FREEZE, 0,
1615+
Fence::NO_FENCE);
1616+
1617+
EXPECT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION,
1618+
mProducer->dequeueBuffer(&slot, &fence, 1, 1, 0, GRALLOC_USAGE_SW_READ_OFTEN,
1619+
nullptr, nullptr));
1620+
EXPECT_EQ(OK, mProducer->requestBuffer(slot, &buf));
1621+
EXPECT_EQ(OK, mProducer->queueBuffer(slot, qbi, &qbo));
1622+
1623+
BufferItem item;
1624+
EXPECT_EQ(OK, mConsumer->acquireBuffer(&item, 0));
1625+
1626+
ASSERT_FALSE(item.mPictureProfileHandle.has_value());
1627+
}
1628+
}
1629+
15721630
} // namespace android

0 commit comments

Comments
 (0)