Merge "Updating bugreport to dump only visible activities."
diff --git a/cmds/atrace/atrace.cpp b/cmds/atrace/atrace.cpp
index 8f2dee1..14eff03 100644
--- a/cmds/atrace/atrace.cpp
+++ b/cmds/atrace/atrace.cpp
@@ -1284,7 +1284,7 @@
fflush(stdout);
int outFd = STDOUT_FILENO;
if (g_outputFile) {
- outFd = open(g_outputFile, O_WRONLY | O_CREAT, 0644);
+ outFd = open(g_outputFile, O_WRONLY | O_CREAT | O_TRUNC, 0644);
}
if (outFd == -1) {
printf("Failed to open '%s', err=%d", g_outputFile, errno);
diff --git a/cmds/dumpstate/dumpstate.cpp b/cmds/dumpstate/dumpstate.cpp
index aa5e970..1cf00f5 100644
--- a/cmds/dumpstate/dumpstate.cpp
+++ b/cmds/dumpstate/dumpstate.cpp
@@ -1059,7 +1059,7 @@
#endif
DumpFile("INTERRUPTS (2)", "/proc/interrupts");
- print_properties();
+ RunCommand("SYSTEM PROPERTIES", {"getprop"});
RunCommand("VOLD DUMP", {"vdc", "dump"});
RunCommand("SECURE CONTAINERS", {"vdc", "asec", "list"});
diff --git a/cmds/dumpstate/dumpstate.h b/cmds/dumpstate/dumpstate.h
index d988429..7fcb980 100644
--- a/cmds/dumpstate/dumpstate.h
+++ b/cmds/dumpstate/dumpstate.h
@@ -363,9 +363,6 @@
int dump_files(const std::string& title, const char* dir, bool (*skip)(const char* path),
int (*dump_from_fd)(const char* title, const char* path, int fd));
-/* prints all the system properties */
-void print_properties();
-
/** opens a socket and returns its file descriptor */
int open_socket(const char *service);
diff --git a/cmds/dumpstate/utils.cpp b/cmds/dumpstate/utils.cpp
index baa6458..4655d33 100644
--- a/cmds/dumpstate/utils.cpp
+++ b/cmds/dumpstate/utils.cpp
@@ -710,40 +710,6 @@
RunCommand(title, dumpsys, options);
}
-size_t num_props = 0;
-static char* props[2000];
-
-static void print_prop(const char *key, const char *name, void *user) {
- (void) user;
- if (num_props < sizeof(props) / sizeof(props[0])) {
- char buf[PROPERTY_KEY_MAX + PROPERTY_VALUE_MAX + 10];
- snprintf(buf, sizeof(buf), "[%s]: [%s]\n", key, name);
- props[num_props++] = strdup(buf);
- }
-}
-
-static int compare_prop(const void *a, const void *b) {
- return strcmp(*(char * const *) a, *(char * const *) b);
-}
-
-/* prints all the system properties */
-void print_properties() {
- const char* title = "SYSTEM PROPERTIES";
- DurationReporter duration_reporter(title);
- printf("------ %s ------\n", title);
- if (PropertiesHelper::IsDryRun()) return;
- size_t i;
- num_props = 0;
- property_list(print_prop, NULL);
- qsort(&props, num_props, sizeof(props[0]), compare_prop);
-
- for (i = 0; i < num_props; ++i) {
- fputs(props[i], stdout);
- free(props[i]);
- }
- printf("\n");
-}
-
int open_socket(const char *service) {
int s = android_get_control_socket(service);
if (s < 0) {
diff --git a/cmds/lshal/Android.bp b/cmds/lshal/Android.bp
index 5aab35a..39e0ba3 100644
--- a/cmds/lshal/Android.bp
+++ b/cmds/lshal/Android.bp
@@ -18,8 +18,10 @@
"libbase",
"libutils",
"libhidlbase",
- "android.hidl.manager@1.0",
"libhidltransport",
+ "libhidl-gen-utils",
+ "libvintf",
+ "android.hidl.manager@1.0",
],
srcs: [
"Lshal.cpp"
diff --git a/cmds/lshal/Lshal.cpp b/cmds/lshal/Lshal.cpp
index 6fd9b21..e953ded 100644
--- a/cmds/lshal/Lshal.cpp
+++ b/cmds/lshal/Lshal.cpp
@@ -28,6 +28,9 @@
#include <android-base/parseint.h>
#include <android/hidl/manager/1.0/IServiceManager.h>
#include <hidl/ServiceManagement.h>
+#include <hidl-util/FQName.h>
+#include <vintf/HalManifest.h>
+#include <vintf/parse_xml.h>
#include "Timeout.h"
@@ -58,12 +61,13 @@
return os.str();
}
-static std::pair<hidl_string, hidl_string> split(const hidl_string &s, char c) {
+template<typename String>
+static std::pair<String, String> splitFirst(const String &s, char c) {
const char *pos = strchr(s.c_str(), c);
if (pos == nullptr) {
return {s, {}};
}
- return {hidl_string(s.c_str(), pos - s.c_str()), hidl_string(pos + 1)};
+ return {String(s.c_str(), pos - s.c_str()), String(pos + 1)};
}
static std::vector<std::string> split(const std::string &s, char c) {
@@ -81,6 +85,14 @@
return components;
}
+static void replaceAll(std::string *s, char from, char to) {
+ for (size_t i = 0; i < s->size(); ++i) {
+ if (s->at(i) == from) {
+ s->at(i) = to;
+ }
+ }
+}
+
std::string getCmdline(pid_t pid) {
std::ifstream ifs("/proc/" + std::to_string(pid) + "/cmdline");
std::string cmdline;
@@ -189,7 +201,78 @@
mOut << std::endl;
}
-void Lshal::dump() const {
+void Lshal::dumpVintf() const {
+ vintf::HalManifest manifest;
+ for (const TableEntry &entry : mTable) {
+
+ std::string fqInstanceName = entry.interfaceName;
+
+ if (entry.source == LIST_DLLIB) {
+ // Quick hack to work around *'s
+ replaceAll(&fqInstanceName, '*', 'D');
+ }
+ auto splittedFqInstanceName = splitFirst(fqInstanceName, '/');
+ FQName fqName(splittedFqInstanceName.first);
+ if (!fqName.isValid()) {
+ mErr << "Warning: '" << splittedFqInstanceName.first
+ << "' is not a valid FQName." << std::endl;
+ continue;
+ }
+ // Strip out system libs.
+ // TODO(b/34772739): might want to add other framework HAL packages
+ if (fqName.inPackage("android.hidl")) {
+ continue;
+ }
+ std::string interfaceName =
+ entry.source == LIST_DLLIB ? "" : fqName.name();
+ std::string instanceName =
+ entry.source == LIST_DLLIB ? "" : splittedFqInstanceName.second;
+
+ vintf::Transport transport;
+ if (entry.transport == "hwbinder") {
+ transport = vintf::Transport::HWBINDER;
+ } else if (entry.transport == "passthrough") {
+ transport = vintf::Transport::PASSTHROUGH;
+ } else {
+ mErr << "Warning: '" << entry.transport << "' is not a valid transport." << std::endl;
+ continue;
+ }
+
+ vintf::ManifestHal *hal = manifest.getHal(fqName.package());
+ if (hal == nullptr) {
+ if (!manifest.add(vintf::ManifestHal{
+ .format = vintf::HalFormat::HIDL,
+ .name = fqName.package(),
+ .impl = {.implLevel = vintf::ImplLevel::GENERIC, .impl = ""},
+ .transport = transport
+ })) {
+ mErr << "Warning: cannot add hal '" << fqInstanceName << "'" << std::endl;
+ continue;
+ }
+ hal = manifest.getHal(fqName.package());
+ }
+ if (hal == nullptr) {
+ mErr << "Warning: cannot get hal '" << fqInstanceName
+ << "' after adding it" << std::endl;
+ continue;
+ }
+ vintf::Version version{fqName.getPackageMajorVersion(), fqName.getPackageMinorVersion()};
+ if (std::find(hal->versions.begin(), hal->versions.end(), version) == hal->versions.end()) {
+ hal->versions.push_back(version);
+ }
+ if (entry.source != LIST_DLLIB) {
+ auto it = hal->interfaces.find(interfaceName);
+ if (it == hal->interfaces.end()) {
+ hal->interfaces.insert({interfaceName, {interfaceName, {{instanceName}}}});
+ } else {
+ it->second.instances.insert(instanceName);
+ }
+ }
+ }
+ mOut << vintf::gHalManifestConverter(manifest);
+}
+
+void Lshal::dumpTable() const {
mOut << "All services:" << std::endl;
mOut << std::left;
printLine("Interface", "Transport", "Server", "Server CMD", "PTR", "Clients", "Clients CMD");
@@ -204,6 +287,20 @@
}
}
+void Lshal::dump() {
+ if (mVintf) {
+ dumpVintf();
+ if (!!mFileOutput) {
+ mFileOutput.buf().close();
+ delete &mFileOutput.buf();
+ mFileOutput = nullptr;
+ }
+ mOut = std::cout;
+ } else {
+ dumpTable();
+ }
+}
+
void Lshal::putEntry(TableEntry &&entry) {
mTable.push_back(std::forward<TableEntry>(entry));
}
@@ -219,7 +316,8 @@
.transport = "passthrough",
.serverPid = NO_PID,
.serverObjectAddress = NO_PTR,
- .clientPids = {}
+ .clientPids = {},
+ .source = LIST_DLLIB
});
}
});
@@ -244,7 +342,8 @@
.transport = "passthrough",
.serverPid = info.clientPids.size() == 1 ? info.clientPids[0] : NO_PID,
.serverObjectAddress = NO_PTR,
- .clientPids = info.clientPids
+ .clientPids = info.clientPids,
+ .source = PTSERVICEMANAGER_REG_CLIENT
});
}
});
@@ -262,79 +361,85 @@
using namespace ::android::hidl::manager::V1_0;
using namespace ::android::hidl::base::V1_0;
const std::string mode = "hwbinder";
- Status status = OK;
- auto listRet = timeoutIPC(manager, &IServiceManager::list, [&] (const auto &fqInstanceNames) {
- // server pid, .ptr value of binder object, child pids
- std::map<std::string, DebugInfo> allDebugInfos;
- std::map<pid_t, std::map<uint64_t, Pids>> allPids;
- for (const auto &fqInstanceName : fqInstanceNames) {
- const auto pair = split(fqInstanceName, '/');
- const auto &serviceName = pair.first;
- const auto &instanceName = pair.second;
- auto getRet = timeoutIPC(manager, &IServiceManager::get, serviceName, instanceName);
- if (!getRet.isOk()) {
- mErr << "Warning: Skipping \"" << fqInstanceName << "\": "
- << "cannot be fetched from service manager:"
- << getRet.description() << std::endl;
- status |= DUMP_BINDERIZED_ERROR;
- continue;
- }
- sp<IBase> service = getRet;
- if (service == nullptr) {
- mErr << "Warning: Skipping \"" << fqInstanceName << "\": "
- << "cannot be fetched from service manager (null)";
- status |= DUMP_BINDERIZED_ERROR;
- continue;
- }
- auto debugRet = timeoutIPC(service, &IBase::getDebugInfo, [&] (const auto &debugInfo) {
- allDebugInfos[fqInstanceName] = debugInfo;
- if (debugInfo.pid >= 0) {
- allPids[static_cast<pid_t>(debugInfo.pid)].clear();
- }
- });
- if (!debugRet.isOk()) {
- mErr << "Warning: Skipping \"" << fqInstanceName << "\": "
- << "debugging information cannot be retrieved:"
- << debugRet.description() << std::endl;
- status |= DUMP_BINDERIZED_ERROR;
- }
- }
- for (auto &pair : allPids) {
- pid_t serverPid = pair.first;
- if (!getReferencedPids(serverPid, &allPids[serverPid])) {
- mErr << "Warning: no information for PID " << serverPid
- << ", are you root?" << std::endl;
- status |= DUMP_BINDERIZED_ERROR;
- }
- }
- for (const auto &fqInstanceName : fqInstanceNames) {
- auto it = allDebugInfos.find(fqInstanceName);
- if (it == allDebugInfos.end()) {
- putEntry({
- .interfaceName = fqInstanceName,
- .transport = mode,
- .serverPid = NO_PID,
- .serverObjectAddress = NO_PTR,
- .clientPids = {}
- });
- continue;
- }
- const DebugInfo &info = it->second;
- putEntry({
- .interfaceName = fqInstanceName,
- .transport = mode,
- .serverPid = info.pid,
- .serverObjectAddress = info.ptr,
- .clientPids = info.pid == NO_PID || info.ptr == NO_PTR
- ? Pids{} : allPids[info.pid][info.ptr]
- });
- }
+ hidl_vec<hidl_string> fqInstanceNames;
+ // copying out for timeoutIPC
+ auto listRet = timeoutIPC(manager, &IServiceManager::list, [&] (const auto &names) {
+ fqInstanceNames = names;
});
if (!listRet.isOk()) {
mErr << "Error: Failed to list services for " << mode << ": "
<< listRet.description() << std::endl;
- status |= DUMP_BINDERIZED_ERROR;
+ return DUMP_BINDERIZED_ERROR;
+ }
+
+ Status status = OK;
+ // server pid, .ptr value of binder object, child pids
+ std::map<std::string, DebugInfo> allDebugInfos;
+ std::map<pid_t, std::map<uint64_t, Pids>> allPids;
+ for (const auto &fqInstanceName : fqInstanceNames) {
+ const auto pair = splitFirst(fqInstanceName, '/');
+ const auto &serviceName = pair.first;
+ const auto &instanceName = pair.second;
+ auto getRet = timeoutIPC(manager, &IServiceManager::get, serviceName, instanceName);
+ if (!getRet.isOk()) {
+ mErr << "Warning: Skipping \"" << fqInstanceName << "\": "
+ << "cannot be fetched from service manager:"
+ << getRet.description() << std::endl;
+ status |= DUMP_BINDERIZED_ERROR;
+ continue;
+ }
+ sp<IBase> service = getRet;
+ if (service == nullptr) {
+ mErr << "Warning: Skipping \"" << fqInstanceName << "\": "
+ << "cannot be fetched from service manager (null)";
+ status |= DUMP_BINDERIZED_ERROR;
+ continue;
+ }
+ auto debugRet = timeoutIPC(service, &IBase::getDebugInfo, [&] (const auto &debugInfo) {
+ allDebugInfos[fqInstanceName] = debugInfo;
+ if (debugInfo.pid >= 0) {
+ allPids[static_cast<pid_t>(debugInfo.pid)].clear();
+ }
+ });
+ if (!debugRet.isOk()) {
+ mErr << "Warning: Skipping \"" << fqInstanceName << "\": "
+ << "debugging information cannot be retrieved:"
+ << debugRet.description() << std::endl;
+ status |= DUMP_BINDERIZED_ERROR;
+ }
+ }
+ for (auto &pair : allPids) {
+ pid_t serverPid = pair.first;
+ if (!getReferencedPids(serverPid, &allPids[serverPid])) {
+ mErr << "Warning: no information for PID " << serverPid
+ << ", are you root?" << std::endl;
+ status |= DUMP_BINDERIZED_ERROR;
+ }
+ }
+ for (const auto &fqInstanceName : fqInstanceNames) {
+ auto it = allDebugInfos.find(fqInstanceName);
+ if (it == allDebugInfos.end()) {
+ putEntry({
+ .interfaceName = fqInstanceName,
+ .transport = mode,
+ .serverPid = NO_PID,
+ .serverObjectAddress = NO_PTR,
+ .clientPids = {},
+ .source = HWSERVICEMANAGER_LIST
+ });
+ continue;
+ }
+ const DebugInfo &info = it->second;
+ putEntry({
+ .interfaceName = fqInstanceName,
+ .transport = mode,
+ .serverPid = info.pid,
+ .serverObjectAddress = info.ptr,
+ .clientPids = info.pid == NO_PID || info.ptr == NO_PTR
+ ? Pids{} : allPids[info.pid][info.ptr],
+ .source = HWSERVICEMANAGER_LIST
+ });
}
return status;
}
@@ -367,7 +472,7 @@
<< " Dump all hals with default ordering and columns [-itpc]." << std::endl
<< " lshal [--interface|-i] [--transport|-t]" << std::endl
<< " [--pid|-p] [--address|-a] [--clients|-c] [--cmdline|-m]" << std::endl
- << " [--sort={interface|i|pid|p}]" << std::endl
+ << " [--sort={interface|i|pid|p}] [--init-vintf[=path]]" << std::endl
<< " -i, --interface: print the interface name column" << std::endl
<< " -n, --instance: print the instance name column" << std::endl
<< " -t, --transport: print the transport mode column" << std::endl
@@ -378,6 +483,8 @@
<< " -m, --cmdline: print cmdline instead of PIDs" << std::endl
<< " --sort=i, --sort=interface: sort by interface name" << std::endl
<< " --sort=p, --sort=pid: sort by server pid" << std::endl
+ << " --init-vintf=path: form a skeleton HAL manifest to specified file " << std::endl
+ << " (stdout if no file specified)" << std::endl
<< " lshal [-h|--help]" << std::endl
<< " -h, --help: show this help information." << std::endl;
}
@@ -395,6 +502,7 @@
// long options without short alternatives
{"sort", required_argument, 0, 's' },
+ {"init-vintf",optional_argument, 0, 'v' },
{ 0, 0, 0, 0 }
};
@@ -420,6 +528,17 @@
}
break;
}
+ case 'v': {
+ if (optarg) {
+ mFileOutput = new std::ofstream{optarg};
+ mOut = mFileOutput;
+ if (!mFileOutput.buf().is_open()) {
+ mErr << "Could not open file '" << optarg << "'." << std::endl;
+ return IO_ERROR;
+ }
+ }
+ mVintf = true;
+ }
case 'i': {
mSelectedColumns |= ENABLE_INTERFACE_NAME;
break;
diff --git a/cmds/lshal/Lshal.h b/cmds/lshal/Lshal.h
index ead99dc..1c30908 100644
--- a/cmds/lshal/Lshal.h
+++ b/cmds/lshal/Lshal.h
@@ -19,12 +19,13 @@
#include <stdint.h>
-#include <iostream>
+#include <fstream>
#include <string>
#include <vector>
#include <android/hidl/manager/1.0/IServiceManager.h>
+#include "NullableOStream.h"
#include "TableEntry.h"
namespace android {
@@ -38,6 +39,7 @@
DUMP_BINDERIZED_ERROR = 1 << 3,
DUMP_PASSTHROUGH_ERROR = 1 << 4,
DUMP_ALL_LIBS_ERROR = 1 << 5,
+ IO_ERROR = 1 << 6,
};
using Status = unsigned int;
@@ -49,7 +51,7 @@
Status parseArgs(int argc, char **argv);
Status fetch();
void postprocess();
- void dump() const;
+ void dump();
void usage() const;
void putEntry(TableEntry &&entry);
Status fetchPassthrough(const sp<::android::hidl::manager::V1_0::IServiceManager> &manager);
@@ -57,6 +59,8 @@
Status fetchAllLibraries(const sp<::android::hidl::manager::V1_0::IServiceManager> &manager);
bool getReferencedPids(
pid_t serverPid, std::map<uint64_t, Pids> *objects) const;
+ void dumpTable() const;
+ void dumpVintf() const;
void printLine(
const std::string &interfaceName,
const std::string &transport, const std::string &server,
@@ -70,12 +74,14 @@
void removeDeadProcesses(Pids *pids);
Table mTable{};
- std::ostream &mErr = std::cerr;
- std::ostream &mOut = std::cout;
+ NullableOStream<std::ostream> mErr = std::cerr;
+ NullableOStream<std::ostream> mOut = std::cout;
+ NullableOStream<std::ofstream> mFileOutput = nullptr;
TableEntryCompare mSortColumn = nullptr;
TableEntrySelect mSelectedColumns = 0;
// If true, cmdlines will be printed instead of pid.
- bool mEnableCmdlines;
+ bool mEnableCmdlines = false;
+ bool mVintf = false;
// If an entry does not exist, need to ask /proc/{pid}/cmdline to get it.
// If an entry exist but is an empty string, process might have died.
// If an entry exist and not empty, it contains the cached content of /proc/{pid}/cmdline.
diff --git a/cmds/lshal/NullableOStream.h b/cmds/lshal/NullableOStream.h
new file mode 100644
index 0000000..ab37a04
--- /dev/null
+++ b/cmds/lshal/NullableOStream.h
@@ -0,0 +1,73 @@
+/*
+ * 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.
+ */
+
+#ifndef FRAMEWORK_NATIVE_CMDS_LSHAL_NULLABLE_O_STREAM_H_
+#define FRAMEWORK_NATIVE_CMDS_LSHAL_NULLABLE_O_STREAM_H_
+
+#include <iostream>
+
+namespace android {
+namespace lshal {
+
+template<typename S>
+class NullableOStream {
+public:
+ NullableOStream(S &os) : mOs(&os) {}
+ NullableOStream(S *os) : mOs(os) {}
+ NullableOStream &operator=(S &os) {
+ mOs = &os;
+ return *this;
+ }
+ NullableOStream &operator=(S *os) {
+ mOs = os;
+ return *this;
+ }
+ template<typename Other>
+ NullableOStream &operator=(const NullableOStream<Other> &other) {
+ mOs = other.mOs;
+ return *this;
+ }
+
+ const NullableOStream &operator<<(std::ostream& (*pf)(std::ostream&)) const {
+ if (mOs) {
+ (*mOs) << pf;
+ }
+ return *this;
+ }
+ template<typename T>
+ const NullableOStream &operator<<(const T &rhs) const {
+ if (mOs) {
+ (*mOs) << rhs;
+ }
+ return *this;
+ }
+ S& buf() const {
+ return *mOs;
+ }
+ operator bool() const {
+ return mOs != nullptr;
+ }
+private:
+ template<typename>
+ friend class NullableOStream;
+
+ S *mOs = nullptr;
+};
+
+} // namespace lshal
+} // namespace android
+
+#endif // FRAMEWORK_NATIVE_CMDS_LSHAL_NULLABLE_O_STREAM_H_
diff --git a/cmds/lshal/TableEntry.h b/cmds/lshal/TableEntry.h
index 4ec3a0c..e55806e 100644
--- a/cmds/lshal/TableEntry.h
+++ b/cmds/lshal/TableEntry.h
@@ -28,6 +28,13 @@
using Pids = std::vector<int32_t>;
+enum : unsigned int {
+ HWSERVICEMANAGER_LIST, // through defaultServiceManager()->list()
+ PTSERVICEMANAGER_REG_CLIENT, // through registerPassthroughClient
+ LIST_DLLIB, // through listing dynamic libraries
+};
+using TableEntrySource = unsigned int;
+
struct TableEntry {
std::string interfaceName;
std::string transport;
@@ -36,6 +43,7 @@
uint64_t serverObjectAddress;
Pids clientPids;
std::vector<std::string> clientCmdlines;
+ TableEntrySource source;
static bool sortByInterfaceName(const TableEntry &a, const TableEntry &b) {
return a.interfaceName < b.interfaceName;
diff --git a/cmds/surfacereplayer/replayer/Replayer.cpp b/cmds/surfacereplayer/replayer/Replayer.cpp
index a49da37..35b63ec 100644
--- a/cmds/surfacereplayer/replayer/Replayer.cpp
+++ b/cmds/surfacereplayer/replayer/Replayer.cpp
@@ -22,8 +22,6 @@
#include <android-base/file.h>
-#include <binder/IMemory.h>
-
#include <gui/BufferQueue.h>
#include <gui/ISurfaceComposer.h>
#include <gui/Surface.h>
diff --git a/include/android/sensor.h b/include/android/sensor.h
index 4a00818..a5e5c05 100644
--- a/include/android/sensor.h
+++ b/include/android/sensor.h
@@ -56,6 +56,7 @@
extern "C" {
#endif
+typedef struct AHardwareBuffer AHardwareBuffer;
/**
* Sensor types.
@@ -144,6 +145,30 @@
AREPORTING_MODE_SPECIAL_TRIGGER = 3
};
+/**
+ * Sensor Direct Report Rates.
+ */
+enum {
+ /** stopped */
+ ASENSOR_DIRECT_RATE_STOP = 0,
+ /** nominal 50Hz */
+ ASENSOR_DIRECT_RATE_NORMAL = 1,
+ /** nominal 200Hz */
+ ASENSOR_DIRECT_RATE_FAST = 2,
+ /** nominal 800Hz */
+ ASENSOR_DIRECT_RATE_VERY_FAST = 3
+};
+
+/**
+ * Sensor Direct Channel Type.
+ */
+enum {
+ /** shared memory created by ASharedMemory_create */
+ ASENSOR_DIRECT_CHANNEL_TYPE_SHARED_MEMORY = 1,
+ /** AHardwareBuffer */
+ ASENSOR_DIRECT_CHANNEL_TYPE_HARDWARE_BUFFER = 2
+};
+
/*
* A few useful constants
*/
@@ -391,6 +416,97 @@
*/
int ASensorManager_destroyEventQueue(ASensorManager* manager, ASensorEventQueue* queue);
+#if __ANDROID_API__ >= __ANDROID_API_O__
+/**
+ * Create direct channel based on shared memory
+ *
+ * Create a direct channel of {@link ASENSOR_DIRECT_CHANNEL_TYPE_SHARED_MEMORY} to be used
+ * for configuring sensor direct report.
+ *
+ * \param manager the {@link ASensorManager} instance obtained from
+ * {@link ASensorManager_getInstanceForPackage}.
+ * \param fd file descriptor representing a shared memory created by
+ * {@link ASharedMemory_create}
+ * \param size size to be used, must be less or equal to size of shared memory.
+ *
+ * \return a positive integer as a channel id to be used in
+ * {@link ASensorManager_destroyDirectChannel} and
+ * {@link ASensorManager_configureDirectReport}, or value less or equal to 0 for failures.
+ */
+int ASensorManager_createSharedMemoryDirectChannel(ASensorManager* manager, int fd, size_t size);
+
+/**
+ * Create direct channel based on AHardwareBuffer
+ *
+ * Create a direct channel of {@link ASENSOR_DIRECT_CHANNEL_TYPE_HARDWARE_BUFFER} type to be used
+ * for configuring sensor direct report.
+ *
+ * \param manager the {@link ASensorManager} instance obtained from
+ * {@link ASensorManager_getInstanceForPackage}.
+ * \param buffer {@link AHardwareBuffer} instance created by {@link AHardwareBuffer_allocate}.
+ * \param size the intended size to be used, must be less or equal to size of buffer.
+ *
+ * \return a positive integer as a channel id to be used in
+ * {@link ASensorManager_destroyDirectChannel} and
+ * {@link ASensorManager_configureDirectReport}, or value less or equal to 0 for failures.
+ */
+int ASensorManager_createHardwareBufferDirectChannel(
+ ASensorManager* manager, AHardwareBuffer const * buffer, size_t size);
+
+/**
+ * Destroy a direct channel
+ *
+ * Destroy a direct channel previously created using {@link ASensorManager_createDirectChannel}.
+ * The buffer used for creating direct channel does not get destroyed with
+ * {@link ASensorManager_destroy} and has to be close or released separately.
+ *
+ * \param manager the {@link ASensorManager} instance obtained from
+ * {@link ASensorManager_getInstanceForPackage}.
+ * \param channelId channel id (a positive integer) returned from
+ * {@link ASensorManager_createSharedMemoryDirectChannel} or
+ * {@link ASensorManager_createHardwareBufferDirectChannel}.
+ */
+void ASensorManager_destroyDirectChannel(ASensorManager* manager, int channelId);
+
+/**
+ * Configure direct report on channel
+ *
+ * Configure sensor direct report on a direct channel: set rate to value other than
+ * {@link ASENSOR_DIRECT_RATE_STOP} so that sensor event can be directly
+ * written into the shared memory region used for creating the buffer; set rate to
+ * {@link ASENSOR_DIRECT_RATE_STOP} will stop the sensor direct report.
+ *
+ * To stop all active sensor direct report configured to a channel, set sensor to NULL and rate to
+ * {@link ASENSOR_DIRECT_RATE_STOP}.
+ *
+ * In order to successfully configure a direct report, the sensor has to support the specified rate
+ * and the channel type, which can be checked by {@link ASensor_getHighestDirectReportRateLevel} and
+ * {@link ASensor_isDirectChannelTypeSupported}, respectively.
+ *
+ * Example:
+ * \code{.cpp}
+ * ASensorManager *manager = ...;
+ * ASensor *sensor = ...;
+ * int channelId = ...;
+ *
+ * ASensorManager_configureDirectReport(
+ * manager, sensor, channel_id, ASENSOR_DIRECT_RATE_FAST);
+ * \endcode
+ *
+ * \param manager the {@link ASensorManager} instance obtained from
+ * {@link ASensorManager_getInstanceForPackage}.
+ * \param sensor a {@link ASensor} to denote which sensor to be operate. It can be NULL if rate
+ * is {@link ASENSOR_DIRECT_RATE_STOP}, denoting stopping of all active sensor
+ * direct report.
+ * \param channelId channel id (a positive integer) returned from
+ * {@link ASensorManager_createSharedMemoryDirectChannel} or
+ * {@link ASensorManager_createHardwareBufferDirectChannel}.
+ *
+ * \return 0 for success or negative integer for failure.
+ */
+int ASensorManager_configureDirectReport(
+ ASensorManager* manager, ASensor const* sensor, int channelId, int rate);
+#endif
/*****************************************************************************/
@@ -502,6 +618,29 @@
bool ASensor_isWakeUpSensor(ASensor const* sensor);
#endif /* __ANDROID_API__ >= 21 */
+#if __ANDROID_API__ >= __ANDROID_API_O__
+/**
+ * Test if sensor supports a certain type of direct channel.
+ *
+ * \param sensor a {@link ASensor} to denote the sensor to be checked.
+ * \param channelType Channel type constant, either
+ * {@ASENSOR_DIRECT_CHANNEL_TYPE_SHARED_MEMORY}
+ * or {@link ASENSOR_DIRECT_CHANNEL_TYPE_HARDWARE_BUFFER}.
+ * \returns true if sensor supports the specified direct channel type.
+ */
+bool ASensor_isDirectChannelTypeSupported(ASensor const* sensor, int channelType);
+/**
+ * Get the highest direct rate level that a sensor support.
+ *
+ * \param sensor a {@link ASensor} to denote the sensor to be checked.
+ *
+ * \return a ASENSOR_DIRECT_RATE_... enum denoting the highest rate level supported by the sensor.
+ * If return value is {@link ASENSOR_DIRECT_RATE_STOP}, it means the sensor
+ * does not support direct report.
+ */
+int ASensor_getHighestDirectReportRateLevel(ASensor const* sensor);
+#endif
+
#ifdef __cplusplus
};
#endif
diff --git a/include/gui/SurfaceComposerClient.h b/include/gui/SurfaceComposerClient.h
index 8302160..1e8cf76 100644
--- a/include/gui/SurfaceComposerClient.h
+++ b/include/gui/SurfaceComposerClient.h
@@ -21,7 +21,6 @@
#include <sys/types.h>
#include <binder/IBinder.h>
-#include <binder/IMemory.h>
#include <utils/RefBase.h>
#include <utils/Singleton.h>
@@ -148,7 +147,7 @@
status_t setTransparentRegionHint(const sp<IBinder>& id, const Region& transparent);
status_t setLayer(const sp<IBinder>& id, int32_t layer);
status_t setAlpha(const sp<IBinder>& id, float alpha=1.0f);
- status_t setMatrix(const sp<IBinder>& id, float dsdx, float dtdx, float dsdy, float dtdy);
+ status_t setMatrix(const sp<IBinder>& id, float dsdx, float dtdx, float dtdy, float dsdy);
status_t setPosition(const sp<IBinder>& id, float x, float y);
status_t setSize(const sp<IBinder>& id, uint32_t w, uint32_t h);
status_t setCrop(const sp<IBinder>& id, const Rect& crop);
@@ -156,8 +155,11 @@
status_t setLayerStack(const sp<IBinder>& id, uint32_t layerStack);
status_t deferTransactionUntil(const sp<IBinder>& id,
const sp<IBinder>& handle, uint64_t frameNumber);
+ status_t deferTransactionUntil(const sp<IBinder>& id,
+ const sp<Surface>& handle, uint64_t frameNumber);
status_t reparentChildren(const sp<IBinder>& id,
const sp<IBinder>& newParentHandle);
+ status_t detachChildren(const sp<IBinder>& id);
status_t setOverrideScalingMode(const sp<IBinder>& id,
int32_t overrideScalingMode);
status_t setGeometryAppliesWithResize(const sp<IBinder>& id);
diff --git a/include/gui/SurfaceControl.h b/include/gui/SurfaceControl.h
index 54c8fa9..8ee35bc 100644
--- a/include/gui/SurfaceControl.h
+++ b/include/gui/SurfaceControl.h
@@ -69,7 +69,7 @@
status_t setFlags(uint32_t flags, uint32_t mask);
status_t setTransparentRegionHint(const Region& transparent);
status_t setAlpha(float alpha=1.0f);
- status_t setMatrix(float dsdx, float dtdx, float dsdy, float dtdy);
+ status_t setMatrix(float dsdx, float dtdx, float dtdy, float dsdy);
status_t setCrop(const Rect& crop);
status_t setFinalCrop(const Rect& crop);
@@ -80,11 +80,31 @@
status_t setGeometryAppliesWithResize();
// Defers applying any changes made in this transaction until the Layer
- // identified by handle reaches the given frameNumber
+ // identified by handle reaches the given frameNumber. If the Layer identified
+ // by handle is removed, then we will apply this transaction regardless of
+ // what frame number has been reached.
status_t deferTransactionUntil(const sp<IBinder>& handle, uint64_t frameNumber);
+
+ // A variant of deferTransactionUntil which identifies the Layer we wait for by
+ // Surface instead of Handle. Useful for clients which may not have the
+ // SurfaceControl for some of their Surfaces. Otherwise behaves identically.
+ status_t deferTransactionUntil(const sp<Surface>& barrier, uint64_t frameNumber);
+
// Reparents all children of this layer to the new parent handle.
status_t reparentChildren(const sp<IBinder>& newParentHandle);
+ // Detaches all child surfaces (and their children recursively)
+ // from their SurfaceControl.
+ // The child SurfaceControl's will not throw exceptions or return errors,
+ // but transactions will have no effect.
+ // The child surfaces will continue to follow their parent surfaces,
+ // and remain eligible for rendering, but their relative state will be
+ // frozen. We use this in the WindowManager, in app shutdown/relaunch
+ // scenarios, where the app would otherwise clean up its child Surfaces.
+ // Sometimes the WindowManager needs to extend their lifetime slightly
+ // in order to perform an exit animation or prevent flicker.
+ status_t detachChildren();
+
// Set an override scaling mode as documented in <system/window.h>
// the override scaling mode will take precedence over any client
// specified scaling mode. -1 will clear the override scaling mode.
diff --git a/include/private/binder/Static.h b/include/private/binder/Static.h
index d104646..3d10456 100644
--- a/include/private/binder/Static.h
+++ b/include/private/binder/Static.h
@@ -20,7 +20,6 @@
#include <utils/threads.h>
#include <binder/IBinder.h>
-#include <binder/IMemory.h>
#include <binder/ProcessState.h>
#include <binder/IPermissionController.h>
#include <binder/IServiceManager.h>
diff --git a/include/private/gui/LayerState.h b/include/private/gui/LayerState.h
index 2a1801b..20f51a5 100644
--- a/include/private/gui/LayerState.h
+++ b/include/private/gui/LayerState.h
@@ -24,6 +24,7 @@
#include <ui/Region.h>
#include <ui/Rect.h>
+#include <gui/IGraphicBufferProducer.h>
namespace android {
@@ -57,6 +58,7 @@
eOverrideScalingModeChanged = 0x00000800,
eGeometryAppliesWithResize = 0x00001000,
eReparentChildren = 0x00002000,
+ eDetachChildren = 0x00004000
};
layer_state_t()
@@ -77,8 +79,8 @@
struct matrix22_t {
float dsdx{0};
float dtdx{0};
- float dsdy{0};
float dtdy{0};
+ float dsdy{0};
};
sp<IBinder> surface;
uint32_t what;
@@ -95,10 +97,13 @@
matrix22_t matrix;
Rect crop;
Rect finalCrop;
- sp<IBinder> handle;
+ sp<IBinder> barrierHandle;
sp<IBinder> reparentHandle;
uint64_t frameNumber;
int32_t overrideScalingMode;
+
+ sp<IGraphicBufferProducer> barrierGbp;
+
// non POD must be last. see write/read
Region transparentRegion;
};
diff --git a/libs/gui/ISurfaceComposer.cpp b/libs/gui/ISurfaceComposer.cpp
index 06d1261..4d2692f 100644
--- a/libs/gui/ISurfaceComposer.cpp
+++ b/libs/gui/ISurfaceComposer.cpp
@@ -21,7 +21,6 @@
#include <sys/types.h>
#include <binder/Parcel.h>
-#include <binder/IMemory.h>
#include <binder/IPCThreadState.h>
#include <binder/IServiceManager.h>
diff --git a/libs/gui/ISurfaceComposerClient.cpp b/libs/gui/ISurfaceComposerClient.cpp
index 5a3fa04..db8a517 100644
--- a/libs/gui/ISurfaceComposerClient.cpp
+++ b/libs/gui/ISurfaceComposerClient.cpp
@@ -22,7 +22,6 @@
#include <sys/types.h>
#include <binder/Parcel.h>
-#include <binder/IMemory.h>
#include <binder/IPCThreadState.h>
#include <binder/IServiceManager.h>
diff --git a/libs/gui/LayerState.cpp b/libs/gui/LayerState.cpp
index bb552aa..2461cba 100644
--- a/libs/gui/LayerState.cpp
+++ b/libs/gui/LayerState.cpp
@@ -39,10 +39,11 @@
output.writeInplace(sizeof(layer_state_t::matrix22_t))) = matrix;
output.write(crop);
output.write(finalCrop);
- output.writeStrongBinder(handle);
+ output.writeStrongBinder(barrierHandle);
output.writeStrongBinder(reparentHandle);
output.writeUint64(frameNumber);
output.writeInt32(overrideScalingMode);
+ output.writeStrongBinder(IInterface::asBinder(barrierGbp));
output.write(transparentRegion);
return NO_ERROR;
}
@@ -68,10 +69,12 @@
}
input.read(crop);
input.read(finalCrop);
- handle = input.readStrongBinder();
+ barrierHandle = input.readStrongBinder();
reparentHandle = input.readStrongBinder();
frameNumber = input.readUint64();
overrideScalingMode = input.readInt32();
+ barrierGbp =
+ interface_cast<IGraphicBufferProducer>(input.readStrongBinder());
input.read(transparentRegion);
return NO_ERROR;
}
diff --git a/libs/gui/SurfaceComposerClient.cpp b/libs/gui/SurfaceComposerClient.cpp
index ae81c8f..088933a 100644
--- a/libs/gui/SurfaceComposerClient.cpp
+++ b/libs/gui/SurfaceComposerClient.cpp
@@ -26,7 +26,6 @@
#include <utils/String8.h>
#include <utils/threads.h>
-#include <binder/IMemory.h>
#include <binder/IServiceManager.h>
#include <system/graphics.h>
@@ -38,6 +37,7 @@
#include <gui/IGraphicBufferProducer.h>
#include <gui/ISurfaceComposer.h>
#include <gui/ISurfaceComposerClient.h>
+#include <gui/Surface.h>
#include <gui/SurfaceComposerClient.h>
#include <private/gui/ComposerService.h>
@@ -157,7 +157,7 @@
status_t setAlpha(const sp<SurfaceComposerClient>& client, const sp<IBinder>& id,
float alpha);
status_t setMatrix(const sp<SurfaceComposerClient>& client, const sp<IBinder>& id,
- float dsdx, float dtdx, float dsdy, float dtdy);
+ float dsdx, float dtdx, float dtdy, float dsdy);
status_t setOrientation(int orientation);
status_t setCrop(const sp<SurfaceComposerClient>& client, const sp<IBinder>& id,
const Rect& crop);
@@ -168,9 +168,14 @@
status_t deferTransactionUntil(const sp<SurfaceComposerClient>& client,
const sp<IBinder>& id, const sp<IBinder>& handle,
uint64_t frameNumber);
+ status_t deferTransactionUntil(const sp<SurfaceComposerClient>& client,
+ const sp<IBinder>& id, const sp<Surface>& barrierSurface,
+ uint64_t frameNumber);
status_t reparentChildren(const sp<SurfaceComposerClient>& client,
const sp<IBinder>& id,
const sp<IBinder>& newParentHandle);
+ status_t detachChildren(const sp<SurfaceComposerClient>& client,
+ const sp<IBinder>& id);
status_t setOverrideScalingMode(const sp<SurfaceComposerClient>& client,
const sp<IBinder>& id, int32_t overrideScalingMode);
status_t setGeometryAppliesWithResize(const sp<SurfaceComposerClient>& client,
@@ -392,7 +397,7 @@
status_t Composer::setMatrix(const sp<SurfaceComposerClient>& client,
const sp<IBinder>& id, float dsdx, float dtdx,
- float dsdy, float dtdy) {
+ float dtdy, float dsdy) {
Mutex::Autolock _l(mLock);
layer_state_t* s = getLayerStateLocked(client, id);
if (!s)
@@ -439,7 +444,21 @@
return BAD_INDEX;
}
s->what |= layer_state_t::eDeferTransaction;
- s->handle = handle;
+ s->barrierHandle = handle;
+ s->frameNumber = frameNumber;
+ return NO_ERROR;
+}
+
+status_t Composer::deferTransactionUntil(
+ const sp<SurfaceComposerClient>& client, const sp<IBinder>& id,
+ const sp<Surface>& barrierSurface, uint64_t frameNumber) {
+ Mutex::Autolock lock(mLock);
+ layer_state_t* s = getLayerStateLocked(client, id);
+ if (!s) {
+ return BAD_INDEX;
+ }
+ s->what |= layer_state_t::eDeferTransaction;
+ s->barrierGbp = barrierSurface->getIGraphicBufferProducer();
s->frameNumber = frameNumber;
return NO_ERROR;
}
@@ -458,6 +477,18 @@
return NO_ERROR;
}
+status_t Composer::detachChildren(
+ const sp<SurfaceComposerClient>& client,
+ const sp<IBinder>& id) {
+ Mutex::Autolock lock(mLock);
+ layer_state_t* s = getLayerStateLocked(client, id);
+ if (!s) {
+ return BAD_INDEX;
+ }
+ s->what |= layer_state_t::eDetachChildren;
+ return NO_ERROR;
+}
+
status_t Composer::setOverrideScalingMode(
const sp<SurfaceComposerClient>& client,
const sp<IBinder>& id, int32_t overrideScalingMode) {
@@ -768,8 +799,8 @@
}
status_t SurfaceComposerClient::setMatrix(const sp<IBinder>& id, float dsdx, float dtdx,
- float dsdy, float dtdy) {
- return getComposer().setMatrix(this, id, dsdx, dtdx, dsdy, dtdy);
+ float dtdy, float dsdy) {
+ return getComposer().setMatrix(this, id, dsdx, dtdx, dtdy, dsdy);
}
status_t SurfaceComposerClient::deferTransactionUntil(const sp<IBinder>& id,
@@ -777,11 +808,20 @@
return getComposer().deferTransactionUntil(this, id, handle, frameNumber);
}
+status_t SurfaceComposerClient::deferTransactionUntil(const sp<IBinder>& id,
+ const sp<Surface>& barrierSurface, uint64_t frameNumber) {
+ return getComposer().deferTransactionUntil(this, id, barrierSurface, frameNumber);
+}
+
status_t SurfaceComposerClient::reparentChildren(const sp<IBinder>& id,
const sp<IBinder>& newParentHandle) {
return getComposer().reparentChildren(this, id, newParentHandle);
}
+status_t SurfaceComposerClient::detachChildren(const sp<IBinder>& id) {
+ return getComposer().detachChildren(this, id);
+}
+
status_t SurfaceComposerClient::setOverrideScalingMode(
const sp<IBinder>& id, int32_t overrideScalingMode) {
return getComposer().setOverrideScalingMode(
diff --git a/libs/gui/SurfaceControl.cpp b/libs/gui/SurfaceControl.cpp
index 0362216..1e69379 100644
--- a/libs/gui/SurfaceControl.cpp
+++ b/libs/gui/SurfaceControl.cpp
@@ -147,10 +147,10 @@
if (err < 0) return err;
return mClient->setAlpha(mHandle, alpha);
}
-status_t SurfaceControl::setMatrix(float dsdx, float dtdx, float dsdy, float dtdy) {
+status_t SurfaceControl::setMatrix(float dsdx, float dtdx, float dtdy, float dsdy) {
status_t err = validate();
if (err < 0) return err;
- return mClient->setMatrix(mHandle, dsdx, dtdx, dsdy, dtdy);
+ return mClient->setMatrix(mHandle, dsdx, dtdx, dtdy, dsdy);
}
status_t SurfaceControl::setCrop(const Rect& crop) {
status_t err = validate();
@@ -170,12 +170,25 @@
return mClient->deferTransactionUntil(mHandle, handle, frameNumber);
}
+status_t SurfaceControl::deferTransactionUntil(const sp<Surface>& handle,
+ uint64_t frameNumber) {
+ status_t err = validate();
+ if (err < 0) return err;
+ return mClient->deferTransactionUntil(mHandle, handle, frameNumber);
+}
+
status_t SurfaceControl::reparentChildren(const sp<IBinder>& newParentHandle) {
status_t err = validate();
if (err < 0) return err;
return mClient->reparentChildren(mHandle, newParentHandle);
}
+status_t SurfaceControl::detachChildren() {
+ status_t err = validate();
+ if (err < 0) return err;
+ return mClient->detachChildren(mHandle);
+}
+
status_t SurfaceControl::setOverrideScalingMode(int32_t overrideScalingMode) {
status_t err = validate();
if (err < 0) return err;
diff --git a/libs/gui/tests/Surface_test.cpp b/libs/gui/tests/Surface_test.cpp
index ceeb90a..012dbe7 100644
--- a/libs/gui/tests/Surface_test.cpp
+++ b/libs/gui/tests/Surface_test.cpp
@@ -18,7 +18,6 @@
#include <gtest/gtest.h>
-#include <binder/IMemory.h>
#include <binder/ProcessState.h>
#include <gui/IDisplayEventConnection.h>
#include <gui/ISurfaceComposer.h>
diff --git a/libs/nativewindow/AHardwareBuffer.cpp b/libs/nativewindow/AHardwareBuffer.cpp
index b4b5303..3fbab17 100644
--- a/libs/nativewindow/AHardwareBuffer.cpp
+++ b/libs/nativewindow/AHardwareBuffer.cpp
@@ -57,7 +57,8 @@
uint64_t producerUsage = 0;
uint64_t consumerUsage = 0;
- AHardwareBuffer_convertToGrallocUsageBits(desc->usage0, &producerUsage, &consumerUsage);
+ AHardwareBuffer_convertToGrallocUsageBits(&producerUsage, &consumerUsage, desc->usage0,
+ desc->usage1);
sp<GraphicBuffer> gbuffer(new GraphicBuffer(
desc->width, desc->height, format, desc->layers, producerUsage, consumerUsage,
@@ -97,9 +98,8 @@
outDesc->width = gbuffer->getWidth();
outDesc->height = gbuffer->getHeight();
outDesc->layers = gbuffer->getLayerCount();
- outDesc->usage0 = AHardwareBuffer_convertFromGrallocUsageBits(
+ AHardwareBuffer_convertFromGrallocUsageBits(&outDesc->usage0, &outDesc->usage1,
gbuffer->getUsage(), gbuffer->getUsage());
- outDesc->usage1 = 0;
outDesc->format = AHardwareBuffer_convertFromPixelFormat(
static_cast<uint32_t>(gbuffer->getPixelFormat()));
}
@@ -117,7 +117,7 @@
uint64_t producerUsage = 0;
uint64_t consumerUsage = 0;
- AHardwareBuffer_convertToGrallocUsageBits(usage0, &producerUsage, &consumerUsage);
+ AHardwareBuffer_convertToGrallocUsageBits(&producerUsage, &consumerUsage, usage0, 0);
GraphicBuffer* gBuffer = AHardwareBuffer_to_GraphicBuffer(buffer);
Rect bounds;
if (!rect) {
@@ -268,8 +268,76 @@
namespace android {
+// A 1:1 mapping of AHardwaqreBuffer bitmasks to gralloc1 bitmasks.
+struct UsageMaskMapping {
+ uint64_t hardwareBufferMask;
+ uint64_t grallocMask;
+};
+
+static constexpr UsageMaskMapping kUsage0ProducerMapping[] = {
+ { AHARDWAREBUFFER_USAGE0_CPU_WRITE, GRALLOC1_PRODUCER_USAGE_CPU_WRITE },
+ { AHARDWAREBUFFER_USAGE0_CPU_WRITE_OFTEN, GRALLOC1_PRODUCER_USAGE_CPU_WRITE_OFTEN },
+ { AHARDWAREBUFFER_USAGE0_GPU_COLOR_OUTPUT, GRALLOC1_PRODUCER_USAGE_GPU_RENDER_TARGET },
+ { AHARDWAREBUFFER_USAGE0_PROTECTED_CONTENT, GRALLOC1_PRODUCER_USAGE_PROTECTED },
+ { AHARDWAREBUFFER_USAGE0_SENSOR_DIRECT_DATA, GRALLOC1_PRODUCER_USAGE_SENSOR_DIRECT_DATA },
+};
+
+static constexpr UsageMaskMapping kUsage1ProducerMapping[] = {
+ { AHARDWAREBUFFER_USAGE1_PRODUCER_PRIVATE_0, GRALLOC1_PRODUCER_USAGE_PRIVATE_0 },
+ { AHARDWAREBUFFER_USAGE1_PRODUCER_PRIVATE_1, GRALLOC1_PRODUCER_USAGE_PRIVATE_1 },
+ { AHARDWAREBUFFER_USAGE1_PRODUCER_PRIVATE_2, GRALLOC1_PRODUCER_USAGE_PRIVATE_2 },
+ { AHARDWAREBUFFER_USAGE1_PRODUCER_PRIVATE_3, GRALLOC1_PRODUCER_USAGE_PRIVATE_3 },
+ { AHARDWAREBUFFER_USAGE1_PRODUCER_PRIVATE_4, GRALLOC1_PRODUCER_USAGE_PRIVATE_4 },
+ { AHARDWAREBUFFER_USAGE1_PRODUCER_PRIVATE_5, GRALLOC1_PRODUCER_USAGE_PRIVATE_5 },
+ { AHARDWAREBUFFER_USAGE1_PRODUCER_PRIVATE_6, GRALLOC1_PRODUCER_USAGE_PRIVATE_6 },
+ { AHARDWAREBUFFER_USAGE1_PRODUCER_PRIVATE_7, GRALLOC1_PRODUCER_USAGE_PRIVATE_7 },
+ { AHARDWAREBUFFER_USAGE1_PRODUCER_PRIVATE_8, GRALLOC1_PRODUCER_USAGE_PRIVATE_8 },
+ { AHARDWAREBUFFER_USAGE1_PRODUCER_PRIVATE_9, GRALLOC1_PRODUCER_USAGE_PRIVATE_9 },
+ { AHARDWAREBUFFER_USAGE1_PRODUCER_PRIVATE_10, GRALLOC1_PRODUCER_USAGE_PRIVATE_10 },
+ { AHARDWAREBUFFER_USAGE1_PRODUCER_PRIVATE_11, GRALLOC1_PRODUCER_USAGE_PRIVATE_11 },
+ { AHARDWAREBUFFER_USAGE1_PRODUCER_PRIVATE_12, GRALLOC1_PRODUCER_USAGE_PRIVATE_12 },
+ { AHARDWAREBUFFER_USAGE1_PRODUCER_PRIVATE_13, GRALLOC1_PRODUCER_USAGE_PRIVATE_13 },
+ { AHARDWAREBUFFER_USAGE1_PRODUCER_PRIVATE_14, GRALLOC1_PRODUCER_USAGE_PRIVATE_14 },
+ { AHARDWAREBUFFER_USAGE1_PRODUCER_PRIVATE_15, GRALLOC1_PRODUCER_USAGE_PRIVATE_15 },
+ { AHARDWAREBUFFER_USAGE1_PRODUCER_PRIVATE_16, GRALLOC1_PRODUCER_USAGE_PRIVATE_16 },
+ { AHARDWAREBUFFER_USAGE1_PRODUCER_PRIVATE_17, GRALLOC1_PRODUCER_USAGE_PRIVATE_17 },
+ { AHARDWAREBUFFER_USAGE1_PRODUCER_PRIVATE_18, GRALLOC1_PRODUCER_USAGE_PRIVATE_18 },
+ { AHARDWAREBUFFER_USAGE1_PRODUCER_PRIVATE_19, GRALLOC1_PRODUCER_USAGE_PRIVATE_19 },
+};
+
+static constexpr UsageMaskMapping kUsage0ConsumerMapping[] = {
+ { AHARDWAREBUFFER_USAGE0_CPU_READ, GRALLOC1_CONSUMER_USAGE_CPU_READ },
+ { AHARDWAREBUFFER_USAGE0_CPU_READ_OFTEN, GRALLOC1_CONSUMER_USAGE_CPU_READ_OFTEN },
+ { AHARDWAREBUFFER_USAGE0_GPU_SAMPLED_IMAGE, GRALLOC1_CONSUMER_USAGE_GPU_TEXTURE },
+ { AHARDWAREBUFFER_USAGE0_GPU_DATA_BUFFER, GRALLOC1_CONSUMER_USAGE_GPU_DATA_BUFFER },
+ { AHARDWAREBUFFER_USAGE0_VIDEO_ENCODE, GRALLOC1_CONSUMER_USAGE_VIDEO_ENCODER },
+};
+
+static constexpr UsageMaskMapping kUsage1ConsumerMapping[] = {
+ { AHARDWAREBUFFER_USAGE1_CONSUMER_PRIVATE_0, GRALLOC1_CONSUMER_USAGE_PRIVATE_0 },
+ { AHARDWAREBUFFER_USAGE1_CONSUMER_PRIVATE_1, GRALLOC1_CONSUMER_USAGE_PRIVATE_1 },
+ { AHARDWAREBUFFER_USAGE1_CONSUMER_PRIVATE_2, GRALLOC1_CONSUMER_USAGE_PRIVATE_2 },
+ { AHARDWAREBUFFER_USAGE1_CONSUMER_PRIVATE_3, GRALLOC1_CONSUMER_USAGE_PRIVATE_3 },
+ { AHARDWAREBUFFER_USAGE1_CONSUMER_PRIVATE_4, GRALLOC1_CONSUMER_USAGE_PRIVATE_4 },
+ { AHARDWAREBUFFER_USAGE1_CONSUMER_PRIVATE_5, GRALLOC1_CONSUMER_USAGE_PRIVATE_5 },
+ { AHARDWAREBUFFER_USAGE1_CONSUMER_PRIVATE_6, GRALLOC1_CONSUMER_USAGE_PRIVATE_6 },
+ { AHARDWAREBUFFER_USAGE1_CONSUMER_PRIVATE_7, GRALLOC1_CONSUMER_USAGE_PRIVATE_7 },
+ { AHARDWAREBUFFER_USAGE1_CONSUMER_PRIVATE_8, GRALLOC1_CONSUMER_USAGE_PRIVATE_8 },
+ { AHARDWAREBUFFER_USAGE1_CONSUMER_PRIVATE_9, GRALLOC1_CONSUMER_USAGE_PRIVATE_9 },
+ { AHARDWAREBUFFER_USAGE1_CONSUMER_PRIVATE_10, GRALLOC1_CONSUMER_USAGE_PRIVATE_10 },
+ { AHARDWAREBUFFER_USAGE1_CONSUMER_PRIVATE_11, GRALLOC1_CONSUMER_USAGE_PRIVATE_11 },
+ { AHARDWAREBUFFER_USAGE1_CONSUMER_PRIVATE_12, GRALLOC1_CONSUMER_USAGE_PRIVATE_12 },
+ { AHARDWAREBUFFER_USAGE1_CONSUMER_PRIVATE_13, GRALLOC1_CONSUMER_USAGE_PRIVATE_13 },
+ { AHARDWAREBUFFER_USAGE1_CONSUMER_PRIVATE_14, GRALLOC1_CONSUMER_USAGE_PRIVATE_14 },
+ { AHARDWAREBUFFER_USAGE1_CONSUMER_PRIVATE_15, GRALLOC1_CONSUMER_USAGE_PRIVATE_15 },
+ { AHARDWAREBUFFER_USAGE1_CONSUMER_PRIVATE_16, GRALLOC1_CONSUMER_USAGE_PRIVATE_16 },
+ { AHARDWAREBUFFER_USAGE1_CONSUMER_PRIVATE_17, GRALLOC1_CONSUMER_USAGE_PRIVATE_17 },
+ { AHARDWAREBUFFER_USAGE1_CONSUMER_PRIVATE_18, GRALLOC1_CONSUMER_USAGE_PRIVATE_18 },
+ { AHARDWAREBUFFER_USAGE1_CONSUMER_PRIVATE_19, GRALLOC1_CONSUMER_USAGE_PRIVATE_19 },
+};
+
static inline bool containsBits(uint64_t mask, uint64_t bitsToCheck) {
- return (mask & bitsToCheck) == bitsToCheck;
+ return (mask & bitsToCheck) == bitsToCheck && bitsToCheck;
}
uint32_t AHardwareBuffer_convertFromPixelFormat(uint32_t format) {
@@ -300,58 +368,56 @@
}
}
-void AHardwareBuffer_convertToGrallocUsageBits(uint64_t usage, uint64_t* outProducerUsage,
- uint64_t* outConsumerUsage) {
+void AHardwareBuffer_convertToGrallocUsageBits(uint64_t* outProducerUsage,
+ uint64_t* outConsumerUsage, uint64_t usage0, uint64_t usage1) {
*outProducerUsage = 0;
*outConsumerUsage = 0;
- if (containsBits(usage, AHARDWAREBUFFER_USAGE0_CPU_READ))
- *outConsumerUsage |= GRALLOC1_CONSUMER_USAGE_CPU_READ;
- if (containsBits(usage, AHARDWAREBUFFER_USAGE0_CPU_READ_OFTEN))
- *outConsumerUsage |= GRALLOC1_CONSUMER_USAGE_CPU_READ_OFTEN;
- if (containsBits(usage, AHARDWAREBUFFER_USAGE0_CPU_WRITE))
- *outProducerUsage |= GRALLOC1_PRODUCER_USAGE_CPU_WRITE;
- if (containsBits(usage, AHARDWAREBUFFER_USAGE0_CPU_WRITE_OFTEN))
- *outProducerUsage |= GRALLOC1_PRODUCER_USAGE_CPU_WRITE_OFTEN;
- if (containsBits(usage, AHARDWAREBUFFER_USAGE0_GPU_SAMPLED_IMAGE))
- *outConsumerUsage |= GRALLOC1_CONSUMER_USAGE_GPU_TEXTURE;
- if (containsBits(usage, AHARDWAREBUFFER_USAGE0_GPU_COLOR_OUTPUT))
- *outProducerUsage |= GRALLOC1_PRODUCER_USAGE_GPU_RENDER_TARGET;
- // Not sure what this should be.
- //if (containsBits(usage0, AHARDWAREBUFFER_USAGE0_GPU_CUBEMAP)) bits |= 0;
- if (containsBits(usage, AHARDWAREBUFFER_USAGE0_GPU_DATA_BUFFER))
- *outConsumerUsage |= GRALLOC1_CONSUMER_USAGE_GPU_DATA_BUFFER;
- if (containsBits(usage, AHARDWAREBUFFER_USAGE0_VIDEO_ENCODE))
- *outConsumerUsage |= GRALLOC1_CONSUMER_USAGE_VIDEO_ENCODER;
- if (containsBits(usage, AHARDWAREBUFFER_USAGE0_PROTECTED_CONTENT))
- *outProducerUsage |= GRALLOC1_PRODUCER_USAGE_PROTECTED;
- if (containsBits(usage, AHARDWAREBUFFER_USAGE0_SENSOR_DIRECT_DATA))
- *outProducerUsage |= GRALLOC1_PRODUCER_USAGE_SENSOR_DIRECT_DATA;
+ for (const UsageMaskMapping& mapping : kUsage0ProducerMapping) {
+ if (containsBits(usage0, mapping.hardwareBufferMask)) {
+ *outProducerUsage |= mapping.grallocMask;
+ }
+ }
+ for (const UsageMaskMapping& mapping : kUsage1ProducerMapping) {
+ if (containsBits(usage1, mapping.hardwareBufferMask)) {
+ *outProducerUsage |= mapping.grallocMask;
+ }
+ }
+ for (const UsageMaskMapping& mapping : kUsage0ConsumerMapping) {
+ if (containsBits(usage0, mapping.hardwareBufferMask)) {
+ *outConsumerUsage |= mapping.grallocMask;
+ }
+ }
+ for (const UsageMaskMapping& mapping : kUsage1ConsumerMapping) {
+ if (containsBits(usage1, mapping.hardwareBufferMask)) {
+ *outConsumerUsage |= mapping.grallocMask;
+ }
+ }
}
-uint64_t AHardwareBuffer_convertFromGrallocUsageBits(uint64_t producerUsage, uint64_t consumerUsage) {
- uint64_t bits = 0;
- if (containsBits(consumerUsage, GRALLOC1_CONSUMER_USAGE_CPU_READ))
- bits |= AHARDWAREBUFFER_USAGE0_CPU_READ;
- if (containsBits(consumerUsage, GRALLOC1_CONSUMER_USAGE_CPU_READ_OFTEN))
- bits |= AHARDWAREBUFFER_USAGE0_CPU_READ_OFTEN;
- if (containsBits(producerUsage, GRALLOC1_PRODUCER_USAGE_CPU_WRITE))
- bits |= AHARDWAREBUFFER_USAGE0_CPU_WRITE;
- if (containsBits(producerUsage, GRALLOC1_PRODUCER_USAGE_CPU_WRITE_OFTEN))
- bits |= AHARDWAREBUFFER_USAGE0_CPU_WRITE_OFTEN;
- if (containsBits(consumerUsage, GRALLOC1_CONSUMER_USAGE_GPU_TEXTURE))
- bits |= AHARDWAREBUFFER_USAGE0_GPU_SAMPLED_IMAGE;
- if (containsBits(producerUsage, GRALLOC1_PRODUCER_USAGE_GPU_RENDER_TARGET))
- bits |= AHARDWAREBUFFER_USAGE0_GPU_COLOR_OUTPUT;
- if (containsBits(consumerUsage, GRALLOC1_CONSUMER_USAGE_GPU_DATA_BUFFER))
- bits |= AHARDWAREBUFFER_USAGE0_GPU_DATA_BUFFER;
- if (containsBits(consumerUsage, GRALLOC1_CONSUMER_USAGE_VIDEO_ENCODER))
- bits |= AHARDWAREBUFFER_USAGE0_VIDEO_ENCODE;
- if (containsBits(producerUsage, GRALLOC1_PRODUCER_USAGE_PROTECTED))
- bits |= AHARDWAREBUFFER_USAGE0_PROTECTED_CONTENT;
- if (containsBits(producerUsage, GRALLOC1_PRODUCER_USAGE_SENSOR_DIRECT_DATA))
- bits |= AHARDWAREBUFFER_USAGE0_SENSOR_DIRECT_DATA;
-
- return bits;
+void AHardwareBuffer_convertFromGrallocUsageBits(uint64_t* outUsage0, uint64_t* outUsage1,
+ uint64_t producerUsage, uint64_t consumerUsage) {
+ *outUsage0 = 0;
+ *outUsage1 = 0;
+ for (const UsageMaskMapping& mapping : kUsage0ProducerMapping) {
+ if (containsBits(producerUsage, mapping.grallocMask)) {
+ *outUsage0 |= mapping.hardwareBufferMask;
+ }
+ }
+ for (const UsageMaskMapping& mapping : kUsage1ProducerMapping) {
+ if (containsBits(producerUsage, mapping.grallocMask)) {
+ *outUsage1 |= mapping.hardwareBufferMask;
+ }
+ }
+ for (const UsageMaskMapping& mapping : kUsage0ConsumerMapping) {
+ if (containsBits(consumerUsage, mapping.grallocMask)) {
+ *outUsage0 |= mapping.hardwareBufferMask;
+ }
+ }
+ for (const UsageMaskMapping& mapping : kUsage1ConsumerMapping) {
+ if (containsBits(consumerUsage, mapping.grallocMask)) {
+ *outUsage1 |= mapping.hardwareBufferMask;
+ }
+ }
}
const GraphicBuffer* AHardwareBuffer_to_GraphicBuffer(const AHardwareBuffer* buffer) {
diff --git a/libs/nativewindow/Android.bp b/libs/nativewindow/Android.bp
index 46e5d50..9c5f096 100644
--- a/libs/nativewindow/Android.bp
+++ b/libs/nativewindow/Android.bp
@@ -13,13 +13,21 @@
// limitations under the License.
ndk_headers {
- name: "libnativewindwow_headers",
+ name: "libnativewindow_headers",
from: "include/android",
to: "android",
srcs: ["include/android/*.h"],
license: "NOTICE",
}
+ndk_library {
+ name: "libnativewindow.ndk",
+ symbol_file: "libnativewindow.map.txt",
+
+ // Android O
+ first_version: "26",
+}
+
cc_library {
name: "libnativewindow",
export_include_dirs: ["include"],
@@ -48,3 +56,5 @@
"libarect",
],
}
+
+subdirs = ["tests"]
diff --git a/libs/nativewindow/include/android/hardware_buffer.h b/libs/nativewindow/include/android/hardware_buffer.h
index 9c08c7b..ef49995 100644
--- a/libs/nativewindow/include/android/hardware_buffer.h
+++ b/libs/nativewindow/include/android/hardware_buffer.h
@@ -97,10 +97,6 @@
AHARDWAREBUFFER_USAGE0_GPU_SAMPLED_IMAGE = 1ULL << 10,
/* The buffer will be written to by the GPU */
AHARDWAREBUFFER_USAGE0_GPU_COLOR_OUTPUT = 1ULL << 11,
- /* The buffer will be read from and written to by the GPU */
- AHARDWAREBUFFER_USAGE0_GPU_STORAGE_IMAGE =
- AHARDWAREBUFFER_USAGE0_GPU_SAMPLED_IMAGE |
- AHARDWAREBUFFER_USAGE0_GPU_COLOR_OUTPUT,
/* The buffer will be used as a cubemap texture */
AHARDWAREBUFFER_USAGE0_GPU_CUBEMAP = 1ULL << 13,
/* The buffer will be used as a shader storage or uniform buffer object*/
@@ -113,13 +109,57 @@
AHARDWAREBUFFER_USAGE0_VIDEO_ENCODE = 1ULL << 21,
};
+/* These flags are intended only for use by device-specific graphics drivers. */
+enum {
+ AHARDWAREBUFFER_USAGE1_CONSUMER_PRIVATE_19 = 1ULL << 24,
+ AHARDWAREBUFFER_USAGE1_PRODUCER_PRIVATE_19 = 1ULL << 25,
+ AHARDWAREBUFFER_USAGE1_CONSUMER_PRIVATE_18 = 1ULL << 26,
+ AHARDWAREBUFFER_USAGE1_PRODUCER_PRIVATE_18 = 1ULL << 27,
+ AHARDWAREBUFFER_USAGE1_CONSUMER_PRIVATE_17 = 1ULL << 28,
+ AHARDWAREBUFFER_USAGE1_PRODUCER_PRIVATE_17 = 1ULL << 29,
+ AHARDWAREBUFFER_USAGE1_CONSUMER_PRIVATE_16 = 1ULL << 30,
+ AHARDWAREBUFFER_USAGE1_PRODUCER_PRIVATE_16 = 1ULL << 31,
+ AHARDWAREBUFFER_USAGE1_CONSUMER_PRIVATE_15 = 1ULL << 32,
+ AHARDWAREBUFFER_USAGE1_PRODUCER_PRIVATE_15 = 1ULL << 33,
+ AHARDWAREBUFFER_USAGE1_CONSUMER_PRIVATE_14 = 1ULL << 34,
+ AHARDWAREBUFFER_USAGE1_PRODUCER_PRIVATE_14 = 1ULL << 35,
+ AHARDWAREBUFFER_USAGE1_CONSUMER_PRIVATE_13 = 1ULL << 36,
+ AHARDWAREBUFFER_USAGE1_PRODUCER_PRIVATE_13 = 1ULL << 37,
+ AHARDWAREBUFFER_USAGE1_CONSUMER_PRIVATE_12 = 1ULL << 38,
+ AHARDWAREBUFFER_USAGE1_PRODUCER_PRIVATE_12 = 1ULL << 39,
+ AHARDWAREBUFFER_USAGE1_CONSUMER_PRIVATE_11 = 1ULL << 40,
+ AHARDWAREBUFFER_USAGE1_PRODUCER_PRIVATE_11 = 1ULL << 41,
+ AHARDWAREBUFFER_USAGE1_CONSUMER_PRIVATE_10 = 1ULL << 42,
+ AHARDWAREBUFFER_USAGE1_PRODUCER_PRIVATE_10 = 1ULL << 43,
+ AHARDWAREBUFFER_USAGE1_CONSUMER_PRIVATE_9 = 1ULL << 44,
+ AHARDWAREBUFFER_USAGE1_PRODUCER_PRIVATE_9 = 1ULL << 45,
+ AHARDWAREBUFFER_USAGE1_CONSUMER_PRIVATE_8 = 1ULL << 46,
+ AHARDWAREBUFFER_USAGE1_PRODUCER_PRIVATE_8 = 1ULL << 47,
+ AHARDWAREBUFFER_USAGE1_CONSUMER_PRIVATE_7 = 1ULL << 48,
+ AHARDWAREBUFFER_USAGE1_PRODUCER_PRIVATE_7 = 1ULL << 49,
+ AHARDWAREBUFFER_USAGE1_CONSUMER_PRIVATE_6 = 1ULL << 50,
+ AHARDWAREBUFFER_USAGE1_PRODUCER_PRIVATE_6 = 1ULL << 51,
+ AHARDWAREBUFFER_USAGE1_CONSUMER_PRIVATE_5 = 1ULL << 52,
+ AHARDWAREBUFFER_USAGE1_PRODUCER_PRIVATE_5 = 1ULL << 53,
+ AHARDWAREBUFFER_USAGE1_CONSUMER_PRIVATE_4 = 1ULL << 54,
+ AHARDWAREBUFFER_USAGE1_PRODUCER_PRIVATE_4 = 1ULL << 55,
+ AHARDWAREBUFFER_USAGE1_CONSUMER_PRIVATE_3 = 1ULL << 56,
+ AHARDWAREBUFFER_USAGE1_PRODUCER_PRIVATE_3 = 1ULL << 57,
+ AHARDWAREBUFFER_USAGE1_CONSUMER_PRIVATE_2 = 1ULL << 58,
+ AHARDWAREBUFFER_USAGE1_PRODUCER_PRIVATE_2 = 1ULL << 59,
+ AHARDWAREBUFFER_USAGE1_CONSUMER_PRIVATE_1 = 1ULL << 60,
+ AHARDWAREBUFFER_USAGE1_PRODUCER_PRIVATE_1 = 1ULL << 61,
+ AHARDWAREBUFFER_USAGE1_CONSUMER_PRIVATE_0 = 1ULL << 62,
+ AHARDWAREBUFFER_USAGE1_PRODUCER_PRIVATE_0 = 1ULL << 63,
+};
+
typedef struct AHardwareBuffer_Desc {
uint32_t width;
uint32_t height;
uint32_t layers;
+ uint32_t format; // One of AHARDWAREBUFFER_FORMAT_*
uint64_t usage0; // Combination of AHARDWAREBUFFER_USAGE0_*
uint64_t usage1; // Initialize to zero, reserved for future use
- uint32_t format; // One of AHARDWAREBUFFER_FORMAT_*
} AHardwareBuffer_Desc;
typedef struct AHardwareBuffer AHardwareBuffer;
diff --git a/libs/nativewindow/include/private/android/AHardwareBufferHelpers.h b/libs/nativewindow/include/private/android/AHardwareBufferHelpers.h
index f138fa7..612ee80 100644
--- a/libs/nativewindow/include/private/android/AHardwareBufferHelpers.h
+++ b/libs/nativewindow/include/private/android/AHardwareBufferHelpers.h
@@ -18,11 +18,11 @@
#define ANDROID_PRIVATE_NATIVE_AHARDWARE_BUFFER_HELPERS_H
/*
- * This file contains utility functions related to AHardwareBuffer, mostly to convert
- * to/from HAL formats.
+ * This file contains utility functions related to AHardwareBuffer, mostly to
+ * convert to/from HAL formats.
*
- * These are PRIVATE methods, so this file can NEVER appear in a public NDK header.
- * They are used by higher level libraries such as core/jni.
+ * These are PRIVATE methods, so this file can NEVER appear in a public NDK
+ * header. They are used by higher level libraries such as core/jni.
*/
#include <stdint.h>
@@ -35,12 +35,11 @@
uint32_t AHardwareBuffer_convertToPixelFormat(uint32_t format);
-void AHardwareBuffer_convertToGrallocUsageBits(uint64_t usage,
- uint64_t* outProducerUsage, uint64_t* outConsumerUsage);
+void AHardwareBuffer_convertToGrallocUsageBits(uint64_t* outProducerUsage,
+ uint64_t* outConsumerUsage, uint64_t usage0, uint64_t usage1);
-uint64_t AHardwareBuffer_convertFromGrallocUsageBits(
- uint64_t producerUsage, uint64_t consumerUsage);
-
+void AHardwareBuffer_convertFromGrallocUsageBits(uint64_t* outUsage0, uint64_t* outUsage1,
+ uint64_t producerUsage, uint64_t consumerUsage);
class GraphicBuffer;
const GraphicBuffer* AHardwareBuffer_to_GraphicBuffer(const AHardwareBuffer* buffer);
diff --git a/libs/nativewindow/libnativewindow.map.txt b/libs/nativewindow/libnativewindow.map.txt
new file mode 100644
index 0000000..dcfabac
--- /dev/null
+++ b/libs/nativewindow/libnativewindow.map.txt
@@ -0,0 +1,26 @@
+LIBNATIVEWINDOW {
+ global:
+ AHardwareBuffer_acquire;
+ AHardwareBuffer_allocate;
+ AHardwareBuffer_describe;
+ AHardwareBuffer_fromHardwareBuffer;
+ AHardwareBuffer_getNativeHandle;
+ AHardwareBuffer_lock;
+ AHardwareBuffer_recvHandleFromUnixSocket;
+ AHardwareBuffer_release;
+ AHardwareBuffer_sendHandleToUnixSocket;
+ AHardwareBuffer_toHardwareBuffer;
+ AHardwareBuffer_unlock;
+ ANativeWindow_acquire;
+ ANativeWindow_fromSurface;
+ ANativeWindow_fromSurfaceTexture;
+ ANativeWindow_getFormat;
+ ANativeWindow_getHeight;
+ ANativeWindow_getWidth;
+ ANativeWindow_lock;
+ ANativeWindow_release;
+ ANativeWindow_setBuffersGeometry;
+ ANativeWindow_unlockAndPost;
+ local:
+ *;
+};
diff --git a/libs/nativewindow/tests/AHardwareBufferTest.cpp b/libs/nativewindow/tests/AHardwareBufferTest.cpp
new file mode 100644
index 0000000..1099043
--- /dev/null
+++ b/libs/nativewindow/tests/AHardwareBufferTest.cpp
@@ -0,0 +1,186 @@
+/*
+ * Copyright (C) 2017 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.
+ */
+
+#define LOG_TAG "AHardwareBuffer_test"
+//#define LOG_NDEBUG 0
+
+#include <android/hardware_buffer.h>
+#include <private/android/AHardwareBufferHelpers.h>
+#include <hardware/gralloc1.h>
+
+#include <gtest/gtest.h>
+
+using namespace android;
+
+static ::testing::AssertionResult BuildHexFailureMessage(uint64_t expected,
+ uint64_t actual, const char* type) {
+ std::ostringstream ss;
+ ss << type << " 0x" << std::hex << actual
+ << " does not match expected " << type << " 0x" << std::hex
+ << expected;
+ return ::testing::AssertionFailure() << ss.str();
+}
+
+static ::testing::AssertionResult TestUsageConversion(
+ uint64_t grallocProducerUsage, uint64_t grallocConsumerUsage,
+ uint64_t hardwareBufferUsage0, uint64_t hardwareBufferUsage1) {
+ uint64_t producerUsage = 0;
+ uint64_t consumerUsage = 0;
+ uint64_t usage0 = 0;
+ uint64_t usage1 = 0;
+
+ AHardwareBuffer_convertToGrallocUsageBits(
+ &producerUsage, &consumerUsage, hardwareBufferUsage0, hardwareBufferUsage1);
+ if (producerUsage != grallocProducerUsage)
+ return BuildHexFailureMessage(grallocProducerUsage, producerUsage,
+ "producer");
+ if (consumerUsage != grallocConsumerUsage)
+ return BuildHexFailureMessage(grallocConsumerUsage, consumerUsage,
+ "consumer");
+
+ AHardwareBuffer_convertFromGrallocUsageBits(
+ &usage0, &usage1, grallocProducerUsage, grallocConsumerUsage);
+ if (usage0 != hardwareBufferUsage0)
+ return BuildHexFailureMessage(hardwareBufferUsage0, usage0, "usage0");
+ if (usage1 != hardwareBufferUsage1)
+ return BuildHexFailureMessage(hardwareBufferUsage1, usage1, "usage1");
+
+ return testing::AssertionSuccess();
+}
+
+// This is a unit test rather than going through AHardwareBuffer because not
+// all flags may be supported by the host device.
+TEST(AHardwareBufferTest, ConvertToAndFromGrallocBits) {
+ EXPECT_TRUE(TestUsageConversion(0, GRALLOC1_CONSUMER_USAGE_CPU_READ,
+ AHARDWAREBUFFER_USAGE0_CPU_READ, 0));
+ EXPECT_TRUE(TestUsageConversion(0, GRALLOC1_CONSUMER_USAGE_CPU_READ_OFTEN,
+ AHARDWAREBUFFER_USAGE0_CPU_READ_OFTEN, 0));
+ EXPECT_TRUE(TestUsageConversion(GRALLOC1_PRODUCER_USAGE_CPU_WRITE, 0,
+ AHARDWAREBUFFER_USAGE0_CPU_WRITE, 0));
+ EXPECT_TRUE(TestUsageConversion(GRALLOC1_PRODUCER_USAGE_CPU_WRITE_OFTEN, 0,
+ AHARDWAREBUFFER_USAGE0_CPU_WRITE_OFTEN, 0));
+ EXPECT_TRUE(TestUsageConversion(0, GRALLOC1_CONSUMER_USAGE_GPU_TEXTURE,
+ AHARDWAREBUFFER_USAGE0_GPU_SAMPLED_IMAGE, 0));
+ EXPECT_TRUE(TestUsageConversion(GRALLOC1_PRODUCER_USAGE_GPU_RENDER_TARGET,
+ 0, AHARDWAREBUFFER_USAGE0_GPU_COLOR_OUTPUT, 0));
+ EXPECT_TRUE(TestUsageConversion(0, GRALLOC1_CONSUMER_USAGE_GPU_DATA_BUFFER,
+ AHARDWAREBUFFER_USAGE0_GPU_DATA_BUFFER, 0));
+ EXPECT_TRUE(TestUsageConversion(GRALLOC1_PRODUCER_USAGE_PROTECTED, 0,
+ AHARDWAREBUFFER_USAGE0_PROTECTED_CONTENT, 0));
+ EXPECT_TRUE(TestUsageConversion(GRALLOC1_PRODUCER_USAGE_SENSOR_DIRECT_DATA,
+ 0, AHARDWAREBUFFER_USAGE0_SENSOR_DIRECT_DATA, 0));
+ EXPECT_TRUE(TestUsageConversion(0, GRALLOC1_CONSUMER_USAGE_VIDEO_ENCODER,
+ AHARDWAREBUFFER_USAGE0_VIDEO_ENCODE, 0));
+
+ EXPECT_TRUE(TestUsageConversion(GRALLOC1_PRODUCER_USAGE_PRIVATE_0, 0,
+ 0, AHARDWAREBUFFER_USAGE1_PRODUCER_PRIVATE_0));
+ EXPECT_TRUE(TestUsageConversion(GRALLOC1_PRODUCER_USAGE_PRIVATE_1, 0,
+ 0, AHARDWAREBUFFER_USAGE1_PRODUCER_PRIVATE_1));
+ EXPECT_TRUE(TestUsageConversion(GRALLOC1_PRODUCER_USAGE_PRIVATE_2, 0,
+ 0, AHARDWAREBUFFER_USAGE1_PRODUCER_PRIVATE_2));
+ EXPECT_TRUE(TestUsageConversion(GRALLOC1_PRODUCER_USAGE_PRIVATE_3, 0,
+ 0, AHARDWAREBUFFER_USAGE1_PRODUCER_PRIVATE_3));
+ EXPECT_TRUE(TestUsageConversion(GRALLOC1_PRODUCER_USAGE_PRIVATE_4, 0,
+ 0, AHARDWAREBUFFER_USAGE1_PRODUCER_PRIVATE_4));
+ EXPECT_TRUE(TestUsageConversion(GRALLOC1_PRODUCER_USAGE_PRIVATE_5, 0,
+ 0, AHARDWAREBUFFER_USAGE1_PRODUCER_PRIVATE_5));
+ EXPECT_TRUE(TestUsageConversion(GRALLOC1_PRODUCER_USAGE_PRIVATE_6, 0,
+ 0, AHARDWAREBUFFER_USAGE1_PRODUCER_PRIVATE_6));
+ EXPECT_TRUE(TestUsageConversion(GRALLOC1_PRODUCER_USAGE_PRIVATE_7, 0,
+ 0, AHARDWAREBUFFER_USAGE1_PRODUCER_PRIVATE_7));
+ EXPECT_TRUE(TestUsageConversion(GRALLOC1_PRODUCER_USAGE_PRIVATE_8, 0,
+ 0, AHARDWAREBUFFER_USAGE1_PRODUCER_PRIVATE_8));
+ EXPECT_TRUE(TestUsageConversion(GRALLOC1_PRODUCER_USAGE_PRIVATE_9, 0,
+ 0, AHARDWAREBUFFER_USAGE1_PRODUCER_PRIVATE_9));
+ EXPECT_TRUE(TestUsageConversion(GRALLOC1_PRODUCER_USAGE_PRIVATE_10, 0,
+ 0, AHARDWAREBUFFER_USAGE1_PRODUCER_PRIVATE_10));
+ EXPECT_TRUE(TestUsageConversion(GRALLOC1_PRODUCER_USAGE_PRIVATE_11, 0,
+ 0, AHARDWAREBUFFER_USAGE1_PRODUCER_PRIVATE_11));
+ EXPECT_TRUE(TestUsageConversion(GRALLOC1_PRODUCER_USAGE_PRIVATE_12, 0,
+ 0, AHARDWAREBUFFER_USAGE1_PRODUCER_PRIVATE_12));
+ EXPECT_TRUE(TestUsageConversion(GRALLOC1_PRODUCER_USAGE_PRIVATE_13, 0,
+ 0, AHARDWAREBUFFER_USAGE1_PRODUCER_PRIVATE_13));
+ EXPECT_TRUE(TestUsageConversion(GRALLOC1_PRODUCER_USAGE_PRIVATE_14, 0,
+ 0, AHARDWAREBUFFER_USAGE1_PRODUCER_PRIVATE_14));
+ EXPECT_TRUE(TestUsageConversion(GRALLOC1_PRODUCER_USAGE_PRIVATE_15, 0,
+ 0, AHARDWAREBUFFER_USAGE1_PRODUCER_PRIVATE_15));
+ EXPECT_TRUE(TestUsageConversion(GRALLOC1_PRODUCER_USAGE_PRIVATE_16, 0,
+ 0, AHARDWAREBUFFER_USAGE1_PRODUCER_PRIVATE_16));
+ EXPECT_TRUE(TestUsageConversion(GRALLOC1_PRODUCER_USAGE_PRIVATE_17, 0,
+ 0, AHARDWAREBUFFER_USAGE1_PRODUCER_PRIVATE_17));
+ EXPECT_TRUE(TestUsageConversion(GRALLOC1_PRODUCER_USAGE_PRIVATE_18, 0,
+ 0, AHARDWAREBUFFER_USAGE1_PRODUCER_PRIVATE_18));
+ EXPECT_TRUE(TestUsageConversion(GRALLOC1_PRODUCER_USAGE_PRIVATE_19, 0,
+ 0, AHARDWAREBUFFER_USAGE1_PRODUCER_PRIVATE_19));
+ EXPECT_TRUE(TestUsageConversion(0, GRALLOC1_CONSUMER_USAGE_PRIVATE_0,
+ 0, AHARDWAREBUFFER_USAGE1_CONSUMER_PRIVATE_0));
+ EXPECT_TRUE(TestUsageConversion(0, GRALLOC1_CONSUMER_USAGE_PRIVATE_1,
+ 0, AHARDWAREBUFFER_USAGE1_CONSUMER_PRIVATE_1));
+ EXPECT_TRUE(TestUsageConversion(0, GRALLOC1_CONSUMER_USAGE_PRIVATE_2,
+ 0, AHARDWAREBUFFER_USAGE1_CONSUMER_PRIVATE_2));
+ EXPECT_TRUE(TestUsageConversion(0, GRALLOC1_CONSUMER_USAGE_PRIVATE_3,
+ 0, AHARDWAREBUFFER_USAGE1_CONSUMER_PRIVATE_3));
+ EXPECT_TRUE(TestUsageConversion(0, GRALLOC1_CONSUMER_USAGE_PRIVATE_4,
+ 0, AHARDWAREBUFFER_USAGE1_CONSUMER_PRIVATE_4));
+ EXPECT_TRUE(TestUsageConversion(0, GRALLOC1_CONSUMER_USAGE_PRIVATE_5,
+ 0, AHARDWAREBUFFER_USAGE1_CONSUMER_PRIVATE_5));
+ EXPECT_TRUE(TestUsageConversion(0, GRALLOC1_CONSUMER_USAGE_PRIVATE_6,
+ 0, AHARDWAREBUFFER_USAGE1_CONSUMER_PRIVATE_6));
+ EXPECT_TRUE(TestUsageConversion(0, GRALLOC1_CONSUMER_USAGE_PRIVATE_7,
+ 0, AHARDWAREBUFFER_USAGE1_CONSUMER_PRIVATE_7));
+ EXPECT_TRUE(TestUsageConversion(0, GRALLOC1_CONSUMER_USAGE_PRIVATE_8,
+ 0, AHARDWAREBUFFER_USAGE1_CONSUMER_PRIVATE_8));
+ EXPECT_TRUE(TestUsageConversion(0, GRALLOC1_CONSUMER_USAGE_PRIVATE_9,
+ 0, AHARDWAREBUFFER_USAGE1_CONSUMER_PRIVATE_9));
+ EXPECT_TRUE(TestUsageConversion(0, GRALLOC1_CONSUMER_USAGE_PRIVATE_10,
+ 0, AHARDWAREBUFFER_USAGE1_CONSUMER_PRIVATE_10));
+ EXPECT_TRUE(TestUsageConversion(0, GRALLOC1_CONSUMER_USAGE_PRIVATE_11,
+ 0, AHARDWAREBUFFER_USAGE1_CONSUMER_PRIVATE_11));
+ EXPECT_TRUE(TestUsageConversion(0, GRALLOC1_CONSUMER_USAGE_PRIVATE_12,
+ 0, AHARDWAREBUFFER_USAGE1_CONSUMER_PRIVATE_12));
+ EXPECT_TRUE(TestUsageConversion(0, GRALLOC1_CONSUMER_USAGE_PRIVATE_13,
+ 0, AHARDWAREBUFFER_USAGE1_CONSUMER_PRIVATE_13));
+ EXPECT_TRUE(TestUsageConversion(0, GRALLOC1_CONSUMER_USAGE_PRIVATE_14,
+ 0, AHARDWAREBUFFER_USAGE1_CONSUMER_PRIVATE_14));
+ EXPECT_TRUE(TestUsageConversion(0, GRALLOC1_CONSUMER_USAGE_PRIVATE_15,
+ 0, AHARDWAREBUFFER_USAGE1_CONSUMER_PRIVATE_15));
+ EXPECT_TRUE(TestUsageConversion(0, GRALLOC1_CONSUMER_USAGE_PRIVATE_16,
+ 0, AHARDWAREBUFFER_USAGE1_CONSUMER_PRIVATE_16));
+ EXPECT_TRUE(TestUsageConversion(0, GRALLOC1_CONSUMER_USAGE_PRIVATE_17,
+ 0, AHARDWAREBUFFER_USAGE1_CONSUMER_PRIVATE_17));
+ EXPECT_TRUE(TestUsageConversion(0, GRALLOC1_CONSUMER_USAGE_PRIVATE_18,
+ 0, AHARDWAREBUFFER_USAGE1_CONSUMER_PRIVATE_18));
+ EXPECT_TRUE(TestUsageConversion(0, GRALLOC1_CONSUMER_USAGE_PRIVATE_19,
+ 0, AHARDWAREBUFFER_USAGE1_CONSUMER_PRIVATE_19));
+
+ // Test some more complex flag combinations.
+ EXPECT_TRUE(TestUsageConversion(GRALLOC1_PRODUCER_USAGE_CPU_WRITE,
+ GRALLOC1_CONSUMER_USAGE_CPU_READ,
+ AHARDWAREBUFFER_USAGE0_CPU_READ | AHARDWAREBUFFER_USAGE0_CPU_WRITE,
+ 0));
+ EXPECT_TRUE(TestUsageConversion(GRALLOC1_PRODUCER_USAGE_CPU_WRITE_OFTEN, 0,
+ AHARDWAREBUFFER_USAGE0_CPU_WRITE_OFTEN, 0));
+ EXPECT_TRUE(TestUsageConversion(GRALLOC1_PRODUCER_USAGE_GPU_RENDER_TARGET,
+ GRALLOC1_CONSUMER_USAGE_GPU_TEXTURE |
+ GRALLOC1_CONSUMER_USAGE_PRIVATE_17,
+ AHARDWAREBUFFER_USAGE0_GPU_COLOR_OUTPUT |
+ AHARDWAREBUFFER_USAGE0_GPU_SAMPLED_IMAGE,
+ AHARDWAREBUFFER_USAGE1_CONSUMER_PRIVATE_17));
+ EXPECT_TRUE(TestUsageConversion(GRALLOC1_PRODUCER_USAGE_SENSOR_DIRECT_DATA,
+ GRALLOC1_CONSUMER_USAGE_GPU_DATA_BUFFER,
+ AHARDWAREBUFFER_USAGE0_GPU_DATA_BUFFER |
+ AHARDWAREBUFFER_USAGE0_SENSOR_DIRECT_DATA, 0));
+}
diff --git a/libs/nativewindow/tests/Android.bp b/libs/nativewindow/tests/Android.bp
new file mode 100644
index 0000000..437ab75
--- /dev/null
+++ b/libs/nativewindow/tests/Android.bp
@@ -0,0 +1,21 @@
+//
+// Copyright (C) 2017 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_test {
+ name: "AHardwareBufferTest",
+ shared_libs: ["libnativewindow"],
+ srcs: ["AHardwareBufferTest.cpp"],
+}
diff --git a/libs/ui/GraphicBuffer.cpp b/libs/ui/GraphicBuffer.cpp
index 37ebfb3..c4d8f76 100644
--- a/libs/ui/GraphicBuffer.cpp
+++ b/libs/ui/GraphicBuffer.cpp
@@ -17,6 +17,9 @@
#define LOG_TAG "GraphicBuffer"
#include <ui/GraphicBuffer.h>
+
+#include <cutils/atomic.h>
+
#include <ui/GrallocMapper.h>
#include <ui/GraphicBufferAllocator.h>
#include <ui/GraphicBufferMapper.h>
diff --git a/libs/ui/tests/Android.bp b/libs/ui/tests/Android.bp
index 6733505..b55c212 100644
--- a/libs/ui/tests/Android.bp
+++ b/libs/ui/tests/Android.bp
@@ -25,3 +25,9 @@
shared_libs: ["libui"],
srcs: ["colorspace_test.cpp"],
}
+
+cc_test {
+ name: "Gralloc1Mapper_test",
+ shared_libs: ["libui", "libutils"],
+ srcs: ["Gralloc1Mapper_test.cpp"],
+}
diff --git a/libs/ui/tests/Gralloc1Mapper_test.cpp b/libs/ui/tests/Gralloc1Mapper_test.cpp
new file mode 100644
index 0000000..b7c9f0f
--- /dev/null
+++ b/libs/ui/tests/Gralloc1Mapper_test.cpp
@@ -0,0 +1,105 @@
+/*
+ * Copyright (C) 2017 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.
+ */
+
+#define LOG_TAG "Gralloc1Mapper_test"
+//#define LOG_NDEBUG 0
+
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/un.h>
+
+#include <ui/GraphicBuffer.h>
+#include <ui/GraphicBufferMapper.h>
+#include <utils/Errors.h>
+
+#include <gtest/gtest.h>
+
+using namespace android;
+
+class Gralloc1MapperTest : public ::testing::Test
+{
+public:
+ ~Gralloc1MapperTest() override = default;
+
+protected:
+ void SetUp() override {
+ buffer = new GraphicBuffer(4, 8, HAL_PIXEL_FORMAT_RGBA_8888, 1,
+ GRALLOC1_PRODUCER_USAGE_CPU_WRITE_OFTEN,
+ GRALLOC1_CONSUMER_USAGE_CPU_READ_OFTEN, "Gralloc1MapperTest");
+ ASSERT_NE(nullptr, buffer.get());
+
+ handle = static_cast<buffer_handle_t>(buffer->handle);
+
+ mapper = &GraphicBufferMapper::get();
+ }
+
+ sp<GraphicBuffer> buffer;
+ buffer_handle_t handle;
+ GraphicBufferMapper* mapper;
+};
+
+TEST_F(Gralloc1MapperTest, Gralloc1MapperTest_getDimensions) {
+ uint32_t width = 0;
+ uint32_t height = 0;
+ status_t err = mapper->getDimensions(handle, &width, &height);
+ ASSERT_EQ(GRALLOC1_ERROR_NONE, err);
+ EXPECT_EQ(4U, width);
+ EXPECT_EQ(8U, height);
+}
+
+TEST_F(Gralloc1MapperTest, Gralloc1MapperTest_getFormat) {
+ int32_t value = 0;
+ status_t err = mapper->getFormat(handle, &value);
+ ASSERT_EQ(GRALLOC1_ERROR_NONE, err);
+ EXPECT_EQ(HAL_PIXEL_FORMAT_RGBA_8888, value);
+}
+
+TEST_F(Gralloc1MapperTest, Gralloc1MapperTest_getLayerCount) {
+ uint32_t value = 0;
+ status_t err = mapper->getLayerCount(handle, &value);
+ if (err != GRALLOC1_ERROR_UNSUPPORTED) {
+ EXPECT_EQ(1U, value);
+ }
+}
+
+TEST_F(Gralloc1MapperTest, Gralloc1MapperTest_getProducerUsage) {
+ uint64_t value = 0;
+ status_t err = mapper->getProducerUsage(handle, &value);
+ ASSERT_EQ(GRALLOC1_ERROR_NONE, err);
+ EXPECT_EQ(GRALLOC1_PRODUCER_USAGE_CPU_WRITE_OFTEN, value);
+}
+
+TEST_F(Gralloc1MapperTest, Gralloc1MapperTest_getConsumerUsage) {
+ uint64_t value = 0;
+ status_t err = mapper->getConsumerUsage(handle, &value);
+ ASSERT_EQ(GRALLOC1_ERROR_NONE, err);
+ EXPECT_EQ(GRALLOC1_CONSUMER_USAGE_CPU_READ_OFTEN, value);
+}
+
+TEST_F(Gralloc1MapperTest, Gralloc1MapperTest_getBackingStore) {
+ uint64_t value = 0;
+ status_t err = mapper->getBackingStore(handle, &value);
+ ASSERT_EQ(GRALLOC1_ERROR_NONE, err);
+}
+
+TEST_F(Gralloc1MapperTest, Gralloc1MapperTest_getStride) {
+ uint32_t value = 0;
+ status_t err = mapper->getStride(handle, &value);
+ ASSERT_EQ(GRALLOC1_ERROR_NONE, err);
+ // The stride should be at least the width of the buffer.
+ EXPECT_LE(4U, value);
+}
diff --git a/libs/vr/libeds/Android.mk b/libs/vr/libeds/Android.mk
index fd2c56e..d2e6526 100644
--- a/libs/vr/libeds/Android.mk
+++ b/libs/vr/libeds/Android.mk
@@ -37,7 +37,6 @@
libGLESv1_CM \
libGLESv2 \
libvulkan \
- libandroid
staticLibraries := \
libdisplay \
diff --git a/opengl/libs/EGL/Loader.cpp b/opengl/libs/EGL/Loader.cpp
index b1ca13d..9aedc61 100644
--- a/opengl/libs/EGL/Loader.cpp
+++ b/opengl/libs/EGL/Loader.cpp
@@ -17,26 +17,21 @@
//#define LOG_NDEBUG 0
#define ATRACE_TAG ATRACE_TAG_GRAPHICS
-#include <array>
-#include <ctype.h>
+#include "Loader.h"
+
#include <dirent.h>
#include <dlfcn.h>
-#include <errno.h>
-#include <limits.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
#include <android/dlext.h>
#include <cutils/properties.h>
#include <log/log.h>
+
+#include <utils/String8.h>
#include <utils/Trace.h>
+
#include <ui/GraphicsEnv.h>
-#include <EGL/egl.h>
-
#include "egldefs.h"
-#include "Loader.h"
// ----------------------------------------------------------------------------
namespace android {
@@ -437,10 +432,10 @@
return android_dlopen_ext(path, mode, info);
}
-static const std::array<const char*, 2> HAL_SUBNAME_KEY_PROPERTIES = {{
+static const char* HAL_SUBNAME_KEY_PROPERTIES[2] = {
"ro.hardware.egl",
"ro.board.platform",
-}};
+};
static void* load_updated_driver(const char* kind, android_namespace_t* ns) {
ATRACE_CALL();
@@ -454,10 +449,10 @@
if (property_get(key, prop, nullptr) > 0) {
String8 name;
name.appendFormat("lib%s_%s.so", kind, prop);
- so = do_android_dlopen_ext(name.string(), RTLD_LOCAL | RTLD_NOW,
- &dlextinfo);
- if (so)
+ so = do_android_dlopen_ext(name.string(), RTLD_LOCAL | RTLD_NOW, &dlextinfo);
+ if (so) {
return so;
+ }
}
}
return nullptr;
diff --git a/opengl/libs/EGL/Loader.h b/opengl/libs/EGL/Loader.h
index b0743a5..2dd4206 100644
--- a/opengl/libs/EGL/Loader.h
+++ b/opengl/libs/EGL/Loader.h
@@ -17,13 +17,10 @@
#ifndef ANDROID_EGL_LOADER_H
#define ANDROID_EGL_LOADER_H
-#include <ctype.h>
-#include <string.h>
-#include <errno.h>
+#include <stdint.h>
#include <utils/Errors.h>
#include <utils/Singleton.h>
-#include <utils/String8.h>
#include <EGL/egl.h>
@@ -33,12 +30,10 @@
struct egl_connection_t;
-class Loader : public Singleton<Loader>
-{
+class Loader : public Singleton<Loader> {
friend class Singleton<Loader>;
- typedef __eglMustCastToProperFunctionPointerType (*getProcAddressType)(
- const char*);
+ typedef __eglMustCastToProperFunctionPointerType (* getProcAddressType)(const char*);
enum {
EGL = 0x01,
diff --git a/opengl/libs/EGL/egl.cpp b/opengl/libs/EGL/egl.cpp
index ee83ada..34b0ba2 100644
--- a/opengl/libs/EGL/egl.cpp
+++ b/opengl/libs/EGL/egl.cpp
@@ -14,30 +14,26 @@
** limitations under the License.
*/
-#include <ctype.h>
#include <stdlib.h>
-#include <string.h>
#include <hardware/gralloc.h>
-#include <system/window.h>
#include <EGL/egl.h>
-#include <EGL/eglext.h>
#include <cutils/atomic.h>
#include <cutils/properties.h>
+
#include <log/log.h>
+
#include <utils/CallStack.h>
-#include <utils/String8.h>
#include "../egl_impl.h"
-#include "egl_tls.h"
#include "egldefs.h"
-#include "Loader.h"
-
+#include "egl_tls.h"
#include "egl_display.h"
#include "egl_object.h"
+#include "Loader.h"
typedef __eglMustCastToProperFunctionPointerType EGLFuncPointer;
diff --git a/opengl/libs/EGL/eglApi.cpp b/opengl/libs/EGL/eglApi.cpp
index c434d0e..3359c64 100644
--- a/opengl/libs/EGL/eglApi.cpp
+++ b/opengl/libs/EGL/eglApi.cpp
@@ -22,7 +22,6 @@
#include <string.h>
#include <hardware/gralloc1.h>
-#include <system/window.h>
#include <EGL/egl.h>
#include <EGL/eglext.h>
@@ -30,9 +29,7 @@
#include <android/hardware_buffer.h>
#include <private/android/AHardwareBufferHelpers.h>
-#include <cutils/atomic.h>
#include <cutils/compiler.h>
-#include <cutils/memory.h>
#include <cutils/properties.h>
#include <log/log.h>
@@ -44,18 +41,17 @@
#include <utils/KeyedVector.h>
#include <utils/String8.h>
#include <utils/Trace.h>
+#include <utils/Thread.h>
#include "binder/Binder.h"
#include "binder/Parcel.h"
#include "binder/IServiceManager.h"
#include "../egl_impl.h"
-#include "../hooks.h"
#include "egl_display.h"
#include "egl_object.h"
#include "egl_tls.h"
-#include "egldefs.h"
using namespace android;
@@ -84,11 +80,10 @@
* NOTE: Both strings MUST have a single space as the last character.
*/
-// CLion mistakenly warns about the extern keyword below.
-#pragma clang diagnostic push
-#pragma clang diagnostic ignored "-Wextern-initializer"
+extern char const * const gBuiltinExtensionString;
+extern char const * const gExtensionString;
-extern char const * const gBuiltinExtensionString =
+char const * const gBuiltinExtensionString =
"EGL_KHR_get_all_proc_addresses "
"EGL_ANDROID_presentation_time "
"EGL_KHR_swap_buffers_with_damage "
@@ -97,7 +92,8 @@
"EGL_ANDROID_front_buffer_auto_refresh "
"EGL_ANDROID_get_frame_timestamps "
;
-extern char const * const gExtensionString =
+
+char const * const gExtensionString =
"EGL_KHR_image " // mandatory
"EGL_KHR_image_base " // mandatory
"EGL_KHR_image_pixmap "
@@ -237,8 +233,6 @@
(__eglMustCastToProperFunctionPointerType)&eglGetFrameTimestampSupportedANDROID },
};
-#pragma clang diagnostic pop
-
/*
* These extensions entry-points should not be exposed to applications.
* They're used internally by the Android EGL layer.
diff --git a/opengl/libs/EGL/egl_cache.cpp b/opengl/libs/EGL/egl_cache.cpp
index 1fe322d..e46716c 100644
--- a/opengl/libs/EGL/egl_cache.cpp
+++ b/opengl/libs/EGL/egl_cache.cpp
@@ -14,18 +14,17 @@
** limitations under the License.
*/
+#include "egl_cache.h"
+
#include "../egl_impl.h"
-#include "egl_cache.h"
#include "egl_display.h"
-#include "egldefs.h"
-#include <fcntl.h>
#include <inttypes.h>
#include <sys/mman.h>
#include <sys/stat.h>
-#include <sys/types.h>
-#include <unistd.h>
+
+#include <utils/Thread.h>
// Cache size limits.
static const size_t maxKeySize = 12 * 1024;
@@ -87,7 +86,7 @@
bool atStart = !strncmp(BC_EXT_STR " ", exts, bcExtLen+1);
bool atEnd = (bcExtLen+1) < extsLen &&
!strcmp(" " BC_EXT_STR, exts + extsLen - (bcExtLen+1));
- bool inMiddle = strstr(exts, " " BC_EXT_STR " ");
+ bool inMiddle = strstr(exts, " " BC_EXT_STR " ") != nullptr;
if (equal || atStart || atEnd || inMiddle) {
PFNEGLSETBLOBCACHEFUNCSANDROIDPROC eglSetBlobCacheFuncsANDROID;
eglSetBlobCacheFuncsANDROID =
diff --git a/opengl/libs/EGL/egl_cache.h b/opengl/libs/EGL/egl_cache.h
index 8760009..e7f1712 100644
--- a/opengl/libs/EGL/egl_cache.h
+++ b/opengl/libs/EGL/egl_cache.h
@@ -21,6 +21,7 @@
#include <EGL/eglext.h>
#include <utils/BlobCache.h>
+#include <utils/Mutex.h>
#include <utils/String8.h>
#include <utils/StrongPointer.h>
diff --git a/opengl/libs/EGL/egl_display.cpp b/opengl/libs/EGL/egl_display.cpp
index d7df40c..c804fa7 100644
--- a/opengl/libs/EGL/egl_display.cpp
+++ b/opengl/libs/EGL/egl_display.cpp
@@ -17,16 +17,16 @@
#define __STDC_LIMIT_MACROS 1
#define ATRACE_TAG ATRACE_TAG_GRAPHICS
-#include <string.h>
+#include "egl_display.h"
#include "../egl_impl.h"
#include "egl_cache.h"
-#include "egl_display.h"
#include "egl_object.h"
#include "egl_tls.h"
#include "Loader.h"
#include <cutils/properties.h>
+
#include <utils/Trace.h>
// ----------------------------------------------------------------------------
diff --git a/opengl/libs/EGL/egl_display.h b/opengl/libs/EGL/egl_display.h
index e17558c..f5e7294 100644
--- a/opengl/libs/EGL/egl_display.h
+++ b/opengl/libs/EGL/egl_display.h
@@ -18,16 +18,16 @@
#define ANDROID_EGL_DISPLAY_H
-#include <ctype.h>
#include <stdint.h>
-#include <stdlib.h>
+#include <stddef.h>
#include <EGL/egl.h>
#include <EGL/eglext.h>
#include <cutils/compiler.h>
#include <utils/SortedVector.h>
-#include <utils/threads.h>
+#include <utils/Condition.h>
+#include <utils/Mutex.h>
#include <utils/String8.h>
#include "egldefs.h"
diff --git a/opengl/libs/EGL/egl_object.cpp b/opengl/libs/EGL/egl_object.cpp
index 7fc5609..b553d71 100644
--- a/opengl/libs/EGL/egl_object.cpp
+++ b/opengl/libs/EGL/egl_object.cpp
@@ -14,19 +14,10 @@
** limitations under the License.
*/
-#include <string>
+#include "egl_object.h"
+
#include <sstream>
-#include <ctype.h>
-#include <stdint.h>
-#include <stdlib.h>
-
-#include <EGL/egl.h>
-#include <EGL/eglext.h>
-
-#include <utils/threads.h>
-
-#include "egl_object.h"
// ----------------------------------------------------------------------------
namespace android {
diff --git a/opengl/libs/EGL/egl_object.h b/opengl/libs/EGL/egl_object.h
index 8ceba1d..f4012ab 100644
--- a/opengl/libs/EGL/egl_object.h
+++ b/opengl/libs/EGL/egl_object.h
@@ -17,15 +17,13 @@
#ifndef ANDROID_EGL_OBJECT_H
#define ANDROID_EGL_OBJECT_H
-#include <atomic>
-#include <ctype.h>
#include <stdint.h>
-#include <stdlib.h>
+#include <stddef.h>
#include <EGL/egl.h>
#include <EGL/eglext.h>
-#include <utils/threads.h>
+#include <utils/StrongPointer.h>
#include <utils/String8.h>
#include <utils/Vector.h>
@@ -62,8 +60,8 @@
template <typename N, typename T>
class LocalRef {
egl_object_t* ref;
- LocalRef();
- explicit LocalRef(const LocalRef* rhs);
+ LocalRef() = delete;
+ LocalRef(const LocalRef* rhs) = delete;
public:
~LocalRef();
explicit LocalRef(egl_object_t* rhs);
diff --git a/opengl/libs/EGL/egl_tls.cpp b/opengl/libs/EGL/egl_tls.cpp
index 6de5f27..ca8684e 100644
--- a/opengl/libs/EGL/egl_tls.cpp
+++ b/opengl/libs/EGL/egl_tls.cpp
@@ -14,16 +14,14 @@
** limitations under the License.
*/
-#include <pthread.h>
+#include "egl_tls.h"
+
#include <stdlib.h>
#include <cutils/properties.h>
#include <log/log.h>
#include <utils/CallStack.h>
-#include <EGL/egl.h>
-
-#include "egl_tls.h"
namespace android {
@@ -31,7 +29,7 @@
pthread_once_t egl_tls_t::sOnceKey = PTHREAD_ONCE_INIT;
egl_tls_t::egl_tls_t()
- : error(EGL_SUCCESS), ctx(0), logCallWithNoContext(EGL_TRUE) {
+ : error(EGL_SUCCESS), ctx(0), logCallWithNoContext(true) {
}
const char *egl_tls_t::egl_strerror(EGLint err) {
@@ -85,11 +83,12 @@
bool egl_tls_t::logNoContextCall() {
egl_tls_t* tls = getTLS();
- if (tls->logCallWithNoContext == true) {
+ if (tls->logCallWithNoContext) {
tls->logCallWithNoContext = false;
return true;
}
return false;
+
}
egl_tls_t* egl_tls_t::getTLS() {
diff --git a/opengl/libs/EGL/egl_tls.h b/opengl/libs/EGL/egl_tls.h
index 00eae0b..9feae68 100644
--- a/opengl/libs/EGL/egl_tls.h
+++ b/opengl/libs/EGL/egl_tls.h
@@ -17,11 +17,9 @@
#ifndef ANDROID_EGL_TLS_H
#define ANDROID_EGL_TLS_H
-#include <pthread.h>
-
#include <EGL/egl.h>
-#include "egldefs.h"
+#include <pthread.h>
// ----------------------------------------------------------------------------
namespace android {
@@ -36,7 +34,7 @@
EGLint error;
EGLContext ctx;
- EGLBoolean logCallWithNoContext;
+ bool logCallWithNoContext;
egl_tls_t();
static void validateTLSKey();
diff --git a/opengl/libs/egl_impl.h b/opengl/libs/egl_impl.h
index c0990ec..a8855ef 100644
--- a/opengl/libs/egl_impl.h
+++ b/opengl/libs/egl_impl.h
@@ -17,8 +17,6 @@
#ifndef ANDROID_EGL_IMPL_H
#define ANDROID_EGL_IMPL_H
-#include <ctype.h>
-
#include <EGL/egl.h>
#include <EGL/eglext.h>
#include <EGL/eglplatform.h>
@@ -30,8 +28,7 @@
// ----------------------------------------------------------------------------
EGLAPI const GLubyte * egl_get_string_for_current_context(GLenum name);
-EGLAPI const GLubyte * egl_get_string_for_current_context(GLenum name,
- GLuint index);
+EGLAPI const GLubyte * egl_get_string_for_current_context(GLenum name, GLuint index);
EGLAPI GLint egl_get_num_extensions_for_current_context();
// ----------------------------------------------------------------------------
diff --git a/services/surfaceflinger/Android.mk b/services/surfaceflinger/Android.mk
index 24c68ec..afaccd2 100644
--- a/services/surfaceflinger/Android.mk
+++ b/services/surfaceflinger/Android.mk
@@ -131,9 +131,11 @@
LOCAL_CFLAGS += -fvisibility=hidden -Werror=format
+LOCAL_HEADER_LIBRARIES := \
+ android.hardware.configstore-utils
+
LOCAL_STATIC_LIBRARIES := \
libhwcomposer-command-buffer \
- android.hardware.configstore-utils \
libtrace_proto \
libvkjson \
libvr_manager \
diff --git a/services/surfaceflinger/Client.cpp b/services/surfaceflinger/Client.cpp
index 2b4f4cb..9ddae2b 100644
--- a/services/surfaceflinger/Client.cpp
+++ b/services/surfaceflinger/Client.cpp
@@ -49,7 +49,10 @@
{
const size_t count = mLayers.size();
for (size_t i=0 ; i<count ; i++) {
- mFlinger->removeLayer(mLayers.valueAt(i));
+ sp<Layer> l = mLayers.valueAt(i).promote();
+ if (l != nullptr) {
+ mFlinger->removeLayer(l);
+ }
}
}
diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp
index 2f83c0e..24ebac7 100644
--- a/services/surfaceflinger/Layer.cpp
+++ b/services/surfaceflinger/Layer.cpp
@@ -1436,29 +1436,23 @@
// If this transaction is waiting on the receipt of a frame, generate a sync
// point and send it to the remote layer.
- if (mCurrentState.handle != nullptr) {
- sp<IBinder> strongBinder = mCurrentState.handle.promote();
- sp<Handle> handle = nullptr;
- sp<Layer> handleLayer = nullptr;
- if (strongBinder != nullptr) {
- handle = static_cast<Handle*>(strongBinder.get());
- handleLayer = handle->owner.promote();
- }
- if (strongBinder == nullptr || handleLayer == nullptr) {
- ALOGE("[%s] Unable to promote Layer handle", mName.string());
+ if (mCurrentState.barrierLayer != nullptr) {
+ sp<Layer> barrierLayer = mCurrentState.barrierLayer.promote();
+ if (barrierLayer == nullptr) {
+ ALOGE("[%s] Unable to promote barrier Layer.", mName.string());
// If we can't promote the layer we are intended to wait on,
// then it is expired or otherwise invalid. Allow this transaction
// to be applied as per normal (no synchronization).
- mCurrentState.handle = nullptr;
+ mCurrentState.barrierLayer = nullptr;
} else {
auto syncPoint = std::make_shared<SyncPoint>(
mCurrentState.frameNumber);
- if (handleLayer->addSyncPoint(syncPoint)) {
+ if (barrierLayer->addSyncPoint(syncPoint)) {
mRemoteSyncPoints.push_back(std::move(syncPoint));
} else {
// We already missed the frame we're supposed to synchronize
// on, so go ahead and apply the state update
- mCurrentState.handle = nullptr;
+ mCurrentState.barrierLayer = nullptr;
}
}
@@ -1481,7 +1475,7 @@
bool Layer::applyPendingStates(State* stateToCommit) {
bool stateUpdateAvailable = false;
while (!mPendingStates.empty()) {
- if (mPendingStates[0].handle != nullptr) {
+ if (mPendingStates[0].barrierLayer != nullptr) {
if (mRemoteSyncPoints.empty()) {
// If we don't have a sync point for this, apply it anyway. It
// will be visually wrong, but it should keep us from getting
@@ -1733,7 +1727,7 @@
bool Layer::setMatrix(const layer_state_t::matrix22_t& matrix) {
mCurrentState.sequence++;
mCurrentState.requested.transform.set(
- matrix.dsdx, matrix.dsdy, matrix.dtdx, matrix.dtdy);
+ matrix.dsdx, matrix.dtdy, matrix.dtdx, matrix.dsdy);
mCurrentState.modified = true;
setTransactionFlags(eTransactionNeeded);
return true;
@@ -1828,17 +1822,24 @@
return p->getLayerStack();
}
-void Layer::deferTransactionUntil(const sp<IBinder>& handle,
+void Layer::deferTransactionUntil(const sp<Layer>& barrierLayer,
uint64_t frameNumber) {
- mCurrentState.handle = handle;
+ mCurrentState.barrierLayer = barrierLayer;
mCurrentState.frameNumber = frameNumber;
// We don't set eTransactionNeeded, because just receiving a deferral
// request without any other state updates shouldn't actually induce a delay
mCurrentState.modified = true;
pushPendingState();
- mCurrentState.handle = nullptr;
+ mCurrentState.barrierLayer = nullptr;
mCurrentState.frameNumber = 0;
mCurrentState.modified = false;
+ ALOGE("Deferred transaction");
+}
+
+void Layer::deferTransactionUntil(const sp<IBinder>& barrierHandle,
+ uint64_t frameNumber) {
+ sp<Handle> handle = static_cast<Handle*>(barrierHandle.get());
+ deferTransactionUntil(handle->owner.promote(), frameNumber);
}
void Layer::useSurfaceDamage() {
@@ -2454,6 +2455,21 @@
return true;
}
+bool Layer::detachChildren() {
+ traverseInZOrder([this](Layer* child) {
+ if (child == this) {
+ return;
+ }
+
+ sp<Client> client(child->mClientRef.promote());
+ if (client != nullptr) {
+ client->detachLayer(child);
+ }
+ });
+
+ return true;
+}
+
void Layer::setParent(const sp<Layer>& layer) {
mParent = layer;
}
diff --git a/services/surfaceflinger/Layer.h b/services/surfaceflinger/Layer.h
index c5fea73..f2e5f22 100644
--- a/services/surfaceflinger/Layer.h
+++ b/services/surfaceflinger/Layer.h
@@ -128,9 +128,9 @@
// finalCrop is expressed in display space coordinate.
Rect finalCrop;
- // If set, defers this state update until the Layer identified by handle
+ // If set, defers this state update until the identified Layer
// receives a frame with the given frameNumber
- wp<IBinder> handle;
+ wp<Layer> barrierLayer;
uint64_t frameNumber;
// the transparentRegion hint is a bit special, it's latched only
@@ -171,10 +171,12 @@
bool setLayerStack(uint32_t layerStack);
bool setDataSpace(android_dataspace dataSpace);
uint32_t getLayerStack() const;
- void deferTransactionUntil(const sp<IBinder>& handle, uint64_t frameNumber);
+ void deferTransactionUntil(const sp<IBinder>& barrierHandle, uint64_t frameNumber);
+ void deferTransactionUntil(const sp<Layer>& barrierLayer, uint64_t frameNumber);
bool setOverrideScalingMode(int32_t overrideScalingMode);
void setInfo(uint32_t type, uint32_t appId);
bool reparentChildren(const sp<IBinder>& layer);
+ bool detachChildren();
// If we have received a new buffer this frame, we will pass its surface
// damage down to hardware composer. Otherwise, we must send a region with
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index 842ff0b..4acdb82 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -33,7 +33,6 @@
#include <binder/IPCThreadState.h>
#include <binder/IServiceManager.h>
-#include <binder/MemoryHeapBase.h>
#include <binder/PermissionCache.h>
#include <dvr/vr_flinger.h>
@@ -167,7 +166,7 @@
mLastTransactionTime(0),
mBootFinished(false),
mForceFullDamage(false),
- mInterceptor(),
+ mInterceptor(this),
mPrimaryDispSync("PrimaryDispSync"),
mPrimaryHWVsyncEnabled(false),
mHWVsyncAvailable(false),
@@ -629,6 +628,11 @@
bool SurfaceFlinger::authenticateSurfaceTexture(
const sp<IGraphicBufferProducer>& bufferProducer) const {
Mutex::Autolock _l(mStateLock);
+ return authenticateSurfaceTextureLocked(bufferProducer);
+}
+
+bool SurfaceFlinger::authenticateSurfaceTextureLocked(
+ const sp<IGraphicBufferProducer>& bufferProducer) const {
sp<IBinder> surfaceTextureBinder(IInterface::asBinder(bufferProducer));
return mGraphicBufferProducerList.indexOf(surfaceTextureBinder) >= 0;
}
@@ -2530,14 +2534,7 @@
return NO_ERROR;
}
-status_t SurfaceFlinger::removeLayer(const wp<Layer>& weakLayer) {
- Mutex::Autolock _l(mStateLock);
- sp<Layer> layer = weakLayer.promote();
- if (layer == nullptr) {
- // The layer has already been removed, carry on
- return NO_ERROR;
- }
-
+status_t SurfaceFlinger::removeLayer(const sp<Layer>& layer) {
const auto& p = layer->getParent();
const ssize_t index = (p != nullptr) ? p->removeChild(layer) :
mCurrentState.layersSortedByZ.remove(layer);
@@ -2799,7 +2796,19 @@
}
}
if (what & layer_state_t::eDeferTransaction) {
- layer->deferTransactionUntil(s.handle, s.frameNumber);
+ if (s.barrierHandle != nullptr) {
+ layer->deferTransactionUntil(s.barrierHandle, s.frameNumber);
+ } else if (s.barrierGbp != nullptr) {
+ const sp<IGraphicBufferProducer>& gbp = s.barrierGbp;
+ if (authenticateSurfaceTextureLocked(gbp)) {
+ const auto& otherLayer =
+ (static_cast<MonitoredProducer*>(gbp.get()))->getLayer();
+ layer->deferTransactionUntil(otherLayer, s.frameNumber);
+ } else {
+ ALOGE("Attempt to defer transaction to to an"
+ " unrecognized GraphicBufferProducer");
+ }
+ }
// We don't trigger a traversal here because if no other state is
// changed, we don't want this to cause any more work
}
@@ -2808,6 +2817,9 @@
flags |= eTransactionNeeded|eTraversalNeeded;
}
}
+ if (what & layer_state_t::eDetachChildren) {
+ layer->detachChildren();
+ }
if (what & layer_state_t::eOverrideScalingModeChanged) {
layer->setOverrideScalingMode(s.overrideScalingMode);
// We don't trigger a traversal here because if no other state is
@@ -2904,7 +2916,7 @@
status_t SurfaceFlinger::onLayerRemoved(const sp<Client>& client, const sp<IBinder>& handle)
{
- // called by the window manager when it wants to remove a Layer
+ // called by a client when it wants to remove a Layer
status_t err = NO_ERROR;
sp<Layer> l(client->getLayerUser(handle));
if (l != NULL) {
@@ -2920,7 +2932,15 @@
{
// called by ~LayerCleaner() when all references to the IBinder (handle)
// are gone
- return removeLayer(layer);
+ sp<Layer> l = layer.promote();
+ if (l == nullptr) {
+ // The layer has already been removed, carry on
+ return NO_ERROR;
+ } if (l->getParent() != nullptr) {
+ // If we have a parent, then we can continue to live as long as it does.
+ return NO_ERROR;
+ }
+ return removeLayer(l);
}
// ---------------------------------------------------------------------------
diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h
index c43786a..0b3deef 100644
--- a/services/surfaceflinger/SurfaceFlinger.h
+++ b/services/surfaceflinger/SurfaceFlinger.h
@@ -36,8 +36,6 @@
#include <utils/SortedVector.h>
#include <utils/threads.h>
-#include <binder/IMemory.h>
-
#include <ui/FenceTime.h>
#include <ui/PixelFormat.h>
#include <math/mat4.h>
@@ -160,6 +158,9 @@
return *mRenderEngine;
}
+ bool authenticateSurfaceTextureLocked(
+ const sp<IGraphicBufferProducer>& bufferProducer) const;
+
private:
friend class Client;
friend class DisplayEventConnection;
@@ -329,7 +330,7 @@
status_t onLayerDestroyed(const wp<Layer>& layer);
// remove a layer from SurfaceFlinger immediately
- status_t removeLayer(const wp<Layer>& layer);
+ status_t removeLayer(const sp<Layer>& layer);
// add a layer to SurfaceFlinger
status_t addClientLayer(const sp<Client>& client,
diff --git a/services/surfaceflinger/SurfaceFlinger_hwc1.cpp b/services/surfaceflinger/SurfaceFlinger_hwc1.cpp
index 5aaaab1..fe8dd0c 100644
--- a/services/surfaceflinger/SurfaceFlinger_hwc1.cpp
+++ b/services/surfaceflinger/SurfaceFlinger_hwc1.cpp
@@ -33,7 +33,6 @@
#include <binder/IPCThreadState.h>
#include <binder/IServiceManager.h>
-#include <binder/MemoryHeapBase.h>
#include <binder/PermissionCache.h>
#include <ui/DisplayInfo.h>
@@ -155,7 +154,7 @@
mLastTransactionTime(0),
mBootFinished(false),
mForceFullDamage(false),
- mInterceptor(),
+ mInterceptor(this),
mPrimaryDispSync("PrimaryDispSync"),
mPrimaryHWVsyncEnabled(false),
mHWVsyncAvailable(false),
@@ -628,6 +627,11 @@
bool SurfaceFlinger::authenticateSurfaceTexture(
const sp<IGraphicBufferProducer>& bufferProducer) const {
Mutex::Autolock _l(mStateLock);
+ return authenticateSurfaceTextureLocked(bufferProducer);
+}
+
+bool SurfaceFlinger::authenticateSurfaceTextureLocked(
+ const sp<IGraphicBufferProducer>& bufferProducer) const {
sp<IBinder> surfaceTextureBinder(IInterface::asBinder(bufferProducer));
return mGraphicBufferProducerList.indexOf(surfaceTextureBinder) >= 0;
}
@@ -2313,14 +2317,7 @@
return NO_ERROR;
}
-status_t SurfaceFlinger::removeLayer(const wp<Layer>& weakLayer) {
- Mutex::Autolock _l(mStateLock);
- sp<Layer> layer = weakLayer.promote();
- if (layer == nullptr) {
- // The layer has already been removed, carry on
- return NO_ERROR;
- }
-
+status_t SurfaceFlinger::removeLayer(const sp<Layer>& layer) {
const auto& p = layer->getParent();
const ssize_t index = (p != nullptr) ? p->removeChild(layer) :
mCurrentState.layersSortedByZ.remove(layer);
@@ -2582,7 +2579,19 @@
}
}
if (what & layer_state_t::eDeferTransaction) {
- layer->deferTransactionUntil(s.handle, s.frameNumber);
+ if (s.barrierHandle != nullptr) {
+ layer->deferTransactionUntil(s.barrierHandle, s.frameNumber);
+ } else if (s.barrierGbp != nullptr) {
+ const sp<IGraphicBufferProducer>& gbp = s.barrierGbp;
+ if (authenticateSurfaceTextureLocked(gbp)) {
+ const auto& otherLayer =
+ (static_cast<MonitoredProducer*>(gbp.get()))->getLayer();
+ layer->deferTransactionUntil(otherLayer, s.frameNumber);
+ } else {
+ ALOGE("Attempt to defer transaction to to an"
+ " unrecognized GraphicBufferProducer");
+ }
+ }
// We don't trigger a traversal here because if no other state is
// changed, we don't want this to cause any more work
}
@@ -2591,6 +2600,9 @@
flags |= eTransactionNeeded|eTraversalNeeded;
}
}
+ if (what & layer_state_t::eDetachChildren) {
+ layer->detachChildren();
+ }
if (what & layer_state_t::eOverrideScalingModeChanged) {
layer->setOverrideScalingMode(s.overrideScalingMode);
// We don't trigger a traversal here because if no other state is
@@ -2687,7 +2699,7 @@
status_t SurfaceFlinger::onLayerRemoved(const sp<Client>& client, const sp<IBinder>& handle)
{
- // called by the window manager when it wants to remove a Layer
+ // called by a client when it wants to remove a Layer
status_t err = NO_ERROR;
sp<Layer> l(client->getLayerUser(handle));
if (l != NULL) {
@@ -2703,7 +2715,15 @@
{
// called by ~LayerCleaner() when all references to the IBinder (handle)
// are gone
- return removeLayer(layer);
+ sp<Layer> l = layer.promote();
+ if (l == nullptr) {
+ // The layer has already been removed, carry on
+ return NO_ERROR;
+ } if (l->getParent() != nullptr) {
+ // If we have a parent, then we can continue to live as long as it does.
+ return NO_ERROR;
+ }
+ return removeLayer(l);
}
// ---------------------------------------------------------------------------
diff --git a/services/surfaceflinger/SurfaceInterceptor.cpp b/services/surfaceflinger/SurfaceInterceptor.cpp
index 2d6472a..026fe80 100644
--- a/services/surfaceflinger/SurfaceInterceptor.cpp
+++ b/services/surfaceflinger/SurfaceInterceptor.cpp
@@ -31,6 +31,11 @@
// ----------------------------------------------------------------------------
+SurfaceInterceptor::SurfaceInterceptor(SurfaceFlinger* flinger)
+ : mFlinger(flinger)
+{
+}
+
void SurfaceInterceptor::enable(const SortedVector<sp<Layer>>& layers,
const DefaultKeyedVector< wp<IBinder>, DisplayDeviceState>& displays)
{
@@ -97,8 +102,8 @@
addTransparentRegionLocked(transaction, layerId, layer->mCurrentState.activeTransparentRegion);
addLayerStackLocked(transaction, layerId, layer->mCurrentState.layerStack);
addCropLocked(transaction, layerId, layer->mCurrentState.crop);
- if (layer->mCurrentState.handle != nullptr) {
- addDeferTransactionLocked(transaction, layerId, layer->mCurrentState.handle,
+ if (layer->mCurrentState.barrierLayer != nullptr) {
+ addDeferTransactionLocked(transaction, layerId, layer->mCurrentState.barrierLayer.promote(),
layer->mCurrentState.frameNumber);
}
addFinalCropLocked(transaction, layerId, layer->mCurrentState.finalCrop);
@@ -287,10 +292,9 @@
}
void SurfaceInterceptor::addDeferTransactionLocked(Transaction* transaction, int32_t layerId,
- const wp<const IBinder>& weakHandle, uint64_t frameNumber)
+ const sp<const Layer>& layer, uint64_t frameNumber)
{
SurfaceChange* change(createSurfaceChangeLocked(transaction, layerId));
- const sp<const Layer> layer(getLayer(weakHandle));
if (layer == nullptr) {
ALOGE("An existing layer could not be retrieved with the handle"
" for the deferred transaction");
@@ -349,7 +353,18 @@
addCropLocked(transaction, layerId, state.crop);
}
if (state.what & layer_state_t::eDeferTransaction) {
- addDeferTransactionLocked(transaction, layerId, state.handle, state.frameNumber);
+ sp<Layer> otherLayer = nullptr;
+ if (state.barrierHandle != nullptr) {
+ otherLayer = static_cast<Layer::Handle*>(state.barrierHandle.get())->owner.promote();
+ } else if (state.barrierGbp != nullptr) {
+ auto const& gbp = state.barrierGbp;
+ if (mFlinger->authenticateSurfaceTextureLocked(gbp)) {
+ otherLayer = (static_cast<MonitoredProducer*>(gbp.get()))->getLayer();
+ } else {
+ ALOGE("Attempt to defer transaction to to an unrecognized GraphicBufferProducer");
+ }
+ }
+ addDeferTransactionLocked(transaction, layerId, otherLayer, state.frameNumber);
}
if (state.what & layer_state_t::eFinalCropChanged) {
addFinalCropLocked(transaction, layerId, state.finalCrop);
diff --git a/services/surfaceflinger/SurfaceInterceptor.h b/services/surfaceflinger/SurfaceInterceptor.h
index 9af6e61..30ebcc6 100644
--- a/services/surfaceflinger/SurfaceInterceptor.h
+++ b/services/surfaceflinger/SurfaceInterceptor.h
@@ -28,6 +28,7 @@
class BufferItem;
class Layer;
+class SurfaceFlinger;
struct DisplayState;
struct layer_state_t;
@@ -39,6 +40,7 @@
*/
class SurfaceInterceptor {
public:
+ SurfaceInterceptor(SurfaceFlinger* const flinger);
// Both vectors are used to capture the current state of SF as the initial snapshot in the trace
void enable(const SortedVector<sp<Layer>>& layers,
const DefaultKeyedVector< wp<IBinder>, DisplayDeviceState>& displays);
@@ -102,7 +104,7 @@
void addLayerStackLocked(Transaction* transaction, int32_t layerId, uint32_t layerStack);
void addCropLocked(Transaction* transaction, int32_t layerId, const Rect& rect);
void addDeferTransactionLocked(Transaction* transaction, int32_t layerId,
- const wp<const IBinder>& weakHandle, uint64_t frameNumber);
+ const sp<const Layer>& layer, uint64_t frameNumber);
void addFinalCropLocked(Transaction* transaction, int32_t layerId, const Rect& rect);
void addOverrideScalingModeLocked(Transaction* transaction, int32_t layerId,
int32_t overrideScalingMode);
@@ -129,6 +131,7 @@
std::string mOutputFileName {DEFAULT_FILENAME};
std::mutex mTraceMutex {};
Trace mTrace {};
+ SurfaceFlinger* const mFlinger;
};
}
diff --git a/services/surfaceflinger/tests/Transaction_test.cpp b/services/surfaceflinger/tests/Transaction_test.cpp
index d9f1438..aeb557a 100644
--- a/services/surfaceflinger/tests/Transaction_test.cpp
+++ b/services/surfaceflinger/tests/Transaction_test.cpp
@@ -18,8 +18,6 @@
#include <android/native_window.h>
-#include <binder/IMemory.h>
-
#include <gui/ISurfaceComposer.h>
#include <gui/Surface.h>
#include <gui/SurfaceComposerClient.h>
@@ -199,9 +197,9 @@
{
SCOPED_TRACE("before move");
ScreenCapture::captureScreen(&sc);
- sc->checkPixel( 0, 12, 63, 63, 195);
- sc->checkPixel( 75, 75, 195, 63, 63);
- sc->checkPixel(145, 145, 63, 63, 195);
+ sc->expectBGColor(0, 12);
+ sc->expectFGColor(75, 75);
+ sc->expectBGColor(145, 145);
}
SurfaceComposerClient::openGlobalTransaction();
@@ -211,9 +209,9 @@
// This should reflect the new position, but not the new color.
SCOPED_TRACE("after move, before redraw");
ScreenCapture::captureScreen(&sc);
- sc->checkPixel( 24, 24, 63, 63, 195);
- sc->checkPixel( 75, 75, 63, 63, 195);
- sc->checkPixel(145, 145, 195, 63, 63);
+ sc->expectBGColor(24, 24);
+ sc->expectBGColor(75, 75);
+ sc->expectFGColor(145, 145);
}
fillSurfaceRGBA8(mFGSurfaceControl, 63, 195, 63);
@@ -222,9 +220,9 @@
// This should reflect the new position and the new color.
SCOPED_TRACE("after redraw");
ScreenCapture::captureScreen(&sc);
- sc->checkPixel( 24, 24, 63, 63, 195);
- sc->checkPixel( 75, 75, 63, 63, 195);
- sc->checkPixel(145, 145, 63, 195, 63);
+ sc->expectBGColor(24, 24);
+ sc->expectBGColor(75, 75);
+ sc->checkPixel(145, 145, 63, 195, 63);
}
}
@@ -233,9 +231,9 @@
{
SCOPED_TRACE("before resize");
ScreenCapture::captureScreen(&sc);
- sc->checkPixel( 0, 12, 63, 63, 195);
- sc->checkPixel( 75, 75, 195, 63, 63);
- sc->checkPixel(145, 145, 63, 63, 195);
+ sc->expectBGColor(0, 12);
+ sc->expectFGColor(75, 75);
+ sc->expectBGColor(145, 145);
}
ALOGD("resizing");
@@ -248,9 +246,9 @@
// has not yet received a buffer of the correct size.
SCOPED_TRACE("after resize, before redraw");
ScreenCapture::captureScreen(&sc);
- sc->checkPixel( 0, 12, 63, 63, 195);
- sc->checkPixel( 75, 75, 195, 63, 63);
- sc->checkPixel(145, 145, 63, 63, 195);
+ sc->expectBGColor(0, 12);
+ sc->expectFGColor(75, 75);
+ sc->expectBGColor(145, 145);
}
ALOGD("drawing");
@@ -261,9 +259,9 @@
// This should reflect the new size and the new color.
SCOPED_TRACE("after redraw");
ScreenCapture::captureScreen(&sc);
- sc->checkPixel( 24, 24, 63, 63, 195);
- sc->checkPixel( 75, 75, 63, 195, 63);
- sc->checkPixel(145, 145, 63, 195, 63);
+ sc->expectBGColor(24, 24);
+ sc->checkPixel(75, 75, 63, 195, 63);
+ sc->checkPixel(145, 145, 63, 195, 63);
}
}
@@ -272,9 +270,9 @@
{
SCOPED_TRACE("before crop");
ScreenCapture::captureScreen(&sc);
- sc->checkPixel( 24, 24, 63, 63, 195);
- sc->checkPixel( 75, 75, 195, 63, 63);
- sc->checkPixel(145, 145, 63, 63, 195);
+ sc->expectBGColor(24, 24);
+ sc->expectFGColor(75, 75);
+ sc->expectBGColor(145, 145);
}
SurfaceComposerClient::openGlobalTransaction();
@@ -285,11 +283,11 @@
// This should crop the foreground surface.
SCOPED_TRACE("after crop");
ScreenCapture::captureScreen(&sc);
- sc->checkPixel( 24, 24, 63, 63, 195);
- sc->checkPixel( 75, 75, 63, 63, 195);
- sc->checkPixel( 95, 80, 195, 63, 63);
- sc->checkPixel( 80, 95, 195, 63, 63);
- sc->checkPixel( 96, 96, 63, 63, 195);
+ sc->expectBGColor(24, 24);
+ sc->expectBGColor(75, 75);
+ sc->expectFGColor(95, 80);
+ sc->expectFGColor(80, 95);
+ sc->expectBGColor(96, 96);
}
}
@@ -298,9 +296,9 @@
{
SCOPED_TRACE("before crop");
ScreenCapture::captureScreen(&sc);
- sc->checkPixel( 24, 24, 63, 63, 195);
- sc->checkPixel( 75, 75, 195, 63, 63);
- sc->checkPixel(145, 145, 63, 63, 195);
+ sc->expectBGColor(24, 24);
+ sc->expectFGColor(75, 75);
+ sc->expectBGColor(145, 145);
}
SurfaceComposerClient::openGlobalTransaction();
Rect cropRect(16, 16, 32, 32);
@@ -310,11 +308,11 @@
// This should crop the foreground surface.
SCOPED_TRACE("after crop");
ScreenCapture::captureScreen(&sc);
- sc->checkPixel( 24, 24, 63, 63, 195);
- sc->checkPixel( 75, 75, 63, 63, 195);
- sc->checkPixel( 95, 80, 63, 63, 195);
- sc->checkPixel( 80, 95, 63, 63, 195);
- sc->checkPixel( 96, 96, 63, 63, 195);
+ sc->expectBGColor(24, 24);
+ sc->expectBGColor(75, 75);
+ sc->expectBGColor(95, 80);
+ sc->expectBGColor(80, 95);
+ sc->expectBGColor(96, 96);
}
}
@@ -323,9 +321,9 @@
{
SCOPED_TRACE("before setLayer");
ScreenCapture::captureScreen(&sc);
- sc->checkPixel( 24, 24, 63, 63, 195);
- sc->checkPixel( 75, 75, 195, 63, 63);
- sc->checkPixel(145, 145, 63, 63, 195);
+ sc->expectBGColor(24, 24);
+ sc->expectFGColor(75, 75);
+ sc->expectBGColor(145, 145);
}
SurfaceComposerClient::openGlobalTransaction();
@@ -335,9 +333,9 @@
// This should hide the foreground surface beneath the background.
SCOPED_TRACE("after setLayer");
ScreenCapture::captureScreen(&sc);
- sc->checkPixel( 24, 24, 63, 63, 195);
- sc->checkPixel( 75, 75, 63, 63, 195);
- sc->checkPixel(145, 145, 63, 63, 195);
+ sc->expectBGColor(24, 24);
+ sc->expectBGColor(75, 75);
+ sc->expectBGColor(145, 145);
}
}
@@ -346,9 +344,9 @@
{
SCOPED_TRACE("before hide");
ScreenCapture::captureScreen(&sc);
- sc->checkPixel( 24, 24, 63, 63, 195);
- sc->checkPixel( 75, 75, 195, 63, 63);
- sc->checkPixel(145, 145, 63, 63, 195);
+ sc->expectBGColor(24, 24);
+ sc->expectFGColor(75, 75);
+ sc->expectBGColor(145, 145);
}
SurfaceComposerClient::openGlobalTransaction();
@@ -358,9 +356,9 @@
// This should hide the foreground surface.
SCOPED_TRACE("after hide, before show");
ScreenCapture::captureScreen(&sc);
- sc->checkPixel( 24, 24, 63, 63, 195);
- sc->checkPixel( 75, 75, 63, 63, 195);
- sc->checkPixel(145, 145, 63, 63, 195);
+ sc->expectBGColor(24, 24);
+ sc->expectBGColor(75, 75);
+ sc->expectBGColor(145, 145);
}
SurfaceComposerClient::openGlobalTransaction();
@@ -370,9 +368,9 @@
// This should show the foreground surface.
SCOPED_TRACE("after show");
ScreenCapture::captureScreen(&sc);
- sc->checkPixel( 24, 24, 63, 63, 195);
- sc->checkPixel( 75, 75, 195, 63, 63);
- sc->checkPixel(145, 145, 63, 63, 195);
+ sc->expectBGColor(24, 24);
+ sc->expectFGColor(75, 75);
+ sc->expectBGColor(145, 145);
}
}
@@ -381,9 +379,9 @@
{
SCOPED_TRACE("before setAlpha");
ScreenCapture::captureScreen(&sc);
- sc->checkPixel( 24, 24, 63, 63, 195);
- sc->checkPixel( 75, 75, 195, 63, 63);
- sc->checkPixel(145, 145, 63, 63, 195);
+ sc->expectBGColor(24, 24);
+ sc->expectFGColor(75, 75);
+ sc->expectBGColor(145, 145);
}
SurfaceComposerClient::openGlobalTransaction();
@@ -393,9 +391,9 @@
// This should set foreground to be 75% opaque.
SCOPED_TRACE("after setAlpha");
ScreenCapture::captureScreen(&sc);
- sc->checkPixel( 24, 24, 63, 63, 195);
- sc->checkPixel( 75, 75, 162, 63, 96);
- sc->checkPixel(145, 145, 63, 63, 195);
+ sc->expectBGColor(24, 24);
+ sc->checkPixel(75, 75, 162, 63, 96);
+ sc->expectBGColor(145, 145);
}
}
@@ -404,9 +402,9 @@
{
SCOPED_TRACE("before setLayerStack");
ScreenCapture::captureScreen(&sc);
- sc->checkPixel( 24, 24, 63, 63, 195);
- sc->checkPixel( 75, 75, 195, 63, 63);
- sc->checkPixel(145, 145, 63, 63, 195);
+ sc->expectBGColor(24, 24);
+ sc->expectFGColor(75, 75);
+ sc->expectBGColor(145, 145);
}
SurfaceComposerClient::openGlobalTransaction();
@@ -417,9 +415,9 @@
// layer stack.
SCOPED_TRACE("after setLayerStack");
ScreenCapture::captureScreen(&sc);
- sc->checkPixel( 24, 24, 63, 63, 195);
- sc->checkPixel( 75, 75, 63, 63, 195);
- sc->checkPixel(145, 145, 63, 63, 195);
+ sc->expectBGColor(24, 24);
+ sc->expectBGColor(75, 75);
+ sc->expectBGColor(145, 145);
}
}
@@ -428,9 +426,9 @@
{
SCOPED_TRACE("before setFlags");
ScreenCapture::captureScreen(&sc);
- sc->checkPixel( 24, 24, 63, 63, 195);
- sc->checkPixel( 75, 75, 195, 63, 63);
- sc->checkPixel(145, 145, 63, 63, 195);
+ sc->expectBGColor(24, 24);
+ sc->expectFGColor(75, 75);
+ sc->expectBGColor(145, 145);
}
SurfaceComposerClient::openGlobalTransaction();
@@ -441,9 +439,9 @@
// This should hide the foreground surface
SCOPED_TRACE("after setFlags");
ScreenCapture::captureScreen(&sc);
- sc->checkPixel( 24, 24, 63, 63, 195);
- sc->checkPixel( 75, 75, 63, 63, 195);
- sc->checkPixel(145, 145, 63, 63, 195);
+ sc->expectBGColor(24, 24);
+ sc->expectBGColor(75, 75);
+ sc->expectBGColor(145, 145);
}
}
@@ -452,10 +450,10 @@
{
SCOPED_TRACE("before setMatrix");
ScreenCapture::captureScreen(&sc);
- sc->checkPixel( 24, 24, 63, 63, 195);
- sc->checkPixel( 91, 96, 195, 63, 63);
- sc->checkPixel( 96, 101, 195, 63, 63);
- sc->checkPixel(145, 145, 63, 63, 195);
+ sc->expectBGColor(24, 24);
+ sc->expectFGColor(91, 96);
+ sc->expectFGColor(96, 101);
+ sc->expectBGColor(145, 145);
}
SurfaceComposerClient::openGlobalTransaction();
@@ -465,10 +463,10 @@
{
SCOPED_TRACE("after setMatrix");
ScreenCapture::captureScreen(&sc);
- sc->checkPixel( 24, 24, 63, 63, 195);
- sc->checkPixel( 91, 96, 195, 63, 63);
- sc->checkPixel( 96, 91, 63, 63, 195);
- sc->checkPixel(145, 145, 63, 63, 195);
+ sc->expectBGColor(24, 24);
+ sc->expectFGColor(91, 96);
+ sc->expectBGColor(96, 91);
+ sc->expectBGColor(145, 145);
}
}
@@ -477,9 +475,9 @@
{
SCOPED_TRACE("before anything");
ScreenCapture::captureScreen(&sc);
- sc->checkPixel( 32, 32, 63, 63, 195);
- sc->checkPixel( 96, 96, 195, 63, 63);
- sc->checkPixel(160, 160, 63, 63, 195);
+ sc->expectBGColor(32, 32);
+ sc->expectFGColor(96, 96);
+ sc->expectBGColor(160, 160);
}
// set up two deferred transactions on different frames
@@ -498,9 +496,9 @@
{
SCOPED_TRACE("before any trigger");
ScreenCapture::captureScreen(&sc);
- sc->checkPixel( 32, 32, 63, 63, 195);
- sc->checkPixel( 96, 96, 195, 63, 63);
- sc->checkPixel(160, 160, 63, 63, 195);
+ sc->expectBGColor(32, 32);
+ sc->expectFGColor(96, 96);
+ sc->expectBGColor(160, 160);
}
// should trigger the first deferred transaction, but not the second one
@@ -508,9 +506,9 @@
{
SCOPED_TRACE("after first trigger");
ScreenCapture::captureScreen(&sc);
- sc->checkPixel( 32, 32, 63, 63, 195);
- sc->checkPixel( 96, 96, 162, 63, 96);
- sc->checkPixel(160, 160, 63, 63, 195);
+ sc->expectBGColor(32, 32);
+ sc->checkPixel(96, 96, 162, 63, 96);
+ sc->expectBGColor(160, 160);
}
// should show up immediately since it's not deferred
@@ -523,9 +521,9 @@
{
SCOPED_TRACE("after second trigger");
ScreenCapture::captureScreen(&sc);
- sc->checkPixel( 32, 32, 63, 63, 195);
- sc->checkPixel( 96, 96, 63, 63, 195);
- sc->checkPixel(160, 160, 195, 63, 63);
+ sc->expectBGColor(32, 32);
+ sc->expectBGColor(96, 96);
+ sc->expectFGColor(160, 160);
}
}
@@ -630,4 +628,68 @@
mCapture->expectFGColor(20, 20);
}
}
+
+TEST_F(ChildLayerTest, ReparentChildren) {
+ SurfaceComposerClient::openGlobalTransaction();
+ mChild->show();
+ mChild->setPosition(10, 10);
+ mFGSurfaceControl->setPosition(64, 64);
+ SurfaceComposerClient::closeGlobalTransaction(true);
+
+ {
+ ScreenCapture::captureScreen(&mCapture);
+ // Top left of foreground must now be visible
+ mCapture->expectFGColor(64, 64);
+ // But 10 pixels in we should see the child surface
+ mCapture->expectChildColor(74, 74);
+ // And 10 more pixels we should be back to the foreground surface
+ mCapture->expectFGColor(84, 84);
+ }
+ mFGSurfaceControl->reparentChildren(mBGSurfaceControl->getHandle());
+ {
+ ScreenCapture::captureScreen(&mCapture);
+ mCapture->expectFGColor(64, 64);
+ // In reparenting we should have exposed the entire foreground surface.
+ mCapture->expectFGColor(74, 74);
+ // And the child layer should now begin at 10, 10 (since the BG
+ // layer is at (0, 0)).
+ mCapture->expectBGColor(9, 9);
+ mCapture->expectChildColor(10, 10);
+ }
+}
+
+TEST_F(ChildLayerTest, DetachChildren) {
+ SurfaceComposerClient::openGlobalTransaction();
+ mChild->show();
+ mChild->setPosition(10, 10);
+ mFGSurfaceControl->setPosition(64, 64);
+ SurfaceComposerClient::closeGlobalTransaction(true);
+
+ {
+ ScreenCapture::captureScreen(&mCapture);
+ // Top left of foreground must now be visible
+ mCapture->expectFGColor(64, 64);
+ // But 10 pixels in we should see the child surface
+ mCapture->expectChildColor(74, 74);
+ // And 10 more pixels we should be back to the foreground surface
+ mCapture->expectFGColor(84, 84);
+ }
+
+ SurfaceComposerClient::openGlobalTransaction();
+ mFGSurfaceControl->detachChildren();
+ SurfaceComposerClient::closeGlobalTransaction();
+
+ SurfaceComposerClient::openGlobalTransaction();
+ mChild->hide();
+ SurfaceComposerClient::closeGlobalTransaction();
+
+ // Nothing should have changed.
+ {
+ ScreenCapture::captureScreen(&mCapture);
+ mCapture->expectFGColor(64, 64);
+ mCapture->expectChildColor(74, 74);
+ mCapture->expectFGColor(84, 84);
+ }
+}
+
}
diff --git a/services/vr/sensord/pose_service.cpp b/services/vr/sensord/pose_service.cpp
index 40eb21d..32a2160 100644
--- a/services/vr/sensord/pose_service.cpp
+++ b/services/vr/sensord/pose_service.cpp
@@ -25,8 +25,6 @@
#include <private/dvr/sensor_constants.h>
#include <utils/Trace.h>
-#define arraysize(x) (static_cast<ssize_t>(std::extent<decltype(x)>::value))
-
using android::pdx::LocalChannelHandle;
using android::pdx::default_transport::Endpoint;
using android::pdx::Status;
@@ -35,11 +33,8 @@
namespace dvr {
using Vector3d = vec3d;
-using Vector3f = vec3f;
using Rotationd = quatd;
-using Rotationf = quatf;
using AngleAxisd = Eigen::AngleAxis<double>;
-using AngleAxisf = Eigen::AngleAxis<float>;
namespace {
// Wait a few seconds before checking if we need to disable sensors.
@@ -69,7 +64,6 @@
static constexpr int kDatasetIdLength = 36;
static constexpr char kDatasetIdChars[] = "0123456789abcdef-";
-static constexpr char kDatasetLocation[] = "/data/sdcard/datasets/";
// These are the flags used by BufferProducer::CreatePersistentUncachedBlob,
// plus PRIVATE_ADSP_HEAP to allow access from the DSP.
@@ -77,14 +71,6 @@
GRALLOC_USAGE_SW_READ_RARELY | GRALLOC_USAGE_SW_WRITE_RARELY |
GRALLOC_USAGE_PRIVATE_UNCACHED | GRALLOC_USAGE_PRIVATE_ADSP_HEAP;
-// Extract yaw angle from a given quaternion rotation.
-// Y-axis is considered to be vertical. Result is in rad.
-template <typename T>
-T ExtractYaw(Eigen::Quaternion<T> rotation) {
- const Eigen::Vector3<T> yaw_axis = rotation * vec3::UnitZ();
- return std::atan2(yaw_axis.z(), yaw_axis.x());
-}
-
std::string GetPoseModeString(DvrPoseMode mode) {
switch (mode) {
case DVR_POSE_MODE_6DOF:
@@ -110,19 +96,6 @@
}
}
-inline std::string GetVector3dString(const Vector3d& vector) {
- std::ostringstream stream;
- stream << "[" << vector[0] << "," << vector[1] << "," << vector[2] << "]";
- return stream.str();
-}
-
-inline std::string GetRotationdString(const Rotationd& rotation) {
- std::ostringstream stream;
- stream << "[" << rotation.w() << ", " << GetVector3dString(rotation.vec())
- << "]";
- return stream.str();
-}
-
} // namespace
PoseService::PoseService(SensorThread* sensor_thread)
diff --git a/vulkan/libvulkan/swapchain.cpp b/vulkan/libvulkan/swapchain.cpp
index 31f8796..e105922 100644
--- a/vulkan/libvulkan/swapchain.cpp
+++ b/vulkan/libvulkan/swapchain.cpp
@@ -804,7 +804,8 @@
int gralloc_usage = 0;
if (dispatch.GetSwapchainGrallocUsage2ANDROID) {
uint64_t consumer_usage, producer_usage;
- if (GetData(device).driver_version == 256587285) {
+ uint32_t driver_version = GetData(device).driver_version;
+ if (driver_version == 256587285 || driver_version == 96011958) {
// HACK workaround for loader/driver mismatch during transition to
// vkGetSwapchainGrallocUsage2ANDROID.
typedef VkResult(VKAPI_PTR *