dri_util.cc revision 010d83a9304c5a91596085d917d248abff47903a
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 11namespace ui { 12 13namespace { 14 15bool 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 25uint32_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 67HardwareDisplayControllerInfo::HardwareDisplayControllerInfo( 68 drmModeConnector* connector, 69 drmModeCrtc* crtc) 70 : connector_(connector), 71 crtc_(crtc) {} 72 73HardwareDisplayControllerInfo::~HardwareDisplayControllerInfo() { 74 drmModeFreeConnector(connector_); 75 drmModeFreeCrtc(crtc_); 76} 77 78ScopedVector<HardwareDisplayControllerInfo> 79GetAvailableDisplayControllerInfos(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 108bool 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