10529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch// Copyright 2014 The Chromium Authors. All rights reserved.
24e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
34e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// found in the LICENSE file.
44e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
50529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch#include "ui/ozone/platform/dri/dri_wrapper.h"
64e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
74e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include <fcntl.h>
8116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include <sys/mman.h>
94e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include <unistd.h>
10cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include <xf86drm.h>
114e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include <xf86drmMode.h>
124e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
135f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "base/debug/trace_event.h"
144e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "base/logging.h"
155f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "base/stl_util.h"
16116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "third_party/skia/include/core/SkImageInfo.h"
17116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "ui/ozone/platform/dri/dri_util.h"
184e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
190529e5d033099cbfc42635f6f6183833b09dff6eBen Murdochnamespace ui {
204e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
21116680a4aac90f2aa7413d9095a592090648e557Ben Murdochnamespace {
22116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
23116680a4aac90f2aa7413d9095a592090648e557Ben Murdochuint32_t ToFixedPoint(double v) {
24116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // This returns a number in a 16-bit.16-bit fixed point.
25116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  return v * 65536.0;
26116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}
27116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
28116680a4aac90f2aa7413d9095a592090648e557Ben Murdochbool DrmCreateDumbBuffer(int fd,
29116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                         const SkImageInfo& info,
30116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                         uint32_t* handle,
31116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                         uint32_t* stride) {
32116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  struct drm_mode_create_dumb request;
33116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  memset(&request, 0, sizeof(request));
34116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  request.width = info.width();
35116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  request.height = info.height();
36116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  request.bpp = info.bytesPerPixel() << 3;
37116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  request.flags = 0;
38116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
39116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  if (drmIoctl(fd, DRM_IOCTL_MODE_CREATE_DUMB, &request) < 0) {
40116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    VLOG(2) << "Cannot create dumb buffer (" << errno << ") "
41116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch            << strerror(errno);
42116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    return false;
43116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  }
44116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
45116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // The driver may choose to align the last row as well. We don't care about
46116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // the last alignment bits since they aren't used for display purposes, so
47116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // just check that the expected size is <= to what the driver allocated.
48116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  DCHECK_LE(info.getSafeSize(request.pitch), request.size);
49116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
50116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  *handle = request.handle;
51116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  *stride = request.pitch;
52116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  return true;
53116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}
54116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
55116680a4aac90f2aa7413d9095a592090648e557Ben Murdochvoid DrmDestroyDumbBuffer(int fd, uint32_t handle) {
56116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  struct drm_mode_destroy_dumb destroy_request;
57116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  memset(&destroy_request, 0, sizeof(destroy_request));
58116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  destroy_request.handle = handle;
59116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  drmIoctl(fd, DRM_IOCTL_MODE_DESTROY_DUMB, &destroy_request);
60116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}
61116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
62116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}  // namespace
63116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
641320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciDriWrapper::DriWrapper(const char* device_path)
651320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    : fd_(-1), device_path_(device_path) {
664e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
674e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
68f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)DriWrapper::~DriWrapper() {
694e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  if (fd_ >= 0)
704e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    close(fd_);
714e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
724e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
731320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid DriWrapper::Initialize() {
741320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  fd_ = open(device_path_, O_RDWR | O_CLOEXEC);
751320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (fd_ < 0)
761320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    PLOG(FATAL) << "open: " << device_path_;
771320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
781320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
79116680a4aac90f2aa7413d9095a592090648e557Ben MurdochScopedDrmCrtcPtr DriWrapper::GetCrtc(uint32_t crtc_id) {
805f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  DCHECK(fd_ >= 0);
81116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  return ScopedDrmCrtcPtr(drmModeGetCrtc(fd_, crtc_id));
824e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
834e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
84f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)bool DriWrapper::SetCrtc(uint32_t crtc_id,
850529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch                         uint32_t framebuffer,
865f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                         std::vector<uint32_t> connectors,
870529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch                         drmModeModeInfo* mode) {
885f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  DCHECK(fd_ >= 0);
895f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  DCHECK(!connectors.empty());
905f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  DCHECK(mode);
915f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
921320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  TRACE_EVENT2("dri",
931320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci               "DriWrapper::SetCrtc",
941320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci               "crtc",
951320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci               crtc_id,
961320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci               "size",
971320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci               gfx::Size(mode->hdisplay, mode->vdisplay).ToString());
985f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  return !drmModeSetCrtc(fd_,
995f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                         crtc_id,
1005f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                         framebuffer,
1015f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                         0,
1025f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                         0,
1035f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                         vector_as_array(&connectors),
1045f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                         connectors.size(), mode);
1054e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
1064e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
1075f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)bool DriWrapper::SetCrtc(drmModeCrtc* crtc, std::vector<uint32_t> connectors) {
1085f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  DCHECK(fd_ >= 0);
1095f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // If there's no buffer then the CRTC was disabled.
1105f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  if (!crtc->buffer_id)
1115f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    return DisableCrtc(crtc->crtc_id);
1125f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
1135f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  DCHECK(!connectors.empty());
1145f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
1155f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  TRACE_EVENT1("dri", "DriWrapper::RestoreCrtc",
1165f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)               "crtc", crtc->crtc_id);
1174e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  return !drmModeSetCrtc(fd_,
1184e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                         crtc->crtc_id,
1194e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                         crtc->buffer_id,
1204e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                         crtc->x,
1214e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                         crtc->y,
1225f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                         vector_as_array(&connectors),
1235f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                         connectors.size(),
1244e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                         &crtc->mode);
1254e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
1264e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
1270529e5d033099cbfc42635f6f6183833b09dff6eBen Murdochbool DriWrapper::DisableCrtc(uint32_t crtc_id) {
1285f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  DCHECK(fd_ >= 0);
1295f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  TRACE_EVENT1("dri", "DriWrapper::DisableCrtc",
1305f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)               "crtc", crtc_id);
1310529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  return !drmModeSetCrtc(fd_, crtc_id, 0, 0, 0, NULL, 0, NULL);
1320529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch}
1330529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
1341320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciScopedDrmConnectorPtr DriWrapper::GetConnector(uint32_t connector_id) {
1351320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  DCHECK(fd_ >= 0);
1361320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  TRACE_EVENT1("dri", "DriWrapper::GetConnector", "connector", connector_id);
1371320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  return ScopedDrmConnectorPtr(drmModeGetConnector(fd_, connector_id));
1381320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
1391320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
140cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)bool DriWrapper::AddFramebuffer(uint32_t width,
141cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                                uint32_t height,
142cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                                uint8_t depth,
143cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                                uint8_t bpp,
144cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                                uint32_t stride,
145cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                                uint32_t handle,
146cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                                uint32_t* framebuffer) {
1475f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  DCHECK(fd_ >= 0);
1485f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  TRACE_EVENT1("dri", "DriWrapper::AddFramebuffer",
1495f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)               "handle", handle);
1504e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  return !drmModeAddFB(fd_,
151cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                       width,
152cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                       height,
1534e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                       depth,
1544e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                       bpp,
1554e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                       stride,
1564e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                       handle,
1574e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                       framebuffer);
1584e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
1594e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
160f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)bool DriWrapper::RemoveFramebuffer(uint32_t framebuffer) {
1615f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  DCHECK(fd_ >= 0);
1625f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  TRACE_EVENT1("dri", "DriWrapper::RemoveFramebuffer",
1635f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)               "framebuffer", framebuffer);
1644e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  return !drmModeRmFB(fd_, framebuffer);
1654e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
1664e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
167f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)bool DriWrapper::PageFlip(uint32_t crtc_id,
168cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                          uint32_t framebuffer,
169cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                          void* data) {
1705f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  DCHECK(fd_ >= 0);
1715f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  TRACE_EVENT2("dri", "DriWrapper::PageFlip",
1725f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)               "crtc", crtc_id,
1735f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)               "framebuffer", framebuffer);
1744e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  return !drmModePageFlip(fd_,
1754e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                          crtc_id,
1764e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                          framebuffer,
1774e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                          DRM_MODE_PAGE_FLIP_EVENT,
1784e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                          data);
1794e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
1804e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
181116680a4aac90f2aa7413d9095a592090648e557Ben Murdochbool DriWrapper::PageFlipOverlay(uint32_t crtc_id,
182116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                                 uint32_t framebuffer,
183116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                                 const gfx::Rect& location,
184116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                                 const gfx::RectF& source,
185116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                                 int overlay_plane) {
1865f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  DCHECK(fd_ >= 0);
1875f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  TRACE_EVENT2("dri", "DriWrapper::PageFlipOverlay",
1885f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)               "crtc", crtc_id,
1895f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)               "framebuffer", framebuffer);
190116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  return !drmModeSetPlane(fd_,
191116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                          overlay_plane,
192116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                          crtc_id,
193116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                          framebuffer,
194116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                          0,
195116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                          location.x(),
196116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                          location.y(),
197116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                          location.width(),
198116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                          location.height(),
199116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                          ToFixedPoint(source.x()),
200116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                          ToFixedPoint(source.y()),
201116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                          ToFixedPoint(source.width()),
202116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                          ToFixedPoint(source.height()));
203116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}
204116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
205116680a4aac90f2aa7413d9095a592090648e557Ben MurdochScopedDrmFramebufferPtr DriWrapper::GetFramebuffer(uint32_t framebuffer) {
2065f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  DCHECK(fd_ >= 0);
2075f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  TRACE_EVENT1("dri", "DriWrapper::GetFramebuffer",
2085f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)               "framebuffer", framebuffer);
209116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  return ScopedDrmFramebufferPtr(drmModeGetFB(fd_, framebuffer));
210116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}
211116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
212116680a4aac90f2aa7413d9095a592090648e557Ben MurdochScopedDrmPropertyPtr DriWrapper::GetProperty(drmModeConnector* connector,
213116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                                             const char* name) {
2145f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  TRACE_EVENT2("dri", "DriWrapper::GetProperty",
2155f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)               "connector", connector->connector_id,
2165f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)               "name", name);
2170529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  for (int i = 0; i < connector->count_props; ++i) {
218116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    ScopedDrmPropertyPtr property(drmModeGetProperty(fd_, connector->props[i]));
2190529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    if (!property)
2200529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      continue;
2210529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
2220529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    if (strcmp(property->name, name) == 0)
223116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      return property.Pass();
2240529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  }
2250529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
226116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  return ScopedDrmPropertyPtr();
2270529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch}
2280529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
2290529e5d033099cbfc42635f6f6183833b09dff6eBen Murdochbool DriWrapper::SetProperty(uint32_t connector_id,
2300529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch                             uint32_t property_id,
2310529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch                             uint64_t value) {
2325f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  DCHECK(fd_ >= 0);
2331e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  return !drmModeConnectorSetProperty(fd_, connector_id, property_id, value);
2341e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)}
2351e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
236116680a4aac90f2aa7413d9095a592090648e557Ben MurdochScopedDrmPropertyBlobPtr DriWrapper::GetPropertyBlob(
237116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    drmModeConnector* connector, const char* name) {
2385f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  DCHECK(fd_ >= 0);
2395f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  TRACE_EVENT2("dri", "DriWrapper::GetPropertyBlob",
2405f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)               "connector", connector->connector_id,
2415f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)               "name", name);
2420529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  for (int i = 0; i < connector->count_props; ++i) {
243116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    ScopedDrmPropertyPtr property(drmModeGetProperty(fd_, connector->props[i]));
2440529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    if (!property)
2450529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      continue;
2460529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
2470529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    if (strcmp(property->name, name) == 0 &&
248116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch        property->flags & DRM_MODE_PROP_BLOB)
249116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      return ScopedDrmPropertyBlobPtr(
250116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch          drmModeGetPropertyBlob(fd_, connector->prop_values[i]));
2510529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  }
2520529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
253116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  return ScopedDrmPropertyBlobPtr();
2540529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch}
2550529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
25623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)bool DriWrapper::SetCursor(uint32_t crtc_id,
25723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)                           uint32_t handle,
2585f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                           const gfx::Size& size) {
2595f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  DCHECK(fd_ >= 0);
2605f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  TRACE_EVENT1("dri", "DriWrapper::SetCursor", "handle", handle);
2615f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  return !drmModeSetCursor(fd_, crtc_id, handle, size.width(), size.height());
26223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)}
26323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
2645f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)bool DriWrapper::MoveCursor(uint32_t crtc_id, const gfx::Point& point) {
2655f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  DCHECK(fd_ >= 0);
2665f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  return !drmModeMoveCursor(fd_, crtc_id, point.x(), point.y());
26723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)}
26823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
269cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void DriWrapper::HandleEvent(drmEventContext& event) {
2705f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  DCHECK(fd_ >= 0);
2715f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  TRACE_EVENT0("dri", "DriWrapper::HandleEvent");
272cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  drmHandleEvent(fd_, &event);
273cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
274cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
275116680a4aac90f2aa7413d9095a592090648e557Ben Murdochbool DriWrapper::CreateDumbBuffer(const SkImageInfo& info,
276116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                                  uint32_t* handle,
277116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                                  uint32_t* stride,
278116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                                  void** pixels) {
2795f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  DCHECK(fd_ >= 0);
280116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
2815f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  TRACE_EVENT0("dri", "DriWrapper::CreateDumbBuffer");
282116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  if (!DrmCreateDumbBuffer(fd_, info, handle, stride))
283116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    return false;
284116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
285116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  if (!MapDumbBuffer(fd_, *handle, info.getSafeSize(*stride), pixels)) {
286116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    DrmDestroyDumbBuffer(fd_, *handle);
287116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    return false;
288116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  }
289116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
290116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  return true;
291116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}
292116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
293116680a4aac90f2aa7413d9095a592090648e557Ben Murdochvoid DriWrapper::DestroyDumbBuffer(const SkImageInfo& info,
294116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                                   uint32_t handle,
295116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                                   uint32_t stride,
296116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                                   void* pixels) {
2975f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  DCHECK(fd_ >= 0);
2985f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  TRACE_EVENT1("dri", "DriWrapper::DestroyDumbBuffer", "handle", handle);
299116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  munmap(pixels, info.getSafeSize(stride));
300116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  DrmDestroyDumbBuffer(fd_, handle);
301116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}
302116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
303116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
3040529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch}  // namespace ui
305