• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2024 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_TAG "drmhwc"
18 
19 #if HAS_LIBDISPLAY_INFO
20 
21 #include "utils/EdidWrapper.h"
22 #include "utils/log.h"
23 
24 namespace android {
25 
Create(DrmModePropertyBlobUnique blob)26 auto LibdisplayEdidWrapper::Create(DrmModePropertyBlobUnique blob)
27     -> std::unique_ptr<LibdisplayEdidWrapper> {
28   if (!blob)
29     return nullptr;
30 
31   auto *info = di_info_parse_edid(blob->data, blob->length);
32   if (!info) {
33     ALOGW("Failed to parse edid blob.");
34     return nullptr;
35   }
36 
37   return std::unique_ptr<LibdisplayEdidWrapper>(
38       new LibdisplayEdidWrapper(std::move(info)));
39 }
40 
GetSupportedHdrTypes(std::vector<ui::Hdr> & types)41 void LibdisplayEdidWrapper::GetSupportedHdrTypes(std::vector<ui::Hdr> &types) {
42   types.clear();
43 
44   const auto *hdr_static_meta = di_info_get_hdr_static_metadata(info_);
45   const auto *colorimetries = di_info_get_supported_signal_colorimetry(info_);
46   if (colorimetries->bt2020_cycc || colorimetries->bt2020_ycc ||
47       colorimetries->bt2020_rgb) {
48     if (hdr_static_meta->pq)
49       types.emplace_back(ui::Hdr::HDR10);
50     if (hdr_static_meta->hlg)
51       types.emplace_back(ui::Hdr::HLG);
52   }
53 }
54 
GetHdrCapabilities(std::vector<ui::Hdr> & types,float * max_luminance,float * max_average_luminance,float * min_luminance)55 void LibdisplayEdidWrapper::GetHdrCapabilities(
56     std::vector<ui::Hdr> &types, float *max_luminance,
57     float *max_average_luminance, float *min_luminance) {
58   GetSupportedHdrTypes(types);
59 
60   const auto *hdr_static_meta = di_info_get_hdr_static_metadata(info_);
61   *max_luminance = hdr_static_meta->desired_content_max_luminance;
62   *max_average_luminance = hdr_static_meta
63                                ->desired_content_max_frame_avg_luminance;
64   *min_luminance = hdr_static_meta->desired_content_min_luminance;
65 }
66 
GetColorModes(std::vector<Colormode> & color_modes)67 void LibdisplayEdidWrapper::GetColorModes(std::vector<Colormode> &color_modes) {
68   color_modes.clear();
69   color_modes.emplace_back(Colormode::kNative);
70 
71   const auto *hdr_static_meta = di_info_get_hdr_static_metadata(info_);
72   const auto *colorimetries = di_info_get_supported_signal_colorimetry(info_);
73 
74   /* Rec. ITU-R BT.2020 constant luminance YCbCr */
75   /* Rec. ITU-R BT.2020 non-constant luminance YCbCr */
76   if (colorimetries->bt2020_cycc || colorimetries->bt2020_ycc)
77     color_modes.emplace_back(Colormode::kBt2020);
78 
79   /* Rec. ITU-R BT.2020 RGB */
80   if (colorimetries->bt2020_rgb)
81     color_modes.emplace_back(Colormode::kDisplayBt2020);
82 
83   /* SMPTE ST 2113 RGB: P3D65 and P3DCI */
84   if (colorimetries->st2113_rgb) {
85     color_modes.emplace_back(Colormode::kDciP3);
86     color_modes.emplace_back(Colormode::kDisplayP3);
87   }
88 
89   /* Rec. ITU-R BT.2100 ICtCp HDR (with PQ and/or HLG) */
90   if (colorimetries->ictcp) {
91     if (hdr_static_meta->pq)
92       color_modes.emplace_back(Colormode::kBt2100Pq);
93     if (hdr_static_meta->hlg)
94       color_modes.emplace_back(Colormode::kBt2100Hlg);
95   }
96 }
97 
GetDpiX()98 auto LibdisplayEdidWrapper::GetDpiX() -> int {
99   return GetDpi().first;
100 }
101 
GetDpiY()102 auto LibdisplayEdidWrapper::GetDpiY() -> int {
103   return GetDpi().second;
104 }
105 
GetBoundsMm()106 auto LibdisplayEdidWrapper::GetBoundsMm() -> std::pair<int32_t, int32_t> {
107   const auto edid = di_info_get_edid(info_);
108   const auto detailed_timing_defs = di_edid_get_detailed_timing_defs(edid);
109   const auto dtd = detailed_timing_defs[0];
110   if (dtd == nullptr || dtd->horiz_image_mm == 0 || dtd->vert_image_mm == 0) {
111     // try to fallback on display size if no dtd.
112     // However since edid screen size are vastly unreliable only provide a valid
113     // width to avoid invalid dpi computation.
114     const auto screen_size = di_edid_get_screen_size(edid);
115     return {screen_size->width_cm * 10, -1};
116   }
117 
118   return {dtd->horiz_image_mm, dtd->vert_image_mm};
119 }
120 
GetDpi()121 auto LibdisplayEdidWrapper::GetDpi() -> std::pair<int32_t, int32_t> {
122   static const int32_t kUmPerInch = 25400;
123   const auto edid = di_info_get_edid(info_);
124   const auto detailed_timing_defs = di_edid_get_detailed_timing_defs(edid);
125   const auto dtd = detailed_timing_defs[0];
126   if (dtd == nullptr || dtd->horiz_image_mm == 0 || dtd->vert_image_mm == 0) {
127     // try to fallback on display size if no dtd.
128     const auto screen_size = di_edid_get_screen_size(edid);
129     const auto standard_timings = di_edid_get_standard_timings(edid);
130     if (screen_size->width_cm <= 0 || standard_timings == nullptr) {
131       return {-1, -1};
132     }
133 
134     // display size is more unreliable so use only horizontal dpi.
135     int32_t horiz_video = standard_timings[0]->horiz_video;
136     int32_t dpi = horiz_video * kUmPerInch / (screen_size->width_cm * 10);
137     return {dpi, dpi};
138   }
139 
140   return {dtd->horiz_video * kUmPerInch / dtd->horiz_image_mm,
141           dtd->vert_video * kUmPerInch / dtd->vert_image_mm};
142 }
143 
144 }  // namespace android
145 #endif
146