Merge changes Ia0c2e99d,I68a26ced
* changes:
Always set usage bits for GPU comp in DisplayDevice.
Revert "Revert "Bind to FBO when using GPU composition""
diff --git a/CleanSpec.mk b/CleanSpec.mk
index 1855d26..6a9007c 100644
--- a/CleanSpec.mk
+++ b/CleanSpec.mk
@@ -34,23 +34,21 @@
# made today requires touching the same file, just copy the old
# touch step and add it to the end of the list.
#
-# *****************************************************************
-# NEWER CLEAN STEPS MUST BE AT THE END OF THE LIST ABOVE THE BANNER
-# *****************************************************************
+# ************************************************
+# NEWER CLEAN STEPS MUST BE AT THE END OF THE LIST
+# ************************************************
# For example:
#$(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/APPS/AndroidTests_intermediates)
#$(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/JAVA_LIBRARIES/core_intermediates)
#$(call add-clean-step, find $(OUT_DIR) -type f -name "IGTalkSession*" -print0 | xargs -0 rm -f)
#$(call add-clean-step, rm -rf $(PRODUCT_OUT)/data/*)
+
$(call add-clean-step, find $(PRODUCT_OUT) -type f -name "libdvr.so" -print0 | xargs -0 rm -f)
$(call add-clean-step, rm -rf $(PRODUCT_OUT)/obj/SHARED_LIBRARIES/libdvr_intermediates)
-$(call add-clean-step, rm -rf $(PRODUCT_OUT)/obj/SHARED_LIBRARIES/libdvr_intermediates)
$(call add-clean-step, find $(PRODUCT_OUT) -type f -name "libgui*" -print0 | xargs -0 rm -f)
$(call add-clean-step, rm -rf $(PRODUCT_OUT)/obj/SHARED_LIBRARIES/libgui_intermediates)
-$(call add-clean-step, rm -rf $(PRODUCT_OUT)/obj/SHARED_LIBRARIES/libgui_intermediates)
$(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/bin/thermalserviced)
$(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/etc/init/thermalservice.rc)
-# ******************************************************************
-# NEWER CLEAN STEPS MUST BE AT THE END OF THE LIST ABOVE THIS BANNER
-# ******************************************************************
+$(call add-clean-step, find $(PRODUCT_OUT) -type f -name "gpuservice*" -print0 | xargs -0 rm -f)
+$(call add-clean-step, rm -rf $(PRODUCT_OUT)/obj/EXECUTABLES/gpuservice_intermediates)
diff --git a/cmds/bugreportz/Android.bp b/cmds/bugreportz/Android.bp
new file mode 100644
index 0000000..924a3a3
--- /dev/null
+++ b/cmds/bugreportz/Android.bp
@@ -0,0 +1,44 @@
+// bugreportz
+// ==========
+cc_binary {
+ name: "bugreportz",
+
+ srcs: [
+ "bugreportz.cpp",
+ "main.cpp",
+ ],
+
+ cflags: [
+ "-Werror",
+ "-Wall",
+ ],
+
+ shared_libs: [
+ "libbase",
+ "libcutils",
+ ],
+}
+
+// bugreportz_test
+// ===============
+cc_test {
+ name: "bugreportz_test",
+ test_suites: ["device-tests"],
+
+ cflags: [
+ "-Werror",
+ "-Wall",
+ ],
+
+ srcs: [
+ "bugreportz.cpp",
+ "bugreportz_test.cpp",
+ ],
+
+ static_libs: ["libgmock"],
+
+ shared_libs: [
+ "libbase",
+ "libutils",
+ ],
+}
diff --git a/cmds/bugreportz/Android.mk b/cmds/bugreportz/Android.mk
deleted file mode 100644
index 10dda56..0000000
--- a/cmds/bugreportz/Android.mk
+++ /dev/null
@@ -1,44 +0,0 @@
-LOCAL_PATH:= $(call my-dir)
-
-# bugreportz
-# ==========
-
-include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES:= \
- bugreportz.cpp \
- main.cpp \
-
-LOCAL_MODULE:= bugreportz
-
-LOCAL_CFLAGS := -Werror -Wall
-
-LOCAL_SHARED_LIBRARIES := \
- libbase \
- libcutils \
-
-include $(BUILD_EXECUTABLE)
-
-# bugreportz_test
-# ===============
-
-include $(CLEAR_VARS)
-
-LOCAL_MODULE := bugreportz_test
-LOCAL_COMPATIBILITY_SUITE := device-tests
-LOCAL_MODULE_TAGS := tests
-
-LOCAL_CFLAGS := -Werror -Wall
-
-LOCAL_SRC_FILES := \
- bugreportz.cpp \
- bugreportz_test.cpp \
-
-LOCAL_STATIC_LIBRARIES := \
- libgmock \
-
-LOCAL_SHARED_LIBRARIES := \
- libbase \
- libutils \
-
-include $(BUILD_NATIVE_TEST)
diff --git a/cmds/cmd/Android.bp b/cmds/cmd/Android.bp
new file mode 100644
index 0000000..d91184a
--- /dev/null
+++ b/cmds/cmd/Android.bp
@@ -0,0 +1,18 @@
+cc_binary {
+ name: "cmd",
+
+ srcs: ["cmd.cpp"],
+
+ shared_libs: [
+ "libutils",
+ "liblog",
+ "libselinux",
+ "libbinder",
+ ],
+
+ cflags: [
+ "-Wall",
+ "-Werror",
+ "-DXP_UNIX",
+ ],
+}
diff --git a/cmds/cmd/Android.mk b/cmds/cmd/Android.mk
deleted file mode 100644
index 4868555..0000000
--- a/cmds/cmd/Android.mk
+++ /dev/null
@@ -1,25 +0,0 @@
-LOCAL_PATH:= $(call my-dir)
-include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES:= \
- cmd.cpp
-
-LOCAL_SHARED_LIBRARIES := \
- libutils \
- liblog \
- libselinux \
- libbinder
-
-LOCAL_CFLAGS := -Wall -Werror
-
-LOCAL_C_INCLUDES += \
- $(JNI_H_INCLUDE)
-
-ifeq ($(TARGET_OS),linux)
- LOCAL_CFLAGS += -DXP_UNIX
- #LOCAL_SHARED_LIBRARIES += librt
-endif
-
-LOCAL_MODULE:= cmd
-
-include $(BUILD_EXECUTABLE)
diff --git a/cmds/dumpstate/DumpstateService.cpp b/cmds/dumpstate/DumpstateService.cpp
index 71658d8..0ee6c3a 100644
--- a/cmds/dumpstate/DumpstateService.cpp
+++ b/cmds/dumpstate/DumpstateService.cpp
@@ -24,10 +24,31 @@
#include "DumpstateInternal.h"
+using android::base::StringPrintf;
+
namespace android {
namespace os {
namespace {
+
+static binder::Status exception(uint32_t code, const std::string& msg) {
+ MYLOGE("%s (%d) ", msg.c_str(), code);
+ return binder::Status::fromExceptionCode(code, String8(msg.c_str()));
+}
+
+static binder::Status error(uint32_t code, const std::string& msg) {
+ MYLOGE("%s (%d) ", msg.c_str(), code);
+ return binder::Status::fromServiceSpecificError(code, String8(msg.c_str()));
+}
+
+static void* callAndNotify(void* data) {
+ Dumpstate& ds = *static_cast<Dumpstate*>(data);
+ // TODO(111441001): Return status on listener.
+ ds.Run();
+ MYLOGE("Finished Run()\n");
+ return nullptr;
+}
+
class DumpstateToken : public BnDumpstateToken {};
}
@@ -77,10 +98,30 @@
return binder::Status::ok();
}
-binder::Status DumpstateService::startBugreport(int, const sp<IDumpstateListener>&,
- const DumpstateOptions&, int32_t* returned_id) {
- // TODO: fork to handle the bugreport request and return the process id or a request id here.
+binder::Status DumpstateService::startBugreport(int, int bugreport_mode, int32_t* returned_id) {
+ // TODO(111441001): return a request id here.
*returned_id = -1;
+ MYLOGI("startBugreport() with mode: %d\n", bugreport_mode);
+
+ if (bugreport_mode != Dumpstate::BugreportMode::BUGREPORT_FULL &&
+ bugreport_mode != Dumpstate::BugreportMode::BUGREPORT_INTERACTIVE &&
+ bugreport_mode != Dumpstate::BugreportMode::BUGREPORT_REMOTE &&
+ bugreport_mode != Dumpstate::BugreportMode::BUGREPORT_WEAR &&
+ bugreport_mode != Dumpstate::BugreportMode::BUGREPORT_TELEPHONY &&
+ bugreport_mode != Dumpstate::BugreportMode::BUGREPORT_WIFI) {
+ return exception(binder::Status::EX_ILLEGAL_ARGUMENT,
+ StringPrintf("Invalid bugreport mode: %d", bugreport_mode));
+ }
+
+ std::unique_ptr<Dumpstate::DumpOptions> options = std::make_unique<Dumpstate::DumpOptions>();
+ options->Initialize(static_cast<Dumpstate::BugreportMode>(bugreport_mode));
+ ds_.SetOptions(std::move(options));
+
+ pthread_t thread;
+ status_t err = pthread_create(&thread, nullptr, callAndNotify, &ds_);
+ if (err != 0) {
+ return error(err, "Could not create a background thread.");
+ }
return binder::Status::ok();
}
diff --git a/cmds/dumpstate/DumpstateService.h b/cmds/dumpstate/DumpstateService.h
index 131aff3..58095b3 100644
--- a/cmds/dumpstate/DumpstateService.h
+++ b/cmds/dumpstate/DumpstateService.h
@@ -41,8 +41,7 @@
bool getSectionDetails,
sp<IDumpstateToken>* returned_token) override;
- binder::Status startBugreport(int fd, const sp<IDumpstateListener>& listener,
- const DumpstateOptions& options, int32_t* returned_id) override;
+ binder::Status startBugreport(int fd, int bugreport_mode, int32_t* returned_id) override;
private:
Dumpstate& ds_;
diff --git a/cmds/dumpstate/binder/android/os/IDumpstate.aidl b/cmds/dumpstate/binder/android/os/IDumpstate.aidl
index 68a4f21..9e59f58 100644
--- a/cmds/dumpstate/binder/android/os/IDumpstate.aidl
+++ b/cmds/dumpstate/binder/android/os/IDumpstate.aidl
@@ -39,10 +39,27 @@
IDumpstateToken setListener(@utf8InCpp String name, IDumpstateListener listener,
boolean getSectionDetails);
+ // These modes encapsulate a set of run time options for generating bugreports.
+ // A zipped bugreport; default mode.
+ const int BUGREPORT_MODE_FULL = 0;
+
+ // Interactive bugreport, i.e. triggered by the user.
+ const int BUGREPORT_MODE_INTERACTIVE = 1;
+
+ // Remote bugreport triggered by DevicePolicyManager, for e.g.
+ const int BUGREPORT_MODE_REMOTE = 2;
+
+ // Bugreport triggered on a wear device.
+ const int BUGREPORT_MODE_WEAR = 3;
+
+ // Bugreport limited to only telephony info.
+ const int BUGREPORT_MODE_TELEPHONY = 4;
+
+ // Bugreport limited to only wifi info.
+ const int BUGREPORT_MODE_WIFI = 5;
+
/*
- * Starts a bugreport in a child process.
- *
- * Returns an identifier of the bugreport process running in the background.
+ * Starts a bugreport in the background.
*/
- int startBugreport(int fd, IDumpstateListener listener, in DumpstateOptions options);
+ int startBugreport(int fd, int bugreportMode);
}
diff --git a/cmds/dumpstate/dumpstate.cpp b/cmds/dumpstate/dumpstate.cpp
index 21b0695..72d1de9 100644
--- a/cmds/dumpstate/dumpstate.cpp
+++ b/cmds/dumpstate/dumpstate.cpp
@@ -1940,37 +1940,95 @@
}
}
-// TODO: Move away from system properties when we have options passed via binder calls.
-/* Sets runtime options from the system properties and then clears those properties. */
-static void SetOptionsFromProperties(Dumpstate::DumpOptions* options) {
- options->extra_options = android::base::GetProperty(PROPERTY_EXTRA_OPTIONS, "");
- if (!options->extra_options.empty()) {
- // Framework uses a system property to override some command-line args.
- // Currently, it contains the type of the requested bugreport.
- if (options->extra_options == "bugreportplus") {
+static inline const char* ModeToString(Dumpstate::BugreportMode mode) {
+ switch (mode) {
+ case Dumpstate::BugreportMode::BUGREPORT_FULL:
+ return "BUGREPORT_FULL";
+ case Dumpstate::BugreportMode::BUGREPORT_INTERACTIVE:
+ return "BUGREPORT_INTERACTIVE";
+ case Dumpstate::BugreportMode::BUGREPORT_REMOTE:
+ return "BUGREPORT_REMOTE";
+ case Dumpstate::BugreportMode::BUGREPORT_WEAR:
+ return "BUGREPORT_WEAR";
+ case Dumpstate::BugreportMode::BUGREPORT_TELEPHONY:
+ return "BUGREPORT_TELEPHONY";
+ case Dumpstate::BugreportMode::BUGREPORT_WIFI:
+ return "BUGREPORT_WIFI";
+ }
+}
+
+static void SetOptionsFromMode(Dumpstate::BugreportMode mode, Dumpstate::DumpOptions* options) {
+ switch (mode) {
+ case Dumpstate::BugreportMode::BUGREPORT_FULL:
+ options->do_broadcast = true;
+ options->do_fb = true;
+ break;
+ case Dumpstate::BugreportMode::BUGREPORT_INTERACTIVE:
// Currently, the dumpstate binder is only used by Shell to update progress.
options->do_start_service = true;
options->do_progress_updates = true;
options->do_fb = false;
- } else if (options->extra_options == "bugreportremote") {
+ options->do_broadcast = true;
+ break;
+ case Dumpstate::BugreportMode::BUGREPORT_REMOTE:
options->do_vibrate = false;
options->is_remote_mode = true;
options->do_fb = false;
- } else if (options->extra_options == "bugreportwear") {
+ options->do_broadcast = true;
+ break;
+ case Dumpstate::BugreportMode::BUGREPORT_WEAR:
options->do_start_service = true;
options->do_progress_updates = true;
options->do_zip_file = true;
- } else if (options->extra_options == "bugreporttelephony") {
+ options->do_fb = true;
+ options->do_broadcast = true;
+ break;
+ case Dumpstate::BugreportMode::BUGREPORT_TELEPHONY:
options->telephony_only = true;
- } else if (options->extra_options == "bugreportwifi") {
+ options->do_fb = true;
+ options->do_broadcast = true;
+ break;
+ case Dumpstate::BugreportMode::BUGREPORT_WIFI:
options->wifi_only = true;
options->do_zip_file = true;
+ options->do_fb = true;
+ options->do_broadcast = true;
+ break;
+ }
+}
+
+static Dumpstate::BugreportMode getBugreportModeFromProperty() {
+ // If the system property is not set, it's assumed to be a full bugreport.
+ Dumpstate::BugreportMode mode = Dumpstate::BugreportMode::BUGREPORT_FULL;
+
+ std::string extra_options = android::base::GetProperty(PROPERTY_EXTRA_OPTIONS, "");
+ if (!extra_options.empty()) {
+ // Framework uses a system property to override some command-line args.
+ // Currently, it contains the type of the requested bugreport.
+ if (extra_options == "bugreportplus") {
+ mode = Dumpstate::BugreportMode::BUGREPORT_INTERACTIVE;
+ } else if (extra_options == "bugreportremote") {
+ mode = Dumpstate::BugreportMode::BUGREPORT_REMOTE;
+ } else if (extra_options == "bugreportwear") {
+ mode = Dumpstate::BugreportMode::BUGREPORT_WEAR;
+ } else if (extra_options == "bugreporttelephony") {
+ mode = Dumpstate::BugreportMode::BUGREPORT_TELEPHONY;
+ } else if (extra_options == "bugreportwifi") {
+ mode = Dumpstate::BugreportMode::BUGREPORT_WIFI;
} else {
- MYLOGE("Unknown extra option: %s\n", options->extra_options.c_str());
+ MYLOGE("Unknown extra option: %s\n", extra_options.c_str());
}
// Reset the property
android::base::SetProperty(PROPERTY_EXTRA_OPTIONS, "");
}
+ return mode;
+}
+
+// TODO: Move away from system properties when we have options passed via binder calls.
+/* Sets runtime options from the system properties and then clears those properties. */
+static void SetOptionsFromProperties(Dumpstate::DumpOptions* options) {
+ Dumpstate::BugreportMode mode = getBugreportModeFromProperty();
+ SetOptionsFromMode(mode, options);
options->notification_title = android::base::GetProperty(PROPERTY_EXTRA_TITLE, "");
if (!options->notification_title.empty()) {
@@ -1988,6 +2046,40 @@
}
}
+static void LogDumpOptions(const Dumpstate::DumpOptions& options) {
+ MYLOGI("do_zip_file: %d\n", options.do_zip_file);
+ MYLOGI("do_add_date: %d\n", options.do_add_date);
+ MYLOGI("do_vibrate: %d\n", options.do_vibrate);
+ MYLOGI("use_socket: %d\n", options.use_socket);
+ MYLOGI("use_control_socket: %d\n", options.use_control_socket);
+ MYLOGI("do_fb: %d\n", options.do_fb);
+ MYLOGI("do_broadcast: %d\n", options.do_broadcast);
+ MYLOGI("is_remote_mode: %d\n", options.is_remote_mode);
+ MYLOGI("show_header_only: %d\n", options.show_header_only);
+ MYLOGI("do_start_service: %d\n", options.do_start_service);
+ MYLOGI("telephony_only: %d\n", options.telephony_only);
+ MYLOGI("wifi_only: %d\n", options.wifi_only);
+ MYLOGI("do_progress_updates: %d\n", options.do_progress_updates);
+ MYLOGI("use_outfile: %s\n", options.use_outfile.c_str());
+ MYLOGI("extra_options: %s\n", options.extra_options.c_str());
+ MYLOGI("args: %s\n", options.args.c_str());
+ MYLOGI("notification_title: %s\n", options.notification_title.c_str());
+ MYLOGI("notification_description: %s\n", options.notification_description.c_str());
+}
+
+void Dumpstate::DumpOptions::Initialize(BugreportMode bugreport_mode) {
+ // In the new API world, date is always added; output is always a zip file.
+ // TODO(111441001): remove these options once they are obsolete.
+ do_add_date = true;
+ do_zip_file = true;
+
+ // STOPSHIP b/111441001: Remove hardcoded output file path; accept fd.
+ use_outfile = "/data/user_de/0/com.android.shell/files/bugreports/bugreport";
+
+ extra_options = ModeToString(bugreport_mode);
+ SetOptionsFromMode(bugreport_mode, this);
+}
+
Dumpstate::RunStatus Dumpstate::DumpOptions::Initialize(int argc, char* argv[]) {
RunStatus status = RunStatus::OK;
int c;
@@ -2052,11 +2144,16 @@
return true;
}
-Dumpstate::RunStatus Dumpstate::RunWithOptions(std::unique_ptr<DumpOptions> options) {
- if (!options->ValidateOptions()) {
+void Dumpstate::SetOptions(std::unique_ptr<DumpOptions> options) {
+ options_ = std::move(options);
+}
+
+Dumpstate::RunStatus Dumpstate::Run() {
+ if (!options_->ValidateOptions()) {
+ MYLOGE("Invalid options specified\n");
+ LogDumpOptions(*options_);
return RunStatus::INVALID_INPUT;
}
- options_ = std::move(options);
/* set as high priority, and protect from OOM killer */
setpriority(PRIO_PROCESS, 0, -20);
@@ -2278,7 +2375,8 @@
std::unique_ptr<Dumpstate::DumpOptions> options = std::make_unique<Dumpstate::DumpOptions>();
Dumpstate::RunStatus status = options->Initialize(argc, argv);
if (status == Dumpstate::RunStatus::OK) {
- status = ds.RunWithOptions(std::move(options));
+ ds.SetOptions(std::move(options));
+ status = ds.Run();
}
switch (status) {
diff --git a/cmds/dumpstate/dumpstate.h b/cmds/dumpstate/dumpstate.h
index c2f7f6a..5e7f71d 100644
--- a/cmds/dumpstate/dumpstate.h
+++ b/cmds/dumpstate/dumpstate.h
@@ -27,6 +27,7 @@
#include <android-base/macros.h>
#include <android-base/unique_fd.h>
+#include <android/os/IDumpstate.h>
#include <android/os/IDumpstateListener.h>
#include <utils/StrongPointer.h>
#include <ziparchive/zip_writer.h>
@@ -42,6 +43,9 @@
// TODO: and then remove explicitly android::os::dumpstate:: prefixes
namespace android {
namespace os {
+
+struct DumpstateOptions;
+
namespace dumpstate {
class DumpstateTest;
@@ -185,6 +189,16 @@
public:
enum RunStatus { OK, HELP, INVALID_INPUT, ERROR };
+ // The mode under which the bugreport should be run. Each mode encapsulates a few options.
+ enum BugreportMode {
+ BUGREPORT_FULL = android::os::IDumpstate::BUGREPORT_MODE_FULL,
+ BUGREPORT_INTERACTIVE = android::os::IDumpstate::BUGREPORT_MODE_INTERACTIVE,
+ BUGREPORT_REMOTE = android::os::IDumpstate::BUGREPORT_MODE_REMOTE,
+ BUGREPORT_WEAR = android::os::IDumpstate::BUGREPORT_MODE_WEAR,
+ BUGREPORT_TELEPHONY = android::os::IDumpstate::BUGREPORT_MODE_TELEPHONY,
+ BUGREPORT_WIFI = android::os::IDumpstate::BUGREPORT_MODE_WIFI
+ };
+
static android::os::dumpstate::CommandOptions DEFAULT_DUMPSYS;
static Dumpstate& GetInstance();
@@ -294,8 +308,11 @@
struct DumpOptions;
- /* Main entry point for running a complete bugreport. Takes ownership of options. */
- RunStatus RunWithOptions(std::unique_ptr<DumpOptions> options);
+ /* Main entry point for running a complete bugreport. */
+ RunStatus Run();
+
+ /* Sets runtime options. */
+ void SetOptions(std::unique_ptr<DumpOptions> options);
// TODO: add other options from DumpState.
/*
@@ -317,6 +334,7 @@
// Whether progress updates should be published.
bool do_progress_updates = false;
std::string use_outfile;
+ // TODO: rename to MODE.
// Extra options passed as system property.
std::string extra_options;
// Command-line arguments as string
@@ -328,6 +346,9 @@
/* Initializes options from commandline arguments and system properties. */
RunStatus Initialize(int argc, char* argv[]);
+ /* Initializes options from the requested mode. */
+ void Initialize(BugreportMode bugreport_mode);
+
/* Returns true if the options set so far are consistent. */
bool ValidateOptions() const;
};
diff --git a/cmds/dumpstate/tests/dumpstate_test.cpp b/cmds/dumpstate/tests/dumpstate_test.cpp
index 2cb9800..9ca894d 100644
--- a/cmds/dumpstate/tests/dumpstate_test.cpp
+++ b/cmds/dumpstate/tests/dumpstate_test.cpp
@@ -159,10 +159,11 @@
};
// clang-format on
- Dumpstate::DumpOptions options;
Dumpstate::RunStatus status = options_.Initialize(ARRAY_SIZE(argv), argv);
EXPECT_EQ(status, Dumpstate::RunStatus::OK);
+
+ // These correspond to bugreport_mode = full, because that's the default.
EXPECT_FALSE(options_.do_add_date);
EXPECT_FALSE(options_.do_zip_file);
EXPECT_EQ("", options_.use_outfile);
@@ -170,10 +171,10 @@
EXPECT_FALSE(options_.use_control_socket);
EXPECT_FALSE(options_.show_header_only);
EXPECT_TRUE(options_.do_vibrate);
- EXPECT_FALSE(options_.do_fb);
+ EXPECT_TRUE(options_.do_fb);
EXPECT_FALSE(options_.do_progress_updates);
EXPECT_FALSE(options_.is_remote_mode);
- EXPECT_FALSE(options_.do_broadcast);
+ EXPECT_TRUE(options_.do_broadcast);
}
TEST_F(DumpOptionsTest, InitializePartial1) {
@@ -202,10 +203,10 @@
// Other options retain default values
EXPECT_FALSE(options_.show_header_only);
EXPECT_TRUE(options_.do_vibrate);
- EXPECT_FALSE(options_.do_fb);
+ EXPECT_TRUE(options_.do_fb);
EXPECT_FALSE(options_.do_progress_updates);
EXPECT_FALSE(options_.is_remote_mode);
- EXPECT_FALSE(options_.do_broadcast);
+ EXPECT_TRUE(options_.do_broadcast);
}
TEST_F(DumpOptionsTest, InitializePartial2) {
diff --git a/cmds/dumpstate/utils.cpp b/cmds/dumpstate/utils.cpp
index 4ad5c4b..6cbb691 100644
--- a/cmds/dumpstate/utils.cpp
+++ b/cmds/dumpstate/utils.cpp
@@ -82,8 +82,12 @@
CommandOptions Dumpstate::DEFAULT_DUMPSYS = CommandOptions::WithTimeout(30).Build();
+// TODO(111441001): Default DumpOptions to sensible values.
Dumpstate::Dumpstate(const std::string& version)
- : pid_(getpid()), version_(version), now_(time(nullptr)) {
+ : pid_(getpid()),
+ options_(new Dumpstate::DumpOptions()),
+ version_(version),
+ now_(time(nullptr)) {
}
Dumpstate& Dumpstate::GetInstance() {
diff --git a/libs/binder/IPCThreadState.cpp b/libs/binder/IPCThreadState.cpp
index 7a47724..f0c21f5 100644
--- a/libs/binder/IPCThreadState.cpp
+++ b/libs/binder/IPCThreadState.cpp
@@ -387,23 +387,28 @@
return mStrictModePolicy;
}
-uid_t IPCThreadState::setWorkSource(uid_t uid)
+int64_t IPCThreadState::setCallingWorkSourceUid(uid_t uid)
{
- uid_t returnValue = mWorkSource;
+ // Note: we currently only use half of the int64. We return an int64 for extensibility.
+ int64_t token = mWorkSource;
mWorkSource = uid;
- return returnValue;
+ return token;
}
-uid_t IPCThreadState::getWorkSource() const
+uid_t IPCThreadState::getCallingWorkSourceUid() const
{
return mWorkSource;
}
-uid_t IPCThreadState::clearWorkSource()
+int64_t IPCThreadState::clearCallingWorkSource()
{
- uid_t returnValue = mWorkSource;
- mWorkSource = kUnsetWorkSource;
- return returnValue;
+ return setCallingWorkSourceUid(kUnsetWorkSource);
+}
+
+void IPCThreadState::restoreCallingWorkSource(int64_t token)
+{
+ uid_t uid = (int)token;
+ setCallingWorkSourceUid(uid);
}
void IPCThreadState::setLastTransactionBinderFlags(int32_t flags)
diff --git a/libs/binder/Parcel.cpp b/libs/binder/Parcel.cpp
index 532f7f1..643f428 100644
--- a/libs/binder/Parcel.cpp
+++ b/libs/binder/Parcel.cpp
@@ -601,7 +601,7 @@
{
writeInt32(IPCThreadState::self()->getStrictModePolicy() |
STRICT_MODE_PENALTY_GATHER);
- writeInt32(IPCThreadState::self()->getWorkSource());
+ writeInt32(IPCThreadState::self()->getCallingWorkSourceUid());
// currently the interface identification token is just its name as a string
return writeString16(interface);
}
@@ -631,7 +631,7 @@
}
// WorkSource.
int32_t workSource = readInt32();
- threadState->setWorkSource(workSource);
+ threadState->setCallingWorkSourceUid(workSource);
// Interface descriptor.
const String16 str(readString16());
if (str == interface) {
diff --git a/libs/binder/include/binder/IPCThreadState.h b/libs/binder/include/binder/IPCThreadState.h
index 5888e14..de126d5 100644
--- a/libs/binder/include/binder/IPCThreadState.h
+++ b/libs/binder/include/binder/IPCThreadState.h
@@ -47,12 +47,14 @@
void setStrictModePolicy(int32_t policy);
int32_t getStrictModePolicy() const;
- // See Binder#setThreadWorkSource in Binder.java.
- uid_t setWorkSource(uid_t uid);
- // See Binder#getThreadWorkSource in Binder.java.
- uid_t getWorkSource() const;
- // See Binder#clearThreadWorkSource in Binder.java.
- uid_t clearWorkSource();
+ // See Binder#setCallingWorkSourceUid in Binder.java.
+ int64_t setCallingWorkSourceUid(uid_t uid);
+ // See Binder#getCallingWorkSourceUid in Binder.java.
+ uid_t getCallingWorkSourceUid() const;
+ // See Binder#clearCallingWorkSource in Binder.java.
+ int64_t clearCallingWorkSource();
+ // See Binder#restoreCallingWorkSource in Binder.java.
+ void restoreCallingWorkSource(int64_t token);
void setLastTransactionBinderFlags(int32_t flags);
int32_t getLastTransactionBinderFlags() const;
diff --git a/libs/binder/ndk/include_ndk/android/binder_parcel.h b/libs/binder/ndk/include_ndk/android/binder_parcel.h
index b021c23..3594349 100644
--- a/libs/binder/ndk/include_ndk/android/binder_parcel.h
+++ b/libs/binder/ndk/include_ndk/android/binder_parcel.h
@@ -347,7 +347,7 @@
* This corresponds to the SDK's android.os.ParcelFileDescriptor.
*
* \param parcel the parcel to write to.
- * \param fd the value to write to the parcel.
+ * \param fd the value to write to the parcel (-1 to represent a null ParcelFileDescriptor).
*
* \return STATUS_OK on successful write.
*/
@@ -361,7 +361,8 @@
* This corresponds to the SDK's android.os.ParcelFileDescriptor.
*
* \param parcel the parcel to read from.
- * \param binder the out parameter for what is read from the parcel.
+ * \param fd the out parameter for what is read from the parcel (or -1 to represent a null
+ * ParcelFileDescriptor)
*
* \return STATUS_OK on successful write.
*/
diff --git a/libs/binder/ndk/include_ndk/android/binder_parcel_utils.h b/libs/binder/ndk/include_ndk/android/binder_parcel_utils.h
index a478ee0..f99c3a9 100644
--- a/libs/binder/ndk/include_ndk/android/binder_parcel_utils.h
+++ b/libs/binder/ndk/include_ndk/android/binder_parcel_utils.h
@@ -26,6 +26,7 @@
#pragma once
+#include <android/binder_auto_utils.h>
#include <android/binder_parcel.h>
#include <optional>
@@ -152,28 +153,103 @@
}
/**
+ * Convenience method to write a nullable strong binder.
+ */
+static inline binder_status_t AParcel_writeNullableStrongBinder(AParcel* parcel,
+ const SpAIBinder& binder) {
+ return AParcel_writeStrongBinder(parcel, binder.get());
+}
+
+/**
+ * Convenience method to read a nullable strong binder.
+ */
+static inline binder_status_t AParcel_readNullableStrongBinder(const AParcel* parcel,
+ SpAIBinder* binder) {
+ AIBinder* readBinder;
+ binder_status_t status = AParcel_readStrongBinder(parcel, &readBinder);
+ if (status == STATUS_OK) {
+ binder->set(readBinder);
+ }
+ return status;
+}
+
+/**
* Convenience method to write a strong binder but return an error if it is null.
*/
-static inline binder_status_t AParcel_writeRequiredStrongBinder(AParcel* parcel, AIBinder* binder) {
- if (binder == nullptr) {
+static inline binder_status_t AParcel_writeRequiredStrongBinder(AParcel* parcel,
+ const SpAIBinder& binder) {
+ if (binder.get() == nullptr) {
return STATUS_UNEXPECTED_NULL;
}
- return AParcel_writeStrongBinder(parcel, binder);
+ return AParcel_writeStrongBinder(parcel, binder.get());
}
/**
* Convenience method to read a strong binder but return an error if it is null.
*/
static inline binder_status_t AParcel_readRequiredStrongBinder(const AParcel* parcel,
- AIBinder** binder) {
- binder_status_t ret = AParcel_readStrongBinder(parcel, binder);
- if (ret == STATUS_OK && *binder == nullptr) {
- return STATUS_UNEXPECTED_NULL;
+ SpAIBinder* binder) {
+ AIBinder* readBinder;
+ binder_status_t ret = AParcel_readStrongBinder(parcel, &readBinder);
+ if (ret == STATUS_OK) {
+ if (readBinder == nullptr) {
+ return STATUS_UNEXPECTED_NULL;
+ }
+
+ binder->set(readBinder);
}
return ret;
}
/**
+ * Convenience method to write a ParcelFileDescriptor where -1 represents a null value.
+ */
+static inline binder_status_t AParcel_writeNullableParcelFileDescriptor(
+ AParcel* parcel, const ScopedFileDescriptor& fd) {
+ return AParcel_writeParcelFileDescriptor(parcel, fd.get());
+}
+
+/**
+ * Convenience method to read a ParcelFileDescriptor where -1 represents a null value.
+ */
+static inline binder_status_t AParcel_readNullableParcelFileDescriptor(const AParcel* parcel,
+ ScopedFileDescriptor* fd) {
+ int readFd;
+ binder_status_t status = AParcel_readParcelFileDescriptor(parcel, &readFd);
+ if (status == STATUS_OK) {
+ fd->set(readFd);
+ }
+ return status;
+}
+
+/**
+ * Convenience method to write a valid ParcelFileDescriptor.
+ */
+static inline binder_status_t AParcel_writeRequiredParcelFileDescriptor(
+ AParcel* parcel, const ScopedFileDescriptor& fd) {
+ if (fd.get() < 0) {
+ return STATUS_UNEXPECTED_NULL;
+ }
+ return AParcel_writeParcelFileDescriptor(parcel, fd.get());
+}
+
+/**
+ * Convenience method to read a valid ParcelFileDescriptor.
+ */
+static inline binder_status_t AParcel_readRequiredParcelFileDescriptor(const AParcel* parcel,
+ ScopedFileDescriptor* fd) {
+ int readFd;
+ binder_status_t status = AParcel_readParcelFileDescriptor(parcel, &readFd);
+ if (status == STATUS_OK) {
+ if (readFd < 0) {
+ return STATUS_UNEXPECTED_NULL;
+ }
+ fd->set(readFd);
+ }
+ return status;
+}
+
+/**
* Allocates a std::string to length and returns the underlying buffer. For use with
* AParcel_readString. See use below in AParcel_readString(const AParcel*, std::string*).
*/
diff --git a/libs/binder/ndk/parcel.cpp b/libs/binder/ndk/parcel.cpp
index b1a2955..3c32100 100644
--- a/libs/binder/ndk/parcel.cpp
+++ b/libs/binder/ndk/parcel.cpp
@@ -229,23 +229,39 @@
}
binder_status_t AParcel_writeParcelFileDescriptor(AParcel* parcel, int fd) {
- ParcelFileDescriptor parcelFd((unique_fd(fd)));
+ std::unique_ptr<ParcelFileDescriptor> parcelFd;
- status_t status = parcel->get()->writeParcelable(parcelFd);
+ if (fd < 0) {
+ if (fd != -1) {
+ return STATUS_UNKNOWN_ERROR;
+ }
+ // parcelFd = nullptr
+ } else { // fd >= 0
+ parcelFd = std::make_unique<ParcelFileDescriptor>(unique_fd(fd));
+ }
+
+ status_t status = parcel->get()->writeNullableParcelable(parcelFd);
// ownership is retained by caller
- (void)parcelFd.release().release();
+ if (parcelFd != nullptr) {
+ (void)parcelFd->release().release();
+ }
return PruneStatusT(status);
}
binder_status_t AParcel_readParcelFileDescriptor(const AParcel* parcel, int* fd) {
- ParcelFileDescriptor parcelFd;
- // status_t status = parcelFd.readFromParcel(parcel->get());
+ std::unique_ptr<ParcelFileDescriptor> parcelFd;
+
status_t status = parcel->get()->readParcelable(&parcelFd);
if (status != STATUS_OK) return PruneStatusT(status);
- *fd = parcelFd.release().release();
+ if (parcelFd) {
+ *fd = parcelFd->release().release();
+ } else {
+ *fd = -1;
+ }
+
return STATUS_OK;
}
diff --git a/libs/binder/tests/binderLibTest.cpp b/libs/binder/tests/binderLibTest.cpp
index 7bcfffd..22c1bad 100644
--- a/libs/binder/tests/binderLibTest.cpp
+++ b/libs/binder/tests/binderLibTest.cpp
@@ -953,7 +953,7 @@
{
status_t ret;
Parcel data, reply;
- uid_t previousWorkSource = IPCThreadState::self()->setWorkSource(100);
+ int64_t previousWorkSource = IPCThreadState::self()->setCallingWorkSourceUid(100);
data.writeInterfaceToken(binderLibTestServiceName);
ret = m_server->transact(BINDER_LIB_TEST_GET_WORK_SOURCE_TRANSACTION, data, &reply);
EXPECT_EQ(100, reply.readInt32());
@@ -966,8 +966,8 @@
status_t ret;
Parcel data, reply;
- IPCThreadState::self()->setWorkSource(100);
- uid_t previousWorkSource = IPCThreadState::self()->clearWorkSource();
+ IPCThreadState::self()->setCallingWorkSourceUid(100);
+ int64_t previousWorkSource = IPCThreadState::self()->clearCallingWorkSource();
data.writeInterfaceToken(binderLibTestServiceName);
ret = m_server->transact(BINDER_LIB_TEST_GET_WORK_SOURCE_TRANSACTION, data, &reply);
@@ -976,6 +976,22 @@
EXPECT_EQ(NO_ERROR, ret);
}
+TEST_F(BinderLibTest, WorkSourceRestored)
+{
+ status_t ret;
+ Parcel data, reply;
+
+ IPCThreadState::self()->setCallingWorkSourceUid(100);
+ int64_t token = IPCThreadState::self()->clearCallingWorkSource();
+ IPCThreadState::self()->restoreCallingWorkSource(token);
+
+ data.writeInterfaceToken(binderLibTestServiceName);
+ ret = m_server->transact(BINDER_LIB_TEST_GET_WORK_SOURCE_TRANSACTION, data, &reply);
+
+ EXPECT_EQ(100, reply.readInt32());
+ EXPECT_EQ(NO_ERROR, ret);
+}
+
class BinderLibTestService : public BBinder
{
public:
@@ -1276,7 +1292,7 @@
}
case BINDER_LIB_TEST_GET_WORK_SOURCE_TRANSACTION: {
data.enforceInterface(binderLibTestServiceName);
- reply->writeInt32(IPCThreadState::self()->getWorkSource());
+ reply->writeInt32(IPCThreadState::self()->getCallingWorkSourceUid());
return NO_ERROR;
}
default:
diff --git a/services/bufferhub/Android.bp b/services/bufferhub/Android.bp
index 8b43333..28a7501 100644
--- a/services/bufferhub/Android.bp
+++ b/services/bufferhub/Android.bp
@@ -25,6 +25,7 @@
"BufferClient.cpp",
"BufferHubService.cpp",
"BufferNode.cpp",
+ "UniqueIdGenerator.cpp",
],
header_libs: [
"libbufferhub_headers",
diff --git a/services/bufferhub/BufferHubService.cpp b/services/bufferhub/BufferHubService.cpp
index 3bfd9cb..fc5ad1d 100644
--- a/services/bufferhub/BufferHubService.cpp
+++ b/services/bufferhub/BufferHubService.cpp
@@ -35,7 +35,7 @@
std::shared_ptr<BufferNode> node =
std::make_shared<BufferNode>(desc.width, desc.height, desc.layers, desc.format,
- desc.usage, userMetadataSize);
+ desc.usage, userMetadataSize, nodeIdGenerator.getId());
if (node == nullptr || !node->IsValid()) {
ALOGE("%s: creating BufferNode failed.", __FUNCTION__);
_hidl_cb(/*bufferClient=*/nullptr, /*status=*/BufferHubStatus::ALLOCATION_FAILED);
diff --git a/services/bufferhub/BufferNode.cpp b/services/bufferhub/BufferNode.cpp
index 53dd702..715d0a1 100644
--- a/services/bufferhub/BufferNode.cpp
+++ b/services/bufferhub/BufferNode.cpp
@@ -1,5 +1,6 @@
#include <errno.h>
+#include <bufferhub/BufferHubService.h>
#include <bufferhub/BufferNode.h>
#include <private/dvr/buffer_hub_defs.h>
#include <ui/GraphicBufferAllocator.h>
@@ -22,7 +23,8 @@
// Allocates a new BufferNode.
BufferNode::BufferNode(uint32_t width, uint32_t height, uint32_t layer_count, uint32_t format,
- uint64_t usage, size_t user_metadata_size) {
+ uint64_t usage, size_t user_metadata_size, uint32_t id)
+ : mId(id) {
uint32_t out_stride = 0;
// graphicBufferId is not used in GraphicBufferAllocator::allocate
// TODO(b/112338294) After move to the service folder, stop using the
@@ -54,14 +56,23 @@
InitializeMetadata();
}
-// Free the handle
BufferNode::~BufferNode() {
+ // Free the handle
if (buffer_handle_ != nullptr) {
status_t ret = GraphicBufferAllocator::get().free(buffer_handle_);
if (ret != OK) {
ALOGE("%s: Failed to free handle; Got error: %d", __FUNCTION__, ret);
}
}
+
+ // Free the id, if valid
+ if (id() != UniqueIdGenerator::kInvalidId) {
+ if (nodeIdGenerator.freeId(id())) {
+ ALOGI("%s: id #%u is freed.", __FUNCTION__, id());
+ } else {
+ ALOGE("%s: Cannot free nonexistent id #%u", __FUNCTION__, id());
+ }
+ }
}
uint64_t BufferNode::GetActiveClientsBitMask() const {
diff --git a/services/bufferhub/UniqueIdGenerator.cpp b/services/bufferhub/UniqueIdGenerator.cpp
new file mode 100644
index 0000000..362a026
--- /dev/null
+++ b/services/bufferhub/UniqueIdGenerator.cpp
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <bufferhub/UniqueIdGenerator.h>
+
+namespace android {
+namespace frameworks {
+namespace bufferhub {
+namespace V1_0 {
+namespace implementation {
+
+constexpr uint32_t UniqueIdGenerator::kInvalidId;
+
+uint32_t UniqueIdGenerator::getId() {
+ std::lock_guard<std::mutex> lock(mIdsInUseMutex);
+
+ do {
+ if (++mLastId >= std::numeric_limits<uint32_t>::max()) {
+ mLastId = kInvalidId + 1;
+ }
+ } while (mIdsInUse.find(mLastId) != mIdsInUse.end());
+
+ mIdsInUse.insert(mLastId);
+ return mLastId;
+}
+
+bool UniqueIdGenerator::freeId(uint32_t id) {
+ std::lock_guard<std::mutex> lock(mIdsInUseMutex);
+ auto iter = mIdsInUse.find(id);
+ if (iter != mIdsInUse.end()) {
+ mIdsInUse.erase(iter);
+ return true;
+ }
+
+ return false;
+}
+
+} // namespace implementation
+} // namespace V1_0
+} // namespace bufferhub
+} // namespace frameworks
+} // namespace android
diff --git a/services/bufferhub/include/bufferhub/BufferHubService.h b/services/bufferhub/include/bufferhub/BufferHubService.h
index dbbee8f..5441750 100644
--- a/services/bufferhub/include/bufferhub/BufferHubService.h
+++ b/services/bufferhub/include/bufferhub/BufferHubService.h
@@ -22,6 +22,7 @@
#include <android/frameworks/bufferhub/1.0/IBufferHub.h>
#include <bufferhub/BufferClient.h>
+#include <bufferhub/UniqueIdGenerator.h>
#include <utils/Mutex.h>
namespace android {
@@ -34,6 +35,8 @@
using hardware::Return;
using hardware::graphics::common::V1_2::HardwareBufferDescription;
+static UniqueIdGenerator nodeIdGenerator;
+
class BufferHubService : public IBufferHub {
public:
Return<void> allocateBuffer(const HardwareBufferDescription& description,
diff --git a/services/bufferhub/include/bufferhub/BufferNode.h b/services/bufferhub/include/bufferhub/BufferNode.h
index ffeacac..c490e7c 100644
--- a/services/bufferhub/include/bufferhub/BufferNode.h
+++ b/services/bufferhub/include/bufferhub/BufferNode.h
@@ -2,6 +2,7 @@
#define ANDROID_FRAMEWORKS_BUFFERHUB_V1_0_BUFFER_NODE_H_
#include <android/hardware_buffer.h>
+#include <bufferhub/UniqueIdGenerator.h>
#include <ui/BufferHubMetadata.h>
namespace android {
@@ -14,13 +15,16 @@
public:
// Allocates a new BufferNode.
BufferNode(uint32_t width, uint32_t height, uint32_t layer_count, uint32_t format,
- uint64_t usage, size_t user_metadata_size);
+ uint64_t usage, size_t user_metadata_size,
+ uint32_t id = UniqueIdGenerator::kInvalidId);
~BufferNode();
// Returns whether the object holds a valid metadata.
bool IsValid() const { return metadata_.IsValid(); }
+ uint32_t id() const { return mId; }
+
size_t user_metadata_size() const { return metadata_.user_metadata_size(); }
// Accessors of the buffer description and handle
@@ -59,6 +63,11 @@
// Metadata in shared memory.
BufferHubMetadata metadata_;
+ // A system-unique id generated by bufferhub from 1 to std::numeric_limits<uint32_t>::max().
+ // BufferNodes not created by bufferhub will have id = 0, meaning "not specified".
+ // TODO(b/118891412): remove default id = 0 and update comments after pdx is no longer in use
+ const uint32_t mId = 0;
+
// The following variables are atomic variables in metadata_ that are visible
// to Bn object and Bp objects. Please find more info in
// BufferHubDefs::MetadataHeader.
diff --git a/services/bufferhub/include/bufferhub/UniqueIdGenerator.h b/services/bufferhub/include/bufferhub/UniqueIdGenerator.h
new file mode 100644
index 0000000..d2e702f
--- /dev/null
+++ b/services/bufferhub/include/bufferhub/UniqueIdGenerator.h
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_FRAMEWORKS_BUFFERHUB_V1_0_ID_GENERATOR_H
+#define ANDROID_FRAMEWORKS_BUFFERHUB_V1_0_ID_GENERATOR_H
+
+#include <mutex>
+#include <set>
+
+#include <utils/Mutex.h>
+
+namespace android {
+namespace frameworks {
+namespace bufferhub {
+namespace V1_0 {
+namespace implementation {
+
+// A thread-safe incremental uint32_t id generator.
+class UniqueIdGenerator {
+public:
+ // 0 is considered invalid
+ static constexpr uint32_t kInvalidId = 0UL;
+
+ // Gets next available id. If next id is greater than std::numeric_limits<uint32_t>::max() (2 ^
+ // 32 - 1), it will try to get an id start from 1 again.
+ uint32_t getId();
+
+ // Free a specific id. Return true on freed, false on not found.
+ bool freeId(uint32_t id);
+
+private:
+ std::mutex mIdsInUseMutex;
+ // Start from kInvalidID to avoid generating it.
+ uint32_t mLastId = kInvalidId;
+ std::set<uint32_t> mIdsInUse GUARDED_BY(mIdsInUseMutex);
+};
+
+} // namespace implementation
+} // namespace V1_0
+} // namespace bufferhub
+} // namespace frameworks
+} // namespace android
+
+#endif // ANDROID_FRAMEWORKS_BUFFERHUB_V1_0_ID_GENERATOR_H
diff --git a/services/bufferhub/tests/Android.bp b/services/bufferhub/tests/Android.bp
index cef31f6..8a30ef5 100644
--- a/services/bufferhub/tests/Android.bp
+++ b/services/bufferhub/tests/Android.bp
@@ -21,4 +21,20 @@
],
// TODO(b/117568153): Temporarily opt out using libcrt.
no_libcrt: true,
+}
+
+cc_test {
+ name: "UniqueIdGenerator_test",
+ srcs: ["UniqueIdGenerator_test.cpp"],
+ cflags: [
+ "-DLOG_TAG=\"UniqueIdGenerator_test\"",
+ "-DTRACE=0",
+ "-DATRACE_TAG=ATRACE_TAG_GRAPHICS",
+ ],
+ shared_libs: [
+ "libbufferhubservice",
+ ],
+ static_libs: [
+ "libgmock",
+ ],
}
\ No newline at end of file
diff --git a/services/bufferhub/tests/UniqueIdGenerator_test.cpp b/services/bufferhub/tests/UniqueIdGenerator_test.cpp
new file mode 100644
index 0000000..c4d83e0
--- /dev/null
+++ b/services/bufferhub/tests/UniqueIdGenerator_test.cpp
@@ -0,0 +1,45 @@
+#include <bufferhub/UniqueIdGenerator.h>
+#include <gtest/gtest.h>
+
+namespace android {
+namespace frameworks {
+namespace bufferhub {
+namespace V1_0 {
+namespace implementation {
+
+namespace {
+
+class UniqueIdGeneratorTest : public testing::Test {
+protected:
+ UniqueIdGenerator mIdGenerator;
+};
+
+TEST_F(UniqueIdGeneratorTest, TestGenerateAndFreeID) {
+ uint32_t id = mIdGenerator.getId();
+ EXPECT_NE(id, UniqueIdGenerator::kInvalidId);
+
+ EXPECT_TRUE(mIdGenerator.freeId(id));
+ EXPECT_FALSE(mIdGenerator.freeId(id));
+}
+
+TEST_F(UniqueIdGeneratorTest, TestGenerateUniqueIncrementalID) {
+ // 10 IDs should not overflow the UniqueIdGenerator to cause a roll back to start, so the
+ // resulting IDs should still keep incresing.
+ const size_t kTestSize = 10U;
+ uint32_t ids[kTestSize];
+ for (int i = 0; i < kTestSize; ++i) {
+ ids[i] = mIdGenerator.getId();
+ EXPECT_NE(ids[i], UniqueIdGenerator::kInvalidId);
+ if (i >= 1) {
+ EXPECT_GT(ids[i], ids[i - 1]);
+ }
+ }
+}
+
+} // namespace
+
+} // namespace implementation
+} // namespace V1_0
+} // namespace bufferhub
+} // namespace frameworks
+} // namespace android
\ No newline at end of file
diff --git a/services/gpuservice/GpuService.cpp b/services/gpuservice/GpuService.cpp
index e4ca6bc..150896c 100644
--- a/services/gpuservice/GpuService.cpp
+++ b/services/gpuservice/GpuService.cpp
@@ -62,7 +62,7 @@
status_t cmd_vkjson(int out, int err);
}
-const char* const GpuService::SERVICE_NAME = "gpuservice";
+const char* const GpuService::SERVICE_NAME = "gpu";
GpuService::GpuService() = default;
diff --git a/services/gpuservice/gpuservice.rc b/services/gpuservice/gpuservice.rc
index d23cf46..65a5c27 100644
--- a/services/gpuservice/gpuservice.rc
+++ b/services/gpuservice/gpuservice.rc
@@ -1,4 +1,4 @@
-service gpuservice /system/bin/gpuservice
+service gpu /system/bin/gpuservice
class core
user gpu_service
group graphics
diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp
index 038bc58..1e910ce 100644
--- a/services/surfaceflinger/Layer.cpp
+++ b/services/surfaceflinger/Layer.cpp
@@ -1344,7 +1344,10 @@
void Layer::updateTransformHint(const sp<const DisplayDevice>& display) const {
uint32_t orientation = 0;
- if (!mFlinger->mDebugDisableTransformHint) {
+ // Disable setting transform hint if the debug flag is set or if the
+ // getTransformToDisplayInverse flag is set and the client wants to submit buffers
+ // in one orientation.
+ if (!mFlinger->mDebugDisableTransformHint && !getTransformToDisplayInverse()) {
// The transform hint is used to improve performance, but we can
// only have a single transform hint, it cannot
// apply to all displays.
@@ -1976,6 +1979,7 @@
layerInfo->set_window_type(state.type);
layerInfo->set_app_id(state.appId);
layerInfo->set_curr_frame(mCurrentFrameNumber);
+ layerInfo->set_effective_scaling_mode(getEffectiveScalingMode());
for (const auto& pendingState : mPendingStates) {
auto barrierLayer = pendingState.barrierLayer_legacy.promote();
diff --git a/services/surfaceflinger/SurfaceTracing.cpp b/services/surfaceflinger/SurfaceTracing.cpp
index 67dcd06..1835929 100644
--- a/services/surfaceflinger/SurfaceTracing.cpp
+++ b/services/surfaceflinger/SurfaceTracing.cpp
@@ -26,22 +26,48 @@
namespace android {
-void SurfaceTracing::enable() {
- ATRACE_CALL();
+void SurfaceTracing::LayersTraceBuffer::reset(size_t newSize) {
+ // use the swap trick to make sure memory is released
+ std::queue<LayersTraceProto>().swap(mStorage);
+ mSizeInBytes = newSize;
+ mUsedInBytes = 0U;
+}
+
+void SurfaceTracing::LayersTraceBuffer::emplace(LayersTraceProto&& proto) {
+ auto protoSize = proto.ByteSize();
+ while (mUsedInBytes + protoSize > mSizeInBytes) {
+ if (mStorage.empty()) {
+ return;
+ }
+ mUsedInBytes -= mStorage.front().ByteSize();
+ mStorage.pop();
+ }
+ mUsedInBytes += protoSize;
+ mStorage.emplace();
+ mStorage.back().Swap(&proto);
+}
+
+void SurfaceTracing::LayersTraceBuffer::flush(LayersTraceFileProto* fileProto) {
+ fileProto->mutable_entry()->Reserve(mStorage.size());
+
+ while (!mStorage.empty()) {
+ auto entry = fileProto->add_entry();
+ entry->Swap(&mStorage.front());
+ mStorage.pop();
+ }
+}
+
+void SurfaceTracing::enable(size_t bufferSizeInByte) {
std::lock_guard<std::mutex> protoGuard(mTraceMutex);
if (mEnabled) {
return;
}
mEnabled = true;
-
- mTrace = std::make_unique<LayersTraceFileProto>();
- mTrace->set_magic_number(uint64_t(LayersTraceFileProto_MagicNumber_MAGIC_NUMBER_H) << 32 |
- LayersTraceFileProto_MagicNumber_MAGIC_NUMBER_L);
+ mBuffer.reset(bufferSizeInByte);
}
status_t SurfaceTracing::disable() {
- ATRACE_CALL();
std::lock_guard<std::mutex> protoGuard(mTraceMutex);
if (!mEnabled) {
@@ -51,7 +77,7 @@
status_t err(writeProtoFileLocked());
ALOGE_IF(err == PERMISSION_DENIED, "Could not save the proto file! Permission denied");
ALOGE_IF(err == NOT_ENOUGH_DATA, "Could not save the proto file! There are missing fields");
- mTrace.reset();
+ mBuffer.reset(0);
return err;
}
@@ -65,32 +91,29 @@
if (!mEnabled) {
return;
}
- LayersTraceProto* entry = mTrace->add_entry();
- entry->set_elapsed_realtime_nanos(elapsedRealtimeNano());
- entry->set_where(where);
- entry->mutable_layers()->Swap(&layers);
- constexpr int maxBufferedEntryCount = 3600;
- if (mTrace->entry_size() >= maxBufferedEntryCount) {
- // TODO: flush buffered entries without disabling tracing
- ALOGE("too many buffered frames; force disable tracing");
- mEnabled = false;
- writeProtoFileLocked();
- mTrace.reset();
- }
+ LayersTraceProto entry;
+ entry.set_elapsed_realtime_nanos(elapsedRealtimeNano());
+ entry.set_where(where);
+ entry.mutable_layers()->Swap(&layers);
+
+ mBuffer.emplace(std::move(entry));
}
status_t SurfaceTracing::writeProtoFileLocked() {
ATRACE_CALL();
- if (!mTrace->IsInitialized()) {
- return NOT_ENOUGH_DATA;
- }
+ LayersTraceFileProto fileProto;
std::string output;
- if (!mTrace->SerializeToString(&output)) {
+
+ fileProto.set_magic_number(uint64_t(LayersTraceFileProto_MagicNumber_MAGIC_NUMBER_H) << 32 |
+ LayersTraceFileProto_MagicNumber_MAGIC_NUMBER_L);
+ mBuffer.flush(&fileProto);
+
+ if (!fileProto.SerializeToString(&output)) {
return PERMISSION_DENIED;
}
- if (!android::base::WriteStringToFile(output, mOutputFileName, true)) {
+ if (!android::base::WriteStringToFile(output, kDefaultFileName, true)) {
return PERMISSION_DENIED;
}
@@ -101,7 +124,8 @@
std::lock_guard<std::mutex> protoGuard(mTraceMutex);
result.appendFormat("Tracing state: %s\n", mEnabled ? "enabled" : "disabled");
- result.appendFormat(" number of entries: %d\n", mTrace ? mTrace->entry_size() : 0);
+ result.appendFormat(" number of entries: %zu (%.2fMB / %.2fMB)\n", mBuffer.frameCount(),
+ float(mBuffer.used()) / float(1_MB), float(mBuffer.size()) / float(1_MB));
}
} // namespace android
diff --git a/services/surfaceflinger/SurfaceTracing.h b/services/surfaceflinger/SurfaceTracing.h
index fd8cb82..ec01be7 100644
--- a/services/surfaceflinger/SurfaceTracing.h
+++ b/services/surfaceflinger/SurfaceTracing.h
@@ -22,32 +22,54 @@
#include <memory>
#include <mutex>
+#include <queue>
using namespace android::surfaceflinger;
namespace android {
+constexpr auto operator""_MB(unsigned long long const num) {
+ return num * 1024 * 1024;
+}
+
/*
* SurfaceTracing records layer states during surface flinging.
*/
class SurfaceTracing {
public:
- void enable();
+ void enable() { enable(kDefaultBufferCapInByte); }
+ void enable(size_t bufferSizeInByte);
status_t disable();
- bool isEnabled() const;
-
void traceLayers(const char* where, LayersProto);
+
+ bool isEnabled() const;
void dump(String8& result) const;
private:
- static constexpr auto DEFAULT_FILENAME = "/data/misc/wmtrace/layers_trace.pb";
+ static constexpr auto kDefaultBufferCapInByte = 100_MB;
+ static constexpr auto kDefaultFileName = "/data/misc/wmtrace/layers_trace.pb";
+
+ class LayersTraceBuffer { // ring buffer
+ public:
+ size_t size() const { return mSizeInBytes; }
+ size_t used() const { return mUsedInBytes; }
+ size_t frameCount() const { return mStorage.size(); }
+
+ void reset(size_t newSize);
+ void emplace(LayersTraceProto&& proto);
+ void flush(LayersTraceFileProto* fileProto);
+
+ private:
+ size_t mUsedInBytes = 0U;
+ size_t mSizeInBytes = 0U;
+ std::queue<LayersTraceProto> mStorage;
+ };
status_t writeProtoFileLocked();
bool mEnabled = false;
- std::string mOutputFileName = DEFAULT_FILENAME;
mutable std::mutex mTraceMutex;
- std::unique_ptr<LayersTraceFileProto> mTrace;
+ LayersTraceBuffer mBuffer;
};
} // namespace android
diff --git a/services/surfaceflinger/layerproto/layers.proto b/services/surfaceflinger/layerproto/layers.proto
index 2a09634..c141ee3 100644
--- a/services/surfaceflinger/layerproto/layers.proto
+++ b/services/surfaceflinger/layerproto/layers.proto
@@ -86,6 +86,7 @@
repeated BarrierLayerProto barrier_layer = 38;
// If active_buffer is not null, record its transform.
optional TransformProto buffer_transform = 39;
+ optional int32 effective_scaling_mode = 40;
}
message PositionProto {
diff --git a/services/vr/performanced/Android.bp b/services/vr/performanced/Android.bp
new file mode 100644
index 0000000..20301f6
--- /dev/null
+++ b/services/vr/performanced/Android.bp
@@ -0,0 +1,53 @@
+// Copyright (C) 2016 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.
+
+cc_defaults {
+ name: "performanced_defaults",
+ static_libs: [
+ "libperformance",
+ "libvr_manager",
+ ],
+ shared_libs: [
+ "libbinder",
+ "libbase",
+ "libcutils",
+ "liblog",
+ "libutils",
+ "libpdx_default_transport",
+ ],
+}
+
+cc_binary {
+ name: "performanced",
+ defaults: ["performanced_defaults"],
+ srcs: [
+ "cpu_set.cpp",
+ "main.cpp",
+ "performance_service.cpp",
+ "task.cpp",
+ ],
+ cflags: [
+ "-DLOG_TAG=\"performanced\"",
+ "-DTRACE=0",
+ "-Wall",
+ "-Werror",
+ ],
+ init_rc: ["performanced.rc"],
+}
+
+cc_test {
+ name: "performance_service_tests",
+ defaults: ["performanced_defaults"],
+ srcs: ["performance_service_tests.cpp"],
+}
diff --git a/services/vr/performanced/Android.mk b/services/vr/performanced/Android.mk
deleted file mode 100644
index a548ef0..0000000
--- a/services/vr/performanced/Android.mk
+++ /dev/null
@@ -1,52 +0,0 @@
-# Copyright (C) 2016 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.
-
-LOCAL_PATH := $(call my-dir)
-
-sourceFiles := \
- cpu_set.cpp \
- main.cpp \
- performance_service.cpp \
- task.cpp
-
-staticLibraries := \
- libperformance \
- libvr_manager
-
-sharedLibraries := \
- libbinder \
- libbase \
- libcutils \
- liblog \
- libutils \
- libpdx_default_transport \
-
-include $(CLEAR_VARS)
-LOCAL_SRC_FILES := $(sourceFiles)
-LOCAL_CFLAGS := -DLOG_TAG=\"performanced\"
-LOCAL_CFLAGS += -DTRACE=0
-LOCAL_CFLAGS += -Wall -Werror
-LOCAL_STATIC_LIBRARIES := $(staticLibraries)
-LOCAL_SHARED_LIBRARIES := $(sharedLibraries)
-LOCAL_MODULE := performanced
-LOCAL_INIT_RC := performanced.rc
-include $(BUILD_EXECUTABLE)
-
-include $(CLEAR_VARS)
-LOCAL_SRC_FILES := performance_service_tests.cpp
-LOCAL_STATIC_LIBRARIES := $(staticLibraries) libgtest_main
-LOCAL_SHARED_LIBRARIES := $(sharedLibraries)
-LOCAL_MODULE := performance_service_tests
-LOCAL_MODULE_TAGS := optional
-include $(BUILD_NATIVE_TEST)
diff --git a/vulkan/api/vulkan.api b/vulkan/api/vulkan.api
index 8f76606..e4c50d5 100644
--- a/vulkan/api/vulkan.api
+++ b/vulkan/api/vulkan.api
@@ -28,7 +28,7 @@
// API version (major.minor.patch)
define VERSION_MAJOR 1
define VERSION_MINOR 1
-define VERSION_PATCH 91
+define VERSION_PATCH 93
// API limits
define VK_MAX_PHYSICAL_DEVICE_NAME_SIZE 256
@@ -615,6 +615,10 @@
@extension("VK_FUCHSIA_imagepipe_surface") define VK_FUCHSIA_IMAGEPIPE_SURFACE_SPEC_VERSION 1
@extension("VK_FUCHSIA_imagepipe_surface") define VK_FUCHSIA_IMAGEPIPE_SURFACE_EXTENSION_NAME "VK_FUCHSIA_imagepipe_surface"
+// 222
+@extension("VK_EXT_scalar_block_layout") define VK_EXT_SCALAR_BLOCK_LAYOUT_SPEC_VERSION 1
+@extension("VK_EXT_scalar_block_layout") define VK_EXT_SCALAR_BLOCK_LAYOUT_EXTENSION_NAME "VK_EXT_scalar_block_layout"
+
// 224
@extension("VK_GOOGLE_hlsl_functionality1") define VK_GOOGLE_HLSL_FUNCTIONALITY1_SPEC_VERSION 0
@extension("VK_GOOGLE_hlsl_functionality1") define VK_GOOGLE_HLSL_FUNCTIONALITY1_EXTENSION_NAME "VK_GOOGLE_hlsl_functionality1"
@@ -623,6 +627,10 @@
@extension("VK_GOOGLE_decorate_string") define VK_GOOGLE_DECORATE_STRING_SPEC_VERSION 0
@extension("VK_GOOGLE_decorate_string") define VK_GOOGLE_DECORATE_STRING_EXTENSION_NAME "VK_GOOGLE_decorate_string"
+// 247
+@extension("VK_EXT_separate_stencil_usage") define VK_EXT_SEPARATE_STENCIL_USAGE_SPEC_VERSION 1
+@extension("VK_EXT_separate_stencil_usage") define VK_EXT_SEPARATE_STENCIL_USAGE_EXTENSION_NAME "VK_EXT_separate_stencil_usage"
+
/////////////
// Types //
/////////////
@@ -1848,10 +1856,16 @@
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_MEMORY_MODEL_FEATURES_KHR = 1000211000,
//@extension("VK_EXT_pci_bus_info") // 213
- VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PCI_BUS_INFO_PROPERTIES_EXT = 1000212000,
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PCI_BUS_INFO_PROPERTIES_EXT = 1000212000,
//@extension("VK_FUCHSIA_imagepipe_surface") // 215
VK_STRUCTURE_TYPE_IMAGEPIPE_SURFACE_CREATE_INFO_FUCHSIA = 1000214000,
+
+ //@extension("VK_EXT_scalar_block_layout")
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SCALAR_BLOCK_LAYOUT_FEATURES_EXT = 1000221000,
+
+ //@extension("VK_EXT_separate_stencil_usage") // 247
+ VK_STRUCTURE_TYPE_IMAGE_STENCIL_USAGE_CREATE_INFO_EXT = 1000246000,
}
enum VkSubpassContents {
@@ -2382,6 +2396,7 @@
VK_DRIVER_ID_IMAGINATION_PROPRIETARY_KHR = 7,
VK_DRIVER_ID_QUALCOMM_PROPRIETARY_KHR = 8,
VK_DRIVER_ID_ARM_PROPRIETARY_KHR = 9,
+ VK_DRIVER_ID_GOOGLE_PASTEL_KHR = 10,
}
/////////////////
@@ -7656,6 +7671,20 @@
platform.zx_handle_t imagePipeHandle
}
+@extension("VK_EXT_scalar_block_layout") // 222
+class VkPhysicalDeviceScalarBlockLayoutFeaturesEXT {
+ VkStructureType sType
+ void* pNext
+ VkBool32 scalarBlockLayout
+}
+
+@extension("VK_EXT_separate_stencil_usage") // 247
+class VkImageStencilUsageCreateInfoEXT {
+ VkStructureType sType
+ const void* pNext
+ VkImageUsageFlags stencilUsage
+}
+
////////////////
// Commands //
diff --git a/vulkan/include/vulkan/vulkan_core.h b/vulkan/include/vulkan/vulkan_core.h
index 4cd8ed5..35c0664 100644
--- a/vulkan/include/vulkan/vulkan_core.h
+++ b/vulkan/include/vulkan/vulkan_core.h
@@ -43,7 +43,7 @@
#define VK_VERSION_MINOR(version) (((uint32_t)(version) >> 12) & 0x3ff)
#define VK_VERSION_PATCH(version) ((uint32_t)(version) & 0xfff)
// Version of this file
-#define VK_HEADER_VERSION 91
+#define VK_HEADER_VERSION 93
#define VK_NULL_HANDLE 0
@@ -454,6 +454,8 @@
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_MEMORY_MODEL_FEATURES_KHR = 1000211000,
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PCI_BUS_INFO_PROPERTIES_EXT = 1000212000,
VK_STRUCTURE_TYPE_IMAGEPIPE_SURFACE_CREATE_INFO_FUCHSIA = 1000214000,
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SCALAR_BLOCK_LAYOUT_FEATURES_EXT = 1000221000,
+ VK_STRUCTURE_TYPE_IMAGE_STENCIL_USAGE_CREATE_INFO_EXT = 1000246000,
VK_STRUCTURE_TYPE_DEBUG_REPORT_CREATE_INFO_EXT = VK_STRUCTURE_TYPE_DEBUG_REPORT_CALLBACK_CREATE_INFO_EXT,
VK_STRUCTURE_TYPE_RENDER_PASS_MULTIVIEW_CREATE_INFO_KHR = VK_STRUCTURE_TYPE_RENDER_PASS_MULTIVIEW_CREATE_INFO,
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTIVIEW_FEATURES_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTIVIEW_FEATURES,
@@ -6101,9 +6103,10 @@
VK_DRIVER_ID_IMAGINATION_PROPRIETARY_KHR = 7,
VK_DRIVER_ID_QUALCOMM_PROPRIETARY_KHR = 8,
VK_DRIVER_ID_ARM_PROPRIETARY_KHR = 9,
+ VK_DRIVER_ID_GOOGLE_PASTEL_KHR = 10,
VK_DRIVER_ID_BEGIN_RANGE_KHR = VK_DRIVER_ID_AMD_PROPRIETARY_KHR,
- VK_DRIVER_ID_END_RANGE_KHR = VK_DRIVER_ID_ARM_PROPRIETARY_KHR,
- VK_DRIVER_ID_RANGE_SIZE_KHR = (VK_DRIVER_ID_ARM_PROPRIETARY_KHR - VK_DRIVER_ID_AMD_PROPRIETARY_KHR + 1),
+ VK_DRIVER_ID_END_RANGE_KHR = VK_DRIVER_ID_GOOGLE_PASTEL_KHR,
+ VK_DRIVER_ID_RANGE_SIZE_KHR = (VK_DRIVER_ID_GOOGLE_PASTEL_KHR - VK_DRIVER_ID_AMD_PROPRIETARY_KHR + 1),
VK_DRIVER_ID_MAX_ENUM_KHR = 0x7FFFFFFF
} VkDriverIdKHR;
@@ -7791,8 +7794,6 @@
#define VK_EXT_image_drm_format_modifier 1
-#define VK_EXT_EXTENSION_159_SPEC_VERSION 0
-#define VK_EXT_EXTENSION_159_EXTENSION_NAME "VK_EXT_extension_159"
#define VK_EXT_IMAGE_DRM_FORMAT_MODIFIER_SPEC_VERSION 1
#define VK_EXT_IMAGE_DRM_FORMAT_MODIFIER_EXTENSION_NAME "VK_EXT_image_drm_format_modifier"
@@ -8806,6 +8807,18 @@
+#define VK_EXT_scalar_block_layout 1
+#define VK_EXT_SCALAR_BLOCK_LAYOUT_SPEC_VERSION 1
+#define VK_EXT_SCALAR_BLOCK_LAYOUT_EXTENSION_NAME "VK_EXT_scalar_block_layout"
+
+typedef struct VkPhysicalDeviceScalarBlockLayoutFeaturesEXT {
+ VkStructureType sType;
+ void* pNext;
+ VkBool32 scalarBlockLayout;
+} VkPhysicalDeviceScalarBlockLayoutFeaturesEXT;
+
+
+
#define VK_GOOGLE_hlsl_functionality1 1
#define VK_GOOGLE_HLSL_FUNCTIONALITY1_SPEC_VERSION 0
#define VK_GOOGLE_HLSL_FUNCTIONALITY1_EXTENSION_NAME "VK_GOOGLE_hlsl_functionality1"
@@ -8816,6 +8829,18 @@
#define VK_GOOGLE_DECORATE_STRING_EXTENSION_NAME "VK_GOOGLE_decorate_string"
+#define VK_EXT_separate_stencil_usage 1
+#define VK_EXT_SEPARATE_STENCIL_USAGE_SPEC_VERSION 1
+#define VK_EXT_SEPARATE_STENCIL_USAGE_EXTENSION_NAME "VK_EXT_separate_stencil_usage"
+
+typedef struct VkImageStencilUsageCreateInfoEXT {
+ VkStructureType sType;
+ const void* pNext;
+ VkImageUsageFlags stencilUsage;
+} VkImageStencilUsageCreateInfoEXT;
+
+
+
#ifdef __cplusplus
}
#endif