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