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