Pawin Vongmasa | 586b198 | 2019-10-23 19:21:04 -0700 | [diff] [blame] | 1 | /* |
| 2 | * Copyright 2018 The Android Open Source Project |
| 3 | * |
| 4 | * Licensed under the Apache License, Version 2.0 (the "License"); |
| 5 | * you may not use this file except in compliance with the License. |
| 6 | * You may obtain a copy of the License at |
| 7 | * |
| 8 | * http://www.apache.org/licenses/LICENSE-2.0 |
| 9 | * |
| 10 | * Unless required by applicable law or agreed to in writing, software |
| 11 | * distributed under the License is distributed on an "AS IS" BASIS, |
| 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| 13 | * See the License for the specific language governing permissions and |
| 14 | * limitations under the License. |
| 15 | */ |
| 16 | |
| 17 | //#define LOG_NDEBUG 0 |
| 18 | #define LOG_TAG "Codec2-OutputBufferQueue" |
| 19 | #include <android-base/logging.h> |
| 20 | |
| 21 | #include <android/hardware/graphics/bufferqueue/2.0/IGraphicBufferProducer.h> |
Sungtak Lee | a714f11 | 2021-03-16 05:40:03 -0700 | [diff] [blame^] | 22 | #include <codec2/hidl/output.h> |
| 23 | #include <cutils/ashmem.h> |
Pawin Vongmasa | 586b198 | 2019-10-23 19:21:04 -0700 | [diff] [blame] | 24 | #include <gui/bufferqueue/2.0/B2HGraphicBufferProducer.h> |
Sungtak Lee | a714f11 | 2021-03-16 05:40:03 -0700 | [diff] [blame^] | 25 | #include <sys/mman.h> |
Pawin Vongmasa | 586b198 | 2019-10-23 19:21:04 -0700 | [diff] [blame] | 26 | |
| 27 | #include <C2AllocatorGralloc.h> |
| 28 | #include <C2BlockInternal.h> |
| 29 | #include <C2Buffer.h> |
| 30 | #include <C2PlatformSupport.h> |
Sungtak Lee | a714f11 | 2021-03-16 05:40:03 -0700 | [diff] [blame^] | 31 | #include <C2SurfaceSyncObj.h> |
Pawin Vongmasa | 586b198 | 2019-10-23 19:21:04 -0700 | [diff] [blame] | 32 | |
| 33 | #include <iomanip> |
| 34 | |
| 35 | namespace android { |
| 36 | namespace hardware { |
| 37 | namespace media { |
| 38 | namespace c2 { |
Pawin Vongmasa | 586b198 | 2019-10-23 19:21:04 -0700 | [diff] [blame] | 39 | |
| 40 | using HGraphicBufferProducer = ::android::hardware::graphics::bufferqueue:: |
| 41 | V2_0::IGraphicBufferProducer; |
| 42 | using B2HGraphicBufferProducer = ::android::hardware::graphics::bufferqueue:: |
| 43 | V2_0::utils::B2HGraphicBufferProducer; |
| 44 | |
| 45 | namespace /* unnamed */ { |
| 46 | |
| 47 | // Create a GraphicBuffer object from a graphic block. |
| 48 | sp<GraphicBuffer> createGraphicBuffer(const C2ConstGraphicBlock& block) { |
| 49 | uint32_t width; |
| 50 | uint32_t height; |
| 51 | uint32_t format; |
| 52 | uint64_t usage; |
| 53 | uint32_t stride; |
| 54 | uint32_t generation; |
| 55 | uint64_t bqId; |
| 56 | int32_t bqSlot; |
| 57 | _UnwrapNativeCodec2GrallocMetadata( |
| 58 | block.handle(), &width, &height, &format, &usage, |
| 59 | &stride, &generation, &bqId, reinterpret_cast<uint32_t*>(&bqSlot)); |
| 60 | native_handle_t *grallocHandle = |
| 61 | UnwrapNativeCodec2GrallocHandle(block.handle()); |
| 62 | sp<GraphicBuffer> graphicBuffer = |
| 63 | new GraphicBuffer(grallocHandle, |
| 64 | GraphicBuffer::CLONE_HANDLE, |
| 65 | width, height, format, |
| 66 | 1, usage, stride); |
| 67 | native_handle_delete(grallocHandle); |
| 68 | return graphicBuffer; |
| 69 | } |
| 70 | |
| 71 | template <typename BlockProcessor> |
| 72 | void forEachBlock(C2FrameData& frameData, |
| 73 | BlockProcessor process) { |
| 74 | for (const std::shared_ptr<C2Buffer>& buffer : frameData.buffers) { |
| 75 | if (buffer) { |
| 76 | for (const C2ConstGraphicBlock& block : |
| 77 | buffer->data().graphicBlocks()) { |
| 78 | process(block); |
| 79 | } |
| 80 | } |
| 81 | } |
| 82 | } |
| 83 | |
| 84 | template <typename BlockProcessor> |
| 85 | void forEachBlock(const std::list<std::unique_ptr<C2Work>>& workList, |
| 86 | BlockProcessor process) { |
| 87 | for (const std::unique_ptr<C2Work>& work : workList) { |
| 88 | if (!work) { |
| 89 | continue; |
| 90 | } |
| 91 | for (const std::unique_ptr<C2Worklet>& worklet : work->worklets) { |
| 92 | if (worklet) { |
| 93 | forEachBlock(worklet->output, process); |
| 94 | } |
| 95 | } |
| 96 | } |
| 97 | } |
| 98 | |
| 99 | sp<HGraphicBufferProducer> getHgbp(const sp<IGraphicBufferProducer>& igbp) { |
| 100 | sp<HGraphicBufferProducer> hgbp = |
| 101 | igbp->getHalInterface<HGraphicBufferProducer>(); |
| 102 | return hgbp ? hgbp : |
| 103 | new B2HGraphicBufferProducer(igbp); |
| 104 | } |
| 105 | |
| 106 | status_t attachToBufferQueue(const C2ConstGraphicBlock& block, |
| 107 | const sp<IGraphicBufferProducer>& igbp, |
| 108 | uint32_t generation, |
Sungtak Lee | a714f11 | 2021-03-16 05:40:03 -0700 | [diff] [blame^] | 109 | int32_t* bqSlot, |
| 110 | std::shared_ptr<C2SurfaceSyncMemory> syncMem) { |
Pawin Vongmasa | 586b198 | 2019-10-23 19:21:04 -0700 | [diff] [blame] | 111 | if (!igbp) { |
| 112 | LOG(WARNING) << "attachToBufferQueue -- null producer."; |
| 113 | return NO_INIT; |
| 114 | } |
| 115 | |
| 116 | sp<GraphicBuffer> graphicBuffer = createGraphicBuffer(block); |
| 117 | graphicBuffer->setGenerationNumber(generation); |
| 118 | |
| 119 | LOG(VERBOSE) << "attachToBufferQueue -- attaching buffer:" |
| 120 | << " block dimension " << block.width() << "x" |
| 121 | << block.height() |
| 122 | << ", graphicBuffer dimension " << graphicBuffer->getWidth() << "x" |
| 123 | << graphicBuffer->getHeight() |
| 124 | << std::hex << std::setfill('0') |
| 125 | << ", format 0x" << std::setw(8) << graphicBuffer->getPixelFormat() |
| 126 | << ", usage 0x" << std::setw(16) << graphicBuffer->getUsage() |
| 127 | << std::dec << std::setfill(' ') |
| 128 | << ", stride " << graphicBuffer->getStride() |
| 129 | << ", generation " << graphicBuffer->getGenerationNumber(); |
| 130 | |
Sungtak Lee | a714f11 | 2021-03-16 05:40:03 -0700 | [diff] [blame^] | 131 | C2SyncVariables *syncVar = syncMem ? syncMem->mem() : nullptr; |
| 132 | status_t result = OK; |
| 133 | if (syncVar) { |
| 134 | syncVar->lock(); |
| 135 | if (!syncVar->isDequeueableLocked() || |
| 136 | syncVar->getSyncStatusLocked() == C2SyncVariables::STATUS_SWITCHING) { |
| 137 | syncVar->unlock(); |
| 138 | LOG(WARNING) << "attachToBufferQueue -- attachBuffer failed: " |
| 139 | "status = " << INVALID_OPERATION << "."; |
| 140 | return INVALID_OPERATION; |
| 141 | } |
| 142 | result = igbp->attachBuffer(bqSlot, graphicBuffer); |
| 143 | if (result == OK) { |
| 144 | syncVar->notifyDequeuedLocked(); |
| 145 | } |
| 146 | syncVar->unlock(); |
| 147 | } else { |
| 148 | result = igbp->attachBuffer(bqSlot, graphicBuffer); |
| 149 | } |
Pawin Vongmasa | 586b198 | 2019-10-23 19:21:04 -0700 | [diff] [blame] | 150 | if (result != OK) { |
| 151 | LOG(WARNING) << "attachToBufferQueue -- attachBuffer failed: " |
| 152 | "status = " << result << "."; |
| 153 | return result; |
| 154 | } |
| 155 | LOG(VERBOSE) << "attachToBufferQueue -- attachBuffer returned slot #" |
| 156 | << *bqSlot << "."; |
| 157 | return OK; |
| 158 | } |
| 159 | |
| 160 | bool getBufferQueueAssignment(const C2ConstGraphicBlock& block, |
| 161 | uint32_t* generation, |
| 162 | uint64_t* bqId, |
| 163 | int32_t* bqSlot) { |
| 164 | return _C2BlockFactory::GetBufferQueueData( |
| 165 | _C2BlockFactory::GetGraphicBlockPoolData(block), |
| 166 | generation, bqId, bqSlot); |
| 167 | } |
| 168 | |
| 169 | } // unnamed namespace |
| 170 | |
| 171 | OutputBufferQueue::OutputBufferQueue() |
| 172 | : mGeneration{0}, mBqId{0} { |
| 173 | } |
| 174 | |
| 175 | OutputBufferQueue::~OutputBufferQueue() { |
| 176 | } |
| 177 | |
| 178 | bool OutputBufferQueue::configure(const sp<IGraphicBufferProducer>& igbp, |
| 179 | uint32_t generation, |
Sungtak Lee | a714f11 | 2021-03-16 05:40:03 -0700 | [diff] [blame^] | 180 | uint64_t bqId, |
| 181 | std::shared_ptr<V1_2::SurfaceSyncObj> *syncObj) { |
Chih-Yu Huang | b5ec89e | 2021-02-09 17:37:32 +0900 | [diff] [blame] | 182 | uint64_t consumerUsage = 0; |
| 183 | if (igbp->getConsumerUsage(&consumerUsage) != OK) { |
| 184 | ALOGW("failed to get consumer usage"); |
| 185 | } |
| 186 | |
Sungtak Lee | a714f11 | 2021-03-16 05:40:03 -0700 | [diff] [blame^] | 187 | // TODO : Abstract creation process into C2SurfaceSyncMemory class. |
| 188 | // use C2LinearBlock instead ashmem. |
| 189 | std::shared_ptr<C2SurfaceSyncMemory> syncMem; |
| 190 | if (syncObj && igbp) { |
| 191 | bool mapped = false; |
| 192 | int memFd = ashmem_create_region("C2SurfaceMem", sizeof(C2SyncVariables)); |
| 193 | size_t memSize = memFd < 0 ? 0 : ashmem_get_size_region(memFd); |
| 194 | if (memSize > 0) { |
| 195 | syncMem = C2SurfaceSyncMemory::Create(memFd, memSize); |
| 196 | if (syncMem) { |
| 197 | mapped = true; |
| 198 | *syncObj = std::make_shared<V1_2::SurfaceSyncObj>(); |
| 199 | (*syncObj)->syncMemory = syncMem->handle(); |
| 200 | (*syncObj)->bqId = bqId; |
| 201 | (*syncObj)->generationId = generation; |
| 202 | (*syncObj)->consumerUsage = consumerUsage; |
| 203 | ALOGD("C2SurfaceSyncMemory created %zu(%zu)", sizeof(C2SyncVariables), memSize); |
| 204 | } |
| 205 | } |
| 206 | if (!mapped) { |
| 207 | if (memFd >= 0) { |
| 208 | ::close(memFd); |
| 209 | } |
| 210 | ALOGW("SurfaceSyncObj creation failure"); |
| 211 | } |
| 212 | } |
| 213 | |
Pawin Vongmasa | 586b198 | 2019-10-23 19:21:04 -0700 | [diff] [blame] | 214 | size_t tryNum = 0; |
| 215 | size_t success = 0; |
| 216 | sp<GraphicBuffer> buffers[BufferQueueDefs::NUM_BUFFER_SLOTS]; |
| 217 | std::weak_ptr<_C2BlockPoolData> |
| 218 | poolDatas[BufferQueueDefs::NUM_BUFFER_SLOTS]; |
| 219 | { |
| 220 | std::scoped_lock<std::mutex> l(mMutex); |
| 221 | if (generation == mGeneration) { |
| 222 | return false; |
| 223 | } |
Sungtak Lee | a714f11 | 2021-03-16 05:40:03 -0700 | [diff] [blame^] | 224 | std::shared_ptr<C2SurfaceSyncMemory> oldMem = mSyncMem; |
| 225 | C2SyncVariables *oldSync = mSyncMem ? mSyncMem->mem() : nullptr; |
| 226 | if (oldSync) { |
| 227 | oldSync->lock(); |
| 228 | oldSync->setSyncStatusLocked(C2SyncVariables::STATUS_SWITCHING); |
| 229 | oldSync->unlock(); |
| 230 | } |
| 231 | mSyncMem.reset(); |
| 232 | if (syncMem) { |
| 233 | mSyncMem = syncMem; |
| 234 | } |
| 235 | C2SyncVariables *newSync = mSyncMem ? mSyncMem->mem() : nullptr; |
| 236 | |
Pawin Vongmasa | 586b198 | 2019-10-23 19:21:04 -0700 | [diff] [blame] | 237 | mIgbp = igbp; |
| 238 | mGeneration = generation; |
| 239 | mBqId = bqId; |
| 240 | mOwner = std::make_shared<int>(0); |
| 241 | for (int i = 0; i < BufferQueueDefs::NUM_BUFFER_SLOTS; ++i) { |
| 242 | if (mBqId == 0 || !mBuffers[i]) { |
| 243 | continue; |
| 244 | } |
| 245 | std::shared_ptr<_C2BlockPoolData> data = mPoolDatas[i].lock(); |
| 246 | if (!data || |
| 247 | !_C2BlockFactory::BeginAttachBlockToBufferQueue(data)) { |
| 248 | continue; |
| 249 | } |
| 250 | ++tryNum; |
| 251 | int bqSlot; |
Chih-Yu Huang | b5ec89e | 2021-02-09 17:37:32 +0900 | [diff] [blame] | 252 | |
| 253 | // Update buffer's generation and usage. |
| 254 | if ((mBuffers[i]->getUsage() & consumerUsage) != consumerUsage) { |
| 255 | mBuffers[i] = new GraphicBuffer( |
| 256 | mBuffers[i]->handle, GraphicBuffer::CLONE_HANDLE, |
| 257 | mBuffers[i]->width, mBuffers[i]->height, |
| 258 | mBuffers[i]->format, mBuffers[i]->layerCount, |
| 259 | mBuffers[i]->getUsage() | consumerUsage, |
| 260 | mBuffers[i]->stride); |
| 261 | if (mBuffers[i]->initCheck() != OK) { |
| 262 | ALOGW("%s() failed to update usage, original usage=%" PRIx64 |
| 263 | ", consumer usage=%" PRIx64, |
| 264 | __func__, mBuffers[i]->getUsage(), consumerUsage); |
| 265 | continue; |
| 266 | } |
| 267 | } |
Pawin Vongmasa | 586b198 | 2019-10-23 19:21:04 -0700 | [diff] [blame] | 268 | mBuffers[i]->setGenerationNumber(generation); |
Chih-Yu Huang | b5ec89e | 2021-02-09 17:37:32 +0900 | [diff] [blame] | 269 | |
Pawin Vongmasa | 586b198 | 2019-10-23 19:21:04 -0700 | [diff] [blame] | 270 | status_t result = igbp->attachBuffer(&bqSlot, mBuffers[i]); |
| 271 | if (result != OK) { |
| 272 | continue; |
| 273 | } |
| 274 | bool attach = |
| 275 | _C2BlockFactory::EndAttachBlockToBufferQueue( |
Sungtak Lee | a714f11 | 2021-03-16 05:40:03 -0700 | [diff] [blame^] | 276 | data, mOwner, getHgbp(mIgbp), mSyncMem, |
Pawin Vongmasa | 586b198 | 2019-10-23 19:21:04 -0700 | [diff] [blame] | 277 | generation, bqId, bqSlot); |
| 278 | if (!attach) { |
| 279 | igbp->cancelBuffer(bqSlot, Fence::NO_FENCE); |
| 280 | continue; |
| 281 | } |
| 282 | buffers[bqSlot] = mBuffers[i]; |
| 283 | poolDatas[bqSlot] = data; |
| 284 | ++success; |
| 285 | } |
| 286 | for (int i = 0; i < BufferQueueDefs::NUM_BUFFER_SLOTS; ++i) { |
| 287 | mBuffers[i] = buffers[i]; |
| 288 | mPoolDatas[i] = poolDatas[i]; |
| 289 | } |
Sungtak Lee | a714f11 | 2021-03-16 05:40:03 -0700 | [diff] [blame^] | 290 | if (newSync) { |
| 291 | newSync->setInitialDequeueCount(mMaxDequeueBufferCount, success); |
| 292 | } |
Pawin Vongmasa | 586b198 | 2019-10-23 19:21:04 -0700 | [diff] [blame] | 293 | } |
Sungtak Lee | a714f11 | 2021-03-16 05:40:03 -0700 | [diff] [blame^] | 294 | ALOGD("remote graphic buffer migration %zu/%zu", |
| 295 | success, tryNum); |
Pawin Vongmasa | 586b198 | 2019-10-23 19:21:04 -0700 | [diff] [blame] | 296 | return true; |
| 297 | } |
| 298 | |
| 299 | bool OutputBufferQueue::registerBuffer(const C2ConstGraphicBlock& block) { |
| 300 | std::shared_ptr<_C2BlockPoolData> data = |
| 301 | _C2BlockFactory::GetGraphicBlockPoolData(block); |
| 302 | if (!data) { |
| 303 | return false; |
| 304 | } |
| 305 | std::scoped_lock<std::mutex> l(mMutex); |
| 306 | |
| 307 | if (!mIgbp) { |
| 308 | return false; |
| 309 | } |
| 310 | |
| 311 | uint32_t oldGeneration; |
| 312 | uint64_t oldId; |
| 313 | int32_t oldSlot; |
| 314 | // If the block is not bufferqueue-based, do nothing. |
| 315 | if (!_C2BlockFactory::GetBufferQueueData( |
| 316 | data, &oldGeneration, &oldId, &oldSlot) || (oldId == 0)) { |
| 317 | return false; |
| 318 | } |
| 319 | // If the block's bqId is the same as the desired bqId, just hold. |
| 320 | if ((oldId == mBqId) && (oldGeneration == mGeneration)) { |
| 321 | LOG(VERBOSE) << "holdBufferQueueBlock -- import without attaching:" |
| 322 | << " bqId " << oldId |
| 323 | << ", bqSlot " << oldSlot |
| 324 | << ", generation " << mGeneration |
| 325 | << "."; |
Sungtak Lee | a714f11 | 2021-03-16 05:40:03 -0700 | [diff] [blame^] | 326 | _C2BlockFactory::HoldBlockFromBufferQueue(data, mOwner, getHgbp(mIgbp), mSyncMem); |
Pawin Vongmasa | 586b198 | 2019-10-23 19:21:04 -0700 | [diff] [blame] | 327 | mPoolDatas[oldSlot] = data; |
| 328 | mBuffers[oldSlot] = createGraphicBuffer(block); |
| 329 | mBuffers[oldSlot]->setGenerationNumber(mGeneration); |
| 330 | return true; |
| 331 | } |
| 332 | int32_t d = (int32_t) mGeneration - (int32_t) oldGeneration; |
| 333 | LOG(WARNING) << "receiving stale buffer: generation " |
| 334 | << mGeneration << " , diff " << d << " : slot " |
| 335 | << oldSlot; |
| 336 | return false; |
| 337 | } |
| 338 | |
| 339 | status_t OutputBufferQueue::outputBuffer( |
| 340 | const C2ConstGraphicBlock& block, |
| 341 | const BnGraphicBufferProducer::QueueBufferInput& input, |
| 342 | BnGraphicBufferProducer::QueueBufferOutput* output) { |
| 343 | uint32_t generation; |
| 344 | uint64_t bqId; |
| 345 | int32_t bqSlot; |
Sungtak Lee | a714f11 | 2021-03-16 05:40:03 -0700 | [diff] [blame^] | 346 | bool display = V1_0::utils::displayBufferQueueBlock(block); |
Pawin Vongmasa | 586b198 | 2019-10-23 19:21:04 -0700 | [diff] [blame] | 347 | if (!getBufferQueueAssignment(block, &generation, &bqId, &bqSlot) || |
| 348 | bqId == 0) { |
| 349 | // Block not from bufferqueue -- it must be attached before queuing. |
| 350 | |
Sungtak Lee | a714f11 | 2021-03-16 05:40:03 -0700 | [diff] [blame^] | 351 | std::shared_ptr<C2SurfaceSyncMemory> syncMem; |
Pawin Vongmasa | 586b198 | 2019-10-23 19:21:04 -0700 | [diff] [blame] | 352 | mMutex.lock(); |
| 353 | sp<IGraphicBufferProducer> outputIgbp = mIgbp; |
| 354 | uint32_t outputGeneration = mGeneration; |
Sungtak Lee | a714f11 | 2021-03-16 05:40:03 -0700 | [diff] [blame^] | 355 | syncMem = mSyncMem; |
Pawin Vongmasa | 586b198 | 2019-10-23 19:21:04 -0700 | [diff] [blame] | 356 | mMutex.unlock(); |
| 357 | |
| 358 | status_t status = attachToBufferQueue( |
Sungtak Lee | a714f11 | 2021-03-16 05:40:03 -0700 | [diff] [blame^] | 359 | block, outputIgbp, outputGeneration, &bqSlot, syncMem); |
| 360 | |
Pawin Vongmasa | 586b198 | 2019-10-23 19:21:04 -0700 | [diff] [blame] | 361 | if (status != OK) { |
| 362 | LOG(WARNING) << "outputBuffer -- attaching failed."; |
| 363 | return INVALID_OPERATION; |
| 364 | } |
| 365 | |
Sungtak Lee | a714f11 | 2021-03-16 05:40:03 -0700 | [diff] [blame^] | 366 | auto syncVar = syncMem ? syncMem->mem() : nullptr; |
| 367 | if(syncVar) { |
| 368 | syncVar->lock(); |
| 369 | status = outputIgbp->queueBuffer(static_cast<int>(bqSlot), |
| 370 | input, output); |
| 371 | if (status == OK) { |
| 372 | syncVar->notifyQueuedLocked(); |
| 373 | } |
| 374 | syncVar->unlock(); |
| 375 | } else { |
| 376 | status = outputIgbp->queueBuffer(static_cast<int>(bqSlot), |
| 377 | input, output); |
| 378 | } |
Pawin Vongmasa | 586b198 | 2019-10-23 19:21:04 -0700 | [diff] [blame] | 379 | if (status != OK) { |
| 380 | LOG(ERROR) << "outputBuffer -- queueBuffer() failed " |
| 381 | "on non-bufferqueue-based block. " |
| 382 | "Error = " << status << "."; |
| 383 | return status; |
| 384 | } |
| 385 | return OK; |
| 386 | } |
| 387 | |
Sungtak Lee | a714f11 | 2021-03-16 05:40:03 -0700 | [diff] [blame^] | 388 | std::shared_ptr<C2SurfaceSyncMemory> syncMem; |
Pawin Vongmasa | 586b198 | 2019-10-23 19:21:04 -0700 | [diff] [blame] | 389 | mMutex.lock(); |
| 390 | sp<IGraphicBufferProducer> outputIgbp = mIgbp; |
| 391 | uint32_t outputGeneration = mGeneration; |
| 392 | uint64_t outputBqId = mBqId; |
Sungtak Lee | a714f11 | 2021-03-16 05:40:03 -0700 | [diff] [blame^] | 393 | syncMem = mSyncMem; |
Pawin Vongmasa | 586b198 | 2019-10-23 19:21:04 -0700 | [diff] [blame] | 394 | mMutex.unlock(); |
| 395 | |
| 396 | if (!outputIgbp) { |
| 397 | LOG(VERBOSE) << "outputBuffer -- output surface is null."; |
| 398 | return NO_INIT; |
| 399 | } |
| 400 | |
| 401 | if (!display) { |
| 402 | LOG(WARNING) << "outputBuffer -- cannot display " |
| 403 | "bufferqueue-based block to the bufferqueue."; |
| 404 | return UNKNOWN_ERROR; |
| 405 | } |
| 406 | if (bqId != outputBqId || generation != outputGeneration) { |
| 407 | int32_t diff = (int32_t) outputGeneration - (int32_t) generation; |
| 408 | LOG(WARNING) << "outputBuffer -- buffers from old generation to " |
| 409 | << outputGeneration << " , diff: " << diff |
| 410 | << " , slot: " << bqSlot; |
| 411 | return DEAD_OBJECT; |
| 412 | } |
| 413 | |
Sungtak Lee | a714f11 | 2021-03-16 05:40:03 -0700 | [diff] [blame^] | 414 | auto syncVar = syncMem ? syncMem->mem() : nullptr; |
| 415 | status_t status = OK; |
| 416 | if (syncVar) { |
| 417 | syncVar->lock(); |
| 418 | status = outputIgbp->queueBuffer(static_cast<int>(bqSlot), |
| 419 | input, output); |
| 420 | if (status == OK) { |
| 421 | syncVar->notifyQueuedLocked(); |
| 422 | } |
| 423 | syncVar->unlock(); |
| 424 | } else { |
| 425 | status = outputIgbp->queueBuffer(static_cast<int>(bqSlot), |
| 426 | input, output); |
| 427 | } |
| 428 | |
Pawin Vongmasa | 586b198 | 2019-10-23 19:21:04 -0700 | [diff] [blame] | 429 | if (status != OK) { |
| 430 | LOG(ERROR) << "outputBuffer -- queueBuffer() failed " |
| 431 | "on bufferqueue-based block. " |
| 432 | "Error = " << status << "."; |
| 433 | return status; |
| 434 | } |
| 435 | return OK; |
| 436 | } |
| 437 | |
| 438 | void OutputBufferQueue::holdBufferQueueBlocks( |
| 439 | const std::list<std::unique_ptr<C2Work>>& workList) { |
| 440 | forEachBlock(workList, |
| 441 | std::bind(&OutputBufferQueue::registerBuffer, |
| 442 | this, std::placeholders::_1)); |
| 443 | } |
| 444 | |
Sungtak Lee | a714f11 | 2021-03-16 05:40:03 -0700 | [diff] [blame^] | 445 | void OutputBufferQueue::updateMaxDequeueBufferCount(int maxDequeueBufferCount) { |
| 446 | mMutex.lock(); |
| 447 | mMaxDequeueBufferCount = maxDequeueBufferCount; |
| 448 | auto syncVar = mSyncMem ? mSyncMem->mem() : nullptr; |
| 449 | if (syncVar) { |
| 450 | syncVar->lock(); |
| 451 | syncVar->updateMaxDequeueCountLocked(maxDequeueBufferCount); |
| 452 | syncVar->unlock(); |
| 453 | } |
| 454 | mMutex.unlock(); |
| 455 | } |
| 456 | |
Pawin Vongmasa | 586b198 | 2019-10-23 19:21:04 -0700 | [diff] [blame] | 457 | } // namespace c2 |
| 458 | } // namespace media |
| 459 | } // namespace hardware |
| 460 | } // namespace android |
| 461 | |