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