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::GbmBufferPlane>&& 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::GbmBufferPlane> 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::GbmBufferPlane>& 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_EQ(fds.size(), strides.size()); | 146 DCHECK_EQ(fds.size(), planes.size()); |
146 // TODO(reveman): Use gbm_bo_import after making buffers survive | 147 // TODO(reveman): Use gbm_bo_import after making buffers survive |
147 // GPU process crashes. crbug.com/597932 | 148 // GPU process crashes. crbug.com/597932 |
148 return make_scoped_refptr( | 149 return make_scoped_refptr( |
149 new GbmBuffer(gbm, nullptr, format, gfx::BufferUsage::GPU_READ, | 150 new GbmBuffer(gbm, nullptr, format, gfx::BufferUsage::GPU_READ, |
150 std::move(fds), size, strides, offsets)); | 151 std::move(fds), size, std::move(planes))); |
151 } | 152 } |
152 | 153 |
153 GbmPixmap::GbmPixmap(GbmSurfaceFactory* surface_manager, | 154 GbmPixmap::GbmPixmap(GbmSurfaceFactory* surface_manager, |
154 const scoped_refptr<GbmBuffer>& buffer) | 155 const scoped_refptr<GbmBuffer>& buffer) |
155 : surface_manager_(surface_manager), buffer_(buffer) {} | 156 : surface_manager_(surface_manager), buffer_(buffer) {} |
156 | 157 |
157 void GbmPixmap::SetProcessingCallback( | 158 void GbmPixmap::SetProcessingCallback( |
158 const ProcessingCallback& processing_callback) { | 159 const ProcessingCallback& processing_callback) { |
159 DCHECK(processing_callback_.is_null()); | 160 DCHECK(processing_callback_.is_null()); |
160 processing_callback_ = processing_callback; | 161 processing_callback_ = processing_callback; |
161 } | 162 } |
162 | 163 |
163 gfx::NativePixmapHandle GbmPixmap::ExportHandle() { | 164 gfx::NativePixmapHandle GbmPixmap::ExportHandle() { |
164 gfx::NativePixmapHandle handle; | 165 gfx::NativePixmapHandle handle; |
165 for (size_t i = 0; | 166 for (size_t i = 0; |
166 i < gfx::NumberOfPlanesForBufferFormat(buffer_->GetFormat()); ++i) { | 167 i < gfx::NumberOfPlanesForBufferFormat(buffer_->GetFormat()); ++i) { |
167 // Some formats (e.g: YVU_420) might have less than one fd per plane. | 168 // Some formats (e.g: YVU_420) might have less than one fd per plane. |
168 if (i < buffer_->GetFdCount()) { | 169 if (i < buffer_->GetFdCount()) { |
169 base::ScopedFD scoped_fd(HANDLE_EINTR(dup(buffer_->GetFd(i)))); | 170 base::ScopedFD scoped_fd(HANDLE_EINTR(dup(buffer_->GetFd(i)))); |
170 if (!scoped_fd.is_valid()) { | 171 if (!scoped_fd.is_valid()) { |
171 PLOG(ERROR) << "dup"; | 172 PLOG(ERROR) << "dup"; |
172 return gfx::NativePixmapHandle(); | 173 return gfx::NativePixmapHandle(); |
173 } | 174 } |
174 handle.fds.emplace_back( | 175 handle.fds.emplace_back( |
175 base::FileDescriptor(scoped_fd.release(), true /* auto_close */)); | 176 base::FileDescriptor(scoped_fd.release(), true /* auto_close */)); |
176 } | 177 } |
177 handle.strides_and_offsets.emplace_back(buffer_->GetStride(i), | 178 handle.planes.emplace_back(buffer_->GetStride(i), buffer_->GetOffset(i), |
178 buffer_->GetOffset(i)); | 179 buffer_->GetFormatModifier(i)); |
179 } | 180 } |
180 return handle; | 181 return handle; |
181 } | 182 } |
182 | 183 |
183 GbmPixmap::~GbmPixmap() { | 184 GbmPixmap::~GbmPixmap() { |
184 } | 185 } |
185 | 186 |
186 void* GbmPixmap::GetEGLClientBuffer() const { | 187 void* GbmPixmap::GetEGLClientBuffer() const { |
187 return nullptr; | 188 return nullptr; |
188 } | 189 } |
(...skipping 11 matching lines...) Expand all Loading... |
200 } | 201 } |
201 | 202 |
202 int GbmPixmap::GetDmaBufPitch(size_t plane) const { | 203 int GbmPixmap::GetDmaBufPitch(size_t plane) const { |
203 return buffer_->GetStride(plane); | 204 return buffer_->GetStride(plane); |
204 } | 205 } |
205 | 206 |
206 int GbmPixmap::GetDmaBufOffset(size_t plane) const { | 207 int GbmPixmap::GetDmaBufOffset(size_t plane) const { |
207 return buffer_->GetOffset(plane); | 208 return buffer_->GetOffset(plane); |
208 } | 209 } |
209 | 210 |
| 211 uint64_t GbmPixmap::GetDmaBufModifier(size_t plane) const { |
| 212 return buffer_->GetFormatModifier(plane); |
| 213 } |
| 214 |
210 gfx::BufferFormat GbmPixmap::GetBufferFormat() const { | 215 gfx::BufferFormat GbmPixmap::GetBufferFormat() const { |
211 return buffer_->GetFormat(); | 216 return buffer_->GetFormat(); |
212 } | 217 } |
213 | 218 |
214 gfx::Size GbmPixmap::GetBufferSize() const { | 219 gfx::Size GbmPixmap::GetBufferSize() const { |
215 return buffer_->GetSize(); | 220 return buffer_->GetSize(); |
216 } | 221 } |
217 | 222 |
218 bool GbmPixmap::ScheduleOverlayPlane(gfx::AcceleratedWidget widget, | 223 bool GbmPixmap::ScheduleOverlayPlane(gfx::AcceleratedWidget widget, |
219 int plane_z_order, | 224 int plane_z_order, |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
257 DCHECK(!processing_callback_.is_null()); | 262 DCHECK(!processing_callback_.is_null()); |
258 if (!processing_callback_.Run(this, processed_pixmap_)) { | 263 if (!processing_callback_.Run(this, processed_pixmap_)) { |
259 LOG(ERROR) << "Failed processing NativePixmap"; | 264 LOG(ERROR) << "Failed processing NativePixmap"; |
260 return nullptr; | 265 return nullptr; |
261 } | 266 } |
262 | 267 |
263 return processed_pixmap_->buffer(); | 268 return processed_pixmap_->buffer(); |
264 } | 269 } |
265 | 270 |
266 } // namespace ui | 271 } // namespace ui |
OLD | NEW |