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_buffer.h"
12 #include "base/logging.h"
13 #include "third_party/skia/include/core/SkCanvas.h"
14 #include "ui/ozone/platform/dri/dri_util.h"
15 #include "ui/ozone/platform/dri/dri_wrapper.h"
21 // Modesetting cannot happen from a buffer with transparencies. Return the size
22 // of a pixel without alpha.
23 uint8_t GetColorDepth(SkColorType type
) {
25 case kUnknown_SkColorType
:
26 case kAlpha_8_SkColorType
:
28 case kIndex_8_SkColorType
:
30 case kRGB_565_SkColorType
:
32 case kARGB_4444_SkColorType
:
34 case kPMColor_SkColorType
:
42 void DestroyDumbBuffer(int fd
, uint32_t handle
) {
43 struct drm_mode_destroy_dumb destroy_request
;
44 destroy_request
.handle
= handle
;
45 drmIoctl(fd
, DRM_IOCTL_MODE_DESTROY_DUMB
, &destroy_request
);
48 bool CreateDumbBuffer(int fd
,
49 const SkImageInfo
& info
,
52 struct drm_mode_create_dumb request
;
53 request
.width
= info
.width();
54 request
.height
= info
.height();
55 request
.bpp
= info
.bytesPerPixel() << 3;
58 if (drmIoctl(fd
, DRM_IOCTL_MODE_CREATE_DUMB
, &request
) < 0) {
59 DLOG(ERROR
) << "Cannot create dumb buffer (" << errno
<< ") "
64 // The driver may choose to align the last row as well. We don't care about
65 // the last alignment bits since they aren't used for display purposes, so
66 // just check that the expected size is <= to what the driver allocated.
67 DCHECK_LE(info
.getSafeSize(request
.pitch
), request
.size
);
69 *handle
= request
.handle
;
70 *stride
= request
.pitch
;
76 DriBuffer::DriBuffer(DriWrapper
* dri
)
77 : dri_(dri
), handle_(0), framebuffer_(0) {}
79 DriBuffer::~DriBuffer() {
84 dri_
->RemoveFramebuffer(framebuffer_
);
87 void* pixels
= const_cast<void*>(surface_
->peekPixels(&info
, NULL
));
91 munmap(pixels
, info
.getSafeSize(stride_
));
92 DestroyDumbBuffer(dri_
->get_fd(), handle_
);
95 bool DriBuffer::Initialize(const SkImageInfo
& info
) {
97 if (!CreateDumbBuffer(dri_
->get_fd(), info
, &handle_
, &stride_
)) {
98 DLOG(ERROR
) << "Cannot allocate drm dumb buffer";
102 if (!MapDumbBuffer(dri_
->get_fd(),
104 info
.getSafeSize(stride_
),
106 DLOG(ERROR
) << "Cannot map drm dumb buffer";
107 DestroyDumbBuffer(dri_
->get_fd(), handle_
);
111 if (!dri_
->AddFramebuffer(info
.width(),
113 GetColorDepth(info
.colorType()),
114 info
.bytesPerPixel() << 3,
118 DLOG(ERROR
) << "Failed to register framebuffer: " << strerror(errno
);
122 surface_
= skia::AdoptRef(SkSurface::NewRasterDirect(info
, pixels
, stride_
));
124 DLOG(ERROR
) << "Cannot install Skia pixels for drm buffer";