Merge "SF: Adding Layer History to SF."
diff --git a/include/android/system_fonts.h b/include/android/system_fonts.h
index c541511..38f036e 100644
--- a/include/android/system_fonts.h
+++ b/include/android/system_fonts.h
@@ -24,7 +24,7 @@
  * The ASystemFontIterator_open method will give you an iterator which can iterate all system
  * installed font files as shown in the following example.
  *
- * <code>
+ * \code{.cpp}
  *   ASystemFontIterator* iterator = ASystemFontIterator_open();
  *   ASystemFont* font = NULL;
  *
@@ -50,7 +50,7 @@
  *
  *   // Use this font for your text rendering engine.
  *
- * </code>
+ * \endcode
  *
  * Available since API level 29.
  */
@@ -142,7 +142,7 @@
 /**
  * Close an opened system font iterator, freeing any related resources.
  *
- * \param a pointer of an iterator for the system fonts. Do nothing if NULL is passed.
+ * \param iterator a pointer of an iterator for the system fonts. Do nothing if NULL is passed.
  */
 void ASystemFontIterator_close(ASystemFontIterator* _Nullable iterator) __INTRODUCED_IN(29);
 
@@ -174,7 +174,7 @@
  * drawing Tofu character.
  *
  * Examples:
- * <code>
+ * \code{.cpp}
  *  // Simple font query for the ASCII character.
  *  std::vector<uint16_t> text = { 'A' };
  *  ASystemFont font = ASystemFont_matchFamilyStyleCharacter(
@@ -202,15 +202,15 @@
  *  ASystemFont font = ASystemFont_matchFamilyStyleCharacter(
  *      "sans", 400, false, "en-US", text.data(), text.length(), &runLength);
  *  // runLength will be 1 and the font will points a Hebrew font.
- * </code>
+ * \endcode
  *
  * \param familyName a null character terminated font family name
  * \param weight a font weight value. Only from 0 to 1000 value is valid
  * \param italic true if italic, otherwise false.
  * \param languageTags a null character terminated comma separated IETF BCP47 compliant language
  *                     tags.
- * \param text a UTF-16 encoded text buffer to be rendered.
- * \param textLength a length of the given text buffer.
+ * \param text a UTF-16 encoded text buffer to be rendered. Do not pass empty string.
+ * \param textLength a length of the given text buffer. This must not be zero.
  * \param runLengthOut if not null, the font run length will be filled.
  * \return a font to be used for given text and params. You need to release the returned font by
  *         ASystemFont_close when it is no longer needed.
@@ -239,7 +239,7 @@
  * The font file returned is guaranteed to be opend with O_RDONLY.
  * Note that the returned pointer is valid until ASystemFont_close() is called for the given font.
  *
- * \param iterator an iterator for the system fonts. Passing NULL is not allowed.
+ * \param font a font object. Passing NULL is not allowed.
  * \return a string of the font file path.
  */
 const char* _Nonnull ASystemFont_getFontFilePath(const ASystemFont* _Nonnull font) __INTRODUCED_IN(29);
@@ -251,14 +251,11 @@
  * Here are pairs of the common names and their values.
  * <p>
  *  <table>
- *  <thead>
  *  <tr>
  *  <th align="center">Value</th>
  *  <th align="center">Name</th>
  *  <th align="center">NDK Definition</th>
  *  </tr>
- *  </thead>
- *  <tbody>
  *  <tr>
  *  <td align="center">100</td>
  *  <td align="center">Thin</td>
@@ -304,13 +301,13 @@
  *  <td align="center">Black (Heavy)</td>
  *  <td align="center">{@link ASYSTEM_FONT_WEIGHT_BLACK}</td>
  *  </tr>
- *  </tbody>
+ *  </table>
  * </p>
  * Note that the weight value may fall in between above values, e.g. 250 weight.
  *
  * For more information about font weight, read [OpenType usWeightClass](https://docs.microsoft.com/en-us/typography/opentype/spec/os2#usweightclass)
  *
- * \param iterator an iterator for the system fonts. Passing NULL is not allowed.
+ * \param font a font object. Passing NULL is not allowed.
  * \return a positive integer less than or equal to {@link ASYSTEM_FONT_MAX_WEIGHT} is returned.
  */
 uint16_t ASystemFont_getWeight(const ASystemFont* _Nonnull font) __INTRODUCED_IN(29);
@@ -318,7 +315,7 @@
 /**
  * Return true if the current font is italic, otherwise returns false.
  *
- * \param iterator an iterator for the system fonts. Passing NULL is not allowed.
+ * \param font a font object. Passing NULL is not allowed.
  * \return true if italic, otherwise false.
  */
 bool ASystemFont_isItalic(const ASystemFont* _Nonnull font) __INTRODUCED_IN(29);
@@ -330,7 +327,7 @@
  *
  * Note that the returned pointer is valid until ASystemFont_close() is called.
  *
- * \param iterator an iterator for the system fonts. Passing NULL is not allowed.
+ * \param font a font object. Passing NULL is not allowed.
  * \return a IETF BCP47 compliant langauge tag or nullptr if not available.
  */
 const char* _Nullable ASystemFont_getLocale(const ASystemFont* _Nonnull font) __INTRODUCED_IN(29);
@@ -342,7 +339,7 @@
  * returns a non-negative value as an font offset in the collection. This
  * always returns 0 if the target font file is a regular font.
  *
- * \param iterator an iterator for the system fonts. Passing NULL is not allowed.
+ * \param font a font object. Passing NULL is not allowed.
  * \return a font collection index.
  */
 size_t ASystemFont_getCollectionIndex(const ASystemFont* _Nonnull font) __INTRODUCED_IN(29);
@@ -356,7 +353,7 @@
  *     'wght' 700, 'slnt' -12
  * In this case, ASystemFont_getAxisCount returns 2 and ASystemFont_getAxisTag
  * and ASystemFont_getAxisValue will return following values.
- * <code>
+ * \code{.cpp}
  *     ASystemFont* font = ASystemFontIterator_next(ite);
  *
  *     // Returns the number of axes
@@ -369,11 +366,11 @@
  *     // Returns the tag-value pair for the second axis.
  *     ASystemFont_getAxisTag(font, 1);  // Returns 'slnt'(0x736c6e74)
  *     ASystemFont_getAxisValue(font, 1);  // Returns -12.0
- * </code>
+ * \endcode
  *
  * For more information about font variation settings, read [Font Variations Table](https://docs.microsoft.com/en-us/typography/opentype/spec/fvar)
  *
- * \param iterator an iterator for the system fonts. Passing NULL is not allowed.
+ * \param font a font object. Passing NULL is not allowed.
  * \return a number of font variation settings.
  */
 size_t ASystemFont_getAxisCount(const ASystemFont* _Nonnull font) __INTRODUCED_IN(29);
@@ -384,8 +381,8 @@
  *
  * See ASystemFont_getAxisCount for more details.
  *
- * \param iterator an iterator for the system fonts. Passing NULL is not allowed.
- * \param an index to the font variation settings. Passing value larger than or
+ * \param font a font object. Passing NULL is not allowed.
+ * \param axisIndex an index to the font variation settings. Passing value larger than or
  *        equal to {@link ASystemFont_getAxisCount} is not allowed.
  * \return an OpenType axis tag value for the given font variation setting.
  */
@@ -397,8 +394,8 @@
  *
  * See ASystemFont_getAxisCount for more details.
  *
- * \param iterator an iterator for the system fonts. Passing NULL is not allowed.
- * \param an index to the font variation settings. Passing value larger than or
+ * \param font a font object. Passing NULL is not allowed.
+ * \param axisIndex an index to the font variation settings. Passing value larger than or
  *         equal to {@link ASYstemFont_getAxisCount} is not allwed.
  * \return a float value for the given font variation setting.
  */
diff --git a/libs/binder/IPCThreadState.cpp b/libs/binder/IPCThreadState.cpp
index f0c21f5..8df83f1 100644
--- a/libs/binder/IPCThreadState.cpp
+++ b/libs/binder/IPCThreadState.cpp
@@ -109,9 +109,7 @@
     "BC_DEAD_BINDER_DONE"
 };
 
-// The work source represents the UID of the process we should attribute the transaction to.
-// We use -1 to specify that the work source was not set using #setWorkSource.
-static const int kUnsetWorkSource = -1;
+static const int64_t kWorkSourcePropagatedBitIndex = 32;
 
 static const char* getReturnString(uint32_t cmd)
 {
@@ -389,12 +387,29 @@
 
 int64_t IPCThreadState::setCallingWorkSourceUid(uid_t uid)
 {
-    // Note: we currently only use half of the int64. We return an int64 for extensibility.
-    int64_t token = mWorkSource;
+    int64_t token = setCallingWorkSourceUidWithoutPropagation(uid);
+    mPropagateWorkSource = true;
+    return token;
+}
+
+int64_t IPCThreadState::setCallingWorkSourceUidWithoutPropagation(uid_t uid)
+{
+    const int64_t propagatedBit = ((int64_t)mPropagateWorkSource) << kWorkSourcePropagatedBitIndex;
+    int64_t token = propagatedBit | mWorkSource;
     mWorkSource = uid;
     return token;
 }
 
+void IPCThreadState::clearPropagateWorkSource()
+{
+    mPropagateWorkSource = false;
+}
+
+bool IPCThreadState::shouldPropagateWorkSource() const
+{
+    return mPropagateWorkSource;
+}
+
 uid_t IPCThreadState::getCallingWorkSourceUid() const
 {
     return mWorkSource;
@@ -408,7 +423,8 @@
 void IPCThreadState::restoreCallingWorkSource(int64_t token)
 {
     uid_t uid = (int)token;
-    setCallingWorkSourceUid(uid);
+    setCallingWorkSourceUidWithoutPropagation(uid);
+    mPropagateWorkSource = ((token >> kWorkSourcePropagatedBitIndex) & 1) == 1;
 }
 
 void IPCThreadState::setLastTransactionBinderFlags(int32_t flags)
@@ -765,6 +781,7 @@
 IPCThreadState::IPCThreadState()
     : mProcess(ProcessState::self()),
       mWorkSource(kUnsetWorkSource),
+      mPropagateWorkSource(false),
       mStrictModePolicy(0),
       mLastTransactionBinderFlags(0)
 {
@@ -1127,6 +1144,13 @@
             const uid_t origUid = mCallingUid;
             const int32_t origStrictModePolicy = mStrictModePolicy;
             const int32_t origTransactionBinderFlags = mLastTransactionBinderFlags;
+            const int32_t origWorkSource = mWorkSource;
+            const bool origPropagateWorkSet = mPropagateWorkSource;
+            // Calling work source will be set by Parcel#enforceInterface. Parcel#enforceInterface
+            // is only guaranteed to be called for AIDL-generated stubs so we reset the work source
+            // here to never propagate it.
+            clearCallingWorkSource();
+            clearPropagateWorkSource();
 
             mCallingPid = tr.sender_pid;
             mCallingUid = tr.sender_euid;
@@ -1179,6 +1203,8 @@
             mCallingUid = origUid;
             mStrictModePolicy = origStrictModePolicy;
             mLastTransactionBinderFlags = origTransactionBinderFlags;
+            mWorkSource = origWorkSource;
+            mPropagateWorkSource = origPropagateWorkSet;
 
             IF_LOG_TRANSACTIONS() {
                 TextOutput::Bundle _b(alog);
diff --git a/libs/binder/Parcel.cpp b/libs/binder/Parcel.cpp
index 643f428..a0a634a 100644
--- a/libs/binder/Parcel.cpp
+++ b/libs/binder/Parcel.cpp
@@ -599,9 +599,10 @@
 // Write RPC headers.  (previously just the interface token)
 status_t Parcel::writeInterfaceToken(const String16& interface)
 {
-    writeInt32(IPCThreadState::self()->getStrictModePolicy() |
-               STRICT_MODE_PENALTY_GATHER);
-    writeInt32(IPCThreadState::self()->getCallingWorkSourceUid());
+    const IPCThreadState* threadState = IPCThreadState::self();
+    writeInt32(threadState->getStrictModePolicy() | STRICT_MODE_PENALTY_GATHER);
+    writeInt32(threadState->shouldPropagateWorkSource() ?
+            threadState->getCallingWorkSourceUid() : IPCThreadState::kUnsetWorkSource);
     // currently the interface identification token is just its name as a string
     return writeString16(interface);
 }
@@ -631,7 +632,7 @@
     }
     // WorkSource.
     int32_t workSource = readInt32();
-    threadState->setCallingWorkSourceUid(workSource);
+    threadState->setCallingWorkSourceUidWithoutPropagation(workSource);
     // Interface descriptor.
     const String16 str(readString16());
     if (str == interface) {
diff --git a/libs/binder/include/binder/IPCThreadState.h b/libs/binder/include/binder/IPCThreadState.h
index de126d5..75b348c 100644
--- a/libs/binder/include/binder/IPCThreadState.h
+++ b/libs/binder/include/binder/IPCThreadState.h
@@ -49,12 +49,16 @@
 
             // See Binder#setCallingWorkSourceUid in Binder.java.
             int64_t             setCallingWorkSourceUid(uid_t uid);
+            // Internal only. Use setCallingWorkSourceUid(uid) instead.
+            int64_t             setCallingWorkSourceUidWithoutPropagation(uid_t uid);
             // See Binder#getCallingWorkSourceUid in Binder.java.
             uid_t               getCallingWorkSourceUid() const;
             // See Binder#clearCallingWorkSource in Binder.java.
             int64_t             clearCallingWorkSource();
             // See Binder#restoreCallingWorkSource in Binder.java.
             void                restoreCallingWorkSource(int64_t token);
+            void                clearPropagateWorkSource();
+            bool                shouldPropagateWorkSource() const;
 
             void                setLastTransactionBinderFlags(int32_t flags);
             int32_t             getLastTransactionBinderFlags() const;
@@ -127,6 +131,11 @@
             // infer information about thread state.
             bool                isServingCall() const;
 
+            // The work source represents the UID of the process we should attribute the transaction
+            // to.
+            // We use -1 to specify that the work source was not set using #setWorkSource.
+            static const int32_t kUnsetWorkSource = -1;
+
 private:
                                 IPCThreadState();
                                 ~IPCThreadState();
@@ -167,6 +176,8 @@
             // The UID of the process who is responsible for this transaction.
             // This is used for resource attribution.
             int32_t             mWorkSource;
+            // Whether the work source should be propagated.
+            bool                mPropagateWorkSource;
             int32_t             mStrictModePolicy;
             int32_t             mLastTransactionBinderFlags;
             IPCThreadStateBase  *mIPCThreadStateBase;
diff --git a/libs/binder/ndk/include_ndk/android/binder_auto_utils.h b/libs/binder/ndk/include_ndk/android/binder_auto_utils.h
index e2c0cfa..c6fcaa4 100644
--- a/libs/binder/ndk/include_ndk/android/binder_auto_utils.h
+++ b/libs/binder/ndk/include_ndk/android/binder_auto_utils.h
@@ -163,7 +163,9 @@
     ScopedAResource& operator=(ScopedAResource&&) = delete;
 
     // move-constructing is okay
-    ScopedAResource(ScopedAResource&&) = default;
+    ScopedAResource(ScopedAResource&& other) : mT(std::move(other.mT)) {
+      other.mT = DEFAULT;
+    }
 
    private:
     T mT;
diff --git a/libs/binder/ndk/include_ndk/android/binder_parcel.h b/libs/binder/ndk/include_ndk/android/binder_parcel.h
index 3594349..866af70 100644
--- a/libs/binder/ndk/include_ndk/android/binder_parcel.h
+++ b/libs/binder/ndk/include_ndk/android/binder_parcel.h
@@ -54,6 +54,31 @@
 void AParcel_delete(AParcel* parcel) __INTRODUCED_IN(29);
 
 /**
+ * Sets the position within the parcel.
+ *
+ * \param parcel The parcel of which to set the position.
+ * \param position Position of the parcel to set. This must be a value returned by
+ * AParcel_getDataPosition. Positions are constant for a given parcel between processes.
+ *
+ * \return STATUS_OK on success. If position is negative, then STATUS_BAD_VALUE will be returned.
+ */
+binder_status_t AParcel_setDataPosition(const AParcel* parcel, int32_t position)
+        __INTRODUCED_IN(29);
+
+/**
+ * Gets the current position within the parcel.
+ *
+ * \param parcel The parcel of which to get the position.
+ *
+ * \return The size of the parcel. This will always be greater than 0. The values returned by this
+ * function before and after calling various reads and writes are not defined. Only the delta
+ * between two positions between a specific sequence of calls is defined. For instance, if position
+ * is X, writeBool is called, and then position is Y, readBool can be called from position X will
+ * return the same value, and then position will be Y.
+ */
+int32_t AParcel_getDataPosition(const AParcel* parcel) __INTRODUCED_IN(29);
+
+/**
  * This is called to allocate a buffer for a C-style string (null-terminated). The returned buffer
  * should be at least length bytes. This includes space for a null terminator. For a string, length
  * will always be strictly less than or equal to the maximum size that can be held in a size_t and
diff --git a/libs/binder/ndk/libbinder_ndk.map.txt b/libs/binder/ndk/libbinder_ndk.map.txt
index 41df90b..4328b6e 100644
--- a/libs/binder/ndk/libbinder_ndk.map.txt
+++ b/libs/binder/ndk/libbinder_ndk.map.txt
@@ -25,6 +25,7 @@
     AIBinder_Weak_new;
     AIBinder_Weak_promote;
     AParcel_delete;
+    AParcel_getDataPosition;
     AParcel_readBool;
     AParcel_readBoolArray;
     AParcel_readByte;
@@ -48,6 +49,7 @@
     AParcel_readUint32Array;
     AParcel_readUint64;
     AParcel_readUint64Array;
+    AParcel_setDataPosition;
     AParcel_writeBool;
     AParcel_writeBoolArray;
     AParcel_writeByte;
diff --git a/libs/binder/ndk/parcel.cpp b/libs/binder/ndk/parcel.cpp
index 3c32100..2d68559 100644
--- a/libs/binder/ndk/parcel.cpp
+++ b/libs/binder/ndk/parcel.cpp
@@ -212,6 +212,19 @@
     delete parcel;
 }
 
+binder_status_t AParcel_setDataPosition(const AParcel* parcel, int32_t position) {
+    if (position < 0) {
+        return STATUS_BAD_VALUE;
+    }
+
+    parcel->get()->setDataPosition(position);
+    return STATUS_OK;
+}
+
+int32_t AParcel_getDataPosition(const AParcel* parcel) {
+    return parcel->get()->dataPosition();
+}
+
 binder_status_t AParcel_writeStrongBinder(AParcel* parcel, AIBinder* binder) {
     sp<IBinder> writeBinder = binder != nullptr ? binder->getBinder() : nullptr;
     return parcel->get()->writeStrongBinder(writeBinder);
diff --git a/libs/binder/tests/binderLibTest.cpp b/libs/binder/tests/binderLibTest.cpp
index 22c1bad..cd37d49 100644
--- a/libs/binder/tests/binderLibTest.cpp
+++ b/libs/binder/tests/binderLibTest.cpp
@@ -180,6 +180,7 @@
     public:
         virtual void SetUp() {
             m_server = static_cast<BinderLibTestEnv *>(binder_env)->getServer();
+            IPCThreadState::self()->restoreCallingWorkSource(0); 
         }
         virtual void TearDown() {
         }
@@ -953,11 +954,28 @@
 {
     status_t ret;
     Parcel data, reply;
+    IPCThreadState::self()->clearCallingWorkSource();
     int64_t previousWorkSource = IPCThreadState::self()->setCallingWorkSourceUid(100);
     data.writeInterfaceToken(binderLibTestServiceName);
     ret = m_server->transact(BINDER_LIB_TEST_GET_WORK_SOURCE_TRANSACTION, data, &reply);
     EXPECT_EQ(100, reply.readInt32());
     EXPECT_EQ(-1, previousWorkSource);
+    EXPECT_EQ(true, IPCThreadState::self()->shouldPropagateWorkSource());
+    EXPECT_EQ(NO_ERROR, ret);
+}
+
+TEST_F(BinderLibTest, WorkSourceSetWithoutPropagation)
+{
+    status_t ret;
+    Parcel data, reply;
+
+    IPCThreadState::self()->setCallingWorkSourceUidWithoutPropagation(100);
+    EXPECT_EQ(false, IPCThreadState::self()->shouldPropagateWorkSource());
+
+    data.writeInterfaceToken(binderLibTestServiceName);
+    ret = m_server->transact(BINDER_LIB_TEST_GET_WORK_SOURCE_TRANSACTION, data, &reply);
+    EXPECT_EQ(-1, reply.readInt32());
+    EXPECT_EQ(false, IPCThreadState::self()->shouldPropagateWorkSource());
     EXPECT_EQ(NO_ERROR, ret);
 }
 
@@ -967,7 +985,8 @@
     Parcel data, reply;
 
     IPCThreadState::self()->setCallingWorkSourceUid(100);
-    int64_t previousWorkSource = IPCThreadState::self()->clearCallingWorkSource();
+    int64_t token = IPCThreadState::self()->clearCallingWorkSource();
+    int32_t previousWorkSource = (int32_t)token;
     data.writeInterfaceToken(binderLibTestServiceName);
     ret = m_server->transact(BINDER_LIB_TEST_GET_WORK_SOURCE_TRANSACTION, data, &reply);
 
@@ -989,9 +1008,58 @@
     ret = m_server->transact(BINDER_LIB_TEST_GET_WORK_SOURCE_TRANSACTION, data, &reply);
 
     EXPECT_EQ(100, reply.readInt32());
+    EXPECT_EQ(true, IPCThreadState::self()->shouldPropagateWorkSource());
     EXPECT_EQ(NO_ERROR, ret);
 }
 
+TEST_F(BinderLibTest, PropagateFlagSet)
+{
+    status_t ret;
+    Parcel data, reply;
+
+    IPCThreadState::self()->clearPropagateWorkSource();
+    IPCThreadState::self()->setCallingWorkSourceUid(100);
+    EXPECT_EQ(true, IPCThreadState::self()->shouldPropagateWorkSource());
+}
+
+TEST_F(BinderLibTest, PropagateFlagCleared)
+{
+    status_t ret;
+    Parcel data, reply;
+
+    IPCThreadState::self()->setCallingWorkSourceUid(100);
+    IPCThreadState::self()->clearPropagateWorkSource();
+    EXPECT_EQ(false, IPCThreadState::self()->shouldPropagateWorkSource());
+}
+
+TEST_F(BinderLibTest, PropagateFlagRestored)
+{
+    status_t ret;
+    Parcel data, reply;
+
+    int token = IPCThreadState::self()->setCallingWorkSourceUid(100);
+    IPCThreadState::self()->restoreCallingWorkSource(token);
+
+    EXPECT_EQ(false, IPCThreadState::self()->shouldPropagateWorkSource());
+}
+
+TEST_F(BinderLibTest, WorkSourcePropagatedForAllFollowingBinderCalls)
+{
+    IPCThreadState::self()->setCallingWorkSourceUid(100);
+
+    Parcel data, reply;
+    status_t ret;
+    data.writeInterfaceToken(binderLibTestServiceName);
+    ret = m_server->transact(BINDER_LIB_TEST_GET_WORK_SOURCE_TRANSACTION, data, &reply);
+
+    Parcel data2, reply2;
+    status_t ret2;
+    data2.writeInterfaceToken(binderLibTestServiceName);
+    ret2 = m_server->transact(BINDER_LIB_TEST_GET_WORK_SOURCE_TRANSACTION, data2, &reply2);
+    EXPECT_EQ(100, reply2.readInt32());
+    EXPECT_EQ(NO_ERROR, ret2);
+}
+
 class BinderLibTestService : public BBinder
 {
     public:
diff --git a/libs/gui/HdrMetadata.cpp b/libs/gui/HdrMetadata.cpp
index b715e43..add3ef0 100644
--- a/libs/gui/HdrMetadata.cpp
+++ b/libs/gui/HdrMetadata.cpp
@@ -15,6 +15,7 @@
  */
 
 #include <gui/HdrMetadata.h>
+#include <limits>
 
 namespace android {
 
@@ -26,6 +27,10 @@
     if (validTypes & CTA861_3) {
         size += sizeof(cta8613);
     }
+    if (validTypes & HDR10PLUS) {
+        size += sizeof(size_t);
+        size += hdr10plus.size();
+    }
     return size;
 }
 
@@ -41,6 +46,12 @@
     if (validTypes & CTA861_3) {
         FlattenableUtils::write(buffer, size, cta8613);
     }
+    if (validTypes & HDR10PLUS) {
+        size_t metadataSize = hdr10plus.size();
+        FlattenableUtils::write(buffer, size, metadataSize);
+        memcpy(buffer, hdr10plus.data(), metadataSize);
+        FlattenableUtils::advance(buffer, size, metadataSize);
+    }
 
     return NO_ERROR;
 }
@@ -62,6 +73,22 @@
         }
         FlattenableUtils::read(buffer, size, cta8613);
     }
+    if (validTypes & HDR10PLUS) {
+        if (size < sizeof(size_t)) {
+            return NO_MEMORY;
+        }
+
+        size_t metadataSize;
+        FlattenableUtils::read(buffer, size, metadataSize);
+
+        if (size < metadataSize) {
+            return NO_MEMORY;
+        }
+
+        hdr10plus.resize(metadataSize);
+        memcpy(hdr10plus.data(), buffer, metadataSize);
+        FlattenableUtils::advance(buffer, size, metadataSize);
+    }
 
     return NO_ERROR;
 }
@@ -91,6 +118,10 @@
         }
     }
 
