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 #include <log/log.h>
19 #include <utils/Errors.h>
20 
21 #include "Properties.h"
22 
23 namespace android {
24 namespace uirenderer {
25 
get()26 DeviceInfo* DeviceInfo::get() {
27     static DeviceInfo sDeviceInfo;
28     return &sDeviceInfo;
29 }
30 
DeviceInfo()31 DeviceInfo::DeviceInfo() {
32 #if HWUI_NULL_GPU
33         mMaxTextureSize = NULL_GPU_MAX_TEXTURE_SIZE;
34 #else
35         mMaxTextureSize = -1;
36 #endif
37         updateDisplayInfo();
38 }
~DeviceInfo()39 DeviceInfo::~DeviceInfo() {
40     ADisplay_release(mDisplays);
41 }
42 
maxTextureSize() const43 int DeviceInfo::maxTextureSize() const {
44     LOG_ALWAYS_FATAL_IF(mMaxTextureSize < 0, "MaxTextureSize has not been initialized yet.");
45     return mMaxTextureSize;
46 }
47 
setMaxTextureSize(int maxTextureSize)48 void DeviceInfo::setMaxTextureSize(int maxTextureSize) {
49     DeviceInfo::get()->mMaxTextureSize = maxTextureSize;
50 }
51 
onRefreshRateChanged(int64_t vsyncPeriod)52 void DeviceInfo::onRefreshRateChanged(int64_t vsyncPeriod) {
53     mVsyncPeriod = vsyncPeriod;
54 }
55 
updateDisplayInfo()56 void DeviceInfo::updateDisplayInfo() {
57     if (Properties::isolatedProcess) {
58         return;
59     }
60 
61     if (mCurrentConfig == nullptr) {
62         mDisplaysSize = ADisplay_acquirePhysicalDisplays(&mDisplays);
63         LOG_ALWAYS_FATAL_IF(mDisplays == nullptr || mDisplaysSize <= 0,
64                             "Failed to get physical displays: no connected display: %d!", mDisplaysSize);
65         for (size_t i = 0; i < mDisplaysSize; i++) {
66             ADisplayType type = ADisplay_getDisplayType(mDisplays[i]);
67             if (type == ADisplayType::DISPLAY_TYPE_INTERNAL) {
68                 mPhysicalDisplayIndex = i;
69                 break;
70             }
71         }
72         LOG_ALWAYS_FATAL_IF(mPhysicalDisplayIndex < 0, "Failed to find a connected physical display!");
73 
74 
75         // Since we now just got the primary display for the first time, then
76         // store the primary display metadata here.
77         ADisplay* primaryDisplay = mDisplays[mPhysicalDisplayIndex];
78         mMaxRefreshRate = ADisplay_getMaxSupportedFps(primaryDisplay);
79         ADataSpace dataspace;
80         AHardwareBuffer_Format format;
81         ADisplay_getPreferredWideColorFormat(primaryDisplay, &dataspace, &format);
82         switch (dataspace) {
83             case ADATASPACE_DISPLAY_P3:
84                 mWideColorSpace =
85                         SkColorSpace::MakeRGB(SkNamedTransferFn::kSRGB, SkNamedGamut::kDCIP3);
86                 break;
87             case ADATASPACE_SCRGB:
88                 mWideColorSpace = SkColorSpace::MakeSRGB();
89                 break;
90             case ADATASPACE_SRGB:
91                 // when sRGB is returned, it means wide color gamut is not supported.
92                 mWideColorSpace = SkColorSpace::MakeSRGB();
93                 break;
94             default:
95                 LOG_ALWAYS_FATAL("Unreachable: unsupported wide color space.");
96         }
97         switch (format) {
98             case AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM:
99                 mWideColorType = SkColorType::kN32_SkColorType;
100                 break;
101             case AHARDWAREBUFFER_FORMAT_R16G16B16A16_FLOAT:
102                 mWideColorType = SkColorType::kRGBA_F16_SkColorType;
103                 break;
104             default:
105                 LOG_ALWAYS_FATAL("Unreachable: unsupported pixel format.");
106         }
107     }
108     // This method may have been called when the display config changed, so
109     // sync with the current configuration.
110     ADisplay* primaryDisplay = mDisplays[mPhysicalDisplayIndex];
111     status_t status = ADisplay_getCurrentConfig(primaryDisplay, &mCurrentConfig);
112     LOG_ALWAYS_FATAL_IF(status, "Failed to get display config, error %d", status);
113 
114     mWidth = ADisplayConfig_getWidth(mCurrentConfig);
115     mHeight = ADisplayConfig_getHeight(mCurrentConfig);
116     mDensity = ADisplayConfig_getDensity(mCurrentConfig);
117     mVsyncPeriod = static_cast<int64_t>(1000000000 / ADisplayConfig_getFps(mCurrentConfig));
118     mCompositorOffset = ADisplayConfig_getCompositorOffsetNanos(mCurrentConfig);
119     mAppOffset = ADisplayConfig_getAppVsyncOffsetNanos(mCurrentConfig);
120 }
121 
122 } /* namespace uirenderer */
123 } /* namespace android */
124