Index: ui/ozone/platform/drm/gbm_surface_factory.cc |
diff --git a/ui/ozone/platform/drm/gbm_surface_factory.cc b/ui/ozone/platform/drm/gbm_surface_factory.cc |
index afe8d2cb6644f929ee2bda09965fbf291c5e95f6..c4150aab587c5ba541101948d4f36160f1b1b30e 100644 |
--- a/ui/ozone/platform/drm/gbm_surface_factory.cc |
+++ b/ui/ozone/platform/drm/gbm_surface_factory.cc |
@@ -8,6 +8,7 @@ |
#include "base/command_line.h" |
#include "base/files/file_path.h" |
+#include "base/posix/eintr_wrapper.h" |
#include "third_party/khronos/EGL/egl.h" |
#include "ui/gfx/geometry/rect_conversions.h" |
#include "ui/ozone/common/egl_util.h" |
@@ -71,10 +72,24 @@ class SingleOverlay : public OverlayCandidatesOzone { |
DISALLOW_COPY_AND_ASSIGN(SingleOverlay); |
}; |
+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; |
+} |
+ |
} // namespace |
GbmSurfaceFactory::GbmSurfaceFactory(bool allow_surfaceless) |
- : DrmSurfaceFactory(NULL), allow_surfaceless_(allow_surfaceless) { |
+ : DrmSurfaceFactory(NULL), |
+ allow_surfaceless_(allow_surfaceless), |
+ drm_device_manager_(nullptr) { |
} |
GbmSurfaceFactory::~GbmSurfaceFactory() { |
@@ -151,14 +166,11 @@ scoped_refptr<ui::NativePixmap> GbmSurfaceFactory::CreateNativePixmap( |
gfx::Size size, |
BufferFormat format, |
BufferUsage usage) { |
- if (usage == MAP) |
- return nullptr; |
- |
scoped_refptr<GbmDevice> gbm = GetGbmDevice(widget); |
DCHECK(gbm); |
scoped_refptr<GbmBuffer> buffer = |
- GbmBuffer::CreateBuffer(gbm, format, size, true); |
+ GbmBuffer::CreateBuffer(gbm, format, size, usage == SCANOUT); |
if (!buffer.get()) |
return nullptr; |
@@ -169,6 +181,38 @@ scoped_refptr<ui::NativePixmap> GbmSurfaceFactory::CreateNativePixmap( |
return pixmap; |
} |
+gfx::GpuMemoryBufferHandle GbmSurfaceFactory::ExportGpuMemoryBufferHandle( |
+ gfx::AcceleratedWidget widget, |
+ scoped_refptr<NativePixmap> pixmap) { |
+ scoped_refptr<GbmDevice> gbm = GetGbmDevice(widget); |
+ DCHECK(gbm); |
+ |
+ base::FileDescriptor dup_handle; |
+ if (!ShareToRenderProcess(pixmap->GetDmaBufFd(), &dup_handle)) { |
+ DLOG(ERROR) << "Fail to duplicate a DMA-BUF file descriptor"; |
+ return gfx::GpuMemoryBufferHandle(); |
+ } |
+ |
+ int vgem_fd = drm_device_manager_->GetVgemDevice()->get_fd(); |
+ if (vgem_fd < 0) { |
+ LOG(ERROR) << "This device doesn't support VGEM."; |
+ return gfx::GpuMemoryBufferHandle(); |
+ } |
+ |
+ base::FileDescriptor dup_device_handle; |
+ if (!ShareToRenderProcess(vgem_fd, &dup_device_handle)) { |
+ base::ScopedFD fd(dup_handle.fd); |
+ LOG(ERROR) << "Fail to duplicate a VGEM file descriptor"; |
+ return gfx::GpuMemoryBufferHandle(); |
+ } |
+ |
+ gfx::GpuMemoryBufferHandle handle; |
+ handle.type = gfx::OZONE_NATIVE_BUFFER; |
+ handle.handle = dup_handle; |
+ handle.device_handle = dup_device_handle; |
+ return handle; |
+} |
+ |
OverlayCandidatesOzone* GbmSurfaceFactory::GetOverlayCandidates( |
gfx::AcceleratedWidget w) { |
if (base::CommandLine::ForCurrentProcess()->HasSwitch( |
@@ -199,15 +243,18 @@ bool GbmSurfaceFactory::CanShowPrimaryPlaneAsOverlay() { |
return allow_surfaceless_; |
} |
-bool GbmSurfaceFactory::CanCreateNativePixmap(BufferUsage usage) { |
- switch (usage) { |
- case MAP: |
- return false; |
- case SCANOUT: |
- return true; |
- } |
- NOTREACHED(); |
- return false; |
+std::vector<SurfaceFactoryOzone::Configuration> |
+GbmSurfaceFactory::GetSupportedNativePixmapConfigurations() const { |
+ std::vector<Configuration> configurations; |
+ configurations.push_back( |
+ {SurfaceFactoryOzone::BGRA_8888, SurfaceFactoryOzone::SCANOUT}); |
+ configurations.push_back( |
+ {SurfaceFactoryOzone::RGBX_8888, SurfaceFactoryOzone::SCANOUT}); |
+ // MAP is supported on the device, which supports VGEM. |
+ if (drm_device_manager_ && drm_device_manager_->GetVgemDevice()) |
+ configurations.push_back( |
+ {SurfaceFactoryOzone::BGRA_8888, SurfaceFactoryOzone::MAP}); |
+ return configurations; |
} |
scoped_refptr<GbmDevice> GbmSurfaceFactory::GetGbmDevice( |