1 /* 2 * Copyright (C) 2007 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_NDEBUG 0 18 #undef LOG_TAG 19 #define LOG_TAG "DisplayDevice" 20 21 #include <array> 22 #include <unordered_set> 23 24 #include <stdlib.h> 25 #include <stdio.h> 26 #include <string.h> 27 #include <math.h> 28 29 #include <cutils/properties.h> 30 31 #include <utils/RefBase.h> 32 #include <utils/Log.h> 33 34 #include <ui/DebugUtils.h> 35 #include <ui/DisplayInfo.h> 36 #include <ui/PixelFormat.h> 37 38 #include <gui/Surface.h> 39 40 #include <hardware/gralloc.h> 41 42 #include "DisplayHardware/DisplaySurface.h" 43 #include "DisplayHardware/HWComposer.h" 44 #include "DisplayHardware/HWC2.h" 45 #include "RenderEngine/RenderEngine.h" 46 47 #include "clz.h" 48 #include "DisplayDevice.h" 49 #include "SurfaceFlinger.h" 50 #include "Layer.h" 51 52 #include <android/hardware/configstore/1.0/ISurfaceFlingerConfigs.h> 53 #include <configstore/Utils.h> 54 55 namespace android { 56 57 // retrieve triple buffer setting from configstore 58 using namespace android::hardware::configstore; 59 using namespace android::hardware::configstore::V1_0; 60 using android::ui::ColorMode; 61 using android::ui::Dataspace; 62 using android::ui::Hdr; 63 using android::ui::RenderIntent; 64 65 /* 66 * Initialize the display to the specified values. 67 * 68 */ 69 70 uint32_t DisplayDevice::sPrimaryDisplayOrientation = 0; 71 72 namespace { 73 74 // ordered list of known SDR color modes 75 const std::array<ColorMode, 2> sSdrColorModes = { 76 ColorMode::DISPLAY_P3, 77 ColorMode::SRGB, 78 }; 79 80 // ordered list of known HDR color modes 81 const std::array<ColorMode, 2> sHdrColorModes = { 82 ColorMode::BT2100_PQ, 83 ColorMode::BT2100_HLG, 84 }; 85 86 // ordered list of known SDR render intents 87 const std::array<RenderIntent, 2> sSdrRenderIntents = { 88 RenderIntent::ENHANCE, 89 RenderIntent::COLORIMETRIC, 90 }; 91 92 // ordered list of known HDR render intents 93 const std::array<RenderIntent, 2> sHdrRenderIntents = { 94 RenderIntent::TONE_MAP_ENHANCE, 95 RenderIntent::TONE_MAP_COLORIMETRIC, 96 }; 97 98 // map known color mode to dataspace 99 Dataspace colorModeToDataspace(ColorMode mode) { 100 switch (mode) { 101 case ColorMode::SRGB: 102 return Dataspace::SRGB; 103 case ColorMode::DISPLAY_P3: 104 return Dataspace::DISPLAY_P3; 105 case ColorMode::BT2100_HLG: 106 return Dataspace::BT2020_HLG; 107 case ColorMode::BT2100_PQ: 108 return Dataspace::BT2020_PQ; 109 default: 110 return Dataspace::UNKNOWN; 111 } 112 } 113 114 // Return a list of candidate color modes. 115 std::vector<ColorMode> getColorModeCandidates(ColorMode mode) { 116 std::vector<ColorMode> candidates; 117 118 // add mode itself 119 candidates.push_back(mode); 120 121 // check if mode is HDR 122 bool isHdr = false; 123 for (auto hdrMode : sHdrColorModes) { 124 if (hdrMode == mode) { 125 isHdr = true; 126 break; 127 } 128 } 129 130 // add other HDR candidates when mode is HDR 131 if (isHdr) { 132 for (auto hdrMode : sHdrColorModes) { 133 if (hdrMode != mode) { 134 candidates.push_back(hdrMode); 135 } 136 } 137 } 138 139 // add other SDR candidates 140 for (auto sdrMode : sSdrColorModes) { 141 if (sdrMode != mode) { 142 candidates.push_back(sdrMode); 143 } 144 } 145 146 return candidates; 147 } 148 149 // Return a list of candidate render intents. 150 std::vector<RenderIntent> getRenderIntentCandidates(RenderIntent intent) { 151 std::vector<RenderIntent> candidates; 152 153 // add intent itself 154 candidates.push_back(intent); 155 156 // check if intent is HDR 157 bool isHdr = false; 158 for (auto hdrIntent : sHdrRenderIntents) { 159 if (hdrIntent == intent) { 160 isHdr = true; 161 break; 162 } 163 } 164 165 if (isHdr) { 166 // add other HDR candidates when intent is HDR 167 for (auto hdrIntent : sHdrRenderIntents) { 168 if (hdrIntent != intent) { 169 candidates.push_back(hdrIntent); 170 } 171 } 172 } else { 173 // add other SDR candidates when intent is SDR 174 for (auto sdrIntent : sSdrRenderIntents) { 175 if (sdrIntent != intent) { 176 candidates.push_back(sdrIntent); 177 } 178 } 179 } 180 181 return candidates; 182 } 183 184 // Return the best color mode supported by HWC. 185 ColorMode getHwcColorMode( 186 const std::unordered_map<ColorMode, std::vector<RenderIntent>>& hwcColorModes, 187 ColorMode mode) { 188 std::vector<ColorMode> candidates = getColorModeCandidates(mode); 189 for (auto candidate : candidates) { 190 auto iter = hwcColorModes.find(candidate); 191 if (iter != hwcColorModes.end()) { 192 return candidate; 193 } 194 } 195 196 return ColorMode::NATIVE; 197 } 198 199 // Return the best render intent supported by HWC. 200 RenderIntent getHwcRenderIntent(const std::vector<RenderIntent>& hwcIntents, RenderIntent intent) { 201 std::vector<RenderIntent> candidates = getRenderIntentCandidates(intent); 202 for (auto candidate : candidates) { 203 for (auto hwcIntent : hwcIntents) { 204 if (candidate == hwcIntent) { 205 return candidate; 206 } 207 } 208 } 209 210 return RenderIntent::COLORIMETRIC; 211 } 212 213 } // anonymous namespace 214 215 // clang-format off 216 DisplayDevice::DisplayDevice( 217 const sp<SurfaceFlinger>& flinger, 218 DisplayType type, 219 int32_t hwcId, 220 bool isSecure, 221 const wp<IBinder>& displayToken, 222 const sp<ANativeWindow>& nativeWindow, 223 const sp<DisplaySurface>& displaySurface, 224 std::unique_ptr<RE::Surface> renderSurface, 225 int displayWidth, 226 int displayHeight, 227 bool hasWideColorGamut, 228 const HdrCapabilities& hdrCapabilities, 229 const int32_t supportedPerFrameMetadata, 230 const std::unordered_map<ColorMode, std::vector<RenderIntent>>& hwcColorModes, 231 int initialPowerMode) 232 : lastCompositionHadVisibleLayers(false), 233 mFlinger(flinger), 234 mType(type), 235 mHwcDisplayId(hwcId), 236 mDisplayToken(displayToken), 237 mNativeWindow(nativeWindow), 238 mDisplaySurface(displaySurface), 239 mSurface{std::move(renderSurface)}, 240 mDisplayWidth(displayWidth), 241 mDisplayHeight(displayHeight), 242 mPageFlipCount(0), 243 mIsSecure(isSecure), 244 mLayerStack(NO_LAYER_STACK), 245 mOrientation(), 246 mViewport(Rect::INVALID_RECT), 247 mFrame(Rect::INVALID_RECT), 248 mPowerMode(initialPowerMode), 249 mActiveConfig(0), 250 mColorTransform(HAL_COLOR_TRANSFORM_IDENTITY), 251 mHasWideColorGamut(hasWideColorGamut), 252 mHasHdr10(false), 253 mHasHLG(false), 254 mHasDolbyVision(false), 255 mSupportedPerFrameMetadata(supportedPerFrameMetadata) 256 { 257 // clang-format on 258 populateColorModes(hwcColorModes); 259 260 std::vector<Hdr> types = hdrCapabilities.getSupportedHdrTypes(); 261 for (Hdr hdrType : types) { 262 switch (hdrType) { 263 case Hdr::HDR10: 264 mHasHdr10 = true; 265 break; 266 case Hdr::HLG: 267 mHasHLG = true; 268 break; 269 case Hdr::DOLBY_VISION: 270 mHasDolbyVision = true; 271 break; 272 default: 273 ALOGE("UNKNOWN HDR capability: %d", static_cast<int32_t>(hdrType)); 274 } 275 } 276 277 float minLuminance = hdrCapabilities.getDesiredMinLuminance(); 278 float maxLuminance = hdrCapabilities.getDesiredMaxLuminance(); 279 float maxAverageLuminance = hdrCapabilities.getDesiredMaxAverageLuminance(); 280 281 minLuminance = minLuminance <= 0.0 ? sDefaultMinLumiance : minLuminance; 282 maxLuminance = maxLuminance <= 0.0 ? sDefaultMaxLumiance : maxLuminance; 283 maxAverageLuminance = maxAverageLuminance <= 0.0 ? sDefaultMaxLumiance : maxAverageLuminance; 284 if (this->hasWideColorGamut()) { 285 // insert HDR10/HLG as we will force client composition for HDR10/HLG 286 // layers 287 if (!hasHDR10Support()) { 288 types.push_back(Hdr::HDR10); 289 } 290 291 if (!hasHLGSupport()) { 292 types.push_back(Hdr::HLG); 293 } 294 } 295 mHdrCapabilities = HdrCapabilities(types, maxLuminance, maxAverageLuminance, minLuminance); 296 297 // initialize the display orientation transform. 298 setProjection(DisplayState::eOrientationDefault, mViewport, mFrame); 299 } 300 301 DisplayDevice::~DisplayDevice() = default; 302 303 void DisplayDevice::disconnect(HWComposer& hwc) { 304 if (mHwcDisplayId >= 0) { 305 hwc.disconnectDisplay(mHwcDisplayId); 306 mHwcDisplayId = -1; 307 } 308 } 309 310 bool DisplayDevice::isValid() const { 311 return mFlinger != nullptr; 312 } 313 314 int DisplayDevice::getWidth() const { 315 return mDisplayWidth; 316 } 317 318 int DisplayDevice::getHeight() const { 319 return mDisplayHeight; 320 } 321 322 void DisplayDevice::setDisplayName(const String8& displayName) { 323 if (!displayName.isEmpty()) { 324 // never override the name with an empty name 325 mDisplayName = displayName; 326 } 327 } 328 329 uint32_t DisplayDevice::getPageFlipCount() const { 330 return mPageFlipCount; 331 } 332 333 void DisplayDevice::flip() const 334 { 335 mFlinger->getRenderEngine().checkErrors(); 336 mPageFlipCount++; 337 } 338 339 status_t DisplayDevice::beginFrame(bool mustRecompose) const { 340 return mDisplaySurface->beginFrame(mustRecompose); 341 } 342 343 status_t DisplayDevice::prepareFrame(HWComposer& hwc) { 344 status_t error = hwc.prepare(*this); 345 if (error != NO_ERROR) { 346 return error; 347 } 348 349 DisplaySurface::CompositionType compositionType; 350 bool hasClient = hwc.hasClientComposition(mHwcDisplayId); 351 bool hasDevice = hwc.hasDeviceComposition(mHwcDisplayId); 352 if (hasClient && hasDevice) { 353 compositionType = DisplaySurface::COMPOSITION_MIXED; 354 } else if (hasClient) { 355 compositionType = DisplaySurface::COMPOSITION_GLES; 356 } else if (hasDevice) { 357 compositionType = DisplaySurface::COMPOSITION_HWC; 358 } else { 359 // Nothing to do -- when turning the screen off we get a frame like 360 // this. Call it a HWC frame since we won't be doing any GLES work but 361 // will do a prepare/set cycle. 362 compositionType = DisplaySurface::COMPOSITION_HWC; 363 } 364 return mDisplaySurface->prepareFrame(compositionType); 365 } 366 367 void DisplayDevice::swapBuffers(HWComposer& hwc) const { 368 if (hwc.hasClientComposition(mHwcDisplayId) || hwc.hasFlipClientTargetRequest(mHwcDisplayId)) { 369 mSurface->swapBuffers(); 370 } 371 372 status_t result = mDisplaySurface->advanceFrame(); 373 if (result != NO_ERROR) { 374 ALOGE("[%s] failed pushing new frame to HWC: %d", 375 mDisplayName.string(), result); 376 } 377 } 378 379 void DisplayDevice::onSwapBuffersCompleted() const { 380 mDisplaySurface->onFrameCommitted(); 381 } 382 383 bool DisplayDevice::makeCurrent() const { 384 bool success = mFlinger->getRenderEngine().setCurrentSurface(*mSurface); 385 setViewportAndProjection(); 386 return success; 387 } 388 389 void DisplayDevice::setViewportAndProjection() const { 390 size_t w = mDisplayWidth; 391 size_t h = mDisplayHeight; 392 Rect sourceCrop(0, 0, w, h); 393 mFlinger->getRenderEngine().setViewportAndProjection(w, h, sourceCrop, h, 394 false, Transform::ROT_0); 395 } 396 397 const sp<Fence>& DisplayDevice::getClientTargetAcquireFence() const { 398 return mDisplaySurface->getClientTargetAcquireFence(); 399 } 400 401 // ---------------------------------------------------------------------------- 402 403 void DisplayDevice::setVisibleLayersSortedByZ(const Vector< sp<Layer> >& layers) { 404 mVisibleLayersSortedByZ = layers; 405 } 406 407 const Vector< sp<Layer> >& DisplayDevice::getVisibleLayersSortedByZ() const { 408 return mVisibleLayersSortedByZ; 409 } 410 411 void DisplayDevice::setLayersNeedingFences(const Vector< sp<Layer> >& layers) { 412 mLayersNeedingFences = layers; 413 } 414 415 const Vector< sp<Layer> >& DisplayDevice::getLayersNeedingFences() const { 416 return mLayersNeedingFences; 417 } 418 419 Region DisplayDevice::getDirtyRegion(bool repaintEverything) const { 420 Region dirty; 421 if (repaintEverything) { 422 dirty.set(getBounds()); 423 } else { 424 const Transform& planeTransform(mGlobalTransform); 425 dirty = planeTransform.transform(this->dirtyRegion); 426 dirty.andSelf(getBounds()); 427 } 428 return dirty; 429 } 430 431 // ---------------------------------------------------------------------------- 432 void DisplayDevice::setPowerMode(int mode) { 433 mPowerMode = mode; 434 } 435 436 int DisplayDevice::getPowerMode() const { 437 return mPowerMode; 438 } 439 440 bool DisplayDevice::isDisplayOn() const { 441 return (mPowerMode != HWC_POWER_MODE_OFF); 442 } 443 444 // ---------------------------------------------------------------------------- 445 void DisplayDevice::setActiveConfig(int mode) { 446 mActiveConfig = mode; 447 } 448 449 int DisplayDevice::getActiveConfig() const { 450 return mActiveConfig; 451 } 452 453 // ---------------------------------------------------------------------------- 454 void DisplayDevice::setActiveColorMode(ColorMode mode) { 455 mActiveColorMode = mode; 456 } 457 458 ColorMode DisplayDevice::getActiveColorMode() const { 459 return mActiveColorMode; 460 } 461 462 RenderIntent DisplayDevice::getActiveRenderIntent() const { 463 return mActiveRenderIntent; 464 } 465 466 void DisplayDevice::setActiveRenderIntent(RenderIntent renderIntent) { 467 mActiveRenderIntent = renderIntent; 468 } 469 470 void DisplayDevice::setColorTransform(const mat4& transform) { 471 const bool isIdentity = (transform == mat4()); 472 mColorTransform = 473 isIdentity ? HAL_COLOR_TRANSFORM_IDENTITY : HAL_COLOR_TRANSFORM_ARBITRARY_MATRIX; 474 } 475 476 android_color_transform_t DisplayDevice::getColorTransform() const { 477 return mColorTransform; 478 } 479 480 void DisplayDevice::setCompositionDataSpace(ui::Dataspace dataspace) { 481 mCompositionDataSpace = dataspace; 482 ANativeWindow* const window = mNativeWindow.get(); 483 native_window_set_buffers_data_space(window, static_cast<android_dataspace>(dataspace)); 484 } 485 486 ui::Dataspace DisplayDevice::getCompositionDataSpace() const { 487 return mCompositionDataSpace; 488 } 489 490 // ---------------------------------------------------------------------------- 491 492 void DisplayDevice::setLayerStack(uint32_t stack) { 493 mLayerStack = stack; 494 dirtyRegion.set(bounds()); 495 } 496 497 // ---------------------------------------------------------------------------- 498 499 uint32_t DisplayDevice::getOrientationTransform() const { 500 uint32_t transform = 0; 501 switch (mOrientation) { 502 case DisplayState::eOrientationDefault: 503 transform = Transform::ROT_0; 504 break; 505 case DisplayState::eOrientation90: 506 transform = Transform::ROT_90; 507 break; 508 case DisplayState::eOrientation180: 509 transform = Transform::ROT_180; 510 break; 511 case DisplayState::eOrientation270: 512 transform = Transform::ROT_270; 513 break; 514 } 515 return transform; 516 } 517 518 status_t DisplayDevice::orientationToTransfrom( 519 int orientation, int w, int h, Transform* tr) 520 { 521 uint32_t flags = 0; 522 switch (orientation) { 523 case DisplayState::eOrientationDefault: 524 flags = Transform::ROT_0; 525 break; 526 case DisplayState::eOrientation90: 527 flags = Transform::ROT_90; 528 break; 529 case DisplayState::eOrientation180: 530 flags = Transform::ROT_180; 531 break; 532 case DisplayState::eOrientation270: 533 flags = Transform::ROT_270; 534 break; 535 default: 536 return BAD_VALUE; 537 } 538 tr->set(flags, w, h); 539 return NO_ERROR; 540 } 541 542 void DisplayDevice::setDisplaySize(const int newWidth, const int newHeight) { 543 dirtyRegion.set(getBounds()); 544 545 mSurface->setNativeWindow(nullptr); 546 547 mDisplaySurface->resizeBuffers(newWidth, newHeight); 548 549 ANativeWindow* const window = mNativeWindow.get(); 550 mSurface->setNativeWindow(window); 551 mDisplayWidth = mSurface->queryWidth(); 552 mDisplayHeight = mSurface->queryHeight(); 553 554 LOG_FATAL_IF(mDisplayWidth != newWidth, 555 "Unable to set new width to %d", newWidth); 556 LOG_FATAL_IF(mDisplayHeight != newHeight, 557 "Unable to set new height to %d", newHeight); 558 } 559 560 void DisplayDevice::setProjection(int orientation, 561 const Rect& newViewport, const Rect& newFrame) { 562 Rect viewport(newViewport); 563 Rect frame(newFrame); 564 565 const int w = mDisplayWidth; 566 const int h = mDisplayHeight; 567 568 Transform R; 569 DisplayDevice::orientationToTransfrom(orientation, w, h, &R); 570 571 if (!frame.isValid()) { 572 // the destination frame can be invalid if it has never been set, 573 // in that case we assume the whole display frame. 574 frame = Rect(w, h); 575 } 576 577 if (viewport.isEmpty()) { 578 // viewport can be invalid if it has never been set, in that case 579 // we assume the whole display size. 580 // it's also invalid to have an empty viewport, so we handle that 581 // case in the same way. 582 viewport = Rect(w, h); 583 if (R.getOrientation() & Transform::ROT_90) { 584 // viewport is always specified in the logical orientation 585 // of the display (ie: post-rotation). 586 swap(viewport.right, viewport.bottom); 587 } 588 } 589 590 dirtyRegion.set(getBounds()); 591 592 Transform TL, TP, S; 593 float src_width = viewport.width(); 594 float src_height = viewport.height(); 595 float dst_width = frame.width(); 596 float dst_height = frame.height(); 597 if (src_width != dst_width || src_height != dst_height) { 598 float sx = dst_width / src_width; 599 float sy = dst_height / src_height; 600 S.set(sx, 0, 0, sy); 601 } 602 603 float src_x = viewport.left; 604 float src_y = viewport.top; 605 float dst_x = frame.left; 606 float dst_y = frame.top; 607 TL.set(-src_x, -src_y); 608 TP.set(dst_x, dst_y); 609 610 // need to take care of primary display rotation for mGlobalTransform 611 // for case if the panel is not installed aligned with device orientation 612 if (mType == DisplayType::DISPLAY_PRIMARY) { 613 int primaryDisplayOrientation = mFlinger->getPrimaryDisplayOrientation(); 614 DisplayDevice::orientationToTransfrom( 615 (orientation + primaryDisplayOrientation) % (DisplayState::eOrientation270 + 1), 616 w, h, &R); 617 } 618 619 // The viewport and frame are both in the logical orientation. 620 // Apply the logical translation, scale to physical size, apply the 621 // physical translation and finally rotate to the physical orientation. 622 mGlobalTransform = R * TP * S * TL; 623 624 const uint8_t type = mGlobalTransform.getType(); 625 mNeedsFiltering = (!mGlobalTransform.preserveRects() || 626 (type >= Transform::SCALE)); 627 628 mScissor = mGlobalTransform.transform(viewport); 629 if (mScissor.isEmpty()) { 630 mScissor = getBounds(); 631 } 632 633 mOrientation = orientation; 634 if (mType == DisplayType::DISPLAY_PRIMARY) { 635 uint32_t transform = 0; 636 switch (mOrientation) { 637 case DisplayState::eOrientationDefault: 638 transform = Transform::ROT_0; 639 break; 640 case DisplayState::eOrientation90: 641 transform = Transform::ROT_90; 642 break; 643 case DisplayState::eOrientation180: 644 transform = Transform::ROT_180; 645 break; 646 case DisplayState::eOrientation270: 647 transform = Transform::ROT_270; 648 break; 649 } 650 sPrimaryDisplayOrientation = transform; 651 } 652 mViewport = viewport; 653 mFrame = frame; 654 } 655 656 uint32_t DisplayDevice::getPrimaryDisplayOrientationTransform() { 657 return sPrimaryDisplayOrientation; 658 } 659 660 void DisplayDevice::dump(String8& result) const { 661 const Transform& tr(mGlobalTransform); 662 ANativeWindow* const window = mNativeWindow.get(); 663 result.appendFormat("+ DisplayDevice: %s\n", mDisplayName.string()); 664 result.appendFormat(" type=%x, hwcId=%d, layerStack=%u, (%4dx%4d), ANativeWindow=%p " 665 "(%d:%d:%d:%d), orient=%2d (type=%08x), " 666 "flips=%u, isSecure=%d, powerMode=%d, activeConfig=%d, numLayers=%zu\n", 667 mType, mHwcDisplayId, mLayerStack, mDisplayWidth, mDisplayHeight, window, 668 mSurface->queryRedSize(), mSurface->queryGreenSize(), 669 mSurface->queryBlueSize(), mSurface->queryAlphaSize(), mOrientation, 670 tr.getType(), getPageFlipCount(), mIsSecure, mPowerMode, mActiveConfig, 671 mVisibleLayersSortedByZ.size()); 672 result.appendFormat(" v:[%d,%d,%d,%d], f:[%d,%d,%d,%d], s:[%d,%d,%d,%d]," 673 "transform:[[%0.3f,%0.3f,%0.3f][%0.3f,%0.3f,%0.3f][%0.3f,%0.3f,%0.3f]]\n", 674 mViewport.left, mViewport.top, mViewport.right, mViewport.bottom, 675 mFrame.left, mFrame.top, mFrame.right, mFrame.bottom, mScissor.left, 676 mScissor.top, mScissor.right, mScissor.bottom, tr[0][0], tr[1][0], tr[2][0], 677 tr[0][1], tr[1][1], tr[2][1], tr[0][2], tr[1][2], tr[2][2]); 678 auto const surface = static_cast<Surface*>(window); 679 ui::Dataspace dataspace = surface->getBuffersDataSpace(); 680 result.appendFormat(" wideColorGamut=%d, hdr10=%d, colorMode=%s, dataspace: %s (%d)\n", 681 mHasWideColorGamut, mHasHdr10, 682 decodeColorMode(mActiveColorMode).c_str(), 683 dataspaceDetails(static_cast<android_dataspace>(dataspace)).c_str(), dataspace); 684 685 String8 surfaceDump; 686 mDisplaySurface->dumpAsString(surfaceDump); 687 result.append(surfaceDump); 688 } 689 690 // Map dataspace/intent to the best matched dataspace/colorMode/renderIntent 691 // supported by HWC. 692 void DisplayDevice::addColorMode( 693 const std::unordered_map<ColorMode, std::vector<RenderIntent>>& hwcColorModes, 694 const ColorMode mode, const RenderIntent intent) { 695 // find the best color mode 696 const ColorMode hwcColorMode = getHwcColorMode(hwcColorModes, mode); 697 698 // find the best render intent 699 auto iter = hwcColorModes.find(hwcColorMode); 700 const auto& hwcIntents = 701 iter != hwcColorModes.end() ? iter->second : std::vector<RenderIntent>(); 702 const RenderIntent hwcIntent = getHwcRenderIntent(hwcIntents, intent); 703 704 const Dataspace dataspace = colorModeToDataspace(mode); 705 const Dataspace hwcDataspace = colorModeToDataspace(hwcColorMode); 706 707 ALOGV("DisplayDevice %d/%d: map (%s, %s) to (%s, %s, %s)", mType, mHwcDisplayId, 708 dataspaceDetails(static_cast<android_dataspace_t>(dataspace)).c_str(), 709 decodeRenderIntent(intent).c_str(), 710 dataspaceDetails(static_cast<android_dataspace_t>(hwcDataspace)).c_str(), 711 decodeColorMode(hwcColorMode).c_str(), decodeRenderIntent(hwcIntent).c_str()); 712 713 mColorModes[getColorModeKey(dataspace, intent)] = {hwcDataspace, hwcColorMode, hwcIntent}; 714 } 715 716 void DisplayDevice::populateColorModes( 717 const std::unordered_map<ColorMode, std::vector<RenderIntent>>& hwcColorModes) { 718 if (!hasWideColorGamut()) { 719 return; 720 } 721 722 // collect all known SDR render intents 723 std::unordered_set<RenderIntent> sdrRenderIntents(sSdrRenderIntents.begin(), 724 sSdrRenderIntents.end()); 725 auto iter = hwcColorModes.find(ColorMode::SRGB); 726 if (iter != hwcColorModes.end()) { 727 for (auto intent : iter->second) { 728 sdrRenderIntents.insert(intent); 729 } 730 } 731 732 // add all known SDR combinations 733 for (auto intent : sdrRenderIntents) { 734 for (auto mode : sSdrColorModes) { 735 addColorMode(hwcColorModes, mode, intent); 736 } 737 } 738 739 // collect all known HDR render intents 740 std::unordered_set<RenderIntent> hdrRenderIntents(sHdrRenderIntents.begin(), 741 sHdrRenderIntents.end()); 742 iter = hwcColorModes.find(ColorMode::BT2100_PQ); 743 if (iter != hwcColorModes.end()) { 744 for (auto intent : iter->second) { 745 hdrRenderIntents.insert(intent); 746 } 747 } 748 749 // add all known HDR combinations 750 for (auto intent : sHdrRenderIntents) { 751 for (auto mode : sHdrColorModes) { 752 addColorMode(hwcColorModes, mode, intent); 753 } 754 } 755 } 756 757 bool DisplayDevice::hasRenderIntent(RenderIntent intent) const { 758 // assume a render intent is supported when SRGB supports it; we should 759 // get rid of that assumption. 760 auto iter = mColorModes.find(getColorModeKey(Dataspace::SRGB, intent)); 761 return iter != mColorModes.end() && iter->second.renderIntent == intent; 762 } 763 764 bool DisplayDevice::hasLegacyHdrSupport(Dataspace dataspace) const { 765 if ((dataspace == Dataspace::BT2020_PQ && hasHDR10Support()) || 766 (dataspace == Dataspace::BT2020_HLG && hasHLGSupport())) { 767 auto iter = 768 mColorModes.find(getColorModeKey(dataspace, RenderIntent::TONE_MAP_COLORIMETRIC)); 769 return iter == mColorModes.end() || iter->second.dataspace != dataspace; 770 } 771 772 return false; 773 } 774 775 void DisplayDevice::getBestColorMode(Dataspace dataspace, RenderIntent intent, 776 Dataspace* outDataspace, ColorMode* outMode, 777 RenderIntent* outIntent) const { 778 auto iter = mColorModes.find(getColorModeKey(dataspace, intent)); 779 if (iter != mColorModes.end()) { 780 *outDataspace = iter->second.dataspace; 781 *outMode = iter->second.colorMode; 782 *outIntent = iter->second.renderIntent; 783 } else { 784 ALOGE("map unknown (%s)/(%s) to default color mode", 785 dataspaceDetails(static_cast<android_dataspace_t>(dataspace)).c_str(), 786 decodeRenderIntent(intent).c_str()); 787 788 *outDataspace = Dataspace::UNKNOWN; 789 *outMode = ColorMode::NATIVE; 790 *outIntent = RenderIntent::COLORIMETRIC; 791 } 792 } 793 794 std::atomic<int32_t> DisplayDeviceState::nextDisplayId(1); 795 796 DisplayDeviceState::DisplayDeviceState(DisplayDevice::DisplayType type, bool isSecure) 797 : type(type), 798 layerStack(DisplayDevice::NO_LAYER_STACK), 799 orientation(0), 800 width(0), 801 height(0), 802 isSecure(isSecure) 803 { 804 viewport.makeInvalid(); 805 frame.makeInvalid(); 806 } 807 808 } // namespace android 809