| 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 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 51 if (!bo) | 51 if (!bo) |
| 52 return nullptr; | 52 return nullptr; |
| 53 | 53 |
| 54 scoped_refptr<GbmBuffer> buffer(new GbmBuffer(gbm, bo, usage)); | 54 scoped_refptr<GbmBuffer> buffer(new GbmBuffer(gbm, bo, usage)); |
| 55 if (use_scanout && !buffer->GetFramebufferId()) | 55 if (use_scanout && !buffer->GetFramebufferId()) |
| 56 return nullptr; | 56 return nullptr; |
| 57 | 57 |
| 58 return buffer; | 58 return buffer; |
| 59 } | 59 } |
| 60 | 60 |
| 61 GbmPixmap::GbmPixmap(const scoped_refptr<GbmBuffer>& buffer, | 61 GbmPixmap::GbmPixmap(GbmSurfaceFactory* surface_manager) |
| 62 GbmSurfaceFactory* surface_manager) | 62 : surface_manager_(surface_manager) {} |
| 63 : buffer_(buffer), surface_manager_(surface_manager) {} | |
| 64 | 63 |
| 65 bool GbmPixmap::Initialize() { | 64 void GbmPixmap::Initialize(base::ScopedFD dma_buf, int dma_buf_pitch) { |
| 65 dma_buf_ = dma_buf.Pass(); |
| 66 dma_buf_pitch_ = dma_buf_pitch; |
| 67 } |
| 68 |
| 69 bool GbmPixmap::InitializeFromBuffer(const scoped_refptr<GbmBuffer>& buffer) { |
| 66 // We want to use the GBM API because it's going to call into libdrm | 70 // We want to use the GBM API because it's going to call into libdrm |
| 67 // which might do some optimizations on buffer allocation, | 71 // which might do some optimizations on buffer allocation, |
| 68 // especially when sharing buffers via DMABUF. | 72 // especially when sharing buffers via DMABUF. |
| 69 dma_buf_ = gbm_bo_get_fd(buffer_->bo()); | 73 base::ScopedFD dma_buf(gbm_bo_get_fd(buffer->bo())); |
| 70 if (dma_buf_ < 0) { | 74 if (!dma_buf.is_valid()) { |
| 71 PLOG(ERROR) << "Failed to export buffer to dma_buf"; | 75 PLOG(ERROR) << "Failed to export buffer to dma_buf"; |
| 72 return false; | 76 return false; |
| 73 } | 77 } |
| 78 Initialize(dma_buf.Pass(), gbm_bo_get_stride(buffer->bo())); |
| 79 buffer_ = buffer; |
| 74 return true; | 80 return true; |
| 75 } | 81 } |
| 76 | 82 |
| 77 void GbmPixmap::SetScalingCallback(const ScalingCallback& scaling_callback) { | 83 void GbmPixmap::SetScalingCallback(const ScalingCallback& scaling_callback) { |
| 78 scaling_callback_ = scaling_callback; | 84 scaling_callback_ = scaling_callback; |
| 79 } | 85 } |
| 80 | 86 |
| 81 scoped_refptr<NativePixmap> GbmPixmap::GetScaledPixmap(gfx::Size new_size) { | 87 scoped_refptr<NativePixmap> GbmPixmap::GetScaledPixmap(gfx::Size new_size) { |
| 82 return scaling_callback_.Run(new_size); | 88 return scaling_callback_.Run(new_size); |
| 83 } | 89 } |
| 84 | 90 |
| 85 gfx::NativePixmapHandle GbmPixmap::ExportHandle() { | 91 gfx::NativePixmapHandle GbmPixmap::ExportHandle() { |
| 86 gfx::NativePixmapHandle handle; | 92 gfx::NativePixmapHandle handle; |
| 87 | 93 |
| 88 int dmabuf_fd = HANDLE_EINTR(dup(dma_buf_)); | 94 base::ScopedFD dmabuf_fd(HANDLE_EINTR(dup(dma_buf_.get()))); |
| 89 if (dmabuf_fd < 0) { | 95 if (!dmabuf_fd.is_valid()) { |
| 90 PLOG(ERROR) << "dup"; | 96 PLOG(ERROR) << "dup"; |
| 91 return handle; | 97 return handle; |
| 92 } | 98 } |
| 93 | 99 |
| 94 handle.fd = base::FileDescriptor(dmabuf_fd, true /* auto_close */); | 100 handle.fd = base::FileDescriptor(dmabuf_fd.release(), true /* auto_close */); |
| 95 handle.stride = gbm_bo_get_stride(buffer_->bo()); | 101 handle.stride = dma_buf_pitch_; |
| 96 return handle; | 102 return handle; |
| 97 } | 103 } |
| 98 | 104 |
| 99 GbmPixmap::~GbmPixmap() { | 105 GbmPixmap::~GbmPixmap() { |
| 100 if (dma_buf_ > 0) | |
| 101 close(dma_buf_); | |
| 102 } | 106 } |
| 103 | 107 |
| 104 void* GbmPixmap::GetEGLClientBuffer() { | 108 void* GbmPixmap::GetEGLClientBuffer() { |
| 105 return nullptr; | 109 return nullptr; |
| 106 } | 110 } |
| 107 | 111 |
| 108 int GbmPixmap::GetDmaBufFd() { | 112 int GbmPixmap::GetDmaBufFd() { |
| 109 return dma_buf_; | 113 return dma_buf_.get(); |
| 110 } | 114 } |
| 111 | 115 |
| 112 int GbmPixmap::GetDmaBufPitch() { | 116 int GbmPixmap::GetDmaBufPitch() { |
| 113 return gbm_bo_get_stride(buffer_->bo()); | 117 return dma_buf_pitch_; |
| 114 } | 118 } |
| 115 | 119 |
| 116 bool GbmPixmap::ScheduleOverlayPlane(gfx::AcceleratedWidget widget, | 120 bool GbmPixmap::ScheduleOverlayPlane(gfx::AcceleratedWidget widget, |
| 117 int plane_z_order, | 121 int plane_z_order, |
| 118 gfx::OverlayTransform plane_transform, | 122 gfx::OverlayTransform plane_transform, |
| 119 const gfx::Rect& display_bounds, | 123 const gfx::Rect& display_bounds, |
| 120 const gfx::RectF& crop_rect) { | 124 const gfx::RectF& crop_rect) { |
| 121 DCHECK(buffer_->GetUsage() == gfx::BufferUsage::SCANOUT); | |
| 122 gfx::Size required_size; | 125 gfx::Size required_size; |
| 123 if (plane_z_order && | 126 if (plane_z_order && |
| 124 ShouldApplyScaling(display_bounds, crop_rect, &required_size)) { | 127 ShouldApplyScaling(display_bounds, crop_rect, &required_size)) { |
| 125 scoped_refptr<NativePixmap> scaled_pixmap = GetScaledPixmap(required_size); | 128 scoped_refptr<NativePixmap> scaled_pixmap = GetScaledPixmap(required_size); |
| 126 if (scaled_pixmap) { | 129 if (scaled_pixmap) { |
| 127 return scaled_pixmap->ScheduleOverlayPlane( | 130 return scaled_pixmap->ScheduleOverlayPlane( |
| 128 widget, plane_z_order, plane_transform, display_bounds, crop_rect); | 131 widget, plane_z_order, plane_transform, display_bounds, crop_rect); |
| 129 } else { | 132 } else { |
| 130 return false; | 133 return false; |
| 131 } | 134 } |
| 132 } | 135 } |
| 133 | 136 |
| 137 // TODO(reveman): Add support for imported buffers. crbug.com/541558 |
| 138 if (!buffer_) { |
| 139 PLOG(ERROR) << "ScheduleOverlayPlane requires a buffer."; |
| 140 return false; |
| 141 } |
| 142 |
| 143 DCHECK(buffer_->GetUsage() == gfx::BufferUsage::SCANOUT); |
| 134 surface_manager_->GetSurface(widget)->QueueOverlayPlane(OverlayPlane( | 144 surface_manager_->GetSurface(widget)->QueueOverlayPlane(OverlayPlane( |
| 135 buffer_, plane_z_order, plane_transform, display_bounds, crop_rect)); | 145 buffer_, plane_z_order, plane_transform, display_bounds, crop_rect)); |
| 136 return true; | 146 return true; |
| 137 } | 147 } |
| 138 | 148 |
| 139 bool GbmPixmap::ShouldApplyScaling(const gfx::Rect& display_bounds, | 149 bool GbmPixmap::ShouldApplyScaling(const gfx::Rect& display_bounds, |
| 140 const gfx::RectF& crop_rect, | 150 const gfx::RectF& crop_rect, |
| 141 gfx::Size* required_size) { | 151 gfx::Size* required_size) { |
| 142 if (crop_rect.width() == 0 || crop_rect.height() == 0) { | 152 if (crop_rect.width() == 0 || crop_rect.height() == 0) { |
| 143 PLOG(ERROR) << "ShouldApplyScaling passed zero scaling target."; | 153 PLOG(ERROR) << "ShouldApplyScaling passed zero scaling target."; |
| 144 return false; | 154 return false; |
| 145 } | 155 } |
| 146 | 156 |
| 157 if (!buffer_) { |
| 158 PLOG(ERROR) << "ShouldApplyScaling requires a buffer."; |
| 159 return false; |
| 160 } |
| 161 |
| 147 gfx::Size pixmap_size = buffer_->GetSize(); | 162 gfx::Size pixmap_size = buffer_->GetSize(); |
| 148 // If the required size is not integer-sized, round it to the next integer. | 163 // If the required size is not integer-sized, round it to the next integer. |
| 149 *required_size = gfx::ToCeiledSize( | 164 *required_size = gfx::ToCeiledSize( |
| 150 gfx::SizeF(display_bounds.width() / crop_rect.width(), | 165 gfx::SizeF(display_bounds.width() / crop_rect.width(), |
| 151 display_bounds.height() / crop_rect.height())); | 166 display_bounds.height() / crop_rect.height())); |
| 152 return pixmap_size != *required_size; | 167 return pixmap_size != *required_size; |
| 153 } | 168 } |
| 154 | 169 |
| 155 } // namespace ui | 170 } // namespace ui |
| OLD | NEW |