Merge "Revert "blast: create SurfaceControl from Surface parent""
diff --git a/cmds/atrace/atrace.cpp b/cmds/atrace/atrace.cpp
index 53b3a00..bd3d2d8 100644
--- a/cmds/atrace/atrace.cpp
+++ b/cmds/atrace/atrace.cpp
@@ -99,30 +99,31 @@
 
 /* Tracing categories */
 static const TracingCategory k_categories[] = {
-    { "gfx",        "Graphics",         ATRACE_TAG_GRAPHICS, { } },
-    { "input",      "Input",            ATRACE_TAG_INPUT, { } },
-    { "view",       "View System",      ATRACE_TAG_VIEW, { } },
-    { "webview",    "WebView",          ATRACE_TAG_WEBVIEW, { } },
-    { "wm",         "Window Manager",   ATRACE_TAG_WINDOW_MANAGER, { } },
-    { "am",         "Activity Manager", ATRACE_TAG_ACTIVITY_MANAGER, { } },
-    { "sm",         "Sync Manager",     ATRACE_TAG_SYNC_MANAGER, { } },
-    { "audio",      "Audio",            ATRACE_TAG_AUDIO, { } },
-    { "video",      "Video",            ATRACE_TAG_VIDEO, { } },
-    { "camera",     "Camera",           ATRACE_TAG_CAMERA, { } },
-    { "hal",        "Hardware Modules", ATRACE_TAG_HAL, { } },
-    { "res",        "Resource Loading", ATRACE_TAG_RESOURCES, { } },
-    { "dalvik",     "Dalvik VM",        ATRACE_TAG_DALVIK, { } },
-    { "rs",         "RenderScript",     ATRACE_TAG_RS, { } },
-    { "bionic",     "Bionic C Library", ATRACE_TAG_BIONIC, { } },
-    { "power",      "Power Management", ATRACE_TAG_POWER, { } },
-    { "pm",         "Package Manager",  ATRACE_TAG_PACKAGE_MANAGER, { } },
-    { "ss",         "System Server",    ATRACE_TAG_SYSTEM_SERVER, { } },
-    { "database",   "Database",         ATRACE_TAG_DATABASE, { } },
-    { "network",    "Network",          ATRACE_TAG_NETWORK, { } },
-    { "adb",        "ADB",              ATRACE_TAG_ADB, { } },
-    { "vibrator",   "Vibrator",         ATRACE_TAG_VIBRATOR, { } },
-    { "aidl",       "AIDL calls",       ATRACE_TAG_AIDL, { } },
-    { "nnapi",      "NNAPI",            ATRACE_TAG_NNAPI, { } },
+    { "gfx",        "Graphics",                 ATRACE_TAG_GRAPHICS, { } },
+    { "input",      "Input",                    ATRACE_TAG_INPUT, { } },
+    { "view",       "View System",              ATRACE_TAG_VIEW, { } },
+    { "webview",    "WebView",                  ATRACE_TAG_WEBVIEW, { } },
+    { "wm",         "Window Manager",           ATRACE_TAG_WINDOW_MANAGER, { } },
+    { "am",         "Activity Manager",         ATRACE_TAG_ACTIVITY_MANAGER, { } },
+    { "sm",         "Sync Manager",             ATRACE_TAG_SYNC_MANAGER, { } },
+    { "audio",      "Audio",                    ATRACE_TAG_AUDIO, { } },
+    { "video",      "Video",                    ATRACE_TAG_VIDEO, { } },
+    { "camera",     "Camera",                   ATRACE_TAG_CAMERA, { } },
+    { "hal",        "Hardware Modules",         ATRACE_TAG_HAL, { } },
+    { "res",        "Resource Loading",         ATRACE_TAG_RESOURCES, { } },
+    { "dalvik",     "Dalvik VM",                ATRACE_TAG_DALVIK, { } },
+    { "rs",         "RenderScript",             ATRACE_TAG_RS, { } },
+    { "bionic",     "Bionic C Library",         ATRACE_TAG_BIONIC, { } },
+    { "power",      "Power Management",         ATRACE_TAG_POWER, { } },
+    { "pm",         "Package Manager",          ATRACE_TAG_PACKAGE_MANAGER, { } },
+    { "ss",         "System Server",            ATRACE_TAG_SYSTEM_SERVER, { } },
+    { "database",   "Database",                 ATRACE_TAG_DATABASE, { } },
+    { "network",    "Network",                  ATRACE_TAG_NETWORK, { } },
+    { "adb",        "ADB",                      ATRACE_TAG_ADB, { } },
+    { "vibrator",   "Vibrator",                 ATRACE_TAG_VIBRATOR, { } },
+    { "aidl",       "AIDL calls",               ATRACE_TAG_AIDL, { } },
+    { "nnapi",      "NNAPI",                    ATRACE_TAG_NNAPI, { } },
+    { "rro",        "Runtime Resource Overlay", ATRACE_TAG_RRO, { } },
     { k_coreServiceCategory, "Core services", 0, { } },
     { k_pdxServiceCategory, "PDX services", 0, { } },
     { "sched",      "CPU Scheduling",   0, {
diff --git a/cmds/servicemanager/binder.c b/cmds/servicemanager/binder.c
index fade8cf..a2b4da2 100644
--- a/cmds/servicemanager/binder.c
+++ b/cmds/servicemanager/binder.c
@@ -146,7 +146,21 @@
 
 int binder_become_context_manager(struct binder_state *bs)
 {
-    return ioctl(bs->fd, BINDER_SET_CONTEXT_MGR, 0);
+    struct flat_binder_object obj;
+    memset(&obj, 0, sizeof(obj));
+    obj.flags = FLAT_BINDER_FLAG_TXN_SECURITY_CTX;
+
+    int result = ioctl(bs->fd, BINDER_SET_CONTEXT_MGR_EXT, &obj);
+
+    // fallback to original method
+    if (result != 0) {
+#ifndef VENDORSERVICEMANAGER
+        android_errorWriteLog(0x534e4554, "121035042");
+#endif
+
+        result = ioctl(bs->fd, BINDER_SET_CONTEXT_MGR, 0);
+    }
+    return result;
 }
 
 int binder_write(struct binder_state *bs, void *data, size_t len)
@@ -240,13 +254,28 @@
 #endif
             ptr += sizeof(struct binder_ptr_cookie);
             break;
+        case BR_TRANSACTION_SEC_CTX:
         case BR_TRANSACTION: {
-            struct binder_transaction_data *txn = (struct binder_transaction_data *) ptr;
-            if ((end - ptr) < sizeof(*txn)) {
-                ALOGE("parse: txn too small!\n");
-                return -1;
+            struct binder_transaction_data_secctx txn;
+            if (cmd == BR_TRANSACTION_SEC_CTX) {
+                if ((end - ptr) < sizeof(struct binder_transaction_data_secctx)) {
+                    ALOGE("parse: txn too small (binder_transaction_data_secctx)!\n");
+                    return -1;
+                }
+                memcpy(&txn, (void*) ptr, sizeof(struct binder_transaction_data_secctx));
+                ptr += sizeof(struct binder_transaction_data_secctx);
+            } else /* BR_TRANSACTION */ {
+                if ((end - ptr) < sizeof(struct binder_transaction_data)) {
+                    ALOGE("parse: txn too small (binder_transaction_data)!\n");
+                    return -1;
+                }
+                memcpy(&txn.transaction_data, (void*) ptr, sizeof(struct binder_transaction_data));
+                ptr += sizeof(struct binder_transaction_data);
+
+                txn.secctx = 0;
             }
-            binder_dump_txn(txn);
+
+            binder_dump_txn(&txn.transaction_data);
             if (func) {
                 unsigned rdata[256/4];
                 struct binder_io msg;
@@ -254,15 +283,14 @@
                 int res;
 
                 bio_init(&reply, rdata, sizeof(rdata), 4);
-                bio_init_from_txn(&msg, txn);
-                res = func(bs, txn, &msg, &reply);
-                if (txn->flags & TF_ONE_WAY) {
-                    binder_free_buffer(bs, txn->data.ptr.buffer);
+                bio_init_from_txn(&msg, &txn.transaction_data);
+                res = func(bs, &txn, &msg, &reply);
+                if (txn.transaction_data.flags & TF_ONE_WAY) {
+                    binder_free_buffer(bs, txn.transaction_data.data.ptr.buffer);
                 } else {
-                    binder_send_reply(bs, &reply, txn->data.ptr.buffer, res);
+                    binder_send_reply(bs, &reply, txn.transaction_data.data.ptr.buffer, res);
                 }
             }
-            ptr += sizeof(*txn);
             break;
         }
         case BR_REPLY: {
diff --git a/cmds/servicemanager/binder.h b/cmds/servicemanager/binder.h
index c95b33f..70be3b4 100644
--- a/cmds/servicemanager/binder.h
+++ b/cmds/servicemanager/binder.h
@@ -5,7 +5,8 @@
 #define _BINDER_H_
 
 #include <sys/ioctl.h>
-#include <linux/android/binder.h>
+
+#include "binder_kernel.h"
 
 struct binder_state;
 
@@ -42,7 +43,7 @@
 };
 
 typedef int (*binder_handler)(struct binder_state *bs,
-                              struct binder_transaction_data *txn,
+                              struct binder_transaction_data_secctx *txn,
                               struct binder_io *msg,
                               struct binder_io *reply);
 
diff --git a/cmds/servicemanager/binder_kernel.h b/cmds/servicemanager/binder_kernel.h
new file mode 100644
index 0000000..19fd773
--- /dev/null
+++ b/cmds/servicemanager/binder_kernel.h
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2019 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.
+ */
+
+#ifndef ANDROID_BINDER_KERNEL_H
+#define ANDROID_BINDER_KERNEL_H
+
+#include <linux/android/binder.h>
+
+/**
+ * This file exists because the uapi kernel headers in bionic are built
+ * from upstream kernel headers only, and not all of the hwbinder kernel changes
+ * have made it upstream yet. Therefore, the modifications to the
+ * binder header are added locally in this file.
+ */
+
+enum {
+        FLAT_BINDER_FLAG_TXN_SECURITY_CTX = 0x1000,
+};
+
+#define BINDER_SET_CONTEXT_MGR_EXT      _IOW('b', 13, struct flat_binder_object)
+
+struct binder_transaction_data_secctx {
+        struct binder_transaction_data transaction_data;
+        binder_uintptr_t secctx;
+};
+
+enum {
+        BR_TRANSACTION_SEC_CTX = _IOR('r', 2,
+                              struct binder_transaction_data_secctx),
+};
+
+
+#endif // ANDROID_BINDER_KERNEL_H
diff --git a/cmds/servicemanager/service_manager.c b/cmds/servicemanager/service_manager.c
index 79cd6b5..ca004e9 100644
--- a/cmds/servicemanager/service_manager.c
+++ b/cmds/servicemanager/service_manager.c
@@ -61,14 +61,14 @@
 static char *service_manager_context;
 static struct selabel_handle* sehandle;
 
-static bool check_mac_perms(pid_t spid, uid_t uid, const char *tctx, const char *perm, const char *name)
+static bool check_mac_perms(pid_t spid, const char* sid, uid_t uid, const char *tctx, const char *perm, const char *name)
 {
-    char *sctx = NULL;
+    char *lookup_sid = NULL;
     const char *class = "service_manager";
     bool allowed;
     struct audit_data ad;
 
-    if (getpidcon(spid, &sctx) < 0) {
+    if (sid == NULL && getpidcon(spid, &lookup_sid) < 0) {
         ALOGE("SELinux: getpidcon(pid=%d) failed to retrieve pid context.\n", spid);
         return false;
     }
@@ -77,19 +77,25 @@
     ad.uid = uid;
     ad.name = name;
 
-    int result = selinux_check_access(sctx, tctx, class, perm, (void *) &ad);
+#ifndef VENDORSERVICEMANAGER
+    if (sid == NULL) {
+        android_errorWriteLog(0x534e4554, "121035042");
+    }
+#endif
+
+    int result = selinux_check_access(sid ? sid : lookup_sid, tctx, class, perm, (void *) &ad);
     allowed = (result == 0);
 
-    freecon(sctx);
+    freecon(lookup_sid);
     return allowed;
 }
 
-static bool check_mac_perms_from_getcon(pid_t spid, uid_t uid, const char *perm)
+static bool check_mac_perms_from_getcon(pid_t spid, const char* sid, uid_t uid, const char *perm)
 {
-    return check_mac_perms(spid, uid, service_manager_context, perm, NULL);
+    return check_mac_perms(spid, sid, uid, service_manager_context, perm, NULL);
 }
 
-static bool check_mac_perms_from_lookup(pid_t spid, uid_t uid, const char *perm, const char *name)
+static bool check_mac_perms_from_lookup(pid_t spid, const char* sid, uid_t uid, const char *perm, const char *name)
 {
     bool allowed;
     char *tctx = NULL;
@@ -104,12 +110,12 @@
         return false;
     }
 
-    allowed = check_mac_perms(spid, uid, tctx, perm, name);
+    allowed = check_mac_perms(spid, sid, uid, tctx, perm, name);
     freecon(tctx);
     return allowed;
 }
 
-static int svc_can_register(const uint16_t *name, size_t name_len, pid_t spid, uid_t uid)
+static int svc_can_register(const uint16_t *name, size_t name_len, pid_t spid, const char* sid, uid_t uid)
 {
     const char *perm = "add";
 
@@ -117,19 +123,19 @@
         return 0; /* Don't allow apps to register services */
     }
 
-    return check_mac_perms_from_lookup(spid, uid, perm, str8(name, name_len)) ? 1 : 0;
+    return check_mac_perms_from_lookup(spid, sid, uid, perm, str8(name, name_len)) ? 1 : 0;
 }
 
-static int svc_can_list(pid_t spid, uid_t uid)
+static int svc_can_list(pid_t spid, const char* sid, uid_t uid)
 {
     const char *perm = "list";
-    return check_mac_perms_from_getcon(spid, uid, perm) ? 1 : 0;
+    return check_mac_perms_from_getcon(spid, sid, uid, perm) ? 1 : 0;
 }
 
-static int svc_can_find(const uint16_t *name, size_t name_len, pid_t spid, uid_t uid)
+static int svc_can_find(const uint16_t *name, size_t name_len, pid_t spid, const char* sid, uid_t uid)
 {
     const char *perm = "find";
-    return check_mac_perms_from_lookup(spid, uid, perm, str8(name, name_len)) ? 1 : 0;
+    return check_mac_perms_from_lookup(spid, sid, uid, perm, str8(name, name_len)) ? 1 : 0;
 }
 
 struct svcinfo
@@ -175,7 +181,7 @@
 };
 
 
-uint32_t do_find_service(const uint16_t *s, size_t len, uid_t uid, pid_t spid)
+uint32_t do_find_service(const uint16_t *s, size_t len, uid_t uid, pid_t spid, const char* sid)
 {
     struct svcinfo *si = find_svc(s, len);
 
@@ -192,7 +198,7 @@
         }
     }
 
-    if (!svc_can_find(s, len, spid, uid)) {
+    if (!svc_can_find(s, len, spid, sid, uid)) {
         return 0;
     }
 
@@ -200,7 +206,7 @@
 }
 
 int do_add_service(struct binder_state *bs, const uint16_t *s, size_t len, uint32_t handle,
-                   uid_t uid, int allow_isolated, uint32_t dumpsys_priority, pid_t spid) {
+                   uid_t uid, int allow_isolated, uint32_t dumpsys_priority, pid_t spid, const char* sid) {
     struct svcinfo *si;
 
     //ALOGI("add_service('%s',%x,%s) uid=%d\n", str8(s, len), handle,
@@ -209,7 +215,7 @@
     if (!handle || (len == 0) || (len > 127))
         return -1;
 
-    if (!svc_can_register(s, len, spid, uid)) {
+    if (!svc_can_register(s, len, spid, sid, uid)) {
         ALOGE("add_service('%s',%x) uid=%d - PERMISSION DENIED\n",
              str8(s, len), handle, uid);
         return -1;
@@ -248,7 +254,7 @@
 }
 
 int svcmgr_handler(struct binder_state *bs,
-                   struct binder_transaction_data *txn,
+                   struct binder_transaction_data_secctx *txn_secctx,
                    struct binder_io *msg,
                    struct binder_io *reply)
 {
@@ -260,6 +266,8 @@
     int allow_isolated;
     uint32_t dumpsys_priority;
 
+    struct binder_transaction_data *txn = &txn_secctx->transaction_data;
+
     //ALOGI("target=%p code=%d pid=%d uid=%d\n",
     //      (void*) txn->target.ptr, txn->code, txn->sender_pid, txn->sender_euid);
 
@@ -305,7 +313,8 @@
         if (s == NULL) {
             return -1;
         }
-        handle = do_find_service(s, len, txn->sender_euid, txn->sender_pid);
+        handle = do_find_service(s, len, txn->sender_euid, txn->sender_pid,
+                                 (const char*) txn_secctx->secctx);
         if (!handle)
             break;
         bio_put_ref(reply, handle);
@@ -320,7 +329,7 @@
         allow_isolated = bio_get_uint32(msg) ? 1 : 0;
         dumpsys_priority = bio_get_uint32(msg);
         if (do_add_service(bs, s, len, handle, txn->sender_euid, allow_isolated, dumpsys_priority,
-                           txn->sender_pid))
+                           txn->sender_pid, (const char*) txn_secctx->secctx))
             return -1;
         break;
 
@@ -328,7 +337,7 @@
         uint32_t n = bio_get_uint32(msg);
         uint32_t req_dumpsys_priority = bio_get_uint32(msg);
 
-        if (!svc_can_list(txn->sender_pid, txn->sender_euid)) {
+        if (!svc_can_list(txn->sender_pid, (const char*) txn_secctx->secctx, txn->sender_euid)) {
             ALOGE("list_service() uid=%d - PERMISSION DENIED\n",
                     txn->sender_euid);
             return -1;
diff --git a/include/OWNERS b/include/OWNERS
index 82ae4cf..22be776 100644
--- a/include/OWNERS
+++ b/include/OWNERS
@@ -1,17 +1,14 @@
 alexeykuzmin@google.com
-brianderson@google.com
 dangittik@google.com
 lajos@google.com
 mathias@google.com
 michaelwr@google.com
-olv@google.com
-pceballos@google.com
-pengxu@google.com
 racarr@google.com
-romainguy@google.com
-ronghuawu@google.com
-sadmac@google.com
+romainguy@android.com
 santoscordon@google.com
 stoza@google.com
 svv@google.com
-wiley@google.com
+
+# For multinetwork.h only.
+lorenzo@google.com
+
diff --git a/include/android/multinetwork.h b/include/android/multinetwork.h
index fa7d908..05d96ff 100644
--- a/include/android/multinetwork.h
+++ b/include/android/multinetwork.h
@@ -112,26 +112,43 @@
 
 #if __ANDROID_API__ >= 29
 
+enum ResNsendFlags : uint32_t {
+    // Send a single request to a single resolver and fail on timeout or network errors
+    ANDROID_RESOLV_NO_RETRY = 1 << 0,
+
+    // Do not cache the result of the lookup. The lookup may return a result that is already
+    // in the cache, unless the ANDROID_RESOLV_NO_CACHE_LOOKUP flag is also specified.
+    ANDROID_RESOLV_NO_CACHE_STORE = 1 << 1,
+
+    // Don't lookup the request in cache, do not write back the response into the cache
+    ANDROID_RESOLV_NO_CACHE_LOOKUP = 1 << 2,
+};
+
 /**
  * Look up the {|ns_class|, |ns_type|} Resource Record (RR) associated
  * with Domain Name |dname| on the given |network|.
  * The typical value for |ns_class| is ns_c_in, while |type| can be any
  * record type (for instance, ns_t_aaaa or ns_t_txt).
+ * |flags| is a additional config to control actual querying behavior, see
+ * ResNsendFlags for detail.
  *
  * Returns a file descriptor to watch for read events, or a negative
  * POSIX error code (see errno.h) if an immediate error occurs.
  */
 int android_res_nquery(net_handle_t network,
-        const char *dname, int ns_class, int ns_type) __INTRODUCED_IN(29);
+        const char *dname, int ns_class, int ns_type,
+        enum ResNsendFlags flags) __INTRODUCED_IN(29);
 
 /**
  * Issue the query |msg| on the given |network|.
+ * |flags| is a additional config to control actual querying behavior, see
+ * ResNsendFlags for detail.
  *
  * Returns a file descriptor to watch for read events, or a negative
  * POSIX error code (see errno.h) if an immediate error occurs.
  */
 int android_res_nsend(net_handle_t network,
-        const uint8_t *msg, size_t msglen) __INTRODUCED_IN(29);
+        const uint8_t *msg, size_t msglen, enum ResNsendFlags flags) __INTRODUCED_IN(29);
 
 /**
  * Read a result for the query associated with the |fd| descriptor.
diff --git a/include/input/IInputFlinger.h b/include/input/IInputFlinger.h
index 610834d..ff443c6 100644
--- a/include/input/IInputFlinger.h
+++ b/include/input/IInputFlinger.h
@@ -36,7 +36,7 @@
     DECLARE_META_INTERFACE(InputFlinger)
 
     virtual void setInputWindows(const Vector<InputWindowInfo>& inputHandles) = 0;
-
+    virtual void transferTouchFocus(const sp<IBinder>& fromToken, const sp<IBinder>& toToken) = 0;
     virtual void registerInputChannel(const sp<InputChannel>& channel) = 0;
     virtual void unregisterInputChannel(const sp<InputChannel>& channel) = 0;
 };
@@ -50,7 +50,8 @@
     enum {
         SET_INPUT_WINDOWS_TRANSACTION = IBinder::FIRST_CALL_TRANSACTION,
         REGISTER_INPUT_CHANNEL_TRANSACTION,
-        UNREGISTER_INPUT_CHANNEL_TRANSACTION
+        UNREGISTER_INPUT_CHANNEL_TRANSACTION,
+        TRANSFER_TOUCH_FOCUS
     };
 
     virtual status_t onTransact(uint32_t code, const Parcel& data,
diff --git a/libs/graphicsenv/GraphicsEnv.cpp b/libs/graphicsenv/GraphicsEnv.cpp
index 9dc7431..660e3c3 100644
--- a/libs/graphicsenv/GraphicsEnv.cpp
+++ b/libs/graphicsenv/GraphicsEnv.cpp
@@ -284,16 +284,7 @@
     } else {
         // The "Developer Options" value wasn't set to force the use of ANGLE.  Need to temporarily
         // load ANGLE and call the updatable opt-in/out logic:
-
-        // Check if ANGLE is enabled. Workaround for several bugs:
-        // b/119305693 b/119322355 b/119305887
-        // Something is not working correctly in the feature library
-        char prop[PROPERTY_VALUE_MAX];
-        property_get("debug.angle.enable", prop, "0");
-        void* featureSo = nullptr;
-        if (atoi(prop)) {
-            featureSo = loadLibrary("feature_support");
-        }
+        void* featureSo = loadLibrary("feature_support");
         if (featureSo) {
             ALOGV("loaded ANGLE's opt-in/out logic from namespace");
             mUseAngle = checkAngleRules(featureSo);
diff --git a/libs/gui/tests/EndToEndNativeInputTest.cpp b/libs/gui/tests/EndToEndNativeInputTest.cpp
index 60542bd..7fc69ff 100644
--- a/libs/gui/tests/EndToEndNativeInputTest.cpp
+++ b/libs/gui/tests/EndToEndNativeInputTest.cpp
@@ -133,6 +133,27 @@
         EXPECT_EQ(AMOTION_EVENT_ACTION_UP, mev->getAction());
     }
 
+    void expectMotionEvent(int motionEventType, int x, int y) {
+        InputEvent *ev = consumeEvent();
+        ASSERT_NE(ev, nullptr);
+        ASSERT_EQ(ev->getType(), AINPUT_EVENT_TYPE_MOTION);
+        MotionEvent *mev = static_cast<MotionEvent *>(ev);
+        EXPECT_EQ(motionEventType, mev->getAction());
+        EXPECT_EQ(x, mev->getX(0));
+        EXPECT_EQ(y, mev->getY(0));
+    }
+
+    void expectNoMotionEvent(int motionEventType) {
+        InputEvent *ev = consumeEvent();
+        if (ev == nullptr || ev->getType() != AINPUT_EVENT_TYPE_MOTION) {
+            // Didn't find an event or a motion event so assume action didn't occur.
+            return;
+        }
+
+        MotionEvent *mev = static_cast<MotionEvent *>(ev);
+        EXPECT_NE(motionEventType, mev->getAction());
+    }
+
     ~InputSurface() {
         mInputFlinger->unregisterInputChannel(mServerChannel);
     }
@@ -255,6 +276,15 @@
     }
 }
 
+void injectMotionEvent(std::string event, int x, int y) {
+    char *buf1, *buf2;
+    asprintf(&buf1, "%d", x);
+    asprintf(&buf2, "%d", y);
+    if (fork() == 0) {
+        execlp("input", "input", "motionevent", event.c_str(), buf1, buf2, NULL);
+    }
+}
+
 TEST_F(InputSurfacesTest, can_receive_input) {
     std::unique_ptr<InputSurface> surface = makeSurface(100, 100);
     surface->showAt(100, 100);
@@ -439,5 +469,25 @@
     injectTap(11, 11);
     bgSurface->expectTap(1, 1);
 }
+
+TEST_F(InputSurfacesTest, transfer_touch_focus) {
+    std::unique_ptr<InputSurface> fromSurface = makeSurface(100, 100);
+
+    fromSurface->showAt(10, 10);
+    injectMotionEvent("DOWN", 11, 11);
+    fromSurface->expectMotionEvent(AMOTION_EVENT_ACTION_DOWN, 1, 1);
+
+    std::unique_ptr<InputSurface> toSurface = makeSurface(100, 100);
+    toSurface->showAt(10, 10);
+
+    sp<IBinder> fromToken = fromSurface->mServerChannel->getToken();
+    sp<IBinder> toToken = toSurface->mServerChannel->getToken();
+    SurfaceComposerClient::Transaction t;
+    t.transferTouchFocus(fromToken, toToken).apply(true);
+
+    injectMotionEvent("UP", 11, 11);
+    toSurface->expectMotionEvent(AMOTION_EVENT_ACTION_UP, 1, 1);
+    fromSurface->expectNoMotionEvent(AMOTION_EVENT_ACTION_UP);
+}
 }
 }
diff --git a/libs/input/IInputFlinger.cpp b/libs/input/IInputFlinger.cpp
index 139570a..acf40bc 100644
--- a/libs/input/IInputFlinger.cpp
+++ b/libs/input/IInputFlinger.cpp
@@ -42,6 +42,16 @@
                 IBinder::FLAG_ONEWAY);
     }
 
+    virtual void transferTouchFocus(const sp<IBinder>& fromToken, const sp<IBinder>& toToken) {
+        Parcel data, reply;
+        data.writeInterfaceToken(IInputFlinger::getInterfaceDescriptor());
+
+        data.writeStrongBinder(fromToken);
+        data.writeStrongBinder(toToken);
+        remote()->transact(BnInputFlinger::TRANSFER_TOUCH_FOCUS, data, &reply,
+                IBinder::FLAG_ONEWAY);
+    }
+
     virtual void registerInputChannel(const sp<InputChannel>& channel) {
         Parcel data, reply;
         data.writeInterfaceToken(IInputFlinger::getInterfaceDescriptor());
@@ -90,6 +100,13 @@
         unregisterInputChannel(channel);
         break;
     }
+    case TRANSFER_TOUCH_FOCUS: {
+        CHECK_INTERFACE(IInputFlinger, data, reply);
+        sp<IBinder> fromToken = data.readStrongBinder();
+        sp<IBinder> toToken = data.readStrongBinder();
+        transferTouchFocus(fromToken, toToken);
+        break;
+    }
     default:
         return BBinder::onTransact(code, data, reply, flags);
     }
diff --git a/libs/nativewindow/include/android/hardware_buffer.h b/libs/nativewindow/include/android/hardware_buffer.h
index 03545a6..2796c75 100644
--- a/libs/nativewindow/include/android/hardware_buffer.h
+++ b/libs/nativewindow/include/android/hardware_buffer.h
@@ -208,6 +208,17 @@
      */
     AHARDWAREBUFFER_USAGE_GPU_COLOR_OUTPUT       = AHARDWAREBUFFER_USAGE_GPU_FRAMEBUFFER,
     /**
+     * The buffer will be used as a composer HAL overlay layer.
+     *
+     * This flag is currently only needed when using ASurfaceTransaction_setBuffer
+     * to set a buffer. In all other cases, the framework adds this flag
+     * internally to buffers that could be presented in a composer overlay.
+     * ASurfaceTransaction_setBuffer is special because it uses buffers allocated
+     * directly through AHardwareBuffer_allocate instead of buffers allocated
+     * by the framework.
+     */
+    AHARDWAREBUFFER_USAGE_COMPOSER_OVERLAY       = 1ULL << 11,
+    /**
      * The buffer is protected from direct CPU access or being read by
      * non-secure hardware, such as video encoders.
      *
diff --git a/libs/renderengine/Android.bp b/libs/renderengine/Android.bp
index ac053f3..36211ca 100644
--- a/libs/renderengine/Android.bp
+++ b/libs/renderengine/Android.bp
@@ -80,3 +80,19 @@
         thin: true,
     },
 }
+
+cc_library_static {
+    name: "librenderengine_mocks",
+    defaults: ["librenderengine_defaults"],
+    srcs: [
+        "mock/Framebuffer.cpp",
+        "mock/Image.cpp",
+        "mock/RenderEngine.cpp",
+    ],
+    static_libs: [
+        "libgtest",
+        "libgmock",
+    ],
+    local_include_dirs: ["include"],
+    export_include_dirs: ["include"],
+}
diff --git a/libs/renderengine/gl/GLESRenderEngine.cpp b/libs/renderengine/gl/GLESRenderEngine.cpp
index d0a0ac8..2915bb8 100644
--- a/libs/renderengine/gl/GLESRenderEngine.cpp
+++ b/libs/renderengine/gl/GLESRenderEngine.cpp
@@ -30,6 +30,7 @@
 #include <GLES2/gl2ext.h>
 #include <android-base/stringprintf.h>
 #include <cutils/compiler.h>
+#include <cutils/properties.h>
 #include <renderengine/Mesh.h>
 #include <renderengine/Texture.h>
 #include <renderengine/private/Description.h>
@@ -416,6 +417,13 @@
         mBt2020ToSrgb = mXyzToSrgb * mBt2020ToXyz;
         mBt2020ToDisplayP3 = mXyzToDisplayP3 * mBt2020ToXyz;
     }
+
+    char value[PROPERTY_VALUE_MAX];
+    property_get("debug.egl.traceGpuCompletion", value, "0");
+    if (atoi(value)) {
+        mTraceGpuCompletion = true;
+        mFlushTracer = std::make_unique<FlushTracer>(this);
+    }
 }
 
 GLESRenderEngine::~GLESRenderEngine() {
@@ -461,6 +469,12 @@
         ALOGW("failed to dup EGL native fence sync: %#x", eglGetError());
     }
 
+    // Only trace if we have a valid fence, as current usage falls back to
+    // calling finish() if the fence fd is invalid.
+    if (CC_UNLIKELY(mTraceGpuCompletion && mFlushTracer) && fenceFd.get() >= 0) {
+        mFlushTracer->queueSync(eglCreateSyncKHR(mEGLDisplay, EGL_SYNC_FENCE_KHR, nullptr));
+    }
+
     return fenceFd;
 }
 
@@ -476,8 +490,15 @@
         return false;
     }
 
-    EGLint result = eglClientWaitSyncKHR(mEGLDisplay, sync, EGL_SYNC_FLUSH_COMMANDS_BIT_KHR,
-                                         2000000000 /*2 sec*/);
+    if (CC_UNLIKELY(mTraceGpuCompletion && mFlushTracer)) {
+        mFlushTracer->queueSync(eglCreateSyncKHR(mEGLDisplay, EGL_SYNC_FENCE_KHR, nullptr));
+    }
+
+    return waitSync(sync, EGL_SYNC_FLUSH_COMMANDS_BIT_KHR);
+}
+
+bool GLESRenderEngine::waitSync(EGLSyncKHR sync, EGLint flags) {
+    EGLint result = eglClientWaitSyncKHR(mEGLDisplay, sync, flags, 2000000000 /*2 sec*/);
     EGLint error = eglGetError();
     eglDestroySyncKHR(mEGLDisplay, sync);
     if (result != EGL_CONDITION_SATISFIED_KHR) {
@@ -626,6 +647,25 @@
     return NO_ERROR;
 }
 
+FloatRect GLESRenderEngine::setupLayerCropping(const LayerSettings& layer, Mesh& mesh) {
+    // Translate win by the rounded corners rect coordinates, to have all values in
+    // layer coordinate space.
+    FloatRect cropWin = layer.geometry.boundaries;
+    const FloatRect& roundedCornersCrop = layer.geometry.roundedCornersCrop;
+    cropWin.left -= roundedCornersCrop.left;
+    cropWin.right -= roundedCornersCrop.left;
+    cropWin.top -= roundedCornersCrop.top;
+    cropWin.bottom -= roundedCornersCrop.top;
+    Mesh::VertexArray<vec2> cropCoords(mesh.getCropCoordArray<vec2>());
+    cropCoords[0] = vec2(cropWin.left, cropWin.top);
+    cropCoords[1] = vec2(cropWin.left, cropWin.top + cropWin.getHeight());
+    cropCoords[2] = vec2(cropWin.right, cropWin.top + cropWin.getHeight());
+    cropCoords[3] = vec2(cropWin.right, cropWin.top);
+
+    setupCornerRadiusCropSize(roundedCornersCrop.getWidth(), roundedCornersCrop.getHeight());
+    return cropWin;
+}
+
 status_t GLESRenderEngine::bindFrameBuffer(Framebuffer* framebuffer) {
     GLFramebuffer* glFramebuffer = static_cast<GLFramebuffer*>(framebuffer);
     EGLImageKHR eglImage = glFramebuffer->getEGLImage();
@@ -714,6 +754,10 @@
     setDisplayMaxLuminance(display.maxLuminance);
 
     mat4 projectionMatrix = mState.projectionMatrix * display.globalTransform;
+    mState.projectionMatrix = projectionMatrix;
+    if (!display.clearRegion.isEmpty()) {
+        fillRegionWithColor(display.clearRegion, 0.0, 0.0, 0.0, 1.0);
+    }
 
     Mesh mesh(Mesh::TRIANGLE_FAN, 4, 2, 2);
     for (auto layer : layers) {
@@ -726,6 +770,7 @@
         position[2] = vec2(bounds.right, bounds.bottom);
         position[3] = vec2(bounds.right, bounds.top);
 
+        setupLayerCropping(layer, mesh);
         setColorTransform(display.colorTransform * layer.colorTransform);
 
         bool usePremultipliedAlpha = true;
@@ -760,7 +805,7 @@
         // Buffer sources will have a black solid color ignored in the shader,
         // so in that scenario the solid color passed here is arbitrary.
         setupLayerBlending(usePremultipliedAlpha, layer.source.buffer.isOpaque, disableTexture,
-                           color, /*cornerRadius=*/0.0);
+                           color, layer.geometry.roundedCornersRadius);
         setSourceDataSpace(layer.sourceDataspace);
 
         drawMesh(mesh);
@@ -1200,6 +1245,61 @@
     return (isInputHdrDataSpace || isOutputHdrDataSpace) && inputTransfer != outputTransfer;
 }
 
+// FlushTracer implementation
+GLESRenderEngine::FlushTracer::FlushTracer(GLESRenderEngine* engine) : mEngine(engine) {
+    mThread = std::thread(&GLESRenderEngine::FlushTracer::loop, this);
+}
+
+GLESRenderEngine::FlushTracer::~FlushTracer() {
+    {
+        std::lock_guard<std::mutex> lock(mMutex);
+        mRunning = false;
+    }
+    mCondition.notify_all();
+    if (mThread.joinable()) {
+        mThread.join();
+    }
+}
+
+void GLESRenderEngine::FlushTracer::queueSync(EGLSyncKHR sync) {
+    std::lock_guard<std::mutex> lock(mMutex);
+    char name[64];
+    const uint64_t frameNum = mFramesQueued++;
+    snprintf(name, sizeof(name), "Queueing sync for frame: %lu",
+             static_cast<unsigned long>(frameNum));
+    ATRACE_NAME(name);
+    mQueue.push({sync, frameNum});
+    ATRACE_INT("GPU Frames Outstanding", mQueue.size());
+    mCondition.notify_one();
+}
+
+void GLESRenderEngine::FlushTracer::loop() {
+    while (mRunning) {
+        QueueEntry entry;
+        {
+            std::lock_guard<std::mutex> lock(mMutex);
+
+            mCondition.wait(mMutex,
+                            [&]() REQUIRES(mMutex) { return !mQueue.empty() && !mRunning; });
+
+            if (!mRunning) {
+                // if mRunning is false, then FlushTracer is being destroyed, so
+                // bail out now.
+                break;
+            }
+            entry = mQueue.front();
+            mQueue.pop();
+        }
+        {
+            char name[64];
+            snprintf(name, sizeof(name), "waiting for frame %lu",
+                     static_cast<unsigned long>(entry.mFrameNum));
+            ATRACE_NAME(name);
+            mEngine->waitSync(entry.mSync, 0);
+        }
+    }
+}
+
 } // namespace gl
 } // namespace renderengine
 } // namespace android
