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