1 /* 2 * Copyright (C) 2010 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 "Surface" 18 #define ATRACE_TAG ATRACE_TAG_GRAPHICS 19 //#define LOG_NDEBUG 0 20 21 #include <gui/Surface.h> 22 23 #include <condition_variable> 24 #include <deque> 25 #include <mutex> 26 #include <thread> 27 28 #include <inttypes.h> 29 30 #include <android/native_window.h> 31 32 #include <utils/Log.h> 33 #include <utils/Trace.h> 34 #include <utils/NativeHandle.h> 35 36 #include <ui/DisplayStatInfo.h> 37 #include <ui/Fence.h> 38 #include <ui/HdrCapabilities.h> 39 #include <ui/Region.h> 40 41 #include <gui/BufferItem.h> 42 #include <gui/IProducerListener.h> 43 44 #include <gui/ISurfaceComposer.h> 45 #include <private/gui/ComposerService.h> 46 47 namespace android { 48 49 using ui::ColorMode; 50 using ui::Dataspace; 51 52 Surface::Surface(const sp<IGraphicBufferProducer>& bufferProducer, bool controlledByApp) 53 : mGraphicBufferProducer(bufferProducer), 54 mCrop(Rect::EMPTY_RECT), 55 mBufferAge(0), 56 mGenerationNumber(0), 57 mSharedBufferMode(false), 58 mAutoRefresh(false), 59 mSharedBufferSlot(BufferItem::INVALID_BUFFER_SLOT), 60 mSharedBufferHasBeenQueued(false), 61 mQueriedSupportedTimestamps(false), 62 mFrameTimestampsSupportsPresent(false), 63 mEnableFrameTimestamps(false), 64 mFrameEventHistory(std::make_unique<ProducerFrameEventHistory>()) { 65 // Initialize the ANativeWindow function pointers. 66 ANativeWindow::setSwapInterval = hook_setSwapInterval; 67 ANativeWindow::dequeueBuffer = hook_dequeueBuffer; 68 ANativeWindow::cancelBuffer = hook_cancelBuffer; 69 ANativeWindow::queueBuffer = hook_queueBuffer; 70 ANativeWindow::query = hook_query; 71 ANativeWindow::perform = hook_perform; 72 73 ANativeWindow::dequeueBuffer_DEPRECATED = hook_dequeueBuffer_DEPRECATED; 74 ANativeWindow::cancelBuffer_DEPRECATED = hook_cancelBuffer_DEPRECATED; 75 ANativeWindow::lockBuffer_DEPRECATED = hook_lockBuffer_DEPRECATED; 76 ANativeWindow::queueBuffer_DEPRECATED = hook_queueBuffer_DEPRECATED; 77 78 const_cast<int&>(ANativeWindow::minSwapInterval) = 0; 79 const_cast<int&>(ANativeWindow::maxSwapInterval) = 1; 80 81 mReqWidth = 0; 82 mReqHeight = 0; 83 mReqFormat = 0; 84 mReqUsage = 0; 85 mTimestamp = NATIVE_WINDOW_TIMESTAMP_AUTO; 86 mDataSpace = Dataspace::UNKNOWN; 87 mScalingMode = NATIVE_WINDOW_SCALING_MODE_FREEZE; 88 mTransform = 0; 89 mStickyTransform = 0; 90 mDefaultWidth = 0; 91 mDefaultHeight = 0; 92 mUserWidth = 0; 93 mUserHeight = 0; 94 mTransformHint = 0; 95 mConsumerRunningBehind = false; 96 mConnectedToCpu = false; 97 mProducerControlledByApp = controlledByApp; 98 mSwapIntervalZero = false; 99 } 100 101 Surface::~Surface() { 102 if (mConnectedToCpu) { 103 Surface::disconnect(NATIVE_WINDOW_API_CPU); 104 } 105 } 106 107 sp<ISurfaceComposer> Surface::composerService() const { 108 return ComposerService::getComposerService(); 109 } 110 111 nsecs_t Surface::now() const { 112 return systemTime(); 113 } 114 115 sp<IGraphicBufferProducer> Surface::getIGraphicBufferProducer() const { 116 return mGraphicBufferProducer; 117 } 118 119 void Surface::setSidebandStream(const sp<NativeHandle>& stream) { 120 mGraphicBufferProducer->setSidebandStream(stream); 121 } 122 123 void Surface::allocateBuffers() { 124 uint32_t reqWidth = mReqWidth ? mReqWidth : mUserWidth; 125 uint32_t reqHeight = mReqHeight ? mReqHeight : mUserHeight; 126 mGraphicBufferProducer->allocateBuffers(reqWidth, reqHeight, 127 mReqFormat, mReqUsage); 128 } 129 130 status_t Surface::setGenerationNumber(uint32_t generation) { 131 status_t result = mGraphicBufferProducer->setGenerationNumber(generation); 132 if (result == NO_ERROR) { 133 mGenerationNumber = generation; 134 } 135 return result; 136 } 137 138 uint64_t Surface::getNextFrameNumber() const { 139 Mutex::Autolock lock(mMutex); 140 return mNextFrameNumber; 141 } 142 143 String8 Surface::getConsumerName() const { 144 return mGraphicBufferProducer->getConsumerName(); 145 } 146 147 status_t Surface::setDequeueTimeout(nsecs_t timeout) { 148 return mGraphicBufferProducer->setDequeueTimeout(timeout); 149 } 150 151 status_t Surface::getLastQueuedBuffer(sp<GraphicBuffer>* outBuffer, 152 sp<Fence>* outFence, float outTransformMatrix[16]) { 153 return mGraphicBufferProducer->getLastQueuedBuffer(outBuffer, outFence, 154 outTransformMatrix); 155 } 156 157 status_t Surface::getDisplayRefreshCycleDuration(nsecs_t* outRefreshDuration) { 158 ATRACE_CALL(); 159 160 DisplayStatInfo stats; 161 status_t result = composerService()->getDisplayStats(nullptr, &stats); 162 if (result != NO_ERROR) { 163 return result; 164 } 165 166 *outRefreshDuration = stats.vsyncPeriod; 167 168 return NO_ERROR; 169 } 170 171 void Surface::enableFrameTimestamps(bool enable) { 172 Mutex::Autolock lock(mMutex); 173 // If going from disabled to enabled, get the initial values for 174 // compositor and display timing. 175 if (!mEnableFrameTimestamps && enable) { 176 FrameEventHistoryDelta delta; 177 mGraphicBufferProducer->getFrameTimestamps(&delta); 178 mFrameEventHistory->applyDelta(delta); 179 } 180 mEnableFrameTimestamps = enable; 181 } 182 183 status_t Surface::getCompositorTiming( 184 nsecs_t* compositeDeadline, nsecs_t* compositeInterval, 185 nsecs_t* compositeToPresentLatency) { 186 Mutex::Autolock lock(mMutex); 187 if (!mEnableFrameTimestamps) { 188 return INVALID_OPERATION; 189 } 190 191 if (compositeDeadline != nullptr) { 192 *compositeDeadline = 193 mFrameEventHistory->getNextCompositeDeadline(now()); 194 } 195 if (compositeInterval != nullptr) { 196 *compositeInterval = mFrameEventHistory->getCompositeInterval(); 197 } 198 if (compositeToPresentLatency != nullptr) { 199 *compositeToPresentLatency = 200 mFrameEventHistory->getCompositeToPresentLatency(); 201 } 202 return NO_ERROR; 203 } 204 205 static bool checkConsumerForUpdates( 206 const FrameEvents* e, const uint64_t lastFrameNumber, 207 const nsecs_t* outLatchTime, 208 const nsecs_t* outFirstRefreshStartTime, 209 const nsecs_t* outLastRefreshStartTime, 210 const nsecs_t* outGpuCompositionDoneTime, 211 const nsecs_t* outDisplayPresentTime, 212 const nsecs_t* outDequeueReadyTime, 213 const nsecs_t* outReleaseTime) { 214 bool checkForLatch = (outLatchTime != nullptr) && !e->hasLatchInfo(); 215 bool checkForFirstRefreshStart = (outFirstRefreshStartTime != nullptr) && 216 !e->hasFirstRefreshStartInfo(); 217 bool checkForGpuCompositionDone = (outGpuCompositionDoneTime != nullptr) && 218 !e->hasGpuCompositionDoneInfo(); 219 bool checkForDisplayPresent = (outDisplayPresentTime != nullptr) && 220 !e->hasDisplayPresentInfo(); 221 222 // LastRefreshStart, DequeueReady, and Release are never available for the 223 // last frame. 224 bool checkForLastRefreshStart = (outLastRefreshStartTime != nullptr) && 225 !e->hasLastRefreshStartInfo() && 226 (e->frameNumber != lastFrameNumber); 227 bool checkForDequeueReady = (outDequeueReadyTime != nullptr) && 228 !e->hasDequeueReadyInfo() && (e->frameNumber != lastFrameNumber); 229 bool checkForRelease = (outReleaseTime != nullptr) && 230 !e->hasReleaseInfo() && (e->frameNumber != lastFrameNumber); 231 232 // RequestedPresent and Acquire info are always available producer-side. 233 return checkForLatch || checkForFirstRefreshStart || 234 checkForLastRefreshStart || checkForGpuCompositionDone || 235 checkForDisplayPresent || checkForDequeueReady || checkForRelease; 236 } 237 238 static void getFrameTimestamp(nsecs_t *dst, const nsecs_t& src) { 239 if (dst != nullptr) { 240 // We always get valid timestamps for these eventually. 241 *dst = (src == FrameEvents::TIMESTAMP_PENDING) ? 242 NATIVE_WINDOW_TIMESTAMP_PENDING : src; 243 } 244 } 245 246 static void getFrameTimestampFence(nsecs_t *dst, 247 const std::shared_ptr<FenceTime>& src, bool fenceShouldBeKnown) { 248 if (dst != nullptr) { 249 if (!fenceShouldBeKnown) { 250 *dst = NATIVE_WINDOW_TIMESTAMP_PENDING; 251 return; 252 } 253 254 nsecs_t signalTime = src->getSignalTime(); 255 *dst = (signalTime == Fence::SIGNAL_TIME_PENDING) ? 256 NATIVE_WINDOW_TIMESTAMP_PENDING : 257 (signalTime == Fence::SIGNAL_TIME_INVALID) ? 258 NATIVE_WINDOW_TIMESTAMP_INVALID : 259 signalTime; 260 } 261 } 262 263 status_t Surface::getFrameTimestamps(uint64_t frameNumber, 264 nsecs_t* outRequestedPresentTime, nsecs_t* outAcquireTime, 265 nsecs_t* outLatchTime, nsecs_t* outFirstRefreshStartTime, 266 nsecs_t* outLastRefreshStartTime, nsecs_t* outGpuCompositionDoneTime, 267 nsecs_t* outDisplayPresentTime, nsecs_t* outDequeueReadyTime, 268 nsecs_t* outReleaseTime) { 269 ATRACE_CALL(); 270 271 Mutex::Autolock lock(mMutex); 272 273 if (!mEnableFrameTimestamps) { 274 return INVALID_OPERATION; 275 } 276 277 // Verify the requested timestamps are supported. 278 querySupportedTimestampsLocked(); 279 if (outDisplayPresentTime != nullptr && !mFrameTimestampsSupportsPresent) { 280 return BAD_VALUE; 281 } 282 283 FrameEvents* events = mFrameEventHistory->getFrame(frameNumber); 284 if (events == nullptr) { 285 // If the entry isn't available in the producer, it's definitely not 286 // available in the consumer. 287 return NAME_NOT_FOUND; 288 } 289 290 // Update our cache of events if the requested events are not available. 291 if (checkConsumerForUpdates(events, mLastFrameNumber, 292 outLatchTime, outFirstRefreshStartTime, outLastRefreshStartTime, 293 outGpuCompositionDoneTime, outDisplayPresentTime, 294 outDequeueReadyTime, outReleaseTime)) { 295 FrameEventHistoryDelta delta; 296 mGraphicBufferProducer->getFrameTimestamps(&delta); 297 mFrameEventHistory->applyDelta(delta); 298 events = mFrameEventHistory->getFrame(frameNumber); 299 } 300 301 if (events == nullptr) { 302 // The entry was available before the update, but was overwritten 303 // after the update. Make sure not to send the wrong frame's data. 304 return NAME_NOT_FOUND; 305 } 306 307 getFrameTimestamp(outRequestedPresentTime, events->requestedPresentTime); 308 getFrameTimestamp(outLatchTime, events->latchTime); 309 getFrameTimestamp(outFirstRefreshStartTime, events->firstRefreshStartTime); 310 getFrameTimestamp(outLastRefreshStartTime, events->lastRefreshStartTime); 311 getFrameTimestamp(outDequeueReadyTime, events->dequeueReadyTime); 312 313 getFrameTimestampFence(outAcquireTime, events->acquireFence, 314 events->hasAcquireInfo()); 315 getFrameTimestampFence(outGpuCompositionDoneTime, 316 events->gpuCompositionDoneFence, 317 events->hasGpuCompositionDoneInfo()); 318 getFrameTimestampFence(outDisplayPresentTime, events->displayPresentFence, 319 events->hasDisplayPresentInfo()); 320 getFrameTimestampFence(outReleaseTime, events->releaseFence, 321 events->hasReleaseInfo()); 322 323 return NO_ERROR; 324 } 325 326 status_t Surface::getWideColorSupport(bool* supported) { 327 ATRACE_CALL(); 328 329 const sp<IBinder> display = composerService()->getInternalDisplayToken(); 330 if (display == nullptr) { 331 return NAME_NOT_FOUND; 332 } 333 334 *supported = false; 335 status_t error = composerService()->isWideColorDisplay(display, supported); 336 return error; 337 } 338 339 status_t Surface::getHdrSupport(bool* supported) { 340 ATRACE_CALL(); 341 342 const sp<IBinder> display = composerService()->getInternalDisplayToken(); 343 if (display == nullptr) { 344 return NAME_NOT_FOUND; 345 } 346 347 HdrCapabilities hdrCapabilities; 348 status_t err = 349 composerService()->getHdrCapabilities(display, &hdrCapabilities); 350 351 if (err) 352 return err; 353 354 *supported = !hdrCapabilities.getSupportedHdrTypes().empty(); 355 356 return NO_ERROR; 357 } 358 359 int Surface::hook_setSwapInterval(ANativeWindow* window, int interval) { 360 Surface* c = getSelf(window); 361 return c->setSwapInterval(interval); 362 } 363 364 int Surface::hook_dequeueBuffer(ANativeWindow* window, 365 ANativeWindowBuffer** buffer, int* fenceFd) { 366 Surface* c = getSelf(window); 367 return c->dequeueBuffer(buffer, fenceFd); 368 } 369 370 int Surface::hook_cancelBuffer(ANativeWindow* window, 371 ANativeWindowBuffer* buffer, int fenceFd) { 372 Surface* c = getSelf(window); 373 return c->cancelBuffer(buffer, fenceFd); 374 } 375 376 int Surface::hook_queueBuffer(ANativeWindow* window, 377 ANativeWindowBuffer* buffer, int fenceFd) { 378 Surface* c = getSelf(window); 379 return c->queueBuffer(buffer, fenceFd); 380 } 381 382 int Surface::hook_dequeueBuffer_DEPRECATED(ANativeWindow* window, 383 ANativeWindowBuffer** buffer) { 384 Surface* c = getSelf(window); 385 ANativeWindowBuffer* buf; 386 int fenceFd = -1; 387 int result = c->dequeueBuffer(&buf, &fenceFd); 388 if (result != OK) { 389 return result; 390 } 391 sp<Fence> fence(new Fence(fenceFd)); 392 int waitResult = fence->waitForever("dequeueBuffer_DEPRECATED"); 393 if (waitResult != OK) { 394 ALOGE("dequeueBuffer_DEPRECATED: Fence::wait returned an error: %d", 395 waitResult); 396 c->cancelBuffer(buf, -1); 397 return waitResult; 398 } 399 *buffer = buf; 400 return result; 401 } 402 403 int Surface::hook_cancelBuffer_DEPRECATED(ANativeWindow* window, 404 ANativeWindowBuffer* buffer) { 405 Surface* c = getSelf(window); 406 return c->cancelBuffer(buffer, -1); 407 } 408 409 int Surface::hook_lockBuffer_DEPRECATED(ANativeWindow* window, 410 ANativeWindowBuffer* buffer) { 411 Surface* c = getSelf(window); 412 return c->lockBuffer_DEPRECATED(buffer); 413 } 414 415 int Surface::hook_queueBuffer_DEPRECATED(ANativeWindow* window, 416 ANativeWindowBuffer* buffer) { 417 Surface* c = getSelf(window); 418 return c->queueBuffer(buffer, -1); 419 } 420 421 int Surface::hook_query(const ANativeWindow* window, 422 int what, int* value) { 423 const Surface* c = getSelf(window); 424 return c->query(what, value); 425 } 426 427 int Surface::hook_perform(ANativeWindow* window, int operation, ...) { 428 va_list args; 429 va_start(args, operation); 430 Surface* c = getSelf(window); 431 int result = c->perform(operation, args); 432 va_end(args); 433 return result; 434 } 435 436 int Surface::setSwapInterval(int interval) { 437 ATRACE_CALL(); 438 // EGL specification states: 439 // interval is silently clamped to minimum and maximum implementation 440 // dependent values before being stored. 441 442 if (interval < minSwapInterval) 443 interval = minSwapInterval; 444 445 if (interval > maxSwapInterval) 446 interval = maxSwapInterval; 447 448 const bool wasSwapIntervalZero = mSwapIntervalZero; 449 mSwapIntervalZero = (interval == 0); 450 451 if (mSwapIntervalZero != wasSwapIntervalZero) { 452 mGraphicBufferProducer->setAsyncMode(mSwapIntervalZero); 453 } 454 455 return NO_ERROR; 456 } 457 458 class FenceMonitor { 459 public: 460 explicit FenceMonitor(const char* name) : mName(name), mFencesQueued(0), mFencesSignaled(0) { 461 std::thread thread(&FenceMonitor::loop, this); 462 pthread_setname_np(thread.native_handle(), mName); 463 thread.detach(); 464 } 465 466 void queueFence(const sp<Fence>& fence) { 467 char message[64]; 468 469 std::lock_guard<std::mutex> lock(mMutex); 470 if (fence->getSignalTime() != Fence::SIGNAL_TIME_PENDING) { 471 snprintf(message, sizeof(message), "%s fence %u has signaled", mName, mFencesQueued); 472 ATRACE_NAME(message); 473 // Need an increment on both to make the trace number correct. 474 mFencesQueued++; 475 mFencesSignaled++; 476 return; 477 } 478 snprintf(message, sizeof(message), "Trace %s fence %u", mName, mFencesQueued); 479 ATRACE_NAME(message); 480 481 mQueue.push_back(fence); 482 mCondition.notify_one(); 483 mFencesQueued++; 484 ATRACE_INT(mName, int32_t(mQueue.size())); 485 } 486 487 private: 488 #pragma clang diagnostic push 489 #pragma clang diagnostic ignored "-Wmissing-noreturn" 490 void loop() { 491 while (true) { 492 threadLoop(); 493 } 494 } 495 #pragma clang diagnostic pop 496 497 void threadLoop() { 498 sp<Fence> fence; 499 uint32_t fenceNum; 500 { 501 std::unique_lock<std::mutex> lock(mMutex); 502 while (mQueue.empty()) { 503 mCondition.wait(lock); 504 } 505 fence = mQueue[0]; 506 fenceNum = mFencesSignaled; 507 } 508 { 509 char message[64]; 510 snprintf(message, sizeof(message), "waiting for %s %u", mName, fenceNum); 511 ATRACE_NAME(message); 512 513 status_t result = fence->waitForever(message); 514 if (result != OK) { 515 ALOGE("Error waiting for fence: %d", result); 516 } 517 } 518 { 519 std::lock_guard<std::mutex> lock(mMutex); 520 mQueue.pop_front(); 521 mFencesSignaled++; 522 ATRACE_INT(mName, int32_t(mQueue.size())); 523 } 524 } 525 526 const char* mName; 527 uint32_t mFencesQueued; 528 uint32_t mFencesSignaled; 529 std::deque<sp<Fence>> mQueue; 530 std::condition_variable mCondition; 531 std::mutex mMutex; 532 }; 533 534 int Surface::dequeueBuffer(android_native_buffer_t** buffer, int* fenceFd) { 535 ATRACE_CALL(); 536 ALOGV("Surface::dequeueBuffer"); 537 538 uint32_t reqWidth; 539 uint32_t reqHeight; 540 PixelFormat reqFormat; 541 uint64_t reqUsage; 542 bool enableFrameTimestamps; 543 544 { 545 Mutex::Autolock lock(mMutex); 546 if (mReportRemovedBuffers) { 547 mRemovedBuffers.clear(); 548 } 549 550 reqWidth = mReqWidth ? mReqWidth : mUserWidth; 551 reqHeight = mReqHeight ? mReqHeight : mUserHeight; 552 553 reqFormat = mReqFormat; 554 reqUsage = mReqUsage; 555 556 enableFrameTimestamps = mEnableFrameTimestamps; 557 558 if (mSharedBufferMode && mAutoRefresh && mSharedBufferSlot != 559 BufferItem::INVALID_BUFFER_SLOT) { 560 sp<GraphicBuffer>& gbuf(mSlots[mSharedBufferSlot].buffer); 561 if (gbuf != nullptr) { 562 *buffer = gbuf.get(); 563 *fenceFd = -1; 564 return OK; 565 } 566 } 567 } // Drop the lock so that we can still touch the Surface while blocking in IGBP::dequeueBuffer 568 569 int buf = -1; 570 sp<Fence> fence; 571 nsecs_t startTime = systemTime(); 572 573 FrameEventHistoryDelta frameTimestamps; 574 status_t result = mGraphicBufferProducer->dequeueBuffer(&buf, &fence, reqWidth, reqHeight, 575 reqFormat, reqUsage, &mBufferAge, 576 enableFrameTimestamps ? &frameTimestamps 577 : nullptr); 578 mLastDequeueDuration = systemTime() - startTime; 579 580 if (result < 0) { 581 ALOGV("dequeueBuffer: IGraphicBufferProducer::dequeueBuffer" 582 "(%d, %d, %d, %#" PRIx64 ") failed: %d", 583 reqWidth, reqHeight, reqFormat, reqUsage, result); 584 return result; 585 } 586 587 if (buf < 0 || buf >= NUM_BUFFER_SLOTS) { 588 ALOGE("dequeueBuffer: IGraphicBufferProducer returned invalid slot number %d", buf); 589 android_errorWriteLog(0x534e4554, "36991414"); // SafetyNet logging 590 return FAILED_TRANSACTION; 591 } 592 593 Mutex::Autolock lock(mMutex); 594 595 // Write this while holding the mutex 596 mLastDequeueStartTime = startTime; 597 598 sp<GraphicBuffer>& gbuf(mSlots[buf].buffer); 599 600 // this should never happen 601 ALOGE_IF(fence == nullptr, "Surface::dequeueBuffer: received null Fence! buf=%d", buf); 602 603 if (CC_UNLIKELY(atrace_is_tag_enabled(ATRACE_TAG_GRAPHICS))) { 604 static FenceMonitor hwcReleaseThread("HWC release"); 605 hwcReleaseThread.queueFence(fence); 606 } 607 608 if (result & IGraphicBufferProducer::RELEASE_ALL_BUFFERS) { 609 freeAllBuffers(); 610 } 611 612 if (enableFrameTimestamps) { 613 mFrameEventHistory->applyDelta(frameTimestamps); 614 } 615 616 if ((result & IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION) || gbuf == nullptr) { 617 if (mReportRemovedBuffers && (gbuf != nullptr)) { 618 mRemovedBuffers.push_back(gbuf); 619 } 620 result = mGraphicBufferProducer->requestBuffer(buf, &gbuf); 621 if (result != NO_ERROR) { 622 ALOGE("dequeueBuffer: IGraphicBufferProducer::requestBuffer failed: %d", result); 623 mGraphicBufferProducer->cancelBuffer(buf, fence); 624 return result; 625 } 626 } 627 628 if (fence->isValid()) { 629 *fenceFd = fence->dup(); 630 if (*fenceFd == -1) { 631 ALOGE("dequeueBuffer: error duping fence: %d", errno); 632 // dup() should never fail; something is badly wrong. Soldier on 633 // and hope for the best; the worst that should happen is some 634 // visible corruption that lasts until the next frame. 635 } 636 } else { 637 *fenceFd = -1; 638 } 639 640 *buffer = gbuf.get(); 641 642 if (mSharedBufferMode && mAutoRefresh) { 643 mSharedBufferSlot = buf; 644 mSharedBufferHasBeenQueued = false; 645 } else if (mSharedBufferSlot == buf) { 646 mSharedBufferSlot = BufferItem::INVALID_BUFFER_SLOT; 647 mSharedBufferHasBeenQueued = false; 648 } 649 650 return OK; 651 } 652 653 int Surface::cancelBuffer(android_native_buffer_t* buffer, 654 int fenceFd) { 655 ATRACE_CALL(); 656 ALOGV("Surface::cancelBuffer"); 657 Mutex::Autolock lock(mMutex); 658 int i = getSlotFromBufferLocked(buffer); 659 if (i < 0) { 660 if (fenceFd >= 0) { 661 close(fenceFd); 662 } 663 return i; 664 } 665 if (mSharedBufferSlot == i && mSharedBufferHasBeenQueued) { 666 if (fenceFd >= 0) { 667 close(fenceFd); 668 } 669 return OK; 670 } 671 sp<Fence> fence(fenceFd >= 0 ? new Fence(fenceFd) : Fence::NO_FENCE); 672 mGraphicBufferProducer->cancelBuffer(i, fence); 673 674 if (mSharedBufferMode && mAutoRefresh && mSharedBufferSlot == i) { 675 mSharedBufferHasBeenQueued = true; 676 } 677 678 return OK; 679 } 680 681 int Surface::getSlotFromBufferLocked( 682 android_native_buffer_t* buffer) const { 683 for (int i = 0; i < NUM_BUFFER_SLOTS; i++) { 684 if (mSlots[i].buffer != nullptr && 685 mSlots[i].buffer->handle == buffer->handle) { 686 return i; 687 } 688 } 689 ALOGE("getSlotFromBufferLocked: unknown buffer: %p", buffer->handle); 690 return BAD_VALUE; 691 } 692 693 int Surface::lockBuffer_DEPRECATED(android_native_buffer_t* buffer __attribute__((unused))) { 694 ALOGV("Surface::lockBuffer"); 695 Mutex::Autolock lock(mMutex); 696 return OK; 697 } 698 699 int Surface::queueBuffer(android_native_buffer_t* buffer, int fenceFd) { 700 ATRACE_CALL(); 701 ALOGV("Surface::queueBuffer"); 702 Mutex::Autolock lock(mMutex); 703 int64_t timestamp; 704 bool isAutoTimestamp = false; 705 706 if (mTimestamp == NATIVE_WINDOW_TIMESTAMP_AUTO) { 707 timestamp = systemTime(SYSTEM_TIME_MONOTONIC); 708 isAutoTimestamp = true; 709 ALOGV("Surface::queueBuffer making up timestamp: %.2f ms", 710 timestamp / 1000000.0); 711 } else { 712 timestamp = mTimestamp; 713 } 714 int i = getSlotFromBufferLocked(buffer); 715 if (i < 0) { 716 if (fenceFd >= 0) { 717 close(fenceFd); 718 } 719 return i; 720 } 721 if (mSharedBufferSlot == i && mSharedBufferHasBeenQueued) { 722 if (fenceFd >= 0) { 723 close(fenceFd); 724 } 725 return OK; 726 } 727 728 729 // Make sure the crop rectangle is entirely inside the buffer. 730 Rect crop(Rect::EMPTY_RECT); 731 mCrop.intersect(Rect(buffer->width, buffer->height), &crop); 732 733 sp<Fence> fence(fenceFd >= 0 ? new Fence(fenceFd) : Fence::NO_FENCE); 734 IGraphicBufferProducer::QueueBufferOutput output; 735 IGraphicBufferProducer::QueueBufferInput input(timestamp, isAutoTimestamp, 736 static_cast<android_dataspace>(mDataSpace), crop, mScalingMode, 737 mTransform ^ mStickyTransform, fence, mStickyTransform, 738 mEnableFrameTimestamps); 739 740 // we should send HDR metadata as needed if this becomes a bottleneck 741 input.setHdrMetadata(mHdrMetadata); 742 743 if (mConnectedToCpu || mDirtyRegion.bounds() == Rect::INVALID_RECT) { 744 input.setSurfaceDamage(Region::INVALID_REGION); 745 } else { 746 // Here we do two things: 747 // 1) The surface damage was specified using the OpenGL ES convention of 748 // the origin being in the bottom-left corner. Here we flip to the 749 // convention that the rest of the system uses (top-left corner) by 750 // subtracting all top/bottom coordinates from the buffer height. 751 // 2) If the buffer is coming in rotated (for example, because the EGL 752 // implementation is reacting to the transform hint coming back from 753 // SurfaceFlinger), the surface damage needs to be rotated the 754 // opposite direction, since it was generated assuming an unrotated 755 // buffer (the app doesn't know that the EGL implementation is 756 // reacting to the transform hint behind its back). The 757 // transformations in the switch statement below apply those 758 // complementary rotations (e.g., if 90 degrees, rotate 270 degrees). 759 760 int width = buffer->width; 761 int height = buffer->height; 762 bool rotated90 = (mTransform ^ mStickyTransform) & 763 NATIVE_WINDOW_TRANSFORM_ROT_90; 764 if (rotated90) { 765 std::swap(width, height); 766 } 767 768 Region flippedRegion; 769 for (auto rect : mDirtyRegion) { 770 int left = rect.left; 771 int right = rect.right; 772 int top = height - rect.bottom; // Flip from OpenGL convention 773 int bottom = height - rect.top; // Flip from OpenGL convention 774 switch (mTransform ^ mStickyTransform) { 775 case NATIVE_WINDOW_TRANSFORM_ROT_90: { 776 // Rotate 270 degrees 777 Rect flippedRect{top, width - right, bottom, width - left}; 778 flippedRegion.orSelf(flippedRect); 779 break; 780 } 781 case NATIVE_WINDOW_TRANSFORM_ROT_180: { 782 // Rotate 180 degrees 783 Rect flippedRect{width - right, height - bottom, 784 width - left, height - top}; 785 flippedRegion.orSelf(flippedRect); 786 break; 787 } 788 case NATIVE_WINDOW_TRANSFORM_ROT_270: { 789 // Rotate 90 degrees 790 Rect flippedRect{height - bottom, left, 791 height - top, right}; 792 flippedRegion.orSelf(flippedRect); 793 break; 794 } 795 default: { 796 Rect flippedRect{left, top, right, bottom}; 797 flippedRegion.orSelf(flippedRect); 798 break; 799 } 800 } 801 } 802 803 input.setSurfaceDamage(flippedRegion); 804 } 805 806 nsecs_t now = systemTime(); 807 status_t err = mGraphicBufferProducer->queueBuffer(i, input, &output); 808 mLastQueueDuration = systemTime() - now; 809 if (err != OK) { 810 ALOGE("queueBuffer: error queuing buffer to SurfaceTexture, %d", err); 811 } 812 813 if (mEnableFrameTimestamps) { 814 mFrameEventHistory->applyDelta(output.frameTimestamps); 815 // Update timestamps with the local acquire fence. 816 // The consumer doesn't send it back to prevent us from having two 817 // file descriptors of the same fence. 818 mFrameEventHistory->updateAcquireFence(mNextFrameNumber, 819 std::make_shared<FenceTime>(fence)); 820 821 // Cache timestamps of signaled fences so we can close their file 822 // descriptors. 823 mFrameEventHistory->updateSignalTimes(); 824 } 825 826 mLastFrameNumber = mNextFrameNumber; 827 828 mDefaultWidth = output.width; 829 mDefaultHeight = output.height; 830 mNextFrameNumber = output.nextFrameNumber; 831 832 // Ignore transform hint if sticky transform is set or transform to display inverse flag is 833 // set. 834 if (mStickyTransform == 0 && !transformToDisplayInverse()) { 835 mTransformHint = output.transformHint; 836 } 837 838 mConsumerRunningBehind = (output.numPendingBuffers >= 2); 839 840 if (!mConnectedToCpu) { 841 // Clear surface damage back to full-buffer 842 mDirtyRegion = Region::INVALID_REGION; 843 } 844 845 if (mSharedBufferMode && mAutoRefresh && mSharedBufferSlot == i) { 846 mSharedBufferHasBeenQueued = true; 847 } 848 849 mQueueBufferCondition.broadcast(); 850 851 if (CC_UNLIKELY(atrace_is_tag_enabled(ATRACE_TAG_GRAPHICS))) { 852 static FenceMonitor gpuCompletionThread("GPU completion"); 853 gpuCompletionThread.queueFence(fence); 854 } 855 856 return err; 857 } 858 859 void Surface::querySupportedTimestampsLocked() const { 860 // mMutex must be locked when calling this method. 861 862 if (mQueriedSupportedTimestamps) { 863 return; 864 } 865 mQueriedSupportedTimestamps = true; 866 867 std::vector<FrameEvent> supportedFrameTimestamps; 868 status_t err = composerService()->getSupportedFrameTimestamps( 869 &supportedFrameTimestamps); 870 871 if (err != NO_ERROR) { 872 return; 873 } 874 875 for (auto sft : supportedFrameTimestamps) { 876 if (sft == FrameEvent::DISPLAY_PRESENT) { 877 mFrameTimestampsSupportsPresent = true; 878 } 879 } 880 } 881 882 int Surface::query(int what, int* value) const { 883 ATRACE_CALL(); 884 ALOGV("Surface::query"); 885 { // scope for the lock 886 Mutex::Autolock lock(mMutex); 887 switch (what) { 888 case NATIVE_WINDOW_FORMAT: 889 if (mReqFormat) { 890 *value = static_cast<int>(mReqFormat); 891 return NO_ERROR; 892 } 893 break; 894 case NATIVE_WINDOW_QUEUES_TO_WINDOW_COMPOSER: { 895 if (composerService()->authenticateSurfaceTexture( 896 mGraphicBufferProducer)) { 897 *value = 1; 898 } else { 899 *value = 0; 900 } 901 return NO_ERROR; 902 } 903 case NATIVE_WINDOW_CONCRETE_TYPE: 904 *value = NATIVE_WINDOW_SURFACE; 905 return NO_ERROR; 906 case NATIVE_WINDOW_DEFAULT_WIDTH: 907 *value = static_cast<int>( 908 mUserWidth ? mUserWidth : mDefaultWidth); 909 return NO_ERROR; 910 case NATIVE_WINDOW_DEFAULT_HEIGHT: 911 *value = static_cast<int>( 912 mUserHeight ? mUserHeight : mDefaultHeight); 913 return NO_ERROR; 914 case NATIVE_WINDOW_TRANSFORM_HINT: 915 *value = static_cast<int>(mTransformHint); 916 return NO_ERROR; 917 case NATIVE_WINDOW_CONSUMER_RUNNING_BEHIND: { 918 status_t err = NO_ERROR; 919 if (!mConsumerRunningBehind) { 920 *value = 0; 921 } else { 922 err = mGraphicBufferProducer->query(what, value); 923 if (err == NO_ERROR) { 924 mConsumerRunningBehind = *value; 925 } 926 } 927 return err; 928 } 929 case NATIVE_WINDOW_BUFFER_AGE: { 930 if (mBufferAge > INT32_MAX) { 931 *value = 0; 932 } else { 933 *value = static_cast<int32_t>(mBufferAge); 934 } 935 return NO_ERROR; 936 } 937 case NATIVE_WINDOW_LAST_DEQUEUE_DURATION: { 938 int64_t durationUs = mLastDequeueDuration / 1000; 939 *value = durationUs > std::numeric_limits<int>::max() ? 940 std::numeric_limits<int>::max() : 941 static_cast<int>(durationUs); 942 return NO_ERROR; 943 } 944 case NATIVE_WINDOW_LAST_QUEUE_DURATION: { 945 int64_t durationUs = mLastQueueDuration / 1000; 946 *value = durationUs > std::numeric_limits<int>::max() ? 947 std::numeric_limits<int>::max() : 948 static_cast<int>(durationUs); 949 return NO_ERROR; 950 } 951 case NATIVE_WINDOW_FRAME_TIMESTAMPS_SUPPORTS_PRESENT: { 952 querySupportedTimestampsLocked(); 953 *value = mFrameTimestampsSupportsPresent ? 1 : 0; 954 return NO_ERROR; 955 } 956 case NATIVE_WINDOW_IS_VALID: { 957 *value = mGraphicBufferProducer != nullptr ? 1 : 0; 958 return NO_ERROR; 959 } 960 case NATIVE_WINDOW_DATASPACE: { 961 *value = static_cast<int>(mDataSpace); 962 return NO_ERROR; 963 } 964 } 965 } 966 return mGraphicBufferProducer->query(what, value); 967 } 968 969 int Surface::perform(int operation, va_list args) 970 { 971 int res = NO_ERROR; 972 switch (operation) { 973 case NATIVE_WINDOW_CONNECT: 974 // deprecated. must return NO_ERROR. 975 break; 976 case NATIVE_WINDOW_DISCONNECT: 977 // deprecated. must return NO_ERROR. 978 break; 979 case NATIVE_WINDOW_SET_USAGE: 980 res = dispatchSetUsage(args); 981 break; 982 case NATIVE_WINDOW_SET_CROP: 983 res = dispatchSetCrop(args); 984 break; 985 case NATIVE_WINDOW_SET_BUFFER_COUNT: 986 res = dispatchSetBufferCount(args); 987 break; 988 case NATIVE_WINDOW_SET_BUFFERS_GEOMETRY: 989 res = dispatchSetBuffersGeometry(args); 990 break; 991 case NATIVE_WINDOW_SET_BUFFERS_TRANSFORM: 992 res = dispatchSetBuffersTransform(args); 993 break; 994 case NATIVE_WINDOW_SET_BUFFERS_STICKY_TRANSFORM: 995 res = dispatchSetBuffersStickyTransform(args); 996 break; 997 case NATIVE_WINDOW_SET_BUFFERS_TIMESTAMP: 998 res = dispatchSetBuffersTimestamp(args); 999 break; 1000 case NATIVE_WINDOW_SET_BUFFERS_DIMENSIONS: 1001 res = dispatchSetBuffersDimensions(args); 1002 break; 1003 case NATIVE_WINDOW_SET_BUFFERS_USER_DIMENSIONS: 1004 res = dispatchSetBuffersUserDimensions(args); 1005 break; 1006 case NATIVE_WINDOW_SET_BUFFERS_FORMAT: 1007 res = dispatchSetBuffersFormat(args); 1008 break; 1009 case NATIVE_WINDOW_LOCK: 1010 res = dispatchLock(args); 1011 break; 1012 case NATIVE_WINDOW_UNLOCK_AND_POST: 1013 res = dispatchUnlockAndPost(args); 1014 break; 1015 case NATIVE_WINDOW_SET_SCALING_MODE: 1016 res = dispatchSetScalingMode(args); 1017 break; 1018 case NATIVE_WINDOW_API_CONNECT: 1019 res = dispatchConnect(args); 1020 break; 1021 case NATIVE_WINDOW_API_DISCONNECT: 1022 res = dispatchDisconnect(args); 1023 break; 1024 case NATIVE_WINDOW_SET_SIDEBAND_STREAM: 1025 res = dispatchSetSidebandStream(args); 1026 break; 1027 case NATIVE_WINDOW_SET_BUFFERS_DATASPACE: 1028 res = dispatchSetBuffersDataSpace(args); 1029 break; 1030 case NATIVE_WINDOW_SET_BUFFERS_SMPTE2086_METADATA: 1031 res = dispatchSetBuffersSmpte2086Metadata(args); 1032 break; 1033 case NATIVE_WINDOW_SET_BUFFERS_CTA861_3_METADATA: 1034 res = dispatchSetBuffersCta8613Metadata(args); 1035 break; 1036 case NATIVE_WINDOW_SET_BUFFERS_HDR10_PLUS_METADATA: 1037 res = dispatchSetBuffersHdr10PlusMetadata(args); 1038 break; 1039 case NATIVE_WINDOW_SET_SURFACE_DAMAGE: 1040 res = dispatchSetSurfaceDamage(args); 1041 break; 1042 case NATIVE_WINDOW_SET_SHARED_BUFFER_MODE: 1043 res = dispatchSetSharedBufferMode(args); 1044 break; 1045 case NATIVE_WINDOW_SET_AUTO_REFRESH: 1046 res = dispatchSetAutoRefresh(args); 1047 break; 1048 case NATIVE_WINDOW_GET_REFRESH_CYCLE_DURATION: 1049 res = dispatchGetDisplayRefreshCycleDuration(args); 1050 break; 1051 case NATIVE_WINDOW_GET_NEXT_FRAME_ID: 1052 res = dispatchGetNextFrameId(args); 1053 break; 1054 case NATIVE_WINDOW_ENABLE_FRAME_TIMESTAMPS: 1055 res = dispatchEnableFrameTimestamps(args); 1056 break; 1057 case NATIVE_WINDOW_GET_COMPOSITOR_TIMING: 1058 res = dispatchGetCompositorTiming(args); 1059 break; 1060 case NATIVE_WINDOW_GET_FRAME_TIMESTAMPS: 1061 res = dispatchGetFrameTimestamps(args); 1062 break; 1063 case NATIVE_WINDOW_GET_WIDE_COLOR_SUPPORT: 1064 res = dispatchGetWideColorSupport(args); 1065 break; 1066 case NATIVE_WINDOW_GET_HDR_SUPPORT: 1067 res = dispatchGetHdrSupport(args); 1068 break; 1069 case NATIVE_WINDOW_SET_USAGE64: 1070 res = dispatchSetUsage64(args); 1071 break; 1072 case NATIVE_WINDOW_GET_CONSUMER_USAGE64: 1073 res = dispatchGetConsumerUsage64(args); 1074 break; 1075 default: 1076 res = NAME_NOT_FOUND; 1077 break; 1078 } 1079 return res; 1080 } 1081 1082 int Surface::dispatchConnect(va_list args) { 1083 int api = va_arg(args, int); 1084 return connect(api); 1085 } 1086 1087 int Surface::dispatchDisconnect(va_list args) { 1088 int api = va_arg(args, int); 1089 return disconnect(api); 1090 } 1091 1092 int Surface::dispatchSetUsage(va_list args) { 1093 uint64_t usage = va_arg(args, uint32_t); 1094 return setUsage(usage); 1095 } 1096 1097 int Surface::dispatchSetUsage64(va_list args) { 1098 uint64_t usage = va_arg(args, uint64_t); 1099 return setUsage(usage); 1100 } 1101 1102 int Surface::dispatchSetCrop(va_list args) { 1103 android_native_rect_t const* rect = va_arg(args, android_native_rect_t*); 1104 return setCrop(reinterpret_cast<Rect const*>(rect)); 1105 } 1106 1107 int Surface::dispatchSetBufferCount(va_list args) { 1108 size_t bufferCount = va_arg(args, size_t); 1109 return setBufferCount(static_cast<int32_t>(bufferCount)); 1110 } 1111 1112 int Surface::dispatchSetBuffersGeometry(va_list args) { 1113 uint32_t width = va_arg(args, uint32_t); 1114 uint32_t height = va_arg(args, uint32_t); 1115 PixelFormat format = va_arg(args, PixelFormat); 1116 int err = setBuffersDimensions(width, height); 1117 if (err != 0) { 1118 return err; 1119 } 1120 return setBuffersFormat(format); 1121 } 1122 1123 int Surface::dispatchSetBuffersDimensions(va_list args) { 1124 uint32_t width = va_arg(args, uint32_t); 1125 uint32_t height = va_arg(args, uint32_t); 1126 return setBuffersDimensions(width, height); 1127 } 1128 1129 int Surface::dispatchSetBuffersUserDimensions(va_list args) { 1130 uint32_t width = va_arg(args, uint32_t); 1131 uint32_t height = va_arg(args, uint32_t); 1132 return setBuffersUserDimensions(width, height); 1133 } 1134 1135 int Surface::dispatchSetBuffersFormat(va_list args) { 1136 PixelFormat format = va_arg(args, PixelFormat); 1137 return setBuffersFormat(format); 1138 } 1139 1140 int Surface::dispatchSetScalingMode(va_list args) { 1141 int mode = va_arg(args, int); 1142 return setScalingMode(mode); 1143 } 1144 1145 int Surface::dispatchSetBuffersTransform(va_list args) { 1146 uint32_t transform = va_arg(args, uint32_t); 1147 return setBuffersTransform(transform); 1148 } 1149 1150 int Surface::dispatchSetBuffersStickyTransform(va_list args) { 1151 uint32_t transform = va_arg(args, uint32_t); 1152 return setBuffersStickyTransform(transform); 1153 } 1154 1155 int Surface::dispatchSetBuffersTimestamp(va_list args) { 1156 int64_t timestamp = va_arg(args, int64_t); 1157 return setBuffersTimestamp(timestamp); 1158 } 1159 1160 int Surface::dispatchLock(va_list args) { 1161 ANativeWindow_Buffer* outBuffer = va_arg(args, ANativeWindow_Buffer*); 1162 ARect* inOutDirtyBounds = va_arg(args, ARect*); 1163 return lock(outBuffer, inOutDirtyBounds); 1164 } 1165 1166 int Surface::dispatchUnlockAndPost(va_list args __attribute__((unused))) { 1167 return unlockAndPost(); 1168 } 1169 1170 int Surface::dispatchSetSidebandStream(va_list args) { 1171 native_handle_t* sH = va_arg(args, native_handle_t*); 1172 sp<NativeHandle> sidebandHandle = NativeHandle::create(sH, false); 1173 setSidebandStream(sidebandHandle); 1174 return OK; 1175 } 1176 1177 int Surface::dispatchSetBuffersDataSpace(va_list args) { 1178 Dataspace dataspace = static_cast<Dataspace>(va_arg(args, int)); 1179 return setBuffersDataSpace(dataspace); 1180 } 1181 1182 int Surface::dispatchSetBuffersSmpte2086Metadata(va_list args) { 1183 const android_smpte2086_metadata* metadata = 1184 va_arg(args, const android_smpte2086_metadata*); 1185 return setBuffersSmpte2086Metadata(metadata); 1186 } 1187 1188 int Surface::dispatchSetBuffersCta8613Metadata(va_list args) { 1189 const android_cta861_3_metadata* metadata = 1190 va_arg(args, const android_cta861_3_metadata*); 1191 return setBuffersCta8613Metadata(metadata); 1192 } 1193 1194 int Surface::dispatchSetBuffersHdr10PlusMetadata(va_list args) { 1195 const size_t size = va_arg(args, size_t); 1196 const uint8_t* metadata = va_arg(args, const uint8_t*); 1197 return setBuffersHdr10PlusMetadata(size, metadata); 1198 } 1199 1200 int Surface::dispatchSetSurfaceDamage(va_list args) { 1201 android_native_rect_t* rects = va_arg(args, android_native_rect_t*); 1202 size_t numRects = va_arg(args, size_t); 1203 setSurfaceDamage(rects, numRects); 1204 return NO_ERROR; 1205 } 1206 1207 int Surface::dispatchSetSharedBufferMode(va_list args) { 1208 bool sharedBufferMode = va_arg(args, int); 1209 return setSharedBufferMode(sharedBufferMode); 1210 } 1211 1212 int Surface::dispatchSetAutoRefresh(va_list args) { 1213 bool autoRefresh = va_arg(args, int); 1214 return setAutoRefresh(autoRefresh); 1215 } 1216 1217 int Surface::dispatchGetDisplayRefreshCycleDuration(va_list args) { 1218 nsecs_t* outRefreshDuration = va_arg(args, int64_t*); 1219 return getDisplayRefreshCycleDuration(outRefreshDuration); 1220 } 1221 1222 int Surface::dispatchGetNextFrameId(va_list args) { 1223 uint64_t* nextFrameId = va_arg(args, uint64_t*); 1224 *nextFrameId = getNextFrameNumber(); 1225 return NO_ERROR; 1226 } 1227 1228 int Surface::dispatchEnableFrameTimestamps(va_list args) { 1229 bool enable = va_arg(args, int); 1230 enableFrameTimestamps(enable); 1231 return NO_ERROR; 1232 } 1233 1234 int Surface::dispatchGetCompositorTiming(va_list args) { 1235 nsecs_t* compositeDeadline = va_arg(args, int64_t*); 1236 nsecs_t* compositeInterval = va_arg(args, int64_t*); 1237 nsecs_t* compositeToPresentLatency = va_arg(args, int64_t*); 1238 return getCompositorTiming(compositeDeadline, compositeInterval, 1239 compositeToPresentLatency); 1240 } 1241 1242 int Surface::dispatchGetFrameTimestamps(va_list args) { 1243 uint64_t frameId = va_arg(args, uint64_t); 1244 nsecs_t* outRequestedPresentTime = va_arg(args, int64_t*); 1245 nsecs_t* outAcquireTime = va_arg(args, int64_t*); 1246 nsecs_t* outLatchTime = va_arg(args, int64_t*); 1247 nsecs_t* outFirstRefreshStartTime = va_arg(args, int64_t*); 1248 nsecs_t* outLastRefreshStartTime = va_arg(args, int64_t*); 1249 nsecs_t* outGpuCompositionDoneTime = va_arg(args, int64_t*); 1250 nsecs_t* outDisplayPresentTime = va_arg(args, int64_t*); 1251 nsecs_t* outDequeueReadyTime = va_arg(args, int64_t*); 1252 nsecs_t* outReleaseTime = va_arg(args, int64_t*); 1253 return getFrameTimestamps(frameId, 1254 outRequestedPresentTime, outAcquireTime, outLatchTime, 1255 outFirstRefreshStartTime, outLastRefreshStartTime, 1256 outGpuCompositionDoneTime, outDisplayPresentTime, 1257 outDequeueReadyTime, outReleaseTime); 1258 } 1259 1260 int Surface::dispatchGetWideColorSupport(va_list args) { 1261 bool* outSupport = va_arg(args, bool*); 1262 return getWideColorSupport(outSupport); 1263 } 1264 1265 int Surface::dispatchGetHdrSupport(va_list args) { 1266 bool* outSupport = va_arg(args, bool*); 1267 return getHdrSupport(outSupport); 1268 } 1269 1270 int Surface::dispatchGetConsumerUsage64(va_list args) { 1271 uint64_t* usage = va_arg(args, uint64_t*); 1272 return getConsumerUsage(usage); 1273 } 1274 1275 bool Surface::transformToDisplayInverse() { 1276 return (mTransform & NATIVE_WINDOW_TRANSFORM_INVERSE_DISPLAY) == 1277 NATIVE_WINDOW_TRANSFORM_INVERSE_DISPLAY; 1278 } 1279 1280 int Surface::connect(int api) { 1281 static sp<IProducerListener> listener = new DummyProducerListener(); 1282 return connect(api, listener); 1283 } 1284 1285 int Surface::connect(int api, const sp<IProducerListener>& listener) { 1286 return connect(api, listener, false); 1287 } 1288 1289 int Surface::connect( 1290 int api, const sp<IProducerListener>& listener, bool reportBufferRemoval) { 1291 ATRACE_CALL(); 1292 ALOGV("Surface::connect"); 1293 Mutex::Autolock lock(mMutex); 1294 IGraphicBufferProducer::QueueBufferOutput output; 1295 mReportRemovedBuffers = reportBufferRemoval; 1296 int err = mGraphicBufferProducer->connect(listener, api, mProducerControlledByApp, &output); 1297 if (err == NO_ERROR) { 1298 mDefaultWidth = output.width; 1299 mDefaultHeight = output.height; 1300 mNextFrameNumber = output.nextFrameNumber; 1301 1302 // Ignore transform hint if sticky transform is set or transform to display inverse flag is 1303 // set. Transform hint should be ignored if the client is expected to always submit buffers 1304 // in the same orientation. 1305 if (mStickyTransform == 0 && !transformToDisplayInverse()) { 1306 mTransformHint = output.transformHint; 1307 } 1308 1309 mConsumerRunningBehind = (output.numPendingBuffers >= 2); 1310 } 1311 if (!err && api == NATIVE_WINDOW_API_CPU) { 1312 mConnectedToCpu = true; 1313 // Clear the dirty region in case we're switching from a non-CPU API 1314 mDirtyRegion.clear(); 1315 } else if (!err) { 1316 // Initialize the dirty region for tracking surface damage 1317 mDirtyRegion = Region::INVALID_REGION; 1318 } 1319 1320 return err; 1321 } 1322 1323 1324 int Surface::disconnect(int api, IGraphicBufferProducer::DisconnectMode mode) { 1325 ATRACE_CALL(); 1326 ALOGV("Surface::disconnect"); 1327 Mutex::Autolock lock(mMutex); 1328 mRemovedBuffers.clear(); 1329 mSharedBufferSlot = BufferItem::INVALID_BUFFER_SLOT; 1330 mSharedBufferHasBeenQueued = false; 1331 freeAllBuffers(); 1332 int err = mGraphicBufferProducer->disconnect(api, mode); 1333 if (!err) { 1334 mReqFormat = 0; 1335 mReqWidth = 0; 1336 mReqHeight = 0; 1337 mReqUsage = 0; 1338 mCrop.clear(); 1339 mScalingMode = NATIVE_WINDOW_SCALING_MODE_FREEZE; 1340 mTransform = 0; 1341 mStickyTransform = 0; 1342 1343 if (api == NATIVE_WINDOW_API_CPU) { 1344 mConnectedToCpu = false; 1345 } 1346 } 1347 return err; 1348 } 1349 1350 int Surface::detachNextBuffer(sp<GraphicBuffer>* outBuffer, 1351 sp<Fence>* outFence) { 1352 ATRACE_CALL(); 1353 ALOGV("Surface::detachNextBuffer"); 1354 1355 if (outBuffer == nullptr || outFence == nullptr) { 1356 return BAD_VALUE; 1357 } 1358 1359 Mutex::Autolock lock(mMutex); 1360 if (mReportRemovedBuffers) { 1361 mRemovedBuffers.clear(); 1362 } 1363 1364 sp<GraphicBuffer> buffer(nullptr); 1365 sp<Fence> fence(nullptr); 1366 status_t result = mGraphicBufferProducer->detachNextBuffer( 1367 &buffer, &fence); 1368 if (result != NO_ERROR) { 1369 return result; 1370 } 1371 1372 *outBuffer = buffer; 1373 if (fence != nullptr && fence->isValid()) { 1374 *outFence = fence; 1375 } else { 1376 *outFence = Fence::NO_FENCE; 1377 } 1378 1379 for (int i = 0; i < NUM_BUFFER_SLOTS; i++) { 1380 if (mSlots[i].buffer != nullptr && 1381 mSlots[i].buffer->getId() == buffer->getId()) { 1382 if (mReportRemovedBuffers) { 1383 mRemovedBuffers.push_back(mSlots[i].buffer); 1384 } 1385 mSlots[i].buffer = nullptr; 1386 } 1387 } 1388 1389 return NO_ERROR; 1390 } 1391 1392 int Surface::attachBuffer(ANativeWindowBuffer* buffer) 1393 { 1394 ATRACE_CALL(); 1395 ALOGV("Surface::attachBuffer"); 1396 1397 Mutex::Autolock lock(mMutex); 1398 if (mReportRemovedBuffers) { 1399 mRemovedBuffers.clear(); 1400 } 1401 1402 sp<GraphicBuffer> graphicBuffer(static_cast<GraphicBuffer*>(buffer)); 1403 uint32_t priorGeneration = graphicBuffer->mGenerationNumber; 1404 graphicBuffer->mGenerationNumber = mGenerationNumber; 1405 int32_t attachedSlot = -1; 1406 status_t result = mGraphicBufferProducer->attachBuffer(&attachedSlot, graphicBuffer); 1407 if (result != NO_ERROR) { 1408 ALOGE("attachBuffer: IGraphicBufferProducer call failed (%d)", result); 1409 graphicBuffer->mGenerationNumber = priorGeneration; 1410 return result; 1411 } 1412 if (mReportRemovedBuffers && (mSlots[attachedSlot].buffer != nullptr)) { 1413 mRemovedBuffers.push_back(mSlots[attachedSlot].buffer); 1414 } 1415 mSlots[attachedSlot].buffer = graphicBuffer; 1416 1417 return NO_ERROR; 1418 } 1419 1420 int Surface::setUsage(uint64_t reqUsage) 1421 { 1422 ALOGV("Surface::setUsage"); 1423 Mutex::Autolock lock(mMutex); 1424 if (reqUsage != mReqUsage) { 1425 mSharedBufferSlot = BufferItem::INVALID_BUFFER_SLOT; 1426 } 1427 mReqUsage = reqUsage; 1428 return OK; 1429 } 1430 1431 int Surface::setCrop(Rect const* rect) 1432 { 1433 ATRACE_CALL(); 1434 1435 Rect realRect(Rect::EMPTY_RECT); 1436 if (rect == nullptr || rect->isEmpty()) { 1437 realRect.clear(); 1438 } else { 1439 realRect = *rect; 1440 } 1441 1442 ALOGV("Surface::setCrop rect=[%d %d %d %d]", 1443 realRect.left, realRect.top, realRect.right, realRect.bottom); 1444 1445 Mutex::Autolock lock(mMutex); 1446 mCrop = realRect; 1447 return NO_ERROR; 1448 } 1449 1450 int Surface::setBufferCount(int bufferCount) 1451 { 1452 ATRACE_CALL(); 1453 ALOGV("Surface::setBufferCount"); 1454 Mutex::Autolock lock(mMutex); 1455 1456 status_t err = NO_ERROR; 1457 if (bufferCount == 0) { 1458 err = mGraphicBufferProducer->setMaxDequeuedBufferCount(1); 1459 } else { 1460 int minUndequeuedBuffers = 0; 1461 err = mGraphicBufferProducer->query( 1462 NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS, &minUndequeuedBuffers); 1463 if (err == NO_ERROR) { 1464 err = mGraphicBufferProducer->setMaxDequeuedBufferCount( 1465 bufferCount - minUndequeuedBuffers); 1466 } 1467 } 1468 1469 ALOGE_IF(err, "IGraphicBufferProducer::setBufferCount(%d) returned %s", 1470 bufferCount, strerror(-err)); 1471 1472 return err; 1473 } 1474 1475 int Surface::setMaxDequeuedBufferCount(int maxDequeuedBuffers) { 1476 ATRACE_CALL(); 1477 ALOGV("Surface::setMaxDequeuedBufferCount"); 1478 Mutex::Autolock lock(mMutex); 1479 1480 status_t err = mGraphicBufferProducer->setMaxDequeuedBufferCount( 1481 maxDequeuedBuffers); 1482 ALOGE_IF(err, "IGraphicBufferProducer::setMaxDequeuedBufferCount(%d) " 1483 "returned %s", maxDequeuedBuffers, strerror(-err)); 1484 1485 return err; 1486 } 1487 1488 int Surface::setAsyncMode(bool async) { 1489 ATRACE_CALL(); 1490 ALOGV("Surface::setAsyncMode"); 1491 Mutex::Autolock lock(mMutex); 1492 1493 status_t err = mGraphicBufferProducer->setAsyncMode(async); 1494 ALOGE_IF(err, "IGraphicBufferProducer::setAsyncMode(%d) returned %s", 1495 async, strerror(-err)); 1496 1497 return err; 1498 } 1499 1500 int Surface::setSharedBufferMode(bool sharedBufferMode) { 1501 ATRACE_CALL(); 1502 ALOGV("Surface::setSharedBufferMode (%d)", sharedBufferMode); 1503 Mutex::Autolock lock(mMutex); 1504 1505 status_t err = mGraphicBufferProducer->setSharedBufferMode( 1506 sharedBufferMode); 1507 if (err == NO_ERROR) { 1508 mSharedBufferMode = sharedBufferMode; 1509 } 1510 ALOGE_IF(err, "IGraphicBufferProducer::setSharedBufferMode(%d) returned" 1511 "%s", sharedBufferMode, strerror(-err)); 1512 1513 return err; 1514 } 1515 1516 int Surface::setAutoRefresh(bool autoRefresh) { 1517 ATRACE_CALL(); 1518 ALOGV("Surface::setAutoRefresh (%d)", autoRefresh); 1519 Mutex::Autolock lock(mMutex); 1520 1521 status_t err = mGraphicBufferProducer->setAutoRefresh(autoRefresh); 1522 if (err == NO_ERROR) { 1523 mAutoRefresh = autoRefresh; 1524 } 1525 ALOGE_IF(err, "IGraphicBufferProducer::setAutoRefresh(%d) returned %s", 1526 autoRefresh, strerror(-err)); 1527 return err; 1528 } 1529 1530 int Surface::setBuffersDimensions(uint32_t width, uint32_t height) 1531 { 1532 ATRACE_CALL(); 1533 ALOGV("Surface::setBuffersDimensions"); 1534 1535 if ((width && !height) || (!width && height)) 1536 return BAD_VALUE; 1537 1538 Mutex::Autolock lock(mMutex); 1539 if (width != mReqWidth || height != mReqHeight) { 1540 mSharedBufferSlot = BufferItem::INVALID_BUFFER_SLOT; 1541 } 1542 mReqWidth = width; 1543 mReqHeight = height; 1544 return NO_ERROR; 1545 } 1546 1547 int Surface::setBuffersUserDimensions(uint32_t width, uint32_t height) 1548 { 1549 ATRACE_CALL(); 1550 ALOGV("Surface::setBuffersUserDimensions"); 1551 1552 if ((width && !height) || (!width && height)) 1553 return BAD_VALUE; 1554 1555 Mutex::Autolock lock(mMutex); 1556 if (width != mUserWidth || height != mUserHeight) { 1557 mSharedBufferSlot = BufferItem::INVALID_BUFFER_SLOT; 1558 } 1559 mUserWidth = width; 1560 mUserHeight = height; 1561 return NO_ERROR; 1562 } 1563 1564 int Surface::setBuffersFormat(PixelFormat format) 1565 { 1566 ALOGV("Surface::setBuffersFormat"); 1567 1568 Mutex::Autolock lock(mMutex); 1569 if (format != mReqFormat) { 1570 mSharedBufferSlot = BufferItem::INVALID_BUFFER_SLOT; 1571 } 1572 mReqFormat = format; 1573 return NO_ERROR; 1574 } 1575 1576 int Surface::setScalingMode(int mode) 1577 { 1578 ATRACE_CALL(); 1579 ALOGV("Surface::setScalingMode(%d)", mode); 1580 1581 switch (mode) { 1582 case NATIVE_WINDOW_SCALING_MODE_FREEZE: 1583 case NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW: 1584 case NATIVE_WINDOW_SCALING_MODE_SCALE_CROP: 1585 case NATIVE_WINDOW_SCALING_MODE_NO_SCALE_CROP: 1586 break; 1587 default: 1588 ALOGE("unknown scaling mode: %d", mode); 1589 return BAD_VALUE; 1590 } 1591 1592 Mutex::Autolock lock(mMutex); 1593 mScalingMode = mode; 1594 return NO_ERROR; 1595 } 1596 1597 int Surface::setBuffersTransform(uint32_t transform) 1598 { 1599 ATRACE_CALL(); 1600 ALOGV("Surface::setBuffersTransform"); 1601 Mutex::Autolock lock(mMutex); 1602 // Ensure NATIVE_WINDOW_TRANSFORM_INVERSE_DISPLAY is sticky. If the client sets the flag, do not 1603 // override it until the surface is disconnected. This is a temporary workaround for camera 1604 // until they switch to using Buffer State Layers. Currently if client sets the buffer transform 1605 // it may be overriden by the buffer producer when the producer sets the buffer transform. 1606 if (transformToDisplayInverse()) { 1607 transform |= NATIVE_WINDOW_TRANSFORM_INVERSE_DISPLAY; 1608 } 1609 mTransform = transform; 1610 return NO_ERROR; 1611 } 1612 1613 int Surface::setBuffersStickyTransform(uint32_t transform) 1614 { 1615 ATRACE_CALL(); 1616 ALOGV("Surface::setBuffersStickyTransform"); 1617 Mutex::Autolock lock(mMutex); 1618 mStickyTransform = transform; 1619 return NO_ERROR; 1620 } 1621 1622 int Surface::setBuffersTimestamp(int64_t timestamp) 1623 { 1624 ALOGV("Surface::setBuffersTimestamp"); 1625 Mutex::Autolock lock(mMutex); 1626 mTimestamp = timestamp; 1627 return NO_ERROR; 1628 } 1629 1630 int Surface::setBuffersDataSpace(Dataspace dataSpace) 1631 { 1632 ALOGV("Surface::setBuffersDataSpace"); 1633 Mutex::Autolock lock(mMutex); 1634 mDataSpace = dataSpace; 1635 return NO_ERROR; 1636 } 1637 1638 int Surface::setBuffersSmpte2086Metadata(const android_smpte2086_metadata* metadata) { 1639 ALOGV("Surface::setBuffersSmpte2086Metadata"); 1640 Mutex::Autolock lock(mMutex); 1641 if (metadata) { 1642 mHdrMetadata.smpte2086 = *metadata; 1643 mHdrMetadata.validTypes |= HdrMetadata::SMPTE2086; 1644 } else { 1645 mHdrMetadata.validTypes &= ~HdrMetadata::SMPTE2086; 1646 } 1647 return NO_ERROR; 1648 } 1649 1650 int Surface::setBuffersCta8613Metadata(const android_cta861_3_metadata* metadata) { 1651 ALOGV("Surface::setBuffersCta8613Metadata"); 1652 Mutex::Autolock lock(mMutex); 1653 if (metadata) { 1654 mHdrMetadata.cta8613 = *metadata; 1655 mHdrMetadata.validTypes |= HdrMetadata::CTA861_3; 1656 } else { 1657 mHdrMetadata.validTypes &= ~HdrMetadata::CTA861_3; 1658 } 1659 return NO_ERROR; 1660 } 1661 1662 int Surface::setBuffersHdr10PlusMetadata(const size_t size, const uint8_t* metadata) { 1663 ALOGV("Surface::setBuffersBlobMetadata"); 1664 Mutex::Autolock lock(mMutex); 1665 if (size > 0) { 1666 mHdrMetadata.hdr10plus.assign(metadata, metadata + size); 1667 mHdrMetadata.validTypes |= HdrMetadata::HDR10PLUS; 1668 } else { 1669 mHdrMetadata.validTypes &= ~HdrMetadata::HDR10PLUS; 1670 mHdrMetadata.hdr10plus.clear(); 1671 } 1672 return NO_ERROR; 1673 } 1674 1675 Dataspace Surface::getBuffersDataSpace() { 1676 ALOGV("Surface::getBuffersDataSpace"); 1677 Mutex::Autolock lock(mMutex); 1678 return mDataSpace; 1679 } 1680 1681 void Surface::freeAllBuffers() { 1682 for (int i = 0; i < NUM_BUFFER_SLOTS; i++) { 1683 mSlots[i].buffer = nullptr; 1684 } 1685 } 1686 1687 void Surface::setSurfaceDamage(android_native_rect_t* rects, size_t numRects) { 1688 ATRACE_CALL(); 1689 ALOGV("Surface::setSurfaceDamage"); 1690 Mutex::Autolock lock(mMutex); 1691 1692 if (mConnectedToCpu || numRects == 0) { 1693 mDirtyRegion = Region::INVALID_REGION; 1694 return; 1695 } 1696 1697 mDirtyRegion.clear(); 1698 for (size_t r = 0; r < numRects; ++r) { 1699 // We intentionally flip top and bottom here, since because they're 1700 // specified with a bottom-left origin, top > bottom, which fails 1701 // validation in the Region class. We will fix this up when we flip to a 1702 // top-left origin in queueBuffer. 1703 Rect rect(rects[r].left, rects[r].bottom, rects[r].right, rects[r].top); 1704 mDirtyRegion.orSelf(rect); 1705 } 1706 } 1707 1708 // ---------------------------------------------------------------------- 1709 // the lock/unlock APIs must be used from the same thread 1710 1711 static status_t copyBlt( 1712 const sp<GraphicBuffer>& dst, 1713 const sp<GraphicBuffer>& src, 1714 const Region& reg, 1715 int *dstFenceFd) 1716 { 1717 if (dst->getId() == src->getId()) 1718 return OK; 1719 1720 // src and dst with, height and format must be identical. no verification 1721 // is done here. 1722 status_t err; 1723 uint8_t* src_bits = nullptr; 1724 err = src->lock(GRALLOC_USAGE_SW_READ_OFTEN, reg.bounds(), 1725 reinterpret_cast<void**>(&src_bits)); 1726 ALOGE_IF(err, "error locking src buffer %s", strerror(-err)); 1727 1728 uint8_t* dst_bits = nullptr; 1729 err = dst->lockAsync(GRALLOC_USAGE_SW_WRITE_OFTEN, reg.bounds(), 1730 reinterpret_cast<void**>(&dst_bits), *dstFenceFd); 1731 ALOGE_IF(err, "error locking dst buffer %s", strerror(-err)); 1732 *dstFenceFd = -1; 1733 1734 Region::const_iterator head(reg.begin()); 1735 Region::const_iterator tail(reg.end()); 1736 if (head != tail && src_bits && dst_bits) { 1737 const size_t bpp = bytesPerPixel(src->format); 1738 const size_t dbpr = static_cast<uint32_t>(dst->stride) * bpp; 1739 const size_t sbpr = static_cast<uint32_t>(src->stride) * bpp; 1740 1741 while (head != tail) { 1742 const Rect& r(*head++); 1743 int32_t h = r.height(); 1744 if (h <= 0) continue; 1745 size_t size = static_cast<uint32_t>(r.width()) * bpp; 1746 uint8_t const * s = src_bits + 1747 static_cast<uint32_t>(r.left + src->stride * r.top) * bpp; 1748 uint8_t * d = dst_bits + 1749 static_cast<uint32_t>(r.left + dst->stride * r.top) * bpp; 1750 if (dbpr==sbpr && size==sbpr) { 1751 size *= static_cast<size_t>(h); 1752 h = 1; 1753 } 1754 do { 1755 memcpy(d, s, size); 1756 d += dbpr; 1757 s += sbpr; 1758 } while (--h > 0); 1759 } 1760 } 1761 1762 if (src_bits) 1763 src->unlock(); 1764 1765 if (dst_bits) 1766 dst->unlockAsync(dstFenceFd); 1767 1768 return err; 1769 } 1770 1771 // ---------------------------------------------------------------------------- 1772 1773 status_t Surface::lock( 1774 ANativeWindow_Buffer* outBuffer, ARect* inOutDirtyBounds) 1775 { 1776 if (mLockedBuffer != nullptr) { 1777 ALOGE("Surface::lock failed, already locked"); 1778 return INVALID_OPERATION; 1779 } 1780 1781 if (!mConnectedToCpu) { 1782 int err = Surface::connect(NATIVE_WINDOW_API_CPU); 1783 if (err) { 1784 return err; 1785 } 1786 // we're intending to do software rendering from this point 1787 setUsage(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN); 1788 } 1789 1790 ANativeWindowBuffer* out; 1791 int fenceFd = -1; 1792 status_t err = dequeueBuffer(&out, &fenceFd); 1793 ALOGE_IF(err, "dequeueBuffer failed (%s)", strerror(-err)); 1794 if (err == NO_ERROR) { 1795 sp<GraphicBuffer> backBuffer(GraphicBuffer::getSelf(out)); 1796 const Rect bounds(backBuffer->width, backBuffer->height); 1797 1798 Region newDirtyRegion; 1799 if (inOutDirtyBounds) { 1800 newDirtyRegion.set(static_cast<Rect const&>(*inOutDirtyBounds)); 1801 newDirtyRegion.andSelf(bounds); 1802 } else { 1803 newDirtyRegion.set(bounds); 1804 } 1805 1806 // figure out if we can copy the frontbuffer back 1807 const sp<GraphicBuffer>& frontBuffer(mPostedBuffer); 1808 const bool canCopyBack = (frontBuffer != nullptr && 1809 backBuffer->width == frontBuffer->width && 1810 backBuffer->height == frontBuffer->height && 1811 backBuffer->format == frontBuffer->format); 1812 1813 if (canCopyBack) { 1814 // copy the area that is invalid and not repainted this round 1815 const Region copyback(mDirtyRegion.subtract(newDirtyRegion)); 1816 if (!copyback.isEmpty()) { 1817 copyBlt(backBuffer, frontBuffer, copyback, &fenceFd); 1818 } 1819 } else { 1820 // if we can't copy-back anything, modify the user's dirty 1821 // region to make sure they redraw the whole buffer 1822 newDirtyRegion.set(bounds); 1823 mDirtyRegion.clear(); 1824 Mutex::Autolock lock(mMutex); 1825 for (size_t i=0 ; i<NUM_BUFFER_SLOTS ; i++) { 1826 mSlots[i].dirtyRegion.clear(); 1827 } 1828 } 1829 1830 1831 { // scope for the lock 1832 Mutex::Autolock lock(mMutex); 1833 int backBufferSlot(getSlotFromBufferLocked(backBuffer.get())); 1834 if (backBufferSlot >= 0) { 1835 Region& dirtyRegion(mSlots[backBufferSlot].dirtyRegion); 1836 mDirtyRegion.subtract(dirtyRegion); 1837 dirtyRegion = newDirtyRegion; 1838 } 1839 } 1840 1841 mDirtyRegion.orSelf(newDirtyRegion); 1842 if (inOutDirtyBounds) { 1843 *inOutDirtyBounds = newDirtyRegion.getBounds(); 1844 } 1845 1846 void* vaddr; 1847 status_t res = backBuffer->lockAsync( 1848 GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN, 1849 newDirtyRegion.bounds(), &vaddr, fenceFd); 1850 1851 ALOGW_IF(res, "failed locking buffer (handle = %p)", 1852 backBuffer->handle); 1853 1854 if (res != 0) { 1855 err = INVALID_OPERATION; 1856 } else { 1857 mLockedBuffer = backBuffer; 1858 outBuffer->width = backBuffer->width; 1859 outBuffer->height = backBuffer->height; 1860 outBuffer->stride = backBuffer->stride; 1861 outBuffer->format = backBuffer->format; 1862 outBuffer->bits = vaddr; 1863 } 1864 } 1865 return err; 1866 } 1867 1868 status_t Surface::unlockAndPost() 1869 { 1870 if (mLockedBuffer == nullptr) { 1871 ALOGE("Surface::unlockAndPost failed, no locked buffer"); 1872 return INVALID_OPERATION; 1873 } 1874 1875 int fd = -1; 1876 status_t err = mLockedBuffer->unlockAsync(&fd); 1877 ALOGE_IF(err, "failed unlocking buffer (%p)", mLockedBuffer->handle); 1878 1879 err = queueBuffer(mLockedBuffer.get(), fd); 1880 ALOGE_IF(err, "queueBuffer (handle=%p) failed (%s)", 1881 mLockedBuffer->handle, strerror(-err)); 1882 1883 mPostedBuffer = mLockedBuffer; 1884 mLockedBuffer = nullptr; 1885 return err; 1886 } 1887 1888 bool Surface::waitForNextFrame(uint64_t lastFrame, nsecs_t timeout) { 1889 Mutex::Autolock lock(mMutex); 1890 if (mNextFrameNumber > lastFrame) { 1891 return true; 1892 } 1893 return mQueueBufferCondition.waitRelative(mMutex, timeout) == OK; 1894 } 1895 1896 status_t Surface::getUniqueId(uint64_t* outId) const { 1897 Mutex::Autolock lock(mMutex); 1898 return mGraphicBufferProducer->getUniqueId(outId); 1899 } 1900 1901 int Surface::getConsumerUsage(uint64_t* outUsage) const { 1902 Mutex::Autolock lock(mMutex); 1903 return mGraphicBufferProducer->getConsumerUsage(outUsage); 1904 } 1905 1906 nsecs_t Surface::getLastDequeueStartTime() const { 1907 Mutex::Autolock lock(mMutex); 1908 return mLastDequeueStartTime; 1909 } 1910 1911 status_t Surface::getAndFlushRemovedBuffers(std::vector<sp<GraphicBuffer>>* out) { 1912 if (out == nullptr) { 1913 ALOGE("%s: out must not be null!", __FUNCTION__); 1914 return BAD_VALUE; 1915 } 1916 1917 Mutex::Autolock lock(mMutex); 1918 *out = mRemovedBuffers; 1919 mRemovedBuffers.clear(); 1920 return OK; 1921 } 1922 1923 status_t Surface::attachAndQueueBuffer(Surface* surface, sp<GraphicBuffer> buffer) { 1924 if (buffer == nullptr) { 1925 return BAD_VALUE; 1926 } 1927 int err = static_cast<ANativeWindow*>(surface)->perform(surface, NATIVE_WINDOW_API_CONNECT, 1928 NATIVE_WINDOW_API_CPU); 1929 if (err != OK) { 1930 return err; 1931 } 1932 err = surface->attachBuffer(buffer->getNativeBuffer()); 1933 if (err != OK) { 1934 return err; 1935 } 1936 err = static_cast<ANativeWindow*>(surface)->queueBuffer(surface, buffer->getNativeBuffer(), -1); 1937 if (err != OK) { 1938 return err; 1939 } 1940 err = surface->disconnect(NATIVE_WINDOW_API_CPU); 1941 return err; 1942 } 1943 1944 }; // namespace android 1945