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