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->mFenceTime = FenceTime::NO_FENCE; 209 outBuffer->mCrop = mCore->mSharedBufferCache.crop; 210 outBuffer->mTransform = mCore->mSharedBufferCache.transform & 211 ~static_cast<uint32_t>( 212 NATIVE_WINDOW_TRANSFORM_INVERSE_DISPLAY); 213 outBuffer->mScalingMode = mCore->mSharedBufferCache.scalingMode; 214 outBuffer->mDataSpace = mCore->mSharedBufferCache.dataspace; 215 outBuffer->mFrameNumber = mCore->mFrameCounter; 216 outBuffer->mSlot = slot; 217 outBuffer->mAcquireCalled = mSlots[slot].mAcquireCalled; 218 outBuffer->mTransformToDisplayInverse = 219 (mCore->mSharedBufferCache.transform & 220 NATIVE_WINDOW_TRANSFORM_INVERSE_DISPLAY) != 0; 221 outBuffer->mSurfaceDamage = Region::INVALID_REGION; 222 outBuffer->mQueuedBuffer = false; 223 outBuffer->mIsStale = false; 224 outBuffer->mAutoRefresh = mCore->mSharedBufferMode && 225 mCore->mAutoRefresh; 226 } else { 227 slot = front->mSlot; 228 *outBuffer = *front; 229 } 230 231 ATRACE_BUFFER_INDEX(slot); 232 233 BQ_LOGV("acquireBuffer: acquiring { slot=%d/%" PRIu64 " buffer=%p }", 234 slot, outBuffer->mFrameNumber, outBuffer->mGraphicBuffer->handle); 235 236 if (!outBuffer->mIsStale) { 237 mSlots[slot].mAcquireCalled = true; 238 // Don't decrease the queue count if the BufferItem wasn't 239 // previously in the queue. This happens in shared buffer mode when 240 // the queue is empty and the BufferItem is created above. 241 if (mCore->mQueue.empty()) { 242 mSlots[slot].mBufferState.acquireNotInQueue(); 243 } else { 244 mSlots[slot].mBufferState.acquire(); 245 } 246 mSlots[slot].mFence = Fence::NO_FENCE; 247 } 248 249 // If the buffer has previously been acquired by the consumer, set 250 // mGraphicBuffer to NULL to avoid unnecessarily remapping this buffer 251 // on the consumer side 252 if (outBuffer->mAcquireCalled) { 253 outBuffer->mGraphicBuffer = NULL; 254 } 255 256 mCore->mQueue.erase(front); 257 258 // We might have freed a slot while dropping old buffers, or the producer 259 // may be blocked waiting for the number of buffers in the queue to 260 // decrease. 261 mCore->mDequeueCondition.broadcast(); 262 263 ATRACE_INT(mCore->mConsumerName.string(), 264 static_cast<int32_t>(mCore->mQueue.size())); 265 mCore->mOccupancyTracker.registerOccupancyChange(mCore->mQueue.size()); 266 267 VALIDATE_CONSISTENCY(); 268 } 269 270 if (listener != NULL) { 271 for (int i = 0; i < numDroppedBuffers; ++i) { 272 listener->onBufferReleased(); 273 } 274 } 275 276 return NO_ERROR; 277 } 278 279 status_t BufferQueueConsumer::detachBuffer(int slot) { 280 ATRACE_CALL(); 281 ATRACE_BUFFER_INDEX(slot); 282 BQ_LOGV("detachBuffer: slot %d", slot); 283 Mutex::Autolock lock(mCore->mMutex); 284 285 if (mCore->mIsAbandoned) { 286 BQ_LOGE("detachBuffer: BufferQueue has been abandoned"); 287 return NO_INIT; 288 } 289 290 if (mCore->mSharedBufferMode || slot == mCore->mSharedBufferSlot) { 291 BQ_LOGE("detachBuffer: detachBuffer not allowed in shared buffer mode"); 292 return BAD_VALUE; 293 } 294 295 if (slot < 0 || slot >= BufferQueueDefs::NUM_BUFFER_SLOTS) { 296 BQ_LOGE("detachBuffer: slot index %d out of range [0, %d)", 297 slot, BufferQueueDefs::NUM_BUFFER_SLOTS); 298 return BAD_VALUE; 299 } else if (!mSlots[slot].mBufferState.isAcquired()) { 300 BQ_LOGE("detachBuffer: slot %d is not owned by the consumer " 301 "(state = %s)", slot, mSlots[slot].mBufferState.string()); 302 return BAD_VALUE; 303 } 304 305 mSlots[slot].mBufferState.detachConsumer(); 306 mCore->mActiveBuffers.erase(slot); 307 mCore->mFreeSlots.insert(slot); 308 mCore->clearBufferSlotLocked(slot); 309 mCore->mDequeueCondition.broadcast(); 310 VALIDATE_CONSISTENCY(); 311 312 return NO_ERROR; 313 } 314 315 status_t BufferQueueConsumer::attachBuffer(int* outSlot, 316 const sp<android::GraphicBuffer>& buffer) { 317 ATRACE_CALL(); 318 319 if (outSlot == NULL) { 320 BQ_LOGE("attachBuffer: outSlot must not be NULL"); 321 return BAD_VALUE; 322 } else if (buffer == NULL) { 323 BQ_LOGE("attachBuffer: cannot attach NULL buffer"); 324 return BAD_VALUE; 325 } 326 327 Mutex::Autolock lock(mCore->mMutex); 328 329 if (mCore->mSharedBufferMode) { 330 BQ_LOGE("attachBuffer: cannot attach a buffer in shared buffer mode"); 331 return BAD_VALUE; 332 } 333 334 // Make sure we don't have too many acquired buffers 335 int numAcquiredBuffers = 0; 336 for (int s : mCore->mActiveBuffers) { 337 if (mSlots[s].mBufferState.isAcquired()) { 338 ++numAcquiredBuffers; 339 } 340 } 341 342 if (numAcquiredBuffers >= mCore->mMaxAcquiredBufferCount + 1) { 343 BQ_LOGE("attachBuffer: max acquired buffer count reached: %d " 344 "(max %d)", numAcquiredBuffers, 345 mCore->mMaxAcquiredBufferCount); 346 return INVALID_OPERATION; 347 } 348 349 if (buffer->getGenerationNumber() != mCore->mGenerationNumber) { 350 BQ_LOGE("attachBuffer: generation number mismatch [buffer %u] " 351 "[queue %u]", buffer->getGenerationNumber(), 352 mCore->mGenerationNumber); 353 return BAD_VALUE; 354 } 355 356 // Find a free slot to put the buffer into 357 int found = BufferQueueCore::INVALID_BUFFER_SLOT; 358 if (!mCore->mFreeSlots.empty()) { 359 auto slot = mCore->mFreeSlots.begin(); 360 found = *slot; 361 mCore->mFreeSlots.erase(slot); 362 } else if (!mCore->mFreeBuffers.empty()) { 363 found = mCore->mFreeBuffers.front(); 364 mCore->mFreeBuffers.remove(found); 365 } 366 if (found == BufferQueueCore::INVALID_BUFFER_SLOT) { 367 BQ_LOGE("attachBuffer: could not find free buffer slot"); 368 return NO_MEMORY; 369 } 370 371 mCore->mActiveBuffers.insert(found); 372 *outSlot = found; 373 ATRACE_BUFFER_INDEX(*outSlot); 374 BQ_LOGV("attachBuffer: returning slot %d", *outSlot); 375 376 mSlots[*outSlot].mGraphicBuffer = buffer; 377 mSlots[*outSlot].mBufferState.attachConsumer(); 378 mSlots[*outSlot].mNeedsReallocation = true; 379 mSlots[*outSlot].mFence = Fence::NO_FENCE; 380 mSlots[*outSlot].mFrameNumber = 0; 381 382 // mAcquireCalled tells BufferQueue that it doesn't need to send a valid 383 // GraphicBuffer pointer on the next acquireBuffer call, which decreases 384 // Binder traffic by not un/flattening the GraphicBuffer. However, it 385 // requires that the consumer maintain a cached copy of the slot <--> buffer 386 // mappings, which is why the consumer doesn't need the valid pointer on 387 // acquire. 388 // 389 // The StreamSplitter is one of the primary users of the attach/detach 390 // logic, and while it is running, all buffers it acquires are immediately 391 // detached, and all buffers it eventually releases are ones that were 392 // attached (as opposed to having been obtained from acquireBuffer), so it 393 // doesn't make sense to maintain the slot/buffer mappings, which would 394 // become invalid for every buffer during detach/attach. By setting this to 395 // false, the valid GraphicBuffer pointer will always be sent with acquire 396 // for attached buffers. 397 mSlots[*outSlot].mAcquireCalled = false; 398 399 VALIDATE_CONSISTENCY(); 400 401 return NO_ERROR; 402 } 403 404 status_t BufferQueueConsumer::releaseBuffer(int slot, uint64_t frameNumber, 405 const sp<Fence>& releaseFence, EGLDisplay eglDisplay, 406 EGLSyncKHR eglFence) { 407 ATRACE_CALL(); 408 ATRACE_BUFFER_INDEX(slot); 409 410 if (slot < 0 || slot >= BufferQueueDefs::NUM_BUFFER_SLOTS || 411 releaseFence == NULL) { 412 BQ_LOGE("releaseBuffer: slot %d out of range or fence %p NULL", slot, 413 releaseFence.get()); 414 return BAD_VALUE; 415 } 416 417 sp<IProducerListener> listener; 418 { // Autolock scope 419 Mutex::Autolock lock(mCore->mMutex); 420 421 // If the frame number has changed because the buffer has been reallocated, 422 // we can ignore this releaseBuffer for the old buffer. 423 // Ignore this for the shared buffer where the frame number can easily 424 // get out of sync due to the buffer being queued and acquired at the 425 // same time. 426 if (frameNumber != mSlots[slot].mFrameNumber && 427 !mSlots[slot].mBufferState.isShared()) { 428 return STALE_BUFFER_SLOT; 429 } 430 431 if (!mSlots[slot].mBufferState.isAcquired()) { 432 BQ_LOGE("releaseBuffer: attempted to release buffer slot %d " 433 "but its state was %s", slot, 434 mSlots[slot].mBufferState.string()); 435 return BAD_VALUE; 436 } 437 438 mSlots[slot].mEglDisplay = eglDisplay; 439 mSlots[slot].mEglFence = eglFence; 440 mSlots[slot].mFence = releaseFence; 441 mSlots[slot].mBufferState.release(); 442 443 // After leaving shared buffer mode, the shared buffer will 444 // still be around. Mark it as no longer shared if this 445 // operation causes it to be free. 446 if (!mCore->mSharedBufferMode && mSlots[slot].mBufferState.isFree()) { 447 mSlots[slot].mBufferState.mShared = false; 448 } 449 // Don't put the shared buffer on the free list. 450 if (!mSlots[slot].mBufferState.isShared()) { 451 mCore->mActiveBuffers.erase(slot); 452 mCore->mFreeBuffers.push_back(slot); 453 } 454 455 listener = mCore->mConnectedProducerListener; 456 BQ_LOGV("releaseBuffer: releasing slot %d", slot); 457 458 mCore->mDequeueCondition.broadcast(); 459 VALIDATE_CONSISTENCY(); 460 } // Autolock scope 461 462 // Call back without lock held 463 if (listener != NULL) { 464 listener->onBufferReleased(); 465 } 466 467 return NO_ERROR; 468 } 469 470 status_t BufferQueueConsumer::connect( 471 const sp<IConsumerListener>& consumerListener, bool controlledByApp) { 472 ATRACE_CALL(); 473 474 if (consumerListener == NULL) { 475 BQ_LOGE("connect: consumerListener may not be NULL"); 476 return BAD_VALUE; 477 } 478 479 BQ_LOGV("connect: controlledByApp=%s", 480 controlledByApp ? "true" : "false"); 481 482 Mutex::Autolock lock(mCore->mMutex); 483 484 if (mCore->mIsAbandoned) { 485 BQ_LOGE("connect: BufferQueue has been abandoned"); 486 return NO_INIT; 487 } 488 489 mCore->mConsumerListener = consumerListener; 490 mCore->mConsumerControlledByApp = controlledByApp; 491 492 return NO_ERROR; 493 } 494 495 status_t BufferQueueConsumer::disconnect() { 496 ATRACE_CALL(); 497 498 BQ_LOGV("disconnect"); 499 500 Mutex::Autolock lock(mCore->mMutex); 501 502 if (mCore->mConsumerListener == NULL) { 503 BQ_LOGE("disconnect: no consumer is connected"); 504 return BAD_VALUE; 505 } 506 507 mCore->mIsAbandoned = true; 508 mCore->mConsumerListener = NULL; 509 mCore->mQueue.clear(); 510 mCore->freeAllBuffersLocked(); 511 mCore->mSharedBufferSlot = BufferQueueCore::INVALID_BUFFER_SLOT; 512 mCore->mDequeueCondition.broadcast(); 513 return NO_ERROR; 514 } 515 516 status_t BufferQueueConsumer::getReleasedBuffers(uint64_t *outSlotMask) { 517 ATRACE_CALL(); 518 519 if (outSlotMask == NULL) { 520 BQ_LOGE("getReleasedBuffers: outSlotMask may not be NULL"); 521 return BAD_VALUE; 522 } 523 524 Mutex::Autolock lock(mCore->mMutex); 525 526 if (mCore->mIsAbandoned) { 527 BQ_LOGE("getReleasedBuffers: BufferQueue has been abandoned"); 528 return NO_INIT; 529 } 530 531 uint64_t mask = 0; 532 for (int s = 0; s < BufferQueueDefs::NUM_BUFFER_SLOTS; ++s) { 533 if (!mSlots[s].mAcquireCalled) { 534 mask |= (1ULL << s); 535 } 536 } 537 538 // Remove from the mask queued buffers for which acquire has been called, 539 // since the consumer will not receive their buffer addresses and so must 540 // retain their cached information 541 BufferQueueCore::Fifo::iterator current(mCore->mQueue.begin()); 542 while (current != mCore->mQueue.end()) { 543 if (current->mAcquireCalled) { 544 mask &= ~(1ULL << current->mSlot); 545 } 546 ++current; 547 } 548 549 BQ_LOGV("getReleasedBuffers: returning mask %#" PRIx64, mask); 550 *outSlotMask = mask; 551 return NO_ERROR; 552 } 553 554 status_t BufferQueueConsumer::setDefaultBufferSize(uint32_t width, 555 uint32_t height) { 556 ATRACE_CALL(); 557 558 if (width == 0 || height == 0) { 559 BQ_LOGV("setDefaultBufferSize: dimensions cannot be 0 (width=%u " 560 "height=%u)", width, height); 561 return BAD_VALUE; 562 } 563 564 BQ_LOGV("setDefaultBufferSize: width=%u height=%u", width, height); 565 566 Mutex::Autolock lock(mCore->mMutex); 567 mCore->mDefaultWidth = width; 568 mCore->mDefaultHeight = height; 569 return NO_ERROR; 570 } 571 572 status_t BufferQueueConsumer::setMaxBufferCount(int bufferCount) { 573 ATRACE_CALL(); 574 575 if (bufferCount < 1 || bufferCount > BufferQueueDefs::NUM_BUFFER_SLOTS) { 576 BQ_LOGE("setMaxBufferCount: invalid count %d", bufferCount); 577 return BAD_VALUE; 578 } 579 580 Mutex::Autolock lock(mCore->mMutex); 581 582 if (mCore->mConnectedApi != BufferQueueCore::NO_CONNECTED_API) { 583 BQ_LOGE("setMaxBufferCount: producer is already connected"); 584 return INVALID_OPERATION; 585 } 586 587 if (bufferCount < mCore->mMaxAcquiredBufferCount) { 588 BQ_LOGE("setMaxBufferCount: invalid buffer count (%d) less than" 589 "mMaxAcquiredBufferCount (%d)", bufferCount, 590 mCore->mMaxAcquiredBufferCount); 591 return BAD_VALUE; 592 } 593 594 int delta = mCore->getMaxBufferCountLocked(mCore->mAsyncMode, 595 mCore->mDequeueBufferCannotBlock, bufferCount) - 596 mCore->getMaxBufferCountLocked(); 597 if (!mCore->adjustAvailableSlotsLocked(delta)) { 598 BQ_LOGE("setMaxBufferCount: BufferQueue failed to adjust the number of " 599 "available slots. Delta = %d", delta); 600 return BAD_VALUE; 601 } 602 603 mCore->mMaxBufferCount = bufferCount; 604 return NO_ERROR; 605 } 606 607 status_t BufferQueueConsumer::setMaxAcquiredBufferCount( 608 int maxAcquiredBuffers) { 609 ATRACE_CALL(); 610 611 if (maxAcquiredBuffers < 1 || 612 maxAcquiredBuffers > BufferQueueCore::MAX_MAX_ACQUIRED_BUFFERS) { 613 BQ_LOGE("setMaxAcquiredBufferCount: invalid count %d", 614 maxAcquiredBuffers); 615 return BAD_VALUE; 616 } 617 618 sp<IConsumerListener> listener; 619 { // Autolock scope 620 Mutex::Autolock lock(mCore->mMutex); 621 mCore->waitWhileAllocatingLocked(); 622 623 if (mCore->mIsAbandoned) { 624 BQ_LOGE("setMaxAcquiredBufferCount: consumer is abandoned"); 625 return NO_INIT; 626 } 627 628 if (maxAcquiredBuffers == mCore->mMaxAcquiredBufferCount) { 629 return NO_ERROR; 630 } 631 632 // The new maxAcquiredBuffers count should not be violated by the number 633 // of currently acquired buffers 634 int acquiredCount = 0; 635 for (int slot : mCore->mActiveBuffers) { 636 if (mSlots[slot].mBufferState.isAcquired()) { 637 acquiredCount++; 638 } 639 } 640 if (acquiredCount > maxAcquiredBuffers) { 641 BQ_LOGE("setMaxAcquiredBufferCount: the requested maxAcquiredBuffer" 642 "count (%d) exceeds the current acquired buffer count (%d)", 643 maxAcquiredBuffers, acquiredCount); 644 return BAD_VALUE; 645 } 646 647 if ((maxAcquiredBuffers + mCore->mMaxDequeuedBufferCount + 648 (mCore->mAsyncMode || mCore->mDequeueBufferCannotBlock ? 1 : 0)) 649 > mCore->mMaxBufferCount) { 650 BQ_LOGE("setMaxAcquiredBufferCount: %d acquired buffers would " 651 "exceed the maxBufferCount (%d) (maxDequeued %d async %d)", 652 maxAcquiredBuffers, mCore->mMaxBufferCount, 653 mCore->mMaxDequeuedBufferCount, mCore->mAsyncMode || 654 mCore->mDequeueBufferCannotBlock); 655 return BAD_VALUE; 656 } 657 658 int delta = maxAcquiredBuffers - mCore->mMaxAcquiredBufferCount; 659 if (!mCore->adjustAvailableSlotsLocked(delta)) { 660 return BAD_VALUE; 661 } 662 663 BQ_LOGV("setMaxAcquiredBufferCount: %d", maxAcquiredBuffers); 664 mCore->mMaxAcquiredBufferCount = maxAcquiredBuffers; 665 VALIDATE_CONSISTENCY(); 666 if (delta < 0) { 667 listener = mCore->mConsumerListener; 668 } 669 } 670 // Call back without lock held 671 if (listener != NULL) { 672 listener->onBuffersReleased(); 673 } 674 675 return NO_ERROR; 676 } 677 678 status_t BufferQueueConsumer::setConsumerName(const String8& name) { 679 ATRACE_CALL(); 680 BQ_LOGV("setConsumerName: '%s'", name.string()); 681 Mutex::Autolock lock(mCore->mMutex); 682 mCore->mConsumerName = name; 683 mConsumerName = name; 684 return NO_ERROR; 685 } 686 687 status_t BufferQueueConsumer::setDefaultBufferFormat(PixelFormat defaultFormat) { 688 ATRACE_CALL(); 689 BQ_LOGV("setDefaultBufferFormat: %u", defaultFormat); 690 Mutex::Autolock lock(mCore->mMutex); 691 mCore->mDefaultBufferFormat = defaultFormat; 692 return NO_ERROR; 693 } 694 695 status_t BufferQueueConsumer::setDefaultBufferDataSpace( 696 android_dataspace defaultDataSpace) { 697 ATRACE_CALL(); 698 BQ_LOGV("setDefaultBufferDataSpace: %u", defaultDataSpace); 699 Mutex::Autolock lock(mCore->mMutex); 700 mCore->mDefaultBufferDataSpace = defaultDataSpace; 701 return NO_ERROR; 702 } 703 704 status_t BufferQueueConsumer::setConsumerUsageBits(uint32_t usage) { 705 ATRACE_CALL(); 706 BQ_LOGV("setConsumerUsageBits: %#x", usage); 707 Mutex::Autolock lock(mCore->mMutex); 708 mCore->mConsumerUsageBits = usage; 709 return NO_ERROR; 710 } 711 712 status_t BufferQueueConsumer::setConsumerIsProtected(bool isProtected) { 713 ATRACE_CALL(); 714 BQ_LOGV("setConsumerIsProtected: %s", isProtected ? "true" : "false"); 715 Mutex::Autolock lock(mCore->mMutex); 716 mCore->mConsumerIsProtected = isProtected; 717 return NO_ERROR; 718 } 719 720 status_t BufferQueueConsumer::setTransformHint(uint32_t hint) { 721 ATRACE_CALL(); 722 BQ_LOGV("setTransformHint: %#x", hint); 723 Mutex::Autolock lock(mCore->mMutex); 724 mCore->mTransformHint = hint; 725 return NO_ERROR; 726 } 727 728 status_t BufferQueueConsumer::getSidebandStream(sp<NativeHandle>* outStream) const { 729 Mutex::Autolock lock(mCore->mMutex); 730 *outStream = mCore->mSidebandStream; 731 return NO_ERROR; 732 } 733 734 status_t BufferQueueConsumer::getOccupancyHistory(bool forceFlush, 735 std::vector<OccupancyTracker::Segment>* outHistory) { 736 Mutex::Autolock lock(mCore->mMutex); 737 *outHistory = mCore->mOccupancyTracker.getSegmentHistory(forceFlush); 738 return NO_ERROR; 739 } 740 741 status_t BufferQueueConsumer::discardFreeBuffers() { 742 Mutex::Autolock lock(mCore->mMutex); 743 mCore->discardFreeBuffersLocked(); 744 return NO_ERROR; 745 } 746 747 status_t BufferQueueConsumer::dumpState(const String8& prefix, String8* outResult) const { 748 const IPCThreadState* ipc = IPCThreadState::self(); 749 const pid_t pid = ipc->getCallingPid(); 750 const uid_t uid = ipc->getCallingUid(); 751 if ((uid != AID_SHELL) 752 && !PermissionCache::checkPermission(String16( 753 "android.permission.DUMP"), pid, uid)) { 754 outResult->appendFormat("Permission Denial: can't dump BufferQueueConsumer " 755 "from pid=%d, uid=%d\n", pid, uid); 756 android_errorWriteWithInfoLog(0x534e4554, "27046057", 757 static_cast<int32_t>(uid), NULL, 0); 758 return PERMISSION_DENIED; 759 } 760 761 mCore->dumpState(prefix, outResult); 762 return NO_ERROR; 763 } 764 765 } // namespace android 766