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