| 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 |