BufferQueueProducer.cpp revision 50101d02a8eae555887282a5f761fdec57bdaf30
1/* 2 * Copyright 2014 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#include <inttypes.h> 18 19#define LOG_TAG "BufferQueueProducer" 20#define ATRACE_TAG ATRACE_TAG_GRAPHICS 21//#define LOG_NDEBUG 0 22 23#if DEBUG_ONLY_CODE 24#define VALIDATE_CONSISTENCY() do { mCore->validateConsistencyLocked(); } while (0) 25#else 26#define VALIDATE_CONSISTENCY() 27#endif 28 29#define EGL_EGLEXT_PROTOTYPES 30 31#include <gui/BufferItem.h> 32#include <gui/BufferQueueCore.h> 33#include <gui/BufferQueueProducer.h> 34#include <gui/IConsumerListener.h> 35#include <gui/IGraphicBufferAlloc.h> 36#include <gui/IProducerListener.h> 37 38#include <utils/Log.h> 39#include <utils/Trace.h> 40 41namespace android { 42 43BufferQueueProducer::BufferQueueProducer(const sp<BufferQueueCore>& core) : 44 mCore(core), 45 mSlots(core->mSlots), 46 mConsumerName(), 47 mStickyTransform(0), 48 mLastQueueBufferFence(Fence::NO_FENCE), 49 mCallbackMutex(), 50 mNextCallbackTicket(0), 51 mCurrentCallbackTicket(0), 52 mCallbackCondition(), 53 mDequeueTimeout(-1) {} 54 55BufferQueueProducer::~BufferQueueProducer() {} 56 57status_t BufferQueueProducer::requestBuffer(int slot, sp<GraphicBuffer>* buf) { 58 ATRACE_CALL(); 59 BQ_LOGV("requestBuffer: slot %d", slot); 60 Mutex::Autolock lock(mCore->mMutex); 61 62 if (mCore->mIsAbandoned) { 63 BQ_LOGE("requestBuffer: BufferQueue has been abandoned"); 64 return NO_INIT; 65 } 66 67 if (mCore->mConnectedApi == BufferQueueCore::NO_CONNECTED_API) { 68 BQ_LOGE("requestBuffer: BufferQueue has no connected producer"); 69 return NO_INIT; 70 } 71 72 if (slot < 0 || slot >= BufferQueueDefs::NUM_BUFFER_SLOTS) { 73 BQ_LOGE("requestBuffer: slot index %d out of range [0, %d)", 74 slot, BufferQueueDefs::NUM_BUFFER_SLOTS); 75 return BAD_VALUE; 76 } else if (!mSlots[slot].mBufferState.isDequeued()) { 77 BQ_LOGE("requestBuffer: slot %d is not owned by the producer " 78 "(state = %s)", slot, mSlots[slot].mBufferState.string()); 79 return BAD_VALUE; 80 } 81 82 mSlots[slot].mRequestBufferCalled = true; 83 *buf = mSlots[slot].mGraphicBuffer; 84 return NO_ERROR; 85} 86 87status_t BufferQueueProducer::setMaxDequeuedBufferCount( 88 int maxDequeuedBuffers) { 89 ATRACE_CALL(); 90 BQ_LOGV("setMaxDequeuedBufferCount: maxDequeuedBuffers = %d", 91 maxDequeuedBuffers); 92 93 sp<IConsumerListener> listener; 94 { // Autolock scope 95 Mutex::Autolock lock(mCore->mMutex); 96 mCore->waitWhileAllocatingLocked(); 97 98 if (mCore->mIsAbandoned) { 99 BQ_LOGE("setMaxDequeuedBufferCount: BufferQueue has been " 100 "abandoned"); 101 return NO_INIT; 102 } 103 104 // The new maxDequeuedBuffer count should not be violated by the number 105 // of currently dequeued buffers 106 int dequeuedCount = 0; 107 for (int s : mCore->mActiveBuffers) { 108 if (mSlots[s].mBufferState.isDequeued()) { 109 dequeuedCount++; 110 } 111 } 112 if (dequeuedCount > maxDequeuedBuffers) { 113 BQ_LOGE("setMaxDequeuedBufferCount: the requested maxDequeuedBuffer" 114 "count (%d) exceeds the current dequeued buffer count (%d)", 115 maxDequeuedBuffers, dequeuedCount); 116 return BAD_VALUE; 117 } 118 119 int bufferCount = mCore->getMinUndequeuedBufferCountLocked(); 120 bufferCount += maxDequeuedBuffers; 121 122 if (bufferCount > BufferQueueDefs::NUM_BUFFER_SLOTS) { 123 BQ_LOGE("setMaxDequeuedBufferCount: bufferCount %d too large " 124 "(max %d)", bufferCount, BufferQueueDefs::NUM_BUFFER_SLOTS); 125 return BAD_VALUE; 126 } 127 128 const int minBufferSlots = mCore->getMinMaxBufferCountLocked(); 129 if (bufferCount < minBufferSlots) { 130 BQ_LOGE("setMaxDequeuedBufferCount: requested buffer count %d is " 131 "less than minimum %d", bufferCount, minBufferSlots); 132 return BAD_VALUE; 133 } 134 135 if (bufferCount > mCore->mMaxBufferCount) { 136 BQ_LOGE("setMaxDequeuedBufferCount: %d dequeued buffers would " 137 "exceed the maxBufferCount (%d) (maxAcquired %d async %d " 138 "mDequeuedBufferCannotBlock %d)", maxDequeuedBuffers, 139 mCore->mMaxBufferCount, mCore->mMaxAcquiredBufferCount, 140 mCore->mAsyncMode, mCore->mDequeueBufferCannotBlock); 141 return BAD_VALUE; 142 } 143 144 int delta = maxDequeuedBuffers - mCore->mMaxDequeuedBufferCount; 145 if (!mCore->adjustAvailableSlotsLocked(delta)) { 146 return BAD_VALUE; 147 } 148 mCore->mMaxDequeuedBufferCount = maxDequeuedBuffers; 149 VALIDATE_CONSISTENCY(); 150 if (delta < 0) { 151 listener = mCore->mConsumerListener; 152 } 153 mCore->mDequeueCondition.broadcast(); 154 } // Autolock scope 155 156 // Call back without lock held 157 if (listener != NULL) { 158 listener->onBuffersReleased(); 159 } 160 161 return NO_ERROR; 162} 163 164status_t BufferQueueProducer::setAsyncMode(bool async) { 165 ATRACE_CALL(); 166 BQ_LOGV("setAsyncMode: async = %d", async); 167 168 sp<IConsumerListener> listener; 169 { // Autolock scope 170 Mutex::Autolock lock(mCore->mMutex); 171 mCore->waitWhileAllocatingLocked(); 172 173 if (mCore->mIsAbandoned) { 174 BQ_LOGE("setAsyncMode: BufferQueue has been abandoned"); 175 return NO_INIT; 176 } 177 178 if ((mCore->mMaxAcquiredBufferCount + mCore->mMaxDequeuedBufferCount + 179 (async || mCore->mDequeueBufferCannotBlock ? 1 : 0)) > 180 mCore->mMaxBufferCount) { 181 BQ_LOGE("setAsyncMode(%d): this call would cause the " 182 "maxBufferCount (%d) to be exceeded (maxAcquired %d " 183 "maxDequeued %d mDequeueBufferCannotBlock %d)", async, 184 mCore->mMaxBufferCount, mCore->mMaxAcquiredBufferCount, 185 mCore->mMaxDequeuedBufferCount, 186 mCore->mDequeueBufferCannotBlock); 187 return BAD_VALUE; 188 } 189 190 int delta = mCore->getMaxBufferCountLocked(async, 191 mCore->mDequeueBufferCannotBlock, mCore->mMaxBufferCount) 192 - mCore->getMaxBufferCountLocked(); 193 194 if (!mCore->adjustAvailableSlotsLocked(delta)) { 195 BQ_LOGE("setAsyncMode: BufferQueue failed to adjust the number of " 196 "available slots. Delta = %d", delta); 197 return BAD_VALUE; 198 } 199 mCore->mAsyncMode = async; 200 VALIDATE_CONSISTENCY(); 201 mCore->mDequeueCondition.broadcast(); 202 listener = mCore->mConsumerListener; 203 } // Autolock scope 204 205 // Call back without lock held 206 if (listener != NULL) { 207 listener->onBuffersReleased(); 208 } 209 return NO_ERROR; 210} 211 212int BufferQueueProducer::getFreeBufferLocked() const { 213 if (mCore->mFreeBuffers.empty()) { 214 return BufferQueueCore::INVALID_BUFFER_SLOT; 215 } 216 int slot = mCore->mFreeBuffers.front(); 217 mCore->mFreeBuffers.pop_front(); 218 return slot; 219} 220 221int BufferQueueProducer::getFreeSlotLocked() const { 222 if (mCore->mFreeSlots.empty()) { 223 return BufferQueueCore::INVALID_BUFFER_SLOT; 224 } 225 int slot = *(mCore->mFreeSlots.begin()); 226 mCore->mFreeSlots.erase(slot); 227 return slot; 228} 229 230status_t BufferQueueProducer::waitForFreeSlotThenRelock(FreeSlotCaller caller, 231 int* found) const { 232 auto callerString = (caller == FreeSlotCaller::Dequeue) ? 233 "dequeueBuffer" : "attachBuffer"; 234 bool tryAgain = true; 235 while (tryAgain) { 236 if (mCore->mIsAbandoned) { 237 BQ_LOGE("%s: BufferQueue has been abandoned", callerString); 238 return NO_INIT; 239 } 240 241 int dequeuedCount = 0; 242 int acquiredCount = 0; 243 for (int s : mCore->mActiveBuffers) { 244 if (mSlots[s].mBufferState.isDequeued()) { 245 ++dequeuedCount; 246 } 247 if (mSlots[s].mBufferState.isAcquired()) { 248 ++acquiredCount; 249 } 250 } 251 252 // Producers are not allowed to dequeue more than 253 // mMaxDequeuedBufferCount buffers. 254 // This check is only done if a buffer has already been queued 255 if (mCore->mBufferHasBeenQueued && 256 dequeuedCount >= mCore->mMaxDequeuedBufferCount) { 257 BQ_LOGE("%s: attempting to exceed the max dequeued buffer count " 258 "(%d)", callerString, mCore->mMaxDequeuedBufferCount); 259 return INVALID_OPERATION; 260 } 261 262 *found = BufferQueueCore::INVALID_BUFFER_SLOT; 263 264 // If we disconnect and reconnect quickly, we can be in a state where 265 // our slots are empty but we have many buffers in the queue. This can 266 // cause us to run out of memory if we outrun the consumer. Wait here if 267 // it looks like we have too many buffers queued up. 268 const int maxBufferCount = mCore->getMaxBufferCountLocked(); 269 bool tooManyBuffers = mCore->mQueue.size() 270 > static_cast<size_t>(maxBufferCount); 271 if (tooManyBuffers) { 272 BQ_LOGV("%s: queue size is %zu, waiting", callerString, 273 mCore->mQueue.size()); 274 } else { 275 // If in shared buffer mode and a shared buffer exists, always 276 // return it. 277 if (mCore->mSharedBufferMode && mCore->mSharedBufferSlot != 278 BufferQueueCore::INVALID_BUFFER_SLOT) { 279 *found = mCore->mSharedBufferSlot; 280 } else { 281 if (caller == FreeSlotCaller::Dequeue) { 282 // If we're calling this from dequeue, prefer free buffers 283 int slot = getFreeBufferLocked(); 284 if (slot != BufferQueueCore::INVALID_BUFFER_SLOT) { 285 *found = slot; 286 } else if (mCore->mAllowAllocation) { 287 *found = getFreeSlotLocked(); 288 } 289 } else { 290 // If we're calling this from attach, prefer free slots 291 int slot = getFreeSlotLocked(); 292 if (slot != BufferQueueCore::INVALID_BUFFER_SLOT) { 293 *found = slot; 294 } else { 295 *found = getFreeBufferLocked(); 296 } 297 } 298 } 299 } 300 301 // If no buffer is found, or if the queue has too many buffers 302 // outstanding, wait for a buffer to be acquired or released, or for the 303 // max buffer count to change. 304 tryAgain = (*found == BufferQueueCore::INVALID_BUFFER_SLOT) || 305 tooManyBuffers; 306 if (tryAgain) { 307 // Return an error if we're in non-blocking mode (producer and 308 // consumer are controlled by the application). 309 // However, the consumer is allowed to briefly acquire an extra 310 // buffer (which could cause us to have to wait here), which is 311 // okay, since it is only used to implement an atomic acquire + 312 // release (e.g., in GLConsumer::updateTexImage()) 313 if ((mCore->mDequeueBufferCannotBlock || mCore->mAsyncMode) && 314 (acquiredCount <= mCore->mMaxAcquiredBufferCount)) { 315 return WOULD_BLOCK; 316 } 317 if (mDequeueTimeout >= 0) { 318 status_t result = mCore->mDequeueCondition.waitRelative( 319 mCore->mMutex, mDequeueTimeout); 320 if (result == TIMED_OUT) { 321 return result; 322 } 323 } else { 324 mCore->mDequeueCondition.wait(mCore->mMutex); 325 } 326 } 327 } // while (tryAgain) 328 329 return NO_ERROR; 330} 331 332status_t BufferQueueProducer::dequeueBuffer(int *outSlot, 333 sp<android::Fence> *outFence, uint32_t width, uint32_t height, 334 PixelFormat format, uint32_t usage) { 335 ATRACE_CALL(); 336 { // Autolock scope 337 Mutex::Autolock lock(mCore->mMutex); 338 mConsumerName = mCore->mConsumerName; 339 340 if (mCore->mIsAbandoned) { 341 BQ_LOGE("dequeueBuffer: BufferQueue has been abandoned"); 342 return NO_INIT; 343 } 344 345 if (mCore->mConnectedApi == BufferQueueCore::NO_CONNECTED_API) { 346 BQ_LOGE("dequeueBuffer: BufferQueue has no connected producer"); 347 return NO_INIT; 348 } 349 } // Autolock scope 350 351 BQ_LOGV("dequeueBuffer: w=%u h=%u format=%#x, usage=%#x", width, height, 352 format, usage); 353 354 if ((width && !height) || (!width && height)) { 355 BQ_LOGE("dequeueBuffer: invalid size: w=%u h=%u", width, height); 356 return BAD_VALUE; 357 } 358 359 status_t returnFlags = NO_ERROR; 360 EGLDisplay eglDisplay = EGL_NO_DISPLAY; 361 EGLSyncKHR eglFence = EGL_NO_SYNC_KHR; 362 bool attachedByConsumer = false; 363 364 { // Autolock scope 365 Mutex::Autolock lock(mCore->mMutex); 366 mCore->waitWhileAllocatingLocked(); 367 368 if (format == 0) { 369 format = mCore->mDefaultBufferFormat; 370 } 371 372 // Enable the usage bits the consumer requested 373 usage |= mCore->mConsumerUsageBits; 374 375 const bool useDefaultSize = !width && !height; 376 if (useDefaultSize) { 377 width = mCore->mDefaultWidth; 378 height = mCore->mDefaultHeight; 379 } 380 381 int found = BufferItem::INVALID_BUFFER_SLOT; 382 while (found == BufferItem::INVALID_BUFFER_SLOT) { 383 status_t status = waitForFreeSlotThenRelock(FreeSlotCaller::Dequeue, 384 &found); 385 if (status != NO_ERROR) { 386 return status; 387 } 388 389 // This should not happen 390 if (found == BufferQueueCore::INVALID_BUFFER_SLOT) { 391 BQ_LOGE("dequeueBuffer: no available buffer slots"); 392 return -EBUSY; 393 } 394 395 const sp<GraphicBuffer>& buffer(mSlots[found].mGraphicBuffer); 396 397 // If we are not allowed to allocate new buffers, 398 // waitForFreeSlotThenRelock must have returned a slot containing a 399 // buffer. If this buffer would require reallocation to meet the 400 // requested attributes, we free it and attempt to get another one. 401 if (!mCore->mAllowAllocation) { 402 if (buffer->needsReallocation(width, height, format, usage)) { 403 if (mCore->mSharedBufferSlot == found) { 404 BQ_LOGE("dequeueBuffer: cannot re-allocate a shared" 405 "buffer"); 406 return BAD_VALUE; 407 } 408 mCore->mFreeSlots.insert(found); 409 mCore->clearBufferSlotLocked(found); 410 found = BufferItem::INVALID_BUFFER_SLOT; 411 continue; 412 } 413 } 414 } 415 416 const sp<GraphicBuffer>& buffer(mSlots[found].mGraphicBuffer); 417 if (mCore->mSharedBufferSlot == found && 418 buffer->needsReallocation(width, height, format, usage)) { 419 BQ_LOGE("dequeueBuffer: cannot re-allocate a shared" 420 "buffer"); 421 422 return BAD_VALUE; 423 } 424 425 if (mCore->mSharedBufferSlot != found) { 426 mCore->mActiveBuffers.insert(found); 427 } 428 *outSlot = found; 429 ATRACE_BUFFER_INDEX(found); 430 431 attachedByConsumer = mSlots[found].mNeedsReallocation; 432 mSlots[found].mNeedsReallocation = false; 433 434 mSlots[found].mBufferState.dequeue(); 435 436 // If shared buffer mode has just been enabled, cache the slot of the 437 // first buffer that is dequeued and mark it as the shared buffer. 438 if (mCore->mSharedBufferMode && mCore->mSharedBufferSlot == 439 BufferQueueCore::INVALID_BUFFER_SLOT) { 440 mCore->mSharedBufferSlot = found; 441 mSlots[found].mBufferState.mShared = true; 442 } 443 444 if ((buffer == NULL) || 445 buffer->needsReallocation(width, height, format, usage)) 446 { 447 mSlots[found].mAcquireCalled = false; 448 mSlots[found].mGraphicBuffer = NULL; 449 mSlots[found].mRequestBufferCalled = false; 450 mSlots[found].mEglDisplay = EGL_NO_DISPLAY; 451 mSlots[found].mEglFence = EGL_NO_SYNC_KHR; 452 mSlots[found].mFence = Fence::NO_FENCE; 453 mCore->mBufferAge = 0; 454 mCore->mIsAllocating = true; 455 456 returnFlags |= BUFFER_NEEDS_REALLOCATION; 457 } else { 458 // We add 1 because that will be the frame number when this buffer 459 // is queued 460 mCore->mBufferAge = 461 mCore->mFrameCounter + 1 - mSlots[found].mFrameNumber; 462 } 463 464 BQ_LOGV("dequeueBuffer: setting buffer age to %" PRIu64, 465 mCore->mBufferAge); 466 467 if (CC_UNLIKELY(mSlots[found].mFence == NULL)) { 468 BQ_LOGE("dequeueBuffer: about to return a NULL fence - " 469 "slot=%d w=%d h=%d format=%u", 470 found, buffer->width, buffer->height, buffer->format); 471 } 472 473 eglDisplay = mSlots[found].mEglDisplay; 474 eglFence = mSlots[found].mEglFence; 475 *outFence = mSlots[found].mFence; 476 mSlots[found].mEglFence = EGL_NO_SYNC_KHR; 477 mSlots[found].mFence = Fence::NO_FENCE; 478 } // Autolock scope 479 480 if (returnFlags & BUFFER_NEEDS_REALLOCATION) { 481 status_t error; 482 BQ_LOGV("dequeueBuffer: allocating a new buffer for slot %d", *outSlot); 483 sp<GraphicBuffer> graphicBuffer(mCore->mAllocator->createGraphicBuffer( 484 width, height, format, usage, &error)); 485 { // Autolock scope 486 Mutex::Autolock lock(mCore->mMutex); 487 488 if (graphicBuffer != NULL && !mCore->mIsAbandoned) { 489 graphicBuffer->setGenerationNumber(mCore->mGenerationNumber); 490 mSlots[*outSlot].mGraphicBuffer = graphicBuffer; 491 } 492 493 mCore->mIsAllocating = false; 494 mCore->mIsAllocatingCondition.broadcast(); 495 496 if (graphicBuffer == NULL) { 497 BQ_LOGE("dequeueBuffer: createGraphicBuffer failed"); 498 return error; 499 } 500 501 if (mCore->mIsAbandoned) { 502 BQ_LOGE("dequeueBuffer: BufferQueue has been abandoned"); 503 return NO_INIT; 504 } 505 506 VALIDATE_CONSISTENCY(); 507 } // Autolock scope 508 } 509 510 if (attachedByConsumer) { 511 returnFlags |= BUFFER_NEEDS_REALLOCATION; 512 } 513 514 if (eglFence != EGL_NO_SYNC_KHR) { 515 EGLint result = eglClientWaitSyncKHR(eglDisplay, eglFence, 0, 516 1000000000); 517 // If something goes wrong, log the error, but return the buffer without 518 // synchronizing access to it. It's too late at this point to abort the 519 // dequeue operation. 520 if (result == EGL_FALSE) { 521 BQ_LOGE("dequeueBuffer: error %#x waiting for fence", 522 eglGetError()); 523 } else if (result == EGL_TIMEOUT_EXPIRED_KHR) { 524 BQ_LOGE("dequeueBuffer: timeout waiting for fence"); 525 } 526 eglDestroySyncKHR(eglDisplay, eglFence); 527 } 528 529 BQ_LOGV("dequeueBuffer: returning slot=%d/%" PRIu64 " buf=%p flags=%#x", 530 *outSlot, 531 mSlots[*outSlot].mFrameNumber, 532 mSlots[*outSlot].mGraphicBuffer->handle, returnFlags); 533 534 return returnFlags; 535} 536 537status_t BufferQueueProducer::detachBuffer(int slot) { 538 ATRACE_CALL(); 539 ATRACE_BUFFER_INDEX(slot); 540 BQ_LOGV("detachBuffer: slot %d", slot); 541 Mutex::Autolock lock(mCore->mMutex); 542 543 if (mCore->mIsAbandoned) { 544 BQ_LOGE("detachBuffer: BufferQueue has been abandoned"); 545 return NO_INIT; 546 } 547 548 if (mCore->mConnectedApi == BufferQueueCore::NO_CONNECTED_API) { 549 BQ_LOGE("detachBuffer: BufferQueue has no connected producer"); 550 return NO_INIT; 551 } 552 553 if (mCore->mSharedBufferMode || mCore->mSharedBufferSlot == slot) { 554 BQ_LOGE("detachBuffer: cannot detach a buffer in shared buffer mode"); 555 return BAD_VALUE; 556 } 557 558 if (slot < 0 || slot >= BufferQueueDefs::NUM_BUFFER_SLOTS) { 559 BQ_LOGE("detachBuffer: slot index %d out of range [0, %d)", 560 slot, BufferQueueDefs::NUM_BUFFER_SLOTS); 561 return BAD_VALUE; 562 } else if (!mSlots[slot].mBufferState.isDequeued()) { 563 BQ_LOGE("detachBuffer: slot %d is not owned by the producer " 564 "(state = %s)", slot, mSlots[slot].mBufferState.string()); 565 return BAD_VALUE; 566 } else if (!mSlots[slot].mRequestBufferCalled) { 567 BQ_LOGE("detachBuffer: buffer in slot %d has not been requested", 568 slot); 569 return BAD_VALUE; 570 } 571 572 mSlots[slot].mBufferState.detachProducer(); 573 mCore->mActiveBuffers.erase(slot); 574 mCore->mFreeSlots.insert(slot); 575 mCore->clearBufferSlotLocked(slot); 576 mCore->mDequeueCondition.broadcast(); 577 VALIDATE_CONSISTENCY(); 578 579 return NO_ERROR; 580} 581 582status_t BufferQueueProducer::detachNextBuffer(sp<GraphicBuffer>* outBuffer, 583 sp<Fence>* outFence) { 584 ATRACE_CALL(); 585 586 if (outBuffer == NULL) { 587 BQ_LOGE("detachNextBuffer: outBuffer must not be NULL"); 588 return BAD_VALUE; 589 } else if (outFence == NULL) { 590 BQ_LOGE("detachNextBuffer: outFence must not be NULL"); 591 return BAD_VALUE; 592 } 593 594 Mutex::Autolock lock(mCore->mMutex); 595 596 if (mCore->mIsAbandoned) { 597 BQ_LOGE("detachNextBuffer: BufferQueue has been abandoned"); 598 return NO_INIT; 599 } 600 601 if (mCore->mConnectedApi == BufferQueueCore::NO_CONNECTED_API) { 602 BQ_LOGE("detachNextBuffer: BufferQueue has no connected producer"); 603 return NO_INIT; 604 } 605 606 if (mCore->mSharedBufferMode) { 607 BQ_LOGE("detachNextBuffer: cannot detach a buffer in shared buffer " 608 "mode"); 609 return BAD_VALUE; 610 } 611 612 mCore->waitWhileAllocatingLocked(); 613 614 if (mCore->mFreeBuffers.empty()) { 615 return NO_MEMORY; 616 } 617 618 int found = mCore->mFreeBuffers.front(); 619 mCore->mFreeBuffers.remove(found); 620 mCore->mFreeSlots.insert(found); 621 622 BQ_LOGV("detachNextBuffer detached slot %d", found); 623 624 *outBuffer = mSlots[found].mGraphicBuffer; 625 *outFence = mSlots[found].mFence; 626 mCore->clearBufferSlotLocked(found); 627 VALIDATE_CONSISTENCY(); 628 629 return NO_ERROR; 630} 631 632status_t BufferQueueProducer::attachBuffer(int* outSlot, 633 const sp<android::GraphicBuffer>& buffer) { 634 ATRACE_CALL(); 635 636 if (outSlot == NULL) { 637 BQ_LOGE("attachBuffer: outSlot must not be NULL"); 638 return BAD_VALUE; 639 } else if (buffer == NULL) { 640 BQ_LOGE("attachBuffer: cannot attach NULL buffer"); 641 return BAD_VALUE; 642 } 643 644 Mutex::Autolock lock(mCore->mMutex); 645 646 if (mCore->mIsAbandoned) { 647 BQ_LOGE("attachBuffer: BufferQueue has been abandoned"); 648 return NO_INIT; 649 } 650 651 if (mCore->mConnectedApi == BufferQueueCore::NO_CONNECTED_API) { 652 BQ_LOGE("attachBuffer: BufferQueue has no connected producer"); 653 return NO_INIT; 654 } 655 656 if (mCore->mSharedBufferMode) { 657 BQ_LOGE("attachBuffer: cannot attach a buffer in shared buffer mode"); 658 return BAD_VALUE; 659 } 660 661 if (buffer->getGenerationNumber() != mCore->mGenerationNumber) { 662 BQ_LOGE("attachBuffer: generation number mismatch [buffer %u] " 663 "[queue %u]", buffer->getGenerationNumber(), 664 mCore->mGenerationNumber); 665 return BAD_VALUE; 666 } 667 668 mCore->waitWhileAllocatingLocked(); 669 670 status_t returnFlags = NO_ERROR; 671 int found; 672 status_t status = waitForFreeSlotThenRelock(FreeSlotCaller::Attach, &found); 673 if (status != NO_ERROR) { 674 return status; 675 } 676 677 // This should not happen 678 if (found == BufferQueueCore::INVALID_BUFFER_SLOT) { 679 BQ_LOGE("attachBuffer: no available buffer slots"); 680 return -EBUSY; 681 } 682 683 *outSlot = found; 684 ATRACE_BUFFER_INDEX(*outSlot); 685 BQ_LOGV("attachBuffer: returning slot %d flags=%#x", 686 *outSlot, returnFlags); 687 688 mSlots[*outSlot].mGraphicBuffer = buffer; 689 mSlots[*outSlot].mBufferState.attachProducer(); 690 mSlots[*outSlot].mEglFence = EGL_NO_SYNC_KHR; 691 mSlots[*outSlot].mFence = Fence::NO_FENCE; 692 mSlots[*outSlot].mRequestBufferCalled = true; 693 mSlots[*outSlot].mAcquireCalled = false; 694 mCore->mActiveBuffers.insert(found); 695 VALIDATE_CONSISTENCY(); 696 697 return returnFlags; 698} 699 700status_t BufferQueueProducer::queueBuffer(int slot, 701 const QueueBufferInput &input, QueueBufferOutput *output) { 702 ATRACE_CALL(); 703 ATRACE_BUFFER_INDEX(slot); 704 705 int64_t timestamp; 706 bool isAutoTimestamp; 707 android_dataspace dataSpace; 708 Rect crop(Rect::EMPTY_RECT); 709 int scalingMode; 710 uint32_t transform; 711 uint32_t stickyTransform; 712 sp<Fence> fence; 713 input.deflate(×tamp, &isAutoTimestamp, &dataSpace, &crop, &scalingMode, 714 &transform, &fence, &stickyTransform); 715 Region surfaceDamage = input.getSurfaceDamage(); 716 717 if (fence == NULL) { 718 BQ_LOGE("queueBuffer: fence is NULL"); 719 return BAD_VALUE; 720 } 721 722 switch (scalingMode) { 723 case NATIVE_WINDOW_SCALING_MODE_FREEZE: 724 case NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW: 725 case NATIVE_WINDOW_SCALING_MODE_SCALE_CROP: 726 case NATIVE_WINDOW_SCALING_MODE_NO_SCALE_CROP: 727 break; 728 default: 729 BQ_LOGE("queueBuffer: unknown scaling mode %d", scalingMode); 730 return BAD_VALUE; 731 } 732 733 sp<IConsumerListener> frameAvailableListener; 734 sp<IConsumerListener> frameReplacedListener; 735 int callbackTicket = 0; 736 BufferItem item; 737 { // Autolock scope 738 Mutex::Autolock lock(mCore->mMutex); 739 740 if (mCore->mIsAbandoned) { 741 BQ_LOGE("queueBuffer: BufferQueue has been abandoned"); 742 return NO_INIT; 743 } 744 745 if (mCore->mConnectedApi == BufferQueueCore::NO_CONNECTED_API) { 746 BQ_LOGE("queueBuffer: BufferQueue has no connected producer"); 747 return NO_INIT; 748 } 749 750 if (slot < 0 || slot >= BufferQueueDefs::NUM_BUFFER_SLOTS) { 751 BQ_LOGE("queueBuffer: slot index %d out of range [0, %d)", 752 slot, BufferQueueDefs::NUM_BUFFER_SLOTS); 753 return BAD_VALUE; 754 } else if (!mSlots[slot].mBufferState.isDequeued()) { 755 BQ_LOGE("queueBuffer: slot %d is not owned by the producer " 756 "(state = %s)", slot, mSlots[slot].mBufferState.string()); 757 return BAD_VALUE; 758 } else if (!mSlots[slot].mRequestBufferCalled) { 759 BQ_LOGE("queueBuffer: slot %d was queued without requesting " 760 "a buffer", slot); 761 return BAD_VALUE; 762 } 763 764 // If shared buffer mode has just been enabled, cache the slot of the 765 // first buffer that is queued and mark it as the shared buffer. 766 if (mCore->mSharedBufferMode && mCore->mSharedBufferSlot == 767 BufferQueueCore::INVALID_BUFFER_SLOT) { 768 mCore->mSharedBufferSlot = slot; 769 mSlots[slot].mBufferState.mShared = true; 770 } 771 772 BQ_LOGV("queueBuffer: slot=%d/%" PRIu64 " time=%" PRIu64 " dataSpace=%d" 773 " crop=[%d,%d,%d,%d] transform=%#x scale=%s", 774 slot, mCore->mFrameCounter + 1, timestamp, dataSpace, 775 crop.left, crop.top, crop.right, crop.bottom, transform, 776 BufferItem::scalingModeName(static_cast<uint32_t>(scalingMode))); 777 778 const sp<GraphicBuffer>& graphicBuffer(mSlots[slot].mGraphicBuffer); 779 Rect bufferRect(graphicBuffer->getWidth(), graphicBuffer->getHeight()); 780 Rect croppedRect(Rect::EMPTY_RECT); 781 crop.intersect(bufferRect, &croppedRect); 782 if (croppedRect != crop) { 783 BQ_LOGE("queueBuffer: crop rect is not contained within the " 784 "buffer in slot %d", slot); 785 return BAD_VALUE; 786 } 787 788 // Override UNKNOWN dataspace with consumer default 789 if (dataSpace == HAL_DATASPACE_UNKNOWN) { 790 dataSpace = mCore->mDefaultBufferDataSpace; 791 } 792 793 mSlots[slot].mFence = fence; 794 mSlots[slot].mBufferState.queue(); 795 796 ++mCore->mFrameCounter; 797 mSlots[slot].mFrameNumber = mCore->mFrameCounter; 798 799 item.mAcquireCalled = mSlots[slot].mAcquireCalled; 800 item.mGraphicBuffer = mSlots[slot].mGraphicBuffer; 801 item.mCrop = crop; 802 item.mTransform = transform & 803 ~static_cast<uint32_t>(NATIVE_WINDOW_TRANSFORM_INVERSE_DISPLAY); 804 item.mTransformToDisplayInverse = 805 (transform & NATIVE_WINDOW_TRANSFORM_INVERSE_DISPLAY) != 0; 806 item.mScalingMode = static_cast<uint32_t>(scalingMode); 807 item.mTimestamp = timestamp; 808 item.mIsAutoTimestamp = isAutoTimestamp; 809 item.mDataSpace = dataSpace; 810 item.mFrameNumber = mCore->mFrameCounter; 811 item.mSlot = slot; 812 item.mFence = fence; 813 item.mIsDroppable = mCore->mAsyncMode || 814 mCore->mDequeueBufferCannotBlock || 815 (mCore->mSharedBufferMode && mCore->mSharedBufferSlot == slot); 816 item.mSurfaceDamage = surfaceDamage; 817 item.mQueuedBuffer = true; 818 item.mAutoRefresh = mCore->mSharedBufferMode && mCore->mAutoRefresh; 819 820 mStickyTransform = stickyTransform; 821 822 // Cache the shared buffer data so that the BufferItem can be recreated. 823 if (mCore->mSharedBufferMode) { 824 mCore->mSharedBufferCache.crop = crop; 825 mCore->mSharedBufferCache.transform = transform; 826 mCore->mSharedBufferCache.scalingMode = static_cast<uint32_t>( 827 scalingMode); 828 mCore->mSharedBufferCache.dataspace = dataSpace; 829 } 830 831 if (mCore->mQueue.empty()) { 832 // When the queue is empty, we can ignore mDequeueBufferCannotBlock 833 // and simply queue this buffer 834 mCore->mQueue.push_back(item); 835 frameAvailableListener = mCore->mConsumerListener; 836 } else { 837 // When the queue is not empty, we need to look at the front buffer 838 // state to see if we need to replace it 839 BufferQueueCore::Fifo::iterator front(mCore->mQueue.begin()); 840 if (front->mIsDroppable) { 841 842 if (!front->mIsStale) { 843 mSlots[front->mSlot].mBufferState.freeQueued(); 844 845 // After leaving shared buffer mode, the shared buffer will 846 // still be around. Mark it as no longer shared if this 847 // operation causes it to be free. 848 if (!mCore->mSharedBufferMode && 849 mSlots[front->mSlot].mBufferState.isFree()) { 850 mSlots[front->mSlot].mBufferState.mShared = false; 851 } 852 // Don't put the shared buffer on the free list. 853 if (!mSlots[front->mSlot].mBufferState.isShared()) { 854 mCore->mActiveBuffers.erase(front->mSlot); 855 mCore->mFreeBuffers.push_back(front->mSlot); 856 } 857 } 858 859 // Overwrite the droppable buffer with the incoming one 860 *front = item; 861 frameReplacedListener = mCore->mConsumerListener; 862 } else { 863 mCore->mQueue.push_back(item); 864 frameAvailableListener = mCore->mConsumerListener; 865 } 866 } 867 868 mCore->mBufferHasBeenQueued = true; 869 mCore->mDequeueCondition.broadcast(); 870 mCore->mLastQueuedSlot = slot; 871 872 output->inflate(mCore->mDefaultWidth, mCore->mDefaultHeight, 873 mCore->mTransformHint, 874 static_cast<uint32_t>(mCore->mQueue.size())); 875 876 ATRACE_INT(mCore->mConsumerName.string(), mCore->mQueue.size()); 877 878 // Take a ticket for the callback functions 879 callbackTicket = mNextCallbackTicket++; 880 881 VALIDATE_CONSISTENCY(); 882 } // Autolock scope 883 884 // Don't send the GraphicBuffer through the callback, and don't send 885 // the slot number, since the consumer shouldn't need it 886 item.mGraphicBuffer.clear(); 887 item.mSlot = BufferItem::INVALID_BUFFER_SLOT; 888 889 // Call back without the main BufferQueue lock held, but with the callback 890 // lock held so we can ensure that callbacks occur in order 891 { 892 Mutex::Autolock lock(mCallbackMutex); 893 while (callbackTicket != mCurrentCallbackTicket) { 894 mCallbackCondition.wait(mCallbackMutex); 895 } 896 897 if (frameAvailableListener != NULL) { 898 frameAvailableListener->onFrameAvailable(item); 899 } else if (frameReplacedListener != NULL) { 900 frameReplacedListener->onFrameReplaced(item); 901 } 902 903 ++mCurrentCallbackTicket; 904 mCallbackCondition.broadcast(); 905 } 906 907 // Wait without lock held 908 if (mCore->mConnectedApi == NATIVE_WINDOW_API_EGL) { 909 // Waiting here allows for two full buffers to be queued but not a 910 // third. In the event that frames take varying time, this makes a 911 // small trade-off in favor of latency rather than throughput. 912 mLastQueueBufferFence->waitForever("Throttling EGL Production"); 913 } 914 mLastQueueBufferFence = fence; 915 916 return NO_ERROR; 917} 918 919status_t BufferQueueProducer::cancelBuffer(int slot, const sp<Fence>& fence) { 920 ATRACE_CALL(); 921 BQ_LOGV("cancelBuffer: slot %d", slot); 922 Mutex::Autolock lock(mCore->mMutex); 923 924 if (mCore->mIsAbandoned) { 925 BQ_LOGE("cancelBuffer: BufferQueue has been abandoned"); 926 return NO_INIT; 927 } 928 929 if (mCore->mConnectedApi == BufferQueueCore::NO_CONNECTED_API) { 930 BQ_LOGE("cancelBuffer: BufferQueue has no connected producer"); 931 return NO_INIT; 932 } 933 934 if (mCore->mSharedBufferMode) { 935 BQ_LOGE("cancelBuffer: cannot cancel a buffer in shared buffer mode"); 936 return BAD_VALUE; 937 } 938 939 if (slot < 0 || slot >= BufferQueueDefs::NUM_BUFFER_SLOTS) { 940 BQ_LOGE("cancelBuffer: slot index %d out of range [0, %d)", 941 slot, BufferQueueDefs::NUM_BUFFER_SLOTS); 942 return BAD_VALUE; 943 } else if (!mSlots[slot].mBufferState.isDequeued()) { 944 BQ_LOGE("cancelBuffer: slot %d is not owned by the producer " 945 "(state = %s)", slot, mSlots[slot].mBufferState.string()); 946 return BAD_VALUE; 947 } else if (fence == NULL) { 948 BQ_LOGE("cancelBuffer: fence is NULL"); 949 return BAD_VALUE; 950 } 951 952 mSlots[slot].mBufferState.cancel(); 953 954 // After leaving shared buffer mode, the shared buffer will still be around. 955 // Mark it as no longer shared if this operation causes it to be free. 956 if (!mCore->mSharedBufferMode && mSlots[slot].mBufferState.isFree()) { 957 mSlots[slot].mBufferState.mShared = false; 958 } 959 960 // Don't put the shared buffer on the free list. 961 if (!mSlots[slot].mBufferState.isShared()) { 962 mCore->mActiveBuffers.erase(slot); 963 mCore->mFreeBuffers.push_back(slot); 964 } 965 966 mSlots[slot].mFence = fence; 967 mCore->mDequeueCondition.broadcast(); 968 VALIDATE_CONSISTENCY(); 969 970 return NO_ERROR; 971} 972 973int BufferQueueProducer::query(int what, int *outValue) { 974 ATRACE_CALL(); 975 Mutex::Autolock lock(mCore->mMutex); 976 977 if (outValue == NULL) { 978 BQ_LOGE("query: outValue was NULL"); 979 return BAD_VALUE; 980 } 981 982 if (mCore->mIsAbandoned) { 983 BQ_LOGE("query: BufferQueue has been abandoned"); 984 return NO_INIT; 985 } 986 987 int value; 988 switch (what) { 989 case NATIVE_WINDOW_WIDTH: 990 value = static_cast<int32_t>(mCore->mDefaultWidth); 991 break; 992 case NATIVE_WINDOW_HEIGHT: 993 value = static_cast<int32_t>(mCore->mDefaultHeight); 994 break; 995 case NATIVE_WINDOW_FORMAT: 996 value = static_cast<int32_t>(mCore->mDefaultBufferFormat); 997 break; 998 case NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS: 999 value = mCore->getMinUndequeuedBufferCountLocked(); 1000 break; 1001 case NATIVE_WINDOW_STICKY_TRANSFORM: 1002 value = static_cast<int32_t>(mStickyTransform); 1003 break; 1004 case NATIVE_WINDOW_CONSUMER_RUNNING_BEHIND: 1005 value = (mCore->mQueue.size() > 1); 1006 break; 1007 case NATIVE_WINDOW_CONSUMER_USAGE_BITS: 1008 value = static_cast<int32_t>(mCore->mConsumerUsageBits); 1009 break; 1010 case NATIVE_WINDOW_DEFAULT_DATASPACE: 1011 value = static_cast<int32_t>(mCore->mDefaultBufferDataSpace); 1012 break; 1013 case NATIVE_WINDOW_BUFFER_AGE: 1014 if (mCore->mBufferAge > INT32_MAX) { 1015 value = 0; 1016 } else { 1017 value = static_cast<int32_t>(mCore->mBufferAge); 1018 } 1019 break; 1020 default: 1021 return BAD_VALUE; 1022 } 1023 1024 BQ_LOGV("query: %d? %d", what, value); 1025 *outValue = value; 1026 return NO_ERROR; 1027} 1028 1029status_t BufferQueueProducer::connect(const sp<IProducerListener>& listener, 1030 int api, bool producerControlledByApp, QueueBufferOutput *output) { 1031 ATRACE_CALL(); 1032 Mutex::Autolock lock(mCore->mMutex); 1033 mConsumerName = mCore->mConsumerName; 1034 BQ_LOGV("connect: api=%d producerControlledByApp=%s", api, 1035 producerControlledByApp ? "true" : "false"); 1036 1037 if (mCore->mIsAbandoned) { 1038 BQ_LOGE("connect: BufferQueue has been abandoned"); 1039 return NO_INIT; 1040 } 1041 1042 if (mCore->mConsumerListener == NULL) { 1043 BQ_LOGE("connect: BufferQueue has no consumer"); 1044 return NO_INIT; 1045 } 1046 1047 if (output == NULL) { 1048 BQ_LOGE("connect: output was NULL"); 1049 return BAD_VALUE; 1050 } 1051 1052 if (mCore->mConnectedApi != BufferQueueCore::NO_CONNECTED_API) { 1053 BQ_LOGE("connect: already connected (cur=%d req=%d)", 1054 mCore->mConnectedApi, api); 1055 return BAD_VALUE; 1056 } 1057 1058 int delta = mCore->getMaxBufferCountLocked(mCore->mAsyncMode, 1059 mDequeueTimeout < 0 ? 1060 mCore->mConsumerControlledByApp && producerControlledByApp : false, 1061 mCore->mMaxBufferCount) - 1062 mCore->getMaxBufferCountLocked(); 1063 if (!mCore->adjustAvailableSlotsLocked(delta)) { 1064 BQ_LOGE("connect: BufferQueue failed to adjust the number of available " 1065 "slots. Delta = %d", delta); 1066 return BAD_VALUE; 1067 } 1068 1069 int status = NO_ERROR; 1070 switch (api) { 1071 case NATIVE_WINDOW_API_EGL: 1072 case NATIVE_WINDOW_API_CPU: 1073 case NATIVE_WINDOW_API_MEDIA: 1074 case NATIVE_WINDOW_API_CAMERA: 1075 mCore->mConnectedApi = api; 1076 output->inflate(mCore->mDefaultWidth, mCore->mDefaultHeight, 1077 mCore->mTransformHint, 1078 static_cast<uint32_t>(mCore->mQueue.size())); 1079 1080 // Set up a death notification so that we can disconnect 1081 // automatically if the remote producer dies 1082 if (listener != NULL && 1083 IInterface::asBinder(listener)->remoteBinder() != NULL) { 1084 status = IInterface::asBinder(listener)->linkToDeath( 1085 static_cast<IBinder::DeathRecipient*>(this)); 1086 if (status != NO_ERROR) { 1087 BQ_LOGE("connect: linkToDeath failed: %s (%d)", 1088 strerror(-status), status); 1089 } 1090 } 1091 mCore->mConnectedProducerListener = listener; 1092 break; 1093 default: 1094 BQ_LOGE("connect: unknown API %d", api); 1095 status = BAD_VALUE; 1096 break; 1097 } 1098 1099 mCore->mBufferHasBeenQueued = false; 1100 mCore->mDequeueBufferCannotBlock = false; 1101 if (mDequeueTimeout < 0) { 1102 mCore->mDequeueBufferCannotBlock = 1103 mCore->mConsumerControlledByApp && producerControlledByApp; 1104 } 1105 1106 mCore->mAllowAllocation = true; 1107 VALIDATE_CONSISTENCY(); 1108 return status; 1109} 1110 1111status_t BufferQueueProducer::disconnect(int api) { 1112 ATRACE_CALL(); 1113 BQ_LOGV("disconnect: api %d", api); 1114 1115 int status = NO_ERROR; 1116 sp<IConsumerListener> listener; 1117 { // Autolock scope 1118 Mutex::Autolock lock(mCore->mMutex); 1119 mCore->waitWhileAllocatingLocked(); 1120 1121 if (mCore->mIsAbandoned) { 1122 // It's not really an error to disconnect after the surface has 1123 // been abandoned; it should just be a no-op. 1124 return NO_ERROR; 1125 } 1126 1127 if (api == BufferQueueCore::CURRENTLY_CONNECTED_API) { 1128 api = mCore->mConnectedApi; 1129 // If we're asked to disconnect the currently connected api but 1130 // nobody is connected, it's not really an error. 1131 if (api == BufferQueueCore::NO_CONNECTED_API) { 1132 return NO_ERROR; 1133 } 1134 } 1135 1136 switch (api) { 1137 case NATIVE_WINDOW_API_EGL: 1138 case NATIVE_WINDOW_API_CPU: 1139 case NATIVE_WINDOW_API_MEDIA: 1140 case NATIVE_WINDOW_API_CAMERA: 1141 if (mCore->mConnectedApi == api) { 1142 mCore->freeAllBuffersLocked(); 1143 1144 // Remove our death notification callback if we have one 1145 if (mCore->mConnectedProducerListener != NULL) { 1146 sp<IBinder> token = 1147 IInterface::asBinder(mCore->mConnectedProducerListener); 1148 // This can fail if we're here because of the death 1149 // notification, but we just ignore it 1150 token->unlinkToDeath( 1151 static_cast<IBinder::DeathRecipient*>(this)); 1152 } 1153 mCore->mSharedBufferSlot = 1154 BufferQueueCore::INVALID_BUFFER_SLOT; 1155 mCore->mConnectedProducerListener = NULL; 1156 mCore->mConnectedApi = BufferQueueCore::NO_CONNECTED_API; 1157 mCore->mSidebandStream.clear(); 1158 mCore->mDequeueCondition.broadcast(); 1159 listener = mCore->mConsumerListener; 1160 } else if (mCore->mConnectedApi != BufferQueueCore::NO_CONNECTED_API) { 1161 BQ_LOGE("disconnect: still connected to another API " 1162 "(cur=%d req=%d)", mCore->mConnectedApi, api); 1163 status = BAD_VALUE; 1164 } 1165 break; 1166 default: 1167 BQ_LOGE("disconnect: unknown API %d", api); 1168 status = BAD_VALUE; 1169 break; 1170 } 1171 } // Autolock scope 1172 1173 // Call back without lock held 1174 if (listener != NULL) { 1175 listener->onBuffersReleased(); 1176 } 1177 1178 return status; 1179} 1180 1181status_t BufferQueueProducer::setSidebandStream(const sp<NativeHandle>& stream) { 1182 sp<IConsumerListener> listener; 1183 { // Autolock scope 1184 Mutex::Autolock _l(mCore->mMutex); 1185 mCore->mSidebandStream = stream; 1186 listener = mCore->mConsumerListener; 1187 } // Autolock scope 1188 1189 if (listener != NULL) { 1190 listener->onSidebandStreamChanged(); 1191 } 1192 return NO_ERROR; 1193} 1194 1195void BufferQueueProducer::allocateBuffers(uint32_t width, uint32_t height, 1196 PixelFormat format, uint32_t usage) { 1197 ATRACE_CALL(); 1198 while (true) { 1199 size_t newBufferCount = 0; 1200 uint32_t allocWidth = 0; 1201 uint32_t allocHeight = 0; 1202 PixelFormat allocFormat = PIXEL_FORMAT_UNKNOWN; 1203 uint32_t allocUsage = 0; 1204 { // Autolock scope 1205 Mutex::Autolock lock(mCore->mMutex); 1206 mCore->waitWhileAllocatingLocked(); 1207 1208 if (!mCore->mAllowAllocation) { 1209 BQ_LOGE("allocateBuffers: allocation is not allowed for this " 1210 "BufferQueue"); 1211 return; 1212 } 1213 1214 newBufferCount = mCore->mFreeSlots.size(); 1215 if (newBufferCount == 0) { 1216 return; 1217 } 1218 1219 allocWidth = width > 0 ? width : mCore->mDefaultWidth; 1220 allocHeight = height > 0 ? height : mCore->mDefaultHeight; 1221 allocFormat = format != 0 ? format : mCore->mDefaultBufferFormat; 1222 allocUsage = usage | mCore->mConsumerUsageBits; 1223 1224 mCore->mIsAllocating = true; 1225 } // Autolock scope 1226 1227 Vector<sp<GraphicBuffer>> buffers; 1228 for (size_t i = 0; i < newBufferCount; ++i) { 1229 status_t result = NO_ERROR; 1230 sp<GraphicBuffer> graphicBuffer(mCore->mAllocator->createGraphicBuffer( 1231 allocWidth, allocHeight, allocFormat, allocUsage, &result)); 1232 if (result != NO_ERROR) { 1233 BQ_LOGE("allocateBuffers: failed to allocate buffer (%u x %u, format" 1234 " %u, usage %u)", width, height, format, usage); 1235 Mutex::Autolock lock(mCore->mMutex); 1236 mCore->mIsAllocating = false; 1237 mCore->mIsAllocatingCondition.broadcast(); 1238 return; 1239 } 1240 buffers.push_back(graphicBuffer); 1241 } 1242 1243 { // Autolock scope 1244 Mutex::Autolock lock(mCore->mMutex); 1245 uint32_t checkWidth = width > 0 ? width : mCore->mDefaultWidth; 1246 uint32_t checkHeight = height > 0 ? height : mCore->mDefaultHeight; 1247 PixelFormat checkFormat = format != 0 ? 1248 format : mCore->mDefaultBufferFormat; 1249 uint32_t checkUsage = usage | mCore->mConsumerUsageBits; 1250 if (checkWidth != allocWidth || checkHeight != allocHeight || 1251 checkFormat != allocFormat || checkUsage != allocUsage) { 1252 // Something changed while we released the lock. Retry. 1253 BQ_LOGV("allocateBuffers: size/format/usage changed while allocating. Retrying."); 1254 mCore->mIsAllocating = false; 1255 mCore->mIsAllocatingCondition.broadcast(); 1256 continue; 1257 } 1258 1259 for (size_t i = 0; i < newBufferCount; ++i) { 1260 if (mCore->mFreeSlots.empty()) { 1261 BQ_LOGV("allocateBuffers: a slot was occupied while " 1262 "allocating. Dropping allocated buffer."); 1263 continue; 1264 } 1265 auto slot = mCore->mFreeSlots.begin(); 1266 mCore->clearBufferSlotLocked(*slot); // Clean up the slot first 1267 mSlots[*slot].mGraphicBuffer = buffers[i]; 1268 mSlots[*slot].mFence = Fence::NO_FENCE; 1269 1270 // freeBufferLocked puts this slot on the free slots list. Since 1271 // we then attached a buffer, move the slot to free buffer list. 1272 mCore->mFreeSlots.erase(slot); 1273 mCore->mFreeBuffers.push_front(*slot); 1274 1275 BQ_LOGV("allocateBuffers: allocated a new buffer in slot %d", 1276 *slot); 1277 } 1278 1279 mCore->mIsAllocating = false; 1280 mCore->mIsAllocatingCondition.broadcast(); 1281 VALIDATE_CONSISTENCY(); 1282 } // Autolock scope 1283 } 1284} 1285 1286status_t BufferQueueProducer::allowAllocation(bool allow) { 1287 ATRACE_CALL(); 1288 BQ_LOGV("allowAllocation: %s", allow ? "true" : "false"); 1289 1290 Mutex::Autolock lock(mCore->mMutex); 1291 mCore->mAllowAllocation = allow; 1292 return NO_ERROR; 1293} 1294 1295status_t BufferQueueProducer::setGenerationNumber(uint32_t generationNumber) { 1296 ATRACE_CALL(); 1297 BQ_LOGV("setGenerationNumber: %u", generationNumber); 1298 1299 Mutex::Autolock lock(mCore->mMutex); 1300 mCore->mGenerationNumber = generationNumber; 1301 return NO_ERROR; 1302} 1303 1304String8 BufferQueueProducer::getConsumerName() const { 1305 ATRACE_CALL(); 1306 BQ_LOGV("getConsumerName: %s", mConsumerName.string()); 1307 return mConsumerName; 1308} 1309 1310uint64_t BufferQueueProducer::getNextFrameNumber() const { 1311 ATRACE_CALL(); 1312 1313 Mutex::Autolock lock(mCore->mMutex); 1314 uint64_t nextFrameNumber = mCore->mFrameCounter + 1; 1315 return nextFrameNumber; 1316} 1317 1318status_t BufferQueueProducer::setSharedBufferMode(bool sharedBufferMode) { 1319 ATRACE_CALL(); 1320 BQ_LOGV("setSharedBufferMode: %d", sharedBufferMode); 1321 1322 Mutex::Autolock lock(mCore->mMutex); 1323 if (!sharedBufferMode) { 1324 mCore->mSharedBufferSlot = BufferQueueCore::INVALID_BUFFER_SLOT; 1325 } 1326 mCore->mSharedBufferMode = sharedBufferMode; 1327 return NO_ERROR; 1328} 1329 1330status_t BufferQueueProducer::setAutoRefresh(bool autoRefresh) { 1331 ATRACE_CALL(); 1332 BQ_LOGV("setAutoRefresh: %d", autoRefresh); 1333 1334 Mutex::Autolock lock(mCore->mMutex); 1335 1336 mCore->mAutoRefresh = autoRefresh; 1337 return NO_ERROR; 1338} 1339 1340status_t BufferQueueProducer::setDequeueTimeout(nsecs_t timeout) { 1341 ATRACE_CALL(); 1342 BQ_LOGV("setDequeueTimeout: %" PRId64, timeout); 1343 1344 Mutex::Autolock lock(mCore->mMutex); 1345 int delta = mCore->getMaxBufferCountLocked(mCore->mAsyncMode, false, 1346 mCore->mMaxBufferCount) - mCore->getMaxBufferCountLocked(); 1347 if (!mCore->adjustAvailableSlotsLocked(delta)) { 1348 BQ_LOGE("setDequeueTimeout: BufferQueue failed to adjust the number of " 1349 "available slots. Delta = %d", delta); 1350 return BAD_VALUE; 1351 } 1352 1353 mDequeueTimeout = timeout; 1354 mCore->mDequeueBufferCannotBlock = false; 1355 1356 VALIDATE_CONSISTENCY(); 1357 return NO_ERROR; 1358} 1359 1360status_t BufferQueueProducer::getLastQueuedBuffer(sp<GraphicBuffer>* outBuffer, 1361 sp<Fence>* outFence) { 1362 ATRACE_CALL(); 1363 BQ_LOGV("getLastQueuedBuffer"); 1364 1365 Mutex::Autolock lock(mCore->mMutex); 1366 if (mCore->mLastQueuedSlot == BufferItem::INVALID_BUFFER_SLOT) { 1367 *outBuffer = nullptr; 1368 *outFence = Fence::NO_FENCE; 1369 return NO_ERROR; 1370 } 1371 1372 *outBuffer = mSlots[mCore->mLastQueuedSlot].mGraphicBuffer; 1373 *outFence = mLastQueueBufferFence; 1374 1375 return NO_ERROR; 1376} 1377 1378void BufferQueueProducer::binderDied(const wp<android::IBinder>& /* who */) { 1379 // If we're here, it means that a producer we were connected to died. 1380 // We're guaranteed that we are still connected to it because we remove 1381 // this callback upon disconnect. It's therefore safe to read mConnectedApi 1382 // without synchronization here. 1383 int api = mCore->mConnectedApi; 1384 disconnect(api); 1385} 1386 1387} // namespace android 1388