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 "content/common/gpu/client/gpu_memory_buffer_impl_ozone_native_buffer.h " | 5 #include "content/common/gpu/client/gpu_memory_buffer_impl_ozone_native_buffer.h " |
6 | 6 |
7 #include <fcntl.h> | |
8 #include <sys/mman.h> | |
9 #include <xf86drm.h> | |
10 | |
11 #include "base/trace_event/trace_event.h" | |
7 #include "ui/ozone/public/surface_factory_ozone.h" | 12 #include "ui/ozone/public/surface_factory_ozone.h" |
8 | 13 |
9 namespace content { | 14 namespace content { |
10 | 15 |
11 GpuMemoryBufferImplOzoneNativeBuffer::GpuMemoryBufferImplOzoneNativeBuffer( | 16 GpuMemoryBufferImplOzoneNativeBuffer::GpuMemoryBufferImplOzoneNativeBuffer( |
12 gfx::GpuMemoryBufferId id, | 17 gfx::GpuMemoryBufferId id, |
13 const gfx::Size& size, | 18 const gfx::Size& size, |
14 Format format, | 19 Format format, |
15 const DestructionCallback& callback) | 20 const DestructionCallback& callback) |
16 : GpuMemoryBufferImpl(id, size, format, callback) { | 21 : GpuMemoryBufferImpl(id, size, format, callback), |
22 vgem_bo_handle_(0), | |
23 stride_(0), | |
24 mmap_ptr_(nullptr) { | |
25 RowSizeInBytes(size_.width(), format_, 0, &stride_); | |
17 } | 26 } |
18 | 27 |
19 GpuMemoryBufferImplOzoneNativeBuffer::~GpuMemoryBufferImplOzoneNativeBuffer() { | 28 GpuMemoryBufferImplOzoneNativeBuffer::~GpuMemoryBufferImplOzoneNativeBuffer() { |
29 if (vgem_bo_handle_) { | |
30 // TODO(dshwang): Both causes CRASH. How to release a handle? | |
dshwang
2015/05/14 12:25:47
zachr, could you advice how to release vgem bo han
| |
31 if (false) { | |
32 struct drm_mode_destroy_dumb destroy; | |
33 memset(&destroy, 0, sizeof(destroy)); | |
34 destroy.handle = vgem_bo_handle_; | |
35 int ret = drmIoctl(vgem_fd_.get(), DRM_IOCTL_MODE_DESTROY_DUMB, &destroy); | |
36 if (!ret) | |
37 LOG(ERROR) << "fail to free a vgem buffer. error:" << ret; | |
38 } | |
39 if (false) { | |
40 struct drm_gem_close close; | |
41 memset(&close, 0, sizeof(close)); | |
42 close.handle = vgem_bo_handle_; | |
43 int ret = drmIoctl(vgem_fd_.get(), DRM_IOCTL_GEM_CLOSE, &close); | |
44 if (!ret) | |
45 LOG(ERROR) << "fail to free a vgem buffer. error:" << ret; | |
46 } | |
47 vgem_bo_handle_ = 0; | |
48 } | |
20 } | 49 } |
21 | 50 |
22 // static | 51 // static |
23 scoped_ptr<GpuMemoryBufferImpl> | 52 scoped_ptr<GpuMemoryBufferImpl> |
24 GpuMemoryBufferImplOzoneNativeBuffer::CreateFromHandle( | 53 GpuMemoryBufferImplOzoneNativeBuffer::CreateFromHandle( |
25 const gfx::GpuMemoryBufferHandle& handle, | 54 const gfx::GpuMemoryBufferHandle& handle, |
26 const gfx::Size& size, | 55 const gfx::Size& size, |
27 Format format, | 56 Format format, |
28 const DestructionCallback& callback) { | 57 const DestructionCallback& callback) { |
29 return make_scoped_ptr<GpuMemoryBufferImpl>( | 58 scoped_ptr<GpuMemoryBufferImplOzoneNativeBuffer> buffer = |
30 new GpuMemoryBufferImplOzoneNativeBuffer( | 59 make_scoped_ptr(new GpuMemoryBufferImplOzoneNativeBuffer( |
31 handle.id, size, format, callback)); | 60 handle.id, size, format, callback)); |
61 | |
62 if (!buffer->Initialize(handle)) | |
63 return nullptr; | |
64 return buffer.Pass(); | |
65 } | |
66 | |
67 bool GpuMemoryBufferImplOzoneNativeBuffer::Initialize( | |
68 const gfx::GpuMemoryBufferHandle& handle) { | |
69 // If |fd| is -1, it's SCANOUT buffer. | |
70 if (handle.device_handle.fd == -1) { | |
71 DCHECK_EQ(handle.device_handle.fd, -1); | |
72 return true; | |
73 } | |
74 | |
75 DCHECK(handle.device_handle.auto_close); | |
76 DCHECK(handle.device_handle.fd); | |
77 vgem_fd_.reset(handle.device_handle.fd); | |
78 | |
79 DCHECK(handle.handle.auto_close); | |
80 dma_buf_.reset(handle.handle.fd); | |
81 | |
82 int ret = | |
83 drmPrimeFDToHandle(vgem_fd_.get(), dma_buf_.get(), &vgem_bo_handle_); | |
84 if (ret) { | |
85 LOG(ERROR) << "drmPrimeFDToHandle failed, handle:" << vgem_bo_handle_; | |
86 return false; | |
87 } | |
88 return true; | |
32 } | 89 } |
33 | 90 |
34 bool GpuMemoryBufferImplOzoneNativeBuffer::Map(void** data) { | 91 bool GpuMemoryBufferImplOzoneNativeBuffer::Map(void** data) { |
35 NOTREACHED(); | 92 TRACE_EVENT0("gpu", "GpuMemoryBufferImplOzoneNativeBuffer::Map"); |
36 return false; | 93 DCHECK(!mapped_); |
94 DCHECK(!mmap_ptr_); | |
95 if (!vgem_bo_handle_) { | |
96 LOG(ERROR) << "Map is called for SCANOUT buffer."; | |
97 return false; | |
98 } | |
99 | |
100 struct drm_mode_map_dumb mmap_arg; | |
101 memset(&mmap_arg, 0, sizeof(mmap_arg)); | |
102 mmap_arg.handle = vgem_bo_handle_; | |
103 | |
104 int ret = drmIoctl(vgem_fd_.get(), DRM_IOCTL_MODE_MAP_DUMB, &mmap_arg); | |
105 if (ret) { | |
106 LOG(ERROR) << "fail to map a vgem buffer. error:" << ret; | |
107 return false; | |
108 } | |
109 DCHECK(mmap_arg.offset); | |
110 | |
111 size_t size = stride_ * size_.height(); | |
112 mmap_ptr_ = mmap(nullptr, size, (PROT_READ | PROT_WRITE), MAP_SHARED, | |
113 vgem_fd_.get(), mmap_arg.offset); | |
114 DCHECK(mmap_ptr_ != MAP_FAILED); | |
115 mapped_ = true; | |
116 *data = mmap_ptr_; | |
117 return true; | |
37 } | 118 } |
38 | 119 |
39 void GpuMemoryBufferImplOzoneNativeBuffer::Unmap() { | 120 void GpuMemoryBufferImplOzoneNativeBuffer::Unmap() { |
40 NOTREACHED(); | 121 TRACE_EVENT0("gpu", "GpuMemoryBufferImplOzoneNativeBuffer::Unmap"); |
122 DCHECK(mapped_); | |
123 DCHECK(mmap_ptr_); | |
124 if (!vgem_bo_handle_) { | |
125 LOG(ERROR) << "Unmap is called for SCANOUT buffer."; | |
126 return; | |
127 } | |
128 | |
129 size_t size = stride_ * size_.height(); | |
130 int ret = munmap(mmap_ptr_, size); | |
131 DCHECK(!ret); | |
132 mmap_ptr_ = nullptr; | |
133 mapped_ = false; | |
41 } | 134 } |
42 | 135 |
43 void GpuMemoryBufferImplOzoneNativeBuffer::GetStride(int* stride) const { | 136 void GpuMemoryBufferImplOzoneNativeBuffer::GetStride(int* stride) const { |
44 NOTREACHED(); | 137 *stride = stride_; |
45 } | 138 } |
46 | 139 |
47 gfx::GpuMemoryBufferHandle GpuMemoryBufferImplOzoneNativeBuffer::GetHandle() | 140 gfx::GpuMemoryBufferHandle GpuMemoryBufferImplOzoneNativeBuffer::GetHandle() |
48 const { | 141 const { |
142 // Don't need to set |handle.handle| and |handle.device_handle| because gpu | |
143 // process can look up the right pixmap only by id. | |
144 // See ui::GpuMemoryBufferFactoryOzoneNativeBuffer | |
49 gfx::GpuMemoryBufferHandle handle; | 145 gfx::GpuMemoryBufferHandle handle; |
50 handle.type = gfx::OZONE_NATIVE_BUFFER; | 146 handle.type = gfx::OZONE_NATIVE_BUFFER; |
51 handle.id = id_; | 147 handle.id = id_; |
52 return handle; | 148 return handle; |
53 } | 149 } |
54 | 150 |
55 } // namespace content | 151 } // namespace content |
OLD | NEW |