display_snapshot_dri.cc revision 0529e5d033099cbfc42635f6f6183833b09dff6e
1// Copyright 2014 The Chromium Authors. All rights reserved. 2// Use of this source code is governed by a BSD-style license that can be 3// found in the LICENSE file. 4 5#include "ui/ozone/platform/dri/chromeos/display_snapshot_dri.h" 6 7#include <stdint.h> 8#include <stdlib.h> 9#include <xf86drmMode.h> 10 11#include "base/format_macros.h" 12#include "base/logging.h" 13#include "base/strings/stringprintf.h" 14#include "ui/display/util/edid_parser.h" 15#include "ui/ozone/platform/dri/chromeos/display_mode_dri.h" 16#include "ui/ozone/platform/dri/dri_wrapper.h" 17 18namespace ui { 19 20namespace { 21 22DisplayConnectionType GetDisplayType(drmModeConnector* connector) { 23 switch (connector->connector_type) { 24 case DRM_MODE_CONNECTOR_VGA: 25 return DISPLAY_CONNECTION_TYPE_VGA; 26 case DRM_MODE_CONNECTOR_DVII: 27 case DRM_MODE_CONNECTOR_DVID: 28 case DRM_MODE_CONNECTOR_DVIA: 29 return DISPLAY_CONNECTION_TYPE_DVI; 30 case DRM_MODE_CONNECTOR_LVDS: 31 case DRM_MODE_CONNECTOR_eDP: 32 return DISPLAY_CONNECTION_TYPE_INTERNAL; 33 case DRM_MODE_CONNECTOR_DisplayPort: 34 return DISPLAY_CONNECTION_TYPE_DISPLAYPORT; 35 case DRM_MODE_CONNECTOR_HDMIA: 36 case DRM_MODE_CONNECTOR_HDMIB: 37 return DISPLAY_CONNECTION_TYPE_HDMI; 38 default: 39 return DISPLAY_CONNECTION_TYPE_UNKNOWN; 40 } 41} 42 43bool SameMode(const drmModeModeInfo& lhs, const drmModeModeInfo& rhs) { 44 return lhs.clock == rhs.clock && 45 lhs.hdisplay == rhs.vdisplay && 46 lhs.vrefresh == rhs.vrefresh && 47 lhs.hsync_start == rhs.hsync_start && 48 lhs.hsync_end == rhs.hsync_end && 49 lhs.htotal == rhs.htotal && 50 lhs.hskew == rhs.hskew && 51 lhs.vsync_start == rhs.vsync_start && 52 lhs.vsync_end == rhs.vsync_end && 53 lhs.vtotal == rhs.vtotal && 54 lhs.vscan == rhs.vscan && 55 lhs.flags == rhs.flags && 56 strcmp(lhs.name, rhs.name) == 0; 57} 58 59bool IsAspectPreserving(DriWrapper* drm, drmModeConnector* connector) { 60 drmModePropertyRes* property = drm->GetProperty(connector, "scaling mode"); 61 if (property) { 62 for (int j = 0; j < property->count_enums; ++j) { 63 if (property->enums[j].value == 64 connector->prop_values[property->prop_id] && 65 strcmp(property->enums[j].name, "Full aspect") == 0) { 66 drm->FreeProperty(property); 67 return true; 68 } 69 } 70 71 drm->FreeProperty(property); 72 } 73 74 return false; 75} 76 77} // namespace 78 79DisplaySnapshotDri::DisplaySnapshotDri( 80 DriWrapper* drm, 81 drmModeConnector* connector, 82 drmModeCrtc* crtc, 83 uint32_t index) 84 : DisplaySnapshot(index, 85 false, 86 gfx::Point(crtc->x, crtc->y), 87 gfx::Size(connector->mmWidth, connector->mmHeight), 88 GetDisplayType(connector), 89 IsAspectPreserving(drm, connector), 90 false, 91 std::string(), 92 std::vector<const DisplayMode*>(), 93 NULL, 94 NULL), 95 connector_(connector->connector_id), 96 crtc_(crtc->crtc_id), 97 dpms_property_(drm->GetProperty(connector, "DPMS")) { 98 drmModePropertyBlobRes* edid_blob = drm->GetPropertyBlob(connector, "EDID"); 99 100 if (edid_blob) { 101 std::vector<uint8_t> edid( 102 static_cast<uint8_t*>(edid_blob->data), 103 static_cast<uint8_t*>(edid_blob->data) + edid_blob->length); 104 105 has_proper_display_id_ = GetDisplayIdFromEDID(edid, index, &display_id_); 106 ParseOutputDeviceData(edid, NULL, &display_name_); 107 ParseOutputOverscanFlag(edid, &overscan_flag_); 108 109 drm->FreePropertyBlob(edid_blob); 110 } else { 111 VLOG(1) << "Failed to get EDID blob for connector " 112 << connector->connector_id; 113 } 114 115 for (int i = 0; i < connector->count_modes; ++i) { 116 drmModeModeInfo& mode = connector->modes[i]; 117 modes_.push_back(new DisplayModeDri(mode)); 118 119 if (crtc->mode_valid && SameMode(crtc->mode, mode)) 120 current_mode_ = modes_.back(); 121 122 if (mode.type & DRM_MODE_TYPE_PREFERRED) 123 native_mode_ = modes_.back(); 124 } 125} 126 127DisplaySnapshotDri::~DisplaySnapshotDri() { 128 if (dpms_property_) 129 drmModeFreeProperty(dpms_property_); 130} 131 132std::string DisplaySnapshotDri::ToString() const { 133 return base::StringPrintf( 134 "[type=%d, connector=%" PRIu32 ", crtc=%" PRIu32 ", mode=%s, dim=%s]", 135 type_, 136 connector_, 137 crtc_, 138 current_mode_ ? current_mode_->ToString().c_str() : "NULL", 139 physical_size_.ToString().c_str()); 140} 141 142} // namespace ui 143