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();
}