Home | History | Annotate | Download | only in surfaceflinger
      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