+    if ((validTypes & HDR10PLUS) == HDR10PLUS) {
+        if (hdr10plus != rhs.hdr10plus) return false;
+    }
+
     return true;
 }
 
diff --git a/libs/gui/Surface.cpp b/libs/gui/Surface.cpp
index b505c6f..00e23f0 100644
--- a/libs/gui/Surface.cpp
+++ b/libs/gui/Surface.cpp
@@ -965,6 +965,9 @@
     case NATIVE_WINDOW_SET_BUFFERS_CTA861_3_METADATA:
         res = dispatchSetBuffersCta8613Metadata(args);
         break;
+    case NATIVE_WINDOW_SET_BUFFERS_HDR10_PLUS_METADATA:
+        res = dispatchSetBuffersHdr10PlusMetadata(args);
+        break;
     case NATIVE_WINDOW_SET_SURFACE_DAMAGE:
         res = dispatchSetSurfaceDamage(args);
         break;
@@ -1120,6 +1123,12 @@
     return setBuffersCta8613Metadata(metadata);
 }
 
+int Surface::dispatchSetBuffersHdr10PlusMetadata(va_list args) {
+    const size_t size = va_arg(args, size_t);
+    const uint8_t* metadata = va_arg(args, const uint8_t*);
+    return setBuffersHdr10PlusMetadata(size, metadata);
+}
+
 int Surface::dispatchSetSurfaceDamage(va_list args) {
     android_native_rect_t* rects = va_arg(args, android_native_rect_t*);
     size_t numRects = va_arg(args, size_t);
@@ -1568,6 +1577,19 @@
     return NO_ERROR;
 }
 
