Merge changes Iad7bf035,I870e08c6
* changes:
VNDK ANativeWindow API - step 2
VNDK ANativeWindow API
diff --git a/cmds/lshal/Android.bp b/cmds/lshal/Android.bp
index 39e0ba3..4740202 100644
--- a/cmds/lshal/Android.bp
+++ b/cmds/lshal/Android.bp
@@ -16,6 +16,7 @@
name: "lshal",
shared_libs: [
"libbase",
+ "libcutils",
"libutils",
"libhidlbase",
"libhidltransport",
@@ -24,6 +25,7 @@
"android.hidl.manager@1.0",
],
srcs: [
- "Lshal.cpp"
+ "Lshal.cpp",
+ "PipeRelay.cpp"
],
}
diff --git a/cmds/lshal/Lshal.cpp b/cmds/lshal/Lshal.cpp
index a5cac15..420ec3c 100644
--- a/cmds/lshal/Lshal.cpp
+++ b/cmds/lshal/Lshal.cpp
@@ -25,13 +25,17 @@
#include <sstream>
#include <regex>
+#include <android-base/logging.h>
#include <android-base/parseint.h>
#include <android/hidl/manager/1.0/IServiceManager.h>
#include <hidl/ServiceManagement.h>
#include <hidl-util/FQName.h>
+#include <private/android_filesystem_config.h>
+#include <sys/stat.h>
#include <vintf/HalManifest.h>
#include <vintf/parse_xml.h>
+#include "PipeRelay.h"
#include "Timeout.h"
using ::android::hardware::hidl_string;
@@ -357,6 +361,52 @@
}
}
+// A unique_ptr type using a custom deleter function.
+template<typename T>
+using deleted_unique_ptr = std::unique_ptr<T, std::function<void(T *)> >;
+
+void Lshal::emitDebugInfo(
+ const sp<IServiceManager> &serviceManager,
+ const std::string &interfaceName,
+ const std::string &instanceName) const {
+ using android::hidl::base::V1_0::IBase;
+
+ hardware::Return<sp<IBase>> retBase =
+ serviceManager->get(interfaceName, instanceName);
+
+ sp<IBase> base;
+ if (!retBase.isOk() || (base = retBase) == nullptr) {
+ // There's a small race, where a service instantiated while collecting
+ // the list of services has by now terminated, so this isn't anything
+ // to be concerned about.
+ return;
+ }
+
+ PipeRelay relay(mOut.buf());
+
+ if (relay.initCheck() != OK) {
+ LOG(ERROR) << "PipeRelay::initCheck() FAILED w/ " << relay.initCheck();
+ return;
+ }
+
+ deleted_unique_ptr<native_handle_t> fdHandle(
+ native_handle_create(1 /* numFds */, 0 /* numInts */),
+ native_handle_delete);
+
+ fdHandle->data[0] = relay.fd();
+
+ hardware::hidl_vec<hardware::hidl_string> options;
+ hardware::Return<void> ret = base->debug(fdHandle.get(), options);
+
+ if (!ret.isOk()) {
+ LOG(ERROR)
+ << interfaceName
+ << "::debug(...) FAILED. (instance "
+ << instanceName
+ << ")";
+ }
+}
+
void Lshal::dumpTable() {
mServicesTable.description =
"All binderized services (registered services through hwservicemanager)";
@@ -374,6 +424,16 @@
mOut << std::left;
printLine("Interface", "Transport", "Arch", "Server", "Server CMD",
"PTR", "Clients", "Clients CMD");
+
+ // We're only interested in dumping debug info for already
+ // instantiated services. There's little value in dumping the
+ // debug info for a service we create on the fly, so we only operate
+ // on the "mServicesTable".
+ sp<IServiceManager> serviceManager;
+ if (mEmitDebugInfo && &table == &mServicesTable) {
+ serviceManager = ::android::hardware::defaultServiceManager();
+ }
+
for (const auto &entry : table) {
printLine(entry.interfaceName,
entry.transport,
@@ -383,6 +443,11 @@
entry.serverObjectAddress == NO_PTR ? "N/A" : toHexString(entry.serverObjectAddress),
join(entry.clientPids, " "),
join(entry.clientCmdlines, ";"));
+
+ if (serviceManager != nullptr) {
+ auto pair = splitFirst(entry.interfaceName, '/');
+ emitDebugInfo(serviceManager, pair.first, pair.second);
+ }
}
mOut << std::endl;
});
@@ -626,6 +691,7 @@
{"address", no_argument, 0, 'a' },
{"clients", no_argument, 0, 'c' },
{"cmdline", no_argument, 0, 'm' },
+ {"debug", optional_argument, 0, 'd' },
// long options without short alternatives
{"sort", required_argument, 0, 's' },
@@ -638,7 +704,7 @@
optind = 1;
for (;;) {
// using getopt_long in case we want to add other options in the future
- c = getopt_long(argc, argv, "hitrpacm", longOptions, &optionIndex);
+ c = getopt_long(argc, argv, "hitrpacmd", longOptions, &optionIndex);
if (c == -1) {
break;
}
@@ -694,6 +760,20 @@
mEnableCmdlines = true;
break;
}
+ case 'd': {
+ mEmitDebugInfo = true;
+
+ 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;
+ }
+ chown(optarg, AID_SHELL, AID_SHELL);
+ }
+ break;
+ }
case 'h': // falls through
default: // see unrecognized options
usage();
diff --git a/cmds/lshal/Lshal.h b/cmds/lshal/Lshal.h
index c9c6660..a21e86c 100644
--- a/cmds/lshal/Lshal.h
+++ b/cmds/lshal/Lshal.h
@@ -77,6 +77,11 @@
void forEachTable(const std::function<void(Table &)> &f);
void forEachTable(const std::function<void(const Table &)> &f) const;
+ void emitDebugInfo(
+ const sp<hidl::manager::V1_0::IServiceManager> &serviceManager,
+ const std::string &interfaceName,
+ const std::string &instanceName) const;
+
Table mServicesTable{};
Table mPassthroughRefTable{};
Table mImplementationsTable{};
@@ -88,6 +93,10 @@
TableEntrySelect mSelectedColumns = 0;
// If true, cmdlines will be printed instead of pid.
bool mEnableCmdlines = false;
+
+ // If true, calls IBase::debug(...) on each service.
+ bool mEmitDebugInfo = 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.
diff --git a/cmds/lshal/PipeRelay.cpp b/cmds/lshal/PipeRelay.cpp
new file mode 100644
index 0000000..c7b29df
--- /dev/null
+++ b/cmds/lshal/PipeRelay.cpp
@@ -0,0 +1,108 @@
+/*
+ * 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.
+ */
+
+#include "PipeRelay.h"
+
+#include <sys/socket.h>
+#include <utils/Thread.h>
+
+namespace android {
+namespace lshal {
+
+struct PipeRelay::RelayThread : public Thread {
+ explicit RelayThread(int fd, std::ostream &os);
+
+ bool threadLoop() override;
+
+private:
+ int mFd;
+ std::ostream &mOutStream;
+
+ DISALLOW_COPY_AND_ASSIGN(RelayThread);
+};
+
+////////////////////////////////////////////////////////////////////////////////
+
+PipeRelay::RelayThread::RelayThread(int fd, std::ostream &os)
+ : mFd(fd),
+ mOutStream(os) {
+}
+
+bool PipeRelay::RelayThread::threadLoop() {
+ char buffer[1024];
+ ssize_t n = read(mFd, buffer, sizeof(buffer));
+
+ if (n <= 0) {
+ return false;
+ }
+
+ mOutStream.write(buffer, n);
+
+ return true;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+PipeRelay::PipeRelay(std::ostream &os)
+ : mOutStream(os),
+ mInitCheck(NO_INIT) {
+ int res = socketpair(AF_UNIX, SOCK_STREAM, 0 /* protocol */, mFds);
+
+ if (res < 0) {
+ mInitCheck = -errno;
+ return;
+ }
+
+ mThread = new RelayThread(mFds[0], os);
+ mInitCheck = mThread->run("RelayThread");
+}
+
+// static
+void PipeRelay::CloseFd(int *fd) {
+ if (*fd >= 0) {
+ close(*fd);
+ *fd = -1;
+ }
+}
+
+PipeRelay::~PipeRelay() {
+ if (mFds[1] >= 0) {
+ shutdown(mFds[1], SHUT_WR);
+ }
+
+ if (mFds[0] >= 0) {
+ shutdown(mFds[0], SHUT_RD);
+ }
+
+ if (mThread != NULL) {
+ mThread->join();
+ mThread.clear();
+ }
+
+ CloseFd(&mFds[1]);
+ CloseFd(&mFds[0]);
+}
+
+status_t PipeRelay::initCheck() const {
+ return mInitCheck;
+}
+
+int PipeRelay::fd() const {
+ return mFds[1];
+}
+
+} // namespace lshal
+} // namespace android
diff --git a/cmds/lshal/PipeRelay.h b/cmds/lshal/PipeRelay.h
new file mode 100644
index 0000000..76b2b23
--- /dev/null
+++ b/cmds/lshal/PipeRelay.h
@@ -0,0 +1,59 @@
+/*
+ * 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.
+ */
+
+#ifndef FRAMEWORKS_NATIVE_CMDS_LSHAL_PIPE_RELAY_H_
+
+#define FRAMEWORKS_NATIVE_CMDS_LSHAL_PIPE_RELAY_H_
+
+#include <android-base/macros.h>
+#include <ostream>
+#include <utils/Errors.h>
+#include <utils/RefBase.h>
+
+namespace android {
+namespace lshal {
+
+/* Creates an AF_UNIX socketpair and spawns a thread that relays any data
+ * written to the "write"-end of the pair to the specified output stream "os".
+ */
+struct PipeRelay {
+ explicit PipeRelay(std::ostream &os);
+ ~PipeRelay();
+
+ status_t initCheck() const;
+
+ // Returns the file descriptor corresponding to the "write"-end of the
+ // connection.
+ int fd() const;
+
+private:
+ struct RelayThread;
+
+ std::ostream &mOutStream;
+ status_t mInitCheck;
+ int mFds[2];
+ sp<RelayThread> mThread;
+
+ static void CloseFd(int *fd);
+
+ DISALLOW_COPY_AND_ASSIGN(PipeRelay);
+};
+
+} // namespace lshal
+} // namespace android
+
+#endif // FRAMEWORKS_NATIVE_CMDS_LSHAL_PIPE_RELAY_H_
+
diff --git a/include/gfx/SafeLog.h b/include/gfx/SafeLog.h
deleted file mode 100644
index e45e541..0000000
--- a/include/gfx/SafeLog.h
+++ /dev/null
@@ -1,106 +0,0 @@
-/*
- * Copyright 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.
- */
-
-#pragma once
-
-#pragma clang diagnostic push
-#pragma clang diagnostic ignored "-Weverything"
-#include <fmt/format.h>
-#include <log/log.h>
-#pragma clang diagnostic pop
-
-#include <type_traits>
-
-namespace android {
-namespace gfx {
-
-/* SafeLog is a mix-in that can be used to easily add typesafe logging using fmtlib to any class.
- * To use it, inherit from it using CRTP and implement the getLogTag method.
- *
- * For example:
- *
- * class Frobnicator : private SafeLog<Frobnicator> {
- * friend class SafeLog<Frobnicator>; // Allows getLogTag to be private
- *
- * public:
- * void frobnicate(int32_t i);
- *
- * private:
- * // SafeLog does member access on the object calling alog*, so this tag can theoretically vary
- * // by instance unless getLogTag is made static
- * const char* getLogTag() { return "Frobnicator"; }
- * };
- *
- * void Frobnicator::frobnicate(int32_t i) {
- * // Logs something like "04-16 21:35:46.811 3513 3513 I Frobnicator: frobnicating 42"
- * alogi("frobnicating {}", i);
- * }
- *
- * See http://fmtlib.net for more information on the formatting API.
- */
-
-template <typename T>
-class SafeLog {
- protected:
- template <typename... Args>
-#if LOG_NDEBUG
- void alogv(Args&&... /*unused*/) const {
- }
-#else
- void alogv(Args&&... args) const {
- alog<ANDROID_LOG_VERBOSE>(std::forward<Args>(args)...);
- }
-#endif
-
- template <typename... Args>
- void alogd(Args&&... args) const {
- alog<ANDROID_LOG_DEBUG>(std::forward<Args>(args)...);
- }
-
- template <typename... Args>
- void alogi(Args&&... args) const {
- alog<ANDROID_LOG_INFO>(std::forward<Args>(args)...);
- }
-
- template <typename... Args>
- void alogw(Args&&... args) const {
- alog<ANDROID_LOG_WARN>(std::forward<Args>(args)...);
- }
-
- template <typename... Args>
- void aloge(Args&&... args) const {
- alog<ANDROID_LOG_ERROR>(std::forward<Args>(args)...);
- }
-
- private:
- // Suppresses clang-tidy check cppcoreguidelines-pro-bounds-array-to-pointer-decay
- template <size_t strlen, typename... Args>
- void write(fmt::MemoryWriter* writer, const char (&str)[strlen], Args&&... args) const {
- writer->write(static_cast<const char*>(str), std::forward<Args>(args)...);
- }
-
- template <int priority, typename... Args>
- void alog(Args&&... args) const {
- static_assert(std::is_base_of<SafeLog<T>, T>::value, "Can't convert to SafeLog pointer");
- fmt::MemoryWriter writer;
- write(&writer, std::forward<Args>(args)...);
- auto derivedThis = static_cast<const T*>(this);
- android_writeLog(priority, derivedThis->getLogTag(), writer.c_str());
- }
-};
-
-} // namespace gfx
-} // namespace android
diff --git a/libs/vr/libbufferhub/Android.bp b/libs/vr/libbufferhub/Android.bp
index e068469..452bad0 100644
--- a/libs/vr/libbufferhub/Android.bp
+++ b/libs/vr/libbufferhub/Android.bp
@@ -15,7 +15,6 @@
sourceFiles = [
"buffer_hub_client.cpp",
"buffer_hub_rpc.cpp",
- "dvr_buffer.cpp",
"ion_buffer.cpp",
]
diff --git a/libs/vr/libbufferhubqueue/Android.bp b/libs/vr/libbufferhubqueue/Android.bp
index 1c8f2c0..2d96638 100644
--- a/libs/vr/libbufferhubqueue/Android.bp
+++ b/libs/vr/libbufferhubqueue/Android.bp
@@ -43,7 +43,7 @@
cc_library {
name: "libbufferhubqueue",
cflags = [
- "-DLOGTAG=\"libbufferhubqueue\"",
+ "-DLOG_TAG=\"libbufferhubqueue\"",
"-DTRACE=0",
],
srcs: sourceFiles,
diff --git a/libs/vr/libbufferhubqueue/include/private/dvr/buffer_hub_queue_client.h b/libs/vr/libbufferhubqueue/include/private/dvr/buffer_hub_queue_client.h
index feaf3d7..f786356 100644
--- a/libs/vr/libbufferhubqueue/include/private/dvr/buffer_hub_queue_client.h
+++ b/libs/vr/libbufferhubqueue/include/private/dvr/buffer_hub_queue_client.h
@@ -329,6 +329,9 @@
return Dequeue(timeout, slot, meta, sizeof(*meta), acquire_fence);
}
+ std::shared_ptr<BufferConsumer> Dequeue(int timeout, size_t* slot, void* meta,
+ size_t meta_size,
+ LocalHandle* acquire_fence);
private:
friend BASE;
@@ -344,13 +347,27 @@
LocalHandle* acquire_fence) override;
int OnBufferAllocated() override;
-
- std::shared_ptr<BufferConsumer> Dequeue(int timeout, size_t* slot, void* meta,
- size_t meta_size,
- LocalHandle* acquire_fence);
};
} // namespace dvr
} // namespace android
+// Concrete C type definition for DVR API.
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct DvrWriteBufferQueue {
+ std::shared_ptr<android::dvr::ProducerQueue> producer_queue_;
+};
+
+struct DvrReadBufferQueue {
+ std::shared_ptr<android::dvr::ConsumerQueue> consumer_queue_;
+};
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
#endif // ANDROID_DVR_BUFFER_HUB_QUEUE_CLIENT_H_
diff --git a/libs/vr/libbufferhubqueue/tests/Android.bp b/libs/vr/libbufferhubqueue/tests/Android.bp
index b8a0da3..865573c 100644
--- a/libs/vr/libbufferhubqueue/tests/Android.bp
+++ b/libs/vr/libbufferhubqueue/tests/Android.bp
@@ -24,6 +24,7 @@
static_libs: static_libraries,
shared_libs: shared_libraries,
cflags: [
+ "-DLOG_TAG=\"buffer_hub_queue-test\"",
"-DTRACE=0",
"-O0",
"-g",
@@ -37,6 +38,7 @@
static_libs: static_libraries,
shared_libs: shared_libraries,
cflags: [
+ "-DLOG_TAG=\"buffer_hub_queue_producer-test\"",
"-DTRACE=0",
"-O0",
"-g",
diff --git a/libs/vr/libdisplay/Android.bp b/libs/vr/libdisplay/Android.bp
index f3c71b5..de2a56e 100644
--- a/libs/vr/libdisplay/Android.bp
+++ b/libs/vr/libdisplay/Android.bp
@@ -15,7 +15,6 @@
sourceFiles = [
"native_buffer_queue.cpp",
"display_client.cpp",
- "display_manager_client.cpp",
"display_manager_client_impl.cpp",
"display_rpc.cpp",
"dummy_native_window.cpp",
@@ -24,7 +23,6 @@
"late_latch.cpp",
"video_mesh_surface_client.cpp",
"vsync_client.cpp",
- "vsync_client_api.cpp",
"screenshot_client.cpp",
"frame_history.cpp",
]
diff --git a/libs/vr/libdisplay/graphics.cpp b/libs/vr/libdisplay/graphics.cpp
index 3713389..2abdf8e 100644
--- a/libs/vr/libdisplay/graphics.cpp
+++ b/libs/vr/libdisplay/graphics.cpp
@@ -17,7 +17,6 @@
#include <private/dvr/clock_ns.h>
#include <private/dvr/debug.h>
#include <private/dvr/display_types.h>
-#include <private/dvr/dvr_buffer.h>
#include <private/dvr/frame_history.h>
#include <private/dvr/gl_fenced_flush.h>
#include <private/dvr/graphics/vr_gl_extensions.h>
@@ -1575,14 +1574,3 @@
};
}
}
-
-extern "C" int dvrGetPoseBuffer(DvrReadBuffer** pose_buffer) {
- auto client = android::dvr::DisplayClient::Create();
- if (!client) {
- ALOGE("Failed to create display client!");
- return -ECOMM;
- }
-
- *pose_buffer = CreateDvrReadBufferFromBufferConsumer(client->GetPoseBuffer());
- return 0;
-}
diff --git a/libs/vr/libdisplay/include/dvr/graphics.h b/libs/vr/libdisplay/include/dvr/graphics.h
index fc51d52..ac8b27f 100644
--- a/libs/vr/libdisplay/include/dvr/graphics.h
+++ b/libs/vr/libdisplay/include/dvr/graphics.h
@@ -442,9 +442,6 @@
const int eye,
const float* transform);
-// Get a pointer to the global pose buffer.
-int dvrGetPoseBuffer(DvrReadBuffer** pose_buffer);
-
__END_DECLS
#endif // DVR_GRAPHICS_H_
diff --git a/libs/vr/libdisplay/include/private/dvr/vsync_client.h b/libs/vr/libdisplay/include/private/dvr/vsync_client.h
index 32fa40f..1eeb80e 100644
--- a/libs/vr/libdisplay/include/private/dvr/vsync_client.h
+++ b/libs/vr/libdisplay/include/private/dvr/vsync_client.h
@@ -4,7 +4,6 @@
#include <stdint.h>
#include <pdx/client.h>
-#include <private/dvr/vsync_client_api.h>
struct dvr_vsync_client {};
diff --git a/libs/vr/libdvr/Android.mk b/libs/vr/libdvr/Android.mk
new file mode 100644
index 0000000..5449cb5
--- /dev/null
+++ b/libs/vr/libdvr/Android.mk
@@ -0,0 +1,54 @@
+# 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.
+LOCAL_PATH := $(call my-dir)
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := libdvr
+LOCAL_MODULE_OWNER := google
+LOCAL_MODULE_CLASS := STATIC_LIBRARIES
+
+LOCAL_CFLAGS += \
+ -fvisibility=hidden \
+ -D DVR_EXPORT='__attribute__ ((visibility ("default")))'
+
+LOCAL_C_INCLUDES := \
+ $(LOCAL_PATH)/include \
+
+LOCAL_EXPORT_C_INCLUDE_DIRS := \
+ $(LOCAL_PATH)/include \
+
+LOCAL_SRC_FILES := \
+ display_manager_client.cpp \
+ dvr_api.cpp \
+ dvr_buffer.cpp \
+ dvr_buffer_queue.cpp \
+ dvr_surface.cpp \
+ vsync_client_api.cpp \
+
+LOCAL_STATIC_LIBRARIES := \
+ libbufferhub \
+ libbufferhubqueue \
+ libdisplay \
+ libvrsensor \
+ libvirtualtouchpadclient \
+
+LOCAL_SHARED_LIBRARIES := \
+ android.hardware.graphics.bufferqueue@1.0 \
+ android.hidl.token@1.0-utils \
+ libandroid_runtime \
+ libbase \
+
+include $(BUILD_STATIC_LIBRARY)
+
+include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/libs/vr/libdisplay/display_manager_client.cpp b/libs/vr/libdvr/display_manager_client.cpp
similarity index 97%
rename from libs/vr/libdisplay/display_manager_client.cpp
rename to libs/vr/libdvr/display_manager_client.cpp
index d60d35b..7cbfc21 100644
--- a/libs/vr/libdisplay/display_manager_client.cpp
+++ b/libs/vr/libdvr/display_manager_client.cpp
@@ -1,8 +1,8 @@
-#include "include/private/dvr/display_manager_client.h"
+#include "include/dvr/display_manager_client.h"
+#include <dvr/dvr_buffer.h>
#include <private/dvr/buffer_hub_client.h>
#include <private/dvr/display_manager_client_impl.h>
-#include <private/dvr/dvr_buffer.h>
using android::dvr::DisplaySurfaceAttributeEnum;
diff --git a/libs/vr/libdvr/dvr_api.cpp b/libs/vr/libdvr/dvr_api.cpp
new file mode 100644
index 0000000..4dd49da
--- /dev/null
+++ b/libs/vr/libdvr/dvr_api.cpp
@@ -0,0 +1,106 @@
+#include "include/dvr/dvr_api.h"
+
+#include <errno.h>
+
+// Headers from libdvr
+#include <dvr/display_manager_client.h>
+#include <dvr/dvr_buffer.h>
+#include <dvr/dvr_buffer_queue.h>
+#include <dvr/dvr_surface.h>
+#include <dvr/vsync_client_api.h>
+
+// Headers not yet moved into libdvr.
+// TODO(jwcai) Move these once their callers are moved into Google3.
+#include <dvr/pose_client.h>
+#include <dvr/virtual_touchpad_client.h>
+
+extern "C" {
+
+DVR_EXPORT int dvrGetApi(void* api, size_t struct_size, int version) {
+ if (version == 1) {
+ if (struct_size != sizeof(DvrApi_v1)) {
+ return -EINVAL;
+ }
+ DvrApi_v1* dvr_api = static_cast<DvrApi_v1*>(api);
+
+ // display_manager_client.h
+ dvr_api->display_manager_client_create_ = dvrDisplayManagerClientCreate;
+ dvr_api->display_manager_client_destroy_ = dvrDisplayManagerClientDestroy;
+ dvr_api->display_manager_client_get_surface_list_ =
+ dvrDisplayManagerClientGetSurfaceList;
+ dvr_api->display_manager_client_surface_list_destroy_ =
+ dvrDisplayManagerClientSurfaceListDestroy;
+ dvr_api->display_manager_setup_pose_buffer_ =
+ dvrDisplayManagerSetupPoseBuffer;
+ dvr_api->display_manager_client_surface_list_get_size_ =
+ dvrDisplayManagerClientSurfaceListGetSize;
+ dvr_api->display_manager_client_surface_list_get_surface_id_ =
+ dvrDisplayManagerClientSurfaceListGetSurfaceId;
+ dvr_api->display_manager_client_get_surface_buffer_list_ =
+ dvrDisplayManagerClientGetSurfaceBuffers;
+ dvr_api->display_manager_client_surface_buffer_list_destroy_ =
+ dvrDisplayManagerClientSurfaceBuffersDestroy;
+ dvr_api->display_manager_client_surface_buffer_list_get_size_ =
+ dvrDisplayManagerClientSurfaceBuffersGetSize;
+ dvr_api->display_manager_client_surface_buffer_list_get_fd_ =
+ dvrDisplayManagerClientSurfaceBuffersGetFd;
+
+ // dvr_buffer.h
+ dvr_api->write_buffer_destroy_ = dvrWriteBufferDestroy;
+ dvr_api->write_buffer_get_blob_fds_ = dvrWriteBufferGetBlobFds;
+ dvr_api->write_buffer_get_AHardwareBuffer_ =
+ dvrWriteBufferGetAHardwareBuffer;
+ dvr_api->write_buffer_post_ = dvrWriteBufferPost;
+ dvr_api->write_buffer_gain_ = dvrWriteBufferGain;
+ dvr_api->write_buffer_gain_async_ = dvrWriteBufferGainAsync;
+
+ dvr_api->read_buffer_destroy_ = dvrReadBufferDestroy;
+ dvr_api->read_buffer_get_blob_fds_ = dvrReadBufferGetBlobFds;
+ dvr_api->read_buffer_get_AHardwareBuffer_ = dvrReadBufferGetAHardwareBuffer;
+ dvr_api->read_buffer_acquire_ = dvrReadBufferAcquire;
+ dvr_api->read_buffer_release_ = dvrReadBufferRelease;
+ dvr_api->read_buffer_release_async_ = dvrReadBufferReleaseAsync;
+
+ // dvr_buffer_queue.h
+ dvr_api->write_buffer_queue_destroy_ = dvrWriteBufferQueueDestroy;
+ dvr_api->write_buffer_queue_get_capacity_ = dvrWriteBufferQueueGetCapacity;
+ dvr_api->write_buffer_queue_get_external_surface_ =
+ dvrWriteBufferQueueGetExternalSurface;
+ dvr_api->write_buffer_queue_create_read_queue_ =
+ dvrWriteBufferQueueCreateReadQueue;
+ dvr_api->write_buffer_queue_dequeue_ = dvrWriteBufferQueueDequeue;
+ dvr_api->read_buffer_queue_destroy_ = dvrReadBufferQueueDestroy;
+ dvr_api->read_buffer_queue_get_capacity_ = dvrReadBufferQueueGetCapacity;
+ dvr_api->read_buffer_queue_create_read_queue_ =
+ dvrReadBufferQueueCreateReadQueue;
+ dvr_api->read_buffer_queue_dequeue = dvrReadBufferQueueDequeue;
+
+ // dvr_surface.h
+ dvr_api->get_pose_buffer_ = dvrGetPoseBuffer;
+
+ // vsync_client_api.h
+ dvr_api->vsync_client_create_ = dvr_vsync_client_create;
+ dvr_api->vsync_client_destroy_ = dvr_vsync_client_destroy;
+ dvr_api->vsync_client_get_sched_info_ = dvr_vsync_client_get_sched_info;
+
+ // pose_client.h
+ dvr_api->pose_client_create_ = dvrPoseCreate;
+ dvr_api->pose_client_destroy_ = dvrPoseDestroy;
+ dvr_api->pose_get_ = dvrPoseGet;
+ dvr_api->pose_get_vsync_count_ = dvrPoseGetVsyncCount;
+ dvr_api->pose_get_controller_ = dvrPoseGetController;
+
+ // virtual_touchpad_client.h
+ dvr_api->virtual_touchpad_create_ = dvrVirtualTouchpadCreate;
+ dvr_api->virtual_touchpad_destroy_ = dvrVirtualTouchpadDestroy;
+ dvr_api->virtual_touchpad_attach_ = dvrVirtualTouchpadAttach;
+ dvr_api->virtual_touchpad_detach_ = dvrVirtualTouchpadDetach;
+ dvr_api->virtual_touchpad_touch_ = dvrVirtualTouchpadTouch;
+ dvr_api->virtual_touchpad_button_state_ = dvrVirtualTouchpadButtonState;
+
+ return 0;
+ }
+ return -EINVAL;
+}
+
+} // extern "C"
diff --git a/libs/vr/libbufferhub/dvr_buffer.cpp b/libs/vr/libdvr/dvr_buffer.cpp
similarity index 91%
rename from libs/vr/libbufferhub/dvr_buffer.cpp
rename to libs/vr/libdvr/dvr_buffer.cpp
index 3eb611f..25128a6 100644
--- a/libs/vr/libbufferhub/dvr_buffer.cpp
+++ b/libs/vr/libdvr/dvr_buffer.cpp
@@ -1,16 +1,17 @@
+#include "include/dvr/dvr_buffer.h"
+
#include <private/dvr/buffer_hub_client.h>
-#include <private/dvr/dvr_buffer.h>
#include <ui/GraphicBuffer.h>
using namespace android;
struct DvrWriteBuffer {
- std::unique_ptr<dvr::BufferProducer> write_buffer_;
+ std::shared_ptr<dvr::BufferProducer> write_buffer_;
sp<GraphicBuffer> graphic_buffer_;
};
struct DvrReadBuffer {
- std::unique_ptr<dvr::BufferConsumer> read_buffer_;
+ std::shared_ptr<dvr::BufferConsumer> read_buffer_;
sp<GraphicBuffer> graphic_buffer_;
};
@@ -18,14 +19,14 @@
namespace dvr {
DvrWriteBuffer* CreateDvrWriteBufferFromBufferProducer(
- std::unique_ptr<dvr::BufferProducer> buffer_producer) {
+ const std::shared_ptr<dvr::BufferProducer>& buffer_producer) {
DvrWriteBuffer* write_buffer = new DvrWriteBuffer;
write_buffer->write_buffer_ = std::move(buffer_producer);
return write_buffer;
}
DvrReadBuffer* CreateDvrReadBufferFromBufferConsumer(
- std::unique_ptr<dvr::BufferConsumer> buffer_consumer) {
+ const std::shared_ptr<dvr::BufferConsumer>& buffer_consumer) {
DvrReadBuffer* read_buffer = new DvrReadBuffer;
read_buffer->read_buffer_ = std::move(buffer_consumer);
return read_buffer;
@@ -85,6 +86,8 @@
return client->write_buffer_->GainAsync();
}
+void dvrReadBufferDestroy(DvrReadBuffer* client) { delete client; }
+
void dvrReadBufferGetBlobFds(DvrReadBuffer* client, int* fds, size_t* fds_count,
size_t max_fds_count) {
client->read_buffer_->GetBlobFds(fds, fds_count, max_fds_count);
diff --git a/libs/vr/libdvr/dvr_buffer_queue.cpp b/libs/vr/libdvr/dvr_buffer_queue.cpp
new file mode 100644
index 0000000..b0b5a2a
--- /dev/null
+++ b/libs/vr/libdvr/dvr_buffer_queue.cpp
@@ -0,0 +1,146 @@
+#include "include/dvr/dvr_buffer_queue.h"
+
+#include <gui/Surface.h>
+#include <private/dvr/buffer_hub_queue_client.h>
+#include <private/dvr/buffer_hub_queue_producer.h>
+
+#include <android_runtime/android_view_Surface.h>
+
+#define CHECK_PARAM(param) \
+ LOG_ALWAYS_FATAL_IF(param == nullptr, "%s: " #param "cannot be NULL.", \
+ __FUNCTION__)
+
+using namespace android;
+
+extern "C" {
+
+void dvrWriteBufferQueueDestroy(DvrWriteBufferQueue* write_queue) {
+ delete write_queue;
+}
+
+size_t dvrWriteBufferQueueGetCapacity(DvrWriteBufferQueue* write_queue) {
+ CHECK_PARAM(write_queue);
+ return write_queue->producer_queue_->capacity();
+}
+
+void* dvrWriteBufferQueueGetExternalSurface(DvrWriteBufferQueue* write_queue,
+ JNIEnv* env) {
+ CHECK_PARAM(env);
+ CHECK_PARAM(write_queue);
+
+ std::shared_ptr<dvr::BufferHubQueueCore> core =
+ dvr::BufferHubQueueCore::Create(write_queue->producer_queue_);
+
+ return android_view_Surface_createFromIGraphicBufferProducer(
+ env, new dvr::BufferHubQueueProducer(core));
+}
+
+int dvrWriteBufferQueueCreateReadQueue(DvrWriteBufferQueue* write_queue,
+ DvrReadBufferQueue** out_read_queue) {
+ CHECK_PARAM(write_queue);
+ CHECK_PARAM(write_queue->producer_queue_);
+ CHECK_PARAM(out_read_queue);
+
+ auto read_queue = std::make_unique<DvrReadBufferQueue>();
+ read_queue->consumer_queue_ =
+ write_queue->producer_queue_->CreateConsumerQueue();
+ if (read_queue->consumer_queue_ == nullptr) {
+ ALOGE(
+ "dvrWriteBufferQueueCreateReadQueue: Failed to create consumer queue "
+ "from DvrWriteBufferQueue[%p].",
+ write_queue);
+ return -ENOMEM;
+ }
+
+ *out_read_queue = read_queue.release();
+ return 0;
+}
+
+int dvrWriteBufferQueueDequeue(DvrWriteBufferQueue* write_queue, int timeout,
+ DvrWriteBuffer** out_buffer,
+ int* out_fence_fd) {
+ CHECK_PARAM(write_queue);
+ CHECK_PARAM(write_queue->producer_queue_);
+ CHECK_PARAM(out_buffer);
+ CHECK_PARAM(out_fence_fd);
+
+ size_t slot;
+ pdx::LocalHandle release_fence;
+ std::shared_ptr<dvr::BufferProducer> buffer =
+ write_queue->producer_queue_->Dequeue(timeout, &slot, &release_fence);
+ if (buffer == nullptr) {
+ ALOGE("dvrWriteBufferQueueDequeue: Failed to dequeue buffer.");
+ return -ENOMEM;
+ }
+
+ *out_buffer = CreateDvrWriteBufferFromBufferProducer(buffer);
+ *out_fence_fd = release_fence.Release();
+ return 0;
+}
+
+// ReadBufferQueue
+void dvrReadBufferQueueDestroy(DvrReadBufferQueue* read_queue) {
+ delete read_queue;
+}
+
+size_t dvrReadBufferQueueGetCapacity(DvrReadBufferQueue* read_queue) {
+ CHECK_PARAM(read_queue);
+
+ return read_queue->consumer_queue_->capacity();
+}
+
+int dvrReadBufferQueueCreateReadQueue(DvrReadBufferQueue* read_queue,
+ DvrReadBufferQueue** out_read_queue) {
+ CHECK_PARAM(read_queue);
+ CHECK_PARAM(read_queue->consumer_queue_);
+ CHECK_PARAM(out_read_queue);
+
+ auto new_read_queue = std::make_unique<DvrReadBufferQueue>();
+ new_read_queue->consumer_queue_ =
+ read_queue->consumer_queue_->CreateConsumerQueue();
+ if (new_read_queue->consumer_queue_ == nullptr) {
+ ALOGE(
+ "dvrReadBufferQueueCreateReadQueue: Failed to create consumer queue "
+ "from DvrReadBufferQueue[%p].",
+ read_queue);
+ return -ENOMEM;
+ }
+
+ *out_read_queue = new_read_queue.release();
+ return 0;
+}
+
+int dvrReadBufferQueueDequeue(DvrReadBufferQueue* read_queue, int timeout,
+ DvrReadBuffer** out_buffer, int* out_fence_fd,
+ void* out_meta, size_t meta_size_bytes) {
+ CHECK_PARAM(read_queue);
+ CHECK_PARAM(read_queue->consumer_queue_);
+ CHECK_PARAM(out_buffer);
+ CHECK_PARAM(out_fence_fd);
+ CHECK_PARAM(out_meta);
+
+ if (meta_size_bytes != read_queue->consumer_queue_->metadata_size()) {
+ ALOGE(
+ "dvrReadBufferQueueDequeue: Invalid metadata size, expected (%zu), "
+ "but actual (%zu).",
+ read_queue->consumer_queue_->metadata_size(), meta_size_bytes);
+ return -EINVAL;
+ }
+
+ size_t slot;
+ pdx::LocalHandle acquire_fence;
+ std::shared_ptr<dvr::BufferConsumer> buffer =
+ read_queue->consumer_queue_->Dequeue(timeout, &slot, out_meta,
+ meta_size_bytes, &acquire_fence);
+
+ if (buffer == nullptr) {
+ ALOGE("dvrReadBufferQueueGainBuffer: Failed to dequeue buffer.");
+ return -ENOMEM;
+ }
+
+ *out_buffer = CreateDvrReadBufferFromBufferConsumer(buffer);
+ *out_fence_fd = acquire_fence.Release();
+ return 0;
+}
+
+} // extern "C"
diff --git a/libs/vr/libdvr/dvr_surface.cpp b/libs/vr/libdvr/dvr_surface.cpp
new file mode 100644
index 0000000..2abbe63
--- /dev/null
+++ b/libs/vr/libdvr/dvr_surface.cpp
@@ -0,0 +1,20 @@
+#include "include/dvr/dvr_surface.h"
+
+#include <private/dvr/display_client.h>
+
+using namespace android;
+
+extern "C" {
+
+int dvrGetPoseBuffer(DvrReadBuffer** pose_buffer) {
+ auto client = android::dvr::DisplayClient::Create();
+ if (!client) {
+ ALOGE("Failed to create display client!");
+ return -ECOMM;
+ }
+
+ *pose_buffer = CreateDvrReadBufferFromBufferConsumer(client->GetPoseBuffer());
+ return 0;
+}
+
+} // extern "C"
diff --git a/libs/vr/libdvr/include/CPPLINT.cfg b/libs/vr/libdvr/include/CPPLINT.cfg
new file mode 100644
index 0000000..2f8a3c0
--- /dev/null
+++ b/libs/vr/libdvr/include/CPPLINT.cfg
@@ -0,0 +1 @@
+filter=-build/header_guard
diff --git a/libs/vr/libdisplay/include/private/dvr/display_manager_client.h b/libs/vr/libdvr/include/dvr/display_manager_client.h
similarity index 100%
rename from libs/vr/libdisplay/include/private/dvr/display_manager_client.h
rename to libs/vr/libdvr/include/dvr/display_manager_client.h
diff --git a/libs/vr/libdvr/include/dvr/dvr_api.h b/libs/vr/libdvr/include/dvr/dvr_api.h
new file mode 100644
index 0000000..6fd50ee
--- /dev/null
+++ b/libs/vr/libdvr/include/dvr/dvr_api.h
@@ -0,0 +1,220 @@
+#ifndef ANDROID_DVR_API_H_
+#define ANDROID_DVR_API_H_
+
+#include <stdbool.h>
+#include <stddef.h>
+#include <stdint.h>
+
+#include <jni.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct DvrPoseAsync DvrPoseAsync;
+
+typedef struct DvrDisplayManagerClient DvrDisplayManagerClient;
+typedef struct DvrDisplayManagerClientSurfaceList
+ DvrDisplayManagerClientSurfaceList;
+typedef struct DvrDisplayManagerClientSurfaceBuffers
+ DvrDisplayManagerClientSurfaceBuffers;
+typedef struct DvrPose DvrPose;
+typedef struct dvr_vsync_client dvr_vsync_client;
+typedef struct DvrVirtualTouchpad DvrVirtualTouchpad;
+
+typedef DvrDisplayManagerClient* (*DisplayManagerClientCreatePtr)(void);
+typedef void (*DisplayManagerClientDestroyPtr)(DvrDisplayManagerClient* client);
+
+typedef struct DvrWriteBuffer DvrWriteBuffer;
+typedef struct DvrReadBuffer DvrReadBuffer;
+typedef struct AHardwareBuffer AHardwareBuffer;
+
+typedef struct DvrWriteBufferQueue DvrWriteBufferQueue;
+typedef struct DvrReadBufferQueue DvrReadBufferQueue;
+
+// display_manager_client.h
+typedef int (*DisplayManagerClientGetSurfaceListPtr)(
+ DvrDisplayManagerClient* client,
+ DvrDisplayManagerClientSurfaceList** surface_list);
+typedef void (*DisplayManagerClientSurfaceListDestroyPtr)(
+ DvrDisplayManagerClientSurfaceList* surface_list);
+typedef DvrWriteBuffer* (*DisplayManagerSetupPoseBufferPtr)(
+ DvrDisplayManagerClient* client, size_t extended_region_size,
+ uint64_t usage0, uint64_t usage1);
+typedef size_t (*DisplayManagerClientSurfaceListGetSizePtr)(
+ DvrDisplayManagerClientSurfaceList* surface_list);
+typedef int (*DisplayManagerClientSurfaceListGetSurfaceIdPtr)(
+ DvrDisplayManagerClientSurfaceList* surface_list, size_t index);
+typedef int (*DisplayManagerClientGetSurfaceBufferListPtr)(
+ DvrDisplayManagerClient* client, int surface_id,
+ DvrDisplayManagerClientSurfaceBuffers** surface_buffers);
+typedef void (*DisplayManagerClientSurfaceBufferListDestroyPtr)(
+ DvrDisplayManagerClientSurfaceBuffers* surface_buffers);
+typedef size_t (*DisplayManagerClientSurfaceBufferListGetSizePtr)(
+ DvrDisplayManagerClientSurfaceBuffers* surface_buffers);
+typedef int (*DisplayManagerClientSurfaceBufferListGetFdPtr)(
+ DvrDisplayManagerClientSurfaceBuffers* surface_buffers, size_t index);
+
+// dvr_buffer.h
+typedef void (*DvrWriteBufferDestroyPtr)(DvrWriteBuffer* client);
+typedef void (*DvrWriteBufferGetBlobFdsPtr)(DvrWriteBuffer* client, int* fds,
+ size_t* fds_count,
+ size_t max_fds_count);
+typedef int (*DvrWriteBufferGetAHardwareBufferPtr)(
+ DvrWriteBuffer* client, AHardwareBuffer** hardware_buffer);
+typedef int (*DvrWriteBufferPostPtr)(DvrWriteBuffer* client, int ready_fence_fd,
+ const void* meta, size_t meta_size_bytes);
+typedef int (*DvrWriteBufferGainPtr)(DvrWriteBuffer* client,
+ int* release_fence_fd);
+typedef int (*DvrWriteBufferGainAsyncPtr)(DvrWriteBuffer* client);
+
+typedef void (*DvrReadBufferDestroyPtr)(DvrReadBuffer* client);
+typedef void (*DvrReadBufferGetBlobFdsPtr)(DvrReadBuffer* client, int* fds,
+ size_t* fds_count,
+ size_t max_fds_count);
+typedef int (*DvrReadBufferGetAHardwareBufferPtr)(
+ DvrReadBuffer* client, AHardwareBuffer** hardware_buffer);
+typedef int (*DvrReadBufferAcquirePtr)(DvrReadBuffer* client,
+ int* ready_fence_fd, void* meta,
+ size_t meta_size_bytes);
+typedef int (*DvrReadBufferReleasePtr)(DvrReadBuffer* client,
+ int release_fence_fd);
+typedef int (*DvrReadBufferReleaseAsyncPtr)(DvrReadBuffer* client);
+
+// dvr_buffer_queue.h
+typedef void (*DvrWriteBufferQueueDestroyPtr)(DvrWriteBufferQueue* write_queue);
+typedef size_t (*DvrWriteBufferQueueGetCapacityPtr)(
+ DvrWriteBufferQueue* write_queue);
+typedef void* (*DvrWriteBufferQueueGetExternalSurfacePtr)(
+ DvrWriteBufferQueue* write_queue, JNIEnv* env);
+typedef int (*DvrWriteBufferQueueCreateReadQueuePtr)(
+ DvrWriteBufferQueue* write_queue, DvrReadBufferQueue** out_read_queue);
+typedef int (*DvrWriteBufferQueueDequeuePtr)(DvrWriteBufferQueue* write_queue,
+ int timeout,
+ DvrWriteBuffer** out_buffer,
+ int* out_fence_fd);
+typedef void (*DvrReadBufferQueueDestroyPtr)(DvrReadBufferQueue* read_queue);
+typedef size_t (*DvrReadBufferQueueGetCapacityPtr)(
+ DvrReadBufferQueue* read_queue);
+typedef int (*DvrReadBufferQueueCreateReadQueuePtr)(
+ DvrReadBufferQueue* read_queue, DvrReadBufferQueue** out_read_queue);
+typedef int (*DvrReadBufferQueueDequeuePtr)(DvrReadBufferQueue* read_queue,
+ int timeout,
+ DvrReadBuffer** out_buffer,
+ int* out_fence_fd, void* out_meta,
+ size_t meta_size_bytes);
+
+// dvr_surface.h
+typedef int (*DvrGetPoseBufferPtr)(DvrReadBuffer** pose_buffer);
+
+// vsync_client_api.h
+typedef dvr_vsync_client* (*VSyncClientCreatePtr)();
+typedef void (*VSyncClientDestroyPtr)(dvr_vsync_client* client);
+typedef int (*VSyncClientGetSchedInfoPtr)(dvr_vsync_client* client,
+ int64_t* vsync_period_ns,
+ int64_t* next_timestamp_ns,
+ uint32_t* next_vsync_count);
+
+// pose_client.h
+typedef DvrPose* (*PoseClientCreatePtr)(void);
+typedef void (*PoseClientDestroyPtr)(DvrPose* client);
+typedef int (*PoseGetPtr)(DvrPose* client, uint32_t vsync_count,
+ DvrPoseAsync* out_pose);
+typedef uint32_t (*PoseGetVsyncCountPtr)(DvrPose* client);
+typedef int (*PoseGetControllerPtr)(DvrPose* client, int32_t controller_id,
+ uint32_t vsync_count,
+ DvrPoseAsync* out_pose);
+
+// virtual_touchpad_client.h
+typedef DvrVirtualTouchpad* (*VirtualTouchpadCreatePtr)(void);
+typedef void (*VirtualTouchpadDestroyPtr)(DvrVirtualTouchpad* client);
+typedef int (*VirtualTouchpadAttachPtr)(DvrVirtualTouchpad* client);
+typedef int (*VirtualTouchpadDetachPtr)(DvrVirtualTouchpad* client);
+typedef int (*VirtualTouchpadTouchPtr)(DvrVirtualTouchpad* client, int touchpad,
+ float x, float y, float pressure);
+typedef int (*VirtualTouchpadButtonStatePtr)(DvrVirtualTouchpad* client,
+ int touchpad, int buttons);
+
+struct DvrApi_v1 {
+ // Display manager client
+ DisplayManagerClientCreatePtr display_manager_client_create_;
+ DisplayManagerClientDestroyPtr display_manager_client_destroy_;
+ DisplayManagerClientGetSurfaceListPtr
+ display_manager_client_get_surface_list_;
+ DisplayManagerClientSurfaceListDestroyPtr
+ display_manager_client_surface_list_destroy_;
+ DisplayManagerSetupPoseBufferPtr display_manager_setup_pose_buffer_;
+ DisplayManagerClientSurfaceListGetSizePtr
+ display_manager_client_surface_list_get_size_;
+ DisplayManagerClientSurfaceListGetSurfaceIdPtr
+ display_manager_client_surface_list_get_surface_id_;
+ DisplayManagerClientGetSurfaceBufferListPtr
+ display_manager_client_get_surface_buffer_list_;
+ DisplayManagerClientSurfaceBufferListDestroyPtr
+ display_manager_client_surface_buffer_list_destroy_;
+ DisplayManagerClientSurfaceBufferListGetSizePtr
+ display_manager_client_surface_buffer_list_get_size_;
+ DisplayManagerClientSurfaceBufferListGetFdPtr
+ display_manager_client_surface_buffer_list_get_fd_;
+
+ // Write buffer
+ DvrWriteBufferDestroyPtr write_buffer_destroy_;
+ DvrWriteBufferGetBlobFdsPtr write_buffer_get_blob_fds_;
+ DvrWriteBufferGetAHardwareBufferPtr write_buffer_get_AHardwareBuffer_;
+ DvrWriteBufferPostPtr write_buffer_post_;
+ DvrWriteBufferGainPtr write_buffer_gain_;
+ DvrWriteBufferGainAsyncPtr write_buffer_gain_async_;
+
+ // Read buffer
+ DvrReadBufferDestroyPtr read_buffer_destroy_;
+ DvrReadBufferGetBlobFdsPtr read_buffer_get_blob_fds_;
+ DvrReadBufferGetAHardwareBufferPtr read_buffer_get_AHardwareBuffer_;
+ DvrReadBufferAcquirePtr read_buffer_acquire_;
+ DvrReadBufferReleasePtr read_buffer_release_;
+ DvrReadBufferReleaseAsyncPtr read_buffer_release_async_;
+
+ // Write buffer queue
+ DvrWriteBufferQueueDestroyPtr write_buffer_queue_destroy_;
+ DvrWriteBufferQueueGetCapacityPtr write_buffer_queue_get_capacity_;
+ DvrWriteBufferQueueGetExternalSurfacePtr
+ write_buffer_queue_get_external_surface_;
+ DvrWriteBufferQueueCreateReadQueuePtr write_buffer_queue_create_read_queue_;
+ DvrWriteBufferQueueDequeuePtr write_buffer_queue_dequeue_;
+
+ // Read buffer queue
+ DvrReadBufferQueueDestroyPtr read_buffer_queue_destroy_;
+ DvrReadBufferQueueGetCapacityPtr read_buffer_queue_get_capacity_;
+ DvrReadBufferQueueCreateReadQueuePtr read_buffer_queue_create_read_queue_;
+ DvrReadBufferQueueDequeuePtr read_buffer_queue_dequeue;
+
+ // V-Sync client
+ VSyncClientCreatePtr vsync_client_create_;
+ VSyncClientDestroyPtr vsync_client_destroy_;
+ VSyncClientGetSchedInfoPtr vsync_client_get_sched_info_;
+
+ // Display surface
+ DvrGetPoseBufferPtr get_pose_buffer_;
+
+ // Pose client
+ PoseClientCreatePtr pose_client_create_;
+ PoseClientDestroyPtr pose_client_destroy_;
+ PoseGetPtr pose_get_;
+ PoseGetVsyncCountPtr pose_get_vsync_count_;
+ PoseGetControllerPtr pose_get_controller_;
+
+ // Virtual touchpad client
+ VirtualTouchpadCreatePtr virtual_touchpad_create_;
+ VirtualTouchpadDestroyPtr virtual_touchpad_destroy_;
+ VirtualTouchpadAttachPtr virtual_touchpad_attach_;
+ VirtualTouchpadDetachPtr virtual_touchpad_detach_;
+ VirtualTouchpadTouchPtr virtual_touchpad_touch_;
+ VirtualTouchpadButtonStatePtr virtual_touchpad_button_state_;
+};
+
+int dvrGetApi(void* api, size_t struct_size, int version);
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+#endif // ANDROID_DVR_API_H_
diff --git a/libs/vr/libbufferhub/include/private/dvr/dvr_buffer.h b/libs/vr/libdvr/include/dvr/dvr_buffer.h
similarity index 90%
rename from libs/vr/libbufferhub/include/private/dvr/dvr_buffer.h
rename to libs/vr/libdvr/include/dvr/dvr_buffer.h
index c14b1a3..bbfbb00 100644
--- a/libs/vr/libbufferhub/include/private/dvr/dvr_buffer.h
+++ b/libs/vr/libdvr/include/dvr/dvr_buffer.h
@@ -25,6 +25,7 @@
int dvrWriteBufferGainAsync(DvrWriteBuffer* client);
// Read buffer
+void dvrReadBufferDestroy(DvrReadBuffer* client);
void dvrReadBufferGetBlobFds(DvrReadBuffer* client, int* fds, size_t* fds_count,
size_t max_fds_count);
int dvrReadBufferGetAHardwareBuffer(DvrReadBuffer* client,
@@ -45,9 +46,9 @@
class BufferConsumer;
DvrWriteBuffer* CreateDvrWriteBufferFromBufferProducer(
- std::unique_ptr<BufferProducer> buffer_producer);
+ const std::shared_ptr<BufferProducer>& buffer_producer);
DvrReadBuffer* CreateDvrReadBufferFromBufferConsumer(
- std::unique_ptr<BufferConsumer> buffer_consumer);
+ const std::shared_ptr<BufferConsumer>& buffer_consumer);
} // namespace dvr
} // namespace android
diff --git a/libs/vr/libdvr/include/dvr/dvr_buffer_queue.h b/libs/vr/libdvr/include/dvr/dvr_buffer_queue.h
new file mode 100644
index 0000000..86b3ae2
--- /dev/null
+++ b/libs/vr/libdvr/include/dvr/dvr_buffer_queue.h
@@ -0,0 +1,41 @@
+#ifndef ANDROID_DVR_BUFFER_QUEUE_H_
+#define ANDROID_DVR_BUFFER_QUEUE_H_
+
+#include <dvr/dvr_buffer.h>
+#include <jni.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct DvrWriteBufferQueue DvrWriteBufferQueue;
+typedef struct DvrReadBufferQueue DvrReadBufferQueue;
+
+// WriteBufferQueue
+void dvrWriteBufferQueueDestroy(DvrWriteBufferQueue* write_queue);
+size_t dvrWriteBufferQueueGetCapacity(DvrWriteBufferQueue* write_queue);
+
+// Returns ANativeWindow in the form of jobject. Can be casted to ANativeWindow
+// using ANativeWindow_fromSurface NDK API.
+void* dvrWriteBufferQueueGetExternalSurface(DvrWriteBufferQueue* write_queue,
+ JNIEnv* env);
+
+int dvrWriteBufferQueueCreateReadQueue(DvrWriteBufferQueue* write_queue,
+ DvrReadBufferQueue** out_read_queue);
+int dvrWriteBufferQueueDequeue(DvrWriteBufferQueue* write_queue, int timeout,
+ DvrWriteBuffer** out_buffer, int* out_fence_fd);
+
+// ReadeBufferQueue
+void dvrReadBufferQueueDestroy(DvrReadBufferQueue* read_queue);
+size_t dvrReadBufferQueueGetCapacity(DvrReadBufferQueue* read_queue);
+int dvrReadBufferQueueCreateReadQueue(DvrReadBufferQueue* read_queue,
+ DvrReadBufferQueue** out_read_queue);
+int dvrReadBufferQueueDequeue(DvrReadBufferQueue* read_queue, int timeout,
+ DvrReadBuffer** out_buffer, int* out_fence_fd,
+ void* out_meta, size_t meta_size_bytes);
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+#endif // ANDROID_DVR_BUFFER_QUEUE_H_
diff --git a/libs/vr/libdvr/include/dvr/dvr_surface.h b/libs/vr/libdvr/include/dvr/dvr_surface.h
new file mode 100644
index 0000000..fa8d228
--- /dev/null
+++ b/libs/vr/libdvr/include/dvr/dvr_surface.h
@@ -0,0 +1,17 @@
+#ifndef ANDROID_DVR_SURFACE_H_
+#define ANDROID_DVR_SURFACE_H_
+
+#include <dvr/dvr_buffer.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+// Get a pointer to the global pose buffer.
+int dvrGetPoseBuffer(DvrReadBuffer** pose_buffer);
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+#endif // ANDROID_DVR_SURFACE_H_
diff --git a/libs/vr/libdisplay/include/private/dvr/vsync_client_api.h b/libs/vr/libdvr/include/dvr/vsync_client_api.h
similarity index 100%
rename from libs/vr/libdisplay/include/private/dvr/vsync_client_api.h
rename to libs/vr/libdvr/include/dvr/vsync_client_api.h
diff --git a/libs/vr/libdvr/tests/Android.mk b/libs/vr/libdvr/tests/Android.mk
new file mode 100644
index 0000000..158d58f
--- /dev/null
+++ b/libs/vr/libdvr/tests/Android.mk
@@ -0,0 +1,29 @@
+LOCAL_PATH := $(call my-dir)
+
+shared_libraries := \
+ libbase \
+ libbinder \
+ libcutils \
+ libgui \
+ liblog \
+ libhardware \
+ libui \
+ libutils \
+
+static_libraries := \
+ libdvr \
+ libbufferhubqueue \
+ libbufferhub \
+ libchrome \
+ libdvrcommon \
+ libpdx_default_transport \
+
+include $(CLEAR_VARS)
+LOCAL_SRC_FILES := dvr_buffer_queue-test.cpp
+LOCAL_STATIC_LIBRARIES := $(static_libraries)
+LOCAL_SHARED_LIBRARIES := $(shared_libraries)
+LOCAL_EXPORT_C_INCLUDE_DIRS := ${LOCAL_C_INCLUDES}
+LOCAL_CFLAGS := -DLOG_TAG=\"dvr_buffer_queue-test\" -DTRACE=0 -O0 -g
+LOCAL_MODULE := dvr_buffer_queue-test
+LOCAL_MODULE_TAGS := optional
+include $(BUILD_NATIVE_TEST)
diff --git a/libs/vr/libdvr/tests/dvr_buffer_queue-test.cpp b/libs/vr/libdvr/tests/dvr_buffer_queue-test.cpp
new file mode 100644
index 0000000..f344a24
--- /dev/null
+++ b/libs/vr/libdvr/tests/dvr_buffer_queue-test.cpp
@@ -0,0 +1,149 @@
+#include <dvr/dvr_buffer_queue.h>
+#include <private/dvr/buffer_hub_queue_client.h>
+
+#include <base/logging.h>
+#include <gtest/gtest.h>
+
+namespace android {
+namespace dvr {
+
+namespace {
+
+static constexpr int kBufferWidth = 100;
+static constexpr int kBufferHeight = 1;
+static constexpr int kBufferFormat = HAL_PIXEL_FORMAT_BLOB;
+static constexpr int kBufferUsage = GRALLOC_USAGE_SW_READ_RARELY;
+static constexpr int kBufferSliceCount = 1; // number of slices in each buffer
+static constexpr size_t kQueueCapacity = 3;
+
+typedef uint64_t TestMeta;
+
+class DvrBufferQueueTest : public ::testing::Test {
+ protected:
+ void SetUp() override {
+ write_queue_ = new DvrWriteBufferQueue;
+ write_queue_->producer_queue_ = ProducerQueue::Create<TestMeta>(0, 0, 0, 0);
+ ASSERT_NE(nullptr, write_queue_->producer_queue_);
+ }
+
+ void TearDown() override {
+ if (write_queue_ != nullptr) {
+ dvrWriteBufferQueueDestroy(write_queue_);
+ write_queue_ = nullptr;
+ }
+ }
+
+ void AllocateBuffers(size_t buffer_count) {
+ size_t out_slot;
+ for (size_t i = 0; i < buffer_count; i++) {
+ int ret = write_queue_->producer_queue_->AllocateBuffer(
+ kBufferWidth, kBufferHeight, kBufferFormat, kBufferUsage,
+ kBufferSliceCount, &out_slot);
+ ASSERT_EQ(0, ret);
+ }
+ }
+
+ DvrWriteBufferQueue* write_queue_{nullptr};
+};
+
+TEST_F(DvrBufferQueueTest, TestWrite_QueueDestroy) {
+ dvrWriteBufferQueueDestroy(write_queue_);
+ write_queue_ = nullptr;
+}
+
+TEST_F(DvrBufferQueueTest, TestWrite_QueueGetCapacity) {
+ AllocateBuffers(kQueueCapacity);
+ size_t capacity = dvrWriteBufferQueueGetCapacity(write_queue_);
+
+ ALOGD_IF(TRACE, "TestWrite_QueueGetCapacity, capacity=%zu", capacity);
+ ASSERT_EQ(kQueueCapacity, capacity);
+}
+
+TEST_F(DvrBufferQueueTest, TestCreateReadQueueFromWriteQueue) {
+ DvrReadBufferQueue* read_queue = nullptr;
+ int ret = dvrWriteBufferQueueCreateReadQueue(write_queue_, &read_queue);
+
+ ASSERT_EQ(0, ret);
+ ASSERT_NE(nullptr, read_queue);
+
+ dvrReadBufferQueueDestroy(read_queue);
+}
+
+TEST_F(DvrBufferQueueTest, TestCreateReadQueueFromReadQueue) {
+ DvrReadBufferQueue* read_queue1 = nullptr;
+ DvrReadBufferQueue* read_queue2 = nullptr;
+ int ret = dvrWriteBufferQueueCreateReadQueue(write_queue_, &read_queue1);
+
+ ASSERT_EQ(0, ret);
+ ASSERT_NE(nullptr, read_queue1);
+
+ ret = dvrReadBufferQueueCreateReadQueue(read_queue1, &read_queue2);
+ ASSERT_EQ(0, ret);
+ ASSERT_NE(nullptr, read_queue2);
+ ASSERT_NE(read_queue1, read_queue2);
+
+ dvrReadBufferQueueDestroy(read_queue1);
+ dvrReadBufferQueueDestroy(read_queue2);
+}
+
+TEST_F(DvrBufferQueueTest, TestDequeuePostDequeueRelease) {
+ static constexpr int kTimeout = 0;
+ DvrReadBufferQueue* read_queue = nullptr;
+ DvrReadBuffer* rb = nullptr;
+ DvrWriteBuffer* wb = nullptr;
+ int fence_fd = -1;
+
+ int ret = dvrWriteBufferQueueCreateReadQueue(write_queue_, &read_queue);
+
+ ASSERT_EQ(0, ret);
+ ASSERT_NE(nullptr, read_queue);
+
+ AllocateBuffers(kQueueCapacity);
+
+ // Gain buffer for writing.
+ ret = dvrWriteBufferQueueDequeue(write_queue_, kTimeout, &wb, &fence_fd);
+ ASSERT_EQ(0, ret);
+ ASSERT_NE(nullptr, wb);
+ ALOGD_IF(TRACE, "TestDequeuePostDequeueRelease, gain buffer %p, fence_fd=%d",
+ wb, fence_fd);
+ pdx::LocalHandle release_fence(fence_fd);
+
+ // Post buffer to the read_queue.
+ TestMeta seq = 42U;
+ ret = dvrWriteBufferPost(wb, /* fence */ -1, &seq, sizeof(seq));
+ ASSERT_EQ(0, ret);
+ dvrWriteBufferDestroy(wb);
+ wb = nullptr;
+
+ // Acquire buffer for reading.
+ TestMeta acquired_seq = 0U;
+ ret = dvrReadBufferQueueDequeue(read_queue, kTimeout, &rb, &fence_fd,
+ &acquired_seq, sizeof(acquired_seq));
+ ASSERT_EQ(0, ret);
+ ASSERT_NE(nullptr, rb);
+ ASSERT_EQ(seq, acquired_seq);
+ ALOGD_IF(TRACE,
+ "TestDequeuePostDequeueRelease, acquire buffer %p, fence_fd=%d", rb,
+ fence_fd);
+ pdx::LocalHandle acquire_fence(fence_fd);
+
+ // Release buffer to the write_queue.
+ ret = dvrReadBufferRelease(rb, -1);
+ ASSERT_EQ(0, ret);
+ dvrReadBufferDestroy(rb);
+ rb = nullptr;
+
+ // TODO(b/34387835) Currently buffer allocation has to happen after all queues
+ // are initialized.
+ size_t capacity = dvrReadBufferQueueGetCapacity(read_queue);
+
+ ALOGD_IF(TRACE, "TestDequeuePostDequeueRelease, capacity=%zu", capacity);
+ ASSERT_EQ(kQueueCapacity, capacity);
+
+ dvrReadBufferQueueDestroy(read_queue);
+}
+
+} // namespace
+
+} // namespace dvr
+} // namespace android
diff --git a/libs/vr/libdisplay/vsync_client_api.cpp b/libs/vr/libdvr/vsync_client_api.cpp
similarity index 93%
rename from libs/vr/libdisplay/vsync_client_api.cpp
rename to libs/vr/libdvr/vsync_client_api.cpp
index 00af525..dbddd3d 100644
--- a/libs/vr/libdisplay/vsync_client_api.cpp
+++ b/libs/vr/libdvr/vsync_client_api.cpp
@@ -1,4 +1,4 @@
-#include "include/private/dvr/vsync_client_api.h"
+#include "include/dvr/vsync_client_api.h"
#include <private/dvr/vsync_client.h>