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