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 <binder/IPCThreadState.h> 38 #ifndef __ANDROID_VNDK__ 39 #include <binder/PermissionCache.h> 40 #endif 41 42 #include <system/window.h> 43 44 namespace android { 45 46 BufferQueueConsumer::BufferQueueConsumer(const sp<BufferQueueCore>& core) : 47 mCore(core), 48 mSlots(core->mSlots), 49 mConsumerName() {} 50 51 BufferQueueConsumer::~BufferQueueConsumer() {} 52 53 status_t BufferQueueConsumer::acquireBuffer(BufferItem* outBuffer, 54 nsecs_t expectedPresent, uint64_t maxFrameNumber) { 55 ATRACE_CALL(); 56 57 int numDroppedBuffers = 0; 58 sp<IProducerListener> listener; 59 { 60 Mutex::Autolock lock(mCore->mMutex); 61 62 // Check that the consumer doesn't currently have the maximum number of 63 // buffers acquired. We allow the max buffer count to be exceeded by one 64 // buffer so that the consumer can successfully set up the newly acquired 65 // buffer before releasing the old one. 66 int numAcquiredBuffers = 0; 67 for (int s : mCore->mActiveBuffers) { 68 if (mSlots[s].mBufferState.isAcquired()) { 69 ++numAcquiredBuffers; 70 } 71 } 72 if (numAcquiredBuffers >= mCore->mMaxAcquiredBufferCount + 1) { 73 BQ_LOGE("acquireBuffer: max acquired buffer count reached: %d (max %d)", 74 numAcquiredBuffers, mCore->mMaxAcquiredBufferCount); 75 return INVALID_OPERATION; 76 } 77 78 bool sharedBufferAvailable = mCore->mSharedBufferMode && 79 mCore->mAutoRefresh && mCore->mSharedBufferSlot != 80 BufferQueueCore::INVALID_BUFFER_SLOT; 81 82 // In asynchronous mode the list is guaranteed to be one buffer deep, 83 // while in synchronous mode we use the oldest buffer. 84 if (mCore->mQueue.empty() && !sharedBufferAvailable) { 85 return NO_BUFFER_AVAILABLE; 86 } 87 88 BufferQueueCore::Fifo::iterator front(mCore->mQueue.begin()); 89 90 // If expectedPresent is specified, we may not want to return a buffer yet. 91 // If it's specified and there's more than one buffer queued, we may want 92 // to drop a buffer. 93 // Skip this if we're in shared buffer mode and the queue is empty, 94 // since in that case we'll just return the shared buffer. 95 if (expectedPresent != 0 && !mCore->mQueue.empty()) { 96 const int MAX_REASONABLE_NSEC = 1000000000ULL; // 1 second 97 98 // The 'expectedPresent' argument indicates when the buffer is expected 99 // to be presented on-screen. If the buffer's desired present time is 100 // earlier (less) than expectedPresent -- meaning it will be displayed 101 // on time or possibly late if we show it as soon as possible -- we 102 // acquire and return it. If we don't want to display it until after the 103 // expectedPresent time, we return PRESENT_LATER without acquiring it. 104 // 105 // To be safe, we don't defer acquisition if expectedPresent is more 106 // than one second in the future beyond the desired present time 107 // (i.e., we'd be holding the buffer for a long time). 108 // 109 // NOTE: Code assumes monotonic time values from the system clock 110 // are positive. 111 112 // Start by checking to see if we can drop frames. We skip this check if 113 // the timestamps are being auto-generated by Surface. If the app isn't 114 // generating timestamps explicitly, it probably doesn't want frames to 115 // be discarded based on them. 116 while (mCore->mQueue.size() > 1 && !mCore->mQueue[0].mIsAutoTimestamp) { 117 const BufferItem& bufferItem(mCore->mQueue[1]); 118 119 // If dropping entry[0] would leave us with a buffer that the 120 // consumer is not yet ready for, don't drop it. 121 if (maxFrameNumber && bufferItem.mFrameNumber > maxFrameNumber) { 122 break; 123 } 124 125 // If entry[1] is timely, drop entry[0] (and repeat). We apply an 126 // additional criterion here: we only drop the earlier buffer if our 127 // desiredPresent falls within +/- 1 second of the expected present. 128 // Otherwise, bogus desiredPresent times (e.g., 0 or a small 129 // relative timestamp), which normally mean "ignore the timestamp 130 // and acquire immediately", would cause us to drop frames. 131 // 132 // We may want to add an additional criterion: don't drop the 133 // earlier buffer if entry[1]'s fence hasn't signaled yet. 134 nsecs_t desiredPresent = bufferItem.mTimestamp; 135 if (desiredPresent < expectedPresent - MAX_REASONABLE_NSEC || 136 desiredPresent > expectedPresent) { 137 // This buffer is set to display in the near future, or 138 // desiredPresent is garbage. Either way we don't want to drop 139 // the previous buffer just to get this on the screen sooner. 140 BQ_LOGV("acquireBuffer: nodrop desire=%" PRId64 " expect=%" 141 PRId64 " (%" PRId64 ") now=%" PRId64, 142 desiredPresent, expectedPresent, 143 desiredPresent - expectedPresent, 144 systemTime(CLOCK_MONOTONIC)); 145 break; 146 } 147 148 BQ_LOGV("acquireBuffer: drop desire=%" PRId64 " expect=%" PRId64 149 " size=%zu", 150 desiredPresent, expectedPresent, mCore->mQueue.size()); 151 152 if (!front->mIsStale) { 153 // Front buffer is still in mSlots, so mark the slot as free 154 mSlots[front->mSlot].mBufferState.freeQueued(); 155 156 // After leaving shared buffer mode, the shared buffer will 157 // still be around. Mark it as no longer shared if this 158 // operation causes it to be free. 159 if (!mCore->mSharedBufferMode && 160 mSlots[front->mSlot].mBufferState.isFree()) { 161 mSlots[front->mSlot].mBufferState.mShared = false; 162 } 163 164 // Don't put the shared buffer on the free list 165 if (!mSlots[front->mSlot].mBufferState.isShared()) { 166 mCore->mActiveBuffers.erase(front->mSlot); 167 mCore->mFreeBuffers.push_back(front->mSlot); 168 } 169 170 listener = mCore->mConnectedProducerListener; 171 ++numDroppedBuffers; 172 } 173 174 mCore->mQueue.erase(front); 175 front = mCore->mQueue.begin(); 176 } 177 178 // See if the front buffer is ready to be acquired 179 nsecs_t desiredPresent = front->mTimestamp; 180 bool bufferIsDue = desiredPresent <= expectedPresent || 181 desiredPresent > expectedPresent + MAX_REASONABLE_NSEC; 182 bool consumerIsReady = maxFrameNumber > 0 ? 183 front->mFrameNumber <= maxFrameNumber : true; 184 if (!bufferIsDue || !consumerIsReady) { 185 BQ_LOGV("acquireBuffer: defer desire=%" PRId64 " expect=%" PRId64 186 " (%" PRId64 ") now=%" PRId64 " frame=%" PRIu64 187 " consumer=%" PRIu64, 188 desiredPresent, expectedPresent, 189 desiredPresent - expectedPresent, 190 systemTime(CLOCK_MONOTONIC), 191 front->mFrameNumber, maxFrameNumber); 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(); 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 = NULL; 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.broadcast(); 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 != NULL) { 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 Mutex::Autolock 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.broadcast(); 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 == NULL) { 325 BQ_LOGE("attachBuffer: outSlot must not be NULL"); 326 return BAD_VALUE; 327 } else if (buffer == NULL) { 328 BQ_LOGE("attachBuffer: cannot attach NULL buffer"); 329 return BAD_VALUE; 330 } 331 332 Mutex::Autolock 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 == NULL) { 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 Mutex::Autolock 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.broadcast(); 464 VALIDATE_CONSISTENCY(); 465 } // Autolock scope 466 467 // Call back without lock held 468 if (listener != NULL) { 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 == NULL) { 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 Mutex::Autolock 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 Mutex::Autolock lock(mCore->mMutex); 506 507 if (mCore->mConsumerListener == NULL) { 508 BQ_LOGE("disconnect: no consumer is connected"); 509 return BAD_VALUE; 510 } 511 512 mCore->mIsAbandoned = true; 513 mCore->mConsumerListener = NULL; 514 mCore->mQueue.clear(); 515 mCore->freeAllBuffersLocked(); 516 mCore->mSharedBufferSlot = BufferQueueCore::INVALID_BUFFER_SLOT; 517 mCore->mDequeueCondition.broadcast(); 518 return NO_ERROR; 519 } 520 521 status_t BufferQueueConsumer::getReleasedBuffers(uint64_t *outSlotMask) { 522 ATRACE_CALL(); 523 524 if (outSlotMask == NULL) { 525 BQ_LOGE("getReleasedBuffers: outSlotMask may not be NULL"); 526 return BAD_VALUE; 527 } 528 529 Mutex::Autolock 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 Mutex::Autolock 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 Mutex::Autolock 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 Mutex::Autolock lock(mCore->mMutex); 626 mCore->waitWhileAllocatingLocked(); 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 != NULL) { 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 Mutex::Autolock 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 Mutex::Autolock 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 Mutex::Autolock 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 Mutex::Autolock 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 Mutex::Autolock 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 Mutex::Autolock lock(mCore->mMutex); 729 mCore->mTransformHint = hint; 730 return NO_ERROR; 731 } 732 733 status_t BufferQueueConsumer::getSidebandStream(sp<NativeHandle>* outStream) const { 734 Mutex::Autolock 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 Mutex::Autolock lock(mCore->mMutex); 742 *outHistory = mCore->mOccupancyTracker.getSegmentHistory(forceFlush); 743 return NO_ERROR; 744 } 745 746 status_t BufferQueueConsumer::discardFreeBuffers() { 747 Mutex::Autolock 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 const IPCThreadState* ipc = IPCThreadState::self(); 762 const uid_t uid = ipc->getCallingUid(); 763 #ifndef __ANDROID_VNDK__ 764 // permission check can't be done for vendors as vendors have no access to 765 // the PermissionController 766 const pid_t pid = ipc->getCallingPid(); 767 if ((uid != shellUid) && 768 !PermissionCache::checkPermission(String16("android.permission.DUMP"), pid, uid)) { 769 outResult->appendFormat("Permission Denial: can't dump BufferQueueConsumer " 770 "from pid=%d, uid=%d\n", pid, uid); 771 #else 772 if (uid != shellUid) { 773 #endif 774 android_errorWriteWithInfoLog(0x534e4554, "27046057", 775 static_cast<int32_t>(uid), NULL, 0); 776 return PERMISSION_DENIED; 777 } 778 779 mCore->dumpState(prefix, outResult); 780 return NO_ERROR; 781 } 782 783 } // namespace android 784