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 "BufferQueueConsumer" 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 #include <gui/BufferItem.h> 30 #include <gui/BufferQueueConsumer.h> 31 #include <gui/BufferQueueCore.h> 32 #include <gui/IConsumerListener.h> 33 #include <gui/IProducerListener.h> 34 35 #include <binder/IPCThreadState.h> 36 #include <binder/PermissionCache.h> 37 #include <private/android_filesystem_config.h> 38 39 namespace android { 40 41 BufferQueueConsumer::BufferQueueConsumer(const sp<BufferQueueCore>& core) : 42 mCore(core), 43 mSlots(core->mSlots), 44 mConsumerName() {} 45 46 BufferQueueConsumer::~BufferQueueConsumer() {} 47 48 status_t BufferQueueConsumer::acquireBuffer(BufferItem* outBuffer, 49 nsecs_t expectedPresent, uint64_t maxFrameNumber) { 50 ATRACE_CALL(); 51 52 int numDroppedBuffers = 0; 53 sp<IProducerListener> listener; 54 { 55 Mutex::Autolock lock(mCore->mMutex); 56 57 // Check that the consumer doesn't currently have the maximum number of 58 // buffers acquired. We allow the max buffer count to be exceeded by one 59 // buffer so that the consumer can successfully set up the newly acquired 60 // buffer before releasing the old one. 61 int numAcquiredBuffers = 0; 62 for (int s : mCore->mActiveBuffers) { 63 if (mSlots[s].mBufferState.isAcquired()) { 64 ++numAcquiredBuffers; 65 } 66 } 67 if (numAcquiredBuffers >= mCore->mMaxAcquiredBufferCount + 1) { 68 BQ_LOGE("acquireBuffer: max acquired buffer count reached: %d (max %d)", 69 numAcquiredBuffers, mCore->mMaxAcquiredBufferCount); 70 return INVALID_OPERATION; 71 } 72 73 bool sharedBufferAvailable = mCore->mSharedBufferMode && 74 mCore->mAutoRefresh && mCore->mSharedBufferSlot != 75 BufferQueueCore::INVALID_BUFFER_SLOT; 76 77 // In asynchronous mode the list is guaranteed to be one buffer deep, 78 // while in synchronous mode we use the oldest buffer. 79 if (mCore->mQueue.empty() && !sharedBufferAvailable) { 80 return NO_BUFFER_AVAILABLE; 81 } 82 83 BufferQueueCore::Fifo::iterator front(mCore->mQueue.begin()); 84 85 // If expectedPresent is specified, we may not want to return a buffer yet. 86 // If it's specified and there's more than one buffer queued, we may want 87 // to drop a buffer. 88 // Skip this if we're in shared buffer mode and the queue is empty, 89 // since in that case we'll just return the shared buffer. 90 if (expectedPresent != 0 && !mCore->mQueue.empty()) { 91 const int MAX_REASONABLE_NSEC = 1000000000ULL; // 1 second 92 93 // The 'expectedPresent' argument indicates when the buffer is expected 94 // to be presented on-screen. If the buffer's desired present time is 95 // earlier (less) than expectedPresent -- meaning it will be displayed 96 // on time or possibly late if we show it as soon as possible -- we 97 // acquire and return it. If we don't want to display it until after the 98 // expectedPresent time, we return PRESENT_LATER without acquiring it. 99 // 100 // To be safe, we don't defer acquisition if expectedPresent is more 101 // than one second in the future beyond the desired present time 102 // (i.e., we'd be holding the buffer for a long time). 103 // 104 // NOTE: Code assumes monotonic time values from the system clock 105 // are positive. 106 107 // Start by checking to see if we can drop frames. We skip this check if 108 // the timestamps are being auto-generated by Surface. If the app isn't 109 // generating timestamps explicitly, it probably doesn't want frames to 110 // be discarded based on them. 111 while (mCore->mQueue.size() > 1 && !mCore->mQueue[0].mIsAutoTimestamp) { 112 const BufferItem& bufferItem(mCore->mQueue[1]); 113 114 // If dropping entry[0] would leave us with a buffer that the 115 // consumer is not yet ready for, don't drop it. 116 if (maxFrameNumber && bufferItem.mFrameNumber > maxFrameNumber) { 117 break; 118 } 119 120 // If entry[1] is timely, drop entry[0] (and repeat). We apply an 121 // additional criterion here: we only drop the earlier buffer if our 122 // desiredPresent falls within +/- 1 second of the expected present. 123 // Otherwise, bogus desiredPresent times (e.g., 0 or a small 124 // relative timestamp), which normally mean "ignore the timestamp 125 // and acquire immediately", would cause us to drop frames. 126 // 127 // We may want to add an additional criterion: don't drop the 128 // earlier buffer if entry[1]'s fence hasn't signaled yet. 129 nsecs_t desiredPresent = bufferItem.mTimestamp; 130 if (desiredPresent < expectedPresent - MAX_REASONABLE_NSEC || 131 desiredPresent > expectedPresent) { 132 // This buffer is set to display in the near future, or 133 // desiredPresent is garbage. Either way we don't want to drop 134 // the previous buffer just to get this on the screen sooner. 135 BQ_LOGV("acquireBuffer: nodrop desire=%" PRId64 " expect=%" 136 PRId64 " (%" PRId64 ") now=%" PRId64, 137 desiredPresent, expectedPresent, 138 desiredPresent - expectedPresent, 139 systemTime(CLOCK_MONOTONIC)); 140 break; 141 } 142 143 BQ_LOGV("acquireBuffer: drop desire=%" PRId64 " expect=%" PRId64 144 " size=%zu", 145 desiredPresent, expectedPresent, mCore->mQueue.size()); 146 147 if (!front->mIsStale) { 148 // Front buffer is still in mSlots, so mark the slot as free 149 mSlots[front->mSlot].mBufferState.freeQueued(); 150 151 // After leaving shared buffer mode, the shared buffer will 152 // still be around. Mark it as no longer shared if this 153 // operation causes it to be free. 154 if (!mCore->mSharedBufferMode && 155 mSlots[front->mSlot].mBufferState.isFree()) { 156 mSlots[front->mSlot].mBufferState.mShared = false; 157 } 158 159 // Don't put the shared buffer on the free list 160 if (!mSlots[front->mSlot].mBufferState.isShared()) { 161 mCore->mActiveBuffers.erase(front->mSlot); 162 mCore->mFreeBuffers.push_back(front->mSlot); 163 } 164 165 listener = mCore->mConnectedProducerListener; 166 ++numDroppedBuffers; 167 } 168 169 mCore->mQueue.erase(front); 170 front = mCore->mQueue.begin(); 171 } 172 173 // See if the front buffer is ready to be acquired 174 nsecs_t desiredPresent = front->mTimestamp; 175 bool bufferIsDue = desiredPresent <= expectedPresent || 176 desiredPresent > expectedPresent + MAX_REASONABLE_NSEC; 177 bool consumerIsReady = maxFrameNumber > 0 ? 178 front->mFrameNumber <= maxFrameNumber : true; 179 if (!bufferIsDue || !consumerIsReady) { 180 BQ_LOGV("acquireBuffer: defer desire=%" PRId64 " expect=%" PRId64 181 " (%" PRId64 ") now=%" PRId64 " frame=%" PRIu64 182 " consumer=%" PRIu64, 183 desiredPresent, expectedPresent, 184 desiredPresent - expectedPresent, 185 systemTime(CLOCK_MONOTONIC), 186 front->mFrameNumber, maxFrameNumber); 187 return PRESENT_LATER; 188 } 189 190 BQ_LOGV("acquireBuffer: accept desire=%" PRId64 " expect=%" PRId64 " " 191 "(%" PRId64 ") now=%" PRId64, desiredPresent, expectedPresent, 192 desiredPresent - expectedPresent, 193 systemTime(CLOCK_MONOTONIC)); 194 } 195 196 int slot = BufferQueueCore::INVALID_BUFFER_SLOT; 197 198 if (sharedBufferAvailable && mCore->mQueue.empty()) { 199 // make sure the buffer has finished allocating before acquiring it 200 mCore->waitWhileAllocatingLocked(); 201 202 slot = mCore->mSharedBufferSlot; 203 204 // Recreate the BufferItem for the shared buffer from the data that 205 // was cached when it was last queued. 206 outBuffer->mGraphicBuffer = mSlots[slot].mGraphicBuffer; 207 outBuffer->mFence = Fence::NO_FENCE; 208 outBuffer->mCrop = mCore->mSharedBufferCache.crop; 209 outBuffer->mTransform = mCore->mSharedBufferCache.transform & 210 ~static_cast<uint32_t>( 211 NATIVE_WINDOW_TRANSFORM_INVERSE_DISPLAY); 212 outBuffer->mScalingMode = mCore->mSharedBufferCache.scalingMode; 213 outBuffer->mDataSpace = mCore->mSharedBufferCache.dataspace; 214 outBuffer->mFrameNumber = mCore->mFrameCounter; 215 outBuffer->mSlot = slot; 216 outBuffer->mAcquireCalled = mSlots[slot].mAcquireCalled; 217 outBuffer->mTransformToDisplayInverse = 218 (mCore->mSharedBufferCache.transform & 219 NATIVE_WINDOW_TRANSFORM_INVERSE_DISPLAY) != 0; 220 outBuffer->mSurfaceDamage = Region::INVALID_REGION; 221 outBuffer->mQueuedBuffer = false; 222 outBuffer->mIsStale = false; 223 outBuffer->mAutoRefresh = mCore->mSharedBufferMode && 224 mCore->mAutoRefresh; 225 } else { 226 slot = front->mSlot; 227 *outBuffer = *front; 228 } 229 230 ATRACE_BUFFER_INDEX(slot); 231 232 BQ_LOGV("acquireBuffer: acquiring { slot=%d/%" PRIu64 " buffer=%p }", 233 slot, outBuffer->mFrameNumber, outBuffer->mGraphicBuffer->handle); 234 235 if (!outBuffer->mIsStale) { 236 mSlots[slot].mAcquireCalled = true; 237 // Don't decrease the queue count if the BufferItem wasn't 238 // previously in the queue. This happens in shared buffer mode when 239 // the queue is empty and the BufferItem is created above. 240 if (mCore->mQueue.empty()) { 241 mSlots[slot].mBufferState.acquireNotInQueue(); 242 } else { 243 mSlots[slot].mBufferState.acquire(); 244 } 245 mSlots[slot].mFence = Fence::NO_FENCE; 246 } 247 248 // If the buffer has previously been acquired by the consumer, set 249 // mGraphicBuffer to NULL to avoid unnecessarily remapping this buffer 250 // on the consumer side 251 if (outBuffer->mAcquireCalled) { 252 outBuffer->mGraphicBuffer = NULL; 253 } 254 255 mCore->mQueue.erase(front); 256 257 // We might have freed a slot while dropping old buffers, or the producer 258 // may be blocked waiting for the number of buffers in the queue to 259 // decrease. 260 mCore->mDequeueCondition.broadcast(); 261 262 ATRACE_INT(mCore->mConsumerName.string(), mCore->mQueue.size()); 263 mCore->mOccupancyTracker.registerOccupancyChange(mCore->mQueue.size()); 264 265 VALIDATE_CONSISTENCY(); 266 } 267 268 if (listener != NULL) { 269 for (int i = 0; i < numDroppedBuffers; ++i) { 270 listener->onBufferReleased(); 271 } 272 } 273 274 return NO_ERROR; 275 } 276 277 status_t BufferQueueConsumer::detachBuffer(int slot) { 278 ATRACE_CALL(); 279 ATRACE_BUFFER_INDEX(slot); 280 BQ_LOGV("detachBuffer: slot %d", slot); 281 Mutex::Autolock lock(mCore->mMutex); 282 283 if (mCore->mIsAbandoned) { 284 BQ_LOGE("detachBuffer: BufferQueue has been abandoned"); 285 return NO_INIT; 286 } 287 288 if (mCore->mSharedBufferMode || slot == mCore->mSharedBufferSlot) { 289 BQ_LOGE("detachBuffer: detachBuffer not allowed in shared buffer mode"); 290 return BAD_VALUE; 291 } 292 293 if (slot < 0 || slot >= BufferQueueDefs::NUM_BUFFER_SLOTS) { 294 BQ_LOGE("detachBuffer: slot index %d out of range [0, %d)", 295 slot, BufferQueueDefs::NUM_BUFFER_SLOTS); 296 return BAD_VALUE; 297 } else if (!mSlots[slot].mBufferState.isAcquired()) { 298 BQ_LOGE("detachBuffer: slot %d is not owned by the consumer " 299 "(state = %s)", slot, mSlots[slot].mBufferState.string()); 300 return BAD_VALUE; 301 } 302 303 mSlots[slot].mBufferState.detachConsumer(); 304 mCore->mActiveBuffers.erase(slot); 305 mCore->mFreeSlots.insert(slot); 306 mCore->clearBufferSlotLocked(slot); 307 mCore->mDequeueCondition.broadcast(); 308 VALIDATE_CONSISTENCY(); 309 310 return NO_ERROR; 311 } 312 313 status_t BufferQueueConsumer::attachBuffer(int* outSlot, 314 const sp<android::GraphicBuffer>& buffer) { 315 ATRACE_CALL(); 316 317 if (outSlot == NULL) { 318 BQ_LOGE("attachBuffer: outSlot must not be NULL"); 319 return BAD_VALUE; 320 } else if (buffer == NULL) { 321 BQ_LOGE("attachBuffer: cannot attach NULL buffer"); 322 return BAD_VALUE; 323 } 324 325 Mutex::Autolock lock(mCore->mMutex); 326 327 if (mCore->mSharedBufferMode) { 328 BQ_LOGE("attachBuffer: cannot attach a buffer in shared buffer mode"); 329 return BAD_VALUE; 330 } 331 332 // Make sure we don't have too many acquired buffers 333 int numAcquiredBuffers = 0; 334 for (int s : mCore->mActiveBuffers) { 335 if (mSlots[s].mBufferState.isAcquired()) { 336 ++numAcquiredBuffers; 337 } 338 } 339 340 if (numAcquiredBuffers >= mCore->mMaxAcquiredBufferCount + 1) { 341 BQ_LOGE("attachBuffer: max acquired buffer count reached: %d " 342 "(max %d)", numAcquiredBuffers, 343 mCore->mMaxAcquiredBufferCount); 344 return INVALID_OPERATION; 345 } 346 347 if (buffer->getGenerationNumber() != mCore->mGenerationNumber) { 348 BQ_LOGE("attachBuffer: generation number mismatch [buffer %u] " 349 "[queue %u]", buffer->getGenerationNumber(), 350 mCore->mGenerationNumber); 351 return BAD_VALUE; 352 } 353 354 // Find a free slot to put the buffer into 355 int found = BufferQueueCore::INVALID_BUFFER_SLOT; 356 if (!mCore->mFreeSlots.empty()) { 357 auto slot = mCore->mFreeSlots.begin(); 358 found = *slot; 359 mCore->mFreeSlots.erase(slot); 360 } else if (!mCore->mFreeBuffers.empty()) { 361 found = mCore->mFreeBuffers.front(); 362 mCore->mFreeBuffers.remove(found); 363 } 364 if (found == BufferQueueCore::INVALID_BUFFER_SLOT) { 365 BQ_LOGE("attachBuffer: could not find free buffer slot"); 366 return NO_MEMORY; 367 } 368 369 mCore->mActiveBuffers.insert(found); 370 *outSlot = found; 371 ATRACE_BUFFER_INDEX(*outSlot); 372 BQ_LOGV("attachBuffer: returning slot %d", *outSlot); 373 374 mSlots[*outSlot].mGraphicBuffer = buffer; 375 mSlots[*outSlot].mBufferState.attachConsumer(); 376 mSlots[*outSlot].mNeedsReallocation = true; 377 mSlots[*outSlot].mFence = Fence::NO_FENCE; 378 mSlots[*outSlot].mFrameNumber = 0; 379 380 // mAcquireCalled tells BufferQueue that it doesn't need to send a valid 381 // GraphicBuffer pointer on the next acquireBuffer call, which decreases 382 // Binder traffic by not un/flattening the GraphicBuffer. However, it 383 // requires that the consumer maintain a cached copy of the slot <--> buffer 384 // mappings, which is why the consumer doesn't need the valid pointer on 385 // acquire. 386 // 387 // The StreamSplitter is one of the primary users of the attach/detach 388 // logic, and while it is running, all buffers it acquires are immediately 389 // detached, and all buffers it eventually releases are ones that were 390 // attached (as opposed to having been obtained from acquireBuffer), so it 391 // doesn't make sense to maintain the slot/buffer mappings, which would 392 // become invalid for every buffer during detach/attach. By setting this to 393 // false, the valid GraphicBuffer pointer will always be sent with acquire 394 // for attached buffers. 395 mSlots[*outSlot].mAcquireCalled = false; 396 397 VALIDATE_CONSISTENCY(); 398 399 return NO_ERROR; 400 } 401 402 status_t BufferQueueConsumer::releaseBuffer(int slot, uint64_t frameNumber, 403 const sp<Fence>& releaseFence, EGLDisplay eglDisplay, 404 EGLSyncKHR eglFence) { 405 ATRACE_CALL(); 406 ATRACE_BUFFER_INDEX(slot); 407 408 if (slot < 0 || slot >= BufferQueueDefs::NUM_BUFFER_SLOTS || 409 releaseFence == NULL) { 410 BQ_LOGE("releaseBuffer: slot %d out of range or fence %p NULL", slot, 411 releaseFence.get()); 412 return BAD_VALUE; 413 } 414 415 sp<IProducerListener> listener; 416 { // Autolock scope 417 Mutex::Autolock lock(mCore->mMutex); 418 419 // If the frame number has changed because the buffer has been reallocated, 420 // we can ignore this releaseBuffer for the old buffer. 421 // Ignore this for the shared buffer where the frame number can easily 422 // get out of sync due to the buffer being queued and acquired at the 423 // same time. 424 if (frameNumber != mSlots[slot].mFrameNumber && 425 !mSlots[slot].mBufferState.isShared()) { 426 return STALE_BUFFER_SLOT; 427 } 428 429 if (!mSlots[slot].mBufferState.isAcquired()) { 430 BQ_LOGE("releaseBuffer: attempted to release buffer slot %d " 431 "but its state was %s", slot, 432 mSlots[slot].mBufferState.string()); 433 return BAD_VALUE; 434 } 435 436 mSlots[slot].mEglDisplay = eglDisplay; 437 mSlots[slot].mEglFence = eglFence; 438 mSlots[slot].mFence = releaseFence; 439 mSlots[slot].mBufferState.release(); 440 441 // After leaving shared buffer mode, the shared buffer will 442 // still be around. Mark it as no longer shared if this 443 // operation causes it to be free. 444 if (!mCore->mSharedBufferMode && mSlots[slot].mBufferState.isFree()) { 445 mSlots[slot].mBufferState.mShared = false; 446 } 447 // Don't put the shared buffer on the free list. 448 if (!mSlots[slot].mBufferState.isShared()) { 449 mCore->mActiveBuffers.erase(slot); 450 mCore->mFreeBuffers.push_back(slot); 451 } 452 453 listener = mCore->mConnectedProducerListener; 454 BQ_LOGV("releaseBuffer: releasing slot %d", slot); 455 456 mCore->mDequeueCondition.broadcast(); 457 VALIDATE_CONSISTENCY(); 458 } // Autolock scope 459 460 // Call back without lock held 461 if (listener != NULL) { 462 listener->onBufferReleased(); 463 } 464 465 return NO_ERROR; 466 } 467 468 status_t BufferQueueConsumer::connect( 469 const sp<IConsumerListener>& consumerListener, bool controlledByApp) { 470 ATRACE_CALL(); 471 472 if (consumerListener == NULL) { 473 BQ_LOGE("connect: consumerListener may not be NULL"); 474 return BAD_VALUE; 475 } 476 477 BQ_LOGV("connect: controlledByApp=%s", 478 controlledByApp ? "true" : "false"); 479 480 Mutex::Autolock lock(mCore->mMutex); 481 482 if (mCore->mIsAbandoned) { 483 BQ_LOGE("connect: BufferQueue has been abandoned"); 484 return NO_INIT; 485 } 486 487 mCore->mConsumerListener = consumerListener; 488 mCore->mConsumerControlledByApp = controlledByApp; 489 490 return NO_ERROR; 491 } 492 493 status_t BufferQueueConsumer::disconnect() { 494 ATRACE_CALL(); 495 496 BQ_LOGV("disconnect"); 497 498 Mutex::Autolock lock(mCore->mMutex); 499 500 if (mCore->mConsumerListener == NULL) { 501 BQ_LOGE("disconnect: no consumer is connected"); 502 return BAD_VALUE; 503 } 504 505 mCore->mIsAbandoned = true; 506 mCore->mConsumerListener = NULL; 507 mCore->mQueue.clear(); 508 mCore->freeAllBuffersLocked(); 509 mCore->mSharedBufferSlot = BufferQueueCore::INVALID_BUFFER_SLOT; 510 mCore->mDequeueCondition.broadcast(); 511 return NO_ERROR; 512 } 513 514 status_t BufferQueueConsumer::getReleasedBuffers(uint64_t *outSlotMask) { 515 ATRACE_CALL(); 516 517 if (outSlotMask == NULL) { 518 BQ_LOGE("getReleasedBuffers: outSlotMask may not be NULL"); 519 return BAD_VALUE; 520 } 521 522 Mutex::Autolock lock(mCore->mMutex); 523 524 if (mCore->mIsAbandoned) { 525 BQ_LOGE("getReleasedBuffers: BufferQueue has been abandoned"); 526 return NO_INIT; 527 } 528 529 uint64_t mask = 0; 530 for (int s = 0; s < BufferQueueDefs::NUM_BUFFER_SLOTS; ++s) { 531 if (!mSlots[s].mAcquireCalled) { 532 mask |= (1ULL << s); 533 } 534 } 535 536 // Remove from the mask queued buffers for which acquire has been called, 537 // since the consumer will not receive their buffer addresses and so must 538 // retain their cached information 539 BufferQueueCore::Fifo::iterator current(mCore->mQueue.begin()); 540 while (current != mCore->mQueue.end()) { 541 if (current->mAcquireCalled) { 542 mask &= ~(1ULL << current->mSlot); 543 } 544 ++current; 545 } 546 547 BQ_LOGV("getReleasedBuffers: returning mask %#" PRIx64, mask); 548 *outSlotMask = mask; 549 return NO_ERROR; 550 } 551 552 status_t BufferQueueConsumer::setDefaultBufferSize(uint32_t width, 553 uint32_t height) { 554 ATRACE_CALL(); 555 556 if (width == 0 || height == 0) { 557 BQ_LOGV("setDefaultBufferSize: dimensions cannot be 0 (width=%u " 558 "height=%u)", width, height); 559 return BAD_VALUE; 560 } 561 562 BQ_LOGV("setDefaultBufferSize: width=%u height=%u", width, height); 563 564 Mutex::Autolock lock(mCore->mMutex); 565 mCore->mDefaultWidth = width; 566 mCore->mDefaultHeight = height; 567 return NO_ERROR; 568 } 569 570 status_t BufferQueueConsumer::setMaxBufferCount(int bufferCount) { 571 ATRACE_CALL(); 572 573 if (bufferCount < 1 || bufferCount > BufferQueueDefs::NUM_BUFFER_SLOTS) { 574 BQ_LOGE("setMaxBufferCount: invalid count %d", bufferCount); 575 return BAD_VALUE; 576 } 577 578 Mutex::Autolock lock(mCore->mMutex); 579 580 if (mCore->mConnectedApi != BufferQueueCore::NO_CONNECTED_API) { 581 BQ_LOGE("setMaxBufferCount: producer is already connected"); 582 return INVALID_OPERATION; 583 } 584 585 if (bufferCount < mCore->mMaxAcquiredBufferCount) { 586 BQ_LOGE("setMaxBufferCount: invalid buffer count (%d) less than" 587 "mMaxAcquiredBufferCount (%d)", bufferCount, 588 mCore->mMaxAcquiredBufferCount); 589 return BAD_VALUE; 590 } 591 592 int delta = mCore->getMaxBufferCountLocked(mCore->mAsyncMode, 593 mCore->mDequeueBufferCannotBlock, bufferCount) - 594 mCore->getMaxBufferCountLocked(); 595 if (!mCore->adjustAvailableSlotsLocked(delta)) { 596 BQ_LOGE("setMaxBufferCount: BufferQueue failed to adjust the number of " 597 "available slots. Delta = %d", delta); 598 return BAD_VALUE; 599 } 600 601 mCore->mMaxBufferCount = bufferCount; 602 return NO_ERROR; 603 } 604 605 status_t BufferQueueConsumer::setMaxAcquiredBufferCount( 606 int maxAcquiredBuffers) { 607 ATRACE_CALL(); 608 609 if (maxAcquiredBuffers < 1 || 610 maxAcquiredBuffers > BufferQueueCore::MAX_MAX_ACQUIRED_BUFFERS) { 611 BQ_LOGE("setMaxAcquiredBufferCount: invalid count %d", 612 maxAcquiredBuffers); 613 return BAD_VALUE; 614 } 615 616 sp<IConsumerListener> listener; 617 { // Autolock scope 618 Mutex::Autolock lock(mCore->mMutex); 619 mCore->waitWhileAllocatingLocked(); 620 621 if (mCore->mIsAbandoned) { 622 BQ_LOGE("setMaxAcquiredBufferCount: consumer is abandoned"); 623 return NO_INIT; 624 } 625 626 if (maxAcquiredBuffers == mCore->mMaxAcquiredBufferCount) { 627 return NO_ERROR; 628 } 629 630 // The new maxAcquiredBuffers count should not be violated by the number 631 // of currently acquired buffers 632 int acquiredCount = 0; 633 for (int slot : mCore->mActiveBuffers) { 634 if (mSlots[slot].mBufferState.isAcquired()) { 635 acquiredCount++; 636 } 637 } 638 if (acquiredCount > maxAcquiredBuffers) { 639 BQ_LOGE("setMaxAcquiredBufferCount: the requested maxAcquiredBuffer" 640 "count (%d) exceeds the current acquired buffer count (%d)", 641 maxAcquiredBuffers, acquiredCount); 642 return BAD_VALUE; 643 } 644 645 if ((maxAcquiredBuffers + mCore->mMaxDequeuedBufferCount + 646 (mCore->mAsyncMode || mCore->mDequeueBufferCannotBlock ? 1 : 0)) 647 > mCore->mMaxBufferCount) { 648 BQ_LOGE("setMaxAcquiredBufferCount: %d acquired buffers would " 649 "exceed the maxBufferCount (%d) (maxDequeued %d async %d)", 650 maxAcquiredBuffers, mCore->mMaxBufferCount, 651 mCore->mMaxDequeuedBufferCount, mCore->mAsyncMode || 652 mCore->mDequeueBufferCannotBlock); 653 return BAD_VALUE; 654 } 655 656 int delta = maxAcquiredBuffers - mCore->mMaxAcquiredBufferCount; 657 if (!mCore->adjustAvailableSlotsLocked(delta)) { 658 return BAD_VALUE; 659 } 660 661 BQ_LOGV("setMaxAcquiredBufferCount: %d", maxAcquiredBuffers); 662 mCore->mMaxAcquiredBufferCount = maxAcquiredBuffers; 663 VALIDATE_CONSISTENCY(); 664 if (delta < 0) { 665 listener = mCore->mConsumerListener; 666 } 667 } 668 // Call back without lock held 669 if (listener != NULL) { 670 listener->onBuffersReleased(); 671 } 672 673 return NO_ERROR; 674 } 675 676 void BufferQueueConsumer::setConsumerName(const String8& name) { 677 ATRACE_CALL(); 678 BQ_LOGV("setConsumerName: '%s'", name.string()); 679 Mutex::Autolock lock(mCore->mMutex); 680 mCore->mConsumerName = name; 681 mConsumerName = name; 682 } 683 684 status_t BufferQueueConsumer::setDefaultBufferFormat(PixelFormat defaultFormat) { 685 ATRACE_CALL(); 686 BQ_LOGV("setDefaultBufferFormat: %u", defaultFormat); 687 Mutex::Autolock lock(mCore->mMutex); 688 mCore->mDefaultBufferFormat = defaultFormat; 689 return NO_ERROR; 690 } 691 692 status_t BufferQueueConsumer::setDefaultBufferDataSpace( 693 android_dataspace defaultDataSpace) { 694 ATRACE_CALL(); 695 BQ_LOGV("setDefaultBufferDataSpace: %u", defaultDataSpace); 696 Mutex::Autolock lock(mCore->mMutex); 697 mCore->mDefaultBufferDataSpace = defaultDataSpace; 698 return NO_ERROR; 699 } 700 701 status_t BufferQueueConsumer::setConsumerUsageBits(uint32_t usage) { 702 ATRACE_CALL(); 703 BQ_LOGV("setConsumerUsageBits: %#x", usage); 704 Mutex::Autolock lock(mCore->mMutex); 705 mCore->mConsumerUsageBits = usage; 706 return NO_ERROR; 707 } 708 709 status_t BufferQueueConsumer::setTransformHint(uint32_t hint) { 710 ATRACE_CALL(); 711 BQ_LOGV("setTransformHint: %#x", hint); 712 Mutex::Autolock lock(mCore->mMutex); 713 mCore->mTransformHint = hint; 714 return NO_ERROR; 715 } 716 717 sp<NativeHandle> BufferQueueConsumer::getSidebandStream() const { 718 return mCore->mSidebandStream; 719 } 720 721 status_t BufferQueueConsumer::getOccupancyHistory(bool forceFlush, 722 std::vector<OccupancyTracker::Segment>* outHistory) { 723 Mutex::Autolock lock(mCore->mMutex); 724 *outHistory = mCore->mOccupancyTracker.getSegmentHistory(forceFlush); 725 return NO_ERROR; 726 } 727 728 status_t BufferQueueConsumer::discardFreeBuffers() { 729 Mutex::Autolock lock(mCore->mMutex); 730 mCore->discardFreeBuffersLocked(); 731 return NO_ERROR; 732 } 733 734 void BufferQueueConsumer::dump(String8& result, const char* prefix) const { 735 const IPCThreadState* ipc = IPCThreadState::self(); 736 const pid_t pid = ipc->getCallingPid(); 737 const uid_t uid = ipc->getCallingUid(); 738 if ((uid != AID_SHELL) 739 && !PermissionCache::checkPermission(String16( 740 "android.permission.DUMP"), pid, uid)) { 741 result.appendFormat("Permission Denial: can't dump BufferQueueConsumer " 742 "from pid=%d, uid=%d\n", pid, uid); 743 android_errorWriteWithInfoLog(0x534e4554, "27046057", uid, NULL, 0); 744 } else { 745 mCore->dump(result, prefix); 746 } 747 } 748 749 } // namespace android 750