1 /*
2 * Copyright (C) 2015 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 #include <DeviceInfo.h>
18
19 #include "Properties.h"
20
21 #include <gui/ISurfaceComposer.h>
22 #include <gui/SurfaceComposerClient.h>
23 #include <ui/GraphicTypes.h>
24
25 #include <mutex>
26 #include <thread>
27
28 #include <log/log.h>
29
30 namespace android {
31 namespace uirenderer {
32
33 static constexpr android::DisplayInfo sDummyDisplay{
34 1080, // w
35 1920, // h
36 320.0, // xdpi
37 320.0, // ydpi
38 60.0, // fps
39 2.0, // density
40 0, // orientation
41 false, // secure?
42 0, // appVsyncOffset
43 0, // presentationDeadline
44 1080, // viewportW
45 1920, // viewportH
46 };
47
get()48 DeviceInfo* DeviceInfo::get() {
49 static DeviceInfo sDeviceInfo;
50 return &sDeviceInfo;
51 }
52
QueryDisplayInfo()53 static DisplayInfo QueryDisplayInfo() {
54 if (Properties::isolatedProcess) {
55 return sDummyDisplay;
56 }
57
58 const sp<IBinder> token = SurfaceComposerClient::getInternalDisplayToken();
59 LOG_ALWAYS_FATAL_IF(token == nullptr,
60 "Failed to get display info because internal display is disconnected");
61
62 DisplayInfo displayInfo;
63 status_t status = SurfaceComposerClient::getDisplayInfo(token, &displayInfo);
64 LOG_ALWAYS_FATAL_IF(status, "Failed to get display info, error %d", status);
65 return displayInfo;
66 }
67
QueryMaxRefreshRate()68 static float QueryMaxRefreshRate() {
69 if (Properties::isolatedProcess) {
70 return sDummyDisplay.fps;
71 }
72
73 const sp<IBinder> token = SurfaceComposerClient::getInternalDisplayToken();
74 LOG_ALWAYS_FATAL_IF(token == nullptr,
75 "Failed to get display info because internal display is disconnected");
76
77 Vector<DisplayInfo> configs;
78 configs.reserve(10);
79 status_t status = SurfaceComposerClient::getDisplayConfigs(token, &configs);
80 LOG_ALWAYS_FATAL_IF(status, "Failed to getDisplayConfigs, error %d", status);
81 LOG_ALWAYS_FATAL_IF(configs.size() == 0, "getDisplayConfigs returned 0 configs?");
82 float max = 0.0f;
83 for (auto& info : configs) {
84 max = std::max(max, info.fps);
85 }
86 return max;
87 }
88
queryWideColorGamutPreference(sk_sp<SkColorSpace> * colorSpace,SkColorType * colorType)89 static void queryWideColorGamutPreference(sk_sp<SkColorSpace>* colorSpace, SkColorType* colorType) {
90 if (Properties::isolatedProcess) {
91 *colorSpace = SkColorSpace::MakeSRGB();
92 *colorType = SkColorType::kN32_SkColorType;
93 return;
94 }
95 ui::Dataspace defaultDataspace, wcgDataspace;
96 ui::PixelFormat defaultPixelFormat, wcgPixelFormat;
97 status_t status =
98 SurfaceComposerClient::getCompositionPreference(&defaultDataspace, &defaultPixelFormat,
99 &wcgDataspace, &wcgPixelFormat);
100 LOG_ALWAYS_FATAL_IF(status, "Failed to get composition preference, error %d", status);
101 switch (wcgDataspace) {
102 case ui::Dataspace::DISPLAY_P3:
103 *colorSpace = SkColorSpace::MakeRGB(SkNamedTransferFn::kSRGB, SkNamedGamut::kDCIP3);
104 break;
105 case ui::Dataspace::V0_SCRGB:
106 *colorSpace = SkColorSpace::MakeSRGB();
107 break;
108 case ui::Dataspace::V0_SRGB:
109 // when sRGB is returned, it means wide color gamut is not supported.
110 *colorSpace = SkColorSpace::MakeSRGB();
111 break;
112 default:
113 LOG_ALWAYS_FATAL("Unreachable: unsupported wide color space.");
114 }
115 switch (wcgPixelFormat) {
116 case ui::PixelFormat::RGBA_8888:
117 *colorType = SkColorType::kN32_SkColorType;
118 break;
119 case ui::PixelFormat::RGBA_FP16:
120 *colorType = SkColorType::kRGBA_F16_SkColorType;
121 break;
122 default:
123 LOG_ALWAYS_FATAL("Unreachable: unsupported pixel format.");
124 }
125 }
126
DeviceInfo()127 DeviceInfo::DeviceInfo() : mMaxRefreshRate(QueryMaxRefreshRate()) {
128 #if HWUI_NULL_GPU
129 mMaxTextureSize = NULL_GPU_MAX_TEXTURE_SIZE;
130 #else
131 mMaxTextureSize = -1;
132 #endif
133 mDisplayInfo = QueryDisplayInfo();
134 queryWideColorGamutPreference(&mWideColorSpace, &mWideColorType);
135 }
136
maxTextureSize() const137 int DeviceInfo::maxTextureSize() const {
138 LOG_ALWAYS_FATAL_IF(mMaxTextureSize < 0, "MaxTextureSize has not been initialized yet.");
139 return mMaxTextureSize;
140 }
141
setMaxTextureSize(int maxTextureSize)142 void DeviceInfo::setMaxTextureSize(int maxTextureSize) {
143 DeviceInfo::get()->mMaxTextureSize = maxTextureSize;
144 }
145
onDisplayConfigChanged()146 void DeviceInfo::onDisplayConfigChanged() {
147 mDisplayInfo = QueryDisplayInfo();
148 }
149
150 } /* namespace uirenderer */
151 } /* namespace android */
152