Merge changes I20e4aa1a,I00370f05

* changes:
  SF: Introduce LayerCompositionState
  SF: Introduce OutputLayerCompositionState
diff --git a/cmds/dumpstate/dumpstate.cpp b/cmds/dumpstate/dumpstate.cpp
index db8848a..61745b5 100644
--- a/cmds/dumpstate/dumpstate.cpp
+++ b/cmds/dumpstate/dumpstate.cpp
@@ -1464,6 +1464,12 @@
     // Run iotop as root to show top 100 IO threads
     RunCommand("IOTOP", {"iotop", "-n", "1", "-m", "100"});
 
+    // Gather shared memory buffer info if the product implements it
+    struct stat st;
+    if (!stat("/product/bin/dmabuf_dump", &st)) {
+        RunCommand("Dmabuf dump", {"/product/bin/dmabuf_dump"});
+    }
+
     if (!DropRootUser()) {
         return false;
     }
diff --git a/libs/gui/SurfaceComposerClient.cpp b/libs/gui/SurfaceComposerClient.cpp
index 46b9128..bf2a03d 100644
--- a/libs/gui/SurfaceComposerClient.cpp
+++ b/libs/gui/SurfaceComposerClient.cpp
@@ -383,6 +383,7 @@
     other.mListenerCallbacks.clear();
 
     mInputWindowCommands.merge(other.mInputWindowCommands);
+    other.mInputWindowCommands.clear();
 
     return *this;
 }
diff --git a/libs/nativewindow/AHardwareBuffer.cpp b/libs/nativewindow/AHardwareBuffer.cpp
index 8ef4896..994e953 100644
--- a/libs/nativewindow/AHardwareBuffer.cpp
+++ b/libs/nativewindow/AHardwareBuffer.cpp
@@ -122,6 +122,54 @@
     return gbuffer->lockAsync(usage, usage, bounds, outVirtualAddress, fence);
 }
 
+int AHardwareBuffer_lockPlanes(AHardwareBuffer* buffer, uint64_t usage,
+        int32_t fence, const ARect* rect, AHardwareBuffer_Planes* outPlanes) {
+    if (!buffer || !outPlanes) return BAD_VALUE;
+
+    if (usage & ~(AHARDWAREBUFFER_USAGE_CPU_READ_MASK |
+                  AHARDWAREBUFFER_USAGE_CPU_WRITE_MASK)) {
+        ALOGE("Invalid usage flags passed to AHardwareBuffer_lock; only "
+                " AHARDWAREBUFFER_USAGE_CPU_* flags are allowed");
+        return BAD_VALUE;
+    }
+
+    usage = AHardwareBuffer_convertToGrallocUsageBits(usage);
+    GraphicBuffer* gBuffer = AHardwareBuffer_to_GraphicBuffer(buffer);
+    Rect bounds;
+    if (!rect) {
+        bounds.set(Rect(gBuffer->getWidth(), gBuffer->getHeight()));
+    } else {
+        bounds.set(Rect(rect->left, rect->top, rect->right, rect->bottom));
+    }
+    int format = AHardwareBuffer_convertFromPixelFormat(uint32_t(gBuffer->getPixelFormat()));
+    memset(outPlanes->planes, 0, sizeof(outPlanes->planes));
+    if (AHardwareBuffer_formatIsYuv(format)) {
+      android_ycbcr yuvData;
+      int result = gBuffer->lockAsyncYCbCr(usage, bounds, &yuvData, fence);
+      if (result == 0) {
+        outPlanes->planeCount = 3;
+        outPlanes->planes[0].data = yuvData.y;
+        outPlanes->planes[0].pixelStride = 1;
+        outPlanes->planes[0].rowStride = yuvData.ystride;
+        outPlanes->planes[1].data = yuvData.cb;
+        outPlanes->planes[1].pixelStride = yuvData.chroma_step;
+        outPlanes->planes[1].rowStride = yuvData.cstride;
+        outPlanes->planes[2].data = yuvData.cr;
+        outPlanes->planes[2].pixelStride = yuvData.chroma_step;
+        outPlanes->planes[2].rowStride = yuvData.cstride;
+      } else {
+        outPlanes->planeCount = 0;
+      }
+      return result;
+    } else {
+      const uint32_t pixelStride = AHardwareBuffer_bytesPerPixel(format);
+      outPlanes->planeCount = 1;
+      outPlanes->planes[0].pixelStride = pixelStride;
+      outPlanes->planes[0].rowStride = gBuffer->getStride() * pixelStride;
+      return gBuffer->lockAsync(usage, usage, bounds, &outPlanes->planes[0].data, fence);
+    }
+}
+
 int AHardwareBuffer_unlock(AHardwareBuffer* buffer, int32_t* fence) {
     if (!buffer) return BAD_VALUE;
 
@@ -375,6 +423,19 @@
             ALOGE_IF(log, "AHARDWAREBUFFER_FORMAT_BLOB cannot be encoded as video");
             return false;
         }
+    } else if (AHardwareBuffer_formatIsYuv(desc->format)) {
+        if (desc->layers != 1) {
+            ALOGE_IF(log, "Layers must be 1 for YUV formats.");
+            return false;
+        }
+        const uint64_t yuvInvalidGpuMask =
+            AHARDWAREBUFFER_USAGE_GPU_MIPMAP_COMPLETE |
+            AHARDWAREBUFFER_USAGE_GPU_CUBE_MAP;
+        if (desc->usage & yuvInvalidGpuMask) {
+            ALOGE_IF(log, "Invalid usage flags specified for YUV format; "
+                    "mip-mapping and cube-mapping are not allowed.");
+            return false;
+        }
     } else {
         if (desc->usage & AHARDWAREBUFFER_USAGE_SENSOR_DIRECT_DATA) {
             ALOGE_IF(log, "AHARDWAREBUFFER_USAGE_SENSOR_DIRECT_DATA requires AHARDWAREBUFFER_FORMAT_BLOB");
@@ -474,6 +535,7 @@
         case AHARDWAREBUFFER_FORMAT_D32_FLOAT:
         case AHARDWAREBUFFER_FORMAT_D32_FLOAT_S8_UINT:
         case AHARDWAREBUFFER_FORMAT_S8_UINT:
+        case AHARDWAREBUFFER_FORMAT_Y8Cb8Cr8_420:
             // VNDK formats only -- unfortunately we can't differentiate from where we're called
         case AHARDWAREBUFFER_FORMAT_B8G8R8A8_UNORM:
         case AHARDWAREBUFFER_FORMAT_YV12:
@@ -484,7 +546,6 @@
         case AHARDWAREBUFFER_FORMAT_RAW12:
         case AHARDWAREBUFFER_FORMAT_RAW_OPAQUE:
         case AHARDWAREBUFFER_FORMAT_IMPLEMENTATION_DEFINED:
-        case AHARDWAREBUFFER_FORMAT_Y8Cb8Cr8_420:
         case AHARDWAREBUFFER_FORMAT_YCbCr_422_SP:
         case AHARDWAREBUFFER_FORMAT_YCrCb_420_SP:
         case AHARDWAREBUFFER_FORMAT_YCbCr_422_I:
@@ -495,6 +556,40 @@
     }
 }
 
+bool AHardwareBuffer_formatIsYuv(uint32_t format) {
+    switch (format) {
+        case AHARDWAREBUFFER_FORMAT_Y8Cb8Cr8_420:
+        case AHARDWAREBUFFER_FORMAT_YV12:
+        case AHARDWAREBUFFER_FORMAT_Y8:
+        case AHARDWAREBUFFER_FORMAT_Y16:
+        case AHARDWAREBUFFER_FORMAT_YCbCr_422_SP:
+        case AHARDWAREBUFFER_FORMAT_YCrCb_420_SP:
+        case AHARDWAREBUFFER_FORMAT_YCbCr_422_I:
+            return true;
+        default:
+            return false;
+    }
+}
+
+uint32_t AHardwareBuffer_bytesPerPixel(uint32_t format) {
+  switch (format) {
+      case AHARDWAREBUFFER_FORMAT_R5G6B5_UNORM:
+      case AHARDWAREBUFFER_FORMAT_D16_UNORM:
+          return 2;
+      case AHARDWAREBUFFER_FORMAT_R8G8B8_UNORM:
+      case AHARDWAREBUFFER_FORMAT_D24_UNORM:
+          return 3;
+      case AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM:
+      case AHARDWAREBUFFER_FORMAT_R8G8B8X8_UNORM:
+      case AHARDWAREBUFFER_FORMAT_D32_FLOAT:
+      case AHARDWAREBUFFER_FORMAT_R10G10B10A2_UNORM:
+      case AHARDWAREBUFFER_FORMAT_D24_UNORM_S8_UINT:
+          return 4;
+      default:
+          return 0;
+  }
+}
+
 uint32_t AHardwareBuffer_convertFromPixelFormat(uint32_t hal_format) {
     return hal_format;
 }
diff --git a/libs/nativewindow/include-private/private/android/AHardwareBufferHelpers.h b/libs/nativewindow/include-private/private/android/AHardwareBufferHelpers.h
index bf688f8..ddfd1d1 100644
--- a/libs/nativewindow/include-private/private/android/AHardwareBufferHelpers.h
+++ b/libs/nativewindow/include-private/private/android/AHardwareBufferHelpers.h
@@ -40,6 +40,12 @@
 // whether this AHardwareBuffer format is valid
 bool AHardwareBuffer_isValidPixelFormat(uint32_t ahardwarebuffer_format);
 
+// whether this is a YUV type format
+bool AHardwareBuffer_formatIsYuv(uint32_t format);
+
+// number of bytes per pixel or 0 if unknown or multi-planar
+uint32_t AHardwareBuffer_bytesPerPixel(uint32_t format);
+
 // convert AHardwareBuffer format to HAL format (note: this is a no-op)
 uint32_t AHardwareBuffer_convertFromPixelFormat(uint32_t format);
 
diff --git a/libs/nativewindow/include/android/hardware_buffer.h b/libs/nativewindow/include/android/hardware_buffer.h
index 2796c75..02c7c1b 100644
--- a/libs/nativewindow/include/android/hardware_buffer.h
+++ b/libs/nativewindow/include/android/hardware_buffer.h
@@ -150,6 +150,14 @@
      *   OpenGL ES: GL_STENCIL_INDEX8
      */
     AHARDWAREBUFFER_FORMAT_S8_UINT                  = 0x35,
