Index: content/common/gpu/client/gpu_memory_buffer_impl_ozone_gbm_intel.cc |
diff --git a/content/common/gpu/client/gpu_memory_buffer_impl_ozone_gbm_intel.cc b/content/common/gpu/client/gpu_memory_buffer_impl_ozone_gbm_intel.cc |
new file mode 100644 |
index 0000000000000000000000000000000000000000..db2b3ad691389e6eaa616f4d90c4533b5668a52c |
--- /dev/null |
+++ b/content/common/gpu/client/gpu_memory_buffer_impl_ozone_gbm_intel.cc |
@@ -0,0 +1,117 @@ |
+// 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 "content/common/gpu/client/gpu_memory_buffer_impl_ozone_gbm_intel.h" |
+ |
+#include <libdrm/i915_drm.h> |
+ |
+#include "base/lazy_instance.h" |
+#include "base/threading/thread_local.h" |
+#include "base/trace_event/trace_event.h" |
+#include "ui/ozone/public/platform/drm_intel_buffer_manager.h" |
+ |
+namespace content { |
+ |
+namespace { |
+ |
+// --single-process launches a render thread instead of a render process. |
+base::LazyInstance<base::ThreadLocalPointer<ui::DrmIntelBufferManager>>::Leaky |
+ g_buffer_manager = LAZY_INSTANCE_INITIALIZER; |
+ |
+} // namespace |
+ |
+GpuMemoryBufferImplOzoneGbmIntel::GpuMemoryBufferImplOzoneGbmIntel( |
+ gfx::GpuMemoryBufferId id, |
+ const gfx::Size& size, |
+ Format format, |
+ const DestructionCallback& callback) |
+ : GpuMemoryBufferImplOzoneNativeBuffer(id, size, format, callback), |
+ buffer_(nullptr), |
+ stride_(0) { |
+} |
+ |
+GpuMemoryBufferImplOzoneGbmIntel::~GpuMemoryBufferImplOzoneGbmIntel() { |
+ if (buffer_) { |
+ drm_intel_bo_unreference(buffer_); |
+ buffer_ = nullptr; |
+ } |
+} |
+ |
+// static |
+scoped_ptr<GpuMemoryBufferImpl> |
+GpuMemoryBufferImplOzoneGbmIntel::CreateFromHandle( |
+ const gfx::GpuMemoryBufferHandle& handle, |
+ const gfx::Size& size, |
+ Format format, |
+ const DestructionCallback& callback) { |
+ scoped_ptr<GpuMemoryBufferImplOzoneGbmIntel> buffer = make_scoped_ptr( |
+ new GpuMemoryBufferImplOzoneGbmIntel(handle.id, size, format, callback)); |
+ if (!buffer->Initialize(handle)) |
+ return nullptr; |
+ return buffer.Pass(); |
+} |
+ |
+bool GpuMemoryBufferImplOzoneGbmIntel::Initialize( |
+ const gfx::GpuMemoryBufferHandle& handle) { |
+ // Render process must close |device_handle|. |
+ DCHECK(handle.device_handle.auto_close); |
+ if (!g_buffer_manager.Pointer()->Get()) { |
+ g_buffer_manager.Pointer()->Set(new ui::DrmIntelBufferManager); |
+ g_buffer_manager.Pointer()->Get()->Initialize(handle.device_handle); |
+ } else { |
+ // TODO(dshwang): dup this fd once per render process. |
+ base::ScopedFD closing_fd(handle.device_handle.fd); |
+ } |
+ DCHECK(g_buffer_manager.Pointer()->Get()->buffer_manager()); |
+ |
+ stride_ = handle.stride; |
+ int buffer_size = stride_ * size_.height(); |
+ buffer_ = drm_intel_bo_gem_create_from_prime( |
+ g_buffer_manager.Pointer()->Get()->buffer_manager(), handle.handle.fd, |
+ buffer_size); |
+ if (!buffer_) { |
+ DLOG(ERROR) << "drm_intel_bo_gem_create_from_prime failed."; |
+ return false; |
+ } |
+ DCHECK(handle.handle.auto_close); |
+ prime_fd_.reset(handle.handle.fd); |
+ return true; |
+} |
+ |
+bool GpuMemoryBufferImplOzoneGbmIntel::Map(void** data) { |
+ TRACE_EVENT0("gpu", "GpuMemoryBufferImplOzoneGbmIntel::Map"); |
+ DCHECK(!mapped_); |
+ mapped_ = true; |
+ int write_enable = 1; |
+ DCHECK(buffer_); |
+ int error = drm_intel_bo_map(buffer_, write_enable); |
+ if (error) { |
+ DLOG(ERROR) << "fail to map a drm buffer. error:" << error; |
+ return false; |
+ } |
+ DCHECK(buffer_->virt); |
+ *data = buffer_->virt; |
+ return true; |
+} |
+ |
+void GpuMemoryBufferImplOzoneGbmIntel::Unmap() { |
+ TRACE_EVENT0("gpu", "GpuMemoryBufferImplOzoneGbmIntel::Unmap"); |
+ DCHECK(mapped_); |
+ int error = drm_intel_bo_unmap(buffer_); |
+ DCHECK(!error) << error; |
+ mapped_ = false; |
+} |
+ |
+void GpuMemoryBufferImplOzoneGbmIntel::GetStride(uint32* stride) const { |
+ *stride = stride_; |
+} |
+ |
+gfx::GpuMemoryBufferHandle GpuMemoryBufferImplOzoneGbmIntel::GetHandle() const { |
+ // Don't need to set |handle.handle| and |handle.device_handle| because gpu |
+ // process can look up the right pixmap only by id. |
+ // See ui::GpuMemoryBufferFactoryOzoneNativeBuffer |
+ return GpuMemoryBufferImplOzoneNativeBuffer::GetHandle(); |
+} |
+ |
+} // namespace content |