drm_hwcomposer: uses edid DTD to get better estimate of dpi
Edid are not the most reliable when it comes to panel size, however it seems like preferred DTD are slightly more reliable. This change moves from the drm parse edid display size to the first preferred DTD to try improve dpi accuracy. If no preferred DTD is available we still fallback to the display size. Change-Id: Ibcc95da9f38ba74e9b95b9d68587b38efbed8de2 signed-off-by: Lucas Berthou <berlu@google.com>
This commit is contained in:
parent
75855a6ab8
commit
30808a20bb
5 changed files with 113 additions and 20 deletions
|
|
@ -18,6 +18,7 @@
|
|||
|
||||
#if HAS_LIBDISPLAY_INFO
|
||||
extern "C" {
|
||||
#include <libdisplay-info/edid.h>
|
||||
#include <libdisplay-info/info.h>
|
||||
}
|
||||
#endif
|
||||
|
|
@ -48,6 +49,16 @@ class EdidWrapper {
|
|||
virtual void GetColorModes(std::vector<Colormode> &color_modes) {
|
||||
color_modes.clear();
|
||||
};
|
||||
virtual int GetDpiX() {
|
||||
return -1;
|
||||
}
|
||||
virtual int GetDpiY() {
|
||||
return -1;
|
||||
}
|
||||
|
||||
virtual auto GetBoundsMm() -> std::pair<int32_t, int32_t> {
|
||||
return {-1, -1};
|
||||
}
|
||||
};
|
||||
|
||||
#if HAS_LIBDISPLAY_INFO
|
||||
|
|
@ -70,10 +81,17 @@ class LibdisplayEdidWrapper final : public EdidWrapper {
|
|||
|
||||
void GetColorModes(std::vector<Colormode> &color_modes) override;
|
||||
|
||||
auto GetDpiX() -> int override;
|
||||
auto GetDpiY() -> int override;
|
||||
|
||||
auto GetBoundsMm() -> std::pair<int32_t, int32_t> override;
|
||||
|
||||
private:
|
||||
LibdisplayEdidWrapper(di_info *info) : info_(std::move(info)) {
|
||||
}
|
||||
|
||||
std::pair<int32_t, int32_t> GetDpi();
|
||||
|
||||
di_info *info_{};
|
||||
};
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -95,5 +95,51 @@ void LibdisplayEdidWrapper::GetColorModes(std::vector<Colormode> &color_modes) {
|
|||
}
|
||||
}
|
||||
|
||||
auto LibdisplayEdidWrapper::GetDpiX() -> int {
|
||||
return GetDpi().first;
|
||||
}
|
||||
|
||||
auto LibdisplayEdidWrapper::GetDpiY() -> int {
|
||||
return GetDpi().second;
|
||||
}
|
||||
|
||||
auto LibdisplayEdidWrapper::GetBoundsMm() -> std::pair<int32_t, int32_t> {
|
||||
const auto edid = di_info_get_edid(info_);
|
||||
const auto detailed_timing_defs = di_edid_get_detailed_timing_defs(edid);
|
||||
const auto dtd = detailed_timing_defs[0];
|
||||
if (dtd == nullptr || dtd->horiz_image_mm == 0 || dtd->vert_image_mm == 0) {
|
||||
// try to fallback on display size if no dtd.
|
||||
// However since edid screen size are vastly unreliable only provide a valid
|
||||
// width to avoid invalid dpi computation.
|
||||
const auto screen_size = di_edid_get_screen_size(edid);
|
||||
return {screen_size->width_cm * 10, -1};
|
||||
}
|
||||
|
||||
return {dtd->horiz_image_mm, dtd->vert_image_mm};
|
||||
}
|
||||
|
||||
auto LibdisplayEdidWrapper::GetDpi() -> std::pair<int32_t, int32_t> {
|
||||
static const int32_t kUmPerInch = 25400;
|
||||
const auto edid = di_info_get_edid(info_);
|
||||
const auto detailed_timing_defs = di_edid_get_detailed_timing_defs(edid);
|
||||
const auto dtd = detailed_timing_defs[0];
|
||||
if (dtd == nullptr || dtd->horiz_image_mm == 0 || dtd->vert_image_mm == 0) {
|
||||
// try to fallback on display size if no dtd.
|
||||
const auto screen_size = di_edid_get_screen_size(edid);
|
||||
const auto standard_timings = di_edid_get_standard_timings(edid);
|
||||
if (screen_size->width_cm <= 0 || standard_timings == nullptr) {
|
||||
return {-1, -1};
|
||||
}
|
||||
|
||||
// display size is more unreliable so use only horizontal dpi.
|
||||
int32_t horiz_video = standard_timings[0]->horiz_video;
|
||||
int32_t dpi = horiz_video * kUmPerInch / (screen_size->width_cm * 10);
|
||||
return {dpi, dpi};
|
||||
}
|
||||
|
||||
return {dtd->horiz_video * kUmPerInch / dtd->horiz_image_mm,
|
||||
dtd->vert_video * kUmPerInch / dtd->vert_image_mm};
|
||||
}
|
||||
|
||||
} // namespace android
|
||||
#endif
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue