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