BufferQueue.cpp revision 1585c4d9fbbba3ba70ae625923b85cd02cb8a0fd
1/* 2 * Copyright (C) 2012 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#define LOG_TAG "BufferQueue" 18#define ATRACE_TAG ATRACE_TAG_GRAPHICS 19//#define LOG_NDEBUG 0 20 21#define GL_GLEXT_PROTOTYPES 22#define EGL_EGLEXT_PROTOTYPES 23 24#include <EGL/egl.h> 25#include <EGL/eglext.h> 26 27#include <gui/BufferQueue.h> 28#include <gui/ISurfaceComposer.h> 29#include <private/gui/ComposerService.h> 30 31#include <utils/Log.h> 32#include <utils/Trace.h> 33 34// Macros for including the BufferQueue name in log messages 35#define ST_LOGV(x, ...) ALOGV("[%s] "x, mConsumerName.string(), ##__VA_ARGS__) 36#define ST_LOGD(x, ...) ALOGD("[%s] "x, mConsumerName.string(), ##__VA_ARGS__) 37#define ST_LOGI(x, ...) ALOGI("[%s] "x, mConsumerName.string(), ##__VA_ARGS__) 38#define ST_LOGW(x, ...) ALOGW("[%s] "x, mConsumerName.string(), ##__VA_ARGS__) 39#define ST_LOGE(x, ...) ALOGE("[%s] "x, mConsumerName.string(), ##__VA_ARGS__) 40 41#define ATRACE_BUFFER_INDEX(index) \ 42 if (ATRACE_ENABLED()) { \ 43 char ___traceBuf[1024]; \ 44 snprintf(___traceBuf, 1024, "%s: %d", mConsumerName.string(), \ 45 (index)); \ 46 android::ScopedTrace ___bufTracer(ATRACE_TAG, ___traceBuf); \ 47 } 48 49namespace android { 50 51// Get an ID that's unique within this process. 52static int32_t createProcessUniqueId() { 53 static volatile int32_t globalCounter = 0; 54 return android_atomic_inc(&globalCounter); 55} 56 57static const char* scalingModeName(int scalingMode) { 58 switch (scalingMode) { 59 case NATIVE_WINDOW_SCALING_MODE_FREEZE: return "FREEZE"; 60 case NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW: return "SCALE_TO_WINDOW"; 61 case NATIVE_WINDOW_SCALING_MODE_SCALE_CROP: return "SCALE_CROP"; 62 default: return "Unknown"; 63 } 64} 65 66BufferQueue::BufferQueue(bool allowSynchronousMode, 67 const sp<IGraphicBufferAlloc>& allocator) : 68 mDefaultWidth(1), 69 mDefaultHeight(1), 70 mMaxAcquiredBufferCount(1), 71 mDefaultMaxBufferCount(2), 72 mOverrideMaxBufferCount(0), 73 mSynchronousMode(false), 74 mAllowSynchronousMode(allowSynchronousMode), 75 mConnectedApi(NO_CONNECTED_API), 76 mAbandoned(false), 77 mFrameCounter(0), 78 mBufferHasBeenQueued(false), 79 mDefaultBufferFormat(PIXEL_FORMAT_RGBA_8888), 80 mConsumerUsageBits(0), 81 mTransformHint(0) 82{ 83 // Choose a name using the PID and a process-unique ID. 84 mConsumerName = String8::format("unnamed-%d-%d", getpid(), createProcessUniqueId()); 85 86 ST_LOGV("BufferQueue"); 87 if (allocator == NULL) { 88 sp<ISurfaceComposer> composer(ComposerService::getComposerService()); 89 mGraphicBufferAlloc = composer->createGraphicBufferAlloc(); 90 if (mGraphicBufferAlloc == 0) { 91 ST_LOGE("createGraphicBufferAlloc() failed in BufferQueue()"); 92 } 93 } else { 94 mGraphicBufferAlloc = allocator; 95 } 96} 97 98BufferQueue::~BufferQueue() { 99 ST_LOGV("~BufferQueue"); 100} 101 102status_t BufferQueue::setDefaultMaxBufferCountLocked(int count) { 103 if (count < 2 || count > NUM_BUFFER_SLOTS) 104 return BAD_VALUE; 105 106 mDefaultMaxBufferCount = count; 107 mDequeueCondition.broadcast(); 108 109 return NO_ERROR; 110} 111 112bool BufferQueue::isSynchronousMode() const { 113 Mutex::Autolock lock(mMutex); 114 return mSynchronousMode; 115} 116 117void BufferQueue::setConsumerName(const String8& name) { 118 Mutex::Autolock lock(mMutex); 119 mConsumerName = name; 120} 121 122status_t BufferQueue::setDefaultBufferFormat(uint32_t defaultFormat) { 123 Mutex::Autolock lock(mMutex); 124 mDefaultBufferFormat = defaultFormat; 125 return NO_ERROR; 126} 127 128status_t BufferQueue::setConsumerUsageBits(uint32_t usage) { 129 Mutex::Autolock lock(mMutex); 130 mConsumerUsageBits = usage; 131 return NO_ERROR; 132} 133 134status_t BufferQueue::setTransformHint(uint32_t hint) { 135 ST_LOGV("setTransformHint: %02x", hint); 136 Mutex::Autolock lock(mMutex); 137 mTransformHint = hint; 138 return NO_ERROR; 139} 140 141status_t BufferQueue::setBufferCount(int bufferCount) { 142 ST_LOGV("setBufferCount: count=%d", bufferCount); 143 144 sp<ConsumerListener> listener; 145 { 146 Mutex::Autolock lock(mMutex); 147 148 if (mAbandoned) { 149 ST_LOGE("setBufferCount: BufferQueue has been abandoned!"); 150 return NO_INIT; 151 } 152 if (bufferCount > NUM_BUFFER_SLOTS) { 153 ST_LOGE("setBufferCount: bufferCount too large (max %d)", 154 NUM_BUFFER_SLOTS); 155 return BAD_VALUE; 156 } 157 158 // Error out if the user has dequeued buffers 159 int maxBufferCount = getMaxBufferCountLocked(); 160 for (int i=0 ; i<maxBufferCount; i++) { 161 if (mSlots[i].mBufferState == BufferSlot::DEQUEUED) { 162 ST_LOGE("setBufferCount: client owns some buffers"); 163 return -EINVAL; 164 } 165 } 166 167 const int minBufferSlots = getMinMaxBufferCountLocked(); 168 if (bufferCount == 0) { 169 mOverrideMaxBufferCount = 0; 170 mDequeueCondition.broadcast(); 171 return NO_ERROR; 172 } 173 174 if (bufferCount < minBufferSlots) { 175 ST_LOGE("setBufferCount: requested buffer count (%d) is less than " 176 "minimum (%d)", bufferCount, minBufferSlots); 177 return BAD_VALUE; 178 } 179 180 // here we're guaranteed that the client doesn't have dequeued buffers 181 // and will release all of its buffer references. We don't clear the 182 // queue, however, so currently queued buffers still get displayed. 183 freeAllBuffersLocked(); 184 mOverrideMaxBufferCount = bufferCount; 185 mDequeueCondition.broadcast(); 186 listener = mConsumerListener; 187 } // scope for lock 188 189 if (listener != NULL) { 190 listener->onBuffersReleased(); 191 } 192 193 return NO_ERROR; 194} 195 196int BufferQueue::query(int what, int* outValue) 197{ 198 ATRACE_CALL(); 199 Mutex::Autolock lock(mMutex); 200 201 if (mAbandoned) { 202 ST_LOGE("query: BufferQueue has been abandoned!"); 203 return NO_INIT; 204 } 205 206 int value; 207 switch (what) { 208 case NATIVE_WINDOW_WIDTH: 209 value = mDefaultWidth; 210 break; 211 case NATIVE_WINDOW_HEIGHT: 212 value = mDefaultHeight; 213 break; 214 case NATIVE_WINDOW_FORMAT: 215 value = mDefaultBufferFormat; 216 break; 217 case NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS: 218 value = getMinUndequeuedBufferCountLocked(); 219 break; 220 case NATIVE_WINDOW_CONSUMER_RUNNING_BEHIND: 221 value = (mQueue.size() >= 2); 222 break; 223 default: 224 return BAD_VALUE; 225 } 226 outValue[0] = value; 227 return NO_ERROR; 228} 229 230status_t BufferQueue::requestBuffer(int slot, sp<GraphicBuffer>* buf) { 231 ATRACE_CALL(); 232 ST_LOGV("requestBuffer: slot=%d", slot); 233 Mutex::Autolock lock(mMutex); 234 if (mAbandoned) { 235 ST_LOGE("requestBuffer: BufferQueue has been abandoned!"); 236 return NO_INIT; 237 } 238 int maxBufferCount = getMaxBufferCountLocked(); 239 if (slot < 0 || maxBufferCount <= slot) { 240 ST_LOGE("requestBuffer: slot index out of range [0, %d]: %d", 241 maxBufferCount, slot); 242 return BAD_VALUE; 243 } else if (mSlots[slot].mBufferState != BufferSlot::DEQUEUED) { 244 // XXX: I vaguely recall there was some reason this can be valid, but 245 // for the life of me I can't recall under what circumstances that's 246 // the case. 247 ST_LOGE("requestBuffer: slot %d is not owned by the client (state=%d)", 248 slot, mSlots[slot].mBufferState); 249 return BAD_VALUE; 250 } 251 mSlots[slot].mRequestBufferCalled = true; 252 *buf = mSlots[slot].mGraphicBuffer; 253 return NO_ERROR; 254} 255 256status_t BufferQueue::dequeueBuffer(int *outBuf, sp<Fence>* outFence, 257 uint32_t w, uint32_t h, uint32_t format, uint32_t usage) { 258 ATRACE_CALL(); 259 ST_LOGV("dequeueBuffer: w=%d h=%d fmt=%#x usage=%#x", w, h, format, usage); 260 261 if ((w && !h) || (!w && h)) { 262 ST_LOGE("dequeueBuffer: invalid size: w=%u, h=%u", w, h); 263 return BAD_VALUE; 264 } 265 266 status_t returnFlags(OK); 267 EGLDisplay dpy = EGL_NO_DISPLAY; 268 EGLSyncKHR eglFence = EGL_NO_SYNC_KHR; 269 270 { // Scope for the lock 271 Mutex::Autolock lock(mMutex); 272 273 if (format == 0) { 274 format = mDefaultBufferFormat; 275 } 276 // turn on usage bits the consumer requested 277 usage |= mConsumerUsageBits; 278 279 int found = -1; 280 int dequeuedCount = 0; 281 bool tryAgain = true; 282 while (tryAgain) { 283 if (mAbandoned) { 284 ST_LOGE("dequeueBuffer: BufferQueue has been abandoned!"); 285 return NO_INIT; 286 } 287 288 const int maxBufferCount = getMaxBufferCountLocked(); 289 290 // Free up any buffers that are in slots beyond the max buffer 291 // count. 292 for (int i = maxBufferCount; i < NUM_BUFFER_SLOTS; i++) { 293 assert(mSlots[i].mBufferState == BufferSlot::FREE); 294 if (mSlots[i].mGraphicBuffer != NULL) { 295 freeBufferLocked(i); 296 returnFlags |= IGraphicBufferProducer::RELEASE_ALL_BUFFERS; 297 } 298 } 299 300 // look for a free buffer to give to the client 301 found = INVALID_BUFFER_SLOT; 302 dequeuedCount = 0; 303 for (int i = 0; i < maxBufferCount; i++) { 304 const int state = mSlots[i].mBufferState; 305 if (state == BufferSlot::DEQUEUED) { 306 dequeuedCount++; 307 } 308 309 if (state == BufferSlot::FREE) { 310 /* We return the oldest of the free buffers to avoid 311 * stalling the producer if possible. This is because 312 * the consumer may still have pending reads of the 313 * buffers in flight. 314 */ 315 if ((found < 0) || 316 mSlots[i].mFrameNumber < mSlots[found].mFrameNumber) { 317 found = i; 318 } 319 } 320 } 321 322 // clients are not allowed to dequeue more than one buffer 323 // if they didn't set a buffer count. 324 if (!mOverrideMaxBufferCount && dequeuedCount) { 325 ST_LOGE("dequeueBuffer: can't dequeue multiple buffers without " 326 "setting the buffer count"); 327 return -EINVAL; 328 } 329 330 // See whether a buffer has been queued since the last 331 // setBufferCount so we know whether to perform the min undequeued 332 // buffers check below. 333 if (mBufferHasBeenQueued) { 334 // make sure the client is not trying to dequeue more buffers 335 // than allowed. 336 const int newUndequeuedCount = maxBufferCount - (dequeuedCount+1); 337 const int minUndequeuedCount = getMinUndequeuedBufferCountLocked(); 338 if (newUndequeuedCount < minUndequeuedCount) { 339 ST_LOGE("dequeueBuffer: min undequeued buffer count (%d) " 340 "exceeded (dequeued=%d undequeudCount=%d)", 341 minUndequeuedCount, dequeuedCount, 342 newUndequeuedCount); 343 return -EBUSY; 344 } 345 } 346 347 // If no buffer is found, wait for a buffer to be released or for 348 // the max buffer count to change. 349 tryAgain = found == INVALID_BUFFER_SLOT; 350 if (tryAgain) { 351 mDequeueCondition.wait(mMutex); 352 } 353 } 354 355 356 if (found == INVALID_BUFFER_SLOT) { 357 // This should not happen. 358 ST_LOGE("dequeueBuffer: no available buffer slots"); 359 return -EBUSY; 360 } 361 362 const int buf = found; 363 *outBuf = found; 364 365 ATRACE_BUFFER_INDEX(buf); 366 367 const bool useDefaultSize = !w && !h; 368 if (useDefaultSize) { 369 // use the default size 370 w = mDefaultWidth; 371 h = mDefaultHeight; 372 } 373 374 mSlots[buf].mBufferState = BufferSlot::DEQUEUED; 375 376 const sp<GraphicBuffer>& buffer(mSlots[buf].mGraphicBuffer); 377 if ((buffer == NULL) || 378 (uint32_t(buffer->width) != w) || 379 (uint32_t(buffer->height) != h) || 380 (uint32_t(buffer->format) != format) || 381 ((uint32_t(buffer->usage) & usage) != usage)) 382 { 383 mSlots[buf].mAcquireCalled = false; 384 mSlots[buf].mGraphicBuffer = NULL; 385 mSlots[buf].mRequestBufferCalled = false; 386 mSlots[buf].mEglFence = EGL_NO_SYNC_KHR; 387 mSlots[buf].mFence = Fence::NO_FENCE; 388 mSlots[buf].mEglDisplay = EGL_NO_DISPLAY; 389 390 returnFlags |= IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION; 391 } 392 393 dpy = mSlots[buf].mEglDisplay; 394 eglFence = mSlots[buf].mEglFence; 395 *outFence = mSlots[buf].mFence; 396 mSlots[buf].mEglFence = EGL_NO_SYNC_KHR; 397 mSlots[buf].mFence = Fence::NO_FENCE; 398 } // end lock scope 399 400 if (returnFlags & IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION) { 401 status_t error; 402 sp<GraphicBuffer> graphicBuffer( 403 mGraphicBufferAlloc->createGraphicBuffer( 404 w, h, format, usage, &error)); 405 if (graphicBuffer == 0) { 406 ST_LOGE("dequeueBuffer: SurfaceComposer::createGraphicBuffer " 407 "failed"); 408 return error; 409 } 410 411 { // Scope for the lock 412 Mutex::Autolock lock(mMutex); 413 414 if (mAbandoned) { 415 ST_LOGE("dequeueBuffer: BufferQueue has been abandoned!"); 416 return NO_INIT; 417 } 418 419 mSlots[*outBuf].mFrameNumber = ~0; 420 mSlots[*outBuf].mGraphicBuffer = graphicBuffer; 421 } 422 } 423 424 if (eglFence != EGL_NO_SYNC_KHR) { 425 EGLint result = eglClientWaitSyncKHR(dpy, eglFence, 0, 1000000000); 426 // If something goes wrong, log the error, but return the buffer without 427 // synchronizing access to it. It's too late at this point to abort the 428 // dequeue operation. 429 if (result == EGL_FALSE) { 430 ST_LOGE("dequeueBuffer: error waiting for fence: %#x", eglGetError()); 431 } else if (result == EGL_TIMEOUT_EXPIRED_KHR) { 432 ST_LOGE("dequeueBuffer: timeout waiting for fence"); 433 } 434 eglDestroySyncKHR(dpy, eglFence); 435 } 436 437 ST_LOGV("dequeueBuffer: returning slot=%d/%llu buf=%p flags=%#x", *outBuf, 438 mSlots[*outBuf].mFrameNumber, 439 mSlots[*outBuf].mGraphicBuffer->handle, returnFlags); 440 441 return returnFlags; 442} 443 444status_t BufferQueue::setSynchronousMode(bool enabled) { 445 ATRACE_CALL(); 446 ST_LOGV("setSynchronousMode: enabled=%d", enabled); 447 Mutex::Autolock lock(mMutex); 448 449 if (mAbandoned) { 450 ST_LOGE("setSynchronousMode: BufferQueue has been abandoned!"); 451 return NO_INIT; 452 } 453 454 status_t err = OK; 455 if (!mAllowSynchronousMode && enabled) 456 return err; 457 458 if (!enabled) { 459 // going to asynchronous mode, drain the queue 460 err = drainQueueLocked(); 461 if (err != NO_ERROR) 462 return err; 463 } 464 465 if (mSynchronousMode != enabled) { 466 // - if we're going to asynchronous mode, the queue is guaranteed to be 467 // empty here 468 // - if the client set the number of buffers, we're guaranteed that 469 // we have at least 3 (because we don't allow less) 470 mSynchronousMode = enabled; 471 mDequeueCondition.broadcast(); 472 } 473 return err; 474} 475 476status_t BufferQueue::queueBuffer(int buf, 477 const QueueBufferInput& input, QueueBufferOutput* output) { 478 ATRACE_CALL(); 479 ATRACE_BUFFER_INDEX(buf); 480 481 Rect crop; 482 uint32_t transform; 483 int scalingMode; 484 int64_t timestamp; 485 sp<Fence> fence; 486 487 input.deflate(×tamp, &crop, &scalingMode, &transform, &fence); 488 489 if (fence == NULL) { 490 ST_LOGE("queueBuffer: fence is NULL"); 491 return BAD_VALUE; 492 } 493 494 switch (scalingMode) { 495 case NATIVE_WINDOW_SCALING_MODE_FREEZE: 496 case NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW: 497 case NATIVE_WINDOW_SCALING_MODE_SCALE_CROP: 498 case NATIVE_WINDOW_SCALING_MODE_NO_SCALE_CROP: 499 break; 500 default: 501 ST_LOGE("unknown scaling mode: %d", scalingMode); 502 return -EINVAL; 503 } 504 505 sp<ConsumerListener> listener; 506 507 { // scope for the lock 508 Mutex::Autolock lock(mMutex); 509 510 if (mAbandoned) { 511 ST_LOGE("queueBuffer: BufferQueue has been abandoned!"); 512 return NO_INIT; 513 } 514 int maxBufferCount = getMaxBufferCountLocked(); 515 if (buf < 0 || buf >= maxBufferCount) { 516 ST_LOGE("queueBuffer: slot index out of range [0, %d]: %d", 517 maxBufferCount, buf); 518 return -EINVAL; 519 } else if (mSlots[buf].mBufferState != BufferSlot::DEQUEUED) { 520 ST_LOGE("queueBuffer: slot %d is not owned by the client " 521 "(state=%d)", buf, mSlots[buf].mBufferState); 522 return -EINVAL; 523 } else if (!mSlots[buf].mRequestBufferCalled) { 524 ST_LOGE("queueBuffer: slot %d was enqueued without requesting a " 525 "buffer", buf); 526 return -EINVAL; 527 } 528 529 ST_LOGV("queueBuffer: slot=%d/%llu time=%#llx crop=[%d,%d,%d,%d] " 530 "tr=%#x scale=%s", 531 buf, mFrameCounter + 1, timestamp, 532 crop.left, crop.top, crop.right, crop.bottom, 533 transform, scalingModeName(scalingMode)); 534 535 const sp<GraphicBuffer>& graphicBuffer(mSlots[buf].mGraphicBuffer); 536 Rect bufferRect(graphicBuffer->getWidth(), graphicBuffer->getHeight()); 537 Rect croppedCrop; 538 crop.intersect(bufferRect, &croppedCrop); 539 if (croppedCrop != crop) { 540 ST_LOGE("queueBuffer: crop rect is not contained within the " 541 "buffer in slot %d", buf); 542 return -EINVAL; 543 } 544 545 mSlots[buf].mFence = fence; 546 mSlots[buf].mBufferState = BufferSlot::QUEUED; 547 mFrameCounter++; 548 mSlots[buf].mFrameNumber = mFrameCounter; 549 550 BufferItem item; 551 item.mAcquireCalled = mSlots[buf].mAcquireCalled; 552 item.mGraphicBuffer = mSlots[buf].mGraphicBuffer; 553 item.mCrop = crop; 554 item.mTransform = transform; 555 item.mScalingMode = scalingMode; 556 item.mTimestamp = timestamp; 557 item.mFrameNumber = mFrameCounter; 558 item.mBuf = buf; 559 item.mFence = fence; 560 561 if (mSynchronousMode) { 562 // In synchronous mode we queue all buffers in a FIFO. 563 mQueue.push_back(item); 564 565 // Synchronous mode always signals that an additional frame should 566 // be consumed. 567 listener = mConsumerListener; 568 } else { 569 // In asynchronous mode we only keep the most recent buffer. 570 if (mQueue.empty()) { 571 mQueue.push_back(item); 572 573 // Asynchronous mode only signals that a frame should be 574 // consumed if no previous frame was pending. If a frame were 575 // pending then the consumer would have already been notified. 576 listener = mConsumerListener; 577 } else { 578 Fifo::iterator front(mQueue.begin()); 579 // buffer slot currently queued is marked free if still tracked 580 if (stillTracking(front)) { 581 mSlots[front->mBuf].mBufferState = BufferSlot::FREE; 582 } 583 // and we record the new buffer index in the queued list 584 *front = item; 585 } 586 } 587 588 mBufferHasBeenQueued = true; 589 mDequeueCondition.broadcast(); 590 591 output->inflate(mDefaultWidth, mDefaultHeight, mTransformHint, 592 mQueue.size()); 593 594 ATRACE_INT(mConsumerName.string(), mQueue.size()); 595 } // scope for the lock 596 597 // call back without lock held 598 if (listener != 0) { 599 listener->onFrameAvailable(); 600 } 601 return NO_ERROR; 602} 603 604void BufferQueue::cancelBuffer(int buf, const sp<Fence>& fence) { 605 ATRACE_CALL(); 606 ST_LOGV("cancelBuffer: slot=%d", buf); 607 Mutex::Autolock lock(mMutex); 608 609 if (mAbandoned) { 610 ST_LOGW("cancelBuffer: BufferQueue has been abandoned!"); 611 return; 612 } 613 614 int maxBufferCount = getMaxBufferCountLocked(); 615 if (buf < 0 || buf >= maxBufferCount) { 616 ST_LOGE("cancelBuffer: slot index out of range [0, %d]: %d", 617 maxBufferCount, buf); 618 return; 619 } else if (mSlots[buf].mBufferState != BufferSlot::DEQUEUED) { 620 ST_LOGE("cancelBuffer: slot %d is not owned by the client (state=%d)", 621 buf, mSlots[buf].mBufferState); 622 return; 623 } else if (fence == NULL) { 624 ST_LOGE("cancelBuffer: fence is NULL"); 625 return; 626 } 627 mSlots[buf].mBufferState = BufferSlot::FREE; 628 mSlots[buf].mFrameNumber = 0; 629 mSlots[buf].mFence = fence; 630 mDequeueCondition.broadcast(); 631} 632 633status_t BufferQueue::connect(int api, QueueBufferOutput* output) { 634 ATRACE_CALL(); 635 ST_LOGV("connect: api=%d", api); 636 Mutex::Autolock lock(mMutex); 637 638 if (mAbandoned) { 639 ST_LOGE("connect: BufferQueue has been abandoned!"); 640 return NO_INIT; 641 } 642 643 if (mConsumerListener == NULL) { 644 ST_LOGE("connect: BufferQueue has no consumer!"); 645 return NO_INIT; 646 } 647 648 int err = NO_ERROR; 649 switch (api) { 650 case NATIVE_WINDOW_API_EGL: 651 case NATIVE_WINDOW_API_CPU: 652 case NATIVE_WINDOW_API_MEDIA: 653 case NATIVE_WINDOW_API_CAMERA: 654 if (mConnectedApi != NO_CONNECTED_API) { 655 ST_LOGE("connect: already connected (cur=%d, req=%d)", 656 mConnectedApi, api); 657 err = -EINVAL; 658 } else { 659 mConnectedApi = api; 660 output->inflate(mDefaultWidth, mDefaultHeight, mTransformHint, 661 mQueue.size()); 662 } 663 break; 664 default: 665 err = -EINVAL; 666 break; 667 } 668 669 mBufferHasBeenQueued = false; 670 671 return err; 672} 673 674status_t BufferQueue::disconnect(int api) { 675 ATRACE_CALL(); 676 ST_LOGV("disconnect: api=%d", api); 677 678 int err = NO_ERROR; 679 sp<ConsumerListener> listener; 680 681 { // Scope for the lock 682 Mutex::Autolock lock(mMutex); 683 684 if (mAbandoned) { 685 // it is not really an error to disconnect after the surface 686 // has been abandoned, it should just be a no-op. 687 return NO_ERROR; 688 } 689 690 switch (api) { 691 case NATIVE_WINDOW_API_EGL: 692 case NATIVE_WINDOW_API_CPU: 693 case NATIVE_WINDOW_API_MEDIA: 694 case NATIVE_WINDOW_API_CAMERA: 695 if (mConnectedApi == api) { 696 drainQueueAndFreeBuffersLocked(); 697 mConnectedApi = NO_CONNECTED_API; 698 mDequeueCondition.broadcast(); 699 listener = mConsumerListener; 700 } else { 701 ST_LOGE("disconnect: connected to another api (cur=%d, req=%d)", 702 mConnectedApi, api); 703 err = -EINVAL; 704 } 705 break; 706 default: 707 ST_LOGE("disconnect: unknown API %d", api); 708 err = -EINVAL; 709 break; 710 } 711 } 712 713 if (listener != NULL) { 714 listener->onBuffersReleased(); 715 } 716 717 return err; 718} 719 720void BufferQueue::dump(String8& result) const { 721 BufferQueue::dump(result, ""); 722} 723 724void BufferQueue::dump(String8& result, const char* prefix) const { 725 Mutex::Autolock _l(mMutex); 726 727 String8 fifo; 728 int fifoSize = 0; 729 Fifo::const_iterator i(mQueue.begin()); 730 while (i != mQueue.end()) { 731 fifo.appendFormat("%02d:%p crop=[%d,%d,%d,%d], " 732 "xform=0x%02x, time=%#llx, scale=%s\n", 733 i->mBuf, i->mGraphicBuffer.get(), 734 i->mCrop.left, i->mCrop.top, i->mCrop.right, 735 i->mCrop.bottom, i->mTransform, i->mTimestamp, 736 scalingModeName(i->mScalingMode) 737 ); 738 i++; 739 fifoSize++; 740 } 741 742 int maxBufferCount = getMaxBufferCountLocked(); 743 744 result.appendFormat( 745 "%s-BufferQueue maxBufferCount=%d, mSynchronousMode=%d, default-size=[%dx%d], " 746 "default-format=%d, transform-hint=%02x, FIFO(%d)={%s}\n", 747 prefix, maxBufferCount, mSynchronousMode, mDefaultWidth, 748 mDefaultHeight, mDefaultBufferFormat, mTransformHint, 749 fifoSize, fifo.string()); 750 751 struct { 752 const char * operator()(int state) const { 753 switch (state) { 754 case BufferSlot::DEQUEUED: return "DEQUEUED"; 755 case BufferSlot::QUEUED: return "QUEUED"; 756 case BufferSlot::FREE: return "FREE"; 757 case BufferSlot::ACQUIRED: return "ACQUIRED"; 758 default: return "Unknown"; 759 } 760 } 761 } stateName; 762 763 for (int i=0 ; i<maxBufferCount ; i++) { 764 const BufferSlot& slot(mSlots[i]); 765 result.appendFormat( 766 "%s%s[%02d:%p] state=%-8s", 767 prefix, (slot.mBufferState == BufferSlot::ACQUIRED)?">":" ", i, 768 slot.mGraphicBuffer.get(), 769 stateName(slot.mBufferState) 770 ); 771 772 const sp<GraphicBuffer>& buf(slot.mGraphicBuffer); 773 if (buf != NULL) { 774 result.appendFormat( 775 ", %p [%4ux%4u:%4u,%3X]", 776 buf->handle, buf->width, buf->height, buf->stride, 777 buf->format); 778 } 779 result.append("\n"); 780 } 781} 782 783void BufferQueue::freeBufferLocked(int slot) { 784 ST_LOGV("freeBufferLocked: slot=%d", slot); 785 mSlots[slot].mGraphicBuffer = 0; 786 if (mSlots[slot].mBufferState == BufferSlot::ACQUIRED) { 787 mSlots[slot].mNeedsCleanupOnRelease = true; 788 } 789 mSlots[slot].mBufferState = BufferSlot::FREE; 790 mSlots[slot].mFrameNumber = 0; 791 mSlots[slot].mAcquireCalled = false; 792 793 // destroy fence as BufferQueue now takes ownership 794 if (mSlots[slot].mEglFence != EGL_NO_SYNC_KHR) { 795 eglDestroySyncKHR(mSlots[slot].mEglDisplay, mSlots[slot].mEglFence); 796 mSlots[slot].mEglFence = EGL_NO_SYNC_KHR; 797 } 798 mSlots[slot].mFence = Fence::NO_FENCE; 799} 800 801void BufferQueue::freeAllBuffersLocked() { 802 ALOGD_IF(!mQueue.isEmpty(), 803 "freeAllBuffersLocked called with non-empty mQueue"); 804 mBufferHasBeenQueued = false; 805 for (int i = 0; i < NUM_BUFFER_SLOTS; i++) { 806 freeBufferLocked(i); 807 } 808} 809 810status_t BufferQueue::acquireBuffer(BufferItem *buffer, nsecs_t presentWhen) { 811 ATRACE_CALL(); 812 Mutex::Autolock _l(mMutex); 813 814 // Check that the consumer doesn't currently have the maximum number of 815 // buffers acquired. We allow the max buffer count to be exceeded by one 816 // buffer, so that the consumer can successfully set up the newly acquired 817 // buffer before releasing the old one. 818 int numAcquiredBuffers = 0; 819 for (int i = 0; i < NUM_BUFFER_SLOTS; i++) { 820 if (mSlots[i].mBufferState == BufferSlot::ACQUIRED) { 821 numAcquiredBuffers++; 822 } 823 } 824 if (numAcquiredBuffers >= mMaxAcquiredBufferCount+1) { 825 ST_LOGE("acquireBuffer: max acquired buffer count reached: %d (max=%d)", 826 numAcquiredBuffers, mMaxAcquiredBufferCount); 827 return INVALID_OPERATION; 828 } 829 830 // check if queue is empty 831 // In asynchronous mode the list is guaranteed to be one buffer 832 // deep, while in synchronous mode we use the oldest buffer. 833 if (mQueue.empty()) { 834 return NO_BUFFER_AVAILABLE; 835 } 836 837 Fifo::iterator front(mQueue.begin()); 838 int buf = front->mBuf; 839 840 // Compare the buffer's desired presentation time to the predicted 841 // actual display time. 842 // 843 // The "presentWhen" argument indicates when the buffer is expected 844 // to be presented on-screen. If the buffer's desired-present time 845 // is earlier (less) than presentWhen, meaning it'll be displayed 846 // on time or possibly late, we acquire and return it. If we don't want 847 // to display it until after the presentWhen time, we return PRESENT_LATER 848 // without acquiring it. 849 // 850 // To be safe, we don't refuse to acquire the buffer if presentWhen is 851 // more than one second in the future beyond the desired present time 852 // (i.e. we'd be holding the buffer for a really long time). 853 const int MAX_FUTURE_NSEC = 1000000000ULL; 854 nsecs_t desiredPresent = front->mTimestamp; 855 if (presentWhen != 0 && desiredPresent > presentWhen && 856 desiredPresent - presentWhen < MAX_FUTURE_NSEC) 857 { 858 ALOGV("pts defer: des=%lld when=%lld (%lld) now=%lld", 859 desiredPresent, presentWhen, desiredPresent - presentWhen, 860 systemTime(CLOCK_MONOTONIC)); 861 return PRESENT_LATER; 862 } 863 if (presentWhen != 0) { 864 ALOGV("pts accept: %p[%d] sig=%lld des=%lld when=%lld (%lld)", 865 mSlots, buf, mSlots[buf].mFence->getSignalTime(), 866 desiredPresent, presentWhen, desiredPresent - presentWhen); 867 } 868 869 *buffer = *front; 870 ATRACE_BUFFER_INDEX(buf); 871 872 ST_LOGV("acquireBuffer: acquiring { slot=%d/%llu, buffer=%p }", 873 front->mBuf, front->mFrameNumber, 874 front->mGraphicBuffer->handle); 875 // if front buffer still being tracked update slot state 876 if (stillTracking(front)) { 877 mSlots[buf].mAcquireCalled = true; 878 mSlots[buf].mNeedsCleanupOnRelease = false; 879 mSlots[buf].mBufferState = BufferSlot::ACQUIRED; 880 mSlots[buf].mFence = Fence::NO_FENCE; 881 } 882 883 // If the buffer has previously been acquired by the consumer, set 884 // mGraphicBuffer to NULL to avoid unnecessarily remapping this 885 // buffer on the consumer side. 886 if (buffer->mAcquireCalled) { 887 buffer->mGraphicBuffer = NULL; 888 } 889 890 mQueue.erase(front); 891 mDequeueCondition.broadcast(); 892 893 ATRACE_INT(mConsumerName.string(), mQueue.size()); 894 895 return NO_ERROR; 896} 897 898status_t BufferQueue::releaseBuffer( 899 int buf, uint64_t frameNumber, EGLDisplay display, 900 EGLSyncKHR eglFence, const sp<Fence>& fence) { 901 ATRACE_CALL(); 902 ATRACE_BUFFER_INDEX(buf); 903 904 Mutex::Autolock _l(mMutex); 905 906 if (buf == INVALID_BUFFER_SLOT || fence == NULL) { 907 return BAD_VALUE; 908 } 909 910 // Check if this buffer slot is on the queue 911 bool slotQueued = false; 912 Fifo::iterator front(mQueue.begin()); 913 while (front != mQueue.end() && !slotQueued) { 914 if (front->mBuf == buf) 915 slotQueued = true; 916 front++; 917 } 918 919 // If the frame number has changed because buffer has been reallocated, 920 // we can ignore this releaseBuffer for the old buffer. 921 if (frameNumber != mSlots[buf].mFrameNumber) { 922 // This should only occur if new buffer is still in the queue 923 ALOGE_IF(!slotQueued, 924 "received old buffer(#%lld) after new buffer(#%lld) on same " 925 "slot #%d already acquired", frameNumber, 926 mSlots[buf].mFrameNumber, buf); 927 return STALE_BUFFER_SLOT; 928 } 929 // this should never happen 930 ALOGE_IF(slotQueued, 931 "received new buffer(#%lld) on slot #%d that has not yet been " 932 "acquired", frameNumber, buf); 933 934 // The buffer can now only be released if its in the acquired state 935 if (mSlots[buf].mBufferState == BufferSlot::ACQUIRED) { 936 mSlots[buf].mEglDisplay = display; 937 mSlots[buf].mEglFence = eglFence; 938 mSlots[buf].mFence = fence; 939 mSlots[buf].mBufferState = BufferSlot::FREE; 940 } else if (mSlots[buf].mNeedsCleanupOnRelease) { 941 ST_LOGV("releasing a stale buf %d its state was %d", buf, mSlots[buf].mBufferState); 942 mSlots[buf].mNeedsCleanupOnRelease = false; 943 return STALE_BUFFER_SLOT; 944 } else { 945 ST_LOGE("attempted to release buf %d but its state was %d", buf, mSlots[buf].mBufferState); 946 return -EINVAL; 947 } 948 949 mDequeueCondition.broadcast(); 950 return NO_ERROR; 951} 952 953status_t BufferQueue::consumerConnect(const sp<ConsumerListener>& consumerListener) { 954 ST_LOGV("consumerConnect"); 955 Mutex::Autolock lock(mMutex); 956 957 if (mAbandoned) { 958 ST_LOGE("consumerConnect: BufferQueue has been abandoned!"); 959 return NO_INIT; 960 } 961 if (consumerListener == NULL) { 962 ST_LOGE("consumerConnect: consumerListener may not be NULL"); 963 return BAD_VALUE; 964 } 965 966 mConsumerListener = consumerListener; 967 968 return NO_ERROR; 969} 970 971status_t BufferQueue::consumerDisconnect() { 972 ST_LOGV("consumerDisconnect"); 973 Mutex::Autolock lock(mMutex); 974 975 if (mConsumerListener == NULL) { 976 ST_LOGE("consumerDisconnect: No consumer is connected!"); 977 return -EINVAL; 978 } 979 980 mAbandoned = true; 981 mConsumerListener = NULL; 982 mQueue.clear(); 983 freeAllBuffersLocked(); 984 mDequeueCondition.broadcast(); 985 return NO_ERROR; 986} 987 988status_t BufferQueue::getReleasedBuffers(uint32_t* slotMask) { 989 ST_LOGV("getReleasedBuffers"); 990 Mutex::Autolock lock(mMutex); 991 992 if (mAbandoned) { 993 ST_LOGE("getReleasedBuffers: BufferQueue has been abandoned!"); 994 return NO_INIT; 995 } 996 997 uint32_t mask = 0; 998 for (int i = 0; i < NUM_BUFFER_SLOTS; i++) { 999 if (!mSlots[i].mAcquireCalled) { 1000 mask |= 1 << i; 1001 } 1002 } 1003 1004 // Remove buffers in flight (on the queue) from the mask where acquire has 1005 // been called, as the consumer will not receive the buffer address, so 1006 // it should not free these slots. 1007 Fifo::iterator front(mQueue.begin()); 1008 while (front != mQueue.end()) { 1009 if (front->mAcquireCalled) 1010 mask &= ~(1 << front->mBuf); 1011 front++; 1012 } 1013 1014 *slotMask = mask; 1015 1016 ST_LOGV("getReleasedBuffers: returning mask %#x", mask); 1017 return NO_ERROR; 1018} 1019 1020status_t BufferQueue::setDefaultBufferSize(uint32_t w, uint32_t h) 1021{ 1022 ST_LOGV("setDefaultBufferSize: w=%d, h=%d", w, h); 1023 if (!w || !h) { 1024 ST_LOGE("setDefaultBufferSize: dimensions cannot be 0 (w=%d, h=%d)", 1025 w, h); 1026 return BAD_VALUE; 1027 } 1028 1029 Mutex::Autolock lock(mMutex); 1030 mDefaultWidth = w; 1031 mDefaultHeight = h; 1032 return NO_ERROR; 1033} 1034 1035status_t BufferQueue::setDefaultMaxBufferCount(int bufferCount) { 1036 ATRACE_CALL(); 1037 Mutex::Autolock lock(mMutex); 1038 return setDefaultMaxBufferCountLocked(bufferCount); 1039} 1040 1041status_t BufferQueue::setMaxAcquiredBufferCount(int maxAcquiredBuffers) { 1042 ATRACE_CALL(); 1043 Mutex::Autolock lock(mMutex); 1044 if (maxAcquiredBuffers < 1 || maxAcquiredBuffers > MAX_MAX_ACQUIRED_BUFFERS) { 1045 ST_LOGE("setMaxAcquiredBufferCount: invalid count specified: %d", 1046 maxAcquiredBuffers); 1047 return BAD_VALUE; 1048 } 1049 if (mConnectedApi != NO_CONNECTED_API) { 1050 return INVALID_OPERATION; 1051 } 1052 mMaxAcquiredBufferCount = maxAcquiredBuffers; 1053 return NO_ERROR; 1054} 1055 1056status_t BufferQueue::drainQueueLocked() { 1057 while (mSynchronousMode && mQueue.size() > 1) { 1058 mDequeueCondition.wait(mMutex); 1059 if (mAbandoned) { 1060 ST_LOGE("drainQueueLocked: BufferQueue has been abandoned!"); 1061 return NO_INIT; 1062 } 1063 if (mConnectedApi == NO_CONNECTED_API) { 1064 ST_LOGE("drainQueueLocked: BufferQueue is not connected!"); 1065 return NO_INIT; 1066 } 1067 } 1068 return NO_ERROR; 1069} 1070 1071status_t BufferQueue::drainQueueAndFreeBuffersLocked() { 1072 status_t err = drainQueueLocked(); 1073 if (err == NO_ERROR) { 1074 freeAllBuffersLocked(); 1075 } 1076 return err; 1077} 1078 1079int BufferQueue::getMinMaxBufferCountLocked() const { 1080 return getMinUndequeuedBufferCountLocked() + 1; 1081} 1082 1083int BufferQueue::getMinUndequeuedBufferCountLocked() const { 1084 return mSynchronousMode ? mMaxAcquiredBufferCount : 1085 mMaxAcquiredBufferCount + 1; 1086} 1087 1088int BufferQueue::getMaxBufferCountLocked() const { 1089 int minMaxBufferCount = getMinMaxBufferCountLocked(); 1090 1091 int maxBufferCount = mDefaultMaxBufferCount; 1092 if (maxBufferCount < minMaxBufferCount) { 1093 maxBufferCount = minMaxBufferCount; 1094 } 1095 if (mOverrideMaxBufferCount != 0) { 1096 assert(mOverrideMaxBufferCount >= minMaxBufferCount); 1097 maxBufferCount = mOverrideMaxBufferCount; 1098 } 1099 1100 // Any buffers that are dequeued by the producer or sitting in the queue 1101 // waiting to be consumed need to have their slots preserved. Such 1102 // buffers will temporarily keep the max buffer count up until the slots 1103 // no longer need to be preserved. 1104 for (int i = maxBufferCount; i < NUM_BUFFER_SLOTS; i++) { 1105 BufferSlot::BufferState state = mSlots[i].mBufferState; 1106 if (state == BufferSlot::QUEUED || state == BufferSlot::DEQUEUED) { 1107 maxBufferCount = i + 1; 1108 } 1109 } 1110 1111 return maxBufferCount; 1112} 1113 1114bool BufferQueue::stillTracking(const BufferItem *item) const { 1115 const BufferSlot &slot = mSlots[item->mBuf]; 1116 1117 ST_LOGV("stillTracking?: item: { slot=%d/%llu, buffer=%p }, " 1118 "slot: { slot=%d/%llu, buffer=%p }", 1119 item->mBuf, item->mFrameNumber, 1120 (item->mGraphicBuffer.get() ? item->mGraphicBuffer->handle : 0), 1121 item->mBuf, slot.mFrameNumber, 1122 (slot.mGraphicBuffer.get() ? slot.mGraphicBuffer->handle : 0)); 1123 1124 // Compare item with its original buffer slot. We can check the slot 1125 // as the buffer would not be moved to a different slot by the producer. 1126 return (slot.mGraphicBuffer != NULL && 1127 item->mGraphicBuffer->handle == slot.mGraphicBuffer->handle); 1128} 1129 1130BufferQueue::ProxyConsumerListener::ProxyConsumerListener( 1131 const wp<BufferQueue::ConsumerListener>& consumerListener): 1132 mConsumerListener(consumerListener) {} 1133 1134BufferQueue::ProxyConsumerListener::~ProxyConsumerListener() {} 1135 1136void BufferQueue::ProxyConsumerListener::onFrameAvailable() { 1137 sp<BufferQueue::ConsumerListener> listener(mConsumerListener.promote()); 1138 if (listener != NULL) { 1139 listener->onFrameAvailable(); 1140 } 1141} 1142 1143void BufferQueue::ProxyConsumerListener::onBuffersReleased() { 1144 sp<BufferQueue::ConsumerListener> listener(mConsumerListener.promote()); 1145 if (listener != NULL) { 1146 listener->onBuffersReleased(); 1147 } 1148} 1149 1150}; // namespace android 1151