diff options
36 files changed, 0 insertions, 7239 deletions
diff --git a/libs/gui/Android.bp b/libs/gui/Android.bp index 23a2181e59..a988e39de0 100644 --- a/libs/gui/Android.bp +++ b/libs/gui/Android.bp @@ -191,8 +191,6 @@ cc_library_shared { "BitTube.cpp", "BLASTBufferQueue.cpp", - "BufferHubConsumer.cpp", - "BufferHubProducer.cpp", "BufferItemConsumer.cpp", "CompositorTiming.cpp", "ConsumerBase.cpp", @@ -228,9 +226,6 @@ cc_library_shared { shared_libs: [ "libbinder", - "libbufferhub", - "libbufferhubqueue", // TODO(b/70046255): Remove this once BufferHub is integrated into libgui. - "libpdx_default_transport", ], export_shared_lib_headers: [ @@ -241,24 +236,6 @@ cc_library_shared { "libgui_aidl_headers", ], - // bufferhub is not used when building libgui for vendors - target: { - vendor: { - cflags: [ - "-DNO_BUFFERHUB", - ], - exclude_srcs: [ - "BufferHubConsumer.cpp", - "BufferHubProducer.cpp", - ], - exclude_shared_libs: [ - "libbufferhub", - "libbufferhubqueue", - "libpdx_default_transport", - ], - }, - }, - aidl: { export_aidl_headers: true, }, @@ -288,7 +265,6 @@ cc_library_static { min_sdk_version: "29", cflags: [ - "-DNO_BUFFERHUB", "-DNO_BINDER", ], diff --git a/libs/gui/BufferHubConsumer.cpp b/libs/gui/BufferHubConsumer.cpp deleted file mode 100644 index b5cdeb280a..0000000000 --- a/libs/gui/BufferHubConsumer.cpp +++ /dev/null @@ -1,161 +0,0 @@ -/* - * Copyright 2018 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 <gui/BufferHubConsumer.h> - -namespace android { - -using namespace dvr; - -/* static */ -sp<BufferHubConsumer> BufferHubConsumer::Create(const std::shared_ptr<ConsumerQueue>& queue) { - sp<BufferHubConsumer> consumer = new BufferHubConsumer; - consumer->mQueue = queue; - return consumer; -} - -/* static */ sp<BufferHubConsumer> BufferHubConsumer::Create(ConsumerQueueParcelable parcelable) { - if (!parcelable.IsValid()) { - ALOGE("BufferHubConsumer::Create: Invalid consumer parcelable."); - return nullptr; - } - - sp<BufferHubConsumer> consumer = new BufferHubConsumer; - consumer->mQueue = ConsumerQueue::Import(parcelable.TakeChannelHandle()); - return consumer; -} - -status_t BufferHubConsumer::acquireBuffer(BufferItem* /*buffer*/, nsecs_t /*presentWhen*/, - uint64_t /*maxFrameNumber*/) { - ALOGE("BufferHubConsumer::acquireBuffer: not implemented."); - return INVALID_OPERATION; -} - -status_t BufferHubConsumer::detachBuffer(int /*slot*/) { - ALOGE("BufferHubConsumer::detachBuffer: not implemented."); - return INVALID_OPERATION; -} - -status_t BufferHubConsumer::attachBuffer(int* /*outSlot*/, const sp<GraphicBuffer>& /*buffer*/) { - ALOGE("BufferHubConsumer::attachBuffer: not implemented."); - return INVALID_OPERATION; -} - -status_t BufferHubConsumer::releaseBuffer(int /*buf*/, uint64_t /*frameNumber*/, - EGLDisplay /*display*/, EGLSyncKHR /*fence*/, - const sp<Fence>& /*releaseFence*/) { - ALOGE("BufferHubConsumer::releaseBuffer: not implemented."); - return INVALID_OPERATION; -} - -status_t BufferHubConsumer::consumerConnect(const sp<IConsumerListener>& /*consumer*/, - bool /*controlledByApp*/) { - ALOGE("BufferHubConsumer::consumerConnect: not implemented."); - - // TODO(b/73267953): Make BufferHub honor producer and consumer connection. Returns NO_ERROR to - // make IGraphicBufferConsumer_test happy. - return NO_ERROR; -} - -status_t BufferHubConsumer::consumerDisconnect() { - ALOGE("BufferHubConsumer::consumerDisconnect: not implemented."); - - // TODO(b/73267953): Make BufferHub honor producer and consumer connection. Returns NO_ERROR to - // make IGraphicBufferConsumer_test happy. - return NO_ERROR; -} - -status_t BufferHubConsumer::getReleasedBuffers(uint64_t* /*slotMask*/) { - ALOGE("BufferHubConsumer::getReleasedBuffers: not implemented."); - return INVALID_OPERATION; -} - -status_t BufferHubConsumer::setDefaultBufferSize(uint32_t /*w*/, uint32_t /*h*/) { - ALOGE("BufferHubConsumer::setDefaultBufferSize: not implemented."); - return INVALID_OPERATION; -} - -status_t BufferHubConsumer::setMaxBufferCount(int /*bufferCount*/) { - ALOGE("BufferHubConsumer::setMaxBufferCount: not implemented."); - return INVALID_OPERATION; -} - -status_t BufferHubConsumer::setMaxAcquiredBufferCount(int /*maxAcquiredBuffers*/) { - ALOGE("BufferHubConsumer::setMaxAcquiredBufferCount: not implemented."); - - // TODO(b/73267953): Make BufferHub honor producer and consumer connection. Returns NO_ERROR to - // make IGraphicBufferConsumer_test happy. - return NO_ERROR; -} - -status_t BufferHubConsumer::setConsumerName(const String8& /*name*/) { - ALOGE("BufferHubConsumer::setConsumerName: not implemented."); - return INVALID_OPERATION; -} - -status_t BufferHubConsumer::setDefaultBufferFormat(PixelFormat /*defaultFormat*/) { - ALOGE("BufferHubConsumer::setDefaultBufferFormat: not implemented."); - return INVALID_OPERATION; -} - -status_t BufferHubConsumer::setDefaultBufferDataSpace(android_dataspace /*defaultDataSpace*/) { - ALOGE("BufferHubConsumer::setDefaultBufferDataSpace: not implemented."); - return INVALID_OPERATION; -} - -status_t BufferHubConsumer::setConsumerUsageBits(uint64_t /*usage*/) { - ALOGE("BufferHubConsumer::setConsumerUsageBits: not implemented."); - return INVALID_OPERATION; -} - -status_t BufferHubConsumer::setConsumerIsProtected(bool /*isProtected*/) { - ALOGE("BufferHubConsumer::setConsumerIsProtected: not implemented."); - return INVALID_OPERATION; -} - -status_t BufferHubConsumer::setTransformHint(uint32_t /*hint*/) { - ALOGE("BufferHubConsumer::setTransformHint: not implemented."); - return INVALID_OPERATION; -} - -status_t BufferHubConsumer::getSidebandStream(sp<NativeHandle>* /*outStream*/) const { - ALOGE("BufferHubConsumer::getSidebandStream: not implemented."); - return INVALID_OPERATION; -} - -status_t BufferHubConsumer::getOccupancyHistory( - bool /*forceFlush*/, std::vector<OccupancyTracker::Segment>* /*outHistory*/) { - ALOGE("BufferHubConsumer::getOccupancyHistory: not implemented."); - return INVALID_OPERATION; -} - -status_t BufferHubConsumer::discardFreeBuffers() { - ALOGE("BufferHubConsumer::discardFreeBuffers: not implemented."); - return INVALID_OPERATION; -} - -status_t BufferHubConsumer::dumpState(const String8& /*prefix*/, String8* /*outResult*/) const { - ALOGE("BufferHubConsumer::dumpState: not implemented."); - return INVALID_OPERATION; -} - -IBinder* BufferHubConsumer::onAsBinder() { - ALOGE("BufferHubConsumer::onAsBinder: BufferHubConsumer should never be used as an Binder " - "object."); - return nullptr; -} - -} // namespace android diff --git a/libs/gui/BufferHubProducer.cpp b/libs/gui/BufferHubProducer.cpp deleted file mode 100644 index 1f71e23b4d..0000000000 --- a/libs/gui/BufferHubProducer.cpp +++ /dev/null @@ -1,868 +0,0 @@ -/* - * Copyright 2018 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 <dvr/dvr_api.h> -#include <gui/BufferHubProducer.h> -#include <inttypes.h> -#include <log/log.h> -#include <system/window.h> - -namespace android { - -using namespace dvr; - -/* static */ -sp<BufferHubProducer> BufferHubProducer::Create(const std::shared_ptr<ProducerQueue>& queue) { - sp<BufferHubProducer> producer = new BufferHubProducer; - producer->queue_ = queue; - return producer; -} - -/* static */ -sp<BufferHubProducer> BufferHubProducer::Create(ProducerQueueParcelable parcelable) { - if (!parcelable.IsValid()) { - ALOGE("BufferHubProducer::Create: Invalid producer parcelable."); - return nullptr; - } - - sp<BufferHubProducer> producer = new BufferHubProducer; - producer->queue_ = ProducerQueue::Import(parcelable.TakeChannelHandle()); - return producer; -} - -status_t BufferHubProducer::requestBuffer(int slot, sp<GraphicBuffer>* buf) { - ALOGV("requestBuffer: slot=%d", slot); - - std::unique_lock<std::mutex> lock(mutex_); - - if (connected_api_ == kNoConnectedApi) { - ALOGE("requestBuffer: BufferHubProducer has no connected producer"); - return NO_INIT; - } - - if (slot < 0 || slot >= max_buffer_count_) { - ALOGE("requestBuffer: slot index %d out of range [0, %d)", slot, max_buffer_count_); - return BAD_VALUE; - } else if (!buffers_[slot].mBufferState.isDequeued()) { - ALOGE("requestBuffer: slot %d is not owned by the producer (state = %s)", slot, - buffers_[slot].mBufferState.string()); - return BAD_VALUE; - } else if (buffers_[slot].mGraphicBuffer != nullptr) { - ALOGE("requestBuffer: slot %d is not empty.", slot); - return BAD_VALUE; - } else if (buffers_[slot].mProducerBuffer == nullptr) { - ALOGE("requestBuffer: slot %d is not dequeued.", slot); - return BAD_VALUE; - } - - const auto& producer_buffer = buffers_[slot].mProducerBuffer; - sp<GraphicBuffer> graphic_buffer = producer_buffer->buffer()->buffer(); - - buffers_[slot].mGraphicBuffer = graphic_buffer; - buffers_[slot].mRequestBufferCalled = true; - - *buf = graphic_buffer; - return NO_ERROR; -} - -status_t BufferHubProducer::setMaxDequeuedBufferCount(int max_dequeued_buffers) { - ALOGV("setMaxDequeuedBufferCount: max_dequeued_buffers=%d", max_dequeued_buffers); - - std::unique_lock<std::mutex> lock(mutex_); - - if (max_dequeued_buffers <= 0 || - max_dequeued_buffers > - int(BufferHubQueue::kMaxQueueCapacity - kDefaultUndequeuedBuffers)) { - ALOGE("setMaxDequeuedBufferCount: %d out of range (0, %zu]", max_dequeued_buffers, - BufferHubQueue::kMaxQueueCapacity); - return BAD_VALUE; - } - - // The new dequeued_buffers count should not be violated by the number - // of currently dequeued buffers. - int dequeued_count = 0; - for (const auto& buf : buffers_) { - if (buf.mBufferState.isDequeued()) { - dequeued_count++; - } - } - if (dequeued_count > max_dequeued_buffers) { - ALOGE("setMaxDequeuedBufferCount: the requested dequeued_buffers" - "count (%d) exceeds the current dequeued buffer count (%d)", - max_dequeued_buffers, dequeued_count); - return BAD_VALUE; - } - - max_dequeued_buffer_count_ = max_dequeued_buffers; - return NO_ERROR; -} - -status_t BufferHubProducer::setAsyncMode(bool async) { - if (async) { - // TODO(b/36724099) BufferHubQueue's consumer end always acquires the buffer - // automatically and behaves differently from IGraphicBufferConsumer. Thus, - // android::BufferQueue's async mode (a.k.a. allocating an additional buffer - // to prevent dequeueBuffer from being blocking) technically does not apply - // here. - // - // In Daydream, non-blocking producer side dequeue is guaranteed by careful - // buffer consumer implementations. In another word, BufferHubQueue based - // dequeueBuffer should never block whether setAsyncMode(true) is set or - // not. - // - // See: IGraphicBufferProducer::setAsyncMode and - // BufferQueueProducer::setAsyncMode for more about original implementation. - ALOGW("BufferHubProducer::setAsyncMode: BufferHubQueue should always be " - "asynchronous. This call makes no effact."); - return NO_ERROR; - } - return NO_ERROR; -} - -status_t BufferHubProducer::dequeueBuffer(int* out_slot, sp<Fence>* out_fence, uint32_t width, - uint32_t height, PixelFormat format, uint64_t usage, - uint64_t* /*outBufferAge*/, - FrameEventHistoryDelta* /* out_timestamps */) { - ALOGV("dequeueBuffer: w=%u, h=%u, format=%d, usage=%" PRIu64, width, height, format, usage); - - status_t ret; - std::unique_lock<std::mutex> lock(mutex_); - - if (connected_api_ == kNoConnectedApi) { - ALOGE("dequeueBuffer: BufferQueue has no connected producer"); - return NO_INIT; - } - - const uint32_t kLayerCount = 1; - if (int32_t(queue_->capacity()) < max_dequeued_buffer_count_ + kDefaultUndequeuedBuffers) { - // Lazy allocation. When the capacity of |queue_| has not reached - // |max_dequeued_buffer_count_|, allocate new buffer. - // TODO(jwcai) To save memory, the really reasonable thing to do is to go - // over existing slots and find first existing one to dequeue. - ret = AllocateBuffer(width, height, kLayerCount, format, usage); - if (ret < 0) return ret; - } - - size_t slot = 0; - std::shared_ptr<ProducerBuffer> producer_buffer; - - for (size_t retry = 0; retry < BufferHubQueue::kMaxQueueCapacity; retry++) { - LocalHandle fence; - auto buffer_status = queue_->Dequeue(dequeue_timeout_ms_, &slot, &fence); - if (!buffer_status) return NO_MEMORY; - - producer_buffer = buffer_status.take(); - if (!producer_buffer) return NO_MEMORY; - - if (width == producer_buffer->width() && height == producer_buffer->height() && - uint32_t(format) == producer_buffer->format()) { - // The producer queue returns a producer buffer matches the request. - break; - } - - // Needs reallocation. - // TODO(jwcai) Consider use VLOG instead if we find this log is not useful. - ALOGI("dequeueBuffer: requested buffer (w=%u, h=%u, format=%u) is different " - "from the buffer returned at slot: %zu (w=%u, h=%u, format=%u). Need " - "re-allocattion.", - width, height, format, slot, producer_buffer->width(), producer_buffer->height(), - producer_buffer->format()); - // Mark the slot as reallocating, so that later we can set - // BUFFER_NEEDS_REALLOCATION when the buffer actually get dequeued. - buffers_[slot].mIsReallocating = true; - - // Remove the old buffer once the allocation before allocating its - // replacement. - RemoveBuffer(slot); - - // Allocate a new producer buffer with new buffer configs. Note that if - // there are already multiple buffers in the queue, the next one returned - // from |queue_->Dequeue| may not be the new buffer we just reallocated. - // Retry up to BufferHubQueue::kMaxQueueCapacity times. - ret = AllocateBuffer(width, height, kLayerCount, format, usage); - if (ret < 0) return ret; - } - - // With the BufferHub backed solution. Buffer slot returned from - // |queue_->Dequeue| is guaranteed to avaiable for producer's use. - // It's either in free state (if the buffer has never been used before) or - // in queued state (if the buffer has been dequeued and queued back to - // BufferHubQueue). - LOG_ALWAYS_FATAL_IF((!buffers_[slot].mBufferState.isFree() && - !buffers_[slot].mBufferState.isQueued()), - "dequeueBuffer: slot %zu is not free or queued, actual state: %s.", slot, - buffers_[slot].mBufferState.string()); - - buffers_[slot].mBufferState.freeQueued(); - buffers_[slot].mBufferState.dequeue(); - ALOGV("dequeueBuffer: slot=%zu", slot); - - // TODO(jwcai) Handle fence properly. |BufferHub| has full fence support, we - // just need to exopose that through |BufferHubQueue| once we need fence. - *out_fence = Fence::NO_FENCE; - *out_slot = int(slot); - ret = NO_ERROR; - - if (buffers_[slot].mIsReallocating) { - ret |= BUFFER_NEEDS_REALLOCATION; - buffers_[slot].mIsReallocating = false; - } - - return ret; -} - -status_t BufferHubProducer::detachBuffer(int slot) { - ALOGV("detachBuffer: slot=%d", slot); - std::unique_lock<std::mutex> lock(mutex_); - - return DetachBufferLocked(static_cast<size_t>(slot)); -} - -status_t BufferHubProducer::DetachBufferLocked(size_t slot) { - if (connected_api_ == kNoConnectedApi) { - ALOGE("detachBuffer: BufferHubProducer is not connected."); - return NO_INIT; - } - - if (slot >= static_cast<size_t>(max_buffer_count_)) { - ALOGE("detachBuffer: slot index %zu out of range [0, %d)", slot, max_buffer_count_); - return BAD_VALUE; - } else if (!buffers_[slot].mBufferState.isDequeued()) { - ALOGE("detachBuffer: slot %zu is not owned by the producer (state = %s)", slot, - buffers_[slot].mBufferState.string()); - return BAD_VALUE; - } else if (!buffers_[slot].mRequestBufferCalled) { - ALOGE("detachBuffer: buffer in slot %zu has not been requested", slot); - return BAD_VALUE; - } - std::shared_ptr<ProducerBuffer> producer_buffer = queue_->GetBuffer(slot); - if (producer_buffer == nullptr || producer_buffer->buffer() == nullptr) { - ALOGE("detachBuffer: Invalid ProducerBuffer at slot %zu.", slot); - return BAD_VALUE; - } - sp<GraphicBuffer> graphic_buffer = producer_buffer->buffer()->buffer(); - if (graphic_buffer == nullptr) { - ALOGE("detachBuffer: Invalid GraphicBuffer at slot %zu.", slot); - return BAD_VALUE; - } - - // Remove the ProducerBuffer from the ProducerQueue. - status_t error = RemoveBuffer(slot); - if (error != NO_ERROR) { - ALOGE("detachBuffer: Failed to remove buffer, slot=%zu, error=%d.", slot, error); - return error; - } - - // Here we need to convert the existing ProducerBuffer into a DetachedBufferHandle and inject - // the handle into the GraphicBuffer object at the requested slot. - auto status_or_handle = producer_buffer->Detach(); - if (!status_or_handle.ok()) { - ALOGE("detachBuffer: Failed to detach from a ProducerBuffer at slot %zu, error=%d.", slot, - status_or_handle.error()); - return BAD_VALUE; - } - - // TODO(b/70912269): Reimplement BufferHubProducer::DetachBufferLocked() once GraphicBuffer can - // be directly backed by BufferHub. - return INVALID_OPERATION; -} - -status_t BufferHubProducer::detachNextBuffer(sp<GraphicBuffer>* out_buffer, sp<Fence>* out_fence) { - ALOGV("detachNextBuffer."); - - if (out_buffer == nullptr || out_fence == nullptr) { - ALOGE("detachNextBuffer: Invalid parameter: out_buffer=%p, out_fence=%p", out_buffer, - out_fence); - return BAD_VALUE; - } - - std::unique_lock<std::mutex> lock(mutex_); - - if (connected_api_ == kNoConnectedApi) { - ALOGE("detachNextBuffer: BufferHubProducer is not connected."); - return NO_INIT; - } - - // detachNextBuffer is equivalent to calling dequeueBuffer, requestBuffer, and detachBuffer in - // sequence, except for two things: - // - // 1) It is unnecessary to know the dimensions, format, or usage of the next buffer, i.e. the - // function just returns whatever ProducerBuffer is available from the ProducerQueue and no - // buffer allocation or re-allocation will happen. - // 2) It will not block, since if it cannot find an appropriate buffer to return, it will return - // an error instead. - size_t slot = 0; - LocalHandle fence; - - // First, dequeue a ProducerBuffer from the ProducerQueue with no timeout. Report error - // immediately if ProducerQueue::Dequeue() fails. - auto status_or_buffer = queue_->Dequeue(/*timeout=*/0, &slot, &fence); - if (!status_or_buffer.ok()) { - ALOGE("detachNextBuffer: Failed to dequeue buffer, error=%d.", status_or_buffer.error()); - return NO_MEMORY; - } - - std::shared_ptr<ProducerBuffer> producer_buffer = status_or_buffer.take(); - if (producer_buffer == nullptr) { - ALOGE("detachNextBuffer: Dequeued buffer is null."); - return NO_MEMORY; - } - - // With the BufferHub backed solution, slot returned from |queue_->Dequeue| is guaranteed to - // be available for producer's use. It's either in free state (if the buffer has never been used - // before) or in queued state (if the buffer has been dequeued and queued back to - // BufferHubQueue). - if (!buffers_[slot].mBufferState.isFree() && !buffers_[slot].mBufferState.isQueued()) { - ALOGE("detachNextBuffer: slot %zu is not free or queued, actual state: %s.", slot, - buffers_[slot].mBufferState.string()); - return BAD_VALUE; - } - if (buffers_[slot].mProducerBuffer == nullptr) { - ALOGE("detachNextBuffer: ProducerBuffer at slot %zu is null.", slot); - return BAD_VALUE; - } - if (buffers_[slot].mProducerBuffer->id() != producer_buffer->id()) { - ALOGE("detachNextBuffer: ProducerBuffer at slot %zu has mismatched id, actual: " - "%d, expected: %d.", - slot, buffers_[slot].mProducerBuffer->id(), producer_buffer->id()); - return BAD_VALUE; - } - - ALOGV("detachNextBuffer: slot=%zu", slot); - buffers_[slot].mBufferState.freeQueued(); - buffers_[slot].mBufferState.dequeue(); - - // Second, request the buffer. - sp<GraphicBuffer> graphic_buffer = producer_buffer->buffer()->buffer(); - buffers_[slot].mGraphicBuffer = producer_buffer->buffer()->buffer(); - - // Finally, detach the buffer and then return. - status_t error = DetachBufferLocked(slot); - if (error == NO_ERROR) { - *out_fence = new Fence(fence.Release()); - *out_buffer = graphic_buffer; - } - return error; -} - -status_t BufferHubProducer::attachBuffer(int* out_slot, const sp<GraphicBuffer>& buffer) { - // In the BufferHub design, all buffers are allocated and owned by the BufferHub. Thus only - // GraphicBuffers that are originated from BufferHub can be attached to a BufferHubProducer. - ALOGV("queueBuffer: buffer=%p", buffer.get()); - - if (out_slot == nullptr) { - ALOGE("attachBuffer: out_slot cannot be NULL."); - return BAD_VALUE; - } - if (buffer == nullptr) { - ALOGE("attachBuffer: invalid GraphicBuffer."); - return BAD_VALUE; - } - - std::unique_lock<std::mutex> lock(mutex_); - - if (connected_api_ == kNoConnectedApi) { - ALOGE("attachBuffer: BufferQueue has no connected producer"); - return NO_INIT; - } - - // Before attaching the buffer, caller is supposed to call - // IGraphicBufferProducer::setGenerationNumber to inform the - // BufferHubProducer the next generation number. - if (buffer->getGenerationNumber() != generation_number_) { - ALOGE("attachBuffer: Mismatched generation number, buffer: %u, queue: %u.", - buffer->getGenerationNumber(), generation_number_); - return BAD_VALUE; - } - - // TODO(b/70912269): Reimplement BufferHubProducer::DetachBufferLocked() once GraphicBuffer can - // be directly backed by BufferHub. - return INVALID_OPERATION; -} - -status_t BufferHubProducer::queueBuffer(int slot, const QueueBufferInput& input, - QueueBufferOutput* output) { - ALOGV("queueBuffer: slot %d", slot); - - if (output == nullptr) { - return BAD_VALUE; - } - - int64_t timestamp; - bool is_auto_timestamp; - android_dataspace dataspace; - Rect crop(Rect::EMPTY_RECT); - int scaling_mode; - uint32_t transform; - sp<Fence> fence; - - input.deflate(×tamp, &is_auto_timestamp, &dataspace, &crop, &scaling_mode, &transform, - &fence); - - // Check input scaling mode is valid. - switch (scaling_mode) { - case NATIVE_WINDOW_SCALING_MODE_FREEZE: - case NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW: - case NATIVE_WINDOW_SCALING_MODE_SCALE_CROP: - case NATIVE_WINDOW_SCALING_MODE_NO_SCALE_CROP: - break; - default: - ALOGE("queueBuffer: unknown scaling mode %d", scaling_mode); - return BAD_VALUE; - } - - // Check input fence is valid. - if (fence == nullptr) { - ALOGE("queueBuffer: fence is NULL"); - return BAD_VALUE; - } - - std::unique_lock<std::mutex> lock(mutex_); - - if (connected_api_ == kNoConnectedApi) { - ALOGE("queueBuffer: BufferQueue has no connected producer"); - return NO_INIT; - } - - if (slot < 0 || slot >= max_buffer_count_) { - ALOGE("queueBuffer: slot index %d out of range [0, %d)", slot, max_buffer_count_); - return BAD_VALUE; - } else if (!buffers_[slot].mBufferState.isDequeued()) { - ALOGE("queueBuffer: slot %d is not owned by the producer (state = %s)", slot, - buffers_[slot].mBufferState.string()); - return BAD_VALUE; - } else if ((!buffers_[slot].mRequestBufferCalled || buffers_[slot].mGraphicBuffer == nullptr)) { - ALOGE("queueBuffer: slot %d is not requested (mRequestBufferCalled=%d, " - "mGraphicBuffer=%p)", - slot, buffers_[slot].mRequestBufferCalled, buffers_[slot].mGraphicBuffer.get()); - return BAD_VALUE; - } - - // Post the producer buffer with timestamp in the metadata. - const auto& producer_buffer = buffers_[slot].mProducerBuffer; - - // Check input crop is not out of boundary of current buffer. - Rect buffer_rect(producer_buffer->width(), producer_buffer->height()); - Rect cropped_rect(Rect::EMPTY_RECT); - crop.intersect(buffer_rect, &cropped_rect); - if (cropped_rect != crop) { - ALOGE("queueBuffer: slot %d has out-of-boundary crop.", slot); - return BAD_VALUE; - } - - LocalHandle fence_fd(fence->isValid() ? fence->dup() : -1); - - DvrNativeBufferMetadata meta_data; - meta_data.timestamp = timestamp; - meta_data.is_auto_timestamp = int32_t(is_auto_timestamp); - meta_data.dataspace = int32_t(dataspace); - meta_data.crop_left = crop.left; - meta_data.crop_top = crop.top; - meta_data.crop_right = crop.right; - meta_data.crop_bottom = crop.bottom; - meta_data.scaling_mode = int32_t(scaling_mode); - meta_data.transform = int32_t(transform); - - producer_buffer->PostAsync(&meta_data, fence_fd); - buffers_[slot].mBufferState.queue(); - - output->width = producer_buffer->width(); - output->height = producer_buffer->height(); - output->transformHint = 0; // default value, we don't use it yet. - - // |numPendingBuffers| counts of the number of buffers that has been enqueued - // by the producer but not yet acquired by the consumer. Due to the nature - // of BufferHubQueue design, this is hard to trace from the producer's client - // side, but it's safe to assume it's zero. - output->numPendingBuffers = 0; - - // Note that we are not setting nextFrameNumber here as it seems to be only - // used by surface flinger. See more at b/22802885, ag/791760. - output->nextFrameNumber = 0; - - return NO_ERROR; -} - -status_t BufferHubProducer::cancelBuffer(int slot, const sp<Fence>& fence) { - ALOGV(__FUNCTION__); - - std::unique_lock<std::mutex> lock(mutex_); - - if (connected_api_ == kNoConnectedApi) { - ALOGE("cancelBuffer: BufferQueue has no connected producer"); - return NO_INIT; - } - - if (slot < 0 || slot >= max_buffer_count_) { - ALOGE("cancelBuffer: slot index %d out of range [0, %d)", slot, max_buffer_count_); - return BAD_VALUE; - } else if (!buffers_[slot].mBufferState.isDequeued()) { - ALOGE("cancelBuffer: slot %d is not owned by the producer (state = %s)", slot, - buffers_[slot].mBufferState.string()); - return BAD_VALUE; - } else if (fence == nullptr) { - ALOGE("cancelBuffer: fence is NULL"); - return BAD_VALUE; - } - - auto producer_buffer = buffers_[slot].mProducerBuffer; - queue_->Enqueue(producer_buffer, size_t(slot), 0U); - buffers_[slot].mBufferState.cancel(); - buffers_[slot].mFence = fence; - ALOGV("cancelBuffer: slot %d", slot); - - return NO_ERROR; -} - -status_t BufferHubProducer::query(int what, int* out_value) { - ALOGV(__FUNCTION__); - - std::unique_lock<std::mutex> lock(mutex_); - - if (out_value == nullptr) { - ALOGE("query: out_value was NULL"); - return BAD_VALUE; - } - - int value = 0; - switch (what) { - case NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS: - // TODO(b/36187402) This should be the maximum number of buffers that this - // producer queue's consumer can acquire. Set to be at least one. Need to - // find a way to set from the consumer side. - value = kDefaultUndequeuedBuffers; - break; - case NATIVE_WINDOW_BUFFER_AGE: - value = 0; - break; - case NATIVE_WINDOW_WIDTH: - value = int32_t(queue_->default_width()); - break; - case NATIVE_WINDOW_HEIGHT: - value = int32_t(queue_->default_height()); - break; - case NATIVE_WINDOW_FORMAT: - value = int32_t(queue_->default_format()); - break; - case NATIVE_WINDOW_CONSUMER_RUNNING_BEHIND: - // BufferHubQueue is always operating in async mode, thus semantically - // consumer can never be running behind. See BufferQueueCore.cpp core - // for more information about the original meaning of this flag. - value = 0; - break; - case NATIVE_WINDOW_CONSUMER_USAGE_BITS: - // TODO(jwcai) This is currently not implement as we don't need - // IGraphicBufferConsumer parity. - value = 0; - break; - case NATIVE_WINDOW_DEFAULT_DATASPACE: - // TODO(jwcai) Return the default value android::BufferQueue is using as - // there is no way dvr::ConsumerQueue can set it. - value = 0; // HAL_DATASPACE_UNKNOWN - break; - case NATIVE_WINDOW_STICKY_TRANSFORM: - // TODO(jwcai) Return the default value android::BufferQueue is using as - // there is no way dvr::ConsumerQueue can set it. - value = 0; - break; - case NATIVE_WINDOW_CONSUMER_IS_PROTECTED: - // In Daydream's implementation, the consumer end (i.e. VR Compostior) - // knows how to handle protected buffers. - value = 1; - break; - default: - return BAD_VALUE; - } - - ALOGV("query: key=%d, v=%d", what, value); - *out_value = value; - return NO_ERROR; -} - -status_t BufferHubProducer::connect(const sp<IProducerListener>& /* listener */, int api, - bool /* producer_controlled_by_app */, - QueueBufferOutput* output) { - // Consumer interaction are actually handled by buffer hub, and we need - // to maintain consumer operations here. We only need to perform basic input - // parameter checks here. - ALOGV(__FUNCTION__); - - if (output == nullptr) { - return BAD_VALUE; - } - - std::unique_lock<std::mutex> lock(mutex_); - - if (connected_api_ != kNoConnectedApi) { - return BAD_VALUE; - } - - if (!queue_->is_connected()) { - ALOGE("BufferHubProducer::connect: This BufferHubProducer is not " - "connected to bufferhud. Has it been taken out as a parcelable?"); - return BAD_VALUE; - } - - switch (api) { - case NATIVE_WINDOW_API_EGL: - case NATIVE_WINDOW_API_CPU: - case NATIVE_WINDOW_API_MEDIA: - case NATIVE_WINDOW_API_CAMERA: - connected_api_ = api; - - output->width = queue_->default_width(); - output->height = queue_->default_height(); - - // default values, we don't use them yet. - output->transformHint = 0; - output->numPendingBuffers = 0; - output->nextFrameNumber = 0; - output->bufferReplaced = false; - - break; - default: - ALOGE("BufferHubProducer::connect: unknow API %d", api); - return BAD_VALUE; - } - - return NO_ERROR; -} - -status_t BufferHubProducer::disconnect(int api, DisconnectMode /*mode*/) { - // Consumer interaction are actually handled by buffer hub, and we need - // to maintain consumer operations here. We only need to perform basic input - // parameter checks here. - ALOGV(__FUNCTION__); - - std::unique_lock<std::mutex> lock(mutex_); - - if (kNoConnectedApi == connected_api_) { - return NO_INIT; - } else if (api != connected_api_) { - return BAD_VALUE; - } - - FreeAllBuffers(); - connected_api_ = kNoConnectedApi; - return NO_ERROR; -} - -status_t BufferHubProducer::setSidebandStream(const sp<NativeHandle>& stream) { - if (stream != nullptr) { - // TODO(jwcai) Investigate how is is used, maybe use BufferHubBuffer's - // metadata. - ALOGE("SidebandStream is not currently supported."); - return INVALID_OPERATION; - } - return NO_ERROR; -} - -void BufferHubProducer::allocateBuffers(uint32_t /* width */, uint32_t /* height */, - PixelFormat /* format */, uint64_t /* usage */) { - // TODO(jwcai) |allocateBuffers| aims to preallocate up to the maximum number - // of buffers permitted by the current BufferQueue configuration (aka - // |max_buffer_count_|). - ALOGE("BufferHubProducer::allocateBuffers not implemented."); -} - -status_t BufferHubProducer::allowAllocation(bool /* allow */) { - ALOGE("BufferHubProducer::allowAllocation not implemented."); - return INVALID_OPERATION; -} - -status_t BufferHubProducer::setGenerationNumber(uint32_t generation_number) { - ALOGV(__FUNCTION__); - - std::unique_lock<std::mutex> lock(mutex_); - generation_number_ = generation_number; - return NO_ERROR; -} - -String8 BufferHubProducer::getConsumerName() const { - // BufferHub based implementation could have one to many producer/consumer - // relationship, thus |getConsumerName| from the producer side does not - // make any sense. - ALOGE("BufferHubProducer::getConsumerName not supported."); - return String8("BufferHubQueue::StubConsumer"); -} - -status_t BufferHubProducer::setSharedBufferMode(bool shared_buffer_mode) { - if (shared_buffer_mode) { - ALOGE("BufferHubProducer::setSharedBufferMode(true) is not supported."); - // TODO(b/36373181) Front buffer mode for buffer hub queue as ANativeWindow. - return INVALID_OPERATION; - } - // Setting to default should just work as a no-op. - return NO_ERROR; -} - -status_t BufferHubProducer::setAutoRefresh(bool auto_refresh) { - if (auto_refresh) { - ALOGE("BufferHubProducer::setAutoRefresh(true) is not supported."); - return INVALID_OPERATION; - } - // Setting to default should just work as a no-op. - return NO_ERROR; -} - -status_t BufferHubProducer::setDequeueTimeout(nsecs_t timeout) { - ALOGV(__FUNCTION__); - - std::unique_lock<std::mutex> lock(mutex_); - dequeue_timeout_ms_ = static_cast<int>(timeout / (1000 * 1000)); - return NO_ERROR; -} - -status_t BufferHubProducer::getLastQueuedBuffer(sp<GraphicBuffer>* /* out_buffer */, - sp<Fence>* /* out_fence */, - float /*out_transform_matrix*/[16]) { - ALOGE("BufferHubProducer::getLastQueuedBuffer not implemented."); - return INVALID_OPERATION; -} - -void BufferHubProducer::getFrameTimestamps(FrameEventHistoryDelta* /*outDelta*/) { - ALOGE("BufferHubProducer::getFrameTimestamps not implemented."); -} - -status_t BufferHubProducer::getUniqueId(uint64_t* out_id) const { - ALOGV(__FUNCTION__); - - *out_id = unique_id_; - return NO_ERROR; -} - -status_t BufferHubProducer::getConsumerUsage(uint64_t* out_usage) const { - ALOGV(__FUNCTION__); - - // same value as returned by querying NATIVE_WINDOW_CONSUMER_USAGE_BITS - *out_usage = 0; - return NO_ERROR; -} - -status_t BufferHubProducer::TakeAsParcelable(ProducerQueueParcelable* out_parcelable) { - if (!out_parcelable || out_parcelable->IsValid()) return BAD_VALUE; - - if (connected_api_ != kNoConnectedApi) { - ALOGE("BufferHubProducer::TakeAsParcelable: BufferHubProducer has " - "connected client. Must disconnect first."); - return BAD_VALUE; - } - - if (!queue_->is_connected()) { - ALOGE("BufferHubProducer::TakeAsParcelable: This BufferHubProducer " - "is not connected to bufferhud. Has it been taken out as a " - "parcelable?"); - return BAD_VALUE; - } - - auto status = queue_->TakeAsParcelable(); - if (!status) { - ALOGE("BufferHubProducer::TakeAsParcelable: Failed to take out " - "ProducuerQueueParcelable from the producer queue, error: %s.", - status.GetErrorMessage().c_str()); - return BAD_VALUE; - } - - *out_parcelable = status.take(); - return NO_ERROR; -} - -status_t BufferHubProducer::AllocateBuffer(uint32_t width, uint32_t height, uint32_t layer_count, - PixelFormat format, uint64_t usage) { - auto status = queue_->AllocateBuffer(width, height, layer_count, uint32_t(format), usage); - if (!status) { - ALOGE("BufferHubProducer::AllocateBuffer: Failed to allocate buffer: %s", - status.GetErrorMessage().c_str()); - return NO_MEMORY; - } - - size_t slot = status.get(); - auto producer_buffer = queue_->GetBuffer(slot); - - LOG_ALWAYS_FATAL_IF(producer_buffer == nullptr, - "Failed to get the producer buffer at slot: %zu", slot); - - buffers_[slot].mProducerBuffer = producer_buffer; - - return NO_ERROR; -} - -status_t BufferHubProducer::RemoveBuffer(size_t slot) { - auto status = queue_->RemoveBuffer(slot); - if (!status) { - ALOGE("BufferHubProducer::RemoveBuffer: Failed to remove buffer at slot: %zu, error: %s.", - slot, status.GetErrorMessage().c_str()); - return INVALID_OPERATION; - } - - // Reset in memory objects related the the buffer. - buffers_[slot].mProducerBuffer = nullptr; - buffers_[slot].mBufferState.detachProducer(); - buffers_[slot].mFence = Fence::NO_FENCE; - buffers_[slot].mGraphicBuffer = nullptr; - buffers_[slot].mRequestBufferCalled = false; - return NO_ERROR; -} - -status_t BufferHubProducer::FreeAllBuffers() { - for (size_t slot = 0; slot < BufferHubQueue::kMaxQueueCapacity; slot++) { - // Reset in memory objects related the the buffer. - buffers_[slot].mProducerBuffer = nullptr; - buffers_[slot].mBufferState.reset(); - buffers_[slot].mFence = Fence::NO_FENCE; - buffers_[slot].mGraphicBuffer = nullptr; - buffers_[slot].mRequestBufferCalled = false; - } - - auto status = queue_->FreeAllBuffers(); - if (!status) { - ALOGE("BufferHubProducer::FreeAllBuffers: Failed to free all buffers on " - "the queue: %s", - status.GetErrorMessage().c_str()); - } - - if (queue_->capacity() != 0 || queue_->count() != 0) { - LOG_ALWAYS_FATAL("BufferHubProducer::FreeAllBuffers: Not all buffers are freed."); - } - - return NO_ERROR; -} - -status_t BufferHubProducer::exportToParcel(Parcel* parcel) { - status_t res = TakeAsParcelable(&pending_producer_parcelable_); - if (res != NO_ERROR) return res; - - if (!pending_producer_parcelable_.IsValid()) { - ALOGE("BufferHubProducer::exportToParcel: Invalid parcelable object."); - return BAD_VALUE; - } - - res = parcel->writeUint32(USE_BUFFER_HUB); - if (res != NO_ERROR) { - ALOGE("BufferHubProducer::exportToParcel: Cannot write magic, res=%d.", res); - return res; - } - - return pending_producer_parcelable_.writeToParcel(parcel); -} - -IBinder* BufferHubProducer::onAsBinder() { - ALOGE("BufferHubProducer::onAsBinder: BufferHubProducer should never be used as an Binder " - "object."); - return nullptr; -} - -} // namespace android diff --git a/libs/gui/BufferQueue.cpp b/libs/gui/BufferQueue.cpp index c1d92a2a7f..66cad03fec 100644 --- a/libs/gui/BufferQueue.cpp +++ b/libs/gui/BufferQueue.cpp @@ -18,11 +18,6 @@ #define ATRACE_TAG ATRACE_TAG_GRAPHICS //#define LOG_NDEBUG 0 -#ifndef NO_BUFFERHUB -#include <gui/BufferHubConsumer.h> -#include <gui/BufferHubProducer.h> -#endif - #include <gui/BufferQueue.h> #include <gui/BufferQueueConsumer.h> #include <gui/BufferQueueCore.h> @@ -127,32 +122,4 @@ void BufferQueue::createBufferQueue(sp<IGraphicBufferProducer>* outProducer, *outConsumer = consumer; } -#ifndef NO_BUFFERHUB -void BufferQueue::createBufferHubQueue(sp<IGraphicBufferProducer>* outProducer, - sp<IGraphicBufferConsumer>* outConsumer) { - LOG_ALWAYS_FATAL_IF(outProducer == nullptr, "BufferQueue: outProducer must not be NULL"); - LOG_ALWAYS_FATAL_IF(outConsumer == nullptr, "BufferQueue: outConsumer must not be NULL"); - - sp<IGraphicBufferProducer> producer; - sp<IGraphicBufferConsumer> consumer; - - dvr::ProducerQueueConfigBuilder configBuilder; - std::shared_ptr<dvr::ProducerQueue> producerQueue = - dvr::ProducerQueue::Create(configBuilder.Build(), dvr::UsagePolicy{}); - LOG_ALWAYS_FATAL_IF(producerQueue == nullptr, "BufferQueue: failed to create ProducerQueue."); - - std::shared_ptr<dvr::ConsumerQueue> consumerQueue = producerQueue->CreateConsumerQueue(); - LOG_ALWAYS_FATAL_IF(consumerQueue == nullptr, "BufferQueue: failed to create ConsumerQueue."); - - producer = BufferHubProducer::Create(producerQueue); - consumer = BufferHubConsumer::Create(consumerQueue); - - LOG_ALWAYS_FATAL_IF(producer == nullptr, "BufferQueue: failed to create BufferQueueProducer"); - LOG_ALWAYS_FATAL_IF(consumer == nullptr, "BufferQueue: failed to create BufferQueueConsumer"); - - *outProducer = producer; - *outConsumer = consumer; -} -#endif - }; // namespace android diff --git a/libs/gui/IGraphicBufferProducer.cpp b/libs/gui/IGraphicBufferProducer.cpp index 797069c798..918ff2dd25 100644 --- a/libs/gui/IGraphicBufferProducer.cpp +++ b/libs/gui/IGraphicBufferProducer.cpp @@ -27,10 +27,6 @@ #include <binder/Parcel.h> #include <binder/IInterface.h> -#ifndef NO_BUFFERHUB -#include <gui/BufferHubProducer.h> -#endif - #include <gui/bufferqueue/1.0/H2BGraphicBufferProducer.h> #include <gui/bufferqueue/2.0/H2BGraphicBufferProducer.h> #include <gui/BufferQueueDefs.h> @@ -1012,17 +1008,7 @@ sp<IGraphicBufferProducer> IGraphicBufferProducer::createFromParcel(const Parcel } case USE_BUFFER_HUB: { ALOGE("createFromParcel: BufferHub not implemented."); -#ifndef NO_BUFFERHUB - dvr::ProducerQueueParcelable producerParcelable; - res = producerParcelable.readFromParcel(parcel); - if (res != NO_ERROR) { - ALOGE("createFromParcel: Failed to read from parcel, error=%d", res); - return nullptr; - } - return BufferHubProducer::Create(std::move(producerParcelable)); -#else return nullptr; -#endif } default: { ALOGE("createFromParcel: Unexpected mgaic: 0x%x.", outMagic); diff --git a/libs/gui/include/gui/BufferHubConsumer.h b/libs/gui/include/gui/BufferHubConsumer.h deleted file mode 100644 index d38077014b..0000000000 --- a/libs/gui/include/gui/BufferHubConsumer.h +++ /dev/null @@ -1,112 +0,0 @@ -/* - * Copyright 2018 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_GUI_BUFFERHUBCONSUMER_H_ -#define ANDROID_GUI_BUFFERHUBCONSUMER_H_ - -#include <gui/IGraphicBufferConsumer.h> -#include <private/dvr/buffer_hub_queue_client.h> -#include <private/dvr/buffer_hub_queue_parcelable.h> - -namespace android { - -class BufferHubConsumer : public IGraphicBufferConsumer { -public: - // Creates a BufferHubConsumer instance by importing an existing producer queue. - static sp<BufferHubConsumer> Create(const std::shared_ptr<dvr::ConsumerQueue>& queue); - - // Creates a BufferHubConsumer instance by importing an existing producer - // parcelable. Note that this call takes the ownership of the parcelable - // object and is guaranteed to succeed if parcelable object is valid. - static sp<BufferHubConsumer> Create(dvr::ConsumerQueueParcelable parcelable); - - // See |IGraphicBufferConsumer::acquireBuffer| - status_t acquireBuffer(BufferItem* buffer, nsecs_t presentWhen, - uint64_t maxFrameNumber = 0) override; - - // See |IGraphicBufferConsumer::detachBuffer| - status_t detachBuffer(int slot) override; - - // See |IGraphicBufferConsumer::attachBuffer| - status_t attachBuffer(int* outSlot, const sp<GraphicBuffer>& buffer) override; - - // See |IGraphicBufferConsumer::releaseBuffer| - status_t releaseBuffer(int buf, uint64_t frameNumber, EGLDisplay display, EGLSyncKHR fence, - const sp<Fence>& releaseFence) override; - - // See |IGraphicBufferConsumer::consumerConnect| - status_t consumerConnect(const sp<IConsumerListener>& consumer, bool controlledByApp) override; - - // See |IGraphicBufferConsumer::consumerDisconnect| - status_t consumerDisconnect() override; - - // See |IGraphicBufferConsumer::getReleasedBuffers| - status_t getReleasedBuffers(uint64_t* slotMask) override; - - // See |IGraphicBufferConsumer::setDefaultBufferSize| - status_t setDefaultBufferSize(uint32_t w, uint32_t h) override; - - // See |IGraphicBufferConsumer::setMaxBufferCount| - status_t setMaxBufferCount(int bufferCount) override; - - // See |IGraphicBufferConsumer::setMaxAcquiredBufferCount| - status_t setMaxAcquiredBufferCount(int maxAcquiredBuffers) override; - - // See |IGraphicBufferConsumer::setConsumerName| - status_t setConsumerName(const String8& name) override; - - // See |IGraphicBufferConsumer::setDefaultBufferFormat| - status_t setDefaultBufferFormat(PixelFormat defaultFormat) override; - - // See |IGraphicBufferConsumer::setDefaultBufferDataSpace| - status_t setDefaultBufferDataSpace(android_dataspace defaultDataSpace) override; - - // See |IGraphicBufferConsumer::setConsumerUsageBits| - status_t setConsumerUsageBits(uint64_t usage) override; - - // See |IGraphicBufferConsumer::setConsumerIsProtected| - status_t setConsumerIsProtected(bool isProtected) override; - - // See |IGraphicBufferConsumer::setTransformHint| - status_t setTransformHint(uint32_t hint) override; - - // See |IGraphicBufferConsumer::getSidebandStream| - status_t getSidebandStream(sp<NativeHandle>* outStream) const override; - - // See |IGraphicBufferConsumer::getOccupancyHistory| - status_t getOccupancyHistory(bool forceFlush, - std::vector<OccupancyTracker::Segment>* outHistory) override; - - // See |IGraphicBufferConsumer::discardFreeBuffers| - status_t discardFreeBuffers() override; - - // See |IGraphicBufferConsumer::dumpState| - status_t dumpState(const String8& prefix, String8* outResult) const override; - - // BufferHubConsumer provides its own logic to cast to a binder object. - IBinder* onAsBinder() override; - -private: - // Private constructor to force use of |Create|. - BufferHubConsumer() = default; - - // Concrete implementation backed by BufferHubBuffer. - std::shared_ptr<dvr::ConsumerQueue> mQueue; -}; - -} // namespace android - -#endif // ANDROID_GUI_BUFFERHUBCONSUMER_H_ diff --git a/libs/gui/include/gui/BufferHubProducer.h b/libs/gui/include/gui/BufferHubProducer.h deleted file mode 100644 index 0e925ceb3b..0000000000 --- a/libs/gui/include/gui/BufferHubProducer.h +++ /dev/null @@ -1,223 +0,0 @@ -/* - * Copyright 2018 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_GUI_BUFFERHUBPRODUCER_H_ -#define ANDROID_GUI_BUFFERHUBPRODUCER_H_ - -#include <gui/BufferSlot.h> -#include <gui/IGraphicBufferProducer.h> -#include <private/dvr/buffer_hub_queue_client.h> -#include <private/dvr/buffer_hub_queue_parcelable.h> - -namespace android { - -class BufferHubProducer : public IGraphicBufferProducer { -public: - static constexpr int kNoConnectedApi = -1; - - // TODO(b/36187402) The actual implementation of BufferHubQueue's consumer - // side logic doesn't limit the number of buffer it can acquire - // simultaneously. We need a way for consumer logic to configure and enforce - // that. - static constexpr int kDefaultUndequeuedBuffers = 1; - - // Creates a BufferHubProducer instance by importing an existing prodcuer - // queue. - static sp<BufferHubProducer> Create(const std::shared_ptr<dvr::ProducerQueue>& producer); - - // Creates a BufferHubProducer instance by importing an existing prodcuer - // parcelable. Note that this call takes the ownership of the parcelable - // object and is guaranteed to succeed if parcelable object is valid. - static sp<BufferHubProducer> Create(dvr::ProducerQueueParcelable parcelable); - - // See |IGraphicBufferProducer::requestBuffer| - status_t requestBuffer(int slot, sp<GraphicBuffer>* buf) override; - - // For the BufferHub based implementation. All buffers in the queue are - // allowed to be dequeued from the consumer side. It call always returns - // 0 for |NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS| query. Thus setting - // |max_dequeued_buffers| here can be considered the same as setting queue - // capacity. - // - // See |IGraphicBufferProducer::setMaxDequeuedBufferCount| for more info - status_t setMaxDequeuedBufferCount(int max_dequeued_buffers) override; - - // See |IGraphicBufferProducer::setAsyncMode| - status_t setAsyncMode(bool async) override; - - // See |IGraphicBufferProducer::dequeueBuffer| - status_t dequeueBuffer(int* out_slot, sp<Fence>* out_fence, uint32_t width, uint32_t height, - PixelFormat format, uint64_t usage, uint64_t* outBufferAge, - FrameEventHistoryDelta* outTimestamps) override; - - // See |IGraphicBufferProducer::detachBuffer| - status_t detachBuffer(int slot) override; - - // See |IGraphicBufferProducer::detachNextBuffer| - status_t detachNextBuffer(sp<GraphicBuffer>* out_buffer, sp<Fence>* out_fence) override; - - // See |IGraphicBufferProducer::attachBuffer| - status_t attachBuffer(int* out_slot, const sp<GraphicBuffer>& buffer) override; - - // See |IGraphicBufferProducer::queueBuffer| - status_t queueBuffer(int slot, const QueueBufferInput& input, - QueueBufferOutput* output) override; - - // See |IGraphicBufferProducer::cancelBuffer| - status_t cancelBuffer(int slot, const sp<Fence>& fence) override; - - // See |IGraphicBufferProducer::query| - status_t query(int what, int* out_value) override; - - // See |IGraphicBufferProducer::connect| - status_t connect(const sp<IProducerListener>& listener, int api, - bool producer_controlled_by_app, QueueBufferOutput* output) override; - - // See |IGraphicBufferProducer::disconnect| - status_t disconnect(int api, DisconnectMode mode = DisconnectMode::Api) override; - - // See |IGraphicBufferProducer::setSidebandStream| - status_t setSidebandStream(const sp<NativeHandle>& stream) override; - - // See |IGraphicBufferProducer::allocateBuffers| - void allocateBuffers(uint32_t width, uint32_t height, PixelFormat format, - uint64_t usage) override; - - // See |IGraphicBufferProducer::allowAllocation| - status_t allowAllocation(bool allow) override; - - // See |IGraphicBufferProducer::setGenerationNumber| - status_t setGenerationNumber(uint32_t generation_number) override; - - // See |IGraphicBufferProducer::getConsumerName| - String8 getConsumerName() const override; - - // See |IGraphicBufferProducer::setSharedBufferMode| - status_t setSharedBufferMode(bool shared_buffer_mode) override; - - // See |IGraphicBufferProducer::setAutoRefresh| - status_t setAutoRefresh(bool auto_refresh) override; - - // See |IGraphicBufferProducer::setDequeueTimeout| - status_t setDequeueTimeout(nsecs_t timeout) override; - - // See |IGraphicBufferProducer::getLastQueuedBuffer| - status_t getLastQueuedBuffer(sp<GraphicBuffer>* out_buffer, sp<Fence>* out_fence, - float out_transform_matrix[16]) override; - - // See |IGraphicBufferProducer::getFrameTimestamps| - void getFrameTimestamps(FrameEventHistoryDelta* /*outDelta*/) override; - - // See |IGraphicBufferProducer::getUniqueId| - status_t getUniqueId(uint64_t* out_id) const override; - - // See |IGraphicBufferProducer::getConsumerUsage| - status_t getConsumerUsage(uint64_t* out_usage) const override; - - // Takes out the current producer as a binder parcelable object. Note that the - // producer must be disconnected to be exportable. After successful export, - // the producer queue can no longer be connected again. Returns NO_ERROR when - // takeout is successful and out_parcelable will hold the new parcelable - // object. Also note that out_parcelable cannot be NULL and must points to an - // invalid parcelable. - status_t TakeAsParcelable(dvr::ProducerQueueParcelable* out_parcelable); - - IBinder* onAsBinder() override; - -protected: - // See |IGraphicBufferProducer::exportToParcel| - status_t exportToParcel(Parcel* parcel) override; - -private: - using LocalHandle = pdx::LocalHandle; - - // Private constructor to force use of |Create|. - BufferHubProducer() {} - - static uint64_t genUniqueId() { - static std::atomic<uint32_t> counter{0}; - static uint64_t id = static_cast<uint64_t>(getpid()) << 32; - return id | counter++; - } - - // Allocate new buffer through BufferHub and add it into |queue_| for - // bookkeeping. - status_t AllocateBuffer(uint32_t width, uint32_t height, uint32_t layer_count, - PixelFormat format, uint64_t usage); - - // Remove a buffer via BufferHubRPC. - status_t RemoveBuffer(size_t slot); - - // Free all buffers which are owned by the prodcuer. Note that if graphic - // buffers are acquired by the consumer, we can't . - status_t FreeAllBuffers(); - - // Helper function that implements the detachBuffer() call, but assuming |mutex_| has been - // locked already. - status_t DetachBufferLocked(size_t slot); - - // Concreate implementation backed by BufferHubBuffer. - std::shared_ptr<dvr::ProducerQueue> queue_; - - // Mutex for thread safety. - std::mutex mutex_; - - // Connect client API, should be one of the NATIVE_WINDOW_API_* flags. - int connected_api_{kNoConnectedApi}; - - // |max_buffer_count_| sets the capacity of the underlying buffer queue. - int32_t max_buffer_count_{dvr::BufferHubQueue::kMaxQueueCapacity}; - - // |max_dequeued_buffer_count_| set the maximum number of buffers that can - // be dequeued at the same momment. - int32_t max_dequeued_buffer_count_{1}; - - // Sets how long dequeueBuffer or attachBuffer will block if a buffer or - // slot is not yet available. The timeout is stored in milliseconds. - int dequeue_timeout_ms_{dvr::BufferHubQueue::kNoTimeOut}; - - // |generation_number_| stores the current generation number of the attached - // producer. Any attempt to attach a buffer with a different generation - // number will fail. - // TOOD(b/38137191) Currently not used as we don't support - // IGraphicBufferProducer::detachBuffer. - uint32_t generation_number_{0}; - - // |buffers_| stores the buffers that have been dequeued from - // |dvr::BufferHubQueue|, It is initialized to invalid buffers, and gets - // filled in with the result of |Dequeue|. - // TODO(jwcai) The buffer allocated to a slot will also be replaced if the - // requested buffer usage or geometry differs from that of the buffer - // allocated to a slot. - struct BufferHubSlot : public BufferSlot { - BufferHubSlot() : mProducerBuffer(nullptr), mIsReallocating(false) {} - // BufferSlot comes from android framework, using m prefix to comply with - // the name convention with the reset of data fields from BufferSlot. - std::shared_ptr<dvr::ProducerBuffer> mProducerBuffer; - bool mIsReallocating; - }; - BufferHubSlot buffers_[dvr::BufferHubQueue::kMaxQueueCapacity]; - - // A uniqueId used by IGraphicBufferProducer interface. - const uint64_t unique_id_{genUniqueId()}; - - // A pending parcelable object which keeps the bufferhub channel alive. - dvr::ProducerQueueParcelable pending_producer_parcelable_; -}; - -} // namespace android - -#endif // ANDROID_GUI_BUFFERHUBPRODUCER_H_ diff --git a/libs/gui/include/gui/BufferQueue.h b/libs/gui/include/gui/BufferQueue.h index 91f80d2f17..690587f0e6 100644 --- a/libs/gui/include/gui/BufferQueue.h +++ b/libs/gui/include/gui/BufferQueue.h @@ -82,12 +82,6 @@ public: sp<IGraphicBufferConsumer>* outConsumer, bool consumerIsSurfaceFlinger = false); -#ifndef NO_BUFFERHUB - // Creates an IGraphicBufferProducer and IGraphicBufferConsumer pair backed by BufferHub. - static void createBufferHubQueue(sp<IGraphicBufferProducer>* outProducer, - sp<IGraphicBufferConsumer>* outConsumer); -#endif - BufferQueue() = delete; // Create through createBufferQueue }; diff --git a/libs/gui/tests/Android.bp b/libs/gui/tests/Android.bp index 7b37b25a61..183acc12cc 100644 --- a/libs/gui/tests/Android.bp +++ b/libs/gui/tests/Android.bp @@ -93,39 +93,6 @@ cc_test { header_libs: ["libsurfaceflinger_headers"], } -// Build a separate binary to $(TARGET_OUT_DATA_NATIVE_TESTS)/$(LOCAL_MODULE) -// This test has a main method, and requires a separate binary to be built. -// To add move tests like this, just add additional cc_test statements, -// as opposed to adding more source files to this one. -cc_test { - name: "SurfaceParcelable_test", - test_suites: ["device-tests"], - - cflags: [ - "-Wall", - "-Werror", - ], - - srcs: [ - "SurfaceParcelable_test.cpp", - ], - - shared_libs: [ - "liblog", - "libbinder", - "libcutils", - "libgui", - "libui", - "libutils", - "libbufferhubqueue", // TODO(b/70046255): Remove these once BufferHub is integrated into libgui. - "libpdx_default_transport", - ], - - header_libs: [ - "libdvr_headers", - ], -} - cc_test { name: "SamplingDemo", diff --git a/libs/gui/tests/IGraphicBufferProducer_test.cpp b/libs/gui/tests/IGraphicBufferProducer_test.cpp index 2af2fe1f91..3427731fff 100644 --- a/libs/gui/tests/IGraphicBufferProducer_test.cpp +++ b/libs/gui/tests/IGraphicBufferProducer_test.cpp @@ -42,10 +42,6 @@ #define TEST_CONTROLLED_BY_APP false #define TEST_PRODUCER_USAGE_BITS (0) -#ifndef USE_BUFFER_HUB_AS_BUFFER_QUEUE -#define USE_BUFFER_HUB_AS_BUFFER_QUEUE 0 -#endif - namespace android { namespace { @@ -77,7 +73,6 @@ namespace { // Enums to control which IGraphicBufferProducer backend to test. enum IGraphicBufferProducerTestCode { USE_BUFFER_QUEUE_PRODUCER = 0, - USE_BUFFER_HUB_PRODUCER, }; }; // namespace anonymous @@ -99,10 +94,6 @@ protected: BufferQueue::createBufferQueue(&mProducer, &mConsumer); break; } - case USE_BUFFER_HUB_PRODUCER: { - BufferQueue::createBufferHubQueue(&mProducer, &mConsumer); - break; - } default: { // Should never reach here. LOG_ALWAYS_FATAL("Invalid test params: %u", GetParam()); @@ -880,11 +871,6 @@ TEST_P(IGraphicBufferProducerTest, SetMaxDequeuedBufferCount_Fails) { } TEST_P(IGraphicBufferProducerTest, SetAsyncMode_Succeeds) { - if (GetParam() == USE_BUFFER_HUB_PRODUCER) { - // TODO(b/36724099): Add support for BufferHubProducer::setAsyncMode(true) - return; - } - ASSERT_OK(mConsumer->setMaxAcquiredBufferCount(1)) << "maxAcquire: " << 1; ASSERT_NO_FATAL_FAILURE(ConnectProducer()); ASSERT_OK(mProducer->setAsyncMode(true)) << "async mode: " << true; @@ -1117,14 +1103,7 @@ TEST_P(IGraphicBufferProducerTest, DetachThenAttach_Succeeds) { } } -#if USE_BUFFER_HUB_AS_BUFFER_QUEUE -INSTANTIATE_TEST_CASE_P(IGraphicBufferProducerBackends, IGraphicBufferProducerTest, - ::testing::Values(USE_BUFFER_QUEUE_PRODUCER, USE_BUFFER_HUB_PRODUCER)); -#else -// TODO(b/70046255): Remove the #ifdef here and always tests both backends once BufferHubQueue can -// pass all existing libgui tests. INSTANTIATE_TEST_CASE_P(IGraphicBufferProducerBackends, IGraphicBufferProducerTest, ::testing::Values(USE_BUFFER_QUEUE_PRODUCER)); -#endif } // namespace android diff --git a/libs/gui/tests/SurfaceParcelable_test.cpp b/libs/gui/tests/SurfaceParcelable_test.cpp deleted file mode 100644 index 686dc82f3e..0000000000 --- a/libs/gui/tests/SurfaceParcelable_test.cpp +++ /dev/null @@ -1,168 +0,0 @@ -/* - * Copyright (C) 2018 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. - */ - -#define LOG_TAG "SurfaceParcelable_test" - -#include <gtest/gtest.h> - -#include <binder/IServiceManager.h> -#include <binder/ProcessState.h> -#include <gui/BufferHubProducer.h> -#include <gui/BufferQueue.h> -#include <gui/view/Surface.h> -#include <utils/Log.h> - -namespace android { - -static const String16 kTestServiceName = String16("SurfaceParcelableTestService"); -static const String16 kSurfaceName = String16("TEST_SURFACE"); -static const uint32_t kBufferWidth = 100; -static const uint32_t kBufferHeight = 1; -static const uint32_t kBufferFormat = HAL_PIXEL_FORMAT_BLOB; - -enum SurfaceParcelableTestServiceCode { - CREATE_BUFFER_QUEUE_SURFACE = IBinder::FIRST_CALL_TRANSACTION, - CREATE_BUFFER_HUB_SURFACE, -}; - -class SurfaceParcelableTestService : public BBinder { -public: - SurfaceParcelableTestService() { - // BufferQueue - BufferQueue::createBufferQueue(&mBufferQueueProducer, &mBufferQueueConsumer); - - // BufferHub - dvr::ProducerQueueConfigBuilder configBuilder; - mProducerQueue = dvr::ProducerQueue::Create(configBuilder.SetDefaultWidth(kBufferWidth) - .SetDefaultHeight(kBufferHeight) - .SetDefaultFormat(kBufferFormat) - .Build(), - dvr::UsagePolicy{}); - mBufferHubProducer = BufferHubProducer::Create(mProducerQueue); - } - - ~SurfaceParcelableTestService() = default; - - virtual status_t onTransact(uint32_t code, const Parcel& /*data*/, Parcel* reply, - uint32_t /*flags*/ = 0) { - switch (code) { - case CREATE_BUFFER_QUEUE_SURFACE: { - view::Surface surfaceShim; - surfaceShim.name = kSurfaceName; - surfaceShim.graphicBufferProducer = mBufferQueueProducer; - return surfaceShim.writeToParcel(reply); - } - case CREATE_BUFFER_HUB_SURFACE: { - view::Surface surfaceShim; - surfaceShim.name = kSurfaceName; - surfaceShim.graphicBufferProducer = mBufferHubProducer; - return surfaceShim.writeToParcel(reply); - } - default: - return UNKNOWN_TRANSACTION; - }; - } - -protected: - sp<IGraphicBufferProducer> mBufferQueueProducer; - sp<IGraphicBufferConsumer> mBufferQueueConsumer; - - std::shared_ptr<dvr::ProducerQueue> mProducerQueue; - sp<IGraphicBufferProducer> mBufferHubProducer; -}; - -static int runBinderServer() { - ProcessState::self()->startThreadPool(); - - sp<IServiceManager> sm = defaultServiceManager(); - sp<SurfaceParcelableTestService> service = new SurfaceParcelableTestService; - sm->addService(kTestServiceName, service, false); - - ALOGI("Binder server running..."); - - while (true) { - int stat, retval; - retval = wait(&stat); - if (retval == -1 && errno == ECHILD) { - break; - } - } - - ALOGI("Binder server exiting..."); - return 0; -} - -class SurfaceParcelableTest : public ::testing::TestWithParam<uint32_t> { -protected: - virtual void SetUp() { - mService = defaultServiceManager()->getService(kTestServiceName); - if (mService == nullptr) { - ALOGE("Failed to connect to the test service."); - return; - } - - ALOGI("Binder service is ready for client."); - } - - status_t GetSurface(view::Surface* surfaceShim) { - ALOGI("...Test: %d", GetParam()); - - uint32_t opCode = GetParam(); - Parcel data; - Parcel reply; - status_t error = mService->transact(opCode, data, &reply); - if (error != NO_ERROR) { - ALOGE("Failed to get surface over binder, error=%d.", error); - return error; - } - - error = surfaceShim->readFromParcel(&reply); - if (error != NO_ERROR) { - ALOGE("Failed to get surface from parcel, error=%d.", error); - return error; - } - - return NO_ERROR; - } - -private: - sp<IBinder> mService; -}; - -TEST_P(SurfaceParcelableTest, SendOverBinder) { - view::Surface surfaceShim; - EXPECT_EQ(GetSurface(&surfaceShim), NO_ERROR); - EXPECT_EQ(surfaceShim.name, kSurfaceName); - EXPECT_FALSE(surfaceShim.graphicBufferProducer == nullptr); -} - -INSTANTIATE_TEST_CASE_P(SurfaceBackends, SurfaceParcelableTest, - ::testing::Values(CREATE_BUFFER_QUEUE_SURFACE, CREATE_BUFFER_HUB_SURFACE)); - -} // namespace android - -int main(int argc, char** argv) { - pid_t pid = fork(); - if (pid == 0) { - android::ProcessState::self()->startThreadPool(); - ::testing::InitGoogleTest(&argc, argv); - return RUN_ALL_TESTS(); - - } else { - ALOGI("Test process pid: %d.", pid); - return android::runBinderServer(); - } -} diff --git a/libs/vr/libbufferhubqueue/benchmarks/Android.bp b/libs/vr/libbufferhubqueue/benchmarks/Android.bp deleted file mode 100644 index e33e03b37b..0000000000 --- a/libs/vr/libbufferhubqueue/benchmarks/Android.bp +++ /dev/null @@ -1,35 +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_benchmark { - srcs: ["buffer_transport_benchmark.cpp"], - shared_libs: [ - "libbase", - "libbinder", - "libcutils", - "libdvr.google", - "libgui", - "liblog", - "libhardware", - "libui", - "libutils", - "libnativewindow", - "libbufferhubqueue", - "libpdx_default_transport", - ], - cflags: [ - "-DLOG_TAG=\"buffer_transport_benchmark\"", - "-DTRACE=0", - "-O2", - "-Wall", - "-Werror", - ], - name: "buffer_transport_benchmark", -} diff --git a/libs/vr/libbufferhubqueue/benchmarks/buffer_transport_benchmark.cpp b/libs/vr/libbufferhubqueue/benchmarks/buffer_transport_benchmark.cpp deleted file mode 100644 index b6813eb51d..0000000000 --- a/libs/vr/libbufferhubqueue/benchmarks/buffer_transport_benchmark.cpp +++ /dev/null @@ -1,589 +0,0 @@ -#include <android-base/logging.h> -#include <android/native_window.h> -#include <benchmark/benchmark.h> -#include <binder/IPCThreadState.h> -#include <binder/IServiceManager.h> -#include <dvr/dvr_api.h> -#include <gui/BufferItem.h> -#include <gui/BufferItemConsumer.h> -#include <gui/Surface.h> -#include <private/dvr/epoll_file_descriptor.h> -#include <utils/Trace.h> - -#include <chrono> -#include <functional> -#include <iostream> -#include <thread> -#include <vector> - -#include <dlfcn.h> -#include <poll.h> -#include <sys/epoll.h> -#include <sys/wait.h> - -// Use ALWAYS at the tag level. Control is performed manually during command -// line processing. -#ifdef ATRACE_TAG -#undef ATRACE_TAG -#endif -#define ATRACE_TAG ATRACE_TAG_ALWAYS - -using namespace android; -using ::benchmark::State; - -static const String16 kBinderService = String16("bufferTransport"); -static const uint32_t kBufferWidth = 100; -static const uint32_t kBufferHeight = 1; -static const uint32_t kBufferFormat = HAL_PIXEL_FORMAT_BLOB; -static const uint64_t kBufferUsage = - GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN; -static const uint32_t kBufferLayer = 1; -static const int kMaxAcquiredImages = 1; -static const int kQueueDepth = 2; // We are double buffering for this test. -static const size_t kMaxQueueCounts = 128; -static const int kInvalidFence = -1; - -enum BufferTransportServiceCode { - CREATE_BUFFER_QUEUE = IBinder::FIRST_CALL_TRANSACTION, -}; - -// A binder services that minics a compositor that consumes buffers. It provides -// one Binder interface to create a new Surface for buffer producer to write -// into; while itself will carry out no-op buffer consuming by acquiring then -// releasing the buffer immediately. -class BufferTransportService : public BBinder { - public: - BufferTransportService() = default; - ~BufferTransportService() = default; - - virtual status_t onTransact(uint32_t code, const Parcel& data, Parcel* reply, - uint32_t flags = 0) { - (void)flags; - (void)data; - switch (code) { - case CREATE_BUFFER_QUEUE: { - auto new_queue = std::make_shared<BufferQueueHolder>(this); - reply->writeStrongBinder( - IGraphicBufferProducer::asBinder(new_queue->producer)); - buffer_queues_.push_back(new_queue); - return OK; - } - default: - return UNKNOWN_TRANSACTION; - }; - } - - private: - struct FrameListener : public ConsumerBase::FrameAvailableListener { - public: - FrameListener(BufferTransportService* /*service*/, - sp<BufferItemConsumer> buffer_item_consumer) - : buffer_item_consumer_(buffer_item_consumer) {} - - void onFrameAvailable(const BufferItem& /*item*/) override { - BufferItem buffer; - status_t ret = 0; - { - ATRACE_NAME("AcquireBuffer"); - ret = buffer_item_consumer_->acquireBuffer(&buffer, /*presentWhen=*/0, - /*waitForFence=*/false); - } - - if (ret != OK) { - LOG(ERROR) << "Failed to acquire next buffer."; - return; - } - - { - ATRACE_NAME("ReleaseBuffer"); - ret = buffer_item_consumer_->releaseBuffer(buffer); - } - - if (ret != OK) { - LOG(ERROR) << "Failed to release buffer."; - return; - } - } - - private: - sp<BufferItemConsumer> buffer_item_consumer_; - }; - - struct BufferQueueHolder { - explicit BufferQueueHolder(BufferTransportService* service) { - BufferQueue::createBufferQueue(&producer, &consumer); - - sp<BufferItemConsumer> buffer_item_consumer = - new BufferItemConsumer(consumer, kBufferUsage, kMaxAcquiredImages, - /*controlledByApp=*/true); - buffer_item_consumer->setName(String8("BinderBufferTransport")); - frame_listener_ = new FrameListener(service, buffer_item_consumer); - buffer_item_consumer->setFrameAvailableListener(frame_listener_); - } - - sp<IGraphicBufferProducer> producer; - sp<IGraphicBufferConsumer> consumer; - - private: - sp<FrameListener> frame_listener_; - }; - - std::vector<std::shared_ptr<BufferQueueHolder>> buffer_queues_; -}; - -// A virtual interfaces that abstracts the common BufferQueue operations, so -// that the test suite can use the same test case to drive different types of -// transport backends. -class BufferTransport { - public: - virtual ~BufferTransport() {} - - virtual int Start() = 0; - virtual sp<Surface> CreateSurface() = 0; -}; - -// Binder-based buffer transport backend. -// -// On Start() a new process will be swapned to run a Binder server that -// actually consumes the buffer. -// On CreateSurface() a new Binder BufferQueue will be created, which the -// service holds the concrete binder node of the IGraphicBufferProducer while -// sending the binder proxy to the client. In another word, the producer side -// operations are carried out process while the consumer side operations are -// carried out within the BufferTransportService's own process. -class BinderBufferTransport : public BufferTransport { - public: - BinderBufferTransport() {} - - int Start() override { - sp<IServiceManager> sm = defaultServiceManager(); - service_ = sm->getService(kBinderService); - if (service_ == nullptr) { - LOG(ERROR) << "Failed to get the benchmark service."; - return -EIO; - } - - LOG(INFO) << "Binder server is ready for client."; - return 0; - } - - sp<Surface> CreateSurface() override { - Parcel data; - Parcel reply; - int error = service_->transact(CREATE_BUFFER_QUEUE, data, &reply); - if (error != OK) { - LOG(ERROR) << "Failed to get buffer queue over binder."; - return nullptr; - } - - sp<IBinder> binder; - error = reply.readNullableStrongBinder(&binder); - if (error != OK) { - LOG(ERROR) << "Failed to get IGraphicBufferProducer over binder."; - return nullptr; - } - - auto producer = interface_cast<IGraphicBufferProducer>(binder); - if (producer == nullptr) { - LOG(ERROR) << "Failed to get IGraphicBufferProducer over binder."; - return nullptr; - } - - sp<Surface> surface = new Surface(producer, /*controlledByApp=*/true); - - // Set buffer dimension. - ANativeWindow* window = static_cast<ANativeWindow*>(surface.get()); - ANativeWindow_setBuffersGeometry(window, kBufferWidth, kBufferHeight, - kBufferFormat); - - return surface; - } - - private: - sp<IBinder> service_; -}; - -class DvrApi { - public: - DvrApi() { - handle_ = dlopen("libdvr.google.so", RTLD_NOW | RTLD_LOCAL); - CHECK(handle_); - - auto dvr_get_api = - reinterpret_cast<decltype(&dvrGetApi)>(dlsym(handle_, "dvrGetApi")); - int ret = dvr_get_api(&api_, sizeof(api_), /*version=*/1); - - CHECK(ret == 0); - } - - ~DvrApi() { dlclose(handle_); } - - const DvrApi_v1& Api() { return api_; } - - private: - void* handle_ = nullptr; - DvrApi_v1 api_; -}; - -// BufferHub/PDX-based buffer transport. -// -// On Start() a new thread will be swapned to run an epoll polling thread which -// minics the behavior of a compositor. Similar to Binder-based backend, the -// buffer available handler is also a no-op: Buffer gets acquired and released -// immediately. -// On CreateSurface() a pair of dvr::ProducerQueue and dvr::ConsumerQueue will -// be created. The epoll thread holds on the consumer queue and dequeues buffer -// from it; while the producer queue will be wrapped in a Surface and returned -// to test suite. -class BufferHubTransport : public BufferTransport { - public: - virtual ~BufferHubTransport() { - stopped_.store(true); - if (reader_thread_.joinable()) { - reader_thread_.join(); - } - } - - int Start() override { - int ret = epoll_fd_.Create(); - if (ret < 0) { - LOG(ERROR) << "Failed to create epoll fd: %s", strerror(-ret); - return -1; - } - - // Create the reader thread. - reader_thread_ = std::thread([this]() { - int ret = dvr_.Api().PerformanceSetSchedulerPolicy(0, "graphics"); - if (ret < 0) { - LOG(ERROR) << "Failed to set scheduler policy, ret=" << ret; - return; - } - - stopped_.store(false); - LOG(INFO) << "Reader Thread Running..."; - - while (!stopped_.load()) { - std::array<epoll_event, kMaxQueueCounts> events; - - // Don't sleep forever so that we will have a chance to wake up. - const int ret = epoll_fd_.Wait(events.data(), events.size(), - /*timeout=*/100); - if (ret < 0) { - LOG(ERROR) << "Error polling consumer queues."; - continue; - } - if (ret == 0) { - continue; - } - - const int num_events = ret; - for (int i = 0; i < num_events; i++) { - uint32_t index = events[i].data.u32; - dvr_.Api().ReadBufferQueueHandleEvents( - buffer_queues_[index]->GetReadQueue()); - } - } - - LOG(INFO) << "Reader Thread Exiting..."; - }); - - return 0; - } - - sp<Surface> CreateSurface() override { - auto new_queue = std::make_shared<BufferQueueHolder>(); - if (!new_queue->IsReady()) { - LOG(ERROR) << "Failed to create BufferHub-based BufferQueue."; - return nullptr; - } - - // Set buffer dimension. - ANativeWindow_setBuffersGeometry(new_queue->GetSurface(), kBufferWidth, - kBufferHeight, kBufferFormat); - - // Use the next position as buffer_queue index. - uint32_t index = buffer_queues_.size(); - epoll_event event = {.events = EPOLLIN | EPOLLET, .data = {.u32 = index}}; - int queue_fd = - dvr_.Api().ReadBufferQueueGetEventFd(new_queue->GetReadQueue()); - const int ret = epoll_fd_.Control(EPOLL_CTL_ADD, queue_fd, &event); - if (ret < 0) { - LOG(ERROR) << "Failed to track consumer queue: " << strerror(-ret) - << ", consumer queue fd: " << queue_fd; - return nullptr; - } - - buffer_queues_.push_back(new_queue); - ANativeWindow_acquire(new_queue->GetSurface()); - return static_cast<Surface*>(new_queue->GetSurface()); - } - - private: - struct BufferQueueHolder { - BufferQueueHolder() { - int ret = 0; - ret = dvr_.Api().WriteBufferQueueCreate( - kBufferWidth, kBufferHeight, kBufferFormat, kBufferLayer, - kBufferUsage, 0, sizeof(DvrNativeBufferMetadata), &write_queue_); - if (ret < 0) { - LOG(ERROR) << "Failed to create write buffer queue, ret=" << ret; - return; - } - - ret = dvr_.Api().WriteBufferQueueCreateReadQueue(write_queue_, - &read_queue_); - if (ret < 0) { - LOG(ERROR) << "Failed to create read buffer queue, ret=" << ret; - return; - } - - ret = dvr_.Api().ReadBufferQueueSetBufferAvailableCallback( - read_queue_, BufferAvailableCallback, this); - if (ret < 0) { - LOG(ERROR) << "Failed to create buffer available callback, ret=" << ret; - return; - } - - ret = - dvr_.Api().WriteBufferQueueGetANativeWindow(write_queue_, &surface_); - if (ret < 0) { - LOG(ERROR) << "Failed to create surface, ret=" << ret; - return; - } - } - - static void BufferAvailableCallback(void* context) { - BufferQueueHolder* thiz = static_cast<BufferQueueHolder*>(context); - thiz->HandleBufferAvailable(); - } - - DvrReadBufferQueue* GetReadQueue() { return read_queue_; } - - ANativeWindow* GetSurface() { return surface_; } - - bool IsReady() { - return write_queue_ != nullptr && read_queue_ != nullptr && - surface_ != nullptr; - } - - void HandleBufferAvailable() { - int ret = 0; - DvrNativeBufferMetadata meta; - DvrReadBuffer* buffer = nullptr; - DvrNativeBufferMetadata metadata; - int acquire_fence = kInvalidFence; - - { - ATRACE_NAME("AcquireBuffer"); - ret = dvr_.Api().ReadBufferQueueAcquireBuffer( - read_queue_, 0, &buffer, &metadata, &acquire_fence); - } - if (ret < 0) { - LOG(ERROR) << "Failed to acquire consumer buffer, error: " << ret; - return; - } - - if (buffer != nullptr) { - ATRACE_NAME("ReleaseBuffer"); - ret = dvr_.Api().ReadBufferQueueReleaseBuffer(read_queue_, buffer, - &meta, kInvalidFence); - } - if (ret < 0) { - LOG(ERROR) << "Failed to release consumer buffer, error: " << ret; - } - } - - private: - DvrWriteBufferQueue* write_queue_ = nullptr; - DvrReadBufferQueue* read_queue_ = nullptr; - ANativeWindow* surface_ = nullptr; - }; - - static DvrApi dvr_; - std::atomic<bool> stopped_; - std::thread reader_thread_; - - dvr::EpollFileDescriptor epoll_fd_; - std::vector<std::shared_ptr<BufferQueueHolder>> buffer_queues_; -}; - -DvrApi BufferHubTransport::dvr_ = {}; - -enum TransportType { - kBinderBufferTransport, - kBufferHubTransport, -}; - -// Main test suite, which supports two transport backend: 1) BinderBufferQueue, -// 2) BufferHubQueue. The test case drives the producer end of both transport -// backend by queuing buffers into the buffer queue by using ANativeWindow API. -class BufferTransportBenchmark : public ::benchmark::Fixture { - public: - void SetUp(State& state) override { - if (state.thread_index == 0) { - const int transport = state.range(0); - switch (transport) { - case kBinderBufferTransport: - transport_.reset(new BinderBufferTransport); - break; - case kBufferHubTransport: - transport_.reset(new BufferHubTransport); - break; - default: - CHECK(false) << "Unknown test case."; - break; - } - - CHECK(transport_); - const int ret = transport_->Start(); - CHECK_EQ(ret, 0); - - LOG(INFO) << "Transport backend running, transport=" << transport << "."; - - // Create surfaces for each thread. - surfaces_.resize(state.threads); - for (int i = 0; i < state.threads; i++) { - // Common setup every thread needs. - surfaces_[i] = transport_->CreateSurface(); - CHECK(surfaces_[i]); - - LOG(INFO) << "Surface initialized on thread " << i << "."; - } - } - } - - void TearDown(State& state) override { - if (state.thread_index == 0) { - surfaces_.clear(); - transport_.reset(); - LOG(INFO) << "Tear down benchmark."; - } - } - - protected: - std::unique_ptr<BufferTransport> transport_; - std::vector<sp<Surface>> surfaces_; -}; - -BENCHMARK_DEFINE_F(BufferTransportBenchmark, Producers)(State& state) { - ANativeWindow* window = nullptr; - ANativeWindow_Buffer buffer; - int32_t error = 0; - double total_gain_buffer_us = 0; - double total_post_buffer_us = 0; - int iterations = 0; - - while (state.KeepRunning()) { - if (window == nullptr) { - CHECK(surfaces_[state.thread_index]); - window = static_cast<ANativeWindow*>(surfaces_[state.thread_index].get()); - - // Lock buffers a couple time from the queue, so that we have the buffer - // allocated. - for (int i = 0; i < kQueueDepth; i++) { - error = ANativeWindow_lock(window, &buffer, - /*inOutDirtyBounds=*/nullptr); - CHECK_EQ(error, 0); - error = ANativeWindow_unlockAndPost(window); - CHECK_EQ(error, 0); - } - } - - { - ATRACE_NAME("GainBuffer"); - auto t1 = std::chrono::high_resolution_clock::now(); - error = ANativeWindow_lock(window, &buffer, - /*inOutDirtyBounds=*/nullptr); - auto t2 = std::chrono::high_resolution_clock::now(); - std::chrono::duration<double, std::micro> delta_us = t2 - t1; - total_gain_buffer_us += delta_us.count(); - } - CHECK_EQ(error, 0); - - { - ATRACE_NAME("PostBuffer"); - auto t1 = std::chrono::high_resolution_clock::now(); - error = ANativeWindow_unlockAndPost(window); - auto t2 = std::chrono::high_resolution_clock::now(); - std::chrono::duration<double, std::micro> delta_us = t2 - t1; - total_post_buffer_us += delta_us.count(); - } - CHECK_EQ(error, 0); - - iterations++; - } - - state.counters["gain_buffer_us"] = ::benchmark::Counter( - total_gain_buffer_us / iterations, ::benchmark::Counter::kAvgThreads); - state.counters["post_buffer_us"] = ::benchmark::Counter( - total_post_buffer_us / iterations, ::benchmark::Counter::kAvgThreads); - state.counters["producer_us"] = ::benchmark::Counter( - (total_gain_buffer_us + total_post_buffer_us) / iterations, - ::benchmark::Counter::kAvgThreads); -} - -BENCHMARK_REGISTER_F(BufferTransportBenchmark, Producers) - ->Unit(::benchmark::kMicrosecond) - ->Ranges({{kBinderBufferTransport, kBufferHubTransport}}) - ->ThreadRange(1, 32); - -static void runBinderServer() { - ProcessState::self()->setThreadPoolMaxThreadCount(0); - ProcessState::self()->startThreadPool(); - - sp<IServiceManager> sm = defaultServiceManager(); - sp<BufferTransportService> service = new BufferTransportService; - sm->addService(kBinderService, service, false); - - LOG(INFO) << "Binder server running..."; - - while (true) { - int stat, retval; - retval = wait(&stat); - if (retval == -1 && errno == ECHILD) { - break; - } - } - - LOG(INFO) << "Service Exiting..."; -} - -// To run binder-based benchmark, use: -// adb shell buffer_transport_benchmark \ -// --benchmark_filter="BufferTransportBenchmark/ContinuousLoad/0/" -// -// To run bufferhub-based benchmark, use: -// adb shell buffer_transport_benchmark \ -// --benchmark_filter="BufferTransportBenchmark/ContinuousLoad/1/" -int main(int argc, char** argv) { - bool tracing_enabled = false; - - // Parse arguments in addition to "--benchmark_filter" paramters. - for (int i = 1; i < argc; i++) { - if (std::string(argv[i]) == "--help") { - std::cout << "Usage: binderThroughputTest [OPTIONS]" << std::endl; - std::cout << "\t--trace: Enable systrace logging." << std::endl; - return 0; - } - if (std::string(argv[i]) == "--trace") { - tracing_enabled = true; - continue; - } - } - - // Setup ATRACE/systrace based on command line. - atrace_setup(); - atrace_set_tracing_enabled(tracing_enabled); - - pid_t pid = fork(); - if (pid == 0) { - // Child, i.e. the client side. - ProcessState::self()->startThreadPool(); - - ::benchmark::Initialize(&argc, argv); - ::benchmark::RunSpecifiedBenchmarks(); - } else { - LOG(INFO) << "Benchmark process pid: " << pid; - runBinderServer(); - } -} diff --git a/libs/vr/libbufferhubqueue/tests/Android.bp b/libs/vr/libbufferhubqueue/tests/Android.bp index 33a0d754c1..e373376ab9 100644 --- a/libs/vr/libbufferhubqueue/tests/Android.bp +++ b/libs/vr/libbufferhubqueue/tests/Android.bp @@ -48,19 +48,3 @@ cc_test { ], name: "buffer_hub_queue-test", } - -cc_test { - srcs: ["buffer_hub_queue_producer-test.cpp"], - header_libs: header_libraries, - static_libs: static_libraries, - shared_libs: shared_libraries, - cflags: [ - "-DLOG_TAG=\"buffer_hub_queue_producer-test\"", - "-DTRACE=0", - "-O0", - "-g", - "-Wall", - "-Werror", - ], - name: "buffer_hub_queue_producer-test", -} diff --git a/libs/vr/libbufferhubqueue/tests/buffer_hub_queue_producer-test.cpp b/libs/vr/libbufferhubqueue/tests/buffer_hub_queue_producer-test.cpp deleted file mode 100644 index fab10978d6..0000000000 --- a/libs/vr/libbufferhubqueue/tests/buffer_hub_queue_producer-test.cpp +++ /dev/null @@ -1,603 +0,0 @@ -#include <base/logging.h> -#include <gui/BufferHubProducer.h> -#include <gui/IProducerListener.h> -#include <gui/Surface.h> -#include <pdx/default_transport/channel_parcelable.h> - -#include <gtest/gtest.h> - -namespace android { -namespace dvr { - -using pdx::LocalHandle; - -namespace { - -// Default dimensions before setDefaultBufferSize is called by the consumer. -constexpr uint32_t kDefaultWidth = 1; -constexpr uint32_t kDefaultHeight = 1; - -// Default format before setDefaultBufferFormat is called by the consumer. -constexpr PixelFormat kDefaultFormat = HAL_PIXEL_FORMAT_RGBA_8888; -constexpr int kDefaultConsumerUsageBits = 0; - -// Default transform hint before setTransformHint is called by the consumer. -constexpr uint32_t kDefaultTransformHint = 0; - -constexpr int kTestApi = NATIVE_WINDOW_API_CPU; -constexpr int kTestApiOther = NATIVE_WINDOW_API_EGL; -constexpr int kTestApiInvalid = 0xDEADBEEF; -constexpr int kTestProducerUsageBits = 0; -constexpr bool kTestControlledByApp = true; - -// Builder pattern to slightly vary *almost* correct input -// -- avoids copying and pasting -struct QueueBufferInputBuilder { - IGraphicBufferProducer::QueueBufferInput build() { - return IGraphicBufferProducer::QueueBufferInput( - mTimestamp, mIsAutoTimestamp, mDataSpace, mCrop, mScalingMode, - mTransform, mFence); - } - - QueueBufferInputBuilder& setTimestamp(int64_t timestamp) { - this->mTimestamp = timestamp; - return *this; - } - - QueueBufferInputBuilder& setIsAutoTimestamp(bool isAutoTimestamp) { - this->mIsAutoTimestamp = isAutoTimestamp; - return *this; - } - - QueueBufferInputBuilder& setDataSpace(android_dataspace dataSpace) { - this->mDataSpace = dataSpace; - return *this; - } - - QueueBufferInputBuilder& setCrop(Rect crop) { - this->mCrop = crop; - return *this; - } - - QueueBufferInputBuilder& setScalingMode(int scalingMode) { - this->mScalingMode = scalingMode; - return *this; - } - - QueueBufferInputBuilder& setTransform(uint32_t transform) { - this->mTransform = transform; - return *this; - } - - QueueBufferInputBuilder& setFence(sp<Fence> fence) { - this->mFence = fence; - return *this; - } - - private: - int64_t mTimestamp{1384888611}; - bool mIsAutoTimestamp{false}; - android_dataspace mDataSpace{HAL_DATASPACE_UNKNOWN}; - Rect mCrop{Rect(kDefaultWidth, kDefaultHeight)}; - int mScalingMode{0}; - uint32_t mTransform{0}; - sp<Fence> mFence{Fence::NO_FENCE}; -}; - -// This is a test that covers our implementation of bufferhubqueue-based -// IGraphicBufferProducer. -class BufferHubQueueProducerTest : public ::testing::Test { - protected: - virtual void SetUp() { - const ::testing::TestInfo* const testInfo = - ::testing::UnitTest::GetInstance()->current_test_info(); - ALOGD_IF(TRACE, "Begin test: %s.%s", testInfo->test_case_name(), - testInfo->name()); - - auto config = ProducerQueueConfigBuilder().Build(); - auto queue = ProducerQueue::Create(config, UsagePolicy{}); - ASSERT_TRUE(queue != nullptr); - - mProducer = BufferHubProducer::Create(std::move(queue)); - ASSERT_TRUE(mProducer != nullptr); - mSurface = new Surface(mProducer, true); - ASSERT_TRUE(mSurface != nullptr); - } - - // Connect to a producer in a 'correct' fashion. - void ConnectProducer() { - IGraphicBufferProducer::QueueBufferOutput output; - // Can connect the first time. - ASSERT_EQ(OK, mProducer->connect(kStubListener, kTestApi, - kTestControlledByApp, &output)); - } - - // Dequeue a buffer in a 'correct' fashion. - // Precondition: Producer is connected. - void DequeueBuffer(int* outSlot) { - sp<Fence> fence; - ASSERT_NO_FATAL_FAILURE(DequeueBuffer(outSlot, &fence)); - } - - void DequeueBuffer(int* outSlot, sp<Fence>* outFence) { - ASSERT_NE(nullptr, outSlot); - ASSERT_NE(nullptr, outFence); - - int ret = mProducer->dequeueBuffer( - outSlot, outFence, kDefaultWidth, kDefaultHeight, kDefaultFormat, - kTestProducerUsageBits, nullptr, nullptr); - // BUFFER_NEEDS_REALLOCATION can be either on or off. - ASSERT_EQ(0, ~IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION & ret); - - // Slot number should be in boundary. - ASSERT_LE(0, *outSlot); - ASSERT_GT(BufferQueueDefs::NUM_BUFFER_SLOTS, *outSlot); - } - - // Create a generic "valid" input for queueBuffer - // -- uses the default buffer format, width, etc. - static IGraphicBufferProducer::QueueBufferInput CreateBufferInput() { - return QueueBufferInputBuilder().build(); - } - - const sp<IProducerListener> kStubListener{new StubProducerListener}; - - sp<BufferHubProducer> mProducer; - sp<Surface> mSurface; -}; - -TEST_F(BufferHubQueueProducerTest, ConnectFirst_ReturnsError) { - IGraphicBufferProducer::QueueBufferOutput output; - - // NULL output returns BAD_VALUE - EXPECT_EQ(BAD_VALUE, mProducer->connect(kStubListener, kTestApi, - kTestControlledByApp, nullptr)); - - // Invalid API returns bad value - EXPECT_EQ(BAD_VALUE, mProducer->connect(kStubListener, kTestApiInvalid, - kTestControlledByApp, &output)); -} - -TEST_F(BufferHubQueueProducerTest, ConnectAgain_ReturnsError) { - ASSERT_NO_FATAL_FAILURE(ConnectProducer()); - - // Can't connect when there is already a producer connected. - IGraphicBufferProducer::QueueBufferOutput output; - EXPECT_EQ(BAD_VALUE, mProducer->connect(kStubListener, kTestApi, - kTestControlledByApp, &output)); -} - -TEST_F(BufferHubQueueProducerTest, Disconnect_Succeeds) { - ASSERT_NO_FATAL_FAILURE(ConnectProducer()); - - ASSERT_EQ(OK, mProducer->disconnect(kTestApi)); -} - -TEST_F(BufferHubQueueProducerTest, Disconnect_ReturnsError) { - ASSERT_NO_FATAL_FAILURE(ConnectProducer()); - - // Must disconnect with same API number - EXPECT_EQ(BAD_VALUE, mProducer->disconnect(kTestApiOther)); - // API must not be out of range - EXPECT_EQ(BAD_VALUE, mProducer->disconnect(kTestApiInvalid)); -} - -TEST_F(BufferHubQueueProducerTest, Query_Succeeds) { - ASSERT_NO_FATAL_FAILURE(ConnectProducer()); - - int32_t value = -1; - EXPECT_EQ(OK, mProducer->query(NATIVE_WINDOW_WIDTH, &value)); - EXPECT_EQ(kDefaultWidth, static_cast<uint32_t>(value)); - - EXPECT_EQ(OK, mProducer->query(NATIVE_WINDOW_HEIGHT, &value)); - EXPECT_EQ(kDefaultHeight, static_cast<uint32_t>(value)); - - EXPECT_EQ(OK, mProducer->query(NATIVE_WINDOW_FORMAT, &value)); - EXPECT_EQ(kDefaultFormat, value); - - EXPECT_EQ(OK, mProducer->query(NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS, &value)); - EXPECT_LE(0, value); - EXPECT_GE(BufferQueueDefs::NUM_BUFFER_SLOTS, value); - - EXPECT_EQ(OK, - mProducer->query(NATIVE_WINDOW_CONSUMER_RUNNING_BEHIND, &value)); - EXPECT_FALSE(value); // Can't run behind when we haven't touched the queue - - EXPECT_EQ(OK, mProducer->query(NATIVE_WINDOW_CONSUMER_USAGE_BITS, &value)); - EXPECT_EQ(kDefaultConsumerUsageBits, value); -} - -TEST_F(BufferHubQueueProducerTest, Query_ReturnsError) { - ASSERT_NO_FATAL_FAILURE(ConnectProducer()); - - // One past the end of the last 'query' enum value. Update this if we add more - // enums. - const int NATIVE_WINDOW_QUERY_LAST_OFF_BY_ONE = NATIVE_WINDOW_BUFFER_AGE + 1; - - int value; - // What was out of range - EXPECT_EQ(BAD_VALUE, mProducer->query(/*what*/ -1, &value)); - EXPECT_EQ(BAD_VALUE, mProducer->query(/*what*/ 0xDEADBEEF, &value)); - EXPECT_EQ(BAD_VALUE, - mProducer->query(NATIVE_WINDOW_QUERY_LAST_OFF_BY_ONE, &value)); - - // Some enums from window.h are 'invalid' - EXPECT_EQ(BAD_VALUE, - mProducer->query(NATIVE_WINDOW_QUEUES_TO_WINDOW_COMPOSER, &value)); - EXPECT_EQ(BAD_VALUE, mProducer->query(NATIVE_WINDOW_CONCRETE_TYPE, &value)); - EXPECT_EQ(BAD_VALUE, mProducer->query(NATIVE_WINDOW_DEFAULT_WIDTH, &value)); - EXPECT_EQ(BAD_VALUE, mProducer->query(NATIVE_WINDOW_DEFAULT_HEIGHT, &value)); - EXPECT_EQ(BAD_VALUE, mProducer->query(NATIVE_WINDOW_TRANSFORM_HINT, &value)); - - // Value was NULL - EXPECT_EQ(BAD_VALUE, mProducer->query(NATIVE_WINDOW_FORMAT, /*value*/ NULL)); -} - -TEST_F(BufferHubQueueProducerTest, Queue_Succeeds) { - int slot = -1; - - ASSERT_NO_FATAL_FAILURE(ConnectProducer()); - ASSERT_NO_FATAL_FAILURE(DequeueBuffer(&slot)); - - // Request the buffer (pre-requisite for queueing) - sp<GraphicBuffer> buffer; - ASSERT_EQ(OK, mProducer->requestBuffer(slot, &buffer)); - - // A generic "valid" input - IGraphicBufferProducer::QueueBufferInput input = CreateBufferInput(); - IGraphicBufferProducer::QueueBufferOutput output; - - // Queue the buffer back into the BQ - ASSERT_EQ(OK, mProducer->queueBuffer(slot, input, &output)); - - EXPECT_EQ(kDefaultWidth, output.width); - EXPECT_EQ(kDefaultHeight, output.height); - EXPECT_EQ(kDefaultTransformHint, output.transformHint); - - // BufferHubQueue delivers buffers to consumer immediately. - EXPECT_EQ(0u, output.numPendingBuffers); - - // Note that BufferHubQueue doesn't support nextFrameNumber as it seems to - // be a SurfaceFlinger specific optimization. - EXPECT_EQ(0u, output.nextFrameNumber); - - // Buffer was not in the dequeued state - EXPECT_EQ(BAD_VALUE, mProducer->queueBuffer(slot, input, &output)); -} - -// Test invalid slot number -TEST_F(BufferHubQueueProducerTest, QueueInvalidSlot_ReturnsError) { - ASSERT_NO_FATAL_FAILURE(ConnectProducer()); - - // A generic "valid" input - IGraphicBufferProducer::QueueBufferInput input = CreateBufferInput(); - IGraphicBufferProducer::QueueBufferOutput output; - - EXPECT_EQ(BAD_VALUE, mProducer->queueBuffer(/*slot*/ -1, input, &output)); - EXPECT_EQ(BAD_VALUE, - mProducer->queueBuffer(/*slot*/ 0xDEADBEEF, input, &output)); - EXPECT_EQ(BAD_VALUE, mProducer->queueBuffer(BufferQueueDefs::NUM_BUFFER_SLOTS, - input, &output)); -} - -// Slot was not in the dequeued state (all slots start out in Free state) -TEST_F(BufferHubQueueProducerTest, QueueNotDequeued_ReturnsError) { - ASSERT_NO_FATAL_FAILURE(ConnectProducer()); - - IGraphicBufferProducer::QueueBufferInput input = CreateBufferInput(); - IGraphicBufferProducer::QueueBufferOutput output; - - EXPECT_EQ(BAD_VALUE, mProducer->queueBuffer(/*slot*/ 0, input, &output)); -} - -// Slot was enqueued without requesting a buffer -TEST_F(BufferHubQueueProducerTest, QueueNotRequested_ReturnsError) { - int slot = -1; - - ASSERT_NO_FATAL_FAILURE(ConnectProducer()); - ASSERT_NO_FATAL_FAILURE(DequeueBuffer(&slot)); - - IGraphicBufferProducer::QueueBufferInput input = CreateBufferInput(); - IGraphicBufferProducer::QueueBufferOutput output; - - EXPECT_EQ(BAD_VALUE, mProducer->queueBuffer(slot, input, &output)); -} - -// Test when fence was NULL -TEST_F(BufferHubQueueProducerTest, QueueNoFence_ReturnsError) { - int slot = -1; - - ASSERT_NO_FATAL_FAILURE(ConnectProducer()); - ASSERT_NO_FATAL_FAILURE(DequeueBuffer(&slot)); - - sp<GraphicBuffer> buffer; - ASSERT_EQ(OK, mProducer->requestBuffer(slot, &buffer)); - - sp<Fence> nullFence = NULL; - - IGraphicBufferProducer::QueueBufferInput input = - QueueBufferInputBuilder().setFence(nullFence).build(); - IGraphicBufferProducer::QueueBufferOutput output; - - EXPECT_EQ(BAD_VALUE, mProducer->queueBuffer(slot, input, &output)); -} - -// Test scaling mode was invalid -TEST_F(BufferHubQueueProducerTest, QueueTestInvalidScalingMode_ReturnsError) { - int slot = -1; - - ASSERT_NO_FATAL_FAILURE(ConnectProducer()); - ASSERT_NO_FATAL_FAILURE(DequeueBuffer(&slot)); - - sp<GraphicBuffer> buffer; - ASSERT_EQ(OK, mProducer->requestBuffer(slot, &buffer)); - - IGraphicBufferProducer::QueueBufferInput input = - QueueBufferInputBuilder().setScalingMode(-1).build(); - IGraphicBufferProducer::QueueBufferOutput output; - - EXPECT_EQ(BAD_VALUE, mProducer->queueBuffer(slot, input, &output)); - - input = QueueBufferInputBuilder().setScalingMode(0xDEADBEEF).build(); - - EXPECT_EQ(BAD_VALUE, mProducer->queueBuffer(slot, input, &output)); -} - -// Test crop rect is out of bounds of the buffer dimensions -TEST_F(BufferHubQueueProducerTest, QueueCropOutOfBounds_ReturnsError) { - int slot = -1; - - ASSERT_NO_FATAL_FAILURE(ConnectProducer()); - ASSERT_NO_FATAL_FAILURE(DequeueBuffer(&slot)); - - sp<GraphicBuffer> buffer; - ASSERT_EQ(OK, mProducer->requestBuffer(slot, &buffer)); - - IGraphicBufferProducer::QueueBufferInput input = - QueueBufferInputBuilder() - .setCrop(Rect(kDefaultWidth + 1, kDefaultHeight + 1)) - .build(); - IGraphicBufferProducer::QueueBufferOutput output; - - EXPECT_EQ(BAD_VALUE, mProducer->queueBuffer(slot, input, &output)); -} - -TEST_F(BufferHubQueueProducerTest, CancelBuffer_Succeeds) { - int slot = -1; - sp<Fence> fence; - - ASSERT_NO_FATAL_FAILURE(ConnectProducer()); - ASSERT_NO_FATAL_FAILURE(DequeueBuffer(&slot, &fence)); - - // Should be able to cancel buffer after a dequeue. - EXPECT_EQ(OK, mProducer->cancelBuffer(slot, fence)); -} - -TEST_F(BufferHubQueueProducerTest, SetMaxDequeuedBufferCount_Succeeds) { - return; - ASSERT_NO_FATAL_FAILURE(ConnectProducer()); - - int minUndequeuedBuffers; - ASSERT_EQ(OK, mProducer->query(NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS, - &minUndequeuedBuffers)); - - const int minBuffers = 1; - const int maxBuffers = - BufferQueueDefs::NUM_BUFFER_SLOTS - minUndequeuedBuffers; - - ASSERT_EQ(OK, mProducer->setAsyncMode(false)) << "async mode: " << false; - ASSERT_EQ(OK, mProducer->setMaxDequeuedBufferCount(minBuffers)) - << "bufferCount: " << minBuffers; - - // Should now be able to dequeue up to minBuffers times - // Should now be able to dequeue up to maxBuffers times - int slot = -1; - for (int i = 0; i < minBuffers; ++i) { - ASSERT_NO_FATAL_FAILURE(DequeueBuffer(&slot)); - } - - ASSERT_EQ(OK, mProducer->setMaxDequeuedBufferCount(maxBuffers)); - - // queue the first buffer to enable max dequeued buffer count checking - IGraphicBufferProducer::QueueBufferInput input = CreateBufferInput(); - IGraphicBufferProducer::QueueBufferOutput output; - sp<GraphicBuffer> buffer; - ASSERT_EQ(OK, mProducer->requestBuffer(slot, &buffer)); - ASSERT_EQ(OK, mProducer->queueBuffer(slot, input, &output)); - - sp<Fence> fence; - for (int i = 0; i < maxBuffers; ++i) { - ASSERT_NO_FATAL_FAILURE(DequeueBuffer(&slot, &fence)); - } - - // Cancel a buffer, so we can decrease the buffer count - ASSERT_EQ(OK, mProducer->cancelBuffer(slot, fence)); - - // Should now be able to decrease the max dequeued count by 1 - ASSERT_EQ(OK, mProducer->setMaxDequeuedBufferCount(maxBuffers - 1)); -} - -TEST_F(BufferHubQueueProducerTest, SetMaxDequeuedBufferCount_Fails) { - ASSERT_NO_FATAL_FAILURE(ConnectProducer()); - - int minUndequeuedBuffers; - ASSERT_EQ(OK, mProducer->query(NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS, - &minUndequeuedBuffers)); - - const int minBuffers = 1; - const int maxBuffers = - BufferQueueDefs::NUM_BUFFER_SLOTS - minUndequeuedBuffers; - - ASSERT_EQ(OK, mProducer->setAsyncMode(false)) << "async mode: " << false; - // Buffer count was out of range - EXPECT_EQ(BAD_VALUE, mProducer->setMaxDequeuedBufferCount(0)) - << "bufferCount: " << 0; - EXPECT_EQ(BAD_VALUE, mProducer->setMaxDequeuedBufferCount(maxBuffers + 1)) - << "bufferCount: " << maxBuffers + 1; - - // Set max dequeue count to 2 - ASSERT_EQ(OK, mProducer->setMaxDequeuedBufferCount(2)); - // Dequeue 2 buffers - int slot = -1; - sp<Fence> fence; - for (int i = 0; i < 2; i++) { - ASSERT_EQ(OK, ~IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION & - (mProducer->dequeueBuffer(&slot, &fence, kDefaultWidth, - kDefaultHeight, kDefaultFormat, - kTestProducerUsageBits, - nullptr, nullptr))) - << "slot: " << slot; - } - - // Client has too many buffers dequeued - EXPECT_EQ(BAD_VALUE, mProducer->setMaxDequeuedBufferCount(1)) - << "bufferCount: " << minBuffers; -} - -TEST_F(BufferHubQueueProducerTest, - DisconnectedProducerReturnsError_dequeueBuffer) { - int slot = -1; - sp<Fence> fence; - - ASSERT_EQ(NO_INIT, mProducer->dequeueBuffer(&slot, &fence, kDefaultWidth, - kDefaultHeight, kDefaultFormat, - kTestProducerUsageBits, - nullptr, nullptr)); -} - -TEST_F(BufferHubQueueProducerTest, - DisconnectedProducerReturnsError_requestBuffer) { - int slot = -1; - sp<GraphicBuffer> buffer; - - ASSERT_NO_FATAL_FAILURE(ConnectProducer()); - ASSERT_NO_FATAL_FAILURE(DequeueBuffer(&slot)); - - // Shouldn't be able to request buffer after disconnect. - ASSERT_EQ(OK, mProducer->disconnect(kTestApi)); - ASSERT_EQ(NO_INIT, mProducer->requestBuffer(slot, &buffer)); -} - -TEST_F(BufferHubQueueProducerTest, - DisconnectedProducerReturnsError_queueBuffer) { - int slot = -1; - sp<GraphicBuffer> buffer; - - ASSERT_NO_FATAL_FAILURE(ConnectProducer()); - ASSERT_NO_FATAL_FAILURE(DequeueBuffer(&slot)); - ASSERT_EQ(OK, mProducer->requestBuffer(slot, &buffer)); - - // A generic "valid" input - IGraphicBufferProducer::QueueBufferInput input = CreateBufferInput(); - IGraphicBufferProducer::QueueBufferOutput output; - - // Shouldn't be able to queue buffer after disconnect. - ASSERT_EQ(OK, mProducer->disconnect(kTestApi)); - ASSERT_EQ(NO_INIT, mProducer->queueBuffer(slot, input, &output)); -} - -TEST_F(BufferHubQueueProducerTest, - DisconnectedProducerReturnsError_cancelBuffer) { - int slot = -1; - sp<GraphicBuffer> buffer; - - ASSERT_NO_FATAL_FAILURE(ConnectProducer()); - ASSERT_NO_FATAL_FAILURE(DequeueBuffer(&slot)); - ASSERT_EQ(OK, mProducer->requestBuffer(slot, &buffer)); - - // Shouldn't be able to cancel buffer after disconnect. - ASSERT_EQ(OK, mProducer->disconnect(kTestApi)); - ASSERT_EQ(NO_INIT, mProducer->cancelBuffer(slot, Fence::NO_FENCE)); -} - -TEST_F(BufferHubQueueProducerTest, ConnectDisconnectReconnect) { - int slot = -1; - sp<GraphicBuffer> buffer; - IGraphicBufferProducer::QueueBufferInput input = CreateBufferInput(); - IGraphicBufferProducer::QueueBufferOutput output; - - EXPECT_NO_FATAL_FAILURE(ConnectProducer()); - - constexpr int maxDequeuedBuffers = 1; - int minUndequeuedBuffers; - EXPECT_EQ(OK, mProducer->query(NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS, - &minUndequeuedBuffers)); - EXPECT_EQ(OK, mProducer->setAsyncMode(false)); - EXPECT_EQ(OK, mProducer->setMaxDequeuedBufferCount(maxDequeuedBuffers)); - - int maxCapacity = maxDequeuedBuffers + minUndequeuedBuffers; - - // Dequeue, request, and queue all buffers. - for (int i = 0; i < maxCapacity; i++) { - EXPECT_NO_FATAL_FAILURE(DequeueBuffer(&slot)); - EXPECT_EQ(OK, mProducer->requestBuffer(slot, &buffer)); - EXPECT_EQ(OK, mProducer->queueBuffer(slot, input, &output)); - } - - // Disconnect then reconnect. - EXPECT_EQ(OK, mProducer->disconnect(kTestApi)); - EXPECT_NO_FATAL_FAILURE(ConnectProducer()); - - // Dequeue, request, and queue all buffers. - for (int i = 0; i < maxCapacity; i++) { - EXPECT_NO_FATAL_FAILURE(DequeueBuffer(&slot)); - EXPECT_EQ(OK, mProducer->requestBuffer(slot, &buffer)); - EXPECT_EQ(OK, mProducer->queueBuffer(slot, input, &output)); - } - - EXPECT_EQ(OK, mProducer->disconnect(kTestApi)); -} - -TEST_F(BufferHubQueueProducerTest, TakeAsParcelable) { - // Connected producer cannot be taken out as a parcelable. - EXPECT_NO_FATAL_FAILURE(ConnectProducer()); - ProducerQueueParcelable producer_parcelable; - EXPECT_EQ(mProducer->TakeAsParcelable(&producer_parcelable), BAD_VALUE); - - // Create a valid fake producer parcelable. - auto fake_channel_parcelable = - std::make_unique<pdx::default_transport::ChannelParcelable>( - LocalHandle(0), LocalHandle(0), LocalHandle(0)); - EXPECT_TRUE(fake_channel_parcelable->IsValid()); - ProducerQueueParcelable fake_producer_parcelable( - std::move(fake_channel_parcelable)); - EXPECT_TRUE(fake_producer_parcelable.IsValid()); - - // Disconnect producer can be taken out, but only to an invalid parcelable. - ASSERT_EQ(mProducer->disconnect(kTestApi), OK); - EXPECT_EQ(mProducer->TakeAsParcelable(&fake_producer_parcelable), BAD_VALUE); - EXPECT_FALSE(producer_parcelable.IsValid()); - EXPECT_EQ(mProducer->TakeAsParcelable(&producer_parcelable), OK); - EXPECT_TRUE(producer_parcelable.IsValid()); - - // Should still be able to query buffer dimension after disconnect. - int32_t value = -1; - EXPECT_EQ(OK, mProducer->query(NATIVE_WINDOW_WIDTH, &value)); - EXPECT_EQ(static_cast<uint32_t>(value), kDefaultWidth); - - EXPECT_EQ(mProducer->query(NATIVE_WINDOW_HEIGHT, &value), OK); - EXPECT_EQ(static_cast<uint32_t>(value), kDefaultHeight); - - EXPECT_EQ(mProducer->query(NATIVE_WINDOW_FORMAT, &value), OK); - EXPECT_EQ(value, kDefaultFormat); - - // But connect to API will fail. - IGraphicBufferProducer::QueueBufferOutput output; - EXPECT_EQ(mProducer->connect(kStubListener, kTestApi, kTestControlledByApp, - &output), - BAD_VALUE); - - // Create a new producer from the parcelable and connect to kTestApi should - // succeed. - sp<BufferHubProducer> new_producer = - BufferHubProducer::Create(std::move(producer_parcelable)); - ASSERT_TRUE(new_producer != nullptr); - EXPECT_EQ(new_producer->connect(kStubListener, kTestApi, kTestControlledByApp, - &output), - OK); -} - -} // namespace - -} // namespace dvr -} // namespace android diff --git a/libs/vr/libdvr/Android.bp b/libs/vr/libdvr/Android.bp index 96023ddf86..9dbeacba94 100644 --- a/libs/vr/libdvr/Android.bp +++ b/libs/vr/libdvr/Android.bp @@ -33,87 +33,3 @@ cc_library_headers { ], min_sdk_version: "29", } - -cc_library_headers { - name: "libdvr_private_headers", - export_include_dirs: ["."], - vendor_available: false, -} - -cflags = [ - "-DDVR_TRACKING_IMPLEMENTED=0", - "-DLOG_TAG=\"libdvr\"", - "-DTRACE=0", - "-Wall", - "-Werror", -] - -srcs = [ - "dvr_api.cpp", - "dvr_buffer.cpp", - "dvr_buffer_queue.cpp", - "dvr_configuration_data.cpp", - "dvr_display_manager.cpp", - "dvr_hardware_composer_client.cpp", - "dvr_performance.cpp", - "dvr_pose.cpp", - "dvr_surface.cpp", - "dvr_tracking.cpp", -] - -static_libs = [ - "libbroadcastring", - "libvrsensor", - "libdisplay", - "libvirtualtouchpadclient", - "libvr_hwc-impl", - "libvr_hwc-binder", - "libgrallocusage", - "libperformance", -] - -shared_libs = [ - "android.hardware.graphics.bufferqueue@1.0", - "android.hidl.token@1.0-utils", - "libbase", - "libbufferhubqueue", - "libbinder", - "liblog", - "libcutils", - "libutils", - "libnativewindow", - "libgui", - "libui", - "libpdx_default_transport", -] - -cc_library_shared { - name: "libdvr.google", - system_ext_specific: true, - owner: "google", - cflags: cflags, - header_libs: ["libdvr_headers"], - export_header_lib_headers: ["libdvr_headers"], - srcs: srcs, - static_libs: static_libs, - shared_libs: shared_libs, - version_script: "exported_apis.lds", -} - -// Also build a static libdvr for linking into tests. The linker script -// restricting function access in the shared lib makes it inconvenient to use in -// test code. -cc_library_static { - name: "libdvr_static.google", - owner: "google", - cflags: cflags, - header_libs: ["libdvr_headers"], - export_header_lib_headers: ["libdvr_headers"], - srcs: srcs, - static_libs: static_libs, - shared_libs: shared_libs, -} - -subdirs = [ - "tests", -] diff --git a/libs/vr/libdvr/dvr_api.cpp b/libs/vr/libdvr/dvr_api.cpp deleted file mode 100644 index e099f6a699..0000000000 --- a/libs/vr/libdvr/dvr_api.cpp +++ /dev/null @@ -1,66 +0,0 @@ -#include "include/dvr/dvr_api.h" - -#include <errno.h> -#include <utils/Log.h> - -#include <algorithm> - -// Headers from libdvr -#include <dvr/dvr_buffer.h> -#include <dvr/dvr_buffer_queue.h> -#include <dvr/dvr_configuration_data.h> -#include <dvr/dvr_display_manager.h> -#include <dvr/dvr_performance.h> -#include <dvr/dvr_surface.h> -#include <dvr/dvr_tracking.h> -#include <dvr/dvr_vsync.h> - -// Headers not yet moved into libdvr. -// TODO(jwcai) Move these once their callers are moved into Google3. -#include <dvr/dvr_hardware_composer_client.h> -#include <dvr/pose_client.h> -#include <dvr/virtual_touchpad_client.h> - -extern "C" { - -int dvrGetApi(void* api, size_t struct_size, int version) { - ALOGI("dvrGetApi: api=%p struct_size=%zu version=%d", api, struct_size, - version); - if (version == 1) { - // New entry points are added at the end. If the caller's struct and - // this library have different sizes, we define the entry points in common. - // The caller is expected to handle unset entry points if necessary. - size_t clamped_struct_size = std::min(struct_size, sizeof(DvrApi_v1)); - DvrApi_v1* dvr_api = static_cast<DvrApi_v1*>(api); - -// Defines an API entry for V1 (no version suffix). -#define DVR_V1_API_ENTRY(name) \ - do { \ - if ((offsetof(DvrApi_v1, name) + sizeof(dvr_api->name)) <= \ - clamped_struct_size) { \ - dvr_api->name = dvr##name; \ - } \ - } while (0) - -#define DVR_V1_API_ENTRY_DEPRECATED(name) \ - do { \ - if ((offsetof(DvrApi_v1, name) + sizeof(dvr_api->name)) <= \ - clamped_struct_size) { \ - dvr_api->name = nullptr; \ - } \ - } while (0) - -#include "include/dvr/dvr_api_entries.h" - -// Undefine macro definitions to play nice with Google3 style rules. -#undef DVR_V1_API_ENTRY -#undef DVR_V1_API_ENTRY_DEPRECATED - - return 0; - } - - ALOGE("dvrGetApi: Unknown API version=%d", version); - return -EINVAL; -} - -} // extern "C" diff --git a/libs/vr/libdvr/dvr_buffer.cpp b/libs/vr/libdvr/dvr_buffer.cpp deleted file mode 100644 index c11706fc7f..0000000000 --- a/libs/vr/libdvr/dvr_buffer.cpp +++ /dev/null @@ -1,121 +0,0 @@ -#include "include/dvr/dvr_buffer.h" - -#include <android/hardware_buffer.h> -#include <dvr/dvr_shared_buffers.h> -#include <private/dvr/consumer_buffer.h> -#include <private/dvr/producer_buffer.h> -#include <ui/GraphicBuffer.h> - -#include "dvr_internal.h" - -using namespace android; - -namespace android { -namespace dvr { - -DvrBuffer* CreateDvrBufferFromIonBuffer( - const std::shared_ptr<IonBuffer>& ion_buffer) { - if (!ion_buffer) - return nullptr; - return new DvrBuffer{std::move(ion_buffer)}; -} - -} // namespace dvr -} // namespace android - -namespace { - -int ConvertToAHardwareBuffer(GraphicBuffer* graphic_buffer, - AHardwareBuffer** hardware_buffer) { - if (!hardware_buffer || !graphic_buffer) { - return -EINVAL; - } - *hardware_buffer = reinterpret_cast<AHardwareBuffer*>(graphic_buffer); - AHardwareBuffer_acquire(*hardware_buffer); - return 0; -} - -} // anonymous namespace - -extern "C" { - -void dvrWriteBufferDestroy(DvrWriteBuffer* write_buffer) { - if (write_buffer != nullptr) { - ALOGW_IF( - write_buffer->slot != -1, - "dvrWriteBufferDestroy: Destroying a buffer associated with a valid " - "buffer queue slot. This may indicate possible leaks, buffer_id=%d.", - dvrWriteBufferGetId(write_buffer)); - delete write_buffer; - } -} - -int dvrWriteBufferIsValid(DvrWriteBuffer* write_buffer) { - return write_buffer && write_buffer->write_buffer; -} - -int dvrWriteBufferGetId(DvrWriteBuffer* write_buffer) { - if (!write_buffer || !write_buffer->write_buffer) - return -EINVAL; - - return write_buffer->write_buffer->id(); -} - -int dvrWriteBufferGetAHardwareBuffer(DvrWriteBuffer* write_buffer, - AHardwareBuffer** hardware_buffer) { - if (!write_buffer || !write_buffer->write_buffer) - return -EINVAL; - - return ConvertToAHardwareBuffer( - write_buffer->write_buffer->buffer()->buffer().get(), hardware_buffer); -} - -void dvrReadBufferDestroy(DvrReadBuffer* read_buffer) { - if (read_buffer != nullptr) { - ALOGW_IF( - read_buffer->slot != -1, - "dvrReadBufferDestroy: Destroying a buffer associated with a valid " - "buffer queue slot. This may indicate possible leaks, buffer_id=%d.", - dvrReadBufferGetId(read_buffer)); - delete read_buffer; - } -} - -int dvrReadBufferIsValid(DvrReadBuffer* read_buffer) { - return read_buffer && read_buffer->read_buffer; -} - -int dvrReadBufferGetId(DvrReadBuffer* read_buffer) { - if (!read_buffer || !read_buffer->read_buffer) - return -EINVAL; - - return read_buffer->read_buffer->id(); -} - -int dvrReadBufferGetAHardwareBuffer(DvrReadBuffer* read_buffer, - AHardwareBuffer** hardware_buffer) { - if (!read_buffer || !read_buffer->read_buffer) - return -EINVAL; - - return ConvertToAHardwareBuffer( - read_buffer->read_buffer->buffer()->buffer().get(), hardware_buffer); -} - -void dvrBufferDestroy(DvrBuffer* buffer) { delete buffer; } - -int dvrBufferGetAHardwareBuffer(DvrBuffer* buffer, - AHardwareBuffer** hardware_buffer) { - if (!buffer || !buffer->buffer || !hardware_buffer) { - return -EINVAL; - } - - return ConvertToAHardwareBuffer(buffer->buffer->buffer().get(), - hardware_buffer); -} - -// Retrieve the shared buffer layout version defined in dvr_shared_buffers.h. -int dvrBufferGlobalLayoutVersionGet() { - return android::dvr::kSharedBufferLayoutVersion; -} - -} // extern "C" diff --git a/libs/vr/libdvr/dvr_buffer_queue.cpp b/libs/vr/libdvr/dvr_buffer_queue.cpp deleted file mode 100644 index 1ca653c4ff..0000000000 --- a/libs/vr/libdvr/dvr_buffer_queue.cpp +++ /dev/null @@ -1,552 +0,0 @@ -#include "include/dvr/dvr_api.h" -#include "include/dvr/dvr_buffer_queue.h" - -#include <android/native_window.h> -#include <gui/BufferHubProducer.h> - -#include "dvr_internal.h" -#include "dvr_buffer_queue_internal.h" - -using namespace android; -using android::dvr::BufferHubBase; -using android::dvr::ConsumerBuffer; -using android::dvr::ConsumerQueue; -using android::dvr::ProducerBuffer; -using android::dvr::ProducerQueue; -using android::dvr::ProducerQueueConfigBuilder; -using android::dvr::UsagePolicy; - -extern "C" { - -DvrWriteBufferQueue::DvrWriteBufferQueue( - const std::shared_ptr<ProducerQueue>& producer_queue) - : producer_queue_(producer_queue), - width_(producer_queue->default_width()), - height_(producer_queue->default_height()), - format_(producer_queue->default_format()) {} - -int DvrWriteBufferQueue::GetNativeWindow(ANativeWindow** out_window) { - if (native_window_ == nullptr) { - // Lazy creation of |native_window|, as not everyone is using - // DvrWriteBufferQueue as an external surface. - sp<IGraphicBufferProducer> gbp = BufferHubProducer::Create(producer_queue_); - native_window_ = new Surface(gbp, true); - } - - *out_window = static_cast<ANativeWindow*>(native_window_.get()); - return 0; -} - -int DvrWriteBufferQueue::CreateReadQueue(DvrReadBufferQueue** out_read_queue) { - std::unique_ptr<ConsumerQueue> consumer_queue = - producer_queue_->CreateConsumerQueue(); - if (consumer_queue == nullptr) { - ALOGE( - "DvrWriteBufferQueue::CreateReadQueue: Failed to create consumer queue " - "from producer queue: queue_id=%d.", producer_queue_->id()); - return -ENOMEM; - } - - *out_read_queue = new DvrReadBufferQueue(std::move(consumer_queue)); - return 0; -} - -int DvrWriteBufferQueue::Dequeue(int timeout, DvrWriteBuffer* write_buffer, - int* out_fence_fd) { - DvrNativeBufferMetadata meta; - DvrWriteBuffer* buffer = nullptr; - int fence_fd = -1; - if (const int ret = GainBuffer(timeout, &buffer, &meta, &fence_fd)) - return ret; - if (!buffer) - return -ENOMEM; - - write_buffers_[buffer->slot].reset(buffer); - write_buffer->write_buffer = std::move(buffer->write_buffer); - *out_fence_fd = fence_fd; - return 0; -} - -int DvrWriteBufferQueue::GainBuffer(int timeout, - DvrWriteBuffer** out_write_buffer, - DvrNativeBufferMetadata* out_meta, - int* out_fence_fd) { - size_t slot; - pdx::LocalHandle release_fence; - - // Need to retry N+1 times, where N is total number of buffers in the queue. - // As in the worst case, we will dequeue all N buffers and reallocate them, on - // the {N+1}th dequeue, we are guaranteed to get a buffer with new dimension. - size_t max_retries = 1 + producer_queue_->capacity(); - size_t retry = 0; - - for (; retry < max_retries; retry++) { - auto buffer_status = - producer_queue_->Dequeue(timeout, &slot, out_meta, &release_fence); - if (!buffer_status) { - ALOGE_IF(buffer_status.error() != ETIMEDOUT, - "DvrWriteBufferQueue::GainBuffer: Failed to dequeue buffer: %s", - buffer_status.GetErrorMessage().c_str()); - return -buffer_status.error(); - } - - if (write_buffers_[slot] == nullptr) { - // Lazy initialization of a write_buffers_ slot. Note that a slot will - // only be dynamically allocated once during the entire cycle life of a - // queue. - write_buffers_[slot] = std::make_unique<DvrWriteBuffer>(); - write_buffers_[slot]->slot = slot; - } - - LOG_ALWAYS_FATAL_IF( - write_buffers_[slot]->write_buffer, - "DvrWriteBufferQueue::GainBuffer: Buffer slot is not empty: %zu", slot); - write_buffers_[slot]->write_buffer = std::move(buffer_status.take()); - - const auto& producer_buffer = write_buffers_[slot]->write_buffer; - if (!producer_buffer) - return -ENOMEM; - - if (width_ == producer_buffer->width() && - height_ == producer_buffer->height() && - format_ == producer_buffer->format()) { - // Producer queue returns a buffer matches the current request. - break; - } - - // Needs reallocation. Note that if there are already multiple available - // buffers in the queue, the next one returned from |queue_->Dequeue| may - // still have the old buffer dimension or format. Retry up to N+1 times or - // until we dequeued a buffer with new configuration. - ALOGD_IF(TRACE, - "DvrWriteBufferQueue::Dequeue: requested buffer at slot: %zu " - "(w=%u, h=%u, fmt=%u) is different from the buffer returned " - "(w=%u, h=%u, fmt=%u). Need re-allocation.", - slot, width_, height_, format_, producer_buffer->width(), - producer_buffer->height(), producer_buffer->format()); - - // Currently, we are not storing |layer_count| and |usage| in queue - // configuration. Copy those setup from the last buffer dequeued before we - // remove it. - uint32_t old_layer_count = producer_buffer->layer_count(); - uint64_t old_usage = producer_buffer->usage(); - - // Allocate a new producer buffer with new buffer configs. Note that if - // there are already multiple available buffers in the queue, the next one - // returned from |queue_->Dequeue| may still have the old buffer dimension - // or format. Retry up to BufferHubQueue::kMaxQueueCapacity times or until - // we dequeued a buffer with new configuration. - auto remove_status = producer_queue_->RemoveBuffer(slot); - if (!remove_status) { - ALOGE("DvrWriteBufferQueue::Dequeue: Failed to remove buffer: %s", - remove_status.GetErrorMessage().c_str()); - return -remove_status.error(); - } - // Make sure that the previously allocated buffer is dereferenced from - // write_buffers_ array. - write_buffers_[slot]->write_buffer = nullptr; - - auto allocate_status = producer_queue_->AllocateBuffer( - width_, height_, old_layer_count, format_, old_usage); - if (!allocate_status) { - ALOGE("DvrWriteBufferQueue::Dequeue: Failed to allocate buffer: %s", - allocate_status.GetErrorMessage().c_str()); - return -allocate_status.error(); - } - } - - if (retry >= max_retries) { - ALOGE( - "DvrWriteBufferQueue::Dequeue: Failed to re-allocate buffer after " - "resizing."); - return -ENOMEM; - } - - *out_write_buffer = write_buffers_[slot].release(); - *out_fence_fd = release_fence.Release(); - - return 0; -} - -int DvrWriteBufferQueue::PostBuffer(DvrWriteBuffer* write_buffer, - const DvrNativeBufferMetadata* meta, - int ready_fence_fd) { - // Some basic sanity checks before we put the buffer back into a slot. - size_t slot = static_cast<size_t>(write_buffer->slot); - LOG_FATAL_IF( - (write_buffers->slot < 0 || write_buffers->slot >= write_buffers_.size()), - "DvrWriteBufferQueue::ReleaseBuffer: Invalid slot: %zu", slot); - - if (write_buffers_[slot] != nullptr) { - ALOGE("DvrWriteBufferQueue::PostBuffer: Slot is not empty: %zu", slot); - return -EINVAL; - } - if (write_buffer->write_buffer == nullptr) { - ALOGE("DvrWriteBufferQueue::PostBuffer: Invalid write buffer."); - return -EINVAL; - } - if (write_buffer->write_buffer->id() != producer_queue_->GetBufferId(slot)) { - ALOGE( - "DvrWriteBufferQueue::PostBuffer: Buffer to be posted does not " - "belong to this buffer queue. Posting buffer: id=%d, buffer in " - "queue: id=%d", - write_buffer->write_buffer->id(), producer_queue_->GetBufferId(slot)); - return -EINVAL; - } - - write_buffer->write_buffer->SetQueueIndex(next_post_index_++); - pdx::LocalHandle fence(ready_fence_fd); - const int ret = write_buffer->write_buffer->PostAsync(meta, fence); - if (ret < 0) { - ALOGE("DvrWriteBufferQueue::PostBuffer: Failed to post buffer, ret=%d", - ret); - return ret; - } - - // Put the DvrWriteBuffer pointer back into its slot for reuse. - write_buffers_[slot].reset(write_buffer); - // It's import to reset the write buffer client now. It should stay invalid - // until next GainBuffer on the same slot. - write_buffers_[slot]->write_buffer = nullptr; - return 0; -} - -int DvrWriteBufferQueue::ResizeBuffer(uint32_t width, uint32_t height) { - if (width == 0 || height == 0) { - ALOGE( - "DvrWriteBufferQueue::ResizeBuffer: invalid buffer dimension: w=%u, " - "h=%u.", - width, height); - return -EINVAL; - } - - width_ = width; - height_ = height; - return 0; -} - -int dvrWriteBufferQueueCreate(uint32_t width, uint32_t height, uint32_t format, - uint32_t layer_count, uint64_t usage, - size_t capacity, size_t metadata_size, - DvrWriteBufferQueue** out_write_queue) { - if (!out_write_queue) - return -EINVAL; - - auto config_builder = ProducerQueueConfigBuilder() - .SetDefaultWidth(width) - .SetDefaultHeight(height) - .SetDefaultFormat(format) - .SetMetadataSize(metadata_size); - std::unique_ptr<ProducerQueue> producer_queue = - ProducerQueue::Create(config_builder.Build(), UsagePolicy{}); - if (!producer_queue) { - ALOGE("dvrWriteBufferQueueCreate: Failed to create producer queue."); - return -ENOMEM; - } - - auto status = producer_queue->AllocateBuffers(width, height, layer_count, - format, usage, capacity); - if (!status.ok()) { - ALOGE("dvrWriteBufferQueueCreate: Failed to allocate buffers."); - return -ENOMEM; - } - - *out_write_queue = new DvrWriteBufferQueue(std::move(producer_queue)); - return 0; -} - -void dvrWriteBufferQueueDestroy(DvrWriteBufferQueue* write_queue) { - delete write_queue; -} - -ssize_t dvrWriteBufferQueueGetCapacity(DvrWriteBufferQueue* write_queue) { - if (!write_queue) - return -EINVAL; - - return write_queue->capacity(); -} - -int dvrWriteBufferQueueGetId(DvrWriteBufferQueue* write_queue) { - if (!write_queue) - return -EINVAL; - - return write_queue->id(); -} - -int dvrWriteBufferQueueGetANativeWindow(DvrWriteBufferQueue* write_queue, - ANativeWindow** out_window) { - if (!write_queue || !out_window) - return -EINVAL; - - return write_queue->GetNativeWindow(out_window); -} - -int dvrWriteBufferQueueCreateReadQueue(DvrWriteBufferQueue* write_queue, - DvrReadBufferQueue** out_read_queue) { - if (!write_queue || !out_read_queue) - return -EINVAL; - - return write_queue->CreateReadQueue(out_read_queue); -} - -int dvrWriteBufferQueueGainBuffer(DvrWriteBufferQueue* write_queue, int timeout, - DvrWriteBuffer** out_write_buffer, - DvrNativeBufferMetadata* out_meta, - int* out_fence_fd) { - if (!write_queue || !out_write_buffer || !out_meta || !out_fence_fd) - return -EINVAL; - - return write_queue->GainBuffer(timeout, out_write_buffer, out_meta, - out_fence_fd); -} - -int dvrWriteBufferQueuePostBuffer(DvrWriteBufferQueue* write_queue, - DvrWriteBuffer* write_buffer, - const DvrNativeBufferMetadata* meta, - int ready_fence_fd) { - if (!write_queue || !write_buffer || !write_buffer->write_buffer || !meta) - return -EINVAL; - - return write_queue->PostBuffer(write_buffer, meta, ready_fence_fd); -} - -int dvrWriteBufferQueueResizeBuffer(DvrWriteBufferQueue* write_queue, - uint32_t width, uint32_t height) { - if (!write_queue) - return -EINVAL; - - return write_queue->ResizeBuffer(width, height); -} - -// ReadBufferQueue - -DvrReadBufferQueue::DvrReadBufferQueue( - const std::shared_ptr<ConsumerQueue>& consumer_queue) - : consumer_queue_(consumer_queue) {} - -int DvrReadBufferQueue::CreateReadQueue(DvrReadBufferQueue** out_read_queue) { - std::unique_ptr<ConsumerQueue> consumer_queue = - consumer_queue_->CreateConsumerQueue(); - if (consumer_queue == nullptr) { - ALOGE( - "DvrReadBufferQueue::CreateReadQueue: Failed to create consumer queue " - "from producer queue: queue_id=%d.", consumer_queue_->id()); - return -ENOMEM; - } - - *out_read_queue = new DvrReadBufferQueue(std::move(consumer_queue)); - return 0; -} - -int DvrReadBufferQueue::AcquireBuffer(int timeout, - DvrReadBuffer** out_read_buffer, - DvrNativeBufferMetadata* out_meta, - int* out_fence_fd) { - size_t slot; - pdx::LocalHandle acquire_fence; - auto buffer_status = - consumer_queue_->Dequeue(timeout, &slot, out_meta, &acquire_fence); - if (!buffer_status) { - ALOGE_IF(buffer_status.error() != ETIMEDOUT, - "DvrReadBufferQueue::AcquireBuffer: Failed to dequeue buffer: %s", - buffer_status.GetErrorMessage().c_str()); - return -buffer_status.error(); - } - - if (read_buffers_[slot] == nullptr) { - // Lazy initialization of a read_buffers_ slot. Note that a slot will only - // be dynamically allocated once during the entire cycle life of a queue. - read_buffers_[slot] = std::make_unique<DvrReadBuffer>(); - read_buffers_[slot]->slot = slot; - } - - LOG_FATAL_IF( - read_buffers_[slot]->read_buffer, - "DvrReadBufferQueue::AcquireBuffer: Buffer slot is not empty: %zu", slot); - read_buffers_[slot]->read_buffer = std::move(buffer_status.take()); - - *out_read_buffer = read_buffers_[slot].release(); - *out_fence_fd = acquire_fence.Release(); - - return 0; -} - -int DvrReadBufferQueue::ReleaseBuffer(DvrReadBuffer* read_buffer, - const DvrNativeBufferMetadata* meta, - int release_fence_fd) { - // Some basic sanity checks before we put the buffer back into a slot. - size_t slot = static_cast<size_t>(read_buffer->slot); - LOG_FATAL_IF( - (read_buffers->slot < 0 || read_buffers->slot >= read_buffers_size()), - "DvrReadBufferQueue::ReleaseBuffer: Invalid slot: %zu", slot); - - if (read_buffers_[slot] != nullptr) { - ALOGE("DvrReadBufferQueue::ReleaseBuffer: Slot is not empty: %zu", slot); - return -EINVAL; - } - if (read_buffer->read_buffer == nullptr) { - ALOGE("DvrReadBufferQueue::ReleaseBuffer: Invalid read buffer."); - return -EINVAL; - } - if (read_buffer->read_buffer->id() != consumer_queue_->GetBufferId(slot)) { - if (consumer_queue_->GetBufferId(slot) > 0) { - ALOGE( - "DvrReadBufferQueue::ReleaseBuffer: Buffer to be released may not " - "belong to this queue (queue_id=%d): attempting to release buffer " - "(buffer_id=%d) at slot %d which holds a different buffer " - "(buffer_id=%d).", - consumer_queue_->id(), read_buffer->read_buffer->id(), - static_cast<int>(slot), consumer_queue_->GetBufferId(slot)); - } else { - ALOGI( - "DvrReadBufferQueue::ReleaseBuffer: Buffer to be released may not " - "belong to this queue (queue_id=%d): attempting to release buffer " - "(buffer_id=%d) at slot %d which is empty.", - consumer_queue_->id(), read_buffer->read_buffer->id(), - static_cast<int>(slot)); - } - } - - pdx::LocalHandle fence(release_fence_fd); - int ret = read_buffer->read_buffer->ReleaseAsync(meta, fence); - if (ret < 0) { - ALOGE("DvrReadBufferQueue::ReleaseBuffer: Failed to release buffer, ret=%d", - ret); - return ret; - } - - // Put the DvrReadBuffer pointer back into its slot for reuse. - read_buffers_[slot].reset(read_buffer); - // It's import to reset the read buffer client now. It should stay invalid - // until next AcquireBuffer on the same slot. - read_buffers_[slot]->read_buffer = nullptr; - return 0; -} - -void DvrReadBufferQueue::SetBufferAvailableCallback( - DvrReadBufferQueueBufferAvailableCallback callback, void* context) { - if (callback == nullptr) { - consumer_queue_->SetBufferAvailableCallback(nullptr); - } else { - consumer_queue_->SetBufferAvailableCallback( - [callback, context]() { callback(context); }); - } -} - -void DvrReadBufferQueue::SetBufferRemovedCallback( - DvrReadBufferQueueBufferRemovedCallback callback, void* context) { - if (callback == nullptr) { - consumer_queue_->SetBufferRemovedCallback(nullptr); - } else { - consumer_queue_->SetBufferRemovedCallback( - [callback, context](const std::shared_ptr<BufferHubBase>& buffer) { - // When buffer is removed from the queue, the slot is already invalid. - auto read_buffer = std::make_unique<DvrReadBuffer>(); - read_buffer->read_buffer = - std::static_pointer_cast<ConsumerBuffer>(buffer); - callback(read_buffer.release(), context); - }); - } -} - -int DvrReadBufferQueue::HandleEvents() { - // TODO(jwcai) Probably should change HandleQueueEvents to return Status. - consumer_queue_->HandleQueueEvents(); - return 0; -} - -void dvrReadBufferQueueDestroy(DvrReadBufferQueue* read_queue) { - delete read_queue; -} - -ssize_t dvrReadBufferQueueGetCapacity(DvrReadBufferQueue* read_queue) { - if (!read_queue) - return -EINVAL; - - return read_queue->capacity(); -} - -int dvrReadBufferQueueGetId(DvrReadBufferQueue* read_queue) { - if (!read_queue) - return -EINVAL; - - return read_queue->id(); -} - -int dvrReadBufferQueueGetEventFd(DvrReadBufferQueue* read_queue) { - if (!read_queue) - return -EINVAL; - - return read_queue->event_fd(); -} - -int dvrReadBufferQueueCreateReadQueue(DvrReadBufferQueue* read_queue, - DvrReadBufferQueue** out_read_queue) { - if (!read_queue || !out_read_queue) - return -EINVAL; - - return read_queue->CreateReadQueue(out_read_queue); -} - -int dvrReadBufferQueueDequeue(DvrReadBufferQueue* read_queue, int timeout, - DvrReadBuffer* read_buffer, int* out_fence_fd, - void* out_meta, size_t meta_size_bytes) { - if (!read_queue || !read_buffer || !out_fence_fd) - return -EINVAL; - - if (meta_size_bytes != 0 && !out_meta) - return -EINVAL; - - return read_queue->Dequeue(timeout, read_buffer, out_fence_fd, out_meta, - meta_size_bytes); -} - -int dvrReadBufferQueueAcquireBuffer(DvrReadBufferQueue* read_queue, int timeout, - DvrReadBuffer** out_read_buffer, - DvrNativeBufferMetadata* out_meta, - int* out_fence_fd) { - if (!read_queue || !out_read_buffer || !out_meta || !out_fence_fd) - return -EINVAL; - - return read_queue->AcquireBuffer(timeout, out_read_buffer, out_meta, - out_fence_fd); -} - -int dvrReadBufferQueueReleaseBuffer(DvrReadBufferQueue* read_queue, - DvrReadBuffer* read_buffer, - const DvrNativeBufferMetadata* meta, - int release_fence_fd) { - if (!read_queue || !read_buffer || !read_buffer->read_buffer || !meta) - return -EINVAL; - - return read_queue->ReleaseBuffer(read_buffer, meta, release_fence_fd); -} - -int dvrReadBufferQueueSetBufferAvailableCallback( - DvrReadBufferQueue* read_queue, - DvrReadBufferQueueBufferAvailableCallback callback, void* context) { - if (!read_queue) - return -EINVAL; - - read_queue->SetBufferAvailableCallback(callback, context); - return 0; -} - -int dvrReadBufferQueueSetBufferRemovedCallback( - DvrReadBufferQueue* read_queue, - DvrReadBufferQueueBufferRemovedCallback callback, void* context) { - if (!read_queue) - return -EINVAL; - - read_queue->SetBufferRemovedCallback(callback, context); - return 0; -} - -int dvrReadBufferQueueHandleEvents(DvrReadBufferQueue* read_queue) { - if (!read_queue) - return -EINVAL; - - return read_queue->HandleEvents(); -} - -} // extern "C" diff --git a/libs/vr/libdvr/dvr_buffer_queue_internal.h b/libs/vr/libdvr/dvr_buffer_queue_internal.h deleted file mode 100644 index e53a6868ff..0000000000 --- a/libs/vr/libdvr/dvr_buffer_queue_internal.h +++ /dev/null @@ -1,95 +0,0 @@ -#ifndef ANDROID_DVR_BUFFER_QUEUE_INTERNAL_H_ -#define ANDROID_DVR_BUFFER_QUEUE_INTERNAL_H_ - -#include <gui/Surface.h> -#include <private/dvr/buffer_hub_queue_client.h> -#include <sys/cdefs.h> - -#include <array> -#include <memory> - -#include "dvr_internal.h" - -struct ANativeWindow; - -typedef struct DvrNativeBufferMetadata DvrNativeBufferMetadata; -typedef struct DvrReadBuffer DvrReadBuffer; -typedef struct DvrReadBufferQueue DvrReadBufferQueue; -typedef struct DvrWriteBuffer DvrWriteBuffer; -typedef void (*DvrReadBufferQueueBufferAvailableCallback)(void* context); -typedef void (*DvrReadBufferQueueBufferRemovedCallback)(DvrReadBuffer* buffer, - void* context); - -struct DvrWriteBufferQueue { - using BufferHubQueue = android::dvr::BufferHubQueue; - using ProducerQueue = android::dvr::ProducerQueue; - - // Create a concrete object for DvrWriteBufferQueue. - // - // @param producer_queue The BufferHub's ProducerQueue that is used to back - // this DvrWriteBufferQueue, must not be NULL. - explicit DvrWriteBufferQueue( - const std::shared_ptr<ProducerQueue>& producer_queue); - - int id() const { return producer_queue_->id(); } - uint32_t width() const { return width_; }; - uint32_t height() const { return height_; }; - uint32_t format() const { return format_; }; - size_t capacity() const { return producer_queue_->capacity(); } - const std::shared_ptr<ProducerQueue>& producer_queue() const { - return producer_queue_; - } - - int GetNativeWindow(ANativeWindow** out_window); - int CreateReadQueue(DvrReadBufferQueue** out_read_queue); - int Dequeue(int timeout, DvrWriteBuffer* write_buffer, int* out_fence_fd); - int GainBuffer(int timeout, DvrWriteBuffer** out_write_buffer, - DvrNativeBufferMetadata* out_meta, int* out_fence_fd); - int PostBuffer(DvrWriteBuffer* write_buffer, - const DvrNativeBufferMetadata* meta, int ready_fence_fd); - int ResizeBuffer(uint32_t width, uint32_t height); - - private: - std::shared_ptr<ProducerQueue> producer_queue_; - std::array<std::unique_ptr<DvrWriteBuffer>, BufferHubQueue::kMaxQueueCapacity> - write_buffers_; - - int64_t next_post_index_ = 0; - uint32_t width_; - uint32_t height_; - uint32_t format_; - - android::sp<android::Surface> native_window_; -}; - -struct DvrReadBufferQueue { - using BufferHubQueue = android::dvr::BufferHubQueue; - using ConsumerQueue = android::dvr::ConsumerQueue; - - explicit DvrReadBufferQueue( - const std::shared_ptr<ConsumerQueue>& consumer_queue); - - int id() const { return consumer_queue_->id(); } - int event_fd() const { return consumer_queue_->queue_fd(); } - size_t capacity() const { return consumer_queue_->capacity(); } - - int CreateReadQueue(DvrReadBufferQueue** out_read_queue); - int Dequeue(int timeout, DvrReadBuffer* read_buffer, int* out_fence_fd, - void* out_meta, size_t user_metadata_size); - int AcquireBuffer(int timeout, DvrReadBuffer** out_read_buffer, - DvrNativeBufferMetadata* out_meta, int* out_fence_fd); - int ReleaseBuffer(DvrReadBuffer* read_buffer, - const DvrNativeBufferMetadata* meta, int release_fence_fd); - void SetBufferAvailableCallback( - DvrReadBufferQueueBufferAvailableCallback callback, void* context); - void SetBufferRemovedCallback( - DvrReadBufferQueueBufferRemovedCallback callback, void* context); - int HandleEvents(); - - private: - std::shared_ptr<ConsumerQueue> consumer_queue_; - std::array<std::unique_ptr<DvrReadBuffer>, BufferHubQueue::kMaxQueueCapacity> - read_buffers_; -}; - -#endif // ANDROID_DVR_BUFFER_QUEUE_INTERNAL_H_ diff --git a/libs/vr/libdvr/dvr_configuration_data.cpp b/libs/vr/libdvr/dvr_configuration_data.cpp deleted file mode 100644 index df0d54e1a2..0000000000 --- a/libs/vr/libdvr/dvr_configuration_data.cpp +++ /dev/null @@ -1,40 +0,0 @@ -#include "include/dvr/dvr_configuration_data.h" - -#include <private/dvr/display_client.h> - -using android::dvr::display::ConfigFileType; -using android::dvr::display::DisplayClient; - -extern "C" { - -int dvrConfigurationDataGet(int config_type, uint8_t** data, - size_t* data_size) { - if (!data || !data_size) { - return -EINVAL; - } - - auto client = DisplayClient::Create(); - if (!client) { - ALOGE("dvrGetGlobalBuffer: Failed to create display client!"); - return -ECOMM; - } - - ConfigFileType config_file_type = static_cast<ConfigFileType>(config_type); - auto config_data_status = - client->GetConfigurationData(config_file_type); - - if (!config_data_status) { - return -config_data_status.error(); - } - - *data_size = config_data_status.get().size(); - *data = new uint8_t[*data_size]; - std::copy_n(config_data_status.get().begin(), *data_size, *data); - return 0; -} - -void dvrConfigurationDataDestroy(uint8_t* data) { - delete[] data; -} - -} // extern "C" diff --git a/libs/vr/libdvr/dvr_display_manager.cpp b/libs/vr/libdvr/dvr_display_manager.cpp deleted file mode 100644 index 7f631e3d39..0000000000 --- a/libs/vr/libdvr/dvr_display_manager.cpp +++ /dev/null @@ -1,283 +0,0 @@ -#include "include/dvr/dvr_display_manager.h" - -#include <dvr/dvr_buffer.h> -#include <pdx/rpc/variant.h> -#include <private/dvr/buffer_hub_queue_client.h> -#include <private/dvr/consumer_buffer.h> -#include <private/dvr/display_client.h> -#include <private/dvr/display_manager_client.h> - -#include "dvr_internal.h" -#include "dvr_buffer_queue_internal.h" - -using android::dvr::ConsumerBuffer; -using android::dvr::display::DisplayManagerClient; -using android::dvr::display::SurfaceAttribute; -using android::dvr::display::SurfaceAttributes; -using android::dvr::display::SurfaceState; -using android::pdx::rpc::EmptyVariant; - -namespace { - -// Extracts type and value from the attribute Variant and writes them into the -// respective fields of DvrSurfaceAttribute. -struct AttributeVisitor { - DvrSurfaceAttribute* attribute; - - void operator()(int32_t value) { - attribute->value.int32_value = value; - attribute->value.type = DVR_SURFACE_ATTRIBUTE_TYPE_INT32; - } - void operator()(int64_t value) { - attribute->value.int64_value = value; - attribute->value.type = DVR_SURFACE_ATTRIBUTE_TYPE_INT64; - } - void operator()(bool value) { - attribute->value.bool_value = value; - attribute->value.type = DVR_SURFACE_ATTRIBUTE_TYPE_BOOL; - } - void operator()(float value) { - attribute->value.float_value = value; - attribute->value.type = DVR_SURFACE_ATTRIBUTE_TYPE_FLOAT; - } - void operator()(const std::array<float, 2>& value) { - std::copy(value.cbegin(), value.cend(), attribute->value.float2_value); - attribute->value.type = DVR_SURFACE_ATTRIBUTE_TYPE_FLOAT2; - } - void operator()(const std::array<float, 3>& value) { - std::copy(value.cbegin(), value.cend(), attribute->value.float3_value); - attribute->value.type = DVR_SURFACE_ATTRIBUTE_TYPE_FLOAT3; - } - void operator()(const std::array<float, 4>& value) { - std::copy(value.cbegin(), value.cend(), attribute->value.float4_value); - attribute->value.type = DVR_SURFACE_ATTRIBUTE_TYPE_FLOAT4; - } - void operator()(const std::array<float, 8>& value) { - std::copy(value.cbegin(), value.cend(), attribute->value.float8_value); - attribute->value.type = DVR_SURFACE_ATTRIBUTE_TYPE_FLOAT8; - } - void operator()(const std::array<float, 16>& value) { - std::copy(value.cbegin(), value.cend(), attribute->value.float16_value); - attribute->value.type = DVR_SURFACE_ATTRIBUTE_TYPE_FLOAT16; - } - void operator()(EmptyVariant) { - attribute->value.type = DVR_SURFACE_ATTRIBUTE_TYPE_NONE; - } -}; - -size_t ConvertSurfaceAttributes(const SurfaceAttributes& surface_attributes, - DvrSurfaceAttribute* attributes, - size_t max_count) { - size_t count = 0; - for (const auto& attribute : surface_attributes) { - if (count >= max_count) - break; - - // Copy the key and extract the Variant value using a visitor. - attributes[count].key = attribute.first; - attribute.second.Visit(AttributeVisitor{&attributes[count]}); - count++; - } - - return count; -} - -} // anonymous namespace - -extern "C" { - -struct DvrDisplayManager { - std::unique_ptr<DisplayManagerClient> client; -}; - -struct DvrSurfaceState { - std::vector<SurfaceState> state; -}; - -int dvrDisplayManagerCreate(DvrDisplayManager** client_out) { - if (!client_out) - return -EINVAL; - - auto client = DisplayManagerClient::Create(); - if (!client) { - ALOGE("dvrDisplayManagerCreate: Failed to create display manager client!"); - return -EIO; - } - - *client_out = new DvrDisplayManager{std::move(client)}; - return 0; -} - -void dvrDisplayManagerDestroy(DvrDisplayManager* client) { delete client; } - -int dvrDisplayManagerGetEventFd(DvrDisplayManager* client) { - if (!client) - return -EINVAL; - - return client->client->event_fd(); -} - -int dvrDisplayManagerTranslateEpollEventMask(DvrDisplayManager* client, - int in_events, int* out_events) { - if (!client || !out_events) - return -EINVAL; - - auto status = client->client->GetEventMask(in_events); - if (!status) - return -status.error(); - - *out_events = status.get(); - return 0; -} - -int dvrDisplayManagerGetSurfaceState(DvrDisplayManager* client, - DvrSurfaceState* state) { - if (!client || !state) - return -EINVAL; - - auto status = client->client->GetSurfaceState(); - if (!status) - return -status.error(); - - state->state = status.take(); - return 0; -} - -int dvrDisplayManagerGetReadBufferQueue(DvrDisplayManager* client, - int surface_id, int queue_id, - DvrReadBufferQueue** queue_out) { - if (!client || !queue_out) - return -EINVAL; - - auto status = client->client->GetSurfaceQueue(surface_id, queue_id); - if (!status) { - ALOGE("dvrDisplayManagerGetReadBufferQueue: Failed to get queue: %s", - status.GetErrorMessage().c_str()); - return -status.error(); - } - - *queue_out = new DvrReadBufferQueue(status.take()); - return 0; -} - -int dvrSurfaceStateCreate(DvrSurfaceState** surface_state_out) { - if (!surface_state_out) - return -EINVAL; - - *surface_state_out = new DvrSurfaceState{}; - return 0; -} - -void dvrSurfaceStateDestroy(DvrSurfaceState* surface_state) { - delete surface_state; -} - -int dvrSurfaceStateGetSurfaceCount(DvrSurfaceState* surface_state, - size_t* count_out) { - if (!surface_state) - return -EINVAL; - - *count_out = surface_state->state.size(); - return 0; -} - -int dvrSurfaceStateGetUpdateFlags(DvrSurfaceState* surface_state, - size_t surface_index, - DvrSurfaceUpdateFlags* flags_out) { - if (!surface_state || surface_index >= surface_state->state.size()) - return -EINVAL; - - *flags_out = surface_state->state[surface_index].update_flags; - return 0; -} - -int dvrSurfaceStateGetSurfaceId(DvrSurfaceState* surface_state, - size_t surface_index, int* surface_id_out) { - if (!surface_state || surface_index >= surface_state->state.size()) - return -EINVAL; - - *surface_id_out = surface_state->state[surface_index].surface_id; - return 0; -} - -int dvrSurfaceStateGetProcessId(DvrSurfaceState* surface_state, - size_t surface_index, int* process_id_out) { - if (!surface_state || surface_index >= surface_state->state.size()) - return -EINVAL; - - *process_id_out = surface_state->state[surface_index].process_id; - return 0; -} - -int dvrSurfaceStateGetQueueCount(DvrSurfaceState* surface_state, - size_t surface_index, size_t* count_out) { - if (!surface_state || surface_index >= surface_state->state.size()) - return -EINVAL; - - *count_out = surface_state->state[surface_index].queue_ids.size(); - return 0; -} - -ssize_t dvrSurfaceStateGetQueueIds(DvrSurfaceState* surface_state, - size_t surface_index, int* queue_ids, - size_t max_count) { - if (!surface_state || surface_index >= surface_state->state.size()) - return -EINVAL; - - size_t i; - const auto& state = surface_state->state[surface_index]; - for (i = 0; i < std::min(max_count, state.queue_ids.size()); i++) { - queue_ids[i] = state.queue_ids[i]; - } - - return i; -} - -int dvrSurfaceStateGetZOrder(DvrSurfaceState* surface_state, - size_t surface_index, int* z_order_out) { - if (!surface_state || surface_index >= surface_state->state.size() || - !z_order_out) { - return -EINVAL; - } - - *z_order_out = surface_state->state[surface_index].GetZOrder(); - return 0; -} - -int dvrSurfaceStateGetVisible(DvrSurfaceState* surface_state, - size_t surface_index, bool* visible_out) { - if (!surface_state || surface_index >= surface_state->state.size() || - !visible_out) { - return -EINVAL; - } - - *visible_out = surface_state->state[surface_index].GetVisible(); - return 0; -} - -int dvrSurfaceStateGetAttributeCount(DvrSurfaceState* surface_state, - size_t surface_index, size_t* count_out) { - if (!surface_state || surface_index >= surface_state->state.size() || - !count_out) { - return -EINVAL; - } - - *count_out = surface_state->state[surface_index].surface_attributes.size(); - return 0; -} - -ssize_t dvrSurfaceStateGetAttributes(DvrSurfaceState* surface_state, - size_t surface_index, - DvrSurfaceAttribute* attributes, - size_t max_count) { - if (!surface_state || surface_index >= surface_state->state.size() || - !attributes) { - return -EINVAL; - } - - return ConvertSurfaceAttributes( - surface_state->state[surface_index].surface_attributes, attributes, - max_count); -} - -} // extern "C" diff --git a/libs/vr/libdvr/dvr_hardware_composer_client.cpp b/libs/vr/libdvr/dvr_hardware_composer_client.cpp deleted file mode 100644 index 4e87cf6b8f..0000000000 --- a/libs/vr/libdvr/dvr_hardware_composer_client.cpp +++ /dev/null @@ -1,267 +0,0 @@ -#include "include/dvr/dvr_hardware_composer_client.h" - -#include <android/dvr/IVrComposer.h> -#include <android/dvr/BnVrComposerCallback.h> -#include <android/hardware_buffer.h> -#include <binder/IServiceManager.h> -#include <private/android/AHardwareBufferHelpers.h> - -#include <functional> -#include <memory> -#include <mutex> - -struct DvrHwcFrame { - android::dvr::ComposerView::Frame frame; -}; - -namespace { - -class HwcCallback : public android::dvr::BnVrComposerCallback { - public: - using CallbackFunction = std::function<int(DvrHwcFrame*)>; - - explicit HwcCallback(const CallbackFunction& callback); - ~HwcCallback() override; - - // Reset the callback. This needs to be done early to avoid use after free - // accesses from binder thread callbacks. - void Shutdown(); - - std::unique_ptr<DvrHwcFrame> DequeueFrame(); - - private: - // android::dvr::BnVrComposerCallback: - android::binder::Status onNewFrame( - const android::dvr::ParcelableComposerFrame& frame, - android::dvr::ParcelableUniqueFd* fence) override; - - // Protects the |callback_| from uses from multiple threads. During shutdown - // there may be in-flight frame update events. In those cases the callback - // access needs to be protected otherwise binder threads may access an invalid - // callback. - std::mutex mutex_; - CallbackFunction callback_; - - HwcCallback(const HwcCallback&) = delete; - void operator=(const HwcCallback&) = delete; -}; - -HwcCallback::HwcCallback(const CallbackFunction& callback) - : callback_(callback) {} - -HwcCallback::~HwcCallback() {} - -void HwcCallback::Shutdown() { - std::lock_guard<std::mutex> guard(mutex_); - callback_ = nullptr; -} - -android::binder::Status HwcCallback::onNewFrame( - const android::dvr::ParcelableComposerFrame& frame, - android::dvr::ParcelableUniqueFd* fence) { - std::lock_guard<std::mutex> guard(mutex_); - - if (!callback_) { - fence->set_fence(android::base::unique_fd()); - return android::binder::Status::ok(); - } - - std::unique_ptr<DvrHwcFrame> dvr_frame(new DvrHwcFrame()); - dvr_frame->frame = frame.frame(); - - fence->set_fence(android::base::unique_fd(callback_(dvr_frame.release()))); - return android::binder::Status::ok(); -} - -} // namespace - -struct DvrHwcClient { - android::sp<android::dvr::IVrComposer> composer; - android::sp<HwcCallback> callback; -}; - -DvrHwcClient* dvrHwcClientCreate(DvrHwcOnFrameCallback callback, void* data) { - std::unique_ptr<DvrHwcClient> client(new DvrHwcClient()); - - android::sp<android::IServiceManager> sm(android::defaultServiceManager()); - client->composer = android::interface_cast<android::dvr::IVrComposer>( - sm->getService(android::dvr::IVrComposer::SERVICE_NAME())); - if (!client->composer.get()) - return nullptr; - - client->callback = new HwcCallback(std::bind(callback, data, - std::placeholders::_1)); - android::binder::Status status = client->composer->registerObserver( - client->callback); - if (!status.isOk()) - return nullptr; - - return client.release(); -} - -void dvrHwcClientDestroy(DvrHwcClient* client) { - client->composer->clearObserver(); - - // NOTE: Deleting DvrHwcClient* isn't enough since DvrHwcClient::callback is a - // shared pointer that could be referenced from a binder thread. But the - // client callback isn't valid past this calls so that needs to be reset. - client->callback->Shutdown(); - - delete client; -} - -void dvrHwcFrameDestroy(DvrHwcFrame* frame) { - delete frame; -} - -DvrHwcDisplay dvrHwcFrameGetDisplayId(DvrHwcFrame* frame) { - return frame->frame.display_id; -} - -int32_t dvrHwcFrameGetDisplayWidth(DvrHwcFrame* frame) { - return frame->frame.display_width; -} - -int32_t dvrHwcFrameGetDisplayHeight(DvrHwcFrame* frame) { - return frame->frame.display_height; -} - -bool dvrHwcFrameGetDisplayRemoved(DvrHwcFrame* frame) { - return frame->frame.removed; -} - -size_t dvrHwcFrameGetLayerCount(DvrHwcFrame* frame) { - return frame->frame.layers.size(); -} - -uint32_t dvrHwcFrameGetActiveConfig(DvrHwcFrame* frame) { - return static_cast<uint32_t>(frame->frame.active_config); -} - -uint32_t dvrHwcFrameGetColorMode(DvrHwcFrame* frame) { - return static_cast<uint32_t>(frame->frame.color_mode); -} - -void dvrHwcFrameGetColorTransform(DvrHwcFrame* frame, float* out_matrix, - int32_t* out_hint) { - *out_hint = frame->frame.color_transform_hint; - memcpy(out_matrix, frame->frame.color_transform, - sizeof(frame->frame.color_transform)); -} - -uint32_t dvrHwcFrameGetPowerMode(DvrHwcFrame* frame) { - return static_cast<uint32_t>(frame->frame.power_mode); -} - -uint32_t dvrHwcFrameGetVsyncEnabled(DvrHwcFrame* frame) { - return static_cast<uint32_t>(frame->frame.vsync_enabled); -} - -DvrHwcLayer dvrHwcFrameGetLayerId(DvrHwcFrame* frame, size_t layer_index) { - return frame->frame.layers[layer_index].id; -} - -AHardwareBuffer* dvrHwcFrameGetLayerBuffer(DvrHwcFrame* frame, - size_t layer_index) { - AHardwareBuffer* buffer = android::AHardwareBuffer_from_GraphicBuffer( - frame->frame.layers[layer_index].buffer.get()); - AHardwareBuffer_acquire(buffer); - return buffer; -} - -int dvrHwcFrameGetLayerFence(DvrHwcFrame* frame, size_t layer_index) { - return frame->frame.layers[layer_index].fence->dup(); -} - -DvrHwcRecti dvrHwcFrameGetLayerDisplayFrame(DvrHwcFrame* frame, - size_t layer_index) { - return DvrHwcRecti{ - frame->frame.layers[layer_index].display_frame.left, - frame->frame.layers[layer_index].display_frame.top, - frame->frame.layers[layer_index].display_frame.right, - frame->frame.layers[layer_index].display_frame.bottom, - }; -} - -DvrHwcRectf dvrHwcFrameGetLayerCrop(DvrHwcFrame* frame, size_t layer_index) { - return DvrHwcRectf{ - frame->frame.layers[layer_index].crop.left, - frame->frame.layers[layer_index].crop.top, - frame->frame.layers[layer_index].crop.right, - frame->frame.layers[layer_index].crop.bottom, - }; -} - -DvrHwcBlendMode dvrHwcFrameGetLayerBlendMode(DvrHwcFrame* frame, - size_t layer_index) { - return static_cast<DvrHwcBlendMode>( - frame->frame.layers[layer_index].blend_mode); -} - -float dvrHwcFrameGetLayerAlpha(DvrHwcFrame* frame, size_t layer_index) { - return frame->frame.layers[layer_index].alpha; -} - -uint32_t dvrHwcFrameGetLayerType(DvrHwcFrame* frame, size_t layer_index) { - return frame->frame.layers[layer_index].type; -} - -uint32_t dvrHwcFrameGetLayerApplicationId(DvrHwcFrame* frame, - size_t layer_index) { - return frame->frame.layers[layer_index].app_id; -} - -uint32_t dvrHwcFrameGetLayerZOrder(DvrHwcFrame* frame, size_t layer_index) { - return frame->frame.layers[layer_index].z_order; -} - -void dvrHwcFrameGetLayerCursor(DvrHwcFrame* frame, size_t layer_index, - int32_t* out_x, int32_t* out_y) { - *out_x = frame->frame.layers[layer_index].cursor_x; - *out_y = frame->frame.layers[layer_index].cursor_y; -} - -uint32_t dvrHwcFrameGetLayerTransform(DvrHwcFrame* frame, size_t layer_index) { - return frame->frame.layers[layer_index].transform; -} - -uint32_t dvrHwcFrameGetLayerDataspace(DvrHwcFrame* frame, size_t layer_index) { - return frame->frame.layers[layer_index].dataspace; -} - -uint32_t dvrHwcFrameGetLayerColor(DvrHwcFrame* frame, size_t layer_index) { - const auto& color = frame->frame.layers[layer_index].color; - return color.r | (static_cast<uint32_t>(color.g) << 8) | - (static_cast<uint32_t>(color.b) << 16) | - (static_cast<uint32_t>(color.a) << 24); -} - -uint32_t dvrHwcFrameGetLayerNumVisibleRegions(DvrHwcFrame* frame, - size_t layer_index) { - return frame->frame.layers[layer_index].visible_regions.size(); -} - -DvrHwcRecti dvrHwcFrameGetLayerVisibleRegion(DvrHwcFrame* frame, - size_t layer_index, size_t index) { - return DvrHwcRecti{ - frame->frame.layers[layer_index].visible_regions[index].left, - frame->frame.layers[layer_index].visible_regions[index].top, - frame->frame.layers[layer_index].visible_regions[index].right, - frame->frame.layers[layer_index].visible_regions[index].bottom, - }; -} - -uint32_t dvrHwcFrameGetLayerNumDamagedRegions(DvrHwcFrame* frame, - size_t layer_index) { - return frame->frame.layers[layer_index].damaged_regions.size(); -} - -DvrHwcRecti dvrHwcFrameGetLayerDamagedRegion(DvrHwcFrame* frame, - size_t layer_index, size_t index) { - return DvrHwcRecti{ - frame->frame.layers[layer_index].damaged_regions[index].left, - frame->frame.layers[layer_index].damaged_regions[index].top, - frame->frame.layers[layer_index].damaged_regions[index].right, - frame->frame.layers[layer_index].damaged_regions[index].bottom, - }; -} diff --git a/libs/vr/libdvr/dvr_internal.h b/libs/vr/libdvr/dvr_internal.h deleted file mode 100644 index f845cd896d..0000000000 --- a/libs/vr/libdvr/dvr_internal.h +++ /dev/null @@ -1,53 +0,0 @@ -#ifndef ANDROID_DVR_INTERNAL_H_ -#define ANDROID_DVR_INTERNAL_H_ - -#include <sys/cdefs.h> - -#include <memory> - -extern "C" { - -typedef struct DvrBuffer DvrBuffer; -typedef struct DvrReadBuffer DvrReadBuffer; -typedef struct DvrWriteBuffer DvrWriteBuffer; - -} // extern "C" - -namespace android { -namespace dvr { - -class IonBuffer; - -DvrBuffer* CreateDvrBufferFromIonBuffer( - const std::shared_ptr<IonBuffer>& ion_buffer); - -} // namespace dvr -} // namespace android - -extern "C" { - -struct DvrWriteBuffer { - // The slot nubmer of the buffer, a valid slot number must be in the range of - // [0, android::BufferQueueDefs::NUM_BUFFER_SLOTS). This is only valid for - // DvrWriteBuffer acquired from a DvrWriteBufferQueue. - int32_t slot = -1; - - std::shared_ptr<android::dvr::ProducerBuffer> write_buffer; -}; - -struct DvrReadBuffer { - // The slot nubmer of the buffer, a valid slot number must be in the range of - // [0, android::BufferQueueDefs::NUM_BUFFER_SLOTS). This is only valid for - // DvrReadBuffer acquired from a DvrReadBufferQueue. - int32_t slot = -1; - - std::shared_ptr<android::dvr::ConsumerBuffer> read_buffer; -}; - -struct DvrBuffer { - std::shared_ptr<android::dvr::IonBuffer> buffer; -}; - -} // extern "C" - -#endif // ANDROID_DVR_INTERNAL_H_ diff --git a/libs/vr/libdvr/dvr_performance.cpp b/libs/vr/libdvr/dvr_performance.cpp deleted file mode 100644 index 599101fea3..0000000000 --- a/libs/vr/libdvr/dvr_performance.cpp +++ /dev/null @@ -1,18 +0,0 @@ -#include "include/dvr/dvr_performance.h" - -#include <private/dvr/performance_client.h> - -using android::dvr::PerformanceClient; - -extern "C" { - -int dvrPerformanceSetSchedulerPolicy(pid_t task_id, - const char* scheduler_policy) { - int error; - if (auto client = PerformanceClient::Create(&error)) - return client->SetSchedulerPolicy(task_id, scheduler_policy); - else - return error; -} - -} // extern "C" diff --git a/libs/vr/libdvr/dvr_pose.cpp b/libs/vr/libdvr/dvr_pose.cpp deleted file mode 100644 index c379ef55e8..0000000000 --- a/libs/vr/libdvr/dvr_pose.cpp +++ /dev/null @@ -1,29 +0,0 @@ -#include "include/dvr/dvr_pose.h" - -#include <memory> - -#include <private/dvr/buffer_hub_queue_client.h> -#include <private/dvr/pose_client_internal.h> - -#include "dvr_buffer_queue_internal.h" - -using android::dvr::ConsumerQueue; - -int dvrPoseClientGetDataReader(DvrPoseClient* client, uint64_t data_type, - DvrReadBufferQueue** queue_out) { - if (!client || !queue_out) - return -EINVAL; - - ConsumerQueue* consumer_queue; - int status = android::dvr::dvrPoseClientGetDataReaderHandle(client, - data_type, - &consumer_queue); - if (status != 0) { - ALOGE("dvrPoseClientGetDataReader: Failed to get queue: %d", status); - return status; - } - - std::shared_ptr<ConsumerQueue> consumer_queue_ptr{consumer_queue}; - *queue_out = new DvrReadBufferQueue(consumer_queue_ptr); - return 0; -} diff --git a/libs/vr/libdvr/dvr_surface.cpp b/libs/vr/libdvr/dvr_surface.cpp deleted file mode 100644 index 0c7ec01640..0000000000 --- a/libs/vr/libdvr/dvr_surface.cpp +++ /dev/null @@ -1,277 +0,0 @@ -#include "include/dvr/dvr_surface.h" - -#include <inttypes.h> - -#include <pdx/rpc/variant.h> -#include <private/android/AHardwareBufferHelpers.h> -#include <private/dvr/display_client.h> - -#include "dvr_buffer_queue_internal.h" -#include "dvr_internal.h" - -using android::AHardwareBuffer_convertToGrallocUsageBits; -using android::dvr::display::DisplayClient; -using android::dvr::display::Surface; -using android::dvr::display::SurfaceAttributes; -using android::dvr::display::SurfaceAttributeValue; -using android::pdx::rpc::EmptyVariant; - -namespace { - -// Sets the Variant |destination| to the target std::array type and copies the C -// array into it. Unsupported std::array configurations will fail to compile. -template <typename T, std::size_t N> -void ArrayCopy(SurfaceAttributeValue* destination, const T (&source)[N]) { - using ArrayType = std::array<T, N>; - *destination = ArrayType{}; - std::copy(std::begin(source), std::end(source), - std::get<ArrayType>(*destination).begin()); -} - -bool ConvertSurfaceAttributes(const DvrSurfaceAttribute* attributes, - size_t attribute_count, - SurfaceAttributes* surface_attributes, - size_t* error_index) { - for (size_t i = 0; i < attribute_count; i++) { - SurfaceAttributeValue value; - switch (attributes[i].value.type) { - case DVR_SURFACE_ATTRIBUTE_TYPE_INT32: - value = attributes[i].value.int32_value; - break; - case DVR_SURFACE_ATTRIBUTE_TYPE_INT64: - value = attributes[i].value.int64_value; - break; - case DVR_SURFACE_ATTRIBUTE_TYPE_BOOL: - // bool_value is defined in an extern "C" block, which makes it look - // like an int to C++. Use a cast to assign the correct type to the - // Variant type SurfaceAttributeValue. - value = static_cast<bool>(attributes[i].value.bool_value); - break; - case DVR_SURFACE_ATTRIBUTE_TYPE_FLOAT: - value = attributes[i].value.float_value; - break; - case DVR_SURFACE_ATTRIBUTE_TYPE_FLOAT2: - ArrayCopy(&value, attributes[i].value.float2_value); - break; - case DVR_SURFACE_ATTRIBUTE_TYPE_FLOAT3: - ArrayCopy(&value, attributes[i].value.float3_value); - break; - case DVR_SURFACE_ATTRIBUTE_TYPE_FLOAT4: - ArrayCopy(&value, attributes[i].value.float4_value); - break; - case DVR_SURFACE_ATTRIBUTE_TYPE_FLOAT8: - ArrayCopy(&value, attributes[i].value.float8_value); - break; - case DVR_SURFACE_ATTRIBUTE_TYPE_FLOAT16: - ArrayCopy(&value, attributes[i].value.float16_value); - break; - case DVR_SURFACE_ATTRIBUTE_TYPE_NONE: - value = EmptyVariant{}; - break; - default: - *error_index = i; - return false; - } - - surface_attributes->emplace(attributes[i].key, value); - } - - return true; -} - -} // anonymous namespace - -extern "C" { - -struct DvrSurface { - std::unique_ptr<Surface> surface; -}; - -int dvrSurfaceCreate(const DvrSurfaceAttribute* attributes, - size_t attribute_count, DvrSurface** out_surface) { - if (out_surface == nullptr) { - ALOGE("dvrSurfaceCreate: Invalid inputs: out_surface=%p.", out_surface); - return -EINVAL; - } - - size_t error_index; - SurfaceAttributes surface_attributes; - if (!ConvertSurfaceAttributes(attributes, attribute_count, - &surface_attributes, &error_index)) { - ALOGE("dvrSurfaceCreate: Invalid surface attribute type: %" PRIu64, - attributes[error_index].value.type); - return -EINVAL; - } - - auto status = Surface::CreateSurface(surface_attributes); - if (!status) { - ALOGE("dvrSurfaceCreate:: Failed to create display surface: %s", - status.GetErrorMessage().c_str()); - return -status.error(); - } - - *out_surface = new DvrSurface{status.take()}; - return 0; -} - -void dvrSurfaceDestroy(DvrSurface* surface) { delete surface; } - -int dvrSurfaceGetId(DvrSurface* surface) { - return surface->surface->surface_id(); -} - -int dvrSurfaceSetAttributes(DvrSurface* surface, - const DvrSurfaceAttribute* attributes, - size_t attribute_count) { - if (surface == nullptr || attributes == nullptr) { - ALOGE( - "dvrSurfaceSetAttributes: Invalid inputs: surface=%p attributes=%p " - "attribute_count=%zu", - surface, attributes, attribute_count); - return -EINVAL; - } - - size_t error_index; - SurfaceAttributes surface_attributes; - if (!ConvertSurfaceAttributes(attributes, attribute_count, - &surface_attributes, &error_index)) { - ALOGE("dvrSurfaceSetAttributes: Invalid surface attribute type: %" PRIu64, - attributes[error_index].value.type); - return -EINVAL; - } - - auto status = surface->surface->SetAttributes(surface_attributes); - if (!status) { - ALOGE("dvrSurfaceSetAttributes: Failed to set attributes: %s", - status.GetErrorMessage().c_str()); - return -status.error(); - } - - return 0; -} - -int dvrSurfaceCreateWriteBufferQueue(DvrSurface* surface, uint32_t width, - uint32_t height, uint32_t format, - uint32_t layer_count, uint64_t usage, - size_t capacity, size_t metadata_size, - DvrWriteBufferQueue** out_writer) { - if (surface == nullptr || out_writer == nullptr) { - ALOGE( - "dvrSurfaceCreateWriteBufferQueue: Invalid inputs: surface=%p, " - "out_writer=%p.", - surface, out_writer); - return -EINVAL; - } - - auto status = surface->surface->CreateQueue( - width, height, layer_count, format, usage, capacity, metadata_size); - if (!status) { - ALOGE("dvrSurfaceCreateWriteBufferQueue: Failed to create queue: %s", - status.GetErrorMessage().c_str()); - return -status.error(); - } - - *out_writer = new DvrWriteBufferQueue(status.take()); - return 0; -} - -int dvrSetupGlobalBuffer(DvrGlobalBufferKey key, size_t size, uint64_t usage, - DvrBuffer** buffer_out) { - if (!buffer_out) - return -EINVAL; - - int error; - auto client = DisplayClient::Create(&error); - if (!client) { - ALOGE("dvrSetupGlobalBuffer: Failed to create display client: %s", - strerror(-error)); - return error; - } - - uint64_t gralloc_usage = AHardwareBuffer_convertToGrallocUsageBits(usage); - - auto buffer_status = client->SetupGlobalBuffer(key, size, gralloc_usage); - if (!buffer_status) { - ALOGE("dvrSetupGlobalBuffer: Failed to setup global buffer: %s", - buffer_status.GetErrorMessage().c_str()); - return -buffer_status.error(); - } - - *buffer_out = CreateDvrBufferFromIonBuffer(buffer_status.take()); - return 0; -} - -int dvrDeleteGlobalBuffer(DvrGlobalBufferKey key) { - int error; - auto client = DisplayClient::Create(&error); - if (!client) { - ALOGE("dvrDeleteGlobalBuffer: Failed to create display client: %s", - strerror(-error)); - return error; - } - - auto buffer_status = client->DeleteGlobalBuffer(key); - if (!buffer_status) { - ALOGE("dvrDeleteGlobalBuffer: Failed to delete named buffer: %s", - buffer_status.GetErrorMessage().c_str()); - return -buffer_status.error(); - } - - return 0; -} - -int dvrGetGlobalBuffer(DvrGlobalBufferKey key, DvrBuffer** out_buffer) { - if (!out_buffer) - return -EINVAL; - - int error; - auto client = DisplayClient::Create(&error); - if (!client) { - ALOGE("dvrGetGlobalBuffer: Failed to create display client: %s", - strerror(-error)); - return error; - } - - auto status = client->GetGlobalBuffer(key); - if (!status) { - return -status.error(); - } - *out_buffer = CreateDvrBufferFromIonBuffer(status.take()); - return 0; -} - -int dvrGetNativeDisplayMetrics(size_t sizeof_metrics, - DvrNativeDisplayMetrics* metrics) { - ALOGE_IF(sizeof_metrics != sizeof(DvrNativeDisplayMetrics), - "dvrGetNativeDisplayMetrics: metrics struct mismatch, your dvr api " - "header is out of date."); - - auto client = DisplayClient::Create(); - if (!client) { - ALOGE("dvrGetNativeDisplayMetrics: Failed to create display client!"); - return -ECOMM; - } - - if (metrics == nullptr) { - ALOGE("dvrGetNativeDisplayMetrics: output metrics buffer must be non-null"); - return -EINVAL; - } - - auto status = client->GetDisplayMetrics(); - - if (!status) { - return -status.error(); - } - - if (sizeof_metrics >= 20) { - metrics->display_width = status.get().display_width; - metrics->display_height = status.get().display_height; - metrics->display_x_dpi = status.get().display_x_dpi; - metrics->display_y_dpi = status.get().display_y_dpi; - metrics->vsync_period_ns = status.get().vsync_period_ns; - } - - return 0; -} - -} // extern "C" diff --git a/libs/vr/libdvr/dvr_tracking.cpp b/libs/vr/libdvr/dvr_tracking.cpp deleted file mode 100644 index 73addc9a0c..0000000000 --- a/libs/vr/libdvr/dvr_tracking.cpp +++ /dev/null @@ -1,82 +0,0 @@ -#include "include/dvr/dvr_tracking.h" - -#include <utils/Errors.h> -#include <utils/Log.h> - -#if !DVR_TRACKING_IMPLEMENTED - -extern "C" { - -// This file provides the stub implementation of dvrTrackingXXX APIs. On -// platforms that implement these APIs, set -DDVR_TRACKING_IMPLEMENTED=1 in the -// build file. -int dvrTrackingCameraCreate(DvrTrackingCamera**) { - ALOGE("dvrTrackingCameraCreate is not implemented."); - return -ENOSYS; -} - -void dvrTrackingCameraDestroy(DvrTrackingCamera*) { - ALOGE("dvrTrackingCameraDestroy is not implemented."); -} - -int dvrTrackingCameraStart(DvrTrackingCamera*, DvrWriteBufferQueue*) { - ALOGE("dvrTrackingCameraCreate is not implemented."); - return -ENOSYS; -} - -int dvrTrackingCameraStop(DvrTrackingCamera*) { - ALOGE("dvrTrackingCameraCreate is not implemented."); - return -ENOSYS; -} - -int dvrTrackingFeatureExtractorCreate(DvrTrackingFeatureExtractor**) { - ALOGE("dvrTrackingFeatureExtractorCreate is not implemented."); - return -ENOSYS; -} - -void dvrTrackingFeatureExtractorDestroy(DvrTrackingFeatureExtractor*) { - ALOGE("dvrTrackingFeatureExtractorDestroy is not implemented."); -} - -int dvrTrackingFeatureExtractorStart(DvrTrackingFeatureExtractor*, - DvrTrackingFeatureCallback, void*) { - ALOGE("dvrTrackingFeatureExtractorCreate is not implemented."); - return -ENOSYS; -} - -int dvrTrackingFeatureExtractorStop(DvrTrackingFeatureExtractor*) { - ALOGE("dvrTrackingFeatureExtractorCreate is not implemented."); - return -ENOSYS; -} - -int dvrTrackingFeatureExtractorProcessBuffer(DvrTrackingFeatureExtractor*, - DvrReadBuffer*, - const DvrTrackingBufferMetadata*, - bool*) { - ALOGE("dvrTrackingFeatureExtractorProcessBuffer is not implemented."); - return -ENOSYS; -} - -int dvrTrackingSensorsCreate(DvrTrackingSensors**, const char*) { - ALOGE("dvrTrackingSensorsCreate is not implemented."); - return -ENOSYS; -} - -void dvrTrackingSensorsDestroy(DvrTrackingSensors*) { - ALOGE("dvrTrackingSensorsDestroy is not implemented."); -} - -int dvrTrackingSensorsStart(DvrTrackingSensors*, DvrTrackingSensorEventCallback, - void*) { - ALOGE("dvrTrackingStart is not implemented."); - return -ENOSYS; -} - -int dvrTrackingSensorsStop(DvrTrackingSensors*) { - ALOGE("dvrTrackingStop is not implemented."); - return -ENOSYS; -} - -} // extern "C" - -#endif // DVR_TRACKING_IMPLEMENTED diff --git a/libs/vr/libdvr/exported_apis.lds b/libs/vr/libdvr/exported_apis.lds deleted file mode 100644 index 5ecb49861c..0000000000 --- a/libs/vr/libdvr/exported_apis.lds +++ /dev/null @@ -1,9 +0,0 @@ -{ - global: - # Whitelist the function to load the dvr api. - dvrGetApi; - - local: - # Hide everything else. - *; -}; diff --git a/libs/vr/libdvr/tests/Android.bp b/libs/vr/libdvr/tests/Android.bp deleted file mode 100644 index fe7feb824d..0000000000 --- a/libs/vr/libdvr/tests/Android.bp +++ /dev/null @@ -1,113 +0,0 @@ -// Copyright (C) 2017 The Android Open Source Project -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -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_test { - srcs: [ - "dvr_display_manager-test.cpp", - "dvr_named_buffer-test.cpp", - "dvr_tracking-test.cpp", - ], - - header_libs: ["libdvr_headers"], - static_libs: [ - "libdvr_static.google", - "libchrome", - "libdvrcommon", - "libdisplay", - "libbroadcastring", - ], - shared_libs: [ - "libbase", - "libbinder", - "libbufferhubqueue", - "libcutils", - "libgui", - "liblog", - "libhardware", - "libui", - "libutils", - "libnativewindow", - "libpdx_default_transport", - ], - cflags: [ - "-DDVR_TRACKING_IMPLEMENTED=0", - "-DLOG_TAG=\"dvr_api-test\"", - "-DTRACE=0", - "-Wno-missing-field-initializers", - "-O0", - "-g", - ], - name: "dvr_api-test", -} - -cc_test { - name: "dvr_buffer_queue-test", - - // Includes the dvr_api.h header. Tests should only include "dvr_api.h", - // and shall only get access to |dvrGetApi|, as other symbols are hidden - // from the library. - include_dirs: ["frameworks/native/libs/vr/libdvr/include"], - - srcs: ["dvr_buffer_queue-test.cpp"], - - shared_libs: [ - "libandroid", - "liblog", - ], - - cflags: [ - "-DTRACE=0", - "-O2", - "-g", - ], - - // DTS Should only link to NDK libraries. - sdk_version: "26", - stl: "c++_static", -} - -cc_test { - name: "dvr_display-test", - - include_dirs: [ - "frameworks/native/libs/vr/libdvr/include", - "frameworks/native/libs/nativewindow/include", - ], - - srcs: ["dvr_display-test.cpp"], - - shared_libs: [ - "libandroid", - "liblog", - ], - - cflags: [ - "-DTRACE=0", - "-O2", - "-g", - ], - - // DTS Should only link to NDK libraries. - sdk_version: "26", - stl: "c++_static", -} diff --git a/libs/vr/libdvr/tests/dvr_api_test.h b/libs/vr/libdvr/tests/dvr_api_test.h deleted file mode 100644 index 5d2ec285eb..0000000000 --- a/libs/vr/libdvr/tests/dvr_api_test.h +++ /dev/null @@ -1,36 +0,0 @@ -#include <dlfcn.h> -#include <dvr/dvr_api.h> - -#include <gtest/gtest.h> - -/** DvrTestBase loads the libdvr.so at runtime and get the Dvr API version 1. */ -class DvrApiTest : public ::testing::Test { - protected: - void SetUp() override { - int flags = RTLD_NOW | RTLD_LOCAL; - - // Here we need to ensure that libdvr is loaded with RTLD_NODELETE flag set - // (so that calls to `dlclose` don't actually unload the library). This is a - // workaround for an Android NDK bug. See more detail: - // https://github.com/android-ndk/ndk/issues/360 - flags |= RTLD_NODELETE; - platform_handle_ = dlopen("libdvr.google.so", flags); - ASSERT_NE(nullptr, platform_handle_) << "Dvr shared library missing."; - - auto dvr_get_api = reinterpret_cast<decltype(&dvrGetApi)>( - dlsym(platform_handle_, "dvrGetApi")); - ASSERT_NE(nullptr, dvr_get_api) << "Platform library missing dvrGetApi."; - - ASSERT_EQ(dvr_get_api(&api_, sizeof(api_), /*version=*/1), 0) - << "Unable to find compatible Dvr API."; - } - - void TearDown() override { - if (platform_handle_ != nullptr) { - dlclose(platform_handle_); - } - } - - void* platform_handle_ = nullptr; - DvrApi_v1 api_; -}; diff --git a/libs/vr/libdvr/tests/dvr_buffer_queue-test.cpp b/libs/vr/libdvr/tests/dvr_buffer_queue-test.cpp deleted file mode 100644 index df060973ec..0000000000 --- a/libs/vr/libdvr/tests/dvr_buffer_queue-test.cpp +++ /dev/null @@ -1,579 +0,0 @@ -#include <android/log.h> -#include <android/native_window.h> -#include <dvr/dvr_api.h> -#include <dvr/dvr_buffer_queue.h> - -#include <gtest/gtest.h> - -#include <array> -#include <unordered_map> - -#include "dvr_api_test.h" - -#define LOG_TAG "dvr_buffer_queue-test" - -#ifndef ALOGD -#define ALOGD(...) __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, __VA_ARGS__) -#endif - -#ifndef ALOGD_IF -#define ALOGD_IF(cond, ...) \ - ((__predict_false(cond)) ? ((void)ALOGD(__VA_ARGS__)) : (void)0) -#endif - -namespace { - -static constexpr uint32_t kBufferWidth = 100; -static constexpr uint32_t kBufferHeight = 1; -static constexpr uint32_t kLayerCount = 1; -static constexpr uint32_t kBufferFormat = AHARDWAREBUFFER_FORMAT_BLOB; -static constexpr uint64_t kBufferUsage = AHARDWAREBUFFER_USAGE_CPU_READ_OFTEN; -static constexpr size_t kQueueCapacity = 3; - -class DvrBufferQueueTest : public DvrApiTest { - public: - static void BufferAvailableCallback(void* context) { - DvrBufferQueueTest* thiz = static_cast<DvrBufferQueueTest*>(context); - thiz->HandleBufferAvailable(); - } - - static void BufferRemovedCallback(DvrReadBuffer* buffer, void* context) { - DvrBufferQueueTest* thiz = static_cast<DvrBufferQueueTest*>(context); - thiz->HandleBufferRemoved(buffer); - } - - protected: - void TearDown() override { - if (write_queue_ != nullptr) { - api_.WriteBufferQueueDestroy(write_queue_); - write_queue_ = nullptr; - } - DvrApiTest::TearDown(); - } - - void HandleBufferAvailable() { - buffer_available_count_ += 1; - ALOGD_IF(TRACE, "Buffer avaiable, count=%d", buffer_available_count_); - } - - void HandleBufferRemoved(DvrReadBuffer* buffer) { - buffer_removed_count_ += 1; - ALOGD_IF(TRACE, "Buffer removed, buffer=%p, count=%d", buffer, - buffer_removed_count_); - } - - DvrWriteBufferQueue* write_queue_ = nullptr; - int buffer_available_count_{0}; - int buffer_removed_count_{0}; -}; - -TEST_F(DvrBufferQueueTest, WriteQueueCreateDestroy) { - int ret = api_.WriteBufferQueueCreate( - kBufferWidth, kBufferHeight, kBufferFormat, kLayerCount, kBufferUsage, - /*capacity=*/0, sizeof(DvrNativeBufferMetadata), &write_queue_); - ASSERT_EQ(0, ret); - - api_.WriteBufferQueueDestroy(write_queue_); - write_queue_ = nullptr; -} - -TEST_F(DvrBufferQueueTest, WriteQueueGetCapacity) { - int ret = api_.WriteBufferQueueCreate( - kBufferWidth, kBufferHeight, kBufferFormat, kLayerCount, kBufferUsage, - kQueueCapacity, sizeof(DvrNativeBufferMetadata), &write_queue_); - ASSERT_EQ(0, ret); - - size_t capacity = api_.WriteBufferQueueGetCapacity(write_queue_); - - ALOGD_IF(TRACE, "TestWrite_QueueGetCapacity, capacity=%zu", capacity); - ASSERT_EQ(kQueueCapacity, capacity); -} - -TEST_F(DvrBufferQueueTest, CreateReadQueueFromWriteQueue) { - int ret = api_.WriteBufferQueueCreate( - kBufferWidth, kBufferHeight, kBufferFormat, kLayerCount, kBufferUsage, - /*capacity=*/0, sizeof(DvrNativeBufferMetadata), &write_queue_); - ASSERT_EQ(0, ret); - - DvrReadBufferQueue* read_queue = nullptr; - ret = api_.WriteBufferQueueCreateReadQueue(write_queue_, &read_queue); - - ASSERT_EQ(0, ret); - ASSERT_NE(nullptr, read_queue); - - api_.ReadBufferQueueDestroy(read_queue); -} - -TEST_F(DvrBufferQueueTest, CreateReadQueueFromReadQueue) { - int ret = api_.WriteBufferQueueCreate( - kBufferWidth, kBufferHeight, kBufferFormat, kLayerCount, kBufferUsage, - /*capacity=*/0, sizeof(DvrNativeBufferMetadata), &write_queue_); - ASSERT_EQ(0, ret); - - DvrReadBufferQueue* read_queue1 = nullptr; - DvrReadBufferQueue* read_queue2 = nullptr; - ret = api_.WriteBufferQueueCreateReadQueue(write_queue_, &read_queue1); - - ASSERT_EQ(0, ret); - ASSERT_NE(nullptr, read_queue1); - - ret = api_.ReadBufferQueueCreateReadQueue(read_queue1, &read_queue2); - ASSERT_EQ(0, ret); - ASSERT_NE(nullptr, read_queue2); - ASSERT_NE(read_queue1, read_queue2); - - api_.ReadBufferQueueDestroy(read_queue1); - api_.ReadBufferQueueDestroy(read_queue2); -} - -TEST_F(DvrBufferQueueTest, GainBuffer) { - int ret = api_.WriteBufferQueueCreate( - kBufferWidth, kBufferHeight, kBufferFormat, kLayerCount, kBufferUsage, - kQueueCapacity, sizeof(DvrNativeBufferMetadata), &write_queue_); - ASSERT_EQ(ret, 0); - - DvrWriteBuffer* wb = nullptr; - EXPECT_FALSE(api_.WriteBufferIsValid(wb)); - - DvrNativeBufferMetadata meta; - int fence_fd = -1; - ret = api_.WriteBufferQueueGainBuffer(write_queue_, /*timeout=*/0, &wb, &meta, - &fence_fd); - ASSERT_EQ(ret, 0); - EXPECT_EQ(fence_fd, -1); - EXPECT_NE(wb, nullptr); - EXPECT_TRUE(api_.WriteBufferIsValid(wb)); -} - -TEST_F(DvrBufferQueueTest, AcquirePostGainRelease) { - int ret = api_.WriteBufferQueueCreate( - kBufferWidth, kBufferHeight, kBufferFormat, kLayerCount, kBufferUsage, - kQueueCapacity, sizeof(DvrNativeBufferMetadata), &write_queue_); - ASSERT_EQ(ret, 0); - - DvrReadBufferQueue* read_queue = nullptr; - DvrReadBuffer* rb = nullptr; - DvrWriteBuffer* wb = nullptr; - DvrNativeBufferMetadata meta1; - DvrNativeBufferMetadata meta2; - int fence_fd = -1; - - ret = api_.WriteBufferQueueCreateReadQueue(write_queue_, &read_queue); - - ASSERT_EQ(ret, 0); - ASSERT_NE(read_queue, nullptr); - - api_.ReadBufferQueueSetBufferAvailableCallback( - read_queue, &BufferAvailableCallback, this); - - // Gain buffer for writing. - ret = api_.WriteBufferQueueGainBuffer(write_queue_, /*timeout=*/0, &wb, - &meta1, &fence_fd); - ASSERT_EQ(ret, 0); - ASSERT_NE(wb, nullptr); - ASSERT_TRUE(api_.WriteBufferIsValid(wb)); - ALOGD_IF(TRACE, "TestDequeuePostDequeueRelease, gain buffer %p, fence_fd=%d", - wb, fence_fd); - close(fence_fd); - - // Post buffer to the read_queue. - meta1.timestamp = 42; - ret = api_.WriteBufferQueuePostBuffer(write_queue_, wb, &meta1, /*fence=*/-1); - ASSERT_EQ(ret, 0); - ASSERT_FALSE(api_.WriteBufferIsValid(wb)); - wb = nullptr; - - // Acquire buffer for reading. - ret = api_.ReadBufferQueueAcquireBuffer(read_queue, /*timeout=*/10, &rb, - &meta2, &fence_fd); - ASSERT_EQ(ret, 0); - ASSERT_NE(rb, nullptr); - - // Dequeue is successfully, BufferAvailableCallback should be fired once. - ASSERT_EQ(buffer_available_count_, 1); - ASSERT_TRUE(api_.ReadBufferIsValid(rb)); - - // Metadata should be passed along from producer to consumer properly. - ASSERT_EQ(meta1.timestamp, meta2.timestamp); - - ALOGD_IF(TRACE, - "TestDequeuePostDequeueRelease, acquire buffer %p, fence_fd=%d", rb, - fence_fd); - close(fence_fd); - - // Release buffer to the write_queue. - ret = api_.ReadBufferQueueReleaseBuffer(read_queue, rb, &meta2, - /*release_fence_fd=*/-1); - ASSERT_EQ(ret, 0); - ASSERT_FALSE(api_.ReadBufferIsValid(rb)); - rb = nullptr; - - // TODO(b/34387835) Currently buffer allocation has to happen after all queues - // are initialized. - size_t capacity = api_.ReadBufferQueueGetCapacity(read_queue); - - ALOGD_IF(TRACE, "TestDequeuePostDequeueRelease, capacity=%zu", capacity); - ASSERT_EQ(kQueueCapacity, capacity); - - api_.ReadBufferQueueDestroy(read_queue); -} - -TEST_F(DvrBufferQueueTest, GetANativeWindow) { - int ret = api_.WriteBufferQueueCreate( - kBufferWidth, kBufferHeight, kBufferFormat, kLayerCount, kBufferUsage, - /*capacity=*/0, /*user_metadata_size=*/0, &write_queue_); - ASSERT_EQ(0, ret); - ASSERT_NE(nullptr, write_queue_); - - ANativeWindow* window = nullptr; - ret = api_.WriteBufferQueueGetANativeWindow(write_queue_, &window); - ASSERT_EQ(0, ret); - ASSERT_NE(nullptr, window); - - uint32_t width = ANativeWindow_getWidth(window); - uint32_t height = ANativeWindow_getHeight(window); - uint32_t format = ANativeWindow_getFormat(window); - ASSERT_EQ(kBufferWidth, width); - ASSERT_EQ(kBufferHeight, height); - ASSERT_EQ(kBufferFormat, format); -} - -// Create buffer queue of three buffers and dequeue three buffers out of it. -// Before each dequeue operation, we resize the buffer queue and expect the -// queue always return buffer with desired dimension. -TEST_F(DvrBufferQueueTest, ResizeBuffer) { - int ret = api_.WriteBufferQueueCreate( - kBufferWidth, kBufferHeight, kBufferFormat, kLayerCount, kBufferUsage, - kQueueCapacity, sizeof(DvrNativeBufferMetadata), &write_queue_); - ASSERT_EQ(0, ret); - - int fence_fd = -1; - - DvrNativeBufferMetadata meta; - DvrReadBufferQueue* read_queue = nullptr; - DvrWriteBuffer* wb1 = nullptr; - DvrWriteBuffer* wb2 = nullptr; - DvrWriteBuffer* wb3 = nullptr; - AHardwareBuffer* ahb1 = nullptr; - AHardwareBuffer* ahb2 = nullptr; - AHardwareBuffer* ahb3 = nullptr; - AHardwareBuffer_Desc buffer_desc; - - ret = api_.WriteBufferQueueCreateReadQueue(write_queue_, &read_queue); - - ASSERT_EQ(0, ret); - ASSERT_NE(nullptr, read_queue); - - api_.ReadBufferQueueSetBufferRemovedCallback(read_queue, - &BufferRemovedCallback, this); - - // Handle all pending events on the read queue. - ret = api_.ReadBufferQueueHandleEvents(read_queue); - ASSERT_EQ(0, ret); - - size_t capacity = api_.ReadBufferQueueGetCapacity(read_queue); - ALOGD_IF(TRACE, "TestResizeBuffer, capacity=%zu", capacity); - ASSERT_EQ(kQueueCapacity, capacity); - - // Resize before dequeuing. - constexpr uint32_t w1 = 10; - ret = api_.WriteBufferQueueResizeBuffer(write_queue_, w1, kBufferHeight); - ASSERT_EQ(0, ret); - - // Gain first buffer for writing. All buffers will be resized. - ret = api_.WriteBufferQueueGainBuffer(write_queue_, /*timeout=*/0, &wb1, - &meta, &fence_fd); - ASSERT_EQ(0, ret); - ASSERT_TRUE(api_.WriteBufferIsValid(wb1)); - ALOGD_IF(TRACE, "TestResizeBuffer, gain buffer %p", wb1); - close(fence_fd); - - // Check the buffer dimension. - ret = api_.WriteBufferGetAHardwareBuffer(wb1, &ahb1); - ASSERT_EQ(0, ret); - AHardwareBuffer_describe(ahb1, &buffer_desc); - ASSERT_EQ(w1, buffer_desc.width); - ASSERT_EQ(kBufferHeight, buffer_desc.height); - AHardwareBuffer_release(ahb1); - - // For the first resize, all buffers are reallocated. - int expected_buffer_removed_count = kQueueCapacity; - ret = api_.ReadBufferQueueHandleEvents(read_queue); - ASSERT_EQ(0, ret); - ASSERT_EQ(expected_buffer_removed_count, buffer_removed_count_); - - // Resize the queue. We are testing with blob format, keep height to be 1. - constexpr uint32_t w2 = 20; - ret = api_.WriteBufferQueueResizeBuffer(write_queue_, w2, kBufferHeight); - ASSERT_EQ(0, ret); - - // The next buffer we dequeued should have new width. - ret = api_.WriteBufferQueueGainBuffer(write_queue_, /*timeout=*/0, &wb2, - &meta, &fence_fd); - ASSERT_EQ(0, ret); - ASSERT_TRUE(api_.WriteBufferIsValid(wb2)); - ALOGD_IF(TRACE, "TestResizeBuffer, gain buffer %p, fence_fd=%d", wb2, - fence_fd); - close(fence_fd); - - // Check the buffer dimension, should be new width - ret = api_.WriteBufferGetAHardwareBuffer(wb2, &ahb2); - ASSERT_EQ(0, ret); - AHardwareBuffer_describe(ahb2, &buffer_desc); - ASSERT_EQ(w2, buffer_desc.width); - AHardwareBuffer_release(ahb2); - - // For the second resize, all but one buffers are reallocated. - expected_buffer_removed_count += (kQueueCapacity - 1); - ret = api_.ReadBufferQueueHandleEvents(read_queue); - ASSERT_EQ(0, ret); - ASSERT_EQ(expected_buffer_removed_count, buffer_removed_count_); - - // Resize the queue for the third time. - constexpr uint32_t w3 = 30; - ret = api_.WriteBufferQueueResizeBuffer(write_queue_, w3, kBufferHeight); - ASSERT_EQ(0, ret); - - // The next buffer we dequeued should have new width. - ret = api_.WriteBufferQueueGainBuffer(write_queue_, /*timeout=*/0, &wb3, - &meta, &fence_fd); - ASSERT_EQ(0, ret); - ASSERT_TRUE(api_.WriteBufferIsValid(wb3)); - ALOGD_IF(TRACE, "TestResizeBuffer, gain buffer %p, fence_fd=%d", wb3, - fence_fd); - close(fence_fd); - - // Check the buffer dimension, should be new width - ret = api_.WriteBufferGetAHardwareBuffer(wb3, &ahb3); - ASSERT_EQ(0, ret); - AHardwareBuffer_describe(ahb3, &buffer_desc); - ASSERT_EQ(w3, buffer_desc.width); - AHardwareBuffer_release(ahb3); - - // For the third resize, all but two buffers are reallocated. - expected_buffer_removed_count += (kQueueCapacity - 2); - ret = api_.ReadBufferQueueHandleEvents(read_queue); - ASSERT_EQ(0, ret); - ASSERT_EQ(expected_buffer_removed_count, buffer_removed_count_); - - api_.ReadBufferQueueDestroy(read_queue); -} - -TEST_F(DvrBufferQueueTest, ReadQueueEventFd) { - int ret = api_.WriteBufferQueueCreate( - kBufferWidth, kBufferHeight, kBufferFormat, kLayerCount, kBufferUsage, - kQueueCapacity, sizeof(DvrNativeBufferMetadata), &write_queue_); - ASSERT_EQ(0, ret); - - DvrReadBufferQueue* read_queue = nullptr; - ret = api_.WriteBufferQueueCreateReadQueue(write_queue_, &read_queue); - - ASSERT_EQ(0, ret); - ASSERT_NE(nullptr, read_queue); - - int event_fd = api_.ReadBufferQueueGetEventFd(read_queue); - ASSERT_GT(event_fd, 0); -} - -// Verifies a Dvr{Read,Write}BufferQueue contains the same set of -// Dvr{Read,Write}Buffer(s) during their lifecycles. And for the same buffer_id, -// the corresponding AHardwareBuffer handle stays the same. -TEST_F(DvrBufferQueueTest, StableBufferIdAndHardwareBuffer) { - int ret = api_.WriteBufferQueueCreate( - kBufferWidth, kBufferHeight, kBufferFormat, kLayerCount, kBufferUsage, - kQueueCapacity, sizeof(DvrNativeBufferMetadata), &write_queue_); - ASSERT_EQ(0, ret); - - int fence_fd = -1; - DvrReadBufferQueue* read_queue = nullptr; - EXPECT_EQ(0, api_.WriteBufferQueueCreateReadQueue(write_queue_, &read_queue)); - - // Read buffers. - std::array<DvrReadBuffer*, kQueueCapacity> rbs; - // Write buffers. - std::array<DvrWriteBuffer*, kQueueCapacity> wbs; - // Buffer metadata. - std::array<DvrNativeBufferMetadata, kQueueCapacity> metas; - // Hardware buffers for Read buffers. - std::unordered_map<int, AHardwareBuffer*> rhbs; - // Hardware buffers for Write buffers. - std::unordered_map<int, AHardwareBuffer*> whbs; - - constexpr int kNumTests = 100; - - // This test runs the following operations many many times. Thus we prefer to - // use ASSERT_XXX rather than EXPECT_XXX to avoid spamming the output. - std::function<void(size_t i)> Gain = [&](size_t i) { - int ret = api_.WriteBufferQueueGainBuffer(write_queue_, /*timeout=*/10, - &wbs[i], &metas[i], &fence_fd); - ASSERT_EQ(ret, 0); - ASSERT_LT(fence_fd, 0); // expect invalid fence. - ASSERT_TRUE(api_.WriteBufferIsValid(wbs[i])); - int buffer_id = api_.WriteBufferGetId(wbs[i]); - ASSERT_GT(buffer_id, 0); - - AHardwareBuffer* hb = nullptr; - ASSERT_EQ(0, api_.WriteBufferGetAHardwareBuffer(wbs[i], &hb)); - - auto whb_it = whbs.find(buffer_id); - if (whb_it == whbs.end()) { - // If this is a new buffer id, check that total number of unique - // hardware buffers won't exceed queue capacity. - ASSERT_LT(whbs.size(), kQueueCapacity); - whbs.emplace(buffer_id, hb); - } else { - // If this is a buffer id we have seen before, check that the - // buffer_id maps to the same AHardwareBuffer handle. - ASSERT_EQ(hb, whb_it->second); - } - }; - - std::function<void(size_t i)> Post = [&](size_t i) { - ASSERT_TRUE(api_.WriteBufferIsValid(wbs[i])); - - metas[i].timestamp++; - int ret = api_.WriteBufferQueuePostBuffer(write_queue_, wbs[i], &metas[i], - /*fence=*/-1); - ASSERT_EQ(ret, 0); - }; - - std::function<void(size_t i)> Acquire = [&](size_t i) { - int ret = api_.ReadBufferQueueAcquireBuffer(read_queue, /*timeout=*/10, - &rbs[i], &metas[i], &fence_fd); - ASSERT_EQ(ret, 0); - ASSERT_LT(fence_fd, 0); // expect invalid fence. - ASSERT_TRUE(api_.ReadBufferIsValid(rbs[i])); - - int buffer_id = api_.ReadBufferGetId(rbs[i]); - ASSERT_GT(buffer_id, 0); - - AHardwareBuffer* hb = nullptr; - ASSERT_EQ(0, api_.ReadBufferGetAHardwareBuffer(rbs[i], &hb)); - - auto rhb_it = rhbs.find(buffer_id); - if (rhb_it == rhbs.end()) { - // If this is a new buffer id, check that total number of unique hardware - // buffers won't exceed queue capacity. - ASSERT_LT(rhbs.size(), kQueueCapacity); - rhbs.emplace(buffer_id, hb); - } else { - // If this is a buffer id we have seen before, check that the buffer_id - // maps to the same AHardwareBuffer handle. - ASSERT_EQ(hb, rhb_it->second); - } - }; - - std::function<void(size_t i)> Release = [&](size_t i) { - ASSERT_TRUE(api_.ReadBufferIsValid(rbs[i])); - - int ret = api_.ReadBufferQueueReleaseBuffer(read_queue, rbs[i], &metas[i], - /*release_fence_fd=*/-1); - ASSERT_EQ(ret, 0); - }; - - // Scenario one: - for (int i = 0; i < kNumTests; i++) { - // Gain all write buffers. - for (size_t i = 0; i < kQueueCapacity; i++) { - ASSERT_NO_FATAL_FAILURE(Gain(i)); - } - // Post all write buffers. - for (size_t i = 0; i < kQueueCapacity; i++) { - ASSERT_NO_FATAL_FAILURE(Post(i)); - } - // Acquire all read buffers. - for (size_t i = 0; i < kQueueCapacity; i++) { - ASSERT_NO_FATAL_FAILURE(Acquire(i)); - } - // Release all read buffers. - for (size_t i = 0; i < kQueueCapacity; i++) { - ASSERT_NO_FATAL_FAILURE(Release(i)); - } - } - - // Scenario two: - for (int i = 0; i < kNumTests; i++) { - // Gain and post all write buffers. - for (size_t i = 0; i < kQueueCapacity; i++) { - ASSERT_NO_FATAL_FAILURE(Gain(i)); - ASSERT_NO_FATAL_FAILURE(Post(i)); - } - // Acquire and release all read buffers. - for (size_t i = 0; i < kQueueCapacity; i++) { - ASSERT_NO_FATAL_FAILURE(Acquire(i)); - ASSERT_NO_FATAL_FAILURE(Release(i)); - } - } - - // Scenario three: - for (int i = 0; i < kNumTests; i++) { - // Gain all write buffers then post them in reversed order. - for (size_t i = 0; i < kQueueCapacity; i++) { - ASSERT_NO_FATAL_FAILURE(Gain(i)); - } - for (size_t i = 0; i < kQueueCapacity; i++) { - ASSERT_NO_FATAL_FAILURE(Post(kQueueCapacity - 1 - i)); - } - - // Acquire all write buffers then release them in reversed order. - for (size_t i = 0; i < kQueueCapacity; i++) { - ASSERT_NO_FATAL_FAILURE(Acquire(i)); - } - for (size_t i = 0; i < kQueueCapacity; i++) { - ASSERT_NO_FATAL_FAILURE(Release(kQueueCapacity - 1 - i)); - } - } -} - -TEST_F(DvrBufferQueueTest, ConsumerReleaseAfterProducerDestroy) { - int ret = api_.WriteBufferQueueCreate( - kBufferWidth, kBufferHeight, kBufferFormat, kLayerCount, kBufferUsage, - kQueueCapacity, sizeof(DvrNativeBufferMetadata), &write_queue_); - ASSERT_EQ(ret, 0); - - DvrReadBufferQueue* read_queue = nullptr; - DvrReadBuffer* rb = nullptr; - DvrWriteBuffer* wb = nullptr; - DvrNativeBufferMetadata meta1; - DvrNativeBufferMetadata meta2; - int fence_fd = -1; - - ret = api_.WriteBufferQueueCreateReadQueue(write_queue_, &read_queue); - ASSERT_EQ(ret, 0); - - api_.ReadBufferQueueSetBufferAvailableCallback( - read_queue, &BufferAvailableCallback, this); - - // Gain buffer for writing. - ret = api_.WriteBufferQueueGainBuffer(write_queue_, /*timeout=*/0, &wb, - &meta1, &fence_fd); - ASSERT_EQ(ret, 0); - close(fence_fd); - - // Post buffer to the read_queue. - ret = api_.WriteBufferQueuePostBuffer(write_queue_, wb, &meta1, /*fence=*/-1); - ASSERT_EQ(ret, 0); - wb = nullptr; - - // Acquire buffer for reading. - ret = api_.ReadBufferQueueAcquireBuffer(read_queue, /*timeout=*/10, &rb, - &meta2, &fence_fd); - ASSERT_EQ(ret, 0); - close(fence_fd); - - // Destroy the write buffer queue and make sure the reader queue is picking - // these events up. - api_.WriteBufferQueueDestroy(write_queue_); - ret = api_.ReadBufferQueueHandleEvents(read_queue); - ASSERT_EQ(0, ret); - - // Release buffer to the write_queue. - ret = api_.ReadBufferQueueReleaseBuffer(read_queue, rb, &meta2, - /*release_fence_fd=*/-1); - ASSERT_EQ(ret, 0); - rb = nullptr; - - api_.ReadBufferQueueDestroy(read_queue); -} - -} // namespace diff --git a/libs/vr/libdvr/tests/dvr_display-test.cpp b/libs/vr/libdvr/tests/dvr_display-test.cpp deleted file mode 100644 index c72f94035b..0000000000 --- a/libs/vr/libdvr/tests/dvr_display-test.cpp +++ /dev/null @@ -1,351 +0,0 @@ -#include <android/hardware_buffer.h> -#include <android/log.h> -#include <dvr/dvr_api.h> -#include <dvr/dvr_display_types.h> -#include <dvr/dvr_surface.h> - -#include <gtest/gtest.h> - -#include "dvr_api_test.h" - -#define LOG_TAG "dvr_display-test" - -#ifndef ALOGD -#define ALOGD(...) __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, __VA_ARGS__) -#endif - -class DvrDisplayTest : public DvrApiTest { - protected: - void SetUp() override { - DvrApiTest::SetUp(); - int ret = api_.GetNativeDisplayMetrics(sizeof(display_metrics_), - &display_metrics_); - ASSERT_EQ(ret, 0) << "Failed to get display metrics."; - ALOGD( - "display_width: %d, display_height: %d, display_x_dpi: %d, " - "display_y_dpi: %d, vsync_period_ns: %d.", - display_metrics_.display_width, display_metrics_.display_height, - display_metrics_.display_x_dpi, display_metrics_.display_y_dpi, - display_metrics_.vsync_period_ns); - } - - void TearDown() override { - if (write_queue_ != nullptr) { - api_.WriteBufferQueueDestroy(write_queue_); - write_queue_ = nullptr; - } - if (direct_surface_ != nullptr) { - api_.SurfaceDestroy(direct_surface_); - direct_surface_ = nullptr; - } - DvrApiTest::TearDown(); - } - - /* Convert a write buffer to an android hardware buffer and fill in - * color_textures evenly to the buffer. - * AssertionError if the width of the buffer is not equal to the input width, - * AssertionError if the height of the buffer is not equal to the input - * height. - */ - void FillWriteBuffer(DvrWriteBuffer* write_buffer, - const std::vector<uint32_t>& color_textures, - uint32_t width, uint32_t height); - - // Write buffer queue properties. - static constexpr uint64_t kUsage = AHARDWAREBUFFER_USAGE_GPU_SAMPLED_IMAGE | - AHARDWAREBUFFER_USAGE_GPU_COLOR_OUTPUT | - AHARDWAREBUFFER_USAGE_CPU_WRITE_OFTEN; - uint32_t kFormat = AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM; - static constexpr size_t kMetadataSize = 0; - static constexpr int kTimeoutMs = 1000; // Time for getting buffer. - uint32_t kLayerCount = 1; - DvrWriteBufferQueue* write_queue_ = nullptr; - DvrSurface* direct_surface_ = nullptr; - - // Device display properties. - DvrNativeDisplayMetrics display_metrics_; -}; - -TEST_F(DvrDisplayTest, DisplayWithOneBuffer) { - // Create a direct surface. - std::vector<DvrSurfaceAttribute> direct_surface_attributes = { - {.key = DVR_SURFACE_ATTRIBUTE_DIRECT, - .value.type = DVR_SURFACE_ATTRIBUTE_TYPE_BOOL, - .value.bool_value = true}, - {.key = DVR_SURFACE_ATTRIBUTE_Z_ORDER, - .value.type = DVR_SURFACE_ATTRIBUTE_TYPE_INT32, - .value.int32_value = 10}, - {.key = DVR_SURFACE_ATTRIBUTE_VISIBLE, - .value.type = DVR_SURFACE_ATTRIBUTE_TYPE_BOOL, - .value.bool_value = true}, - }; - int ret = - api_.SurfaceCreate(direct_surface_attributes.data(), - direct_surface_attributes.size(), &direct_surface_); - ASSERT_EQ(ret, 0) << "Failed to create direct surface."; - - // Create a buffer queue with the direct surface. - constexpr size_t kCapacity = 1; - uint32_t width = display_metrics_.display_width; - uint32_t height = display_metrics_.display_height; - ret = api_.SurfaceCreateWriteBufferQueue( - direct_surface_, width, height, kFormat, kLayerCount, kUsage, kCapacity, - kMetadataSize, &write_queue_); - EXPECT_EQ(0, ret) << "Failed to create buffer queue."; - ASSERT_NE(nullptr, write_queue_) << "Write buffer queue should not be null."; - - // Get buffer from WriteBufferQueue. - DvrWriteBuffer* write_buffer = nullptr; - DvrNativeBufferMetadata out_meta; - int out_fence_fd = -1; - ret = api_.WriteBufferQueueGainBuffer(write_queue_, kTimeoutMs, &write_buffer, - &out_meta, &out_fence_fd); - EXPECT_EQ(0, ret) << "Failed to get the buffer."; - ASSERT_NE(nullptr, write_buffer) << "Gained buffer should not be null."; - - // Color the write buffer. - FillWriteBuffer(write_buffer, - {0xff000000, 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00000000}, - width, height); - - // Post buffer. - int ready_fence_fd = -1; - ret = api_.WriteBufferQueuePostBuffer(write_queue_, write_buffer, &out_meta, - ready_fence_fd); - EXPECT_EQ(0, ret) << "Failed to post the buffer."; - - sleep(5); // For visual check on the device under test. - // Should observe three primary colors on the screen center. -} - -TEST_F(DvrDisplayTest, DisplayWithDoubleBuffering) { - // Create a direct surface. - std::vector<DvrSurfaceAttribute> direct_surface_attributes = { - {.key = DVR_SURFACE_ATTRIBUTE_DIRECT, - .value.type = DVR_SURFACE_ATTRIBUTE_TYPE_BOOL, - .value.bool_value = true}, - {.key = DVR_SURFACE_ATTRIBUTE_Z_ORDER, - .value.type = DVR_SURFACE_ATTRIBUTE_TYPE_INT32, - .value.int32_value = 10}, - {.key = DVR_SURFACE_ATTRIBUTE_VISIBLE, - .value.type = DVR_SURFACE_ATTRIBUTE_TYPE_BOOL, - .value.bool_value = true}, - }; - int ret = - api_.SurfaceCreate(direct_surface_attributes.data(), - direct_surface_attributes.size(), &direct_surface_); - ASSERT_EQ(ret, 0) << "Failed to create direct surface."; - - // Create a buffer queue with the direct surface. - constexpr size_t kCapacity = 2; - uint32_t width = display_metrics_.display_width; - uint32_t height = display_metrics_.display_height; - ret = api_.SurfaceCreateWriteBufferQueue( - direct_surface_, width, height, kFormat, kLayerCount, kUsage, kCapacity, - kMetadataSize, &write_queue_); - EXPECT_EQ(0, ret) << "Failed to create buffer queue."; - ASSERT_NE(nullptr, write_queue_) << "Write buffer queue should not be null."; - - int num_display_cycles_in_5s = 5 / (display_metrics_.vsync_period_ns / 1e9); - ALOGD("The number of display cycles: %d", num_display_cycles_in_5s); - int bufferhub_id_prev_write_buffer = -1; - for (int i = 0; i < num_display_cycles_in_5s; ++i) { - // Get a buffer from the WriteBufferQueue. - DvrWriteBuffer* write_buffer = nullptr; - DvrNativeBufferMetadata out_meta; - int out_fence_fd = -1; - ret = api_.WriteBufferQueueGainBuffer( - write_queue_, kTimeoutMs, &write_buffer, &out_meta, &out_fence_fd); - EXPECT_EQ(0, ret) << "Failed to get the a write buffer."; - ASSERT_NE(nullptr, write_buffer) << "The gained buffer should not be null."; - - int bufferhub_id = api_.WriteBufferGetId(write_buffer); - ALOGD("Display cycle: %d, bufferhub id of the write buffer: %d", i, - bufferhub_id); - EXPECT_NE(bufferhub_id_prev_write_buffer, bufferhub_id) - << "Double buffering should be using the two buffers in turns, not " - "reusing the same write buffer."; - bufferhub_id_prev_write_buffer = bufferhub_id; - - // Color the write buffer. - if (i % 2) { - FillWriteBuffer(write_buffer, {0xffff0000, 0xff00ff00, 0xff0000ff}, width, - height); - } else { - FillWriteBuffer(write_buffer, {0xff00ff00, 0xff0000ff, 0xffff0000}, width, - height); - } - - // Post the write buffer. - int ready_fence_fd = -1; - ret = api_.WriteBufferQueuePostBuffer(write_queue_, write_buffer, &out_meta, - ready_fence_fd); - EXPECT_EQ(0, ret) << "Failed to post the buffer."; - } - // Should observe blinking screen in secondary colors - // although it is actually displaying primary colors. -} - -TEST_F(DvrDisplayTest, DisplayWithTwoHardwareLayers) { - // Create the direct_surface_0 of z order 10 and direct_surface_1 of z - // order 11. - DvrSurface* direct_surface_0 = nullptr; - std::vector<DvrSurfaceAttribute> direct_surface_0_attributes = { - {.key = DVR_SURFACE_ATTRIBUTE_DIRECT, - .value.type = DVR_SURFACE_ATTRIBUTE_TYPE_BOOL, - .value.bool_value = true}, - {.key = DVR_SURFACE_ATTRIBUTE_Z_ORDER, - .value.type = DVR_SURFACE_ATTRIBUTE_TYPE_INT32, - .value.int32_value = 10}, - {.key = DVR_SURFACE_ATTRIBUTE_VISIBLE, - .value.type = DVR_SURFACE_ATTRIBUTE_TYPE_BOOL, - .value.bool_value = true}, - }; - int ret = - api_.SurfaceCreate(direct_surface_0_attributes.data(), - direct_surface_0_attributes.size(), &direct_surface_0); - EXPECT_EQ(ret, 0) << "Failed to create direct surface."; - - DvrSurface* direct_surface_1 = nullptr; - std::vector<DvrSurfaceAttribute> direct_surface_1_attributes = { - {.key = DVR_SURFACE_ATTRIBUTE_DIRECT, - .value.type = DVR_SURFACE_ATTRIBUTE_TYPE_BOOL, - .value.bool_value = true}, - {.key = DVR_SURFACE_ATTRIBUTE_Z_ORDER, - .value.type = DVR_SURFACE_ATTRIBUTE_TYPE_INT32, - .value.int32_value = 11}, - {.key = DVR_SURFACE_ATTRIBUTE_VISIBLE, - .value.type = DVR_SURFACE_ATTRIBUTE_TYPE_BOOL, - .value.bool_value = true}, - }; - ret = - api_.SurfaceCreate(direct_surface_1_attributes.data(), - direct_surface_1_attributes.size(), &direct_surface_1); - EXPECT_EQ(ret, 0) << "Failed to create direct surface."; - - // Create a buffer queue for each of the direct surfaces. - constexpr size_t kCapacity = 1; - uint32_t width = display_metrics_.display_width; - uint32_t height = display_metrics_.display_height; - - DvrWriteBufferQueue* write_queue_0 = nullptr; - ret = api_.SurfaceCreateWriteBufferQueue( - direct_surface_0, width, height, kFormat, kLayerCount, kUsage, kCapacity, - kMetadataSize, &write_queue_0); - EXPECT_EQ(0, ret) << "Failed to create buffer queue."; - EXPECT_NE(nullptr, write_queue_0) << "Write buffer queue should not be null."; - - DvrWriteBufferQueue* write_queue_1 = nullptr; - ret = api_.SurfaceCreateWriteBufferQueue( - direct_surface_1, width, height, kFormat, kLayerCount, kUsage, kCapacity, - kMetadataSize, &write_queue_1); - EXPECT_EQ(0, ret) << "Failed to create buffer queue."; - EXPECT_NE(nullptr, write_queue_1) << "Write buffer queue should not be null."; - - // Get a buffer from each of the write buffer queues. - DvrWriteBuffer* write_buffer_0 = nullptr; - DvrNativeBufferMetadata out_meta_0; - int out_fence_fd = -1; - ret = api_.WriteBufferQueueGainBuffer( - write_queue_0, kTimeoutMs, &write_buffer_0, &out_meta_0, &out_fence_fd); - EXPECT_EQ(0, ret) << "Failed to get the buffer."; - EXPECT_NE(nullptr, write_buffer_0) << "Gained buffer should not be null."; - - DvrWriteBuffer* write_buffer_1 = nullptr; - DvrNativeBufferMetadata out_meta_1; - out_fence_fd = -1; - ret = api_.WriteBufferQueueGainBuffer( - write_queue_1, kTimeoutMs, &write_buffer_1, &out_meta_1, &out_fence_fd); - EXPECT_EQ(0, ret) << "Failed to get the buffer."; - EXPECT_NE(nullptr, write_buffer_1) << "Gained buffer should not be null."; - - // Color the write buffers. - FillWriteBuffer(write_buffer_0, {0xffff0000, 0xff00ff00, 0xff0000ff}, width, - height); - FillWriteBuffer(write_buffer_1, {0x7f00ff00, 0x7f0000ff, 0x7fff0000}, width, - height); - - // Post buffers. - int ready_fence_fd = -1; - ret = api_.WriteBufferQueuePostBuffer(write_queue_0, write_buffer_0, - &out_meta_0, ready_fence_fd); - EXPECT_EQ(0, ret) << "Failed to post the buffer."; - - ready_fence_fd = -1; - ret = api_.WriteBufferQueuePostBuffer(write_queue_1, write_buffer_1, - &out_meta_1, ready_fence_fd); - EXPECT_EQ(0, ret) << "Failed to post the buffer."; - - sleep(5); // For visual check on the device under test. - // Should observe three secondary colors. - - // Test finished. Clean up buffers and surfaces. - if (write_queue_0 != nullptr) { - api_.WriteBufferQueueDestroy(write_queue_0); - write_queue_0 = nullptr; - } - if (write_queue_1 != nullptr) { - api_.WriteBufferQueueDestroy(write_queue_1); - write_queue_1 = nullptr; - } - if (direct_surface_0 != nullptr) { - api_.SurfaceDestroy(direct_surface_0); - } - if (direct_surface_1 != nullptr) { - api_.SurfaceDestroy(direct_surface_1); - } -} - -void DvrDisplayTest::FillWriteBuffer( - DvrWriteBuffer* write_buffer, const std::vector<uint32_t>& color_textures, - uint32_t width, uint32_t height) { - uint32_t num_colors = color_textures.size(); - // Convert the first write buffer to an android hardware buffer. - AHardwareBuffer* ah_buffer = nullptr; - int ret = api_.WriteBufferGetAHardwareBuffer(write_buffer, &ah_buffer); - ASSERT_EQ(0, ret) << "Failed to get a hardware buffer from the write buffer."; - ASSERT_NE(nullptr, ah_buffer) << "AHardware buffer should not be null."; - AHardwareBuffer_Desc ah_buffer_describe; - AHardwareBuffer_describe(ah_buffer, &ah_buffer_describe); - ASSERT_EQ(ah_buffer_describe.format, kFormat) - << "The format of the android hardware buffer is wrong."; - ASSERT_EQ(ah_buffer_describe.layers, kLayerCount) - << "The obtained android hardware buffer should have 2 layers."; - ASSERT_EQ(ah_buffer_describe.width, width) - << "The obtained android hardware buffer width is wrong."; - ASSERT_EQ(ah_buffer_describe.height, height) - << "The obtained android hardware buffer height is wrong."; - // Change the content of the android hardware buffer. - void* buffer_data = nullptr; - int32_t fence = -1; - ret = AHardwareBuffer_lock(ah_buffer, AHARDWAREBUFFER_USAGE_CPU_WRITE_OFTEN, - fence, nullptr, &buffer_data); - ASSERT_EQ(0, ret) << "Failed to lock the hardware buffer."; - ASSERT_NE(nullptr, buffer_data) << "Buffer data should not be null."; - - uint32_t num_pixels = width * height / num_colors; - for (uint32_t color_index = 0; color_index < num_colors - 1; ++color_index) { - uint32_t color_texture = color_textures[color_index]; - for (uint32_t i = 0; i < num_pixels; ++i) { - memcpy(reinterpret_cast<void*>(reinterpret_cast<int64_t>(buffer_data) + - (i + num_pixels * color_index) * - sizeof(color_texture)), - &color_texture, sizeof(color_texture)); - } - } - uint32_t color_texture = color_textures[num_colors - 1]; - uint32_t num_colored_pixels = num_pixels * (num_colors - 1); - num_pixels = width * height - num_colored_pixels; - for (uint32_t i = 0; i < num_pixels; ++i) { - memcpy(reinterpret_cast<void*>(reinterpret_cast<int64_t>(buffer_data) + - (i + num_colored_pixels) * - sizeof(color_texture)), - &color_texture, sizeof(color_texture)); - } - fence = -1; - ret = AHardwareBuffer_unlock(ah_buffer, &fence); - EXPECT_EQ(0, ret) << "Failed to unlock the hardware buffer."; - - // Release the android hardware buffer. - AHardwareBuffer_release(ah_buffer); -} diff --git a/libs/vr/libdvr/tests/dvr_display_manager-test.cpp b/libs/vr/libdvr/tests/dvr_display_manager-test.cpp deleted file mode 100644 index 07e2121970..0000000000 --- a/libs/vr/libdvr/tests/dvr_display_manager-test.cpp +++ /dev/null @@ -1,891 +0,0 @@ -#include <android-base/properties.h> -#include <base/logging.h> -#include <cutils/properties.h> -#include <gtest/gtest.h> -#include <log/log.h> -#include <poll.h> - -#include <android/hardware_buffer.h> - -#include <algorithm> -#include <array> -#include <set> -#include <thread> -#include <vector> - -#include <dvr/dvr_configuration_data.h> -#include <dvr/dvr_deleter.h> -#include <dvr/dvr_display_manager.h> -#include <dvr/dvr_surface.h> - -#include <pdx/status.h> - -using android::pdx::ErrorStatus; -using android::pdx::Status; - -namespace android { -namespace dvr { - -namespace { - -using ::testing::Test; - -DvrSurfaceAttribute MakeAttribute(DvrSurfaceAttributeKey key, nullptr_t) { - DvrSurfaceAttribute attribute; - attribute.key = key; - attribute.value.type = DVR_SURFACE_ATTRIBUTE_TYPE_NONE; - return attribute; -} - -DvrSurfaceAttribute MakeAttribute(DvrSurfaceAttributeKey key, int32_t value) { - DvrSurfaceAttribute attribute; - attribute.key = key; - attribute.value.type = DVR_SURFACE_ATTRIBUTE_TYPE_INT32; - attribute.value.int32_value = value; - return attribute; -} - -DvrSurfaceAttribute MakeAttribute(DvrSurfaceAttributeKey key, int64_t value) { - DvrSurfaceAttribute attribute; - attribute.key = key; - attribute.value.type = DVR_SURFACE_ATTRIBUTE_TYPE_INT64; - attribute.value.int64_value = value; - return attribute; -} - -DvrSurfaceAttribute MakeAttribute(DvrSurfaceAttributeKey key, bool value) { - DvrSurfaceAttribute attribute; - attribute.key = key; - attribute.value.type = DVR_SURFACE_ATTRIBUTE_TYPE_BOOL; - attribute.value.bool_value = value; - return attribute; -} - -DvrSurfaceAttribute MakeAttribute(DvrSurfaceAttributeKey key, float value) { - DvrSurfaceAttribute attribute; - attribute.key = key; - attribute.value.type = DVR_SURFACE_ATTRIBUTE_TYPE_FLOAT; - attribute.value.float_value = value; - return attribute; -} - -DvrSurfaceAttribute MakeAttribute(DvrSurfaceAttributeKey key, - const std::array<float, 2>& value) { - DvrSurfaceAttribute attribute; - attribute.key = key; - attribute.value.type = DVR_SURFACE_ATTRIBUTE_TYPE_FLOAT2; - std::copy(value.begin(), value.end(), attribute.value.float2_value); - return attribute; -} - -DvrSurfaceAttribute MakeAttribute(DvrSurfaceAttributeKey key, - const std::array<float, 3>& value) { - DvrSurfaceAttribute attribute; - attribute.key = key; - attribute.value.type = DVR_SURFACE_ATTRIBUTE_TYPE_FLOAT3; - std::copy(value.begin(), value.end(), attribute.value.float3_value); - return attribute; -} - -DvrSurfaceAttribute MakeAttribute(DvrSurfaceAttributeKey key, - const std::array<float, 4>& value) { - DvrSurfaceAttribute attribute; - attribute.key = key; - attribute.value.type = DVR_SURFACE_ATTRIBUTE_TYPE_FLOAT4; - std::copy(value.begin(), value.end(), attribute.value.float4_value); - return attribute; -} - -DvrSurfaceAttribute MakeAttribute(DvrSurfaceAttributeKey key, - const std::array<float, 8>& value) { - DvrSurfaceAttribute attribute; - attribute.key = key; - attribute.value.type = DVR_SURFACE_ATTRIBUTE_TYPE_FLOAT8; - std::copy(value.begin(), value.end(), attribute.value.float8_value); - return attribute; -} - -DvrSurfaceAttribute MakeAttribute(DvrSurfaceAttributeKey key, - const std::array<float, 16>& value) { - DvrSurfaceAttribute attribute; - attribute.key = key; - attribute.value.type = DVR_SURFACE_ATTRIBUTE_TYPE_FLOAT16; - std::copy(value.begin(), value.end(), attribute.value.float16_value); - return attribute; -} - -Status<UniqueDvrSurface> CreateApplicationSurface(bool visible = false, - int32_t z_order = 0) { - DvrSurface* surface = nullptr; - DvrSurfaceAttribute attributes[] = { - MakeAttribute(DVR_SURFACE_ATTRIBUTE_Z_ORDER, z_order), - MakeAttribute(DVR_SURFACE_ATTRIBUTE_VISIBLE, visible)}; - - const int ret = dvrSurfaceCreate( - attributes, std::extent<decltype(attributes)>::value, &surface); - if (ret < 0) - return ErrorStatus(-ret); - else - return {UniqueDvrSurface(surface)}; -} - -Status<UniqueDvrWriteBufferQueue> CreateSurfaceQueue( - const UniqueDvrSurface& surface, uint32_t width, uint32_t height, - uint32_t format, uint32_t layer_count, uint64_t usage, size_t capacity, - size_t metadata_size) { - DvrWriteBufferQueue* queue; - const int ret = dvrSurfaceCreateWriteBufferQueue( - surface.get(), width, height, format, layer_count, usage, capacity, - metadata_size, &queue); - if (ret < 0) - return ErrorStatus(-ret); - else - return {UniqueDvrWriteBufferQueue(queue)}; -} - -Status<std::vector<uint8_t>> GetConfigData(int config_type) { - uint8_t* data = nullptr; - size_t data_size = 0; - int error = dvrConfigurationDataGet(config_type, &data, &data_size); - if (error < 0) { - return ErrorStatus(-error); - } - - if (!data || data_size == 0) { - return ErrorStatus(EINVAL); - } - std::vector<uint8_t> data_result(data, data + data_size); - dvrConfigurationDataDestroy(data); - std::string s(data, data + data_size); - return {std::move(data_result)}; -} - -class TestDisplayManager { - public: - TestDisplayManager(UniqueDvrDisplayManager display_manager, - UniqueDvrSurfaceState surface_state) - : display_manager_(std::move(display_manager)), - surface_state_(std::move(surface_state)) { - const int fd = dvrDisplayManagerGetEventFd(display_manager_.get()); - LOG_IF(INFO, fd < 0) << "Failed to get event fd: " << strerror(-fd); - display_manager_event_fd_ = fd; - } - - Status<UniqueDvrReadBufferQueue> GetReadBufferQueue(int surface_id, - int queue_id) { - DvrReadBufferQueue* queue; - const int ret = dvrDisplayManagerGetReadBufferQueue( - display_manager_.get(), surface_id, queue_id, &queue); - if (ret < 0) - return ErrorStatus(-ret); - else - return {UniqueDvrReadBufferQueue(queue)}; - } - - Status<void> UpdateSurfaceState() { - const int ret = dvrDisplayManagerGetSurfaceState(display_manager_.get(), - surface_state_.get()); - if (ret < 0) - return ErrorStatus(-ret); - else - return {}; - } - - enum : int { kTimeoutMs = 10000 }; // 10s - - Status<void> WaitForUpdate(int timeout_ms = kTimeoutMs) { - if (display_manager_event_fd_ < 0) - return ErrorStatus(-display_manager_event_fd_); - - pollfd pfd = {display_manager_event_fd_, POLLIN, 0}; - const int count = poll(&pfd, 1, timeout_ms); - if (count < 0) - return ErrorStatus(errno); - else if (count == 0) - return ErrorStatus(ETIMEDOUT); - - int events; - const int ret = dvrDisplayManagerTranslateEpollEventMask( - display_manager_.get(), pfd.revents, &events); - if (ret < 0) - return ErrorStatus(-ret); - else if (events & POLLIN) - return UpdateSurfaceState(); - else - return ErrorStatus(EPROTO); - } - - Status<size_t> GetSurfaceCount() { - size_t count = 0; - const int ret = - dvrSurfaceStateGetSurfaceCount(surface_state_.get(), &count); - if (ret < 0) - return ErrorStatus(-ret); - else - return {count}; - } - - Status<DvrSurfaceUpdateFlags> GetUpdateFlags(size_t surface_index) { - DvrSurfaceUpdateFlags update_flags; - const int ret = dvrSurfaceStateGetUpdateFlags(surface_state_.get(), - surface_index, &update_flags); - if (ret < 0) - return ErrorStatus(-ret); - else - return {update_flags}; - } - - Status<int> GetSurfaceId(size_t surface_index) { - int surface_id; - const int ret = dvrSurfaceStateGetSurfaceId(surface_state_.get(), - surface_index, &surface_id); - if (ret < 0) - return ErrorStatus(-ret); - else - return {surface_id}; - } - - Status<int> GetProcessId(size_t surface_index) { - int process_id; - const int ret = dvrSurfaceStateGetProcessId(surface_state_.get(), - surface_index, &process_id); - if (ret < 0) - return ErrorStatus(-ret); - else - return {process_id}; - } - - Status<std::vector<DvrSurfaceAttribute>> GetAttributes(size_t surface_index) { - std::vector<DvrSurfaceAttribute> attributes; - size_t count = 0; - const int ret = dvrSurfaceStateGetAttributeCount(surface_state_.get(), - surface_index, &count); - if (ret < 0) - return ErrorStatus(-ret); - - attributes.resize(count); - const ssize_t return_count = dvrSurfaceStateGetAttributes( - surface_state_.get(), surface_index, attributes.data(), count); - if (return_count < 0) - return ErrorStatus(-return_count); - - attributes.resize(return_count); - return {std::move(attributes)}; - } - - Status<std::vector<int>> GetQueueIds(size_t surface_index) { - std::vector<int> queue_ids; - size_t count = 0; - const int ret = dvrSurfaceStateGetQueueCount(surface_state_.get(), - surface_index, &count); - if (ret < 0) - return ErrorStatus(-ret); - - if (count > 0) { - queue_ids.resize(count); - const ssize_t return_count = dvrSurfaceStateGetQueueIds( - surface_state_.get(), surface_index, queue_ids.data(), count); - if (return_count < 0) - return ErrorStatus(-return_count); - - queue_ids.resize(return_count); - } - - return {std::move(queue_ids)}; - } - - private: - UniqueDvrDisplayManager display_manager_; - UniqueDvrSurfaceState surface_state_; - - // Owned by object in display_manager_, do not explicitly close. - int display_manager_event_fd_; - - TestDisplayManager(const TestDisplayManager&) = delete; - void operator=(const TestDisplayManager&) = delete; -}; - -class DvrDisplayManagerTest : public Test { - protected: - void SetUp() override { - int ret; - DvrDisplayManager* display_manager; - DvrSurfaceState* surface_state; - - ret = dvrDisplayManagerCreate(&display_manager); - ASSERT_EQ(0, ret) << "Failed to create display manager client"; - ASSERT_NE(nullptr, display_manager); - - ret = dvrSurfaceStateCreate(&surface_state); - ASSERT_EQ(0, ret) << "Failed to create surface state object"; - ASSERT_NE(nullptr, surface_state); - - manager_.reset( - new TestDisplayManager(UniqueDvrDisplayManager(display_manager), - UniqueDvrSurfaceState(surface_state))); - } - void TearDown() override {} - - std::unique_ptr<TestDisplayManager> manager_; -}; - -// TODO(eieio): Consider moving these somewhere more central because they are -// broadly useful. - -template <typename T> -testing::AssertionResult StatusOk(const char* status_expression, - const Status<T>& status) { - if (!status.ok()) { - return testing::AssertionFailure() - << "(" << status_expression - << ") expected to indicate success but actually contains error (" - << status.error() << ")"; - } else { - return testing::AssertionSuccess(); - } -} - -template <typename T> -testing::AssertionResult StatusError(const char* status_expression, - const Status<T>& status) { - if (status.ok()) { - return testing::AssertionFailure() - << "(" << status_expression - << ") expected to indicate error but instead indicates success."; - } else { - return testing::AssertionSuccess(); - } -} - -template <typename T> -testing::AssertionResult StatusHasError(const char* status_expression, - const char* /*error_code_expression*/, - const Status<T>& status, - int error_code) { - if (status.ok()) { - return StatusError(status_expression, status); - } else if (status.error() != error_code) { - return testing::AssertionFailure() - << "(" << status_expression << ") expected to indicate error (" - << error_code << ") but actually indicates error (" << status.error() - << ")"; - } else { - return testing::AssertionSuccess(); - } -} - -template <typename T, typename U> -testing::AssertionResult StatusHasValue(const char* status_expression, - const char* /*value_expression*/, - const Status<T>& status, - const U& value) { - if (!status.ok()) { - return StatusOk(status_expression, status); - } else if (status.get() != value) { - return testing::AssertionFailure() - << "(" << status_expression << ") expected to contain value (" - << testing::PrintToString(value) << ") but actually contains value (" - << testing::PrintToString(status.get()) << ")"; - } else { - return testing::AssertionSuccess(); - } -} - -template <typename T, typename Op> -testing::AssertionResult StatusPred(const char* status_expression, - const char* pred_expression, - const Status<T>& status, Op pred) { - if (!status.ok()) { - return StatusOk(status_expression, status); - } else if (!pred(status.get())) { - return testing::AssertionFailure() - << status_expression << " value (" - << testing::PrintToString(status.get()) - << ") failed to pass predicate " << pred_expression; - } else { - return testing::AssertionSuccess(); - } -} - -#define ASSERT_STATUS_OK(status) ASSERT_PRED_FORMAT1(StatusOk, status) -#define ASSERT_STATUS_ERROR(status) ASSERT_PRED_FORMAT1(StatusError, status) - -#define ASSERT_STATUS_ERROR_VALUE(value, status) \ - ASSERT_PRED_FORMAT2(StatusHasError, status, value) - -#define ASSERT_STATUS_EQ(value, status) \ - ASSERT_PRED_FORMAT2(StatusHasValue, status, value) - -#define EXPECT_STATUS_OK(status) EXPECT_PRED_FORMAT1(StatusOk, status) -#define EXPECT_STATUS_ERROR(status) EXPECT_PRED_FORMAT1(StatusError, status) - -#define EXPECT_STATUS_ERROR_VALUE(value, status) \ - EXPECT_PRED_FORMAT2(StatusHasError, status, value) - -#define EXPECT_STATUS_EQ(value, status) \ - EXPECT_PRED_FORMAT2(StatusHasValue, status, value) - -#define EXPECT_STATUS_PRED(pred, status) \ - EXPECT_PRED_FORMAT2(StatusPred, status, pred) - -#if 0 -// Verify utility predicate/macro functionality. This section is commented out -// because it is designed to fail in some cases to validate the helpers. -TEST_F(Test, ExpectVoid) { - Status<void> status_error{ErrorStatus{EINVAL}}; - Status<void> status_ok{}; - - EXPECT_STATUS_ERROR(status_error); - EXPECT_STATUS_ERROR(status_ok); - EXPECT_STATUS_OK(status_error); - EXPECT_STATUS_OK(status_ok); - - EXPECT_STATUS_ERROR_VALUE(EINVAL, status_error); - EXPECT_STATUS_ERROR_VALUE(ENOMEM, status_error); - EXPECT_STATUS_ERROR_VALUE(EINVAL, status_ok); - EXPECT_STATUS_ERROR_VALUE(ENOMEM, status_ok); -} - -TEST_F(Test, ExpectInt) { - Status<int> status_error{ErrorStatus{EINVAL}}; - Status<int> status_ok{10}; - - EXPECT_STATUS_ERROR(status_error); - EXPECT_STATUS_ERROR(status_ok); - EXPECT_STATUS_OK(status_error); - EXPECT_STATUS_OK(status_ok); - - EXPECT_STATUS_ERROR_VALUE(EINVAL, status_error); - EXPECT_STATUS_ERROR_VALUE(ENOMEM, status_error); - EXPECT_STATUS_ERROR_VALUE(EINVAL, status_ok); - EXPECT_STATUS_ERROR_VALUE(ENOMEM, status_ok); - - EXPECT_STATUS_EQ(10, status_error); - EXPECT_STATUS_EQ(20, status_error); - EXPECT_STATUS_EQ(10, status_ok); - EXPECT_STATUS_EQ(20, status_ok); - - auto pred1 = [](const auto& value) { return value < 15; }; - auto pred2 = [](const auto& value) { return value > 5; }; - auto pred3 = [](const auto& value) { return value > 15; }; - auto pred4 = [](const auto& value) { return value < 5; }; - - EXPECT_STATUS_PRED(pred1, status_error); - EXPECT_STATUS_PRED(pred2, status_error); - EXPECT_STATUS_PRED(pred3, status_error); - EXPECT_STATUS_PRED(pred4, status_error); - EXPECT_STATUS_PRED(pred1, status_ok); - EXPECT_STATUS_PRED(pred2, status_ok); - EXPECT_STATUS_PRED(pred3, status_ok); - EXPECT_STATUS_PRED(pred4, status_ok); -} -#endif - -TEST_F(DvrDisplayManagerTest, SurfaceCreateEvent) { - // Get surface state and verify there are no surfaces. - ASSERT_STATUS_OK(manager_->UpdateSurfaceState()); - ASSERT_STATUS_EQ(0u, manager_->GetSurfaceCount()); - - // Get flags for invalid surface index. - EXPECT_STATUS_ERROR_VALUE(EINVAL, manager_->GetUpdateFlags(0)); - - // Create an application surface. - auto surface_status = CreateApplicationSurface(); - ASSERT_STATUS_OK(surface_status); - UniqueDvrSurface surface = surface_status.take(); - ASSERT_NE(nullptr, surface.get()); - - const int surface_id = dvrSurfaceGetId(surface.get()); - ASSERT_GE(surface_id, 0); - - // Now there should be one new surface. - ASSERT_STATUS_OK(manager_->WaitForUpdate()); - EXPECT_STATUS_EQ(1u, manager_->GetSurfaceCount()); - - // Verify the new surface flag is set. - auto check_flags = [](const auto& value) { - return value & DVR_SURFACE_UPDATE_FLAGS_NEW_SURFACE; - }; - EXPECT_STATUS_PRED(check_flags, manager_->GetUpdateFlags(0)); - - // Verify the surface id matches. - EXPECT_STATUS_EQ(surface_id, manager_->GetSurfaceId(0)); - - // Verify the owning process of the surface. - EXPECT_STATUS_EQ(getpid(), manager_->GetProcessId(0)); - - surface.reset(); - - ASSERT_STATUS_OK(manager_->WaitForUpdate()); - EXPECT_STATUS_EQ(0u, manager_->GetSurfaceCount()); -} - -TEST_F(DvrDisplayManagerTest, SurfaceAttributeEvent) { - // Get surface state and verify there are no surfaces. - ASSERT_STATUS_OK(manager_->UpdateSurfaceState()); - ASSERT_STATUS_EQ(0u, manager_->GetSurfaceCount()); - - // Get attributes for an invalid surface index. - EXPECT_STATUS_ERROR_VALUE(EINVAL, manager_->GetAttributes(0)); - - const bool kInitialVisibility = true; - const int32_t kInitialZOrder = 10; - auto surface_status = - CreateApplicationSurface(kInitialVisibility, kInitialZOrder); - ASSERT_STATUS_OK(surface_status); - auto surface = surface_status.take(); - ASSERT_NE(nullptr, surface.get()); - - ASSERT_STATUS_OK(manager_->WaitForUpdate()); - ASSERT_STATUS_EQ(1u, manager_->GetSurfaceCount()); - - // Check the initial attribute values. - auto attribute_status = manager_->GetAttributes(0); - ASSERT_STATUS_OK(attribute_status); - auto attributes = attribute_status.take(); - EXPECT_GE(attributes.size(), 2u); - - std::set<int32_t> actual_keys; - std::set<int32_t> expected_keys = {DVR_SURFACE_ATTRIBUTE_Z_ORDER, - DVR_SURFACE_ATTRIBUTE_VISIBLE}; - - // Collect all the keys in attributes that match the expected keys. - auto compare_keys = [](const auto& attributes, const auto& expected_keys) { - std::set<int32_t> keys; - for (const auto& attribute : attributes) { - if (expected_keys.find(attribute.key) != expected_keys.end()) - keys.emplace(attribute.key); - } - return keys; - }; - - // If the sets match then attributes contained at least the expected keys, - // even if other keys were also present. - actual_keys = compare_keys(attributes, expected_keys); - EXPECT_EQ(expected_keys, actual_keys); - - std::vector<DvrSurfaceAttribute> attributes_to_set = { - MakeAttribute(DVR_SURFACE_ATTRIBUTE_Z_ORDER, 0)}; - - // Test invalid args. - EXPECT_EQ(-EINVAL, dvrSurfaceSetAttributes(nullptr, attributes_to_set.data(), - attributes_to_set.size())); - EXPECT_EQ(-EINVAL, dvrSurfaceSetAttributes(surface.get(), nullptr, - attributes_to_set.size())); - - // Test attribute change events. - ASSERT_EQ(0, dvrSurfaceSetAttributes(surface.get(), attributes_to_set.data(), - attributes_to_set.size())); - ASSERT_STATUS_OK(manager_->WaitForUpdate()); - - // Verify the attributes changed flag is set. - auto check_flags = [](const auto& value) { - return value & DVR_SURFACE_UPDATE_FLAGS_ATTRIBUTES_CHANGED; - }; - EXPECT_STATUS_PRED(check_flags, manager_->GetUpdateFlags(0)); - - attribute_status = manager_->GetAttributes(0); - ASSERT_STATUS_OK(attribute_status); - attributes = attribute_status.take(); - EXPECT_GE(attributes.size(), 2u); - - expected_keys = {DVR_SURFACE_ATTRIBUTE_Z_ORDER, - DVR_SURFACE_ATTRIBUTE_VISIBLE}; - - actual_keys.clear(); - actual_keys = compare_keys(attributes, expected_keys); - EXPECT_EQ(expected_keys, actual_keys); - - // Test setting and then deleting an attribute. - const DvrSurfaceAttributeKey kUserKey = 1; - attributes_to_set = {MakeAttribute(kUserKey, 1024)}; - - ASSERT_EQ(0, dvrSurfaceSetAttributes(surface.get(), attributes_to_set.data(), - attributes_to_set.size())); - ASSERT_STATUS_OK(manager_->WaitForUpdate()); - EXPECT_STATUS_PRED(check_flags, manager_->GetUpdateFlags(0)); - - attribute_status = manager_->GetAttributes(0); - ASSERT_STATUS_OK(attribute_status); - attributes = attribute_status.take(); - EXPECT_GE(attributes.size(), 2u); - - expected_keys = {DVR_SURFACE_ATTRIBUTE_Z_ORDER, DVR_SURFACE_ATTRIBUTE_VISIBLE, - kUserKey}; - - actual_keys.clear(); - actual_keys = compare_keys(attributes, expected_keys); - EXPECT_EQ(expected_keys, actual_keys); - - // Delete the attribute. - attributes_to_set = {MakeAttribute(kUserKey, nullptr)}; - - ASSERT_EQ(0, dvrSurfaceSetAttributes(surface.get(), attributes_to_set.data(), - attributes_to_set.size())); - ASSERT_STATUS_OK(manager_->WaitForUpdate()); - EXPECT_STATUS_PRED(check_flags, manager_->GetUpdateFlags(0)); - - attribute_status = manager_->GetAttributes(0); - ASSERT_STATUS_OK(attribute_status); - attributes = attribute_status.take(); - EXPECT_GE(attributes.size(), 2u); - - expected_keys = {DVR_SURFACE_ATTRIBUTE_Z_ORDER, DVR_SURFACE_ATTRIBUTE_VISIBLE, - kUserKey}; - - actual_keys.clear(); - actual_keys = compare_keys(attributes, expected_keys); - EXPECT_NE(expected_keys, actual_keys); - - // Test deleting a reserved attribute. - attributes_to_set = {MakeAttribute(DVR_SURFACE_ATTRIBUTE_VISIBLE, nullptr)}; - - EXPECT_EQ(0, dvrSurfaceSetAttributes(surface.get(), attributes_to_set.data(), - attributes_to_set.size())); - - // Failed attribute operations should not trigger update events. - const int kTimeoutMs = 100; // 0.1s - EXPECT_STATUS_ERROR_VALUE(ETIMEDOUT, manager_->WaitForUpdate(kTimeoutMs)); - - attribute_status = manager_->GetAttributes(0); - ASSERT_STATUS_OK(attribute_status); - attributes = attribute_status.take(); - EXPECT_GE(attributes.size(), 2u); - - expected_keys = {DVR_SURFACE_ATTRIBUTE_Z_ORDER, - DVR_SURFACE_ATTRIBUTE_VISIBLE}; - - actual_keys.clear(); - actual_keys = compare_keys(attributes, expected_keys); - EXPECT_EQ(expected_keys, actual_keys); -} - -TEST_F(DvrDisplayManagerTest, SurfaceAttributeTypes) { - // Create an application surface. - auto surface_status = CreateApplicationSurface(); - ASSERT_STATUS_OK(surface_status); - UniqueDvrSurface surface = surface_status.take(); - ASSERT_NE(nullptr, surface.get()); - - enum : std::int32_t { - kInt32Key = 1, - kInt64Key, - kBoolKey, - kFloatKey, - kFloat2Key, - kFloat3Key, - kFloat4Key, - kFloat8Key, - kFloat16Key, - }; - - const std::vector<DvrSurfaceAttribute> attributes_to_set = { - MakeAttribute(kInt32Key, int32_t{0}), - MakeAttribute(kInt64Key, int64_t{0}), - MakeAttribute(kBoolKey, false), - MakeAttribute(kFloatKey, 0.0f), - MakeAttribute(kFloat2Key, std::array<float, 2>{{1.0f, 2.0f}}), - MakeAttribute(kFloat3Key, std::array<float, 3>{{3.0f, 4.0f, 5.0f}}), - MakeAttribute(kFloat4Key, std::array<float, 4>{{6.0f, 7.0f, 8.0f, 9.0f}}), - MakeAttribute(kFloat8Key, - std::array<float, 8>{{10.0f, 11.0f, 12.0f, 13.0f, 14.0f, - 15.0f, 16.0f, 17.0f}}), - MakeAttribute(kFloat16Key, std::array<float, 16>{ - {18.0f, 19.0f, 20.0f, 21.0f, 22.0f, 23.0f, - 24.0f, 25.0f, 26.0f, 27.0f, 28.0f, 29.0f, - 30.0f, 31.0f, 32.0f, 33.0f}})}; - - EXPECT_EQ(0, dvrSurfaceSetAttributes(surface.get(), attributes_to_set.data(), - attributes_to_set.size())); - - ASSERT_STATUS_OK(manager_->WaitForUpdate()); - auto attribute_status = manager_->GetAttributes(0); - ASSERT_STATUS_OK(attribute_status); - auto attributes = attribute_status.take(); - EXPECT_GE(attributes.size(), attributes_to_set.size()); - - auto HasAttribute = [](const auto& attributes, - DvrSurfaceAttributeKey key) -> bool { - for (const auto& attribute : attributes) { - if (attribute.key == key) - return true; - } - return false; - }; - auto AttributeType = - [](const auto& attributes, - DvrSurfaceAttributeKey key) -> DvrSurfaceAttributeType { - for (const auto& attribute : attributes) { - if (attribute.key == key) - return attribute.value.type; - } - return DVR_SURFACE_ATTRIBUTE_TYPE_NONE; - }; - - ASSERT_TRUE(HasAttribute(attributes, kInt32Key)); - EXPECT_EQ(DVR_SURFACE_ATTRIBUTE_TYPE_INT32, - AttributeType(attributes, kInt32Key)); - - ASSERT_TRUE(HasAttribute(attributes, kInt64Key)); - EXPECT_EQ(DVR_SURFACE_ATTRIBUTE_TYPE_INT64, - AttributeType(attributes, kInt64Key)); - - ASSERT_TRUE(HasAttribute(attributes, kBoolKey)); - EXPECT_EQ(DVR_SURFACE_ATTRIBUTE_TYPE_BOOL, - AttributeType(attributes, kBoolKey)); - - ASSERT_TRUE(HasAttribute(attributes, kFloatKey)); - EXPECT_EQ(DVR_SURFACE_ATTRIBUTE_TYPE_FLOAT, - AttributeType(attributes, kFloatKey)); - - ASSERT_TRUE(HasAttribute(attributes, kFloat2Key)); - EXPECT_EQ(DVR_SURFACE_ATTRIBUTE_TYPE_FLOAT2, - AttributeType(attributes, kFloat2Key)); - - ASSERT_TRUE(HasAttribute(attributes, kFloat3Key)); - EXPECT_EQ(DVR_SURFACE_ATTRIBUTE_TYPE_FLOAT3, - AttributeType(attributes, kFloat3Key)); - - ASSERT_TRUE(HasAttribute(attributes, kFloat4Key)); - EXPECT_EQ(DVR_SURFACE_ATTRIBUTE_TYPE_FLOAT4, - AttributeType(attributes, kFloat4Key)); - - ASSERT_TRUE(HasAttribute(attributes, kFloat8Key)); - EXPECT_EQ(DVR_SURFACE_ATTRIBUTE_TYPE_FLOAT8, - AttributeType(attributes, kFloat8Key)); - - ASSERT_TRUE(HasAttribute(attributes, kFloat16Key)); - EXPECT_EQ(DVR_SURFACE_ATTRIBUTE_TYPE_FLOAT16, - AttributeType(attributes, kFloat16Key)); -} - -TEST_F(DvrDisplayManagerTest, SurfaceQueueEvent) { - // Create an application surface. - auto surface_status = CreateApplicationSurface(); - ASSERT_STATUS_OK(surface_status); - UniqueDvrSurface surface = surface_status.take(); - ASSERT_NE(nullptr, surface.get()); - - const int surface_id = dvrSurfaceGetId(surface.get()); - ASSERT_GE(surface_id, 0); - // Get surface state and verify there is one surface. - ASSERT_STATUS_OK(manager_->WaitForUpdate()); - ASSERT_STATUS_EQ(1u, manager_->GetSurfaceCount()); - - // Verify there are no queues for the surface recorded in the state - // snapshot. - EXPECT_STATUS_EQ(std::vector<int>{}, manager_->GetQueueIds(0)); - - // Create a new queue in the surface. - auto write_queue_status = CreateSurfaceQueue( - surface, 320, 240, AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM, 1, - AHARDWAREBUFFER_USAGE_CPU_READ_RARELY, 1, 0); - ASSERT_STATUS_OK(write_queue_status); - UniqueDvrWriteBufferQueue write_queue = write_queue_status.take(); - ASSERT_NE(nullptr, write_queue.get()); - - const int queue_id = dvrWriteBufferQueueGetId(write_queue.get()); - ASSERT_GE(queue_id, 0); - - // Update surface state. - ASSERT_STATUS_OK(manager_->WaitForUpdate()); - ASSERT_STATUS_EQ(1u, manager_->GetSurfaceCount()); - - // Verify the buffers changed flag is set. - auto check_flags = [](const auto& value) { - return value & DVR_SURFACE_UPDATE_FLAGS_BUFFERS_CHANGED; - }; - EXPECT_STATUS_PRED(check_flags, manager_->GetUpdateFlags(0)); - - auto queue_ids_status = manager_->GetQueueIds(0); - ASSERT_STATUS_OK(queue_ids_status); - - auto queue_ids = queue_ids_status.take(); - ASSERT_EQ(1u, queue_ids.size()); - EXPECT_EQ(queue_id, queue_ids[0]); - - auto read_queue_status = manager_->GetReadBufferQueue(surface_id, queue_id); - ASSERT_STATUS_OK(read_queue_status); - UniqueDvrReadBufferQueue read_queue = read_queue_status.take(); - ASSERT_NE(nullptr, read_queue.get()); - EXPECT_EQ(queue_id, dvrReadBufferQueueGetId(read_queue.get())); - - write_queue.reset(); - - // Verify that destroying the queue generates a surface update event. - ASSERT_STATUS_OK(manager_->WaitForUpdate()); - ASSERT_STATUS_EQ(1u, manager_->GetSurfaceCount()); - - // Verify that the buffers changed flag is set. - EXPECT_STATUS_PRED(check_flags, manager_->GetUpdateFlags(0)); - - // Verify that the queue ids reflect the change. - queue_ids_status = manager_->GetQueueIds(0); - ASSERT_STATUS_OK(queue_ids_status); - - queue_ids = queue_ids_status.take(); - ASSERT_EQ(0u, queue_ids.size()); -} - -TEST_F(DvrDisplayManagerTest, MultiLayerBufferQueue) { - // Create an application surface. - auto surface_status = CreateApplicationSurface(); - ASSERT_STATUS_OK(surface_status); - UniqueDvrSurface surface = surface_status.take(); - ASSERT_NE(nullptr, surface.get()); - - // Get surface state and verify there is one surface. - ASSERT_STATUS_OK(manager_->WaitForUpdate()); - ASSERT_STATUS_EQ(1u, manager_->GetSurfaceCount()); - - // Create a new queue in the surface. - const uint32_t kLayerCount = 3; - auto write_queue_status = CreateSurfaceQueue( - surface, 320, 240, AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM, kLayerCount, - AHARDWAREBUFFER_USAGE_CPU_READ_RARELY, 1, 0); - ASSERT_STATUS_OK(write_queue_status); - UniqueDvrWriteBufferQueue write_queue = write_queue_status.take(); - ASSERT_NE(nullptr, write_queue.get()); - - DvrWriteBuffer* buffer = nullptr; - DvrNativeBufferMetadata metadata; - int fence_fd = -1; - int error = dvrWriteBufferQueueGainBuffer(write_queue.get(), /*timeout=*/1000, - &buffer, &metadata, &fence_fd); - ASSERT_EQ(0, error); - - AHardwareBuffer* hardware_buffer = nullptr; - error = dvrWriteBufferGetAHardwareBuffer(buffer, &hardware_buffer); - ASSERT_EQ(0, error); - - AHardwareBuffer_Desc desc = {}; - AHardwareBuffer_describe(hardware_buffer, &desc); - ASSERT_EQ(kLayerCount, desc.layers); - - AHardwareBuffer_release(hardware_buffer); - dvrWriteBufferDestroy(buffer); -} - -TEST_F(Test, ConfigurationData) { - // TODO(hendrikw): Move this test and GetConfigData helper function out of the - // display manager tests. - auto data1 = GetConfigData(-1); - ASSERT_STATUS_ERROR(data1); - - const char kDvrLensMetricsProperty[] = "ro.dvr.lens_metrics"; - - // This should be run on devices with and without built in metrics. - bool has_metric = !base::GetProperty(kDvrLensMetricsProperty, "").empty(); - auto data2 = GetConfigData(DVR_CONFIGURATION_DATA_LENS_METRICS); - if (has_metric) { - ASSERT_STATUS_OK(data2); - ASSERT_NE(0u, data2.get().size()); - } else { - ASSERT_STATUS_ERROR(data2); - } -} - -} // namespace - -} // namespace dvr -} // namespace android diff --git a/libs/vr/libdvr/tests/dvr_named_buffer-test.cpp b/libs/vr/libdvr/tests/dvr_named_buffer-test.cpp deleted file mode 100644 index 5c837e74ea..0000000000 --- a/libs/vr/libdvr/tests/dvr_named_buffer-test.cpp +++ /dev/null @@ -1,284 +0,0 @@ -#include <android/hardware_buffer.h> -#include <dvr/dvr_buffer.h> -#include <dvr/dvr_config.h> -#include <dvr/dvr_shared_buffers.h> -#include <dvr/dvr_surface.h> -#include <system/graphics.h> - -#include <gtest/gtest.h> - -namespace android { -namespace dvr { - -namespace { - -TEST(DvrGlobalBufferTest, TestGlobalBuffersSameName) { - const DvrGlobalBufferKey buffer_key = 101; - DvrBuffer* buffer1 = nullptr; - int ret1 = dvrSetupGlobalBuffer(buffer_key, 10, 0, &buffer1); - ASSERT_EQ(0, ret1); - ASSERT_NE(nullptr, buffer1); - - DvrBuffer* buffer2 = nullptr; - int ret2 = dvrSetupGlobalBuffer(buffer_key, 10, 0, &buffer2); - ASSERT_EQ(0, ret2); - ASSERT_NE(nullptr, buffer2); - - AHardwareBuffer* hardware_buffer1 = nullptr; - int e1 = dvrBufferGetAHardwareBuffer(buffer1, &hardware_buffer1); - ASSERT_EQ(0, e1); - ASSERT_NE(nullptr, hardware_buffer1); - - AHardwareBuffer* hardware_buffer2 = nullptr; - int e2 = dvrBufferGetAHardwareBuffer(buffer2, &hardware_buffer2); - ASSERT_EQ(0, e2); - ASSERT_NE(nullptr, hardware_buffer2); - - AHardwareBuffer_Desc desc1 = {}; - AHardwareBuffer_describe(hardware_buffer1, &desc1); - AHardwareBuffer_Desc desc2 = {}; - AHardwareBuffer_describe(hardware_buffer2, &desc2); - ASSERT_EQ(desc1.width, 10u); - ASSERT_EQ(desc1.height, 1u); - ASSERT_EQ(desc1.layers, 1u); - ASSERT_EQ(desc1.format, HAL_PIXEL_FORMAT_BLOB); - ASSERT_EQ(desc1.usage, 0u); - ASSERT_EQ(desc2.width, 10u); - ASSERT_EQ(desc2.height, 1u); - ASSERT_EQ(desc2.layers, 1u); - ASSERT_EQ(desc2.format, HAL_PIXEL_FORMAT_BLOB); - ASSERT_EQ(desc2.usage, 0u); - - dvrBufferDestroy(buffer1); - dvrBufferDestroy(buffer2); - - DvrBuffer* buffer3 = nullptr; - int e3 = dvrGetGlobalBuffer(buffer_key, &buffer3); - ASSERT_NE(nullptr, buffer3); - ASSERT_EQ(0, e3); - - AHardwareBuffer* hardware_buffer3 = nullptr; - int e4 = dvrBufferGetAHardwareBuffer(buffer3, &hardware_buffer3); - ASSERT_EQ(0, e4); - ASSERT_NE(nullptr, hardware_buffer3); - - AHardwareBuffer_Desc desc3 = {}; - AHardwareBuffer_describe(hardware_buffer3, &desc3); - ASSERT_EQ(desc3.width, 10u); - ASSERT_EQ(desc3.height, 1u); - ASSERT_EQ(desc3.layers, 1u); - ASSERT_EQ(desc3.format, HAL_PIXEL_FORMAT_BLOB); - ASSERT_EQ(desc3.usage, 0u); - - dvrBufferDestroy(buffer3); - - AHardwareBuffer_release(hardware_buffer1); - AHardwareBuffer_release(hardware_buffer2); - AHardwareBuffer_release(hardware_buffer3); -} - -TEST(DvrGlobalBufferTest, TestMultipleGlobalBuffers) { - const DvrGlobalBufferKey buffer_key1 = 102; - const DvrGlobalBufferKey buffer_key2 = 103; - DvrBuffer* setup_buffer1 = nullptr; - int ret1 = dvrSetupGlobalBuffer(buffer_key1, 10, 0, &setup_buffer1); - ASSERT_EQ(0, ret1); - ASSERT_NE(nullptr, setup_buffer1); - dvrBufferDestroy(setup_buffer1); - - DvrBuffer* setup_buffer2 = nullptr; - int ret2 = dvrSetupGlobalBuffer(buffer_key2, 10, 0, &setup_buffer2); - ASSERT_EQ(0, ret2); - ASSERT_NE(nullptr, setup_buffer2); - dvrBufferDestroy(setup_buffer2); - - DvrBuffer* buffer1 = nullptr; - int e1 = dvrGetGlobalBuffer(buffer_key1, &buffer1); - ASSERT_NE(nullptr, buffer1); - ASSERT_EQ(0, e1); - dvrBufferDestroy(buffer1); - - DvrBuffer* buffer2 = nullptr; - int e2 = dvrGetGlobalBuffer(buffer_key2, &buffer2); - ASSERT_NE(nullptr, buffer2); - ASSERT_EQ(0, e2); - dvrBufferDestroy(buffer2); -} - -TEST(DvrGlobalBufferTest, TestGlobalBufferUsage) { - const DvrGlobalBufferKey buffer_key = 100; - - // Set usage to AHARDWAREBUFFER_USAGE_VIDEO_ENCODE. We use this because - // internally AHARDWAREBUFFER_USAGE_VIDEO_ENCODE is converted to - // GRALLOC1_CONSUMER_USAGE_VIDEO_ENCODER, and these two values are different. - // If all is good, when we get the AHardwareBuffer, it should be converted - // back to AHARDWAREBUFFER_USAGE_VIDEO_ENCODE. - const uint64_t usage = AHARDWAREBUFFER_USAGE_VIDEO_ENCODE; - - DvrBuffer* setup_buffer = nullptr; - int e1 = dvrSetupGlobalBuffer(buffer_key, 10, usage, &setup_buffer); - ASSERT_NE(nullptr, setup_buffer); - ASSERT_EQ(0, e1); - - AHardwareBuffer* hardware_buffer = nullptr; - int e2 = dvrBufferGetAHardwareBuffer(setup_buffer, &hardware_buffer); - ASSERT_EQ(0, e2); - ASSERT_NE(nullptr, hardware_buffer); - - AHardwareBuffer_Desc desc = {}; - AHardwareBuffer_describe(hardware_buffer, &desc); - ASSERT_EQ(usage, desc.usage); - - dvrBufferDestroy(setup_buffer); - AHardwareBuffer_release(hardware_buffer); -} - -TEST(DvrGlobalBufferTest, TestGlobalBufferCarriesData) { - const DvrGlobalBufferKey buffer_name = 110; - - uint64_t usage = AHARDWAREBUFFER_USAGE_CPU_READ_OFTEN | - AHARDWAREBUFFER_USAGE_CPU_WRITE_OFTEN; - constexpr size_t size = 1024 * sizeof(uint64_t); - constexpr uint64_t value = 0x123456787654321; - - { - // Allocate some data and set it to something. - DvrBuffer* setup_buffer = nullptr; - int e1 = dvrSetupGlobalBuffer(buffer_name, size, usage, &setup_buffer); - ASSERT_NE(nullptr, setup_buffer); - ASSERT_EQ(0, e1); - - AHardwareBuffer* hardware_buffer = nullptr; - int e2 = dvrBufferGetAHardwareBuffer(setup_buffer, &hardware_buffer); - ASSERT_EQ(0, e2); - ASSERT_NE(nullptr, hardware_buffer); - - void* buffer; - int e3 = AHardwareBuffer_lock(hardware_buffer, usage, -1, nullptr, &buffer); - ASSERT_EQ(0, e3); - ASSERT_NE(nullptr, buffer); - // Verify that the buffer pointer is at least 16 byte aligned. - ASSERT_EQ(0U, reinterpret_cast<uintptr_t>(buffer) & (16 - 1)); - - uint64_t* data = static_cast<uint64_t*>(buffer); - constexpr size_t num_values = size / sizeof(uint64_t); - for (size_t i = 0; i < num_values; ++i) { - data[i] = value; - } - - int32_t fence = -1; - int e4 = AHardwareBuffer_unlock(hardware_buffer, &fence); - ASSERT_EQ(0, e4); - - dvrBufferDestroy(setup_buffer); - AHardwareBuffer_release(hardware_buffer); - } - - { - // Get the buffer and check that all the data is still present. - DvrBuffer* setup_buffer = nullptr; - int e1 = dvrGetGlobalBuffer(buffer_name, &setup_buffer); - ASSERT_NE(nullptr, setup_buffer); - ASSERT_EQ(0, e1); - - AHardwareBuffer* hardware_buffer = nullptr; - int e2 = dvrBufferGetAHardwareBuffer(setup_buffer, &hardware_buffer); - ASSERT_EQ(0, e2); - ASSERT_NE(nullptr, hardware_buffer); - - void* buffer; - int e3 = AHardwareBuffer_lock(hardware_buffer, usage, -1, nullptr, &buffer); - ASSERT_EQ(0, e3); - ASSERT_NE(nullptr, buffer); - // Verify that the buffer pointer is at least 16 byte aligned. - ASSERT_EQ(0U, reinterpret_cast<uintptr_t>(buffer) & (16 - 1)); - - uint64_t* data = static_cast<uint64_t*>(buffer); - constexpr size_t num_values = size / sizeof(uint64_t); - bool is_equal = true; - for (size_t i = 0; i < num_values; ++i) { - is_equal &= (data[i] == value); - } - ASSERT_TRUE(is_equal); - - int32_t fence = -1; - int e4 = AHardwareBuffer_unlock(hardware_buffer, &fence); - ASSERT_EQ(0, e4); - - dvrBufferDestroy(setup_buffer); - AHardwareBuffer_release(hardware_buffer); - } -} - -TEST(DvrGlobalBufferTest, TestGlobalBufferZeroed) { - const DvrGlobalBufferKey buffer_name = 120; - - // Allocate 1MB and check that it is all zeros. - uint64_t usage = AHARDWAREBUFFER_USAGE_CPU_READ_OFTEN | - AHARDWAREBUFFER_USAGE_CPU_WRITE_OFTEN; - constexpr size_t size = 1024 * 1024; - DvrBuffer* setup_buffer = nullptr; - int e1 = dvrSetupGlobalBuffer(buffer_name, size, usage, &setup_buffer); - ASSERT_NE(nullptr, setup_buffer); - ASSERT_EQ(0, e1); - - AHardwareBuffer* hardware_buffer = nullptr; - int e2 = dvrBufferGetAHardwareBuffer(setup_buffer, &hardware_buffer); - ASSERT_EQ(0, e2); - ASSERT_NE(nullptr, hardware_buffer); - - void* buffer; - int e3 = AHardwareBuffer_lock(hardware_buffer, usage, -1, nullptr, &buffer); - ASSERT_EQ(0, e3); - ASSERT_NE(nullptr, buffer); - // Verify that the buffer pointer is at least 16 byte aligned. - ASSERT_EQ(0U, reinterpret_cast<uintptr_t>(buffer) & (16 - 1)); - - uint64_t* data = static_cast<uint64_t*>(buffer); - constexpr size_t num_values = size / sizeof(uint64_t); - uint64_t zero = 0; - for (size_t i = 0; i < num_values; ++i) { - zero |= data[i]; - } - ASSERT_EQ(0U, zero); - - int32_t fence = -1; - int e4 = AHardwareBuffer_unlock(hardware_buffer, &fence); - ASSERT_EQ(0, e4); - - dvrBufferDestroy(setup_buffer); - AHardwareBuffer_release(hardware_buffer); -} - -TEST(DvrGlobalBufferTest, TestVrflingerConfigBuffer) { - const DvrGlobalBufferKey buffer_name = - DvrGlobalBuffers::kVrFlingerConfigBufferKey; - - // First delete any existing buffer so we can test the failure case. - dvrDeleteGlobalBuffer(buffer_name); - - const uint64_t usage = AHARDWAREBUFFER_USAGE_CPU_READ_OFTEN | - AHARDWAREBUFFER_USAGE_CPU_WRITE_RARELY; - - size_t correct_size = DvrConfigRing::MemorySize(); - size_t wrong_size = DvrConfigRing::MemorySize(0); - - // Setup an invalid config buffer (too small) and assert that it fails. - DvrBuffer* setup_buffer = nullptr; - int e1 = dvrSetupGlobalBuffer(buffer_name, wrong_size, usage, &setup_buffer); - ASSERT_EQ(nullptr, setup_buffer); - ASSERT_GT(0, e1); - - // Setup a correct config buffer. - int e2 = - dvrSetupGlobalBuffer(buffer_name, correct_size, usage, &setup_buffer); - ASSERT_NE(nullptr, setup_buffer); - ASSERT_EQ(0, e2); - - dvrBufferDestroy(setup_buffer); -} - -} // namespace - -} // namespace dvr -} // namespace android diff --git a/libs/vr/libdvr/tests/dvr_tracking-test.cpp b/libs/vr/libdvr/tests/dvr_tracking-test.cpp deleted file mode 100644 index 3b6d6e1ec4..0000000000 --- a/libs/vr/libdvr/tests/dvr_tracking-test.cpp +++ /dev/null @@ -1,103 +0,0 @@ -#include <android/log.h> -#include <gtest/gtest.h> - -#include "dvr_api_test.h" - -namespace { - -class DvrTrackingTest : public DvrApiTest {}; - -#if DVR_TRACKING_IMPLEMENTED - -TEST_F(DvrTrackingTest, Implemented) { - ASSERT_TRUE(api_.TrackingCameraCreate != nullptr); - ASSERT_TRUE(api_.TrackingCameraStart != nullptr); - ASSERT_TRUE(api_.TrackingCameraStop != nullptr); - - ASSERT_TRUE(api_.TrackingFeatureExtractorCreate != nullptr); - ASSERT_TRUE(api_.TrackingFeatureExtractorDestroy != nullptr); - ASSERT_TRUE(api_.TrackingFeatureExtractorStart != nullptr); - ASSERT_TRUE(api_.TrackingFeatureExtractorStop != nullptr); - ASSERT_TRUE(api_.TrackingFeatureExtractorProcessBuffer != nullptr); -} - -TEST_F(DvrTrackingTest, CameraCreateFailsForInvalidInput) { - int ret; - ret = api_.TrackingCameraCreate(nullptr); - EXPECT_EQ(ret, -EINVAL); - - DvrTrackingCamera* camera = reinterpret_cast<DvrTrackingCamera*>(42); - ret = api_.TrackingCameraCreate(&camera); - EXPECT_EQ(ret, -EINVAL); -} - -TEST_F(DvrTrackingTest, CameraCreateDestroy) { - DvrTrackingCamera* camera = nullptr; - int ret = api_.TrackingCameraCreate(&camera); - - EXPECT_EQ(ret, 0); - ASSERT_TRUE(camera != nullptr); - - api_.TrackingCameraDestroy(camera); -} - -TEST_F(DvrTrackingTest, FeatureExtractorCreateFailsForInvalidInput) { - int ret; - ret = api_.TrackingFeatureExtractorCreate(nullptr); - EXPECT_EQ(ret, -EINVAL); - - DvrTrackingFeatureExtractor* camera = - reinterpret_cast<DvrTrackingFeatureExtractor*>(42); - ret = api_.TrackingFeatureExtractorCreate(&camera); - EXPECT_EQ(ret, -EINVAL); -} - -TEST_F(DvrTrackingTest, FeatureExtractorCreateDestroy) { - DvrTrackingFeatureExtractor* camera = nullptr; - int ret = api_.TrackingFeatureExtractorCreate(&camera); - - EXPECT_EQ(ret, 0); - ASSERT_TRUE(camera != nullptr); - - api_.TrackingFeatureExtractorDestroy(camera); -} - -#else // !DVR_TRACKING_IMPLEMENTED - -TEST_F(DvrTrackingTest, NotImplemented) { - ASSERT_TRUE(api_.TrackingCameraCreate != nullptr); - ASSERT_TRUE(api_.TrackingCameraDestroy != nullptr); - ASSERT_TRUE(api_.TrackingCameraStart != nullptr); - ASSERT_TRUE(api_.TrackingCameraStop != nullptr); - - EXPECT_EQ(api_.TrackingCameraCreate(nullptr), -ENOSYS); - EXPECT_EQ(api_.TrackingCameraStart(nullptr, nullptr), -ENOSYS); - EXPECT_EQ(api_.TrackingCameraStop(nullptr), -ENOSYS); - - ASSERT_TRUE(api_.TrackingFeatureExtractorCreate != nullptr); - ASSERT_TRUE(api_.TrackingFeatureExtractorDestroy != nullptr); - ASSERT_TRUE(api_.TrackingFeatureExtractorStart != nullptr); - ASSERT_TRUE(api_.TrackingFeatureExtractorStop != nullptr); - ASSERT_TRUE(api_.TrackingFeatureExtractorProcessBuffer != nullptr); - - EXPECT_EQ(api_.TrackingFeatureExtractorCreate(nullptr), -ENOSYS); - EXPECT_EQ(api_.TrackingFeatureExtractorStart(nullptr, nullptr, nullptr), - -ENOSYS); - EXPECT_EQ(api_.TrackingFeatureExtractorStop(nullptr), -ENOSYS); - EXPECT_EQ(api_.TrackingFeatureExtractorProcessBuffer(nullptr, nullptr, - nullptr, nullptr), - -ENOSYS); - - ASSERT_TRUE(api_.TrackingSensorsCreate != nullptr); - ASSERT_TRUE(api_.TrackingSensorsDestroy != nullptr); - ASSERT_TRUE(api_.TrackingSensorsStart != nullptr); - ASSERT_TRUE(api_.TrackingSensorsStop != nullptr); - - EXPECT_EQ(api_.TrackingSensorsCreate(nullptr, nullptr), -ENOSYS); - EXPECT_EQ(api_.TrackingSensorsStart(nullptr, nullptr, nullptr), -ENOSYS); - EXPECT_EQ(api_.TrackingSensorsStop(nullptr), -ENOSYS); -} - -#endif // DVR_TRACKING_IMPLEMENTED - -} // namespace |