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