Merge "Convert certain format types to another buffer format." into sc-dev
diff --git a/cmds/dumpstate/Android.bp b/cmds/dumpstate/Android.bp
index 80d14ac..34e9a85 100644
--- a/cmds/dumpstate/Android.bp
+++ b/cmds/dumpstate/Android.bp
@@ -112,6 +112,7 @@
],
required: [
"atrace",
+ "dmabuf_dump",
"ip",
"iptables",
"librank",
diff --git a/cmds/dumpstate/dumpstate.cpp b/cmds/dumpstate/dumpstate.cpp
index 4a4a510..990aa53 100644
--- a/cmds/dumpstate/dumpstate.cpp
+++ b/cmds/dumpstate/dumpstate.cpp
@@ -1846,10 +1846,8 @@
RunCommand("IOTOP", {"iotop", "-n", "1", "-m", "100"});
// Gather shared memory buffer info if the product implements it
- struct stat st;
- if (!stat("/product/bin/dmabuf_dump", &st)) {
- RunCommand("Dmabuf dump", {"/product/bin/dmabuf_dump"});
- }
+ RunCommand("Dmabuf dump", {"dmabuf_dump"});
+ RunCommand("Dmabuf per-buffer/per-exporter/per-device stats", {"dmabuf_dump", "-b"});
DumpFile("PSI cpu", "/proc/pressure/cpu");
DumpFile("PSI memory", "/proc/pressure/memory");
diff --git a/cmds/idlcli/Android.bp b/cmds/idlcli/Android.bp
index 643b3ca..72ffc94 100644
--- a/cmds/idlcli/Android.bp
+++ b/cmds/idlcli/Android.bp
@@ -15,7 +15,7 @@
cc_defaults {
name: "idlcli-defaults",
shared_libs: [
- "android.hardware.vibrator-unstable-ndk_platform",
+ "android.hardware.vibrator-V2-ndk_platform",
"android.hardware.vibrator@1.0",
"android.hardware.vibrator@1.1",
"android.hardware.vibrator@1.2",
diff --git a/cmds/installd/Android.bp b/cmds/installd/Android.bp
index 96875d5..cbe857a 100644
--- a/cmds/installd/Android.bp
+++ b/cmds/installd/Android.bp
@@ -38,6 +38,9 @@
"libutils",
"server_configurable_flags",
],
+ export_shared_lib_headers: [
+ "libbinder",
+ ],
product_variables: {
arc: {
diff --git a/cmds/lshal/DebugCommand.cpp b/cmds/lshal/DebugCommand.cpp
index 72958bd..ccf1ab1 100644
--- a/cmds/lshal/DebugCommand.cpp
+++ b/cmds/lshal/DebugCommand.cpp
@@ -28,7 +28,7 @@
}
std::string DebugCommand::getSimpleDescription() const {
- return "Debug a specified HAL.";
+ return "Debug a specified HIDL HAL.";
}
Status DebugCommand::parseArgs(const Arg &arg) {
@@ -78,7 +78,7 @@
"debug:\n"
" lshal debug [-E] <interface> [options [options [...]]] \n"
" Print debug information of a specified interface.\n"
- " -E: excludes debug output if HAL is actually a subclass.\n"
+ " -E: excludes debug output if HIDL HAL is actually a subclass.\n"
" <interface>: Format is `android.hardware.foo@1.0::IFoo/default`.\n"
" If instance name is missing `default` is used.\n"
" options: space separated options to IBase::debug.\n";
diff --git a/cmds/lshal/ListCommand.cpp b/cmds/lshal/ListCommand.cpp
index 22268ac..d5110f6 100644
--- a/cmds/lshal/ListCommand.cpp
+++ b/cmds/lshal/ListCommand.cpp
@@ -81,7 +81,7 @@
return "list";
}
std::string ListCommand::getSimpleDescription() const {
- return "List HALs.";
+ return "List HIDL HALs.";
}
std::string ListCommand::parseCmdline(pid_t pid) const {
@@ -295,21 +295,21 @@
}
mServicesTable.setDescription(
- "| All binderized services (registered with hwservicemanager)");
+ "| All HIDL binderized services (registered with hwservicemanager)");
mPassthroughRefTable.setDescription(
- "| All interfaces that getService() has ever returned as a passthrough interface;\n"
+ "| All HIDL interfaces getService() has ever returned as a passthrough interface;\n"
"| PIDs / processes shown below might be inaccurate because the process\n"
"| might have relinquished the interface or might have died.\n"
"| The Server / Server CMD column can be ignored.\n"
"| The Clients / Clients CMD column shows all process that have ever dlopen'ed \n"
"| the library and successfully fetched the passthrough implementation.");
mImplementationsTable.setDescription(
- "| All available passthrough implementations (all -impl.so files).\n"
+ "| All available HIDL passthrough implementations (all -impl.so files).\n"
"| These may return subclasses through their respective HIDL_FETCH_I* functions.");
mManifestHalsTable.setDescription(
- "| All HALs that are in VINTF manifest.");
+ "| All HIDL HALs that are in VINTF manifest.");
mLazyHalsTable.setDescription(
- "| All HALs that are declared in VINTF manifest:\n"
+ "| All HIDL HALs that are declared in VINTF manifest:\n"
"| - as hwbinder HALs but are not registered to hwservicemanager, and\n"
"| - as hwbinder/passthrough HALs with no implementation.");
}
@@ -903,11 +903,11 @@
thiz->mSelectedColumns.push_back(TableColumnType::VINTF);
return OK;
}, "print VINTF info. This column contains a comma-separated list of:\n"
- " - DM: if the HAL is in the device manifest\n"
- " - DC: if the HAL is in the device compatibility matrix\n"
- " - FM: if the HAL is in the framework manifest\n"
- " - FC: if the HAL is in the framework compatibility matrix\n"
- " - X: if the HAL is in none of the above lists"});
+ " - DM: if the HIDL HAL is in the device manifest\n"
+ " - DC: if the HIDL HAL is in the device compatibility matrix\n"
+ " - FM: if the HIDL HAL is in the framework manifest\n"
+ " - FC: if the HIDL HAL is in the framework compatibility matrix\n"
+ " - X: if the HIDL HAL is in none of the above lists"});
mOptions.push_back({'S', "service-status", no_argument, v++, [](ListCommand* thiz, const char*) {
thiz->mSelectedColumns.push_back(TableColumnType::SERVICE_STATUS);
return OK;
diff --git a/cmds/lshal/Lshal.cpp b/cmds/lshal/Lshal.cpp
index 99cb93a..bc99f4d 100644
--- a/cmds/lshal/Lshal.cpp
+++ b/cmds/lshal/Lshal.cpp
@@ -59,7 +59,8 @@
}
void Lshal::usage() {
- err() << "lshal: List and debug HALs." << std::endl << std::endl
+ err() << "lshal: List and debug HIDL HALs." << std::endl
+ << " (for AIDL HALs, see `dumpsys`)" << std::endl << std::endl
<< "commands:" << std::endl;
size_t nameMaxLength = 0;
diff --git a/cmds/lshal/WaitCommand.cpp b/cmds/lshal/WaitCommand.cpp
index 65b41b9..437a66a 100644
--- a/cmds/lshal/WaitCommand.cpp
+++ b/cmds/lshal/WaitCommand.cpp
@@ -29,7 +29,7 @@
}
std::string WaitCommand::getSimpleDescription() const {
- return "Wait for HAL to start if it is not already started.";
+ return "Wait for HIDL HAL to start if it is not already started.";
}
Status WaitCommand::parseArgs(const Arg &arg) {
diff --git a/libs/binder/Android.bp b/libs/binder/Android.bp
index 2c0cca1..91033e9 100644
--- a/libs/binder/Android.bp
+++ b/libs/binder/Android.bp
@@ -22,11 +22,13 @@
header_libs: [
"libbase_headers",
+ "libbinder_headers_platform_shared",
"libcutils_headers",
"libutils_headers",
],
export_header_lib_headers: [
"libbase_headers",
+ "libbinder_headers_platform_shared",
"libcutils_headers",
"libutils_headers",
],
diff --git a/libs/binder/include/binder/IBinder.h b/libs/binder/include/binder/IBinder.h
index c8fb448..31f63c8 100644
--- a/libs/binder/include/binder/IBinder.h
+++ b/libs/binder/include/binder/IBinder.h
@@ -60,6 +60,15 @@
EXTENSION_TRANSACTION = B_PACK_CHARS('_', 'E', 'X', 'T'),
DEBUG_PID_TRANSACTION = B_PACK_CHARS('_', 'P', 'I', 'D'),
+ // See android.os.IBinder.TWEET_TRANSACTION
+ // Most importantly, messages can be anything not exceeding 130 UTF-8
+ // characters, and callees should exclaim "jolly good message old boy!"
+ TWEET_TRANSACTION = B_PACK_CHARS('_', 'T', 'W', 'T'),
+
+ // See android.os.IBinder.LIKE_TRANSACTION
+ // Improve binder self-esteem.
+ LIKE_TRANSACTION = B_PACK_CHARS('_', 'L', 'I', 'K'),
+
// Corresponds to TF_ONE_WAY -- an asynchronous call.
FLAG_ONEWAY = 0x00000001,
diff --git a/libs/binder/ndk/Android.bp b/libs/binder/ndk/Android.bp
index 82f3882..d76a1f9 100644
--- a/libs/binder/ndk/Android.bp
+++ b/libs/binder/ndk/Android.bp
@@ -129,6 +129,28 @@
],
}
+cc_library_headers {
+ name: "libbinder_headers_platform_shared",
+ export_include_dirs: ["include_cpp"],
+ vendor_available: true,
+ host_supported: true,
+ // TODO(b/153609531): remove when no longer needed.
+ native_bridge_supported: true,
+ target: {
+ darwin: {
+ enabled: false,
+ },
+ },
+ min_sdk_version: "29",
+ apex_available: [
+ "//apex_available:platform",
+ // TODO(b/166468760) remove these three
+ "com.android.media",
+ "com.android.media.swcodec",
+ "test_com.android.media.swcodec",
+ ],
+}
+
ndk_headers {
name: "libbinder_ndk_headers",
from: "include_ndk/android",
diff --git a/libs/binder/ndk/include_cpp/android/binder_to_string.h b/libs/binder/ndk/include_cpp/android/binder_to_string.h
new file mode 100644
index 0000000..bd51b11
--- /dev/null
+++ b/libs/binder/ndk/include_cpp/android/binder_to_string.h
@@ -0,0 +1,184 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * @addtogroup NdkBinder
+ * @{
+ */
+
+/**
+ * @file binder_to_string.h
+ * @brief Helper for parcelable.
+ */
+
+#pragma once
+
+#include <codecvt>
+#include <locale>
+#include <sstream>
+#include <string>
+#include <type_traits>
+
+#if __has_include(<android/binder_ibinder.h>)
+#include <android/binder_auto_utils.h>
+#include <android/binder_interface_utils.h>
+#include <android/binder_parcelable_utils.h>
+#define HAS_NDK_INTERFACE
+#else
+#include <binder/IBinder.h>
+#include <binder/IInterface.h>
+#include <binder/ParcelFileDescriptor.h>
+#include <binder/ParcelableHolder.h>
+#include <utils/String16.h>
+#include <utils/StrongPointer.h>
+#define HAS_CPP_INTERFACE
+#endif //_has_include
+
+namespace android {
+namespace internal {
+
+// ToString is a utility to generate string representation for various AIDL-supported types.
+template <typename _T>
+std::string ToString(const _T& t);
+
+namespace details {
+
+// Truthy if _T has toString() method.
+template <typename _T>
+class HasToStringMethod {
+ template <typename _U>
+ static auto _test(int) -> decltype(std::declval<_U>().toString(), std::true_type());
+ template <typename _U>
+ static std::false_type _test(...);
+
+ public:
+ enum { value = decltype(_test<_T>(0))::value };
+};
+
+// Truthy if _T has a overloaded toString(T)
+template <typename _T>
+class HasToStringFunction {
+ template <typename _U>
+ static auto _test(int) -> decltype(toString(std::declval<_U>()), std::true_type());
+ template <typename _U>
+ static std::false_type _test(...);
+
+ public:
+ enum { value = decltype(_test<_T>(0))::value };
+};
+
+// Truthy if _T is like a pointer
+template <typename _T>
+class IsPointerLike {
+ template <typename _U>
+ static auto _test(int) -> decltype(!std::declval<_U>(), *std::declval<_U>(), std::true_type());
+ template <typename _U>
+ static std::false_type _test(...);
+
+ public:
+ enum { value = decltype(_test<_T>(0))::value };
+};
+
+// Truthy if _T is like a container
+template <typename _T>
+class IsIterable {
+ template <typename _U>
+ static auto _test(int)
+ -> decltype(begin(std::declval<_U>()), end(std::declval<_U>()), std::true_type());
+ template <typename _U>
+ static std::false_type _test(...);
+
+ public:
+ enum { value = decltype(_test<_T>(0))::value };
+};
+
+template <typename _T>
+class ToEmptyString {
+ template <typename _U>
+ static std::enable_if_t<
+#ifdef HAS_NDK_INTERFACE
+ std::is_base_of_v<::ndk::ICInterface, _U> || std::is_same_v<::ndk::SpAIBinder, _U> ||
+ std::is_same_v<::ndk::ScopedFileDescriptor, _U> ||
+ std::is_same_v<::ndk::AParcelableHolder, _U>
+#else
+ std::is_base_of_v<IInterface, _U> || std::is_same_v<IBinder, _U> ||
+ std::is_same_v<os::ParcelFileDescriptor, _U> ||
+ std::is_same_v<os::ParcelableHolder, _U>
+#endif
+ ,
+ std::true_type>
+ _test(int);
+ template <typename _U>
+ static std::false_type _test(...);
+
+ public:
+ enum { value = decltype(_test<_T>(0))::value };
+};
+
+} // namespace details
+
+template <typename _T>
+std::string ToString(const _T& t) {
+ if constexpr (details::ToEmptyString<_T>::value) {
+ return "";
+ } else if constexpr (std::is_same_v<bool, _T>) {
+ return t ? "true" : "false";
+ } else if constexpr (std::is_same_v<char16_t, _T>) {
+ return std::wstring_convert<std::codecvt_utf8_utf16<char16_t>, char16_t>().to_bytes(t);
+ } else if constexpr (std::is_arithmetic_v<_T>) {
+ return std::to_string(t);
+ } else if constexpr (std::is_same_v<std::string, _T>) {
+ return t;
+#ifdef HAS_CPP_INTERFACE
+ } else if constexpr (std::is_same_v<String16, _T>) {
+ std::stringstream out;
+ out << t;
+ return out.str();
+#endif
+ } else if constexpr (details::HasToStringMethod<_T>::value) {
+ return t.toString();
+ } else if constexpr (details::HasToStringFunction<_T>::value) {
+ return toString(t);
+ } else if constexpr (details::IsIterable<_T>::value) {
+ std::stringstream out;
+ bool first = true;
+ out << "[";
+ for (const auto& e : t) {
+ if (first) {
+ first = false;
+ } else {
+ out << ", ";
+ }
+ // Use explicit type parameter in case deref of iterator has different type
+ // e.g. vector<bool>
+ out << ToString<typename _T::value_type>(e);
+ }
+ out << "]";
+ return out.str();
+ } else if constexpr (details::IsPointerLike<_T>::value) {
+ if (!t) return "(null)";
+ std::stringstream out;
+ out << ToString(*t);
+ return out.str();
+ } else {
+ return "{no toString() implemented}";
+ }
+}
+
+} // namespace internal
+} // namespace android
+
+/** @} */
diff --git a/libs/binder/tests/binderLibTest.cpp b/libs/binder/tests/binderLibTest.cpp
index a5261e5..e2193fa 100644
--- a/libs/binder/tests/binderLibTest.cpp
+++ b/libs/binder/tests/binderLibTest.cpp
@@ -21,6 +21,7 @@
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
+#include <thread>
#include <gtest/gtest.h>
@@ -28,6 +29,7 @@
#include <binder/IBinder.h>
#include <binder/IPCThreadState.h>
#include <binder/IServiceManager.h>
+#include <binder/ParcelRef.h>
#include <private/binder/binder_module.h>
#include <linux/sched.h>
@@ -916,6 +918,36 @@
}
}
+TEST_F(BinderLibTest, ParcelAllocatedOnAnotherThread) {
+ sp<IBinder> server = addServer();
+ ASSERT_TRUE(server != nullptr);
+
+ Parcel data;
+ sp<ParcelRef> reply = ParcelRef::create();
+
+ // when we have a Parcel which is deleted on another thread, if it gets
+ // deleted, it will tell the kernel this, and it will drop strong references
+ // to binder, so that we can't BR_ACQUIRE would fail
+ IPCThreadState::self()->createTransactionReference(reply.get());
+ ASSERT_EQ(NO_ERROR, server->transact(BINDER_LIB_TEST_CREATE_BINDER_TRANSACTION,
+ data,
+ reply.get()));
+
+ // we have sp to binder, but it is not actually acquired by kernel, the
+ // transaction is sitting on an out buffer
+ sp<IBinder> binder = reply->readStrongBinder();
+
+ std::thread([&] {
+ // without the transaction reference, this would cause the Parcel to be
+ // deallocated before the first thread flushes BR_ACQUIRE
+ reply = nullptr;
+ IPCThreadState::self()->flushCommands();
+ }).join();
+
+ ASSERT_NE(nullptr, binder);
+ ASSERT_EQ(NO_ERROR, binder->pingBinder());
+}
+
TEST_F(BinderLibTest, CheckNoHeaderMappedInUser) {
status_t ret;
Parcel data, reply;
diff --git a/libs/gralloc/types/Android.bp b/libs/gralloc/types/Android.bp
index 243d7f1..dd0ae30 100644
--- a/libs/gralloc/types/Android.bp
+++ b/libs/gralloc/types/Android.bp
@@ -43,14 +43,14 @@
],
shared_libs: [
- "android.hardware.graphics.common-unstable-ndk_platform",
+ "android.hardware.graphics.common-V2-ndk_platform",
"android.hardware.graphics.mapper@4.0",
"libhidlbase",
"liblog",
],
export_shared_lib_headers: [
- "android.hardware.graphics.common-unstable-ndk_platform",
+ "android.hardware.graphics.common-V2-ndk_platform",
"android.hardware.graphics.mapper@4.0",
"libhidlbase",
],
diff --git a/libs/renderengine/skia/SkiaGLRenderEngine.cpp b/libs/renderengine/skia/SkiaGLRenderEngine.cpp
index 79505ba..dd26b17 100644
--- a/libs/renderengine/skia/SkiaGLRenderEngine.cpp
+++ b/libs/renderengine/skia/SkiaGLRenderEngine.cpp
@@ -33,9 +33,11 @@
#include <SkRegion.h>
#include <SkShadowUtils.h>
#include <SkSurface.h>
+#include <android-base/stringprintf.h>
#include <gl/GrGLInterface.h>
#include <sync/sync.h>
#include <ui/BlurRegion.h>
+#include <ui/DebugUtils.h>
#include <ui/GraphicBuffer.h>
#include <utils/Trace.h>
@@ -59,6 +61,8 @@
namespace renderengine {
namespace skia {
+using base::StringAppendF;
+
static status_t selectConfigForAttribute(EGLDisplay dpy, EGLint const* attrs, EGLint attribute,
EGLint wanted, EGLConfig* outConfig) {
EGLint numConfigs = -1, n = 0;
@@ -1075,6 +1079,53 @@
return value;
}
+void SkiaGLRenderEngine::dump(std::string& result) {
+ const gl::GLExtensions& extensions = gl::GLExtensions::getInstance();
+
+ StringAppendF(&result, "\n ------------RE-----------------\n");
+ StringAppendF(&result, "EGL implementation : %s\n", extensions.getEGLVersion());
+ StringAppendF(&result, "%s\n", extensions.getEGLExtensions());
+ StringAppendF(&result, "GLES: %s, %s, %s\n", extensions.getVendor(), extensions.getRenderer(),
+ extensions.getVersion());
+ StringAppendF(&result, "%s\n", extensions.getExtensions());
+ StringAppendF(&result, "RenderEngine supports protected context: %d\n",
+ supportsProtectedContent());
+ StringAppendF(&result, "RenderEngine is in protected context: %d\n", mInProtectedContext);
+
+ {
+ std::lock_guard<std::mutex> lock(mRenderingMutex);
+ StringAppendF(&result, "RenderEngine texture cache size: %zu\n", mTextureCache.size());
+ StringAppendF(&result, "Dumping buffer ids...\n");
+ // TODO(178539829): It would be nice to know which layer these are coming from and what
+ // the texture sizes are.
+ for (const auto& [id, unused] : mTextureCache) {
+ StringAppendF(&result, "- 0x%" PRIx64 "\n", id);
+ }
+ StringAppendF(&result, "\n");
+ StringAppendF(&result, "RenderEngine protected texture cache size: %zu\n",
+ mProtectedTextureCache.size());
+ StringAppendF(&result, "Dumping buffer ids...\n");
+ for (const auto& [id, unused] : mProtectedTextureCache) {
+ StringAppendF(&result, "- 0x%" PRIx64 "\n", id);
+ }
+ StringAppendF(&result, "\n");
+ StringAppendF(&result, "RenderEngine runtime effects: %zu\n", mRuntimeEffects.size());
+ for (const auto& [linearEffect, unused] : mRuntimeEffects) {
+ StringAppendF(&result, "- inputDataspace: %s\n",
+ dataspaceDetails(
+ static_cast<android_dataspace>(linearEffect.inputDataspace))
+ .c_str());
+ StringAppendF(&result, "- outputDataspace: %s\n",
+ dataspaceDetails(
+ static_cast<android_dataspace>(linearEffect.outputDataspace))
+ .c_str());
+ StringAppendF(&result, "undoPremultipliedAlpha: %s\n",
+ linearEffect.undoPremultipliedAlpha ? "true" : "false");
+ }
+ }
+ StringAppendF(&result, "\n");
+}
+
} // namespace skia
} // namespace renderengine
} // namespace android
diff --git a/libs/renderengine/skia/SkiaGLRenderEngine.h b/libs/renderengine/skia/SkiaGLRenderEngine.h
index 3294de8..810fc2a 100644
--- a/libs/renderengine/skia/SkiaGLRenderEngine.h
+++ b/libs/renderengine/skia/SkiaGLRenderEngine.h
@@ -63,7 +63,7 @@
bool useProtectedContext(bool useProtectedContext) override;
protected:
- void dump(std::string& /*result*/) override{};
+ void dump(std::string& result) override;
size_t getMaxTextureSize() const override;
size_t getMaxViewportDims() const override;
diff --git a/libs/renderengine/skia/debug/record.sh b/libs/renderengine/skia/debug/record.sh
new file mode 100755
index 0000000..bc406d9
--- /dev/null
+++ b/libs/renderengine/skia/debug/record.sh
@@ -0,0 +1,106 @@
+# This script captures MSKP files from RenderEngine in a connected device.
+# this only functions when RenderEngine uses the Skia backend.
+# it triggers code in SkiaCapture.cpp.
+
+# for a newly flashed device, perform first time steps with
+# record.sh rootandsetup
+
+# record all frames that RenderEngine handles over the span of 2 seconds.
+# record.sh 2000
+
+if [ -z "$1" ]; then
+ printf 'Usage:\n record.sh rootandsetup\n'
+ printf ' record.sh MILLISECONDS\n\n'
+ exit 1
+elif [ "$1" == "rootandsetup" ]; then
+ # first time use requires these changes
+ adb root
+ adb shell setenforce 0
+ adb shell setprop debug.renderengine.backend "skiagl"
+ adb shell stop
+ adb shell start
+ exit 1;
+fi
+
+# name of the newest file in /data/user/ before starting
+oldname=$(adb shell ls -cr /data/user/ | head -n 1)
+
+# record frames for some number of milliseconds.
+adb shell setprop debug.renderengine.capture_skia_ms $1
+
+# give the device time to both record, and starting writing the file.
+# Total time needed to write the file depends on how much data was recorded.
+# the loop at the end waits for this.
+sleep $(($1 / 1000 + 2));
+
+# There is no guarantee that at least one frame passed through renderengine during that time
+# but as far as I know it always at least writes a 0-byte file with a new name, unless it crashes
+# the process it is recording.
+# /data/user/re_skiacapture_56204430551705.mskp
+
+# list the files here from newest to oldest, keep only the name of the newest.
+name=$(adb shell ls -cr /data/user/ | head -n 1)
+remote_path=/data/user/$name
+
+if [[ $oldname = $name ]]; then
+ echo "No new file written, probably no RenderEngine activity during recording period."
+ exit 1
+fi
+
+# return the size of a file in bytes
+adb_filesize() {
+ adb shell "wc -c \"$1\"" 2> /dev/null | awk '{print $1}'
+}
+
+mskp_size=$(adb_filesize "/data/user/$name")
+if [[ $mskp_size = "0" ]]; then
+ echo "Empty file, probably no RenderEngine activity during recording period."
+ exit 1
+fi
+
+spin() {
+ case "$spin" in
+ 1) printf '\b|';;
+ 2) printf '\b\\';;
+ 3) printf '\b-';;
+ *) printf '\b/';;
+ esac
+ spin=$(( ( ${spin:-0} + 1 ) % 4 ))
+ sleep $1
+}
+
+printf "MSKP captured, Waiting for file serialization to finish.\n"
+
+local_path=~/Downloads/$name
+
+# wait for the file size to stop changing
+
+timeout=$(( $(date +%s) + 300))
+last_size='0' # output of last size check command
+unstable=true # false once the file size stops changing
+counter=0 # used to perform size check only 1/sec though we update spinner 20/sec
+# loop until the file size is unchanged for 1 second.
+while [ $unstable != 0 ] ; do
+ spin 0.05
+ counter=$(( $counter+1 ))
+ if ! (( $counter % 20)) ; then
+ new_size=$(adb_filesize "$remote_path")
+ unstable=$(($new_size != $last_size))
+ last_size=$new_size
+ fi
+ if [ $(date +%s) -gt $timeout ] ; then
+ printf '\bTimed out.\n'
+ exit 3
+ fi
+done
+printf '\b'
+
+printf "MSKP file serialized: %s\n" $(echo $last_size | numfmt --to=iec)
+
+adb pull "$remote_path" "$local_path"
+if ! [ -f "$local_path" ] ; then
+ printf "something went wrong with `adb pull`."
+ exit 4
+fi
+adb shell rm "$remote_path"
+printf 'SKP saved to %s\n\n' "$local_path"
\ No newline at end of file
diff --git a/libs/ui/Android.bp b/libs/ui/Android.bp
index 7c68aaa..714ee3e 100644
--- a/libs/ui/Android.bp
+++ b/libs/ui/Android.bp
@@ -140,7 +140,7 @@
"android.hardware.graphics.allocator@2.0",
"android.hardware.graphics.allocator@3.0",
"android.hardware.graphics.allocator@4.0",
- "android.hardware.graphics.common-unstable-ndk_platform",
+ "android.hardware.graphics.common-V2-ndk_platform",
"android.hardware.graphics.common@1.2",
"android.hardware.graphics.mapper@2.0",
"android.hardware.graphics.mapper@2.1",
@@ -157,7 +157,7 @@
export_shared_lib_headers: [
"android.hardware.graphics.common@1.2",
- "android.hardware.graphics.common-unstable-ndk_platform",
+ "android.hardware.graphics.common-V2-ndk_platform",
"android.hardware.graphics.mapper@4.0",
"libgralloctypes",
],
diff --git a/libs/ui/PublicFormat.cpp b/libs/ui/PublicFormat.cpp
index a6595cf..78e82da 100644
--- a/libs/ui/PublicFormat.cpp
+++ b/libs/ui/PublicFormat.cpp
@@ -100,6 +100,7 @@
case HAL_PIXEL_FORMAT_RAW12:
case HAL_PIXEL_FORMAT_YCbCr_420_888:
case HAL_PIXEL_FORMAT_YV12:
+ case HAL_PIXEL_FORMAT_YCBCR_P010:
// Enums overlap in both name and value
return static_cast<PublicFormat>(format);
case HAL_PIXEL_FORMAT_RAW16:
diff --git a/libs/ui/include/ui/PublicFormat.h b/libs/ui/include/ui/PublicFormat.h
index 22274a2..aa58805 100644
--- a/libs/ui/include/ui/PublicFormat.h
+++ b/libs/ui/include/ui/PublicFormat.h
@@ -54,6 +54,7 @@
YV12 = 0x32315659,
Y8 = 0x20203859,
Y16 = 0x20363159, // @hide
+ YCBCR_P010 = 0x36,
DEPTH16 = 0x44363159,
DEPTH_JPEG = 0x69656963,
HEIC = 0x48454946,
diff --git a/services/powermanager/Android.bp b/services/powermanager/Android.bp
index b5e6ae9..68f4f28 100644
--- a/services/powermanager/Android.bp
+++ b/services/powermanager/Android.bp
@@ -29,7 +29,7 @@
"libutils",
"android.hardware.power@1.0",
"android.hardware.power@1.1",
- "android.hardware.power-cpp",
+ "android.hardware.power-V1-cpp",
],
cflags: [
diff --git a/services/powermanager/benchmarks/Android.bp b/services/powermanager/benchmarks/Android.bp
index 4c5d508..ad93a65 100644
--- a/services/powermanager/benchmarks/Android.bp
+++ b/services/powermanager/benchmarks/Android.bp
@@ -29,7 +29,7 @@
"libutils",
"android.hardware.power@1.0",
"android.hardware.power@1.1",
- "android.hardware.power-cpp",
+ "android.hardware.power-V1-cpp",
],
static_libs: [
"libtestUtil",
diff --git a/services/powermanager/tests/Android.bp b/services/powermanager/tests/Android.bp
index 49abc11..0f5037e 100644
--- a/services/powermanager/tests/Android.bp
+++ b/services/powermanager/tests/Android.bp
@@ -37,7 +37,7 @@
"libutils",
"android.hardware.power@1.0",
"android.hardware.power@1.1",
- "android.hardware.power-cpp",
+ "android.hardware.power-V1-cpp",
],
static_libs: [
"libgmock",
diff --git a/services/surfaceflinger/Android.bp b/services/surfaceflinger/Android.bp
index a7cd258..825626a 100644
--- a/services/surfaceflinger/Android.bp
+++ b/services/surfaceflinger/Android.bp
@@ -36,7 +36,7 @@
"android.hardware.graphics.composer@2.4",
"android.hardware.power@1.0",
"android.hardware.power@1.3",
- "android.hardware.power-cpp",
+ "android.hardware.power-V1-cpp",
"libbase",
"libbinder",
"libcutils",
diff --git a/services/surfaceflinger/Layer.h b/services/surfaceflinger/Layer.h
index 4b40c8e..3930a81 100644
--- a/services/surfaceflinger/Layer.h
+++ b/services/surfaceflinger/Layer.h
@@ -904,7 +904,6 @@
bool mPendingHWCDestroy{false};
bool backpressureEnabled() { return mDrawingState.flags & layer_state_t::eEnableBackpressure; }
- bool hasPendingBuffer() { return mCurrentState.buffer != mDrawingState.buffer; };
protected:
class SyncPoint {
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index e9b5875..cf7d1e1 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -3291,66 +3291,75 @@
// we must keep a copy of the transactions (specifically the composer
// states) around outside the scope of the lock
std::vector<const TransactionState> transactions;
+ // Layer handles that have transactions with buffers that are ready to be applied.
+ std::unordered_set<sp<IBinder>, ISurfaceComposer::SpHash<IBinder>> pendingBuffers;
{
- Mutex::Autolock _l(mQueueLock);
- // Collect transactions from pending transaction queue.
- auto it = mPendingTransactionQueues.begin();
- while (it != mPendingTransactionQueues.end()) {
- auto& [applyToken, transactionQueue] = *it;
+ Mutex::Autolock _l(mStateLock);
+ {
+ Mutex::Autolock _l(mQueueLock);
+ // Collect transactions from pending transaction queue.
+ auto it = mPendingTransactionQueues.begin();
+ while (it != mPendingTransactionQueues.end()) {
+ auto& [applyToken, transactionQueue] = *it;
- while (!transactionQueue.empty()) {
- const auto& transaction = transactionQueue.front();
+ while (!transactionQueue.empty()) {
+ const auto& transaction = transactionQueue.front();
+ if (!transactionIsReadyToBeApplied(transaction.isAutoTimestamp,
+ transaction.desiredPresentTime,
+ transaction.states,
+ false /* updateTransactionCounters*/,
+ pendingBuffers)) {
+ setTransactionFlags(eTransactionFlushNeeded);
+ break;
+ }
+ transactions.push_back(transaction);
+ transactionQueue.pop();
+ }
+
+ if (transactionQueue.empty()) {
+ it = mPendingTransactionQueues.erase(it);
+ mTransactionQueueCV.broadcast();
+ } else {
+ it = std::next(it, 1);
+ }
+ }
+
+ // Collect transactions from current transaction queue or queue to pending transactions.
+ // Case 1: push to pending when transactionIsReadyToBeApplied is false.
+ // Case 2: push to pending when there exist a pending queue.
+ // Case 3: others are ready to apply.
+ while (!mTransactionQueue.empty()) {
+ const auto& transaction = mTransactionQueue.front();
+ bool pendingTransactions = mPendingTransactionQueues.find(transaction.applyToken) !=
+ mPendingTransactionQueues.end();
+ // Call transactionIsReadyToBeApplied first in case we need to
+ // incrementPendingBufferCount and keep track of pending buffers
+ // if the transaction contains a buffer.
if (!transactionIsReadyToBeApplied(transaction.isAutoTimestamp,
transaction.desiredPresentTime,
- transaction.states)) {
- setTransactionFlags(eTransactionFlushNeeded);
- break;
+ transaction.states,
+ true /* updateTransactionCounters */,
+ pendingBuffers) ||
+ pendingTransactions) {
+ mPendingTransactionQueues[transaction.applyToken].push(transaction);
+ } else {
+ transactions.push_back(transaction);
}
- transactions.push_back(transaction);
- transactionQueue.pop();
- }
-
- if (transactionQueue.empty()) {
- it = mPendingTransactionQueues.erase(it);
- mTransactionQueueCV.broadcast();
- } else {
- it = std::next(it, 1);
+ mTransactionQueue.pop();
}
}
- // Collect transactions from current transaction queue or queue to pending transactions.
- // Case 1: push to pending when transactionIsReadyToBeApplied is false.
- // Case 2: push to pending when there exist a pending queue.
- // Case 3: others are ready to apply.
- while (!mTransactionQueue.empty()) {
- const auto& transaction = mTransactionQueue.front();
- bool pendingTransactions = mPendingTransactionQueues.find(transaction.applyToken) !=
- mPendingTransactionQueues.end();
- // Call transactionIsReadyToBeApplied first in case we need to
- // incrementPendingBufferCount if the transaction contains a buffer.
- if (!transactionIsReadyToBeApplied(transaction.isAutoTimestamp,
- transaction.desiredPresentTime, transaction.states,
- true) ||
- pendingTransactions) {
- mPendingTransactionQueues[transaction.applyToken].push(transaction);
- } else {
- transactions.push_back(transaction);
- }
- mTransactionQueue.pop();
+ // Now apply all transactions.
+ for (const auto& transaction : transactions) {
+ applyTransactionState(transaction.frameTimelineInfo, transaction.states,
+ transaction.displays, transaction.flags,
+ transaction.inputWindowCommands, transaction.desiredPresentTime,
+ transaction.isAutoTimestamp, transaction.buffer,
+ transaction.postTime, transaction.privileged,
+ transaction.hasListenerCallbacks, transaction.listenerCallbacks,
+ transaction.originPid, transaction.originUid, transaction.id);
}
}
-
- // Now apply all transactions.
- Mutex::Autolock _l(mStateLock);
- for (const auto& transaction : transactions) {
- applyTransactionState(transaction.frameTimelineInfo, transaction.states,
- transaction.displays, transaction.flags,
- transaction.inputWindowCommands, transaction.desiredPresentTime,
- transaction.isAutoTimestamp, transaction.buffer, transaction.postTime,
- transaction.privileged, transaction.hasListenerCallbacks,
- transaction.listenerCallbacks, transaction.originPid,
- transaction.originUid, transaction.id);
- }
}
bool SurfaceFlinger::transactionFlushNeeded() {
@@ -3358,9 +3367,10 @@
return !mPendingTransactionQueues.empty();
}
-bool SurfaceFlinger::transactionIsReadyToBeApplied(bool isAutoTimestamp, int64_t desiredPresentTime,
- const Vector<ComposerState>& states,
- bool updateTransactionCounters) {
+bool SurfaceFlinger::transactionIsReadyToBeApplied(
+ bool isAutoTimestamp, int64_t desiredPresentTime, const Vector<ComposerState>& states,
+ bool updateTransactionCounters,
+ std::unordered_set<sp<IBinder>, ISurfaceComposer::SpHash<IBinder>>& pendingBuffers) {
const nsecs_t expectedPresentTime = mExpectedPresentTime.load();
bool ready = true;
// Do not present if the desiredPresentTime has not passed unless it is more than one second
@@ -3379,7 +3389,6 @@
ready = false;
}
- Mutex::Autolock _l(mStateLock);
sp<Layer> layer = nullptr;
if (s.surface) {
layer = fromHandleLocked(s.surface).promote();
@@ -3402,12 +3411,11 @@
// If backpressure is enabled and we already have a buffer to commit, keep the transaction
// in the queue.
- bool hasBuffer = s.what & layer_state_t::eBufferChanged ||
- s.what & layer_state_t::eCachedBufferChanged;
- if (hasBuffer && layer->backpressureEnabled() && layer->hasPendingBuffer() &&
- isAutoTimestamp) {
+ const bool hasPendingBuffer = pendingBuffers.find(s.surface) != pendingBuffers.end();
+ if (layer->backpressureEnabled() && hasPendingBuffer && isAutoTimestamp) {
ready = false;
}
+ pendingBuffers.insert(s.surface);
}
return ready;
}
diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h
index 66fc4f0..400345f 100644
--- a/services/surfaceflinger/SurfaceFlinger.h
+++ b/services/surfaceflinger/SurfaceFlinger.h
@@ -760,9 +760,11 @@
uint32_t setTransactionFlags(uint32_t flags, TransactionSchedule);
void commitTransaction() REQUIRES(mStateLock);
void commitOffscreenLayers();
- bool transactionIsReadyToBeApplied(bool isAutoTimestamp, int64_t desiredPresentTime,
- const Vector<ComposerState>& states,
- bool updateTransactionCounters = false);
+ bool transactionIsReadyToBeApplied(
+ bool isAutoTimestamp, int64_t desiredPresentTime, const Vector<ComposerState>& states,
+ bool updateTransactionCounters,
+ std::unordered_set<sp<IBinder>, ISurfaceComposer::SpHash<IBinder>>& pendingBuffers)
+ REQUIRES(mStateLock);
uint32_t setDisplayStateLocked(const DisplayState& s) REQUIRES(mStateLock);
uint32_t addInputWindowCommands(const InputWindowCommands& inputWindowCommands)
REQUIRES(mStateLock);
diff --git a/services/surfaceflinger/tests/Android.bp b/services/surfaceflinger/tests/Android.bp
index cfaf229..8142aad 100644
--- a/services/surfaceflinger/tests/Android.bp
+++ b/services/surfaceflinger/tests/Android.bp
@@ -49,7 +49,7 @@
"android.hardware.graphics.composer@2.1",
],
shared_libs: [
- "android.hardware.graphics.common-unstable-ndk_platform",
+ "android.hardware.graphics.common-V2-ndk_platform",
"android.hardware.graphics.common@1.2",
"libandroid",
"libbase",
diff --git a/services/surfaceflinger/tests/unittests/Android.bp b/services/surfaceflinger/tests/unittests/Android.bp
index 13b26fc..9b29b70 100644
--- a/services/surfaceflinger/tests/unittests/Android.bp
+++ b/services/surfaceflinger/tests/unittests/Android.bp
@@ -124,7 +124,7 @@
"android.hardware.graphics.allocator@2.0",
"android.hardware.graphics.allocator@3.0",
"android.hardware.graphics.common@1.2",
- "android.hardware.power-cpp",
+ "android.hardware.power-V1-cpp",
"libbase",
"libbinder",
"libcutils",
diff --git a/services/vibratorservice/Android.bp b/services/vibratorservice/Android.bp
index c18bf18..4f89353 100644
--- a/services/vibratorservice/Android.bp
+++ b/services/vibratorservice/Android.bp
@@ -36,7 +36,7 @@
"libhidlbase",
"liblog",
"libutils",
- "android.hardware.vibrator-unstable-cpp",
+ "android.hardware.vibrator-V2-cpp",
"android.hardware.vibrator@1.0",
"android.hardware.vibrator@1.1",
"android.hardware.vibrator@1.2",
diff --git a/services/vibratorservice/benchmarks/Android.bp b/services/vibratorservice/benchmarks/Android.bp
index d3130f4..7b4cc19 100644
--- a/services/vibratorservice/benchmarks/Android.bp
+++ b/services/vibratorservice/benchmarks/Android.bp
@@ -23,7 +23,7 @@
"liblog",
"libutils",
"libvibratorservice",
- "android.hardware.vibrator-unstable-cpp",
+ "android.hardware.vibrator-V2-cpp",
"android.hardware.vibrator@1.0",
"android.hardware.vibrator@1.1",
"android.hardware.vibrator@1.2",
diff --git a/services/vibratorservice/test/Android.bp b/services/vibratorservice/test/Android.bp
index 9af1b7b..ad85990 100644
--- a/services/vibratorservice/test/Android.bp
+++ b/services/vibratorservice/test/Android.bp
@@ -39,7 +39,7 @@
"liblog",
"libvibratorservice",
"libutils",
- "android.hardware.vibrator-unstable-cpp",
+ "android.hardware.vibrator-V2-cpp",
"android.hardware.vibrator@1.0",
"android.hardware.vibrator@1.1",
"android.hardware.vibrator@1.2",
diff --git a/vulkan/libvulkan/swapchain.cpp b/vulkan/libvulkan/swapchain.cpp
index 48090af..cb845a0 100644
--- a/vulkan/libvulkan/swapchain.cpp
+++ b/vulkan/libvulkan/swapchain.cpp
@@ -606,44 +606,9 @@
VKAPI_ATTR
VkResult GetPhysicalDeviceSurfaceSupportKHR(VkPhysicalDevice /*pdev*/,
uint32_t /*queue_family*/,
- VkSurfaceKHR surface_handle,
+ VkSurfaceKHR /*surface_handle*/,
VkBool32* supported) {
- ATRACE_CALL();
-
- const Surface* surface = SurfaceFromHandle(surface_handle);
- if (!surface) {
- return VK_ERROR_SURFACE_LOST_KHR;
- }
- const ANativeWindow* window = surface->window.get();
-
- int query_value;
- int err = window->query(window, NATIVE_WINDOW_FORMAT, &query_value);
- if (err != android::OK || query_value < 0) {
- ALOGE("NATIVE_WINDOW_FORMAT query failed: %s (%d) value=%d",
- strerror(-err), err, query_value);
- return VK_ERROR_SURFACE_LOST_KHR;
- }
-
- android_pixel_format native_format =
- static_cast<android_pixel_format>(query_value);
-
- bool format_supported = false;
- switch (native_format) {
- case HAL_PIXEL_FORMAT_RGBA_8888:
- case HAL_PIXEL_FORMAT_RGB_565:
- case HAL_PIXEL_FORMAT_RGBA_FP16:
- case HAL_PIXEL_FORMAT_RGBA_1010102:
- format_supported = true;
- break;
- default:
- break;
- }
-
- *supported = static_cast<VkBool32>(
- format_supported || (surface->consumer_usage &
- (AHARDWAREBUFFER_USAGE_CPU_READ_MASK |
- AHARDWAREBUFFER_USAGE_CPU_WRITE_MASK)) == 0);
-
+ *supported = VK_TRUE;
return VK_SUCCESS;
}