BufferQueueProducer.cpp revision 107fbe5599016b0e35145a1a00c4f238b63d61e4
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 "BufferQueueProducer" 20#define ATRACE_TAG ATRACE_TAG_GRAPHICS 21//#define LOG_NDEBUG 0 22 23#define EGL_EGLEXT_PROTOTYPES 24 25#include <gui/BufferItem.h> 26#include <gui/BufferQueueCore.h> 27#include <gui/BufferQueueProducer.h> 28#include <gui/IConsumerListener.h> 29#include <gui/IGraphicBufferAlloc.h> 30#include <gui/IProducerListener.h> 31 32#include <utils/Log.h> 33#include <utils/Trace.h> 34 35namespace android { 36 37BufferQueueProducer::BufferQueueProducer(const sp<BufferQueueCore>& core) : 38 mCore(core), 39 mSlots(core->mSlots), 40 mConsumerName(), 41 mStickyTransform(0), 42 mLastQueueBufferFence(Fence::NO_FENCE), 43 mCallbackMutex(), 44 mNextCallbackTicket(0), 45 mCurrentCallbackTicket(0), 46 mCallbackCondition() {} 47 48BufferQueueProducer::~BufferQueueProducer() {} 49 50status_t BufferQueueProducer::requestBuffer(int slot, sp<GraphicBuffer>* buf) { 51 ATRACE_CALL(); 52 BQ_LOGV("requestBuffer: slot %d", slot); 53 Mutex::Autolock lock(mCore->mMutex); 54 55 if (mCore->mIsAbandoned) { 56 BQ_LOGE("requestBuffer: BufferQueue has been abandoned"); 57 return NO_INIT; 58 } 59 60 if (slot < 0 || slot >= BufferQueueDefs::NUM_BUFFER_SLOTS) { 61 BQ_LOGE("requestBuffer: slot index %d out of range [0, %d)", 62 slot, BufferQueueDefs::NUM_BUFFER_SLOTS); 63 return BAD_VALUE; 64 } else if (mSlots[slot].mBufferState != BufferSlot::DEQUEUED) { 65 BQ_LOGE("requestBuffer: slot %d is not owned by the producer " 66 "(state = %d)", slot, mSlots[slot].mBufferState); 67 return BAD_VALUE; 68 } 69 70 mSlots[slot].mRequestBufferCalled = true; 71 *buf = mSlots[slot].mGraphicBuffer; 72 return NO_ERROR; 73} 74 75status_t BufferQueueProducer::setBufferCount(int bufferCount) { 76 ATRACE_CALL(); 77 BQ_LOGV("setBufferCount: count = %d", bufferCount); 78 79 sp<IConsumerListener> listener; 80 { // Autolock scope 81 Mutex::Autolock lock(mCore->mMutex); 82 mCore->waitWhileAllocatingLocked(); 83 84 if (mCore->mIsAbandoned) { 85 BQ_LOGE("setBufferCount: BufferQueue has been abandoned"); 86 return NO_INIT; 87 } 88 89 if (bufferCount > BufferQueueDefs::NUM_BUFFER_SLOTS) { 90 BQ_LOGE("setBufferCount: bufferCount %d too large (max %d)", 91 bufferCount, BufferQueueDefs::NUM_BUFFER_SLOTS); 92 return BAD_VALUE; 93 } 94 95 // There must be no dequeued buffers when changing the buffer count. 96 for (int s = 0; s < BufferQueueDefs::NUM_BUFFER_SLOTS; ++s) { 97 if (mSlots[s].mBufferState == BufferSlot::DEQUEUED) { 98 BQ_LOGE("setBufferCount: buffer owned by producer"); 99 return BAD_VALUE; 100 } 101 } 102 103 if (bufferCount == 0) { 104 mCore->mOverrideMaxBufferCount = 0; 105 mCore->mDequeueCondition.broadcast(); 106 return NO_ERROR; 107 } 108 109 const int minBufferSlots = mCore->getMinMaxBufferCountLocked(false); 110 if (bufferCount < minBufferSlots) { 111 BQ_LOGE("setBufferCount: requested buffer count %d is less than " 112 "minimum %d", bufferCount, minBufferSlots); 113 return BAD_VALUE; 114 } 115 116 // Here we are guaranteed that the producer doesn't have any dequeued 117 // buffers and will release all of its buffer references. We don't 118 // clear the queue, however, so that currently queued buffers still 119 // get displayed. 120 mCore->freeAllBuffersLocked(); 121 mCore->mOverrideMaxBufferCount = bufferCount; 122 mCore->mDequeueCondition.broadcast(); 123 listener = mCore->mConsumerListener; 124 } // Autolock scope 125 126 // Call back without lock held 127 if (listener != NULL) { 128 listener->onBuffersReleased(); 129 } 130 131 return NO_ERROR; 132} 133 134status_t BufferQueueProducer::waitForFreeSlotThenRelock(const char* caller, 135 bool async, int* found, status_t* returnFlags) const { 136 bool tryAgain = true; 137 while (tryAgain) { 138 if (mCore->mIsAbandoned) { 139 BQ_LOGE("%s: BufferQueue has been abandoned", caller); 140 return NO_INIT; 141 } 142 143 const int maxBufferCount = mCore->getMaxBufferCountLocked(async); 144 if (async && mCore->mOverrideMaxBufferCount) { 145 // FIXME: Some drivers are manually setting the buffer count 146 // (which they shouldn't), so we do this extra test here to 147 // handle that case. This is TEMPORARY until we get this fixed. 148 if (mCore->mOverrideMaxBufferCount < maxBufferCount) { 149 BQ_LOGE("%s: async mode is invalid with buffer count override", 150 caller); 151 return BAD_VALUE; 152 } 153 } 154 155 // Free up any buffers that are in slots beyond the max buffer count 156 for (int s = maxBufferCount; s < BufferQueueDefs::NUM_BUFFER_SLOTS; ++s) { 157 assert(mSlots[s].mBufferState == BufferSlot::FREE); 158 if (mSlots[s].mGraphicBuffer != NULL) { 159 mCore->freeBufferLocked(s); 160 *returnFlags |= RELEASE_ALL_BUFFERS; 161 } 162 } 163 164 int dequeuedCount = 0; 165 int acquiredCount = 0; 166 for (int s = 0; s < maxBufferCount; ++s) { 167 switch (mSlots[s].mBufferState) { 168 case BufferSlot::DEQUEUED: 169 ++dequeuedCount; 170 break; 171 case BufferSlot::ACQUIRED: 172 ++acquiredCount; 173 break; 174 default: 175 break; 176 } 177 } 178 179 // Producers are not allowed to dequeue more than one buffer if they 180 // did not set a buffer count 181 if (!mCore->mOverrideMaxBufferCount && dequeuedCount) { 182 BQ_LOGE("%s: can't dequeue multiple buffers without setting the " 183 "buffer count", caller); 184 return INVALID_OPERATION; 185 } 186 187 // See whether a buffer has been queued since the last 188 // setBufferCount so we know whether to perform the min undequeued 189 // buffers check below 190 if (mCore->mBufferHasBeenQueued) { 191 // Make sure the producer is not trying to dequeue more buffers 192 // than allowed 193 const int newUndequeuedCount = 194 maxBufferCount - (dequeuedCount + 1); 195 const int minUndequeuedCount = 196 mCore->getMinUndequeuedBufferCountLocked(async); 197 if (newUndequeuedCount < minUndequeuedCount) { 198 BQ_LOGE("%s: min undequeued buffer count (%d) exceeded " 199 "(dequeued=%d undequeued=%d)", 200 caller, minUndequeuedCount, 201 dequeuedCount, newUndequeuedCount); 202 return INVALID_OPERATION; 203 } 204 } 205 206 *found = BufferQueueCore::INVALID_BUFFER_SLOT; 207 208 // If we disconnect and reconnect quickly, we can be in a state where 209 // our slots are empty but we have many buffers in the queue. This can 210 // cause us to run out of memory if we outrun the consumer. Wait here if 211 // it looks like we have too many buffers queued up. 212 bool tooManyBuffers = mCore->mQueue.size() 213 > static_cast<size_t>(maxBufferCount); 214 if (tooManyBuffers) { 215 BQ_LOGV("%s: queue size is %zu, waiting", caller, 216 mCore->mQueue.size()); 217 } else { 218 if (!mCore->mFreeBuffers.empty()) { 219 auto slot = mCore->mFreeBuffers.begin(); 220 *found = *slot; 221 mCore->mFreeBuffers.erase(slot); 222 } else if (mCore->mAllowAllocation && !mCore->mFreeSlots.empty()) { 223 auto slot = mCore->mFreeSlots.begin(); 224 // Only return free slots up to the max buffer count 225 if (*slot < maxBufferCount) { 226 *found = *slot; 227 mCore->mFreeSlots.erase(slot); 228 } 229 } 230 } 231 232 // If no buffer is found, or if the queue has too many buffers 233 // outstanding, wait for a buffer to be acquired or released, or for the 234 // max buffer count to change. 235 tryAgain = (*found == BufferQueueCore::INVALID_BUFFER_SLOT) || 236 tooManyBuffers; 237 if (tryAgain) { 238 // Return an error if we're in non-blocking mode (producer and 239 // consumer are controlled by the application). 240 // However, the consumer is allowed to briefly acquire an extra 241 // buffer (which could cause us to have to wait here), which is 242 // okay, since it is only used to implement an atomic acquire + 243 // release (e.g., in GLConsumer::updateTexImage()) 244 if (mCore->mDequeueBufferCannotBlock && 245 (acquiredCount <= mCore->mMaxAcquiredBufferCount)) { 246 return WOULD_BLOCK; 247 } 248 mCore->mDequeueCondition.wait(mCore->mMutex); 249 } 250 } // while (tryAgain) 251 252 return NO_ERROR; 253} 254 255status_t BufferQueueProducer::dequeueBuffer(int *outSlot, 256 sp<android::Fence> *outFence, bool async, 257 uint32_t width, uint32_t height, PixelFormat format, uint32_t usage) { 258 ATRACE_CALL(); 259 { // Autolock scope 260 Mutex::Autolock lock(mCore->mMutex); 261 mConsumerName = mCore->mConsumerName; 262 } // Autolock scope 263 264 BQ_LOGV("dequeueBuffer: async=%s w=%u h=%u format=%#x, usage=%#x", 265 async ? "true" : "false", width, height, format, usage); 266 267 if ((width && !height) || (!width && height)) { 268 BQ_LOGE("dequeueBuffer: invalid size: w=%u h=%u", width, height); 269 return BAD_VALUE; 270 } 271 272 status_t returnFlags = NO_ERROR; 273 EGLDisplay eglDisplay = EGL_NO_DISPLAY; 274 EGLSyncKHR eglFence = EGL_NO_SYNC_KHR; 275 bool attachedByConsumer = false; 276 277 { // Autolock scope 278 Mutex::Autolock lock(mCore->mMutex); 279 mCore->waitWhileAllocatingLocked(); 280 281 if (format == 0) { 282 format = mCore->mDefaultBufferFormat; 283 } 284 285 // Enable the usage bits the consumer requested 286 usage |= mCore->mConsumerUsageBits; 287 288 const bool useDefaultSize = !width && !height; 289 if (useDefaultSize) { 290 width = mCore->mDefaultWidth; 291 height = mCore->mDefaultHeight; 292 } 293 294 int found = BufferItem::INVALID_BUFFER_SLOT; 295 while (found == BufferItem::INVALID_BUFFER_SLOT) { 296 status_t status = waitForFreeSlotThenRelock("dequeueBuffer", async, 297 &found, &returnFlags); 298 if (status != NO_ERROR) { 299 return status; 300 } 301 302 // This should not happen 303 if (found == BufferQueueCore::INVALID_BUFFER_SLOT) { 304 BQ_LOGE("dequeueBuffer: no available buffer slots"); 305 return -EBUSY; 306 } 307 308 const sp<GraphicBuffer>& buffer(mSlots[found].mGraphicBuffer); 309 310 // If we are not allowed to allocate new buffers, 311 // waitForFreeSlotThenRelock must have returned a slot containing a 312 // buffer. If this buffer would require reallocation to meet the 313 // requested attributes, we free it and attempt to get another one. 314 if (!mCore->mAllowAllocation) { 315 if (buffer->needsReallocation(width, height, format, usage)) { 316 mCore->freeBufferLocked(found); 317 found = BufferItem::INVALID_BUFFER_SLOT; 318 continue; 319 } 320 } 321 } 322 323 *outSlot = found; 324 ATRACE_BUFFER_INDEX(found); 325 326 attachedByConsumer = mSlots[found].mAttachedByConsumer; 327 328 mSlots[found].mBufferState = BufferSlot::DEQUEUED; 329 330 const sp<GraphicBuffer>& buffer(mSlots[found].mGraphicBuffer); 331 if ((buffer == NULL) || 332 buffer->needsReallocation(width, height, format, usage)) 333 { 334 mSlots[found].mAcquireCalled = false; 335 mSlots[found].mGraphicBuffer = NULL; 336 mSlots[found].mRequestBufferCalled = false; 337 mSlots[found].mEglDisplay = EGL_NO_DISPLAY; 338 mSlots[found].mEglFence = EGL_NO_SYNC_KHR; 339 mSlots[found].mFence = Fence::NO_FENCE; 340 mCore->mBufferAge = 0; 341 342 returnFlags |= BUFFER_NEEDS_REALLOCATION; 343 } else { 344 // We add 1 because that will be the frame number when this buffer 345 // is queued 346 mCore->mBufferAge = 347 mCore->mFrameCounter + 1 - mSlots[found].mFrameNumber; 348 } 349 350 BQ_LOGV("dequeueBuffer: setting buffer age to %" PRIu64, 351 mCore->mBufferAge); 352 353 if (CC_UNLIKELY(mSlots[found].mFence == NULL)) { 354 BQ_LOGE("dequeueBuffer: about to return a NULL fence - " 355 "slot=%d w=%d h=%d format=%u", 356 found, buffer->width, buffer->height, buffer->format); 357 } 358 359 eglDisplay = mSlots[found].mEglDisplay; 360 eglFence = mSlots[found].mEglFence; 361 *outFence = mSlots[found].mFence; 362 mSlots[found].mEglFence = EGL_NO_SYNC_KHR; 363 mSlots[found].mFence = Fence::NO_FENCE; 364 365 mCore->validateConsistencyLocked(); 366 } // Autolock scope 367 368 if (returnFlags & BUFFER_NEEDS_REALLOCATION) { 369 status_t error; 370 BQ_LOGV("dequeueBuffer: allocating a new buffer for slot %d", *outSlot); 371 sp<GraphicBuffer> graphicBuffer(mCore->mAllocator->createGraphicBuffer( 372 width, height, format, usage, &error)); 373 if (graphicBuffer == NULL) { 374 BQ_LOGE("dequeueBuffer: createGraphicBuffer failed"); 375 return error; 376 } 377 378 { // Autolock scope 379 Mutex::Autolock lock(mCore->mMutex); 380 381 if (mCore->mIsAbandoned) { 382 BQ_LOGE("dequeueBuffer: BufferQueue has been abandoned"); 383 return NO_INIT; 384 } 385 386 graphicBuffer->setGenerationNumber(mCore->mGenerationNumber); 387 mSlots[*outSlot].mGraphicBuffer = graphicBuffer; 388 } // Autolock scope 389 } 390 391 if (attachedByConsumer) { 392 returnFlags |= BUFFER_NEEDS_REALLOCATION; 393 } 394 395 if (eglFence != EGL_NO_SYNC_KHR) { 396 EGLint result = eglClientWaitSyncKHR(eglDisplay, eglFence, 0, 397 1000000000); 398 // If something goes wrong, log the error, but return the buffer without 399 // synchronizing access to it. It's too late at this point to abort the 400 // dequeue operation. 401 if (result == EGL_FALSE) { 402 BQ_LOGE("dequeueBuffer: error %#x waiting for fence", 403 eglGetError()); 404 } else if (result == EGL_TIMEOUT_EXPIRED_KHR) { 405 BQ_LOGE("dequeueBuffer: timeout waiting for fence"); 406 } 407 eglDestroySyncKHR(eglDisplay, eglFence); 408 } 409 410 BQ_LOGV("dequeueBuffer: returning slot=%d/%" PRIu64 " buf=%p flags=%#x", 411 *outSlot, 412 mSlots[*outSlot].mFrameNumber, 413 mSlots[*outSlot].mGraphicBuffer->handle, returnFlags); 414 415 return returnFlags; 416} 417 418status_t BufferQueueProducer::detachBuffer(int slot) { 419 ATRACE_CALL(); 420 ATRACE_BUFFER_INDEX(slot); 421 BQ_LOGV("detachBuffer(P): slot %d", slot); 422 Mutex::Autolock lock(mCore->mMutex); 423 424 if (mCore->mIsAbandoned) { 425 BQ_LOGE("detachBuffer(P): BufferQueue has been abandoned"); 426 return NO_INIT; 427 } 428 429 if (slot < 0 || slot >= BufferQueueDefs::NUM_BUFFER_SLOTS) { 430 BQ_LOGE("detachBuffer(P): slot index %d out of range [0, %d)", 431 slot, BufferQueueDefs::NUM_BUFFER_SLOTS); 432 return BAD_VALUE; 433 } else if (mSlots[slot].mBufferState != BufferSlot::DEQUEUED) { 434 BQ_LOGE("detachBuffer(P): slot %d is not owned by the producer " 435 "(state = %d)", slot, mSlots[slot].mBufferState); 436 return BAD_VALUE; 437 } else if (!mSlots[slot].mRequestBufferCalled) { 438 BQ_LOGE("detachBuffer(P): buffer in slot %d has not been requested", 439 slot); 440 return BAD_VALUE; 441 } 442 443 mCore->freeBufferLocked(slot); 444 mCore->mDequeueCondition.broadcast(); 445 mCore->validateConsistencyLocked(); 446 447 return NO_ERROR; 448} 449 450status_t BufferQueueProducer::detachNextBuffer(sp<GraphicBuffer>* outBuffer, 451 sp<Fence>* outFence) { 452 ATRACE_CALL(); 453 454 if (outBuffer == NULL) { 455 BQ_LOGE("detachNextBuffer: outBuffer must not be NULL"); 456 return BAD_VALUE; 457 } else if (outFence == NULL) { 458 BQ_LOGE("detachNextBuffer: outFence must not be NULL"); 459 return BAD_VALUE; 460 } 461 462 Mutex::Autolock lock(mCore->mMutex); 463 mCore->waitWhileAllocatingLocked(); 464 465 if (mCore->mIsAbandoned) { 466 BQ_LOGE("detachNextBuffer: BufferQueue has been abandoned"); 467 return NO_INIT; 468 } 469 470 if (mCore->mFreeBuffers.empty()) { 471 return NO_MEMORY; 472 } 473 474 int found = mCore->mFreeBuffers.front(); 475 mCore->mFreeBuffers.remove(found); 476 477 BQ_LOGV("detachNextBuffer detached slot %d", found); 478 479 *outBuffer = mSlots[found].mGraphicBuffer; 480 *outFence = mSlots[found].mFence; 481 mCore->freeBufferLocked(found); 482 mCore->validateConsistencyLocked(); 483 484 return NO_ERROR; 485} 486 487status_t BufferQueueProducer::attachBuffer(int* outSlot, 488 const sp<android::GraphicBuffer>& buffer) { 489 ATRACE_CALL(); 490 491 if (outSlot == NULL) { 492 BQ_LOGE("attachBuffer(P): outSlot must not be NULL"); 493 return BAD_VALUE; 494 } else if (buffer == NULL) { 495 BQ_LOGE("attachBuffer(P): cannot attach NULL buffer"); 496 return BAD_VALUE; 497 } 498 499 Mutex::Autolock lock(mCore->mMutex); 500 mCore->waitWhileAllocatingLocked(); 501 502 if (buffer->getGenerationNumber() != mCore->mGenerationNumber) { 503 BQ_LOGE("attachBuffer: generation number mismatch [buffer %u] " 504 "[queue %u]", buffer->getGenerationNumber(), 505 mCore->mGenerationNumber); 506 return BAD_VALUE; 507 } 508 509 status_t returnFlags = NO_ERROR; 510 int found; 511 // TODO: Should we provide an async flag to attachBuffer? It seems 512 // unlikely that buffers which we are attaching to a BufferQueue will 513 // be asynchronous (droppable), but it may not be impossible. 514 status_t status = waitForFreeSlotThenRelock("attachBuffer(P)", false, 515 &found, &returnFlags); 516 if (status != NO_ERROR) { 517 return status; 518 } 519 520 // This should not happen 521 if (found == BufferQueueCore::INVALID_BUFFER_SLOT) { 522 BQ_LOGE("attachBuffer(P): no available buffer slots"); 523 return -EBUSY; 524 } 525 526 *outSlot = found; 527 ATRACE_BUFFER_INDEX(*outSlot); 528 BQ_LOGV("attachBuffer(P): returning slot %d flags=%#x", 529 *outSlot, returnFlags); 530 531 mSlots[*outSlot].mGraphicBuffer = buffer; 532 mSlots[*outSlot].mBufferState = BufferSlot::DEQUEUED; 533 mSlots[*outSlot].mEglFence = EGL_NO_SYNC_KHR; 534 mSlots[*outSlot].mFence = Fence::NO_FENCE; 535 mSlots[*outSlot].mRequestBufferCalled = true; 536 537 mCore->validateConsistencyLocked(); 538 539 return returnFlags; 540} 541 542status_t BufferQueueProducer::queueBuffer(int slot, 543 const QueueBufferInput &input, QueueBufferOutput *output) { 544 ATRACE_CALL(); 545 ATRACE_BUFFER_INDEX(slot); 546 547 int64_t timestamp; 548 bool isAutoTimestamp; 549 android_dataspace dataSpace; 550 Rect crop; 551 int scalingMode; 552 uint32_t transform; 553 uint32_t stickyTransform; 554 bool async; 555 sp<Fence> fence; 556 input.deflate(×tamp, &isAutoTimestamp, &dataSpace, &crop, &scalingMode, 557 &transform, &async, &fence, &stickyTransform); 558 Region surfaceDamage = input.getSurfaceDamage(); 559 560 if (fence == NULL) { 561 BQ_LOGE("queueBuffer: fence is NULL"); 562 return BAD_VALUE; 563 } 564 565 switch (scalingMode) { 566 case NATIVE_WINDOW_SCALING_MODE_FREEZE: 567 case NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW: 568 case NATIVE_WINDOW_SCALING_MODE_SCALE_CROP: 569 case NATIVE_WINDOW_SCALING_MODE_NO_SCALE_CROP: 570 break; 571 default: 572 BQ_LOGE("queueBuffer: unknown scaling mode %d", scalingMode); 573 return BAD_VALUE; 574 } 575 576 sp<IConsumerListener> frameAvailableListener; 577 sp<IConsumerListener> frameReplacedListener; 578 int callbackTicket = 0; 579 BufferItem item; 580 { // Autolock scope 581 Mutex::Autolock lock(mCore->mMutex); 582 583 if (mCore->mIsAbandoned) { 584 BQ_LOGE("queueBuffer: BufferQueue has been abandoned"); 585 return NO_INIT; 586 } 587 588 const int maxBufferCount = mCore->getMaxBufferCountLocked(async); 589 if (async && mCore->mOverrideMaxBufferCount) { 590 // FIXME: Some drivers are manually setting the buffer count 591 // (which they shouldn't), so we do this extra test here to 592 // handle that case. This is TEMPORARY until we get this fixed. 593 if (mCore->mOverrideMaxBufferCount < maxBufferCount) { 594 BQ_LOGE("queueBuffer: async mode is invalid with " 595 "buffer count override"); 596 return BAD_VALUE; 597 } 598 } 599 600 if (slot < 0 || slot >= maxBufferCount) { 601 BQ_LOGE("queueBuffer: slot index %d out of range [0, %d)", 602 slot, maxBufferCount); 603 return BAD_VALUE; 604 } else if (mSlots[slot].mBufferState != BufferSlot::DEQUEUED) { 605 BQ_LOGE("queueBuffer: slot %d is not owned by the producer " 606 "(state = %d)", slot, mSlots[slot].mBufferState); 607 return BAD_VALUE; 608 } else if (!mSlots[slot].mRequestBufferCalled) { 609 BQ_LOGE("queueBuffer: slot %d was queued without requesting " 610 "a buffer", slot); 611 return BAD_VALUE; 612 } 613 614 BQ_LOGV("queueBuffer: slot=%d/%" PRIu64 " time=%" PRIu64 " dataSpace=%d" 615 " crop=[%d,%d,%d,%d] transform=%#x scale=%s", 616 slot, mCore->mFrameCounter + 1, timestamp, dataSpace, 617 crop.left, crop.top, crop.right, crop.bottom, transform, 618 BufferItem::scalingModeName(static_cast<uint32_t>(scalingMode))); 619 620 const sp<GraphicBuffer>& graphicBuffer(mSlots[slot].mGraphicBuffer); 621 Rect bufferRect(graphicBuffer->getWidth(), graphicBuffer->getHeight()); 622 Rect croppedRect; 623 crop.intersect(bufferRect, &croppedRect); 624 if (croppedRect != crop) { 625 BQ_LOGE("queueBuffer: crop rect is not contained within the " 626 "buffer in slot %d", slot); 627 return BAD_VALUE; 628 } 629 630 // Override UNKNOWN dataspace with consumer default 631 if (dataSpace == HAL_DATASPACE_UNKNOWN) { 632 dataSpace = mCore->mDefaultBufferDataSpace; 633 } 634 635 mSlots[slot].mFence = fence; 636 mSlots[slot].mBufferState = BufferSlot::QUEUED; 637 ++mCore->mFrameCounter; 638 mSlots[slot].mFrameNumber = mCore->mFrameCounter; 639 640 item.mAcquireCalled = mSlots[slot].mAcquireCalled; 641 item.mGraphicBuffer = mSlots[slot].mGraphicBuffer; 642 item.mCrop = crop; 643 item.mTransform = transform & 644 ~static_cast<uint32_t>(NATIVE_WINDOW_TRANSFORM_INVERSE_DISPLAY); 645 item.mTransformToDisplayInverse = 646 (transform & NATIVE_WINDOW_TRANSFORM_INVERSE_DISPLAY) != 0; 647 item.mScalingMode = static_cast<uint32_t>(scalingMode); 648 item.mTimestamp = timestamp; 649 item.mIsAutoTimestamp = isAutoTimestamp; 650 item.mDataSpace = dataSpace; 651 item.mFrameNumber = mCore->mFrameCounter; 652 item.mSlot = slot; 653 item.mFence = fence; 654 item.mIsDroppable = mCore->mDequeueBufferCannotBlock || async; 655 item.mSurfaceDamage = surfaceDamage; 656 657 mStickyTransform = stickyTransform; 658 659 if (mCore->mQueue.empty()) { 660 // When the queue is empty, we can ignore mDequeueBufferCannotBlock 661 // and simply queue this buffer 662 mCore->mQueue.push_back(item); 663 frameAvailableListener = mCore->mConsumerListener; 664 } else { 665 // When the queue is not empty, we need to look at the front buffer 666 // state to see if we need to replace it 667 BufferQueueCore::Fifo::iterator front(mCore->mQueue.begin()); 668 if (front->mIsDroppable) { 669 // If the front queued buffer is still being tracked, we first 670 // mark it as freed 671 if (mCore->stillTracking(front)) { 672 mSlots[front->mSlot].mBufferState = BufferSlot::FREE; 673 mCore->mFreeBuffers.push_front(front->mSlot); 674 } 675 // Overwrite the droppable buffer with the incoming one 676 *front = item; 677 frameReplacedListener = mCore->mConsumerListener; 678 } else { 679 mCore->mQueue.push_back(item); 680 frameAvailableListener = mCore->mConsumerListener; 681 } 682 } 683 684 mCore->mBufferHasBeenQueued = true; 685 mCore->mDequeueCondition.broadcast(); 686 687 output->inflate(mCore->mDefaultWidth, mCore->mDefaultHeight, 688 mCore->mTransformHint, 689 static_cast<uint32_t>(mCore->mQueue.size())); 690 691 ATRACE_INT(mCore->mConsumerName.string(), mCore->mQueue.size()); 692 693 // Take a ticket for the callback functions 694 callbackTicket = mNextCallbackTicket++; 695 696 mCore->validateConsistencyLocked(); 697 } // Autolock scope 698 699 // Wait without lock held 700 if (mCore->mConnectedApi == NATIVE_WINDOW_API_EGL) { 701 // Waiting here allows for two full buffers to be queued but not a 702 // third. In the event that frames take varying time, this makes a 703 // small trade-off in favor of latency rather than throughput. 704 mLastQueueBufferFence->waitForever("Throttling EGL Production"); 705 mLastQueueBufferFence = fence; 706 } 707 708 // Don't send the GraphicBuffer through the callback, and don't send 709 // the slot number, since the consumer shouldn't need it 710 item.mGraphicBuffer.clear(); 711 item.mSlot = BufferItem::INVALID_BUFFER_SLOT; 712 713 // Call back without the main BufferQueue lock held, but with the callback 714 // lock held so we can ensure that callbacks occur in order 715 { 716 Mutex::Autolock lock(mCallbackMutex); 717 while (callbackTicket != mCurrentCallbackTicket) { 718 mCallbackCondition.wait(mCallbackMutex); 719 } 720 721 if (frameAvailableListener != NULL) { 722 frameAvailableListener->onFrameAvailable(item); 723 } else if (frameReplacedListener != NULL) { 724 frameReplacedListener->onFrameReplaced(item); 725 } 726 727 ++mCurrentCallbackTicket; 728 mCallbackCondition.broadcast(); 729 } 730 731 return NO_ERROR; 732} 733 734void BufferQueueProducer::cancelBuffer(int slot, const sp<Fence>& fence) { 735 ATRACE_CALL(); 736 BQ_LOGV("cancelBuffer: slot %d", slot); 737 Mutex::Autolock lock(mCore->mMutex); 738 739 if (mCore->mIsAbandoned) { 740 BQ_LOGE("cancelBuffer: BufferQueue has been abandoned"); 741 return; 742 } 743 744 if (slot < 0 || slot >= BufferQueueDefs::NUM_BUFFER_SLOTS) { 745 BQ_LOGE("cancelBuffer: slot index %d out of range [0, %d)", 746 slot, BufferQueueDefs::NUM_BUFFER_SLOTS); 747 return; 748 } else if (mSlots[slot].mBufferState != BufferSlot::DEQUEUED) { 749 BQ_LOGE("cancelBuffer: slot %d is not owned by the producer " 750 "(state = %d)", slot, mSlots[slot].mBufferState); 751 return; 752 } else if (fence == NULL) { 753 BQ_LOGE("cancelBuffer: fence is NULL"); 754 return; 755 } 756 757 mCore->mFreeBuffers.push_front(slot); 758 mSlots[slot].mBufferState = BufferSlot::FREE; 759 mSlots[slot].mFence = fence; 760 mCore->mDequeueCondition.broadcast(); 761 mCore->validateConsistencyLocked(); 762} 763 764int BufferQueueProducer::query(int what, int *outValue) { 765 ATRACE_CALL(); 766 Mutex::Autolock lock(mCore->mMutex); 767 768 if (outValue == NULL) { 769 BQ_LOGE("query: outValue was NULL"); 770 return BAD_VALUE; 771 } 772 773 if (mCore->mIsAbandoned) { 774 BQ_LOGE("query: BufferQueue has been abandoned"); 775 return NO_INIT; 776 } 777 778 int value; 779 switch (what) { 780 case NATIVE_WINDOW_WIDTH: 781 value = static_cast<int32_t>(mCore->mDefaultWidth); 782 break; 783 case NATIVE_WINDOW_HEIGHT: 784 value = static_cast<int32_t>(mCore->mDefaultHeight); 785 break; 786 case NATIVE_WINDOW_FORMAT: 787 value = static_cast<int32_t>(mCore->mDefaultBufferFormat); 788 break; 789 case NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS: 790 value = mCore->getMinUndequeuedBufferCountLocked(false); 791 break; 792 case NATIVE_WINDOW_STICKY_TRANSFORM: 793 value = static_cast<int32_t>(mStickyTransform); 794 break; 795 case NATIVE_WINDOW_CONSUMER_RUNNING_BEHIND: 796 value = (mCore->mQueue.size() > 1); 797 break; 798 case NATIVE_WINDOW_CONSUMER_USAGE_BITS: 799 value = static_cast<int32_t>(mCore->mConsumerUsageBits); 800 break; 801 case NATIVE_WINDOW_DEFAULT_DATASPACE: 802 value = static_cast<int32_t>(mCore->mDefaultBufferDataSpace); 803 break; 804 case NATIVE_WINDOW_BUFFER_AGE: 805 if (mCore->mBufferAge > INT32_MAX) { 806 value = 0; 807 } else { 808 value = static_cast<int32_t>(mCore->mBufferAge); 809 } 810 break; 811 default: 812 return BAD_VALUE; 813 } 814 815 BQ_LOGV("query: %d? %d", what, value); 816 *outValue = value; 817 return NO_ERROR; 818} 819 820status_t BufferQueueProducer::connect(const sp<IProducerListener>& listener, 821 int api, bool producerControlledByApp, QueueBufferOutput *output) { 822 ATRACE_CALL(); 823 Mutex::Autolock lock(mCore->mMutex); 824 mConsumerName = mCore->mConsumerName; 825 BQ_LOGV("connect(P): api=%d producerControlledByApp=%s", api, 826 producerControlledByApp ? "true" : "false"); 827 828 if (mCore->mIsAbandoned) { 829 BQ_LOGE("connect(P): BufferQueue has been abandoned"); 830 return NO_INIT; 831 } 832 833 if (mCore->mConsumerListener == NULL) { 834 BQ_LOGE("connect(P): BufferQueue has no consumer"); 835 return NO_INIT; 836 } 837 838 if (output == NULL) { 839 BQ_LOGE("connect(P): output was NULL"); 840 return BAD_VALUE; 841 } 842 843 if (mCore->mConnectedApi != BufferQueueCore::NO_CONNECTED_API) { 844 BQ_LOGE("connect(P): already connected (cur=%d req=%d)", 845 mCore->mConnectedApi, api); 846 return BAD_VALUE; 847 } 848 849 int status = NO_ERROR; 850 switch (api) { 851 case NATIVE_WINDOW_API_EGL: 852 case NATIVE_WINDOW_API_CPU: 853 case NATIVE_WINDOW_API_MEDIA: 854 case NATIVE_WINDOW_API_CAMERA: 855 mCore->mConnectedApi = api; 856 output->inflate(mCore->mDefaultWidth, mCore->mDefaultHeight, 857 mCore->mTransformHint, 858 static_cast<uint32_t>(mCore->mQueue.size())); 859 860 // Set up a death notification so that we can disconnect 861 // automatically if the remote producer dies 862 if (listener != NULL && 863 IInterface::asBinder(listener)->remoteBinder() != NULL) { 864 status = IInterface::asBinder(listener)->linkToDeath( 865 static_cast<IBinder::DeathRecipient*>(this)); 866 if (status != NO_ERROR) { 867 BQ_LOGE("connect(P): linkToDeath failed: %s (%d)", 868 strerror(-status), status); 869 } 870 } 871 mCore->mConnectedProducerListener = listener; 872 break; 873 default: 874 BQ_LOGE("connect(P): unknown API %d", api); 875 status = BAD_VALUE; 876 break; 877 } 878 879 mCore->mBufferHasBeenQueued = false; 880 mCore->mDequeueBufferCannotBlock = 881 mCore->mConsumerControlledByApp && producerControlledByApp; 882 mCore->mAllowAllocation = true; 883 884 return status; 885} 886 887status_t BufferQueueProducer::disconnect(int api) { 888 ATRACE_CALL(); 889 BQ_LOGV("disconnect(P): api %d", api); 890 891 int status = NO_ERROR; 892 sp<IConsumerListener> listener; 893 { // Autolock scope 894 Mutex::Autolock lock(mCore->mMutex); 895 mCore->waitWhileAllocatingLocked(); 896 897 if (mCore->mIsAbandoned) { 898 // It's not really an error to disconnect after the surface has 899 // been abandoned; it should just be a no-op. 900 return NO_ERROR; 901 } 902 903 switch (api) { 904 case NATIVE_WINDOW_API_EGL: 905 case NATIVE_WINDOW_API_CPU: 906 case NATIVE_WINDOW_API_MEDIA: 907 case NATIVE_WINDOW_API_CAMERA: 908 if (mCore->mConnectedApi == api) { 909 mCore->freeAllBuffersLocked(); 910 911 // Remove our death notification callback if we have one 912 if (mCore->mConnectedProducerListener != NULL) { 913 sp<IBinder> token = 914 IInterface::asBinder(mCore->mConnectedProducerListener); 915 // This can fail if we're here because of the death 916 // notification, but we just ignore it 917 token->unlinkToDeath( 918 static_cast<IBinder::DeathRecipient*>(this)); 919 } 920 mCore->mConnectedProducerListener = NULL; 921 mCore->mConnectedApi = BufferQueueCore::NO_CONNECTED_API; 922 mCore->mSidebandStream.clear(); 923 mCore->mDequeueCondition.broadcast(); 924 listener = mCore->mConsumerListener; 925 } else { 926 BQ_LOGE("disconnect(P): connected to another API " 927 "(cur=%d req=%d)", mCore->mConnectedApi, api); 928 status = BAD_VALUE; 929 } 930 break; 931 default: 932 BQ_LOGE("disconnect(P): unknown API %d", api); 933 status = BAD_VALUE; 934 break; 935 } 936 } // Autolock scope 937 938 // Call back without lock held 939 if (listener != NULL) { 940 listener->onBuffersReleased(); 941 } 942 943 return status; 944} 945 946status_t BufferQueueProducer::setSidebandStream(const sp<NativeHandle>& stream) { 947 sp<IConsumerListener> listener; 948 { // Autolock scope 949 Mutex::Autolock _l(mCore->mMutex); 950 mCore->mSidebandStream = stream; 951 listener = mCore->mConsumerListener; 952 } // Autolock scope 953 954 if (listener != NULL) { 955 listener->onSidebandStreamChanged(); 956 } 957 return NO_ERROR; 958} 959 960void BufferQueueProducer::allocateBuffers(bool async, uint32_t width, 961 uint32_t height, PixelFormat format, uint32_t usage) { 962 ATRACE_CALL(); 963 while (true) { 964 Vector<int> freeSlots; 965 size_t newBufferCount = 0; 966 uint32_t allocWidth = 0; 967 uint32_t allocHeight = 0; 968 PixelFormat allocFormat = PIXEL_FORMAT_UNKNOWN; 969 uint32_t allocUsage = 0; 970 { // Autolock scope 971 Mutex::Autolock lock(mCore->mMutex); 972 mCore->waitWhileAllocatingLocked(); 973 974 if (!mCore->mAllowAllocation) { 975 BQ_LOGE("allocateBuffers: allocation is not allowed for this " 976 "BufferQueue"); 977 return; 978 } 979 980 int currentBufferCount = 0; 981 for (int slot = 0; slot < BufferQueueDefs::NUM_BUFFER_SLOTS; ++slot) { 982 if (mSlots[slot].mGraphicBuffer != NULL) { 983 ++currentBufferCount; 984 } else { 985 if (mSlots[slot].mBufferState != BufferSlot::FREE) { 986 BQ_LOGE("allocateBuffers: slot %d without buffer is not FREE", 987 slot); 988 continue; 989 } 990 991 freeSlots.push_back(slot); 992 } 993 } 994 995 int maxBufferCount = mCore->getMaxBufferCountLocked(async); 996 BQ_LOGV("allocateBuffers: allocating from %d buffers up to %d buffers", 997 currentBufferCount, maxBufferCount); 998 if (maxBufferCount <= currentBufferCount) 999 return; 1000 newBufferCount = 1001 static_cast<size_t>(maxBufferCount - currentBufferCount); 1002 if (freeSlots.size() < newBufferCount) { 1003 BQ_LOGE("allocateBuffers: ran out of free slots"); 1004 return; 1005 } 1006 allocWidth = width > 0 ? width : mCore->mDefaultWidth; 1007 allocHeight = height > 0 ? height : mCore->mDefaultHeight; 1008 allocFormat = format != 0 ? format : mCore->mDefaultBufferFormat; 1009 allocUsage = usage | mCore->mConsumerUsageBits; 1010 1011 mCore->mIsAllocating = true; 1012 } // Autolock scope 1013 1014 Vector<sp<GraphicBuffer>> buffers; 1015 for (size_t i = 0; i < newBufferCount; ++i) { 1016 status_t result = NO_ERROR; 1017 sp<GraphicBuffer> graphicBuffer(mCore->mAllocator->createGraphicBuffer( 1018 allocWidth, allocHeight, allocFormat, allocUsage, &result)); 1019 if (result != NO_ERROR) { 1020 BQ_LOGE("allocateBuffers: failed to allocate buffer (%u x %u, format" 1021 " %u, usage %u)", width, height, format, usage); 1022 Mutex::Autolock lock(mCore->mMutex); 1023 mCore->mIsAllocating = false; 1024 mCore->mIsAllocatingCondition.broadcast(); 1025 return; 1026 } 1027 buffers.push_back(graphicBuffer); 1028 } 1029 1030 { // Autolock scope 1031 Mutex::Autolock lock(mCore->mMutex); 1032 uint32_t checkWidth = width > 0 ? width : mCore->mDefaultWidth; 1033 uint32_t checkHeight = height > 0 ? height : mCore->mDefaultHeight; 1034 PixelFormat checkFormat = format != 0 ? 1035 format : mCore->mDefaultBufferFormat; 1036 uint32_t checkUsage = usage | mCore->mConsumerUsageBits; 1037 if (checkWidth != allocWidth || checkHeight != allocHeight || 1038 checkFormat != allocFormat || checkUsage != allocUsage) { 1039 // Something changed while we released the lock. Retry. 1040 BQ_LOGV("allocateBuffers: size/format/usage changed while allocating. Retrying."); 1041 mCore->mIsAllocating = false; 1042 mCore->mIsAllocatingCondition.broadcast(); 1043 continue; 1044 } 1045 1046 for (size_t i = 0; i < newBufferCount; ++i) { 1047 int slot = freeSlots[i]; 1048 if (mSlots[slot].mBufferState != BufferSlot::FREE) { 1049 // A consumer allocated the FREE slot with attachBuffer. Discard the buffer we 1050 // allocated. 1051 BQ_LOGV("allocateBuffers: slot %d was acquired while allocating. " 1052 "Dropping allocated buffer.", slot); 1053 continue; 1054 } 1055 mCore->freeBufferLocked(slot); // Clean up the slot first 1056 mSlots[slot].mGraphicBuffer = buffers[i]; 1057 mSlots[slot].mFence = Fence::NO_FENCE; 1058 1059 // freeBufferLocked puts this slot on the free slots list. Since 1060 // we then attached a buffer, move the slot to free buffer list. 1061 mCore->mFreeSlots.erase(slot); 1062 mCore->mFreeBuffers.push_front(slot); 1063 1064 BQ_LOGV("allocateBuffers: allocated a new buffer in slot %d", slot); 1065 } 1066 1067 mCore->mIsAllocating = false; 1068 mCore->mIsAllocatingCondition.broadcast(); 1069 mCore->validateConsistencyLocked(); 1070 } // Autolock scope 1071 } 1072} 1073 1074status_t BufferQueueProducer::allowAllocation(bool allow) { 1075 ATRACE_CALL(); 1076 BQ_LOGV("allowAllocation: %s", allow ? "true" : "false"); 1077 1078 Mutex::Autolock lock(mCore->mMutex); 1079 mCore->mAllowAllocation = allow; 1080 return NO_ERROR; 1081} 1082 1083status_t BufferQueueProducer::setGenerationNumber(uint32_t generationNumber) { 1084 ATRACE_CALL(); 1085 BQ_LOGV("setGenerationNumber: %u", generationNumber); 1086 1087 Mutex::Autolock lock(mCore->mMutex); 1088 mCore->mGenerationNumber = generationNumber; 1089 return NO_ERROR; 1090} 1091 1092String8 BufferQueueProducer::getConsumerName() const { 1093 ATRACE_CALL(); 1094 BQ_LOGV("getConsumerName: %s", mConsumerName.string()); 1095 return mConsumerName; 1096} 1097 1098void BufferQueueProducer::binderDied(const wp<android::IBinder>& /* who */) { 1099 // If we're here, it means that a producer we were connected to died. 1100 // We're guaranteed that we are still connected to it because we remove 1101 // this callback upon disconnect. It's therefore safe to read mConnectedApi 1102 // without synchronization here. 1103 int api = mCore->mConnectedApi; 1104 disconnect(api); 1105} 1106 1107} // namespace android 1108