Explicitly add python-numpy dependency to install-build-deps.
[chromium-blink-merge.git] / ui / ozone / platform / dri / dri_wrapper.cc
blob3b6ceb0e02e80e970e96ed8b4aac3ad1a9c65137
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.
5 #include "ui/ozone/platform/dri/dri_wrapper.h"
7 #include <fcntl.h>
8 #include <sys/mman.h>
9 #include <unistd.h>
10 #include <xf86drm.h>
11 #include <xf86drmMode.h>
13 #include "base/debug/trace_event.h"
14 #include "base/logging.h"
15 #include "base/stl_util.h"
16 #include "third_party/skia/include/core/SkImageInfo.h"
17 #include "ui/ozone/platform/dri/dri_util.h"
19 namespace ui {
21 namespace {
23 uint32_t ToFixedPoint(double v) {
24 // This returns a number in a 16-bit.16-bit fixed point.
25 return v * 65536.0;
28 bool DrmCreateDumbBuffer(int fd,
29 const SkImageInfo& info,
30 uint32_t* handle,
31 uint32_t* stride) {
32 struct drm_mode_create_dumb request;
33 memset(&request, 0, sizeof(request));
34 request.width = info.width();
35 request.height = info.height();
36 request.bpp = info.bytesPerPixel() << 3;
37 request.flags = 0;
39 if (drmIoctl(fd, DRM_IOCTL_MODE_CREATE_DUMB, &request) < 0) {
40 VLOG(2) << "Cannot create dumb buffer (" << errno << ") "
41 << strerror(errno);
42 return false;
45 // The driver may choose to align the last row as well. We don't care about
46 // the last alignment bits since they aren't used for display purposes, so
47 // just check that the expected size is <= to what the driver allocated.
48 DCHECK_LE(info.getSafeSize(request.pitch), request.size);
50 *handle = request.handle;
51 *stride = request.pitch;
52 return true;
55 void DrmDestroyDumbBuffer(int fd, uint32_t handle) {
56 struct drm_mode_destroy_dumb destroy_request;
57 memset(&destroy_request, 0, sizeof(destroy_request));
58 destroy_request.handle = handle;
59 drmIoctl(fd, DRM_IOCTL_MODE_DESTROY_DUMB, &destroy_request);
62 } // namespace
64 DriWrapper::DriWrapper(const char* device_path)
65 : fd_(-1), device_path_(device_path) {
68 DriWrapper::~DriWrapper() {
69 if (fd_ >= 0)
70 close(fd_);
73 void DriWrapper::Initialize() {
74 fd_ = open(device_path_, O_RDWR | O_CLOEXEC);
75 if (fd_ < 0)
76 PLOG(FATAL) << "open: " << device_path_;
79 ScopedDrmCrtcPtr DriWrapper::GetCrtc(uint32_t crtc_id) {
80 DCHECK(fd_ >= 0);
81 return ScopedDrmCrtcPtr(drmModeGetCrtc(fd_, crtc_id));
84 bool DriWrapper::SetCrtc(uint32_t crtc_id,
85 uint32_t framebuffer,
86 std::vector<uint32_t> connectors,
87 drmModeModeInfo* mode) {
88 DCHECK(fd_ >= 0);
89 DCHECK(!connectors.empty());
90 DCHECK(mode);
92 TRACE_EVENT2("dri", "DriWrapper::SetCrtc", "crtc", crtc_id, "size",
93 gfx::Size(mode->hdisplay, mode->vdisplay).ToString());
94 return !drmModeSetCrtc(fd_,
95 crtc_id,
96 framebuffer,
99 vector_as_array(&connectors),
100 connectors.size(), mode);
103 bool DriWrapper::SetCrtc(drmModeCrtc* crtc, std::vector<uint32_t> connectors) {
104 DCHECK(fd_ >= 0);
105 // If there's no buffer then the CRTC was disabled.
106 if (!crtc->buffer_id)
107 return DisableCrtc(crtc->crtc_id);
109 DCHECK(!connectors.empty());
111 TRACE_EVENT1("dri", "DriWrapper::RestoreCrtc",
112 "crtc", crtc->crtc_id);
113 return !drmModeSetCrtc(fd_,
114 crtc->crtc_id,
115 crtc->buffer_id,
116 crtc->x,
117 crtc->y,
118 vector_as_array(&connectors),
119 connectors.size(),
120 &crtc->mode);
123 bool DriWrapper::DisableCrtc(uint32_t crtc_id) {
124 DCHECK(fd_ >= 0);
125 TRACE_EVENT1("dri", "DriWrapper::DisableCrtc",
126 "crtc", crtc_id);
127 return !drmModeSetCrtc(fd_, crtc_id, 0, 0, 0, NULL, 0, NULL);
130 ScopedDrmConnectorPtr DriWrapper::GetConnector(uint32_t connector_id) {
131 DCHECK(fd_ >= 0);
132 TRACE_EVENT1("dri", "DriWrapper::GetConnector", "connector", connector_id);
133 return ScopedDrmConnectorPtr(drmModeGetConnector(fd_, connector_id));
136 bool DriWrapper::AddFramebuffer(uint32_t width,
137 uint32_t height,
138 uint8_t depth,
139 uint8_t bpp,
140 uint32_t stride,
141 uint32_t handle,
142 uint32_t* framebuffer) {
143 DCHECK(fd_ >= 0);
144 TRACE_EVENT1("dri", "DriWrapper::AddFramebuffer",
145 "handle", handle);
146 return !drmModeAddFB(fd_,
147 width,
148 height,
149 depth,
150 bpp,
151 stride,
152 handle,
153 framebuffer);
156 bool DriWrapper::RemoveFramebuffer(uint32_t framebuffer) {
157 DCHECK(fd_ >= 0);
158 TRACE_EVENT1("dri", "DriWrapper::RemoveFramebuffer",
159 "framebuffer", framebuffer);
160 return !drmModeRmFB(fd_, framebuffer);
163 bool DriWrapper::PageFlip(uint32_t crtc_id,
164 uint32_t framebuffer,
165 void* data) {
166 DCHECK(fd_ >= 0);
167 TRACE_EVENT2("dri", "DriWrapper::PageFlip",
168 "crtc", crtc_id,
169 "framebuffer", framebuffer);
170 return !drmModePageFlip(fd_,
171 crtc_id,
172 framebuffer,
173 DRM_MODE_PAGE_FLIP_EVENT,
174 data);
177 bool DriWrapper::PageFlipOverlay(uint32_t crtc_id,
178 uint32_t framebuffer,
179 const gfx::Rect& location,
180 const gfx::RectF& source,
181 int overlay_plane) {
182 DCHECK(fd_ >= 0);
183 TRACE_EVENT2("dri", "DriWrapper::PageFlipOverlay",
184 "crtc", crtc_id,
185 "framebuffer", framebuffer);
186 return !drmModeSetPlane(fd_,
187 overlay_plane,
188 crtc_id,
189 framebuffer,
191 location.x(),
192 location.y(),
193 location.width(),
194 location.height(),
195 ToFixedPoint(source.x()),
196 ToFixedPoint(source.y()),
197 ToFixedPoint(source.width()),
198 ToFixedPoint(source.height()));
201 ScopedDrmFramebufferPtr DriWrapper::GetFramebuffer(uint32_t framebuffer) {
202 DCHECK(fd_ >= 0);
203 TRACE_EVENT1("dri", "DriWrapper::GetFramebuffer",
204 "framebuffer", framebuffer);
205 return ScopedDrmFramebufferPtr(drmModeGetFB(fd_, framebuffer));
208 ScopedDrmPropertyPtr DriWrapper::GetProperty(drmModeConnector* connector,
209 const char* name) {
210 TRACE_EVENT2("dri", "DriWrapper::GetProperty",
211 "connector", connector->connector_id,
212 "name", name);
213 for (int i = 0; i < connector->count_props; ++i) {
214 ScopedDrmPropertyPtr property(drmModeGetProperty(fd_, connector->props[i]));
215 if (!property)
216 continue;
218 if (strcmp(property->name, name) == 0)
219 return property.Pass();
222 return ScopedDrmPropertyPtr();
225 bool DriWrapper::SetProperty(uint32_t connector_id,
226 uint32_t property_id,
227 uint64_t value) {
228 DCHECK(fd_ >= 0);
229 return !drmModeConnectorSetProperty(fd_, connector_id, property_id, value);
232 bool DriWrapper::GetCapability(uint64_t capability, uint64_t* value) {
233 DCHECK(fd_ >= 0);
234 return !drmGetCap(fd_, capability, value);
237 ScopedDrmPropertyBlobPtr DriWrapper::GetPropertyBlob(
238 drmModeConnector* connector, const char* name) {
239 DCHECK(fd_ >= 0);
240 TRACE_EVENT2("dri", "DriWrapper::GetPropertyBlob",
241 "connector", connector->connector_id,
242 "name", name);
243 for (int i = 0; i < connector->count_props; ++i) {
244 ScopedDrmPropertyPtr property(drmModeGetProperty(fd_, connector->props[i]));
245 if (!property)
246 continue;
248 if (strcmp(property->name, name) == 0 &&
249 property->flags & DRM_MODE_PROP_BLOB)
250 return ScopedDrmPropertyBlobPtr(
251 drmModeGetPropertyBlob(fd_, connector->prop_values[i]));
254 return ScopedDrmPropertyBlobPtr();
257 bool DriWrapper::SetCursor(uint32_t crtc_id,
258 uint32_t handle,
259 const gfx::Size& size) {
260 DCHECK(fd_ >= 0);
261 TRACE_EVENT1("dri", "DriWrapper::SetCursor", "handle", handle);
262 return !drmModeSetCursor(fd_, crtc_id, handle, size.width(), size.height());
265 bool DriWrapper::MoveCursor(uint32_t crtc_id, const gfx::Point& point) {
266 DCHECK(fd_ >= 0);
267 return !drmModeMoveCursor(fd_, crtc_id, point.x(), point.y());
270 void DriWrapper::HandleEvent(drmEventContext& event) {
271 DCHECK(fd_ >= 0);
272 TRACE_EVENT0("dri", "DriWrapper::HandleEvent");
273 drmHandleEvent(fd_, &event);
276 bool DriWrapper::CreateDumbBuffer(const SkImageInfo& info,
277 uint32_t* handle,
278 uint32_t* stride,
279 void** pixels) {
280 DCHECK(fd_ >= 0);
282 TRACE_EVENT0("dri", "DriWrapper::CreateDumbBuffer");
283 if (!DrmCreateDumbBuffer(fd_, info, handle, stride))
284 return false;
286 if (!MapDumbBuffer(fd_, *handle, info.getSafeSize(*stride), pixels)) {
287 DrmDestroyDumbBuffer(fd_, *handle);
288 return false;
291 return true;
294 void DriWrapper::DestroyDumbBuffer(const SkImageInfo& info,
295 uint32_t handle,
296 uint32_t stride,
297 void* pixels) {
298 DCHECK(fd_ >= 0);
299 TRACE_EVENT1("dri", "DriWrapper::DestroyDumbBuffer", "handle", handle);
300 munmap(pixels, info.getSafeSize(stride));
301 DrmDestroyDumbBuffer(fd_, handle);
304 bool DriWrapper::SetMaster() {
305 DCHECK(fd_ >= 0);
306 return (drmSetMaster(fd_) == 0);
309 bool DriWrapper::DropMaster() {
310 DCHECK(fd_ >= 0);
311 return (drmDropMaster(fd_) == 0);
314 } // namespace ui