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