1e93355155764df62c1bb71f67a0796b33fe7a452Pin-chih Lin/* 2e93355155764df62c1bb71f67a0796b33fe7a452Pin-chih Lin * Copyright 2018, The Android Open Source Project 3e93355155764df62c1bb71f67a0796b33fe7a452Pin-chih Lin * 4e93355155764df62c1bb71f67a0796b33fe7a452Pin-chih Lin * Licensed under the Apache License, Version 2.0 (the "License"); 5e93355155764df62c1bb71f67a0796b33fe7a452Pin-chih Lin * you may not use this file except in compliance with the License. 6e93355155764df62c1bb71f67a0796b33fe7a452Pin-chih Lin * You may obtain a copy of the License at 7e93355155764df62c1bb71f67a0796b33fe7a452Pin-chih Lin * 8e93355155764df62c1bb71f67a0796b33fe7a452Pin-chih Lin * http://www.apache.org/licenses/LICENSE-2.0 9e93355155764df62c1bb71f67a0796b33fe7a452Pin-chih Lin * 10e93355155764df62c1bb71f67a0796b33fe7a452Pin-chih Lin * Unless required by applicable law or agreed to in writing, software 11e93355155764df62c1bb71f67a0796b33fe7a452Pin-chih Lin * distributed under the License is distributed on an "AS IS" BASIS, 12e93355155764df62c1bb71f67a0796b33fe7a452Pin-chih Lin * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13e93355155764df62c1bb71f67a0796b33fe7a452Pin-chih Lin * See the License for the specific language governing permissions and 14e93355155764df62c1bb71f67a0796b33fe7a452Pin-chih Lin * limitations under the License. 15e93355155764df62c1bb71f67a0796b33fe7a452Pin-chih Lin */ 16e93355155764df62c1bb71f67a0796b33fe7a452Pin-chih Lin 17e93355155764df62c1bb71f67a0796b33fe7a452Pin-chih Lin//#define LOG_NDEBUG 0 18e93355155764df62c1bb71f67a0796b33fe7a452Pin-chih Lin#define LOG_TAG "C2VdaBqBlockPool" 19e93355155764df62c1bb71f67a0796b33fe7a452Pin-chih Lin 20e93355155764df62c1bb71f67a0796b33fe7a452Pin-chih Lin#include <errno.h> 21e93355155764df62c1bb71f67a0796b33fe7a452Pin-chih Lin 22e93355155764df62c1bb71f67a0796b33fe7a452Pin-chih Lin#include <mutex> 23e93355155764df62c1bb71f67a0796b33fe7a452Pin-chih Lin 24e93355155764df62c1bb71f67a0796b33fe7a452Pin-chih Lin#include <gui/BufferQueueDefs.h> 25e93355155764df62c1bb71f67a0796b33fe7a452Pin-chih Lin#include <utils/Log.h> 26e93355155764df62c1bb71f67a0796b33fe7a452Pin-chih Lin 27e93355155764df62c1bb71f67a0796b33fe7a452Pin-chih Lin#include <C2AllocatorGralloc.h> 28e93355155764df62c1bb71f67a0796b33fe7a452Pin-chih Lin#include <C2BlockInternal.h> 29e93355155764df62c1bb71f67a0796b33fe7a452Pin-chih Lin#include <v4l2/C2VdaBqBlockPool.h> 30e93355155764df62c1bb71f67a0796b33fe7a452Pin-chih Lin 31e93355155764df62c1bb71f67a0796b33fe7a452Pin-chih Linusing ::android::AnwBuffer; 32e93355155764df62c1bb71f67a0796b33fe7a452Pin-chih Linusing ::android::C2AndroidMemoryUsage; 33e93355155764df62c1bb71f67a0796b33fe7a452Pin-chih Linusing ::android::Fence; 34e93355155764df62c1bb71f67a0796b33fe7a452Pin-chih Linusing ::android::GraphicBuffer; 35e93355155764df62c1bb71f67a0796b33fe7a452Pin-chih Linusing ::android::HGraphicBufferProducer; 36e93355155764df62c1bb71f67a0796b33fe7a452Pin-chih Linusing ::android::hidl_handle; 37e93355155764df62c1bb71f67a0796b33fe7a452Pin-chih Linusing ::android::IGraphicBufferProducer; 38e93355155764df62c1bb71f67a0796b33fe7a452Pin-chih Linusing ::android::sp; 39e93355155764df62c1bb71f67a0796b33fe7a452Pin-chih Linusing ::android::status_t; 40e93355155764df62c1bb71f67a0796b33fe7a452Pin-chih Linusing ::android::hardware::graphics::common::V1_0::PixelFormat; 41e93355155764df62c1bb71f67a0796b33fe7a452Pin-chih Lin 42e93355155764df62c1bb71f67a0796b33fe7a452Pin-chih Linnamespace { 43e93355155764df62c1bb71f67a0796b33fe7a452Pin-chih Lin 44e93355155764df62c1bb71f67a0796b33fe7a452Pin-chih Lin// The wait time for acquire fence in milliseconds. 45e93355155764df62c1bb71f67a0796b33fe7a452Pin-chih Linconst int kFenceWaitTimeMs = 10; 46e93355155764df62c1bb71f67a0796b33fe7a452Pin-chih Lin// The timeout delay for dequeuing buffer from producer in nanoseconds. 47e93355155764df62c1bb71f67a0796b33fe7a452Pin-chih Linconst int64_t kDequeueTimeoutNs = 10 * 1000 * 1000; 48e93355155764df62c1bb71f67a0796b33fe7a452Pin-chih Lin 49e93355155764df62c1bb71f67a0796b33fe7a452Pin-chih Lin} // namespace 50e93355155764df62c1bb71f67a0796b33fe7a452Pin-chih Lin 51e93355155764df62c1bb71f67a0796b33fe7a452Pin-chih Linstatic c2_status_t asC2Error(int32_t err) { 52e93355155764df62c1bb71f67a0796b33fe7a452Pin-chih Lin switch (err) { 53e93355155764df62c1bb71f67a0796b33fe7a452Pin-chih Lin case android::NO_ERROR: 54e93355155764df62c1bb71f67a0796b33fe7a452Pin-chih Lin return C2_OK; 55e93355155764df62c1bb71f67a0796b33fe7a452Pin-chih Lin case android::NO_INIT: 56e93355155764df62c1bb71f67a0796b33fe7a452Pin-chih Lin return C2_NO_INIT; 57e93355155764df62c1bb71f67a0796b33fe7a452Pin-chih Lin case android::BAD_VALUE: 58e93355155764df62c1bb71f67a0796b33fe7a452Pin-chih Lin return C2_BAD_VALUE; 59e93355155764df62c1bb71f67a0796b33fe7a452Pin-chih Lin case android::TIMED_OUT: 60e93355155764df62c1bb71f67a0796b33fe7a452Pin-chih Lin return C2_TIMED_OUT; 61e93355155764df62c1bb71f67a0796b33fe7a452Pin-chih Lin case android::WOULD_BLOCK: 62e93355155764df62c1bb71f67a0796b33fe7a452Pin-chih Lin return C2_BLOCKING; 63e93355155764df62c1bb71f67a0796b33fe7a452Pin-chih Lin case android::NO_MEMORY: 64e93355155764df62c1bb71f67a0796b33fe7a452Pin-chih Lin return C2_NO_MEMORY; 65e93355155764df62c1bb71f67a0796b33fe7a452Pin-chih Lin case -ETIME: 66e93355155764df62c1bb71f67a0796b33fe7a452Pin-chih Lin return C2_TIMED_OUT; // for fence wait 67e93355155764df62c1bb71f67a0796b33fe7a452Pin-chih Lin } 68e93355155764df62c1bb71f67a0796b33fe7a452Pin-chih Lin return C2_CORRUPTED; 69e93355155764df62c1bb71f67a0796b33fe7a452Pin-chih Lin} 70e93355155764df62c1bb71f67a0796b33fe7a452Pin-chih Lin 71e93355155764df62c1bb71f67a0796b33fe7a452Pin-chih LinC2VdaBqBlockPool::C2VdaBqBlockPool(const std::shared_ptr<C2Allocator>& allocator, 72e93355155764df62c1bb71f67a0796b33fe7a452Pin-chih Lin const local_id_t localId) 73e93355155764df62c1bb71f67a0796b33fe7a452Pin-chih Lin : C2BufferQueueBlockPool(allocator, localId), 74e93355155764df62c1bb71f67a0796b33fe7a452Pin-chih Lin mAllocator(allocator), 75e93355155764df62c1bb71f67a0796b33fe7a452Pin-chih Lin mLocalId(localId), 76e93355155764df62c1bb71f67a0796b33fe7a452Pin-chih Lin mMaxDequeuedBuffers(0u) {} 77e93355155764df62c1bb71f67a0796b33fe7a452Pin-chih Lin 78e93355155764df62c1bb71f67a0796b33fe7a452Pin-chih LinC2VdaBqBlockPool::~C2VdaBqBlockPool() { 79e93355155764df62c1bb71f67a0796b33fe7a452Pin-chih Lin std::lock_guard<std::mutex> lock(mMutex); 80e93355155764df62c1bb71f67a0796b33fe7a452Pin-chih Lin cancelAllBuffers(); 81e93355155764df62c1bb71f67a0796b33fe7a452Pin-chih Lin} 82e93355155764df62c1bb71f67a0796b33fe7a452Pin-chih Lin 83e93355155764df62c1bb71f67a0796b33fe7a452Pin-chih Linc2_status_t C2VdaBqBlockPool::fetchGraphicBlock( 84e93355155764df62c1bb71f67a0796b33fe7a452Pin-chih Lin uint32_t width, uint32_t height, uint32_t format, C2MemoryUsage usage, 85e93355155764df62c1bb71f67a0796b33fe7a452Pin-chih Lin std::shared_ptr<C2GraphicBlock>* block /* nonnull */) { 86e93355155764df62c1bb71f67a0796b33fe7a452Pin-chih Lin std::lock_guard<std::mutex> lock(mMutex); 87e93355155764df62c1bb71f67a0796b33fe7a452Pin-chih Lin 88e93355155764df62c1bb71f67a0796b33fe7a452Pin-chih Lin if (!mProducer) { 89e93355155764df62c1bb71f67a0796b33fe7a452Pin-chih Lin // Producer will not be configured in byte-buffer mode. Allocate buffers from allocator 90e93355155764df62c1bb71f67a0796b33fe7a452Pin-chih Lin // directly as a basic graphic block pool. 91e93355155764df62c1bb71f67a0796b33fe7a452Pin-chih Lin std::shared_ptr<C2GraphicAllocation> alloc; 92e93355155764df62c1bb71f67a0796b33fe7a452Pin-chih Lin c2_status_t err = mAllocator->newGraphicAllocation(width, height, format, usage, &alloc); 93e93355155764df62c1bb71f67a0796b33fe7a452Pin-chih Lin if (err != C2_OK) { 94e93355155764df62c1bb71f67a0796b33fe7a452Pin-chih Lin return err; 95e93355155764df62c1bb71f67a0796b33fe7a452Pin-chih Lin } 96e93355155764df62c1bb71f67a0796b33fe7a452Pin-chih Lin *block = _C2BlockFactory::CreateGraphicBlock(alloc); 97e93355155764df62c1bb71f67a0796b33fe7a452Pin-chih Lin return C2_OK; 98e93355155764df62c1bb71f67a0796b33fe7a452Pin-chih Lin } 99e93355155764df62c1bb71f67a0796b33fe7a452Pin-chih Lin 100e93355155764df62c1bb71f67a0796b33fe7a452Pin-chih Lin sp<Fence> fence = new Fence(); 101e93355155764df62c1bb71f67a0796b33fe7a452Pin-chih Lin C2AndroidMemoryUsage androidUsage = usage; 102e93355155764df62c1bb71f67a0796b33fe7a452Pin-chih Lin int32_t status; 103e93355155764df62c1bb71f67a0796b33fe7a452Pin-chih Lin PixelFormat pixelFormat = static_cast<PixelFormat>(format); 104e93355155764df62c1bb71f67a0796b33fe7a452Pin-chih Lin int32_t slot; 105e93355155764df62c1bb71f67a0796b33fe7a452Pin-chih Lin 106e93355155764df62c1bb71f67a0796b33fe7a452Pin-chih Lin mProducer->dequeueBuffer( 107e93355155764df62c1bb71f67a0796b33fe7a452Pin-chih Lin width, height, pixelFormat, androidUsage.asGrallocUsage(), true, 108e93355155764df62c1bb71f67a0796b33fe7a452Pin-chih Lin [&status, &slot, &fence](int32_t tStatus, int32_t tSlot, hidl_handle const& tFence, 109e93355155764df62c1bb71f67a0796b33fe7a452Pin-chih Lin HGraphicBufferProducer::FrameEventHistoryDelta const& tTs) { 110e93355155764df62c1bb71f67a0796b33fe7a452Pin-chih Lin status = tStatus; 111e93355155764df62c1bb71f67a0796b33fe7a452Pin-chih Lin slot = tSlot; 112e93355155764df62c1bb71f67a0796b33fe7a452Pin-chih Lin if (!android::conversion::convertTo(fence.get(), tFence) && 113e93355155764df62c1bb71f67a0796b33fe7a452Pin-chih Lin status == android::NO_ERROR) { 114e93355155764df62c1bb71f67a0796b33fe7a452Pin-chih Lin status = android::BAD_VALUE; 115e93355155764df62c1bb71f67a0796b33fe7a452Pin-chih Lin } 116e93355155764df62c1bb71f67a0796b33fe7a452Pin-chih Lin (void)tTs; 117e93355155764df62c1bb71f67a0796b33fe7a452Pin-chih Lin }); 118e93355155764df62c1bb71f67a0796b33fe7a452Pin-chih Lin 119e93355155764df62c1bb71f67a0796b33fe7a452Pin-chih Lin // check dequeueBuffer return flag 120e93355155764df62c1bb71f67a0796b33fe7a452Pin-chih Lin if (status != android::NO_ERROR && 121e93355155764df62c1bb71f67a0796b33fe7a452Pin-chih Lin status != IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION) { 122e93355155764df62c1bb71f67a0796b33fe7a452Pin-chih Lin if (status == android::TIMED_OUT) { 123e93355155764df62c1bb71f67a0796b33fe7a452Pin-chih Lin // no buffer is available now, wait for another retry. 124e93355155764df62c1bb71f67a0796b33fe7a452Pin-chih Lin ALOGV("dequeueBuffer timed out, wait for retry..."); 125e93355155764df62c1bb71f67a0796b33fe7a452Pin-chih Lin return C2_TIMED_OUT; 126e93355155764df62c1bb71f67a0796b33fe7a452Pin-chih Lin } 127e93355155764df62c1bb71f67a0796b33fe7a452Pin-chih Lin ALOGE("dequeueBuffer failed: %d", status); 128e93355155764df62c1bb71f67a0796b33fe7a452Pin-chih Lin return asC2Error(status); 129e93355155764df62c1bb71f67a0796b33fe7a452Pin-chih Lin } 130e93355155764df62c1bb71f67a0796b33fe7a452Pin-chih Lin 131e93355155764df62c1bb71f67a0796b33fe7a452Pin-chih Lin // wait for acquire fence if we get one. 132e93355155764df62c1bb71f67a0796b33fe7a452Pin-chih Lin native_handle_t* nh = nullptr; 133e93355155764df62c1bb71f67a0796b33fe7a452Pin-chih Lin hidl_handle fenceHandle; 134e93355155764df62c1bb71f67a0796b33fe7a452Pin-chih Lin if (fence) { 135e93355155764df62c1bb71f67a0796b33fe7a452Pin-chih Lin android::conversion::wrapAs(&fenceHandle, &nh, *fence); 136e93355155764df62c1bb71f67a0796b33fe7a452Pin-chih Lin status_t fenceStatus = fence->wait(kFenceWaitTimeMs); 137e93355155764df62c1bb71f67a0796b33fe7a452Pin-chih Lin if (fenceStatus != android::NO_ERROR) { 138e93355155764df62c1bb71f67a0796b33fe7a452Pin-chih Lin ALOGE("buffer fence wait error: %d", fenceStatus); 139e93355155764df62c1bb71f67a0796b33fe7a452Pin-chih Lin mProducer->cancelBuffer(slot, fenceHandle); 140e93355155764df62c1bb71f67a0796b33fe7a452Pin-chih Lin native_handle_delete(nh); 141e93355155764df62c1bb71f67a0796b33fe7a452Pin-chih Lin return asC2Error(fenceStatus); 142e93355155764df62c1bb71f67a0796b33fe7a452Pin-chih Lin } 143e93355155764df62c1bb71f67a0796b33fe7a452Pin-chih Lin } 144e93355155764df62c1bb71f67a0796b33fe7a452Pin-chih Lin 145e93355155764df62c1bb71f67a0796b33fe7a452Pin-chih Lin auto iter = mSlotAllocations.find(slot); 146e93355155764df62c1bb71f67a0796b33fe7a452Pin-chih Lin if (iter == mSlotAllocations.end()) { 147e93355155764df62c1bb71f67a0796b33fe7a452Pin-chih Lin // it's a new slot index, request for a new buffer. 148e93355155764df62c1bb71f67a0796b33fe7a452Pin-chih Lin if (mSlotAllocations.size() >= mMaxDequeuedBuffers) { 149e93355155764df62c1bb71f67a0796b33fe7a452Pin-chih Lin ALOGE("still get a new slot index but already allocated enough buffers."); 150e93355155764df62c1bb71f67a0796b33fe7a452Pin-chih Lin mProducer->cancelBuffer(slot, fenceHandle); 151e93355155764df62c1bb71f67a0796b33fe7a452Pin-chih Lin native_handle_delete(nh); 152e93355155764df62c1bb71f67a0796b33fe7a452Pin-chih Lin return C2_CORRUPTED; 153e93355155764df62c1bb71f67a0796b33fe7a452Pin-chih Lin } 154e93355155764df62c1bb71f67a0796b33fe7a452Pin-chih Lin if (status != IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION) { 155e93355155764df62c1bb71f67a0796b33fe7a452Pin-chih Lin ALOGE("expect BUFFER_NEEDS_REALLOCATION flag but didn't get one."); 156e93355155764df62c1bb71f67a0796b33fe7a452Pin-chih Lin mProducer->cancelBuffer(slot, fenceHandle); 157e93355155764df62c1bb71f67a0796b33fe7a452Pin-chih Lin native_handle_delete(nh); 158e93355155764df62c1bb71f67a0796b33fe7a452Pin-chih Lin return C2_CORRUPTED; 159e93355155764df62c1bb71f67a0796b33fe7a452Pin-chih Lin } 160e93355155764df62c1bb71f67a0796b33fe7a452Pin-chih Lin sp<GraphicBuffer> slotBuffer = new GraphicBuffer(); 161e93355155764df62c1bb71f67a0796b33fe7a452Pin-chih Lin mProducer->requestBuffer( 162e93355155764df62c1bb71f67a0796b33fe7a452Pin-chih Lin slot, [&status, &slotBuffer](int32_t tStatus, AnwBuffer const& tBuffer) { 163e93355155764df62c1bb71f67a0796b33fe7a452Pin-chih Lin status = tStatus; 164e93355155764df62c1bb71f67a0796b33fe7a452Pin-chih Lin if (!android::conversion::convertTo(slotBuffer.get(), tBuffer) && 165e93355155764df62c1bb71f67a0796b33fe7a452Pin-chih Lin status == android::NO_ERROR) { 166e93355155764df62c1bb71f67a0796b33fe7a452Pin-chih Lin status = android::BAD_VALUE; 167e93355155764df62c1bb71f67a0796b33fe7a452Pin-chih Lin } 168e93355155764df62c1bb71f67a0796b33fe7a452Pin-chih Lin }); 169e93355155764df62c1bb71f67a0796b33fe7a452Pin-chih Lin 170e93355155764df62c1bb71f67a0796b33fe7a452Pin-chih Lin // check requestBuffer return flag 171e93355155764df62c1bb71f67a0796b33fe7a452Pin-chih Lin if (status != android::NO_ERROR) { 172e93355155764df62c1bb71f67a0796b33fe7a452Pin-chih Lin ALOGE("requestBuffer failed: %d", status); 173e93355155764df62c1bb71f67a0796b33fe7a452Pin-chih Lin mProducer->cancelBuffer(slot, fenceHandle); 174e93355155764df62c1bb71f67a0796b33fe7a452Pin-chih Lin native_handle_delete(nh); 175e93355155764df62c1bb71f67a0796b33fe7a452Pin-chih Lin return asC2Error(status); 176e93355155764df62c1bb71f67a0796b33fe7a452Pin-chih Lin } 177e93355155764df62c1bb71f67a0796b33fe7a452Pin-chih Lin native_handle_delete(nh); 178e93355155764df62c1bb71f67a0796b33fe7a452Pin-chih Lin 179e93355155764df62c1bb71f67a0796b33fe7a452Pin-chih Lin // convert GraphicBuffer to C2GraphicAllocation and wrap producer id and slot index 180e93355155764df62c1bb71f67a0796b33fe7a452Pin-chih Lin native_handle_t* grallocHandle = native_handle_clone(slotBuffer->handle); 181e93355155764df62c1bb71f67a0796b33fe7a452Pin-chih Lin ALOGV("buffer wraps { producer id: %" PRIu64 ", slot: %d }", mProducerId, slot); 182e93355155764df62c1bb71f67a0796b33fe7a452Pin-chih Lin C2Handle* c2Handle = android::WrapNativeCodec2GrallocHandle( 183e93355155764df62c1bb71f67a0796b33fe7a452Pin-chih Lin grallocHandle, slotBuffer->width, slotBuffer->height, slotBuffer->format, 184e93355155764df62c1bb71f67a0796b33fe7a452Pin-chih Lin slotBuffer->usage, slotBuffer->stride, mProducerId, slot); 185e93355155764df62c1bb71f67a0796b33fe7a452Pin-chih Lin native_handle_delete(grallocHandle); 186e93355155764df62c1bb71f67a0796b33fe7a452Pin-chih Lin if (!c2Handle) { 187e93355155764df62c1bb71f67a0796b33fe7a452Pin-chih Lin ALOGE("WrapNativeCodec2GrallocHandle failed"); 188e93355155764df62c1bb71f67a0796b33fe7a452Pin-chih Lin return C2_NO_MEMORY; 189e93355155764df62c1bb71f67a0796b33fe7a452Pin-chih Lin } 190e93355155764df62c1bb71f67a0796b33fe7a452Pin-chih Lin 191e93355155764df62c1bb71f67a0796b33fe7a452Pin-chih Lin std::shared_ptr<C2GraphicAllocation> alloc; 192e93355155764df62c1bb71f67a0796b33fe7a452Pin-chih Lin c2_status_t err = mAllocator->priorGraphicAllocation(c2Handle, &alloc); 193e93355155764df62c1bb71f67a0796b33fe7a452Pin-chih Lin if (err != C2_OK) { 194e93355155764df62c1bb71f67a0796b33fe7a452Pin-chih Lin ALOGE("priorGraphicAllocation failed: %d", err); 195e93355155764df62c1bb71f67a0796b33fe7a452Pin-chih Lin return err; 196e93355155764df62c1bb71f67a0796b33fe7a452Pin-chih Lin } 197e93355155764df62c1bb71f67a0796b33fe7a452Pin-chih Lin 198e93355155764df62c1bb71f67a0796b33fe7a452Pin-chih Lin mSlotAllocations[slot] = std::move(alloc); 199e93355155764df62c1bb71f67a0796b33fe7a452Pin-chih Lin if (mSlotAllocations.size() == mMaxDequeuedBuffers) { 200e93355155764df62c1bb71f67a0796b33fe7a452Pin-chih Lin // already allocated enough buffers, set allowAllocation to false to restrict the 201e93355155764df62c1bb71f67a0796b33fe7a452Pin-chih Lin // eligible slots to allocated ones for future dequeue. 202e93355155764df62c1bb71f67a0796b33fe7a452Pin-chih Lin status = mProducer->allowAllocation(false); 203e93355155764df62c1bb71f67a0796b33fe7a452Pin-chih Lin if (status != android::NO_ERROR) { 204e93355155764df62c1bb71f67a0796b33fe7a452Pin-chih Lin ALOGE("allowAllocation(false) failed"); 205e93355155764df62c1bb71f67a0796b33fe7a452Pin-chih Lin return asC2Error(status); 206e93355155764df62c1bb71f67a0796b33fe7a452Pin-chih Lin } 207e93355155764df62c1bb71f67a0796b33fe7a452Pin-chih Lin } 208e93355155764df62c1bb71f67a0796b33fe7a452Pin-chih Lin } else if (mSlotAllocations.size() < mMaxDequeuedBuffers) { 209e93355155764df62c1bb71f67a0796b33fe7a452Pin-chih Lin ALOGE("failed to allocate enough buffers"); 210e93355155764df62c1bb71f67a0796b33fe7a452Pin-chih Lin return C2_BAD_STATE; 211e93355155764df62c1bb71f67a0796b33fe7a452Pin-chih Lin } 212e93355155764df62c1bb71f67a0796b33fe7a452Pin-chih Lin 213e93355155764df62c1bb71f67a0796b33fe7a452Pin-chih Lin *block = _C2BlockFactory::CreateGraphicBlock(mSlotAllocations[slot]); 214e93355155764df62c1bb71f67a0796b33fe7a452Pin-chih Lin return C2_OK; 215e93355155764df62c1bb71f67a0796b33fe7a452Pin-chih Lin} 216e93355155764df62c1bb71f67a0796b33fe7a452Pin-chih Lin 217e93355155764df62c1bb71f67a0796b33fe7a452Pin-chih Linc2_status_t C2VdaBqBlockPool::requestNewBufferSet(int32_t bufferCount) { 218e93355155764df62c1bb71f67a0796b33fe7a452Pin-chih Lin if (bufferCount <= 0) { 219e93355155764df62c1bb71f67a0796b33fe7a452Pin-chih Lin ALOGE("Invalid requested buffer count = %d", bufferCount); 220e93355155764df62c1bb71f67a0796b33fe7a452Pin-chih Lin return C2_BAD_VALUE; 221e93355155764df62c1bb71f67a0796b33fe7a452Pin-chih Lin } 222e93355155764df62c1bb71f67a0796b33fe7a452Pin-chih Lin 223e93355155764df62c1bb71f67a0796b33fe7a452Pin-chih Lin std::lock_guard<std::mutex> lock(mMutex); 224e93355155764df62c1bb71f67a0796b33fe7a452Pin-chih Lin if (!mProducer) { 225e93355155764df62c1bb71f67a0796b33fe7a452Pin-chih Lin ALOGD("No HGraphicBufferProducer is configured..."); 226e93355155764df62c1bb71f67a0796b33fe7a452Pin-chih Lin return C2_NO_INIT; 227e93355155764df62c1bb71f67a0796b33fe7a452Pin-chih Lin } 228e93355155764df62c1bb71f67a0796b33fe7a452Pin-chih Lin 229e93355155764df62c1bb71f67a0796b33fe7a452Pin-chih Lin // For dynamic resolution change, cancel all mapping buffers and discard references. 230e93355155764df62c1bb71f67a0796b33fe7a452Pin-chih Lin // Client needs to make sure all buffers are dequeued and owned by client before calling. 231e93355155764df62c1bb71f67a0796b33fe7a452Pin-chih Lin auto cancelStatus = cancelAllBuffers(); 232e93355155764df62c1bb71f67a0796b33fe7a452Pin-chih Lin if (cancelStatus != C2_OK) { 233e93355155764df62c1bb71f67a0796b33fe7a452Pin-chih Lin ALOGE("cancelBuffer failed while requesting new buffer set..."); 234e93355155764df62c1bb71f67a0796b33fe7a452Pin-chih Lin return C2_CORRUPTED; 235e93355155764df62c1bb71f67a0796b33fe7a452Pin-chih Lin } 236e93355155764df62c1bb71f67a0796b33fe7a452Pin-chih Lin 237e93355155764df62c1bb71f67a0796b33fe7a452Pin-chih Lin // TODO: should we query(NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS) and add it on? 238e93355155764df62c1bb71f67a0796b33fe7a452Pin-chih Lin int32_t status = mProducer->setMaxDequeuedBufferCount(bufferCount); 239e93355155764df62c1bb71f67a0796b33fe7a452Pin-chih Lin if (status != android::NO_ERROR) { 240e93355155764df62c1bb71f67a0796b33fe7a452Pin-chih Lin ALOGE("setMaxDequeuedBufferCount failed"); 241e93355155764df62c1bb71f67a0796b33fe7a452Pin-chih Lin return asC2Error(status); 242e93355155764df62c1bb71f67a0796b33fe7a452Pin-chih Lin } 243e93355155764df62c1bb71f67a0796b33fe7a452Pin-chih Lin mMaxDequeuedBuffers = static_cast<size_t>(bufferCount); 244e93355155764df62c1bb71f67a0796b33fe7a452Pin-chih Lin 245e93355155764df62c1bb71f67a0796b33fe7a452Pin-chih Lin status = mProducer->allowAllocation(true); 246e93355155764df62c1bb71f67a0796b33fe7a452Pin-chih Lin if (status != android::NO_ERROR) { 247e93355155764df62c1bb71f67a0796b33fe7a452Pin-chih Lin ALOGE("allowAllocation(true) failed"); 248e93355155764df62c1bb71f67a0796b33fe7a452Pin-chih Lin return asC2Error(status); 249e93355155764df62c1bb71f67a0796b33fe7a452Pin-chih Lin } 250e93355155764df62c1bb71f67a0796b33fe7a452Pin-chih Lin return C2_OK; 251e93355155764df62c1bb71f67a0796b33fe7a452Pin-chih Lin} 252e93355155764df62c1bb71f67a0796b33fe7a452Pin-chih Lin 253e93355155764df62c1bb71f67a0796b33fe7a452Pin-chih Linvoid C2VdaBqBlockPool::configureProducer(const sp<HGraphicBufferProducer>& producer) { 254e93355155764df62c1bb71f67a0796b33fe7a452Pin-chih Lin ALOGV("configureProducer"); 255e93355155764df62c1bb71f67a0796b33fe7a452Pin-chih Lin std::lock_guard<std::mutex> lock(mMutex); 256e93355155764df62c1bb71f67a0796b33fe7a452Pin-chih Lin // TODO: handle producer change request (client changes surface) while codec is running. 257e93355155764df62c1bb71f67a0796b33fe7a452Pin-chih Lin if (mProducer) { 258e93355155764df62c1bb71f67a0796b33fe7a452Pin-chih Lin ALOGE("Not allowed to reset HGraphicBufferProducer"); 259e93355155764df62c1bb71f67a0796b33fe7a452Pin-chih Lin return; 260e93355155764df62c1bb71f67a0796b33fe7a452Pin-chih Lin } 261e93355155764df62c1bb71f67a0796b33fe7a452Pin-chih Lin 262e93355155764df62c1bb71f67a0796b33fe7a452Pin-chih Lin mProducer = producer; 263e93355155764df62c1bb71f67a0796b33fe7a452Pin-chih Lin if (producer) { 264e93355155764df62c1bb71f67a0796b33fe7a452Pin-chih Lin int32_t status; 265e93355155764df62c1bb71f67a0796b33fe7a452Pin-chih Lin producer->getUniqueId( 266e93355155764df62c1bb71f67a0796b33fe7a452Pin-chih Lin [&status, &producerId = mProducerId](int32_t tStatus, int64_t tProducerId) { 267e93355155764df62c1bb71f67a0796b33fe7a452Pin-chih Lin status = tStatus; 268e93355155764df62c1bb71f67a0796b33fe7a452Pin-chih Lin producerId = tProducerId; 269e93355155764df62c1bb71f67a0796b33fe7a452Pin-chih Lin }); 270e93355155764df62c1bb71f67a0796b33fe7a452Pin-chih Lin if (status != android::NO_ERROR) { 271e93355155764df62c1bb71f67a0796b33fe7a452Pin-chih Lin ALOGE("getUniqueId failed"); 272e93355155764df62c1bb71f67a0796b33fe7a452Pin-chih Lin mProducer = nullptr; 273e93355155764df62c1bb71f67a0796b33fe7a452Pin-chih Lin mProducerId = 0; 274e93355155764df62c1bb71f67a0796b33fe7a452Pin-chih Lin return; 275e93355155764df62c1bb71f67a0796b33fe7a452Pin-chih Lin } 276e93355155764df62c1bb71f67a0796b33fe7a452Pin-chih Lin status = producer->setDequeueTimeout(kDequeueTimeoutNs); 277e93355155764df62c1bb71f67a0796b33fe7a452Pin-chih Lin if (status != android::NO_ERROR) { 278e93355155764df62c1bb71f67a0796b33fe7a452Pin-chih Lin ALOGE("setDequeueTimeout failed"); 279e93355155764df62c1bb71f67a0796b33fe7a452Pin-chih Lin mProducer = nullptr; 280e93355155764df62c1bb71f67a0796b33fe7a452Pin-chih Lin mProducerId = 0; 281e93355155764df62c1bb71f67a0796b33fe7a452Pin-chih Lin return; 282e93355155764df62c1bb71f67a0796b33fe7a452Pin-chih Lin } 283e93355155764df62c1bb71f67a0796b33fe7a452Pin-chih Lin } else { 284e93355155764df62c1bb71f67a0796b33fe7a452Pin-chih Lin mProducerId = 0; 285e93355155764df62c1bb71f67a0796b33fe7a452Pin-chih Lin } 286e93355155764df62c1bb71f67a0796b33fe7a452Pin-chih Lin mSlotAllocations.clear(); 287e93355155764df62c1bb71f67a0796b33fe7a452Pin-chih Lin} 288e93355155764df62c1bb71f67a0796b33fe7a452Pin-chih Lin 289e93355155764df62c1bb71f67a0796b33fe7a452Pin-chih Linc2_status_t C2VdaBqBlockPool::cancelAllBuffers() { 290e93355155764df62c1bb71f67a0796b33fe7a452Pin-chih Lin int32_t lastError = android::NO_ERROR; 291e93355155764df62c1bb71f67a0796b33fe7a452Pin-chih Lin for (const auto& elem : mSlotAllocations) { 292e93355155764df62c1bb71f67a0796b33fe7a452Pin-chih Lin int32_t slot = elem.first; 293e93355155764df62c1bb71f67a0796b33fe7a452Pin-chih Lin sp<Fence> fence(Fence::NO_FENCE); 294e93355155764df62c1bb71f67a0796b33fe7a452Pin-chih Lin native_handle_t* nh = nullptr; 295e93355155764df62c1bb71f67a0796b33fe7a452Pin-chih Lin hidl_handle fenceHandle; 296e93355155764df62c1bb71f67a0796b33fe7a452Pin-chih Lin android::conversion::wrapAs(&fenceHandle, &nh, *fence); 297e93355155764df62c1bb71f67a0796b33fe7a452Pin-chih Lin int32_t status = mProducer->cancelBuffer(slot, fenceHandle); 298e93355155764df62c1bb71f67a0796b33fe7a452Pin-chih Lin native_handle_delete(nh); 299e93355155764df62c1bb71f67a0796b33fe7a452Pin-chih Lin if (status == android::NO_INIT) { 300e93355155764df62c1bb71f67a0796b33fe7a452Pin-chih Lin // Producer may be disconnected during the loop of cancelBuffer (especially in the 301e93355155764df62c1bb71f67a0796b33fe7a452Pin-chih Lin // destruction state). Break the loop and return immediately. 302e93355155764df62c1bb71f67a0796b33fe7a452Pin-chih Lin mSlotAllocations.clear(); 303e93355155764df62c1bb71f67a0796b33fe7a452Pin-chih Lin return C2_NO_INIT; 304e93355155764df62c1bb71f67a0796b33fe7a452Pin-chih Lin } 305e93355155764df62c1bb71f67a0796b33fe7a452Pin-chih Lin if (status != android::NO_ERROR) { 306e93355155764df62c1bb71f67a0796b33fe7a452Pin-chih Lin ALOGE("cancelBuffer failed at slot = %d, err: %d", slot, status); 307e93355155764df62c1bb71f67a0796b33fe7a452Pin-chih Lin lastError = status; 308e93355155764df62c1bb71f67a0796b33fe7a452Pin-chih Lin } 309e93355155764df62c1bb71f67a0796b33fe7a452Pin-chih Lin } 310e93355155764df62c1bb71f67a0796b33fe7a452Pin-chih Lin mSlotAllocations.clear(); 311e93355155764df62c1bb71f67a0796b33fe7a452Pin-chih Lin return asC2Error(lastError); 312e93355155764df62c1bb71f67a0796b33fe7a452Pin-chih Lin} 313