Pin Chrome's shortcut to the Win10 Start menu on install and OS upgrade.
[chromium-blink-merge.git] / ui / ozone / platform / drm / gpu / gbm_buffer.cc
blobc92ba44240b58351d82a76fbabd96cab1e87b388
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/drm/gpu/gbm_buffer.h"
7 #include <drm.h>
8 #include <fcntl.h>
9 #include <gbm.h>
10 #include <xf86drm.h>
12 #include "base/logging.h"
13 #include "base/trace_event/trace_event.h"
14 #include "ui/gfx/geometry/size_conversions.h"
15 #include "ui/ozone/platform/drm/gpu/drm_window.h"
16 #include "ui/ozone/platform/drm/gpu/gbm_device.h"
18 namespace ui {
20 namespace {
22 int GetGbmFormatFromBufferFormat(SurfaceFactoryOzone::BufferFormat fmt) {
23 switch (fmt) {
24 case SurfaceFactoryOzone::BGRA_8888:
25 return GBM_BO_FORMAT_ARGB8888;
26 case SurfaceFactoryOzone::RGBX_8888:
27 return GBM_BO_FORMAT_XRGB8888;
28 default:
29 NOTREACHED();
30 return 0;
34 } // namespace
36 GbmBuffer::GbmBuffer(const scoped_refptr<GbmDevice>& gbm,
37 gbm_bo* bo,
38 bool scanout)
39 : GbmBufferBase(gbm, bo, scanout) {
42 GbmBuffer::~GbmBuffer() {
43 if (bo())
44 gbm_bo_destroy(bo());
47 // static
48 scoped_refptr<GbmBuffer> GbmBuffer::CreateBuffer(
49 const scoped_refptr<GbmDevice>& gbm,
50 SurfaceFactoryOzone::BufferFormat format,
51 const gfx::Size& size,
52 bool scanout) {
53 TRACE_EVENT2("drm", "GbmBuffer::CreateBuffer", "device",
54 gbm->device_path().value(), "size", size.ToString());
55 unsigned flags = GBM_BO_USE_RENDERING;
56 if (scanout)
57 flags |= GBM_BO_USE_SCANOUT;
58 gbm_bo* bo = gbm_bo_create(gbm->device(), size.width(), size.height(),
59 GetGbmFormatFromBufferFormat(format), flags);
60 if (!bo)
61 return NULL;
63 scoped_refptr<GbmBuffer> buffer(new GbmBuffer(gbm, bo, scanout));
64 if (scanout && !buffer->GetFramebufferId())
65 return NULL;
67 return buffer;
70 GbmPixmap::GbmPixmap(const scoped_refptr<GbmBuffer>& buffer,
71 ScreenManager* screen_manager)
72 : buffer_(buffer), screen_manager_(screen_manager) {
75 bool GbmPixmap::Initialize() {
76 // We want to use the GBM API because it's going to call into libdrm
77 // which might do some optimizations on buffer allocation,
78 // especially when sharing buffers via DMABUF.
79 dma_buf_ = gbm_bo_get_fd(buffer_->bo());
80 if (dma_buf_ < 0) {
81 PLOG(ERROR) << "Failed to export buffer to dma_buf";
82 return false;
84 return true;
87 void GbmPixmap::SetScalingCallback(const ScalingCallback& scaling_callback) {
88 scaling_callback_ = scaling_callback;
91 scoped_refptr<NativePixmap> GbmPixmap::GetScaledPixmap(gfx::Size new_size) {
92 return scaling_callback_.Run(new_size);
95 GbmPixmap::~GbmPixmap() {
96 if (dma_buf_ > 0)
97 close(dma_buf_);
100 void* GbmPixmap::GetEGLClientBuffer() {
101 return nullptr;
104 int GbmPixmap::GetDmaBufFd() {
105 return dma_buf_;
108 int GbmPixmap::GetDmaBufPitch() {
109 return gbm_bo_get_stride(buffer_->bo());
112 bool GbmPixmap::ScheduleOverlayPlane(gfx::AcceleratedWidget widget,
113 int plane_z_order,
114 gfx::OverlayTransform plane_transform,
115 const gfx::Rect& display_bounds,
116 const gfx::RectF& crop_rect) {
117 gfx::Size required_size;
118 if (plane_z_order &&
119 ShouldApplyScaling(display_bounds, crop_rect, &required_size)) {
120 scoped_refptr<NativePixmap> scaled_pixmap = GetScaledPixmap(required_size);
121 if (scaled_pixmap) {
122 return scaled_pixmap->ScheduleOverlayPlane(
123 widget, plane_z_order, plane_transform, display_bounds, crop_rect);
124 } else {
125 return false;
129 screen_manager_->GetWindow(widget)->QueueOverlayPlane(OverlayPlane(
130 buffer_, plane_z_order, plane_transform, display_bounds, crop_rect));
131 return true;
134 bool GbmPixmap::ShouldApplyScaling(const gfx::Rect& display_bounds,
135 const gfx::RectF& crop_rect,
136 gfx::Size* required_size) {
137 if (crop_rect.width() == 0 || crop_rect.height() == 0) {
138 PLOG(ERROR) << "ShouldApplyScaling passed zero scaling target.";
139 return false;
142 gfx::Size pixmap_size = buffer_->GetSize();
143 // If the required size is not integer-sized, round it to the next integer.
144 *required_size = gfx::ToCeiledSize(
145 gfx::SizeF(display_bounds.width() / crop_rect.width(),
146 display_bounds.height() / crop_rect.height()));
147 return pixmap_size != *required_size;
150 } // namespace ui