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
3 // found in the LICENSE file.
4
5 #include "gpu/ipc/common/gpu_memory_buffer_impl_native_pixmap.h"
6
7 #include <vulkan/vulkan.h>
8
9 #include <utility>
10
11 #include "base/bind.h"
12 #include "base/memory/ptr_util.h"
13 #include "gpu/ipc/common/gpu_memory_buffer_support.h"
14 #include "ui/gfx/buffer_format_util.h"
15 #include "ui/gfx/client_native_pixmap_factory.h"
16 #include "ui/gfx/native_pixmap.h"
17
18 #if defined(USE_OZONE)
19 #include "ui/base/ui_base_features.h"
20 #include "ui/ozone/public/ozone_platform.h"
21 #include "ui/ozone/public/surface_factory_ozone.h"
22 #endif
23
24 namespace gpu {
25 namespace {
26
FreeNativePixmapForTesting(scoped_refptr<gfx::NativePixmap> native_pixmap)27 void FreeNativePixmapForTesting(
28 scoped_refptr<gfx::NativePixmap> native_pixmap) {
29 // Nothing to do here. |native_pixmap| will be freed when this function
30 // returns and reference count drops to 0.
31 }
32
33 } // namespace
34
GpuMemoryBufferImplNativePixmap(gfx::GpuMemoryBufferId id,const gfx::Size & size,gfx::BufferFormat format,DestructionCallback callback,std::unique_ptr<gfx::ClientNativePixmap> pixmap,gfx::NativePixmapHandle handle)35 GpuMemoryBufferImplNativePixmap::GpuMemoryBufferImplNativePixmap(
36 gfx::GpuMemoryBufferId id,
37 const gfx::Size& size,
38 gfx::BufferFormat format,
39 DestructionCallback callback,
40 std::unique_ptr<gfx::ClientNativePixmap> pixmap,
41 gfx::NativePixmapHandle handle)
42 : GpuMemoryBufferImpl(id, size, format, std::move(callback)),
43 pixmap_(std::move(pixmap)),
44 handle_(std::move(handle)) {}
45
46 GpuMemoryBufferImplNativePixmap::~GpuMemoryBufferImplNativePixmap() = default;
47
48 // static
49 std::unique_ptr<GpuMemoryBufferImplNativePixmap>
CreateFromHandle(gfx::ClientNativePixmapFactory * client_native_pixmap_factory,gfx::GpuMemoryBufferHandle handle,const gfx::Size & size,gfx::BufferFormat format,gfx::BufferUsage usage,DestructionCallback callback)50 GpuMemoryBufferImplNativePixmap::CreateFromHandle(
51 gfx::ClientNativePixmapFactory* client_native_pixmap_factory,
52 gfx::GpuMemoryBufferHandle handle,
53 const gfx::Size& size,
54 gfx::BufferFormat format,
55 gfx::BufferUsage usage,
56 DestructionCallback callback) {
57 std::unique_ptr<gfx::ClientNativePixmap> native_pixmap =
58 client_native_pixmap_factory->ImportFromHandle(
59 CloneHandleForIPC(handle.native_pixmap_handle), size, format, usage);
60 if (!native_pixmap)
61 return nullptr;
62
63 return base::WrapUnique(new GpuMemoryBufferImplNativePixmap(
64 handle.id, size, format, std::move(callback), std::move(native_pixmap),
65 std::move(handle.native_pixmap_handle)));
66 }
67
68 // static
AllocateForTesting(const gfx::Size & size,gfx::BufferFormat format,gfx::BufferUsage usage,gfx::GpuMemoryBufferHandle * handle)69 base::OnceClosure GpuMemoryBufferImplNativePixmap::AllocateForTesting(
70 const gfx::Size& size,
71 gfx::BufferFormat format,
72 gfx::BufferUsage usage,
73 gfx::GpuMemoryBufferHandle* handle) {
74 scoped_refptr<gfx::NativePixmap> pixmap;
75 #if defined(USE_OZONE)
76 if (features::IsUsingOzonePlatform()) {
77 pixmap = ui::OzonePlatform::GetInstance()
78 ->GetSurfaceFactoryOzone()
79 ->CreateNativePixmap(gfx::kNullAcceleratedWidget,
80 VK_NULL_HANDLE, size, format, usage);
81 handle->native_pixmap_handle = pixmap->ExportHandle();
82 } else
83 #endif
84 {
85 // TODO(j.isorce): use gbm_bo_create / gbm_bo_get_fd from system libgbm.
86 NOTIMPLEMENTED();
87 }
88 handle->type = gfx::NATIVE_PIXMAP;
89 return base::BindOnce(&FreeNativePixmapForTesting, pixmap);
90 }
91
Map()92 bool GpuMemoryBufferImplNativePixmap::Map() {
93 DCHECK(!mapped_);
94 DCHECK_EQ(gfx::NumberOfPlanesForLinearBufferFormat(GetFormat()),
95 handle_.planes.size());
96 mapped_ = pixmap_->Map();
97 return mapped_;
98 }
99
memory(size_t plane)100 void* GpuMemoryBufferImplNativePixmap::memory(size_t plane) {
101 DCHECK(mapped_);
102 return pixmap_->GetMemoryAddress(plane);
103 }
104
Unmap()105 void GpuMemoryBufferImplNativePixmap::Unmap() {
106 DCHECK(mapped_);
107 pixmap_->Unmap();
108 mapped_ = false;
109 }
110
stride(size_t plane) const111 int GpuMemoryBufferImplNativePixmap::stride(size_t plane) const {
112 // The caller is responsible for ensuring that |plane| is within bounds.
113 CHECK_LT(plane, handle_.planes.size());
114
115 // |handle_|.planes[plane].stride is a uint32_t. For usages for which we
116 // create a ClientNativePixmapDmaBuf,
117 // ClientNativePixmapDmaBuf::ImportFromDmabuf() ensures that the stride fits
118 // on an int, so this checked_cast shouldn't fail. For usages for which we
119 // create a ClientNativePixmapOpaque, we don't validate the stride, but the
120 // expectation is that either a) the stride() method won't be called, or b)
121 // the stride() method is called on the GPU process and
122 // |handle_|.planes[plane].stride is also set on the GPU process so there's no
123 // need to validate it. Refer to http://crbug.com/1093644#c1 for a more
124 // detailed discussion.
125 return base::checked_cast<int>(handle_.planes[plane].stride);
126 }
127
GetType() const128 gfx::GpuMemoryBufferType GpuMemoryBufferImplNativePixmap::GetType() const {
129 return gfx::NATIVE_PIXMAP;
130 }
131
CloneHandle() const132 gfx::GpuMemoryBufferHandle GpuMemoryBufferImplNativePixmap::CloneHandle()
133 const {
134 gfx::GpuMemoryBufferHandle handle;
135 handle.type = gfx::NATIVE_PIXMAP;
136 handle.id = id_;
137 handle.native_pixmap_handle = gfx::CloneHandleForIPC(handle_);
138 return handle;
139 }
140
141 } // namespace gpu
142