Merge "Remove TARGET_USES_QCOM_BSP from libvrflinger"
diff --git a/aidl/gui/android/view/Surface.aidl b/aidl/gui/android/view/Surface.aidl
index 674c163..7e89220 100644
--- a/aidl/gui/android/view/Surface.aidl
+++ b/aidl/gui/android/view/Surface.aidl
@@ -17,4 +17,4 @@
package android.view;
-parcelable Surface cpp_header "gui/Surface.h";
+parcelable Surface cpp_header "gui/view/Surface.h";
diff --git a/cmds/dumpstate/Android.mk b/cmds/dumpstate/Android.mk
index efc050b..d1e94ed 100644
--- a/cmds/dumpstate/Android.mk
+++ b/cmds/dumpstate/Android.mk
@@ -103,8 +103,7 @@
LOCAL_MODULE := dumpstate
-LOCAL_SHARED_LIBRARIES := $(COMMON_SHARED_LIBRARIES) \
- android.hardware.vibrator@1.0
+LOCAL_SHARED_LIBRARIES := $(COMMON_SHARED_LIBRARIES)
LOCAL_STATIC_LIBRARIES := $(COMMON_STATIC_LIBRARIES)
diff --git a/cmds/dumpstate/dumpstate.cpp b/cmds/dumpstate/dumpstate.cpp
index 67172b6..b323624 100644
--- a/cmds/dumpstate/dumpstate.cpp
+++ b/cmds/dumpstate/dumpstate.cpp
@@ -42,7 +42,6 @@
#include <android-base/strings.h>
#include <android-base/unique_fd.h>
#include <android/hardware/dumpstate/1.0/IDumpstateDevice.h>
-#include <android/hardware/vibrator/1.0/IVibrator.h>
#include <cutils/native_handle.h>
#include <cutils/properties.h>
#include <openssl/sha.h>
@@ -54,8 +53,6 @@
#include "dumpstate.h"
using ::android::hardware::dumpstate::V1_0::IDumpstateDevice;
-using ::android::hardware::vibrator::V1_0::IVibrator;
-using VibratorStatus = ::android::hardware::vibrator::V1_0::Status;
// TODO: remove once moved to namespace
using android::os::dumpstate::CommandOptions;
@@ -1363,6 +1360,16 @@
.Build());
}
+static void Vibrate(int duration_ms) {
+ // clang-format off
+ RunCommand("", {"cmd", "vibrator", "vibrate", std::to_string(duration_ms), "dumpstate"},
+ CommandOptions::WithTimeout(10)
+ .Log("Vibrate: '%s'\n")
+ .Always()
+ .Build());
+ // clang-format on
+}
+
int main(int argc, char *argv[]) {
int do_add_date = 0;
int do_zip_file = 0;
@@ -1608,22 +1615,8 @@
fclose(cmdline);
}
- ::android::sp<IVibrator> vibrator = nullptr;
if (do_vibrate) {
- vibrator = IVibrator::getService();
-
- if (vibrator != nullptr) {
- // cancel previous vibration if any
- ::android::hardware::Return<VibratorStatus> offStatus = vibrator->off();
- if (!offStatus.isOk() || offStatus != VibratorStatus::OK) {
- MYLOGE("Vibrator off failed.");
- } else {
- ::android::hardware::Return<VibratorStatus> onStatus = vibrator->on(150);
- if (!onStatus.isOk() || onStatus != VibratorStatus::OK) {
- MYLOGE("Vibrator on failed.");
- }
- }
- }
+ Vibrate(150);
}
if (do_fb && ds.do_early_screenshot_) {
@@ -1803,21 +1796,9 @@
}
/* vibrate a few but shortly times to let user know it's finished */
- if (vibrator != nullptr) {
- // in case dumpstate magically completes before the above vibration
- ::android::hardware::Return<VibratorStatus> offStatus = vibrator->off();
- if (!offStatus.isOk() || offStatus != VibratorStatus::OK) {
- MYLOGE("Vibrator off failed.");
- } else {
- for (int i = 0; i < 3; i++) {
- ::android::hardware::Return<VibratorStatus> onStatus = vibrator->on(75);
- if (!onStatus.isOk() || onStatus != VibratorStatus::OK) {
- MYLOGE("Vibrator on failed.");
- break;
- }
- usleep((75 + 50) * 1000);
- }
- }
+ for (int i = 0; i < 3; i++) {
+ Vibrate(75);
+ usleep((75 + 50) * 1000);
}
/* tell activity manager we're done */
diff --git a/cmds/dumpsys/tests/dumpsys_test.cpp b/cmds/dumpsys/tests/dumpsys_test.cpp
index 01a2fa3..a596a67 100644
--- a/cmds/dumpsys/tests/dumpsys_test.cpp
+++ b/cmds/dumpsys/tests/dumpsys_test.cpp
@@ -79,6 +79,8 @@
const hidl_string&,
const sp<IServiceNotification>&));
MOCK_METHOD1(debugDump, R<void>(debugDump_cb));
+ MOCK_METHOD3(registerPassthroughClient, R<void>(
+ const hidl_string&, const hidl_string&, int32_t));
};
diff --git a/cmds/lshal/lshal.cpp b/cmds/lshal/lshal.cpp
index bc5eaf2..9998a46 100644
--- a/cmds/lshal/lshal.cpp
+++ b/cmds/lshal/lshal.cpp
@@ -28,31 +28,60 @@
#include <android/hidl/manager/1.0/IServiceManager.h>
#include <hidl/ServiceManagement.h>
-template <typename A, typename B, typename C, typename D, typename E>
+using ::android::sp;
+using ::android::hardware::hidl_string;
+using ::android::hidl::manager::V1_0::IServiceManager;
+
+template <typename A, typename B, typename C, typename D, typename E, typename F>
void printColumn(std::stringstream &stream,
- const A &a, const B &b, const C &c, const D &d, const E &e) {
+ const A &a, const B &b, const C &c, const D &d, const E &, const F &f) {
using namespace ::std;
stream << left
<< setw(70) << a << "\t"
<< setw(20) << b << "\t"
<< setw(10) << c << "\t"
<< setw(5) << d << "\t"
- << setw(0) << e
+ // TODO(b/34984175): enable selecting columns
+ // << setw(16) << e << "\t"
+ << setw(0) << f
<< endl;
}
+template <typename A>
+std::string join(const A &components, const std::string &separator) {
+ std::stringstream out;
+ bool first = true;
+ for (const auto &component : components) {
+ if (!first) {
+ out << separator;
+ }
+ out << component;
+
+ first = false;
+ }
+ return out.str();
+}
+
std::string toHexString(uint64_t t) {
std::ostringstream os;
os << std::hex << std::setfill('0') << std::setw(16) << t;
return os.str();
}
-::android::status_t getReferencedPids(
+std::pair<hidl_string, hidl_string> split(const hidl_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)};
+}
+
+bool getReferencedPids(
pid_t serverPid, std::map<uint64_t, std::string> *objects) {
std::ifstream ifs("/d/binder/proc/" + std::to_string(serverPid));
if (!ifs.is_open()) {
- return ::android::PERMISSION_DENIED;
+ return false;
}
static const std::regex prefix("^\\s*node \\d+:\\s+u([0-9a-f]+)\\s+c([0-9a-f]+)\\s+");
@@ -77,66 +106,165 @@
(*objects)[ptr] += line.substr(pos + proc.size());
}
}
- return ::android::OK;
+ return true;
}
+void dumpAllLibraries(std::stringstream &stream, const std::string &mode,
+ const sp<IServiceManager> &manager) {
+ using namespace ::std;
+ using namespace ::android::hardware;
+ using namespace ::android::hidl::manager::V1_0;
+ using namespace ::android::hidl::base::V1_0;
+ auto ret = manager->list([&] (const auto &fqInstanceNames) {
+ for (const auto &fqInstanceName : fqInstanceNames) {
+ const auto pair = split(fqInstanceName, '/');
+ const auto &serviceName = pair.first;
+ const auto &instanceName = pair.second;
+ printColumn(stream,
+ serviceName,
+ instanceName,
+ mode,
+ "N/A",
+ "N/A",
+ "N/A");
+ }
+ });
+ if (!ret.isOk()) {
+ cerr << "Error: Failed to call debugDump on defaultServiceManager(): "
+ << ret.description() << endl;
+ }
+}
+
+void dumpPassthrough(std::stringstream &stream, const std::string &mode,
+ const sp<IServiceManager> &manager) {
+ using namespace ::std;
+ using namespace ::android::hardware;
+ using namespace ::android::hidl::manager::V1_0;
+ using namespace ::android::hidl::base::V1_0;
+ auto ret = manager->debugDump([&] (const auto &infos) {
+ for (const auto &info : infos) {
+
+ printColumn(stream,
+ info.interfaceName,
+ info.instanceName,
+ mode,
+ info.clientPids.size() == 1 ? std::to_string(info.clientPids[0]) : "N/A",
+ "N/A",
+ join(info.clientPids, " "));
+ }
+ });
+ if (!ret.isOk()) {
+ cerr << "Error: Failed to call debugDump on defaultServiceManager(): "
+ << ret.description() << endl;
+ }
+}
+
+void dumpBinderized(std::stringstream &stream, const std::string &mode,
+ const sp<IServiceManager> &manager) {
+ using namespace ::std;
+ using namespace ::android::hardware;
+ using namespace ::android::hidl::manager::V1_0;
+ using namespace ::android::hidl::base::V1_0;
+ auto listRet = manager->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, std::string>> allPids;
+ for (const auto &fqInstanceName : fqInstanceNames) {
+ const auto pair = split(fqInstanceName, '/');
+ const auto &serviceName = pair.first;
+ const auto &instanceName = pair.second;
+ auto getRet = manager->get(serviceName, instanceName);
+ if (!getRet.isOk()) {
+ cerr << "Warning: Skipping \"" << fqInstanceName << "\": "
+ << "cannot be fetched from service manager:"
+ << getRet.description() << endl;
+ continue;
+ }
+ sp<IBase> service = getRet;
+ if (service == nullptr) {
+ cerr << "Warning: Skipping \"" << fqInstanceName << "\": "
+ << "cannot be fetched from service manager (null)";
+ continue;
+ }
+ auto debugRet = service->getDebugInfo([&] (const auto &debugInfo) {
+ allDebugInfos[fqInstanceName] = debugInfo;
+ if (debugInfo.pid >= 0) {
+ allPids[static_cast<pid_t>(debugInfo.pid)].clear();
+ }
+ });
+ if (!debugRet.isOk()) {
+ cerr << "Warning: Skipping \"" << fqInstanceName << "\": "
+ << "debugging information cannot be retrieved:"
+ << debugRet.description() << endl;
+ }
+ }
+ for (auto &pair : allPids) {
+ pid_t serverPid = pair.first;
+ if (!getReferencedPids(serverPid, &allPids[serverPid])) {
+ std::cerr << "Warning: no information for PID " << serverPid
+ << ", are you root?" << std::endl;
+ }
+ }
+ for (const auto &fqInstanceName : fqInstanceNames) {
+ const auto pair = split(fqInstanceName, '/');
+ const auto &serviceName = pair.first;
+ const auto &instanceName = pair.second;
+ auto it = allDebugInfos.find(fqInstanceName);
+ if (it == allDebugInfos.end()) {
+ printColumn(stream,
+ serviceName,
+ instanceName,
+ mode,
+ "N/A",
+ "N/A",
+ ""
+ );
+ continue;
+ }
+ const DebugInfo &info = it->second;
+ printColumn(stream,
+ serviceName,
+ instanceName,
+ mode,
+ info.pid < 0 ? "N/A" : std::to_string(info.pid),
+ info.ptr == 0 ? "N/A" : toHexString(info.ptr),
+ info.pid < 0 || info.ptr == 0 ? "" : allPids[info.pid][info.ptr]
+ );
+ }
+
+ });
+ if (!listRet.isOk()) {
+ cerr << "Error: Failed to list services for " << mode << ": "
+ << listRet.description() << endl;
+ }
+}
int dump() {
using namespace ::std;
using namespace ::android::hardware;
- using namespace ::android::hidl::manager::V1_0;
-
- std::map<std::string, ::android::sp<IServiceManager>> mapping = {
- {"hwbinder", defaultServiceManager()},
- {"passthrough", getPassthroughServiceManager()}
- };
std::stringstream stream;
stream << "All services:" << endl;
stream << left;
- printColumn(stream, "Interface", "Instance", "Transport", "Server", "Clients");
+ printColumn(stream, "Interface", "Instance", "Transport", "Server", "PTR", "Clients");
- for (const auto &pair : mapping) {
- const std::string &mode = pair.first;
- const ::android::sp<IServiceManager> &manager = pair.second;
-
- if (manager == nullptr) {
- cerr << "Failed to get IServiceManager for " << mode << "!" << endl;
- continue;
- }
-
- auto ret = manager->debugDump([&](const auto ®istered) {
- // server pid, .ptr value of binder object, child pids
- std::map<pid_t, std::map<uint64_t, std::string>> allPids;
- for (const auto &info : registered) {
- if (info.pid < 0) {
- continue;
- }
- pid_t serverPid = info.pid;
- allPids[serverPid].clear();
- }
- for (auto &pair : allPids) {
- pid_t serverPid = pair.first;
- if (getReferencedPids(serverPid, &allPids[serverPid]) != ::android::OK) {
- std::cerr << "Warning: no information for PID " << serverPid
- << ", are you root?" << std::endl;
- }
- }
- for (const auto &info : registered) {
- printColumn(stream,
- info.interfaceName,
- info.instanceName.empty() ? "N/A" : info.instanceName,
- mode,
- info.pid < 0 ? "N/A" : std::to_string(info.pid),
- info.pid < 0 || info.ptr == 0 ? "" : allPids[info.pid][info.ptr]);
- }
- });
- if (!ret.isOk()) {
- cerr << "Failed to list services for " << mode << ": "
- << ret.description() << endl;
- }
+ auto bManager = defaultServiceManager();
+ if (bManager == nullptr) {
+ cerr << "Failed to get defaultServiceManager()!" << endl;
+ } else {
+ dumpBinderized(stream, "hwbinder", bManager);
+ // Passthrough PIDs are registered to the binderized manager as well.
+ dumpPassthrough(stream, "passthrough", bManager);
}
+
+ auto pManager = getPassthroughServiceManager();
+ if (pManager == nullptr) {
+ cerr << "Failed to get getPassthroughServiceManager()!" << endl;
+ } else {
+ dumpAllLibraries(stream, "passthrough", pManager);
+ }
+
cout << stream.rdbuf();
return 0;
}
diff --git a/include/gui/GraphicBufferAlloc.h b/include/gui/GraphicBufferAlloc.h
index 9e18907..54c9829 100644
--- a/include/gui/GraphicBufferAlloc.h
+++ b/include/gui/GraphicBufferAlloc.h
@@ -14,8 +14,8 @@
* limitations under the License.
*/
-#ifndef ANDROID_SF_GRAPHIC_BUFFER_ALLOC_H
-#define ANDROID_SF_GRAPHIC_BUFFER_ALLOC_H
+#ifndef ANDROID_GUI_GRAPHIC_BUFFER_ALLOC_H
+#define ANDROID_GUI_GRAPHIC_BUFFER_ALLOC_H
#include <stdint.h>
#include <sys/types.h>
@@ -25,10 +25,16 @@
#include <utils/Errors.h>
namespace android {
-// ---------------------------------------------------------------------------
class GraphicBuffer;
+/*
+ * Concrete implementation of the IGraphicBufferAlloc interface.
+ *
+ * This can create GraphicBuffer instance across processes. This is mainly used
+ * by surfaceflinger.
+ */
+
class GraphicBufferAlloc : public BnGraphicBufferAlloc {
public:
GraphicBufferAlloc();
@@ -40,7 +46,6 @@
};
-// ---------------------------------------------------------------------------
-}; // namespace android
+} // namespace android
-#endif // ANDROID_SF_GRAPHIC_BUFFER_ALLOC_H
+#endif // ANDROID_GUI_GRAPHIC_BUFFER_ALLOC_H
diff --git a/include/gui/Surface.h b/include/gui/Surface.h
index 60203f7..c3014b2 100644
--- a/include/gui/Surface.h
+++ b/include/gui/Surface.h
@@ -17,8 +17,6 @@
#ifndef ANDROID_GUI_SURFACE_H
#define ANDROID_GUI_SURFACE_H
-#include <binder/Parcelable.h>
-
#include <gui/IGraphicBufferProducer.h>
#include <gui/BufferQueueDefs.h>
@@ -410,43 +408,6 @@
std::unique_ptr<ProducerFrameEventHistory> mFrameEventHistory;
};
-namespace view {
-
-/**
- * A simple holder for an IGraphicBufferProducer, to match the managed-side
- * android.view.Surface parcelable behavior.
- *
- * This implements android/view/Surface.aidl
- *
- * TODO: Convert IGraphicBufferProducer into AIDL so that it can be directly
- * used in managed Binder calls.
- */
-class Surface : public Parcelable {
- public:
-
- String16 name;
- sp<IGraphicBufferProducer> graphicBufferProducer;
-
- virtual status_t writeToParcel(Parcel* parcel) const override;
- virtual status_t readFromParcel(const Parcel* parcel) override;
-
- // nameAlreadyWritten set to true by Surface.java, because it splits
- // Parceling itself between managed and native code, so it only wants a part
- // of the full parceling to happen on its native side.
- status_t writeToParcel(Parcel* parcel, bool nameAlreadyWritten) const;
-
- // nameAlreadyRead set to true by Surface.java, because it splits
- // Parceling itself between managed and native code, so it only wants a part
- // of the full parceling to happen on its native side.
- status_t readFromParcel(const Parcel* parcel, bool nameAlreadyRead);
-
- private:
-
- static String16 readMaybeEmptyString16(const Parcel* parcel);
-};
-
-} // namespace view
-
-}; // namespace android
+} // namespace android
#endif // ANDROID_GUI_SURFACE_H
diff --git a/include/gui/view/Surface.h b/include/gui/view/Surface.h
new file mode 100644
index 0000000..cc64fd4
--- /dev/null
+++ b/include/gui/view/Surface.h
@@ -0,0 +1,68 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_GUI_VIEW_SURFACE_H
+#define ANDROID_GUI_VIEW_SURFACE_H
+
+#include <utils/Errors.h>
+#include <utils/StrongPointer.h>
+#include <utils/String16.h>
+
+#include <binder/Parcelable.h>
+
+namespace android {
+
+class IGraphicBufferProducer;
+
+namespace view {
+
+/**
+ * A simple holder for an IGraphicBufferProducer, to match the managed-side
+ * android.view.Surface parcelable behavior.
+ *
+ * This implements android/view/Surface.aidl
+ *
+ * TODO: Convert IGraphicBufferProducer into AIDL so that it can be directly
+ * used in managed Binder calls.
+ */
+class Surface : public Parcelable {
+ public:
+
+ String16 name;
+ sp<IGraphicBufferProducer> graphicBufferProducer;
+
+ virtual status_t writeToParcel(Parcel* parcel) const override;
+ virtual status_t readFromParcel(const Parcel* parcel) override;
+
+ // nameAlreadyWritten set to true by Surface.java, because it splits
+ // Parceling itself between managed and native code, so it only wants a part
+ // of the full parceling to happen on its native side.
+ status_t writeToParcel(Parcel* parcel, bool nameAlreadyWritten) const;
+
+ // nameAlreadyRead set to true by Surface.java, because it splits
+ // Parceling itself between managed and native code, so it only wants a part
+ // of the full parceling to happen on its native side.
+ status_t readFromParcel(const Parcel* parcel, bool nameAlreadyRead);
+
+ private:
+
+ static String16 readMaybeEmptyString16(const Parcel* parcel);
+};
+
+} // namespace view
+} // namespace android
+
+#endif // ANDROID_GUI_VIEW_SURFACE_H
diff --git a/include/ui/GraphicBuffer.h b/include/ui/GraphicBuffer.h
index 95ca0f3..759c9ec 100644
--- a/include/ui/GraphicBuffer.h
+++ b/include/ui/GraphicBuffer.h
@@ -76,11 +76,6 @@
GraphicBuffer(uint32_t inWidth, uint32_t inHeight, PixelFormat inFormat,
uint32_t inUsage, std::string requestorName = "<Unknown>");
- // creates w * h buffer with a layer count
- GraphicBuffer(uint32_t inWidth, uint32_t inHeight, PixelFormat inFormat,
- uint32_t inLayerCount, uint32_t inUsage,
- std::string requestorName = "<Unknown>");
-
// creates w * h buffer with a layer count using gralloc1
GraphicBuffer(uint32_t inWidth, uint32_t inHeight, PixelFormat inFormat,
uint32_t inLayerCount, uint64_t inProducerUsage,
diff --git a/include/ui/GraphicBufferMapper.h b/include/ui/GraphicBufferMapper.h
index 8e93f72..001769f 100644
--- a/include/ui/GraphicBufferMapper.h
+++ b/include/ui/GraphicBufferMapper.h
@@ -39,7 +39,9 @@
public:
static inline GraphicBufferMapper& get() { return getInstance(); }
+ // This may NOT work on devices without a valid Gralloc2::Mapper.
status_t registerBuffer(buffer_handle_t handle);
+
status_t registerBuffer(const GraphicBuffer* buffer);
status_t unregisterBuffer(buffer_handle_t handle);
diff --git a/libs/gui/Android.bp b/libs/gui/Android.bp
index cb17da4..ddf1072 100644
--- a/libs/gui/Android.bp
+++ b/libs/gui/Android.bp
@@ -96,6 +96,7 @@
"SurfaceControl.cpp",
"SurfaceComposerClient.cpp",
"SyncFeatures.cpp",
+ "view/Surface.cpp",
],
shared_libs: [
diff --git a/libs/gui/GraphicBufferAlloc.cpp b/libs/gui/GraphicBufferAlloc.cpp
index f2d3677..cc7d403 100644
--- a/libs/gui/GraphicBufferAlloc.cpp
+++ b/libs/gui/GraphicBufferAlloc.cpp
@@ -15,21 +15,15 @@
** limitations under the License.
*/
-#include <log/log.h>
-
-#include <ui/GraphicBuffer.h>
-
#include <gui/GraphicBufferAlloc.h>
-// ----------------------------------------------------------------------------
+#include <log/log.h>
+
+
namespace android {
-// ----------------------------------------------------------------------------
-GraphicBufferAlloc::GraphicBufferAlloc() {
-}
-
-GraphicBufferAlloc::~GraphicBufferAlloc() {
-}
+GraphicBufferAlloc::GraphicBufferAlloc() = default;
+GraphicBufferAlloc::~GraphicBufferAlloc() = default;
sp<GraphicBuffer> GraphicBufferAlloc::createGraphicBuffer(uint32_t width,
uint32_t height, PixelFormat format, uint32_t layerCount,
@@ -44,15 +38,12 @@
if (err == NO_MEMORY) {
GraphicBuffer::dumpAllocationsToSystemLog();
}
- ALOGE("GraphicBufferAlloc::createGraphicBuffer(w=%u, h=%u, lc=%u) "
- "failed (%s), handle=%p",
+ ALOGE("GraphicBufferAlloc::createGraphicBuffer(w=%u, h=%u, lc=%u) failed (%s), handle=%p",
width, height, layerCount, strerror(-err),
graphicBuffer->handle);
- return 0;
+ graphicBuffer.clear();
}
return graphicBuffer;
}
-// ----------------------------------------------------------------------------
-}; // namespace android
-// ----------------------------------------------------------------------------
+} // namespace android
diff --git a/libs/gui/Surface.cpp b/libs/gui/Surface.cpp
index c663620..72fa843 100644
--- a/libs/gui/Surface.cpp
+++ b/libs/gui/Surface.cpp
@@ -18,9 +18,9 @@
#define ATRACE_TAG ATRACE_TAG_GRAPHICS
//#define LOG_NDEBUG 0
-#include <android/native_window.h>
+#include <gui/Surface.h>
-#include <binder/Parcel.h>
+#include <android/native_window.h>
#include <utils/Log.h>
#include <utils/Trace.h>
@@ -32,7 +32,6 @@
#include <gui/BufferItem.h>
#include <gui/IProducerListener.h>
-#include <gui/Surface.h>
#include <gui/ISurfaceComposer.h>
#include <private/gui/ComposerService.h>
@@ -1539,74 +1538,4 @@
return mGraphicBufferProducer->getUniqueId(outId);
}
-namespace view {
-
-status_t Surface::writeToParcel(Parcel* parcel) const {
- return writeToParcel(parcel, false);
-}
-
-status_t Surface::writeToParcel(Parcel* parcel, bool nameAlreadyWritten) const {
- if (parcel == nullptr) return BAD_VALUE;
-
- status_t res = OK;
-
- if (!nameAlreadyWritten) {
- res = parcel->writeString16(name);
- if (res != OK) return res;
-
- /* isSingleBuffered defaults to no */
- res = parcel->writeInt32(0);
- if (res != OK) return res;
- }
-
- res = parcel->writeStrongBinder(
- IGraphicBufferProducer::asBinder(graphicBufferProducer));
-
- return res;
-}
-
-status_t Surface::readFromParcel(const Parcel* parcel) {
- return readFromParcel(parcel, false);
-}
-
-status_t Surface::readFromParcel(const Parcel* parcel, bool nameAlreadyRead) {
- if (parcel == nullptr) return BAD_VALUE;
-
- status_t res = OK;
- if (!nameAlreadyRead) {
- name = readMaybeEmptyString16(parcel);
- // Discard this for now
- int isSingleBuffered;
- res = parcel->readInt32(&isSingleBuffered);
- if (res != OK) {
- ALOGE("Can't read isSingleBuffered");
- return res;
- }
- }
-
- sp<IBinder> binder;
-
- res = parcel->readNullableStrongBinder(&binder);
- if (res != OK) {
- ALOGE("%s: Can't read strong binder", __FUNCTION__);
- return res;
- }
-
- graphicBufferProducer = interface_cast<IGraphicBufferProducer>(binder);
-
- return OK;
-}
-
-String16 Surface::readMaybeEmptyString16(const Parcel* parcel) {
- size_t len;
- const char16_t* str = parcel->readString16Inplace(&len);
- if (str != nullptr) {
- return String16(str, len);
- } else {
- return String16();
- }
-}
-
-} // namespace view
-
}; // namespace android
diff --git a/libs/gui/view/Surface.cpp b/libs/gui/view/Surface.cpp
new file mode 100644
index 0000000..5ed3d3b
--- /dev/null
+++ b/libs/gui/view/Surface.cpp
@@ -0,0 +1,97 @@
+/*
+ * Copyright (C) 2010 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 "Surface"
+
+#include <gui/view/Surface.h>
+
+#include <binder/Parcel.h>
+
+#include <utils/Log.h>
+
+#include <gui/IGraphicBufferProducer.h>
+
+namespace android {
+namespace view {
+
+status_t Surface::writeToParcel(Parcel* parcel) const {
+ return writeToParcel(parcel, false);
+}
+
+status_t Surface::writeToParcel(Parcel* parcel, bool nameAlreadyWritten) const {
+ if (parcel == nullptr) return BAD_VALUE;
+
+ status_t res = OK;
+
+ if (!nameAlreadyWritten) {
+ res = parcel->writeString16(name);
+ if (res != OK) return res;
+
+ /* isSingleBuffered defaults to no */
+ res = parcel->writeInt32(0);
+ if (res != OK) return res;
+ }
+
+ res = parcel->writeStrongBinder(
+ IGraphicBufferProducer::asBinder(graphicBufferProducer));
+
+ return res;
+}
+
+status_t Surface::readFromParcel(const Parcel* parcel) {
+ return readFromParcel(parcel, false);
+}
+
+status_t Surface::readFromParcel(const Parcel* parcel, bool nameAlreadyRead) {
+ if (parcel == nullptr) return BAD_VALUE;
+
+ status_t res = OK;
+ if (!nameAlreadyRead) {
+ name = readMaybeEmptyString16(parcel);
+ // Discard this for now
+ int isSingleBuffered;
+ res = parcel->readInt32(&isSingleBuffered);
+ if (res != OK) {
+ ALOGE("Can't read isSingleBuffered");
+ return res;
+ }
+ }
+
+ sp<IBinder> binder;
+
+ res = parcel->readNullableStrongBinder(&binder);
+ if (res != OK) {
+ ALOGE("%s: Can't read strong binder", __FUNCTION__);
+ return res;
+ }
+
+ graphicBufferProducer = interface_cast<IGraphicBufferProducer>(binder);
+
+ return OK;
+}
+
+String16 Surface::readMaybeEmptyString16(const Parcel* parcel) {
+ size_t len;
+ const char16_t* str = parcel->readString16Inplace(&len);
+ if (str != nullptr) {
+ return String16(str, len);
+ } else {
+ return String16();
+ }
+}
+
+} // namespace view
+} // namespace android
diff --git a/libs/ui/GraphicBuffer.cpp b/libs/ui/GraphicBuffer.cpp
index 5ef95ec..b544426 100644
--- a/libs/ui/GraphicBuffer.cpp
+++ b/libs/ui/GraphicBuffer.cpp
@@ -50,8 +50,8 @@
height =
stride =
format =
- layerCount =
usage = 0;
+ layerCount = 0;
handle = NULL;
}
@@ -64,8 +64,8 @@
height =
stride =
format =
- layerCount =
usage = 0;
+ layerCount = 0;
handle = NULL;
mInitCheck = initSize(inWidth, inHeight, inFormat, 1, inUsage, inUsage,
std::move(requestorName));
@@ -81,8 +81,8 @@
height =
stride =
format =
- layerCount =
usage = 0;
+ layerCount = 0;
handle = NULL;
mInitCheck = initSize(inWidth, inHeight, inFormat, inLayerCount,
producerUsage, consumerUsage, std::move(requestorName));
diff --git a/libs/ui/GraphicBufferMapper.cpp b/libs/ui/GraphicBufferMapper.cpp
index b0ed2df..a3b6e18 100644
--- a/libs/ui/GraphicBufferMapper.cpp
+++ b/libs/ui/GraphicBufferMapper.cpp
@@ -63,7 +63,14 @@
if (mMapper->valid()) {
error = static_cast<gralloc1_error_t>(mMapper->retain(handle));
} else {
+ // This always returns GRALLOC1_BAD_HANDLE when handle is from a
+ // remote process and mDevice is backed by Gralloc1On0Adapter.
error = mDevice->retain(handle);
+ if (error == GRALLOC1_ERROR_BAD_HANDLE &&
+ mDevice->hasCapability(GRALLOC1_CAPABILITY_ON_ADAPTER)) {
+ ALOGE("registerBuffer by handle is not supported with "
+ "Gralloc1On0Adapter");
+ }
}
ALOGW_IF(error != GRALLOC1_ERROR_NONE, "registerBuffer(%p) failed: %d",
diff --git a/services/vr/vr_manager/Android.mk b/libs/vr/libvr_manager/Android.mk
similarity index 79%
rename from services/vr/vr_manager/Android.mk
rename to libs/vr/libvr_manager/Android.mk
index 54b1c1a..e9987f7 100644
--- a/services/vr/vr_manager/Android.mk
+++ b/libs/vr/libvr_manager/Android.mk
@@ -14,11 +14,16 @@
LOCAL_PATH := $(call my-dir)
+exported_include_dirs := \
+ $(LOCAL_PATH)/include
+
+include_dirs := \
+ frameworks/native/include/vr/vr_manager \
+ $(exported_include_dirs)
+
src_files := \
vr_manager.cpp \
-
-inc_files := \
- frameworks/native/include/vr/vr_manager
+ trusted_uids.cpp
static_libs := \
libutils \
@@ -26,13 +31,12 @@
include $(CLEAR_VARS)
LOCAL_SRC_FILES := $(src_files)
-LOCAL_C_INCLUDES := $(inc_files)
+LOCAL_C_INCLUDES := $(include_dirs)
+LOCAL_EXPORT_C_INCLUDE_DIRS := $(exported_include_dirs)
LOCAL_CFLAGS += -Wall
LOCAL_CFLAGS += -Werror
LOCAL_CFLAGS += -Wunused
LOCAL_CFLAGS += -Wunreachable-code
-LOCAL_EXPORT_C_INCLUDE_DIRS := $(inc_files)
-#LOCAL_SHARED_LIBRARIES := $(sharedLibraries)
LOCAL_STATIC_LIBRARIES := $(static_libs)
LOCAL_MODULE := libvr_manager
include $(BUILD_STATIC_LIBRARY)
diff --git a/libs/vr/libvr_manager/include/private/dvr/trusted_uids.h b/libs/vr/libvr_manager/include/private/dvr/trusted_uids.h
new file mode 100644
index 0000000..4496fbf
--- /dev/null
+++ b/libs/vr/libvr_manager/include/private/dvr/trusted_uids.h
@@ -0,0 +1,33 @@
+#ifndef ANDROID_DVR_TRUSTED_UIDS_H_
+#define ANDROID_DVR_TRUSTED_UIDS_H_
+
+#include <sys/types.h>
+
+namespace android {
+namespace dvr {
+
+/**
+ * Tells if a provided UID can be trusted to access restricted VR APIs.
+ *
+ * UID trust is based on the android.permission.RESTRICTED_VR_ACCESS permission.
+ * AID_SYSTEM and AID_ROOT are automatically trusted by Android.
+ *
+ * UIDs are guaranteed not to be reused until the next reboot even in case
+ * of package reinstall. For performance reasons this method caches results by
+ * default, as otherwise every check would trigger a Java call.
+ *
+ * This function is thread-safe.
+ *
+ * @param uid The uid to check.
+ * @param use_cache If true any cached result for the provided uid will be
+ * reused. If false this call will reach the Application Manager Service
+ * in Java to get updated values. Any updates will be stored in the cache.
+ * @return true if the uid is trusted, false if not or if the VR Manager Service
+ * could not be reached to verify the uid.
+ */
+bool IsTrustedUid(uid_t uid, bool use_cache = true);
+
+} // namespace dvr
+} // namespace android
+
+#endif // ANDROID_DVR_TRUSTED_UIDS_H_
diff --git a/libs/vr/libvr_manager/trusted_uids.cpp b/libs/vr/libvr_manager/trusted_uids.cpp
new file mode 100644
index 0000000..4228a05
--- /dev/null
+++ b/libs/vr/libvr_manager/trusted_uids.cpp
@@ -0,0 +1,51 @@
+#include "private/dvr/trusted_uids.h"
+
+#include <mutex>
+#include <unordered_map>
+
+#include <binder/IPermissionController.h>
+#include <binder/IServiceManager.h>
+#include <private/android_filesystem_config.h>
+#include <utils/String16.h>
+#include <vr/vr_manager/vr_manager.h>
+
+namespace android {
+namespace dvr {
+
+bool IsTrustedUid(uid_t uid, bool use_cache) {
+ static std::unordered_map<uid_t, bool> uid_cache;
+ static std::mutex uid_cache_mutex;
+
+ // Whitelist requests from the system UID.
+ // These are already whitelisted by the permission service, but it might not
+ // be available if the ActivityManagerService is up during boot.
+ // This ensures the correct result for system services while booting up.
+ if (uid == AID_SYSTEM)
+ return true;
+
+ std::lock_guard<std::mutex> lock(uid_cache_mutex);
+
+ if (use_cache) {
+ auto it = uid_cache.find(uid);
+ if (it != uid_cache.end())
+ return it->second;
+ }
+
+ sp<IBinder> binder = defaultServiceManager()->getService(String16("permission"));
+ if (binder == 0) {
+ ALOGW("Could not access permission service");
+ return false;
+ }
+
+ // Note: we ignore the pid because it's only used to automatically reply
+ // true if the caller is the Activity Manager Service.
+ bool trusted = interface_cast<IPermissionController>(binder)->checkPermission(
+ String16("android.permission.RESTRICTED_VR_ACCESS"), -1, uid);
+
+ // Cache the information for this uid to avoid future Java calls.
+ uid_cache[uid] = trusted;
+ return trusted;
+}
+
+} // namespace dvr
+} // namespace android
diff --git a/services/vr/vr_manager/vr_manager.cpp b/libs/vr/libvr_manager/vr_manager.cpp
similarity index 100%
rename from services/vr/vr_manager/vr_manager.cpp
rename to libs/vr/libvr_manager/vr_manager.cpp
diff --git a/libs/vr/libvrflinger/Android.mk b/libs/vr/libvrflinger/Android.mk
index d99558e..1706f30 100644
--- a/libs/vr/libvrflinger/Android.mk
+++ b/libs/vr/libvrflinger/Android.mk
@@ -45,6 +45,7 @@
libperformance \
libsensor \
libpdx_default_transport \
+ libvr_manager \
sharedLibraries := \
android.dvr.composer@1.0 \
diff --git a/libs/vr/libvrflinger/screenshot_service.cpp b/libs/vr/libvrflinger/screenshot_service.cpp
index e174943..fd1c582 100644
--- a/libs/vr/libvrflinger/screenshot_service.cpp
+++ b/libs/vr/libvrflinger/screenshot_service.cpp
@@ -3,7 +3,9 @@
#include <utils/Trace.h>
#include <pdx/default_transport/service_endpoint.h>
+#include <private/android_filesystem_config.h>
#include <private/dvr/display_types.h>
+#include <private/dvr/trusted_uids.h>
using android::pdx::Message;
using android::pdx::MessageInfo;
@@ -40,6 +42,12 @@
ScreenshotData ScreenshotService::OnTakeScreenshot(pdx::Message& message,
int layer_index) {
+ // Also allow AID_SHELL to support vrscreencap commands.
+ if (message.GetEffectiveUserId() != AID_SHELL &&
+ !IsTrustedUid(message.GetEffectiveUserId())) {
+ REPLY_ERROR_RETURN(message, EACCES, {});
+ }
+
AddWaiter(std::move(message), layer_index);
return {};
}
diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp
index 3a9bca6..6e0a489 100644
--- a/services/surfaceflinger/Layer.cpp
+++ b/services/surfaceflinger/Layer.cpp
@@ -427,7 +427,9 @@
Rect bounds = win;
const auto& p = getParent();
if (p != nullptr) {
- bounds = p->computeScreenBounds();
+ // Look in computeScreenBounds recursive call for explanation of
+ // why we pass false here.
+ bounds = p->computeScreenBounds(false /* reduceTransparentRegion */);
}
Transform t = getTransform();
diff --git a/services/vr/vr_window_manager/Android.mk b/services/vr/vr_window_manager/Android.mk
index 47d9dcc..85f8e1f 100644
--- a/services/vr/vr_window_manager/Android.mk
+++ b/services/vr/vr_window_manager/Android.mk
@@ -110,6 +110,7 @@
LOCAL_LDLIBS := -llog
LOCAL_MODULE := libvr_window_manager_jni
LOCAL_MODULE_TAGS := optional
+LOCAL_MODULE_TARGET_ARCH := arm arm64 x86 x86_64
LOCAL_MULTILIB := 64
LOCAL_CXX_STL := libc++_static
include $(BUILD_SHARED_LIBRARY)
@@ -126,6 +127,7 @@
LOCAL_LDLIBS := -llog
LOCAL_MODULE := vr_wm
LOCAL_MODULE_TAGS := optional
+LOCAL_MODULE_TARGET_ARCH := arm arm64 x86 x86_64
LOCAL_INIT_RC := vr_wm.rc
include $(BUILD_EXECUTABLE)
@@ -147,6 +149,7 @@
LOCAL_AAPT_FLAGS += --auto-add-overlay
LOCAL_AAPT_FLAGS += --extra-packages com.google.vr.cardboard
LOCAL_PROGUARD_FLAG_FILES := proguard.flags
+LOCAL_MODULE_TARGET_ARCH := arm arm64 x86 x86_64
include $(BUILD_PACKAGE)
diff --git a/vulkan/api/vulkan.api b/vulkan/api/vulkan.api
index 5a67d36..a89fed9 100644
--- a/vulkan/api/vulkan.api
+++ b/vulkan/api/vulkan.api
@@ -2908,14 +2908,20 @@
platform.HWND hwnd
}
+@internal class Gralloc1Usage {
+ u64 consumer
+ u64 producer
+}
+
@extension("VK_ANDROID_native_buffer")
class VkNativeBufferANDROID {
VkStructureType sType
const void* pNext
platform.buffer_handle_t handle
- int stride
- int format
- int usage
+ s32 stride
+ s32 format
+ s32 usage
+ Gralloc1Usage usage2
}
@extension("VK_ANDROID_native_buffer")
@@ -5833,21 +5839,24 @@
}
@extension("VK_ANDROID_native_buffer")
+@optional
cmd VkResult vkGetSwapchainGrallocUsageANDROID(
VkDevice device,
VkFormat format,
VkImageUsageFlags imageUsage,
- int* grallocUsage) {
+ s32* grallocUsage) {
return ?
}
@extension("VK_ANDROID_native_buffer")
+@optional
cmd VkResult vkGetSwapchainGrallocUsage2ANDROID(
VkDevice device,
VkFormat format,
VkImageUsageFlags imageUsage,
VkSwapchainImageUsageFlagsANDROID swapchainImageUsage,
- int* grallocUsage) {
+ u64* grallocConsumerUsage,
+ u64* grallocProducerUsage) {
return ?
}
diff --git a/vulkan/doc/implementors_guide/implementors_guide.adoc b/vulkan/doc/implementors_guide/implementors_guide.adoc
index 009472a..24af950 100644
--- a/vulkan/doc/implementors_guide/implementors_guide.adoc
+++ b/vulkan/doc/implementors_guide/implementors_guide.adoc
@@ -47,19 +47,7 @@
The +vk_wsi_swapchin+ and +vk_wsi_device_swapchain+ extensions are primarily be implemented by the platform and live in +libvulkan.so+. The +VkSwapchain+ object and all interaction with +ANativeWindow+ will be handled by the platform and not exposed to drivers. The WSI implementation will rely on a few private interfaces to the driver for this implementation. These will be loaded through the driver's +vkGetDeviceProcAddr+ functions, after passing through any enabled layers.
-Implementations may need swapchain buffers to be allocated with implementation-defined private gralloc usage flags. When creating a swapchain, the platform will ask the driver to translate the requested format and image usage flags into gralloc usage flags by calling
-[source,c]
-----
-VkResult VKAPI vkGetSwapchainGrallocUsageANDROID(
- VkDevice device,
- VkFormat format,
- VkImageUsageFlags imageUsage,
- int* grallocUsage
-);
-----
-The +format+ and +imageUsage+ parameters are taken from the +VkSwapchainCreateInfoKHR+ structure. The driver should fill +*grallocUsage+ with the gralloc usage flags it requires for that format and usage. These will be combined with the usage flags requested by the swapchain consumer when allocating buffers.
-
-Implementations may further need swapchain buffers to be allocated with implementation-defined private gralloc usage flags that depend not only on +format+ and +imageUsage+, but also on the intended usage of the swapchain. The additional usage bits are defined as
+Implementations may need swapchain buffers to be allocated with implementation-defined private gralloc usage flags that depend not only on +format+ and +imageUsage+, but also on the intended usage of the swapchain. The swapchain usage bits are defined as
[source,c]
----
typedef enum VkSwapchainImageUsageFlagBitsANDROID {
@@ -69,7 +57,7 @@
typedef VkFlags VkSwapchainImageUsageFlagsANDROID;
----
-If the driver provides the +vkGetSwapchainGrallocUsage2ANDROID+ function, the platform will use it in preference to +vkGetSwapchainGrallocUsageANDROID+ when translating a requested format, image usage flags, and swapchain image usage flags into gralloc usage flags. +vkGetSwapchainGrallocUsage2ANDROID+ behaves in the same way as +vkGetSwapchainGrallocUsageANDROID+, and is declared as
+Implementations may need swapchain buffers to be allocated with implementation-defined private gralloc usage flags. When creating a swapchain, the platform will ask the driver to translate the requested format and image usage flags into gralloc usage flags by calling
[source,c]
----
VKAPI_ATTR VkResult VKAPI_CALL vkGetSwapchainGrallocUsage2ANDROID(
@@ -77,6 +65,19 @@
VkFormat format,
VkImageUsageFlags imageUsage,
VkSwapchainImageUsageFlagsANDROID swapchainImageUsage,
+ uint64_t* grallocConsumerUsage,
+ uint64_t* grallocProducerUsage,
+);
+----
+The +format+ and +imageUsage+ parameters are taken from the +VkSwapchainCreateInfoKHR+ structure. The driver should fill +*grallocConsumerUsage+ and +*grallocProducerUsage+ with the gralloc usage flags it requires for that format and usage. These will be combined with the usage flags requested by the swapchain consumer when allocating buffers.
+
+An older version of this function is deprecated but still supported for backwards compatibility; it will be used if +vkGetSwapchainGrallocUsage2ANDROID+ is not supported:
+[source,c]
+----
+VkResult VKAPI vkGetSwapchainGrallocUsageANDROID(
+ VkDevice device,
+ VkFormat format,
+ VkImageUsageFlags imageUsage,
int* grallocUsage
);
----
@@ -95,7 +96,11 @@
// Gralloc format and usage requested when the buffer was allocated.
int format;
- int usage;
+ int usage; // deprecated
+ struct {
+ uint64_t consumer;
+ uint64_t producer;
+ } usage2;
} VkNativeBufferANDROID;
----
@@ -200,3 +205,5 @@
* Added VkSwapchainImageUsageFlagBitsANDROID
* Added vkGetSwapchainGrallocUsage2ANDROID
* Added VkSwapchainImageCreateInfoANDROID
+. *2017-02-09*
+ * Extended vkGetSwapchainGrallocUsage2ANDROID and VkNativeBufferANDROID to use gralloc1-style usage bitfields.
\ No newline at end of file
diff --git a/vulkan/doc/implementors_guide/implementors_guide.html b/vulkan/doc/implementors_guide/implementors_guide.html
index 4e74a78..9fecce5 100644
--- a/vulkan/doc/implementors_guide/implementors_guide.html
+++ b/vulkan/doc/implementors_guide/implementors_guide.html
@@ -730,7 +730,7 @@
/*]]>*/
</script>
</head>
-<body class="article">
+<body class="book">
<div id="header">
<h1>Vulkan on Android Implementor’s Guide</h1>
<span id="revnumber">version 5</span>
@@ -793,20 +793,7 @@
<h2 id="_window_system_integration">2. Window System Integration</h2>
<div class="sectionbody">
<div class="paragraph"><p>The <span class="monospaced">vk_wsi_swapchin</span> and <span class="monospaced">vk_wsi_device_swapchain</span> extensions are primarily be implemented by the platform and live in <span class="monospaced">libvulkan.so</span>. The <span class="monospaced">VkSwapchain</span> object and all interaction with <span class="monospaced">ANativeWindow</span> will be handled by the platform and not exposed to drivers. The WSI implementation will rely on a few private interfaces to the driver for this implementation. These will be loaded through the driver’s <span class="monospaced">vkGetDeviceProcAddr</span> functions, after passing through any enabled layers.</p></div>
-<div class="paragraph"><p>Implementations may need swapchain buffers to be allocated with implementation-defined private gralloc usage flags. When creating a swapchain, the platform will ask the driver to translate the requested format and image usage flags into gralloc usage flags by calling</p></div>
-<div class="listingblock">
-<div class="content"><!-- Generator: GNU source-highlight 3.1.6
-by Lorenzo Bettini
-http://www.lorenzobettini.it
-http://www.gnu.org/software/src-highlite -->
-<pre><tt>VkResult <span style="color: #008080">VKAPI</span> <span style="font-weight: bold"><span style="color: #000000">vkGetSwapchainGrallocUsageANDROID</span></span><span style="color: #990000">(</span>
- <span style="color: #008080">VkDevice</span> device<span style="color: #990000">,</span>
- <span style="color: #008080">VkFormat</span> format<span style="color: #990000">,</span>
- <span style="color: #008080">VkImageUsageFlags</span> imageUsage<span style="color: #990000">,</span>
- <span style="color: #009900">int</span><span style="color: #990000">*</span> grallocUsage
-<span style="color: #990000">);</span></tt></pre></div></div>
-<div class="paragraph"><p>The <span class="monospaced">format</span> and <span class="monospaced">imageUsage</span> parameters are taken from the <span class="monospaced">VkSwapchainCreateInfoKHR</span> structure. The driver should fill <span class="monospaced">*grallocUsage</span> with the gralloc usage flags it requires for that format and usage. These will be combined with the usage flags requested by the swapchain consumer when allocating buffers.</p></div>
-<div class="paragraph"><p>Implementations may further need swapchain buffers to be allocated with implementation-defined private gralloc usage flags that depend not only on <span class="monospaced">format</span> and <span class="monospaced">imageUsage</span>, but also on the intended usage of the swapchain. The additional usage bits are defined as</p></div>
+<div class="paragraph"><p>Implementations may need swapchain buffers to be allocated with implementation-defined private gralloc usage flags that depend not only on <span class="monospaced">format</span> and <span class="monospaced">imageUsage</span>, but also on the intended usage of the swapchain. The swapchain usage bits are defined as</p></div>
<div class="listingblock">
<div class="content"><!-- Generator: GNU source-highlight 3.1.6
by Lorenzo Bettini
@@ -817,7 +804,7 @@
VK_SWAPCHAIN_IMAGE_USAGE_FLAG_BITS_MAX_ENUM <span style="color: #990000">=</span> <span style="color: #993399">0x7FFFFFFF</span>
<span style="color: #FF0000">}</span> VkSwapchainImageUsageFlagBitsANDROID<span style="color: #990000">;</span>
<span style="font-weight: bold"><span style="color: #0000FF">typedef</span></span> <span style="color: #008080">VkFlags</span> VkSwapchainImageUsageFlagsANDROID<span style="color: #990000">;</span></tt></pre></div></div>
-<div class="paragraph"><p>If the driver provides the <span class="monospaced">vkGetSwapchainGrallocUsage2ANDROID</span> function, the platform will use it in preference to <span class="monospaced">vkGetSwapchainGrallocUsageANDROID</span> when translating a requested format, image usage flags, and swapchain image usage flags into gralloc usage flags. <span class="monospaced">vkGetSwapchainGrallocUsage2ANDROID</span> behaves in the same way as <span class="monospaced">vkGetSwapchainGrallocUsageANDROID</span>, and is declared as</p></div>
+<div class="paragraph"><p>Implementations may need swapchain buffers to be allocated with implementation-defined private gralloc usage flags. When creating a swapchain, the platform will ask the driver to translate the requested format and image usage flags into gralloc usage flags by calling</p></div>
<div class="listingblock">
<div class="content"><!-- Generator: GNU source-highlight 3.1.6
by Lorenzo Bettini
@@ -828,6 +815,20 @@
<span style="color: #008080">VkFormat</span> format<span style="color: #990000">,</span>
<span style="color: #008080">VkImageUsageFlags</span> imageUsage<span style="color: #990000">,</span>
<span style="color: #008080">VkSwapchainImageUsageFlagsANDROID</span> swapchainImageUsage<span style="color: #990000">,</span>
+ uint64_t<span style="color: #990000">*</span> grallocConsumerUsage<span style="color: #990000">,</span>
+ uint64_t<span style="color: #990000">*</span> grallocProducerUsage<span style="color: #990000">,</span>
+<span style="color: #990000">);</span></tt></pre></div></div>
+<div class="paragraph"><p>The <span class="monospaced">format</span> and <span class="monospaced">imageUsage</span> parameters are taken from the <span class="monospaced">VkSwapchainCreateInfoKHR</span> structure. The driver should fill <span class="monospaced">*grallocConsumerUsage</span> and <span class="monospaced">*grallocProducerUsage</span> with the gralloc usage flags it requires for that format and usage. These will be combined with the usage flags requested by the swapchain consumer when allocating buffers.</p></div>
+<div class="paragraph"><p>An older version of this function is deprecated but still supported for backwards compatibility; it will be used if <span class="monospaced">vkGetSwapchainGrallocUsage2ANDROID</span> is not supported:</p></div>
+<div class="listingblock">
+<div class="content"><!-- Generator: GNU source-highlight 3.1.6
+by Lorenzo Bettini
+http://www.lorenzobettini.it
+http://www.gnu.org/software/src-highlite -->
+<pre><tt>VkResult <span style="color: #008080">VKAPI</span> <span style="font-weight: bold"><span style="color: #000000">vkGetSwapchainGrallocUsageANDROID</span></span><span style="color: #990000">(</span>
+ <span style="color: #008080">VkDevice</span> device<span style="color: #990000">,</span>
+ <span style="color: #008080">VkFormat</span> format<span style="color: #990000">,</span>
+ <span style="color: #008080">VkImageUsageFlags</span> imageUsage<span style="color: #990000">,</span>
<span style="color: #009900">int</span><span style="color: #990000">*</span> grallocUsage
<span style="color: #990000">);</span></tt></pre></div></div>
<div class="paragraph"><p><span class="monospaced">VkNativeBufferANDROID</span> is a <span class="monospaced">vkCreateImage</span> extension structure for creating an image backed by a gralloc buffer. This structure is provided to <span class="monospaced">vkCreateImage</span> in the <span class="monospaced">VkImageCreateInfo</span> structure chain. Calls to <span class="monospaced">vkCreateImage</span> with this structure will happen during the first call to <span class="monospaced">vkGetSwapChainInfoWSI(.. VK_SWAP_CHAIN_INFO_TYPE_IMAGES_WSI ..)</span>. The WSI implementation will allocate the number of native buffers requested for the swapchain, then create a <span class="monospaced">VkImage</span> for each one.</p></div>
@@ -846,7 +847,11 @@
<span style="font-style: italic"><span style="color: #9A1900">// Gralloc format and usage requested when the buffer was allocated.</span></span>
<span style="color: #009900">int</span> format<span style="color: #990000">;</span>
- <span style="color: #009900">int</span> usage<span style="color: #990000">;</span>
+ <span style="color: #009900">int</span> usage<span style="color: #990000">;</span> <span style="font-style: italic"><span style="color: #9A1900">// deprecated</span></span>
+ <span style="font-weight: bold"><span style="color: #0000FF">struct</span></span> <span style="color: #FF0000">{</span>
+ <span style="color: #008080">uint64_t</span> consumer<span style="color: #990000">;</span>
+ <span style="color: #008080">uint64_t</span> producer<span style="color: #990000">;</span>
+ <span style="color: #FF0000">}</span> usage2<span style="color: #990000">;</span>
<span style="color: #FF0000">}</span> VkNativeBufferANDROID<span style="color: #990000">;</span></tt></pre></div></div>
<div class="paragraph"><p>When creating a gralloc-backed image, the <span class="monospaced">VkImageCreateInfo</span> will have:</p></div>
<div class="listingblock">
@@ -1044,6 +1049,18 @@
</li>
</ul></div>
</li>
+<li>
+<p>
+<strong>2017-02-09</strong>
+</p>
+<div class="ulist"><ul>
+<li>
+<p>
+Extended vkGetSwapchainGrallocUsage2ANDROID and VkNativeBufferANDROID to use gralloc1-style usage bitfields.
+</p>
+</li>
+</ul></div>
+</li>
</ol></div>
</div>
</div>
@@ -1052,7 +1069,7 @@
<div id="footer">
<div id="footer-text">
Version 5<br>
-Last updated 2017-01-12 14:25:30 NZDT
+Last updated 2017-02-09 22:40:30 PST
</div>
</div>
</body>
diff --git a/vulkan/include/vulkan/vk_android_native_buffer.h b/vulkan/include/vulkan/vk_android_native_buffer.h
index db23e79..d7c5a07 100644
--- a/vulkan/include/vulkan/vk_android_native_buffer.h
+++ b/vulkan/include/vulkan/vk_android_native_buffer.h
@@ -27,6 +27,16 @@
#define VK_ANDROID_native_buffer 1
#define VK_ANDROID_NATIVE_BUFFER_EXTENSION_NUMBER 11
+/* NOTE ON VK_ANDROID_NATIVE_BUFFER_SPEC_VERSION 6
+ *
+ * This version of the extension transitions from gralloc0 to gralloc1 usage
+ * flags (int -> 2x uint64_t). The WSI implementation will temporarily continue
+ * to fill out deprecated fields in VkNativeBufferANDROID, and will call the
+ * deprecated vkGetSwapchainGrallocUsageANDROID if the new
+ * vkGetSwapchainGrallocUsage2ANDROID is not supported. This transitionary
+ * backwards-compatibility support is temporary, and will likely be removed in
+ * (along with all gralloc0 support) in a future release.
+ */
#define VK_ANDROID_NATIVE_BUFFER_SPEC_VERSION 6
#define VK_ANDROID_NATIVE_BUFFER_EXTENSION_NAME "VK_ANDROID_native_buffer"
@@ -50,7 +60,12 @@
// Gralloc format and usage requested when the buffer was allocated.
int format;
- int usage;
+ int usage; // DEPRECATED in SPEC_VERSION 6
+ // -- Added in SPEC_VERSION 6 --
+ struct {
+ uint64_t consumer;
+ uint64_t producer;
+ } usage2;
} VkNativeBufferANDROID;
typedef struct {
@@ -60,24 +75,30 @@
VkSwapchainImageUsageFlagsANDROID usage;
} VkSwapchainImageCreateInfoANDROID;
+// -- DEPRECATED in SPEC_VERSION 6 --
typedef VkResult (VKAPI_PTR *PFN_vkGetSwapchainGrallocUsageANDROID)(VkDevice device, VkFormat format, VkImageUsageFlags imageUsage, int* grallocUsage);
-typedef VkResult (VKAPI_PTR *PFN_vkGetSwapchainGrallocUsage2ANDROID)(VkDevice device, VkFormat format, VkImageUsageFlags imageUsage, VkSwapchainImageUsageFlagsANDROID swapchainImageUsage, int* grallocUsage);
+// -- ADDED in SPEC_VERSION 6 --
+typedef VkResult (VKAPI_PTR *PFN_vkGetSwapchainGrallocUsage2ANDROID)(VkDevice device, VkFormat format, VkImageUsageFlags imageUsage, VkSwapchainImageUsageFlagsANDROID swapchainImageUsage, uint64_t* grallocConsumerUsage, uint64_t* grallocProducerUsage);
typedef VkResult (VKAPI_PTR *PFN_vkAcquireImageANDROID)(VkDevice device, VkImage image, int nativeFenceFd, VkSemaphore semaphore, VkFence fence);
typedef VkResult (VKAPI_PTR *PFN_vkQueueSignalReleaseImageANDROID)(VkQueue queue, uint32_t waitSemaphoreCount, const VkSemaphore* pWaitSemaphores, VkImage image, int* pNativeFenceFd);
#ifndef VK_NO_PROTOTYPES
+
+// -- DEPRECATED in SPEC_VERSION 6 --
VKAPI_ATTR VkResult VKAPI_CALL vkGetSwapchainGrallocUsageANDROID(
VkDevice device,
VkFormat format,
VkImageUsageFlags imageUsage,
int* grallocUsage
);
+// -- ADDED in SPEC_VERSION 6 --
VKAPI_ATTR VkResult VKAPI_CALL vkGetSwapchainGrallocUsage2ANDROID(
VkDevice device,
VkFormat format,
VkImageUsageFlags imageUsage,
VkSwapchainImageUsageFlagsANDROID swapchainImageUsage,
- int* grallocUsage
+ uint64_t* grallocConsumerUsage,
+ uint64_t* grallocProducerUsage
);
VKAPI_ATTR VkResult VKAPI_CALL vkAcquireImageANDROID(
VkDevice device,
@@ -93,17 +114,6 @@
VkImage image,
int* pNativeFenceFd
);
-// -- DEPRECATED --
-VKAPI_ATTR VkResult VKAPI_CALL vkImportNativeFenceANDROID(
- VkDevice device,
- VkSemaphore semaphore,
- int nativeFenceFd
-);
-VKAPI_ATTR VkResult VKAPI_CALL vkQueueSignalNativeFenceANDROID(
- VkQueue queue,
- int* pNativeFenceFd
-);
-// ----------------
#endif
#ifdef __cplusplus
diff --git a/vulkan/libvulkan/code-generator.tmpl b/vulkan/libvulkan/code-generator.tmpl
index 501877c..e3c44d2 100644
--- a/vulkan/libvulkan/code-generator.tmpl
+++ b/vulkan/libvulkan/code-generator.tmpl
@@ -413,13 +413,14 @@
{{AssertType $ "Function"}}
{{$ext := GetAnnotation $ "extension"}}
- {{$required := (Macro "IsRequiredFunction" $)}}
{{if $ext}}
- INIT_PROC_EXT({{Macro "BaseName" $ext}}, {{$required}}, §
+ INIT_PROC_EXT({{Macro "BaseName" $ext}}, §
{{else}}
- INIT_PROC({{$required}}, §
+ INIT_PROC(§
{{end}}
+ {{if GetAnnotation $ "optional"}}false{{else}}true{{end}}, §
+
{{if (Macro "IsInstanceDispatched" $)}}
instance, §
{{else}}
@@ -432,25 +433,6 @@
{{/*
------------------------------------------------------------------------------
- Emits true if a function /must/ be resolved. The only time this is not
- the case is for extension-added functions added in a later revision of the
- extension, and where we have to cope with drivers written against an older
- revision.
-------------------------------------------------------------------------------
-*/}}
-{{define "IsRequiredFunction"}}
- {{AssertType $ "Function"}}
-
- {{if eq $.Name "vkGetSwapchainGrallocUsage2ANDROID"}}
- false
- {{else}}
- true
- {{end}}
-{{end}}
-
-
-{{/*
-------------------------------------------------------------------------------
Emits true if a function is exported and instance-dispatched.
------------------------------------------------------------------------------
*/}}
@@ -981,6 +963,8 @@
{{else if eq $.Name "vkCreateImage"}}true
{{else if eq $.Name "vkDestroyImage"}}true
+ {{else if eq $.Name "vkGetPhysicalDeviceProperties"}}true
+
{{end}}
{{$ext := GetAnnotation $ "extension"}}
diff --git a/vulkan/libvulkan/driver.cpp b/vulkan/libvulkan/driver.cpp
index 991c3ed..32f777d 100644
--- a/vulkan/libvulkan/driver.cpp
+++ b/vulkan/libvulkan/driver.cpp
@@ -899,7 +899,29 @@
return VK_ERROR_INCOMPATIBLE_DRIVER;
}
+
+ // sanity check ANDROID_native_buffer implementation, whose set of
+ // entrypoints varies according to the spec version.
+ if ((wrapper.GetHalExtensions()[ProcHook::ANDROID_native_buffer]) &&
+ !data->driver.GetSwapchainGrallocUsageANDROID &&
+ !data->driver.GetSwapchainGrallocUsage2ANDROID) {
+ ALOGE("Driver's implementation of ANDROID_native_buffer is broken;"
+ " must expose at least one of "
+ "vkGetSwapchainGrallocUsageANDROID or "
+ "vkGetSwapchainGrallocUsage2ANDROID");
+
+ data->driver.DestroyDevice(dev, pAllocator);
+ FreeDeviceData(data, data_allocator);
+
+ return VK_ERROR_INCOMPATIBLE_DRIVER;
+ }
+
+ VkPhysicalDeviceProperties properties;
+ instance_data.driver.GetPhysicalDeviceProperties(physicalDevice,
+ &properties);
+
data->driver_device = dev;
+ data->driver_version = properties.driverVersion;
*pDevice = dev;
diff --git a/vulkan/libvulkan/driver.h b/vulkan/libvulkan/driver.h
index e058439..5383f59 100644
--- a/vulkan/libvulkan/driver.h
+++ b/vulkan/libvulkan/driver.h
@@ -102,6 +102,7 @@
VkDevice driver_device;
DeviceDriverTable driver;
+ uint32_t driver_version;
};
bool Debuggable();
diff --git a/vulkan/libvulkan/driver_gen.cpp b/vulkan/libvulkan/driver_gen.cpp
index 689a228..951ea6e 100644
--- a/vulkan/libvulkan/driver_gen.cpp
+++ b/vulkan/libvulkan/driver_gen.cpp
@@ -387,6 +387,7 @@
INIT_PROC(true, instance, DestroyInstance);
INIT_PROC(true, instance, EnumeratePhysicalDevices);
INIT_PROC(true, instance, GetInstanceProcAddr);
+ INIT_PROC(true, instance, GetPhysicalDeviceProperties);
INIT_PROC(true, instance, CreateDevice);
INIT_PROC(true, instance, EnumerateDeviceExtensionProperties);
INIT_PROC_EXT(EXT_debug_report, true, instance, CreateDebugReportCallbackEXT);
@@ -410,7 +411,7 @@
INIT_PROC(true, dev, CreateImage);
INIT_PROC(true, dev, DestroyImage);
INIT_PROC(true, dev, AllocateCommandBuffers);
- INIT_PROC_EXT(ANDROID_native_buffer, true, dev, GetSwapchainGrallocUsageANDROID);
+ INIT_PROC_EXT(ANDROID_native_buffer, false, dev, GetSwapchainGrallocUsageANDROID);
INIT_PROC_EXT(ANDROID_native_buffer, false, dev, GetSwapchainGrallocUsage2ANDROID);
INIT_PROC_EXT(ANDROID_native_buffer, true, dev, AcquireImageANDROID);
INIT_PROC_EXT(ANDROID_native_buffer, true, dev, QueueSignalReleaseImageANDROID);
diff --git a/vulkan/libvulkan/driver_gen.h b/vulkan/libvulkan/driver_gen.h
index 9f3b705..95c70f8 100644
--- a/vulkan/libvulkan/driver_gen.h
+++ b/vulkan/libvulkan/driver_gen.h
@@ -60,6 +60,7 @@
PFN_vkDestroyInstance DestroyInstance;
PFN_vkEnumeratePhysicalDevices EnumeratePhysicalDevices;
PFN_vkGetInstanceProcAddr GetInstanceProcAddr;
+ PFN_vkGetPhysicalDeviceProperties GetPhysicalDeviceProperties;
PFN_vkCreateDevice CreateDevice;
PFN_vkEnumerateDeviceExtensionProperties EnumerateDeviceExtensionProperties;
PFN_vkCreateDebugReportCallbackEXT CreateDebugReportCallbackEXT;
diff --git a/vulkan/libvulkan/swapchain.cpp b/vulkan/libvulkan/swapchain.cpp
index f4ee375..c11d20f 100644
--- a/vulkan/libvulkan/swapchain.cpp
+++ b/vulkan/libvulkan/swapchain.cpp
@@ -812,13 +812,35 @@
int gralloc_usage = 0;
if (dispatch.GetSwapchainGrallocUsage2ANDROID) {
- result = dispatch.GetSwapchainGrallocUsage2ANDROID(
- device, create_info->imageFormat, create_info->imageUsage,
- swapchain_image_usage, &gralloc_usage);
+ uint64_t consumer_usage, producer_usage;
+ if (GetData(device).driver_version == 256587285) {
+ // HACK workaround for loader/driver mismatch during transition to
+ // vkGetSwapchainGrallocUsage2ANDROID.
+ typedef VkResult(VKAPI_PTR *
+ PFN_vkGetSwapchainGrallocUsage2ANDROID_HACK)(
+ VkDevice device, VkFormat format, VkImageUsageFlags imageUsage,
+ uint64_t * grallocConsumerUsage,
+ uint64_t * grallocProducerUsage);
+ auto get_swapchain_gralloc_usage =
+ reinterpret_cast<PFN_vkGetSwapchainGrallocUsage2ANDROID_HACK>(
+ dispatch.GetSwapchainGrallocUsage2ANDROID);
+ result = get_swapchain_gralloc_usage(
+ device, create_info->imageFormat, create_info->imageUsage,
+ &consumer_usage, &producer_usage);
+ } else {
+ result = dispatch.GetSwapchainGrallocUsage2ANDROID(
+ device, create_info->imageFormat, create_info->imageUsage,
+ swapchain_image_usage, &consumer_usage, &producer_usage);
+ }
if (result != VK_SUCCESS) {
ALOGE("vkGetSwapchainGrallocUsage2ANDROID failed: %d", result);
return VK_ERROR_INITIALIZATION_FAILED;
}
+ // TODO: This is the same translation done by Gralloc1On0Adapter.
+ // Remove it once ANativeWindow has been updated to take gralloc1-style
+ // usages.
+ gralloc_usage =
+ static_cast<int>(consumer_usage) | static_cast<int>(producer_usage);
} else if (dispatch.GetSwapchainGrallocUsageANDROID) {
result = dispatch.GetSwapchainGrallocUsageANDROID(
device, create_info->imageFormat, create_info->imageUsage,
@@ -827,8 +849,6 @@
ALOGE("vkGetSwapchainGrallocUsageANDROID failed: %d", result);
return VK_ERROR_INITIALIZATION_FAILED;
}
- } else {
- gralloc_usage = GRALLOC_USAGE_HW_RENDER | GRALLOC_USAGE_HW_TEXTURE;
}
err = native_window_set_usage(surface.window.get(), gralloc_usage);
if (err != 0) {
@@ -918,6 +938,12 @@
image_native_buffer.stride = img.buffer->stride;
image_native_buffer.format = img.buffer->format;
image_native_buffer.usage = img.buffer->usage;
+ // TODO: Adjust once ANativeWindowBuffer supports gralloc1-style usage.
+ // For now, this is the same translation Gralloc1On0Adapter does.
+ image_native_buffer.usage2.consumer =
+ static_cast<uint64_t>(img.buffer->usage);
+ image_native_buffer.usage2.producer =
+ static_cast<uint64_t>(img.buffer->usage);
result =
dispatch.CreateImage(device, &image_create, nullptr, &img.image);
diff --git a/vulkan/nulldrv/null_driver.cpp b/vulkan/nulldrv/null_driver.cpp
index 55f7f19..e03ee0a 100644
--- a/vulkan/nulldrv/null_driver.cpp
+++ b/vulkan/nulldrv/null_driver.cpp
@@ -906,9 +906,11 @@
VkFormat,
VkImageUsageFlags,
VkSwapchainImageUsageFlagsANDROID,
- int* grallocUsage) {
+ uint64_t* grallocConsumerUsage,
+ uint64_t* grallocProducerUsage) {
// The null driver never reads or writes the gralloc buffer
- *grallocUsage = 0;
+ *grallocConsumerUsage = 0;
+ *grallocProducerUsage = 0;
return VK_SUCCESS;
}
diff --git a/vulkan/nulldrv/null_driver_gen.h b/vulkan/nulldrv/null_driver_gen.h
index cfc14dd..d73bf14 100644
--- a/vulkan/nulldrv/null_driver_gen.h
+++ b/vulkan/nulldrv/null_driver_gen.h
@@ -165,8 +165,8 @@
VKAPI_ATTR void CmdNextSubpass(VkCommandBuffer commandBuffer, VkSubpassContents contents);
VKAPI_ATTR void CmdEndRenderPass(VkCommandBuffer commandBuffer);
VKAPI_ATTR void CmdExecuteCommands(VkCommandBuffer commandBuffer, uint32_t commandBufferCount, const VkCommandBuffer* pCommandBuffers);
-VKAPI_ATTR VkResult GetSwapchainGrallocUsageANDROID(VkDevice device, VkFormat format, VkImageUsageFlags imageUsage, int* grallocUsage);
-VKAPI_ATTR VkResult GetSwapchainGrallocUsage2ANDROID(VkDevice device, VkFormat format, VkImageUsageFlags imageUsage, VkSwapchainImageUsageFlagsANDROID swapchainImageUsage, int* grallocUsage);
+VKAPI_ATTR VkResult GetSwapchainGrallocUsageANDROID(VkDevice device, VkFormat format, VkImageUsageFlags imageUsage, int32_t* grallocUsage);
+VKAPI_ATTR VkResult GetSwapchainGrallocUsage2ANDROID(VkDevice device, VkFormat format, VkImageUsageFlags imageUsage, VkSwapchainImageUsageFlagsANDROID swapchainImageUsage, uint64_t* grallocConsumerUsage, uint64_t* grallocProducerUsage);
VKAPI_ATTR VkResult AcquireImageANDROID(VkDevice device, VkImage image, int nativeFenceFd, VkSemaphore semaphore, VkFence fence);
VKAPI_ATTR VkResult QueueSignalReleaseImageANDROID(VkQueue queue, uint32_t waitSemaphoreCount, const VkSemaphore* pWaitSemaphores, VkImage image, int* pNativeFenceFd);
VKAPI_ATTR VkResult CreateDebugReportCallbackEXT(VkInstance instance, const VkDebugReportCallbackCreateInfoEXT* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkDebugReportCallbackEXT* pCallback);