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