Chromium Code Reviews| 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 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 66 if (!bo) | 66 if (!bo) |
| 67 return nullptr; | 67 return nullptr; |
| 68 | 68 |
| 69 scoped_refptr<GbmBuffer> buffer(new GbmBuffer(gbm, bo, usage)); | 69 scoped_refptr<GbmBuffer> buffer(new GbmBuffer(gbm, bo, usage)); |
| 70 if (use_scanout && !buffer->GetFramebufferId()) | 70 if (use_scanout && !buffer->GetFramebufferId()) |
| 71 return nullptr; | 71 return nullptr; |
| 72 | 72 |
| 73 return buffer; | 73 return buffer; |
| 74 } | 74 } |
| 75 | 75 |
| 76 GbmPixmap::GbmPixmap(const scoped_refptr<GbmBuffer>& buffer, | 76 GbmPixmap::GbmPixmap(GbmSurfaceFactory* surface_manager) |
| 77 GbmSurfaceFactory* surface_manager) | 77 : surface_manager_(surface_manager) {} |
| 78 : buffer_(buffer), surface_manager_(surface_manager) {} | |
| 79 | 78 |
| 80 bool GbmPixmap::Initialize() { | 79 void GbmPixmap::Initialize(int dma_buf, int dma_buf_pitch) { |
| 80 dma_buf_ = dma_buf; | |
| 81 dma_buf_pitch_ = dma_buf_pitch; | |
| 82 } | |
| 83 | |
| 84 bool GbmPixmap::InitializeFromBuffer(const scoped_refptr<GbmBuffer>& buffer) { | |
| 81 // We want to use the GBM API because it's going to call into libdrm | 85 // We want to use the GBM API because it's going to call into libdrm |
| 82 // which might do some optimizations on buffer allocation, | 86 // which might do some optimizations on buffer allocation, |
| 83 // especially when sharing buffers via DMABUF. | 87 // especially when sharing buffers via DMABUF. |
| 84 dma_buf_ = gbm_bo_get_fd(buffer_->bo()); | 88 int dma_buf = gbm_bo_get_fd(buffer->bo()); |
| 85 if (dma_buf_ < 0) { | 89 if (dma_buf < 0) { |
| 86 PLOG(ERROR) << "Failed to export buffer to dma_buf"; | 90 PLOG(ERROR) << "Failed to export buffer to dma_buf"; |
| 87 return false; | 91 return false; |
| 88 } | 92 } |
| 93 Initialize(dma_buf, gbm_bo_get_stride(buffer->bo())); | |
| 94 buffer_ = buffer; | |
| 89 return true; | 95 return true; |
| 90 } | 96 } |
| 91 | 97 |
| 92 void GbmPixmap::SetScalingCallback(const ScalingCallback& scaling_callback) { | 98 void GbmPixmap::SetScalingCallback(const ScalingCallback& scaling_callback) { |
| 93 scaling_callback_ = scaling_callback; | 99 scaling_callback_ = scaling_callback; |
| 94 } | 100 } |
| 95 | 101 |
| 96 scoped_refptr<NativePixmap> GbmPixmap::GetScaledPixmap(gfx::Size new_size) { | 102 scoped_refptr<NativePixmap> GbmPixmap::GetScaledPixmap(gfx::Size new_size) { |
| 97 return scaling_callback_.Run(new_size); | 103 return scaling_callback_.Run(new_size); |
| 98 } | 104 } |
| 99 | 105 |
| 100 gfx::NativePixmapHandle GbmPixmap::ExportHandle() { | 106 gfx::NativePixmapHandle GbmPixmap::ExportHandle() { |
| 101 gfx::NativePixmapHandle handle; | 107 gfx::NativePixmapHandle handle; |
| 102 | 108 |
| 103 int dmabuf_fd = HANDLE_EINTR(dup(dma_buf_)); | 109 int dmabuf_fd = HANDLE_EINTR(dup(dma_buf_)); |
| 104 if (dmabuf_fd < 0) { | 110 if (dmabuf_fd < 0) { |
| 105 PLOG(ERROR) << "dup"; | 111 PLOG(ERROR) << "dup"; |
| 106 return handle; | 112 return handle; |
| 107 } | 113 } |
| 108 | 114 |
| 109 handle.fd = base::FileDescriptor(dmabuf_fd, true /* auto_close */); | 115 handle.fd = base::FileDescriptor(dmabuf_fd, true /* auto_close */); |
| 110 handle.stride = gbm_bo_get_stride(buffer_->bo()); | 116 handle.stride = dma_buf_pitch_; |
| 111 return handle; | 117 return handle; |
| 112 } | 118 } |
| 113 | 119 |
| 114 GbmPixmap::~GbmPixmap() { | 120 GbmPixmap::~GbmPixmap() { |
| 115 if (dma_buf_ > 0) | 121 if (dma_buf_ > 0) |
| 116 close(dma_buf_); | 122 close(dma_buf_); |
| 117 } | 123 } |
| 118 | 124 |
| 119 void* GbmPixmap::GetEGLClientBuffer() { | 125 void* GbmPixmap::GetEGLClientBuffer() { |
| 120 return nullptr; | 126 return nullptr; |
| 121 } | 127 } |
| 122 | 128 |
| 123 int GbmPixmap::GetDmaBufFd() { | 129 int GbmPixmap::GetDmaBufFd() { |
| 124 return dma_buf_; | 130 return dma_buf_; |
| 125 } | 131 } |
| 126 | 132 |
| 127 int GbmPixmap::GetDmaBufPitch() { | 133 int GbmPixmap::GetDmaBufPitch() { |
| 128 return gbm_bo_get_stride(buffer_->bo()); | 134 return dma_buf_pitch_; |
| 129 } | 135 } |
| 130 | 136 |
| 131 bool GbmPixmap::ScheduleOverlayPlane(gfx::AcceleratedWidget widget, | 137 bool GbmPixmap::ScheduleOverlayPlane(gfx::AcceleratedWidget widget, |
| 132 int plane_z_order, | 138 int plane_z_order, |
| 133 gfx::OverlayTransform plane_transform, | 139 gfx::OverlayTransform plane_transform, |
| 134 const gfx::Rect& display_bounds, | 140 const gfx::Rect& display_bounds, |
| 135 const gfx::RectF& crop_rect) { | 141 const gfx::RectF& crop_rect) { |
| 136 DCHECK(buffer_->GetUsage() == gfx::BufferUsage::SCANOUT); | |
| 137 gfx::Size required_size; | 142 gfx::Size required_size; |
| 138 if (plane_z_order && | 143 if (plane_z_order && |
| 139 ShouldApplyScaling(display_bounds, crop_rect, &required_size)) { | 144 ShouldApplyScaling(display_bounds, crop_rect, &required_size)) { |
| 140 scoped_refptr<NativePixmap> scaled_pixmap = GetScaledPixmap(required_size); | 145 scoped_refptr<NativePixmap> scaled_pixmap = GetScaledPixmap(required_size); |
| 141 if (scaled_pixmap) { | 146 if (scaled_pixmap) { |
| 142 return scaled_pixmap->ScheduleOverlayPlane( | 147 return scaled_pixmap->ScheduleOverlayPlane( |
| 143 widget, plane_z_order, plane_transform, display_bounds, crop_rect); | 148 widget, plane_z_order, plane_transform, display_bounds, crop_rect); |
| 144 } else { | 149 } else { |
| 145 return false; | 150 return false; |
| 146 } | 151 } |
| 147 } | 152 } |
| 148 | 153 |
| 154 if (!buffer_) { | |
|
piman
2015/10/08 23:24:36
I assume eventually we'll want to support this for
reveman
2015/10/09 12:47:02
I haven't looked at this much in detail but it see
| |
| 155 PLOG(ERROR) << "ScheduleOverlayPlane requires a buffer."; | |
| 156 return false; | |
| 157 } | |
| 158 | |
| 159 DCHECK(buffer_->GetUsage() == gfx::BufferUsage::SCANOUT); | |
| 149 surface_manager_->GetSurface(widget)->QueueOverlayPlane(OverlayPlane( | 160 surface_manager_->GetSurface(widget)->QueueOverlayPlane(OverlayPlane( |
| 150 buffer_, plane_z_order, plane_transform, display_bounds, crop_rect)); | 161 buffer_, plane_z_order, plane_transform, display_bounds, crop_rect)); |
| 151 return true; | 162 return true; |
| 152 } | 163 } |
| 153 | 164 |
| 154 bool GbmPixmap::ShouldApplyScaling(const gfx::Rect& display_bounds, | 165 bool GbmPixmap::ShouldApplyScaling(const gfx::Rect& display_bounds, |
| 155 const gfx::RectF& crop_rect, | 166 const gfx::RectF& crop_rect, |
| 156 gfx::Size* required_size) { | 167 gfx::Size* required_size) { |
| 157 if (crop_rect.width() == 0 || crop_rect.height() == 0) { | 168 if (crop_rect.width() == 0 || crop_rect.height() == 0) { |
| 158 PLOG(ERROR) << "ShouldApplyScaling passed zero scaling target."; | 169 PLOG(ERROR) << "ShouldApplyScaling passed zero scaling target."; |
| 159 return false; | 170 return false; |
| 160 } | 171 } |
| 161 | 172 |
| 173 if (!buffer_) { | |
| 174 PLOG(ERROR) << "ShouldApplyScaling requires a buffer."; | |
| 175 return false; | |
| 176 } | |
| 177 | |
| 162 gfx::Size pixmap_size = buffer_->GetSize(); | 178 gfx::Size pixmap_size = buffer_->GetSize(); |
| 163 // If the required size is not integer-sized, round it to the next integer. | 179 // If the required size is not integer-sized, round it to the next integer. |
| 164 *required_size = gfx::ToCeiledSize( | 180 *required_size = gfx::ToCeiledSize( |
| 165 gfx::SizeF(display_bounds.width() / crop_rect.width(), | 181 gfx::SizeF(display_bounds.width() / crop_rect.width(), |
| 166 display_bounds.height() / crop_rect.height())); | 182 display_bounds.height() / crop_rect.height())); |
| 167 return pixmap_size != *required_size; | 183 return pixmap_size != *required_size; |
| 168 } | 184 } |
| 169 | 185 |
| 170 } // namespace ui | 186 } // namespace ui |
| OLD | NEW |