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 14 matching lines...) Expand all Loading... |
25 #include "ui/ozone/public/surface_factory_ozone.h" | 25 #include "ui/ozone/public/surface_factory_ozone.h" |
26 | 26 |
27 namespace ui { | 27 namespace ui { |
28 | 28 |
29 GbmBuffer::GbmBuffer(const scoped_refptr<GbmDevice>& gbm, | 29 GbmBuffer::GbmBuffer(const scoped_refptr<GbmDevice>& gbm, |
30 gbm_bo* bo, | 30 gbm_bo* bo, |
31 gfx::BufferFormat format, | 31 gfx::BufferFormat format, |
32 gfx::BufferUsage usage, | 32 gfx::BufferUsage usage, |
33 std::vector<base::ScopedFD>&& fds, | 33 std::vector<base::ScopedFD>&& fds, |
34 const gfx::Size& size, | 34 const gfx::Size& size, |
35 const std::vector<gfx::NativePixmapPlane>&& planes) | 35 const std::vector<int>& strides, |
| 36 const std::vector<int>& offsets) |
36 : GbmBufferBase(gbm, bo, format, usage), | 37 : GbmBufferBase(gbm, bo, format, usage), |
37 format_(format), | 38 format_(format), |
38 usage_(usage), | 39 usage_(usage), |
39 fds_(std::move(fds)), | 40 fds_(std::move(fds)), |
40 size_(size), | 41 size_(size), |
41 planes_(std::move(planes)) {} | 42 strides_(strides), |
| 43 offsets_(offsets) {} |
42 | 44 |
43 GbmBuffer::~GbmBuffer() { | 45 GbmBuffer::~GbmBuffer() { |
44 if (bo()) | 46 if (bo()) |
45 gbm_bo_destroy(bo()); | 47 gbm_bo_destroy(bo()); |
46 } | 48 } |
47 | 49 |
48 bool GbmBuffer::AreFdsValid() const { | 50 bool GbmBuffer::AreFdsValid() const { |
49 if (fds_.empty()) | 51 if (fds_.empty()) |
50 return false; | 52 return false; |
51 | 53 |
52 for (const auto& fd : fds_) { | 54 for (const auto& fd : fds_) { |
53 if (fd.get() == -1) | 55 if (fd.get() == -1) |
54 return false; | 56 return false; |
55 } | 57 } |
56 return true; | 58 return true; |
57 } | 59 } |
58 | 60 |
59 size_t GbmBuffer::GetFdCount() const { | 61 size_t GbmBuffer::GetFdCount() const { |
60 return fds_.size(); | 62 return fds_.size(); |
61 } | 63 } |
62 | 64 |
63 int GbmBuffer::GetFd(size_t index) const { | 65 int GbmBuffer::GetFd(size_t plane) const { |
64 DCHECK_LT(index, fds_.size()); | 66 DCHECK_LT(plane, fds_.size()); |
65 return fds_[index].get(); | 67 return fds_[plane].get(); |
66 } | 68 } |
67 | 69 |
68 int GbmBuffer::GetStride(size_t index) const { | 70 int GbmBuffer::GetStride(size_t plane) const { |
69 DCHECK_LT(index, planes_.size()); | 71 DCHECK_LT(plane, strides_.size()); |
70 return planes_[index].stride; | 72 return strides_[plane]; |
71 } | 73 } |
72 | 74 |
73 int GbmBuffer::GetOffset(size_t index) const { | 75 int GbmBuffer::GetOffset(size_t plane) const { |
74 DCHECK_LT(index, planes_.size()); | 76 DCHECK_LT(plane, offsets_.size()); |
75 return planes_[index].offset; | 77 return offsets_[plane]; |
76 } | |
77 | |
78 uint64_t GbmBuffer::GetFormatModifier(size_t index) const { | |
79 DCHECK_LT(index, planes_.size()); | |
80 return planes_[index].modifier; | |
81 } | 78 } |
82 | 79 |
83 // TODO(reveman): This should not be needed once crbug.com/597932 is fixed, | 80 // TODO(reveman): This should not be needed once crbug.com/597932 is fixed, |
84 // as the size would be queried directly from the underlying bo. | 81 // as the size would be queried directly from the underlying bo. |
85 gfx::Size GbmBuffer::GetSize() const { | 82 gfx::Size GbmBuffer::GetSize() const { |
86 return size_; | 83 return size_; |
87 } | 84 } |
88 | 85 |
89 // static | 86 // static |
90 scoped_refptr<GbmBuffer> GbmBuffer::CreateBuffer( | 87 scoped_refptr<GbmBuffer> GbmBuffer::CreateBuffer( |
(...skipping 25 matching lines...) Expand all Loading... |
116 // The fd returned by gbm_bo_get_fd is not ref-counted and need to be | 113 // The fd returned by gbm_bo_get_fd is not ref-counted and need to be |
117 // kept open for the lifetime of the buffer. | 114 // kept open for the lifetime of the buffer. |
118 base::ScopedFD fd(gbm_bo_get_fd(bo)); | 115 base::ScopedFD fd(gbm_bo_get_fd(bo)); |
119 if (!fd.is_valid()) { | 116 if (!fd.is_valid()) { |
120 PLOG(ERROR) << "Failed to export buffer to dma_buf"; | 117 PLOG(ERROR) << "Failed to export buffer to dma_buf"; |
121 gbm_bo_destroy(bo); | 118 gbm_bo_destroy(bo); |
122 return nullptr; | 119 return nullptr; |
123 } | 120 } |
124 std::vector<base::ScopedFD> fds; | 121 std::vector<base::ScopedFD> fds; |
125 fds.emplace_back(std::move(fd)); | 122 fds.emplace_back(std::move(fd)); |
126 std::vector<gfx::NativePixmapPlane> planes; | 123 std::vector<int> strides; |
127 planes.emplace_back(gbm_bo_get_stride(bo), gbm_bo_get_plane_offset(bo, 0), | 124 strides.push_back(gbm_bo_get_stride(bo)); |
128 gbm_bo_get_format_modifier(bo)); | 125 std::vector<int> offsets; |
| 126 offsets.push_back(gbm_bo_get_plane_offset(bo, 0)); |
129 scoped_refptr<GbmBuffer> buffer(new GbmBuffer( | 127 scoped_refptr<GbmBuffer> buffer(new GbmBuffer( |
130 gbm, bo, format, usage, std::move(fds), size, std::move(planes))); | 128 gbm, bo, format, usage, std::move(fds), size, strides, offsets)); |
131 if (usage == gfx::BufferUsage::SCANOUT && !buffer->GetFramebufferId()) | 129 if (usage == gfx::BufferUsage::SCANOUT && !buffer->GetFramebufferId()) |
132 return nullptr; | 130 return nullptr; |
133 | 131 |
134 return buffer; | 132 return buffer; |
135 } | 133 } |
136 | 134 |
137 // static | 135 // static |
138 scoped_refptr<GbmBuffer> GbmBuffer::CreateBufferFromFds( | 136 scoped_refptr<GbmBuffer> GbmBuffer::CreateBufferFromFds( |
139 const scoped_refptr<GbmDevice>& gbm, | 137 const scoped_refptr<GbmDevice>& gbm, |
140 gfx::BufferFormat format, | 138 gfx::BufferFormat format, |
141 const gfx::Size& size, | 139 const gfx::Size& size, |
142 std::vector<base::ScopedFD>&& fds, | 140 std::vector<base::ScopedFD>&& fds, |
143 const std::vector<gfx::NativePixmapPlane>& planes) { | 141 const std::vector<int>& strides, |
| 142 const std::vector<int>& offsets) { |
144 TRACE_EVENT2("drm", "GbmBuffer::CreateBufferFromFD", "device", | 143 TRACE_EVENT2("drm", "GbmBuffer::CreateBufferFromFD", "device", |
145 gbm->device_path().value(), "size", size.ToString()); | 144 gbm->device_path().value(), "size", size.ToString()); |
146 DCHECK_LE(fds.size(), planes.size()); | 145 DCHECK_LE(fds.size(), strides.size()); |
147 DCHECK_EQ(planes[0].offset, 0); | 146 DCHECK_EQ(strides.size(), offsets.size()); |
| 147 DCHECK_EQ(offsets[0], 0); |
148 | 148 |
149 uint32_t fourcc_format = GetFourCCFormatFromBufferFormat(format); | 149 uint32_t fourcc_format = GetFourCCFormatFromBufferFormat(format); |
150 | 150 |
151 // Use scanout if supported. | 151 // Use scanout if supported. |
152 bool use_scanout = gbm_device_is_format_supported( | 152 bool use_scanout = gbm_device_is_format_supported( |
153 gbm->device(), fourcc_format, GBM_BO_USE_SCANOUT | GBM_BO_USE_RENDERING); | 153 gbm->device(), fourcc_format, GBM_BO_USE_SCANOUT | GBM_BO_USE_RENDERING); |
154 | 154 |
155 gbm_bo* bo = nullptr; | 155 gbm_bo* bo = nullptr; |
156 if (use_scanout) { | 156 if (use_scanout) { |
157 struct gbm_import_fd_data fd_data; | 157 struct gbm_import_fd_data fd_data; |
158 fd_data.fd = fds[0].get(); | 158 fd_data.fd = fds[0].get(); |
159 fd_data.width = size.width(); | 159 fd_data.width = size.width(); |
160 fd_data.height = size.height(); | 160 fd_data.height = size.height(); |
161 fd_data.stride = planes[0].stride; | 161 fd_data.stride = strides[0]; |
162 fd_data.format = fourcc_format; | 162 fd_data.format = fourcc_format; |
163 | 163 |
164 // The fd passed to gbm_bo_import is not ref-counted and need to be | 164 // The fd passed to gbm_bo_import is not ref-counted and need to be |
165 // kept open for the lifetime of the buffer. | 165 // kept open for the lifetime of the buffer. |
166 bo = gbm_bo_import(gbm->device(), GBM_BO_IMPORT_FD, &fd_data, | 166 bo = gbm_bo_import(gbm->device(), GBM_BO_IMPORT_FD, &fd_data, |
167 GBM_BO_USE_SCANOUT | GBM_BO_USE_RENDERING); | 167 GBM_BO_USE_SCANOUT | GBM_BO_USE_RENDERING); |
168 if (!bo) { | 168 if (!bo) { |
169 LOG(ERROR) << "nullptr returned from gbm_bo_import"; | 169 LOG(ERROR) << "nullptr returned from gbm_bo_import"; |
170 return nullptr; | 170 return nullptr; |
171 } | 171 } |
172 } | 172 } |
173 | 173 |
174 scoped_refptr<GbmBuffer> buffer(new GbmBuffer( | 174 scoped_refptr<GbmBuffer> buffer(new GbmBuffer( |
175 gbm, bo, format, | 175 gbm, bo, format, |
176 use_scanout ? gfx::BufferUsage::SCANOUT : gfx::BufferUsage::GPU_READ, | 176 use_scanout ? gfx::BufferUsage::SCANOUT : gfx::BufferUsage::GPU_READ, |
177 std::move(fds), size, std::move(planes))); | 177 std::move(fds), size, strides, offsets)); |
178 // If scanout support for buffer is expected then make sure we managed to | 178 // If scanout support for buffer is expected then make sure we managed to |
179 // create a framebuffer for it as otherwise using it for scanout will fail. | 179 // create a framebuffer for it as otherwise using it for scanout will fail. |
180 if (use_scanout && !buffer->GetFramebufferId()) | 180 if (use_scanout && !buffer->GetFramebufferId()) |
181 return nullptr; | 181 return nullptr; |
182 | 182 |
183 return buffer; | 183 return buffer; |
184 } | 184 } |
185 | 185 |
186 GbmPixmap::GbmPixmap(GbmSurfaceFactory* surface_manager, | 186 GbmPixmap::GbmPixmap(GbmSurfaceFactory* surface_manager, |
187 const scoped_refptr<GbmBuffer>& buffer) | 187 const scoped_refptr<GbmBuffer>& buffer) |
(...skipping 12 matching lines...) Expand all Loading... |
200 // Some formats (e.g: YVU_420) might have less than one fd per plane. | 200 // Some formats (e.g: YVU_420) might have less than one fd per plane. |
201 if (i < buffer_->GetFdCount()) { | 201 if (i < buffer_->GetFdCount()) { |
202 base::ScopedFD scoped_fd(HANDLE_EINTR(dup(buffer_->GetFd(i)))); | 202 base::ScopedFD scoped_fd(HANDLE_EINTR(dup(buffer_->GetFd(i)))); |
203 if (!scoped_fd.is_valid()) { | 203 if (!scoped_fd.is_valid()) { |
204 PLOG(ERROR) << "dup"; | 204 PLOG(ERROR) << "dup"; |
205 return gfx::NativePixmapHandle(); | 205 return gfx::NativePixmapHandle(); |
206 } | 206 } |
207 handle.fds.emplace_back( | 207 handle.fds.emplace_back( |
208 base::FileDescriptor(scoped_fd.release(), true /* auto_close */)); | 208 base::FileDescriptor(scoped_fd.release(), true /* auto_close */)); |
209 } | 209 } |
210 handle.planes.emplace_back(buffer_->GetStride(i), buffer_->GetOffset(i), | 210 handle.strides_and_offsets.emplace_back(buffer_->GetStride(i), |
211 buffer_->GetFormatModifier(i)); | 211 buffer_->GetOffset(i)); |
212 } | 212 } |
213 return handle; | 213 return handle; |
214 } | 214 } |
215 | 215 |
216 GbmPixmap::~GbmPixmap() { | 216 GbmPixmap::~GbmPixmap() { |
217 } | 217 } |
218 | 218 |
219 void* GbmPixmap::GetEGLClientBuffer() const { | 219 void* GbmPixmap::GetEGLClientBuffer() const { |
220 return nullptr; | 220 return nullptr; |
221 } | 221 } |
(...skipping 11 matching lines...) Expand all Loading... |
233 } | 233 } |
234 | 234 |
235 int GbmPixmap::GetDmaBufPitch(size_t plane) const { | 235 int GbmPixmap::GetDmaBufPitch(size_t plane) const { |
236 return buffer_->GetStride(plane); | 236 return buffer_->GetStride(plane); |
237 } | 237 } |
238 | 238 |
239 int GbmPixmap::GetDmaBufOffset(size_t plane) const { | 239 int GbmPixmap::GetDmaBufOffset(size_t plane) const { |
240 return buffer_->GetOffset(plane); | 240 return buffer_->GetOffset(plane); |
241 } | 241 } |
242 | 242 |
243 uint64_t GbmPixmap::GetDmaBufModifier(size_t plane) const { | |
244 return buffer_->GetFormatModifier(plane); | |
245 } | |
246 | |
247 gfx::BufferFormat GbmPixmap::GetBufferFormat() const { | 243 gfx::BufferFormat GbmPixmap::GetBufferFormat() const { |
248 return buffer_->GetFormat(); | 244 return buffer_->GetFormat(); |
249 } | 245 } |
250 | 246 |
251 gfx::Size GbmPixmap::GetBufferSize() const { | 247 gfx::Size GbmPixmap::GetBufferSize() const { |
252 return buffer_->GetSize(); | 248 return buffer_->GetSize(); |
253 } | 249 } |
254 | 250 |
255 bool GbmPixmap::ScheduleOverlayPlane(gfx::AcceleratedWidget widget, | 251 bool GbmPixmap::ScheduleOverlayPlane(gfx::AcceleratedWidget widget, |
256 int plane_z_order, | 252 int plane_z_order, |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
294 DCHECK(!processing_callback_.is_null()); | 290 DCHECK(!processing_callback_.is_null()); |
295 if (!processing_callback_.Run(this, processed_pixmap_)) { | 291 if (!processing_callback_.Run(this, processed_pixmap_)) { |
296 LOG(ERROR) << "Failed processing NativePixmap"; | 292 LOG(ERROR) << "Failed processing NativePixmap"; |
297 return nullptr; | 293 return nullptr; |
298 } | 294 } |
299 | 295 |
300 return processed_pixmap_->buffer(); | 296 return processed_pixmap_->buffer(); |
301 } | 297 } |
302 | 298 |
303 } // namespace ui | 299 } // namespace ui |
OLD | NEW |