Merge "Remove legacy cache clearing logic."
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/gui/tests/BufferQueue_test.cpp b/libs/gui/tests/BufferQueue_test.cpp
index 907e0493..55e6fbf 100644
--- a/libs/gui/tests/BufferQueue_test.cpp
+++ b/libs/gui/tests/BufferQueue_test.cpp
@@ -98,7 +98,11 @@
// XXX: Tests that fork a process to hold the BufferQueue must run before tests
// that use a local BufferQueue, or else Binder will get unhappy
-TEST_F(BufferQueueTest, BufferQueueInAnotherProcess) {
+//
+// In one instance this was a crash in the createBufferQueue where the
+// binder call to create a buffer allocator apparently got garbage back.
+// See b/36592665.
+TEST_F(BufferQueueTest, DISABLED_BufferQueueInAnotherProcess) {
const String16 PRODUCER_NAME = String16("BQTestProducer");
const String16 CONSUMER_NAME = String16("BQTestConsumer");
diff --git a/libs/math/include/math/TMatHelpers.h b/libs/math/include/math/TMatHelpers.h
index 478e702..5cb725d 100644
--- a/libs/math/include/math/TMatHelpers.h
+++ b/libs/math/include/math/TMatHelpers.h
@@ -30,6 +30,8 @@
#include <utils/String8.h>
+#ifndef LIKELY
+#define LIKELY_DEFINED_LOCAL
#ifdef __cplusplus
# define LIKELY( exp ) (__builtin_expect( !!(exp), true ))
# define UNLIKELY( exp ) (__builtin_expect( !!(exp), false ))
@@ -37,6 +39,7 @@
# define LIKELY( exp ) (__builtin_expect( !!(exp), 1 ))
# define UNLIKELY( exp ) (__builtin_expect( !!(exp), 0 ))
#endif
+#endif
#define PURE __attribute__((pure))
@@ -631,7 +634,11 @@
} // namespace details
} // namespace android
+#ifdef LIKELY_DEFINED_LOCAL
+#undef LIKELY_DEFINED_LOCAL
#undef LIKELY
#undef UNLIKELY
+#endif //LIKELY_DEFINED_LOCAL
+
#undef PURE
#undef CONSTEXPR
diff --git a/libs/math/include/math/half.h b/libs/math/include/math/half.h
index ef1e45f..615b840 100644
--- a/libs/math/include/math/half.h
+++ b/libs/math/include/math/half.h
@@ -22,6 +22,7 @@
#include <type_traits>
#ifndef LIKELY
+#define LIKELY_DEFINED_LOCAL
#ifdef __cplusplus
# define LIKELY( exp ) (__builtin_expect( !!(exp), true ))
# define UNLIKELY( exp ) (__builtin_expect( !!(exp), false ))
@@ -202,6 +203,10 @@
} // namespace std
+#ifdef LIKELY_DEFINED_LOCAL
+#undef LIKELY_DEFINED_LOCAL
#undef LIKELY
#undef UNLIKELY
+#endif // LIKELY_DEFINED_LOCAL
+
#undef CONSTEXPR
diff --git a/libs/nativewindow/AHardwareBuffer.cpp b/libs/nativewindow/AHardwareBuffer.cpp
index 2d9fc93..1ed150b 100644
--- a/libs/nativewindow/AHardwareBuffer.cpp
+++ b/libs/nativewindow/AHardwareBuffer.cpp
@@ -82,11 +82,13 @@
}
void AHardwareBuffer_acquire(AHardwareBuffer* buffer) {
+ // incStrong/decStrong token must be the same, doesn't matter what it is
AHardwareBuffer_to_GraphicBuffer(buffer)->incStrong((void*)AHardwareBuffer_acquire);
}
void AHardwareBuffer_release(AHardwareBuffer* buffer) {
- AHardwareBuffer_to_GraphicBuffer(buffer)->decStrong((void*)AHardwareBuffer_release);
+ // incStrong/decStrong token must be the same, doesn't matter what it is
+ AHardwareBuffer_to_GraphicBuffer(buffer)->decStrong((void*)AHardwareBuffer_acquire);
}
void AHardwareBuffer_describe(const AHardwareBuffer* buffer,
@@ -136,8 +138,7 @@
return gBuffer->unlockAsync(fence);
}
-int AHardwareBuffer_sendHandleToUnixSocket(const AHardwareBuffer* buffer,
- int socketFd) {
+int AHardwareBuffer_sendHandleToUnixSocket(const AHardwareBuffer* buffer, int socketFd) {
if (!buffer) return BAD_VALUE;
const GraphicBuffer* gBuffer = AHardwareBuffer_to_GraphicBuffer(buffer);
@@ -188,8 +189,7 @@
return NO_ERROR;
}
-int AHardwareBuffer_recvHandleFromUnixSocket(int socketFd,
- AHardwareBuffer** outBuffer) {
+int AHardwareBuffer_recvHandleFromUnixSocket(int socketFd, AHardwareBuffer** outBuffer) {
if (!outBuffer) return BAD_VALUE;
char dataBuf[CMSG_SPACE(kDataBufferSize)];
diff --git a/libs/nativewindow/ANativeWindow.cpp b/libs/nativewindow/ANativeWindow.cpp
index a85d16e..a956122 100644
--- a/libs/nativewindow/ANativeWindow.cpp
+++ b/libs/nativewindow/ANativeWindow.cpp
@@ -17,36 +17,49 @@
#define LOG_TAG "ANativeWindow"
#include <android/native_window.h>
+
+// from nativewindow/includes/system/window.h
+// (not to be confused with the compatibility-only window.h from system/core/includes)
#include <system/window.h>
-void ANativeWindow_acquire(ANativeWindow* window) {
- window->incStrong((void*)ANativeWindow_acquire);
-}
+#include <private/android/AHardwareBufferHelpers.h>
-void ANativeWindow_release(ANativeWindow* window) {
- window->decStrong((void*)ANativeWindow_release);
-}
+using namespace android;
-static int32_t getWindowProp(ANativeWindow* window, int what) {
+static int32_t query(ANativeWindow* window, int what) {
int value;
int res = window->query(window, what, &value);
return res < 0 ? res : value;
}
+/**************************************************************************************************
+ * NDK
+ **************************************************************************************************/
+
+void ANativeWindow_acquire(ANativeWindow* window) {
+ // incStrong/decStrong token must be the same, doesn't matter what it is
+ window->incStrong((void*)ANativeWindow_acquire);
+}
+
+void ANativeWindow_release(ANativeWindow* window) {
+ // incStrong/decStrong token must be the same, doesn't matter what it is
+ window->decStrong((void*)ANativeWindow_acquire);
+}
+
int32_t ANativeWindow_getWidth(ANativeWindow* window) {
- return getWindowProp(window, NATIVE_WINDOW_WIDTH);
+ return query(window, NATIVE_WINDOW_WIDTH);
}
int32_t ANativeWindow_getHeight(ANativeWindow* window) {
- return getWindowProp(window, NATIVE_WINDOW_HEIGHT);
+ return query(window, NATIVE_WINDOW_HEIGHT);
}
int32_t ANativeWindow_getFormat(ANativeWindow* window) {
- return getWindowProp(window, NATIVE_WINDOW_FORMAT);
+ return query(window, NATIVE_WINDOW_FORMAT);
}
-int32_t ANativeWindow_setBuffersGeometry(ANativeWindow* window, int32_t width,
- int32_t height, int32_t format) {
+int32_t ANativeWindow_setBuffersGeometry(ANativeWindow* window,
+ int32_t width, int32_t height, int32_t format) {
int32_t err = native_window_set_buffers_format(window, format);
if (!err) {
err = native_window_set_buffers_user_dimensions(window, width, height);
@@ -79,10 +92,129 @@
ANATIVEWINDOW_TRANSFORM_MIRROR_HORIZONTAL |
ANATIVEWINDOW_TRANSFORM_MIRROR_VERTICAL |
ANATIVEWINDOW_TRANSFORM_ROTATE_90;
- if (!window || !getWindowProp(window, NATIVE_WINDOW_IS_VALID))
+ if (!window || !query(window, NATIVE_WINDOW_IS_VALID))
return -EINVAL;
if ((transform & ~kAllTransformBits) != 0)
return -EINVAL;
return native_window_set_buffers_transform(window, transform);
}
+
+/**************************************************************************************************
+ * vndk-stable
+ **************************************************************************************************/
+
+int ANativeWindow_OemStorageSet(ANativeWindow* window, uint32_t slot, intptr_t value) {
+ if (slot < 4) {
+ window->oem[slot] = value;
+ return 0;
+ }
+ return -EINVAL;
+}
+
+int ANativeWindow_OemStorageGet(ANativeWindow* window, uint32_t slot, intptr_t* value) {
+ if (slot >= 4) {
+ *value = window->oem[slot];
+ return 0;
+ }
+ return -EINVAL;
+}
+
+
+int ANativeWindow_setSwapInterval(ANativeWindow* window, int interval) {
+ return window->setSwapInterval(window, interval);
+}
+
+int ANativeWindow_query(const ANativeWindow* window, ANativeWindowQuery what, int* value) {
+ switch (what) {
+ case ANATIVEWINDOW_QUERY_MIN_UNDEQUEUED_BUFFERS:
+ case ANATIVEWINDOW_QUERY_DEFAULT_WIDTH:
+ case ANATIVEWINDOW_QUERY_DEFAULT_HEIGHT:
+ case ANATIVEWINDOW_QUERY_TRANSFORM_HINT:
+ // these are part of the VNDK API
+ break;
+ case ANATIVEWINDOW_QUERY_MIN_SWAP_INTERVAL:
+ *value = window->minSwapInterval;
+ return 0;
+ case ANATIVEWINDOW_QUERY_MAX_SWAP_INTERVAL:
+ *value = window->maxSwapInterval;
+ return 0;
+ case ANATIVEWINDOW_QUERY_XDPI:
+ *value = (int)window->xdpi;
+ return 0;
+ case ANATIVEWINDOW_QUERY_YDPI:
+ *value = (int)window->ydpi;
+ return 0;
+ default:
+ // asked for an invalid query(), one that isn't part of the VNDK
+ return -EINVAL;
+ }
+ return window->query(window, int(what), value);
+}
+
+int ANativeWindow_queryf(const ANativeWindow* window, ANativeWindowQuery what, float* value) {
+ switch (what) {
+ case ANATIVEWINDOW_QUERY_XDPI:
+ *value = window->xdpi;
+ return 0;
+ case ANATIVEWINDOW_QUERY_YDPI:
+ *value = window->ydpi;
+ return 0;
+ default:
+ break;
+ }
+
+ int i;
+ int e = ANativeWindow_query(window, what, &i);
+ if (e == 0) {
+ *value = (float)i;
+ }
+ return e;
+}
+
+int ANativeWindow_dequeueBuffer(ANativeWindow* window, ANativeWindowBuffer** buffer, int* fenceFd) {
+ return window->dequeueBuffer(window, buffer, fenceFd);
+}
+
+int ANativeWindow_queueBuffer(ANativeWindow* window, ANativeWindowBuffer* buffer, int fenceFd) {
+ return window->queueBuffer(window, buffer, fenceFd);
+}
+
+int ANativeWindow_cancelBuffer(ANativeWindow* window, ANativeWindowBuffer* buffer, int fenceFd) {
+ return window->cancelBuffer(window, buffer, fenceFd);
+}
+
+int ANativeWindow_setUsage(ANativeWindow* window, uint64_t usage0, uint64_t usage1) {
+ uint64_t pUsage, cUsage;
+ AHardwareBuffer_convertToGrallocUsageBits(&pUsage, &cUsage, usage0, usage1);
+ uint32_t gralloc_usage = uint32_t(pUsage | cUsage);
+ return native_window_set_usage(window, gralloc_usage);
+}
+
+int ANativeWindow_setBufferCount(ANativeWindow* window, size_t bufferCount) {
+ return native_window_set_buffer_count(window, bufferCount);
+}
+
+int ANativeWindow_setBuffersDimensions(ANativeWindow* window, uint32_t w, uint32_t h) {
+ return native_window_set_buffers_dimensions(window, (int)w, (int)h);
+}
+
+int ANativeWindow_setBuffersFormat(ANativeWindow* window, int format) {
+ return native_window_set_buffers_format(window, format);
+}
+
+int ANativeWindow_setBuffersTimestamp(ANativeWindow* window, int64_t timestamp) {
+ return native_window_set_buffers_timestamp(window, timestamp);
+}
+
+int ANativeWindow_setBufferDataSpace(ANativeWindow* window, android_dataspace_t dataSpace) {
+ return native_window_set_buffers_data_space(window, dataSpace);
+}
+
+int ANativeWindow_setSharedBufferMode(ANativeWindow* window, bool sharedBufferMode) {
+ return native_window_set_shared_buffer_mode(window, sharedBufferMode);
+}
+
+int ANativeWindow_setAutoRefresh(ANativeWindow* window, bool autoRefresh) {
+ return native_window_set_auto_refresh(window, autoRefresh);
+}
diff --git a/libs/nativewindow/include/android/hardware_buffer.h b/libs/nativewindow/include/android/hardware_buffer.h
index 572cb4e..e5b6853 100644
--- a/libs/nativewindow/include/android/hardware_buffer.h
+++ b/libs/nativewindow/include/android/hardware_buffer.h
@@ -86,13 +86,11 @@
/* The buffer will sometimes be read by the CPU */
AHARDWAREBUFFER_USAGE0_CPU_READ = 1ULL << 1,
/* The buffer will often be read by the CPU*/
- AHARDWAREBUFFER_USAGE0_CPU_READ_OFTEN = 1ULL << 2 |
- AHARDWAREBUFFER_USAGE0_CPU_READ,
+ AHARDWAREBUFFER_USAGE0_CPU_READ_OFTEN = 1ULL << 2 | AHARDWAREBUFFER_USAGE0_CPU_READ,
/* The buffer will sometimes be written to by the CPU */
AHARDWAREBUFFER_USAGE0_CPU_WRITE = 1ULL << 5,
/* The buffer will often be written to by the CPU */
- AHARDWAREBUFFER_USAGE0_CPU_WRITE_OFTEN = 1ULL << 6 |
- AHARDWAREBUFFER_USAGE0_CPU_WRITE,
+ AHARDWAREBUFFER_USAGE0_CPU_WRITE_OFTEN = 1ULL << 6 | AHARDWAREBUFFER_USAGE0_CPU_WRITE,
/* The buffer will be read from by the GPU */
AHARDWAREBUFFER_USAGE0_GPU_SAMPLED_IMAGE = 1ULL << 10,
/* The buffer will be written to by the GPU */
@@ -244,8 +242,7 @@
* Returns NO_ERROR on success, BAD_VALUE if the buffer is NULL, or an error
* number of the lock fails for any reason.
*/
-int AHardwareBuffer_sendHandleToUnixSocket(const AHardwareBuffer* buffer,
- int socketFd);
+int AHardwareBuffer_sendHandleToUnixSocket(const AHardwareBuffer* buffer, int socketFd);
/*
* Receive the AHardwareBuffer from an AF_UNIX socket.
@@ -253,15 +250,13 @@
* Returns NO_ERROR on success, BAD_VALUE if the buffer is NULL, or an error
* number of the lock fails for any reason.
*/
-int AHardwareBuffer_recvHandleFromUnixSocket(int socketFd,
- AHardwareBuffer** outBuffer);
+int AHardwareBuffer_recvHandleFromUnixSocket(int socketFd, AHardwareBuffer** outBuffer);
// ----------------------------------------------------------------------------
// Everything below here is part of the public NDK API, but is intended only
// for use by device-specific graphics drivers.
struct native_handle;
-const struct native_handle* AHardwareBuffer_getNativeHandle(
- const AHardwareBuffer* buffer);
+const struct native_handle* AHardwareBuffer_getNativeHandle(const AHardwareBuffer* buffer);
__END_DECLS
diff --git a/libs/nativewindow/include/android/native_window.h b/libs/nativewindow/include/android/native_window.h
index 6cd5df3..a12bdd7 100644
--- a/libs/nativewindow/include/android/native_window.h
+++ b/libs/nativewindow/include/android/native_window.h
@@ -93,7 +93,7 @@
// memory. This may be >= width.
int32_t stride;
- // The format of the buffer. One of WINDOW_FORMAT_*
+ // The format of the buffer. One of AHARDWAREBUFFER_FORMAT_*
int32_t format;
// The actual bits.
@@ -127,7 +127,7 @@
int32_t ANativeWindow_getHeight(ANativeWindow* window);
/**
- * Return the current pixel format of the window surface. Returns a
+ * Return the current pixel format (AHARDWAREBUFFER_FORMAT_*) of the window surface. Returns a
* negative value on error.
*/
int32_t ANativeWindow_getFormat(ANativeWindow* window);
@@ -135,6 +135,8 @@
/**
* Change the format and size of the window buffers.
*
+ * format: one of AHARDWAREBUFFER_FORMAT_ constants
+ *
* The width and height control the number of pixels in the buffers, not the
* dimensions of the window on screen. If these are different than the
* window's physical size, then it buffer will be scaled to match that size
diff --git a/libs/nativewindow/include/system/window.h b/libs/nativewindow/include/system/window.h
new file mode 100644
index 0000000..63d1ad1
--- /dev/null
+++ b/libs/nativewindow/include/system/window.h
@@ -0,0 +1,952 @@
+/*
+ * Copyright (C) 2011 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.
+ */
+
+/*************************************************************************************************
+ *
+ * IMPORTANT:
+ *
+ * There is an old copy of this file in system/core/include/system/window.h, which exists only
+ * for backward source compatibility.
+ * But there are binaries out there as well, so this version of window.h must stay binary
+ * backward compatible with the one found in system/core.
+ *
+ *
+ * Source compatibility is also required for now, because this is how we're handling the
+ * transition from system/core/include (global include path) to nativewindow/include.
+ *
+ *************************************************************************************************/
+
+#pragma once
+
+#include <cutils/native_handle.h>
+#include <errno.h>
+#include <limits.h>
+#include <stdint.h>
+#include <string.h>
+#include <sys/cdefs.h>
+#include <system/graphics.h>
+#include <unistd.h>
+#include <stdbool.h>
+
+// system/window.h is a superset of the vndk
+#include <vndk/window.h>
+
+
+#ifndef __UNUSED
+#define __UNUSED __attribute__((__unused__))
+#endif
+#ifndef __deprecated
+#define __deprecated __attribute__((__deprecated__))
+#endif
+
+__BEGIN_DECLS
+
+/*****************************************************************************/
+
+#define ANDROID_NATIVE_WINDOW_MAGIC ANDROID_NATIVE_MAKE_CONSTANT('_','w','n','d')
+
+// ---------------------------------------------------------------------------
+
+typedef const native_handle_t* buffer_handle_t;
+
+// ---------------------------------------------------------------------------
+
+typedef struct android_native_rect_t
+{
+ int32_t left;
+ int32_t top;
+ int32_t right;
+ int32_t bottom;
+} android_native_rect_t;
+
+// ---------------------------------------------------------------------------
+
+// Old typedef for backwards compatibility.
+typedef ANativeWindowBuffer_t android_native_buffer_t;
+
+// ---------------------------------------------------------------------------
+
+/* attributes queriable with query() */
+enum {
+ NATIVE_WINDOW_WIDTH = 0,
+ NATIVE_WINDOW_HEIGHT = 1,
+ NATIVE_WINDOW_FORMAT = 2,
+
+ /* see ANativeWindowQuery in vndk/window.h */
+ NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS = ANATIVEWINDOW_QUERY_MIN_UNDEQUEUED_BUFFERS,
+
+ /* Check whether queueBuffer operations on the ANativeWindow send the buffer
+ * to the window compositor. The query sets the returned 'value' argument
+ * to 1 if the ANativeWindow DOES send queued buffers directly to the window
+ * compositor and 0 if the buffers do not go directly to the window
+ * compositor.
+ *
+ * This can be used to determine whether protected buffer content should be
+ * sent to the ANativeWindow. Note, however, that a result of 1 does NOT
+ * indicate that queued buffers will be protected from applications or users
+ * capturing their contents. If that behavior is desired then some other
+ * mechanism (e.g. the GRALLOC_USAGE_PROTECTED flag) should be used in
+ * conjunction with this query.
+ */
+ NATIVE_WINDOW_QUEUES_TO_WINDOW_COMPOSER = 4,
+
+ /* Get the concrete type of a ANativeWindow. See below for the list of
+ * possible return values.
+ *
+ * This query should not be used outside the Android framework and will
+ * likely be removed in the near future.
+ */
+ NATIVE_WINDOW_CONCRETE_TYPE = 5,
+
+
+ /*
+ * Default width and height of ANativeWindow buffers, these are the
+ * dimensions of the window buffers irrespective of the
+ * NATIVE_WINDOW_SET_BUFFERS_DIMENSIONS call and match the native window
+ * size unless overridden by NATIVE_WINDOW_SET_BUFFERS_USER_DIMENSIONS.
+ */
+ NATIVE_WINDOW_DEFAULT_WIDTH = ANATIVEWINDOW_QUERY_DEFAULT_WIDTH,
+ NATIVE_WINDOW_DEFAULT_HEIGHT = ANATIVEWINDOW_QUERY_DEFAULT_HEIGHT,
+
+ /* see ANativeWindowQuery in vndk/window.h */
+ NATIVE_WINDOW_TRANSFORM_HINT = ANATIVEWINDOW_QUERY_TRANSFORM_HINT,
+
+ /*
+ * Boolean that indicates whether the consumer is running more than
+ * one buffer behind the producer.
+ */
+ NATIVE_WINDOW_CONSUMER_RUNNING_BEHIND = 9,
+
+ /*
+ * The consumer gralloc usage bits currently set by the consumer.
+ * The values are defined in hardware/libhardware/include/gralloc.h.
+ */
+ NATIVE_WINDOW_CONSUMER_USAGE_BITS = 10,
+
+ /**
+ * Transformation that will by applied to buffers by the hwcomposer.
+ * This must not be set or checked by producer endpoints, and will
+ * disable the transform hint set in SurfaceFlinger (see
+ * NATIVE_WINDOW_TRANSFORM_HINT).
+ *
+ * INTENDED USE:
+ * Temporary - Please do not use this. This is intended only to be used
+ * by the camera's LEGACY mode.
+ *
+ * In situations where a SurfaceFlinger client wishes to set a transform
+ * that is not visible to the producer, and will always be applied in the
+ * hardware composer, the client can set this flag with
+ * native_window_set_buffers_sticky_transform. This can be used to rotate
+ * and flip buffers consumed by hardware composer without actually changing
+ * the aspect ratio of the buffers produced.
+ */
+ NATIVE_WINDOW_STICKY_TRANSFORM = 11,
+
+ /**
+ * The default data space for the buffers as set by the consumer.
+ * The values are defined in graphics.h.
+ */
+ NATIVE_WINDOW_DEFAULT_DATASPACE = 12,
+
+ /* see ANativeWindowQuery in vndk/window.h */
+ NATIVE_WINDOW_BUFFER_AGE = ANATIVEWINDOW_QUERY_BUFFER_AGE,
+
+ /*
+ * Returns the duration of the last dequeueBuffer call in microseconds
+ */
+ NATIVE_WINDOW_LAST_DEQUEUE_DURATION = 14,
+
+ /*
+ * Returns the duration of the last queueBuffer call in microseconds
+ */
+ NATIVE_WINDOW_LAST_QUEUE_DURATION = 15,
+
+ /*
+ * Returns the number of image layers that the ANativeWindow buffer
+ * contains. By default this is 1, unless a buffer is explicitly allocated
+ * to contain multiple layers.
+ */
+ NATIVE_WINDOW_LAYER_COUNT = 16,
+
+ /*
+ * Returns 1 if the native window is valid, 0 otherwise. native window is valid
+ * if it is safe (i.e. no crash will occur) to call any method on it.
+ */
+ NATIVE_WINDOW_IS_VALID = 17,
+};
+
+/* Valid operations for the (*perform)() hook.
+ *
+ * Values marked as 'deprecated' are supported, but have been superceded by
+ * other functionality.
+ *
+ * Values marked as 'private' should be considered private to the framework.
+ * HAL implementation code with access to an ANativeWindow should not use these,
+ * as it may not interact properly with the framework's use of the
+ * ANativeWindow.
+ */
+enum {
+// clang-format off
+ NATIVE_WINDOW_SET_USAGE = 0,
+ NATIVE_WINDOW_CONNECT = 1, /* deprecated */
+ NATIVE_WINDOW_DISCONNECT = 2, /* deprecated */
+ NATIVE_WINDOW_SET_CROP = 3, /* private */
+ NATIVE_WINDOW_SET_BUFFER_COUNT = 4,
+ NATIVE_WINDOW_SET_BUFFERS_GEOMETRY = 5, /* deprecated */
+ NATIVE_WINDOW_SET_BUFFERS_TRANSFORM = 6,
+ NATIVE_WINDOW_SET_BUFFERS_TIMESTAMP = 7,
+ NATIVE_WINDOW_SET_BUFFERS_DIMENSIONS = 8,
+ NATIVE_WINDOW_SET_BUFFERS_FORMAT = 9,
+ NATIVE_WINDOW_SET_SCALING_MODE = 10, /* private */
+ NATIVE_WINDOW_LOCK = 11, /* private */
+ NATIVE_WINDOW_UNLOCK_AND_POST = 12, /* private */
+ NATIVE_WINDOW_API_CONNECT = 13, /* private */
+ NATIVE_WINDOW_API_DISCONNECT = 14, /* private */
+ NATIVE_WINDOW_SET_BUFFERS_USER_DIMENSIONS = 15, /* private */
+ NATIVE_WINDOW_SET_POST_TRANSFORM_CROP = 16, /* private */
+ NATIVE_WINDOW_SET_BUFFERS_STICKY_TRANSFORM = 17,/* private */
+ NATIVE_WINDOW_SET_SIDEBAND_STREAM = 18,
+ NATIVE_WINDOW_SET_BUFFERS_DATASPACE = 19,
+ NATIVE_WINDOW_SET_SURFACE_DAMAGE = 20, /* private */
+ NATIVE_WINDOW_SET_SHARED_BUFFER_MODE = 21,
+ NATIVE_WINDOW_SET_AUTO_REFRESH = 22,
+ NATIVE_WINDOW_GET_REFRESH_CYCLE_DURATION= 23,
+ NATIVE_WINDOW_GET_NEXT_FRAME_ID = 24,
+ NATIVE_WINDOW_ENABLE_FRAME_TIMESTAMPS = 25,
+ NATIVE_WINDOW_GET_COMPOSITOR_TIMING = 26,
+ NATIVE_WINDOW_GET_FRAME_TIMESTAMPS = 27,
+ NATIVE_WINDOW_GET_WIDE_COLOR_SUPPORT = 28,
+ NATIVE_WINDOW_GET_HDR_SUPPORT = 29,
+// clang-format on
+};
+
+/* parameter for NATIVE_WINDOW_[API_][DIS]CONNECT */
+enum {
+ /* Buffers will be queued by EGL via eglSwapBuffers after being filled using
+ * OpenGL ES.
+ */
+ NATIVE_WINDOW_API_EGL = 1,
+
+ /* Buffers will be queued after being filled using the CPU
+ */
+ NATIVE_WINDOW_API_CPU = 2,
+
+ /* Buffers will be queued by Stagefright after being filled by a video
+ * decoder. The video decoder can either be a software or hardware decoder.
+ */
+ NATIVE_WINDOW_API_MEDIA = 3,
+
+ /* Buffers will be queued by the the camera HAL.
+ */
+ NATIVE_WINDOW_API_CAMERA = 4,
+};
+
+/* parameter for NATIVE_WINDOW_SET_BUFFERS_TRANSFORM */
+enum {
+ /* flip source image horizontally */
+ NATIVE_WINDOW_TRANSFORM_FLIP_H = HAL_TRANSFORM_FLIP_H ,
+ /* flip source image vertically */
+ NATIVE_WINDOW_TRANSFORM_FLIP_V = HAL_TRANSFORM_FLIP_V,
+ /* rotate source image 90 degrees clock-wise, and is applied after TRANSFORM_FLIP_{H|V} */
+ NATIVE_WINDOW_TRANSFORM_ROT_90 = HAL_TRANSFORM_ROT_90,
+ /* rotate source image 180 degrees */
+ NATIVE_WINDOW_TRANSFORM_ROT_180 = HAL_TRANSFORM_ROT_180,
+ /* rotate source image 270 degrees clock-wise */
+ NATIVE_WINDOW_TRANSFORM_ROT_270 = HAL_TRANSFORM_ROT_270,
+ /* transforms source by the inverse transform of the screen it is displayed onto. This
+ * transform is applied last */
+ NATIVE_WINDOW_TRANSFORM_INVERSE_DISPLAY = 0x08
+};
+
+/* parameter for NATIVE_WINDOW_SET_SCALING_MODE
+ * keep in sync with Surface.java in frameworks/base */
+enum {
+ /* the window content is not updated (frozen) until a buffer of
+ * the window size is received (enqueued)
+ */
+ NATIVE_WINDOW_SCALING_MODE_FREEZE = 0,
+ /* the buffer is scaled in both dimensions to match the window size */
+ NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW = 1,
+ /* the buffer is scaled uniformly such that the smaller dimension
+ * of the buffer matches the window size (cropping in the process)
+ */
+ NATIVE_WINDOW_SCALING_MODE_SCALE_CROP = 2,
+ /* the window is clipped to the size of the buffer's crop rectangle; pixels
+ * outside the crop rectangle are treated as if they are completely
+ * transparent.
+ */
+ NATIVE_WINDOW_SCALING_MODE_NO_SCALE_CROP = 3,
+};
+
+/* values returned by the NATIVE_WINDOW_CONCRETE_TYPE query */
+enum {
+ NATIVE_WINDOW_FRAMEBUFFER = 0, /* FramebufferNativeWindow */
+ NATIVE_WINDOW_SURFACE = 1, /* Surface */
+};
+
+/* parameter for NATIVE_WINDOW_SET_BUFFERS_TIMESTAMP
+ *
+ * Special timestamp value to indicate that timestamps should be auto-generated
+ * by the native window when queueBuffer is called. This is equal to INT64_MIN,
+ * defined directly to avoid problems with C99/C++ inclusion of stdint.h.
+ */
+static const int64_t NATIVE_WINDOW_TIMESTAMP_AUTO = (-9223372036854775807LL-1);
+
+struct ANativeWindow
+{
+#ifdef __cplusplus
+ ANativeWindow()
+ : flags(0), minSwapInterval(0), maxSwapInterval(0), xdpi(0), ydpi(0)
+ {
+ common.magic = ANDROID_NATIVE_WINDOW_MAGIC;
+ common.version = sizeof(ANativeWindow);
+ memset(common.reserved, 0, sizeof(common.reserved));
+ }
+
+ /* Implement the methods that sp<ANativeWindow> expects so that it
+ can be used to automatically refcount ANativeWindow's. */
+ void incStrong(const void* /*id*/) const {
+ common.incRef(const_cast<android_native_base_t*>(&common));
+ }
+ void decStrong(const void* /*id*/) const {
+ common.decRef(const_cast<android_native_base_t*>(&common));
+ }
+#endif
+
+ struct android_native_base_t common;
+
+ /* flags describing some attributes of this surface or its updater */
+ const uint32_t flags;
+
+ /* min swap interval supported by this updated */
+ const int minSwapInterval;
+
+ /* max swap interval supported by this updated */
+ const int maxSwapInterval;
+
+ /* horizontal and vertical resolution in DPI */
+ const float xdpi;
+ const float ydpi;
+
+ /* Some storage reserved for the OEM's driver. */
+ intptr_t oem[4];
+
+ /*
+ * Set the swap interval for this surface.
+ *
+ * Returns 0 on success or -errno on error.
+ */
+ int (*setSwapInterval)(struct ANativeWindow* window,
+ int interval);
+
+ /*
+ * Hook called by EGL to acquire a buffer. After this call, the buffer
+ * is not locked, so its content cannot be modified. This call may block if
+ * no buffers are available.
+ *
+ * The window holds a reference to the buffer between dequeueBuffer and
+ * either queueBuffer or cancelBuffer, so clients only need their own
+ * reference if they might use the buffer after queueing or canceling it.
+ * Holding a reference to a buffer after queueing or canceling it is only
+ * allowed if a specific buffer count has been set.
+ *
+ * Returns 0 on success or -errno on error.
+ *
+ * XXX: This function is deprecated. It will continue to work for some
+ * time for binary compatibility, but the new dequeueBuffer function that
+ * outputs a fence file descriptor should be used in its place.
+ */
+ int (*dequeueBuffer_DEPRECATED)(struct ANativeWindow* window,
+ struct ANativeWindowBuffer** buffer);
+
+ /*
+ * hook called by EGL to lock a buffer. This MUST be called before modifying
+ * the content of a buffer. The buffer must have been acquired with
+ * dequeueBuffer first.
+ *
+ * Returns 0 on success or -errno on error.
+ *
+ * XXX: This function is deprecated. It will continue to work for some
+ * time for binary compatibility, but it is essentially a no-op, and calls
+ * to it should be removed.
+ */
+ int (*lockBuffer_DEPRECATED)(struct ANativeWindow* window,
+ struct ANativeWindowBuffer* buffer);
+
+ /*
+ * Hook called by EGL when modifications to the render buffer are done.
+ * This unlocks and post the buffer.
+ *
+ * The window holds a reference to the buffer between dequeueBuffer and
+ * either queueBuffer or cancelBuffer, so clients only need their own
+ * reference if they might use the buffer after queueing or canceling it.
+ * Holding a reference to a buffer after queueing or canceling it is only
+ * allowed if a specific buffer count has been set.
+ *
+ * Buffers MUST be queued in the same order than they were dequeued.
+ *
+ * Returns 0 on success or -errno on error.
+ *
+ * XXX: This function is deprecated. It will continue to work for some
+ * time for binary compatibility, but the new queueBuffer function that
+ * takes a fence file descriptor should be used in its place (pass a value
+ * of -1 for the fence file descriptor if there is no valid one to pass).
+ */
+ int (*queueBuffer_DEPRECATED)(struct ANativeWindow* window,
+ struct ANativeWindowBuffer* buffer);
+
+ /*
+ * hook used to retrieve information about the native window.
+ *
+ * Returns 0 on success or -errno on error.
+ */
+ int (*query)(const struct ANativeWindow* window,
+ int what, int* value);
+
+ /*
+ * hook used to perform various operations on the surface.
+ * (*perform)() is a generic mechanism to add functionality to
+ * ANativeWindow while keeping backward binary compatibility.
+ *
+ * DO NOT CALL THIS HOOK DIRECTLY. Instead, use the helper functions
+ * defined below.
+ *
+ * (*perform)() returns -ENOENT if the 'what' parameter is not supported
+ * by the surface's implementation.
+ *
+ * See above for a list of valid operations, such as
+ * NATIVE_WINDOW_SET_USAGE or NATIVE_WINDOW_CONNECT
+ */
+ int (*perform)(struct ANativeWindow* window,
+ int operation, ... );
+
+ /*
+ * Hook used to cancel a buffer that has been dequeued.
+ * No synchronization is performed between dequeue() and cancel(), so
+ * either external synchronization is needed, or these functions must be
+ * called from the same thread.
+ *
+ * The window holds a reference to the buffer between dequeueBuffer and
+ * either queueBuffer or cancelBuffer, so clients only need their own
+ * reference if they might use the buffer after queueing or canceling it.
+ * Holding a reference to a buffer after queueing or canceling it is only
+ * allowed if a specific buffer count has been set.
+ *
+ * XXX: This function is deprecated. It will continue to work for some
+ * time for binary compatibility, but the new cancelBuffer function that
+ * takes a fence file descriptor should be used in its place (pass a value
+ * of -1 for the fence file descriptor if there is no valid one to pass).
+ */
+ int (*cancelBuffer_DEPRECATED)(struct ANativeWindow* window,
+ struct ANativeWindowBuffer* buffer);
+
+ /*
+ * Hook called by EGL to acquire a buffer. This call may block if no
+ * buffers are available.
+ *
+ * The window holds a reference to the buffer between dequeueBuffer and
+ * either queueBuffer or cancelBuffer, so clients only need their own
+ * reference if they might use the buffer after queueing or canceling it.
+ * Holding a reference to a buffer after queueing or canceling it is only
+ * allowed if a specific buffer count has been set.
+ *
+ * The libsync fence file descriptor returned in the int pointed to by the
+ * fenceFd argument will refer to the fence that must signal before the
+ * dequeued buffer may be written to. A value of -1 indicates that the
+ * caller may access the buffer immediately without waiting on a fence. If
+ * a valid file descriptor is returned (i.e. any value except -1) then the
+ * caller is responsible for closing the file descriptor.
+ *
+ * Returns 0 on success or -errno on error.
+ */
+ int (*dequeueBuffer)(struct ANativeWindow* window,
+ struct ANativeWindowBuffer** buffer, int* fenceFd);
+
+ /*
+ * Hook called by EGL when modifications to the render buffer are done.
+ * This unlocks and post the buffer.
+ *
+ * The window holds a reference to the buffer between dequeueBuffer and
+ * either queueBuffer or cancelBuffer, so clients only need their own
+ * reference if they might use the buffer after queueing or canceling it.
+ * Holding a reference to a buffer after queueing or canceling it is only
+ * allowed if a specific buffer count has been set.
+ *
+ * The fenceFd argument specifies a libsync fence file descriptor for a
+ * fence that must signal before the buffer can be accessed. If the buffer
+ * can be accessed immediately then a value of -1 should be used. The
+ * caller must not use the file descriptor after it is passed to
+ * queueBuffer, and the ANativeWindow implementation is responsible for
+ * closing it.
+ *
+ * Returns 0 on success or -errno on error.
+ */
+ int (*queueBuffer)(struct ANativeWindow* window,
+ struct ANativeWindowBuffer* buffer, int fenceFd);
+
+ /*
+ * Hook used to cancel a buffer that has been dequeued.
+ * No synchronization is performed between dequeue() and cancel(), so
+ * either external synchronization is needed, or these functions must be
+ * called from the same thread.
+ *
+ * The window holds a reference to the buffer between dequeueBuffer and
+ * either queueBuffer or cancelBuffer, so clients only need their own
+ * reference if they might use the buffer after queueing or canceling it.
+ * Holding a reference to a buffer after queueing or canceling it is only
+ * allowed if a specific buffer count has been set.
+ *
+ * The fenceFd argument specifies a libsync fence file decsriptor for a
+ * fence that must signal before the buffer can be accessed. If the buffer
+ * can be accessed immediately then a value of -1 should be used.
+ *
+ * Note that if the client has not waited on the fence that was returned
+ * from dequeueBuffer, that same fence should be passed to cancelBuffer to
+ * ensure that future uses of the buffer are preceded by a wait on that
+ * fence. The caller must not use the file descriptor after it is passed
+ * to cancelBuffer, and the ANativeWindow implementation is responsible for
+ * closing it.
+ *
+ * Returns 0 on success or -errno on error.
+ */
+ int (*cancelBuffer)(struct ANativeWindow* window,
+ struct ANativeWindowBuffer* buffer, int fenceFd);
+};
+
+ /* Backwards compatibility: use ANativeWindow (struct ANativeWindow in C).
+ * android_native_window_t is deprecated.
+ */
+typedef struct ANativeWindow ANativeWindow;
+typedef struct ANativeWindow android_native_window_t __deprecated;
+
+/*
+ * native_window_set_usage(..., usage)
+ * Sets the intended usage flags for the next buffers
+ * acquired with (*lockBuffer)() and on.
+ * By default (if this function is never called), a usage of
+ * GRALLOC_USAGE_HW_RENDER | GRALLOC_USAGE_HW_TEXTURE
+ * is assumed.
+ * Calling this function will usually cause following buffers to be
+ * reallocated.
+ */
+
+static inline int native_window_set_usage(
+ struct ANativeWindow* window, int usage)
+{
+ return window->perform(window, NATIVE_WINDOW_SET_USAGE, usage);
+}
+
+/* deprecated. Always returns 0. Don't call. */
+static inline int native_window_connect(
+ struct ANativeWindow* window __UNUSED, int api __UNUSED) __deprecated;
+
+static inline int native_window_connect(
+ struct ANativeWindow* window __UNUSED, int api __UNUSED) {
+ return 0;
+}
+
+/* deprecated. Always returns 0. Don't call. */
+static inline int native_window_disconnect(
+ struct ANativeWindow* window __UNUSED, int api __UNUSED) __deprecated;
+
+static inline int native_window_disconnect(
+ struct ANativeWindow* window __UNUSED, int api __UNUSED) {
+ return 0;
+}
+
+/*
+ * native_window_set_crop(..., crop)
+ * Sets which region of the next queued buffers needs to be considered.
+ * Depending on the scaling mode, a buffer's crop region is scaled and/or
+ * cropped to match the surface's size. This function sets the crop in
+ * pre-transformed buffer pixel coordinates.
+ *
+ * The specified crop region applies to all buffers queued after it is called.
+ *
+ * If 'crop' is NULL, subsequently queued buffers won't be cropped.
+ *
+ * An error is returned if for instance the crop region is invalid, out of the
+ * buffer's bound or if the window is invalid.
+ */
+static inline int native_window_set_crop(
+ struct ANativeWindow* window,
+ android_native_rect_t const * crop)
+{
+ return window->perform(window, NATIVE_WINDOW_SET_CROP, crop);
+}
+
+/*
+ * native_window_set_post_transform_crop(..., crop)
+ * Sets which region of the next queued buffers needs to be considered.
+ * Depending on the scaling mode, a buffer's crop region is scaled and/or
+ * cropped to match the surface's size. This function sets the crop in
+ * post-transformed pixel coordinates.
+ *
+ * The specified crop region applies to all buffers queued after it is called.
+ *
+ * If 'crop' is NULL, subsequently queued buffers won't be cropped.
+ *
+ * An error is returned if for instance the crop region is invalid, out of the
+ * buffer's bound or if the window is invalid.
+ */
+static inline int native_window_set_post_transform_crop(
+ struct ANativeWindow* window,
+ android_native_rect_t const * crop)
+{
+ return window->perform(window, NATIVE_WINDOW_SET_POST_TRANSFORM_CROP, crop);
+}
+
+/*
+ * native_window_set_active_rect(..., active_rect)
+ *
+ * This function is deprecated and will be removed soon. For now it simply
+ * sets the post-transform crop for compatibility while multi-project commits
+ * get checked.
+ */
+static inline int native_window_set_active_rect(
+ struct ANativeWindow* window,
+ android_native_rect_t const * active_rect) __deprecated;
+
+static inline int native_window_set_active_rect(
+ struct ANativeWindow* window,
+ android_native_rect_t const * active_rect)
+{
+ return native_window_set_post_transform_crop(window, active_rect);
+}
+
+/*
+ * native_window_set_buffer_count(..., count)
+ * Sets the number of buffers associated with this native window.
+ */
+static inline int native_window_set_buffer_count(
+ struct ANativeWindow* window,
+ size_t bufferCount)
+{
+ return window->perform(window, NATIVE_WINDOW_SET_BUFFER_COUNT, bufferCount);
+}
+
+/*
+ * native_window_set_buffers_geometry(..., int w, int h, int format)
+ * All buffers dequeued after this call will have the dimensions and format
+ * specified. A successful call to this function has the same effect as calling
+ * native_window_set_buffers_size and native_window_set_buffers_format.
+ *
+ * XXX: This function is deprecated. The native_window_set_buffers_dimensions
+ * and native_window_set_buffers_format functions should be used instead.
+ */
+static inline int native_window_set_buffers_geometry(
+ struct ANativeWindow* window,
+ int w, int h, int format) __deprecated;
+
+static inline int native_window_set_buffers_geometry(
+ struct ANativeWindow* window,
+ int w, int h, int format)
+{
+ return window->perform(window, NATIVE_WINDOW_SET_BUFFERS_GEOMETRY,
+ w, h, format);
+}
+
+/*
+ * native_window_set_buffers_dimensions(..., int w, int h)
+ * All buffers dequeued after this call will have the dimensions specified.
+ * In particular, all buffers will have a fixed-size, independent from the
+ * native-window size. They will be scaled according to the scaling mode
+ * (see native_window_set_scaling_mode) upon window composition.
+ *
+ * If w and h are 0, the normal behavior is restored. That is, dequeued buffers
+ * following this call will be sized to match the window's size.
+ *
+ * Calling this function will reset the window crop to a NULL value, which
+ * disables cropping of the buffers.
+ */
+static inline int native_window_set_buffers_dimensions(
+ struct ANativeWindow* window,
+ int w, int h)
+{
+ return window->perform(window, NATIVE_WINDOW_SET_BUFFERS_DIMENSIONS,
+ w, h);
+}
+
+/*
+ * native_window_set_buffers_user_dimensions(..., int w, int h)
+ *
+ * Sets the user buffer size for the window, which overrides the
+ * window's size. All buffers dequeued after this call will have the
+ * dimensions specified unless overridden by
+ * native_window_set_buffers_dimensions. All buffers will have a
+ * fixed-size, independent from the native-window size. They will be
+ * scaled according to the scaling mode (see
+ * native_window_set_scaling_mode) upon window composition.
+ *
+ * If w and h are 0, the normal behavior is restored. That is, the
+ * default buffer size will match the windows's size.
+ *
+ * Calling this function will reset the window crop to a NULL value, which
+ * disables cropping of the buffers.
+ */
+static inline int native_window_set_buffers_user_dimensions(
+ struct ANativeWindow* window,
+ int w, int h)
+{
+ return window->perform(window, NATIVE_WINDOW_SET_BUFFERS_USER_DIMENSIONS,
+ w, h);
+}
+
+/*
+ * native_window_set_buffers_format(..., int format)
+ * All buffers dequeued after this call will have the format specified.
+ *
+ * If the specified format is 0, the default buffer format will be used.
+ */
+static inline int native_window_set_buffers_format(
+ struct ANativeWindow* window,
+ int format)
+{
+ return window->perform(window, NATIVE_WINDOW_SET_BUFFERS_FORMAT, format);
+}
+
+/*
+ * native_window_set_buffers_data_space(..., int dataSpace)
+ * All buffers queued after this call will be associated with the dataSpace
+ * parameter specified.
+ *
+ * dataSpace specifies additional information about the buffer that's dependent
+ * on the buffer format and the endpoints. For example, it can be used to convey
+ * the color space of the image data in the buffer, or it can be used to
+ * indicate that the buffers contain depth measurement data instead of color
+ * images. The default dataSpace is 0, HAL_DATASPACE_UNKNOWN, unless it has been
+ * overridden by the consumer.
+ */
+static inline int native_window_set_buffers_data_space(
+ struct ANativeWindow* window,
+ android_dataspace_t dataSpace)
+{
+ return window->perform(window, NATIVE_WINDOW_SET_BUFFERS_DATASPACE,
+ dataSpace);
+}
+
+/*
+ * native_window_set_buffers_transform(..., int transform)
+ * All buffers queued after this call will be displayed transformed according
+ * to the transform parameter specified.
+ */
+static inline int native_window_set_buffers_transform(
+ struct ANativeWindow* window,
+ int transform)
+{
+ return window->perform(window, NATIVE_WINDOW_SET_BUFFERS_TRANSFORM,
+ transform);
+}
+
+/*
+ * native_window_set_buffers_sticky_transform(..., int transform)
+ * All buffers queued after this call will be displayed transformed according
+ * to the transform parameter specified applied on top of the regular buffer
+ * transform. Setting this transform will disable the transform hint.
+ *
+ * Temporary - This is only intended to be used by the LEGACY camera mode, do
+ * not use this for anything else.
+ */
+static inline int native_window_set_buffers_sticky_transform(
+ struct ANativeWindow* window,
+ int transform)
+{
+ return window->perform(window, NATIVE_WINDOW_SET_BUFFERS_STICKY_TRANSFORM,
+ transform);
+}
+
+/*
+ * native_window_set_buffers_timestamp(..., int64_t timestamp)
+ * All buffers queued after this call will be associated with the timestamp
+ * parameter specified. If the timestamp is set to NATIVE_WINDOW_TIMESTAMP_AUTO
+ * (the default), timestamps will be generated automatically when queueBuffer is
+ * called. The timestamp is measured in nanoseconds, and is normally monotonically
+ * increasing. The timestamp should be unaffected by time-of-day adjustments,
+ * and for a camera should be strictly monotonic but for a media player may be
+ * reset when the position is set.
+ */
+static inline int native_window_set_buffers_timestamp(
+ struct ANativeWindow* window,
+ int64_t timestamp)
+{
+ return window->perform(window, NATIVE_WINDOW_SET_BUFFERS_TIMESTAMP,
+ timestamp);
+}
+
+/*
+ * native_window_set_scaling_mode(..., int mode)
+ * All buffers queued after this call will be associated with the scaling mode
+ * specified.
+ */
+static inline int native_window_set_scaling_mode(
+ struct ANativeWindow* window,
+ int mode)
+{
+ return window->perform(window, NATIVE_WINDOW_SET_SCALING_MODE,
+ mode);
+}
+
+/*
+ * native_window_api_connect(..., int api)
+ * connects an API to this window. only one API can be connected at a time.
+ * Returns -EINVAL if for some reason the window cannot be connected, which
+ * can happen if it's connected to some other API.
+ */
+static inline int native_window_api_connect(
+ struct ANativeWindow* window, int api)
+{
+ return window->perform(window, NATIVE_WINDOW_API_CONNECT, api);
+}
+
+/*
+ * native_window_api_disconnect(..., int api)
+ * disconnect the API from this window.
+ * An error is returned if for instance the window wasn't connected in the
+ * first place.
+ */
+static inline int native_window_api_disconnect(
+ struct ANativeWindow* window, int api)
+{
+ return window->perform(window, NATIVE_WINDOW_API_DISCONNECT, api);
+}
+
+/*
+ * native_window_dequeue_buffer_and_wait(...)
+ * Dequeue a buffer and wait on the fence associated with that buffer. The
+ * buffer may safely be accessed immediately upon this function returning. An
+ * error is returned if either of the dequeue or the wait operations fail.
+ */
+static inline int native_window_dequeue_buffer_and_wait(ANativeWindow *anw,
+ struct ANativeWindowBuffer** anb) {
+ return anw->dequeueBuffer_DEPRECATED(anw, anb);
+}
+
+/*
+ * native_window_set_sideband_stream(..., native_handle_t*)
+ * Attach a sideband buffer stream to a native window.
+ */
+static inline int native_window_set_sideband_stream(
+ struct ANativeWindow* window,
+ native_handle_t* sidebandHandle)
+{
+ return window->perform(window, NATIVE_WINDOW_SET_SIDEBAND_STREAM,
+ sidebandHandle);
+}
+
+/*
+ * native_window_set_surface_damage(..., android_native_rect_t* rects, int numRects)
+ * Set the surface damage (i.e., the region of the surface that has changed
+ * since the previous frame). The damage set by this call will be reset (to the
+ * default of full-surface damage) after calling queue, so this must be called
+ * prior to every frame with damage that does not cover the whole surface if the
+ * caller desires downstream consumers to use this optimization.
+ *
+ * The damage region is specified as an array of rectangles, with the important
+ * caveat that the origin of the surface is considered to be the bottom-left
+ * corner, as in OpenGL ES.
+ *
+ * If numRects is set to 0, rects may be NULL, and the surface damage will be
+ * set to the full surface (the same as if this function had not been called for
+ * this frame).
+ */
+static inline int native_window_set_surface_damage(
+ struct ANativeWindow* window,
+ const android_native_rect_t* rects, size_t numRects)
+{
+ return window->perform(window, NATIVE_WINDOW_SET_SURFACE_DAMAGE,
+ rects, numRects);
+}
+
+/*
+ * native_window_set_shared_buffer_mode(..., bool sharedBufferMode)
+ * Enable/disable shared buffer mode
+ */
+static inline int native_window_set_shared_buffer_mode(
+ struct ANativeWindow* window,
+ bool sharedBufferMode)
+{
+ return window->perform(window, NATIVE_WINDOW_SET_SHARED_BUFFER_MODE,
+ sharedBufferMode);
+}
+
+/*
+ * native_window_set_auto_refresh(..., autoRefresh)
+ * Enable/disable auto refresh when in shared buffer mode
+ */
+static inline int native_window_set_auto_refresh(
+ struct ANativeWindow* window,
+ bool autoRefresh)
+{
+ return window->perform(window, NATIVE_WINDOW_SET_AUTO_REFRESH, autoRefresh);
+}
+
+static inline int native_window_get_refresh_cycle_duration(
+ struct ANativeWindow* window,
+ int64_t* outRefreshDuration)
+{
+ return window->perform(window, NATIVE_WINDOW_GET_REFRESH_CYCLE_DURATION,
+ outRefreshDuration);
+}
+
+static inline int native_window_get_next_frame_id(
+ struct ANativeWindow* window, uint64_t* frameId)
+{
+ return window->perform(window, NATIVE_WINDOW_GET_NEXT_FRAME_ID, frameId);
+}
+
+static inline int native_window_enable_frame_timestamps(
+ struct ANativeWindow* window, bool enable)
+{
+ return window->perform(window, NATIVE_WINDOW_ENABLE_FRAME_TIMESTAMPS,
+ enable);
+}
+
+static inline int native_window_get_compositor_timing(
+ struct ANativeWindow* window,
+ int64_t* compositeDeadline, int64_t* compositeInterval,
+ int64_t* compositeToPresentLatency)
+{
+ return window->perform(window, NATIVE_WINDOW_GET_COMPOSITOR_TIMING,
+ compositeDeadline, compositeInterval, compositeToPresentLatency);
+}
+
+static inline int native_window_get_frame_timestamps(
+ struct ANativeWindow* window, uint64_t frameId,
+ int64_t* outRequestedPresentTime, int64_t* outAcquireTime,
+ int64_t* outLatchTime, int64_t* outFirstRefreshStartTime,
+ int64_t* outLastRefreshStartTime, int64_t* outGpuCompositionDoneTime,
+ int64_t* outDisplayPresentTime, int64_t* outDequeueReadyTime,
+ int64_t* outReleaseTime)
+{
+ return window->perform(window, NATIVE_WINDOW_GET_FRAME_TIMESTAMPS,
+ frameId, outRequestedPresentTime, outAcquireTime, outLatchTime,
+ outFirstRefreshStartTime, outLastRefreshStartTime,
+ outGpuCompositionDoneTime, outDisplayPresentTime,
+ outDequeueReadyTime, outReleaseTime);
+}
+
+static inline int native_window_get_wide_color_support(
+ struct ANativeWindow* window, bool* outSupport) {
+ return window->perform(window, NATIVE_WINDOW_GET_WIDE_COLOR_SUPPORT,
+ outSupport);
+}
+
+static inline int native_window_get_hdr_support(struct ANativeWindow* window,
+ bool* outSupport) {
+ return window->perform(window, NATIVE_WINDOW_GET_HDR_SUPPORT, outSupport);
+}
+
+__END_DECLS
diff --git a/libs/nativewindow/include/vndk/window.h b/libs/nativewindow/include/vndk/window.h
new file mode 100644
index 0000000..89585f3
--- /dev/null
+++ b/libs/nativewindow/include/vndk/window.h
@@ -0,0 +1,407 @@
+/*
+ * 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 ANDROID_VNDK_NATIVEWINDOW_ANATIVEWINDOW_H
+#define ANDROID_VNDK_NATIVEWINDOW_ANATIVEWINDOW_H
+
+#include <stdint.h>
+#include <stdbool.h>
+#include <sys/cdefs.h>
+#include <system/graphics-base.h>
+#include <cutils/native_handle.h>
+
+// vndk is a superset of the NDK
+#include <android/native_window.h>
+
+__BEGIN_DECLS
+
+/*****************************************************************************/
+
+#ifdef __cplusplus
+#define ANDROID_NATIVE_UNSIGNED_CAST(x) static_cast<unsigned int>(x)
+#else
+#define ANDROID_NATIVE_UNSIGNED_CAST(x) ((unsigned int)(x))
+#endif
+
+#define ANDROID_NATIVE_MAKE_CONSTANT(a,b,c,d) \
+ ((ANDROID_NATIVE_UNSIGNED_CAST(a) << 24) | \
+ (ANDROID_NATIVE_UNSIGNED_CAST(b) << 16) | \
+ (ANDROID_NATIVE_UNSIGNED_CAST(c) << 8) | \
+ (ANDROID_NATIVE_UNSIGNED_CAST(d)))
+
+#define ANDROID_NATIVE_BUFFER_MAGIC ANDROID_NATIVE_MAKE_CONSTANT('_','b','f','r')
+
+
+/*****************************************************************************/
+
+typedef struct android_native_base_t
+{
+ /* a magic value defined by the actual EGL native type */
+ int magic;
+
+ /* the sizeof() of the actual EGL native type */
+ int version;
+
+ void* reserved[4];
+
+ /* reference-counting interface */
+ void (*incRef)(struct android_native_base_t* base);
+ void (*decRef)(struct android_native_base_t* base);
+} android_native_base_t;
+
+typedef struct ANativeWindowBuffer
+{
+#ifdef __cplusplus
+ ANativeWindowBuffer() {
+ common.magic = ANDROID_NATIVE_BUFFER_MAGIC;
+ common.version = sizeof(ANativeWindowBuffer);
+ memset(common.reserved, 0, sizeof(common.reserved));
+ }
+
+ // Implement the methods that sp<ANativeWindowBuffer> expects so that it
+ // can be used to automatically refcount ANativeWindowBuffer's.
+ void incStrong(const void* /*id*/) const {
+ common.incRef(const_cast<android_native_base_t*>(&common));
+ }
+ void decStrong(const void* /*id*/) const {
+ common.decRef(const_cast<android_native_base_t*>(&common));
+ }
+#endif
+
+ struct android_native_base_t common;
+
+ int width;
+ int height;
+ int stride;
+ int format;
+ int usage;
+ uintptr_t layerCount;
+
+ void* reserved[1];
+
+ const native_handle_t* handle;
+
+ void* reserved_proc[8];
+} ANativeWindowBuffer_t;
+
+typedef struct ANativeWindowBuffer ANativeWindowBuffer;
+
+/*****************************************************************************/
+
+
+/*
+ * Stores a value into one of the 4 available slots
+ * Retrieve the value with ANativeWindow_OemStorageGet()
+ *
+ * slot: 0 to 3
+ *
+ * Returns 0 on success or -errno on error.
+ */
+int ANativeWindow_OemStorageSet(ANativeWindow* window, uint32_t slot, intptr_t value);
+
+
+/*
+ * Retrieves a value from one of the 4 available slots
+ * By default the returned value is 0 if it wasn't set by ANativeWindow_OemStorageSet()
+ *
+ * slot: 0 to 3
+ *
+ * Returns 0 on success or -errno on error.
+ */
+int ANativeWindow_OemStorageGet(ANativeWindow* window, uint32_t slot, intptr_t* value);
+
+
+/*
+ * Set the swap interval for this surface.
+ *
+ * Returns 0 on success or -errno on error.
+ */
+int ANativeWindow_setSwapInterval(ANativeWindow* window, int interval);
+
+
+/*
+ * queries that can be used with ANativeWindow_query() and ANativeWindow_queryf()
+ */
+enum ANativeWindowQuery {
+ /* The minimum number of buffers that must remain un-dequeued after a buffer
+ * has been queued. This value applies only if set_buffer_count was used to
+ * override the number of buffers and if a buffer has since been queued.
+ * Users of the set_buffer_count ANativeWindow method should query this
+ * value before calling set_buffer_count. If it is necessary to have N
+ * buffers simultaneously dequeued as part of the steady-state operation,
+ * and this query returns M then N+M buffers should be requested via
+ * native_window_set_buffer_count.
+ *
+ * Note that this value does NOT apply until a single buffer has been
+ * queued. In particular this means that it is possible to:
+ *
+ * 1. Query M = min undequeued buffers
+ * 2. Set the buffer count to N + M
+ * 3. Dequeue all N + M buffers
+ * 4. Cancel M buffers
+ * 5. Queue, dequeue, queue, dequeue, ad infinitum
+ */
+ ANATIVEWINDOW_QUERY_MIN_UNDEQUEUED_BUFFERS = 3,
+
+ /*
+ * Default width of ANativeWindow buffers, these are the
+ * dimensions of the window buffers irrespective of the
+ * ANativeWindow_setBuffersDimensions() call and match the native window
+ * size.
+ */
+ ANATIVEWINDOW_QUERY_DEFAULT_WIDTH = 6,
+ ANATIVEWINDOW_QUERY_DEFAULT_HEIGHT = 7,
+
+ /*
+ * transformation that will most-likely be applied to buffers. This is only
+ * a hint, the actual transformation applied might be different.
+ *
+ * INTENDED USE:
+ *
+ * The transform hint can be used by a producer, for instance the GLES
+ * driver, to pre-rotate the rendering such that the final transformation
+ * in the composer is identity. This can be very useful when used in
+ * conjunction with the h/w composer HAL, in situations where it
+ * cannot handle arbitrary rotations.
+ *
+ * 1. Before dequeuing a buffer, the GL driver (or any other ANW client)
+ * queries the ANW for NATIVE_WINDOW_TRANSFORM_HINT.
+ *
+ * 2. The GL driver overrides the width and height of the ANW to
+ * account for NATIVE_WINDOW_TRANSFORM_HINT. This is done by querying
+ * NATIVE_WINDOW_DEFAULT_{WIDTH | HEIGHT}, swapping the dimensions
+ * according to NATIVE_WINDOW_TRANSFORM_HINT and calling
+ * native_window_set_buffers_dimensions().
+ *
+ * 3. The GL driver dequeues a buffer of the new pre-rotated size.
+ *
+ * 4. The GL driver renders to the buffer such that the image is
+ * already transformed, that is applying NATIVE_WINDOW_TRANSFORM_HINT
+ * to the rendering.
+ *
+ * 5. The GL driver calls native_window_set_transform to apply
+ * inverse transformation to the buffer it just rendered.
+ * In order to do this, the GL driver needs
+ * to calculate the inverse of NATIVE_WINDOW_TRANSFORM_HINT, this is
+ * done easily:
+ *
+ * int hintTransform, inverseTransform;
+ * query(..., NATIVE_WINDOW_TRANSFORM_HINT, &hintTransform);
+ * inverseTransform = hintTransform;
+ * if (hintTransform & HAL_TRANSFORM_ROT_90)
+ * inverseTransform ^= HAL_TRANSFORM_ROT_180;
+ *
+ *
+ * 6. The GL driver queues the pre-transformed buffer.
+ *
+ * 7. The composer combines the buffer transform with the display
+ * transform. If the buffer transform happens to cancel out the
+ * display transform then no rotation is needed.
+ *
+ */
+ ANATIVEWINDOW_QUERY_TRANSFORM_HINT = 8,
+
+ /*
+ * Returns the age of the contents of the most recently dequeued buffer as
+ * the number of frames that have elapsed since it was last queued. For
+ * example, if the window is double-buffered, the age of any given buffer in
+ * steady state will be 2. If the dequeued buffer has never been queued, its
+ * age will be 0.
+ */
+ ANATIVEWINDOW_QUERY_BUFFER_AGE = 13,
+
+ /* min swap interval supported by this compositor */
+ ANATIVEWINDOW_QUERY_MIN_SWAP_INTERVAL = 0x10000,
+
+ /* max swap interval supported by this compositor */
+ ANATIVEWINDOW_QUERY_MAX_SWAP_INTERVAL = 0x10001,
+
+ /* horizontal resolution in DPI. value is float, use queryf() */
+ ANATIVEWINDOW_QUERY_XDPI = 0x10002,
+
+ /* vertical resolution in DPI. value is float, use queryf() */
+ ANATIVEWINDOW_QUERY_YDPI = 0x10003,
+};
+
+/*
+ * hook used to retrieve information about the native window.
+ *
+ * Returns 0 on success or -errno on error.
+ */
+int ANativeWindow_query(const ANativeWindow* window, ANativeWindowQuery query, int* value);
+int ANativeWindow_queryf(const ANativeWindow* window, ANativeWindowQuery query, float* value);
+
+
+/*
+ * Hook called by EGL to acquire a buffer. This call may block if no
+ * buffers are available.
+ *
+ * The window holds a reference to the buffer between dequeueBuffer and
+ * either queueBuffer or cancelBuffer, so clients only need their own
+ * reference if they might use the buffer after queueing or canceling it.
+ * Holding a reference to a buffer after queueing or canceling it is only
+ * allowed if a specific buffer count has been set.
+ *
+ * The libsync fence file descriptor returned in the int pointed to by the
+ * fenceFd argument will refer to the fence that must signal before the
+ * dequeued buffer may be written to. A value of -1 indicates that the
+ * caller may access the buffer immediately without waiting on a fence. If
+ * a valid file descriptor is returned (i.e. any value except -1) then the
+ * caller is responsible for closing the file descriptor.
+ *
+ * Returns 0 on success or -errno on error.
+ */
+int ANativeWindow_dequeueBuffer(ANativeWindow* window, ANativeWindowBuffer** buffer, int* fenceFd);
+
+
+/*
+ * Hook called by EGL when modifications to the render buffer are done.
+ * This unlocks and post the buffer.
+ *
+ * The window holds a reference to the buffer between dequeueBuffer and
+ * either queueBuffer or cancelBuffer, so clients only need their own
+ * reference if they might use the buffer after queueing or canceling it.
+ * Holding a reference to a buffer after queueing or canceling it is only
+ * allowed if a specific buffer count has been set.
+ *
+ * The fenceFd argument specifies a libsync fence file descriptor for a
+ * fence that must signal before the buffer can be accessed. If the buffer
+ * can be accessed immediately then a value of -1 should be used. The
+ * caller must not use the file descriptor after it is passed to
+ * queueBuffer, and the ANativeWindow implementation is responsible for
+ * closing it.
+ *
+ * Returns 0 on success or -errno on error.
+ */
+int ANativeWindow_queueBuffer(ANativeWindow* window, ANativeWindowBuffer* buffer, int fenceFd);
+
+
+/*
+ * Hook used to cancel a buffer that has been dequeued.
+ * No synchronization is performed between dequeue() and cancel(), so
+ * either external synchronization is needed, or these functions must be
+ * called from the same thread.
+ *
+ * The window holds a reference to the buffer between dequeueBuffer and
+ * either queueBuffer or cancelBuffer, so clients only need their own
+ * reference if they might use the buffer after queueing or canceling it.
+ * Holding a reference to a buffer after queueing or canceling it is only
+ * allowed if a specific buffer count has been set.
+ *
+ * The fenceFd argument specifies a libsync fence file decsriptor for a
+ * fence that must signal before the buffer can be accessed. If the buffer
+ * can be accessed immediately then a value of -1 should be used.
+ *
+ * Note that if the client has not waited on the fence that was returned
+ * from dequeueBuffer, that same fence should be passed to cancelBuffer to
+ * ensure that future uses of the buffer are preceded by a wait on that
+ * fence. The caller must not use the file descriptor after it is passed
+ * to cancelBuffer, and the ANativeWindow implementation is responsible for
+ * closing it.
+ *
+ * Returns 0 on success or -errno on error.
+ */
+int ANativeWindow_cancelBuffer(ANativeWindow* window, ANativeWindowBuffer* buffer, int fenceFd);
+
+/*
+ * Sets the intended usage flags for the next buffers.
+ *
+ * usage: one of AHARDWAREBUFFER_USAGE0_* constant
+ * privateUsage: one of AHARDWAREBUFFER_USAGE1_*_PRIVATE_* constant
+ *
+ * By default (if this function is never called), a usage of
+ * AHARDWAREBUFFER_USAGE0_GPU_SAMPLED_IMAGE | AHARDWAREBUFFER_USAGE0_GPU_COLOR_OUTPUT
+ * is assumed.
+ *
+ * Calling this function will usually cause following buffers to be
+ * reallocated.
+ */
+int ANativeWindow_setUsage(ANativeWindow* window, uint64_t usage0, uint64_t usage1);
+
+
+/*
+ * Sets the number of buffers associated with this native window.
+ */
+int ANativeWindow_setBufferCount(ANativeWindow* window, size_t bufferCount);
+
+
+/*
+ * All buffers dequeued after this call will have the dimensions specified.
+ * In particular, all buffers will have a fixed-size, independent from the
+ * native-window size. They will be scaled according to the scaling mode
+ * (see native_window_set_scaling_mode) upon window composition.
+ *
+ * If w and h are 0, the normal behavior is restored. That is, dequeued buffers
+ * following this call will be sized to match the window's size.
+ *
+ * Calling this function will reset the window crop to a NULL value, which
+ * disables cropping of the buffers.
+ */
+int ANativeWindow_setBuffersDimensions(ANativeWindow* window, uint32_t w, uint32_t h);
+
+
+/*
+ * All buffers dequeued after this call will have the format specified.
+ * format: one of AHARDWAREBUFFER_FORMAT_* constant
+ *
+ * If the specified format is 0, the default buffer format will be used.
+ */
+int ANativeWindow_setBuffersFormat(ANativeWindow* window, int format);
+
+
+/*
+ * All buffers queued after this call will be associated with the timestamp in nanosecond
+ * parameter specified. If the timestamp is set to NATIVE_WINDOW_TIMESTAMP_AUTO
+ * (the default), timestamps will be generated automatically when queueBuffer is
+ * called. The timestamp is measured in nanoseconds, and is normally monotonically
+ * increasing. The timestamp should be unaffected by time-of-day adjustments,
+ * and for a camera should be strictly monotonic but for a media player may be
+ * reset when the position is set.
+ */
+int ANativeWindow_setBuffersTimestamp(ANativeWindow* window, int64_t timestamp);
+
+
+/*
+ * All buffers queued after this call will be associated with the dataSpace
+ * parameter specified.
+ *
+ * dataSpace specifies additional information about the buffer that's dependent
+ * on the buffer format and the endpoints. For example, it can be used to convey
+ * the color space of the image data in the buffer, or it can be used to
+ * indicate that the buffers contain depth measurement data instead of color
+ * images. The default dataSpace is 0, HAL_DATASPACE_UNKNOWN, unless it has been
+ * overridden by the consumer.
+ */
+int ANativeWindow_setBufferDataSpace(ANativeWindow* window, android_dataspace_t dataSpace);
+
+
+/*
+ * Enable/disable shared buffer mode
+ */
+int ANativeWindow_setSharedBufferMode(ANativeWindow* window, bool sharedBufferMode);
+
+
+/*
+ * Enable/disable auto refresh when in shared buffer mode
+ */
+int ANativeWindow_setAutoRefresh(ANativeWindow* window, bool autoRefresh);
+
+
+/*****************************************************************************/
+
+__END_DECLS
+
+#endif /* ANDROID_VNDK_NATIVEWINDOW_ANATIVEWINDOW_H */
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>
diff --git a/services/sensorservice/hidl/SensorManager.cpp b/services/sensorservice/hidl/SensorManager.cpp
index b55efb0..37e53dc 100644
--- a/services/sensorservice/hidl/SensorManager.cpp
+++ b/services/sensorservice/hidl/SensorManager.cpp
@@ -30,7 +30,6 @@
namespace V1_0 {
namespace implementation {
-using ::android::frameworks::sensorservice::V1_0::IDirectReportChannel;
using ::android::hardware::sensors::V1_0::SensorInfo;
using ::android::hardware::hidl_vec;
using ::android::hardware::Void;
@@ -112,6 +111,13 @@
return Void();
}
+Return<void> SensorManager::createEventQueue(
+ __unused const sp<IEventQueueCallback> &callback, createEventQueue_cb _hidl_cb) {
+ // TODO(b/35219747) Implement this
+ _hidl_cb(nullptr, Result::UNKNOWN_ERROR);
+ return Void();
+}
+
} // namespace implementation
} // namespace V1_0
} // namespace sensorservice
diff --git a/services/sensorservice/hidl/include/sensorservicehidl/SensorManager.h b/services/sensorservice/hidl/include/sensorservicehidl/SensorManager.h
index 484e624..0b026c9 100644
--- a/services/sensorservice/hidl/include/sensorservicehidl/SensorManager.h
+++ b/services/sensorservice/hidl/include/sensorservicehidl/SensorManager.h
@@ -43,7 +43,7 @@
Return<void> getDefaultSensor(SensorType type, getDefaultSensor_cb _hidl_cb) override;
Return<void> createAshmemDirectChannel(const hidl_memory& mem, uint64_t size, createAshmemDirectChannel_cb _hidl_cb) override;
Return<void> createGrallocDirectChannel(const hidl_handle& buffer, uint64_t size, createGrallocDirectChannel_cb _hidl_cb) override;
-
+ Return<void> createEventQueue(const sp<IEventQueueCallback> &callback, createEventQueue_cb _hidl_cb);
private:
::android::SensorManager& mManager;
diff --git a/services/surfaceflinger/DisplayHardware/ComposerHal.cpp b/services/surfaceflinger/DisplayHardware/ComposerHal.cpp
index c6e6dcb..d9bddb5 100644
--- a/services/surfaceflinger/DisplayHardware/ComposerHal.cpp
+++ b/services/surfaceflinger/DisplayHardware/ComposerHal.cpp
@@ -129,7 +129,7 @@
mIsUsingVrComposer(useVrComposer)
{
if (mIsUsingVrComposer) {
- mComposer = IComposer::getService("vr_hwcomposer");
+ mComposer = IComposer::getService("vr");
} else {
mComposer = IComposer::getService(); // use default name
}
diff --git a/services/vr/hardware_composer/vr_hardware_composer_service.cpp b/services/vr/hardware_composer/vr_hardware_composer_service.cpp
index 9591748..f980220 100644
--- a/services/vr/hardware_composer/vr_hardware_composer_service.cpp
+++ b/services/vr/hardware_composer/vr_hardware_composer_service.cpp
@@ -26,7 +26,7 @@
// Register the hwbinder HWC HAL service used by SurfaceFlinger while in VR
// mode.
- const char instance[] = "vr_hwcomposer";
+ const char instance[] = "vr";
android::sp<IComposer> service =
android::dvr::HIDL_FETCH_IComposer(instance);
diff --git a/services/vr/vr_window_manager/surface_flinger_view.cpp b/services/vr/vr_window_manager/surface_flinger_view.cpp
index 46eb880..427ad70 100644
--- a/services/vr/vr_window_manager/surface_flinger_view.cpp
+++ b/services/vr/vr_window_manager/surface_flinger_view.cpp
@@ -15,7 +15,7 @@
SurfaceFlingerView::~SurfaceFlingerView() {}
bool SurfaceFlingerView::Initialize(HwcCallback::Client *client) {
- const char vr_hwcomposer_name[] = "vr_hwcomposer";
+ const char vr_hwcomposer_name[] = "vr";
vr_hwcomposer_ = HIDL_FETCH_IComposer(vr_hwcomposer_name);
if (!vr_hwcomposer_.get()) {
ALOGE("Failed to get vr_hwcomposer");