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