BufferQueue.cpp revision 207c1e287c129e7ebf679a3aaf2076c3c47c1afb
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#include <utils/CallStack.h> 34 35// Macros for including the BufferQueue name in log messages 36#define ST_LOGV(x, ...) ALOGV("[%s] "x, mConsumerName.string(), ##__VA_ARGS__) 37#define ST_LOGD(x, ...) ALOGD("[%s] "x, mConsumerName.string(), ##__VA_ARGS__) 38#define ST_LOGI(x, ...) ALOGI("[%s] "x, mConsumerName.string(), ##__VA_ARGS__) 39#define ST_LOGW(x, ...) ALOGW("[%s] "x, mConsumerName.string(), ##__VA_ARGS__) 40#define ST_LOGE(x, ...) ALOGE("[%s] "x, mConsumerName.string(), ##__VA_ARGS__) 41 42#define ATRACE_BUFFER_INDEX(index) \ 43 if (ATRACE_ENABLED()) { \ 44 char ___traceBuf[1024]; \ 45 snprintf(___traceBuf, 1024, "%s: %d", mConsumerName.string(), \ 46 (index)); \ 47 android::ScopedTrace ___bufTracer(ATRACE_TAG, ___traceBuf); \ 48 } 49 50namespace android { 51 52// Get an ID that's unique within this process. 53static int32_t createProcessUniqueId() { 54 static volatile int32_t globalCounter = 0; 55 return android_atomic_inc(&globalCounter); 56} 57 58static const char* scalingModeName(int scalingMode) { 59 switch (scalingMode) { 60 case NATIVE_WINDOW_SCALING_MODE_FREEZE: return "FREEZE"; 61 case NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW: return "SCALE_TO_WINDOW"; 62 case NATIVE_WINDOW_SCALING_MODE_SCALE_CROP: return "SCALE_CROP"; 63 default: return "Unknown"; 64 } 65} 66 67BufferQueue::BufferQueue(const sp<IGraphicBufferAlloc>& allocator) : 68 mDefaultWidth(1), 69 mDefaultHeight(1), 70 mMaxAcquiredBufferCount(1), 71 mDefaultMaxBufferCount(2), 72 mOverrideMaxBufferCount(0), 73 mConsumerControlledByApp(false), 74 mDequeueBufferCannotBlock(false), 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 for (int i=0 ; i<NUM_BUFFER_SLOTS; i++) { 155 if (mSlots[i].mBufferState == BufferSlot::DEQUEUED) { 156 ST_LOGE("setBufferCount: client owns some buffers"); 157 return -EINVAL; 158 } 159 } 160 161 if (bufferCount == 0) { 162 mOverrideMaxBufferCount = 0; 163 mDequeueCondition.broadcast(); 164 return NO_ERROR; 165 } 166 167 // fine to assume async to false before we're setting the buffer count 168 const int minBufferSlots = getMinMaxBufferCountLocked(false); 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 = getMinUndequeuedBufferCount(false); 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 if (slot < 0 || slot >= NUM_BUFFER_SLOTS) { 234 ST_LOGE("requestBuffer: slot index out of range [0, %d]: %d", 235 NUM_BUFFER_SLOTS, slot); 236 return BAD_VALUE; 237 } else if (mSlots[slot].mBufferState != BufferSlot::DEQUEUED) { 238 ST_LOGE("requestBuffer: slot %d is not owned by the client (state=%d)", 239 slot, mSlots[slot].mBufferState); 240 return BAD_VALUE; 241 } 242 mSlots[slot].mRequestBufferCalled = true; 243 *buf = mSlots[slot].mGraphicBuffer; 244 return NO_ERROR; 245} 246 247status_t BufferQueue::dequeueBuffer(int *outBuf, sp<Fence>* outFence, bool async, 248 uint32_t w, uint32_t h, uint32_t format, uint32_t usage) { 249 ATRACE_CALL(); 250 ST_LOGV("dequeueBuffer: w=%d h=%d fmt=%#x usage=%#x", w, h, format, usage); 251 252 if ((w && !h) || (!w && h)) { 253 ST_LOGE("dequeueBuffer: invalid size: w=%u, h=%u", w, h); 254 return BAD_VALUE; 255 } 256 257 status_t returnFlags(OK); 258 EGLDisplay dpy = EGL_NO_DISPLAY; 259 EGLSyncKHR eglFence = EGL_NO_SYNC_KHR; 260 261 { // Scope for the lock 262 Mutex::Autolock lock(mMutex); 263 264 if (format == 0) { 265 format = mDefaultBufferFormat; 266 } 267 // turn on usage bits the consumer requested 268 usage |= mConsumerUsageBits; 269 270 int found = -1; 271 int dequeuedCount = 0; 272 bool tryAgain = true; 273 while (tryAgain) { 274 if (mAbandoned) { 275 ST_LOGE("dequeueBuffer: BufferQueue has been abandoned!"); 276 return NO_INIT; 277 } 278 279 const int maxBufferCount = getMaxBufferCountLocked(async); 280 if (async && mOverrideMaxBufferCount) { 281 // FIXME: some drivers are manually setting the buffer-count (which they 282 // shouldn't), so we do this extra test here to handle that case. 283 // This is TEMPORARY, until we get this fixed. 284 if (mOverrideMaxBufferCount < maxBufferCount) { 285 ST_LOGE("dequeueBuffer: async mode is invalid with buffercount override"); 286 return BAD_VALUE; 287 } 288 } 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 = getMinUndequeuedBufferCount(async); 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 if (mDequeueBufferCannotBlock) { 352 ST_LOGE("dequeueBuffer: would block! returning an error instead."); 353 return WOULD_BLOCK; 354 } 355 mDequeueCondition.wait(mMutex); 356 } 357 } 358 359 360 if (found == INVALID_BUFFER_SLOT) { 361 // This should not happen. 362 ST_LOGE("dequeueBuffer: no available buffer slots"); 363 return -EBUSY; 364 } 365 366 const int buf = found; 367 *outBuf = found; 368 369 ATRACE_BUFFER_INDEX(buf); 370 371 const bool useDefaultSize = !w && !h; 372 if (useDefaultSize) { 373 // use the default size 374 w = mDefaultWidth; 375 h = mDefaultHeight; 376 } 377 378 mSlots[buf].mBufferState = BufferSlot::DEQUEUED; 379 380 const sp<GraphicBuffer>& buffer(mSlots[buf].mGraphicBuffer); 381 if ((buffer == NULL) || 382 (uint32_t(buffer->width) != w) || 383 (uint32_t(buffer->height) != h) || 384 (uint32_t(buffer->format) != format) || 385 ((uint32_t(buffer->usage) & usage) != usage)) 386 { 387 mSlots[buf].mAcquireCalled = false; 388 mSlots[buf].mGraphicBuffer = NULL; 389 mSlots[buf].mRequestBufferCalled = false; 390 mSlots[buf].mEglFence = EGL_NO_SYNC_KHR; 391 mSlots[buf].mFence = Fence::NO_FENCE; 392 mSlots[buf].mEglDisplay = EGL_NO_DISPLAY; 393 394 returnFlags |= IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION; 395 } 396 397 dpy = mSlots[buf].mEglDisplay; 398 eglFence = mSlots[buf].mEglFence; 399 *outFence = mSlots[buf].mFence; 400 mSlots[buf].mEglFence = EGL_NO_SYNC_KHR; 401 mSlots[buf].mFence = Fence::NO_FENCE; 402 } // end lock scope 403 404 if (returnFlags & IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION) { 405 status_t error; 406 sp<GraphicBuffer> graphicBuffer( 407 mGraphicBufferAlloc->createGraphicBuffer( 408 w, h, format, usage, &error)); 409 if (graphicBuffer == 0) { 410 ST_LOGE("dequeueBuffer: SurfaceComposer::createGraphicBuffer " 411 "failed"); 412 return error; 413 } 414 415 { // Scope for the lock 416 Mutex::Autolock lock(mMutex); 417 418 if (mAbandoned) { 419 ST_LOGE("dequeueBuffer: BufferQueue has been abandoned!"); 420 return NO_INIT; 421 } 422 423 mSlots[*outBuf].mFrameNumber = ~0; 424 mSlots[*outBuf].mGraphicBuffer = graphicBuffer; 425 } 426 } 427 428 if (eglFence != EGL_NO_SYNC_KHR) { 429 EGLint result = eglClientWaitSyncKHR(dpy, eglFence, 0, 1000000000); 430 // If something goes wrong, log the error, but return the buffer without 431 // synchronizing access to it. It's too late at this point to abort the 432 // dequeue operation. 433 if (result == EGL_FALSE) { 434 ST_LOGE("dequeueBuffer: error waiting for fence: %#x", eglGetError()); 435 } else if (result == EGL_TIMEOUT_EXPIRED_KHR) { 436 ST_LOGE("dequeueBuffer: timeout waiting for fence"); 437 } 438 eglDestroySyncKHR(dpy, eglFence); 439 } 440 441 ST_LOGV("dequeueBuffer: returning slot=%d/%llu buf=%p flags=%#x", *outBuf, 442 mSlots[*outBuf].mFrameNumber, 443 mSlots[*outBuf].mGraphicBuffer->handle, returnFlags); 444 445 return returnFlags; 446} 447 448status_t BufferQueue::queueBuffer(int buf, 449 const QueueBufferInput& input, QueueBufferOutput* output) { 450 ATRACE_CALL(); 451 ATRACE_BUFFER_INDEX(buf); 452 453 Rect crop; 454 uint32_t transform; 455 int scalingMode; 456 int64_t timestamp; 457 bool async; 458 sp<Fence> fence; 459 460 input.deflate(×tamp, &crop, &scalingMode, &transform, &async, &fence); 461 462 if (fence == NULL) { 463 ST_LOGE("queueBuffer: fence is NULL"); 464 return BAD_VALUE; 465 } 466 467 switch (scalingMode) { 468 case NATIVE_WINDOW_SCALING_MODE_FREEZE: 469 case NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW: 470 case NATIVE_WINDOW_SCALING_MODE_SCALE_CROP: 471 case NATIVE_WINDOW_SCALING_MODE_NO_SCALE_CROP: 472 break; 473 default: 474 ST_LOGE("unknown scaling mode: %d", scalingMode); 475 return -EINVAL; 476 } 477 478 sp<ConsumerListener> listener; 479 480 { // scope for the lock 481 Mutex::Autolock lock(mMutex); 482 483 if (mAbandoned) { 484 ST_LOGE("queueBuffer: BufferQueue has been abandoned!"); 485 return NO_INIT; 486 } 487 488 const int maxBufferCount = getMaxBufferCountLocked(async); 489 if (async && mOverrideMaxBufferCount) { 490 // FIXME: some drivers are manually setting the buffer-count (which they 491 // shouldn't), so we do this extra test here to handle that case. 492 // This is TEMPORARY, until we get this fixed. 493 if (mOverrideMaxBufferCount < maxBufferCount) { 494 ST_LOGE("queueBuffer: async mode is invalid with buffercount override"); 495 return BAD_VALUE; 496 } 497 } 498 if (buf < 0 || buf >= maxBufferCount) { 499 ST_LOGE("queueBuffer: slot index out of range [0, %d]: %d", 500 maxBufferCount, buf); 501 return -EINVAL; 502 } else if (mSlots[buf].mBufferState != BufferSlot::DEQUEUED) { 503 ST_LOGE("queueBuffer: slot %d is not owned by the client " 504 "(state=%d)", buf, mSlots[buf].mBufferState); 505 return -EINVAL; 506 } else if (!mSlots[buf].mRequestBufferCalled) { 507 ST_LOGE("queueBuffer: slot %d was enqueued without requesting a " 508 "buffer", buf); 509 return -EINVAL; 510 } 511 512 ST_LOGV("queueBuffer: slot=%d/%llu time=%#llx crop=[%d,%d,%d,%d] " 513 "tr=%#x scale=%s", 514 buf, mFrameCounter + 1, timestamp, 515 crop.left, crop.top, crop.right, crop.bottom, 516 transform, scalingModeName(scalingMode)); 517 518 const sp<GraphicBuffer>& graphicBuffer(mSlots[buf].mGraphicBuffer); 519 Rect bufferRect(graphicBuffer->getWidth(), graphicBuffer->getHeight()); 520 Rect croppedCrop; 521 crop.intersect(bufferRect, &croppedCrop); 522 if (croppedCrop != crop) { 523 ST_LOGE("queueBuffer: crop rect is not contained within the " 524 "buffer in slot %d", buf); 525 return -EINVAL; 526 } 527 528 mSlots[buf].mFence = fence; 529 mSlots[buf].mBufferState = BufferSlot::QUEUED; 530 mFrameCounter++; 531 mSlots[buf].mFrameNumber = mFrameCounter; 532 533 BufferItem item; 534 item.mAcquireCalled = mSlots[buf].mAcquireCalled; 535 item.mGraphicBuffer = mSlots[buf].mGraphicBuffer; 536 item.mCrop = crop; 537 item.mTransform = transform; 538 item.mScalingMode = scalingMode; 539 item.mTimestamp = timestamp; 540 item.mFrameNumber = mFrameCounter; 541 item.mBuf = buf; 542 item.mFence = fence; 543 item.mIsDroppable = mDequeueBufferCannotBlock || async; 544 545 if (mQueue.empty()) { 546 // when the queue is empty, we can ignore "mDequeueBufferCannotBlock", and 547 // simply queue this buffer. 548 mQueue.push_back(item); 549 listener = mConsumerListener; 550 } else { 551 // when the queue is not empty, we need to look at the front buffer 552 // state and see if we need to replace it. 553 Fifo::iterator front(mQueue.begin()); 554 if (front->mIsDroppable) { 555 // buffer slot currently queued is marked free if still tracked 556 if (stillTracking(front)) { 557 mSlots[front->mBuf].mBufferState = BufferSlot::FREE; 558 // reset the frame number of the freed buffer so that it is the first in 559 // line to be dequeued again. 560 mSlots[front->mBuf].mFrameNumber = 0; 561 } 562 // and we record the new buffer in the queued list 563 *front = item; 564 } else { 565 mQueue.push_back(item); 566 listener = mConsumerListener; 567 } 568 } 569 570 mBufferHasBeenQueued = true; 571 mDequeueCondition.broadcast(); 572 573 output->inflate(mDefaultWidth, mDefaultHeight, mTransformHint, 574 mQueue.size()); 575 576 ATRACE_INT(mConsumerName.string(), mQueue.size()); 577 } // scope for the lock 578 579 // call back without lock held 580 if (listener != 0) { 581 listener->onFrameAvailable(); 582 } 583 return NO_ERROR; 584} 585 586void BufferQueue::cancelBuffer(int buf, const sp<Fence>& fence) { 587 ATRACE_CALL(); 588 ST_LOGV("cancelBuffer: slot=%d", buf); 589 Mutex::Autolock lock(mMutex); 590 591 if (mAbandoned) { 592 ST_LOGW("cancelBuffer: BufferQueue has been abandoned!"); 593 return; 594 } 595 596 if (buf < 0 || buf >= NUM_BUFFER_SLOTS) { 597 ST_LOGE("cancelBuffer: slot index out of range [0, %d]: %d", 598 NUM_BUFFER_SLOTS, buf); 599 return; 600 } else if (mSlots[buf].mBufferState != BufferSlot::DEQUEUED) { 601 ST_LOGE("cancelBuffer: slot %d is not owned by the client (state=%d)", 602 buf, mSlots[buf].mBufferState); 603 return; 604 } else if (fence == NULL) { 605 ST_LOGE("cancelBuffer: fence is NULL"); 606 return; 607 } 608 mSlots[buf].mBufferState = BufferSlot::FREE; 609 mSlots[buf].mFrameNumber = 0; 610 mSlots[buf].mFence = fence; 611 mDequeueCondition.broadcast(); 612} 613 614status_t BufferQueue::connect(int api, bool producerControlledByApp, QueueBufferOutput* output) { 615 ATRACE_CALL(); 616 ST_LOGV("connect: api=%d", api); 617 Mutex::Autolock lock(mMutex); 618 619 if (mAbandoned) { 620 ST_LOGE("connect: BufferQueue has been abandoned!"); 621 return NO_INIT; 622 } 623 624 if (mConsumerListener == NULL) { 625 ST_LOGE("connect: BufferQueue has no consumer!"); 626 return NO_INIT; 627 } 628 629 int err = NO_ERROR; 630 switch (api) { 631 case NATIVE_WINDOW_API_EGL: 632 case NATIVE_WINDOW_API_CPU: 633 case NATIVE_WINDOW_API_MEDIA: 634 case NATIVE_WINDOW_API_CAMERA: 635 if (mConnectedApi != NO_CONNECTED_API) { 636 ST_LOGE("connect: already connected (cur=%d, req=%d)", 637 mConnectedApi, api); 638 err = -EINVAL; 639 } else { 640 mConnectedApi = api; 641 output->inflate(mDefaultWidth, mDefaultHeight, mTransformHint, 642 mQueue.size()); 643 } 644 break; 645 default: 646 err = -EINVAL; 647 break; 648 } 649 650 mBufferHasBeenQueued = false; 651 mDequeueBufferCannotBlock = mConsumerControlledByApp && producerControlledByApp; 652 653 return err; 654} 655 656status_t BufferQueue::disconnect(int api) { 657 ATRACE_CALL(); 658 ST_LOGV("disconnect: api=%d", api); 659 660 int err = NO_ERROR; 661 sp<ConsumerListener> listener; 662 663 { // Scope for the lock 664 Mutex::Autolock lock(mMutex); 665 666 if (mAbandoned) { 667 // it is not really an error to disconnect after the surface 668 // has been abandoned, it should just be a no-op. 669 return NO_ERROR; 670 } 671 672 switch (api) { 673 case NATIVE_WINDOW_API_EGL: 674 case NATIVE_WINDOW_API_CPU: 675 case NATIVE_WINDOW_API_MEDIA: 676 case NATIVE_WINDOW_API_CAMERA: 677 if (mConnectedApi == api) { 678 freeAllBuffersLocked(); 679 mConnectedApi = NO_CONNECTED_API; 680 mDequeueCondition.broadcast(); 681 listener = mConsumerListener; 682 } else { 683 ST_LOGE("disconnect: connected to another api (cur=%d, req=%d)", 684 mConnectedApi, api); 685 err = -EINVAL; 686 } 687 break; 688 default: 689 ST_LOGE("disconnect: unknown API %d", api); 690 err = -EINVAL; 691 break; 692 } 693 } 694 695 if (listener != NULL) { 696 listener->onBuffersReleased(); 697 } 698 699 return err; 700} 701 702void BufferQueue::dump(String8& result) const { 703 BufferQueue::dump(result, ""); 704} 705 706void BufferQueue::dump(String8& result, const char* prefix) const { 707 Mutex::Autolock _l(mMutex); 708 709 String8 fifo; 710 int fifoSize = 0; 711 Fifo::const_iterator i(mQueue.begin()); 712 while (i != mQueue.end()) { 713 fifo.appendFormat("%02d:%p crop=[%d,%d,%d,%d], " 714 "xform=0x%02x, time=%#llx, scale=%s\n", 715 i->mBuf, i->mGraphicBuffer.get(), 716 i->mCrop.left, i->mCrop.top, i->mCrop.right, 717 i->mCrop.bottom, i->mTransform, i->mTimestamp, 718 scalingModeName(i->mScalingMode) 719 ); 720 i++; 721 fifoSize++; 722 } 723 724 725 result.appendFormat( 726 "%s-BufferQueue mMaxAcquiredBufferCount=%d, mDequeueBufferCannotBlock=%d, default-size=[%dx%d], " 727 "default-format=%d, transform-hint=%02x, FIFO(%d)={%s}\n", 728 prefix, mMaxAcquiredBufferCount, mDequeueBufferCannotBlock, mDefaultWidth, 729 mDefaultHeight, mDefaultBufferFormat, mTransformHint, 730 fifoSize, fifo.string()); 731 732 struct { 733 const char * operator()(int state) const { 734 switch (state) { 735 case BufferSlot::DEQUEUED: return "DEQUEUED"; 736 case BufferSlot::QUEUED: return "QUEUED"; 737 case BufferSlot::FREE: return "FREE"; 738 case BufferSlot::ACQUIRED: return "ACQUIRED"; 739 default: return "Unknown"; 740 } 741 } 742 } stateName; 743 744 // just trim the free buffers to not spam the dump 745 int maxBufferCount = 0; 746 for (int i=NUM_BUFFER_SLOTS-1 ; i>=0 ; i--) { 747 const BufferSlot& slot(mSlots[i]); 748 if ((slot.mBufferState != BufferSlot::FREE) || (slot.mGraphicBuffer != NULL)) { 749 maxBufferCount = i+1; 750 break; 751 } 752 } 753 754 for (int i=0 ; i<maxBufferCount ; i++) { 755 const BufferSlot& slot(mSlots[i]); 756 const sp<GraphicBuffer>& buf(slot.mGraphicBuffer); 757 result.appendFormat( 758 "%s%s[%02d:%p] state=%-8s", 759 prefix, (slot.mBufferState == BufferSlot::ACQUIRED)?">":" ", i, buf.get(), 760 stateName(slot.mBufferState) 761 ); 762 763 if (buf != NULL) { 764 result.appendFormat( 765 ", %p [%4ux%4u:%4u,%3X]", 766 buf->handle, buf->width, buf->height, buf->stride, 767 buf->format); 768 } 769 result.append("\n"); 770 } 771} 772 773void BufferQueue::freeBufferLocked(int slot) { 774 ST_LOGV("freeBufferLocked: slot=%d", slot); 775 mSlots[slot].mGraphicBuffer = 0; 776 if (mSlots[slot].mBufferState == BufferSlot::ACQUIRED) { 777 mSlots[slot].mNeedsCleanupOnRelease = true; 778 } 779 mSlots[slot].mBufferState = BufferSlot::FREE; 780 mSlots[slot].mFrameNumber = 0; 781 mSlots[slot].mAcquireCalled = false; 782 783 // destroy fence as BufferQueue now takes ownership 784 if (mSlots[slot].mEglFence != EGL_NO_SYNC_KHR) { 785 eglDestroySyncKHR(mSlots[slot].mEglDisplay, mSlots[slot].mEglFence); 786 mSlots[slot].mEglFence = EGL_NO_SYNC_KHR; 787 } 788 mSlots[slot].mFence = Fence::NO_FENCE; 789} 790 791void BufferQueue::freeAllBuffersLocked() { 792 mBufferHasBeenQueued = false; 793 for (int i = 0; i < NUM_BUFFER_SLOTS; i++) { 794 freeBufferLocked(i); 795 } 796} 797 798status_t BufferQueue::acquireBuffer(BufferItem *buffer, nsecs_t presentWhen) { 799 ATRACE_CALL(); 800 Mutex::Autolock _l(mMutex); 801 802 // Check that the consumer doesn't currently have the maximum number of 803 // buffers acquired. We allow the max buffer count to be exceeded by one 804 // buffer, so that the consumer can successfully set up the newly acquired 805 // buffer before releasing the old one. 806 int numAcquiredBuffers = 0; 807 for (int i = 0; i < NUM_BUFFER_SLOTS; i++) { 808 if (mSlots[i].mBufferState == BufferSlot::ACQUIRED) { 809 numAcquiredBuffers++; 810 } 811 } 812 if (numAcquiredBuffers >= mMaxAcquiredBufferCount+1) { 813 ST_LOGE("acquireBuffer: max acquired buffer count reached: %d (max=%d)", 814 numAcquiredBuffers, mMaxAcquiredBufferCount); 815 return INVALID_OPERATION; 816 } 817 818 // check if queue is empty 819 // In asynchronous mode the list is guaranteed to be one buffer 820 // deep, while in synchronous mode we use the oldest buffer. 821 if (mQueue.empty()) { 822 return NO_BUFFER_AVAILABLE; 823 } 824 825 Fifo::iterator front(mQueue.begin()); 826 int buf = front->mBuf; 827 828 // Compare the buffer's desired presentation time to the predicted 829 // actual display time. 830 // 831 // The "presentWhen" argument indicates when the buffer is expected 832 // to be presented on-screen. If the buffer's desired-present time 833 // is earlier (less) than presentWhen, meaning it'll be displayed 834 // on time or possibly late, we acquire and return it. If we don't want 835 // to display it until after the presentWhen time, we return PRESENT_LATER 836 // without acquiring it. 837 // 838 // To be safe, we don't refuse to acquire the buffer if presentWhen is 839 // more than one second in the future beyond the desired present time 840 // (i.e. we'd be holding the buffer for a really long time). 841 const int MAX_FUTURE_NSEC = 1000000000ULL; 842 nsecs_t desiredPresent = front->mTimestamp; 843 if (presentWhen != 0 && desiredPresent > presentWhen && 844 desiredPresent - presentWhen < MAX_FUTURE_NSEC) 845 { 846 ST_LOGV("pts defer: des=%lld when=%lld (%lld) now=%lld", 847 desiredPresent, presentWhen, desiredPresent - presentWhen, 848 systemTime(CLOCK_MONOTONIC)); 849 return PRESENT_LATER; 850 } 851 if (presentWhen != 0) { 852 ST_LOGV("pts accept: %p[%d] sig=%lld des=%lld when=%lld (%lld)", 853 mSlots, buf, mSlots[buf].mFence->getSignalTime(), 854 desiredPresent, presentWhen, desiredPresent - presentWhen); 855 } 856 857 *buffer = *front; 858 ATRACE_BUFFER_INDEX(buf); 859 860 ST_LOGV("acquireBuffer: acquiring { slot=%d/%llu, buffer=%p }", 861 front->mBuf, front->mFrameNumber, 862 front->mGraphicBuffer->handle); 863 // if front buffer still being tracked update slot state 864 if (stillTracking(front)) { 865 mSlots[buf].mAcquireCalled = true; 866 mSlots[buf].mNeedsCleanupOnRelease = false; 867 mSlots[buf].mBufferState = BufferSlot::ACQUIRED; 868 mSlots[buf].mFence = Fence::NO_FENCE; 869 } 870 871 // If the buffer has previously been acquired by the consumer, set 872 // mGraphicBuffer to NULL to avoid unnecessarily remapping this 873 // buffer on the consumer side. 874 if (buffer->mAcquireCalled) { 875 buffer->mGraphicBuffer = NULL; 876 } 877 878 mQueue.erase(front); 879 mDequeueCondition.broadcast(); 880 881 ATRACE_INT(mConsumerName.string(), mQueue.size()); 882 883 return NO_ERROR; 884} 885 886status_t BufferQueue::releaseBuffer( 887 int buf, uint64_t frameNumber, EGLDisplay display, 888 EGLSyncKHR eglFence, const sp<Fence>& fence) { 889 ATRACE_CALL(); 890 ATRACE_BUFFER_INDEX(buf); 891 892 if (buf == INVALID_BUFFER_SLOT || fence == NULL) { 893 return BAD_VALUE; 894 } 895 896 Mutex::Autolock _l(mMutex); 897 898 // If the frame number has changed because buffer has been reallocated, 899 // we can ignore this releaseBuffer for the old buffer. 900 if (frameNumber != mSlots[buf].mFrameNumber) { 901 return STALE_BUFFER_SLOT; 902 } 903 904 905 // Internal state consistency checks: 906 // Make sure this buffers hasn't been queued while we were owning it (acquired) 907 Fifo::iterator front(mQueue.begin()); 908 Fifo::const_iterator const end(mQueue.end()); 909 while (front != end) { 910 if (front->mBuf == buf) { 911 LOG_ALWAYS_FATAL("[%s] received new buffer(#%lld) on slot #%d that has not yet been " 912 "acquired", mConsumerName.string(), frameNumber, buf); 913 break; // never reached 914 } 915 front++; 916 } 917 918 // The buffer can now only be released if its in the acquired state 919 if (mSlots[buf].mBufferState == BufferSlot::ACQUIRED) { 920 mSlots[buf].mEglDisplay = display; 921 mSlots[buf].mEglFence = eglFence; 922 mSlots[buf].mFence = fence; 923 mSlots[buf].mBufferState = BufferSlot::FREE; 924 } else if (mSlots[buf].mNeedsCleanupOnRelease) { 925 ST_LOGV("releasing a stale buf %d its state was %d", buf, mSlots[buf].mBufferState); 926 mSlots[buf].mNeedsCleanupOnRelease = false; 927 return STALE_BUFFER_SLOT; 928 } else { 929 ST_LOGE("attempted to release buf %d but its state was %d", buf, mSlots[buf].mBufferState); 930 return -EINVAL; 931 } 932 933 mDequeueCondition.broadcast(); 934 return NO_ERROR; 935} 936 937status_t BufferQueue::consumerConnect(const sp<ConsumerListener>& consumerListener, 938 bool controlledByApp) { 939 ST_LOGV("consumerConnect"); 940 Mutex::Autolock lock(mMutex); 941 942 if (mAbandoned) { 943 ST_LOGE("consumerConnect: BufferQueue has been abandoned!"); 944 return NO_INIT; 945 } 946 if (consumerListener == NULL) { 947 ST_LOGE("consumerConnect: consumerListener may not be NULL"); 948 return BAD_VALUE; 949 } 950 951 mConsumerListener = consumerListener; 952 mConsumerControlledByApp = controlledByApp; 953 954 return NO_ERROR; 955} 956 957status_t BufferQueue::consumerDisconnect() { 958 ST_LOGV("consumerDisconnect"); 959 Mutex::Autolock lock(mMutex); 960 961 if (mConsumerListener == NULL) { 962 ST_LOGE("consumerDisconnect: No consumer is connected!"); 963 return -EINVAL; 964 } 965 966 mAbandoned = true; 967 mConsumerListener = NULL; 968 mQueue.clear(); 969 freeAllBuffersLocked(); 970 mDequeueCondition.broadcast(); 971 return NO_ERROR; 972} 973 974status_t BufferQueue::getReleasedBuffers(uint32_t* slotMask) { 975 ST_LOGV("getReleasedBuffers"); 976 Mutex::Autolock lock(mMutex); 977 978 if (mAbandoned) { 979 ST_LOGE("getReleasedBuffers: BufferQueue has been abandoned!"); 980 return NO_INIT; 981 } 982 983 uint32_t mask = 0; 984 for (int i = 0; i < NUM_BUFFER_SLOTS; i++) { 985 if (!mSlots[i].mAcquireCalled) { 986 mask |= 1 << i; 987 } 988 } 989 990 // Remove buffers in flight (on the queue) from the mask where acquire has 991 // been called, as the consumer will not receive the buffer address, so 992 // it should not free these slots. 993 Fifo::iterator front(mQueue.begin()); 994 while (front != mQueue.end()) { 995 if (front->mAcquireCalled) 996 mask &= ~(1 << front->mBuf); 997 front++; 998 } 999 1000 *slotMask = mask; 1001 1002 ST_LOGV("getReleasedBuffers: returning mask %#x", mask); 1003 return NO_ERROR; 1004} 1005 1006status_t BufferQueue::setDefaultBufferSize(uint32_t w, uint32_t h) { 1007 ST_LOGV("setDefaultBufferSize: w=%d, h=%d", w, h); 1008 if (!w || !h) { 1009 ST_LOGE("setDefaultBufferSize: dimensions cannot be 0 (w=%d, h=%d)", 1010 w, h); 1011 return BAD_VALUE; 1012 } 1013 1014 Mutex::Autolock lock(mMutex); 1015 mDefaultWidth = w; 1016 mDefaultHeight = h; 1017 return NO_ERROR; 1018} 1019 1020status_t BufferQueue::setDefaultMaxBufferCount(int bufferCount) { 1021 ATRACE_CALL(); 1022 Mutex::Autolock lock(mMutex); 1023 return setDefaultMaxBufferCountLocked(bufferCount); 1024} 1025 1026status_t BufferQueue::setMaxAcquiredBufferCount(int maxAcquiredBuffers) { 1027 ATRACE_CALL(); 1028 Mutex::Autolock lock(mMutex); 1029 if (maxAcquiredBuffers < 1 || maxAcquiredBuffers > MAX_MAX_ACQUIRED_BUFFERS) { 1030 ST_LOGE("setMaxAcquiredBufferCount: invalid count specified: %d", 1031 maxAcquiredBuffers); 1032 return BAD_VALUE; 1033 } 1034 if (mConnectedApi != NO_CONNECTED_API) { 1035 return INVALID_OPERATION; 1036 } 1037 mMaxAcquiredBufferCount = maxAcquiredBuffers; 1038 return NO_ERROR; 1039} 1040 1041int BufferQueue::getMinUndequeuedBufferCount(bool async) const { 1042 return (mDequeueBufferCannotBlock || async) ? 1043 mMaxAcquiredBufferCount+1 : mMaxAcquiredBufferCount; 1044} 1045 1046int BufferQueue::getMinMaxBufferCountLocked(bool async) const { 1047 return getMinUndequeuedBufferCount(async) + 1; 1048} 1049 1050int BufferQueue::getMaxBufferCountLocked(bool async) const { 1051 int minMaxBufferCount = getMinMaxBufferCountLocked(async); 1052 1053 int maxBufferCount = mDefaultMaxBufferCount; 1054 if (maxBufferCount < minMaxBufferCount) { 1055 maxBufferCount = minMaxBufferCount; 1056 } 1057 if (mOverrideMaxBufferCount != 0) { 1058 assert(mOverrideMaxBufferCount >= minMaxBufferCount); 1059 maxBufferCount = mOverrideMaxBufferCount; 1060 } 1061 1062 // Any buffers that are dequeued by the producer or sitting in the queue 1063 // waiting to be consumed need to have their slots preserved. Such 1064 // buffers will temporarily keep the max buffer count up until the slots 1065 // no longer need to be preserved. 1066 for (int i = maxBufferCount; i < NUM_BUFFER_SLOTS; i++) { 1067 BufferSlot::BufferState state = mSlots[i].mBufferState; 1068 if (state == BufferSlot::QUEUED || state == BufferSlot::DEQUEUED) { 1069 maxBufferCount = i + 1; 1070 } 1071 } 1072 1073 return maxBufferCount; 1074} 1075 1076bool BufferQueue::stillTracking(const BufferItem *item) const { 1077 const BufferSlot &slot = mSlots[item->mBuf]; 1078 1079 ST_LOGV("stillTracking?: item: { slot=%d/%llu, buffer=%p }, " 1080 "slot: { slot=%d/%llu, buffer=%p }", 1081 item->mBuf, item->mFrameNumber, 1082 (item->mGraphicBuffer.get() ? item->mGraphicBuffer->handle : 0), 1083 item->mBuf, slot.mFrameNumber, 1084 (slot.mGraphicBuffer.get() ? slot.mGraphicBuffer->handle : 0)); 1085 1086 // Compare item with its original buffer slot. We can check the slot 1087 // as the buffer would not be moved to a different slot by the producer. 1088 return (slot.mGraphicBuffer != NULL && 1089 item->mGraphicBuffer->handle == slot.mGraphicBuffer->handle); 1090} 1091 1092BufferQueue::ProxyConsumerListener::ProxyConsumerListener( 1093 const wp<BufferQueue::ConsumerListener>& consumerListener): 1094 mConsumerListener(consumerListener) {} 1095 1096BufferQueue::ProxyConsumerListener::~ProxyConsumerListener() {} 1097 1098void BufferQueue::ProxyConsumerListener::onFrameAvailable() { 1099 sp<BufferQueue::ConsumerListener> listener(mConsumerListener.promote()); 1100 if (listener != NULL) { 1101 listener->onFrameAvailable(); 1102 } 1103} 1104 1105void BufferQueue::ProxyConsumerListener::onBuffersReleased() { 1106 sp<BufferQueue::ConsumerListener> listener(mConsumerListener.promote()); 1107 if (listener != NULL) { 1108 listener->onBuffersReleased(); 1109 } 1110} 1111 1112}; // namespace android 1113