diff --git a/libs/renderengine/gl/GLESRenderEngine.h b/libs/renderengine/gl/GLESRenderEngine.h
index 2af2aed..b596242 100644
--- a/libs/renderengine/gl/GLESRenderEngine.h
+++ b/libs/renderengine/gl/GLESRenderEngine.h
@@ -17,8 +17,13 @@
 #ifndef SF_GLESRENDERENGINE_H_
 #define SF_GLESRENDERENGINE_H_
 
+#include <android-base/thread_annotations.h>
 #include <stdint.h>
 #include <sys/types.h>
+#include <condition_variable>
+#include <mutex>
+#include <queue>
+#include <thread>
 
 #include <EGL/egl.h>
 #include <EGL/eglext.h>
@@ -119,6 +124,7 @@
                                        Protection protection);
     static EGLSurface createDummyEglPbufferSurface(EGLDisplay display, EGLConfig config,
                                                    int hwcFormat, Protection protection);
+    bool waitSync(EGLSyncKHR sync, EGLint flags);
 
     // A data space is considered HDR data space if it has BT2020 color space
     // with PQ or HLG transfer function.
@@ -128,6 +134,9 @@
     // defined by the clip.
     void setViewportAndProjection(Rect viewport, Rect clip);
     status_t bindExternalTextureBuffer(uint32_t texName, sp<GraphicBuffer> buffer, sp<Fence> fence);
+    // Computes the cropping window for the layer and sets up cropping
+    // coordinates for the mesh.
+    FloatRect setupLayerCropping(const LayerSettings& layer, Mesh& mesh);
 
     EGLDisplay mEGLDisplay;
     EGLConfig mEGLConfig;
@@ -156,6 +165,8 @@
     mat4 mBt2020ToDisplayP3;
 
     bool mInProtectedContext = false;
+    // If set to true, then enables tracing flush() and finish() to systrace.
+    bool mTraceGpuCompletion = false;
     int32_t mFboHeight = 0;
 
     // Current dataspace of layer being rendered
@@ -167,6 +178,30 @@
     // Whether device supports color management, currently color management
     // supports sRGB, DisplayP3 color spaces.
     const bool mUseColorManagement = false;
+
+    class FlushTracer {
+    public:
+        FlushTracer(GLESRenderEngine* engine);
+        ~FlushTracer();
+        void queueSync(EGLSyncKHR sync) EXCLUDES(mMutex);
+
+        struct QueueEntry {
+            EGLSyncKHR mSync = nullptr;
+            uint64_t mFrameNum = 0;
+        };
+
+    private:
+        void loop();
+        GLESRenderEngine* const mEngine;
+        std::thread mThread;
+        std::condition_variable_any mCondition;
+        std::mutex mMutex;
+        std::queue<QueueEntry> mQueue GUARDED_BY(mMutex);
+        uint64_t mFramesQueued GUARDED_BY(mMutex) = 0;
+        bool mRunning = true;
+    };
+    friend class FlushTracer;
+    std::unique_ptr<FlushTracer> mFlushTracer;
 };
 
 } // namespace gl
diff --git a/libs/renderengine/include/renderengine/DisplaySettings.h b/libs/renderengine/include/renderengine/DisplaySettings.h
index 0c92353..af8de23 100644
--- a/libs/renderengine/include/renderengine/DisplaySettings.h
+++ b/libs/renderengine/include/renderengine/DisplaySettings.h
@@ -51,9 +51,10 @@
     // to the output dataspace.
     mat4 colorTransform = mat4();
 
-    // Region that will be cleared to (0, 0, 0, 0) prior to rendering.
-    // clearRegion will first be transformed by globalTransform so that it will
-    // be in the same coordinate space as the rendered layers.
+    // Region that will be cleared to (0, 0, 0, 1) prior to rendering.
+    // RenderEngine will transform the clearRegion passed in here, by
+    // globalTransform, so that it will be in the same coordinate space as the
+    // rendered layers.
     Region clearRegion = Region::INVALID_REGION;
 };
 
diff --git a/libs/renderengine/include/renderengine/LayerSettings.h b/libs/renderengine/include/renderengine/LayerSettings.h
index a37a163..4d53205 100644
--- a/libs/renderengine/include/renderengine/LayerSettings.h
+++ b/libs/renderengine/include/renderengine/LayerSettings.h
@@ -69,6 +69,20 @@
 
     // Transform matrix to apply to mesh coordinates.
     mat4 positionTransform = mat4();
+
+    // Radius of rounded corners, if greater than 0. Otherwise, this layer's
+    // corners are not rounded.
+    // Having corner radius will force GPU composition on the layer and its children, drawing it
+    // with a special shader. The shader will receive the radius and the crop rectangle as input,
+    // modifying the opacity of the destination texture, multiplying it by a number between 0 and 1.
+    // We query Layer#getRoundedCornerState() to retrieve the radius as well as the rounded crop
+    // rectangle to figure out how to apply the radius for this layer. The crop rectangle will be
+    // in local layer coordinate space, so we have to take the layer transform into account when
+    // walking up the tree.
+    float roundedCornersRadius = 0.0;
+
+    // Rectangle within which corners will be rounded.
+    FloatRect roundedCornersCrop = FloatRect();
 };
 
 // Descriptor of the source pixels for this layer.
@@ -94,11 +108,11 @@
     half alpha = half(0.0);
 
     // Color space describing how the source pixels should be interpreted.
-    ui::Dataspace sourceDataspace;
+    ui::Dataspace sourceDataspace = ui::Dataspace::UNKNOWN;
 
     // Additional layer-specific color transform to be applied before the global
     // transform.
-    mat4 colorTransform;
+    mat4 colorTransform = mat4();
 };
 
 } // namespace renderengine
diff --git a/services/surfaceflinger/tests/unittests/mock/RenderEngine/MockRenderEngine.cpp b/libs/renderengine/include/renderengine/mock/Framebuffer.h
similarity index 63%
copy from services/surfaceflinger/tests/unittests/mock/RenderEngine/MockRenderEngine.cpp
copy to libs/renderengine/include/renderengine/mock/Framebuffer.h
index fbfbc3f..7695885 100644
--- a/services/surfaceflinger/tests/unittests/mock/RenderEngine/MockRenderEngine.cpp
+++ b/libs/renderengine/include/renderengine/mock/Framebuffer.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2018 The Android Open Source Project
+ * 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.
@@ -14,23 +14,22 @@
  * limitations under the License.
  */
 
-#include "mock/RenderEngine/MockRenderEngine.h"
+#pragma once
 
-#include <ui/Region.h>
+#include <gmock/gmock.h>
+#include <renderengine/Framebuffer.h>
 
 namespace android {
 namespace renderengine {
 namespace mock {
 
-// Explicit default instantiation is recommended.
-RenderEngine::RenderEngine() = default;
-RenderEngine::~RenderEngine() = default;
+class Framebuffer : public renderengine::Framebuffer {
+public:
+    Framebuffer();
+    ~Framebuffer() override;
 
-Image::Image() = default;
-Image::~Image() = default;
-
-Framebuffer::Framebuffer() = default;
-Framebuffer::~Framebuffer() = default;
+    MOCK_METHOD2(setNativeWindowBuffer, bool(ANativeWindowBuffer*, bool));
+};
 
 } // namespace mock
 } // namespace renderengine
diff --git a/services/surfaceflinger/tests/unittests/mock/RenderEngine/MockRenderEngine.cpp b/libs/renderengine/include/renderengine/mock/Image.h
similarity index 63%
copy from services/surfaceflinger/tests/unittests/mock/RenderEngine/MockRenderEngine.cpp
copy to libs/renderengine/include/renderengine/mock/Image.h
index fbfbc3f..2b0eed1 100644
--- a/services/surfaceflinger/tests/unittests/mock/RenderEngine/MockRenderEngine.cpp
+++ b/libs/renderengine/include/renderengine/mock/Image.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2018 The Android Open Source Project
+ * 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.
@@ -14,23 +14,22 @@
  * limitations under the License.
  */
 
-#include "mock/RenderEngine/MockRenderEngine.h"
+#pragma once
 
-#include <ui/Region.h>
+#include <gmock/gmock.h>
+#include <renderengine/Image.h>
 
 namespace android {
 namespace renderengine {
 namespace mock {
 
-// Explicit default instantiation is recommended.
-RenderEngine::RenderEngine() = default;
-RenderEngine::~RenderEngine() = default;
+class Image : public renderengine::Image {
+public:
+    Image();
+    ~Image() override;
 
-Image::Image() = default;
-Image::~Image() = default;
-
-Framebuffer::Framebuffer() = default;
-Framebuffer::~Framebuffer() = default;
+    MOCK_METHOD2(setNativeWindowBuffer, bool(ANativeWindowBuffer* buffer, bool isProtected));
+};
 
 } // namespace mock
 } // namespace renderengine
diff --git a/services/surfaceflinger/tests/unittests/mock/RenderEngine/MockRenderEngine.h b/libs/renderengine/include/renderengine/mock/RenderEngine.h
similarity index 82%
rename from services/surfaceflinger/tests/unittests/mock/RenderEngine/MockRenderEngine.h
rename to libs/renderengine/include/renderengine/mock/RenderEngine.h
index 81a7768..b4c7c96 100644
--- a/services/surfaceflinger/tests/unittests/mock/RenderEngine/MockRenderEngine.h
+++ b/libs/renderengine/include/renderengine/mock/RenderEngine.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2018 The Android Open Source Project
+ * 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.
@@ -18,13 +18,12 @@
 
 #include <gmock/gmock.h>
 #include <renderengine/DisplaySettings.h>
-#include <renderengine/Framebuffer.h>
-#include <renderengine/Image.h>
 #include <renderengine/LayerSettings.h>
 #include <renderengine/Mesh.h>
 #include <renderengine/RenderEngine.h>
 #include <renderengine/Texture.h>
 #include <ui/GraphicBuffer.h>
+#include <ui/Region.h>
 
 namespace android {
 namespace renderengine {
@@ -35,7 +34,7 @@
     RenderEngine();
     ~RenderEngine() override;
 
-    MOCK_METHOD0(createFramebuffer, std::unique_ptr<Framebuffer>());
+    MOCK_METHOD0(createFramebuffer, std::unique_ptr<renderengine::Framebuffer>());
     MOCK_METHOD0(createImage, std::unique_ptr<renderengine::Image>());
     MOCK_CONST_METHOD0(primeCache, void());
     MOCK_METHOD1(dump, void(std::string&));
@@ -69,9 +68,9 @@
     MOCK_METHOD1(setSourceDataSpace, void(ui::Dataspace));
     MOCK_METHOD1(setOutputDataSpace, void(ui::Dataspace));
     MOCK_METHOD1(setDisplayMaxLuminance, void(const float));
-    MOCK_METHOD1(bindFrameBuffer, status_t(Framebuffer*));
-    MOCK_METHOD1(unbindFrameBuffer, void(Framebuffer*));
-    MOCK_METHOD1(drawMesh, void(const Mesh&));
+    MOCK_METHOD1(bindFrameBuffer, status_t(renderengine::Framebuffer*));
+    MOCK_METHOD1(unbindFrameBuffer, void(renderengine::Framebuffer*));
+    MOCK_METHOD1(drawMesh, void(const renderengine::Mesh&));
     MOCK_CONST_METHOD0(getMaxTextureSize, size_t());
     MOCK_CONST_METHOD0(getMaxViewportDims, size_t());
     MOCK_CONST_METHOD0(isProtected, bool());
@@ -82,22 +81,6 @@
                           ANativeWindowBuffer*, base::unique_fd*));
 };
 
-class Image : public renderengine::Image {
-public:
-    Image();
-    ~Image() override;
-
-    MOCK_METHOD2(setNativeWindowBuffer, bool(ANativeWindowBuffer*, bool));
-};
-
-class Framebuffer : public renderengine::Framebuffer {
-public:
-    Framebuffer();
-    ~Framebuffer() override;
-
-    MOCK_METHOD2(setNativeWindowBuffer, bool(ANativeWindowBuffer*, bool));
-};
-
 } // namespace mock
 } // namespace renderengine
 } // namespace android
diff --git a/services/surfaceflinger/tests/unittests/mock/RenderEngine/MockRenderEngine.cpp b/libs/renderengine/mock/Framebuffer.cpp
similarity index 70%
copy from services/surfaceflinger/tests/unittests/mock/RenderEngine/MockRenderEngine.cpp
copy to libs/renderengine/mock/Framebuffer.cpp
index fbfbc3f..fbdcaab 100644
--- a/services/surfaceflinger/tests/unittests/mock/RenderEngine/MockRenderEngine.cpp
+++ b/libs/renderengine/mock/Framebuffer.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2018 The Android Open Source Project
+ * 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.
@@ -14,21 +14,14 @@
  * limitations under the License.
  */
 
-#include "mock/RenderEngine/MockRenderEngine.h"
-
-#include <ui/Region.h>
+#include <renderengine/mock/Framebuffer.h>
 
 namespace android {
 namespace renderengine {
 namespace mock {
 
-// Explicit default instantiation is recommended.
-RenderEngine::RenderEngine() = default;
-RenderEngine::~RenderEngine() = default;
-
-Image::Image() = default;
-Image::~Image() = default;
-
+// The Google Mock documentation recommends explicit non-header instantiations
+// for better compile time performance.
 Framebuffer::Framebuffer() = default;
 Framebuffer::~Framebuffer() = default;
 
diff --git a/services/surfaceflinger/tests/unittests/mock/RenderEngine/MockRenderEngine.cpp b/libs/renderengine/mock/Image.cpp
similarity index 68%
copy from services/surfaceflinger/tests/unittests/mock/RenderEngine/MockRenderEngine.cpp
copy to libs/renderengine/mock/Image.cpp
index fbfbc3f..57f4346 100644
--- a/services/surfaceflinger/tests/unittests/mock/RenderEngine/MockRenderEngine.cpp
+++ b/libs/renderengine/mock/Image.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2018 The Android Open Source Project
+ * 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.
@@ -14,24 +14,17 @@
  * limitations under the License.
  */
 
-#include "mock/RenderEngine/MockRenderEngine.h"
-
-#include <ui/Region.h>
+#include <renderengine/mock/Image.h>
 
 namespace android {
 namespace renderengine {
 namespace mock {
 
-// Explicit default instantiation is recommended.
-RenderEngine::RenderEngine() = default;
-RenderEngine::~RenderEngine() = default;
-
+// The Google Mock documentation recommends explicit non-header instantiations
+// for better compile time performance.
 Image::Image() = default;
 Image::~Image() = default;
 
-Framebuffer::Framebuffer() = default;
-Framebuffer::~Framebuffer() = default;
-
 } // namespace mock
 } // namespace renderengine
 } // namespace android
diff --git a/services/surfaceflinger/tests/unittests/mock/RenderEngine/MockRenderEngine.cpp b/libs/renderengine/mock/RenderEngine.cpp
similarity index 71%
rename from services/surfaceflinger/tests/unittests/mock/RenderEngine/MockRenderEngine.cpp
rename to libs/renderengine/mock/RenderEngine.cpp
index fbfbc3f..261636d 100644
--- a/services/surfaceflinger/tests/unittests/mock/RenderEngine/MockRenderEngine.cpp
+++ b/libs/renderengine/mock/RenderEngine.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2018 The Android Open Source Project
+ * 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.
@@ -14,24 +14,17 @@
  * limitations under the License.
  */
 
-#include "mock/RenderEngine/MockRenderEngine.h"
-
-#include <ui/Region.h>
+#include <renderengine/mock/RenderEngine.h>
 
 namespace android {
 namespace renderengine {
 namespace mock {
 
-// Explicit default instantiation is recommended.
+// The Google Mock documentation recommends explicit non-header instantiations
+// for better compile time performance.
 RenderEngine::RenderEngine() = default;
 RenderEngine::~RenderEngine() = default;
 
-Image::Image() = default;
-Image::~Image() = default;
-
-Framebuffer::Framebuffer() = default;
-Framebuffer::~Framebuffer() = default;
-
 } // namespace mock
 } // namespace renderengine
 } // namespace android
diff --git a/libs/renderengine/tests/RenderEngineTest.cpp b/libs/renderengine/tests/RenderEngineTest.cpp
index e43ee37..bef25a8 100644
--- a/libs/renderengine/tests/RenderEngineTest.cpp
+++ b/libs/renderengine/tests/RenderEngineTest.cpp
@@ -172,6 +172,12 @@
     template <typename SourceVariant>
     void fillBufferColorTransform();
 
+    template <typename SourceVariant>
+    void fillRedBufferWithRoundedCorners();
+
+    template <typename SourceVariant>
+    void fillBufferWithRoundedCorners();
+
     void fillRedBufferTextureTransform();
 
     void fillBufferTextureTransform();
@@ -184,6 +190,12 @@
 
     void fillBufferWithoutPremultiplyAlpha();
 
+    void fillGreenColorBufferThenClearRegion();
+
+    void clearLeftRegion();
+
+    void fillBufferThenClearRegion();
+
     // Dumb hack to get aroud the fact that tear-down for renderengine isn't
     // well defined right now, so we can't create multiple instances
     static std::unique_ptr<renderengine::RenderEngine> sRE;
@@ -495,6 +507,42 @@
     expectBufferColor(fullscreenRect(), 191, 0, 0, 255);
 }
 
+template <typename SourceVariant>
+void RenderEngineTest::fillRedBufferWithRoundedCorners() {
+    renderengine::DisplaySettings settings;
+    settings.physicalDisplay = fullscreenRect();
+    settings.clip = fullscreenRect();
+
+    std::vector<renderengine::LayerSettings> layers;
+
+    renderengine::LayerSettings layer;
+    layer.geometry.boundaries = fullscreenRect().toFloatRect();
+    layer.geometry.roundedCornersRadius = 5.0f;
+    layer.geometry.roundedCornersCrop = fullscreenRect().toFloatRect();
+    SourceVariant::fillColor(layer, 1.0f, 0.0f, 0.0f, this);
+    layer.alpha = 1.0f;
+
+    layers.push_back(layer);
+
+    invokeDraw(settings, layers, mBuffer);
+}
+
+template <typename SourceVariant>
+void RenderEngineTest::fillBufferWithRoundedCorners() {
+    fillRedBufferWithRoundedCorners<SourceVariant>();
+    // Corners should be ignored...
+    expectBufferColor(Rect(0, 0, 1, 1), 0, 0, 0, 0);
+    expectBufferColor(Rect(DEFAULT_DISPLAY_WIDTH - 1, 0, DEFAULT_DISPLAY_WIDTH, 1), 0, 0, 0, 0);
+    expectBufferColor(Rect(0, DEFAULT_DISPLAY_HEIGHT - 1, 1, DEFAULT_DISPLAY_HEIGHT), 0, 0, 0, 0);
+    expectBufferColor(Rect(DEFAULT_DISPLAY_WIDTH - 1, DEFAULT_DISPLAY_HEIGHT - 1,
+                           DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT),
+                      0, 0, 0, 0);
+    // ...And the non-rounded portion should be red.
+    // Other pixels may be anti-aliased, so let's not check those.
+    expectBufferColor(Rect(5, 5, DEFAULT_DISPLAY_WIDTH - 5, DEFAULT_DISPLAY_HEIGHT - 5), 255, 0, 0,
+                      255);
+}
+
 void RenderEngineTest::fillRedBufferTextureTransform() {
     renderengine::DisplaySettings settings;
     settings.physicalDisplay = fullscreenRect();
@@ -623,6 +671,30 @@
     expectBufferColor(fullscreenRect(), 128, 0, 0, 64, 1);
 }
 
+void RenderEngineTest::clearLeftRegion() {
+    renderengine::DisplaySettings settings;
+    settings.physicalDisplay = fullscreenRect();
+    // Here logical space is 4x4
+    settings.clip = Rect(4, 4);
+    settings.globalTransform = mat4::scale(vec4(2, 4, 0, 1));
+    settings.clearRegion = Region(Rect(1, 1));
+    std::vector<renderengine::LayerSettings> layers;
+    // dummy layer, without bounds should not render anything
+    renderengine::LayerSettings layer;
+    layers.push_back(layer);
+    invokeDraw(settings, layers, mBuffer);
+}
+
+void RenderEngineTest::fillBufferThenClearRegion() {
+    fillGreenBuffer<ColorSourceVariant>();
+    // Reuse mBuffer
+    clearLeftRegion();
+    expectBufferColor(Rect(DEFAULT_DISPLAY_WIDTH / 2, DEFAULT_DISPLAY_HEIGHT), 0, 0, 0, 255);
+    expectBufferColor(Rect(DEFAULT_DISPLAY_WIDTH / 2, 0, DEFAULT_DISPLAY_WIDTH,
+                           DEFAULT_DISPLAY_HEIGHT),
+                      0, 255, 0, 255);
+}
+
 TEST_F(RenderEngineTest, drawLayers_noLayersToDraw) {
     drawEmptyLayers();
 }
@@ -671,6 +743,10 @@
     fillBufferLayerTransform<ColorSourceVariant>();
 }
 
+TEST_F(RenderEngineTest, drawLayers_fillBufferRoundedCorners_colorSource) {
+    fillBufferWithRoundedCorners<ColorSourceVariant>();
+}
+
 TEST_F(RenderEngineTest, drawLayers_fillRedBuffer_opaqueBufferSource) {
     fillRedBuffer<BufferSourceVariant<ForceOpaqueBufferVariant>>();
 }
@@ -715,6 +791,10 @@
     fillBufferLayerTransform<BufferSourceVariant<ForceOpaqueBufferVariant>>();
 }
 
+TEST_F(RenderEngineTest, drawLayers_fillBufferRoundedCorners_opaqueBufferSource) {
+    fillBufferWithRoundedCorners<BufferSourceVariant<ForceOpaqueBufferVariant>>();
+}
+
 TEST_F(RenderEngineTest, drawLayers_fillRedBuffer_bufferSource) {
     fillRedBuffer<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
 }
@@ -759,6 +839,10 @@
     fillBufferLayerTransform<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
 }
 
+TEST_F(RenderEngineTest, drawLayers_fillBufferRoundedCorners_bufferSource) {
+    fillBufferWithRoundedCorners<BufferSourceVariant<RelaxOpaqueBufferVariant>>();
+}
+
 TEST_F(RenderEngineTest, drawLayers_fillBufferTextureTransform) {
     fillBufferTextureTransform();
 }
@@ -771,4 +855,8 @@
     fillBufferWithoutPremultiplyAlpha();
 }
 
+TEST_F(RenderEngineTest, drawLayers_fillBufferThenClearRegion) {
+    fillBufferThenClearRegion();
+}
+
 } // namespace android
diff --git a/libs/ui/BufferHubBuffer.cpp b/libs/ui/BufferHubBuffer.cpp
index 0582e1a..1184960 100644
--- a/libs/ui/BufferHubBuffer.cpp
+++ b/libs/ui/BufferHubBuffer.cpp
@@ -64,7 +64,6 @@
 
 using BufferHubDefs::AnyClientAcquired;
 using BufferHubDefs::AnyClientGained;
-using BufferHubDefs::AnyClientPosted;
 using BufferHubDefs::IsClientAcquired;
 using BufferHubDefs::IsClientGained;
 using BufferHubDefs::IsClientPosted;
@@ -226,8 +225,7 @@
 
 int BufferHubBuffer::Post() {
     uint32_t current_buffer_state = buffer_state_->load(std::memory_order_acquire);
-    uint32_t current_active_clients_bit_mask = 0U;
-    uint32_t updated_buffer_state = 0U;
+    uint32_t updated_buffer_state = (~mClientStateMask) & kHighBitsMask;
     do {
         if (!IsClientGained(current_buffer_state, mClientStateMask)) {
             ALOGE("%s: Cannot post a buffer that is not gained by this client. buffer_id=%d "
@@ -236,9 +234,7 @@
             return -EBUSY;
         }
         // Set the producer client buffer state to released, other clients' buffer state to posted.
-        current_active_clients_bit_mask = active_clients_bit_mask_->load(std::memory_order_acquire);
-        updated_buffer_state =
-                current_active_clients_bit_mask & (~mClientStateMask) & kHighBitsMask;
+        // Post to all existing and non-existing clients.
     } while (!buffer_state_->compare_exchange_weak(current_buffer_state, updated_buffer_state,
                                                    std::memory_order_acq_rel,
                                                    std::memory_order_acquire));
diff --git a/libs/ui/tests/BufferHubBuffer_test.cpp b/libs/ui/tests/BufferHubBuffer_test.cpp
index 1b339a0..69b9590 100644
--- a/libs/ui/tests/BufferHubBuffer_test.cpp
+++ b/libs/ui/tests/BufferHubBuffer_test.cpp
@@ -67,9 +67,9 @@
     }
 
     std::unique_ptr<BufferHubBuffer> b1;
-    uint64_t b1ClientMask = 0U;
+    uint32_t b1ClientMask = 0U;
     std::unique_ptr<BufferHubBuffer> b2;
-    uint64_t b2ClientMask = 0U;
+    uint32_t b2ClientMask = 0U;
 
 private:
     // Creates b1 and b2 as the clients of the same buffer for testing.
@@ -125,7 +125,7 @@
     auto b1 = BufferHubBuffer::Create(kWidth, kHeight, kLayerCount, kFormat, kUsage,
                                       kUserMetadataSize);
     int id1 = b1->id();
-    uint64_t bufferStateMask1 = b1->client_state_mask();
+    uint32_t bufferStateMask1 = b1->client_state_mask();
     EXPECT_NE(bufferStateMask1, 0U);
     EXPECT_TRUE(b1->IsValid());
     EXPECT_EQ(b1->user_metadata_size(), kUserMetadataSize);
@@ -148,7 +148,7 @@
     EXPECT_EQ(b2->user_metadata_size(), kUserMetadataSize);
 
     int id2 = b2->id();
-    uint64_t bufferStateMask2 = b2->client_state_mask();
+    uint32_t bufferStateMask2 = b2->client_state_mask();
     EXPECT_NE(bufferStateMask2, 0U);
 
     // These two buffer instances are based on the same physical buffer under the
@@ -340,5 +340,53 @@
     EXPECT_EQ(b2->Release(), 0);
 }
 
+TEST_F(BufferHubBufferStateTransitionTest, BasicUsage) {
+    // 1 producer buffer and 1 consumer buffer initialised in testcase setup.
+    // Test if this set of basic operation succeed:
+    // Producer post three times to the consumer, and released by consumer.
+    for (int i = 0; i < 3; ++i) {
+        ASSERT_EQ(b1->Gain(), 0);
+        ASSERT_EQ(b1->Post(), 0);
+        ASSERT_EQ(b2->Acquire(), 0);
+        ASSERT_EQ(b2->Release(), 0);
+    }
+}
+
+TEST_F(BufferHubBufferTest, createNewConsumerAfterGain) {
+    // Create a poducer buffer and gain.
+    std::unique_ptr<BufferHubBuffer> b1 =
+            BufferHubBuffer::Create(kWidth, kHeight, kLayerCount, kFormat, kUsage,
+                                    kUserMetadataSize);
+    ASSERT_EQ(b1->Gain(), 0);
+
+    // Create a consumer of the buffer and test if the consumer can acquire the
+    // buffer if producer posts.
+    auto statusOrHandle = b1->Duplicate();
+    ASSERT_TRUE(statusOrHandle);
+    std::unique_ptr<BufferHubBuffer> b2 = BufferHubBuffer::Import(std::move(statusOrHandle.take()));
+    ASSERT_NE(b1->client_state_mask(), b2->client_state_mask());
+
+    ASSERT_EQ(b1->Post(), 0);
+    EXPECT_EQ(b2->Acquire(), 0);
+}
+
+TEST_F(BufferHubBufferTest, createNewConsumerAfterPost) {
+    // Create a poducer buffer and post.
+    std::unique_ptr<BufferHubBuffer> b1 =
+            BufferHubBuffer::Create(kWidth, kHeight, kLayerCount, kFormat, kUsage,
+                                    kUserMetadataSize);
+    ASSERT_EQ(b1->Gain(), 0);
+    ASSERT_EQ(b1->Post(), 0);
+
+    // Create a consumer of the buffer and test if the consumer can acquire the
+    // buffer if producer posts.
+    auto statusOrHandle = b1->Duplicate();
+    ASSERT_TRUE(statusOrHandle);
+    std::unique_ptr<BufferHubBuffer> b2 = BufferHubBuffer::Import(std::move(statusOrHandle.take()));
+    ASSERT_NE(b1->client_state_mask(), b2->client_state_mask());
+
+    EXPECT_EQ(b2->Acquire(), 0);
+}
+
 } // namespace
 } // namespace android
diff --git a/libs/vr/libbufferhub/buffer_hub-test.cpp b/libs/vr/libbufferhub/buffer_hub-test.cpp
index 1359f4c..487a604 100644
--- a/libs/vr/libbufferhub/buffer_hub-test.cpp
+++ b/libs/vr/libbufferhub/buffer_hub-test.cpp
@@ -361,9 +361,11 @@
   ASSERT_TRUE(p.get() != nullptr);
   ASSERT_EQ(0, p->GainAsync());
   ASSERT_EQ(0, p->Post(LocalHandle()));
-  // Producer state bit is in released state after post. The overall state of
-  // the buffer is also released because there is no consumer of this buffer.
-  ASSERT_TRUE(IsBufferReleased(p->buffer_state()));
+  // Producer state bit is in released state after post, other clients shall be
+  // in posted state although there is no consumer of this buffer yet.
+  ASSERT_TRUE(IsClientReleased(p->buffer_state(), p->client_state_mask()));
+  ASSERT_FALSE(IsBufferReleased(p->buffer_state()));
+  ASSERT_TRUE(AnyClientPosted(p->buffer_state()));
 
   // Gain in released state should succeed.
   LocalHandle invalid_fence;
@@ -450,27 +452,17 @@
   LocalHandle invalid_fence;
 
   // Post the gained buffer before any consumer gets created.
-  // The buffer should be in released state because it is not expected to be
-  // read by any clients.
   EXPECT_EQ(0, p->PostAsync(&metadata, invalid_fence));
-  EXPECT_TRUE(IsBufferReleased(p->buffer_state()));
+  EXPECT_FALSE(IsBufferReleased(p->buffer_state()));
   EXPECT_EQ(0, RETRY_EINTR(p->Poll(kPollTimeoutMs)));
 
-  // Newly created consumer will not be signalled for the posted buffer before
-  // its creation. It cannot acquire the buffer immediately.
+  // Newly created consumer will be signalled for the posted buffer although it
+  // is created after producer posting.
   std::unique_ptr<ConsumerBuffer> c =
       ConsumerBuffer::Import(p->CreateConsumer());
   ASSERT_TRUE(c.get() != nullptr);
-  EXPECT_FALSE(IsClientPosted(c->buffer_state(), c->client_state_mask()));
-  EXPECT_EQ(-EBUSY, c->AcquireAsync(&metadata, &invalid_fence));
-
-  // Producer should be able to gain back and post the buffer
-  EXPECT_EQ(0, p->GainAsync());
-  EXPECT_EQ(0, p->PostAsync(&metadata, invalid_fence));
-
-  // Consumer should be able to pick up the buffer this time.
+  EXPECT_TRUE(IsClientPosted(c->buffer_state(), c->client_state_mask()));
   EXPECT_EQ(0, c->AcquireAsync(&metadata, &invalid_fence));
-  EXPECT_TRUE(IsClientAcquired(c->buffer_state(), c->client_state_mask()));
 }
 
 TEST_F(LibBufferHubTest, TestCreateConsumerWhenBufferReleased) {
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 440a59d..889763a 100644
--- a/libs/vr/libbufferhub/include/private/dvr/buffer_hub_base.h
+++ b/libs/vr/libbufferhub/include/private/dvr/buffer_hub_base.h
@@ -94,6 +94,12 @@
     return buffer_state_->load(std::memory_order_acquire);
   };
 
+  // Returns whether the buffer is already released by all current clients.
+  bool is_released() {
+    return (buffer_state() &
+            active_clients_bit_mask_->load(std::memory_order_acquire)) == 0;
+  }
+
   // A state mask which is unique to a buffer hub client among all its siblings
   // sharing the same concrete graphic buffer.
   uint32_t client_state_mask() const { return client_state_mask_; }
diff --git a/libs/vr/libbufferhub/producer_buffer.cpp b/libs/vr/libbufferhub/producer_buffer.cpp
index 5274bf2..edfdddf 100644
--- a/libs/vr/libbufferhub/producer_buffer.cpp
+++ b/libs/vr/libbufferhub/producer_buffer.cpp
@@ -89,13 +89,10 @@
     return -EBUSY;
   }
 
