dvrapi: Pass layer_count down
* We were missing layer count, which would prevent multiview
from working
Bug: 37245304
Test: MultiLayerBufferQueue
Change-Id: I88b41f1aa7665df01e89a7386cbc23b15c9a79b0
diff --git a/libs/vr/libbufferhub/buffer_hub_client.cpp b/libs/vr/libbufferhub/buffer_hub_client.cpp
index 0326084..a09a7a1 100644
--- a/libs/vr/libbufferhub/buffer_hub_client.cpp
+++ b/libs/vr/libbufferhub/buffer_hub_client.cpp
@@ -59,10 +59,8 @@
ALOGE("BufferHubBuffer::ImportBuffer: Failed to get buffer: %s",
status.GetErrorMessage().c_str());
return -status.error();
- } else if (status.get().id() >= 0) {
- ALOGE(
- "BufferHubBuffer::ImportBuffer: Expected to receive a buffer handle "
- "but got null!");
+ } else if (status.get().id() < 0) {
+ ALOGE("BufferHubBuffer::ImportBuffer: Received an invalid id!");
return -EIO;
}
diff --git a/libs/vr/libbufferhub/include/private/dvr/bufferhub_rpc.h b/libs/vr/libbufferhub/include/private/dvr/bufferhub_rpc.h
index 6fee7a0..ffdc9e2 100644
--- a/libs/vr/libbufferhub/include/private/dvr/bufferhub_rpc.h
+++ b/libs/vr/libbufferhub/include/private/dvr/bufferhub_rpc.h
@@ -23,6 +23,7 @@
stride_(buffer.stride()),
width_(buffer.width()),
height_(buffer.height()),
+ layer_count_(buffer.layer_count()),
format_(buffer.format()),
usage_(buffer.usage()) {
// Populate the fd and int vectors: native_handle->data[] is an array of fds
@@ -47,9 +48,10 @@
for (const auto& fd : fds_)
fd_ints.push_back(fd.Get());
- const int ret = buffer->Import(fd_ints.data(), fd_ints.size(),
- opaque_ints_.data(), opaque_ints_.size(),
- width_, height_, stride_, format_, usage_);
+ const int ret =
+ buffer->Import(fd_ints.data(), fd_ints.size(), opaque_ints_.data(),
+ opaque_ints_.size(), width_, height_, layer_count_,
+ stride_, format_, usage_);
if (ret < 0)
return ret;
@@ -72,6 +74,7 @@
uint32_t stride_;
uint32_t width_;
uint32_t height_;
+ uint32_t layer_count_;
uint32_t format_;
uint64_t usage_;
std::vector<int> opaque_ints_;
@@ -83,8 +86,8 @@
}
PDX_SERIALIZABLE_MEMBERS(NativeBufferHandle<FileHandleType>, id_, stride_,
- width_, height_, format_, usage_, opaque_ints_,
- fds_);
+ width_, height_, layer_count_, format_, usage_,
+ opaque_ints_, fds_);
NativeBufferHandle(const NativeBufferHandle&) = delete;
void operator=(const NativeBufferHandle&) = delete;
@@ -224,8 +227,8 @@
PDX_REMOTE_METHOD(ProducerQueueAllocateBuffers,
kOpProducerQueueAllocateBuffers,
std::vector<std::pair<LocalChannelHandle, size_t>>(
- uint32_t width, uint32_t height, uint32_t format,
- uint64_t usage, size_t buffer_count));
+ uint32_t width, uint32_t height, uint32_t layer_count,
+ uint32_t format, uint64_t usage, size_t buffer_count));
PDX_REMOTE_METHOD(ProducerQueueDetachBuffer, kOpProducerQueueDetachBuffer,
void(size_t slot));
PDX_REMOTE_METHOD(ConsumerQueueImportBuffers, kOpConsumerQueueImportBuffers,
diff --git a/libs/vr/libbufferhub/include/private/dvr/ion_buffer.h b/libs/vr/libbufferhub/include/private/dvr/ion_buffer.h
index 72c8d81..0d337f7 100644
--- a/libs/vr/libbufferhub/include/private/dvr/ion_buffer.h
+++ b/libs/vr/libbufferhub/include/private/dvr/ion_buffer.h
@@ -16,8 +16,8 @@
IonBuffer(buffer_handle_t handle, uint32_t width, uint32_t height,
uint32_t stride, uint32_t format, uint64_t usage);
IonBuffer(buffer_handle_t handle, uint32_t width, uint32_t height,
- uint32_t layer_count, uint32_t stride, uint32_t layer_stride,
- uint32_t format, uint64_t usage);
+ uint32_t layer_count, uint32_t stride, uint32_t format,
+ uint64_t usage);
~IonBuffer();
IonBuffer(IonBuffer&& other);
@@ -31,25 +31,29 @@
// previous native handle if necessary. Returns 0 on success or a negative
// errno code otherwise. If allocation fails the previous native handle is
// left intact.
- int Alloc(uint32_t width, uint32_t height, uint32_t format, uint64_t usage);
+ int Alloc(uint32_t width, uint32_t height, uint32_t layer_count,
+ uint32_t format, uint64_t usage);
// Resets the underlying native handle and parameters, freeing the previous
// native handle if necessary.
void Reset(buffer_handle_t handle, uint32_t width, uint32_t height,
- uint32_t stride, uint32_t format, uint64_t usage);
+ uint32_t layer_count, uint32_t stride, uint32_t format,
+ uint64_t usage);
// Like Reset but also registers the native handle, which is necessary for
// native handles received over IPC. Returns 0 on success or a negative errno
// code otherwise. If import fails the previous native handle is left intact.
int Import(buffer_handle_t handle, uint32_t width, uint32_t height,
- uint32_t stride, uint32_t format, uint64_t usage);
+ uint32_t layer_count, uint32_t stride, uint32_t format,
+ uint64_t usage);
// Like Reset but imports a native handle from raw fd and int arrays. Returns
// 0 on success or a negative errno code otherwise. If import fails the
// previous native handle is left intact.
int Import(const int* fd_array, int fd_count, const int* int_array,
- int int_count, uint32_t width, uint32_t height, uint32_t stride,
- uint32_t format, uint64_t usage);
+ int int_count, uint32_t width, uint32_t height,
+ uint32_t layer_count, uint32_t stride, uint32_t format,
+ uint64_t usage);
// Duplicates the native handle underlying |other| and then imports it. This
// is useful for creating multiple, independent views of the same Ion/Gralloc
@@ -72,7 +76,6 @@
return buffer_.get() ? buffer_->getLayerCount() : 0;
}
uint32_t stride() const { return buffer_.get() ? buffer_->getStride() : 0; }
- uint32_t layer_stride() const { return 0; }
uint32_t format() const {
return buffer_.get() ? buffer_->getPixelFormat() : 0;
}
diff --git a/libs/vr/libbufferhub/ion_buffer.cpp b/libs/vr/libbufferhub/ion_buffer.cpp
index 716ab42..cbaa24a 100644
--- a/libs/vr/libbufferhub/ion_buffer.cpp
+++ b/libs/vr/libbufferhub/ion_buffer.cpp
@@ -15,36 +15,36 @@
namespace android {
namespace dvr {
-IonBuffer::IonBuffer() : IonBuffer(nullptr, 0, 0, 0, 0, 0, 0, 0) {}
+IonBuffer::IonBuffer() : IonBuffer(nullptr, 0, 0, 0, 0, 0, 0) {}
IonBuffer::IonBuffer(uint32_t width, uint32_t height, uint32_t format,
uint64_t usage)
: IonBuffer() {
- Alloc(width, height, format, usage);
+ Alloc(width, height, kDefaultGraphicBufferLayerCount, format, usage);
}
IonBuffer::IonBuffer(buffer_handle_t handle, uint32_t width, uint32_t height,
uint32_t stride, uint32_t format, uint64_t usage)
- : IonBuffer(handle, width, height, 1, stride, 0, format, usage) {}
+ : IonBuffer(handle, width, height, kDefaultGraphicBufferLayerCount, stride,
+ format, usage) {}
IonBuffer::IonBuffer(buffer_handle_t handle, uint32_t width, uint32_t height,
- uint32_t layer_count, uint32_t stride,
- uint32_t layer_stride, uint32_t format, uint64_t usage)
+ uint32_t layer_count, uint32_t stride, uint32_t format,
+ uint64_t usage)
: buffer_(nullptr) {
ALOGD_IF(TRACE,
"IonBuffer::IonBuffer: handle=%p width=%u height=%u layer_count=%u "
- "stride=%u layer stride=%u format=%u usage=%" PRIx64,
- handle, width, height, layer_count, stride, layer_stride, format,
- usage);
+ "stride=%u format=%u usage=%" PRIx64,
+ handle, width, height, layer_count, stride, format, usage);
if (handle != 0) {
- Import(handle, width, height, stride, format, usage);
+ Import(handle, width, height, layer_count, stride, format, usage);
}
}
IonBuffer::~IonBuffer() {
ALOGD_IF(TRACE,
"IonBuffer::~IonBuffer: handle=%p width=%u height=%u stride=%u "
- "format=%u usage=%x",
+ "format=%u usage=%" PRIx64,
handle(), width(), height(), stride(), format(), usage());
FreeHandle();
}
@@ -71,14 +71,14 @@
}
}
-int IonBuffer::Alloc(uint32_t width, uint32_t height, uint32_t format,
- uint64_t usage) {
+int IonBuffer::Alloc(uint32_t width, uint32_t height, uint32_t layer_count,
+ uint32_t format, uint64_t usage) {
ALOGD_IF(TRACE,
- "IonBuffer::Alloc: width=%u height=%u format=%u usage=%" PRIx64,
- width, height, format, usage);
+ "IonBuffer::Alloc: width=%u height=%u layer_count=%u format=%u "
+ "usage=%" PRIx64, width, height, layer_count, format, usage);
- sp<GraphicBuffer> buffer = new GraphicBuffer(
- width, height, format, kDefaultGraphicBufferLayerCount, usage);
+ sp<GraphicBuffer> buffer =
+ new GraphicBuffer(width, height, format, layer_count, usage);
if (buffer->initCheck() != OK) {
ALOGE("IonBuffer::Aloc: Failed to allocate buffer");
return -EINVAL;
@@ -89,26 +89,27 @@
}
void IonBuffer::Reset(buffer_handle_t handle, uint32_t width, uint32_t height,
- uint32_t stride, uint32_t format, uint64_t usage) {
+ uint32_t layer_count, uint32_t stride, uint32_t format,
+ uint64_t usage) {
ALOGD_IF(TRACE,
- "IonBuffer::Reset: handle=%p width=%u height=%u stride=%u format=%u "
- "usage=%" PRIx64,
- handle, width, height, stride, format, usage);
- Import(handle, width, height, stride, format, usage);
+ "IonBuffer::Reset: handle=%p width=%u height=%u layer_count=%u "
+ "stride=%u format=%u usage=%" PRIx64,
+ handle, width, height, layer_count, stride, format, usage);
+ Import(handle, width, height, layer_count, stride, format, usage);
}
int IonBuffer::Import(buffer_handle_t handle, uint32_t width, uint32_t height,
- uint32_t stride, uint32_t format, uint64_t usage) {
+ uint32_t layer_count, uint32_t stride, uint32_t format,
+ uint64_t usage) {
ATRACE_NAME("IonBuffer::Import1");
- ALOGD_IF(
- TRACE,
- "IonBuffer::Import: handle=%p width=%u height=%u stride=%u format=%u "
- "usage=%" PRIx64,
- handle, width, height, stride, format, usage);
+ ALOGD_IF(TRACE,
+ "IonBuffer::Import: handle=%p width=%u height=%u layer_count=%u "
+ "stride=%u format=%u usage=%" PRIx64,
+ handle, width, height, layer_count, stride, format, usage);
FreeHandle();
- sp<GraphicBuffer> buffer = new GraphicBuffer(
- handle, GraphicBuffer::TAKE_UNREGISTERED_HANDLE, width, height, format,
- kDefaultGraphicBufferLayerCount, usage, stride);
+ sp<GraphicBuffer> buffer =
+ new GraphicBuffer(handle, GraphicBuffer::TAKE_UNREGISTERED_HANDLE, width,
+ height, format, layer_count, usage, stride);
if (buffer->initCheck() != OK) {
ALOGE("IonBuffer::Import: Failed to import buffer");
return -EINVAL;
@@ -120,12 +121,14 @@
int IonBuffer::Import(const int* fd_array, int fd_count, const int* int_array,
int int_count, uint32_t width, uint32_t height,
- uint32_t stride, uint32_t format, uint64_t usage) {
+ uint32_t layer_count, uint32_t stride, uint32_t format,
+ uint64_t usage) {
ATRACE_NAME("IonBuffer::Import2");
ALOGD_IF(TRACE,
"IonBuffer::Import: fd_count=%d int_count=%d width=%u height=%u "
- "stride=%u format=%u usage=%" PRIx64,
- fd_count, int_count, width, height, stride, format, usage);
+ "layer_count=%u stride=%u format=%u usage=%" PRIx64,
+ fd_count, int_count, width, height, layer_count, stride, format,
+ usage);
if (fd_count < 0 || int_count < 0) {
ALOGE("IonBuffer::Import: invalid arguments.");
@@ -143,7 +146,8 @@
memcpy(handle->data, fd_array, sizeof(int) * fd_count);
memcpy(handle->data + fd_count, int_array, sizeof(int) * int_count);
- const int ret = Import(handle, width, height, stride, format, usage);
+ const int ret =
+ Import(handle, width, height, layer_count, stride, format, usage);
if (ret < 0) {
ALOGE("IonBuffer::Import: failed to import raw native handle: %s",
strerror(-ret));
@@ -179,8 +183,8 @@
sizeof(int) * int_count);
const int ret =
- Import(handle, other->width(), other->height(), other->stride(),
- other->format(), other->usage());
+ Import(handle, other->width(), other->height(), other->layer_count(),
+ other->stride(), other->format(), other->usage());
if (ret < 0) {
ALOGE("IonBuffer::Duplicate: Failed to import duplicate native handle: %s",
strerror(-ret));
diff --git a/libs/vr/libbufferhub/mocks/ion_buffer/private/dvr/ion_buffer.h b/libs/vr/libbufferhub/mocks/ion_buffer/private/dvr/ion_buffer.h
index fac6db0..8929c95 100644
--- a/libs/vr/libbufferhub/mocks/ion_buffer/private/dvr/ion_buffer.h
+++ b/libs/vr/libbufferhub/mocks/ion_buffer/private/dvr/ion_buffer.h
@@ -17,10 +17,11 @@
IonBufferMock() {}
MOCK_METHOD0(GetGrallocModuleImpl, gralloc_module_t const*());
MOCK_METHOD6(Import, int(buffer_handle_t handle, int width, int height,
- int stride, int format, int usage));
- MOCK_METHOD9(Import, int(const int* fd_array, int fd_count,
- const int* int_array, int int_count, int width,
- int height, int stride, int format, int usage));
+ int layer_count, int stride, int format, int usage));
+ MOCK_METHOD9(Import,
+ int(const int* fd_array, int fd_count, const int* int_array,
+ int int_count, int width, int height, int layer_count,
+ int stride, int format, int usage));
MOCK_METHOD6(Lock, int(int usage, int x, int y, int width, int height,
void** address));
MOCK_METHOD0(Unlock, int());
@@ -29,7 +30,6 @@
MOCK_CONST_METHOD0(height, int());
MOCK_CONST_METHOD0(layer_count, int());
MOCK_CONST_METHOD0(stride, int());
- MOCK_CONST_METHOD0(layer_stride, int());
MOCK_CONST_METHOD0(format, int());
MOCK_CONST_METHOD0(usage, int());
};
@@ -46,15 +46,16 @@
static gralloc_module_t const* GetGrallocModule() {
return staticObject->GetGrallocModuleImpl();
}
- int Import(buffer_handle_t handle, int width, int height, int stride,
- int format, int usage) {
- return mock_->Import(handle, width, height, stride, format, usage);
+ int Import(buffer_handle_t handle, int width, int height, int layer_count,
+ int stride, int format, int usage) {
+ return mock_->Import(handle, width, height, layer_count, stride, format,
+ usage);
}
int Import(const int* fd_array, int fd_count, const int* int_array,
- int int_count, int width, int height, int stride, int format,
- int usage) {
+ int int_count, int width, int height, int layer_count, int stride,
+ int format, int usage) {
return mock_->Import(fd_array, fd_count, int_array, int_count, width,
- height, stride, format, usage);
+ height, layer_count, stride, format, usage);
}
int Lock(int usage, int x, int y, int width, int height, void** address) {
return mock_->Lock(usage, x, y, width, height, address);
@@ -65,7 +66,6 @@
int height() const { return mock_->height(); }
int layer_count() const { return mock_->layer_count(); }
int stride() const { return mock_->stride(); }
- int layer_stride() const { return mock_->layer_stride(); }
int format() const { return mock_->format(); }
int usage() const { return mock_->usage(); }
std::unique_ptr<IonBufferMock> mock_;
diff --git a/libs/vr/libbufferhubqueue/buffer_hub_queue_client.cpp b/libs/vr/libbufferhubqueue/buffer_hub_queue_client.cpp
index a081af0..012a4e7 100644
--- a/libs/vr/libbufferhubqueue/buffer_hub_queue_client.cpp
+++ b/libs/vr/libbufferhubqueue/buffer_hub_queue_client.cpp
@@ -389,8 +389,8 @@
}
int ProducerQueue::AllocateBuffer(uint32_t width, uint32_t height,
- uint32_t format, uint64_t usage,
- size_t* out_slot) {
+ uint32_t layer_count, uint32_t format,
+ uint64_t usage, size_t* out_slot) {
if (out_slot == nullptr) {
ALOGE("ProducerQueue::AllocateBuffer: Parameter out_slot cannot be null.");
return -EINVAL;
@@ -405,7 +405,7 @@
const size_t kBufferCount = 1U;
Status<std::vector<std::pair<LocalChannelHandle, size_t>>> status =
InvokeRemoteMethod<BufferHubRPC::ProducerQueueAllocateBuffers>(
- width, height, format, usage, kBufferCount);
+ width, height, layer_count, format, usage, kBufferCount);
if (!status) {
ALOGE("ProducerQueue::AllocateBuffer failed to create producer buffer: %s",
status.GetErrorMessage().c_str());
diff --git a/libs/vr/libbufferhubqueue/buffer_hub_queue_core.cpp b/libs/vr/libbufferhubqueue/buffer_hub_queue_core.cpp
index 8e9501a..31cccf0 100644
--- a/libs/vr/libbufferhubqueue/buffer_hub_queue_core.cpp
+++ b/libs/vr/libbufferhubqueue/buffer_hub_queue_core.cpp
@@ -33,13 +33,15 @@
unique_id_(getUniqueId()) {}
status_t BufferHubQueueCore::AllocateBuffer(uint32_t width, uint32_t height,
+ uint32_t layer_count,
PixelFormat format,
- uint32_t usage) {
+ uint64_t usage) {
size_t slot;
// Allocate new buffer through BufferHub and add it into |producer_| queue for
// bookkeeping.
- if (producer_->AllocateBuffer(width, height, format, usage, &slot) < 0) {
+ if (producer_->AllocateBuffer(width, height, layer_count, format, usage,
+ &slot) < 0) {
ALOGE("Failed to allocate new buffer in BufferHub.");
return NO_MEMORY;
}
diff --git a/libs/vr/libbufferhubqueue/buffer_hub_queue_producer.cpp b/libs/vr/libbufferhubqueue/buffer_hub_queue_producer.cpp
index c886c27..64a7944 100644
--- a/libs/vr/libbufferhubqueue/buffer_hub_queue_producer.cpp
+++ b/libs/vr/libbufferhubqueue/buffer_hub_queue_producer.cpp
@@ -121,6 +121,7 @@
return NO_INIT;
}
+ const uint32_t kLayerCount = 1;
if (static_cast<int32_t>(core_->producer_->capacity()) <
max_dequeued_buffer_count_ +
BufferHubQueueCore::kDefaultUndequeuedBuffers) {
@@ -128,7 +129,7 @@
// |max_dequeued_buffer_count_|, allocate new buffer.
// TODO(jwcai) To save memory, the really reasonable thing to do is to go
// over existing slots and find first existing one to dequeue.
- ret = core_->AllocateBuffer(width, height, format, usage);
+ ret = core_->AllocateBuffer(width, height, kLayerCount, format, usage);
if (ret < 0)
return ret;
}
@@ -172,7 +173,7 @@
// there are already multiple buffers in the queue, the next one returned
// from |core_->producer_->Dequeue| may not be the new buffer we just
// reallocated. Retry up to BufferHubQueue::kMaxQueueCapacity times.
- ret = core_->AllocateBuffer(width, height, format, usage);
+ ret = core_->AllocateBuffer(width, height, kLayerCount, format, usage);
if (ret < 0)
return ret;
}
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 f9f742e..ed67f79 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
@@ -336,8 +336,8 @@
// use (i.e. in |Gain|'ed mode).
// Returns Zero on success and negative error code when buffer allocation
// fails.
- int AllocateBuffer(uint32_t width, uint32_t height, uint32_t format,
- uint64_t usage, size_t* out_slot);
+ int AllocateBuffer(uint32_t width, uint32_t height, uint32_t layer_count,
+ uint32_t format, uint64_t usage, size_t* out_slot);
// Add a producer buffer to populate the queue. Once added, a producer buffer
// is available to use (i.e. in |Gain|'ed mode).
diff --git a/libs/vr/libbufferhubqueue/include/private/dvr/buffer_hub_queue_core.h b/libs/vr/libbufferhubqueue/include/private/dvr/buffer_hub_queue_core.h
index e48b014..180906b 100644
--- a/libs/vr/libbufferhubqueue/include/private/dvr/buffer_hub_queue_core.h
+++ b/libs/vr/libbufferhubqueue/include/private/dvr/buffer_hub_queue_core.h
@@ -118,8 +118,8 @@
BufferHubQueueCore();
// Allocate a new buffer producer through BufferHub.
- int AllocateBuffer(uint32_t width, uint32_t height, PixelFormat format,
- uint32_t usage);
+ int AllocateBuffer(uint32_t width, uint32_t height, uint32_t layer_count,
+ PixelFormat format, uint64_t usage);
// Detach a buffer producer through BufferHub.
int DetachBuffer(size_t slot);
diff --git a/libs/vr/libbufferhubqueue/tests/buffer_hub_queue-test.cpp b/libs/vr/libbufferhubqueue/tests/buffer_hub_queue-test.cpp
index dcfefa4..fe0b12a 100644
--- a/libs/vr/libbufferhubqueue/tests/buffer_hub_queue-test.cpp
+++ b/libs/vr/libbufferhubqueue/tests/buffer_hub_queue-test.cpp
@@ -15,6 +15,7 @@
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;
@@ -54,7 +55,8 @@
// Create producer buffer.
size_t slot;
int ret = producer_queue_->AllocateBuffer(kBufferWidth, kBufferHeight,
- kBufferFormat, kBufferUsage, &slot);
+ kBufferLayerCount, kBufferFormat,
+ kBufferUsage, &slot);
ASSERT_EQ(ret, 0);
}
@@ -345,9 +347,9 @@
// When allocation, leave out |set_mask| from usage bits on purpose.
size_t slot;
- int ret = producer_queue_->AllocateBuffer(
- kBufferWidth, kBufferHeight, kBufferFormat, kBufferUsage & ~set_mask,
- &slot);
+ int ret = producer_queue_->AllocateBuffer(kBufferWidth, kBufferHeight,
+ kBufferFormat, kBufferLayerCount,
+ kBufferUsage & ~set_mask, &slot);
ASSERT_EQ(0, ret);
LocalHandle fence;
@@ -363,9 +365,9 @@
// When allocation, add |clear_mask| into usage bits on purpose.
size_t slot;
- int ret = producer_queue_->AllocateBuffer(
- kBufferWidth, kBufferHeight, kBufferFormat, kBufferUsage | clear_mask,
- &slot);
+ int ret = producer_queue_->AllocateBuffer(kBufferWidth, kBufferHeight,
+ kBufferLayerCount, kBufferFormat,
+ kBufferUsage | clear_mask, &slot);
ASSERT_EQ(0, ret);
LocalHandle fence;
@@ -383,14 +385,14 @@
// be able to succeed.
size_t slot;
int ret = producer_queue_->AllocateBuffer(
- kBufferWidth, kBufferHeight, kBufferFormat, kBufferUsage & ~deny_set_mask,
- &slot);
+ kBufferWidth, kBufferHeight, kBufferLayerCount, kBufferFormat,
+ kBufferUsage & ~deny_set_mask, &slot);
ASSERT_EQ(ret, 0);
// While allocation with those bits should fail.
- ret = producer_queue_->AllocateBuffer(
- kBufferWidth, kBufferHeight, kBufferFormat, kBufferUsage | deny_set_mask,
- &slot);
+ ret = producer_queue_->AllocateBuffer(kBufferWidth, kBufferHeight,
+ kBufferLayerCount, kBufferFormat,
+ kBufferUsage | deny_set_mask, &slot);
ASSERT_EQ(ret, -EINVAL);
}
@@ -402,14 +404,14 @@
// mandatory), allocation with those bits should be able to succeed.
size_t slot;
int ret = producer_queue_->AllocateBuffer(
- kBufferWidth, kBufferHeight, kBufferFormat,
+ kBufferWidth, kBufferHeight, kBufferLayerCount, kBufferFormat,
kBufferUsage | deny_clear_mask, &slot);
ASSERT_EQ(ret, 0);
// While allocation without those bits should fail.
- ret = producer_queue_->AllocateBuffer(
- kBufferWidth, kBufferHeight, kBufferFormat,
- kBufferUsage & ~deny_clear_mask, &slot);
+ ret = producer_queue_->AllocateBuffer(kBufferWidth, kBufferHeight,
+ kBufferLayerCount, kBufferFormat,
+ kBufferUsage & ~deny_clear_mask, &slot);
ASSERT_EQ(ret, -EINVAL);
}
diff --git a/libs/vr/libdisplay/display_client.cpp b/libs/vr/libdisplay/display_client.cpp
index eaf919e..5c9ebd4 100644
--- a/libs/vr/libdisplay/display_client.cpp
+++ b/libs/vr/libdisplay/display_client.cpp
@@ -123,15 +123,13 @@
return {std::move(producer_queue)};
}
-Status<std::unique_ptr<ProducerQueue>> Surface::CreateQueue(uint32_t width,
- uint32_t height,
- uint32_t format,
- uint64_t usage,
- size_t capacity) {
+Status<std::unique_ptr<ProducerQueue>> Surface::CreateQueue(
+ uint32_t width, uint32_t height, uint32_t layer_count, uint32_t format,
+ uint64_t usage, size_t capacity) {
ALOGD_IF(TRACE,
- "Surface::CreateQueue: width=%u height=%u format=%u usage=%" PRIx64
- " capacity=%zu",
- width, height, format, usage, capacity);
+ "Surface::CreateQueue: width=%u height=%u layer_count=%u format=%u "
+ "usage=%" PRIx64 " capacity=%zu",
+ width, height, layer_count, format, usage, capacity);
auto status = CreateQueue();
if (!status)
return status.error_status();
@@ -141,8 +139,8 @@
ALOGD_IF(TRACE, "Surface::CreateQueue: Allocating %zu buffers...", capacity);
for (size_t i = 0; i < capacity; i++) {
size_t slot;
- const int ret =
- producer_queue->AllocateBuffer(width, height, format, usage, &slot);
+ const int ret = producer_queue->AllocateBuffer(width, height, layer_count,
+ format, usage, &slot);
if (ret < 0) {
ALOGE(
"Surface::CreateQueue: Failed to allocate buffer on queue_id=%d: %s",
diff --git a/libs/vr/libdisplay/graphics.cpp b/libs/vr/libdisplay/graphics.cpp
index 58a906e..36f8095 100644
--- a/libs/vr/libdisplay/graphics.cpp
+++ b/libs/vr/libdisplay/graphics.cpp
@@ -310,7 +310,7 @@
if (!direct_surface) {
auto queue_status = surface->CreateQueue(
- sizeof(DisplaySurfaceMetadata), 1, HAL_PIXEL_FORMAT_BLOB,
+ sizeof(DisplaySurfaceMetadata), 1, 1, HAL_PIXEL_FORMAT_BLOB,
GRALLOC1_PRODUCER_USAGE_GPU_RENDER_TARGET |
GRALLOC1_PRODUCER_USAGE_CPU_WRITE_OFTEN |
GRALLOC1_CONSUMER_USAGE_GPU_DATA_BUFFER,
diff --git a/libs/vr/libdisplay/include/private/dvr/display_client.h b/libs/vr/libdisplay/include/private/dvr/display_client.h
index 668532d..7a7f670 100644
--- a/libs/vr/libdisplay/include/private/dvr/display_client.h
+++ b/libs/vr/libdisplay/include/private/dvr/display_client.h
@@ -42,6 +42,7 @@
// parameters.
pdx::Status<std::unique_ptr<ProducerQueue>> CreateQueue(uint32_t width,
uint32_t height,
+ uint32_t layer_count,
uint32_t format,
uint64_t usage,
size_t capacity);
diff --git a/libs/vr/libdisplay/native_buffer_queue.cpp b/libs/vr/libdisplay/native_buffer_queue.cpp
index 6d81975..1bb05d8 100644
--- a/libs/vr/libdisplay/native_buffer_queue.cpp
+++ b/libs/vr/libdisplay/native_buffer_queue.cpp
@@ -27,7 +27,7 @@
for (size_t i = 0; i < capacity; i++) {
size_t slot;
// TODO(jwcai) Should change to use BufferViewPort's spec to config.
- const int ret = producer_queue_->AllocateBuffer(width_, height_, format_,
+ const int ret = producer_queue_->AllocateBuffer(width_, height_, 1, format_,
usage_, &slot);
if (ret < 0) {
ALOGE(
diff --git a/libs/vr/libdvr/dvr_surface.cpp b/libs/vr/libdvr/dvr_surface.cpp
index b70f726..67e2ae8 100644
--- a/libs/vr/libdvr/dvr_surface.cpp
+++ b/libs/vr/libdvr/dvr_surface.cpp
@@ -133,7 +133,8 @@
int dvrSurfaceCreateWriteBufferQueue(DvrSurface* surface, uint32_t width,
uint32_t height, uint32_t format,
- uint64_t usage, size_t capacity,
+ uint32_t layer_count, uint64_t usage,
+ size_t capacity,
DvrWriteBufferQueue** out_writer) {
if (surface == nullptr || out_writer == nullptr) {
ALOGE(
@@ -143,8 +144,8 @@
return -EINVAL;
}
- auto status =
- surface->surface->CreateQueue(width, height, format, usage, capacity);
+ auto status = surface->surface->CreateQueue(width, height, layer_count,
+ format, usage, capacity);
if (!status) {
ALOGE("dvrSurfaceCreateWriteBufferQueue: Failed to create queue: %s",
status.GetErrorMessage().c_str());
diff --git a/libs/vr/libdvr/include/dvr/dvr_api.h b/libs/vr/libdvr/include/dvr/dvr_api.h
index 7124bee..bb9d8d8 100644
--- a/libs/vr/libdvr/include/dvr/dvr_api.h
+++ b/libs/vr/libdvr/include/dvr/dvr_api.h
@@ -162,7 +162,8 @@
size_t attribute_count);
typedef int (*DvrSurfaceCreateWriteBufferQueuePtr)(
DvrSurface* surface, uint32_t width, uint32_t height, uint32_t format,
- uint64_t usage, size_t capacity, DvrWriteBufferQueue** queue_out);
+ uint32_t layer_count, uint64_t usage, size_t capacity,
+ DvrWriteBufferQueue** queue_out);
// vsync_client_api.h
typedef int (*DvrVSyncClientCreatePtr)(DvrVSyncClient** client_out);
diff --git a/libs/vr/libdvr/include/dvr/dvr_surface.h b/libs/vr/libdvr/include/dvr/dvr_surface.h
index 58f2a10..361488e 100644
--- a/libs/vr/libdvr/include/dvr/dvr_surface.h
+++ b/libs/vr/libdvr/include/dvr/dvr_surface.h
@@ -78,7 +78,8 @@
// @return 0 on success. Otherwise returns a negative error value.
int dvrSurfaceCreateWriteBufferQueue(DvrSurface* surface, uint32_t width,
uint32_t height, uint32_t format,
- uint64_t usage, size_t capacity,
+ uint32_t layer_count, uint64_t usage,
+ size_t capacity,
DvrWriteBufferQueue** queue_out);
// Get a named buffer from the display service.
diff --git a/libs/vr/libdvr/tests/dvr_buffer_queue-test.cpp b/libs/vr/libdvr/tests/dvr_buffer_queue-test.cpp
index c38a1b8..474e968 100644
--- a/libs/vr/libdvr/tests/dvr_buffer_queue-test.cpp
+++ b/libs/vr/libdvr/tests/dvr_buffer_queue-test.cpp
@@ -15,6 +15,7 @@
static constexpr int kBufferWidth = 100;
static constexpr int kBufferHeight = 1;
+static constexpr int kLayerCount = 1;
static constexpr int kBufferFormat = HAL_PIXEL_FORMAT_BLOB;
static constexpr int kBufferUsage = GRALLOC_USAGE_SW_READ_RARELY;
static constexpr size_t kQueueCapacity = 3;
@@ -40,8 +41,8 @@
size_t out_slot;
for (size_t i = 0; i < buffer_count; i++) {
int ret = GetProducerQueueFromDvrWriteBufferQueue(write_queue_)
- ->AllocateBuffer(kBufferWidth, kBufferHeight, kBufferFormat,
- kBufferUsage, &out_slot);
+ ->AllocateBuffer(kBufferWidth, kBufferHeight, kLayerCount,
+ kBufferFormat, kBufferUsage, &out_slot);
ASSERT_EQ(0, ret);
}
}
diff --git a/libs/vr/libdvr/tests/dvr_display_manager-test.cpp b/libs/vr/libdvr/tests/dvr_display_manager-test.cpp
index 0150984..a2414d6 100644
--- a/libs/vr/libdvr/tests/dvr_display_manager-test.cpp
+++ b/libs/vr/libdvr/tests/dvr_display_manager-test.cpp
@@ -56,10 +56,11 @@
Status<UniqueDvrWriteBufferQueue> CreateSurfaceQueue(
const UniqueDvrSurface& surface, uint32_t width, uint32_t height,
- uint32_t format, uint64_t usage, size_t capacity) {
+ uint32_t format, uint32_t layer_count, uint64_t usage, size_t capacity) {
DvrWriteBufferQueue* queue;
- const int ret = dvrSurfaceCreateWriteBufferQueue(
- surface.get(), width, height, format, usage, capacity, &queue);
+ const int ret =
+ dvrSurfaceCreateWriteBufferQueue(surface.get(), width, height, format,
+ layer_count, usage, capacity, &queue);
if (ret < 0)
return ErrorStatus(-ret);
else
@@ -484,7 +485,7 @@
// Create a new queue in the surface.
auto write_queue_status = CreateSurfaceQueue(
- surface, 320, 240, AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM,
+ surface, 320, 240, AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM, 1,
AHARDWAREBUFFER_USAGE_CPU_READ_RARELY, 1);
ASSERT_STATUS_OK(write_queue_status);
UniqueDvrWriteBufferQueue write_queue = write_queue_status.take();
@@ -533,6 +534,45 @@
ASSERT_EQ(0u, queue_ids.size());
}
+TEST_F(DvrDisplayManagerTest, MultiLayerBufferQueue) {
+ // Create an application surface.
+ auto surface_status = CreateApplicationSurface();
+ ASSERT_STATUS_OK(surface_status);
+ UniqueDvrSurface surface = surface_status.take();
+ ASSERT_NE(nullptr, surface.get());
+
+ // Get surface state and verify there is one surface.
+ ASSERT_STATUS_OK(manager_->WaitForUpdate());
+ ASSERT_STATUS_EQ(1u, manager_->GetSurfaceCount());
+
+ // Create a new queue in the surface.
+ const uint32_t kLayerCount = 3;
+ auto write_queue_status = CreateSurfaceQueue(
+ surface, 320, 240, AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM, kLayerCount,
+ AHARDWAREBUFFER_USAGE_CPU_READ_RARELY, 1);
+ ASSERT_STATUS_OK(write_queue_status);
+ UniqueDvrWriteBufferQueue write_queue = write_queue_status.take();
+ ASSERT_NE(nullptr, write_queue.get());
+
+ DvrWriteBuffer* buffer = nullptr;
+ dvrWriteBufferCreateEmpty(&buffer);
+ int fence_fd = -1;
+ int error =
+ dvrWriteBufferQueueDequeue(write_queue.get(), 1000, buffer, &fence_fd);
+ ASSERT_EQ(0, error);
+
+ AHardwareBuffer* hardware_buffer = nullptr;
+ error = dvrWriteBufferGetAHardwareBuffer(buffer, &hardware_buffer);
+ ASSERT_EQ(0, error);
+
+ AHardwareBuffer_Desc desc = {};
+ AHardwareBuffer_describe(hardware_buffer, &desc);
+ ASSERT_EQ(kLayerCount, desc.layers);
+
+ AHardwareBuffer_release(hardware_buffer);
+ dvrWriteBufferDestroy(buffer);
+}
+
} // namespace
} // namespace dvr