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
colorModeToDataspace(ColorMode mode)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.
getColorModeCandidates(ColorMode mode)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.
getRenderIntentCandidates(RenderIntent intent)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.
getHwcColorMode(const std::unordered_map<ColorMode,std::vector<RenderIntent>> & hwcColorModes,ColorMode mode)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.
getHwcRenderIntent(const std::vector<RenderIntent> & hwcIntents,RenderIntent intent)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
DisplayDevice(const sp<SurfaceFlinger> & flinger,DisplayType type,int32_t hwcId,bool isSecure,const wp<IBinder> & displayToken,const sp<ANativeWindow> & nativeWindow,const sp<DisplaySurface> & displaySurface,std::unique_ptr<RE::Surface> renderSurface,int displayWidth,int displayHeight,bool hasWideColorGamut,const HdrCapabilities & hdrCapabilities,const int32_t supportedPerFrameMetadata,const std::unordered_map<ColorMode,std::vector<RenderIntent>> & hwcColorModes,int initialPowerMode)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 
disconnect(HWComposer & hwc)303 void DisplayDevice::disconnect(HWComposer& hwc) {
304     if (mHwcDisplayId >= 0) {
305         hwc.disconnectDisplay(mHwcDisplayId);
306         mHwcDisplayId = -1;
307     }
308 }
309 
isValid() const310 bool DisplayDevice::isValid() const {
311     return mFlinger != nullptr;
312 }
313 
getWidth() const314 int DisplayDevice::getWidth() const {
315     return mDisplayWidth;
316 }
317 
getHeight() const318 int DisplayDevice::getHeight() const {
319     return mDisplayHeight;
320 }
321 
setDisplayName(const String8 & displayName)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 
getPageFlipCount() const329 uint32_t DisplayDevice::getPageFlipCount() const {
330     return mPageFlipCount;
331 }
332 
flip() const333 void DisplayDevice::flip() const
334 {
335     mFlinger->getRenderEngine().checkErrors();
336     mPageFlipCount++;
337 }
338 
beginFrame(bool mustRecompose) const339 status_t DisplayDevice::beginFrame(bool mustRecompose) const {
340     return mDisplaySurface->beginFrame(mustRecompose);
341 }
342 
prepareFrame(HWComposer & hwc)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 
swapBuffers(HWComposer & hwc) const367 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 
onSwapBuffersCompleted() const379 void DisplayDevice::onSwapBuffersCompleted() const {
380     mDisplaySurface->onFrameCommitted();
381 }
382 
makeCurrent() const383 bool DisplayDevice::makeCurrent() const {
384     bool success = mFlinger->getRenderEngine().setCurrentSurface(*mSurface);
385     setViewportAndProjection();
386     return success;
387 }
388 
setViewportAndProjection() const389 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 
getClientTargetAcquireFence() const397 const sp<Fence>& DisplayDevice::getClientTargetAcquireFence() const {
398     return mDisplaySurface->getClientTargetAcquireFence();
399 }
400 
401 // ----------------------------------------------------------------------------
402 
setVisibleLayersSortedByZ(const Vector<sp<Layer>> & layers)403 void DisplayDevice::setVisibleLayersSortedByZ(const Vector< sp<Layer> >& layers) {
404     mVisibleLayersSortedByZ = layers;
405 }
406 
getVisibleLayersSortedByZ() const407 const Vector< sp<Layer> >& DisplayDevice::getVisibleLayersSortedByZ() const {
408     return mVisibleLayersSortedByZ;
409 }
410 
setLayersNeedingFences(const Vector<sp<Layer>> & layers)411 void DisplayDevice::setLayersNeedingFences(const Vector< sp<Layer> >& layers) {
412     mLayersNeedingFences = layers;
413 }
414 
getLayersNeedingFences() const415 const Vector< sp<Layer> >& DisplayDevice::getLayersNeedingFences() const {
416     return mLayersNeedingFences;
417 }
418 
getDirtyRegion(bool repaintEverything) const419 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 // ----------------------------------------------------------------------------
setPowerMode(int mode)432 void DisplayDevice::setPowerMode(int mode) {
433     mPowerMode = mode;
434 }
435 
getPowerMode() const436 int DisplayDevice::getPowerMode()  const {
437     return mPowerMode;
438 }
439 
isDisplayOn() const440 bool DisplayDevice::isDisplayOn() const {
441     return (mPowerMode != HWC_POWER_MODE_OFF);
442 }
443 
444 // ----------------------------------------------------------------------------
setActiveConfig(int mode)445 void DisplayDevice::setActiveConfig(int mode) {
446     mActiveConfig = mode;
447 }
448 
getActiveConfig() const449 int DisplayDevice::getActiveConfig()  const {
450     return mActiveConfig;
451 }
452 
453 // ----------------------------------------------------------------------------
setActiveColorMode(ColorMode mode)454 void DisplayDevice::setActiveColorMode(ColorMode mode) {
455     mActiveColorMode = mode;
456 }
457 
getActiveColorMode() const458 ColorMode DisplayDevice::getActiveColorMode() const {
459     return mActiveColorMode;
460 }
461 
getActiveRenderIntent() const462 RenderIntent DisplayDevice::getActiveRenderIntent() const {
463     return mActiveRenderIntent;
464 }
465 
setActiveRenderIntent(RenderIntent renderIntent)466 void DisplayDevice::setActiveRenderIntent(RenderIntent renderIntent) {
467     mActiveRenderIntent = renderIntent;
468 }
469 
setColorTransform(const mat4 & transform)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 
getColorTransform() const476 android_color_transform_t DisplayDevice::getColorTransform() const {
477     return mColorTransform;
478 }
479 
setCompositionDataSpace(ui::Dataspace dataspace)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 
getCompositionDataSpace() const486 ui::Dataspace DisplayDevice::getCompositionDataSpace() const {
487     return mCompositionDataSpace;
488 }
489 
490 // ----------------------------------------------------------------------------
491 
setLayerStack(uint32_t stack)492 void DisplayDevice::setLayerStack(uint32_t stack) {
493     mLayerStack = stack;
494     dirtyRegion.set(bounds());
495 }
496 
497 // ----------------------------------------------------------------------------
498 
getOrientationTransform() const499 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 
orientationToTransfrom(int orientation,int w,int h,Transform * tr)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 
setDisplaySize(const int newWidth,const int newHeight)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 
setProjection(int orientation,const Rect & newViewport,const Rect & newFrame)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 
getPrimaryDisplayOrientationTransform()656 uint32_t DisplayDevice::getPrimaryDisplayOrientationTransform() {
657     return sPrimaryDisplayOrientation;
658 }
659 
dump(String8 & result) const660 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.
addColorMode(const std::unordered_map<ColorMode,std::vector<RenderIntent>> & hwcColorModes,const ColorMode mode,const RenderIntent intent)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 
populateColorModes(const std::unordered_map<ColorMode,std::vector<RenderIntent>> & hwcColorModes)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 
hasRenderIntent(RenderIntent intent) const757 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 
hasLegacyHdrSupport(Dataspace dataspace) const764 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 
getBestColorMode(Dataspace dataspace,RenderIntent intent,Dataspace * outDataspace,ColorMode * outMode,RenderIntent * outIntent) const775 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 
DisplayDeviceState(DisplayDevice::DisplayType type,bool isSecure)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