BufferQueueProducer.cpp revision f8b4ca51111cd2e566d1774ac464da859db78976
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 if (mCore->mConnectedApi == NATIVE_WINDOW_API_MEDIA) { 1226 ALOGD("About to force-disconnect API_MEDIA, mode=%d", mode); 1227 } 1228 api = mCore->mConnectedApi; 1229 // If we're asked to disconnect the currently connected api but 1230 // nobody is connected, it's not really an error. 1231 if (api == BufferQueueCore::NO_CONNECTED_API) { 1232 return NO_ERROR; 1233 } 1234 } 1235 1236 switch (api) { 1237 case NATIVE_WINDOW_API_EGL: 1238 case NATIVE_WINDOW_API_CPU: 1239 case NATIVE_WINDOW_API_MEDIA: 1240 case NATIVE_WINDOW_API_CAMERA: 1241 if (mCore->mConnectedApi == api) { 1242 mCore->freeAllBuffersLocked(); 1243 1244 // Remove our death notification callback if we have one 1245 if (mCore->mLinkedToDeath != NULL) { 1246 sp<IBinder> token = 1247 IInterface::asBinder(mCore->mLinkedToDeath); 1248 // This can fail if we're here because of the death 1249 // notification, but we just ignore it 1250 token->unlinkToDeath( 1251 static_cast<IBinder::DeathRecipient*>(this)); 1252 } 1253 mCore->mSharedBufferSlot = 1254 BufferQueueCore::INVALID_BUFFER_SLOT; 1255 mCore->mLinkedToDeath = NULL; 1256 mCore->mConnectedProducerListener = NULL; 1257 mCore->mConnectedApi = BufferQueueCore::NO_CONNECTED_API; 1258 mCore->mConnectedPid = -1; 1259 mCore->mSidebandStream.clear(); 1260 mCore->mDequeueCondition.broadcast(); 1261 listener = mCore->mConsumerListener; 1262 } else if (mCore->mConnectedApi != BufferQueueCore::NO_CONNECTED_API) { 1263 BQ_LOGE("disconnect: still connected to another API " 1264 "(cur=%d req=%d)", mCore->mConnectedApi, api); 1265 status = BAD_VALUE; 1266 } 1267 break; 1268 default: 1269 BQ_LOGE("disconnect: unknown API %d", api); 1270 status = BAD_VALUE; 1271 break; 1272 } 1273 } // Autolock scope 1274 1275 // Call back without lock held 1276 if (listener != NULL) { 1277 listener->onBuffersReleased(); 1278 listener->onDisconnect(); 1279 } 1280 1281 return status; 1282} 1283 1284status_t BufferQueueProducer::setSidebandStream(const sp<NativeHandle>& stream) { 1285 sp<IConsumerListener> listener; 1286 { // Autolock scope 1287 Mutex::Autolock _l(mCore->mMutex); 1288 mCore->mSidebandStream = stream; 1289 listener = mCore->mConsumerListener; 1290 } // Autolock scope 1291 1292 if (listener != NULL) { 1293 listener->onSidebandStreamChanged(); 1294 } 1295 return NO_ERROR; 1296} 1297 1298void BufferQueueProducer::allocateBuffers(uint32_t width, uint32_t height, 1299 PixelFormat format, uint32_t usage) { 1300 ATRACE_CALL(); 1301 while (true) { 1302 size_t newBufferCount = 0; 1303 uint32_t allocWidth = 0; 1304 uint32_t allocHeight = 0; 1305 PixelFormat allocFormat = PIXEL_FORMAT_UNKNOWN; 1306 uint32_t allocUsage = 0; 1307 { // Autolock scope 1308 Mutex::Autolock lock(mCore->mMutex); 1309 mCore->waitWhileAllocatingLocked(); 1310 1311 if (!mCore->mAllowAllocation) { 1312 BQ_LOGE("allocateBuffers: allocation is not allowed for this " 1313 "BufferQueue"); 1314 return; 1315 } 1316 1317 newBufferCount = mCore->mFreeSlots.size(); 1318 if (newBufferCount == 0) { 1319 return; 1320 } 1321 1322 allocWidth = width > 0 ? width : mCore->mDefaultWidth; 1323 allocHeight = height > 0 ? height : mCore->mDefaultHeight; 1324 allocFormat = format != 0 ? format : mCore->mDefaultBufferFormat; 1325 allocUsage = usage | mCore->mConsumerUsageBits; 1326 1327 mCore->mIsAllocating = true; 1328 } // Autolock scope 1329 1330 Vector<sp<GraphicBuffer>> buffers; 1331 for (size_t i = 0; i < newBufferCount; ++i) { 1332 status_t result = NO_ERROR; 1333 sp<GraphicBuffer> graphicBuffer(mCore->mAllocator->createGraphicBuffer( 1334 allocWidth, allocHeight, allocFormat, BQ_LAYER_COUNT, 1335 allocUsage, {mConsumerName.string(), mConsumerName.size()}, 1336 &result)); 1337 if (result != NO_ERROR) { 1338 BQ_LOGE("allocateBuffers: failed to allocate buffer (%u x %u, format" 1339 " %u, usage %u)", width, height, format, usage); 1340 Mutex::Autolock lock(mCore->mMutex); 1341 mCore->mIsAllocating = false; 1342 mCore->mIsAllocatingCondition.broadcast(); 1343 return; 1344 } 1345 buffers.push_back(graphicBuffer); 1346 } 1347 1348 { // Autolock scope 1349 Mutex::Autolock lock(mCore->mMutex); 1350 uint32_t checkWidth = width > 0 ? width : mCore->mDefaultWidth; 1351 uint32_t checkHeight = height > 0 ? height : mCore->mDefaultHeight; 1352 PixelFormat checkFormat = format != 0 ? 1353 format : mCore->mDefaultBufferFormat; 1354 uint32_t checkUsage = usage | mCore->mConsumerUsageBits; 1355 if (checkWidth != allocWidth || checkHeight != allocHeight || 1356 checkFormat != allocFormat || checkUsage != allocUsage) { 1357 // Something changed while we released the lock. Retry. 1358 BQ_LOGV("allocateBuffers: size/format/usage changed while allocating. Retrying."); 1359 mCore->mIsAllocating = false; 1360 mCore->mIsAllocatingCondition.broadcast(); 1361 continue; 1362 } 1363 1364 for (size_t i = 0; i < newBufferCount; ++i) { 1365 if (mCore->mFreeSlots.empty()) { 1366 BQ_LOGV("allocateBuffers: a slot was occupied while " 1367 "allocating. Dropping allocated buffer."); 1368 continue; 1369 } 1370 auto slot = mCore->mFreeSlots.begin(); 1371 mCore->clearBufferSlotLocked(*slot); // Clean up the slot first 1372 mSlots[*slot].mGraphicBuffer = buffers[i]; 1373 mSlots[*slot].mFence = Fence::NO_FENCE; 1374 1375 // freeBufferLocked puts this slot on the free slots list. Since 1376 // we then attached a buffer, move the slot to free buffer list. 1377 mCore->mFreeBuffers.push_front(*slot); 1378 1379 BQ_LOGV("allocateBuffers: allocated a new buffer in slot %d", 1380 *slot); 1381 1382 // Make sure the erase is done after all uses of the slot 1383 // iterator since it will be invalid after this point. 1384 mCore->mFreeSlots.erase(slot); 1385 } 1386 1387 mCore->mIsAllocating = false; 1388 mCore->mIsAllocatingCondition.broadcast(); 1389 VALIDATE_CONSISTENCY(); 1390 } // Autolock scope 1391 } 1392} 1393 1394status_t BufferQueueProducer::allowAllocation(bool allow) { 1395 ATRACE_CALL(); 1396 BQ_LOGV("allowAllocation: %s", allow ? "true" : "false"); 1397 1398 Mutex::Autolock lock(mCore->mMutex); 1399 mCore->mAllowAllocation = allow; 1400 return NO_ERROR; 1401} 1402 1403status_t BufferQueueProducer::setGenerationNumber(uint32_t generationNumber) { 1404 ATRACE_CALL(); 1405 BQ_LOGV("setGenerationNumber: %u", generationNumber); 1406 1407 Mutex::Autolock lock(mCore->mMutex); 1408 mCore->mGenerationNumber = generationNumber; 1409 return NO_ERROR; 1410} 1411 1412String8 BufferQueueProducer::getConsumerName() const { 1413 ATRACE_CALL(); 1414 Mutex::Autolock lock(mCore->mMutex); 1415 BQ_LOGV("getConsumerName: %s", mConsumerName.string()); 1416 return mConsumerName; 1417} 1418 1419status_t BufferQueueProducer::setSharedBufferMode(bool sharedBufferMode) { 1420 ATRACE_CALL(); 1421 BQ_LOGV("setSharedBufferMode: %d", sharedBufferMode); 1422 1423 Mutex::Autolock lock(mCore->mMutex); 1424 if (!sharedBufferMode) { 1425 mCore->mSharedBufferSlot = BufferQueueCore::INVALID_BUFFER_SLOT; 1426 } 1427 mCore->mSharedBufferMode = sharedBufferMode; 1428 return NO_ERROR; 1429} 1430 1431status_t BufferQueueProducer::setAutoRefresh(bool autoRefresh) { 1432 ATRACE_CALL(); 1433 BQ_LOGV("setAutoRefresh: %d", autoRefresh); 1434 1435 Mutex::Autolock lock(mCore->mMutex); 1436 1437 mCore->mAutoRefresh = autoRefresh; 1438 return NO_ERROR; 1439} 1440 1441status_t BufferQueueProducer::setDequeueTimeout(nsecs_t timeout) { 1442 ATRACE_CALL(); 1443 BQ_LOGV("setDequeueTimeout: %" PRId64, timeout); 1444 1445 Mutex::Autolock lock(mCore->mMutex); 1446 int delta = mCore->getMaxBufferCountLocked(mCore->mAsyncMode, false, 1447 mCore->mMaxBufferCount) - mCore->getMaxBufferCountLocked(); 1448 if (!mCore->adjustAvailableSlotsLocked(delta)) { 1449 BQ_LOGE("setDequeueTimeout: BufferQueue failed to adjust the number of " 1450 "available slots. Delta = %d", delta); 1451 return BAD_VALUE; 1452 } 1453 1454 mDequeueTimeout = timeout; 1455 mCore->mDequeueBufferCannotBlock = false; 1456 1457 VALIDATE_CONSISTENCY(); 1458 return NO_ERROR; 1459} 1460 1461status_t BufferQueueProducer::getLastQueuedBuffer(sp<GraphicBuffer>* outBuffer, 1462 sp<Fence>* outFence, float outTransformMatrix[16]) { 1463 ATRACE_CALL(); 1464 BQ_LOGV("getLastQueuedBuffer"); 1465 1466 Mutex::Autolock lock(mCore->mMutex); 1467 if (mCore->mLastQueuedSlot == BufferItem::INVALID_BUFFER_SLOT) { 1468 *outBuffer = nullptr; 1469 *outFence = Fence::NO_FENCE; 1470 return NO_ERROR; 1471 } 1472 1473 *outBuffer = mSlots[mCore->mLastQueuedSlot].mGraphicBuffer; 1474 *outFence = mLastQueueBufferFence; 1475 1476 // Currently only SurfaceFlinger internally ever changes 1477 // GLConsumer's filtering mode, so we just use 'true' here as 1478 // this is slightly specialized for the current client of this API, 1479 // which does want filtering. 1480 GLConsumer::computeTransformMatrix(outTransformMatrix, 1481 mSlots[mCore->mLastQueuedSlot].mGraphicBuffer, mLastQueuedCrop, 1482 mLastQueuedTransform, true /* filter */); 1483 1484 return NO_ERROR; 1485} 1486 1487void BufferQueueProducer::getFrameTimestamps(FrameEventHistoryDelta* outDelta) { 1488 addAndGetFrameTimestamps(nullptr, outDelta); 1489} 1490 1491void BufferQueueProducer::addAndGetFrameTimestamps( 1492 const NewFrameEventsEntry* newTimestamps, 1493 FrameEventHistoryDelta* outDelta) { 1494 if (newTimestamps == nullptr && outDelta == nullptr) { 1495 return; 1496 } 1497 1498 ATRACE_CALL(); 1499 BQ_LOGV("addAndGetFrameTimestamps"); 1500 sp<IConsumerListener> listener; 1501 { 1502 Mutex::Autolock lock(mCore->mMutex); 1503 listener = mCore->mConsumerListener; 1504 } 1505 if (listener != NULL) { 1506 listener->addAndGetFrameTimestamps(newTimestamps, outDelta); 1507 } 1508} 1509 1510void BufferQueueProducer::binderDied(const wp<android::IBinder>& /* who */) { 1511 // If we're here, it means that a producer we were connected to died. 1512 // We're guaranteed that we are still connected to it because we remove 1513 // this callback upon disconnect. It's therefore safe to read mConnectedApi 1514 // without synchronization here. 1515 int api = mCore->mConnectedApi; 1516 disconnect(api); 1517} 1518 1519status_t BufferQueueProducer::getUniqueId(uint64_t* outId) const { 1520 BQ_LOGV("getUniqueId"); 1521 1522 *outId = mCore->mUniqueId; 1523 return NO_ERROR; 1524} 1525 1526} // namespace android 1527