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