OLD | NEW |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "ui/ozone/platform/drm/gpu/gbm_buffer.h" | 5 #include "ui/ozone/platform/drm/gpu/gbm_buffer.h" |
6 | 6 |
7 #include <drm.h> | 7 #include <drm.h> |
8 #include <fcntl.h> | 8 #include <fcntl.h> |
9 #include <gbm.h> | 9 #include <gbm.h> |
10 #include <xf86drm.h> | 10 #include <xf86drm.h> |
(...skipping 11 matching lines...) Expand all Loading... |
22 #include "ui/ozone/platform/drm/gpu/gbm_surfaceless.h" | 22 #include "ui/ozone/platform/drm/gpu/gbm_surfaceless.h" |
23 #include "ui/ozone/public/ozone_platform.h" | 23 #include "ui/ozone/public/ozone_platform.h" |
24 #include "ui/ozone/public/surface_factory_ozone.h" | 24 #include "ui/ozone/public/surface_factory_ozone.h" |
25 | 25 |
26 namespace ui { | 26 namespace ui { |
27 | 27 |
28 GbmBuffer::GbmBuffer(const scoped_refptr<GbmDevice>& gbm, | 28 GbmBuffer::GbmBuffer(const scoped_refptr<GbmDevice>& gbm, |
29 gbm_bo* bo, | 29 gbm_bo* bo, |
30 gfx::BufferFormat format, | 30 gfx::BufferFormat format, |
31 gfx::BufferUsage usage, | 31 gfx::BufferUsage usage, |
32 base::ScopedFD fd) | 32 base::ScopedFD fd, |
| 33 int stride) |
33 : GbmBufferBase(gbm, bo, format, usage), | 34 : GbmBufferBase(gbm, bo, format, usage), |
34 format_(format), | 35 format_(format), |
35 usage_(usage), | 36 usage_(usage), |
36 fd_(std::move(fd)) {} | 37 fd_(std::move(fd)), |
| 38 stride_(stride) {} |
37 | 39 |
38 GbmBuffer::~GbmBuffer() { | 40 GbmBuffer::~GbmBuffer() { |
39 if (bo()) | 41 if (bo()) |
40 gbm_bo_destroy(bo()); | 42 gbm_bo_destroy(bo()); |
41 } | 43 } |
42 | 44 |
43 int GbmBuffer::GetFd() const { | 45 int GbmBuffer::GetFd() const { |
44 return fd_.get(); | 46 return fd_.get(); |
45 } | 47 } |
46 | 48 |
47 int GbmBuffer::GetStride() const { | 49 int GbmBuffer::GetStride() const { |
48 return gbm_bo_get_stride(bo()); | 50 return stride_; |
49 } | 51 } |
50 | 52 |
51 // static | 53 // static |
52 scoped_refptr<GbmBuffer> GbmBuffer::CreateBuffer( | 54 scoped_refptr<GbmBuffer> GbmBuffer::CreateBuffer( |
53 const scoped_refptr<GbmDevice>& gbm, | 55 const scoped_refptr<GbmDevice>& gbm, |
54 gfx::BufferFormat format, | 56 gfx::BufferFormat format, |
55 const gfx::Size& size, | 57 const gfx::Size& size, |
56 gfx::BufferUsage usage) { | 58 gfx::BufferUsage usage) { |
57 TRACE_EVENT2("drm", "GbmBuffer::CreateBuffer", "device", | 59 TRACE_EVENT2("drm", "GbmBuffer::CreateBuffer", "device", |
58 gbm->device_path().value(), "size", size.ToString()); | 60 gbm->device_path().value(), "size", size.ToString()); |
(...skipping 18 matching lines...) Expand all Loading... |
77 | 79 |
78 // The fd returned by gbm_bo_get_fd is not ref-counted and need to be | 80 // The fd returned by gbm_bo_get_fd is not ref-counted and need to be |
79 // kept open for the lifetime of the buffer. | 81 // kept open for the lifetime of the buffer. |
80 base::ScopedFD fd(gbm_bo_get_fd(bo)); | 82 base::ScopedFD fd(gbm_bo_get_fd(bo)); |
81 if (!fd.is_valid()) { | 83 if (!fd.is_valid()) { |
82 PLOG(ERROR) << "Failed to export buffer to dma_buf"; | 84 PLOG(ERROR) << "Failed to export buffer to dma_buf"; |
83 gbm_bo_destroy(bo); | 85 gbm_bo_destroy(bo); |
84 return nullptr; | 86 return nullptr; |
85 } | 87 } |
86 | 88 |
87 scoped_refptr<GbmBuffer> buffer( | 89 scoped_refptr<GbmBuffer> buffer(new GbmBuffer( |
88 new GbmBuffer(gbm, bo, format, usage, std::move(fd))); | 90 gbm, bo, format, usage, std::move(fd), gbm_bo_get_stride(bo))); |
89 if (usage == gfx::BufferUsage::SCANOUT && !buffer->GetFramebufferId()) | 91 if (usage == gfx::BufferUsage::SCANOUT && !buffer->GetFramebufferId()) |
90 return nullptr; | 92 return nullptr; |
91 | 93 |
92 return buffer; | 94 return buffer; |
93 } | 95 } |
94 | 96 |
95 // static | 97 // static |
96 scoped_refptr<GbmBuffer> GbmBuffer::CreateBufferFromFD( | 98 scoped_refptr<GbmBuffer> GbmBuffer::CreateBufferFromFD( |
97 const scoped_refptr<GbmDevice>& gbm, | 99 const scoped_refptr<GbmDevice>& gbm, |
98 gfx::BufferFormat format, | 100 gfx::BufferFormat format, |
99 const gfx::Size& size, | 101 const gfx::Size& size, |
100 base::ScopedFD fd, | 102 base::ScopedFD fd, |
101 int stride) { | 103 int stride) { |
102 TRACE_EVENT2("drm", "GbmBuffer::CreateBufferFromFD", "device", | 104 TRACE_EVENT2("drm", "GbmBuffer::CreateBufferFromFD", "device", |
103 gbm->device_path().value(), "size", size.ToString()); | 105 gbm->device_path().value(), "size", size.ToString()); |
104 | 106 |
105 struct gbm_import_fd_data fd_data; | 107 // TODO(reveman): Use gbm_bo_import after making buffers survive |
106 fd_data.fd = fd.get(); | 108 // GPU process crashes. crbug.com/597932 |
107 fd_data.width = size.width(); | 109 return make_scoped_refptr(new GbmBuffer( |
108 fd_data.height = size.height(); | 110 gbm, nullptr, format, gfx::BufferUsage::GPU_READ, std::move(fd), stride)); |
109 fd_data.stride = stride; | |
110 fd_data.format = GetFourCCFormatFromBufferFormat(format); | |
111 | |
112 // Use scanout if supported. | |
113 const std::vector<uint32_t>& scanout_formats = | |
114 gbm->plane_manager()->GetSupportedFormats(); | |
115 bool use_scanout = std::find(scanout_formats.begin(), scanout_formats.end(), | |
116 fd_data.format) != scanout_formats.end(); | |
117 unsigned flags = 0; | |
118 if (use_scanout) | |
119 flags = GBM_BO_USE_SCANOUT | GBM_BO_USE_RENDERING; | |
120 | |
121 // The fd passed to gbm_bo_import is not ref-counted and need to be | |
122 // kept open for the lifetime of the buffer. | |
123 gbm_bo* bo = gbm_bo_import(gbm->device(), GBM_BO_IMPORT_FD, &fd_data, flags); | |
124 if (!bo) | |
125 return nullptr; | |
126 | |
127 scoped_refptr<GbmBuffer> buffer(new GbmBuffer( | |
128 gbm, bo, format, | |
129 use_scanout ? gfx::BufferUsage::SCANOUT : gfx::BufferUsage::GPU_READ, | |
130 std::move(fd))); | |
131 if (use_scanout && !buffer->GetFramebufferId()) | |
132 return nullptr; | |
133 | |
134 return buffer; | |
135 } | 111 } |
136 | 112 |
137 GbmPixmap::GbmPixmap(GbmSurfaceFactory* surface_manager, | 113 GbmPixmap::GbmPixmap(GbmSurfaceFactory* surface_manager, |
138 const scoped_refptr<GbmBuffer>& buffer) | 114 const scoped_refptr<GbmBuffer>& buffer) |
139 : surface_manager_(surface_manager), buffer_(buffer) {} | 115 : surface_manager_(surface_manager), buffer_(buffer) {} |
140 | 116 |
141 void GbmPixmap::SetProcessingCallback( | 117 void GbmPixmap::SetProcessingCallback( |
142 const ProcessingCallback& processing_callback) { | 118 const ProcessingCallback& processing_callback) { |
143 DCHECK(processing_callback_.is_null()); | 119 DCHECK(processing_callback_.is_null()); |
144 processing_callback_ = processing_callback; | 120 processing_callback_ = processing_callback; |
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
223 DCHECK(!processing_callback_.is_null()); | 199 DCHECK(!processing_callback_.is_null()); |
224 if (!processing_callback_.Run(this, processed_pixmap_)) { | 200 if (!processing_callback_.Run(this, processed_pixmap_)) { |
225 LOG(ERROR) << "Failed processing NativePixmap"; | 201 LOG(ERROR) << "Failed processing NativePixmap"; |
226 return nullptr; | 202 return nullptr; |
227 } | 203 } |
228 | 204 |
229 return processed_pixmap_->buffer(); | 205 return processed_pixmap_->buffer(); |
230 } | 206 } |
231 | 207 |
232 } // namespace ui | 208 } // namespace ui |
OLD | NEW |