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
diff --git a/libs/gui/IGraphicBufferProducerFlattenables.cpp b/libs/gui/IGraphicBufferProducerFlattenables.cpp
index c8b9b67..4e92a39 100644
--- a/libs/gui/IGraphicBufferProducerFlattenables.cpp
+++ b/libs/gui/IGraphicBufferProducerFlattenables.cpp
@@ -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 @@
     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 @@
     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);