Merge "DO NOT MERGE: InputDispatcher: Consider ownerPid in FLAG_OBSCURED calculations" into rvc-dev
diff --git a/cmds/atrace/atrace.cpp b/cmds/atrace/atrace.cpp
index 8637a31..28fdaa4 100644
--- a/cmds/atrace/atrace.cpp
+++ b/cmds/atrace/atrace.cpp
@@ -237,6 +237,7 @@
{ OPT, "events/kmem/rss_stat/enable" },
{ OPT, "events/kmem/ion_heap_grow/enable" },
{ OPT, "events/kmem/ion_heap_shrink/enable" },
+ { OPT, "events/ion/ion_stat/enable" },
} },
};
diff --git a/cmds/atrace/atrace.rc b/cmds/atrace/atrace.rc
index 040ddde..9b2f4a8 100644
--- a/cmds/atrace/atrace.rc
+++ b/cmds/atrace/atrace.rc
@@ -107,6 +107,8 @@
chmod 0666 /sys/kernel/tracing/events/kmem/ion_heap_grow/enable
chmod 0666 /sys/kernel/debug/tracing/events/kmem/ion_heap_shrink/enable
chmod 0666 /sys/kernel/tracing/events/kmem/ion_heap_shrink/enable
+ chmod 0666 /sys/kernel/debug/tracing/events/ion/ion_stat/enable
+ chmod 0666 /sys/kernel/tracing/events/ion/ion_stat/enable
chmod 0666 /sys/kernel/debug/tracing/events/mm_event/mm_event_record/enable
chmod 0666 /sys/kernel/tracing/events/mm_event/mm_event_record/enable
chmod 0666 /sys/kernel/debug/tracing/events/signal/signal_generate/enable
diff --git a/cmds/dumpstate/binder/android/os/IDumpstateListener.aidl b/cmds/dumpstate/binder/android/os/IDumpstateListener.aidl
index 8ff4ca6..a5e6c68 100644
--- a/cmds/dumpstate/binder/android/os/IDumpstateListener.aidl
+++ b/cmds/dumpstate/binder/android/os/IDumpstateListener.aidl
@@ -68,4 +68,9 @@
* Called when screenshot is taken.
*/
oneway void onScreenshotTaken(boolean success);
+
+ /**
+ * Called when ui intensive bugreport dumps are finished.
+ */
+ oneway void onUiIntensiveBugreportDumpsFinished(String callingPackage);
}
diff --git a/cmds/dumpstate/dumpstate.cpp b/cmds/dumpstate/dumpstate.cpp
index c85c7cf..9ba4819 100644
--- a/cmds/dumpstate/dumpstate.cpp
+++ b/cmds/dumpstate/dumpstate.cpp
@@ -169,6 +169,7 @@
#define OTA_METADATA_DIR "/metadata/ota"
#define SNAPSHOTCTL_LOG_DIR "/data/misc/snapshotctl_log"
#define LINKERCONFIG_DIR "/linkerconfig"
+#define PACKAGE_DEX_USE_LIST "/data/system/package-dex-usage.list"
// TODO(narayan): Since this information has to be kept in sync
// with tombstoned, we should just put it in a common header.
@@ -1612,6 +1613,7 @@
if (!PropertiesHelper::IsUserBuild()) {
ds.AddDir(PROFILE_DATA_DIR_CUR, true);
ds.AddDir(PROFILE_DATA_DIR_REF, true);
+ ds.AddZipEntry(ZIP_ROOT_DIR + PACKAGE_DEX_USE_LIST, PACKAGE_DEX_USE_LIST);
}
ds.AddDir(PREREBOOT_DATA_DIR, false);
add_mountinfo();
@@ -2630,11 +2632,13 @@
if (options_->telephony_only) {
MaybeTakeEarlyScreenshot();
+ onUiIntensiveBugreportDumpsFinished(calling_uid, calling_package);
MaybeCheckUserConsent(calling_uid, calling_package);
DumpstateTelephonyOnly(calling_package);
DumpstateBoard();
} else if (options_->wifi_only) {
MaybeTakeEarlyScreenshot();
+ onUiIntensiveBugreportDumpsFinished(calling_uid, calling_package);
MaybeCheckUserConsent(calling_uid, calling_package);
DumpstateWifiOnly();
} else {
@@ -2643,6 +2647,7 @@
// Take screenshot and get consent only after critical dumpsys has finished.
MaybeTakeEarlyScreenshot();
+ onUiIntensiveBugreportDumpsFinished(calling_uid, calling_package);
MaybeCheckUserConsent(calling_uid, calling_package);
// Dump state for the default case. This also drops root.
@@ -2732,6 +2737,19 @@
TakeScreenshot();
}
+void Dumpstate::onUiIntensiveBugreportDumpsFinished(int32_t calling_uid,
+ const std::string& calling_package) {
+ if (calling_uid == AID_SHELL || !CalledByApi()) {
+ return;
+ }
+ if (listener_ != nullptr) {
+ // Let listener know ui intensive bugreport dumps are finished, then it can do event
+ // handling if required.
+ android::String16 package(calling_package.c_str());
+ listener_->onUiIntensiveBugreportDumpsFinished(package);
+ }
+}
+
void Dumpstate::MaybeCheckUserConsent(int32_t calling_uid, const std::string& calling_package) {
if (calling_uid == AID_SHELL || !CalledByApi()) {
// No need to get consent for shell triggered dumpstates, or not through
diff --git a/cmds/dumpstate/dumpstate.h b/cmds/dumpstate/dumpstate.h
index 498f338..28d8936 100644
--- a/cmds/dumpstate/dumpstate.h
+++ b/cmds/dumpstate/dumpstate.h
@@ -509,6 +509,9 @@
void MaybeTakeEarlyScreenshot();
+ void onUiIntensiveBugreportDumpsFinished(int32_t calling_uid,
+ const std::string& calling_package);
+
void MaybeCheckUserConsent(int32_t calling_uid, const std::string& calling_package);
// Removes the in progress files output files (tmp file, zip/txt file, screenshot),
diff --git a/cmds/dumpstate/tests/dumpstate_smoke_test.cpp b/cmds/dumpstate/tests/dumpstate_smoke_test.cpp
index 047a1c3..6f2d754 100644
--- a/cmds/dumpstate/tests/dumpstate_smoke_test.cpp
+++ b/cmds/dumpstate/tests/dumpstate_smoke_test.cpp
@@ -173,6 +173,15 @@
return binder::Status::ok();
}
+ binder::Status onUiIntensiveBugreportDumpsFinished(const android::String16& callingpackage)
+ override {
+ std::lock_guard <std::mutex> lock(lock_);
+ std::string callingpackageUtf8 = std::string(String8(callingpackage).string());
+ dprintf(out_fd_, "\rCalling package of ui intensive bugreport dumps finished: %s",
+ callingpackageUtf8.c_str());
+ return binder::Status::ok();
+ }
+
bool getIsFinished() {
std::lock_guard<std::mutex> lock(lock_);
return is_finished_;
diff --git a/cmds/dumpstate/tests/dumpstate_test.cpp b/cmds/dumpstate/tests/dumpstate_test.cpp
index 2efb130..9871a3b 100644
--- a/cmds/dumpstate/tests/dumpstate_test.cpp
+++ b/cmds/dumpstate/tests/dumpstate_test.cpp
@@ -66,6 +66,8 @@
MOCK_METHOD1(onError, binder::Status(int32_t error_code));
MOCK_METHOD0(onFinished, binder::Status());
MOCK_METHOD1(onScreenshotTaken, binder::Status(bool success));
+ MOCK_METHOD1(onUiIntensiveBugreportDumpsFinished,
+ binder::Status(const android::String16& callingpackage));
protected:
MOCK_METHOD0(onAsBinder, IBinder*());
diff --git a/cmds/installd/InstalldNativeService.cpp b/cmds/installd/InstalldNativeService.cpp
index ae44d38..7d1c1ad 100644
--- a/cmds/installd/InstalldNativeService.cpp
+++ b/cmds/installd/InstalldNativeService.cpp
@@ -420,6 +420,32 @@
return true;
}
+binder::Status InstalldNativeService::createAppDataBatched(
+ const std::unique_ptr<std::vector<std::unique_ptr<std::string>>>& uuids,
+ const std::unique_ptr<std::vector<std::unique_ptr<std::string>>>& packageNames,
+ int32_t userId, int32_t flags, const std::vector<int32_t>& appIds,
+ const std::vector<std::string>& seInfos, const std::vector<int32_t>& targetSdkVersions,
+ int64_t* _aidl_return) {
+ ENFORCE_UID(AID_SYSTEM);
+ std::lock_guard<std::recursive_mutex> lock(mLock);
+
+ ATRACE_BEGIN("createAppDataBatched");
+ binder::Status ret;
+ for (size_t i = 0; i < uuids->size(); i++) {
+ if (!packageNames->at(i)) {
+ continue;
+ }
+ ret = createAppData(uuids->at(i), *packageNames->at(i), userId, flags, appIds[i],
+ seInfos[i], targetSdkVersions[i], _aidl_return);
+ if (!ret.isOk()) {
+ ATRACE_END();
+ return ret;
+ }
+ }
+ ATRACE_END();
+ return ok();
+}
+
binder::Status InstalldNativeService::createAppData(const std::unique_ptr<std::string>& uuid,
const std::string& packageName, int32_t userId, int32_t flags, int32_t appId,
const std::string& seInfo, int32_t targetSdkVersion, int64_t* _aidl_return) {
diff --git a/cmds/installd/InstalldNativeService.h b/cmds/installd/InstalldNativeService.h
index eb151ca..8e7d98b 100644
--- a/cmds/installd/InstalldNativeService.h
+++ b/cmds/installd/InstalldNativeService.h
@@ -44,7 +44,12 @@
int32_t userSerial, int32_t flags);
binder::Status destroyUserData(const std::unique_ptr<std::string>& uuid, int32_t userId,
int32_t flags);
-
+ binder::Status createAppDataBatched(
+ const std::unique_ptr<std::vector<std::unique_ptr<std::string>>>& uuids,
+ const std::unique_ptr<std::vector<std::unique_ptr<std::string>>>& packageNames,
+ int32_t userId, int32_t flags, const std::vector<int32_t>& appIds,
+ const std::vector<std::string>& seInfos, const std::vector<int32_t>& targetSdkVersions,
+ int64_t* _aidl_return);
binder::Status createAppData(const std::unique_ptr<std::string>& uuid,
const std::string& packageName, int32_t userId, int32_t flags, int32_t appId,
const std::string& seInfo, int32_t targetSdkVersion, int64_t* _aidl_return);
diff --git a/cmds/installd/binder/android/os/IInstalld.aidl b/cmds/installd/binder/android/os/IInstalld.aidl
index 5e5af73..eeda6c5 100644
--- a/cmds/installd/binder/android/os/IInstalld.aidl
+++ b/cmds/installd/binder/android/os/IInstalld.aidl
@@ -23,6 +23,9 @@
long createAppData(@nullable @utf8InCpp String uuid, in @utf8InCpp String packageName,
int userId, int flags, int appId, in @utf8InCpp String seInfo, int targetSdkVersion);
+ long createAppDataBatched(in @nullable @utf8InCpp String[] uuids,
+ in @nullable @utf8InCpp String[] packageNames, in int userId, int flags, in int[] appIds,
+ in @utf8InCpp String[] seInfos, in int[] targetSdkVersions);
void restoreconAppData(@nullable @utf8InCpp String uuid, @utf8InCpp String packageName,
int userId, int flags, int appId, @utf8InCpp String seInfo);
void migrateAppData(@nullable @utf8InCpp String uuid, @utf8InCpp String packageName,
diff --git a/cmds/installd/dexopt.cpp b/cmds/installd/dexopt.cpp
index 5ee6a9f..ebca892 100644
--- a/cmds/installd/dexopt.cpp
+++ b/cmds/installd/dexopt.cpp
@@ -262,6 +262,17 @@
return "";
}
+static std::string MapPropertyToArgWithBackup(const std::string& property,
+ const std::string& backupProperty,
+ const std::string& format,
+ const std::string& default_value = "") {
+ std::string value = GetProperty(property, default_value);
+ if (!value.empty()) {
+ return StringPrintf(format.c_str(), value.c_str());
+ }
+ return MapPropertyToArg(backupProperty, format, default_value);
+}
+
// Determines which binary we should use for execution (the debug or non-debug version).
// e.g. dex2oatd vs dex2oat
static const char* select_execution_binary(const char* binary, const char* debug_binary,
@@ -321,6 +332,7 @@
const char* compiler_filter,
bool debuggable,
bool post_bootcomplete,
+ bool for_restore,
bool background_job_compile,
int profile_fd,
const char* class_loader_context,
@@ -336,14 +348,24 @@
std::string dex2oat_Xms_arg = MapPropertyToArg("dalvik.vm.dex2oat-Xms", "-Xms%s");
std::string dex2oat_Xmx_arg = MapPropertyToArg("dalvik.vm.dex2oat-Xmx", "-Xmx%s");
- const char* threads_property = post_bootcomplete
- ? "dalvik.vm.dex2oat-threads"
- : "dalvik.vm.boot-dex2oat-threads";
- std::string dex2oat_threads_arg = MapPropertyToArg(threads_property, "-j%s");
- const char* cpu_set_property = post_bootcomplete
- ? "dalvik.vm.dex2oat-cpu-set"
- : "dalvik.vm.boot-dex2oat-cpu-set";
- std::string dex2oat_cpu_set_arg = MapPropertyToArg(cpu_set_property, "--cpu-set=%s");
+ std::string threads_format = "-j%s";
+ std::string dex2oat_threads_arg = post_bootcomplete
+ ? (for_restore
+ ? MapPropertyToArgWithBackup(
+ "dalvik.vm.restore-dex2oat-threads",
+ "dalvik.vm.dex2oat-threads",
+ threads_format)
+ : MapPropertyToArg("dalvik.vm.dex2oat-threads", threads_format))
+ : MapPropertyToArg("dalvik.vm.boot-dex2oat-threads", threads_format);
+ std::string cpu_set_format = "--cpu-set=%s";
+ std::string dex2oat_cpu_set_arg = post_bootcomplete
+ ? (for_restore
+ ? MapPropertyToArgWithBackup(
+ "dalvik.vm.restore-dex2oat-cpu-set",
+ "dalvik.vm.dex2oat-cpu-set",
+ cpu_set_format)
+ : MapPropertyToArg("dalvik.vm.dex2oat-cpu-set", cpu_set_format))
+ : MapPropertyToArg("dalvik.vm.boot-dex2oat-cpu-set", cpu_set_format);
std::string bootclasspath;
char* dex2oat_bootclasspath = getenv("DEX2OATBOOTCLASSPATH");
@@ -407,8 +429,17 @@
MapPropertyToArg("dalvik.vm.dex2oat-very-large", "--very-large-app-threshold=%s");
+
+ // Decide whether to use dex2oat64.
+ bool use_dex2oat64 = false;
+ // Check whether the device even supports 64-bit ABIs.
+ if (!GetProperty("ro.product.cpu.abilist64", "").empty()) {
+ use_dex2oat64 = GetBoolProperty("dalvik.vm.dex2oat64.enabled", false);
+ }
const char* dex2oat_bin = select_execution_binary(
- kDex2oatPath, kDex2oatDebugPath, background_job_compile);
+ (use_dex2oat64 ? kDex2oat64Path : kDex2oat32Path),
+ (use_dex2oat64 ? kDex2oatDebug64Path : kDex2oatDebug32Path),
+ background_job_compile);
bool generate_minidebug_info = kEnableMinidebugInfo &&
GetBoolProperty(kMinidebugInfoSystemProperty, kMinidebugInfoSystemPropertyDefault);
@@ -2075,6 +2106,7 @@
bool enable_hidden_api_checks = (dexopt_flags & DEXOPT_ENABLE_HIDDEN_API_CHECKS) != 0;
bool generate_compact_dex = (dexopt_flags & DEXOPT_GENERATE_COMPACT_DEX) != 0;
bool generate_app_image = (dexopt_flags & DEXOPT_GENERATE_APP_IMAGE) != 0;
+ bool for_restore = (dexopt_flags & DEXOPT_FOR_RESTORE) != 0;
// Check if we're dealing with a secondary dex file and if we need to compile it.
std::string oat_dir_str;
@@ -2191,6 +2223,7 @@
compiler_filter,
debuggable,
boot_complete,
+ for_restore,
background_job_compile,
reference_profile_fd.get(),
class_loader_context,
diff --git a/cmds/installd/dexopt.h b/cmds/installd/dexopt.h
index ef739ba..cc44873 100644
--- a/cmds/installd/dexopt.h
+++ b/cmds/installd/dexopt.h
@@ -34,8 +34,10 @@
#define ANDROID_ART_APEX_BIN "/apex/com.android.art/bin"
// Location of binaries in the Android Runtime APEX.
-static constexpr const char* kDex2oatPath = ANDROID_ART_APEX_BIN "/dex2oat";
-static constexpr const char* kDex2oatDebugPath = ANDROID_ART_APEX_BIN "/dex2oatd";
+static constexpr const char* kDex2oat32Path = ANDROID_ART_APEX_BIN "/dex2oat32";
+static constexpr const char* kDex2oat64Path = ANDROID_ART_APEX_BIN "/dex2oat64";
+static constexpr const char* kDex2oatDebug32Path = ANDROID_ART_APEX_BIN "/dex2oatd32";
+static constexpr const char* kDex2oatDebug64Path = ANDROID_ART_APEX_BIN "/dex2oatd64";
static constexpr const char* kProfmanPath = ANDROID_ART_APEX_BIN "/profman";
static constexpr const char* kProfmanDebugPath = ANDROID_ART_APEX_BIN "/profmand";
static constexpr const char* kDexoptanalyzerPath = ANDROID_ART_APEX_BIN "/dexoptanalyzer";
diff --git a/cmds/installd/installd_constants.h b/cmds/installd/installd_constants.h
index c928631..b5ee481 100644
--- a/cmds/installd/installd_constants.h
+++ b/cmds/installd/installd_constants.h
@@ -55,6 +55,7 @@
constexpr int DEXOPT_ENABLE_HIDDEN_API_CHECKS = 1 << 10;
constexpr int DEXOPT_GENERATE_COMPACT_DEX = 1 << 11;
constexpr int DEXOPT_GENERATE_APP_IMAGE = 1 << 12;
+constexpr int DEXOPT_FOR_RESTORE = 1 << 13; // TODO(b/135202722): remove
/* all known values for dexopt flags */
constexpr int DEXOPT_MASK =
@@ -69,7 +70,8 @@
| DEXOPT_IDLE_BACKGROUND_JOB
| DEXOPT_ENABLE_HIDDEN_API_CHECKS
| DEXOPT_GENERATE_COMPACT_DEX
- | DEXOPT_GENERATE_APP_IMAGE;
+ | DEXOPT_GENERATE_APP_IMAGE
+ | DEXOPT_FOR_RESTORE;
// NOTE: keep in sync with StorageManager
constexpr int FLAG_STORAGE_DE = 1 << 0;
diff --git a/cmds/installd/otapreopt.cpp b/cmds/installd/otapreopt.cpp
index d773790..18f8268 100644
--- a/cmds/installd/otapreopt.cpp
+++ b/cmds/installd/otapreopt.cpp
@@ -83,7 +83,7 @@
static_assert(DEXOPT_GENERATE_COMPACT_DEX == 1 << 11, "DEXOPT_GENERATE_COMPACT_DEX unexpected");
static_assert(DEXOPT_GENERATE_APP_IMAGE == 1 << 12, "DEXOPT_GENERATE_APP_IMAGE unexpected");
-static_assert(DEXOPT_MASK == (0x1dfe | DEXOPT_IDLE_BACKGROUND_JOB),
+static_assert(DEXOPT_MASK == (0x3dfe | DEXOPT_IDLE_BACKGROUND_JOB),
"DEXOPT_MASK unexpected.");
diff --git a/cmds/installd/tests/installd_dexopt_test.cpp b/cmds/installd/tests/installd_dexopt_test.cpp
index 69fefa1..16e4055 100644
--- a/cmds/installd/tests/installd_dexopt_test.cpp
+++ b/cmds/installd/tests/installd_dexopt_test.cpp
@@ -653,6 +653,15 @@
DEX2OAT_FROM_SCRATCH);
}
+TEST_F(DexoptTest, DexoptPrimaryPublicRestore) {
+ LOG(INFO) << "DexoptPrimaryPublicRestore";
+ CompilePrimaryDexOk("verify",
+ DEXOPT_FOR_RESTORE | DEXOPT_BOOTCOMPLETE | DEXOPT_PUBLIC,
+ app_oat_dir_.c_str(),
+ kTestAppGid,
+ DEX2OAT_FROM_SCRATCH);
+}
+
TEST_F(DexoptTest, DexoptPrimaryFailedInvalidFilter) {
LOG(INFO) << "DexoptPrimaryFailedInvalidFilter";
binder::Status status;
@@ -750,6 +759,36 @@
EXPECT_TRUE(found_enable);
}
+TEST_F(DexoptTest, DexoptDex2oat64Enabled) {
+ LOG(INFO) << "DexoptDex2oat64Enabled";
+ const std::string property = "dalvik.vm.dex2oat64.enabled";
+ const std::string previous_value = android::base::GetProperty(property, "");
+ auto restore_property = android::base::make_scope_guard([=]() {
+ android::base::SetProperty(property, previous_value);
+ });
+ std::string odex = GetPrimaryDexArtifact(app_oat_dir_.c_str(), apk_path_, "odex");
+ // Disable the property and use dex2oat32.
+ ASSERT_TRUE(android::base::SetProperty(property, "false")) << property;
+ CompilePrimaryDexOk("speed-profile",
+ DEXOPT_IDLE_BACKGROUND_JOB | DEXOPT_PROFILE_GUIDED |
+ DEXOPT_GENERATE_APP_IMAGE,
+ app_oat_dir_.c_str(),
+ kTestAppGid,
+ DEX2OAT_FROM_SCRATCH,
+ /*binder_result=*/nullptr,
+ empty_dm_file_.c_str());
+ // Enable the property and use dex2oat64.
+ ASSERT_TRUE(android::base::SetProperty(property, "true")) << property;
+ CompilePrimaryDexOk("speed-profile",
+ DEXOPT_IDLE_BACKGROUND_JOB | DEXOPT_PROFILE_GUIDED |
+ DEXOPT_GENERATE_APP_IMAGE,
+ app_oat_dir_.c_str(),
+ kTestAppGid,
+ DEX2OAT_FROM_SCRATCH,
+ /*binder_result=*/nullptr,
+ empty_dm_file_.c_str());
+}
+
class PrimaryDexReCompilationTest : public DexoptTest {
public:
virtual void SetUp() {
diff --git a/headers/media_plugin/media/openmax/OMX_IndexExt.h b/headers/media_plugin/media/openmax/OMX_IndexExt.h
index bbb3193..a427db7 100644
--- a/headers/media_plugin/media/openmax/OMX_IndexExt.h
+++ b/headers/media_plugin/media/openmax/OMX_IndexExt.h
@@ -89,6 +89,7 @@
OMX_IndexParamVideoVp9, /**< reference: OMX_VIDEO_PARAM_VP9TYPE */
OMX_IndexParamVideoAndroidVp9Encoder, /**< reference: OMX_VIDEO_PARAM_ANDROID_VP9ENCODERTYPE */
OMX_IndexParamVideoAndroidImageGrid, /**< reference: OMX_VIDEO_PARAM_ANDROID_IMAGEGRIDTYPE */
+ OMX_IndexParamVideoAndroidRequiresSwRenderer, /**< reference: OMX_PARAM_U32TYPE */
OMX_IndexExtVideoEndUnused,
/* Image & Video common configurations */
diff --git a/include/input/InputWindow.h b/include/input/InputWindow.h
index c44db51..a695a8f 100644
--- a/include/input/InputWindow.h
+++ b/include/input/InputWindow.h
@@ -123,17 +123,17 @@
// input windows that have the same token.
sp<IBinder> token;
// This uniquely identifies the input window.
- int32_t id = 0;
+ int32_t id = -1;
std::string name;
- int32_t layoutParamsFlags;
- int32_t layoutParamsType;
- nsecs_t dispatchingTimeout;
+ int32_t layoutParamsFlags = 0;
+ int32_t layoutParamsType = 0;
+ nsecs_t dispatchingTimeout = -1;
/* These values are filled in by SurfaceFlinger. */
- int32_t frameLeft;
- int32_t frameTop;
- int32_t frameRight;
- int32_t frameBottom;
+ int32_t frameLeft = -1;
+ int32_t frameTop = -1;
+ int32_t frameRight = -1;
+ int32_t frameBottom = -1;
/*
* SurfaceFlinger consumes this value to shrink the computed frame. This is
@@ -145,7 +145,7 @@
// A global scaling factor for all windows. Unlike windowScaleX/Y this results
// in scaling of the TOUCH_MAJOR/TOUCH_MINOR axis.
- float globalScaleFactor;
+ float globalScaleFactor = 1.0f;
// Scaling factors applied to individual windows.
float windowXScale = 1.0f;
@@ -156,18 +156,18 @@
* to absolute coordinates by SurfaceFlinger once the frame is computed.
*/
Region touchableRegion;
- bool visible;
- bool canReceiveKeys;
- bool hasFocus;
- bool hasWallpaper;
- bool paused;
- int32_t ownerPid;
- int32_t ownerUid;
- int32_t inputFeatures;
- int32_t displayId;
+ bool visible = false;
+ bool canReceiveKeys = false;
+ bool hasFocus = false;
+ bool hasWallpaper = false;
+ bool paused = false;
+ int32_t ownerPid = -1;
+ int32_t ownerUid = -1;
+ int32_t inputFeatures = 0;
+ int32_t displayId = ADISPLAY_ID_NONE;
int32_t portalToDisplayId = ADISPLAY_ID_NONE;
InputApplicationInfo applicationInfo;
- bool replaceTouchableRegionWithCrop;
+ bool replaceTouchableRegionWithCrop = false;
wp<IBinder> touchableRegionCropHandle;
void addTouchableRegion(const Rect& region);
@@ -213,7 +213,7 @@
}
inline std::string getName() const {
- return mInfo.token ? mInfo.name : "<invalid>";
+ return !mInfo.name.empty() ? mInfo.name : "<invalid>";
}
inline nsecs_t getDispatchingTimeout(nsecs_t defaultValue) const {
diff --git a/libs/binder/Android.bp b/libs/binder/Android.bp
index e6cfeb4..7298282 100644
--- a/libs/binder/Android.bp
+++ b/libs/binder/Android.bp
@@ -170,6 +170,7 @@
aidl_interface {
name: "libbinder_aidl_test_stub",
+ unstable: true,
local_include_dir: "aidl",
srcs: [":libbinder_aidl"],
vendor_available: true,
diff --git a/libs/binder/IPCThreadState.cpp b/libs/binder/IPCThreadState.cpp
index 9e89c57..d67ce15 100644
--- a/libs/binder/IPCThreadState.cpp
+++ b/libs/binder/IPCThreadState.cpp
@@ -997,7 +997,11 @@
if (err >= NO_ERROR) {
if (bwr.write_consumed > 0) {
if (bwr.write_consumed < mOut.dataSize())
- LOG_ALWAYS_FATAL("Driver did not consume write buffer");
+ LOG_ALWAYS_FATAL("Driver did not consume write buffer. "
+ "err: %s consumed: %zu of %zu",
+ statusToString(err).c_str(),
+ (size_t)bwr.write_consumed,
+ mOut.dataSize());
else {
mOut.setDataSize(0);
processPostWriteDerefs();
diff --git a/libs/binder/Parcel.cpp b/libs/binder/Parcel.cpp
index beab270..9642a87 100644
--- a/libs/binder/Parcel.cpp
+++ b/libs/binder/Parcel.cpp
@@ -987,12 +987,22 @@
status_t Parcel::writeString8(const String8& str)
{
- status_t err = writeInt32(str.bytes());
- // only write string if its length is more than zero characters,
- // as readString8 will only read if the length field is non-zero.
- // this is slightly different from how writeString16 works.
- if (str.bytes() > 0 && err == NO_ERROR) {
- err = write(str.string(), str.bytes()+1);
+ return writeString8(str.string(), str.size());
+}
+
+status_t Parcel::writeString8(const char* str, size_t len)
+{
+ if (str == nullptr) return writeInt32(-1);
+
+ status_t err = writeInt32(len);
+ if (err == NO_ERROR) {
+ uint8_t* data = (uint8_t*)writeInplace(len+sizeof(char));
+ if (data) {
+ memcpy(data, str, len);
+ *reinterpret_cast<char*>(data+len) = 0;
+ return NO_ERROR;
+ }
+ err = mError;
}
return err;
}
@@ -1832,37 +1842,39 @@
String8 Parcel::readString8() const
{
- String8 retString;
- status_t status = readString8(&retString);
- if (status != OK) {
- // We don't care about errors here, so just return an empty string.
- return String8();
- }
- return retString;
+ size_t len;
+ const char* str = readString8Inplace(&len);
+ if (str) return String8(str, len);
+ ALOGE("Reading a NULL string not supported here.");
+ return String8();
}
status_t Parcel::readString8(String8* pArg) const
{
- int32_t size;
- status_t status = readInt32(&size);
- if (status != OK) {
- return status;
- }
- // watch for potential int overflow from size+1
- if (size < 0 || size >= INT32_MAX) {
- return BAD_VALUE;
- }
- // |writeString8| writes nothing for empty string.
- if (size == 0) {
+ size_t len;
+ const char* str = readString8Inplace(&len);
+ if (str) {
+ pArg->setTo(str, len);
+ return 0;
+ } else {
*pArg = String8();
- return OK;
+ return UNEXPECTED_NULL;
}
- const char* str = (const char*)readInplace(size + 1);
- if (str == nullptr) {
- return BAD_VALUE;
+}
+
+const char* Parcel::readString8Inplace(size_t* outLen) const
+{
+ int32_t size = readInt32();
+ // watch for potential int overflow from size+1
+ if (size >= 0 && size < INT32_MAX) {
+ *outLen = size;
+ const char* str = (const char*)readInplace(size+1);
+ if (str != nullptr) {
+ return str;
+ }
}
- pArg->setTo(str, size);
- return OK;
+ *outLen = 0;
+ return nullptr;
}
String16 Parcel::readString16() const
diff --git a/libs/binder/include/binder/Parcel.h b/libs/binder/include/binder/Parcel.h
index 4b1a758..c1f64fb 100644
--- a/libs/binder/include/binder/Parcel.h
+++ b/libs/binder/include/binder/Parcel.h
@@ -119,6 +119,7 @@
status_t writeDouble(double val);
status_t writeCString(const char* str);
status_t writeString8(const String8& str);
+ status_t writeString8(const char* str, size_t len);
status_t writeString16(const String16& str);
status_t writeString16(const std::unique_ptr<String16>& str);
status_t writeString16(const char16_t* str, size_t len);
@@ -283,6 +284,7 @@
const char* readCString() const;
String8 readString8() const;
status_t readString8(String8* pArg) const;
+ const char* readString8Inplace(size_t* outLen) const;
String16 readString16() const;
status_t readString16(String16* pArg) const;
status_t readString16(std::unique_ptr<String16>* pArg) const;
diff --git a/libs/binder/ndk/test/Android.bp b/libs/binder/ndk/test/Android.bp
index cb4b20f..5f5265c 100644
--- a/libs/binder/ndk/test/Android.bp
+++ b/libs/binder/ndk/test/Android.bp
@@ -92,6 +92,7 @@
aidl_interface {
name: "IBinderVendorDoubleLoadTest",
+ unstable: true,
vendor: true,
srcs: [
"IBinderVendorDoubleLoadTest.aidl",
@@ -100,6 +101,7 @@
aidl_interface {
name: "IBinderNdkUnitTest",
+ unstable: true,
srcs: [
"IBinderNdkUnitTest.aidl",
"IEmpty.aidl",
diff --git a/libs/binder/tests/Android.bp b/libs/binder/tests/Android.bp
index c7b7551..69fdd7c 100644
--- a/libs/binder/tests/Android.bp
+++ b/libs/binder/tests/Android.bp
@@ -137,6 +137,7 @@
aidl_interface {
name: "binderStabilityTestIface",
+ unstable: true,
srcs: [
"IBinderStabilityTest.aidl",
],
diff --git a/libs/binderthreadstate/Android.bp b/libs/binderthreadstate/Android.bp
index c186110..5eb509c 100644
--- a/libs/binderthreadstate/Android.bp
+++ b/libs/binderthreadstate/Android.bp
@@ -39,6 +39,7 @@
aidl_interface {
name: "binderthreadstateutilstest.aidl",
+ unstable: true,
srcs: ["IAidlStuff.aidl"],
}
diff --git a/libs/gui/BLASTBufferQueue.cpp b/libs/gui/BLASTBufferQueue.cpp
index a8384ac..5965201 100644
--- a/libs/gui/BLASTBufferQueue.cpp
+++ b/libs/gui/BLASTBufferQueue.cpp
@@ -95,7 +95,8 @@
if (needsDisconnect != nullptr) *needsDisconnect = disconnect;
}
-BLASTBufferQueue::BLASTBufferQueue(const sp<SurfaceControl>& surface, int width, int height)
+BLASTBufferQueue::BLASTBufferQueue(const sp<SurfaceControl>& surface, int width, int height,
+ bool enableTripleBuffering)
: mSurfaceControl(surface),
mWidth(width),
mHeight(height),
@@ -105,8 +106,7 @@
// explicitly so that dequeueBuffer will block
mProducer->setDequeueTimeout(std::numeric_limits<int64_t>::max());
- int8_t disableTripleBuffer = property_get_bool("ro.sf.disable_triple_buffer", 0);
- if (!disableTripleBuffer) {
+ if (enableTripleBuffering) {
mProducer->setMaxDequeuedBufferCount(2);
}
mBufferItemConsumer =
@@ -189,13 +189,13 @@
mPendingReleaseItem.item = std::move(mSubmitted.front());
mSubmitted.pop();
- processNextBufferLocked();
+ processNextBufferLocked(false);
mCallbackCV.notify_all();
decStrong((void*)transactionCallbackThunk);
}
-void BLASTBufferQueue::processNextBufferLocked() {
+void BLASTBufferQueue::processNextBufferLocked(bool useNextTransaction) {
ATRACE_CALL();
if (mNumFrameAvailable == 0 || mNumAcquired == MAX_ACQUIRED_BUFFERS + 1) {
return;
@@ -209,7 +209,7 @@
SurfaceComposerClient::Transaction localTransaction;
bool applyTransaction = true;
SurfaceComposerClient::Transaction* t = &localTransaction;
- if (mNextTransaction != nullptr && mUseNextTransaction) {
+ if (mNextTransaction != nullptr && useNextTransaction) {
t = mNextTransaction;
mNextTransaction = nullptr;
applyTransaction = false;
@@ -274,16 +274,14 @@
while (mNumFrameAvailable > 0 || mNumAcquired == MAX_ACQUIRED_BUFFERS + 1) {
mCallbackCV.wait(_lock);
}
- mUseNextTransaction = true;
}
// add to shadow queue
mNumFrameAvailable++;
- processNextBufferLocked();
+ processNextBufferLocked(true);
}
void BLASTBufferQueue::setNextTransaction(SurfaceComposerClient::Transaction* t) {
std::lock_guard _lock{mMutex};
- mUseNextTransaction = false;
mNextTransaction = t;
}
diff --git a/libs/gui/BufferQueueProducer.cpp b/libs/gui/BufferQueueProducer.cpp
index 3f4c5da..a7cf39a 100644
--- a/libs/gui/BufferQueueProducer.cpp
+++ b/libs/gui/BufferQueueProducer.cpp
@@ -655,8 +655,9 @@
}
listener = mCore->mConsumerListener;
- if (listener != nullptr) {
- listener->onFrameDetached(mSlots[slot].mGraphicBuffer->getId());
+ auto gb = mSlots[slot].mGraphicBuffer;
+ if (listener != nullptr && gb != nullptr) {
+ listener->onFrameDetached(gb->getId());
}
mSlots[slot].mBufferState.detachProducer();
mCore->mActiveBuffers.erase(slot);
@@ -1120,8 +1121,9 @@
mCore->mFreeBuffers.push_back(slot);
}
- if (mCore->mConsumerListener != nullptr) {
- mCore->mConsumerListener->onFrameCancelled(mSlots[slot].mGraphicBuffer->getId());
+ auto gb = mSlots[slot].mGraphicBuffer;
+ if (mCore->mConsumerListener != nullptr && gb != nullptr) {
+ mCore->mConsumerListener->onFrameCancelled(gb->getId());
}
mSlots[slot].mFence = fence;
mCore->mDequeueCondition.notify_all();
diff --git a/libs/gui/include/gui/BLASTBufferQueue.h b/libs/gui/include/gui/BLASTBufferQueue.h
index 64c21e0..2320771 100644
--- a/libs/gui/include/gui/BLASTBufferQueue.h
+++ b/libs/gui/include/gui/BLASTBufferQueue.h
@@ -66,7 +66,9 @@
: public ConsumerBase::FrameAvailableListener, public BufferItemConsumer::BufferFreedListener
{
public:
- BLASTBufferQueue(const sp<SurfaceControl>& surface, int width, int height);
+ BLASTBufferQueue(const sp<SurfaceControl>& surface, int width, int height,
+ bool enableTripleBuffering = true);
+
sp<IGraphicBufferProducer> getIGraphicBufferProducer() const {
return mProducer;
}
@@ -90,7 +92,7 @@
BLASTBufferQueue& operator = (const BLASTBufferQueue& rhs);
BLASTBufferQueue(const BLASTBufferQueue& rhs);
- void processNextBufferLocked() REQUIRES(mMutex);
+ void processNextBufferLocked(bool useNextTransaction) REQUIRES(mMutex);
Rect computeCrop(const BufferItem& item);
sp<SurfaceControl> mSurfaceControl;
@@ -123,8 +125,6 @@
sp<BLASTBufferItemConsumer> mBufferItemConsumer;
SurfaceComposerClient::Transaction* mNextTransaction GUARDED_BY(mMutex);
-
- bool mUseNextTransaction = false;
};
} // namespace android
diff --git a/libs/gui/include/gui/DisplayEventReceiver.h b/libs/gui/include/gui/DisplayEventReceiver.h
index 109e28b..d9a0253 100644
--- a/libs/gui/include/gui/DisplayEventReceiver.h
+++ b/libs/gui/include/gui/DisplayEventReceiver.h
@@ -65,6 +65,7 @@
struct VSync {
uint32_t count;
+ nsecs_t expectedVSyncTimestamp;
};
struct Hotplug {
diff --git a/libs/gui/tests/Android.bp b/libs/gui/tests/Android.bp
index 7f960ab..a6bcd10 100644
--- a/libs/gui/tests/Android.bp
+++ b/libs/gui/tests/Android.bp
@@ -39,6 +39,7 @@
shared_libs: [
"android.hardware.configstore@1.0",
"android.hardware.configstore-utils",
+ "libSurfaceFlingerProp",
"libbase",
"liblog",
"libEGL",
@@ -53,6 +54,8 @@
"libutils",
"libnativewindow"
],
+
+ header_libs: ["libsurfaceflinger_headers"],
}
// Build a separate binary to $(TARGET_OUT_DATA_NATIVE_TESTS)/$(LOCAL_MODULE)
diff --git a/libs/gui/tests/BLASTBufferQueue_test.cpp b/libs/gui/tests/BLASTBufferQueue_test.cpp
index a87ccd6..d929a59 100644
--- a/libs/gui/tests/BLASTBufferQueue_test.cpp
+++ b/libs/gui/tests/BLASTBufferQueue_test.cpp
@@ -722,5 +722,8 @@
ASSERT_EQ(2, events->frameNumber);
ASSERT_EQ(requestedPresentTimeB, events->requestedPresentTime);
ASSERT_GE(events->postedTime, postedTimeB);
+
+ // wait for any callbacks that have not been received
+ adapter.waitForCallbacks();
}
} // namespace android
diff --git a/libs/gui/tests/RegionSampling_test.cpp b/libs/gui/tests/RegionSampling_test.cpp
index dbd4ef9..6746b0a 100644
--- a/libs/gui/tests/RegionSampling_test.cpp
+++ b/libs/gui/tests/RegionSampling_test.cpp
@@ -240,6 +240,19 @@
float const luma_gray = 0.50;
};
+TEST_F(RegionSamplingTest, invalidLayerHandle_doesNotCrash) {
+ sp<ISurfaceComposer> composer = ComposerService::getComposerService();
+ sp<Listener> listener = new Listener();
+ const Rect sampleArea{100, 100, 200, 200};
+ // Passing in composer service as the layer handle should not crash, we'll
+ // treat it as a layer that no longer exists and silently allow sampling to
+ // occur.
+ status_t status = composer->addRegionSamplingListener(sampleArea,
+ IInterface::asBinder(composer), listener);
+ ASSERT_EQ(NO_ERROR, status);
+ composer->removeRegionSamplingListener(listener);
+}
+
TEST_F(RegionSamplingTest, DISABLED_CollectsLuma) {
fill_render(rgba_green);
diff --git a/libs/gui/tests/Surface_test.cpp b/libs/gui/tests/Surface_test.cpp
index 2de6b69..d1d770e 100644
--- a/libs/gui/tests/Surface_test.cpp
+++ b/libs/gui/tests/Surface_test.cpp
@@ -18,17 +18,18 @@
#include <gtest/gtest.h>
+#include <SurfaceFlingerProperties.h>
#include <android/hardware/configstore/1.0/ISurfaceFlingerConfigs.h>
#include <binder/ProcessState.h>
#include <configstore/Utils.h>
#include <cutils/properties.h>
-#include <inttypes.h>
#include <gui/BufferItemConsumer.h>
#include <gui/IDisplayEventConnection.h>
#include <gui/IProducerListener.h>
#include <gui/ISurfaceComposer.h>
#include <gui/Surface.h>
#include <gui/SurfaceComposerClient.h>
+#include <inttypes.h>
#include <private/gui/ComposerService.h>
#include <ui/Rect.h>
#include <utils/String8.h>
@@ -46,11 +47,9 @@
using Transaction = SurfaceComposerClient::Transaction;
-static bool hasWideColorDisplay =
- getBool<ISurfaceFlingerConfigs, &ISurfaceFlingerConfigs::hasWideColorDisplay>(false);
+static bool hasWideColorDisplay = android::sysprop::has_wide_color_display(false);
-static bool hasHdrDisplay =
- getBool<ISurfaceFlingerConfigs, &ISurfaceFlingerConfigs::hasHDRDisplay>(false);
+static bool hasHdrDisplay = android::sysprop::has_HDR_display(false);
class FakeSurfaceComposer;
class FakeProducerFrameEventHistory;
diff --git a/libs/input/InputTransport.cpp b/libs/input/InputTransport.cpp
index ef7cc7d..11af23e 100644
--- a/libs/input/InputTransport.cpp
+++ b/libs/input/InputTransport.cpp
@@ -468,7 +468,7 @@
msg.body.key.deviceId = deviceId;
msg.body.key.source = source;
msg.body.key.displayId = displayId;
- msg.body.key.hmac = hmac;
+ msg.body.key.hmac = std::move(hmac);
msg.body.key.action = action;
msg.body.key.flags = flags;
msg.body.key.keyCode = keyCode;
@@ -526,7 +526,7 @@
msg.body.motion.deviceId = deviceId;
msg.body.motion.source = source;
msg.body.motion.displayId = displayId;
- msg.body.motion.hmac = hmac;
+ msg.body.motion.hmac = std::move(hmac);
msg.body.motion.action = action;
msg.body.motion.actionButton = actionButton;
msg.body.motion.flags = flags;
diff --git a/libs/input/InputWindow.cpp b/libs/input/InputWindow.cpp
index 03ca459..6e4c97d 100644
--- a/libs/input/InputWindow.cpp
+++ b/libs/input/InputWindow.cpp
@@ -65,7 +65,7 @@
}
status_t InputWindowInfo::write(Parcel& output) const {
- if (token == nullptr) {
+ if (name.empty()) {
output.writeInt32(0);
return OK;
}
@@ -110,12 +110,7 @@
return ret;
}
- sp<IBinder> token = from.readStrongBinder();
- if (token == nullptr) {
- return ret;
- }
-
- ret.token = token;
+ ret.token = from.readStrongBinder();
ret.id = from.readInt32();
ret.name = from.readString8().c_str();
ret.layoutParamsFlags = from.readInt32();
diff --git a/libs/nativewindow/Android.bp b/libs/nativewindow/Android.bp
index 55400c7..5baec2f 100644
--- a/libs/nativewindow/Android.bp
+++ b/libs/nativewindow/Android.bp
@@ -59,7 +59,6 @@
],
shared_libs: [
- "libhardware",
"libcutils",
"liblog",
"libutils",
diff --git a/libs/renderengine/gl/GLESRenderEngine.cpp b/libs/renderengine/gl/GLESRenderEngine.cpp
index 36a54a7..b0b4f6c 100644
--- a/libs/renderengine/gl/GLESRenderEngine.cpp
+++ b/libs/renderengine/gl/GLESRenderEngine.cpp
@@ -147,52 +147,6 @@
return NAME_NOT_FOUND;
}
-class EGLAttributeVector {
- struct Attribute;
- class Adder;
- friend class Adder;
- KeyedVector<Attribute, EGLint> mList;
- struct Attribute {
- Attribute() : v(0){};
- explicit Attribute(EGLint v) : v(v) {}
- EGLint v;
- bool operator<(const Attribute& other) const {
- // this places EGL_NONE at the end
- EGLint lhs(v);
- EGLint rhs(other.v);
- if (lhs == EGL_NONE) lhs = 0x7FFFFFFF;
- if (rhs == EGL_NONE) rhs = 0x7FFFFFFF;
- return lhs < rhs;
- }
- };
- class Adder {
- friend class EGLAttributeVector;
- EGLAttributeVector& v;
- EGLint attribute;
- Adder(EGLAttributeVector& v, EGLint attribute) : v(v), attribute(attribute) {}
-
- public:
- void operator=(EGLint value) {
- if (attribute != EGL_NONE) {
- v.mList.add(Attribute(attribute), value);
- }
- }
- operator EGLint() const { return v.mList[attribute]; }
- };
-
-public:
- EGLAttributeVector() { mList.add(Attribute(EGL_NONE), EGL_NONE); }
- void remove(EGLint attribute) {
- if (attribute != EGL_NONE) {
- mList.removeItem(Attribute(attribute));
- }
- }
- Adder operator[](EGLint attribute) { return Adder(*this, attribute); }
- EGLint operator[](EGLint attribute) const { return mList[attribute]; }
- // cast-operator to (EGLint const*)
- operator EGLint const*() const { return &mList.keyAt(0).v; }
-};
-
static status_t selectEGLConfig(EGLDisplay display, EGLint format, EGLint renderableType,
EGLConfig* config) {
// select our EGLConfig. It must support EGL_RECORDABLE_ANDROID if
@@ -201,16 +155,33 @@
EGLint wantedAttribute;
EGLint wantedAttributeValue;
- EGLAttributeVector attribs;
+ std::vector<EGLint> attribs;
if (renderableType) {
- attribs[EGL_RENDERABLE_TYPE] = renderableType;
- attribs[EGL_RECORDABLE_ANDROID] = EGL_TRUE;
- attribs[EGL_SURFACE_TYPE] = EGL_WINDOW_BIT | EGL_PBUFFER_BIT;
- attribs[EGL_FRAMEBUFFER_TARGET_ANDROID] = EGL_TRUE;
- attribs[EGL_RED_SIZE] = 8;
- attribs[EGL_GREEN_SIZE] = 8;
- attribs[EGL_BLUE_SIZE] = 8;
- attribs[EGL_ALPHA_SIZE] = 8;
+ const ui::PixelFormat pixelFormat = static_cast<ui::PixelFormat>(format);
+ const bool is1010102 = pixelFormat == ui::PixelFormat::RGBA_1010102;
+
+ // Default to 8 bits per channel.
+ const EGLint tmpAttribs[] = {
+ EGL_RENDERABLE_TYPE,
+ renderableType,
+ EGL_RECORDABLE_ANDROID,
+ EGL_TRUE,
+ EGL_SURFACE_TYPE,
+ EGL_WINDOW_BIT | EGL_PBUFFER_BIT,
+ EGL_FRAMEBUFFER_TARGET_ANDROID,
+ EGL_TRUE,
+ EGL_RED_SIZE,
+ is1010102 ? 10 : 8,
+ EGL_GREEN_SIZE,
+ is1010102 ? 10 : 8,
+ EGL_BLUE_SIZE,
+ is1010102 ? 10 : 8,
+ EGL_ALPHA_SIZE,
+ is1010102 ? 2 : 8,
+ EGL_NONE,
+ };
+ std::copy(tmpAttribs, tmpAttribs + (sizeof(tmpAttribs) / sizeof(EGLint)),
+ std::back_inserter(attribs));
wantedAttribute = EGL_NONE;
wantedAttributeValue = EGL_NONE;
} else {
@@ -219,7 +190,8 @@
wantedAttributeValue = format;
}
- err = selectConfigForAttribute(display, attribs, wantedAttribute, wantedAttributeValue, config);
+ err = selectConfigForAttribute(display, attribs.data(), wantedAttribute, wantedAttributeValue,
+ config);
if (err == NO_ERROR) {
EGLint caveat;
if (eglGetConfigAttrib(display, *config, EGL_CONFIG_CAVEAT, &caveat))
@@ -897,13 +869,32 @@
return glStatus == GL_FRAMEBUFFER_COMPLETE_OES ? NO_ERROR : BAD_VALUE;
}
-void GLESRenderEngine::unbindFrameBuffer(Framebuffer* /* framebuffer */) {
+void GLESRenderEngine::unbindFrameBuffer(Framebuffer* /*framebuffer*/) {
ATRACE_CALL();
// back to main framebuffer
glBindFramebuffer(GL_FRAMEBUFFER, 0);
}
+bool GLESRenderEngine::cleanupPostRender() {
+ ATRACE_CALL();
+
+ if (mPriorResourcesCleaned ||
+ (mLastDrawFence != nullptr && mLastDrawFence->getStatus() != Fence::Status::Signaled)) {
+ // If we don't have a prior frame needing cleanup, then don't do anything.
+ return false;
+ }
+
+ // Bind the texture to dummy data so that backing image data can be freed.
+ GLFramebuffer* glFramebuffer = static_cast<GLFramebuffer*>(getFramebufferForDrawing());
+ glFramebuffer->allocateBuffers(1, 1, mPlaceholderDrawBuffer);
+ // Release the cached fence here, so that we don't churn reallocations when
+ // we could no-op repeated calls of this method instead.
+ mLastDrawFence = nullptr;
+ mPriorResourcesCleaned = true;
+ return true;
+}
+
void GLESRenderEngine::checkErrors() const {
checkErrors(nullptr);
}
@@ -1189,7 +1180,13 @@
// us bad parameters, or we messed up our shader generation).
return INVALID_OPERATION;
}
+ mLastDrawFence = nullptr;
+ } else {
+ // The caller takes ownership of drawFence, so we need to duplicate the
+ // fd here.
+ mLastDrawFence = new Fence(dup(drawFence->get()));
}
+ mPriorResourcesCleaned = false;
checkErrors();
return NO_ERROR;
diff --git a/libs/renderengine/gl/GLESRenderEngine.h b/libs/renderengine/gl/GLESRenderEngine.h
index 32dbad1..42b8537 100644
--- a/libs/renderengine/gl/GLESRenderEngine.h
+++ b/libs/renderengine/gl/GLESRenderEngine.h
@@ -17,7 +17,6 @@
#ifndef SF_GLESRENDERENGINE_H_
#define SF_GLESRENDERENGINE_H_
-#include <stdint.h>
#include <condition_variable>
#include <deque>
#include <mutex>
@@ -76,6 +75,7 @@
const std::vector<const LayerSettings*>& layers,
ANativeWindowBuffer* buffer, const bool useFramebufferCache,
base::unique_fd&& bufferFence, base::unique_fd* drawFence) override;
+ bool cleanupPostRender() override;
EGLDisplay getEGLDisplay() const { return mEGLDisplay; }
// Creates an output image for rendering to
@@ -231,6 +231,17 @@
std::mutex mRenderingMutex;
std::unique_ptr<Framebuffer> mDrawingBuffer;
+ // this is a 1x1 RGB buffer, but over-allocate in case a driver wants more
+ // memory or if it needs to satisfy alignment requirements. In this case:
+ // assume that each channel requires 4 bytes, and add 3 additional bytes to
+ // ensure that we align on a word. Allocating 16 bytes will provide a
+ // guarantee that we don't clobber memory.
+ uint32_t mPlaceholderDrawBuffer[4];
+ sp<Fence> mLastDrawFence;
+ // Store a separate boolean checking if prior resources were cleaned up, as
+ // devices that don't support native sync fences can't rely on a last draw
+ // fence that doesn't exist.
+ bool mPriorResourcesCleaned = true;
// Blur effect processor, only instantiated when a layer requests it.
BlurFilter* mBlurFilter = nullptr;
diff --git a/libs/renderengine/gl/GLFramebuffer.cpp b/libs/renderengine/gl/GLFramebuffer.cpp
index cb0d5cf..383486b 100644
--- a/libs/renderengine/gl/GLFramebuffer.cpp
+++ b/libs/renderengine/gl/GLFramebuffer.cpp
@@ -68,11 +68,11 @@
return true;
}
-void GLFramebuffer::allocateBuffers(uint32_t width, uint32_t height) {
+void GLFramebuffer::allocateBuffers(uint32_t width, uint32_t height, void* data) {
ATRACE_CALL();
glBindTexture(GL_TEXTURE_2D, mTextureName);
- glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, nullptr);
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, data);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_MIRRORED_REPEAT);
diff --git a/libs/renderengine/gl/GLFramebuffer.h b/libs/renderengine/gl/GLFramebuffer.h
index b88da3b..6757695 100644
--- a/libs/renderengine/gl/GLFramebuffer.h
+++ b/libs/renderengine/gl/GLFramebuffer.h
@@ -39,7 +39,7 @@
bool setNativeWindowBuffer(ANativeWindowBuffer* nativeBuffer, bool isProtected,
const bool useFramebufferCache) override;
- void allocateBuffers(uint32_t width, uint32_t height);
+ void allocateBuffers(uint32_t width, uint32_t height, void* data = nullptr);
EGLImageKHR getEGLImage() const { return mEGLImage; }
uint32_t getTextureName() const { return mTextureName; }
uint32_t getFramebufferName() const { return mFramebufferName; }
diff --git a/libs/renderengine/gl/filters/BlurFilter.cpp b/libs/renderengine/gl/filters/BlurFilter.cpp
index 724877b..db55d17 100644
--- a/libs/renderengine/gl/filters/BlurFilter.cpp
+++ b/libs/renderengine/gl/filters/BlurFilter.cpp
@@ -261,15 +261,6 @@
return shader;
}
-void BlurFilter::blit(GLFramebuffer& read, GLFramebuffer& draw) const {
- ATRACE_NAME("BlurFilter::blit");
- read.bindAsReadBuffer();
- draw.bindAsDrawBuffer();
- glBlitFramebuffer(0, 0, read.getBufferWidth(), read.getBufferHeight(), 0, 0,
- draw.getBufferWidth(), draw.getBufferHeight(), GL_COLOR_BUFFER_BIT,
- GL_LINEAR);
-}
-
} // namespace gl
} // namespace renderengine
} // namespace android
diff --git a/libs/renderengine/gl/filters/BlurFilter.h b/libs/renderengine/gl/filters/BlurFilter.h
index 7e0819f..9d3fc60 100644
--- a/libs/renderengine/gl/filters/BlurFilter.h
+++ b/libs/renderengine/gl/filters/BlurFilter.h
@@ -56,7 +56,6 @@
private:
uint32_t mRadius;
void drawMesh(GLuint uv, GLuint position);
- void blit(GLFramebuffer& read, GLFramebuffer& draw) const;
string getVertexShader() const;
string getFragmentShader() const;
string getMixFragShader() const;
diff --git a/libs/renderengine/include/renderengine/RenderEngine.h b/libs/renderengine/include/renderengine/RenderEngine.h
index 46f3fc6..e06e128 100644
--- a/libs/renderengine/include/renderengine/RenderEngine.h
+++ b/libs/renderengine/include/renderengine/RenderEngine.h
@@ -111,6 +111,14 @@
// Returns NO_ERROR when binds successfully, NO_MEMORY when there's no memory for allocation.
virtual status_t bindFrameBuffer(Framebuffer* framebuffer) = 0;
virtual void unbindFrameBuffer(Framebuffer* framebuffer) = 0;
+ // Clean-up method that should be called on the main thread after the
+ // drawFence returned by drawLayers fires. This method will free up
+ // resources used by the most recently drawn frame. If the frame is still
+ // being drawn, then this call is silently ignored.
+ //
+ // Returns true if resources were cleaned up, and false if we didn't need to
+ // do any work.
+ virtual bool cleanupPostRender() = 0;
// queries
virtual size_t getMaxTextureSize() const = 0;
diff --git a/libs/renderengine/include/renderengine/mock/RenderEngine.h b/libs/renderengine/include/renderengine/mock/RenderEngine.h
index 3358c69..df0f17a 100644
--- a/libs/renderengine/include/renderengine/mock/RenderEngine.h
+++ b/libs/renderengine/include/renderengine/mock/RenderEngine.h
@@ -22,6 +22,7 @@
#include <renderengine/Mesh.h>
#include <renderengine/RenderEngine.h>
#include <renderengine/Texture.h>
+#include <ui/Fence.h>
#include <ui/GraphicBuffer.h>
#include <ui/Region.h>
@@ -55,6 +56,7 @@
MOCK_CONST_METHOD0(isProtected, bool());
MOCK_CONST_METHOD0(supportsProtectedContent, bool());
MOCK_METHOD1(useProtectedContext, bool(bool));
+ MOCK_METHOD0(cleanupPostRender, bool());
MOCK_METHOD6(drawLayers,
status_t(const DisplaySettings&, const std::vector<const LayerSettings*>&,
ANativeWindowBuffer*, const bool, base::unique_fd&&, base::unique_fd*));
diff --git a/libs/renderengine/tests/RenderEngineTest.cpp b/libs/renderengine/tests/RenderEngineTest.cpp
index f5bf014..16a8a0d 100644
--- a/libs/renderengine/tests/RenderEngineTest.cpp
+++ b/libs/renderengine/tests/RenderEngineTest.cpp
@@ -1241,12 +1241,12 @@
EXPECT_EQ(NO_ERROR, barrier->result);
}
-TEST_F(RenderEngineTest, drawLayers_bindExternalBufferWithNullBuffer) {
+TEST_F(RenderEngineTest, bindExternalBuffer_withNullBuffer) {
status_t result = sRE->bindExternalTextureBuffer(0, nullptr, nullptr);
ASSERT_EQ(BAD_VALUE, result);
}
-TEST_F(RenderEngineTest, drawLayers_bindExternalBufferCachesImages) {
+TEST_F(RenderEngineTest, bindExternalBuffer_cachesImages) {
sp<GraphicBuffer> buf = allocateSourceBuffer(1, 1);
uint32_t texName;
sRE->genTextures(1, &texName);
@@ -1266,7 +1266,7 @@
EXPECT_FALSE(sRE->isImageCachedForTesting(bufferId));
}
-TEST_F(RenderEngineTest, drawLayers_cacheExternalBufferWithNullBuffer) {
+TEST_F(RenderEngineTest, cacheExternalBuffer_withNullBuffer) {
std::shared_ptr<renderengine::gl::ImageManager::Barrier> barrier =
sRE->cacheExternalTextureBufferForTesting(nullptr);
std::lock_guard<std::mutex> lock(barrier->mutex);
@@ -1278,7 +1278,7 @@
EXPECT_EQ(BAD_VALUE, barrier->result);
}
-TEST_F(RenderEngineTest, drawLayers_cacheExternalBufferCachesImages) {
+TEST_F(RenderEngineTest, cacheExternalBuffer_cachesImages) {
sp<GraphicBuffer> buf = allocateSourceBuffer(1, 1);
uint64_t bufferId = buf->getId();
std::shared_ptr<renderengine::gl::ImageManager::Barrier> barrier =
@@ -1401,6 +1401,35 @@
backgroundColor.a);
}
+TEST_F(RenderEngineTest, cleanupPostRender_cleansUpOnce) {
+ renderengine::DisplaySettings settings;
+ settings.physicalDisplay = fullscreenRect();
+ settings.clip = fullscreenRect();
+
+ std::vector<const renderengine::LayerSettings*> layers;
+ renderengine::LayerSettings layer;
+ layer.geometry.boundaries = fullscreenRect().toFloatRect();
+ BufferSourceVariant<ForceOpaqueBufferVariant>::fillColor(layer, 1.0f, 0.0f, 0.0f, this);
+ layer.alpha = 1.0;
+ layers.push_back(&layer);
+
+ base::unique_fd fenceOne;
+ sRE->drawLayers(settings, layers, mBuffer->getNativeBuffer(), true, base::unique_fd(),
+ &fenceOne);
+ base::unique_fd fenceTwo;
+ sRE->drawLayers(settings, layers, mBuffer->getNativeBuffer(), true, std::move(fenceOne),
+ &fenceTwo);
+
+ const int fd = fenceTwo.get();
+ if (fd >= 0) {
+ sync_wait(fd, -1);
+ }
+
+ // Only cleanup the first time.
+ EXPECT_TRUE(sRE->cleanupPostRender());
+ EXPECT_FALSE(sRE->cleanupPostRender());
+}
+
} // namespace android
// TODO(b/129481165): remove the #pragma below and fix conversion issues
diff --git a/libs/vr/libpdx_uds/service_endpoint.cpp b/libs/vr/libpdx_uds/service_endpoint.cpp
index ecbfdba..9bc70ea 100644
--- a/libs/vr/libpdx_uds/service_endpoint.cpp
+++ b/libs/vr/libpdx_uds/service_endpoint.cpp
@@ -535,13 +535,13 @@
*message = Message{info};
auto* state = static_cast<MessageState*>(message->GetState());
state->request = std::move(request);
- if (request.send_len > 0 && !request.is_impulse) {
- state->request_data.resize(request.send_len);
+ if (state->request.send_len > 0 && !state->request.is_impulse) {
+ state->request_data.resize(state->request.send_len);
status = ReceiveData(channel_fd, state->request_data.data(),
state->request_data.size());
}
- if (status && request.is_impulse)
+ if (status && state->request.is_impulse)
status = ReenableEpollEvent(channel_fd);
if (!status) {
diff --git a/libs/vr/libvrflinger/tests/Android.bp b/libs/vr/libvrflinger/tests/Android.bp
index 410e234..7fafd3b 100644
--- a/libs/vr/libvrflinger/tests/Android.bp
+++ b/libs/vr/libvrflinger/tests/Android.bp
@@ -11,6 +11,7 @@
"libutils",
"libnativewindow",
"libpdx_default_transport",
+ "libSurfaceFlingerProp",
]
static_libs = [
@@ -32,5 +33,6 @@
"-Wall",
"-Werror",
],
+ header_libs: ["libsurfaceflinger_headers"],
name: "vrflinger_test",
}
diff --git a/libs/vr/libvrflinger/tests/vrflinger_test.cpp b/libs/vr/libvrflinger/tests/vrflinger_test.cpp
index 7075e88..efd6d1d 100644
--- a/libs/vr/libvrflinger/tests/vrflinger_test.cpp
+++ b/libs/vr/libvrflinger/tests/vrflinger_test.cpp
@@ -1,3 +1,4 @@
+#include <SurfaceFlingerProperties.h>
#include <android/hardware/configstore/1.0/ISurfaceFlingerConfigs.h>
#include <android/hardware/configstore/1.1/types.h>
#include <android/hardware_buffer.h>
@@ -147,9 +148,7 @@
// Exit immediately if the device doesn't support vr flinger. This ConfigStore
// check is the same mechanism used by surface flinger to decide if it should
// initialize vr flinger.
- bool vr_flinger_enabled =
- getBool<ISurfaceFlingerConfigs, &ISurfaceFlingerConfigs::useVrFlinger>(
- false);
+ bool vr_flinger_enabled = android::sysprop::use_vr_flinger(false);
if (!vr_flinger_enabled) {
return;
}
diff --git a/opengl/libs/Android.bp b/opengl/libs/Android.bp
index e255b9d..19b8a58 100644
--- a/opengl/libs/Android.bp
+++ b/opengl/libs/Android.bp
@@ -154,6 +154,7 @@
"libnativebridge_lazy",
"libnativeloader_lazy",
"libutils",
+ "libSurfaceFlingerProp",
],
static_libs: [
"libEGL_getProcAddress",
@@ -165,6 +166,7 @@
symbol_file: "libEGL.map.txt",
versions: ["29"],
},
+ header_libs: ["libsurfaceflinger_headers"],
}
cc_test {
diff --git a/opengl/libs/EGL/Loader.cpp b/opengl/libs/EGL/Loader.cpp
index e19802b..d664e4d 100644
--- a/opengl/libs/EGL/Loader.cpp
+++ b/opengl/libs/EGL/Loader.cpp
@@ -222,13 +222,6 @@
return cnx->dso;
}
- // Check if we should use ANGLE early, so loading each driver doesn't require repeated queries.
- if (android::GraphicsEnv::getInstance().shouldUseAngle()) {
- cnx->shouldUseAngle = true;
- } else {
- cnx->shouldUseAngle = false;
- }
-
// Firstly, try to load ANGLE driver.
driver_t* hnd = attempt_to_load_angle(cnx);
if (!hnd) {
@@ -278,6 +271,12 @@
if (!hnd) {
android::GraphicsEnv::getInstance().setDriverLoaded(android::GpuStatsInfo::Api::API_GL,
false, systemTime() - openTime);
+ } else {
+ // init_angle_backend will check if loaded driver is ANGLE or not,
+ // will set cnx->useAngle appropriately.
+ // Do this here so that we use ANGLE path when driver is ANGLE (e.g. loaded as native),
+ // not just loading ANGLE as option.
+ init_angle_backend(hnd->dso[0], cnx);
}
LOG_ALWAYS_FATAL_IF(!hnd,
@@ -317,14 +316,7 @@
delete hnd;
cnx->dso = nullptr;
- cnx->shouldUseAngle = false;
- cnx->angleDecided = false;
cnx->useAngle = false;
-
- if (cnx->vendorEGL) {
- dlclose(cnx->vendorEGL);
- cnx->vendorEGL = nullptr;
- }
}
void Loader::init_api(void* dso,
@@ -491,7 +483,7 @@
return dso;
}
-static void* load_angle_from_namespace(const char* kind, android_namespace_t* ns) {
+static void* load_angle(const char* kind, android_namespace_t* ns) {
const android_dlextinfo dlextinfo = {
.flags = ANDROID_DLEXT_USE_NAMESPACE,
.library_namespace = ns,
@@ -511,69 +503,6 @@
return nullptr;
}
-static void* load_angle(const char* kind, android_namespace_t* ns, egl_connection_t* cnx) {
- void* so = nullptr;
-
- if ((cnx->shouldUseAngle) || android::GraphicsEnv::getInstance().shouldUseAngle()) {
- so = load_angle_from_namespace(kind, ns);
- cnx->shouldUseAngle = true;
- } else {
- cnx->shouldUseAngle = false;
- }
-
- if (so) {
- ALOGV("Loaded ANGLE %s library for '%s' (instead of native)", kind,
- android::GraphicsEnv::getInstance().getAngleAppName().c_str());
- cnx->useAngle = true;
-
- char prop[PROPERTY_VALUE_MAX];
-
- property_get("debug.hwui.renderer", prop, "UNSET");
- ALOGV("Skia's renderer set to %s", prop);
-
- EGLint angleBackendDefault = EGL_PLATFORM_ANGLE_TYPE_VULKAN_ANGLE;
- property_get("debug.angle.backend", prop, "0");
- switch (atoi(prop)) {
- case 1:
- ALOGV("%s: Requesting OpenGLES back-end", __FUNCTION__);
- angleBackendDefault = EGL_PLATFORM_ANGLE_TYPE_OPENGLES_ANGLE;
- break;
- case 2:
- ALOGV("%s: Requesting Vulkan back-end", __FUNCTION__);
- angleBackendDefault = EGL_PLATFORM_ANGLE_TYPE_VULKAN_ANGLE;
- break;
- default:
- break;
- }
-
- cnx->angleBackend = angleBackendDefault;
- if (!cnx->vendorEGL && (cnx->angleBackend == EGL_PLATFORM_ANGLE_TYPE_OPENGLES_ANGLE)) {
- // Find and load vendor libEGL for ANGLE's GL back-end to use.
- char prop[PROPERTY_VALUE_MAX + 1];
- for (auto key : HAL_SUBNAME_KEY_PROPERTIES) {
- if (property_get(key, prop, nullptr) <= 0) {
- continue;
- }
- void* dso = load_system_driver("EGL", prop, true);
- if (dso) {
- cnx->vendorEGL = dso;
- break;
- }
- }
- if (!cnx->vendorEGL) {
- cnx->vendorEGL = load_system_driver("EGL", nullptr, true);
- }
- }
- } else {
- ALOGV("Loaded native %s library for '%s' (instead of ANGLE)", kind,
- android::GraphicsEnv::getInstance().getAngleAppName().c_str());
- cnx->useAngle = false;
- }
- cnx->angleDecided = true;
-
- return so;
-}
-
static void* load_updated_driver(const char* kind, android_namespace_t* ns) {
ATRACE_CALL();
const android_dlextinfo dlextinfo = {
@@ -597,6 +526,11 @@
Loader::driver_t* Loader::attempt_to_load_angle(egl_connection_t* cnx) {
ATRACE_CALL();
+
+ if (!android::GraphicsEnv::getInstance().shouldUseAngle()) {
+ return nullptr;
+ }
+
android_namespace_t* ns = android::GraphicsEnv::getInstance().getAngleNamespace();
if (!ns) {
return nullptr;
@@ -606,22 +540,37 @@
driver_t* hnd = nullptr;
// ANGLE doesn't ship with GLES library, and thus we skip GLES driver.
- void* dso = load_angle("EGL", ns, cnx);
+ void* dso = load_angle("EGL", ns);
if (dso) {
initialize_api(dso, cnx, EGL);
hnd = new driver_t(dso);
- dso = load_angle("GLESv1_CM", ns, cnx);
+ dso = load_angle("GLESv1_CM", ns);
initialize_api(dso, cnx, GLESv1_CM);
hnd->set(dso, GLESv1_CM);
- dso = load_angle("GLESv2", ns, cnx);
+ dso = load_angle("GLESv2", ns);
initialize_api(dso, cnx, GLESv2);
hnd->set(dso, GLESv2);
}
return hnd;
}
+void Loader::init_angle_backend(void* dso, egl_connection_t* cnx) {
+ void* eglCreateDeviceANGLE = nullptr;
+
+ ALOGV("dso: %p", dso);
+ eglCreateDeviceANGLE = dlsym(dso, "eglCreateDeviceANGLE");
+ ALOGV("eglCreateDeviceANGLE: %p", eglCreateDeviceANGLE);
+ if (eglCreateDeviceANGLE) {
+ ALOGV("ANGLE GLES library in use");
+ cnx->useAngle = true;
+ } else {
+ ALOGV("Native GLES library in use");
+ cnx->useAngle = false;
+ }
+}
+
Loader::driver_t* Loader::attempt_to_load_updated_driver(egl_connection_t* cnx) {
ATRACE_CALL();
#ifndef __ANDROID_VNDK__
diff --git a/opengl/libs/EGL/Loader.h b/opengl/libs/EGL/Loader.h
index 6f31ab4..7b2d7c9 100644
--- a/opengl/libs/EGL/Loader.h
+++ b/opengl/libs/EGL/Loader.h
@@ -60,6 +60,7 @@
driver_t* attempt_to_load_system_driver(egl_connection_t* cnx, const char* suffix, const bool exact);
void unload_system_driver(egl_connection_t* cnx);
void initialize_api(void* dso, egl_connection_t* cnx, uint32_t mask);
+ void init_angle_backend(void* dso, egl_connection_t* cnx);
static __attribute__((noinline))
void init_api(void* dso,
diff --git a/opengl/libs/EGL/egl_display.cpp b/opengl/libs/EGL/egl_display.cpp
index a58e87c..6af7cd2 100644
--- a/opengl/libs/EGL/egl_display.cpp
+++ b/opengl/libs/EGL/egl_display.cpp
@@ -31,6 +31,7 @@
#include "egl_object.h"
#include "egl_tls.h"
+#include <SurfaceFlingerProperties.h>
#include <android/dlext.h>
#include <dlfcn.h>
#include <graphicsenv/GraphicsEnv.h>
@@ -133,45 +134,6 @@
return sDisplay[uintptr_t(disp)].getPlatformDisplay(disp, attrib_list);
}
-static bool addAnglePlatformAttributes(egl_connection_t* const cnx,
- std::vector<EGLAttrib>& attrs) {
- intptr_t vendorEGL = (intptr_t)cnx->vendorEGL;
-
- attrs.reserve(4 * 2);
-
- attrs.push_back(EGL_PLATFORM_ANGLE_TYPE_ANGLE);
- attrs.push_back(cnx->angleBackend);
-
- switch (cnx->angleBackend) {
- case EGL_PLATFORM_ANGLE_TYPE_VULKAN_ANGLE:
- ALOGV("%s: Requesting Vulkan ANGLE back-end", __FUNCTION__);
- char prop[PROPERTY_VALUE_MAX];
- property_get("debug.angle.validation", prop, "0");
- attrs.push_back(EGL_PLATFORM_ANGLE_DEBUG_LAYERS_ENABLED_ANGLE);
- attrs.push_back(atoi(prop));
- break;
- case EGL_PLATFORM_ANGLE_TYPE_DEFAULT_ANGLE:
- ALOGV("%s: Requesting Default ANGLE back-end", __FUNCTION__);
- break;
- case EGL_PLATFORM_ANGLE_TYPE_OPENGLES_ANGLE:
- ALOGV("%s: Requesting OpenGL ES ANGLE back-end", __FUNCTION__);
- // NOTE: This is only valid if the backend is OpenGL
- attrs.push_back(EGL_PLATFORM_ANGLE_EGL_HANDLE_ANGLE);
- attrs.push_back(vendorEGL);
-
- // Context virtualization is only available on GL back-end.
- // Needed to support threading with GL back-end
- attrs.push_back(EGL_PLATFORM_ANGLE_CONTEXT_VIRTUALIZATION_ANGLE);
- attrs.push_back(EGL_FALSE);
- break;
- default:
- ALOGE("%s: Requesting Unknown (%d) ANGLE back-end", __FUNCTION__, cnx->angleBackend);
- break;
- }
-
- return true;
-}
-
static EGLDisplay getPlatformDisplayAngle(EGLNativeDisplayType display, egl_connection_t* const cnx,
const EGLAttrib* attrib_list, EGLint* error) {
EGLDisplay dpy = EGL_NO_DISPLAY;
@@ -186,11 +148,14 @@
}
}
- if (!addAnglePlatformAttributes(cnx, attrs)) {
- ALOGE("eglGetDisplay(%p) failed: Mismatch display request", display);
- *error = EGL_BAD_PARAMETER;
- return EGL_NO_DISPLAY;
- }
+ attrs.push_back(EGL_PLATFORM_ANGLE_TYPE_ANGLE);
+ attrs.push_back(EGL_PLATFORM_ANGLE_TYPE_VULKAN_ANGLE);
+
+ char prop[PROPERTY_VALUE_MAX];
+ property_get("debug.angle.validation", prop, "0");
+ attrs.push_back(EGL_PLATFORM_ANGLE_DEBUG_LAYERS_ENABLED_ANGLE);
+ attrs.push_back(atoi(prop));
+
attrs.push_back(EGL_NONE);
dpy = cnx->egl.eglGetPlatformDisplay(EGL_PLATFORM_ANGLE_ANGLE,
@@ -361,9 +326,7 @@
// Note: CDD requires that devices supporting wide color and/or HDR color also support
// the EGL_KHR_gl_colorspace extension.
- bool wideColorBoardConfig =
- getBool<ISurfaceFlingerConfigs, &ISurfaceFlingerConfigs::hasWideColorDisplay>(
- false);
+ bool wideColorBoardConfig = android::sysprop::has_wide_color_display(false);
// Add wide-color extensions if device can support wide-color
if (wideColorBoardConfig && hasColorSpaceSupport) {
@@ -373,8 +336,7 @@
"EGL_EXT_gl_colorspace_display_p3_passthrough ");
}
- bool hasHdrBoardConfig =
- getBool<ISurfaceFlingerConfigs, &ISurfaceFlingerConfigs::hasHDRDisplay>(false);
+ bool hasHdrBoardConfig = android::sysprop::has_HDR_display(false);
if (hasHdrBoardConfig && hasColorSpaceSupport) {
// hasHDRBoardConfig indicates the system is capable of supporting HDR content.
diff --git a/opengl/libs/EGL/egl_platform_entries.cpp b/opengl/libs/EGL/egl_platform_entries.cpp
index c8840f9..1b75b20 100644
--- a/opengl/libs/EGL/egl_platform_entries.cpp
+++ b/opengl/libs/EGL/egl_platform_entries.cpp
@@ -721,7 +721,7 @@
// NOTE: When using Vulkan backend, the Vulkan runtime makes all the
// native_window_* calls, so don't do them here.
- if (cnx->angleBackend != EGL_PLATFORM_ANGLE_TYPE_VULKAN_ANGLE) {
+ if (!cnx->useAngle) {
int result = native_window_api_connect(window, NATIVE_WINDOW_API_EGL);
if (result < 0) {
ALOGE("eglCreateWindowSurface: native_window_api_connect (win=%p) "
@@ -740,14 +740,14 @@
std::vector<AttrType> strippedAttribList;
if (!processAttributes<AttrType>(dp, window, attrib_list, &colorSpace, &strippedAttribList)) {
ALOGE("error invalid colorspace: %d", colorSpace);
- if (cnx->angleBackend != EGL_PLATFORM_ANGLE_TYPE_VULKAN_ANGLE) {
+ if (!cnx->useAngle) {
native_window_api_disconnect(window, NATIVE_WINDOW_API_EGL);
}
return EGL_NO_SURFACE;
}
attrib_list = strippedAttribList.data();
- if (cnx->angleBackend != EGL_PLATFORM_ANGLE_TYPE_VULKAN_ANGLE) {
+ if (!cnx->useAngle) {
int err = native_window_set_buffers_format(window, format);
if (err != 0) {
ALOGE("error setting native window pixel format: %s (%d)", strerror(-err), err);
@@ -779,7 +779,7 @@
}
// EGLSurface creation failed
- if (cnx->angleBackend != EGL_PLATFORM_ANGLE_TYPE_VULKAN_ANGLE) {
+ if (!cnx->useAngle) {
native_window_set_buffers_format(window, 0);
native_window_api_disconnect(window, NATIVE_WINDOW_API_EGL);
}
@@ -1419,7 +1419,7 @@
}
}
- if (s->cnx->angleBackend != EGL_PLATFORM_ANGLE_TYPE_VULKAN_ANGLE) {
+ if (!s->cnx->useAngle) {
if (!sendSurfaceMetadata(s)) {
native_window_api_disconnect(s->getNativeWindow(), NATIVE_WINDOW_API_EGL);
return setError(EGL_BAD_NATIVE_WINDOW, (EGLBoolean)EGL_FALSE);
@@ -1444,7 +1444,7 @@
androidRect.bottom = y;
androidRects.push_back(androidRect);
}
- if (s->cnx->angleBackend != EGL_PLATFORM_ANGLE_TYPE_VULKAN_ANGLE) {
+ if (!s->cnx->useAngle) {
native_window_set_surface_damage(s->getNativeWindow(), androidRects.data(),
androidRects.size());
}
diff --git a/opengl/libs/EGL/egldefs.h b/opengl/libs/EGL/egldefs.h
index 7bb9b59..5fbffbd 100644
--- a/opengl/libs/EGL/egldefs.h
+++ b/opengl/libs/EGL/egldefs.h
@@ -81,11 +81,7 @@
void* libGles2;
bool systemDriverUnloaded;
- bool shouldUseAngle; // Should we attempt to load ANGLE
- bool angleDecided; // Have we tried to load ANGLE
bool useAngle; // Was ANGLE successfully loaded
- EGLint angleBackend;
- void* vendorEGL;
};
// clang-format on
diff --git a/opengl/tests/EGLTest/Android.bp b/opengl/tests/EGLTest/Android.bp
index 8bfe517..e3912a8 100644
--- a/opengl/tests/EGLTest/Android.bp
+++ b/opengl/tests/EGLTest/Android.bp
@@ -25,6 +25,7 @@
"liblog",
"libutils",
"libnativewindow",
+ "libSurfaceFlingerProp",
],
include_dirs: [
@@ -34,5 +35,6 @@
header_libs: [
"bionic_libc_platform_headers",
+ "libsurfaceflinger_headers",
],
}
diff --git a/opengl/tests/EGLTest/EGL_test.cpp b/opengl/tests/EGLTest/EGL_test.cpp
index cca91c3..510226d 100644
--- a/opengl/tests/EGLTest/EGL_test.cpp
+++ b/opengl/tests/EGLTest/EGL_test.cpp
@@ -16,6 +16,7 @@
#include <gtest/gtest.h>
+#include <SurfaceFlingerProperties.h>
#include <android/hardware/configstore/1.0/ISurfaceFlingerConfigs.h>
#include <configstore/Utils.h>
@@ -52,11 +53,9 @@
#define METADATA_SCALE(x) (static_cast<EGLint>(x * EGL_METADATA_SCALING_EXT))
-static bool hasWideColorDisplay =
- getBool<ISurfaceFlingerConfigs, &ISurfaceFlingerConfigs::hasWideColorDisplay>(false);
+static bool hasWideColorDisplay = android::sysprop::has_wide_color_display(false);
-static bool hasHdrDisplay =
- getBool<ISurfaceFlingerConfigs, &ISurfaceFlingerConfigs::hasHDRDisplay>(false);
+static bool hasHdrDisplay = android::sysprop::has_HDR_display(false);
class EGLTest : public ::testing::Test {
public:
diff --git a/services/inputflinger/dispatcher/InputDispatcher.cpp b/services/inputflinger/dispatcher/InputDispatcher.cpp
index 0982ea7..baf2f2b 100644
--- a/services/inputflinger/dispatcher/InputDispatcher.cpp
+++ b/services/inputflinger/dispatcher/InputDispatcher.cpp
@@ -352,18 +352,16 @@
break;
}
}
- std::vector<uint8_t> data;
const uint8_t* start = reinterpret_cast<const uint8_t*>(&event);
- data.assign(start, start + size);
- return sign(data);
+ return sign(start, size);
}
-std::array<uint8_t, 32> HmacKeyManager::sign(const std::vector<uint8_t>& data) const {
+std::array<uint8_t, 32> HmacKeyManager::sign(const uint8_t* data, size_t size) const {
// SHA256 always generates 32-bytes result
std::array<uint8_t, 32> hash;
unsigned int hashLen = 0;
- uint8_t* result = HMAC(EVP_sha256(), mHmacKey.data(), mHmacKey.size(), data.data(), data.size(),
- hash.data(), &hashLen);
+ uint8_t* result =
+ HMAC(EVP_sha256(), mHmacKey.data(), mHmacKey.size(), data, size, hash.data(), &hashLen);
if (result == nullptr) {
ALOGE("Could not sign the data using HMAC");
return INVALID_HMAC;
@@ -2482,11 +2480,8 @@
EventEntry* eventEntry = dispatchEntry->eventEntry;
switch (eventEntry->type) {
case EventEntry::Type::KEY: {
- KeyEntry* keyEntry = static_cast<KeyEntry*>(eventEntry);
- VerifiedKeyEvent verifiedEvent = verifiedKeyEventFromKeyEntry(*keyEntry);
- verifiedEvent.flags = dispatchEntry->resolvedFlags & VERIFIED_KEY_EVENT_FLAGS;
- verifiedEvent.action = dispatchEntry->resolvedAction;
- std::array<uint8_t, 32> hmac = mHmacKeyManager.sign(verifiedEvent);
+ const KeyEntry* keyEntry = static_cast<KeyEntry*>(eventEntry);
+ std::array<uint8_t, 32> hmac = getSignature(*keyEntry, *dispatchEntry);
// Publish the key event.
status =
@@ -2538,12 +2533,8 @@
usingCoords = scaledCoords;
}
}
- VerifiedMotionEvent verifiedEvent =
- verifiedMotionEventFromMotionEntry(*motionEntry);
- verifiedEvent.actionMasked =
- dispatchEntry->resolvedAction & AMOTION_EVENT_ACTION_MASK;
- verifiedEvent.flags = dispatchEntry->resolvedFlags & VERIFIED_MOTION_EVENT_FLAGS;
- std::array<uint8_t, 32> hmac = mHmacKeyManager.sign(verifiedEvent);
+
+ std::array<uint8_t, 32> hmac = getSignature(*motionEntry, *dispatchEntry);
// Publish the motion event.
status = connection->inputPublisher
@@ -2623,6 +2614,28 @@
}
}
+const std::array<uint8_t, 32> InputDispatcher::getSignature(
+ const MotionEntry& motionEntry, const DispatchEntry& dispatchEntry) const {
+ int32_t actionMasked = dispatchEntry.resolvedAction & AMOTION_EVENT_ACTION_MASK;
+ if ((actionMasked == AMOTION_EVENT_ACTION_UP) || (actionMasked == AMOTION_EVENT_ACTION_DOWN)) {
+ // Only sign events up and down events as the purely move events
+ // are tied to their up/down counterparts so signing would be redundant.
+ VerifiedMotionEvent verifiedEvent = verifiedMotionEventFromMotionEntry(motionEntry);
+ verifiedEvent.actionMasked = actionMasked;
+ verifiedEvent.flags = dispatchEntry.resolvedFlags & VERIFIED_MOTION_EVENT_FLAGS;
+ return mHmacKeyManager.sign(verifiedEvent);
+ }
+ return INVALID_HMAC;
+}
+
+const std::array<uint8_t, 32> InputDispatcher::getSignature(
+ const KeyEntry& keyEntry, const DispatchEntry& dispatchEntry) const {
+ VerifiedKeyEvent verifiedEvent = verifiedKeyEventFromKeyEntry(keyEntry);
+ verifiedEvent.flags = dispatchEntry.resolvedFlags & VERIFIED_KEY_EVENT_FLAGS;
+ verifiedEvent.action = dispatchEntry.resolvedAction;
+ return mHmacKeyManager.sign(verifiedEvent);
+}
+
void InputDispatcher::finishDispatchCycleLocked(nsecs_t currentTime,
const sp<Connection>& connection, uint32_t seq,
bool handled) {
@@ -3311,9 +3324,8 @@
KeyEntry* injectedEntry =
new KeyEntry(incomingKey.getId(), incomingKey.getEventTime(),
VIRTUAL_KEYBOARD_ID, incomingKey.getSource(),
- incomingKey.getDisplayId(), policyFlags, action, flags,
- incomingKey.getKeyCode(), incomingKey.getScanCode(),
- incomingKey.getMetaState(), incomingKey.getRepeatCount(),
+ incomingKey.getDisplayId(), policyFlags, action, flags, keyCode,
+ incomingKey.getScanCode(), metaState, incomingKey.getRepeatCount(),
incomingKey.getDownTime());
injectedEntries.push(injectedEntry);
break;
@@ -3629,8 +3641,8 @@
if (canReceiveInput && !noInputChannel) {
ALOGV("Window handle %s has no registered input channel",
handle->getName().c_str());
+ continue;
}
- continue;
}
if (info->displayId != displayId) {
diff --git a/services/inputflinger/dispatcher/InputDispatcher.h b/services/inputflinger/dispatcher/InputDispatcher.h
index cbba7e1..2b9cbce 100644
--- a/services/inputflinger/dispatcher/InputDispatcher.h
+++ b/services/inputflinger/dispatcher/InputDispatcher.h
@@ -62,7 +62,7 @@
std::array<uint8_t, 32> sign(const VerifiedInputEvent& event) const;
private:
- std::array<uint8_t, 32> sign(const std::vector<uint8_t>& data) const;
+ std::array<uint8_t, 32> sign(const uint8_t* data, size_t size) const;
const std::array<uint8_t, 128> mHmacKey;
};
@@ -219,7 +219,11 @@
// the pointer stream in order to claim it for a system gesture.
std::unordered_map<int32_t, std::vector<Monitor>> mGestureMonitorsByDisplay GUARDED_BY(mLock);
- HmacKeyManager mHmacKeyManager;
+ const HmacKeyManager mHmacKeyManager;
+ const std::array<uint8_t, 32> getSignature(const MotionEntry& motionEntry,
+ const DispatchEntry& dispatchEntry) const;
+ const std::array<uint8_t, 32> getSignature(const KeyEntry& keyEntry,
+ const DispatchEntry& dispatchEntry) const;
// Event injection and synchronization.
std::condition_variable mInjectionResultAvailable;
diff --git a/services/inputflinger/reader/mapper/MultiTouchInputMapper.cpp b/services/inputflinger/reader/mapper/MultiTouchInputMapper.cpp
index d77c8c8..43bd9f1 100644
--- a/services/inputflinger/reader/mapper/MultiTouchInputMapper.cpp
+++ b/services/inputflinger/reader/mapper/MultiTouchInputMapper.cpp
@@ -255,6 +255,7 @@
getDeviceName().c_str());
cancelTouch(when);
}
+ continue;
}
if (outCount >= MAX_POINTERS) {
diff --git a/services/inputflinger/tests/InputReader_test.cpp b/services/inputflinger/tests/InputReader_test.cpp
index 96d86b6..109edfe 100644
--- a/services/inputflinger/tests/InputReader_test.cpp
+++ b/services/inputflinger/tests/InputReader_test.cpp
@@ -1748,7 +1748,8 @@
virtual void SetUp() override {
mFakePolicy = new FakeInputReaderPolicy();
- mTestListener = new TestInputListener(50ms);
+ mTestListener = new TestInputListener(2000ms /*eventHappenedTimeout*/,
+ 30ms /*eventDidNotHappenTimeout*/);
mReader = new InputReader(std::make_shared<EventHub>(), mFakePolicy, mTestListener);
ASSERT_EQ(mReader->start(), OK);
@@ -7081,6 +7082,76 @@
ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
}
+/**
+ * Test multi-touch should be canceled when received the MT_TOOL_PALM event from some finger,
+ * and could be allowed again after all non-MT_TOOL_PALM is release and the new point is
+ * MT_TOOL_FINGER.
+ */
+TEST_F(MultiTouchInputMapperTest, Process_ShouldHandlePalmToolType2) {
+ addConfigurationProperty("touch.deviceType", "touchScreen");
+ prepareDisplay(DISPLAY_ORIENTATION_0);
+ prepareAxes(POSITION | ID | SLOT | TOOL_TYPE);
+ MultiTouchInputMapper& mapper = addMapperAndConfigure<MultiTouchInputMapper>();
+
+ NotifyMotionArgs motionArgs;
+
+ // default tool type is finger
+ constexpr int32_t x1 = 100, y1 = 200, x2 = 120, y2 = 220, x3 = 140, y3 = 240;
+ processId(mapper, 1);
+ processPosition(mapper, x1, y1);
+ processSync(mapper);
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+ ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
+ ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
+
+ // Second finger down.
+ processSlot(mapper, 1);
+ processPosition(mapper, x2, y2);
+ processId(mapper, 2);
+ processSync(mapper);
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+ ASSERT_EQ(AMOTION_EVENT_ACTION_POINTER_DOWN | (1 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT),
+ motionArgs.action);
+ ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
+
+ // If the tool type of the first pointer changes to MT_TOOL_PALM,
+ // the entire gesture should be aborted, so we expect to receive ACTION_CANCEL.
+ processSlot(mapper, 0);
+ processId(mapper, 1);
+ processToolType(mapper, MT_TOOL_PALM);
+ processSync(mapper);
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+ ASSERT_EQ(AMOTION_EVENT_ACTION_CANCEL, motionArgs.action);
+
+ // Ignore the following MOVE and UP events if had detect a palm event.
+ processSlot(mapper, 1);
+ processId(mapper, 2);
+ processPosition(mapper, x3, y3);
+ processSync(mapper);
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasNotCalled());
+
+ // second finger up.
+ processId(mapper, -1);
+ processSync(mapper);
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasNotCalled());
+
+ // first finger move, but still in palm
+ processSlot(mapper, 0);
+ processId(mapper, 1);
+ processPosition(mapper, x1 - 1, y1 - 1);
+ processSync(mapper);
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasNotCalled());
+
+ // second finger down, expect as new finger down.
+ processSlot(mapper, 1);
+ processId(mapper, 2);
+ processPosition(mapper, x2, y2);
+ processSync(mapper);
+ ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&motionArgs));
+ ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
+ ASSERT_EQ(AMOTION_EVENT_TOOL_TYPE_FINGER, motionArgs.pointerProperties[0].toolType);
+}
+
// --- MultiTouchInputMapperTest_ExternalDevice ---
class MultiTouchInputMapperTest_ExternalDevice : public MultiTouchInputMapperTest {
diff --git a/services/inputflinger/tests/TestInputListener.cpp b/services/inputflinger/tests/TestInputListener.cpp
index 86ff3b1..9bff166 100644
--- a/services/inputflinger/tests/TestInputListener.cpp
+++ b/services/inputflinger/tests/TestInputListener.cpp
@@ -23,7 +23,10 @@
// --- TestInputListener ---
-TestInputListener::TestInputListener(const std::chrono::milliseconds timeout) : mTimeout(timeout) {}
+TestInputListener::TestInputListener(std::chrono::milliseconds eventHappenedTimeout,
+ std::chrono::milliseconds eventDidNotHappenTimeout)
+ : mEventHappenedTimeout(eventHappenedTimeout),
+ mEventDidNotHappenTimeout(eventDidNotHappenTimeout) {}
TestInputListener::~TestInputListener() { }
@@ -86,9 +89,9 @@
std::vector<NotifyArgsType>& queue = std::get<std::vector<NotifyArgsType>>(mQueues);
if (queue.empty()) {
- const bool eventReceived = mCondition.wait_for(lock, mTimeout, [&queue]() REQUIRES(mLock) {
- return !queue.empty();
- });
+ const bool eventReceived =
+ mCondition.wait_for(lock, mEventHappenedTimeout,
+ [&queue]() REQUIRES(mLock) { return !queue.empty(); });
if (!eventReceived) {
FAIL() << "Timed out waiting for event: " << message.c_str();
}
@@ -105,9 +108,9 @@
base::ScopedLockAssertion assumeLocked(mLock);
std::vector<NotifyArgsType>& queue = std::get<std::vector<NotifyArgsType>>(mQueues);
- const bool eventReceived = mCondition.wait_for(lock, mTimeout, [&queue]() REQUIRES(mLock) {
- return !queue.empty();
- });
+ const bool eventReceived =
+ mCondition.wait_for(lock, mEventDidNotHappenTimeout,
+ [&queue]() REQUIRES(mLock) { return !queue.empty(); });
if (eventReceived) {
FAIL() << "Unexpected event: " << message.c_str();
}
diff --git a/services/inputflinger/tests/TestInputListener.h b/services/inputflinger/tests/TestInputListener.h
index 4262f5a..d50c6bc 100644
--- a/services/inputflinger/tests/TestInputListener.h
+++ b/services/inputflinger/tests/TestInputListener.h
@@ -32,7 +32,8 @@
virtual ~TestInputListener();
public:
- TestInputListener(const std::chrono::milliseconds timeout = 5ms);
+ TestInputListener(std::chrono::milliseconds eventHappenedTimeout = 0ms,
+ std::chrono::milliseconds eventDidNotHappenTimeout = 0ms);
void assertNotifyConfigurationChangedWasCalled(
NotifyConfigurationChangedArgs* outEventArgs = nullptr);
@@ -75,7 +76,8 @@
std::mutex mLock;
std::condition_variable mCondition;
- const std::chrono::milliseconds mTimeout;
+ const std::chrono::milliseconds mEventHappenedTimeout;
+ const std::chrono::milliseconds mEventDidNotHappenTimeout;
std::tuple<std::vector<NotifyConfigurationChangedArgs>, //
std::vector<NotifyDeviceResetArgs>, //
diff --git a/services/sensorservice/SensorDevice.cpp b/services/sensorservice/SensorDevice.cpp
index 3b68e0e..45e67f7 100644
--- a/services/sensorservice/SensorDevice.cpp
+++ b/services/sensorservice/SensorDevice.cpp
@@ -20,7 +20,6 @@
#include "android/hardware/sensors/2.1/ISensorsCallback.h"
#include "android/hardware/sensors/2.1/types.h"
#include "convertV2_1.h"
-#include "SensorService.h"
#include <android-base/logging.h>
#include <android/util/ProtoOutputStream.h>
@@ -30,6 +29,7 @@
#include <utils/Errors.h>
#include <utils/Singleton.h>
+#include <cstddef>
#include <chrono>
#include <cinttypes>
#include <thread>
@@ -143,6 +143,25 @@
for (size_t i=0 ; i < count; i++) {
sensor_t sensor;
convertToSensor(convertToOldSensorInfo(list[i]), &sensor);
+
+ if (sensor.type < static_cast<int>(SensorType::DEVICE_PRIVATE_BASE)) {
+ if(sensor.resolution == 0) {
+ // Don't crash here or the device will go into a crashloop.
+ ALOGW("%s must have a non-zero resolution", sensor.name);
+ // For simple algos, map their resolution to 1 if it's not specified
+ sensor.resolution =
+ SensorDeviceUtils::defaultResolutionForType(sensor.type);
+ }
+
+ double promotedResolution = sensor.resolution;
+ double promotedMaxRange = sensor.maxRange;
+ if (fmod(promotedMaxRange, promotedResolution) != 0) {
+ ALOGW("%s's max range %f is not a multiple of the resolution %f",
+ sensor.name, sensor.maxRange, sensor.resolution);
+ SensorDeviceUtils::quantizeValue(&sensor.maxRange, promotedResolution);
+ }
+ }
+
// Sanity check and clamp power if it is 0 (or close)
if (sensor.power < minPowerMa) {
ALOGI("Reported power %f not deemed sane, clamping to %f",
@@ -403,8 +422,8 @@
if (mSensors == nullptr) return "HAL not initialized\n";
String8 result;
- result.appendFormat("Total %zu h/w sensors, %zu running:\n",
- mSensorList.size(), mActivationCount.size());
+ result.appendFormat("Total %zu h/w sensors, %zu running %zu disabled clients:\n",
+ mSensorList.size(), mActivationCount.size(), mDisabledClients.size());
Mutex::Autolock _l(mLock);
for (const auto & s : mSensorList) {
@@ -417,16 +436,18 @@
result.append("sampling_period(ms) = {");
for (size_t j = 0; j < info.batchParams.size(); j++) {
const BatchParams& params = info.batchParams[j];
- result.appendFormat("%.1f%s", params.mTSample / 1e6f,
- j < info.batchParams.size() - 1 ? ", " : "");
+ result.appendFormat("%.1f%s%s", params.mTSample / 1e6f,
+ isClientDisabledLocked(info.batchParams.keyAt(j)) ? "(disabled)" : "",
+ (j < info.batchParams.size() - 1) ? ", " : "");
}
result.appendFormat("}, selected = %.2f ms; ", info.bestBatchParams.mTSample / 1e6f);
result.append("batching_period(ms) = {");
for (size_t j = 0; j < info.batchParams.size(); j++) {
const BatchParams& params = info.batchParams[j];
- result.appendFormat("%.1f%s", params.mTBatch / 1e6f,
- j < info.batchParams.size() - 1 ? ", " : "");
+ result.appendFormat("%.1f%s%s", params.mTBatch / 1e6f,
+ isClientDisabledLocked(info.batchParams.keyAt(j)) ? "(disabled)" : "",
+ (j < info.batchParams.size() - 1) ? ", " : "");
}
result.appendFormat("}, selected = %.2f ms\n", info.bestBatchParams.mTBatch / 1e6f);
}
@@ -508,7 +529,7 @@
const auto &events,
const auto &dynamicSensorsAdded) {
if (result == Result::OK) {
- convertToSensorEvents(convertToNewEvents(events),
+ convertToSensorEventsAndQuantize(convertToNewEvents(events),
convertToNewSensorInfos(dynamicSensorsAdded), buffer);
err = (ssize_t)events.size();
} else {
@@ -571,6 +592,8 @@
for (size_t i = 0; i < eventsToRead; i++) {
convertToSensorEvent(mEventBuffer[i], &buffer[i]);
+ android::SensorDeviceUtils::quantizeSensorEventValues(&buffer[i],
+ getResolutionForSensor(buffer[i].sensor));
}
eventsRead = eventsToRead;
} else {
@@ -641,7 +664,7 @@
}
status_t SensorDevice::activateLocked(void* ident, int handle, int enabled) {
- bool actuateHardware = false;
+ bool activateHardware = false;
status_t err(NO_ERROR);
@@ -667,7 +690,7 @@
if (info.batchParams.indexOfKey(ident) >= 0) {
if (info.numActiveClients() > 0 && !info.isActive) {
- actuateHardware = true;
+ activateHardware = true;
}
} else {
// Log error. Every activate call should be preceded by a batch() call.
@@ -687,7 +710,7 @@
if (info.removeBatchParamsForIdent(ident) >= 0) {
if (info.numActiveClients() == 0) {
// This is the last connection, we need to de-activate the underlying h/w sensor.
- actuateHardware = true;
+ activateHardware = true;
} else {
// Call batch for this sensor with the previously calculated best effort
// batch_rate and timeout. One of the apps has unregistered for sensor
@@ -707,12 +730,8 @@
}
}
- if (actuateHardware) {
- ALOGD_IF(DEBUG_CONNECTIONS, "\t>>> actuating h/w activate handle=%d enabled=%d", handle,
- enabled);
- err = checkReturnAndGetStatus(mSensors->activate(handle, enabled));
- ALOGE_IF(err, "Error %s sensor %d (%s)", enabled ? "activating" : "disabling", handle,
- strerror(-err));
+ if (activateHardware) {
+ err = doActivateHardwareLocked(handle, enabled);
if (err != NO_ERROR && enabled) {
// Failure when enabling the sensor. Clean up on failure.
@@ -728,6 +747,15 @@
return err;
}
+status_t SensorDevice::doActivateHardwareLocked(int handle, bool enabled) {
+ ALOGD_IF(DEBUG_CONNECTIONS, "\t>>> actuating h/w activate handle=%d enabled=%d", handle,
+ enabled);
+ status_t err = checkReturnAndGetStatus(mSensors->activate(handle, enabled));
+ ALOGE_IF(err, "Error %s sensor %d (%s)", enabled ? "activating" : "disabling", handle,
+ strerror(-err));
+ return err;
+}
+
status_t SensorDevice::batch(
void* ident,
int handle,
@@ -768,6 +796,18 @@
info.setBatchParamsForIdent(ident, flags, samplingPeriodNs, maxBatchReportLatencyNs);
}
+ status_t err = updateBatchParamsLocked(handle, info);
+ if (err != NO_ERROR) {
+ ALOGE("sensor batch failed %p 0x%08x %" PRId64 " %" PRId64 " err=%s",
+ mSensors.get(), handle, info.bestBatchParams.mTSample,
+ info.bestBatchParams.mTBatch, strerror(-err));
+ info.removeBatchParamsForIdent(ident);
+ }
+
+ return err;
+}
+
+status_t SensorDevice::updateBatchParamsLocked(int handle, Info &info) {
BatchParams prevBestBatchParams = info.bestBatchParams;
// Find the minimum of all timeouts and batch_rates for this sensor.
info.selectBatchParams();
@@ -785,13 +825,8 @@
info.bestBatchParams.mTSample, info.bestBatchParams.mTBatch);
err = checkReturnAndGetStatus(mSensors->batch(
handle, info.bestBatchParams.mTSample, info.bestBatchParams.mTBatch));
- if (err != NO_ERROR) {
- ALOGE("sensor batch failed %p 0x%08x %" PRId64 " %" PRId64 " err=%s",
- mSensors.get(), handle, info.bestBatchParams.mTSample,
- info.bestBatchParams.mTBatch, strerror(-err));
- info.removeBatchParamsForIdent(ident);
- }
}
+
return err;
}
@@ -811,13 +846,61 @@
return checkReturnAndGetStatus(mSensors->flush(handle));
}
-bool SensorDevice::isClientDisabled(void* ident) {
+bool SensorDevice::isClientDisabled(void* ident) const {
Mutex::Autolock _l(mLock);
return isClientDisabledLocked(ident);
}
-bool SensorDevice::isClientDisabledLocked(void* ident) {
- return mDisabledClients.indexOf(ident) >= 0;
+bool SensorDevice::isClientDisabledLocked(void* ident) const {
+ return mDisabledClients.count(ident) > 0;
+}
+
+std::vector<void *> SensorDevice::getDisabledClientsLocked() const {
+ std::vector<void *> vec;
+ for (const auto& it : mDisabledClients) {
+ vec.push_back(it.first);
+ }
+
+ return vec;
+}
+
+void SensorDevice::addDisabledReasonForIdentLocked(void* ident, DisabledReason reason) {
+ mDisabledClients[ident] |= 1 << reason;
+}
+
+void SensorDevice::removeDisabledReasonForIdentLocked(void* ident, DisabledReason reason) {
+ if (isClientDisabledLocked(ident)) {
+ mDisabledClients[ident] &= ~(1 << reason);
+ if (mDisabledClients[ident] == 0) {
+ mDisabledClients.erase(ident);
+ }
+ }
+}
+
+void SensorDevice::setUidStateForConnection(void* ident, SensorService::UidState state) {
+ Mutex::Autolock _l(mLock);
+ if (state == SensorService::UID_STATE_ACTIVE) {
+ removeDisabledReasonForIdentLocked(ident, DisabledReason::DISABLED_REASON_UID_IDLE);
+ } else {
+ addDisabledReasonForIdentLocked(ident, DisabledReason::DISABLED_REASON_UID_IDLE);
+ }
+
+ for (size_t i = 0; i< mActivationCount.size(); ++i) {
+ int handle = mActivationCount.keyAt(i);
+ Info& info = mActivationCount.editValueAt(i);
+
+ if (info.hasBatchParamsForIdent(ident)) {
+ if (updateBatchParamsLocked(handle, info) != NO_ERROR) {
+ bool enable = info.numActiveClients() == 0 && info.isActive;
+ bool disable = info.numActiveClients() > 0 && !info.isActive;
+
+ if ((enable || disable) &&
+ doActivateHardwareLocked(handle, enable) == NO_ERROR) {
+ info.isActive = enable;
+ }
+ }
+ }
+ }
}
bool SensorDevice::isSensorActive(int handle) const {
@@ -832,8 +915,12 @@
void SensorDevice::enableAllSensors() {
if (mSensors == nullptr) return;
Mutex::Autolock _l(mLock);
- mDisabledClients.clear();
- ALOGI("cleared mDisabledClients");
+
+ for (void *client : getDisabledClientsLocked()) {
+ removeDisabledReasonForIdentLocked(
+ client, DisabledReason::DISABLED_REASON_SERVICE_RESTRICTED);
+ }
+
for (size_t i = 0; i< mActivationCount.size(); ++i) {
Info& info = mActivationCount.editValueAt(i);
if (info.batchParams.isEmpty()) continue;
@@ -873,7 +960,8 @@
// Add all the connections that were registered for this sensor to the disabled
// clients list.
for (size_t j = 0; j < info.batchParams.size(); ++j) {
- mDisabledClients.add(info.batchParams.keyAt(j));
+ addDisabledReasonForIdentLocked(
+ info.batchParams.keyAt(j), DisabledReason::DISABLED_REASON_SERVICE_RESTRICTED);
ALOGI("added %p to mDisabledClients", info.batchParams.keyAt(j));
}
@@ -1048,7 +1136,7 @@
void SensorDevice::notifyConnectionDestroyed(void* ident) {
Mutex::Autolock _l(mLock);
- mDisabledClients.remove(ident);
+ mDisabledClients.erase(ident);
}
bool SensorDevice::isDirectReportSupported() const {
@@ -1077,7 +1165,7 @@
}
}
-void SensorDevice::convertToSensorEvents(
+void SensorDevice::convertToSensorEventsAndQuantize(
const hidl_vec<Event> &src,
const hidl_vec<SensorInfo> &dynamicSensorsAdded,
sensors_event_t *dst) {
@@ -1088,9 +1176,26 @@
for (size_t i = 0; i < src.size(); ++i) {
V2_1::implementation::convertToSensorEvent(src[i], &dst[i]);
+ android::SensorDeviceUtils::quantizeSensorEventValues(&dst[i],
+ getResolutionForSensor(dst[i].sensor));
}
}
+float SensorDevice::getResolutionForSensor(int sensorHandle) {
+ for (size_t i = 0; i < mSensorList.size(); i++) {
+ if (sensorHandle == mSensorList[i].handle) {
+ return mSensorList[i].resolution;
+ }
+ }
+
+ auto it = mConnectedDynamicSensors.find(sensorHandle);
+ if (it != mConnectedDynamicSensors.end()) {
+ return it->second->resolution;
+ }
+
+ return 0;
+}
+
void SensorDevice::handleHidlDeath(const std::string & detail) {
if (!mSensors->supportsMessageQueues()) {
// restart is the only option at present.
diff --git a/services/sensorservice/SensorDevice.h b/services/sensorservice/SensorDevice.h
index 24d03c6..5e7d3da 100644
--- a/services/sensorservice/SensorDevice.h
+++ b/services/sensorservice/SensorDevice.h
@@ -18,6 +18,7 @@
#define ANDROID_SENSOR_DEVICE_H
#include "SensorDeviceUtils.h"
+#include "SensorService.h"
#include "SensorServiceUtils.h"
#include "ISensorsWrapper.h"
@@ -116,6 +117,8 @@
hardware::Return<void> onDynamicSensorsDisconnected(
const hardware::hidl_vec<int32_t> &dynamicSensorHandlesRemoved);
+ void setUidStateForConnection(void* ident, SensorService::UidState state);
+
bool isReconnecting() const {
return mReconnecting;
}
@@ -179,6 +182,13 @@
// the removed ident. If index >=0, ident is present and successfully removed.
ssize_t removeBatchParamsForIdent(void* ident);
+ bool hasBatchParamsForIdent(void* ident) const {
+ return batchParams.indexOfKey(ident) >= 0;
+ }
+
+ /**
+ * @return The number of active clients of this sensor.
+ */
int numActiveClients() const;
};
DefaultKeyedVector<int, Info> mActivationCount;
@@ -187,8 +197,26 @@
SensorServiceUtil::RingBuffer<HidlTransportErrorLog> mHidlTransportErrors;
int mTotalHidlTransportErrors;
- // Use this vector to determine which client is activated or deactivated.
- SortedVector<void *> mDisabledClients;
+ /**
+ * Enums describing the reason why a client was disabled.
+ */
+ enum DisabledReason : uint8_t {
+ // UID becomes idle (e.g. app goes to background).
+ DISABLED_REASON_UID_IDLE = 0,
+
+ // Sensors are restricted for all clients.
+ DISABLED_REASON_SERVICE_RESTRICTED,
+ DISABLED_REASON_MAX,
+ };
+
+ static_assert(DisabledReason::DISABLED_REASON_MAX < sizeof(uint8_t) * CHAR_BIT);
+
+ // Use this map to determine which client is activated or deactivated.
+ std::unordered_map<void *, uint8_t> mDisabledClients;
+
+ void addDisabledReasonForIdentLocked(void* ident, DisabledReason reason);
+ void removeDisabledReasonForIdentLocked(void* ident, DisabledReason reason);
+
SensorDevice();
bool connectHidlService();
void initializeSensorList();
@@ -214,6 +242,9 @@
status_t batchLocked(void* ident, int handle, int flags, int64_t samplingPeriodNs,
int64_t maxBatchReportLatencyNs);
+ status_t updateBatchParamsLocked(int handle, Info& info);
+ status_t doActivateHardwareLocked(int handle, bool enable);
+
void handleHidlDeath(const std::string &detail);
template<typename T>
void checkReturn(const Return<T>& ret) {
@@ -225,19 +256,24 @@
//TODO(b/67425500): remove waiter after bug is resolved.
sp<SensorDeviceUtils::HidlServiceRegistrationWaiter> mRestartWaiter;
- bool isClientDisabled(void* ident);
- bool isClientDisabledLocked(void* ident);
+ bool isClientDisabled(void* ident) const;
+ bool isClientDisabledLocked(void* ident) const;
+ std::vector<void *> getDisabledClientsLocked() const;
+
+ bool clientHasNoAccessLocked(void* ident) const;
using Event = hardware::sensors::V2_1::Event;
using SensorInfo = hardware::sensors::V2_1::SensorInfo;
void convertToSensorEvent(const Event &src, sensors_event_t *dst);
- void convertToSensorEvents(
+ void convertToSensorEventsAndQuantize(
const hardware::hidl_vec<Event> &src,
const hardware::hidl_vec<SensorInfo> &dynamicSensorsAdded,
sensors_event_t *dst);
+ float getResolutionForSensor(int sensorHandle);
+
bool mIsDirectReportSupported;
typedef hardware::MessageQueue<uint32_t, hardware::kSynchronizedReadWrite> WakeLockQueue;
diff --git a/services/sensorservice/SensorDeviceUtils.cpp b/services/sensorservice/SensorDeviceUtils.cpp
index dbafffe..0dcf8c0 100644
--- a/services/sensorservice/SensorDeviceUtils.cpp
+++ b/services/sensorservice/SensorDeviceUtils.cpp
@@ -17,17 +17,101 @@
#include "SensorDeviceUtils.h"
#include <android/hardware/sensors/1.0/ISensors.h>
+#include <android/hardware/sensors/2.1/ISensors.h>
#include <utils/Log.h>
#include <chrono>
#include <thread>
using ::android::hardware::Void;
+using SensorTypeV2_1 = android::hardware::sensors::V2_1::SensorType;
using namespace android::hardware::sensors::V1_0;
namespace android {
namespace SensorDeviceUtils {
+void quantizeSensorEventValues(sensors_event_t *event, float resolution) {
+ LOG_FATAL_IF(resolution == 0, "Resolution must be specified for all sensors!");
+ if (resolution == 0) {
+ return;
+ }
+
+ size_t axes = 0;
+ switch ((SensorTypeV2_1)event->type) {
+ case SensorTypeV2_1::ACCELEROMETER:
+ case SensorTypeV2_1::MAGNETIC_FIELD:
+ case SensorTypeV2_1::ORIENTATION:
+ case SensorTypeV2_1::GYROSCOPE:
+ case SensorTypeV2_1::GRAVITY:
+ case SensorTypeV2_1::LINEAR_ACCELERATION:
+ case SensorTypeV2_1::MAGNETIC_FIELD_UNCALIBRATED:
+ case SensorTypeV2_1::GYROSCOPE_UNCALIBRATED:
+ case SensorTypeV2_1::ACCELEROMETER_UNCALIBRATED:
+ axes = 3;
+ break;
+ case SensorTypeV2_1::GAME_ROTATION_VECTOR:
+ axes = 4;
+ break;
+ case SensorTypeV2_1::ROTATION_VECTOR:
+ case SensorTypeV2_1::GEOMAGNETIC_ROTATION_VECTOR:
+ axes = 5;
+ break;
+ case SensorTypeV2_1::DEVICE_ORIENTATION:
+ case SensorTypeV2_1::LIGHT:
+ case SensorTypeV2_1::PRESSURE:
+ case SensorTypeV2_1::TEMPERATURE:
+ case SensorTypeV2_1::PROXIMITY:
+ case SensorTypeV2_1::RELATIVE_HUMIDITY:
+ case SensorTypeV2_1::AMBIENT_TEMPERATURE:
+ case SensorTypeV2_1::SIGNIFICANT_MOTION:
+ case SensorTypeV2_1::STEP_DETECTOR:
+ case SensorTypeV2_1::TILT_DETECTOR:
+ case SensorTypeV2_1::WAKE_GESTURE:
+ case SensorTypeV2_1::GLANCE_GESTURE:
+ case SensorTypeV2_1::PICK_UP_GESTURE:
+ case SensorTypeV2_1::WRIST_TILT_GESTURE:
+ case SensorTypeV2_1::STATIONARY_DETECT:
+ case SensorTypeV2_1::MOTION_DETECT:
+ case SensorTypeV2_1::HEART_BEAT:
+ case SensorTypeV2_1::LOW_LATENCY_OFFBODY_DETECT:
+ case SensorTypeV2_1::HINGE_ANGLE:
+ axes = 1;
+ break;
+ case SensorTypeV2_1::POSE_6DOF:
+ axes = 15;
+ break;
+ default:
+ // No other sensors have data that needs to be rounded.
+ break;
+ }
+
+ // sensor_event_t is a union so we're able to perform the same quanitization action for most
+ // sensors by only knowing the number of axes their output data has.
+ for (size_t i = 0; i < axes; i++) {
+ quantizeValue(&event->data[i], resolution);
+ }
+}
+
+float defaultResolutionForType(int type) {
+ switch ((SensorTypeV2_1)type) {
+ case SensorTypeV2_1::SIGNIFICANT_MOTION:
+ case SensorTypeV2_1::STEP_DETECTOR:
+ case SensorTypeV2_1::STEP_COUNTER:
+ case SensorTypeV2_1::TILT_DETECTOR:
+ case SensorTypeV2_1::WAKE_GESTURE:
+ case SensorTypeV2_1::GLANCE_GESTURE:
+ case SensorTypeV2_1::PICK_UP_GESTURE:
+ case SensorTypeV2_1::WRIST_TILT_GESTURE:
+ case SensorTypeV2_1::STATIONARY_DETECT:
+ case SensorTypeV2_1::MOTION_DETECT:
+ return 1.0f;
+ default:
+ // fall through and return 0 for all other types
+ break;
+ }
+ return 0.0f;
+}
+
HidlServiceRegistrationWaiter::HidlServiceRegistrationWaiter() {
}
diff --git a/services/sensorservice/SensorDeviceUtils.h b/services/sensorservice/SensorDeviceUtils.h
index e2eb606..d7e621c 100644
--- a/services/sensorservice/SensorDeviceUtils.h
+++ b/services/sensorservice/SensorDeviceUtils.h
@@ -18,7 +18,9 @@
#define ANDROID_SENSOR_DEVICE_UTIL
#include <android/hidl/manager/1.0/IServiceNotification.h>
+#include <hardware/sensors.h>
+#include <cmath>
#include <condition_variable>
#include <thread>
@@ -29,6 +31,21 @@
namespace android {
namespace SensorDeviceUtils {
+// Quantizes a single value using a sensor's resolution.
+inline void quantizeValue(float *value, double resolution) {
+ // Increase the value of the sensor's nominal resolution to ensure that
+ // sensor accuracy improvements, like runtime calibration, are not masked
+ // during requantization.
+ double incRes = 0.25 * resolution;
+ *value = round(static_cast<double>(*value) / incRes) * incRes;
+}
+
+// Ensures a sensor event doesn't provide values finer grained than its sensor resolution allows.
+void quantizeSensorEventValues(sensors_event_t *event, float resolution);
+
+// Provides a default resolution for simple sensor types if one wasn't provided by the HAL.
+float defaultResolutionForType(int type);
+
class HidlServiceRegistrationWaiter : public IServiceNotification {
public:
diff --git a/services/sensorservice/SensorDirectConnection.cpp b/services/sensorservice/SensorDirectConnection.cpp
index 106efd6..e4c33da 100644
--- a/services/sensorservice/SensorDirectConnection.cpp
+++ b/services/sensorservice/SensorDirectConnection.cpp
@@ -93,6 +93,18 @@
return nullptr;
}
+void SensorService::SensorDirectConnection::onSensorAccessChanged(bool hasAccess) {
+ if (!hasAccess) {
+ stopAll(true /* backupRecord */);
+ } else {
+ recoverAll();
+ }
+}
+
+bool SensorService::SensorDirectConnection::hasSensorAccess() const {
+ return mService->hasSensorAccess(mUid, mOpPackageName);
+}
+
status_t SensorService::SensorDirectConnection::enableDisable(
int handle, bool enabled, nsecs_t samplingPeriodNs, nsecs_t maxBatchReportLatencyNs,
int reservedFlags) {
@@ -125,7 +137,7 @@
return NO_ERROR;
}
- if (!mService->isOperationPermitted(mOpPackageName)) {
+ if (!hasSensorAccess()) {
return PERMISSION_DENIED;
}
@@ -169,12 +181,15 @@
}
void SensorService::SensorDirectConnection::stopAll(bool backupRecord) {
+ Mutex::Autolock _l(mConnectionLock);
+ stopAllLocked(backupRecord);
+}
+void SensorService::SensorDirectConnection::stopAllLocked(bool backupRecord) {
struct sensors_direct_cfg_t config = {
.rate_level = SENSOR_DIRECT_RATE_STOP
};
- Mutex::Autolock _l(mConnectionLock);
SensorDevice& dev(SensorDevice::getInstance());
for (auto &i : mActivated) {
dev.configureDirectChannel(i.first, getHalChannelHandle(), &config);
@@ -187,21 +202,25 @@
}
void SensorService::SensorDirectConnection::recoverAll() {
- stopAll(false);
-
Mutex::Autolock _l(mConnectionLock);
- SensorDevice& dev(SensorDevice::getInstance());
+ if (!mActivatedBackup.empty()) {
+ stopAllLocked(false);
- // recover list of report from backup
- mActivated = mActivatedBackup;
- mActivatedBackup.clear();
+ SensorDevice& dev(SensorDevice::getInstance());
- // re-enable them
- for (auto &i : mActivated) {
- struct sensors_direct_cfg_t config = {
- .rate_level = i.second
- };
- dev.configureDirectChannel(i.first, getHalChannelHandle(), &config);
+ // recover list of report from backup
+ ALOG_ASSERT(mActivated.empty(),
+ "mActivated must be empty if mActivatedBackup was non-empty");
+ mActivated = mActivatedBackup;
+ mActivatedBackup.clear();
+
+ // re-enable them
+ for (auto &i : mActivated) {
+ struct sensors_direct_cfg_t config = {
+ .rate_level = i.second
+ };
+ dev.configureDirectChannel(i.first, getHalChannelHandle(), &config);
+ }
}
}
diff --git a/services/sensorservice/SensorDirectConnection.h b/services/sensorservice/SensorDirectConnection.h
index ead08d3..4181b65 100644
--- a/services/sensorservice/SensorDirectConnection.h
+++ b/services/sensorservice/SensorDirectConnection.h
@@ -42,17 +42,14 @@
void dump(String8& result) const;
void dump(util::ProtoOutputStream* proto) const;
uid_t getUid() const { return mUid; }
+ const String16& getOpPackageName() const { return mOpPackageName; }
int32_t getHalChannelHandle() const;
bool isEquivalent(const sensors_direct_mem_t *mem) const;
- // stop all active sensor report. if backupRecord is set to false,
- // those report can be recovered by recoverAll
- // called by SensorService when enter restricted mode
- void stopAll(bool backupRecord = false);
-
- // recover sensor reports previously stopped by stopAll(true)
- // called by SensorService when return to NORMAL mode.
- void recoverAll();
+ // Invoked when access to sensors for this connection has changed, e.g. lost or
+ // regained due to changes in the sensor restricted/privacy mode or the
+ // app changed to idle/active status.
+ void onSensorAccessChanged(bool hasAccess);
protected:
virtual ~SensorDirectConnection();
@@ -66,6 +63,25 @@
virtual int32_t configureChannel(int handle, int rateLevel);
virtual void destroy();
private:
+ bool hasSensorAccess() const;
+
+ // Stops all active sensor direct report requests.
+ //
+ // If backupRecord is true, stopped requests can be recovered
+ // by a subsequent recoverAll() call (e.g. when temporarily stopping
+ // sensors for sensor privacy/restrict mode or when an app becomes
+ // idle).
+ void stopAll(bool backupRecord = false);
+ // Same as stopAll() but with mConnectionLock held.
+ void stopAllLocked(bool backupRecord);
+
+ // Recover sensor requests previously stopped by stopAll(true).
+ // This method can be called when a sensor access resumes (e.g.
+ // sensor privacy/restrict mode lifted or app becomes active).
+ //
+ // If no requests are backed up by stopAll(), this method is no-op.
+ void recoverAll();
+
const sp<SensorService> mService;
const uid_t mUid;
const sensors_direct_mem_t mMem;
diff --git a/services/sensorservice/SensorEventConnection.cpp b/services/sensorservice/SensorEventConnection.cpp
index e799372..ccf05d9 100644
--- a/services/sensorservice/SensorEventConnection.cpp
+++ b/services/sensorservice/SensorEventConnection.cpp
@@ -31,12 +31,11 @@
SensorService::SensorEventConnection::SensorEventConnection(
const sp<SensorService>& service, uid_t uid, String8 packageName, bool isDataInjectionMode,
- const String16& opPackageName, bool hasSensorAccess)
+ const String16& opPackageName)
: mService(service), mUid(uid), mWakeLockRefCount(0), mHasLooperCallbacks(false),
mDead(false), mDataInjectionMode(isDataInjectionMode), mEventCache(nullptr),
mCacheSize(0), mMaxCacheSize(0), mTimeOfLastEventDrop(0), mEventsDropped(0),
- mPackageName(packageName), mOpPackageName(opPackageName), mDestroyed(false),
- mHasSensorAccess(hasSensorAccess) {
+ mPackageName(packageName), mOpPackageName(opPackageName), mDestroyed(false) {
mChannel = new BitTube(mService->mSocketBufferSize);
#if DEBUG_CONNECTIONS
mEventsReceived = mEventsSentFromCache = mEventsSent = 0;
@@ -431,13 +430,9 @@
return size < 0 ? status_t(size) : status_t(NO_ERROR);
}
-void SensorService::SensorEventConnection::setSensorAccess(const bool hasAccess) {
- Mutex::Autolock _l(mConnectionLock);
- mHasSensorAccess = hasAccess;
-}
-
bool SensorService::SensorEventConnection::hasSensorAccess() {
- return mHasSensorAccess && !mService->mSensorPrivacyPolicy->isSensorPrivacyEnabled();
+ return mService->isUidActive(mUid)
+ && !mService->mSensorPrivacyPolicy->isSensorPrivacyEnabled();
}
bool SensorService::SensorEventConnection::noteOpIfRequired(const sensors_event_t& event) {
diff --git a/services/sensorservice/SensorEventConnection.h b/services/sensorservice/SensorEventConnection.h
index 1ca35c0..13cee6f 100644
--- a/services/sensorservice/SensorEventConnection.h
+++ b/services/sensorservice/SensorEventConnection.h
@@ -49,8 +49,7 @@
public:
SensorEventConnection(const sp<SensorService>& service, uid_t uid, String8 packageName,
- bool isDataInjectionMode, const String16& opPackageName,
- bool hasSensorAccess);
+ bool isDataInjectionMode, const String16& opPackageName);
status_t sendEvents(sensors_event_t const* buffer, size_t count, sensors_event_t* scratch,
wp<const SensorEventConnection> const * mapFlushEventsToConnections = nullptr);
@@ -69,8 +68,6 @@
uid_t getUid() const { return mUid; }
- void setSensorAccess(const bool hasAccess);
-
private:
virtual ~SensorEventConnection();
virtual void onFirstRef();
@@ -185,7 +182,6 @@
mutable Mutex mDestroyLock;
bool mDestroyed;
- bool mHasSensorAccess;
// Store a mapping of sensor handles to required AppOp for a sensor. This map only contains a
// valid mapping for sensors that require a permission in order to reduce the lookup time.
diff --git a/services/sensorservice/SensorService.cpp b/services/sensorservice/SensorService.cpp
index 5fdc74f..ffcd0a0 100644
--- a/services/sensorservice/SensorService.cpp
+++ b/services/sensorservice/SensorService.cpp
@@ -299,13 +299,33 @@
}
}
-void SensorService::setSensorAccess(uid_t uid, bool hasAccess) {
+void SensorService::onUidStateChanged(uid_t uid, UidState state) {
+ SensorDevice& dev(SensorDevice::getInstance());
+
ConnectionSafeAutolock connLock = mConnectionHolder.lock(mLock);
for (const sp<SensorEventConnection>& conn : connLock.getActiveConnections()) {
if (conn->getUid() == uid) {
- conn->setSensorAccess(hasAccess);
+ dev.setUidStateForConnection(conn.get(), state);
}
}
+
+ for (const sp<SensorDirectConnection>& conn : connLock.getDirectConnections()) {
+ if (conn->getUid() == uid) {
+ // Update sensor subscriptions if needed
+ bool hasAccess = hasSensorAccessLocked(conn->getUid(), conn->getOpPackageName());
+ conn->onSensorAccessChanged(hasAccess);
+ }
+ }
+}
+
+bool SensorService::hasSensorAccess(uid_t uid, const String16& opPackageName) {
+ Mutex::Autolock _l(mLock);
+ return hasSensorAccessLocked(uid, opPackageName);
+}
+
+bool SensorService::hasSensorAccessLocked(uid_t uid, const String16& opPackageName) {
+ return !mSensorPrivacyPolicy->isSensorPrivacyEnabled()
+ && isUidActive(uid) && !isOperationRestrictedLocked(opPackageName);
}
const Sensor& SensorService::registerSensor(SensorInterface* s, bool isDebug, bool isVirtual) {
@@ -638,8 +658,9 @@
void SensorService::disableAllSensorsLocked(ConnectionSafeAutolock* connLock) {
SensorDevice& dev(SensorDevice::getInstance());
- for (const sp<SensorDirectConnection>& connection : connLock->getDirectConnections()) {
- connection->stopAll(true /* backupRecord */);
+ for (const sp<SensorDirectConnection>& conn : connLock->getDirectConnections()) {
+ bool hasAccess = hasSensorAccessLocked(conn->getUid(), conn->getOpPackageName());
+ conn->onSensorAccessChanged(hasAccess);
}
dev.disableAllSensors();
// Clear all pending flush connections for all active sensors. If one of the active
@@ -666,8 +687,9 @@
}
SensorDevice& dev(SensorDevice::getInstance());
dev.enableAllSensors();
- for (const sp<SensorDirectConnection>& connection : connLock->getDirectConnections()) {
- connection->recoverAll();
+ for (const sp<SensorDirectConnection>& conn : connLock->getDirectConnections()) {
+ bool hasAccess = hasSensorAccessLocked(conn->getUid(), conn->getOpPackageName());
+ conn->onSensorAccessChanged(hasAccess);
}
}
@@ -1234,9 +1256,8 @@
(packageName == "") ? String8::format("unknown_package_pid_%d", pid) : packageName;
String16 connOpPackageName =
(opPackageName == String16("")) ? String16(connPackageName) : opPackageName;
- bool hasSensorAccess = mUidPolicy->isUidActive(uid);
sp<SensorEventConnection> result(new SensorEventConnection(this, uid, connPackageName,
- requestedMode == DATA_INJECTION, connOpPackageName, hasSensorAccess));
+ requestedMode == DATA_INJECTION, connOpPackageName));
if (requestedMode == DATA_INJECTION) {
mConnectionHolder.addEventConnectionIfNotPresent(result);
// Add the associated file descriptor to the Looper for polling whenever there is data to
@@ -1887,13 +1908,12 @@
return (packageName.contains(mWhiteListedPackage.string()));
}
-bool SensorService::isOperationPermitted(const String16& opPackageName) {
- Mutex::Autolock _l(mLock);
+bool SensorService::isOperationRestrictedLocked(const String16& opPackageName) {
if (mCurrentOperatingMode == RESTRICTED) {
String8 package(opPackageName);
- return isWhiteListedPackage(package);
+ return !isWhiteListedPackage(package);
}
- return true;
+ return false;
}
void SensorService::UidPolicy::registerSelf() {
@@ -1921,7 +1941,7 @@
}
sp<SensorService> service = mService.promote();
if (service != nullptr) {
- service->setSensorAccess(uid, true);
+ service->onUidStateChanged(uid, UID_STATE_ACTIVE);
}
}
@@ -1936,7 +1956,7 @@
if (deleted) {
sp<SensorService> service = mService.promote();
if (service != nullptr) {
- service->setSensorAccess(uid, false);
+ service->onUidStateChanged(uid, UID_STATE_IDLE);
}
}
}
@@ -1964,7 +1984,7 @@
if (wasActive != isActive) {
sp<SensorService> service = mService.promote();
if (service != nullptr) {
- service->setSensorAccess(uid, isActive);
+ service->onUidStateChanged(uid, isActive ? UID_STATE_ACTIVE : UID_STATE_IDLE);
}
}
}
@@ -1990,6 +2010,10 @@
return mActiveUids.find(uid) != mActiveUids.end();
}
+bool SensorService::isUidActive(uid_t uid) {
+ return mUidPolicy->isUidActive(uid);
+}
+
void SensorService::SensorPrivacyPolicy::registerSelf() {
SensorPrivacyManager spm;
mSensorPrivacyEnabled = spm.isSensorPrivacyEnabled();
diff --git a/services/sensorservice/SensorService.h b/services/sensorservice/SensorService.h
index 7d17dda..3bb8421 100644
--- a/services/sensorservice/SensorService.h
+++ b/services/sensorservice/SensorService.h
@@ -75,6 +75,11 @@
class SensorDirectConnection;
public:
+ enum UidState {
+ UID_STATE_ACTIVE = 0,
+ UID_STATE_IDLE,
+ };
+
void cleanupConnection(SensorEventConnection* connection);
void cleanupConnection(SensorDirectConnection* c);
@@ -194,6 +199,8 @@
std::unordered_map<uid_t, bool> mOverrideUids;
};
+ bool isUidActive(uid_t uid);
+
// Sensor privacy allows a user to disable access to all sensors on the device. When
// enabled sensor privacy will prevent all apps, including active apps, from accessing
// sensors, they will not receive trigger nor on-change events, flush event behavior
@@ -332,7 +339,11 @@
// allowed to register for or call flush on sensors. Typically only cts test packages are
// allowed.
bool isWhiteListedPackage(const String8& packageName);
- bool isOperationPermitted(const String16& opPackageName);
+
+ // Returns true if a connection with the specified opPackageName has no access to sensors
+ // in the RESTRICTED mode (i.e. the service is in RESTRICTED mode, and the package is not
+ // whitelisted). mLock must be held to invoke this method.
+ bool isOperationRestrictedLocked(const String16& opPackageName);
// Reset the state of SensorService to NORMAL mode.
status_t resetToNormalMode();
@@ -349,7 +360,13 @@
void enableSchedFifoMode();
// Sets whether the given UID can get sensor data
- void setSensorAccess(uid_t uid, bool hasAccess);
+ void onUidStateChanged(uid_t uid, UidState state);
+
+ // Returns true if a connection with the given uid and opPackageName
+ // currently has access to sensors.
+ bool hasSensorAccess(uid_t uid, const String16& opPackageName);
+ // Same as hasSensorAccess but with mLock held.
+ bool hasSensorAccessLocked(uid_t uid, const String16& opPackageName);
// Overrides the UID state as if it is idle
status_t handleSetUidState(Vector<String16>& args, int err);
diff --git a/services/surfaceflinger/Android.bp b/services/surfaceflinger/Android.bp
index c6f1f7e..0182937 100644
--- a/services/surfaceflinger/Android.bp
+++ b/services/surfaceflinger/Android.bp
@@ -44,7 +44,6 @@
"libGLESv1_CM",
"libGLESv2",
"libgui",
- "libhardware",
"libhidlbase",
"liblayers_proto",
"liblog",
@@ -287,6 +286,7 @@
export_shared_lib_headers: [
"android.hardware.graphics.common@1.2",
"libhidlbase",
+ "libui",
],
export_static_lib_headers: [
"SurfaceFlingerProperties",
diff --git a/services/surfaceflinger/Barrier.h b/services/surfaceflinger/Barrier.h
deleted file mode 100644
index 97028a8..0000000
--- a/services/surfaceflinger/Barrier.h
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef ANDROID_BARRIER_H
-#define ANDROID_BARRIER_H
-
-#include <stdint.h>
-#include <condition_variable>
-#include <mutex>
-
-namespace android {
-
-class Barrier
-{
-public:
- // Release any threads waiting at the Barrier.
- // Provides release semantics: preceding loads and stores will be visible
- // to other threads before they wake up.
- void open() {
- std::lock_guard<std::mutex> lock(mMutex);
- mIsOpen = true;
- mCondition.notify_all();
- }
-
- // Reset the Barrier, so wait() will block until open() has been called.
- void close() {
- std::lock_guard<std::mutex> lock(mMutex);
- mIsOpen = false;
- }
-
- // Wait until the Barrier is OPEN.
- // Provides acquire semantics: no subsequent loads or stores will occur
- // until wait() returns.
- void wait() const {
- std::unique_lock<std::mutex> lock(mMutex);
- mCondition.wait(lock, [this]() NO_THREAD_SAFETY_ANALYSIS { return mIsOpen; });
- }
-private:
- mutable std::mutex mMutex;
- mutable std::condition_variable mCondition;
- int mIsOpen GUARDED_BY(mMutex){false};
-};
-
-}; // namespace android
-
-#endif // ANDROID_BARRIER_H
diff --git a/services/surfaceflinger/BufferLayer.cpp b/services/surfaceflinger/BufferLayer.cpp
index 54cd04f..5b28384 100644
--- a/services/surfaceflinger/BufferLayer.cpp
+++ b/services/surfaceflinger/BufferLayer.cpp
@@ -497,10 +497,6 @@
}
}
- if (recomputeVisibleRegions == true) {
- maybeDirtyInput();
- }
-
return true;
}
diff --git a/services/surfaceflinger/BufferLayerConsumer.cpp b/services/surfaceflinger/BufferLayerConsumer.cpp
index e50a909..648d129 100644
--- a/services/surfaceflinger/BufferLayerConsumer.cpp
+++ b/services/surfaceflinger/BufferLayerConsumer.cpp
@@ -407,8 +407,17 @@
}
Rect BufferLayerConsumer::getCurrentCropLocked() const {
+ uint32_t width = mDefaultWidth;
+ uint32_t height = mDefaultHeight;
+ // If the buffer comes with a rotated bit for 90 (or 270) degrees, switch width/height in order
+ // to scale and crop correctly.
+ if (mCurrentTransform & NATIVE_WINDOW_TRANSFORM_ROT_90) {
+ width = mDefaultHeight;
+ height = mDefaultWidth;
+ }
+
return (mCurrentScalingMode == NATIVE_WINDOW_SCALING_MODE_SCALE_CROP)
- ? GLConsumer::scaleDownCrop(mCurrentCrop, mDefaultWidth, mDefaultHeight)
+ ? GLConsumer::scaleDownCrop(mCurrentCrop, width, height)
: mCurrentCrop;
}
diff --git a/services/surfaceflinger/CompositionEngine/include/compositionengine/LayerFECompositionState.h b/services/surfaceflinger/CompositionEngine/include/compositionengine/LayerFECompositionState.h
index d8ce629..8a9763b 100644
--- a/services/surfaceflinger/CompositionEngine/include/compositionengine/LayerFECompositionState.h
+++ b/services/surfaceflinger/CompositionEngine/include/compositionengine/LayerFECompositionState.h
@@ -33,13 +33,15 @@
#include <ui/GraphicBuffer.h>
#include <ui/GraphicTypes.h>
-#include "DisplayHardware/ComposerHal.h"
+#include "DisplayHardware/Hal.h"
// TODO(b/129481165): remove the #pragma below and fix conversion issues
#pragma clang diagnostic pop // ignored "-Wconversion"
namespace android::compositionengine {
+namespace hal = android::hardware::graphics::composer::hal;
+
// More complex metadata for this layer
struct GenericLayerMetadataEntry {
// True if the metadata may affect the composed result.
@@ -108,7 +110,7 @@
Region transparentRegionHint;
// The blend mode for this layer
- Hwc2::IComposerClient::BlendMode blendMode{Hwc2::IComposerClient::BlendMode::INVALID};
+ hal::BlendMode blendMode{hal::BlendMode::INVALID};
// The bounds of the layer in layer local coordinates
FloatRect geomLayerBounds;
@@ -145,7 +147,7 @@
*/
// The type of composition for this layer
- Hwc2::IComposerClient::Composition compositionType{Hwc2::IComposerClient::Composition::INVALID};
+ hal::Composition compositionType{hal::Composition::INVALID};
// The buffer and related state
sp<GraphicBuffer> buffer;
diff --git a/services/surfaceflinger/CompositionEngine/include/compositionengine/Output.h b/services/surfaceflinger/CompositionEngine/include/compositionengine/Output.h
index a5711a3..baf5258 100644
--- a/services/surfaceflinger/CompositionEngine/include/compositionengine/Output.h
+++ b/services/surfaceflinger/CompositionEngine/include/compositionengine/Output.h
@@ -34,11 +34,13 @@
#include "DisplayHardware/DisplayIdentification.h"
+namespace android {
+
namespace HWC2 {
class Layer;
} // namespace HWC2
-namespace android::compositionengine {
+namespace compositionengine {
class DisplayColorProfile;
class LayerFE;
@@ -280,4 +282,5 @@
virtual void cacheClientCompositionRequests(uint32_t cacheSize) = 0;
};
-} // namespace android::compositionengine
+} // namespace compositionengine
+} // namespace android
diff --git a/services/surfaceflinger/CompositionEngine/include/compositionengine/OutputLayer.h b/services/surfaceflinger/CompositionEngine/include/compositionengine/OutputLayer.h
index 007b0e8..cf77738 100644
--- a/services/surfaceflinger/CompositionEngine/include/compositionengine/OutputLayer.h
+++ b/services/surfaceflinger/CompositionEngine/include/compositionengine/OutputLayer.h
@@ -31,12 +31,12 @@
// TODO(b/129481165): remove the #pragma below and fix conversion issues
#pragma clang diagnostic pop // ignored "-Wconversion"
+namespace android {
+
namespace HWC2 {
class Layer;
} // namespace HWC2
-namespace android {
-
namespace compositionengine {
class CompositionEngine;
diff --git a/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/OutputLayerCompositionState.h b/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/OutputLayerCompositionState.h
index b0a9bc9..75394fa 100644
--- a/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/OutputLayerCompositionState.h
+++ b/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/OutputLayerCompositionState.h
@@ -36,12 +36,12 @@
// TODO(b/129481165): remove the #pragma below and fix conversion issues
#pragma clang diagnostic pop // ignored "-Wconversion"
+namespace android {
+
namespace HWC2 {
class Layer;
} // namespace HWC2
-namespace android {
-
class HWComposer;
namespace compositionengine::impl {
diff --git a/services/surfaceflinger/CompositionEngine/src/Display.cpp b/services/surfaceflinger/CompositionEngine/src/Display.cpp
index 308ec5a..ab26939 100644
--- a/services/surfaceflinger/CompositionEngine/src/Display.cpp
+++ b/services/surfaceflinger/CompositionEngine/src/Display.cpp
@@ -269,8 +269,8 @@
bool Display::getSkipColorTransform() const {
const auto& hwc = getCompositionEngine().getHwComposer();
- return mId ? hwc.hasDisplayCapability(*mId, HWC2::DisplayCapability::SkipClientColorTransform)
- : hwc.hasCapability(HWC2::Capability::SkipClientColorTransform);
+ return mId ? hwc.hasDisplayCapability(*mId, hal::DisplayCapability::SKIP_CLIENT_COLOR_TRANSFORM)
+ : hwc.hasCapability(hal::Capability::SKIP_CLIENT_COLOR_TRANSFORM);
}
bool Display::anyLayersRequireClientComposition() const {
@@ -306,7 +306,7 @@
void Display::applyDisplayRequests(const DisplayRequests& displayRequests) {
auto& state = editState();
state.flipClientTarget = (static_cast<uint32_t>(displayRequests) &
- static_cast<uint32_t>(HWC2::DisplayRequest::FlipClientTarget)) != 0;
+ static_cast<uint32_t>(hal::DisplayRequest::FLIP_CLIENT_TARGET)) != 0;
// Note: HWC2::DisplayRequest::WriteClientTargetToOutput is currently ignored.
}
diff --git a/services/surfaceflinger/CompositionEngine/src/OutputLayer.cpp b/services/surfaceflinger/CompositionEngine/src/OutputLayer.cpp
index 3aa7956..c9a070d 100644
--- a/services/surfaceflinger/CompositionEngine/src/OutputLayer.cpp
+++ b/services/surfaceflinger/CompositionEngine/src/OutputLayer.cpp
@@ -344,11 +344,11 @@
}
void OutputLayer::writeOutputDependentGeometryStateToHWC(
- HWC2::Layer* hwcLayer, Hwc2::IComposerClient::Composition requestedCompositionType) {
+ HWC2::Layer* hwcLayer, hal::Composition requestedCompositionType) {
const auto& outputDependentState = getState();
if (auto error = hwcLayer->setDisplayFrame(outputDependentState.displayFrame);
- error != HWC2::Error::None) {
+ error != hal::Error::NONE) {
ALOGE("[%s] Failed to set display frame [%d, %d, %d, %d]: %s (%d)",
getLayerFE().getDebugName(), outputDependentState.displayFrame.left,
outputDependentState.displayFrame.top, outputDependentState.displayFrame.right,
@@ -357,7 +357,7 @@
}
if (auto error = hwcLayer->setSourceCrop(outputDependentState.sourceCrop);
- error != HWC2::Error::None) {
+ error != hal::Error::NONE) {
ALOGE("[%s] Failed to set source crop [%.3f, %.3f, %.3f, %.3f]: "
"%s (%d)",
getLayerFE().getDebugName(), outputDependentState.sourceCrop.left,
@@ -366,18 +366,17 @@
static_cast<int32_t>(error));
}
- if (auto error = hwcLayer->setZOrder(outputDependentState.z); error != HWC2::Error::None) {
+ if (auto error = hwcLayer->setZOrder(outputDependentState.z); error != hal::Error::NONE) {
ALOGE("[%s] Failed to set Z %u: %s (%d)", getLayerFE().getDebugName(),
outputDependentState.z, to_string(error).c_str(), static_cast<int32_t>(error));
}
// Solid-color layers should always use an identity transform.
- const auto bufferTransform =
- requestedCompositionType != Hwc2::IComposerClient::Composition::SOLID_COLOR
+ const auto bufferTransform = requestedCompositionType != hal::Composition::SOLID_COLOR
? outputDependentState.bufferTransform
- : static_cast<Hwc2::Transform>(0);
- if (auto error = hwcLayer->setTransform(static_cast<HWC2::Transform>(bufferTransform));
- error != HWC2::Error::None) {
+ : static_cast<hal::Transform>(0);
+ if (auto error = hwcLayer->setTransform(static_cast<hal::Transform>(bufferTransform));
+ error != hal::Error::NONE) {
ALOGE("[%s] Failed to set transform %s: %s (%d)", getLayerFE().getDebugName(),
toString(outputDependentState.bufferTransform).c_str(), to_string(error).c_str(),
static_cast<int32_t>(error));
@@ -386,30 +385,29 @@
void OutputLayer::writeOutputIndependentGeometryStateToHWC(
HWC2::Layer* hwcLayer, const LayerFECompositionState& outputIndependentState) {
- if (auto error = hwcLayer->setBlendMode(
- static_cast<HWC2::BlendMode>(outputIndependentState.blendMode));
- error != HWC2::Error::None) {
+ if (auto error = hwcLayer->setBlendMode(outputIndependentState.blendMode);
+ error != hal::Error::NONE) {
ALOGE("[%s] Failed to set blend mode %s: %s (%d)", getLayerFE().getDebugName(),
toString(outputIndependentState.blendMode).c_str(), to_string(error).c_str(),
static_cast<int32_t>(error));
}
if (auto error = hwcLayer->setPlaneAlpha(outputIndependentState.alpha);
- error != HWC2::Error::None) {
+ error != hal::Error::NONE) {
ALOGE("[%s] Failed to set plane alpha %.3f: %s (%d)", getLayerFE().getDebugName(),
outputIndependentState.alpha, to_string(error).c_str(), static_cast<int32_t>(error));
}
if (auto error = hwcLayer->setInfo(static_cast<uint32_t>(outputIndependentState.type),
static_cast<uint32_t>(outputIndependentState.appId));
- error != HWC2::Error::None) {
+ error != hal::Error::NONE) {
ALOGE("[%s] Failed to set info %s (%d)", getLayerFE().getDebugName(),
to_string(error).c_str(), static_cast<int32_t>(error));
}
for (const auto& [name, entry] : outputIndependentState.metadata) {
if (auto error = hwcLayer->setLayerGenericMetadata(name, entry.mandatory, entry.value);
- error != HWC2::Error::None) {
+ error != hal::Error::NONE) {
ALOGE("[%s] Failed to set generic metadata %s %s (%d)", getLayerFE().getDebugName(),
name.c_str(), to_string(error).c_str(), static_cast<int32_t>(error));
}
@@ -422,14 +420,14 @@
// TODO(lpique): b/121291683 outputSpaceVisibleRegion is output-dependent geometry
// state and should not change every frame.
if (auto error = hwcLayer->setVisibleRegion(outputDependentState.outputSpaceVisibleRegion);
- error != HWC2::Error::None) {
+ error != hal::Error::NONE) {
ALOGE("[%s] Failed to set visible region: %s (%d)", getLayerFE().getDebugName(),
to_string(error).c_str(), static_cast<int32_t>(error));
outputDependentState.outputSpaceVisibleRegion.dump(LOG_TAG);
}
if (auto error = hwcLayer->setDataspace(outputDependentState.dataspace);
- error != HWC2::Error::None) {
+ error != hal::Error::NONE) {
ALOGE("[%s] Failed to set dataspace %d: %s (%d)", getLayerFE().getDebugName(),
outputDependentState.dataspace, to_string(error).c_str(),
static_cast<int32_t>(error));
@@ -439,9 +437,9 @@
void OutputLayer::writeOutputIndependentPerFrameStateToHWC(
HWC2::Layer* hwcLayer, const LayerFECompositionState& outputIndependentState) {
switch (auto error = hwcLayer->setColorTransform(outputIndependentState.colorTransform)) {
- case HWC2::Error::None:
+ case hal::Error::NONE:
break;
- case HWC2::Error::Unsupported:
+ case hal::Error::UNSUPPORTED:
editState().forceClientComposition = true;
break;
default:
@@ -450,7 +448,7 @@
}
if (auto error = hwcLayer->setSurfaceDamage(outputIndependentState.surfaceDamage);
- error != HWC2::Error::None) {
+ error != hal::Error::NONE) {
ALOGE("[%s] Failed to set surface damage: %s (%d)", getLayerFE().getDebugName(),
to_string(error).c_str(), static_cast<int32_t>(error));
outputIndependentState.surfaceDamage.dump(LOG_TAG);
@@ -458,18 +456,18 @@
// Content-specific per-frame state
switch (outputIndependentState.compositionType) {
- case Hwc2::IComposerClient::Composition::SOLID_COLOR:
+ case hal::Composition::SOLID_COLOR:
// For compatibility, should be written AFTER the composition type.
break;
- case Hwc2::IComposerClient::Composition::SIDEBAND:
+ case hal::Composition::SIDEBAND:
writeSidebandStateToHWC(hwcLayer, outputIndependentState);
break;
- case Hwc2::IComposerClient::Composition::CURSOR:
- case Hwc2::IComposerClient::Composition::DEVICE:
+ case hal::Composition::CURSOR:
+ case hal::Composition::DEVICE:
writeBufferStateToHWC(hwcLayer, outputIndependentState);
break;
- case Hwc2::IComposerClient::Composition::INVALID:
- case Hwc2::IComposerClient::Composition::CLIENT:
+ case hal::Composition::INVALID:
+ case hal::Composition::CLIENT:
// Ignored
break;
}
@@ -477,16 +475,16 @@
void OutputLayer::writeSolidColorStateToHWC(HWC2::Layer* hwcLayer,
const LayerFECompositionState& outputIndependentState) {
- if (outputIndependentState.compositionType != Hwc2::IComposerClient::Composition::SOLID_COLOR) {
+ if (outputIndependentState.compositionType != hal::Composition::SOLID_COLOR) {
return;
}
- hwc_color_t color = {static_cast<uint8_t>(std::round(255.0f * outputIndependentState.color.r)),
- static_cast<uint8_t>(std::round(255.0f * outputIndependentState.color.g)),
- static_cast<uint8_t>(std::round(255.0f * outputIndependentState.color.b)),
- 255};
+ hal::Color color = {static_cast<uint8_t>(std::round(255.0f * outputIndependentState.color.r)),
+ static_cast<uint8_t>(std::round(255.0f * outputIndependentState.color.g)),
+ static_cast<uint8_t>(std::round(255.0f * outputIndependentState.color.b)),
+ 255};
- if (auto error = hwcLayer->setColor(color); error != HWC2::Error::None) {
+ if (auto error = hwcLayer->setColor(color); error != hal::Error::NONE) {
ALOGE("[%s] Failed to set color: %s (%d)", getLayerFE().getDebugName(),
to_string(error).c_str(), static_cast<int32_t>(error));
}
@@ -495,7 +493,7 @@
void OutputLayer::writeSidebandStateToHWC(HWC2::Layer* hwcLayer,
const LayerFECompositionState& outputIndependentState) {
if (auto error = hwcLayer->setSidebandStream(outputIndependentState.sidebandStream->handle());
- error != HWC2::Error::None) {
+ error != hal::Error::NONE) {
ALOGE("[%s] Failed to set sideband stream %p: %s (%d)", getLayerFE().getDebugName(),
outputIndependentState.sidebandStream->handle(), to_string(error).c_str(),
static_cast<int32_t>(error));
@@ -508,7 +506,7 @@
getOutput().getDisplayColorProfile()->getSupportedPerFrameMetadata();
if (auto error = hwcLayer->setPerFrameMetadata(supportedPerFrameMetadata,
outputIndependentState.hdrMetadata);
- error != HWC2::Error::None && error != HWC2::Error::Unsupported) {
+ error != hal::Error::NONE && error != hal::Error::UNSUPPORTED) {
ALOGE("[%s] Failed to set hdrMetadata: %s (%d)", getLayerFE().getDebugName(),
to_string(error).c_str(), static_cast<int32_t>(error));
}
@@ -522,29 +520,28 @@
&hwcBuffer);
if (auto error = hwcLayer->setBuffer(hwcSlot, hwcBuffer, outputIndependentState.acquireFence);
- error != HWC2::Error::None) {
+ error != hal::Error::NONE) {
ALOGE("[%s] Failed to set buffer %p: %s (%d)", getLayerFE().getDebugName(),
outputIndependentState.buffer->handle, to_string(error).c_str(),
static_cast<int32_t>(error));
}
}
-void OutputLayer::writeCompositionTypeToHWC(
- HWC2::Layer* hwcLayer, Hwc2::IComposerClient::Composition requestedCompositionType) {
+void OutputLayer::writeCompositionTypeToHWC(HWC2::Layer* hwcLayer,
+ hal::Composition requestedCompositionType) {
auto& outputDependentState = editState();
// If we are forcing client composition, we need to tell the HWC
if (outputDependentState.forceClientComposition) {
- requestedCompositionType = Hwc2::IComposerClient::Composition::CLIENT;
+ requestedCompositionType = hal::Composition::CLIENT;
}
// Set the requested composition type with the HWC whenever it changes
if (outputDependentState.hwc->hwcCompositionType != requestedCompositionType) {
outputDependentState.hwc->hwcCompositionType = requestedCompositionType;
- if (auto error = hwcLayer->setCompositionType(
- static_cast<HWC2::Composition>(requestedCompositionType));
- error != HWC2::Error::None) {
+ if (auto error = hwcLayer->setCompositionType(requestedCompositionType);
+ error != hal::Error::NONE) {
ALOGE("[%s] Failed to set composition type %s: %s (%d)", getLayerFE().getDebugName(),
toString(requestedCompositionType).c_str(), to_string(error).c_str(),
static_cast<int32_t>(error));
@@ -571,7 +568,7 @@
Rect position = outputState.transform.transform(frame);
if (auto error = hwcLayer->setCursorPosition(position.left, position.top);
- error != HWC2::Error::None) {
+ error != hal::Error::NONE) {
ALOGE("[%s] Failed to set cursor position to (%d, %d): %s (%d)",
getLayerFE().getDebugName(), position.left, position.top, to_string(error).c_str(),
static_cast<int32_t>(error));
@@ -585,33 +582,31 @@
bool OutputLayer::requiresClientComposition() const {
const auto& state = getState();
- return !state.hwc ||
- state.hwc->hwcCompositionType == Hwc2::IComposerClient::Composition::CLIENT;
+ return !state.hwc || state.hwc->hwcCompositionType == hal::Composition::CLIENT;
}
bool OutputLayer::isHardwareCursor() const {
const auto& state = getState();
- return state.hwc && state.hwc->hwcCompositionType == Hwc2::IComposerClient::Composition::CURSOR;
+ return state.hwc && state.hwc->hwcCompositionType == hal::Composition::CURSOR;
}
-void OutputLayer::detectDisallowedCompositionTypeChange(
- Hwc2::IComposerClient::Composition from, Hwc2::IComposerClient::Composition to) const {
+void OutputLayer::detectDisallowedCompositionTypeChange(hal::Composition from,
+ hal::Composition to) const {
bool result = false;
switch (from) {
- case Hwc2::IComposerClient::Composition::INVALID:
- case Hwc2::IComposerClient::Composition::CLIENT:
+ case hal::Composition::INVALID:
+ case hal::Composition::CLIENT:
result = false;
break;
- case Hwc2::IComposerClient::Composition::DEVICE:
- case Hwc2::IComposerClient::Composition::SOLID_COLOR:
- result = (to == Hwc2::IComposerClient::Composition::CLIENT);
+ case hal::Composition::DEVICE:
+ case hal::Composition::SOLID_COLOR:
+ result = (to == hal::Composition::CLIENT);
break;
- case Hwc2::IComposerClient::Composition::CURSOR:
- case Hwc2::IComposerClient::Composition::SIDEBAND:
- result = (to == Hwc2::IComposerClient::Composition::CLIENT ||
- to == Hwc2::IComposerClient::Composition::DEVICE);
+ case hal::Composition::CURSOR:
+ case hal::Composition::SIDEBAND:
+ result = (to == hal::Composition::CLIENT || to == hal::Composition::DEVICE);
break;
}
@@ -622,8 +617,7 @@
}
}
-void OutputLayer::applyDeviceCompositionTypeChange(
- Hwc2::IComposerClient::Composition compositionType) {
+void OutputLayer::applyDeviceCompositionTypeChange(hal::Composition compositionType) {
auto& state = editState();
LOG_FATAL_IF(!state.hwc);
auto& hwcState = *state.hwc;
@@ -638,10 +632,10 @@
state.clearClientTarget = false;
}
-void OutputLayer::applyDeviceLayerRequest(Hwc2::IComposerClient::LayerRequest request) {
+void OutputLayer::applyDeviceLayerRequest(hal::LayerRequest request) {
auto& state = editState();
switch (request) {
- case Hwc2::IComposerClient::LayerRequest::CLEAR_CLIENT_TARGET:
+ case hal::LayerRequest::CLEAR_CLIENT_TARGET:
state.clearClientTarget = true;
break;
diff --git a/services/surfaceflinger/CompositionEngine/tests/DisplayTest.cpp b/services/surfaceflinger/CompositionEngine/tests/DisplayTest.cpp
index f73a6f7..59889b6 100644
--- a/services/surfaceflinger/CompositionEngine/tests/DisplayTest.cpp
+++ b/services/surfaceflinger/CompositionEngine/tests/DisplayTest.cpp
@@ -40,6 +40,8 @@
namespace android::compositionengine {
namespace {
+namespace hal = android::hardware::graphics::composer::hal;
+
using testing::_;
using testing::DoAll;
using testing::Eq;
@@ -645,9 +647,9 @@
TEST_F(DisplayChooseCompositionStrategyTest, normalOperationWithChanges) {
android::HWComposer::DeviceRequestedChanges changes{
- {{nullptr, HWC2::Composition::Client}},
- HWC2::DisplayRequest::FlipClientTarget,
- {{nullptr, HWC2::LayerRequest::ClearClientTarget}},
+ {{nullptr, hal::Composition::CLIENT}},
+ hal::DisplayRequest::FLIP_CLIENT_TARGET,
+ {{nullptr, hal::LayerRequest::CLEAR_CLIENT_TARGET}},
};
// Since two calls are made to anyLayersRequireClientComposition with different return
@@ -682,7 +684,7 @@
using DisplayGetSkipColorTransformTest = DisplayWithLayersTestCommon;
TEST_F(DisplayGetSkipColorTransformTest, checksCapabilityIfNonHwcDisplay) {
- EXPECT_CALL(mHwComposer, hasCapability(HWC2::Capability::SkipClientColorTransform))
+ EXPECT_CALL(mHwComposer, hasCapability(hal::Capability::SKIP_CLIENT_COLOR_TRANSFORM))
.WillOnce(Return(true));
auto args = getDisplayCreationArgsForNonHWCVirtualDisplay();
auto nonHwcDisplay{impl::createDisplay(mCompositionEngine, args)};
@@ -692,7 +694,7 @@
TEST_F(DisplayGetSkipColorTransformTest, checksDisplayCapability) {
EXPECT_CALL(mHwComposer,
hasDisplayCapability(DEFAULT_DISPLAY_ID,
- HWC2::DisplayCapability::SkipClientColorTransform))
+ hal::DisplayCapability::SKIP_CLIENT_COLOR_TRANSFORM))
.WillOnce(Return(true));
EXPECT_TRUE(mDisplay->getSkipColorTransform());
}
@@ -758,9 +760,9 @@
.Times(1);
mDisplay->applyChangedTypesToLayers(impl::Display::ChangedTypes{
- {&mLayer1.hwc2Layer, HWC2::Composition::Client},
- {&mLayer2.hwc2Layer, HWC2::Composition::Device},
- {&hwc2LayerUnknown, HWC2::Composition::SolidColor},
+ {&mLayer1.hwc2Layer, hal::Composition::CLIENT},
+ {&mLayer2.hwc2Layer, hal::Composition::DEVICE},
+ {&hwc2LayerUnknown, hal::Composition::SOLID_COLOR},
});
}
@@ -771,28 +773,28 @@
using DisplayApplyDisplayRequestsTest = DisplayWithLayersTestCommon;
TEST_F(DisplayApplyDisplayRequestsTest, handlesNoRequests) {
- mDisplay->applyDisplayRequests(static_cast<HWC2::DisplayRequest>(0));
+ mDisplay->applyDisplayRequests(static_cast<hal::DisplayRequest>(0));
auto& state = mDisplay->getState();
EXPECT_FALSE(state.flipClientTarget);
}
TEST_F(DisplayApplyDisplayRequestsTest, handlesFlipClientTarget) {
- mDisplay->applyDisplayRequests(HWC2::DisplayRequest::FlipClientTarget);
+ mDisplay->applyDisplayRequests(hal::DisplayRequest::FLIP_CLIENT_TARGET);
auto& state = mDisplay->getState();
EXPECT_TRUE(state.flipClientTarget);
}
TEST_F(DisplayApplyDisplayRequestsTest, handlesWriteClientTargetToOutput) {
- mDisplay->applyDisplayRequests(HWC2::DisplayRequest::WriteClientTargetToOutput);
+ mDisplay->applyDisplayRequests(hal::DisplayRequest::WRITE_CLIENT_TARGET_TO_OUTPUT);
auto& state = mDisplay->getState();
EXPECT_FALSE(state.flipClientTarget);
}
TEST_F(DisplayApplyDisplayRequestsTest, handlesAllRequestFlagsSet) {
- mDisplay->applyDisplayRequests(static_cast<HWC2::DisplayRequest>(~0));
+ mDisplay->applyDisplayRequests(static_cast<hal::DisplayRequest>(~0));
auto& state = mDisplay->getState();
EXPECT_TRUE(state.flipClientTarget);
@@ -822,8 +824,8 @@
.Times(1);
mDisplay->applyLayerRequestsToLayers(impl::Display::LayerRequests{
- {&mLayer1.hwc2Layer, HWC2::LayerRequest::ClearClientTarget},
- {&hwc2LayerUnknown, HWC2::LayerRequest::ClearClientTarget},
+ {&mLayer1.hwc2Layer, hal::LayerRequest::CLEAR_CLIENT_TARGET},
+ {&hwc2LayerUnknown, hal::LayerRequest::CLEAR_CLIENT_TARGET},
});
}
diff --git a/services/surfaceflinger/CompositionEngine/tests/MockHWC2.cpp b/services/surfaceflinger/CompositionEngine/tests/MockHWC2.cpp
index 8c10341..0baa79d 100644
--- a/services/surfaceflinger/CompositionEngine/tests/MockHWC2.cpp
+++ b/services/surfaceflinger/CompositionEngine/tests/MockHWC2.cpp
@@ -16,7 +16,7 @@
#include "MockHWC2.h"
-namespace HWC2 {
+namespace android::HWC2 {
// This will go away once HWC2::Layer is moved into the "backend" library
Layer::~Layer() = default;
@@ -29,4 +29,4 @@
Layer::~Layer() = default;
} // namespace mock
-} // namespace HWC2
+} // namespace android::HWC2
diff --git a/services/surfaceflinger/CompositionEngine/tests/MockHWC2.h b/services/surfaceflinger/CompositionEngine/tests/MockHWC2.h
index be89c1a..d21b97e 100644
--- a/services/surfaceflinger/CompositionEngine/tests/MockHWC2.h
+++ b/services/surfaceflinger/CompositionEngine/tests/MockHWC2.h
@@ -20,7 +20,6 @@
#include <ui/Fence.h>
#include <ui/FloatRect.h>
#include <ui/GraphicBuffer.h>
-
#include <ui/Rect.h>
#include <ui/Region.h>
#include <ui/Transform.h>
@@ -35,31 +34,36 @@
// TODO(b/129481165): remove the #pragma below and fix conversion issues
#pragma clang diagnostic pop // ignored "-Wconversion"
+namespace android {
namespace HWC2 {
namespace mock {
+namespace hal = android::hardware::graphics::composer::hal;
+
+using Error = hal::Error;
+
class Layer : public HWC2::Layer {
public:
Layer();
~Layer() override;
- MOCK_CONST_METHOD0(getId, hwc2_layer_t());
+ MOCK_CONST_METHOD0(getId, hal::HWLayerId());
MOCK_METHOD2(setCursorPosition, Error(int32_t, int32_t));
MOCK_METHOD3(setBuffer,
Error(uint32_t, const android::sp<android::GraphicBuffer>&,
const android::sp<android::Fence>&));
MOCK_METHOD1(setSurfaceDamage, Error(const android::Region&));
- MOCK_METHOD1(setBlendMode, Error(BlendMode));
- MOCK_METHOD1(setColor, Error(hwc_color_t));
- MOCK_METHOD1(setCompositionType, Error(Composition));
+ MOCK_METHOD1(setBlendMode, Error(hal::BlendMode));
+ MOCK_METHOD1(setColor, Error(hal::Color));
+ MOCK_METHOD1(setCompositionType, Error(hal::Composition));
MOCK_METHOD1(setDataspace, Error(android::ui::Dataspace));
MOCK_METHOD2(setPerFrameMetadata, Error(const int32_t, const android::HdrMetadata&));
MOCK_METHOD1(setDisplayFrame, Error(const android::Rect&));
MOCK_METHOD1(setPlaneAlpha, Error(float));
MOCK_METHOD1(setSidebandStream, Error(const native_handle_t*));
MOCK_METHOD1(setSourceCrop, Error(const android::FloatRect&));
- MOCK_METHOD1(setTransform, Error(Transform));
+ MOCK_METHOD1(setTransform, Error(hal::Transform));
MOCK_METHOD1(setVisibleRegion, Error(const android::Region&));
MOCK_METHOD1(setZOrder, Error(uint32_t));
MOCK_METHOD2(setInfo, Error(uint32_t, uint32_t));
@@ -71,3 +75,4 @@
} // namespace mock
} // namespace HWC2
+} // namespace android
diff --git a/services/surfaceflinger/CompositionEngine/tests/MockHWComposer.h b/services/surfaceflinger/CompositionEngine/tests/MockHWComposer.h
index 52bd6a1..27266b7 100644
--- a/services/surfaceflinger/CompositionEngine/tests/MockHWComposer.h
+++ b/services/surfaceflinger/CompositionEngine/tests/MockHWComposer.h
@@ -31,6 +31,8 @@
namespace android {
namespace mock {
+namespace hal = android::hardware::graphics::composer::hal;
+
class HWComposer : public android::HWComposer {
public:
HWComposer();
@@ -38,13 +40,13 @@
MOCK_METHOD2(setConfiguration, void(HWC2::ComposerCallback*, int32_t));
MOCK_CONST_METHOD3(getDisplayIdentificationData,
- bool(hwc2_display_t, uint8_t*, DisplayIdentificationData*));
- MOCK_CONST_METHOD1(hasCapability, bool(HWC2::Capability));
- MOCK_CONST_METHOD2(hasDisplayCapability, bool(DisplayId, HWC2::DisplayCapability));
+ bool(hal::HWDisplayId, uint8_t*, DisplayIdentificationData*));
+ MOCK_CONST_METHOD1(hasCapability, bool(hal::Capability));
+ MOCK_CONST_METHOD2(hasDisplayCapability, bool(DisplayId, hal::DisplayCapability));
MOCK_METHOD3(allocateVirtualDisplay,
std::optional<DisplayId>(uint32_t, uint32_t, ui::PixelFormat*));
- MOCK_METHOD2(allocatePhysicalDisplay, void(hwc2_display_t, DisplayId));
+ MOCK_METHOD2(allocatePhysicalDisplay, void(hal::HWDisplayId, DisplayId));
MOCK_METHOD1(createLayer, HWC2::Layer*(DisplayId));
MOCK_METHOD2(destroyLayer, void(DisplayId, HWC2::Layer*));
MOCK_METHOD3(getDeviceCompositionChanges,
@@ -54,7 +56,7 @@
status_t(DisplayId, uint32_t, const sp<Fence>&, const sp<GraphicBuffer>&,
ui::Dataspace));
MOCK_METHOD1(presentAndGetReleaseFences, status_t(DisplayId));
- MOCK_METHOD2(setPowerMode, status_t(DisplayId, int));
+ MOCK_METHOD2(setPowerMode, status_t(DisplayId, hal::PowerMode));
MOCK_METHOD2(setActiveConfig, status_t(DisplayId, size_t));
MOCK_METHOD2(setColorTransform, status_t(DisplayId, const mat4&));
MOCK_METHOD1(disconnectDisplay, void(DisplayId));
@@ -76,9 +78,9 @@
MOCK_METHOD2(getDisplayBrightnessSupport, status_t(DisplayId, bool*));
MOCK_METHOD2(onHotplug,
- std::optional<DisplayIdentificationInfo>(hwc2_display_t, HWC2::Connection));
- MOCK_METHOD2(onVsync, bool(hwc2_display_t, int64_t));
- MOCK_METHOD2(setVsyncEnabled, void(DisplayId, HWC2::Vsync));
+ std::optional<DisplayIdentificationInfo>(hal::HWDisplayId, hal::Connection));
+ MOCK_METHOD2(onVsync, bool(hal::HWDisplayId, int64_t));
+ MOCK_METHOD2(setVsyncEnabled, void(DisplayId, hal::Vsync));
MOCK_CONST_METHOD1(getRefreshTimestamp, nsecs_t(DisplayId));
MOCK_CONST_METHOD1(isConnected, bool(DisplayId));
MOCK_CONST_METHOD1(getConfigs,
@@ -92,21 +94,21 @@
MOCK_CONST_METHOD1(isVsyncPeriodSwitchSupported, bool(DisplayId));
MOCK_CONST_METHOD1(getDisplayVsyncPeriod, nsecs_t(DisplayId));
MOCK_METHOD4(setActiveConfigWithConstraints,
- status_t(DisplayId, size_t, const HWC2::VsyncPeriodChangeConstraints&,
- HWC2::VsyncPeriodChangeTimeline*));
+ status_t(DisplayId, size_t, const hal::VsyncPeriodChangeConstraints&,
+ hal::VsyncPeriodChangeTimeline*));
MOCK_METHOD2(setAutoLowLatencyMode, status_t(DisplayId, bool));
- MOCK_METHOD2(getSupportedContentTypes, status_t(DisplayId, std::vector<HWC2::ContentType>*));
- MOCK_METHOD2(setContentType, status_t(DisplayId, HWC2::ContentType));
+ MOCK_METHOD2(getSupportedContentTypes, status_t(DisplayId, std::vector<hal::ContentType>*));
+ MOCK_METHOD2(setContentType, status_t(DisplayId, hal::ContentType));
MOCK_CONST_METHOD0(getSupportedLayerGenericMetadata,
const std::unordered_map<std::string, bool>&());
MOCK_CONST_METHOD1(dump, void(std::string&));
MOCK_CONST_METHOD0(getComposer, android::Hwc2::Composer*());
- MOCK_CONST_METHOD1(getHwcDisplayId, std::optional<hwc2_display_t>(int32_t));
- MOCK_CONST_METHOD0(getInternalHwcDisplayId, std::optional<hwc2_display_t>());
- MOCK_CONST_METHOD0(getExternalHwcDisplayId, std::optional<hwc2_display_t>());
- MOCK_CONST_METHOD1(toPhysicalDisplayId, std::optional<DisplayId>(hwc2_display_t));
- MOCK_CONST_METHOD1(fromPhysicalDisplayId, std::optional<hwc2_display_t>(DisplayId));
+ MOCK_CONST_METHOD1(getHwcDisplayId, std::optional<hal::HWDisplayId>(int32_t));
+ MOCK_CONST_METHOD0(getInternalHwcDisplayId, std::optional<hal::HWDisplayId>());
+ MOCK_CONST_METHOD0(getExternalHwcDisplayId, std::optional<hal::HWDisplayId>());
+ MOCK_CONST_METHOD1(toPhysicalDisplayId, std::optional<DisplayId>(hal::HWDisplayId));
+ MOCK_CONST_METHOD1(fromPhysicalDisplayId, std::optional<hal::HWDisplayId>(DisplayId));
};
} // namespace mock
diff --git a/services/surfaceflinger/CompositionEngine/tests/OutputLayerTest.cpp b/services/surfaceflinger/CompositionEngine/tests/OutputLayerTest.cpp
index 1b5617c..bdacb22 100644
--- a/services/surfaceflinger/CompositionEngine/tests/OutputLayerTest.cpp
+++ b/services/surfaceflinger/CompositionEngine/tests/OutputLayerTest.cpp
@@ -29,6 +29,8 @@
namespace android::compositionengine {
namespace {
+namespace hal = android::hardware::graphics::composer::hal;
+
using testing::_;
using testing::InSequence;
using testing::Return;
@@ -613,7 +615,7 @@
*/
struct OutputLayerWriteStateToHWCTest : public OutputLayerTest {
- static constexpr HWC2::Error kError = HWC2::Error::Unsupported;
+ static constexpr hal::Error kError = hal::Error::UNSUPPORTED;
static constexpr FloatRect kSourceCrop{11.f, 12.f, 13.f, 14.f};
static constexpr uint32_t kZOrder = 21u;
static constexpr Hwc2::Transform kBufferTransform = static_cast<Hwc2::Transform>(31);
@@ -686,11 +688,9 @@
EXPECT_CALL(*mHwcLayer, setDisplayFrame(kDisplayFrame)).WillOnce(Return(kError));
EXPECT_CALL(*mHwcLayer, setSourceCrop(kSourceCrop)).WillOnce(Return(kError));
EXPECT_CALL(*mHwcLayer, setZOrder(kZOrder)).WillOnce(Return(kError));
- EXPECT_CALL(*mHwcLayer, setTransform(static_cast<HWC2::Transform>(kBufferTransform)))
- .WillOnce(Return(kError));
+ EXPECT_CALL(*mHwcLayer, setTransform(kBufferTransform)).WillOnce(Return(kError));
- EXPECT_CALL(*mHwcLayer, setBlendMode(static_cast<HWC2::BlendMode>(kBlendMode)))
- .WillOnce(Return(kError));
+ EXPECT_CALL(*mHwcLayer, setBlendMode(kBlendMode)).WillOnce(Return(kError));
EXPECT_CALL(*mHwcLayer, setPlaneAlpha(kAlpha)).WillOnce(Return(kError));
EXPECT_CALL(*mHwcLayer, setInfo(kType, kAppId)).WillOnce(Return(kError));
}
@@ -701,15 +701,14 @@
EXPECT_CALL(*mHwcLayer, setDataspace(kDataspace)).WillOnce(Return(kError));
EXPECT_CALL(*mHwcLayer, setColorTransform(kColorTransform))
.WillOnce(Return(unsupported == SimulateUnsupported::ColorTransform
- ? HWC2::Error::Unsupported
- : HWC2::Error::None));
+ ? hal::Error::UNSUPPORTED
+ : hal::Error::NONE));
EXPECT_CALL(*mHwcLayer, setSurfaceDamage(RegionEq(kSurfaceDamage)))
.WillOnce(Return(kError));
}
void expectSetCompositionTypeCall(Hwc2::IComposerClient::Composition compositionType) {
- EXPECT_CALL(*mHwcLayer, setCompositionType(static_cast<HWC2::Composition>(compositionType)))
- .WillOnce(Return(kError));
+ EXPECT_CALL(*mHwcLayer, setCompositionType(compositionType)).WillOnce(Return(kError));
}
void expectNoSetCompositionTypeCall() {
@@ -717,9 +716,9 @@
}
void expectSetColorCall() {
- hwc_color_t color = {static_cast<uint8_t>(std::round(kColor.r * 255)),
- static_cast<uint8_t>(std::round(kColor.g * 255)),
- static_cast<uint8_t>(std::round(kColor.b * 255)), 255};
+ const hal::Color color = {static_cast<uint8_t>(std::round(kColor.r * 255)),
+ static_cast<uint8_t>(std::round(kColor.g * 255)),
+ static_cast<uint8_t>(std::round(kColor.b * 255)), 255};
EXPECT_CALL(*mHwcLayer, setColor(ColorEq(color))).WillOnce(Return(kError));
}
@@ -924,7 +923,7 @@
struct OutputLayerWriteCursorPositionToHWCTest : public OutputLayerTest {
static constexpr int kDefaultTransform = TR_IDENT;
- static constexpr HWC2::Error kDefaultError = HWC2::Error::Unsupported;
+ static constexpr hal::Error kDefaultError = hal::Error::UNSUPPORTED;
static const Rect kDefaultDisplayViewport;
static const Rect kDefaultCursorFrame;
diff --git a/services/surfaceflinger/DisplayDevice.cpp b/services/surfaceflinger/DisplayDevice.cpp
index b81eb18..9af9cad 100644
--- a/services/surfaceflinger/DisplayDevice.cpp
+++ b/services/surfaceflinger/DisplayDevice.cpp
@@ -43,6 +43,8 @@
namespace android {
+namespace hal = hardware::graphics::composer::hal;
+
using android::base::StringAppendF;
ui::Transform::RotationFlags DisplayDevice::sPrimaryDisplayRotationFlags = ui::Transform::ROT_0;
@@ -119,17 +121,17 @@
}
// ----------------------------------------------------------------------------
-void DisplayDevice::setPowerMode(int mode) {
+void DisplayDevice::setPowerMode(hal::PowerMode mode) {
mPowerMode = mode;
- getCompositionDisplay()->setCompositionEnabled(mPowerMode != HWC_POWER_MODE_OFF);
+ getCompositionDisplay()->setCompositionEnabled(mPowerMode != hal::PowerMode::OFF);
}
-int DisplayDevice::getPowerMode() const {
+hal::PowerMode DisplayDevice::getPowerMode() const {
return mPowerMode;
}
bool DisplayDevice::isPoweredOn() const {
- return mPowerMode != HWC_POWER_MODE_OFF;
+ return mPowerMode != hal::PowerMode::OFF;
}
void DisplayDevice::setActiveConfig(HwcConfigIndexType mode) {
@@ -262,7 +264,8 @@
StringAppendF(&result, "+ %s\n", getDebugName().c_str());
result.append(" ");
- StringAppendF(&result, "powerMode=%d, ", mPowerMode);
+ StringAppendF(&result, "powerMode=%s (%d), ", to_string(mPowerMode).c_str(),
+ static_cast<int32_t>(mPowerMode));
StringAppendF(&result, "activeConfig=%d, ", mActiveConfig.value());
getCompositionDisplay()->dump(result);
}
diff --git a/services/surfaceflinger/DisplayDevice.h b/services/surfaceflinger/DisplayDevice.h
index e670d78..8c86153 100644
--- a/services/surfaceflinger/DisplayDevice.h
+++ b/services/surfaceflinger/DisplayDevice.h
@@ -24,7 +24,6 @@
#include <android/native_window.h>
#include <binder/IBinder.h>
#include <gui/LayerState.h>
-#include <hardware/hwcomposer_defs.h>
#include <math/mat4.h>
#include <renderengine/RenderEngine.h>
#include <system/window.h>
@@ -39,6 +38,7 @@
#include <utils/Timers.h>
#include "DisplayHardware/DisplayIdentification.h"
+#include "DisplayHardware/Hal.h"
#include "DisplayHardware/PowerAdvisor.h"
#include "RenderArea.h"
#include "Scheduler/HwcStrongTypes.h"
@@ -135,8 +135,8 @@
/* ------------------------------------------------------------------------
* Display power mode management.
*/
- int getPowerMode() const;
- void setPowerMode(int mode);
+ hardware::graphics::composer::hal::PowerMode getPowerMode() const;
+ void setPowerMode(hardware::graphics::composer::hal::PowerMode mode);
bool isPoweredOn() const;
ui::Dataspace getCompositionDataSpace() const;
@@ -172,7 +172,8 @@
static ui::Transform::RotationFlags sPrimaryDisplayRotationFlags;
- int mPowerMode = HWC_POWER_MODE_OFF;
+ hardware::graphics::composer::hal::PowerMode mPowerMode =
+ hardware::graphics::composer::hal::PowerMode::OFF;
HwcConfigIndexType mActiveConfig;
// TODO(b/74619554): Remove special cases for primary display.
@@ -183,7 +184,7 @@
struct Physical {
DisplayId id;
DisplayConnectionType type;
- hwc2_display_t hwcDisplayId;
+ hardware::graphics::composer::hal::HWDisplayId hwcDisplayId;
bool operator==(const Physical& other) const {
return id == other.id && type == other.type && hwcDisplayId == other.hwcDisplayId;
@@ -227,7 +228,8 @@
HdrCapabilities hdrCapabilities;
int32_t supportedPerFrameMetadata{0};
std::unordered_map<ui::ColorMode, std::vector<ui::RenderIntent>> hwcColorModes;
- int initialPowerMode{HWC_POWER_MODE_NORMAL};
+ hardware::graphics::composer::hal::PowerMode initialPowerMode{
+ hardware::graphics::composer::hal::PowerMode::ON};
bool isPrimary{false};
};
diff --git a/services/surfaceflinger/DisplayHardware/DisplayIdentification.h b/services/surfaceflinger/DisplayHardware/DisplayIdentification.h
index 9e6c549..4819d1d 100644
--- a/services/surfaceflinger/DisplayHardware/DisplayIdentification.h
+++ b/services/surfaceflinger/DisplayHardware/DisplayIdentification.h
@@ -26,6 +26,9 @@
#include <ui/DeviceProductInfo.h>
#include <ui/PhysicalDisplayId.h>
+#define LEGACY_DISPLAY_TYPE_PRIMARY 0
+#define LEGACY_DISPLAY_TYPE_EXTERNAL 1
+
namespace android {
struct DisplayId {
diff --git a/services/surfaceflinger/DisplayHardware/HWC2.cpp b/services/surfaceflinger/DisplayHardware/HWC2.cpp
index fc5d441..d6dbd57 100644
--- a/services/surfaceflinger/DisplayHardware/HWC2.cpp
+++ b/services/surfaceflinger/DisplayHardware/HWC2.cpp
@@ -38,6 +38,8 @@
#include <iterator>
#include <set>
+namespace android {
+
using android::Fence;
using android::FloatRect;
using android::GraphicBuffer;
@@ -49,11 +51,9 @@
namespace HWC2 {
+using namespace android::hardware::graphics::composer::hal;
+
namespace Hwc2 = android::Hwc2;
-using android::ui::ColorMode;
-using android::ui::Dataspace;
-using android::ui::PixelFormat;
-using android::ui::RenderIntent;
namespace {
@@ -67,7 +67,7 @@
// Display methods
Display::~Display() = default;
-Display::Config::Config(Display& display, hwc2_config_t id)
+Display::Config::Config(Display& display, HWConfigId id)
: mDisplay(display),
mId(id),
mWidth(-1),
@@ -76,7 +76,7 @@
mDpiX(-1),
mDpiY(-1) {}
-Display::Config::Builder::Builder(Display& display, hwc2_config_t id)
+Display::Config::Builder::Builder(Display& display, HWConfigId id)
: mConfig(new Config(display, id)) {}
float Display::Config::Builder::getDefaultDensity() {
@@ -97,37 +97,34 @@
namespace impl {
Display::Display(android::Hwc2::Composer& composer,
- const std::unordered_set<Capability>& capabilities, hwc2_display_t id,
+ const std::unordered_set<Capability>& capabilities, HWDisplayId id,
DisplayType type)
- : mComposer(composer),
- mCapabilities(capabilities),
- mId(id),
- mType(type) {
+ : mComposer(composer), mCapabilities(capabilities), mId(id), mType(type) {
ALOGV("Created display %" PRIu64, id);
}
Display::~Display() {
mLayers.clear();
- Error error = Error::None;
+ Error error = Error::NONE;
const char* msg;
switch (mType) {
- case DisplayType::Physical:
- error = setVsyncEnabled(HWC2::Vsync::Disable);
+ case DisplayType::PHYSICAL:
+ error = setVsyncEnabled(HWC2::Vsync::DISABLE);
msg = "disable VSYNC for";
break;
- case DisplayType::Virtual:
+ case DisplayType::VIRTUAL:
error = static_cast<Error>(mComposer.destroyVirtualDisplay(mId));
msg = "destroy virtual";
break;
- case DisplayType::Invalid: // Used in unit tests.
+ case DisplayType::INVALID: // Used in unit tests.
break;
}
- ALOGE_IF(error != Error::None, "%s: Failed to %s display %" PRIu64 ": %s (%d)", __FUNCTION__,
- msg, mId, to_string(error).c_str(), static_cast<int32_t>(error));
+ ALOGE_IF(error != Error::NONE, "%s: Failed to %s display %" PRIu64 ": %d", __FUNCTION__, msg,
+ mId, static_cast<int32_t>(error));
ALOGV("Destroyed display %" PRIu64, mId);
}
@@ -141,38 +138,38 @@
Error Display::createLayer(HWC2::Layer** outLayer) {
if (!outLayer) {
- return Error::BadParameter;
+ return Error::BAD_PARAMETER;
}
- hwc2_layer_t layerId = 0;
+ HWLayerId layerId = 0;
auto intError = mComposer.createLayer(mId, &layerId);
auto error = static_cast<Error>(intError);
- if (error != Error::None) {
+ if (error != Error::NONE) {
return error;
}
auto layer = std::make_unique<impl::Layer>(mComposer, mCapabilities, mId, layerId);
*outLayer = layer.get();
mLayers.emplace(layerId, std::move(layer));
- return Error::None;
+ return Error::NONE;
}
Error Display::destroyLayer(HWC2::Layer* layer) {
if (!layer) {
- return Error::BadParameter;
+ return Error::BAD_PARAMETER;
}
mLayers.erase(layer->getId());
- return Error::None;
+ return Error::NONE;
}
Error Display::getActiveConfig(
std::shared_ptr<const Display::Config>* outConfig) const
{
ALOGV("[%" PRIu64 "] getActiveConfig", mId);
- hwc2_config_t configId = 0;
+ HWConfigId configId = 0;
auto intError = mComposer.getActiveConfig(mId, &configId);
auto error = static_cast<Error>(intError);
- if (error != Error::None) {
+ if (error != Error::NONE) {
ALOGE("Unable to get active config for mId:[%" PRIu64 "]", mId);
*outConfig = nullptr;
return error;
@@ -188,7 +185,7 @@
*outConfig = nullptr;
}
- return Error::None;
+ return Error::NONE;
}
bool Display::isVsyncPeriodSwitchSupported() const {
@@ -209,10 +206,10 @@
*outVsyncPeriod = static_cast<nsecs_t>(vsyncPeriodNanos);
} else {
// Get the default vsync period
- hwc2_config_t configId = 0;
+ HWConfigId configId = 0;
auto intError_2_1 = mComposer.getActiveConfig(mId, &configId);
error = static_cast<Error>(intError_2_1);
- if (error == Error::None) {
+ if (error == Error::NONE) {
auto config = mConfigs.at(configId);
*outVsyncPeriod = config->getVsyncPeriod();
}
@@ -223,11 +220,11 @@
Error Display::getActiveConfigIndex(int* outIndex) const {
ALOGV("[%" PRIu64 "] getActiveConfigIndex", mId);
- hwc2_config_t configId = 0;
+ HWConfigId configId = 0;
auto intError = mComposer.getActiveConfig(mId, &configId);
auto error = static_cast<Error>(intError);
- if (error != Error::None) {
+ if (error != Error::NONE) {
ALOGE("Unable to get active config for mId:[%" PRIu64 "]", mId);
*outIndex = -1;
return error;
@@ -244,7 +241,7 @@
*outIndex = -1;
}
- return Error::None;
+ return Error::NONE;
}
Error Display::getChangedCompositionTypes(std::unordered_map<HWC2::Layer*, Composition>* outTypes) {
@@ -255,7 +252,7 @@
uint32_t numElements = layerIds.size();
auto error = static_cast<Error>(intError);
error = static_cast<Error>(intError);
- if (error != Error::None) {
+ if (error != Error::NONE) {
return error;
}
@@ -264,7 +261,7 @@
for (uint32_t element = 0; element < numElements; ++element) {
auto layer = getLayerById(layerIds[element]);
if (layer) {
- auto type = static_cast<Composition>(types[element]);
+ auto type = types[element];
ALOGV("getChangedCompositionTypes: adding %" PRIu64 " %s",
layer->getId(), to_string(type).c_str());
outTypes->emplace(layer, type);
@@ -274,7 +271,7 @@
}
}
- return Error::None;
+ return Error::NONE;
}
Error Display::getColorModes(std::vector<ColorMode>* outModes) const
@@ -357,7 +354,7 @@
mId, &intDisplayRequests, &layerIds, &layerRequests);
uint32_t numElements = layerIds.size();
auto error = static_cast<Error>(intError);
- if (error != Error::None) {
+ if (error != Error::NONE) {
return error;
}
@@ -376,28 +373,28 @@
}
}
- return Error::None;
+ return Error::NONE;
}
Error Display::getConnectionType(android::DisplayConnectionType* outType) const {
- if (mType != DisplayType::Physical) return Error::BadDisplay;
+ if (mType != DisplayType::PHYSICAL) return Error::BAD_DISPLAY;
using ConnectionType = Hwc2::IComposerClient::DisplayConnectionType;
ConnectionType connectionType;
const auto error = static_cast<Error>(mComposer.getDisplayConnectionType(mId, &connectionType));
- if (error != Error::None) {
+ if (error != Error::NONE) {
return error;
}
*outType = connectionType == ConnectionType::INTERNAL
? android::DisplayConnectionType::Internal
: android::DisplayConnectionType::External;
- return Error::None;
+ return Error::NONE;
}
Error Display::supportsDoze(bool* outSupport) const {
- *outSupport = mDisplayCapabilities.count(DisplayCapability::Doze) > 0;
- return Error::None;
+ *outSupport = mDisplayCapabilities.count(DisplayCapability::DOZE) > 0;
+ return Error::NONE;
}
Error Display::getHdrCapabilities(HdrCapabilities* outCapabilities) const
@@ -410,16 +407,16 @@
&maxLuminance, &maxAverageLuminance, &minLuminance);
auto error = static_cast<HWC2::Error>(intError);
- if (error != Error::None) {
+ if (error != Error::NONE) {
return error;
}
*outCapabilities = HdrCapabilities(std::move(types),
maxLuminance, maxAverageLuminance, minLuminance);
- return Error::None;
+ return Error::NONE;
}
-Error Display::getDisplayedContentSamplingAttributes(PixelFormat* outFormat,
+Error Display::getDisplayedContentSamplingAttributes(hal::PixelFormat* outFormat,
Dataspace* outDataspace,
uint8_t* outComponentMask) const {
auto intError = mComposer.getDisplayedContentSamplingAttributes(mId, outFormat, outDataspace,
@@ -446,7 +443,7 @@
auto intError = mComposer.getReleaseFences(mId, &layerIds, &fenceFds);
auto error = static_cast<Error>(intError);
uint32_t numElements = layerIds.size();
- if (error != Error::None) {
+ if (error != Error::NONE) {
return error;
}
@@ -463,12 +460,12 @@
for (; element < numElements; ++element) {
close(fenceFds[element]);
}
- return Error::BadLayer;
+ return Error::BAD_LAYER;
}
}
*outFences = std::move(releaseFences);
- return Error::None;
+ return Error::NONE;
}
Error Display::present(sp<Fence>* outPresentFence)
@@ -476,12 +473,12 @@
int32_t presentFenceFd = -1;
auto intError = mComposer.presentDisplay(mId, &presentFenceFd);
auto error = static_cast<Error>(intError);
- if (error != Error::None) {
+ if (error != Error::NONE) {
return error;
}
*outPresentFence = new Fence(presentFenceFd);
- return Error::None;
+ return Error::NONE;
}
Error Display::setActiveConfigWithConstraints(
@@ -492,7 +489,7 @@
ALOGE("setActiveConfigWithConstraints received config %u for the wrong display %" PRIu64
" (expected %" PRIu64 ")",
config->getId(), config->getDisplayId(), mId);
- return Error::BadConfig;
+ return Error::BAD_CONFIG;
}
if (isVsyncPeriodSwitchSupported()) {
@@ -530,7 +527,7 @@
ALOGE("setActiveConfig received config %u for the wrong display %"
PRIu64 " (expected %" PRIu64 ")", config->getId(),
config->getDisplayId(), mId);
- return Error::BadConfig;
+ return Error::BAD_CONFIG;
}
auto intError = mComposer.setActiveConfig(mId, config->getId());
return static_cast<Error>(intError);
@@ -552,11 +549,8 @@
return static_cast<Error>(intError);
}
-Error Display::setColorTransform(const android::mat4& matrix,
- android_color_transform_t hint)
-{
- auto intError = mComposer.setColorTransform(mId,
- matrix.asArray(), static_cast<Hwc2::ColorTransform>(hint));
+Error Display::setColorTransform(const android::mat4& matrix, ColorTransform hint) {
+ auto intError = mComposer.setColorTransform(mId, matrix.asArray(), hint);
return static_cast<Error>(intError);
}
@@ -575,23 +569,23 @@
auto intMode = static_cast<Hwc2::IComposerClient::PowerMode>(mode);
auto intError = mComposer.setPowerMode(mId, intMode);
- if (mode == PowerMode::On) {
+ if (mode == PowerMode::ON) {
std::call_once(mDisplayCapabilityQueryFlag, [this]() {
std::vector<Hwc2::DisplayCapability> tmpCapabilities;
auto error =
static_cast<Error>(mComposer.getDisplayCapabilities(mId, &tmpCapabilities));
- if (error == Error::None) {
+ if (error == Error::NONE) {
for (auto capability : tmpCapabilities) {
mDisplayCapabilities.emplace(static_cast<DisplayCapability>(capability));
}
- } else if (error == Error::Unsupported) {
- if (mCapabilities.count(Capability::SkipClientColorTransform)) {
- mDisplayCapabilities.emplace(DisplayCapability::SkipClientColorTransform);
+ } else if (error == Error::UNSUPPORTED) {
+ if (mCapabilities.count(Capability::SKIP_CLIENT_COLOR_TRANSFORM)) {
+ mDisplayCapabilities.emplace(DisplayCapability::SKIP_CLIENT_COLOR_TRANSFORM);
}
bool dozeSupport = false;
error = static_cast<Error>(mComposer.getDozeSupport(mId, &dozeSupport));
- if (error == Error::None && dozeSupport) {
- mDisplayCapabilities.emplace(DisplayCapability::Doze);
+ if (error == Error::NONE && dozeSupport) {
+ mDisplayCapabilities.emplace(DisplayCapability::DOZE);
}
}
});
@@ -613,7 +607,7 @@
uint32_t numRequests = 0;
auto intError = mComposer.validateDisplay(mId, &numTypes, &numRequests);
auto error = static_cast<Error>(intError);
- if (error != Error::None && error != Error::HasChanges) {
+ if (error != Error::NONE && !hasChangesError(error)) {
return error;
}
@@ -631,7 +625,7 @@
auto intError = mComposer.presentOrValidateDisplay(
mId, &numTypes, &numRequests, &presentFenceFd, state);
auto error = static_cast<Error>(intError);
- if (error != Error::None && error != Error::HasChanges) {
+ if (error != Error::NONE && !hasChangesError(error)) {
return error;
}
@@ -647,7 +641,7 @@
}
Error Display::setDisplayBrightness(float brightness) const {
- auto intError = mComposer.setDisplayBrightness(mId, brightness);
+ const auto intError = mComposer.setDisplayBrightness(mId, brightness);
return static_cast<Error>(intError);
}
@@ -666,8 +660,7 @@
}
Error Display::setContentType(ContentType contentType) const {
- using Hwc2_ContentType = Hwc2::IComposerClient::ContentType;
- auto intError = mComposer.setContentType(mId, static_cast<Hwc2_ContentType>(contentType));
+ auto intError = mComposer.setContentType(mId, contentType);
return static_cast<Error>(intError);
}
@@ -676,21 +669,18 @@
void Display::setConnected(bool connected) {
if (!mIsConnected && connected) {
mComposer.setClientTargetSlotCount(mId);
- if (mType == DisplayType::Physical) {
+ if (mType == DisplayType::PHYSICAL) {
loadConfigs();
}
}
mIsConnected = connected;
}
-int32_t Display::getAttribute(hwc2_config_t configId, Attribute attribute)
-{
+int32_t Display::getAttribute(HWConfigId configId, Attribute attribute) {
int32_t value = 0;
- auto intError = mComposer.getDisplayAttribute(mId, configId,
- static_cast<Hwc2::IComposerClient::Attribute>(attribute),
- &value);
+ auto intError = mComposer.getDisplayAttribute(mId, configId, attribute, &value);
auto error = static_cast<Error>(intError);
- if (error != Error::None) {
+ if (error != Error::NONE) {
ALOGE("getDisplayAttribute(%" PRIu64 ", %u, %s) failed: %s (%d)", mId,
configId, to_string(attribute).c_str(),
to_string(error).c_str(), intError);
@@ -699,17 +689,16 @@
return value;
}
-void Display::loadConfig(hwc2_config_t configId)
-{
+void Display::loadConfig(HWConfigId configId) {
ALOGV("[%" PRIu64 "] loadConfig(%u)", mId, configId);
auto config = Config::Builder(*this, configId)
- .setWidth(getAttribute(configId, Attribute::Width))
- .setHeight(getAttribute(configId, Attribute::Height))
- .setVsyncPeriod(getAttribute(configId, Attribute::VsyncPeriod))
- .setDpiX(getAttribute(configId, Attribute::DpiX))
- .setDpiY(getAttribute(configId, Attribute::DpiY))
- .setConfigGroup(getAttribute(configId, Attribute::ConfigGroup))
+ .setWidth(getAttribute(configId, hal::Attribute::WIDTH))
+ .setHeight(getAttribute(configId, hal::Attribute::HEIGHT))
+ .setVsyncPeriod(getAttribute(configId, hal::Attribute::VSYNC_PERIOD))
+ .setDpiX(getAttribute(configId, hal::Attribute::DPI_X))
+ .setDpiY(getAttribute(configId, hal::Attribute::DPI_Y))
+ .setConfigGroup(getAttribute(configId, hal::Attribute::CONFIG_GROUP))
.build();
mConfigs.emplace(configId, std::move(config));
}
@@ -718,10 +707,10 @@
{
ALOGV("[%" PRIu64 "] loadConfigs", mId);
- std::vector<Hwc2::Config> configIds;
+ std::vector<HWConfigId> configIds;
auto intError = mComposer.getDisplayConfigs(mId, &configIds);
auto error = static_cast<Error>(intError);
- if (error != Error::None) {
+ if (error != Error::NONE) {
ALOGE("[%" PRIu64 "] getDisplayConfigs [2] failed: %s (%d)", mId,
to_string(error).c_str(), intError);
return;
@@ -734,7 +723,7 @@
// Other Display methods
-HWC2::Layer* Display::getLayerById(hwc2_layer_t id) const {
+HWC2::Layer* Display::getLayerById(HWLayerId id) const {
if (mLayers.count(id) == 0) {
return nullptr;
}
@@ -750,7 +739,7 @@
namespace impl {
Layer::Layer(android::Hwc2::Composer& composer, const std::unordered_set<Capability>& capabilities,
- hwc2_display_t displayId, hwc2_layer_t layerId)
+ HWDisplayId displayId, HWLayerId layerId)
: mComposer(composer),
mCapabilities(capabilities),
mDisplayId(displayId),
@@ -763,9 +752,10 @@
{
auto intError = mComposer.destroyLayer(mDisplayId, mId);
auto error = static_cast<Error>(intError);
- ALOGE_IF(error != Error::None, "destroyLayer(%" PRIu64 ", %" PRIu64 ")"
- " failed: %s (%d)", mDisplayId, mId, to_string(error).c_str(),
- intError);
+ ALOGE_IF(error != Error::NONE,
+ "destroyLayer(%" PRIu64 ", %" PRIu64 ")"
+ " failed: %s (%d)",
+ mDisplayId, mId, to_string(error).c_str(), intError);
}
Error Layer::setCursorPosition(int32_t x, int32_t y)
@@ -778,7 +768,7 @@
const sp<Fence>& acquireFence)
{
if (buffer == nullptr && mBufferSlot == slot) {
- return Error::None;
+ return Error::NONE;
}
mBufferSlot = slot;
@@ -792,7 +782,7 @@
{
if (damage.isRect() && mDamageRegion.isRect() &&
(damage.getBounds() == mDamageRegion.getBounds())) {
- return Error::None;
+ return Error::NONE;
}
mDamageRegion = damage;
@@ -820,30 +810,25 @@
Error Layer::setBlendMode(BlendMode mode)
{
- auto intMode = static_cast<Hwc2::IComposerClient::BlendMode>(mode);
- auto intError = mComposer.setLayerBlendMode(mDisplayId, mId, intMode);
+ auto intError = mComposer.setLayerBlendMode(mDisplayId, mId, mode);
return static_cast<Error>(intError);
}
-Error Layer::setColor(hwc_color_t color)
-{
- Hwc2::IComposerClient::Color hwcColor{color.r, color.g, color.b, color.a};
- auto intError = mComposer.setLayerColor(mDisplayId, mId, hwcColor);
+Error Layer::setColor(Color color) {
+ auto intError = mComposer.setLayerColor(mDisplayId, mId, color);
return static_cast<Error>(intError);
}
Error Layer::setCompositionType(Composition type)
{
- auto intType = static_cast<Hwc2::IComposerClient::Composition>(type);
- auto intError = mComposer.setLayerCompositionType(
- mDisplayId, mId, intType);
+ auto intError = mComposer.setLayerCompositionType(mDisplayId, mId, type);
return static_cast<Error>(intError);
}
Error Layer::setDataspace(Dataspace dataspace)
{
if (dataspace == mDataSpace) {
- return Error::None;
+ return Error::NONE;
}
mDataSpace = dataspace;
auto intError = mComposer.setLayerDataspace(mDisplayId, mId, mDataSpace);
@@ -854,7 +839,7 @@
const android::HdrMetadata& metadata)
{
if (metadata == mHdrMetadata) {
- return Error::None;
+ return Error::NONE;
}
mHdrMetadata = metadata;
@@ -901,7 +886,7 @@
{Hwc2::PerFrameMetadataKey::HDR10_PLUS_SEI, mHdrMetadata.hdr10plus});
Error setMetadataBlobsError = static_cast<Error>(
mComposer.setLayerPerFrameMetadataBlobs(mDisplayId, mId, perFrameMetadataBlobs));
- if (error == Error::None) {
+ if (error == Error::NONE) {
return setMetadataBlobsError;
}
}
@@ -924,10 +909,10 @@
Error Layer::setSidebandStream(const native_handle_t* stream)
{
- if (mCapabilities.count(Capability::SidebandStream) == 0) {
+ if (mCapabilities.count(Capability::SIDEBAND_STREAM) == 0) {
ALOGE("Attempted to call setSidebandStream without checking that the "
"device supports sideband streams");
- return Error::Unsupported;
+ return Error::UNSUPPORTED;
}
auto intError = mComposer.setLayerSidebandStream(mDisplayId, mId, stream);
return static_cast<Error>(intError);
@@ -952,7 +937,7 @@
{
if (region.isRect() && mVisibleRegion.isRect() &&
(region.getBounds() == mVisibleRegion.getBounds())) {
- return Error::None;
+ return Error::NONE;
}
mVisibleRegion = region;
@@ -984,11 +969,11 @@
// Composer HAL 2.3
Error Layer::setColorTransform(const android::mat4& matrix) {
if (matrix == mColorMatrix) {
- return Error::None;
+ return Error::NONE;
}
auto intError = mComposer.setLayerColorTransform(mDisplayId, mId, matrix.asArray());
Error error = static_cast<Error>(intError);
- if (error != Error::None) {
+ if (error != Error::NONE) {
return error;
}
mColorMatrix = matrix;
@@ -1004,6 +989,7 @@
} // namespace impl
} // namespace HWC2
+} // namespace android
// TODO(b/129481165): remove the #pragma below and fix conversion issues
#pragma clang diagnostic pop // ignored "-Wconversion"
diff --git a/services/surfaceflinger/DisplayHardware/HWC2.h b/services/surfaceflinger/DisplayHardware/HWC2.h
index 6549525..af31df8 100644
--- a/services/surfaceflinger/DisplayHardware/HWC2.h
+++ b/services/surfaceflinger/DisplayHardware/HWC2.h
@@ -17,16 +17,9 @@
#ifndef ANDROID_SF_HWC2_H
#define ANDROID_SF_HWC2_H
-#define HWC2_INCLUDE_STRINGIFICATION
-#define HWC2_USE_CPP11
-#include <hardware/hwcomposer2.h>
-#undef HWC2_INCLUDE_STRINGIFICATION
-#undef HWC2_USE_CPP11
-
#include <gui/HdrMetadata.h>
#include <math/mat4.h>
#include <ui/DisplayInfo.h>
-#include <ui/GraphicTypes.h>
#include <ui/HdrCapabilities.h>
#include <ui/Region.h>
#include <utils/Log.h>
@@ -39,6 +32,8 @@
#include <unordered_set>
#include <vector>
+#include "Hal.h"
+
namespace android {
struct DisplayedFrameStats;
class Fence;
@@ -49,13 +44,12 @@
}
class TestableSurfaceFlinger;
-}
namespace HWC2 {
class Layer;
-using VsyncPeriodChangeConstraints = hwc_vsync_period_change_constraints_t;
-using VsyncPeriodChangeTimeline = hwc_vsync_period_change_timeline_t;
+
+namespace hal = android::hardware::graphics::composer::hal;
// Implement this interface to receive hardware composer events.
//
@@ -68,21 +62,20 @@
// from different hardware composer instances.
class ComposerCallback {
public:
- virtual void onHotplugReceived(int32_t sequenceId, hwc2_display_t display,
- Connection connection) = 0;
- virtual void onRefreshReceived(int32_t sequenceId,
- hwc2_display_t display) = 0;
- virtual void onVsyncReceived(int32_t sequenceId, hwc2_display_t display, int64_t timestamp,
- std::optional<hwc2_vsync_period_t> vsyncPeriod) = 0;
- virtual void onVsyncPeriodTimingChangedReceived(
- int32_t sequenceId, hwc2_display_t display,
- const hwc_vsync_period_change_timeline_t& updatedTimeline) = 0;
- virtual void onSeamlessPossible(int32_t sequenceId, hwc2_display_t display) = 0;
+ virtual void onHotplugReceived(int32_t sequenceId, hal::HWDisplayId display,
+ hal::Connection connection) = 0;
+ virtual void onRefreshReceived(int32_t sequenceId, hal::HWDisplayId display) = 0;
+ virtual void onVsyncReceived(int32_t sequenceId, hal::HWDisplayId display, int64_t timestamp,
+ std::optional<hal::VsyncPeriodNanos> vsyncPeriod) = 0;
+ virtual void onVsyncPeriodTimingChangedReceived(
+ int32_t sequenceId, hal::HWDisplayId display,
+ const hal::VsyncPeriodChangeTimeline& updatedTimeline) = 0;
+ virtual void onSeamlessPossible(int32_t sequenceId, hal::HWDisplayId display) = 0;
- virtual ~ComposerCallback() = default;
+ virtual ~ComposerCallback() = default;
};
-// Convenience C++ class to access hwc2_device_t Display functions directly.
+// Convenience C++ class to access per display functions directly.
class Display {
public:
virtual ~Display();
@@ -92,7 +85,7 @@
class Builder
{
public:
- Builder(Display& display, hwc2_config_t id);
+ Builder(Display& display, hal::HWConfigId id);
std::shared_ptr<const Config> build() {
return std::const_pointer_cast<const Config>(
@@ -137,8 +130,8 @@
std::shared_ptr<Config> mConfig;
};
- hwc2_display_t getDisplayId() const { return mDisplay.getId(); }
- hwc2_config_t getId() const { return mId; }
+ hal::HWDisplayId getDisplayId() const { return mDisplay.getId(); }
+ hal::HWConfigId getId() const { return mId; }
int32_t getWidth() const { return mWidth; }
int32_t getHeight() const { return mHeight; }
@@ -148,10 +141,10 @@
int32_t getConfigGroup() const { return mConfigGroup; }
private:
- Config(Display& display, hwc2_config_t id);
+ Config(Display& display, hal::HWConfigId id);
Display& mDisplay;
- hwc2_config_t mId;
+ hal::HWConfigId mId;
int32_t mWidth;
int32_t mHeight;
@@ -161,168 +154,173 @@
int32_t mConfigGroup;
};
- virtual hwc2_display_t getId() const = 0;
+ virtual hal::HWDisplayId getId() const = 0;
virtual bool isConnected() const = 0;
virtual void setConnected(bool connected) = 0; // For use by Device only
- virtual const std::unordered_set<DisplayCapability>& getCapabilities() const = 0;
+ virtual const std::unordered_set<hal::DisplayCapability>& getCapabilities() const = 0;
virtual bool isVsyncPeriodSwitchSupported() const = 0;
- [[clang::warn_unused_result]] virtual Error acceptChanges() = 0;
- [[clang::warn_unused_result]] virtual Error createLayer(Layer** outLayer) = 0;
- [[clang::warn_unused_result]] virtual Error destroyLayer(Layer* layer) = 0;
- [[clang::warn_unused_result]] virtual Error getActiveConfig(
+ [[clang::warn_unused_result]] virtual hal::Error acceptChanges() = 0;
+ [[clang::warn_unused_result]] virtual hal::Error createLayer(Layer** outLayer) = 0;
+ [[clang::warn_unused_result]] virtual hal::Error destroyLayer(Layer* layer) = 0;
+ [[clang::warn_unused_result]] virtual hal::Error getActiveConfig(
std::shared_ptr<const Config>* outConfig) const = 0;
- [[clang::warn_unused_result]] virtual Error getActiveConfigIndex(int* outIndex) const = 0;
- [[clang::warn_unused_result]] virtual Error getChangedCompositionTypes(
- std::unordered_map<Layer*, Composition>* outTypes) = 0;
- [[clang::warn_unused_result]] virtual Error getColorModes(
- std::vector<android::ui::ColorMode>* outModes) const = 0;
+ [[clang::warn_unused_result]] virtual hal::Error getActiveConfigIndex(int* outIndex) const = 0;
+ [[clang::warn_unused_result]] virtual hal::Error getChangedCompositionTypes(
+ std::unordered_map<Layer*, hal::Composition>* outTypes) = 0;
+ [[clang::warn_unused_result]] virtual hal::Error getColorModes(
+ std::vector<hal::ColorMode>* outModes) const = 0;
// Returns a bitmask which contains HdrMetadata::Type::*.
[[clang::warn_unused_result]] virtual int32_t getSupportedPerFrameMetadata() const = 0;
- [[clang::warn_unused_result]] virtual Error getRenderIntents(
- android::ui::ColorMode colorMode,
- std::vector<android::ui::RenderIntent>* outRenderIntents) const = 0;
- [[clang::warn_unused_result]] virtual Error getDataspaceSaturationMatrix(
- android::ui::Dataspace dataspace, android::mat4* outMatrix) = 0;
+ [[clang::warn_unused_result]] virtual hal::Error getRenderIntents(
+ hal::ColorMode colorMode, std::vector<hal::RenderIntent>* outRenderIntents) const = 0;
+ [[clang::warn_unused_result]] virtual hal::Error getDataspaceSaturationMatrix(
+ hal::Dataspace dataspace, android::mat4* outMatrix) = 0;
- // Doesn't call into the HWC2 device, so no Errors are possible
- virtual std::vector<std::shared_ptr<const Config>> getConfigs() const = 0;
+ // Doesn't call into the HWC2 device, so no errors are possible
+ [[clang::warn_unused_result]] virtual std::vector<std::shared_ptr<const Config>> getConfigs()
+ const = 0;
- [[clang::warn_unused_result]] virtual Error getName(std::string* outName) const = 0;
- [[clang::warn_unused_result]] virtual Error getRequests(
- DisplayRequest* outDisplayRequests,
- std::unordered_map<Layer*, LayerRequest>* outLayerRequests) = 0;
- [[clang::warn_unused_result]] virtual Error getConnectionType(
+ [[clang::warn_unused_result]] virtual hal::Error getName(std::string* outName) const = 0;
+ [[clang::warn_unused_result]] virtual hal::Error getRequests(
+ hal::DisplayRequest* outDisplayRequests,
+ std::unordered_map<Layer*, hal::LayerRequest>* outLayerRequests) = 0;
+ [[clang::warn_unused_result]] virtual hal::Error getConnectionType(
android::DisplayConnectionType*) const = 0;
- [[clang::warn_unused_result]] virtual Error supportsDoze(bool* outSupport) const = 0;
- [[clang::warn_unused_result]] virtual Error getHdrCapabilities(
+ [[clang::warn_unused_result]] virtual hal::Error supportsDoze(bool* outSupport) const = 0;
+ [[clang::warn_unused_result]] virtual hal::Error getHdrCapabilities(
android::HdrCapabilities* outCapabilities) const = 0;
- [[clang::warn_unused_result]] virtual Error getDisplayedContentSamplingAttributes(
- android::ui::PixelFormat* outFormat, android::ui::Dataspace* outDataspace,
+ [[clang::warn_unused_result]] virtual hal::Error getDisplayedContentSamplingAttributes(
+ hal::PixelFormat* outFormat, hal::Dataspace* outDataspace,
uint8_t* outComponentMask) const = 0;
- [[clang::warn_unused_result]] virtual Error setDisplayContentSamplingEnabled(
+ [[clang::warn_unused_result]] virtual hal::Error setDisplayContentSamplingEnabled(
bool enabled, uint8_t componentMask, uint64_t maxFrames) const = 0;
- [[clang::warn_unused_result]] virtual Error getDisplayedContentSample(
+ [[clang::warn_unused_result]] virtual hal::Error getDisplayedContentSample(
uint64_t maxFrames, uint64_t timestamp,
android::DisplayedFrameStats* outStats) const = 0;
- [[clang::warn_unused_result]] virtual Error getReleaseFences(
+ [[clang::warn_unused_result]] virtual hal::Error getReleaseFences(
std::unordered_map<Layer*, android::sp<android::Fence>>* outFences) const = 0;
- [[clang::warn_unused_result]] virtual Error present(
+ [[clang::warn_unused_result]] virtual hal::Error present(
android::sp<android::Fence>* outPresentFence) = 0;
- [[clang::warn_unused_result]] virtual Error setActiveConfig(
+ [[clang::warn_unused_result]] virtual hal::Error setActiveConfig(
const std::shared_ptr<const Config>& config) = 0;
- [[clang::warn_unused_result]] virtual Error setClientTarget(
+ [[clang::warn_unused_result]] virtual hal::Error setClientTarget(
uint32_t slot, const android::sp<android::GraphicBuffer>& target,
- const android::sp<android::Fence>& acquireFence, android::ui::Dataspace dataspace) = 0;
- [[clang::warn_unused_result]] virtual Error setColorMode(
- android::ui::ColorMode mode, android::ui::RenderIntent renderIntent) = 0;
- [[clang::warn_unused_result]] virtual Error setColorTransform(
- const android::mat4& matrix, android_color_transform_t hint) = 0;
- [[clang::warn_unused_result]] virtual Error setOutputBuffer(
+ const android::sp<android::Fence>& acquireFence, hal::Dataspace dataspace) = 0;
+ [[clang::warn_unused_result]] virtual hal::Error setColorMode(
+ hal::ColorMode mode, hal::RenderIntent renderIntent) = 0;
+ [[clang::warn_unused_result]] virtual hal::Error setColorTransform(
+ const android::mat4& matrix, hal::ColorTransform hint) = 0;
+ [[clang::warn_unused_result]] virtual hal::Error setOutputBuffer(
const android::sp<android::GraphicBuffer>& buffer,
const android::sp<android::Fence>& releaseFence) = 0;
- [[clang::warn_unused_result]] virtual Error setPowerMode(PowerMode mode) = 0;
- [[clang::warn_unused_result]] virtual Error setVsyncEnabled(Vsync enabled) = 0;
- [[clang::warn_unused_result]] virtual Error validate(uint32_t* outNumTypes,
- uint32_t* outNumRequests) = 0;
- [[clang::warn_unused_result]] virtual Error presentOrValidate(
+ [[clang::warn_unused_result]] virtual hal::Error setPowerMode(hal::PowerMode mode) = 0;
+ [[clang::warn_unused_result]] virtual hal::Error setVsyncEnabled(hal::Vsync enabled) = 0;
+ [[clang::warn_unused_result]] virtual hal::Error validate(uint32_t* outNumTypes,
+ uint32_t* outNumRequests) = 0;
+ [[clang::warn_unused_result]] virtual hal::Error presentOrValidate(
uint32_t* outNumTypes, uint32_t* outNumRequests,
android::sp<android::Fence>* outPresentFence, uint32_t* state) = 0;
- [[clang::warn_unused_result]] virtual Error setDisplayBrightness(float brightness) const = 0;
- [[clang::warn_unused_result]] virtual Error getDisplayVsyncPeriod(
+ [[clang::warn_unused_result]] virtual hal::Error setDisplayBrightness(
+ float brightness) const = 0;
+ [[clang::warn_unused_result]] virtual hal::Error getDisplayVsyncPeriod(
nsecs_t* outVsyncPeriod) const = 0;
- [[clang::warn_unused_result]] virtual Error setActiveConfigWithConstraints(
+ [[clang::warn_unused_result]] virtual hal::Error setActiveConfigWithConstraints(
const std::shared_ptr<const HWC2::Display::Config>& config,
- const VsyncPeriodChangeConstraints& constraints,
- VsyncPeriodChangeTimeline* outTimeline) = 0;
- [[clang::warn_unused_result]] virtual Error setAutoLowLatencyMode(bool on) const = 0;
- [[clang::warn_unused_result]] virtual Error getSupportedContentTypes(
- std::vector<HWC2::ContentType>*) const = 0;
- [[clang::warn_unused_result]] virtual Error setContentType(HWC2::ContentType) const = 0;
+ const hal::VsyncPeriodChangeConstraints& constraints,
+ hal::VsyncPeriodChangeTimeline* outTimeline) = 0;
+ [[clang::warn_unused_result]] virtual hal::Error setAutoLowLatencyMode(bool on) const = 0;
+ [[clang::warn_unused_result]] virtual hal::Error getSupportedContentTypes(
+ std::vector<hal::ContentType>*) const = 0;
+ [[clang::warn_unused_result]] virtual hal::Error setContentType(hal::ContentType) const = 0;
};
namespace impl {
class Display : public HWC2::Display {
public:
- Display(android::Hwc2::Composer& composer, const std::unordered_set<Capability>& capabilities,
- hwc2_display_t id, DisplayType type);
+ Display(android::Hwc2::Composer& composer,
+ const std::unordered_set<hal::Capability>& capabilities, hal::HWDisplayId id,
+ hal::DisplayType type);
~Display() override;
// Required by HWC2
- Error acceptChanges() override;
- Error createLayer(Layer** outLayer) override;
- Error destroyLayer(Layer* layer) override;
- Error getActiveConfig(std::shared_ptr<const Config>* outConfig) const override;
- Error getActiveConfigIndex(int* outIndex) const override;
- Error getChangedCompositionTypes(std::unordered_map<Layer*, Composition>* outTypes) override;
- Error getColorModes(std::vector<android::ui::ColorMode>* outModes) const override;
+ hal::Error acceptChanges() override;
+ hal::Error createLayer(Layer** outLayer) override;
+ hal::Error destroyLayer(Layer* layer) override;
+ hal::Error getActiveConfig(std::shared_ptr<const Config>* outConfig) const override;
+ hal::Error getActiveConfigIndex(int* outIndex) const override;
+ hal::Error getChangedCompositionTypes(
+ std::unordered_map<Layer*, hal::Composition>* outTypes) override;
+ hal::Error getColorModes(std::vector<hal::ColorMode>* outModes) const override;
// Returns a bitmask which contains HdrMetadata::Type::*.
int32_t getSupportedPerFrameMetadata() const override;
- Error getRenderIntents(android::ui::ColorMode colorMode,
- std::vector<android::ui::RenderIntent>* outRenderIntents) const override;
- Error getDataspaceSaturationMatrix(android::ui::Dataspace dataspace,
- android::mat4* outMatrix) override;
+ hal::Error getRenderIntents(hal::ColorMode colorMode,
+ std::vector<hal::RenderIntent>* outRenderIntents) const override;
+ hal::Error getDataspaceSaturationMatrix(hal::Dataspace dataspace,
+ android::mat4* outMatrix) override;
// Doesn't call into the HWC2 device, so no errors are possible
std::vector<std::shared_ptr<const Config>> getConfigs() const override;
- Error getName(std::string* outName) const override;
- Error getRequests(DisplayRequest* outDisplayRequests,
- std::unordered_map<Layer*, LayerRequest>* outLayerRequests) override;
- Error getConnectionType(android::DisplayConnectionType*) const override;
- Error supportsDoze(bool* outSupport) const override;
- Error getHdrCapabilities(android::HdrCapabilities* outCapabilities) const override;
- Error getDisplayedContentSamplingAttributes(android::ui::PixelFormat* outFormat,
- android::ui::Dataspace* outDataspace,
- uint8_t* outComponentMask) const override;
- Error setDisplayContentSamplingEnabled(bool enabled, uint8_t componentMask,
- uint64_t maxFrames) const override;
- Error getDisplayedContentSample(uint64_t maxFrames, uint64_t timestamp,
- android::DisplayedFrameStats* outStats) const override;
- Error getReleaseFences(
+ hal::Error getName(std::string* outName) const override;
+ hal::Error getRequests(
+ hal::DisplayRequest* outDisplayRequests,
+ std::unordered_map<Layer*, hal::LayerRequest>* outLayerRequests) override;
+ hal::Error getConnectionType(android::DisplayConnectionType*) const override;
+ hal::Error supportsDoze(bool* outSupport) const override;
+ hal::Error getHdrCapabilities(android::HdrCapabilities* outCapabilities) const override;
+ hal::Error getDisplayedContentSamplingAttributes(hal::PixelFormat* outFormat,
+ hal::Dataspace* outDataspace,
+ uint8_t* outComponentMask) const override;
+ hal::Error setDisplayContentSamplingEnabled(bool enabled, uint8_t componentMask,
+ uint64_t maxFrames) const override;
+ hal::Error getDisplayedContentSample(uint64_t maxFrames, uint64_t timestamp,
+ android::DisplayedFrameStats* outStats) const override;
+ hal::Error getReleaseFences(
std::unordered_map<Layer*, android::sp<android::Fence>>* outFences) const override;
- Error present(android::sp<android::Fence>* outPresentFence) override;
- Error setActiveConfig(const std::shared_ptr<const HWC2::Display::Config>& config) override;
- Error setClientTarget(uint32_t slot, const android::sp<android::GraphicBuffer>& target,
- const android::sp<android::Fence>& acquireFence,
- android::ui::Dataspace dataspace) override;
- Error setColorMode(android::ui::ColorMode mode,
- android::ui::RenderIntent renderIntent) override;
- Error setColorTransform(const android::mat4& matrix, android_color_transform_t hint) override;
- Error setOutputBuffer(const android::sp<android::GraphicBuffer>& buffer,
- const android::sp<android::Fence>& releaseFence) override;
- Error setPowerMode(PowerMode mode) override;
- Error setVsyncEnabled(Vsync enabled) override;
- Error validate(uint32_t* outNumTypes, uint32_t* outNumRequests) override;
- Error presentOrValidate(uint32_t* outNumTypes, uint32_t* outNumRequests,
- android::sp<android::Fence>* outPresentFence, uint32_t* state) override;
- Error setDisplayBrightness(float brightness) const override;
- Error getDisplayVsyncPeriod(nsecs_t* outVsyncPeriod) const override;
- Error setActiveConfigWithConstraints(const std::shared_ptr<const HWC2::Display::Config>& config,
- const VsyncPeriodChangeConstraints& constraints,
- VsyncPeriodChangeTimeline* outTimeline) override;
- Error setAutoLowLatencyMode(bool on) const override;
- Error getSupportedContentTypes(
- std::vector<HWC2::ContentType>* outSupportedContentTypes) const override;
- Error setContentType(HWC2::ContentType contentType) const override;
+ hal::Error present(android::sp<android::Fence>* outPresentFence) override;
+ hal::Error setActiveConfig(const std::shared_ptr<const HWC2::Display::Config>& config) override;
+ hal::Error setClientTarget(uint32_t slot, const android::sp<android::GraphicBuffer>& target,
+ const android::sp<android::Fence>& acquireFence,
+ hal::Dataspace dataspace) override;
+ hal::Error setColorMode(hal::ColorMode mode, hal::RenderIntent renderIntent) override;
+ hal::Error setColorTransform(const android::mat4& matrix, hal::ColorTransform hint) override;
+ hal::Error setOutputBuffer(const android::sp<android::GraphicBuffer>& buffer,
+ const android::sp<android::Fence>& releaseFence) override;
+ hal::Error setPowerMode(hal::PowerMode mode) override;
+ hal::Error setVsyncEnabled(hal::Vsync enabled) override;
+ hal::Error validate(uint32_t* outNumTypes, uint32_t* outNumRequests) override;
+ hal::Error presentOrValidate(uint32_t* outNumTypes, uint32_t* outNumRequests,
+ android::sp<android::Fence>* outPresentFence,
+ uint32_t* state) override;
+ hal::Error setDisplayBrightness(float brightness) const override;
+ hal::Error getDisplayVsyncPeriod(nsecs_t* outVsyncPeriod) const override;
+ hal::Error setActiveConfigWithConstraints(
+ const std::shared_ptr<const HWC2::Display::Config>& config,
+ const hal::VsyncPeriodChangeConstraints& constraints,
+ hal::VsyncPeriodChangeTimeline* outTimeline) override;
+ hal::Error setAutoLowLatencyMode(bool on) const override;
+ hal::Error getSupportedContentTypes(
+ std::vector<hal::ContentType>* outSupportedContentTypes) const override;
+ hal::Error setContentType(hal::ContentType contentType) const override;
// Other Display methods
- hwc2_display_t getId() const override { return mId; }
+ hal::HWDisplayId getId() const override { return mId; }
bool isConnected() const override { return mIsConnected; }
void setConnected(bool connected) override; // For use by Device only
- const std::unordered_set<DisplayCapability>& getCapabilities() const override {
+ const std::unordered_set<hal::DisplayCapability>& getCapabilities() const override {
return mDisplayCapabilities;
};
virtual bool isVsyncPeriodSwitchSupported() const override;
private:
- int32_t getAttribute(hwc2_config_t configId, Attribute attribute);
- void loadConfig(hwc2_config_t configId);
+ int32_t getAttribute(hal::HWConfigId configId, hal::Attribute attribute);
+ void loadConfig(hal::HWConfigId configId);
void loadConfigs();
// This may fail (and return a null pointer) if no layer with this ID exists
// on this display
- Layer* getLayerById(hwc2_layer_t id) const;
+ Layer* getLayerById(hal::HWLayerId id) const;
friend android::TestableSurfaceFlinger;
@@ -332,17 +330,17 @@
// this HWC2::Display, so these references are guaranteed to be valid for
// the lifetime of this object.
android::Hwc2::Composer& mComposer;
- const std::unordered_set<Capability>& mCapabilities;
+ const std::unordered_set<hal::Capability>& mCapabilities;
- const hwc2_display_t mId;
- DisplayType mType;
+ const hal::HWDisplayId mId;
+ hal::DisplayType mType;
bool mIsConnected = false;
- std::unordered_map<hwc2_layer_t, std::unique_ptr<Layer>> mLayers;
- std::unordered_map<hwc2_config_t, std::shared_ptr<const Config>> mConfigs;
+ std::unordered_map<hal::HWLayerId, std::unique_ptr<Layer>> mLayers;
+ std::unordered_map<hal::HWConfigId, std::shared_ptr<const Config>> mConfigs;
std::once_flag mDisplayCapabilityQueryFlag;
- std::unordered_set<DisplayCapability> mDisplayCapabilities;
+ std::unordered_set<hal::DisplayCapability> mDisplayCapabilities;
};
} // namespace impl
@@ -351,99 +349,105 @@
public:
virtual ~Layer();
- virtual hwc2_layer_t getId() const = 0;
+ virtual hal::HWLayerId getId() const = 0;
- [[clang::warn_unused_result]] virtual Error setCursorPosition(int32_t x, int32_t y) = 0;
- [[clang::warn_unused_result]] virtual Error setBuffer(
+ [[clang::warn_unused_result]] virtual hal::Error setCursorPosition(int32_t x, int32_t y) = 0;
+ [[clang::warn_unused_result]] virtual hal::Error setBuffer(
uint32_t slot, const android::sp<android::GraphicBuffer>& buffer,
const android::sp<android::Fence>& acquireFence) = 0;
- [[clang::warn_unused_result]] virtual Error setSurfaceDamage(const android::Region& damage) = 0;
+ [[clang::warn_unused_result]] virtual hal::Error setSurfaceDamage(
+ const android::Region& damage) = 0;
- [[clang::warn_unused_result]] virtual Error setBlendMode(BlendMode mode) = 0;
- [[clang::warn_unused_result]] virtual Error setColor(hwc_color_t color) = 0;
- [[clang::warn_unused_result]] virtual Error setCompositionType(Composition type) = 0;
- [[clang::warn_unused_result]] virtual Error setDataspace(android::ui::Dataspace dataspace) = 0;
- [[clang::warn_unused_result]] virtual Error setPerFrameMetadata(
+ [[clang::warn_unused_result]] virtual hal::Error setBlendMode(hal::BlendMode mode) = 0;
+ [[clang::warn_unused_result]] virtual hal::Error setColor(hal::Color color) = 0;
+ [[clang::warn_unused_result]] virtual hal::Error setCompositionType(hal::Composition type) = 0;
+ [[clang::warn_unused_result]] virtual hal::Error setDataspace(hal::Dataspace dataspace) = 0;
+ [[clang::warn_unused_result]] virtual hal::Error setPerFrameMetadata(
const int32_t supportedPerFrameMetadata, const android::HdrMetadata& metadata) = 0;
- [[clang::warn_unused_result]] virtual Error setDisplayFrame(const android::Rect& frame) = 0;
- [[clang::warn_unused_result]] virtual Error setPlaneAlpha(float alpha) = 0;
- [[clang::warn_unused_result]] virtual Error setSidebandStream(
+ [[clang::warn_unused_result]] virtual hal::Error setDisplayFrame(
+ const android::Rect& frame) = 0;
+ [[clang::warn_unused_result]] virtual hal::Error setPlaneAlpha(float alpha) = 0;
+ [[clang::warn_unused_result]] virtual hal::Error setSidebandStream(
const native_handle_t* stream) = 0;
- [[clang::warn_unused_result]] virtual Error setSourceCrop(const android::FloatRect& crop) = 0;
- [[clang::warn_unused_result]] virtual Error setTransform(Transform transform) = 0;
- [[clang::warn_unused_result]] virtual Error setVisibleRegion(const android::Region& region) = 0;
- [[clang::warn_unused_result]] virtual Error setZOrder(uint32_t z) = 0;
- [[clang::warn_unused_result]] virtual Error setInfo(uint32_t type, uint32_t appId) = 0;
+ [[clang::warn_unused_result]] virtual hal::Error setSourceCrop(
+ const android::FloatRect& crop) = 0;
+ [[clang::warn_unused_result]] virtual hal::Error setTransform(hal::Transform transform) = 0;
+ [[clang::warn_unused_result]] virtual hal::Error setVisibleRegion(
+ const android::Region& region) = 0;
+ [[clang::warn_unused_result]] virtual hal::Error setZOrder(uint32_t z) = 0;
+ [[clang::warn_unused_result]] virtual hal::Error setInfo(uint32_t type, uint32_t appId) = 0;
// Composer HAL 2.3
- [[clang::warn_unused_result]] virtual Error setColorTransform(const android::mat4& matrix) = 0;
+ [[clang::warn_unused_result]] virtual hal::Error setColorTransform(
+ const android::mat4& matrix) = 0;
// Composer HAL 2.4
- [[clang::warn_unused_result]] virtual Error setLayerGenericMetadata(
+ [[clang::warn_unused_result]] virtual hal::Error setLayerGenericMetadata(
const std::string& name, bool mandatory, const std::vector<uint8_t>& value) = 0;
};
namespace impl {
-// Convenience C++ class to access hwc2_device_t Layer functions directly.
+// Convenience C++ class to access per layer functions directly.
class Layer : public HWC2::Layer {
public:
- Layer(android::Hwc2::Composer& composer, const std::unordered_set<Capability>& capabilities,
- hwc2_display_t displayId, hwc2_layer_t layerId);
+ Layer(android::Hwc2::Composer& composer,
+ const std::unordered_set<hal::Capability>& capabilities, hal::HWDisplayId displayId,
+ hal::HWLayerId layerId);
~Layer() override;
- hwc2_layer_t getId() const override { return mId; }
+ hal::HWLayerId getId() const override { return mId; }
- Error setCursorPosition(int32_t x, int32_t y) override;
- Error setBuffer(uint32_t slot, const android::sp<android::GraphicBuffer>& buffer,
- const android::sp<android::Fence>& acquireFence) override;
- Error setSurfaceDamage(const android::Region& damage) override;
+ hal::Error setCursorPosition(int32_t x, int32_t y) override;
+ hal::Error setBuffer(uint32_t slot, const android::sp<android::GraphicBuffer>& buffer,
+ const android::sp<android::Fence>& acquireFence) override;
+ hal::Error setSurfaceDamage(const android::Region& damage) override;
- Error setBlendMode(BlendMode mode) override;
- Error setColor(hwc_color_t color) override;
- Error setCompositionType(Composition type) override;
- Error setDataspace(android::ui::Dataspace dataspace) override;
- Error setPerFrameMetadata(const int32_t supportedPerFrameMetadata,
- const android::HdrMetadata& metadata) override;
- Error setDisplayFrame(const android::Rect& frame) override;
- Error setPlaneAlpha(float alpha) override;
- Error setSidebandStream(const native_handle_t* stream) override;
- Error setSourceCrop(const android::FloatRect& crop) override;
- Error setTransform(Transform transform) override;
- Error setVisibleRegion(const android::Region& region) override;
- Error setZOrder(uint32_t z) override;
- Error setInfo(uint32_t type, uint32_t appId) override;
+ hal::Error setBlendMode(hal::BlendMode mode) override;
+ hal::Error setColor(hal::Color color) override;
+ hal::Error setCompositionType(hal::Composition type) override;
+ hal::Error setDataspace(hal::Dataspace dataspace) override;
+ hal::Error setPerFrameMetadata(const int32_t supportedPerFrameMetadata,
+ const android::HdrMetadata& metadata) override;
+ hal::Error setDisplayFrame(const android::Rect& frame) override;
+ hal::Error setPlaneAlpha(float alpha) override;
+ hal::Error setSidebandStream(const native_handle_t* stream) override;
+ hal::Error setSourceCrop(const android::FloatRect& crop) override;
+ hal::Error setTransform(hal::Transform transform) override;
+ hal::Error setVisibleRegion(const android::Region& region) override;
+ hal::Error setZOrder(uint32_t z) override;
+ hal::Error setInfo(uint32_t type, uint32_t appId) override;
// Composer HAL 2.3
- Error setColorTransform(const android::mat4& matrix) override;
+ hal::Error setColorTransform(const android::mat4& matrix) override;
// Composer HAL 2.4
- Error setLayerGenericMetadata(const std::string& name, bool mandatory,
- const std::vector<uint8_t>& value) override;
+ hal::Error setLayerGenericMetadata(const std::string& name, bool mandatory,
+ const std::vector<uint8_t>& value) override;
private:
// These are references to data owned by HWC2::Device, which will outlive
// this HWC2::Layer, so these references are guaranteed to be valid for
// the lifetime of this object.
android::Hwc2::Composer& mComposer;
- const std::unordered_set<Capability>& mCapabilities;
+ const std::unordered_set<hal::Capability>& mCapabilities;
- hwc2_display_t mDisplayId;
- hwc2_layer_t mId;
+ hal::HWDisplayId mDisplayId;
+ hal::HWLayerId mId;
// Cached HWC2 data, to ensure the same commands aren't sent to the HWC
// multiple times.
android::Region mVisibleRegion = android::Region::INVALID_REGION;
android::Region mDamageRegion = android::Region::INVALID_REGION;
- android::ui::Dataspace mDataSpace = android::ui::Dataspace::UNKNOWN;
+ hal::Dataspace mDataSpace = hal::Dataspace::UNKNOWN;
android::HdrMetadata mHdrMetadata;
android::mat4 mColorMatrix;
uint32_t mBufferSlot;
};
} // namespace impl
-
} // namespace HWC2
+} // namespace android
#endif // ANDROID_SF_HWC2_H
diff --git a/services/surfaceflinger/DisplayHardware/HWComposer.cpp b/services/surfaceflinger/DisplayHardware/HWComposer.cpp
index f30d662..4344a8d 100644
--- a/services/surfaceflinger/DisplayHardware/HWComposer.cpp
+++ b/services/surfaceflinger/DisplayHardware/HWComposer.cpp
@@ -60,7 +60,7 @@
#define RETURN_IF_HWC_ERROR_FOR(what, error, displayId, ...) \
do { \
- if (error != HWC2::Error::None) { \
+ if (error != hal::Error::NONE) { \
LOG_HWC_ERROR(what, error, displayId); \
return __VA_ARGS__; \
} \
@@ -69,34 +69,34 @@
#define RETURN_IF_HWC_ERROR(error, displayId, ...) \
RETURN_IF_HWC_ERROR_FOR(__FUNCTION__, error, displayId, __VA_ARGS__)
+namespace hal = android::hardware::graphics::composer::hal;
+
namespace {
using android::hardware::Return;
using android::hardware::Void;
+using android::HWC2::ComposerCallback;
-class ComposerCallbackBridge : public android::Hwc2::IComposerCallback {
+class ComposerCallbackBridge : public hal::IComposerCallback {
public:
- ComposerCallbackBridge(HWC2::ComposerCallback* callback, int32_t sequenceId,
+ ComposerCallbackBridge(ComposerCallback* callback, int32_t sequenceId,
bool vsyncSwitchingSupported)
: mCallback(callback),
mSequenceId(sequenceId),
mVsyncSwitchingSupported(vsyncSwitchingSupported) {}
- android::hardware::Return<void> onHotplug(
- android::Hwc2::Display display,
- android::Hwc2::IComposerCallback::Connection conn) override {
- HWC2::Connection connection = static_cast<HWC2::Connection>(conn);
- mCallback->onHotplugReceived(mSequenceId, display, connection);
+ android::hardware::Return<void> onHotplug(hal::HWDisplayId display,
+ hal::Connection conn) override {
+ mCallback->onHotplugReceived(mSequenceId, display, conn);
return android::hardware::Void();
}
- android::hardware::Return<void> onRefresh(android::Hwc2::Display display) override {
+ android::hardware::Return<void> onRefresh(hal::HWDisplayId display) override {
mCallback->onRefreshReceived(mSequenceId, display);
return android::hardware::Void();
}
- android::hardware::Return<void> onVsync(android::Hwc2::Display display,
- int64_t timestamp) override {
+ android::hardware::Return<void> onVsync(hal::HWDisplayId display, int64_t timestamp) override {
if (!mVsyncSwitchingSupported) {
mCallback->onVsyncReceived(mSequenceId, display, timestamp, std::nullopt);
} else {
@@ -105,9 +105,8 @@
return android::hardware::Void();
}
- android::hardware::Return<void> onVsync_2_4(
- android::Hwc2::Display display, int64_t timestamp,
- android::Hwc2::VsyncPeriodNanos vsyncPeriodNanos) override {
+ android::hardware::Return<void> onVsync_2_4(hal::HWDisplayId display, int64_t timestamp,
+ hal::VsyncPeriodNanos vsyncPeriodNanos) override {
if (mVsyncSwitchingSupported) {
mCallback->onVsyncReceived(mSequenceId, display, timestamp,
std::make_optional(vsyncPeriodNanos));
@@ -118,23 +117,19 @@
}
android::hardware::Return<void> onVsyncPeriodTimingChanged(
- android::Hwc2::Display display,
- const android::Hwc2::VsyncPeriodChangeTimeline& updatedTimeline) override {
- hwc_vsync_period_change_timeline_t timeline;
- timeline.newVsyncAppliedTimeNanos = updatedTimeline.newVsyncAppliedTimeNanos;
- timeline.refreshRequired = updatedTimeline.refreshRequired;
- timeline.refreshTimeNanos = updatedTimeline.refreshTimeNanos;
- mCallback->onVsyncPeriodTimingChangedReceived(mSequenceId, display, timeline);
+ hal::HWDisplayId display,
+ const hal::VsyncPeriodChangeTimeline& updatedTimeline) override {
+ mCallback->onVsyncPeriodTimingChangedReceived(mSequenceId, display, updatedTimeline);
return android::hardware::Void();
}
- android::hardware::Return<void> onSeamlessPossible(android::Hwc2::Display display) override {
+ android::hardware::Return<void> onSeamlessPossible(hal::HWDisplayId display) override {
mCallback->onSeamlessPossible(mSequenceId, display);
return android::hardware::Void();
}
private:
- HWC2::ComposerCallback* mCallback;
+ ComposerCallback* mCallback;
const int32_t mSequenceId;
const bool mVsyncSwitchingSupported;
};
@@ -173,12 +168,12 @@
mComposer->registerCallback(callbackBridge);
}
-bool HWComposer::getDisplayIdentificationData(hwc2_display_t hwcDisplayId, uint8_t* outPort,
+bool HWComposer::getDisplayIdentificationData(hal::HWDisplayId hwcDisplayId, uint8_t* outPort,
DisplayIdentificationData* outData) const {
- const auto error = static_cast<HWC2::Error>(
+ const auto error = static_cast<hal::Error>(
mComposer->getDisplayIdentificationData(hwcDisplayId, outPort, outData));
- if (error != HWC2::Error::None) {
- if (error != HWC2::Error::Unsupported) {
+ if (error != hal::Error::NONE) {
+ if (error != hal::Error::UNSUPPORTED) {
LOG_HWC_DISPLAY_ERROR(hwcDisplayId, to_string(error).c_str());
}
return false;
@@ -186,29 +181,29 @@
return true;
}
-bool HWComposer::hasCapability(HWC2::Capability capability) const {
+bool HWComposer::hasCapability(hal::Capability capability) const {
return mCapabilities.count(capability) > 0;
}
bool HWComposer::hasDisplayCapability(DisplayId displayId,
- HWC2::DisplayCapability capability) const {
+ hal::DisplayCapability capability) const {
RETURN_IF_INVALID_DISPLAY(displayId, false);
return mDisplayData.at(displayId).hwcDisplay->getCapabilities().count(capability) > 0;
}
-std::optional<DisplayIdentificationInfo> HWComposer::onHotplug(hwc2_display_t hwcDisplayId,
- HWC2::Connection connection) {
+std::optional<DisplayIdentificationInfo> HWComposer::onHotplug(hal::HWDisplayId hwcDisplayId,
+ hal::Connection connection) {
switch (connection) {
- case HWC2::Connection::Connected:
+ case hal::Connection::CONNECTED:
return onHotplugConnect(hwcDisplayId);
- case HWC2::Connection::Disconnected:
+ case hal::Connection::DISCONNECTED:
return onHotplugDisconnect(hwcDisplayId);
- case HWC2::Connection::Invalid:
+ case hal::Connection::INVALID:
return {};
}
}
-bool HWComposer::onVsync(hwc2_display_t hwcDisplayId, int64_t timestamp) {
+bool HWComposer::onVsync(hal::HWDisplayId hwcDisplayId, int64_t timestamp) {
const auto displayId = toPhysicalDisplayId(hwcDisplayId);
if (!displayId) {
LOG_HWC_DISPLAY_ERROR(hwcDisplayId, "Invalid HWC display");
@@ -260,16 +255,16 @@
height, SurfaceFlinger::maxVirtualDisplaySize);
return {};
}
- hwc2_display_t hwcDisplayId = 0;
- const auto error = static_cast<HWC2::Error>(
+ hal::HWDisplayId hwcDisplayId = 0;
+ const auto error = static_cast<hal::Error>(
mComposer->createVirtualDisplay(width, height, format, &hwcDisplayId));
- if (error != HWC2::Error::None) {
+ if (error != hal::Error::NONE) {
ALOGE("%s: Failed to create HWC virtual display", __FUNCTION__);
return {};
}
auto display = std::make_unique<HWC2::impl::Display>(*mComposer.get(), mCapabilities,
- hwcDisplayId, HWC2::DisplayType::Virtual);
+ hwcDisplayId, hal::DisplayType::VIRTUAL);
display->setConnected(true);
DisplayId displayId;
@@ -288,7 +283,7 @@
return displayId;
}
-void HWComposer::allocatePhysicalDisplay(hwc2_display_t hwcDisplayId, DisplayId displayId) {
+void HWComposer::allocatePhysicalDisplay(hal::HWDisplayId hwcDisplayId, DisplayId displayId) {
if (!mInternalHwcDisplayId) {
mInternalHwcDisplayId = hwcDisplayId;
} else if (mInternalHwcDisplayId != hwcDisplayId && !mExternalHwcDisplayId) {
@@ -298,7 +293,7 @@
auto& displayData = mDisplayData[displayId];
auto newDisplay =
std::make_unique<HWC2::impl::Display>(*mComposer.get(), mCapabilities, hwcDisplayId,
- HWC2::DisplayType::Physical);
+ hal::DisplayType::PHYSICAL);
newDisplay->setConnected(true);
displayData.hwcDisplay = std::move(newDisplay);
mPhysicalDisplayIdMap[hwcDisplayId] = displayId;
@@ -357,7 +352,7 @@
std::shared_ptr<const HWC2::Display::Config> config;
auto error = mDisplayData.at(displayId).hwcDisplay->getActiveConfig(&config);
- if (error == HWC2::Error::BadConfig) {
+ if (error == hal::Error::BAD_CONFIG) {
LOG_DISPLAY_ERROR(displayId, "No active config");
return nullptr;
}
@@ -408,7 +403,7 @@
int index;
auto error = mDisplayData.at(displayId).hwcDisplay->getActiveConfigIndex(&index);
- if (error == HWC2::Error::BadConfig) {
+ if (error == hal::Error::BAD_CONFIG) {
LOG_DISPLAY_ERROR(displayId, "No active config");
return -1;
}
@@ -446,7 +441,7 @@
return NO_ERROR;
}
-void HWComposer::setVsyncEnabled(DisplayId displayId, HWC2::Vsync enabled) {
+void HWComposer::setVsyncEnabled(DisplayId displayId, hal::Vsync enabled) {
RETURN_IF_INVALID_DISPLAY(displayId);
auto& displayData = mDisplayData[displayId];
@@ -471,7 +466,7 @@
displayData.vsyncEnabled = enabled;
const auto tag = "HW_VSYNC_ON_" + to_string(displayId);
- ATRACE_INT(tag.c_str(), enabled == HWC2::Vsync::Enable ? 1 : 0);
+ ATRACE_INT(tag.c_str(), enabled == hal::Vsync::ENABLE ? 1 : 0);
}
status_t HWComposer::setClientTarget(DisplayId displayId, uint32_t slot,
@@ -502,7 +497,7 @@
uint32_t numTypes = 0;
uint32_t numRequests = 0;
- HWC2::Error error = HWC2::Error::None;
+ hal::Error error = hal::Error::NONE;
// First try to skip validate altogether when there is no client
// composition. When there is client composition, since we haven't
@@ -513,7 +508,7 @@
sp<Fence> outPresentFence;
uint32_t state = UINT32_MAX;
error = hwcDisplay->presentOrValidate(&numTypes, &numRequests, &outPresentFence , &state);
- if (error != HWC2::Error::HasChanges) {
+ if (!hasChangesError(error)) {
RETURN_IF_HWC_ERROR_FOR("presentOrValidate", error, displayId, UNKNOWN_ERROR);
}
if (state == 1) { //Present Succeeded.
@@ -530,7 +525,7 @@
error = hwcDisplay->validate(&numTypes, &numRequests);
}
ALOGV("SkipValidate failed, Falling back to SLOW validate/present");
- if (error != HWC2::Error::HasChanges) {
+ if (!hasChangesError(error)) {
RETURN_IF_HWC_ERROR_FOR("validate", error, displayId, BAD_INDEX);
}
@@ -539,7 +534,7 @@
error = hwcDisplay->getChangedCompositionTypes(&changedTypes);
RETURN_IF_HWC_ERROR_FOR("getChangedCompositionTypes", error, displayId, BAD_INDEX);
- auto displayRequests = static_cast<HWC2::DisplayRequest>(0);
+ auto displayRequests = static_cast<hal::DisplayRequest>(0);
android::HWComposer::DeviceRequestedChanges::LayerRequests layerRequests;
layerRequests.reserve(numRequests);
error = hwcDisplay->getRequests(&displayRequests, &layerRequests);
@@ -580,7 +575,7 @@
if (displayData.validateWasSkipped) {
// explicitly flush all pending commands
- auto error = static_cast<HWC2::Error>(mComposer->executeCommands());
+ auto error = static_cast<hal::Error>(mComposer->executeCommands());
RETURN_IF_HWC_ERROR_FOR("executeCommands", error, displayId, UNKNOWN_ERROR);
RETURN_IF_HWC_ERROR_FOR("present", displayData.presentError, displayId, UNKNOWN_ERROR);
return NO_ERROR;
@@ -598,7 +593,7 @@
return NO_ERROR;
}
-status_t HWComposer::setPowerMode(DisplayId displayId, int32_t intMode) {
+status_t HWComposer::setPowerMode(DisplayId displayId, hal::PowerMode mode) {
RETURN_IF_INVALID_DISPLAY(displayId, BAD_INDEX);
const auto& displayData = mDisplayData[displayId];
@@ -607,42 +602,41 @@
return INVALID_OPERATION;
}
- auto mode = static_cast<HWC2::PowerMode>(intMode);
- if (mode == HWC2::PowerMode::Off) {
- setVsyncEnabled(displayId, HWC2::Vsync::Disable);
+ if (mode == hal::PowerMode::OFF) {
+ setVsyncEnabled(displayId, hal::Vsync::DISABLE);
}
auto& hwcDisplay = displayData.hwcDisplay;
switch (mode) {
- case HWC2::PowerMode::Off:
- case HWC2::PowerMode::On:
+ case hal::PowerMode::OFF:
+ case hal::PowerMode::ON:
ALOGV("setPowerMode: Calling HWC %s", to_string(mode).c_str());
{
auto error = hwcDisplay->setPowerMode(mode);
- if (error != HWC2::Error::None) {
- LOG_HWC_ERROR(("setPowerMode(" + to_string(mode) + ")").c_str(),
- error, displayId);
+ if (error != hal::Error::NONE) {
+ LOG_HWC_ERROR(("setPowerMode(" + to_string(mode) + ")").c_str(), error,
+ displayId);
}
}
break;
- case HWC2::PowerMode::Doze:
- case HWC2::PowerMode::DozeSuspend:
+ case hal::PowerMode::DOZE:
+ case hal::PowerMode::DOZE_SUSPEND:
ALOGV("setPowerMode: Calling HWC %s", to_string(mode).c_str());
{
bool supportsDoze = false;
auto error = hwcDisplay->supportsDoze(&supportsDoze);
- if (error != HWC2::Error::None) {
+ if (error != hal::Error::NONE) {
LOG_HWC_ERROR("supportsDoze", error, displayId);
}
if (!supportsDoze) {
- mode = HWC2::PowerMode::On;
+ mode = hal::PowerMode::ON;
}
error = hwcDisplay->setPowerMode(mode);
- if (error != HWC2::Error::None) {
- LOG_HWC_ERROR(("setPowerMode(" + to_string(mode) + ")").c_str(),
- error, displayId);
+ if (error != hal::Error::NONE) {
+ LOG_HWC_ERROR(("setPowerMode(" + to_string(mode) + ")").c_str(), error,
+ displayId);
}
}
break;
@@ -655,8 +649,8 @@
}
status_t HWComposer::setActiveConfigWithConstraints(
- DisplayId displayId, size_t configId, const HWC2::VsyncPeriodChangeConstraints& constraints,
- HWC2::VsyncPeriodChangeTimeline* outTimeline) {
+ DisplayId displayId, size_t configId, const hal::VsyncPeriodChangeConstraints& constraints,
+ hal::VsyncPeriodChangeTimeline* outTimeline) {
RETURN_IF_INVALID_DISPLAY(displayId, BAD_INDEX);
auto& displayData = mDisplayData[displayId];
@@ -677,9 +671,10 @@
auto& displayData = mDisplayData[displayId];
bool isIdentity = transform == mat4();
- auto error = displayData.hwcDisplay->setColorTransform(transform,
- isIdentity ? HAL_COLOR_TRANSFORM_IDENTITY :
- HAL_COLOR_TRANSFORM_ARBITRARY_MATRIX);
+ auto error = displayData.hwcDisplay
+ ->setColorTransform(transform,
+ isIdentity ? hal::ColorTransform::IDENTITY
+ : hal::ColorTransform::ARBITRARY_MATRIX);
RETURN_IF_HWC_ERROR(error, displayId, UNKNOWN_ERROR);
return NO_ERROR;
}
@@ -770,7 +765,7 @@
mDisplayData[displayId]
.hwcDisplay->getDisplayedContentSamplingAttributes(outFormat, outDataspace,
outComponentMask);
- if (error == HWC2::Error::Unsupported) RETURN_IF_HWC_ERROR(error, displayId, INVALID_OPERATION);
+ if (error == hal::Error::UNSUPPORTED) RETURN_IF_HWC_ERROR(error, displayId, INVALID_OPERATION);
RETURN_IF_HWC_ERROR(error, displayId, UNKNOWN_ERROR);
return NO_ERROR;
}
@@ -783,8 +778,8 @@
componentMask,
maxFrames);
- if (error == HWC2::Error::Unsupported) RETURN_IF_HWC_ERROR(error, displayId, INVALID_OPERATION);
- if (error == HWC2::Error::BadParameter) RETURN_IF_HWC_ERROR(error, displayId, BAD_VALUE);
+ if (error == hal::Error::UNSUPPORTED) RETURN_IF_HWC_ERROR(error, displayId, INVALID_OPERATION);
+ if (error == hal::Error::BAD_PARAMETER) RETURN_IF_HWC_ERROR(error, displayId, BAD_VALUE);
RETURN_IF_HWC_ERROR(error, displayId, UNKNOWN_ERROR);
return NO_ERROR;
}
@@ -802,10 +797,10 @@
status_t HWComposer::setDisplayBrightness(DisplayId displayId, float brightness) {
RETURN_IF_INVALID_DISPLAY(displayId, BAD_INDEX);
const auto error = mDisplayData[displayId].hwcDisplay->setDisplayBrightness(brightness);
- if (error == HWC2::Error::Unsupported) {
+ if (error == hal::Error::UNSUPPORTED) {
RETURN_IF_HWC_ERROR(error, displayId, INVALID_OPERATION);
}
- if (error == HWC2::Error::BadParameter) {
+ if (error == hal::Error::BAD_PARAMETER) {
RETURN_IF_HWC_ERROR(error, displayId, BAD_VALUE);
}
RETURN_IF_HWC_ERROR(error, displayId, UNKNOWN_ERROR);
@@ -819,10 +814,10 @@
status_t HWComposer::setAutoLowLatencyMode(DisplayId displayId, bool on) {
RETURN_IF_INVALID_DISPLAY(displayId, BAD_INDEX);
const auto error = mDisplayData[displayId].hwcDisplay->setAutoLowLatencyMode(on);
- if (error == HWC2::Error::Unsupported) {
+ if (error == hal::Error::UNSUPPORTED) {
RETURN_IF_HWC_ERROR(error, displayId, INVALID_OPERATION);
}
- if (error == HWC2::Error::BadParameter) {
+ if (error == hal::Error::BAD_PARAMETER) {
RETURN_IF_HWC_ERROR(error, displayId, BAD_VALUE);
}
RETURN_IF_HWC_ERROR(error, displayId, UNKNOWN_ERROR);
@@ -830,7 +825,7 @@
}
status_t HWComposer::getSupportedContentTypes(
- DisplayId displayId, std::vector<HWC2::ContentType>* outSupportedContentTypes) {
+ DisplayId displayId, std::vector<hal::ContentType>* outSupportedContentTypes) {
RETURN_IF_INVALID_DISPLAY(displayId, BAD_INDEX);
const auto error =
mDisplayData[displayId].hwcDisplay->getSupportedContentTypes(outSupportedContentTypes);
@@ -840,13 +835,13 @@
return NO_ERROR;
}
-status_t HWComposer::setContentType(DisplayId displayId, HWC2::ContentType contentType) {
+status_t HWComposer::setContentType(DisplayId displayId, hal::ContentType contentType) {
RETURN_IF_INVALID_DISPLAY(displayId, BAD_INDEX);
const auto error = mDisplayData[displayId].hwcDisplay->setContentType(contentType);
- if (error == HWC2::Error::Unsupported) {
+ if (error == hal::Error::UNSUPPORTED) {
RETURN_IF_HWC_ERROR(error, displayId, INVALID_OPERATION);
}
- if (error == HWC2::Error::BadParameter) {
+ if (error == hal::Error::BAD_PARAMETER) {
RETURN_IF_HWC_ERROR(error, displayId, BAD_VALUE);
}
RETURN_IF_HWC_ERROR(error, displayId, UNKNOWN_ERROR);
@@ -862,7 +857,7 @@
result.append(mComposer->dumpDebugInfo());
}
-std::optional<DisplayId> HWComposer::toPhysicalDisplayId(hwc2_display_t hwcDisplayId) const {
+std::optional<DisplayId> HWComposer::toPhysicalDisplayId(hal::HWDisplayId hwcDisplayId) const {
if (const auto it = mPhysicalDisplayIdMap.find(hwcDisplayId);
it != mPhysicalDisplayIdMap.end()) {
return it->second;
@@ -870,7 +865,7 @@
return {};
}
-std::optional<hwc2_display_t> HWComposer::fromPhysicalDisplayId(DisplayId displayId) const {
+std::optional<hal::HWDisplayId> HWComposer::fromPhysicalDisplayId(DisplayId displayId) const {
if (const auto it = mDisplayData.find(displayId);
it != mDisplayData.end() && !it->second.isVirtual) {
return it->second.hwcDisplay->getId();
@@ -878,7 +873,7 @@
return {};
}
-bool HWComposer::shouldIgnoreHotplugConnect(hwc2_display_t hwcDisplayId,
+bool HWComposer::shouldIgnoreHotplugConnect(hal::HWDisplayId hwcDisplayId,
bool hasDisplayIdentificationData) const {
if (isUsingVrComposer() && mInternalHwcDisplayId) {
ALOGE("Ignoring connection of external display %" PRIu64 " in VR mode", hwcDisplayId);
@@ -899,7 +894,8 @@
return false;
}
-std::optional<DisplayIdentificationInfo> HWComposer::onHotplugConnect(hwc2_display_t hwcDisplayId) {
+std::optional<DisplayIdentificationInfo> HWComposer::onHotplugConnect(
+ hal::HWDisplayId hwcDisplayId) {
std::optional<DisplayIdentificationInfo> info;
if (const auto displayId = toPhysicalDisplayId(hwcDisplayId)) {
info = DisplayIdentificationInfo{.id = *displayId,
@@ -930,7 +926,7 @@
} else {
ALOGW_IF(hasDisplayIdentificationData,
"Ignoring identification data for display %" PRIu64, hwcDisplayId);
- port = isPrimary ? HWC_DISPLAY_PRIMARY : HWC_DISPLAY_EXTERNAL;
+ port = isPrimary ? LEGACY_DISPLAY_TYPE_PRIMARY : LEGACY_DISPLAY_TYPE_EXTERNAL;
}
return DisplayIdentificationInfo{.id = getFallbackDisplayId(port),
@@ -947,7 +943,7 @@
}
std::optional<DisplayIdentificationInfo> HWComposer::onHotplugDisconnect(
- hwc2_display_t hwcDisplayId) {
+ hal::HWDisplayId hwcDisplayId) {
const auto displayId = toPhysicalDisplayId(hwcDisplayId);
if (!displayId) {
ALOGE("Ignoring disconnection of invalid HWC display %" PRIu64, hwcDisplayId);
@@ -969,10 +965,10 @@
}
void HWComposer::loadCapabilities() {
- static_assert(sizeof(HWC2::Capability) == sizeof(int32_t), "Capability size has changed");
+ static_assert(sizeof(hal::Capability) == sizeof(int32_t), "Capability size has changed");
auto capabilities = mComposer->getCapabilities();
for (auto capability : capabilities) {
- mCapabilities.emplace(static_cast<HWC2::Capability>(capability));
+ mCapabilities.emplace(static_cast<hal::Capability>(capability));
}
}
diff --git a/services/surfaceflinger/DisplayHardware/HWComposer.h b/services/surfaceflinger/DisplayHardware/HWComposer.h
index e18419a..cfa2193 100644
--- a/services/surfaceflinger/DisplayHardware/HWComposer.h
+++ b/services/surfaceflinger/DisplayHardware/HWComposer.h
@@ -39,9 +39,12 @@
#include "DisplayIdentification.h"
#include "HWC2.h"
+#include "Hal.h"
namespace android {
+namespace hal = hardware::graphics::composer::hal;
+
struct DisplayedFrameStats;
class GraphicBuffer;
class TestableSurfaceFlinger;
@@ -66,18 +69,18 @@
virtual void setConfiguration(HWC2::ComposerCallback* callback, int32_t sequenceId) = 0;
- virtual bool getDisplayIdentificationData(hwc2_display_t hwcDisplayId, uint8_t* outPort,
+ virtual bool getDisplayIdentificationData(hal::HWDisplayId hwcDisplayId, uint8_t* outPort,
DisplayIdentificationData* outData) const = 0;
- virtual bool hasCapability(HWC2::Capability capability) const = 0;
+ virtual bool hasCapability(hal::Capability capability) const = 0;
virtual bool hasDisplayCapability(DisplayId displayId,
- HWC2::DisplayCapability capability) const = 0;
+ hal::DisplayCapability capability) const = 0;
// Attempts to allocate a virtual display and returns its ID if created on the HWC device.
virtual std::optional<DisplayId> allocateVirtualDisplay(uint32_t width, uint32_t height,
ui::PixelFormat* format) = 0;
- virtual void allocatePhysicalDisplay(hwc2_display_t hwcDisplayId, DisplayId displayId) = 0;
+ virtual void allocatePhysicalDisplay(hal::HWDisplayId hwcDisplayId, DisplayId displayId) = 0;
// Attempts to create a new layer on this display
virtual HWC2::Layer* createLayer(DisplayId displayId) = 0;
@@ -85,9 +88,9 @@
virtual void destroyLayer(DisplayId displayId, HWC2::Layer* layer) = 0;
struct DeviceRequestedChanges {
- using ChangedTypes = std::unordered_map<HWC2::Layer*, HWC2::Composition>;
- using DisplayRequests = HWC2::DisplayRequest;
- using LayerRequests = std::unordered_map<HWC2::Layer*, HWC2::LayerRequest>;
+ using ChangedTypes = std::unordered_map<HWC2::Layer*, hal::Composition>;
+ using DisplayRequests = hal::DisplayRequest;
+ using LayerRequests = std::unordered_map<HWC2::Layer*, hal::LayerRequest>;
ChangedTypes changedTypes;
DisplayRequests displayRequests;
@@ -113,7 +116,7 @@
virtual status_t presentAndGetReleaseFences(DisplayId displayId) = 0;
// set power mode
- virtual status_t setPowerMode(DisplayId displayId, int mode) = 0;
+ virtual status_t setPowerMode(DisplayId displayId, hal::PowerMode mode) = 0;
// Sets a color transform to be applied to the result of composition
virtual status_t setColorTransform(DisplayId displayId, const mat4& transform) = 0;
@@ -167,11 +170,11 @@
// Returns stable display ID (and display name on connection of new or previously disconnected
// display), or std::nullopt if hotplug event was ignored.
// This function is called from SurfaceFlinger.
- virtual std::optional<DisplayIdentificationInfo> onHotplug(hwc2_display_t hwcDisplayId,
- HWC2::Connection connection) = 0;
+ virtual std::optional<DisplayIdentificationInfo> onHotplug(hal::HWDisplayId hwcDisplayId,
+ hal::Connection connection) = 0;
- virtual bool onVsync(hwc2_display_t hwcDisplayId, int64_t timestamp) = 0;
- virtual void setVsyncEnabled(DisplayId displayId, HWC2::Vsync enabled) = 0;
+ virtual bool onVsync(hal::HWDisplayId hwcDisplayId, int64_t timestamp) = 0;
+ virtual void setVsyncEnabled(DisplayId displayId, hal::Vsync enabled) = 0;
virtual nsecs_t getRefreshTimestamp(DisplayId displayId) const = 0;
virtual bool isConnected(DisplayId displayId) const = 0;
@@ -197,12 +200,12 @@
virtual nsecs_t getDisplayVsyncPeriod(DisplayId displayId) const = 0;
virtual status_t setActiveConfigWithConstraints(
DisplayId displayId, size_t configId,
- const HWC2::VsyncPeriodChangeConstraints& constraints,
- HWC2::VsyncPeriodChangeTimeline* outTimeline) = 0;
+ const hal::VsyncPeriodChangeConstraints& constraints,
+ hal::VsyncPeriodChangeTimeline* outTimeline) = 0;
virtual status_t setAutoLowLatencyMode(DisplayId displayId, bool on) = 0;
virtual status_t getSupportedContentTypes(
- DisplayId displayId, std::vector<HWC2::ContentType>* outSupportedContentTypes) = 0;
- virtual status_t setContentType(DisplayId displayId, HWC2::ContentType contentType) = 0;
+ DisplayId displayId, std::vector<hal::ContentType>* outSupportedContentTypes) = 0;
+ virtual status_t setContentType(DisplayId displayId, hal::ContentType contentType) = 0;
virtual const std::unordered_map<std::string, bool>& getSupportedLayerGenericMetadata()
const = 0;
@@ -212,11 +215,11 @@
virtual Hwc2::Composer* getComposer() const = 0;
// TODO(b/74619554): Remove special cases for internal/external display.
- virtual std::optional<hwc2_display_t> getInternalHwcDisplayId() const = 0;
- virtual std::optional<hwc2_display_t> getExternalHwcDisplayId() const = 0;
+ virtual std::optional<hal::HWDisplayId> getInternalHwcDisplayId() const = 0;
+ virtual std::optional<hal::HWDisplayId> getExternalHwcDisplayId() const = 0;
- virtual std::optional<DisplayId> toPhysicalDisplayId(hwc2_display_t hwcDisplayId) const = 0;
- virtual std::optional<hwc2_display_t> fromPhysicalDisplayId(DisplayId displayId) const = 0;
+ virtual std::optional<DisplayId> toPhysicalDisplayId(hal::HWDisplayId hwcDisplayId) const = 0;
+ virtual std::optional<hal::HWDisplayId> fromPhysicalDisplayId(DisplayId displayId) const = 0;
};
namespace impl {
@@ -230,19 +233,19 @@
void setConfiguration(HWC2::ComposerCallback* callback, int32_t sequenceId) override;
- bool getDisplayIdentificationData(hwc2_display_t hwcDisplayId, uint8_t* outPort,
+ bool getDisplayIdentificationData(hal::HWDisplayId hwcDisplayId, uint8_t* outPort,
DisplayIdentificationData* outData) const override;
- bool hasCapability(HWC2::Capability capability) const override;
+ bool hasCapability(hal::Capability capability) const override;
bool hasDisplayCapability(DisplayId displayId,
- HWC2::DisplayCapability capability) const override;
+ hal::DisplayCapability capability) const override;
// Attempts to allocate a virtual display and returns its ID if created on the HWC device.
std::optional<DisplayId> allocateVirtualDisplay(uint32_t width, uint32_t height,
ui::PixelFormat* format) override;
// Called from SurfaceFlinger, when the state for a new physical display needs to be recreated.
- void allocatePhysicalDisplay(hwc2_display_t hwcDisplayId, DisplayId displayId) override;
+ void allocatePhysicalDisplay(hal::HWDisplayId hwcDisplayId, DisplayId displayId) override;
// Attempts to create a new layer on this display
HWC2::Layer* createLayer(DisplayId displayId) override;
@@ -260,7 +263,7 @@
status_t presentAndGetReleaseFences(DisplayId displayId) override;
// set power mode
- status_t setPowerMode(DisplayId displayId, int mode) override;
+ status_t setPowerMode(DisplayId displayId, hal::PowerMode mode) override;
// Sets a color transform to be applied to the result of composition
status_t setColorTransform(DisplayId displayId, const mat4& transform) override;
@@ -308,11 +311,11 @@
// Returns stable display ID (and display name on connection of new or previously disconnected
// display), or std::nullopt if hotplug event was ignored.
- std::optional<DisplayIdentificationInfo> onHotplug(hwc2_display_t hwcDisplayId,
- HWC2::Connection connection) override;
+ std::optional<DisplayIdentificationInfo> onHotplug(hal::HWDisplayId hwcDisplayId,
+ hal::Connection connection) override;
- bool onVsync(hwc2_display_t hwcDisplayId, int64_t timestamp) override;
- void setVsyncEnabled(DisplayId displayId, HWC2::Vsync enabled) override;
+ bool onVsync(hal::HWDisplayId hwcDisplayId, int64_t timestamp) override;
+ void setVsyncEnabled(DisplayId displayId, hal::Vsync enabled) override;
nsecs_t getRefreshTimestamp(DisplayId displayId) const override;
bool isConnected(DisplayId displayId) const override;
@@ -337,12 +340,11 @@
bool isVsyncPeriodSwitchSupported(DisplayId displayId) const override;
nsecs_t getDisplayVsyncPeriod(DisplayId displayId) const override;
status_t setActiveConfigWithConstraints(DisplayId displayId, size_t configId,
- const HWC2::VsyncPeriodChangeConstraints& constraints,
- HWC2::VsyncPeriodChangeTimeline* outTimeline) override;
+ const hal::VsyncPeriodChangeConstraints& constraints,
+ hal::VsyncPeriodChangeTimeline* outTimeline) override;
status_t setAutoLowLatencyMode(DisplayId displayId, bool) override;
- status_t getSupportedContentTypes(DisplayId displayId,
- std::vector<HWC2::ContentType>*) override;
- status_t setContentType(DisplayId displayId, HWC2::ContentType) override;
+ status_t getSupportedContentTypes(DisplayId displayId, std::vector<hal::ContentType>*) override;
+ status_t setContentType(DisplayId displayId, hal::ContentType) override;
const std::unordered_map<std::string, bool>& getSupportedLayerGenericMetadata() const override;
@@ -352,23 +354,23 @@
Hwc2::Composer* getComposer() const override { return mComposer.get(); }
// TODO(b/74619554): Remove special cases for internal/external display.
- std::optional<hwc2_display_t> getInternalHwcDisplayId() const override {
+ std::optional<hal::HWDisplayId> getInternalHwcDisplayId() const override {
return mInternalHwcDisplayId;
}
- std::optional<hwc2_display_t> getExternalHwcDisplayId() const override {
+ std::optional<hal::HWDisplayId> getExternalHwcDisplayId() const override {
return mExternalHwcDisplayId;
}
- std::optional<DisplayId> toPhysicalDisplayId(hwc2_display_t hwcDisplayId) const override;
- std::optional<hwc2_display_t> fromPhysicalDisplayId(DisplayId displayId) const override;
+ std::optional<DisplayId> toPhysicalDisplayId(hal::HWDisplayId hwcDisplayId) const override;
+ std::optional<hal::HWDisplayId> fromPhysicalDisplayId(DisplayId displayId) const override;
private:
// For unit tests
friend TestableSurfaceFlinger;
- std::optional<DisplayIdentificationInfo> onHotplugConnect(hwc2_display_t hwcDisplayId);
- std::optional<DisplayIdentificationInfo> onHotplugDisconnect(hwc2_display_t hwcDisplayId);
- bool shouldIgnoreHotplugConnect(hwc2_display_t hwcDisplayId,
+ std::optional<DisplayIdentificationInfo> onHotplugConnect(hal::HWDisplayId hwcDisplayId);
+ std::optional<DisplayIdentificationInfo> onHotplugDisconnect(hal::HWDisplayId hwcDisplayId);
+ bool shouldIgnoreHotplugConnect(hal::HWDisplayId hwcDisplayId,
bool hasDisplayIdentificationData) const;
void loadCapabilities();
@@ -386,12 +388,12 @@
std::shared_ptr<const HWC2::Display::Config>> configMap;
bool validateWasSkipped;
- HWC2::Error presentError;
+ hal::Error presentError;
bool vsyncTraceToggle = false;
std::mutex vsyncEnabledLock;
- HWC2::Vsync vsyncEnabled GUARDED_BY(vsyncEnabledLock) = HWC2::Vsync::Disable;
+ hal::Vsync vsyncEnabled GUARDED_BY(vsyncEnabledLock) = hal::Vsync::DISABLE;
mutable std::mutex lastHwVsyncLock;
nsecs_t lastHwVsync GUARDED_BY(lastHwVsyncLock) = 0;
@@ -400,13 +402,13 @@
std::unordered_map<DisplayId, DisplayData> mDisplayData;
std::unique_ptr<android::Hwc2::Composer> mComposer;
- std::unordered_set<HWC2::Capability> mCapabilities;
+ std::unordered_set<hal::Capability> mCapabilities;
std::unordered_map<std::string, bool> mSupportedLayerGenericMetadata;
bool mRegisteredCallback = false;
- std::unordered_map<hwc2_display_t, DisplayId> mPhysicalDisplayIdMap;
- std::optional<hwc2_display_t> mInternalHwcDisplayId;
- std::optional<hwc2_display_t> mExternalHwcDisplayId;
+ std::unordered_map<hal::HWDisplayId, DisplayId> mPhysicalDisplayIdMap;
+ std::optional<hal::HWDisplayId> mInternalHwcDisplayId;
+ std::optional<hal::HWDisplayId> mExternalHwcDisplayId;
bool mHasMultiDisplaySupport = false;
std::unordered_set<DisplayId> mFreeVirtualDisplayIds;
diff --git a/services/surfaceflinger/DisplayHardware/Hal.h b/services/surfaceflinger/DisplayHardware/Hal.h
new file mode 100644
index 0000000..66ee425
--- /dev/null
+++ b/services/surfaceflinger/DisplayHardware/Hal.h
@@ -0,0 +1,168 @@
+/*
+ * Copyright 2020 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 <android/hardware/graphics/common/1.1/types.h>
+#include <android/hardware/graphics/composer/2.4/IComposer.h>
+#include <android/hardware/graphics/composer/2.4/IComposerClient.h>
+
+#define ERROR_HAS_CHANGES 5
+
+namespace android {
+namespace hardware::graphics::composer::hal {
+
+namespace types = android::hardware::graphics::common;
+namespace V2_1 = android::hardware::graphics::composer::V2_1;
+namespace V2_2 = android::hardware::graphics::composer::V2_2;
+namespace V2_3 = android::hardware::graphics::composer::V2_3;
+namespace V2_4 = android::hardware::graphics::composer::V2_4;
+
+using types::V1_0::ColorTransform;
+using types::V1_0::Transform;
+using types::V1_1::RenderIntent;
+using types::V1_2::ColorMode;
+using types::V1_2::Dataspace;
+using types::V1_2::Hdr;
+using types::V1_2::PixelFormat;
+
+using V2_1::Error;
+using V2_4::IComposer;
+using V2_4::IComposerCallback;
+using V2_4::IComposerClient;
+using V2_4::VsyncPeriodChangeTimeline;
+using V2_4::VsyncPeriodNanos;
+
+using Attribute = IComposerClient::Attribute;
+using BlendMode = IComposerClient::BlendMode;
+using Color = IComposerClient::Color;
+using Composition = IComposerClient::Composition;
+using Connection = IComposerCallback::Connection;
+using ContentType = IComposerClient::ContentType;
+using Capability = IComposer::Capability;
+using DisplayCapability = IComposerClient::DisplayCapability;
+using DisplayRequest = IComposerClient::DisplayRequest;
+using DisplayType = IComposerClient::DisplayType;
+using HWConfigId = V2_1::Config;
+using HWDisplayId = V2_1::Display;
+using HWError = V2_1::Error;
+using HWLayerId = V2_1::Layer;
+using LayerGenericMetadataKey = IComposerClient::LayerGenericMetadataKey;
+using LayerRequest = IComposerClient::LayerRequest;
+using PerFrameMetadata = IComposerClient::PerFrameMetadata;
+using PerFrameMetadataKey = IComposerClient::PerFrameMetadataKey;
+using PerFrameMetadataBlob = IComposerClient::PerFrameMetadataBlob;
+using PowerMode = IComposerClient::PowerMode;
+using Vsync = IComposerClient::Vsync;
+using VsyncPeriodChangeConstraints = IComposerClient::VsyncPeriodChangeConstraints;
+
+} // namespace hardware::graphics::composer::hal
+
+inline bool hasChangesError(hardware::graphics::composer::hal::Error error) {
+ return ERROR_HAS_CHANGES == static_cast<int32_t>(error);
+}
+
+inline std::string to_string(hardware::graphics::composer::hal::Attribute attribute) {
+ switch (attribute) {
+ case hardware::graphics::composer::hal::Attribute::INVALID:
+ return "Invalid";
+ case hardware::graphics::composer::hal::Attribute::WIDTH:
+ return "Width";
+ case hardware::graphics::composer::hal::Attribute::HEIGHT:
+ return "Height";
+ case hardware::graphics::composer::hal::Attribute::VSYNC_PERIOD:
+ return "VsyncPeriod";
+ case hardware::graphics::composer::hal::Attribute::DPI_X:
+ return "DpiX";
+ case hardware::graphics::composer::hal::Attribute::DPI_Y:
+ return "DpiY";
+ default:
+ return "Unknown";
+ }
+}
+
+inline std::string to_string(hardware::graphics::composer::hal::Composition composition) {
+ switch (composition) {
+ case hardware::graphics::composer::hal::Composition::INVALID:
+ return "Invalid";
+ case hardware::graphics::composer::hal::Composition::CLIENT:
+ return "Client";
+ case hardware::graphics::composer::hal::Composition::DEVICE:
+ return "Device";
+ case hardware::graphics::composer::hal::Composition::SOLID_COLOR:
+ return "SolidColor";
+ case hardware::graphics::composer::hal::Composition::CURSOR:
+ return "Cursor";
+ case hardware::graphics::composer::hal::Composition::SIDEBAND:
+ return "Sideband";
+ default:
+ return "Unknown";
+ }
+}
+
+inline std::string to_string(hardware::graphics::composer::hal::V2_4::Error error) {
+ // 5 is reserved for historical reason, during validation 5 means has changes.
+ if (ERROR_HAS_CHANGES == static_cast<int32_t>(error)) {
+ return "HasChanges";
+ }
+ switch (error) {
+ case hardware::graphics::composer::hal::V2_4::Error::NONE:
+ return "None";
+ case hardware::graphics::composer::hal::V2_4::Error::BAD_CONFIG:
+ return "BadConfig";
+ case hardware::graphics::composer::hal::V2_4::Error::BAD_DISPLAY:
+ return "BadDisplay";
+ case hardware::graphics::composer::hal::V2_4::Error::BAD_LAYER:
+ return "BadLayer";
+ case hardware::graphics::composer::hal::V2_4::Error::BAD_PARAMETER:
+ return "BadParameter";
+ case hardware::graphics::composer::hal::V2_4::Error::NO_RESOURCES:
+ return "NoResources";
+ case hardware::graphics::composer::hal::V2_4::Error::NOT_VALIDATED:
+ return "NotValidated";
+ case hardware::graphics::composer::hal::V2_4::Error::UNSUPPORTED:
+ return "Unsupported";
+ case hardware::graphics::composer::hal::V2_4::Error::SEAMLESS_NOT_ALLOWED:
+ return "SeamlessNotAllowed";
+ case hardware::graphics::composer::hal::V2_4::Error::SEAMLESS_NOT_POSSIBLE:
+ return "SeamlessNotPossible";
+ default:
+ return "Unknown";
+ }
+}
+
+inline std::string to_string(hardware::graphics::composer::hal::Error error) {
+ return to_string(static_cast<hardware::graphics::composer::hal::V2_4::Error>(error));
+}
+
+inline std::string to_string(hardware::graphics::composer::hal::PowerMode mode) {
+ switch (mode) {
+ case hardware::graphics::composer::hal::PowerMode::OFF:
+ return "Off";
+ case hardware::graphics::composer::hal::PowerMode::DOZE:
+ return "Doze";
+ case hardware::graphics::composer::hal::PowerMode::ON:
+ return "On";
+ case hardware::graphics::composer::hal::PowerMode::DOZE_SUSPEND:
+ return "DozeSuspend";
+ case hardware::graphics::composer::hal::PowerMode::ON_SUSPEND:
+ return "OnSuspend";
+ default:
+ return "Unknown";
+ }
+}
+
+} // namespace android
diff --git a/services/surfaceflinger/DisplayHardware/PowerAdvisor.h b/services/surfaceflinger/DisplayHardware/PowerAdvisor.h
index 4a90acb..34e63e7 100644
--- a/services/surfaceflinger/DisplayHardware/PowerAdvisor.h
+++ b/services/surfaceflinger/DisplayHardware/PowerAdvisor.h
@@ -16,12 +16,6 @@
#pragma once
-#define HWC2_INCLUDE_STRINGIFICATION
-#define HWC2_USE_CPP11
-#include <hardware/hwcomposer2.h>
-#undef HWC2_INCLUDE_STRINGIFICATION
-#undef HWC2_USE_CPP11
-
#include <atomic>
#include <unordered_set>
diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp
index 5039761..8452957 100644
--- a/services/surfaceflinger/Layer.cpp
+++ b/services/surfaceflinger/Layer.cpp
@@ -220,9 +220,6 @@
}
mFlinger->markLayerPendingRemovalLocked(this);
- if (hasInput()) {
- mFlinger->dirtyInput();
- }
}
void Layer::onRemovedFromCurrentState() {
@@ -998,8 +995,6 @@
mPendingStatesSnapshot = mPendingStates;
mCurrentState.callbackHandles = {};
- maybeDirtyInput();
-
return flags;
}
@@ -1384,6 +1379,9 @@
return false;
}
+ // Activate the layer in Scheduler's LayerHistory
+ mFlinger->mScheduler->recordLayerHistory(this, systemTime());
+
mCurrentState.sequence++;
mCurrentState.frameRate = frameRate;
mCurrentState.modified = true;
@@ -2545,32 +2543,6 @@
}
}
-bool Layer::maybeDirtyInput() {
- // No sense redirtying input.
- if (mFlinger->inputDirty()) return true;
-
- if (hasInput()) {
- mFlinger->dirtyInput();
- return true;
- }
-
- // If a child or relative dirties the input, no sense continuing to traverse
- // so we return early and halt the recursion. We traverse ourselves instead
- // of using traverse() so we can implement this early halt.
- for (const sp<Layer>& child : mDrawingChildren) {
- if (child->maybeDirtyInput()) {
- return true;
- }
- }
- for (const wp<Layer>& weakRelative : mDrawingState.zOrderRelatives) {
- sp<Layer> relative = weakRelative.promote();
- if (relative && relative->maybeDirtyInput()) {
- return true;
- }
- }
- return false;
-}
-
// ---------------------------------------------------------------------------
}; // namespace android
diff --git a/services/surfaceflinger/Layer.h b/services/surfaceflinger/Layer.h
index 92ac015..6636b5e 100644
--- a/services/surfaceflinger/Layer.h
+++ b/services/surfaceflinger/Layer.h
@@ -1015,10 +1015,6 @@
// Window types from WindowManager.LayoutParams
const int mWindowType;
- // Called when mDrawingState has changed. If we or one of our children/relatives hasInput()
- // then we will dirty the setInputWindows cache.
- bool maybeDirtyInput();
-
private:
/**
* Returns an unsorted vector of all layers that are part of this tree.
diff --git a/services/surfaceflinger/MonitoredProducer.cpp b/services/surfaceflinger/MonitoredProducer.cpp
index 5009e10..18a2891 100644
--- a/services/surfaceflinger/MonitoredProducer.cpp
+++ b/services/surfaceflinger/MonitoredProducer.cpp
@@ -38,13 +38,7 @@
// because we don't know where this destructor is called from. It could be
// called with the mStateLock held, leading to a dead-lock (it actually
// happens).
- sp<LambdaMessage> cleanUpListMessage =
- new LambdaMessage([flinger = mFlinger, asBinder = wp<IBinder>(onAsBinder())]() {
- Mutex::Autolock lock(flinger->mStateLock);
- flinger->mGraphicBufferProducerList.erase(asBinder);
- });
-
- mFlinger->postMessageAsync(cleanUpListMessage);
+ mFlinger->removeGraphicBufferProducerAsync(onAsBinder());
}
status_t MonitoredProducer::requestBuffer(int slot, sp<GraphicBuffer>* buf) {
diff --git a/services/surfaceflinger/Promise.h b/services/surfaceflinger/Promise.h
new file mode 100644
index 0000000..a80d441
--- /dev/null
+++ b/services/surfaceflinger/Promise.h
@@ -0,0 +1,80 @@
+/*
+ * Copyright 2020 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 <future>
+#include <type_traits>
+#include <utility>
+
+namespace android::promise {
+namespace impl {
+
+template <typename T>
+struct FutureResult {
+ using Type = T;
+};
+
+template <typename T>
+struct FutureResult<std::future<T>> {
+ using Type = T;
+};
+
+} // namespace impl
+
+template <typename T>
+using FutureResult = typename impl::FutureResult<T>::Type;
+
+template <typename... Args>
+inline auto defer(Args... args) {
+ return std::async(std::launch::deferred, std::forward<Args>(args)...);
+}
+
+template <typename T>
+inline std::future<T> yield(T&& v) {
+ return defer([](T&& v) { return std::forward<T>(v); }, std::forward<T>(v));
+}
+
+template <typename T>
+struct Chain {
+ Chain(std::future<T>&& f) : future(std::move(f)) {}
+ operator std::future<T>&&() && { return std::move(future); }
+
+ T get() && { return future.get(); }
+
+ template <typename F, typename R = std::invoke_result_t<F, T>>
+ auto then(F&& op) && -> Chain<FutureResult<R>> {
+ return defer(
+ [](auto&& f, F&& op) {
+ R r = op(f.get());
+ if constexpr (std::is_same_v<R, FutureResult<R>>) {
+ return r;
+ } else {
+ return r.get();
+ }
+ },
+ std::move(future), std::forward<F>(op));
+ }
+
+ std::future<T> future;
+};
+
+template <typename T>
+inline Chain<T> chain(std::future<T>&& f) {
+ return std::move(f);
+}
+
+} // namespace android::promise
diff --git a/services/surfaceflinger/RefreshRateOverlay.cpp b/services/surfaceflinger/RefreshRateOverlay.cpp
index 0a0f2f1..2e7fbc1 100644
--- a/services/surfaceflinger/RefreshRateOverlay.cpp
+++ b/services/surfaceflinger/RefreshRateOverlay.cpp
@@ -116,9 +116,13 @@
sp<GraphicBuffer> buffer =
new GraphicBuffer(BUFFER_WIDTH, BUFFER_HEIGHT, HAL_PIXEL_FORMAT_RGBA_8888, 1,
- GRALLOC_USAGE_SW_WRITE_RARELY, "RefreshRateOverlayBuffer");
+ GRALLOC_USAGE_SW_WRITE_RARELY | GRALLOC_USAGE_HW_COMPOSER |
+ GRALLOC_USAGE_HW_TEXTURE,
+ "RefreshRateOverlayBuffer");
uint8_t* pixels;
buffer->lock(GRALLOC_USAGE_SW_WRITE_RARELY, reinterpret_cast<void**>(&pixels));
+ // Clear buffer content
+ drawRect(Rect(BUFFER_WIDTH, BUFFER_HEIGHT), half4(0), buffer, pixels);
int left = 0;
if (hundreds != 0) {
drawDigit(hundreds, left, color, buffer, pixels);
diff --git a/services/surfaceflinger/RegionSamplingThread.cpp b/services/surfaceflinger/RegionSamplingThread.cpp
index 68cd84f..27353d8 100644
--- a/services/surfaceflinger/RegionSamplingThread.cpp
+++ b/services/surfaceflinger/RegionSamplingThread.cpp
@@ -130,7 +130,7 @@
mVsyncListening = false;
}
- void onDispSyncEvent(nsecs_t /* when */) final {
+ void onDispSyncEvent(nsecs_t /*when*/, nsecs_t /*expectedVSyncTimestamp*/) final {
std::unique_lock<decltype(mMutex)> lock(mMutex);
if (mPhaseIntervalSetting == Phase::ZERO) {
@@ -199,13 +199,8 @@
}
}
-void RegionSamplingThread::addListener(const Rect& samplingArea, const sp<IBinder>& stopLayerHandle,
+void RegionSamplingThread::addListener(const Rect& samplingArea, const wp<Layer>& stopLayer,
const sp<IRegionSamplingListener>& listener) {
- wp<Layer> stopLayer;
- if (stopLayerHandle != nullptr && stopLayerHandle->localBinder() != nullptr) {
- stopLayer = static_cast<Layer::Handle*>(stopLayerHandle.get())->owner;
- }
-
sp<IBinder> asBinder = IInterface::asBinder(listener);
asBinder->linkToDeath(this);
std::lock_guard lock(mSamplingMutex);
@@ -430,7 +425,8 @@
}
bool ignored;
- mFlinger.captureScreenCommon(renderArea, traverseLayers, buffer, false, ignored);
+ mFlinger.captureScreenCommon(renderArea, traverseLayers, buffer, false /* identityTransform */,
+ true /* regionSampling */, ignored);
std::vector<Descriptor> activeDescriptors;
for (const auto& descriptor : descriptors) {
diff --git a/services/surfaceflinger/RegionSamplingThread.h b/services/surfaceflinger/RegionSamplingThread.h
index 99c07c2..b9b7a3c 100644
--- a/services/surfaceflinger/RegionSamplingThread.h
+++ b/services/surfaceflinger/RegionSamplingThread.h
@@ -69,7 +69,7 @@
// Add a listener to receive luma notifications. The luma reported via listener will
// report the median luma for the layers under the stopLayerHandle, in the samplingArea region.
- void addListener(const Rect& samplingArea, const sp<IBinder>& stopLayerHandle,
+ void addListener(const Rect& samplingArea, const wp<Layer>& stopLayer,
const sp<IRegionSamplingListener>& listener);
// Remove the listener to stop receiving median luma notifications.
void removeListener(const sp<IRegionSamplingListener>& listener);
diff --git a/services/surfaceflinger/Scheduler/DispSync.cpp b/services/surfaceflinger/Scheduler/DispSync.cpp
index 809a0e5..ff91bf7 100644
--- a/services/surfaceflinger/Scheduler/DispSync.cpp
+++ b/services/surfaceflinger/Scheduler/DispSync.cpp
@@ -200,7 +200,8 @@
}
}
- callbackInvocations = gatherCallbackInvocationsLocked(now);
+ callbackInvocations =
+ gatherCallbackInvocationsLocked(now, computeNextRefreshLocked(0, now));
}
if (callbackInvocations.size() > 0) {
@@ -303,6 +304,11 @@
return BAD_VALUE;
}
+ nsecs_t computeNextRefresh(int periodOffset, nsecs_t now) const {
+ Mutex::Autolock lock(mMutex);
+ return computeNextRefreshLocked(periodOffset, now);
+ }
+
private:
struct EventListener {
const char* mName;
@@ -315,6 +321,7 @@
struct CallbackInvocation {
DispSync::Callback* mCallback;
nsecs_t mEventTime;
+ nsecs_t mExpectedVSyncTime;
};
nsecs_t computeNextEventTimeLocked(nsecs_t now) {
@@ -340,7 +347,8 @@
return duration < (3 * mPeriod) / 5;
}
- std::vector<CallbackInvocation> gatherCallbackInvocationsLocked(nsecs_t now) {
+ std::vector<CallbackInvocation> gatherCallbackInvocationsLocked(nsecs_t now,
+ nsecs_t expectedVSyncTime) {
if (mTraceDetailedInfo) ATRACE_CALL();
ALOGV("[%s] gatherCallbackInvocationsLocked @ %" PRId64, mName, ns2us(now));
@@ -361,6 +369,10 @@
CallbackInvocation ci;
ci.mCallback = eventListener.mCallback;
ci.mEventTime = t;
+ ci.mExpectedVSyncTime = expectedVSyncTime;
+ if (eventListener.mPhase < 0) {
+ ci.mExpectedVSyncTime += mPeriod;
+ }
ALOGV("[%s] [%s] Preparing to fire, latency: %" PRId64, mName, eventListener.mName,
t - eventListener.mLastEventTime);
callbackInvocations.push_back(ci);
@@ -426,10 +438,19 @@
void fireCallbackInvocations(const std::vector<CallbackInvocation>& callbacks) {
if (mTraceDetailedInfo) ATRACE_CALL();
for (size_t i = 0; i < callbacks.size(); i++) {
- callbacks[i].mCallback->onDispSyncEvent(callbacks[i].mEventTime);
+ callbacks[i].mCallback->onDispSyncEvent(callbacks[i].mEventTime,
+ callbacks[i].mExpectedVSyncTime);
}
}
+ nsecs_t computeNextRefreshLocked(int periodOffset, nsecs_t now) const {
+ nsecs_t phase = mReferenceTime + mPhase;
+ if (mPeriod == 0) {
+ return 0;
+ }
+ return (((now - phase) / mPeriod) + periodOffset + 1) * mPeriod + phase;
+ }
+
const char* const mName;
bool mStop;
@@ -444,7 +465,7 @@
std::vector<EventListener> mEventListeners;
- Mutex mMutex;
+ mutable Mutex mMutex;
Condition mCond;
// Flag to turn on logging in systrace.
@@ -458,7 +479,7 @@
public:
ZeroPhaseTracer() : mParity("ZERO_PHASE_VSYNC", false) {}
- virtual void onDispSyncEvent(nsecs_t /*when*/) {
+ virtual void onDispSyncEvent(nsecs_t /*when*/, nsecs_t /*expectedVSyncTimestamp*/) {
mParity = !mParity;
}
@@ -768,9 +789,8 @@
}
}
-nsecs_t DispSync::computeNextRefresh(int periodOffset) const {
+nsecs_t DispSync::computeNextRefresh(int periodOffset, nsecs_t now) const {
Mutex::Autolock lock(mMutex);
- nsecs_t now = systemTime(SYSTEM_TIME_MONOTONIC);
nsecs_t phase = mReferenceTime + mPhase;
if (mPeriod == 0) {
return 0;
@@ -837,7 +857,7 @@
StringAppendF(&result, "current monotonic time: %" PRId64 "\n", now);
}
-nsecs_t DispSync::expectedPresentTime() {
+nsecs_t DispSync::expectedPresentTime(nsecs_t now) {
// The HWC doesn't currently have a way to report additional latency.
// Assume that whatever we submit now will appear right after the flip.
// For a smart panel this might be 1. This is expressed in frames,
@@ -846,7 +866,7 @@
const uint32_t hwcLatency = 0;
// Ask DispSync when the next refresh will be (CLOCK_MONOTONIC).
- return computeNextRefresh(hwcLatency);
+ return mThread->computeNextRefresh(hwcLatency, now);
}
} // namespace impl
diff --git a/services/surfaceflinger/Scheduler/DispSync.h b/services/surfaceflinger/Scheduler/DispSync.h
index 2d9afc9..832f08e 100644
--- a/services/surfaceflinger/Scheduler/DispSync.h
+++ b/services/surfaceflinger/Scheduler/DispSync.h
@@ -36,7 +36,7 @@
public:
Callback() = default;
virtual ~Callback();
- virtual void onDispSyncEvent(nsecs_t when) = 0;
+ virtual void onDispSyncEvent(nsecs_t when, nsecs_t expectedVSyncTimestamp) = 0;
protected:
Callback(Callback const&) = delete;
@@ -58,9 +58,9 @@
nsecs_t lastCallbackTime) = 0;
virtual status_t removeEventListener(Callback* callback, nsecs_t* outLastCallback) = 0;
virtual status_t changePhaseOffset(Callback* callback, nsecs_t phase) = 0;
- virtual nsecs_t computeNextRefresh(int periodOffset) const = 0;
+ virtual nsecs_t computeNextRefresh(int periodOffset, nsecs_t now) const = 0;
virtual void setIgnorePresentFences(bool ignore) = 0;
- virtual nsecs_t expectedPresentTime() = 0;
+ virtual nsecs_t expectedPresentTime(nsecs_t now) = 0;
virtual void dump(std::string& result) const = 0;
@@ -167,7 +167,7 @@
// The periodOffset value can be used to move forward or backward; an
// offset of zero is the next refresh, -1 is the previous refresh, 1 is
// the refresh after next. etc.
- nsecs_t computeNextRefresh(int periodOffset) const override;
+ nsecs_t computeNextRefresh(int periodOffset, nsecs_t now) const override;
// In certain situations the present fences aren't a good indicator of vsync
// time, e.g. when vr flinger is active, or simply aren't available,
@@ -178,7 +178,7 @@
void setIgnorePresentFences(bool ignore) override;
// Determine the expected present time when a buffer acquired now will be displayed.
- nsecs_t expectedPresentTime();
+ nsecs_t expectedPresentTime(nsecs_t now);
// dump appends human-readable debug info to the result string.
void dump(std::string& result) const override;
diff --git a/services/surfaceflinger/Scheduler/DispSyncSource.cpp b/services/surfaceflinger/Scheduler/DispSyncSource.cpp
index 4e3f85f..8752b66 100644
--- a/services/surfaceflinger/Scheduler/DispSyncSource.cpp
+++ b/services/surfaceflinger/Scheduler/DispSyncSource.cpp
@@ -92,7 +92,7 @@
}
}
-void DispSyncSource::onDispSyncEvent(nsecs_t when) {
+void DispSyncSource::onDispSyncEvent(nsecs_t when, nsecs_t expectedVSyncTimestamp) {
VSyncSource::Callback* callback;
{
std::lock_guard lock(mCallbackMutex);
@@ -104,7 +104,7 @@
}
if (callback != nullptr) {
- callback->onVSyncEvent(when);
+ callback->onVSyncEvent(when, expectedVSyncTimestamp);
}
}
diff --git a/services/surfaceflinger/Scheduler/DispSyncSource.h b/services/surfaceflinger/Scheduler/DispSyncSource.h
index f278712..2aee3f6 100644
--- a/services/surfaceflinger/Scheduler/DispSyncSource.h
+++ b/services/surfaceflinger/Scheduler/DispSyncSource.h
@@ -40,7 +40,7 @@
private:
// The following method is the implementation of the DispSync::Callback.
- virtual void onDispSyncEvent(nsecs_t when);
+ void onDispSyncEvent(nsecs_t when, nsecs_t expectedVSyncTimestamp) override;
const char* const mName;
TracedOrdinal<int> mValue;
diff --git a/services/surfaceflinger/Scheduler/EventThread.cpp b/services/surfaceflinger/Scheduler/EventThread.cpp
index 8347650..5dedb6a 100644
--- a/services/surfaceflinger/Scheduler/EventThread.cpp
+++ b/services/surfaceflinger/Scheduler/EventThread.cpp
@@ -79,8 +79,9 @@
event.hotplug.connected ? "connected" : "disconnected");
case DisplayEventReceiver::DISPLAY_EVENT_VSYNC:
return StringPrintf("VSync{displayId=%" ANDROID_PHYSICAL_DISPLAY_ID_FORMAT
- ", count=%u}",
- event.header.displayId, event.vsync.count);
+ ", count=%u, expectedVSyncTimestamp=%" PRId64 "}",
+ event.header.displayId, event.vsync.count,
+ event.vsync.expectedVSyncTimestamp);
case DisplayEventReceiver::DISPLAY_EVENT_CONFIG_CHANGED:
return StringPrintf("ConfigChanged{displayId=%" ANDROID_PHYSICAL_DISPLAY_ID_FORMAT
", configId=%u}",
@@ -99,10 +100,11 @@
}
DisplayEventReceiver::Event makeVSync(PhysicalDisplayId displayId, nsecs_t timestamp,
- uint32_t count) {
+ uint32_t count, nsecs_t expectedVSyncTimestamp) {
DisplayEventReceiver::Event event;
event.header = {DisplayEventReceiver::DISPLAY_EVENT_VSYNC, displayId, timestamp};
event.vsync.count = count;
+ event.vsync.expectedVSyncTimestamp = expectedVSyncTimestamp;
return event;
}
@@ -312,11 +314,12 @@
mCondition.notify_all();
}
-void EventThread::onVSyncEvent(nsecs_t timestamp) {
+void EventThread::onVSyncEvent(nsecs_t timestamp, nsecs_t expectedVSyncTimestamp) {
std::lock_guard<std::mutex> lock(mMutex);
LOG_FATAL_IF(!mVSyncState);
- mPendingEvents.push_back(makeVSync(mVSyncState->displayId, timestamp, ++mVSyncState->count));
+ mPendingEvents.push_back(makeVSync(mVSyncState->displayId, timestamp, ++mVSyncState->count,
+ expectedVSyncTimestamp));
mCondition.notify_all();
}
@@ -423,7 +426,8 @@
} else {
// Generate a fake VSYNC after a long timeout in case the driver stalls. When the
// display is off, keep feeding clients at 60 Hz.
- const auto timeout = mState == State::SyntheticVSync ? 16ms : 1000ms;
+ const std::chrono::nanoseconds timeout =
+ mState == State::SyntheticVSync ? 16ms : 1000ms;
if (mCondition.wait_for(lock, timeout) == std::cv_status::timeout) {
if (mState == State::VSync) {
ALOGW("Faking VSYNC due to driver stall for thread %s", mThreadName);
@@ -439,9 +443,10 @@
}
LOG_FATAL_IF(!mVSyncState);
- mPendingEvents.push_back(makeVSync(mVSyncState->displayId,
- systemTime(SYSTEM_TIME_MONOTONIC),
- ++mVSyncState->count));
+ const auto now = systemTime(SYSTEM_TIME_MONOTONIC);
+ const auto expectedVSyncTime = now + timeout.count();
+ mPendingEvents.push_back(makeVSync(mVSyncState->displayId, now,
+ ++mVSyncState->count, expectedVSyncTime));
}
}
}
diff --git a/services/surfaceflinger/Scheduler/EventThread.h b/services/surfaceflinger/Scheduler/EventThread.h
index 98b1876..9e7086e 100644
--- a/services/surfaceflinger/Scheduler/EventThread.h
+++ b/services/surfaceflinger/Scheduler/EventThread.h
@@ -57,7 +57,7 @@
class Callback {
public:
virtual ~Callback() {}
- virtual void onVSyncEvent(nsecs_t when) = 0;
+ virtual void onVSyncEvent(nsecs_t when, nsecs_t expectedVSyncTimestamp) = 0;
};
virtual ~VSyncSource() {}
@@ -189,7 +189,7 @@
REQUIRES(mMutex);
// Implements VSyncSource::Callback
- void onVSyncEvent(nsecs_t timestamp) override;
+ void onVSyncEvent(nsecs_t timestamp, nsecs_t expectedVSyncTimestamp) override;
const std::unique_ptr<VSyncSource> mVSyncSource GUARDED_BY(mMutex);
diff --git a/services/surfaceflinger/Scheduler/InjectVSyncSource.h b/services/surfaceflinger/Scheduler/InjectVSyncSource.h
index 31da588..975c9db 100644
--- a/services/surfaceflinger/Scheduler/InjectVSyncSource.h
+++ b/services/surfaceflinger/Scheduler/InjectVSyncSource.h
@@ -35,10 +35,10 @@
mCallback = callback;
}
- void onInjectSyncEvent(nsecs_t when) {
+ void onInjectSyncEvent(nsecs_t when, nsecs_t expectedVSyncTimestamp) {
std::lock_guard<std::mutex> lock(mCallbackMutex);
if (mCallback) {
- mCallback->onVSyncEvent(when);
+ mCallback->onVSyncEvent(when, expectedVSyncTimestamp);
}
}
diff --git a/services/surfaceflinger/Scheduler/LayerHistoryV2.cpp b/services/surfaceflinger/Scheduler/LayerHistoryV2.cpp
index 8b08592..b067466 100644
--- a/services/surfaceflinger/Scheduler/LayerHistoryV2.cpp
+++ b/services/surfaceflinger/Scheduler/LayerHistoryV2.cpp
@@ -40,9 +40,11 @@
namespace {
bool isLayerActive(const Layer& layer, const LayerInfoV2& info, nsecs_t threshold) {
+ // Layers with an explicit vote are always kept active
if (layer.getFrameRateForLayerTree().rate > 0) {
- return layer.isVisible();
+ return true;
}
+
return layer.isVisible() && info.getLastUpdatedTime() >= threshold;
}
@@ -127,29 +129,24 @@
// an additional parameter.
ALOGV("Layer has priority: %d", strong->getFrameRateSelectionPriority());
- const bool recent = info->isRecentlyActive(now);
- if (recent) {
- const auto [type, refreshRate] = info->getRefreshRate(now);
- // Skip NoVote layer as those don't have any requirements
- if (type == LayerHistory::LayerVoteType::NoVote) {
- continue;
- }
+ const auto [type, refreshRate] = info->getRefreshRate(now);
+ // Skip NoVote layer as those don't have any requirements
+ if (type == LayerHistory::LayerVoteType::NoVote) {
+ continue;
+ }
- // Compute the layer's position on the screen
- const Rect bounds = Rect(strong->getBounds());
- const ui::Transform transform = strong->getTransform();
- constexpr bool roundOutwards = true;
- Rect transformed = transform.transform(bounds, roundOutwards);
+ // Compute the layer's position on the screen
+ const Rect bounds = Rect(strong->getBounds());
+ const ui::Transform transform = strong->getTransform();
+ constexpr bool roundOutwards = true;
+ Rect transformed = transform.transform(bounds, roundOutwards);
- const float layerArea = transformed.getWidth() * transformed.getHeight();
- float weight = mDisplayArea ? layerArea / mDisplayArea : 0.0f;
- summary.push_back({strong->getName(), type, refreshRate, weight});
+ const float layerArea = transformed.getWidth() * transformed.getHeight();
+ float weight = mDisplayArea ? layerArea / mDisplayArea : 0.0f;
+ summary.push_back({strong->getName(), type, refreshRate, weight});
- if (CC_UNLIKELY(mTraceEnabled)) {
- trace(layer, type, static_cast<int>(std::round(refreshRate)));
- }
- } else if (CC_UNLIKELY(mTraceEnabled)) {
- trace(layer, LayerHistory::LayerVoteType::NoVote, 0);
+ if (CC_UNLIKELY(mTraceEnabled)) {
+ trace(layer, type, static_cast<int>(std::round(refreshRate)));
}
}
@@ -177,7 +174,7 @@
return LayerVoteType::NoVote;
}
}();
- if (frameRate.rate > 0 || voteType == LayerVoteType::NoVote) {
+ if (layer->isVisible() && (frameRate.rate > 0 || voteType == LayerVoteType::NoVote)) {
info->setLayerVote(voteType, frameRate.rate);
} else {
info->resetLayerVote();
diff --git a/services/surfaceflinger/Scheduler/LayerInfoV2.cpp b/services/surfaceflinger/Scheduler/LayerInfoV2.cpp
index b4365bf..bf1fb88 100644
--- a/services/surfaceflinger/Scheduler/LayerInfoV2.cpp
+++ b/services/surfaceflinger/Scheduler/LayerInfoV2.cpp
@@ -45,15 +45,6 @@
}
}
-// Returns whether the earliest present time is within the active threshold.
-bool LayerInfoV2::isRecentlyActive(nsecs_t now) const {
- if (mFrameTimes.empty()) {
- return false;
- }
-
- return mFrameTimes.back().queueTime >= getActiveLayerThreshold(now);
-}
-
bool LayerInfoV2::isFrameTimeValid(const FrameTimeData& frameTime) const {
return frameTime.queueTime >= std::chrono::duration_cast<std::chrono::nanoseconds>(
mFrameTimeValidSince.time_since_epoch())
diff --git a/services/surfaceflinger/Scheduler/LayerInfoV2.h b/services/surfaceflinger/Scheduler/LayerInfoV2.h
index 25fb95a..ad91f18 100644
--- a/services/surfaceflinger/Scheduler/LayerInfoV2.h
+++ b/services/surfaceflinger/Scheduler/LayerInfoV2.h
@@ -64,8 +64,6 @@
// updated time, the updated time is the present time.
void setLastPresentTime(nsecs_t lastPresentTime, nsecs_t now);
- bool isRecentlyActive(nsecs_t now) const;
-
// Sets an explicit layer vote. This usually comes directly from the application via
// ANativeWindow_setFrameRate API
void setLayerVote(LayerHistory::LayerVoteType type, float fps) { mLayerVote = {type, fps}; }
diff --git a/services/surfaceflinger/Scheduler/MessageQueue.cpp b/services/surfaceflinger/Scheduler/MessageQueue.cpp
index 005d157..6067e69 100644
--- a/services/surfaceflinger/Scheduler/MessageQueue.cpp
+++ b/services/surfaceflinger/Scheduler/MessageQueue.cpp
@@ -18,10 +18,6 @@
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wconversion"
-#include <errno.h>
-#include <stdint.h>
-#include <sys/types.h>
-
#include <binder/IPCThreadState.h>
#include <utils/Log.h>
@@ -35,26 +31,7 @@
#include "MessageQueue.h"
#include "SurfaceFlinger.h"
-namespace android {
-
-// ---------------------------------------------------------------------------
-
-MessageBase::MessageBase() : MessageHandler() {}
-
-MessageBase::~MessageBase() {}
-
-void MessageBase::handleMessage(const Message&) {
- this->handler();
- barrier.open();
-};
-
-// ---------------------------------------------------------------------------
-
-MessageQueue::~MessageQueue() = default;
-
-// ---------------------------------------------------------------------------
-
-namespace impl {
+namespace android::impl {
void MessageQueue::Handler::dispatchRefresh() {
if ((android_atomic_or(eventMaskRefresh, &mEventMask) & eventMaskRefresh) == 0) {
@@ -62,8 +39,9 @@
}
}
-void MessageQueue::Handler::dispatchInvalidate() {
+void MessageQueue::Handler::dispatchInvalidate(nsecs_t expectedVSyncTimestamp) {
if ((android_atomic_or(eventMaskInvalidate, &mEventMask) & eventMaskInvalidate) == 0) {
+ mExpectedVSyncTime = expectedVSyncTimestamp;
mQueue.mLooper->sendMessage(this, Message(MessageQueue::INVALIDATE));
}
}
@@ -72,11 +50,11 @@
switch (message.what) {
case INVALIDATE:
android_atomic_and(~eventMaskInvalidate, &mEventMask);
- mQueue.mFlinger->onMessageReceived(message.what);
+ mQueue.mFlinger->onMessageReceived(message.what, mExpectedVSyncTime);
break;
case REFRESH:
android_atomic_and(~eventMaskRefresh, &mEventMask);
- mQueue.mFlinger->onMessageReceived(message.what);
+ mQueue.mFlinger->onMessageReceived(message.what, mExpectedVSyncTime);
break;
}
}
@@ -122,14 +100,8 @@
} while (true);
}
-status_t MessageQueue::postMessage(const sp<MessageBase>& messageHandler, nsecs_t relTime) {
- const Message dummyMessage;
- if (relTime > 0) {
- mLooper->sendMessageDelayed(relTime, messageHandler, dummyMessage);
- } else {
- mLooper->sendMessage(messageHandler, dummyMessage);
- }
- return NO_ERROR;
+void MessageQueue::postMessage(sp<MessageHandler>&& handler) {
+ mLooper->sendMessage(handler, Message());
}
void MessageQueue::invalidate() {
@@ -151,7 +123,7 @@
while ((n = DisplayEventReceiver::getEvents(&mEventTube, buffer, 8)) > 0) {
for (int i = 0; i < n; i++) {
if (buffer[i].header.type == DisplayEventReceiver::DISPLAY_EVENT_VSYNC) {
- mHandler->dispatchInvalidate();
+ mHandler->dispatchInvalidate(buffer[i].vsync.expectedVSyncTimestamp);
break;
}
}
@@ -159,10 +131,7 @@
return 1;
}
-// ---------------------------------------------------------------------------
-
-} // namespace impl
-} // namespace android
+} // namespace android::impl
// TODO(b/129481165): remove the #pragma below and fix conversion issues
#pragma clang diagnostic pop // ignored "-Wconversion"
diff --git a/services/surfaceflinger/Scheduler/MessageQueue.h b/services/surfaceflinger/Scheduler/MessageQueue.h
index fcfc4aa..132b416 100644
--- a/services/surfaceflinger/Scheduler/MessageQueue.h
+++ b/services/surfaceflinger/Scheduler/MessageQueue.h
@@ -14,12 +14,12 @@
* limitations under the License.
*/
-#ifndef ANDROID_MESSAGE_QUEUE_H
-#define ANDROID_MESSAGE_QUEUE_H
+#pragma once
-#include <errno.h>
-#include <stdint.h>
-#include <sys/types.h>
+#include <cstdint>
+#include <future>
+#include <type_traits>
+#include <utility>
#include <utils/Looper.h>
#include <utils/Timers.h>
@@ -28,52 +28,30 @@
#include <gui/IDisplayEventConnection.h>
#include <private/gui/BitTube.h>
-#include "Barrier.h"
#include "EventThread.h"
-#include <functional>
-
namespace android {
class SurfaceFlinger;
-// ---------------------------------------------------------------------------
+template <typename F>
+class Task : public MessageHandler {
+ template <typename G>
+ friend auto makeTask(G&&);
-class MessageBase : public MessageHandler {
-public:
- MessageBase();
+ explicit Task(F&& f) : mTask(std::move(f)) {}
- // return true if message has a handler
- virtual bool handler() = 0;
+ void handleMessage(const Message&) override { mTask(); }
- // waits for the handler to be processed
- void wait() const { barrier.wait(); }
-
-protected:
- virtual ~MessageBase();
-
-private:
- virtual void handleMessage(const Message& message);
-
- mutable Barrier barrier;
+ using T = std::invoke_result_t<F>;
+ std::packaged_task<T()> mTask;
};
-class LambdaMessage : public MessageBase {
-public:
- explicit LambdaMessage(std::function<void()> handler)
- : MessageBase(), mHandler(std::move(handler)) {}
-
- bool handler() override {
- mHandler();
- // This return value is no longer checked, so it's always safe to return true
- return true;
- }
-
-private:
- const std::function<void()> mHandler;
-};
-
-// ---------------------------------------------------------------------------
+template <typename F>
+inline auto makeTask(F&& f) {
+ sp<Task<F>> task = new Task<F>(std::move(f));
+ return std::make_pair(task, task->mTask.get_future());
+}
class MessageQueue {
public:
@@ -82,12 +60,12 @@
REFRESH = 1,
};
- virtual ~MessageQueue();
+ virtual ~MessageQueue() = default;
virtual void init(const sp<SurfaceFlinger>& flinger) = 0;
virtual void setEventConnection(const sp<EventThreadConnection>& connection) = 0;
virtual void waitMessage() = 0;
- virtual status_t postMessage(const sp<MessageBase>& message, nsecs_t reltime = 0) = 0;
+ virtual void postMessage(sp<MessageHandler>&&) = 0;
virtual void invalidate() = 0;
virtual void refresh() = 0;
};
@@ -101,12 +79,13 @@
enum { eventMaskInvalidate = 0x1, eventMaskRefresh = 0x2, eventMaskTransaction = 0x4 };
MessageQueue& mQueue;
int32_t mEventMask;
+ std::atomic<nsecs_t> mExpectedVSyncTime;
public:
explicit Handler(MessageQueue& queue) : mQueue(queue), mEventMask(0) {}
virtual void handleMessage(const Message& message);
void dispatchRefresh();
- void dispatchInvalidate();
+ void dispatchInvalidate(nsecs_t expectedVSyncTimestamp);
};
friend class Handler;
@@ -126,7 +105,7 @@
void setEventConnection(const sp<EventThreadConnection>& connection) override;
void waitMessage() override;
- status_t postMessage(const sp<MessageBase>& message, nsecs_t reltime = 0) override;
+ void postMessage(sp<MessageHandler>&&) override;
// sends INVALIDATE message at next VSYNC
void invalidate() override;
@@ -135,9 +114,5 @@
void refresh() override;
};
-// ---------------------------------------------------------------------------
-
} // namespace impl
} // namespace android
-
-#endif /* ANDROID_MESSAGE_QUEUE_H */
diff --git a/services/surfaceflinger/Scheduler/PhaseOffsets.cpp b/services/surfaceflinger/Scheduler/PhaseOffsets.cpp
index d9aaa05..fe2e406 100644
--- a/services/surfaceflinger/Scheduler/PhaseOffsets.cpp
+++ b/services/surfaceflinger/Scheduler/PhaseOffsets.cpp
@@ -60,6 +60,12 @@
PhaseOffsets::PhaseOffsets(const scheduler::RefreshRateConfigs& refreshRateConfigs)
: PhaseOffsets(getRefreshRatesFromConfigs(refreshRateConfigs),
refreshRateConfigs.getCurrentRefreshRate().getFps(),
+ sysprop::vsync_event_phase_offset_ns(1000000),
+ sysprop::vsync_sf_event_phase_offset_ns(1000000),
+ getProperty("debug.sf.early_phase_offset_ns"),
+ getProperty("debug.sf.early_gl_phase_offset_ns"),
+ getProperty("debug.sf.early_app_phase_offset_ns"),
+ getProperty("debug.sf.early_gl_app_phase_offset_ns"),
// Below defines the threshold when an offset is considered to be negative,
// i.e. targeting for the N+2 vsync instead of N+1. This means that: For offset
// < threshold, SF wake up (vsync_duration - offset) before HW vsync. For
@@ -69,8 +75,18 @@
.value_or(std::numeric_limits<nsecs_t>::max())) {}
PhaseOffsets::PhaseOffsets(const std::vector<float>& refreshRates, float currentFps,
- nsecs_t thresholdForNextVsync)
- : mThresholdForNextVsync(thresholdForNextVsync),
+ nsecs_t vsyncPhaseOffsetNs, nsecs_t sfVSyncPhaseOffsetNs,
+ std::optional<nsecs_t> earlySfOffsetNs,
+ std::optional<nsecs_t> earlyGlSfOffsetNs,
+ std::optional<nsecs_t> earlyAppOffsetNs,
+ std::optional<nsecs_t> earlyGlAppOffsetNs, nsecs_t thresholdForNextVsync)
+ : mVSyncPhaseOffsetNs(vsyncPhaseOffsetNs),
+ mSfVSyncPhaseOffsetNs(sfVSyncPhaseOffsetNs),
+ mEarlySfOffsetNs(earlySfOffsetNs),
+ mEarlyGlSfOffsetNs(earlyGlSfOffsetNs),
+ mEarlyAppOffsetNs(earlyAppOffsetNs),
+ mEarlyGlAppOffsetNs(earlyGlAppOffsetNs),
+ mThresholdForNextVsync(thresholdForNextVsync),
mOffsets(initializeOffsets(refreshRates)),
mRefreshRateFps(currentFps) {}
@@ -106,35 +122,27 @@
}
PhaseOffsets::Offsets PhaseOffsets::getDefaultOffsets(nsecs_t vsyncDuration) const {
- const int64_t vsyncPhaseOffsetNs = sysprop::vsync_event_phase_offset_ns(1000000);
- const int64_t sfVsyncPhaseOffsetNs = sysprop::vsync_sf_event_phase_offset_ns(1000000);
-
- const auto earlySfOffsetNs = getProperty("debug.sf.early_phase_offset_ns");
- const auto earlyGlSfOffsetNs = getProperty("debug.sf.early_gl_phase_offset_ns");
- const auto earlyAppOffsetNs = getProperty("debug.sf.early_app_phase_offset_ns");
- const auto earlyGlAppOffsetNs = getProperty("debug.sf.early_gl_app_phase_offset_ns");
-
return {
{
- earlySfOffsetNs.value_or(sfVsyncPhaseOffsetNs) < mThresholdForNextVsync
- ? earlySfOffsetNs.value_or(sfVsyncPhaseOffsetNs)
- : earlySfOffsetNs.value_or(sfVsyncPhaseOffsetNs) - vsyncDuration,
+ mEarlySfOffsetNs.value_or(mSfVSyncPhaseOffsetNs) < mThresholdForNextVsync
+ ? mEarlySfOffsetNs.value_or(mSfVSyncPhaseOffsetNs)
+ : mEarlySfOffsetNs.value_or(mSfVSyncPhaseOffsetNs) - vsyncDuration,
- earlyAppOffsetNs.value_or(vsyncPhaseOffsetNs),
+ mEarlyAppOffsetNs.value_or(mVSyncPhaseOffsetNs),
},
{
- earlyGlSfOffsetNs.value_or(sfVsyncPhaseOffsetNs) < mThresholdForNextVsync
- ? earlyGlSfOffsetNs.value_or(sfVsyncPhaseOffsetNs)
- : earlyGlSfOffsetNs.value_or(sfVsyncPhaseOffsetNs) - vsyncDuration,
+ mEarlyGlSfOffsetNs.value_or(mSfVSyncPhaseOffsetNs) < mThresholdForNextVsync
+ ? mEarlyGlSfOffsetNs.value_or(mSfVSyncPhaseOffsetNs)
+ : mEarlyGlSfOffsetNs.value_or(mSfVSyncPhaseOffsetNs) - vsyncDuration,
- earlyGlAppOffsetNs.value_or(vsyncPhaseOffsetNs),
+ mEarlyGlAppOffsetNs.value_or(mVSyncPhaseOffsetNs),
},
{
- sfVsyncPhaseOffsetNs < mThresholdForNextVsync
- ? sfVsyncPhaseOffsetNs
- : sfVsyncPhaseOffsetNs - vsyncDuration,
+ mSfVSyncPhaseOffsetNs < mThresholdForNextVsync
+ ? mSfVSyncPhaseOffsetNs
+ : mSfVSyncPhaseOffsetNs - vsyncDuration,
- vsyncPhaseOffsetNs,
+ mVSyncPhaseOffsetNs,
},
};
}
diff --git a/services/surfaceflinger/Scheduler/PhaseOffsets.h b/services/surfaceflinger/Scheduler/PhaseOffsets.h
index fa8011d..9ec6d56 100644
--- a/services/surfaceflinger/Scheduler/PhaseOffsets.h
+++ b/services/surfaceflinger/Scheduler/PhaseOffsets.h
@@ -69,6 +69,9 @@
protected:
// Used for unit tests
PhaseOffsets(const std::vector<float>& refreshRates, float currentFps,
+ nsecs_t vsyncPhaseOffsetNs, nsecs_t sfVSyncPhaseOffsetNs,
+ std::optional<nsecs_t> earlySfOffsetNs, std::optional<nsecs_t> earlyGlSfOffsetNs,
+ std::optional<nsecs_t> earlyAppOffsetNs, std::optional<nsecs_t> earlyGlAppOffsetNs,
nsecs_t thresholdForNextVsync);
std::unordered_map<float, Offsets> initializeOffsets(
const std::vector<float>& refreshRates) const;
@@ -76,6 +79,12 @@
Offsets getHighFpsOffsets(nsecs_t vsyncPeriod) const;
Offsets getPhaseOffsets(float fps, nsecs_t vsyncPeriod) const;
+ const nsecs_t mVSyncPhaseOffsetNs;
+ const nsecs_t mSfVSyncPhaseOffsetNs;
+ const std::optional<nsecs_t> mEarlySfOffsetNs;
+ const std::optional<nsecs_t> mEarlyGlSfOffsetNs;
+ const std::optional<nsecs_t> mEarlyAppOffsetNs;
+ const std::optional<nsecs_t> mEarlyGlAppOffsetNs;
const nsecs_t mThresholdForNextVsync;
const std::unordered_map<float, Offsets> mOffsets;
diff --git a/services/surfaceflinger/Scheduler/RefreshRateStats.h b/services/surfaceflinger/Scheduler/RefreshRateStats.h
index 66d4a03..d9e7b37 100644
--- a/services/surfaceflinger/Scheduler/RefreshRateStats.h
+++ b/services/surfaceflinger/Scheduler/RefreshRateStats.h
@@ -41,14 +41,15 @@
public:
RefreshRateStats(const RefreshRateConfigs& refreshRateConfigs, TimeStats& timeStats,
- HwcConfigIndexType currentConfigId, int currentPowerMode)
+ HwcConfigIndexType currentConfigId,
+ android::hardware::graphics::composer::hal::PowerMode currentPowerMode)
: mRefreshRateConfigs(refreshRateConfigs),
mTimeStats(timeStats),
mCurrentConfigMode(currentConfigId),
mCurrentPowerMode(currentPowerMode) {}
// Sets power mode.
- void setPowerMode(int mode) {
+ void setPowerMode(android::hardware::graphics::composer::hal::PowerMode mode) {
if (mCurrentPowerMode == mode) {
return;
}
@@ -108,7 +109,7 @@
mPreviousRecordedTime = currentTime;
uint32_t fps = 0;
- if (mCurrentPowerMode == HWC_POWER_MODE_NORMAL) {
+ if (mCurrentPowerMode == android::hardware::graphics::composer::hal::PowerMode::ON) {
// Normal power mode is counted under different config modes.
if (mConfigModesTotalTime.find(mCurrentConfigMode) == mConfigModesTotalTime.end()) {
mConfigModesTotalTime[mCurrentConfigMode] = 0;
@@ -140,7 +141,7 @@
TimeStats& mTimeStats;
HwcConfigIndexType mCurrentConfigMode;
- int32_t mCurrentPowerMode;
+ android::hardware::graphics::composer::hal::PowerMode mCurrentPowerMode;
std::unordered_map<HwcConfigIndexType /* configId */, int64_t /* duration in ms */>
mConfigModesTotalTime;
diff --git a/services/surfaceflinger/Scheduler/Scheduler.cpp b/services/surfaceflinger/Scheduler/Scheduler.cpp
index 9a9523f..86bb6eb 100644
--- a/services/surfaceflinger/Scheduler/Scheduler.cpp
+++ b/services/surfaceflinger/Scheduler/Scheduler.cpp
@@ -250,7 +250,7 @@
}
void Scheduler::getDisplayStatInfo(DisplayStatInfo* stats) {
- stats->vsyncTime = mPrimaryDispSync->computeNextRefresh(0);
+ stats->vsyncTime = mPrimaryDispSync->computeNextRefresh(0, systemTime());
stats->vsyncPeriod = mPrimaryDispSync->getPeriod();
}
@@ -276,12 +276,12 @@
return mInjectorConnectionHandle;
}
-bool Scheduler::injectVSync(nsecs_t when) {
+bool Scheduler::injectVSync(nsecs_t when, nsecs_t expectedVSyncTime) {
if (!mInjectVSyncs || !mVSyncInjector) {
return false;
}
- mVSyncInjector->onInjectSyncEvent(when);
+ mVSyncInjector->onInjectSyncEvent(when, expectedVSyncTime);
return true;
}
@@ -378,8 +378,8 @@
mPrimaryDispSync->setIgnorePresentFences(ignore);
}
-nsecs_t Scheduler::getDispSyncExpectedPresentTime() {
- return mPrimaryDispSync->expectedPresentTime();
+nsecs_t Scheduler::getDispSyncExpectedPresentTime(nsecs_t now) {
+ return mPrimaryDispSync->expectedPresentTime(now);
}
void Scheduler::registerLayer(Layer* layer) {
@@ -634,7 +634,7 @@
return mFeatures.configId;
}
-void Scheduler::onNewVsyncPeriodChangeTimeline(const HWC2::VsyncPeriodChangeTimeline& timeline) {
+void Scheduler::onNewVsyncPeriodChangeTimeline(const hal::VsyncPeriodChangeTimeline& timeline) {
if (timeline.refreshRequired) {
mSchedulerCallback.repaintEverythingForHWC();
}
diff --git a/services/surfaceflinger/Scheduler/Scheduler.h b/services/surfaceflinger/Scheduler/Scheduler.h
index 04cc96a..4a0280f 100644
--- a/services/surfaceflinger/Scheduler/Scheduler.h
+++ b/services/surfaceflinger/Scheduler/Scheduler.h
@@ -95,7 +95,7 @@
ConnectionHandle enableVSyncInjection(bool enable);
// Returns false if injection is disabled.
- bool injectVSync(nsecs_t when);
+ bool injectVSync(nsecs_t when, nsecs_t expectedVSyncTime);
void enableHardwareVsync();
void disableHardwareVsync(bool makeUnavailable);
@@ -114,7 +114,7 @@
bool* periodFlushed);
void addPresentFence(const std::shared_ptr<FenceTime>&);
void setIgnorePresentFences(bool ignore);
- nsecs_t getDispSyncExpectedPresentTime();
+ nsecs_t getDispSyncExpectedPresentTime(nsecs_t now);
// Layers are registered on creation, and unregistered when the weak reference expires.
void registerLayer(Layer*);
@@ -138,7 +138,7 @@
std::optional<HwcConfigIndexType> getPreferredConfigId();
// Notifies the scheduler about a refresh rate timeline change.
- void onNewVsyncPeriodChangeTimeline(const HWC2::VsyncPeriodChangeTimeline& timeline);
+ void onNewVsyncPeriodChangeTimeline(const hal::VsyncPeriodChangeTimeline& timeline);
// Notifies the scheduler when the display was refreshed
void onDisplayRefreshed(nsecs_t timestamp);
@@ -242,7 +242,7 @@
const scheduler::RefreshRateConfigs& mRefreshRateConfigs;
std::mutex mVsyncTimelineLock;
- std::optional<HWC2::VsyncPeriodChangeTimeline> mLastVsyncPeriodChangeTimeline
+ std::optional<hal::VsyncPeriodChangeTimeline> mLastVsyncPeriodChangeTimeline
GUARDED_BY(mVsyncTimelineLock);
static constexpr std::chrono::nanoseconds MAX_VSYNC_APPLIED_TIME = 200ms;
diff --git a/services/surfaceflinger/Scheduler/VSyncReactor.cpp b/services/surfaceflinger/Scheduler/VSyncReactor.cpp
index 892ae62..5f0c9ce 100644
--- a/services/surfaceflinger/Scheduler/VSyncReactor.cpp
+++ b/services/surfaceflinger/Scheduler/VSyncReactor.cpp
@@ -128,7 +128,7 @@
mLastCallTime = vsynctime;
}
- mCallback->onDispSyncEvent(wakeupTime);
+ mCallback->onDispSyncEvent(wakeupTime, vsynctime);
{
std::lock_guard<std::mutex> lk(mMutex);
@@ -221,14 +221,13 @@
}
}
-nsecs_t VSyncReactor::computeNextRefresh(int periodOffset) const {
- auto const now = mClock->now();
+nsecs_t VSyncReactor::computeNextRefresh(int periodOffset, nsecs_t now) const {
auto const currentPeriod = periodOffset ? mTracker->currentPeriod() : 0;
return mTracker->nextAnticipatedVSyncTimeFrom(now + periodOffset * currentPeriod);
}
-nsecs_t VSyncReactor::expectedPresentTime() {
- return mTracker->nextAnticipatedVSyncTimeFrom(mClock->now());
+nsecs_t VSyncReactor::expectedPresentTime(nsecs_t now) {
+ return mTracker->nextAnticipatedVSyncTimeFrom(now);
}
void VSyncReactor::startPeriodTransition(nsecs_t newPeriod) {
diff --git a/services/surfaceflinger/Scheduler/VSyncReactor.h b/services/surfaceflinger/Scheduler/VSyncReactor.h
index 5ee29f8..31ddf5a 100644
--- a/services/surfaceflinger/Scheduler/VSyncReactor.h
+++ b/services/surfaceflinger/Scheduler/VSyncReactor.h
@@ -42,8 +42,8 @@
bool addPresentFence(const std::shared_ptr<FenceTime>& fence) final;
void setIgnorePresentFences(bool ignoration) final;
- nsecs_t computeNextRefresh(int periodOffset) const final;
- nsecs_t expectedPresentTime() final;
+ nsecs_t computeNextRefresh(int periodOffset, nsecs_t now) const final;
+ nsecs_t expectedPresentTime(nsecs_t now) final;
void setPeriod(nsecs_t period) final;
nsecs_t getPeriod() final;
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index ddf0775..2943499 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -140,6 +140,8 @@
using ui::Hdr;
using ui::RenderIntent;
+namespace hal = android::hardware::graphics::composer::hal;
+
namespace {
#pragma clang diagnostic push
@@ -169,19 +171,22 @@
#pragma clang diagnostic pop
-class ConditionalLock {
-public:
- ConditionalLock(Mutex& mutex, bool lock) : mMutex(mutex), mLocked(lock) {
- if (lock) {
- mMutex.lock();
- }
+template <typename Mutex>
+struct ConditionalLockGuard {
+ ConditionalLockGuard(Mutex& mutex, bool lock) : mutex(mutex), lock(lock) {
+ if (lock) mutex.lock();
}
- ~ConditionalLock() { if (mLocked) mMutex.unlock(); }
-private:
- Mutex& mMutex;
- bool mLocked;
+
+ ~ConditionalLockGuard() {
+ if (lock) mutex.unlock();
+ }
+
+ Mutex& mutex;
+ const bool lock;
};
+using ConditionalLock = ConditionalLockGuard<Mutex>;
+
// TODO(b/141333600): Consolidate with HWC2::Display::Config::Builder::getDefaultDensity.
constexpr float FALLBACK_DENSITY = ACONFIGURATION_DENSITY_TV / 160.f;
@@ -405,15 +410,13 @@
useFrameRateApi = use_frame_rate_api(true);
}
-void SurfaceFlinger::onFirstRef()
-{
+SurfaceFlinger::~SurfaceFlinger() = default;
+
+void SurfaceFlinger::onFirstRef() {
mEventQueue->init(this);
}
-SurfaceFlinger::~SurfaceFlinger() = default;
-
-void SurfaceFlinger::binderDied(const wp<IBinder>& /* who */)
-{
+void SurfaceFlinger::binderDied(const wp<IBinder>&) {
// the window manager died on us. prepare its eulogy.
mBootFinished = false;
@@ -424,21 +427,25 @@
startBootAnim();
}
-static sp<ISurfaceComposerClient> initClient(const sp<Client>& client) {
- status_t err = client->initCheck();
- if (err == NO_ERROR) {
- return client;
+void SurfaceFlinger::run() {
+ while (true) {
+ mEventQueue->waitMessage();
}
- return nullptr;
+}
+
+template <typename F, typename T>
+inline std::future<T> SurfaceFlinger::schedule(F&& f) {
+ auto [task, future] = makeTask(std::move(f));
+ mEventQueue->postMessage(std::move(task));
+ return std::move(future);
}
sp<ISurfaceComposerClient> SurfaceFlinger::createConnection() {
- return initClient(new Client(this));
+ const sp<Client> client = new Client(this);
+ return client->initCheck() == NO_ERROR ? client : nullptr;
}
-sp<IBinder> SurfaceFlinger::createDisplay(const String8& displayName,
- bool secure)
-{
+sp<IBinder> SurfaceFlinger::createDisplay(const String8& displayName, bool secure) {
class DisplayToken : public BBinder {
sp<SurfaceFlinger> flinger;
virtual ~DisplayToken() {
@@ -574,7 +581,7 @@
LOG_EVENT_LONG(LOGTAG_SF_STOP_BOOTANIM,
ns2ms(systemTime(SYSTEM_TIME_MONOTONIC)));
- postMessageAsync(new LambdaMessage([this]() NO_THREAD_SAFETY_ANALYSIS {
+ static_cast<void>(schedule([this]() NO_THREAD_SAFETY_ANALYSIS {
readPersistentProperties();
mPowerAdvisor.onBootFinished();
mBootStage = BootStage::FINISHED;
@@ -602,9 +609,12 @@
// The pool was empty, so we need to get a new texture name directly using a
// blocking call to the main thread
- uint32_t name = 0;
- postMessageSync(new LambdaMessage([&]() { getRenderEngine().genTextures(1, &name); }));
- return name;
+ return schedule([this] {
+ uint32_t name = 0;
+ getRenderEngine().genTextures(1, &name);
+ return name;
+ })
+ .get();
}
void SurfaceFlinger::deleteTextureAsync(uint32_t texture) {
@@ -658,7 +668,7 @@
// mStateLock from the vr flinger dispatch thread might trigger a
// deadlock in surface flinger (see b/66916578), so post a message
// to be handled on the main thread instead.
- postMessageAsync(new LambdaMessage([=] {
+ static_cast<void>(schedule([=] {
ALOGI("VR request display mode: requestDisplay=%d", requestDisplay);
mVrFlingerRequestsDisplay = requestDisplay;
signalTransaction();
@@ -689,7 +699,7 @@
// Inform native graphics APIs whether the present timestamp is supported:
const bool presentFenceReliable =
- !getHwComposer().hasCapability(HWC2::Capability::PresentFenceIsNotReliable);
+ !getHwComposer().hasCapability(hal::Capability::PRESENT_FENCE_IS_NOT_RELIABLE);
mStartPropertySetThread = getFactory().createStartPropertySetThread(presentFenceReliable);
if (mStartPropertySetThread->Start() != NO_ERROR) {
@@ -767,8 +777,7 @@
};
ConditionalLock _l(mStateLock,
std::this_thread::get_id() != mMainThreadId);
- if (!getHwComposer().hasCapability(
- HWC2::Capability::PresentFenceIsNotReliable)) {
+ if (!getHwComposer().hasCapability(hal::Capability::PRESENT_FENCE_IS_NOT_RELIABLE)) {
outSupported->push_back(FrameEvent::DISPLAY_PRESENT);
}
return NO_ERROR;
@@ -981,29 +990,26 @@
return BAD_VALUE;
}
- status_t result = NAME_NOT_FOUND;
-
- postMessageSync(new LambdaMessage([&]() {
+ auto future = schedule([=]() -> status_t {
const auto display = getDisplayDeviceLocked(displayToken);
if (!display) {
ALOGE("Attempt to set allowed display configs for invalid display token %p",
displayToken.get());
+ return NAME_NOT_FOUND;
} else if (display->isVirtual()) {
ALOGW("Attempt to set allowed display configs for virtual display");
- result = INVALID_OPERATION;
+ return INVALID_OPERATION;
} else {
- HwcConfigIndexType config(mode);
- const auto& refreshRate = mRefreshRateConfigs->getRefreshRateFromConfigId(config);
- result = setDesiredDisplayConfigSpecsInternal(display,
- scheduler::RefreshRateConfigs::
- Policy{config,
- refreshRate.getFps(),
- refreshRate.getFps()},
- /*overridePolicy=*/false);
- }
- }));
+ const HwcConfigIndexType config(mode);
+ const float fps = mRefreshRateConfigs->getRefreshRateFromConfigId(config).getFps();
+ const scheduler::RefreshRateConfigs::Policy policy{config, fps, fps};
+ constexpr bool kOverridePolicy = false;
- return result;
+ return setDesiredDisplayConfigSpecsInternal(display, policy, kOverridePolicy);
+ }
+ });
+
+ return future.get();
}
void SurfaceFlinger::setActiveConfigInternal() {
@@ -1096,11 +1102,11 @@
ATRACE_INT("ActiveConfigFPS_HWC", refreshRate.getFps());
// TODO(b/142753666) use constrains
- HWC2::VsyncPeriodChangeConstraints constraints;
+ hal::VsyncPeriodChangeConstraints constraints;
constraints.desiredTimeNanos = systemTime();
constraints.seamlessRequired = false;
- HWC2::VsyncPeriodChangeTimeline outTimeline;
+ hal::VsyncPeriodChangeTimeline outTimeline;
auto status =
getHwComposer().setActiveConfigWithConstraints(*displayId,
mUpcomingActiveConfig.configId.value(),
@@ -1177,7 +1183,7 @@
}
status_t SurfaceFlinger::setActiveColorMode(const sp<IBinder>& displayToken, ColorMode mode) {
- postMessageSync(new LambdaMessage([&] {
+ schedule([=] {
Vector<ColorMode> modes;
getDisplayColorModes(displayToken, &modes);
bool exists = std::find(std::begin(modes), std::end(modes), mode) != std::end(modes);
@@ -1199,7 +1205,7 @@
RenderIntent::COLORIMETRIC,
Dataspace::UNKNOWN});
}
- }));
+ }).wait();
return NO_ERROR;
}
@@ -1216,13 +1222,14 @@
if (!displayId) {
return NAME_NOT_FOUND;
}
- *outSupport = getHwComposer().hasDisplayCapability(*displayId,
- HWC2::DisplayCapability::AutoLowLatencyMode);
+ *outSupport =
+ getHwComposer().hasDisplayCapability(*displayId,
+ hal::DisplayCapability::AUTO_LOW_LATENCY_MODE);
return NO_ERROR;
}
void SurfaceFlinger::setAutoLowLatencyMode(const sp<IBinder>& displayToken, bool on) {
- postMessageAsync(new LambdaMessage([=] {
+ static_cast<void>(schedule([=] {
if (const auto displayId = getPhysicalDisplayIdLocked(displayToken)) {
getHwComposer().setAutoLowLatencyMode(*displayId, on);
} else {
@@ -1244,18 +1251,18 @@
return NAME_NOT_FOUND;
}
- std::vector<HWC2::ContentType> types;
+ std::vector<hal::ContentType> types;
getHwComposer().getSupportedContentTypes(*displayId, &types);
*outSupport = std::any_of(types.begin(), types.end(),
- [](auto type) { return type == HWC2::ContentType::Game; });
+ [](auto type) { return type == hal::ContentType::GAME; });
return NO_ERROR;
}
void SurfaceFlinger::setGameContentType(const sp<IBinder>& displayToken, bool on) {
- postMessageAsync(new LambdaMessage([=] {
+ static_cast<void>(schedule([=] {
if (const auto displayId = getPhysicalDisplayIdLocked(displayToken)) {
- const auto type = on ? HWC2::ContentType::Game : HWC2::ContentType::None;
+ const auto type = on ? hal::ContentType::GAME : hal::ContentType::NONE;
getHwComposer().setContentType(*displayId, type);
} else {
ALOGE("%s: Invalid display token %p", __FUNCTION__, displayToken.get());
@@ -1343,18 +1350,17 @@
status_t SurfaceFlinger::setDisplayContentSamplingEnabled(const sp<IBinder>& displayToken,
bool enable, uint8_t componentMask,
uint64_t maxFrames) {
- status_t result = NAME_NOT_FOUND;
-
- postMessageSync(new LambdaMessage([&] {
- if (const auto displayId = getPhysicalDisplayIdLocked(displayToken)) {
- result = getHwComposer().setDisplayContentSamplingEnabled(*displayId, enable,
- componentMask, maxFrames);
- } else {
- ALOGE("%s: Invalid display token %p", __FUNCTION__, displayToken.get());
- }
- }));
-
- return result;
+ return schedule([=]() -> status_t {
+ if (const auto displayId = getPhysicalDisplayIdLocked(displayToken)) {
+ return getHwComposer().setDisplayContentSamplingEnabled(*displayId, enable,
+ componentMask,
+ maxFrames);
+ } else {
+ ALOGE("%s: Invalid display token %p", __FUNCTION__, displayToken.get());
+ return NAME_NOT_FOUND;
+ }
+ })
+ .get();
}
status_t SurfaceFlinger::getDisplayedContentSample(const sp<IBinder>& displayToken,
@@ -1396,21 +1402,21 @@
}
status_t SurfaceFlinger::enableVSyncInjections(bool enable) {
- postMessageSync(new LambdaMessage([&] {
+ schedule([=] {
Mutex::Autolock lock(mStateLock);
if (const auto handle = mScheduler->enableVSyncInjection(enable)) {
mEventQueue->setEventConnection(
mScheduler->getEventConnection(enable ? handle : mSfConnectionHandle));
}
- }));
+ }).wait();
return NO_ERROR;
}
status_t SurfaceFlinger::injectVSync(nsecs_t when) {
Mutex::Autolock lock(mStateLock);
- return mScheduler->injectVSync(when) ? NO_ERROR : BAD_VALUE;
+ return mScheduler->injectVSync(when, calculateExpectedPresentTime(when)) ? NO_ERROR : BAD_VALUE;
}
status_t SurfaceFlinger::getLayerDebugInfo(std::vector<LayerDebugInfo>* outLayers) const
@@ -1449,7 +1455,9 @@
if (!listener || samplingArea == Rect::INVALID_RECT) {
return BAD_VALUE;
}
- mRegionSamplingThread->addListener(samplingArea, stopLayerHandle, listener);
+
+ const wp<Layer> stopLayer = fromHandle(stopLayerHandle);
+ mRegionSamplingThread->addListener(samplingArea, stopLayer, listener);
return NO_ERROR;
}
@@ -1474,7 +1482,7 @@
return NAME_NOT_FOUND;
}
*outSupport =
- getHwComposer().hasDisplayCapability(*displayId, HWC2::DisplayCapability::Brightness);
+ getHwComposer().hasDisplayCapability(*displayId, hal::DisplayCapability::BRIGHTNESS);
return NO_ERROR;
}
@@ -1483,17 +1491,15 @@
return BAD_VALUE;
}
- status_t result = NAME_NOT_FOUND;
-
- postMessageSync(new LambdaMessage([&] {
- if (const auto displayId = getPhysicalDisplayIdLocked(displayToken)) {
- result = getHwComposer().setDisplayBrightness(*displayId, brightness);
- } else {
- ALOGE("%s: Invalid display token %p", __FUNCTION__, displayToken.get());
- }
- }));
-
- return result;
+ return schedule([=]() -> status_t {
+ if (const auto displayId = getPhysicalDisplayIdLocked(displayToken)) {
+ return getHwComposer().setDisplayBrightness(*displayId, brightness);
+ } else {
+ ALOGE("%s: Invalid display token %p", __FUNCTION__, displayToken.get());
+ return NAME_NOT_FOUND;
+ }
+ })
+ .get();
}
status_t SurfaceFlinger::notifyPowerHint(int32_t hintId) {
@@ -1516,12 +1522,6 @@
return mScheduler->createDisplayEventConnection(handle, configChanged);
}
-// ----------------------------------------------------------------------------
-
-void SurfaceFlinger::waitForEvent() {
- mEventQueue->waitMessage();
-}
-
void SurfaceFlinger::signalTransaction() {
mScheduler->resetIdleTimer();
mPowerAdvisor.notifyDisplayUpdateImminent();
@@ -1539,26 +1539,6 @@
mEventQueue->refresh();
}
-status_t SurfaceFlinger::postMessageAsync(const sp<MessageBase>& msg,
- nsecs_t reltime, uint32_t /* flags */) {
- return mEventQueue->postMessage(msg, reltime);
-}
-
-status_t SurfaceFlinger::postMessageSync(const sp<MessageBase>& msg,
- nsecs_t reltime, uint32_t /* flags */) {
- status_t res = mEventQueue->postMessage(msg, reltime);
- if (res == NO_ERROR) {
- msg->wait();
- }
- return res;
-}
-
-void SurfaceFlinger::run() {
- do {
- waitForEvent();
- } while (true);
-}
-
nsecs_t SurfaceFlinger::getVsyncPeriod() const {
const auto displayId = getInternalDisplayIdLocked();
if (!displayId || !getHwComposer().isConnected(*displayId)) {
@@ -1568,9 +1548,9 @@
return getHwComposer().getDisplayVsyncPeriod(*displayId);
}
-void SurfaceFlinger::onVsyncReceived(int32_t sequenceId, hwc2_display_t hwcDisplayId,
+void SurfaceFlinger::onVsyncReceived(int32_t sequenceId, hal::HWDisplayId hwcDisplayId,
int64_t timestamp,
- std::optional<hwc2_vsync_period_t> vsyncPeriod) {
+ std::optional<hal::VsyncPeriodNanos> vsyncPeriod) {
ATRACE_NAME("SF onVsync");
Mutex::Autolock lock(mStateLock);
@@ -1622,10 +1602,10 @@
setDesiredActiveConfig({refreshRate.getConfigId(), event});
}
-void SurfaceFlinger::onHotplugReceived(int32_t sequenceId, hwc2_display_t hwcDisplayId,
- HWC2::Connection connection) {
+void SurfaceFlinger::onHotplugReceived(int32_t sequenceId, hal::HWDisplayId hwcDisplayId,
+ hal::Connection connection) {
ALOGV("%s(%d, %" PRIu64 ", %s)", __FUNCTION__, sequenceId, hwcDisplayId,
- connection == HWC2::Connection::Connected ? "connected" : "disconnected");
+ connection == hal::Connection::CONNECTED ? "connected" : "disconnected");
// Ignore events that do not have the right sequenceId.
if (sequenceId != getBE().mComposerSequenceId) {
@@ -1649,8 +1629,8 @@
}
void SurfaceFlinger::onVsyncPeriodTimingChangedReceived(
- int32_t sequenceId, hwc2_display_t /*display*/,
- const hwc_vsync_period_change_timeline_t& updatedTimeline) {
+ int32_t sequenceId, hal::HWDisplayId /*display*/,
+ const hal::VsyncPeriodChangeTimeline& updatedTimeline) {
Mutex::Autolock lock(mStateLock);
if (sequenceId != getBE().mComposerSequenceId) {
return;
@@ -1658,12 +1638,12 @@
mScheduler->onNewVsyncPeriodChangeTimeline(updatedTimeline);
}
-void SurfaceFlinger::onSeamlessPossible(int32_t /*sequenceId*/, hwc2_display_t /*display*/) {
+void SurfaceFlinger::onSeamlessPossible(int32_t /*sequenceId*/, hal::HWDisplayId /*display*/) {
// TODO(b/142753666): use constraints when calling to setActiveConfigWithConstrains and
// use this callback to know when to retry in case of SEAMLESS_NOT_POSSIBLE.
}
-void SurfaceFlinger::onRefreshReceived(int sequenceId, hwc2_display_t /*hwcDisplayId*/) {
+void SurfaceFlinger::onRefreshReceived(int sequenceId, hal::HWDisplayId /*hwcDisplayId*/) {
Mutex::Autolock lock(mStateLock);
if (sequenceId != getBE().mComposerSequenceId) {
return;
@@ -1676,14 +1656,14 @@
// Enable / Disable HWVsync from the main thread to avoid race conditions with
// display power state.
- postMessageAsync(new LambdaMessage(
- [=]() NO_THREAD_SAFETY_ANALYSIS { setPrimaryVsyncEnabledInternal(enabled); }));
+ static_cast<void>(
+ schedule([=]() NO_THREAD_SAFETY_ANALYSIS { setPrimaryVsyncEnabledInternal(enabled); }));
}
void SurfaceFlinger::setPrimaryVsyncEnabledInternal(bool enabled) {
ATRACE_CALL();
- mHWCVsyncPendingState = enabled ? HWC2::Vsync::Enable : HWC2::Vsync::Disable;
+ mHWCVsyncPendingState = enabled ? hal::Vsync::ENABLE : hal::Vsync::DISABLE;
if (const auto displayId = getInternalDisplayIdLocked()) {
sp<DisplayDevice> display = getDefaultDisplayDeviceLocked();
@@ -1726,7 +1706,7 @@
sp<DisplayDevice> display = getDefaultDisplayDeviceLocked();
LOG_ALWAYS_FATAL_IF(!display);
- const int currentDisplayPowerMode = display->getPowerMode();
+ const hal::PowerMode currentDisplayPowerMode = display->getPowerMode();
// Clear out all the output layers from the composition engine for all
// displays before destroying the hardware composer interface. This ensures
@@ -1819,16 +1799,16 @@
return fence->getSignalTime();
}
-void SurfaceFlinger::populateExpectedPresentTime() {
+nsecs_t SurfaceFlinger::calculateExpectedPresentTime(nsecs_t now) const {
DisplayStatInfo stats;
mScheduler->getDisplayStatInfo(&stats);
- const nsecs_t presentTime = mScheduler->getDispSyncExpectedPresentTime();
+ const nsecs_t presentTime = mScheduler->getDispSyncExpectedPresentTime(now);
// Inflate the expected present time if we're targetting the next vsync.
- mExpectedPresentTime.store(
- mVSyncModulator->getOffsets().sf > 0 ? presentTime : presentTime + stats.vsyncPeriod);
+ return mVSyncModulator->getOffsets().sf > 0 ? presentTime : presentTime + stats.vsyncPeriod;
}
-void SurfaceFlinger::onMessageReceived(int32_t what) NO_THREAD_SAFETY_ANALYSIS {
+void SurfaceFlinger::onMessageReceived(int32_t what,
+ nsecs_t expectedVSyncTime) NO_THREAD_SAFETY_ANALYSIS {
ATRACE_CALL();
switch (what) {
case MessageQueue::INVALIDATE: {
@@ -1837,7 +1817,7 @@
// value throughout this frame to make sure all layers are
// seeing this same value.
const nsecs_t lastExpectedPresentTime = mExpectedPresentTime.load();
- populateExpectedPresentTime();
+ mExpectedPresentTime = expectedVSyncTime;
// When Backpressure propagation is enabled we want to give a small grace period
// for the present fence to fire instead of just giving up on this frame to handle cases
@@ -1928,7 +1908,7 @@
// power mode may operate at a different frame rate than is
// reported in their config, which causes noticeable (but less
// severe) jank.
- if (displayDevice && displayDevice->getPowerMode() == HWC_POWER_MODE_NORMAL) {
+ if (displayDevice && displayDevice->getPowerMode() == hal::PowerMode::ON) {
const nsecs_t currentTime = systemTime();
const nsecs_t jankDuration = currentTime - mMissedFrameJankStart;
if (jankDuration > kMinJankyDuration && jankDuration < kMaxJankyDuration) {
@@ -1953,8 +1933,15 @@
// potentially trigger a display handoff.
updateVrFlinger();
+ if (mTracingEnabledChanged) {
+ mTracingEnabled = mTracing.isEnabled();
+ mTracingEnabledChanged = false;
+ }
+
bool refreshNeeded;
- withTracingLock([&]() {
+ {
+ ConditionalLockGuard<std::mutex> lock(mTracingLock, mTracingEnabled);
+
refreshNeeded = handleMessageTransaction();
refreshNeeded |= handleMessageInvalidate();
if (mTracingEnabled) {
@@ -1964,7 +1951,7 @@
mTracing.notifyLocked("visibleRegionsDirty");
}
}
- });
+ }
// Layers need to get updated (in the previous line) before we can use them for
// choosing the refresh rate.
@@ -2084,6 +2071,8 @@
postFrame();
postComposition();
+ const bool prevFrameHadDeviceComposition = mHadDeviceComposition;
+
mHadClientComposition =
std::any_of(mDisplays.cbegin(), mDisplays.cend(), [](const auto& tokenDisplayPair) {
auto& displayDevice = tokenDisplayPair.second;
@@ -2101,6 +2090,11 @@
return displayDevice->getCompositionDisplay()->getState().reusedClientComposition;
});
+ // Only report a strategy change if we move in and out of composition with hw overlays
+ if (prevFrameHadDeviceComposition != mHadDeviceComposition) {
+ mTimeStats->incrementCompositionStrategyChanges();
+ }
+
mVSyncModulator->onRefreshed(mHadClientComposition);
mLayersWithQueuedFrames.clear();
@@ -2249,7 +2243,7 @@
mTransactionCompletedThread.sendCallbacks();
if (displayDevice && displayDevice->isPrimary() &&
- displayDevice->getPowerMode() == HWC_POWER_MODE_NORMAL && presentFenceTime->isValid()) {
+ displayDevice->getPowerMode() == hal::PowerMode::ON && presentFenceTime->isValid()) {
mScheduler->addPresentFence(presentFenceTime);
}
@@ -2311,6 +2305,9 @@
}
getBE().mLastSwapTime = currentTime;
+ // Cleanup any outstanding resources due to rendering a prior frame.
+ getRenderEngine().cleanupPostRender();
+
{
std::lock_guard lock(mTexturePoolMutex);
if (mTexturePool.size() < mTexturePoolSize) {
@@ -2340,6 +2337,10 @@
}
}
+FloatRect SurfaceFlinger::getLayerClipBoundsForDisplay(const DisplayDevice& displayDevice) const {
+ return displayDevice.getViewport().toFloatRect();
+}
+
void SurfaceFlinger::computeLayerBounds() {
for (const auto& pair : mDisplays) {
const auto& displayDevice = pair.second;
@@ -2350,7 +2351,7 @@
continue;
}
- layer->computeBounds(displayDevice->getViewport().toFloatRect(), ui::Transform(),
+ layer->computeBounds(getLayerClipBoundsForDisplay(*displayDevice), ui::Transform(),
0.f /* shadowRadius */);
}
}
@@ -2408,7 +2409,7 @@
const DisplayId displayId = info->id;
const auto it = mPhysicalDisplayTokens.find(displayId);
- if (event.connection == HWC2::Connection::Connected) {
+ if (event.connection == hal::Connection::CONNECTED) {
if (it == mPhysicalDisplayTokens.end()) {
ALOGV("Creating display %s", to_string(displayId).c_str());
@@ -2512,7 +2513,7 @@
isInternalDisplay ? internalDisplayOrientation : ui::ROTATION_0;
// virtual displays are always considered enabled
- creationArgs.initialPowerMode = state.isVirtual() ? HWC_POWER_MODE_NORMAL : HWC_POWER_MODE_OFF;
+ creationArgs.initialPowerMode = state.isVirtual() ? hal::PowerMode::ON : hal::PowerMode::OFF;
sp<DisplayDevice> display = getFactory().createDisplayDevice(creationArgs);
@@ -2878,19 +2879,6 @@
void SurfaceFlinger::updateInputWindowInfo() {
std::vector<InputWindowInfo> inputHandles;
- // We use a simple caching algorithm here. mInputDirty begins as true,
- // after we call setInputWindows we set it to false, so
- // in the future we wont call it again.. We set input dirty to true again
- // when any layer that hasInput() has a transaction performed on it
- // or when any parent or relative parent of such a layer has a transaction
- // performed on it. Not all of these transactions will really result in
- // input changes but all input changes will spring from these transactions
- // so the cache is safe but not optimal. It seems like it might be annoyingly
- // costly to cache and comapre the actual InputWindowHandle vector though.
- if (!mInputDirty && !mInputWindowCommands.syncInputWindows) {
- return;
- }
-
mDrawingState.traverseInReverseZOrder([&](Layer* layer) {
if (layer->hasInput()) {
// When calculating the screen bounds we ignore the transparent region since it may
@@ -2902,8 +2890,6 @@
mInputFlinger->setInputWindows(inputHandles,
mInputWindowCommands.syncInputWindows ? mSetInputWindowsListener
: nullptr);
-
- mInputDirty = false;
}
void SurfaceFlinger::commitInputWindowCommands() {
@@ -2948,7 +2934,7 @@
currentConfig);
mRefreshRateStats =
std::make_unique<scheduler::RefreshRateStats>(*mRefreshRateConfigs, *mTimeStats,
- currentConfig, HWC_POWER_MODE_OFF);
+ currentConfig, hal::PowerMode::OFF);
mRefreshRateStats->setConfigMode(currentConfig);
mPhaseConfiguration = getFactory().createPhaseConfiguration(*mRefreshRateConfigs);
@@ -3037,26 +3023,6 @@
mDrawingState.traverse([&](Layer* layer) { layer->updateMirrorInfo(); });
}
-void SurfaceFlinger::withTracingLock(std::function<void()> lockedOperation) {
- if (mTracingEnabledChanged) {
- mTracingEnabled = mTracing.isEnabled();
- mTracingEnabledChanged = false;
- }
-
- // Synchronize with Tracing thread
- std::unique_lock<std::mutex> lock;
- if (mTracingEnabled) {
- lock = std::unique_lock<std::mutex>(mDrawingStateLock);
- }
-
- lockedOperation();
-
- // Synchronize with Tracing thread
- if (mTracingEnabled) {
- lock.unlock();
- }
-}
-
void SurfaceFlinger::commitOffscreenLayers() {
for (Layer* offscreenLayer : mOffscreenLayers) {
offscreenLayer->traverse(LayerVector::StateSet::Drawing, [](Layer* layer) {
@@ -3173,7 +3139,7 @@
Mutex::Autolock _l(mStateLock);
sp<Layer> parent;
if (parentHandle != nullptr) {
- parent = fromHandle(parentHandle);
+ parent = fromHandleLocked(parentHandle).promote();
if (parent == nullptr) {
return NAME_NOT_FOUND;
}
@@ -3217,6 +3183,13 @@
return NO_ERROR;
}
+void SurfaceFlinger::removeGraphicBufferProducerAsync(const wp<IBinder>& binder) {
+ static_cast<void>(schedule([=] {
+ Mutex::Autolock lock(mStateLock);
+ mGraphicBufferProducerList.erase(binder);
+ }));
+}
+
uint32_t SurfaceFlinger::peekTransactionFlags() {
return mTransactionFlags;
}
@@ -3255,7 +3228,6 @@
while (!transactionQueue.empty()) {
const auto& transaction = transactionQueue.front();
if (!transactionIsReadyToBeApplied(transaction.desiredPresentTime,
- true /* useCachedExpectedPresentTime */,
transaction.states)) {
setTransactionFlags(eTransactionFlushNeeded);
break;
@@ -3287,10 +3259,7 @@
bool SurfaceFlinger::transactionIsReadyToBeApplied(int64_t desiredPresentTime,
- bool useCachedExpectedPresentTime,
const Vector<ComposerState>& states) {
- if (!useCachedExpectedPresentTime)
- populateExpectedPresentTime();
const nsecs_t expectedPresentTime = mExpectedPresentTime.load();
// Do not present if the desiredPresentTime has not passed unless it is more than one second
@@ -3342,9 +3311,13 @@
}
}
+ const bool pendingTransactions = itr != mTransactionQueues.end();
// Expected present time is computed and cached on invalidate, so it may be stale.
- if (itr != mTransactionQueues.end() || !transactionIsReadyToBeApplied(
- desiredPresentTime, false /* useCachedExpectedPresentTime */, states)) {
+ if (!pendingTransactions) {
+ mExpectedPresentTime = calculateExpectedPresentTime(systemTime());
+ }
+
+ if (pendingTransactions || !transactionIsReadyToBeApplied(desiredPresentTime, states)) {
mTransactionQueues[applyToken].emplace(states, displays, flags, desiredPresentTime,
uncacheBuffer, postTime, privileged,
hasListenerCallbacks, listenerCallbacks);
@@ -3548,7 +3521,7 @@
sp<Layer> layer = nullptr;
if (s.surface) {
- layer = fromHandle(s.surface);
+ layer = fromHandleLocked(s.surface).promote();
} else {
// The client may provide us a null handle. Treat it as if the layer was removed.
ALOGW("Attempt to set client state with a null layer handle");
@@ -3864,7 +3837,7 @@
{
Mutex::Autolock _l(mStateLock);
- mirrorFrom = fromHandle(mirrorFromHandle);
+ mirrorFrom = fromHandleLocked(mirrorFromHandle).promote();
if (!mirrorFrom) {
return NAME_NOT_FOUND;
}
@@ -4127,7 +4100,7 @@
setTransactionState(state, displays, 0, nullptr, mPendingInputWindowCommands, -1, {}, false,
{});
- setPowerModeInternal(display, HWC_POWER_MODE_NORMAL);
+ setPowerModeInternal(display, hal::PowerMode::ON);
const nsecs_t vsyncPeriod = getVsyncPeriod();
mAnimFrameTracker.setDisplayRefreshPeriod(vsyncPeriod);
@@ -4140,18 +4113,17 @@
void SurfaceFlinger::initializeDisplays() {
// Async since we may be called from the main thread.
- postMessageAsync(
- new LambdaMessage([this]() NO_THREAD_SAFETY_ANALYSIS { onInitializeDisplays(); }));
+ static_cast<void>(schedule([this]() NO_THREAD_SAFETY_ANALYSIS { onInitializeDisplays(); }));
}
-void SurfaceFlinger::setVsyncEnabledInHWC(DisplayId displayId, HWC2::Vsync enabled) {
+void SurfaceFlinger::setVsyncEnabledInHWC(DisplayId displayId, hal::Vsync enabled) {
if (mHWCVsyncState != enabled) {
getHwComposer().setVsyncEnabled(displayId, enabled);
mHWCVsyncState = enabled;
}
}
-void SurfaceFlinger::setPowerModeInternal(const sp<DisplayDevice>& display, int mode) {
+void SurfaceFlinger::setPowerModeInternal(const sp<DisplayDevice>& display, hal::PowerMode mode) {
if (display->isVirtual()) {
ALOGE("%s: Invalid operation on virtual display", __FUNCTION__);
return;
@@ -4162,7 +4134,7 @@
ALOGD("Setting power mode %d on display %s", mode, to_string(*displayId).c_str());
- int currentMode = display->getPowerMode();
+ const hal::PowerMode currentMode = display->getPowerMode();
if (mode == currentMode) {
return;
}
@@ -4170,15 +4142,15 @@
display->setPowerMode(mode);
if (mInterceptor->isEnabled()) {
- mInterceptor->savePowerModeUpdate(display->getSequenceId(), mode);
+ mInterceptor->savePowerModeUpdate(display->getSequenceId(), static_cast<int32_t>(mode));
}
- if (currentMode == HWC_POWER_MODE_OFF) {
+ if (currentMode == hal::PowerMode::OFF) {
if (SurfaceFlinger::setSchedFifo(true) != NO_ERROR) {
ALOGW("Couldn't set SCHED_FIFO on display on: %s\n", strerror(errno));
}
getHwComposer().setPowerMode(*displayId, mode);
- if (display->isPrimary() && mode != HWC_POWER_MODE_DOZE_SUSPEND) {
+ if (display->isPrimary() && mode != hal::PowerMode::DOZE_SUSPEND) {
setVsyncEnabledInHWC(*displayId, mHWCVsyncPendingState);
mScheduler->onScreenAcquired(mAppConnectionHandle);
mScheduler->resyncToHardwareVsync(true, getVsyncPeriod());
@@ -4187,31 +4159,30 @@
mVisibleRegionsDirty = true;
mHasPoweredOff = true;
repaintEverything();
- } else if (mode == HWC_POWER_MODE_OFF) {
+ } else if (mode == hal::PowerMode::OFF) {
// Turn off the display
if (SurfaceFlinger::setSchedFifo(false) != NO_ERROR) {
ALOGW("Couldn't set SCHED_OTHER on display off: %s\n", strerror(errno));
}
- if (display->isPrimary() && currentMode != HWC_POWER_MODE_DOZE_SUSPEND) {
+ if (display->isPrimary() && currentMode != hal::PowerMode::DOZE_SUSPEND) {
mScheduler->disableHardwareVsync(true);
mScheduler->onScreenReleased(mAppConnectionHandle);
}
// Make sure HWVsync is disabled before turning off the display
- setVsyncEnabledInHWC(*displayId, HWC2::Vsync::Disable);
+ setVsyncEnabledInHWC(*displayId, hal::Vsync::DISABLE);
getHwComposer().setPowerMode(*displayId, mode);
mVisibleRegionsDirty = true;
// from this point on, SF will stop drawing on this display
- } else if (mode == HWC_POWER_MODE_DOZE ||
- mode == HWC_POWER_MODE_NORMAL) {
+ } else if (mode == hal::PowerMode::DOZE || mode == hal::PowerMode::ON) {
// Update display while dozing
getHwComposer().setPowerMode(*displayId, mode);
- if (display->isPrimary() && currentMode == HWC_POWER_MODE_DOZE_SUSPEND) {
+ if (display->isPrimary() && currentMode == hal::PowerMode::DOZE_SUSPEND) {
mScheduler->onScreenAcquired(mAppConnectionHandle);
mScheduler->resyncToHardwareVsync(true, getVsyncPeriod());
}
- } else if (mode == HWC_POWER_MODE_DOZE_SUSPEND) {
+ } else if (mode == hal::PowerMode::DOZE_SUSPEND) {
// Leave display going to doze
if (display->isPrimary()) {
mScheduler->disableHardwareVsync(true);
@@ -4226,14 +4197,14 @@
if (display->isPrimary()) {
mTimeStats->setPowerMode(mode);
mRefreshRateStats->setPowerMode(mode);
- mScheduler->setDisplayPowerState(mode == HWC_POWER_MODE_NORMAL);
+ mScheduler->setDisplayPowerState(mode == hal::PowerMode::ON);
}
ALOGD("Finished setting power mode %d on display %s", mode, to_string(*displayId).c_str());
}
void SurfaceFlinger::setPowerMode(const sp<IBinder>& displayToken, int mode) {
- postMessageSync(new LambdaMessage([&]() NO_THREAD_SAFETY_ANALYSIS {
+ schedule([=]() NO_THREAD_SAFETY_ANALYSIS {
const auto display = getDisplayDeviceLocked(displayToken);
if (!display) {
ALOGE("Attempt to set power mode %d for invalid display token %p", mode,
@@ -4241,13 +4212,11 @@
} else if (display->isVirtual()) {
ALOGW("Attempt to set power mode %d for virtual display", mode);
} else {
- setPowerModeInternal(display, mode);
+ setPowerModeInternal(display, static_cast<hal::PowerMode>(mode));
}
- }));
+ }).wait();
}
-// ---------------------------------------------------------------------------
-
status_t SurfaceFlinger::doDump(int fd, const DumpArgs& args,
bool asProto) NO_THREAD_SAFETY_ANALYSIS {
std::string result;
@@ -4401,11 +4370,19 @@
scheduler::RefreshRateConfigs::Policy policy = mRefreshRateConfigs->getDisplayManagerPolicy();
StringAppendF(&result,
- "DesiredDisplayConfigSpecs: default config ID: %d"
+ "DesiredDisplayConfigSpecs (DisplayManager): default config ID: %d"
", min: %.2f Hz, max: %.2f Hz",
policy.defaultConfig.value(), policy.minRefreshRate, policy.maxRefreshRate);
StringAppendF(&result, "(config override by backdoor: %s)\n\n",
mDebugDisplayConfigSetByBackdoor ? "yes" : "no");
+ scheduler::RefreshRateConfigs::Policy currentPolicy = mRefreshRateConfigs->getCurrentPolicy();
+ if (currentPolicy != policy) {
+ StringAppendF(&result,
+ "DesiredDisplayConfigSpecs (Override): default config ID: %d"
+ ", min: %.2f Hz, max: %.2f Hz\n\n",
+ currentPolicy.defaultConfig.value(), currentPolicy.minRefreshRate,
+ currentPolicy.maxRefreshRate);
+ }
mScheduler->dump(mAppConnectionHandle, result);
mScheduler->getPrimaryDispSync().dump(result);
@@ -4526,7 +4503,7 @@
void SurfaceFlinger::dumpRawDisplayIdentificationData(const DumpArgs& args,
std::string& result) const {
- hwc2_display_t hwcDisplayId;
+ hal::HWDisplayId hwcDisplayId;
uint8_t port;
DisplayIdentificationData data;
@@ -4563,11 +4540,13 @@
result.append("\n");
}
-LayersProto SurfaceFlinger::dumpDrawingStateProto(
- uint32_t traceFlags, const sp<const DisplayDevice>& displayDevice) const {
+LayersProto SurfaceFlinger::dumpDrawingStateProto(uint32_t traceFlags) const {
+ // If context is SurfaceTracing thread, mTracingLock blocks display transactions on main thread.
+ const auto display = getDefaultDisplayDeviceLocked();
+
LayersProto layersProto;
for (const sp<Layer>& layer : mDrawingState.layersSortedByZ) {
- layer->writeToProto(layersProto, traceFlags, displayDevice);
+ layer->writeToProto(layersProto, traceFlags, display);
}
return layersProto;
@@ -4598,23 +4577,21 @@
}
LayersProto SurfaceFlinger::dumpProtoFromMainThread(uint32_t traceFlags) {
- LayersProto layersProto;
- postMessageSync(new LambdaMessage([&]() {
- const auto& displayDevice = getDefaultDisplayDeviceLocked();
- layersProto = dumpDrawingStateProto(traceFlags, displayDevice);
- }));
- return layersProto;
+ return schedule([=] { return dumpDrawingStateProto(traceFlags); }).get();
}
void SurfaceFlinger::dumpOffscreenLayers(std::string& result) {
result.append("Offscreen Layers:\n");
- postMessageSync(new LambdaMessage([&]() {
- for (Layer* offscreenLayer : mOffscreenLayers) {
- offscreenLayer->traverse(LayerVector::StateSet::Drawing, [&](Layer* layer) {
- layer->dumpCallingUidPid(result);
- });
- }
- }));
+ result.append(schedule([this] {
+ std::string result;
+ for (Layer* offscreenLayer : mOffscreenLayers) {
+ offscreenLayer->traverse(LayerVector::StateSet::Drawing,
+ [&](Layer* layer) {
+ layer->dumpCallingUidPid(result);
+ });
+ }
+ return result;
+ }).get());
}
void SurfaceFlinger::dumpAllLocked(const DumpArgs& args, std::string& result) const {
@@ -4931,9 +4908,9 @@
code == IBinder::SYSPROPS_TRANSACTION) {
return OK;
}
- // Numbers from 1000 to 1034 are currently used for backdoors. The code
+ // Numbers from 1000 to 1036 are currently used for backdoors. The code
// in onTransact verifies that the user is root, and has access to use SF.
- if (code >= 1000 && code <= 1035) {
+ if (code >= 1000 && code <= 1036) {
ALOGV("Accessing SurfaceFlinger through backdoor code: %u", code);
return OK;
}
@@ -5129,20 +5106,12 @@
n = data.readInt32();
if (n) {
ALOGD("LayerTracing enabled");
- Mutex::Autolock lock(mStateLock);
- mTracingEnabledChanged = true;
- mTracing.enable();
+ mTracingEnabledChanged = mTracing.enable();
reply->writeInt32(NO_ERROR);
} else {
ALOGD("LayerTracing disabled");
- bool writeFile = false;
- {
- Mutex::Autolock lock(mStateLock);
- mTracingEnabledChanged = true;
- writeFile = mTracing.disable();
- }
-
- if (writeFile) {
+ mTracingEnabledChanged = mTracing.disable();
+ if (mTracingEnabledChanged) {
reply->writeInt32(mTracing.writeToFile());
} else {
reply->writeInt32(NO_ERROR);
@@ -5270,6 +5239,18 @@
}
return NO_ERROR;
}
+ case 1036: {
+ if (data.readInt32() > 0) {
+ status_t result =
+ acquireFrameRateFlexibilityToken(&mDebugFrameRateFlexibilityToken);
+ if (result != NO_ERROR) {
+ return result;
+ }
+ } else {
+ mDebugFrameRateFlexibilityToken = nullptr;
+ }
+ return NO_ERROR;
+ }
}
}
return err;
@@ -5293,7 +5274,7 @@
// Update the overlay on the main thread to avoid race conditions with
// mRefreshRateConfigs->getCurrentRefreshRate()
- postMessageAsync(new LambdaMessage([this, expired]() NO_THREAD_SAFETY_ANALYSIS {
+ static_cast<void>(schedule([=]() NO_THREAD_SAFETY_ANALYSIS {
if (mRefreshRateOverlay) {
const auto kernelTimerEnabled = property_get_bool(KERNEL_IDLE_TIMER_PROP, false);
const bool timerExpired = kernelTimerEnabled && expired;
@@ -5566,7 +5547,7 @@
{
Mutex::Autolock lock(mStateLock);
- parent = fromHandle(layerHandleBinder);
+ parent = fromHandleLocked(layerHandleBinder).promote();
if (parent == nullptr || parent->isRemovedFromCurrentState()) {
ALOGE("captureLayers called with an invalid or removed parent");
return NAME_NOT_FOUND;
@@ -5599,7 +5580,7 @@
reqHeight = crop.height() * frameScale;
for (const auto& handle : excludeHandles) {
- sp<Layer> excludeLayer = fromHandle(handle);
+ sp<Layer> excludeLayer = fromHandleLocked(handle).promote();
if (excludeLayer != nullptr) {
excludeLayers.emplace(excludeLayer);
} else {
@@ -5669,68 +5650,41 @@
usage, "screenshot");
return captureScreenCommon(renderArea, traverseLayers, *outBuffer, useIdentityTransform,
- outCapturedSecureLayers);
+ false /* regionSampling */, outCapturedSecureLayers);
}
status_t SurfaceFlinger::captureScreenCommon(RenderArea& renderArea,
TraverseLayersFunction traverseLayers,
const sp<GraphicBuffer>& buffer,
- bool useIdentityTransform,
+ bool useIdentityTransform, bool regionSampling,
bool& outCapturedSecureLayers) {
- // This mutex protects syncFd and captureResult for communication of the return values from the
- // main thread back to this Binder thread
- std::mutex captureMutex;
- std::condition_variable captureCondition;
- std::unique_lock<std::mutex> captureLock(captureMutex);
- int syncFd = -1;
- std::optional<status_t> captureResult;
-
const int uid = IPCThreadState::self()->getCallingUid();
const bool forSystem = uid == AID_GRAPHICS || uid == AID_SYSTEM;
- sp<LambdaMessage> message = new LambdaMessage([&] {
- // If there is a refresh pending, bug out early and tell the binder thread to try again
- // after the refresh.
- if (mRefreshPending) {
- ATRACE_NAME("Skipping screenshot for now");
- std::unique_lock<std::mutex> captureLock(captureMutex);
- captureResult = std::make_optional<status_t>(EAGAIN);
- captureCondition.notify_one();
- return;
- }
+ status_t result;
+ int syncFd;
- status_t result = NO_ERROR;
- int fd = -1;
- {
- Mutex::Autolock _l(mStateLock);
- renderArea.render([&] {
- result = captureScreenImplLocked(renderArea, traverseLayers, buffer.get(),
- useIdentityTransform, forSystem, &fd,
- outCapturedSecureLayers);
- });
- }
+ do {
+ std::tie(result, syncFd) =
+ schedule([&] {
+ if (mRefreshPending) {
+ ATRACE_NAME("Skipping screenshot for now");
+ return std::make_pair(EAGAIN, -1);
+ }
- {
- std::unique_lock<std::mutex> captureLock(captureMutex);
- syncFd = fd;
- captureResult = std::make_optional<status_t>(result);
- captureCondition.notify_one();
- }
- });
+ status_t result = NO_ERROR;
+ int fd = -1;
- status_t result = postMessageAsync(message);
- if (result == NO_ERROR) {
- captureCondition.wait(captureLock, [&] { return captureResult; });
- while (*captureResult == EAGAIN) {
- captureResult.reset();
- result = postMessageAsync(message);
- if (result != NO_ERROR) {
- return result;
- }
- captureCondition.wait(captureLock, [&] { return captureResult; });
- }
- result = *captureResult;
- }
+ Mutex::Autolock lock(mStateLock);
+ renderArea.render([&] {
+ result = captureScreenImplLocked(renderArea, traverseLayers, buffer.get(),
+ useIdentityTransform, forSystem, &fd,
+ regionSampling, outCapturedSecureLayers);
+ });
+
+ return std::make_pair(result, fd);
+ }).get();
+ } while (result == EAGAIN);
if (result == NO_ERROR) {
sync_wait(syncFd, -1);
@@ -5743,7 +5697,7 @@
void SurfaceFlinger::renderScreenImplLocked(const RenderArea& renderArea,
TraverseLayersFunction traverseLayers,
ANativeWindowBuffer* buffer, bool useIdentityTransform,
- int* outSyncFd) {
+ bool regionSampling, int* outSyncFd) {
ATRACE_CALL();
const auto reqWidth = renderArea.getReqWidth();
@@ -5799,6 +5753,12 @@
for (auto& settings : results) {
settings.geometry.positionTransform =
transform.asMatrix4() * settings.geometry.positionTransform;
+ // There's no need to process blurs when we're executing region sampling,
+ // we're just trying to understand what we're drawing, and doing so without
+ // blurs is already a pretty good approximation.
+ if (regionSampling) {
+ settings.backgroundBlurRadius = 0;
+ }
}
clientCompositionLayers.insert(clientCompositionLayers.end(),
std::make_move_iterator(results.begin()),
@@ -5836,7 +5796,8 @@
TraverseLayersFunction traverseLayers,
ANativeWindowBuffer* buffer,
bool useIdentityTransform, bool forSystem,
- int* outSyncFd, bool& outCapturedSecureLayers) {
+ int* outSyncFd, bool regionSampling,
+ bool& outCapturedSecureLayers) {
ATRACE_CALL();
traverseLayers([&](Layer* layer) {
@@ -5851,7 +5812,8 @@
ALOGW("FB is protected: PERMISSION_DENIED");
return PERMISSION_DENIED;
}
- renderScreenImplLocked(renderArea, traverseLayers, buffer, useIdentityTransform, outSyncFd);
+ renderScreenImplLocked(renderArea, traverseLayers, buffer, useIdentityTransform, regionSampling,
+ outSyncFd);
return NO_ERROR;
}
@@ -5915,11 +5877,11 @@
const auto displayId = display->getId();
LOG_ALWAYS_FATAL_IF(!displayId);
- HWC2::VsyncPeriodChangeConstraints constraints;
+ hal::VsyncPeriodChangeConstraints constraints;
constraints.desiredTimeNanos = systemTime();
constraints.seamlessRequired = false;
- HWC2::VsyncPeriodChangeTimeline timeline = {0, 0, 0};
+ hal::VsyncPeriodChangeTimeline timeline = {0, 0, 0};
if (getHwComposer().setActiveConfigWithConstraints(*displayId,
policy->defaultConfig.value(),
constraints, &timeline) < 0) {
@@ -5997,28 +5959,25 @@
return BAD_VALUE;
}
- status_t result = NAME_NOT_FOUND;
-
- postMessageSync(new LambdaMessage([&]() {
+ auto future = schedule([=]() -> status_t {
const auto display = getDisplayDeviceLocked(displayToken);
if (!display) {
ALOGE("Attempt to set desired display configs for invalid display token %p",
displayToken.get());
+ return NAME_NOT_FOUND;
} else if (display->isVirtual()) {
ALOGW("Attempt to set desired display configs for virtual display");
- result = INVALID_OPERATION;
+ return INVALID_OPERATION;
} else {
- result = setDesiredDisplayConfigSpecsInternal(display,
- scheduler::RefreshRateConfigs::
- Policy{HwcConfigIndexType(
- defaultConfig),
- minRefreshRate,
- maxRefreshRate},
- /*overridePolicy=*/false);
- }
- }));
+ using Policy = scheduler::RefreshRateConfigs::Policy;
+ const Policy policy{HwcConfigIndexType(defaultConfig), minRefreshRate, maxRefreshRate};
+ constexpr bool kOverridePolicy = false;
- return result;
+ return setDesiredDisplayConfigSpecsInternal(display, policy, kOverridePolicy);
+ }
+ });
+
+ return future.get();
}
status_t SurfaceFlinger::getDesiredDisplayConfigSpecs(const sp<IBinder>& displayToken,
@@ -6062,7 +6021,12 @@
mFlinger->setInputWindowsFinished();
}
-sp<Layer> SurfaceFlinger::fromHandle(const sp<IBinder>& handle) {
+wp<Layer> SurfaceFlinger::fromHandle(const sp<IBinder>& handle) {
+ Mutex::Autolock _l(mStateLock);
+ return fromHandleLocked(handle);
+}
+
+wp<Layer> SurfaceFlinger::fromHandleLocked(const sp<IBinder>& handle) {
BBinder* b = nullptr;
if (handle) {
b = handle->localBinder();
@@ -6072,7 +6036,7 @@
}
auto it = mLayersByLocalBinderToken.find(b);
if (it != mLayersByLocalBinderToken.end()) {
- return it->second.promote();
+ return it->second;
}
return nullptr;
}
@@ -6142,7 +6106,7 @@
return BAD_VALUE;
}
- postMessageAsync(new LambdaMessage([=]() NO_THREAD_SAFETY_ANALYSIS {
+ static_cast<void>(schedule([=]() NO_THREAD_SAFETY_ANALYSIS {
Mutex::Autolock lock(mStateLock);
if (authenticateSurfaceTextureLocked(surface)) {
sp<Layer> layer = (static_cast<MonitoredProducer*>(surface.get()))->getLayer();
@@ -6165,8 +6129,11 @@
if (!outToken) {
return BAD_VALUE;
}
- status_t result = NO_ERROR;
- postMessageSync(new LambdaMessage([&]() {
+
+ auto future = schedule([this] {
+ status_t result = NO_ERROR;
+ sp<IBinder> token;
+
if (mFrameRateFlexibilityTokenCount == 0) {
// |mStateLock| not needed as we are on the main thread
const auto display = getDefaultDisplayDeviceLocked();
@@ -6180,8 +6147,8 @@
overridePolicy.defaultConfig =
mRefreshRateConfigs->getDisplayManagerPolicy().defaultConfig;
overridePolicy.allowGroupSwitching = true;
- result = setDesiredDisplayConfigSpecsInternal(display, overridePolicy,
- /*overridePolicy=*/true);
+ constexpr bool kOverridePolicy = true;
+ result = setDesiredDisplayConfigSpecsInternal(display, overridePolicy, kOverridePolicy);
}
if (result == NO_ERROR) {
@@ -6198,17 +6165,22 @@
// 2. The frame rate flexibility token is acquired/released only by CTS tests, so even
// if condition 1 were changed, the problem would only show up when running CTS tests,
// not on end user devices, so we could spot it and fix it without serious impact.
- *outToken = new FrameRateFlexibilityToken(
+ token = new FrameRateFlexibilityToken(
[this]() { onFrameRateFlexibilityTokenReleased(); });
ALOGD("Frame rate flexibility token acquired. count=%d",
mFrameRateFlexibilityTokenCount);
}
- }));
+
+ return std::make_pair(result, token);
+ });
+
+ status_t result;
+ std::tie(result, *outToken) = future.get();
return result;
}
void SurfaceFlinger::onFrameRateFlexibilityTokenReleased() {
- postMessageAsync(new LambdaMessage([&]() {
+ static_cast<void>(schedule([this] {
LOG_ALWAYS_FATAL_IF(mFrameRateFlexibilityTokenCount == 0,
"Failed tracking frame rate flexibility tokens");
mFrameRateFlexibilityTokenCount--;
@@ -6216,8 +6188,8 @@
if (mFrameRateFlexibilityTokenCount == 0) {
// |mStateLock| not needed as we are on the main thread
const auto display = getDefaultDisplayDeviceLocked();
- status_t result =
- setDesiredDisplayConfigSpecsInternal(display, {}, /*overridePolicy=*/true);
+ constexpr bool kOverridePolicy = true;
+ status_t result = setDesiredDisplayConfigSpecsInternal(display, {}, kOverridePolicy);
LOG_ALWAYS_FATAL_IF(result < 0, "Failed releasing frame rate flexibility token");
}
}));
diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h
index f3c481a..b65e4f6 100644
--- a/services/surfaceflinger/SurfaceFlinger.h
+++ b/services/surfaceflinger/SurfaceFlinger.h
@@ -33,7 +33,6 @@
#include <gui/ITransactionCompletedListener.h>
#include <gui/LayerState.h>
#include <gui/OccupancyTracker.h>
-#include <hardware/hwcomposer_defs.h>
#include <input/ISetInputWindowsListener.h>
#include <layerproto/LayerProtoHeader.h>
#include <math/mat4.h>
@@ -69,6 +68,7 @@
#include <atomic>
#include <cstdint>
#include <functional>
+#include <future>
#include <map>
#include <memory>
#include <mutex>
@@ -277,12 +277,9 @@
// starts SurfaceFlinger main loop in the current thread
void run() ANDROID_API;
- // post an asynchronous message to the main thread
- status_t postMessageAsync(const sp<MessageBase>& msg, nsecs_t reltime = 0, uint32_t flags = 0);
-
- // post a synchronous message to the main thread
- status_t postMessageSync(const sp<MessageBase>& msg, nsecs_t reltime = 0, uint32_t flags = 0)
- EXCLUDES(mStateLock);
+ // Schedule an asynchronous or synchronous task on the main thread.
+ template <typename F, typename T = std::invoke_result_t<F>>
+ [[nodiscard]] std::future<T> schedule(F&&);
// force full composition on all displays
void repaintEverything();
@@ -311,12 +308,12 @@
// main thread function to enable/disable h/w composer event
void setPrimaryVsyncEnabledInternal(bool enabled);
- void setVsyncEnabledInHWC(DisplayId displayId, HWC2::Vsync enabled);
+ void setVsyncEnabledInHWC(DisplayId displayId, hal::Vsync enabled);
// called on the main thread by MessageQueue when an internal message
// is received
// TODO: this should be made accessible only to MessageQueue
- void onMessageReceived(int32_t what);
+ void onMessageReceived(int32_t what, nsecs_t expectedVSyncTime);
renderengine::RenderEngine& getRenderEngine() const;
@@ -332,7 +329,12 @@
return mTransactionCompletedThread;
}
- sp<Layer> fromHandle(const sp<IBinder>& handle) REQUIRES(mStateLock);
+ // Converts from a binder handle to a Layer
+ // Returns nullptr if the handle does not point to an existing layer.
+ // Otherwise, returns a weak reference so that callers off the main-thread
+ // won't accidentally hold onto the last strong reference.
+ wp<Layer> fromHandle(const sp<IBinder>& handle);
+ wp<Layer> fromHandleLocked(const sp<IBinder>& handle) REQUIRES(mStateLock);
// Inherit from ClientCache::ErasedRecipient
void bufferErased(const client_cache_t& clientCacheId) override;
@@ -517,15 +519,15 @@
/* ------------------------------------------------------------------------
* HWC2::ComposerCallback / HWComposer::EventHandler interface
*/
- void onVsyncReceived(int32_t sequenceId, hwc2_display_t hwcDisplayId, int64_t timestamp,
- std::optional<hwc2_vsync_period_t> vsyncPeriod) override;
- void onHotplugReceived(int32_t sequenceId, hwc2_display_t hwcDisplayId,
- HWC2::Connection connection) override;
- void onRefreshReceived(int32_t sequenceId, hwc2_display_t hwcDisplayId) override;
+ void onVsyncReceived(int32_t sequenceId, hal::HWDisplayId hwcDisplayId, int64_t timestamp,
+ std::optional<hal::VsyncPeriodNanos> vsyncPeriod) override;
+ void onHotplugReceived(int32_t sequenceId, hal::HWDisplayId hwcDisplayId,
+ hal::Connection connection) override;
+ void onRefreshReceived(int32_t sequenceId, hal::HWDisplayId hwcDisplayId) override;
void onVsyncPeriodTimingChangedReceived(
- int32_t sequenceId, hwc2_display_t display,
- const hwc_vsync_period_change_timeline_t& updatedTimeline) override;
- void onSeamlessPossible(int32_t sequenceId, hwc2_display_t display) override;
+ int32_t sequenceId, hal::HWDisplayId display,
+ const hal::VsyncPeriodChangeTimeline& updatedTimeline) override;
+ void onSeamlessPossible(int32_t sequenceId, hal::HWDisplayId display) override;
/* ------------------------------------------------------------------------
* ISchedulerCallback
@@ -538,7 +540,6 @@
/* ------------------------------------------------------------------------
* Message handling
*/
- void waitForEvent();
// Can only be called from the main thread or with mStateLock held
void signalTransaction();
// Can only be called from the main thread or with mStateLock held
@@ -570,7 +571,8 @@
// Called when active config is no longer is progress
void desiredActiveConfigChangeDone() REQUIRES(mStateLock);
// called on the main thread in response to setPowerMode()
- void setPowerModeInternal(const sp<DisplayDevice>& display, int mode) REQUIRES(mStateLock);
+ void setPowerModeInternal(const sp<DisplayDevice>& display, hal::PowerMode mode)
+ REQUIRES(mStateLock);
// Sets the desired display configs.
status_t setDesiredDisplayConfigSpecsInternal(
@@ -625,7 +627,6 @@
void commitTransaction() REQUIRES(mStateLock);
void commitOffscreenLayers();
bool transactionIsReadyToBeApplied(int64_t desiredPresentTime,
- bool useCachedExpectedPresentTime,
const Vector<ComposerState>& states);
uint32_t setDisplayStateLocked(const DisplayState& s) REQUIRES(mStateLock);
uint32_t addInputWindowCommands(const InputWindowCommands& inputWindowCommands)
@@ -639,6 +640,13 @@
REQUIRES(mStateLock);
virtual void commitTransactionLocked();
+ // Used internally by computeLayerBounds() to gets the clip rectangle to use for the
+ // root layers on a particular display in layer-coordinate space. The
+ // layers (and effectively their children) will be clipped against this
+ // rectangle. The base behavior is to clip to the visible region of the
+ // display.
+ virtual FloatRect getLayerClipBoundsForDisplay(const DisplayDevice&) const;
+
private:
/* ------------------------------------------------------------------------
* Layer management
@@ -697,19 +705,20 @@
void renderScreenImplLocked(const RenderArea& renderArea, TraverseLayersFunction traverseLayers,
ANativeWindowBuffer* buffer, bool useIdentityTransform,
- int* outSyncFd);
+ bool regionSampling, int* outSyncFd);
status_t captureScreenCommon(RenderArea& renderArea, TraverseLayersFunction traverseLayers,
sp<GraphicBuffer>* outBuffer, const ui::PixelFormat reqPixelFormat,
bool useIdentityTransform, bool& outCapturedSecureLayers);
status_t captureScreenCommon(RenderArea& renderArea, TraverseLayersFunction traverseLayers,
const sp<GraphicBuffer>& buffer, bool useIdentityTransform,
- bool& outCapturedSecureLayers);
+ bool regionSampling, bool& outCapturedSecureLayers);
const sp<DisplayDevice> getDisplayByIdOrLayerStack(uint64_t displayOrLayerStack);
const sp<DisplayDevice> getDisplayByLayerStack(uint64_t layerStack);
status_t captureScreenImplLocked(const RenderArea& renderArea,
TraverseLayersFunction traverseLayers,
ANativeWindowBuffer* buffer, bool useIdentityTransform,
- bool forSystem, int* outSyncFd, bool& outCapturedSecureLayers);
+ bool forSystem, int* outSyncFd, bool regionSampling,
+ bool& outCapturedSecureLayers);
void traverseLayersInDisplay(const sp<const DisplayDevice>& display,
const LayerVector::Visitor& visitor);
@@ -847,9 +856,9 @@
// Must be called on the main thread.
nsecs_t previousFramePresentTime();
- // Populates the expected present time for this frame. For negative offsets, performs a
+ // Calculates the expected present time for this frame. For negative offsets, performs a
// correction using the predicted vsync for the next frame instead.
- void populateExpectedPresentTime();
+ nsecs_t calculateExpectedPresentTime(nsecs_t now) const;
/*
* Display identification
@@ -929,8 +938,7 @@
void dumpDisplayIdentificationData(std::string& result) const;
void dumpRawDisplayIdentificationData(const DumpArgs&, std::string& result) const;
void dumpWideColorInfo(std::string& result) const;
- LayersProto dumpDrawingStateProto(uint32_t traceFlags = SurfaceTracing::TRACE_ALL,
- const sp<const DisplayDevice>& displayDevice = nullptr) const;
+ LayersProto dumpDrawingStateProto(uint32_t traceFlags) const;
void dumpOffscreenLayersProto(LayersProto& layersProto,
uint32_t traceFlags = SurfaceTracing::TRACE_ALL) const;
// Dumps state from HW Composer
@@ -938,7 +946,6 @@
LayersProto dumpProtoFromMainThread(uint32_t traceFlags = SurfaceTracing::TRACE_ALL)
EXCLUDES(mStateLock);
void dumpOffscreenLayers(std::string& result) EXCLUDES(mStateLock);
- void withTracingLock(std::function<void()> operation) REQUIRES(mStateLock);
bool isLayerTripleBufferingDisabled() const {
return this->mLayerTripleBufferingDisabled;
@@ -980,9 +987,6 @@
SortedVector<sp<Layer>> mLayersPendingRemoval;
bool mTraversalNeededMainThread = false;
- // guards access to the mDrawing state if tracing is enabled.
- mutable std::mutex mDrawingStateLock;
-
// global color transform states
Daltonizer mDaltonizer;
float mGlobalSaturationFactor = 1.0f;
@@ -992,6 +996,8 @@
std::set<wp<IBinder>> mGraphicBufferProducerList;
size_t mMaxGraphicBufferProducerListSize = ISurfaceComposer::MAX_LAYERS;
+ void removeGraphicBufferProducerAsync(const wp<IBinder>&);
+
// protected by mStateLock (but we could use another lock)
bool mLayersRemoved = false;
bool mLayersAdded = false;
@@ -1034,8 +1040,8 @@
BootStage mBootStage = BootStage::BOOTLOADER;
struct HotplugEvent {
- hwc2_display_t hwcDisplayId;
- HWC2::Connection connection = HWC2::Connection::Invalid;
+ hal::HWDisplayId hwcDisplayId;
+ hal::Connection connection = hal::Connection::INVALID;
};
// protected by mStateLock
std::vector<HotplugEvent> mPendingHotplugEvents;
@@ -1057,10 +1063,13 @@
bool mPropagateBackpressure = true;
bool mPropagateBackpressureClientComposition = false;
std::unique_ptr<SurfaceInterceptor> mInterceptor;
+
SurfaceTracing mTracing{*this};
+ std::mutex mTracingLock;
bool mTracingEnabled = false;
bool mAddCompositionStateToTrace = false;
- bool mTracingEnabledChanged GUARDED_BY(mStateLock) = false;
+ std::atomic<bool> mTracingEnabledChanged = false;
+
const std::shared_ptr<TimeStats> mTimeStats;
const std::unique_ptr<FrameTracer> mFrameTracer;
bool mUseHwcVirtualDisplays = false;
@@ -1250,20 +1259,17 @@
std::unordered_set<Layer*> mOffscreenLayers;
// Flags to capture the state of Vsync in HWC
- HWC2::Vsync mHWCVsyncState = HWC2::Vsync::Disable;
- HWC2::Vsync mHWCVsyncPendingState = HWC2::Vsync::Disable;
+ hal::Vsync mHWCVsyncState = hal::Vsync::DISABLE;
+ hal::Vsync mHWCVsyncPendingState = hal::Vsync::DISABLE;
// Fields tracking the current jank event: when it started and how many
// janky frames there are.
nsecs_t mMissedFrameJankStart = 0;
int32_t mMissedFrameJankCount = 0;
- // See updateInputWindowInfo() for details
- std::atomic<bool> mInputDirty = true;
- void dirtyInput() { mInputDirty = true; }
- bool inputDirty() { return mInputDirty; }
-
int mFrameRateFlexibilityTokenCount = 0;
+
+ sp<IBinder> mDebugFrameRateFlexibilityToken;
};
} // namespace android
diff --git a/services/surfaceflinger/SurfaceTracing.cpp b/services/surfaceflinger/SurfaceTracing.cpp
index f0b895d..d84ce69 100644
--- a/services/surfaceflinger/SurfaceTracing.cpp
+++ b/services/surfaceflinger/SurfaceTracing.cpp
@@ -33,7 +33,7 @@
namespace android {
SurfaceTracing::SurfaceTracing(SurfaceFlinger& flinger)
- : mFlinger(flinger), mSfLock(flinger.mDrawingStateLock) {}
+ : mFlinger(flinger), mSfLock(flinger.mTracingLock) {}
void SurfaceTracing::mainLoop() {
bool enabled = addFirstEntry();
@@ -44,21 +44,19 @@
}
bool SurfaceTracing::addFirstEntry() {
- const auto displayDevice = mFlinger.getDefaultDisplayDevice();
LayersTraceProto entry;
{
std::scoped_lock lock(mSfLock);
- entry = traceLayersLocked("tracing.enable", displayDevice);
+ entry = traceLayersLocked("tracing.enable");
}
return addTraceToBuffer(entry);
}
LayersTraceProto SurfaceTracing::traceWhenNotified() {
- const auto displayDevice = mFlinger.getDefaultDisplayDevice();
std::unique_lock<std::mutex> lock(mSfLock);
mCanStartTrace.wait(lock);
android::base::ScopedLockAssertion assumeLock(mSfLock);
- LayersTraceProto entry = traceLayersLocked(mWhere, displayDevice);
+ LayersTraceProto entry = traceLayersLocked(mWhere);
mTracingInProgress = false;
mMissedTraceEntries = 0;
lock.unlock();
@@ -126,15 +124,17 @@
}
}
-void SurfaceTracing::enable() {
+bool SurfaceTracing::enable() {
std::scoped_lock lock(mTraceLock);
if (mEnabled) {
- return;
+ return false;
}
+
mBuffer.reset(mBufferSize);
mEnabled = true;
mThread = std::thread(&SurfaceTracing::mainLoop, this);
+ return true;
}
status_t SurfaceTracing::writeToFile() {
@@ -176,14 +176,13 @@
mTraceFlags = flags;
}
-LayersTraceProto SurfaceTracing::traceLayersLocked(const char* where,
- const sp<const DisplayDevice>& displayDevice) {
+LayersTraceProto SurfaceTracing::traceLayersLocked(const char* where) {
ATRACE_CALL();
LayersTraceProto entry;
entry.set_elapsed_realtime_nanos(elapsedRealtimeNano());
entry.set_where(where);
- LayersProto layers(mFlinger.dumpDrawingStateProto(mTraceFlags, displayDevice));
+ LayersProto layers(mFlinger.dumpDrawingStateProto(mTraceFlags));
if (flagIsSetLocked(SurfaceTracing::TRACE_EXTRA)) {
mFlinger.dumpOffscreenLayersProto(layers);
diff --git a/services/surfaceflinger/SurfaceTracing.h b/services/surfaceflinger/SurfaceTracing.h
index e90fc4d..f208eb8 100644
--- a/services/surfaceflinger/SurfaceTracing.h
+++ b/services/surfaceflinger/SurfaceTracing.h
@@ -27,8 +27,6 @@
#include <queue>
#include <thread>
-#include "DisplayDevice.h"
-
using namespace android::surfaceflinger;
namespace android {
@@ -44,7 +42,7 @@
class SurfaceTracing {
public:
explicit SurfaceTracing(SurfaceFlinger& flinger);
- void enable();
+ bool enable();
bool disable();
status_t writeToFile();
bool isEnabled() const;
@@ -92,9 +90,7 @@
void mainLoop();
bool addFirstEntry();
LayersTraceProto traceWhenNotified();
- LayersTraceProto traceLayersLocked(const char* where,
- const sp<const DisplayDevice>& displayDevice)
- REQUIRES(mSfLock);
+ LayersTraceProto traceLayersLocked(const char* where) REQUIRES(mSfLock);
// Returns true if trace is enabled.
bool addTraceToBuffer(LayersTraceProto& entry);
diff --git a/services/surfaceflinger/TimeStats/Android.bp b/services/surfaceflinger/TimeStats/Android.bp
index d27fbb4..3901757 100644
--- a/services/surfaceflinger/TimeStats/Android.bp
+++ b/services/surfaceflinger/TimeStats/Android.bp
@@ -4,6 +4,7 @@
"TimeStats.cpp",
],
shared_libs: [
+ "android.hardware.graphics.composer@2.4",
"libbase",
"libcutils",
"liblog",
diff --git a/services/surfaceflinger/TimeStats/TimeStats.cpp b/services/surfaceflinger/TimeStats/TimeStats.cpp
index 606e137..37194c6 100644
--- a/services/surfaceflinger/TimeStats/TimeStats.cpp
+++ b/services/surfaceflinger/TimeStats/TimeStats.cpp
@@ -290,6 +290,15 @@
mTimeStats.refreshRateSwitches++;
}
+void TimeStats::incrementCompositionStrategyChanges() {
+ if (!mEnabled.load()) return;
+
+ ATRACE_CALL();
+
+ std::lock_guard<std::mutex> lock(mMutex);
+ mTimeStats.compositionStrategyChanges++;
+}
+
void TimeStats::recordDisplayEventConnectionCount(int32_t count) {
if (!mEnabled.load()) return;
@@ -312,7 +321,7 @@
if (!mEnabled.load()) return;
std::lock_guard<std::mutex> lock(mMutex);
- if (mPowerTime.powerMode == HWC_POWER_MODE_NORMAL) {
+ if (mPowerTime.powerMode == PowerMode::ON) {
mTimeStats.frameDuration.insert(msBetween(startTime, endTime));
}
}
@@ -683,12 +692,13 @@
int64_t elapsedTime = (curTime - mPowerTime.prevTime) / 1000000;
switch (mPowerTime.powerMode) {
- case HWC_POWER_MODE_NORMAL:
+ case PowerMode::ON:
mTimeStats.displayOnTime += elapsedTime;
break;
- case HWC_POWER_MODE_OFF:
- case HWC_POWER_MODE_DOZE:
- case HWC_POWER_MODE_DOZE_SUSPEND:
+ case PowerMode::OFF:
+ case PowerMode::DOZE:
+ case PowerMode::DOZE_SUSPEND:
+ case PowerMode::ON_SUSPEND:
default:
break;
}
@@ -696,7 +706,7 @@
mPowerTime.prevTime = curTime;
}
-void TimeStats::setPowerMode(int32_t powerMode) {
+void TimeStats::setPowerMode(PowerMode powerMode) {
if (!mEnabled.load()) {
std::lock_guard<std::mutex> lock(mMutex);
mPowerTime.powerMode = powerMode;
@@ -784,8 +794,8 @@
return;
}
- if (mPowerTime.powerMode != HWC_POWER_MODE_NORMAL) {
- // Try flushing the last present fence on HWC_POWER_MODE_NORMAL.
+ if (mPowerTime.powerMode != PowerMode::ON) {
+ // Try flushing the last present fence on PowerMode::ON.
flushAvailableGlobalRecordsToStatsLocked();
mGlobalRecord.presentFences.clear();
mGlobalRecord.prevPresentTime = 0;
@@ -844,6 +854,7 @@
mTimeStats.clientCompositionFrames = 0;
mTimeStats.clientCompositionReusedFrames = 0;
mTimeStats.refreshRateSwitches = 0;
+ mTimeStats.compositionStrategyChanges = 0;
mTimeStats.displayEventConnectionsCount = 0;
mTimeStats.displayOnTime = 0;
mTimeStats.presentToPresent.hist.clear();
diff --git a/services/surfaceflinger/TimeStats/TimeStats.h b/services/surfaceflinger/TimeStats/TimeStats.h
index 806b47e..8de5d0c 100644
--- a/services/surfaceflinger/TimeStats/TimeStats.h
+++ b/services/surfaceflinger/TimeStats/TimeStats.h
@@ -16,7 +16,15 @@
#pragma once
-#include <hardware/hwcomposer_defs.h>
+// TODO(b/129481165): remove the #pragma below and fix conversion issues
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wconversion"
+
+#include <android/hardware/graphics/composer/2.4/IComposerClient.h>
+
+// TODO(b/129481165): remove the #pragma below and fix conversion issues
+#pragma clang diagnostic pop // ignored "-Wconversion"
+
#include <stats_event.h>
#include <stats_pull_atom_callback.h>
#include <statslog.h>
@@ -54,6 +62,10 @@
virtual void incrementClientCompositionReusedFrames() = 0;
// Increments the number of times the display refresh rate changed.
virtual void incrementRefreshRateSwitches() = 0;
+ // Increments the number of changes in composition strategy
+ // The intention is to reflect the number of changes between hwc and gpu
+ // composition, where "gpu composition" may also include mixed composition.
+ virtual void incrementCompositionStrategyChanges() = 0;
// Records the most up-to-date count of display event connections.
// The stored count will be the maximum ever recoded.
virtual void recordDisplayEventConnectionCount(int32_t count) = 0;
@@ -101,7 +113,8 @@
// If SF skips or rejects a buffer, remove the corresponding TimeRecord.
virtual void removeTimeRecord(int32_t layerId, uint64_t frameNumber) = 0;
- virtual void setPowerMode(int32_t powerMode) = 0;
+ virtual void setPowerMode(
+ hardware::graphics::composer::V2_4::IComposerClient::PowerMode powerMode) = 0;
// Source of truth is RefrehRateStats.
virtual void recordRefreshRate(uint32_t fps, nsecs_t duration) = 0;
virtual void setPresentFenceGlobal(const std::shared_ptr<FenceTime>& presentFence) = 0;
@@ -110,6 +123,8 @@
namespace impl {
class TimeStats : public android::TimeStats {
+ using PowerMode = android::hardware::graphics::composer::V2_4::IComposerClient::PowerMode;
+
struct FrameTime {
uint64_t frameNumber = 0;
nsecs_t postTime = 0;
@@ -140,7 +155,7 @@
};
struct PowerTime {
- int32_t powerMode = HWC_POWER_MODE_OFF;
+ PowerMode powerMode = PowerMode::OFF;
nsecs_t prevTime = 0;
};
@@ -218,6 +233,7 @@
void incrementClientCompositionFrames() override;
void incrementClientCompositionReusedFrames() override;
void incrementRefreshRateSwitches() override;
+ void incrementCompositionStrategyChanges() override;
void recordDisplayEventConnectionCount(int32_t count) override;
void recordFrameDuration(nsecs_t startTime, nsecs_t endTime) override;
@@ -242,7 +258,8 @@
// If SF skips or rejects a buffer, remove the corresponding TimeRecord.
void removeTimeRecord(int32_t layerId, uint64_t frameNumber) override;
- void setPowerMode(int32_t powerMode) override;
+ void setPowerMode(
+ hardware::graphics::composer::V2_4::IComposerClient::PowerMode powerMode) override;
// Source of truth is RefrehRateStats.
void recordRefreshRate(uint32_t fps, nsecs_t duration) override;
void setPresentFenceGlobal(const std::shared_ptr<FenceTime>& presentFence) override;
diff --git a/services/surfaceflinger/TimeStats/timestatsproto/TimeStatsHelper.cpp b/services/surfaceflinger/TimeStats/timestatsproto/TimeStatsHelper.cpp
index 5305de9..c90b1b8 100644
--- a/services/surfaceflinger/TimeStats/timestatsproto/TimeStatsHelper.cpp
+++ b/services/surfaceflinger/TimeStats/timestatsproto/TimeStatsHelper.cpp
@@ -106,6 +106,7 @@
StringAppendF(&result, "clientCompositionFrames = %d\n", clientCompositionFrames);
StringAppendF(&result, "clientCompositionReusedFrames = %d\n", clientCompositionReusedFrames);
StringAppendF(&result, "refreshRateSwitches = %d\n", refreshRateSwitches);
+ StringAppendF(&result, "compositionStrategyChanges = %d\n", compositionStrategyChanges);
StringAppendF(&result, "displayOnTime = %" PRId64 " ms\n", displayOnTime);
StringAppendF(&result, "displayConfigStats is as below:\n");
for (const auto& [fps, duration] : refreshRateStats) {
diff --git a/services/surfaceflinger/TimeStats/timestatsproto/include/timestatsproto/TimeStatsHelper.h b/services/surfaceflinger/TimeStats/timestatsproto/include/timestatsproto/TimeStatsHelper.h
index afb98e0..0c75f96 100644
--- a/services/surfaceflinger/TimeStats/timestatsproto/include/timestatsproto/TimeStatsHelper.h
+++ b/services/surfaceflinger/TimeStats/timestatsproto/include/timestatsproto/TimeStatsHelper.h
@@ -63,6 +63,7 @@
int32_t clientCompositionFrames = 0;
int32_t clientCompositionReusedFrames = 0;
int32_t refreshRateSwitches = 0;
+ int32_t compositionStrategyChanges = 0;
int32_t displayEventConnectionsCount = 0;
int64_t displayOnTime = 0;
Histogram presentToPresent;
diff --git a/services/surfaceflinger/tests/LayerTransactionTest.h b/services/surfaceflinger/tests/LayerTransactionTest.h
index 40ec502..f3e11d8 100644
--- a/services/surfaceflinger/tests/LayerTransactionTest.h
+++ b/services/surfaceflinger/tests/LayerTransactionTest.h
@@ -19,7 +19,6 @@
#include <gtest/gtest.h>
#include <gui/ISurfaceComposer.h>
#include <gui/SurfaceComposerClient.h>
-#include <hardware/hwcomposer_defs.h>
#include <private/gui/ComposerService.h>
#include <ui/DisplayConfig.h>
diff --git a/services/surfaceflinger/tests/fakehwc/Android.bp b/services/surfaceflinger/tests/fakehwc/Android.bp
index ff403f6..2861013 100644
--- a/services/surfaceflinger/tests/fakehwc/Android.bp
+++ b/services/surfaceflinger/tests/fakehwc/Android.bp
@@ -23,7 +23,6 @@
"libcutils",
"libfmq",
"libgui",
- "libhardware",
"libhidlbase",
"liblayers_proto",
"liblog",
diff --git a/services/surfaceflinger/tests/fakehwc/FakeComposerClient.h b/services/surfaceflinger/tests/fakehwc/FakeComposerClient.h
index 5240b72..600e765 100644
--- a/services/surfaceflinger/tests/fakehwc/FakeComposerClient.h
+++ b/services/surfaceflinger/tests/fakehwc/FakeComposerClient.h
@@ -16,24 +16,16 @@
#pragma once
-#define HWC2_USE_CPP11
-#define HWC2_INCLUDE_STRINGIFICATION
+#include <chrono>
+
#include <composer-hal/2.1/ComposerClient.h>
#include <composer-hal/2.2/ComposerClient.h>
#include <composer-hal/2.3/ComposerClient.h>
#include <composer-hal/2.4/ComposerClient.h>
-#undef HWC2_USE_CPP11
-#undef HWC2_INCLUDE_STRINGIFICATION
-#include "RenderState.h"
-
-#include "MockComposerHal.h"
-
-// Needed for display type/ID enums
-#include <hardware/hwcomposer_defs.h>
-
#include <utils/Condition.h>
-#include <chrono>
+#include "MockComposerHal.h"
+#include "RenderState.h"
using namespace android::hardware::graphics::common;
using namespace android::hardware::graphics::composer;
diff --git a/services/surfaceflinger/tests/fakehwc/FakeComposerUtils.h b/services/surfaceflinger/tests/fakehwc/FakeComposerUtils.h
index 09a2a89..383a111 100644
--- a/services/surfaceflinger/tests/fakehwc/FakeComposerUtils.h
+++ b/services/surfaceflinger/tests/fakehwc/FakeComposerUtils.h
@@ -19,11 +19,7 @@
#include "FakeComposerClient.h"
#include <gui/SurfaceComposerClient.h>
-
-#include <hardware/hwcomposer_defs.h>
-
#include <log/log.h>
-
#include <gtest/gtest.h>
// clang-format off
diff --git a/services/surfaceflinger/tests/fakehwc/RenderState.h b/services/surfaceflinger/tests/fakehwc/RenderState.h
index 0059289..40193f2 100644
--- a/services/surfaceflinger/tests/fakehwc/RenderState.h
+++ b/services/surfaceflinger/tests/fakehwc/RenderState.h
@@ -16,8 +16,6 @@
#pragma once
-#include <hardware/hwcomposer2.h>
-
#include <vector>
namespace sftest {
diff --git a/services/surfaceflinger/tests/unittests/Android.bp b/services/surfaceflinger/tests/unittests/Android.bp
index 2f2fb20..7574ff1 100644
--- a/services/surfaceflinger/tests/unittests/Android.bp
+++ b/services/surfaceflinger/tests/unittests/Android.bp
@@ -48,6 +48,7 @@
"LayerHistoryTestV2.cpp",
"LayerMetadataTest.cpp",
"PhaseOffsetsTest.cpp",
+ "PromiseTest.cpp",
"SchedulerTest.cpp",
"SchedulerUtilsTest.cpp",
"SetFrameRateTest.cpp",
diff --git a/services/surfaceflinger/tests/unittests/CompositionTest.cpp b/services/surfaceflinger/tests/unittests/CompositionTest.cpp
index 2dcaf63..8713b2b 100644
--- a/services/surfaceflinger/tests/unittests/CompositionTest.cpp
+++ b/services/surfaceflinger/tests/unittests/CompositionTest.cpp
@@ -50,6 +50,14 @@
namespace android {
namespace {
+namespace hal = android::hardware::graphics::composer::hal;
+
+using hal::Error;
+using hal::IComposer;
+using hal::IComposerClient;
+using hal::PowerMode;
+using hal::Transform;
+
using testing::_;
using testing::AtLeast;
using testing::Between;
@@ -65,16 +73,11 @@
using testing::ReturnRef;
using testing::SetArgPointee;
-using android::Hwc2::Error;
-using android::Hwc2::IComposer;
-using android::Hwc2::IComposerClient;
-using android::Hwc2::Transform;
-
using FakeHwcDisplayInjector = TestableSurfaceFlinger::FakeHwcDisplayInjector;
using FakeDisplayDeviceInjector = TestableSurfaceFlinger::FakeDisplayDeviceInjector;
-constexpr hwc2_display_t HWC_DISPLAY = FakeHwcDisplayInjector::DEFAULT_HWC_DISPLAY_ID;
-constexpr hwc2_layer_t HWC_LAYER = 5000;
+constexpr hal::HWDisplayId HWC_DISPLAY = FakeHwcDisplayInjector::DEFAULT_HWC_DISPLAY_ID;
+constexpr hal::HWLayerId HWC_LAYER = 5000;
constexpr Transform DEFAULT_TRANSFORM = static_cast<Transform>(0);
constexpr DisplayId DEFAULT_DISPLAY_ID = DisplayId{42};
@@ -141,10 +144,10 @@
auto primaryDispSync = std::make_unique<mock::DispSync>();
- EXPECT_CALL(*primaryDispSync, computeNextRefresh(0)).WillRepeatedly(Return(0));
+ EXPECT_CALL(*primaryDispSync, computeNextRefresh(0, _)).WillRepeatedly(Return(0));
EXPECT_CALL(*primaryDispSync, getPeriod())
.WillRepeatedly(Return(FakeHwcDisplayInjector::DEFAULT_REFRESH_RATE));
- EXPECT_CALL(*primaryDispSync, expectedPresentTime()).WillRepeatedly(Return(0));
+ EXPECT_CALL(*primaryDispSync, expectedPresentTime(_)).WillRepeatedly(Return(0));
mFlinger.setupScheduler(std::move(primaryDispSync),
std::make_unique<mock::EventControlThread>(),
@@ -170,7 +173,7 @@
template <typename Case>
void captureScreenComposition();
- std::unordered_set<HWC2::Capability> mDefaultCapabilities = {HWC2::Capability::SidebandStream};
+ std::unordered_set<hal::Capability> mDefaultCapabilities = {hal::Capability::SIDEBAND_STREAM};
bool mDisplayOff = false;
TestableSurfaceFlinger mFlinger;
@@ -228,6 +231,7 @@
const Rect sourceCrop(0, 0, DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT);
constexpr bool useIdentityTransform = true;
constexpr bool forSystem = true;
+ constexpr bool regionSampling = false;
DisplayRenderArea renderArea(mDisplay, sourceCrop, DEFAULT_DISPLAY_WIDTH,
DEFAULT_DISPLAY_HEIGHT, ui::Dataspace::V0_SRGB,
@@ -246,7 +250,7 @@
int fd = -1;
status_t result =
mFlinger.captureScreenImplLocked(renderArea, traverseLayers, mCaptureScreenBuffer.get(),
- useIdentityTransform, forSystem, &fd);
+ useIdentityTransform, forSystem, &fd, regionSampling);
if (fd >= 0) {
close(fd);
}
@@ -263,17 +267,13 @@
template <typename Derived>
struct BaseDisplayVariant {
static constexpr bool IS_SECURE = true;
- static constexpr int INIT_POWER_MODE = HWC_POWER_MODE_NORMAL;
+ static constexpr hal::PowerMode INIT_POWER_MODE = hal::PowerMode::ON;
static void setupPreconditions(CompositionTest* test) {
- EXPECT_CALL(*test->mComposer,
- setPowerMode(HWC_DISPLAY,
- static_cast<Hwc2::IComposerClient::PowerMode>(
- Derived::INIT_POWER_MODE)))
+ EXPECT_CALL(*test->mComposer, setPowerMode(HWC_DISPLAY, Derived::INIT_POWER_MODE))
.WillOnce(Return(Error::NONE));
- FakeHwcDisplayInjector(DEFAULT_DISPLAY_ID, HWC2::DisplayType::Physical,
- true /* isPrimary */)
+ FakeHwcDisplayInjector(DEFAULT_DISPLAY_ID, hal::DisplayType::PHYSICAL, true /* isPrimary */)
.setCapabilities(&test->mDefaultCapabilities)
.setPowerMode(Derived::INIT_POWER_MODE)
.inject(&test->mFlinger, test->mComposer);
@@ -437,7 +437,7 @@
};
struct PoweredOffDisplaySetupVariant : public BaseDisplayVariant<PoweredOffDisplaySetupVariant> {
- static constexpr int INIT_POWER_MODE = HWC_POWER_MODE_OFF;
+ static constexpr hal::PowerMode INIT_POWER_MODE = hal::PowerMode::OFF;
template <typename Case>
static void setupPreconditionCallExpectations(CompositionTest*) {}
@@ -542,7 +542,7 @@
EXPECT_CALL(*test->mMessageQueue, invalidate()).Times(1);
enqueueBuffer(test, layer);
- Mock::VerifyAndClear(test->mMessageQueue);
+ Mock::VerifyAndClearExpectations(test->mMessageQueue);
EXPECT_CALL(*test->mRenderEngine, useNativeFenceSync()).WillRepeatedly(Return(true));
bool ignoredRecomputeVisibleRegions;
@@ -834,7 +834,7 @@
struct BaseLayerVariant {
template <typename L, typename F>
static sp<L> createLayerWithFactory(CompositionTest* test, F factory) {
- EXPECT_CALL(*test->mMessageQueue, postMessage(_, 0)).Times(0);
+ EXPECT_CALL(*test->mMessageQueue, postMessage(_)).Times(0);
sp<L> layer = factory();
@@ -843,7 +843,7 @@
Mock::VerifyAndClear(test->mComposer);
Mock::VerifyAndClear(test->mRenderEngine);
- Mock::VerifyAndClear(test->mMessageQueue);
+ Mock::VerifyAndClearExpectations(test->mMessageQueue);
auto& layerDrawingState = test->mFlinger.mutableLayerDrawingState(layer);
layerDrawingState.layerStack = DEFAULT_LAYER_STACK;
@@ -944,7 +944,7 @@
}
static void cleanupInjectedLayers(CompositionTest* test) {
- EXPECT_CALL(*test->mMessageQueue, postMessage(_, 0)).Times(1);
+ EXPECT_CALL(*test->mMessageQueue, postMessage(_)).Times(1);
Base::cleanupInjectedLayers(test);
}
@@ -989,7 +989,7 @@
template <IComposerClient::Composition CompositionType>
struct KeepCompositionTypeVariant {
- static constexpr HWC2::Composition TYPE = static_cast<HWC2::Composition>(CompositionType);
+ static constexpr hal::Composition TYPE = CompositionType;
static void setupHwcSetCallExpectations(CompositionTest* test) {
if (!test->mDisplayOff) {
@@ -1007,7 +1007,7 @@
template <IComposerClient::Composition InitialCompositionType,
IComposerClient::Composition FinalCompositionType>
struct ChangeCompositionTypeVariant {
- static constexpr HWC2::Composition TYPE = static_cast<HWC2::Composition>(FinalCompositionType);
+ static constexpr hal::Composition TYPE = FinalCompositionType;
static void setupHwcSetCallExpectations(CompositionTest* test) {
if (!test->mDisplayOff) {
diff --git a/services/surfaceflinger/tests/unittests/DispSyncSourceTest.cpp b/services/surfaceflinger/tests/unittests/DispSyncSourceTest.cpp
index 2e705da..afebc40 100644
--- a/services/surfaceflinger/tests/unittests/DispSyncSourceTest.cpp
+++ b/services/surfaceflinger/tests/unittests/DispSyncSourceTest.cpp
@@ -43,7 +43,7 @@
void createDispSync();
void createDispSyncSource();
- void onVSyncEvent(nsecs_t when) override;
+ void onVSyncEvent(nsecs_t when, nsecs_t expectedVSyncTimestamp) override;
std::unique_ptr<mock::DispSync> mDispSync;
std::unique_ptr<DispSyncSource> mDispSyncSource;
@@ -66,7 +66,7 @@
ALOGD("**** Tearing down after %s.%s\n", test_info->test_case_name(), test_info->name());
}
-void DispSyncSourceTest::onVSyncEvent(nsecs_t when) {
+void DispSyncSourceTest::onVSyncEvent(nsecs_t when, nsecs_t /*expectedVSyncTimestamp*/) {
ALOGD("onVSyncEvent: %" PRId64, when);
mVSyncEventCallRecorder.recordCall(when);
diff --git a/services/surfaceflinger/tests/unittests/DisplayTransactionTest.cpp b/services/surfaceflinger/tests/unittests/DisplayTransactionTest.cpp
index cd11409..ce5f35c 100644
--- a/services/surfaceflinger/tests/unittests/DisplayTransactionTest.cpp
+++ b/services/surfaceflinger/tests/unittests/DisplayTransactionTest.cpp
@@ -55,6 +55,8 @@
namespace android {
namespace {
+namespace hal = android::hardware::graphics::composer::hal;
+
using testing::_;
using testing::AnyNumber;
using testing::DoAll;
@@ -65,13 +67,18 @@
using testing::SetArgPointee;
using testing::StrictMock;
-using android::Hwc2::ColorMode;
-using android::Hwc2::Error;
-using android::Hwc2::Hdr;
-using android::Hwc2::IComposer;
-using android::Hwc2::IComposerClient;
-using android::Hwc2::PerFrameMetadataKey;
-using android::Hwc2::RenderIntent;
+using hal::ColorMode;
+using hal::Connection;
+using hal::DisplayCapability;
+using hal::DisplayType;
+using hal::Error;
+using hal::Hdr;
+using hal::HWDisplayId;
+using hal::IComposer;
+using hal::IComposerClient;
+using hal::PerFrameMetadataKey;
+using hal::PowerMode;
+using hal::RenderIntent;
using FakeDisplayDeviceInjector = TestableSurfaceFlinger::FakeDisplayDeviceInjector;
using FakeHwcDisplayInjector = TestableSurfaceFlinger::FakeHwcDisplayInjector;
@@ -82,7 +89,7 @@
constexpr int32_t DEFAULT_DPI = 320;
constexpr int DEFAULT_VIRTUAL_DISPLAY_SURFACE_FORMAT = HAL_PIXEL_FORMAT_RGB_565;
-constexpr int HWC_POWER_MODE_LEET = 1337; // An out of range power mode value
+constexpr int POWER_MODE_LEET = 1337; // An out of range power mode value
/* ------------------------------------------------------------------------
* Boolean avoidance
@@ -120,7 +127,7 @@
// --------------------------------------------------------------------
// Postcondition helpers
- bool hasPhysicalHwcDisplay(hwc2_display_t hwcDisplayId);
+ bool hasPhysicalHwcDisplay(HWDisplayId hwcDisplayId);
bool hasTransactionFlagSet(int flag);
bool hasDisplayDevice(sp<IBinder> displayToken);
sp<DisplayDevice> getDisplayDevice(sp<IBinder> displayToken);
@@ -246,7 +253,7 @@
constexpr DisplayId DEFAULT_DISPLAY_ID = DisplayId{777};
constexpr int DEFAULT_DISPLAY_WIDTH = 1080;
constexpr int DEFAULT_DISPLAY_HEIGHT = 1920;
- constexpr hwc2_display_t DEFAULT_DISPLAY_HWC_DISPLAY_ID = 0;
+ constexpr HWDisplayId DEFAULT_DISPLAY_HWC_DISPLAY_ID = 0;
// The DisplayDevice is required to have a framebuffer (behind the
// ANativeWindow interface) which uses the actual hardware display
@@ -285,7 +292,7 @@
return displayDevice;
}
-bool DisplayTransactionTest::hasPhysicalHwcDisplay(hwc2_display_t hwcDisplayId) {
+bool DisplayTransactionTest::hasPhysicalHwcDisplay(HWDisplayId hwcDisplayId) {
return mFlinger.mutableHwcPhysicalDisplayIdMap().count(hwcDisplayId) == 1;
}
@@ -343,8 +350,8 @@
static std::optional<DisplayId> get() {
if (!PhysicalDisplay::HAS_IDENTIFICATION_DATA) {
return getFallbackDisplayId(static_cast<bool>(PhysicalDisplay::PRIMARY)
- ? HWC_DISPLAY_PRIMARY
- : HWC_DISPLAY_EXTERNAL);
+ ? LEGACY_DISPLAY_TYPE_PRIMARY
+ : LEGACY_DISPLAY_TYPE_EXTERNAL);
}
const auto info =
@@ -376,19 +383,19 @@
template <typename>
struct HwcDisplayIdGetter {
- static constexpr std::optional<hwc2_display_t> value;
+ static constexpr std::optional<HWDisplayId> value;
};
-constexpr hwc2_display_t HWC_VIRTUAL_DISPLAY_HWC_DISPLAY_ID = 1010;
+constexpr HWDisplayId HWC_VIRTUAL_DISPLAY_HWC_DISPLAY_ID = 1010;
template <DisplayId::Type displayId>
struct HwcDisplayIdGetter<VirtualDisplayId<displayId>> {
- static constexpr std::optional<hwc2_display_t> value = HWC_VIRTUAL_DISPLAY_HWC_DISPLAY_ID;
+ static constexpr std::optional<HWDisplayId> value = HWC_VIRTUAL_DISPLAY_HWC_DISPLAY_ID;
};
template <typename PhysicalDisplay>
struct HwcDisplayIdGetter<PhysicalDisplayId<PhysicalDisplay>> {
- static constexpr std::optional<hwc2_display_t> value = PhysicalDisplay::HWC_DISPLAY_ID;
+ static constexpr std::optional<HWDisplayId> value = PhysicalDisplay::HWC_DISPLAY_ID;
};
// DisplayIdType can be:
@@ -497,21 +504,20 @@
}
};
-template <hwc2_display_t hwcDisplayId, HWC2::DisplayType hwcDisplayType, typename DisplayVariant,
+template <HWDisplayId hwcDisplayId, DisplayType hwcDisplayType, typename DisplayVariant,
typename PhysicalDisplay = void>
struct HwcDisplayVariant {
// The display id supplied by the HWC
- static constexpr hwc2_display_t HWC_DISPLAY_ID = hwcDisplayId;
+ static constexpr HWDisplayId HWC_DISPLAY_ID = hwcDisplayId;
// The HWC display type
- static constexpr HWC2::DisplayType HWC_DISPLAY_TYPE = hwcDisplayType;
+ static constexpr DisplayType HWC_DISPLAY_TYPE = hwcDisplayType;
// The HWC active configuration id
static constexpr int HWC_ACTIVE_CONFIG_ID = 2001;
- static constexpr int INIT_POWER_MODE = HWC_POWER_MODE_NORMAL;
+ static constexpr PowerMode INIT_POWER_MODE = PowerMode::ON;
- static void injectPendingHotplugEvent(DisplayTransactionTest* test,
- HWC2::Connection connection) {
+ static void injectPendingHotplugEvent(DisplayTransactionTest* test, Connection connection) {
test->mFlinger.mutablePendingHotplugEvents().emplace_back(
HotplugEvent{HWC_DISPLAY_ID, connection});
}
@@ -533,11 +539,9 @@
// Called by tests to inject a HWC display setup
static void injectHwcDisplay(DisplayTransactionTest* test) {
EXPECT_CALL(*test->mComposer, getDisplayCapabilities(HWC_DISPLAY_ID, _))
- .WillOnce(DoAll(SetArgPointee<1>(std::vector<Hwc2::DisplayCapability>({})),
+ .WillOnce(DoAll(SetArgPointee<1>(std::vector<DisplayCapability>({})),
Return(Error::NONE)));
- EXPECT_CALL(*test->mComposer,
- setPowerMode(HWC_DISPLAY_ID,
- static_cast<Hwc2::IComposerClient::PowerMode>(INIT_POWER_MODE)))
+ EXPECT_CALL(*test->mComposer, setPowerMode(HWC_DISPLAY_ID, INIT_POWER_MODE))
.WillOnce(Return(Error::NONE));
injectHwcDisplayWithNoDefaultCapabilities(test);
}
@@ -568,10 +572,10 @@
: IComposerClient::DisplayConnectionType::EXTERNAL;
EXPECT_CALL(*test->mComposer, getDisplayConnectionType(HWC_DISPLAY_ID, _))
- .WillOnce(
- DoAll(SetArgPointee<1>(CONNECTION_TYPE), Return(Hwc2::V2_4::Error::NONE)));
+ .WillOnce(DoAll(SetArgPointee<1>(CONNECTION_TYPE), Return(hal::V2_4::Error::NONE)));
- EXPECT_CALL(*test->mComposer, setClientTargetSlotCount(_)).WillOnce(Return(Error::NONE));
+ EXPECT_CALL(*test->mComposer, setClientTargetSlotCount(_))
+ .WillOnce(Return(hal::Error::NONE));
EXPECT_CALL(*test->mComposer, getDisplayConfigs(HWC_DISPLAY_ID, _))
.WillOnce(DoAll(SetArgPointee<1>(std::vector<unsigned>{HWC_ACTIVE_CONFIG_ID}),
Return(Error::NONE)));
@@ -626,7 +630,7 @@
struct PhysicalDisplayVariant
: DisplayVariant<PhysicalDisplayId<PhysicalDisplay>, width, height, critical, Async::FALSE,
Secure::TRUE, PhysicalDisplay::PRIMARY, GRALLOC_USAGE_PHYSICAL_DISPLAY>,
- HwcDisplayVariant<PhysicalDisplay::HWC_DISPLAY_ID, HWC2::DisplayType::Physical,
+ HwcDisplayVariant<PhysicalDisplay::HWC_DISPLAY_ID, DisplayType::PHYSICAL,
DisplayVariant<PhysicalDisplayId<PhysicalDisplay>, width, height,
critical, Async::FALSE, Secure::TRUE,
PhysicalDisplay::PRIMARY, GRALLOC_USAGE_PHYSICAL_DISPLAY>,
@@ -637,7 +641,7 @@
static constexpr auto CONNECTION_TYPE = DisplayConnectionType::Internal;
static constexpr Primary PRIMARY = Primary::TRUE;
static constexpr uint8_t PORT = 255;
- static constexpr hwc2_display_t HWC_DISPLAY_ID = 1001;
+ static constexpr HWDisplayId HWC_DISPLAY_ID = 1001;
static constexpr bool HAS_IDENTIFICATION_DATA = hasIdentificationData;
static constexpr auto GET_IDENTIFICATION_DATA = getInternalEdid;
};
@@ -647,7 +651,7 @@
static constexpr auto CONNECTION_TYPE = DisplayConnectionType::External;
static constexpr Primary PRIMARY = Primary::FALSE;
static constexpr uint8_t PORT = 254;
- static constexpr hwc2_display_t HWC_DISPLAY_ID = 1002;
+ static constexpr HWDisplayId HWC_DISPLAY_ID = 1002;
static constexpr bool HAS_IDENTIFICATION_DATA = hasIdentificationData;
static constexpr auto GET_IDENTIFICATION_DATA = getExternalEdid;
};
@@ -655,7 +659,7 @@
struct TertiaryDisplay {
static constexpr Primary PRIMARY = Primary::FALSE;
static constexpr uint8_t PORT = 253;
- static constexpr hwc2_display_t HWC_DISPLAY_ID = 1003;
+ static constexpr HWDisplayId HWC_DISPLAY_ID = 1003;
static constexpr auto GET_IDENTIFICATION_DATA = getExternalEdid;
};
@@ -716,7 +720,7 @@
: DisplayVariant<VirtualDisplayId<42>, width, height, Critical::FALSE, Async::TRUE, secure,
Primary::FALSE, GRALLOC_USAGE_HWC_VIRTUAL_DISPLAY>,
HwcDisplayVariant<
- HWC_VIRTUAL_DISPLAY_HWC_DISPLAY_ID, HWC2::DisplayType::Virtual,
+ HWC_VIRTUAL_DISPLAY_HWC_DISPLAY_ID, DisplayType::VIRTUAL,
DisplayVariant<VirtualDisplayId<42>, width, height, Critical::FALSE, Async::TRUE,
secure, Primary::FALSE, GRALLOC_USAGE_HWC_VIRTUAL_DISPLAY>> {
using Base = DisplayVariant<VirtualDisplayId<42>, width, height, Critical::FALSE, Async::TRUE,
@@ -1046,8 +1050,8 @@
TEST_F(DisplayTransactionTest, hotplugEnqueuesEventsForDisplayTransaction) {
constexpr int currentSequenceId = 123;
- constexpr hwc2_display_t hwcDisplayId1 = 456;
- constexpr hwc2_display_t hwcDisplayId2 = 654;
+ constexpr HWDisplayId hwcDisplayId1 = 456;
+ constexpr HWDisplayId hwcDisplayId2 = 654;
// --------------------------------------------------------------------
// Preconditions
@@ -1070,8 +1074,8 @@
// Invocation
// Simulate two hotplug events (a connect and a disconnect)
- mFlinger.onHotplugReceived(currentSequenceId, hwcDisplayId1, HWC2::Connection::Connected);
- mFlinger.onHotplugReceived(currentSequenceId, hwcDisplayId2, HWC2::Connection::Disconnected);
+ mFlinger.onHotplugReceived(currentSequenceId, hwcDisplayId1, Connection::CONNECTED);
+ mFlinger.onHotplugReceived(currentSequenceId, hwcDisplayId2, Connection::DISCONNECTED);
// --------------------------------------------------------------------
// Postconditions
@@ -1083,15 +1087,15 @@
const auto& pendingEvents = mFlinger.mutablePendingHotplugEvents();
ASSERT_EQ(2u, pendingEvents.size());
EXPECT_EQ(hwcDisplayId1, pendingEvents[0].hwcDisplayId);
- EXPECT_EQ(HWC2::Connection::Connected, pendingEvents[0].connection);
+ EXPECT_EQ(Connection::CONNECTED, pendingEvents[0].connection);
EXPECT_EQ(hwcDisplayId2, pendingEvents[1].hwcDisplayId);
- EXPECT_EQ(HWC2::Connection::Disconnected, pendingEvents[1].connection);
+ EXPECT_EQ(Connection::DISCONNECTED, pendingEvents[1].connection);
}
TEST_F(DisplayTransactionTest, hotplugDiscardsUnexpectedEvents) {
constexpr int currentSequenceId = 123;
constexpr int otherSequenceId = 321;
- constexpr hwc2_display_t displayId = 456;
+ constexpr HWDisplayId displayId = 456;
// --------------------------------------------------------------------
// Preconditions
@@ -1113,7 +1117,7 @@
// Invocation
// Call with an unexpected sequence id
- mFlinger.onHotplugReceived(otherSequenceId, displayId, HWC2::Connection::Invalid);
+ mFlinger.onHotplugReceived(otherSequenceId, displayId, Connection::INVALID);
// --------------------------------------------------------------------
// Postconditions
@@ -1127,7 +1131,7 @@
TEST_F(DisplayTransactionTest, hotplugProcessesEnqueuedEventsIfCalledOnMainThread) {
constexpr int currentSequenceId = 123;
- constexpr hwc2_display_t displayId1 = 456;
+ constexpr HWDisplayId displayId1 = 456;
// --------------------------------------------------------------------
// Note:
@@ -1161,7 +1165,7 @@
// Simulate a disconnect on a display id that is not connected. This should
// be enqueued by onHotplugReceived(), and dequeued by
// processDisplayHotplugEventsLocked(), but then ignored as invalid.
- mFlinger.onHotplugReceived(currentSequenceId, displayId1, HWC2::Connection::Disconnected);
+ mFlinger.onHotplugReceived(currentSequenceId, displayId1, Connection::DISCONNECTED);
// --------------------------------------------------------------------
// Postconditions
@@ -2010,7 +2014,7 @@
setupCommonPreconditions<Case>();
// A hotplug connect event is enqueued for a display
- Case::Display::injectPendingHotplugEvent(this, HWC2::Connection::Connected);
+ Case::Display::injectPendingHotplugEvent(this, Connection::CONNECTED);
// --------------------------------------------------------------------
// Call Expectations
@@ -2046,7 +2050,7 @@
setupCommonPreconditions<Case>();
// A hotplug connect event is enqueued for a display
- Case::Display::injectPendingHotplugEvent(this, HWC2::Connection::Connected);
+ Case::Display::injectPendingHotplugEvent(this, Connection::CONNECTED);
// --------------------------------------------------------------------
// Invocation
@@ -2068,7 +2072,7 @@
setupCommonPreconditions<Case>();
// A hotplug disconnect event is enqueued for a display
- Case::Display::injectPendingHotplugEvent(this, HWC2::Connection::Disconnected);
+ Case::Display::injectPendingHotplugEvent(this, Connection::DISCONNECTED);
// The display is already completely set up.
Case::Display::injectHwcDisplay(this);
@@ -2166,9 +2170,9 @@
setupCommonPreconditions<Case>();
// A hotplug connect event is enqueued for a display
- Case::Display::injectPendingHotplugEvent(this, HWC2::Connection::Connected);
+ Case::Display::injectPendingHotplugEvent(this, Connection::CONNECTED);
// A hotplug disconnect event is also enqueued for the same display
- Case::Display::injectPendingHotplugEvent(this, HWC2::Connection::Disconnected);
+ Case::Display::injectPendingHotplugEvent(this, Connection::DISCONNECTED);
// --------------------------------------------------------------------
// Call Expectations
@@ -2214,9 +2218,9 @@
existing.inject();
// A hotplug disconnect event is enqueued for a display
- Case::Display::injectPendingHotplugEvent(this, HWC2::Connection::Disconnected);
+ Case::Display::injectPendingHotplugEvent(this, Connection::DISCONNECTED);
// A hotplug connect event is also enqueued for the same display
- Case::Display::injectPendingHotplugEvent(this, HWC2::Connection::Connected);
+ Case::Display::injectPendingHotplugEvent(this, Connection::CONNECTED);
// --------------------------------------------------------------------
// Call Expectations
@@ -3093,7 +3097,7 @@
// processing.
EXPECT_CALL(*mMessageQueue, invalidate()).Times(1);
- EXPECT_CALL(*mPrimaryDispSync, expectedPresentTime()).WillRepeatedly(Return(0));
+ EXPECT_CALL(*mPrimaryDispSync, expectedPresentTime(_)).WillRepeatedly(Return(0));
// --------------------------------------------------------------------
// Invocation
@@ -3121,10 +3125,10 @@
EXPECT_EQ(0u, primaryDisplayState.width);
EXPECT_EQ(0u, primaryDisplayState.height);
- // The display should be set to HWC_POWER_MODE_NORMAL
+ // The display should be set to PowerMode::ON
ASSERT_TRUE(hasDisplayDevice(primaryDisplay.token()));
auto displayDevice = primaryDisplay.mutableDisplayDevice();
- EXPECT_EQ(HWC_POWER_MODE_NORMAL, displayDevice->getPowerMode());
+ EXPECT_EQ(PowerMode::ON, displayDevice->getPowerMode());
// The display refresh period should be set in the frame tracker.
FrameStats stats;
@@ -3156,8 +3160,8 @@
static void setupComposerCallExpectations(DisplayTransactionTest* test) {
EXPECT_CALL(*test->mComposer, getDisplayCapabilities(Display::HWC_DISPLAY_ID, _))
- .WillOnce(DoAll(SetArgPointee<1>(std::vector<Hwc2::DisplayCapability>(
- {Hwc2::DisplayCapability::DOZE})),
+ .WillOnce(DoAll(SetArgPointee<1>(
+ std::vector<DisplayCapability>({DisplayCapability::DOZE})),
Return(Error::NONE)));
}
};
@@ -3173,7 +3177,7 @@
static void setupComposerCallExpectations(DisplayTransactionTest* test) {
EXPECT_CALL(*test->mComposer, getDisplayCapabilities(Display::HWC_DISPLAY_ID, _))
- .WillOnce(DoAll(SetArgPointee<1>(std::vector<Hwc2::DisplayCapability>({})),
+ .WillOnce(DoAll(SetArgPointee<1>(std::vector<DisplayCapability>({})),
Return(Error::NONE)));
}
};
@@ -3247,7 +3251,7 @@
// selected subset which provides complete test coverage of the implementation.
// --------------------------------------------------------------------
-template <int initialPowerMode, int targetPowerMode>
+template <PowerMode initialPowerMode, PowerMode targetPowerMode>
struct TransitionVariantCommon {
static constexpr auto INITIAL_POWER_MODE = initialPowerMode;
static constexpr auto TARGET_POWER_MODE = targetPowerMode;
@@ -3255,8 +3259,7 @@
static void verifyPostconditions(DisplayTransactionTest*) {}
};
-struct TransitionOffToOnVariant
- : public TransitionVariantCommon<HWC_POWER_MODE_OFF, HWC_POWER_MODE_NORMAL> {
+struct TransitionOffToOnVariant : public TransitionVariantCommon<PowerMode::OFF, PowerMode::ON> {
template <typename Case>
static void setupCallExpectations(DisplayTransactionTest* test) {
Case::setupComposerCallExpectations(test, IComposerClient::PowerMode::ON);
@@ -3272,7 +3275,7 @@
};
struct TransitionOffToDozeSuspendVariant
- : public TransitionVariantCommon<HWC_POWER_MODE_OFF, HWC_POWER_MODE_DOZE_SUSPEND> {
+ : public TransitionVariantCommon<PowerMode::OFF, PowerMode::DOZE_SUSPEND> {
template <typename Case>
static void setupCallExpectations(DisplayTransactionTest* test) {
Case::setupComposerCallExpectations(test, Case::Doze::ACTUAL_POWER_MODE_FOR_DOZE_SUSPEND);
@@ -3286,8 +3289,7 @@
}
};
-struct TransitionOnToOffVariant
- : public TransitionVariantCommon<HWC_POWER_MODE_NORMAL, HWC_POWER_MODE_OFF> {
+struct TransitionOnToOffVariant : public TransitionVariantCommon<PowerMode::ON, PowerMode::OFF> {
template <typename Case>
static void setupCallExpectations(DisplayTransactionTest* test) {
Case::EventThread::setupReleaseAndDisableVsyncCallExpectations(test);
@@ -3301,7 +3303,7 @@
};
struct TransitionDozeSuspendToOffVariant
- : public TransitionVariantCommon<HWC_POWER_MODE_DOZE_SUSPEND, HWC_POWER_MODE_OFF> {
+ : public TransitionVariantCommon<PowerMode::DOZE_SUSPEND, PowerMode::OFF> {
template <typename Case>
static void setupCallExpectations(DisplayTransactionTest* test) {
Case::EventThread::setupEventAndEventControlThreadNoCallExpectations(test);
@@ -3313,8 +3315,7 @@
}
};
-struct TransitionOnToDozeVariant
- : public TransitionVariantCommon<HWC_POWER_MODE_NORMAL, HWC_POWER_MODE_DOZE> {
+struct TransitionOnToDozeVariant : public TransitionVariantCommon<PowerMode::ON, PowerMode::DOZE> {
template <typename Case>
static void setupCallExpectations(DisplayTransactionTest* test) {
Case::EventThread::setupEventAndEventControlThreadNoCallExpectations(test);
@@ -3323,7 +3324,7 @@
};
struct TransitionDozeSuspendToDozeVariant
- : public TransitionVariantCommon<HWC_POWER_MODE_DOZE_SUSPEND, HWC_POWER_MODE_DOZE> {
+ : public TransitionVariantCommon<PowerMode::DOZE_SUSPEND, PowerMode::DOZE> {
template <typename Case>
static void setupCallExpectations(DisplayTransactionTest* test) {
Case::EventThread::setupAcquireAndEnableVsyncCallExpectations(test);
@@ -3332,8 +3333,7 @@
}
};
-struct TransitionDozeToOnVariant
- : public TransitionVariantCommon<HWC_POWER_MODE_DOZE, HWC_POWER_MODE_NORMAL> {
+struct TransitionDozeToOnVariant : public TransitionVariantCommon<PowerMode::DOZE, PowerMode::ON> {
template <typename Case>
static void setupCallExpectations(DisplayTransactionTest* test) {
Case::EventThread::setupEventAndEventControlThreadNoCallExpectations(test);
@@ -3342,7 +3342,7 @@
};
struct TransitionDozeSuspendToOnVariant
- : public TransitionVariantCommon<HWC_POWER_MODE_DOZE_SUSPEND, HWC_POWER_MODE_NORMAL> {
+ : public TransitionVariantCommon<PowerMode::DOZE_SUSPEND, PowerMode::ON> {
template <typename Case>
static void setupCallExpectations(DisplayTransactionTest* test) {
Case::EventThread::setupAcquireAndEnableVsyncCallExpectations(test);
@@ -3352,7 +3352,7 @@
};
struct TransitionOnToDozeSuspendVariant
- : public TransitionVariantCommon<HWC_POWER_MODE_NORMAL, HWC_POWER_MODE_DOZE_SUSPEND> {
+ : public TransitionVariantCommon<PowerMode::ON, PowerMode::DOZE_SUSPEND> {
template <typename Case>
static void setupCallExpectations(DisplayTransactionTest* test) {
Case::EventThread::setupReleaseAndDisableVsyncCallExpectations(test);
@@ -3362,7 +3362,7 @@
};
struct TransitionOnToUnknownVariant
- : public TransitionVariantCommon<HWC_POWER_MODE_NORMAL, HWC_POWER_MODE_LEET> {
+ : public TransitionVariantCommon<PowerMode::ON, static_cast<PowerMode>(POWER_MODE_LEET)> {
template <typename Case>
static void setupCallExpectations(DisplayTransactionTest* test) {
Case::EventThread::setupEventAndEventControlThreadNoCallExpectations(test);
@@ -3387,7 +3387,7 @@
using DispSync = DispSyncVariant;
using Transition = TransitionVariant;
- static auto injectDisplayWithInitialPowerMode(DisplayTransactionTest* test, int mode) {
+ static auto injectDisplayWithInitialPowerMode(DisplayTransactionTest* test, PowerMode mode) {
Display::injectHwcDisplayWithNoDefaultCapabilities(test);
auto display = Display::makeFakeExistingDisplayInjector(test);
display.inject();
@@ -3403,13 +3403,14 @@
EXPECT_CALL(*test->mMessageQueue, invalidate()).Times(1);
}
- static void setupSurfaceInterceptorCallExpectations(DisplayTransactionTest* test, int mode) {
+ static void setupSurfaceInterceptorCallExpectations(DisplayTransactionTest* test,
+ PowerMode mode) {
EXPECT_CALL(*test->mSurfaceInterceptor, isEnabled()).WillOnce(Return(true));
- EXPECT_CALL(*test->mSurfaceInterceptor, savePowerModeUpdate(_, mode)).Times(1);
+ EXPECT_CALL(*test->mSurfaceInterceptor, savePowerModeUpdate(_, static_cast<int32_t>(mode)))
+ .Times(1);
}
- static void setupComposerCallExpectations(DisplayTransactionTest* test,
- IComposerClient::PowerMode mode) {
+ static void setupComposerCallExpectations(DisplayTransactionTest* test, PowerMode mode) {
// Any calls to get the active config will return a default value.
EXPECT_CALL(*test->mComposer, getActiveConfig(Display::HWC_DISPLAY_ID, _))
.WillRepeatedly(DoAll(SetArgPointee<1>(Display::HWC_ACTIVE_CONFIG_ID),
@@ -3451,14 +3452,14 @@
void transitionDisplayCommon();
};
-template <int PowerMode>
+template <PowerMode PowerMode>
struct PowerModeInitialVSyncEnabled : public std::false_type {};
template <>
-struct PowerModeInitialVSyncEnabled<HWC_POWER_MODE_NORMAL> : public std::true_type {};
+struct PowerModeInitialVSyncEnabled<PowerMode::ON> : public std::true_type {};
template <>
-struct PowerModeInitialVSyncEnabled<HWC_POWER_MODE_DOZE> : public std::true_type {};
+struct PowerModeInitialVSyncEnabled<PowerMode::DOZE> : public std::true_type {};
template <typename Case>
void SetPowerModeInternalTest::transitionDisplayCommon() {
@@ -3501,18 +3502,18 @@
auto display = Case::Display::makeFakeExistingDisplayInjector(this);
display.inject();
- // The display is already set to HWC_POWER_MODE_NORMAL
- display.mutableDisplayDevice()->setPowerMode(HWC_POWER_MODE_NORMAL);
+ // The display is already set to PowerMode::ON
+ display.mutableDisplayDevice()->setPowerMode(PowerMode::ON);
// --------------------------------------------------------------------
// Invocation
- mFlinger.setPowerModeInternal(display.mutableDisplayDevice(), HWC_POWER_MODE_NORMAL);
+ mFlinger.setPowerModeInternal(display.mutableDisplayDevice(), PowerMode::ON);
// --------------------------------------------------------------------
// Postconditions
- EXPECT_EQ(HWC_POWER_MODE_NORMAL, display.mutableDisplayDevice()->getPowerMode());
+ EXPECT_EQ(PowerMode::ON, display.mutableDisplayDevice()->getPowerMode());
}
TEST_F(SetPowerModeInternalTest, setPowerModeInternalDoesNothingIfVirtualDisplay) {
@@ -3531,18 +3532,18 @@
auto display = Case::Display::makeFakeExistingDisplayInjector(this);
display.inject();
- // The display is set to HWC_POWER_MODE_NORMAL
- getDisplayDevice(display.token())->setPowerMode(HWC_POWER_MODE_NORMAL);
+ // The display is set to PowerMode::ON
+ getDisplayDevice(display.token())->setPowerMode(PowerMode::ON);
// --------------------------------------------------------------------
// Invocation
- mFlinger.setPowerModeInternal(display.mutableDisplayDevice(), HWC_POWER_MODE_OFF);
+ mFlinger.setPowerModeInternal(display.mutableDisplayDevice(), PowerMode::OFF);
// --------------------------------------------------------------------
// Postconditions
- EXPECT_EQ(HWC_POWER_MODE_NORMAL, display.mutableDisplayDevice()->getPowerMode());
+ EXPECT_EQ(PowerMode::ON, display.mutableDisplayDevice()->getPowerMode());
}
TEST_F(SetPowerModeInternalTest, transitionsDisplayFromOffToOnPrimaryDisplay) {
diff --git a/services/surfaceflinger/tests/unittests/EventThreadTest.cpp b/services/surfaceflinger/tests/unittests/EventThreadTest.cpp
index ba5c0c2..b90b566 100644
--- a/services/surfaceflinger/tests/unittests/EventThreadTest.cpp
+++ b/services/surfaceflinger/tests/unittests/EventThreadTest.cpp
@@ -258,14 +258,14 @@
// Use the received callback to signal a first vsync event.
// The interceptor should receive the event, as well as the connection.
- mCallback->onVSyncEvent(123);
+ mCallback->onVSyncEvent(123, 456);
expectInterceptCallReceived(123);
expectVsyncEventReceivedByConnection(123, 1u);
// Use the received callback to signal a second vsync event.
// The interceptor should receive the event, but the the connection should
// not as it was only interested in the first.
- mCallback->onVSyncEvent(456);
+ mCallback->onVSyncEvent(456, 123);
expectInterceptCallReceived(456);
EXPECT_FALSE(mConnectionEventCallRecorder.waitForUnexpectedCall().has_value());
@@ -299,7 +299,7 @@
// Send a vsync event. EventThread should then make a call to the
// interceptor, and the second connection. The first connection should not
// get the event.
- mCallback->onVSyncEvent(123);
+ mCallback->onVSyncEvent(123, 456);
expectInterceptCallReceived(123);
EXPECT_FALSE(firstConnectionEventRecorder.waitForUnexpectedCall().has_value());
expectVsyncEventReceivedByConnection("secondConnection", secondConnectionEventRecorder, 123,
@@ -314,17 +314,17 @@
// Send a vsync event. EventThread should then make a call to the
// interceptor, and the connection.
- mCallback->onVSyncEvent(123);
+ mCallback->onVSyncEvent(123, 456);
expectInterceptCallReceived(123);
expectVsyncEventReceivedByConnection(123, 1u);
// A second event should go to the same places.
- mCallback->onVSyncEvent(456);
+ mCallback->onVSyncEvent(456, 123);
expectInterceptCallReceived(456);
expectVsyncEventReceivedByConnection(456, 2u);
// A third event should go to the same places.
- mCallback->onVSyncEvent(789);
+ mCallback->onVSyncEvent(789, 777);
expectInterceptCallReceived(789);
expectVsyncEventReceivedByConnection(789, 3u);
}
@@ -336,22 +336,22 @@
expectVSyncSetEnabledCallReceived(true);
// The first event will be seen by the interceptor, and not the connection.
- mCallback->onVSyncEvent(123);
+ mCallback->onVSyncEvent(123, 456);
expectInterceptCallReceived(123);
EXPECT_FALSE(mConnectionEventCallRecorder.waitForUnexpectedCall().has_value());
// The second event will be seen by the interceptor and the connection.
- mCallback->onVSyncEvent(456);
+ mCallback->onVSyncEvent(456, 123);
expectInterceptCallReceived(456);
expectVsyncEventReceivedByConnection(456, 2u);
// The third event will be seen by the interceptor, and not the connection.
- mCallback->onVSyncEvent(789);
+ mCallback->onVSyncEvent(789, 777);
expectInterceptCallReceived(789);
EXPECT_FALSE(mConnectionEventCallRecorder.waitForUnexpectedCall().has_value());
// The fourth event will be seen by the interceptor and the connection.
- mCallback->onVSyncEvent(101112);
+ mCallback->onVSyncEvent(101112, 7847);
expectInterceptCallReceived(101112);
expectVsyncEventReceivedByConnection(101112, 4u);
}
@@ -366,7 +366,7 @@
mConnection = nullptr;
// The first event will be seen by the interceptor, and not the connection.
- mCallback->onVSyncEvent(123);
+ mCallback->onVSyncEvent(123, 456);
expectInterceptCallReceived(123);
EXPECT_FALSE(mConnectionEventCallRecorder.waitForUnexpectedCall().has_value());
@@ -386,13 +386,13 @@
// The first event will be seen by the interceptor, and by the connection,
// which then returns an error.
- mCallback->onVSyncEvent(123);
+ mCallback->onVSyncEvent(123, 456);
expectInterceptCallReceived(123);
expectVsyncEventReceivedByConnection("errorConnection", errorConnectionEventRecorder, 123, 1u);
// A subsequent event will be seen by the interceptor and not by the
// connection.
- mCallback->onVSyncEvent(456);
+ mCallback->onVSyncEvent(456, 123);
expectInterceptCallReceived(456);
EXPECT_FALSE(errorConnectionEventRecorder.waitForUnexpectedCall().has_value());
@@ -420,7 +420,7 @@
// The first event will be seen by the interceptor, and by the connection,
// which then returns an error.
- mCallback->onVSyncEvent(123);
+ mCallback->onVSyncEvent(123, 456);
expectInterceptCallReceived(123);
expectVsyncEventReceivedByConnection("errorConnection", errorConnectionEventRecorder, 123, 1u);
expectVsyncEventReceivedByConnection("successConnection", secondConnectionEventRecorder, 123,
@@ -440,13 +440,13 @@
// The first event will be seen by the interceptor, and by the connection,
// which then returns an non-fatal error.
- mCallback->onVSyncEvent(123);
+ mCallback->onVSyncEvent(123, 456);
expectInterceptCallReceived(123);
expectVsyncEventReceivedByConnection("errorConnection", errorConnectionEventRecorder, 123, 1u);
// A subsequent event will be seen by the interceptor, and by the connection,
// which still then returns an non-fatal error.
- mCallback->onVSyncEvent(456);
+ mCallback->onVSyncEvent(456, 123);
expectInterceptCallReceived(456);
expectVsyncEventReceivedByConnection("errorConnection", errorConnectionEventRecorder, 456, 2u);
diff --git a/services/surfaceflinger/tests/unittests/HWComposerTest.cpp b/services/surfaceflinger/tests/unittests/HWComposerTest.cpp
index c6fe205..91b304c 100644
--- a/services/surfaceflinger/tests/unittests/HWComposerTest.cpp
+++ b/services/surfaceflinger/tests/unittests/HWComposerTest.cpp
@@ -36,6 +36,8 @@
namespace android {
namespace {
+namespace hal = android::hardware::graphics::composer::hal;
+
using ::testing::_;
using ::testing::DoAll;
using ::testing::ElementsAreArray;
@@ -47,15 +49,15 @@
~MockHWC2ComposerCallback() = default;
MOCK_METHOD3(onHotplugReceived,
- void(int32_t sequenceId, hwc2_display_t display, HWC2::Connection connection));
- MOCK_METHOD2(onRefreshReceived, void(int32_t sequenceId, hwc2_display_t display));
+ void(int32_t sequenceId, hal::HWDisplayId display, hal::Connection connection));
+ MOCK_METHOD2(onRefreshReceived, void(int32_t sequenceId, hal::HWDisplayId display));
MOCK_METHOD4(onVsyncReceived,
- void(int32_t sequenceId, hwc2_display_t display, int64_t timestamp,
- std::optional<hwc2_vsync_period_t> vsyncPeriod));
+ void(int32_t sequenceId, hal::HWDisplayId display, int64_t timestamp,
+ std::optional<hal::VsyncPeriodNanos> vsyncPeriod));
MOCK_METHOD3(onVsyncPeriodTimingChangedReceived,
- void(int32_t sequenceId, hwc2_display_t display,
- const hwc_vsync_period_change_timeline_t& updatedTimeline));
- MOCK_METHOD2(onSeamlessPossible, void(int32_t sequenceId, hwc2_display_t display));
+ void(int32_t sequenceId, hal::HWDisplayId display,
+ const hal::VsyncPeriodChangeTimeline& updatedTimeline));
+ MOCK_METHOD2(onSeamlessPossible, void(int32_t sequenceId, hal::HWDisplayId display));
};
struct HWComposerTest : public testing::Test {
@@ -73,14 +75,12 @@
constexpr bool kMetadata2Mandatory = true;
EXPECT_CALL(*mHal, getMaxVirtualDisplayCount()).WillOnce(Return(0));
- EXPECT_CALL(*mHal, getCapabilities())
- .WillOnce(Return(std::vector<Hwc2::IComposer::Capability>{}));
+ EXPECT_CALL(*mHal, getCapabilities()).WillOnce(Return(std::vector<hal::Capability>{}));
EXPECT_CALL(*mHal, getLayerGenericMetadataKeys(_))
- .WillOnce(DoAll(SetArgPointee<0>(
- std::vector<Hwc2::IComposerClient::LayerGenericMetadataKey>{
- {kMetadata1Name, kMetadata1Mandatory},
- {kMetadata2Name, kMetadata2Mandatory},
- }),
+ .WillOnce(DoAll(SetArgPointee<0>(std::vector<hal::LayerGenericMetadataKey>{
+ {kMetadata1Name, kMetadata1Mandatory},
+ {kMetadata2Name, kMetadata2Mandatory},
+ }),
Return(hardware::graphics::composer::V2_4::Error::NONE)));
EXPECT_CALL(*mHal, registerCallback(_));
EXPECT_CALL(*mHal, isVsyncPeriodSwitchSupported()).WillOnce(Return(false));
@@ -98,8 +98,7 @@
TEST_F(HWComposerSetConfigurationTest, handlesUnsupportedCallToGetLayerGenericMetadataKeys) {
EXPECT_CALL(*mHal, getMaxVirtualDisplayCount()).WillOnce(Return(0));
- EXPECT_CALL(*mHal, getCapabilities())
- .WillOnce(Return(std::vector<Hwc2::IComposer::Capability>{}));
+ EXPECT_CALL(*mHal, getCapabilities()).WillOnce(Return(std::vector<hal::Capability>{}));
EXPECT_CALL(*mHal, getLayerGenericMetadataKeys(_))
.WillOnce(Return(hardware::graphics::composer::V2_4::Error::UNSUPPORTED));
EXPECT_CALL(*mHal, registerCallback(_));
@@ -113,16 +112,16 @@
}
struct HWComposerLayerTest : public testing::Test {
- static constexpr hwc2_display_t kDisplayId = static_cast<hwc2_display_t>(1001);
- static constexpr hwc2_layer_t kLayerId = static_cast<hwc2_layer_t>(1002);
+ static constexpr hal::HWDisplayId kDisplayId = static_cast<hal::HWDisplayId>(1001);
+ static constexpr hal::HWLayerId kLayerId = static_cast<hal::HWLayerId>(1002);
- HWComposerLayerTest(const std::unordered_set<HWC2::Capability>& capabilities)
+ HWComposerLayerTest(const std::unordered_set<hal::Capability>& capabilities)
: mCapabilies(capabilities) {}
~HWComposerLayerTest() override { EXPECT_CALL(*mHal, destroyLayer(kDisplayId, kLayerId)); }
std::unique_ptr<Hwc2::mock::Composer> mHal{new StrictMock<Hwc2::mock::Composer>()};
- const std::unordered_set<HWC2::Capability> mCapabilies;
+ const std::unordered_set<hal::Capability> mCapabilies;
HWC2::impl::Layer mLayer{*mHal, mCapabilies, kDisplayId, kLayerId};
};
@@ -159,7 +158,7 @@
auto result = mLayer.setLayerGenericMetadata(kLayerGenericMetadata1Name,
kLayerGenericMetadata1Mandatory,
kLayerGenericMetadata1Value);
- EXPECT_EQ(HWC2::Error::None, result);
+ EXPECT_EQ(hal::Error::NONE, result);
EXPECT_CALL(*mHal,
setLayerGenericMetadata(kDisplayId, kLayerId, kLayerGenericMetadata2Name,
@@ -169,7 +168,7 @@
result = mLayer.setLayerGenericMetadata(kLayerGenericMetadata2Name,
kLayerGenericMetadata2Mandatory,
kLayerGenericMetadata2Value);
- EXPECT_EQ(HWC2::Error::Unsupported, result);
+ EXPECT_EQ(hal::Error::UNSUPPORTED, result);
}
} // namespace
diff --git a/services/surfaceflinger/tests/unittests/LayerHistoryTestV2.cpp b/services/surfaceflinger/tests/unittests/LayerHistoryTestV2.cpp
index 71e37a8..6fca673 100644
--- a/services/surfaceflinger/tests/unittests/LayerHistoryTestV2.cpp
+++ b/services/surfaceflinger/tests/unittests/LayerHistoryTestV2.cpp
@@ -270,12 +270,12 @@
EXPECT_EQ(1, activeLayerCount());
EXPECT_EQ(1, frequentLayerCount(time));
- // layer became inactive
+ // layer became inactive, but the vote stays
setLayerInfoVote(layer.get(), LayerHistory::LayerVoteType::Heuristic);
time += MAX_ACTIVE_LAYER_PERIOD_NS.count();
- ASSERT_TRUE(history().summarize(time).empty());
- // TODO: activeLayerCount() should be 0 but it is 1 since getFrameRateForLayerTree() returns a
- // value > 0
+ ASSERT_EQ(1, history().summarize(time).size());
+ EXPECT_EQ(LayerHistory::LayerVoteType::ExplicitDefault, history().summarize(time)[0].vote);
+ EXPECT_FLOAT_EQ(73.4f, history().summarize(time)[0].desiredRefreshRate);
EXPECT_EQ(1, activeLayerCount());
EXPECT_EQ(0, frequentLayerCount(time));
}
@@ -303,12 +303,13 @@
EXPECT_EQ(1, activeLayerCount());
EXPECT_EQ(1, frequentLayerCount(time));
- // layer became inactive
+ // layer became inactive, but the vote stays
setLayerInfoVote(layer.get(), LayerHistory::LayerVoteType::Heuristic);
time += MAX_ACTIVE_LAYER_PERIOD_NS.count();
- ASSERT_TRUE(history().summarize(time).empty());
- // TODO: activeLayerCount() should be 0 but it is 1 since getFrameRateForLayerTree() returns a
- // value > 0
+ ASSERT_EQ(1, history().summarize(time).size());
+ EXPECT_EQ(LayerHistory::LayerVoteType::ExplicitExactOrMultiple,
+ history().summarize(time)[0].vote);
+ EXPECT_FLOAT_EQ(73.4f, history().summarize(time)[0].desiredRefreshRate);
EXPECT_EQ(1, activeLayerCount());
EXPECT_EQ(0, frequentLayerCount(time));
}
diff --git a/services/surfaceflinger/tests/unittests/PhaseOffsetsTest.cpp b/services/surfaceflinger/tests/unittests/PhaseOffsetsTest.cpp
index ce5993a..0b74682 100644
--- a/services/surfaceflinger/tests/unittests/PhaseOffsetsTest.cpp
+++ b/services/surfaceflinger/tests/unittests/PhaseOffsetsTest.cpp
@@ -145,7 +145,9 @@
class TestablePhaseOffsets : public impl::PhaseOffsets {
public:
- TestablePhaseOffsets() : impl::PhaseOffsets({60.0f, 90.0f}, 60.0f, 10'000'000) {}
+ TestablePhaseOffsets()
+ : impl::PhaseOffsets({60.0f, 90.0f}, 60.0f, 1'000'000, 1'000'000, {}, {}, {}, {},
+ 10'000'000) {}
};
class PhaseOffsetsTest : public testing::Test {
diff --git a/services/surfaceflinger/tests/unittests/PromiseTest.cpp b/services/surfaceflinger/tests/unittests/PromiseTest.cpp
new file mode 100644
index 0000000..e4dc1fe
--- /dev/null
+++ b/services/surfaceflinger/tests/unittests/PromiseTest.cpp
@@ -0,0 +1,88 @@
+/*
+ * Copyright 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <algorithm>
+#include <future>
+#include <string>
+#include <thread>
+#include <vector>
+
+#include <gtest/gtest.h>
+
+#include "Promise.h"
+
+namespace android {
+namespace {
+
+using Bytes = std::vector<uint8_t>;
+
+Bytes decrement(Bytes bytes) {
+ std::transform(bytes.begin(), bytes.end(), bytes.begin(), [](auto b) { return b - 1; });
+ return bytes;
+}
+
+} // namespace
+
+TEST(PromiseTest, yield) {
+ EXPECT_EQ(42, promise::yield(42).get());
+
+ auto ptr = std::make_unique<char>('!');
+ auto future = promise::yield(std::move(ptr));
+ EXPECT_EQ('!', *future.get());
+}
+
+TEST(PromiseTest, chain) {
+ std::packaged_task<const char*()> fetchString([] { return "ifmmp-"; });
+
+ std::packaged_task<Bytes(std::string)> appendString([](std::string str) {
+ str += "!xpsme";
+ return Bytes{str.begin(), str.end()};
+ });
+
+ std::packaged_task<std::future<Bytes>(Bytes)> decrementBytes(
+ [](Bytes bytes) { return promise::defer(decrement, std::move(bytes)); });
+
+ auto fetch = fetchString.get_future();
+ std::thread fetchThread(std::move(fetchString));
+
+ std::thread appendThread, decrementThread;
+
+ EXPECT_EQ("hello, world",
+ promise::chain(std::move(fetch))
+ .then([](const char* str) { return std::string(str); })
+ .then([&](std::string str) {
+ auto append = appendString.get_future();
+ appendThread = std::thread(std::move(appendString), std::move(str));
+ return append;
+ })
+ .then([&](Bytes bytes) {
+ auto decrement = decrementBytes.get_future();
+ decrementThread = std::thread(std::move(decrementBytes),
+ std::move(bytes));
+ return decrement;
+ })
+ .then([](std::future<Bytes> bytes) { return bytes; })
+ .then([](const Bytes& bytes) {
+ return std::string(bytes.begin(), bytes.end());
+ })
+ .get());
+
+ fetchThread.join();
+ appendThread.join();
+ decrementThread.join();
+}
+
+} // namespace android
diff --git a/services/surfaceflinger/tests/unittests/RefreshRateConfigsTest.cpp b/services/surfaceflinger/tests/unittests/RefreshRateConfigsTest.cpp
index 1b8f11b..2ceb89c 100644
--- a/services/surfaceflinger/tests/unittests/RefreshRateConfigsTest.cpp
+++ b/services/surfaceflinger/tests/unittests/RefreshRateConfigsTest.cpp
@@ -32,6 +32,8 @@
namespace android {
namespace scheduler {
+namespace hal = android::hardware::graphics::composer::hal;
+
using RefreshRate = RefreshRateConfigs::RefreshRate;
using LayerVoteType = RefreshRateConfigs::LayerVoteType;
using LayerRequirement = RefreshRateConfigs::LayerRequirement;
@@ -142,7 +144,7 @@
std::shared_ptr<const HWC2::Display::Config> RefreshRateConfigsTest::createConfig(
HwcConfigIndexType configId, int32_t configGroup, int64_t vsyncPeriod, int32_t hight,
int32_t width) {
- return HWC2::Display::Config::Builder(mDisplay, hwc2_config_t(configId.value()))
+ return HWC2::Display::Config::Builder(mDisplay, hal::HWConfigId(configId.value()))
.setVsyncPeriod(int32_t(vsyncPeriod))
.setConfigGroup(configGroup)
.setHeight(hight)
diff --git a/services/surfaceflinger/tests/unittests/RefreshRateSelectionTest.cpp b/services/surfaceflinger/tests/unittests/RefreshRateSelectionTest.cpp
index 18b1063..43b8e01 100644
--- a/services/surfaceflinger/tests/unittests/RefreshRateSelectionTest.cpp
+++ b/services/surfaceflinger/tests/unittests/RefreshRateSelectionTest.cpp
@@ -142,10 +142,10 @@
auto primaryDispSync = std::make_unique<mock::DispSync>();
- EXPECT_CALL(*primaryDispSync, computeNextRefresh(0)).WillRepeatedly(Return(0));
+ EXPECT_CALL(*primaryDispSync, computeNextRefresh(0, _)).WillRepeatedly(Return(0));
EXPECT_CALL(*primaryDispSync, getPeriod())
.WillRepeatedly(Return(FakeHwcDisplayInjector::DEFAULT_REFRESH_RATE));
- EXPECT_CALL(*primaryDispSync, expectedPresentTime()).WillRepeatedly(Return(0));
+ EXPECT_CALL(*primaryDispSync, expectedPresentTime(_)).WillRepeatedly(Return(0));
mFlinger.setupScheduler(std::move(primaryDispSync),
std::make_unique<mock::EventControlThread>(), std::move(eventThread),
std::move(sfEventThread));
diff --git a/services/surfaceflinger/tests/unittests/RefreshRateStatsTest.cpp b/services/surfaceflinger/tests/unittests/RefreshRateStatsTest.cpp
index 038e6e6..de66f8f 100644
--- a/services/surfaceflinger/tests/unittests/RefreshRateStatsTest.cpp
+++ b/services/surfaceflinger/tests/unittests/RefreshRateStatsTest.cpp
@@ -30,6 +30,7 @@
#include "mock/MockTimeStats.h"
using namespace std::chrono_literals;
+using android::hardware::graphics::composer::hal::PowerMode;
using testing::_;
using testing::AtLeast;
@@ -50,10 +51,9 @@
void init(const std::vector<std::shared_ptr<const HWC2::Display::Config>>& configs) {
mRefreshRateConfigs =
std::make_unique<RefreshRateConfigs>(configs, /*currentConfig=*/CONFIG_ID_0);
- mRefreshRateStats =
- std::make_unique<RefreshRateStats>(*mRefreshRateConfigs, mTimeStats,
- /*currentConfigId=*/CONFIG_ID_0,
- /*currentPowerMode=*/HWC_POWER_MODE_OFF);
+ mRefreshRateStats = std::make_unique<RefreshRateStats>(*mRefreshRateConfigs, mTimeStats,
+ /*currentConfigId=*/CONFIG_ID_0,
+ /*currentPowerMode=*/PowerMode::OFF);
}
Hwc2::mock::Display mDisplay;
@@ -80,7 +80,7 @@
std::shared_ptr<const HWC2::Display::Config> RefreshRateStatsTest::createConfig(
HwcConfigIndexType configId, int32_t configGroup, int64_t vsyncPeriod) {
- return HWC2::Display::Config::Builder(mDisplay, hwc2_config_t(configId.value()))
+ return HWC2::Display::Config::Builder(mDisplay, configId.value())
.setVsyncPeriod(int32_t(vsyncPeriod))
.setConfigGroup(configGroup)
.build();
@@ -111,7 +111,7 @@
EXPECT_EQ(0u, times.count("90fps"));
mRefreshRateStats->setConfigMode(CONFIG_ID_0);
- mRefreshRateStats->setPowerMode(HWC_POWER_MODE_NORMAL);
+ mRefreshRateStats->setPowerMode(PowerMode::ON);
screenOff = mRefreshRateStats->getTotalTimes()["ScreenOff"];
std::this_thread::sleep_for(std::chrono::milliseconds(2));
times = mRefreshRateStats->getTotalTimes();
@@ -119,7 +119,7 @@
ASSERT_EQ(1u, times.count("90fps"));
EXPECT_LT(0, times["90fps"]);
- mRefreshRateStats->setPowerMode(HWC_POWER_MODE_DOZE);
+ mRefreshRateStats->setPowerMode(PowerMode::DOZE);
int ninety = mRefreshRateStats->getTotalTimes()["90fps"];
std::this_thread::sleep_for(std::chrono::milliseconds(2));
times = mRefreshRateStats->getTotalTimes();
@@ -130,7 +130,7 @@
screenOff = mRefreshRateStats->getTotalTimes()["ScreenOff"];
std::this_thread::sleep_for(std::chrono::milliseconds(2));
times = mRefreshRateStats->getTotalTimes();
- // Because the power mode is not HWC_POWER_MODE_NORMAL, switching the config
+ // Because the power mode is not PowerMode::ON, switching the config
// does not update refresh rates that come from the config.
EXPECT_LT(screenOff, times["ScreenOff"]);
EXPECT_EQ(ninety, times["90fps"]);
@@ -158,7 +158,7 @@
EXPECT_LT(screenOff, times["ScreenOff"]);
mRefreshRateStats->setConfigMode(CONFIG_ID_0);
- mRefreshRateStats->setPowerMode(HWC_POWER_MODE_NORMAL);
+ mRefreshRateStats->setPowerMode(PowerMode::ON);
screenOff = mRefreshRateStats->getTotalTimes()["ScreenOff"];
std::this_thread::sleep_for(std::chrono::milliseconds(2));
times = mRefreshRateStats->getTotalTimes();
@@ -192,9 +192,9 @@
EXPECT_EQ(ninety, times["90fps"]);
EXPECT_LT(sixty, times["60fps"]);
- // Because the power mode is not HWC_POWER_MODE_NORMAL, switching the config
+ // Because the power mode is not PowerMode::ON, switching the config
// does not update refresh rates that come from the config.
- mRefreshRateStats->setPowerMode(HWC_POWER_MODE_DOZE);
+ mRefreshRateStats->setPowerMode(PowerMode::DOZE);
mRefreshRateStats->setConfigMode(CONFIG_ID_0);
sixty = mRefreshRateStats->getTotalTimes()["60fps"];
std::this_thread::sleep_for(std::chrono::milliseconds(2));
diff --git a/services/surfaceflinger/tests/unittests/SetFrameRateTest.cpp b/services/surfaceflinger/tests/unittests/SetFrameRateTest.cpp
index b069085..0d6c799 100644
--- a/services/surfaceflinger/tests/unittests/SetFrameRateTest.cpp
+++ b/services/surfaceflinger/tests/unittests/SetFrameRateTest.cpp
@@ -178,10 +178,10 @@
auto primaryDispSync = std::make_unique<mock::DispSync>();
- EXPECT_CALL(*primaryDispSync, computeNextRefresh(0)).WillRepeatedly(Return(0));
+ EXPECT_CALL(*primaryDispSync, computeNextRefresh(0, _)).WillRepeatedly(Return(0));
EXPECT_CALL(*primaryDispSync, getPeriod())
.WillRepeatedly(Return(FakeHwcDisplayInjector::DEFAULT_REFRESH_RATE));
- EXPECT_CALL(*primaryDispSync, expectedPresentTime()).WillRepeatedly(Return(0));
+ EXPECT_CALL(*primaryDispSync, expectedPresentTime(_)).WillRepeatedly(Return(0));
mFlinger.setupScheduler(std::move(primaryDispSync),
std::make_unique<mock::EventControlThread>(), std::move(eventThread),
std::move(sfEventThread));
diff --git a/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h b/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h
index 6995ee0..add3327 100644
--- a/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h
+++ b/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h
@@ -57,6 +57,8 @@
} // namespace Hwc2
+namespace hal = android::hardware::graphics::composer::hal;
+
namespace surfaceflinger::test {
class Factory final : public surfaceflinger::Factory {
@@ -210,7 +212,7 @@
mFlinger->mRefreshRateStats = std::make_unique<
scheduler::RefreshRateStats>(*mFlinger->mRefreshRateConfigs, *mFlinger->mTimeStats,
/*currentConfig=*/HwcConfigIndexType(0),
- /*powerMode=*/HWC_POWER_MODE_OFF);
+ /*powerMode=*/hal::PowerMode::OFF);
mFlinger->mPhaseConfiguration =
mFactory.createPhaseConfiguration(*mFlinger->mRefreshRateConfigs);
@@ -257,12 +259,12 @@
layer->editCompositionState()->sidebandStream = sidebandStream;
}
- void setLayerCompositionType(sp<Layer> layer, HWC2::Composition type) {
+ void setLayerCompositionType(sp<Layer> layer, hal::Composition type) {
auto outputLayer = layer->findOutputLayerForDisplay(mFlinger->getDefaultDisplayDevice());
LOG_ALWAYS_FATAL_IF(!outputLayer);
auto& state = outputLayer->editState();
LOG_ALWAYS_FATAL_IF(!outputLayer->getState().hwc);
- (*state.hwc).hwcCompositionType = static_cast<Hwc2::IComposerClient::Composition>(type);
+ (*state.hwc).hwcCompositionType = type;
};
void setLayerPotentialCursor(sp<Layer> layer, bool potentialCursor) {
@@ -298,8 +300,8 @@
return mFlinger->handleTransactionLocked(transactionFlags);
}
- auto onHotplugReceived(int32_t sequenceId, hwc2_display_t display,
- HWC2::Connection connection) {
+ auto onHotplugReceived(int32_t sequenceId, hal::HWDisplayId display,
+ hal::Connection connection) {
return mFlinger->onHotplugReceived(sequenceId, display, connection);
}
@@ -315,19 +317,20 @@
// Allow reading display state without locking, as if called on the SF main thread.
auto setPowerModeInternal(const sp<DisplayDevice>& display,
- int mode) NO_THREAD_SAFETY_ANALYSIS {
+ hal::PowerMode mode) NO_THREAD_SAFETY_ANALYSIS {
return mFlinger->setPowerModeInternal(display, mode);
}
- auto onMessageReceived(int32_t what) { return mFlinger->onMessageReceived(what); }
+ auto onMessageReceived(int32_t what) { return mFlinger->onMessageReceived(what, systemTime()); }
- auto captureScreenImplLocked(
- const RenderArea& renderArea, SurfaceFlinger::TraverseLayersFunction traverseLayers,
- ANativeWindowBuffer* buffer, bool useIdentityTransform, bool forSystem, int* outSyncFd) {
+ auto captureScreenImplLocked(const RenderArea& renderArea,
+ SurfaceFlinger::TraverseLayersFunction traverseLayers,
+ ANativeWindowBuffer* buffer, bool useIdentityTransform,
+ bool forSystem, int* outSyncFd, bool regionSampling) {
bool ignored;
return mFlinger->captureScreenImplLocked(renderArea, traverseLayers, buffer,
useIdentityTransform, forSystem, outSyncFd,
- ignored);
+ regionSampling, ignored);
}
auto traverseLayersInDisplay(const sp<const DisplayDevice>& display,
@@ -402,7 +405,6 @@
auto& mutableUseFrameRateApi() { return mFlinger->useFrameRateApi; }
auto fromHandle(const sp<IBinder>& handle) {
- Mutex::Autolock _l(mFlinger->mStateLock);
return mFlinger->fromHandle(handle);
}
@@ -428,12 +430,12 @@
*/
struct HWC2Display : public HWC2::impl::Display {
HWC2Display(Hwc2::Composer& composer,
- const std::unordered_set<HWC2::Capability>& capabilities, hwc2_display_t id,
- HWC2::DisplayType type)
+ const std::unordered_set<hal::Capability>& capabilities, hal::HWDisplayId id,
+ hal::DisplayType type)
: HWC2::impl::Display(composer, capabilities, id, type) {}
~HWC2Display() {
// Prevents a call to disable vsyncs.
- mType = HWC2::DisplayType::Invalid;
+ mType = hal::DisplayType::INVALID;
}
auto& mutableIsConnected() { return this->mIsConnected; }
@@ -443,20 +445,19 @@
class FakeHwcDisplayInjector {
public:
- static constexpr hwc2_display_t DEFAULT_HWC_DISPLAY_ID = 1000;
+ static constexpr hal::HWDisplayId DEFAULT_HWC_DISPLAY_ID = 1000;
static constexpr int32_t DEFAULT_WIDTH = 1920;
static constexpr int32_t DEFAULT_HEIGHT = 1280;
static constexpr int32_t DEFAULT_REFRESH_RATE = 16'666'666;
static constexpr int32_t DEFAULT_CONFIG_GROUP = 7;
static constexpr int32_t DEFAULT_DPI = 320;
- static constexpr hwc2_config_t DEFAULT_ACTIVE_CONFIG = 0;
- static constexpr int32_t DEFAULT_POWER_MODE = 2;
+ static constexpr hal::HWConfigId DEFAULT_ACTIVE_CONFIG = 0;
+ static constexpr hal::PowerMode DEFAULT_POWER_MODE = hal::PowerMode::ON;
- FakeHwcDisplayInjector(DisplayId displayId, HWC2::DisplayType hwcDisplayType,
- bool isPrimary)
+ FakeHwcDisplayInjector(DisplayId displayId, hal::DisplayType hwcDisplayType, bool isPrimary)
: mDisplayId(displayId), mHwcDisplayType(hwcDisplayType), mIsPrimary(isPrimary) {}
- auto& setHwcDisplayId(hwc2_display_t displayId) {
+ auto& setHwcDisplayId(hal::HWDisplayId displayId) {
mHwcDisplayId = displayId;
return *this;
}
@@ -486,23 +487,23 @@
return *this;
}
- auto& setActiveConfig(hwc2_config_t config) {
+ auto& setActiveConfig(hal::HWConfigId config) {
mActiveConfig = config;
return *this;
}
- auto& setCapabilities(const std::unordered_set<HWC2::Capability>* capabilities) {
+ auto& setCapabilities(const std::unordered_set<hal::Capability>* capabilities) {
mCapabilities = capabilities;
return *this;
}
- auto& setPowerMode(int mode) {
+ auto& setPowerMode(hal::PowerMode mode) {
mPowerMode = mode;
return *this;
}
void inject(TestableSurfaceFlinger* flinger, Hwc2::Composer* composer) {
- static const std::unordered_set<HWC2::Capability> defaultCapabilities;
+ static const std::unordered_set<hal::Capability> defaultCapabilities;
if (mCapabilities == nullptr) mCapabilities = &defaultCapabilities;
// Caution - Make sure that any values passed by reference here do
@@ -521,11 +522,11 @@
config.setConfigGroup(mConfigGroup);
display->mutableConfigs().emplace(static_cast<int32_t>(mActiveConfig), config.build());
display->mutableIsConnected() = true;
- display->setPowerMode(static_cast<HWC2::PowerMode>(mPowerMode));
+ display->setPowerMode(mPowerMode);
flinger->mutableHwcDisplayData()[mDisplayId].hwcDisplay = std::move(display);
- if (mHwcDisplayType == HWC2::DisplayType::Physical) {
+ if (mHwcDisplayType == hal::DisplayType::PHYSICAL) {
flinger->mutableHwcPhysicalDisplayIdMap().emplace(mHwcDisplayId, mDisplayId);
(mIsPrimary ? flinger->mutableInternalHwcDisplayId()
: flinger->mutableExternalHwcDisplayId()) = mHwcDisplayId;
@@ -534,19 +535,19 @@
private:
const DisplayId mDisplayId;
- const HWC2::DisplayType mHwcDisplayType;
+ const hal::DisplayType mHwcDisplayType;
const bool mIsPrimary;
- hwc2_display_t mHwcDisplayId = DEFAULT_HWC_DISPLAY_ID;
+ hal::HWDisplayId mHwcDisplayId = DEFAULT_HWC_DISPLAY_ID;
int32_t mWidth = DEFAULT_WIDTH;
int32_t mHeight = DEFAULT_HEIGHT;
int32_t mRefreshRate = DEFAULT_REFRESH_RATE;
int32_t mDpiX = DEFAULT_DPI;
int32_t mConfigGroup = DEFAULT_CONFIG_GROUP;
int32_t mDpiY = DEFAULT_DPI;
- hwc2_config_t mActiveConfig = DEFAULT_ACTIVE_CONFIG;
- int32_t mPowerMode = DEFAULT_POWER_MODE;
- const std::unordered_set<HWC2::Capability>* mCapabilities = nullptr;
+ hal::HWConfigId mActiveConfig = DEFAULT_ACTIVE_CONFIG;
+ hal::PowerMode mPowerMode = DEFAULT_POWER_MODE;
+ const std::unordered_set<hal::Capability>* mCapabilities = nullptr;
};
class FakeDisplayDeviceInjector {
@@ -554,7 +555,7 @@
FakeDisplayDeviceInjector(TestableSurfaceFlinger& flinger,
std::shared_ptr<compositionengine::Display> compositionDisplay,
std::optional<DisplayConnectionType> connectionType,
- std::optional<hwc2_display_t> hwcDisplayId, bool isPrimary)
+ std::optional<hal::HWDisplayId> hwcDisplayId, bool isPrimary)
: mFlinger(flinger),
mCreationArgs(flinger.mFlinger.get(), mDisplayToken, compositionDisplay),
mHwcDisplayId(hwcDisplayId) {
@@ -597,7 +598,7 @@
return *this;
}
- auto& setPowerMode(int mode) {
+ auto& setPowerMode(hal::PowerMode mode) {
mCreationArgs.initialPowerMode = mode;
return *this;
}
@@ -647,7 +648,7 @@
TestableSurfaceFlinger& mFlinger;
sp<BBinder> mDisplayToken = new BBinder();
DisplayDeviceCreationArgs mCreationArgs;
- const std::optional<hwc2_display_t> mHwcDisplayId;
+ const std::optional<hal::HWDisplayId> mHwcDisplayId;
};
surfaceflinger::test::Factory mFactory;
diff --git a/services/surfaceflinger/tests/unittests/TimeStatsTest.cpp b/services/surfaceflinger/tests/unittests/TimeStatsTest.cpp
index 1f04673..7a1c7c6 100644
--- a/services/surfaceflinger/tests/unittests/TimeStatsTest.cpp
+++ b/services/surfaceflinger/tests/unittests/TimeStatsTest.cpp
@@ -51,6 +51,8 @@
using testing::StrEq;
using testing::UnorderedElementsAre;
+using PowerMode = hardware::graphics::composer::V2_4::IComposerClient::PowerMode;
+
// clang-format off
#define FMT_PROTO true
#define FMT_STRING false
@@ -377,9 +379,24 @@
EXPECT_THAT(result, HasSubstr(expectedResult));
}
+TEST_F(TimeStatsTest, canIncreaseCompositionStrategyChanges) {
+ // this stat is not in the proto so verify by checking the string dump
+ constexpr size_t COMPOSITION_STRATEGY_CHANGES = 2;
+
+ EXPECT_TRUE(inputCommand(InputCommand::ENABLE, FMT_STRING).empty());
+ for (size_t i = 0; i < COMPOSITION_STRATEGY_CHANGES; i++) {
+ ASSERT_NO_FATAL_FAILURE(mTimeStats->incrementCompositionStrategyChanges());
+ }
+
+ const std::string result(inputCommand(InputCommand::DUMP_ALL, FMT_STRING));
+ const std::string expectedResult =
+ "compositionStrategyChanges = " + std::to_string(COMPOSITION_STRATEGY_CHANGES);
+ EXPECT_THAT(result, HasSubstr(expectedResult));
+}
+
TEST_F(TimeStatsTest, canAverageFrameDuration) {
EXPECT_TRUE(inputCommand(InputCommand::ENABLE, FMT_STRING).empty());
- mTimeStats->setPowerMode(HWC_POWER_MODE_NORMAL);
+ mTimeStats->setPowerMode(PowerMode::ON);
mTimeStats
->recordFrameDuration(std::chrono::duration_cast<std::chrono::nanoseconds>(1ms).count(),
std::chrono::duration_cast<std::chrono::nanoseconds>(6ms)
@@ -408,7 +425,7 @@
.count());
// Push a dummy present fence to trigger flushing the RenderEngine timings.
- mTimeStats->setPowerMode(HWC_POWER_MODE_NORMAL);
+ mTimeStats->setPowerMode(PowerMode::ON);
mTimeStats->setPresentFenceGlobal(std::make_shared<FenceTime>(
std::chrono::duration_cast<std::chrono::nanoseconds>(1ms).count()));
@@ -424,13 +441,13 @@
ASSERT_NO_FATAL_FAILURE(
mTimeStats->setPresentFenceGlobal(std::make_shared<FenceTime>(2000000)));
- ASSERT_NO_FATAL_FAILURE(mTimeStats->setPowerMode(HWC_POWER_MODE_NORMAL));
+ ASSERT_NO_FATAL_FAILURE(mTimeStats->setPowerMode(PowerMode::ON));
ASSERT_NO_FATAL_FAILURE(
mTimeStats->setPresentFenceGlobal(std::make_shared<FenceTime>(3000000)));
ASSERT_NO_FATAL_FAILURE(
mTimeStats->setPresentFenceGlobal(std::make_shared<FenceTime>(5000000)));
- ASSERT_NO_FATAL_FAILURE(mTimeStats->setPowerMode(HWC_POWER_MODE_OFF));
+ ASSERT_NO_FATAL_FAILURE(mTimeStats->setPowerMode(PowerMode::OFF));
ASSERT_NO_FATAL_FAILURE(
mTimeStats->setPresentFenceGlobal(std::make_shared<FenceTime>(6000000)));
ASSERT_NO_FATAL_FAILURE(
@@ -448,12 +465,12 @@
TEST_F(TimeStatsTest, canInsertGlobalFrameDuration) {
EXPECT_TRUE(inputCommand(InputCommand::ENABLE, FMT_STRING).empty());
- mTimeStats->setPowerMode(HWC_POWER_MODE_OFF);
+ mTimeStats->setPowerMode(PowerMode::OFF);
mTimeStats
->recordFrameDuration(std::chrono::duration_cast<std::chrono::nanoseconds>(1ms).count(),
std::chrono::duration_cast<std::chrono::nanoseconds>(5ms)
.count());
- mTimeStats->setPowerMode(HWC_POWER_MODE_NORMAL);
+ mTimeStats->setPowerMode(PowerMode::ON);
mTimeStats
->recordFrameDuration(std::chrono::duration_cast<std::chrono::nanoseconds>(3ms).count(),
std::chrono::duration_cast<std::chrono::nanoseconds>(6ms)
@@ -489,7 +506,7 @@
ASSERT_EQ(0, preFlushProto.render_engine_timing_size());
// Push a dummy present fence to trigger flushing the RenderEngine timings.
- mTimeStats->setPowerMode(HWC_POWER_MODE_NORMAL);
+ mTimeStats->setPowerMode(PowerMode::ON);
mTimeStats->setPresentFenceGlobal(std::make_shared<FenceTime>(
std::chrono::duration_cast<std::chrono::nanoseconds>(1ms).count()));
@@ -724,7 +741,7 @@
ASSERT_NO_FATAL_FAILURE(mTimeStats->incrementTotalFrames());
ASSERT_NO_FATAL_FAILURE(mTimeStats->incrementMissedFrames());
ASSERT_NO_FATAL_FAILURE(mTimeStats->incrementClientCompositionFrames());
- ASSERT_NO_FATAL_FAILURE(mTimeStats->setPowerMode(HWC_POWER_MODE_NORMAL));
+ ASSERT_NO_FATAL_FAILURE(mTimeStats->setPowerMode(PowerMode::ON));
mTimeStats
->recordFrameDuration(std::chrono::duration_cast<std::chrono::nanoseconds>(3ms).count(),
@@ -760,7 +777,8 @@
EXPECT_TRUE(inputCommand(InputCommand::ENABLE, FMT_STRING).empty());
ASSERT_NO_FATAL_FAILURE(mTimeStats->incrementClientCompositionReusedFrames());
ASSERT_NO_FATAL_FAILURE(mTimeStats->incrementRefreshRateSwitches());
- mTimeStats->setPowerMode(HWC_POWER_MODE_NORMAL);
+ ASSERT_NO_FATAL_FAILURE(mTimeStats->incrementCompositionStrategyChanges());
+ mTimeStats->setPowerMode(PowerMode::ON);
mTimeStats
->recordFrameDuration(std::chrono::duration_cast<std::chrono::nanoseconds>(1ms).count(),
std::chrono::duration_cast<std::chrono::nanoseconds>(5ms)
@@ -776,6 +794,7 @@
const std::string result(inputCommand(InputCommand::DUMP_ALL, FMT_STRING));
EXPECT_THAT(result, HasSubstr("clientCompositionReusedFrames = 0"));
EXPECT_THAT(result, HasSubstr("refreshRateSwitches = 0"));
+ EXPECT_THAT(result, HasSubstr("compositionStrategyChanges = 0"));
EXPECT_THAT(result, HasSubstr("averageFrameDuration = 0.000 ms"));
EXPECT_THAT(result, HasSubstr("averageRenderEngineTiming = 0.000 ms"));
}
@@ -877,7 +896,7 @@
}
mTimeStats->recordDisplayEventConnectionCount(DISPLAY_EVENT_CONNECTIONS);
- mTimeStats->setPowerMode(HWC_POWER_MODE_NORMAL);
+ mTimeStats->setPowerMode(PowerMode::ON);
mTimeStats->recordFrameDuration(1000000, 3000000);
mTimeStats->recordRenderEngineDuration(2000000, 4000000);
mTimeStats->recordRenderEngineDuration(2000000, std::make_shared<FenceTime>(3000000));
@@ -1057,7 +1076,7 @@
insertTimeRecord(NORMAL_SEQUENCE, LAYER_ID_0, 4, 5000000);
// Now make sure that TimeStats flushes global stats to set the callback.
- mTimeStats->setPowerMode(HWC_POWER_MODE_NORMAL);
+ mTimeStats->setPowerMode(PowerMode::ON);
mTimeStats->setPresentFenceGlobal(std::make_shared<FenceTime>(3000000));
mTimeStats->setPresentFenceGlobal(std::make_shared<FenceTime>(5000000));
EXPECT_THAT(mDelegate->mAtomTags,
diff --git a/services/surfaceflinger/tests/unittests/TransactionApplicationTest.cpp b/services/surfaceflinger/tests/unittests/TransactionApplicationTest.cpp
index f1739e5..2a48a22 100644
--- a/services/surfaceflinger/tests/unittests/TransactionApplicationTest.cpp
+++ b/services/surfaceflinger/tests/unittests/TransactionApplicationTest.cpp
@@ -76,7 +76,7 @@
new EventThreadConnection(sfEventThread.get(), ResyncCallback(),
ISurfaceComposer::eConfigChangedSuppress)));
- EXPECT_CALL(*mPrimaryDispSync, computeNextRefresh(0)).WillRepeatedly(Return(0));
+ EXPECT_CALL(*mPrimaryDispSync, computeNextRefresh(0, _)).WillRepeatedly(Return(0));
EXPECT_CALL(*mPrimaryDispSync, getPeriod())
.WillRepeatedly(Return(FakeHwcDisplayInjector::DEFAULT_REFRESH_RATE));
@@ -126,7 +126,7 @@
ASSERT_EQ(0, mFlinger.getTransactionQueue().size());
// called in SurfaceFlinger::signalTransaction
EXPECT_CALL(*mMessageQueue, invalidate()).Times(1);
- EXPECT_CALL(*mPrimaryDispSync, expectedPresentTime()).WillOnce(Return(systemTime()));
+ EXPECT_CALL(*mPrimaryDispSync, expectedPresentTime(_)).WillOnce(Return(systemTime()));
TransactionInfo transaction;
setupSingle(transaction, flags, syncInputWindows,
/*desiredPresentTime*/ -1);
@@ -159,7 +159,7 @@
// first check will see desired present time has not passed,
// but afterwards it will look like the desired present time has passed
nsecs_t time = systemTime();
- EXPECT_CALL(*mPrimaryDispSync, expectedPresentTime())
+ EXPECT_CALL(*mPrimaryDispSync, expectedPresentTime(_))
.WillOnce(Return(time + nsecs_t(5 * 1e8)));
TransactionInfo transaction;
setupSingle(transaction, flags, syncInputWindows,
@@ -182,7 +182,7 @@
// called in SurfaceFlinger::signalTransaction
nsecs_t time = systemTime();
EXPECT_CALL(*mMessageQueue, invalidate()).Times(1);
- EXPECT_CALL(*mPrimaryDispSync, expectedPresentTime())
+ EXPECT_CALL(*mPrimaryDispSync, expectedPresentTime(_))
.WillOnce(Return(time + nsecs_t(5 * 1e8)));
// transaction that should go on the pending thread
TransactionInfo transactionA;
@@ -247,7 +247,7 @@
EXPECT_CALL(*mMessageQueue, invalidate()).Times(1);
// nsecs_t time = systemTime();
- EXPECT_CALL(*mPrimaryDispSync, expectedPresentTime())
+ EXPECT_CALL(*mPrimaryDispSync, expectedPresentTime(_))
.WillOnce(Return(nsecs_t(5 * 1e8)))
.WillOnce(Return(s2ns(2)));
TransactionInfo transactionA; // transaction to go on pending queue
@@ -322,7 +322,7 @@
TEST_F(TransactionApplicationTest, FromHandle) {
sp<IBinder> badHandle;
auto ret = mFlinger.fromHandle(badHandle);
- EXPECT_EQ(nullptr, ret.get());
+ EXPECT_EQ(nullptr, ret.promote().get());
}
} // namespace android
diff --git a/services/surfaceflinger/tests/unittests/VSyncReactorTest.cpp b/services/surfaceflinger/tests/unittests/VSyncReactorTest.cpp
index 4f150ef..3f14d65 100644
--- a/services/surfaceflinger/tests/unittests/VSyncReactorTest.cpp
+++ b/services/surfaceflinger/tests/unittests/VSyncReactorTest.cpp
@@ -135,7 +135,7 @@
class StubCallback : public DispSync::Callback {
public:
- void onDispSyncEvent(nsecs_t when) final {
+ void onDispSyncEvent(nsecs_t when, nsecs_t /*expectedVSyncTimestamp*/) final {
std::lock_guard<std::mutex> lk(mMutex);
mLastCallTime = when;
}
@@ -270,7 +270,7 @@
.Times(1)
.WillOnce(Return(fakeTimestamp));
- EXPECT_THAT(mReactor.computeNextRefresh(0), Eq(fakeTimestamp));
+ EXPECT_THAT(mReactor.computeNextRefresh(0, mMockClock->now()), Eq(fakeTimestamp));
}
TEST_F(VSyncReactorTest, queriesTrackerForExpectedPresentTime) {
@@ -280,7 +280,7 @@
.Times(1)
.WillOnce(Return(fakeTimestamp));
- EXPECT_THAT(mReactor.expectedPresentTime(), Eq(fakeTimestamp));
+ EXPECT_THAT(mReactor.expectedPresentTime(mMockClock->now()), Eq(fakeTimestamp));
}
TEST_F(VSyncReactorTest, queriesTrackerForNextRefreshFuture) {
@@ -292,7 +292,7 @@
EXPECT_CALL(*mMockTracker, currentPeriod()).WillOnce(Return(fakePeriod));
EXPECT_CALL(*mMockTracker, nextAnticipatedVSyncTimeFrom(mFakeNow + numPeriodsOut * fakePeriod))
.WillOnce(Return(fakeTimestamp));
- EXPECT_THAT(mReactor.computeNextRefresh(numPeriodsOut), Eq(fakeTimestamp));
+ EXPECT_THAT(mReactor.computeNextRefresh(numPeriodsOut, mMockClock->now()), Eq(fakeTimestamp));
}
TEST_F(VSyncReactorTest, getPeriod) {
@@ -544,7 +544,9 @@
class SelfRemovingCallback : public DispSync::Callback {
public:
SelfRemovingCallback(VSyncReactor& vsr) : mVsr(vsr) {}
- void onDispSyncEvent(nsecs_t when) final { mVsr.removeEventListener(this, &when); }
+ void onDispSyncEvent(nsecs_t when, nsecs_t /*expectedVSyncTimestamp*/) final {
+ mVsr.removeEventListener(this, &when);
+ }
private:
VSyncReactor& mVsr;
diff --git a/services/surfaceflinger/tests/unittests/mock/DisplayHardware/MockDisplay.h b/services/surfaceflinger/tests/unittests/mock/DisplayHardware/MockDisplay.h
index 3968035..67d3e1c 100644
--- a/services/surfaceflinger/tests/unittests/mock/DisplayHardware/MockDisplay.h
+++ b/services/surfaceflinger/tests/unittests/mock/DisplayHardware/MockDisplay.h
@@ -20,78 +20,80 @@
#include "DisplayHardware/HWC2.h"
-using HWC2::Error;
-using HWC2::Layer;
+using android::HWC2::Layer;
namespace android {
namespace Hwc2 {
namespace mock {
+namespace hal = android::hardware::graphics::composer::hal;
+
class Display : public HWC2::Display {
public:
- using Error = ::Error;
using Layer = ::Layer;
Display();
~Display();
- MOCK_CONST_METHOD0(getId, hwc2_layer_t());
+ MOCK_CONST_METHOD0(getId, hal::HWDisplayId());
MOCK_CONST_METHOD0(isConnected, bool());
MOCK_METHOD1(setConnected, void(bool));
- MOCK_CONST_METHOD0(getCapabilities, const std::unordered_set<HWC2::DisplayCapability>&());
+ MOCK_CONST_METHOD0(getCapabilities, const std::unordered_set<hal::DisplayCapability>&());
- MOCK_METHOD0(acceptChanges, Error());
- MOCK_METHOD1(createLayer, Error(Layer**));
- MOCK_METHOD1(destroyLayer, Error(Layer*));
- MOCK_CONST_METHOD1(getActiveConfig, Error(std::shared_ptr<const Config>*));
- MOCK_CONST_METHOD1(getActiveConfigIndex, Error(int* outIndex));
- MOCK_METHOD1(getChangedCompositionTypes, Error(std::unordered_map<Layer*, HWC2::Composition>*));
- MOCK_CONST_METHOD1(getColorModes, Error(std::vector<android::ui::ColorMode>*));
+ MOCK_METHOD0(acceptChanges, hal::Error());
+ MOCK_METHOD1(createLayer, hal::Error(Layer**));
+ MOCK_METHOD1(destroyLayer, hal::Error(Layer*));
+ MOCK_CONST_METHOD1(getActiveConfig, hal::Error(std::shared_ptr<const Config>*));
+ MOCK_CONST_METHOD1(getActiveConfigIndex, hal::Error(int* outIndex));
+ MOCK_METHOD1(getChangedCompositionTypes,
+ hal::Error(std::unordered_map<Layer*, hal::Composition>*));
+ MOCK_CONST_METHOD1(getColorModes, hal::Error(std::vector<hal::ColorMode>*));
MOCK_CONST_METHOD0(getSupportedPerFrameMetadata, int32_t());
MOCK_CONST_METHOD2(getRenderIntents,
- Error(android::ui::ColorMode, std::vector<android::ui::RenderIntent>*));
- MOCK_METHOD2(getDataspaceSaturationMatrix, Error(android::ui::Dataspace, android::mat4*));
+ hal::Error(hal::ColorMode, std::vector<hal::RenderIntent>*));
+ MOCK_METHOD2(getDataspaceSaturationMatrix, hal::Error(hal::Dataspace, android::mat4*));
MOCK_CONST_METHOD0(getConfigs, std::vector<std::shared_ptr<const Config>>());
- MOCK_CONST_METHOD1(getName, Error(std::string*));
+ MOCK_CONST_METHOD1(getName, hal::Error(std::string*));
MOCK_METHOD2(getRequests,
- Error(HWC2::DisplayRequest*, std::unordered_map<Layer*, HWC2::LayerRequest>*));
- MOCK_CONST_METHOD1(getType, Error(HWC2::DisplayType*));
- MOCK_CONST_METHOD1(supportsDoze, Error(bool*));
- MOCK_CONST_METHOD1(getHdrCapabilities, Error(android::HdrCapabilities*));
+ hal::Error(hal::DisplayRequest*, std::unordered_map<Layer*, hal::LayerRequest>*));
+ MOCK_CONST_METHOD1(getType, hal::Error(hal::DisplayType*));
+ MOCK_CONST_METHOD1(supportsDoze, hal::Error(bool*));
+ MOCK_CONST_METHOD1(getHdrCapabilities, hal::Error(android::HdrCapabilities*));
MOCK_CONST_METHOD3(getDisplayedContentSamplingAttributes,
- Error(android::ui::PixelFormat*, android::ui::Dataspace*, uint8_t*));
- MOCK_CONST_METHOD3(setDisplayContentSamplingEnabled, Error(bool, uint8_t, uint64_t));
+ hal::Error(hal::PixelFormat*, hal::Dataspace*, uint8_t*));
+ MOCK_CONST_METHOD3(setDisplayContentSamplingEnabled, hal::Error(bool, uint8_t, uint64_t));
MOCK_CONST_METHOD3(getDisplayedContentSample,
- Error(uint64_t, uint64_t, android::DisplayedFrameStats*));
- MOCK_CONST_METHOD1(getReleaseFences,
- Error(std::unordered_map<Layer*, android::sp<android::Fence>>* outFences));
- MOCK_METHOD1(present, Error(android::sp<android::Fence>*));
- MOCK_METHOD1(setActiveConfig, Error(const std::shared_ptr<const HWC2::Display::Config>&));
+ hal::Error(uint64_t, uint64_t, android::DisplayedFrameStats*));
+ MOCK_CONST_METHOD1(
+ getReleaseFences,
+ hal::Error(std::unordered_map<Layer*, android::sp<android::Fence>>* outFences));
+ MOCK_METHOD1(present, hal::Error(android::sp<android::Fence>*));
+ MOCK_METHOD1(setActiveConfig, hal::Error(const std::shared_ptr<const HWC2::Display::Config>&));
MOCK_METHOD4(setClientTarget,
- Error(uint32_t, const android::sp<android::GraphicBuffer>&,
- const android::sp<android::Fence>&, android::ui::Dataspace));
- MOCK_METHOD2(setColorMode, Error(android::ui::ColorMode, android::ui::RenderIntent));
- MOCK_METHOD2(setColorTransform, Error(const android::mat4&, android_color_transform_t));
+ hal::Error(uint32_t, const android::sp<android::GraphicBuffer>&,
+ const android::sp<android::Fence>&, hal::Dataspace));
+ MOCK_METHOD2(setColorMode, hal::Error(hal::ColorMode, hal::RenderIntent));
+ MOCK_METHOD2(setColorTransform, hal::Error(const android::mat4&, hal::ColorTransform));
MOCK_METHOD2(setOutputBuffer,
- Error(const android::sp<android::GraphicBuffer>&,
- const android::sp<android::Fence>&));
- MOCK_METHOD1(setPowerMode, Error(HWC2::PowerMode));
- MOCK_METHOD1(setVsyncEnabled, Error(HWC2::Vsync));
- MOCK_METHOD2(validate, Error(uint32_t*, uint32_t*));
+ hal::Error(const android::sp<android::GraphicBuffer>&,
+ const android::sp<android::Fence>&));
+ MOCK_METHOD1(setPowerMode, hal::Error(hal::PowerMode));
+ MOCK_METHOD1(setVsyncEnabled, hal::Error(hal::Vsync));
+ MOCK_METHOD2(validate, hal::Error(uint32_t*, uint32_t*));
MOCK_METHOD4(presentOrValidate,
- Error(uint32_t*, uint32_t*, android::sp<android::Fence>*, uint32_t*));
- MOCK_CONST_METHOD1(setDisplayBrightness, Error(float));
- MOCK_CONST_METHOD1(getDisplayVsyncPeriod, Error(nsecs_t*));
+ hal::Error(uint32_t*, uint32_t*, android::sp<android::Fence>*, uint32_t*));
+ MOCK_CONST_METHOD1(setDisplayBrightness, hal::Error(float));
+ MOCK_CONST_METHOD1(getDisplayVsyncPeriod, hal::Error(nsecs_t*));
MOCK_METHOD3(setActiveConfigWithConstraints,
- Error(const std::shared_ptr<const HWC2::Display::Config>&,
- const HWC2::VsyncPeriodChangeConstraints&,
- HWC2::VsyncPeriodChangeTimeline*));
- MOCK_CONST_METHOD1(setAutoLowLatencyMode, Error(bool on));
- MOCK_CONST_METHOD1(getSupportedContentTypes, Error(std::vector<HWC2::ContentType>*));
- MOCK_CONST_METHOD1(setContentType, Error(HWC2::ContentType));
- MOCK_CONST_METHOD1(getConnectionType, Error(android::DisplayConnectionType*));
+ hal::Error(const std::shared_ptr<const HWC2::Display::Config>&,
+ const hal::VsyncPeriodChangeConstraints&,
+ hal::VsyncPeriodChangeTimeline*));
+ MOCK_CONST_METHOD1(setAutoLowLatencyMode, hal::Error(bool on));
+ MOCK_CONST_METHOD1(getSupportedContentTypes, hal::Error(std::vector<hal::ContentType>*));
+ MOCK_CONST_METHOD1(setContentType, hal::Error(hal::ContentType));
+ MOCK_CONST_METHOD1(getConnectionType, hal::Error(android::DisplayConnectionType*));
MOCK_CONST_METHOD0(isVsyncPeriodSwitchSupported, bool());
};
diff --git a/services/surfaceflinger/tests/unittests/mock/MockDispSync.cpp b/services/surfaceflinger/tests/unittests/mock/MockDispSync.cpp
index f6c4f62..1c8c44d 100644
--- a/services/surfaceflinger/tests/unittests/mock/MockDispSync.cpp
+++ b/services/surfaceflinger/tests/unittests/mock/MockDispSync.cpp
@@ -17,6 +17,7 @@
#include "mock/MockDispSync.h"
#include <thread>
+using namespace std::chrono_literals;
namespace android {
namespace mock {
@@ -54,8 +55,9 @@
void DispSync::triggerCallback() {
if (mCallback.callback == nullptr) return;
- mCallback.callback->onDispSyncEvent(
- std::chrono::steady_clock::now().time_since_epoch().count());
+ const std::chrono::nanoseconds now = std::chrono::steady_clock::now().time_since_epoch();
+ const auto expectedVSyncTime = now + 16ms;
+ mCallback.callback->onDispSyncEvent(now.count(), expectedVSyncTime.count());
}
} // namespace mock
diff --git a/services/surfaceflinger/tests/unittests/mock/MockDispSync.h b/services/surfaceflinger/tests/unittests/mock/MockDispSync.h
index a2ae6c9..b39487c 100644
--- a/services/surfaceflinger/tests/unittests/mock/MockDispSync.h
+++ b/services/surfaceflinger/tests/unittests/mock/MockDispSync.h
@@ -37,9 +37,9 @@
MOCK_METHOD0(getPeriod, nsecs_t());
MOCK_METHOD0(getIntendedPeriod, nsecs_t());
MOCK_METHOD1(setRefreshSkipCount, void(int));
- MOCK_CONST_METHOD1(computeNextRefresh, nsecs_t(int));
+ MOCK_CONST_METHOD2(computeNextRefresh, nsecs_t(int, nsecs_t));
MOCK_METHOD1(setIgnorePresentFences, void(bool));
- MOCK_METHOD0(expectedPresentTime, nsecs_t());
+ MOCK_METHOD1(expectedPresentTime, nsecs_t(nsecs_t));
MOCK_CONST_METHOD1(dump, void(std::string&));
diff --git a/services/surfaceflinger/tests/unittests/mock/MockMessageQueue.cpp b/services/surfaceflinger/tests/unittests/mock/MockMessageQueue.cpp
index 97a13e4..5fb06fd 100644
--- a/services/surfaceflinger/tests/unittests/mock/MockMessageQueue.cpp
+++ b/services/surfaceflinger/tests/unittests/mock/MockMessageQueue.cpp
@@ -16,12 +16,15 @@
#include "mock/MockMessageQueue.h"
-namespace android {
-namespace mock {
+namespace android::mock {
-// Explicit default instantiation is recommended.
-MessageQueue::MessageQueue() = default;
+MessageQueue::MessageQueue() {
+ ON_CALL(*this, postMessage).WillByDefault([](sp<MessageHandler>&& handler) {
+ // Execute task to prevent broken promise exception on destruction.
+ handler->handleMessage(Message());
+ });
+}
+
MessageQueue::~MessageQueue() = default;
-} // namespace mock
-} // namespace android
\ No newline at end of file
+} // namespace android::mock
diff --git a/services/surfaceflinger/tests/unittests/mock/MockMessageQueue.h b/services/surfaceflinger/tests/unittests/mock/MockMessageQueue.h
index e781c0a..a82b583 100644
--- a/services/surfaceflinger/tests/unittests/mock/MockMessageQueue.h
+++ b/services/surfaceflinger/tests/unittests/mock/MockMessageQueue.h
@@ -21,8 +21,7 @@
#include "Scheduler/EventThread.h"
#include "Scheduler/MessageQueue.h"
-namespace android {
-namespace mock {
+namespace android::mock {
class MessageQueue : public android::MessageQueue {
public:
@@ -32,10 +31,9 @@
MOCK_METHOD1(init, void(const sp<SurfaceFlinger>&));
MOCK_METHOD1(setEventConnection, void(const sp<EventThreadConnection>& connection));
MOCK_METHOD0(waitMessage, void());
- MOCK_METHOD2(postMessage, status_t(const sp<MessageBase>&, nsecs_t));
+ MOCK_METHOD1(postMessage, void(sp<MessageHandler>&&));
MOCK_METHOD0(invalidate, void());
MOCK_METHOD0(refresh, void());
};
-} // namespace mock
-} // namespace android
+} // namespace android::mock
diff --git a/services/surfaceflinger/tests/unittests/mock/MockTimeStats.h b/services/surfaceflinger/tests/unittests/mock/MockTimeStats.h
index 9ea4dd0..4186e2b 100644
--- a/services/surfaceflinger/tests/unittests/mock/MockTimeStats.h
+++ b/services/surfaceflinger/tests/unittests/mock/MockTimeStats.h
@@ -37,6 +37,7 @@
MOCK_METHOD0(incrementClientCompositionFrames, void());
MOCK_METHOD0(incrementClientCompositionReusedFrames, void());
MOCK_METHOD0(incrementRefreshRateSwitches, void());
+ MOCK_METHOD0(incrementCompositionStrategyChanges, void());
MOCK_METHOD1(recordDisplayEventConnectionCount, void(int32_t));
MOCK_METHOD2(recordFrameDuration, void(nsecs_t, nsecs_t));
MOCK_METHOD2(recordRenderEngineDuration, void(nsecs_t, nsecs_t));
@@ -52,7 +53,8 @@
MOCK_METHOD3(setPresentFence, void(int32_t, uint64_t, const std::shared_ptr<FenceTime>&));
MOCK_METHOD1(onDestroy, void(int32_t));
MOCK_METHOD2(removeTimeRecord, void(int32_t, uint64_t));
- MOCK_METHOD1(setPowerMode, void(int32_t));
+ MOCK_METHOD1(setPowerMode,
+ void(hardware::graphics::composer::V2_4::IComposerClient::PowerMode));
MOCK_METHOD2(recordRefreshRate, void(uint32_t, nsecs_t));
MOCK_METHOD1(setPresentFenceGlobal, void(const std::shared_ptr<FenceTime>&));
};
diff --git a/services/surfaceflinger/tests/utils/TransactionUtils.h b/services/surfaceflinger/tests/utils/TransactionUtils.h
index 2c63da0..8e1f943 100644
--- a/services/surfaceflinger/tests/utils/TransactionUtils.h
+++ b/services/surfaceflinger/tests/utils/TransactionUtils.h
@@ -17,18 +17,13 @@
#pragma once
#include <chrono>
-#include <gtest/gtest.h>
#include <android/native_window.h>
-#include <hardware/hwcomposer_defs.h>
-
#include <binder/IPCThreadState.h>
-
+#include <gtest/gtest.h>
#include <gui/Surface.h>
#include <gui/SurfaceComposerClient.h>
-
#include <private/gui/ComposerService.h>
-
#include <ui/GraphicBuffer.h>
#include <ui/Rect.h>
diff --git a/vulkan/libvulkan/Android.bp b/vulkan/libvulkan/Android.bp
index 018f200..f69de1f 100644
--- a/vulkan/libvulkan/Android.bp
+++ b/vulkan/libvulkan/Android.bp
@@ -79,6 +79,7 @@
"hwvulkan_headers",
"libnativeloader-headers",
"vulkan_headers",
+ "libsurfaceflinger_headers",
],
export_header_lib_headers: ["vulkan_headers"],
shared_libs: [
@@ -100,6 +101,7 @@
"libnativeloader_lazy",
"libnativewindow",
"android.hardware.graphics.common@1.0",
+ "libSurfaceFlingerProp",
],
static_libs: ["libgrallocusage"],
}
diff --git a/vulkan/libvulkan/driver.cpp b/vulkan/libvulkan/driver.cpp
index a7ec4ae..a5f0c9f 100644
--- a/vulkan/libvulkan/driver.cpp
+++ b/vulkan/libvulkan/driver.cpp
@@ -23,9 +23,10 @@
#include <stdlib.h>
#include <string.h>
+#include <SurfaceFlingerProperties.h>
+#include <android-base/properties.h>
#include <android/dlext.h>
#include <android/hardware/configstore/1.0/ISurfaceFlingerConfigs.h>
-#include <android-base/properties.h>
#include <configstore/Utils.h>
#include <cutils/properties.h>
#include <graphicsenv/GraphicsEnv.h>
@@ -959,9 +960,7 @@
VK_KHR_INCREMENTAL_PRESENT_EXTENSION_NAME,
VK_KHR_INCREMENTAL_PRESENT_SPEC_VERSION});
- bool hdrBoardConfig =
- getBool<ISurfaceFlingerConfigs, &ISurfaceFlingerConfigs::hasHDRDisplay>(
- false);
+ bool hdrBoardConfig = android::sysprop::has_HDR_display(false);
if (hdrBoardConfig) {
loader_extensions.push_back({VK_EXT_HDR_METADATA_EXTENSION_NAME,
VK_EXT_HDR_METADATA_SPEC_VERSION});