diff options
49 files changed, 0 insertions, 7546 deletions
diff --git a/libs/vr/libbufferhubqueue/Android.bp b/libs/vr/libbufferhubqueue/Android.bp deleted file mode 100644 index 0bda7987a0..0000000000 --- a/libs/vr/libbufferhubqueue/Android.bp +++ /dev/null @@ -1,71 +0,0 @@ -// Copyright (C) 2016 The Android Open Source Project -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package { - // See: http://go/android-license-faq - // A large-scale-change added 'default_applicable_licenses' to import - // all of the 'license_kinds' from "frameworks_native_license" - // to get the below license kinds: - // SPDX-license-identifier-Apache-2.0 - default_applicable_licenses: ["frameworks_native_license"], -} - -sourceFiles = [ - "buffer_hub_queue_client.cpp", - "buffer_hub_queue_parcelable.cpp", -] - -includeFiles = [ - "include", -] - -staticLibraries = [ - "libbufferhub", -] - -sharedLibraries = [ - "libbinder", - "libcutils", - "liblog", - "libui", - "libutils", - "libpdx_default_transport", -] - -headerLibraries = [ - "libdvr_headers", - "libnativebase_headers", -] - -cc_library_shared { - name: "libbufferhubqueue", - cflags: [ - "-DLOG_TAG=\"libbufferhubqueue\"", - "-DTRACE=0", - "-DATRACE_TAG=ATRACE_TAG_GRAPHICS", - "-Wall", - "-Werror", - "-Wno-format", - "-Wno-unused-parameter", - "-Wno-unused-variable", - ], - srcs: sourceFiles, - export_include_dirs: includeFiles, - export_static_lib_headers: staticLibraries, - static_libs: staticLibraries, - shared_libs: sharedLibraries, - header_libs: headerLibraries, -} - -subdirs = ["benchmarks", "tests"] diff --git a/libs/vr/libbufferhubqueue/buffer_hub_queue_client.cpp b/libs/vr/libbufferhubqueue/buffer_hub_queue_client.cpp deleted file mode 100644 index 2d3fa4aec0..0000000000 --- a/libs/vr/libbufferhubqueue/buffer_hub_queue_client.cpp +++ /dev/null @@ -1,823 +0,0 @@ -#include "include/private/dvr/buffer_hub_queue_client.h" - -#include <inttypes.h> -#include <log/log.h> -#include <poll.h> -#include <sys/epoll.h> - -#include <array> - -#include <pdx/default_transport/client_channel.h> -#include <pdx/default_transport/client_channel_factory.h> -#include <pdx/file_handle.h> -#include <pdx/trace.h> - -#define RETRY_EINTR(fnc_call) \ - ([&]() -> decltype(fnc_call) { \ - decltype(fnc_call) result; \ - do { \ - result = (fnc_call); \ - } while (result == -1 && errno == EINTR); \ - return result; \ - })() - -using android::pdx::ErrorStatus; -using android::pdx::LocalChannelHandle; -using android::pdx::LocalHandle; -using android::pdx::Status; - -namespace android { -namespace dvr { - -namespace { - -std::pair<int32_t, int32_t> Unstuff(uint64_t value) { - return {static_cast<int32_t>(value >> 32), - static_cast<int32_t>(value & ((1ull << 32) - 1))}; -} - -uint64_t Stuff(int32_t a, int32_t b) { - const uint32_t ua = static_cast<uint32_t>(a); - const uint32_t ub = static_cast<uint32_t>(b); - return (static_cast<uint64_t>(ua) << 32) | static_cast<uint64_t>(ub); -} - -} // anonymous namespace - -BufferHubQueue::BufferHubQueue(LocalChannelHandle channel_handle) - : Client{pdx::default_transport::ClientChannel::Create( - std::move(channel_handle))} { - Initialize(); -} - -BufferHubQueue::BufferHubQueue(const std::string& endpoint_path) - : Client{ - pdx::default_transport::ClientChannelFactory::Create(endpoint_path)} { - Initialize(); -} - -void BufferHubQueue::Initialize() { - int ret = epoll_fd_.Create(); - if (ret < 0) { - ALOGE("BufferHubQueue::BufferHubQueue: Failed to create epoll fd: %s", - strerror(-ret)); - return; - } - - epoll_event event = { - .events = EPOLLIN | EPOLLET, - .data = {.u64 = Stuff(-1, BufferHubQueue::kEpollQueueEventIndex)}}; - ret = epoll_fd_.Control(EPOLL_CTL_ADD, event_fd(), &event); - if (ret < 0) { - ALOGE("%s: Failed to add event fd to epoll set: %s", __FUNCTION__, - strerror(-ret)); - } -} - -Status<void> BufferHubQueue::ImportQueue() { - auto status = InvokeRemoteMethod<BufferHubRPC::GetQueueInfo>(); - if (!status) { - ALOGE("%s: Failed to import queue: %s", __FUNCTION__, - status.GetErrorMessage().c_str()); - return ErrorStatus(status.error()); - } else { - SetupQueue(status.get()); - return {}; - } -} - -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; - user_metadata_size_ = queue_info.producer_config.user_metadata_size; - id_ = queue_info.id; -} - -std::unique_ptr<ConsumerQueue> BufferHubQueue::CreateConsumerQueue() { - if (auto status = CreateConsumerQueueHandle(/*silent*/ false)) - return std::unique_ptr<ConsumerQueue>(new ConsumerQueue(status.take())); - else - return nullptr; -} - -std::unique_ptr<ConsumerQueue> BufferHubQueue::CreateSilentConsumerQueue() { - if (auto status = CreateConsumerQueueHandle(/*silent*/ true)) - return std::unique_ptr<ConsumerQueue>(new ConsumerQueue(status.take())); - else - return nullptr; -} - -Status<LocalChannelHandle> BufferHubQueue::CreateConsumerQueueHandle( - bool silent) { - auto status = InvokeRemoteMethod<BufferHubRPC::CreateConsumerQueue>(silent); - if (!status) { - ALOGE( - "BufferHubQueue::CreateConsumerQueue: Failed to create consumer queue: " - "%s", - status.GetErrorMessage().c_str()); - return ErrorStatus(status.error()); - } - - return status; -} - -pdx::Status<ConsumerQueueParcelable> -BufferHubQueue::CreateConsumerQueueParcelable(bool silent) { - auto status = CreateConsumerQueueHandle(silent); - if (!status) - return status.error_status(); - - // A temporary consumer queue client to pull its channel parcelable. - auto consumer_queue = - std::unique_ptr<ConsumerQueue>(new ConsumerQueue(status.take())); - ConsumerQueueParcelable queue_parcelable( - consumer_queue->GetChannel()->TakeChannelParcelable()); - - if (!queue_parcelable.IsValid()) { - ALOGE("%s: Failed to create consumer queue parcelable.", __FUNCTION__); - return ErrorStatus(EINVAL); - } - - return {std::move(queue_parcelable)}; -} - -bool BufferHubQueue::WaitForBuffers(int timeout) { - ATRACE_NAME("BufferHubQueue::WaitForBuffers"); - std::array<epoll_event, kMaxEvents> events; - - // Loop at least once to check for hangups. - do { - ALOGD_IF( - TRACE, - "BufferHubQueue::WaitForBuffers: queue_id=%d count=%zu capacity=%zu", - id(), count(), capacity()); - - // If there is already a buffer then just check for hangup without waiting. - const int ret = epoll_fd_.Wait(events.data(), events.size(), - count() == 0 ? timeout : 0); - - if (ret == 0) { - ALOGI_IF(TRACE, - "BufferHubQueue::WaitForBuffers: No events before timeout: " - "queue_id=%d", - id()); - return count() != 0; - } - - if (ret < 0 && ret != -EINTR) { - ALOGE("%s: Failed to wait for buffers: %s", __FUNCTION__, strerror(-ret)); - return false; - } - - const int num_events = ret; - - // A BufferQueue's epoll fd tracks N+1 events, where there are N events, - // one for each buffer in the queue, and one extra event for the queue - // client itself. - for (int i = 0; i < num_events; i++) { - int32_t event_fd; - int32_t index; - std::tie(event_fd, index) = Unstuff(events[i].data.u64); - - PDX_TRACE_FORMAT( - "epoll_event|queue_id=%d;num_events=%d;event_index=%d;event_fd=%d;" - "slot=%d|", - id(), num_events, i, event_fd, index); - - ALOGD_IF(TRACE, - "BufferHubQueue::WaitForBuffers: event %d: event_fd=%d index=%d", - i, event_fd, index); - - if (is_buffer_event_index(index)) { - HandleBufferEvent(static_cast<size_t>(index), event_fd, - events[i].events); - } else if (is_queue_event_index(index)) { - HandleQueueEvent(events[i].events); - } else { - ALOGW( - "BufferHubQueue::WaitForBuffers: Unknown event type event_fd=%d " - "index=%d", - event_fd, index); - } - } - } while (count() == 0 && capacity() > 0 && !hung_up()); - - return count() != 0; -} - -Status<void> BufferHubQueue::HandleBufferEvent(size_t slot, int event_fd, - int poll_events) { - ATRACE_NAME("BufferHubQueue::HandleBufferEvent"); - if (!buffers_[slot]) { - ALOGW("BufferHubQueue::HandleBufferEvent: Invalid buffer slot: %zu", slot); - return ErrorStatus(ENOENT); - } - - auto status = buffers_[slot]->GetEventMask(poll_events); - if (!status) { - ALOGW("BufferHubQueue::HandleBufferEvent: Failed to get event mask: %s", - status.GetErrorMessage().c_str()); - return status.error_status(); - } - - const int events = status.get(); - PDX_TRACE_FORMAT( - "buffer|queue_id=%d;buffer_id=%d;slot=%zu;event_fd=%d;poll_events=%x;" - "events=%d|", - id(), buffers_[slot]->id(), slot, event_fd, poll_events, events); - - if (events & EPOLLIN) { - return Enqueue({buffers_[slot], slot, buffers_[slot]->GetQueueIndex()}); - } else if (events & EPOLLHUP) { - ALOGW( - "BufferHubQueue::HandleBufferEvent: Received EPOLLHUP event: slot=%zu " - "event_fd=%d buffer_id=%d", - slot, buffers_[slot]->event_fd(), buffers_[slot]->id()); - return RemoveBuffer(slot); - } else { - ALOGW( - "BufferHubQueue::HandleBufferEvent: Unknown event, slot=%zu, epoll " - "events=%d", - slot, events); - } - - return {}; -} - -Status<void> BufferHubQueue::HandleQueueEvent(int poll_event) { - ATRACE_NAME("BufferHubQueue::HandleQueueEvent"); - auto status = GetEventMask(poll_event); - if (!status) { - ALOGW("BufferHubQueue::HandleQueueEvent: Failed to get event mask: %s", - status.GetErrorMessage().c_str()); - return status.error_status(); - } - - const int events = status.get(); - if (events & EPOLLIN) { - // Note that after buffer imports, if |count()| still returns 0, epoll - // wait will be tried again to acquire the newly imported buffer. - auto buffer_status = OnBufferAllocated(); - if (!buffer_status) { - ALOGE("%s: Failed to import buffer: %s", __FUNCTION__, - buffer_status.GetErrorMessage().c_str()); - } - } else if (events & EPOLLHUP) { - ALOGD_IF(TRACE, "%s: hang up event!", __FUNCTION__); - hung_up_ = true; - } else { - ALOGW("%s: Unknown epoll events=%x", __FUNCTION__, events); - } - - return {}; -} - -Status<void> BufferHubQueue::AddBuffer( - const std::shared_ptr<BufferHubBase>& buffer, size_t slot) { - ALOGD_IF(TRACE, "%s: buffer_id=%d slot=%zu", __FUNCTION__, buffer->id(), - slot); - - if (is_full()) { - ALOGE("%s: queue is at maximum capacity: %zu", __FUNCTION__, capacity_); - return ErrorStatus(E2BIG); - } - - if (buffers_[slot]) { - // Replace the buffer if the slot is occupied. This could happen when the - // producer side replaced the slot with a newly allocated buffer. Remove the - // buffer before setting up with the new one. - auto remove_status = RemoveBuffer(slot); - if (!remove_status) - return remove_status.error_status(); - } - - for (const auto& event_source : buffer->GetEventSources()) { - epoll_event event = {.events = event_source.event_mask | EPOLLET, - .data = {.u64 = Stuff(buffer->event_fd(), slot)}}; - const int ret = - epoll_fd_.Control(EPOLL_CTL_ADD, event_source.event_fd, &event); - if (ret < 0) { - ALOGE("%s: Failed to add buffer to epoll set: %s", __FUNCTION__, - strerror(-ret)); - return ErrorStatus(-ret); - } - } - - buffers_[slot] = buffer; - capacity_++; - return {}; -} - -Status<void> BufferHubQueue::RemoveBuffer(size_t slot) { - ALOGD_IF(TRACE, "%s: slot=%zu", __FUNCTION__, slot); - - if (buffers_[slot]) { - for (const auto& event_source : buffers_[slot]->GetEventSources()) { - const int ret = - epoll_fd_.Control(EPOLL_CTL_DEL, event_source.event_fd, nullptr); - if (ret < 0) { - ALOGE("%s: Failed to remove buffer from epoll set: %s", __FUNCTION__, - strerror(-ret)); - return ErrorStatus(-ret); - } - } - - // Trigger OnBufferRemoved callback if registered. - if (on_buffer_removed_) - on_buffer_removed_(buffers_[slot]); - - buffers_[slot] = nullptr; - capacity_--; - } - - return {}; -} - -Status<void> BufferHubQueue::Enqueue(Entry entry) { - if (!is_full()) { - // Find and remove the enqueued buffer from unavailable_buffers_slot if - // exist. - auto enqueued_buffer_iter = std::find_if( - unavailable_buffers_slot_.begin(), unavailable_buffers_slot_.end(), - [&entry](size_t slot) -> bool { return slot == entry.slot; }); - if (enqueued_buffer_iter != unavailable_buffers_slot_.end()) { - unavailable_buffers_slot_.erase(enqueued_buffer_iter); - } - - available_buffers_.push(std::move(entry)); - - // Trigger OnBufferAvailable callback if registered. - if (on_buffer_available_) - on_buffer_available_(); - - return {}; - } else { - ALOGE("%s: Buffer queue is full!", __FUNCTION__); - return ErrorStatus(E2BIG); - } -} - -Status<std::shared_ptr<BufferHubBase>> BufferHubQueue::Dequeue(int timeout, - size_t* slot) { - ALOGD_IF(TRACE, "%s: count=%zu, timeout=%d", __FUNCTION__, count(), timeout); - - PDX_TRACE_FORMAT("%s|count=%zu|", __FUNCTION__, count()); - - if (count() == 0) { - if (!WaitForBuffers(timeout)) - return ErrorStatus(ETIMEDOUT); - } - - auto& entry = available_buffers_.top(); - PDX_TRACE_FORMAT("buffer|buffer_id=%d;slot=%zu|", entry.buffer->id(), - entry.slot); - - std::shared_ptr<BufferHubBase> buffer = std::move(entry.buffer); - *slot = entry.slot; - - available_buffers_.pop(); - unavailable_buffers_slot_.push_back(*slot); - - return {std::move(buffer)}; -} - -void BufferHubQueue::SetBufferAvailableCallback( - BufferAvailableCallback callback) { - on_buffer_available_ = callback; -} - -void BufferHubQueue::SetBufferRemovedCallback(BufferRemovedCallback callback) { - on_buffer_removed_ = callback; -} - -pdx::Status<void> BufferHubQueue::FreeAllBuffers() { - // Clear all available buffers. - while (!available_buffers_.empty()) - available_buffers_.pop(); - - pdx::Status<void> last_error; // No error. - // Clear all buffers this producer queue is tracking. - for (size_t slot = 0; slot < BufferHubQueue::kMaxQueueCapacity; slot++) { - if (buffers_[slot] != nullptr) { - auto status = RemoveBuffer(slot); - if (!status) { - ALOGE( - "ProducerQueue::FreeAllBuffers: Failed to remove buffer at " - "slot=%zu.", - slot); - last_error = status.error_status(); - } - } - } - - return last_error; -} - -ProducerQueue::ProducerQueue(LocalChannelHandle handle) - : BASE(std::move(handle)) { - auto status = ImportQueue(); - if (!status) { - ALOGE("ProducerQueue::ProducerQueue: Failed to import queue: %s", - status.GetErrorMessage().c_str()); - Close(-status.error()); - } -} - -ProducerQueue::ProducerQueue(const ProducerQueueConfig& config, - const UsagePolicy& usage) - : BASE(BufferHubRPC::kClientPath) { - auto status = - InvokeRemoteMethod<BufferHubRPC::CreateProducerQueue>(config, usage); - if (!status) { - ALOGE("ProducerQueue::ProducerQueue: Failed to create producer queue: %s", - status.GetErrorMessage().c_str()); - Close(-status.error()); - return; - } - - SetupQueue(status.get()); -} - -Status<std::vector<size_t>> ProducerQueue::AllocateBuffers( - uint32_t width, uint32_t height, uint32_t layer_count, uint32_t format, - uint64_t usage, size_t buffer_count) { - if (buffer_count == 0) { - return {std::vector<size_t>()}; - } - - if (capacity() + buffer_count > kMaxQueueCapacity) { - ALOGE( - "ProducerQueue::AllocateBuffers: queue is at capacity: %zu, cannot " - "allocate %zu more buffer(s).", - capacity(), buffer_count); - return ErrorStatus(E2BIG); - } - - Status<std::vector<std::pair<LocalChannelHandle, size_t>>> status = - InvokeRemoteMethod<BufferHubRPC::ProducerQueueAllocateBuffers>( - width, height, layer_count, format, usage, buffer_count); - if (!status) { - ALOGE("ProducerQueue::AllocateBuffers: failed to allocate buffers: %s", - status.GetErrorMessage().c_str()); - return status.error_status(); - } - - auto buffer_handle_slots = status.take(); - LOG_ALWAYS_FATAL_IF(buffer_handle_slots.size() != buffer_count, - "BufferHubRPC::ProducerQueueAllocateBuffers should " - "return %zu buffer handle(s), but returned %zu instead.", - buffer_count, buffer_handle_slots.size()); - - std::vector<size_t> buffer_slots; - buffer_slots.reserve(buffer_count); - - // Bookkeeping for each buffer. - for (auto& hs : buffer_handle_slots) { - auto& buffer_handle = hs.first; - size_t buffer_slot = hs.second; - - // Note that import might (though very unlikely) fail. If so, buffer_handle - // will be closed and included in returned buffer_slots. - if (AddBuffer(ProducerBuffer::Import(std::move(buffer_handle)), - buffer_slot)) { - ALOGD_IF(TRACE, "ProducerQueue::AllocateBuffers: new buffer at slot: %zu", - buffer_slot); - buffer_slots.push_back(buffer_slot); - } - } - - if (buffer_slots.size() != buffer_count) { - // Error out if the count of imported buffer(s) is not correct. - ALOGE( - "ProducerQueue::AllocateBuffers: requested to import %zu " - "buffers, but actually imported %zu buffers.", - buffer_count, buffer_slots.size()); - return ErrorStatus(ENOMEM); - } - - return {std::move(buffer_slots)}; -} - -Status<size_t> ProducerQueue::AllocateBuffer(uint32_t width, uint32_t height, - uint32_t layer_count, - uint32_t format, uint64_t usage) { - // We only allocate one buffer at a time. - constexpr size_t buffer_count = 1; - auto status = - AllocateBuffers(width, height, layer_count, format, usage, buffer_count); - if (!status) { - ALOGE("ProducerQueue::AllocateBuffer: Failed to allocate buffer: %s", - status.GetErrorMessage().c_str()); - return status.error_status(); - } - - return {status.get()[0]}; -} - -Status<void> ProducerQueue::AddBuffer( - const std::shared_ptr<ProducerBuffer>& buffer, size_t slot) { - ALOGD_IF(TRACE, "ProducerQueue::AddBuffer: queue_id=%d buffer_id=%d slot=%zu", - id(), buffer->id(), slot); - // For producer buffer, we need to enqueue the newly added buffer - // immediately. Producer queue starts with all buffers in available state. - auto status = BufferHubQueue::AddBuffer(buffer, slot); - if (!status) - return status; - - return BufferHubQueue::Enqueue({buffer, slot, 0ULL}); -} - -Status<size_t> ProducerQueue::InsertBuffer( - const std::shared_ptr<ProducerBuffer>& buffer) { - if (buffer == nullptr || - !BufferHubDefs::isClientGained(buffer->buffer_state(), - buffer->client_state_mask())) { - ALOGE( - "ProducerQueue::InsertBuffer: Can only insert a buffer when it's in " - "gained state."); - return ErrorStatus(EINVAL); - } - - auto status_or_slot = - InvokeRemoteMethod<BufferHubRPC::ProducerQueueInsertBuffer>( - buffer->cid()); - if (!status_or_slot) { - ALOGE( - "ProducerQueue::InsertBuffer: Failed to insert producer buffer: " - "buffer_cid=%d, error: %s.", - buffer->cid(), status_or_slot.GetErrorMessage().c_str()); - return status_or_slot.error_status(); - } - - size_t slot = status_or_slot.get(); - - // Note that we are calling AddBuffer() from the base class to explicitly - // avoid Enqueue() the ProducerBuffer. - auto status = BufferHubQueue::AddBuffer(buffer, slot); - if (!status) { - ALOGE("ProducerQueue::InsertBuffer: Failed to add buffer: %s.", - status.GetErrorMessage().c_str()); - return status.error_status(); - } - return {slot}; -} - -Status<void> ProducerQueue::RemoveBuffer(size_t slot) { - auto status = - InvokeRemoteMethod<BufferHubRPC::ProducerQueueRemoveBuffer>(slot); - if (!status) { - ALOGE("%s: Failed to remove producer buffer: %s", __FUNCTION__, - status.GetErrorMessage().c_str()); - return status.error_status(); - } - - return BufferHubQueue::RemoveBuffer(slot); -} - -Status<std::shared_ptr<ProducerBuffer>> ProducerQueue::Dequeue( - int timeout, size_t* slot, LocalHandle* release_fence) { - DvrNativeBufferMetadata canonical_meta; - return Dequeue(timeout, slot, &canonical_meta, release_fence); -} - -pdx::Status<std::shared_ptr<ProducerBuffer>> ProducerQueue::Dequeue( - int timeout, size_t* slot, DvrNativeBufferMetadata* out_meta, - pdx::LocalHandle* release_fence, bool gain_posted_buffer) { - ATRACE_NAME("ProducerQueue::Dequeue"); - if (slot == nullptr || out_meta == nullptr || release_fence == nullptr) { - ALOGE("%s: Invalid parameter.", __FUNCTION__); - return ErrorStatus(EINVAL); - } - - std::shared_ptr<ProducerBuffer> buffer; - Status<std::shared_ptr<BufferHubBase>> dequeue_status = - BufferHubQueue::Dequeue(timeout, slot); - if (dequeue_status.ok()) { - buffer = std::static_pointer_cast<ProducerBuffer>(dequeue_status.take()); - } else { - if (gain_posted_buffer) { - Status<std::shared_ptr<ProducerBuffer>> dequeue_unacquired_status = - ProducerQueue::DequeueUnacquiredBuffer(slot); - if (!dequeue_unacquired_status.ok()) { - ALOGE("%s: DequeueUnacquiredBuffer returned error: %d", __FUNCTION__, - dequeue_unacquired_status.error()); - return dequeue_unacquired_status.error_status(); - } - buffer = dequeue_unacquired_status.take(); - } else { - return dequeue_status.error_status(); - } - } - const int ret = - buffer->GainAsync(out_meta, release_fence, gain_posted_buffer); - if (ret < 0 && ret != -EALREADY) - return ErrorStatus(-ret); - - return {std::move(buffer)}; -} - -Status<std::shared_ptr<ProducerBuffer>> ProducerQueue::DequeueUnacquiredBuffer( - size_t* slot) { - if (unavailable_buffers_slot_.size() < 1) { - ALOGE( - "%s: Failed to dequeue un-acquired buffer. All buffer(s) are in " - "acquired state if exist.", - __FUNCTION__); - return ErrorStatus(ENOMEM); - } - - // Find the first buffer that is not in acquired state from - // unavailable_buffers_slot_. - for (auto iter = unavailable_buffers_slot_.begin(); - iter != unavailable_buffers_slot_.end(); iter++) { - std::shared_ptr<ProducerBuffer> buffer = ProducerQueue::GetBuffer(*iter); - if (buffer == nullptr) { - ALOGE("%s failed. Buffer slot %d is null.", __FUNCTION__, - static_cast<int>(*slot)); - return ErrorStatus(EIO); - } - if (!BufferHubDefs::isAnyClientAcquired(buffer->buffer_state())) { - *slot = *iter; - unavailable_buffers_slot_.erase(iter); - unavailable_buffers_slot_.push_back(*slot); - ALOGD("%s: Producer queue dequeue unacquired buffer in slot %d", - __FUNCTION__, static_cast<int>(*slot)); - return {std::move(buffer)}; - } - } - ALOGE( - "%s: Failed to dequeue un-acquired buffer. No un-acquired buffer exist.", - __FUNCTION__); - return ErrorStatus(EBUSY); -} - -pdx::Status<ProducerQueueParcelable> ProducerQueue::TakeAsParcelable() { - if (capacity() != 0) { - ALOGE( - "%s: producer queue can only be taken out as a parcelable when empty. " - "Current queue capacity: %zu", - __FUNCTION__, capacity()); - return ErrorStatus(EINVAL); - } - - std::unique_ptr<pdx::ClientChannel> channel = TakeChannel(); - ProducerQueueParcelable queue_parcelable(channel->TakeChannelParcelable()); - - // Here the queue parcelable is returned and holds the underlying system - // resources backing the queue; while the original client channel of this - // producer queue is destroyed in place so that this client can no longer - // provide producer operations. - return {std::move(queue_parcelable)}; -} - -/*static */ -std::unique_ptr<ConsumerQueue> ConsumerQueue::Import( - LocalChannelHandle handle) { - return std::unique_ptr<ConsumerQueue>(new ConsumerQueue(std::move(handle))); -} - -ConsumerQueue::ConsumerQueue(LocalChannelHandle handle) - : BufferHubQueue(std::move(handle)) { - auto status = ImportQueue(); - if (!status) { - ALOGE("%s: Failed to import queue: %s", __FUNCTION__, - status.GetErrorMessage().c_str()); - Close(-status.error()); - } - - auto import_status = ImportBuffers(); - if (import_status) { - ALOGI("%s: Imported %zu buffers.", __FUNCTION__, import_status.get()); - } else { - ALOGE("%s: Failed to import buffers: %s", __FUNCTION__, - import_status.GetErrorMessage().c_str()); - } -} - -Status<size_t> ConsumerQueue::ImportBuffers() { - auto status = InvokeRemoteMethod<BufferHubRPC::ConsumerQueueImportBuffers>(); - if (!status) { - if (status.error() == EBADR) { - ALOGI("%s: Queue is silent, no buffers imported.", __FUNCTION__); - return {0}; - } else { - ALOGE("%s: Failed to import consumer buffer: %s", __FUNCTION__, - status.GetErrorMessage().c_str()); - return status.error_status(); - } - } - - int ret; - Status<void> last_error; - size_t imported_buffers_count = 0; - - auto buffer_handle_slots = status.take(); - for (auto& buffer_handle_slot : buffer_handle_slots) { - ALOGD_IF(TRACE, ": buffer_handle=%d", __FUNCTION__, - buffer_handle_slot.first.value()); - - std::unique_ptr<ConsumerBuffer> consumer_buffer = - ConsumerBuffer::Import(std::move(buffer_handle_slot.first)); - if (!consumer_buffer) { - ALOGE("%s: Failed to import buffer: slot=%zu", __FUNCTION__, - buffer_handle_slot.second); - last_error = ErrorStatus(EPIPE); - continue; - } - - auto add_status = - AddBuffer(std::move(consumer_buffer), buffer_handle_slot.second); - if (!add_status) { - ALOGE("%s: Failed to add buffer: %s", __FUNCTION__, - add_status.GetErrorMessage().c_str()); - last_error = add_status; - } else { - imported_buffers_count++; - } - } - - if (imported_buffers_count > 0) - return {imported_buffers_count}; - else - return last_error.error_status(); -} - -Status<void> ConsumerQueue::AddBuffer( - const std::shared_ptr<ConsumerBuffer>& buffer, size_t slot) { - ALOGD_IF(TRACE, "%s: queue_id=%d buffer_id=%d slot=%zu", __FUNCTION__, id(), - buffer->id(), slot); - return BufferHubQueue::AddBuffer(buffer, slot); -} - -Status<std::shared_ptr<ConsumerBuffer>> ConsumerQueue::Dequeue( - int timeout, size_t* slot, void* meta, size_t user_metadata_size, - LocalHandle* acquire_fence) { - if (user_metadata_size != user_metadata_size_) { - ALOGE( - "%s: Metadata size (%zu) for the dequeuing buffer does not match " - "metadata size (%zu) for the queue.", - __FUNCTION__, user_metadata_size, user_metadata_size_); - return ErrorStatus(EINVAL); - } - - DvrNativeBufferMetadata canonical_meta; - auto status = Dequeue(timeout, slot, &canonical_meta, acquire_fence); - if (!status) - return status.error_status(); - - if (meta && user_metadata_size) { - void* metadata_src = - reinterpret_cast<void*>(canonical_meta.user_metadata_ptr); - if (metadata_src) { - memcpy(meta, metadata_src, user_metadata_size); - } else { - ALOGW("%s: no user-defined metadata.", __FUNCTION__); - } - } - - return status; -} - -Status<std::shared_ptr<ConsumerBuffer>> ConsumerQueue::Dequeue( - int timeout, size_t* slot, DvrNativeBufferMetadata* out_meta, - pdx::LocalHandle* acquire_fence) { - ATRACE_NAME("ConsumerQueue::Dequeue"); - if (slot == nullptr || out_meta == nullptr || acquire_fence == nullptr) { - ALOGE("%s: Invalid parameter.", __FUNCTION__); - return ErrorStatus(EINVAL); - } - - auto status = BufferHubQueue::Dequeue(timeout, slot); - if (!status) - return status.error_status(); - - auto buffer = std::static_pointer_cast<ConsumerBuffer>(status.take()); - const int ret = buffer->AcquireAsync(out_meta, acquire_fence); - if (ret < 0) - return ErrorStatus(-ret); - - return {std::move(buffer)}; -} - -Status<void> ConsumerQueue::OnBufferAllocated() { - ALOGD_IF(TRACE, "%s: queue_id=%d", __FUNCTION__, id()); - - auto status = ImportBuffers(); - if (!status) { - ALOGE("%s: Failed to import buffers: %s", __FUNCTION__, - status.GetErrorMessage().c_str()); - return ErrorStatus(status.error()); - } else if (status.get() == 0) { - ALOGW("%s: No new buffers allocated!", __FUNCTION__); - return ErrorStatus(ENOBUFS); - } else { - ALOGD_IF(TRACE, "%s: Imported %zu consumer buffers.", __FUNCTION__, - status.get()); - return {}; - } -} - -} // namespace dvr -} // namespace android diff --git a/libs/vr/libbufferhubqueue/buffer_hub_queue_parcelable.cpp b/libs/vr/libbufferhubqueue/buffer_hub_queue_parcelable.cpp deleted file mode 100644 index f705749243..0000000000 --- a/libs/vr/libbufferhubqueue/buffer_hub_queue_parcelable.cpp +++ /dev/null @@ -1,82 +0,0 @@ -#include "include/private/dvr/buffer_hub_queue_parcelable.h" - -#include <binder/Parcel.h> -#include <pdx/default_transport/channel_parcelable.h> - -namespace android { -namespace dvr { - -template <BufferHubQueueParcelableMagic Magic> -bool BufferHubQueueParcelable<Magic>::IsValid() const { - return !!channel_parcelable_ && channel_parcelable_->IsValid(); -} - -template <BufferHubQueueParcelableMagic Magic> -pdx::LocalChannelHandle BufferHubQueueParcelable<Magic>::TakeChannelHandle() { - if (!IsValid()) { - ALOGE( - "BufferHubQueueParcelable::TakeChannelHandle: Invalid channel parcel."); - return {}; // Returns an empty channel handle. - } - - // Take channel handle out of the parcelable and reset the parcelable. - pdx::LocalChannelHandle handle = channel_parcelable_->TakeChannelHandle(); - // Now channel_parcelable_ should already be invalid, but reset it to release - // the invalid parcelable object from unique_ptr. - channel_parcelable_ = nullptr; - return handle; -} - -template <BufferHubQueueParcelableMagic Magic> -status_t BufferHubQueueParcelable<Magic>::writeToParcel(Parcel* parcel) const { - if (!IsValid()) { - ALOGE("BufferHubQueueParcelable::writeToParcel: Invalid channel."); - return -EINVAL; - } - - status_t res = parcel->writeUint32(Magic); - if (res != OK) { - ALOGE("BufferHubQueueParcelable::writeToParcel: Cannot write magic."); - return res; - } - - return channel_parcelable_->writeToParcel(parcel); -} - -template <BufferHubQueueParcelableMagic Magic> -status_t BufferHubQueueParcelable<Magic>::readFromParcel(const Parcel* parcel) { - if (IsValid()) { - ALOGE( - "BufferHubQueueParcelable::readFromParcel: This parcelable object has " - "been initialized already."); - return -EINVAL; - } - - uint32_t out_magic = 0; - status_t res = OK; - - res = parcel->readUint32(&out_magic); - if (res != OK) - return res; - - if (out_magic != Magic) { - ALOGE( - "BufferHubQueueParcelable::readFromParcel: Unexpected magic: 0x%x, " - "epxected: 0x%x", - out_magic, Magic); - return -EINVAL; - } - - // (Re)Alocate channel parcelable object. - channel_parcelable_ = - std::make_unique<pdx::default_transport::ChannelParcelable>(); - return channel_parcelable_->readFromParcel(parcel); -} - -template class BufferHubQueueParcelable< - BufferHubQueueParcelableMagic::Producer>; -template class BufferHubQueueParcelable< - BufferHubQueueParcelableMagic::Consumer>; - -} // namespace dvr -} // namespace android 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 deleted file mode 100644 index 74b4b3d67f..0000000000 --- a/libs/vr/libbufferhubqueue/include/private/dvr/buffer_hub_queue_client.h +++ /dev/null @@ -1,476 +0,0 @@ -#ifndef ANDROID_DVR_BUFFER_HUB_QUEUE_CLIENT_H_ -#define ANDROID_DVR_BUFFER_HUB_QUEUE_CLIENT_H_ - -#include <ui/BufferQueueDefs.h> - -#if defined(__clang__) -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Weverything" -#endif - -// The following headers are included without checking every warning. -// TODO(b/72172820): Remove the workaround once we have enforced -Weverything -// in these headers and their dependencies. -#include <pdx/client.h> -#include <pdx/status.h> -#include <private/dvr/buffer_hub_queue_parcelable.h> -#include <private/dvr/bufferhub_rpc.h> -#include <private/dvr/consumer_buffer.h> -#include <private/dvr/epoll_file_descriptor.h> -#include <private/dvr/producer_buffer.h> - -#if defined(__clang__) -#pragma clang diagnostic pop -#endif - -#include <memory> -#include <queue> -#include <vector> - -namespace android { -namespace dvr { - -class ConsumerQueue; - -// |BufferHubQueue| manages a queue of |BufferHubBase|s. Buffers are -// automatically re-requeued when released by the remote side. -class BufferHubQueue : public pdx::Client { - public: - using BufferAvailableCallback = std::function<void()>; - using BufferRemovedCallback = - std::function<void(const std::shared_ptr<BufferHubBase>&)>; - - virtual ~BufferHubQueue() {} - - // Creates a new consumer queue that is attached to the producer. Returns - // a new consumer queue client or nullptr on failure. - std::unique_ptr<ConsumerQueue> CreateConsumerQueue(); - - // Creates a new consumer queue that is attached to the producer. This queue - // sets each of its imported consumer buffers to the ignored state to avoid - // 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. - uint32_t default_width() const { return default_width_; } - - // Returns the default buffer height of this buffer queue. - uint32_t default_height() const { return default_height_; } - - // Returns the default buffer format of this buffer queue. - 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( - bool silent = false); - - // Creates a new consumer in parcelable form for immediate transport over - // Binder. - pdx::Status<ConsumerQueueParcelable> CreateConsumerQueueParcelable( - bool silent = false); - - // Returns the number of buffers avaiable for dequeue. - size_t count() const { return available_buffers_.size(); } - - // Returns the total number of buffers that the queue is tracking. - size_t capacity() const { return capacity_; } - - // Returns the size of metadata structure associated with this queue. - size_t metadata_size() const { return user_metadata_size_; } - - // Returns whether the buffer queue is full. - bool is_full() const { - return available_buffers_.size() >= kMaxQueueCapacity; - } - - // Returns whether the buffer queue is connected to bufferhubd. - bool is_connected() const { return !!GetChannel(); } - - int GetBufferId(size_t slot) const { - return (slot < buffers_.size() && buffers_[slot]) ? buffers_[slot]->id() - : -1; - } - - std::shared_ptr<BufferHubBase> GetBuffer(size_t slot) const { - return buffers_[slot]; - } - - pdx::Status<int> GetEventMask(int events) { - if (auto* client_channel = GetChannel()) { - return client_channel->GetEventMask(events); - } else { - return pdx::ErrorStatus(EINVAL); - } - } - - // Returns an fd that signals pending queue events using - // EPOLLIN/POLLIN/readible. Either HandleQueueEvents or WaitForBuffers may be - // called to handle pending queue events. - int queue_fd() const { return epoll_fd_.Get(); } - - // Handles any pending events, returning available buffers to the queue and - // reaping disconnected buffers. Returns true if successful, false if an error - // occurred. - bool HandleQueueEvents() { return WaitForBuffers(0); } - - // Set buffer event callbacks, which are std::function wrappers. The caller is - // responsible for ensuring the validity of these callbacks' callable targets. - void SetBufferAvailableCallback(BufferAvailableCallback callback); - void SetBufferRemovedCallback(BufferRemovedCallback callback); - - // The queue tracks at most this many buffers. - static constexpr size_t kMaxQueueCapacity = - android::BufferQueueDefs::NUM_BUFFER_SLOTS; - - static constexpr int kNoTimeOut = -1; - - int id() const { return id_; } - bool hung_up() const { return hung_up_; } - - protected: - explicit BufferHubQueue(pdx::LocalChannelHandle channel); - explicit BufferHubQueue(const std::string& endpoint_path); - - // Imports the queue parameters by querying BufferHub for the parameters for - // this channel. - pdx::Status<void> ImportQueue(); - - // Sets up the queue with the given parameters. - void SetupQueue(const QueueInfo& queue_info); - - // Register a buffer for management by the queue. Used by subclasses to add a - // buffer to internal bookkeeping. - pdx::Status<void> AddBuffer(const std::shared_ptr<BufferHubBase>& buffer, - size_t slot); - - // Called by ProducerQueue::RemoveBuffer and ConsumerQueue::RemoveBuffer only - // to deregister a buffer for epoll and internal bookkeeping. - virtual pdx::Status<void> RemoveBuffer(size_t slot); - - // Free all buffers that belongs to this queue. Can only be called from - // producer side. - virtual pdx::Status<void> FreeAllBuffers(); - - // Dequeue a buffer from the free queue, blocking until one is available. The - // timeout argument specifies the number of milliseconds that |Dequeue()| will - // block. Specifying a timeout of -1 causes Dequeue() to block indefinitely, - // while specifying a timeout equal to zero cause Dequeue() to return - // immediately, even if no buffers are available. - pdx::Status<std::shared_ptr<BufferHubBase>> Dequeue(int timeout, - size_t* slot); - - // Waits for buffers to become available and adds them to the available queue. - bool WaitForBuffers(int timeout); - - pdx::Status<void> HandleBufferEvent(size_t slot, int event_fd, - int poll_events); - pdx::Status<void> HandleQueueEvent(int poll_events); - - // Entry in the priority queue of available buffers that stores related - // per-buffer data. - struct Entry { - Entry() : slot(0) {} - Entry(const std::shared_ptr<BufferHubBase>& in_buffer, size_t in_slot, - uint64_t in_index) - : buffer(in_buffer), slot(in_slot), index(in_index) {} - Entry(const std::shared_ptr<BufferHubBase>& in_buffer, - std::unique_ptr<uint8_t[]> in_metadata, pdx::LocalHandle in_fence, - size_t in_slot) - : buffer(in_buffer), - metadata(std::move(in_metadata)), - fence(std::move(in_fence)), - slot(in_slot) {} - Entry(Entry&&) = default; - Entry& operator=(Entry&&) = default; - - std::shared_ptr<BufferHubBase> buffer; - std::unique_ptr<uint8_t[]> metadata; - pdx::LocalHandle fence; - size_t slot; - uint64_t index; - }; - - struct EntryComparator { - bool operator()(const Entry& lhs, const Entry& rhs) { - return lhs.index > rhs.index; - } - }; - - // Enqueues a buffer to the available list (Gained for producer or Acquireed - // for consumer). - pdx::Status<void> Enqueue(Entry entry); - - // Called when a buffer is allocated remotely. - virtual pdx::Status<void> OnBufferAllocated() { return {}; } - - // Size of the metadata that buffers in this queue cary. - size_t user_metadata_size_{0}; - - // Buffers and related data that are available for dequeue. - std::priority_queue<Entry, std::vector<Entry>, EntryComparator> - available_buffers_; - - // Slot of the buffers that are not available for normal dequeue. For example, - // the slot of posted or acquired buffers in the perspective of a producer. - std::vector<size_t> unavailable_buffers_slot_; - - private: - void Initialize(); - - // Special epoll data field indicating that the epoll event refers to the - // queue. - static constexpr int64_t kEpollQueueEventIndex = -1; - - static constexpr size_t kMaxEvents = 128; - - // The u64 data field of an epoll event is interpreted as int64_t: - // When |index| >= 0 and |index| < kMaxQueueCapacity it refers to a specific - // element of |buffers_| as a direct index; - static bool is_buffer_event_index(int64_t index) { - return index >= 0 && - index < static_cast<int64_t>(BufferHubQueue::kMaxQueueCapacity); - } - - // When |index| == kEpollQueueEventIndex it refers to the queue itself. - static bool is_queue_event_index(int64_t index) { - return index == BufferHubQueue::kEpollQueueEventIndex; - } - - // 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. - uint32_t default_width_{1}; - - // Default buffer height that is set during ProducerQueue's creation. - uint32_t default_height_{1}; - - // Default buffer format that is set during ProducerQueue's creation. - uint32_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 - // queue regardless of its queue position or presence in the ring buffer. - std::array<std::shared_ptr<BufferHubBase>, kMaxQueueCapacity> buffers_; - - // Keeps track with how many buffers have been added into the queue. - size_t capacity_{0}; - - // Epoll fd used to manage buffer events. - EpollFileDescriptor epoll_fd_; - - // Flag indicating that the other side hung up. For ProducerQueues this - // triggers when BufferHub dies or explicitly closes the queue channel. For - // ConsumerQueues this can either mean the same or that the ProducerQueue on - // the other end hung up. - bool hung_up_{false}; - - // Global id for the queue that is consistent across processes. - int id_{-1}; - - // Buffer event callbacks - BufferAvailableCallback on_buffer_available_; - BufferRemovedCallback on_buffer_removed_; - - BufferHubQueue(const BufferHubQueue&) = delete; - void operator=(BufferHubQueue&) = delete; -}; - -class ProducerQueue : public pdx::ClientBase<ProducerQueue, BufferHubQueue> { - public: - // 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 - // |usage_set_mask| takes precedence over |usage_clear_mask|. All buffer - // allocation through this producer queue shall not have any of the usage bits - // in |usage_deny_set_mask| set. Allocation calls violating this will be - // rejected. All buffer allocation through this producer queue must have all - // the usage bits in |usage_deny_clear_mask| set. Allocation calls violating - // 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. - static std::unique_ptr<ProducerQueue> Create( - const ProducerQueueConfig& config, const UsagePolicy& usage) { - return BASE::Create(config, usage); - } - - // Import a ProducerQueue from a channel handle. - static std::unique_ptr<ProducerQueue> Import(pdx::LocalChannelHandle handle) { - return BASE::Create(std::move(handle)); - } - - // Get a producer buffer. Note that the method doesn't check whether the - // buffer slot has a valid buffer that has been allocated already. When no - // buffer has been imported before it returns nullptr; otherwise it returns - // a shared pointer to a ProducerBuffer. - std::shared_ptr<ProducerBuffer> GetBuffer(size_t slot) const { - return std::static_pointer_cast<ProducerBuffer>( - BufferHubQueue::GetBuffer(slot)); - } - - // Batch allocate buffers. Once allocated, producer buffers are automatically - // enqueue'd into the ProducerQueue and available to use (i.e. in GAINED - // state). Upon success, returns a list of slots for each buffer allocated. - pdx::Status<std::vector<size_t>> AllocateBuffers( - uint32_t width, uint32_t height, uint32_t layer_count, uint32_t format, - uint64_t usage, size_t buffer_count); - - // Allocate producer buffer to populate the queue. Once allocated, a producer - // buffer is automatically enqueue'd into the ProducerQueue and available to - // use (i.e. in GAINED state). Upon success, returns the slot number for the - // buffer allocated. - pdx::Status<size_t> AllocateBuffer(uint32_t width, uint32_t height, - uint32_t layer_count, uint32_t format, - uint64_t usage); - - // Add a producer buffer to populate the queue. Once added, a producer buffer - // is available to use (i.e. in GAINED state). - pdx::Status<void> AddBuffer(const std::shared_ptr<ProducerBuffer>& buffer, - size_t slot); - - // Inserts a ProducerBuffer into the queue. On success, the method returns the - // |slot| number where the new buffer gets inserted. Note that the buffer - // being inserted should be in Gain'ed state prior to the call and it's - // considered as already Dequeued when the function returns. - pdx::Status<size_t> InsertBuffer( - const std::shared_ptr<ProducerBuffer>& buffer); - - // Remove producer buffer from the queue. - pdx::Status<void> RemoveBuffer(size_t slot) override; - - // Free all buffers on this producer queue. - pdx::Status<void> FreeAllBuffers() override { - return BufferHubQueue::FreeAllBuffers(); - } - - // Dequeue a producer buffer to write. The returned buffer in |Gain|'ed mode, - // and caller should call Post() once it's done writing to release the buffer - // to the consumer side. - // @return a buffer in gained state, which was originally in released state. - pdx::Status<std::shared_ptr<ProducerBuffer>> Dequeue( - int timeout, size_t* slot, pdx::LocalHandle* release_fence); - - // Dequeue a producer buffer to write. The returned buffer in |Gain|'ed mode, - // and caller should call Post() once it's done writing to release the buffer - // to the consumer side. - // - // @param timeout to dequeue a buffer. - // @param slot is the slot of the output ProducerBuffer. - // @param release_fence for gaining a buffer. - // @param out_meta metadata of the output buffer. - // @param gain_posted_buffer whether to gain posted buffer if no released - // buffer is available to gain. - // @return a buffer in gained state, which was originally in released state if - // gain_posted_buffer is false, or in posted/released state if - // gain_posted_buffer is true. - // TODO(b/112007999): gain_posted_buffer true is only used to prevent - // libdvrtracking from starving when there are non-responding clients. This - // gain_posted_buffer param can be removed once libdvrtracking start to use - // the new AHardwareBuffer API. - pdx::Status<std::shared_ptr<ProducerBuffer>> Dequeue( - int timeout, size_t* slot, DvrNativeBufferMetadata* out_meta, - pdx::LocalHandle* release_fence, bool gain_posted_buffer = false); - - // Enqueues a producer buffer in the queue. - pdx::Status<void> Enqueue(const std::shared_ptr<ProducerBuffer>& buffer, - size_t slot, uint64_t index) { - return BufferHubQueue::Enqueue({buffer, slot, index}); - } - - // Takes out the current producer queue as a binder parcelable object. Note - // that the queue must be empty to be exportable. After successful export, the - // producer queue client should no longer be used. - pdx::Status<ProducerQueueParcelable> TakeAsParcelable(); - - private: - friend BASE; - - // Constructors are automatically exposed through ProducerQueue::Create(...) - // static template methods inherited from ClientBase, which take the same - // arguments as the constructors. - explicit ProducerQueue(pdx::LocalChannelHandle handle); - ProducerQueue(const ProducerQueueConfig& config, const UsagePolicy& usage); - - // Dequeue a producer buffer to write. The returned buffer in |Gain|'ed mode, - // and caller should call Post() once it's done writing to release the buffer - // to the consumer side. - // - // @param slot the slot of the returned buffer. - // @return a buffer in gained state, which was originally in posted state or - // released state. - pdx::Status<std::shared_ptr<ProducerBuffer>> DequeueUnacquiredBuffer( - size_t* slot); -}; - -class ConsumerQueue : public BufferHubQueue { - public: - // Get a consumer buffer. Note that the method doesn't check whether the - // buffer slot has a valid buffer that has been imported already. When no - // buffer has been imported before it returns nullptr; otherwise returns a - // shared pointer to a ConsumerBuffer. - std::shared_ptr<ConsumerBuffer> GetBuffer(size_t slot) const { - return std::static_pointer_cast<ConsumerBuffer>( - BufferHubQueue::GetBuffer(slot)); - } - - // Import a ConsumerQueue from a channel handle. |ignore_on_import| controls - // whether or not buffers are set to be ignored when imported. This may be - // used to avoid participation in the buffer lifecycle by a consumer queue - // that is only used to spawn other consumer queues, such as in an - // intermediate service. - static std::unique_ptr<ConsumerQueue> Import(pdx::LocalChannelHandle handle); - - // Import newly created buffers from the service side. - // Returns number of buffers successfully imported or an error. - pdx::Status<size_t> ImportBuffers(); - - // Dequeue a consumer buffer to read. The returned buffer in |Acquired|'ed - // mode, and caller should call Releasse() once it's done writing to release - // the buffer to the producer side. |meta| is passed along from BufferHub, - // The user of ProducerBuffer is responsible with making sure that the - // Dequeue() is done with the corect metadata type and size with those used - // when the buffer is orignally created. - template <typename Meta> - pdx::Status<std::shared_ptr<ConsumerBuffer>> Dequeue( - int timeout, size_t* slot, Meta* meta, pdx::LocalHandle* acquire_fence) { - return Dequeue(timeout, slot, meta, sizeof(*meta), acquire_fence); - } - pdx::Status<std::shared_ptr<ConsumerBuffer>> Dequeue( - int timeout, size_t* slot, pdx::LocalHandle* acquire_fence) { - return Dequeue(timeout, slot, nullptr, 0, acquire_fence); - } - - pdx::Status<std::shared_ptr<ConsumerBuffer>> Dequeue( - int timeout, size_t* slot, void* meta, size_t user_metadata_size, - pdx::LocalHandle* acquire_fence); - pdx::Status<std::shared_ptr<ConsumerBuffer>> Dequeue( - int timeout, size_t* slot, DvrNativeBufferMetadata* out_meta, - pdx::LocalHandle* acquire_fence); - - private: - friend BufferHubQueue; - - explicit ConsumerQueue(pdx::LocalChannelHandle handle); - - // Add a consumer buffer to populate the queue. Once added, a consumer buffer - // is NOT available to use until the producer side |Post| it. |WaitForBuffers| - // will catch the |Post| and |Acquire| the buffer to make it available for - // consumer. - pdx::Status<void> AddBuffer(const std::shared_ptr<ConsumerBuffer>& buffer, - size_t slot); - - pdx::Status<void> OnBufferAllocated() override; -}; - -} // namespace dvr -} // namespace android - -#endif // ANDROID_DVR_BUFFER_HUB_QUEUE_CLIENT_H_ diff --git a/libs/vr/libbufferhubqueue/include/private/dvr/buffer_hub_queue_parcelable.h b/libs/vr/libbufferhubqueue/include/private/dvr/buffer_hub_queue_parcelable.h deleted file mode 100644 index 36ab5f6ac7..0000000000 --- a/libs/vr/libbufferhubqueue/include/private/dvr/buffer_hub_queue_parcelable.h +++ /dev/null @@ -1,74 +0,0 @@ -#ifndef ANDROID_DVR_BUFFER_HUB_QUEUE_PARCELABLE_H_ -#define ANDROID_DVR_BUFFER_HUB_QUEUE_PARCELABLE_H_ - -#if defined(__clang__) -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Weverything" -#endif - -// The following headers are included without checking every warning. -// TODO(b/72172820): Remove the workaround once we have enforced -Weverything -// in these headers and their dependencies. -#include <pdx/channel_parcelable.h> - -#if defined(__clang__) -#pragma clang diagnostic pop -#endif - -namespace android { -namespace dvr { - -enum BufferHubQueueParcelableMagic : uint32_t { - Producer = 0x62687170, // 'bhqp' - Consumer = 0x62687163, // 'bhqc' -}; - -template <BufferHubQueueParcelableMagic Magic> -class BufferHubQueueParcelable : public Parcelable { - public: - BufferHubQueueParcelable() = default; - - BufferHubQueueParcelable(BufferHubQueueParcelable&& other) noexcept = default; - BufferHubQueueParcelable& operator=(BufferHubQueueParcelable&& other) noexcept { - channel_parcelable_ = std::move(other.channel_parcelable_); - return *this; - } - - // Constructs an parcelable contains the channel parcelable. - explicit BufferHubQueueParcelable( - std::unique_ptr<pdx::ChannelParcelable> channel_parcelable) - : channel_parcelable_(std::move(channel_parcelable)) {} - - BufferHubQueueParcelable(const BufferHubQueueParcelable&) = delete; - void operator=(const BufferHubQueueParcelable&) = delete; - - bool IsValid() const; - - // Returns a channel handle constructed from this parcelable object and takes - // the ownership of all resources from the parcelable object. - pdx::LocalChannelHandle TakeChannelHandle(); - - // Serializes the queue parcelable into the given parcel. Note that no system - // resources are getting duplicated, nor did the parcel takes ownership of the - // queue parcelable. Thus, the parcelable object must remain valid for the - // lifetime of the parcel. - status_t writeToParcel(Parcel* parcel) const override; - - // Deserialize the queue parcelable from the given parcel. Note that system - // resources are duplicated from the parcel into the queue parcelable. Returns - // error if the targeting parcelable object is already valid. - status_t readFromParcel(const Parcel* parcel) override; - - private: - std::unique_ptr<pdx::ChannelParcelable> channel_parcelable_; -}; - -using ProducerQueueParcelable = - BufferHubQueueParcelable<BufferHubQueueParcelableMagic::Producer>; -using ConsumerQueueParcelable = - BufferHubQueueParcelable<BufferHubQueueParcelableMagic::Consumer>; - -} // namespace dvr -} // namespace android - -#endif // ANDROID_DVR_BUFFER_HUB_QUEUE_PARCELABLE_H_ diff --git a/libs/vr/libbufferhubqueue/include/private/dvr/epoll_file_descriptor.h b/libs/vr/libbufferhubqueue/include/private/dvr/epoll_file_descriptor.h deleted file mode 100644 index 2f14f7cd91..0000000000 --- a/libs/vr/libbufferhubqueue/include/private/dvr/epoll_file_descriptor.h +++ /dev/null @@ -1,64 +0,0 @@ -#ifndef ANDROID_DVR_EPOLL_FILE_DESCRIPTOR_H_ -#define ANDROID_DVR_EPOLL_FILE_DESCRIPTOR_H_ - -#include <android-base/unique_fd.h> -#include <log/log.h> -#include <sys/epoll.h> - -namespace android { -namespace dvr { - -class EpollFileDescriptor { - public: - static const int CTL_ADD = EPOLL_CTL_ADD; - static const int CTL_MOD = EPOLL_CTL_MOD; - static const int CTL_DEL = EPOLL_CTL_DEL; - - EpollFileDescriptor() : fd_(-1) {} - - // Constructs an EpollFileDescriptor from an integer file descriptor and - // takes ownership. - explicit EpollFileDescriptor(int fd) : fd_(fd) {} - - bool IsValid() const { return fd_.get() >= 0; } - - int Create() { - if (IsValid()) { - ALOGW("epoll fd has already been created."); - return -EALREADY; - } - - fd_.reset(epoll_create1(EPOLL_CLOEXEC)); - - if (fd_.get() < 0) - return -errno; - else - return 0; - } - - int Control(int op, int target_fd, epoll_event* ev) { - if (epoll_ctl(fd_.get(), op, target_fd, ev) < 0) - return -errno; - else - return 0; - } - - int Wait(epoll_event* events, int maxevents, int timeout) { - int ret = epoll_wait(fd_.get(), events, maxevents, timeout); - - if (ret < 0) - return -errno; - else - return ret; - } - - int Get() const { return fd_.get(); } - - private: - base::unique_fd fd_; -}; - -} // namespace dvr -} // namespace android - -#endif // ANDROID_DVR_EPOLL_FILE_DESCRIPTOR_H_ diff --git a/libs/vr/libbufferhubqueue/tests/Android.bp b/libs/vr/libbufferhubqueue/tests/Android.bp deleted file mode 100644 index e373376ab9..0000000000 --- a/libs/vr/libbufferhubqueue/tests/Android.bp +++ /dev/null @@ -1,50 +0,0 @@ - -package { - // See: http://go/android-license-faq - // A large-scale-change added 'default_applicable_licenses' to import - // all of the 'license_kinds' from "frameworks_native_license" - // to get the below license kinds: - // SPDX-license-identifier-Apache-2.0 - default_applicable_licenses: ["frameworks_native_license"], -} - -header_libraries = [ - "libdvr_headers", -] - -shared_libraries = [ - "libbase", - "libbinder", - "libbufferhubqueue", - "libcutils", - "libgui", - "liblog", - "libhardware", - "libui", - "libutils", - "libnativewindow", - "libpdx_default_transport", -] - -static_libraries = [ - "libchrome", - "libdvrcommon", - "libperformance", -] - -cc_test { - srcs: ["buffer_hub_queue-test.cpp"], - header_libs: header_libraries, - static_libs: static_libraries, - shared_libs: shared_libraries, - cflags: [ - "-DLOG_TAG=\"buffer_hub_queue-test\"", - "-DTRACE=0", - "-O0", - "-g", - "-Wall", - "-Werror", - "-Wno-error=sign-compare", // to fix later - ], - name: "buffer_hub_queue-test", -} diff --git a/libs/vr/libbufferhubqueue/tests/buffer_hub_queue-test.cpp b/libs/vr/libbufferhubqueue/tests/buffer_hub_queue-test.cpp deleted file mode 100644 index 6ae603b892..0000000000 --- a/libs/vr/libbufferhubqueue/tests/buffer_hub_queue-test.cpp +++ /dev/null @@ -1,1083 +0,0 @@ -#include <base/logging.h> -#include <binder/Parcel.h> -#include <dvr/dvr_api.h> -#include <private/dvr/buffer_hub_queue_client.h> -#include <private/dvr/consumer_buffer.h> -#include <private/dvr/producer_buffer.h> - -#include <gtest/gtest.h> -#include <poll.h> -#include <sys/eventfd.h> - -#include <vector> - -// Enable/disable debug logging. -#define TRACE 0 - -namespace android { -namespace dvr { - -using pdx::LocalChannelHandle; -using pdx::LocalHandle; - -namespace { - -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; -constexpr int kTimeoutMs = 100; -constexpr int kNoTimeout = 0; - -class BufferHubQueueTest : public ::testing::Test { - public: - bool CreateProducerQueue(const ProducerQueueConfig& config, - const UsagePolicy& usage) { - producer_queue_ = ProducerQueue::Create(config, usage); - return producer_queue_ != nullptr; - } - - bool CreateConsumerQueue() { - if (producer_queue_) { - consumer_queue_ = producer_queue_->CreateConsumerQueue(); - return consumer_queue_ != nullptr; - } else { - return false; - } - } - - bool CreateQueues(const ProducerQueueConfig& config, - const UsagePolicy& usage) { - return CreateProducerQueue(config, usage) && CreateConsumerQueue(); - } - - void AllocateBuffer(size_t* slot_out = nullptr) { - // Create producer buffer. - auto status = producer_queue_->AllocateBuffer(kBufferWidth, kBufferHeight, - kBufferLayerCount, - kBufferFormat, kBufferUsage); - - ASSERT_TRUE(status.ok()); - size_t slot = status.take(); - if (slot_out) - *slot_out = slot; - } - - bool WaitAndHandleOnce(BufferHubQueue* queue, int timeout_ms) { - pollfd pfd{queue->queue_fd(), POLLIN, 0}; - int ret; - do { - ret = poll(&pfd, 1, timeout_ms); - } while (ret == -1 && errno == EINTR); - - if (ret < 0) { - ALOGW("Failed to poll queue %d's event fd, error: %s.", queue->id(), - strerror(errno)); - return false; - } else if (ret == 0) { - return false; - } - return queue->HandleQueueEvents(); - } - - protected: - ProducerQueueConfigBuilder config_builder_; - std::unique_ptr<ProducerQueue> producer_queue_; - std::unique_ptr<ConsumerQueue> consumer_queue_; -}; - -TEST_F(BufferHubQueueTest, TestDequeue) { - const int64_t nb_dequeue_times = 16; - - ASSERT_TRUE(CreateQueues(config_builder_.Build(), UsagePolicy{})); - - // Allocate only one buffer. - AllocateBuffer(); - - // But dequeue multiple times. - for (int64_t i = 0; i < nb_dequeue_times; i++) { - size_t slot; - LocalHandle fence; - DvrNativeBufferMetadata mi, mo; - - // Producer gains a buffer. - auto p1_status = producer_queue_->Dequeue(kTimeoutMs, &slot, &mo, &fence); - EXPECT_TRUE(p1_status.ok()); - auto p1 = p1_status.take(); - ASSERT_NE(p1, nullptr); - - // Producer posts the buffer. - mi.index = i; - EXPECT_EQ(p1->PostAsync(&mi, LocalHandle()), 0); - - // Consumer acquires a buffer. - auto c1_status = consumer_queue_->Dequeue(kTimeoutMs, &slot, &mo, &fence); - EXPECT_TRUE(c1_status.ok()) << c1_status.GetErrorMessage(); - auto c1 = c1_status.take(); - ASSERT_NE(c1, nullptr); - EXPECT_EQ(mi.index, i); - EXPECT_EQ(mo.index, i); - - // Consumer releases the buffer. - EXPECT_EQ(c1->ReleaseAsync(&mi, LocalHandle()), 0); - } -} - -TEST_F(BufferHubQueueTest, - TestDequeuePostedBufferIfNoAvailableReleasedBuffer_withConsumerBuffer) { - ASSERT_TRUE(CreateQueues(config_builder_.Build(), UsagePolicy{})); - - // Allocate 3 buffers to use. - const size_t test_queue_capacity = 3; - for (int64_t i = 0; i < test_queue_capacity; i++) { - AllocateBuffer(); - } - EXPECT_EQ(producer_queue_->capacity(), test_queue_capacity); - - size_t producer_slot, consumer_slot; - LocalHandle fence; - DvrNativeBufferMetadata mi, mo; - - // Producer posts 2 buffers and remember their posted sequence. - std::deque<size_t> posted_slots; - for (int64_t i = 0; i < 2; i++) { - auto p1_status = - producer_queue_->Dequeue(kTimeoutMs, &producer_slot, &mo, &fence, true); - EXPECT_TRUE(p1_status.ok()); - auto p1 = p1_status.take(); - ASSERT_NE(p1, nullptr); - - // Producer should not be gaining posted buffer when there are still - // available buffers to gain. - auto found_iter = - std::find(posted_slots.begin(), posted_slots.end(), producer_slot); - EXPECT_EQ(found_iter, posted_slots.end()); - posted_slots.push_back(producer_slot); - - // Producer posts the buffer. - mi.index = i; - EXPECT_EQ(0, p1->PostAsync(&mi, LocalHandle())); - } - - // Consumer acquires one buffer. - auto c1_status = - consumer_queue_->Dequeue(kTimeoutMs, &consumer_slot, &mo, &fence); - EXPECT_TRUE(c1_status.ok()); - auto c1 = c1_status.take(); - ASSERT_NE(c1, nullptr); - // Consumer should get the oldest posted buffer. No checks here. - // posted_slots[0] should be in acquired state now. - EXPECT_EQ(mo.index, 0); - // Consumer releases the buffer. - EXPECT_EQ(c1->ReleaseAsync(&mi, LocalHandle()), 0); - // posted_slots[0] should be in released state now. - - // Producer gain and post 2 buffers. - for (int64_t i = 0; i < 2; i++) { - auto p1_status = - producer_queue_->Dequeue(kTimeoutMs, &producer_slot, &mo, &fence, true); - EXPECT_TRUE(p1_status.ok()); - auto p1 = p1_status.take(); - ASSERT_NE(p1, nullptr); - - // The gained buffer should be the one in released state or the one haven't - // been use. - EXPECT_NE(posted_slots[1], producer_slot); - - mi.index = i + 2; - EXPECT_EQ(0, p1->PostAsync(&mi, LocalHandle())); - } - - // Producer gains a buffer. - auto p1_status = - producer_queue_->Dequeue(kTimeoutMs, &producer_slot, &mo, &fence, true); - EXPECT_TRUE(p1_status.ok()); - auto p1 = p1_status.take(); - ASSERT_NE(p1, nullptr); - - // The gained buffer should be the oldest posted buffer. - EXPECT_EQ(posted_slots[1], producer_slot); - - // Producer posts the buffer. - mi.index = 4; - EXPECT_EQ(0, p1->PostAsync(&mi, LocalHandle())); -} - -TEST_F(BufferHubQueueTest, - TestDequeuePostedBufferIfNoAvailableReleasedBuffer_noConsumerBuffer) { - ASSERT_TRUE(CreateQueues(config_builder_.Build(), UsagePolicy{})); - - // Allocate 4 buffers to use. - const size_t test_queue_capacity = 4; - for (int64_t i = 0; i < test_queue_capacity; i++) { - AllocateBuffer(); - } - EXPECT_EQ(producer_queue_->capacity(), test_queue_capacity); - - // Post all allowed buffers and remember their posted sequence. - std::deque<size_t> posted_slots; - for (int64_t i = 0; i < test_queue_capacity; i++) { - size_t slot; - LocalHandle fence; - DvrNativeBufferMetadata mi, mo; - - // Producer gains a buffer. - auto p1_status = - producer_queue_->Dequeue(kTimeoutMs, &slot, &mo, &fence, true); - EXPECT_TRUE(p1_status.ok()); - auto p1 = p1_status.take(); - ASSERT_NE(p1, nullptr); - - // Producer should not be gaining posted buffer when there are still - // available buffers to gain. - auto found_iter = std::find(posted_slots.begin(), posted_slots.end(), slot); - EXPECT_EQ(found_iter, posted_slots.end()); - posted_slots.push_back(slot); - - // Producer posts the buffer. - mi.index = i; - EXPECT_EQ(p1->PostAsync(&mi, LocalHandle()), 0); - } - - // Gain posted buffers in sequence. - const int64_t nb_dequeue_all_times = 2; - for (int j = 0; j < nb_dequeue_all_times; ++j) { - for (int i = 0; i < test_queue_capacity; ++i) { - size_t slot; - LocalHandle fence; - DvrNativeBufferMetadata mi, mo; - - // Producer gains a buffer. - auto p1_status = - producer_queue_->Dequeue(kTimeoutMs, &slot, &mo, &fence, true); - EXPECT_TRUE(p1_status.ok()); - auto p1 = p1_status.take(); - ASSERT_NE(p1, nullptr); - - // The gained buffer should be the oldest posted buffer. - EXPECT_EQ(posted_slots[i], slot); - - // Producer posts the buffer. - mi.index = i + test_queue_capacity * (j + 1); - EXPECT_EQ(p1->PostAsync(&mi, LocalHandle()), 0); - } - } -} - -TEST_F(BufferHubQueueTest, TestProducerConsumer) { - const size_t kBufferCount = 16; - size_t slot; - DvrNativeBufferMetadata mi, mo; - LocalHandle fence; - - ASSERT_TRUE(CreateQueues(config_builder_.Build(), UsagePolicy{})); - - for (size_t i = 0; i < kBufferCount; i++) { - AllocateBuffer(); - - // Producer queue has all the available buffers on initialize. - ASSERT_EQ(producer_queue_->count(), i + 1); - ASSERT_EQ(producer_queue_->capacity(), i + 1); - - // Consumer queue has no avaiable buffer on initialize. - ASSERT_EQ(consumer_queue_->count(), 0U); - // Consumer queue does not import buffers until a dequeue is issued. - ASSERT_EQ(consumer_queue_->capacity(), i); - // Dequeue returns timeout since no buffer is ready to consumer, but - // this implicitly triggers buffer import and bump up |capacity|. - auto status = consumer_queue_->Dequeue(kNoTimeout, &slot, &mo, &fence); - ASSERT_FALSE(status.ok()); - ASSERT_EQ(ETIMEDOUT, status.error()); - ASSERT_EQ(consumer_queue_->capacity(), i + 1); - } - - // Use eventfd as a stand-in for a fence. - LocalHandle post_fence(eventfd(0, EFD_CLOEXEC | EFD_NONBLOCK)); - - for (size_t i = 0; i < kBufferCount; i++) { - // First time there is no buffer available to dequeue. - auto consumer_status = - consumer_queue_->Dequeue(kNoTimeout, &slot, &mo, &fence); - ASSERT_FALSE(consumer_status.ok()); - ASSERT_EQ(consumer_status.error(), ETIMEDOUT); - - // Make sure Producer buffer is POSTED so that it's ready to Accquire - // in the consumer's Dequeue() function. - auto producer_status = - producer_queue_->Dequeue(kTimeoutMs, &slot, &mo, &fence); - ASSERT_TRUE(producer_status.ok()); - auto producer = producer_status.take(); - ASSERT_NE(nullptr, producer); - - mi.index = static_cast<int64_t>(i); - ASSERT_EQ(producer->PostAsync(&mi, post_fence), 0); - - // Second time the just the POSTED buffer should be dequeued. - consumer_status = consumer_queue_->Dequeue(kTimeoutMs, &slot, &mo, &fence); - ASSERT_TRUE(consumer_status.ok()); - EXPECT_TRUE(fence.IsValid()); - - auto consumer = consumer_status.take(); - ASSERT_NE(nullptr, consumer); - ASSERT_EQ(mi.index, mo.index); - } -} - -TEST_F(BufferHubQueueTest, TestInsertBuffer) { - ASSERT_TRUE(CreateProducerQueue(config_builder_.Build(), UsagePolicy{})); - - consumer_queue_ = producer_queue_->CreateConsumerQueue(); - ASSERT_TRUE(consumer_queue_ != nullptr); - EXPECT_EQ(producer_queue_->capacity(), 0); - EXPECT_EQ(consumer_queue_->capacity(), 0); - - std::shared_ptr<ProducerBuffer> p1 = ProducerBuffer::Create( - kBufferWidth, kBufferHeight, kBufferFormat, kBufferUsage, 0); - ASSERT_TRUE(p1 != nullptr); - ASSERT_EQ(p1->GainAsync(), 0); - - // Inserting a posted buffer will fail. - DvrNativeBufferMetadata meta; - EXPECT_EQ(p1->PostAsync(&meta, LocalHandle()), 0); - auto status_or_slot = producer_queue_->InsertBuffer(p1); - EXPECT_FALSE(status_or_slot.ok()); - EXPECT_EQ(status_or_slot.error(), EINVAL); - - // Inserting a gained buffer will succeed. - std::shared_ptr<ProducerBuffer> p2 = ProducerBuffer::Create( - kBufferWidth, kBufferHeight, kBufferFormat, kBufferUsage); - ASSERT_EQ(p2->GainAsync(), 0); - ASSERT_TRUE(p2 != nullptr); - status_or_slot = producer_queue_->InsertBuffer(p2); - EXPECT_TRUE(status_or_slot.ok()) << status_or_slot.GetErrorMessage(); - // This is the first buffer inserted, should take slot 0. - size_t slot = status_or_slot.get(); - EXPECT_EQ(slot, 0); - - // Wait and expect the consumer to kick up the newly inserted buffer. - WaitAndHandleOnce(consumer_queue_.get(), kTimeoutMs); - EXPECT_EQ(consumer_queue_->capacity(), 1ULL); -} - -TEST_F(BufferHubQueueTest, TestRemoveBuffer) { - ASSERT_TRUE(CreateProducerQueue(config_builder_.Build(), UsagePolicy{})); - DvrNativeBufferMetadata mo; - - // Allocate buffers. - const size_t kBufferCount = 4u; - for (size_t i = 0; i < kBufferCount; i++) { - AllocateBuffer(); - } - ASSERT_EQ(kBufferCount, producer_queue_->count()); - ASSERT_EQ(kBufferCount, producer_queue_->capacity()); - - consumer_queue_ = producer_queue_->CreateConsumerQueue(); - ASSERT_NE(nullptr, consumer_queue_); - - // Check that buffers are correctly imported on construction. - EXPECT_EQ(kBufferCount, consumer_queue_->capacity()); - EXPECT_EQ(0u, consumer_queue_->count()); - - // Dequeue all the buffers and keep track of them in an array. This prevents - // the producer queue ring buffer ref counts from interfering with the tests. - struct Entry { - std::shared_ptr<ProducerBuffer> buffer; - LocalHandle fence; - size_t slot; - }; - std::array<Entry, kBufferCount> buffers; - - for (size_t i = 0; i < kBufferCount; i++) { - Entry* entry = &buffers[i]; - auto producer_status = - producer_queue_->Dequeue(kTimeoutMs, &entry->slot, &mo, &entry->fence); - ASSERT_TRUE(producer_status.ok()); - entry->buffer = producer_status.take(); - ASSERT_NE(nullptr, entry->buffer); - } - - // Remove a buffer and make sure both queues reflect the change. - ASSERT_TRUE(producer_queue_->RemoveBuffer(buffers[0].slot)); - EXPECT_EQ(kBufferCount - 1, producer_queue_->capacity()); - - // As long as the removed buffer is still alive the consumer queue won't know - // its gone. - EXPECT_EQ(kBufferCount, consumer_queue_->capacity()); - EXPECT_FALSE(consumer_queue_->HandleQueueEvents()); - EXPECT_EQ(kBufferCount, consumer_queue_->capacity()); - - // Release the removed buffer. - buffers[0].buffer = nullptr; - - // Now the consumer queue should know it's gone. - EXPECT_FALSE(WaitAndHandleOnce(consumer_queue_.get(), kTimeoutMs)); - ASSERT_EQ(kBufferCount - 1, consumer_queue_->capacity()); - - // Allocate a new buffer. This should take the first empty slot. - size_t slot; - AllocateBuffer(&slot); - ALOGE_IF(TRACE, "ALLOCATE %zu", slot); - EXPECT_EQ(buffers[0].slot, slot); - EXPECT_EQ(kBufferCount, producer_queue_->capacity()); - - // The consumer queue should pick up the new buffer. - EXPECT_EQ(kBufferCount - 1, consumer_queue_->capacity()); - EXPECT_FALSE(consumer_queue_->HandleQueueEvents()); - EXPECT_EQ(kBufferCount, consumer_queue_->capacity()); - - // Remove and allocate a buffer. - ASSERT_TRUE(producer_queue_->RemoveBuffer(buffers[1].slot)); - EXPECT_EQ(kBufferCount - 1, producer_queue_->capacity()); - buffers[1].buffer = nullptr; - - AllocateBuffer(&slot); - ALOGE_IF(TRACE, "ALLOCATE %zu", slot); - EXPECT_EQ(buffers[1].slot, slot); - EXPECT_EQ(kBufferCount, producer_queue_->capacity()); - - // The consumer queue should pick up the new buffer but the count shouldn't - // change. - EXPECT_EQ(kBufferCount, consumer_queue_->capacity()); - EXPECT_FALSE(consumer_queue_->HandleQueueEvents()); - EXPECT_EQ(kBufferCount, consumer_queue_->capacity()); - - // Remove and allocate a buffer, but don't free the buffer right away. - ASSERT_TRUE(producer_queue_->RemoveBuffer(buffers[2].slot)); - EXPECT_EQ(kBufferCount - 1, producer_queue_->capacity()); - - AllocateBuffer(&slot); - ALOGE_IF(TRACE, "ALLOCATE %zu", slot); - EXPECT_EQ(buffers[2].slot, slot); - EXPECT_EQ(kBufferCount, producer_queue_->capacity()); - - EXPECT_EQ(kBufferCount, consumer_queue_->capacity()); - EXPECT_FALSE(consumer_queue_->HandleQueueEvents()); - EXPECT_EQ(kBufferCount, consumer_queue_->capacity()); - - // Release the producer buffer to trigger a POLLHUP event for an already - // removed buffer. - buffers[2].buffer = nullptr; - EXPECT_EQ(kBufferCount, consumer_queue_->capacity()); - EXPECT_FALSE(consumer_queue_->HandleQueueEvents()); - EXPECT_EQ(kBufferCount, consumer_queue_->capacity()); -} - -TEST_F(BufferHubQueueTest, TestMultipleConsumers) { - // 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; - for (size_t i = 0; i < kBufferCount; i++) { - AllocateBuffer(); - } - ASSERT_EQ(kBufferCount, producer_queue_->count()); - - // Build a silent consumer queue to test multi-consumer queue features. - auto silent_queue = producer_queue_->CreateSilentConsumerQueue(); - ASSERT_NE(nullptr, silent_queue); - - // Check that silent queue doesn't import buffers on creation. - EXPECT_EQ(silent_queue->capacity(), 0U); - - // Dequeue and post a buffer. - size_t slot; - LocalHandle fence; - DvrNativeBufferMetadata mi, mo; - auto producer_status = - producer_queue_->Dequeue(kTimeoutMs, &slot, &mo, &fence); - EXPECT_TRUE(producer_status.ok()); - auto producer_buffer = producer_status.take(); - ASSERT_NE(producer_buffer, nullptr); - EXPECT_EQ(producer_buffer->PostAsync(&mi, {}), 0); - // After post, check the number of remaining available buffers. - EXPECT_EQ(producer_queue_->count(), kBufferCount - 1); - - // Currently we expect no buffer to be available prior to calling - // WaitForBuffers/HandleQueueEvents. - // TODO(eieio): Note this behavior may change in the future. - EXPECT_EQ(silent_queue->count(), 0U); - EXPECT_FALSE(silent_queue->HandleQueueEvents()); - EXPECT_EQ(silent_queue->count(), 0U); - - // Build a new consumer queue to test multi-consumer queue features. - consumer_queue_ = silent_queue->CreateConsumerQueue(); - ASSERT_NE(consumer_queue_, nullptr); - - // Check that buffers are correctly imported on construction. - EXPECT_EQ(consumer_queue_->capacity(), kBufferCount); - // Buffers are only imported, but their availability is not checked until - // first call to Dequeue(). - EXPECT_EQ(consumer_queue_->count(), 0U); - - // Reclaim released/ignored buffers. - EXPECT_EQ(producer_queue_->count(), kBufferCount - 1); - - usleep(10000); - WaitAndHandleOnce(producer_queue_.get(), kTimeoutMs); - EXPECT_EQ(producer_queue_->count(), kBufferCount - 1); - - // Post another buffer. - producer_status = producer_queue_->Dequeue(kTimeoutMs, &slot, &mo, &fence); - EXPECT_TRUE(producer_status.ok()); - producer_buffer = producer_status.take(); - ASSERT_NE(producer_buffer, nullptr); - EXPECT_EQ(producer_buffer->PostAsync(&mi, {}), 0); - - // Verify that the consumer queue receives it. - size_t consumer_queue_count = consumer_queue_->count(); - WaitAndHandleOnce(consumer_queue_.get(), kTimeoutMs); - EXPECT_GT(consumer_queue_->count(), consumer_queue_count); - - // Save the current consumer queue buffer count to compare after the dequeue. - consumer_queue_count = consumer_queue_->count(); - - // Dequeue and acquire/release (discard) buffers on the consumer end. - auto consumer_status = - consumer_queue_->Dequeue(kTimeoutMs, &slot, &mo, &fence); - EXPECT_TRUE(consumer_status.ok()); - auto consumer_buffer = consumer_status.take(); - ASSERT_NE(consumer_buffer, nullptr); - consumer_buffer->Discard(); - - // Buffer should be returned to the producer queue without being handled by - // the silent consumer queue. - EXPECT_LT(consumer_queue_->count(), consumer_queue_count); - EXPECT_EQ(producer_queue_->count(), kBufferCount - 2); - - WaitAndHandleOnce(producer_queue_.get(), kTimeoutMs); - EXPECT_EQ(producer_queue_->count(), kBufferCount - 1); -} - -struct TestUserMetadata { - char a; - int32_t b; - int64_t c; -}; - -constexpr uint64_t kUserMetadataSize = - static_cast<uint64_t>(sizeof(TestUserMetadata)); - -TEST_F(BufferHubQueueTest, TestUserMetadata) { - ASSERT_TRUE(CreateQueues( - config_builder_.SetMetadata<TestUserMetadata>().Build(), UsagePolicy{})); - - AllocateBuffer(); - - std::vector<TestUserMetadata> user_metadata_list = { - {'0', 0, 0}, {'1', 10, 3333}, {'@', 123, 1000000000}}; - - for (auto user_metadata : user_metadata_list) { - size_t slot; - LocalHandle fence; - DvrNativeBufferMetadata mi, mo; - - auto p1_status = producer_queue_->Dequeue(kTimeoutMs, &slot, &mo, &fence); - EXPECT_TRUE(p1_status.ok()); - auto p1 = p1_status.take(); - ASSERT_NE(p1, nullptr); - - // TODO(b/69469185): Test against metadata from consumer once we implement - // release metadata properly. - // EXPECT_EQ(mo.user_metadata_ptr, 0U); - // EXPECT_EQ(mo.user_metadata_size, 0U); - - mi.user_metadata_size = kUserMetadataSize; - mi.user_metadata_ptr = reinterpret_cast<uint64_t>(&user_metadata); - EXPECT_EQ(p1->PostAsync(&mi, {}), 0); - auto c1_status = consumer_queue_->Dequeue(kTimeoutMs, &slot, &mo, &fence); - EXPECT_TRUE(c1_status.ok()) << c1_status.GetErrorMessage(); - auto c1 = c1_status.take(); - ASSERT_NE(c1, nullptr); - - EXPECT_EQ(mo.user_metadata_size, kUserMetadataSize); - auto out_user_metadata = - reinterpret_cast<TestUserMetadata*>(mo.user_metadata_ptr); - EXPECT_EQ(user_metadata.a, out_user_metadata->a); - EXPECT_EQ(user_metadata.b, out_user_metadata->b); - EXPECT_EQ(user_metadata.c, out_user_metadata->c); - - // When release, empty metadata is also legit. - mi.user_metadata_size = 0U; - mi.user_metadata_ptr = 0U; - c1->ReleaseAsync(&mi, {}); - } -} - -TEST_F(BufferHubQueueTest, TestUserMetadataMismatch) { - ASSERT_TRUE(CreateQueues( - config_builder_.SetMetadata<TestUserMetadata>().Build(), UsagePolicy{})); - - AllocateBuffer(); - - TestUserMetadata user_metadata; - size_t slot; - LocalHandle fence; - DvrNativeBufferMetadata mi, mo; - auto p1_status = producer_queue_->Dequeue(kTimeoutMs, &slot, &mo, &fence); - EXPECT_TRUE(p1_status.ok()); - auto p1 = p1_status.take(); - ASSERT_NE(p1, nullptr); - - // Post with mismatched user metadata size will fail. But the producer buffer - // itself should stay untouched. - mi.user_metadata_ptr = reinterpret_cast<uint64_t>(&user_metadata); - mi.user_metadata_size = kUserMetadataSize + 1; - EXPECT_EQ(p1->PostAsync(&mi, {}), -E2BIG); - // Post with the exact same user metdata size can success. - mi.user_metadata_ptr = reinterpret_cast<uint64_t>(&user_metadata); - mi.user_metadata_size = kUserMetadataSize; - EXPECT_EQ(p1->PostAsync(&mi, {}), 0); -} - -TEST_F(BufferHubQueueTest, TestEnqueue) { - ASSERT_TRUE(CreateQueues(config_builder_.SetMetadata<int64_t>().Build(), - UsagePolicy{})); - AllocateBuffer(); - - size_t slot; - LocalHandle fence; - DvrNativeBufferMetadata mo; - auto p1_status = producer_queue_->Dequeue(kTimeoutMs, &slot, &mo, &fence); - ASSERT_TRUE(p1_status.ok()); - auto p1 = p1_status.take(); - ASSERT_NE(nullptr, p1); - - producer_queue_->Enqueue(p1, slot, 0ULL); - auto c1_status = consumer_queue_->Dequeue(kTimeoutMs, &slot, &mo, &fence); - ASSERT_FALSE(c1_status.ok()); -} - -TEST_F(BufferHubQueueTest, TestAllocateBuffer) { - ASSERT_TRUE(CreateQueues(config_builder_.Build(), UsagePolicy{})); - - size_t ps1; - AllocateBuffer(); - LocalHandle fence; - DvrNativeBufferMetadata mi, mo; - auto p1_status = producer_queue_->Dequeue(kTimeoutMs, &ps1, &mo, &fence); - ASSERT_TRUE(p1_status.ok()); - auto p1 = p1_status.take(); - ASSERT_NE(p1, nullptr); - - // producer queue is exhausted - size_t ps2; - auto p2_status = producer_queue_->Dequeue(kTimeoutMs, &ps2, &mo, &fence); - ASSERT_FALSE(p2_status.ok()); - ASSERT_EQ(ETIMEDOUT, p2_status.error()); - - // dynamically add buffer. - AllocateBuffer(); - ASSERT_EQ(producer_queue_->count(), 1U); - ASSERT_EQ(producer_queue_->capacity(), 2U); - - // now we can dequeue again - p2_status = producer_queue_->Dequeue(kTimeoutMs, &ps2, &mo, &fence); - ASSERT_TRUE(p2_status.ok()); - auto p2 = p2_status.take(); - ASSERT_NE(p2, nullptr); - ASSERT_EQ(producer_queue_->count(), 0U); - // p1 and p2 should have different slot number - ASSERT_NE(ps1, ps2); - - // Consumer queue does not import buffers until |Dequeue| or |ImportBuffers| - // are called. So far consumer_queue_ should be empty. - ASSERT_EQ(consumer_queue_->count(), 0U); - - int64_t seq = 1; - mi.index = seq; - ASSERT_EQ(p1->PostAsync(&mi, {}), 0); - - size_t cs1, cs2; - auto c1_status = consumer_queue_->Dequeue(kTimeoutMs, &cs1, &mo, &fence); - ASSERT_TRUE(c1_status.ok()) << c1_status.GetErrorMessage(); - auto c1 = c1_status.take(); - ASSERT_NE(c1, nullptr); - ASSERT_EQ(consumer_queue_->count(), 0U); - ASSERT_EQ(consumer_queue_->capacity(), 2U); - ASSERT_EQ(cs1, ps1); - - ASSERT_EQ(p2->PostAsync(&mi, {}), 0); - auto c2_status = consumer_queue_->Dequeue(kTimeoutMs, &cs2, &mo, &fence); - ASSERT_TRUE(c2_status.ok()); - auto c2 = c2_status.take(); - ASSERT_NE(c2, nullptr); - ASSERT_EQ(cs2, ps2); -} - -TEST_F(BufferHubQueueTest, TestAllocateTwoBuffers) { - ASSERT_TRUE(CreateQueues(config_builder_.Build(), UsagePolicy{})); - ASSERT_EQ(producer_queue_->capacity(), 0); - auto status = producer_queue_->AllocateBuffers( - kBufferWidth, kBufferHeight, kBufferLayerCount, kBufferFormat, - kBufferUsage, /*buffer_count=*/2); - ASSERT_TRUE(status.ok()); - std::vector<size_t> buffer_slots = status.take(); - ASSERT_EQ(buffer_slots.size(), 2); - ASSERT_EQ(producer_queue_->capacity(), 2); -} - -TEST_F(BufferHubQueueTest, TestAllocateZeroBuffers) { - ASSERT_TRUE(CreateQueues(config_builder_.Build(), UsagePolicy{})); - ASSERT_EQ(producer_queue_->capacity(), 0); - auto status = producer_queue_->AllocateBuffers( - kBufferWidth, kBufferHeight, kBufferLayerCount, kBufferFormat, - kBufferUsage, /*buffer_count=*/0); - ASSERT_TRUE(status.ok()); - std::vector<size_t> buffer_slots = status.take(); - ASSERT_EQ(buffer_slots.size(), 0); - ASSERT_EQ(producer_queue_->capacity(), 0); -} - -TEST_F(BufferHubQueueTest, TestUsageSetMask) { - const uint32_t set_mask = GRALLOC_USAGE_SW_WRITE_OFTEN; - ASSERT_TRUE( - CreateQueues(config_builder_.Build(), UsagePolicy{set_mask, 0, 0, 0})); - - // When allocation, leave out |set_mask| from usage bits on purpose. - auto status = producer_queue_->AllocateBuffer( - kBufferWidth, kBufferHeight, kBufferLayerCount, kBufferFormat, - kBufferUsage & ~set_mask); - ASSERT_TRUE(status.ok()); - - LocalHandle fence; - size_t slot; - DvrNativeBufferMetadata mo; - auto p1_status = producer_queue_->Dequeue(kTimeoutMs, &slot, &mo, &fence); - ASSERT_TRUE(p1_status.ok()); - auto p1 = p1_status.take(); - ASSERT_EQ(p1->usage() & set_mask, set_mask); -} - -TEST_F(BufferHubQueueTest, TestUsageClearMask) { - const uint32_t clear_mask = GRALLOC_USAGE_SW_WRITE_OFTEN; - ASSERT_TRUE( - CreateQueues(config_builder_.Build(), UsagePolicy{0, clear_mask, 0, 0})); - - // When allocation, add |clear_mask| into usage bits on purpose. - auto status = producer_queue_->AllocateBuffer( - kBufferWidth, kBufferHeight, kBufferLayerCount, kBufferFormat, - kBufferUsage | clear_mask); - ASSERT_TRUE(status.ok()); - - LocalHandle fence; - size_t slot; - DvrNativeBufferMetadata mo; - auto p1_status = producer_queue_->Dequeue(kTimeoutMs, &slot, &mo, &fence); - ASSERT_TRUE(p1_status.ok()); - auto p1 = p1_status.take(); - ASSERT_EQ(p1->usage() & clear_mask, 0U); -} - -TEST_F(BufferHubQueueTest, TestUsageDenySetMask) { - const uint32_t deny_set_mask = GRALLOC_USAGE_SW_WRITE_OFTEN; - 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. - auto status = producer_queue_->AllocateBuffer( - kBufferWidth, kBufferHeight, kBufferLayerCount, kBufferFormat, - kBufferUsage & ~deny_set_mask); - ASSERT_TRUE(status.ok()); - - // While allocation with those bits should fail. - status = producer_queue_->AllocateBuffer(kBufferWidth, kBufferHeight, - kBufferLayerCount, kBufferFormat, - kBufferUsage | deny_set_mask); - ASSERT_FALSE(status.ok()); - ASSERT_EQ(EINVAL, status.error()); -} - -TEST_F(BufferHubQueueTest, TestUsageDenyClearMask) { - const uint32_t deny_clear_mask = GRALLOC_USAGE_SW_WRITE_OFTEN; - 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. - auto status = producer_queue_->AllocateBuffer( - kBufferWidth, kBufferHeight, kBufferLayerCount, kBufferFormat, - kBufferUsage | deny_clear_mask); - ASSERT_TRUE(status.ok()); - - // While allocation without those bits should fail. - status = producer_queue_->AllocateBuffer(kBufferWidth, kBufferHeight, - kBufferLayerCount, kBufferFormat, - kBufferUsage & ~deny_clear_mask); - ASSERT_FALSE(status.ok()); - 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); -} - -TEST_F(BufferHubQueueTest, TestFreeAllBuffers) { - constexpr size_t kBufferCount = 2; - -#define CHECK_NO_BUFFER_THEN_ALLOCATE(num_buffers) \ - EXPECT_EQ(consumer_queue_->count(), 0U); \ - EXPECT_EQ(consumer_queue_->capacity(), 0U); \ - EXPECT_EQ(producer_queue_->count(), 0U); \ - EXPECT_EQ(producer_queue_->capacity(), 0U); \ - for (size_t i = 0; i < num_buffers; i++) { \ - AllocateBuffer(); \ - } \ - EXPECT_EQ(producer_queue_->count(), num_buffers); \ - EXPECT_EQ(producer_queue_->capacity(), num_buffers); - - size_t slot; - LocalHandle fence; - pdx::Status<void> status; - pdx::Status<std::shared_ptr<ConsumerBuffer>> consumer_status; - pdx::Status<std::shared_ptr<ProducerBuffer>> producer_status; - std::shared_ptr<ConsumerBuffer> consumer_buffer; - std::shared_ptr<ProducerBuffer> producer_buffer; - DvrNativeBufferMetadata mi, mo; - - ASSERT_TRUE(CreateQueues(config_builder_.Build(), UsagePolicy{})); - - // Free all buffers when buffers are avaible for dequeue. - CHECK_NO_BUFFER_THEN_ALLOCATE(kBufferCount); - status = producer_queue_->FreeAllBuffers(); - EXPECT_TRUE(status.ok()); - - // Free all buffers when one buffer is dequeued. - CHECK_NO_BUFFER_THEN_ALLOCATE(kBufferCount); - producer_status = producer_queue_->Dequeue(kTimeoutMs, &slot, &mo, &fence); - ASSERT_TRUE(producer_status.ok()); - status = producer_queue_->FreeAllBuffers(); - EXPECT_TRUE(status.ok()); - - // Free all buffers when all buffers are dequeued. - CHECK_NO_BUFFER_THEN_ALLOCATE(kBufferCount); - for (size_t i = 0; i < kBufferCount; i++) { - producer_status = producer_queue_->Dequeue(kTimeoutMs, &slot, &mo, &fence); - ASSERT_TRUE(producer_status.ok()); - } - status = producer_queue_->FreeAllBuffers(); - EXPECT_TRUE(status.ok()); - - // Free all buffers when one buffer is posted. - CHECK_NO_BUFFER_THEN_ALLOCATE(kBufferCount); - producer_status = producer_queue_->Dequeue(kTimeoutMs, &slot, &mo, &fence); - ASSERT_TRUE(producer_status.ok()); - producer_buffer = producer_status.take(); - ASSERT_NE(nullptr, producer_buffer); - ASSERT_EQ(0, producer_buffer->PostAsync(&mi, fence)); - status = producer_queue_->FreeAllBuffers(); - EXPECT_TRUE(status.ok()); - - // Free all buffers when all buffers are posted. - CHECK_NO_BUFFER_THEN_ALLOCATE(kBufferCount); - for (size_t i = 0; i < kBufferCount; i++) { - producer_status = producer_queue_->Dequeue(kTimeoutMs, &slot, &mo, &fence); - ASSERT_TRUE(producer_status.ok()); - producer_buffer = producer_status.take(); - ASSERT_NE(producer_buffer, nullptr); - ASSERT_EQ(producer_buffer->PostAsync(&mi, fence), 0); - } - status = producer_queue_->FreeAllBuffers(); - EXPECT_TRUE(status.ok()); - - // Free all buffers when all buffers are acquired. - CHECK_NO_BUFFER_THEN_ALLOCATE(kBufferCount); - for (size_t i = 0; i < kBufferCount; i++) { - producer_status = producer_queue_->Dequeue(kTimeoutMs, &slot, &mo, &fence); - ASSERT_TRUE(producer_status.ok()); - producer_buffer = producer_status.take(); - ASSERT_NE(producer_buffer, nullptr); - ASSERT_EQ(producer_buffer->PostAsync(&mi, fence), 0); - consumer_status = consumer_queue_->Dequeue(kTimeoutMs, &slot, &mo, &fence); - ASSERT_TRUE(consumer_status.ok()) << consumer_status.GetErrorMessage(); - } - - status = producer_queue_->FreeAllBuffers(); - EXPECT_TRUE(status.ok()); - - // In addition to FreeAllBuffers() from the queue, it is also required to - // delete all references to the ProducerBuffer (i.e. the PDX client). - producer_buffer = nullptr; - - // Crank consumer queue events to pickup EPOLLHUP events on the queue. - consumer_queue_->HandleQueueEvents(); - - // One last check. - CHECK_NO_BUFFER_THEN_ALLOCATE(kBufferCount); - -#undef CHECK_NO_BUFFER_THEN_ALLOCATE -} - -TEST_F(BufferHubQueueTest, TestProducerToParcelableNotEmpty) { - ASSERT_TRUE(CreateQueues(config_builder_.SetMetadata<uint64_t>().Build(), - UsagePolicy{})); - - // Allocate only one buffer. - AllocateBuffer(); - - // Export should fail as the queue is not empty. - auto status = producer_queue_->TakeAsParcelable(); - EXPECT_FALSE(status.ok()); -} - -TEST_F(BufferHubQueueTest, TestProducerExportToParcelable) { - ASSERT_TRUE(CreateQueues(config_builder_.Build(), UsagePolicy{})); - - auto s1 = producer_queue_->TakeAsParcelable(); - EXPECT_TRUE(s1.ok()); - - ProducerQueueParcelable output_parcelable = s1.take(); - EXPECT_TRUE(output_parcelable.IsValid()); - - Parcel parcel; - status_t res; - res = output_parcelable.writeToParcel(&parcel); - EXPECT_EQ(res, OK); - - // After written into parcelable, the output_parcelable is still valid has - // keeps the producer channel alive. - EXPECT_TRUE(output_parcelable.IsValid()); - - // Creating producer buffer should fail. - auto s2 = producer_queue_->AllocateBuffer(kBufferWidth, kBufferHeight, - kBufferLayerCount, kBufferFormat, - kBufferUsage); - ASSERT_FALSE(s2.ok()); - - // Reset the data position so that we can read back from the same parcel - // without doing actually Binder IPC. - parcel.setDataPosition(0); - producer_queue_ = nullptr; - - // Recreate the producer queue from the parcel. - ProducerQueueParcelable input_parcelable; - EXPECT_FALSE(input_parcelable.IsValid()); - - res = input_parcelable.readFromParcel(&parcel); - EXPECT_EQ(res, OK); - EXPECT_TRUE(input_parcelable.IsValid()); - - EXPECT_EQ(producer_queue_, nullptr); - producer_queue_ = ProducerQueue::Import(input_parcelable.TakeChannelHandle()); - EXPECT_FALSE(input_parcelable.IsValid()); - ASSERT_NE(producer_queue_, nullptr); - - // Newly created queue from the parcel can allocate buffer, post buffer to - // consumer. - EXPECT_NO_FATAL_FAILURE(AllocateBuffer()); - EXPECT_EQ(producer_queue_->count(), 1U); - EXPECT_EQ(producer_queue_->capacity(), 1U); - - size_t slot; - DvrNativeBufferMetadata producer_meta; - DvrNativeBufferMetadata consumer_meta; - LocalHandle fence; - auto s3 = producer_queue_->Dequeue(0, &slot, &producer_meta, &fence); - EXPECT_TRUE(s3.ok()); - - std::shared_ptr<ProducerBuffer> p1 = s3.take(); - ASSERT_NE(p1, nullptr); - - producer_meta.timestamp = 42; - EXPECT_EQ(p1->PostAsync(&producer_meta, LocalHandle()), 0); - - // Make sure the buffer can be dequeued from consumer side. - auto s4 = consumer_queue_->Dequeue(kTimeoutMs, &slot, &consumer_meta, &fence); - EXPECT_TRUE(s4.ok()) << s4.GetErrorMessage(); - EXPECT_EQ(consumer_queue_->capacity(), 1U); - - auto consumer = s4.take(); - ASSERT_NE(consumer, nullptr); - EXPECT_EQ(producer_meta.timestamp, consumer_meta.timestamp); -} - -TEST_F(BufferHubQueueTest, TestCreateConsumerParcelable) { - ASSERT_TRUE(CreateProducerQueue(config_builder_.Build(), UsagePolicy{})); - - auto s1 = producer_queue_->CreateConsumerQueueParcelable(); - EXPECT_TRUE(s1.ok()); - ConsumerQueueParcelable output_parcelable = s1.take(); - EXPECT_TRUE(output_parcelable.IsValid()); - - // Write to a Parcel new object. - Parcel parcel; - status_t res; - res = output_parcelable.writeToParcel(&parcel); - - // Reset the data position so that we can read back from the same parcel - // without doing actually Binder IPC. - parcel.setDataPosition(0); - - // No consumer queue created yet. - EXPECT_EQ(consumer_queue_, nullptr); - - // If the parcel contains a consumer queue, read into a - // ProducerQueueParcelable should fail. - ProducerQueueParcelable wrongly_typed_parcelable; - EXPECT_FALSE(wrongly_typed_parcelable.IsValid()); - res = wrongly_typed_parcelable.readFromParcel(&parcel); - EXPECT_EQ(res, -EINVAL); - parcel.setDataPosition(0); - - // Create the consumer queue from the parcel. - ConsumerQueueParcelable input_parcelable; - EXPECT_FALSE(input_parcelable.IsValid()); - - res = input_parcelable.readFromParcel(&parcel); - EXPECT_EQ(res, OK); - EXPECT_TRUE(input_parcelable.IsValid()); - - consumer_queue_ = ConsumerQueue::Import(input_parcelable.TakeChannelHandle()); - EXPECT_FALSE(input_parcelable.IsValid()); - ASSERT_NE(consumer_queue_, nullptr); - - EXPECT_NO_FATAL_FAILURE(AllocateBuffer()); - EXPECT_EQ(producer_queue_->count(), 1U); - EXPECT_EQ(producer_queue_->capacity(), 1U); - - size_t slot; - DvrNativeBufferMetadata producer_meta; - DvrNativeBufferMetadata consumer_meta; - LocalHandle fence; - auto s2 = producer_queue_->Dequeue(0, &slot, &producer_meta, &fence); - EXPECT_TRUE(s2.ok()); - - std::shared_ptr<ProducerBuffer> p1 = s2.take(); - ASSERT_NE(p1, nullptr); - - producer_meta.timestamp = 42; - EXPECT_EQ(p1->PostAsync(&producer_meta, LocalHandle()), 0); - - // Make sure the buffer can be dequeued from consumer side. - auto s3 = consumer_queue_->Dequeue(kTimeoutMs, &slot, &consumer_meta, &fence); - EXPECT_TRUE(s3.ok()) << s3.GetErrorMessage(); - EXPECT_EQ(consumer_queue_->capacity(), 1U); - - auto consumer = s3.take(); - ASSERT_NE(consumer, nullptr); - EXPECT_EQ(producer_meta.timestamp, consumer_meta.timestamp); -} - -} // namespace - -} // namespace dvr -} // namespace android diff --git a/libs/vr/libdisplay/Android.bp b/libs/vr/libdisplay/Android.bp deleted file mode 100644 index b0ed950c51..0000000000 --- a/libs/vr/libdisplay/Android.bp +++ /dev/null @@ -1,78 +0,0 @@ -// Copyright (C) 2015 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. - -package { - // See: http://go/android-license-faq - // A large-scale-change added 'default_applicable_licenses' to import - // all of the 'license_kinds' from "frameworks_native_license" - // to get the below license kinds: - // SPDX-license-identifier-Apache-2.0 - default_applicable_licenses: ["frameworks_native_license"], -} - -sourceFiles = [ - "display_client.cpp", - "display_manager_client.cpp", - "display_protocol.cpp", - "shared_buffer_helpers.cpp", - "vsync_service.cpp", -] - -localIncludeFiles = [ - "include", -] - -sharedLibraries = [ - "libbase", - "libbinder", - "libbufferhubqueue", - "libcutils", - "liblog", - "libutils", - "libui", - "libgui", - "libhardware", - "libsync", - "libnativewindow", - "libpdx_default_transport", -] - -staticLibraries = [ - "libdvrcommon", - "libbroadcastring", -] - -headerLibraries = [ - "vulkan_headers", - "libdvr_headers", -] - -cc_library { - srcs: sourceFiles, - cflags: ["-DLOG_TAG=\"libdisplay\"", - "-DTRACE=0", - "-DATRACE_TAG=ATRACE_TAG_GRAPHICS", - "-DGL_GLEXT_PROTOTYPES", - "-DEGL_EGLEXT_PROTOTYPES", - "-Wall", - "-Werror", - ], // + [ "-UNDEBUG", "-DDEBUG", "-O0", "-g" ], - export_include_dirs: localIncludeFiles, - shared_libs: sharedLibraries, - static_libs: staticLibraries, - header_libs: headerLibraries, - export_header_lib_headers: headerLibraries, - - name: "libdisplay", -} diff --git a/libs/vr/libdisplay/display_client.cpp b/libs/vr/libdisplay/display_client.cpp deleted file mode 100644 index 62856dfbf8..0000000000 --- a/libs/vr/libdisplay/display_client.cpp +++ /dev/null @@ -1,261 +0,0 @@ -#include "include/private/dvr/display_client.h" - -#include <cutils/native_handle.h> -#include <log/log.h> -#include <pdx/default_transport/client_channel.h> -#include <pdx/default_transport/client_channel_factory.h> -#include <pdx/status.h> - -#include <mutex> - -#include <private/dvr/display_protocol.h> - -using android::pdx::ErrorStatus; -using android::pdx::LocalHandle; -using android::pdx::LocalChannelHandle; -using android::pdx::Status; -using android::pdx::Transaction; -using android::pdx::rpc::IfAnyOf; - -namespace android { -namespace dvr { -namespace display { - -Surface::Surface(LocalChannelHandle channel_handle, int* error) - : BASE{pdx::default_transport::ClientChannel::Create( - std::move(channel_handle))} { - auto status = InvokeRemoteMethod<DisplayProtocol::GetSurfaceInfo>(); - if (!status) { - ALOGE("Surface::Surface: Failed to get surface info: %s", - status.GetErrorMessage().c_str()); - Close(status.error()); - if (error) - *error = status.error(); - } - - surface_id_ = status.get().surface_id; - z_order_ = status.get().z_order; - visible_ = status.get().visible; -} - -Surface::Surface(const SurfaceAttributes& attributes, int* error) - : BASE{pdx::default_transport::ClientChannelFactory::Create( - DisplayProtocol::kClientPath), - kInfiniteTimeout} { - auto status = InvokeRemoteMethod<DisplayProtocol::CreateSurface>(attributes); - if (!status) { - ALOGE("Surface::Surface: Failed to create display surface: %s", - status.GetErrorMessage().c_str()); - Close(status.error()); - if (error) - *error = status.error(); - } - - surface_id_ = status.get().surface_id; - z_order_ = status.get().z_order; - visible_ = status.get().visible; -} - -Status<void> Surface::SetVisible(bool visible) { - return SetAttributes( - {{SurfaceAttribute::Visible, SurfaceAttributeValue{visible}}}); -} - -Status<void> Surface::SetZOrder(int z_order) { - return SetAttributes( - {{SurfaceAttribute::ZOrder, SurfaceAttributeValue{z_order}}}); -} - -Status<void> Surface::SetAttributes(const SurfaceAttributes& attributes) { - auto status = InvokeRemoteMethod<DisplayProtocol::SetAttributes>(attributes); - if (!status) { - ALOGE( - "Surface::SetAttributes: Failed to set display surface " - "attributes: %s", - status.GetErrorMessage().c_str()); - return status.error_status(); - } - - // Set the local cached copies of the attributes we care about from the full - // set of attributes sent to the display service. - for (const auto& attribute : attributes) { - const auto& key = attribute.first; - const auto* variant = &attribute.second; - bool invalid_value = false; - switch (key) { - case SurfaceAttribute::Visible: - invalid_value = - !IfAnyOf<int32_t, int64_t, bool>::Get(variant, &visible_); - break; - case SurfaceAttribute::ZOrder: - invalid_value = !IfAnyOf<int32_t>::Get(variant, &z_order_); - break; - } - - if (invalid_value) { - ALOGW( - "Surface::SetAttributes: Failed to set display surface " - "attribute %d because of incompatible type: %d", - key, variant->index()); - } - } - - return {}; -} - -Status<std::unique_ptr<ProducerQueue>> Surface::CreateQueue( - uint32_t width, uint32_t height, uint32_t format, size_t metadata_size) { - ALOGD_IF(TRACE, "Surface::CreateQueue: Creating empty queue."); - auto status = InvokeRemoteMethod<DisplayProtocol::CreateQueue>( - ProducerQueueConfigBuilder() - .SetDefaultWidth(width) - .SetDefaultHeight(height) - .SetDefaultFormat(format) - .SetMetadataSize(metadata_size) - .Build()); - if (!status) { - ALOGE("Surface::CreateQueue: Failed to create queue: %s", - status.GetErrorMessage().c_str()); - return status.error_status(); - } - - auto producer_queue = ProducerQueue::Import(status.take()); - if (!producer_queue) { - ALOGE("Surface::CreateQueue: Failed to import producer queue!"); - return ErrorStatus(ENOMEM); - } - - return {std::move(producer_queue)}; -} - -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, size_t metadata_size) { - ALOGD_IF(TRACE, - "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(width, height, format, metadata_size); - if (!status) - return status.error_status(); - - auto producer_queue = status.take(); - - ALOGD_IF(TRACE, "Surface::CreateQueue: Allocating %zu buffers...", capacity); - auto allocate_status = producer_queue->AllocateBuffers( - width, height, layer_count, format, usage, capacity); - if (!allocate_status) { - ALOGE("Surface::CreateQueue: Failed to allocate buffer on queue_id=%d: %s", - producer_queue->id(), allocate_status.GetErrorMessage().c_str()); - return allocate_status.error_status(); - } - - return {std::move(producer_queue)}; -} - -DisplayClient::DisplayClient(int* error) - : BASE(pdx::default_transport::ClientChannelFactory::Create( - DisplayProtocol::kClientPath), - kInfiniteTimeout) { - if (error) - *error = Client::error(); -} - -Status<Metrics> DisplayClient::GetDisplayMetrics() { - return InvokeRemoteMethod<DisplayProtocol::GetMetrics>(); -} - -Status<std::string> DisplayClient::GetConfigurationData( - ConfigFileType config_type) { - auto status = - InvokeRemoteMethod<DisplayProtocol::GetConfigurationData>(config_type); - if (!status && status.error() != ENOENT) { - ALOGE( - "DisplayClient::GetConfigurationData: Unable to get" - "configuration data. Error: %s", - status.GetErrorMessage().c_str()); - } - return status; -} - -Status<uint8_t> DisplayClient::GetDisplayIdentificationPort() { - return InvokeRemoteMethod<DisplayProtocol::GetDisplayIdentificationPort>(); -} - -Status<std::unique_ptr<Surface>> DisplayClient::CreateSurface( - const SurfaceAttributes& attributes) { - int error; - if (auto client = Surface::Create(attributes, &error)) - return {std::move(client)}; - else - return ErrorStatus(error); -} - -pdx::Status<std::unique_ptr<IonBuffer>> DisplayClient::SetupGlobalBuffer( - DvrGlobalBufferKey key, size_t size, uint64_t usage) { - auto status = - InvokeRemoteMethod<DisplayProtocol::SetupGlobalBuffer>(key, size, usage); - if (!status) { - ALOGE( - "DisplayClient::SetupGlobalBuffer: Failed to create the global buffer " - "%s", - status.GetErrorMessage().c_str()); - return status.error_status(); - } - - auto ion_buffer = std::make_unique<IonBuffer>(); - auto native_buffer_handle = status.take(); - const int ret = native_buffer_handle.Import(ion_buffer.get()); - if (ret < 0) { - ALOGE( - "DisplayClient::GetGlobalBuffer: Failed to import global buffer: " - "key=%d; error=%s", - key, strerror(-ret)); - return ErrorStatus(-ret); - } - - return {std::move(ion_buffer)}; -} - -pdx::Status<void> DisplayClient::DeleteGlobalBuffer(DvrGlobalBufferKey key) { - auto status = InvokeRemoteMethod<DisplayProtocol::DeleteGlobalBuffer>(key); - if (!status) { - ALOGE("DisplayClient::DeleteGlobalBuffer Failed: %s", - status.GetErrorMessage().c_str()); - } - - return status; -} - -Status<std::unique_ptr<IonBuffer>> DisplayClient::GetGlobalBuffer( - DvrGlobalBufferKey key) { - auto status = InvokeRemoteMethod<DisplayProtocol::GetGlobalBuffer>(key); - if (!status) { - ALOGE( - "DisplayClient::GetGlobalBuffer: Failed to get named buffer: key=%d; " - "error=%s", - key, status.GetErrorMessage().c_str()); - return status.error_status(); - } - - auto ion_buffer = std::make_unique<IonBuffer>(); - auto native_buffer_handle = status.take(); - const int ret = native_buffer_handle.Import(ion_buffer.get()); - if (ret < 0) { - ALOGE( - "DisplayClient::GetGlobalBuffer: Failed to import global buffer: " - "key=%d; error=%s", - key, strerror(-ret)); - return ErrorStatus(-ret); - } - - return {std::move(ion_buffer)}; -} - -Status<bool> DisplayClient::IsVrAppRunning() { - return InvokeRemoteMethod<DisplayProtocol::IsVrAppRunning>(); -} - -} // namespace display -} // namespace dvr -} // namespace android diff --git a/libs/vr/libdisplay/display_manager_client.cpp b/libs/vr/libdisplay/display_manager_client.cpp deleted file mode 100644 index fdeeb70dfb..0000000000 --- a/libs/vr/libdisplay/display_manager_client.cpp +++ /dev/null @@ -1,51 +0,0 @@ -#include "include/private/dvr/display_manager_client.h" - -#include <pdx/default_transport/client_channel_factory.h> -#include <private/dvr/buffer_hub_queue_client.h> -#include <private/dvr/display_protocol.h> -#include <utils/Log.h> - -using android::pdx::ErrorStatus; -using android::pdx::LocalChannelHandle; -using android::pdx::Transaction; - -namespace android { -namespace dvr { -namespace display { - -DisplayManagerClient::DisplayManagerClient() - : BASE(pdx::default_transport::ClientChannelFactory::Create( - DisplayManagerProtocol::kClientPath)) {} - -DisplayManagerClient::~DisplayManagerClient() {} - -pdx::Status<std::vector<display::SurfaceState>> -DisplayManagerClient::GetSurfaceState() { - auto status = InvokeRemoteMethod<DisplayManagerProtocol::GetSurfaceState>(); - if (!status) { - ALOGE( - "DisplayManagerClient::GetSurfaceState: Failed to get surface info: %s", - status.GetErrorMessage().c_str()); - } - - return status; -} - -pdx::Status<std::unique_ptr<ConsumerQueue>> -DisplayManagerClient::GetSurfaceQueue(int surface_id, int queue_id) { - auto status = InvokeRemoteMethod<DisplayManagerProtocol::GetSurfaceQueue>( - surface_id, queue_id); - if (!status) { - ALOGE( - "DisplayManagerClient::GetSurfaceQueue: Failed to get queue for " - "surface_id=%d queue_id=%d: %s", - surface_id, queue_id, status.GetErrorMessage().c_str()); - return status.error_status(); - } - - return {ConsumerQueue::Import(status.take())}; -} - -} // namespace display -} // namespace dvr -} // namespace android diff --git a/libs/vr/libdisplay/display_protocol.cpp b/libs/vr/libdisplay/display_protocol.cpp deleted file mode 100644 index 773f9a5aa3..0000000000 --- a/libs/vr/libdisplay/display_protocol.cpp +++ /dev/null @@ -1,13 +0,0 @@ -#include "include/private/dvr/display_protocol.h" - -namespace android { -namespace dvr { -namespace display { - -constexpr char DisplayProtocol::kClientPath[]; -constexpr char DisplayManagerProtocol::kClientPath[]; -constexpr char VSyncProtocol::kClientPath[]; - -} // namespace display -} // namespace dvr -} // namespace android diff --git a/libs/vr/libdisplay/include/CPPLINT.cfg b/libs/vr/libdisplay/include/CPPLINT.cfg deleted file mode 100644 index 2f8a3c018c..0000000000 --- a/libs/vr/libdisplay/include/CPPLINT.cfg +++ /dev/null @@ -1 +0,0 @@ -filter=-build/header_guard diff --git a/libs/vr/libdisplay/include/private/dvr/display_client.h b/libs/vr/libdisplay/include/private/dvr/display_client.h deleted file mode 100644 index 81546ac5c2..0000000000 --- a/libs/vr/libdisplay/include/private/dvr/display_client.h +++ /dev/null @@ -1,100 +0,0 @@ -#ifndef ANDROID_DVR_DISPLAY_CLIENT_H_ -#define ANDROID_DVR_DISPLAY_CLIENT_H_ - -#include <dvr/dvr_api.h> -#include <hardware/hwcomposer.h> -#include <pdx/client.h> -#include <pdx/file_handle.h> -#include <private/dvr/buffer_hub_queue_client.h> -#include <private/dvr/display_protocol.h> - -namespace android { -namespace dvr { -namespace display { - -class Surface : public pdx::ClientBase<Surface> { - public: - // Utility named constructor. This can be removed once ClientBase::Create is - // refactored to return Status<T> types. - static pdx::Status<std::unique_ptr<Surface>> CreateSurface( - const SurfaceAttributes& attributes) { - int error; - pdx::Status<std::unique_ptr<Surface>> status; - if (auto surface = Create(attributes, &error)) - status.SetValue(std::move(surface)); - else - status.SetError(error); - return status; - } - - int surface_id() const { return surface_id_; } - int z_order() const { return z_order_; } - bool visible() const { return visible_; } - - pdx::Status<void> SetVisible(bool visible); - pdx::Status<void> SetZOrder(int z_order); - pdx::Status<void> SetAttributes(const SurfaceAttributes& attributes); - - // Creates an empty queue. - pdx::Status<std::unique_ptr<ProducerQueue>> CreateQueue(uint32_t width, - uint32_t height, - uint32_t format, - size_t metadata_size); - - // Creates a queue and populates it with |capacity| buffers of the specified - // 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, - size_t metadata_size); - - private: - friend BASE; - - int surface_id_ = -1; - int z_order_ = 0; - bool visible_ = false; - - // TODO(eieio,avakulenko): Remove error param once pdx::ClientBase::Create() - // returns Status<T>. - explicit Surface(const SurfaceAttributes& attributes, int* error = nullptr); - explicit Surface(pdx::LocalChannelHandle channel_handle, - int* error = nullptr); - - Surface(const Surface&) = delete; - void operator=(const Surface&) = delete; -}; - -class DisplayClient : public pdx::ClientBase<DisplayClient> { - public: - pdx::Status<Metrics> GetDisplayMetrics(); - pdx::Status<std::string> GetConfigurationData(ConfigFileType config_type); - pdx::Status<uint8_t> GetDisplayIdentificationPort(); - pdx::Status<std::unique_ptr<IonBuffer>> SetupGlobalBuffer( - DvrGlobalBufferKey key, size_t size, uint64_t usage); - pdx::Status<void> DeleteGlobalBuffer(DvrGlobalBufferKey key); - pdx::Status<std::unique_ptr<IonBuffer>> GetGlobalBuffer( - DvrGlobalBufferKey key); - pdx::Status<std::unique_ptr<Surface>> CreateSurface( - const SurfaceAttributes& attributes); - - // Temporary query for current VR status. Will be removed later. - pdx::Status<bool> IsVrAppRunning(); - - private: - friend BASE; - - explicit DisplayClient(int* error = nullptr); - - DisplayClient(const DisplayClient&) = delete; - void operator=(const DisplayClient&) = delete; -}; - -} // namespace display -} // namespace dvr -} // namespace android - -#endif // ANDROID_DVR_DISPLAY_CLIENT_H_ diff --git a/libs/vr/libdisplay/include/private/dvr/display_manager_client.h b/libs/vr/libdisplay/include/private/dvr/display_manager_client.h deleted file mode 100644 index 45aef51baf..0000000000 --- a/libs/vr/libdisplay/include/private/dvr/display_manager_client.h +++ /dev/null @@ -1,49 +0,0 @@ -#ifndef ANDROID_DVR_DISPLAY_MANAGER_CLIENT_H_ -#define ANDROID_DVR_DISPLAY_MANAGER_CLIENT_H_ - -#include <string> -#include <vector> - -#include <pdx/client.h> -#include <pdx/status.h> -#include <private/dvr/display_protocol.h> - -namespace android { -namespace dvr { - -class IonBuffer; -class ConsumerQueue; - -namespace display { - -class DisplayManagerClient : public pdx::ClientBase<DisplayManagerClient> { - public: - ~DisplayManagerClient() override; - - pdx::Status<std::vector<SurfaceState>> GetSurfaceState(); - pdx::Status<std::unique_ptr<ConsumerQueue>> GetSurfaceQueue(int surface_id, - int queue_id); - - using Client::event_fd; - - pdx::Status<int> GetEventMask(int events) { - if (auto* client_channel = GetChannel()) - return client_channel->GetEventMask(events); - else - return pdx::ErrorStatus(EINVAL); - } - - private: - friend BASE; - - DisplayManagerClient(); - - DisplayManagerClient(const DisplayManagerClient&) = delete; - void operator=(const DisplayManagerClient&) = delete; -}; - -} // namespace display -} // namespace dvr -} // namespace android - -#endif // ANDROID_DVR_DISPLAY_MANAGER_CLIENT_H_ diff --git a/libs/vr/libdisplay/include/private/dvr/display_protocol.h b/libs/vr/libdisplay/include/private/dvr/display_protocol.h deleted file mode 100644 index 9f4cc4afcc..0000000000 --- a/libs/vr/libdisplay/include/private/dvr/display_protocol.h +++ /dev/null @@ -1,304 +0,0 @@ -#ifndef ANDROID_DVR_DISPLAY_PROTOCOL_H_ -#define ANDROID_DVR_DISPLAY_PROTOCOL_H_ - -#include <sys/types.h> - -#include <array> -#include <map> - -#include <dvr/dvr_display_types.h> - -#include <dvr/dvr_api.h> -#include <pdx/rpc/buffer_wrapper.h> -#include <pdx/rpc/remote_method.h> -#include <pdx/rpc/serializable.h> -#include <pdx/rpc/variant.h> -#include <private/dvr/bufferhub_rpc.h> - -// RPC protocol definitions for DVR display services (VrFlinger). - -namespace android { -namespace dvr { -namespace display { - -// Native display metrics. -struct Metrics { - // Basic display properties. - uint32_t display_width; - uint32_t display_height; - uint32_t display_x_dpi; - uint32_t display_y_dpi; - uint32_t vsync_period_ns; - - // HMD metrics. - // TODO(eieio): Determine how these fields should be populated. On phones - // these values are determined at runtime by VrCore based on which headset the - // phone is in. On dedicated hardware this needs to come from somewhere else. - // Perhaps these should be moved to a separate structure that is returned by a - // separate runtime call. - uint32_t distorted_width; - uint32_t distorted_height; - uint32_t hmd_ipd_mm; - float inter_lens_distance_m; - std::array<float, 4> left_fov_lrbt; - std::array<float, 4> right_fov_lrbt; - - private: - PDX_SERIALIZABLE_MEMBERS(Metrics, display_width, display_height, - display_x_dpi, display_y_dpi, vsync_period_ns, - distorted_width, distorted_height, hmd_ipd_mm, - inter_lens_distance_m, left_fov_lrbt, - right_fov_lrbt); -}; - -// Serializable base type for enum structs. Enum structs are easier to use than -// enum classes, especially for bitmasks. This base type provides common -// utilities for flags types. -template <typename Integer> -class Flags { - public: - using Base = Flags<Integer>; - using Type = Integer; - - // NOLINTNEXTLINE(google-explicit-constructor) - Flags(const Integer& value) : value_{value} {} - Flags(const Flags&) = default; - Flags& operator=(const Flags&) = default; - - Integer value() const { return value_; } - // NOLINTNEXTLINE(google-explicit-constructor) - operator Integer() const { return value_; } - - bool IsSet(Integer bits) const { return (value_ & bits) == bits; } - bool IsClear(Integer bits) const { return (value_ & bits) == 0; } - - void Set(Integer bits) { value_ |= bits; } - void Clear(Integer bits) { value_ &= ~bits; } - - Integer operator|(Integer bits) const { return value_ | bits; } - Integer operator&(Integer bits) const { return value_ & bits; } - - Flags& operator|=(Integer bits) { - value_ |= bits; - return *this; - } - Flags& operator&=(Integer bits) { - value_ &= bits; - return *this; - } - - private: - Integer value_; - - PDX_SERIALIZABLE_MEMBERS(Flags<Integer>, value_); -}; - -// Flags indicating what changed since last update. -struct SurfaceUpdateFlags : public Flags<uint32_t> { - enum : Type { - None = DVR_SURFACE_UPDATE_FLAGS_NONE, - NewSurface = DVR_SURFACE_UPDATE_FLAGS_NEW_SURFACE, - BuffersChanged = DVR_SURFACE_UPDATE_FLAGS_BUFFERS_CHANGED, - VisibilityChanged = DVR_SURFACE_UPDATE_FLAGS_VISIBILITY_CHANGED, - AttributesChanged = DVR_SURFACE_UPDATE_FLAGS_ATTRIBUTES_CHANGED, - }; - - SurfaceUpdateFlags() : Base{None} {} - using Base::Base; -}; - -// Surface attribute key/value types. -using SurfaceAttributeKey = int32_t; -using SurfaceAttributeValue = - pdx::rpc::Variant<int32_t, int64_t, bool, float, std::array<float, 2>, - std::array<float, 3>, std::array<float, 4>, - std::array<float, 8>, std::array<float, 16>>; - -// Defined surface attribute keys. -struct SurfaceAttribute : public Flags<SurfaceAttributeKey> { - enum : Type { - // Keys in the negative integer space are interpreted by VrFlinger for - // direct surfaces. - Direct = DVR_SURFACE_ATTRIBUTE_DIRECT, - ZOrder = DVR_SURFACE_ATTRIBUTE_Z_ORDER, - Visible = DVR_SURFACE_ATTRIBUTE_VISIBLE, - - // Invalid key. May be used to terminate C style lists in public API code. - Invalid = DVR_SURFACE_ATTRIBUTE_INVALID, - - // Positive keys are interpreted by the compositor only. - FirstUserKey = DVR_SURFACE_ATTRIBUTE_FIRST_USER_KEY, - }; - - SurfaceAttribute() : Base{Invalid} {} - using Base::Base; -}; - -// Collection of surface attribute key/value pairs. -using SurfaceAttributes = std::map<SurfaceAttributeKey, SurfaceAttributeValue>; - -struct SurfaceState { - int32_t surface_id; - int32_t process_id; - int32_t user_id; - - SurfaceAttributes surface_attributes; - SurfaceUpdateFlags update_flags; - std::vector<int32_t> queue_ids; - - // Convenience accessors. - bool GetVisible() const { - bool bool_value = false; - GetAttribute(SurfaceAttribute::Visible, &bool_value, - ValidTypes<int32_t, int64_t, bool, float>{}); - return bool_value; - } - - int GetZOrder() const { - int int_value = 0; - GetAttribute(SurfaceAttribute::ZOrder, &int_value, - ValidTypes<int32_t, int64_t, float>{}); - return int_value; - } - - private: - template <typename... Types> - struct ValidTypes {}; - - template <typename ReturnType, typename... Types> - bool GetAttribute(SurfaceAttributeKey key, ReturnType* out_value, - ValidTypes<Types...>) const { - auto search = surface_attributes.find(key); - if (search != surface_attributes.end()) - return pdx::rpc::IfAnyOf<Types...>::Get(&search->second, out_value); - else - return false; - } - - PDX_SERIALIZABLE_MEMBERS(SurfaceState, surface_id, process_id, - surface_attributes, update_flags, queue_ids); -}; - -struct SurfaceInfo { - int surface_id; - bool visible; - int z_order; - - private: - PDX_SERIALIZABLE_MEMBERS(SurfaceInfo, surface_id, visible, z_order); -}; - -enum class ConfigFileType : uint32_t { - kLensMetrics, - kDeviceMetrics, - kDeviceConfiguration, - kDeviceEdid -}; - -struct DisplayProtocol { - // Service path. - static constexpr char kClientPath[] = "system/vr/display/client"; - - // Op codes. - enum { - kOpGetMetrics = 0, - kOpGetConfigurationData, - kOpSetupGlobalBuffer, - kOpDeleteGlobalBuffer, - kOpGetGlobalBuffer, - kOpIsVrAppRunning, - kOpCreateSurface, - kOpGetSurfaceInfo, - kOpCreateQueue, - kOpSetAttributes, - kOpGetDisplayIdentificationPort, - }; - - // Aliases. - using LocalChannelHandle = pdx::LocalChannelHandle; - using Void = pdx::rpc::Void; - - // Methods. - PDX_REMOTE_METHOD(GetMetrics, kOpGetMetrics, Metrics(Void)); - PDX_REMOTE_METHOD(GetConfigurationData, kOpGetConfigurationData, - std::string(ConfigFileType config_type)); - PDX_REMOTE_METHOD(GetDisplayIdentificationPort, - kOpGetDisplayIdentificationPort, uint8_t(Void)); - PDX_REMOTE_METHOD(SetupGlobalBuffer, kOpSetupGlobalBuffer, - LocalNativeBufferHandle(DvrGlobalBufferKey key, size_t size, - uint64_t usage)); - PDX_REMOTE_METHOD(DeleteGlobalBuffer, kOpDeleteGlobalBuffer, - void(DvrGlobalBufferKey key)); - PDX_REMOTE_METHOD(GetGlobalBuffer, kOpGetGlobalBuffer, - LocalNativeBufferHandle(DvrGlobalBufferKey key)); - PDX_REMOTE_METHOD(IsVrAppRunning, kOpIsVrAppRunning, bool(Void)); - PDX_REMOTE_METHOD(CreateSurface, kOpCreateSurface, - SurfaceInfo(const SurfaceAttributes& attributes)); - PDX_REMOTE_METHOD(GetSurfaceInfo, kOpGetSurfaceInfo, SurfaceInfo(Void)); - PDX_REMOTE_METHOD( - CreateQueue, kOpCreateQueue, - LocalChannelHandle(const ProducerQueueConfig& producer_config)); - PDX_REMOTE_METHOD(SetAttributes, kOpSetAttributes, - void(const SurfaceAttributes& attributes)); -}; - -struct DisplayManagerProtocol { - // Service path. - static constexpr char kClientPath[] = "system/vr/display/manager"; - - // Op codes. - enum { - kOpGetSurfaceState = 0, - kOpGetSurfaceQueue, - }; - - // Aliases. - using LocalChannelHandle = pdx::LocalChannelHandle; - using Void = pdx::rpc::Void; - - // Methods. - PDX_REMOTE_METHOD(GetSurfaceState, kOpGetSurfaceState, - std::vector<SurfaceState>(Void)); - PDX_REMOTE_METHOD(GetSurfaceQueue, kOpGetSurfaceQueue, - LocalChannelHandle(int surface_id, int queue_id)); -}; - -struct VSyncSchedInfo { - int64_t vsync_period_ns; - int64_t timestamp_ns; - uint32_t next_vsync_count; - - private: - PDX_SERIALIZABLE_MEMBERS(VSyncSchedInfo, vsync_period_ns, timestamp_ns, - next_vsync_count); -}; - -struct VSyncProtocol { - // Service path. - static constexpr char kClientPath[] = "system/vr/display/vsync"; - - // Op codes. - enum { - kOpWait = 0, - kOpAck, - kOpGetLastTimestamp, - kOpGetSchedInfo, - kOpAcknowledge, - }; - - // Aliases. - using Void = pdx::rpc::Void; - using Timestamp = int64_t; - - // Methods. - PDX_REMOTE_METHOD(Wait, kOpWait, Timestamp(Void)); - PDX_REMOTE_METHOD(GetLastTimestamp, kOpGetLastTimestamp, Timestamp(Void)); - PDX_REMOTE_METHOD(GetSchedInfo, kOpGetSchedInfo, VSyncSchedInfo(Void)); - PDX_REMOTE_METHOD(Acknowledge, kOpAcknowledge, void(Void)); -}; - -} // namespace display -} // namespace dvr -} // namespace android - -#endif // ANDROID_DVR_DISPLAY_PROTOCOL_H_ diff --git a/libs/vr/libdisplay/include/private/dvr/shared_buffer_helpers.h b/libs/vr/libdisplay/include/private/dvr/shared_buffer_helpers.h deleted file mode 100644 index 20541a69a5..0000000000 --- a/libs/vr/libdisplay/include/private/dvr/shared_buffer_helpers.h +++ /dev/null @@ -1,146 +0,0 @@ -#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; - - // The last time we connected to the display service. - int64_t last_display_service_connection_ns_ = 0; - - // 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() { - // No ring created yet? - if (ring_ == nullptr) { - // Not mapped the memory yet? - if (IsMapped() == false) { - TryMapping(); - } - - // If have the memory mapped, allocate the ring. - 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/include/private/dvr/vsync_service.h b/libs/vr/libdisplay/include/private/dvr/vsync_service.h deleted file mode 100644 index 152464abd1..0000000000 --- a/libs/vr/libdisplay/include/private/dvr/vsync_service.h +++ /dev/null @@ -1,65 +0,0 @@ -#ifndef ANDROID_DVR_VSYNC_SERVICE_H_ -#define ANDROID_DVR_VSYNC_SERVICE_H_ - -#include <binder/IInterface.h> - -namespace android { -namespace dvr { - -class IVsyncCallback : public IInterface { - public: - DECLARE_META_INTERFACE(VsyncCallback) - - enum { - ON_VSYNC = IBinder::FIRST_CALL_TRANSACTION - }; - - virtual status_t onVsync(int64_t vsync_timestamp) = 0; -}; - -class BnVsyncCallback : public BnInterface<IVsyncCallback> { - public: - virtual status_t onTransact(uint32_t code, const Parcel& data, - Parcel* reply, uint32_t flags = 0); -}; - -// Register a callback with IVsyncService to be notified of vsync events and -// timestamps. There's also a shared memory vsync buffer defined in -// dvr_shared_buffers.h. IVsyncService has advantages over the vsync shared -// memory buffer that make it preferable in certain situations: -// -// 1. The shared memory buffer lifetime is controlled by VrCore. IVsyncService -// is always available as long as surface flinger is running. -// -// 2. IVsyncService will make a binder callback when a vsync event occurs. This -// allows the client to not write code to implement periodic "get the latest -// vsync" calls, which is necessary with the vsync shared memory buffer. -// -// 3. The IVsyncService provides the real vsync timestamp reported by hardware -// composer, whereas the vsync shared memory buffer only has predicted vsync -// times. -class IVsyncService : public IInterface { -public: - DECLARE_META_INTERFACE(VsyncService) - - static const char* GetServiceName() { return "vrflinger_vsync"; } - - enum { - REGISTER_CALLBACK = IBinder::FIRST_CALL_TRANSACTION, - UNREGISTER_CALLBACK - }; - - virtual status_t registerCallback(const sp<IVsyncCallback> callback) = 0; - virtual status_t unregisterCallback(const sp<IVsyncCallback> callback) = 0; -}; - -class BnVsyncService : public BnInterface<IVsyncService> { - public: - virtual status_t onTransact(uint32_t code, const Parcel& data, - Parcel* reply, uint32_t flags = 0); -}; - -} // namespace dvr -} // namespace android - -#endif // ANDROID_DVR_VSYNC_SERVICE_H_ diff --git a/libs/vr/libdisplay/shared_buffer_helpers.cpp b/libs/vr/libdisplay/shared_buffer_helpers.cpp deleted file mode 100644 index 6ebf487d16..0000000000 --- a/libs/vr/libdisplay/shared_buffer_helpers.cpp +++ /dev/null @@ -1,98 +0,0 @@ -#include <private/dvr/clock_ns.h> -#include <private/dvr/shared_buffer_helpers.h> - -namespace android { -namespace dvr { -namespace { - -// We will not poll the display service for buffers more frequently than this. -constexpr size_t kDisplayServiceTriesPerSecond = 2; -} // namespace - -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) { - // Has it been too long since we last connected to the display service? - const auto current_time_ns = GetSystemClockNs(); - if ((current_time_ns - last_display_service_connection_ns_) < - (1e9 / kDisplayServiceTriesPerSecond)) { - // Early exit. - return; - } - last_display_service_connection_ns_ = current_time_ns; - - // Create a display client and get the buffer. - 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 { - // The buffer has not been created yet. This is OK, we will keep - // retrying. - } - } 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/libdisplay/system/CPPLINT.cfg b/libs/vr/libdisplay/system/CPPLINT.cfg deleted file mode 100644 index 2f8a3c018c..0000000000 --- a/libs/vr/libdisplay/system/CPPLINT.cfg +++ /dev/null @@ -1 +0,0 @@ -filter=-build/header_guard diff --git a/libs/vr/libdisplay/vsync_service.cpp b/libs/vr/libdisplay/vsync_service.cpp deleted file mode 100644 index 04d4f30140..0000000000 --- a/libs/vr/libdisplay/vsync_service.cpp +++ /dev/null @@ -1,146 +0,0 @@ -#include "include/private/dvr/vsync_service.h" - -#include <binder/Parcel.h> -#include <log/log.h> - -namespace android { -namespace dvr { - -status_t BnVsyncCallback::onTransact( - uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) { - switch (code) { - case ON_VSYNC: { - CHECK_INTERFACE(IVsyncCallback, data, reply); - int64_t vsync_timestamp = 0; - status_t result = data.readInt64(&vsync_timestamp); - if (result != OK) { - ALOGE("onVsync failed to readInt64: %d", result); - return result; - } - onVsync(vsync_timestamp); - return OK; - } - default: { - return BBinder::onTransact(code, data, reply, flags); - } - } -} - -class BpVsyncCallback : public BpInterface<IVsyncCallback> { -public: - explicit BpVsyncCallback(const sp<IBinder>& impl) - : BpInterface<IVsyncCallback>(impl) {} - virtual ~BpVsyncCallback() {} - - virtual status_t onVsync(int64_t vsync_timestamp) { - Parcel data, reply; - status_t result = data.writeInterfaceToken( - IVsyncCallback::getInterfaceDescriptor()); - if (result != OK) { - ALOGE("onVsync failed to writeInterfaceToken: %d", result); - return result; - } - result = data.writeInt64(vsync_timestamp); - if (result != OK) { - ALOGE("onVsync failed to writeInt64: %d", result); - return result; - } - result = remote()->transact(BnVsyncCallback::ON_VSYNC, data, &reply, - IBinder::FLAG_ONEWAY); - if (result != OK) { - ALOGE("onVsync failed to transact: %d", result); - return result; - } - return result; - } -}; - -IMPLEMENT_META_INTERFACE(VsyncCallback, "android.dvr.IVsyncCallback"); - - -status_t BnVsyncService::onTransact( - uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) { - switch (code) { - case REGISTER_CALLBACK: { - CHECK_INTERFACE(IVsyncService, data, reply); - sp<IBinder> callback; - status_t result = data.readStrongBinder(&callback); - if (result != OK) { - ALOGE("registerCallback failed to readStrongBinder: %d", result); - return result; - } - registerCallback(interface_cast<IVsyncCallback>(callback)); - return OK; - } - case UNREGISTER_CALLBACK: { - CHECK_INTERFACE(IVsyncService, data, reply); - sp<IBinder> callback; - status_t result = data.readStrongBinder(&callback); - if (result != OK) { - ALOGE("unregisterCallback failed to readStrongBinder: %d", result); - return result; - } - unregisterCallback(interface_cast<IVsyncCallback>(callback)); - return OK; - } - default: { - return BBinder::onTransact(code, data, reply, flags); - } - } -} - -class BpVsyncService : public BpInterface<IVsyncService> { -public: - explicit BpVsyncService(const sp<IBinder>& impl) - : BpInterface<IVsyncService>(impl) {} - virtual ~BpVsyncService() {} - - virtual status_t registerCallback(const sp<IVsyncCallback> callback) { - Parcel data, reply; - status_t result = data.writeInterfaceToken( - IVsyncService::getInterfaceDescriptor()); - if (result != OK) { - ALOGE("registerCallback failed to writeInterfaceToken: %d", result); - return result; - } - result = data.writeStrongBinder(IInterface::asBinder(callback)); - if (result != OK) { - ALOGE("registerCallback failed to writeStrongBinder: %d", result); - return result; - } - result = remote()->transact( - BnVsyncService::REGISTER_CALLBACK, data, &reply); - if (result != OK) { - ALOGE("registerCallback failed to transact: %d", result); - return result; - } - return result; - } - - virtual status_t unregisterCallback(const sp<IVsyncCallback> callback) { - Parcel data, reply; - status_t result = data.writeInterfaceToken( - IVsyncService::getInterfaceDescriptor()); - if (result != OK) { - ALOGE("unregisterCallback failed to writeInterfaceToken: %d", result); - return result; - } - result = data.writeStrongBinder(IInterface::asBinder(callback)); - if (result != OK) { - ALOGE("unregisterCallback failed to writeStrongBinder: %d", result); - return result; - } - result = remote()->transact( - BnVsyncService::UNREGISTER_CALLBACK, data, &reply); - if (result != OK) { - ALOGE("unregisterCallback failed to transact: %d", result); - return result; - } - return result; - } -}; - -IMPLEMENT_META_INTERFACE(VsyncService, "android.dvr.IVsyncService"); - -} // namespace dvr -} // namespace android diff --git a/libs/vr/libvrsensor/Android.bp b/libs/vr/libvrsensor/Android.bp deleted file mode 100644 index 40a5099177..0000000000 --- a/libs/vr/libvrsensor/Android.bp +++ /dev/null @@ -1,63 +0,0 @@ -// Copyright (C) 2015 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. - -package { - // See: http://go/android-license-faq - // A large-scale-change added 'default_applicable_licenses' to import - // all of the 'license_kinds' from "frameworks_native_license" - // to get the below license kinds: - // SPDX-license-identifier-Apache-2.0 - default_applicable_licenses: ["frameworks_native_license"], -} - -sourceFiles = [ - "pose_client.cpp", - "latency_model.cpp", -] - -includeFiles = [ - "include", -] - -staticLibraries = [ - "libdisplay", - "libdvrcommon", - "libbroadcastring", -] - -sharedLibraries = [ - "libbase", - "libbinder", - "libbufferhubqueue", - "libcutils", - "libhardware", - "liblog", - "libutils", - "libui", - "libpdx_default_transport", -] - -cc_library { - srcs: sourceFiles, - cflags: [ - "-Wall", - "-Werror", - "-Wno-macro-redefined", - ], - export_include_dirs: includeFiles, - static_libs: staticLibraries, - shared_libs: sharedLibraries, - header_libs: ["libdvr_headers"], - name: "libvrsensor", -} diff --git a/libs/vr/libvrsensor/include/CPPLINT.cfg b/libs/vr/libvrsensor/include/CPPLINT.cfg deleted file mode 100644 index 2f8a3c018c..0000000000 --- a/libs/vr/libvrsensor/include/CPPLINT.cfg +++ /dev/null @@ -1 +0,0 @@ -filter=-build/header_guard diff --git a/libs/vr/libvrsensor/include/dvr/pose_client.h b/libs/vr/libvrsensor/include/dvr/pose_client.h deleted file mode 100644 index b663a67cea..0000000000 --- a/libs/vr/libvrsensor/include/dvr/pose_client.h +++ /dev/null @@ -1,176 +0,0 @@ -#ifndef ANDROID_DVR_POSE_CLIENT_H_ -#define ANDROID_DVR_POSE_CLIENT_H_ - -#ifdef __ARM_NEON -#include <arm_neon.h> -#else -#ifndef __FLOAT32X4T_86 -#define __FLOAT32X4T_86 -typedef float float32x4_t __attribute__ ((__vector_size__ (16))); -typedef struct float32x4x4_t { float32x4_t val[4]; } float32x4x4_t; -#endif -#endif - -#include <stdbool.h> -#include <stdint.h> - -#include <dvr/dvr_pose.h> - -#ifdef __cplusplus -extern "C" { -#endif - -typedef struct DvrPoseClient DvrPoseClient; - -// Returned by the async pose ring buffer access API. -typedef struct DvrPoseRingBufferInfo { - // Read-only pointer to the pose ring buffer. The current pose is in this - // buffer at element buffer[current_frame & (buffer_size - 1)]. The next - // frame's forecasted pose is at element - // ((current_frame + 1) & (buffer_size - 1)). And so on. The poses are - // predicted for when 50% of the corresponding frame's pixel data is visible - // to the user. - // The last value returned by dvrPresent is the count for the next frame, - // which is the earliest that the application could display something if they - // were to render promptly. (TODO(jbates) move this comment to dvrPresent). - volatile const DvrPoseAsync* buffer; - // Minimum number of accurate forecasted poses including the current frame's - // pose. This is the number of poses that are udpated by the pose service. - // If the application reads past this count, they will get a stale prediction - // from a previous frame. Guaranteed to be at least 2. - uint32_t min_future_count; - // Number of elements in buffer. At least 8 and greater than min_future_count. - // Guaranteed to be a power of two. The total size of the buffer in bytes is: - // total_count * sizeof(DvrPoseAsync) - uint32_t total_count; -} DvrPoseRingBufferInfo; - -typedef enum DvrPoseMode { - DVR_POSE_MODE_6DOF = 0, - DVR_POSE_MODE_3DOF, - DVR_POSE_MODE_MOCK_FROZEN, - DVR_POSE_MODE_MOCK_HEAD_TURN_SLOW, - DVR_POSE_MODE_MOCK_HEAD_TURN_FAST, - DVR_POSE_MODE_MOCK_ROTATE_SLOW, - DVR_POSE_MODE_MOCK_ROTATE_MEDIUM, - DVR_POSE_MODE_MOCK_ROTATE_FAST, - DVR_POSE_MODE_MOCK_CIRCLE_STRAFE, - DVR_POSE_MODE_FLOAT, - DVR_POSE_MODE_MOCK_MOTION_SICKNESS, - - // Always last. - DVR_POSE_MODE_COUNT, -} DvrPoseMode; - -typedef enum DvrControllerId { - DVR_CONTROLLER_0 = 0, - DVR_CONTROLLER_1 = 1, -} DvrControllerId; - -// Creates a new pose client. -// -// @return Pointer to the created pose client, nullptr on failure. -DvrPoseClient* dvrPoseClientCreate(); - -// Destroys a pose client. -// -// @param client Pointer to the pose client to be destroyed. -void dvrPoseClientDestroy(DvrPoseClient* client); - -// Gets the pose for the given vsync count. -// -// @param client Pointer to the pose client. -// @param vsync_count Vsync that this pose should be forward-predicted to. -// 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 dvrPoseClientGet(DvrPoseClient* client, uint32_t vsync_count, - DvrPoseAsync* out_pose); - -// Gets the current vsync count. -uint32_t dvrPoseClientGetVsyncCount(DvrPoseClient* client); - -// Gets the pose for the given controller at the given vsync count. -// -// @param client Pointer to the pose client. -// @param controller_id The controller id. -// @param vsync_count Vsync that this pose should be forward-predicted to. -// 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 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 dvrPoseClientLogController(DvrPoseClient* client, bool enable); - -// DEPRECATED -// Polls current pose state. -// -// @param client Pointer to the pose client. -// @param state Struct to store polled state. -// @return Zero on success, negative error code on failure. -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 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 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 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 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: -// index = (<current> + <offset>) % out_buffer_size -// Where <current> was the last value returned by dvrPresent and -// <offset> is less than or equal to |out_min_future_count|. -// |out_buffer| will be set to a pointer to the buffer. -// |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 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); - -// Requests a burst of data samples from pose service. The data samples are -// passed through a shared memory buffer obtained by calling -// dvrPoseClientGetDataReader(). -// -// @param DvrPoseDataCaptureRequest Parameters on how to capture data. -// @return Zero on success. -int dvrPoseClientDataCapture(DvrPoseClient* client, - const DvrPoseDataCaptureRequest* request); - -// Destroys the write buffer queue for the given |data_type|. -int dvrPoseClientDataReaderDestroy(DvrPoseClient* client, uint64_t data_type); - -#ifdef __cplusplus -} // extern "C" -#endif - -#endif // ANDROID_DVR_POSE_CLIENT_H_ diff --git a/libs/vr/libvrsensor/include/private/dvr/latency_model.h b/libs/vr/libvrsensor/include/private/dvr/latency_model.h deleted file mode 100644 index bf0e687b7f..0000000000 --- a/libs/vr/libvrsensor/include/private/dvr/latency_model.h +++ /dev/null @@ -1,29 +0,0 @@ -#ifndef ANDROID_DVR_LATENCY_MODEL_H_ -#define ANDROID_DVR_LATENCY_MODEL_H_ - -#include <vector> - -namespace android { -namespace dvr { - -// This class models the latency from sensors. It will look at the first -// window_size measurements and return their average after that. -class LatencyModel { - public: - explicit LatencyModel(size_t window_size); - ~LatencyModel() = default; - - void AddLatency(int64_t latency_ns); - int64_t CurrentLatencyEstimate() const { return latency_; } - - private: - size_t window_size_; - int64_t latency_sum_ = 0; - size_t num_summed_ = 0; - int64_t latency_ = 0; -}; - -} // namespace dvr -} // namespace android - -#endif // ANDROID_DVR_LATENCY_MODEL_H_ diff --git a/libs/vr/libvrsensor/include/private/dvr/pose-ipc.h b/libs/vr/libvrsensor/include/private/dvr/pose-ipc.h deleted file mode 100644 index 7bf1cd4d29..0000000000 --- a/libs/vr/libvrsensor/include/private/dvr/pose-ipc.h +++ /dev/null @@ -1,29 +0,0 @@ -#ifndef ANDROID_DVR_POSE_IPC_H_ -#define ANDROID_DVR_POSE_IPC_H_ - -#include <stdint.h> - -#ifdef __cplusplus -extern "C" { -#endif - -#define DVR_POSE_SERVICE_BASE "system/vr/pose" -#define DVR_POSE_SERVICE_CLIENT (DVR_POSE_SERVICE_BASE "/client") - -enum { - DVR_POSE_FREEZE = 0, - DVR_POSE_SET_MODE, - DVR_POSE_GET_MODE, - DVR_POSE_GET_CONTROLLER_RING_BUFFER, - DVR_POSE_LOG_CONTROLLER, - DVR_POSE_SENSORS_ENABLE, - DVR_POSE_GET_TANGO_READER, - DVR_POSE_DATA_CAPTURE, - DVR_POSE_TANGO_READER_DESTROY, -}; - -#ifdef __cplusplus -} // extern "C" -#endif - -#endif // ANDROID_DVR_POSE_IPC_H_ 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 39592bb15d..0000000000 --- a/libs/vr/libvrsensor/include/private/dvr/pose_client_internal.h +++ /dev/null @@ -1,19 +0,0 @@ -#ifndef ANDROID_DVR_POSE_CLIENT_INTERNAL_H_ -#define ANDROID_DVR_POSE_CLIENT_INTERNAL_H_ - -#include <private/dvr/buffer_hub_queue_client.h> - -using android::dvr::ConsumerQueue; - -typedef struct DvrPoseClient DvrPoseClient; - -namespace android { -namespace dvr { - -int dvrPoseClientGetDataReaderHandle(DvrPoseClient *client, uint64_t data_type, - ConsumerQueue **queue_out); - -} // namespace dvr -} // namespace android - -#endif // ANDROID_DVR_POSE_CLIENT_INTERNAL_H_ diff --git a/libs/vr/libvrsensor/latency_model.cpp b/libs/vr/libvrsensor/latency_model.cpp deleted file mode 100644 index d3a45210a7..0000000000 --- a/libs/vr/libvrsensor/latency_model.cpp +++ /dev/null @@ -1,24 +0,0 @@ -#include <private/dvr/latency_model.h> - -#include <cmath> - -namespace android { -namespace dvr { - -LatencyModel::LatencyModel(size_t window_size) : window_size_(window_size) {} - -void LatencyModel::AddLatency(int64_t latency_ns) { - // Not enough samples yet? - if (num_summed_ < window_size_) { - // Accumulate. - latency_sum_ += latency_ns; - - // Have enough samples for latency estimate? - if (++num_summed_ == window_size_) { - latency_ = latency_sum_ / window_size_; - } - } -} - -} // namespace dvr -} // namespace android diff --git a/libs/vr/libvrsensor/pose_client.cpp b/libs/vr/libvrsensor/pose_client.cpp deleted file mode 100644 index 4ff6a0912c..0000000000 --- a/libs/vr/libvrsensor/pose_client.cpp +++ /dev/null @@ -1,368 +0,0 @@ -#define LOG_TAG "PoseClient" -#include <dvr/dvr_shared_buffers.h> -#include <dvr/pose_client.h> - -#include <stdint.h> - -#include <log/log.h> -#include <pdx/client.h> -#include <pdx/default_transport/client_channel_factory.h> -#include <pdx/file_handle.h> -#include <private/dvr/buffer_hub_queue_client.h> -#include <private/dvr/consumer_buffer.h> -#include <private/dvr/display_client.h> -#include <private/dvr/pose-ipc.h> -#include <private/dvr/shared_buffer_helpers.h> - -using android::dvr::ConsumerQueue; -using android::pdx::LocalHandle; -using android::pdx::LocalChannelHandle; -using android::pdx::Status; -using android::pdx::Transaction; - -namespace android { -namespace dvr { -namespace { - -typedef CPUMappedBroadcastRing<DvrPoseRing> SensorPoseRing; - -constexpr static int32_t MAX_CONTROLLERS = 2; -} // namespace - -// PoseClient is a remote interface to the pose service in sensord. -class PoseClient : public pdx::ClientBase<PoseClient> { - public: - ~PoseClient() override {} - - // Casts C handle into an instance of this class. - 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(DvrPose* state) { - // Allocate the helper class to access the sensor pose buffer. - if (sensor_pose_buffer_ == nullptr) { - sensor_pose_buffer_ = std::make_unique<SensorPoseRing>( - DvrGlobalBuffers::kSensorPoseBuffer, CPUUsageMode::READ_RARELY); - } - - if (state) { - if (sensor_pose_buffer_->GetNewest(state)) { - return 0; - } else { - return -EAGAIN; - } - } - - return -EINVAL; - } - - int GetPose(uint32_t vsync_count, DvrPoseAsync* out_pose) { - const auto vsync_buffer = GetVsyncBuffer(); - if (vsync_buffer) { - *out_pose = - vsync_buffer - ->vsync_poses[vsync_count & DvrVsyncPoseBuffer::kIndexMask]; - return 0; - } else { - return -EAGAIN; - } - } - - uint32_t GetVsyncCount() { - const auto vsync_buffer = GetVsyncBuffer(); - if (vsync_buffer) { - return vsync_buffer->vsync_count; - } - - return 0; - } - - int GetControllerPose(int32_t controller_id, uint32_t vsync_count, - DvrPoseAsync* out_pose) { - if (controller_id < 0 || controller_id >= MAX_CONTROLLERS) { - return -EINVAL; - } - if (!controllers_[controller_id].mapped_pose_buffer) { - int ret = GetControllerRingBuffer(controller_id); - if (ret < 0) - return ret; - } - *out_pose = - controllers_[controller_id] - .mapped_pose_buffer[vsync_count & DvrVsyncPoseBuffer::kIndexMask]; - return 0; - } - - int LogController(bool enable) { - Transaction trans{*this}; - Status<int> status = trans.Send<int>(DVR_POSE_LOG_CONTROLLER, &enable, - sizeof(enable), nullptr, 0); - ALOGE_IF(!status, "Pose LogController() failed because: %s", - status.GetErrorMessage().c_str()); - return ReturnStatusOrError(status); - } - - // Freezes the pose to the provided state. Future poll operations will return - // 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 DvrPose& frozen_state) { - Transaction trans{*this}; - Status<int> status = trans.Send<int>(DVR_POSE_FREEZE, &frozen_state, - sizeof(frozen_state), nullptr, 0); - ALOGE_IF(!status, "Pose Freeze() failed because: %s\n", - status.GetErrorMessage().c_str()); - return ReturnStatusOrError(status); - } - - // Sets the data mode for the pose service. - int SetMode(DvrPoseMode mode) { - Transaction trans{*this}; - Status<int> status = - trans.Send<int>(DVR_POSE_SET_MODE, &mode, sizeof(mode), nullptr, 0); - ALOGE_IF(!status, "Pose SetPoseMode() failed because: %s", - status.GetErrorMessage().c_str()); - return ReturnStatusOrError(status); - } - - // Gets the data mode for the pose service. - int GetMode(DvrPoseMode* out_mode) { - int mode; - Transaction trans{*this}; - Status<int> status = - trans.Send<int>(DVR_POSE_GET_MODE, nullptr, 0, &mode, sizeof(mode)); - ALOGE_IF(!status, "Pose GetPoseMode() failed because: %s", - status.GetErrorMessage().c_str()); - if (status) - *out_mode = DvrPoseMode(mode); - return ReturnStatusOrError(status); - } - - int GetTangoReaderHandle(uint64_t data_type, ConsumerQueue** queue_out) { - // Get buffer. - Transaction trans{*this}; - Status<LocalChannelHandle> status = trans.Send<LocalChannelHandle>( - DVR_POSE_GET_TANGO_READER, &data_type, sizeof(data_type), nullptr, 0); - - if (!status) { - ALOGE("PoseClient GetTangoReaderHandle() failed because: %s", - status.GetErrorMessage().c_str()); - *queue_out = nullptr; - return -status.error(); - } - - std::unique_ptr<ConsumerQueue> consumer_queue = - ConsumerQueue::Import(status.take()); - *queue_out = consumer_queue.release(); - return 0; - } - - int DataCapture(const DvrPoseDataCaptureRequest* request) { - Transaction trans{*this}; - Status<int> status = trans.Send<int>(DVR_POSE_DATA_CAPTURE, request, - sizeof(*request), nullptr, 0); - ALOGE_IF(!status, "PoseClient DataCapture() failed because: %s\n", - status.GetErrorMessage().c_str()); - return ReturnStatusOrError(status); - } - - int DataReaderDestroy(uint64_t data_type) { - Transaction trans{*this}; - Status<int> status = trans.Send<int>(DVR_POSE_TANGO_READER_DESTROY, - &data_type, sizeof(data_type), nullptr, - 0); - ALOGE_IF(!status, "PoseClient DataReaderDestroy() failed because: %s\n", - status.GetErrorMessage().c_str()); - return ReturnStatusOrError(status); - } - - // Enables or disables all pose processing from sensors - int EnableSensors(bool enabled) { - Transaction trans{*this}; - 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; - } - - return -EAGAIN; - } - - int GetControllerRingBuffer(int32_t controller_id) { - if (controller_id < 0 || controller_id >= MAX_CONTROLLERS) { - return -EINVAL; - } - ControllerClientState& client_state = controllers_[controller_id]; - if (client_state.pose_buffer.get()) { - return 0; - } - - Transaction trans{*this}; - Status<LocalChannelHandle> status = trans.Send<LocalChannelHandle>( - DVR_POSE_GET_CONTROLLER_RING_BUFFER, &controller_id, - sizeof(controller_id), nullptr, 0); - if (!status) { - return -status.error(); - } - - auto buffer = ConsumerBuffer::Import(status.take()); - if (!buffer) { - ALOGE("Pose failed to import ring buffer"); - return -EIO; - } - constexpr size_t size = DvrVsyncPoseBuffer::kSize * sizeof(DvrPoseAsync); - void* addr = nullptr; - int ret = buffer->GetBlobReadWritePointer(size, &addr); - if (ret < 0 || !addr) { - ALOGE("Pose failed to map ring buffer: ret:%d, addr:%p", ret, addr); - return -EIO; - } - client_state.pose_buffer.swap(buffer); - 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].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], - client_state.mapped_pose_buffer[0].orientation[3]); - return 0; - } - - private: - friend BASE; - - // Set up a channel to the pose service. - PoseClient() - : BASE(pdx::default_transport::ClientChannelFactory::Create( - DVR_POSE_SERVICE_CLIENT)) { - // TODO(eieio): Cache the pose and make timeout 0 so that the API doesn't - // block while waiting for the pose service to come back up. - EnableAutoReconnect(kInfiniteTimeout); - } - - PoseClient(const PoseClient&) = delete; - PoseClient& operator=(const PoseClient&) = delete; - - 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_; - } - - // The vsync pose buffer if already mapped. - std::unique_ptr<CPUMappedBuffer> vsync_pose_buffer_; - - // The direct sensor pose buffer. - std::unique_ptr<SensorPoseRing> sensor_pose_buffer_; - - const DvrVsyncPoseBuffer* mapped_vsync_pose_buffer_ = nullptr; - - struct ControllerClientState { - std::unique_ptr<ConsumerBuffer> pose_buffer; - const DvrPoseAsync* mapped_pose_buffer = nullptr; - }; - ControllerClientState controllers_[MAX_CONTROLLERS]; -}; - -int dvrPoseClientGetDataReaderHandle(DvrPoseClient* client, uint64_t type, - ConsumerQueue** queue_out) { - return PoseClient::FromC(client)->GetTangoReaderHandle(type, queue_out); -} - -} // namespace dvr -} // namespace android - -using android::dvr::PoseClient; - -extern "C" { - -DvrPoseClient* dvrPoseClientCreate() { - auto* client = PoseClient::Create().release(); - return reinterpret_cast<DvrPoseClient*>(client); -} - -void dvrPoseClientDestroy(DvrPoseClient* client) { - delete PoseClient::FromC(client); -} - -int dvrPoseClientGet(DvrPoseClient* client, uint32_t vsync_count, - DvrPoseAsync* out_pose) { - return PoseClient::FromC(client)->GetPose(vsync_count, out_pose); -} - -uint32_t dvrPoseClientGetVsyncCount(DvrPoseClient* client) { - return PoseClient::FromC(client)->GetVsyncCount(); -} - -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 dvrPoseClientLogController(DvrPoseClient* client, bool enable) { - return PoseClient::FromC(client)->LogController(enable); -} - -int dvrPoseClientPoll(DvrPoseClient* client, DvrPose* state) { - return PoseClient::FromC(client)->Poll(state); -} - -int dvrPoseClientFreeze(DvrPoseClient* client, const DvrPose* frozen_state) { - return PoseClient::FromC(client)->Freeze(*frozen_state); -} - -int dvrPoseClientModeSet(DvrPoseClient* client, DvrPoseMode mode) { - return PoseClient::FromC(client)->SetMode(mode); -} - -int dvrPoseClientModeGet(DvrPoseClient* client, DvrPoseMode* mode) { - return PoseClient::FromC(client)->GetMode(mode); -} - -int dvrPoseClientSensorsEnable(DvrPoseClient* client, bool enabled) { - return PoseClient::FromC(client)->EnableSensors(enabled); -} - -int dvrPoseClientDataCapture(DvrPoseClient* client, - const DvrPoseDataCaptureRequest* request) { - return PoseClient::FromC(client)->DataCapture(request); -} - -int dvrPoseClientDataReaderDestroy(DvrPoseClient* client, uint64_t data_type) { - return PoseClient::FromC(client)->DataReaderDestroy(data_type); -} - -} // extern "C" diff --git a/services/vr/hardware_composer/Android.bp b/services/vr/hardware_composer/Android.bp deleted file mode 100644 index 80e9a3c3b1..0000000000 --- a/services/vr/hardware_composer/Android.bp +++ /dev/null @@ -1,134 +0,0 @@ -package { - // See: http://go/android-license-faq - // A large-scale-change added 'default_applicable_licenses' to import - // all of the 'license_kinds' from "frameworks_native_license" - // to get the below license kinds: - // SPDX-license-identifier-Apache-2.0 - default_applicable_licenses: ["frameworks_native_license"], -} - -cc_library_shared { - name: "libvr_hwc-hal", - - system_ext_specific: true, - - srcs: [ - "impl/vr_hwc.cpp", - "impl/vr_composer_client.cpp", - ], - - static_libs: [ - "libbroadcastring", - "libdisplay", - ], - - shared_libs: [ - "android.frameworks.vr.composer@2.0", - "android.hardware.graphics.composer@2.1", - "android.hardware.graphics.composer@2.2", - "android.hardware.graphics.composer@2.3", - "android.hardware.graphics.composer@2.1-resources", - "android.hardware.graphics.mapper@2.0", - "android.hardware.graphics.mapper@3.0", - "android.hardware.graphics.mapper@4.0", - "libbase", - "libbufferhubqueue", - "libbinder", - "libcutils", - "libfmq", - "libhardware", - "libhidlbase", - "liblog", - "libsync", - "libui", - "libutils", - "libpdx_default_transport", - ], - - header_libs: [ - "android.hardware.graphics.composer@2.1-command-buffer", - "android.hardware.graphics.composer@2.3-hal", - ], - - export_header_lib_headers: [ - "android.hardware.graphics.composer@2.3-hal", - ], - - export_static_lib_headers: [ - "libdisplay", - ], - - export_shared_lib_headers: [ - "android.frameworks.vr.composer@2.0", - "android.hardware.graphics.composer@2.1", - "android.hardware.graphics.composer@2.2", - "android.hardware.graphics.composer@2.3", - ], - - export_include_dirs: ["."], - - cflags: [ - "-DLOG_TAG=\"vr_hwc\"", - "-DATRACE_TAG=ATRACE_TAG_GRAPHICS", - "-Wall", - "-Werror", - "-Wno-error=unused-private-field", - // Warnings in vr_hwc.cpp to be fixed after sync of goog/master. - "-Wno-sign-compare", - "-Wno-unused-parameter", - ], - -} - -cc_library_static { - name: "libvr_hwc-impl", - srcs: [ - "vr_composer.cpp", - ], - static_libs: [ - "libvr_hwc-binder", - ], - shared_libs: [ - "libbase", - "libbinder", - "liblog", - "libui", - "libutils", - "libvr_hwc-hal", - ], - export_shared_lib_headers: [ - "libvr_hwc-hal", - ], - cflags: [ - "-DLOG_TAG=\"vr_hwc\"", - "-Wall", - "-Werror", - ], -} - -cc_test { - name: "vr_hwc_test", - gtest: true, - srcs: ["tests/vr_composer_test.cpp"], - static_libs: [ - "libgtest", - "libvr_hwc-impl", - // NOTE: This needs to be included after the *-impl lib otherwise the - // symbols in the *-binder library get optimized out. - "libvr_hwc-binder", - ], - cflags: [ - "-Wall", - "-Werror", - // warnings in vr_composer_test.cpp to be fixed after merge of goog/master - "-Wno-sign-compare", - "-Wno-unused-parameter", - ], - shared_libs: [ - "libbase", - "libbinder", - "liblog", - "libui", - "libutils", - ], -} diff --git a/services/vr/hardware_composer/aidl/Android.bp b/services/vr/hardware_composer/aidl/Android.bp deleted file mode 100644 index fa71ed7633..0000000000 --- a/services/vr/hardware_composer/aidl/Android.bp +++ /dev/null @@ -1,36 +0,0 @@ -package { - // See: http://go/android-license-faq - // A large-scale-change added 'default_applicable_licenses' to import - // all of the 'license_kinds' from "frameworks_native_license" - // to get the below license kinds: - // SPDX-license-identifier-Apache-2.0 - default_applicable_licenses: ["frameworks_native_license"], -} - -cc_library_static { - name: "libvr_hwc-binder", - srcs: [ - "android/dvr/IVrComposer.aidl", - "android/dvr/IVrComposerCallback.aidl", - "android/dvr/parcelable_composer_frame.cpp", - "android/dvr/parcelable_composer_layer.cpp", - "android/dvr/parcelable_unique_fd.cpp", - ], - aidl: { - local_include_dirs: ["."], - export_aidl_headers: true, - }, - export_include_dirs: ["."], - - cflags: [ - "-Wall", - "-Werror", - ], - - shared_libs: [ - "libbinder", - "libui", - "libutils", - "libvr_hwc-hal", - ], -} diff --git a/services/vr/hardware_composer/aidl/android/dvr/IVrComposer.aidl b/services/vr/hardware_composer/aidl/android/dvr/IVrComposer.aidl deleted file mode 100644 index be1ec5b2a3..0000000000 --- a/services/vr/hardware_composer/aidl/android/dvr/IVrComposer.aidl +++ /dev/null @@ -1,25 +0,0 @@ -package android.dvr; - -import android.dvr.IVrComposerCallback; - -/** - * Service interface exposed by VR HWC exposed to system apps which allows one - * system app to connect to get SurfaceFlinger's outputs (all displays). This - * is active when SurfaceFlinger is in VR mode, where all 2D output is - * redirected to VR HWC. - * - * @hide */ -interface IVrComposer -{ - const String SERVICE_NAME = "vr_hwc"; - - /** - * Registers a callback used to receive frame notifications. - */ - void registerObserver(in IVrComposerCallback callback); - - /** - * Clears a previously registered frame notification callback. - */ - void clearObserver(); -} diff --git a/services/vr/hardware_composer/aidl/android/dvr/IVrComposerCallback.aidl b/services/vr/hardware_composer/aidl/android/dvr/IVrComposerCallback.aidl deleted file mode 100644 index aa70de1645..0000000000 --- a/services/vr/hardware_composer/aidl/android/dvr/IVrComposerCallback.aidl +++ /dev/null @@ -1,22 +0,0 @@ -package android.dvr; - -import android.dvr.ParcelableComposerFrame; -import android.dvr.ParcelableUniqueFd; - -/** - * A system app will implement and register this callback with VRComposer - * to receive the layers SurfaceFlinger presented when in VR mode. - * - * @hide */ -interface IVrComposerCallback { - /** - * Called by the VR HWC service when a new frame is ready to be presented. - * - * @param frame The new frame VR HWC wants to present. - * @return A fence FD used to signal when the previous frame is no longer - * used by the client. This may be an invalid fence (-1) if the client is not - * using the previous frame, in which case the previous frame may be re-used - * at any point in time. - */ - ParcelableUniqueFd onNewFrame(in ParcelableComposerFrame frame); -} diff --git a/services/vr/hardware_composer/aidl/android/dvr/ParcelableComposerFrame.aidl b/services/vr/hardware_composer/aidl/android/dvr/ParcelableComposerFrame.aidl deleted file mode 100644 index 84abc19c23..0000000000 --- a/services/vr/hardware_composer/aidl/android/dvr/ParcelableComposerFrame.aidl +++ /dev/null @@ -1,3 +0,0 @@ -package android.dvr; - -parcelable ParcelableComposerFrame cpp_header "android/dvr/parcelable_composer_frame.h"; diff --git a/services/vr/hardware_composer/aidl/android/dvr/ParcelableComposerLayer.aidl b/services/vr/hardware_composer/aidl/android/dvr/ParcelableComposerLayer.aidl deleted file mode 100644 index a200345fbd..0000000000 --- a/services/vr/hardware_composer/aidl/android/dvr/ParcelableComposerLayer.aidl +++ /dev/null @@ -1,3 +0,0 @@ -package android.dvr; - -parcelable ParcelableComposerLayer cpp_header "android/dvr/parcelable_composer_layer.h"; diff --git a/services/vr/hardware_composer/aidl/android/dvr/ParcelableUniqueFd.aidl b/services/vr/hardware_composer/aidl/android/dvr/ParcelableUniqueFd.aidl deleted file mode 100644 index eee9d138ba..0000000000 --- a/services/vr/hardware_composer/aidl/android/dvr/ParcelableUniqueFd.aidl +++ /dev/null @@ -1,3 +0,0 @@ -package android.dvr; - -parcelable ParcelableUniqueFd cpp_header "android/dvr/parcelable_unique_fd.h"; diff --git a/services/vr/hardware_composer/aidl/android/dvr/parcelable_composer_frame.cpp b/services/vr/hardware_composer/aidl/android/dvr/parcelable_composer_frame.cpp deleted file mode 100644 index db7d5dc225..0000000000 --- a/services/vr/hardware_composer/aidl/android/dvr/parcelable_composer_frame.cpp +++ /dev/null @@ -1,110 +0,0 @@ -#include "aidl/android/dvr/parcelable_composer_frame.h" - -#include <binder/Parcel.h> - -#include "aidl/android/dvr/parcelable_composer_layer.h" - -namespace android { -namespace dvr { - -ParcelableComposerFrame::ParcelableComposerFrame() {} - -ParcelableComposerFrame::ParcelableComposerFrame( - const ComposerView::Frame& frame) - : frame_(frame) {} - -ParcelableComposerFrame::~ParcelableComposerFrame() {} - -status_t ParcelableComposerFrame::writeToParcel(Parcel* parcel) const { - status_t ret = parcel->writeUint64(frame_.display_id); - if (ret != OK) return ret; - - ret = parcel->writeInt32(frame_.display_width); - if (ret != OK) return ret; - - ret = parcel->writeInt32(frame_.display_height); - if (ret != OK) return ret; - - ret = parcel->writeBool(frame_.removed); - if (ret != OK) return ret; - - ret = parcel->writeUint32(static_cast<uint32_t>(frame_.active_config)); - if (ret != OK) return ret; - - ret = parcel->writeUint32(static_cast<uint32_t>(frame_.color_mode)); - if (ret != OK) return ret; - - ret = parcel->writeUint32(static_cast<uint32_t>(frame_.power_mode)); - if (ret != OK) return ret; - - ret = parcel->writeUint32(static_cast<uint32_t>(frame_.vsync_enabled)); - if (ret != OK) return ret; - - ret = parcel->writeInt32(frame_.color_transform_hint); - if (ret != OK) return ret; - - for(size_t i = 0; i < 16; i++) { - ret = parcel->writeFloat(frame_.color_transform[i]); - if (ret != OK) return ret; - } - - std::vector<ParcelableComposerLayer> layers; - for (size_t i = 0; i < frame_.layers.size(); ++i) - layers.push_back(ParcelableComposerLayer(frame_.layers[i])); - - ret = parcel->writeParcelableVector(layers); - - return ret; -} - -status_t ParcelableComposerFrame::readFromParcel(const Parcel* parcel) { - status_t ret = parcel->readUint64(&frame_.display_id); - if (ret != OK) return ret; - - ret = parcel->readInt32(&frame_.display_width); - if (ret != OK) return ret; - - ret = parcel->readInt32(&frame_.display_height); - if (ret != OK) return ret; - - ret = parcel->readBool(&frame_.removed); - if (ret != OK) return ret; - - uint32_t value; - ret = parcel->readUint32(&value); - if (ret != OK) return ret; - frame_.active_config = static_cast<Config>(value); - - ret = parcel->readUint32(&value); - if (ret != OK) return ret; - frame_.color_mode = static_cast<ColorMode>(value); - - ret = parcel->readUint32(&value); - if (ret != OK) return ret; - frame_.power_mode = static_cast<IComposerClient::PowerMode>(value); - - ret = parcel->readUint32(&value); - if (ret != OK) return ret; - frame_.vsync_enabled = static_cast<IComposerClient::Vsync>(value); - - ret = parcel->readInt32(&frame_.color_transform_hint); - if (ret != OK) return ret; - - for(size_t i = 0; i < 16; i++) { - ret = parcel->readFloat(&frame_.color_transform[i]); - if (ret != OK) return ret; - } - - std::vector<ParcelableComposerLayer> layers; - ret = parcel->readParcelableVector(&layers); - if (ret != OK) return ret; - - frame_.layers.clear(); - for (size_t i = 0; i < layers.size(); ++i) - frame_.layers.push_back(layers[i].layer()); - - return ret; -} - -} // namespace dvr -} // namespace android diff --git a/services/vr/hardware_composer/aidl/android/dvr/parcelable_composer_frame.h b/services/vr/hardware_composer/aidl/android/dvr/parcelable_composer_frame.h deleted file mode 100644 index a82df7f2e7..0000000000 --- a/services/vr/hardware_composer/aidl/android/dvr/parcelable_composer_frame.h +++ /dev/null @@ -1,28 +0,0 @@ -#ifndef ANDROID_DVR_HARDWARE_COMPOSER_AIDL_ANDROID_DVR_PARCELABLE_COMPOSER_FRAME_H -#define ANDROID_DVR_HARDWARE_COMPOSER_AIDL_ANDROID_DVR_PARCELABLE_COMPOSER_FRAME_H - -#include <binder/Parcelable.h> -#include <impl/vr_hwc.h> - -namespace android { -namespace dvr { - -class ParcelableComposerFrame : public Parcelable { - public: - ParcelableComposerFrame(); - explicit ParcelableComposerFrame(const ComposerView::Frame& frame); - ~ParcelableComposerFrame() override; - - ComposerView::Frame frame() const { return frame_; } - - status_t writeToParcel(Parcel* parcel) const override; - status_t readFromParcel(const Parcel* parcel) override; - - private: - ComposerView::Frame frame_; -}; - -} // namespace dvr -} // namespace android - -#endif // ANDROID_DVR_HARDWARE_COMPOSER_AIDL_ANDROID_DVR_PARCELABLE_COMPOSER_FRAME_H diff --git a/services/vr/hardware_composer/aidl/android/dvr/parcelable_composer_layer.cpp b/services/vr/hardware_composer/aidl/android/dvr/parcelable_composer_layer.cpp deleted file mode 100644 index c3621ebf0f..0000000000 --- a/services/vr/hardware_composer/aidl/android/dvr/parcelable_composer_layer.cpp +++ /dev/null @@ -1,240 +0,0 @@ -#include "aidl/android/dvr/parcelable_composer_layer.h" - -#include <binder/Parcel.h> -#include <ui/Fence.h> -#include <ui/GraphicBuffer.h> -#include <ui/GraphicBufferMapper.h> - -namespace android { -namespace dvr { - -ParcelableComposerLayer::ParcelableComposerLayer() {} - -ParcelableComposerLayer::ParcelableComposerLayer( - const ComposerView::ComposerLayer& layer) : layer_(layer) {} - -ParcelableComposerLayer::~ParcelableComposerLayer() {} - -status_t ParcelableComposerLayer::writeToParcel(Parcel* parcel) const { - status_t ret = parcel->writeUint64(layer_.id); - if (ret != OK) return ret; - - ret = parcel->write(*layer_.buffer); - if (ret != OK) return ret; - - ret = parcel->writeBool(layer_.fence->isValid()); - if (ret != OK) return ret; - - if (layer_.fence->isValid()) { - ret = parcel->writeFileDescriptor(layer_.fence->dup(), true); - if (ret != OK) return ret; - } - - ret = parcel->writeInt32(layer_.display_frame.left); - if (ret != OK) return ret; - - ret = parcel->writeInt32(layer_.display_frame.top); - if (ret != OK) return ret; - - ret = parcel->writeInt32(layer_.display_frame.right); - if (ret != OK) return ret; - - ret = parcel->writeInt32(layer_.display_frame.bottom); - if (ret != OK) return ret; - - ret = parcel->writeFloat(layer_.crop.left); - if (ret != OK) return ret; - - ret = parcel->writeFloat(layer_.crop.top); - if (ret != OK) return ret; - - ret = parcel->writeFloat(layer_.crop.right); - if (ret != OK) return ret; - - ret = parcel->writeFloat(layer_.crop.bottom); - if (ret != OK) return ret; - - ret = parcel->writeInt32(static_cast<int32_t>(layer_.blend_mode)); - if (ret != OK) return ret; - - ret = parcel->writeFloat(layer_.alpha); - if (ret != OK) return ret; - - ret = parcel->writeUint32(layer_.type); - if (ret != OK) return ret; - - ret = parcel->writeUint32(layer_.app_id); - if (ret != OK) return ret; - - ret = parcel->writeUint32(layer_.z_order); - if (ret != OK) return ret; - - ret = parcel->writeInt32(layer_.cursor_x); - if (ret != OK) return ret; - - ret = parcel->writeInt32(layer_.cursor_y); - if (ret != OK) return ret; - - uint32_t color = layer_.color.r | - (static_cast<uint32_t>(layer_.color.g) << 8) | - (static_cast<uint32_t>(layer_.color.b) << 16) | - (static_cast<uint32_t>(layer_.color.a) << 24); - ret = parcel->writeUint32(color); - if (ret != OK) return ret; - - ret = parcel->writeInt32(layer_.dataspace); - if (ret != OK) return ret; - - ret = parcel->writeInt32(layer_.transform); - if (ret != OK) return ret; - - ret = parcel->writeUint32(static_cast<uint32_t>(layer_.visible_regions.size())); - if (ret != OK) return ret; - - for (auto& rect: layer_.visible_regions) { - ret = parcel->writeInt32(rect.left); - ret = parcel->writeInt32(rect.top); - ret = parcel->writeInt32(rect.right); - ret = parcel->writeInt32(rect.bottom); - if (ret != OK) return ret; - } - - ret = parcel->writeUint32(static_cast<uint32_t>(layer_.damaged_regions.size())); - if (ret != OK) return ret; - - for (auto& rect: layer_.damaged_regions) { - ret = parcel->writeInt32(rect.left); - ret = parcel->writeInt32(rect.top); - ret = parcel->writeInt32(rect.right); - ret = parcel->writeInt32(rect.bottom); - if (ret != OK) return ret; - } - - return OK; -} - -status_t ParcelableComposerLayer::readFromParcel(const Parcel* parcel) { - status_t ret = parcel->readUint64(&layer_.id); - if (ret != OK) return ret; - - layer_.buffer = new GraphicBuffer(); - ret = parcel->read(*layer_.buffer); - if (ret != OK) { - layer_.buffer.clear(); - return ret; - } - - bool has_fence = 0; - ret = parcel->readBool(&has_fence); - if (ret != OK) return ret; - - if (has_fence) - layer_.fence = new Fence(dup(parcel->readFileDescriptor())); - else - layer_.fence = new Fence(); - - ret = parcel->readInt32(&layer_.display_frame.left); - if (ret != OK) return ret; - - ret = parcel->readInt32(&layer_.display_frame.top); - if (ret != OK) return ret; - - ret = parcel->readInt32(&layer_.display_frame.right); - if (ret != OK) return ret; - - ret = parcel->readInt32(&layer_.display_frame.bottom); - if (ret != OK) return ret; - - ret = parcel->readFloat(&layer_.crop.left); - if (ret != OK) return ret; - - ret = parcel->readFloat(&layer_.crop.top); - if (ret != OK) return ret; - - ret = parcel->readFloat(&layer_.crop.right); - if (ret != OK) return ret; - - ret = parcel->readFloat(&layer_.crop.bottom); - if (ret != OK) return ret; - - ret = parcel->readInt32(reinterpret_cast<int32_t*>(&layer_.blend_mode)); - if (ret != OK) return ret; - - ret = parcel->readFloat(&layer_.alpha); - if (ret != OK) return ret; - - ret = parcel->readUint32(&layer_.type); - if (ret != OK) return ret; - - ret = parcel->readUint32(&layer_.app_id); - if (ret != OK) return ret; - - ret = parcel->readUint32(&layer_.z_order); - if (ret != OK) return ret; - - ret = parcel->readInt32(&layer_.cursor_x); - if (ret != OK) return ret; - - ret = parcel->readInt32(&layer_.cursor_y); - if (ret != OK) return ret; - - uint32_t color; - ret = parcel->readUint32(&color); - if (ret != OK) return ret; - layer_.color.r = color & 0xFF; - layer_.color.g = (color >> 8) & 0xFF; - layer_.color.b = (color >> 16) & 0xFF; - layer_.color.a = (color >> 24) & 0xFF; - - ret = parcel->readInt32(&layer_.dataspace); - if (ret != OK) return ret; - - ret = parcel->readInt32(&layer_.transform); - if (ret != OK) return ret; - - uint32_t size; - ret = parcel->readUint32(&size); - if (ret != OK) return ret; - - for(size_t i = 0; i < size; i++) { - hwc_rect_t rect; - ret = parcel->readInt32(&rect.left); - if (ret != OK) return ret; - - ret = parcel->readInt32(&rect.top); - if (ret != OK) return ret; - - ret = parcel->readInt32(&rect.right); - if (ret != OK) return ret; - - ret = parcel->readInt32(&rect.bottom); - if (ret != OK) return ret; - - layer_.visible_regions.push_back(rect); - } - - ret = parcel->readUint32(&size); - if (ret != OK) return ret; - - for(size_t i = 0; i < size; i++) { - hwc_rect_t rect; - ret = parcel->readInt32(&rect.left); - if (ret != OK) return ret; - - ret = parcel->readInt32(&rect.top); - if (ret != OK) return ret; - - ret = parcel->readInt32(&rect.right); - if (ret != OK) return ret; - - ret = parcel->readInt32(&rect.bottom); - if (ret != OK) return ret; - - layer_.damaged_regions.push_back(rect); - } - - return OK; -} - -} // namespace dvr -} // namespace android diff --git a/services/vr/hardware_composer/aidl/android/dvr/parcelable_composer_layer.h b/services/vr/hardware_composer/aidl/android/dvr/parcelable_composer_layer.h deleted file mode 100644 index 6d2ac097e5..0000000000 --- a/services/vr/hardware_composer/aidl/android/dvr/parcelable_composer_layer.h +++ /dev/null @@ -1,30 +0,0 @@ -#ifndef ANDROID_DVR_HARDWARE_COMPOSER_AIDL_ANDROID_DVR_PARCELABLE_COMPOSER_LAYER_H -#define ANDROID_DVR_HARDWARE_COMPOSER_AIDL_ANDROID_DVR_PARCELABLE_COMPOSER_LAYER_H - -#include <binder/Parcelable.h> -#include <impl/vr_hwc.h> - -#include <memory> - -namespace android { -namespace dvr { - -class ParcelableComposerLayer : public Parcelable { - public: - ParcelableComposerLayer(); - explicit ParcelableComposerLayer(const ComposerView::ComposerLayer& layer); - ~ParcelableComposerLayer() override; - - ComposerView::ComposerLayer layer() const { return layer_; } - - status_t writeToParcel(Parcel* parcel) const override; - status_t readFromParcel(const Parcel* parcel) override; - - private: - ComposerView::ComposerLayer layer_; -}; - -} // namespace dvr -} // namespace android - -#endif // ANDROID_DVR_HARDWARE_COMPOSER_AIDL_ANDROID_DVR_PARCELABLE_COMPOSER_LAYER_H diff --git a/services/vr/hardware_composer/aidl/android/dvr/parcelable_unique_fd.cpp b/services/vr/hardware_composer/aidl/android/dvr/parcelable_unique_fd.cpp deleted file mode 100644 index 9486f3c919..0000000000 --- a/services/vr/hardware_composer/aidl/android/dvr/parcelable_unique_fd.cpp +++ /dev/null @@ -1,37 +0,0 @@ -#include "android/dvr/parcelable_unique_fd.h" - -#include <binder/Parcel.h> - -namespace android { -namespace dvr { - -ParcelableUniqueFd::ParcelableUniqueFd() {} - -ParcelableUniqueFd::ParcelableUniqueFd(const base::unique_fd& fence) - : fence_(dup(fence.get())) {} - -ParcelableUniqueFd::~ParcelableUniqueFd() {} - -status_t ParcelableUniqueFd::writeToParcel(Parcel* parcel) const { - status_t ret = parcel->writeBool(fence_.get() >= 0); - if (ret != OK) return ret; - - if (fence_.get() >= 0) - ret = parcel->writeUniqueFileDescriptor(fence_); - - return ret; -} - -status_t ParcelableUniqueFd::readFromParcel(const Parcel* parcel) { - bool has_fence = 0; - status_t ret = parcel->readBool(&has_fence); - if (ret != OK) return ret; - - if (has_fence) - ret = parcel->readUniqueFileDescriptor(&fence_); - - return ret; -} - -} // namespace dvr -} // namespace android diff --git a/services/vr/hardware_composer/aidl/android/dvr/parcelable_unique_fd.h b/services/vr/hardware_composer/aidl/android/dvr/parcelable_unique_fd.h deleted file mode 100644 index c4216f6212..0000000000 --- a/services/vr/hardware_composer/aidl/android/dvr/parcelable_unique_fd.h +++ /dev/null @@ -1,34 +0,0 @@ -#ifndef ANDROID_DVR_HARDWARE_COMPOSER_AIDL_ANDROID_DVR_PARCELABLE_UNIQUE_FD_H -#define ANDROID_DVR_HARDWARE_COMPOSER_AIDL_ANDROID_DVR_PARCELABLE_UNIQUE_FD_H - -#include <android-base/unique_fd.h> -#include <binder/Parcelable.h> - -namespace android { -namespace dvr { - -// Provide a wrapper to serialized base::unique_fd. The wrapper also handles the -// case where the FD is invalid (-1), unlike FileDescriptor which expects a -// valid FD. -class ParcelableUniqueFd : public Parcelable { - public: - ParcelableUniqueFd(); - explicit ParcelableUniqueFd(const base::unique_fd& fence); - ~ParcelableUniqueFd() override; - - void set_fence(const base::unique_fd& fence) { - fence_.reset(dup(fence.get())); - } - base::unique_fd fence() const { return base::unique_fd(dup(fence_.get())); } - - status_t writeToParcel(Parcel* parcel) const override; - status_t readFromParcel(const Parcel* parcel) override; - - private: - base::unique_fd fence_; -}; - -} // namespace dvr -} // namespace android - -#endif // ANDROID_DVR_HARDWARE_COMPOSER_AIDL_ANDROID_DVR_PARCELABLE_UNIQUE_FD_H diff --git a/services/vr/hardware_composer/impl/vr_composer_client.cpp b/services/vr/hardware_composer/impl/vr_composer_client.cpp deleted file mode 100644 index dd1603d4a9..0000000000 --- a/services/vr/hardware_composer/impl/vr_composer_client.cpp +++ /dev/null @@ -1,123 +0,0 @@ -/* - * Copyright 2016 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include <android/frameworks/vr/composer/2.0/IVrComposerClient.h> -#include <hardware/gralloc.h> -#include <hardware/gralloc1.h> -#include <log/log.h> - -#include <memory> - -#include "impl/vr_hwc.h" -#include "impl/vr_composer_client.h" - -namespace android { -namespace dvr { - -using android::frameworks::vr::composer::V2_0::IVrComposerClient; - -VrComposerClient::VrComposerClient(dvr::VrHwc& hal) - : ComposerClient(&hal), mVrHal(hal) { - if (!init()) { - LOG_ALWAYS_FATAL("failed to initialize VrComposerClient"); - } -} - -VrComposerClient::~VrComposerClient() {} - -std::unique_ptr<ComposerCommandEngine> -VrComposerClient::createCommandEngine() { - return std::make_unique<VrCommandEngine>(*this); -} - -VrComposerClient::VrCommandEngine::VrCommandEngine(VrComposerClient& client) - : ComposerCommandEngine(client.mHal, client.mResources.get()), - mVrHal(client.mVrHal) {} - -VrComposerClient::VrCommandEngine::~VrCommandEngine() {} - -bool VrComposerClient::VrCommandEngine::executeCommand( - hardware::graphics::composer::V2_1::IComposerClient::Command command, - uint16_t length) { - IVrComposerClient::VrCommand vrCommand = - static_cast<IVrComposerClient::VrCommand>(command); - switch (vrCommand) { - case IVrComposerClient::VrCommand::SET_LAYER_INFO: - return executeSetLayerInfo(length); - case IVrComposerClient::VrCommand::SET_CLIENT_TARGET_METADATA: - return executeSetClientTargetMetadata(length); - case IVrComposerClient::VrCommand::SET_LAYER_BUFFER_METADATA: - return executeSetLayerBufferMetadata(length); - default: - return ComposerCommandEngine::executeCommand(command, length); - } -} - -bool VrComposerClient::VrCommandEngine::executeSetLayerInfo(uint16_t length) { - if (length != 2) { - return false; - } - - auto err = mVrHal.setLayerInfo(mCurrentDisplay, mCurrentLayer, read(), read()); - if (err != Error::NONE) { - mWriter->setError(getCommandLoc(), err); - } - - return true; -} - -bool VrComposerClient::VrCommandEngine::executeSetClientTargetMetadata( - uint16_t length) { - if (length != 7) - return false; - - auto err = mVrHal.setClientTargetMetadata(mCurrentDisplay, readBufferMetadata()); - if (err != Error::NONE) - mWriter->setError(getCommandLoc(), err); - - return true; -} - -bool VrComposerClient::VrCommandEngine::executeSetLayerBufferMetadata( - uint16_t length) { - if (length != 7) - return false; - - auto err = mVrHal.setLayerBufferMetadata(mCurrentDisplay, mCurrentLayer, - readBufferMetadata()); - if (err != Error::NONE) - mWriter->setError(getCommandLoc(), err); - - return true; -} - -IVrComposerClient::BufferMetadata -VrComposerClient::VrCommandEngine::readBufferMetadata() { - IVrComposerClient::BufferMetadata metadata = { - .width = read(), - .height = read(), - .stride = read(), - .layerCount = read(), - .format = - static_cast<android::hardware::graphics::common::V1_2::PixelFormat>( - readSigned()), - .usage = read64(), - }; - return metadata; -} - -} // namespace dvr -} // namespace android diff --git a/services/vr/hardware_composer/impl/vr_composer_client.h b/services/vr/hardware_composer/impl/vr_composer_client.h deleted file mode 100644 index 1b2b5f4f56..0000000000 --- a/services/vr/hardware_composer/impl/vr_composer_client.h +++ /dev/null @@ -1,76 +0,0 @@ -/* - * Copyright 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_DVR_HARDWARE_COMPOSER_IMPL_VR_COMPOSER_CLIENT_H -#define ANDROID_DVR_HARDWARE_COMPOSER_IMPL_VR_COMPOSER_CLIENT_H - -#include <android/frameworks/vr/composer/2.0/IVrComposerClient.h> -#include <composer-command-buffer/2.3/ComposerCommandBuffer.h> -#include <composer-hal/2.1/ComposerClient.h> -#include <composer-hal/2.1/ComposerCommandEngine.h> -#include <composer-hal/2.2/ComposerClient.h> -#include <composer-hal/2.3/ComposerClient.h> - -namespace android { -namespace dvr { - -class VrHwc; - -using hardware::graphics::composer::V2_1::hal::ComposerCommandEngine; -using hardware::graphics::composer::V2_3::hal::ComposerHal; -using hardware::graphics::composer::V2_3::hal::detail::ComposerClientImpl; - -using ComposerClient = ComposerClientImpl<IVrComposerClient, ComposerHal>; - -class VrComposerClient : public ComposerClient { - public: - explicit VrComposerClient(android::dvr::VrHwc& hal); - virtual ~VrComposerClient(); - - private: - class VrCommandEngine : public ComposerCommandEngine { - public: - explicit VrCommandEngine(VrComposerClient& client); - ~VrCommandEngine() override; - - bool executeCommand( - hardware::graphics::composer::V2_1::IComposerClient::Command command, - uint16_t length) override; - - private: - bool executeSetLayerInfo(uint16_t length); - bool executeSetClientTargetMetadata(uint16_t length); - bool executeSetLayerBufferMetadata(uint16_t length); - - IVrComposerClient::BufferMetadata readBufferMetadata(); - - android::dvr::VrHwc& mVrHal; - - VrCommandEngine(const VrCommandEngine&) = delete; - void operator=(const VrCommandEngine&) = delete; - }; - - VrComposerClient(const VrComposerClient&) = delete; - void operator=(const VrComposerClient&) = delete; - - std::unique_ptr<ComposerCommandEngine> createCommandEngine() override; - dvr::VrHwc& mVrHal; -}; - -} // namespace dvr -} // namespace android - -#endif // ANDROID_DVR_HARDWARE_COMPOSER_IMPL_VR_COMPOSER_CLIENT_H diff --git a/services/vr/hardware_composer/impl/vr_hwc.cpp b/services/vr/hardware_composer/impl/vr_hwc.cpp deleted file mode 100644 index e530b16b1b..0000000000 --- a/services/vr/hardware_composer/impl/vr_hwc.cpp +++ /dev/null @@ -1,1178 +0,0 @@ -/* - * Copyright 2016 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -#include "impl/vr_hwc.h" - -#include "android-base/stringprintf.h" -#include <binder/IServiceManager.h> -#include <cutils/properties.h> -#include <private/dvr/display_client.h> -#include <ui/Fence.h> -#include <utils/Trace.h> - -#include <mutex> - -#include "vr_composer_client.h" - -using namespace android::hardware::graphics::common::V1_0; -using namespace android::hardware::graphics::composer::V2_3; - -using android::base::StringPrintf; -using android::hardware::hidl_handle; -using android::hardware::hidl_string; -using android::hardware::hidl_vec; -using android::hardware::Return; -using android::hardware::Void; - -namespace types = android::hardware::graphics::common; - -namespace android { -namespace dvr { -namespace { - -const Display kDefaultDisplayId = 1; -const Config kDefaultConfigId = 1; - -sp<GraphicBuffer> CreateGraphicBuffer( - const native_handle_t* handle, - const IVrComposerClient::BufferMetadata& metadata) { - sp<GraphicBuffer> buffer = new GraphicBuffer( - handle, GraphicBuffer::CLONE_HANDLE, metadata.width, metadata.height, - static_cast<int32_t>(metadata.format), metadata.layerCount, - metadata.usage, metadata.stride); - if (buffer->initCheck() != OK) { - ALOGE("Failed to create graphic buffer"); - return nullptr; - } - - return buffer; -} - -void GetPrimaryDisplaySize(int32_t* width, int32_t* height) { - *width = 1080; - *height = 1920; - - int error = 0; - auto display_client = display::DisplayClient::Create(&error); - if (!display_client) { - ALOGE("Could not connect to display service : %s(%d)", strerror(error), - error); - return; - } - - auto status = display_client->GetDisplayMetrics(); - if (!status) { - ALOGE("Could not get display metrics from display service : %s(%d)", - status.GetErrorMessage().c_str(), status.error()); - return; - } - - *width = status.get().display_width; - *height = status.get().display_height; -} - -} // namespace - -HwcDisplay::HwcDisplay(int32_t width, int32_t height) - : width_(width), height_(height) {} - -HwcDisplay::~HwcDisplay() {} - -bool HwcDisplay::SetClientTarget(const native_handle_t* handle, - base::unique_fd fence) { - if (handle) - buffer_ = CreateGraphicBuffer(handle, buffer_metadata_); - - fence_ = new Fence(fence.release()); - return true; -} - -void HwcDisplay::SetClientTargetMetadata( - const IVrComposerClient::BufferMetadata& metadata) { - buffer_metadata_ = metadata; -} - -HwcLayer* HwcDisplay::CreateLayer() { - uint64_t layer_id = layer_ids_++; - layers_.push_back(HwcLayer(layer_id)); - return &layers_.back(); -} - -HwcLayer* HwcDisplay::GetLayer(Layer id) { - for (size_t i = 0; i < layers_.size(); ++i) - if (layers_[i].info.id == id) - return &layers_[i]; - - return nullptr; -} - -bool HwcDisplay::DestroyLayer(Layer id) { - for (auto it = layers_.begin(); it != layers_.end(); ++it) { - if (it->info.id == id) { - layers_.erase(it); - return true; - } - } - - return false; -} - -void HwcDisplay::GetChangedCompositionTypes( - std::vector<Layer>* layer_ids, - std::vector<IComposerClient::Composition>* types) { - std::sort(layers_.begin(), layers_.end(), - [](const auto& lhs, const auto& rhs) { - return lhs.info.z_order < rhs.info.z_order; - }); - - const size_t no_layer = std::numeric_limits<size_t>::max(); - size_t first_client_layer = no_layer, last_client_layer = no_layer; - for (size_t i = 0; i < layers_.size(); ++i) { - switch (layers_[i].composition_type) { - case IComposerClient::Composition::SOLID_COLOR: - case IComposerClient::Composition::CURSOR: - case IComposerClient::Composition::SIDEBAND: - if (first_client_layer == no_layer) - first_client_layer = i; - - last_client_layer = i; - break; - default: - break; - } - } - - for (size_t i = 0; i < layers_.size(); ++i) { - if (i >= first_client_layer && i <= last_client_layer) { - if (layers_[i].composition_type != IComposerClient::Composition::CLIENT) { - layer_ids->push_back(layers_[i].info.id); - types->push_back(IComposerClient::Composition::CLIENT); - layers_[i].composition_type = IComposerClient::Composition::CLIENT; - } - - continue; - } - - if (layers_[i].composition_type != IComposerClient::Composition::DEVICE) { - layer_ids->push_back(layers_[i].info.id); - types->push_back(IComposerClient::Composition::DEVICE); - layers_[i].composition_type = IComposerClient::Composition::DEVICE; - } - } -} - -Error HwcDisplay::GetFrame( - std::vector<ComposerView::ComposerLayer>* out_frames) { - bool queued_client_target = false; - std::vector<ComposerView::ComposerLayer> frame; - for (const auto& layer : layers_) { - if (layer.composition_type == IComposerClient::Composition::CLIENT) { - if (queued_client_target) - continue; - - if (!buffer_.get()) { - ALOGE("Client composition requested but no client target buffer"); - return Error::BAD_LAYER; - } - - ComposerView::ComposerLayer client_target_layer = { - .buffer = buffer_, - .fence = fence_.get() ? fence_ : new Fence(-1), - .display_frame = {0, 0, static_cast<int32_t>(buffer_->getWidth()), - static_cast<int32_t>(buffer_->getHeight())}, - .crop = {0.0f, 0.0f, static_cast<float>(buffer_->getWidth()), - static_cast<float>(buffer_->getHeight())}, - .blend_mode = IComposerClient::BlendMode::NONE, - }; - - frame.push_back(client_target_layer); - queued_client_target = true; - } else { - if (!layer.info.buffer.get() || !layer.info.fence.get()) { - ALOGV("Layer requested without valid buffer"); - continue; - } - - frame.push_back(layer.info); - } - } - - out_frames->swap(frame); - return Error::NONE; -} - -std::vector<Layer> HwcDisplay::UpdateLastFrameAndGetLastFrameLayers() { - std::vector<Layer> last_frame_layers; - last_frame_layers.swap(last_frame_layers_ids_); - - for (const auto& layer : layers_) - last_frame_layers_ids_.push_back(layer.info.id); - - return last_frame_layers; -} - -void HwcDisplay::SetColorTransform(const float* matrix, int32_t hint) { - color_transform_hint_ = hint; - if (matrix) - memcpy(color_transform_, matrix, sizeof(color_transform_)); -} - -void HwcDisplay::dumpDebugInfo(std::string* result) const { - if (!result) { - return; - } - *result += StringPrintf("HwcDisplay: width: %d, height: %d, layers size: %zu, colormode: %d\ - , config: %d\n", width_, height_, layers_.size(), color_mode_, active_config_); - *result += StringPrintf("HwcDisplay buffer metadata: width: %d, height: %d, stride: %d,\ - layerCount: %d, pixelFormat: %d\n", buffer_metadata_.width, buffer_metadata_.height, - buffer_metadata_.stride, buffer_metadata_.layerCount, buffer_metadata_.format); - for (const auto& layer : layers_) { - layer.dumpDebugInfo(result); - } -} - -//////////////////////////////////////////////////////////////////////////////// -// VrHwcClient - -VrHwc::VrHwc() { - vsync_callback_ = new VsyncCallback; -} - -VrHwc::~VrHwc() { - vsync_callback_->SetEventCallback(nullptr); -} - -bool VrHwc::hasCapability(hwc2_capability_t /* capability */) { return false; } - -void VrHwc::registerEventCallback(EventCallback* callback) { - std::unique_lock<std::mutex> lock(mutex_); - event_callback_ = callback; - int32_t width, height; - GetPrimaryDisplaySize(&width, &height); - // Create the primary display late to avoid initialization issues between - // VR HWC and SurfaceFlinger. - displays_[kDefaultDisplayId].reset(new HwcDisplay(width, height)); - - // Surface flinger will make calls back into vr_hwc when it receives the - // onHotplug() call, so it's important to release mutex_ here. - lock.unlock(); - event_callback_->onHotplug(kDefaultDisplayId, - hardware::graphics::composer::V2_1:: - IComposerCallback::Connection::CONNECTED); - lock.lock(); - UpdateVsyncCallbackEnabledLocked(); -} - -void VrHwc::unregisterEventCallback() { - std::lock_guard<std::mutex> guard(mutex_); - event_callback_ = nullptr; - UpdateVsyncCallbackEnabledLocked(); -} - -uint32_t VrHwc::getMaxVirtualDisplayCount() { return 1; } - -Error VrHwc::destroyVirtualDisplay(Display display) { - std::lock_guard<std::mutex> guard(mutex_); - if (display == kDefaultDisplayId || displays_.erase(display) == 0) - return Error::BAD_DISPLAY; - ComposerView::Frame frame; - frame.display_id = display; - frame.removed = true; - if (observer_) - observer_->OnNewFrame(frame); - return Error::NONE; -} - -Error VrHwc::createLayer(Display display, Layer* outLayer) { - std::lock_guard<std::mutex> guard(mutex_); - auto display_ptr = FindDisplay(display); - if (!display_ptr) - return Error::BAD_DISPLAY; - - HwcLayer* layer = display_ptr->CreateLayer(); - *outLayer = layer->info.id; - return Error::NONE; -} - -Error VrHwc::destroyLayer(Display display, Layer layer) { - std::lock_guard<std::mutex> guard(mutex_); - auto display_ptr = FindDisplay(display); - if (!display_ptr) { - return Error::BAD_DISPLAY; - } - - return display_ptr->DestroyLayer(layer) ? Error::NONE : Error::BAD_LAYER; -} - -Error VrHwc::getActiveConfig(Display display, Config* outConfig) { - std::lock_guard<std::mutex> guard(mutex_); - if (!FindDisplay(display)) - return Error::BAD_DISPLAY; - *outConfig = kDefaultConfigId; - return Error::NONE; -} - -Error VrHwc::getDisplayAttribute(Display display, Config config, - IComposerClient::Attribute attribute, - int32_t* outValue) { - std::lock_guard<std::mutex> guard(mutex_); - auto display_ptr = FindDisplay(display); - if (!display_ptr) { - return Error::BAD_DISPLAY; - } - if (config != kDefaultConfigId) { - return Error::BAD_CONFIG; - } - - switch (attribute) { - case IComposerClient::Attribute::WIDTH: - *outValue = display_ptr->width(); - break; - case IComposerClient::Attribute::HEIGHT: - *outValue = display_ptr->height(); - break; - case IComposerClient::Attribute::VSYNC_PERIOD: - { - int error = 0; - auto display_client = display::DisplayClient::Create(&error); - if (!display_client) { - ALOGE("Could not connect to display service : %s(%d)", - strerror(error), error); - // Return a default value of 30 fps - *outValue = 1000 * 1000 * 1000 / 30; - } else { - auto metrics = display_client->GetDisplayMetrics(); - *outValue = metrics.get().vsync_period_ns; - } - } - break; - case IComposerClient::Attribute::DPI_X: - case IComposerClient::Attribute::DPI_Y: - { - constexpr int32_t kDefaultDPI = 300; - int32_t dpi = property_get_int32("ro.vr.hwc.dpi", kDefaultDPI); - if (dpi <= 0) { - dpi = kDefaultDPI; - } - *outValue = 1000 * dpi; - } - break; - default: - return Error::BAD_PARAMETER; - } - - return Error::NONE; -} - -Error VrHwc::getDisplayConfigs(Display display, hidl_vec<Config>* outConfigs) { - std::lock_guard<std::mutex> guard(mutex_); - if (!FindDisplay(display)) - return Error::BAD_DISPLAY; - std::vector<Config> configs(1, kDefaultConfigId); - *outConfigs = hidl_vec<Config>(configs); - return Error::NONE; -} - -Error VrHwc::getDisplayName(Display /* display */, hidl_string* outName) { - *outName = hidl_string(); - return Error::NONE; -} - -Error VrHwc::getDisplayType(Display display, - IComposerClient::DisplayType* outType) { - std::lock_guard<std::mutex> guard(mutex_); - auto display_ptr = FindDisplay(display); - if (!display_ptr) { - *outType = IComposerClient::DisplayType::INVALID; - return Error::BAD_DISPLAY; - } - - if (display == kDefaultDisplayId) - *outType = IComposerClient::DisplayType::PHYSICAL; - else - *outType = IComposerClient::DisplayType::VIRTUAL; - - return Error::NONE; -} - -Error VrHwc::getDozeSupport(Display display, bool* outSupport) { - *outSupport = false; - std::lock_guard<std::mutex> guard(mutex_); - if (!FindDisplay(display)) - return Error::BAD_DISPLAY; - return Error::NONE; -} - -Error VrHwc::setActiveConfig(Display display, Config config) { - std::lock_guard<std::mutex> guard(mutex_); - auto display_ptr = FindDisplay(display); - if (!display_ptr) - return Error::BAD_DISPLAY; - if (config != kDefaultConfigId) - return Error::BAD_CONFIG; - - display_ptr->set_active_config(config); - return Error::NONE; -} - -Error VrHwc::setVsyncEnabled(Display display, IComposerClient::Vsync enabled) { - std::lock_guard<std::mutex> guard(mutex_); - auto display_ptr = FindDisplay(display); - if (!display_ptr) - return Error::BAD_DISPLAY; - - if (enabled != IComposerClient::Vsync::ENABLE && - enabled != IComposerClient::Vsync::DISABLE) { - return Error::BAD_PARAMETER; - } - - Error set_vsync_result = Error::NONE; - if (display == kDefaultDisplayId) { - sp<IVsyncService> vsync_service = interface_cast<IVsyncService>( - defaultServiceManager()->getService( - String16(IVsyncService::GetServiceName()))); - if (vsync_service == nullptr) { - ALOGE("Failed to get vsync service"); - return Error::NO_RESOURCES; - } - - if (enabled == IComposerClient::Vsync::ENABLE) { - ALOGI("Enable vsync"); - display_ptr->set_vsync_enabled(true); - status_t result = vsync_service->registerCallback(vsync_callback_); - if (result != OK) { - ALOGE("%s service registerCallback() failed: %s (%d)", - IVsyncService::GetServiceName(), strerror(-result), result); - set_vsync_result = Error::NO_RESOURCES; - } - } else if (enabled == IComposerClient::Vsync::DISABLE) { - ALOGI("Disable vsync"); - display_ptr->set_vsync_enabled(false); - status_t result = vsync_service->unregisterCallback(vsync_callback_); - if (result != OK) { - ALOGE("%s service unregisterCallback() failed: %s (%d)", - IVsyncService::GetServiceName(), strerror(-result), result); - set_vsync_result = Error::NO_RESOURCES; - } - } - - UpdateVsyncCallbackEnabledLocked(); - } - - return set_vsync_result; -} - -Error VrHwc::setColorTransform(Display display, const float* matrix, - int32_t hint) { - std::lock_guard<std::mutex> guard(mutex_); - auto display_ptr = FindDisplay(display); - if (!display_ptr) - return Error::BAD_DISPLAY; - - display_ptr->SetColorTransform(matrix, hint); - return Error::NONE; -} - -Error VrHwc::setClientTarget(Display display, buffer_handle_t target, - int32_t acquireFence, int32_t /* dataspace */, - const std::vector<hwc_rect_t>& /* damage */) { - base::unique_fd fence(acquireFence); - std::lock_guard<std::mutex> guard(mutex_); - auto display_ptr = FindDisplay(display); - if (!display_ptr) - return Error::BAD_DISPLAY; - - if (target == nullptr) - return Error::NONE; - - if (!display_ptr->SetClientTarget(target, std::move(fence))) - return Error::BAD_PARAMETER; - - return Error::NONE; -} - -Error VrHwc::setOutputBuffer(Display display, buffer_handle_t /* buffer */, - int32_t releaseFence) { - base::unique_fd fence(releaseFence); - std::lock_guard<std::mutex> guard(mutex_); - auto display_ptr = FindDisplay(display); - if (!display_ptr) - return Error::BAD_DISPLAY; - - // TODO(dnicoara): Is it necessary to do anything here? - return Error::NONE; -} - -Error VrHwc::validateDisplay( - Display display, std::vector<Layer>* outChangedLayers, - std::vector<IComposerClient::Composition>* outCompositionTypes, - uint32_t* /* outDisplayRequestMask */, - std::vector<Layer>* /* outRequestedLayers */, - std::vector<uint32_t>* /* outRequestMasks */) { - std::lock_guard<std::mutex> guard(mutex_); - auto display_ptr = FindDisplay(display); - if (!display_ptr) - return Error::BAD_DISPLAY; - - display_ptr->GetChangedCompositionTypes(outChangedLayers, - outCompositionTypes); - return Error::NONE; -} - -Error VrHwc::acceptDisplayChanges(Display /* display */) { return Error::NONE; } - -Error VrHwc::presentDisplay(Display display, int32_t* outPresentFence, - std::vector<Layer>* outLayers, - std::vector<int32_t>* outReleaseFences) { - *outPresentFence = -1; - outLayers->clear(); - outReleaseFences->clear(); - - std::lock_guard<std::mutex> guard(mutex_); - auto display_ptr = FindDisplay(display); - - if (!display_ptr) - return Error::BAD_DISPLAY; - - ComposerView::Frame frame; - std::vector<Layer> last_frame_layers; - Error status = display_ptr->GetFrame(&frame.layers); - frame.display_id = display; - frame.display_width = display_ptr->width(); - frame.display_height = display_ptr->height(); - frame.active_config = display_ptr->active_config(); - frame.power_mode = display_ptr->power_mode(); - frame.vsync_enabled = display_ptr->vsync_enabled() ? - IComposerClient::Vsync::ENABLE : IComposerClient::Vsync::DISABLE; - frame.color_transform_hint = display_ptr->color_transform_hint(); - frame.color_mode = display_ptr->color_mode(); - memcpy(frame.color_transform, display_ptr->color_transform(), - sizeof(frame.color_transform)); - if (status != Error::NONE) - return status; - - last_frame_layers = display_ptr->UpdateLastFrameAndGetLastFrameLayers(); - - base::unique_fd fence; - if (observer_) - fence = observer_->OnNewFrame(frame); - - if (fence.get() < 0) - return Error::NONE; - - *outPresentFence = dup(fence.get()); - outLayers->swap(last_frame_layers); - for (size_t i = 0; i < outLayers->size(); ++i) - outReleaseFences->push_back(dup(fence.get())); - - return Error::NONE; -} - -Error VrHwc::setLayerCursorPosition(Display display, Layer layer, int32_t x, - int32_t y) { - std::lock_guard<std::mutex> guard(mutex_); - auto display_ptr = FindDisplay(display); - if (!display_ptr) - return Error::BAD_DISPLAY; - - HwcLayer* hwc_layer = display_ptr->GetLayer(layer); - if (!hwc_layer) - return Error::BAD_LAYER; - - hwc_layer->info.cursor_x = x; - hwc_layer->info.cursor_y = y; - return Error::NONE; -} - -Error VrHwc::setLayerBuffer(Display display, Layer layer, - buffer_handle_t buffer, int32_t acquireFence) { - base::unique_fd fence(acquireFence); - std::lock_guard<std::mutex> guard(mutex_); - auto display_ptr = FindDisplay(display); - if (!display_ptr) - return Error::BAD_DISPLAY; - - HwcLayer* hwc_layer = display_ptr->GetLayer(layer); - if (!hwc_layer) - return Error::BAD_LAYER; - - hwc_layer->info.buffer = CreateGraphicBuffer( - buffer, hwc_layer->buffer_metadata); - hwc_layer->info.fence = new Fence(fence.release()); - - return Error::NONE; -} - -Error VrHwc::setLayerSurfaceDamage(Display display, Layer layer, - const std::vector<hwc_rect_t>& damage) { - std::lock_guard<std::mutex> guard(mutex_); - auto display_ptr = FindDisplay(display); - if (!display_ptr) - return Error::BAD_DISPLAY; - - HwcLayer* hwc_layer = display_ptr->GetLayer(layer); - if (!hwc_layer) - return Error::BAD_LAYER; - - hwc_layer->info.damaged_regions = damage; - return Error::NONE; -} - -Error VrHwc::setLayerBlendMode(Display display, Layer layer, int32_t mode) { - std::lock_guard<std::mutex> guard(mutex_); - auto display_ptr = FindDisplay(display); - if (!display_ptr) - return Error::BAD_DISPLAY; - - HwcLayer* hwc_layer = display_ptr->GetLayer(layer); - if (!hwc_layer) - return Error::BAD_LAYER; - - hwc_layer->info.blend_mode = - static_cast<ComposerView::ComposerLayer::BlendMode>(mode); - - return Error::NONE; -} - -Error VrHwc::setLayerColor(Display display, Layer layer, - IComposerClient::Color color) { - std::lock_guard<std::mutex> guard(mutex_); - auto display_ptr = FindDisplay(display); - if (!display_ptr) - return Error::BAD_DISPLAY; - - HwcLayer* hwc_layer = display_ptr->GetLayer(layer); - if (!hwc_layer) - return Error::BAD_LAYER; - - hwc_layer->info.color = color; - return Error::NONE; -} - -Error VrHwc::setLayerCompositionType(Display display, Layer layer, - int32_t type) { - std::lock_guard<std::mutex> guard(mutex_); - auto display_ptr = FindDisplay(display); - if (!display_ptr) - return Error::BAD_DISPLAY; - - HwcLayer* hwc_layer = display_ptr->GetLayer(layer); - if (!hwc_layer) - return Error::BAD_LAYER; - - hwc_layer->composition_type = static_cast<HwcLayer::Composition>(type); - - return Error::NONE; -} - -Error VrHwc::setLayerDataspace(Display display, Layer layer, - int32_t dataspace) { - std::lock_guard<std::mutex> guard(mutex_); - auto display_ptr = FindDisplay(display); - if (!display_ptr) - return Error::BAD_DISPLAY; - - HwcLayer* hwc_layer = display_ptr->GetLayer(layer); - if (!hwc_layer) - return Error::BAD_LAYER; - - hwc_layer->info.dataspace = dataspace; - return Error::NONE; -} - -Error VrHwc::setLayerDisplayFrame(Display display, Layer layer, - const hwc_rect_t& frame) { - std::lock_guard<std::mutex> guard(mutex_); - auto display_ptr = FindDisplay(display); - if (!display_ptr) - return Error::BAD_DISPLAY; - - HwcLayer* hwc_layer = display_ptr->GetLayer(layer); - if (!hwc_layer) - return Error::BAD_LAYER; - - hwc_layer->info.display_frame = - {frame.left, frame.top, frame.right, frame.bottom}; - - return Error::NONE; -} - -Error VrHwc::setLayerPlaneAlpha(Display display, Layer layer, float alpha) { - std::lock_guard<std::mutex> guard(mutex_); - auto display_ptr = FindDisplay(display); - if (!display_ptr) - return Error::BAD_DISPLAY; - - HwcLayer* hwc_layer = display_ptr->GetLayer(layer); - if (!hwc_layer) - return Error::BAD_LAYER; - - hwc_layer->info.alpha = alpha; - - return Error::NONE; -} - -Error VrHwc::setLayerSidebandStream(Display display, Layer /* layer */, - buffer_handle_t /* stream */) { - std::lock_guard<std::mutex> guard(mutex_); - if (!FindDisplay(display)) - return Error::BAD_DISPLAY; - return Error::NONE; -} - -Error VrHwc::setLayerSourceCrop(Display display, Layer layer, - const hwc_frect_t& crop) { - std::lock_guard<std::mutex> guard(mutex_); - auto display_ptr = FindDisplay(display); - if (!display_ptr) - return Error::BAD_DISPLAY; - - HwcLayer* hwc_layer = display_ptr->GetLayer(layer); - if (!hwc_layer) - return Error::BAD_LAYER; - - hwc_layer->info.crop = {crop.left, crop.top, crop.right, crop.bottom}; - - return Error::NONE; -} - -Error VrHwc::setLayerTransform(Display display, Layer layer, - int32_t transform) { - std::lock_guard<std::mutex> guard(mutex_); - auto display_ptr = FindDisplay(display); - if (!display_ptr) - return Error::BAD_DISPLAY; - - HwcLayer* hwc_layer = display_ptr->GetLayer(layer); - if (!hwc_layer) - return Error::BAD_LAYER; - - hwc_layer->info.transform = transform; - return Error::NONE; -} - -Error VrHwc::setLayerVisibleRegion(Display display, Layer layer, - const std::vector<hwc_rect_t>& visible) { - std::lock_guard<std::mutex> guard(mutex_); - auto display_ptr = FindDisplay(display); - if (!display_ptr) - return Error::BAD_DISPLAY; - - HwcLayer* hwc_layer = display_ptr->GetLayer(layer); - if (!hwc_layer) - return Error::BAD_LAYER; - - hwc_layer->info.visible_regions = visible; - return Error::NONE; -} - -Error VrHwc::setLayerZOrder(Display display, Layer layer, uint32_t z) { - std::lock_guard<std::mutex> guard(mutex_); - auto display_ptr = FindDisplay(display); - if (!display_ptr) - return Error::BAD_DISPLAY; - - HwcLayer* hwc_layer = display_ptr->GetLayer(layer); - if (!hwc_layer) - return Error::BAD_LAYER; - - hwc_layer->info.z_order = z; - - return Error::NONE; -} - -Error VrHwc::setLayerInfo(Display display, Layer layer, uint32_t type, - uint32_t appId) { - std::lock_guard<std::mutex> guard(mutex_); - auto display_ptr = FindDisplay(display); - if (!display_ptr) - return Error::BAD_DISPLAY; - - HwcLayer* hwc_layer = display_ptr->GetLayer(layer); - if (!hwc_layer) - return Error::BAD_LAYER; - - hwc_layer->info.type = type; - hwc_layer->info.app_id = appId; - - return Error::NONE; -} - -Error VrHwc::setClientTargetMetadata( - Display display, const IVrComposerClient::BufferMetadata& metadata) { - std::lock_guard<std::mutex> guard(mutex_); - auto display_ptr = FindDisplay(display); - if (!display_ptr) - return Error::BAD_DISPLAY; - - display_ptr->SetClientTargetMetadata(metadata); - - return Error::NONE; -} - -Error VrHwc::setLayerBufferMetadata( - Display display, Layer layer, - const IVrComposerClient::BufferMetadata& metadata) { - std::lock_guard<std::mutex> guard(mutex_); - auto display_ptr = FindDisplay(display); - if (!display_ptr) - return Error::BAD_DISPLAY; - - HwcLayer* hwc_layer = display_ptr->GetLayer(layer); - if (!hwc_layer) - return Error::BAD_LAYER; - - hwc_layer->buffer_metadata = metadata; - - return Error::NONE; -} - -Return<void> VrHwc::getCapabilities(getCapabilities_cb hidl_cb) { - hidl_cb(hidl_vec<Capability>()); - return Void(); -} - -Return<void> VrHwc::dumpDebugInfo(dumpDebugInfo_cb hidl_cb) { - std::string result; - - { - std::lock_guard<std::mutex> guard(mutex_); - result = "\nVrHwc states:\n"; - for (const auto& pair : displays_) { - result += StringPrintf("Display id: %lu\n", (unsigned long)pair.first); - pair.second->dumpDebugInfo(&result); - } - result += "\n"; - } - - hidl_cb(hidl_string(result)); - return Void(); -} - -Return<void> VrHwc::createClient(createClient_cb hidl_cb) { - std::lock_guard<std::mutex> guard(mutex_); - - Error status = Error::NONE; - sp<VrComposerClient> client; - if (!client_.promote().get()) { - client = new VrComposerClient(*this); - } else { - ALOGE("Already have a client"); - status = Error::NO_RESOURCES; - } - - client_ = client; - hidl_cb(status, client); - return Void(); -} - -Return<void> VrHwc::createClient_2_3(IComposer::createClient_2_3_cb hidl_cb) { - std::lock_guard<std::mutex> guard(mutex_); - - Error status = Error::NONE; - sp<VrComposerClient> client; - if (!client_.promote().get()) { - client = new VrComposerClient(*this); - } else { - ALOGE("Already have a client"); - status = Error::NO_RESOURCES; - } - - client_ = client; - hidl_cb(status, client); - return Void(); -} - -void VrHwc::ForceDisplaysRefresh() { - std::lock_guard<std::mutex> guard(mutex_); - if (event_callback_ != nullptr) { - for (const auto& pair : displays_) - event_callback_->onRefresh(pair.first); - } -} - -void VrHwc::RegisterObserver(Observer* observer) { - std::lock_guard<std::mutex> guard(mutex_); - if (observer_) - ALOGE("Overwriting observer"); - else - observer_ = observer; -} - -void VrHwc::UnregisterObserver(Observer* observer) { - std::lock_guard<std::mutex> guard(mutex_); - if (observer != observer_) - ALOGE("Trying to unregister unknown observer"); - else - observer_ = nullptr; -} - -HwcDisplay* VrHwc::FindDisplay(Display display) { - auto iter = displays_.find(display); - return iter == displays_.end() ? nullptr : iter->second.get(); -} - -void VrHwc::UpdateVsyncCallbackEnabledLocked() { - auto primary_display = FindDisplay(kDefaultDisplayId); - LOG_ALWAYS_FATAL_IF(event_callback_ != nullptr && primary_display == nullptr, - "Should have created the primary display by now"); - bool send_vsync = - event_callback_ != nullptr && primary_display->vsync_enabled(); - vsync_callback_->SetEventCallback(send_vsync ? event_callback_ : nullptr); -} - -Return<void> VrHwc::debug(const hidl_handle& fd, - const hidl_vec<hidl_string>& args) { - std::string result; - - { - std::lock_guard<std::mutex> guard(mutex_); - for (const auto& pair : displays_) { - result += StringPrintf("Display id: %d\n", static_cast<int>(pair.first)); - pair.second->dumpDebugInfo(&result); - } - result += "\n"; - } - - FILE* out = fdopen(dup(fd->data[0]), "w"); - fprintf(out, "%s", result.c_str()); - fclose(out); - - return Void(); -} - -void HwcLayer::dumpDebugInfo(std::string* result) const { - if (!result) { - return; - } - *result += StringPrintf("Layer: composition_type: %d, type: %d, app_id: %d, z_order: %d,\ - cursor_x: %d, cursor_y: %d, color(rgba): (%d,%d,%d,%d), dataspace: %d, transform: %d,\ - display_frame(LTRB): (%d,%d,%d,%d), crop(LTRB): (%.1f,%.1f,%.1f,%.1f), blend_mode: %d\n", - composition_type, info.type, info.app_id, info.z_order, info.cursor_x, info.cursor_y, - info.color.r, info.color.g, info.color.b, info.color.a, info.dataspace, info.transform, - info.display_frame.left, info.display_frame.top, info.display_frame.right, - info.display_frame.bottom, info.crop.left, info.crop.top, info.crop.right, - info.crop.bottom, info.blend_mode); - *result += StringPrintf("Layer buffer metadata: width: %d, height: %d, stride: %d, layerCount: %d\ - , pixelFormat: %d\n", buffer_metadata.width, buffer_metadata.height, buffer_metadata.stride, - buffer_metadata.layerCount, buffer_metadata.format); -} - -status_t VrHwc::VsyncCallback::onVsync(int64_t vsync_timestamp) { - ATRACE_NAME("vr_hwc onVsync"); - std::lock_guard<std::mutex> guard(mutex_); - if (callback_ != nullptr) - callback_->onVsync(kDefaultDisplayId, vsync_timestamp); - return OK; -} - -void VrHwc::VsyncCallback::SetEventCallback(EventCallback* callback) { - std::lock_guard<std::mutex> guard(mutex_); - callback_ = callback; -} - -// composer::V2_2::ComposerHal -Error VrHwc::setReadbackBuffer(Display display, - const native_handle_t* bufferHandle, - android::base::unique_fd fenceFd) { - return Error::NONE; -} - -Error VrHwc::getReadbackBufferFence(Display display, - android::base::unique_fd* outFenceFd) { - return Error::NONE; -} - -Error VrHwc::createVirtualDisplay_2_2(uint32_t width, uint32_t height, - types::V1_1::PixelFormat* format, - Display* outDisplay) { - *format = types::V1_1::PixelFormat::RGBA_8888; - *outDisplay = display_count_; - displays_[display_count_].reset(new HwcDisplay(width, height)); - display_count_++; - return Error::NONE; -} - -Error VrHwc::setPowerMode_2_2(Display display, - IComposerClient::PowerMode mode) { - bool dozeSupported = false; - - Error dozeSupportError = getDozeSupport(display, &dozeSupported); - - if (dozeSupportError != Error::NONE) - return dozeSupportError; - - std::lock_guard<std::mutex> guard(mutex_); - auto display_ptr = FindDisplay(display); - if (!display_ptr) - return Error::BAD_DISPLAY; - - if (mode < IComposerClient::PowerMode::OFF || - mode > IComposerClient::PowerMode::DOZE_SUSPEND) { - return Error::BAD_PARAMETER; - } - - if (!dozeSupported && (mode == IComposerClient::PowerMode::DOZE || - mode == IComposerClient::PowerMode::DOZE_SUSPEND)) { - return Error::UNSUPPORTED; - } - - display_ptr->set_power_mode(mode); - return Error::NONE; -} - -Error VrHwc::setLayerFloatColor(Display display, Layer layer, - IComposerClient::FloatColor color) { - return Error::NONE; -} - -Error VrHwc::getRenderIntents(Display display, types::V1_1::ColorMode mode, - std::vector<RenderIntent>* outIntents) { - return Error::NONE; -} - -std::array<float, 16> VrHwc::getDataspaceSaturationMatrix( - types::V1_1::Dataspace dataspace) { - return {}; -} - -// composer::V2_3::ComposerHal -Error VrHwc::getHdrCapabilities_2_3(Display /*display*/, - hidl_vec<Hdr>* /*outTypes*/, - float* outMaxLuminance, - float* outMaxAverageLuminance, - float* outMinLuminance) { - *outMaxLuminance = 0; - *outMaxAverageLuminance = 0; - *outMinLuminance = 0; - return Error::NONE; -} - -Error VrHwc::setLayerPerFrameMetadata_2_3( - Display display, Layer layer, - const std::vector<IComposerClient::PerFrameMetadata>& metadata) { - return Error::NONE; -} - -Error VrHwc::getPerFrameMetadataKeys_2_3( - Display display, - std::vector<IComposerClient::PerFrameMetadataKey>* outKeys) { - return Error::NONE; -} - -Error VrHwc::setColorMode_2_3(Display display, ColorMode mode, - RenderIntent intent) { - std::lock_guard<std::mutex> guard(mutex_); - auto display_ptr = FindDisplay(display); - if (!display_ptr) - return Error::BAD_DISPLAY; - - if (mode < ColorMode::NATIVE || mode > ColorMode::DISPLAY_P3) - return Error::BAD_PARAMETER; - - display_ptr->set_color_mode(mode); - return Error::NONE; -} - -Error VrHwc::getRenderIntents_2_3(Display display, ColorMode mode, - std::vector<RenderIntent>* outIntents) { - return Error::NONE; -} - -Error VrHwc::getColorModes_2_3(Display display, hidl_vec<ColorMode>* outModes) { - return Error::NONE; -} - -Error VrHwc::getClientTargetSupport_2_3(Display display, uint32_t width, - uint32_t height, PixelFormat format, - Dataspace dataspace) { - return Error::NONE; -} - -Error VrHwc::getReadbackBufferAttributes_2_3(Display display, - PixelFormat* outFormat, - Dataspace* outDataspace) { - return Error::NONE; -} - -Error VrHwc::getDisplayIdentificationData(Display display, uint8_t* outPort, - std::vector<uint8_t>* outData) { - int error = 0; - auto display_client = display::DisplayClient::Create(&error); - if (!display_client) { - ALOGE("Could not connect to display service : %s(%d)", strerror(error), - error); - return Error::BAD_CONFIG; - } - auto edid_data = display_client->GetConfigurationData( - display::ConfigFileType::kDeviceEdid); - auto display_identification_port = - display_client->GetDisplayIdentificationPort(); - *outPort = display_identification_port.get(); - - std::copy(edid_data.get().begin(), edid_data.get().end(), - std::back_inserter(*outData)); - return Error::NONE; -} - -Error VrHwc::setLayerColorTransform(Display display, Layer layer, - const float* matrix) { - return Error::NONE; -} - -Error VrHwc::getDisplayedContentSamplingAttributes( - Display display, PixelFormat& format, Dataspace& dataspace, - hidl_bitfield<IComposerClient::FormatColorComponent>& componentMask) { - return Error::NONE; -} - -Error VrHwc::setDisplayedContentSamplingEnabled( - Display display, IComposerClient::DisplayedContentSampling enable, - hidl_bitfield<IComposerClient::FormatColorComponent> componentMask, - uint64_t maxFrames) { - return Error::NONE; -} - -Error VrHwc::getDisplayedContentSample(Display display, uint64_t maxFrames, - uint64_t timestamp, uint64_t& frameCount, - hidl_vec<uint64_t>& sampleComponent0, - hidl_vec<uint64_t>& sampleComponent1, - hidl_vec<uint64_t>& sampleComponent2, - hidl_vec<uint64_t>& sampleComponent3) { - return Error::NONE; -} - -Error VrHwc::getDisplayCapabilities( - Display display, - std::vector<IComposerClient::DisplayCapability>* outCapabilities) { - return Error::NONE; -} - -Error VrHwc::setLayerPerFrameMetadataBlobs( - Display display, Layer layer, - std::vector<IComposerClient::PerFrameMetadataBlob>& blobs) { - return Error::NONE; -} - -Error VrHwc::getDisplayBrightnessSupport(Display display, bool* outSupport) { - return Error::NONE; -} - -Error VrHwc::setDisplayBrightness(Display display, float brightness) { - return Error::NONE; -} - -} // namespace dvr -} // namespace android diff --git a/services/vr/hardware_composer/impl/vr_hwc.h b/services/vr/hardware_composer/impl/vr_hwc.h deleted file mode 100644 index 3e3a6307fa..0000000000 --- a/services/vr/hardware_composer/impl/vr_hwc.h +++ /dev/null @@ -1,410 +0,0 @@ -/* - * Copyright 2016 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -#ifndef ANDROID_DVR_HARDWARE_COMPOSER_IMPL_VR_HWC_H -#define ANDROID_DVR_HARDWARE_COMPOSER_IMPL_VR_HWC_H - -#include <android-base/unique_fd.h> -#include <android/frameworks/vr/composer/2.0/IVrComposerClient.h> -#include <android/hardware/graphics/composer/2.3/IComposer.h> -#include <composer-hal/2.3/ComposerHal.h> -#include <private/dvr/vsync_service.h> -#include <ui/Fence.h> -#include <ui/GraphicBuffer.h> -#include <utils/StrongPointer.h> - -#include <mutex> -#include <unordered_map> - -using namespace android::frameworks::vr::composer::V2_0; -using namespace android::hardware::graphics::common::V1_0; -using namespace android::hardware::graphics::composer::V2_3; - -using android::hardware::hidl_bitfield; -using android::hardware::hidl_handle; -using android::hardware::hidl_string; -using android::hardware::hidl_vec; -using android::hardware::Return; -using android::hardware::Void; -using android::hardware::graphics::composer::V2_1::Config; -using android::hardware::graphics::composer::V2_1::Display; -using android::hardware::graphics::composer::V2_1::Error; -using android::hardware::graphics::composer::V2_1::Layer; -using android::hardware::graphics::composer::V2_3::IComposerClient; - -namespace android { - -class Fence; - -namespace dvr { - -class VrComposerClient; - -using android::hardware::graphics::composer::V2_3::hal::ComposerHal; - -namespace types = android::hardware::graphics::common; - -using types::V1_1::RenderIntent; -using types::V1_2::ColorMode; -using types::V1_2::Dataspace; -using types::V1_2::Hdr; -using types::V1_2::PixelFormat; - -class ComposerView { - public: - struct ComposerLayer { - using Recti = hardware::graphics::composer::V2_3::IComposerClient::Rect; - using Rectf = hardware::graphics::composer::V2_3::IComposerClient::FRect; - using BlendMode = - hardware::graphics::composer::V2_3::IComposerClient::BlendMode; - - Layer id; - sp<GraphicBuffer> buffer; - sp<Fence> fence; - Recti display_frame; - Rectf crop; - BlendMode blend_mode; - float alpha; - uint32_t type; - uint32_t app_id; - uint32_t z_order; - int32_t cursor_x; - int32_t cursor_y; - IComposerClient::Color color; - int32_t dataspace; - int32_t transform; - std::vector<hwc_rect_t> visible_regions; - std::vector<hwc_rect_t> damaged_regions; - }; - - struct Frame { - Display display_id; - // This is set to true to notify the upper layer that the display is - // being removed, or left false in the case of a normal frame. The upper - // layer tracks display IDs and will handle new ones showing up. - bool removed = false; - int32_t display_width; - int32_t display_height; - Config active_config; - ColorMode color_mode; - IComposerClient::PowerMode power_mode; - IComposerClient::Vsync vsync_enabled; - float color_transform[16]; - int32_t color_transform_hint; - std::vector<ComposerLayer> layers; - }; - - class Observer { - public: - virtual ~Observer() {} - - // Returns a list of layers that need to be shown together. Layers are - // returned in z-order, with the lowest layer first. - virtual base::unique_fd OnNewFrame(const Frame& frame) = 0; - }; - - virtual ~ComposerView() {} - - virtual void ForceDisplaysRefresh() = 0; - virtual void RegisterObserver(Observer* observer) = 0; - virtual void UnregisterObserver(Observer* observer) = 0; -}; - -struct HwcLayer { - using Composition = - hardware::graphics::composer::V2_3::IComposerClient::Composition; - - explicit HwcLayer(Layer new_id) { info.id = new_id; } - - void dumpDebugInfo(std::string* result) const; - - Composition composition_type; - ComposerView::ComposerLayer info; - IVrComposerClient::BufferMetadata buffer_metadata; -}; - -class HwcDisplay { - public: - HwcDisplay(int32_t width, int32_t height); - ~HwcDisplay(); - - int32_t width() const { return width_; } - int32_t height() const { return height_; } - - HwcLayer* CreateLayer(); - bool DestroyLayer(Layer id); - HwcLayer* GetLayer(Layer id); - - bool SetClientTarget(const native_handle_t* handle, base::unique_fd fence); - void SetClientTargetMetadata( - const IVrComposerClient::BufferMetadata& metadata); - - void GetChangedCompositionTypes( - std::vector<Layer>* layer_ids, - std::vector<IComposerClient::Composition>* composition); - - Error GetFrame(std::vector<ComposerView::ComposerLayer>* out_frame); - - std::vector<Layer> UpdateLastFrameAndGetLastFrameLayers(); - - Config active_config() const { return active_config_; } - void set_active_config(Config config) { active_config_ = config; } - - ColorMode color_mode() const { return color_mode_; } - void set_color_mode(ColorMode mode) { color_mode_ = mode; } - - IComposerClient::PowerMode power_mode() const { return power_mode_; } - void set_power_mode(IComposerClient::PowerMode mode) { power_mode_ = mode; } - - bool vsync_enabled() const { return vsync_enabled_; } - void set_vsync_enabled(bool vsync) {vsync_enabled_ = vsync;} - - const float* color_transform() const { return color_transform_; } - int32_t color_transform_hint() const { return color_transform_hint_; } - void SetColorTransform(const float* matrix, int32_t hint); - - void dumpDebugInfo(std::string* result) const; - - private: - // The client target buffer and the associated fence. - sp<GraphicBuffer> buffer_; - IVrComposerClient::BufferMetadata buffer_metadata_; - sp<Fence> fence_; - - // List of currently active layers. - std::vector<HwcLayer> layers_; - - std::vector<Layer> last_frame_layers_ids_; - - // Layer ID generator. - uint64_t layer_ids_ = 1; - - int32_t width_; - int32_t height_; - - Config active_config_; - ColorMode color_mode_; - IComposerClient::PowerMode power_mode_; - bool vsync_enabled_ = false; - float color_transform_[16]; - int32_t color_transform_hint_; - - HwcDisplay(const HwcDisplay&) = delete; - void operator=(const HwcDisplay&) = delete; -}; - -class VrHwc : public IComposer, public ComposerHal, public ComposerView { - public: - VrHwc(); - ~VrHwc() override; - - Error setLayerInfo(Display display, Layer layer, uint32_t type, - uint32_t appId); - Error setClientTargetMetadata( - Display display, const IVrComposerClient::BufferMetadata& metadata); - Error setLayerBufferMetadata( - Display display, Layer layer, - const IVrComposerClient::BufferMetadata& metadata); - - // composer::V2_1::ComposerHal - bool hasCapability(hwc2_capability_t capability) override; - - std::string dumpDebugInfo() override { return {}; } - - void registerEventCallback(ComposerHal::EventCallback* callback) override; - void unregisterEventCallback() override; - - uint32_t getMaxVirtualDisplayCount() override; - Error destroyVirtualDisplay(Display display) override; - - Error createLayer(Display display, Layer* outLayer) override; - Error destroyLayer(Display display, Layer layer) override; - - Error getActiveConfig(Display display, Config* outConfig) override; - Error getDisplayAttribute(Display display, Config config, - IComposerClient::Attribute attribute, - int32_t* outValue) override; - Error getDisplayConfigs(Display display, hidl_vec<Config>* outConfigs) override; - Error getDisplayName(Display display, hidl_string* outName) override; - Error getDisplayType(Display display, - IComposerClient::DisplayType* outType) override; - Error getDozeSupport(Display display, bool* outSupport) override; - - Error setActiveConfig(Display display, Config config) override; - Error setVsyncEnabled(Display display, IComposerClient::Vsync enabled) override; - - Error setColorTransform(Display display, const float* matrix, - int32_t hint) override; - Error setClientTarget(Display display, buffer_handle_t target, - int32_t acquireFence, int32_t dataspace, - const std::vector<hwc_rect_t>& damage) override; - Error setOutputBuffer(Display display, buffer_handle_t buffer, - int32_t releaseFence) override; - Error validateDisplay( - Display display, std::vector<Layer>* outChangedLayers, - std::vector<IComposerClient::Composition>* outCompositionTypes, - uint32_t* outDisplayRequestMask, std::vector<Layer>* outRequestedLayers, - std::vector<uint32_t>* outRequestMasks) override; - Error acceptDisplayChanges(Display display) override; - Error presentDisplay(Display display, int32_t* outPresentFence, - std::vector<Layer>* outLayers, - std::vector<int32_t>* outReleaseFences) override; - - Error setLayerCursorPosition(Display display, Layer layer, int32_t x, - int32_t y) override; - Error setLayerBuffer(Display display, Layer layer, buffer_handle_t buffer, - int32_t acquireFence) override; - Error setLayerSurfaceDamage(Display display, Layer layer, - const std::vector<hwc_rect_t>& damage) override; - Error setLayerBlendMode(Display display, Layer layer, int32_t mode) override; - Error setLayerColor(Display display, Layer layer, - IComposerClient::Color color) override; - Error setLayerCompositionType(Display display, Layer layer, - int32_t type) override; - Error setLayerDataspace(Display display, Layer layer, - int32_t dataspace) override; - Error setLayerDisplayFrame(Display display, Layer layer, - const hwc_rect_t& frame) override; - Error setLayerPlaneAlpha(Display display, Layer layer, float alpha) override; - Error setLayerSidebandStream(Display display, Layer layer, - buffer_handle_t stream) override; - Error setLayerSourceCrop(Display display, Layer layer, - const hwc_frect_t& crop) override; - Error setLayerTransform(Display display, Layer layer, - int32_t transform) override; - Error setLayerVisibleRegion(Display display, Layer layer, - const std::vector<hwc_rect_t>& visible) override; - Error setLayerZOrder(Display display, Layer layer, uint32_t z) override; - - // composer::V2_2::ComposerHal - Error setReadbackBuffer(Display display, const native_handle_t* bufferHandle, - android::base::unique_fd fenceFd) override; - Error getReadbackBufferFence(Display display, - android::base::unique_fd* outFenceFd) override; - Error createVirtualDisplay_2_2(uint32_t width, uint32_t height, - types::V1_1::PixelFormat* format, - Display* outDisplay) override; - Error setPowerMode_2_2(Display display, - IComposerClient::PowerMode mode) override; - Error setLayerFloatColor(Display display, Layer layer, - IComposerClient::FloatColor color) override; - Error getRenderIntents(Display display, types::V1_1::ColorMode mode, - std::vector<RenderIntent>* outIntents) override; - std::array<float, 16> getDataspaceSaturationMatrix( - types::V1_1::Dataspace dataspace) override; - - // composer::V2_3::ComposerHal - Error getHdrCapabilities_2_3(Display display, hidl_vec<Hdr>* outTypes, - float* outMaxLuminance, - float* outMaxAverageLuminance, - float* outMinLuminance) override; - Error setLayerPerFrameMetadata_2_3( - Display display, Layer layer, - const std::vector<IComposerClient::PerFrameMetadata>& metadata) override; - Error getPerFrameMetadataKeys_2_3( - Display display, - std::vector<IComposerClient::PerFrameMetadataKey>* outKeys) override; - Error setColorMode_2_3(Display display, ColorMode mode, - RenderIntent intent) override; - Error getRenderIntents_2_3(Display display, ColorMode mode, - std::vector<RenderIntent>* outIntents) override; - Error getColorModes_2_3(Display display, - hidl_vec<ColorMode>* outModes) override; - Error getClientTargetSupport_2_3(Display display, uint32_t width, - uint32_t height, PixelFormat format, - Dataspace dataspace) override; - Error getReadbackBufferAttributes_2_3(Display display, PixelFormat* outFormat, - Dataspace* outDataspace) override; - Error getDisplayIdentificationData(Display display, uint8_t* outPort, - std::vector<uint8_t>* outData) override; - Error setLayerColorTransform(Display display, Layer layer, - const float* matrix) override; - Error getDisplayedContentSamplingAttributes( - Display display, PixelFormat& format, Dataspace& dataspace, - hidl_bitfield<IComposerClient::FormatColorComponent>& componentMask) - override; - Error setDisplayedContentSamplingEnabled( - Display display, IComposerClient::DisplayedContentSampling enable, - hidl_bitfield<IComposerClient::FormatColorComponent> componentMask, - uint64_t maxFrames) override; - Error getDisplayedContentSample( - Display display, uint64_t maxFrames, uint64_t timestamp, - uint64_t& frameCount, hidl_vec<uint64_t>& sampleComponent0, - hidl_vec<uint64_t>& sampleComponent1, - hidl_vec<uint64_t>& sampleComponent2, - hidl_vec<uint64_t>& sampleComponent3) override; - Error getDisplayCapabilities(Display display, - std::vector<IComposerClient::DisplayCapability>* - outCapabilities) override; - Error setLayerPerFrameMetadataBlobs( - Display display, Layer layer, - std::vector<IComposerClient::PerFrameMetadataBlob>& blobs) override; - Error getDisplayBrightnessSupport(Display display, bool* outSupport) override; - Error setDisplayBrightness(Display display, float brightness) override; - - // IComposer: - Return<void> getCapabilities(getCapabilities_cb hidl_cb) override; - Return<void> dumpDebugInfo(dumpDebugInfo_cb hidl_cb) override; - Return<void> createClient(createClient_cb hidl_cb) override; - Return<void> createClient_2_3( - IComposer::createClient_2_3_cb hidl_cb) override; - - // ComposerView: - void ForceDisplaysRefresh() override; - void RegisterObserver(Observer* observer) override; - void UnregisterObserver(Observer* observer) override; - - Return<void> debug(const hidl_handle& fd, - const hidl_vec<hidl_string>& args) override; - - private: - class VsyncCallback : public BnVsyncCallback { - public: - status_t onVsync(int64_t vsync_timestamp) override; - void SetEventCallback(EventCallback* callback); - private: - std::mutex mutex_; - EventCallback* callback_; - }; - - HwcDisplay* FindDisplay(Display display); - - // Re-evaluate whether or not we should start making onVsync() callbacks to - // the client. We need enableCallback(true) to have been called, and - // setVsyncEnabled() to have been called for the primary display. The caller - // must have mutex_ locked already. - void UpdateVsyncCallbackEnabledLocked(); - - wp<VrComposerClient> client_; - - // Guard access to internal state from binder threads. - std::mutex mutex_; - - std::unordered_map<Display, std::unique_ptr<HwcDisplay>> displays_; - Display display_count_ = 2; - - EventCallback* event_callback_ = nullptr; - Observer* observer_ = nullptr; - - sp<VsyncCallback> vsync_callback_; - - VrHwc(const VrHwc&) = delete; - void operator=(const VrHwc&) = delete; -}; - -} // namespace dvr -} // namespace android - -#endif // ANDROID_DVR_HARDWARE_COMPOSER_IMPL_VR_HWC_H diff --git a/services/vr/hardware_composer/tests/vr_composer_test.cpp b/services/vr/hardware_composer/tests/vr_composer_test.cpp deleted file mode 100644 index 2e70928662..0000000000 --- a/services/vr/hardware_composer/tests/vr_composer_test.cpp +++ /dev/null @@ -1,172 +0,0 @@ -#include <android/dvr/BnVrComposerCallback.h> -#include <binder/IServiceManager.h> -#include <gtest/gtest.h> -#include <sys/eventfd.h> -#include <vr_composer.h> - -namespace android { -namespace dvr { -namespace { - -const char kVrDisplayName[] = "VrDisplay_Test"; - -class TestComposerView : public ComposerView { - public: - TestComposerView() {} - ~TestComposerView() override = default; - - size_t display_refresh_count() const { return display_refresh_count_; } - - void ForceDisplaysRefresh() override { display_refresh_count_++; } - void RegisterObserver(Observer* observer) override {} - void UnregisterObserver(Observer* observer) override {} - - TestComposerView(const TestComposerView&) = delete; - void operator=(const TestComposerView&) = delete; - - private: - size_t display_refresh_count_ = 0; -}; - -class TestComposerCallback : public BnVrComposerCallback { - public: - TestComposerCallback() {} - ~TestComposerCallback() override = default; - - ComposerView::Frame last_frame() const { return last_frame_; } - - binder::Status onNewFrame( - const ParcelableComposerFrame& frame, - ParcelableUniqueFd* /* fence */) override { - last_frame_ = frame.frame(); - return binder::Status::ok(); - } - - private: - ComposerView::Frame last_frame_; - - TestComposerCallback(const TestComposerCallback&) = delete; - void operator=(const TestComposerCallback&) = delete; -}; - -class TestComposerCallbackWithFence : public TestComposerCallback { - public: - ~TestComposerCallbackWithFence() override = default; - - binder::Status onNewFrame( - const ParcelableComposerFrame& frame, - ParcelableUniqueFd* fence) override { - binder::Status status = TestComposerCallback::onNewFrame(frame, fence); - - base::unique_fd fd(eventfd(0, 0)); - EXPECT_LE(0, fd.get()); - fence->set_fence(fd); - - return status; - } -}; - -sp<GraphicBuffer> CreateBuffer() { - return new GraphicBuffer(600, 400, PIXEL_FORMAT_RGBA_8888, - GraphicBuffer::USAGE_HW_TEXTURE); -} - -} // namespace - -class VrComposerTest : public testing::Test { - public: - VrComposerTest() : composer_(new VrComposer(&composer_view_)) {} - ~VrComposerTest() override = default; - - sp<IVrComposer> GetComposerProxy() const { - sp<IServiceManager> sm(defaultServiceManager()); - return interface_cast<IVrComposer>(sm->getService(String16(kVrDisplayName))); - } - - void SetUp() override { - sp<IServiceManager> sm(defaultServiceManager()); - EXPECT_EQ(OK, - sm->addService(String16(kVrDisplayName), composer_, false)); - } - - protected: - TestComposerView composer_view_; - sp<VrComposer> composer_; - - VrComposerTest(const VrComposerTest&) = delete; - void operator=(const VrComposerTest&) = delete; -}; - -TEST_F(VrComposerTest, TestWithoutObserver) { - sp<IVrComposer> composer = GetComposerProxy(); - ComposerView::Frame frame; - - base::unique_fd fence = composer_->OnNewFrame(frame); - ASSERT_EQ(-1, fence.get()); -} - -TEST_F(VrComposerTest, TestWithObserver) { - sp<IVrComposer> composer = GetComposerProxy(); - sp<TestComposerCallback> callback = new TestComposerCallback(); - ASSERT_EQ(0, composer_view_.display_refresh_count()); - ASSERT_TRUE(composer->registerObserver(callback).isOk()); - ASSERT_EQ(1, composer_view_.display_refresh_count()); - - ComposerView::Frame frame; - base::unique_fd fence = composer_->OnNewFrame(frame); - ASSERT_EQ(-1, fence.get()); -} - -TEST_F(VrComposerTest, TestWithOneLayer) { - sp<IVrComposer> composer = GetComposerProxy(); - sp<TestComposerCallback> callback = new TestComposerCallbackWithFence(); - ASSERT_TRUE(composer->registerObserver(callback).isOk()); - - ComposerView::Frame frame; - frame.display_id = 1; - frame.removed = false; - frame.display_width = 600; - frame.display_height = 400; - frame.layers.push_back(ComposerView::ComposerLayer{ - .id = 1, - .buffer = CreateBuffer(), - .fence = new Fence(eventfd(0, 0)), - .display_frame = {0, 0, 600, 400}, - .crop = {0.0f, 0.0f, 600.0f, 400.0f}, - .blend_mode = IComposerClient::BlendMode::NONE, - .alpha = 1.0f, - .type = 1, - .app_id = 1, - }); - base::unique_fd fence = composer_->OnNewFrame(frame); - ASSERT_LE(0, fence.get()); - - ComposerView::Frame received_frame = callback->last_frame(); - ASSERT_EQ(frame.display_id, received_frame.display_id); - ASSERT_EQ(frame.display_width, received_frame.display_width); - ASSERT_EQ(frame.display_height, received_frame.display_height); - ASSERT_EQ(frame.removed, received_frame.removed); - ASSERT_EQ(1u, received_frame.layers.size()); - ASSERT_EQ(frame.layers[0].id, received_frame.layers[0].id); - ASSERT_NE(nullptr, received_frame.layers[0].buffer.get()); - ASSERT_TRUE(received_frame.layers[0].fence->isValid()); - ASSERT_EQ(frame.layers[0].display_frame.left, - received_frame.layers[0].display_frame.left); - ASSERT_EQ(frame.layers[0].display_frame.top, - received_frame.layers[0].display_frame.top); - ASSERT_EQ(frame.layers[0].display_frame.right, - received_frame.layers[0].display_frame.right); - ASSERT_EQ(frame.layers[0].display_frame.bottom, - received_frame.layers[0].display_frame.bottom); - ASSERT_EQ(frame.layers[0].crop.left, received_frame.layers[0].crop.left); - ASSERT_EQ(frame.layers[0].crop.top, received_frame.layers[0].crop.top); - ASSERT_EQ(frame.layers[0].crop.right, received_frame.layers[0].crop.right); - ASSERT_EQ(frame.layers[0].crop.bottom, received_frame.layers[0].crop.bottom); - ASSERT_EQ(frame.layers[0].blend_mode, received_frame.layers[0].blend_mode); - ASSERT_EQ(frame.layers[0].alpha, received_frame.layers[0].alpha); - ASSERT_EQ(frame.layers[0].type, received_frame.layers[0].type); - ASSERT_EQ(frame.layers[0].app_id, received_frame.layers[0].app_id); -} - -} // namespace dvr -} // namespace android diff --git a/services/vr/hardware_composer/vr_composer.cpp b/services/vr/hardware_composer/vr_composer.cpp deleted file mode 100644 index d93f370945..0000000000 --- a/services/vr/hardware_composer/vr_composer.cpp +++ /dev/null @@ -1,85 +0,0 @@ -#include "vr_composer.h" - -#include <binder/IPCThreadState.h> -#include <binder/PermissionCache.h> - -namespace android { -namespace dvr { -namespace { - -bool CheckPermission() { - const android::IPCThreadState* ipc = android::IPCThreadState::self(); - const pid_t pid = ipc->getCallingPid(); - const uid_t uid = ipc->getCallingUid(); - const bool permission = PermissionCache::checkPermission( - String16("android.permission.RESTRICTED_VR_ACCESS"), pid, uid); - if (!permission) - ALOGE("permission denied to pid=%d uid=%u", pid, uid); - - return permission; -} - -} // namespace - -VrComposer::VrComposer(ComposerView* composer_view) - : composer_view_(composer_view) { - composer_view_->RegisterObserver(this); -} - -VrComposer::~VrComposer() { - composer_view_->UnregisterObserver(this); -} - -binder::Status VrComposer::registerObserver( - const sp<IVrComposerCallback>& callback) { - { - std::lock_guard<std::mutex> guard(mutex_); - - if (!CheckPermission()) - return binder::Status::fromStatusT(PERMISSION_DENIED); - - if (callback_.get()) { - ALOGE("Failed to register callback, already registered"); - return binder::Status::fromStatusT(ALREADY_EXISTS); - } - - callback_ = callback; - IInterface::asBinder(callback_)->linkToDeath(this); - } - - // Don't take the lock to force display refresh otherwise it could end in a - // deadlock since HWC calls this with new frames and it has a lock of its own - // to serialize access to the display information. - composer_view_->ForceDisplaysRefresh(); - return binder::Status::ok(); -} - -binder::Status VrComposer::clearObserver() { - std::lock_guard<std::mutex> guard(mutex_); - callback_ = nullptr; - return binder::Status::ok(); -} - -base::unique_fd VrComposer::OnNewFrame(const ComposerView::Frame& frame) { - std::lock_guard<std::mutex> guard(mutex_); - - if (!callback_.get()) - return base::unique_fd(); - - ParcelableComposerFrame parcelable_frame(frame); - ParcelableUniqueFd fence; - binder::Status ret = callback_->onNewFrame(parcelable_frame, &fence); - if (!ret.isOk()) - ALOGE("Failed to send new frame: %s", ret.toString8().string()); - - return fence.fence(); -} - -void VrComposer::binderDied(const wp<IBinder>& /* who */) { - std::lock_guard<std::mutex> guard(mutex_); - - callback_ = nullptr; -} - -} // namespace dvr -} // namespace android diff --git a/services/vr/hardware_composer/vr_composer.h b/services/vr/hardware_composer/vr_composer.h deleted file mode 100644 index 1273352ad0..0000000000 --- a/services/vr/hardware_composer/vr_composer.h +++ /dev/null @@ -1,52 +0,0 @@ -#ifndef ANDROID_DVR_HARDWARE_COMPOSER_VR_COMPOSER_H -#define ANDROID_DVR_HARDWARE_COMPOSER_VR_COMPOSER_H - -#include <android/dvr/BnVrComposer.h> -#include <impl/vr_hwc.h> - -namespace android { -namespace dvr { - -class VrComposerCallback; - -// Implementation of the IVrComposer service used to notify VR Window Manager -// when SurfaceFlinger presents 2D UI changes. -// -// VR HWC updates the presented frame via the ComposerView::Observer interface. -// On notification |callback_| is called to update VR Window Manager. -// NOTE: If VR Window Manager isn't connected, the notification is a no-op. -class VrComposer - : public BnVrComposer, - public ComposerView::Observer, - public IBinder::DeathRecipient { - public: - explicit VrComposer(ComposerView* composer_view); - ~VrComposer() override; - - // BnVrComposer: - binder::Status registerObserver( - const sp<IVrComposerCallback>& callback) override; - - binder::Status clearObserver() override; - - // ComposerView::Observer: - base::unique_fd OnNewFrame(const ComposerView::Frame& frame) override; - - private: - // IBinder::DeathRecipient: - void binderDied(const wp<IBinder>& who) override; - - std::mutex mutex_; - - sp<IVrComposerCallback> callback_; - - ComposerView* composer_view_; // Not owned. - - VrComposer(const VrComposer&) = delete; - void operator=(const VrComposer&) = delete; -}; - -} // namespace dvr -} // namespace android - -#endif // ANDROID_DVR_HARDWARE_COMPOSER_VR_COMPOSER_H |