+
+    /**
+     * YUV 420 888 format.
+     * Must have an even width and height. Can be accessed in OpenGL
+     * shaders through an external sampler. Does not support mip-maps
+     * cube-maps or multi-layered textures.
+     */
+    AHARDWAREBUFFER_FORMAT_Y8Cb8Cr8_420             = 0x23,
 };
 
 /**
@@ -302,6 +310,24 @@
 } AHardwareBuffer_Desc;
 
 /**
+ * Holds data for a single image plane.
+ */
+typedef struct AHardwareBuffer_Plane {
+    void*       data;        ///< Points to first byte in plane
+    uint32_t    pixelStride; ///< Distance in bytes from the color channel of one pixel to the next
+    uint32_t    rowStride;   ///< Distance in bytes from the first value of one row of the image to
+                             ///  the first value of the next row.
+} AHardwareBuffer_Plane;
+
+/**
+ * Holds all image planes that contain the pixel data.
+ */
+typedef struct AHardwareBuffer_Planes {
+    uint32_t               planeCount; ///< Number of distinct planes
+    AHardwareBuffer_Plane  planes[4];     ///< Array of image planes
+} AHardwareBuffer_Planes;
+
+/**
  * Opaque handle for a native hardware buffer.
  */
 typedef struct AHardwareBuffer AHardwareBuffer;
@@ -323,7 +349,7 @@
         AHardwareBuffer** outBuffer) __INTRODUCED_IN(26);
 /**
  * Acquire a reference on the given AHardwareBuffer object.
- * 
+ *
  * This prevents the object from being deleted until the last reference
  * is removed.
  */
@@ -396,6 +422,34 @@
         int32_t fence, const ARect* rect, void** outVirtualAddress) __INTRODUCED_IN(26);
 
 /**
+ * Lock a potentially multi-planar AHardwareBuffer for direct CPU access.
+ *
+ * This function is similar to AHardwareBuffer_lock, but can lock multi-planar
+ * formats. The locked planes are returned in the \a outPlanes argument. Note,
+ * that multi-planar should not be confused with multi-layer images, which this
+ * locking function does not support.
+ *
+ * YUV formats are always represented by three separate planes of data, one for
+ * each color plane. The order of planes in the array is guaranteed such that
+ * plane #0 is always Y, plane #1 is always U (Cb), and plane #2 is always V
+ * (Cr). All other formats are represented by a single plane.
+ *
+ * Additional information always accompanies the buffers, describing the row
+ * stride and the pixel stride for each plane.
+ *
+ * In case the buffer cannot be locked, \a outPlanes will contain zero planes.
+ *
+ * See the AHardwareBuffer_lock documentation for all other locking semantics.
+ *
+ * \return 0 on success. -EINVAL if \a buffer is NULL, the usage flags
+ * are not a combination of AHARDWAREBUFFER_USAGE_CPU_*, or the buffer
+ * has more than one layer. Error number if the lock fails for any other
+ * reason.
+ */
+int AHardwareBuffer_lockPlanes(AHardwareBuffer* buffer, uint64_t usage,
+        int32_t fence, const ARect* rect, AHardwareBuffer_Planes* outPlanes) __INTRODUCED_IN(29);
+
+/**
  * Unlock the AHardwareBuffer from direct CPU access.
  *
  * Must be called after all changes to the buffer are completed by the
diff --git a/libs/nativewindow/include/vndk/hardware_buffer.h b/libs/nativewindow/include/vndk/hardware_buffer.h
index 6c9ec34..3392d7f 100644
--- a/libs/nativewindow/include/vndk/hardware_buffer.h
+++ b/libs/nativewindow/include/vndk/hardware_buffer.h
@@ -73,8 +73,6 @@
     AHARDWAREBUFFER_FORMAT_RAW_OPAQUE               = 0x24,
     /* same as HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED */
     AHARDWAREBUFFER_FORMAT_IMPLEMENTATION_DEFINED   = 0x22,
-    /* same as HAL_PIXEL_FORMAT_YCBCR_420_888 */
-    AHARDWAREBUFFER_FORMAT_Y8Cb8Cr8_420             = 0x23,
     /* same as HAL_PIXEL_FORMAT_YCBCR_422_SP */
     AHARDWAREBUFFER_FORMAT_YCbCr_422_SP             = 0x10,
     /* same as HAL_PIXEL_FORMAT_YCRCB_420_SP */
diff --git a/libs/ui/BufferHubBuffer.cpp b/libs/ui/BufferHubBuffer.cpp
index 604665b..da91a97 100644
--- a/libs/ui/BufferHubBuffer.cpp
+++ b/libs/ui/BufferHubBuffer.cpp
@@ -78,15 +78,14 @@
     BufferHubStatus ret;
     sp<IBufferClient> client;
     BufferTraits bufferTraits;
