BufferQueueProducer.cpp revision 3e198b2b331c09e8d078b5cd4cb770bcf049c0d1
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 int connectedApi; 956 sp<Fence> lastQueuedFence; 957 958 { // scope for the lock 959 Mutex::Autolock lock(mCallbackMutex); 960 while (callbackTicket != mCurrentCallbackTicket) { 961 mCallbackCondition.wait(mCallbackMutex); 962 } 963 964 if (frameAvailableListener != NULL) { 965 frameAvailableListener->onFrameAvailable(item); 966 } else if (frameReplacedListener != NULL) { 967 frameReplacedListener->onFrameReplaced(item); 968 } 969 970 connectedApi = mCore->mConnectedApi; 971 lastQueuedFence = std::move(mLastQueueBufferFence); 972 973 mLastQueueBufferFence = std::move(acquireFence); 974 mLastQueuedCrop = item.mCrop; 975 mLastQueuedTransform = item.mTransform; 976 977 ++mCurrentCallbackTicket; 978 mCallbackCondition.broadcast(); 979 } 980 981 // Wait without lock held 982 if (connectedApi == NATIVE_WINDOW_API_EGL) { 983 // Waiting here allows for two full buffers to be queued but not a 984 // third. In the event that frames take varying time, this makes a 985 // small trade-off in favor of latency rather than throughput. 986 lastQueuedFence->waitForever("Throttling EGL Production"); 987 } 988 989 // Update and get FrameEventHistory. 990 nsecs_t postedTime = systemTime(SYSTEM_TIME_MONOTONIC); 991 NewFrameEventsEntry newFrameEventsEntry = { 992 currentFrameNumber, 993 postedTime, 994 requestedPresentTimestamp, 995 std::move(acquireFenceTime) 996 }; 997 addAndGetFrameTimestamps(&newFrameEventsEntry, 998 getFrameTimestamps ? &output->frameTimestamps : nullptr); 999 1000 return NO_ERROR; 1001} 1002 1003status_t BufferQueueProducer::cancelBuffer(int slot, const sp<Fence>& fence) { 1004 ATRACE_CALL(); 1005 BQ_LOGV("cancelBuffer: slot %d", slot); 1006 Mutex::Autolock lock(mCore->mMutex); 1007 1008 if (mCore->mIsAbandoned) { 1009 BQ_LOGE("cancelBuffer: BufferQueue has been abandoned"); 1010 return NO_INIT; 1011 } 1012 1013 if (mCore->mConnectedApi == BufferQueueCore::NO_CONNECTED_API) { 1014 BQ_LOGE("cancelBuffer: BufferQueue has no connected producer"); 1015 return NO_INIT; 1016 } 1017 1018 if (mCore->mSharedBufferMode) { 1019 BQ_LOGE("cancelBuffer: cannot cancel a buffer in shared buffer mode"); 1020 return BAD_VALUE; 1021 } 1022 1023 if (slot < 0 || slot >= BufferQueueDefs::NUM_BUFFER_SLOTS) { 1024 BQ_LOGE("cancelBuffer: slot index %d out of range [0, %d)", 1025 slot, BufferQueueDefs::NUM_BUFFER_SLOTS); 1026 return BAD_VALUE; 1027 } else if (!mSlots[slot].mBufferState.isDequeued()) { 1028 BQ_LOGE("cancelBuffer: slot %d is not owned by the producer " 1029 "(state = %s)", slot, mSlots[slot].mBufferState.string()); 1030 return BAD_VALUE; 1031 } else if (fence == NULL) { 1032 BQ_LOGE("cancelBuffer: fence is NULL"); 1033 return BAD_VALUE; 1034 } 1035 1036 mSlots[slot].mBufferState.cancel(); 1037 1038 // After leaving shared buffer mode, the shared buffer will still be around. 1039 // Mark it as no longer shared if this operation causes it to be free. 1040 if (!mCore->mSharedBufferMode && mSlots[slot].mBufferState.isFree()) { 1041 mSlots[slot].mBufferState.mShared = false; 1042 } 1043 1044 // Don't put the shared buffer on the free list. 1045 if (!mSlots[slot].mBufferState.isShared()) { 1046 mCore->mActiveBuffers.erase(slot); 1047 mCore->mFreeBuffers.push_back(slot); 1048 } 1049 1050 mSlots[slot].mFence = fence; 1051 mCore->mDequeueCondition.broadcast(); 1052 VALIDATE_CONSISTENCY(); 1053 1054 return NO_ERROR; 1055} 1056 1057int BufferQueueProducer::query(int what, int *outValue) { 1058 ATRACE_CALL(); 1059 Mutex::Autolock lock(mCore->mMutex); 1060 1061 if (outValue == NULL) { 1062 BQ_LOGE("query: outValue was NULL"); 1063 return BAD_VALUE; 1064 } 1065 1066 if (mCore->mIsAbandoned) { 1067 BQ_LOGE("query: BufferQueue has been abandoned"); 1068 return NO_INIT; 1069 } 1070 1071 int value; 1072 switch (what) { 1073 case NATIVE_WINDOW_WIDTH: 1074 value = static_cast<int32_t>(mCore->mDefaultWidth); 1075 break; 1076 case NATIVE_WINDOW_HEIGHT: 1077 value = static_cast<int32_t>(mCore->mDefaultHeight); 1078 break; 1079 case NATIVE_WINDOW_FORMAT: 1080 value = static_cast<int32_t>(mCore->mDefaultBufferFormat); 1081 break; 1082 case NATIVE_WINDOW_LAYER_COUNT: 1083 // All BufferQueue buffers have a single layer. 1084 value = BQ_LAYER_COUNT; 1085 break; 1086 case NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS: 1087 value = mCore->getMinUndequeuedBufferCountLocked(); 1088 break; 1089 case NATIVE_WINDOW_STICKY_TRANSFORM: 1090 value = static_cast<int32_t>(mStickyTransform); 1091 break; 1092 case NATIVE_WINDOW_CONSUMER_RUNNING_BEHIND: 1093 value = (mCore->mQueue.size() > 1); 1094 break; 1095 case NATIVE_WINDOW_CONSUMER_USAGE_BITS: 1096 value = static_cast<int32_t>(mCore->mConsumerUsageBits); 1097 break; 1098 case NATIVE_WINDOW_DEFAULT_DATASPACE: 1099 value = static_cast<int32_t>(mCore->mDefaultBufferDataSpace); 1100 break; 1101 case NATIVE_WINDOW_BUFFER_AGE: 1102 if (mCore->mBufferAge > INT32_MAX) { 1103 value = 0; 1104 } else { 1105 value = static_cast<int32_t>(mCore->mBufferAge); 1106 } 1107 break; 1108 default: 1109 return BAD_VALUE; 1110 } 1111 1112 BQ_LOGV("query: %d? %d", what, value); 1113 *outValue = value; 1114 return NO_ERROR; 1115} 1116 1117status_t BufferQueueProducer::connect(const sp<IProducerListener>& listener, 1118 int api, bool producerControlledByApp, QueueBufferOutput *output) { 1119 ATRACE_CALL(); 1120 Mutex::Autolock lock(mCore->mMutex); 1121 mConsumerName = mCore->mConsumerName; 1122 BQ_LOGV("connect: api=%d producerControlledByApp=%s", api, 1123 producerControlledByApp ? "true" : "false"); 1124 1125 if (mCore->mIsAbandoned) { 1126 BQ_LOGE("connect: BufferQueue has been abandoned"); 1127 return NO_INIT; 1128 } 1129 1130 if (mCore->mConsumerListener == NULL) { 1131 BQ_LOGE("connect: BufferQueue has no consumer"); 1132 return NO_INIT; 1133 } 1134 1135 if (output == NULL) { 1136 BQ_LOGE("connect: output was NULL"); 1137 return BAD_VALUE; 1138 } 1139 1140 if (mCore->mConnectedApi != BufferQueueCore::NO_CONNECTED_API) { 1141 BQ_LOGE("connect: already connected (cur=%d req=%d)", 1142 mCore->mConnectedApi, api); 1143 return BAD_VALUE; 1144 } 1145 1146 int delta = mCore->getMaxBufferCountLocked(mCore->mAsyncMode, 1147 mDequeueTimeout < 0 ? 1148 mCore->mConsumerControlledByApp && producerControlledByApp : false, 1149 mCore->mMaxBufferCount) - 1150 mCore->getMaxBufferCountLocked(); 1151 if (!mCore->adjustAvailableSlotsLocked(delta)) { 1152 BQ_LOGE("connect: BufferQueue failed to adjust the number of available " 1153 "slots. Delta = %d", delta); 1154 return BAD_VALUE; 1155 } 1156 1157 int status = NO_ERROR; 1158 switch (api) { 1159 case NATIVE_WINDOW_API_EGL: 1160 case NATIVE_WINDOW_API_CPU: 1161 case NATIVE_WINDOW_API_MEDIA: 1162 case NATIVE_WINDOW_API_CAMERA: 1163 mCore->mConnectedApi = api; 1164 1165 output->width = mCore->mDefaultWidth; 1166 output->height = mCore->mDefaultHeight; 1167 output->transformHint = mCore->mTransformHint; 1168 output->numPendingBuffers = 1169 static_cast<uint32_t>(mCore->mQueue.size()); 1170 output->nextFrameNumber = mCore->mFrameCounter + 1; 1171 output->bufferReplaced = false; 1172 1173 if (listener != NULL) { 1174 // Set up a death notification so that we can disconnect 1175 // automatically if the remote producer dies 1176 if (IInterface::asBinder(listener)->remoteBinder() != NULL) { 1177 status = IInterface::asBinder(listener)->linkToDeath( 1178 static_cast<IBinder::DeathRecipient*>(this)); 1179 if (status != NO_ERROR) { 1180 BQ_LOGE("connect: linkToDeath failed: %s (%d)", 1181 strerror(-status), status); 1182 } 1183 mCore->mLinkedToDeath = listener; 1184 } 1185 if (listener->needsReleaseNotify()) { 1186 mCore->mConnectedProducerListener = listener; 1187 } 1188 } 1189 break; 1190 default: 1191 BQ_LOGE("connect: unknown API %d", api); 1192 status = BAD_VALUE; 1193 break; 1194 } 1195 mCore->mConnectedPid = IPCThreadState::self()->getCallingPid(); 1196 mCore->mBufferHasBeenQueued = false; 1197 mCore->mDequeueBufferCannotBlock = false; 1198 if (mDequeueTimeout < 0) { 1199 mCore->mDequeueBufferCannotBlock = 1200 mCore->mConsumerControlledByApp && producerControlledByApp; 1201 } 1202 1203 mCore->mAllowAllocation = true; 1204 VALIDATE_CONSISTENCY(); 1205 return status; 1206} 1207 1208status_t BufferQueueProducer::disconnect(int api, DisconnectMode mode) { 1209 ATRACE_CALL(); 1210 BQ_LOGV("disconnect: api %d", api); 1211 1212 int status = NO_ERROR; 1213 sp<IConsumerListener> listener; 1214 { // Autolock scope 1215 Mutex::Autolock lock(mCore->mMutex); 1216 1217 if (mode == DisconnectMode::AllLocal) { 1218 if (IPCThreadState::self()->getCallingPid() != mCore->mConnectedPid) { 1219 return NO_ERROR; 1220 } 1221 api = BufferQueueCore::CURRENTLY_CONNECTED_API; 1222 } 1223 1224 mCore->waitWhileAllocatingLocked(); 1225 1226 if (mCore->mIsAbandoned) { 1227 // It's not really an error to disconnect after the surface has 1228 // been abandoned; it should just be a no-op. 1229 return NO_ERROR; 1230 } 1231 1232 if (api == BufferQueueCore::CURRENTLY_CONNECTED_API) { 1233 if (mCore->mConnectedApi == NATIVE_WINDOW_API_MEDIA) { 1234 ALOGD("About to force-disconnect API_MEDIA, mode=%d", mode); 1235 } 1236 api = mCore->mConnectedApi; 1237 // If we're asked to disconnect the currently connected api but 1238 // nobody is connected, it's not really an error. 1239 if (api == BufferQueueCore::NO_CONNECTED_API) { 1240 return NO_ERROR; 1241 } 1242 } 1243 1244 switch (api) { 1245 case NATIVE_WINDOW_API_EGL: 1246 case NATIVE_WINDOW_API_CPU: 1247 case NATIVE_WINDOW_API_MEDIA: 1248 case NATIVE_WINDOW_API_CAMERA: 1249 if (mCore->mConnectedApi == api) { 1250 mCore->freeAllBuffersLocked(); 1251 1252 // Remove our death notification callback if we have one 1253 if (mCore->mLinkedToDeath != NULL) { 1254 sp<IBinder> token = 1255 IInterface::asBinder(mCore->mLinkedToDeath); 1256 // This can fail if we're here because of the death 1257 // notification, but we just ignore it 1258 token->unlinkToDeath( 1259 static_cast<IBinder::DeathRecipient*>(this)); 1260 } 1261 mCore->mSharedBufferSlot = 1262 BufferQueueCore::INVALID_BUFFER_SLOT; 1263 mCore->mLinkedToDeath = NULL; 1264 mCore->mConnectedProducerListener = NULL; 1265 mCore->mConnectedApi = BufferQueueCore::NO_CONNECTED_API; 1266 mCore->mConnectedPid = -1; 1267 mCore->mSidebandStream.clear(); 1268 mCore->mDequeueCondition.broadcast(); 1269 listener = mCore->mConsumerListener; 1270 } else if (mCore->mConnectedApi == BufferQueueCore::NO_CONNECTED_API) { 1271 BQ_LOGE("disconnect: not connected (req=%d)", api); 1272 status = NO_INIT; 1273 } else { 1274 BQ_LOGE("disconnect: still connected to another API " 1275 "(cur=%d req=%d)", mCore->mConnectedApi, api); 1276 status = BAD_VALUE; 1277 } 1278 break; 1279 default: 1280 BQ_LOGE("disconnect: unknown API %d", api); 1281 status = BAD_VALUE; 1282 break; 1283 } 1284 } // Autolock scope 1285 1286 // Call back without lock held 1287 if (listener != NULL) { 1288 listener->onBuffersReleased(); 1289 listener->onDisconnect(); 1290 } 1291 1292 return status; 1293} 1294 1295status_t BufferQueueProducer::setSidebandStream(const sp<NativeHandle>& stream) { 1296 sp<IConsumerListener> listener; 1297 { // Autolock scope 1298 Mutex::Autolock _l(mCore->mMutex); 1299 mCore->mSidebandStream = stream; 1300 listener = mCore->mConsumerListener; 1301 } // Autolock scope 1302 1303 if (listener != NULL) { 1304 listener->onSidebandStreamChanged(); 1305 } 1306 return NO_ERROR; 1307} 1308 1309void BufferQueueProducer::allocateBuffers(uint32_t width, uint32_t height, 1310 PixelFormat format, uint32_t usage) { 1311 ATRACE_CALL(); 1312 while (true) { 1313 size_t newBufferCount = 0; 1314 uint32_t allocWidth = 0; 1315 uint32_t allocHeight = 0; 1316 PixelFormat allocFormat = PIXEL_FORMAT_UNKNOWN; 1317 uint32_t allocUsage = 0; 1318 { // Autolock scope 1319 Mutex::Autolock lock(mCore->mMutex); 1320 mCore->waitWhileAllocatingLocked(); 1321 1322 if (!mCore->mAllowAllocation) { 1323 BQ_LOGE("allocateBuffers: allocation is not allowed for this " 1324 "BufferQueue"); 1325 return; 1326 } 1327 1328 newBufferCount = mCore->mFreeSlots.size(); 1329 if (newBufferCount == 0) { 1330 return; 1331 } 1332 1333 allocWidth = width > 0 ? width : mCore->mDefaultWidth; 1334 allocHeight = height > 0 ? height : mCore->mDefaultHeight; 1335 allocFormat = format != 0 ? format : mCore->mDefaultBufferFormat; 1336 allocUsage = usage | mCore->mConsumerUsageBits; 1337 1338 mCore->mIsAllocating = true; 1339 } // Autolock scope 1340 1341 Vector<sp<GraphicBuffer>> buffers; 1342 for (size_t i = 0; i < newBufferCount; ++i) { 1343 status_t result = NO_ERROR; 1344 sp<GraphicBuffer> graphicBuffer(mCore->mAllocator->createGraphicBuffer( 1345 allocWidth, allocHeight, allocFormat, BQ_LAYER_COUNT, 1346 allocUsage, {mConsumerName.string(), mConsumerName.size()}, 1347 &result)); 1348 if (result != NO_ERROR) { 1349 BQ_LOGE("allocateBuffers: failed to allocate buffer (%u x %u, format" 1350 " %u, usage %u)", width, height, format, usage); 1351 Mutex::Autolock lock(mCore->mMutex); 1352 mCore->mIsAllocating = false; 1353 mCore->mIsAllocatingCondition.broadcast(); 1354 return; 1355 } 1356 buffers.push_back(graphicBuffer); 1357 } 1358 1359 { // Autolock scope 1360 Mutex::Autolock lock(mCore->mMutex); 1361 uint32_t checkWidth = width > 0 ? width : mCore->mDefaultWidth; 1362 uint32_t checkHeight = height > 0 ? height : mCore->mDefaultHeight; 1363 PixelFormat checkFormat = format != 0 ? 1364 format : mCore->mDefaultBufferFormat; 1365 uint32_t checkUsage = usage | mCore->mConsumerUsageBits; 1366 if (checkWidth != allocWidth || checkHeight != allocHeight || 1367 checkFormat != allocFormat || checkUsage != allocUsage) { 1368 // Something changed while we released the lock. Retry. 1369 BQ_LOGV("allocateBuffers: size/format/usage changed while allocating. Retrying."); 1370 mCore->mIsAllocating = false; 1371 mCore->mIsAllocatingCondition.broadcast(); 1372 continue; 1373 } 1374 1375 for (size_t i = 0; i < newBufferCount; ++i) { 1376 if (mCore->mFreeSlots.empty()) { 1377 BQ_LOGV("allocateBuffers: a slot was occupied while " 1378 "allocating. Dropping allocated buffer."); 1379 continue; 1380 } 1381 auto slot = mCore->mFreeSlots.begin(); 1382 mCore->clearBufferSlotLocked(*slot); // Clean up the slot first 1383 mSlots[*slot].mGraphicBuffer = buffers[i]; 1384 mSlots[*slot].mFence = Fence::NO_FENCE; 1385 1386 // freeBufferLocked puts this slot on the free slots list. Since 1387 // we then attached a buffer, move the slot to free buffer list. 1388 mCore->mFreeBuffers.push_front(*slot); 1389 1390 BQ_LOGV("allocateBuffers: allocated a new buffer in slot %d", 1391 *slot); 1392 1393 // Make sure the erase is done after all uses of the slot 1394 // iterator since it will be invalid after this point. 1395 mCore->mFreeSlots.erase(slot); 1396 } 1397 1398 mCore->mIsAllocating = false; 1399 mCore->mIsAllocatingCondition.broadcast(); 1400 VALIDATE_CONSISTENCY(); 1401 } // Autolock scope 1402 } 1403} 1404 1405status_t BufferQueueProducer::allowAllocation(bool allow) { 1406 ATRACE_CALL(); 1407 BQ_LOGV("allowAllocation: %s", allow ? "true" : "false"); 1408 1409 Mutex::Autolock lock(mCore->mMutex); 1410 mCore->mAllowAllocation = allow; 1411 return NO_ERROR; 1412} 1413 1414status_t BufferQueueProducer::setGenerationNumber(uint32_t generationNumber) { 1415 ATRACE_CALL(); 1416 BQ_LOGV("setGenerationNumber: %u", generationNumber); 1417 1418 Mutex::Autolock lock(mCore->mMutex); 1419 mCore->mGenerationNumber = generationNumber; 1420 return NO_ERROR; 1421} 1422 1423String8 BufferQueueProducer::getConsumerName() const { 1424 ATRACE_CALL(); 1425 Mutex::Autolock lock(mCore->mMutex); 1426 BQ_LOGV("getConsumerName: %s", mConsumerName.string()); 1427 return mConsumerName; 1428} 1429 1430status_t BufferQueueProducer::setSharedBufferMode(bool sharedBufferMode) { 1431 ATRACE_CALL(); 1432 BQ_LOGV("setSharedBufferMode: %d", sharedBufferMode); 1433 1434 Mutex::Autolock lock(mCore->mMutex); 1435 if (!sharedBufferMode) { 1436 mCore->mSharedBufferSlot = BufferQueueCore::INVALID_BUFFER_SLOT; 1437 } 1438 mCore->mSharedBufferMode = sharedBufferMode; 1439 return NO_ERROR; 1440} 1441 1442status_t BufferQueueProducer::setAutoRefresh(bool autoRefresh) { 1443 ATRACE_CALL(); 1444 BQ_LOGV("setAutoRefresh: %d", autoRefresh); 1445 1446 Mutex::Autolock lock(mCore->mMutex); 1447 1448 mCore->mAutoRefresh = autoRefresh; 1449 return NO_ERROR; 1450} 1451 1452status_t BufferQueueProducer::setDequeueTimeout(nsecs_t timeout) { 1453 ATRACE_CALL(); 1454 BQ_LOGV("setDequeueTimeout: %" PRId64, timeout); 1455 1456 Mutex::Autolock lock(mCore->mMutex); 1457 int delta = mCore->getMaxBufferCountLocked(mCore->mAsyncMode, false, 1458 mCore->mMaxBufferCount) - mCore->getMaxBufferCountLocked(); 1459 if (!mCore->adjustAvailableSlotsLocked(delta)) { 1460 BQ_LOGE("setDequeueTimeout: BufferQueue failed to adjust the number of " 1461 "available slots. Delta = %d", delta); 1462 return BAD_VALUE; 1463 } 1464 1465 mDequeueTimeout = timeout; 1466 mCore->mDequeueBufferCannotBlock = false; 1467 1468 VALIDATE_CONSISTENCY(); 1469 return NO_ERROR; 1470} 1471 1472status_t BufferQueueProducer::getLastQueuedBuffer(sp<GraphicBuffer>* outBuffer, 1473 sp<Fence>* outFence, float outTransformMatrix[16]) { 1474 ATRACE_CALL(); 1475 BQ_LOGV("getLastQueuedBuffer"); 1476 1477 Mutex::Autolock lock(mCore->mMutex); 1478 if (mCore->mLastQueuedSlot == BufferItem::INVALID_BUFFER_SLOT) { 1479 *outBuffer = nullptr; 1480 *outFence = Fence::NO_FENCE; 1481 return NO_ERROR; 1482 } 1483 1484 *outBuffer = mSlots[mCore->mLastQueuedSlot].mGraphicBuffer; 1485 *outFence = mLastQueueBufferFence; 1486 1487 // Currently only SurfaceFlinger internally ever changes 1488 // GLConsumer's filtering mode, so we just use 'true' here as 1489 // this is slightly specialized for the current client of this API, 1490 // which does want filtering. 1491 GLConsumer::computeTransformMatrix(outTransformMatrix, 1492 mSlots[mCore->mLastQueuedSlot].mGraphicBuffer, mLastQueuedCrop, 1493 mLastQueuedTransform, true /* filter */); 1494 1495 return NO_ERROR; 1496} 1497 1498void BufferQueueProducer::getFrameTimestamps(FrameEventHistoryDelta* outDelta) { 1499 addAndGetFrameTimestamps(nullptr, outDelta); 1500} 1501 1502void BufferQueueProducer::addAndGetFrameTimestamps( 1503 const NewFrameEventsEntry* newTimestamps, 1504 FrameEventHistoryDelta* outDelta) { 1505 if (newTimestamps == nullptr && outDelta == nullptr) { 1506 return; 1507 } 1508 1509 ATRACE_CALL(); 1510 BQ_LOGV("addAndGetFrameTimestamps"); 1511 sp<IConsumerListener> listener; 1512 { 1513 Mutex::Autolock lock(mCore->mMutex); 1514 listener = mCore->mConsumerListener; 1515 } 1516 if (listener != NULL) { 1517 listener->addAndGetFrameTimestamps(newTimestamps, outDelta); 1518 } 1519} 1520 1521void BufferQueueProducer::binderDied(const wp<android::IBinder>& /* who */) { 1522 // If we're here, it means that a producer we were connected to died. 1523 // We're guaranteed that we are still connected to it because we remove 1524 // this callback upon disconnect. It's therefore safe to read mConnectedApi 1525 // without synchronization here. 1526 int api = mCore->mConnectedApi; 1527 disconnect(api); 1528} 1529 1530status_t BufferQueueProducer::getUniqueId(uint64_t* outId) const { 1531 BQ_LOGV("getUniqueId"); 1532 1533 *outId = mCore->mUniqueId; 1534 return NO_ERROR; 1535} 1536 1537} // namespace android 1538