Home | History | Annotate | Download | only in dri
      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/dri_util.h"
      6 
      7 #include <stdint.h>
      8 #include <stdlib.h>
      9 #include <xf86drmMode.h>
     10 
     11 namespace ui {
     12 
     13 namespace {
     14 
     15 bool IsCrtcInUse(uint32_t crtc,
     16                  const ScopedVector<HardwareDisplayControllerInfo>& displays) {
     17   for (size_t i = 0; i < displays.size(); ++i) {
     18     if (crtc == displays[i]->crtc()->crtc_id)
     19       return true;
     20   }
     21 
     22   return false;
     23 }
     24 
     25 uint32_t GetCrtc(int fd,
     26                  drmModeConnector* connector,
     27                  drmModeRes* resources,
     28                  const ScopedVector<HardwareDisplayControllerInfo>& displays) {
     29   // If the connector already has an encoder try to re-use.
     30   if (connector->encoder_id) {
     31     drmModeEncoder* encoder = drmModeGetEncoder(fd, connector->encoder_id);
     32     if (encoder) {
     33       if (encoder->crtc_id && !IsCrtcInUse(encoder->crtc_id, displays)) {
     34         uint32_t crtc = encoder->crtc_id;
     35         drmModeFreeEncoder(encoder);
     36         return crtc;
     37       }
     38       drmModeFreeEncoder(encoder);
     39     }
     40   }
     41 
     42   // Try to find an encoder for the connector.
     43   for (int i = 0; i < connector->count_encoders; ++i) {
     44     drmModeEncoder* encoder = drmModeGetEncoder(fd, connector->encoders[i]);
     45     if (!encoder)
     46       continue;
     47 
     48     for (int j = 0; j < resources->count_crtcs; ++j) {
     49       // Check if the encoder is compatible with this CRTC
     50       if (!(encoder->possible_crtcs & (1 << j)) ||
     51           IsCrtcInUse(resources->crtcs[j], displays)) {
     52         continue;
     53       }
     54 
     55       drmModeFreeEncoder(encoder);
     56       return resources->crtcs[j];
     57     }
     58 
     59     drmModeFreeEncoder(encoder);
     60   }
     61 
     62   return 0;
     63 }
     64 
     65 }  // namespace
     66 
     67 HardwareDisplayControllerInfo::HardwareDisplayControllerInfo(
     68     drmModeConnector* connector,
     69     drmModeCrtc* crtc)
     70     : connector_(connector),
     71       crtc_(crtc) {}
     72 
     73 HardwareDisplayControllerInfo::~HardwareDisplayControllerInfo() {
     74   drmModeFreeConnector(connector_);
     75   drmModeFreeCrtc(crtc_);
     76 }
     77 
     78 ScopedVector<HardwareDisplayControllerInfo>
     79 GetAvailableDisplayControllerInfos(int fd, drmModeRes* resources) {
     80   ScopedVector<HardwareDisplayControllerInfo> displays;
     81 
     82   for (int i = 0; i < resources->count_connectors; ++i) {
     83     drmModeConnector* connector = drmModeGetConnector(
     84         fd, resources->connectors[i]);
     85 
     86     if (!connector)
     87       continue;
     88 
     89     if (connector->connection != DRM_MODE_CONNECTED ||
     90         connector->count_modes == 0) {
     91       drmModeFreeConnector(connector);
     92       continue;
     93     }
     94 
     95     uint32_t crtc_id = GetCrtc(fd, connector, resources, displays);
     96     if (!crtc_id) {
     97       drmModeFreeConnector(connector);
     98       continue;
     99     }
    100 
    101     drmModeCrtc* crtc = drmModeGetCrtc(fd, crtc_id);
    102     displays.push_back(new HardwareDisplayControllerInfo(connector, crtc));
    103   }
    104 
    105   return displays.Pass();
    106 }
    107 
    108 bool SameMode(const drmModeModeInfo& lhs, const drmModeModeInfo& rhs) {
    109   return lhs.clock == rhs.clock &&
    110          lhs.hdisplay == rhs.hdisplay &&
    111          lhs.vdisplay == rhs.vdisplay &&
    112          lhs.vrefresh == rhs.vrefresh &&
    113          lhs.hsync_start == rhs.hsync_start &&
    114          lhs.hsync_end == rhs.hsync_end &&
    115          lhs.htotal == rhs.htotal &&
    116          lhs.hskew == rhs.hskew &&
    117          lhs.vsync_start == rhs.vsync_start &&
    118          lhs.vsync_end == rhs.vsync_end &&
    119          lhs.vtotal == rhs.vtotal &&
    120          lhs.vscan == rhs.vscan &&
    121          lhs.flags == rhs.flags &&
    122          strcmp(lhs.name, rhs.name) == 0;
    123 }
    124 
    125 }  // namespace ui
    126