-    IBufferHub::allocateBuffer_cb alloc_cb = [&](const auto& status, const auto& outClient,
-                                                 const auto& outTraits) {
+    IBufferHub::allocateBuffer_cb allocCb = [&](const auto& status, const auto& outClient,
+                                                const auto& outTraits) {
         ret = status;
         client = std::move(outClient);
         bufferTraits = std::move(outTraits);
     };
 
-    if (!bufferhub->allocateBuffer(desc, static_cast<uint32_t>(userMetadataSize), alloc_cb)
-                 .isOk()) {
+    if (!bufferhub->allocateBuffer(desc, static_cast<uint32_t>(userMetadataSize), allocCb).isOk()) {
         ALOGE("%s: allocateBuffer transaction failed!", __FUNCTION__);
         return;
     } else if (ret != BufferHubStatus::NO_ERROR) {
@@ -115,8 +114,8 @@
     BufferHubStatus ret;
     sp<IBufferClient> client;
     BufferTraits bufferTraits;
-    IBufferHub::importBuffer_cb import_cb = [&](const auto& status, const auto& outClient,
-                                                const auto& outTraits) {
+    IBufferHub::importBuffer_cb importCb = [&](const auto& status, const auto& outClient,
+                                               const auto& outTraits) {
         ret = status;
         client = std::move(outClient);
         bufferTraits = std::move(outTraits);
@@ -124,7 +123,7 @@
 
     // hidl_handle(native_handle_t*) simply creates a raw pointer reference withouth ownership
     // transfer.
-    if (!bufferhub->importBuffer(hidl_handle(token.get()->handle()), import_cb).isOk()) {
+    if (!bufferhub->importBuffer(hidl_handle(token.get()->handle()), importCb).isOk()) {
         ALOGE("%s: importBuffer transaction failed!", __FUNCTION__);
         return;
     } else if (ret != BufferHubStatus::NO_ERROR) {
@@ -210,9 +209,9 @@
 
     // Populate shortcuts to the atomics in metadata.
     auto metadataHeader = mMetadata.metadataHeader();
-    mBufferState = &metadataHeader->buffer_state;
-    mFenceState = &metadataHeader->fence_state;
-    mActiveClientsBitMask = &metadataHeader->active_clients_bit_mask;
+    mBufferState = &metadataHeader->bufferState;
+    mFenceState = &metadataHeader->fenceState;
+    mActiveClientsBitMask = &metadataHeader->activeClientsBitMask;
     // The C++ standard recommends (but does not require) that lock-free atomic operations are
     // also address-free, that is, suitable for communication between processes using shared
     // memory.
@@ -230,7 +229,7 @@
     mClientStateMask = clientBitMask;
 
     // TODO(b/112012161) Set up shared fences.
-    ALOGD("%s: id=%d, buffer_state=%" PRIx32 ".", __FUNCTION__, mId,
+    ALOGD("%s: id=%d, mBufferState=%" PRIx32 ".", __FUNCTION__, mId,
           mBufferState->load(std::memory_order_acquire));
     return 0;
 }
@@ -336,12 +335,12 @@
 
     hidl_handle token;
     BufferHubStatus ret;
-    IBufferClient::duplicate_cb dup_cb = [&](const auto& outToken, const auto& status) {
+    IBufferClient::duplicate_cb dupCb = [&](const auto& outToken, const auto& status) {
         token = std::move(outToken);
         ret = status;
     };
 
-    if (!mBufferClient->duplicate(dup_cb).isOk()) {
+    if (!mBufferClient->duplicate(dupCb).isOk()) {
         ALOGE("%s: duplicate transaction failed!", __FUNCTION__);
         return nullptr;
     } else if (ret != BufferHubStatus::NO_ERROR) {
diff --git a/libs/ui/include/ui/BufferHubBuffer.h b/libs/ui/include/ui/BufferHubBuffer.h
index 5c09032..5ba189c 100644
--- a/libs/ui/include/ui/BufferHubBuffer.h
+++ b/libs/ui/include/ui/BufferHubBuffer.h
@@ -57,7 +57,7 @@
 
     const BufferHubEventFd& eventFd() const { return mEventFd; }
 
-    // Returns the current value of MetadataHeader::buffer_state.
+    // Returns the current value of MetadataHeader::bufferState.
     uint32_t bufferState() const { return mBufferState->load(std::memory_order_acquire); }
 
     // A state mask which is unique to a buffer hub client among all its siblings sharing the same
diff --git a/libs/ui/include/ui/BufferHubDefs.h b/libs/ui/include/ui/BufferHubDefs.h
index 722a060..10f274f 100644
--- a/libs/ui/include/ui/BufferHubDefs.h
+++ b/libs/ui/include/ui/BufferHubDefs.h
@@ -32,7 +32,7 @@
 // Single buffer clients (up to 16) ownership signal.
 // 32-bit atomic unsigned int.
 // Each client takes 2 bits. The first bit locates in the first 16 bits of
-// buffer_state; the second bit locates in the last 16 bits of buffer_state.
+// bufferState; the second bit locates in the last 16 bits of bufferState.
 // Client states:
 // Gained state 11. Exclusive write state.
 // Posted state 10.
@@ -64,9 +64,9 @@
 
 // Returns true if any of the client is in gained state.
 static inline bool isAnyClientGained(uint32_t state) {
-    uint32_t high_bits = state >> kMaxNumberOfClients;
-    uint32_t low_bits = state & kLowbitsMask;
-    return high_bits == low_bits && low_bits != 0U;
+    uint32_t highBits = state >> kMaxNumberOfClients;
+    uint32_t lowBits = state & kLowbitsMask;
+    return highBits == lowBits && lowBits != 0U;
 }
 
 // Returns true if the input client is in gained state.
@@ -76,34 +76,34 @@
 
 // Returns true if any of the client is in posted state.
 static inline bool isAnyClientPosted(uint32_t state) {
-    uint32_t high_bits = state >> kMaxNumberOfClients;
-    uint32_t low_bits = state & kLowbitsMask;
-    uint32_t posted_or_acquired = high_bits ^ low_bits;
-    return posted_or_acquired & high_bits;
+    uint32_t highBits = state >> kMaxNumberOfClients;
+    uint32_t lowBits = state & kLowbitsMask;
+    uint32_t postedOrAcquired = highBits ^ lowBits;
+    return postedOrAcquired & highBits;
 }
 
 // Returns true if the input client is in posted state.
 static inline bool isClientPosted(uint32_t state, uint32_t client_bit_mask) {
-    uint32_t client_bits = state & client_bit_mask;
-    if (client_bits == 0U) return false;
-    uint32_t low_bits = client_bits & kLowbitsMask;
-    return low_bits == 0U;
+    uint32_t clientBits = state & client_bit_mask;
+    if (clientBits == 0U) return false;
+    uint32_t lowBits = clientBits & kLowbitsMask;
+    return lowBits == 0U;
 }
 
 // Return true if any of the client is in acquired state.
 static inline bool isAnyClientAcquired(uint32_t state) {
-    uint32_t high_bits = state >> kMaxNumberOfClients;
-    uint32_t low_bits = state & kLowbitsMask;
-    uint32_t posted_or_acquired = high_bits ^ low_bits;
-    return posted_or_acquired & low_bits;
+    uint32_t highBits = state >> kMaxNumberOfClients;
+    uint32_t lowBits = state & kLowbitsMask;
+    uint32_t postedOrAcquired = highBits ^ lowBits;
+    return postedOrAcquired & lowBits;
 }
 
 // Return true if the input client is in acquired state.
 static inline bool isClientAcquired(uint32_t state, uint32_t client_bit_mask) {
-    uint32_t client_bits = state & client_bit_mask;
-    if (client_bits == 0U) return false;
-    uint32_t high_bits = client_bits & kHighBitsMask;
-    return high_bits == 0U;
+    uint32_t clientBits = state & client_bit_mask;
+    if (clientBits == 0U) return false;
+    uint32_t highBits = clientBits & kHighBitsMask;
+    return highBits == 0U;
 }
 
 // Returns true if the input client is in released state.
@@ -114,12 +114,12 @@
 // Returns the next available buffer client's client_state_masks.
 // @params union_bits. Union of all existing clients' client_state_masks.
 static inline uint32_t findNextAvailableClientStateMask(uint32_t union_bits) {
-    uint32_t low_union = union_bits & kLowbitsMask;
-    if (low_union == kLowbitsMask) return 0U;
-    uint32_t incremented = low_union + 1U;
-    uint32_t difference = incremented ^ low_union;
-    uint32_t new_low_bit = (difference + 1U) >> 1;
-    return new_low_bit + (new_low_bit << kMaxNumberOfClients);
+    uint32_t lowUnion = union_bits & kLowbitsMask;
+    if (lowUnion == kLowbitsMask) return 0U;
+    uint32_t incremented = lowUnion + 1U;
+    uint32_t difference = incremented ^ lowUnion;
+    uint32_t newLowBit = (difference + 1U) >> 1;
+    return newLowBit + (newLowBit << kMaxNumberOfClients);
 }
 
 struct __attribute__((aligned(8))) MetadataHeader {
@@ -129,22 +129,22 @@
     // platform (include Apps and vendor HAL).
 
     // Every client takes up one bit from the higher 32 bits and one bit from the lower 32 bits in
-    // buffer_state.
-    std::atomic<uint32_t> buffer_state;
+    // bufferState.
+    std::atomic<uint32_t> bufferState;
 
-    // Every client takes up one bit in fence_state. Only the lower 32 bits are valid. The upper 32
+    // Every client takes up one bit in fenceState. Only the lower 32 bits are valid. The upper 32
     // bits are there for easier manipulation, but the value should be ignored.
-    std::atomic<uint32_t> fence_state;
+    std::atomic<uint32_t> fenceState;
 
     // Every client takes up one bit from the higher 32 bits and one bit from the lower 32 bits in
-    // active_clients_bit_mask.
-    std::atomic<uint32_t> active_clients_bit_mask;
+    // activeClientsBitMask.
+    std::atomic<uint32_t> activeClientsBitMask;
 
     // Explicit padding 4 bytes.
     uint32_t padding;
 
     // The index of the buffer queue where the buffer belongs to.
-    uint64_t queue_index;
+    uint64_t queueIndex;
 
     // Public data format, which should be updated with caution. See more details in dvr_api.h
     DvrNativeBufferMetadata metadata;
diff --git a/libs/ui/tests/BufferHubMetadata_test.cpp b/libs/ui/tests/BufferHubMetadata_test.cpp
index f02c4fc..eb978ca 100644
--- a/libs/ui/tests/BufferHubMetadata_test.cpp
+++ b/libs/ui/tests/BufferHubMetadata_test.cpp
@@ -51,7 +51,7 @@
 
     // Check if the newly allocated buffer is initialized in released state (i.e.
     // state equals to 0U).
-    EXPECT_TRUE(mh1->buffer_state.load() == 0U);
+    EXPECT_TRUE(mh1->bufferState.load() == 0U);
 
     EXPECT_TRUE(m2.isValid());
     BufferHubDefs::MetadataHeader* mh2 = m2.metadataHeader();
@@ -59,7 +59,7 @@
 
     // Check if the newly allocated buffer is initialized in released state (i.e.
     // state equals to 0U).
-    EXPECT_TRUE(mh2->buffer_state.load() == 0U);
+    EXPECT_TRUE(mh2->bufferState.load() == 0U);
 }
 
 TEST_F(BufferHubMetadataTest, MoveMetadataInvalidatesOldOne) {
diff --git a/libs/vr/libbufferhub/buffer_hub_base.cpp b/libs/vr/libbufferhub/buffer_hub_base.cpp
index b28d101..17930b4 100644
--- a/libs/vr/libbufferhub/buffer_hub_base.cpp
+++ b/libs/vr/libbufferhub/buffer_hub_base.cpp
@@ -122,15 +122,15 @@
   // are mapped from shared memory as an atomic object. The std::atomic's
   // constructor will not be called so that the original value stored in the
   // memory region will be preserved.
-  buffer_state_ = &metadata_header_->buffer_state;
+  buffer_state_ = &metadata_header_->bufferState;
   ALOGD_IF(TRACE,
            "BufferHubBase::ImportBuffer: id=%d, buffer_state=%" PRIx32 ".",
            id(), buffer_state_->load(std::memory_order_acquire));
-  fence_state_ = &metadata_header_->fence_state;
+  fence_state_ = &metadata_header_->fenceState;
   ALOGD_IF(TRACE,
            "BufferHubBase::ImportBuffer: id=%d, fence_state=%" PRIx32 ".", id(),
            fence_state_->load(std::memory_order_acquire));
-  active_clients_bit_mask_ = &metadata_header_->active_clients_bit_mask;
+  active_clients_bit_mask_ = &metadata_header_->activeClientsBitMask;
   ALOGD_IF(
       TRACE,
       "BufferHubBase::ImportBuffer: id=%d, active_clients_bit_mask=%" PRIx32
diff --git a/libs/vr/libbufferhub/include/private/dvr/buffer_hub_base.h b/libs/vr/libbufferhub/include/private/dvr/buffer_hub_base.h
index fa39d08..8a490d9 100644
--- a/libs/vr/libbufferhub/include/private/dvr/buffer_hub_base.h
+++ b/libs/vr/libbufferhub/include/private/dvr/buffer_hub_base.h
@@ -97,8 +97,8 @@
   uint32_t usage() const { return buffer_.usage(); }
   uint32_t layer_count() const { return buffer_.layer_count(); }
 
-  uint64_t GetQueueIndex() const { return metadata_header_->queue_index; }
-  void SetQueueIndex(uint64_t index) { metadata_header_->queue_index = index; }
+  uint64_t GetQueueIndex() const { return metadata_header_->queueIndex; }
+  void SetQueueIndex(uint64_t index) { metadata_header_->queueIndex = index; }
 
  protected:
   explicit BufferHubBase(LocalChannelHandle channel);
diff --git a/services/bufferhub/BufferHubService.cpp b/services/bufferhub/BufferHubService.cpp
index ade08e7..7a3472f 100644
--- a/services/bufferhub/BufferHubService.cpp
+++ b/services/bufferhub/BufferHubService.cpp
@@ -241,8 +241,8 @@
 
         MetadataHeader* metadataHeader =
                 const_cast<BufferHubMetadata*>(&node->metadata())->metadataHeader();
-        const uint32_t state = metadataHeader->buffer_state.load(std::memory_order_acquire);
-        const uint64_t index = metadataHeader->queue_index;
+        const uint32_t state = metadataHeader->bufferState.load(std::memory_order_acquire);
+        const uint64_t index = metadataHeader->queueIndex;
 
         stream << std::right;
         stream << std::setw(6) << /*Id=*/node->id();
diff --git a/services/bufferhub/BufferNode.cpp b/services/bufferhub/BufferNode.cpp
index 1efb27e..04ca649 100644
--- a/services/bufferhub/BufferNode.cpp
+++ b/services/bufferhub/BufferNode.cpp
@@ -15,9 +15,9 @@
     // Using placement new here to reuse shared memory instead of new allocation
     // Initialize the atomic variables to zero.
     BufferHubDefs::MetadataHeader* metadataHeader = mMetadata.metadataHeader();
-    mBufferState = new (&metadataHeader->buffer_state) std::atomic<uint32_t>(0);
-    mFenceState = new (&metadataHeader->fence_state) std::atomic<uint32_t>(0);
-    mActiveClientsBitMask = new (&metadataHeader->active_clients_bit_mask) std::atomic<uint32_t>(0);
+    mBufferState = new (&metadataHeader->bufferState) std::atomic<uint32_t>(0);
+    mFenceState = new (&metadataHeader->fenceState) std::atomic<uint32_t>(0);
+    mActiveClientsBitMask = new (&metadataHeader->activeClientsBitMask) std::atomic<uint32_t>(0);
     // The C++ standard recommends (but does not require) that lock-free atomic operations are
     // also address-free, that is, suitable for communication between processes using shared
     // memory.
diff --git a/services/inputflinger/InputDispatcher.cpp b/services/inputflinger/InputDispatcher.cpp
index 9702fb2..7ff8b20 100644
--- a/services/inputflinger/InputDispatcher.cpp
+++ b/services/inputflinger/InputDispatcher.cpp
@@ -2673,7 +2673,7 @@
     policyFlags |= POLICY_FLAG_TRUSTED;
 
     android::base::Timer t;
-    mPolicy->interceptMotionBeforeQueueing(args->eventTime, /*byref*/ policyFlags);
+    mPolicy->interceptMotionBeforeQueueing(args->displayId, args->eventTime, /*byref*/ policyFlags);
     if (t.duration() > SLOW_INTERCEPTION_THRESHOLD) {
         ALOGW("Excessive delay in interceptMotionBeforeQueueing; took %s ms",
                 std::to_string(t.duration().count()).c_str());
@@ -2821,6 +2821,7 @@
         size_t pointerCount = motionEvent->getPointerCount();
         const PointerProperties* pointerProperties = motionEvent->getPointerProperties();
         int32_t actionButton = motionEvent->getActionButton();
+        int32_t displayId = motionEvent->getDisplayId();
         if (! validateMotionEvent(action, actionButton, pointerCount, pointerProperties)) {
             return INPUT_EVENT_INJECTION_FAILED;
         }
@@ -2828,7 +2829,7 @@
         if (!(policyFlags & POLICY_FLAG_FILTERED)) {
             nsecs_t eventTime = motionEvent->getEventTime();
             android::base::Timer t;
-            mPolicy->interceptMotionBeforeQueueing(eventTime, /*byref*/ policyFlags);
+            mPolicy->interceptMotionBeforeQueueing(displayId, eventTime, /*byref*/ policyFlags);
             if (t.duration() > SLOW_INTERCEPTION_THRESHOLD) {
                 ALOGW("Excessive delay in interceptMotionBeforeQueueing; took %s ms",
                         std::to_string(t.duration().count()).c_str());
diff --git a/services/inputflinger/InputDispatcher.h b/services/inputflinger/InputDispatcher.h
index 2d8df5c..595b01d 100644
--- a/services/inputflinger/InputDispatcher.h
+++ b/services/inputflinger/InputDispatcher.h
@@ -245,7 +245,8 @@
      * This method is expected to set the POLICY_FLAG_PASS_TO_USER policy flag if the event
      * should be dispatched to applications.
      */
-    virtual void interceptMotionBeforeQueueing(nsecs_t when, uint32_t& policyFlags) = 0;
+    virtual void interceptMotionBeforeQueueing(const int32_t displayId, nsecs_t when,
+            uint32_t& policyFlags) = 0;
 
     /* Allows the policy a chance to intercept a key before dispatching. */
     virtual nsecs_t interceptKeyBeforeDispatching(const sp<IBinder>& token,
diff --git a/services/inputflinger/InputReader.cpp b/services/inputflinger/InputReader.cpp
index f84aa34..1a1ae21 100644
--- a/services/inputflinger/InputReader.cpp
+++ b/services/inputflinger/InputReader.cpp
@@ -4550,7 +4550,8 @@
             mPointerController->setButtonState(mCurrentRawState.buttonState);
             mPointerController->setSpots(mCurrentCookedState.cookedPointerData.pointerCoords,
                     mCurrentCookedState.cookedPointerData.idToIndex,
-                    mCurrentCookedState.cookedPointerData.touchingIdBits);
+                    mCurrentCookedState.cookedPointerData.touchingIdBits,
+                    mViewport.displayId);
         }
 
         if (!mCurrentMotionAborted) {
@@ -5314,7 +5315,8 @@
         if (mPointerGesture.currentGestureMode == PointerGesture::FREEFORM) {
             mPointerController->setSpots(mPointerGesture.currentGestureCoords,
                      mPointerGesture.currentGestureIdToIndex,
-                     mPointerGesture.currentGestureIdBits);
+                     mPointerGesture.currentGestureIdBits,
+                     mPointerController->getDisplayId());
         }
     } else {
         mPointerController->setPresentation(PointerControllerInterface::PRESENTATION_POINTER);
diff --git a/services/inputflinger/include/PointerControllerInterface.h b/services/inputflinger/include/PointerControllerInterface.h
index bc0f1f9..0ff28e4 100644
--- a/services/inputflinger/include/PointerControllerInterface.h
+++ b/services/inputflinger/include/PointerControllerInterface.h
@@ -94,7 +94,7 @@
      * pressed (not hovering).
      */
     virtual void setSpots(const PointerCoords* spotCoords, const uint32_t* spotIdToIndex,
-            BitSet32 spotIdBits) = 0;
+            BitSet32 spotIdBits, int32_t displayId) = 0;
 
     /* Removes all spots. */
     virtual void clearSpots() = 0;
diff --git a/services/inputflinger/tests/InputDispatcher_test.cpp b/services/inputflinger/tests/InputDispatcher_test.cpp
index 0f987c3..3b6fe52 100644
--- a/services/inputflinger/tests/InputDispatcher_test.cpp
+++ b/services/inputflinger/tests/InputDispatcher_test.cpp
@@ -138,7 +138,7 @@
     virtual void interceptKeyBeforeQueueing(const KeyEvent*, uint32_t&) {
     }
 
-    virtual void interceptMotionBeforeQueueing(nsecs_t, uint32_t&) {
+    virtual void interceptMotionBeforeQueueing(int32_t, nsecs_t, uint32_t&) {
     }
 
     virtual nsecs_t interceptKeyBeforeDispatching(const sp<IBinder>&,
diff --git a/services/inputflinger/tests/InputReader_test.cpp b/services/inputflinger/tests/InputReader_test.cpp
index 84c5ad6..fbacb9b 100644
--- a/services/inputflinger/tests/InputReader_test.cpp
+++ b/services/inputflinger/tests/InputReader_test.cpp
@@ -103,6 +103,10 @@
         return mDisplayId;
     }
 
+    const std::map<int32_t, std::vector<int32_t>>& getSpots() {
+        return mSpotsByDisplay;
+    }
+
 private:
     virtual bool getBounds(float* outMinX, float* outMinY, float* outMaxX, float* outMaxY) const {
         *outMinX = mMinX;
@@ -130,11 +134,22 @@
     virtual void setPresentation(Presentation) {
     }
 
-    virtual void setSpots(const PointerCoords*, const uint32_t*, BitSet32) {
+    virtual void setSpots(const PointerCoords*, const uint32_t*, BitSet32 spotIdBits,
+            int32_t displayId) {
+        std::vector<int32_t> newSpots;
+        // Add spots for fingers that are down.
+        for (BitSet32 idBits(spotIdBits); !idBits.isEmpty(); ) {
+            uint32_t id = idBits.clearFirstMarkedBit();
+            newSpots.push_back(id);
+        }
+
+        mSpotsByDisplay[displayId] = newSpots;
     }
 
     virtual void clearSpots() {
     }
+
+    std::map<int32_t, std::vector<int32_t>> mSpotsByDisplay;
 };
 
 
@@ -228,6 +243,10 @@
         mConfig.pointerCapture = enabled;
     }
 
+    void setShowTouches(bool enabled) {
+        mConfig.showTouches = enabled;
+    }
+
 private:
     DisplayViewport createDisplayViewport(int32_t displayId, int32_t width, int32_t height,
             int32_t orientation, const std::string& uniqueId, std::optional<uint8_t> physicalPort,
@@ -6315,4 +6334,85 @@
     ASSERT_EQ(SECONDARY_DISPLAY_ID, motionArgs.displayId);
 }
 
+TEST_F(MultiTouchInputMapperTest, Process_Pointer_ShowTouches) {
+    // Setup the first touch screen device.
+    MultiTouchInputMapper* mapper = new MultiTouchInputMapper(mDevice);
+    prepareAxes(POSITION | ID | SLOT);
+    addConfigurationProperty("touch.deviceType", "touchScreen");
+    addMapperAndConfigure(mapper);
+
+    // Create the second touch screen device, and enable multi fingers.
+    const std::string USB2 = "USB2";
+    const int32_t SECOND_DEVICE_ID = 2;
+    InputDeviceIdentifier identifier;
+    identifier.name = DEVICE_NAME;
+    identifier.location = USB2;
+    InputDevice* device2 = new InputDevice(mFakeContext, SECOND_DEVICE_ID, DEVICE_GENERATION,
+            DEVICE_CONTROLLER_NUMBER, identifier, DEVICE_CLASSES);
+    mFakeEventHub->addDevice(SECOND_DEVICE_ID, DEVICE_NAME, 0 /*classes*/);
+    mFakeEventHub->addAbsoluteAxis(SECOND_DEVICE_ID, ABS_MT_POSITION_X, RAW_X_MIN, RAW_X_MAX,
+            0 /*flat*/, 0 /*fuzz*/);
+    mFakeEventHub->addAbsoluteAxis(SECOND_DEVICE_ID, ABS_MT_POSITION_Y, RAW_Y_MIN, RAW_Y_MAX,
+            0 /*flat*/, 0 /*fuzz*/);
+    mFakeEventHub->addAbsoluteAxis(SECOND_DEVICE_ID, ABS_MT_TRACKING_ID, RAW_ID_MIN, RAW_ID_MAX,
+            0 /*flat*/, 0 /*fuzz*/);
+    mFakeEventHub->addAbsoluteAxis(SECOND_DEVICE_ID, ABS_MT_SLOT, RAW_SLOT_MIN, RAW_SLOT_MAX,
+            0 /*flat*/, 0 /*fuzz*/);
+    mFakeEventHub->setAbsoluteAxisValue(SECOND_DEVICE_ID, ABS_MT_SLOT, 0 /*value*/);
+    mFakeEventHub->addConfigurationProperty(SECOND_DEVICE_ID, String8("touch.deviceType"),
+            String8("touchScreen"));
+
+    // Setup the second touch screen device.
+    MultiTouchInputMapper* mapper2 = new MultiTouchInputMapper(device2);
+    device2->addMapper(mapper2);
+    device2->configure(ARBITRARY_TIME, mFakePolicy->getReaderConfiguration(), 0 /*changes*/);
+    device2->reset(ARBITRARY_TIME);
+
+    // Setup PointerController.
+    sp<FakePointerController> fakePointerController = new FakePointerController();
+    mFakePolicy->setPointerController(mDevice->getId(), fakePointerController);
+    mFakePolicy->setPointerController(SECOND_DEVICE_ID, fakePointerController);
+
+    // Setup policy for associated displays and show touches.
+    const uint8_t hdmi1 = 0;
+    const uint8_t hdmi2 = 1;
+    mFakePolicy->addInputPortAssociation(DEVICE_LOCATION, hdmi1);
+    mFakePolicy->addInputPortAssociation(USB2, hdmi2);
+    mFakePolicy->setShowTouches(true);
+
+    // Create displays.
+    prepareDisplay(DISPLAY_ORIENTATION_0, hdmi1);
+    prepareSecondaryDisplay(ViewportType::VIEWPORT_EXTERNAL, hdmi2);
+
+    // Default device will reconfigure above, need additional reconfiguration for another device.
+    device2->configure(ARBITRARY_TIME, mFakePolicy->getReaderConfiguration(),
+            InputReaderConfiguration::CHANGE_DISPLAY_INFO);
+
+    // Two fingers down at default display.
+    int32_t x1 = 100, y1 = 125, x2 = 300, y2 = 500;
+    processPosition(mapper, x1, y1);
+    processId(mapper, 1);
+    processSlot(mapper, 1);
+    processPosition(mapper, x2, y2);
+    processId(mapper, 2);
+    processSync(mapper);
+
+    std::map<int32_t, std::vector<int32_t>>::const_iterator iter =
+            fakePointerController->getSpots().find(DISPLAY_ID);
+    ASSERT_TRUE(iter != fakePointerController->getSpots().end());
+    ASSERT_EQ(size_t(2), iter->second.size());
+
+    // Two fingers down at second display.
+    processPosition(mapper2, x1, y1);
+    processId(mapper2, 1);
+    processSlot(mapper2, 1);
+    processPosition(mapper2, x2, y2);
+    processId(mapper2, 2);
+    processSync(mapper2);
+
+    iter = fakePointerController->getSpots().find(SECONDARY_DISPLAY_ID);
+    ASSERT_TRUE(iter != fakePointerController->getSpots().end());
+    ASSERT_EQ(size_t(2), iter->second.size());
+}
+
 } // namespace android
diff --git a/services/surfaceflinger/CompositionEngine/src/DisplayColorProfile.cpp b/services/surfaceflinger/CompositionEngine/src/DisplayColorProfile.cpp
index 6e6f3c0..130ab1d 100644
--- a/services/surfaceflinger/CompositionEngine/src/DisplayColorProfile.cpp
+++ b/services/surfaceflinger/CompositionEngine/src/DisplayColorProfile.cpp
@@ -303,7 +303,7 @@
     }
 
     // add all known HDR combinations
-    for (auto intent : sHdrRenderIntents) {
+    for (auto intent : hdrRenderIntents) {
         for (auto mode : sHdrColorModes) {
             addColorMode(hwcColorModes, mode, intent);
         }
diff --git a/services/surfaceflinger/CompositionEngine/tests/DisplayColorProfileTest.cpp b/services/surfaceflinger/CompositionEngine/tests/DisplayColorProfileTest.cpp
index d20fdda..9215884 100644
--- a/services/surfaceflinger/CompositionEngine/tests/DisplayColorProfileTest.cpp
+++ b/services/surfaceflinger/CompositionEngine/tests/DisplayColorProfileTest.cpp
@@ -146,6 +146,8 @@
         return ProfileFactory()
                 .setHasWideColorGamut(true)
                 .addHdrType(Hdr::HDR10)
+                .addColorModeRenderIntent(ColorMode::DISPLAY_BT2020, RenderIntent::COLORIMETRIC)
+                .addColorModeRenderIntent(ColorMode::DISPLAY_BT2020, RenderIntent::ENHANCE)
                 .addColorModeRenderIntent(ColorMode::DISPLAY_BT2020, VendorRenderIntent)
                 .build();
     }
@@ -154,6 +156,8 @@
         return ProfileFactory()
                 .setHasWideColorGamut(true)
                 .addHdrType(Hdr::HDR10)
+                .addColorModeRenderIntent(ColorMode::SRGB, RenderIntent::COLORIMETRIC)
+                .addColorModeRenderIntent(ColorMode::SRGB, RenderIntent::ENHANCE)
                 .addColorModeRenderIntent(ColorMode::SRGB, VendorRenderIntent)
                 .build();
     }
@@ -166,6 +170,16 @@
                 .build();
     }
 
+    static impl::DisplayColorProfile createProfileWithDisplayP3ColorModeSupport() {
+        return ProfileFactory()
+                .setHasWideColorGamut(true)
+                .addHdrType(Hdr::HLG)
+                .addColorModeRenderIntent(ColorMode::DISPLAY_P3, RenderIntent::COLORIMETRIC)
+                .addColorModeRenderIntent(ColorMode::DISPLAY_P3, RenderIntent::ENHANCE)
+                .addColorModeRenderIntent(ColorMode::DISPLAY_P3, VendorRenderIntent)
+                .build();
+    }
+
 private:
     bool mHasWideColorGamut = false;
     std::vector<Hdr> mSupportedHdrTypes;
@@ -348,7 +362,7 @@
     auto profile = ProfileFactory::createProfileWithBT2020ColorModeSupport();
 
     EXPECT_TRUE(profile.hasRenderIntent(RenderIntent::COLORIMETRIC));
-    EXPECT_FALSE(profile.hasRenderIntent(RenderIntent::ENHANCE));
+    EXPECT_TRUE(profile.hasRenderIntent(RenderIntent::ENHANCE));
     EXPECT_FALSE(profile.hasRenderIntent(RenderIntent::TONE_MAP_COLORIMETRIC));
     EXPECT_FALSE(profile.hasRenderIntent(RenderIntent::TONE_MAP_ENHANCE));
     EXPECT_FALSE(profile.hasRenderIntent(VendorRenderIntent));
@@ -358,7 +372,7 @@
     auto profile = ProfileFactory::createProfileWithSRGBColorModeSupport();
 
     EXPECT_TRUE(profile.hasRenderIntent(RenderIntent::COLORIMETRIC));
-    EXPECT_FALSE(profile.hasRenderIntent(RenderIntent::ENHANCE));
+    EXPECT_TRUE(profile.hasRenderIntent(RenderIntent::ENHANCE));
     EXPECT_FALSE(profile.hasRenderIntent(RenderIntent::TONE_MAP_COLORIMETRIC));
     EXPECT_FALSE(profile.hasRenderIntent(RenderIntent::TONE_MAP_ENHANCE));
     EXPECT_TRUE(profile.hasRenderIntent(VendorRenderIntent));
@@ -414,47 +428,37 @@
 
 void checkGetBestColorMode(
         DisplayColorProfile& profile,
-        const std::array<std::tuple<Dataspace, ColorMode, RenderIntent>, 25>& expected) {
+        const std::array<std::tuple<Dataspace, ColorMode, RenderIntent>, 15>& expected) {
     using ArgsType = std::tuple<Dataspace, RenderIntent>;
 
     // These are the combinations of dataspaces and render intents that could be
     // passed to RenderSurface::getBestColorMode()
-    const std::array<std::tuple<Dataspace, RenderIntent>, 25> kArgs = {
+    const std::array<std::tuple<Dataspace, RenderIntent>, 15> kArgs = {
             /* clang-format off */
 
             // Non-HDR combinations
 
             /*  0 */ ArgsType{Dataspace::DISPLAY_BT2020, RenderIntent::COLORIMETRIC},
             /*  1 */ ArgsType{Dataspace::DISPLAY_BT2020, RenderIntent::ENHANCE},
-            /*  2 */ ArgsType{Dataspace::DISPLAY_BT2020, RenderIntent::TONE_MAP_COLORIMETRIC}, // Vendor explicit setting
-            /*  3 */ ArgsType{Dataspace::DISPLAY_BT2020, RenderIntent::TONE_MAP_ENHANCE},      // Vendor explicit setting
-            /*  4 */ ArgsType{Dataspace::DISPLAY_BT2020, VendorRenderIntent},                  // Vendor explicit setting
+            /*  2 */ ArgsType{Dataspace::DISPLAY_BT2020, VendorRenderIntent},                  // Vendor explicit setting
 
-            /*  5 */ ArgsType{Dataspace::DISPLAY_P3, RenderIntent::COLORIMETRIC},
-            /*  6 */ ArgsType{Dataspace::DISPLAY_P3, RenderIntent::ENHANCE},
-            /*  7 */ ArgsType{Dataspace::DISPLAY_P3, RenderIntent::TONE_MAP_COLORIMETRIC}, // Vendor explicit setting
-            /*  8 */ ArgsType{Dataspace::DISPLAY_P3, RenderIntent::TONE_MAP_ENHANCE},      // Vendor explicit setting
-            /*  9 */ ArgsType{Dataspace::DISPLAY_P3, VendorRenderIntent},                  // Vendor explicit setting
+            /*  3 */ ArgsType{Dataspace::DISPLAY_P3, RenderIntent::COLORIMETRIC},
+            /*  4 */ ArgsType{Dataspace::DISPLAY_P3, RenderIntent::ENHANCE},
+            /*  5 */ ArgsType{Dataspace::DISPLAY_P3, VendorRenderIntent},                  // Vendor explicit setting
 
-            /* 10 */ ArgsType{Dataspace::V0_SRGB, RenderIntent::COLORIMETRIC},
-            /* 11 */ ArgsType{Dataspace::V0_SRGB, RenderIntent::ENHANCE},
-            /* 12 */ ArgsType{Dataspace::V0_SRGB, RenderIntent::TONE_MAP_COLORIMETRIC}, // Vendor explicit setting
-            /* 13 */ ArgsType{Dataspace::V0_SRGB, RenderIntent::TONE_MAP_ENHANCE},      // Vendor explicit setting
-            /* 14 */ ArgsType{Dataspace::V0_SRGB, VendorRenderIntent},                  // Vendor explicit setting
+            /*  6 */ ArgsType{Dataspace::V0_SRGB, RenderIntent::COLORIMETRIC},
+            /*  7 */ ArgsType{Dataspace::V0_SRGB, RenderIntent::ENHANCE},
+            /*  8 */ ArgsType{Dataspace::V0_SRGB, VendorRenderIntent},                  // Vendor explicit setting
 
             // HDR combinations
 
-            /* 15 */ ArgsType{Dataspace::BT2020_PQ, RenderIntent::TONE_MAP_COLORIMETRIC},
-            /* 16 */ ArgsType{Dataspace::BT2020_PQ, RenderIntent::TONE_MAP_ENHANCE},
-            /* 17 */ ArgsType{Dataspace::BT2020_PQ, RenderIntent::COLORIMETRIC},       // Vendor explicit setting
-            /* 18 */ ArgsType{Dataspace::BT2020_PQ, RenderIntent::ENHANCE},            // Vendor explicit setting
-            /* 19 */ ArgsType{Dataspace::BT2020_PQ, VendorRenderIntent},               // Vendor explicit setting
+            /*  9 */ ArgsType{Dataspace::BT2020_PQ, RenderIntent::TONE_MAP_COLORIMETRIC},
+            /* 10 */ ArgsType{Dataspace::BT2020_PQ, RenderIntent::TONE_MAP_ENHANCE},
+            /* 11 */ ArgsType{Dataspace::BT2020_PQ, VendorRenderIntent},               // Vendor explicit setting
 
-            /* 20 */ ArgsType{Dataspace::BT2020_HLG, RenderIntent::TONE_MAP_COLORIMETRIC},
-            /* 21 */ ArgsType{Dataspace::BT2020_HLG, RenderIntent::TONE_MAP_ENHANCE},
-            /* 22 */ ArgsType{Dataspace::BT2020_HLG, RenderIntent::COLORIMETRIC},       // Vendor explicit setting
-            /* 23 */ ArgsType{Dataspace::BT2020_HLG, RenderIntent::ENHANCE},            // Vendor explicit setting
-            /* 24 */ ArgsType{Dataspace::BT2020_HLG, VendorRenderIntent},               // Vendor explicit setting
+            /* 12 */ ArgsType{Dataspace::BT2020_HLG, RenderIntent::TONE_MAP_COLORIMETRIC},
+            /* 13 */ ArgsType{Dataspace::BT2020_HLG, RenderIntent::TONE_MAP_ENHANCE},
+            /* 14 */ ArgsType{Dataspace::BT2020_HLG, VendorRenderIntent},               // Vendor explicit setting
             /* clang-format on */
     };
 
@@ -473,38 +477,28 @@
     // Note: This table of expected values goes with the table of arguments
     // used in checkGetBestColorMode.
     using Result = std::tuple<Dataspace, ColorMode, RenderIntent>;
-    std::array<Result, 25> expectedResults = {
+    std::array<Result, 15> expectedResults = {
             /* clang-format off */
             /*  0 */ Result{Dataspace::UNKNOWN, ColorMode::NATIVE, RenderIntent::COLORIMETRIC},
             /*  1 */ Result{Dataspace::UNKNOWN, ColorMode::NATIVE, RenderIntent::COLORIMETRIC},
             /*  2 */ Result{Dataspace::UNKNOWN, ColorMode::NATIVE, RenderIntent::COLORIMETRIC},
+
             /*  3 */ Result{Dataspace::UNKNOWN, ColorMode::NATIVE, RenderIntent::COLORIMETRIC},
             /*  4 */ Result{Dataspace::UNKNOWN, ColorMode::NATIVE, RenderIntent::COLORIMETRIC},
-
             /*  5 */ Result{Dataspace::UNKNOWN, ColorMode::NATIVE, RenderIntent::COLORIMETRIC},
+
             /*  6 */ Result{Dataspace::UNKNOWN, ColorMode::NATIVE, RenderIntent::COLORIMETRIC},
             /*  7 */ Result{Dataspace::UNKNOWN, ColorMode::NATIVE, RenderIntent::COLORIMETRIC},
             /*  8 */ Result{Dataspace::UNKNOWN, ColorMode::NATIVE, RenderIntent::COLORIMETRIC},
-            /*  9 */ Result{Dataspace::UNKNOWN, ColorMode::NATIVE, RenderIntent::COLORIMETRIC},
 
+            /*  9 */ Result{Dataspace::UNKNOWN, ColorMode::NATIVE, RenderIntent::COLORIMETRIC},
             /* 10 */ Result{Dataspace::UNKNOWN, ColorMode::NATIVE, RenderIntent::COLORIMETRIC},
             /* 11 */ Result{Dataspace::UNKNOWN, ColorMode::NATIVE, RenderIntent::COLORIMETRIC},
+
             /* 12 */ Result{Dataspace::UNKNOWN, ColorMode::NATIVE, RenderIntent::COLORIMETRIC},
             /* 13 */ Result{Dataspace::UNKNOWN, ColorMode::NATIVE, RenderIntent::COLORIMETRIC},
             /* 14 */ Result{Dataspace::UNKNOWN, ColorMode::NATIVE, RenderIntent::COLORIMETRIC},
 
-            /* 15 */ Result{Dataspace::UNKNOWN, ColorMode::NATIVE, RenderIntent::COLORIMETRIC},
-            /* 16 */ Result{Dataspace::UNKNOWN, ColorMode::NATIVE, RenderIntent::COLORIMETRIC},
-            /* 17 */ Result{Dataspace::UNKNOWN, ColorMode::NATIVE, RenderIntent::COLORIMETRIC},
-            /* 18 */ Result{Dataspace::UNKNOWN, ColorMode::NATIVE, RenderIntent::COLORIMETRIC},
-            /* 19 */ Result{Dataspace::UNKNOWN, ColorMode::NATIVE, RenderIntent::COLORIMETRIC},
-
-            /* 20 */ Result{Dataspace::UNKNOWN, ColorMode::NATIVE, RenderIntent::COLORIMETRIC},
-            /* 21 */ Result{Dataspace::UNKNOWN, ColorMode::NATIVE, RenderIntent::COLORIMETRIC},
-            /* 22 */ Result{Dataspace::UNKNOWN, ColorMode::NATIVE, RenderIntent::COLORIMETRIC},
-            /* 23 */ Result{Dataspace::UNKNOWN, ColorMode::NATIVE, RenderIntent::COLORIMETRIC},
-            /* 24 */ Result{Dataspace::UNKNOWN, ColorMode::NATIVE, RenderIntent::COLORIMETRIC},
-
             /* clang-format on */
     };
 
@@ -517,37 +511,27 @@
     // Note: This table of expected values goes with the table of arguments
     // used in checkGetBestColorMode.
     using Result = std::tuple<Dataspace, ColorMode, RenderIntent>;
-    std::array<Result, 25> expectedResults = {
+    std::array<Result, 15> expectedResults = {
             /* clang-format off */
             /*  0 */ Result{Dataspace::DISPLAY_BT2020, ColorMode::DISPLAY_BT2020, RenderIntent::COLORIMETRIC},
-            /*  1 */ Result{Dataspace::DISPLAY_BT2020, ColorMode::DISPLAY_BT2020, RenderIntent::COLORIMETRIC},
+            /*  1 */ Result{Dataspace::DISPLAY_BT2020, ColorMode::DISPLAY_BT2020, RenderIntent::ENHANCE},
             /*  2 */ Result{Dataspace::UNKNOWN, ColorMode::NATIVE, RenderIntent::COLORIMETRIC},
-            /*  3 */ Result{Dataspace::UNKNOWN, ColorMode::NATIVE, RenderIntent::COLORIMETRIC},
-            /*  4 */ Result{Dataspace::UNKNOWN, ColorMode::NATIVE, RenderIntent::COLORIMETRIC},
 
-            /*  5 */ Result{Dataspace::DISPLAY_BT2020, ColorMode::DISPLAY_BT2020, RenderIntent::COLORIMETRIC},
+            /*  3 */ Result{Dataspace::DISPLAY_BT2020, ColorMode::DISPLAY_BT2020, RenderIntent::COLORIMETRIC},
+            /*  4 */ Result{Dataspace::DISPLAY_BT2020, ColorMode::DISPLAY_BT2020, RenderIntent::ENHANCE},
+            /*  5 */ Result{Dataspace::UNKNOWN, ColorMode::NATIVE, RenderIntent::COLORIMETRIC},
+
             /*  6 */ Result{Dataspace::DISPLAY_BT2020, ColorMode::DISPLAY_BT2020, RenderIntent::COLORIMETRIC},
-            /*  7 */ Result{Dataspace::UNKNOWN, ColorMode::NATIVE, RenderIntent::COLORIMETRIC},
+            /*  7 */ Result{Dataspace::DISPLAY_BT2020, ColorMode::DISPLAY_BT2020, RenderIntent::ENHANCE},
             /*  8 */ Result{Dataspace::UNKNOWN, ColorMode::NATIVE, RenderIntent::COLORIMETRIC},
-            /*  9 */ Result{Dataspace::UNKNOWN, ColorMode::NATIVE, RenderIntent::COLORIMETRIC},
 
+            /*  9 */ Result{Dataspace::DISPLAY_BT2020, ColorMode::DISPLAY_BT2020, RenderIntent::COLORIMETRIC},
             /* 10 */ Result{Dataspace::DISPLAY_BT2020, ColorMode::DISPLAY_BT2020, RenderIntent::COLORIMETRIC},
-            /* 11 */ Result{Dataspace::DISPLAY_BT2020, ColorMode::DISPLAY_BT2020, RenderIntent::COLORIMETRIC},
-            /* 12 */ Result{Dataspace::UNKNOWN, ColorMode::NATIVE, RenderIntent::COLORIMETRIC},
-            /* 13 */ Result{Dataspace::UNKNOWN, ColorMode::NATIVE, RenderIntent::COLORIMETRIC},
+            /* 11 */ Result{Dataspace::UNKNOWN, ColorMode::NATIVE, RenderIntent::COLORIMETRIC},
+
+            /* 12 */ Result{Dataspace::DISPLAY_BT2020, ColorMode::DISPLAY_BT2020, RenderIntent::COLORIMETRIC},
+            /* 13 */ Result{Dataspace::DISPLAY_BT2020, ColorMode::DISPLAY_BT2020, RenderIntent::COLORIMETRIC},
             /* 14 */ Result{Dataspace::UNKNOWN, ColorMode::NATIVE, RenderIntent::COLORIMETRIC},
-
-            /* 15 */ Result{Dataspace::DISPLAY_BT2020, ColorMode::DISPLAY_BT2020, RenderIntent::COLORIMETRIC},
-            /* 16 */ Result{Dataspace::DISPLAY_BT2020, ColorMode::DISPLAY_BT2020, RenderIntent::COLORIMETRIC},
-            /* 17 */ Result{Dataspace::UNKNOWN, ColorMode::NATIVE, RenderIntent::COLORIMETRIC},
-            /* 18 */ Result{Dataspace::UNKNOWN, ColorMode::NATIVE, RenderIntent::COLORIMETRIC},
-            /* 19 */ Result{Dataspace::UNKNOWN, ColorMode::NATIVE, RenderIntent::COLORIMETRIC},
-
-            /* 20 */ Result{Dataspace::DISPLAY_BT2020, ColorMode::DISPLAY_BT2020, RenderIntent::COLORIMETRIC},
-            /* 21 */ Result{Dataspace::DISPLAY_BT2020, ColorMode::DISPLAY_BT2020, RenderIntent::COLORIMETRIC},
-            /* 22 */ Result{Dataspace::UNKNOWN, ColorMode::NATIVE, RenderIntent::COLORIMETRIC},
-            /* 23 */ Result{Dataspace::UNKNOWN, ColorMode::NATIVE, RenderIntent::COLORIMETRIC},
-            /* 24 */ Result{Dataspace::UNKNOWN, ColorMode::NATIVE, RenderIntent::COLORIMETRIC},
             /* clang-format on */
     };
 
@@ -560,37 +544,61 @@
     // Note: This table of expected values goes with the table of arguments
     // used in checkGetBestColorMode.
     using Result = std::tuple<Dataspace, ColorMode, RenderIntent>;
-    std::array<Result, 25> expectedResults = {
+    std::array<Result, 15> expectedResults = {
             /* clang-format off */
             /*  0 */ Result{Dataspace::V0_SRGB, ColorMode::SRGB, RenderIntent::COLORIMETRIC},
-            /*  1 */ Result{Dataspace::V0_SRGB, ColorMode::SRGB, RenderIntent::COLORIMETRIC},
-            /*  2 */ Result{Dataspace::UNKNOWN, ColorMode::NATIVE, RenderIntent::COLORIMETRIC},
-            /*  3 */ Result{Dataspace::UNKNOWN, ColorMode::NATIVE, RenderIntent::COLORIMETRIC},
-            /*  4 */ Result{Dataspace::V0_SRGB, ColorMode::SRGB, VendorRenderIntent},
+            /*  1 */ Result{Dataspace::V0_SRGB, ColorMode::SRGB, RenderIntent::ENHANCE},
+            /*  2 */ Result{Dataspace::V0_SRGB, ColorMode::SRGB, VendorRenderIntent},
 
-            /*  5 */ Result{Dataspace::V0_SRGB, ColorMode::SRGB, RenderIntent::COLORIMETRIC},
+            /*  3 */ Result{Dataspace::V0_SRGB, ColorMode::SRGB, RenderIntent::COLORIMETRIC},
+            /*  4 */ Result{Dataspace::V0_SRGB, ColorMode::SRGB, RenderIntent::ENHANCE},
+            /*  5 */ Result{Dataspace::V0_SRGB, ColorMode::SRGB, VendorRenderIntent},
+
             /*  6 */ Result{Dataspace::V0_SRGB, ColorMode::SRGB, RenderIntent::COLORIMETRIC},
-            /*  7 */ Result{Dataspace::UNKNOWN, ColorMode::NATIVE, RenderIntent::COLORIMETRIC},
-            /*  8 */ Result{Dataspace::UNKNOWN, ColorMode::NATIVE, RenderIntent::COLORIMETRIC},
-            /*  9 */ Result{Dataspace::V0_SRGB, ColorMode::SRGB, VendorRenderIntent},
+            /*  7 */ Result{Dataspace::V0_SRGB, ColorMode::SRGB, RenderIntent::ENHANCE},
+            /*  8 */ Result{Dataspace::V0_SRGB, ColorMode::SRGB, VendorRenderIntent},
 
+            /*  9 */ Result{Dataspace::V0_SRGB, ColorMode::SRGB, RenderIntent::COLORIMETRIC},
             /* 10 */ Result{Dataspace::V0_SRGB, ColorMode::SRGB, RenderIntent::COLORIMETRIC},
-            /* 11 */ Result{Dataspace::V0_SRGB, ColorMode::SRGB, RenderIntent::COLORIMETRIC},
-            /* 12 */ Result{Dataspace::UNKNOWN, ColorMode::NATIVE, RenderIntent::COLORIMETRIC},
-            /* 13 */ Result{Dataspace::UNKNOWN, ColorMode::NATIVE, RenderIntent::COLORIMETRIC},
-            /* 14 */ Result{Dataspace::V0_SRGB, ColorMode::SRGB, VendorRenderIntent},
+            /* 11 */ Result{Dataspace::UNKNOWN, ColorMode::NATIVE, RenderIntent::COLORIMETRIC},
 
-            /* 15 */ Result{Dataspace::V0_SRGB, ColorMode::SRGB, RenderIntent::COLORIMETRIC},
-            /* 16 */ Result{Dataspace::V0_SRGB, ColorMode::SRGB, RenderIntent::COLORIMETRIC},
-            /* 17 */ Result{Dataspace::UNKNOWN, ColorMode::NATIVE, RenderIntent::COLORIMETRIC},
-            /* 18 */ Result{Dataspace::UNKNOWN, ColorMode::NATIVE, RenderIntent::COLORIMETRIC},
-            /* 19 */ Result{Dataspace::UNKNOWN, ColorMode::NATIVE, RenderIntent::COLORIMETRIC},
+            /* 12 */ Result{Dataspace::V0_SRGB, ColorMode::SRGB, RenderIntent::COLORIMETRIC},
+            /* 13 */ Result{Dataspace::V0_SRGB, ColorMode::SRGB, RenderIntent::COLORIMETRIC},
+            /* 14 */ Result{Dataspace::UNKNOWN, ColorMode::NATIVE, RenderIntent::COLORIMETRIC},
+            /* clang-format on */
+    };
 
-            /* 20 */ Result{Dataspace::V0_SRGB, ColorMode::SRGB, RenderIntent::COLORIMETRIC},
-            /* 21 */ Result{Dataspace::V0_SRGB, ColorMode::SRGB, RenderIntent::COLORIMETRIC},
-            /* 22 */ Result{Dataspace::UNKNOWN, ColorMode::NATIVE, RenderIntent::COLORIMETRIC},
-            /* 23 */ Result{Dataspace::UNKNOWN, ColorMode::NATIVE, RenderIntent::COLORIMETRIC},
-            /* 24 */ Result{Dataspace::UNKNOWN, ColorMode::NATIVE, RenderIntent::COLORIMETRIC},
+    checkGetBestColorMode(profile, expectedResults);
+}
+
+TEST_F(DisplayColorProfileTest, getBestColorModeReturnsExpectedModesWhenOutputHasDisplayP3Support) {
+    auto profile = ProfileFactory::createProfileWithDisplayP3ColorModeSupport();
+
+    // Note: This table of expected values goes with the table of arguments
+    // used in checkGetBestColorMode.
+    using Result = std::tuple<Dataspace, ColorMode, RenderIntent>;
+    std::array<Result, 15> expectedResults = {
+            /* clang-format off */
+            /*  0 */ Result{Dataspace::DISPLAY_P3, ColorMode::DISPLAY_P3, RenderIntent::COLORIMETRIC},
+            /*  1 */ Result{Dataspace::DISPLAY_P3, ColorMode::DISPLAY_P3, RenderIntent::ENHANCE},
+            // TODO(b/124317977): There is bug here.
+            /*  2 */ Result{Dataspace::UNKNOWN, ColorMode::NATIVE, RenderIntent::COLORIMETRIC},
+
+            /*  3 */ Result{Dataspace::DISPLAY_P3, ColorMode::DISPLAY_P3, RenderIntent::COLORIMETRIC},
+            /*  4 */ Result{Dataspace::DISPLAY_P3, ColorMode::DISPLAY_P3, RenderIntent::ENHANCE},
+            /*  5 */ Result{Dataspace::UNKNOWN, ColorMode::NATIVE, RenderIntent::COLORIMETRIC},
+
+            /*  6 */ Result{Dataspace::DISPLAY_P3, ColorMode::DISPLAY_P3, RenderIntent::COLORIMETRIC},
+            /*  7 */ Result{Dataspace::DISPLAY_P3, ColorMode::DISPLAY_P3, RenderIntent::ENHANCE},
+            /*  8 */ Result{Dataspace::UNKNOWN, ColorMode::NATIVE, RenderIntent::COLORIMETRIC},
+
+            /*  9 */ Result{Dataspace::DISPLAY_P3, ColorMode::DISPLAY_P3, RenderIntent::COLORIMETRIC},
+            /* 10 */ Result{Dataspace::DISPLAY_P3, ColorMode::DISPLAY_P3, RenderIntent::COLORIMETRIC},
+            /* 11 */ Result{Dataspace::UNKNOWN, ColorMode::NATIVE, RenderIntent::COLORIMETRIC},
+
+            /* 12 */ Result{Dataspace::DISPLAY_P3, ColorMode::DISPLAY_P3, RenderIntent::COLORIMETRIC},
+            /* 13 */ Result{Dataspace::DISPLAY_P3, ColorMode::DISPLAY_P3, RenderIntent::COLORIMETRIC},
+            /* 14 */ Result{Dataspace::UNKNOWN, ColorMode::NATIVE, RenderIntent::COLORIMETRIC},
             /* clang-format on */
     };
 
@@ -603,37 +611,27 @@
     // Note: This table of expected values goes with the table of arguments
     // used in checkGetBestColorMode.
     using Result = std::tuple<Dataspace, ColorMode, RenderIntent>;
-    std::array<Result, 25> expectedResults = {
+    std::array<Result, 15> expectedResults = {
             /* clang-format off */
             /*  0 */ Result{Dataspace::UNKNOWN, ColorMode::NATIVE, RenderIntent::COLORIMETRIC},
             /*  1 */ Result{Dataspace::UNKNOWN, ColorMode::NATIVE, RenderIntent::COLORIMETRIC},
             /*  2 */ Result{Dataspace::UNKNOWN, ColorMode::NATIVE, RenderIntent::COLORIMETRIC},
+
             /*  3 */ Result{Dataspace::UNKNOWN, ColorMode::NATIVE, RenderIntent::COLORIMETRIC},
             /*  4 */ Result{Dataspace::UNKNOWN, ColorMode::NATIVE, RenderIntent::COLORIMETRIC},
-
             /*  5 */ Result{Dataspace::UNKNOWN, ColorMode::NATIVE, RenderIntent::COLORIMETRIC},
+
             /*  6 */ Result{Dataspace::UNKNOWN, ColorMode::NATIVE, RenderIntent::COLORIMETRIC},
             /*  7 */ Result{Dataspace::UNKNOWN, ColorMode::NATIVE, RenderIntent::COLORIMETRIC},
             /*  8 */ Result{Dataspace::UNKNOWN, ColorMode::NATIVE, RenderIntent::COLORIMETRIC},
-            /*  9 */ Result{Dataspace::UNKNOWN, ColorMode::NATIVE, RenderIntent::COLORIMETRIC},
 
-            /* 19 */ Result{Dataspace::UNKNOWN, ColorMode::NATIVE, RenderIntent::COLORIMETRIC},
-            /* 11 */ Result{Dataspace::UNKNOWN, ColorMode::NATIVE, RenderIntent::COLORIMETRIC},
-            /* 12 */ Result{Dataspace::UNKNOWN, ColorMode::NATIVE, RenderIntent::COLORIMETRIC},
-            /* 13 */ Result{Dataspace::UNKNOWN, ColorMode::NATIVE, RenderIntent::COLORIMETRIC},
-            /* 14 */ Result{Dataspace::UNKNOWN, ColorMode::NATIVE, RenderIntent::COLORIMETRIC},
+            /*  9 */ Result{Dataspace::BT2020_PQ, ColorMode::BT2100_PQ, RenderIntent::COLORIMETRIC},
+            /* 10 */ Result{Dataspace::BT2020_PQ, ColorMode::BT2100_PQ, RenderIntent::COLORIMETRIC},
+            /* 11 */ Result{Dataspace::BT2020_PQ, ColorMode::BT2100_PQ, VendorRenderIntent},
 
-            /* 15 */ Result{Dataspace::BT2020_PQ, ColorMode::BT2100_PQ, RenderIntent::COLORIMETRIC},
-            /* 16 */ Result{Dataspace::BT2020_PQ, ColorMode::BT2100_PQ, RenderIntent::COLORIMETRIC},
-            /* 17 */ Result{Dataspace::UNKNOWN, ColorMode::NATIVE, RenderIntent::COLORIMETRIC},
-            /* 18 */ Result{Dataspace::UNKNOWN, ColorMode::NATIVE, RenderIntent::COLORIMETRIC},
-            /* 19 */ Result{Dataspace::UNKNOWN, ColorMode::NATIVE, RenderIntent::COLORIMETRIC},
-
-            /* 20 */ Result{Dataspace::BT2020_PQ, ColorMode::BT2100_PQ, RenderIntent::COLORIMETRIC},
-            /* 21 */ Result{Dataspace::BT2020_PQ, ColorMode::BT2100_PQ, RenderIntent::COLORIMETRIC},
-            /* 22 */ Result{Dataspace::UNKNOWN, ColorMode::NATIVE, RenderIntent::COLORIMETRIC},
-            /* 23 */ Result{Dataspace::UNKNOWN, ColorMode::NATIVE, RenderIntent::COLORIMETRIC},
-            /* 24 */ Result{Dataspace::UNKNOWN, ColorMode::NATIVE, RenderIntent::COLORIMETRIC},
+            /* 12 */ Result{Dataspace::BT2020_PQ, ColorMode::BT2100_PQ, RenderIntent::COLORIMETRIC},
+            /* 13 */ Result{Dataspace::BT2020_PQ, ColorMode::BT2100_PQ, RenderIntent::COLORIMETRIC},
+            /* 14 */ Result{Dataspace::BT2020_PQ, ColorMode::BT2100_PQ, VendorRenderIntent},
             /* clang-format on */
     };
 
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index b68f053..3abd6a7 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -773,6 +773,9 @@
 
     property_get("persist.sys.sf.native_mode", value, "0");
     mDisplayColorSetting = static_cast<DisplayColorSetting>(atoi(value));
+
+    property_get("persist.sys.sf.color_mode", value, "0");
+    mForceColorMode = static_cast<ColorMode>(atoi(value));
 }
 
 void SurfaceFlinger::startBootAnim() {
@@ -2491,6 +2494,17 @@
 
     auto* profile = display->getCompositionDisplay()->getDisplayColorProfile();
 
+    switch (mForceColorMode) {
+        case ColorMode::SRGB:
+            bestDataSpace = Dataspace::V0_SRGB;
+            break;
+        case ColorMode::DISPLAY_P3:
+            bestDataSpace = Dataspace::DISPLAY_P3;
+            break;
+        default:
+            break;
+    }
+
     // respect hdrDataSpace only when there is no legacy HDR support
     const bool isHdr =
             hdrDataSpace != Dataspace::UNKNOWN && !profile->hasLegacyHdrSupport(hdrDataSpace);
@@ -3078,6 +3092,7 @@
         });
     }
 
+    commitInputWindowCommands();
     commitTransaction();
 }
 
@@ -3108,6 +3123,11 @@
     mInputFlinger->setInputWindows(inputHandles);
 }
 
+void SurfaceFlinger::commitInputWindowCommands() {
+    mInputWindowCommands.merge(mPendingInputWindowCommands);
+    mPendingInputWindowCommands.clear();
+}
+
 void SurfaceFlinger::executeInputWindowCommands() {
     for (const auto& transferTouchFocusCommand : mInputWindowCommands.transferTouchFocusCommands) {
         if (transferTouchFocusCommand.fromToken != nullptr &&
@@ -3686,7 +3706,7 @@
             if (!transactionIsReadyToBeApplied(desiredPresentTime, states)) {
                 break;
             }
-            applyTransactionState(states, displays, flags, mInputWindowCommands);
+            applyTransactionState(states, displays, flags, mPendingInputWindowCommands);
             transactionQueue.pop();
         }
 
@@ -4154,7 +4174,7 @@
         flags |= eTraversalNeeded;
     }
 
-    mInputWindowCommands.merge(inputWindowCommands);
+    mPendingInputWindowCommands.merge(inputWindowCommands);
     return flags;
 }
 
@@ -4370,7 +4390,7 @@
     d.width = 0;
     d.height = 0;
     displays.add(d);
-    setTransactionState(state, displays, 0, nullptr, mInputWindowCommands, -1);
+    setTransactionState(state, displays, 0, nullptr, mPendingInputWindowCommands, -1);
 
     setPowerModeInternal(display, HWC_POWER_MODE_NORMAL);
 
diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h
index 4393077..728e8d3 100644
--- a/services/surfaceflinger/SurfaceFlinger.h
+++ b/services/surfaceflinger/SurfaceFlinger.h
@@ -534,10 +534,11 @@
     void handleMessageRefresh();
 
     void handleTransaction(uint32_t transactionFlags);
-    void handleTransactionLocked(uint32_t transactionFlags);
+    void handleTransactionLocked(uint32_t transactionFlags) REQUIRES(mStateLock);
 
     void updateInputFlinger();
     void updateInputWindowInfo();
+    void commitInputWindowCommands() REQUIRES(mStateLock);
     void executeInputWindowCommands();
     void updateCursorAsync();
 
@@ -566,7 +567,8 @@
                                        const Vector<ComposerState>& states);
     uint32_t setClientStateLocked(const ComposerState& composerState);
     uint32_t setDisplayStateLocked(const DisplayState& s);
-    uint32_t addInputWindowCommands(const InputWindowCommands& inputWindowCommands);
+    uint32_t addInputWindowCommands(const InputWindowCommands& inputWindowCommands)
+            REQUIRES(mStateLock);
 
     /* ------------------------------------------------------------------------
      * Layer management
@@ -1088,6 +1090,15 @@
 
     DisplayColorSetting mDisplayColorSetting = DisplayColorSetting::ENHANCED;
 
+    // Color mode forced by setting persist.sys.sf.color_mode, it must:
+    //     1. not be NATIVE color mode, NATIVE color mode means no forced color mode;
+    //     2. be one of the supported color modes returned by hardware composer, otherwise
+    //        it will not be respected.
+    // persist.sys.sf.color_mode will only take effect when persist.sys.sf.native_mode
+    // is not set to 1.
+    // This property can be used to force SurfaceFlinger to always pick a certain color mode.
+    ui::ColorMode mForceColorMode = ui::ColorMode::NATIVE;
+
     ui::Dataspace mDefaultCompositionDataspace;
     ui::Dataspace mWideColorGamutCompositionDataspace;
 
@@ -1134,6 +1145,8 @@
     /* ------------------------------------------------------------------------ */
     sp<IInputFlinger> mInputFlinger;
 
+    InputWindowCommands mPendingInputWindowCommands GUARDED_BY(mStateLock);
+    // Should only be accessed by the main thread.
     InputWindowCommands mInputWindowCommands;
 
     ui::DisplayPrimaries mInternalDisplayPrimaries;
diff --git a/services/surfaceflinger/surfaceflinger.rc b/services/surfaceflinger/surfaceflinger.rc
index 5bec502..aea602b 100644
--- a/services/surfaceflinger/surfaceflinger.rc
+++ b/services/surfaceflinger/surfaceflinger.rc
@@ -2,7 +2,6 @@
     class core animation
     user system
     group graphics drmrpc readproc
-    updatable
     onrestart restart zygote
     writepid /dev/stune/foreground/tasks
     socket pdx/system/vr/display/client     stream 0666 system graphics u:object_r:pdx_display_client_endpoint_socket:s0
diff --git a/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h b/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h
index 53b867f..959126e 100644
--- a/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h
+++ b/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h
@@ -248,6 +248,7 @@
     }
 
     auto handleTransactionLocked(uint32_t transactionFlags) {
+        Mutex::Autolock _l(mFlinger->mStateLock);
         return mFlinger->handleTransactionLocked(transactionFlags);
     }
 
diff --git a/services/vr/bufferhubd/producer_channel.cpp b/services/vr/bufferhubd/producer_channel.cpp
index f3e54a0..b49d894 100644
--- a/services/vr/bufferhubd/producer_channel.cpp
+++ b/services/vr/bufferhubd/producer_channel.cpp
@@ -91,11 +91,10 @@
 
   // Using placement new here to reuse shared memory instead of new allocation
   // and also initialize the value to zero.
-  buffer_state_ =
-      new (&metadata_header_->buffer_state) std::atomic<uint32_t>(0);
-  fence_state_ = new (&metadata_header_->fence_state) std::atomic<uint32_t>(0);
+  buffer_state_ = new (&metadata_header_->bufferState) std::atomic<uint32_t>(0);
+  fence_state_ = new (&metadata_header_->fenceState) std::atomic<uint32_t>(0);
   active_clients_bit_mask_ =
-      new (&metadata_header_->active_clients_bit_mask) std::atomic<uint32_t>(0);
+      new (&metadata_header_->activeClientsBitMask) std::atomic<uint32_t>(0);
 
   // Producer channel is never created after consumer channel, and one buffer
   // only have one fixed producer for now. Thus, it is correct to assume
@@ -183,7 +182,7 @@
                     buffer_.height(), buffer_.layer_count(), buffer_.format(),
                     buffer_.usage(),
                     buffer_state_->load(std::memory_order_acquire),
-                    signaled_mask, metadata_header_->queue_index);
+                    signaled_mask, metadata_header_->queueIndex);
 }
 
 void ProducerChannel::HandleImpulse(Message& message) {
@@ -547,7 +546,7 @@
           "%s: orphaned buffer detected during the this acquire/release cycle: "
           "id=%d orphaned=0x%" PRIx32 " queue_index=%" PRId64 ".",
           __FUNCTION__, buffer_id(), orphaned_consumer_bit_mask_,
-          metadata_header_->queue_index);
+          metadata_header_->queueIndex);
       orphaned_consumer_bit_mask_ = 0;
     }
   }
@@ -581,7 +580,7 @@
       "consumer_state_mask=%" PRIx32 " queue_index=%" PRId64
       " buffer_state=%" PRIx32 " fence_state=%" PRIx32 ".",
       __FUNCTION__, buffer_id(), consumer_state_mask,
-      metadata_header_->queue_index,
+      metadata_header_->queueIndex,
       buffer_state_->load(std::memory_order_acquire),
       fence_state_->load(std::memory_order_acquire));
 }
diff --git a/vulkan/libvulkan/Android.bp b/vulkan/libvulkan/Android.bp
index fed8481..206c8eb 100644
--- a/vulkan/libvulkan/Android.bp
+++ b/vulkan/libvulkan/Android.bp
@@ -84,8 +84,8 @@
         "libutils",
         "libcutils",
         "libz",
-        "libnativebridge",
-        "libnativeloader",
+        "libnativebridge_lazy",
+        "libnativeloader_lazy",
         "libnativewindow",
         "android.hardware.graphics.common@1.0",
     ],