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