Merge "Use TWO_FINGER_SWIPE classification for touchpad scroll events"
diff --git a/cmds/bugreportz/readme.md b/cmds/bugreportz/readme.md
index eb0d898..3606827 100644
--- a/cmds/bugreportz/readme.md
+++ b/cmds/bugreportz/readme.md
@@ -1,6 +1,6 @@
# bugreportz protocol
-`bugreportz` is used to generate a zippped bugreport whose path is passed back to `adb`, using
+`bugreportz` is used to generate a zipped bugreport whose path is passed back to `adb`, using
the simple protocol defined below.
# Version 1.1
diff --git a/cmds/servicemanager/ServiceManager.cpp b/cmds/servicemanager/ServiceManager.cpp
index 3cfe529..0727383 100644
--- a/cmds/servicemanager/ServiceManager.cpp
+++ b/cmds/servicemanager/ServiceManager.cpp
@@ -762,4 +762,10 @@
return Status::ok();
}
+void ServiceManager::clear() {
+ mNameToService.clear();
+ mNameToRegistrationCallback.clear();
+ mNameToClientCallback.clear();
+}
+
} // namespace android
diff --git a/cmds/servicemanager/ServiceManager.h b/cmds/servicemanager/ServiceManager.h
index 5e40319..c6db697 100644
--- a/cmds/servicemanager/ServiceManager.h
+++ b/cmds/servicemanager/ServiceManager.h
@@ -58,6 +58,12 @@
void binderDied(const wp<IBinder>& who) override;
void handleClientCallbacks();
+ /**
+ * This API is added for debug purposes. It clears members which hold service and callback
+ * information.
+ */
+ void clear();
+
protected:
virtual void tryStartService(const std::string& name);
diff --git a/cmds/servicemanager/ServiceManagerFuzzer.cpp b/cmds/servicemanager/ServiceManagerFuzzer.cpp
index bc48fa9..b76a6bd 100644
--- a/cmds/servicemanager/ServiceManagerFuzzer.cpp
+++ b/cmds/servicemanager/ServiceManagerFuzzer.cpp
@@ -26,15 +26,10 @@
using ::android::sp;
extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
- FuzzedDataProvider provider(data, size);
-
- // Adding this random abort to check bug pipeline.
- bool shouldAbort = provider.ConsumeBool();
- if (shouldAbort) abort();
-
auto accessPtr = std::make_unique<Access>();
auto serviceManager = sp<ServiceManager>::make(std::move(accessPtr));
- fuzzService(serviceManager, std::move(provider));
+ fuzzService(serviceManager, FuzzedDataProvider(data, size));
+ serviceManager->clear();
return 0;
}
diff --git a/data/etc/android.software.credentials.xml b/data/etc/android.software.credentials.xml
new file mode 100644
index 0000000..234d144
--- /dev/null
+++ b/data/etc/android.software.credentials.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2022 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.
+-->
+
+<permissions>
+ <feature name="android.software.credentials" />
+</permissions>
diff --git a/data/etc/handheld_core_hardware.xml b/data/etc/handheld_core_hardware.xml
index 8fdd8d0..0833012 100644
--- a/data/etc/handheld_core_hardware.xml
+++ b/data/etc/handheld_core_hardware.xml
@@ -52,6 +52,7 @@
<feature name="android.software.print" />
<feature name="android.software.companion_device_setup" />
<feature name="android.software.autofill" />
+ <feature name="android.software.credentials" />
<feature name="android.software.cant_save_state" />
<feature name="android.software.secure_lock_screen" />
<feature name="android.software.window_magnification" />
diff --git a/data/etc/tablet_core_hardware.xml b/data/etc/tablet_core_hardware.xml
index 59d5b10..6af4d91 100644
--- a/data/etc/tablet_core_hardware.xml
+++ b/data/etc/tablet_core_hardware.xml
@@ -52,6 +52,7 @@
<feature name="android.software.print" />
<feature name="android.software.companion_device_setup" />
<feature name="android.software.autofill" />
+ <feature name="android.software.credentials" />
<feature name="android.software.cant_save_state" />
<feature name="android.software.secure_lock_screen" />
<feature name="android.software.window_magnification" />
diff --git a/include/android/keycodes.h b/include/android/keycodes.h
index 16a13d6..e5b5db2 100644
--- a/include/android/keycodes.h
+++ b/include/android/keycodes.h
@@ -818,6 +818,17 @@
/** Keyboard backlight Toggle key.
* Toggles the keyboard backlight on/off. */
AKEYCODE_KEYBOARD_BACKLIGHT_TOGGLE = 307,
+ /** The primary button on the barrel of a stylus.
+ * This is usually the button closest to the tip of the stylus. */
+ AKEYCODE_STYLUS_BUTTON_PRIMARY = 308,
+ /** The secondary button on the barrel of a stylus.
+ * This is usually the second button from the tip of the stylus. */
+ AKEYCODE_STYLUS_BUTTON_SECONDARY = 309,
+ /** The tertiary button on the barrel of a stylus.
+ * This is usually the third button from the tip of the stylus. */
+ AKEYCODE_STYLUS_BUTTON_TERTIARY = 310,
+ /** A button on the tail end of a stylus. */
+ AKEYCODE_STYLUS_BUTTON_TAIL = 311,
// NOTE: If you add a new keycode here you must also add it to several other files.
// Refer to frameworks/base/core/java/android/view/KeyEvent.java for the full list.
diff --git a/include/android/surface_control_jni.h b/include/android/surface_control_jni.h
new file mode 100644
index 0000000..67e3a9f
--- /dev/null
+++ b/include/android/surface_control_jni.h
@@ -0,0 +1,65 @@
+/*
+ * Copyright 2022 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.
+ */
+
+/**
+ * @addtogroup NativeActivity Native Activity
+ * @{
+ */
+
+/**
+ * @file surface_control_jni.h
+ */
+
+#ifndef ANDROID_SURFACE_CONTROL_JNI_H
+#define ANDROID_SURFACE_CONTROL_JNI_H
+
+#include <jni.h>
+#include <sys/cdefs.h>
+
+#include <android/surface_control.h>
+
+__BEGIN_DECLS
+
+/**
+ * Return the ASurfaceControl wrapped by a Java SurfaceControl object.
+ *
+ * This method does not acquire any additional reference to the ASurfaceControl
+ * that is returned. To keep the ASurfaceControl alive after the Java
+ * SurfaceControl object is closed, explicitly or by the garbage collector, be
+ * sure to use ASurfaceControl_acquire() to acquire an additional reference.
+ *
+ * Available since API level 34.
+ */
+ASurfaceControl* _Nullable ASurfaceControl_fromSurfaceControl(JNIEnv* _Nonnull env,
+ jobject _Nonnull surfaceControlObj) __INTRODUCED_IN(__ANDROID_API_U__);
+
+/**
+ * Return the ASurfaceTransaction wrapped by a Java Transaction object.
+ *
+ * The returned ASurfaceTransaction is still owned by the Java Transaction object is only
+ * valid while the Java Transaction object is alive. In particular, the returned transaction
+ * must NOT be deleted with ASurfaceTransaction_delete.
+ * May return nullptr on error.
+ *
+ * Available since API level 34.
+ */
+ASurfaceTransaction* _Nullable ASurfaceTransaction_fromTransaction(JNIEnv* _Nonnull env,
+ jobject _Nonnull transactionObj) __INTRODUCED_IN(__ANDROID_API_U__);
+
+__END_DECLS
+
+#endif // ANDROID_SURFACE_CONTROL_JNI_H
+/** @} */
diff --git a/include/input/VelocityTracker.h b/include/input/VelocityTracker.h
index 4251f04..294879e 100644
--- a/include/input/VelocityTracker.h
+++ b/include/input/VelocityTracker.h
@@ -145,16 +145,6 @@
inline int32_t getActivePointerId() const { return mActivePointerId; }
private:
- // All axes supported for velocity tracking, mapped to their default strategies.
- // Although other strategies are available for testing and comparison purposes,
- // the default strategy is the one that applications will actually use. Be very careful
- // when adjusting the default strategy because it can dramatically affect
- // (often in a bad way) the user experience.
- static const std::map<int32_t, Strategy> DEFAULT_STRATEGY_BY_AXIS;
-
- // Axes specifying location on a 2D plane (i.e. X and Y).
- static const std::set<int32_t> PLANAR_AXES;
-
nsecs_t mLastEventTime;
BitSet32 mCurrentPointerIdBits;
int32_t mActivePointerId;
@@ -170,7 +160,12 @@
void configureStrategy(int32_t axis);
- static std::unique_ptr<VelocityTrackerStrategy> createStrategy(const Strategy strategy);
+ // Generates a VelocityTrackerStrategy instance for the given Strategy type.
+ // The `deltaValues` parameter indicates whether or not the created strategy should treat motion
+ // values as deltas (and not as absolute values). This the parameter is applicable only for
+ // strategies that support differential axes.
+ static std::unique_ptr<VelocityTrackerStrategy> createStrategy(const Strategy strategy,
+ bool deltaValues);
};
@@ -316,7 +311,7 @@
class ImpulseVelocityTrackerStrategy : public VelocityTrackerStrategy {
public:
- ImpulseVelocityTrackerStrategy();
+ ImpulseVelocityTrackerStrategy(bool deltaValues);
virtual ~ImpulseVelocityTrackerStrategy();
virtual void clearPointers(BitSet32 idBits);
@@ -341,6 +336,11 @@
inline float getPosition(uint32_t id) const { return positions[idBits.getIndexOfBit(id)]; }
};
+ // Whether or not the input movement values for the strategy come in the form of delta values.
+ // If the input values are not deltas, the strategy needs to calculate deltas as part of its
+ // velocity calculation.
+ const bool mDeltaValues;
+
size_t mIndex;
Movement mMovements[HISTORY_SIZE];
};
diff --git a/libs/binder/IServiceManager.cpp b/libs/binder/IServiceManager.cpp
index 5db3eef..05db774 100644
--- a/libs/binder/IServiceManager.cpp
+++ b/libs/binder/IServiceManager.cpp
@@ -380,6 +380,13 @@
if (Status status = realGetService(name, &out); !status.isOk()) {
ALOGW("Failed to getService in waitForService for %s: %s", name.c_str(),
status.toString8().c_str());
+ if (0 == ProcessState::self()->getThreadPoolMaxTotalThreadCount()) {
+ ALOGW("Got service, but may be racey because we could not wait efficiently for it. "
+ "Threadpool has 0 guaranteed threads. "
+ "Is the threadpool configured properly? "
+ "See ProcessState::startThreadPool and "
+ "ProcessState::setThreadPoolMaxThreadCount.");
+ }
return nullptr;
}
if (out != nullptr) return out;
@@ -410,7 +417,9 @@
if (waiter->mBinder != nullptr) return waiter->mBinder;
}
- ALOGW("Waited one second for %s (is service started? are binder threads started and available?)", name.c_str());
+ ALOGW("Waited one second for %s (is service started? Number of threads started in the "
+ "threadpool: %zu. Are binder threads started and available?)",
+ name.c_str(), ProcessState::self()->getThreadPoolMaxTotalThreadCount());
// Handle race condition for lazy services. Here is what can happen:
// - the service dies (not processed by init yet).
diff --git a/libs/binder/RpcTrusty.cpp b/libs/binder/RpcTrusty.cpp
index ea49eef..3b53b05 100644
--- a/libs/binder/RpcTrusty.cpp
+++ b/libs/binder/RpcTrusty.cpp
@@ -26,8 +26,12 @@
using android::base::unique_fd;
-sp<IBinder> RpcTrustyConnect(const char* device, const char* port) {
+sp<RpcSession> RpcTrustyConnectWithSessionInitializer(
+ const char* device, const char* port,
+ std::function<void(sp<RpcSession>&)> sessionInitializer) {
auto session = RpcSession::make(RpcTransportCtxFactoryTipcAndroid::make());
+ // using the callback to initialize the session
+ sessionInitializer(session);
auto request = [=] {
int tipcFd = tipc_connect(device, port);
if (tipcFd < 0) {
@@ -40,6 +44,11 @@
LOG(ERROR) << "Failed to set up Trusty client. Error: " << statusToString(status).c_str();
return nullptr;
}
+ return session;
+}
+
+sp<IBinder> RpcTrustyConnect(const char* device, const char* port) {
+ auto session = RpcTrustyConnectWithSessionInitializer(device, port, [](auto) {});
return session->getRootObject();
}
diff --git a/libs/binder/include_trusty/binder/RpcTrusty.h b/libs/binder/include_trusty/binder/RpcTrusty.h
index f124e0c..b034b9b 100644
--- a/libs/binder/include_trusty/binder/RpcTrusty.h
+++ b/libs/binder/include_trusty/binder/RpcTrusty.h
@@ -22,4 +22,8 @@
sp<IBinder> RpcTrustyConnect(const char* device, const char* port);
+sp<RpcSession> RpcTrustyConnectWithSessionInitializer(
+ const char* device, const char* port,
+ std::function<void(sp<RpcSession>&)> sessionInitializer);
+
} // namespace android
diff --git a/libs/binder/rust/Android.bp b/libs/binder/rust/Android.bp
index 0ec6183..a135796 100644
--- a/libs/binder/rust/Android.bp
+++ b/libs/binder/rust/Android.bp
@@ -30,6 +30,7 @@
apex_available: [
"//apex_available:platform",
"com.android.compos",
+ "com.android.rkpd",
"com.android.uwb",
"com.android.virt",
],
@@ -80,6 +81,7 @@
apex_available: [
"//apex_available:platform",
"com.android.compos",
+ "com.android.rkpd",
"com.android.uwb",
"com.android.virt",
],
@@ -138,6 +140,7 @@
apex_available: [
"//apex_available:platform",
"com.android.compos",
+ "com.android.rkpd",
"com.android.uwb",
"com.android.virt",
],
diff --git a/libs/binder/rust/rpcbinder/Android.bp b/libs/binder/rust/rpcbinder/Android.bp
index f169390..5ebc27f 100644
--- a/libs/binder/rust/rpcbinder/Android.bp
+++ b/libs/binder/rust/rpcbinder/Android.bp
@@ -16,7 +16,7 @@
],
rustlibs: [
"libbinder_ndk_sys",
- "libbinder_rpc_unstable_bindgen",
+ "libbinder_rpc_unstable_bindgen_sys",
"libbinder_rs",
"libdowncast_rs",
"liblibc",
@@ -29,6 +29,35 @@
min_sdk_version: "Tiramisu",
}
+// Build a separate rust_library rather than depending directly on libbinder_rpc_unstable_bindgen,
+// to work around the fact that rust_bindgen targets only produce rlibs and not dylibs, which would
+// result in duplicate conflicting versions of libbinder_ndk_sys. This will hopefully be fixed in
+// the build system, at which point we can delete this target and go back to using
+// libbinder_rpc_unstable_bindgen directly.
+rust_library {
+ name: "libbinder_rpc_unstable_bindgen_sys",
+ crate_name: "binder_rpc_unstable_bindgen",
+ srcs: [
+ ":libbinder_rpc_unstable_bindgen",
+ ],
+ visibility: [":__subpackages__"],
+ rustlibs: [
+ "libbinder_ndk_sys",
+ ],
+ shared_libs: [
+ "libbinder_rpc_unstable",
+ "libutils",
+ ],
+ apex_available: [
+ "com.android.compos",
+ "com.android.uwb",
+ "com.android.virt",
+ ],
+ min_sdk_version: "Tiramisu",
+ lints: "none",
+ clippy_lints: "none",
+}
+
// TODO(b/184872979): remove once the RPC Binder API is stabilised.
rust_bindgen {
name: "libbinder_rpc_unstable_bindgen",
@@ -36,6 +65,15 @@
crate_name: "binder_rpc_unstable_bindgen",
visibility: [":__subpackages__"],
source_stem: "bindings",
+ bindgen_flags: [
+ "--blocklist-type",
+ "AIBinder",
+ "--raw-line",
+ "use binder_ndk_sys::AIBinder;",
+ ],
+ rustlibs: [
+ "libbinder_ndk_sys",
+ ],
shared_libs: [
"libbinder_rpc_unstable",
"libutils",
@@ -52,6 +90,9 @@
name: "libbinder_rpc_unstable_bindgen_test",
srcs: [":libbinder_rpc_unstable_bindgen"],
crate_name: "binder_rpc_unstable_bindgen",
+ rustlibs: [
+ "libbinder_ndk_sys",
+ ],
test_suites: ["general-tests"],
auto_gen_config: true,
clippy_lints: "none",
diff --git a/libs/binder/rust/rpcbinder/src/client.rs b/libs/binder/rust/rpcbinder/src/client.rs
index dfc6f06..743800b 100644
--- a/libs/binder/rust/rpcbinder/src/client.rs
+++ b/libs/binder/rust/rpcbinder/src/client.rs
@@ -14,10 +14,7 @@
* limitations under the License.
*/
-use binder::{
- unstable_api::{new_spibinder, AIBinder},
- FromIBinder, SpIBinder, StatusCode, Strong,
-};
+use binder::{unstable_api::new_spibinder, FromIBinder, SpIBinder, StatusCode, Strong};
use std::os::{
raw::{c_int, c_void},
unix::io::RawFd,
@@ -27,7 +24,7 @@
pub fn get_vsock_rpc_service(cid: u32, port: u32) -> Option<SpIBinder> {
// SAFETY: AIBinder returned by RpcClient has correct reference count, and the ownership can
// safely be taken by new_spibinder.
- unsafe { new_spibinder(binder_rpc_unstable_bindgen::RpcClient(cid, port) as *mut AIBinder) }
+ unsafe { new_spibinder(binder_rpc_unstable_bindgen::RpcClient(cid, port)) }
}
/// Connects to an RPC Binder server for a particular interface over vsock.
@@ -54,7 +51,7 @@
new_spibinder(binder_rpc_unstable_bindgen::RpcPreconnectedClient(
Some(request_fd_wrapper),
param,
- ) as *mut AIBinder)
+ ))
}
}
diff --git a/libs/binder/rust/rpcbinder/src/server.rs b/libs/binder/rust/rpcbinder/src/server.rs
index d98a439..aeb23c6 100644
--- a/libs/binder/rust/rpcbinder/src/server.rs
+++ b/libs/binder/rust/rpcbinder/src/server.rs
@@ -14,7 +14,10 @@
* limitations under the License.
*/
-use binder::{unstable_api::AsNative, SpIBinder};
+use binder::{
+ unstable_api::{AIBinder, AsNative},
+ SpIBinder,
+};
use std::{os::raw, ptr::null_mut};
/// Runs a binder RPC server, serving the supplied binder service implementation on the given vsock
@@ -44,7 +47,7 @@
F: FnOnce(),
{
fn run_server(&mut self, mut service: SpIBinder, port: u32) -> bool {
- let service = service.as_native_mut() as *mut binder_rpc_unstable_bindgen::AIBinder;
+ let service = service.as_native_mut();
let param = self.as_void_ptr();
// SAFETY: Service ownership is transferring to the server and won't be valid afterward.
@@ -106,10 +109,7 @@
}
}
-unsafe extern "C" fn factory_wrapper(
- cid: u32,
- context: *mut raw::c_void,
-) -> *mut binder_rpc_unstable_bindgen::AIBinder {
+unsafe extern "C" fn factory_wrapper(cid: u32, context: *mut raw::c_void) -> *mut AIBinder {
// SAFETY: `context` was created from an `&mut RpcServerFactoryRef` by
// `run_rpc_server_with_factory`, and we are still within the lifetime of the value it is
// pointing to.
@@ -117,7 +117,7 @@
let factory = factory_ptr.as_mut().unwrap();
if let Some(mut service) = factory(cid) {
- service.as_native_mut() as *mut binder_rpc_unstable_bindgen::AIBinder
+ service.as_native_mut()
} else {
null_mut()
}
diff --git a/libs/binder/rust/src/native.rs b/libs/binder/rust/src/native.rs
index 3a6dadd..dee05d0 100644
--- a/libs/binder/rust/src/native.rs
+++ b/libs/binder/rust/src/native.rs
@@ -296,7 +296,7 @@
/// Must be called with a valid pointer to a `T` object. After this call,
/// the pointer will be invalid and should not be dereferenced.
unsafe extern "C" fn on_destroy(object: *mut c_void) {
- Box::from_raw(object as *mut T);
+ drop(Box::from_raw(object as *mut T));
}
/// Called whenever a new, local `AIBinder` object is needed of a specific
diff --git a/libs/gui/SurfaceComposerClient.cpp b/libs/gui/SurfaceComposerClient.cpp
index 751721e..a9d6b0e 100644
--- a/libs/gui/SurfaceComposerClient.cpp
+++ b/libs/gui/SurfaceComposerClient.cpp
@@ -632,7 +632,7 @@
mAnimation(other.mAnimation),
mEarlyWakeupStart(other.mEarlyWakeupStart),
mEarlyWakeupEnd(other.mEarlyWakeupEnd),
- mContainsBuffer(other.mContainsBuffer),
+ mMayContainBuffer(other.mMayContainBuffer),
mDesiredPresentTime(other.mDesiredPresentTime),
mIsAutoTimestamp(other.mIsAutoTimestamp),
mFrameTimelineInfo(other.mFrameTimelineInfo),
@@ -667,7 +667,6 @@
const bool animation = parcel->readBool();
const bool earlyWakeupStart = parcel->readBool();
const bool earlyWakeupEnd = parcel->readBool();
- const bool containsBuffer = parcel->readBool();
const int64_t desiredPresentTime = parcel->readInt64();
const bool isAutoTimestamp = parcel->readBool();
FrameTimelineInfo frameTimelineInfo;
@@ -745,7 +744,6 @@
mAnimation = animation;
mEarlyWakeupStart = earlyWakeupStart;
mEarlyWakeupEnd = earlyWakeupEnd;
- mContainsBuffer = containsBuffer;
mDesiredPresentTime = desiredPresentTime;
mIsAutoTimestamp = isAutoTimestamp;
mFrameTimelineInfo = frameTimelineInfo;
@@ -777,7 +775,6 @@
parcel->writeBool(mAnimation);
parcel->writeBool(mEarlyWakeupStart);
parcel->writeBool(mEarlyWakeupEnd);
- parcel->writeBool(mContainsBuffer);
parcel->writeInt64(mDesiredPresentTime);
parcel->writeBool(mIsAutoTimestamp);
mFrameTimelineInfo.writeToParcel(parcel);
@@ -876,7 +873,7 @@
mInputWindowCommands.merge(other.mInputWindowCommands);
- mContainsBuffer |= other.mContainsBuffer;
+ mMayContainBuffer |= other.mMayContainBuffer;
mEarlyWakeupStart = mEarlyWakeupStart || other.mEarlyWakeupStart;
mEarlyWakeupEnd = mEarlyWakeupEnd || other.mEarlyWakeupEnd;
mApplyToken = other.mApplyToken;
@@ -892,7 +889,7 @@
mDisplayStates.clear();
mListenerCallbacks.clear();
mInputWindowCommands.clear();
- mContainsBuffer = false;
+ mMayContainBuffer = false;
mForceSynchronous = 0;
mTransactionNestCount = 0;
mAnimation = false;
@@ -920,7 +917,7 @@
}
void SurfaceComposerClient::Transaction::cacheBuffers() {
- if (!mContainsBuffer) {
+ if (!mMayContainBuffer) {
return;
}
@@ -1464,7 +1461,6 @@
s->what &= ~layer_state_t::eBufferChanged;
s->bufferData = nullptr;
- mContainsBuffer = false;
return bufferData;
}
@@ -1495,7 +1491,6 @@
if (buffer == nullptr) {
s->what &= ~layer_state_t::eBufferChanged;
s->bufferData = nullptr;
- mContainsBuffer = false;
return *this;
}
@@ -1530,7 +1525,7 @@
const std::vector<SurfaceControlStats>&) {},
nullptr);
- mContainsBuffer = true;
+ mMayContainBuffer = true;
return *this;
}
diff --git a/libs/gui/include/gui/LayerState.h b/libs/gui/include/gui/LayerState.h
index 3c7b162..c8927ad 100644
--- a/libs/gui/include/gui/LayerState.h
+++ b/libs/gui/include/gui/LayerState.h
@@ -133,7 +133,7 @@
eLayerOpaque = 0x02, // SURFACE_OPAQUE
eLayerSkipScreenshot = 0x40, // SKIP_SCREENSHOT
eLayerSecure = 0x80, // SECURE
- // Queue up BufferStateLayer buffers instead of dropping the oldest buffer when this flag is
+ // Queue up layer buffers instead of dropping the oldest buffer when this flag is
// set. This blocks the client until all the buffers have been presented. If the buffers
// have presentation timestamps, then we may drop buffers.
eEnableBackpressure = 0x100, // ENABLE_BACKPRESSURE
diff --git a/libs/gui/include/gui/SurfaceComposerClient.h b/libs/gui/include/gui/SurfaceComposerClient.h
index 8c47ebc..963cc09 100644
--- a/libs/gui/include/gui/SurfaceComposerClient.h
+++ b/libs/gui/include/gui/SurfaceComposerClient.h
@@ -409,8 +409,10 @@
bool mEarlyWakeupStart = false;
bool mEarlyWakeupEnd = false;
- // Indicates that the Transaction contains a buffer that should be cached
- bool mContainsBuffer = false;
+ // Indicates that the Transaction may contain buffers that should be cached. The reason this
+ // is only a guess is that buffers can be removed before cache is called. This is only a
+ // hint that at some point a buffer was added to this transaction before apply was called.
+ bool mMayContainBuffer = false;
// mDesiredPresentTime is the time in nanoseconds that the client would like the transaction
// to be presented. When it is not possible to present at exactly that time, it will be
diff --git a/libs/input/InputEventLabels.cpp b/libs/input/InputEventLabels.cpp
index 5990ee0..163a2fe 100644
--- a/libs/input/InputEventLabels.cpp
+++ b/libs/input/InputEventLabels.cpp
@@ -23,6 +23,8 @@
namespace android {
+// clang-format off
+
// NOTE: If you add a new keycode here you must also add it to several other files.
// Refer to frameworks/base/core/java/android/view/KeyEvent.java for the full list.
#define KEYCODES_SEQUENCE \
@@ -333,7 +335,11 @@
DEFINE_KEYCODE(DEMO_APP_4), \
DEFINE_KEYCODE(KEYBOARD_BACKLIGHT_DOWN), \
DEFINE_KEYCODE(KEYBOARD_BACKLIGHT_UP), \
- DEFINE_KEYCODE(KEYBOARD_BACKLIGHT_TOGGLE)
+ DEFINE_KEYCODE(KEYBOARD_BACKLIGHT_TOGGLE), \
+ DEFINE_KEYCODE(STYLUS_BUTTON_PRIMARY), \
+ DEFINE_KEYCODE(STYLUS_BUTTON_SECONDARY), \
+ DEFINE_KEYCODE(STYLUS_BUTTON_TERTIARY), \
+ DEFINE_KEYCODE(STYLUS_BUTTON_TAIL)
// NOTE: If you add a new axis here you must also add it to several other files.
// Refer to frameworks/base/core/java/android/view/MotionEvent.java for the full list.
@@ -387,7 +393,6 @@
DEFINE_AXIS(GENERIC_15), \
DEFINE_AXIS(GENERIC_16)
-
// NOTE: If you add new LEDs here, you must also add them to Input.h
#define LEDS_SEQUENCE \
DEFINE_LED(NUM_LOCK), \
@@ -412,6 +417,8 @@
DEFINE_FLAG(GESTURE), \
DEFINE_FLAG(WAKE)
+// clang-format on
+
// --- InputEventLookup ---
const std::unordered_map<std::string, int> InputEventLookup::KEYCODES = {KEYCODES_SEQUENCE};
diff --git a/libs/input/VelocityTracker.cpp b/libs/input/VelocityTracker.cpp
index 527a75b..4a4f734 100644
--- a/libs/input/VelocityTracker.cpp
+++ b/libs/input/VelocityTracker.cpp
@@ -55,6 +55,22 @@
// Nanoseconds per milliseconds.
static const nsecs_t NANOS_PER_MS = 1000000;
+// All axes supported for velocity tracking, mapped to their default strategies.
+// Although other strategies are available for testing and comparison purposes,
+// the default strategy is the one that applications will actually use. Be very careful
+// when adjusting the default strategy because it can dramatically affect
+// (often in a bad way) the user experience.
+static const std::map<int32_t, VelocityTracker::Strategy> DEFAULT_STRATEGY_BY_AXIS =
+ {{AMOTION_EVENT_AXIS_X, VelocityTracker::Strategy::LSQ2},
+ {AMOTION_EVENT_AXIS_Y, VelocityTracker::Strategy::LSQ2},
+ {AMOTION_EVENT_AXIS_SCROLL, VelocityTracker::Strategy::IMPULSE}};
+
+// Axes specifying location on a 2D plane (i.e. X and Y).
+static const std::set<int32_t> PLANAR_AXES = {AMOTION_EVENT_AXIS_X, AMOTION_EVENT_AXIS_Y};
+
+// Axes whose motion values are differential values (i.e. deltas).
+static const std::set<int32_t> DIFFERENTIAL_AXES = {AMOTION_EVENT_AXIS_SCROLL};
+
// Threshold for determining that a pointer has stopped moving.
// Some input devices do not send ACTION_MOVE events in the case where a pointer has
// stopped. We need to detect this case so that we can accurately predict the
@@ -125,12 +141,6 @@
// --- VelocityTracker ---
-const std::map<int32_t, VelocityTracker::Strategy> VelocityTracker::DEFAULT_STRATEGY_BY_AXIS =
- {{AMOTION_EVENT_AXIS_X, VelocityTracker::Strategy::LSQ2},
- {AMOTION_EVENT_AXIS_Y, VelocityTracker::Strategy::LSQ2}};
-
-const std::set<int32_t> VelocityTracker::PLANAR_AXES = {AMOTION_EVENT_AXIS_X, AMOTION_EVENT_AXIS_Y};
-
VelocityTracker::VelocityTracker(const Strategy strategy)
: mLastEventTime(0),
mCurrentPointerIdBits(0),
@@ -141,11 +151,14 @@
}
void VelocityTracker::configureStrategy(int32_t axis) {
+ const bool isDifferentialAxis = DIFFERENTIAL_AXES.find(axis) != DIFFERENTIAL_AXES.end();
+
std::unique_ptr<VelocityTrackerStrategy> createdStrategy;
if (mOverrideStrategy != VelocityTracker::Strategy::DEFAULT) {
- createdStrategy = createStrategy(mOverrideStrategy);
+ createdStrategy = createStrategy(mOverrideStrategy, isDifferentialAxis /* deltaValues */);
} else {
- createdStrategy = createStrategy(VelocityTracker::DEFAULT_STRATEGY_BY_AXIS.at(axis));
+ createdStrategy = createStrategy(DEFAULT_STRATEGY_BY_AXIS.at(axis),
+ isDifferentialAxis /* deltaValues */);
}
LOG_ALWAYS_FATAL_IF(createdStrategy == nullptr,
@@ -154,11 +167,11 @@
}
std::unique_ptr<VelocityTrackerStrategy> VelocityTracker::createStrategy(
- VelocityTracker::Strategy strategy) {
+ VelocityTracker::Strategy strategy, bool deltaValues) {
switch (strategy) {
case VelocityTracker::Strategy::IMPULSE:
ALOGI_IF(DEBUG_STRATEGY, "Initializing impulse strategy");
- return std::make_unique<ImpulseVelocityTrackerStrategy>();
+ return std::make_unique<ImpulseVelocityTrackerStrategy>(deltaValues);
case VelocityTracker::Strategy::LSQ1:
return std::make_unique<LeastSquaresVelocityTrackerStrategy>(1);
@@ -283,9 +296,7 @@
case AMOTION_EVENT_ACTION_HOVER_ENTER:
// Clear all pointers on down before adding the new movement.
clear();
- for (int32_t axis : PLANAR_AXES) {
- axesToProcess.insert(axis);
- }
+ axesToProcess.insert(PLANAR_AXES.begin(), PLANAR_AXES.end());
break;
case AMOTION_EVENT_ACTION_POINTER_DOWN: {
// Start a new movement trace for a pointer that just went down.
@@ -294,16 +305,12 @@
BitSet32 downIdBits;
downIdBits.markBit(event->getPointerId(event->getActionIndex()));
clearPointers(downIdBits);
- for (int32_t axis : PLANAR_AXES) {
- axesToProcess.insert(axis);
- }
+ axesToProcess.insert(PLANAR_AXES.begin(), PLANAR_AXES.end());
break;
}
case AMOTION_EVENT_ACTION_MOVE:
case AMOTION_EVENT_ACTION_HOVER_MOVE:
- for (int32_t axis : PLANAR_AXES) {
- axesToProcess.insert(axis);
- }
+ axesToProcess.insert(PLANAR_AXES.begin(), PLANAR_AXES.end());
break;
case AMOTION_EVENT_ACTION_POINTER_UP:
case AMOTION_EVENT_ACTION_UP: {
@@ -328,6 +335,9 @@
// before adding the movement.
return;
}
+ case AMOTION_EVENT_ACTION_SCROLL:
+ axesToProcess.insert(AMOTION_EVENT_AXIS_SCROLL);
+ break;
default:
// Ignore all other actions.
return;
@@ -1004,7 +1014,8 @@
// --- ImpulseVelocityTrackerStrategy ---
-ImpulseVelocityTrackerStrategy::ImpulseVelocityTrackerStrategy() : mIndex(0) {}
+ImpulseVelocityTrackerStrategy::ImpulseVelocityTrackerStrategy(bool deltaValues)
+ : mDeltaValues(deltaValues), mIndex(0) {}
ImpulseVelocityTrackerStrategy::~ImpulseVelocityTrackerStrategy() {
}
@@ -1112,7 +1123,8 @@
return (work < 0 ? -1.0 : 1.0) * sqrtf(fabsf(work)) * sqrt2;
}
-static float calculateImpulseVelocity(const nsecs_t* t, const float* x, size_t count) {
+static float calculateImpulseVelocity(const nsecs_t* t, const float* x, size_t count,
+ bool deltaValues) {
// The input should be in reversed time order (most recent sample at index i=0)
// t[i] is in nanoseconds, but due to FP arithmetic, convert to seconds inside this function
static constexpr float SECONDS_PER_NANO = 1E-9;
@@ -1123,12 +1135,26 @@
if (t[1] > t[0]) { // Algorithm will still work, but not perfectly
ALOGE("Samples provided to calculateImpulseVelocity in the wrong order");
}
+
+ // If the data values are delta values, we do not have to calculate deltas here.
+ // We can use the delta values directly, along with the calculated time deltas.
+ // Since the data value input is in reversed time order:
+ // [a] for non-delta inputs, instantenous velocity = (x[i] - x[i-1])/(t[i] - t[i-1])
+ // [b] for delta inputs, instantenous velocity = -x[i-1]/(t[i] - t[i - 1])
+ // e.g., let the non-delta values are: V = [2, 3, 7], the equivalent deltas are D = [2, 1, 4].
+ // Since the input is in reversed time order, the input values for this function would be
+ // V'=[7, 3, 2] and D'=[4, 1, 2] for the non-delta and delta values, respectively.
+ //
+ // The equivalent of {(V'[2] - V'[1]) = 2 - 3 = -1} would be {-D'[1] = -1}
+ // Similarly, the equivalent of {(V'[1] - V'[0]) = 3 - 7 = -4} would be {-D'[0] = -4}
+
if (count == 2) { // if 2 points, basic linear calculation
if (t[1] == t[0]) {
ALOGE("Events have identical time stamps t=%" PRId64 ", setting velocity = 0", t[0]);
return 0;
}
- return (x[1] - x[0]) / (SECONDS_PER_NANO * (t[1] - t[0]));
+ const float deltaX = deltaValues ? -x[0] : x[1] - x[0];
+ return deltaX / (SECONDS_PER_NANO * (t[1] - t[0]));
}
// Guaranteed to have at least 3 points here
float work = 0;
@@ -1138,7 +1164,8 @@
continue;
}
float vprev = kineticEnergyToVelocity(work); // v[i-1]
- float vcurr = (x[i] - x[i-1]) / (SECONDS_PER_NANO * (t[i] - t[i-1])); // v[i]
+ const float deltaX = deltaValues ? -x[i-1] : x[i] - x[i-1];
+ float vcurr = deltaX / (SECONDS_PER_NANO * (t[i] - t[i-1])); // v[i]
work += (vcurr - vprev) * fabsf(vcurr);
if (i == count - 1) {
work *= 0.5; // initial condition, case 2) above
@@ -1177,7 +1204,7 @@
return false; // no data
}
outEstimator->coeff[0] = 0;
- outEstimator->coeff[1] = calculateImpulseVelocity(time, positions, m);
+ outEstimator->coeff[1] = calculateImpulseVelocity(time, positions, m, mDeltaValues);
outEstimator->coeff[2] = 0;
outEstimator->time = newestMovement.eventTime;
diff --git a/libs/input/tests/VelocityTracker_test.cpp b/libs/input/tests/VelocityTracker_test.cpp
index 0b7def3..8b00b5c 100644
--- a/libs/input/tests/VelocityTracker_test.cpp
+++ b/libs/input/tests/VelocityTracker_test.cpp
@@ -87,7 +87,7 @@
}
};
-struct MotionEventEntry {
+struct PlanarMotionEventEntry {
std::chrono::nanoseconds eventTime;
std::vector<Position> positions;
};
@@ -136,15 +136,43 @@
return AMOTION_EVENT_ACTION_MOVE;
}
-static std::vector<MotionEvent> createMotionEventStream(
- const std::vector<MotionEventEntry>& motions) {
+static std::vector<MotionEvent> createAxisScrollMotionEventStream(
+ const std::vector<std::pair<std::chrono::nanoseconds, float>>& motions) {
+ std::vector<MotionEvent> events;
+ for (const auto& [timeStamp, value] : motions) {
+ EXPECT_TRUE(!isnan(value)) << "The entry at pointerId must be valid";
+
+ PointerCoords coords[1];
+ coords[0].setAxisValue(AMOTION_EVENT_AXIS_SCROLL, value);
+
+ PointerProperties properties[1];
+ properties[0].id = DEFAULT_POINTER_ID;
+
+ MotionEvent event;
+ ui::Transform identityTransform;
+ event.initialize(InputEvent::nextId(), 5 /*deviceId*/, AINPUT_SOURCE_ROTARY_ENCODER,
+ ADISPLAY_ID_NONE, INVALID_HMAC, AMOTION_EVENT_ACTION_SCROLL,
+ 0 /*actionButton*/, 0 /*flags*/, AMOTION_EVENT_EDGE_FLAG_NONE, AMETA_NONE,
+ 0 /*buttonState*/, MotionClassification::NONE, identityTransform,
+ 0 /*xPrecision*/, 0 /*yPrecision*/, AMOTION_EVENT_INVALID_CURSOR_POSITION,
+ AMOTION_EVENT_INVALID_CURSOR_POSITION, identityTransform, 0 /*downTime*/,
+ timeStamp.count(), 1 /*pointerCount*/, properties, coords);
+
+ events.emplace_back(event);
+ }
+
+ return events;
+}
+
+static std::vector<MotionEvent> createTouchMotionEventStream(
+ const std::vector<PlanarMotionEventEntry>& motions) {
if (motions.empty()) {
ADD_FAILURE() << "Need at least 1 sample to create a MotionEvent. Received empty vector.";
}
std::vector<MotionEvent> events;
for (size_t i = 0; i < motions.size(); i++) {
- const MotionEventEntry& entry = motions[i];
+ const PlanarMotionEventEntry& entry = motions[i];
BitSet32 pointers = getValidPointers(entry.positions);
const uint32_t pointerCount = pointers.count();
@@ -155,8 +183,8 @@
} else if ((i == motions.size() - 1) && pointerCount == 1) {
action = AMOTION_EVENT_ACTION_UP;
} else {
- const MotionEventEntry& previousEntry = motions[i-1];
- const MotionEventEntry& nextEntry = motions[i+1];
+ const PlanarMotionEventEntry& previousEntry = motions[i-1];
+ const PlanarMotionEventEntry& nextEntry = motions[i+1];
action = resolveAction(previousEntry.positions, entry.positions, nextEntry.positions);
}
@@ -196,11 +224,12 @@
}
static void computeAndCheckVelocity(const VelocityTracker::Strategy strategy,
- const std::vector<MotionEventEntry>& motions, int32_t axis,
- float targetVelocity, uint32_t pointerId = DEFAULT_POINTER_ID) {
+ const std::vector<PlanarMotionEventEntry>& motions,
+ int32_t axis, float targetVelocity,
+ uint32_t pointerId = DEFAULT_POINTER_ID) {
VelocityTracker vt(strategy);
- std::vector<MotionEvent> events = createMotionEventStream(motions);
+ std::vector<MotionEvent> events = createTouchMotionEventStream(motions);
for (MotionEvent event : events) {
vt.addMovement(&event);
}
@@ -208,10 +237,33 @@
checkVelocity(vt.getVelocity(axis, pointerId).value_or(0), targetVelocity);
}
-static void computeAndCheckQuadraticEstimate(const std::vector<MotionEventEntry>& motions,
- const std::array<float, 3>& coefficients) {
+static void computeAndCheckAxisScrollVelocity(
+ const VelocityTracker::Strategy strategy,
+ const std::vector<std::pair<std::chrono::nanoseconds, float>>& motions,
+ std::optional<float> targetVelocity) {
+ VelocityTracker vt(strategy);
+
+ std::vector<MotionEvent> events = createAxisScrollMotionEventStream(motions);
+ for (const MotionEvent& event : events) {
+ vt.addMovement(&event);
+ }
+
+ std::optional<float> velocity = vt.getVelocity(AMOTION_EVENT_AXIS_SCROLL, DEFAULT_POINTER_ID);
+ if (velocity && !targetVelocity) {
+ FAIL() << "Expected no velocity, but found " << *velocity;
+ }
+ if (!velocity && targetVelocity) {
+ FAIL() << "Expected velocity, but found no velocity";
+ }
+ if (velocity) {
+ checkVelocity(*velocity, *targetVelocity);
+ }
+}
+
+static void computeAndCheckQuadraticEstimate(const std::vector<PlanarMotionEventEntry>& motions,
+ const std::array<float, 3>& coefficients) {
VelocityTracker vt(VelocityTracker::Strategy::LSQ2);
- std::vector<MotionEvent> events = createMotionEventStream(motions);
+ std::vector<MotionEvent> events = createTouchMotionEventStream(motions);
for (MotionEvent event : events) {
vt.addMovement(&event);
}
@@ -269,7 +321,7 @@
}
TEST_F(VelocityTrackerTest, TestGetComputedVelocity) {
- std::vector<MotionEventEntry> motions = {
+ std::vector<PlanarMotionEventEntry> motions = {
{235089067457000ns, {{528.00, 0}}}, {235089084684000ns, {{527.00, 0}}},
{235089093349000ns, {{527.00, 0}}}, {235089095677625ns, {{527.00, 0}}},
{235089101859000ns, {{527.00, 0}}}, {235089110378000ns, {{528.00, 0}}},
@@ -281,7 +333,7 @@
{235089162955851ns, {{560.66, 0}}}, // ACTION_UP
};
VelocityTracker vt(VelocityTracker::Strategy::IMPULSE);
- std::vector<MotionEvent> events = createMotionEventStream(motions);
+ std::vector<MotionEvent> events = createTouchMotionEventStream(motions);
for (const MotionEvent& event : events) {
vt.addMovement(&event);
}
@@ -333,7 +385,7 @@
// Same coordinate is reported 2 times in a row
// It is difficult to determine the correct answer here, but at least the direction
// of the reported velocity should be positive.
- std::vector<MotionEventEntry> motions = {
+ std::vector<PlanarMotionEventEntry> motions = {
{0ms, {{273, 0}}},
{12585us, {{293, 0}}},
{14730us, {{293, 0}}},
@@ -345,7 +397,7 @@
TEST_F(VelocityTrackerTest, ThreePointsZeroVelocityTest) {
// Same coordinate is reported 3 times in a row
- std::vector<MotionEventEntry> motions = {
+ std::vector<PlanarMotionEventEntry> motions = {
{0ms, {{293, 0}}},
{6132us, {{293, 0}}},
{11283us, {{293, 0}}},
@@ -357,7 +409,7 @@
TEST_F(VelocityTrackerTest, ThreePointsLinearVelocityTest) {
// Fixed velocity at 5 points per 10 milliseconds
- std::vector<MotionEventEntry> motions = {
+ std::vector<PlanarMotionEventEntry> motions = {
{0ms, {{0, 0}}}, {10ms, {{5, 0}}}, {20ms, {{10, 0}}}, {20ms, {{10, 0}}}, // ACTION_UP
};
computeAndCheckVelocity(VelocityTracker::Strategy::IMPULSE, motions, AMOTION_EVENT_AXIS_X, 500);
@@ -381,7 +433,7 @@
// --------------- Recorded by hand on swordfish ---------------------------------------------------
TEST_F(VelocityTrackerTest, SwordfishFlingDown) {
// Recording of a fling on Swordfish that could cause a fling in the wrong direction
- std::vector<MotionEventEntry> motions = {
+ std::vector<PlanarMotionEventEntry> motions = {
{ 0ms, {{271, 96}} },
{ 16071042ns, {{269.786346, 106.922775}} },
{ 35648403ns, {{267.983063, 156.660034}} },
@@ -416,7 +468,7 @@
TEST_F(VelocityTrackerTest, SailfishFlingUpSlow1) {
// Sailfish - fling up - slow - 1
- std::vector<MotionEventEntry> motions = {
+ std::vector<PlanarMotionEventEntry> motions = {
{ 235089067457000ns, {{528.00, 983.00}} },
{ 235089084684000ns, {{527.00, 981.00}} },
{ 235089093349000ns, {{527.00, 977.00}} },
@@ -448,7 +500,7 @@
TEST_F(VelocityTrackerTest, SailfishFlingUpSlow2) {
// Sailfish - fling up - slow - 2
- std::vector<MotionEventEntry> motions = {
+ std::vector<PlanarMotionEventEntry> motions = {
{ 235110560704000ns, {{522.00, 1107.00}} },
{ 235110575764000ns, {{522.00, 1107.00}} },
{ 235110584385000ns, {{522.00, 1107.00}} },
@@ -477,7 +529,7 @@
TEST_F(VelocityTrackerTest, SailfishFlingUpSlow3) {
// Sailfish - fling up - slow - 3
- std::vector<MotionEventEntry> motions = {
+ std::vector<PlanarMotionEventEntry> motions = {
{ 792536237000ns, {{580.00, 1317.00}} },
{ 792541538987ns, {{580.63, 1311.94}} },
{ 792544613000ns, {{581.00, 1309.00}} },
@@ -511,7 +563,7 @@
TEST_F(VelocityTrackerTest, SailfishFlingUpFaster1) {
// Sailfish - fling up - faster - 1
- std::vector<MotionEventEntry> motions = {
+ std::vector<PlanarMotionEventEntry> motions = {
{ 235160420675000ns, {{610.00, 1042.00}} },
{ 235160428220000ns, {{609.00, 1026.00}} },
{ 235160436544000ns, {{609.00, 1024.00}} },
@@ -545,7 +597,7 @@
TEST_F(VelocityTrackerTest, SailfishFlingUpFaster2) {
// Sailfish - fling up - faster - 2
- std::vector<MotionEventEntry> motions = {
+ std::vector<PlanarMotionEventEntry> motions = {
{ 847153808000ns, {{576.00, 1264.00}} },
{ 847171174000ns, {{576.00, 1262.00}} },
{ 847179640000ns, {{576.00, 1257.00}} },
@@ -571,7 +623,7 @@
TEST_F(VelocityTrackerTest, SailfishFlingUpFaster3) {
// Sailfish - fling up - faster - 3
- std::vector<MotionEventEntry> motions = {
+ std::vector<PlanarMotionEventEntry> motions = {
{ 235200532789000ns, {{507.00, 1084.00}} },
{ 235200549221000ns, {{507.00, 1083.00}} },
{ 235200557841000ns, {{507.00, 1081.00}} },
@@ -597,7 +649,7 @@
TEST_F(VelocityTrackerTest, SailfishFlingUpFast1) {
// Sailfish - fling up - fast - 1
- std::vector<MotionEventEntry> motions = {
+ std::vector<PlanarMotionEventEntry> motions = {
{ 920922149000ns, {{561.00, 1412.00}} },
{ 920930185000ns, {{559.00, 1377.00}} },
{ 920930262463ns, {{558.98, 1376.66}} },
@@ -626,7 +678,7 @@
TEST_F(VelocityTrackerTest, SailfishFlingUpFast2) {
// Sailfish - fling up - fast - 2
- std::vector<MotionEventEntry> motions = {
+ std::vector<PlanarMotionEventEntry> motions = {
{ 235247153233000ns, {{518.00, 1168.00}} },
{ 235247170452000ns, {{517.00, 1167.00}} },
{ 235247178908000ns, {{515.00, 1159.00}} },
@@ -649,7 +701,7 @@
TEST_F(VelocityTrackerTest, SailfishFlingUpFast3) {
// Sailfish - fling up - fast - 3
- std::vector<MotionEventEntry> motions = {
+ std::vector<PlanarMotionEventEntry> motions = {
{ 235302568736000ns, {{529.00, 1167.00}} },
{ 235302576644000ns, {{523.00, 1140.00}} },
{ 235302579395063ns, {{520.91, 1130.61}} },
@@ -670,7 +722,7 @@
TEST_F(VelocityTrackerTest, SailfishFlingDownSlow1) {
// Sailfish - fling down - slow - 1
- std::vector<MotionEventEntry> motions = {
+ std::vector<PlanarMotionEventEntry> motions = {
{ 235655749552755ns, {{582.00, 432.49}} },
{ 235655750638000ns, {{582.00, 433.00}} },
{ 235655758865000ns, {{582.00, 440.00}} },
@@ -704,7 +756,7 @@
TEST_F(VelocityTrackerTest, SailfishFlingDownSlow2) {
// Sailfish - fling down - slow - 2
- std::vector<MotionEventEntry> motions = {
+ std::vector<PlanarMotionEventEntry> motions = {
{ 235671152083370ns, {{485.24, 558.28}} },
{ 235671154126000ns, {{485.00, 559.00}} },
{ 235671162497000ns, {{484.00, 566.00}} },
@@ -738,7 +790,7 @@
TEST_F(VelocityTrackerTest, SailfishFlingDownSlow3) {
// Sailfish - fling down - slow - 3
- std::vector<MotionEventEntry> motions = {
+ std::vector<PlanarMotionEventEntry> motions = {
{ 170983201000ns, {{557.00, 533.00}} },
{ 171000668000ns, {{556.00, 534.00}} },
{ 171007359750ns, {{554.73, 535.27}} },
@@ -765,7 +817,7 @@
TEST_F(VelocityTrackerTest, SailfishFlingDownFaster1) {
// Sailfish - fling down - faster - 1
- std::vector<MotionEventEntry> motions = {
+ std::vector<PlanarMotionEventEntry> motions = {
{ 235695280333000ns, {{558.00, 451.00}} },
{ 235695283971237ns, {{558.43, 454.45}} },
{ 235695289038000ns, {{559.00, 462.00}} },
@@ -795,7 +847,7 @@
TEST_F(VelocityTrackerTest, SailfishFlingDownFaster2) {
// Sailfish - fling down - faster - 2
- std::vector<MotionEventEntry> motions = {
+ std::vector<PlanarMotionEventEntry> motions = {
{ 235709624766000ns, {{535.00, 579.00}} },
{ 235709642256000ns, {{534.00, 580.00}} },
{ 235709643350278ns, {{533.94, 580.06}} },
@@ -826,7 +878,7 @@
TEST_F(VelocityTrackerTest, SailfishFlingDownFaster3) {
// Sailfish - fling down - faster - 3
- std::vector<MotionEventEntry> motions = {
+ std::vector<PlanarMotionEventEntry> motions = {
{ 235727628927000ns, {{540.00, 440.00}} },
{ 235727636810000ns, {{537.00, 454.00}} },
{ 235727646176000ns, {{536.00, 454.00}} },
@@ -855,7 +907,7 @@
TEST_F(VelocityTrackerTest, SailfishFlingDownFast1) {
// Sailfish - fling down - fast - 1
- std::vector<MotionEventEntry> motions = {
+ std::vector<PlanarMotionEventEntry> motions = {
{ 235762352849000ns, {{467.00, 286.00}} },
{ 235762360250000ns, {{443.00, 344.00}} },
{ 235762362787412ns, {{434.77, 363.89}} },
@@ -876,7 +928,7 @@
TEST_F(VelocityTrackerTest, SailfishFlingDownFast2) {
// Sailfish - fling down - fast - 2
- std::vector<MotionEventEntry> motions = {
+ std::vector<PlanarMotionEventEntry> motions = {
{ 235772487188000ns, {{576.00, 204.00}} },
{ 235772495159000ns, {{553.00, 236.00}} },
{ 235772503568000ns, {{551.00, 240.00}} },
@@ -897,7 +949,7 @@
TEST_F(VelocityTrackerTest, SailfishFlingDownFast3) {
// Sailfish - fling down - fast - 3
- std::vector<MotionEventEntry> motions = {
+ std::vector<PlanarMotionEventEntry> motions = {
{ 507650295000ns, {{628.00, 233.00}} },
{ 507658234000ns, {{605.00, 269.00}} },
{ 507666784000ns, {{601.00, 274.00}} },
@@ -928,7 +980,7 @@
* part of the fitted data), this can cause large velocity values to be reported instead.
*/
TEST_F(VelocityTrackerTest, LeastSquaresVelocityTrackerStrategyEstimator_ThreeFingerTap) {
- std::vector<MotionEventEntry> motions = {
+ std::vector<PlanarMotionEventEntry> motions = {
{ 0us, {{1063, 1128}, {NAN, NAN}, {NAN, NAN}} },
{ 10800us, {{1063, 1128}, {682, 1318}, {NAN, NAN}} }, // POINTER_DOWN
{ 10800us, {{1063, 1128}, {682, 1318}, {397, 1747}} }, // POINTER_DOWN
@@ -955,7 +1007,7 @@
* affected by the liftoff.
*/
TEST_F(VelocityTrackerTest, ShortDelayBeforeActionUp) {
- std::vector<MotionEventEntry> motions = {
+ std::vector<PlanarMotionEventEntry> motions = {
{0ms, {{10, 0}}}, {10ms, {{20, 0}}}, {20ms, {{30, 0}}}, {30ms, {{30, 0}}}, // ACTION_UP
};
computeAndCheckVelocity(VelocityTracker::Strategy::IMPULSE, motions, AMOTION_EVENT_AXIS_X,
@@ -969,7 +1021,7 @@
* should be assumed to have stopped.
*/
TEST_F(VelocityTrackerTest, LongDelayBeforeActionUp) {
- std::vector<MotionEventEntry> motions = {
+ std::vector<PlanarMotionEventEntry> motions = {
{0ms, {{10, 0}}},
{10ms, {{20, 0}}},
{20ms, {{30, 0}}},
@@ -985,7 +1037,7 @@
* The final velocity should be reported as zero for all pointers.
*/
TEST_F(VelocityTrackerTest, LongDelayBeforeActionPointerUp) {
- std::vector<MotionEventEntry> motions = {
+ std::vector<PlanarMotionEventEntry> motions = {
{0ms, {{10, 0}}},
{10ms, {{20, 0}, {100, 0}}},
{20ms, {{30, 0}, {200, 0}}},
@@ -1029,7 +1081,7 @@
* In the test, we would convert these coefficients to (0*(1E3)^0, 0*(1E3)^1, 1*(1E3)^2).
*/
TEST_F(VelocityTrackerTest, LeastSquaresVelocityTrackerStrategyEstimator_Constant) {
- std::vector<MotionEventEntry> motions = {
+ std::vector<PlanarMotionEventEntry> motions = {
{ 0ms, {{1, 1}} }, // 0 s
{ 1ms, {{1, 1}} }, // 0.001 s
{ 2ms, {{1, 1}} }, // 0.002 s
@@ -1047,7 +1099,7 @@
* Straight line y = x :: the constant and quadratic coefficients are zero.
*/
TEST_F(VelocityTrackerTest, LeastSquaresVelocityTrackerStrategyEstimator_Linear) {
- std::vector<MotionEventEntry> motions = {
+ std::vector<PlanarMotionEventEntry> motions = {
{ 0ms, {{-2, -2}} },
{ 1ms, {{-1, -1}} },
{ 2ms, {{-0, -0}} },
@@ -1065,7 +1117,7 @@
* Parabola
*/
TEST_F(VelocityTrackerTest, LeastSquaresVelocityTrackerStrategyEstimator_Parabolic) {
- std::vector<MotionEventEntry> motions = {
+ std::vector<PlanarMotionEventEntry> motions = {
{ 0ms, {{1, 1}} },
{ 1ms, {{4, 4}} },
{ 2ms, {{8, 8}} },
@@ -1083,7 +1135,7 @@
* Parabola
*/
TEST_F(VelocityTrackerTest, LeastSquaresVelocityTrackerStrategyEstimator_Parabolic2) {
- std::vector<MotionEventEntry> motions = {
+ std::vector<PlanarMotionEventEntry> motions = {
{ 0ms, {{1, 1}} },
{ 1ms, {{4, 4}} },
{ 2ms, {{9, 9}} },
@@ -1101,7 +1153,7 @@
* Parabola :: y = x^2 :: the constant and linear coefficients are zero.
*/
TEST_F(VelocityTrackerTest, LeastSquaresVelocityTrackerStrategyEstimator_Parabolic3) {
- std::vector<MotionEventEntry> motions = {
+ std::vector<PlanarMotionEventEntry> motions = {
{ 0ms, {{4, 4}} },
{ 1ms, {{1, 1}} },
{ 2ms, {{0, 0}} },
@@ -1115,4 +1167,100 @@
computeAndCheckQuadraticEstimate(motions, std::array<float, 3>({0, 0E3, 1E6}));
}
+// Recorded by hand on sailfish, but only the diffs are taken to test cumulative axis velocity.
+TEST_F(VelocityTrackerTest, AxisScrollVelocity) {
+ std::vector<std::pair<std::chrono::nanoseconds, float>> motions = {
+ {235089067457000ns, 0.00}, {235089084684000ns, -1.00}, {235089093349000ns, 0.00},
+ {235089095677625ns, 0.00}, {235089101859000ns, 0.00}, {235089110378000ns, 0.00},
+ {235089112497111ns, 0.25}, {235089118760000ns, 1.75}, {235089126686000ns, 4.00},
+ {235089129316820ns, 1.33}, {235089135199000ns, 3.67}, {235089144297000ns, 6.00},
+ {235089146136443ns, 1.21}, {235089152923000ns, 5.79}, {235089160784000ns, 6.00},
+ {235089162955851ns, 1.66},
+ };
+
+ computeAndCheckAxisScrollVelocity(VelocityTracker::Strategy::IMPULSE, motions, {764.345703});
+}
+
+// --------------- Recorded by hand on a Wear OS device using a rotating side button ---------------
+TEST_F(VelocityTrackerTest, AxisScrollVelocity_ScrollDown) {
+ std::vector<std::pair<std::chrono::nanoseconds, float>> motions = {
+ {224598065152ns, -0.050100}, {224621871104ns, -0.133600}, {224645464064ns, -0.551100},
+ {224669171712ns, -0.801600}, {224687063040ns, -1.035400}, {224706691072ns, -0.484300},
+ {224738213888ns, -0.334000}, {224754401280ns, -0.083500},
+ };
+
+ computeAndCheckAxisScrollVelocity(VelocityTracker::Strategy::IMPULSE, motions, {-27.86});
+}
+
+TEST_F(VelocityTrackerTest, AxisScrollVelocity_ScrollUp) {
+ std::vector<std::pair<std::chrono::nanoseconds, float>> motions = {
+ {269606010880ns, 0.050100}, {269626064896ns, 0.217100}, {269641973760ns, 0.267200},
+ {269658079232ns, 0.267200}, {269674217472ns, 0.267200}, {269690683392ns, 0.367400},
+ {269706133504ns, 0.551100}, {269722173440ns, 0.501000},
+ };
+
+ computeAndCheckAxisScrollVelocity(VelocityTracker::Strategy::IMPULSE, motions, {31.92});
+}
+
+TEST_F(VelocityTrackerTest, AxisScrollVelocity_ScrollDown_ThenUp_ThenDown) {
+ std::vector<std::pair<std::chrono::nanoseconds, float>> motions = {
+ {2580534001664ns, -0.033400}, {2580549992448ns, -0.133600},
+ {2580566769664ns, -0.250500}, {2580581974016ns, -0.183700},
+ {2580597964800ns, -0.267200}, {2580613955584ns, -0.551100},
+ {2580635189248ns, -0.601200}, {2580661927936ns, -0.450900},
+ {2580683161600ns, -0.417500}, {2580705705984ns, -0.150300},
+ {2580722745344ns, -0.016700}, {2580786446336ns, 0.050100},
+ {2580801912832ns, 0.150300}, {2580822360064ns, 0.300600},
+ {2580838088704ns, 0.300600}, {2580854341632ns, 0.400800},
+ {2580869808128ns, 0.517700}, {2580886061056ns, 0.501000},
+ {2580905984000ns, 0.350700}, {2580921974784ns, 0.350700},
+ {2580937965568ns, 0.066800}, {2580974665728ns, 0.016700},
+ {2581034434560ns, -0.066800}, {2581049901056ns, -0.116900},
+ {2581070610432ns, -0.317300}, {2581086076928ns, -0.200400},
+ {2581101805568ns, -0.233800}, {2581118058496ns, -0.417500},
+ {2581134049280ns, -0.417500}, {2581150040064ns, -0.367400},
+ {2581166030848ns, -0.267200}, {2581181759488ns, -0.150300},
+ {2581199847424ns, -0.066800},
+ };
+
+ computeAndCheckAxisScrollVelocity(VelocityTracker::Strategy::IMPULSE, motions, {-9.73});
+}
+
+// ------------------------------- Hand generated test cases ---------------------------------------
+TEST_F(VelocityTrackerTest, AxisScrollVelocity_SimilarDifferentialValues) {
+ std::vector<std::pair<std::chrono::nanoseconds, float>> motions = {{1ns, 2.12}, {3ns, 2.12},
+ {7ns, 2.12}, {8ns, 2.12},
+ {15ns, 2.12}, {18ns, 2.12}};
+
+ computeAndCheckAxisScrollVelocity(VelocityTracker::Strategy::IMPULSE, motions, {1690236059.86});
+}
+
+TEST_F(VelocityTrackerTest, AxisScrollVelocity_OnlyTwoValues) {
+ std::vector<std::pair<std::chrono::nanoseconds, float>> motions = {{1ms, 5}, {2ms, 10}};
+
+ computeAndCheckAxisScrollVelocity(VelocityTracker::Strategy::IMPULSE, motions, {10000});
+}
+
+TEST_F(VelocityTrackerTest, AxisScrollVelocity_ConstantVelocity) {
+ std::vector<std::pair<std::chrono::nanoseconds, float>> motions = {{1ms, 20}, {2ms, 20},
+ {3ms, 20}, {4ms, 20},
+ {5ms, 20}, {6ms, 20}};
+
+ computeAndCheckAxisScrollVelocity(VelocityTracker::Strategy::IMPULSE, motions, {20000});
+}
+
+TEST_F(VelocityTrackerTest, AxisScrollVelocity_NoMotion) {
+ std::vector<std::pair<std::chrono::nanoseconds, float>> motions = {{1ns, 0}, {2ns, 0},
+ {3ns, 0}, {4ns, 0},
+ {5ns, 0}, {6ns, 0}};
+
+ computeAndCheckAxisScrollVelocity(VelocityTracker::Strategy::IMPULSE, motions, {0});
+}
+
+TEST_F(VelocityTrackerTest, AxisScrollVelocity_NoData) {
+ std::vector<std::pair<std::chrono::nanoseconds, float>> motions = {};
+
+ computeAndCheckAxisScrollVelocity(VelocityTracker::Strategy::IMPULSE, motions, std::nullopt);
+}
+
} // namespace android
diff --git a/libs/sensor/fuzz/bittube_fuzzer/bittube_fuzzer.cpp b/libs/sensor/fuzz/bittube_fuzzer/bittube_fuzzer.cpp
index 6f10a67..6a61d36 100644
--- a/libs/sensor/fuzz/bittube_fuzzer/bittube_fuzzer.cpp
+++ b/libs/sensor/fuzz/bittube_fuzzer/bittube_fuzzer.cpp
@@ -24,14 +24,14 @@
extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
FuzzedDataProvider fdp(data, size);
- BitTube bittube(size);
+ sp<BitTube> bittube(new BitTube(size));
Parcel parcel[5];
- bittube.writeToParcel(parcel);
+ bittube->writeToParcel(parcel);
sp<BitTube> tube(new BitTube(size));
- bittube.sendObjects<uint8_t>(tube, data, size);
+ bittube->sendObjects<uint8_t>(tube, data, size);
uint8_t recvData[size];
for (int i = 0; i < size; i++) recvData[i] = fdp.ConsumeIntegral<uint8_t>();
- bittube.recvObjects<uint8_t>(tube, recvData, size);
+ bittube->recvObjects<uint8_t>(tube, recvData, size);
return 0;
}
diff --git a/libs/ui/include/ui/GraphicBuffer.h b/libs/ui/include/ui/GraphicBuffer.h
index 57be686..dbe475b 100644
--- a/libs/ui/include/ui/GraphicBuffer.h
+++ b/libs/ui/include/ui/GraphicBuffer.h
@@ -270,7 +270,7 @@
// Send a callback when a GraphicBuffer dies.
//
- // This is used for BufferStateLayer caching. GraphicBuffers are refcounted per process. When
+ // This is used for layer caching. GraphicBuffers are refcounted per process. When
// A GraphicBuffer doesn't have any more sp<> in a process, it is destroyed. This causes
// problems when trying to implicitcly cache across process boundaries. Ideally, both sides
// of the cache would hold onto wp<> references. When an app dropped its sp<>, the GraphicBuffer
diff --git a/opengl/libs/Android.bp b/opengl/libs/Android.bp
index c1e935a..2237d2d 100644
--- a/opengl/libs/Android.bp
+++ b/opengl/libs/Android.bp
@@ -170,7 +170,11 @@
"libEGL_getProcAddress",
"libEGL_blobCache",
],
- ldflags: ["-Wl,--exclude-libs=ALL,--Bsymbolic-functions"],
+ ldflags: [
+ "-Wl,--exclude-libs=libEGL_getProcAddress.a",
+ "-Wl,--exclude-libs=libEGL_blobCache.a",
+ "-Wl,--Bsymbolic-functions",
+ ],
export_include_dirs: ["EGL/include"],
stubs: {
symbol_file: "libEGL.map.txt",
diff --git a/services/inputflinger/Android.bp b/services/inputflinger/Android.bp
index 5b286dc..88a9acb 100644
--- a/services/inputflinger/Android.bp
+++ b/services/inputflinger/Android.bp
@@ -191,7 +191,16 @@
"libinputservice_test",
"Bug-115739809",
"StructLayout_test",
+
+ // native fuzzers
"inputflinger_latencytracker_fuzzer",
+ "inputflinger_cursor_input_fuzzer",
+ "inputflinger_keyboard_input_fuzzer",
+ "inputflinger_multitouch_input_fuzzer",
+ "inputflinger_switch_input_fuzzer",
+ "inputflinger_input_reader_fuzzer",
+ "inputflinger_blocking_queue_fuzzer",
+ "inputflinger_input_classifier_fuzzer",
// Java/Kotlin targets
"CtsWindowManagerDeviceTestCases",
diff --git a/services/inputflinger/TEST_MAPPING b/services/inputflinger/TEST_MAPPING
index f673a28..4a0f2ec 100644
--- a/services/inputflinger/TEST_MAPPING
+++ b/services/inputflinger/TEST_MAPPING
@@ -38,6 +38,7 @@
"name": "CtsViewTestCases",
"options": [
{
+ "include-filter": "android.view.cts.input",
"include-filter": "android.view.cts.MotionEventTest",
"include-filter": "android.view.cts.PointerCaptureTest",
"include-filter": "android.view.cts.VerifyInputEventTest"
diff --git a/services/stats/StatsAidl.cpp b/services/stats/StatsAidl.cpp
index 8d6a9bd..3de51a4 100644
--- a/services/stats/StatsAidl.cpp
+++ b/services/stats/StatsAidl.cpp
@@ -66,6 +66,61 @@
AStatsEvent_writeBool(event,
atomValue.get<VendorAtomValue::boolValue>());
break;
+ case VendorAtomValue::repeatedIntValue: {
+ const std::optional<std::vector<int>>& repeatedIntValue =
+ atomValue.get<VendorAtomValue::repeatedIntValue>();
+ AStatsEvent_writeInt32Array(event, repeatedIntValue->data(),
+ repeatedIntValue->size());
+ break;
+ }
+ case VendorAtomValue::repeatedLongValue: {
+ const std::optional<std::vector<int64_t>>& repeatedLongValue =
+ atomValue.get<VendorAtomValue::repeatedLongValue>();
+ AStatsEvent_writeInt64Array(event, repeatedLongValue->data(),
+ repeatedLongValue->size());
+ break;
+ }
+ case VendorAtomValue::repeatedFloatValue: {
+ const std::optional<std::vector<float>>& repeatedFloatValue =
+ atomValue.get<VendorAtomValue::repeatedFloatValue>();
+ AStatsEvent_writeFloatArray(event, repeatedFloatValue->data(),
+ repeatedFloatValue->size());
+ break;
+ }
+ case VendorAtomValue::repeatedStringValue: {
+ const std::optional<std::vector<std::optional<std::string>>>& repeatedStringValue =
+ atomValue.get<VendorAtomValue::repeatedStringValue>();
+ const std::vector<std::optional<std::string>>& repeatedStringVector =
+ *repeatedStringValue;
+ const char* cStringArray[repeatedStringVector.size()];
+
+ for (int i = 0; i < repeatedStringVector.size(); ++i) {
+ cStringArray[i] = repeatedStringVector[i]->c_str();
+ }
+
+ AStatsEvent_writeStringArray(event, cStringArray, repeatedStringVector.size());
+ break;
+ }
+ case VendorAtomValue::repeatedBoolValue: {
+ const std::optional<std::vector<bool>>& repeatedBoolValue =
+ atomValue.get<VendorAtomValue::repeatedBoolValue>();
+ const std::vector<bool>& repeatedBoolVector = *repeatedBoolValue;
+ bool boolArray[repeatedBoolValue->size()];
+
+ for (int i = 0; i < repeatedBoolVector.size(); ++i) {
+ boolArray[i] = repeatedBoolVector[i];
+ }
+
+ AStatsEvent_writeBoolArray(event, boolArray, repeatedBoolVector.size());
+ break;
+ }
+ case VendorAtomValue::byteArrayValue: {
+ const std::optional<std::vector<uint8_t>>& byteArrayValue =
+ atomValue.get<VendorAtomValue::byteArrayValue>();
+
+ AStatsEvent_writeByteArray(event, byteArrayValue->data(), byteArrayValue->size());
+ break;
+ }
}
}
AStatsEvent_build(event);
diff --git a/services/surfaceflinger/BufferStateLayer.h b/services/surfaceflinger/BufferStateLayer.h
deleted file mode 100644
index e53e1c1..0000000
--- a/services/surfaceflinger/BufferStateLayer.h
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * Copyright (C) 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 "Layer.h"
-
-namespace android {
-
-class BufferStateLayer : public Layer {
-public:
- explicit BufferStateLayer(const LayerCreationArgs& args) : Layer(args){};
-};
-
-} // namespace android
diff --git a/services/surfaceflinger/DisplayDevice.cpp b/services/surfaceflinger/DisplayDevice.cpp
index 029e449..a25296c 100644
--- a/services/surfaceflinger/DisplayDevice.cpp
+++ b/services/surfaceflinger/DisplayDevice.cpp
@@ -192,17 +192,16 @@
}
void DisplayDevice::setActiveMode(DisplayModeId modeId, const display::DisplaySnapshot& snapshot) {
- const auto modeOpt = snapshot.displayModes().get(modeId);
- LOG_ALWAYS_FATAL_IF(!modeOpt, "Unknown mode");
+ const auto fpsOpt = snapshot.displayModes().get(modeId).transform(
+ [](const DisplayModePtr& mode) { return mode->getFps(); });
- mActiveMode = modeOpt->get();
- const Fps fps = mActiveMode->getFps();
+ LOG_ALWAYS_FATAL_IF(!fpsOpt, "Unknown mode");
+ const Fps fps = *fpsOpt;
ATRACE_INT(mActiveModeFPSTrace.c_str(), fps.getIntValue());
- if (mRefreshRateConfigs) {
- mRefreshRateConfigs->setActiveModeId(modeId);
- }
+ mRefreshRateConfigs->setActiveModeId(modeId);
+
if (mRefreshRateOverlay) {
mRefreshRateOverlay->changeRefreshRate(fps);
}
@@ -224,10 +223,6 @@
constraints, outTimeline);
}
-const DisplayModePtr& DisplayDevice::getActiveMode() const {
- return mActiveMode;
-}
-
nsecs_t DisplayDevice::getVsyncPeriodFromHWC() const {
const auto physicalId = getPhysicalId();
if (!mHwComposer.isConnected(physicalId)) {
@@ -240,7 +235,7 @@
return vsyncPeriod;
}
- return getActiveMode()->getFps().getPeriodNsecs();
+ return refreshRateConfigs().getActiveModePtr()->getVsyncPeriod();
}
nsecs_t DisplayDevice::getRefreshTimestamp() const {
@@ -312,8 +307,10 @@
}
void DisplayDevice::persistBrightness(bool needsComposite) {
- if (needsComposite && mStagedBrightness && mBrightness != *mStagedBrightness) {
- getCompositionDisplay()->setNextBrightness(*mStagedBrightness);
+ if (mStagedBrightness && mBrightness != *mStagedBrightness) {
+ if (needsComposite) {
+ getCompositionDisplay()->setNextBrightness(*mStagedBrightness);
+ }
mBrightness = *mStagedBrightness;
}
mStagedBrightness = std::nullopt;
@@ -449,7 +446,7 @@
mRefreshRateOverlay = std::make_unique<RefreshRateOverlay>(fpsRange, showSpinnner);
mRefreshRateOverlay->setLayerStack(getLayerStack());
mRefreshRateOverlay->setViewport(getSize());
- mRefreshRateOverlay->changeRefreshRate(getActiveMode()->getFps());
+ mRefreshRateOverlay->changeRefreshRate(getActiveMode().getFps());
}
bool DisplayDevice::onKernelTimerChanged(std::optional<DisplayModeId> desiredModeId,
@@ -490,7 +487,7 @@
}
// Check if we are already at the desired mode
- if (getActiveMode()->getId() == info.mode->getId()) {
+ if (refreshRateConfigs().getActiveModePtr()->getId() == info.mode->getId()) {
return false;
}
diff --git a/services/surfaceflinger/DisplayDevice.h b/services/surfaceflinger/DisplayDevice.h
index d79a6b5..0f52aff 100644
--- a/services/surfaceflinger/DisplayDevice.h
+++ b/services/surfaceflinger/DisplayDevice.h
@@ -189,8 +189,6 @@
/* ------------------------------------------------------------------------
* Display mode management.
*/
- const DisplayModePtr& getActiveMode() const;
-
struct ActiveModeInfo {
DisplayModePtr mode;
scheduler::DisplayModeEvent event = scheduler::DisplayModeEvent::None;
@@ -207,6 +205,10 @@
return mUpcomingActiveMode;
}
+ const DisplayMode& getActiveMode() const REQUIRES(kMainThreadContext) {
+ return mRefreshRateConfigs->getActiveMode();
+ }
+
// Precondition: DisplaySnapshot must contain a mode with DisplayModeId.
void setActiveMode(DisplayModeId, const display::DisplaySnapshot&) REQUIRES(kMainThreadContext);
@@ -226,7 +228,7 @@
}
// Enables an overlay to be displayed with the current refresh rate
- void enableRefreshRateOverlay(bool enable, bool showSpinner);
+ void enableRefreshRateOverlay(bool enable, bool showSpinner) REQUIRES(kMainThreadContext);
bool isRefreshRateOverlayEnabled() const { return mRefreshRateOverlay != nullptr; }
bool onKernelTimerChanged(std::optional<DisplayModeId>, bool timerExpired);
void animateRefreshRateOverlay();
@@ -265,10 +267,10 @@
static ui::Transform::RotationFlags sPrimaryDisplayRotationFlags;
- // allow initial power mode as null.
+ // Allow nullopt as initial power mode.
std::optional<hardware::graphics::composer::hal::PowerMode> mPowerMode;
- DisplayModePtr mActiveMode;
- std::optional<float> mStagedBrightness = std::nullopt;
+
+ std::optional<float> mStagedBrightness;
float mBrightness = -1.f;
std::atomic<nsecs_t> mLastHwVsync = 0;
diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp
index 08b71c2..13437a4 100644
--- a/services/surfaceflinger/Layer.cpp
+++ b/services/surfaceflinger/Layer.cpp
@@ -65,7 +65,6 @@
#include <mutex>
#include <sstream>
-#include "BufferStateLayer.h"
#include "DisplayDevice.h"
#include "DisplayHardware/HWComposer.h"
#include "FrameTimeline.h"
@@ -165,7 +164,6 @@
mLayerCreationFlags(args.flags),
mBorderEnabled(false),
mTextureName(args.textureName),
- mCompositionState{mFlinger->getCompositionEngine().createLayerFECompositionState()},
mHwcSlotGenerator(sp<HwcSlotGenerator>::make()) {
ALOGV("Creating Layer %s", getDebugName());
@@ -239,6 +237,12 @@
mPotentialCursor = args.flags & ISurfaceComposerClient::eCursorWindow;
mProtectedByApp = args.flags & ISurfaceComposerClient::eProtectedByApp;
mDrawingState.dataspace = ui::Dataspace::V0_SRGB;
+
+ mSnapshot->sequence = sequence;
+ mSnapshot->name = getDebugName();
+ mSnapshot->textureName = mTextureName;
+ mSnapshot->premultipliedAlpha = mPremultipliedAlpha;
+ mSnapshot->transform = {};
}
void Layer::onFirstRef() {
@@ -504,40 +508,40 @@
: Hwc2::IComposerClient::BlendMode::COVERAGE;
}
- auto* compositionState = editCompositionState();
- compositionState->outputFilter = getOutputFilter();
- compositionState->isVisible = isVisible();
- compositionState->isOpaque = opaque && !usesRoundedCorners && alpha == 1.f;
- compositionState->shadowRadius = mEffectiveShadowRadius;
+ auto* snapshot = editLayerSnapshot();
+ snapshot->outputFilter = getOutputFilter();
+ snapshot->isVisible = isVisible();
+ snapshot->isOpaque = opaque && !usesRoundedCorners && alpha == 1.f;
+ snapshot->shadowRadius = mEffectiveShadowRadius;
- compositionState->contentDirty = contentDirty;
+ snapshot->contentDirty = contentDirty;
contentDirty = false;
- compositionState->geomLayerBounds = mBounds;
- compositionState->geomLayerTransform = getTransform();
- compositionState->geomInverseLayerTransform = compositionState->geomLayerTransform.inverse();
- compositionState->transparentRegionHint = getActiveTransparentRegion(drawingState);
+ snapshot->geomLayerBounds = mBounds;
+ snapshot->geomLayerTransform = getTransform();
+ snapshot->geomInverseLayerTransform = snapshot->geomLayerTransform.inverse();
+ snapshot->transparentRegionHint = getActiveTransparentRegion(drawingState);
- compositionState->blendMode = static_cast<Hwc2::IComposerClient::BlendMode>(blendMode);
- compositionState->alpha = alpha;
- compositionState->backgroundBlurRadius = drawingState.backgroundBlurRadius;
- compositionState->blurRegions = drawingState.blurRegions;
- compositionState->stretchEffect = getStretchEffect();
+ snapshot->blendMode = static_cast<Hwc2::IComposerClient::BlendMode>(blendMode);
+ snapshot->alpha = alpha;
+ snapshot->backgroundBlurRadius = drawingState.backgroundBlurRadius;
+ snapshot->blurRegions = drawingState.blurRegions;
+ snapshot->stretchEffect = getStretchEffect();
}
void Layer::prepareGeometryCompositionState() {
const auto& drawingState{getDrawingState()};
- auto* compositionState = editCompositionState();
+ auto* snapshot = editLayerSnapshot();
- compositionState->geomBufferSize = getBufferSize(drawingState);
- compositionState->geomContentCrop = getBufferCrop();
- compositionState->geomCrop = getCrop(drawingState);
- compositionState->geomBufferTransform = getBufferTransform();
- compositionState->geomBufferUsesDisplayInverseTransform = getTransformToDisplayInverse();
- compositionState->geomUsesSourceCrop = usesSourceCrop();
- compositionState->isSecure = isSecure();
+ snapshot->geomBufferSize = getBufferSize(drawingState);
+ snapshot->geomContentCrop = getBufferCrop();
+ snapshot->geomCrop = getCrop(drawingState);
+ snapshot->geomBufferTransform = getBufferTransform();
+ snapshot->geomBufferUsesDisplayInverseTransform = getTransformToDisplayInverse();
+ snapshot->geomUsesSourceCrop = usesSourceCrop();
+ snapshot->isSecure = isSecure();
- compositionState->metadata.clear();
+ snapshot->metadata.clear();
const auto& supportedMetadata = mFlinger->getHwComposer().getSupportedLayerGenericMetadata();
for (const auto& [key, mandatory] : supportedMetadata) {
const auto& genericLayerMetadataCompatibilityMap =
@@ -553,45 +557,45 @@
continue;
}
- compositionState->metadata
- .emplace(key, compositionengine::GenericLayerMetadataEntry{mandatory, it->second});
+ snapshot->metadata.emplace(key,
+ compositionengine::GenericLayerMetadataEntry{mandatory,
+ it->second});
}
}
void Layer::preparePerFrameCompositionState() {
const auto& drawingState{getDrawingState()};
- auto* compositionState = editCompositionState();
+ auto* snapshot = editLayerSnapshot();
- compositionState->forceClientComposition = false;
+ snapshot->forceClientComposition = false;
- compositionState->isColorspaceAgnostic = isColorSpaceAgnostic();
- compositionState->dataspace = getDataSpace();
- compositionState->colorTransform = getColorTransform();
- compositionState->colorTransformIsIdentity = !hasColorTransform();
- compositionState->surfaceDamage = surfaceDamageRegion;
- compositionState->hasProtectedContent = isProtected();
- compositionState->dimmingEnabled = isDimmingEnabled();
+ snapshot->isColorspaceAgnostic = isColorSpaceAgnostic();
+ snapshot->dataspace = getDataSpace();
+ snapshot->colorTransform = getColorTransform();
+ snapshot->colorTransformIsIdentity = !hasColorTransform();
+ snapshot->surfaceDamage = surfaceDamageRegion;
+ snapshot->hasProtectedContent = isProtected();
+ snapshot->dimmingEnabled = isDimmingEnabled();
const bool usesRoundedCorners = hasRoundedCorners();
- compositionState->isOpaque =
- isOpaque(drawingState) && !usesRoundedCorners && getAlpha() == 1.0_hf;
+ snapshot->isOpaque = isOpaque(drawingState) && !usesRoundedCorners && getAlpha() == 1.0_hf;
// Force client composition for special cases known only to the front-end.
// Rounded corners no longer force client composition, since we may use a
// hole punch so that the layer will appear to have rounded corners.
if (isHdrY410() || drawShadows() || drawingState.blurRegions.size() > 0 ||
- compositionState->stretchEffect.hasEffect()) {
- compositionState->forceClientComposition = true;
+ snapshot->stretchEffect.hasEffect()) {
+ snapshot->forceClientComposition = true;
}
// If there are no visible region changes, we still need to update blur parameters.
- compositionState->blurRegions = drawingState.blurRegions;
- compositionState->backgroundBlurRadius = drawingState.backgroundBlurRadius;
+ snapshot->blurRegions = drawingState.blurRegions;
+ snapshot->backgroundBlurRadius = drawingState.backgroundBlurRadius;
// Layer framerate is used in caching decisions.
// Retrieve it from the scheduler which maintains an instance of LayerHistory, and store it in
// LayerFECompositionState where it would be visible to Flattener.
- compositionState->fps = mFlinger->getLayerFramerate(systemTime(), getSequence());
+ snapshot->fps = mFlinger->getLayerFramerate(systemTime(), getSequence());
if (hasBufferOrSidebandStream()) {
preparePerFrameBufferCompositionState();
@@ -602,41 +606,41 @@
void Layer::preparePerFrameBufferCompositionState() {
// Sideband layers
- auto* compositionState = editCompositionState();
- if (compositionState->sidebandStream.get() && !compositionState->sidebandStreamHasFrame) {
- compositionState->compositionType =
+ auto* snapshot = editLayerSnapshot();
+ if (snapshot->sidebandStream.get() && !snapshot->sidebandStreamHasFrame) {
+ snapshot->compositionType =
aidl::android::hardware::graphics::composer3::Composition::SIDEBAND;
return;
} else if ((mDrawingState.flags & layer_state_t::eLayerIsDisplayDecoration) != 0) {
- compositionState->compositionType =
+ snapshot->compositionType =
aidl::android::hardware::graphics::composer3::Composition::DISPLAY_DECORATION;
} else {
// Normal buffer layers
- compositionState->hdrMetadata = mBufferInfo.mHdrMetadata;
- compositionState->compositionType = mPotentialCursor
+ snapshot->hdrMetadata = mBufferInfo.mHdrMetadata;
+ snapshot->compositionType = mPotentialCursor
? aidl::android::hardware::graphics::composer3::Composition::CURSOR
: aidl::android::hardware::graphics::composer3::Composition::DEVICE;
}
- compositionState->buffer = getBuffer();
- compositionState->bufferSlot = (mBufferInfo.mBufferSlot == BufferQueue::INVALID_BUFFER_SLOT)
+ snapshot->buffer = getBuffer();
+ snapshot->bufferSlot = (mBufferInfo.mBufferSlot == BufferQueue::INVALID_BUFFER_SLOT)
? 0
: mBufferInfo.mBufferSlot;
- compositionState->acquireFence = mBufferInfo.mFence;
- compositionState->frameNumber = mBufferInfo.mFrameNumber;
- compositionState->sidebandStreamHasFrame = false;
+ snapshot->acquireFence = mBufferInfo.mFence;
+ snapshot->frameNumber = mBufferInfo.mFrameNumber;
+ snapshot->sidebandStreamHasFrame = false;
}
void Layer::preparePerFrameEffectsCompositionState() {
- auto* compositionState = editCompositionState();
- compositionState->color = getColor();
- compositionState->compositionType =
+ auto* snapshot = editLayerSnapshot();
+ snapshot->color = getColor();
+ snapshot->compositionType =
aidl::android::hardware::graphics::composer3::Composition::SOLID_COLOR;
}
void Layer::prepareCursorCompositionState() {
const State& drawingState{getDrawingState()};
- auto* compositionState = editCompositionState();
+ auto* snapshot = editLayerSnapshot();
// Apply the layer's transform, followed by the display's global transform
// Here we're guaranteed that the layer's transform preserves rects
@@ -645,7 +649,7 @@
Rect bounds = reduce(win, getActiveTransparentRegion(drawingState));
Rect frame(getTransform().transform(bounds));
- compositionState->cursorFrame = frame;
+ snapshot->cursorFrame = frame;
}
sp<compositionengine::LayerFE> Layer::asLayerFE() const {
@@ -687,31 +691,30 @@
compositionengine::LayerFE::ClientCompositionTargetSettings& targetSettings) const {
ATRACE_CALL();
- if (!getCompositionState()) {
+ const auto* snapshot = getLayerSnapshot();
+ if (!snapshot) {
return {};
}
- FloatRect bounds = getBounds();
- half alpha = getAlpha();
-
compositionengine::LayerFE::LayerSettings layerSettings;
- layerSettings.geometry.boundaries = bounds;
- layerSettings.geometry.positionTransform = getTransform().asMatrix4();
+ layerSettings.geometry.boundaries =
+ reduce(snapshot->geomLayerBounds, snapshot->transparentRegionHint);
+ layerSettings.geometry.positionTransform = snapshot->geomLayerTransform.asMatrix4();
// skip drawing content if the targetSettings indicate the content will be occluded
const bool drawContent = targetSettings.realContentIsVisible || targetSettings.clearContent;
layerSettings.skipContentDraw = !drawContent;
if (hasColorTransform()) {
- layerSettings.colorTransform = getColorTransform();
+ layerSettings.colorTransform = snapshot->colorTransform;
}
- const auto roundedCornerState = getRoundedCornerState();
+ const auto& roundedCornerState = snapshot->roundedCorner;
layerSettings.geometry.roundedCornersRadius = roundedCornerState.radius;
layerSettings.geometry.roundedCornersCrop = roundedCornerState.cropRect;
- layerSettings.alpha = alpha;
- layerSettings.sourceDataspace = getDataSpace();
+ layerSettings.alpha = snapshot->alpha;
+ layerSettings.sourceDataspace = snapshot->dataspace;
// Override the dataspace transfer from 170M to sRGB if the device configuration requests this.
// We do this here instead of in buffer info so that dumpsys can still report layers that are
@@ -728,26 +731,24 @@
layerSettings.whitePointNits = targetSettings.whitePointNits;
switch (targetSettings.blurSetting) {
case LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled:
- layerSettings.backgroundBlurRadius = getBackgroundBlurRadius();
- layerSettings.blurRegions = getBlurRegions();
- layerSettings.blurRegionTransform =
- getActiveTransform(getDrawingState()).inverse().asMatrix4();
+ layerSettings.backgroundBlurRadius = snapshot->backgroundBlurRadius;
+ layerSettings.blurRegions = snapshot->blurRegions;
+ layerSettings.blurRegionTransform = snapshot->geomInverseLayerTransform.asMatrix4();
break;
case LayerFE::ClientCompositionTargetSettings::BlurSetting::BackgroundBlurOnly:
- layerSettings.backgroundBlurRadius = getBackgroundBlurRadius();
+ layerSettings.backgroundBlurRadius = snapshot->backgroundBlurRadius;
break;
case LayerFE::ClientCompositionTargetSettings::BlurSetting::BlurRegionsOnly:
- layerSettings.blurRegions = getBlurRegions();
- layerSettings.blurRegionTransform =
- getActiveTransform(getDrawingState()).inverse().asMatrix4();
+ layerSettings.blurRegions = snapshot->blurRegions;
+ layerSettings.blurRegionTransform = snapshot->geomInverseLayerTransform.asMatrix4();
break;
case LayerFE::ClientCompositionTargetSettings::BlurSetting::Disabled:
default:
break;
}
- layerSettings.stretchEffect = getStretchEffect();
+ layerSettings.stretchEffect = snapshot->stretchEffect;
// Record the name of the layer for debugging further down the stack.
- layerSettings.name = getName();
+ layerSettings.name = snapshot->name;
if (hasEffect() && !hasBufferOrSidebandStream()) {
prepareEffectsClientComposition(layerSettings, targetSettings);
@@ -768,7 +769,7 @@
// If layer is blacked out, force alpha to 1 so that we draw a black color layer.
layerSettings.alpha = blackout ? 1.0f : 0.0f;
- layerSettings.name = getName();
+ layerSettings.name = getLayerSnapshot()->name;
}
void Layer::prepareEffectsClientComposition(
@@ -786,39 +787,41 @@
void Layer::prepareBufferStateClientComposition(
compositionengine::LayerFE::LayerSettings& layerSettings,
compositionengine::LayerFE::ClientCompositionTargetSettings& targetSettings) const {
- if (CC_UNLIKELY(!mBufferInfo.mBuffer)) {
- // For surfaceview of tv sideband, there is no activeBuffer
- // in bufferqueue, we need return LayerSettings.
+ ATRACE_CALL();
+ const auto* snapshot = getLayerSnapshot();
+ if (CC_UNLIKELY(!snapshot->externalTexture)) {
+ // If there is no buffer for the layer or we have sidebandstream where there is no
+ // activeBuffer, then we need to return LayerSettings.
return;
}
- const bool blackOutLayer = (isProtected() && !targetSettings.supportsProtectedContent) ||
- ((isSecure() || isProtected()) && !targetSettings.isSecure);
+ const bool blackOutLayer =
+ (snapshot->hasProtectedContent && !targetSettings.supportsProtectedContent) ||
+ ((snapshot->isSecure || snapshot->hasProtectedContent) && !targetSettings.isSecure);
const bool bufferCanBeUsedAsHwTexture =
- mBufferInfo.mBuffer->getUsage() & GraphicBuffer::USAGE_HW_TEXTURE;
+ snapshot->externalTexture->getUsage() & GraphicBuffer::USAGE_HW_TEXTURE;
if (blackOutLayer || !bufferCanBeUsedAsHwTexture) {
ALOGE_IF(!bufferCanBeUsedAsHwTexture, "%s is blacked out as buffer is not gpu readable",
- mName.c_str());
+ snapshot->name.c_str());
prepareClearClientComposition(layerSettings, true /* blackout */);
return;
}
- const State& s(getDrawingState());
- layerSettings.source.buffer.buffer = mBufferInfo.mBuffer;
- layerSettings.source.buffer.isOpaque = isOpaque(s);
- layerSettings.source.buffer.fence = mBufferInfo.mFence;
- layerSettings.source.buffer.textureName = mTextureName;
- layerSettings.source.buffer.usePremultipliedAlpha = getPremultipledAlpha();
- layerSettings.source.buffer.isY410BT2020 = isHdrY410();
- bool hasSmpte2086 = mBufferInfo.mHdrMetadata.validTypes & HdrMetadata::SMPTE2086;
- bool hasCta861_3 = mBufferInfo.mHdrMetadata.validTypes & HdrMetadata::CTA861_3;
+ layerSettings.source.buffer.buffer = snapshot->externalTexture;
+ layerSettings.source.buffer.isOpaque = snapshot->contentOpaque;
+ layerSettings.source.buffer.fence = snapshot->acquireFence;
+ layerSettings.source.buffer.textureName = snapshot->textureName;
+ layerSettings.source.buffer.usePremultipliedAlpha = snapshot->premultipliedAlpha;
+ layerSettings.source.buffer.isY410BT2020 = snapshot->isHdrY410;
+ bool hasSmpte2086 = snapshot->hdrMetadata.validTypes & HdrMetadata::SMPTE2086;
+ bool hasCta861_3 = snapshot->hdrMetadata.validTypes & HdrMetadata::CTA861_3;
float maxLuminance = 0.f;
if (hasSmpte2086 && hasCta861_3) {
- maxLuminance = std::min(mBufferInfo.mHdrMetadata.smpte2086.maxLuminance,
- mBufferInfo.mHdrMetadata.cta8613.maxContentLightLevel);
+ maxLuminance = std::min(snapshot->hdrMetadata.smpte2086.maxLuminance,
+ snapshot->hdrMetadata.cta8613.maxContentLightLevel);
} else if (hasSmpte2086) {
- maxLuminance = mBufferInfo.mHdrMetadata.smpte2086.maxLuminance;
+ maxLuminance = snapshot->hdrMetadata.smpte2086.maxLuminance;
} else if (hasCta861_3) {
- maxLuminance = mBufferInfo.mHdrMetadata.cta8613.maxContentLightLevel;
+ maxLuminance = snapshot->hdrMetadata.cta8613.maxContentLightLevel;
} else {
switch (layerSettings.sourceDataspace & HAL_DATASPACE_TRANSFER_MASK) {
case HAL_DATASPACE_TRANSFER_ST2084:
@@ -829,17 +832,17 @@
}
}
layerSettings.source.buffer.maxLuminanceNits = maxLuminance;
- layerSettings.frameNumber = mCurrentFrameNumber;
- layerSettings.bufferId = mBufferInfo.mBuffer ? mBufferInfo.mBuffer->getId() : 0;
+ layerSettings.frameNumber = snapshot->frameNumber;
+ layerSettings.bufferId = snapshot->externalTexture->getId();
- const bool useFiltering =
- targetSettings.needsFiltering || mNeedsFiltering || bufferNeedsFiltering();
+ const bool useFiltering = targetSettings.needsFiltering ||
+ snapshot->geomLayerTransform.needsBilinearFiltering() || snapshot->bufferNeedsFiltering;
// Query the texture matrix given our current filtering mode.
float textureMatrix[16];
getDrawingTransformMatrix(useFiltering, textureMatrix);
- if (getTransformToDisplayInverse()) {
+ if (snapshot->geomBufferUsesDisplayInverseTransform) {
/*
* the code below applies the primary display's inverse transform to
* the texture transform
@@ -856,25 +859,22 @@
* of a camera where the buffer remains in native orientation,
* we want the pixels to always be upright.
*/
- sp<Layer> p = mDrawingParent.promote();
- if (p != nullptr) {
- const auto parentTransform = p->getTransform();
- tr = tr * inverseOrientation(parentTransform.getOrientation());
- }
+ const auto parentTransform = snapshot->transform;
+ tr = tr * inverseOrientation(parentTransform.getOrientation());
// and finally apply it to the original texture matrix
const mat4 texTransform(mat4(static_cast<const float*>(textureMatrix)) * tr);
memcpy(textureMatrix, texTransform.asArray(), sizeof(textureMatrix));
}
- const Rect win{getBounds()};
- float bufferWidth = getBufferSize(s).getWidth();
- float bufferHeight = getBufferSize(s).getHeight();
+ const Rect win{layerSettings.geometry.boundaries};
+ float bufferWidth = snapshot->bufferSize.getWidth();
+ float bufferHeight = snapshot->bufferSize.getHeight();
- // BufferStateLayers can have a "buffer size" of [0, 0, -1, -1] when no display frame has
+ // Layers can have a "buffer size" of [0, 0, -1, -1] when no display frame has
// been set and there is no parent layer bounds. In that case, the scale is meaningless so
// ignore them.
- if (!getBufferSize(s).isValid()) {
+ if (!snapshot->bufferSize.isValid()) {
bufferWidth = float(win.right) - float(win.left);
bufferHeight = float(win.bottom) - float(win.top);
}
@@ -2182,35 +2182,17 @@
void Layer::prepareShadowClientComposition(LayerFE::LayerSettings& caster,
const Rect& layerStackRect) const {
- renderengine::ShadowSettings state = mFlinger->mDrawingState.globalShadowSettings;
-
- // Note: this preserves existing behavior of shadowing the entire layer and not cropping it if
- // transparent regions are present. This may not be necessary since shadows are typically cast
- // by layers without transparent regions.
- state.boundaries = mBounds;
+ const auto* snapshot = getLayerSnapshot();
+ renderengine::ShadowSettings state = snapshot->shadowSettings;
+ if (state.length <= 0.f || (state.ambientColor.a <= 0.f && state.spotColor.a <= 0.f)) {
+ return;
+ }
// Shift the spot light x-position to the middle of the display and then
// offset it by casting layer's screen pos.
- state.lightPos.x = (layerStackRect.width() / 2.f) - mScreenBounds.left;
- state.lightPos.y -= mScreenBounds.top;
-
- state.length = mEffectiveShadowRadius;
-
- if (state.length > 0.f) {
- const float casterAlpha = caster.alpha;
- const bool casterIsOpaque =
- ((caster.source.buffer.buffer != nullptr) && caster.source.buffer.isOpaque);
-
- // If the casting layer is translucent, we need to fill in the shadow underneath the layer.
- // Otherwise the generated shadow will only be shown around the casting layer.
- state.casterIsTranslucent = !casterIsOpaque || (casterAlpha < 1.0f);
- state.ambientColor *= casterAlpha;
- state.spotColor *= casterAlpha;
-
- if (state.ambientColor.a > 0.f && state.spotColor.a > 0.f) {
- caster.shadow = state;
- }
- }
+ state.lightPos.x = (layerStackRect.width() / 2.f) - snapshot->transformedBounds.left;
+ state.lightPos.y -= snapshot->transformedBounds.top;
+ caster.shadow = state;
}
bool Layer::findInHierarchy(const sp<Layer>& l) {
@@ -3035,17 +3017,6 @@
mFlinger->getTransactionCallbackInvoker().addCallbackHandles(mDrawingState.callbackHandles,
jankData);
-
- sp<Fence> releaseFence = Fence::NO_FENCE;
- for (auto& handle : mDrawingState.callbackHandles) {
- if (handle->releasePreviousBuffer &&
- mDrawingState.releaseBufferEndpoint == handle->listener) {
- releaseFence =
- handle->previousReleaseFence ? handle->previousReleaseFence : Fence::NO_FENCE;
- break;
- }
- }
-
mDrawingState.callbackHandles = {};
}
@@ -3177,8 +3148,7 @@
const BufferData& bufferData, nsecs_t postTime, nsecs_t desiredPresentTime,
bool isAutoTimestamp, std::optional<nsecs_t> dequeueTime,
const FrameTimelineInfo& info) {
- ATRACE_CALL();
-
+ ATRACE_FORMAT("setBuffer %s - hasBuffer=%s", getDebugName(), (buffer ? "true" : "false"));
if (!buffer) {
return false;
}
@@ -3187,6 +3157,7 @@
bufferData.flags.test(BufferData::BufferDataChange::frameNumberChanged);
const uint64_t frameNumber =
frameNumberChanged ? bufferData.frameNumber : mDrawingState.frameNumber + 1;
+ ATRACE_FORMAT_INSTANT("setBuffer %s - %" PRIu64, getDebugName(), frameNumber);
if (mDrawingState.buffer) {
mReleasePreviousBuffer = true;
@@ -3419,13 +3390,14 @@
bool Layer::latchSidebandStream(bool& recomputeVisibleRegions) {
// We need to update the sideband stream if the layer has both a buffer and a sideband stream.
- editCompositionState()->sidebandStreamHasFrame = hasFrameUpdate() && mSidebandStream.get();
+ auto* snapshot = editLayerSnapshot();
+ snapshot->sidebandStreamHasFrame = hasFrameUpdate() && mSidebandStream.get();
if (mSidebandStreamChanged.exchange(false)) {
const State& s(getDrawingState());
// mSidebandStreamChanged was true
mSidebandStream = s.sidebandStream;
- editCompositionState()->sidebandStream = mSidebandStream;
+ snapshot->sidebandStream = mSidebandStream;
if (mSidebandStream != nullptr) {
setTransactionFlags(eTransactionNeeded);
mFlinger->setTransactionFlags(eTraversalNeeded);
@@ -3538,7 +3510,7 @@
sp<Layer> Layer::createClone() {
LayerCreationArgs args(mFlinger.get(), nullptr, mName + " (Mirror)", 0, LayerMetadata());
args.textureName = mTextureName;
- sp<BufferStateLayer> layer = mFlinger->getFactory().createBufferStateLayer(args);
+ sp<Layer> layer = mFlinger->getFactory().createBufferStateLayer(args);
layer->mHwcSlotGenerator = mHwcSlotGenerator;
layer->setInitialValuesForClone(sp<Layer>::fromExisting(this));
return layer;
@@ -3825,12 +3797,15 @@
}
}
-compositionengine::LayerFECompositionState* Layer::editCompositionState() {
- return mCompositionState.get();
+const Layer::LayerSnapshot* Layer::getLayerSnapshot() const {
+ return mSnapshot.get();
}
+Layer::LayerSnapshot* Layer::editLayerSnapshot() {
+ return mSnapshot.get();
+}
const compositionengine::LayerFECompositionState* Layer::getCompositionState() const {
- return mCompositionState.get();
+ return mSnapshot.get();
}
void Layer::useSurfaceDamage() {
@@ -4225,10 +4200,44 @@
return;
}
+ auto* snapshot = editLayerSnapshot();
if (updateGeometry) {
prepareBasicGeometryCompositionState();
prepareGeometryCompositionState();
+ snapshot->roundedCorner = getRoundedCornerState();
+ snapshot->stretchEffect = getStretchEffect();
+ snapshot->transformedBounds = mScreenBounds;
+ if (mEffectiveShadowRadius > 0.f) {
+ snapshot->shadowSettings = mFlinger->mDrawingState.globalShadowSettings;
+
+ // Note: this preserves existing behavior of shadowing the entire layer and not cropping
+ // it if transparent regions are present. This may not be necessary since shadows are
+ // typically cast by layers without transparent regions.
+ snapshot->shadowSettings.boundaries = mBounds;
+
+ const float casterAlpha = snapshot->alpha;
+ const bool casterIsOpaque =
+ ((mBufferInfo.mBuffer != nullptr) && isOpaque(mDrawingState));
+
+ // If the casting layer is translucent, we need to fill in the shadow underneath the
+ // layer. Otherwise the generated shadow will only be shown around the casting layer.
+ snapshot->shadowSettings.casterIsTranslucent = !casterIsOpaque || (casterAlpha < 1.0f);
+ snapshot->shadowSettings.ambientColor *= casterAlpha;
+ snapshot->shadowSettings.spotColor *= casterAlpha;
+ }
+ snapshot->shadowSettings.length = mEffectiveShadowRadius;
}
+ snapshot->contentOpaque = isOpaque(mDrawingState);
+ snapshot->isHdrY410 = isHdrY410();
+ snapshot->bufferNeedsFiltering = bufferNeedsFiltering();
+ sp<Layer> p = mDrawingParent.promote();
+ if (p != nullptr) {
+ snapshot->transform = p->getTransform();
+ } else {
+ snapshot->transform.reset();
+ }
+ snapshot->bufferSize = getBufferSize(mDrawingState);
+ snapshot->externalTexture = mBufferInfo.mBuffer;
preparePerFrameCompositionState();
}
diff --git a/services/surfaceflinger/Layer.h b/services/surfaceflinger/Layer.h
index 5030fd8..4079d16 100644
--- a/services/surfaceflinger/Layer.h
+++ b/services/surfaceflinger/Layer.h
@@ -38,6 +38,7 @@
#include <utils/Timers.h>
#include <compositionengine/LayerFE.h>
+#include <compositionengine/LayerFECompositionState.h>
#include <scheduler/Fps.h>
#include <scheduler/Seamlessness.h>
@@ -144,6 +145,29 @@
bool hasRoundedCorners() const { return radius.x > 0.0f && radius.y > 0.0f; }
};
+ // LayerSnapshot stores Layer state used by Composition Engine and Render Engine. Composition
+ // Engine uses a pointer to LayerSnapshot (as LayerFECompositionState*) and the LayerSettings
+ // passed to Render Engine are created using properties stored on this struct.
+ //
+ // TODO(b/238781169) Implement LayerFE as a separate subclass. Migrate LayerSnapshot to that
+ // LayerFE subclass.
+ struct LayerSnapshot : public compositionengine::LayerFECompositionState {
+ int32_t sequence;
+ std::string name;
+ uint32_t textureName;
+ bool contentOpaque;
+ RoundedCornerState roundedCorner;
+ StretchEffect stretchEffect;
+ FloatRect transformedBounds;
+ renderengine::ShadowSettings shadowSettings;
+ bool premultipliedAlpha;
+ bool isHdrY410;
+ bool bufferNeedsFiltering;
+ ui::Transform transform;
+ Rect bufferSize;
+ std::shared_ptr<renderengine::ExternalTexture> externalTexture;
+ };
+
using FrameRate = scheduler::LayerInfo::FrameRate;
using FrameRateCompatibility = scheduler::LayerInfo::FrameRateCompatibility;
@@ -392,7 +416,9 @@
ui::Dataspace getRequestedDataSpace() const;
virtual sp<compositionengine::LayerFE> getCompositionEngineLayerFE() const;
- compositionengine::LayerFECompositionState* editCompositionState();
+
+ const LayerSnapshot* getLayerSnapshot() const;
+ LayerSnapshot* editLayerSnapshot();
// If we have received a new buffer this frame, we will pass its surface
// damage down to hardware composer. Otherwise, we must send a region with
@@ -867,6 +893,13 @@
bool simpleBufferUpdate(const layer_state_t&) const;
static bool isOpaqueFormat(PixelFormat format);
+
+ // Updates the LayerSnapshot. This must be called prior to sending layer data to
+ // CompositionEngine or RenderEngine (i.e. before calling CompositionEngine::present or
+ // Layer::prepareClientComposition).
+ //
+ // TODO(b/238781169) Remove direct calls to RenderEngine::drawLayers that don't go through
+ // CompositionEngine to create a single path for composing layers.
void updateSnapshot(bool updateGeometry);
protected:
@@ -1166,8 +1199,6 @@
// the mStateLock.
ui::Transform::RotationFlags mTransformHint = ui::Transform::ROT_0;
- std::unique_ptr<compositionengine::LayerFECompositionState> mCompositionState;
-
ReleaseCallbackId mPreviousReleaseCallbackId = ReleaseCallbackId::INVALID_ID;
uint64_t mPreviousReleasedFrameNumber = 0;
@@ -1200,6 +1231,8 @@
ui::Transform mRequestedTransform;
sp<HwcSlotGenerator> mHwcSlotGenerator;
+
+ std::unique_ptr<LayerSnapshot> mSnapshot = std::make_unique<LayerSnapshot>();
};
std::ostream& operator<<(std::ostream& stream, const Layer::FrameRate& rate);
diff --git a/services/surfaceflinger/RegionSamplingThread.cpp b/services/surfaceflinger/RegionSamplingThread.cpp
index 5705255..8dd3b0f 100644
--- a/services/surfaceflinger/RegionSamplingThread.cpp
+++ b/services/surfaceflinger/RegionSamplingThread.cpp
@@ -203,25 +203,14 @@
return 0.0f;
}
- // (b/133849373) ROT_90 screencap images produced upside down
- auto area = sample_area;
- if (orientation & ui::Transform::ROT_90) {
- area.top = height - area.top;
- area.bottom = height - area.bottom;
- std::swap(area.top, area.bottom);
-
- area.left = width - area.left;
- area.right = width - area.right;
- std::swap(area.left, area.right);
- }
-
- const uint32_t pixelCount = (area.bottom - area.top) * (area.right - area.left);
+ const uint32_t pixelCount =
+ (sample_area.bottom - sample_area.top) * (sample_area.right - sample_area.left);
uint32_t accumulatedLuma = 0;
// Calculates luma with approximation of Rec. 709 primaries
- for (int32_t row = area.top; row < area.bottom; ++row) {
+ for (int32_t row = sample_area.top; row < sample_area.bottom; ++row) {
const uint32_t* rowBase = data + row * stride;
- for (int32_t column = area.left; column < area.right; ++column) {
+ for (int32_t column = sample_area.left; column < sample_area.right; ++column) {
uint32_t pixel = rowBase[column];
const uint32_t r = pixel & 0xFF;
const uint32_t g = (pixel >> 8) & 0xFF;
diff --git a/services/surfaceflinger/Scheduler/RefreshRateConfigs.cpp b/services/surfaceflinger/Scheduler/RefreshRateConfigs.cpp
index 00886f0..3cb052c 100644
--- a/services/surfaceflinger/Scheduler/RefreshRateConfigs.cpp
+++ b/services/surfaceflinger/Scheduler/RefreshRateConfigs.cpp
@@ -48,24 +48,6 @@
} fixedRateBelowThresholdLayersScore;
};
-template <typename Iterator>
-const DisplayModePtr& getMaxScoreRefreshRate(Iterator begin, Iterator end) {
- const auto it =
- std::max_element(begin, end, [](RefreshRateScore max, RefreshRateScore current) {
- const auto& [modeIt, overallScore, _] = current;
-
- std::string name = to_string(modeIt->second->getFps());
- ALOGV("%s scores %.2f", name.c_str(), overallScore);
-
- ATRACE_INT(name.c_str(), static_cast<int>(std::round(overallScore * 100)));
-
- constexpr float kEpsilon = 0.0001f;
- return overallScore > max.overallScore * (1 + kEpsilon);
- });
-
- return it->modeIt->second;
-}
-
constexpr RefreshRateConfigs::GlobalSignals kNoSignals;
std::string formatLayerInfo(const RefreshRateConfigs::LayerRequirement& layer, float weight) {
@@ -137,6 +119,34 @@
} // namespace
+struct RefreshRateConfigs::RefreshRateScoreComparator {
+ bool operator()(const RefreshRateScore& lhs, const RefreshRateScore& rhs) const {
+ const auto& [modeIt, overallScore, _] = lhs;
+
+ std::string name = to_string(modeIt->second->getFps());
+ ALOGV("%s sorting scores %.2f", name.c_str(), overallScore);
+
+ ATRACE_INT(name.c_str(), static_cast<int>(std::round(overallScore * 100)));
+
+ constexpr float kEpsilon = 0.0001f;
+ if (std::abs(overallScore - rhs.overallScore) > kEpsilon) {
+ return overallScore > rhs.overallScore;
+ }
+
+ // If overallScore tie we will pick the higher refresh rate if
+ // high refresh rate is the priority else the lower refresh rate.
+ if (refreshRateOrder == RefreshRateOrder::Descending) {
+ using fps_approx_ops::operator>;
+ return modeIt->second->getFps() > rhs.modeIt->second->getFps();
+ } else {
+ using fps_approx_ops::operator<;
+ return modeIt->second->getFps() < rhs.modeIt->second->getFps();
+ }
+ }
+
+ const RefreshRateOrder refreshRateOrder;
+};
+
std::string RefreshRateConfigs::Policy::toString() const {
return base::StringPrintf("{defaultModeId=%d, allowGroupSwitching=%s"
", primaryRange=%s, appRequestRange=%s}",
@@ -218,6 +228,13 @@
return 0;
}
+float RefreshRateConfigs::calculateRefreshRateScoreForFps(Fps refreshRate) const {
+ const float ratio =
+ refreshRate.getValue() / mAppRequestRefreshRates.back()->second->getFps().getValue();
+ // Use ratio^2 to get a lower score the more we get further from peak
+ return ratio * ratio;
+}
+
float RefreshRateConfigs::calculateLayerScoreLocked(const LayerRequirement& layer, Fps refreshRate,
bool isSeamlessSwitch) const {
// Slightly prefer seamless switches.
@@ -226,10 +243,7 @@
// If the layer wants Max, give higher score to the higher refresh rate
if (layer.vote == LayerVoteType::Max) {
- const auto& maxRefreshRate = mAppRequestRefreshRates.back()->second;
- const auto ratio = refreshRate.getValue() / maxRefreshRate->getFps().getValue();
- // use ratio^2 to get a lower score the more we get further from peak
- return ratio * ratio;
+ return calculateRefreshRateScoreForFps(refreshRate);
}
if (layer.vote == LayerVoteType::ExplicitExact) {
@@ -258,24 +272,24 @@
kNonExactMatchingPenalty;
}
-auto RefreshRateConfigs::getBestRefreshRate(const std::vector<LayerRequirement>& layers,
- GlobalSignals signals) const
- -> std::pair<DisplayModePtr, GlobalSignals> {
+auto RefreshRateConfigs::getRankedRefreshRates(const std::vector<LayerRequirement>& layers,
+ GlobalSignals signals) const
+ -> std::pair<std::vector<RefreshRateRanking>, GlobalSignals> {
std::lock_guard lock(mLock);
- if (mGetBestRefreshRateCache &&
- mGetBestRefreshRateCache->arguments == std::make_pair(layers, signals)) {
- return mGetBestRefreshRateCache->result;
+ if (mGetRankedRefreshRatesCache &&
+ mGetRankedRefreshRatesCache->arguments == std::make_pair(layers, signals)) {
+ return mGetRankedRefreshRatesCache->result;
}
- const auto result = getBestRefreshRateLocked(layers, signals);
- mGetBestRefreshRateCache = GetBestRefreshRateCache{{layers, signals}, result};
+ const auto result = getRankedRefreshRatesLocked(layers, signals);
+ mGetRankedRefreshRatesCache = GetRankedRefreshRatesCache{{layers, signals}, result};
return result;
}
-auto RefreshRateConfigs::getBestRefreshRateLocked(const std::vector<LayerRequirement>& layers,
- GlobalSignals signals) const
- -> std::pair<DisplayModePtr, GlobalSignals> {
+auto RefreshRateConfigs::getRankedRefreshRatesLocked(const std::vector<LayerRequirement>& layers,
+ GlobalSignals signals) const
+ -> std::pair<std::vector<RefreshRateRanking>, GlobalSignals> {
using namespace fps_approx_ops;
ATRACE_CALL();
ALOGV("%s: %zu layers", __func__, layers.size());
@@ -285,8 +299,8 @@
// Keep the display at max refresh rate for the duration of powering on the display.
if (signals.powerOnImminent) {
ALOGV("Power On Imminent");
- const auto& max = getMaxRefreshRateByPolicyLocked(activeMode.getGroup());
- return {max, GlobalSignals{.powerOnImminent = true}};
+ return {getRefreshRatesByPolicyLocked(activeMode.getGroup(), RefreshRateOrder::Descending),
+ GlobalSignals{.powerOnImminent = true}};
}
int noVoteLayers = 0;
@@ -295,7 +309,6 @@
int explicitDefaultVoteLayers = 0;
int explicitExactOrMultipleVoteLayers = 0;
int explicitExact = 0;
- float maxExplicitWeight = 0;
int seamedFocusedLayers = 0;
for (const auto& layer : layers) {
@@ -311,15 +324,12 @@
break;
case LayerVoteType::ExplicitDefault:
explicitDefaultVoteLayers++;
- maxExplicitWeight = std::max(maxExplicitWeight, layer.weight);
break;
case LayerVoteType::ExplicitExactOrMultiple:
explicitExactOrMultipleVoteLayers++;
- maxExplicitWeight = std::max(maxExplicitWeight, layer.weight);
break;
case LayerVoteType::ExplicitExact:
explicitExact++;
- maxExplicitWeight = std::max(maxExplicitWeight, layer.weight);
break;
case LayerVoteType::Heuristic:
break;
@@ -348,9 +358,9 @@
// Consider the touch event if there are no Explicit* layers. Otherwise wait until after we've
// selected a refresh rate to see if we should apply touch boost.
if (signals.touch && !hasExplicitVoteLayers) {
- const DisplayModePtr& max = getMaxRefreshRateByPolicyLocked(anchorGroup);
- ALOGV("TouchBoost - choose %s", to_string(max->getFps()).c_str());
- return {max, GlobalSignals{.touch = true}};
+ ALOGV("Touch Boost");
+ return {getRefreshRatesByPolicyLocked(anchorGroup, RefreshRateOrder::Descending),
+ GlobalSignals{.touch = true}};
}
// If the primary range consists of a single refresh rate then we can only
@@ -360,22 +370,22 @@
isApproxEqual(policy->primaryRange.min, policy->primaryRange.max);
if (!signals.touch && signals.idle && !(primaryRangeIsSingleRate && hasExplicitVoteLayers)) {
- const DisplayModePtr& min = getMinRefreshRateByPolicyLocked();
- ALOGV("Idle - choose %s", to_string(min->getFps()).c_str());
- return {min, GlobalSignals{.idle = true}};
+ ALOGV("Idle");
+ return {getRefreshRatesByPolicyLocked(activeMode.getGroup(), RefreshRateOrder::Ascending),
+ GlobalSignals{.idle = true}};
}
if (layers.empty() || noVoteLayers == layers.size()) {
- const DisplayModePtr& max = getMaxRefreshRateByPolicyLocked(anchorGroup);
- ALOGV("no layers with votes - choose %s", to_string(max->getFps()).c_str());
- return {max, kNoSignals};
+ ALOGV("No layers with votes");
+ return {getRefreshRatesByPolicyLocked(anchorGroup, RefreshRateOrder::Descending),
+ kNoSignals};
}
// Only if all layers want Min we should return Min
if (noVoteLayers + minVoteLayers == layers.size()) {
- const DisplayModePtr& min = getMinRefreshRateByPolicyLocked();
- ALOGV("all layers Min - choose %s", to_string(min->getFps()).c_str());
- return {min, kNoSignals};
+ ALOGV("All layers Min");
+ return {getRefreshRatesByPolicyLocked(activeMode.getGroup(), RefreshRateOrder::Ascending),
+ kNoSignals};
}
// Find the best refresh rate based on score
@@ -522,22 +532,29 @@
}
// Now that we scored all the refresh rates we need to pick the one that got the highest
- // overallScore. In case of a tie we will pick the higher refresh rate if any of the layers
- // wanted Max, or the lower otherwise.
- const DisplayModePtr& bestRefreshRate = maxVoteLayers > 0
- ? getMaxScoreRefreshRate(scores.rbegin(), scores.rend())
- : getMaxScoreRefreshRate(scores.begin(), scores.end());
+ // overallScore. Sort the scores based on their overallScore in descending order of priority.
+ const RefreshRateOrder refreshRateOrder =
+ maxVoteLayers > 0 ? RefreshRateOrder::Descending : RefreshRateOrder::Ascending;
+ std::sort(scores.begin(), scores.end(),
+ RefreshRateScoreComparator{.refreshRateOrder = refreshRateOrder});
+ std::vector<RefreshRateRanking> rankedRefreshRates;
+ rankedRefreshRates.reserve(scores.size());
+
+ std::transform(scores.begin(), scores.end(), back_inserter(rankedRefreshRates),
+ [](const RefreshRateScore& score) {
+ return RefreshRateRanking{score.modeIt->second, score.overallScore};
+ });
if (primaryRangeIsSingleRate) {
// If we never scored any layers, then choose the rate from the primary
// range instead of picking a random score from the app range.
if (std::all_of(scores.begin(), scores.end(),
[](RefreshRateScore score) { return score.overallScore == 0; })) {
- const DisplayModePtr& max = getMaxRefreshRateByPolicyLocked(anchorGroup);
- ALOGV("layers not scored - choose %s", to_string(max->getFps()).c_str());
- return {max, kNoSignals};
+ ALOGV("Layers not scored");
+ return {getRefreshRatesByPolicyLocked(anchorGroup, RefreshRateOrder::Descending),
+ kNoSignals};
} else {
- return {bestRefreshRate, kNoSignals};
+ return {rankedRefreshRates, kNoSignals};
}
}
@@ -545,8 +562,6 @@
// interactive (as opposed to ExplicitExactOrMultiple) and therefore if those posted an explicit
// vote we should not change it if we get a touch event. Only apply touch boost if it will
// actually increase the refresh rate over the normal selection.
- const DisplayModePtr& touchRefreshRate = getMaxRefreshRateByPolicyLocked(anchorGroup);
-
const bool touchBoostForExplicitExact = [&] {
if (mSupportsFrameRateOverrideByContent) {
// Enable touch boost if there are other layers besides exact
@@ -557,15 +572,18 @@
}
}();
+ const auto& touchRefreshRates =
+ getRefreshRatesByPolicyLocked(anchorGroup, RefreshRateOrder::Descending);
using fps_approx_ops::operator<;
if (signals.touch && explicitDefaultVoteLayers == 0 && touchBoostForExplicitExact &&
- bestRefreshRate->getFps() < touchRefreshRate->getFps()) {
- ALOGV("TouchBoost - choose %s", to_string(touchRefreshRate->getFps()).c_str());
- return {touchRefreshRate, GlobalSignals{.touch = true}};
+ scores.front().modeIt->second->getFps() <
+ touchRefreshRates.front().displayModePtr->getFps()) {
+ ALOGV("Touch Boost");
+ return {touchRefreshRates, GlobalSignals{.touch = true}};
}
- return {bestRefreshRate, kNoSignals};
+ return {rankedRefreshRates, kNoSignals};
}
std::unordered_map<uid_t, std::vector<const RefreshRateConfigs::LayerRequirement*>>
@@ -670,11 +688,13 @@
continue;
}
- // Now that we scored all the refresh rates we need to pick the one that got the highest
- // score.
+ // Now that we scored all the refresh rates we need to pick the lowest refresh rate
+ // that got the highest score.
const DisplayModePtr& bestRefreshRate =
- getMaxScoreRefreshRate(scores.begin(), scores.end());
-
+ std::min_element(scores.begin(), scores.end(),
+ RefreshRateScoreComparator{.refreshRateOrder =
+ RefreshRateOrder::Ascending})
+ ->modeIt->second;
frameRateOverrides.emplace(uid, bestRefreshRate->getFps());
}
@@ -715,16 +735,6 @@
return mPrimaryRefreshRates.front()->second;
}
-DisplayModePtr RefreshRateConfigs::getMaxRefreshRateByPolicy() const {
- std::lock_guard lock(mLock);
- return getMaxRefreshRateByPolicyLocked();
-}
-
-const DisplayModePtr& RefreshRateConfigs::getMaxRefreshRateByPolicyLocked() const {
- const int anchorGroup = getActiveModeItLocked()->second->getGroup();
- return getMaxRefreshRateByPolicyLocked(anchorGroup);
-}
-
const DisplayModePtr& RefreshRateConfigs::getMaxRefreshRateByPolicyLocked(int anchorGroup) const {
for (auto it = mPrimaryRefreshRates.rbegin(); it != mPrimaryRefreshRates.rend(); ++it) {
const auto& mode = (*it)->second;
@@ -733,14 +743,41 @@
}
}
- const auto& activeMode = *getActiveModeItLocked()->second;
- ALOGE("Can't find max refresh rate by policy with the same mode group as the current mode %s",
- to_string(activeMode).c_str());
+ ALOGE("Can't find max refresh rate by policy with the same group %d", anchorGroup);
// Default to the highest refresh rate.
return mPrimaryRefreshRates.back()->second;
}
+std::vector<RefreshRateRanking> RefreshRateConfigs::getRefreshRatesByPolicyLocked(
+ std::optional<int> anchorGroupOpt, RefreshRateOrder refreshRateOrder) const {
+ std::vector<RefreshRateRanking> rankings;
+ const auto makeRanking = [&](const DisplayModeIterator it) REQUIRES(mLock) {
+ const auto& mode = it->second;
+ const bool inverseScore = (refreshRateOrder == RefreshRateOrder::Ascending);
+ const float score = calculateRefreshRateScoreForFps(mode->getFps());
+ if (!anchorGroupOpt || mode->getGroup() == anchorGroupOpt) {
+ rankings.push_back(RefreshRateRanking{mode, inverseScore ? 1.0f / score : score});
+ }
+ };
+
+ if (refreshRateOrder == RefreshRateOrder::Ascending) {
+ std::for_each(mPrimaryRefreshRates.begin(), mPrimaryRefreshRates.end(), makeRanking);
+ } else {
+ std::for_each(mPrimaryRefreshRates.rbegin(), mPrimaryRefreshRates.rend(), makeRanking);
+ }
+
+ if (!rankings.empty() || !anchorGroupOpt) {
+ return rankings;
+ }
+
+ ALOGW("Can't find %s refresh rate by policy with the same mode group"
+ " as the mode group %d",
+ refreshRateOrder == RefreshRateOrder::Ascending ? "min" : "max", anchorGroupOpt.value());
+
+ return getRefreshRatesByPolicyLocked(/*anchorGroupOpt*/ std::nullopt, refreshRateOrder);
+}
+
DisplayModePtr RefreshRateConfigs::getActiveModePtr() const {
std::lock_guard lock(mLock);
return getActiveModeItLocked()->second;
@@ -760,9 +797,9 @@
void RefreshRateConfigs::setActiveModeId(DisplayModeId modeId) {
std::lock_guard lock(mLock);
- // Invalidate the cached invocation to getBestRefreshRate. This forces
- // the refresh rate to be recomputed on the next call to getBestRefreshRate.
- mGetBestRefreshRateCache.reset();
+ // Invalidate the cached invocation to getRankedRefreshRates. This forces
+ // the refresh rate to be recomputed on the next call to getRankedRefreshRates.
+ mGetRankedRefreshRatesCache.reset();
mActiveModeIt = mDisplayModes.find(modeId);
LOG_ALWAYS_FATAL_IF(mActiveModeIt == mDisplayModes.end());
@@ -797,9 +834,9 @@
void RefreshRateConfigs::updateDisplayModes(DisplayModes modes, DisplayModeId activeModeId) {
std::lock_guard lock(mLock);
- // Invalidate the cached invocation to getBestRefreshRate. This forces
- // the refresh rate to be recomputed on the next call to getBestRefreshRate.
- mGetBestRefreshRateCache.reset();
+ // Invalidate the cached invocation to getRankedRefreshRates. This forces
+ // the refresh rate to be recomputed on the next call to getRankedRefreshRates.
+ mGetRankedRefreshRatesCache.reset();
mDisplayModes = std::move(modes);
mActiveModeIt = mDisplayModes.find(activeModeId);
@@ -843,7 +880,7 @@
ALOGE("Invalid refresh rate policy: %s", policy.toString().c_str());
return BAD_VALUE;
}
- mGetBestRefreshRateCache.reset();
+ mGetRankedRefreshRatesCache.reset();
Policy previousPolicy = *getCurrentPolicyLocked();
mDisplayManagerPolicy = policy;
if (*getCurrentPolicyLocked() == previousPolicy) {
@@ -858,7 +895,7 @@
if (policy && !isPolicyValidLocked(*policy)) {
return BAD_VALUE;
}
- mGetBestRefreshRateCache.reset();
+ mGetRankedRefreshRatesCache.reset();
Policy previousPolicy = *getCurrentPolicyLocked();
mOverridePolicy = policy;
if (*getCurrentPolicyLocked() == previousPolicy) {
@@ -958,7 +995,8 @@
return KernelIdleTimerAction::TurnOff;
}
- const DisplayModePtr& maxByPolicy = getMaxRefreshRateByPolicyLocked();
+ const DisplayModePtr& maxByPolicy =
+ getMaxRefreshRateByPolicyLocked(getActiveModeItLocked()->second->getGroup());
if (minByPolicy == maxByPolicy) {
// Turn on the timer when the min of the primary range is below the device min.
if (const Policy* currentPolicy = getCurrentPolicyLocked();
diff --git a/services/surfaceflinger/Scheduler/RefreshRateConfigs.h b/services/surfaceflinger/Scheduler/RefreshRateConfigs.h
index 19bcb94..0642fcb 100644
--- a/services/surfaceflinger/Scheduler/RefreshRateConfigs.h
+++ b/services/surfaceflinger/Scheduler/RefreshRateConfigs.h
@@ -44,6 +44,15 @@
return static_cast<DisplayModeEvent>(static_cast<T>(lhs) | static_cast<T>(rhs));
}
+struct RefreshRateRanking {
+ DisplayModePtr displayModePtr;
+ float score = 0.0f;
+
+ bool operator==(const RefreshRateRanking& ranking) const {
+ return displayModePtr == ranking.displayModePtr && score == ranking.score;
+ }
+};
+
using FrameRateOverride = DisplayEventReceiver::Event::FrameRateOverride;
/**
@@ -195,9 +204,9 @@
}
};
- // Returns the refresh rate that best fits the given layers, and whether the refresh rate was
- // chosen based on touch boost and/or idle timer.
- std::pair<DisplayModePtr, GlobalSignals> getBestRefreshRate(
+ // Returns the list in the descending order of refresh rates desired
+ // based on their overall score, and the GlobalSignals that were considered.
+ std::pair<std::vector<RefreshRateRanking>, GlobalSignals> getRankedRefreshRates(
const std::vector<LayerRequirement>&, GlobalSignals) const EXCLUDES(mLock);
FpsRange getSupportedRefreshRateRange() const EXCLUDES(mLock) {
@@ -208,10 +217,6 @@
std::optional<Fps> onKernelTimerChanged(std::optional<DisplayModeId> desiredActiveModeId,
bool timerExpired) const EXCLUDES(mLock);
- // Returns the highest refresh rate according to the current policy. May change at runtime. Only
- // uses the primary range, not the app request range.
- DisplayModePtr getMaxRefreshRateByPolicy() const EXCLUDES(mLock);
-
void setActiveModeId(DisplayModeId) EXCLUDES(mLock) REQUIRES(kMainThreadContext);
// See mActiveModeIt for thread safety.
@@ -343,7 +348,7 @@
// See mActiveModeIt for thread safety.
DisplayModeIterator getActiveModeItLocked() const REQUIRES(mLock);
- std::pair<DisplayModePtr, GlobalSignals> getBestRefreshRateLocked(
+ std::pair<std::vector<RefreshRateRanking>, GlobalSignals> getRankedRefreshRatesLocked(
const std::vector<LayerRequirement>&, GlobalSignals) const REQUIRES(mLock);
// Returns number of display frames and remainder when dividing the layer refresh period by
@@ -356,12 +361,23 @@
// Returns the highest refresh rate according to the current policy. May change at runtime. Only
// uses the primary range, not the app request range.
- const DisplayModePtr& getMaxRefreshRateByPolicyLocked() const REQUIRES(mLock);
const DisplayModePtr& getMaxRefreshRateByPolicyLocked(int anchorGroup) const REQUIRES(mLock);
+ struct RefreshRateScoreComparator;
+
+ enum class RefreshRateOrder { Ascending, Descending };
+
+ // Returns the rankings in RefreshRateOrder. May change at runtime.
+ // Only uses the primary range, not the app request range.
+ std::vector<RefreshRateRanking> getRefreshRatesByPolicyLocked(std::optional<int> anchorGroupOpt,
+ RefreshRateOrder) const
+ REQUIRES(mLock);
+
const Policy* getCurrentPolicyLocked() const REQUIRES(mLock);
bool isPolicyValidLocked(const Policy& policy) const REQUIRES(mLock);
+ // Returns the refresh rate score as a ratio to max refresh rate, which has a score of 1.
+ float calculateRefreshRateScoreForFps(Fps refreshRate) const REQUIRES(mLock);
// calculates a score for a layer. Used to determine the display refresh rate
// and the frame rate override for certains applications.
float calculateLayerScoreLocked(const LayerRequirement&, Fps refreshRate,
@@ -410,11 +426,11 @@
const Config mConfig;
bool mSupportsFrameRateOverrideByContent;
- struct GetBestRefreshRateCache {
+ struct GetRankedRefreshRatesCache {
std::pair<std::vector<LayerRequirement>, GlobalSignals> arguments;
- std::pair<DisplayModePtr, GlobalSignals> result;
+ std::pair<std::vector<RefreshRateRanking>, GlobalSignals> result;
};
- mutable std::optional<GetBestRefreshRateCache> mGetBestRefreshRateCache GUARDED_BY(mLock);
+ mutable std::optional<GetRankedRefreshRatesCache> mGetRankedRefreshRatesCache GUARDED_BY(mLock);
// Declare mIdleTimer last to ensure its thread joins before the mutex/callbacks are destroyed.
std::mutex mIdleTimerCallbacksMutex;
diff --git a/services/surfaceflinger/Scheduler/Scheduler.cpp b/services/surfaceflinger/Scheduler/Scheduler.cpp
index ff6b461..6d68bac 100644
--- a/services/surfaceflinger/Scheduler/Scheduler.cpp
+++ b/services/surfaceflinger/Scheduler/Scheduler.cpp
@@ -674,7 +674,9 @@
if (currentState == newState) return {};
currentState = std::forward<T>(newState);
- std::tie(newMode, consideredSignals) = chooseDisplayMode();
+ const auto [rankings, signals] = getRankedDisplayModes();
+ newMode = rankings.front().displayModePtr;
+ consideredSignals = signals;
frameRateOverridesChanged = updateFrameRateOverrides(consideredSignals, newMode->getFps());
if (mPolicy.mode == newMode) {
@@ -699,7 +701,8 @@
return consideredSignals;
}
-auto Scheduler::chooseDisplayMode() -> std::pair<DisplayModePtr, GlobalSignals> {
+auto Scheduler::getRankedDisplayModes()
+ -> std::pair<std::vector<RefreshRateRanking>, GlobalSignals> {
ATRACE_CALL();
const auto configs = holdRefreshRateConfigs();
@@ -712,14 +715,14 @@
.idle = mPolicy.idleTimer == TimerState::Expired,
.powerOnImminent = powerOnImminent};
- return configs->getBestRefreshRate(mPolicy.contentRequirements, signals);
+ return configs->getRankedRefreshRates(mPolicy.contentRequirements, signals);
}
DisplayModePtr Scheduler::getPreferredDisplayMode() {
std::lock_guard<std::mutex> lock(mPolicyLock);
// Make sure the stored mode is up to date.
if (mPolicy.mode) {
- mPolicy.mode = chooseDisplayMode().first;
+ mPolicy.mode = getRankedDisplayModes().first.front().displayModePtr;
}
return mPolicy.mode;
}
diff --git a/services/surfaceflinger/Scheduler/Scheduler.h b/services/surfaceflinger/Scheduler/Scheduler.h
index afb3459..f567205 100644
--- a/services/surfaceflinger/Scheduler/Scheduler.h
+++ b/services/surfaceflinger/Scheduler/Scheduler.h
@@ -95,8 +95,8 @@
~ISchedulerCallback() = default;
};
-class Scheduler : impl::MessageQueue {
- using Impl = impl::MessageQueue;
+class Scheduler : android::impl::MessageQueue {
+ using Impl = android::impl::MessageQueue;
public:
Scheduler(ICompositor&, ISchedulerCallback&, FeatureFlags);
@@ -130,7 +130,7 @@
ConnectionHandle createConnection(const char* connectionName, frametimeline::TokenManager*,
std::chrono::nanoseconds workDuration,
std::chrono::nanoseconds readyDuration,
- impl::EventThread::InterceptVSyncsCallback);
+ android::impl::EventThread::InterceptVSyncsCallback);
sp<IDisplayEventConnection> createDisplayEventConnection(
ConnectionHandle, EventRegistrationFlags eventRegistration = {});
@@ -269,16 +269,18 @@
template <typename S, typename T>
GlobalSignals applyPolicy(S Policy::*, T&&) EXCLUDES(mPolicyLock);
- // Returns the display mode that fulfills the policy, and the signals that were considered.
- std::pair<DisplayModePtr, GlobalSignals> chooseDisplayMode() REQUIRES(mPolicyLock);
+ // Returns the list of display modes in descending order of their priority that fulfills the
+ // policy, and the signals that were considered.
+ std::pair<std::vector<RefreshRateRanking>, GlobalSignals> getRankedDisplayModes()
+ REQUIRES(mPolicyLock);
bool updateFrameRateOverrides(GlobalSignals, Fps displayRefreshRate) REQUIRES(mPolicyLock);
void dispatchCachedReportedMode() REQUIRES(mPolicyLock) EXCLUDES(mRefreshRateConfigsLock);
- impl::EventThread::ThrottleVsyncCallback makeThrottleVsyncCallback() const
+ android::impl::EventThread::ThrottleVsyncCallback makeThrottleVsyncCallback() const
EXCLUDES(mRefreshRateConfigsLock);
- impl::EventThread::GetVsyncPeriodFunction makeGetVsyncPeriodFunction() const;
+ android::impl::EventThread::GetVsyncPeriodFunction makeGetVsyncPeriodFunction() const;
std::shared_ptr<RefreshRateConfigs> holdRefreshRateConfigs() const
EXCLUDES(mRefreshRateConfigsLock) {
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index e31490c..f3551ae 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -106,7 +106,6 @@
#include <ui/DisplayIdentification.h>
#include "BackgroundExecutor.h"
-#include "BufferStateLayer.h"
#include "Client.h"
#include "Colorizer.h"
#include "Display/DisplayMap.h"
@@ -681,7 +680,7 @@
sp<IBinder> input(defaultServiceManager()->getService(String16("inputflinger")));
- static_cast<void>(mScheduler->schedule([=] {
+ static_cast<void>(mScheduler->schedule([=]() FTL_FAKE_GUARD(kMainThreadContext) {
if (input == nullptr) {
ALOGE("Failed to link to input service");
} else {
@@ -709,8 +708,9 @@
mBootStage = BootStage::FINISHED;
- if (property_get_bool("sf.debug.show_refresh_rate_overlay", false)) {
- FTL_FAKE_GUARD(mStateLock, enableRefreshRateOverlay(true));
+ if (base::GetBoolProperty("sf.debug.show_refresh_rate_overlay"s, false)) {
+ ftl::FakeGuard guard(mStateLock);
+ enableRefreshRateOverlay(true);
}
}));
}
@@ -814,16 +814,37 @@
enableHalVirtualDisplays(true);
}
- // Process any initial hotplug and resulting display changes.
+ // Process hotplug for displays connected at boot.
LOG_ALWAYS_FATAL_IF(!configureLocked(),
"Initial display configuration failed: HWC did not hotplug");
- processDisplayChangesLocked();
- const auto display = getDefaultDisplayDeviceLocked();
+ // Commit primary display.
+ sp<const DisplayDevice> display;
+ if (const auto indexOpt = mCurrentState.getDisplayIndex(getPrimaryDisplayIdLocked())) {
+ const auto& displays = mCurrentState.displays;
+
+ const auto& token = displays.keyAt(*indexOpt);
+ const auto& state = displays.valueAt(*indexOpt);
+
+ processDisplayAdded(token, state);
+ mDrawingState.displays.add(token, state);
+
+ display = getDefaultDisplayDeviceLocked();
+ }
+
LOG_ALWAYS_FATAL_IF(!display, "Failed to configure the primary display");
LOG_ALWAYS_FATAL_IF(!getHwComposer().isConnected(display->getPhysicalId()),
"Primary display is disconnected");
+ // TODO(b/241285876): The Scheduler needlessly depends on creating the CompositionEngine part of
+ // the DisplayDevice, hence the above commit of the primary display. Remove that special case by
+ // initializing the Scheduler after configureLocked, once decoupled from DisplayDevice.
+ initScheduler(display);
+ dispatchDisplayHotplugEvent(display->getPhysicalId(), true);
+
+ // Commit secondary display(s).
+ processDisplayChangesLocked();
+
// initialize our drawing state
mDrawingState = mCurrentState;
@@ -1039,7 +1060,7 @@
const PhysicalDisplayId displayId = snapshot.displayId();
- info->activeDisplayModeId = display->getActiveMode()->getId().value();
+ info->activeDisplayModeId = display->refreshRateConfigs().getActiveModePtr()->getId().value();
info->activeColorMode = display->getCompositionDisplay()->getState().colorMode;
info->supportedColorModes = getDisplayColorModes(displayId);
info->hdrCapabilities = display->getHdrCapabilities();
@@ -1163,7 +1184,7 @@
return;
}
- if (display->getActiveMode()->getResolution() != upcomingModeInfo.mode->getResolution()) {
+ if (display->getActiveMode().getResolution() != upcomingModeInfo.mode->getResolution()) {
auto& state = mCurrentState.displays.editValueFor(display->getDisplayToken());
// We need to generate new sequenceId in order to recreate the display (and this
// way the framebuffer).
@@ -1249,7 +1270,7 @@
ALOGV("%s changing active mode to %d(%s) for display %s", __func__, desiredModeId.value(),
to_string(*refreshRateOpt).c_str(), to_string(display->getId()).c_str());
- if (display->getActiveMode()->getId() == desiredModeId) {
+ if (display->getActiveMode().getId() == desiredModeId) {
// we are already in the requested mode, there is nothing left to do
desiredActiveModeChangeDone(display);
continue;
@@ -1298,7 +1319,7 @@
const auto display = getDisplayDeviceLocked(*displayToUpdateImmediately);
const auto desiredActiveMode = display->getDesiredActiveMode();
if (desiredActiveMode &&
- display->getActiveMode()->getId() == desiredActiveMode->mode->getId()) {
+ display->getActiveMode().getId() == desiredActiveMode->mode->getId()) {
desiredActiveModeChangeDone(display);
}
}
@@ -2087,7 +2108,7 @@
activeDisplay->getPowerMode() == hal::PowerMode::ON;
if (mPowerHintSessionEnabled) {
const auto& display = FTL_FAKE_GUARD(mStateLock, getDefaultDisplayDeviceLocked()).get();
- const Period vsyncPeriod = Period::fromNs(display->getActiveMode()->getVsyncPeriod());
+ const Period vsyncPeriod = Period::fromNs(display->getActiveMode().getVsyncPeriod());
mPowerAdvisor->setCommitStart(frameTime);
mPowerAdvisor->setExpectedPresentTime(mExpectedPresentTime);
@@ -2953,10 +2974,13 @@
LOG_FATAL_IF(!displaySurface);
auto display = setupNewDisplayDeviceInternal(displayToken, std::move(compositionDisplay), state,
displaySurface, producer);
- if (display->isPrimary()) {
- initScheduler(display);
- }
- if (!state.isVirtual()) {
+
+ if (mScheduler && !display->isVirtual()) {
+ // Display modes are reloaded on hotplug reconnect.
+ if (display->isPrimary()) {
+ mScheduler->setRefreshRateConfigs(display->holdRefreshRateConfigs());
+ }
+
dispatchDisplayHotplugEvent(display->getPhysicalId(), true);
}
@@ -3061,7 +3085,7 @@
void SurfaceFlinger::updateInternalDisplayVsyncLocked(const sp<DisplayDevice>& activeDisplay) {
mVsyncConfiguration->reset();
- const Fps refreshRate = activeDisplay->refreshRateConfigs().getActiveMode().getFps();
+ const Fps refreshRate = activeDisplay->getActiveMode().getFps();
updatePhaseConfiguration(refreshRate);
mRefreshRateStats->setRefreshRate(refreshRate);
}
@@ -3368,20 +3392,16 @@
mScheduler->onFrameRateOverridesChanged(mAppConnectionHandle, displayId);
}
-void SurfaceFlinger::initScheduler(const sp<DisplayDevice>& display) {
- if (mScheduler) {
- // If the scheduler is already initialized, this means that we received
- // a hotplug(connected) on the primary display. In that case we should
- // update the scheduler with the most recent display information.
- ALOGW("Scheduler already initialized, updating instead");
- mScheduler->setRefreshRateConfigs(display->holdRefreshRateConfigs());
- return;
- }
- const auto currRefreshRate = display->getActiveMode()->getFps();
- mRefreshRateStats = std::make_unique<scheduler::RefreshRateStats>(*mTimeStats, currRefreshRate,
- hal::PowerMode::OFF);
+void SurfaceFlinger::initScheduler(const sp<const DisplayDevice>& display) {
+ LOG_ALWAYS_FATAL_IF(mScheduler);
- mVsyncConfiguration = getFactory().createVsyncConfiguration(currRefreshRate);
+ const auto activeModePtr = display->refreshRateConfigs().getActiveModePtr();
+ const Fps activeRefreshRate = activeModePtr->getFps();
+ mRefreshRateStats =
+ std::make_unique<scheduler::RefreshRateStats>(*mTimeStats, activeRefreshRate,
+ hal::PowerMode::OFF);
+
+ mVsyncConfiguration = getFactory().createVsyncConfiguration(activeRefreshRate);
mVsyncModulator = sp<VsyncModulator>::make(mVsyncConfiguration->getCurrentConfigs());
using Feature = scheduler::Feature;
@@ -3414,7 +3434,7 @@
mScheduler->startTimers();
const auto configs = mVsyncConfiguration->getCurrentConfigs();
- const nsecs_t vsyncPeriod = currRefreshRate.getPeriodNsecs();
+ const nsecs_t vsyncPeriod = activeRefreshRate.getPeriodNsecs();
mAppConnectionHandle =
mScheduler->createConnection("app", mFrameTimeline->getTokenManager(),
/*workDuration=*/configs.late.appWorkDuration,
@@ -3442,7 +3462,7 @@
// This is a bit hacky, but this avoids a back-pointer into the main SF
// classes from EventThread, and there should be no run-time binder cost
// anyway since there are no connected apps at this point.
- mScheduler->onPrimaryDisplayModeChanged(mAppConnectionHandle, display->getActiveMode());
+ mScheduler->onPrimaryDisplayModeChanged(mAppConnectionHandle, activeModePtr);
}
void SurfaceFlinger::updatePhaseConfiguration(const Fps& refreshRate) {
@@ -5331,10 +5351,10 @@
if (const auto display = getDefaultDisplayDeviceLocked()) {
std::string fps, xDpi, yDpi;
- if (const auto activeMode = display->getActiveMode()) {
- fps = to_string(activeMode->getFps());
+ if (const auto activeModePtr = display->refreshRateConfigs().getActiveModePtr()) {
+ fps = to_string(activeModePtr->getFps());
- const auto dpi = activeMode->getDpi();
+ const auto dpi = activeModePtr->getDpi();
xDpi = base::StringPrintf("%.2f", dpi.x);
yDpi = base::StringPrintf("%.2f", dpi.y);
} else {
@@ -5834,19 +5854,17 @@
return NO_ERROR;
}
case 1034: {
- auto future = mScheduler->schedule([&] {
- switch (n = data.readInt32()) {
- case 0:
- case 1:
- FTL_FAKE_GUARD(mStateLock,
- enableRefreshRateOverlay(static_cast<bool>(n)));
- break;
- default: {
- reply->writeBool(
- FTL_FAKE_GUARD(mStateLock, isRefreshRateOverlayEnabled()));
- }
- }
- });
+ auto future = mScheduler->schedule(
+ [&]() FTL_FAKE_GUARD(mStateLock) FTL_FAKE_GUARD(kMainThreadContext) {
+ switch (n = data.readInt32()) {
+ case 0:
+ case 1:
+ enableRefreshRateOverlay(static_cast<bool>(n));
+ break;
+ default:
+ reply->writeBool(isRefreshRateOverlayEnabled());
+ }
+ });
future.wait();
return NO_ERROR;
@@ -6636,6 +6654,11 @@
std::vector<Layer*> renderedLayers;
bool disableBlurs = false;
traverseLayers([&](Layer* layer) {
+ // Layer::prepareClientComposition uses the layer's snapshot to populate the resulting
+ // LayerSettings. Calling Layer::updateSnapshot ensures that LayerSettings are
+ // generated with the layer's current buffer and geometry.
+ layer->updateSnapshot(true /* updateGeometry */);
+
disableBlurs |= layer->getDrawingState().sidebandStream != nullptr;
Region clip(renderArea.getBounds());
@@ -6782,12 +6805,12 @@
// TODO(b/140204874): Leave the event in until we do proper testing with all apps that might
// be depending in this callback.
- const auto activeMode = display->getActiveMode();
+ const auto activeModePtr = display->refreshRateConfigs().getActiveModePtr();
if (isDisplayActiveLocked(display)) {
- mScheduler->onPrimaryDisplayModeChanged(mAppConnectionHandle, activeMode);
+ mScheduler->onPrimaryDisplayModeChanged(mAppConnectionHandle, activeModePtr);
toggleKernelIdleTimer();
} else {
- mScheduler->onNonPrimaryDisplayModeChanged(mAppConnectionHandle, activeMode);
+ mScheduler->onNonPrimaryDisplayModeChanged(mAppConnectionHandle, activeModePtr);
}
auto preferredModeOpt =
@@ -7077,7 +7100,7 @@
mRegionSamplingThread->onCompositionComplete(mScheduler->getScheduledFrameTime());
}
-void SurfaceFlinger::onActiveDisplaySizeChanged(const sp<DisplayDevice>& activeDisplay) {
+void SurfaceFlinger::onActiveDisplaySizeChanged(const sp<const DisplayDevice>& activeDisplay) {
mScheduler->onActiveDisplayAreaChanged(activeDisplay->getWidth() * activeDisplay->getHeight());
getRenderEngine().onActiveDisplaySizeChanged(activeDisplay->getSize());
}
diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h
index f7684a0..fdaacf0 100644
--- a/services/surfaceflinger/SurfaceFlinger.h
+++ b/services/surfaceflinger/SurfaceFlinger.h
@@ -333,7 +333,6 @@
private:
friend class BufferLayer;
- friend class BufferStateLayer;
friend class Client;
friend class FpsReporter;
friend class TunnelModeEnabledReporter;
@@ -374,7 +373,20 @@
const LayerVector::StateSet stateSet = LayerVector::StateSet::Invalid;
LayerVector layersSortedByZ;
- DefaultKeyedVector< wp<IBinder>, DisplayDeviceState> displays;
+
+ // TODO(b/241285876): Replace deprecated DefaultKeyedVector with ftl::SmallMap.
+ DefaultKeyedVector<wp<IBinder>, DisplayDeviceState> displays;
+
+ std::optional<size_t> getDisplayIndex(PhysicalDisplayId displayId) const {
+ for (size_t i = 0; i < displays.size(); i++) {
+ const auto& state = displays.valueAt(i);
+ if (state.physical && state.physical->id == displayId) {
+ return i;
+ }
+ }
+
+ return {};
+ }
bool colorMatrixChanged = true;
mat4 colorMatrix;
@@ -695,7 +707,7 @@
void commitInputWindowCommands() REQUIRES(mStateLock);
void updateCursorAsync();
- void initScheduler(const sp<DisplayDevice>& display) REQUIRES(mStateLock);
+ void initScheduler(const sp<const DisplayDevice>&) REQUIRES(mStateLock);
void updatePhaseConfiguration(const Fps&) REQUIRES(mStateLock);
void setVsyncConfig(const VsyncModulator::VsyncConfig&, nsecs_t vsyncPeriod);
@@ -1027,7 +1039,7 @@
void onActiveDisplayChangedLocked(const sp<DisplayDevice>& activeDisplay)
REQUIRES(mStateLock, kMainThreadContext);
- void onActiveDisplaySizeChanged(const sp<DisplayDevice>& activeDisplay);
+ void onActiveDisplaySizeChanged(const sp<const DisplayDevice>&);
/*
* Debugging & dumpsys
@@ -1328,7 +1340,7 @@
std::unique_ptr<Hwc2::PowerAdvisor> mPowerAdvisor;
- void enableRefreshRateOverlay(bool enable) REQUIRES(mStateLock);
+ void enableRefreshRateOverlay(bool enable) REQUIRES(mStateLock, kMainThreadContext);
// Flag used to set override desired display mode from backdoor
bool mDebugDisplayModeSetByBackdoor = false;
diff --git a/services/surfaceflinger/SurfaceFlingerDefaultFactory.cpp b/services/surfaceflinger/SurfaceFlingerDefaultFactory.cpp
index 319d014..3e30dcb 100644
--- a/services/surfaceflinger/SurfaceFlingerDefaultFactory.cpp
+++ b/services/surfaceflinger/SurfaceFlingerDefaultFactory.cpp
@@ -22,7 +22,6 @@
#include <cutils/properties.h>
#include <ui/GraphicBuffer.h>
-#include "BufferStateLayer.h"
#include "DisplayDevice.h"
#include "FrameTracer/FrameTracer.h"
#include "Layer.h"
@@ -89,8 +88,8 @@
return compositionengine::impl::createCompositionEngine();
}
-sp<BufferStateLayer> DefaultFactory::createBufferStateLayer(const LayerCreationArgs& args) {
- return sp<BufferStateLayer>::make(args);
+sp<Layer> DefaultFactory::createBufferStateLayer(const LayerCreationArgs& args) {
+ return sp<Layer>::make(args);
}
sp<Layer> DefaultFactory::createEffectLayer(const LayerCreationArgs& args) {
diff --git a/services/surfaceflinger/SurfaceFlingerDefaultFactory.h b/services/surfaceflinger/SurfaceFlingerDefaultFactory.h
index 6602240..6fca402 100644
--- a/services/surfaceflinger/SurfaceFlingerDefaultFactory.h
+++ b/services/surfaceflinger/SurfaceFlingerDefaultFactory.h
@@ -41,7 +41,7 @@
std::unique_ptr<surfaceflinger::NativeWindowSurface> createNativeWindowSurface(
const sp<IGraphicBufferProducer>&) override;
std::unique_ptr<compositionengine::CompositionEngine> createCompositionEngine() override;
- sp<BufferStateLayer> createBufferStateLayer(const LayerCreationArgs& args) override;
+ sp<Layer> createBufferStateLayer(const LayerCreationArgs& args) override;
sp<Layer> createEffectLayer(const LayerCreationArgs& args) override;
std::unique_ptr<FrameTracer> createFrameTracer() override;
std::unique_ptr<frametimeline::FrameTimeline> createFrameTimeline(
diff --git a/services/surfaceflinger/SurfaceFlingerFactory.h b/services/surfaceflinger/SurfaceFlingerFactory.h
index dc2afd3..6d18ade 100644
--- a/services/surfaceflinger/SurfaceFlingerFactory.h
+++ b/services/surfaceflinger/SurfaceFlingerFactory.h
@@ -31,7 +31,6 @@
typedef int32_t PixelFormat;
class BufferLayerConsumer;
-class BufferStateLayer;
class DisplayDevice;
class FrameTracer;
class GraphicBuffer;
@@ -89,7 +88,7 @@
virtual std::unique_ptr<compositionengine::CompositionEngine> createCompositionEngine() = 0;
- virtual sp<BufferStateLayer> createBufferStateLayer(const LayerCreationArgs& args) = 0;
+ virtual sp<Layer> createBufferStateLayer(const LayerCreationArgs& args) = 0;
virtual sp<Layer> createEffectLayer(const LayerCreationArgs& args) = 0;
virtual std::unique_ptr<FrameTracer> createFrameTracer() = 0;
virtual std::unique_ptr<frametimeline::FrameTimeline> createFrameTimeline(
diff --git a/services/surfaceflinger/Tracing/tools/LayerTraceGenerator.cpp b/services/surfaceflinger/Tracing/tools/LayerTraceGenerator.cpp
index 6501e20..8817178 100644
--- a/services/surfaceflinger/Tracing/tools/LayerTraceGenerator.cpp
+++ b/services/surfaceflinger/Tracing/tools/LayerTraceGenerator.cpp
@@ -80,8 +80,8 @@
return compositionengine::impl::createCompositionEngine();
}
- sp<BufferStateLayer> createBufferStateLayer(const LayerCreationArgs& args) {
- return sp<BufferStateLayer>::make(args);
+ sp<Layer> createBufferStateLayer(const LayerCreationArgs& args) {
+ return sp<Layer>::make(args);
}
sp<Layer> createEffectLayer(const LayerCreationArgs& args) { return sp<Layer>::make(args); }
diff --git a/services/surfaceflinger/fuzzer/surfaceflinger_fuzzers_utils.h b/services/surfaceflinger/fuzzer/surfaceflinger_fuzzers_utils.h
index 2297618..69dbfe0 100644
--- a/services/surfaceflinger/fuzzer/surfaceflinger_fuzzers_utils.h
+++ b/services/surfaceflinger/fuzzer/surfaceflinger_fuzzers_utils.h
@@ -30,7 +30,6 @@
#include <ui/DisplayStatInfo.h>
#include <ui/DynamicDisplayInfo.h>
-#include "BufferStateLayer.h"
#include "DisplayDevice.h"
#include "DisplayHardware/ComposerHal.h"
#include "FrameTimeline/FrameTimeline.h"
@@ -355,9 +354,7 @@
return compositionengine::impl::createCompositionEngine();
}
- sp<BufferStateLayer> createBufferStateLayer(const LayerCreationArgs &) override {
- return nullptr;
- }
+ sp<Layer> createBufferStateLayer(const LayerCreationArgs &) override { return nullptr; }
sp<Layer> createEffectLayer(const LayerCreationArgs &args) override {
return sp<Layer>::make(args);
diff --git a/services/surfaceflinger/fuzzer/surfaceflinger_layer_fuzzer.cpp b/services/surfaceflinger/fuzzer/surfaceflinger_layer_fuzzer.cpp
index 9ece260..0a142c3 100644
--- a/services/surfaceflinger/fuzzer/surfaceflinger_layer_fuzzer.cpp
+++ b/services/surfaceflinger/fuzzer/surfaceflinger_layer_fuzzer.cpp
@@ -14,7 +14,6 @@
* limitations under the License.
*
*/
-#include <BufferStateLayer.h>
#include <Client.h>
#include <DisplayDevice.h>
#include <LayerRenderArea.h>
@@ -109,8 +108,7 @@
void LayerFuzzer::invokeBufferStateLayer() {
TestableSurfaceFlinger flinger;
sp<Client> client = sp<Client>::make(sp<SurfaceFlinger>::fromExisting(flinger.flinger()));
- sp<BufferStateLayer> layer =
- sp<BufferStateLayer>::make(createLayerCreationArgs(&flinger, client));
+ sp<Layer> layer = sp<Layer>::make(createLayerCreationArgs(&flinger, client));
sp<Fence> fence = sp<Fence>::make();
const std::shared_ptr<FenceTime> fenceTime = std::make_shared<FenceTime>(fence);
diff --git a/services/surfaceflinger/fuzzer/surfaceflinger_scheduler_fuzzer.cpp b/services/surfaceflinger/fuzzer/surfaceflinger_scheduler_fuzzer.cpp
index 3fc2b7e..66bac44 100644
--- a/services/surfaceflinger/fuzzer/surfaceflinger_scheduler_fuzzer.cpp
+++ b/services/surfaceflinger/fuzzer/surfaceflinger_scheduler_fuzzer.cpp
@@ -322,7 +322,7 @@
LayerCreationArgs args(flinger.flinger(), client,
mFdp.ConsumeRandomLengthString(kRandomStringLength) /*name*/,
mFdp.ConsumeIntegral<uint16_t>() /*layerFlags*/, LayerMetadata());
- sp<Layer> layer = sp<BufferStateLayer>::make(args);
+ sp<Layer> layer = sp<Layer>::make(args);
layer->setFrameRateSelectionPriority(mFdp.ConsumeIntegral<int16_t>());
}
@@ -350,7 +350,7 @@
const RefreshRateConfigs::GlobalSignals globalSignals = {.touch = false, .idle = false};
std::vector<LayerRequirement> layers = {{.weight = mFdp.ConsumeFloatingPoint<float>()}};
- refreshRateConfigs.getBestRefreshRate(layers, globalSignals);
+ refreshRateConfigs.getRankedRefreshRates(layers, globalSignals);
layers[0].name = mFdp.ConsumeRandomLengthString(kRandomStringLength);
layers[0].ownerUid = mFdp.ConsumeIntegral<uint16_t>();
diff --git a/services/surfaceflinger/tests/LayerBorder_test.cpp b/services/surfaceflinger/tests/LayerBorder_test.cpp
index 0d55ec1..85108ad 100644
--- a/services/surfaceflinger/tests/LayerBorder_test.cpp
+++ b/services/surfaceflinger/tests/LayerBorder_test.cpp
@@ -215,13 +215,13 @@
});
}
-TEST_F(LayerBorderTest, BufferStateLayer) {
+TEST_F(LayerBorderTest, LayerWithBuffer) {
asTransaction([&](Transaction& t) {
t.hide(mEffectLayer1);
t.hide(mEffectLayer2);
t.show(mContainerLayer);
- sp<SurfaceControl> bufferStateLayer =
+ sp<SurfaceControl> layer =
mClient->createSurface(String8("BufferState"), 0 /* width */, 0 /* height */,
PIXEL_FORMAT_RGBA_8888,
ISurfaceComposerClient::eFXSurfaceBufferState,
@@ -236,9 +236,9 @@
TransactionUtils::fillGraphicBufferColor(buffer, Rect(0, 0, 200, 200), Color::GREEN);
TransactionUtils::fillGraphicBufferColor(buffer, Rect(200, 200, 400, 400), Color::BLUE);
- t.setBuffer(bufferStateLayer, buffer);
- t.setPosition(bufferStateLayer, 100, 100);
- t.show(bufferStateLayer);
+ t.setBuffer(layer, buffer);
+ t.setPosition(layer, 100, 100);
+ t.show(layer);
t.enableBorder(mContainerLayer, true, 20, mColorOrange);
});
}
diff --git a/services/surfaceflinger/tests/LayerCallback_test.cpp b/services/surfaceflinger/tests/LayerCallback_test.cpp
index 1460fe1..26dbc76 100644
--- a/services/surfaceflinger/tests/LayerCallback_test.cpp
+++ b/services/surfaceflinger/tests/LayerCallback_test.cpp
@@ -51,7 +51,7 @@
LayerTransactionTest::TearDown();
}
- virtual sp<SurfaceControl> createBufferStateLayer() {
+ virtual sp<SurfaceControl> createLayerWithBuffer() {
return createLayer(mClient, "test", 0, 0, ISurfaceComposerClient::eFXSurfaceBufferState);
}
@@ -164,7 +164,7 @@
TEST_F(LayerCallbackTest, BufferColor) {
sp<SurfaceControl> layer;
- ASSERT_NO_FATAL_FAILURE(layer = createBufferStateLayer());
+ ASSERT_NO_FATAL_FAILURE(layer = createLayerWithBuffer());
Transaction transaction;
CallbackHelper callback;
@@ -183,7 +183,7 @@
TEST_F(LayerCallbackTest, NoBufferNoColor) {
sp<SurfaceControl> layer;
- ASSERT_NO_FATAL_FAILURE(layer = createBufferStateLayer());
+ ASSERT_NO_FATAL_FAILURE(layer = createLayerWithBuffer());
Transaction transaction;
CallbackHelper callback;
@@ -206,7 +206,7 @@
TEST_F(LayerCallbackTest, BufferNoColor) {
sp<SurfaceControl> layer;
- ASSERT_NO_FATAL_FAILURE(layer = createBufferStateLayer());
+ ASSERT_NO_FATAL_FAILURE(layer = createLayerWithBuffer());
Transaction transaction;
CallbackHelper callback;
@@ -228,7 +228,7 @@
TEST_F(LayerCallbackTest, NoBufferColor) {
sp<SurfaceControl> layer;
- ASSERT_NO_FATAL_FAILURE(layer = createBufferStateLayer());
+ ASSERT_NO_FATAL_FAILURE(layer = createLayerWithBuffer());
Transaction transaction;
CallbackHelper callback;
@@ -266,7 +266,7 @@
TEST_F(LayerCallbackTest, OffScreen) {
sp<SurfaceControl> layer;
- ASSERT_NO_FATAL_FAILURE(layer = createBufferStateLayer());
+ ASSERT_NO_FATAL_FAILURE(layer = createLayerWithBuffer());
Transaction transaction;
CallbackHelper callback;
@@ -288,8 +288,8 @@
TEST_F(LayerCallbackTest, MergeBufferNoColor) {
sp<SurfaceControl> layer1, layer2;
- ASSERT_NO_FATAL_FAILURE(layer1 = createBufferStateLayer());
- ASSERT_NO_FATAL_FAILURE(layer2 = createBufferStateLayer());
+ ASSERT_NO_FATAL_FAILURE(layer1 = createLayerWithBuffer());
+ ASSERT_NO_FATAL_FAILURE(layer2 = createLayerWithBuffer());
Transaction transaction1, transaction2;
CallbackHelper callback1, callback2;
@@ -322,8 +322,8 @@
TEST_F(LayerCallbackTest, MergeNoBufferColor) {
sp<SurfaceControl> layer1, layer2;
- ASSERT_NO_FATAL_FAILURE(layer1 = createBufferStateLayer());
- ASSERT_NO_FATAL_FAILURE(layer2 = createBufferStateLayer());
+ ASSERT_NO_FATAL_FAILURE(layer1 = createLayerWithBuffer());
+ ASSERT_NO_FATAL_FAILURE(layer2 = createLayerWithBuffer());
Transaction transaction1, transaction2;
CallbackHelper callback1, callback2;
@@ -357,8 +357,8 @@
TEST_F(LayerCallbackTest, MergeOneBufferOneColor) {
sp<SurfaceControl> layer1, layer2;
- ASSERT_NO_FATAL_FAILURE(layer1 = createBufferStateLayer());
- ASSERT_NO_FATAL_FAILURE(layer2 = createBufferStateLayer());
+ ASSERT_NO_FATAL_FAILURE(layer1 = createLayerWithBuffer());
+ ASSERT_NO_FATAL_FAILURE(layer2 = createLayerWithBuffer());
Transaction transaction1, transaction2;
CallbackHelper callback1, callback2;
@@ -392,8 +392,8 @@
}
TEST_F(LayerCallbackTest, Merge_SameCallback) {
sp<SurfaceControl> layer1, layer2;
- ASSERT_NO_FATAL_FAILURE(layer1 = createBufferStateLayer());
- ASSERT_NO_FATAL_FAILURE(layer2 = createBufferStateLayer());
+ ASSERT_NO_FATAL_FAILURE(layer1 = createLayerWithBuffer());
+ ASSERT_NO_FATAL_FAILURE(layer2 = createLayerWithBuffer());
Transaction transaction1, transaction2;
CallbackHelper callback;
@@ -418,7 +418,7 @@
TEST_F(LayerCallbackTest, Merge_SameLayer) {
sp<SurfaceControl> layer;
- ASSERT_NO_FATAL_FAILURE(layer = createBufferStateLayer());
+ ASSERT_NO_FATAL_FAILURE(layer = createLayerWithBuffer());
Transaction transaction1, transaction2;
CallbackHelper callback1, callback2;
@@ -485,7 +485,7 @@
TEST_F(LayerCallbackTest, MultipleTransactions) {
sp<SurfaceControl> layer;
- ASSERT_NO_FATAL_FAILURE(layer = createBufferStateLayer());
+ ASSERT_NO_FATAL_FAILURE(layer = createLayerWithBuffer());
Transaction transaction;
CallbackHelper callback;
@@ -510,7 +510,7 @@
TEST_F(LayerCallbackTest, MultipleTransactions_NoStateChange) {
sp<SurfaceControl> layer;
- ASSERT_NO_FATAL_FAILURE(layer = createBufferStateLayer());
+ ASSERT_NO_FATAL_FAILURE(layer = createLayerWithBuffer());
Transaction transaction;
CallbackHelper callback;
@@ -541,7 +541,7 @@
TEST_F(LayerCallbackTest, MultipleTransactions_SameStateChange) {
sp<SurfaceControl> layer;
- ASSERT_NO_FATAL_FAILURE(layer = createBufferStateLayer());
+ ASSERT_NO_FATAL_FAILURE(layer = createLayerWithBuffer());
Transaction transaction;
CallbackHelper callback;
@@ -579,8 +579,8 @@
TEST_F(LayerCallbackTest, MultipleTransactions_Merge) {
sp<SurfaceControl> layer1, layer2;
- ASSERT_NO_FATAL_FAILURE(layer1 = createBufferStateLayer());
- ASSERT_NO_FATAL_FAILURE(layer2 = createBufferStateLayer());
+ ASSERT_NO_FATAL_FAILURE(layer1 = createLayerWithBuffer());
+ ASSERT_NO_FATAL_FAILURE(layer2 = createLayerWithBuffer());
Transaction transaction1, transaction2;
CallbackHelper callback1, callback2;
@@ -799,7 +799,7 @@
// TODO (b/183181768): Fix & re-enable
TEST_F(LayerCallbackTest, DISABLED_MultipleTransactions_SingleFrame) {
sp<SurfaceControl> layer;
- ASSERT_NO_FATAL_FAILURE(layer = createBufferStateLayer());
+ ASSERT_NO_FATAL_FAILURE(layer = createLayerWithBuffer());
Transaction transaction;
CallbackHelper callback;
@@ -823,7 +823,7 @@
TEST_F(LayerCallbackTest, MultipleTransactions_SingleFrame_NoStateChange) {
sp<SurfaceControl> layer;
- ASSERT_NO_FATAL_FAILURE(layer = createBufferStateLayer());
+ ASSERT_NO_FATAL_FAILURE(layer = createLayerWithBuffer());
// Normal call to set up test
Transaction transaction;
@@ -858,7 +858,7 @@
TEST_F(LayerCallbackTest, MultipleTransactions_SingleFrame_SameStateChange) {
sp<SurfaceControl> layer;
- ASSERT_NO_FATAL_FAILURE(layer = createBufferStateLayer());
+ ASSERT_NO_FATAL_FAILURE(layer = createLayerWithBuffer());
// Normal call to set up test
Transaction transaction;
@@ -901,7 +901,7 @@
TEST_F(LayerCallbackTest, DesiredPresentTime) {
sp<SurfaceControl> layer;
- ASSERT_NO_FATAL_FAILURE(layer = createBufferStateLayer());
+ ASSERT_NO_FATAL_FAILURE(layer = createLayerWithBuffer());
Transaction transaction;
CallbackHelper callback;
@@ -925,7 +925,7 @@
TEST_F(LayerCallbackTest, DesiredPresentTime_Multiple) {
sp<SurfaceControl> layer;
- ASSERT_NO_FATAL_FAILURE(layer = createBufferStateLayer());
+ ASSERT_NO_FATAL_FAILURE(layer = createLayerWithBuffer());
Transaction transaction;
CallbackHelper callback1;
@@ -971,7 +971,7 @@
// TODO (b/183181768): Fix & re-enable
TEST_F(LayerCallbackTest, DISABLED_DesiredPresentTime_OutOfOrder) {
sp<SurfaceControl> layer;
- ASSERT_NO_FATAL_FAILURE(layer = createBufferStateLayer());
+ ASSERT_NO_FATAL_FAILURE(layer = createLayerWithBuffer());
Transaction transaction;
CallbackHelper callback1;
@@ -1015,7 +1015,7 @@
TEST_F(LayerCallbackTest, DesiredPresentTime_Past) {
sp<SurfaceControl> layer;
- ASSERT_NO_FATAL_FAILURE(layer = createBufferStateLayer());
+ ASSERT_NO_FATAL_FAILURE(layer = createLayerWithBuffer());
Transaction transaction;
CallbackHelper callback;
@@ -1039,7 +1039,7 @@
TEST_F(LayerCallbackTest, ExpectedPresentTime) {
sp<SurfaceControl> layer;
- ASSERT_NO_FATAL_FAILURE(layer = createBufferStateLayer());
+ ASSERT_NO_FATAL_FAILURE(layer = createLayerWithBuffer());
Transaction transaction;
CallbackHelper callback;
@@ -1065,8 +1065,8 @@
// b202394221
TEST_F(LayerCallbackTest, EmptyBufferStateChanges) {
sp<SurfaceControl> bufferLayer, emptyBufferLayer;
- ASSERT_NO_FATAL_FAILURE(bufferLayer = createBufferStateLayer());
- ASSERT_NO_FATAL_FAILURE(emptyBufferLayer = createBufferStateLayer());
+ ASSERT_NO_FATAL_FAILURE(bufferLayer = createLayerWithBuffer());
+ ASSERT_NO_FATAL_FAILURE(emptyBufferLayer = createLayerWithBuffer());
Transaction transaction;
CallbackHelper callback;
@@ -1120,7 +1120,7 @@
TEST_F(LayerCallbackTest, CommitCallbackOffscreenLayer) {
sp<SurfaceControl> layer;
- ASSERT_NO_FATAL_FAILURE(layer = createBufferStateLayer());
+ ASSERT_NO_FATAL_FAILURE(layer = createLayerWithBuffer());
sp<SurfaceControl> offscreenLayer =
createSurface(mClient, "Offscreen Layer", 0, 0, PIXEL_FORMAT_RGBA_8888,
ISurfaceComposerClient::eFXSurfaceBufferState, layer.get());
@@ -1151,7 +1151,7 @@
TEST_F(LayerCallbackTest, TransactionCommittedCallback_BSL) {
sp<SurfaceControl> layer;
- ASSERT_NO_FATAL_FAILURE(layer = createBufferStateLayer());
+ ASSERT_NO_FATAL_FAILURE(layer = createLayerWithBuffer());
Transaction transaction;
CallbackHelper callback;
diff --git a/services/surfaceflinger/tests/LayerRenderTypeTransaction_test.cpp b/services/surfaceflinger/tests/LayerRenderTypeTransaction_test.cpp
index bbe7ae8..bf7cae9 100644
--- a/services/surfaceflinger/tests/LayerRenderTypeTransaction_test.cpp
+++ b/services/surfaceflinger/tests/LayerRenderTypeTransaction_test.cpp
@@ -399,7 +399,7 @@
.apply();
ASSERT_NO_FATAL_FAILURE(
fillBufferQueueLayerColor(layerTransparent, Color::TRANSPARENT, 32, 32));
- ASSERT_NO_FATAL_FAILURE(fillBufferStateLayerColor(layerR, Color::RED, 32, 32));
+ ASSERT_NO_FATAL_FAILURE(fillBufferLayerColor(layerR, Color::RED, 32, 32));
getScreenCapture()->expectColor(Rect(16, 16, 48, 48), Color::RED);
}
@@ -482,7 +482,7 @@
}
}
-// RED: Color layer base color and BufferQueueLayer/BufferStateLayer fill
+// RED: Color layer base color and Layer buffer fill
// BLUE: prior background color
// GREEN: final background color
// BLACK: no color or fill
@@ -516,7 +516,7 @@
case ISurfaceComposerClient::eFXSurfaceBufferState:
ASSERT_NO_FATAL_FAILURE(layer = createLayer("test", width, height, layerType));
if (bufferFill) {
- ASSERT_NO_FATAL_FAILURE(fillBufferStateLayerColor(layer, fillColor, width, height));
+ ASSERT_NO_FATAL_FAILURE(fillBufferLayerColor(layer, fillColor, width, height));
expectedColor = fillColor;
}
Transaction().setCrop(layer, Rect(0, 0, width, height)).apply();
@@ -832,7 +832,7 @@
sp<SurfaceControl> layer;
ASSERT_NO_FATAL_FAILURE(
layer = createLayer("test", 32, 32, ISurfaceComposerClient::eFXSurfaceBufferState));
- ASSERT_NO_FATAL_FAILURE(fillBufferStateLayerColor(layer, Color::RED, 32, 32));
+ ASSERT_NO_FATAL_FAILURE(fillBufferLayerColor(layer, Color::RED, 32, 32));
const Rect crop(8, 8, 24, 24);
Transaction().setCrop(layer, crop).apply();
@@ -863,7 +863,7 @@
sp<SurfaceControl> layer;
ASSERT_NO_FATAL_FAILURE(
layer = createLayer("test", 32, 32, ISurfaceComposerClient::eFXSurfaceBufferState));
- ASSERT_NO_FATAL_FAILURE(fillBufferStateLayerColor(layer, Color::RED, 32, 32));
+ ASSERT_NO_FATAL_FAILURE(fillBufferLayerColor(layer, Color::RED, 32, 32));
{
SCOPED_TRACE("empty rect");
@@ -944,7 +944,7 @@
sp<SurfaceControl> layer;
ASSERT_NO_FATAL_FAILURE(
layer = createLayer("test", 32, 32, ISurfaceComposerClient::eFXSurfaceBufferState));
- ASSERT_NO_FATAL_FAILURE(fillBufferStateLayerColor(layer, Color::RED, 32, 32));
+ ASSERT_NO_FATAL_FAILURE(fillBufferLayerColor(layer, Color::RED, 32, 32));
const Rect crop(8, 8, 24, 24);
Transaction().setPosition(layer, 32, 32).setCrop(layer, crop).apply();
@@ -972,7 +972,7 @@
sp<SurfaceControl> layer;
ASSERT_NO_FATAL_FAILURE(
layer = createLayer("test", 32, 32, ISurfaceComposerClient::eFXSurfaceBufferState));
- ASSERT_NO_FATAL_FAILURE(fillBufferStateLayerColor(layer, Color::RED, 32, 32));
+ ASSERT_NO_FATAL_FAILURE(fillBufferLayerColor(layer, Color::RED, 32, 32));
const Rect frame(8, 8, 24, 24);
Transaction t;
@@ -988,7 +988,7 @@
sp<SurfaceControl> layer;
ASSERT_NO_FATAL_FAILURE(
layer = createLayer("test", 32, 32, ISurfaceComposerClient::eFXSurfaceBufferState));
- ASSERT_NO_FATAL_FAILURE(fillBufferStateLayerColor(layer, Color::RED, 32, 32));
+ ASSERT_NO_FATAL_FAILURE(fillBufferLayerColor(layer, Color::RED, 32, 32));
Transaction t;
{
@@ -1014,7 +1014,7 @@
sp<SurfaceControl> layer;
ASSERT_NO_FATAL_FAILURE(
layer = createLayer("test", 32, 32, ISurfaceComposerClient::eFXSurfaceBufferState));
- ASSERT_NO_FATAL_FAILURE(fillBufferStateLayerColor(layer, Color::RED, 10, 10));
+ ASSERT_NO_FATAL_FAILURE(fillBufferLayerColor(layer, Color::RED, 10, 10));
// A layer with a buffer will have a computed size that matches the buffer size.
auto shot = getScreenCapture();
@@ -1026,11 +1026,11 @@
sp<SurfaceControl> parent, child;
ASSERT_NO_FATAL_FAILURE(
parent = createLayer("test", 32, 32, ISurfaceComposerClient::eFXSurfaceBufferState));
- ASSERT_NO_FATAL_FAILURE(fillBufferStateLayerColor(parent, Color::RED, 32, 32));
+ ASSERT_NO_FATAL_FAILURE(fillBufferLayerColor(parent, Color::RED, 32, 32));
ASSERT_NO_FATAL_FAILURE(
child = createLayer("test", 10, 10, ISurfaceComposerClient::eFXSurfaceBufferState));
- ASSERT_NO_FATAL_FAILURE(fillBufferStateLayerColor(child, Color::BLUE, 10, 10));
+ ASSERT_NO_FATAL_FAILURE(fillBufferLayerColor(child, Color::BLUE, 10, 10));
Transaction().reparent(child, parent).apply();
@@ -1047,7 +1047,7 @@
ASSERT_NO_FATAL_FAILURE(
child = createLayer("test", 10, 10, ISurfaceComposerClient::eFXSurfaceBufferState));
- ASSERT_NO_FATAL_FAILURE(fillBufferStateLayerColor(child, Color::BLUE, 10, 10));
+ ASSERT_NO_FATAL_FAILURE(fillBufferLayerColor(child, Color::BLUE, 10, 10));
Transaction().reparent(child, parent).apply();
@@ -1061,7 +1061,7 @@
sp<SurfaceControl> layer;
ASSERT_NO_FATAL_FAILURE(
layer = createLayer("test", 32, 32, ISurfaceComposerClient::eFXSurfaceBufferState));
- ASSERT_NO_FATAL_FAILURE(fillBufferStateLayerColor(layer, Color::RED, 32, 32));
+ ASSERT_NO_FATAL_FAILURE(fillBufferLayerColor(layer, Color::RED, 32, 32));
std::this_thread::sleep_for(500ms);
@@ -1080,9 +1080,9 @@
child = createLayer("test", 10, 10, ISurfaceComposerClient::eFXSurfaceBufferState));
Transaction().reparent(child, parent).apply();
- ASSERT_NO_FATAL_FAILURE(fillBufferStateLayerColor(parent, Color::RED, 32, 32));
+ ASSERT_NO_FATAL_FAILURE(fillBufferLayerColor(parent, Color::RED, 32, 32));
- ASSERT_NO_FATAL_FAILURE(fillBufferStateLayerColor(child, Color::BLUE, 10, 10));
+ ASSERT_NO_FATAL_FAILURE(fillBufferLayerColor(child, Color::BLUE, 10, 10));
Rect childDst(0, 16, 32, 32);
Transaction t;
TransactionUtils::setFrame(t, child, Rect(0, 0, 10, 10), childDst);
@@ -1099,7 +1099,7 @@
ASSERT_NO_FATAL_FAILURE(
layer = createLayer("test", 32, 32, ISurfaceComposerClient::eFXSurfaceBufferState));
- ASSERT_NO_FATAL_FAILURE(fillBufferStateLayerColor(layer, Color::RED, 32, 32));
+ ASSERT_NO_FATAL_FAILURE(fillBufferLayerColor(layer, Color::RED, 32, 32));
auto shot = getScreenCapture();
shot->expectColor(Rect(0, 0, 32, 32), Color::RED);
@@ -1111,7 +1111,7 @@
ASSERT_NO_FATAL_FAILURE(
layer = createLayer("test", 32, 32, ISurfaceComposerClient::eFXSurfaceBufferState));
- ASSERT_NO_FATAL_FAILURE(fillBufferStateLayerColor(layer, Color::RED, 32, 32));
+ ASSERT_NO_FATAL_FAILURE(fillBufferLayerColor(layer, Color::RED, 32, 32));
{
SCOPED_TRACE("set buffer 1");
@@ -1120,7 +1120,7 @@
shot->expectBorder(Rect(0, 0, 32, 32), Color::BLACK);
}
- ASSERT_NO_FATAL_FAILURE(fillBufferStateLayerColor(layer, Color::BLUE, 32, 32));
+ ASSERT_NO_FATAL_FAILURE(fillBufferLayerColor(layer, Color::BLUE, 32, 32));
{
SCOPED_TRACE("set buffer 2");
@@ -1129,7 +1129,7 @@
shot->expectBorder(Rect(0, 0, 32, 32), Color::BLACK);
}
- ASSERT_NO_FATAL_FAILURE(fillBufferStateLayerColor(layer, Color::RED, 32, 32));
+ ASSERT_NO_FATAL_FAILURE(fillBufferLayerColor(layer, Color::RED, 32, 32));
{
SCOPED_TRACE("set buffer 3");
@@ -1148,7 +1148,7 @@
ASSERT_NO_FATAL_FAILURE(
layer2 = createLayer("test", 32, 32, ISurfaceComposerClient::eFXSurfaceBufferState));
- ASSERT_NO_FATAL_FAILURE(fillBufferStateLayerColor(layer1, Color::RED, 64, 64));
+ ASSERT_NO_FATAL_FAILURE(fillBufferLayerColor(layer1, Color::RED, 64, 64));
{
SCOPED_TRACE("set layer 1 buffer red");
@@ -1156,7 +1156,7 @@
shot->expectColor(Rect(0, 0, 64, 64), Color::RED);
}
- ASSERT_NO_FATAL_FAILURE(fillBufferStateLayerColor(layer2, Color::BLUE, 32, 32));
+ ASSERT_NO_FATAL_FAILURE(fillBufferLayerColor(layer2, Color::BLUE, 32, 32));
{
SCOPED_TRACE("set layer 2 buffer blue");
@@ -1166,7 +1166,7 @@
shot->expectColor(Rect(0, 32, 32, 64), Color::RED);
}
- ASSERT_NO_FATAL_FAILURE(fillBufferStateLayerColor(layer1, Color::GREEN, 64, 64));
+ ASSERT_NO_FATAL_FAILURE(fillBufferLayerColor(layer1, Color::GREEN, 64, 64));
{
SCOPED_TRACE("set layer 1 buffer green");
auto shot = getScreenCapture();
@@ -1175,7 +1175,7 @@
shot->expectColor(Rect(0, 32, 32, 64), Color::GREEN);
}
- ASSERT_NO_FATAL_FAILURE(fillBufferStateLayerColor(layer2, Color::WHITE, 32, 32));
+ ASSERT_NO_FATAL_FAILURE(fillBufferLayerColor(layer2, Color::WHITE, 32, 32));
{
SCOPED_TRACE("set layer 2 buffer white");
diff --git a/services/surfaceflinger/tests/LayerTransactionTest.h b/services/surfaceflinger/tests/LayerTransactionTest.h
index 0e8f3dd..774c1d7 100644
--- a/services/surfaceflinger/tests/LayerTransactionTest.h
+++ b/services/surfaceflinger/tests/LayerTransactionTest.h
@@ -137,8 +137,8 @@
postBufferQueueLayerBuffer(layer);
}
- virtual void fillBufferStateLayerColor(const sp<SurfaceControl>& layer, const Color& color,
- int32_t bufferWidth, int32_t bufferHeight) {
+ virtual void fillBufferLayerColor(const sp<SurfaceControl>& layer, const Color& color,
+ int32_t bufferWidth, int32_t bufferHeight) {
sp<GraphicBuffer> buffer =
sp<GraphicBuffer>::make(static_cast<uint32_t>(bufferWidth),
static_cast<uint32_t>(bufferHeight), PIXEL_FORMAT_RGBA_8888,
@@ -159,7 +159,7 @@
fillBufferQueueLayerColor(layer, color, bufferWidth, bufferHeight);
break;
case ISurfaceComposerClient::eFXSurfaceBufferState:
- fillBufferStateLayerColor(layer, color, bufferWidth, bufferHeight);
+ fillBufferLayerColor(layer, color, bufferWidth, bufferHeight);
break;
default:
ASSERT_TRUE(false) << "unsupported layer type: " << mLayerType;
diff --git a/services/surfaceflinger/tests/LayerTransaction_test.cpp b/services/surfaceflinger/tests/LayerTransaction_test.cpp
index c206e1f..cbd54e7 100644
--- a/services/surfaceflinger/tests/LayerTransaction_test.cpp
+++ b/services/surfaceflinger/tests/LayerTransaction_test.cpp
@@ -32,7 +32,7 @@
Transaction().setTransformToDisplayInverse(layer, false).apply();
- ASSERT_NO_FATAL_FAILURE(fillBufferStateLayerColor(layer, Color::GREEN, 32, 32));
+ ASSERT_NO_FATAL_FAILURE(fillBufferLayerColor(layer, Color::GREEN, 32, 32));
Transaction().setTransformToDisplayInverse(layer, true).apply();
}
@@ -161,7 +161,7 @@
TEST_F(LayerTransactionTest, BufferTakesPriorityOverBlur) {
sp<SurfaceControl> layer;
ASSERT_NO_FATAL_FAILURE(layer = createLayer("test", 32, 32));
- ASSERT_NO_FATAL_FAILURE(fillBufferStateLayerColor(layer, Color::RED, 32, 32));
+ ASSERT_NO_FATAL_FAILURE(fillBufferLayerColor(layer, Color::RED, 32, 32));
Transaction().setBackgroundBlurRadius(layer, 5).apply();
{
SCOPED_TRACE("BufferTakesPriorityOverBlur");
@@ -174,7 +174,7 @@
TEST_F(LayerTransactionTest, BufferTakesPriorityOverColor) {
sp<SurfaceControl> layer;
ASSERT_NO_FATAL_FAILURE(layer = createLayer("test", 32, 32));
- ASSERT_NO_FATAL_FAILURE(fillBufferStateLayerColor(layer, Color::RED, 32, 32));
+ ASSERT_NO_FATAL_FAILURE(fillBufferLayerColor(layer, Color::RED, 32, 32));
Transaction().setColor(layer, {Color::GREEN.r, Color::GREEN.g, Color::GREEN.b}).apply();
{
SCOPED_TRACE("BufferTakesPriorityOverColor");
diff --git a/services/surfaceflinger/tests/MirrorLayer_test.cpp b/services/surfaceflinger/tests/MirrorLayer_test.cpp
index a921aa8..faaef5d 100644
--- a/services/surfaceflinger/tests/MirrorLayer_test.cpp
+++ b/services/surfaceflinger/tests/MirrorLayer_test.cpp
@@ -193,14 +193,14 @@
shot->expectColor(Rect(750, 750, 950, 950), Color::GREEN);
}
- sp<SurfaceControl> bufferStateLayer =
- createLayer("BufferStateLayer", 200, 200, ISurfaceComposerClient::eFXSurfaceBufferState,
+ sp<SurfaceControl> layer =
+ createLayer("Layer", 200, 200, ISurfaceComposerClient::eFXSurfaceBufferState,
mChildLayer.get());
- fillBufferStateLayerColor(bufferStateLayer, Color::BLUE, 200, 200);
- Transaction().show(bufferStateLayer).apply();
+ fillBufferLayerColor(layer, Color::BLUE, 200, 200);
+ Transaction().show(layer).apply();
{
- SCOPED_TRACE("Initial Mirror BufferStateLayer");
+ SCOPED_TRACE("Initial Mirror Layer");
auto shot = screenshot();
// Buffer mirror
shot->expectColor(Rect(550, 550, 750, 750), Color::BLUE);
@@ -208,9 +208,9 @@
shot->expectColor(Rect(750, 750, 950, 950), Color::GREEN);
}
- fillBufferStateLayerColor(bufferStateLayer, Color::WHITE, 200, 200);
+ fillBufferLayerColor(layer, Color::WHITE, 200, 200);
{
- SCOPED_TRACE("Update BufferStateLayer");
+ SCOPED_TRACE("Update Layer");
auto shot = screenshot();
// Buffer mirror
shot->expectColor(Rect(550, 550, 750, 750), Color::WHITE);
@@ -218,9 +218,9 @@
shot->expectColor(Rect(750, 750, 950, 950), Color::GREEN);
}
- Transaction().reparent(bufferStateLayer, nullptr).apply();
+ Transaction().reparent(layer, nullptr).apply();
{
- SCOPED_TRACE("Removed BufferStateLayer");
+ SCOPED_TRACE("Removed Layer");
auto shot = screenshot();
// Buffer mirror
shot->expectColor(Rect(550, 550, 750, 750), Color::GREEN);
@@ -283,7 +283,7 @@
sp<SurfaceControl> grandchild =
createLayer("Grandchild layer", 50, 50, ISurfaceComposerClient::eFXSurfaceBufferState,
mChildLayer.get());
- ASSERT_NO_FATAL_FAILURE(fillBufferStateLayerColor(grandchild, Color::BLUE, 50, 50));
+ ASSERT_NO_FATAL_FAILURE(fillBufferLayerColor(grandchild, Color::BLUE, 50, 50));
Rect childBounds = Rect(50, 50, 450, 450);
asTransaction([&](Transaction& t) {
diff --git a/services/surfaceflinger/tests/ScreenCapture_test.cpp b/services/surfaceflinger/tests/ScreenCapture_test.cpp
index d78c8a9..3a5e532 100644
--- a/services/surfaceflinger/tests/ScreenCapture_test.cpp
+++ b/services/surfaceflinger/tests/ScreenCapture_test.cpp
@@ -371,7 +371,7 @@
ScreenCaptureResults captureResults;
ASSERT_EQ(BAD_VALUE, ScreenCapture::captureLayers(args, captureResults));
- ASSERT_NO_FATAL_FAILURE(fillBufferStateLayerColor(child, Color::RED, 32, 32));
+ ASSERT_NO_FATAL_FAILURE(fillBufferLayerColor(child, Color::RED, 32, 32));
SurfaceComposerClient::Transaction().apply(true);
ASSERT_EQ(NO_ERROR, ScreenCapture::captureLayers(args, captureResults));
ScreenCapture sc(captureResults.buffer, captureResults.capturedHdrLayers);
@@ -449,8 +449,8 @@
ISurfaceComposerClient::eFXSurfaceBufferState,
redLayer.get());
- ASSERT_NO_FATAL_FAILURE(fillBufferStateLayerColor(redLayer, Color::RED, 60, 60));
- ASSERT_NO_FATAL_FAILURE(fillBufferStateLayerColor(blueLayer, Color::BLUE, 30, 30));
+ ASSERT_NO_FATAL_FAILURE(fillBufferLayerColor(redLayer, Color::RED, 60, 60));
+ ASSERT_NO_FATAL_FAILURE(fillBufferLayerColor(blueLayer, Color::BLUE, 30, 30));
SurfaceComposerClient::Transaction()
.setLayer(redLayer, INT32_MAX - 1)
@@ -484,8 +484,8 @@
ISurfaceComposerClient::eFXSurfaceBufferState,
redLayer.get());
- ASSERT_NO_FATAL_FAILURE(fillBufferStateLayerColor(redLayer, Color::RED, 60, 60));
- ASSERT_NO_FATAL_FAILURE(fillBufferStateLayerColor(blueLayer, Color::BLUE, 30, 30));
+ ASSERT_NO_FATAL_FAILURE(fillBufferLayerColor(redLayer, Color::RED, 60, 60));
+ ASSERT_NO_FATAL_FAILURE(fillBufferLayerColor(blueLayer, Color::BLUE, 30, 30));
SurfaceComposerClient::Transaction()
.setLayer(redLayer, INT32_MAX - 1)
@@ -549,8 +549,8 @@
ISurfaceComposerClient::eSecure |
ISurfaceComposerClient::eFXSurfaceBufferState,
redLayer.get());
- ASSERT_NO_FATAL_FAILURE(fillBufferStateLayerColor(redLayer, Color::RED, 60, 60));
- ASSERT_NO_FATAL_FAILURE(fillBufferStateLayerColor(secureLayer, Color::BLUE, 30, 30));
+ ASSERT_NO_FATAL_FAILURE(fillBufferLayerColor(redLayer, Color::RED, 60, 60));
+ ASSERT_NO_FATAL_FAILURE(fillBufferLayerColor(secureLayer, Color::BLUE, 30, 30));
auto redLayerHandle = redLayer->getHandle();
Transaction()
@@ -803,7 +803,7 @@
ASSERT_NO_FATAL_FAILURE(layer = createLayer("test layer", 32, 32,
ISurfaceComposerClient::eFXSurfaceBufferState,
mBGSurfaceControl.get()));
- ASSERT_NO_FATAL_FAILURE(fillBufferStateLayerColor(layer, Color::RED, 32, 32));
+ ASSERT_NO_FATAL_FAILURE(fillBufferLayerColor(layer, Color::RED, 32, 32));
Transaction().show(layer).setLayer(layer, INT32_MAX).apply();
LayerCaptureArgs captureArgs;
@@ -825,7 +825,7 @@
mCapture->expectColor(Rect(0, 0, 32, 32),
Color{expectedColor, expectedColor, expectedColor, 255}, tolerance);
- ASSERT_NO_FATAL_FAILURE(fillBufferStateLayerColor(layer, Color::BLUE, 32, 32));
+ ASSERT_NO_FATAL_FAILURE(fillBufferLayerColor(layer, Color::BLUE, 32, 32));
ScreenCapture::captureLayers(&mCapture, captureArgs);
expectedColor = luminance.b * 255;
@@ -838,7 +838,7 @@
ASSERT_NO_FATAL_FAILURE(layer = createLayer("test layer", 32, 32,
ISurfaceComposerClient::eFXSurfaceBufferState,
mBGSurfaceControl.get()));
- ASSERT_NO_FATAL_FAILURE(fillBufferStateLayerColor(layer, Color::RED, 32, 32));
+ ASSERT_NO_FATAL_FAILURE(fillBufferLayerColor(layer, Color::RED, 32, 32));
Transaction().show(layer).hide(mFGSurfaceControl).reparent(layer, nullptr).apply();
@@ -865,7 +865,7 @@
ASSERT_NO_FATAL_FAILURE(layer = createLayer("test layer", 32, 32,
ISurfaceComposerClient::eFXSurfaceBufferState,
mBGSurfaceControl.get()));
- ASSERT_NO_FATAL_FAILURE(fillBufferStateLayerColor(layer, Color::BLACK, 32, 32));
+ ASSERT_NO_FATAL_FAILURE(fillBufferLayerColor(layer, Color::BLACK, 32, 32));
Transaction()
.show(layer)
.setLayer(layer, INT32_MAX)
@@ -885,7 +885,7 @@
ASSERT_NO_FATAL_FAILURE(layer = createLayer("test layer", 32, 32,
ISurfaceComposerClient::eFXSurfaceBufferState,
mBGSurfaceControl.get()));
- ASSERT_NO_FATAL_FAILURE(fillBufferStateLayerColor(layer, Color::BLACK, 32, 32));
+ ASSERT_NO_FATAL_FAILURE(fillBufferLayerColor(layer, Color::BLACK, 32, 32));
Transaction()
.show(layer)
.setLayer(layer, INT32_MAX)
diff --git a/services/surfaceflinger/tests/unittests/CachingTest.cpp b/services/surfaceflinger/tests/unittests/CachingTest.cpp
index 9082a22..c1cbbfb 100644
--- a/services/surfaceflinger/tests/unittests/CachingTest.cpp
+++ b/services/surfaceflinger/tests/unittests/CachingTest.cpp
@@ -20,7 +20,8 @@
#include <gmock/gmock.h>
#include <gtest/gtest.h>
#include <gui/BufferQueue.h>
-#include "BufferStateLayer.h"
+
+#include "HwcSlotGenerator.h"
namespace android {
diff --git a/services/surfaceflinger/tests/unittests/CompositionTest.cpp b/services/surfaceflinger/tests/unittests/CompositionTest.cpp
index 9485f48..7148c11 100644
--- a/services/surfaceflinger/tests/unittests/CompositionTest.cpp
+++ b/services/surfaceflinger/tests/unittests/CompositionTest.cpp
@@ -491,7 +491,7 @@
static constexpr IComposerClient::BlendMode BLENDMODE =
IComposerClient::BlendMode::PREMULTIPLIED;
- static void setupLatchedBuffer(CompositionTest* test, sp<BufferStateLayer> layer) {
+ static void setupLatchedBuffer(CompositionTest* test, sp<Layer> layer) {
Mock::VerifyAndClear(test->mRenderEngine);
const auto buffer = std::make_shared<
@@ -515,7 +515,7 @@
Mock::VerifyAndClear(test->mRenderEngine);
}
- static void setupLayerState(CompositionTest* test, sp<BufferStateLayer> layer) {
+ static void setupLayerState(CompositionTest* test, sp<Layer> layer) {
setupLatchedBuffer(test, layer);
}
@@ -699,7 +699,7 @@
using Base = BaseLayerProperties<SidebandLayerProperties>;
static constexpr IComposerClient::BlendMode BLENDMODE = IComposerClient::BlendMode::NONE;
- static void setupLayerState(CompositionTest* test, sp<BufferStateLayer> layer) {
+ static void setupLayerState(CompositionTest* test, sp<Layer> layer) {
sp<NativeHandle> stream =
NativeHandle::create(reinterpret_cast<native_handle_t*>(DEFAULT_SIDEBAND_STREAM),
false);
@@ -780,14 +780,14 @@
struct CursorLayerProperties : public BaseLayerProperties<CursorLayerProperties> {
using Base = BaseLayerProperties<CursorLayerProperties>;
- static void setupLayerState(CompositionTest* test, sp<BufferStateLayer> layer) {
+ static void setupLayerState(CompositionTest* test, sp<Layer> layer) {
Base::setupLayerState(test, layer);
test->mFlinger.setLayerPotentialCursor(layer, true);
}
};
struct NoLayerVariant {
- using FlingerLayerType = sp<BufferStateLayer>;
+ using FlingerLayerType = sp<Layer>;
static FlingerLayerType createLayer(CompositionTest*) { return FlingerLayerType(); }
static void injectLayer(CompositionTest*, FlingerLayerType) {}
@@ -892,17 +892,17 @@
template <typename LayerProperties>
struct BufferLayerVariant : public BaseLayerVariant<LayerProperties> {
using Base = BaseLayerVariant<LayerProperties>;
- using FlingerLayerType = sp<BufferStateLayer>;
+ using FlingerLayerType = sp<Layer>;
static FlingerLayerType createLayer(CompositionTest* test) {
test->mFlinger.mutableTexturePool().push_back(DEFAULT_TEXTURE_ID);
FlingerLayerType layer =
- Base::template createLayerWithFactory<BufferStateLayer>(test, [test]() {
+ Base::template createLayerWithFactory<Layer>(test, [test]() {
LayerCreationArgs args(test->mFlinger.flinger(), sp<Client>(), "test-layer",
LayerProperties::LAYER_FLAGS, LayerMetadata());
args.textureName = test->mFlinger.mutableTexturePool().back();
- return sp<BufferStateLayer>::make(args);
+ return sp<Layer>::make(args);
});
LayerProperties::setupLayerState(test, layer);
diff --git a/services/surfaceflinger/tests/unittests/FpsReporterTest.cpp b/services/surfaceflinger/tests/unittests/FpsReporterTest.cpp
index 9789df5..1cd9e49 100644
--- a/services/surfaceflinger/tests/unittests/FpsReporterTest.cpp
+++ b/services/surfaceflinger/tests/unittests/FpsReporterTest.cpp
@@ -24,7 +24,6 @@
#include <gtest/gtest.h>
#include <gui/LayerMetadata.h>
-#include "BufferStateLayer.h"
#include "FpsReporter.h"
#include "Layer.h"
#include "TestableSurfaceFlinger.h"
@@ -79,7 +78,7 @@
static constexpr int32_t PRIORITY_UNSET = -1;
void setupScheduler();
- sp<BufferStateLayer> createBufferStateLayer(LayerMetadata metadata);
+ sp<Layer> createBufferStateLayer(LayerMetadata metadata);
TestableSurfaceFlinger mFlinger;
mock::FrameTimeline mFrameTimeline =
@@ -115,10 +114,10 @@
ALOGD("**** Tearing down after %s.%s\n", test_info->test_case_name(), test_info->name());
}
-sp<BufferStateLayer> FpsReporterTest::createBufferStateLayer(LayerMetadata metadata = {}) {
+sp<Layer> FpsReporterTest::createBufferStateLayer(LayerMetadata metadata = {}) {
sp<Client> client;
LayerCreationArgs args(mFlinger.flinger(), client, "buffer-state-layer", LAYER_FLAGS, metadata);
- return sp<BufferStateLayer>::make(args);
+ return sp<Layer>::make(args);
}
void FpsReporterTest::setupScheduler() {
diff --git a/services/surfaceflinger/tests/unittests/GameModeTest.cpp b/services/surfaceflinger/tests/unittests/GameModeTest.cpp
index cd857c3..29aa717 100644
--- a/services/surfaceflinger/tests/unittests/GameModeTest.cpp
+++ b/services/surfaceflinger/tests/unittests/GameModeTest.cpp
@@ -53,11 +53,10 @@
ALOGD("**** Tearing down after %s.%s\n", test_info->test_case_name(), test_info->name());
}
- sp<BufferStateLayer> createBufferStateLayer() {
+ sp<Layer> createLayer() {
sp<Client> client;
- LayerCreationArgs args(mFlinger.flinger(), client, "buffer-state-layer", 0,
- LayerMetadata());
- return sp<BufferStateLayer>::make(args);
+ LayerCreationArgs args(mFlinger.flinger(), client, "layer", 0, LayerMetadata());
+ return sp<Layer>::make(args);
}
void setupScheduler() {
@@ -108,9 +107,9 @@
};
TEST_F(GameModeTest, SetGameModeSetsForAllCurrentChildren) {
- sp<BufferStateLayer> rootLayer = createBufferStateLayer();
- sp<BufferStateLayer> childLayer1 = createBufferStateLayer();
- sp<BufferStateLayer> childLayer2 = createBufferStateLayer();
+ sp<Layer> rootLayer = createLayer();
+ sp<Layer> childLayer1 = createLayer();
+ sp<Layer> childLayer2 = createLayer();
rootLayer->addChild(childLayer1);
rootLayer->addChild(childLayer2);
rootLayer->setGameModeForTree(GameMode::Performance);
@@ -121,8 +120,8 @@
}
TEST_F(GameModeTest, AddChildAppliesGameModeFromParent) {
- sp<BufferStateLayer> rootLayer = createBufferStateLayer();
- sp<BufferStateLayer> childLayer = createBufferStateLayer();
+ sp<Layer> rootLayer = createLayer();
+ sp<Layer> childLayer = createLayer();
rootLayer->setGameModeForTree(GameMode::Performance);
rootLayer->addChild(childLayer);
@@ -131,8 +130,8 @@
}
TEST_F(GameModeTest, RemoveChildResetsGameMode) {
- sp<BufferStateLayer> rootLayer = createBufferStateLayer();
- sp<BufferStateLayer> childLayer = createBufferStateLayer();
+ sp<Layer> rootLayer = createLayer();
+ sp<Layer> childLayer = createLayer();
rootLayer->setGameModeForTree(GameMode::Performance);
rootLayer->addChild(childLayer);
@@ -144,9 +143,9 @@
}
TEST_F(GameModeTest, ReparentingDoesNotOverrideMetadata) {
- sp<BufferStateLayer> rootLayer = createBufferStateLayer();
- sp<BufferStateLayer> childLayer1 = createBufferStateLayer();
- sp<BufferStateLayer> childLayer2 = createBufferStateLayer();
+ sp<Layer> rootLayer = createLayer();
+ sp<Layer> childLayer1 = createLayer();
+ sp<Layer> childLayer2 = createLayer();
rootLayer->setGameModeForTree(GameMode::Standard);
rootLayer->addChild(childLayer1);
diff --git a/services/surfaceflinger/tests/unittests/LayerTestUtils.cpp b/services/surfaceflinger/tests/unittests/LayerTestUtils.cpp
index 14304d1..ee42e19 100644
--- a/services/surfaceflinger/tests/unittests/LayerTestUtils.cpp
+++ b/services/surfaceflinger/tests/unittests/LayerTestUtils.cpp
@@ -29,7 +29,7 @@
sp<Client> client;
LayerCreationArgs args(flinger.flinger(), client, "buffer-state-layer", LAYER_FLAGS,
LayerMetadata());
- return sp<BufferStateLayer>::make(args);
+ return sp<Layer>::make(args);
}
sp<Layer> EffectLayerFactory::createLayer(TestableSurfaceFlinger& flinger) {
diff --git a/services/surfaceflinger/tests/unittests/RefreshRateConfigsTest.cpp b/services/surfaceflinger/tests/unittests/RefreshRateConfigsTest.cpp
index 5d9b2a8..a706c4b 100644
--- a/services/surfaceflinger/tests/unittests/RefreshRateConfigsTest.cpp
+++ b/services/surfaceflinger/tests/unittests/RefreshRateConfigsTest.cpp
@@ -41,6 +41,7 @@
struct TestableRefreshRateConfigs : RefreshRateConfigs {
using RefreshRateConfigs::RefreshRateConfigs;
+ using RefreshRateConfigs::RefreshRateOrder;
void setActiveModeId(DisplayModeId modeId) {
ftl::FakeGuard guard(kMainThreadContext);
@@ -67,19 +68,30 @@
return getMinRefreshRateByPolicyLocked();
}
+ DisplayModePtr getMaxRefreshRateByPolicy() const {
+ std::lock_guard lock(mLock);
+ return getMaxRefreshRateByPolicyLocked(getActiveModeItLocked()->second->getGroup());
+ }
+
+ std::vector<RefreshRateRanking> getRefreshRatesByPolicy(
+ std::optional<int> anchorGroupOpt, RefreshRateOrder refreshRateOrder) const {
+ std::lock_guard lock(mLock);
+ return RefreshRateConfigs::getRefreshRatesByPolicyLocked(anchorGroupOpt, refreshRateOrder);
+ }
+
const std::vector<Fps>& knownFrameRates() const { return mKnownFrameRates; }
- using RefreshRateConfigs::GetBestRefreshRateCache;
- auto& mutableGetBestRefreshRateCache() { return mGetBestRefreshRateCache; }
+ using RefreshRateConfigs::GetRankedRefreshRatesCache;
+ auto& mutableGetRankedRefreshRatesCache() { return mGetRankedRefreshRatesCache; }
- auto getBestRefreshRateAndSignals(const std::vector<LayerRequirement>& layers,
- GlobalSignals signals) const {
- return RefreshRateConfigs::getBestRefreshRate(layers, signals);
+ auto getRankedRefreshRatesAndSignals(const std::vector<LayerRequirement>& layers,
+ GlobalSignals signals) const {
+ return RefreshRateConfigs::getRankedRefreshRates(layers, signals);
}
DisplayModePtr getBestRefreshRate(const std::vector<LayerRequirement>& layers = {},
GlobalSignals signals = {}) const {
- return getBestRefreshRateAndSignals(layers, signals).first;
+ return getRankedRefreshRatesAndSignals(layers, signals).first.front().displayModePtr;
}
};
@@ -977,16 +989,116 @@
EXPECT_EQ(kMode90, configs.getBestRefreshRate(layers));
}
+TEST_F(RefreshRateConfigsTest, getMaxRefreshRatesByPolicy) {
+ // The kModes_30_60_90 contains two kMode72_G1, kMode120_G1 which are from the
+ // different group.
+ TestableRefreshRateConfigs configs(kModes_30_60_90, kModeId60);
+ const std::vector<RefreshRateRanking>& expectedRefreshRates = {RefreshRateRanking{kMode90},
+ RefreshRateRanking{kMode60},
+ RefreshRateRanking{kMode30}};
+
+ const std::vector<RefreshRateRanking>& refreshRates =
+ configs.getRefreshRatesByPolicy(configs.getActiveMode().getGroup(),
+ TestableRefreshRateConfigs::RefreshRateOrder::
+ Descending);
+
+ ASSERT_EQ(expectedRefreshRates.size(), refreshRates.size());
+ for (size_t i = 0; i < expectedRefreshRates.size(); ++i) {
+ EXPECT_EQ(expectedRefreshRates[i].displayModePtr, refreshRates[i].displayModePtr)
+ << "Expected fps " << expectedRefreshRates[i].displayModePtr->getFps().getIntValue()
+ << " Actual fps " << refreshRates[i].displayModePtr->getFps().getIntValue();
+ }
+}
+
+TEST_F(RefreshRateConfigsTest, getMinRefreshRatesByPolicy) {
+ // The kModes_30_60_90 contains two kMode72_G1, kMode120_G1 which are from the
+ // different group.
+ TestableRefreshRateConfigs configs(kModes_30_60_90, kModeId60);
+ const std::vector<RefreshRateRanking>& expectedRefreshRates = {RefreshRateRanking{kMode30},
+ RefreshRateRanking{kMode60},
+ RefreshRateRanking{kMode90}};
+
+ const std::vector<RefreshRateRanking>& refreshRates =
+ configs.getRefreshRatesByPolicy(configs.getActiveMode().getGroup(),
+ TestableRefreshRateConfigs::RefreshRateOrder::
+ Ascending);
+
+ ASSERT_EQ(expectedRefreshRates.size(), refreshRates.size());
+ for (size_t i = 0; i < expectedRefreshRates.size(); ++i) {
+ EXPECT_EQ(expectedRefreshRates[i].displayModePtr, refreshRates[i].displayModePtr)
+ << "Expected fps " << expectedRefreshRates[i].displayModePtr->getFps().getIntValue()
+ << " Actual fps " << refreshRates[i].displayModePtr->getFps().getIntValue();
+ }
+}
+
+TEST_F(RefreshRateConfigsTest, getMinRefreshRatesByPolicyOutsideTheGroup) {
+ // The kModes_30_60_90 contains two kMode72_G1, kMode120_G1 which are from the
+ // different group.
+ TestableRefreshRateConfigs configs(kModes_30_60_90, kModeId72);
+ const std::vector<RefreshRateRanking>& expectedRefreshRates = {RefreshRateRanking{kMode30},
+ RefreshRateRanking{kMode60},
+ RefreshRateRanking{kMode90}};
+
+ EXPECT_GE(configs.setDisplayManagerPolicy({kModeId60, {30_Hz, 90_Hz}, {30_Hz, 90_Hz}}), 0);
+
+ const std::vector<RefreshRateRanking>& refreshRates =
+ configs.getRefreshRatesByPolicy(/*anchorGroupOpt*/ std::nullopt,
+ TestableRefreshRateConfigs::RefreshRateOrder::
+ Ascending);
+
+ ASSERT_EQ(expectedRefreshRates.size(), refreshRates.size());
+ for (size_t i = 0; i < expectedRefreshRates.size(); ++i) {
+ EXPECT_EQ(expectedRefreshRates[i].displayModePtr, refreshRates[i].displayModePtr)
+ << "Expected fps " << expectedRefreshRates[i].displayModePtr->getFps().getIntValue()
+ << " Actual fps " << refreshRates[i].displayModePtr->getFps().getIntValue();
+ }
+}
+
+TEST_F(RefreshRateConfigsTest, getMaxRefreshRatesByPolicyOutsideTheGroup) {
+ // The kModes_30_60_90 contains two kMode72_G1, kMode120_G1 which are from the
+ // different group.
+ TestableRefreshRateConfigs configs(kModes_30_60_90, kModeId72);
+ const std::vector<RefreshRateRanking>& expectedRefreshRates = {RefreshRateRanking{kMode90},
+ RefreshRateRanking{kMode60},
+ RefreshRateRanking{kMode30}};
+
+ EXPECT_GE(configs.setDisplayManagerPolicy({kModeId60, {30_Hz, 90_Hz}, {30_Hz, 90_Hz}}), 0);
+
+ const std::vector<RefreshRateRanking>& refreshRates =
+ configs.getRefreshRatesByPolicy(/*anchorGroupOpt*/ std::nullopt,
+ TestableRefreshRateConfigs::RefreshRateOrder::
+ Descending);
+
+ ASSERT_EQ(expectedRefreshRates.size(), refreshRates.size());
+ for (size_t i = 0; i < expectedRefreshRates.size(); ++i) {
+ EXPECT_EQ(expectedRefreshRates[i].displayModePtr, refreshRates[i].displayModePtr)
+ << "Expected fps " << expectedRefreshRates[i].displayModePtr->getFps().getIntValue()
+ << " Actual fps " << refreshRates[i].displayModePtr->getFps().getIntValue();
+ }
+}
+
TEST_F(RefreshRateConfigsTest, powerOnImminentConsidered) {
RefreshRateConfigs configs(kModes_60_90, kModeId60);
+ std::vector<RefreshRateRanking> expectedRefreshRates = {RefreshRateRanking{kMode90},
+ RefreshRateRanking{kMode60}};
- auto [refreshRate, signals] = configs.getBestRefreshRate({}, {});
+ auto [refreshRates, signals] = configs.getRankedRefreshRates({}, {});
EXPECT_FALSE(signals.powerOnImminent);
- EXPECT_EQ(kMode90, refreshRate);
+ ASSERT_EQ(expectedRefreshRates.size(), refreshRates.size());
+ for (size_t i = 0; i < expectedRefreshRates.size(); ++i) {
+ EXPECT_EQ(expectedRefreshRates[i].displayModePtr, refreshRates[i].displayModePtr)
+ << "Expected fps " << expectedRefreshRates[i].displayModePtr->getFps().getIntValue()
+ << " Actual fps " << refreshRates[i].displayModePtr->getFps().getIntValue();
+ }
- std::tie(refreshRate, signals) = configs.getBestRefreshRate({}, {.powerOnImminent = true});
+ std::tie(refreshRates, signals) = configs.getRankedRefreshRates({}, {.powerOnImminent = true});
EXPECT_TRUE(signals.powerOnImminent);
- EXPECT_EQ(kMode90, refreshRate);
+ ASSERT_EQ(expectedRefreshRates.size(), refreshRates.size());
+ for (size_t i = 0; i < expectedRefreshRates.size(); ++i) {
+ EXPECT_EQ(expectedRefreshRates[i].displayModePtr, refreshRates[i].displayModePtr)
+ << "Expected fps " << expectedRefreshRates[i].displayModePtr->getFps().getIntValue()
+ << " Actual fps " << refreshRates[i].displayModePtr->getFps().getIntValue();
+ }
std::vector<LayerRequirement> layers = {{.weight = 1.f}};
auto& lr1 = layers[0];
@@ -994,22 +1106,35 @@
lr1.desiredRefreshRate = 60_Hz;
lr1.name = "60Hz ExplicitExactOrMultiple";
- std::tie(refreshRate, signals) = configs.getBestRefreshRate(layers, {.powerOnImminent = false});
- EXPECT_FALSE(signals.powerOnImminent);
- EXPECT_EQ(kMode60, refreshRate);
-
- std::tie(refreshRate, signals) = configs.getBestRefreshRate(layers, {.powerOnImminent = true});
+ std::tie(refreshRates, signals) =
+ configs.getRankedRefreshRates(layers, {.powerOnImminent = true});
EXPECT_TRUE(signals.powerOnImminent);
- EXPECT_EQ(kMode90, refreshRate);
+ ASSERT_EQ(expectedRefreshRates.size(), refreshRates.size());
+ for (size_t i = 0; i < expectedRefreshRates.size(); ++i) {
+ EXPECT_EQ(expectedRefreshRates[i].displayModePtr, refreshRates[i].displayModePtr)
+ << "Expected fps " << expectedRefreshRates[i].displayModePtr->getFps().getIntValue()
+ << " Actual fps " << refreshRates[i].displayModePtr->getFps().getIntValue();
+ }
+
+ expectedRefreshRates = {RefreshRateRanking{kMode60}, RefreshRateRanking{kMode90}};
+ std::tie(refreshRates, signals) =
+ configs.getRankedRefreshRates(layers, {.powerOnImminent = false});
+ EXPECT_FALSE(signals.powerOnImminent);
+ ASSERT_EQ(expectedRefreshRates.size(), refreshRates.size());
+ for (size_t i = 0; i < expectedRefreshRates.size(); ++i) {
+ EXPECT_EQ(expectedRefreshRates[i].displayModePtr, refreshRates[i].displayModePtr)
+ << "Expected fps " << expectedRefreshRates[i].displayModePtr->getFps().getIntValue()
+ << " Actual fps " << refreshRates[i].displayModePtr->getFps().getIntValue();
+ }
}
TEST_F(RefreshRateConfigsTest, touchConsidered) {
RefreshRateConfigs configs(kModes_60_90, kModeId60);
- auto [_, signals] = configs.getBestRefreshRate({}, {});
+ auto [_, signals] = configs.getRankedRefreshRates({}, {});
EXPECT_FALSE(signals.touch);
- std::tie(std::ignore, signals) = configs.getBestRefreshRate({}, {.touch = true});
+ std::tie(std::ignore, signals) = configs.getRankedRefreshRates({}, {.touch = true});
EXPECT_TRUE(signals.touch);
std::vector<LayerRequirement> layers = {{.weight = 1.f}, {.weight = 1.f}};
@@ -1022,16 +1147,16 @@
lr2.vote = LayerVoteType::Heuristic;
lr2.desiredRefreshRate = 60_Hz;
lr2.name = "60Hz Heuristic";
- std::tie(std::ignore, signals) = configs.getBestRefreshRate(layers, {.touch = true});
+ std::tie(std::ignore, signals) = configs.getRankedRefreshRates(layers, {.touch = true});
EXPECT_TRUE(signals.touch);
lr1.vote = LayerVoteType::ExplicitDefault;
lr1.desiredRefreshRate = 60_Hz;
- lr1.name = "60Hz ExplicitExactOrMultiple";
+ lr1.name = "60Hz ExplicitDefault";
lr2.vote = LayerVoteType::Heuristic;
lr2.desiredRefreshRate = 60_Hz;
lr2.name = "60Hz Heuristic";
- std::tie(std::ignore, signals) = configs.getBestRefreshRate(layers, {.touch = true});
+ std::tie(std::ignore, signals) = configs.getRankedRefreshRates(layers, {.touch = true});
EXPECT_FALSE(signals.touch);
lr1.vote = LayerVoteType::ExplicitExactOrMultiple;
@@ -1040,16 +1165,16 @@
lr2.vote = LayerVoteType::Heuristic;
lr2.desiredRefreshRate = 60_Hz;
lr2.name = "60Hz Heuristic";
- std::tie(std::ignore, signals) = configs.getBestRefreshRate(layers, {.touch = true});
+ std::tie(std::ignore, signals) = configs.getRankedRefreshRates(layers, {.touch = true});
EXPECT_TRUE(signals.touch);
lr1.vote = LayerVoteType::ExplicitDefault;
lr1.desiredRefreshRate = 60_Hz;
- lr1.name = "60Hz ExplicitExactOrMultiple";
+ lr1.name = "60Hz ExplicitDefault";
lr2.vote = LayerVoteType::Heuristic;
lr2.desiredRefreshRate = 60_Hz;
lr2.name = "60Hz Heuristic";
- std::tie(std::ignore, signals) = configs.getBestRefreshRate(layers, {.touch = true});
+ std::tie(std::ignore, signals) = configs.getRankedRefreshRates(layers, {.touch = true});
EXPECT_FALSE(signals.touch);
}
@@ -1187,9 +1312,10 @@
lr.name = "60Hz ExplicitDefault";
lr.focused = true;
- const auto [mode, signals] = configs.getBestRefreshRate(layers, {.touch = true, .idle = true});
+ const auto [mode, signals] =
+ configs.getRankedRefreshRates(layers, {.touch = true, .idle = true});
- EXPECT_EQ(mode, kMode60);
+ EXPECT_EQ(mode.begin()->displayModePtr, kMode60);
EXPECT_FALSE(signals.touch);
}
@@ -1209,14 +1335,147 @@
EXPECT_EQ(kMode90, configs.getBestRefreshRate(layers, {.idle = true}));
}
+TEST_F(RefreshRateConfigsTest, testDisplayModeOrdering) {
+ TestableRefreshRateConfigs configs(kModes_30_60_72_90_120, kModeId60);
+
+ std::vector<LayerRequirement> layers = {{.weight = 1.f},
+ {.weight = 1.f},
+ {.weight = 1.f},
+ {.weight = 1.f},
+ {.weight = 1.f}};
+ auto& lr1 = layers[0];
+ auto& lr2 = layers[1];
+ auto& lr3 = layers[2];
+ auto& lr4 = layers[3];
+ auto& lr5 = layers[4];
+
+ lr1.desiredRefreshRate = 90_Hz;
+ lr1.name = "90Hz";
+ lr1.focused = true;
+
+ lr2.desiredRefreshRate = 60_Hz;
+ lr2.name = "60Hz";
+ lr2.focused = true;
+
+ lr3.desiredRefreshRate = 72_Hz;
+ lr3.name = "72Hz";
+ lr3.focused = true;
+
+ lr4.desiredRefreshRate = 120_Hz;
+ lr4.name = "120Hz";
+ lr4.focused = true;
+
+ lr5.desiredRefreshRate = 30_Hz;
+ lr5.name = "30Hz";
+ lr5.focused = true;
+
+ std::vector<RefreshRateRanking> expectedRankings = {
+ RefreshRateRanking{kMode120}, RefreshRateRanking{kMode90}, RefreshRateRanking{kMode72},
+ RefreshRateRanking{kMode60}, RefreshRateRanking{kMode30},
+ };
+
+ std::vector<RefreshRateRanking> actualOrder =
+ configs.getRankedRefreshRatesAndSignals(layers, {}).first;
+ ASSERT_EQ(expectedRankings.size(), actualOrder.size());
+ for (size_t i = 0; i < expectedRankings.size(); ++i) {
+ EXPECT_EQ(expectedRankings[i].displayModePtr, actualOrder[i].displayModePtr)
+ << "Expected fps " << expectedRankings[i].displayModePtr->getFps().getIntValue()
+ << " Actual fps " << actualOrder[i].displayModePtr->getFps().getIntValue();
+ }
+
+ lr1.vote = LayerVoteType::Max;
+ lr1.name = "Max";
+
+ lr2.desiredRefreshRate = 60_Hz;
+ lr2.name = "60Hz";
+
+ lr3.desiredRefreshRate = 72_Hz;
+ lr3.name = "72Hz";
+
+ lr4.desiredRefreshRate = 90_Hz;
+ lr4.name = "90Hz";
+
+ lr5.desiredRefreshRate = 120_Hz;
+ lr5.name = "120Hz";
+
+ expectedRankings = {
+ RefreshRateRanking{kMode120}, RefreshRateRanking{kMode90}, RefreshRateRanking{kMode72},
+ RefreshRateRanking{kMode60}, RefreshRateRanking{kMode30},
+ };
+
+ actualOrder = configs.getRankedRefreshRatesAndSignals(layers, {}).first;
+
+ ASSERT_EQ(expectedRankings.size(), actualOrder.size());
+ for (size_t i = 0; i < expectedRankings.size(); ++i) {
+ EXPECT_EQ(expectedRankings[i].displayModePtr, actualOrder[i].displayModePtr)
+ << "Expected fps " << expectedRankings[i].displayModePtr->getFps().getIntValue()
+ << " Actual fps " << actualOrder[i].displayModePtr->getFps().getIntValue();
+ }
+
+ lr1.vote = LayerVoteType::Heuristic;
+ lr1.desiredRefreshRate = 30_Hz;
+ lr1.name = "30Hz";
+
+ lr2.desiredRefreshRate = 120_Hz;
+ lr2.name = "120Hz";
+
+ lr3.desiredRefreshRate = 60_Hz;
+ lr3.name = "60Hz";
+
+ lr5.desiredRefreshRate = 72_Hz;
+ lr5.name = "72Hz";
+
+ expectedRankings = {
+ RefreshRateRanking{kMode30}, RefreshRateRanking{kMode60}, RefreshRateRanking{kMode90},
+ RefreshRateRanking{kMode120}, RefreshRateRanking{kMode72},
+ };
+
+ actualOrder = configs.getRankedRefreshRatesAndSignals(layers, {}).first;
+ ASSERT_EQ(expectedRankings.size(), actualOrder.size());
+ for (size_t i = 0; i < expectedRankings.size(); ++i) {
+ EXPECT_EQ(expectedRankings[i].displayModePtr, actualOrder[i].displayModePtr)
+ << "Expected fps " << expectedRankings[i].displayModePtr->getFps().getIntValue()
+ << " Actual fps " << actualOrder[i].displayModePtr->getFps().getIntValue();
+ }
+
+ lr1.desiredRefreshRate = 120_Hz;
+ lr1.name = "120Hz";
+ lr1.weight = 0.0f;
+
+ lr2.desiredRefreshRate = 60_Hz;
+ lr2.name = "60Hz";
+ lr2.vote = LayerVoteType::NoVote;
+
+ lr3.name = "60Hz-2";
+ lr3.vote = LayerVoteType::Heuristic;
+
+ lr4.vote = LayerVoteType::ExplicitExact;
+
+ lr5.desiredRefreshRate = 120_Hz;
+ lr5.name = "120Hz-2";
+
+ expectedRankings = {
+ RefreshRateRanking{kMode90}, RefreshRateRanking{kMode60}, RefreshRateRanking{kMode120},
+ RefreshRateRanking{kMode72}, RefreshRateRanking{kMode30},
+ };
+
+ actualOrder = configs.getRankedRefreshRatesAndSignals(layers, {}).first;
+ ASSERT_EQ(expectedRankings.size(), actualOrder.size());
+ for (size_t i = 0; i < expectedRankings.size(); ++i) {
+ EXPECT_EQ(expectedRankings[i].displayModePtr, actualOrder[i].displayModePtr)
+ << "Expected fps " << expectedRankings[i].displayModePtr->getFps().getIntValue()
+ << " Actual fps " << actualOrder[i].displayModePtr->getFps().getIntValue();
+ }
+}
+
TEST_F(RefreshRateConfigsTest,
getBestRefreshRate_withDisplayManagerRequestingSingleRate_onlySwitchesRatesForExplicitFocusedLayers) {
TestableRefreshRateConfigs configs(kModes_60_90, kModeId90);
EXPECT_GE(configs.setDisplayManagerPolicy({kModeId90, {90_Hz, 90_Hz}, {60_Hz, 90_Hz}}), 0);
- const auto [mode, signals] = configs.getBestRefreshRateAndSignals({}, {});
- EXPECT_EQ(mode, kMode90);
+ const auto [mode, signals] = configs.getRankedRefreshRatesAndSignals({}, {});
+ EXPECT_EQ(mode.front().displayModePtr, kMode90);
EXPECT_FALSE(signals.touch);
std::vector<LayerRequirement> layers = {{.weight = 1.f}};
@@ -1593,11 +1852,12 @@
layers[0].desiredRefreshRate = 90_Hz;
const auto [refreshRate, signals] =
- configs.getBestRefreshRateAndSignals(layers, {.touch = touchActive, .idle = true});
+ configs.getRankedRefreshRatesAndSignals(layers,
+ {.touch = touchActive, .idle = true});
// Refresh rate will be chosen by either touch state or idle state.
EXPECT_EQ(!touchActive, signals.idle);
- return refreshRate->getId();
+ return refreshRate.front().displayModePtr->getId();
};
EXPECT_GE(configs.setDisplayManagerPolicy({kModeId60, {60_Hz, 90_Hz}, {60_Hz, 90_Hz}}), 0);
@@ -1756,24 +2016,26 @@
using GlobalSignals = RefreshRateConfigs::GlobalSignals;
const auto args = std::make_pair(std::vector<LayerRequirement>{},
GlobalSignals{.touch = true, .idle = true});
- const auto result = std::make_pair(kMode90, GlobalSignals{.touch = true});
- configs.mutableGetBestRefreshRateCache() = {args, result};
+ const auto result = std::make_pair(std::vector<RefreshRateRanking>{RefreshRateRanking{kMode90}},
+ GlobalSignals{.touch = true});
- EXPECT_EQ(result, configs.getBestRefreshRateAndSignals(args.first, args.second));
+ configs.mutableGetRankedRefreshRatesCache() = {args, result};
+
+ EXPECT_EQ(result, configs.getRankedRefreshRatesAndSignals(args.first, args.second));
}
TEST_F(RefreshRateConfigsTest, getBestRefreshRate_WritesCache) {
TestableRefreshRateConfigs configs(kModes_30_60_72_90_120, kModeId60);
- EXPECT_FALSE(configs.mutableGetBestRefreshRateCache());
+ EXPECT_FALSE(configs.mutableGetRankedRefreshRatesCache());
std::vector<LayerRequirement> layers = {{.weight = 1.f}, {.weight = 0.5f}};
RefreshRateConfigs::GlobalSignals globalSignals{.touch = true, .idle = true};
- const auto result = configs.getBestRefreshRateAndSignals(layers, globalSignals);
+ const auto result = configs.getRankedRefreshRatesAndSignals(layers, globalSignals);
- const auto& cache = configs.mutableGetBestRefreshRateCache();
+ const auto& cache = configs.mutableGetRankedRefreshRatesCache();
ASSERT_TRUE(cache);
EXPECT_EQ(cache->arguments, std::make_pair(layers, globalSignals));
diff --git a/services/surfaceflinger/tests/unittests/RefreshRateSelectionTest.cpp b/services/surfaceflinger/tests/unittests/RefreshRateSelectionTest.cpp
index abf1786..ac63a0e 100644
--- a/services/surfaceflinger/tests/unittests/RefreshRateSelectionTest.cpp
+++ b/services/surfaceflinger/tests/unittests/RefreshRateSelectionTest.cpp
@@ -21,7 +21,6 @@
#include <gtest/gtest.h>
#include <gui/LayerMetadata.h>
-#include "BufferStateLayer.h"
#include "Layer.h"
#include "TestableSurfaceFlinger.h"
#include "mock/DisplayHardware/MockComposer.h"
@@ -58,7 +57,7 @@
static constexpr int32_t PRIORITY_UNSET = -1;
void setupScheduler();
- sp<BufferStateLayer> createBufferStateLayer();
+ sp<Layer> createBufferStateLayer();
sp<Layer> createEffectLayer();
void setParent(Layer* child, Layer* parent);
@@ -87,12 +86,11 @@
ALOGD("**** Tearing down after %s.%s\n", test_info->test_case_name(), test_info->name());
}
-
-sp<BufferStateLayer> RefreshRateSelectionTest::createBufferStateLayer() {
+sp<Layer> RefreshRateSelectionTest::createBufferStateLayer() {
sp<Client> client;
LayerCreationArgs args(mFlinger.flinger(), client, "buffer-queue-layer", LAYER_FLAGS,
LayerMetadata());
- return sp<BufferStateLayer>::make(args);
+ return sp<Layer>::make(args);
}
sp<Layer> RefreshRateSelectionTest::createEffectLayer() {
diff --git a/services/surfaceflinger/tests/unittests/RegionSamplingTest.cpp b/services/surfaceflinger/tests/unittests/RegionSamplingTest.cpp
index f19e554..409e1ef 100644
--- a/services/surfaceflinger/tests/unittests/RegionSamplingTest.cpp
+++ b/services/surfaceflinger/tests/unittests/RegionSamplingTest.cpp
@@ -106,40 +106,6 @@
testing::Eq(0.0));
}
-// workaround for b/133849373
-TEST_F(RegionSamplingTest, orientation_90) {
- std::generate(buffer.begin(), buffer.end(),
- [n = 0]() mutable { return (n++ > (kStride * kHeight >> 1)) ? kBlack : kWhite; });
-
- Rect tl_region{0, 0, 4, 4};
- EXPECT_THAT(sampleArea(buffer.data(), kWidth, kHeight, kStride, ui::Transform::ROT_0,
- tl_region),
- testing::Eq(1.0));
- EXPECT_THAT(sampleArea(buffer.data(), kWidth, kHeight, kStride, ui::Transform::ROT_180,
- tl_region),
- testing::Eq(1.0));
- EXPECT_THAT(sampleArea(buffer.data(), kWidth, kHeight, kStride, ui::Transform::ROT_90,
- tl_region),
- testing::Eq(0.0));
- EXPECT_THAT(sampleArea(buffer.data(), kWidth, kHeight, kStride, ui::Transform::ROT_270,
- tl_region),
- testing::Eq(0.0));
-
- Rect br_region{kWidth - 4, kHeight - 4, kWidth, kHeight};
- EXPECT_THAT(sampleArea(buffer.data(), kWidth, kHeight, kStride, ui::Transform::ROT_0,
- br_region),
- testing::Eq(0.0));
- EXPECT_THAT(sampleArea(buffer.data(), kWidth, kHeight, kStride, ui::Transform::ROT_180,
- br_region),
- testing::Eq(0.0));
- EXPECT_THAT(sampleArea(buffer.data(), kWidth, kHeight, kStride, ui::Transform::ROT_90,
- br_region),
- testing::Eq(1.0));
- EXPECT_THAT(sampleArea(buffer.data(), kWidth, kHeight, kStride, ui::Transform::ROT_270,
- br_region),
- testing::Eq(1.0));
-}
-
} // namespace android
// TODO(b/129481165): remove the #pragma below and fix conversion issues
diff --git a/services/surfaceflinger/tests/unittests/SetFrameRateTest.cpp b/services/surfaceflinger/tests/unittests/SetFrameRateTest.cpp
index 51c6bea..dfcfd91 100644
--- a/services/surfaceflinger/tests/unittests/SetFrameRateTest.cpp
+++ b/services/surfaceflinger/tests/unittests/SetFrameRateTest.cpp
@@ -24,7 +24,6 @@
// TODO(b/129481165): remove the #pragma below and fix conversion issues
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wconversion"
-#include "BufferStateLayer.h"
#include "Layer.h"
// TODO(b/129481165): remove the #pragma below and fix conversion issues
#pragma clang diagnostic pop // ignored "-Wconversion"
diff --git a/services/surfaceflinger/tests/unittests/SurfaceFlinger_DisplayModeSwitching.cpp b/services/surfaceflinger/tests/unittests/SurfaceFlinger_DisplayModeSwitching.cpp
index 57937dc..6b7e353 100644
--- a/services/surfaceflinger/tests/unittests/SurfaceFlinger_DisplayModeSwitching.cpp
+++ b/services/surfaceflinger/tests/unittests/SurfaceFlinger_DisplayModeSwitching.cpp
@@ -20,6 +20,7 @@
#include "DisplayTransactionTestHelpers.h"
+#include <ftl/fake_guard.h>
#include <scheduler/Fps.h>
namespace android {
@@ -111,8 +112,10 @@
}
TEST_F(DisplayModeSwitchingTest, changeRefreshRate_OnActiveDisplay_WithRefreshRequired) {
+ ftl::FakeGuard guard(kMainThreadContext);
+
ASSERT_FALSE(mDisplay->getDesiredActiveMode().has_value());
- ASSERT_EQ(mDisplay->getActiveMode()->getId(), kModeId60);
+ ASSERT_EQ(mDisplay->getActiveMode().getId(), kModeId60);
mFlinger.onActiveDisplayChanged(mDisplay);
@@ -121,7 +124,7 @@
ASSERT_TRUE(mDisplay->getDesiredActiveMode().has_value());
ASSERT_EQ(mDisplay->getDesiredActiveMode()->mode->getId(), kModeId90);
- ASSERT_EQ(mDisplay->getActiveMode()->getId(), kModeId60);
+ ASSERT_EQ(mDisplay->getActiveMode().getId(), kModeId60);
// Verify that next commit will call setActiveConfigWithConstraints in HWC
const VsyncPeriodChangeTimeline timeline{.refreshRequired = true};
@@ -134,7 +137,7 @@
Mock::VerifyAndClearExpectations(mComposer);
ASSERT_TRUE(mDisplay->getDesiredActiveMode().has_value());
- ASSERT_EQ(mDisplay->getActiveMode()->getId(), kModeId60);
+ ASSERT_EQ(mDisplay->getActiveMode().getId(), kModeId60);
// Verify that the next commit will complete the mode change and send
// a onModeChanged event to the framework.
@@ -144,10 +147,12 @@
Mock::VerifyAndClearExpectations(mAppEventThread);
ASSERT_FALSE(mDisplay->getDesiredActiveMode().has_value());
- ASSERT_EQ(mDisplay->getActiveMode()->getId(), kModeId90);
+ ASSERT_EQ(mDisplay->getActiveMode().getId(), kModeId90);
}
TEST_F(DisplayModeSwitchingTest, changeRefreshRate_OnActiveDisplay_WithoutRefreshRequired) {
+ ftl::FakeGuard guard(kMainThreadContext);
+
ASSERT_FALSE(mDisplay->getDesiredActiveMode().has_value());
mFlinger.onActiveDisplayChanged(mDisplay);
@@ -157,7 +162,7 @@
ASSERT_TRUE(mDisplay->getDesiredActiveMode().has_value());
ASSERT_EQ(mDisplay->getDesiredActiveMode()->mode->getId(), kModeId90);
- ASSERT_EQ(mDisplay->getActiveMode()->getId(), kModeId60);
+ ASSERT_EQ(mDisplay->getActiveMode().getId(), kModeId60);
// Verify that next commit will call setActiveConfigWithConstraints in HWC
// and complete the mode change.
@@ -172,15 +177,17 @@
mFlinger.commit();
ASSERT_FALSE(mDisplay->getDesiredActiveMode().has_value());
- ASSERT_EQ(mDisplay->getActiveMode()->getId(), kModeId90);
+ ASSERT_EQ(mDisplay->getActiveMode().getId(), kModeId90);
}
TEST_F(DisplayModeSwitchingTest, twoConsecutiveSetDesiredDisplayModeSpecs) {
+ ftl::FakeGuard guard(kMainThreadContext);
+
// Test that if we call setDesiredDisplayModeSpecs while a previous mode change
// is still being processed the later call will be respected.
ASSERT_FALSE(mDisplay->getDesiredActiveMode().has_value());
- ASSERT_EQ(mDisplay->getActiveMode()->getId(), kModeId60);
+ ASSERT_EQ(mDisplay->getActiveMode().getId(), kModeId60);
mFlinger.onActiveDisplayChanged(mDisplay);
@@ -214,12 +221,14 @@
mFlinger.commit();
ASSERT_FALSE(mDisplay->getDesiredActiveMode().has_value());
- ASSERT_EQ(mDisplay->getActiveMode()->getId(), kModeId120);
+ ASSERT_EQ(mDisplay->getActiveMode().getId(), kModeId120);
}
TEST_F(DisplayModeSwitchingTest, changeResolution_OnActiveDisplay_WithoutRefreshRequired) {
+ ftl::FakeGuard guard(kMainThreadContext);
+
ASSERT_FALSE(mDisplay->getDesiredActiveMode().has_value());
- ASSERT_EQ(mDisplay->getActiveMode()->getId(), kModeId60);
+ ASSERT_EQ(mDisplay->getActiveMode().getId(), kModeId60);
mFlinger.onActiveDisplayChanged(mDisplay);
@@ -228,7 +237,7 @@
ASSERT_TRUE(mDisplay->getDesiredActiveMode().has_value());
ASSERT_EQ(mDisplay->getDesiredActiveMode()->mode->getId(), kModeId90_4K);
- ASSERT_EQ(mDisplay->getActiveMode()->getId(), kModeId60);
+ ASSERT_EQ(mDisplay->getActiveMode().getId(), kModeId60);
// Verify that next commit will call setActiveConfigWithConstraints in HWC
// and complete the mode change.
@@ -263,7 +272,7 @@
mDisplay = mFlinger.getDisplay(displayToken);
ASSERT_FALSE(mDisplay->getDesiredActiveMode().has_value());
- ASSERT_EQ(mDisplay->getActiveMode()->getId(), kModeId90_4K);
+ ASSERT_EQ(mDisplay->getActiveMode().getId(), kModeId90_4K);
}
} // namespace
diff --git a/services/surfaceflinger/tests/unittests/SurfaceFlinger_SetupNewDisplayDeviceInternalTest.cpp b/services/surfaceflinger/tests/unittests/SurfaceFlinger_SetupNewDisplayDeviceInternalTest.cpp
index ec2c2b4..073c459 100644
--- a/services/surfaceflinger/tests/unittests/SurfaceFlinger_SetupNewDisplayDeviceInternalTest.cpp
+++ b/services/surfaceflinger/tests/unittests/SurfaceFlinger_SetupNewDisplayDeviceInternalTest.cpp
@@ -17,6 +17,8 @@
#undef LOG_TAG
#define LOG_TAG "LibSurfaceFlingerUnittests"
+#include <ftl/fake_guard.h>
+
#include "DisplayHardware/DisplayMode.h"
#include "DisplayTransactionTestHelpers.h"
@@ -265,7 +267,7 @@
// --------------------------------------------------------------------
// Postconditions
- ASSERT_TRUE(device != nullptr);
+ ASSERT_NE(nullptr, device);
EXPECT_EQ(Case::Display::DISPLAY_ID::get(), device->getId());
EXPECT_EQ(static_cast<bool>(Case::Display::VIRTUAL), device->isVirtual());
EXPECT_EQ(static_cast<bool>(Case::Display::SECURE), device->isSecure());
@@ -282,8 +284,8 @@
device->receivesInput());
if constexpr (Case::Display::CONNECTION_TYPE::value) {
- EXPECT_NE(nullptr, device->getActiveMode());
- EXPECT_EQ(Case::Display::HWC_ACTIVE_CONFIG_ID, device->getActiveMode()->getHwcId());
+ ftl::FakeGuard guard(kMainThreadContext);
+ EXPECT_EQ(Case::Display::HWC_ACTIVE_CONFIG_ID, device->getActiveMode().getHwcId());
}
}
diff --git a/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h b/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h
index 1ce6e18..2c9c451 100644
--- a/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h
+++ b/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h
@@ -30,7 +30,6 @@
#include <ftl/fake_guard.h>
#include <gui/ScreenCaptureResults.h>
-#include "BufferStateLayer.h"
#include "DisplayDevice.h"
#include "FakeVsyncConfiguration.h"
#include "FrameTracer/FrameTracer.h"
@@ -120,9 +119,7 @@
return compositionengine::impl::createCompositionEngine();
}
- sp<BufferStateLayer> createBufferStateLayer(const LayerCreationArgs&) override {
- return nullptr;
- }
+ sp<Layer> createBufferStateLayer(const LayerCreationArgs&) override { return nullptr; }
sp<Layer> createEffectLayer(const LayerCreationArgs&) override { return nullptr; }
@@ -288,7 +285,7 @@
const sp<NativeHandle>& sidebandStream) {
layer->mDrawingState.sidebandStream = sidebandStream;
layer->mSidebandStream = sidebandStream;
- layer->editCompositionState()->sidebandStream = sidebandStream;
+ layer->editLayerSnapshot()->sidebandStream = sidebandStream;
}
void setLayerCompositionType(const sp<Layer>& layer,
diff --git a/services/surfaceflinger/tests/unittests/TransactionApplicationTest.cpp b/services/surfaceflinger/tests/unittests/TransactionApplicationTest.cpp
index efb9e0c..b493d11 100644
--- a/services/surfaceflinger/tests/unittests/TransactionApplicationTest.cpp
+++ b/services/surfaceflinger/tests/unittests/TransactionApplicationTest.cpp
@@ -347,8 +347,7 @@
state.state.bufferData->acquireFence = std::move(fence);
state.state.layerId = layerId;
state.state.surface =
- sp<BufferStateLayer>::make(
- LayerCreationArgs(mFlinger.flinger(), nullptr, "TestLayer", 0, {}))
+ sp<Layer>::make(LayerCreationArgs(mFlinger.flinger(), nullptr, "TestLayer", 0, {}))
->getHandle();
state.state.bufferData->flags = BufferData::BufferDataChange::fenceChanged;
diff --git a/services/surfaceflinger/tests/unittests/TransactionFrameTracerTest.cpp b/services/surfaceflinger/tests/unittests/TransactionFrameTracerTest.cpp
index cd64325..1173d1c 100644
--- a/services/surfaceflinger/tests/unittests/TransactionFrameTracerTest.cpp
+++ b/services/surfaceflinger/tests/unittests/TransactionFrameTracerTest.cpp
@@ -56,11 +56,11 @@
ALOGD("**** Tearing down after %s.%s\n", test_info->test_case_name(), test_info->name());
}
- sp<BufferStateLayer> createBufferStateLayer() {
+ sp<Layer> createLayer() {
sp<Client> client;
LayerCreationArgs args(mFlinger.flinger(), client, "buffer-state-layer", 0,
LayerMetadata());
- return sp<BufferStateLayer>::make(args);
+ return sp<Layer>::make(args);
}
void commitTransaction(Layer* layer) {
@@ -101,7 +101,7 @@
FenceToFenceTimeMap fenceFactory;
void BLASTTransactionSendsFrameTracerEvents() {
- sp<BufferStateLayer> layer = createBufferStateLayer();
+ sp<Layer> layer = createLayer();
sp<Fence> fence(sp<Fence>::make());
int32_t layerId = layer->getSequence();
diff --git a/services/surfaceflinger/tests/unittests/TransactionSurfaceFrameTest.cpp b/services/surfaceflinger/tests/unittests/TransactionSurfaceFrameTest.cpp
index d5823c3..ae03db4 100644
--- a/services/surfaceflinger/tests/unittests/TransactionSurfaceFrameTest.cpp
+++ b/services/surfaceflinger/tests/unittests/TransactionSurfaceFrameTest.cpp
@@ -56,11 +56,10 @@
ALOGD("**** Tearing down after %s.%s\n", test_info->test_case_name(), test_info->name());
}
- sp<BufferStateLayer> createBufferStateLayer() {
+ sp<Layer> createLayer() {
sp<Client> client;
- LayerCreationArgs args(mFlinger.flinger(), client, "buffer-state-layer", 0,
- LayerMetadata());
- return sp<BufferStateLayer>::make(args);
+ LayerCreationArgs args(mFlinger.flinger(), client, "layer", 0, LayerMetadata());
+ return sp<Layer>::make(args);
}
void commitTransaction(Layer* layer) {
@@ -101,7 +100,7 @@
FenceToFenceTimeMap fenceFactory;
void PresentedSurfaceFrameForBufferlessTransaction() {
- sp<BufferStateLayer> layer = createBufferStateLayer();
+ sp<Layer> layer = createLayer();
FrameTimelineInfo ftInfo;
ftInfo.vsyncId = 1;
ftInfo.inputEventId = 0;
@@ -116,7 +115,7 @@
}
void PresentedSurfaceFrameForBufferTransaction() {
- sp<BufferStateLayer> layer = createBufferStateLayer();
+ sp<Layer> layer = createLayer();
sp<Fence> fence(sp<Fence>::make());
auto acquireFence = fenceFactory.createFenceTimeForTest(fence);
BufferData bufferData;
@@ -150,7 +149,7 @@
}
void DroppedSurfaceFrameForBufferTransaction() {
- sp<BufferStateLayer> layer = createBufferStateLayer();
+ sp<Layer> layer = createLayer();
sp<Fence> fence1(sp<Fence>::make());
auto acquireFence1 = fenceFactory.createFenceTimeForTest(fence1);
@@ -208,7 +207,7 @@
}
void BufferlessSurfaceFramePromotedToBufferSurfaceFrame() {
- sp<BufferStateLayer> layer = createBufferStateLayer();
+ sp<Layer> layer = createLayer();
FrameTimelineInfo ftInfo;
ftInfo.vsyncId = 1;
ftInfo.inputEventId = 0;
@@ -249,7 +248,7 @@
}
void BufferlessSurfaceFrameNotCreatedIfBufferSufaceFrameExists() {
- sp<BufferStateLayer> layer = createBufferStateLayer();
+ sp<Layer> layer = createLayer();
sp<Fence> fence(sp<Fence>::make());
auto acquireFence = fenceFactory.createFenceTimeForTest(fence);
BufferData bufferData;
@@ -275,7 +274,7 @@
}
void MultipleSurfaceFramesPresentedTogether() {
- sp<BufferStateLayer> layer = createBufferStateLayer();
+ sp<Layer> layer = createLayer();
FrameTimelineInfo ftInfo;
ftInfo.vsyncId = 1;
ftInfo.inputEventId = 0;
@@ -336,7 +335,7 @@
}
void PendingSurfaceFramesRemovedAfterClassification() {
- sp<BufferStateLayer> layer = createBufferStateLayer();
+ sp<Layer> layer = createLayer();
sp<Fence> fence1(sp<Fence>::make());
auto acquireFence1 = fenceFactory.createFenceTimeForTest(fence1);
@@ -388,7 +387,7 @@
}
void BufferSurfaceFrame_ReplaceValidTokenBufferWithInvalidTokenBuffer() {
- sp<BufferStateLayer> layer = createBufferStateLayer();
+ sp<Layer> layer = createLayer();
sp<Fence> fence1(sp<Fence>::make());
auto acquireFence1 = fenceFactory.createFenceTimeForTest(fence1);
@@ -477,7 +476,7 @@
}
void MultipleCommitsBeforeLatch() {
- sp<BufferStateLayer> layer = createBufferStateLayer();
+ sp<Layer> layer = createLayer();
uint32_t surfaceFramesPendingClassification = 0;
std::vector<std::shared_ptr<frametimeline::SurfaceFrame>> bufferlessSurfaceFrames;
for (int i = 0; i < 10; i += 2) {
diff --git a/services/surfaceflinger/tests/unittests/TunnelModeEnabledReporterTest.cpp b/services/surfaceflinger/tests/unittests/TunnelModeEnabledReporterTest.cpp
index 45ebb85..da87f1d 100644
--- a/services/surfaceflinger/tests/unittests/TunnelModeEnabledReporterTest.cpp
+++ b/services/surfaceflinger/tests/unittests/TunnelModeEnabledReporterTest.cpp
@@ -22,7 +22,6 @@
#include <gtest/gtest.h>
#include <gui/LayerMetadata.h>
-#include "BufferStateLayer.h"
#include "TestableSurfaceFlinger.h"
#include "TunnelModeEnabledReporter.h"
#include "mock/DisplayHardware/MockComposer.h"
@@ -64,7 +63,7 @@
void setupScheduler();
void setupComposer(uint32_t virtualDisplayCount);
- sp<BufferStateLayer> createBufferStateLayer(LayerMetadata metadata);
+ sp<Layer> createBufferStateLayer(LayerMetadata metadata);
TestableSurfaceFlinger mFlinger;
Hwc2::mock::Composer* mComposer = nullptr;
@@ -95,11 +94,10 @@
mTunnelModeEnabledReporter->removeListener(mTunnelModeEnabledListener);
}
-sp<BufferStateLayer> TunnelModeEnabledReporterTest::createBufferStateLayer(
- LayerMetadata metadata = {}) {
+sp<Layer> TunnelModeEnabledReporterTest::createBufferStateLayer(LayerMetadata metadata = {}) {
sp<Client> client;
LayerCreationArgs args(mFlinger.flinger(), client, "buffer-state-layer", LAYER_FLAGS, metadata);
- return sp<BufferStateLayer>::make(args);
+ return sp<Layer>::make(args);
}
void TunnelModeEnabledReporterTest::setupScheduler() {
diff --git a/services/surfaceflinger/tests/unittests/mock/MockLayer.h b/services/surfaceflinger/tests/unittests/mock/MockLayer.h
index 48d05cb..0d94f4c 100644
--- a/services/surfaceflinger/tests/unittests/mock/MockLayer.h
+++ b/services/surfaceflinger/tests/unittests/mock/MockLayer.h
@@ -18,14 +18,12 @@
#include <gmock/gmock.h>
-#include "BufferStateLayer.h"
-
namespace android::mock {
-class MockLayer : public BufferStateLayer {
+class MockLayer : public Layer {
public:
MockLayer(SurfaceFlinger* flinger, std::string name)
- : BufferStateLayer(LayerCreationArgs(flinger, nullptr, std::move(name), 0, {})) {
+ : Layer(LayerCreationArgs(flinger, nullptr, std::move(name), 0, {})) {
EXPECT_CALL(*this, getDefaultFrameRateCompatibility())
.WillOnce(testing::Return(scheduler::LayerInfo::FrameRateCompatibility::Default));
}