Merge "Surface: Do not copy back if front and back buffer are identical"
diff --git a/cmds/atrace/atrace.cpp b/cmds/atrace/atrace.cpp
index 8d9442b..457d203 100644
--- a/cmds/atrace/atrace.cpp
+++ b/cmds/atrace/atrace.cpp
@@ -30,6 +30,7 @@
#include <unistd.h>
#include <zlib.h>
+#include <fstream>
#include <memory>
#include <binder/IBinder.h>
@@ -172,6 +173,7 @@
{ REQ, "events/vmscan/mm_vmscan_direct_reclaim_end/enable" },
{ REQ, "events/vmscan/mm_vmscan_kswapd_wake/enable" },
{ REQ, "events/vmscan/mm_vmscan_kswapd_sleep/enable" },
+ { REQ, "events/lowmemorykiller/enable" },
} },
{ "regulators", "Voltage and Current Regulators", 0, {
{ REQ, "events/regulator/enable" },
@@ -434,56 +436,31 @@
return writeStr(k_traceBufferSizePath, str);
}
-// Read the trace_clock sysfs file and return true if it matches the requested
-// value. The trace_clock file format is:
-// local [global] counter uptime perf
-static bool isTraceClock(const char *mode)
-{
- int fd = open((g_traceFolder + k_traceClockPath).c_str(), O_RDONLY);
- if (fd == -1) {
- fprintf(stderr, "error opening %s: %s (%d)\n", k_traceClockPath,
- strerror(errno), errno);
- return false;
- }
-
- char buf[4097];
- ssize_t n = read(fd, buf, 4096);
- close(fd);
- if (n == -1) {
- fprintf(stderr, "error reading %s: %s (%d)\n", k_traceClockPath,
- strerror(errno), errno);
- return false;
- }
- buf[n] = '\0';
-
- char *start = strchr(buf, '[');
- if (start == NULL) {
- return false;
- }
- start++;
-
- char *end = strchr(start, ']');
- if (end == NULL) {
- return false;
- }
- *end = '\0';
-
- return strcmp(mode, start) == 0;
-}
-
-// Enable or disable the kernel's use of the global clock. Disabling the global
-// clock will result in the kernel using a per-CPU local clock.
+// Set the clock to the best available option while tracing. Use 'boot' if it's
+// available; otherwise, use 'mono'. If neither are available use 'global'.
// Any write to the trace_clock sysfs file will reset the buffer, so only
// update it if the requested value is not the current value.
-static bool setGlobalClockEnable(bool enable)
+static bool setClock()
{
- const char *clock = enable ? "global" : "local";
+ std::ifstream clockFile((g_traceFolder + k_traceClockPath).c_str(), O_RDONLY);
+ std::string clockStr((std::istreambuf_iterator<char>(clockFile)),
+ std::istreambuf_iterator<char>());
- if (isTraceClock(clock)) {
- return true;
+ std::string newClock;
+ if (clockStr.find("boot") != std::string::npos) {
+ newClock = "boot";
+ } else if (clockStr.find("mono") != std::string::npos) {
+ newClock = "mono";
+ } else {
+ newClock = "global";
}
- return writeStr(k_traceClockPath, clock);
+ size_t begin = clockStr.find("[") + 1;
+ size_t end = clockStr.find("]");
+ if (newClock.compare(0, std::string::npos, clockStr, begin, end-begin) == 0) {
+ return true;
+ }
+ return writeStr(k_traceClockPath, newClock.c_str());
}
static bool setPrintTgidEnableIfPresent(bool enable)
@@ -776,7 +753,7 @@
ok &= setCategoriesEnableFromFile(g_categoriesFile);
ok &= setTraceOverwriteEnable(g_traceOverwrite);
ok &= setTraceBufferSizeKB(g_traceBufferSizeKB);
- ok &= setGlobalClockEnable(true);
+ ok &= setClock();
ok &= setPrintTgidEnableIfPresent(true);
ok &= setKernelTraceFuncs(g_kernelTraceFuncs);
@@ -848,7 +825,6 @@
// Set the options back to their defaults.
setTraceOverwriteEnable(true);
setTraceBufferSizeKB(1);
- setGlobalClockEnable(false);
setPrintTgidEnableIfPresent(false);
setKernelTraceFuncs(NULL);
}
diff --git a/cmds/atrace/atrace.rc b/cmds/atrace/atrace.rc
index cef41be..8201d7e 100644
--- a/cmds/atrace/atrace.rc
+++ b/cmds/atrace/atrace.rc
@@ -51,6 +51,8 @@
chown root shell /sys/kernel/tracing/events/binder/binder_locked/enable
chown root shell /sys/kernel/debug/tracing/events/binder/binder_unlock/enable
chown root shell /sys/kernel/tracing/events/binder/binder_unlock/enable
+ chown root shell /sys/kernel/debug/tracing/events/lowmemorykiller/enable
+ chown root shell /sys/kernel/tracing/events/lowmemorykiller/enable
chown root shell /sys/kernel/debug/tracing/tracing_on
chown root shell /sys/kernel/tracing/tracing_on
@@ -119,11 +121,18 @@
chmod 0664 /sys/kernel/tracing/events/i2c/smbus_result/enable
chmod 0664 /sys/kernel/debug/tracing/events/i2c/smbus_reply/enable
chmod 0664 /sys/kernel/tracing/events/i2c/smbus_reply/enable
+ chmod 0664 /sys/kernel/debug/tracing/events/lowmemorykiller/enable
+ chmod 0664 /sys/kernel/tracing/events/lowmemorykiller/enable
# Tracing disabled by default
write /sys/kernel/debug/tracing/tracing_on 0
write /sys/kernel/tracing/tracing_on 0
+ # Set the trace clock to boot; falling back to mono or boot
+ write /d/tracing/trace_clock global
+ write /d/tracing/trace_clock mono
+ write /d/tracing/trace_clock boot
+
# Allow only the shell group to read and truncate the kernel trace.
chown root shell /sys/kernel/debug/tracing/trace
chown root shell /sys/kernel/tracing/trace
diff --git a/cmds/installd/dexopt.cpp b/cmds/installd/dexopt.cpp
index 5a78d78..7419eb4 100644
--- a/cmds/installd/dexopt.cpp
+++ b/cmds/installd/dexopt.cpp
@@ -1763,10 +1763,20 @@
result = false;
continue;
}
+
+ // Delete oat/vdex/art files.
result = unlink_if_exists(oat_path) && result;
result = unlink_if_exists(create_vdex_filename(oat_path)) && result;
result = unlink_if_exists(create_image_filename(oat_path)) && result;
+ // Delete profiles.
+ std::string current_profile = create_current_profile_path(
+ multiuser_get_user_id(uid), dex_path, /*is_secondary*/true);
+ std::string reference_profile = create_reference_profile_path(
+ dex_path, /*is_secondary*/true);
+ result = unlink_if_exists(current_profile) && result;
+ result = unlink_if_exists(reference_profile) && result;
+
// Try removing the directories as well, they might be empty.
result = rmdir_if_empty(oat_isa_dir) && result;
result = rmdir_if_empty(oat_dir) && result;
diff --git a/libs/binder/Parcel.cpp b/libs/binder/Parcel.cpp
index 6fefb38..aec8f10 100644
--- a/libs/binder/Parcel.cpp
+++ b/libs/binder/Parcel.cpp
@@ -2547,16 +2547,8 @@
objectsSize = 0;
} else {
while (objectsSize > 0) {
- if (mObjects[objectsSize-1] < desired) {
- // Check for an object being sliced
- if (desired < mObjects[objectsSize-1] + sizeof(flat_binder_object)) {
- ALOGE("Attempt to shrink Parcel would slice an objects allocated memory");
- return UNKNOWN_ERROR + 0xBADF10;
- }
+ if (mObjects[objectsSize-1] < desired)
break;
- }
- // STOPSHIP: Above code to be replaced with following commented code:
- // if (mObjects[objectsSize-1] + sizeof(flat_binder_object) <= desired) break;
objectsSize--;
}
}
diff --git a/libs/math/tests/mat_test.cpp b/libs/math/tests/mat_test.cpp
index c365366..3217a1a 100644
--- a/libs/math/tests/mat_test.cpp
+++ b/libs/math/tests/mat_test.cpp
@@ -487,7 +487,7 @@
for (size_t i = 0; i < v1.size(); ++i) { \
EXPECT_FLOAT_EQ(v1[i], v2[i]); \
} \
- } else if (std::is_same<TypeParam,float>::value) { \
+ } else if (std::is_same<TypeParam,double>::value) { \
for (size_t i = 0; i < v1.size(); ++i) { \
EXPECT_DOUBLE_EQ(v1[i], v2[i]); \
} \
@@ -506,7 +506,7 @@
const decltype(T2) t2 = T2; \
if (std::is_same<TypeParam,float>::value) { \
ASSERT_FLOAT_EQ(t1, t2); \
- } else if (std::is_same<TypeParam,float>::value) { \
+ } else if (std::is_same<TypeParam,double>::value) { \
ASSERT_DOUBLE_EQ(t1, t2); \
} else { \
ASSERT_EQ(t1, t2); \
diff --git a/libs/vr/libbroadcastring/include/libbroadcastring/broadcast_ring.h b/libs/vr/libbroadcastring/include/libbroadcastring/broadcast_ring.h
index 236e3aa..f2e5034 100644
--- a/libs/vr/libbroadcastring/include/libbroadcastring/broadcast_ring.h
+++ b/libs/vr/libbroadcastring/include/libbroadcastring/broadcast_ring.h
@@ -174,8 +174,6 @@
//
// There must be at least |MemorySize(record_count)| bytes of space already
// allocated at |mmap|. The ring does not take ownership.
- //
- // Use this function for dynamically sized rings.
static BroadcastRing Create(void* mmap, size_t mmap_size,
uint32_t record_count) {
BroadcastRing ring(mmap);
@@ -188,12 +186,11 @@
//
// There must be at least |MemorySize()| bytes of space already allocated at
// |mmap|. The ring does not take ownership.
- //
- // Use this function for statically sized rings.
static BroadcastRing Create(void* mmap, size_t mmap_size) {
- static_assert(Traits::kUseStaticRecordCount,
- "Wrong Create() function called for dynamic record count");
- return Create(mmap, mmap_size, Traits::kStaticRecordCount);
+ return Create(mmap, mmap_size,
+ Traits::kUseStaticRecordCount
+ ? Traits::kStaticRecordCount
+ : BroadcastRing::GetRecordCount(mmap_size));
}
// Imports an existing ring at |mmap|.
@@ -233,6 +230,30 @@
return MemorySize(Traits::kStaticRecordCount);
}
+ static uint32_t NextPowerOf2(uint32_t n) {
+ if (n == 0)
+ return 0;
+ n -= 1;
+ n |= n >> 16;
+ n |= n >> 8;
+ n |= n >> 4;
+ n |= n >> 2;
+ n |= n >> 1;
+ return n + 1;
+ }
+
+ // Gets the biggest power of 2 record count that can fit into this mmap.
+ //
+ // The header size has been taken into account.
+ static uint32_t GetRecordCount(size_t mmap_size) {
+ if (mmap_size <= sizeof(Header)) {
+ return 0;
+ }
+ uint32_t count =
+ static_cast<uint32_t>((mmap_size - sizeof(Header)) / sizeof(Record));
+ return IsPowerOfTwo(count) ? count : (NextPowerOf2(count) / 2);
+ }
+
// Writes a record to the ring.
//
// The oldest record is overwritten unless the ring is not already full.
diff --git a/libs/vr/libbufferhub/include/private/dvr/bufferhub_rpc.h b/libs/vr/libbufferhub/include/private/dvr/bufferhub_rpc.h
index ffdc9e2..d79d96d 100644
--- a/libs/vr/libbufferhub/include/private/dvr/bufferhub_rpc.h
+++ b/libs/vr/libbufferhub/include/private/dvr/bufferhub_rpc.h
@@ -129,19 +129,102 @@
using LocalFence = FenceHandle<pdx::LocalHandle>;
using BorrowedFence = FenceHandle<pdx::BorrowedHandle>;
-struct QueueInfo {
+struct ProducerQueueConfig {
+ // Whether the buffer queue is operating in Async mode.
+ // From GVR's perspective of view, this means a buffer can be acquired
+ // asynchronously by the compositor.
+ // From Android Surface's perspective of view, this is equivalent to
+ // IGraphicBufferProducer's async mode. When in async mode, a producer
+ // will never block even if consumer is running slow.
+ bool is_async;
+
+ // Default buffer width that is set during ProducerQueue's creation.
+ uint32_t default_width;
+
+ // Default buffer height that is set during ProducerQueue's creation.
+ uint32_t default_height;
+
+ // Default buffer format that is set during ProducerQueue's creation.
+ uint32_t default_format;
+
+ // Size of the meta data associated with all the buffers allocated from the
+ // queue.
size_t meta_size_bytes;
+
+ private:
+ PDX_SERIALIZABLE_MEMBERS(ProducerQueueConfig, is_async, default_width,
+ default_height, default_format, meta_size_bytes);
+};
+
+class ProducerQueueConfigBuilder {
+ public:
+ // Build a ProducerQueueConfig object.
+ ProducerQueueConfig Build() {
+ return {is_async_, default_width_, default_height_, default_format_,
+ meta_size_bytes_};
+ }
+
+ ProducerQueueConfigBuilder& SetIsAsync(bool is_async) {
+ is_async_ = is_async;
+ return *this;
+ }
+
+ ProducerQueueConfigBuilder& SetDefaultWidth(uint32_t width) {
+ default_width_ = width;
+ return *this;
+ }
+
+ ProducerQueueConfigBuilder& SetDefaultHeight(uint32_t height) {
+ default_height_ = height;
+ return *this;
+ }
+
+ ProducerQueueConfigBuilder& SetDefaultFormat(uint32_t format) {
+ default_format_ = format;
+ return *this;
+ }
+
+ template <typename Meta>
+ ProducerQueueConfigBuilder& SetMetadata() {
+ meta_size_bytes_ = sizeof(Meta);
+ return *this;
+ }
+
+ ProducerQueueConfigBuilder& SetMetadataSize(size_t meta_size_bytes) {
+ meta_size_bytes_ = meta_size_bytes;
+ return *this;
+ }
+
+ private:
+ bool is_async_{false};
+ uint32_t default_width_{1};
+ uint32_t default_height_{1};
+ uint32_t default_format_{1}; // PIXEL_FORMAT_RGBA_8888
+ size_t meta_size_bytes_{0};
+};
+
+// Explicit specializations of ProducerQueueConfigBuilder::Build for void
+// metadata type.
+template <>
+inline ProducerQueueConfigBuilder&
+ProducerQueueConfigBuilder::SetMetadata<void>() {
+ meta_size_bytes_ = 0;
+ return *this;
+}
+
+struct QueueInfo {
+ ProducerQueueConfig producer_config;
int id;
private:
- PDX_SERIALIZABLE_MEMBERS(QueueInfo, meta_size_bytes, id);
+ PDX_SERIALIZABLE_MEMBERS(QueueInfo, producer_config, id);
};
struct UsagePolicy {
- uint64_t usage_set_mask;
- uint64_t usage_clear_mask;
- uint64_t usage_deny_set_mask;
- uint64_t usage_deny_clear_mask;
+ uint64_t usage_set_mask{0};
+ uint64_t usage_clear_mask{0};
+ uint64_t usage_deny_set_mask{0};
+ uint64_t usage_deny_clear_mask{0};
private:
PDX_SERIALIZABLE_MEMBERS(UsagePolicy, usage_set_mask, usage_clear_mask,
@@ -219,7 +302,7 @@
// Buffer Queue Methods.
PDX_REMOTE_METHOD(CreateProducerQueue, kOpCreateProducerQueue,
- QueueInfo(size_t meta_size_bytes,
+ QueueInfo(const ProducerQueueConfig& producer_config,
const UsagePolicy& usage_policy));
PDX_REMOTE_METHOD(CreateConsumerQueue, kOpCreateConsumerQueue,
LocalChannelHandle(Void));
diff --git a/libs/vr/libbufferhubqueue/buffer_hub_queue_client.cpp b/libs/vr/libbufferhubqueue/buffer_hub_queue_client.cpp
index 1978f41..e59bbb5 100644
--- a/libs/vr/libbufferhubqueue/buffer_hub_queue_client.cpp
+++ b/libs/vr/libbufferhubqueue/buffer_hub_queue_client.cpp
@@ -10,7 +10,6 @@
#include <pdx/default_transport/client_channel.h>
#include <pdx/default_transport/client_channel_factory.h>
#include <pdx/file_handle.h>
-#include <private/dvr/bufferhub_rpc.h>
#define RETRY_EINTR(fnc_call) \
([&]() -> decltype(fnc_call) { \
@@ -106,14 +105,18 @@
status.GetErrorMessage().c_str());
return ErrorStatus(status.error());
} else {
- SetupQueue(status.get().meta_size_bytes, status.get().id);
+ SetupQueue(status.get());
return {};
}
}
-void BufferHubQueue::SetupQueue(size_t meta_size_bytes, int id) {
- meta_size_ = meta_size_bytes;
- id_ = id;
+void BufferHubQueue::SetupQueue(const QueueInfo& queue_info) {
+ is_async_ = queue_info.producer_config.is_async;
+ default_width_ = queue_info.producer_config.default_width;
+ default_height_ = queue_info.producer_config.default_height;
+ default_format_ = queue_info.producer_config.default_format;
+ meta_size_ = queue_info.producer_config.meta_size_bytes;
+ id_ = queue_info.id;
}
std::unique_ptr<ConsumerQueue> BufferHubQueue::CreateConsumerQueue() {
@@ -396,9 +399,6 @@
return {std::move(buffer)};
}
-ProducerQueue::ProducerQueue(size_t meta_size)
- : ProducerQueue(meta_size, 0, 0, 0, 0) {}
-
ProducerQueue::ProducerQueue(LocalChannelHandle handle)
: BASE(std::move(handle)) {
auto status = ImportQueue();
@@ -409,14 +409,11 @@
}
}
-ProducerQueue::ProducerQueue(size_t meta_size, uint64_t usage_set_mask,
- uint64_t usage_clear_mask,
- uint64_t usage_deny_set_mask,
- uint64_t usage_deny_clear_mask)
+ProducerQueue::ProducerQueue(const ProducerQueueConfig& config,
+ const UsagePolicy& usage)
: BASE(BufferHubRPC::kClientPath) {
- auto status = InvokeRemoteMethod<BufferHubRPC::CreateProducerQueue>(
- meta_size, UsagePolicy{usage_set_mask, usage_clear_mask,
- usage_deny_set_mask, usage_deny_clear_mask});
+ auto status =
+ InvokeRemoteMethod<BufferHubRPC::CreateProducerQueue>(config, usage);
if (!status) {
ALOGE("ProducerQueue::ProducerQueue: Failed to create producer queue: %s",
status.GetErrorMessage().c_str());
@@ -424,7 +421,7 @@
return;
}
- SetupQueue(status.get().meta_size_bytes, status.get().id);
+ SetupQueue(status.get());
}
Status<void> ProducerQueue::AllocateBuffer(uint32_t width, uint32_t height,
diff --git a/libs/vr/libbufferhubqueue/buffer_hub_queue_producer.cpp b/libs/vr/libbufferhubqueue/buffer_hub_queue_producer.cpp
index 932aa37..4b3dd7a 100644
--- a/libs/vr/libbufferhubqueue/buffer_hub_queue_producer.cpp
+++ b/libs/vr/libbufferhubqueue/buffer_hub_queue_producer.cpp
@@ -11,7 +11,10 @@
/* static */
sp<BufferHubQueueProducer> BufferHubQueueProducer::Create() {
sp<BufferHubQueueProducer> producer = new BufferHubQueueProducer;
- producer->queue_ = ProducerQueue::Create<DvrNativeBufferMetadata>();
+ auto config = ProducerQueueConfigBuilder()
+ .SetMetadata<DvrNativeBufferMetadata>()
+ .Build();
+ producer->queue_ = ProducerQueue::Create(config, UsagePolicy{});
return producer;
}
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 d8d326b..e62e832 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
@@ -5,6 +5,7 @@
#include <pdx/client.h>
#include <pdx/status.h>
+#include <private/dvr/bufferhub_rpc.h>
#include <private/dvr/buffer_hub_client.h>
#include <private/dvr/epoll_file_descriptor.h>
#include <private/dvr/ring_buffer.h>
@@ -32,14 +33,17 @@
// participation in lifecycle events.
std::unique_ptr<ConsumerQueue> CreateSilentConsumerQueue();
+ // Returns whether the buffer queue is in async mode.
+ bool is_async() const { return is_async_; }
+
// Returns the default buffer width of this buffer queue.
- size_t default_width() const { return default_width_; }
+ uint32_t default_width() const { return default_width_; }
// Returns the default buffer height of this buffer queue.
- size_t default_height() const { return default_height_; }
+ uint32_t default_height() const { return default_height_; }
// Returns the default buffer format of this buffer queue.
- int32_t default_format() const { return default_format_; }
+ uint32_t default_format() const { return default_format_; }
// Creates a new consumer in handle form for immediate transport over RPC.
pdx::Status<pdx::LocalChannelHandle> CreateConsumerQueueHandle();
@@ -98,7 +102,7 @@
pdx::Status<void> ImportQueue();
// Sets up the queue with the given parameters.
- void SetupQueue(size_t meta_size_bytes_, int id);
+ void SetupQueue(const QueueInfo& queue_info);
// Register a buffer for management by the queue. Used by subclasses to add a
// buffer to internal bookkeeping.
@@ -181,17 +185,22 @@
return index == BufferHubQueue::kEpollQueueEventIndex;
}
- // Default buffer width that can be set to override the buffer width when a
- // width and height of 0 are specified in AllocateBuffer.
+ // Whether the buffer queue is operating in Async mode.
+ // From GVR's perspective of view, this means a buffer can be acquired
+ // asynchronously by the compositor.
+ // From Android Surface's perspective of view, this is equivalent to
+ // IGraphicBufferProducer's async mode. When in async mode, a producer
+ // will never block even if consumer is running slow.
+ bool is_async_{false};
+
+ // Default buffer width that is set during ProducerQueue's creation.
size_t default_width_{1};
- // Default buffer height that can be set to override the buffer height when a
- // width and height of 0 are specified in AllocateBuffer.
+ // Default buffer height that is set during ProducerQueue's creation.
size_t default_height_{1};
- // Default buffer format that can be set to override the buffer format when it
- // isn't specified in AllocateBuffer.
- int32_t default_format_{PIXEL_FORMAT_RGBA_8888};
+ // Default buffer format that is set during ProducerQueue's creation.
+ int32_t default_format_{1}; // PIXEL_FORMAT_RGBA_8888
// Tracks the buffers belonging to this queue. Buffers are stored according to
// "slot" in this vector. Each slot is a logical id of the buffer within this
@@ -222,14 +231,6 @@
class ProducerQueue : public pdx::ClientBase<ProducerQueue, BufferHubQueue> {
public:
- template <typename Meta>
- static std::unique_ptr<ProducerQueue> Create() {
- return BASE::Create(sizeof(Meta));
- }
- static std::unique_ptr<ProducerQueue> Create(size_t meta_size_bytes) {
- return BASE::Create(meta_size_bytes);
- }
-
// Usage bits in |usage_set_mask| will be automatically masked on. Usage bits
// in |usage_clear_mask| will be automatically masked off. Note that
// |usage_set_mask| and |usage_clear_mask| may conflict with each other, but
@@ -241,21 +242,9 @@
// this will be rejected. Note that |usage_deny_set_mask| and
// |usage_deny_clear_mask| shall not conflict with each other. Such
// configuration will be treated as invalid input on creation.
- template <typename Meta>
- static std::unique_ptr<ProducerQueue> Create(uint32_t usage_set_mask,
- uint32_t usage_clear_mask,
- uint32_t usage_deny_set_mask,
- uint32_t usage_deny_clear_mask) {
- return BASE::Create(sizeof(Meta), usage_set_mask, usage_clear_mask,
- usage_deny_set_mask, usage_deny_clear_mask);
- }
- static std::unique_ptr<ProducerQueue> Create(size_t meta_size_bytes,
- uint32_t usage_set_mask,
- uint32_t usage_clear_mask,
- uint32_t usage_deny_set_mask,
- uint32_t usage_deny_clear_mask) {
- return BASE::Create(meta_size_bytes, usage_set_mask, usage_clear_mask,
- usage_deny_set_mask, usage_deny_clear_mask);
+ static std::unique_ptr<ProducerQueue> Create(
+ const ProducerQueueConfig& config, const UsagePolicy& usage) {
+ return BASE::Create(config, usage);
}
// Import a ProducerQueue from a channel handle.
@@ -305,29 +294,13 @@
// Constructors are automatically exposed through ProducerQueue::Create(...)
// static template methods inherited from ClientBase, which take the same
// arguments as the constructors.
- explicit ProducerQueue(size_t meta_size);
explicit ProducerQueue(pdx::LocalChannelHandle handle);
- ProducerQueue(size_t meta_size, uint64_t usage_set_mask,
- uint64_t usage_clear_mask, uint64_t usage_deny_set_mask,
- uint64_t usage_deny_clear_mask);
+ ProducerQueue(const ProducerQueueConfig& config, const UsagePolicy& usage);
pdx::Status<Entry> OnBufferReady(
const std::shared_ptr<BufferHubBuffer>& buffer, size_t slot) override;
};
-// Explicit specializations of ProducerQueue::Create for void metadata type.
-template <>
-inline std::unique_ptr<ProducerQueue> ProducerQueue::Create<void>() {
- return ProducerQueue::Create(0);
-}
-template <>
-inline std::unique_ptr<ProducerQueue> ProducerQueue::Create<void>(
- uint32_t usage_set_mask, uint32_t usage_clear_mask,
- uint32_t usage_deny_set_mask, uint32_t usage_deny_clear_mask) {
- return ProducerQueue::Create(0, usage_set_mask, usage_clear_mask,
- usage_deny_set_mask, usage_deny_clear_mask);
-}
-
class ConsumerQueue : public BufferHubQueue {
public:
// Get a buffer consumer. Note that the method doesn't check whether the
diff --git a/libs/vr/libbufferhubqueue/tests/buffer_hub_queue-test.cpp b/libs/vr/libbufferhubqueue/tests/buffer_hub_queue-test.cpp
index ff2e146..064e3fd 100644
--- a/libs/vr/libbufferhubqueue/tests/buffer_hub_queue-test.cpp
+++ b/libs/vr/libbufferhubqueue/tests/buffer_hub_queue-test.cpp
@@ -16,22 +16,17 @@
namespace {
-constexpr int kBufferWidth = 100;
-constexpr int kBufferHeight = 1;
-constexpr int kBufferLayerCount = 1;
-constexpr int kBufferFormat = HAL_PIXEL_FORMAT_BLOB;
-constexpr int kBufferUsage = GRALLOC_USAGE_SW_READ_RARELY;
+constexpr uint32_t kBufferWidth = 100;
+constexpr uint32_t kBufferHeight = 1;
+constexpr uint32_t kBufferLayerCount = 1;
+constexpr uint32_t kBufferFormat = HAL_PIXEL_FORMAT_BLOB;
+constexpr uint64_t kBufferUsage = GRALLOC_USAGE_SW_READ_RARELY;
class BufferHubQueueTest : public ::testing::Test {
public:
- template <typename Meta>
- bool CreateProducerQueue(uint64_t usage_set_mask = 0,
- uint64_t usage_clear_mask = 0,
- uint64_t usage_deny_set_mask = 0,
- uint64_t usage_deny_clear_mask = 0) {
- producer_queue_ =
- ProducerQueue::Create<Meta>(usage_set_mask, usage_clear_mask,
- usage_deny_set_mask, usage_deny_clear_mask);
+ bool CreateProducerQueue(const ProducerQueueConfig& config,
+ const UsagePolicy& usage) {
+ producer_queue_ = ProducerQueue::Create(config, usage);
return producer_queue_ != nullptr;
}
@@ -44,14 +39,9 @@
}
}
- template <typename Meta>
- bool CreateQueues(int usage_set_mask = 0, int usage_clear_mask = 0,
- int usage_deny_set_mask = 0,
- int usage_deny_clear_mask = 0) {
- return CreateProducerQueue<Meta>(usage_set_mask, usage_clear_mask,
- usage_deny_set_mask,
- usage_deny_clear_mask) &&
- CreateConsumerQueue();
+ bool CreateQueues(const ProducerQueueConfig& config,
+ const UsagePolicy& usage) {
+ return CreateProducerQueue(config, usage) && CreateConsumerQueue();
}
void AllocateBuffer(size_t* slot_out = nullptr) {
@@ -67,6 +57,7 @@
}
protected:
+ ProducerQueueConfigBuilder config_builder_;
std::unique_ptr<ProducerQueue> producer_queue_;
std::unique_ptr<ConsumerQueue> consumer_queue_;
};
@@ -74,7 +65,8 @@
TEST_F(BufferHubQueueTest, TestDequeue) {
const size_t nb_dequeue_times = 16;
- ASSERT_TRUE(CreateQueues<size_t>());
+ ASSERT_TRUE(CreateQueues(config_builder_.SetMetadata<size_t>().Build(),
+ UsagePolicy{}));
// Allocate only one buffer.
AllocateBuffer();
@@ -104,7 +96,8 @@
size_t slot;
uint64_t seq;
- ASSERT_TRUE(CreateQueues<uint64_t>());
+ ASSERT_TRUE(CreateQueues(config_builder_.SetMetadata<uint64_t>().Build(),
+ UsagePolicy{}));
for (size_t i = 0; i < kBufferCount; i++) {
AllocateBuffer();
@@ -175,7 +168,7 @@
}
TEST_F(BufferHubQueueTest, TestDetach) {
- ASSERT_TRUE(CreateProducerQueue<void>());
+ ASSERT_TRUE(CreateProducerQueue(config_builder_.Build(), UsagePolicy{}));
// Allocate buffers.
const size_t kBufferCount = 4u;
@@ -278,7 +271,9 @@
}
TEST_F(BufferHubQueueTest, TestMultipleConsumers) {
- ASSERT_TRUE(CreateProducerQueue<void>());
+ // ProducerConfigureBuilder doesn't set Metadata{size}, which means there
+ // is no metadata associated with this BufferQueue's buffer.
+ ASSERT_TRUE(CreateProducerQueue(config_builder_.Build(), UsagePolicy{}));
// Allocate buffers.
const size_t kBufferCount = 4u;
@@ -356,7 +351,9 @@
};
TEST_F(BufferHubQueueTest, TestMetadata) {
- ASSERT_TRUE(CreateQueues<TestMetadata>());
+ ASSERT_TRUE(CreateQueues(config_builder_.SetMetadata<TestMetadata>().Build(),
+ UsagePolicy{}));
+
AllocateBuffer();
std::vector<TestMetadata> ms = {
@@ -382,7 +379,9 @@
}
TEST_F(BufferHubQueueTest, TestMetadataMismatch) {
- ASSERT_TRUE(CreateQueues<int64_t>());
+ ASSERT_TRUE(CreateQueues(config_builder_.SetMetadata<int64_t>().Build(),
+ UsagePolicy{}));
+
AllocateBuffer();
int64_t mi = 3;
@@ -401,7 +400,8 @@
}
TEST_F(BufferHubQueueTest, TestEnqueue) {
- ASSERT_TRUE(CreateQueues<int64_t>());
+ ASSERT_TRUE(CreateQueues(config_builder_.SetMetadata<int64_t>().Build(),
+ UsagePolicy{}));
AllocateBuffer();
size_t slot;
@@ -418,7 +418,8 @@
}
TEST_F(BufferHubQueueTest, TestAllocateBuffer) {
- ASSERT_TRUE(CreateQueues<int64_t>());
+ ASSERT_TRUE(CreateQueues(config_builder_.SetMetadata<int64_t>().Build(),
+ UsagePolicy{}));
size_t s1;
AllocateBuffer();
@@ -473,7 +474,8 @@
TEST_F(BufferHubQueueTest, TestUsageSetMask) {
const uint32_t set_mask = GRALLOC_USAGE_SW_WRITE_OFTEN;
- ASSERT_TRUE(CreateQueues<int64_t>(set_mask, 0, 0, 0));
+ ASSERT_TRUE(CreateQueues(config_builder_.SetMetadata<int64_t>().Build(),
+ UsagePolicy{set_mask, 0, 0, 0}));
// When allocation, leave out |set_mask| from usage bits on purpose.
size_t slot;
@@ -491,7 +493,8 @@
TEST_F(BufferHubQueueTest, TestUsageClearMask) {
const uint32_t clear_mask = GRALLOC_USAGE_SW_WRITE_OFTEN;
- ASSERT_TRUE(CreateQueues<int64_t>(0, clear_mask, 0, 0));
+ ASSERT_TRUE(CreateQueues(config_builder_.SetMetadata<int64_t>().Build(),
+ UsagePolicy{0, clear_mask, 0, 0}));
// When allocation, add |clear_mask| into usage bits on purpose.
size_t slot;
@@ -509,7 +512,8 @@
TEST_F(BufferHubQueueTest, TestUsageDenySetMask) {
const uint32_t deny_set_mask = GRALLOC_USAGE_SW_WRITE_OFTEN;
- ASSERT_TRUE(CreateQueues<int64_t>(0, 0, deny_set_mask, 0));
+ ASSERT_TRUE(CreateQueues(config_builder_.SetMetadata<int64_t>().Build(),
+ UsagePolicy{0, 0, deny_set_mask, 0}));
// Now that |deny_set_mask| is illegal, allocation without those bits should
// be able to succeed.
@@ -529,7 +533,8 @@
TEST_F(BufferHubQueueTest, TestUsageDenyClearMask) {
const uint32_t deny_clear_mask = GRALLOC_USAGE_SW_WRITE_OFTEN;
- ASSERT_TRUE(CreateQueues<int64_t>(0, 0, 0, deny_clear_mask));
+ ASSERT_TRUE(CreateQueues(config_builder_.SetMetadata<int64_t>().Build(),
+ UsagePolicy{0, 0, 0, deny_clear_mask}));
// Now that clearing |deny_clear_mask| is illegal (i.e. setting these bits are
// mandatory), allocation with those bits should be able to succeed.
@@ -547,6 +552,26 @@
ASSERT_EQ(EINVAL, status.error());
}
+TEST_F(BufferHubQueueTest, TestQueueInfo) {
+ static const bool kIsAsync = true;
+ ASSERT_TRUE(CreateQueues(config_builder_.SetIsAsync(kIsAsync)
+ .SetDefaultWidth(kBufferWidth)
+ .SetDefaultHeight(kBufferHeight)
+ .SetDefaultFormat(kBufferFormat)
+ .Build(),
+ UsagePolicy{}));
+
+ EXPECT_EQ(producer_queue_->default_width(), kBufferWidth);
+ EXPECT_EQ(producer_queue_->default_height(), kBufferHeight);
+ EXPECT_EQ(producer_queue_->default_format(), kBufferFormat);
+ EXPECT_EQ(producer_queue_->is_async(), kIsAsync);
+
+ EXPECT_EQ(consumer_queue_->default_width(), kBufferWidth);
+ EXPECT_EQ(consumer_queue_->default_height(), kBufferHeight);
+ EXPECT_EQ(consumer_queue_->default_format(), kBufferFormat);
+ EXPECT_EQ(consumer_queue_->is_async(), kIsAsync);
+}
+
} // namespace
} // namespace dvr
diff --git a/libs/vr/libdisplay/Android.bp b/libs/vr/libdisplay/Android.bp
index c0c7e2f..e3ab7fa 100644
--- a/libs/vr/libdisplay/Android.bp
+++ b/libs/vr/libdisplay/Android.bp
@@ -17,6 +17,7 @@
"display_manager_client.cpp",
"display_protocol.cpp",
"vsync_client.cpp",
+ "shared_buffer_helpers.cpp",
]
localIncludeFiles = [
@@ -39,7 +40,7 @@
"libdvrcommon",
"libbufferhubqueue",
"libbufferhub",
- "libvrsensor",
+ "libbroadcastring",
"libpdx_default_transport",
]
diff --git a/libs/vr/libdisplay/include/private/dvr/shared_buffer_helpers.h b/libs/vr/libdisplay/include/private/dvr/shared_buffer_helpers.h
new file mode 100644
index 0000000..249f410
--- /dev/null
+++ b/libs/vr/libdisplay/include/private/dvr/shared_buffer_helpers.h
@@ -0,0 +1,138 @@
+#ifndef ANDROID_DVR_SHARED_BUFFER_HELPERS_H_
+#define ANDROID_DVR_SHARED_BUFFER_HELPERS_H_
+
+#include <assert.h>
+#include <tuple>
+
+#include <libbroadcastring/broadcast_ring.h>
+#include <private/dvr/display_client.h>
+
+namespace android {
+namespace dvr {
+
+// The buffer usage type for mapped shared buffers.
+enum class CPUUsageMode { READ_OFTEN, READ_RARELY, WRITE_OFTEN, WRITE_RARELY };
+
+// Holds the memory for the mapped shared buffer. Unlocks and releases the
+// underlying IonBuffer in destructor.
+class CPUMappedBuffer {
+ public:
+ // This constructor will create a display client and get the buffer from it.
+ CPUMappedBuffer(DvrGlobalBufferKey key, CPUUsageMode mode);
+
+ // If you already have the IonBuffer, use this. It will take ownership.
+ CPUMappedBuffer(std::unique_ptr<IonBuffer> buffer, CPUUsageMode mode);
+
+ // Use this if you do not want to take ownership.
+ CPUMappedBuffer(IonBuffer* buffer, CPUUsageMode mode);
+
+ ~CPUMappedBuffer();
+
+ // Getters.
+ size_t Size() const { return size_; }
+ void* Address() const { return address_; }
+ bool IsMapped() const { return Address() != nullptr; }
+
+ // Attempt mapping this buffer to the CPU addressable space.
+ // This will create a display client and see if the buffer exists.
+ // If the buffer has not been setup yet, you will need to try again later.
+ void TryMapping();
+
+ protected:
+ // The memory area if we managed to map it.
+ size_t size_ = 0;
+ void* address_ = nullptr;
+
+ // If we are polling the display client, the buffer key here.
+ DvrGlobalBufferKey buffer_key_;
+
+ // If we just own the IonBuffer outright, it's here.
+ std::unique_ptr<IonBuffer> owned_buffer_ = nullptr;
+
+ // If we do not own the IonBuffer, it's here
+ IonBuffer* buffer_ = nullptr;
+
+ // The usage mode.
+ CPUUsageMode usage_mode_ = CPUUsageMode::READ_OFTEN;
+};
+
+// Represents a broadcast ring inside a mapped shared memory buffer.
+// If has the same set of constructors as CPUMappedBuffer.
+// The template argument is the concrete BroadcastRing class that this buffer
+// holds.
+template <class RingType>
+class CPUMappedBroadcastRing : public CPUMappedBuffer {
+ public:
+ CPUMappedBroadcastRing(DvrGlobalBufferKey key, CPUUsageMode mode)
+ : CPUMappedBuffer(key, mode) {}
+
+ CPUMappedBroadcastRing(std::unique_ptr<IonBuffer> buffer, CPUUsageMode mode)
+ : CPUMappedBuffer(std::move(buffer), mode) {}
+
+ CPUMappedBroadcastRing(IonBuffer* buffer, CPUUsageMode mode)
+ : CPUMappedBuffer(buffer, mode) {}
+
+ // Helper function for publishing records in the ring.
+ void Publish(const typename RingType::Record& record) {
+ assert((usage_mode_ == CPUUsageMode::WRITE_OFTEN) ||
+ (usage_mode_ == CPUUsageMode::WRITE_RARELY));
+
+ auto ring = Ring();
+ if (ring) {
+ ring->Put(record);
+ }
+ }
+
+ // Helper function for getting records from the ring.
+ // Returns true if we were able to retrieve the latest.
+ bool GetNewest(typename RingType::Record* record) {
+ assert((usage_mode_ == CPUUsageMode::READ_OFTEN) ||
+ (usage_mode_ == CPUUsageMode::READ_RARELY));
+
+ auto ring = Ring();
+ if (ring) {
+ return ring->GetNewest(&sequence_, record);
+ }
+
+ return false;
+ }
+
+ // Try obtaining the ring. If the named buffer has not been created yet, it
+ // will return nullptr.
+ RingType* Ring() {
+ if (IsMapped() == false) {
+ TryMapping();
+
+ if (IsMapped()) {
+ switch (usage_mode_) {
+ case CPUUsageMode::READ_OFTEN:
+ case CPUUsageMode::READ_RARELY: {
+ RingType ring;
+ bool import_ok;
+ std::tie(ring, import_ok) = RingType::Import(address_, size_);
+ if (import_ok) {
+ ring_ = std::make_unique<RingType>(ring);
+ }
+ } break;
+ case CPUUsageMode::WRITE_OFTEN:
+ case CPUUsageMode::WRITE_RARELY:
+ ring_ =
+ std::make_unique<RingType>(RingType::Create(address_, size_));
+ break;
+ }
+ }
+ }
+
+ return ring_.get();
+ }
+
+ protected:
+ std::unique_ptr<RingType> ring_ = nullptr;
+
+ uint32_t sequence_ = 0;
+};
+
+} // namespace dvr
+} // namespace android
+
+#endif // ANDROID_DVR_SHARED_BUFFER_HELPERS_H_
diff --git a/libs/vr/libdisplay/shared_buffer_helpers.cpp b/libs/vr/libdisplay/shared_buffer_helpers.cpp
new file mode 100644
index 0000000..00bad88
--- /dev/null
+++ b/libs/vr/libdisplay/shared_buffer_helpers.cpp
@@ -0,0 +1,84 @@
+#include <private/dvr/shared_buffer_helpers.h>
+
+namespace android {
+namespace dvr {
+
+CPUMappedBuffer::CPUMappedBuffer(DvrGlobalBufferKey key, CPUUsageMode mode)
+ : buffer_key_(key), usage_mode_(mode) {
+ TryMapping();
+}
+
+CPUMappedBuffer::CPUMappedBuffer(std::unique_ptr<IonBuffer> buffer,
+ CPUUsageMode mode)
+ : owned_buffer_(std::move(buffer)),
+ buffer_(owned_buffer_.get()),
+ usage_mode_(mode) {
+ TryMapping();
+}
+
+CPUMappedBuffer::CPUMappedBuffer(IonBuffer* buffer, CPUUsageMode mode)
+ : buffer_(buffer), usage_mode_(mode) {
+ TryMapping();
+}
+
+CPUMappedBuffer::~CPUMappedBuffer() {
+ if (IsMapped()) {
+ buffer_->Unlock();
+ }
+}
+
+void CPUMappedBuffer::TryMapping() {
+ // Do we have an IonBuffer for this shared memory object?
+ if (buffer_ == nullptr) {
+ // Create a display client and get the buffer.
+ // TODO(okana): We might want to throttle this.
+ auto display_client = display::DisplayClient::Create();
+ if (display_client) {
+ auto get_result = display_client->GetGlobalBuffer(buffer_key_);
+ if (get_result.ok()) {
+ owned_buffer_ = get_result.take();
+ buffer_ = owned_buffer_.get();
+ } else {
+ ALOGW("Could not get named buffer from pose service : %s(%d)",
+ get_result.GetErrorMessage().c_str(), get_result.error());
+ }
+ } else {
+ ALOGE("Unable to create display client for shared buffer access");
+ }
+ }
+
+ if (buffer_) {
+ auto usage = buffer_->usage() & ~GRALLOC_USAGE_SW_READ_MASK &
+ ~GRALLOC_USAGE_SW_WRITE_MASK;
+
+ // Figure out the usage bits.
+ switch (usage_mode_) {
+ case CPUUsageMode::READ_OFTEN:
+ usage |= GRALLOC_USAGE_SW_READ_OFTEN;
+ break;
+ case CPUUsageMode::READ_RARELY:
+ usage |= GRALLOC_USAGE_SW_READ_RARELY;
+ break;
+ case CPUUsageMode::WRITE_OFTEN:
+ usage |= GRALLOC_USAGE_SW_WRITE_OFTEN;
+ break;
+ case CPUUsageMode::WRITE_RARELY:
+ usage |= GRALLOC_USAGE_SW_WRITE_RARELY;
+ break;
+ }
+
+ int width = static_cast<int>(buffer_->width());
+ int height = 1;
+ const auto ret = buffer_->Lock(usage, 0, 0, width, height, &address_);
+
+ if (ret < 0 || !address_) {
+ ALOGE("Pose failed to map ring buffer: ret:%d, addr:%p", ret, address_);
+ buffer_->Unlock();
+ } else {
+ size_ = width;
+ }
+ }
+}
+
+} // namespace dvr
+} // namespace android
diff --git a/libs/vr/libdvr/Android.bp b/libs/vr/libdvr/Android.bp
index fa78b1c..2b4ebbe 100644
--- a/libs/vr/libdvr/Android.bp
+++ b/libs/vr/libdvr/Android.bp
@@ -34,10 +34,11 @@
]
static_libs = [
+ "libbroadcastring",
"libbufferhub",
"libbufferhubqueue",
- "libdisplay",
"libvrsensor",
+ "libdisplay",
"libvirtualtouchpadclient",
"libvr_hwc-impl",
"libvr_hwc-binder",
diff --git a/libs/vr/libdvr/build_sdk.py b/libs/vr/libdvr/build_sdk.py
new file mode 100755
index 0000000..b3c2e44
--- /dev/null
+++ b/libs/vr/libdvr/build_sdk.py
@@ -0,0 +1,47 @@
+#!/usr/bin/python
+import sys
+import os
+import argparse
+
+# Run this script to generate dvr_api.h in the current directory.
+
+def make_argument_parser():
+ parser = argparse.ArgumentParser(
+ description='Process DVR API headers into exportable SDK files.')
+ return parser
+
+parser = make_argument_parser()
+
+in_file = open("include/dvr/dvr_api.h", "r")
+out_file = open("./dvr_api.h", "w")
+
+h_filename = ""
+for line in in_file:
+ if line.startswith("// dvr_") and line.endswith(".h\n"):
+ h_filename = "include/dvr/" + line[3:].strip()
+ if line.startswith("typedef ") and "(*Dvr" in line:
+ start = line.find("(*Dvr") + 5
+ end = line.find("Ptr)")
+ if end != -1:
+ name = "dvr" + line[start:end]
+ # Find the comments for this function and insert into output.
+ with open(h_filename, 'r') as h_file:
+ h_lines = h_file.readlines()
+ i = 1
+ while i < len(h_lines):
+ if name in h_lines[i]:
+ end_i = i
+ while h_lines[i - 1].startswith("//"): i -= 1
+ while i < end_i:
+ out_file.write(h_lines[i])
+ i += 1
+ break
+ i += 1
+ if line.startswith('#include "dvr_api_entries.h"'):
+ with open("include/dvr/dvr_api_entries.h") as f:
+ out_file.write(f.read())
+ else:
+ out_file.write(line)
+
+in_file.close()
+out_file.close()
diff --git a/libs/vr/libdvr/include/dvr/dvr_api.h b/libs/vr/libdvr/include/dvr/dvr_api.h
index ef2c975..06f89da 100644
--- a/libs/vr/libdvr/include/dvr/dvr_api.h
+++ b/libs/vr/libdvr/include/dvr/dvr_api.h
@@ -18,7 +18,7 @@
typedef uint64_t DvrSurfaceUpdateFlags;
typedef struct DvrDisplayManager DvrDisplayManager;
typedef struct DvrSurfaceState DvrSurfaceState;
-typedef struct DvrPose DvrPose;
+typedef struct DvrPoseClient DvrPoseClient;
typedef struct DvrVSyncClient DvrVSyncClient;
typedef struct DvrVirtualTouchpad DvrVirtualTouchpad;
@@ -182,14 +182,15 @@
uint32_t* next_vsync_count);
// pose_client.h
-typedef DvrPose* (*DvrPoseCreatePtr)(void);
-typedef void (*DvrPoseDestroyPtr)(DvrPose* client);
-typedef int (*DvrPoseGetPtr)(DvrPose* client, uint32_t vsync_count,
- DvrPoseAsync* out_pose);
-typedef uint32_t (*DvrPoseGetVsyncCountPtr)(DvrPose* client);
-typedef int (*DvrPoseGetControllerPtr)(DvrPose* client, int32_t controller_id,
- uint32_t vsync_count,
- DvrPoseAsync* out_pose);
+typedef DvrPoseClient* (*DvrPoseClientCreatePtr)(void);
+typedef void (*DvrPoseClientDestroyPtr)(DvrPoseClient* client);
+typedef int (*DvrPoseClientGetPtr)(DvrPoseClient* client, uint32_t vsync_count,
+ DvrPoseAsync* out_pose);
+typedef uint32_t (*DvrPoseClientGetVsyncCountPtr)(DvrPoseClient* client);
+typedef int (*DvrPoseClientGetControllerPtr)(DvrPoseClient* client,
+ int32_t controller_id,
+ uint32_t vsync_count,
+ DvrPoseAsync* out_pose);
// virtual_touchpad_client.h
typedef DvrVirtualTouchpad* (*DvrVirtualTouchpadCreatePtr)(void);
diff --git a/libs/vr/libdvr/include/dvr/dvr_api_entries.h b/libs/vr/libdvr/include/dvr/dvr_api_entries.h
index 30d0a65..441df4f 100644
--- a/libs/vr/libdvr/include/dvr/dvr_api_entries.h
+++ b/libs/vr/libdvr/include/dvr/dvr_api_entries.h
@@ -89,11 +89,11 @@
DVR_V1_API_ENTRY(GetGlobalBuffer);
// Pose client
-DVR_V1_API_ENTRY(PoseCreate);
-DVR_V1_API_ENTRY(PoseDestroy);
-DVR_V1_API_ENTRY(PoseGet);
-DVR_V1_API_ENTRY(PoseGetVsyncCount);
-DVR_V1_API_ENTRY(PoseGetController);
+DVR_V1_API_ENTRY(PoseClientCreate);
+DVR_V1_API_ENTRY(PoseClientDestroy);
+DVR_V1_API_ENTRY(PoseClientGet);
+DVR_V1_API_ENTRY(PoseClientGetVsyncCount);
+DVR_V1_API_ENTRY(PoseClientGetController);
// Virtual touchpad client
DVR_V1_API_ENTRY(VirtualTouchpadCreate);
diff --git a/libs/vr/libdvr/include/dvr/dvr_pose.h b/libs/vr/libdvr/include/dvr/dvr_pose.h
new file mode 100644
index 0000000..a7e83c9
--- /dev/null
+++ b/libs/vr/libdvr/include/dvr/dvr_pose.h
@@ -0,0 +1,79 @@
+#ifndef ANDROID_DVR_PUBLIC_POSE_H_
+#define ANDROID_DVR_PUBLIC_POSE_H_
+
+#include <stdint.h>
+#include <sys/cdefs.h>
+
+__BEGIN_DECLS
+
+#ifdef __ARM_NEON
+#include <arm_neon.h>
+#else
+#ifndef __FLOAT32X4T_86
+#define __FLOAT32X4T_86
+typedef float float32x4_t __attribute__((__vector_size__(16)));
+#endif
+#endif
+
+// Represents an estimated pose, accessed asynchronously through a shared ring
+// buffer. No assumptions should be made about the data in padding space.
+// The size of this struct is 128 bytes.
+typedef struct __attribute__((packed, aligned(16))) DvrPoseAsync {
+ // Left eye head-from-start orientation quaternion x,y,z,w.
+ float32x4_t orientation;
+ // Left eye head-from-start position x,y,z,pad in meters.
+ float32x4_t position;
+ // Right eye head-from-start orientation quaternion x,y,z,w.
+ float32x4_t right_orientation;
+ // Right eye head-from-start position x,y,z,pad in meters.
+ float32x4_t right_position;
+ // Start-space angular velocity x,y,z,pad in radians per second.
+ float32x4_t angular_velocity;
+ // Start-space positional velocity x,y,z,pad in meters per second.
+ float32x4_t velocity;
+ // Timestamp of when this pose is predicted for, typically halfway through
+ // scanout.
+ int64_t timestamp_ns;
+ // Bitmask of DVR_POSE_FLAG_* constants that apply to this pose.
+ //
+ // If DVR_POSE_FLAG_VALID is not set, the pose is indeterminate.
+ uint64_t flags;
+ // Reserved padding to 128 bytes.
+ uint8_t pad[16];
+} DvrPoseAsync;
+
+enum {
+ DVR_POSE_FLAG_VALID = (1UL << 0), // This pose is valid.
+ DVR_POSE_FLAG_HEAD = (1UL << 1), // This pose is the head.
+ DVR_POSE_FLAG_CONTROLLER = (1UL << 2), // This pose is a controller.
+};
+
+// Represents a sensor pose sample.
+typedef struct __attribute__((packed, aligned(16))) DvrPose {
+ // Head-from-start orientation quaternion x,y,z,w.
+ float32x4_t orientation;
+
+ // The angular velocity where the x,y,z is the rotation axis and the
+ // magnitude is the radians / second in the same coordinate frame as
+ // orientation.
+ float32x4_t angular_velocity;
+
+ // Head-from-start position x,y,z,pad in meters.
+ float32x4_t position;
+
+ // In meters / second in the same coordinate frame as position.
+ float32x4_t velocity;
+
+ // In meters / second ^ 2 in the same coordinate frame as position.
+ float32x4_t acceleration;
+
+ // Timestamp for the measurement in nanoseconds.
+ int64_t timestamp_ns;
+
+ // Padding to 96 bytes so the size is a multiple of 16.
+ uint8_t padding[8];
+} DvrPose;
+
+__END_DECLS
+
+#endif // ANDROID_DVR_PUBLIC_POSE_H_
diff --git a/libs/vr/libdvr/include/dvr/dvr_shared_buffers.h b/libs/vr/libdvr/include/dvr/dvr_shared_buffers.h
new file mode 100644
index 0000000..ce17f0c
--- /dev/null
+++ b/libs/vr/libdvr/include/dvr/dvr_shared_buffers.h
@@ -0,0 +1,102 @@
+#ifndef ANDROID_DVR_SHARED_BUFFERS_H_
+#define ANDROID_DVR_SHARED_BUFFERS_H_
+
+#include <dvr/dvr_pose.h>
+#include <dvr/dvr_vrflinger_config.h>
+#include <dvr/dvr_vsync.h>
+#include <libbroadcastring/broadcast_ring.h>
+
+// This header is shared by VrCore and Android and must be kept in sync.
+namespace android {
+namespace dvr {
+
+// Increment when the layout for the buffers change.
+constexpr uint32_t kSharedBufferLayoutVersion = 1;
+
+// Note: These buffers will be mapped from various system processes as well
+// as VrCore and the application processes in a r/w manner.
+//
+// Therefore it is possible for the application to mess with the contents of
+// these buffers.
+//
+// While using them, assume garbage memory: Your logic must not crash or lead
+// to execution of unsafe code as a function of the contents of these buffers.
+
+// Sanity check for basic type sizes.
+static_assert(sizeof(DvrPoseAsync) == 128, "Unexpected size for DvrPoseAsync");
+static_assert(sizeof(DvrPose) == 96, "Unexpected size for DvrPose");
+static_assert(sizeof(DvrVsync) == 32, "Unexpected size for DvrVsync");
+
+// A helper class that provides compile time sized traits for the BroadcastRing.
+template <class DvrType, size_t StaticCount>
+class DvrRingBufferTraits {
+ public:
+ using Record = DvrType;
+ static constexpr bool kUseStaticRecordSize = false;
+ static constexpr uint32_t kStaticRecordCount = StaticCount;
+ static constexpr int kMaxReservedRecords = 1;
+ static constexpr int kMinAvailableRecords = 1;
+};
+
+// Traits classes.
+using DvrPoseTraits = DvrRingBufferTraits<DvrPose, 0>;
+using DvrVsyncTraits = DvrRingBufferTraits<DvrVsync, 2>;
+using DvrVrFlingerConfigTraits = DvrRingBufferTraits<DvrVrFlingerConfig, 2>;
+
+// The broadcast ring classes that will expose the data.
+using DvrPoseRing = BroadcastRing<DvrPose, DvrPoseTraits>;
+using DvrVsyncRing = BroadcastRing<DvrVsync, DvrVsyncTraits>;
+using DvrVrFlingerConfigRing =
+ BroadcastRing<DvrVrFlingerConfig, DvrVrFlingerConfigTraits>;
+
+// This is a shared memory buffer for passing pose data estimated at vsyncs.
+//
+// This will be primarily used for late latching and EDS where we bind this
+// buffer in a shader and extract the right vsync-predicted pose.
+struct __attribute__((packed, aligned(16))) DvrVsyncPoseBuffer {
+ enum : int {
+ // The number vsync predicted poses to keep in the ring buffer.
+ // Must be a power of 2.
+ kSize = 8,
+ kIndexMask = kSize - 1,
+
+ // The number of vsyncs (from the current vsync) we predict in vsync buffer.
+ // The other poses are left alone.
+ kMinFutureCount = 4
+ };
+
+ // The vsync predicted poses.
+ // The pose for the vsync n is:
+ // vsync_poses[n % kSize]
+ //
+ // This buffer is unsynchronized: It is possible to get torn reads as the
+ // sensor service updates the predictions as new sensor measurements come
+ // in. In particular, it is possible to get the position and an updated
+ // orientation while reading.
+ DvrPoseAsync vsync_poses[kSize];
+
+ // The latest sensor pose for GPU usage.
+ DvrPose current_pose;
+
+ // Current vsync_count (where sensord is writing poses from).
+ uint32_t vsync_count;
+
+ // For 16 byte alignment.
+ uint8_t padding[12];
+};
+
+static_assert(sizeof(DvrVsyncPoseBuffer) == 1136,
+ "Unexpected size for DvrVsyncPoseBuffer");
+
+// The keys for the dvr global buffers.
+enum DvrGlobalBuffers : int32_t {
+ kVsyncPoseBuffer = 1,
+ kVsyncBuffer = 2,
+ kSensorPoseBuffer = 3,
+ kVrFlingerConfigBufferKey = 4
+};
+
+} // namespace dvr
+} // namespace android
+
+#endif // ANDROID_DVR_SHARED_BUFFERS_H_
diff --git a/libs/vr/libdvr/include/dvr/dvr_vrflinger_config.h b/libs/vr/libdvr/include/dvr/dvr_vrflinger_config.h
new file mode 100644
index 0000000..cfe9d62
--- /dev/null
+++ b/libs/vr/libdvr/include/dvr/dvr_vrflinger_config.h
@@ -0,0 +1,30 @@
+#ifndef ANDROID_DVR_VRFLINGER_CONFIG_H
+#define ANDROID_DVR_VRFLINGER_CONFIG_H
+
+// This header is shared by VrCore and Android and must be kept in sync.
+
+#include <sys/cdefs.h>
+
+__BEGIN_DECLS
+
+// This is a shared memory buffer for passing config data from VrCore to
+// libvrflinger in SurfaceFlinger.
+struct DvrVrFlingerConfig {
+ // Offset before vsync to submit frames to hardware composer.
+ int frame_post_offset_ns{4000000};
+
+ // If the number of pending fences goes over this count at the point when we
+ // are about to submit a new frame to HWC, we will drop the frame. This
+ // should be a signal that the display driver has begun queuing frames. Note
+ // that with smart displays (with RAM), the fence is signaled earlier than
+ // the next vsync, at the point when the DMA to the display completes.
+ // Currently we use a smart display and the EDS timing coincides with zero
+ // pending fences, so this is 0.
+ size_t allowed_pending_fence_count{0};
+
+ // New fields should always be added to the end for backwards compat.
+};
+
+__END_DECLS
+
+#endif // ANDROID_DVR_VRFLINGER_CONFIG_H
diff --git a/libs/vr/libdvr/include/dvr/dvr_vrflinger_config_buffer.h b/libs/vr/libdvr/include/dvr/dvr_vrflinger_config_buffer.h
deleted file mode 100644
index 108c78b..0000000
--- a/libs/vr/libdvr/include/dvr/dvr_vrflinger_config_buffer.h
+++ /dev/null
@@ -1,51 +0,0 @@
-#ifndef ANDROID_DVR_VRFLINGER_CONFIG_BUFFER_H
-#define ANDROID_DVR_VRFLINGER_CONFIG_BUFFER_H
-
-#include <libbroadcastring/broadcast_ring.h>
-
-// This header is shared by VrCore and Android and must be kept in sync.
-
-namespace android {
-namespace dvr {
-
-// Increment when the layout for the buffers change.
-constexpr uint32_t kSharedConfigBufferLayoutVersion = 1;
-
-// This is a shared memory buffer for passing config data from VrCore to
-// libvrflinger in SurfaceFlinger.
-struct DvrVrFlingerConfigBuffer {
- // Offset before vsync to submit frames to hardware composer.
- int frame_post_offset_ns{4000000};
-
- // If the number of pending fences goes over this count at the point when we
- // are about to submit a new frame to HWC, we will drop the frame. This
- // should be a signal that the display driver has begun queuing frames. Note
- // that with smart displays (with RAM), the fence is signaled earlier than
- // the next vsync, at the point when the DMA to the display completes.
- // Currently we use a smart display and the EDS timing coincides with zero
- // pending fences, so this is 0.
- size_t allowed_pending_fence_count{0};
-
- // New fields should always be added to the end for backwards compat.
-};
-
-class DvrVrFlingerConfigBufferTraits {
- public:
- using Record = DvrVrFlingerConfigBuffer;
- static constexpr bool kUseStaticRecordSize = false;
- static constexpr uint32_t kStaticRecordCount = 2;
- static constexpr int kMaxReservedRecords = 1;
- static constexpr int kMinAvailableRecords = 1;
-};
-
-// The broadcast ring classes that will expose the data.
-using DvrVrFlingerConfigRing =
- BroadcastRing<DvrVrFlingerConfigBuffer, DvrVrFlingerConfigBufferTraits>;
-
-// Common buffers.
-constexpr int kVrFlingerConfigBufferKey = 5;
-
-} // namespace dvr
-} // namespace android
-
-#endif // ANDROID_DVR_VRFLINGER_CONFIG_BUFFER_H
diff --git a/libs/vr/libdvr/include/dvr/dvr_vsync.h b/libs/vr/libdvr/include/dvr/dvr_vsync.h
index 1eea3d9..87fdf31 100644
--- a/libs/vr/libdvr/include/dvr/dvr_vsync.h
+++ b/libs/vr/libdvr/include/dvr/dvr_vsync.h
@@ -8,6 +8,27 @@
typedef struct DvrVSyncClient DvrVSyncClient;
+// Represents a vsync sample. The size of this struct is 32 bytes.
+typedef struct __attribute__((packed, aligned(16))) DvrVsync {
+ // The timestamp for the last vsync in nanoseconds.
+ uint64_t vsync_timestamp_ns;
+
+ // The index of the last vsync.
+ uint32_t vsync_count;
+
+ // Scan out for the left eye = vsync_timestamp_ns + vsync_left_eye_offset_ns.
+ int32_t vsync_left_eye_offset_ns;
+
+ // Scan out for the right eye = vsync_timestamp_ns + vsync_right_eye_offset_ns
+ int32_t vsync_right_eye_offset_ns;
+
+ // The period of a vsync in nanoseconds.
+ uint32_t vsync_period_ns;
+
+ // Padding to 32 bytes so the size is a multiple of 16.
+ uint8_t padding[8];
+} DvrVsync;
+
// Creates a new client to the system vsync service.
int dvrVSyncClientCreate(DvrVSyncClient** client_out);
diff --git a/libs/vr/libdvr/tests/dvr_buffer_queue-test.cpp b/libs/vr/libdvr/tests/dvr_buffer_queue-test.cpp
index 5d12020..2426a49 100644
--- a/libs/vr/libdvr/tests/dvr_buffer_queue-test.cpp
+++ b/libs/vr/libdvr/tests/dvr_buffer_queue-test.cpp
@@ -25,8 +25,9 @@
class DvrBufferQueueTest : public ::testing::Test {
protected:
void SetUp() override {
+ auto config = ProducerQueueConfigBuilder().SetMetadata<TestMeta>().Build();
write_queue_ = CreateDvrWriteBufferQueueFromProducerQueue(
- ProducerQueue::Create<TestMeta>(0, 0, 0, 0));
+ ProducerQueue::Create(config, UsagePolicy{}));
ASSERT_NE(nullptr, write_queue_);
}
@@ -197,11 +198,13 @@
ASSERT_EQ(nullptr, window);
// A write queue with DvrNativeBufferMetadata should work fine.
+ auto config = ProducerQueueConfigBuilder()
+ .SetMetadata<DvrNativeBufferMetadata>()
+ .Build();
std::unique_ptr<DvrWriteBufferQueue, decltype(&dvrWriteBufferQueueDestroy)>
- write_queue(
- CreateDvrWriteBufferQueueFromProducerQueue(
- ProducerQueue::Create<DvrNativeBufferMetadata>(0, 0, 0, 0)),
- dvrWriteBufferQueueDestroy);
+ write_queue(CreateDvrWriteBufferQueueFromProducerQueue(
+ ProducerQueue::Create(config, UsagePolicy{})),
+ dvrWriteBufferQueueDestroy);
ASSERT_NE(nullptr, write_queue.get());
ret = dvrWriteBufferQueueGetExternalSurface(write_queue.get(), &window);
diff --git a/libs/vr/libdvr/tests/dvr_named_buffer-test.cpp b/libs/vr/libdvr/tests/dvr_named_buffer-test.cpp
index cf04588..419083f 100644
--- a/libs/vr/libdvr/tests/dvr_named_buffer-test.cpp
+++ b/libs/vr/libdvr/tests/dvr_named_buffer-test.cpp
@@ -1,8 +1,9 @@
#include <android/hardware_buffer.h>
#include <dvr/dvr_buffer.h>
#include <dvr/dvr_display_manager.h>
+#include <dvr/dvr_shared_buffers.h>
#include <dvr/dvr_surface.h>
-#include <dvr/dvr_vrflinger_config_buffer.h>
+#include <dvr/dvr_vrflinger_config.h>
#include <system/graphics.h>
#include <base/logging.h>
@@ -275,7 +276,8 @@
}
TEST_F(DvrGlobalBufferTest, TestVrflingerConfigBuffer) {
- const DvrGlobalBufferKey buffer_name = kVrFlingerConfigBufferKey;
+ const DvrGlobalBufferKey buffer_name =
+ DvrGlobalBuffers::kVrFlingerConfigBufferKey;
// First delete any existing buffer so we can test the failure case.
dvrDisplayManagerDeleteGlobalBuffer(client_, buffer_name);
diff --git a/libs/vr/libdvrcommon/Android.bp b/libs/vr/libdvrcommon/Android.bp
index 527cdbd..62aeb79 100644
--- a/libs/vr/libdvrcommon/Android.bp
+++ b/libs/vr/libdvrcommon/Android.bp
@@ -28,7 +28,7 @@
"libhardware",
]
-staticLibraries = ["libpdx_default_transport"]
+staticLibraries = ["libpdx_default_transport", "libbroadcastring"]
headerLibraries = [
"libeigen",
diff --git a/libs/vr/libvrflinger/Android.bp b/libs/vr/libvrflinger/Android.bp
index 080479a..0fb2d84 100644
--- a/libs/vr/libvrflinger/Android.bp
+++ b/libs/vr/libvrflinger/Android.bp
@@ -34,6 +34,7 @@
"libdvrcommon",
"libperformance",
"libvrsensor",
+ "libbroadcastring",
"libpdx_default_transport",
"libvr_manager",
"libbroadcastring",
diff --git a/libs/vr/libvrflinger/display_surface.cpp b/libs/vr/libvrflinger/display_surface.cpp
index fb2751b..babdc0e 100644
--- a/libs/vr/libvrflinger/display_surface.cpp
+++ b/libs/vr/libvrflinger/display_surface.cpp
@@ -207,7 +207,9 @@
surface_id(), meta_size_bytes);
std::lock_guard<std::mutex> autolock(lock_);
- auto producer = ProducerQueue::Create(meta_size_bytes);
+ auto config =
+ ProducerQueueConfigBuilder().SetMetadataSize(meta_size_bytes).Build();
+ auto producer = ProducerQueue::Create(config, UsagePolicy{});
if (!producer) {
ALOGE(
"ApplicationDisplaySurface::OnCreateQueue: Failed to create producer "
@@ -268,7 +270,12 @@
std::lock_guard<std::mutex> autolock(lock_);
if (!direct_queue_) {
- auto producer = ProducerQueue::Create(meta_size_bytes);
+ // Inject the hw composer usage flag to enable the display to read the
+ // buffers.
+ auto config =
+ ProducerQueueConfigBuilder().SetMetadataSize(meta_size_bytes).Build();
+ auto producer = ProducerQueue::Create(
+ config, UsagePolicy{GraphicBuffer::USAGE_HW_COMPOSER, 0, 0, 0});
if (!producer) {
ALOGE(
"DirectDisplaySurface::OnCreateQueue: Failed to create producer "
diff --git a/libs/vr/libvrflinger/hardware_composer.cpp b/libs/vr/libvrflinger/hardware_composer.cpp
index 88173ca..7a78d1f 100644
--- a/libs/vr/libvrflinger/hardware_composer.cpp
+++ b/libs/vr/libvrflinger/hardware_composer.cpp
@@ -25,7 +25,6 @@
#include <dvr/performance_client_api.h>
#include <private/dvr/clock_ns.h>
#include <private/dvr/ion_buffer.h>
-#include <private/dvr/pose_client_internal.h>
using android::pdx::LocalHandle;
using android::pdx::rpc::EmptyVariant;
@@ -211,10 +210,6 @@
void HardwareComposer::OnPostThreadResumed() {
hwc2_hidl_->resetCommands();
- // Connect to pose service.
- pose_client_ = dvrPoseCreate();
- ALOGE_IF(!pose_client_, "HardwareComposer: Failed to create pose client");
-
// HIDL HWC seems to have an internal race condition. If we submit a frame too
// soon after turning on VSync we don't get any VSync signals. Give poor HWC
// implementations a chance to enable VSync before we continue.
@@ -243,11 +238,6 @@
}
active_layer_count_ = 0;
- if (pose_client_) {
- dvrPoseDestroy(pose_client_);
- pose_client_ = nullptr;
- }
-
EnableVsync(false);
hwc2_hidl_->resetCommands();
@@ -467,7 +457,16 @@
int HardwareComposer::OnNewGlobalBuffer(DvrGlobalBufferKey key,
IonBuffer& ion_buffer) {
- if (key == kVrFlingerConfigBufferKey) {
+ if (key == DvrGlobalBuffers::kVsyncBuffer) {
+ vsync_ring_ = std::make_unique<CPUMappedBroadcastRing<DvrVsyncRing>>(
+ &ion_buffer, CPUUsageMode::WRITE_OFTEN);
+
+ if (vsync_ring_->IsMapped() == false) {
+ return -EPERM;
+ }
+ }
+
+ if (key == DvrGlobalBuffers::kVrFlingerConfigBufferKey) {
return MapConfigBuffer(ion_buffer);
}
@@ -475,7 +474,7 @@
}
void HardwareComposer::OnDeletedGlobalBuffer(DvrGlobalBufferKey key) {
- if (key == kVrFlingerConfigBufferKey) {
+ if (key == DvrGlobalBuffers::kVrFlingerConfigBufferKey) {
ConfigBufferDeleted();
}
}
@@ -515,7 +514,7 @@
if (!shared_config_ring_.is_valid())
return;
// Copy from latest record in shared_config_ring_ to local copy.
- DvrVrFlingerConfigBuffer record;
+ DvrVrFlingerConfig record;
if (shared_config_ring_.GetNewest(&shared_config_ring_sequence_, &record)) {
post_thread_config_ = record;
}
@@ -850,16 +849,20 @@
++vsync_count_;
- if (pose_client_) {
- // Signal the pose service with vsync info.
- // Display timestamp is in the middle of scanout.
- privateDvrPoseNotifyVsync(pose_client_, vsync_count_,
- vsync_timestamp + photon_offset_ns,
- ns_per_frame, right_eye_photon_offset_ns);
- }
-
const bool layer_config_changed = UpdateLayerConfig();
+ // Publish the vsync event.
+ if (vsync_ring_) {
+ DvrVsync vsync;
+ vsync.vsync_count = vsync_count_;
+ vsync.vsync_timestamp_ns = vsync_timestamp;
+ vsync.vsync_left_eye_offset_ns = photon_offset_ns;
+ vsync.vsync_right_eye_offset_ns = right_eye_photon_offset_ns;
+ vsync.vsync_period_ns = ns_per_frame;
+
+ vsync_ring_->Publish(vsync);
+ }
+
// Signal all of the vsync clients. Because absolute time is used for the
// wakeup time below, this can take a little time if necessary.
if (vsync_callback_)
diff --git a/libs/vr/libvrflinger/hardware_composer.h b/libs/vr/libvrflinger/hardware_composer.h
index c182bf9..de6f9ff 100644
--- a/libs/vr/libvrflinger/hardware_composer.h
+++ b/libs/vr/libvrflinger/hardware_composer.h
@@ -5,6 +5,7 @@
#include "DisplayHardware/ComposerHal.h"
#include "hwc_types.h"
+#include <dvr/dvr_shared_buffers.h>
#include <hardware/gralloc.h>
#include <log/log.h>
@@ -16,11 +17,12 @@
#include <tuple>
#include <vector>
-#include <dvr/dvr_vrflinger_config_buffer.h>
-#include <dvr/pose_client.h>
+#include <dvr/dvr_vrflinger_config.h>
+#include <dvr/dvr_vsync.h>
#include <pdx/file_handle.h>
#include <pdx/rpc/variant.h>
#include <private/dvr/buffer_hub_client.h>
+#include <private/dvr/shared_buffer_helpers.h>
#include "acquired_buffer.h"
#include "display_surface.h"
@@ -446,15 +448,14 @@
// us to detect when the display driver begins queuing frames.
std::vector<pdx::LocalHandle> retire_fence_fds_;
- // Pose client for frame count notifications. Pose client predicts poses
- // out to display frame boundaries, so we need to tell it about vsyncs.
- DvrPose* pose_client_ = nullptr;
+ // If we are publishing vsync data, we will put it here.
+ std::unique_ptr<CPUMappedBroadcastRing<DvrVsyncRing>> vsync_ring_;
// Broadcast ring for receiving config data from the DisplayManager.
DvrVrFlingerConfigRing shared_config_ring_;
uint32_t shared_config_ring_sequence_{0};
// Config buffer for reading from the post thread.
- DvrVrFlingerConfigBuffer post_thread_config_;
+ DvrVrFlingerConfig post_thread_config_;
std::mutex shared_config_mutex_;
static constexpr int kPostThreadInterrupted = 1;
diff --git a/libs/vr/libvrsensor/Android.bp b/libs/vr/libvrsensor/Android.bp
index abad78b..d022adf 100644
--- a/libs/vr/libvrsensor/Android.bp
+++ b/libs/vr/libvrsensor/Android.bp
@@ -23,9 +23,11 @@
]
staticLibraries = [
+ "libdisplay",
"libbufferhub",
"libbufferhubqueue",
"libdvrcommon",
+ "libbroadcastring",
"libpdx_default_transport",
]
@@ -43,6 +45,7 @@
export_include_dirs: includeFiles,
static_libs: staticLibraries,
shared_libs: sharedLibraries,
+ header_libs: ["libdvr_headers"],
name: "libvrsensor",
}
diff --git a/libs/vr/libvrsensor/include/dvr/pose_client.h b/libs/vr/libvrsensor/include/dvr/pose_client.h
index 6802fa9..d684ddc 100644
--- a/libs/vr/libvrsensor/include/dvr/pose_client.h
+++ b/libs/vr/libvrsensor/include/dvr/pose_client.h
@@ -14,63 +14,13 @@
#include <stdbool.h>
#include <stdint.h>
+#include <dvr/dvr_pose.h>
+
#ifdef __cplusplus
extern "C" {
#endif
-typedef struct DvrPose DvrPose;
-
-// Represents the current state provided by the pose service, containing a
-// rotation and translation.
-typedef struct __attribute__((packed, aligned(8))) DvrPoseState {
- // A quaternion representing the rotation of the HMD in Start Space.
- struct __attribute__((packed)) {
- float x, y, z, w;
- } head_from_start_rotation;
- // The position of the HMD in Start Space.
- struct __attribute__((packed)) {
- float x, y, z;
- } head_from_start_translation;
- // Time in nanoseconds for the current pose.
- uint64_t timestamp_ns;
- // The rotational velocity of the HMD.
- struct __attribute__((packed)) {
- float x, y, z;
- } sensor_from_start_rotation_velocity;
-} DvrPoseState;
-
-enum {
- DVR_POSE_FLAG_VALID = (1UL << 0), // This pose is valid.
- DVR_POSE_FLAG_HEAD = (1UL << 1), // This pose is the head.
- DVR_POSE_FLAG_CONTROLLER = (1UL << 2), // This pose is a controller.
-};
-
-// Represents an estimated pose, accessed asynchronously through a shared ring
-// buffer. No assumptions should be made about the data in padding space.
-// The size of this struct is 128 bytes.
-typedef struct __attribute__((packed, aligned(16))) DvrPoseAsync {
- // Left eye head-from-start orientation quaternion x,y,z,w.
- float32x4_t orientation;
- // Left eye head-from-start translation x,y,z,pad in meters.
- float32x4_t translation;
- // Right eye head-from-start orientation quaternion x,y,z,w.
- float32x4_t right_orientation;
- // Right eye head-from-start translation x,y,z,pad in meters.
- float32x4_t right_translation;
- // Start-space angular velocity x,y,z,pad in radians per second.
- float32x4_t angular_velocity;
- // Start-space positional velocity x,y,z,pad in meters per second.
- float32x4_t velocity;
- // Timestamp of when this pose is predicted for, typically halfway through
- // scanout.
- int64_t timestamp_ns;
- // Bitmask of DVR_POSE_FLAG_* constants that apply to this pose.
- //
- // If DVR_POSE_FLAG_VALID is not set, the pose is indeterminate.
- uint64_t flags;
- // Reserved padding to 128 bytes.
- uint8_t pad[16];
-} DvrPoseAsync;
+typedef struct DvrPoseClient DvrPoseClient;
// Returned by the async pose ring buffer access API.
typedef struct DvrPoseRingBufferInfo {
@@ -120,12 +70,12 @@
// Creates a new pose client.
//
// @return Pointer to the created pose client, nullptr on failure.
-DvrPose* dvrPoseCreate();
+DvrPoseClient* dvrPoseClientCreate();
// Destroys a pose client.
//
// @param client Pointer to the pose client to be destroyed.
-void dvrPoseDestroy(DvrPose* client);
+void dvrPoseClientDestroy(DvrPoseClient* client);
// Gets the pose for the given vsync count.
//
@@ -134,10 +84,11 @@
// Typically this is the count returned by dvrGetNextVsyncCount.
// @param out_pose Struct to store pose state.
// @return Zero on success, negative error code on failure.
-int dvrPoseGet(DvrPose* client, uint32_t vsync_count, DvrPoseAsync* out_pose);
+int dvrPoseClientGet(DvrPoseClient* client, uint32_t vsync_count,
+ DvrPoseAsync* out_pose);
// Gets the current vsync count.
-uint32_t dvrPoseGetVsyncCount(DvrPose* client);
+uint32_t dvrPoseClientGetVsyncCount(DvrPoseClient* client);
// Gets the pose for the given controller at the given vsync count.
//
@@ -147,15 +98,15 @@
// Typically this is the count returned by dvrGetNextVsyncCount.
// @param out_pose Struct to store pose state.
// @return Zero on success, negative error code on failure.
-int dvrPoseGetController(DvrPose* client, int32_t controller_id,
- uint32_t vsync_count, DvrPoseAsync* out_pose);
+int dvrPoseClientGetController(DvrPoseClient* client, int32_t controller_id,
+ uint32_t vsync_count, DvrPoseAsync* out_pose);
// Enables/disables logging for the controller fusion.
//
// @param client Pointer to the pose client.
// @param enable True starts logging, False stops.
// @return Zero on success, negative error code on failure.
-int dvrPoseLogController(DvrPose* client, bool enable);
+int dvrPoseClientLogController(DvrPoseClient* client, bool enable);
// DEPRECATED
// Polls current pose state.
@@ -163,30 +114,30 @@
// @param client Pointer to the pose client.
// @param state Struct to store polled state.
// @return Zero on success, negative error code on failure.
-int dvrPosePoll(DvrPose* client, DvrPoseState* state);
+int dvrPoseClientPoll(DvrPoseClient* client, DvrPose* state);
// Freezes the pose to the provided state.
//
// Future poll operations will return this state until a different state is
-// frozen or dvrPoseSetMode() is called with a different mode. The timestamp is
+// frozen or dvrPoseClientModeSet() is called with a different mode. The timestamp is
// not frozen.
//
// @param client Pointer to the pose client.
// @param frozen_state State pose to be frozen to.
// @return Zero on success, negative error code on failure.
-int dvrPoseFreeze(DvrPose* client, const DvrPoseState* frozen_state);
+int dvrPoseClientFreeze(DvrPoseClient* client, const DvrPose* frozen_state);
// Sets the pose service mode.
//
// @param mode The requested pose mode.
// @return Zero on success, negative error code on failure.
-int dvrPoseSetMode(DvrPose* client, DvrPoseMode mode);
+int dvrPoseClientModeSet(DvrPoseClient* client, DvrPoseMode mode);
// Gets the pose service mode.
//
// @param mode Return value for the current pose mode.
// @return Zero on success, negative error code on failure.
-int dvrPoseGetMode(DvrPose* client, DvrPoseMode* mode);
+int dvrPoseClientModeGet(DvrPoseClient* client, DvrPoseMode* mode);
// Get access to the shared memory pose ring buffer.
// A future pose at vsync <current> + <offset> is accessed at index:
@@ -197,8 +148,14 @@
// |out_fd| will be set to the gralloc buffer file descriptor, which is
// required for binding this buffer for GPU use.
// Returns 0 on success.
-int dvrPoseGetRingBuffer(DvrPose* client, DvrPoseRingBufferInfo* out_info);
+int dvrPoseClientGetRingBuffer(DvrPoseClient* client,
+ DvrPoseRingBufferInfo* out_info);
+// Sets enabled state for sensors pose processing.
+//
+// @param enabled Whether sensors are enabled or disabled.
+// @return Zero on success
+int dvrPoseClientSensorsEnable(DvrPoseClient* client, bool enabled);
#ifdef __cplusplus
} // extern "C"
diff --git a/libs/vr/libvrsensor/include/private/dvr/pose-ipc.h b/libs/vr/libvrsensor/include/private/dvr/pose-ipc.h
index 0616d46..e4455f1 100644
--- a/libs/vr/libvrsensor/include/private/dvr/pose-ipc.h
+++ b/libs/vr/libvrsensor/include/private/dvr/pose-ipc.h
@@ -11,14 +11,12 @@
#define DVR_POSE_SERVICE_CLIENT (DVR_POSE_SERVICE_BASE "/client")
enum {
- DVR_POSE_POLL = 0,
- DVR_POSE_FREEZE,
+ DVR_POSE_FREEZE = 0,
DVR_POSE_SET_MODE,
- DVR_POSE_GET_RING_BUFFER,
- DVR_POSE_NOTIFY_VSYNC,
DVR_POSE_GET_MODE,
DVR_POSE_GET_CONTROLLER_RING_BUFFER,
DVR_POSE_LOG_CONTROLLER,
+ DVR_POSE_SENSORS_ENABLE,
};
#ifdef __cplusplus
diff --git a/libs/vr/libvrsensor/include/private/dvr/pose_client_internal.h b/libs/vr/libvrsensor/include/private/dvr/pose_client_internal.h
deleted file mode 100644
index 66c4c7c..0000000
--- a/libs/vr/libvrsensor/include/private/dvr/pose_client_internal.h
+++ /dev/null
@@ -1,43 +0,0 @@
-#ifndef ANDROID_DVR_POSE_CLIENT_INTERNAL_H_
-#define ANDROID_DVR_POSE_CLIENT_INTERNAL_H_
-
-#include <stdint.h>
-
-#include <dvr/pose_client.h>
-#include <pdx/file_handle.h>
-#include <private/dvr/sensor_constants.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-// Sensord head pose ring buffer.
-typedef struct __attribute__((packed, aligned(16))) DvrPoseRingBuffer {
- // Ring buffer always at the beginning of the structure, as consumers may
- // not have access to this parent structure definition.
- DvrPoseAsync ring[kPoseAsyncBufferTotalCount];
- // Current vsync_count (where sensord is writing poses from).
- uint32_t vsync_count;
-} DvrPoseMetadata;
-
-// Called by displayd to give vsync count info to the pose service.
-// |display_timestamp| Display timestamp is in the middle of scanout.
-// |display_period_ns| Nanos between vsyncs.
-// |right_eye_photon_offset_ns| Nanos to shift the prediction timestamp for
-// the right eye head pose (relative to the left eye prediction).
-int privateDvrPoseNotifyVsync(DvrPose* client, uint32_t vsync_count,
- int64_t display_timestamp,
- int64_t display_period_ns,
- int64_t right_eye_photon_offset_ns);
-
-// Get file descriptor for access to the shared memory pose buffer. This can be
-// used with GL extensions that support shared memory buffer objects. The caller
-// takes ownership of the returned fd and must close it or pass on ownership.
-int privateDvrPoseGetRingBufferFd(DvrPose* client,
- android::pdx::LocalHandle* fd);
-
-#ifdef __cplusplus
-} // extern "C"
-#endif
-
-#endif // ANDROID_DVR_POSE_CLIENT_INTERNAL_H_
diff --git a/libs/vr/libvrsensor/include/private/dvr/sensor_constants.h b/libs/vr/libvrsensor/include/private/dvr/sensor_constants.h
deleted file mode 100644
index 8fa87b3..0000000
--- a/libs/vr/libvrsensor/include/private/dvr/sensor_constants.h
+++ /dev/null
@@ -1,23 +0,0 @@
-#ifndef ANDROID_DVR_SENSOR_CONSTANTS_H_
-#define ANDROID_DVR_SENSOR_CONSTANTS_H_
-
-namespace android {
-namespace dvr {
-
-// Number of elements in the async pose buffer.
-// Must be power of two.
-// Macro so that shader code can easily include this value.
-#define kPoseAsyncBufferTotalCount 8
-
-// Mask for accessing the current ring buffer array element:
-// index = vsync_count & kPoseAsyncBufferIndexMask
-constexpr uint32_t kPoseAsyncBufferIndexMask = kPoseAsyncBufferTotalCount - 1;
-
-// Number of pose frames including the current frame that are kept updated with
-// pose forecast data. The other poses are left their last known estimates.
-constexpr uint32_t kPoseAsyncBufferMinFutureCount = 4;
-
-} // namespace dvr
-} // namespace android
-
-#endif // ANDROID_DVR_SENSOR_CONSTANTS_H_
diff --git a/libs/vr/libvrsensor/pose_client.cpp b/libs/vr/libvrsensor/pose_client.cpp
index 9eae3aa..b21c7cf 100644
--- a/libs/vr/libvrsensor/pose_client.cpp
+++ b/libs/vr/libvrsensor/pose_client.cpp
@@ -1,4 +1,5 @@
#define LOG_TAG "PoseClient"
+#include <dvr/dvr_shared_buffers.h>
#include <dvr/pose_client.h>
#include <stdint.h>
@@ -8,9 +9,9 @@
#include <pdx/default_transport/client_channel_factory.h>
#include <pdx/file_handle.h>
#include <private/dvr/buffer_hub_client.h>
+#include <private/dvr/display_client.h>
#include <private/dvr/pose-ipc.h>
-#include <private/dvr/pose_client_internal.h>
-#include <private/dvr/sensor_constants.h>
+#include <private/dvr/shared_buffer_helpers.h>
using android::pdx::LocalHandle;
using android::pdx::LocalChannelHandle;
@@ -28,39 +29,44 @@
~PoseClient() override {}
// Casts C handle into an instance of this class.
- static PoseClient* FromC(DvrPose* client) {
+ static PoseClient* FromC(DvrPoseClient* client) {
return reinterpret_cast<PoseClient*>(client);
}
// Polls the pose service for the current state and stores it in *state.
// Returns zero on success, a negative error code otherwise.
- int Poll(DvrPoseState* state) {
- Transaction trans{*this};
- Status<int> status =
- trans.Send<int>(DVR_POSE_POLL, nullptr, 0, state, sizeof(*state));
- ALOGE_IF(!status, "Pose poll() failed because: %s\n",
- status.GetErrorMessage().c_str());
- return ReturnStatusOrError(status);
+ int Poll(DvrPose* state) {
+ const auto vsync_buffer = GetVsyncBuffer();
+ if (vsync_buffer) {
+ if (state) {
+ // Fill the state
+ *state = vsync_buffer->current_pose;
+ }
+ return -EINVAL;
+ }
+
+ return -EAGAIN;
}
int GetPose(uint32_t vsync_count, DvrPoseAsync* out_pose) {
- if (!mapped_pose_buffer_) {
- int ret = GetRingBuffer(nullptr);
- if (ret < 0)
- return ret;
+ const auto vsync_buffer = GetVsyncBuffer();
+ if (vsync_buffer) {
+ *out_pose =
+ vsync_buffer
+ ->vsync_poses[vsync_count & DvrVsyncPoseBuffer::kIndexMask];
+ return 0;
+ } else {
+ return -EAGAIN;
}
- *out_pose =
- mapped_pose_buffer_->ring[vsync_count & kPoseAsyncBufferIndexMask];
- return 0;
}
uint32_t GetVsyncCount() {
- if (!mapped_pose_buffer_) {
- int ret = GetRingBuffer(nullptr);
- if (ret < 0)
- return 0;
+ const auto vsync_buffer = GetVsyncBuffer();
+ if (vsync_buffer) {
+ return vsync_buffer->vsync_count;
}
- return mapped_pose_buffer_->vsync_count;
+
+ return 0;
}
int GetControllerPose(int32_t controller_id, uint32_t vsync_count,
@@ -75,7 +81,7 @@
}
*out_pose =
controllers_[controller_id]
- .mapped_pose_buffer[vsync_count & kPoseAsyncBufferIndexMask];
+ .mapped_pose_buffer[vsync_count & DvrVsyncPoseBuffer::kIndexMask];
return 0;
}
@@ -92,7 +98,7 @@
// this state until a different state is frozen or SetMode() is called with a
// different mode.
// Returns zero on success, a negative error code otherwise.
- int Freeze(const DvrPoseState& frozen_state) {
+ int Freeze(const DvrPose& frozen_state) {
Transaction trans{*this};
Status<int> status = trans.Send<int>(DVR_POSE_FREEZE, &frozen_state,
sizeof(frozen_state), nullptr, 0);
@@ -124,48 +130,29 @@
return ReturnStatusOrError(status);
}
- int GetRingBuffer(DvrPoseRingBufferInfo* out_info) {
- if (pose_buffer_.get()) {
- if (out_info) {
- GetPoseRingBufferInfo(out_info);
- }
- return 0;
- }
-
+ // Enables or disables all pose processing from sensors
+ int EnableSensors(bool enabled) {
Transaction trans{*this};
- Status<LocalChannelHandle> status =
- trans.Send<LocalChannelHandle>(DVR_POSE_GET_RING_BUFFER);
- if (!status) {
- ALOGE("Pose GetRingBuffer() failed because: %s",
- status.GetErrorMessage().c_str());
- return -status.error();
+ Status<int> status = trans.Send<int>(DVR_POSE_SENSORS_ENABLE, &enabled,
+ sizeof(enabled), nullptr, 0);
+ ALOGE_IF(!status, "Pose EnableSensors() failed because: %s\n",
+ status.GetErrorMessage().c_str());
+ return ReturnStatusOrError(status);
+ }
+
+ int GetRingBuffer(DvrPoseRingBufferInfo* out_info) {
+ // First time mapping the buffer?
+ const auto vsync_buffer = GetVsyncBuffer();
+ if (vsync_buffer) {
+ if (out_info) {
+ out_info->min_future_count = DvrVsyncPoseBuffer::kMinFutureCount;
+ out_info->total_count = DvrVsyncPoseBuffer::kSize;
+ out_info->buffer = vsync_buffer->vsync_poses;
+ }
+ return -EINVAL;
}
- auto buffer = BufferConsumer::Import(status.take());
- if (!buffer) {
- ALOGE("Pose failed to import ring buffer");
- return -EIO;
- }
- void* addr = nullptr;
- int ret = buffer->GetBlobReadOnlyPointer(sizeof(DvrPoseRingBuffer), &addr);
- if (ret < 0 || !addr) {
- ALOGE("Pose failed to map ring buffer: ret:%d, addr:%p", ret, addr);
- return -EIO;
- }
- pose_buffer_.swap(buffer);
- mapped_pose_buffer_ = static_cast<const DvrPoseRingBuffer*>(addr);
- ALOGI("Mapped pose data translation %f,%f,%f quat %f,%f,%f,%f",
- mapped_pose_buffer_->ring[0].translation[0],
- mapped_pose_buffer_->ring[0].translation[1],
- mapped_pose_buffer_->ring[0].translation[2],
- mapped_pose_buffer_->ring[0].orientation[0],
- mapped_pose_buffer_->ring[0].orientation[1],
- mapped_pose_buffer_->ring[0].orientation[2],
- mapped_pose_buffer_->ring[0].orientation[3]);
- if (out_info) {
- GetPoseRingBufferInfo(out_info);
- }
- return 0;
+ return -EAGAIN;
}
int GetControllerRingBuffer(int32_t controller_id) {
@@ -190,7 +177,7 @@
ALOGE("Pose failed to import ring buffer");
return -EIO;
}
- constexpr size_t size = kPoseAsyncBufferTotalCount * sizeof(DvrPoseAsync);
+ constexpr size_t size = DvrVsyncPoseBuffer::kSize * sizeof(DvrPoseAsync);
void* addr = nullptr;
int ret = buffer->GetBlobReadOnlyPointer(size, &addr);
if (ret < 0 || !addr) {
@@ -201,9 +188,9 @@
client_state.mapped_pose_buffer = static_cast<const DvrPoseAsync*>(addr);
ALOGI(
"Mapped controller %d pose data translation %f,%f,%f quat %f,%f,%f,%f",
- controller_id, client_state.mapped_pose_buffer[0].translation[0],
- client_state.mapped_pose_buffer[0].translation[1],
- client_state.mapped_pose_buffer[0].translation[2],
+ controller_id, client_state.mapped_pose_buffer[0].position[0],
+ client_state.mapped_pose_buffer[0].position[1],
+ client_state.mapped_pose_buffer[0].position[2],
client_state.mapped_pose_buffer[0].orientation[0],
client_state.mapped_pose_buffer[0].orientation[1],
client_state.mapped_pose_buffer[0].orientation[2],
@@ -211,32 +198,6 @@
return 0;
}
- int NotifyVsync(uint32_t vsync_count, int64_t display_timestamp,
- int64_t display_period_ns,
- int64_t right_eye_photon_offset_ns) {
- const struct iovec data[] = {
- {.iov_base = &vsync_count, .iov_len = sizeof(vsync_count)},
- {.iov_base = &display_timestamp, .iov_len = sizeof(display_timestamp)},
- {.iov_base = &display_period_ns, .iov_len = sizeof(display_period_ns)},
- {.iov_base = &right_eye_photon_offset_ns,
- .iov_len = sizeof(right_eye_photon_offset_ns)},
- };
- Transaction trans{*this};
- Status<int> status =
- trans.SendVector<int>(DVR_POSE_NOTIFY_VSYNC, data, nullptr);
- ALOGE_IF(!status, "Pose NotifyVsync() failed because: %s\n",
- status.GetErrorMessage().c_str());
- return ReturnStatusOrError(status);
- }
-
- int GetRingBufferFd(LocalHandle* fd) {
- int ret = GetRingBuffer(nullptr);
- if (ret < 0)
- return ret;
- *fd = pose_buffer_->GetBlobFd();
- return 0;
- }
-
private:
friend BASE;
@@ -252,14 +213,29 @@
PoseClient(const PoseClient&) = delete;
PoseClient& operator=(const PoseClient&) = delete;
- void GetPoseRingBufferInfo(DvrPoseRingBufferInfo* out_info) const {
- out_info->min_future_count = kPoseAsyncBufferMinFutureCount;
- out_info->total_count = kPoseAsyncBufferTotalCount;
- out_info->buffer = mapped_pose_buffer_->ring;
+ const DvrVsyncPoseBuffer* GetVsyncBuffer() {
+ if (mapped_vsync_pose_buffer_ == nullptr) {
+ if (vsync_pose_buffer_ == nullptr) {
+ // The constructor tries mapping it so we do not need TryMapping after.
+ vsync_pose_buffer_ = std::make_unique<CPUMappedBuffer>(
+ DvrGlobalBuffers::kVsyncPoseBuffer, CPUUsageMode::READ_OFTEN);
+ } else if (vsync_pose_buffer_->IsMapped() == false) {
+ vsync_pose_buffer_->TryMapping();
+ }
+
+ if (vsync_pose_buffer_->IsMapped()) {
+ mapped_vsync_pose_buffer_ =
+ static_cast<DvrVsyncPoseBuffer*>(vsync_pose_buffer_->Address());
+ }
+ }
+
+ return mapped_vsync_pose_buffer_;
}
- std::unique_ptr<BufferConsumer> pose_buffer_;
- const DvrPoseRingBuffer* mapped_pose_buffer_ = nullptr;
+ // The vsync pose buffer if already mapped.
+ std::unique_ptr<CPUMappedBuffer> vsync_pose_buffer_;
+
+ const DvrVsyncPoseBuffer* mapped_vsync_pose_buffer_ = nullptr;
struct ControllerClientState {
std::unique_ptr<BufferConsumer> pose_buffer;
@@ -273,66 +249,55 @@
using android::dvr::PoseClient;
-struct DvrPose {};
-
extern "C" {
-DvrPose* dvrPoseCreate() {
- PoseClient* client = PoseClient::Create().release();
- return reinterpret_cast<DvrPose*>(client);
+DvrPoseClient* dvrPoseClientCreate() {
+ auto* client = PoseClient::Create().release();
+ return reinterpret_cast<DvrPoseClient*>(client);
}
-void dvrPoseDestroy(DvrPose* client) { delete PoseClient::FromC(client); }
+void dvrPoseClientDestroy(DvrPoseClient* client) {
+ delete PoseClient::FromC(client);
+}
-int dvrPoseGet(DvrPose* client, uint32_t vsync_count, DvrPoseAsync* out_pose) {
+int dvrPoseClientGet(DvrPoseClient* client, uint32_t vsync_count,
+ DvrPoseAsync* out_pose) {
return PoseClient::FromC(client)->GetPose(vsync_count, out_pose);
}
-uint32_t dvrPoseGetVsyncCount(DvrPose* client) {
+uint32_t dvrPoseClientGetVsyncCount(DvrPoseClient* client) {
return PoseClient::FromC(client)->GetVsyncCount();
}
-int dvrPoseGetController(DvrPose* client, int32_t controller_id,
- uint32_t vsync_count, DvrPoseAsync* out_pose) {
+int dvrPoseClientGetController(DvrPoseClient* client, int32_t controller_id,
+ uint32_t vsync_count, DvrPoseAsync* out_pose) {
return PoseClient::FromC(client)->GetControllerPose(controller_id,
vsync_count, out_pose);
}
-int dvrPoseLogController(DvrPose* client, bool enable) {
+int dvrPoseClientLogController(DvrPoseClient* client, bool enable) {
return PoseClient::FromC(client)->LogController(enable);
}
-int dvrPosePoll(DvrPose* client, DvrPoseState* state) {
+int dvrPoseClientPoll(DvrPoseClient* client, DvrPose* state) {
return PoseClient::FromC(client)->Poll(state);
}
-int dvrPoseFreeze(DvrPose* client, const DvrPoseState* frozen_state) {
+int dvrPoseClientFreeze(DvrPoseClient* client, const DvrPose* frozen_state) {
return PoseClient::FromC(client)->Freeze(*frozen_state);
}
-int dvrPoseSetMode(DvrPose* client, DvrPoseMode mode) {
+int dvrPoseClientModeSet(DvrPoseClient* client, DvrPoseMode mode) {
return PoseClient::FromC(client)->SetMode(mode);
}
-int dvrPoseGetMode(DvrPose* client, DvrPoseMode* mode) {
+int dvrPoseClientModeGet(DvrPoseClient* client, DvrPoseMode* mode) {
return PoseClient::FromC(client)->GetMode(mode);
}
-int dvrPoseGetRingBuffer(DvrPose* client, DvrPoseRingBufferInfo* out_info) {
- return PoseClient::FromC(client)->GetRingBuffer(out_info);
-}
-int privateDvrPoseNotifyVsync(DvrPose* client, uint32_t vsync_count,
- int64_t display_timestamp,
- int64_t display_period_ns,
- int64_t right_eye_photon_offset_ns) {
- return PoseClient::FromC(client)->NotifyVsync(vsync_count, display_timestamp,
- display_period_ns,
- right_eye_photon_offset_ns);
-}
-
-int privateDvrPoseGetRingBufferFd(DvrPose* client, LocalHandle* fd) {
- return PoseClient::FromC(client)->GetRingBufferFd(fd);
+int dvrPoseClientSensorsEnable(DvrPoseClient* client, bool enabled) {
+ return PoseClient::FromC(client)->EnableSensors(enabled);
}
} // extern "C"
diff --git a/services/displayservice/DisplayEventReceiver.cpp b/services/displayservice/DisplayEventReceiver.cpp
index a7fd3c5..5993e44 100644
--- a/services/displayservice/DisplayEventReceiver.cpp
+++ b/services/displayservice/DisplayEventReceiver.cpp
@@ -13,6 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
+
#define LOG_TAG "libdisplayservicehidl"
#include <displayservice/DisplayEventReceiver.h>
@@ -43,12 +44,14 @@
return looper;
}
-DisplayEventReceiver::AttachedEvent::AttachedEvent(const sp<IEventCallback> &callback) : mCallback(callback) {
+DisplayEventReceiver::AttachedEvent::AttachedEvent(const sp<IEventCallback> &callback)
+ : mCallback(callback)
+{
mLooperAttached = getLooper()->addFd(mFwkReceiver.getFd(),
- Looper::POLL_CALLBACK,
- Looper::EVENT_INPUT,
- this,
- nullptr);
+ Looper::POLL_CALLBACK,
+ Looper::EVENT_INPUT,
+ this,
+ nullptr);
}
DisplayEventReceiver::AttachedEvent::~AttachedEvent() {
@@ -86,7 +89,7 @@
return 1; // keep the callback
}
- const static size_t SIZE = 1;
+ constexpr size_t SIZE = 1;
ssize_t n;
FwkReceiver::Event buf[SIZE];
@@ -149,11 +152,11 @@
}
Return<Status> DisplayEventReceiver::close() {
+ std::unique_lock<std::mutex> lock(mMutex);
if (mAttached == nullptr) {
return Status::BAD_VALUE;
}
- std::unique_lock<std::mutex> lock(mMutex);
bool success = mAttached->detach();
mAttached = nullptr;
diff --git a/services/displayservice/DisplayService.cpp b/services/displayservice/DisplayService.cpp
index 1699673..18418fd 100644
--- a/services/displayservice/DisplayService.cpp
+++ b/services/displayservice/DisplayService.cpp
@@ -1,3 +1,19 @@
+/*
+ * 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 <displayservice/DisplayService.h>
#include <displayservice/DisplayEventReceiver.h>
diff --git a/services/displayservice/include/displayservice/DisplayEventReceiver.h b/services/displayservice/include/displayservice/DisplayEventReceiver.h
index 83c0931..5d569b6 100644
--- a/services/displayservice/include/displayservice/DisplayEventReceiver.h
+++ b/services/displayservice/include/displayservice/DisplayEventReceiver.h
@@ -1,3 +1,19 @@
+/*
+ * 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_FRAMEWORKS_DISPLAYSERVICE_V1_0_DISPLAYEVENTRECEIVER_H
#define ANDROID_FRAMEWORKS_DISPLAYSERVICE_V1_0_DISPLAYEVENTRECEIVER_H
diff --git a/services/displayservice/include/displayservice/DisplayService.h b/services/displayservice/include/displayservice/DisplayService.h
index d92cb62..9722e71 100644
--- a/services/displayservice/include/displayservice/DisplayService.h
+++ b/services/displayservice/include/displayservice/DisplayService.h
@@ -1,3 +1,19 @@
+/*
+ * 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_FRAMEWORKS_DISPLAYSERVICE_V1_0_DISPLAYSERVICE_H
#define ANDROID_FRAMEWORKS_DISPLAYSERVICE_V1_0_DISPLAYSERVICE_H
diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp
index 0f93cd7..245e0ed 100755
--- a/services/surfaceflinger/Layer.cpp
+++ b/services/surfaceflinger/Layer.cpp
@@ -298,6 +298,11 @@
}
mSurfaceFlingerConsumer->abandon();
+
+#ifdef USE_HWC2
+ clearHwcLayers();
+#endif
+
for (const auto& child : mCurrentChildren) {
child->onRemoved();
}
diff --git a/services/vr/bufferhubd/buffer_hub.cpp b/services/vr/bufferhubd/buffer_hub.cpp
index d27f274..26843c9 100644
--- a/services/vr/bufferhubd/buffer_hub.cpp
+++ b/services/vr/bufferhubd/buffer_hub.cpp
@@ -382,7 +382,7 @@
}
Status<QueueInfo> BufferHubService::OnCreateProducerQueue(
- pdx::Message& message, size_t meta_size_bytes,
+ pdx::Message& message, const ProducerQueueConfig& producer_config,
const UsagePolicy& usage_policy) {
// Use the producer channel id as the global queue id.
const int queue_id = message.GetChannelId();
@@ -396,11 +396,11 @@
return ErrorStatus(EALREADY);
}
- auto status = ProducerQueueChannel::Create(this, queue_id, meta_size_bytes,
+ auto status = ProducerQueueChannel::Create(this, queue_id, producer_config,
usage_policy);
if (status) {
message.SetChannel(status.take());
- return {{meta_size_bytes, queue_id}};
+ return {{producer_config, queue_id}};
} else {
ALOGE("BufferHubService::OnCreateBuffer: Failed to create producer!!");
return status.error_status();
diff --git a/services/vr/bufferhubd/buffer_hub.h b/services/vr/bufferhubd/buffer_hub.h
index 3bc2635..b0df11f 100644
--- a/services/vr/bufferhubd/buffer_hub.h
+++ b/services/vr/bufferhubd/buffer_hub.h
@@ -166,9 +166,9 @@
size_t meta_size_bytes);
pdx::Status<void> OnGetPersistentBuffer(pdx::Message& message,
const std::string& name);
- pdx::Status<QueueInfo> OnCreateProducerQueue(pdx::Message& message,
- size_t meta_size_bytes,
- const UsagePolicy& usage_policy);
+ pdx::Status<QueueInfo> OnCreateProducerQueue(
+ pdx::Message& message, const ProducerQueueConfig& producer_config,
+ const UsagePolicy& usage_policy);
BufferHubService(const BufferHubService&) = delete;
void operator=(const BufferHubService&) = delete;
diff --git a/services/vr/bufferhubd/producer_queue_channel.cpp b/services/vr/bufferhubd/producer_queue_channel.cpp
index 886e621..605b8fb 100644
--- a/services/vr/bufferhubd/producer_queue_channel.cpp
+++ b/services/vr/bufferhubd/producer_queue_channel.cpp
@@ -16,11 +16,11 @@
ProducerQueueChannel::ProducerQueueChannel(BufferHubService* service,
int channel_id,
- size_t meta_size_bytes,
+ const ProducerQueueConfig& config,
const UsagePolicy& usage_policy,
int* error)
: BufferHubChannel(service, channel_id, channel_id, kProducerQueueType),
- meta_size_bytes_(meta_size_bytes),
+ config_(config),
usage_policy_(usage_policy),
capacity_(0) {
*error = 0;
@@ -35,8 +35,8 @@
/* static */
Status<std::shared_ptr<ProducerQueueChannel>> ProducerQueueChannel::Create(
- BufferHubService* service, int channel_id, size_t meta_size_bytes,
- const UsagePolicy& usage_policy) {
+ BufferHubService* service, int channel_id,
+ const ProducerQueueConfig& config, const UsagePolicy& usage_policy) {
// Configuration between |usage_deny_set_mask| and |usage_deny_clear_mask|
// should be mutually exclusive.
if ((usage_policy.usage_deny_set_mask & usage_policy.usage_deny_clear_mask)) {
@@ -50,7 +50,7 @@
int error = 0;
std::shared_ptr<ProducerQueueChannel> producer(new ProducerQueueChannel(
- service, channel_id, meta_size_bytes, usage_policy, &error));
+ service, channel_id, config, usage_policy, &error));
if (error < 0)
return ErrorStatus(-error);
else
@@ -134,7 +134,7 @@
}
Status<QueueInfo> ProducerQueueChannel::OnGetQueueInfo(Message&) {
- return {{meta_size_bytes_, buffer_id()}};
+ return {{config_, buffer_id()}};
}
Status<std::vector<std::pair<RemoteChannelHandle, size_t>>>
@@ -222,7 +222,7 @@
auto producer_channel_status =
ProducerChannel::Create(service(), buffer_id, width, height, layer_count,
- format, usage, meta_size_bytes_);
+ format, usage, config_.meta_size_bytes);
if (!producer_channel_status) {
ALOGE(
"ProducerQueueChannel::AllocateBuffer: Failed to create producer "
diff --git a/services/vr/bufferhubd/producer_queue_channel.h b/services/vr/bufferhubd/producer_queue_channel.h
index 28c74cd..212a90d 100644
--- a/services/vr/bufferhubd/producer_queue_channel.h
+++ b/services/vr/bufferhubd/producer_queue_channel.h
@@ -12,8 +12,8 @@
class ProducerQueueChannel : public BufferHubChannel {
public:
static pdx::Status<std::shared_ptr<ProducerQueueChannel>> Create(
- BufferHubService* service, int channel_id, size_t meta_size_bytes,
- const UsagePolicy& usage_policy);
+ BufferHubService* service, int channel_id,
+ const ProducerQueueConfig& config, const UsagePolicy& usage_policy);
~ProducerQueueChannel() override;
bool HandleMessage(pdx::Message& message) override;
@@ -48,8 +48,8 @@
private:
ProducerQueueChannel(BufferHubService* service, int channel_id,
- size_t meta_size_bytes, const UsagePolicy& usage_policy,
- int* error);
+ const ProducerQueueConfig& config,
+ const UsagePolicy& usage_policy, int* error);
// Allocate one single producer buffer by |OnProducerQueueAllocateBuffers|.
// Note that the newly created buffer's file handle will be pushed to client
@@ -60,10 +60,9 @@
pdx::Message& message, uint32_t width, uint32_t height,
uint32_t layer_count, uint32_t format, uint64_t usage);
- // Size of the meta data associated with all the buffers allocated from the
- // queue. Now we assume the metadata size is immutable once the queue is
- // created.
- size_t meta_size_bytes_;
+ // The producer queue's configuration. Now we assume the configuration is
+ // immutable once the queue is created.
+ ProducerQueueConfig config_;
// A set of variables to control what |usage| bits can this ProducerQueue
// allocate.
diff --git a/services/vr/hardware_composer/Android.bp b/services/vr/hardware_composer/Android.bp
index 5cb201d..9201520 100644
--- a/services/vr/hardware_composer/Android.bp
+++ b/services/vr/hardware_composer/Android.bp
@@ -7,6 +7,7 @@
],
static_libs: [
+ "libbroadcastring",
"libhwcomposer-client",
"libdisplay",
"libbufferhubqueue",
diff --git a/vulkan/api/vulkan.api b/vulkan/api/vulkan.api
index a19fcf1..3efc131 100644
--- a/vulkan/api/vulkan.api
+++ b/vulkan/api/vulkan.api
@@ -28,7 +28,7 @@
// API version (major.minor.patch)
define VERSION_MAJOR 1
define VERSION_MINOR 0
-define VERSION_PATCH 46
+define VERSION_PATCH 49
// API limits
define VK_MAX_PHYSICAL_DEVICE_NAME_SIZE 256
@@ -320,7 +320,7 @@
@extension("VK_KHR_shared_presentable_image") define VK_KHR_SHARED_PRESENTABLE_IMAGE_SPEC_VERSION 1
@extension("VK_KHR_shared_presentable_image") define VK_KHR_SHARED_PRESENTABLE_IMAGE_EXTENSION_NAME "VK_KHR_shared_presentable_image"
-// 119
+// 120
@extension("VK_KHR_get_surface_capabilities2") define VK_KHR_GET_SURFACE_CAPABILITIES_2_SPEC_VERSION 1
@extension("VK_KHR_get_surface_capabilities2") define VK_KHR_GET_SURFACE_CAPABILITIES_2_EXTENSION_NAME "VK_KHR_get_surface_capabilities2"
@@ -409,7 +409,7 @@
//@extension("VK_KHR_swapchain") // 2
VK_IMAGE_LAYOUT_PRESENT_SRC_KHR = 1000001002,
- //@extension("VK_KHR_shared_presentable_image")
+ //@extension("VK_KHR_shared_presentable_image") // 112
VK_IMAGE_LAYOUT_SHARED_PRESENT_KHR = 1000111000,
}
@@ -1005,9 +1005,6 @@
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_BUFFER_INFO_KHX = 1000071002,
VK_STRUCTURE_TYPE_EXTERNAL_BUFFER_PROPERTIES_KHX = 1000071003,
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ID_PROPERTIES_KHX = 1000071004,
- VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2_KHX = 1000071005,
- VK_STRUCTURE_TYPE_IMAGE_FORMAT_PROPERTIES_2_KHX = 1000071006,
- VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_FORMAT_INFO_2_KHX = 1000071007,
//@extension("VK_KHX_external_memory") // 73
VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_BUFFER_CREATE_INFO_KHX = 1000072000,
@@ -1086,10 +1083,10 @@
//@extension("VK_EXT_hdr_metadata") // 106
VK_STRUCTURE_TYPE_HDR_METADATA_EXT = 1000105000,
- //@extension("VK_KHR_shared_presentable_image") // 111
+ //@extension("VK_KHR_shared_presentable_image") // 112
VK_STRUCTURE_TYPE_SHARED_PRESENT_SURFACE_CAPABILITIES_KHR = 1000111000,
- //@extension("VK_KHR_get_surface_capabilities2") // 119
+ //@extension("VK_KHR_get_surface_capabilities2") // 120
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SURFACE_INFO_2_KHR = 1000119000,
VK_STRUCTURE_TYPE_SURFACE_CAPABILITIES_2_KHR = 1000119001,
VK_STRUCTURE_TYPE_SURFACE_FORMAT_2_KHR = 1000119002,
@@ -1179,6 +1176,55 @@
VK_DYNAMIC_STATE_DISCARD_RECTANGLE_EXT = 1000099000,
}
+enum VkObjectType {
+ VK_OBJECT_TYPE_UNKNOWN = 0,
+ VK_OBJECT_TYPE_INSTANCE = 1,
+ VK_OBJECT_TYPE_PHYSICAL_DEVICE = 2,
+ VK_OBJECT_TYPE_DEVICE = 3,
+ VK_OBJECT_TYPE_QUEUE = 4,
+ VK_OBJECT_TYPE_SEMAPHORE = 5,
+ VK_OBJECT_TYPE_COMMAND_BUFFER = 6,
+ VK_OBJECT_TYPE_FENCE = 7,
+ VK_OBJECT_TYPE_DEVICE_MEMORY = 8,
+ VK_OBJECT_TYPE_BUFFER = 9,
+ VK_OBJECT_TYPE_IMAGE = 10,
+ VK_OBJECT_TYPE_EVENT = 11,
+ VK_OBJECT_TYPE_QUERY_POOL = 12,
+ VK_OBJECT_TYPE_BUFFER_VIEW = 13,
+ VK_OBJECT_TYPE_IMAGE_VIEW = 14,
+ VK_OBJECT_TYPE_SHADER_MODULE = 15,
+ VK_OBJECT_TYPE_PIPELINE_CACHE = 16,
+ VK_OBJECT_TYPE_PIPELINE_LAYOUT = 17,
+ VK_OBJECT_TYPE_RENDER_PASS = 18,
+ VK_OBJECT_TYPE_PIPELINE = 19,
+ VK_OBJECT_TYPE_DESCRIPTOR_SET_LAYOUT = 20,
+ VK_OBJECT_TYPE_SAMPLER = 21,
+ VK_OBJECT_TYPE_DESCRIPTOR_POOL = 22,
+ VK_OBJECT_TYPE_DESCRIPTOR_SET = 23,
+ VK_OBJECT_TYPE_FRAMEBUFFER = 24,
+ VK_OBJECT_TYPE_COMMAND_POOL = 25,
+
+ //@extension("VK_KHR_surface") // 1
+ VK_OBJECT_TYPE_SURFACE_KHR = 1000000000,
+
+ //@extension("VK_KHR_swapchain") // 2
+ VK_OBJECT_TYPE_SWAPCHAIN_KHR = 1000001000,
+
+ //@extension("VK_KHR_display") // 3
+ VK_OBJECT_TYPE_DISPLAY_KHR = 1000002000,
+ VK_OBJECT_TYPE_DISPLAY_MODE_KHR = 1000002001,
+
+ //@extension("VK_KHR_debug_report") // 12
+ VK_OBJECT_TYPE_DEBUG_REPORT_CALLBACK_EXT = 1000011000,
+
+ //@extension("VK_KHR_descriptor_update_template") // 86
+ VK_OBJECT_TYPE_DESCRIPTOR_UPDATE_TEMPLATE_KHR = 1000085000,
+
+ //@extension("VK_NVX_device_generated_commands") // 87
+ VK_OBJECT_TYPE_OBJECT_TABLE_NVX = 1000086000,
+ VK_OBJECT_TYPE_INDIRECT_COMMANDS_LAYOUT_NVX = 1000086001,
+}
+
@extension("VK_KHR_surface") // 1
enum VkPresentModeKHR {
VK_PRESENT_MODE_IMMEDIATE_KHR = 0x00000000,
@@ -1186,7 +1232,7 @@
VK_PRESENT_MODE_FIFO_KHR = 0x00000002,
VK_PRESENT_MODE_FIFO_RELAXED_KHR = 0x00000003,
- //@extension("VK_KHR_shared_presentable_image")
+ //@extension("VK_KHR_shared_presentable_image") // 112
VK_PRESENT_MODE_SHARED_DEMAND_REFRESH_KHR = 1000111000,
VK_PRESENT_MODE_SHARED_CONTINUOUS_REFRESH_KHR = 1000111001,
}
@@ -4261,28 +4307,28 @@
f32 maxFrameAverageLightLevel
}
-@extension("VK_KHR_shared_presentable_image") // 111
+@extension("VK_KHR_shared_presentable_image") // 112
class VkSharedPresentSurfaceCapabilitiesKHR {
VkStructureType sType
const void* pNext
VkImageUsageFlags sharedPresentSupportedUsageFlags
}
-@extension("VK_KHR_get_surface_capabilities2") // 119
+@extension("VK_KHR_get_surface_capabilities2") // 120
class VkPhysicalDeviceSurfaceInfo2KHR {
VkStructureType sType
const void* pNext
VkSurfaceKHR surface
}
-@extension("VK_KHR_get_surface_capabilities2") // 119
+@extension("VK_KHR_get_surface_capabilities2") // 120
class VkSurfaceCapabilities2KHR {
VkStructureType sType
void* pNext
VkSurfaceCapabilitiesKHR surfaceCapabilities
}
-@extension("VK_KHR_get_surface_capabilities2") // 119
+@extension("VK_KHR_get_surface_capabilities2") // 120
class VkSurfaceFormat2KHR {
VkStructureType sType
void* pNext
@@ -7462,7 +7508,7 @@
return ?
}
-@extension("VK_KHR_get_surface_capabilities2") // 119
+@extension("VK_KHR_get_surface_capabilities2") // 120
cmd VkResult vkGetPhysicalDeviceSurfaceCapabilities2KHR(
VkPhysicalDevice physicalDevice,
const VkPhysicalDeviceSurfaceInfo2KHR* pSurfaceInfo,
@@ -7470,7 +7516,7 @@
return ?
}
-@extension("VK_KHR_get_surface_capabilities2") // 119
+@extension("VK_KHR_get_surface_capabilities2") // 120
cmd VkResult vkGetPhysicalDeviceSurfaceFormats2KHR(
VkPhysicalDevice physicalDevice,
const VkPhysicalDeviceSurfaceInfo2KHR* pSurfaceInfo,
diff --git a/vulkan/include/vulkan/vulkan.h b/vulkan/include/vulkan/vulkan.h
index 67eba86..ee30913 100644
--- a/vulkan/include/vulkan/vulkan.h
+++ b/vulkan/include/vulkan/vulkan.h
@@ -43,11 +43,11 @@
#define VK_VERSION_MINOR(version) (((uint32_t)(version) >> 12) & 0x3ff)
#define VK_VERSION_PATCH(version) ((uint32_t)(version) & 0xfff)
// Version of this file
-#define VK_HEADER_VERSION 46
+#define VK_HEADER_VERSION 49
#define VK_NULL_HANDLE 0
-
+
#define VK_DEFINE_HANDLE(object) typedef struct object##_T* object;
@@ -60,7 +60,7 @@
#define VK_DEFINE_NON_DISPATCHABLE_HANDLE(object) typedef uint64_t object;
#endif
#endif
-
+
typedef uint32_t VkFlags;
@@ -261,9 +261,6 @@
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_BUFFER_INFO_KHX = 1000071002,
VK_STRUCTURE_TYPE_EXTERNAL_BUFFER_PROPERTIES_KHX = 1000071003,
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ID_PROPERTIES_KHX = 1000071004,
- VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2_KHX = 1000071005,
- VK_STRUCTURE_TYPE_IMAGE_FORMAT_PROPERTIES_2_KHX = 1000071006,
- VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_FORMAT_INFO_2_KHX = 1000071007,
VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_BUFFER_CREATE_INFO_KHX = 1000072000,
VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_IMAGE_CREATE_INFO_KHX = 1000072001,
VK_STRUCTURE_TYPE_EXPORT_MEMORY_ALLOCATE_INFO_KHX = 1000072002,
@@ -901,6 +898,47 @@
VK_SUBPASS_CONTENTS_MAX_ENUM = 0x7FFFFFFF
} VkSubpassContents;
+typedef enum VkObjectType {
+ VK_OBJECT_TYPE_UNKNOWN = 0,
+ VK_OBJECT_TYPE_INSTANCE = 1,
+ VK_OBJECT_TYPE_PHYSICAL_DEVICE = 2,
+ VK_OBJECT_TYPE_DEVICE = 3,
+ VK_OBJECT_TYPE_QUEUE = 4,
+ VK_OBJECT_TYPE_SEMAPHORE = 5,
+ VK_OBJECT_TYPE_COMMAND_BUFFER = 6,
+ VK_OBJECT_TYPE_FENCE = 7,
+ VK_OBJECT_TYPE_DEVICE_MEMORY = 8,
+ VK_OBJECT_TYPE_BUFFER = 9,
+ VK_OBJECT_TYPE_IMAGE = 10,
+ VK_OBJECT_TYPE_EVENT = 11,
+ VK_OBJECT_TYPE_QUERY_POOL = 12,
+ VK_OBJECT_TYPE_BUFFER_VIEW = 13,
+ VK_OBJECT_TYPE_IMAGE_VIEW = 14,
+ VK_OBJECT_TYPE_SHADER_MODULE = 15,
+ VK_OBJECT_TYPE_PIPELINE_CACHE = 16,
+ VK_OBJECT_TYPE_PIPELINE_LAYOUT = 17,
+ VK_OBJECT_TYPE_RENDER_PASS = 18,
+ VK_OBJECT_TYPE_PIPELINE = 19,
+ VK_OBJECT_TYPE_DESCRIPTOR_SET_LAYOUT = 20,
+ VK_OBJECT_TYPE_SAMPLER = 21,
+ VK_OBJECT_TYPE_DESCRIPTOR_POOL = 22,
+ VK_OBJECT_TYPE_DESCRIPTOR_SET = 23,
+ VK_OBJECT_TYPE_FRAMEBUFFER = 24,
+ VK_OBJECT_TYPE_COMMAND_POOL = 25,
+ VK_OBJECT_TYPE_SURFACE_KHR = 1000000000,
+ VK_OBJECT_TYPE_SWAPCHAIN_KHR = 1000001000,
+ VK_OBJECT_TYPE_DISPLAY_KHR = 1000002000,
+ VK_OBJECT_TYPE_DISPLAY_MODE_KHR = 1000002001,
+ VK_OBJECT_TYPE_DEBUG_REPORT_CALLBACK_EXT = 1000011000,
+ VK_OBJECT_TYPE_DESCRIPTOR_UPDATE_TEMPLATE_KHR = 1000085000,
+ VK_OBJECT_TYPE_OBJECT_TABLE_NVX = 1000086000,
+ VK_OBJECT_TYPE_INDIRECT_COMMANDS_LAYOUT_NVX = 1000086001,
+ VK_OBJECT_TYPE_BEGIN_RANGE = VK_OBJECT_TYPE_UNKNOWN,
+ VK_OBJECT_TYPE_END_RANGE = VK_OBJECT_TYPE_COMMAND_POOL,
+ VK_OBJECT_TYPE_RANGE_SIZE = (VK_OBJECT_TYPE_COMMAND_POOL - VK_OBJECT_TYPE_UNKNOWN + 1),
+ VK_OBJECT_TYPE_MAX_ENUM = 0x7FFFFFFF
+} VkObjectType;
+
typedef VkFlags VkInstanceCreateFlags;
typedef enum VkFormatFeatureFlagBits {
@@ -4107,6 +4145,64 @@
const void* pData);
#endif
+#define VK_KHR_shared_presentable_image 1
+#define VK_KHR_SHARED_PRESENTABLE_IMAGE_SPEC_VERSION 1
+#define VK_KHR_SHARED_PRESENTABLE_IMAGE_EXTENSION_NAME "VK_KHR_shared_presentable_image"
+
+typedef struct VkSharedPresentSurfaceCapabilitiesKHR {
+ VkStructureType sType;
+ void* pNext;
+ VkImageUsageFlags sharedPresentSupportedUsageFlags;
+} VkSharedPresentSurfaceCapabilitiesKHR;
+
+
+typedef VkResult (VKAPI_PTR *PFN_vkGetSwapchainStatusKHR)(VkDevice device, VkSwapchainKHR swapchain);
+
+#ifndef VK_NO_PROTOTYPES
+VKAPI_ATTR VkResult VKAPI_CALL vkGetSwapchainStatusKHR(
+ VkDevice device,
+ VkSwapchainKHR swapchain);
+#endif
+
+#define VK_KHR_get_surface_capabilities2 1
+#define VK_KHR_GET_SURFACE_CAPABILITIES_2_SPEC_VERSION 1
+#define VK_KHR_GET_SURFACE_CAPABILITIES_2_EXTENSION_NAME "VK_KHR_get_surface_capabilities2"
+
+typedef struct VkPhysicalDeviceSurfaceInfo2KHR {
+ VkStructureType sType;
+ const void* pNext;
+ VkSurfaceKHR surface;
+} VkPhysicalDeviceSurfaceInfo2KHR;
+
+typedef struct VkSurfaceCapabilities2KHR {
+ VkStructureType sType;
+ void* pNext;
+ VkSurfaceCapabilitiesKHR surfaceCapabilities;
+} VkSurfaceCapabilities2KHR;
+
+typedef struct VkSurfaceFormat2KHR {
+ VkStructureType sType;
+ void* pNext;
+ VkSurfaceFormatKHR surfaceFormat;
+} VkSurfaceFormat2KHR;
+
+
+typedef VkResult (VKAPI_PTR *PFN_vkGetPhysicalDeviceSurfaceCapabilities2KHR)(VkPhysicalDevice physicalDevice, const VkPhysicalDeviceSurfaceInfo2KHR* pSurfaceInfo, VkSurfaceCapabilities2KHR* pSurfaceCapabilities);
+typedef VkResult (VKAPI_PTR *PFN_vkGetPhysicalDeviceSurfaceFormats2KHR)(VkPhysicalDevice physicalDevice, const VkPhysicalDeviceSurfaceInfo2KHR* pSurfaceInfo, uint32_t* pSurfaceFormatCount, VkSurfaceFormat2KHR* pSurfaceFormats);
+
+#ifndef VK_NO_PROTOTYPES
+VKAPI_ATTR VkResult VKAPI_CALL vkGetPhysicalDeviceSurfaceCapabilities2KHR(
+ VkPhysicalDevice physicalDevice,
+ const VkPhysicalDeviceSurfaceInfo2KHR* pSurfaceInfo,
+ VkSurfaceCapabilities2KHR* pSurfaceCapabilities);
+
+VKAPI_ATTR VkResult VKAPI_CALL vkGetPhysicalDeviceSurfaceFormats2KHR(
+ VkPhysicalDevice physicalDevice,
+ const VkPhysicalDeviceSurfaceInfo2KHR* pSurfaceInfo,
+ uint32_t* pSurfaceFormatCount,
+ VkSurfaceFormat2KHR* pSurfaceFormats);
+#endif
+
#define VK_EXT_debug_report 1
VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkDebugReportCallbackEXT)
@@ -5770,66 +5866,6 @@
const VkHdrMetadataEXT* pMetadata);
#endif
-#define VK_KHR_shared_presentable_image 1
-#define VK_KHR_SHARED_PRESENTABLE_IMAGE_SPEC_VERSION 1
-#define VK_KHR_SHARED_PRESENTABLE_IMAGE_EXTENSION_NAME "VK_KHR_shared_presentable_image"
-
-typedef struct VkSharedPresentSurfaceCapabilitiesKHR {
- VkStructureType sType;
- void* pNext;
- VkImageUsageFlags sharedPresentSupportedUsageFlags;
-} VkSharedPresentSurfaceCapabilitiesKHR;
-
-
-typedef VkResult (VKAPI_PTR *PFN_vkGetSwapchainStatusKHR)(VkDevice device, VkSwapchainKHR swapchain);
-
-#ifndef VK_NO_PROTOTYPES
-VKAPI_ATTR VkResult VKAPI_CALL vkGetSwapchainStatusKHR(
- VkDevice device,
- VkSwapchainKHR swapchain);
-#endif
-
-#define VK_KHR_get_surface_capabilities2 1
-#define VK_KHR_GET_SURFACE_CAPABILITIES_2_SPEC_VERSION 1
-#define VK_KHR_GET_SURFACE_CAPABILITIES_2_EXTENSION_NAME "VK_KHR_get_surface_capabilities2"
-
-typedef struct VkPhysicalDeviceSurfaceInfo2KHR {
- VkStructureType sType;
- const void* pNext;
- VkSurfaceKHR surface;
-} VkPhysicalDeviceSurfaceInfo2KHR;
-
-typedef struct VkSurfaceCapabilities2KHR {
- VkStructureType sType;
- void* pNext;
- VkSurfaceCapabilitiesKHR surfaceCapabilities;
-} VkSurfaceCapabilities2KHR;
-
-typedef struct VkSurfaceFormat2KHR {
- VkStructureType sType;
- void* pNext;
- VkSurfaceFormatKHR surfaceFormat;
-} VkSurfaceFormat2KHR;
-
-
-typedef VkResult (VKAPI_PTR *PFN_vkGetPhysicalDeviceSurfaceCapabilities2KHR)(VkPhysicalDevice physicalDevice, const VkPhysicalDeviceSurfaceInfo2KHR* pSurfaceInfo, VkSurfaceCapabilities2KHR* pSurfaceCapabilities);
-typedef VkResult (VKAPI_PTR *PFN_vkGetPhysicalDeviceSurfaceFormats2KHR)(VkPhysicalDevice physicalDevice, const VkPhysicalDeviceSurfaceInfo2KHR* pSurfaceInfo, uint32_t* pSurfaceFormatCount, VkSurfaceFormat2KHR* pSurfaceFormats);
-
-#ifndef VK_NO_PROTOTYPES
-VKAPI_ATTR VkResult VKAPI_CALL vkGetPhysicalDeviceSurfaceCapabilities2KHR(
- VkPhysicalDevice physicalDevice,
- const VkPhysicalDeviceSurfaceInfo2KHR* pSurfaceInfo,
- VkSurfaceCapabilities2KHR* pSurfaceCapabilities);
-
-VKAPI_ATTR VkResult VKAPI_CALL vkGetPhysicalDeviceSurfaceFormats2KHR(
- VkPhysicalDevice physicalDevice,
- const VkPhysicalDeviceSurfaceInfo2KHR* pSurfaceInfo,
- uint32_t* pSurfaceFormatCount,
- VkSurfaceFormat2KHR* pSurfaceFormats);
-#endif
-
-
-
#ifdef VK_USE_PLATFORM_IOS_MVK
#define VK_MVK_ios_surface 1
#define VK_MVK_IOS_SURFACE_SPEC_VERSION 2