-  // Set the producer client buffer state to released, other clients' buffer
-  // state to posted.
-  uint32_t current_active_clients_bit_mask =
-      active_clients_bit_mask_->load(std::memory_order_acquire);
-  uint32_t updated_buffer_state = current_active_clients_bit_mask &
-                                  (~client_state_mask()) &
-                                  BufferHubDefs::kHighBitsMask;
+  // Set the producer client buffer state to released, that of all other clients
+  // (both existing and non-existing clients) to posted.
+  uint32_t updated_buffer_state =
+      (~client_state_mask()) & BufferHubDefs::kHighBitsMask;
   while (!buffer_state_->compare_exchange_weak(
       current_buffer_state, updated_buffer_state, std::memory_order_acq_rel,
       std::memory_order_acquire)) {
@@ -176,7 +173,9 @@
   }
   if (BufferHubDefs::AnyClientAcquired(current_buffer_state) ||
       BufferHubDefs::AnyClientGained(current_buffer_state) ||
-      (BufferHubDefs::AnyClientPosted(current_buffer_state) &&
+      (BufferHubDefs::AnyClientPosted(
+           current_buffer_state &
+           active_clients_bit_mask_->load(std::memory_order_acquire)) &&
        !gain_posted_buffer)) {
     ALOGE("%s: not released id=%d state=%" PRIx32 ".", __FUNCTION__, id(),
           current_buffer_state);
@@ -198,7 +197,9 @@
 
     if (BufferHubDefs::AnyClientAcquired(current_buffer_state) ||
         BufferHubDefs::AnyClientGained(current_buffer_state) ||
-        (BufferHubDefs::AnyClientPosted(current_buffer_state) &&
+        (BufferHubDefs::AnyClientPosted(
+             current_buffer_state &
+             active_clients_bit_mask_->load(std::memory_order_acquire)) &&
          !gain_posted_buffer)) {
       ALOGE(
           "%s: Failed to gain the buffer. The buffer is no longer released. "
diff --git a/opengl/libs/EGL/egl_angle_platform.cpp b/opengl/libs/EGL/egl_angle_platform.cpp
index 297e0c4..00caff2 100644
--- a/opengl/libs/EGL/egl_angle_platform.cpp
+++ b/opengl/libs/EGL/egl_angle_platform.cpp
@@ -106,7 +106,7 @@
             .flags = ANDROID_DLEXT_USE_NAMESPACE,
             .library_namespace = ns,
     };
-    void* so = android_dlopen_ext("libEGL_angle.so", RTLD_LOCAL | RTLD_NOW, &dlextinfo);
+    void* so = android_dlopen_ext("libGLESv2_angle.so", RTLD_LOCAL | RTLD_NOW, &dlextinfo);
     angleGetDisplayPlatform =
             reinterpret_cast<GetDisplayPlatformFunc>(dlsym(so, "ANGLEGetDisplayPlatform"));
 
diff --git a/services/bufferhub/BufferHubService.cpp b/services/bufferhub/BufferHubService.cpp
index 2663812..54796a2 100644
--- a/services/bufferhub/BufferHubService.cpp
+++ b/services/bufferhub/BufferHubService.cpp
@@ -14,10 +14,17 @@
  * limitations under the License.
  */
 
+#include <iomanip>
+#include <sstream>
+
 #include <android/hardware_buffer.h>
 #include <bufferhub/BufferHubService.h>
 #include <cutils/native_handle.h>
 #include <log/log.h>
+#include <system/graphics-base.h>
+
+using ::android::BufferHubDefs::MetadataHeader;
+using ::android::hardware::Void;
 
 namespace android {
 namespace frameworks {
@@ -25,8 +32,6 @@
 namespace V1_0 {
 namespace implementation {
 
-using hardware::Void;
-
 Return<void> BufferHubService::allocateBuffer(const HardwareBufferDescription& description,
                                               const uint32_t userMetadataSize,
                                               allocateBuffer_cb _hidl_cb) {
@@ -124,6 +129,138 @@
     return Void();
 }
 
+Return<void> BufferHubService::debug(const hidl_handle& fd, const hidl_vec<hidl_string>& args) {
+    if (fd.getNativeHandle() == nullptr || fd->numFds < 1) {
+        ALOGE("%s: missing fd for writing.", __FUNCTION__);
+        return Void();
+    }
+
+    FILE* out = fdopen(dup(fd->data[0]), "w");
+
+    if (args.size() != 0) {
+        fprintf(out,
+                "Note: lshal bufferhub currently does not support args. Input arguments are "
+                "ignored.\n");
+    }
+
+    std::ostringstream stream;
+
+    // Get the number of clients of each buffer.
+    // Map from bufferId to bufferNode_clientCount pair.
+    std::map<int, std::pair<const std::shared_ptr<BufferNode>, uint32_t>> clientCount;
+    {
+        std::lock_guard<std::mutex> lock(mClientSetMutex);
+        for (auto iter = mClientSet.begin(); iter != mClientSet.end(); ++iter) {
+            sp<BufferClient> client = iter->promote();
+            if (client != nullptr) {
+                const std::shared_ptr<BufferNode> node = client->getBufferNode();
+                auto mapIter = clientCount.find(node->id());
+                if (mapIter != clientCount.end()) {
+                    ++mapIter->second.second;
+                } else {
+                    clientCount.emplace(node->id(),
+                                        std::pair<std::shared_ptr<BufferNode>, uint32_t>(node, 1U));
+                }
+            }
+        }
+    }
+
+    stream << "Active Buffers:\n";
+    stream << std::right;
+    stream << std::setw(6) << "Id";
+    stream << " ";
+    stream << std::setw(9) << "Clients";
+    stream << " ";
+    stream << std::setw(14) << "Geometry";
+    stream << " ";
+    stream << std::setw(6) << "Format";
+    stream << " ";
+    stream << std::setw(10) << "Usage";
+    stream << " ";
+    stream << std::setw(10) << "State";
+    stream << " ";
+    stream << std::setw(10) << "Index";
+    stream << std::endl;
+
+    for (auto iter = clientCount.begin(); iter != clientCount.end(); ++iter) {
+        const std::shared_ptr<BufferNode> node = std::move(iter->second.first);
+        const uint32_t clientCount = iter->second.second;
+        AHardwareBuffer_Desc desc = node->buffer_desc();
+
+        MetadataHeader* metadataHeader =
+                const_cast<BufferHubMetadata*>(&node->metadata())->metadata_header();
+        const uint32_t state = metadataHeader->buffer_state.load(std::memory_order_acquire);
+        const uint64_t index = metadataHeader->queue_index;
+
+        stream << std::right;
+        stream << std::setw(6) << /*Id=*/node->id();
+        stream << " ";
+        stream << std::setw(9) << /*Clients=*/clientCount;
+        stream << " ";
+        if (desc.format == HAL_PIXEL_FORMAT_BLOB) {
+            std::string size = std::to_string(desc.width) + " B";
+            stream << std::setw(14) << /*Geometry=*/size;
+        } else {
+            std::string dimensions = std::to_string(desc.width) + "x" +
+                    std::to_string(desc.height) + "x" + std::to_string(desc.layers);
+            stream << std::setw(14) << /*Geometry=*/dimensions;
+        }
+        stream << " ";
+        stream << std::setw(6) << /*Format=*/desc.format;
+        stream << " ";
+        stream << "0x" << std::hex << std::setfill('0');
+        stream << std::setw(8) << /*Usage=*/desc.usage;
+        stream << std::dec << std::setfill(' ');
+        stream << " ";
+        stream << "0x" << std::hex << std::setfill('0');
+        stream << std::setw(8) << /*State=*/state;
+        stream << " ";
+        stream << std::setw(8) << /*Index=*/index;
+        stream << std::endl;
+    }
+
+    stream << std::endl;
+
+    // Get the number of tokens of each buffer.
+    // Map from bufferId to tokenCount
+    std::map<int, uint32_t> tokenCount;
+    {
+        std::lock_guard<std::mutex> lock(mTokenMapMutex);
+        for (auto iter = mTokenMap.begin(); iter != mTokenMap.end(); ++iter) {
+            sp<BufferClient> client = iter->second.promote();
+            if (client != nullptr) {
+                const std::shared_ptr<BufferNode> node = client->getBufferNode();
+                auto mapIter = tokenCount.find(node->id());
+                if (mapIter != tokenCount.end()) {
+                    ++mapIter->second;
+                } else {
+                    tokenCount.emplace(node->id(), 1U);
+                }
+            }
+        }
+    }
+
+    stream << "Unused Tokens:\n";
+    stream << std::right;
+    stream << std::setw(8) << "Buffer Id";
+    stream << " ";
+    stream << std::setw(6) << "Tokens";
+    stream << std::endl;
+
+    for (auto iter = tokenCount.begin(); iter != tokenCount.end(); ++iter) {
+        stream << std::right;
+        stream << std::setw(8) << /*Buffer Id=*/iter->first;
+        stream << " ";
+        stream << std::setw(6) << /*Tokens=*/iter->second;
+        stream << std::endl;
+    }
+
+    fprintf(out, "%s", stream.str().c_str());
+
+    fclose(out);
+    return Void();
+}
+
 hidl_handle BufferHubService::registerToken(const wp<BufferClient>& client) {
     uint32_t token;
     std::lock_guard<std::mutex> lock(mTokenMapMutex);
diff --git a/services/bufferhub/include/bufferhub/BufferHubService.h b/services/bufferhub/include/bufferhub/BufferHubService.h
index f2c8ef8..255f329 100644
--- a/services/bufferhub/include/bufferhub/BufferHubService.h
+++ b/services/bufferhub/include/bufferhub/BufferHubService.h
@@ -32,6 +32,8 @@
 namespace implementation {
 
 using hardware::hidl_handle;
+using hardware::hidl_string;
+using hardware::hidl_vec;
 using hardware::Return;
 using hardware::graphics::common::V1_2::HardwareBufferDescription;
 
@@ -42,6 +44,8 @@
                                 allocateBuffer_cb _hidl_cb) override;
     Return<void> importBuffer(const hidl_handle& tokenHandle, importBuffer_cb _hidl_cb) override;
 
+    Return<void> debug(const hidl_handle& fd, const hidl_vec<hidl_string>& args) override;
+
     // Non-binder functions
     // Internal help function for IBufferClient::duplicate.
     hidl_handle registerToken(const wp<BufferClient>& client);
diff --git a/services/inputflinger/InputDispatcher.cpp b/services/inputflinger/InputDispatcher.cpp
index 6173452..7997928 100644
--- a/services/inputflinger/InputDispatcher.cpp
+++ b/services/inputflinger/InputDispatcher.cpp
@@ -2386,7 +2386,8 @@
             }
 
             InputTarget target;
-            sp<InputWindowHandle> windowHandle = getWindowHandleLocked(connection->inputChannel);
+            sp<InputWindowHandle> windowHandle = getWindowHandleLocked(
+                    connection->inputChannel->getToken());
             if (windowHandle != nullptr) {
                 const InputWindowInfo* windowInfo = windowHandle->getInfo();
                 target.xOffset = -windowInfo->frameLeft;
@@ -3024,13 +3025,13 @@
 }
 
 sp<InputWindowHandle> InputDispatcher::getWindowHandleLocked(
-        const sp<InputChannel>& inputChannel) const {
+        const sp<IBinder>& windowHandleToken) const {
     for (auto& it : mWindowHandlesByDisplay) {
         const Vector<sp<InputWindowHandle>> windowHandles = it.second;
         size_t numWindows = windowHandles.size();
         for (size_t i = 0; i < numWindows; i++) {
             const sp<InputWindowHandle>& windowHandle = windowHandles.itemAt(i);
-            if (windowHandle->getToken() == inputChannel->getToken()) {
+            if (windowHandle->getToken() == windowHandleToken) {
                 return windowHandle;
             }
         }
@@ -3375,27 +3376,30 @@
 
 bool InputDispatcher::transferTouchFocus(const sp<InputChannel>& fromChannel,
         const sp<InputChannel>& toChannel) {
+    return transferTouchFocus(fromChannel->getToken(), toChannel->getToken());
+}
+
+bool InputDispatcher::transferTouchFocus(const sp<IBinder>& fromToken, const sp<IBinder>& toToken) {
+    if (fromToken == toToken) {
 #if DEBUG_FOCUS
-    ALOGD("transferTouchFocus: fromChannel=%s, toChannel=%s",
-            fromChannel->getName().c_str(), toChannel->getName().c_str());
+        ALOGD("Trivial transfer to same window.");
 #endif
+        return true;
+    }
+
     { // acquire lock
         AutoMutex _l(mLock);
 
-        sp<InputWindowHandle> fromWindowHandle = getWindowHandleLocked(fromChannel);
-        sp<InputWindowHandle> toWindowHandle = getWindowHandleLocked(toChannel);
+        sp<InputWindowHandle> fromWindowHandle = getWindowHandleLocked(fromToken);
+        sp<InputWindowHandle> toWindowHandle = getWindowHandleLocked(toToken);
+#if DEBUG_FOCUS
+        ALOGD("transferTouchFocus: fromWindowHandle=%s, toWindowHandle=%s",
+            fromWindowHandle->getName().c_str(), toWindowHandle->getName().c_str());
+#endif
         if (fromWindowHandle == nullptr || toWindowHandle == nullptr) {
-#if DEBUG_FOCUS
-            ALOGD("Cannot transfer focus because from or to window not found.");
-#endif
+            ALOGW("Cannot transfer focus because from or to window not found.");
             return false;
         }
-        if (fromWindowHandle == toWindowHandle) {
-#if DEBUG_FOCUS
-            ALOGD("Trivial transfer to same window.");
-#endif
-            return true;
-        }
         if (fromWindowHandle->getInfo()->displayId != toWindowHandle->getInfo()->displayId) {
 #if DEBUG_FOCUS
             ALOGD("Cannot transfer focus because windows are on different displays.");
@@ -3433,6 +3437,9 @@
             return false;
         }
 
+
+        sp<InputChannel> fromChannel = getInputChannelLocked(fromToken);
+        sp<InputChannel> toChannel = getInputChannelLocked(toToken);
         ssize_t fromConnectionIndex = getConnectionIndexLocked(fromChannel);
         ssize_t toConnectionIndex = getConnectionIndexLocked(toChannel);
         if (fromConnectionIndex >= 0 && toConnectionIndex >= 0) {
diff --git a/services/inputflinger/InputDispatcher.h b/services/inputflinger/InputDispatcher.h
index 7e6de6a..970632e 100644
--- a/services/inputflinger/InputDispatcher.h
+++ b/services/inputflinger/InputDispatcher.h
@@ -343,11 +343,12 @@
      */
     virtual void setInputFilterEnabled(bool enabled) = 0;
 
-    /* Transfers touch focus from the window associated with one channel to the
-     * window associated with the other channel.
+    /* Transfers touch focus from one window to another window.
      *
      * Returns true on success.  False if the window did not actually have touch focus.
      */
+    virtual bool transferTouchFocus(const sp<IBinder>& fromToken, const sp<IBinder>& toToken) = 0;
+
     virtual bool transferTouchFocus(const sp<InputChannel>& fromChannel,
             const sp<InputChannel>& toChannel) = 0;
 
@@ -414,6 +415,7 @@
     virtual void setInputDispatchMode(bool enabled, bool frozen);
     virtual void setInputFilterEnabled(bool enabled);
 
+    virtual bool transferTouchFocus(const sp<IBinder>& fromToken, const sp<IBinder>& toToken);
     virtual bool transferTouchFocus(const sp<InputChannel>& fromChannel,
             const sp<InputChannel>& toChannel);
 
@@ -995,7 +997,7 @@
     std::unordered_map<int32_t, Vector<sp<InputWindowHandle>>> mWindowHandlesByDisplay;
     // Get window handles by display, return an empty vector if not found.
     Vector<sp<InputWindowHandle>> getWindowHandlesLocked(int32_t displayId) const;
-    sp<InputWindowHandle> getWindowHandleLocked(const sp<InputChannel>& inputChannel) const;
+    sp<InputWindowHandle> getWindowHandleLocked(const sp<IBinder>& windowHandleToken) const;
     sp<InputChannel> getInputChannelLocked(const sp<IBinder>& windowToken) const;
     bool hasWindowHandleLocked(const sp<InputWindowHandle>& windowHandle) const;
 
diff --git a/services/inputflinger/InputManager.cpp b/services/inputflinger/InputManager.cpp
index 15d8070..1d7ea00 100644
--- a/services/inputflinger/InputManager.cpp
+++ b/services/inputflinger/InputManager.cpp
@@ -111,6 +111,10 @@
     }
 }
 
+void InputManager::transferTouchFocus(const sp<IBinder>& fromToken, const sp<IBinder>& toToken) {
+    mDispatcher->transferTouchFocus(fromToken, toToken);
+}
+
 // Used by tests only.
 void InputManager::registerInputChannel(const sp<InputChannel>& channel) {
     IPCThreadState* ipc = IPCThreadState::self();
diff --git a/services/inputflinger/InputManager.h b/services/inputflinger/InputManager.h
index 8f7551e..ab309b1 100644
--- a/services/inputflinger/InputManager.h
+++ b/services/inputflinger/InputManager.h
@@ -91,6 +91,7 @@
     virtual sp<InputDispatcherInterface> getDispatcher();
 
     virtual void setInputWindows(const Vector<InputWindowInfo>& handles);
+    virtual void transferTouchFocus(const sp<IBinder>& fromToken, const sp<IBinder>& toToken);
 
     virtual void registerInputChannel(const sp<InputChannel>& channel);
     virtual void unregisterInputChannel(const sp<InputChannel>& channel);
diff --git a/services/inputflinger/host/InputFlinger.h b/services/inputflinger/host/InputFlinger.h
index 82ff089..9d0be95 100644
--- a/services/inputflinger/host/InputFlinger.h
+++ b/services/inputflinger/host/InputFlinger.h
@@ -40,6 +40,7 @@
 
     virtual status_t dump(int fd, const Vector<String16>& args);
     void setInputWindows(const Vector<InputWindowInfo>&) {}
+    void transferTouchFocus(const sp<IBinder>&, const sp<IBinder>&) {}
     void registerInputChannel(const sp<InputChannel>&) {}
     void unregisterInputChannel(const sp<InputChannel>&) {}
 
diff --git a/services/surfaceflinger/Android.bp b/services/surfaceflinger/Android.bp
index 0c1ea44..3dee0c0 100644
--- a/services/surfaceflinger/Android.bp
+++ b/services/surfaceflinger/Android.bp
@@ -1,7 +1,6 @@
 cc_defaults {
     name: "surfaceflinger_defaults",
     cflags: [
-        "-DLOG_TAG=\"SurfaceFlinger\"",
         "-Wall",
         "-Werror",
         "-Wformat",
@@ -15,6 +14,7 @@
     name: "libsurfaceflinger_defaults",
     defaults: ["surfaceflinger_defaults"],
     cflags: [
+        "-DLOG_TAG=\"SurfaceFlinger\"",
         "-DGL_GLEXT_PROTOTYPES",
         "-DEGL_EGLEXT_PROTOTYPES",
     ],
@@ -57,6 +57,7 @@
         "libutils",
     ],
     static_libs: [
+        "libcompositionengine",
         "librenderengine",
         "libserviceutils",
         "libtrace_proto",
@@ -69,6 +70,7 @@
         "android.hardware.graphics.composer@2.3-command-buffer",
     ],
     export_static_lib_headers: [
+        "libcompositionengine",
         "librenderengine",
         "libserviceutils",
     ],
@@ -171,6 +173,9 @@
 cc_defaults {
     name: "libsurfaceflinger_binary",
     defaults: ["surfaceflinger_defaults"],
+    cflags: [
+        "-DLOG_TAG=\"SurfaceFlinger\"",
+    ],
     whole_static_libs: [
         "libsigchain",
     ],
diff --git a/services/surfaceflinger/BufferLayer.cpp b/services/surfaceflinger/BufferLayer.cpp
index 0a3be71..4e4d7dd 100644
--- a/services/surfaceflinger/BufferLayer.cpp
+++ b/services/surfaceflinger/BufferLayer.cpp
@@ -396,7 +396,6 @@
     }
 
     // Capture the old state of the layer for comparisons later
-    Mutex::Autolock lock(mStateMutex);
     const State& s(getDrawingState());
     const bool oldOpacity = isOpaque(s);
     sp<GraphicBuffer> oldBuffer = mActiveBuffer;
@@ -503,7 +502,7 @@
 
     // FIXME: postedRegion should be dirty & bounds
     // transform the dirty region to window-manager space
-    return getTransformLocked().transform(Region(getBufferSize(s)));
+    return getTransform().transform(Region(getBufferSize(s)));
 }
 
 // transaction
@@ -551,7 +550,7 @@
 
 // h/w composer set-up
 bool BufferLayer::allTransactionsSignaled() {
-    auto headFrameNumber = getHeadFrameNumberLocked();
+    auto headFrameNumber = getHeadFrameNumber();
     bool matchingFramesFound = false;
     bool allTransactionsApplied = true;
     Mutex::Autolock lock(mLocalSyncPointMutex);
@@ -604,7 +603,6 @@
 
 void BufferLayer::drawWithOpenGL(const RenderArea& renderArea, bool useIdentityTransform) const {
     ATRACE_CALL();
-    Mutex::Autolock lock(mStateMutex);
     const State& s(getDrawingState());
 
     computeGeometry(renderArea, getBE().mMesh, useIdentityTransform);
@@ -623,9 +621,9 @@
      * minimal value)? Or, we could make GL behave like HWC -- but this feel
      * like more of a hack.
      */
-    const Rect bounds{computeBoundsLocked()}; // Rounds from FloatRect
+    const Rect bounds{computeBounds()}; // Rounds from FloatRect
 
-    ui::Transform t = getTransformLocked();
+    ui::Transform t = getTransform();
     Rect win = bounds;
     const int bufferWidth = getBufferSize(s).getWidth();
     const int bufferHeight = getBufferSize(s).getHeight();
@@ -644,7 +642,7 @@
     texCoords[2] = vec2(right, 1.0f - bottom);
     texCoords[3] = vec2(right, 1.0f - top);
 
-    const auto roundedCornerState = getRoundedCornerStateLocked();
+    const auto roundedCornerState = getRoundedCornerState();
     const auto cropRect = roundedCornerState.cropRect;
     setupRoundedCornersCropCoordinates(win, cropRect);
 
@@ -666,12 +664,7 @@
 }
 
 uint64_t BufferLayer::getHeadFrameNumber() const {
-    Mutex::Autolock lock(mStateMutex);
-    return getHeadFrameNumberLocked();
-}
-
-uint64_t BufferLayer::getHeadFrameNumberLocked() const {
-    if (hasFrameUpdateLocked()) {
+    if (hasFrameUpdate()) {
         return getFrameNumber();
     } else {
         return mCurrentFrameNumber;
@@ -698,7 +691,7 @@
         std::swap(bufWidth, bufHeight);
     }
 
-    if (getTransformToDisplayInverseLocked()) {
+    if (getTransformToDisplayInverse()) {
         uint32_t invTransform = DisplayDevice::getPrimaryDisplayOrientationTransform();
         if (invTransform & ui::Transform::ROT_90) {
             std::swap(bufWidth, bufHeight);
diff --git a/services/surfaceflinger/BufferLayer.h b/services/surfaceflinger/BufferLayer.h
index 98ae286..be16cf5 100644
--- a/services/surfaceflinger/BufferLayer.h
+++ b/services/surfaceflinger/BufferLayer.h
@@ -69,7 +69,7 @@
     bool isOpaque(const Layer::State& s) const override;
 
     // isVisible - true if this layer is visible, false otherwise
-    bool isVisible() const override EXCLUDES(mStateMutex);
+    bool isVisible() const override;
 
     // isProtected - true if the layer may contain protected content in the
     // GRALLOC_USAGE_PROTECTED sense.
@@ -91,7 +91,7 @@
     bool onPostComposition(const std::optional<DisplayId>& displayId,
                            const std::shared_ptr<FenceTime>& glDoneFence,
                            const std::shared_ptr<FenceTime>& presentFence,
-                           const CompositorTiming& compositorTiming) override EXCLUDES(mStateMutex);
+                           const CompositorTiming& compositorTiming) override;
 
     // latchBuffer - called each time the screen is redrawn and returns whether
     // the visible regions need to be recomputed (this is a fairly heavy
@@ -101,13 +101,13 @@
     // releaseFence will be populated with a native fence that fires when
     // composition has completed.
     Region latchBuffer(bool& recomputeVisibleRegions, nsecs_t latchTime,
-                       const sp<Fence>& releaseFence) override EXCLUDES(mStateMutex);
+                       const sp<Fence>& releaseFence) override;
 
     bool isBufferLatched() const override { return mRefreshPending; }
 
     void notifyAvailableFrames() override;
 
-    bool hasReadyFrame() const override EXCLUDES(mStateMutex);
+    bool hasReadyFrame() const override;
 
     // Returns the current scaling mode, unless mOverrideScalingMode
     // is set, in which case, it returns mOverrideScalingMode
@@ -118,24 +118,19 @@
     // Functions that must be implemented by derived classes
     // -----------------------------------------------------------------------
 private:
-    virtual bool fenceHasSignaled() const EXCLUDES(mStateMutex) = 0;
+    virtual bool fenceHasSignaled() const = 0;
 
     virtual nsecs_t getDesiredPresentTime() = 0;
-    std::shared_ptr<FenceTime> getCurrentFenceTime() const EXCLUDES(mStateMutex) {
-        Mutex::Autolock lock(mStateMutex);
-        return getCurrentFenceTimeLocked();
-    }
-
-    virtual std::shared_ptr<FenceTime> getCurrentFenceTimeLocked() const REQUIRES(mStateMutex) = 0;
+    virtual std::shared_ptr<FenceTime> getCurrentFenceTime() const = 0;
 
     virtual void getDrawingTransformMatrix(float *matrix) = 0;
-    virtual uint32_t getDrawingTransform() const REQUIRES(mStateMutex) = 0;
-    virtual ui::Dataspace getDrawingDataSpace() const REQUIRES(mStateMutex) = 0;
-    virtual Rect getDrawingCrop() const REQUIRES(mStateMutex) = 0;
+    virtual uint32_t getDrawingTransform() const = 0;
+    virtual ui::Dataspace getDrawingDataSpace() const = 0;
+    virtual Rect getDrawingCrop() const = 0;
     virtual uint32_t getDrawingScalingMode() const = 0;
-    virtual Region getDrawingSurfaceDamage() const EXCLUDES(mStateMutex) = 0;
-    virtual const HdrMetadata& getDrawingHdrMetadata() const EXCLUDES(mStateMutex) = 0;
-    virtual int getDrawingApi() const EXCLUDES(mStateMutex) = 0;
+    virtual Region getDrawingSurfaceDamage() const = 0;
+    virtual const HdrMetadata& getDrawingHdrMetadata() const = 0;
+    virtual int getDrawingApi() const = 0;
     virtual PixelFormat getPixelFormat() const = 0;
 
     virtual uint64_t getFrameNumber() const = 0;
@@ -143,21 +138,20 @@
     virtual bool getAutoRefresh() const = 0;
     virtual bool getSidebandStreamChanged() const = 0;
 
-    virtual std::optional<Region> latchSidebandStream(bool& recomputeVisibleRegions)
-            EXCLUDES(mStateMutex) = 0;
+    virtual std::optional<Region> latchSidebandStream(bool& recomputeVisibleRegions) = 0;
 
-    virtual bool hasFrameUpdateLocked() const REQUIRES(mStateMutex) = 0;
+    virtual bool hasFrameUpdate() const = 0;
 
     virtual void setFilteringEnabled(bool enabled) = 0;
 
-    virtual status_t bindTextureImage() EXCLUDES(mStateMutex) = 0;
+    virtual status_t bindTextureImage() = 0;
     virtual status_t updateTexImage(bool& recomputeVisibleRegions, nsecs_t latchTime,
-                                    const sp<Fence>& flushFence) REQUIRES(mStateMutex) = 0;
+                                    const sp<Fence>& flushFence) = 0;
 
-    virtual status_t updateActiveBuffer() REQUIRES(mStateMutex) = 0;
+    virtual status_t updateActiveBuffer() = 0;
     virtual status_t updateFrameNumber(nsecs_t latchTime) = 0;
 
-    virtual void setHwcLayerBuffer(DisplayId displayId) EXCLUDES(mStateMutex) = 0;
+    virtual void setHwcLayerBuffer(DisplayId displayId) = 0;
 
 protected:
     // Loads the corresponding system property once per process
@@ -166,15 +160,10 @@
     // Check all of the local sync points to ensure that all transactions
     // which need to have been applied prior to the frame which is about to
     // be latched have signaled
-    bool allTransactionsSignaled() REQUIRES(mStateMutex);
+    bool allTransactionsSignaled();
 
     static bool getOpacityForFormat(uint32_t format);
 
-    bool hasFrameUpdate() const EXCLUDES(mStateMutex) {
-        Mutex::Autolock lock(mStateMutex);
-        return hasFrameUpdateLocked();
-    }
-
     // from GLES
     const uint32_t mTextureName;
 
@@ -183,12 +172,9 @@
     bool needsFiltering(const RenderArea& renderArea) const;
 
     // drawing
-    void drawWithOpenGL(const RenderArea& renderArea, bool useIdentityTransform) const
-            EXCLUDES(mStateMutex);
+    void drawWithOpenGL(const RenderArea& renderArea, bool useIdentityTransform) const;
 
-    uint64_t getHeadFrameNumber() const EXCLUDES(mStateMutex);
-
-    uint64_t getHeadFrameNumberLocked() const REQUIRES(mStateMutex);
+    uint64_t getHeadFrameNumber() const;
 
     uint32_t mCurrentScalingMode{NATIVE_WINDOW_SCALING_MODE_FREEZE};
 
@@ -200,7 +186,7 @@
 
     bool mRefreshPending{false};
 
-    Rect getBufferSize(const State& s) const override REQUIRES(mStateMutex);
+    Rect getBufferSize(const State& s) const override;
 };
 
 } // namespace android
diff --git a/services/surfaceflinger/BufferQueueLayer.cpp b/services/surfaceflinger/BufferQueueLayer.cpp
index 3341b98..5a61122 100644
--- a/services/surfaceflinger/BufferQueueLayer.cpp
+++ b/services/surfaceflinger/BufferQueueLayer.cpp
@@ -51,7 +51,7 @@
     return history;
 }
 
-bool BufferQueueLayer::getTransformToDisplayInverseLocked() const {
+bool BufferQueueLayer::getTransformToDisplayInverse() const {
     return mConsumer->getTransformToDisplayInverse();
 }
 
@@ -131,7 +131,7 @@
     return mConsumer->getTimestamp();
 }
 
-std::shared_ptr<FenceTime> BufferQueueLayer::getCurrentFenceTimeLocked() const {
+std::shared_ptr<FenceTime> BufferQueueLayer::getCurrentFenceTime() const {
     return mConsumer->getCurrentFenceTime();
 }
 
@@ -192,7 +192,6 @@
 
 std::optional<Region> BufferQueueLayer::latchSidebandStream(bool& recomputeVisibleRegions) {
     bool sidebandStreamChanged = true;
-    Mutex::Autolock lock(mStateMutex);
     if (mSidebandStreamChanged.compare_exchange_strong(sidebandStreamChanged, false)) {
         // mSidebandStreamChanged was changed to false
         // replicated in LayerBE until FE/BE is ready to be synchronized
@@ -201,15 +200,15 @@
             setTransactionFlags(eTransactionNeeded);
             mFlinger->setTransactionFlags(eTraversalNeeded);
         }
-
         recomputeVisibleRegions = true;
+
         const State& s(getDrawingState());
-        return getTransformLocked().transform(Region(Rect(s.active_legacy.w, s.active_legacy.h)));
+        return getTransform().transform(Region(Rect(s.active_legacy.w, s.active_legacy.h)));
     }
     return {};
 }
 
-bool BufferQueueLayer::hasFrameUpdateLocked() const {
+bool BufferQueueLayer::hasFrameUpdate() const {
     return mQueuedFrames > 0;
 }
 
@@ -229,18 +228,16 @@
     // buffer mode.
     bool queuedBuffer = false;
     const int32_t layerID = getSequence();
-    status_t updateResult;
-    LayerRejecter r(mState.drawing, getCurrentState(), recomputeVisibleRegions,
+    LayerRejecter r(mDrawingState, getCurrentState(), recomputeVisibleRegions,
                     getProducerStickyTransform() != 0, mName.string(), mOverrideScalingMode,
-                    getTransformToDisplayInverseLocked(), mFreezeGeometryUpdates);
+                    getTransformToDisplayInverse(), mFreezeGeometryUpdates);
 
     const nsecs_t expectedPresentTime = mFlinger->mUseScheduler
             ? mFlinger->mScheduler->mPrimaryDispSync->expectedPresentTime()
             : mFlinger->mPrimaryDispSync->expectedPresentTime();
-
-    updateResult = mConsumer->updateTexImage(&r, expectedPresentTime, &mAutoRefresh, &queuedBuffer,
-                                             mLastFrameNumberReceived, releaseFence);
-
+    status_t updateResult =
+            mConsumer->updateTexImage(&r, expectedPresentTime, &mAutoRefresh, &queuedBuffer,
+                                      mLastFrameNumberReceived, releaseFence);
     if (updateResult == BufferQueue::PRESENT_LATER) {
         // Producer doesn't want buffer to be displayed yet.  Signal a
         // layer update so we check again at the next opportunity.
diff --git a/services/surfaceflinger/BufferQueueLayer.h b/services/surfaceflinger/BufferQueueLayer.h
index f9da044..ae0b705 100644
--- a/services/surfaceflinger/BufferQueueLayer.h
+++ b/services/surfaceflinger/BufferQueueLayer.h
@@ -44,7 +44,7 @@
 
     std::vector<OccupancyTracker::Segment> getOccupancyHistory(bool forceFlush) override;
 
-    bool getTransformToDisplayInverseLocked() const override REQUIRES(mStateMutex);
+    bool getTransformToDisplayInverse() const override;
 
     // If a buffer was replaced this frame, release the former buffer
     void releasePendingBuffer(nsecs_t dequeueReadyTime) override;
@@ -64,12 +64,12 @@
 
 private:
     nsecs_t getDesiredPresentTime() override;
-    std::shared_ptr<FenceTime> getCurrentFenceTimeLocked() const override REQUIRES(mStateMutex);
+    std::shared_ptr<FenceTime> getCurrentFenceTime() const override;
 
     void getDrawingTransformMatrix(float *matrix) override;
-    uint32_t getDrawingTransform() const override REQUIRES(mStateMutex);
-    ui::Dataspace getDrawingDataSpace() const override REQUIRES(mStateMutex);
-    Rect getDrawingCrop() const override REQUIRES(mStateMutex);
+    uint32_t getDrawingTransform() const override;
+    ui::Dataspace getDrawingDataSpace() const override;
+    Rect getDrawingCrop() const override;
     uint32_t getDrawingScalingMode() const override;
     Region getDrawingSurfaceDamage() const override;
     const HdrMetadata& getDrawingHdrMetadata() const override;
@@ -81,18 +81,17 @@
     bool getAutoRefresh() const override;
     bool getSidebandStreamChanged() const override;
 
-    std::optional<Region> latchSidebandStream(bool& recomputeVisibleRegions) override
-            EXCLUDES(mStateMutex);
+    std::optional<Region> latchSidebandStream(bool& recomputeVisibleRegions) override;
 
-    bool hasFrameUpdateLocked() const override REQUIRES(mStateMutex);
+    bool hasFrameUpdate() const override;
 
     void setFilteringEnabled(bool enabled) override;
 
     status_t bindTextureImage() override;
     status_t updateTexImage(bool& recomputeVisibleRegions, nsecs_t latchTime,
-                            const sp<Fence>& releaseFence) override REQUIRES(mStateMutex);
+                            const sp<Fence>& releaseFence) override;
 
-    status_t updateActiveBuffer() override REQUIRES(mStateMutex);
+    status_t updateActiveBuffer() override;
     status_t updateFrameNumber(nsecs_t latchTime) override;
 
     void setHwcLayerBuffer(DisplayId displayId) override;
diff --git a/services/surfaceflinger/BufferStateLayer.cpp b/services/surfaceflinger/BufferStateLayer.cpp
index 077be86..e0d9d23 100644
--- a/services/surfaceflinger/BufferStateLayer.cpp
+++ b/services/surfaceflinger/BufferStateLayer.cpp
@@ -72,31 +72,30 @@
 }
 
 bool BufferStateLayer::willPresentCurrentTransaction() const {
-    Mutex::Autolock lock(mStateMutex);
     // Returns true if the most recent Transaction applied to CurrentState will be presented.
     return getSidebandStreamChanged() || getAutoRefresh() ||
-            (mState.current.modified && mState.current.buffer != nullptr);
+            (mCurrentState.modified && mCurrentState.buffer != nullptr);
 }
 
-bool BufferStateLayer::getTransformToDisplayInverseLocked() const {
-    return mState.current.transformToDisplayInverse;
+bool BufferStateLayer::getTransformToDisplayInverse() const {
+    return mCurrentState.transformToDisplayInverse;
 }
 
-void BufferStateLayer::pushPendingStateLocked() {
-    if (!mState.current.modified) {
+void BufferStateLayer::pushPendingState() {
+    if (!mCurrentState.modified) {
         return;
     }
-    mState.pending.push_back(mState.current);
-    ATRACE_INT(mTransactionName.string(), mState.pending.size());
+    mPendingStates.push_back(mCurrentState);
+    ATRACE_INT(mTransactionName.string(), mPendingStates.size());
 }
 
 bool BufferStateLayer::applyPendingStates(Layer::State* stateToCommit) {
-    const bool stateUpdateAvailable = !mState.pending.empty();
-    while (!mState.pending.empty()) {
+    const bool stateUpdateAvailable = !mPendingStates.empty();
+    while (!mPendingStates.empty()) {
         popPendingState(stateToCommit);
     }
-    mCurrentStateModified = stateUpdateAvailable && mState.current.modified;
-    mState.current.modified = false;
+    mCurrentStateModified = stateUpdateAvailable && mCurrentState.modified;
+    mCurrentState.modified = false;
     return stateUpdateAvailable;
 }
 
@@ -106,31 +105,28 @@
 }
 
 bool BufferStateLayer::setTransform(uint32_t transform) {
-    Mutex::Autolock lock(mStateMutex);
-    if (mState.current.transform == transform) return false;
-    mState.current.sequence++;
-    mState.current.transform = transform;
-    mState.current.modified = true;
+    if (mCurrentState.transform == transform) return false;
+    mCurrentState.sequence++;
+    mCurrentState.transform = transform;
+    mCurrentState.modified = true;
     setTransactionFlags(eTransactionNeeded);
     return true;
 }
 
 bool BufferStateLayer::setTransformToDisplayInverse(bool transformToDisplayInverse) {
-    Mutex::Autolock lock(mStateMutex);
-    if (mState.current.transformToDisplayInverse == transformToDisplayInverse) return false;
-    mState.current.sequence++;
-    mState.current.transformToDisplayInverse = transformToDisplayInverse;
-    mState.current.modified = true;
+    if (mCurrentState.transformToDisplayInverse == transformToDisplayInverse) return false;
+    mCurrentState.sequence++;
+    mCurrentState.transformToDisplayInverse = transformToDisplayInverse;
+    mCurrentState.modified = true;
     setTransactionFlags(eTransactionNeeded);
     return true;
 }
 
 bool BufferStateLayer::setCrop(const Rect& crop) {
-    Mutex::Autolock lock(mStateMutex);
-    if (mState.current.crop == crop) return false;
-    mState.current.sequence++;
-    mState.current.crop = crop;
-    mState.current.modified = true;
+    if (mCurrentState.crop == crop) return false;
+    mCurrentState.sequence++;
+    mCurrentState.crop = crop;
+    mCurrentState.modified = true;
     setTransactionFlags(eTransactionNeeded);
     return true;
 }
@@ -151,94 +147,86 @@
         h = frame.bottom;
     }
 
-    Mutex::Autolock lock(mStateMutex);
-    if (mState.current.active.transform.tx() == x && mState.current.active.transform.ty() == y &&
-        mState.current.active.w == w && mState.current.active.h == h) {
+    if (mCurrentState.active.transform.tx() == x && mCurrentState.active.transform.ty() == y &&
+        mCurrentState.active.w == w && mCurrentState.active.h == h) {
         return false;
     }
 
     if (!frame.isValid()) {
         x = y = w = h = 0;
     }
-    mState.current.active.transform.set(x, y);
-    mState.current.active.w = w;
-    mState.current.active.h = h;
+    mCurrentState.active.transform.set(x, y);
+    mCurrentState.active.w = w;
+    mCurrentState.active.h = h;
 
-    mState.current.sequence++;
-    mState.current.modified = true;
+    mCurrentState.sequence++;
+    mCurrentState.modified = true;
     setTransactionFlags(eTransactionNeeded);
     return true;
 }
 
 bool BufferStateLayer::setBuffer(const sp<GraphicBuffer>& buffer) {
-    Mutex::Autolock lock(mStateMutex);
-    if (mState.current.buffer) {
+    if (mCurrentState.buffer) {
         mReleasePreviousBuffer = true;
     }
 
-    mState.current.sequence++;
-    mState.current.buffer = buffer;
-    mState.current.modified = true;
+    mCurrentState.sequence++;
+    mCurrentState.buffer = buffer;
+    mCurrentState.modified = true;
     setTransactionFlags(eTransactionNeeded);
     return true;
 }
 
 bool BufferStateLayer::setAcquireFence(const sp<Fence>& fence) {
-    Mutex::Autolock lock(mStateMutex);
     // The acquire fences of BufferStateLayers have already signaled before they are set
     mCallbackHandleAcquireTime = fence->getSignalTime();
 
-    mState.current.acquireFence = fence;
-    mState.current.modified = true;
+    mCurrentState.acquireFence = fence;
+    mCurrentState.modified = true;
     setTransactionFlags(eTransactionNeeded);
     return true;
 }
 
 bool BufferStateLayer::setDataspace(ui::Dataspace dataspace) {
-    Mutex::Autolock lock(mStateMutex);
-    if (mState.current.dataspace == dataspace) return false;
-    mState.current.sequence++;
-    mState.current.dataspace = dataspace;
-    mState.current.modified = true;
+    if (mCurrentState.dataspace == dataspace) return false;
+    mCurrentState.sequence++;
+    mCurrentState.dataspace = dataspace;
+    mCurrentState.modified = true;
     setTransactionFlags(eTransactionNeeded);
     return true;
 }
 
 bool BufferStateLayer::setHdrMetadata(const HdrMetadata& hdrMetadata) {
-    Mutex::Autolock lock(mStateMutex);
-    if (mState.current.hdrMetadata == hdrMetadata) return false;
-    mState.current.sequence++;
-    mState.current.hdrMetadata = hdrMetadata;
-    mState.current.modified = true;
+    if (mCurrentState.hdrMetadata == hdrMetadata) return false;
+    mCurrentState.sequence++;
+    mCurrentState.hdrMetadata = hdrMetadata;
+    mCurrentState.modified = true;
     setTransactionFlags(eTransactionNeeded);
     return true;
 }
 
 bool BufferStateLayer::setSurfaceDamageRegion(const Region& surfaceDamage) {
-    Mutex::Autolock lock(mStateMutex);
-    mState.current.sequence++;
-    mState.current.surfaceDamageRegion = surfaceDamage;
-    mState.current.modified = true;
+    mCurrentState.sequence++;
+    mCurrentState.surfaceDamageRegion = surfaceDamage;
+    mCurrentState.modified = true;
     setTransactionFlags(eTransactionNeeded);
     return true;
 }
 
 bool BufferStateLayer::setApi(int32_t api) {
-    Mutex::Autolock lock(mStateMutex);
-    if (mState.current.api == api) return false;
-    mState.current.sequence++;
-    mState.current.api = api;
-    mState.current.modified = true;
+    if (mCurrentState.api == api) return false;
+    mCurrentState.sequence++;
+    mCurrentState.api = api;
+    mCurrentState.modified = true;
     setTransactionFlags(eTransactionNeeded);
     return true;
 }
 
 bool BufferStateLayer::setSidebandStream(const sp<NativeHandle>& sidebandStream) {
-    Mutex::Autolock lock(mStateMutex);
-    if (mState.current.sidebandStream == sidebandStream) return false;
-    mState.current.sequence++;
-    mState.current.sidebandStream = sidebandStream;
-    mState.current.modified = true;
+    if (mCurrentState.sidebandStream == sidebandStream) return false;
+    mCurrentState.sequence++;
+    mCurrentState.sidebandStream = sidebandStream;
+    mCurrentState.modified = true;
     setTransactionFlags(eTransactionNeeded);
 
     if (!mSidebandStreamChanged.exchange(true)) {
@@ -272,10 +260,7 @@
             mFlinger->getTransactionCompletedThread().registerPendingLatchedCallbackHandle(handle);
 
             // Store so latched time and release fence can be set
-            {
-                Mutex::Autolock lock(mStateMutex);
-                mState.current.callbackHandles.push_back(handle);
-            }
+            mCurrentState.callbackHandles.push_back(handle);
 
         } else { // If this layer will NOT need to be relatched and presented this frame
             // Notify the transaction completed thread this handle is done
@@ -290,9 +275,8 @@
 }
 
 bool BufferStateLayer::setTransparentRegionHint(const Region& transparent) {
-    Mutex::Autolock lock(mStateMutex);
-    mState.current.transparentRegionHint = transparent;
-    mState.current.modified = true;
+    mCurrentState.transparentRegionHint = transparent;
+    mCurrentState.modified = true;
     setTransactionFlags(eTransactionNeeded);
     return true;
 }
@@ -328,7 +312,6 @@
         return true;
     }
 
-    Mutex::Autolock lock(mStateMutex);
     return getDrawingState().acquireFence->getStatus() == Fence::Status::Signaled;
 }
 
@@ -337,7 +320,7 @@
     return 0;
 }
 
-std::shared_ptr<FenceTime> BufferStateLayer::getCurrentFenceTimeLocked() const {
+std::shared_ptr<FenceTime> BufferStateLayer::getCurrentFenceTime() const {
     return std::make_shared<FenceTime>(getDrawingState().acquireFence);
 }
 
@@ -384,17 +367,14 @@
 }
 
 Region BufferStateLayer::getDrawingSurfaceDamage() const {
-    Mutex::Autolock lock(mStateMutex);
     return getDrawingState().surfaceDamageRegion;
 }
 
 const HdrMetadata& BufferStateLayer::getDrawingHdrMetadata() const {
-    Mutex::Autolock lock(mStateMutex);
     return getDrawingState().hdrMetadata;
 }
 
 int BufferStateLayer::getDrawingApi() const {
-    Mutex::Autolock lock(mStateMutex);
     return getDrawingState().api;
 }
 
@@ -419,7 +399,6 @@
 }
 
 std::optional<Region> BufferStateLayer::latchSidebandStream(bool& recomputeVisibleRegions) {
-    Mutex::Autolock lock(mStateMutex);
     if (mSidebandStreamChanged.exchange(false)) {
         const State& s(getDrawingState());
         // mSidebandStreamChanged was true
@@ -431,12 +410,12 @@
         }
         recomputeVisibleRegions = true;
 
-        return getTransformLocked().transform(Region(Rect(s.active.w, s.active.h)));
+        return getTransform().transform(Region(Rect(s.active.w, s.active.h)));
     }
     return {};
 }
 
-bool BufferStateLayer::hasFrameUpdateLocked() const {
+bool BufferStateLayer::hasFrameUpdate() const {
     return mCurrentStateModified && getCurrentState().buffer != nullptr;
 }
 
@@ -446,10 +425,6 @@
 }
 
 status_t BufferStateLayer::bindTextureImage() {
-    Mutex::Autolock lock(mStateMutex);
-    return bindTextureImageLocked();
-}
-status_t BufferStateLayer::bindTextureImageLocked() {
     const State& s(getDrawingState());
     auto& engine(mFlinger->getRenderEngine());
 
@@ -554,7 +529,7 @@
         auto incomingStatus = releaseFence->getStatus();
         if (incomingStatus == Fence::Status::Invalid) {
             ALOGE("New fence has invalid state");
-            mState.drawing.acquireFence = releaseFence;
+            mDrawingState.acquireFence = releaseFence;
             mFlinger->mTimeStats->onDestroy(layerID);
             return BAD_VALUE;
         }
@@ -565,16 +540,16 @@
             char fenceName[32] = {};
             snprintf(fenceName, 32, "%.28s:%d", mName.string(), mFrameNumber);
             sp<Fence> mergedFence =
-                    Fence::merge(fenceName, mState.drawing.acquireFence, releaseFence);
+                    Fence::merge(fenceName, mDrawingState.acquireFence, releaseFence);
             if (!mergedFence.get()) {
                 ALOGE("failed to merge release fences");
                 // synchronization is broken, the best we can do is hope fences
                 // signal in order so the new fence will act like a union
-                mState.drawing.acquireFence = releaseFence;
+                mDrawingState.acquireFence = releaseFence;
                 mFlinger->mTimeStats->onDestroy(layerID);
                 return BAD_VALUE;
             }
-            mState.drawing.acquireFence = mergedFence;
+            mDrawingState.acquireFence = mergedFence;
         } else if (incomingStatus == Fence::Status::Unsignaled) {
             // If one fence has signaled and the other hasn't, the unsignaled
             // fence will approximately correspond with the correct timestamp.
@@ -583,7 +558,7 @@
             // by this point, they will have both signaled and only the timestamp
             // will be slightly off; any dependencies after this point will
             // already have been met.
-            mState.drawing.acquireFence = releaseFence;
+            mDrawingState.acquireFence = releaseFence;
         }
     } else {
         // Bind the new buffer to the GL texture.
@@ -592,7 +567,7 @@
         // by glEGLImageTargetTexture2DOES, which this method calls.  Newer
         // devices will either call this in Layer::onDraw, or (if it's not
         // a GL-composited layer) not at all.
-        status_t err = bindTextureImageLocked();
+        status_t err = bindTextureImage();
         if (err != NO_ERROR) {
             mFlinger->mTimeStats->onDestroy(layerID);
             return BAD_VALUE;
@@ -601,7 +576,7 @@
 
     // TODO(marissaw): properly support mTimeStats
     mFlinger->mTimeStats->setPostTime(layerID, getFrameNumber(), getName().c_str(), latchTime);
-    mFlinger->mTimeStats->setAcquireFence(layerID, getFrameNumber(), getCurrentFenceTimeLocked());
+    mFlinger->mTimeStats->setAcquireFence(layerID, getFrameNumber(), getCurrentFenceTime());
     mFlinger->mTimeStats->setLatchTime(layerID, getFrameNumber(), latchTime);
 
     return NO_ERROR;
@@ -628,7 +603,6 @@
 }
 
 void BufferStateLayer::setHwcLayerBuffer(DisplayId displayId) {
-    Mutex::Autolock lock(mStateMutex);
     auto& hwcInfo = getBE().mHwcLayers[displayId];
     auto& hwcLayer = hwcInfo.layer;
 
diff --git a/services/surfaceflinger/BufferStateLayer.h b/services/surfaceflinger/BufferStateLayer.h
index 655353c..3f891d3 100644
--- a/services/surfaceflinger/BufferStateLayer.h
+++ b/services/surfaceflinger/BufferStateLayer.h
@@ -41,14 +41,13 @@
 
     bool shouldPresentNow(nsecs_t expectedPresentTime) const override;
 
-    bool getTransformToDisplayInverseLocked() const override REQUIRES(mStateMutex);
+    bool getTransformToDisplayInverse() const override;
 
     uint32_t doTransactionResize(uint32_t flags, Layer::State* /*stateToCommit*/) override {
         return flags;
     }
-
-    void pushPendingStateLocked() override REQUIRES(mStateMutex);
-    bool applyPendingStates(Layer::State* stateToCommit) override REQUIRES(mStateMutex);
+    void pushPendingState() override;
+    bool applyPendingStates(Layer::State* stateToCommit) override;
 
     uint32_t getActiveWidth(const Layer::State& s) const override { return s.active.w; }
     uint32_t getActiveHeight(const Layer::State& s) const override { return s.active.h; }
@@ -60,20 +59,18 @@
     }
     Rect getCrop(const Layer::State& s) const;
 
-    bool setTransform(uint32_t transform) override EXCLUDES(mStateMutex);
-    bool setTransformToDisplayInverse(bool transformToDisplayInverse) override
-            EXCLUDES(mStateMutex);
-    bool setCrop(const Rect& crop) override EXCLUDES(mStateMutex);
-    bool setFrame(const Rect& frame) override EXCLUDES(mStateMutex);
-    bool setBuffer(const sp<GraphicBuffer>& buffer) override EXCLUDES(mStateMutex);
-    bool setAcquireFence(const sp<Fence>& fence) override EXCLUDES(mStateMutex);
-    bool setDataspace(ui::Dataspace dataspace) override EXCLUDES(mStateMutex);
-    bool setHdrMetadata(const HdrMetadata& hdrMetadata) override EXCLUDES(mStateMutex);
-    bool setSurfaceDamageRegion(const Region& surfaceDamage) override EXCLUDES(mStateMutex);
-    bool setApi(int32_t api) override EXCLUDES(mStateMutex);
-    bool setSidebandStream(const sp<NativeHandle>& sidebandStream) override EXCLUDES(mStateMutex);
-    bool setTransactionCompletedListeners(const std::vector<sp<CallbackHandle>>& handles) override
-            EXCLUDES(mStateMutex);
+    bool setTransform(uint32_t transform) override;
+    bool setTransformToDisplayInverse(bool transformToDisplayInverse) override;
+    bool setCrop(const Rect& crop) override;
+    bool setFrame(const Rect& frame) override;
+    bool setBuffer(const sp<GraphicBuffer>& buffer) override;
+    bool setAcquireFence(const sp<Fence>& fence) override;
+    bool setDataspace(ui::Dataspace dataspace) override;
+    bool setHdrMetadata(const HdrMetadata& hdrMetadata) override;
+    bool setSurfaceDamageRegion(const Region& surfaceDamage) override;
+    bool setApi(int32_t api) override;
+    bool setSidebandStream(const sp<NativeHandle>& sidebandStream) override;
+    bool setTransactionCompletedListeners(const std::vector<sp<CallbackHandle>>& handles) override;
 
     // Override to ignore legacy layer state properties that are not used by BufferStateLayer
     bool setSize(uint32_t /*w*/, uint32_t /*h*/) override { return false; }
@@ -90,26 +87,26 @@
     void deferTransactionUntil_legacy(const sp<Layer>& /*barrierLayer*/,
                                       uint64_t /*frameNumber*/) override {}
 
-    Rect getBufferSize(const State& s) const override REQUIRES(mStateMutex);
+    Rect getBufferSize(const State& s) const override;
     // -----------------------------------------------------------------------
 
     // -----------------------------------------------------------------------
     // Interface implementation for BufferLayer
     // -----------------------------------------------------------------------
-    bool fenceHasSignaled() const override EXCLUDES(mStateMutex);
+    bool fenceHasSignaled() const override;
 
 private:
     nsecs_t getDesiredPresentTime() override;
-    std::shared_ptr<FenceTime> getCurrentFenceTimeLocked() const override REQUIRES(mStateMutex);
+    std::shared_ptr<FenceTime> getCurrentFenceTime() const override;
 
     void getDrawingTransformMatrix(float *matrix) override;
-    uint32_t getDrawingTransform() const override REQUIRES(mStateMutex);
-    ui::Dataspace getDrawingDataSpace() const override REQUIRES(mStateMutex);
-    Rect getDrawingCrop() const override REQUIRES(mStateMutex);
+    uint32_t getDrawingTransform() const override;
+    ui::Dataspace getDrawingDataSpace() const override;
+    Rect getDrawingCrop() const override;
     uint32_t getDrawingScalingMode() const override;
-    Region getDrawingSurfaceDamage() const override EXCLUDES(mStateMutex);
-    const HdrMetadata& getDrawingHdrMetadata() const override EXCLUDES(mStateMutex);
-    int getDrawingApi() const override EXCLUDES(mStateMutex);
+    Region getDrawingSurfaceDamage() const override;
+    const HdrMetadata& getDrawingHdrMetadata() const override;
+    int getDrawingApi() const override;
     PixelFormat getPixelFormat() const override;
 
     uint64_t getFrameNumber() const override;
@@ -117,26 +114,24 @@
     bool getAutoRefresh() const override;
     bool getSidebandStreamChanged() const override;
 
-    std::optional<Region> latchSidebandStream(bool& recomputeVisibleRegions) override
-            EXCLUDES(mStateMutex);
+    std::optional<Region> latchSidebandStream(bool& recomputeVisibleRegions) override;
 
-    bool hasFrameUpdateLocked() const override REQUIRES(mStateMutex);
+    bool hasFrameUpdate() const override;
 
     void setFilteringEnabled(bool enabled) override;
 
-    status_t bindTextureImage() override EXCLUDES(mStateMutex);
+    status_t bindTextureImage() override;
     status_t updateTexImage(bool& recomputeVisibleRegions, nsecs_t latchTime,
-                            const sp<Fence>& releaseFence) override REQUIRES(mStateMutex);
+                            const sp<Fence>& releaseFence) override;
 
-    status_t updateActiveBuffer() override REQUIRES(mStateMutex);
+    status_t updateActiveBuffer() override;
     status_t updateFrameNumber(nsecs_t latchTime) override;
 
-    void setHwcLayerBuffer(DisplayId displayId) override EXCLUDES(mStateMutex);
+    void setHwcLayerBuffer(DisplayId displayId) override;
 
 private:
     void onFirstRef() override;
     bool willPresentCurrentTransaction() const;
-    status_t bindTextureImageLocked() REQUIRES(mStateMutex);
 
     static const std::array<float, 16> IDENTITY_MATRIX;
 
diff --git a/services/surfaceflinger/ColorLayer.cpp b/services/surfaceflinger/ColorLayer.cpp
index cb7642e..f27f6aa 100644
--- a/services/surfaceflinger/ColorLayer.cpp
+++ b/services/surfaceflinger/ColorLayer.cpp
@@ -40,16 +40,15 @@
 
 void ColorLayer::onDraw(const RenderArea& renderArea, const Region& /* clip */,
                         bool useIdentityTransform) {
-    Mutex::Autolock lock(mStateMutex);
     half4 color = getColor();
     if (color.a > 0) {
         renderengine::Mesh mesh(renderengine::Mesh::TRIANGLE_FAN, 4, 2);
         computeGeometry(renderArea, mesh, useIdentityTransform);
         auto& engine(mFlinger->getRenderEngine());
 
-        Rect win{computeBoundsLocked()};
+        Rect win{computeBounds()};
 
-        const auto roundedCornerState = getRoundedCornerStateLocked();
+        const auto roundedCornerState = getRoundedCornerState();
         const auto cropRect = roundedCornerState.cropRect;
         setupRoundedCornersCropCoordinates(win, cropRect);
 
@@ -92,7 +91,6 @@
     }
     getBE().compositionInfo.hwc.dataspace = mCurrentDataSpace;
 
-    Mutex::Autolock lock(mStateMutex);
     half4 color = getColor();
     error = hwcLayer->setColor({static_cast<uint8_t>(std::round(255.0f * color.r)),
                                 static_cast<uint8_t>(std::round(255.0f * color.g)),
@@ -113,12 +111,12 @@
     }
     getBE().compositionInfo.hwc.transform = HWC2::Transform::None;
 
-    error = hwcLayer->setColorTransform(getColorTransformLocked());
+    error = hwcLayer->setColorTransform(getColorTransform());
     if (error != HWC2::Error::None) {
         ALOGE("[%s] Failed to setColorTransform: %s (%d)", mName.string(),
                 to_string(error).c_str(), static_cast<int32_t>(error));
     }
-    getBE().compositionInfo.hwc.colorTransform = getColorTransformLocked();
+    getBE().compositionInfo.hwc.colorTransform = getColorTransform();
 
     error = hwcLayer->setSurfaceDamage(surfaceDamageRegion);
     if (error != HWC2::Error::None) {
diff --git a/services/surfaceflinger/ColorLayer.h b/services/surfaceflinger/ColorLayer.h
index 5850a2e..d1b1697 100644
--- a/services/surfaceflinger/ColorLayer.h
+++ b/services/surfaceflinger/ColorLayer.h
@@ -29,12 +29,12 @@
     ~ColorLayer() override;
 
     virtual const char* getTypeId() const { return "ColorLayer"; }
-    virtual void onDraw(const RenderArea& renderArea, const Region& clip, bool useIdentityTransform)
-            EXCLUDES(mStateMutex);
-    bool isVisible() const override EXCLUDES(mStateMutex);
+    virtual void onDraw(const RenderArea& renderArea, const Region& clip,
+                        bool useIdentityTransform);
+    bool isVisible() const override;
 
     void setPerFrameData(DisplayId displayId, const ui::Transform& transform, const Rect& viewport,
-                         int32_t supportedPerFrameMetadata) override EXCLUDES(mStateMutex);
+                         int32_t supportedPerFrameMetadata) override;
 
     bool onPreComposition(nsecs_t /*refreshStartTime*/) override { return false; }
 
diff --git a/services/surfaceflinger/CompositionEngine/Android.bp b/services/surfaceflinger/CompositionEngine/Android.bp
new file mode 100644
index 0000000..ec5e131
--- /dev/null
+++ b/services/surfaceflinger/CompositionEngine/Android.bp
@@ -0,0 +1,88 @@
+cc_defaults {
+    name: "libcompositionengine_defaults",
+    defaults: ["surfaceflinger_defaults"],
+    cflags: [
+        "-DLOG_TAG=\"CompositionEngine\"",
+    ],
+    shared_libs: [
+        "android.hardware.graphics.allocator@2.0",
+        "android.hardware.graphics.composer@2.1",
+        "android.hardware.graphics.composer@2.2",
+        "android.hardware.graphics.composer@2.3",
+        "android.hardware.power@1.0",
+        "android.hardware.power@1.3",
+        "libbase",
+        "libcutils",
+        "libgui",
+        "liblayers_proto",
+        "liblog",
+        "libtimestats_proto",
+        "libui",
+        "libutils",
+    ],
+    static_libs: [
+        "libmath",
+        "librenderengine",
+        "libtrace_proto",
+    ],
+    header_libs: [
+        "libsurfaceflinger_headers",
+    ],
+}
+
+cc_library {
+    name: "libcompositionengine",
+    defaults: ["libcompositionengine_defaults"],
+    srcs: [
+        "src/CompositionEngine.cpp",
+    ],
+    local_include_dirs: ["include"],
+    export_include_dirs: ["include"],
+}
+
+cc_library {
+    name: "libcompositionengine_mocks",
+    defaults: ["libcompositionengine_defaults"],
+    srcs: [
+        "mock/CompositionEngine.cpp",
+    ],
+    static_libs: [
+        "libgtest",
+        "libgmock",
+        "libcompositionengine",
+    ],
+    local_include_dirs: ["include"],
+    export_include_dirs: ["include"],
+}
+
+cc_test {
+    name: "libcompositionengine_test",
+    test_suites: ["device-tests"],
+    defaults: ["libcompositionengine_defaults"],
+    srcs: [
+        "tests/CompositionEngineTest.cpp",
+        "tests/MockHWComposer.cpp",
+    ],
+    static_libs: [
+        "libcompositionengine",
+        "libcompositionengine_mocks",
+        "librenderengine_mocks",
+        "libgmock",
+        "libgtest",
+    ],
+    sanitize: {
+        // By using the address sanitizer, we not only uncover any issues
+        // with the test, but also any issues with the code under test.
+        //
+        // Note: If you get an runtime link error like:
+        //
+        //   CANNOT LINK EXECUTABLE "/data/local/tmp/libcompositionengine_test": library "libclang_rt.asan-aarch64-android.so" not found
+        //
+        // it is because the address sanitizer shared objects are not installed
+        // by default in the system image.
+        //
+        // You can either "make dist tests" before flashing, or set this
+        // option to false temporarily.
+        address: true,
+    },
+}
diff --git a/services/surfaceflinger/CompositionEngine/include/compositionengine/CompositionEngine.h b/services/surfaceflinger/CompositionEngine/include/compositionengine/CompositionEngine.h
new file mode 100644
index 0000000..af8515f
--- /dev/null
+++ b/services/surfaceflinger/CompositionEngine/include/compositionengine/CompositionEngine.h
@@ -0,0 +1,47 @@
+/*
+ * 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 <memory>
+
+namespace android {
+
+class HWComposer;
+
+namespace renderengine {
+class RenderEngine;
+} // namespace renderengine
+
+namespace compositionengine {
+
+/**
+ * Encapsulates all the interfaces and implementation details for performing
+ * display output composition.
+ */
+class CompositionEngine {
+public:
+    virtual ~CompositionEngine();
+
+    virtual HWComposer& getHwComposer() const = 0;
+    virtual void setHwComposer(std::unique_ptr<HWComposer>) = 0;
+
+    virtual renderengine::RenderEngine& getRenderEngine() const = 0;
+    virtual void setRenderEngine(std::unique_ptr<renderengine::RenderEngine>) = 0;
+};
+
+} // namespace compositionengine
+} // namespace android
diff --git a/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/CompositionEngine.h b/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/CompositionEngine.h
new file mode 100644
index 0000000..86d1774
--- /dev/null
+++ b/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/CompositionEngine.h
@@ -0,0 +1,41 @@
+/*
+ * 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 <compositionengine/CompositionEngine.h>
+
+namespace android::compositionengine::impl {
+
+class CompositionEngine : public compositionengine::CompositionEngine {
+public:
+    CompositionEngine();
+    ~CompositionEngine() override;
+
+    HWComposer& getHwComposer() const override;
+    void setHwComposer(std::unique_ptr<HWComposer>) override;
+
+    renderengine::RenderEngine& getRenderEngine() const override;
+    void setRenderEngine(std::unique_ptr<renderengine::RenderEngine>) override;
+
+private:
+    std::unique_ptr<HWComposer> mHwComposer;
+    std::unique_ptr<renderengine::RenderEngine> mRenderEngine;
+};
+
+std::unique_ptr<compositionengine::CompositionEngine> createCompositionEngine();
+
+} // namespace android::compositionengine::impl
diff --git a/services/surfaceflinger/CompositionEngine/include/compositionengine/mock/CompositionEngine.h b/services/surfaceflinger/CompositionEngine/include/compositionengine/mock/CompositionEngine.h
new file mode 100644
index 0000000..9ba213e
--- /dev/null
+++ b/services/surfaceflinger/CompositionEngine/include/compositionengine/mock/CompositionEngine.h
@@ -0,0 +1,39 @@
+/*
+ * 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 <compositionengine/CompositionEngine.h>
+#include <gmock/gmock.h>
+#include <renderengine/RenderEngine.h>
+
+#include "DisplayHardware/HWComposer.h"
+
+namespace android::compositionengine::mock {
+
+class CompositionEngine : public compositionengine::CompositionEngine {
+public:
+    CompositionEngine();
+    ~CompositionEngine() override;
+
+    MOCK_CONST_METHOD0(getHwComposer, HWComposer&());
+    MOCK_METHOD1(setHwComposer, void(std::unique_ptr<HWComposer>));
+
+    MOCK_CONST_METHOD0(getRenderEngine, renderengine::RenderEngine&());
+    MOCK_METHOD1(setRenderEngine, void(std::unique_ptr<renderengine::RenderEngine>));
+};
+
+} // namespace android::compositionengine::mock
diff --git a/services/surfaceflinger/CompositionEngine/mock/CompositionEngine.cpp b/services/surfaceflinger/CompositionEngine/mock/CompositionEngine.cpp
new file mode 100644
index 0000000..778a09e
--- /dev/null
+++ b/services/surfaceflinger/CompositionEngine/mock/CompositionEngine.cpp
@@ -0,0 +1,26 @@
+/*
+ * 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 <compositionengine/mock/CompositionEngine.h>
+
+namespace android::compositionengine::mock {
+
+// The Google Mock documentation recommends explicit non-header instantiations
+// for better compile time performance.
+CompositionEngine::CompositionEngine() = default;
+CompositionEngine::~CompositionEngine() = default;
+
+} // namespace android::compositionengine::mock
diff --git a/services/surfaceflinger/CompositionEngine/src/CompositionEngine.cpp b/services/surfaceflinger/CompositionEngine/src/CompositionEngine.cpp
new file mode 100644
index 0000000..fbf71b5
--- /dev/null
+++ b/services/surfaceflinger/CompositionEngine/src/CompositionEngine.cpp
@@ -0,0 +1,52 @@
+/*
+ * 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 <compositionengine/impl/CompositionEngine.h>
+#include <renderengine/RenderEngine.h>
+
+#include "DisplayHardware/HWComposer.h"
+
+namespace android::compositionengine {
+
+CompositionEngine::~CompositionEngine() = default;
+
+namespace impl {
+
+std::unique_ptr<compositionengine::CompositionEngine> createCompositionEngine() {
+    return std::make_unique<CompositionEngine>();
+}
+
+CompositionEngine::CompositionEngine() = default;
+CompositionEngine::~CompositionEngine() = default;
+
+HWComposer& CompositionEngine::getHwComposer() const {
+    return *mHwComposer.get();
+}
+
+void CompositionEngine::setHwComposer(std::unique_ptr<HWComposer> hwComposer) {
+    mHwComposer = std::move(hwComposer);
+}
+
+renderengine::RenderEngine& CompositionEngine::getRenderEngine() const {
+    return *mRenderEngine.get();
+}
+
+void CompositionEngine::setRenderEngine(std::unique_ptr<renderengine::RenderEngine> renderEngine) {
+    mRenderEngine = std::move(renderEngine);
+}
+
+} // namespace impl
+} // namespace android::compositionengine
diff --git a/services/surfaceflinger/CompositionEngine/tests/CompositionEngineTest.cpp b/services/surfaceflinger/CompositionEngine/tests/CompositionEngineTest.cpp
new file mode 100644
index 0000000..3766f27
--- /dev/null
+++ b/services/surfaceflinger/CompositionEngine/tests/CompositionEngineTest.cpp
@@ -0,0 +1,57 @@
+/*
+ * 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 <compositionengine/impl/CompositionEngine.h>
+#include <gtest/gtest.h>
+#include <renderengine/mock/RenderEngine.h>
+
+#include "MockHWComposer.h"
+
+namespace android::compositionengine {
+namespace {
+
+using ::testing::StrictMock;
+
+class CompositionEngineTest : public testing::Test {
+public:
+    ~CompositionEngineTest() override;
+    mock::HWComposer* mHwc = new StrictMock<mock::HWComposer>();
+    renderengine::mock::RenderEngine* mRenderEngine =
+            new StrictMock<renderengine::mock::RenderEngine>();
+    impl::CompositionEngine mEngine;
+};
+
+CompositionEngineTest::~CompositionEngineTest() = default;
+
+TEST_F(CompositionEngineTest, canInstantiateCompositionEngine) {
+    auto engine = impl::createCompositionEngine();
+    EXPECT_TRUE(engine.get() != nullptr);
+}
+
+TEST_F(CompositionEngineTest, canSetHWComposer) {
+    mEngine.setHwComposer(std::unique_ptr<android::HWComposer>(mHwc));
+
+    EXPECT_EQ(mHwc, &mEngine.getHwComposer());
+}
+
+TEST_F(CompositionEngineTest, canSetRenderEngine) {
+    mEngine.setRenderEngine(std::unique_ptr<renderengine::RenderEngine>(mRenderEngine));
+
+    EXPECT_EQ(mRenderEngine, &mEngine.getRenderEngine());
+}
+
+} // namespace
+} // namespace android::compositionengine
diff --git a/services/surfaceflinger/CompositionEngine/tests/MockHWComposer.cpp b/services/surfaceflinger/CompositionEngine/tests/MockHWComposer.cpp
new file mode 100644
index 0000000..ae52670
--- /dev/null
+++ b/services/surfaceflinger/CompositionEngine/tests/MockHWComposer.cpp
@@ -0,0 +1,32 @@
+/*
+ * 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 "MockHWComposer.h"
+
+namespace android {
+
+// This will go away once HWComposer is moved into the "backend" library
+HWComposer::~HWComposer() = default;
+
+namespace mock {
+
+// The Google Mock documentation recommends explicit non-header instantiations
+// for better compile time performance.
+HWComposer::HWComposer() = default;
+HWComposer::~HWComposer() = default;
+
+} // namespace mock
+} // namespace android
diff --git a/services/surfaceflinger/CompositionEngine/tests/MockHWComposer.h b/services/surfaceflinger/CompositionEngine/tests/MockHWComposer.h
new file mode 100644
index 0000000..ece412f
--- /dev/null
+++ b/services/surfaceflinger/CompositionEngine/tests/MockHWComposer.h
@@ -0,0 +1,94 @@
+/*
+ * 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 <gmock/gmock.h>
+
+#include "LayerBE.h"
+
+#include "DisplayHardware/HWComposer.h"
+
+namespace android {
+namespace mock {
+
+class HWComposer : public android::HWComposer {
+public:
+    HWComposer();
+    ~HWComposer() override;
+
+    MOCK_METHOD2(registerCallback, void(HWC2::ComposerCallback*, int32_t));
+    MOCK_CONST_METHOD3(getDisplayIdentificationData,
+                       bool(hwc2_display_t, uint8_t*, DisplayIdentificationData*));
+    MOCK_CONST_METHOD1(hasCapability, bool(HWC2::Capability));
+    MOCK_CONST_METHOD2(hasDisplayCapability,
+                       bool(const std::optional<DisplayId>&, HWC2::DisplayCapability));
+
+    MOCK_METHOD3(allocateVirtualDisplay,
+                 std::optional<DisplayId>(uint32_t, uint32_t, ui::PixelFormat*));
+    MOCK_METHOD1(createLayer, HWC2::Layer*(DisplayId));
+    MOCK_METHOD2(destroyLayer, void(DisplayId, HWC2::Layer*));
+    MOCK_METHOD2(prepare, status_t(DisplayId, std::vector<CompositionInfo>&));
+    MOCK_METHOD5(setClientTarget,
+                 status_t(DisplayId, uint32_t, const sp<Fence>&, const sp<GraphicBuffer>&,
+                          ui::Dataspace));
+    MOCK_METHOD1(presentAndGetReleaseFences, status_t(DisplayId));
+    MOCK_METHOD2(setPowerMode, status_t(DisplayId, int));
+    MOCK_METHOD2(setActiveConfig, status_t(DisplayId, size_t));
+    MOCK_METHOD2(setColorTransform, status_t(DisplayId, const mat4&));
+    MOCK_METHOD1(disconnectDisplay, void(DisplayId));
+    MOCK_CONST_METHOD1(hasDeviceComposition, bool(const std::optional<DisplayId>&));
+    MOCK_CONST_METHOD1(hasFlipClientTargetRequest, bool(const std::optional<DisplayId>&));
+    MOCK_CONST_METHOD1(hasClientComposition, bool(const std::optional<DisplayId>&));
+    MOCK_CONST_METHOD1(getPresentFence, sp<Fence>(DisplayId));
+    MOCK_CONST_METHOD2(getLayerReleaseFence, sp<Fence>(DisplayId, HWC2::Layer*));
+    MOCK_METHOD3(setOutputBuffer, status_t(DisplayId, const sp<Fence>&, const sp<GraphicBuffer>&));
+    MOCK_METHOD1(clearReleaseFences, void(DisplayId));
+    MOCK_METHOD2(getHdrCapabilities, status_t(DisplayId, HdrCapabilities*));
+    MOCK_CONST_METHOD1(getSupportedPerFrameMetadata, int32_t(DisplayId));
+    MOCK_CONST_METHOD2(getRenderIntents, std::vector<ui::RenderIntent>(DisplayId, ui::ColorMode));
+    MOCK_METHOD2(getDataspaceSaturationMatrix, mat4(DisplayId, ui::Dataspace));
+    MOCK_METHOD4(getDisplayedContentSamplingAttributes,
+                 status_t(DisplayId, ui::PixelFormat*, ui::Dataspace*, uint8_t*));
+    MOCK_METHOD4(setDisplayContentSamplingEnabled, status_t(DisplayId, bool, uint8_t, uint64_t));
+    MOCK_METHOD4(getDisplayedContentSample,
+                 status_t(DisplayId, uint64_t, uint64_t, DisplayedFrameStats*));
+
+    MOCK_METHOD2(onHotplug,
+                 std::optional<DisplayIdentificationInfo>(hwc2_display_t, HWC2::Connection));
+    MOCK_METHOD2(onVsync, bool(hwc2_display_t, int64_t));
+    MOCK_METHOD2(setVsyncEnabled, void(DisplayId, HWC2::Vsync));
+    MOCK_CONST_METHOD1(getRefreshTimestamp, nsecs_t(DisplayId));
+    MOCK_CONST_METHOD1(isConnected, bool(DisplayId));
+    MOCK_CONST_METHOD1(getConfigs,
+                       std::vector<std::shared_ptr<const HWC2::Display::Config>>(DisplayId));
+    MOCK_CONST_METHOD1(getActiveConfig, std::shared_ptr<const HWC2::Display::Config>(DisplayId));
+    MOCK_CONST_METHOD1(getActiveConfigIndex, int(DisplayId));
+    MOCK_CONST_METHOD1(getColorModes, std::vector<ui::ColorMode>(DisplayId));
+    MOCK_METHOD3(setActiveColorMode, status_t(DisplayId, ui::ColorMode, ui::RenderIntent));
+    MOCK_CONST_METHOD0(isUsingVrComposer, bool());
+
+    MOCK_CONST_METHOD1(dump, void(std::string&));
+    MOCK_CONST_METHOD0(getComposer, android::Hwc2::Composer*());
+    MOCK_CONST_METHOD1(getHwcDisplayId, std::optional<hwc2_display_t>(int32_t));
+    MOCK_CONST_METHOD0(getInternalHwcDisplayId, std::optional<hwc2_display_t>());
+    MOCK_CONST_METHOD0(getExternalHwcDisplayId, std::optional<hwc2_display_t>());
+    MOCK_CONST_METHOD1(toPhysicalDisplayId, std::optional<DisplayId>(hwc2_display_t));
+    MOCK_CONST_METHOD1(fromPhysicalDisplayId, std::optional<hwc2_display_t>(DisplayId));
+};
+
+} // namespace mock
+} // namespace android
diff --git a/services/surfaceflinger/ContainerLayer.h b/services/surfaceflinger/ContainerLayer.h
index 6c4f7c8..413844b 100644
--- a/services/surfaceflinger/ContainerLayer.h
+++ b/services/surfaceflinger/ContainerLayer.h
@@ -31,7 +31,7 @@
     const char* getTypeId() const override { return "ContainerLayer"; }
     void onDraw(const RenderArea& renderArea, const Region& clip,
                 bool useIdentityTransform) override;
-    bool isVisible() const override EXCLUDES(mStateMutex);
+    bool isVisible() const override;
 
     void setPerFrameData(DisplayId displayId, const ui::Transform& transform, const Rect& viewport,
                          int32_t supportedPerFrameMetadata) override;
diff --git a/services/surfaceflinger/DisplayHardware/HWComposer.cpp b/services/surfaceflinger/DisplayHardware/HWComposer.cpp
index 168b27c..5b4d347 100644
--- a/services/surfaceflinger/DisplayHardware/HWComposer.cpp
+++ b/services/surfaceflinger/DisplayHardware/HWComposer.cpp
@@ -66,6 +66,10 @@
 
 namespace android {
 
+HWComposer::~HWComposer() = default;
+
+namespace impl {
+
 HWComposer::HWComposer(std::unique_ptr<Hwc2::Composer> composer)
       : mHwcDevice(std::make_unique<HWC2::Device>(std::move(composer))) {}
 
@@ -858,4 +862,5 @@
                                                                            : "External display"};
 }
 
+} // namespace impl
 } // namespace android
diff --git a/services/surfaceflinger/DisplayHardware/HWComposer.h b/services/surfaceflinger/DisplayHardware/HWComposer.h
index d9a0916..f42f860 100644
--- a/services/surfaceflinger/DisplayHardware/HWComposer.h
+++ b/services/surfaceflinger/DisplayHardware/HWComposer.h
@@ -45,134 +45,273 @@
 class Composer;
 } // namespace Hwc2
 
-class HWComposer
-{
+class HWComposer {
+public:
+    virtual ~HWComposer();
+
+    virtual void registerCallback(HWC2::ComposerCallback* callback, int32_t sequenceId) = 0;
+
+    virtual bool getDisplayIdentificationData(hwc2_display_t hwcDisplayId, uint8_t* outPort,
+                                              DisplayIdentificationData* outData) const = 0;
+
+    virtual bool hasCapability(HWC2::Capability capability) const = 0;
+    virtual bool hasDisplayCapability(const std::optional<DisplayId>& displayId,
+                                      HWC2::DisplayCapability capability) const = 0;
+
+    // Attempts to allocate a virtual display and returns its ID if created on the HWC device.
+    virtual std::optional<DisplayId> allocateVirtualDisplay(uint32_t width, uint32_t height,
+                                                            ui::PixelFormat* format) = 0;
+
+    // Attempts to create a new layer on this display
+    virtual HWC2::Layer* createLayer(DisplayId displayId) = 0;
+    // Destroy a previously created layer
+    virtual void destroyLayer(DisplayId displayId, HWC2::Layer* layer) = 0;
+
+    // Asks the HAL what it can do
+    virtual status_t prepare(DisplayId displayId,
+                             std::vector<CompositionInfo>& compositionData) = 0;
+
+    virtual status_t setClientTarget(DisplayId displayId, uint32_t slot,
+                                     const sp<Fence>& acquireFence, const sp<GraphicBuffer>& target,
+                                     ui::Dataspace dataspace) = 0;
+
+    // Present layers to the display and read releaseFences.
+    virtual status_t presentAndGetReleaseFences(DisplayId displayId) = 0;
+
+    // set power mode
+    virtual status_t setPowerMode(DisplayId displayId, int mode) = 0;
+
+    // set active config
+    virtual status_t setActiveConfig(DisplayId displayId, size_t configId) = 0;
+
+    // Sets a color transform to be applied to the result of composition
+    virtual status_t setColorTransform(DisplayId displayId, const mat4& transform) = 0;
+
+    // reset state when an external, non-virtual display is disconnected
+    virtual void disconnectDisplay(DisplayId displayId) = 0;
+
+    // does this display have layers handled by HWC
+    virtual bool hasDeviceComposition(const std::optional<DisplayId>& displayId) const = 0;
+
+    // does this display have pending request to flip client target
+    virtual bool hasFlipClientTargetRequest(const std::optional<DisplayId>& displayId) const = 0;
+
+    // does this display have layers handled by GLES
+    virtual bool hasClientComposition(const std::optional<DisplayId>& displayId) const = 0;
+
+    // get the present fence received from the last call to present.
+    virtual sp<Fence> getPresentFence(DisplayId displayId) const = 0;
+
+    // Get last release fence for the given layer
+    virtual sp<Fence> getLayerReleaseFence(DisplayId displayId, HWC2::Layer* layer) const = 0;
+
+    // Set the output buffer and acquire fence for a virtual display.
+    // Returns INVALID_OPERATION if displayId is not a virtual display.
+    virtual status_t setOutputBuffer(DisplayId displayId, const sp<Fence>& acquireFence,
+                                     const sp<GraphicBuffer>& buffer) = 0;
+
+    // After SurfaceFlinger has retrieved the release fences for all the frames,
+    // it can call this to clear the shared pointers in the release fence map
+    virtual void clearReleaseFences(DisplayId displayId) = 0;
+
+    // Fetches the HDR capabilities of the given display
+    virtual status_t getHdrCapabilities(DisplayId displayId, HdrCapabilities* outCapabilities) = 0;
+
+    virtual int32_t getSupportedPerFrameMetadata(DisplayId displayId) const = 0;
+
+    // Returns the available RenderIntent of the given display.
+    virtual std::vector<ui::RenderIntent> getRenderIntents(DisplayId displayId,
+                                                           ui::ColorMode colorMode) const = 0;
+
+    virtual mat4 getDataspaceSaturationMatrix(DisplayId displayId, ui::Dataspace dataspace) = 0;
+
+    // Returns the attributes of the color sampling engine.
+    virtual status_t getDisplayedContentSamplingAttributes(DisplayId displayId,
+                                                           ui::PixelFormat* outFormat,
+                                                           ui::Dataspace* outDataspace,
+                                                           uint8_t* outComponentMask) = 0;
+    virtual status_t setDisplayContentSamplingEnabled(DisplayId displayId, bool enabled,
+                                                      uint8_t componentMask,
+                                                      uint64_t maxFrames) = 0;
+    virtual status_t getDisplayedContentSample(DisplayId displayId, uint64_t maxFrames,
+                                               uint64_t timestamp,
+                                               DisplayedFrameStats* outStats) = 0;
+
+    // Events handling ---------------------------------------------------------
+
+    // Returns stable display ID (and display name on connection of new or previously disconnected
+    // display), or std::nullopt if hotplug event was ignored.
+    virtual std::optional<DisplayIdentificationInfo> onHotplug(hwc2_display_t hwcDisplayId,
+                                                               HWC2::Connection connection) = 0;
+
+    virtual bool onVsync(hwc2_display_t hwcDisplayId, int64_t timestamp) = 0;
+    virtual void setVsyncEnabled(DisplayId displayId, HWC2::Vsync enabled) = 0;
+
+    virtual nsecs_t getRefreshTimestamp(DisplayId displayId) const = 0;
+    virtual bool isConnected(DisplayId displayId) const = 0;
+
+    // Non-const because it can update configMap inside of mDisplayData
+    virtual std::vector<std::shared_ptr<const HWC2::Display::Config>> getConfigs(
+            DisplayId displayId) const = 0;
+
+    virtual std::shared_ptr<const HWC2::Display::Config> getActiveConfig(
+            DisplayId displayId) const = 0;
+    virtual int getActiveConfigIndex(DisplayId displayId) const = 0;
+
+    virtual std::vector<ui::ColorMode> getColorModes(DisplayId displayId) const = 0;
+
+    virtual status_t setActiveColorMode(DisplayId displayId, ui::ColorMode mode,
+                                        ui::RenderIntent renderIntent) = 0;
+
+    virtual bool isUsingVrComposer() const = 0;
+
+    // for debugging ----------------------------------------------------------
+    virtual void dump(std::string& out) const = 0;
+
+    virtual Hwc2::Composer* getComposer() const = 0;
+
+    // TODO(b/74619554): Remove special cases for internal/external display.
+    virtual std::optional<hwc2_display_t> getInternalHwcDisplayId() const = 0;
+    virtual std::optional<hwc2_display_t> getExternalHwcDisplayId() const = 0;
+
+    virtual std::optional<DisplayId> toPhysicalDisplayId(hwc2_display_t hwcDisplayId) const = 0;
+    virtual std::optional<hwc2_display_t> fromPhysicalDisplayId(DisplayId displayId) const = 0;
+};
+
+namespace impl {
+
+class HWComposer final : public android::HWComposer {
 public:
     explicit HWComposer(std::unique_ptr<Hwc2::Composer> composer);
 
-    ~HWComposer();
+    ~HWComposer() override;
 
-    void registerCallback(HWC2::ComposerCallback* callback,
-                          int32_t sequenceId);
+    void registerCallback(HWC2::ComposerCallback* callback, int32_t sequenceId) override;
 
     bool getDisplayIdentificationData(hwc2_display_t hwcDisplayId, uint8_t* outPort,
-                                      DisplayIdentificationData* outData) const;
+                                      DisplayIdentificationData* outData) const override;
 
-    bool hasCapability(HWC2::Capability capability) const;
+    bool hasCapability(HWC2::Capability capability) const override;
     bool hasDisplayCapability(const std::optional<DisplayId>& displayId,
-                              HWC2::DisplayCapability capability) const;
+                              HWC2::DisplayCapability capability) const override;
 
     // Attempts to allocate a virtual display and returns its ID if created on the HWC device.
     std::optional<DisplayId> allocateVirtualDisplay(uint32_t width, uint32_t height,
-                                                    ui::PixelFormat* format);
+                                                    ui::PixelFormat* format) override;
 
     // Attempts to create a new layer on this display
-    HWC2::Layer* createLayer(DisplayId displayId);
+    HWC2::Layer* createLayer(DisplayId displayId) override;
     // Destroy a previously created layer
-    void destroyLayer(DisplayId displayId, HWC2::Layer* layer);
+    void destroyLayer(DisplayId displayId, HWC2::Layer* layer) override;
 
     // Asks the HAL what it can do
-    status_t prepare(DisplayId displayId, std::vector<CompositionInfo>& compositionData);
+    status_t prepare(DisplayId displayId, std::vector<CompositionInfo>& compositionData) override;
 
     status_t setClientTarget(DisplayId displayId, uint32_t slot, const sp<Fence>& acquireFence,
-                             const sp<GraphicBuffer>& target, ui::Dataspace dataspace);
+                             const sp<GraphicBuffer>& target, ui::Dataspace dataspace) override;
 
     // Present layers to the display and read releaseFences.
-    status_t presentAndGetReleaseFences(DisplayId displayId);
+    status_t presentAndGetReleaseFences(DisplayId displayId) override;
 
     // set power mode
-    status_t setPowerMode(DisplayId displayId, int mode);
+    status_t setPowerMode(DisplayId displayId, int mode) override;
 
     // set active config
-    status_t setActiveConfig(DisplayId displayId, size_t configId);
+    status_t setActiveConfig(DisplayId displayId, size_t configId) override;
 
     // Sets a color transform to be applied to the result of composition
-    status_t setColorTransform(DisplayId displayId, const mat4& transform);
+    status_t setColorTransform(DisplayId displayId, const mat4& transform) override;
 
     // reset state when an external, non-virtual display is disconnected
-    void disconnectDisplay(DisplayId displayId);
+    void disconnectDisplay(DisplayId displayId) override;
 
     // does this display have layers handled by HWC
-    bool hasDeviceComposition(const std::optional<DisplayId>& displayId) const;
+    bool hasDeviceComposition(const std::optional<DisplayId>& displayId) const override;
 
     // does this display have pending request to flip client target
-    bool hasFlipClientTargetRequest(const std::optional<DisplayId>& displayId) const;
+    bool hasFlipClientTargetRequest(const std::optional<DisplayId>& displayId) const override;
 
     // does this display have layers handled by GLES
-    bool hasClientComposition(const std::optional<DisplayId>& displayId) const;
+    bool hasClientComposition(const std::optional<DisplayId>& displayId) const override;
 
     // get the present fence received from the last call to present.
-    sp<Fence> getPresentFence(DisplayId displayId) const;
+    sp<Fence> getPresentFence(DisplayId displayId) const override;
 
     // Get last release fence for the given layer
-    sp<Fence> getLayerReleaseFence(DisplayId displayId, HWC2::Layer* layer) const;
+    sp<Fence> getLayerReleaseFence(DisplayId displayId, HWC2::Layer* layer) const override;
 
     // Set the output buffer and acquire fence for a virtual display.
     // Returns INVALID_OPERATION if displayId is not a virtual display.
     status_t setOutputBuffer(DisplayId displayId, const sp<Fence>& acquireFence,
-                             const sp<GraphicBuffer>& buffer);
+                             const sp<GraphicBuffer>& buffer) override;
 
     // After SurfaceFlinger has retrieved the release fences for all the frames,
     // it can call this to clear the shared pointers in the release fence map
-    void clearReleaseFences(DisplayId displayId);
+    void clearReleaseFences(DisplayId displayId) override;
 
     // Fetches the HDR capabilities of the given display
-    status_t getHdrCapabilities(DisplayId displayId, HdrCapabilities* outCapabilities);
+    status_t getHdrCapabilities(DisplayId displayId, HdrCapabilities* outCapabilities) override;
 
-    int32_t getSupportedPerFrameMetadata(DisplayId displayId) const;
+    int32_t getSupportedPerFrameMetadata(DisplayId displayId) const override;
 
     // Returns the available RenderIntent of the given display.
     std::vector<ui::RenderIntent> getRenderIntents(DisplayId displayId,
-                                                   ui::ColorMode colorMode) const;
+                                                   ui::ColorMode colorMode) const override;
 
-    mat4 getDataspaceSaturationMatrix(DisplayId displayId, ui::Dataspace dataspace);
+    mat4 getDataspaceSaturationMatrix(DisplayId displayId, ui::Dataspace dataspace) override;
 
     // Returns the attributes of the color sampling engine.
     status_t getDisplayedContentSamplingAttributes(DisplayId displayId, ui::PixelFormat* outFormat,
                                                    ui::Dataspace* outDataspace,
-                                                   uint8_t* outComponentMask);
+                                                   uint8_t* outComponentMask) override;
     status_t setDisplayContentSamplingEnabled(DisplayId displayId, bool enabled,
-                                              uint8_t componentMask, uint64_t maxFrames);
+                                              uint8_t componentMask, uint64_t maxFrames) override;
     status_t getDisplayedContentSample(DisplayId displayId, uint64_t maxFrames, uint64_t timestamp,
-                                       DisplayedFrameStats* outStats);
+                                       DisplayedFrameStats* outStats) override;
 
     // Events handling ---------------------------------------------------------
 
     // Returns stable display ID (and display name on connection of new or previously disconnected
     // display), or std::nullopt if hotplug event was ignored.
     std::optional<DisplayIdentificationInfo> onHotplug(hwc2_display_t hwcDisplayId,
-                                                       HWC2::Connection connection);
+                                                       HWC2::Connection connection) override;
 
-    bool onVsync(hwc2_display_t hwcDisplayId, int64_t timestamp);
-    void setVsyncEnabled(DisplayId displayId, HWC2::Vsync enabled);
+    bool onVsync(hwc2_display_t hwcDisplayId, int64_t timestamp) override;
+    void setVsyncEnabled(DisplayId displayId, HWC2::Vsync enabled) override;
 
-    nsecs_t getRefreshTimestamp(DisplayId displayId) const;
-    bool isConnected(DisplayId displayId) const;
+    nsecs_t getRefreshTimestamp(DisplayId displayId) const override;
+    bool isConnected(DisplayId displayId) const override;
 
     // Non-const because it can update configMap inside of mDisplayData
-    std::vector<std::shared_ptr<const HWC2::Display::Config>> getConfigs(DisplayId displayId) const;
+    std::vector<std::shared_ptr<const HWC2::Display::Config>> getConfigs(
+            DisplayId displayId) const override;
 
-    std::shared_ptr<const HWC2::Display::Config> getActiveConfig(DisplayId displayId) const;
-    int getActiveConfigIndex(DisplayId displayId) const;
+    std::shared_ptr<const HWC2::Display::Config> getActiveConfig(
+            DisplayId displayId) const override;
+    int getActiveConfigIndex(DisplayId displayId) const override;
 
-    std::vector<ui::ColorMode> getColorModes(DisplayId displayId) const;
+    std::vector<ui::ColorMode> getColorModes(DisplayId displayId) const override;
 
     status_t setActiveColorMode(DisplayId displayId, ui::ColorMode mode,
-                                ui::RenderIntent renderIntent);
+                                ui::RenderIntent renderIntent) override;
 
-    bool isUsingVrComposer() const;
+    bool isUsingVrComposer() const override;
 
     // for debugging ----------------------------------------------------------
-    void dump(std::string& out) const;
+    void dump(std::string& out) const override;
 
-    Hwc2::Composer* getComposer() const { return mHwcDevice->getComposer(); }
+    Hwc2::Composer* getComposer() const override { return mHwcDevice->getComposer(); }
 
     // TODO(b/74619554): Remove special cases for internal/external display.
-    std::optional<hwc2_display_t> getInternalHwcDisplayId() const { return mInternalHwcDisplayId; }
-    std::optional<hwc2_display_t> getExternalHwcDisplayId() const { return mExternalHwcDisplayId; }
+    std::optional<hwc2_display_t> getInternalHwcDisplayId() const override {
+        return mInternalHwcDisplayId;
+    }
+    std::optional<hwc2_display_t> getExternalHwcDisplayId() const override {
+        return mExternalHwcDisplayId;
+    }
 
-    std::optional<DisplayId> toPhysicalDisplayId(hwc2_display_t hwcDisplayId) const;
-    std::optional<hwc2_display_t> fromPhysicalDisplayId(DisplayId displayId) const;
+    std::optional<DisplayId> toPhysicalDisplayId(hwc2_display_t hwcDisplayId) const override;
+    std::optional<hwc2_display_t> fromPhysicalDisplayId(DisplayId displayId) const override;
 
 private:
     // For unit tests
@@ -223,6 +362,7 @@
     uint32_t mRemainingHwcVirtualDisplays{mHwcDevice->getMaxVirtualDisplayCount()};
 };
 
+} // namespace impl
 } // namespace android
 
 #endif // ANDROID_SF_HWCOMPOSER_H
diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp
index 2d3fd8e..b1827c1 100644
--- a/services/surfaceflinger/Layer.cpp
+++ b/services/surfaceflinger/Layer.cpp
@@ -83,35 +83,35 @@
 
     mTransactionName = String8("TX - ") + mName;
 
-    mState.current.active_legacy.w = args.w;
-    mState.current.active_legacy.h = args.h;
-    mState.current.flags = layerFlags;
-    mState.current.active_legacy.transform.set(0, 0);
-    mState.current.crop_legacy.makeInvalid();
-    mState.current.requestedCrop_legacy = mState.current.crop_legacy;
-    mState.current.z = 0;
-    mState.current.color.a = 1.0f;
-    mState.current.layerStack = 0;
-    mState.current.sequence = 0;
-    mState.current.requested_legacy = mState.current.active_legacy;
-    mState.current.appId = 0;
-    mState.current.type = 0;
-    mState.current.active.w = UINT32_MAX;
-    mState.current.active.h = UINT32_MAX;
-    mState.current.active.transform.set(0, 0);
-    mState.current.transform = 0;
-    mState.current.transformToDisplayInverse = false;
-    mState.current.crop.makeInvalid();
-    mState.current.acquireFence = new Fence(-1);
-    mState.current.dataspace = ui::Dataspace::UNKNOWN;
-    mState.current.hdrMetadata.validTypes = 0;
-    mState.current.surfaceDamageRegion.clear();
-    mState.current.cornerRadius = 0.0f;
-    mState.current.api = -1;
-    mState.current.hasColorTransform = false;
+    mCurrentState.active_legacy.w = args.w;
+    mCurrentState.active_legacy.h = args.h;
+    mCurrentState.flags = layerFlags;
+    mCurrentState.active_legacy.transform.set(0, 0);
+    mCurrentState.crop_legacy.makeInvalid();
+    mCurrentState.requestedCrop_legacy = mCurrentState.crop_legacy;
+    mCurrentState.z = 0;
+    mCurrentState.color.a = 1.0f;
+    mCurrentState.layerStack = 0;
+    mCurrentState.sequence = 0;
+    mCurrentState.requested_legacy = mCurrentState.active_legacy;
+    mCurrentState.appId = 0;
+    mCurrentState.type = 0;
+    mCurrentState.active.w = UINT32_MAX;
+    mCurrentState.active.h = UINT32_MAX;
+    mCurrentState.active.transform.set(0, 0);
+    mCurrentState.transform = 0;
+    mCurrentState.transformToDisplayInverse = false;
+    mCurrentState.crop.makeInvalid();
+    mCurrentState.acquireFence = new Fence(-1);
+    mCurrentState.dataspace = ui::Dataspace::UNKNOWN;
+    mCurrentState.hdrMetadata.validTypes = 0;
+    mCurrentState.surfaceDamageRegion.clear();
+    mCurrentState.cornerRadius = 0.0f;
+    mCurrentState.api = -1;
+    mCurrentState.hasColorTransform = false;
 
     // drawing state & current state are identical
-    mState.drawing = mState.current;
+    mDrawingState = mCurrentState;
 
     CompositorTiming compositorTiming;
     args.flinger->getCompositorTiming(&compositorTiming);
@@ -148,17 +148,14 @@
 void Layer::onRemovedFromCurrentState() {
     mRemovedFromCurrentState = true;
 
-    {
-        Mutex::Autolock lock(mStateMutex);
-        // the layer is removed from SF mState.current to mLayersPendingRemoval
-        if (mState.current.zOrderRelativeOf != nullptr) {
-            sp<Layer> strongRelative = mState.current.zOrderRelativeOf.promote();
-            if (strongRelative != nullptr) {
-                strongRelative->removeZOrderRelative(this);
-                mFlinger->setTransactionFlags(eTraversalNeeded);
-            }
-            mState.current.zOrderRelativeOf = nullptr;
+    // the layer is removed from SF mCurrentState to mLayersPendingRemoval
+    if (mCurrentState.zOrderRelativeOf != nullptr) {
+        sp<Layer> strongRelative = mCurrentState.zOrderRelativeOf.promote();
+        if (strongRelative != nullptr) {
+            strongRelative->removeZOrderRelative(this);
+            mFlinger->setTransactionFlags(eTraversalNeeded);
         }
+        mCurrentState.zOrderRelativeOf = nullptr;
     }
 
     // Since we are no longer reachable from CurrentState SurfaceFlinger
@@ -297,32 +294,21 @@
 }
 
 Rect Layer::computeScreenBounds(bool reduceTransparentRegion) const {
-    Mutex::Autolock lock(mStateMutex);
     const State& s(getDrawingState());
     Region transparentRegion = reduceTransparentRegion ? getActiveTransparentRegion(s) : Region();
-    FloatRect bounds = computeBoundsLocked(transparentRegion);
-    ui::Transform t = getTransformLocked();
+    FloatRect bounds = computeBounds(transparentRegion);
+    ui::Transform t = getTransform();
     // Transform to screen space.
     bounds = t.transform(bounds);
     return Rect{bounds};
 }
 
 FloatRect Layer::computeBounds() const {
-    Mutex::Autolock lock(mStateMutex);
-    return computeBoundsLocked();
-}
-
-FloatRect Layer::computeBoundsLocked() const {
     const State& s(getDrawingState());
-    return computeBoundsLocked(getActiveTransparentRegion(s));
+    return computeBounds(getActiveTransparentRegion(s));
 }
 
 FloatRect Layer::computeBounds(const Region& activeTransparentRegion) const {
-    Mutex::Autolock lock(mStateMutex);
-    return computeBoundsLocked(activeTransparentRegion);
-}
-
-FloatRect Layer::computeBoundsLocked(const Region& activeTransparentRegion) const {
     const State& s(getDrawingState());
     Rect bounds = getCroppedBufferSize(s);
     FloatRect floatBounds = bounds.toFloatRect();
@@ -375,7 +361,6 @@
         // child bounds as well.
         ui::Transform t = s.active_legacy.transform;
         croppedBounds = t.transform(croppedBounds);
-        Mutex::Autolock lock(p->mStateMutex);
         croppedBounds = p->cropChildBounds(croppedBounds);
         croppedBounds = t.inverse().transform(croppedBounds);
     }
@@ -403,8 +388,8 @@
     // if there are no window scaling involved, this operation will map to full
     // pixels in the buffer.
 
-    FloatRect activeCropFloat = computeBoundsLocked();
-    ui::Transform t = getTransformLocked();
+    FloatRect activeCropFloat = computeBounds();
+    ui::Transform t = getTransform();
     // Transform to screen space.
     activeCropFloat = t.transform(activeCropFloat);
     activeCropFloat = activeCropFloat.intersect(display->getViewport().toFloatRect());
@@ -454,7 +439,7 @@
     // which means using the inverse of the current transform set on the
     // SurfaceFlingerConsumer.
     uint32_t invTransform = mCurrentTransform;
-    if (getTransformToDisplayInverseLocked()) {
+    if (getTransformToDisplayInverse()) {
         /*
          * the code below applies the primary display's inverse transform to the
          * buffer
@@ -505,7 +490,6 @@
 }
 
 void Layer::setGeometry(const sp<const DisplayDevice>& display, uint32_t z) {
-    Mutex::Autolock lock(mStateMutex);
     const auto displayId = display->getId();
     LOG_ALWAYS_FATAL_IF(!displayId);
     RETURN_IF_NO_HWC_LAYER(*displayId);
@@ -514,7 +498,7 @@
     // enable this layer
     hwcInfo.forceClientComposition = false;
 
-    if (isSecureLocked() && !display->isSecure()) {
+    if (isSecure() && !display->isSecure()) {
         hwcInfo.forceClientComposition = true;
     }
 
@@ -524,7 +508,7 @@
     const State& s(getDrawingState());
     const Rect bufferSize = getBufferSize(s);
     auto blendMode = HWC2::BlendMode::None;
-    if (!isOpaque(s) || getAlphaLocked() != 1.0f) {
+    if (!isOpaque(s) || getAlpha() != 1.0f) {
         blendMode =
                 mPremultipliedAlpha ? HWC2::BlendMode::Premultiplied : HWC2::BlendMode::Coverage;
     }
@@ -539,7 +523,7 @@
     // apply the layer's transform, followed by the display's global transform
     // here we're guaranteed that the layer's transform preserves rects
     Region activeTransparentRegion(getActiveTransparentRegion(s));
-    ui::Transform t = getTransformLocked();
+    ui::Transform t = getTransform();
     Rect activeCrop = getCrop(s);
     if (!activeCrop.isEmpty() && bufferSize.isValid()) {
         activeCrop = t.transform(activeCrop);
@@ -567,7 +551,7 @@
 
     // computeBounds returns a FloatRect to provide more accuracy during the
     // transformation. We then round upon constructing 'frame'.
-    Rect frame{t.transform(computeBoundsLocked(activeTransparentRegion))};
+    Rect frame{t.transform(computeBounds(activeTransparentRegion))};
     if (!frame.intersect(display->getViewport(), &frame)) {
         frame.clear();
     }
@@ -595,7 +579,7 @@
     }
     getBE().compositionInfo.hwc.sourceCrop = sourceCrop;
 
-    float alpha = static_cast<float>(getAlphaLocked());
+    float alpha = static_cast<float>(getAlpha());
     error = hwcLayer->setPlaneAlpha(alpha);
     ALOGE_IF(error != HWC2::Error::None,
              "[%s] Failed to set plane alpha %.3f: "
@@ -612,7 +596,6 @@
     int appId = s.appId;
     sp<Layer> parent = mDrawingParent.promote();
     if (parent.get()) {
-        Mutex::Autolock lock(parent->mStateMutex);
         auto& parentState = parent->getDrawingState();
         if (parentState.type >= 0 || parentState.appId >= 0) {
             type = parentState.type;
@@ -638,7 +621,7 @@
     const ui::Transform bufferOrientation(mCurrentTransform);
     ui::Transform transform(tr * t * bufferOrientation);
 
-    if (getTransformToDisplayInverseLocked()) {
+    if (getTransformToDisplayInverse()) {
         /*
          * the code below applies the primary display's inverse transform to the
          * buffer
@@ -688,7 +671,6 @@
 }
 
 void Layer::updateCursorPosition(const sp<const DisplayDevice>& display) {
-    Mutex::Autolock lock(mStateMutex);
     const auto displayId = display->getId();
     LOG_ALWAYS_FATAL_IF(!displayId);
     if (!hasHwcLayer(*displayId) || getCompositionType(displayId) != HWC2::Composition::Cursor) {
@@ -703,7 +685,7 @@
     Rect win = getCroppedBufferSize(s);
     // Subtract the transparent region and snap to the bounds
     Rect bounds = reduce(win, getActiveTransparentRegion(s));
-    Rect frame(getTransformLocked().transform(bounds));
+    Rect frame(getTransform().transform(bounds));
     frame.intersect(display->getViewport(), &frame);
     auto& displayTransform = display->getTransform();
     auto position = displayTransform.transform(frame);
@@ -733,7 +715,6 @@
 void Layer::clearWithOpenGL(const RenderArea& renderArea, float red, float green, float blue,
                             float alpha) const {
     auto& engine(mFlinger->getRenderEngine());
-    Mutex::Autolock lock(mStateMutex);
     computeGeometry(renderArea, getBE().mMesh, false);
     engine.setupFillWithColor(red, green, blue, alpha);
     engine.drawMesh(getBE().mMesh);
@@ -818,14 +799,14 @@
                             renderengine::Mesh& mesh,
                             bool useIdentityTransform) const {
     const ui::Transform renderAreaTransform(renderArea.getTransform());
-    FloatRect win = computeBoundsLocked();
+    FloatRect win = computeBounds();
 
     vec2 lt = vec2(win.left, win.top);
     vec2 lb = vec2(win.left, win.bottom);
     vec2 rb = vec2(win.right, win.bottom);
     vec2 rt = vec2(win.right, win.top);
 
-    ui::Transform layerTransform = getTransformLocked();
+    ui::Transform layerTransform = getTransform();
     if (!useIdentityTransform) {
         lt = layerTransform.transform(lt);
         lb = layerTransform.transform(lb);
@@ -841,12 +822,7 @@
 }
 
 bool Layer::isSecure() const {
-    Mutex::Autolock lock(mStateMutex);
-    return isSecureLocked();
-}
-
-bool Layer::isSecureLocked() const {
-    const State& s(mState.drawing);
+    const State& s(mDrawingState);
     return (s.flags & layer_state_t::eLayerSecure);
 }
 
@@ -874,13 +850,9 @@
 // ----------------------------------------------------------------------------
 // transaction
 // ----------------------------------------------------------------------------
-void Layer::pushPendingState() {
-    Mutex::Autolock lock(mStateMutex);
-    pushPendingStateLocked();
-}
 
-void Layer::pushPendingStateLocked() {
-    if (!mState.current.modified) {
+void Layer::pushPendingState() {
+    if (!mCurrentState.modified) {
         return;
     }
 
@@ -888,22 +860,22 @@
     // point and send it to the remote layer.
     // We don't allow installing sync points after we are removed from the current state
     // as we won't be able to signal our end.
-    if (mState.current.barrierLayer_legacy != nullptr && !isRemovedFromCurrentState()) {
-        sp<Layer> barrierLayer = mState.current.barrierLayer_legacy.promote();
+    if (mCurrentState.barrierLayer_legacy != nullptr && !isRemovedFromCurrentState()) {
+        sp<Layer> barrierLayer = mCurrentState.barrierLayer_legacy.promote();
         if (barrierLayer == nullptr) {
             ALOGE("[%s] Unable to promote barrier Layer.", mName.string());
             // If we can't promote the layer we are intended to wait on,
             // then it is expired or otherwise invalid. Allow this transaction
             // to be applied as per normal (no synchronization).
-            mState.current.barrierLayer_legacy = nullptr;
+            mCurrentState.barrierLayer_legacy = nullptr;
         } else {
-            auto syncPoint = std::make_shared<SyncPoint>(mState.current.frameNumber_legacy);
+            auto syncPoint = std::make_shared<SyncPoint>(mCurrentState.frameNumber_legacy);
             if (barrierLayer->addSyncPoint(syncPoint)) {
                 mRemoteSyncPoints.push_back(std::move(syncPoint));
             } else {
                 // We already missed the frame we're supposed to synchronize
                 // on, so go ahead and apply the state update
-                mState.current.barrierLayer_legacy = nullptr;
+                mCurrentState.barrierLayer_legacy = nullptr;
             }
         }
 
@@ -911,21 +883,21 @@
         setTransactionFlags(eTransactionNeeded);
         mFlinger->setTransactionFlags(eTraversalNeeded);
     }
-    mState.pending.push_back(mState.current);
-    ATRACE_INT(mTransactionName.string(), mState.pending.size());
+    mPendingStates.push_back(mCurrentState);
+    ATRACE_INT(mTransactionName.string(), mPendingStates.size());
 }
 
 void Layer::popPendingState(State* stateToCommit) {
-    *stateToCommit = mState.pending[0];
+    *stateToCommit = mPendingStates[0];
 
-    mState.pending.removeAt(0);
-    ATRACE_INT(mTransactionName.string(), mState.pending.size());
+    mPendingStates.removeAt(0);
+    ATRACE_INT(mTransactionName.string(), mPendingStates.size());
 }
 
 bool Layer::applyPendingStates(State* stateToCommit) {
     bool stateUpdateAvailable = false;
-    while (!mState.pending.empty()) {
-        if (mState.pending[0].barrierLayer_legacy != nullptr) {
+    while (!mPendingStates.empty()) {
+        if (mPendingStates[0].barrierLayer_legacy != nullptr) {
             if (mRemoteSyncPoints.empty()) {
                 // If we don't have a sync point for this, apply it anyway. It
                 // will be visually wrong, but it should keep us from getting
@@ -937,7 +909,7 @@
             }
 
             if (mRemoteSyncPoints.front()->getFrameNumber() !=
-                mState.pending[0].frameNumber_legacy) {
+                mPendingStates[0].frameNumber_legacy) {
                 ALOGE("[%s] Unexpected sync point frame number found", mName.string());
 
                 // Signal our end of the sync point and then dispose of it
@@ -965,12 +937,12 @@
 
     // If we still have pending updates, wake SurfaceFlinger back up and point
     // it at this layer so we can process them
-    if (!mState.pending.empty()) {
+    if (!mPendingStates.empty()) {
         setTransactionFlags(eTransactionNeeded);
         mFlinger->setTransactionFlags(eTraversalNeeded);
     }
 
-    mState.current.modified = false;
+    mCurrentState.modified = false;
     return stateUpdateAvailable;
 }
 
@@ -1067,8 +1039,7 @@
         return 0;
     }
 
-    Mutex::Autolock lock(mStateMutex);
-    pushPendingStateLocked();
+    pushPendingState();
     State c = getCurrentState();
     if (!applyPendingStates(&c)) {
         return 0;
@@ -1100,60 +1071,49 @@
         clearSyncPoints();
     }
 
-    if (mState.current.inputInfoChanged) {
+    if (mCurrentState.inputInfoChanged) {
         flags |= eInputInfoChanged;
-        mState.current.inputInfoChanged = false;
+        mCurrentState.inputInfoChanged = false;
     }
 
     // Commit the transaction
     commitTransaction(c);
-    mState.current.callbackHandles = {};
+    mCurrentState.callbackHandles = {};
     return flags;
 }
 
 void Layer::commitTransaction(const State& stateToCommit) {
-    mState.drawing = stateToCommit;
-}
-
-uint32_t Layer::getTransactionFlags() const {
-    Mutex::Autolock lock(mStateMutex);
-    return mState.transactionFlags;
+    mDrawingState = stateToCommit;
 }
 
 uint32_t Layer::getTransactionFlags(uint32_t flags) {
-    Mutex::Autolock lock(mStateMutex);
-    uint32_t and_flags = mState.transactionFlags & flags;
-    mState.transactionFlags &= ~flags;
-    return and_flags;
+    return mTransactionFlags.fetch_and(~flags) & flags;
 }
 
 uint32_t Layer::setTransactionFlags(uint32_t flags) {
-    uint32_t old_flags = mState.transactionFlags;
-    mState.transactionFlags |= flags;
-    return old_flags;
+    return mTransactionFlags.fetch_or(flags);
 }
 
 bool Layer::setPosition(float x, float y, bool immediate) {
-    Mutex::Autolock lock(mStateMutex);
-    if (mState.current.requested_legacy.transform.tx() == x &&
-        mState.current.requested_legacy.transform.ty() == y)
+    if (mCurrentState.requested_legacy.transform.tx() == x &&
+        mCurrentState.requested_legacy.transform.ty() == y)
         return false;
-    mState.current.sequence++;
+    mCurrentState.sequence++;
 
     // We update the requested and active position simultaneously because
     // we want to apply the position portion of the transform matrix immediately,
     // but still delay scaling when resizing a SCALING_MODE_FREEZE layer.
-    mState.current.requested_legacy.transform.set(x, y);
+    mCurrentState.requested_legacy.transform.set(x, y);
     if (immediate && !mFreezeGeometryUpdates) {
         // Here we directly update the active state
         // unlike other setters, because we store it within
         // the transform, but use different latching rules.
         // b/38182305
-        mState.current.active_legacy.transform.set(x, y);
+        mCurrentState.active_legacy.transform.set(x, y);
     }
     mFreezeGeometryUpdates = mFreezeGeometryUpdates || !immediate;
 
-    mState.current.modified = true;
+    mCurrentState.modified = true;
     setTransactionFlags(eTransactionNeeded);
     return true;
 }
@@ -1186,44 +1146,38 @@
 }
 
 bool Layer::setLayer(int32_t z) {
-    Mutex::Autolock lock(mStateMutex);
-    if (mState.current.z == z && !usingRelativeZLocked(LayerVector::StateSet::Current))
-        return false;
-
-    mState.current.sequence++;
-    mState.current.z = z;
-    mState.current.modified = true;
+    if (mCurrentState.z == z && !usingRelativeZ(LayerVector::StateSet::Current)) return false;
+    mCurrentState.sequence++;
+    mCurrentState.z = z;
+    mCurrentState.modified = true;
 
     // Discard all relative layering.
-    if (mState.current.zOrderRelativeOf != nullptr) {
-        sp<Layer> strongRelative = mState.current.zOrderRelativeOf.promote();
+    if (mCurrentState.zOrderRelativeOf != nullptr) {
+        sp<Layer> strongRelative = mCurrentState.zOrderRelativeOf.promote();
         if (strongRelative != nullptr) {
             strongRelative->removeZOrderRelative(this);
         }
-        mState.current.zOrderRelativeOf = nullptr;
+        mCurrentState.zOrderRelativeOf = nullptr;
     }
     setTransactionFlags(eTransactionNeeded);
     return true;
 }
 
 void Layer::removeZOrderRelative(const wp<Layer>& relative) {
-    Mutex::Autolock lock(mStateMutex);
-    mState.current.zOrderRelatives.remove(relative);
-    mState.current.sequence++;
-    mState.current.modified = true;
+    mCurrentState.zOrderRelatives.remove(relative);
+    mCurrentState.sequence++;
+    mCurrentState.modified = true;
     setTransactionFlags(eTransactionNeeded);
 }
 
 void Layer::addZOrderRelative(const wp<Layer>& relative) {
-    Mutex::Autolock lock(mStateMutex);
-    mState.current.zOrderRelatives.add(relative);
-    mState.current.modified = true;
-    mState.current.sequence++;
+    mCurrentState.zOrderRelatives.add(relative);
+    mCurrentState.modified = true;
+    mCurrentState.sequence++;
     setTransactionFlags(eTransactionNeeded);
 }
 
 bool Layer::setRelativeLayer(const sp<IBinder>& relativeToHandle, int32_t relativeZ) {
-    Mutex::Autolock lock(mStateMutex);
     sp<Handle> handle = static_cast<Handle*>(relativeToHandle.get());
     if (handle == nullptr) {
         return false;
@@ -1233,20 +1187,20 @@
         return false;
     }
 
-    if (mState.current.z == relativeZ && usingRelativeZLocked(LayerVector::StateSet::Current) &&
-        mState.current.zOrderRelativeOf == relative) {
+    if (mCurrentState.z == relativeZ && usingRelativeZ(LayerVector::StateSet::Current) &&
+        mCurrentState.zOrderRelativeOf == relative) {
         return false;
     }
 
-    mState.current.sequence++;
-    mState.current.modified = true;
-    mState.current.z = relativeZ;
+    mCurrentState.sequence++;
+    mCurrentState.modified = true;
+    mCurrentState.z = relativeZ;
 
-    auto oldZOrderRelativeOf = mState.current.zOrderRelativeOf.promote();
+    auto oldZOrderRelativeOf = mCurrentState.zOrderRelativeOf.promote();
     if (oldZOrderRelativeOf != nullptr) {
         oldZOrderRelativeOf->removeZOrderRelative(this);
     }
-    mState.current.zOrderRelativeOf = relative;
+    mCurrentState.zOrderRelativeOf = relative;
     relative->addZOrderRelative(this);
 
     setTransactionFlags(eTransactionNeeded);
@@ -1255,51 +1209,47 @@
 }
 
 bool Layer::setSize(uint32_t w, uint32_t h) {
-    Mutex::Autolock lock(mStateMutex);
-    if (mState.current.requested_legacy.w == w && mState.current.requested_legacy.h == h)
+    if (mCurrentState.requested_legacy.w == w && mCurrentState.requested_legacy.h == h)
         return false;
-    mState.current.requested_legacy.w = w;
-    mState.current.requested_legacy.h = h;
-    mState.current.modified = true;
+    mCurrentState.requested_legacy.w = w;
+    mCurrentState.requested_legacy.h = h;
+    mCurrentState.modified = true;
     setTransactionFlags(eTransactionNeeded);
 
     // record the new size, from this point on, when the client request
     // a buffer, it'll get the new size.
-    setDefaultBufferSize(mState.current.requested_legacy.w, mState.current.requested_legacy.h);
+    setDefaultBufferSize(mCurrentState.requested_legacy.w, mCurrentState.requested_legacy.h);
     return true;
 }
 bool Layer::setAlpha(float alpha) {
-    Mutex::Autolock lock(mStateMutex);
-    if (mState.current.color.a == alpha) return false;
-    mState.current.sequence++;
-    mState.current.color.a = alpha;
-    mState.current.modified = true;
+    if (mCurrentState.color.a == alpha) return false;
+    mCurrentState.sequence++;
+    mCurrentState.color.a = alpha;
+    mCurrentState.modified = true;
     setTransactionFlags(eTransactionNeeded);
     return true;
 }
 
 bool Layer::setColor(const half3& color) {
-    Mutex::Autolock lock(mStateMutex);
-    if (color.r == mState.current.color.r && color.g == mState.current.color.g &&
-        color.b == mState.current.color.b)
+    if (color.r == mCurrentState.color.r && color.g == mCurrentState.color.g &&
+        color.b == mCurrentState.color.b)
         return false;
 
-    mState.current.sequence++;
-    mState.current.color.r = color.r;
-    mState.current.color.g = color.g;
-    mState.current.color.b = color.b;
-    mState.current.modified = true;
+    mCurrentState.sequence++;
+    mCurrentState.color.r = color.r;
+    mCurrentState.color.g = color.g;
+    mCurrentState.color.b = color.b;
+    mCurrentState.modified = true;
     setTransactionFlags(eTransactionNeeded);
     return true;
 }
 
 bool Layer::setCornerRadius(float cornerRadius) {
-    Mutex::Autolock lock(mStateMutex);
-    if (mState.current.cornerRadius == cornerRadius) return false;
+    if (mCurrentState.cornerRadius == cornerRadius) return false;
 
-    mState.current.sequence++;
-    mState.current.cornerRadius = cornerRadius;
-    mState.current.modified = true;
+    mCurrentState.sequence++;
+    mCurrentState.cornerRadius = cornerRadius;
+    mCurrentState.modified = true;
     setTransactionFlags(eTransactionNeeded);
     return true;
 }
@@ -1313,50 +1263,45 @@
         ALOGW("Attempt to set rotation matrix without permission ACCESS_SURFACE_FLINGER ignored");
         return false;
     }
-    Mutex::Autolock lock(mStateMutex);
-    mState.current.sequence++;
-    mState.current.requested_legacy.transform.set(matrix.dsdx, matrix.dtdy, matrix.dtdx,
-                                                  matrix.dsdy);
-    mState.current.modified = true;
+    mCurrentState.sequence++;
+    mCurrentState.requested_legacy.transform.set(matrix.dsdx, matrix.dtdy, matrix.dtdx,
+                                                 matrix.dsdy);
+    mCurrentState.modified = true;
     setTransactionFlags(eTransactionNeeded);
     return true;
 }
 
 bool Layer::setTransparentRegionHint(const Region& transparent) {
-    Mutex::Autolock lock(mStateMutex);
-    mState.current.requestedTransparentRegion_legacy = transparent;
-    mState.current.modified = true;
+    mCurrentState.requestedTransparentRegion_legacy = transparent;
+    mCurrentState.modified = true;
     setTransactionFlags(eTransactionNeeded);
     return true;
 }
 bool Layer::setFlags(uint8_t flags, uint8_t mask) {
-    Mutex::Autolock lock(mStateMutex);
-    const uint32_t newFlags = (mState.current.flags & ~mask) | (flags & mask);
-    if (mState.current.flags == newFlags) return false;
-    mState.current.sequence++;
-    mState.current.flags = newFlags;
-    mState.current.modified = true;
+    const uint32_t newFlags = (mCurrentState.flags & ~mask) | (flags & mask);
+    if (mCurrentState.flags == newFlags) return false;
+    mCurrentState.sequence++;
+    mCurrentState.flags = newFlags;
+    mCurrentState.modified = true;
     setTransactionFlags(eTransactionNeeded);
     return true;
 }
 
 bool Layer::setCrop_legacy(const Rect& crop, bool immediate) {
-    Mutex::Autolock lock(mStateMutex);
-    if (mState.current.requestedCrop_legacy == crop) return false;
-    mState.current.sequence++;
-    mState.current.requestedCrop_legacy = crop;
+    if (mCurrentState.requestedCrop_legacy == crop) return false;
+    mCurrentState.sequence++;
+    mCurrentState.requestedCrop_legacy = crop;
     if (immediate && !mFreezeGeometryUpdates) {
-        mState.current.crop_legacy = crop;
+        mCurrentState.crop_legacy = crop;
     }
     mFreezeGeometryUpdates = mFreezeGeometryUpdates || !immediate;
 
-    mState.current.modified = true;
+    mCurrentState.modified = true;
     setTransactionFlags(eTransactionNeeded);
     return true;
 }
 
 bool Layer::setOverrideScalingMode(int32_t scalingMode) {
-    Mutex::Autolock lock(mStateMutex);
     if (scalingMode == mOverrideScalingMode) return false;
     mOverrideScalingMode = scalingMode;
     setTransactionFlags(eTransactionNeeded);
@@ -1364,29 +1309,22 @@
 }
 
 void Layer::setInfo(int32_t type, int32_t appId) {
-    Mutex::Autolock lock(mStateMutex);
-    mState.current.appId = appId;
-    mState.current.type = type;
-    mState.current.modified = true;
+    mCurrentState.appId = appId;
+    mCurrentState.type = type;
+    mCurrentState.modified = true;
     setTransactionFlags(eTransactionNeeded);
 }
 
 bool Layer::setLayerStack(uint32_t layerStack) {
-    Mutex::Autolock lock(mStateMutex);
-    if (mState.current.layerStack == layerStack) return false;
-    mState.current.sequence++;
-    mState.current.layerStack = layerStack;
-    mState.current.modified = true;
+    if (mCurrentState.layerStack == layerStack) return false;
+    mCurrentState.sequence++;
+    mCurrentState.layerStack = layerStack;
+    mCurrentState.modified = true;
     setTransactionFlags(eTransactionNeeded);
     return true;
 }
 
 uint32_t Layer::getLayerStack() const {
-    Mutex::Autolock lock(mStateMutex);
-    return getLayerStackLocked();
-}
-
-uint32_t Layer::getLayerStackLocked() const {
     auto p = mDrawingParent.promote();
     if (p == nullptr) {
         return getDrawingState().layerStack;
@@ -1395,16 +1333,15 @@
 }
 
 void Layer::deferTransactionUntil_legacy(const sp<Layer>& barrierLayer, uint64_t frameNumber) {
-    Mutex::Autolock lock(mStateMutex);
-    mState.current.barrierLayer_legacy = barrierLayer;
-    mState.current.frameNumber_legacy = frameNumber;
+    mCurrentState.barrierLayer_legacy = barrierLayer;
+    mCurrentState.frameNumber_legacy = frameNumber;
     // We don't set eTransactionNeeded, because just receiving a deferral
     // request without any other state updates shouldn't actually induce a delay
-    mState.current.modified = true;
-    pushPendingStateLocked();
-    mState.current.barrierLayer_legacy = nullptr;
-    mState.current.frameNumber_legacy = 0;
-    mState.current.modified = false;
+    mCurrentState.modified = true;
+    pushPendingState();
+    mCurrentState.barrierLayer_legacy = nullptr;
+    mCurrentState.frameNumber_legacy = 0;
+    mCurrentState.modified = false;
 }
 
 void Layer::deferTransactionUntil_legacy(const sp<IBinder>& barrierHandle, uint64_t frameNumber) {
@@ -1417,8 +1354,7 @@
 // ----------------------------------------------------------------------------
 
 bool Layer::isHiddenByPolicy() const {
-    Mutex::Autolock lock(mStateMutex);
-    const State& s(mState.drawing);
+    const State& s(mDrawingState);
     const auto& parent = mDrawingParent.promote();
     if (parent != nullptr && parent->isHiddenByPolicy()) {
         return true;
@@ -1463,7 +1399,6 @@
 
 // TODO(marissaw): add new layer state info to layer debugging
 LayerDebugInfo Layer::getLayerDebugInfo() const {
-    Mutex::Autolock lock(mStateMutex);
     LayerDebugInfo info;
     const State& ds = getDrawingState();
     info.mName = getName();
@@ -1473,7 +1408,7 @@
     info.mTransparentRegion = ds.activeTransparentRegion_legacy;
     info.mVisibleRegion = visibleRegion;
     info.mSurfaceDamageRegion = surfaceDamageRegion;
-    info.mLayerStack = getLayerStackLocked();
+    info.mLayerStack = getLayerStack();
     info.mX = ds.active_legacy.transform.tx();
     info.mY = ds.active_legacy.transform.ty();
     info.mZ = ds.z;
@@ -1509,13 +1444,6 @@
     return info;
 }
 
-std::tuple<uint32_t, int32_t> Layer::getLayerStackAndZ(StateSet stateSet) {
-    Mutex::Autolock lock(mStateMutex);
-    const State& state = (stateSet == StateSet::Current) ? mState.current : mState.drawing;
-
-    return {state.layerStack, state.z};
-}
-
 void Layer::miniDumpHeader(std::string& result) {
     result.append("-------------------------------");
     result.append("-------------------------------");
@@ -1532,7 +1460,6 @@
 }
 
 void Layer::miniDump(std::string& result, DisplayId displayId) const {
-    Mutex::Autolock lock(mStateMutex);
     if (!hasHwcLayer(displayId)) {
         return;
     }
@@ -1661,7 +1588,6 @@
     }
 
     if (attachChildren()) {
-        Mutex::Autolock lock(mStateMutex);
         setTransactionFlags(eTransactionNeeded);
     }
     for (const sp<Layer>& child : mCurrentChildren) {
@@ -1700,7 +1626,6 @@
         addToCurrentState();
     }
 
-    Mutex::Autolock lock(mStateMutex);
     if (mLayerDetached) {
         mLayerDetached = false;
         setTransactionFlags(eTransactionNeeded);
@@ -1744,24 +1669,18 @@
 bool Layer::setColorTransform(const mat4& matrix) {
     static const mat4 identityMatrix = mat4();
 
-    Mutex::Autolock lock(mStateMutex);
-    if (mState.current.colorTransform == matrix) {
+    if (mCurrentState.colorTransform == matrix) {
         return false;
     }
-    ++mState.current.sequence;
-    mState.current.colorTransform = matrix;
-    mState.current.hasColorTransform = matrix != identityMatrix;
-    mState.current.modified = true;
+    ++mCurrentState.sequence;
+    mCurrentState.colorTransform = matrix;
+    mCurrentState.hasColorTransform = matrix != identityMatrix;
+    mCurrentState.modified = true;
     setTransactionFlags(eTransactionNeeded);
     return true;
 }
 
 mat4 Layer::getColorTransform() const {
-    Mutex::Autolock lock(mStateMutex);
-    return getColorTransformLocked();
-}
-
-mat4 Layer::getColorTransformLocked() const {
     mat4 colorTransform = mat4(getDrawingState().colorTransform);
     if (sp<Layer> parent = mDrawingParent.promote(); parent != nullptr) {
         colorTransform = parent->getColorTransform() * colorTransform;
@@ -1770,7 +1689,6 @@
 }
 
 bool Layer::hasColorTransform() const {
-    Mutex::Autolock lock(mStateMutex);
     bool hasColorTransform = getDrawingState().hasColorTransform;
     if (sp<Layer> parent = mDrawingParent.promote(); parent != nullptr) {
         hasColorTransform = hasColorTransform || parent->hasColorTransform();
@@ -1801,18 +1719,12 @@
 }
 
 int32_t Layer::getZ() const {
-    Mutex::Autolock lock(mStateMutex);
-    return mState.drawing.z;
+    return mDrawingState.z;
 }
 
 bool Layer::usingRelativeZ(LayerVector::StateSet stateSet) {
-    Mutex::Autolock lock(mStateMutex);
-    return usingRelativeZLocked(stateSet);
-}
-
-bool Layer::usingRelativeZLocked(LayerVector::StateSet stateSet) {
     const bool useDrawing = stateSet == LayerVector::StateSet::Drawing;
-    const State& state = useDrawing ? mState.drawing : mState.current;
+    const State& state = useDrawing ? mDrawingState : mCurrentState;
     return state.zOrderRelativeOf != nullptr;
 }
 
@@ -1822,7 +1734,7 @@
                         "makeTraversalList received invalid stateSet");
     const bool useDrawing = stateSet == LayerVector::StateSet::Drawing;
     const LayerVector& children = useDrawing ? mDrawingChildren : mCurrentChildren;
-    const State& state = useDrawing ? mState.drawing : mState.current;
+    const State& state = useDrawing ? mDrawingState : mCurrentState;
 
     if (state.zOrderRelatives.size() == 0) {
         *outSkipRelativeZUsers = true;
@@ -1838,7 +1750,7 @@
     }
 
     for (const sp<Layer>& child : children) {
-        const State& childState = useDrawing ? child->mState.drawing : child->mState.current;
+        const State& childState = useDrawing ? child->mDrawingState : child->mCurrentState;
         if (childState.zOrderRelativeOf != nullptr) {
             continue;
         }
@@ -1877,6 +1789,7 @@
     visitor(this);
     for (; i < list.size(); i++) {
         const auto& relative = list[i];
+
         if (skipRelativeZUsers && relative->usingRelativeZ(stateSet)) {
             continue;
         }
@@ -1924,7 +1837,7 @@
                         "makeTraversalList received invalid stateSet");
     const bool useDrawing = stateSet == LayerVector::StateSet::Drawing;
     const LayerVector& children = useDrawing ? mDrawingChildren : mCurrentChildren;
-    const State& state = useDrawing ? mState.drawing : mState.current;
+    const State& state = useDrawing ? mDrawingState : mCurrentState;
 
     LayerVector traverse(stateSet);
     for (const wp<Layer>& weakRelative : state.zOrderRelatives) {
@@ -1937,7 +1850,7 @@
     }
 
     for (const sp<Layer>& child : children) {
-        const State& childState = useDrawing ? child->mState.drawing : child->mState.current;
+        const State& childState = useDrawing ? child->mDrawingState : child->mCurrentState;
         // If a layer has a relativeOf layer, only ignore if the layer it's relative to is a
         // descendent of the top most parent of the tree. If it's not a descendent, then just add
         // the child here since it won't be added later as a relative.
@@ -1994,16 +1907,10 @@
 }
 
 ui::Transform Layer::getTransform() const {
-    Mutex::Autolock lock(mStateMutex);
-    return getTransformLocked();
-}
-
-ui::Transform Layer::getTransformLocked() const {
     ui::Transform t;
     const auto& p = mDrawingParent.promote();
     if (p != nullptr) {
-        Mutex::Autolock lock(p->mStateMutex);
-        t = p->getTransformLocked();
+        t = p->getTransform();
 
         // If the parent is not using NATIVE_WINDOW_SCALING_MODE_FREEZE (e.g.
         // it isFixedSize) then there may be additional scaling not accounted
@@ -2031,27 +1938,18 @@
 }
 
 half Layer::getAlpha() const {
-    Mutex::Autolock lock(mStateMutex);
-    return getAlphaLocked();
-}
-
-half Layer::getAlphaLocked() const {
     const auto& p = mDrawingParent.promote();
+
     half parentAlpha = (p != nullptr) ? p->getAlpha() : 1.0_hf;
     return parentAlpha * getDrawingState().color.a;
 }
 
 half4 Layer::getColor() const {
     const half4 color(getDrawingState().color);
-    return half4(color.r, color.g, color.b, getAlphaLocked());
+    return half4(color.r, color.g, color.b, getAlpha());
 }
 
 Layer::RoundedCornerState Layer::getRoundedCornerState() const {
-    Mutex::Autolock lock(mStateMutex);
-    return getRoundedCornerStateLocked();
-}
-
-Layer::RoundedCornerState Layer::getRoundedCornerStateLocked() const {
     const auto& p = mDrawingParent.promote();
     if (p != nullptr) {
         RoundedCornerState parentState = p->getRoundedCornerState();
@@ -2068,7 +1966,7 @@
         }
     }
     const float radius = getDrawingState().cornerRadius;
-    return radius > 0 ? RoundedCornerState(computeBoundsLocked(), radius) : RoundedCornerState();
+    return radius > 0 ? RoundedCornerState(computeBounds(), radius) : RoundedCornerState();
 }
 
 void Layer::commitChildList() {
@@ -2081,21 +1979,19 @@
 }
 
 void Layer::setInputInfo(const InputWindowInfo& info) {
-    Mutex::Autolock lock(mStateMutex);
-    mState.current.inputInfo = info;
-    mState.current.modified = true;
-    mState.current.inputInfoChanged = true;
+    mCurrentState.inputInfo = info;
+    mCurrentState.modified = true;
+    mCurrentState.inputInfoChanged = true;
     setTransactionFlags(eTransactionNeeded);
 }
 
 void Layer::writeToProto(LayerProto* layerInfo, LayerVector::StateSet stateSet) {
-    Mutex::Autolock lock(mStateMutex);
     const bool useDrawing = stateSet == LayerVector::StateSet::Drawing;
     const LayerVector& children = useDrawing ? mDrawingChildren : mCurrentChildren;
-    const State& state = useDrawing ? mState.drawing : mState.current;
+    const State& state = useDrawing ? mDrawingState : mCurrentState;
 
     ui::Transform requestedTransform = state.active_legacy.transform;
-    ui::Transform transform = getTransformLocked();
+    ui::Transform transform = getTransform();
 
     layerInfo->set_id(sequence);
     layerInfo->set_name(getName().c_str());
@@ -2117,7 +2013,7 @@
     LayerProtoHelper::writeToProto(visibleRegion, layerInfo->mutable_visible_region());
     LayerProtoHelper::writeToProto(surfaceDamageRegion, layerInfo->mutable_damage_region());
 
-    layerInfo->set_layer_stack(getLayerStackLocked());
+    layerInfo->set_layer_stack(getLayerStack());
     layerInfo->set_z(state.z);
 
     PositionProto* position = layerInfo->mutable_position();
@@ -2133,7 +2029,7 @@
     size->set_h(state.active_legacy.h);
 
     LayerProtoHelper::writeToProto(state.crop_legacy, layerInfo->mutable_crop());
-    layerInfo->set_corner_radius(getRoundedCornerStateLocked().radius);
+    layerInfo->set_corner_radius(getRoundedCornerState().radius);
 
     layerInfo->set_is_opaque(isOpaque(state));
     layerInfo->set_invalidate(contentDirty);
@@ -2174,7 +2070,7 @@
     layerInfo->set_curr_frame(mCurrentFrameNumber);
     layerInfo->set_effective_scaling_mode(getEffectiveScalingMode());
 
-    for (const auto& pendingState : mState.pending) {
+    for (const auto& pendingState : mPendingStates) {
         auto barrierLayer = pendingState.barrierLayer_legacy.promote();
         if (barrierLayer != nullptr) {
             BarrierLayerProto* barrierLayerProto = layerInfo->add_barrier_layer();
@@ -2218,25 +2114,19 @@
 }
 
 InputWindowInfo Layer::fillInputInfo(const Rect& screenBounds) {
-    InputWindowInfo info;
-    ui::Transform t;
-    Rect layerBounds;
-    {
-        Mutex::Autolock lock(mStateMutex);
-        info = mState.drawing.inputInfo;
-        t = getTransformLocked();
-        const float xScale = t.sx();
-        const float yScale = t.sy();
-        if (xScale != 1.0f || yScale != 1.0f) {
-            info.windowXScale *= 1.0f / xScale;
-            info.windowYScale *= 1.0f / yScale;
-            info.touchableRegion.scaleSelf(xScale, yScale);
-        }
+    InputWindowInfo info = mDrawingState.inputInfo;
 
-        // Transform layer size to screen space and inset it by surface insets.
-        layerBounds = getCroppedBufferSize(getDrawingState());
+    ui::Transform t = getTransform();
+    const float xScale = t.sx();
+    const float yScale = t.sy();
+    if (xScale != 1.0f || yScale != 1.0f) {
+        info.windowXScale *= 1.0f / xScale;
+        info.windowYScale *= 1.0f / yScale;
+        info.touchableRegion.scaleSelf(xScale, yScale);
     }
 
+    // Transform layer size to screen space and inset it by surface insets.
+    Rect layerBounds = getCroppedBufferSize(getDrawingState());
     layerBounds = t.transform(layerBounds);
     layerBounds.inset(info.surfaceInset, info.surfaceInset, info.surfaceInset, info.surfaceInset);
 
@@ -2259,8 +2149,7 @@
 }
 
 bool Layer::hasInput() const {
-    Mutex::Autolock lock(mStateMutex);
-    return mState.drawing.inputInfo.token != nullptr;
+    return mDrawingState.inputInfo.token != nullptr;
 }
 
 // ---------------------------------------------------------------------------
diff --git a/services/surfaceflinger/Layer.h b/services/surfaceflinger/Layer.h
index fb75e4c..2e75088 100644
--- a/services/surfaceflinger/Layer.h
+++ b/services/surfaceflinger/Layer.h
@@ -55,7 +55,6 @@
 #include "RenderArea.h"
 
 using namespace android::surfaceflinger;
-using StateSet = android::LayerVector::StateSet;
 
 namespace android {
 
@@ -240,7 +239,7 @@
     // also the rendered size of the layer prior to any transformations. Parent
     // or local matrix transformations will not affect the size of the buffer,
     // but may affect it's on-screen size or clipping.
-    virtual bool setSize(uint32_t w, uint32_t h) EXCLUDES(mStateMutex);
+    virtual bool setSize(uint32_t w, uint32_t h);
     // Set a 2x2 transformation matrix on the layer. This transform
     // will be applied after parent transforms, but before any final
     // producer specified transform.
@@ -255,76 +254,58 @@
 
     // setPosition operates in parent buffer space (pre parent-transform) or display
     // space for top-level layers.
-    virtual bool setPosition(float x, float y, bool immediate) EXCLUDES(mStateMutex);
+    virtual bool setPosition(float x, float y, bool immediate);
     // Buffer space
-    virtual bool setCrop_legacy(const Rect& crop, bool immediate) EXCLUDES(mStateMutex);
+    virtual bool setCrop_legacy(const Rect& crop, bool immediate);
 
     // TODO(b/38182121): Could we eliminate the various latching modes by
     // using the layer hierarchy?
     // -----------------------------------------------------------------------
-    virtual bool setLayer(int32_t z) EXCLUDES(mStateMutex);
-    virtual bool setRelativeLayer(const sp<IBinder>& relativeToHandle, int32_t relativeZ)
-            EXCLUDES(mStateMutex);
+    virtual bool setLayer(int32_t z);
+    virtual bool setRelativeLayer(const sp<IBinder>& relativeToHandle, int32_t relativeZ);
 
-    virtual bool setAlpha(float alpha) EXCLUDES(mStateMutex);
-    virtual bool setColor(const half3& color) EXCLUDES(mStateMutex);
+    virtual bool setAlpha(float alpha);
+    virtual bool setColor(const half3& color);
 
     // Set rounded corner radius for this layer and its children.
     //
     // We only support 1 radius per layer in the hierarchy, where parent layers have precedence.
     // The shape of the rounded corner rectangle is specified by the crop rectangle of the layer
     // from which we inferred the rounded corner radius.
-    virtual bool setCornerRadius(float cornerRadius) EXCLUDES(mStateMutex);
-    virtual bool setTransparentRegionHint(const Region& transparent) EXCLUDES(mStateMutex);
-    virtual bool setFlags(uint8_t flags, uint8_t mask) EXCLUDES(mStateMutex);
-    virtual bool setLayerStack(uint32_t layerStack) EXCLUDES(mStateMutex);
-    virtual uint32_t getLayerStack() const EXCLUDES(mStateMutex);
+    virtual bool setCornerRadius(float cornerRadius);
+    virtual bool setTransparentRegionHint(const Region& transparent);
+    virtual bool setFlags(uint8_t flags, uint8_t mask);
+    virtual bool setLayerStack(uint32_t layerStack);
+    virtual uint32_t getLayerStack() const;
     virtual void deferTransactionUntil_legacy(const sp<IBinder>& barrierHandle,
                                               uint64_t frameNumber);
-    virtual void deferTransactionUntil_legacy(const sp<Layer>& barrierLayer, uint64_t frameNumber)
-            EXCLUDES(mStateMutex);
-    virtual bool setOverrideScalingMode(int32_t overrideScalingMode) EXCLUDES(mStateMutex);
-    virtual void setInfo(int32_t type, int32_t appId) EXCLUDES(mStateMutex);
-    virtual bool reparentChildren(const sp<IBinder>& layer) EXCLUDES(mStateMutex);
+    virtual void deferTransactionUntil_legacy(const sp<Layer>& barrierLayer, uint64_t frameNumber);
+    virtual bool setOverrideScalingMode(int32_t overrideScalingMode);
+    virtual void setInfo(int32_t type, int32_t appId);
+    virtual bool reparentChildren(const sp<IBinder>& layer);
     virtual void setChildrenDrawingParent(const sp<Layer>& layer);
-    virtual bool reparent(const sp<IBinder>& newParentHandle) EXCLUDES(mStateMutex);
+    virtual bool reparent(const sp<IBinder>& newParentHandle);
     virtual bool detachChildren();
     bool attachChildren();
     bool isLayerDetached() const { return mLayerDetached; }
-    virtual bool setColorTransform(const mat4& matrix) EXCLUDES(mStateMutex);
-    mat4 getColorTransform() const EXCLUDES(mStateMutex);
-    virtual mat4 getColorTransformLocked() const REQUIRES(mStateMutex);
-    virtual bool hasColorTransform() const EXCLUDES(mStateMutex);
-    ;
+    virtual bool setColorTransform(const mat4& matrix);
+    virtual mat4 getColorTransform() const;
+    virtual bool hasColorTransform() const;
 
     // Used only to set BufferStateLayer state
-    virtual bool setTransform(uint32_t /*transform*/) EXCLUDES(mStateMutex) { return false; };
-    virtual bool setTransformToDisplayInverse(bool /*transformToDisplayInverse*/)
-            EXCLUDES(mStateMutex) {
-        return false;
-    };
-    virtual bool setCrop(const Rect& /*crop*/) EXCLUDES(mStateMutex) { return false; };
-    virtual bool setFrame(const Rect& /*frame*/) EXCLUDES(mStateMutex) { return false; };
-    virtual bool setBuffer(const sp<GraphicBuffer>& /*buffer*/) EXCLUDES(mStateMutex) {
-        return false;
-    };
-    virtual bool setAcquireFence(const sp<Fence>& /*fence*/) EXCLUDES(mStateMutex) {
-        return false;
-    };
-    virtual bool setDataspace(ui::Dataspace /*dataspace*/) EXCLUDES(mStateMutex) { return false; };
-    virtual bool setHdrMetadata(const HdrMetadata& /*hdrMetadata*/) EXCLUDES(mStateMutex) {
-        return false;
-    };
-    virtual bool setSurfaceDamageRegion(const Region& /*surfaceDamage*/) EXCLUDES(mStateMutex) {
-        return false;
-    };
-    virtual bool setApi(int32_t /*api*/) EXCLUDES(mStateMutex) { return false; };
-    virtual bool setSidebandStream(const sp<NativeHandle>& /*sidebandStream*/)
-            EXCLUDES(mStateMutex) {
-        return false;
-    };
+    virtual bool setTransform(uint32_t /*transform*/) { return false; };
+    virtual bool setTransformToDisplayInverse(bool /*transformToDisplayInverse*/) { return false; };
+    virtual bool setCrop(const Rect& /*crop*/) { return false; };
+    virtual bool setFrame(const Rect& /*frame*/) { return false; };
+    virtual bool setBuffer(const sp<GraphicBuffer>& /*buffer*/) { return false; };
+    virtual bool setAcquireFence(const sp<Fence>& /*fence*/) { return false; };
+    virtual bool setDataspace(ui::Dataspace /*dataspace*/) { return false; };
+    virtual bool setHdrMetadata(const HdrMetadata& /*hdrMetadata*/) { return false; };
+    virtual bool setSurfaceDamageRegion(const Region& /*surfaceDamage*/) { return false; };
+    virtual bool setApi(int32_t /*api*/) { return false; };
+    virtual bool setSidebandStream(const sp<NativeHandle>& /*sidebandStream*/) { return false; };
     virtual bool setTransactionCompletedListeners(
-            const std::vector<sp<CallbackHandle>>& /*handles*/) EXCLUDES(mStateMutex) {
+            const std::vector<sp<CallbackHandle>>& /*handles*/) {
         return false;
     };
 
@@ -343,21 +324,18 @@
     virtual void useSurfaceDamage() {}
     virtual void useEmptyDamage() {}
 
-    uint32_t getTransactionFlags() const EXCLUDES(mStateMutex);
-    uint32_t getTransactionFlags(uint32_t flags) EXCLUDES(mStateMutex);
-    uint32_t setTransactionFlags(uint32_t flags) REQUIRES(mStateMutex);
+    uint32_t getTransactionFlags() const { return mTransactionFlags; }
+    uint32_t getTransactionFlags(uint32_t flags);
+    uint32_t setTransactionFlags(uint32_t flags);
 
-    bool belongsToDisplay(uint32_t layerStack, bool isPrimaryDisplay) const EXCLUDES(mStateMutex) {
+    bool belongsToDisplay(uint32_t layerStack, bool isPrimaryDisplay) const {
         return getLayerStack() == layerStack && (!mPrimaryDisplayOnly || isPrimaryDisplay);
     }
 
     void computeGeometry(const RenderArea& renderArea, renderengine::Mesh& mesh,
-                         bool useIdentityTransform) const REQUIRES(mStateMutex);
-    FloatRect computeBounds(const Region& activeTransparentRegion) const EXCLUDES(mStateMutex);
-    FloatRect computeBoundsLocked(const Region& activeTransparentRegion) const
-            REQUIRES(mStateMutex);
-    FloatRect computeBounds() const EXCLUDES(mStateMutex);
-    FloatRect computeBoundsLocked() const REQUIRES(mStateMutex);
+                         bool useIdentityTransform) const;
+    FloatRect computeBounds(const Region& activeTransparentRegion) const;
+    FloatRect computeBounds() const;
 
     int32_t getSequence() const { return sequence; }
 
@@ -374,21 +352,16 @@
      */
     virtual bool isOpaque(const Layer::State&) const { return false; }
 
-    virtual bool isDrawingOpaque() const EXCLUDES(mStateMutex) {
-        Mutex::Autolock lock(mStateMutex);
-        return isOpaque(mState.drawing);
-    }
-
     /*
      * isSecure - true if this surface is secure, that is if it prevents
      * screenshots or VNC servers.
      */
-    bool isSecure() const EXCLUDES(mStateMutex);
+    bool isSecure() const;
 
     /*
      * isVisible - true if this layer is visible, false otherwise
      */
-    virtual bool isVisible() const EXCLUDES(mStateMutex) = 0;
+    virtual bool isVisible() const = 0;
 
     /*
      * isHiddenByPolicy - true if this layer has been forced invisible.
@@ -396,7 +369,7 @@
      * For example if this layer has no active buffer, it may not be hidden by
      * policy, but it still can not be visible.
      */
-    bool isHiddenByPolicy() const EXCLUDES(mStateMutex);
+    bool isHiddenByPolicy() const;
 
     /*
      * isProtected - true if the layer may contain protected content in the
@@ -417,8 +390,7 @@
     bool isRemovedFromCurrentState() const;
 
     void writeToProto(LayerProto* layerInfo,
-                      LayerVector::StateSet stateSet = LayerVector::StateSet::Drawing)
-            EXCLUDES(mStateMutex);
+                      LayerVector::StateSet stateSet = LayerVector::StateSet::Drawing);
 
     void writeToProto(LayerProto* layerInfo, DisplayId displayId);
 
@@ -431,32 +403,25 @@
     virtual Region getActiveTransparentRegion(const Layer::State& s) const {
         return s.activeTransparentRegion_legacy;
     }
-
-    virtual Region getDrawingActiveTransparentRegion() const EXCLUDES(mStateMutex) {
-        Mutex::Autolock lock(mStateMutex);
-        return getActiveTransparentRegion(mState.drawing);
-    }
-
     virtual Rect getCrop(const Layer::State& s) const { return s.crop_legacy; }
 
 protected:
     /*
      * onDraw - draws the surface.
      */
-    virtual void onDraw(const RenderArea& renderArea, const Region& clip, bool useIdentityTransform)
-            EXCLUDES(mStateMutex) = 0;
+    virtual void onDraw(const RenderArea& renderArea, const Region& clip,
+                        bool useIdentityTransform) = 0;
 
 public:
     virtual void setDefaultBufferSize(uint32_t /*w*/, uint32_t /*h*/) {}
 
     virtual bool isHdrY410() const { return false; }
 
-    void setGeometry(const sp<const DisplayDevice>& display, uint32_t z) EXCLUDES(mStateMutex);
+    void setGeometry(const sp<const DisplayDevice>& display, uint32_t z);
     void forceClientComposition(DisplayId displayId);
     bool getForceClientComposition(DisplayId displayId);
     virtual void setPerFrameData(DisplayId displayId, const ui::Transform& transform,
-                                 const Rect& viewport, int32_t supportedPerFrameMetadata)
-            EXCLUDES(mStateMutex) = 0;
+                                 const Rect& viewport, int32_t supportedPerFrameMetadata) = 0;
 
     // callIntoHwc exists so we can update our local state and call
     // acceptDisplayChanges without unnecessarily updating the device's state
@@ -464,7 +429,7 @@
     HWC2::Composition getCompositionType(const std::optional<DisplayId>& displayId) const;
     void setClearClientTarget(DisplayId displayId, bool clear);
     bool getClearClientTarget(DisplayId displayId) const;
-    void updateCursorPosition(const sp<const DisplayDevice>& display) EXCLUDES(mStateMutex);
+    void updateCursorPosition(const sp<const DisplayDevice>& display);
 
     /*
      * called after page-flip
@@ -487,8 +452,7 @@
     virtual bool onPostComposition(const std::optional<DisplayId>& /*displayId*/,
                                    const std::shared_ptr<FenceTime>& /*glDoneFence*/,
                                    const std::shared_ptr<FenceTime>& /*presentFence*/,
-                                   const CompositorTiming& /*compositorTiming*/)
-            EXCLUDES(mStateMutex) {
+                                   const CompositorTiming& /*compositorTiming*/) {
         return false;
     }
 
@@ -500,14 +464,14 @@
      * draw - performs some global clipping optimizations
      * and calls onDraw().
      */
-    void draw(const RenderArea& renderArea, const Region& clip) EXCLUDES(mStateMutex);
-    void draw(const RenderArea& renderArea, bool useIdentityTransform) EXCLUDES(mStateMutex);
+    void draw(const RenderArea& renderArea, const Region& clip);
+    void draw(const RenderArea& renderArea, bool useIdentityTransform);
 
     /*
      * doTransaction - process the transaction. This is a good place to figure
      * out which attributes of the surface have changed.
      */
-    uint32_t doTransaction(uint32_t transactionFlags) EXCLUDES(mStateMutex);
+    uint32_t doTransaction(uint32_t transactionFlags);
 
     /*
      * setVisibleRegion - called to set the new visible region. This gives
@@ -540,17 +504,17 @@
      * to figure out if the content or size of a surface has changed.
      */
     virtual Region latchBuffer(bool& /*recomputeVisibleRegions*/, nsecs_t /*latchTime*/,
-                               const sp<Fence>& /*releaseFence*/) EXCLUDES(mStateMutex) {
+                               const sp<Fence>& /*releaseFence*/) {
         return {};
     }
 
     virtual bool isBufferLatched() const { return false; }
 
     /*
-     * called with SurfaceFlinger mStateLock a binder thread when the layer is
+     * called with the state lock from a binder thread when the layer is
      * removed from the current list to the pending removal list
      */
-    void onRemovedFromCurrentState() EXCLUDES(mStateMutex);
+    void onRemovedFromCurrentState();
 
     /*
      * Called when the layer is added back to the current state list.
@@ -570,7 +534,7 @@
     /*
      * Returns if a frame is ready
      */
-    virtual bool hasReadyFrame() const EXCLUDES(mStateMutex) { return false; }
+    virtual bool hasReadyFrame() const { return false; }
 
     virtual int32_t getQueuedFrameCount() const { return 0; }
 
@@ -599,32 +563,17 @@
     }
 
     // -----------------------------------------------------------------------
-    void clearWithOpenGL(const RenderArea& renderArea) const EXCLUDES(mStateMutex);
+    void clearWithOpenGL(const RenderArea& renderArea) const;
 
-    inline const State& getDrawingState() const REQUIRES(mStateMutex) { return mState.drawing; }
+    inline const State& getDrawingState() const { return mDrawingState; }
+    inline const State& getCurrentState() const { return mCurrentState; }
+    inline State& getCurrentState() { return mCurrentState; }
 
-    inline const State& getCurrentState() const REQUIRES(mStateMutex) { return mState.current; }
-
-    inline State& getCurrentState() REQUIRES(mStateMutex) { return mState.current; }
-
-    std::tuple<uint32_t, int32_t> getLayerStackAndZ(StateSet stateSet) EXCLUDES(mStateMutex);
-    wp<Layer> getZOrderRelativeOf(StateSet stateSet) EXCLUDES(mStateMutex) {
-        Mutex::Autolock lock(mStateMutex);
-        const State& state = (stateSet == StateSet::Current) ? mState.current : mState.drawing;
-
-        return state.zOrderRelativeOf;
-    }
-
-    uint8_t getCurrentFlags() EXCLUDES(mStateMutex) {
-        Mutex::Autolock lock(mStateMutex);
-        return mState.current.flags;
-    }
-
-    LayerDebugInfo getLayerDebugInfo() const EXCLUDES(mStateMutex);
+    LayerDebugInfo getLayerDebugInfo() const;
 
     /* always call base class first */
     static void miniDumpHeader(std::string& result);
-    void miniDump(std::string& result, DisplayId displayId) const EXCLUDES(mStateMutex);
+    void miniDump(std::string& result, DisplayId displayId) const;
     void dumpFrameStats(std::string& result) const;
     void dumpFrameEvents(std::string& result);
     void clearFrameStats();
@@ -639,29 +588,22 @@
     void addAndGetFrameTimestamps(const NewFrameEventsEntry* newEntry,
                                   FrameEventHistoryDelta* outDelta);
 
-    bool getTransformToDisplayInverse() const EXCLUDES(mStateMutex) {
-        Mutex::Autolock lock(mStateMutex);
-        return getTransformToDisplayInverseLocked();
-    }
+    virtual bool getTransformToDisplayInverse() const { return false; }
 
-    virtual bool getTransformToDisplayInverseLocked() const REQUIRES(mStateMutex) { return false; }
-
-    ui::Transform getTransform() const EXCLUDES(mStateMutex);
-    ui::Transform getTransformLocked() const REQUIRES(mStateMutex);
+    ui::Transform getTransform() const;
 
     // Returns the Alpha of the Surface, accounting for the Alpha
     // of parent Surfaces in the hierarchy (alpha's will be multiplied
     // down the hierarchy).
-    half getAlpha() const EXCLUDES(mStateMutex);
-    half4 getColor() const REQUIRES(mStateMutex);
+    half getAlpha() const;
+    half4 getColor() const;
 
     // Returns how rounded corners should be drawn for this layer.
     // This will traverse the hierarchy until it reaches its root, finding topmost rounded
     // corner definition and converting it into current layer's coordinates.
     // As of now, only 1 corner radius per display list is supported. Subsequent ones will be
     // ignored.
-    RoundedCornerState getRoundedCornerState() const EXCLUDES(mStateMutex);
-    RoundedCornerState getRoundedCornerStateLocked() const REQUIRES(mStateMutex);
+    RoundedCornerState getRoundedCornerState() const;
 
     void traverseInReverseZOrder(LayerVector::StateSet stateSet,
                                  const LayerVector::Visitor& visitor);
@@ -681,7 +623,7 @@
     ssize_t removeChild(const sp<Layer>& layer);
     sp<Layer> getParent() const { return mCurrentParent.promote(); }
     bool hasParent() const { return getParent() != nullptr; }
-    Rect computeScreenBounds(bool reduceTransparentRegion = true) const EXCLUDES(mStateMutex);
+    Rect computeScreenBounds(bool reduceTransparentRegion = true) const;
     bool setChildLayer(const sp<Layer>& childLayer, int32_t z);
     bool setChildRelativeLayer(const sp<Layer>& childLayer,
             const sp<IBinder>& relativeToHandle, int32_t relativeZ);
@@ -689,23 +631,14 @@
     // Copy the current list of children to the drawing state. Called by
     // SurfaceFlinger to complete a transaction.
     void commitChildList();
-    int32_t getZ() const EXCLUDES(mStateMutex);
-    void pushPendingState() EXCLUDES(mStateMutex);
-    virtual void pushPendingStateLocked() REQUIRES(mStateMutex);
+    int32_t getZ() const;
+    virtual void pushPendingState();
 
     /**
      * Returns active buffer size in the correct orientation. Buffer size is determined by undoing
      * any buffer transformations. If the layer has no buffer then return INVALID_RECT.
      */
-    virtual Rect getBufferSize(const Layer::State&) const REQUIRES(mStateMutex) {
-        return Rect::INVALID_RECT;
-    }
-
-    virtual Rect getBufferSize(StateSet stateSet) const EXCLUDES(mStateMutex) {
-        Mutex::Autolock lock(mStateMutex);
-        const State& state = (stateSet == StateSet::Current) ? mState.current : mState.drawing;
-        return getBufferSize(state);
-    }
+    virtual Rect getBufferSize(const Layer::State&) const { return Rect::INVALID_RECT; }
 
 protected:
     // constant
@@ -734,17 +667,16 @@
     // For unit tests
     friend class TestableSurfaceFlinger;
 
-    void commitTransaction(const State& stateToCommit) REQUIRES(mStateMutex);
+    void commitTransaction(const State& stateToCommit);
 
     uint32_t getEffectiveUsage(uint32_t usage) const;
 
-    virtual FloatRect computeCrop(const sp<const DisplayDevice>& display) const
-            REQUIRES(mStateMutex);
+    virtual FloatRect computeCrop(const sp<const DisplayDevice>& display) const;
     // Compute the initial crop as specified by parent layers and the
     // SurfaceControl for this layer. Does not include buffer crop from the
     // IGraphicBufferProducer client, as that should not affect child clipping.
     // Returns in screen space.
-    Rect computeInitialCrop(const sp<const DisplayDevice>& display) const REQUIRES(mStateMutex);
+    Rect computeInitialCrop(const sp<const DisplayDevice>& display) const;
     /**
      * Setup rounded corners coordinates of this layer, taking into account the layer bounds and
      * crop coordinates, transforming them into layer space.
@@ -752,13 +684,13 @@
     void setupRoundedCornersCropCoordinates(Rect win, const FloatRect& roundedCornersCrop) const;
 
     // drawing
-    void clearWithOpenGL(const RenderArea& renderArea, float r, float g, float b, float alpha) const
-            EXCLUDES(mStateMutex);
+    void clearWithOpenGL(const RenderArea& renderArea, float r, float g, float b,
+                         float alpha) const;
     void setParent(const sp<Layer>& layer);
 
     LayerVector makeTraversalList(LayerVector::StateSet stateSet, bool* outSkipRelativeZUsers);
-    void addZOrderRelative(const wp<Layer>& relative) EXCLUDES(mStateMutex);
-    void removeZOrderRelative(const wp<Layer>& relative) EXCLUDES(mStateMutex);
+    void addZOrderRelative(const wp<Layer>& relative);
+    void removeZOrderRelative(const wp<Layer>& relative);
 
     class SyncPoint {
     public:
@@ -794,10 +726,9 @@
     // Returns false if the relevant frame has already been latched
     bool addSyncPoint(const std::shared_ptr<SyncPoint>& point);
 
-    void popPendingState(State* stateToCommit) REQUIRES(mStateMutex);
-    virtual bool applyPendingStates(State* stateToCommit) REQUIRES(mStateMutex);
-    virtual uint32_t doTransactionResize(uint32_t flags, Layer::State* stateToCommit)
-            REQUIRES(mStateMutex);
+    void popPendingState(State* stateToCommit);
+    virtual bool applyPendingStates(State* stateToCommit);
+    virtual uint32_t doTransactionResize(uint32_t flags, Layer::State* stateToCommit);
 
     void clearSyncPoints();
 
@@ -830,15 +761,14 @@
     bool getPremultipledAlpha() const;
 
     bool mPendingHWCDestroy{false};
-    void setInputInfo(const InputWindowInfo& info) EXCLUDES(mStateMutex);
+    void setInputInfo(const InputWindowInfo& info);
 
-    InputWindowInfo fillInputInfo(const Rect& screenBounds) EXCLUDES(mStateMutex);
-    bool hasInput() const EXCLUDES(mStateMutex);
+    InputWindowInfo fillInputInfo(const Rect& screenBounds);
+    bool hasInput() const;
 
 protected:
     // -----------------------------------------------------------------------
-    bool usingRelativeZ(LayerVector::StateSet stateSet) EXCLUDES(mStateMutex);
-    bool usingRelativeZLocked(LayerVector::StateSet stateSet) REQUIRES(mStateMutex);
+    bool usingRelativeZ(LayerVector::StateSet stateSet);
 
     bool mPremultipliedAlpha{true};
     String8 mName;
@@ -846,14 +776,14 @@
 
     bool mPrimaryDisplayOnly = false;
 
+    // these are protected by an external lock
+    State mCurrentState;
+    State mDrawingState;
+    std::atomic<uint32_t> mTransactionFlags{0};
+
     // Accessed from main thread and binder threads
-    mutable Mutex mStateMutex;
-    struct {
-        State current;
-        State drawing;
-        uint32_t transactionFlags{0};
-        Vector<State> pending;
-    } mState GUARDED_BY(mStateMutex);
+    Mutex mPendingStateMutex;
+    Vector<State> mPendingStates;
 
     // Timestamp history for UIAutomation. Thread safe.
     FrameTracker mFrameTracker;
@@ -926,7 +856,7 @@
      * The cropped bounds must be transformed back from parent layer space to child layer space by
      * applying the inverse of the child's transformation.
      */
-    FloatRect cropChildBounds(const FloatRect& childBounds) const REQUIRES(mStateMutex);
+    FloatRect cropChildBounds(const FloatRect& childBounds) const;
 
     /**
      * Returns the cropped buffer size or the layer crop if the layer has no buffer. Return
@@ -934,12 +864,7 @@
      * A layer with an invalid buffer size and no crop is considered to be boundless. The layer
      * bounds are constrained by its parent bounds.
      */
-    Rect getCroppedBufferSize(const Layer::State& s) const REQUIRES(mStateMutex);
-
-    // locked version of public methods
-    bool isSecureLocked() const REQUIRES(mStateMutex);
-    virtual uint32_t getLayerStackLocked() const REQUIRES(mStateMutex);
-    half getAlphaLocked() const REQUIRES(mStateMutex);
+    Rect getCroppedBufferSize(const Layer::State& s) const;
 };
 
 } // namespace android
diff --git a/services/surfaceflinger/LayerVector.cpp b/services/surfaceflinger/LayerVector.cpp
index a7db23e..8494524 100644
--- a/services/surfaceflinger/LayerVector.cpp
+++ b/services/surfaceflinger/LayerVector.cpp
@@ -38,12 +38,18 @@
     const auto& l = *reinterpret_cast<const sp<Layer>*>(lhs);
     const auto& r = *reinterpret_cast<const sp<Layer>*>(rhs);
 
-    const auto& [ls, lz] = l->getLayerStackAndZ(mStateSet);
-    const auto& [rs, rz] = r->getLayerStackAndZ(mStateSet);
+    const auto& lState =
+            (mStateSet == StateSet::Current) ? l->getCurrentState() : l->getDrawingState();
+    const auto& rState =
+            (mStateSet == StateSet::Current) ? r->getCurrentState() : r->getDrawingState();
 
+    uint32_t ls = lState.layerStack;
+    uint32_t rs = rState.layerStack;
     if (ls != rs)
         return (ls > rs) ? 1 : -1;
 
+    int32_t lz = lState.z;
+    int32_t rz = rState.z;
     if (lz != rz)
         return (lz > rz) ? 1 : -1;
 
@@ -56,8 +62,9 @@
 void LayerVector::traverseInZOrder(StateSet stateSet, const Visitor& visitor) const {
     for (size_t i = 0; i < size(); i++) {
         const auto& layer = (*this)[i];
-        auto zOrderRelativeOf = layer->getZOrderRelativeOf(stateSet);
-        if (zOrderRelativeOf != nullptr) {
+        auto& state = (stateSet == StateSet::Current) ? layer->getCurrentState()
+                                                      : layer->getDrawingState();
+        if (state.zOrderRelativeOf != nullptr) {
             continue;
         }
         layer->traverseInZOrder(stateSet, visitor);
@@ -67,8 +74,9 @@
 void LayerVector::traverseInReverseZOrder(StateSet stateSet, const Visitor& visitor) const {
     for (auto i = static_cast<int64_t>(size()) - 1; i >= 0; i--) {
         const auto& layer = (*this)[i];
-        auto zOrderRelativeOf = layer->getZOrderRelativeOf(stateSet);
-        if (zOrderRelativeOf != nullptr) {
+        auto& state = (stateSet == StateSet::Current) ? layer->getCurrentState()
+                                                      : layer->getDrawingState();
+        if (state.zOrderRelativeOf != nullptr) {
             continue;
         }
         layer->traverseInReverseZOrder(stateSet, visitor);
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index 13997be..069dcc0 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -35,32 +35,29 @@
 #include <binder/IServiceManager.h>
 #include <binder/PermissionCache.h>
 
+#include <compositionengine/CompositionEngine.h>
 #include <dvr/vr_flinger.h>
-
-#include <input/IInputFlinger.h>
-
-#include <ui/ColorSpace.h>
-#include <ui/DebugUtils.h>
-#include <ui/DisplayInfo.h>
-#include <ui/DisplayStatInfo.h>
-
 #include <gui/BufferQueue.h>
 #include <gui/GuiConfig.h>
 #include <gui/IDisplayEventConnection.h>
 #include <gui/IProducerListener.h>
 #include <gui/LayerDebugInfo.h>
 #include <gui/Surface.h>
+#include <input/IInputFlinger.h>
 #include <renderengine/RenderEngine.h>
+#include <ui/ColorSpace.h>
+#include <ui/DebugUtils.h>
+#include <ui/DisplayInfo.h>
+#include <ui/DisplayStatInfo.h>
 #include <ui/GraphicBufferAllocator.h>
 #include <ui/PixelFormat.h>
 #include <ui/UiConfig.h>
-
-#include <utils/misc.h>
-#include <utils/String8.h>
-#include <utils/String16.h>
 #include <utils/StopWatch.h>
+#include <utils/String16.h>
+#include <utils/String8.h>
 #include <utils/Timers.h>
 #include <utils/Trace.h>
+#include <utils/misc.h>
 
 #include <private/android_filesystem_config.h>
 #include <private/gui/SyncFeatures.h>
@@ -238,7 +235,6 @@
 
 SurfaceFlingerBE::SurfaceFlingerBE()
       : mHwcServiceName(getHwcServiceName()),
-        mRenderEngine(nullptr),
         mFrameBuckets(),
         mTotalTime(0),
         mLastSwapTime(0),
@@ -272,7 +268,8 @@
         mHasPoweredOff(false),
         mNumLayers(0),
         mVrFlingerRequestsDisplay(false),
-        mMainThreadId(std::this_thread::get_id()) {}
+        mMainThreadId(std::this_thread::get_id()),
+        mCompositionEngine{getFactory().createCompositionEngine()} {}
 
 SurfaceFlinger::SurfaceFlinger(surfaceflinger::Factory& factory)
       : SurfaceFlinger(factory, SkipInitialization) {
@@ -531,6 +528,18 @@
     return NO_ERROR;
 }
 
+HWComposer& SurfaceFlinger::getHwComposer() const {
+    return mCompositionEngine->getHwComposer();
+}
+
+renderengine::RenderEngine& SurfaceFlinger::getRenderEngine() const {
+    return mCompositionEngine->getRenderEngine();
+}
+
+compositionengine::CompositionEngine& SurfaceFlinger::getCompositionEngine() const {
+    return *mCompositionEngine.get();
+}
+
 void SurfaceFlinger::bootFinished()
 {
     if (mStartPropertySetThread->join() != NO_ERROR) {
@@ -660,15 +669,14 @@
                             renderengine::RenderEngine::USE_HIGH_PRIORITY_CONTEXT : 0);
 
     // TODO(b/77156734): We need to stop casting and use HAL types when possible.
-    getBE().mRenderEngine =
+    mCompositionEngine->setRenderEngine(
             renderengine::RenderEngine::create(static_cast<int32_t>(defaultCompositionPixelFormat),
-                                               renderEngineFeature);
-    LOG_ALWAYS_FATAL_IF(getBE().mRenderEngine == nullptr, "couldn't create RenderEngine");
+                                               renderEngineFeature));
 
     LOG_ALWAYS_FATAL_IF(mVrFlingerRequestsDisplay,
             "Starting with vr flinger active is not currently supported.");
-    getBE().mHwc = getFactory().createHWComposer(getBE().mHwcServiceName);
-    getBE().mHwc->registerCallback(this, getBE().mComposerSequenceId);
+    mCompositionEngine->setHwComposer(getFactory().createHWComposer(getBE().mHwcServiceName));
+    mCompositionEngine->getHwComposer().registerCallback(this, getBE().mComposerSequenceId);
     // Process any initial hotplug and resulting display changes.
     processDisplayHotplugEventsLocked();
     const auto display = getDefaultDisplayDeviceLocked();
@@ -709,7 +717,7 @@
     // set initial conditions (e.g. unblank default device)
     initializeDisplays();
 
-    getBE().mRenderEngine->primeCache();
+    getRenderEngine().primeCache();
 
     // Inform native graphics APIs whether the present timestamp is supported:
 
@@ -749,11 +757,11 @@
 }
 
 size_t SurfaceFlinger::getMaxTextureSize() const {
-    return getBE().mRenderEngine->getMaxTextureSize();
+    return getRenderEngine().getMaxTextureSize();
 }
 
 size_t SurfaceFlinger::getMaxViewportDims() const {
-    return getBE().mRenderEngine->getMaxViewportDims();
+    return getRenderEngine().getMaxViewportDims();
 }
 
 // ----------------------------------------------------------------------------
@@ -1436,11 +1444,11 @@
     if (!mVrFlinger)
         return;
     bool vrFlingerRequestsDisplay = mVrFlingerRequestsDisplay;
-    if (vrFlingerRequestsDisplay == getBE().mHwc->isUsingVrComposer()) {
+    if (vrFlingerRequestsDisplay == getHwComposer().isUsingVrComposer()) {
         return;
     }
 
-    if (vrFlingerRequestsDisplay && !getBE().mHwc->getComposer()->isRemote()) {
+    if (vrFlingerRequestsDisplay && !getHwComposer().getComposer()->isRemote()) {
         ALOGE("Vr flinger is only supported for remote hardware composer"
               " service connections. Ignoring request to transition to vr"
               " flinger.");
@@ -1463,12 +1471,13 @@
     }
 
     resetDisplayState();
-    getBE().mHwc.reset(); // Delete the current instance before creating the new one
-    getBE().mHwc = getFactory().createHWComposer(
-            vrFlingerRequestsDisplay ? "vr" : getBE().mHwcServiceName);
-    getBE().mHwc->registerCallback(this, ++getBE().mComposerSequenceId);
+    // Delete the current instance before creating the new one
+    mCompositionEngine->setHwComposer(std::unique_ptr<HWComposer>());
+    mCompositionEngine->setHwComposer(getFactory().createHWComposer(
+            vrFlingerRequestsDisplay ? "vr" : getBE().mHwcServiceName));
+    getHwComposer().registerCallback(this, ++getBE().mComposerSequenceId);
 
-    LOG_ALWAYS_FATAL_IF(!getBE().mHwc->getComposer()->isRemote(),
+    LOG_ALWAYS_FATAL_IF(!getHwComposer().getComposer()->isRemote(),
                         "Switched to non-remote hardware composer");
 
     if (vrFlingerRequestsDisplay) {
@@ -1491,9 +1500,10 @@
     // The present fences returned from vr_hwc are not an accurate
     // representation of vsync times.
     if (mUseScheduler) {
-        mScheduler->setIgnorePresentFences(getBE().mHwc->isUsingVrComposer() || !hasSyncFramework);
+        mScheduler->setIgnorePresentFences(getHwComposer().isUsingVrComposer() ||
+                                           !hasSyncFramework);
     } else {
-        mPrimaryDispSync->setIgnorePresentFences(getBE().mHwc->isUsingVrComposer() ||
+        mPrimaryDispSync->setIgnorePresentFences(getHwComposer().isUsingVrComposer() ||
                                                  !hasSyncFramework);
     }
 
@@ -1598,12 +1608,12 @@
 
     mHadClientComposition = false;
     for (const auto& [token, display] : mDisplays) {
-        mHadClientComposition = mHadClientComposition ||
-                getBE().mHwc->hasClientComposition(display->getId());
+        mHadClientComposition =
+                mHadClientComposition || getHwComposer().hasClientComposition(display->getId());
     }
 
     // Setup RenderEngine sync fences if native sync is supported.
-    if (getBE().mRenderEngine->useNativeFenceSync()) {
+    if (getRenderEngine().useNativeFenceSync()) {
         if (mHadClientComposition) {
             base::unique_fd flushFence(getRenderEngine().flush());
             ALOGE_IF(flushFence < 0, "Failed to flush RenderEngine!");
@@ -2272,7 +2282,7 @@
         // supply them with the present fence.
         if (!display->getLayersNeedingFences().isEmpty()) {
             sp<Fence> presentFence =
-                    displayId ? getBE().mHwc->getPresentFence(*displayId) : Fence::NO_FENCE;
+                    displayId ? getHwComposer().getPresentFence(*displayId) : Fence::NO_FENCE;
             for (auto& layer : display->getLayersNeedingFences()) {
                 layer->getBE().onLayerDisplayed(presentFence);
             }
@@ -2738,6 +2748,7 @@
     if (inputChanged || mVisibleRegionsDirty) {
         updateInputWindows();
     }
+    executeInputWindowCommands();
 
     updateCursorAsync();
 }
@@ -2762,6 +2773,23 @@
     mInputFlinger->setInputWindows(inputHandles);
 }
 
+void SurfaceFlinger::executeInputWindowCommands() {
+    if (!mInputFlinger) {
+        return;
+    }
+
+    for (const auto& transferTouchFocusCommand : mInputWindowCommands.transferTouchFocusCommands) {
+        if (transferTouchFocusCommand.fromToken != nullptr &&
+            transferTouchFocusCommand.toToken != nullptr &&
+            transferTouchFocusCommand.fromToken != transferTouchFocusCommand.toToken) {
+            mInputFlinger->transferTouchFocus(transferTouchFocusCommand.fromToken,
+                                              transferTouchFocusCommand.toToken);
+        }
+    }
+
+    mInputWindowCommands.clear();
+}
+
 void SurfaceFlinger::updateCursorAsync()
 {
     for (const auto& [token, display] : mDisplays) {
@@ -2836,6 +2864,9 @@
     outDirtyRegion.clear();
 
     mDrawingState.traverseInReverseZOrder([&](Layer* layer) {
+        // start with the whole surface at its current location
+        const Layer::State& s(layer->getDrawingState());
+
         // only consider the layers on the given layer stack
         if (!layer->belongsToDisplay(display->getLayerStack(), display->isPrimary())) {
             return;
@@ -2873,7 +2904,7 @@
 
         // handle hidden surfaces by setting the visible region to empty
         if (CC_LIKELY(layer->isVisible())) {
-            const bool translucent = !layer->isDrawingOpaque();
+            const bool translucent = !layer->isOpaque(s);
             Rect bounds(layer->computeScreenBounds());
 
             visibleRegion.set(bounds);
@@ -2883,8 +2914,7 @@
                 if (translucent) {
                     if (tr.preserveRects()) {
                         // transform the transparent region
-                        transparentRegion =
-                                tr.transform(layer->getDrawingActiveTransparentRegion());
+                        transparentRegion = tr.transform(layer->getActiveTransparentRegion(s));
                     } else {
                         // transformation too complex, can't do the
                         // transparent region optimization.
@@ -3002,12 +3032,18 @@
         }
     });
 
-    for (auto& layer : mLayersWithQueuedFrames) {
-        const Region dirty(layer->latchBuffer(visibleRegions, latchTime, getBE().flushFence));
-        layer->useSurfaceDamage();
-        invalidateLayerStack(layer, dirty);
-        if (layer->isBufferLatched()) {
-            newDataLatched = true;
+    if (!mLayersWithQueuedFrames.empty()) {
+        // mStateLock is needed for latchBuffer as LayerRejecter::reject()
+        // writes to Layer current state. See also b/119481871
+        Mutex::Autolock lock(mStateLock);
+
+        for (auto& layer : mLayersWithQueuedFrames) {
+            const Region dirty(layer->latchBuffer(visibleRegions, latchTime, getBE().flushFence));
+            layer->useSurfaceDamage();
+            invalidateLayerStack(layer, dirty);
+            if (layer->isBufferLatched()) {
+                newDataLatched = true;
+            }
         }
     }
 
@@ -3069,7 +3105,7 @@
     const Region bounds(display->bounds());
     const DisplayRenderArea renderArea(display);
     const auto displayId = display->getId();
-    const bool hasClientComposition = getBE().mHwc->hasClientComposition(displayId);
+    const bool hasClientComposition = getHwComposer().hasClientComposition(displayId);
     ATRACE_INT("hasClientComposition", hasClientComposition);
 
     mat4 colorMatrix;
@@ -3104,15 +3140,15 @@
         if (display->hasWideColorGamut()) {
             outputDataspace = display->getCompositionDataSpace();
         }
-        getBE().mRenderEngine->setOutputDataSpace(outputDataspace);
-        getBE().mRenderEngine->setDisplayMaxLuminance(
+        getRenderEngine().setOutputDataSpace(outputDataspace);
+        getRenderEngine().setDisplayMaxLuminance(
                 display->getHdrCapabilities().getDesiredMaxLuminance());
 
-        const bool hasDeviceComposition = getBE().mHwc->hasDeviceComposition(displayId);
+        const bool hasDeviceComposition = getHwComposer().hasDeviceComposition(displayId);
         const bool skipClientColorTransform =
-                getBE().mHwc
-                        ->hasDisplayCapability(displayId,
-                                               HWC2::DisplayCapability::SkipClientColorTransform);
+                getHwComposer()
+                        .hasDisplayCapability(displayId,
+                                              HWC2::DisplayCapability::SkipClientColorTransform);
 
         // Compute the global color transform matrix.
         applyColorMatrix = !hasDeviceComposition && !skipClientColorTransform;
@@ -3129,7 +3165,7 @@
             // remove where there are opaque FB layers. however, on some
             // GPUs doing a "clean slate" clear might be more efficient.
             // We'll revisit later if needed.
-            getBE().mRenderEngine->clearWithColor(0, 0, 0, 0);
+            getRenderEngine().clearWithColor(0, 0, 0, 0);
         } else {
             // we start with the whole screen area and remove the scissor part
             // we're left with the letterbox region
@@ -3154,7 +3190,7 @@
             // the GL scissor so we don't draw anything where we shouldn't
 
             // enable scissor for this frame
-            getBE().mRenderEngine->setScissor(scissor);
+            getRenderEngine().setScissor(scissor);
         }
     }
 
@@ -3177,8 +3213,9 @@
                 case HWC2::Composition::Sideband:
                 case HWC2::Composition::SolidColor: {
                     LOG_ALWAYS_FATAL_IF(!displayId);
+                    const Layer::State& state(layer->getDrawingState());
                     if (layer->getClearClientTarget(*displayId) && !firstLayer &&
-                        layer->isDrawingOpaque() && (layer->getAlpha() == 1.0f) &&
+                        layer->isOpaque(state) && (layer->getAlpha() == 1.0f) &&
                         layer->getRoundedCornerState().radius == 0.0f && hasClientComposition) {
                         // never clear the very first layer since we're
                         // guaranteed the FB is already cleared
@@ -3212,7 +3249,7 @@
     // Perform some cleanup steps if we used client composition.
     if (hasClientComposition) {
         getRenderEngine().setColorTransform(mat4());
-        getBE().mRenderEngine->disableScissor();
+        getRenderEngine().disableScissor();
         display->finishBuffer();
         // Clear out error flags here so that we don't wait until next
         // composition to log.
@@ -4671,7 +4708,7 @@
     result.append("SurfaceFlinger global state:\n");
     colorizer.reset(result);
 
-    getBE().mRenderEngine->dump(result);
+    getRenderEngine().dump(result);
 
     if (const auto display = getDefaultDisplayDeviceLocked()) {
         display->undefinedRegion.dump(result, "undefinedRegion");
@@ -5145,7 +5182,7 @@
             // Is VrFlinger active?
             case 1028: {
                 Mutex::Autolock _l(mStateLock);
-                reply->writeBool(getBE().mHwc->isUsingVrComposer());
+                reply->writeBool(getHwComposer().isUsingVrComposer());
                 return NO_ERROR;
             }
             // Is device color managed?
@@ -5262,12 +5299,15 @@
                 mFlinger(flinger),
                 mChildrenOnly(childrenOnly) {}
         const ui::Transform& getTransform() const override { return mTransform; }
-        Rect getBounds() const override { return mLayer->getBufferSize(StateSet::Drawing); }
+        Rect getBounds() const override {
+            const Layer::State& layerState(mLayer->getDrawingState());
+            return mLayer->getBufferSize(layerState);
+        }
         int getHeight() const override {
-            return mLayer->getBufferSize(StateSet::Drawing).getHeight();
+            return mLayer->getBufferSize(mLayer->getDrawingState()).getHeight();
         }
         int getWidth() const override {
-            return mLayer->getBufferSize(StateSet::Drawing).getWidth();
+            return mLayer->getBufferSize(mLayer->getDrawingState()).getWidth();
         }
         bool isSecure() const override { return false; }
         bool needsFiltering() const override { return mNeedsFiltering; }
@@ -5334,7 +5374,7 @@
 
     const int uid = IPCThreadState::self()->getCallingUid();
     const bool forSystem = uid == AID_GRAPHICS || uid == AID_SYSTEM;
-    if (!forSystem && parent->getCurrentFlags() & layer_state_t::eLayerSecure) {
+    if (!forSystem && parent->getCurrentState().flags & layer_state_t::eLayerSecure) {
         ALOGW("Attempting to capture secure layer: PERMISSION_DENIED");
         return PERMISSION_DENIED;
     }
@@ -5342,12 +5382,12 @@
     Rect crop(sourceCrop);
     if (sourceCrop.width() <= 0) {
         crop.left = 0;
-        crop.right = parent->getBufferSize(StateSet::Current).getWidth();
+        crop.right = parent->getBufferSize(parent->getCurrentState()).getWidth();
     }
 
     if (sourceCrop.height() <= 0) {
         crop.top = 0;
-        crop.bottom = parent->getBufferSize(StateSet::Current).getHeight();
+        crop.bottom = parent->getBufferSize(parent->getCurrentState()).getHeight();
     }
 
     int32_t reqWidth = crop.width() * frameScale;
diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h
index bfc87a0..04f454c 100644
--- a/services/surfaceflinger/SurfaceFlinger.h
+++ b/services/surfaceflinger/SurfaceFlinger.h
@@ -146,32 +146,9 @@
 public:
     SurfaceFlingerBE();
 
-    // The current hardware composer interface.
-    //
-    // The following thread safety rules apply when accessing mHwc, either
-    // directly or via getHwComposer():
-    //
-    // 1. When recreating mHwc, acquire mStateLock. We currently recreate mHwc
-    //    only when switching into and out of vr. Recreating mHwc must only be
-    //    done on the main thread.
-    //
-    // 2. When accessing mHwc on the main thread, it's not necessary to acquire
-    //    mStateLock.
-    //
-    // 3. When accessing mHwc on a thread other than the main thread, we always
-    //    need to acquire mStateLock. This is because the main thread could be
-    //    in the process of destroying the current mHwc instance.
-    //
-    // The above thread safety rules only apply to SurfaceFlinger.cpp. In
-    // SurfaceFlinger_hwc1.cpp we create mHwc at surface flinger init and never
-    // destroy it, so it's always safe to access mHwc from any thread without
-    // acquiring mStateLock.
-    std::unique_ptr<HWComposer> mHwc;
-
     const std::string mHwcServiceName; // "default" for real use, something else for testing.
 
     // constant members (no synchronization needed for access)
-    std::unique_ptr<renderengine::RenderEngine> mRenderEngine;
     EGLContext mEGLContext;
     EGLDisplay mEGLDisplay;
 
@@ -336,6 +313,9 @@
 
     surfaceflinger::Factory& getFactory() { return mFactory; }
 
+    // The CompositionEngine encapsulates all composition related interfaces and actions.
+    compositionengine::CompositionEngine& getCompositionEngine() const;
+
     // returns the default Display
     sp<const DisplayDevice> getDefaultDisplayDevice() const {
         Mutex::Autolock _l(mStateLock);
@@ -362,7 +342,7 @@
     // TODO: this should be made accessible only to HWComposer
     const Vector<sp<Layer>>& getLayerSortedByZForHwcDisplay(DisplayId displayId);
 
-    renderengine::RenderEngine& getRenderEngine() const { return *getBE().mRenderEngine; }
+    renderengine::RenderEngine& getRenderEngine() const;
 
     bool authenticateSurfaceTextureLocked(
         const sp<IGraphicBufferProducer>& bufferProducer) const;
@@ -543,6 +523,7 @@
     void handleTransactionLocked(uint32_t transactionFlags);
 
     void updateInputWindows();
+    void executeInputWindowCommands();
     void updateCursorAsync();
 
     /* handlePageFlip - latch a new buffer if available and compute the dirty
@@ -699,7 +680,27 @@
      * H/W composer
      */
 
-    HWComposer& getHwComposer() const { return *getBE().mHwc; }
+    // The current hardware composer interface.
+    //
+    // The following thread safety rules apply when accessing mHwc, either
+    // directly or via getHwComposer():
+    //
+    // 1. When recreating mHwc, acquire mStateLock. We currently recreate mHwc
+    //    only when switching into and out of vr. Recreating mHwc must only be
+    //    done on the main thread.
+    //
+    // 2. When accessing mHwc on the main thread, it's not necessary to acquire
+    //    mStateLock.
+    //
+    // 3. When accessing mHwc on a thread other than the main thread, we always
+    //    need to acquire mStateLock. This is because the main thread could be
+    //    in the process of destroying the current mHwc instance.
+    //
+    // The above thread safety rules only apply to SurfaceFlinger.cpp. In
+    // SurfaceFlinger_hwc1.cpp we create mHwc at surface flinger init and never
+    // destroy it, so it's always safe to access mHwc from any thread without
+    // acquiring mStateLock.
+    HWComposer& getHwComposer() const;
 
     /* ------------------------------------------------------------------------
      * Compositing
@@ -1015,6 +1016,7 @@
     ui::Dataspace mWideColorGamutCompositionDataspace;
 
     SurfaceFlingerBE mBE;
+    std::unique_ptr<compositionengine::CompositionEngine> mCompositionEngine;
 
     bool mUseScheduler = false;
     std::unique_ptr<Scheduler> mScheduler;
diff --git a/services/surfaceflinger/SurfaceFlingerFactory.cpp b/services/surfaceflinger/SurfaceFlingerFactory.cpp
index 88649e3..77679e3 100644
--- a/services/surfaceflinger/SurfaceFlingerFactory.cpp
+++ b/services/surfaceflinger/SurfaceFlingerFactory.cpp
@@ -14,6 +14,7 @@
  * limitations under the License.
  */
 
+#include <compositionengine/impl/CompositionEngine.h>
 #include <ui/GraphicBuffer.h>
 
 #include "BufferQueueLayer.h"
@@ -59,7 +60,7 @@
         }
 
         std::unique_ptr<HWComposer> createHWComposer(const std::string& serviceName) override {
-            return std::make_unique<HWComposer>(
+            return std::make_unique<android::impl::HWComposer>(
                     std::make_unique<Hwc2::impl::Composer>(serviceName));
         }
 
@@ -102,6 +103,10 @@
             return surfaceflinger::impl::createNativeWindowSurface(producer);
         }
 
+        std::unique_ptr<compositionengine::CompositionEngine> createCompositionEngine() override {
+            return compositionengine::impl::createCompositionEngine();
+        }
+
         sp<ContainerLayer> createContainerLayer(const LayerCreationArgs& args) override {
             return new ContainerLayer(args);
         }
diff --git a/services/surfaceflinger/SurfaceFlingerFactory.h b/services/surfaceflinger/SurfaceFlingerFactory.h
index 1c27cc7..f747684 100644
--- a/services/surfaceflinger/SurfaceFlingerFactory.h
+++ b/services/surfaceflinger/SurfaceFlingerFactory.h
@@ -49,6 +49,9 @@
 struct DisplayDeviceCreationArgs;
 struct LayerCreationArgs;
 
+namespace compositionengine {
+class CompositionEngine;
+} // namespace compositionengine
 namespace surfaceflinger {
 
 class NativeWindowSurface;
@@ -78,6 +81,8 @@
     virtual std::unique_ptr<surfaceflinger::NativeWindowSurface> createNativeWindowSurface(
             const sp<IGraphicBufferProducer>&) = 0;
 
+    virtual std::unique_ptr<compositionengine::CompositionEngine> createCompositionEngine() = 0;
+
     virtual sp<BufferQueueLayer> createBufferQueueLayer(const LayerCreationArgs& args) = 0;
     virtual sp<BufferStateLayer> createBufferStateLayer(const LayerCreationArgs& args) = 0;
     virtual sp<ColorLayer> createColorLayer(const LayerCreationArgs& args) = 0;
diff --git a/services/surfaceflinger/SurfaceInterceptor.cpp b/services/surfaceflinger/SurfaceInterceptor.cpp
index a6dcb7e..7bfe033 100644
--- a/services/surfaceflinger/SurfaceInterceptor.cpp
+++ b/services/surfaceflinger/SurfaceInterceptor.cpp
@@ -101,23 +101,22 @@
     transaction->set_animation(layerFlags & BnSurfaceComposer::eAnimation);
 
     const int32_t layerId(getLayerId(layer));
-    Mutex::Autolock lock(layer->mStateMutex);
-    addPositionLocked(transaction, layerId, layer->mState.current.active_legacy.transform.tx(),
-                      layer->mState.current.active_legacy.transform.ty());
-    addDepthLocked(transaction, layerId, layer->mState.current.z);
-    addAlphaLocked(transaction, layerId, layer->mState.current.color.a);
+    addPositionLocked(transaction, layerId, layer->mCurrentState.active_legacy.transform.tx(),
+                      layer->mCurrentState.active_legacy.transform.ty());
+    addDepthLocked(transaction, layerId, layer->mCurrentState.z);
+    addAlphaLocked(transaction, layerId, layer->mCurrentState.color.a);
     addTransparentRegionLocked(transaction, layerId,
-                               layer->mState.current.activeTransparentRegion_legacy);
-    addLayerStackLocked(transaction, layerId, layer->mState.current.layerStack);
-    addCropLocked(transaction, layerId, layer->mState.current.crop_legacy);
-    addCornerRadiusLocked(transaction, layerId, layer->mState.current.cornerRadius);
-    if (layer->mState.current.barrierLayer_legacy != nullptr) {
+                               layer->mCurrentState.activeTransparentRegion_legacy);
+    addLayerStackLocked(transaction, layerId, layer->mCurrentState.layerStack);
+    addCropLocked(transaction, layerId, layer->mCurrentState.crop_legacy);
+    addCornerRadiusLocked(transaction, layerId, layer->mCurrentState.cornerRadius);
+    if (layer->mCurrentState.barrierLayer_legacy != nullptr) {
         addDeferTransactionLocked(transaction, layerId,
-                                  layer->mState.current.barrierLayer_legacy.promote(),
-                                  layer->mState.current.frameNumber_legacy);
+                                  layer->mCurrentState.barrierLayer_legacy.promote(),
+                                  layer->mCurrentState.frameNumber_legacy);
     }
     addOverrideScalingModeLocked(transaction, layerId, layer->getEffectiveScalingMode());
-    addFlagsLocked(transaction, layerId, layer->mState.current.flags);
+    addFlagsLocked(transaction, layerId, layer->mCurrentState.flags);
 }
 
 void SurfaceInterceptor::addInitialDisplayStateLocked(Increment* increment,
@@ -427,9 +426,8 @@
     SurfaceCreation* creation(increment->mutable_surface_creation());
     creation->set_id(getLayerId(layer));
     creation->set_name(getLayerName(layer));
-    Mutex::Autolock lock(layer->mStateMutex);
-    creation->set_w(layer->mState.current.active_legacy.w);
-    creation->set_h(layer->mState.current.active_legacy.h);
+    creation->set_w(layer->mCurrentState.active_legacy.w);
+    creation->set_h(layer->mCurrentState.active_legacy.h);
 }
 
 void SurfaceInterceptor::addSurfaceDeletionLocked(Increment* increment,
diff --git a/services/surfaceflinger/TEST_MAPPING b/services/surfaceflinger/TEST_MAPPING
new file mode 100644
index 0000000..cab33ae
--- /dev/null
+++ b/services/surfaceflinger/TEST_MAPPING
@@ -0,0 +1,10 @@
+{
+  "presubmit": [
+    {
+      "name": "libsurfaceflinger_unittest"
+    },
+    {
+      "name": "libcompositionengine_test"
+    }
+  ]
+}
diff --git a/services/surfaceflinger/tests/unittests/Android.bp b/services/surfaceflinger/tests/unittests/Android.bp
index 2f35ae5..f63c911 100644
--- a/services/surfaceflinger/tests/unittests/Android.bp
+++ b/services/surfaceflinger/tests/unittests/Android.bp
@@ -20,6 +20,16 @@
         // Using the address sanitizer not only helps uncover issues in the code
         // covered by the tests, but also covers some of the tricky injection of
         // fakes the unit tests currently do.
+        //
+        // Note: If you get an runtime link error like:
+        //
+        //   CANNOT LINK EXECUTABLE "/data/local/tmp/libsurfaceflinger_unittest": library "libclang_rt.asan-aarch64-android.so" not found
+        //
+        // it is because the address sanitizer shared objects are not installed
+        // by default in the system image.
+        //
+        // You can either "make dist tests" before flashing, or set this
+        // option to false temporarily.
         address: true,
     },
     srcs: [
@@ -46,11 +56,14 @@
         "mock/MockMessageQueue.cpp",
         "mock/MockNativeWindowSurface.cpp",
         "mock/MockSurfaceInterceptor.cpp",
-        "mock/RenderEngine/MockRenderEngine.cpp",
         "mock/system/window/MockNativeWindow.cpp",
     ],
     static_libs: [
         "libgmock",
+        "libcompositionengine",
+        "libcompositionengine_mocks",
+        "librenderengine_mocks",
+
     ],
     header_libs: [
         "libsurfaceflinger_headers",
diff --git a/services/surfaceflinger/tests/unittests/CompositionTest.cpp b/services/surfaceflinger/tests/unittests/CompositionTest.cpp
index b7c09ed..e417350 100644
--- a/services/surfaceflinger/tests/unittests/CompositionTest.cpp
+++ b/services/surfaceflinger/tests/unittests/CompositionTest.cpp
@@ -19,9 +19,11 @@
 
 #include <gmock/gmock.h>
 #include <gtest/gtest.h>
-
 #include <gui/IProducerListener.h>
 #include <log/log.h>
+#include <renderengine/mock/Framebuffer.h>
+#include <renderengine/mock/Image.h>
+#include <renderengine/mock/RenderEngine.h>
 #include <system/window.h>
 #include <utils/String8.h>
 
@@ -36,7 +38,6 @@
 #include "mock/MockEventControlThread.h"
 #include "mock/MockEventThread.h"
 #include "mock/MockMessageQueue.h"
-#include "mock/RenderEngine/MockRenderEngine.h"
 #include "mock/system/window/MockNativeWindow.h"
 
 namespace android {
@@ -767,7 +768,7 @@
 
         const auto displayId = test->mDisplay->getId();
         ASSERT_TRUE(displayId);
-        layer->createHwcLayer(test->mFlinger.mFlinger->getBE().mHwc.get(), *displayId);
+        layer->createHwcLayer(&test->mFlinger.getHwComposer(), *displayId);
 
         Mock::VerifyAndClear(test->mComposer);
 
diff --git a/services/surfaceflinger/tests/unittests/DisplayTransactionTest.cpp b/services/surfaceflinger/tests/unittests/DisplayTransactionTest.cpp
index bd9b140..ff84a62 100644
--- a/services/surfaceflinger/tests/unittests/DisplayTransactionTest.cpp
+++ b/services/surfaceflinger/tests/unittests/DisplayTransactionTest.cpp
@@ -21,9 +21,8 @@
 
 #include <gmock/gmock.h>
 #include <gtest/gtest.h>
-
 #include <log/log.h>
-
+#include <renderengine/mock/RenderEngine.h>
 #include <ui/DebugUtils.h>
 
 #include "DisplayIdentificationTest.h"
@@ -36,7 +35,6 @@
 #include "mock/MockMessageQueue.h"
 #include "mock/MockNativeWindowSurface.h"
 #include "mock/MockSurfaceInterceptor.h"
-#include "mock/RenderEngine/MockRenderEngine.h"
 #include "mock/gui/MockGraphicBufferConsumer.h"
 #include "mock/gui/MockGraphicBufferProducer.h"
 #include "mock/system/window/MockNativeWindow.h"
diff --git a/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h b/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h
index 4da08b8..9ff5e8d 100644
--- a/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h
+++ b/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h
@@ -16,6 +16,8 @@
 
 #pragma once
 
+#include <compositionengine/impl/CompositionEngine.h>
+
 #include "BufferQueueLayer.h"
 #include "BufferStateLayer.h"
 #include "ColorLayer.h"
@@ -113,6 +115,10 @@
         return mCreateNativeWindowSurface(producer);
     }
 
+    std::unique_ptr<compositionengine::CompositionEngine> createCompositionEngine() override {
+        return compositionengine::impl::createCompositionEngine();
+    }
+
     sp<BufferQueueLayer> createBufferQueueLayer(const LayerCreationArgs&) override {
         // TODO: Use test-fixture controlled factory
         return nullptr;
@@ -148,6 +154,10 @@
             std::function<std::unique_ptr<surfaceflinger::NativeWindowSurface>(
                     const sp<IGraphicBufferProducer>&)>;
     CreateNativeWindowSurfaceFunction mCreateNativeWindowSurface;
+
+    using CreateCompositionEngineFunction =
+            std::function<std::unique_ptr<compositionengine::CompositionEngine>()>;
+    CreateCompositionEngineFunction mCreateCompositionEngine;
 };
 
 } // namespace surfaceflinger::test
@@ -158,11 +168,12 @@
     // functions.
 
     void setupRenderEngine(std::unique_ptr<renderengine::RenderEngine> renderEngine) {
-        mFlinger->getBE().mRenderEngine = std::move(renderEngine);
+        mFlinger->mCompositionEngine->setRenderEngine(std::move(renderEngine));
     }
 
     void setupComposer(std::unique_ptr<Hwc2::Composer> composer) {
-        mFlinger->getBE().mHwc.reset(new HWComposer(std::move(composer)));
+        mFlinger->mCompositionEngine->setHwComposer(
+                std::make_unique<impl::HWComposer>(std::move(composer)));
     }
 
     using CreateBufferQueueFunction = surfaceflinger::test::Factory::CreateBufferQueueFunction;
@@ -178,12 +189,11 @@
 
     using HotplugEvent = SurfaceFlinger::HotplugEvent;
 
-    auto& mutableLayerCurrentState(sp<Layer> layer) { return layer->mState.current; }
-    auto& mutableLayerDrawingState(sp<Layer> layer) { return layer->mState.drawing; }
+    auto& mutableLayerCurrentState(sp<Layer> layer) { return layer->mCurrentState; }
+    auto& mutableLayerDrawingState(sp<Layer> layer) { return layer->mDrawingState; }
 
     void setLayerSidebandStream(sp<Layer> layer, sp<NativeHandle> sidebandStream) {
-        Mutex::Autolock lock(layer->mStateMutex);
-        layer->mState.drawing.sidebandStream = sidebandStream;
+        layer->mDrawingState.sidebandStream = sidebandStream;
         layer->getBE().compositionInfo.hwc.sidebandStream = sidebandStream;
     }
 
@@ -253,6 +263,9 @@
     const auto& getHasPoweredOff() const { return mFlinger->mHasPoweredOff; }
     const auto& getHWVsyncAvailable() const { return mFlinger->mHWVsyncAvailable; }
     const auto& getVisibleRegionsDirty() const { return mFlinger->mVisibleRegionsDirty; }
+    auto& getHwComposer() const {
+        return static_cast<impl::HWComposer&>(mFlinger->getHwComposer());
+    }
 
     const auto& getCompositorTiming() const { return mFlinger->getBE().mCompositorTiming; }
 
@@ -285,13 +298,10 @@
     auto& mutableUseHwcVirtualDisplays() { return mFlinger->mUseHwcVirtualDisplays; }
 
     auto& mutableComposerSequenceId() { return mFlinger->getBE().mComposerSequenceId; }
-    auto& mutableHwcDisplayData() { return mFlinger->getHwComposer().mDisplayData; }
-    auto& mutableHwcPhysicalDisplayIdMap() {
-        return mFlinger->getHwComposer().mPhysicalDisplayIdMap;
-    }
-
-    auto& mutableInternalHwcDisplayId() { return mFlinger->getHwComposer().mInternalHwcDisplayId; }
-    auto& mutableExternalHwcDisplayId() { return mFlinger->getHwComposer().mExternalHwcDisplayId; }
+    auto& mutableHwcDisplayData() { return getHwComposer().mDisplayData; }
+    auto& mutableHwcPhysicalDisplayIdMap() { return getHwComposer().mPhysicalDisplayIdMap; }
+    auto& mutableInternalHwcDisplayId() { return getHwComposer().mInternalHwcDisplayId; }
+    auto& mutableExternalHwcDisplayId() { return getHwComposer().mExternalHwcDisplayId; }
 
     ~TestableSurfaceFlinger() {
         // All these pointer and container clears help ensure that GMock does
@@ -304,8 +314,9 @@
         mutableEventThread().reset();
         mutableInterceptor().reset();
         mutablePrimaryDispSync().reset();
-        mFlinger->getBE().mHwc.reset();
-        mFlinger->getBE().mRenderEngine.reset();
+        mFlinger->mCompositionEngine->setHwComposer(std::unique_ptr<HWComposer>());
+        mFlinger->mCompositionEngine->setRenderEngine(
+                std::unique_ptr<renderengine::RenderEngine>());
     }
 
     /* ------------------------------------------------------------------------
diff --git a/services/vr/bufferhubd/producer_channel.cpp b/services/vr/bufferhubd/producer_channel.cpp
index 2a6e9da..409bce9 100644
--- a/services/vr/bufferhubd/producer_channel.cpp
+++ b/services/vr/bufferhubd/producer_channel.cpp
@@ -369,7 +369,9 @@
           (consumer_state_mask & BufferHubDefs::kHighBitsMask);
     }
   }
-  if (update_buffer_state) {
+  if (update_buffer_state || BufferHubDefs::IsClientPosted(
+                                 buffer_state_->load(std::memory_order_acquire),
+                                 consumer_state_mask)) {
     consumer->OnProducerPosted();
   }
 
@@ -537,8 +539,13 @@
 
   uint32_t current_buffer_state =
       buffer_state_->load(std::memory_order_acquire);
+  uint32_t current_active_clients_bit_mask =
+      active_clients_bit_mask_->load(std::memory_order_acquire);
+  // Signal producer if all current active consumers have released the buffer.
   if (BufferHubDefs::IsBufferReleased(current_buffer_state &
-                                      ~orphaned_consumer_bit_mask_)) {
+                                      ~orphaned_consumer_bit_mask_ &
+                                      current_active_clients_bit_mask)) {
+    buffer_state_->store(0U);
     SignalAvailable();
     if (orphaned_consumer_bit_mask_) {
       ALOGW(
@@ -564,8 +571,13 @@
 
   uint32_t current_buffer_state =
       buffer_state_->load(std::memory_order_acquire);
+  uint32_t current_active_clients_bit_mask =
+      active_clients_bit_mask_->load(std::memory_order_acquire);
+  // Signal producer if all current active consumers have released the buffer.
   if (BufferHubDefs::IsBufferReleased(current_buffer_state &
-                                      ~orphaned_consumer_bit_mask_)) {
+                                      ~orphaned_consumer_bit_mask_ &
+                                      current_active_clients_bit_mask)) {
+    buffer_state_->store(0U);
     SignalAvailable();
   }