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