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/hardware_display_plane.h"
6
7#include <drm.h>
8#include <errno.h>
9#include <xf86drm.h>
10
11#include "base/logging.h"
12#include "ui/gfx/geometry/rect.h"
13#include "ui/ozone/platform/dri/dri_wrapper.h"
14
15namespace ui {
16
17namespace {
18const char* kCrtcPropName = "CRTC_ID";
19const char* kFbPropName = "FB_ID";
20const char* kCrtcXPropName = "CRTC_X";
21const char* kCrtcYPropName = "CRTC_Y";
22const char* kCrtcWPropName = "CRTC_W";
23const char* kCrtcHPropName = "CRTC_H";
24const char* kSrcXPropName = "SRC_X";
25const char* kSrcYPropName = "SRC_Y";
26const char* kSrcWPropName = "SRC_W";
27const char* kSrcHPropName = "SRC_H";
28}
29
30HardwareDisplayPlane::Property::Property() : id_(0) {
31}
32
33bool HardwareDisplayPlane::Property::Initialize(
34    DriWrapper* drm,
35    const char* name,
36    const ScopedDrmObjectPropertyPtr& plane_props) {
37  for (uint32_t i = 0; i < plane_props->count_props; i++) {
38    ScopedDrmPropertyPtr property(
39        drmModeGetProperty(drm->get_fd(), plane_props->props[i]));
40    if (!strcmp(property->name, name)) {
41      id_ = property->prop_id;
42      break;
43    }
44  }
45  if (!id_) {
46    LOG(ERROR) << "Could not find property " << name;
47    return false;
48  }
49  return true;
50}
51
52HardwareDisplayPlane::HardwareDisplayPlane(
53    DriWrapper* drm,
54    drmModePropertySetPtr atomic_property_set,
55    ScopedDrmPlanePtr plane)
56    : drm_(drm),
57      property_set_(atomic_property_set),
58      plane_(plane.Pass()),
59      plane_id_(plane_->plane_id) {
60}
61
62HardwareDisplayPlane::~HardwareDisplayPlane() {
63}
64
65bool HardwareDisplayPlane::CanUseForCrtc(uint32_t crtc_id) {
66  return plane_->possible_crtcs & (1 << crtc_id);
67}
68
69bool HardwareDisplayPlane::SetPlaneData(uint32_t crtc_id,
70                                        uint32_t framebuffer,
71                                        const gfx::Rect& crtc_rect,
72                                        const gfx::Rect& src_rect) {
73  int plane_set_error =
74      drmModePropertySetAdd(
75          property_set_, plane_id_, crtc_prop_.id_, crtc_id) ||
76      drmModePropertySetAdd(
77          property_set_, plane_id_, fb_prop_.id_, framebuffer) ||
78      drmModePropertySetAdd(
79          property_set_, plane_id_, crtc_x_prop_.id_, crtc_rect.x()) ||
80      drmModePropertySetAdd(
81          property_set_, plane_id_, crtc_y_prop_.id_, crtc_rect.y()) ||
82      drmModePropertySetAdd(
83          property_set_, plane_id_, crtc_w_prop_.id_, crtc_rect.width()) ||
84      drmModePropertySetAdd(
85          property_set_, plane_id_, crtc_h_prop_.id_, crtc_rect.height()) ||
86      drmModePropertySetAdd(
87          property_set_, plane_id_, src_x_prop_.id_, src_rect.x()) ||
88      drmModePropertySetAdd(
89          property_set_, plane_id_, src_y_prop_.id_, src_rect.x()) ||
90      drmModePropertySetAdd(
91          property_set_, plane_id_, src_w_prop_.id_, src_rect.width()) ||
92      drmModePropertySetAdd(
93          property_set_, plane_id_, src_h_prop_.id_, src_rect.height());
94
95  if (plane_set_error) {
96    LOG(ERROR) << "Failed to set plane data";
97    return false;
98  }
99  return true;
100}
101
102bool HardwareDisplayPlane::Initialize() {
103  ScopedDrmObjectPropertyPtr plane_props(drmModeObjectGetProperties(
104      drm_->get_fd(), plane_id_, DRM_MODE_OBJECT_PLANE));
105
106  if (!plane_props) {
107    LOG(ERROR) << "Unable to get plane properties.";
108    return false;
109  }
110
111  bool props_init =
112      crtc_prop_.Initialize(drm_, kCrtcPropName, plane_props) &&
113      fb_prop_.Initialize(drm_, kFbPropName, plane_props) &&
114      crtc_x_prop_.Initialize(drm_, kCrtcXPropName, plane_props) &&
115      crtc_y_prop_.Initialize(drm_, kCrtcYPropName, plane_props) &&
116      crtc_w_prop_.Initialize(drm_, kCrtcWPropName, plane_props) &&
117      crtc_h_prop_.Initialize(drm_, kCrtcHPropName, plane_props) &&
118      src_x_prop_.Initialize(drm_, kSrcXPropName, plane_props) &&
119      src_y_prop_.Initialize(drm_, kSrcYPropName, plane_props) &&
120      src_w_prop_.Initialize(drm_, kSrcWPropName, plane_props) &&
121      src_h_prop_.Initialize(drm_, kSrcHPropName, plane_props);
122
123  if (!props_init) {
124    LOG(ERROR) << "Unable to get plane properties.";
125    return false;
126  }
127  return true;
128}
129
130}  // namespace ui
131