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