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<int>& strides, | 35 const std::vector<gfx::NativePixmapPlane>&& planes) |
36 const std::vector<int>& offsets) | |
37 : GbmBufferBase(gbm, bo, format, usage), | 36 : GbmBufferBase(gbm, bo, format, usage), |
38 format_(format), | 37 format_(format), |
39 usage_(usage), | 38 usage_(usage), |
40 fds_(std::move(fds)), | 39 fds_(std::move(fds)), |
41 size_(size), | 40 size_(size), |
42 strides_(strides), | 41 planes_(std::move(planes)) {} |
43 offsets_(offsets) {} | |
44 | 42 |
45 GbmBuffer::~GbmBuffer() { | 43 GbmBuffer::~GbmBuffer() { |
46 if (bo()) | 44 if (bo()) |
47 gbm_bo_destroy(bo()); | 45 gbm_bo_destroy(bo()); |
48 } | 46 } |
49 | 47 |
50 bool GbmBuffer::AreFdsValid() const { | 48 bool GbmBuffer::AreFdsValid() const { |
51 if (fds_.empty()) | 49 if (fds_.empty()) |
52 return false; | 50 return false; |
53 | 51 |
54 for (const auto& fd : fds_) { | 52 for (const auto& fd : fds_) { |
55 if (fd.get() == -1) | 53 if (fd.get() == -1) |
56 return false; | 54 return false; |
57 } | 55 } |
58 return true; | 56 return true; |
59 } | 57 } |
60 | 58 |
61 size_t GbmBuffer::GetFdCount() const { | 59 size_t GbmBuffer::GetFdCount() const { |
62 return fds_.size(); | 60 return fds_.size(); |
63 } | 61 } |
64 | 62 |
65 int GbmBuffer::GetFd(size_t plane) const { | 63 int GbmBuffer::GetFd(size_t index) const { |
66 DCHECK_LT(plane, fds_.size()); | 64 DCHECK_LT(index, fds_.size()); |
67 return fds_[plane].get(); | 65 return fds_[index].get(); |
68 } | 66 } |
69 | 67 |
70 int GbmBuffer::GetStride(size_t plane) const { | 68 int GbmBuffer::GetStride(size_t index) const { |
71 DCHECK_LT(plane, strides_.size()); | 69 DCHECK_LT(index, planes_.size()); |
72 return strides_[plane]; | 70 return planes_[index].stride; |
73 } | 71 } |
74 | 72 |
75 int GbmBuffer::GetOffset(size_t plane) const { | 73 int GbmBuffer::GetOffset(size_t index) const { |
76 DCHECK_LT(plane, offsets_.size()); | 74 DCHECK_LT(index, planes_.size()); |
77 return offsets_[plane]; | 75 return planes_[index].offset; |
| 76 } |
| 77 |
| 78 uint64_t GbmBuffer::GetFormatModifier(size_t index) const { |
| 79 DCHECK_LT(index, planes_.size()); |
| 80 return planes_[index].modifier; |
78 } | 81 } |
79 | 82 |
80 // TODO(reveman): This should not be needed once crbug.com/597932 is fixed, | 83 // TODO(reveman): This should not be needed once crbug.com/597932 is fixed, |
81 // as the size would be queried directly from the underlying bo. | 84 // as the size would be queried directly from the underlying bo. |
82 gfx::Size GbmBuffer::GetSize() const { | 85 gfx::Size GbmBuffer::GetSize() const { |
83 return size_; | 86 return size_; |
84 } | 87 } |
85 | 88 |
86 // static | 89 // static |
87 scoped_refptr<GbmBuffer> GbmBuffer::CreateBuffer( | 90 scoped_refptr<GbmBuffer> GbmBuffer::CreateBuffer( |
(...skipping 25 matching lines...) Expand all Loading... |
113 // The fd returned by gbm_bo_get_fd is not ref-counted and need to be | 116 // The fd returned by gbm_bo_get_fd is not ref-counted and need to be |
114 // kept open for the lifetime of the buffer. | 117 // kept open for the lifetime of the buffer. |
115 base::ScopedFD fd(gbm_bo_get_fd(bo)); | 118 base::ScopedFD fd(gbm_bo_get_fd(bo)); |
116 if (!fd.is_valid()) { | 119 if (!fd.is_valid()) { |
117 PLOG(ERROR) << "Failed to export buffer to dma_buf"; | 120 PLOG(ERROR) << "Failed to export buffer to dma_buf"; |
118 gbm_bo_destroy(bo); | 121 gbm_bo_destroy(bo); |
119 return nullptr; | 122 return nullptr; |
120 } | 123 } |
121 std::vector<base::ScopedFD> fds; | 124 std::vector<base::ScopedFD> fds; |
122 fds.emplace_back(std::move(fd)); | 125 fds.emplace_back(std::move(fd)); |
123 std::vector<int> strides; | 126 std::vector<gfx::NativePixmapPlane> planes; |
124 strides.push_back(gbm_bo_get_stride(bo)); | 127 planes.emplace_back(gbm_bo_get_stride(bo), gbm_bo_get_plane_offset(bo, 0), |
125 std::vector<int> offsets; | 128 gbm_bo_get_format_modifier(bo)); |
126 offsets.push_back(gbm_bo_get_plane_offset(bo, 0)); | |
127 scoped_refptr<GbmBuffer> buffer(new GbmBuffer( | 129 scoped_refptr<GbmBuffer> buffer(new GbmBuffer( |
128 gbm, bo, format, usage, std::move(fds), size, strides, offsets)); | 130 gbm, bo, format, usage, std::move(fds), size, std::move(planes))); |
129 if (usage == gfx::BufferUsage::SCANOUT && !buffer->GetFramebufferId()) | 131 if (usage == gfx::BufferUsage::SCANOUT && !buffer->GetFramebufferId()) |
130 return nullptr; | 132 return nullptr; |
131 | 133 |
132 return buffer; | 134 return buffer; |
133 } | 135 } |
134 | 136 |
135 // static | 137 // static |
136 scoped_refptr<GbmBuffer> GbmBuffer::CreateBufferFromFds( | 138 scoped_refptr<GbmBuffer> GbmBuffer::CreateBufferFromFds( |
137 const scoped_refptr<GbmDevice>& gbm, | 139 const scoped_refptr<GbmDevice>& gbm, |
138 gfx::BufferFormat format, | 140 gfx::BufferFormat format, |
139 const gfx::Size& size, | 141 const gfx::Size& size, |
140 std::vector<base::ScopedFD>&& fds, | 142 std::vector<base::ScopedFD>&& fds, |
141 const std::vector<int>& strides, | 143 const std::vector<gfx::NativePixmapPlane>& planes) { |
142 const std::vector<int>& offsets) { | |
143 TRACE_EVENT2("drm", "GbmBuffer::CreateBufferFromFD", "device", | 144 TRACE_EVENT2("drm", "GbmBuffer::CreateBufferFromFD", "device", |
144 gbm->device_path().value(), "size", size.ToString()); | 145 gbm->device_path().value(), "size", size.ToString()); |
145 DCHECK_LE(fds.size(), strides.size()); | 146 DCHECK_LE(fds.size(), planes.size()); |
146 DCHECK_EQ(strides.size(), offsets.size()); | 147 DCHECK_EQ(planes[0].offset, 0); |
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 = strides[0]; | 161 fd_data.stride = planes[0].stride; |
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, strides, offsets)); | 177 std::move(fds), size, std::move(planes))); |
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.strides_and_offsets.emplace_back(buffer_->GetStride(i), | 210 handle.planes.emplace_back(buffer_->GetStride(i), buffer_->GetOffset(i), |
211 buffer_->GetOffset(i)); | 211 buffer_->GetFormatModifier(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 |
243 gfx::BufferFormat GbmPixmap::GetBufferFormat() const { | 247 gfx::BufferFormat GbmPixmap::GetBufferFormat() const { |
244 return buffer_->GetFormat(); | 248 return buffer_->GetFormat(); |
245 } | 249 } |
246 | 250 |
247 gfx::Size GbmPixmap::GetBufferSize() const { | 251 gfx::Size GbmPixmap::GetBufferSize() const { |
248 return buffer_->GetSize(); | 252 return buffer_->GetSize(); |
249 } | 253 } |
250 | 254 |
251 bool GbmPixmap::ScheduleOverlayPlane(gfx::AcceleratedWidget widget, | 255 bool GbmPixmap::ScheduleOverlayPlane(gfx::AcceleratedWidget widget, |
252 int plane_z_order, | 256 int plane_z_order, |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
290 DCHECK(!processing_callback_.is_null()); | 294 DCHECK(!processing_callback_.is_null()); |
291 if (!processing_callback_.Run(this, processed_pixmap_)) { | 295 if (!processing_callback_.Run(this, processed_pixmap_)) { |
292 LOG(ERROR) << "Failed processing NativePixmap"; | 296 LOG(ERROR) << "Failed processing NativePixmap"; |
293 return nullptr; | 297 return nullptr; |
294 } | 298 } |
295 | 299 |
296 return processed_pixmap_->buffer(); | 300 return processed_pixmap_->buffer(); |
297 } | 301 } |
298 | 302 |
299 } // namespace ui | 303 } // namespace ui |
OLD | NEW |