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 48 DeviceInfo* DeviceInfo::get() { 49 static DeviceInfo sDeviceInfo; 50 return &sDeviceInfo; 51 } 52 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 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 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 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 137 int DeviceInfo::maxTextureSize() const { 138 LOG_ALWAYS_FATAL_IF(mMaxTextureSize < 0, "MaxTextureSize has not been initialized yet."); 139 return mMaxTextureSize; 140 } 141 142 void DeviceInfo::setMaxTextureSize(int maxTextureSize) { 143 DeviceInfo::get()->mMaxTextureSize = maxTextureSize; 144 } 145 146 void DeviceInfo::onDisplayConfigChanged() { 147 mDisplayInfo = QueryDisplayInfo(); 148 } 149 150 } /* namespace uirenderer */ 151 } /* namespace android */ 152