From 1436aefcffbc33ffc9237ef961c2621fe47311bb Mon Sep 17 00:00:00 2001 From: Peter Collingbourne Date: Fri, 30 Sep 2022 10:46:59 -0700 Subject: Remove bufferhub support from libgui. As far as I can tell the bufferhub support in libgui was never completed, and it is unused except for tests and the libdvr library (which is also unused except for benchmarks and tests, which I also removed, and its headers which I kept for now). This will allow building the platform with newer compilers that diagnose invalid code in libpdx, one of bufferhub's dependencies. Bug: 246977679 Change-Id: Iff5f879c2bb5583e789a604d64638e8ce7d2b2c5 --- libs/gui/Android.bp | 24 - libs/gui/BufferHubConsumer.cpp | 161 ----- libs/gui/BufferHubProducer.cpp | 868 ------------------------- libs/gui/BufferQueue.cpp | 33 - libs/gui/IGraphicBufferProducer.cpp | 14 - libs/gui/include/gui/BufferHubConsumer.h | 112 ---- libs/gui/include/gui/BufferHubProducer.h | 223 ------- libs/gui/include/gui/BufferQueue.h | 6 - libs/gui/tests/Android.bp | 33 - libs/gui/tests/IGraphicBufferProducer_test.cpp | 21 - libs/gui/tests/SurfaceParcelable_test.cpp | 168 ----- 11 files changed, 1663 deletions(-) delete mode 100644 libs/gui/BufferHubConsumer.cpp delete mode 100644 libs/gui/BufferHubProducer.cpp delete mode 100644 libs/gui/include/gui/BufferHubConsumer.h delete mode 100644 libs/gui/include/gui/BufferHubProducer.h delete mode 100644 libs/gui/tests/SurfaceParcelable_test.cpp (limited to 'libs/gui') diff --git a/libs/gui/Android.bp b/libs/gui/Android.bp index 56b17aecb2..6c39bbf716 100644 --- a/libs/gui/Android.bp +++ b/libs/gui/Android.bp @@ -177,8 +177,6 @@ cc_library_shared { "BitTube.cpp", "BLASTBufferQueue.cpp", - "BufferHubConsumer.cpp", - "BufferHubProducer.cpp", "BufferItemConsumer.cpp", "ConsumerBase.cpp", "CpuConsumer.cpp", @@ -216,9 +214,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: [ @@ -229,24 +224,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, }, @@ -276,7 +253,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 - -namespace android { - -using namespace dvr; - -/* static */ -sp BufferHubConsumer::Create(const std::shared_ptr& queue) { - sp consumer = new BufferHubConsumer; - consumer->mQueue = queue; - return consumer; -} - -/* static */ sp BufferHubConsumer::Create(ConsumerQueueParcelable parcelable) { - if (!parcelable.IsValid()) { - ALOGE("BufferHubConsumer::Create: Invalid consumer parcelable."); - return nullptr; - } - - sp 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& /*buffer*/) { - ALOGE("BufferHubConsumer::attachBuffer: not implemented."); - return INVALID_OPERATION; -} - -status_t BufferHubConsumer::releaseBuffer(int /*buf*/, uint64_t /*frameNumber*/, - EGLDisplay /*display*/, EGLSyncKHR /*fence*/, - const sp& /*releaseFence*/) { - ALOGE("BufferHubConsumer::releaseBuffer: not implemented."); - return INVALID_OPERATION; -} - -status_t BufferHubConsumer::consumerConnect(const sp& /*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* /*outStream*/) const { - ALOGE("BufferHubConsumer::getSidebandStream: not implemented."); - return INVALID_OPERATION; -} - -status_t BufferHubConsumer::getOccupancyHistory( - bool /*forceFlush*/, std::vector* /*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 -#include -#include -#include -#include - -namespace android { - -using namespace dvr; - -/* static */ -sp BufferHubProducer::Create(const std::shared_ptr& queue) { - sp producer = new BufferHubProducer; - producer->queue_ = queue; - return producer; -} - -/* static */ -sp BufferHubProducer::Create(ProducerQueueParcelable parcelable) { - if (!parcelable.IsValid()) { - ALOGE("BufferHubProducer::Create: Invalid producer parcelable."); - return nullptr; - } - - sp producer = new BufferHubProducer; - producer->queue_ = ProducerQueue::Import(parcelable.TakeChannelHandle()); - return producer; -} - -status_t BufferHubProducer::requestBuffer(int slot, sp* buf) { - ALOGV("requestBuffer: slot=%d", slot); - - std::unique_lock 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 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 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* 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 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 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 lock(mutex_); - - return DetachBufferLocked(static_cast(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(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 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 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* out_buffer, sp* 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 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 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 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& 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 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; - - 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 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) { - ALOGV(__FUNCTION__); - - std::unique_lock 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 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& /* 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 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 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& 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 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 lock(mutex_); - dequeue_timeout_ms_ = static_cast(timeout / (1000 * 1000)); - return NO_ERROR; -} - -status_t BufferHubProducer::getLastQueuedBuffer(sp* /* out_buffer */, - sp* /* 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 -#include -#endif - #include #include #include @@ -127,32 +122,4 @@ void BufferQueue::createBufferQueue(sp* outProducer, *outConsumer = consumer; } -#ifndef NO_BUFFERHUB -void BufferQueue::createBufferHubQueue(sp* outProducer, - sp* 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 producer; - sp consumer; - - dvr::ProducerQueueConfigBuilder configBuilder; - std::shared_ptr producerQueue = - dvr::ProducerQueue::Create(configBuilder.Build(), dvr::UsagePolicy{}); - LOG_ALWAYS_FATAL_IF(producerQueue == nullptr, "BufferQueue: failed to create ProducerQueue."); - - std::shared_ptr 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 #include -#ifndef NO_BUFFERHUB -#include -#endif - #include #include #include @@ -1012,17 +1008,7 @@ sp 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 -#include -#include - -namespace android { - -class BufferHubConsumer : public IGraphicBufferConsumer { -public: - // Creates a BufferHubConsumer instance by importing an existing producer queue. - static sp Create(const std::shared_ptr& 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 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& buffer) override; - - // See |IGraphicBufferConsumer::releaseBuffer| - status_t releaseBuffer(int buf, uint64_t frameNumber, EGLDisplay display, EGLSyncKHR fence, - const sp& releaseFence) override; - - // See |IGraphicBufferConsumer::consumerConnect| - status_t consumerConnect(const sp& 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* outStream) const override; - - // See |IGraphicBufferConsumer::getOccupancyHistory| - status_t getOccupancyHistory(bool forceFlush, - std::vector* 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 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 -#include -#include -#include - -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 Create(const std::shared_ptr& 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 Create(dvr::ProducerQueueParcelable parcelable); - - // See |IGraphicBufferProducer::requestBuffer| - status_t requestBuffer(int slot, sp* 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* 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* out_buffer, sp* out_fence) override; - - // See |IGraphicBufferProducer::attachBuffer| - status_t attachBuffer(int* out_slot, const sp& 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) override; - - // See |IGraphicBufferProducer::query| - status_t query(int what, int* out_value) override; - - // See |IGraphicBufferProducer::connect| - status_t connect(const sp& 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& 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* out_buffer, sp* 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 counter{0}; - static uint64_t id = static_cast(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 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 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* outConsumer, bool consumerIsSurfaceFlinger = false); -#ifndef NO_BUFFERHUB - // Creates an IGraphicBufferProducer and IGraphicBufferConsumer pair backed by BufferHub. - static void createBufferHubQueue(sp* outProducer, - sp* outConsumer); -#endif - BufferQueue() = delete; // Create through createBufferQueue }; diff --git a/libs/gui/tests/Android.bp b/libs/gui/tests/Android.bp index fc68ad27c5..fa54c7d1f6 100644 --- a/libs/gui/tests/Android.bp +++ b/libs/gui/tests/Android.bp @@ -92,39 +92,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 - -#include -#include -#include -#include -#include -#include - -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 mBufferQueueProducer; - sp mBufferQueueConsumer; - - std::shared_ptr mProducerQueue; - sp mBufferHubProducer; -}; - -static int runBinderServer() { - ProcessState::self()->startThreadPool(); - - sp sm = defaultServiceManager(); - sp 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 { -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 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(); - } -} -- cgit v1.2.3-59-g8ed1b