+int Surface::setBuffersHdr10PlusMetadata(const size_t size, const uint8_t* metadata) {
+    ALOGV("Surface::setBuffersBlobMetadata");
+    Mutex::Autolock lock(mMutex);
+    if (size > 0) {
+        mHdrMetadata.hdr10plus.assign(metadata, metadata + size);
+        mHdrMetadata.validTypes |= HdrMetadata::HDR10PLUS;
+    } else {
+        mHdrMetadata.validTypes &= ~HdrMetadata::HDR10PLUS;
+        mHdrMetadata.hdr10plus.clear();
+    }
+    return NO_ERROR;
+}
+
 Dataspace Surface::getBuffersDataSpace() {
     ALOGV("Surface::getBuffersDataSpace");
     Mutex::Autolock lock(mMutex);
diff --git a/libs/gui/include/gui/HdrMetadata.h b/libs/gui/include/gui/HdrMetadata.h
index 9800602..1e9c3e7 100644
--- a/libs/gui/include/gui/HdrMetadata.h
+++ b/libs/gui/include/gui/HdrMetadata.h
@@ -17,6 +17,7 @@
 #pragma once
 
 #include <stdint.h>
+#include <vector>
 
 #include <system/graphics.h>
 #include <utils/Flattenable.h>
@@ -26,12 +27,15 @@
 struct HdrMetadata : public LightFlattenable<HdrMetadata> {
     enum Type : uint32_t {
         SMPTE2086 = 1 << 0,
-        CTA861_3  = 1 << 1,
+        CTA861_3 = 1 << 1,
+        HDR10PLUS = 1 << 2,
     };
+
     uint32_t validTypes{0};
 
     android_smpte2086_metadata smpte2086{};
     android_cta861_3_metadata cta8613{};
+    std::vector<uint8_t> hdr10plus{};
 
     // LightFlattenable
     bool isFixedSize() const { return false; }
diff --git a/libs/gui/include/gui/Surface.h b/libs/gui/include/gui/Surface.h
index 32ee595..248e105 100644
--- a/libs/gui/include/gui/Surface.h
+++ b/libs/gui/include/gui/Surface.h
@@ -218,6 +218,7 @@
     int dispatchSetBuffersDataSpace(va_list args);
     int dispatchSetBuffersSmpte2086Metadata(va_list args);
     int dispatchSetBuffersCta8613Metadata(va_list args);
+    int dispatchSetBuffersHdr10PlusMetadata(va_list args);
     int dispatchSetSurfaceDamage(va_list args);
     int dispatchSetSharedBufferMode(va_list args);
     int dispatchSetAutoRefresh(va_list args);
@@ -249,6 +250,7 @@
     virtual int setBuffersDataSpace(ui::Dataspace dataSpace);
     virtual int setBuffersSmpte2086Metadata(const android_smpte2086_metadata* metadata);
     virtual int setBuffersCta8613Metadata(const android_cta861_3_metadata* metadata);
+    virtual int setBuffersHdr10PlusMetadata(const size_t size, const uint8_t* metadata);
     virtual int setCrop(Rect const* rect);
     virtual int setUsage(uint64_t reqUsage);
     virtual void setSurfaceDamage(android_native_rect_t* rects, size_t numRects);
diff --git a/libs/gui/tests/Surface_test.cpp b/libs/gui/tests/Surface_test.cpp
index d0600da..4ba7da3 100644
--- a/libs/gui/tests/Surface_test.cpp
+++ b/libs/gui/tests/Surface_test.cpp
@@ -366,10 +366,17 @@
         78.0,
         62.0,
     };
+
+    std::vector<uint8_t> hdr10plus;
+    hdr10plus.push_back(0xff);
+
     int error = native_window_set_buffers_smpte2086_metadata(window.get(), &smpte2086);
     ASSERT_EQ(error, NO_ERROR);
     error = native_window_set_buffers_cta861_3_metadata(window.get(), &cta861_3);
     ASSERT_EQ(error, NO_ERROR);
+    error = native_window_set_buffers_hdr10_plus_metadata(window.get(), hdr10plus.size(),
+                                                          hdr10plus.data());
+    ASSERT_EQ(error, NO_ERROR);
 }
 
 TEST_F(SurfaceTest, DynamicSetBufferCount) {
diff --git a/libs/nativewindow/include/system/window.h b/libs/nativewindow/include/system/window.h
index 197f73f..61590e0 100644
--- a/libs/nativewindow/include/system/window.h
+++ b/libs/nativewindow/include/system/window.h
@@ -202,7 +202,7 @@
  * ANativeWindow.
  */
 enum {
-// clang-format off
+    // clang-format off
     NATIVE_WINDOW_SET_USAGE                     =  0,   /* deprecated */
     NATIVE_WINDOW_CONNECT                       =  1,   /* deprecated */
     NATIVE_WINDOW_DISCONNECT                    =  2,   /* deprecated */
@@ -237,7 +237,8 @@
     NATIVE_WINDOW_GET_CONSUMER_USAGE64          = 31,
     NATIVE_WINDOW_SET_BUFFERS_SMPTE2086_METADATA = 32,
     NATIVE_WINDOW_SET_BUFFERS_CTA861_3_METADATA = 33,
-// clang-format on
+    NATIVE_WINDOW_SET_BUFFERS_HDR10_PLUS_METADATA = 34,
+    // clang-format on
 };
 
 /* parameter for NATIVE_WINDOW_[API_][DIS]CONNECT */
@@ -748,6 +749,27 @@
 }
 
 /*
+ * native_window_set_buffers_hdr10_plus_metadata(..., metadata)
+ * All buffers queued after this call will be associated with the
+ * HDR10+ dynamic metadata specified.
+ *
+ * metadata specifies additional dynamic information about the
+ * contents of the buffer that may affect how it is displayed.  When
+ * it is nullptr, it means no such information is available.  No
+ * HDR10+ dynamic emtadata is associated with the buffers by default.
+ *
+ * Parameter "size" refers to the length of the metadata blob pointed to
+ * by parameter "data".  The metadata blob will adhere to the HDR10+ SEI
+ * message standard.
+ */
+static inline int native_window_set_buffers_hdr10_plus_metadata(struct ANativeWindow* window,
+                                                           const size_t size,
+                                                           const uint8_t* metadata) {
+    return window->perform(window, NATIVE_WINDOW_SET_BUFFERS_HDR10_PLUS_METADATA, size,
+                           metadata);
+}
+
+/*
  * native_window_set_buffers_transform(..., int transform)
  * All buffers queued after this call will be displayed transformed according
  * to the transform parameter specified.
diff --git a/libs/renderengine/Android.bp b/libs/renderengine/Android.bp
index 7efc8bd..beaf9ee 100644
--- a/libs/renderengine/Android.bp
+++ b/libs/renderengine/Android.bp
@@ -50,7 +50,6 @@
         "gl/GLExtensions.cpp",
         "gl/GLFramebuffer.cpp",
         "gl/GLImage.cpp",
-        "gl/GLSurface.cpp",
         "gl/Program.cpp",
         "gl/ProgramCache.cpp",
     ],
diff --git a/libs/renderengine/gl/GLES20RenderEngine.cpp b/libs/renderengine/gl/GLES20RenderEngine.cpp
index e244a83..b10b52b 100644
--- a/libs/renderengine/gl/GLES20RenderEngine.cpp
+++ b/libs/renderengine/gl/GLES20RenderEngine.cpp
@@ -41,7 +41,6 @@
 #include "GLExtensions.h"
 #include "GLFramebuffer.h"
 #include "GLImage.h"
-#include "GLSurface.h"
 #include "Program.h"
 #include "ProgramCache.h"
 
@@ -241,60 +240,29 @@
         config = chooseEglConfig(display, hwcFormat, /*logConfig*/ true);
     }
 
-    EGLint renderableType = 0;
-    if (config == EGL_NO_CONFIG) {
-        renderableType = EGL_OPENGL_ES2_BIT;
-    } else if (!eglGetConfigAttrib(display, config, EGL_RENDERABLE_TYPE, &renderableType)) {
-        LOG_ALWAYS_FATAL("can't query EGLConfig RENDERABLE_TYPE");
-    }
-    EGLint contextClientVersion = 0;
-    if (renderableType & EGL_OPENGL_ES2_BIT) {
-        contextClientVersion = 2;
-    } else if (renderableType & EGL_OPENGL_ES_BIT) {
-        contextClientVersion = 1;
-    } else {
-        LOG_ALWAYS_FATAL("no supported EGL_RENDERABLE_TYPEs");
-    }
-
-    std::vector<EGLint> contextAttributes;
-    contextAttributes.reserve(6);
-    contextAttributes.push_back(EGL_CONTEXT_CLIENT_VERSION);
-    contextAttributes.push_back(contextClientVersion);
     bool useContextPriority = extensions.hasContextPriority() &&
             (featureFlags & RenderEngine::USE_HIGH_PRIORITY_CONTEXT);
-    if (useContextPriority) {
-        contextAttributes.push_back(EGL_CONTEXT_PRIORITY_LEVEL_IMG);
-        contextAttributes.push_back(EGL_CONTEXT_PRIORITY_HIGH_IMG);
-    }
-    contextAttributes.push_back(EGL_NONE);
-
-    EGLContext ctxt = eglCreateContext(display, config, nullptr, contextAttributes.data());
+    EGLContext ctxt = createEglContext(display, config, EGL_NO_CONTEXT, useContextPriority);
 
     // if can't create a GL context, we can only abort.
     LOG_ALWAYS_FATAL_IF(ctxt == EGL_NO_CONTEXT, "EGLContext creation failed");
 
-    // now figure out what version of GL did we actually get
-    // NOTE: a dummy surface is not needed if KHR_create_context is supported
-    // TODO(alecmouri): don't create this surface if EGL_KHR_surfaceless_context
-    // is supported.
-
-    EGLConfig dummyConfig = config;
-    if (dummyConfig == EGL_NO_CONFIG) {
-        dummyConfig = chooseEglConfig(display, hwcFormat, /*logConfig*/ true);
+    EGLSurface dummy = EGL_NO_SURFACE;
+    if (!extensions.hasSurfacelessContext()) {
+        dummy = createDummyEglPbufferSurface(display, config, hwcFormat);
+        LOG_ALWAYS_FATAL_IF(dummy == EGL_NO_SURFACE, "can't create dummy pbuffer");
     }
-    EGLint attribs[] = {EGL_WIDTH, 1, EGL_HEIGHT, 1, EGL_NONE, EGL_NONE};
-    EGLSurface dummy = eglCreatePbufferSurface(display, dummyConfig, attribs);
-    LOG_ALWAYS_FATAL_IF(dummy == EGL_NO_SURFACE, "can't create dummy pbuffer");
+
     EGLBoolean success = eglMakeCurrent(display, dummy, dummy, ctxt);
     LOG_ALWAYS_FATAL_IF(!success, "can't make dummy pbuffer current");
 
     extensions.initWithGLStrings(glGetString(GL_VENDOR), glGetString(GL_RENDERER),
                                  glGetString(GL_VERSION), glGetString(GL_EXTENSIONS));
 
+    // now figure out what version of GL did we actually get
     GlesVersion version = parseGlesVersion(extensions.getVersion());
 
     // initialize the renderer while GL is current
-
     std::unique_ptr<GLES20RenderEngine> engine;
     switch (version) {
         case GLES_VERSION_1_0:
@@ -423,10 +391,6 @@
     return std::make_unique<GLFramebuffer>(*this);
 }
 
-std::unique_ptr<Surface> GLES20RenderEngine::createSurface() {
-    return std::make_unique<GLSurface>(*this);
-}
-
 std::unique_ptr<Image> GLES20RenderEngine::createImage() {
     return std::make_unique<GLImage>(*this);
 }
@@ -439,31 +403,6 @@
     return mEGLDisplay == eglGetCurrentDisplay() && mEGLContext == eglGetCurrentContext();
 }
 
