| Index: ui/ozone/platform/drm/gpu/gbm_buffer.cc
|
| diff --git a/ui/ozone/platform/drm/gpu/gbm_buffer.cc b/ui/ozone/platform/drm/gpu/gbm_buffer.cc
|
| index 362f77c8dd6566ca08c6b26fea9341c950f3e8ff..77e05a80f3dd477f379fc4c9aea7a03fa9741b5f 100644
|
| --- a/ui/ozone/platform/drm/gpu/gbm_buffer.cc
|
| +++ b/ui/ozone/platform/drm/gpu/gbm_buffer.cc
|
| @@ -10,7 +10,9 @@
|
| #include <xf86drm.h>
|
|
|
| #include "base/logging.h"
|
| +#include "base/posix/eintr_wrapper.h"
|
| #include "base/trace_event/trace_event.h"
|
| +#include "ui/gfx/gpu_memory_buffer.h"
|
| #include "ui/ozone/platform/drm/gpu/gbm_device.h"
|
|
|
| namespace ui {
|
| @@ -29,6 +31,23 @@ int GetGbmFormatFromBufferFormat(SurfaceFactoryOzone::BufferFormat fmt) {
|
| }
|
| }
|
|
|
| +bool ShareToRenderProcess(int fd, base::FileDescriptor* new_handle) {
|
| + int duped_handle = HANDLE_EINTR(dup(fd));
|
| + if (duped_handle < 0) {
|
| + DPLOG(ERROR) << "dup() failed.";
|
| + *new_handle = base::FileDescriptor();
|
| + return false;
|
| + }
|
| +
|
| + *new_handle = base::FileDescriptor(duped_handle, true);
|
| + return true;
|
| +}
|
| +
|
| +unsigned long StrideInBytes(int width) {
|
| + // Both BGRA_8888 and RGBX_8888 has 4 byte per pixel.
|
| + return width * 4;
|
| +}
|
| +
|
| } // namespace
|
|
|
| GbmBuffer::GbmBuffer(const scoped_refptr<GbmDevice>& gbm,
|
| @@ -51,8 +70,9 @@ scoped_refptr<GbmBuffer> GbmBuffer::CreateBuffer(
|
| TRACE_EVENT2("drm", "GbmBuffer::CreateBuffer", "device",
|
| gbm->device_path().value(), "size", size.ToString());
|
| unsigned flags = GBM_BO_USE_RENDERING;
|
| - if (scanout)
|
| - flags |= GBM_BO_USE_SCANOUT;
|
| + // SCANOUT allocates continuous memory, so better for performance even if
|
| + // |scanout| is false.
|
| + flags |= GBM_BO_USE_SCANOUT;
|
| gbm_bo* bo = gbm_bo_create(gbm->device(), size.width(), size.height(),
|
| GetGbmFormatFromBufferFormat(format), flags);
|
| if (!bo)
|
| @@ -86,6 +106,34 @@ GbmPixmap::~GbmPixmap() {
|
| close(dma_buf_);
|
| }
|
|
|
| +bool GbmPixmap::ExportDmaBuf(int vgem_fd, gfx::GpuMemoryBufferHandle* handle) {
|
| + DCHECK(StrideInBytes(buffer_->GetSize().width()) ==
|
| + gbm_bo_get_stride(buffer_->bo()));
|
| +
|
| + base::FileDescriptor dup_handle;
|
| + if (!ShareToRenderProcess(dma_buf_, &dup_handle)) {
|
| + DLOG(ERROR) << "Fail to duplicate a DMA-BUF file descriptor";
|
| + return false;
|
| + }
|
| +
|
| + if (vgem_fd < 0) {
|
| + LOG(ERROR) << "This device doesn't support vGEM.";
|
| + return false;
|
| + }
|
| +
|
| + base::FileDescriptor dup_device_handle;
|
| + if (!ShareToRenderProcess(vgem_fd, &dup_device_handle)) {
|
| + base::ScopedFD fd(dup_handle.fd);
|
| + DLOG(ERROR) << "Fail to duplicate a DRM file descriptor";
|
| + return false;
|
| + }
|
| +
|
| + handle->handle = dup_handle;
|
| + // TODO(dshwang): pass |device_handle| only one time for each render process.
|
| + handle->device_handle = dup_device_handle;
|
| + return true;
|
| +}
|
| +
|
| void* GbmPixmap::GetEGLClientBuffer() {
|
| return nullptr;
|
| }
|
| @@ -98,4 +146,8 @@ int GbmPixmap::GetDmaBufPitch() {
|
| return gbm_bo_get_stride(buffer_->bo());
|
| }
|
|
|
| +NativePixmap::BufferUsage GbmPixmap::GetBufferUsage() const {
|
| + return buffer_->GetFramebufferId() ? SCANOUT : MAP;
|
| +}
|
| +
|
| } // namespace ui
|
|
|