Home | History | Annotate | Download | only in chromeos
      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_util.h"
     17 #include "ui/ozone/platform/dri/dri_wrapper.h"
     18 
     19 namespace ui {
     20 
     21 namespace {
     22 
     23 DisplayConnectionType GetDisplayType(drmModeConnector* connector) {
     24   switch (connector->connector_type) {
     25     case DRM_MODE_CONNECTOR_VGA:
     26       return DISPLAY_CONNECTION_TYPE_VGA;
     27     case DRM_MODE_CONNECTOR_DVII:
     28     case DRM_MODE_CONNECTOR_DVID:
     29     case DRM_MODE_CONNECTOR_DVIA:
     30       return DISPLAY_CONNECTION_TYPE_DVI;
     31     case DRM_MODE_CONNECTOR_LVDS:
     32     case DRM_MODE_CONNECTOR_eDP:
     33       return DISPLAY_CONNECTION_TYPE_INTERNAL;
     34     case DRM_MODE_CONNECTOR_DisplayPort:
     35       return DISPLAY_CONNECTION_TYPE_DISPLAYPORT;
     36     case DRM_MODE_CONNECTOR_HDMIA:
     37     case DRM_MODE_CONNECTOR_HDMIB:
     38       return DISPLAY_CONNECTION_TYPE_HDMI;
     39     default:
     40       return DISPLAY_CONNECTION_TYPE_UNKNOWN;
     41   }
     42 }
     43 
     44 bool IsAspectPreserving(DriWrapper* drm, drmModeConnector* connector) {
     45   ScopedDrmPropertyPtr property(drm->GetProperty(connector, "scaling mode"));
     46   if (property) {
     47     for (int j = 0; j < property->count_enums; ++j) {
     48       if (property->enums[j].value ==
     49               connector->prop_values[property->prop_id] &&
     50           strcmp(property->enums[j].name, "Full aspect") == 0)
     51         return true;
     52     }
     53   }
     54 
     55   return false;
     56 }
     57 
     58 }  // namespace
     59 
     60 DisplaySnapshotDri::DisplaySnapshotDri(
     61     DriWrapper* drm,
     62     drmModeConnector* connector,
     63     drmModeCrtc* crtc,
     64     uint32_t index)
     65     : DisplaySnapshot(index,
     66                       false,
     67                       gfx::Point(crtc->x, crtc->y),
     68                       gfx::Size(connector->mmWidth, connector->mmHeight),
     69                       GetDisplayType(connector),
     70                       IsAspectPreserving(drm, connector),
     71                       false,
     72                       std::string(),
     73                       std::vector<const DisplayMode*>(),
     74                       NULL,
     75                       NULL),
     76       connector_(connector->connector_id),
     77       crtc_(crtc->crtc_id),
     78       dpms_property_(drm->GetProperty(connector, "DPMS")) {
     79   if (!dpms_property_)
     80     VLOG(1) << "Failed to find the DPMS property for connector "
     81             << connector->connector_id;
     82 
     83   ScopedDrmPropertyBlobPtr edid_blob(drm->GetPropertyBlob(connector, "EDID"));
     84 
     85   if (edid_blob) {
     86     std::vector<uint8_t> edid(
     87         static_cast<uint8_t*>(edid_blob->data),
     88         static_cast<uint8_t*>(edid_blob->data) + edid_blob->length);
     89 
     90     has_proper_display_id_ = GetDisplayIdFromEDID(edid, index, &display_id_);
     91     ParseOutputDeviceData(edid, NULL, &display_name_);
     92     ParseOutputOverscanFlag(edid, &overscan_flag_);
     93   } else {
     94     VLOG(1) << "Failed to get EDID blob for connector "
     95             << connector->connector_id;
     96   }
     97 
     98   for (int i = 0; i < connector->count_modes; ++i) {
     99     drmModeModeInfo& mode = connector->modes[i];
    100     modes_.push_back(new DisplayModeDri(mode));
    101 
    102     if (crtc->mode_valid && SameMode(crtc->mode, mode))
    103       current_mode_ = modes_.back();
    104 
    105     if (mode.type & DRM_MODE_TYPE_PREFERRED)
    106       native_mode_ = modes_.back();
    107   }
    108 
    109   // If no preferred mode is found then use the first one. Using the first one
    110   // since it should be the best mode.
    111   if (!native_mode_ && !modes_.empty())
    112     native_mode_ = modes_.front();
    113 }
    114 
    115 DisplaySnapshotDri::~DisplaySnapshotDri() {}
    116 
    117 std::string DisplaySnapshotDri::ToString() const {
    118   return base::StringPrintf(
    119       "[type=%d, connector=%" PRIu32 ", crtc=%" PRIu32 ", mode=%s, dim=%s]",
    120       type_,
    121       connector_,
    122       crtc_,
    123       current_mode_ ? current_mode_->ToString().c_str() : "NULL",
    124       physical_size_.ToString().c_str());
    125 }
    126 
    127 }  // namespace ui
    128