-bool GLES20RenderEngine::setCurrentSurface(const Surface& surface) {
-    // Surface is an abstract interface. GLES20RenderEngine only ever
-    // creates GLSurface's, so it is safe to just cast to the actual
-    // type.
-    bool success = true;
-    const GLSurface& glSurface = static_cast<const GLSurface&>(surface);
-    EGLSurface eglSurface = glSurface.getEGLSurface();
-    if (eglSurface != eglGetCurrentSurface(EGL_DRAW)) {
-        success = eglMakeCurrent(mEGLDisplay, eglSurface, eglSurface, mEGLContext) == EGL_TRUE;
-        if (success && glSurface.getAsync()) {
-            eglSwapInterval(mEGLDisplay, 0);
-        }
-        if (success) {
-            mSurfaceHeight = glSurface.getHeight();
-        }
-    }
-
-    return success;
-}
-
-void GLES20RenderEngine::resetCurrentSurface() {
-    eglMakeCurrent(mEGLDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
-    mSurfaceHeight = 0;
-}
-
 base::unique_fd GLES20RenderEngine::flush() {
     if (!GLExtensions::getInstance().hasNativeFenceSync()) {
         return base::unique_fd();
@@ -577,7 +516,7 @@
 
 void GLES20RenderEngine::setScissor(const Rect& region) {
     // Invert y-coordinate to map to GL-space.
-    int32_t canvasHeight = mRenderToFbo ? mFboHeight : mSurfaceHeight;
+    int32_t canvasHeight = mFboHeight;
     int32_t glBottom = canvasHeight - region.bottom;
 
     glScissor(region.left, glBottom, region.getWidth(), region.getHeight());
@@ -620,7 +559,6 @@
     glBindFramebuffer(GL_FRAMEBUFFER, framebufferName);
     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, textureName, 0);
 
-    mRenderToFbo = true;
     mFboHeight = glFramebuffer->getBufferHeight();
 
     uint32_t glStatus = glCheckFramebufferStatus(GL_FRAMEBUFFER);
@@ -632,7 +570,6 @@
 }
 
 void GLES20RenderEngine::unbindFrameBuffer(Framebuffer* /* framebuffer */) {
-    mRenderToFbo = false;
     mFboHeight = 0;
 
     // back to main framebuffer
@@ -661,9 +598,7 @@
     int32_t r = sourceCrop.right;
     int32_t b = sourceCrop.bottom;
     int32_t t = sourceCrop.top;
-    if (mRenderToFbo) {
-        std::swap(t, b);
-    }
+    std::swap(t, b);
     mat4 m = mat4::ortho(l, r, b, t, 0, 1);
 
     // Apply custom rotation to the projection.
@@ -942,6 +877,53 @@
     return GLES_VERSION_1_0;
 }
 
+EGLContext GLES20RenderEngine::createEglContext(EGLDisplay display, EGLConfig config,
+                                                EGLContext shareContext, bool useContextPriority) {
+    EGLint renderableType = 0;
+    if (config == EGL_NO_CONFIG) {
+        renderableType = EGL_OPENGL_ES2_BIT;
+    } else if (!eglGetConfigAttrib(display, config, EGL_RENDERABLE_TYPE, &renderableType)) {
+        LOG_ALWAYS_FATAL("can't query EGLConfig RENDERABLE_TYPE");
+    }
+    EGLint contextClientVersion = 0;
+    if (renderableType & EGL_OPENGL_ES2_BIT) {
+        contextClientVersion = 2;
+    } else if (renderableType & EGL_OPENGL_ES_BIT) {
+        contextClientVersion = 1;
+    } else {
+        LOG_ALWAYS_FATAL("no supported EGL_RENDERABLE_TYPEs");
+    }
+
+    std::vector<EGLint> contextAttributes;
+    contextAttributes.reserve(5);
+    contextAttributes.push_back(EGL_CONTEXT_CLIENT_VERSION);
+    contextAttributes.push_back(contextClientVersion);
+    if (useContextPriority) {
+        contextAttributes.push_back(EGL_CONTEXT_PRIORITY_LEVEL_IMG);
+        contextAttributes.push_back(EGL_CONTEXT_PRIORITY_HIGH_IMG);
+    }
+    contextAttributes.push_back(EGL_NONE);
+
+    return eglCreateContext(display, config, shareContext, contextAttributes.data());
+}
+
+EGLSurface GLES20RenderEngine::createDummyEglPbufferSurface(EGLDisplay display, EGLConfig config,
+                                                            int hwcFormat) {
+    EGLConfig dummyConfig = config;
+    if (dummyConfig == EGL_NO_CONFIG) {
+        dummyConfig = chooseEglConfig(display, hwcFormat, /*logConfig*/ true);
+    }
+    std::vector<EGLint> attributes;
+    attributes.reserve(5);
+    attributes.push_back(EGL_WIDTH);
+    attributes.push_back(1);
+    attributes.push_back(EGL_HEIGHT);
+    attributes.push_back(1);
+    attributes.push_back(EGL_NONE);
+
+    return eglCreatePbufferSurface(display, dummyConfig, attributes.data());
+}
+
 bool GLES20RenderEngine::isHdrDataSpace(const Dataspace dataSpace) const {
     const Dataspace standard = static_cast<Dataspace>(dataSpace & Dataspace::STANDARD_MASK);
     const Dataspace transfer = static_cast<Dataspace>(dataSpace & Dataspace::TRANSFER_MASK);
diff --git a/libs/renderengine/gl/GLES20RenderEngine.h b/libs/renderengine/gl/GLES20RenderEngine.h
index aebb319..77dba62 100644
--- a/libs/renderengine/gl/GLES20RenderEngine.h
+++ b/libs/renderengine/gl/GLES20RenderEngine.h
@@ -40,7 +40,6 @@
 namespace gl {
 
 class GLImage;
-class GLSurface;
 
 class GLES20RenderEngine : public impl::RenderEngine {
 public:
@@ -52,13 +51,10 @@
     ~GLES20RenderEngine() override;
 
     std::unique_ptr<Framebuffer> createFramebuffer() override;
-    std::unique_ptr<Surface> createSurface() override;
     std::unique_ptr<Image> createImage() override;
 
     void primeCache() const override;
     bool isCurrent() const override;
-    bool setCurrentSurface(const Surface& surface) override;
-    void resetCurrentSurface() override;
     base::unique_fd flush() override;
     bool finish() override;
     bool waitFence(base::unique_fd fenceFd) override;
@@ -116,6 +112,10 @@
     };
 
     static GlesVersion parseGlesVersion(const char* str);
+    static EGLContext createEglContext(EGLDisplay display, EGLConfig config,
+                                       EGLContext shareContext, bool useContextPriority);
+    static EGLSurface createDummyEglPbufferSurface(EGLDisplay display, EGLConfig config,
+                                                   int hwcFormat);
 
     // A data space is considered HDR data space if it has BT2020 color space
     // with PQ or HLG transfer function.
@@ -147,8 +147,6 @@
     mat4 mBt2020ToSrgb;
     mat4 mBt2020ToDisplayP3;
 
-    bool mRenderToFbo = false;
-    int32_t mSurfaceHeight = 0;
     int32_t mFboHeight = 0;
 
     // Current dataspace of layer being rendered
diff --git a/libs/renderengine/gl/GLExtensions.cpp b/libs/renderengine/gl/GLExtensions.cpp
index 784693b..ce83dd5 100644
--- a/libs/renderengine/gl/GLExtensions.cpp
+++ b/libs/renderengine/gl/GLExtensions.cpp
@@ -112,6 +112,9 @@
     if (extensionSet.hasExtension("EGL_IMG_context_priority")) {
         mHasContextPriority = true;
     }
+    if (extensionSet.hasExtension("EGL_KHR_surfaceless_context")) {
+        mHasSurfacelessContext = true;
+    }
 }
 
 char const* GLExtensions::getEGLVersion() const {
diff --git a/libs/renderengine/gl/GLExtensions.h b/libs/renderengine/gl/GLExtensions.h
index 382c23a..2a654d5 100644
--- a/libs/renderengine/gl/GLExtensions.h
+++ b/libs/renderengine/gl/GLExtensions.h
@@ -32,29 +32,6 @@
 namespace gl {
 
 class GLExtensions : public Singleton<GLExtensions> {
-    friend class Singleton<GLExtensions>;
-
-    bool mHasNoConfigContext = false;
-    bool mHasNativeFenceSync = false;
-    bool mHasFenceSync = false;
-    bool mHasWaitSync = false;
-    bool mHasProtectedContent = false;
-    bool mHasContextPriority = false;
-
-    String8 mVendor;
-    String8 mRenderer;
-    String8 mVersion;
-    String8 mExtensions;
-
-    String8 mEGLVersion;
-    String8 mEGLExtensions;
-
-    GLExtensions(const GLExtensions&);
-    GLExtensions& operator=(const GLExtensions&);
-
-protected:
-    GLExtensions() = default;
-
 public:
     bool hasNoConfigContext() const { return mHasNoConfigContext; }
     bool hasNativeFenceSync() const { return mHasNativeFenceSync; }
@@ -62,6 +39,7 @@
     bool hasWaitSync() const { return mHasWaitSync; }
     bool hasProtectedContent() const { return mHasProtectedContent; }
     bool hasContextPriority() const { return mHasContextPriority; }
+    bool hasSurfacelessContext() const { return mHasSurfacelessContext; }
 
     void initWithGLStrings(GLubyte const* vendor, GLubyte const* renderer, GLubyte const* version,
                            GLubyte const* extensions);
@@ -73,6 +51,31 @@
     void initWithEGLStrings(char const* eglVersion, char const* eglExtensions);
     char const* getEGLVersion() const;
     char const* getEGLExtensions() const;
+
+protected:
+    GLExtensions() = default;
+
+private:
+    friend class Singleton<GLExtensions>;
+
+    bool mHasNoConfigContext = false;
+    bool mHasNativeFenceSync = false;
+    bool mHasFenceSync = false;
+    bool mHasWaitSync = false;
+    bool mHasProtectedContent = false;
+    bool mHasContextPriority = false;
+    bool mHasSurfacelessContext = false;
+
+    String8 mVendor;
+    String8 mRenderer;
+    String8 mVersion;
+    String8 mExtensions;
+
+    String8 mEGLVersion;
+    String8 mEGLExtensions;
+
+    GLExtensions(const GLExtensions&);
+    GLExtensions& operator=(const GLExtensions&);
 };
 
 } // namespace gl
diff --git a/libs/renderengine/gl/GLSurface.cpp b/libs/renderengine/gl/GLSurface.cpp
deleted file mode 100644
index 2d694e9..0000000
--- a/libs/renderengine/gl/GLSurface.cpp
+++ /dev/null
@@ -1,105 +0,0 @@
-/*
- * Copyright 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "GLSurface.h"
-
-#include <android/native_window.h>
-#include <log/log.h>
-#include <ui/PixelFormat.h>
-#include "GLES20RenderEngine.h"
-
-namespace android {
-namespace renderengine {
-namespace gl {
-
-GLSurface::GLSurface(const GLES20RenderEngine& engine)
-      : mEGLDisplay(engine.getEGLDisplay()), mEGLConfig(engine.getEGLConfig()) {
-    // RE does not assume any config when EGL_KHR_no_config_context is supported
-    if (mEGLConfig == EGL_NO_CONFIG_KHR) {
-        mEGLConfig =
-                GLES20RenderEngine::chooseEglConfig(mEGLDisplay, PIXEL_FORMAT_RGBA_8888, false);
-    }
-}
-
-GLSurface::~GLSurface() {
-    setNativeWindow(nullptr);
-}
-
-void GLSurface::setNativeWindow(ANativeWindow* window) {
-    if (mEGLSurface != EGL_NO_SURFACE) {
-        eglDestroySurface(mEGLDisplay, mEGLSurface);
-        mEGLSurface = EGL_NO_SURFACE;
-        mSurfaceWidth = 0;
-        mSurfaceHeight = 0;
-    }
-
-    mWindow = window;
-    if (mWindow) {
-        mEGLSurface = eglCreateWindowSurface(mEGLDisplay, mEGLConfig, mWindow, nullptr);
-        mSurfaceWidth = ANativeWindow_getWidth(window);
-        mSurfaceHeight = ANativeWindow_getHeight(window);
-    }
-}
-
-void GLSurface::swapBuffers() const {
-    if (!eglSwapBuffers(mEGLDisplay, mEGLSurface)) {
-        EGLint error = eglGetError();
-
-        const char format[] = "eglSwapBuffers(%p, %p) failed with 0x%08x";
-        if (mCritical || error == EGL_CONTEXT_LOST) {
-            LOG_ALWAYS_FATAL(format, mEGLDisplay, mEGLSurface, error);
-        } else {
-            ALOGE(format, mEGLDisplay, mEGLSurface, error);
-        }
-    }
-}
-
-EGLint GLSurface::queryConfig(EGLint attrib) const {
-    EGLint value;
-    if (!eglGetConfigAttrib(mEGLDisplay, mEGLConfig, attrib, &value)) {
-        value = 0;
-    }
-
-    return value;
-}
-
-int32_t GLSurface::queryRedSize() const {
-    return queryConfig(EGL_RED_SIZE);
-}
-
-int32_t GLSurface::queryGreenSize() const {
-    return queryConfig(EGL_GREEN_SIZE);
-}
-
-int32_t GLSurface::queryBlueSize() const {
-    return queryConfig(EGL_BLUE_SIZE);
-}
-
-int32_t GLSurface::queryAlphaSize() const {
-    return queryConfig(EGL_ALPHA_SIZE);
-}
-
-int32_t GLSurface::getWidth() const {
-    return mSurfaceWidth;
-}
-
-int32_t GLSurface::getHeight() const {
-    return mSurfaceHeight;
-}
-
-} // namespace gl
-} // namespace renderengine
-} // namespace android
diff --git a/libs/renderengine/gl/GLSurface.h b/libs/renderengine/gl/GLSurface.h
deleted file mode 100644
index 092d371..0000000
--- a/libs/renderengine/gl/GLSurface.h
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
- * Copyright 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-#include <cstdint>
-
-#include <EGL/egl.h>
-#include <android-base/macros.h>
-#include <renderengine/Surface.h>
-
-struct ANativeWindow;
-
-namespace android {
-namespace renderengine {
-namespace gl {
-
-class GLES20RenderEngine;
-
-class GLSurface final : public renderengine::Surface {
-public:
-    GLSurface(const GLES20RenderEngine& engine);
-    ~GLSurface() override;
-
-    // renderengine::Surface implementation
-    void setCritical(bool enable) override { mCritical = enable; }
-    void setAsync(bool enable) override { mAsync = enable; }
-
-    void setNativeWindow(ANativeWindow* window) override;
-    void swapBuffers() const override;
-
-    int32_t queryRedSize() const override;
-    int32_t queryGreenSize() const override;
-    int32_t queryBlueSize() const override;
-    int32_t queryAlphaSize() const override;
-
-    bool getAsync() const { return mAsync; }
-    EGLSurface getEGLSurface() const { return mEGLSurface; }
-
-    int32_t getWidth() const override;
-    int32_t getHeight() const override;
-
-private:
-    EGLint queryConfig(EGLint attrib) const;
-
-    EGLDisplay mEGLDisplay;
-    EGLConfig mEGLConfig;
-
-    bool mCritical = false;
-    bool mAsync = false;
-
-    int32_t mSurfaceWidth = 0;
-    int32_t mSurfaceHeight = 0;
-
-    ANativeWindow* mWindow = nullptr;
-    EGLSurface mEGLSurface = EGL_NO_SURFACE;
-
-    DISALLOW_COPY_AND_ASSIGN(GLSurface);
-};
-
-} // namespace gl
-} // namespace renderengine
-} // namespace android
diff --git a/libs/renderengine/include/renderengine/RenderEngine.h b/libs/renderengine/include/renderengine/RenderEngine.h
index becb3c3..22891c4 100644
--- a/libs/renderengine/include/renderengine/RenderEngine.h
+++ b/libs/renderengine/include/renderengine/RenderEngine.h
@@ -48,7 +48,6 @@
 class BindNativeBufferAsFramebuffer;
 class Image;
 class Mesh;
-class Surface;
 class Texture;
 
 namespace impl {
@@ -72,7 +71,6 @@
     // used to support legacy behavior.
 
     virtual std::unique_ptr<Framebuffer> createFramebuffer() = 0;
-    virtual std::unique_ptr<Surface> createSurface() = 0;
     virtual std::unique_ptr<Image> createImage() = 0;
 
     virtual void primeCache() const = 0;
@@ -84,8 +82,6 @@
     virtual bool useWaitSync() const = 0;
 
     virtual bool isCurrent() const = 0;
-    virtual bool setCurrentSurface(const Surface& surface) = 0;
-    virtual void resetCurrentSurface() = 0;
 
     // helpers
     // flush submits RenderEngine command stream for execution and returns a
diff --git a/libs/renderengine/include/renderengine/Surface.h b/libs/renderengine/include/renderengine/Surface.h
deleted file mode 100644
index ba7331d..0000000
--- a/libs/renderengine/include/renderengine/Surface.h
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * Copyright 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-#include <cstdint>
-
-struct ANativeWindow;
-
-namespace android {
-namespace renderengine {
-
-class Surface {
-public:
-    virtual ~Surface() = default;
-
-    virtual void setCritical(bool enable) = 0;
-    virtual void setAsync(bool enable) = 0;
-
-    virtual void setNativeWindow(ANativeWindow* window) = 0;
-    virtual void swapBuffers() const = 0;
-
-    virtual int32_t queryRedSize() const = 0;
-    virtual int32_t queryGreenSize() const = 0;
-    virtual int32_t queryBlueSize() const = 0;
-    virtual int32_t queryAlphaSize() const = 0;
-
-    virtual int32_t getWidth() const = 0;
-    virtual int32_t getHeight() const = 0;
-};
-
-} // namespace renderengine
-} // namespace android
diff --git a/services/bufferhub/Android.bp b/services/bufferhub/Android.bp
index 28a7501..b747dbc 100644
--- a/services/bufferhub/Android.bp
+++ b/services/bufferhub/Android.bp
@@ -17,6 +17,7 @@
 cc_library_shared {
     name: "libbufferhubservice",
     cflags: [
+        "-DLOG_TAG=\"libbufferhubservice\"",
         "-Wall",
         "-Werror",
         "-Wextra",
@@ -71,6 +72,7 @@
         "libutils",
     ],
     cflags: [
+        "-DLOG_TAG=\"bufferhub\"",
         "-Wall",
         "-Werror",
         "-Wextra",
diff --git a/services/surfaceflinger/BufferStateLayer.cpp b/services/surfaceflinger/BufferStateLayer.cpp
index 425f5c7..5ffd8ad 100644
--- a/services/surfaceflinger/BufferStateLayer.cpp
+++ b/services/surfaceflinger/BufferStateLayer.cpp
@@ -336,6 +336,9 @@
 }
 
 PixelFormat BufferStateLayer::getPixelFormat() const {
+    if (!mActiveBuffer) {
+        return PIXEL_FORMAT_NONE;
+    }
     return mActiveBuffer->format;
 }
 
diff --git a/services/surfaceflinger/DisplayDevice.cpp b/services/surfaceflinger/DisplayDevice.cpp
index 55ce434..1215bd9 100644
--- a/services/surfaceflinger/DisplayDevice.cpp
+++ b/services/surfaceflinger/DisplayDevice.cpp
@@ -225,7 +225,6 @@
         mNativeWindow(args.nativeWindow),
         mGraphicBuffer(nullptr),
         mDisplaySurface(args.displaySurface),
-        mSurface{std::move(args.renderSurface)},
         mDisplayInstallOrientation(args.displayInstallOrientation),
         mPageFlipCount(0),
         mIsVirtual(args.isVirtual),
@@ -247,7 +246,6 @@
 
     ALOGE_IF(!mNativeWindow, "No native window was set for display");
     ALOGE_IF(!mDisplaySurface, "No display surface was set for display");
-    ALOGE_IF(!mSurface, "No render surface was set for display");
 
     std::vector<Hdr> types = args.hdrCapabilities.getSupportedHdrTypes();
     for (Hdr hdrType : types) {
@@ -443,12 +441,6 @@
     mDisplaySurface->onFrameCommitted();
 }
 
-bool DisplayDevice::makeCurrent() const {
-    bool success = mFlinger->getRenderEngine().setCurrentSurface(*mSurface);
-    setViewportAndProjection();
-    return success;
-}
-
 void DisplayDevice::setViewportAndProjection() const {
     size_t w = mDisplayWidth;
     size_t h = mDisplayHeight;
@@ -611,12 +603,8 @@
 void DisplayDevice::setDisplaySize(const int newWidth, const int newHeight) {
     dirtyRegion.set(getBounds());
 
-    mSurface->setNativeWindow(nullptr);
-
     mDisplaySurface->resizeBuffers(newWidth, newHeight);
 
-    ANativeWindow* const window = mNativeWindow.get();
-    mSurface->setNativeWindow(window);
     mDisplayWidth = newWidth;
     mDisplayHeight = newHeight;
 }
@@ -732,12 +720,11 @@
     ANativeWindow* const window = mNativeWindow.get();
     result.appendFormat("+ %s\n", getDebugName().c_str());
     result.appendFormat("  layerStack=%u, (%4dx%4d), ANativeWindow=%p "
-                        "(%d:%d:%d:%d), orient=%2d (type=%08x), "
-                        "flips=%u, isSecure=%d, powerMode=%d, activeConfig=%d, numLayers=%zu\n",
+                        "format=%d, orient=%2d (type=%08x), flips=%u, isSecure=%d, "
+                        "powerMode=%d, activeConfig=%d, numLayers=%zu\n",
                         mLayerStack, mDisplayWidth, mDisplayHeight, window,
-                        mSurface->queryRedSize(), mSurface->queryGreenSize(),
-                        mSurface->queryBlueSize(), mSurface->queryAlphaSize(), mOrientation,
-                        tr.getType(), getPageFlipCount(), mIsSecure, mPowerMode, mActiveConfig,
+                        ANativeWindow_getFormat(window), mOrientation, tr.getType(),
+                        getPageFlipCount(), mIsSecure, mPowerMode, mActiveConfig,
                         mVisibleLayersSortedByZ.size());
     result.appendFormat("   v:[%d,%d,%d,%d], f:[%d,%d,%d,%d], s:[%d,%d,%d,%d],"
                         "transform:[[%0.3f,%0.3f,%0.3f][%0.3f,%0.3f,%0.3f][%0.3f,%0.3f,%0.3f]]\n",
@@ -748,9 +735,9 @@
     auto const surface = static_cast<Surface*>(window);
     ui::Dataspace dataspace = surface->getBuffersDataSpace();
     result.appendFormat("   wideColorGamut=%d, hdr10=%d, colorMode=%s, dataspace: %s (%d)\n",
-                        mHasWideColorGamut, mHasHdr10,
-                        decodeColorMode(mActiveColorMode).c_str(),
-                        dataspaceDetails(static_cast<android_dataspace>(dataspace)).c_str(), dataspace);
+                        mHasWideColorGamut, mHasHdr10, decodeColorMode(mActiveColorMode).c_str(),
+                        dataspaceDetails(static_cast<android_dataspace>(dataspace)).c_str(),
+                        dataspace);
 
     String8 surfaceDump;
     mDisplaySurface->dumpAsString(surfaceDump);
diff --git a/services/surfaceflinger/DisplayDevice.h b/services/surfaceflinger/DisplayDevice.h
index 560a958..eb2c5c3 100644
--- a/services/surfaceflinger/DisplayDevice.h
+++ b/services/surfaceflinger/DisplayDevice.h
@@ -24,12 +24,13 @@
 #include <string>
 #include <unordered_map>
 
+#include <android/native_window.h>
 #include <binder/IBinder.h>
 #include <gui/LayerState.h>
 #include <hardware/hwcomposer_defs.h>
 #include <math/mat4.h>
 #include <renderengine/RenderEngine.h>
-#include <renderengine/Surface.h>
+#include <system/window.h>
 #include <ui/GraphicTypes.h>
 #include <ui/HdrCapabilities.h>
 #include <ui/Region.h>
@@ -42,8 +43,6 @@
 #include "DisplayHardware/DisplayIdentification.h"
 #include "RenderArea.h"
 
-struct ANativeWindow;
-
 namespace android {
 
 class DisplaySurface;
@@ -163,7 +162,6 @@
     void setDisplayName(const std::string& displayName);
     const std::string& getDisplayName() const { return mDisplayName; }
 
-    bool makeCurrent() const;
     // Acquires a new buffer for GPU composition.
     void readyNewBuffer();
     // Marks the current buffer has finished, so that it can be presented and
@@ -220,7 +218,6 @@
     // that drawing to the buffer is now complete.
     base::unique_fd mBufferReady;
 
-    std::unique_ptr<renderengine::Surface> mSurface;
     int             mDisplayWidth;
     int             mDisplayHeight;
     const int       mDisplayInstallOrientation;
@@ -340,7 +337,6 @@
     bool isSecure{false};
     sp<ANativeWindow> nativeWindow;
     sp<DisplaySurface> displaySurface;
-    std::unique_ptr<renderengine::Surface> renderSurface;
     int displayInstallOrientation{DisplayState::eOrientationDefault};
     bool hasWideColorGamut{false};
     HdrCapabilities hdrCapabilities;
diff --git a/services/surfaceflinger/DisplayHardware/HWComposer.cpp b/services/surfaceflinger/DisplayHardware/HWComposer.cpp
index 0f25b52..9bbc37f 100644
--- a/services/surfaceflinger/DisplayHardware/HWComposer.cpp
+++ b/services/surfaceflinger/DisplayHardware/HWComposer.cpp
@@ -20,31 +20,12 @@
 #define LOG_TAG "HWComposer"
 #define ATRACE_TAG ATRACE_TAG_GRAPHICS
 
-#include <inttypes.h>
-#include <math.h>
-#include <stdint.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/types.h>
-
 #include <utils/Errors.h>
-#include <utils/misc.h>
-#include <utils/NativeHandle.h>
-#include <utils/String8.h>
-#include <utils/Thread.h>
 #include <utils/Trace.h>
-#include <utils/Vector.h>
 
 #include <ui/DebugUtils.h>
 #include <ui/GraphicBuffer.h>
 
-#include <hardware/hardware.h>
-#include <hardware/hwcomposer.h>
-
-#include <android/configuration.h>
-
-#include <cutils/properties.h>
 #include <log/log.h>
 
 #include "HWComposer.h"
@@ -85,11 +66,7 @@
 
 namespace android {
 
-#define MIN_HWC_HEADER_VERSION HWC_HEADER_VERSION
-
-// ---------------------------------------------------------------------------
-
-HWComposer::HWComposer(std::unique_ptr<android::Hwc2::Composer> composer)
+HWComposer::HWComposer(std::unique_ptr<Hwc2::Composer> composer)
       : mHwcDevice(std::make_unique<HWC2::Device>(std::move(composer))) {}
 
 HWComposer::~HWComposer() {
@@ -184,30 +161,31 @@
 
     RETURN_IF_INVALID_DISPLAY(*displayId, false);
 
-    const auto& displayData = mDisplayData[*displayId];
+    auto& displayData = mDisplayData[*displayId];
     if (displayData.isVirtual) {
         LOG_DISPLAY_ERROR(*displayId, "Invalid operation on virtual display");
         return false;
     }
 
     {
-        Mutex::Autolock _l(mLock);
+        std::lock_guard lock(displayData.lastHwVsyncLock);
 
         // There have been reports of HWCs that signal several vsync events
         // with the same timestamp when turning the display off and on. This
         // is a bug in the HWC implementation, but filter the extra events
         // out here so they don't cause havoc downstream.
-        if (timestamp == mLastHwVSync[*displayId]) {
+        if (timestamp == displayData.lastHwVsync) {
             ALOGW("Ignoring duplicate VSYNC event from HWC for display %s (t=%" PRId64 ")",
                   to_string(*displayId).c_str(), timestamp);
             return false;
         }
 
-        mLastHwVSync[*displayId] = timestamp;
+        displayData.lastHwVsync = timestamp;
     }
 
     const auto tag = "HW_VSYNC_" + to_string(*displayId);
-    ATRACE_INT(tag.c_str(), ++mVSyncCounts[*displayId] & 1);
+    ATRACE_INT(tag.c_str(), displayData.vsyncTraceToggle);
+    displayData.vsyncTraceToggle = !displayData.vsyncTraceToggle;
 
     return true;
 }
@@ -270,13 +248,14 @@
 
 nsecs_t HWComposer::getRefreshTimestamp(DisplayId displayId) const {
     RETURN_IF_INVALID_DISPLAY(displayId, 0);
+    const auto& displayData = mDisplayData.at(displayId);
     // this returns the last refresh timestamp.
     // if the last one is not available, we estimate it based on
     // the refresh period and whatever closest timestamp we have.
-    Mutex::Autolock _l(mLock);
+    std::lock_guard lock(displayData.lastHwVsyncLock);
     nsecs_t now = systemTime(CLOCK_MONOTONIC);
     auto vsyncPeriod = getActiveConfig(displayId)->getVsyncPeriod();
-    return now - ((now - mLastHwVSync[displayId]) % vsyncPeriod);
+    return now - ((now - displayData.lastHwVsync) % vsyncPeriod);
 }
 
 bool HWComposer::isConnected(DisplayId displayId) const {
@@ -375,17 +354,19 @@
     // into the HWC with the lock held, and we want to make sure
     // that even if HWC blocks (which it shouldn't), it won't
     // affect other threads.
-    Mutex::Autolock _l(mVsyncLock);
-    if (enabled != displayData.vsyncEnabled) {
-        ATRACE_CALL();
-        auto error = displayData.hwcDisplay->setVsyncEnabled(enabled);
-        RETURN_IF_HWC_ERROR(error, displayId);
-
-        displayData.vsyncEnabled = enabled;
-
-        const auto tag = "HW_VSYNC_ON_" + to_string(displayId);
-        ATRACE_INT(tag.c_str(), enabled == HWC2::Vsync::Enable ? 1 : 0);
+    std::lock_guard lock(displayData.vsyncEnabledLock);
+    if (enabled == displayData.vsyncEnabled) {
+        return;
     }
+
+    ATRACE_CALL();
+    auto error = displayData.hwcDisplay->setVsyncEnabled(enabled);
+    RETURN_IF_HWC_ERROR(error, displayId);
+
+    displayData.vsyncEnabled = enabled;
+
+    const auto tag = "HW_VSYNC_ON_" + to_string(displayId);
+    ATRACE_INT(tag.c_str(), enabled == HWC2::Vsync::Enable ? 1 : 0);
 }
 
 status_t HWComposer::setClientTarget(DisplayId displayId, uint32_t slot,
@@ -405,8 +386,6 @@
 
     RETURN_IF_INVALID_DISPLAY(displayId, BAD_INDEX);
 
-    Mutex::Autolock _l(mDisplayLock);
-
     auto& displayData = mDisplayData[displayId];
     auto& hwcDisplay = displayData.hwcDisplay;
     if (!hwcDisplay->isConnected()) {
@@ -428,7 +407,7 @@
     // back to validate when there is any client layer.
     displayData.validateWasSkipped = false;
     if (!displayData.hasClientComposition) {
-        sp<android::Fence> outPresentFence;
+        sp<Fence> outPresentFence;
         uint32_t state = UINT32_MAX;
         error = hwcDisplay->presentOrValidate(&numTypes, &numRequests, &outPresentFence , &state);
         if (error != HWC2::Error::HasChanges) {
@@ -689,7 +668,6 @@
     const auto hwcDisplayId = displayData.hwcDisplay->getId();
     mPhysicalDisplayIdMap.erase(hwcDisplayId);
     mDisplayData.erase(displayId);
-    mVSyncCounts.erase(displayId);
 
     // TODO(b/74619554): Select internal/external display from remaining displays.
     if (hwcDisplayId == mInternalHwcDisplayId) {
@@ -755,26 +733,6 @@
     return matrix;
 }
 
-// Converts a PixelFormat to a human-readable string.  Max 11 chars.
-// (Could use a table of prefab String8 objects.)
-/*
-static String8 getFormatStr(PixelFormat format) {
-    switch (format) {
-    case PIXEL_FORMAT_RGBA_8888:    return String8("RGBA_8888");
-    case PIXEL_FORMAT_RGBX_8888:    return String8("RGBx_8888");
-    case PIXEL_FORMAT_RGB_888:      return String8("RGB_888");
-    case PIXEL_FORMAT_RGB_565:      return String8("RGB_565");
-    case PIXEL_FORMAT_BGRA_8888:    return String8("BGRA_8888");
-    case HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED:
-                                    return String8("ImplDef");
-    default:
-        String8 result;
-        result.appendFormat("? %08x", format);
-        return result;
-    }
-}
-*/
-
 bool HWComposer::isUsingVrComposer() const {
     return getComposer()->isUsingVrComposer();
 }
diff --git a/services/surfaceflinger/DisplayHardware/HWComposer.h b/services/surfaceflinger/DisplayHardware/HWComposer.h
index b78433d..2f57907 100644
--- a/services/surfaceflinger/DisplayHardware/HWComposer.h
+++ b/services/surfaceflinger/DisplayHardware/HWComposer.h
@@ -17,49 +17,26 @@
 #ifndef ANDROID_SF_HWCOMPOSER_H
 #define ANDROID_SF_HWCOMPOSER_H
 
-#include "HWC2.h"
-
-#include <stdint.h>
-#include <sys/types.h>
-
-#include <ui/Fence.h>
-#include <ui/GraphicTypes.h>
-#include <utils/BitSet.h>
-#include <utils/Condition.h>
-#include <utils/Mutex.h>
-#include <utils/StrongPointer.h>
-#include <utils/Thread.h>
-#include <utils/Timers.h>
-#include <utils/Vector.h>
-
+#include <cstdint>
 #include <memory>
+#include <mutex>
 #include <optional>
 #include <unordered_map>
 #include <unordered_set>
 #include <vector>
 
+#include <android-base/thread_annotations.h>
+#include <ui/Fence.h>
+#include <ui/GraphicTypes.h>
+#include <utils/StrongPointer.h>
+#include <utils/Timers.h>
+
 #include "DisplayIdentification.h"
-
-extern "C" int clock_nanosleep(clockid_t clock_id, int flags,
-                           const struct timespec *request,
-                           struct timespec *remain);
-
-struct framebuffer_device_t;
-
-namespace HWC2 {
-    class Device;
-    class Display;
-}
+#include "HWC2.h"
 
 namespace android {
-// ---------------------------------------------------------------------------
 
-class DisplayDevice;
-class Fence;
-class FloatRect;
 class GraphicBuffer;
-class NativeHandle;
-class Region;
 class String8;
 class TestableSurfaceFlinger;
 struct CompositionInfo;
@@ -71,7 +48,7 @@
 class HWComposer
 {
 public:
-    explicit HWComposer(std::unique_ptr<android::Hwc2::Composer> composer);
+    explicit HWComposer(std::unique_ptr<Hwc2::Composer> composer);
 
     ~HWComposer();
 
@@ -177,7 +154,7 @@
     // for debugging ----------------------------------------------------------
     void dump(String8& out) const;
 
-    android::Hwc2::Composer* getComposer() const { return mHwcDevice->getComposer(); }
+    Hwc2::Composer* getComposer() const { return mHwcDevice->getComposer(); }
 
     // TODO(b/74619554): Remove special cases for internal/external display.
     std::optional<hwc2_display_t> getInternalHwcDisplayId() const { return mInternalHwcDisplayId; }
@@ -194,8 +171,6 @@
 
     static void validateChange(HWC2::Composition from, HWC2::Composition to);
 
-    struct cb_context;
-
     struct DisplayData {
         bool isVirtual = false;
         bool hasClientComposition = false;
@@ -209,11 +184,16 @@
         mutable std::unordered_map<int32_t,
                 std::shared_ptr<const HWC2::Display::Config>> configMap;
 
-        // protected by mVsyncLock
-        HWC2::Vsync vsyncEnabled = HWC2::Vsync::Disable;
-
         bool validateWasSkipped;
         HWC2::Error presentError;
+
+        bool vsyncTraceToggle = false;
+
+        std::mutex vsyncEnabledLock;
+        HWC2::Vsync vsyncEnabled GUARDED_BY(vsyncEnabledLock) = HWC2::Vsync::Disable;
+
+        mutable std::mutex lastHwVsyncLock;
+        nsecs_t lastHwVsync GUARDED_BY(lastHwVsyncLock) = 0;
     };
 
     std::unordered_map<DisplayId, DisplayData> mDisplayData;
@@ -227,25 +207,11 @@
     std::optional<hwc2_display_t> mExternalHwcDisplayId;
     bool mHasMultiDisplaySupport = false;
 
-    // protect mDisplayData from races between prepare and dump
-    mutable Mutex mDisplayLock;
-
-    cb_context* mCBContext = nullptr;
-    std::unordered_map<DisplayId, size_t> mVSyncCounts;
-
     std::unordered_set<DisplayId> mFreeVirtualDisplayIds;
     uint32_t mNextVirtualDisplayId = 0;
     uint32_t mRemainingHwcVirtualDisplays{mHwcDevice->getMaxVirtualDisplayCount()};
-
-    // protected by mLock
-    mutable Mutex mLock;
-    mutable std::unordered_map<DisplayId, nsecs_t> mLastHwVSync;
-
-    // thread-safe
-    mutable Mutex mVsyncLock;
 };
 
-// ---------------------------------------------------------------------------
-}; // namespace android
+} // namespace android
 
 #endif // ANDROID_SF_HWCOMPOSER_H
diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp
index 1e910ce..f3182be 100644
--- a/services/surfaceflinger/Layer.cpp
+++ b/services/surfaceflinger/Layer.cpp
@@ -1021,6 +1021,10 @@
 uint32_t Layer::doTransaction(uint32_t flags) {
     ATRACE_CALL();
 
+    if (mLayerDetached) {
+        return 0;
+    }
+
     pushPendingState();
     State c = getCurrentState();
     if (!applyPendingStates(&c)) {
@@ -1553,6 +1557,9 @@
         return false;
     }
 
+    if (attachChildren()) {
+        setTransactionFlags(eTransactionNeeded);
+    }
     for (const sp<Layer>& child : mCurrentChildren) {
         newParent->addChild(child);
 
@@ -1597,6 +1604,13 @@
         client->updateParent(newParent);
     }
 
+    if (mLayerDetached) {
+        mLayerDetached = false;
+        setTransactionFlags(eTransactionNeeded);
+    }
+    if (attachChildren()) {
+        setTransactionFlags(eTransactionNeeded);
+    }
     return true;
 }
 
@@ -1605,7 +1619,7 @@
         sp<Client> parentClient = mClientRef.promote();
         sp<Client> client(child->mClientRef.promote());
         if (client != nullptr && parentClient != client) {
-            client->detachLayer(child.get());
+            child->mLayerDetached = true;
             child->detachChildren();
         }
     }
@@ -1613,6 +1627,23 @@
     return true;
 }
 
+bool Layer::attachChildren() {
+    bool changed = false;
+    for (const sp<Layer>& child : mCurrentChildren) {
+        sp<Client> parentClient = mClientRef.promote();
+        sp<Client> client(child->mClientRef.promote());
+        if (client != nullptr && parentClient != client) {
+            if (child->mLayerDetached) {
+                child->mLayerDetached = false;
+                changed = true;
+            }
+            changed |= child->attachChildren();
+        }
+    }
+
+    return changed;
+}
+
 bool Layer::setColorTransform(const mat4& matrix) {
     static const mat4 identityMatrix = mat4();
 
diff --git a/services/surfaceflinger/Layer.h b/services/surfaceflinger/Layer.h
index 40ebe1e..ed51c61 100644
--- a/services/surfaceflinger/Layer.h
+++ b/services/surfaceflinger/Layer.h
@@ -263,6 +263,8 @@
     virtual void setChildrenDrawingParent(const sp<Layer>& layer);
     virtual bool reparent(const sp<IBinder>& newParentHandle);
     virtual bool detachChildren();
+    bool attachChildren();
+    bool isLayerDetached() const { return mLayerDetached; }
     virtual bool setColorTransform(const mat4& matrix);
     virtual const mat4& getColorTransform() const;
     virtual bool hasColorTransform() const;
@@ -355,7 +357,6 @@
     // to avoid grabbing the lock again to avoid deadlock
     virtual bool isCreatedFromMainThread() const { return false; }
 
-
     bool isRemovedFromCurrentState() const;
 
     void writeToProto(LayerProto* layerInfo,
@@ -776,6 +777,9 @@
 
     mutable LayerBE mBE;
 
+    // Can only be accessed with the SF state lock held.
+    bool mLayerDetached{false};
+
 private:
     /**
      * Returns an unsorted vector of all layers that are part of this tree.
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index d81dea9..8e694fd 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -1683,8 +1683,6 @@
     mDrawingState.colorMatrixChanged = false;
 
     for (const auto& [token, display] : mDisplays) {
-        getBE().mCompositionInfo[token].clear();
-
         for (auto& layer : display->getVisibleLayersSortedByZ()) {
             const auto displayId = display->getId();
             layer->getBE().compositionInfo.compositionType = layer->getCompositionType(displayId);
@@ -1968,6 +1966,17 @@
     ATRACE_CALL();
     ALOGV("rebuildLayerStacks");
 
+    // We need to clear these out now as these may be holding on to a
+    // HWC2::Layer reference at the same time as the LayerBE::HWCInfo structure
+    // also holds a reference. When the set of visible layers is recomputed,
+    // some layers may be destroyed if the only thing keeping them alive was
+    // that list of visible layers associated with each display. The layer
+    // destruction code asserts that the HWC2::Layer is properly destroyed, but
+    // that doesn't happen if SurfaceFlingerBE::mCompositionInfo keeps it alive.
+    for (const auto& [token, display] : mDisplays) {
+        getBE().mCompositionInfo[token].clear();
+    }
+
     // rebuild the visible layer list per screen
     if (CC_UNLIKELY(mVisibleRegionsDirty)) {
         ATRACE_NAME("rebuildLayerStacks VR Dirty");
@@ -2341,14 +2350,6 @@
     auto nativeWindow = nativeWindowSurface->getNativeWindow();
     creationArgs.nativeWindow = nativeWindow;
 
-    /*
-     * Create our display's surface
-     */
-    std::unique_ptr<renderengine::Surface> renderSurface = getRenderEngine().createSurface();
-    renderSurface->setCritical(isInternalDisplay);
-    renderSurface->setAsync(state.isVirtual());
-    creationArgs.renderSurface = std::move(renderSurface);
-
     // Make sure that composition can never be stalled by a virtual display
     // consumer that isn't processing buffers fast enough. We have to do this
     // here, in case the display is composed entirely by HWC.
@@ -3202,6 +3203,10 @@
 }
 
 status_t SurfaceFlinger::removeLayerLocked(const Mutex& lock, const sp<Layer>& layer) {
+    if (layer->isLayerDetached()) {
+        return NO_ERROR;
+    }
+
     const auto& p = layer->getParent();
     ssize_t index;
     if (p != nullptr) {
diff --git a/services/surfaceflinger/TimeStats/timestatsproto/TimeStatsHelper.cpp b/services/surfaceflinger/TimeStats/timestatsproto/TimeStatsHelper.cpp
index 599ff5c..75ce4be 100644
--- a/services/surfaceflinger/TimeStats/timestatsproto/TimeStatsHelper.cpp
+++ b/services/surfaceflinger/TimeStats/timestatsproto/TimeStatsHelper.cpp
@@ -13,8 +13,10 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+#include "timestatsproto/TimeStatsHelper.h"
+
 #include <android-base/stringprintf.h>
-#include <timestatsproto/TimeStatsHelper.h>
+#include <inttypes.h>
 
 #include <array>
 
@@ -46,6 +48,14 @@
     hist[*iter]++;
 }
 
+int64_t TimeStatsHelper::Histogram::totalTime() const {
+    int64_t ret = 0;
+    for (const auto& ele : hist) {
+        ret += ele.first * ele.second;
+    }
+    return ret;
+}
+
 float TimeStatsHelper::Histogram::averageTime() const {
     int64_t ret = 0;
     int64_t count = 0;
@@ -87,12 +97,13 @@
 
 std::string TimeStatsHelper::TimeStatsGlobal::toString(std::optional<uint32_t> maxLayers) const {
     std::string result = "SurfaceFlinger TimeStats:\n";
-    StringAppendF(&result, "statsStart = %lld\n", static_cast<long long int>(statsStart));
-    StringAppendF(&result, "statsEnd = %lld\n", static_cast<long long int>(statsEnd));
+    StringAppendF(&result, "statsStart = %" PRId64 "\n", statsStart);
+    StringAppendF(&result, "statsEnd = %" PRId64 "\n", statsEnd);
     StringAppendF(&result, "totalFrames = %d\n", totalFrames);
     StringAppendF(&result, "missedFrames = %d\n", missedFrames);
     StringAppendF(&result, "clientCompositionFrames = %d\n", clientCompositionFrames);
-    StringAppendF(&result, "displayOnTime = %lld ms\n", static_cast<long long int>(displayOnTime));
+    StringAppendF(&result, "displayOnTime = %" PRId64 " ms\n", displayOnTime);
+    StringAppendF(&result, "totalP2PTime = %" PRId64 " ms\n", presentToPresent.totalTime());
     StringAppendF(&result, "presentToPresent histogram is as below:\n");
     result.append(presentToPresent.toString());
     const auto dumpStats = generateDumpStats(maxLayers);
diff --git a/services/surfaceflinger/TimeStats/timestatsproto/include/timestatsproto/TimeStatsHelper.h b/services/surfaceflinger/TimeStats/timestatsproto/include/timestatsproto/TimeStatsHelper.h
index 7d0fe79..5f40a1a 100644
--- a/services/surfaceflinger/TimeStats/timestatsproto/include/timestatsproto/TimeStatsHelper.h
+++ b/services/surfaceflinger/TimeStats/timestatsproto/include/timestatsproto/TimeStatsHelper.h
@@ -34,6 +34,7 @@
         std::unordered_map<int32_t, int32_t> hist;
 
         void insert(int32_t delta);
+        int64_t totalTime() const;
         float averageTime() const;
         std::string toString() const;
     };
diff --git a/services/surfaceflinger/TransactionCompletedThread.cpp b/services/surfaceflinger/TransactionCompletedThread.cpp
index 9b9dc57..389118a 100644
--- a/services/surfaceflinger/TransactionCompletedThread.cpp
+++ b/services/surfaceflinger/TransactionCompletedThread.cpp
@@ -30,6 +30,8 @@
 namespace android {
 
 TransactionCompletedThread::~TransactionCompletedThread() {
+    std::lock_guard lockThread(mThreadMutex);
+
     {
         std::lock_guard lock(mMutex);
         mKeepRunning = false;
@@ -50,11 +52,13 @@
 
 void TransactionCompletedThread::run() {
     std::lock_guard lock(mMutex);
-    if (mRunning) {
+    if (mRunning || !mKeepRunning) {
         return;
     }
     mDeathRecipient = new ThreadDeathRecipient();
     mRunning = true;
+
+    std::lock_guard lockThread(mThreadMutex);
     mThread = std::thread(&TransactionCompletedThread::threadMain, this);
 }
 
diff --git a/services/surfaceflinger/TransactionCompletedThread.h b/services/surfaceflinger/TransactionCompletedThread.h
index 5af4097..1612f69 100644
--- a/services/surfaceflinger/TransactionCompletedThread.h
+++ b/services/surfaceflinger/TransactionCompletedThread.h
@@ -90,7 +90,10 @@
         }
     };
 
-    std::thread mThread;
+    // Protects the creation and destruction of mThread
+    std::mutex mThreadMutex;
+
+    std::thread mThread GUARDED_BY(mThreadMutex);
 
     std::mutex mMutex;
     std::condition_variable_any mConditionVariable;
diff --git a/services/surfaceflinger/tests/Transaction_test.cpp b/services/surfaceflinger/tests/Transaction_test.cpp
index 988454a..a600a0a 100644
--- a/services/surfaceflinger/tests/Transaction_test.cpp
+++ b/services/surfaceflinger/tests/Transaction_test.cpp
@@ -3356,6 +3356,61 @@
     }
 }
 
+TEST_F(ChildLayerTest, DetachChildrenThenAttach) {
+    sp<SurfaceComposerClient> newComposerClient = new SurfaceComposerClient;
+    sp<SurfaceControl> childNewClient =
+            newComposerClient->createSurface(String8("New Child Test Surface"), 10, 10,
+                                             PIXEL_FORMAT_RGBA_8888, 0, mFGSurfaceControl.get());
+
+    ASSERT_TRUE(childNewClient != nullptr);
+    ASSERT_TRUE(childNewClient->isValid());
+
+    fillSurfaceRGBA8(childNewClient, 200, 200, 200);
+
+    Transaction()
+            .hide(mChild)
+            .show(childNewClient)
+            .setPosition(childNewClient, 10, 10)
+            .setPosition(mFGSurfaceControl, 64, 64)
+            .apply();
+
+    {
+        mCapture = screenshot();
+        // Top left of foreground must now be visible
+        mCapture->expectFGColor(64, 64);
+        // But 10 pixels in we should see the child surface
+        mCapture->expectChildColor(74, 74);
+        // And 10 more pixels we should be back to the foreground surface
+        mCapture->expectFGColor(84, 84);
+    }
+
+    Transaction().detachChildren(mFGSurfaceControl).apply();
+    Transaction().hide(childNewClient).apply();
+
+    // Nothing should have changed.
+    {
+        mCapture = screenshot();
+        mCapture->expectFGColor(64, 64);
+        mCapture->expectChildColor(74, 74);
+        mCapture->expectFGColor(84, 84);
+    }
+
+    sp<SurfaceControl> newParentSurface = createLayer(String8("New Parent Surface"), 32, 32, 0);
+    fillLayerColor(ISurfaceComposerClient::eFXSurfaceBufferQueue, newParentSurface, Color::RED, 32,
+                   32);
+    Transaction()
+            .setLayer(newParentSurface, INT32_MAX - 1)
+            .show(newParentSurface)
+            .setPosition(newParentSurface, 20, 20)
+            .reparent(childNewClient, newParentSurface->getHandle())
+            .apply();
+    {
+        mCapture = screenshot();
+        // Child is now hidden.
+        mCapture->expectColor(Rect(20, 20, 52, 52), Color::RED);
+    }
+}
+
 TEST_F(ChildLayerTest, ChildrenInheritNonTransformScalingFromParent) {
     asTransaction([&](Transaction& t) {
         t.show(mChild);
diff --git a/services/surfaceflinger/tests/unittests/CompositionTest.cpp b/services/surfaceflinger/tests/unittests/CompositionTest.cpp
index 6d3e715..cfaf495 100644
--- a/services/surfaceflinger/tests/unittests/CompositionTest.cpp
+++ b/services/surfaceflinger/tests/unittests/CompositionTest.cpp
@@ -94,6 +94,10 @@
         EXPECT_CALL(*mPrimaryDispSync, computeNextRefresh(0)).WillRepeatedly(Return(0));
         EXPECT_CALL(*mPrimaryDispSync, getPeriod())
                 .WillRepeatedly(Return(FakeHwcDisplayInjector::DEFAULT_REFRESH_RATE));
+        EXPECT_CALL(*mNativeWindow, query(NATIVE_WINDOW_WIDTH, _))
+                .WillRepeatedly(DoAll(SetArgPointee<1>(DEFAULT_DISPLAY_WIDTH), Return(0)));
+        EXPECT_CALL(*mNativeWindow, query(NATIVE_WINDOW_HEIGHT, _))
+                .WillRepeatedly(DoAll(SetArgPointee<1>(DEFAULT_DISPLAY_HEIGHT), Return(0)));
 
         mFlinger.setupRenderEngine(std::unique_ptr<renderengine::RenderEngine>(mRenderEngine));
         setupComposer(0);
@@ -140,7 +144,6 @@
     sp<DisplayDevice> mDisplay;
     sp<DisplayDevice> mExternalDisplay;
     sp<mock::DisplaySurface> mDisplaySurface = new mock::DisplaySurface();
-    renderengine::mock::Surface* mRenderSurface = new renderengine::mock::Surface();
     mock::NativeWindow* mNativeWindow = new mock::NativeWindow();
 
     sp<GraphicBuffer> mBuffer = new GraphicBuffer();
@@ -246,8 +249,6 @@
         test->mDisplay = FakeDisplayDeviceInjector(test->mFlinger, DEFAULT_DISPLAY_ID,
                                                    false /* isVirtual */, true /* isPrimary */)
                                  .setDisplaySurface(test->mDisplaySurface)
-                                 .setRenderSurface(std::unique_ptr<renderengine::Surface>(
-                                         test->mRenderSurface))
                                  .setNativeWindow(test->mNativeWindow)
                                  .setSecure(Derived::IS_SECURE)
                                  .setPowerMode(Derived::INIT_POWER_MODE)
diff --git a/services/surfaceflinger/tests/unittests/DisplayTransactionTest.cpp b/services/surfaceflinger/tests/unittests/DisplayTransactionTest.cpp
index e8c8894..5aaf848 100644
--- a/services/surfaceflinger/tests/unittests/DisplayTransactionTest.cpp
+++ b/services/surfaceflinger/tests/unittests/DisplayTransactionTest.cpp
@@ -135,7 +135,6 @@
     sp<mock::GraphicBufferConsumer> mConsumer;
     sp<mock::GraphicBufferProducer> mProducer;
     surfaceflinger::mock::NativeWindowSurface* mNativeWindowSurface = nullptr;
-    renderengine::mock::Surface* mRenderSurface = nullptr;
 };
 
 DisplayTransactionTest::DisplayTransactionTest() {
@@ -342,22 +341,10 @@
         EXPECT_CALL(*test->mNativeWindowSurface, getNativeWindow())
                 .WillOnce(Return(test->mNativeWindow));
 
-        // For simplicity, we only expect to create a single render surface for
-        // each test.
-        ASSERT_TRUE(test->mRenderSurface == nullptr);
-        test->mRenderSurface = new renderengine::mock::Surface();
-        EXPECT_CALL(*test->mRenderEngine, createSurface())
-                .WillOnce(Return(ByMove(
-                        std::unique_ptr<renderengine::Surface>(test->mRenderSurface))));
         EXPECT_CALL(*test->mNativeWindow, query(NATIVE_WINDOW_WIDTH, _))
                 .WillRepeatedly(DoAll(SetArgPointee<1>(WIDTH), Return(0)));
         EXPECT_CALL(*test->mNativeWindow, query(NATIVE_WINDOW_HEIGHT, _))
                 .WillRepeatedly(DoAll(SetArgPointee<1>(HEIGHT), Return(0)));
-
-        // Creating a DisplayDevice requires getting default dimensions from the
-        // native window.
-        EXPECT_CALL(*test->mRenderSurface, setAsync(static_cast<bool>(ASYNC))).Times(1);
-        EXPECT_CALL(*test->mRenderSurface, setCritical(static_cast<bool>(CRITICAL))).Times(1);
     }
 
     static void setupFramebufferConsumerBufferQueueCallExpectations(DisplayTransactionTest* test) {
@@ -1285,7 +1272,7 @@
     // Insert display data so that the HWC thinks it created the virtual display.
     const auto displayId = Case::Display::DISPLAY_ID::get();
     ASSERT_TRUE(displayId);
-    mFlinger.mutableHwcDisplayData()[*displayId] = {};
+    mFlinger.mutableHwcDisplayData().try_emplace(*displayId);
 
     setupNewDisplayDeviceInternalTest<Case>();
 }
@@ -1798,7 +1785,7 @@
     // A virtual display is set up but is removed from the current state.
     const auto displayId = Case::Display::DISPLAY_ID::get();
     ASSERT_TRUE(displayId);
-    mFlinger.mutableHwcDisplayData()[*displayId] = {};
+    mFlinger.mutableHwcDisplayData().try_emplace(*displayId);
     Case::Display::injectHwcDisplay(this);
     auto existing = Case::Display::makeFakeExistingDisplayInjector(this);
     existing.inject();
@@ -1946,12 +1933,10 @@
     // A display is set up
     auto nativeWindow = new mock::NativeWindow();
     auto displaySurface = new mock::DisplaySurface();
-    auto renderSurface = new renderengine::mock::Surface();
     sp<GraphicBuffer> buf = new GraphicBuffer();
     auto display = Case::Display::makeFakeExistingDisplayInjector(this);
     display.setNativeWindow(nativeWindow);
     display.setDisplaySurface(displaySurface);
-    display.setRenderSurface(std::unique_ptr<renderengine::Surface>(renderSurface));
     // Setup injection expections
     EXPECT_CALL(*nativeWindow, query(NATIVE_WINDOW_WIDTH, _))
             .WillOnce(DoAll(SetArgPointee<1>(oldWidth), Return(0)));
@@ -1992,12 +1977,10 @@
     // A display is set up
     auto nativeWindow = new mock::NativeWindow();
     auto displaySurface = new mock::DisplaySurface();
-    auto renderSurface = new renderengine::mock::Surface();
     sp<GraphicBuffer> buf = new GraphicBuffer();
     auto display = Case::Display::makeFakeExistingDisplayInjector(this);
     display.setNativeWindow(nativeWindow);
     display.setDisplaySurface(displaySurface);
-    display.setRenderSurface(std::unique_ptr<renderengine::Surface>(renderSurface));
     // Setup injection expections
     EXPECT_CALL(*nativeWindow, query(NATIVE_WINDOW_WIDTH, _))
             .WillOnce(DoAll(SetArgPointee<1>(oldWidth), Return(0)));
@@ -2931,7 +2914,7 @@
     // Insert display data so that the HWC thinks it created the virtual display.
     const auto displayId = Case::Display::DISPLAY_ID::get();
     ASSERT_TRUE(displayId);
-    mFlinger.mutableHwcDisplayData()[*displayId] = {};
+    mFlinger.mutableHwcDisplayData().try_emplace(*displayId);
 
     // A virtual display device is set up
     Case::Display::injectHwcDisplay(this);
diff --git a/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h b/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h
index a519f1f..85c835e 100644
--- a/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h
+++ b/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h
@@ -474,11 +474,6 @@
             return *this;
         }
 
-        auto& setRenderSurface(std::unique_ptr<renderengine::Surface> renderSurface) {
-            mCreationArgs.renderSurface = std::move(renderSurface);
-            return *this;
-        }
-
         auto& setSecure(bool secure) {
             mCreationArgs.isSecure = secure;
             return *this;
diff --git a/services/surfaceflinger/tests/unittests/mock/RenderEngine/MockRenderEngine.cpp b/services/surfaceflinger/tests/unittests/mock/RenderEngine/MockRenderEngine.cpp
index af54df6..fbfbc3f 100644
--- a/services/surfaceflinger/tests/unittests/mock/RenderEngine/MockRenderEngine.cpp
+++ b/services/surfaceflinger/tests/unittests/mock/RenderEngine/MockRenderEngine.cpp
@@ -26,9 +26,6 @@
 RenderEngine::RenderEngine() = default;
 RenderEngine::~RenderEngine() = default;
 
-Surface::Surface() = default;
-Surface::~Surface() = default;
-
 Image::Image() = default;
 Image::~Image() = default;
 
diff --git a/services/surfaceflinger/tests/unittests/mock/RenderEngine/MockRenderEngine.h b/services/surfaceflinger/tests/unittests/mock/RenderEngine/MockRenderEngine.h
index afca63a..90c3c20 100644
--- a/services/surfaceflinger/tests/unittests/mock/RenderEngine/MockRenderEngine.h
+++ b/services/surfaceflinger/tests/unittests/mock/RenderEngine/MockRenderEngine.h
@@ -23,7 +23,6 @@
 #include <renderengine/LayerSettings.h>
 #include <renderengine/Mesh.h>
 #include <renderengine/RenderEngine.h>
-#include <renderengine/Surface.h>
 #include <renderengine/Texture.h>
 #include <ui/GraphicBuffer.h>
 
@@ -37,15 +36,12 @@
     ~RenderEngine() override;
 
     MOCK_METHOD0(createFramebuffer, std::unique_ptr<Framebuffer>());
-    MOCK_METHOD0(createSurface, std::unique_ptr<renderengine::Surface>());
     MOCK_METHOD0(createImage, std::unique_ptr<renderengine::Image>());
     MOCK_CONST_METHOD0(primeCache, void());
     MOCK_METHOD1(dump, void(String8&));
     MOCK_CONST_METHOD0(useNativeFenceSync, bool());
     MOCK_CONST_METHOD0(useWaitSync, bool());
     MOCK_CONST_METHOD0(isCurrent, bool());
-    MOCK_METHOD1(setCurrentSurface, bool(const renderengine::Surface&));
-    MOCK_METHOD0(resetCurrentSurface, void());
     MOCK_METHOD0(flush, base::unique_fd());
     MOCK_METHOD0(finish, bool());
     MOCK_METHOD1(waitFence, bool(base::unique_fd*));
@@ -82,23 +78,6 @@
                                 ANativeWindowBuffer* const, base::unique_fd*));
 };
 
-class Surface : public renderengine::Surface {
-public:
-    Surface();
-    ~Surface() override;
-
-    MOCK_METHOD1(setCritical, void(bool));
-    MOCK_METHOD1(setAsync, void(bool));
-    MOCK_METHOD1(setNativeWindow, void(ANativeWindow*));
-    MOCK_CONST_METHOD0(swapBuffers, void());
-    MOCK_CONST_METHOD0(queryRedSize, int32_t());
-    MOCK_CONST_METHOD0(queryGreenSize, int32_t());
-    MOCK_CONST_METHOD0(queryBlueSize, int32_t());
-    MOCK_CONST_METHOD0(queryAlphaSize, int32_t());
-    MOCK_CONST_METHOD0(getWidth, int32_t());
-    MOCK_CONST_METHOD0(getHeight, int32_t());
-};
-
 class Image : public renderengine::Image {
 public:
     Image();