1 // Copyright 2017 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_android_hardware_buffer.h"
6
7 #include <utility>
8
9 #include "base/android/android_hardware_buffer_compat.h"
10 #include "base/bind.h"
11 #include "base/callback_helpers.h"
12 #include "base/logging.h"
13 #include "base/memory/ptr_util.h"
14 #include "gpu/ipc/common/gpu_memory_buffer_support.h"
15 #include "ui/gfx/android/android_surface_control_compat.h"
16 #include "ui/gfx/geometry/size.h"
17
18 namespace gpu {
19
20 namespace {
21
GetBufferDescription(const gfx::Size & size,gfx::BufferFormat format,gfx::BufferUsage usage)22 AHardwareBuffer_Desc GetBufferDescription(const gfx::Size& size,
23 gfx::BufferFormat format,
24 gfx::BufferUsage usage) {
25 // On create, all elements must be initialized, including setting the
26 // "reserved for future use" (rfu) fields to zero.
27 AHardwareBuffer_Desc desc = {};
28 desc.width = size.width();
29 desc.height = size.height();
30 desc.layers = 1; // number of images
31
32 switch (format) {
33 case gfx::BufferFormat::RGBA_8888:
34 desc.format = AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM;
35 break;
36 case gfx::BufferFormat::RGBX_8888:
37 desc.format = AHARDWAREBUFFER_FORMAT_R8G8B8X8_UNORM;
38 break;
39 case gfx::BufferFormat::BGR_565:
40 desc.format = AHARDWAREBUFFER_FORMAT_R5G6B5_UNORM;
41 break;
42 case gfx::BufferFormat::RGBA_F16:
43 desc.format = AHARDWAREBUFFER_FORMAT_R16G16B16A16_FLOAT;
44 break;
45 case gfx::BufferFormat::RGBA_1010102:
46 desc.format = AHARDWAREBUFFER_FORMAT_R10G10B10A2_UNORM;
47 break;
48 default:
49 NOTREACHED();
50 }
51
52 switch (usage) {
53 case gfx::BufferUsage::GPU_READ:
54 case gfx::BufferUsage::SCANOUT:
55 desc.usage = AHARDWAREBUFFER_USAGE_GPU_SAMPLED_IMAGE |
56 AHARDWAREBUFFER_USAGE_GPU_COLOR_OUTPUT;
57 if (usage == gfx::BufferUsage::SCANOUT)
58 desc.usage |= gfx::SurfaceControl::RequiredUsage();
59 break;
60 default:
61 NOTREACHED();
62 }
63 return desc;
64 }
65
66 } // namespace
67
68 GpuMemoryBufferImplAndroidHardwareBuffer::
GpuMemoryBufferImplAndroidHardwareBuffer(gfx::GpuMemoryBufferId id,const gfx::Size & size,gfx::BufferFormat format,DestructionCallback callback,base::android::ScopedHardwareBufferHandle handle)69 GpuMemoryBufferImplAndroidHardwareBuffer(
70 gfx::GpuMemoryBufferId id,
71 const gfx::Size& size,
72 gfx::BufferFormat format,
73 DestructionCallback callback,
74 base::android::ScopedHardwareBufferHandle handle)
75 : GpuMemoryBufferImpl(id, size, format, std::move(callback)),
76 hardware_buffer_handle_(std::move(handle)) {}
77
78 GpuMemoryBufferImplAndroidHardwareBuffer::
~GpuMemoryBufferImplAndroidHardwareBuffer()79 ~GpuMemoryBufferImplAndroidHardwareBuffer() {}
80
81 // static
82 std::unique_ptr<GpuMemoryBufferImplAndroidHardwareBuffer>
Create(gfx::GpuMemoryBufferId id,const gfx::Size & size,gfx::BufferFormat format,gfx::BufferUsage usage,DestructionCallback callback)83 GpuMemoryBufferImplAndroidHardwareBuffer::Create(gfx::GpuMemoryBufferId id,
84 const gfx::Size& size,
85 gfx::BufferFormat format,
86 gfx::BufferUsage usage,
87 DestructionCallback callback) {
88 DCHECK(base::AndroidHardwareBufferCompat::IsSupportAvailable());
89
90 AHardwareBuffer* buffer = nullptr;
91 AHardwareBuffer_Desc desc = GetBufferDescription(size, format, usage);
92 base::AndroidHardwareBufferCompat::GetInstance().Allocate(&desc, &buffer);
93 if (!buffer) {
94 LOG(ERROR) << "Failed to allocate AHardwareBuffer";
95 return nullptr;
96 }
97
98 return base::WrapUnique(new GpuMemoryBufferImplAndroidHardwareBuffer(
99 id, size, format, std::move(callback),
100 base::android::ScopedHardwareBufferHandle::Adopt(buffer)));
101 }
102
103 // static
104 std::unique_ptr<GpuMemoryBufferImplAndroidHardwareBuffer>
CreateFromHandle(gfx::GpuMemoryBufferHandle handle,const gfx::Size & size,gfx::BufferFormat format,gfx::BufferUsage usage,DestructionCallback callback)105 GpuMemoryBufferImplAndroidHardwareBuffer::CreateFromHandle(
106 gfx::GpuMemoryBufferHandle handle,
107 const gfx::Size& size,
108 gfx::BufferFormat format,
109 gfx::BufferUsage usage,
110 DestructionCallback callback) {
111 DCHECK(handle.android_hardware_buffer.is_valid());
112 return base::WrapUnique(new GpuMemoryBufferImplAndroidHardwareBuffer(
113 handle.id, size, format, std::move(callback),
114 std::move(handle.android_hardware_buffer)));
115 }
116
Map()117 bool GpuMemoryBufferImplAndroidHardwareBuffer::Map() {
118 return false;
119 }
120
memory(size_t plane)121 void* GpuMemoryBufferImplAndroidHardwareBuffer::memory(size_t plane) {
122 return nullptr;
123 }
124
Unmap()125 void GpuMemoryBufferImplAndroidHardwareBuffer::Unmap() {}
126
stride(size_t plane) const127 int GpuMemoryBufferImplAndroidHardwareBuffer::stride(size_t plane) const {
128 return 0;
129 }
130
GetType() const131 gfx::GpuMemoryBufferType GpuMemoryBufferImplAndroidHardwareBuffer::GetType()
132 const {
133 return gfx::ANDROID_HARDWARE_BUFFER;
134 }
135
136 gfx::GpuMemoryBufferHandle
CloneHandle() const137 GpuMemoryBufferImplAndroidHardwareBuffer::CloneHandle() const {
138 gfx::GpuMemoryBufferHandle handle;
139 handle.type = gfx::ANDROID_HARDWARE_BUFFER;
140 handle.id = id_;
141 handle.android_hardware_buffer = hardware_buffer_handle_.Clone();
142 return handle;
143 }
144
145 // static
AllocateForTesting(const gfx::Size & size,gfx::BufferFormat format,gfx::BufferUsage usage,gfx::GpuMemoryBufferHandle * handle)146 base::OnceClosure GpuMemoryBufferImplAndroidHardwareBuffer::AllocateForTesting(
147 const gfx::Size& size,
148 gfx::BufferFormat format,
149 gfx::BufferUsage usage,
150 gfx::GpuMemoryBufferHandle* handle) {
151 gfx::GpuMemoryBufferId kBufferId(1);
152 handle->type = gfx::ANDROID_HARDWARE_BUFFER;
153 handle->id = kBufferId;
154 AHardwareBuffer* buffer = nullptr;
155 AHardwareBuffer_Desc desc = GetBufferDescription(size, format, usage);
156 base::AndroidHardwareBufferCompat::GetInstance().Allocate(&desc, &buffer);
157 DCHECK(buffer);
158 handle->android_hardware_buffer =
159 base::android::ScopedHardwareBufferHandle::Adopt(buffer);
160 return base::DoNothing();
161 }
162
163 } // namespace gpu
164