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