-
-
Save tiagovignatti/e9ca94f01a46ebb0e460 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
commit 47aee337cccf43f7018aa2d590c9a471cf6583f0 | |
Author: Tiago Vignatti <[email protected]> | |
Date: Fri Jul 24 20:50:30 2015 -0300 | |
WIP: Native GpuMemoryBUffer through Prime mmap only | |
no VGEM, no vendor dependent ioctls. Just dma-buf. | |
--- | |
.../chromeos/login/chrome_restart_request.cc | 1 + | |
content/browser/gpu/gpu_process_host.cc | 1 + | |
.../renderer_host/render_process_host_impl.cc | 1 + | |
.../drm/common/native_pixmap_manager_gbm.cc | 14 +- | |
ui/ozone/platform/drm/gbm.gypi | 2 + | |
ui/ozone/platform/drm/gpu/drm_pixmap.cc | 155 +++++++++++++++++++++ | |
ui/ozone/platform/drm/gpu/drm_pixmap.h | 61 ++++++++ | |
ui/ozone/platform/drm/gpu/gbm_buffer.cc | 4 +- | |
.../platform/drm/host/drm_display_host_manager.cc | 4 +- | |
ui/ozone/public/ozone_switches.cc | 3 + | |
ui/ozone/public/ozone_switches.h | 2 + | |
11 files changed, 244 insertions(+), 4 deletions(-) | |
diff --git a/chrome/browser/chromeos/login/chrome_restart_request.cc b/chrome/browser/chromeos/login/chrome_restart_request.cc | |
index b9445c6..4ea4e3d 100644 | |
--- a/chrome/browser/chromeos/login/chrome_restart_request.cc | |
+++ b/chrome/browser/chromeos/login/chrome_restart_request.cc | |
@@ -172,6 +172,7 @@ std::string DeriveCommandLine(const GURL& start_url, | |
::switches::kOzonePlatform, | |
::switches::kOzoneUseSurfaceless, | |
::switches::kOzoneUseIntelDrm, | |
+ ::switches::kOzoneUseDrm, | |
#endif | |
app_list::switches::kDisableSyncAppList, | |
app_list::switches::kEnableCenteredAppList, | |
diff --git a/content/browser/gpu/gpu_process_host.cc b/content/browser/gpu/gpu_process_host.cc | |
index 3874fc7..9da4335 100644 | |
--- a/content/browser/gpu/gpu_process_host.cc | |
+++ b/content/browser/gpu/gpu_process_host.cc | |
@@ -125,6 +125,7 @@ static const char* const kSwitchNames[] = { | |
switches::kOzonePlatform, | |
switches::kOzoneUseSurfaceless, | |
switches::kOzoneUseIntelDrm, | |
+ switches::kOzoneUseDrm, | |
#endif | |
#if defined(USE_X11) && !defined(OS_CHROMEOS) | |
switches::kX11Display, | |
diff --git a/content/browser/renderer_host/render_process_host_impl.cc b/content/browser/renderer_host/render_process_host_impl.cc | |
index db412f3..03934f1 100644 | |
--- a/content/browser/renderer_host/render_process_host_impl.cc | |
+++ b/content/browser/renderer_host/render_process_host_impl.cc | |
@@ -1401,6 +1401,7 @@ void RenderProcessHostImpl::PropagateBrowserCommandLineToRenderer( | |
#if defined(USE_OZONE) | |
switches::kOzonePlatform, | |
switches::kOzoneUseIntelDrm, | |
+ switches::kOzoneUseDrm, | |
#endif | |
#if defined(OS_CHROMEOS) | |
switches::kDisableVaapiAcceleratedVideoEncode, | |
diff --git a/ui/ozone/platform/drm/common/native_pixmap_manager_gbm.cc b/ui/ozone/platform/drm/common/native_pixmap_manager_gbm.cc | |
index 93a7f10..d1b9eaf 100644 | |
--- a/ui/ozone/platform/drm/common/native_pixmap_manager_gbm.cc | |
+++ b/ui/ozone/platform/drm/common/native_pixmap_manager_gbm.cc | |
@@ -9,6 +9,7 @@ | |
#include "base/command_line.h" | |
#include "ui/ozone/platform/drm/gpu/intel_drm_pixmap.h" | |
+#include "ui/ozone/platform/drm/gpu/drm_pixmap.h" | |
#include "ui/ozone/public/ozone_switches.h" | |
namespace ui { | |
@@ -66,10 +67,21 @@ scoped_refptr<NativePixmap> NativePixmapManagerGbm::CreateFromFileDescriptor( | |
SurfaceFactoryOzone::BufferUsage usage) { | |
bool enable_intel_drm = base::CommandLine::ForCurrentProcess()->HasSwitch( | |
switches::kOzoneUseIntelDrm); | |
+ bool enable_drm = base::CommandLine::ForCurrentProcess()->HasSwitch( | |
+ switches::kOzoneUseDrm); | |
+ | |
if (enable_intel_drm && usage == SurfaceFactoryOzone::MAP) { | |
return IntelDrmPixmap::CreateFromHandle( | |
base::FileDescriptor(vgem_fd_.get(), false), handle, format, size); | |
- } | |
+ } else if (enable_drm && usage == SurfaceFactoryOzone::MAP) { | |
+ scoped_refptr<DrmPixmap> pixmap(new DrmPixmap( | |
+ handle, base::FileDescriptor(vgem_fd_.get(), false), size, format, | |
+ NativePixmapBufferUsageFromSurfaceFactoryOzone(usage))); | |
+ if (!pixmap->Initialize()) | |
+ return nullptr; | |
+ | |
+ return pixmap; | |
+ } | |
scoped_refptr<VgemPixmap> pixmap(new VgemPixmap( | |
handle, base::FileDescriptor(vgem_fd_.get(), false), size, format, | |
diff --git a/ui/ozone/platform/drm/gbm.gypi b/ui/ozone/platform/drm/gbm.gypi | |
index a5933ee..19a2723 100644 | |
--- a/ui/ozone/platform/drm/gbm.gypi | |
+++ b/ui/ozone/platform/drm/gbm.gypi | |
@@ -48,6 +48,8 @@ | |
'gpu/gbm_surface_factory.h', | |
'gpu/gbm_surfaceless.cc', | |
'gpu/gbm_surfaceless.h', | |
+ 'gpu/drm_pixmap.cc', | |
+ 'gpu/drm_pixmap.h', | |
'gpu/intel_drm_pixmap.cc', | |
'gpu/intel_drm_pixmap.h', | |
'gpu/vgem_pixmap.cc', | |
diff --git a/ui/ozone/platform/drm/gpu/drm_pixmap.cc b/ui/ozone/platform/drm/gpu/drm_pixmap.cc | |
new file mode 100644 | |
index 0000000..3344c9b | |
--- /dev/null | |
+++ b/ui/ozone/platform/drm/gpu/drm_pixmap.cc | |
@@ -0,0 +1,155 @@ | |
+// Copyright 2015 The Chromium Authors. All rights reserved. | |
+// Use of this source code is governed by a BSD-style license that can be | |
+// found in the LICENSE file. | |
+ | |
+#include "ui/ozone/platform/drm/gpu/drm_pixmap.h" | |
+ | |
+#include <fcntl.h> | |
+#include <sys/mman.h> | |
+#include <xf86drm.h> | |
+ | |
+#include "base/trace_event/trace_event.h" | |
+#include "ui/ozone/public/surface_factory_ozone.h" | |
+ | |
+namespace ui { | |
+ | |
+namespace { | |
+ | |
+size_t StrideInBytes(size_t width, SurfaceFactoryOzone::BufferFormat format) { | |
+ switch (format) { | |
+ case SurfaceFactoryOzone::BGRA_8888: | |
+ case SurfaceFactoryOzone::RGBX_8888: | |
+ return width * 4; | |
+ case SurfaceFactoryOzone::UNKNOWN: | |
+ NOTREACHED(); | |
+ } | |
+ NOTREACHED(); | |
+ return 0; | |
+} | |
+ | |
+} // namespace | |
+ | |
+DrmPixmap::DrmPixmap(base::FileDescriptor handle, | |
+ base::FileDescriptor bo_handle, | |
+ gfx::Size size, | |
+ SurfaceFactoryOzone::BufferFormat format, | |
+ BufferUsage usage) | |
+ : bo_handle_(0), | |
+ fd_(bo_handle), | |
+ size_(size), | |
+ format_(format), | |
+ usage_(usage), | |
+ stride_(StrideInBytes(size_.width(), format_)), | |
+ mmap_ptr_(nullptr) { | |
+ if (usage_ == MAP) { | |
+ CHECK(fd_.fd > 0); | |
+ CHECK(handle.fd > 0); | |
+ dma_buf_.reset(handle.fd); | |
+ } | |
+} | |
+ | |
+bool DrmPixmap::Initialize() { | |
+ if (usage_ == SCANOUT) | |
+ return true; | |
+ | |
+ DCHECK(fd_.fd); | |
+ int ret = drmPrimeFDToHandle(fd_.fd, dma_buf_.get(), &bo_handle_); | |
+ if (ret) { | |
+ LOG(ERROR) << "drmPrimeFDToHandle failed, handle:" << bo_handle_; | |
+ return false; | |
+ } | |
+ return true; | |
+} | |
+ | |
+DrmPixmap::~DrmPixmap() { | |
+ if (bo_handle_) { | |
+ DCHECK_EQ(usage_, MAP); | |
+ struct drm_mode_destroy_dumb destroy; | |
+ memset(&destroy, 0, sizeof(destroy)); | |
+ destroy.handle = bo_handle_; | |
+ int ret = drmIoctl(fd_.fd, DRM_IOCTL_MODE_DESTROY_DUMB, &destroy); | |
+ if (!ret) | |
+ LOG(ERROR) << "fail to free drm buffer. error:" << ret; | |
+ bo_handle_ = 0; | |
+ } | |
+} | |
+ | |
+void* DrmPixmap::GetEGLClientBuffer() { | |
+ return nullptr; | |
+} | |
+ | |
+int DrmPixmap::GetDmaBufFd() { | |
+ return dma_buf_.get(); | |
+} | |
+ | |
+int DrmPixmap::GetDmaBufPitch() { | |
+ return stride_; | |
+} | |
+ | |
+bool DrmPixmap::ScheduleOverlayPlane(gfx::AcceleratedWidget widget, | |
+ int plane_z_order, | |
+ gfx::OverlayTransform plane_transform, | |
+ const gfx::Rect& display_bounds, | |
+ const gfx::RectF& crop_rect) { | |
+ // DrmPixmap is used in Browser and Renderer, so this feature is not | |
+ // needed. | |
+ NOTREACHED(); | |
+ return false; | |
+} | |
+ | |
+void DrmPixmap::SetScalingCallback( | |
+ const ScalingCallback& scaling_callback) { | |
+ // DrmPixmap is used in Browser and Renderer, so this feature is not | |
+ // needed. | |
+ NOTREACHED(); | |
+} | |
+ | |
+scoped_refptr<NativePixmap> DrmPixmap::GetScaledPixmap( | |
+ gfx::Size new_size) { | |
+ // DrmPixmap is used in Browser and Renderer, so this feature is not | |
+ // needed. | |
+ NOTREACHED(); | |
+ return nullptr; | |
+} | |
+ | |
+NativePixmap::BufferUsage DrmPixmap::GetBufferUsage() const { | |
+ return MAP; | |
+} | |
+ | |
+void* DrmPixmap::Map() { | |
+ TRACE_EVENT0("gpu", "DrmPixmap::Map"); | |
+ DCHECK(!mmap_ptr_); | |
+ DCHECK(bo_handle_); | |
+ DCHECK_EQ(usage_, MAP); | |
+ | |
+ // TODO(vignatti): the following snip might not be needed. | |
+ struct drm_mode_map_dumb mmap_arg; | |
+ memset(&mmap_arg, 0, sizeof(mmap_arg)); | |
+ mmap_arg.handle = bo_handle_; | |
+ | |
+ int ret = drmIoctl(fd_.fd, DRM_IOCTL_MODE_MAP_DUMB, &mmap_arg); | |
+ if (ret) { | |
+ LOG(ERROR) << "fail to map a vgem buffer. error:" << ret; | |
+ return nullptr; | |
+ } | |
+ DCHECK(mmap_arg.offset); | |
+ | |
+ size_t size = stride_ * size_.height(); | |
+ mmap_ptr_ = mmap(nullptr, size, (PROT_READ | PROT_WRITE), MAP_SHARED, | |
+ fd_.fd, mmap_arg.offset); | |
+ DCHECK(mmap_ptr_ != MAP_FAILED); | |
+ return mmap_ptr_; | |
+} | |
+ | |
+void DrmPixmap::Unmap() { | |
+ TRACE_EVENT0("gpu", "DrmPixmap::Unmap"); | |
+ DCHECK(mmap_ptr_); | |
+ DCHECK(bo_handle_); | |
+ | |
+ size_t size = stride_ * size_.height(); | |
+ int ret = munmap(mmap_ptr_, size); | |
+ DCHECK(!ret); | |
+ mmap_ptr_ = nullptr; | |
+} | |
+ | |
+} // namespace ui | |
diff --git a/ui/ozone/platform/drm/gpu/drm_pixmap.h b/ui/ozone/platform/drm/gpu/drm_pixmap.h | |
new file mode 100644 | |
index 0000000..719ba4c | |
--- /dev/null | |
+++ b/ui/ozone/platform/drm/gpu/drm_pixmap.h | |
@@ -0,0 +1,61 @@ | |
+// Copyright 2015 The Chromium Authors. All rights reserved. | |
+// Use of this source code is governed by a BSD-style license that can be | |
+// found in the LICENSE file. | |
+ | |
+#ifndef UI_OZONE_PLATFORM_DRM_GPU_DRM_PIXMAP_H_ | |
+#define UI_OZONE_PLATFORM_DRM_GPU_DRM_PIXMAP_H_ | |
+ | |
+#include "base/macros.h" | |
+#include "base/memory/scoped_ptr.h" | |
+#include "ui/gfx/geometry/size.h" | |
+#include "ui/ozone/public/native_pixmap.h" | |
+#include "ui/ozone/public/surface_factory_ozone.h" | |
+ | |
+typedef struct _drm_bo drm_bo; | |
+ | |
+namespace ui { | |
+ | |
+class DrmPixmap : public NativePixmap { | |
+ public: | |
+ DrmPixmap(base::FileDescriptor handle, | |
+ base::FileDescriptor bo_handle, | |
+ gfx::Size size, | |
+ SurfaceFactoryOzone::BufferFormat format, | |
+ BufferUsage usage); | |
+ bool Initialize(); | |
+ | |
+ // NativePixmap: | |
+ void* GetEGLClientBuffer() override; | |
+ int GetDmaBufFd() override; | |
+ int GetDmaBufPitch() override; | |
+ | |
+ bool ScheduleOverlayPlane(gfx::AcceleratedWidget widget, | |
+ int plane_z_order, | |
+ gfx::OverlayTransform plane_transform, | |
+ const gfx::Rect& display_bounds, | |
+ const gfx::RectF& crop_rect) override; | |
+ void SetScalingCallback(const ScalingCallback& scaling_callback) override; | |
+ scoped_refptr<NativePixmap> GetScaledPixmap(gfx::Size new_size) override; | |
+ BufferUsage GetBufferUsage() const override; | |
+ void* Map() override; | |
+ void Unmap() override; | |
+ | |
+ protected: | |
+ ~DrmPixmap() override; | |
+ | |
+ private: | |
+ uint32_t bo_handle_; | |
+ base::ScopedFD dma_buf_; | |
+ base::FileDescriptor fd_; | |
+ gfx::Size size_; | |
+ SurfaceFactoryOzone::BufferFormat format_; | |
+ BufferUsage usage_; | |
+ size_t stride_; | |
+ void* mmap_ptr_; | |
+ | |
+ DISALLOW_COPY_AND_ASSIGN(DrmPixmap); | |
+}; | |
+ | |
+} // namespace ui | |
+ | |
+#endif // UI_OZONE_PLATFORM_DRM_GPU_DRM_PIXMAP_H_ | |
diff --git a/ui/ozone/platform/drm/gpu/gbm_buffer.cc b/ui/ozone/platform/drm/gpu/gbm_buffer.cc | |
index 9f4d63d..e7e83e1 100644 | |
--- a/ui/ozone/platform/drm/gpu/gbm_buffer.cc | |
+++ b/ui/ozone/platform/drm/gpu/gbm_buffer.cc | |
@@ -52,10 +52,10 @@ scoped_refptr<GbmBuffer> GbmBuffer::CreateBuffer( | |
bool scanout) { | |
TRACE_EVENT2("drm", "GbmBuffer::CreateBuffer", "device", | |
gbm->device_path().value(), "size", size.ToString()); | |
- unsigned flags = GBM_BO_USE_RENDERING; | |
+ unsigned flags = 0; | |
// GBM_BO_USE_SCANOUT is the hint of x-tiling. | |
if (scanout) | |
- flags |= GBM_BO_USE_SCANOUT; | |
+ flags |= GBM_BO_USE_SCANOUT | GBM_BO_USE_RENDERING; | |
gbm_bo* bo = gbm_bo_create(gbm->device(), size.width(), size.height(), | |
GetGbmFormatFromBufferFormat(format), flags); | |
if (!bo) | |
diff --git a/ui/ozone/platform/drm/host/drm_display_host_manager.cc b/ui/ozone/platform/drm/host/drm_display_host_manager.cc | |
index fff3c59..1e0ca25 100644 | |
--- a/ui/ozone/platform/drm/host/drm_display_host_manager.cc | |
+++ b/ui/ozone/platform/drm/host/drm_display_host_manager.cc | |
@@ -169,7 +169,9 @@ base::FileDescriptor DrmDisplayHostManager::DupVgemFd() { | |
bool enable_intel_drm = base::CommandLine::ForCurrentProcess()->HasSwitch( | |
switches::kOzoneUseIntelDrm); | |
- if (enable_intel_drm) { | |
+ bool enable_drm = base::CommandLine::ForCurrentProcess()->HasSwitch( | |
+ switches::kOzoneUseDrm); | |
+ if (enable_intel_drm || enable_drm) { | |
device_fd = primary_drm_device_file_.get(); | |
device_path = &primary_graphics_card_path_; | |
} | |
diff --git a/ui/ozone/public/ozone_switches.cc b/ui/ozone/public/ozone_switches.cc | |
index ab45746..e2a1916 100644 | |
--- a/ui/ozone/public/ozone_switches.cc | |
+++ b/ui/ozone/public/ozone_switches.cc | |
@@ -19,6 +19,9 @@ const char kOzoneUseSurfaceless[] = "ozone-use-surfaceless"; | |
// Use Intel DRM for native GPU memory buffers. | |
const char kOzoneUseIntelDrm[] = "ozone-use-intel-drm"; | |
+// Use DRM for native GPU memory buffers. | |
+const char kOzoneUseDrm[] = "ozone-use-drm"; | |
+ | |
// Enable support for a single overlay plane. | |
const char kOzoneTestSingleOverlaySupport[] = | |
"ozone-test-single-overlay-support"; | |
diff --git a/ui/ozone/public/ozone_switches.h b/ui/ozone/public/ozone_switches.h | |
index 10e7235..930b17f 100644 | |
--- a/ui/ozone/public/ozone_switches.h | |
+++ b/ui/ozone/public/ozone_switches.h | |
@@ -18,6 +18,8 @@ OZONE_EXPORT extern const char kOzoneUseSurfaceless[]; | |
OZONE_EXPORT extern const char kOzoneUseIntelDrm[]; | |
+OZONE_EXPORT extern const char kOzoneUseDrm[]; | |
+ | |
OZONE_EXPORT extern const char kOzoneTestSingleOverlaySupport[]; | |
OZONE_EXPORT extern const char kOzoneInitialDisplayBounds[]; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment