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