blob: cd179bee08679ab367aa2ae2f7d69853009ca81e [file] [log] [blame]
Pawin Vongmasa36653902018-11-15 00:10:25 -08001/*
2 * Copyright (C) 2016 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17//#define LOG_NDEBUG 0
18#define LOG_TAG "C2AllocatorGralloc"
19#include <utils/Log.h>
20
21#include <android/hardware/graphics/allocator/2.0/IAllocator.h>
22#include <android/hardware/graphics/mapper/2.0/IMapper.h>
Pawin Vongmasad032f2d2019-05-15 08:42:44 -070023#include <android/hardware/graphics/allocator/3.0/IAllocator.h>
24#include <android/hardware/graphics/mapper/3.0/IMapper.h>
Marissa Wall8806edc2019-06-21 09:50:47 -070025#include <android/hardware/graphics/allocator/4.0/IAllocator.h>
26#include <android/hardware/graphics/mapper/4.0/IMapper.h>
Pawin Vongmasa36653902018-11-15 00:10:25 -080027#include <cutils/native_handle.h>
28#include <hardware/gralloc.h>
29
30#include <C2AllocatorGralloc.h>
31#include <C2Buffer.h>
32#include <C2PlatformSupport.h>
33
34namespace android {
35
Pawin Vongmasad032f2d2019-05-15 08:42:44 -070036namespace /* unnamed */ {
Pawin Vongmasa36653902018-11-15 00:10:25 -080037 enum : uint64_t {
38 /**
39 * Usage mask that is passed through from gralloc to Codec 2.0 usage.
40 */
41 PASSTHROUGH_USAGE_MASK =
42 ~(GRALLOC_USAGE_SW_READ_MASK | GRALLOC_USAGE_SW_WRITE_MASK | GRALLOC_USAGE_PROTECTED)
43 };
44
45 // verify that passthrough mask is within the platform mask
46 static_assert((~C2MemoryUsage::PLATFORM_MASK & PASSTHROUGH_USAGE_MASK) == 0, "");
Pawin Vongmasad032f2d2019-05-15 08:42:44 -070047} // unnamed
Pawin Vongmasa36653902018-11-15 00:10:25 -080048
49C2MemoryUsage C2AndroidMemoryUsage::FromGrallocUsage(uint64_t usage) {
50 // gralloc does not support WRITE_PROTECTED
51 return C2MemoryUsage(
52 ((usage & GRALLOC_USAGE_SW_READ_MASK) ? C2MemoryUsage::CPU_READ : 0) |
53 ((usage & GRALLOC_USAGE_SW_WRITE_MASK) ? C2MemoryUsage::CPU_WRITE : 0) |
54 ((usage & GRALLOC_USAGE_PROTECTED) ? C2MemoryUsage::READ_PROTECTED : 0) |
55 (usage & PASSTHROUGH_USAGE_MASK));
56}
57
58uint64_t C2AndroidMemoryUsage::asGrallocUsage() const {
59 // gralloc does not support WRITE_PROTECTED
60 return (((expected & C2MemoryUsage::CPU_READ) ? GRALLOC_USAGE_SW_READ_OFTEN : 0) |
61 ((expected & C2MemoryUsage::CPU_WRITE) ? GRALLOC_USAGE_SW_WRITE_OFTEN : 0) |
62 ((expected & C2MemoryUsage::READ_PROTECTED) ? GRALLOC_USAGE_PROTECTED : 0) |
63 (expected & PASSTHROUGH_USAGE_MASK));
64}
65
Pawin Vongmasa36653902018-11-15 00:10:25 -080066using ::android::hardware::hidl_handle;
67using ::android::hardware::hidl_vec;
Pawin Vongmasad032f2d2019-05-15 08:42:44 -070068using ::android::hardware::graphics::common::V1_0::BufferUsage;
69using PixelFormat2 = ::android::hardware::graphics::common::V1_0::PixelFormat;
70using PixelFormat3 = ::android::hardware::graphics::common::V1_2::PixelFormat;
Marissa Wall8806edc2019-06-21 09:50:47 -070071using PixelFormat4 = ::android::hardware::graphics::common::V1_2::PixelFormat;
Pawin Vongmasa36653902018-11-15 00:10:25 -080072
Pawin Vongmasad032f2d2019-05-15 08:42:44 -070073using IAllocator2 = ::android::hardware::graphics::allocator::V2_0::IAllocator;
74using BufferDescriptor2 = ::android::hardware::graphics::mapper::V2_0::BufferDescriptor;
75using Error2 = ::android::hardware::graphics::mapper::V2_0::Error;
76using IMapper2 = ::android::hardware::graphics::mapper::V2_0::IMapper;
Pawin Vongmasa36653902018-11-15 00:10:25 -080077
Pawin Vongmasad032f2d2019-05-15 08:42:44 -070078using IAllocator3 = ::android::hardware::graphics::allocator::V3_0::IAllocator;
79using BufferDescriptor3 = ::android::hardware::graphics::mapper::V3_0::BufferDescriptor;
80using Error3 = ::android::hardware::graphics::mapper::V3_0::Error;
81using IMapper3 = ::android::hardware::graphics::mapper::V3_0::IMapper;
82
Marissa Wall8806edc2019-06-21 09:50:47 -070083using IAllocator4 = ::android::hardware::graphics::allocator::V4_0::IAllocator;
84using BufferDescriptor4 = ::android::hardware::graphics::mapper::V4_0::BufferDescriptor;
85using Error4 = ::android::hardware::graphics::mapper::V4_0::Error;
86using IMapper4 = ::android::hardware::graphics::mapper::V4_0::IMapper;
87
Pawin Vongmasad032f2d2019-05-15 08:42:44 -070088namespace /* unnamed */ {
89
90struct BufferDescriptorInfo2 {
91 IMapper2::BufferDescriptorInfo mapperInfo;
Pawin Vongmasa36653902018-11-15 00:10:25 -080092 uint32_t stride;
93};
94
Pawin Vongmasad032f2d2019-05-15 08:42:44 -070095struct BufferDescriptorInfo3 {
96 IMapper3::BufferDescriptorInfo mapperInfo;
97 uint32_t stride;
98};
Pawin Vongmasa36653902018-11-15 00:10:25 -080099
Marissa Wall8806edc2019-06-21 09:50:47 -0700100struct BufferDescriptorInfo4 {
101 IMapper4::BufferDescriptorInfo mapperInfo;
102 uint32_t stride;
103};
104
Pawin Vongmasa36653902018-11-15 00:10:25 -0800105/* ===================================== GRALLOC ALLOCATION ==================================== */
Pawin Vongmasad032f2d2019-05-15 08:42:44 -0700106c2_status_t maperr2error(Error2 maperr) {
Pawin Vongmasa36653902018-11-15 00:10:25 -0800107 switch (maperr) {
Pawin Vongmasad032f2d2019-05-15 08:42:44 -0700108 case Error2::NONE: return C2_OK;
109 case Error2::BAD_DESCRIPTOR: return C2_BAD_VALUE;
110 case Error2::BAD_BUFFER: return C2_BAD_VALUE;
111 case Error2::BAD_VALUE: return C2_BAD_VALUE;
112 case Error2::NO_RESOURCES: return C2_NO_MEMORY;
113 case Error2::UNSUPPORTED: return C2_CANNOT_DO;
Pawin Vongmasa36653902018-11-15 00:10:25 -0800114 }
115 return C2_CORRUPTED;
116}
117
Pawin Vongmasad032f2d2019-05-15 08:42:44 -0700118c2_status_t maperr2error(Error3 maperr) {
119 switch (maperr) {
120 case Error3::NONE: return C2_OK;
121 case Error3::BAD_DESCRIPTOR: return C2_BAD_VALUE;
122 case Error3::BAD_BUFFER: return C2_BAD_VALUE;
123 case Error3::BAD_VALUE: return C2_BAD_VALUE;
124 case Error3::NO_RESOURCES: return C2_NO_MEMORY;
125 case Error3::UNSUPPORTED: return C2_CANNOT_DO;
126 }
127 return C2_CORRUPTED;
128}
129
Marissa Wall8806edc2019-06-21 09:50:47 -0700130c2_status_t maperr2error(Error4 maperr) {
131 switch (maperr) {
132 case Error4::NONE: return C2_OK;
133 case Error4::BAD_DESCRIPTOR: return C2_BAD_VALUE;
134 case Error4::BAD_BUFFER: return C2_BAD_VALUE;
135 case Error4::BAD_VALUE: return C2_BAD_VALUE;
136 case Error4::NO_RESOURCES: return C2_NO_MEMORY;
137 case Error4::UNSUPPORTED: return C2_CANNOT_DO;
138 }
139 return C2_CORRUPTED;
140}
141
Pawin Vongmasa36653902018-11-15 00:10:25 -0800142bool native_handle_is_invalid(const native_handle_t *const handle) {
143 // perform basic validation of a native handle
144 if (handle == nullptr) {
145 // null handle is considered valid
146 return false;
147 }
148 return ((size_t)handle->version != sizeof(native_handle_t) ||
149 handle->numFds < 0 ||
150 handle->numInts < 0 ||
151 // for sanity assume handles must occupy less memory than INT_MAX bytes
152 handle->numFds > int((INT_MAX - handle->version) / sizeof(int)) - handle->numInts);
153}
154
155class C2HandleGralloc : public C2Handle {
156private:
157 struct ExtraData {
158 uint32_t width;
159 uint32_t height;
160 uint32_t format;
161 uint32_t usage_lo;
162 uint32_t usage_hi;
163 uint32_t stride;
164 uint32_t generation;
165 uint32_t igbp_id_lo;
166 uint32_t igbp_id_hi;
167 uint32_t igbp_slot;
168 uint32_t magic;
169 };
170
171 enum {
172 NUM_INTS = sizeof(ExtraData) / sizeof(int),
173 };
174 const static uint32_t MAGIC = '\xc2gr\x00';
175
176 static
177 const ExtraData* getExtraData(const C2Handle *const handle) {
178 if (handle == nullptr
179 || native_handle_is_invalid(handle)
180 || handle->numInts < NUM_INTS) {
181 return nullptr;
182 }
183 return reinterpret_cast<const ExtraData*>(
184 &handle->data[handle->numFds + handle->numInts - NUM_INTS]);
185 }
186
187 static
188 ExtraData *getExtraData(C2Handle *const handle) {
189 return const_cast<ExtraData *>(getExtraData(const_cast<const C2Handle *const>(handle)));
190 }
191
192public:
193 void getIgbpData(uint32_t *generation, uint64_t *igbp_id, uint32_t *igbp_slot) const {
194 const ExtraData *ed = getExtraData(this);
195 *generation = ed->generation;
196 *igbp_id = unsigned(ed->igbp_id_lo) | uint64_t(unsigned(ed->igbp_id_hi)) << 32;
197 *igbp_slot = ed->igbp_slot;
198 }
199
200 static bool isValid(const C2Handle *const o) {
201 if (o == nullptr) { // null handle is always valid
202 return true;
203 }
204 const ExtraData *xd = getExtraData(o);
205 // we cannot validate width/height/format/usage without accessing gralloc driver
206 return xd != nullptr && xd->magic == MAGIC;
207 }
208
Sungtak Leea4d13be2019-01-23 15:24:46 -0800209 static C2HandleGralloc* WrapAndMoveNativeHandle(
Pawin Vongmasa36653902018-11-15 00:10:25 -0800210 const native_handle_t *const handle,
211 uint32_t width, uint32_t height, uint32_t format, uint64_t usage,
212 uint32_t stride, uint32_t generation, uint64_t igbp_id = 0, uint32_t igbp_slot = 0) {
213 //CHECK(handle != nullptr);
214 if (native_handle_is_invalid(handle) ||
215 handle->numInts > int((INT_MAX - handle->version) / sizeof(int)) - NUM_INTS - handle->numFds) {
216 return nullptr;
217 }
218 ExtraData xd = {
219 width, height, format, uint32_t(usage & 0xFFFFFFFF), uint32_t(usage >> 32),
220 stride, generation, uint32_t(igbp_id & 0xFFFFFFFF), uint32_t(igbp_id >> 32),
221 igbp_slot, MAGIC
222 };
223 native_handle_t *res = native_handle_create(handle->numFds, handle->numInts + NUM_INTS);
224 if (res != nullptr) {
225 memcpy(&res->data, &handle->data, sizeof(int) * (handle->numFds + handle->numInts));
226 *getExtraData(res) = xd;
227 }
228 return reinterpret_cast<C2HandleGralloc *>(res);
229 }
230
Sungtak Leea4d13be2019-01-23 15:24:46 -0800231 static C2HandleGralloc* WrapNativeHandle(
232 const native_handle_t *const handle,
233 uint32_t width, uint32_t height, uint32_t format, uint64_t usage,
234 uint32_t stride, uint32_t generation, uint64_t igbp_id = 0, uint32_t igbp_slot = 0) {
235 if (handle == nullptr) {
236 return nullptr;
237 }
238 native_handle_t *clone = native_handle_clone(handle);
239 if (clone == nullptr) {
240 return nullptr;
241 }
242 C2HandleGralloc *res = WrapAndMoveNativeHandle(
243 clone, width, height, format, usage, stride, generation, igbp_id, igbp_slot);
244 if (res == nullptr) {
245 native_handle_close(clone);
246 }
247 native_handle_delete(clone);
248 return res;
249 }
250
Sungtak Lee08515812019-06-05 11:16:32 -0700251 static bool MigrateNativeHandle(
252 native_handle_t *handle,
253 uint32_t generation, uint64_t igbp_id, uint32_t igbp_slot) {
254 if (handle == nullptr || !isValid(handle)) {
255 return false;
256 }
257 ExtraData *ed = getExtraData(handle);
258 if (!ed) return false;
259 ed->generation = generation;
260 ed->igbp_id_lo = uint32_t(igbp_id & 0xFFFFFFFF);
261 ed->igbp_id_hi = uint32_t(igbp_id >> 32);
262 ed->igbp_slot = igbp_slot;
263 return true;
264 }
265
266
Pawin Vongmasa36653902018-11-15 00:10:25 -0800267 static native_handle_t* UnwrapNativeHandle(
268 const C2Handle *const handle) {
269 const ExtraData *xd = getExtraData(handle);
270 if (xd == nullptr || xd->magic != MAGIC) {
271 return nullptr;
272 }
273 native_handle_t *res = native_handle_create(handle->numFds, handle->numInts - NUM_INTS);
274 if (res != nullptr) {
275 memcpy(&res->data, &handle->data, sizeof(int) * (res->numFds + res->numInts));
276 }
277 return res;
278 }
279
Pawin Vongmasa36653902018-11-15 00:10:25 -0800280 static const C2HandleGralloc* Import(
281 const C2Handle *const handle,
282 uint32_t *width, uint32_t *height, uint32_t *format,
283 uint64_t *usage, uint32_t *stride,
284 uint32_t *generation, uint64_t *igbp_id, uint32_t *igbp_slot) {
285 const ExtraData *xd = getExtraData(handle);
286 if (xd == nullptr) {
287 return nullptr;
288 }
289 *width = xd->width;
290 *height = xd->height;
291 *format = xd->format;
292 *usage = xd->usage_lo | (uint64_t(xd->usage_hi) << 32);
293 *stride = xd->stride;
294 *generation = xd->generation;
295 *igbp_id = xd->igbp_id_lo | (uint64_t(xd->igbp_id_hi) << 32);
296 *igbp_slot = xd->igbp_slot;
297 return reinterpret_cast<const C2HandleGralloc *>(handle);
298 }
299};
300
Pawin Vongmasad032f2d2019-05-15 08:42:44 -0700301} // unnamed namespace
302
Pawin Vongmasa36653902018-11-15 00:10:25 -0800303native_handle_t *UnwrapNativeCodec2GrallocHandle(const C2Handle *const handle) {
304 return C2HandleGralloc::UnwrapNativeHandle(handle);
305}
306
Pawin Vongmasa36653902018-11-15 00:10:25 -0800307C2Handle *WrapNativeCodec2GrallocHandle(
308 const native_handle_t *const handle,
309 uint32_t width, uint32_t height, uint32_t format, uint64_t usage, uint32_t stride,
310 uint32_t generation, uint64_t igbp_id, uint32_t igbp_slot) {
311 return C2HandleGralloc::WrapNativeHandle(handle, width, height, format, usage, stride,
312 generation, igbp_id, igbp_slot);
313}
314
Sungtak Lee08515812019-06-05 11:16:32 -0700315bool MigrateNativeCodec2GrallocHandle(
316 native_handle_t *handle,
317 uint32_t generation, uint64_t igbp_id, uint32_t igbp_slot) {
318 return C2HandleGralloc::MigrateNativeHandle(handle, generation, igbp_id, igbp_slot);
319}
320
321
Pawin Vongmasa36653902018-11-15 00:10:25 -0800322class C2AllocationGralloc : public C2GraphicAllocation {
323public:
324 virtual ~C2AllocationGralloc() override;
325
326 virtual c2_status_t map(
327 C2Rect rect, C2MemoryUsage usage, C2Fence *fence,
328 C2PlanarLayout *layout /* nonnull */, uint8_t **addr /* nonnull */) override;
329 virtual c2_status_t unmap(
330 uint8_t **addr /* nonnull */, C2Rect rect, C2Fence *fence /* nullable */) override;
331 virtual C2Allocator::id_t getAllocatorId() const override { return mAllocatorId; }
332 virtual const C2Handle *handle() const override { return mLockedHandle ? : mHandle; }
333 virtual bool equals(const std::shared_ptr<const C2GraphicAllocation> &other) const override;
334
335 // internal methods
336 // |handle| will be moved.
337 C2AllocationGralloc(
Pawin Vongmasad032f2d2019-05-15 08:42:44 -0700338 const BufferDescriptorInfo2 &info,
339 const sp<IMapper2> &mapper,
340 hidl_handle &hidlHandle,
341 const C2HandleGralloc *const handle,
342 C2Allocator::id_t allocatorId);
343 C2AllocationGralloc(
344 const BufferDescriptorInfo3 &info,
345 const sp<IMapper3> &mapper,
Pawin Vongmasa36653902018-11-15 00:10:25 -0800346 hidl_handle &hidlHandle,
347 const C2HandleGralloc *const handle,
348 C2Allocator::id_t allocatorId);
Marissa Wall8806edc2019-06-21 09:50:47 -0700349 C2AllocationGralloc(
350 const BufferDescriptorInfo4 &info,
351 const sp<IMapper4> &mapper,
352 hidl_handle &hidlHandle,
353 const C2HandleGralloc *const handle,
354 C2Allocator::id_t allocatorId);
Pawin Vongmasa36653902018-11-15 00:10:25 -0800355 int dup() const;
356 c2_status_t status() const;
357
358private:
Pawin Vongmasad032f2d2019-05-15 08:42:44 -0700359 const BufferDescriptorInfo2 mInfo2{};
360 const sp<IMapper2> mMapper2{nullptr};
361 const BufferDescriptorInfo3 mInfo3{};
362 const sp<IMapper3> mMapper3{nullptr};
Marissa Wall8806edc2019-06-21 09:50:47 -0700363 const BufferDescriptorInfo4 mInfo4{};
364 const sp<IMapper4> mMapper4{nullptr};
Pawin Vongmasa36653902018-11-15 00:10:25 -0800365 const hidl_handle mHidlHandle;
366 const C2HandleGralloc *mHandle;
367 buffer_handle_t mBuffer;
368 const C2HandleGralloc *mLockedHandle;
369 bool mLocked;
370 C2Allocator::id_t mAllocatorId;
371 std::mutex mMappedLock;
372};
373
374C2AllocationGralloc::C2AllocationGralloc(
Pawin Vongmasad032f2d2019-05-15 08:42:44 -0700375 const BufferDescriptorInfo2 &info,
376 const sp<IMapper2> &mapper,
Pawin Vongmasa36653902018-11-15 00:10:25 -0800377 hidl_handle &hidlHandle,
378 const C2HandleGralloc *const handle,
379 C2Allocator::id_t allocatorId)
380 : C2GraphicAllocation(info.mapperInfo.width, info.mapperInfo.height),
Pawin Vongmasad032f2d2019-05-15 08:42:44 -0700381 mInfo2(info),
382 mMapper2(mapper),
383 mHidlHandle(std::move(hidlHandle)),
384 mHandle(handle),
385 mBuffer(nullptr),
386 mLockedHandle(nullptr),
387 mLocked(false),
388 mAllocatorId(allocatorId) {
389}
390
391C2AllocationGralloc::C2AllocationGralloc(
392 const BufferDescriptorInfo3 &info,
393 const sp<IMapper3> &mapper,
394 hidl_handle &hidlHandle,
395 const C2HandleGralloc *const handle,
396 C2Allocator::id_t allocatorId)
397 : C2GraphicAllocation(info.mapperInfo.width, info.mapperInfo.height),
398 mInfo3(info),
399 mMapper3(mapper),
Pawin Vongmasa36653902018-11-15 00:10:25 -0800400 mHidlHandle(std::move(hidlHandle)),
401 mHandle(handle),
402 mBuffer(nullptr),
403 mLockedHandle(nullptr),
404 mLocked(false),
405 mAllocatorId(allocatorId) {
406}
407
Marissa Wall8806edc2019-06-21 09:50:47 -0700408C2AllocationGralloc::C2AllocationGralloc(
409 const BufferDescriptorInfo4 &info,
410 const sp<IMapper4> &mapper,
411 hidl_handle &hidlHandle,
412 const C2HandleGralloc *const handle,
413 C2Allocator::id_t allocatorId)
414 : C2GraphicAllocation(info.mapperInfo.width, info.mapperInfo.height),
415 mInfo4(info),
416 mMapper4(mapper),
417 mHidlHandle(std::move(hidlHandle)),
418 mHandle(handle),
419 mBuffer(nullptr),
420 mLockedHandle(nullptr),
421 mLocked(false),
422 mAllocatorId(allocatorId) {
423}
424
Pawin Vongmasa36653902018-11-15 00:10:25 -0800425C2AllocationGralloc::~C2AllocationGralloc() {
Yichi Chenfa94a3b2018-12-08 00:06:25 +0800426 if (mBuffer && mLocked) {
Pawin Vongmasa36653902018-11-15 00:10:25 -0800427 // implementation ignores addresss and rect
428 uint8_t* addr[C2PlanarLayout::MAX_NUM_PLANES] = {};
429 unmap(addr, C2Rect(), nullptr);
430 }
Yichi Chenfa94a3b2018-12-08 00:06:25 +0800431 if (mBuffer) {
Pawin Vongmasad032f2d2019-05-15 08:42:44 -0700432 if (mMapper2) {
433 if (!mMapper2->freeBuffer(const_cast<native_handle_t *>(
434 mBuffer)).isOk()) {
435 ALOGE("failed transaction: freeBuffer");
436 }
Marissa Wall8806edc2019-06-21 09:50:47 -0700437 } else if (mMapper3) {
Pawin Vongmasad032f2d2019-05-15 08:42:44 -0700438 if (!mMapper3->freeBuffer(const_cast<native_handle_t *>(
439 mBuffer)).isOk()) {
440 ALOGE("failed transaction: freeBuffer");
441 }
Marissa Wall8806edc2019-06-21 09:50:47 -0700442 } else {
443 if (!mMapper4->freeBuffer(const_cast<native_handle_t *>(
444 mBuffer)).isOk()) {
445 ALOGE("failed transaction: freeBuffer");
446 }
Pawin Vongmasad032f2d2019-05-15 08:42:44 -0700447 }
Marissa Wall8806edc2019-06-21 09:50:47 -0700448
Yichi Chenfa94a3b2018-12-08 00:06:25 +0800449 }
450 if (mHandle) {
451 native_handle_delete(
452 const_cast<native_handle_t *>(reinterpret_cast<const native_handle_t *>(mHandle)));
453 }
Sungtak Lee2729dcf2019-01-18 13:15:07 -0800454 if (mLockedHandle) {
455 native_handle_delete(
456 const_cast<native_handle_t *>(
457 reinterpret_cast<const native_handle_t *>(mLockedHandle)));
458 }
Pawin Vongmasa36653902018-11-15 00:10:25 -0800459}
460
461c2_status_t C2AllocationGralloc::map(
462 C2Rect rect, C2MemoryUsage usage, C2Fence *fence,
463 C2PlanarLayout *layout /* nonnull */, uint8_t **addr /* nonnull */) {
464 uint64_t grallocUsage = static_cast<C2AndroidMemoryUsage>(usage).asGrallocUsage();
465 ALOGV("mapping buffer with usage %#llx => %#llx",
466 (long long)usage.expected, (long long)grallocUsage);
467
468 // TODO
469 (void) fence;
470
471 std::lock_guard<std::mutex> lock(mMappedLock);
472 if (mBuffer && mLocked) {
473 ALOGD("already mapped");
474 return C2_DUPLICATE;
475 }
476 if (!layout || !addr) {
477 ALOGD("wrong param");
478 return C2_BAD_VALUE;
479 }
480
481 c2_status_t err = C2_OK;
482 if (!mBuffer) {
Pawin Vongmasad032f2d2019-05-15 08:42:44 -0700483 if (mMapper2) {
484 if (!mMapper2->importBuffer(
485 mHidlHandle, [&err, this](const auto &maperr, const auto &buffer) {
486 err = maperr2error(maperr);
487 if (err == C2_OK) {
488 mBuffer = static_cast<buffer_handle_t>(buffer);
489 }
490 }).isOk()) {
491 ALOGE("failed transaction: importBuffer");
492 return C2_CORRUPTED;
493 }
Marissa Wall8806edc2019-06-21 09:50:47 -0700494 } else if (mMapper3) {
Pawin Vongmasad032f2d2019-05-15 08:42:44 -0700495 if (!mMapper3->importBuffer(
496 mHidlHandle, [&err, this](const auto &maperr, const auto &buffer) {
497 err = maperr2error(maperr);
498 if (err == C2_OK) {
499 mBuffer = static_cast<buffer_handle_t>(buffer);
500 }
501 }).isOk()) {
502 ALOGE("failed transaction: importBuffer (@3.0)");
503 return C2_CORRUPTED;
504 }
Marissa Wall8806edc2019-06-21 09:50:47 -0700505 } else {
506 if (!mMapper4->importBuffer(
507 mHidlHandle, [&err, this](const auto &maperr, const auto &buffer) {
508 err = maperr2error(maperr);
509 if (err == C2_OK) {
510 mBuffer = static_cast<buffer_handle_t>(buffer);
511 }
512 }).isOk()) {
513 ALOGE("failed transaction: importBuffer (@4.0)");
514 return C2_CORRUPTED;
515 }
Pawin Vongmasad032f2d2019-05-15 08:42:44 -0700516 }
Pawin Vongmasa36653902018-11-15 00:10:25 -0800517 if (err != C2_OK) {
518 ALOGD("importBuffer failed: %d", err);
519 return err;
520 }
521 if (mBuffer == nullptr) {
522 ALOGD("importBuffer returned null buffer");
523 return C2_CORRUPTED;
524 }
525 uint32_t generation = 0;
526 uint64_t igbp_id = 0;
527 uint32_t igbp_slot = 0;
528 if (mHandle) {
529 mHandle->getIgbpData(&generation, &igbp_id, &igbp_slot);
530 }
Pawin Vongmasad032f2d2019-05-15 08:42:44 -0700531 if (mMapper2) {
532 mLockedHandle = C2HandleGralloc::WrapAndMoveNativeHandle(
533 mBuffer, mInfo2.mapperInfo.width, mInfo2.mapperInfo.height,
534 (uint32_t)mInfo2.mapperInfo.format, mInfo2.mapperInfo.usage,
535 mInfo2.stride, generation, igbp_id, igbp_slot);
Marissa Wall8806edc2019-06-21 09:50:47 -0700536 } else if (mMapper3) {
Pawin Vongmasad032f2d2019-05-15 08:42:44 -0700537 mLockedHandle = C2HandleGralloc::WrapAndMoveNativeHandle(
538 mBuffer, mInfo3.mapperInfo.width, mInfo3.mapperInfo.height,
539 (uint32_t)mInfo3.mapperInfo.format, mInfo3.mapperInfo.usage,
540 mInfo3.stride, generation, igbp_id, igbp_slot);
Marissa Wall8806edc2019-06-21 09:50:47 -0700541 } else {
542 mLockedHandle = C2HandleGralloc::WrapAndMoveNativeHandle(
543 mBuffer, mInfo4.mapperInfo.width, mInfo4.mapperInfo.height,
544 (uint32_t)mInfo4.mapperInfo.format, mInfo4.mapperInfo.usage,
545 mInfo4.stride, generation, igbp_id, igbp_slot);
Pawin Vongmasad032f2d2019-05-15 08:42:44 -0700546 }
Pawin Vongmasa36653902018-11-15 00:10:25 -0800547 }
548
Marissa Wall8806edc2019-06-21 09:50:47 -0700549 PixelFormat4 format;
550 if (mMapper2) {
551 format = PixelFormat4(mInfo2.mapperInfo.format);
552 } else if (mMapper3) {
553 format = PixelFormat4(mInfo3.mapperInfo.format);
554 } else {
555 format = PixelFormat4(mInfo4.mapperInfo.format);
556 }
Pawin Vongmasad032f2d2019-05-15 08:42:44 -0700557 switch (format) {
Marissa Wall8806edc2019-06-21 09:50:47 -0700558 case PixelFormat4::RGBA_1010102: {
Lajos Molnar35d36cb2018-10-12 15:10:56 -0700559 // TRICKY: this is used for media as YUV444 in the case when it is queued directly to a
560 // Surface. In all other cases it is RGBA. We don't know which case it is here, so
561 // default to YUV for now.
562 void *pointer = nullptr;
Pawin Vongmasad032f2d2019-05-15 08:42:44 -0700563 if (mMapper2) {
564 if (!mMapper2->lock(
565 const_cast<native_handle_t *>(mBuffer),
566 grallocUsage,
567 { (int32_t)rect.left, (int32_t)rect.top,
568 (int32_t)rect.width, (int32_t)rect.height },
569 // TODO: fence
570 hidl_handle(),
571 [&err, &pointer](const auto &maperr, const auto &mapPointer) {
572 err = maperr2error(maperr);
573 if (err == C2_OK) {
574 pointer = mapPointer;
575 }
576 }).isOk()) {
577 ALOGE("failed transaction: lock(RGBA_1010102)");
578 return C2_CORRUPTED;
579 }
Marissa Wall8806edc2019-06-21 09:50:47 -0700580 } else if (mMapper3) {
Pawin Vongmasad032f2d2019-05-15 08:42:44 -0700581 if (!mMapper3->lock(
582 const_cast<native_handle_t *>(mBuffer),
583 grallocUsage,
584 { (int32_t)rect.left, (int32_t)rect.top,
585 (int32_t)rect.width, (int32_t)rect.height },
586 // TODO: fence
587 hidl_handle(),
588 [&err, &pointer](const auto &maperr, const auto &mapPointer,
589 int32_t bytesPerPixel, int32_t bytesPerStride) {
590 err = maperr2error(maperr);
591 if (err == C2_OK) {
592 pointer = mapPointer;
593 }
594 (void)bytesPerPixel;
595 (void)bytesPerStride;
596 }).isOk()) {
597 ALOGE("failed transaction: lock(RGBA_1010102) (@3.0)");
598 return C2_CORRUPTED;
599 }
Marissa Wall8806edc2019-06-21 09:50:47 -0700600 } else {
601 if (!mMapper4->lock(
602 const_cast<native_handle_t *>(mBuffer),
603 grallocUsage,
604 { (int32_t)rect.left, (int32_t)rect.top,
605 (int32_t)rect.width, (int32_t)rect.height },
606 // TODO: fence
607 hidl_handle(),
608 [&err, &pointer](const auto &maperr, const auto &mapPointer,
609 int32_t bytesPerPixel, int32_t bytesPerStride) {
610 err = maperr2error(maperr);
611 if (err == C2_OK) {
612 pointer = mapPointer;
613 }
614 (void)bytesPerPixel;
615 (void)bytesPerStride;
616 }).isOk()) {
617 ALOGE("failed transaction: lock(RGBA_1010102) (@4.0)");
618 return C2_CORRUPTED;
619 }
Pawin Vongmasad032f2d2019-05-15 08:42:44 -0700620 }
Lajos Molnar35d36cb2018-10-12 15:10:56 -0700621 if (err != C2_OK) {
622 ALOGD("lock failed: %d", err);
623 return err;
624 }
625 // treat as 32-bit values
626 addr[C2PlanarLayout::PLANE_Y] = (uint8_t *)pointer;
627 addr[C2PlanarLayout::PLANE_U] = (uint8_t *)pointer;
628 addr[C2PlanarLayout::PLANE_V] = (uint8_t *)pointer;
629 addr[C2PlanarLayout::PLANE_A] = (uint8_t *)pointer;
630 layout->type = C2PlanarLayout::TYPE_YUVA;
631 layout->numPlanes = 4;
632 layout->rootPlanes = 1;
Marissa Wall8806edc2019-06-21 09:50:47 -0700633 int32_t stride;
634 if (mMapper2) {
635 stride = int32_t(mInfo2.stride);
Chong Zhang7875f682019-10-29 17:06:14 -0700636 } else if (mMapper3) {
Marissa Wall8806edc2019-06-21 09:50:47 -0700637 stride = int32_t(mInfo3.stride);
638 } else {
639 stride = int32_t(mInfo4.stride);
640 }
Lajos Molnar35d36cb2018-10-12 15:10:56 -0700641 layout->planes[C2PlanarLayout::PLANE_Y] = {
642 C2PlaneInfo::CHANNEL_Y, // channel
643 4, // colInc
Pawin Vongmasad032f2d2019-05-15 08:42:44 -0700644 4 * stride, // rowInc
Lajos Molnar35d36cb2018-10-12 15:10:56 -0700645 1, // mColSampling
646 1, // mRowSampling
647 32, // allocatedDepth
648 10, // bitDepth
649 10, // rightShift
650 C2PlaneInfo::LITTLE_END, // endianness
651 C2PlanarLayout::PLANE_Y, // rootIx
652 0, // offset
653 };
654 layout->planes[C2PlanarLayout::PLANE_U] = {
655 C2PlaneInfo::CHANNEL_CB, // channel
656 4, // colInc
Pawin Vongmasad032f2d2019-05-15 08:42:44 -0700657 4 * stride, // rowInc
Lajos Molnar35d36cb2018-10-12 15:10:56 -0700658 1, // mColSampling
659 1, // mRowSampling
660 32, // allocatedDepth
661 10, // bitDepth
662 0, // rightShift
663 C2PlaneInfo::LITTLE_END, // endianness
664 C2PlanarLayout::PLANE_Y, // rootIx
665 0, // offset
666 };
667 layout->planes[C2PlanarLayout::PLANE_V] = {
668 C2PlaneInfo::CHANNEL_CR, // channel
669 4, // colInc
Pawin Vongmasad032f2d2019-05-15 08:42:44 -0700670 4 * stride, // rowInc
Lajos Molnar35d36cb2018-10-12 15:10:56 -0700671 1, // mColSampling
672 1, // mRowSampling
673 32, // allocatedDepth
674 10, // bitDepth
675 20, // rightShift
676 C2PlaneInfo::LITTLE_END, // endianness
677 C2PlanarLayout::PLANE_Y, // rootIx
678 0, // offset
679 };
680 layout->planes[C2PlanarLayout::PLANE_A] = {
681 C2PlaneInfo::CHANNEL_A, // channel
682 4, // colInc
Pawin Vongmasad032f2d2019-05-15 08:42:44 -0700683 4 * stride, // rowInc
Lajos Molnar35d36cb2018-10-12 15:10:56 -0700684 1, // mColSampling
685 1, // mRowSampling
686 32, // allocatedDepth
687 2, // bitDepth
688 30, // rightShift
689 C2PlaneInfo::LITTLE_END, // endianness
690 C2PlanarLayout::PLANE_Y, // rootIx
691 0, // offset
692 };
693 break;
694 }
Pawin Vongmasa36653902018-11-15 00:10:25 -0800695
Marissa Wall8806edc2019-06-21 09:50:47 -0700696 case PixelFormat4::RGBA_8888:
Lajos Molnar35d36cb2018-10-12 15:10:56 -0700697 // TODO: alpha channel
698 // fall-through
Marissa Wall8806edc2019-06-21 09:50:47 -0700699 case PixelFormat4::RGBX_8888: {
Lajos Molnar35d36cb2018-10-12 15:10:56 -0700700 void *pointer = nullptr;
Pawin Vongmasad032f2d2019-05-15 08:42:44 -0700701 if (mMapper2) {
702 if (!mMapper2->lock(
703 const_cast<native_handle_t *>(mBuffer),
704 grallocUsage,
705 { (int32_t)rect.left, (int32_t)rect.top,
706 (int32_t)rect.width, (int32_t)rect.height },
707 // TODO: fence
708 hidl_handle(),
709 [&err, &pointer](const auto &maperr, const auto &mapPointer) {
710 err = maperr2error(maperr);
711 if (err == C2_OK) {
712 pointer = mapPointer;
713 }
714 }).isOk()) {
715 ALOGE("failed transaction: lock(RGBA_8888)");
716 return C2_CORRUPTED;
717 }
Marissa Wall8806edc2019-06-21 09:50:47 -0700718 } else if (mMapper3) {
Pawin Vongmasad032f2d2019-05-15 08:42:44 -0700719 if (!mMapper3->lock(
720 const_cast<native_handle_t *>(mBuffer),
721 grallocUsage,
722 { (int32_t)rect.left, (int32_t)rect.top,
723 (int32_t)rect.width, (int32_t)rect.height },
724 // TODO: fence
725 hidl_handle(),
726 [&err, &pointer](const auto &maperr, const auto &mapPointer,
727 int32_t bytesPerPixel, int32_t bytesPerStride) {
728 err = maperr2error(maperr);
729 if (err == C2_OK) {
730 pointer = mapPointer;
731 }
732 (void)bytesPerPixel;
733 (void)bytesPerStride;
734 }).isOk()) {
735 ALOGE("failed transaction: lock(RGBA_8888) (@3.0)");
736 return C2_CORRUPTED;
737 }
Marissa Wall8806edc2019-06-21 09:50:47 -0700738 } else {
739 if (!mMapper4->lock(
740 const_cast<native_handle_t *>(mBuffer),
741 grallocUsage,
742 { (int32_t)rect.left, (int32_t)rect.top,
743 (int32_t)rect.width, (int32_t)rect.height },
744 // TODO: fence
745 hidl_handle(),
746 [&err, &pointer](const auto &maperr, const auto &mapPointer,
747 int32_t bytesPerPixel, int32_t bytesPerStride) {
748 err = maperr2error(maperr);
749 if (err == C2_OK) {
750 pointer = mapPointer;
751 }
752 (void)bytesPerPixel;
753 (void)bytesPerStride;
754 }).isOk()) {
755 ALOGE("failed transaction: lock(RGBA_8888) (@4.0)");
756 return C2_CORRUPTED;
757 }
Pawin Vongmasad032f2d2019-05-15 08:42:44 -0700758 }
Lajos Molnar35d36cb2018-10-12 15:10:56 -0700759 if (err != C2_OK) {
760 ALOGD("lock failed: %d", err);
761 return err;
762 }
763 addr[C2PlanarLayout::PLANE_R] = (uint8_t *)pointer;
764 addr[C2PlanarLayout::PLANE_G] = (uint8_t *)pointer + 1;
765 addr[C2PlanarLayout::PLANE_B] = (uint8_t *)pointer + 2;
766 layout->type = C2PlanarLayout::TYPE_RGB;
767 layout->numPlanes = 3;
768 layout->rootPlanes = 1;
Marissa Wall8806edc2019-06-21 09:50:47 -0700769 int32_t stride;
770 if (mMapper2) {
771 stride = int32_t(mInfo2.stride);
Chong Zhangfad4c792019-10-30 06:37:48 -0700772 } else if (mMapper3) {
Marissa Wall8806edc2019-06-21 09:50:47 -0700773 stride = int32_t(mInfo3.stride);
774 } else {
775 stride = int32_t(mInfo4.stride);
776 }
Lajos Molnar35d36cb2018-10-12 15:10:56 -0700777 layout->planes[C2PlanarLayout::PLANE_R] = {
778 C2PlaneInfo::CHANNEL_R, // channel
779 4, // colInc
Pawin Vongmasad032f2d2019-05-15 08:42:44 -0700780 4 * stride, // rowInc
Lajos Molnar35d36cb2018-10-12 15:10:56 -0700781 1, // mColSampling
782 1, // mRowSampling
783 8, // allocatedDepth
784 8, // bitDepth
785 0, // rightShift
786 C2PlaneInfo::NATIVE, // endianness
787 C2PlanarLayout::PLANE_R, // rootIx
788 0, // offset
789 };
790 layout->planes[C2PlanarLayout::PLANE_G] = {
791 C2PlaneInfo::CHANNEL_G, // channel
792 4, // colInc
Pawin Vongmasad032f2d2019-05-15 08:42:44 -0700793 4 * stride, // rowInc
Lajos Molnar35d36cb2018-10-12 15:10:56 -0700794 1, // mColSampling
795 1, // mRowSampling
796 8, // allocatedDepth
797 8, // bitDepth
798 0, // rightShift
799 C2PlaneInfo::NATIVE, // endianness
800 C2PlanarLayout::PLANE_R, // rootIx
801 1, // offset
802 };
803 layout->planes[C2PlanarLayout::PLANE_B] = {
804 C2PlaneInfo::CHANNEL_B, // channel
805 4, // colInc
Pawin Vongmasad032f2d2019-05-15 08:42:44 -0700806 4 * stride, // rowInc
Lajos Molnar35d36cb2018-10-12 15:10:56 -0700807 1, // mColSampling
808 1, // mRowSampling
809 8, // allocatedDepth
810 8, // bitDepth
811 0, // rightShift
812 C2PlaneInfo::NATIVE, // endianness
813 C2PlanarLayout::PLANE_R, // rootIx
814 2, // offset
815 };
816 break;
817 }
818
Marissa Wall8806edc2019-06-21 09:50:47 -0700819 case PixelFormat4::YCBCR_420_888:
Lajos Molnar35d36cb2018-10-12 15:10:56 -0700820 // fall-through
Marissa Wall8806edc2019-06-21 09:50:47 -0700821 case PixelFormat4::YV12:
Lajos Molnar35d36cb2018-10-12 15:10:56 -0700822 // fall-through
823 default: {
Pawin Vongmasad032f2d2019-05-15 08:42:44 -0700824 struct YCbCrLayout {
825 void* y;
826 void* cb;
827 void* cr;
828 uint32_t yStride;
829 uint32_t cStride;
830 uint32_t chromaStep;
831 };
Pawin Vongmasa36653902018-11-15 00:10:25 -0800832 YCbCrLayout ycbcrLayout;
Pawin Vongmasad032f2d2019-05-15 08:42:44 -0700833 if (mMapper2) {
834 if (!mMapper2->lockYCbCr(
835 const_cast<native_handle_t *>(mBuffer), grallocUsage,
836 { (int32_t)rect.left, (int32_t)rect.top,
837 (int32_t)rect.width, (int32_t)rect.height },
838 // TODO: fence
839 hidl_handle(),
840 [&err, &ycbcrLayout](const auto &maperr, const auto &mapLayout) {
841 err = maperr2error(maperr);
842 if (err == C2_OK) {
843 ycbcrLayout = YCbCrLayout{
844 mapLayout.y,
845 mapLayout.cb,
846 mapLayout.cr,
847 mapLayout.yStride,
848 mapLayout.cStride,
849 mapLayout.chromaStep};
850 }
851 }).isOk()) {
852 ALOGE("failed transaction: lockYCbCr");
853 return C2_CORRUPTED;
854 }
Marissa Wall8806edc2019-06-21 09:50:47 -0700855 } else if (mMapper3) {
Pawin Vongmasad032f2d2019-05-15 08:42:44 -0700856 if (!mMapper3->lockYCbCr(
857 const_cast<native_handle_t *>(mBuffer), grallocUsage,
858 { (int32_t)rect.left, (int32_t)rect.top,
859 (int32_t)rect.width, (int32_t)rect.height },
860 // TODO: fence
861 hidl_handle(),
862 [&err, &ycbcrLayout](const auto &maperr, const auto &mapLayout) {
863 err = maperr2error(maperr);
864 if (err == C2_OK) {
865 ycbcrLayout = YCbCrLayout{
866 mapLayout.y,
867 mapLayout.cb,
868 mapLayout.cr,
869 mapLayout.yStride,
870 mapLayout.cStride,
871 mapLayout.chromaStep};
872 }
873 }).isOk()) {
874 ALOGE("failed transaction: lockYCbCr (@3.0)");
875 return C2_CORRUPTED;
876 }
Marissa Wall8806edc2019-06-21 09:50:47 -0700877 } else {
878 if (!mMapper4->lockYCbCr(
879 const_cast<native_handle_t *>(mBuffer), grallocUsage,
880 { (int32_t)rect.left, (int32_t)rect.top,
881 (int32_t)rect.width, (int32_t)rect.height },
882 // TODO: fence
883 hidl_handle(),
884 [&err, &ycbcrLayout](const auto &maperr, const auto &mapLayout) {
885 err = maperr2error(maperr);
886 if (err == C2_OK) {
887 ycbcrLayout = YCbCrLayout{
888 mapLayout.y,
889 mapLayout.cb,
890 mapLayout.cr,
891 mapLayout.yStride,
892 mapLayout.cStride,
893 mapLayout.chromaStep};
894 }
895 }).isOk()) {
896 ALOGE("failed transaction: lockYCbCr (@4.0)");
897 return C2_CORRUPTED;
898 }
Pawin Vongmasad032f2d2019-05-15 08:42:44 -0700899 }
Pawin Vongmasa36653902018-11-15 00:10:25 -0800900 if (err != C2_OK) {
901 ALOGD("lockYCbCr failed: %d", err);
902 return err;
903 }
904 addr[C2PlanarLayout::PLANE_Y] = (uint8_t *)ycbcrLayout.y;
905 addr[C2PlanarLayout::PLANE_U] = (uint8_t *)ycbcrLayout.cb;
906 addr[C2PlanarLayout::PLANE_V] = (uint8_t *)ycbcrLayout.cr;
907 layout->type = C2PlanarLayout::TYPE_YUV;
908 layout->numPlanes = 3;
909 layout->rootPlanes = 3;
910 layout->planes[C2PlanarLayout::PLANE_Y] = {
911 C2PlaneInfo::CHANNEL_Y, // channel
912 1, // colInc
913 (int32_t)ycbcrLayout.yStride, // rowInc
914 1, // mColSampling
915 1, // mRowSampling
916 8, // allocatedDepth
917 8, // bitDepth
918 0, // rightShift
919 C2PlaneInfo::NATIVE, // endianness
920 C2PlanarLayout::PLANE_Y, // rootIx
921 0, // offset
922 };
923 layout->planes[C2PlanarLayout::PLANE_U] = {
924 C2PlaneInfo::CHANNEL_CB, // channel
925 (int32_t)ycbcrLayout.chromaStep, // colInc
926 (int32_t)ycbcrLayout.cStride, // rowInc
927 2, // mColSampling
928 2, // mRowSampling
929 8, // allocatedDepth
930 8, // bitDepth
931 0, // rightShift
932 C2PlaneInfo::NATIVE, // endianness
933 C2PlanarLayout::PLANE_U, // rootIx
934 0, // offset
935 };
936 layout->planes[C2PlanarLayout::PLANE_V] = {
937 C2PlaneInfo::CHANNEL_CR, // channel
938 (int32_t)ycbcrLayout.chromaStep, // colInc
939 (int32_t)ycbcrLayout.cStride, // rowInc
940 2, // mColSampling
941 2, // mRowSampling
942 8, // allocatedDepth
943 8, // bitDepth
944 0, // rightShift
945 C2PlaneInfo::NATIVE, // endianness
946 C2PlanarLayout::PLANE_V, // rootIx
947 0, // offset
948 };
949 // handle interleaved formats
950 intptr_t uvOffset = addr[C2PlanarLayout::PLANE_V] - addr[C2PlanarLayout::PLANE_U];
951 if (uvOffset > 0 && uvOffset < (intptr_t)ycbcrLayout.chromaStep) {
952 layout->rootPlanes = 2;
953 layout->planes[C2PlanarLayout::PLANE_V].rootIx = C2PlanarLayout::PLANE_U;
954 layout->planes[C2PlanarLayout::PLANE_V].offset = uvOffset;
955 } else if (uvOffset < 0 && uvOffset > -(intptr_t)ycbcrLayout.chromaStep) {
956 layout->rootPlanes = 2;
957 layout->planes[C2PlanarLayout::PLANE_U].rootIx = C2PlanarLayout::PLANE_V;
958 layout->planes[C2PlanarLayout::PLANE_U].offset = -uvOffset;
959 }
960 break;
961 }
Pawin Vongmasa36653902018-11-15 00:10:25 -0800962 }
963 mLocked = true;
964
965 return C2_OK;
966}
967
968c2_status_t C2AllocationGralloc::unmap(
969 uint8_t **addr, C2Rect rect, C2Fence *fence /* nullable */) {
970 // TODO: check addr and size, use fence
971 (void)addr;
972 (void)rect;
973
974 std::lock_guard<std::mutex> lock(mMappedLock);
975 c2_status_t err = C2_OK;
Pawin Vongmasad032f2d2019-05-15 08:42:44 -0700976 if (mMapper2) {
977 if (!mMapper2->unlock(
978 const_cast<native_handle_t *>(mBuffer),
979 [&err, &fence](const auto &maperr, const auto &releaseFence) {
980 // TODO
981 (void) fence;
982 (void) releaseFence;
983 err = maperr2error(maperr);
984 if (err == C2_OK) {
985 // TODO: fence
986 }
987 }).isOk()) {
988 ALOGE("failed transaction: unlock");
989 return C2_CORRUPTED;
990 }
Marissa Wall8806edc2019-06-21 09:50:47 -0700991 } else if (mMapper3) {
Pawin Vongmasad032f2d2019-05-15 08:42:44 -0700992 if (!mMapper3->unlock(
993 const_cast<native_handle_t *>(mBuffer),
994 [&err, &fence](const auto &maperr, const auto &releaseFence) {
995 // TODO
996 (void) fence;
997 (void) releaseFence;
998 err = maperr2error(maperr);
999 if (err == C2_OK) {
1000 // TODO: fence
1001 }
1002 }).isOk()) {
1003 ALOGE("failed transaction: unlock (@3.0)");
1004 return C2_CORRUPTED;
1005 }
Marissa Wall8806edc2019-06-21 09:50:47 -07001006 } else {
1007 if (!mMapper4->unlock(
1008 const_cast<native_handle_t *>(mBuffer),
1009 [&err, &fence](const auto &maperr, const auto &releaseFence) {
1010 // TODO
1011 (void) fence;
1012 (void) releaseFence;
1013 err = maperr2error(maperr);
1014 if (err == C2_OK) {
1015 // TODO: fence
1016 }
1017 }).isOk()) {
1018 ALOGE("failed transaction: unlock (@4.0)");
1019 return C2_CORRUPTED;
1020 }
Pawin Vongmasad032f2d2019-05-15 08:42:44 -07001021 }
Pawin Vongmasa36653902018-11-15 00:10:25 -08001022 if (err == C2_OK) {
1023 mLocked = false;
1024 }
1025 return err;
1026}
1027
1028bool C2AllocationGralloc::equals(const std::shared_ptr<const C2GraphicAllocation> &other) const {
1029 return other && other->handle() == handle();
1030}
1031
1032/* ===================================== GRALLOC ALLOCATOR ==================================== */
1033class C2AllocatorGralloc::Impl {
1034public:
1035 Impl(id_t id, bool bufferQueue);
1036
1037 id_t getId() const {
1038 return mTraits->id;
1039 }
1040
1041 C2String getName() const {
1042 return mTraits->name;
1043 }
1044
1045 std::shared_ptr<const C2Allocator::Traits> getTraits() const {
1046 return mTraits;
1047 }
1048
1049 c2_status_t newGraphicAllocation(
1050 uint32_t width, uint32_t height, uint32_t format, const C2MemoryUsage &usage,
1051 std::shared_ptr<C2GraphicAllocation> *allocation);
1052
1053 c2_status_t priorGraphicAllocation(
1054 const C2Handle *handle,
1055 std::shared_ptr<C2GraphicAllocation> *allocation);
1056
1057 c2_status_t status() const { return mInit; }
1058
1059private:
1060 std::shared_ptr<C2Allocator::Traits> mTraits;
1061 c2_status_t mInit;
Pawin Vongmasad032f2d2019-05-15 08:42:44 -07001062 sp<IAllocator2> mAllocator2;
1063 sp<IMapper2> mMapper2;
1064 sp<IAllocator3> mAllocator3;
1065 sp<IMapper3> mMapper3;
Marissa Wall8806edc2019-06-21 09:50:47 -07001066 sp<IAllocator4> mAllocator4;
1067 sp<IMapper4> mMapper4;
Pawin Vongmasa36653902018-11-15 00:10:25 -08001068 const bool mBufferQueue;
1069};
1070
1071void _UnwrapNativeCodec2GrallocMetadata(
1072 const C2Handle *const handle,
1073 uint32_t *width, uint32_t *height, uint32_t *format,uint64_t *usage, uint32_t *stride,
1074 uint32_t *generation, uint64_t *igbp_id, uint32_t *igbp_slot) {
1075 (void)C2HandleGralloc::Import(handle, width, height, format, usage, stride,
1076 generation, igbp_id, igbp_slot);
1077}
1078
1079C2AllocatorGralloc::Impl::Impl(id_t id, bool bufferQueue)
1080 : mInit(C2_OK), mBufferQueue(bufferQueue) {
1081 // TODO: get this from allocator
1082 C2MemoryUsage minUsage = { 0, 0 }, maxUsage = { ~(uint64_t)0, ~(uint64_t)0 };
1083 Traits traits = { "android.allocator.gralloc", id, C2Allocator::GRAPHIC, minUsage, maxUsage };
1084 mTraits = std::make_shared<C2Allocator::Traits>(traits);
1085
1086 // gralloc allocator is a singleton, so all objects share a global service
Marissa Wall8806edc2019-06-21 09:50:47 -07001087 mAllocator4 = IAllocator4::getService();
1088 mMapper4 = IMapper4::getService();
1089 if (!mAllocator4 || !mMapper4) {
1090 mAllocator4 = nullptr;
1091 mMapper4 = nullptr;
1092 mAllocator3 = IAllocator3::getService();
1093 mMapper3 = IMapper3::getService();
1094 if (!mAllocator3 || !mMapper3) {
1095 mAllocator3 = nullptr;
1096 mMapper3 = nullptr;
1097 mAllocator2 = IAllocator2::getService();
1098 mMapper2 = IMapper2::getService();
1099 if (!mAllocator2 || !mMapper2) {
1100 mAllocator2 = nullptr;
1101 mMapper2 = nullptr;
1102 mInit = C2_CORRUPTED;
1103 }
Pawin Vongmasad032f2d2019-05-15 08:42:44 -07001104 }
Pawin Vongmasa36653902018-11-15 00:10:25 -08001105 }
1106}
1107
1108c2_status_t C2AllocatorGralloc::Impl::newGraphicAllocation(
1109 uint32_t width, uint32_t height, uint32_t format, const C2MemoryUsage &usage,
1110 std::shared_ptr<C2GraphicAllocation> *allocation) {
1111 uint64_t grallocUsage = static_cast<C2AndroidMemoryUsage>(usage).asGrallocUsage();
1112 ALOGV("allocating buffer with usage %#llx => %#llx",
1113 (long long)usage.expected, (long long)grallocUsage);
1114
Pawin Vongmasa36653902018-11-15 00:10:25 -08001115 c2_status_t err = C2_OK;
Pawin Vongmasad032f2d2019-05-15 08:42:44 -07001116 hidl_handle buffer{};
1117
1118 if (mMapper2) {
1119 BufferDescriptorInfo2 info = {
1120 {
1121 width,
1122 height,
1123 1u, // layerCount
1124 PixelFormat2(format),
1125 grallocUsage,
1126 },
1127 0u, // stride placeholder
1128 };
1129 BufferDescriptor2 desc;
1130 if (!mMapper2->createDescriptor(
1131 info.mapperInfo, [&err, &desc](const auto &maperr, const auto &descriptor) {
1132 err = maperr2error(maperr);
1133 if (err == C2_OK) {
1134 desc = descriptor;
1135 }
1136 }).isOk()) {
1137 ALOGE("failed transaction: createDescriptor");
1138 return C2_CORRUPTED;
1139 }
1140 if (err != C2_OK) {
1141 return err;
1142 }
1143
1144 // IAllocator shares IMapper error codes.
1145 if (!mAllocator2->allocate(
1146 desc,
1147 1u,
1148 [&err, &buffer, &info](const auto &maperr, const auto &stride, auto &buffers) {
1149 err = maperr2error(maperr);
1150 if (err != C2_OK) {
1151 return;
1152 }
1153 if (buffers.size() != 1u) {
1154 err = C2_CORRUPTED;
1155 return;
1156 }
1157 info.stride = stride;
1158 buffer = buffers[0];
1159 }).isOk()) {
1160 ALOGE("failed transaction: allocate");
1161 return C2_CORRUPTED;
1162 }
1163 if (err != C2_OK) {
1164 return err;
1165 }
1166 allocation->reset(new C2AllocationGralloc(
1167 info, mMapper2, buffer,
1168 C2HandleGralloc::WrapAndMoveNativeHandle(
1169 buffer.getNativeHandle(),
1170 width, height,
1171 format, grallocUsage, info.stride,
1172 0, 0, mBufferQueue ? ~0 : 0),
1173 mTraits->id));
1174 return C2_OK;
Marissa Wall8806edc2019-06-21 09:50:47 -07001175 } else if (mMapper3) {
Pawin Vongmasad032f2d2019-05-15 08:42:44 -07001176 BufferDescriptorInfo3 info = {
1177 {
1178 width,
1179 height,
1180 1u, // layerCount
Marissa Wall8806edc2019-06-21 09:50:47 -07001181 PixelFormat4(format),
Pawin Vongmasad032f2d2019-05-15 08:42:44 -07001182 grallocUsage,
1183 },
1184 0u, // stride placeholder
1185 };
1186 BufferDescriptor3 desc;
1187 if (!mMapper3->createDescriptor(
1188 info.mapperInfo, [&err, &desc](const auto &maperr, const auto &descriptor) {
1189 err = maperr2error(maperr);
1190 if (err == C2_OK) {
1191 desc = descriptor;
1192 }
1193 }).isOk()) {
1194 ALOGE("failed transaction: createDescriptor");
1195 return C2_CORRUPTED;
1196 }
1197 if (err != C2_OK) {
1198 return err;
1199 }
1200
1201 // IAllocator shares IMapper error codes.
1202 if (!mAllocator3->allocate(
1203 desc,
1204 1u,
1205 [&err, &buffer, &info](const auto &maperr, const auto &stride, auto &buffers) {
1206 err = maperr2error(maperr);
1207 if (err != C2_OK) {
1208 return;
1209 }
1210 if (buffers.size() != 1u) {
1211 err = C2_CORRUPTED;
1212 return;
1213 }
1214 info.stride = stride;
1215 buffer = buffers[0];
1216 }).isOk()) {
1217 ALOGE("failed transaction: allocate");
1218 return C2_CORRUPTED;
1219 }
1220 if (err != C2_OK) {
1221 return err;
1222 }
1223 allocation->reset(new C2AllocationGralloc(
1224 info, mMapper3, buffer,
1225 C2HandleGralloc::WrapAndMoveNativeHandle(
1226 buffer.getNativeHandle(),
1227 width, height,
1228 format, grallocUsage, info.stride,
1229 0, 0, mBufferQueue ? ~0 : 0),
1230 mTraits->id));
1231 return C2_OK;
Marissa Wall8806edc2019-06-21 09:50:47 -07001232 } else {
1233 BufferDescriptorInfo4 info = {
1234 {
Marissa Wallc759fc52019-11-06 10:11:11 -08001235 "C2GrallocAllocation",
Marissa Wall8806edc2019-06-21 09:50:47 -07001236 width,
1237 height,
1238 1u, // layerCount
1239 PixelFormat4(format),
1240 grallocUsage,
1241 },
1242 0u, // stride placeholder
1243 };
1244 BufferDescriptor4 desc;
1245 if (!mMapper4->createDescriptor(
1246 info.mapperInfo, [&err, &desc](const auto &maperr, const auto &descriptor) {
1247 err = maperr2error(maperr);
1248 if (err == C2_OK) {
1249 desc = descriptor;
1250 }
1251 }).isOk()) {
1252 ALOGE("failed transaction: createDescriptor");
1253 return C2_CORRUPTED;
1254 }
1255 if (err != C2_OK) {
1256 return err;
1257 }
1258
1259 // IAllocator shares IMapper error codes.
1260 if (!mAllocator4->allocate(
1261 desc,
1262 1u,
1263 [&err, &buffer, &info](const auto &maperr, const auto &stride, auto &buffers) {
1264 err = maperr2error(maperr);
1265 if (err != C2_OK) {
1266 return;
1267 }
1268 if (buffers.size() != 1u) {
1269 err = C2_CORRUPTED;
1270 return;
1271 }
1272 info.stride = stride;
1273 buffer = buffers[0];
1274 }).isOk()) {
1275 ALOGE("failed transaction: allocate");
1276 return C2_CORRUPTED;
1277 }
1278 if (err != C2_OK) {
1279 return err;
1280 }
1281 allocation->reset(new C2AllocationGralloc(
1282 info, mMapper4, buffer,
1283 C2HandleGralloc::WrapAndMoveNativeHandle(
1284 buffer.getNativeHandle(),
1285 width, height,
1286 format, grallocUsage, info.stride,
1287 0, 0, mBufferQueue ? ~0 : 0),
1288 mTraits->id));
1289 return C2_OK;
Pawin Vongmasa36653902018-11-15 00:10:25 -08001290 }
Pawin Vongmasa36653902018-11-15 00:10:25 -08001291}
1292
1293c2_status_t C2AllocatorGralloc::Impl::priorGraphicAllocation(
1294 const C2Handle *handle,
1295 std::shared_ptr<C2GraphicAllocation> *allocation) {
Pawin Vongmasad032f2d2019-05-15 08:42:44 -07001296 if (mMapper2) {
1297 BufferDescriptorInfo2 info;
1298 info.mapperInfo.layerCount = 1u;
1299 uint32_t generation;
1300 uint64_t igbp_id;
1301 uint32_t igbp_slot;
1302 const C2HandleGralloc *grallocHandle = C2HandleGralloc::Import(
1303 handle,
1304 &info.mapperInfo.width, &info.mapperInfo.height,
1305 (uint32_t *)&info.mapperInfo.format,
1306 (uint64_t *)&info.mapperInfo.usage,
1307 &info.stride,
1308 &generation, &igbp_id, &igbp_slot);
1309 if (grallocHandle == nullptr) {
1310 return C2_BAD_VALUE;
1311 }
1312
1313 hidl_handle hidlHandle;
1314 hidlHandle.setTo(C2HandleGralloc::UnwrapNativeHandle(grallocHandle), true);
1315
1316 allocation->reset(new C2AllocationGralloc(
1317 info, mMapper2, hidlHandle, grallocHandle, mTraits->id));
1318 return C2_OK;
Marissa Wall8806edc2019-06-21 09:50:47 -07001319 } else if (mMapper3) {
Pawin Vongmasad032f2d2019-05-15 08:42:44 -07001320 BufferDescriptorInfo3 info;
1321 info.mapperInfo.layerCount = 1u;
1322 uint32_t generation;
1323 uint64_t igbp_id;
1324 uint32_t igbp_slot;
1325 const C2HandleGralloc *grallocHandle = C2HandleGralloc::Import(
1326 handle,
1327 &info.mapperInfo.width, &info.mapperInfo.height,
1328 (uint32_t *)&info.mapperInfo.format,
1329 (uint64_t *)&info.mapperInfo.usage,
1330 &info.stride,
1331 &generation, &igbp_id, &igbp_slot);
1332 if (grallocHandle == nullptr) {
1333 return C2_BAD_VALUE;
1334 }
1335
1336 hidl_handle hidlHandle;
1337 hidlHandle.setTo(C2HandleGralloc::UnwrapNativeHandle(grallocHandle), true);
1338
1339 allocation->reset(new C2AllocationGralloc(
1340 info, mMapper3, hidlHandle, grallocHandle, mTraits->id));
1341 return C2_OK;
Marissa Wall8806edc2019-06-21 09:50:47 -07001342 } else {
1343 BufferDescriptorInfo4 info;
1344 info.mapperInfo.layerCount = 1u;
1345 uint32_t generation;
1346 uint64_t igbp_id;
1347 uint32_t igbp_slot;
1348 const C2HandleGralloc *grallocHandle = C2HandleGralloc::Import(
1349 handle,
1350 &info.mapperInfo.width, &info.mapperInfo.height,
1351 (uint32_t *)&info.mapperInfo.format,
1352 (uint64_t *)&info.mapperInfo.usage,
1353 &info.stride,
1354 &generation, &igbp_id, &igbp_slot);
1355 if (grallocHandle == nullptr) {
1356 return C2_BAD_VALUE;
1357 }
1358
1359 hidl_handle hidlHandle;
1360 hidlHandle.setTo(C2HandleGralloc::UnwrapNativeHandle(grallocHandle), true);
1361
1362 allocation->reset(new C2AllocationGralloc(
1363 info, mMapper4, hidlHandle, grallocHandle, mTraits->id));
1364 return C2_OK;
Pawin Vongmasa36653902018-11-15 00:10:25 -08001365 }
Pawin Vongmasa36653902018-11-15 00:10:25 -08001366}
1367
1368C2AllocatorGralloc::C2AllocatorGralloc(id_t id, bool bufferQueue)
1369 : mImpl(new Impl(id, bufferQueue)) {}
1370
1371C2AllocatorGralloc::~C2AllocatorGralloc() { delete mImpl; }
1372
1373C2Allocator::id_t C2AllocatorGralloc::getId() const {
1374 return mImpl->getId();
1375}
1376
1377C2String C2AllocatorGralloc::getName() const {
1378 return mImpl->getName();
1379}
1380
1381std::shared_ptr<const C2Allocator::Traits> C2AllocatorGralloc::getTraits() const {
1382 return mImpl->getTraits();
1383}
1384
1385c2_status_t C2AllocatorGralloc::newGraphicAllocation(
1386 uint32_t width, uint32_t height, uint32_t format, C2MemoryUsage usage,
1387 std::shared_ptr<C2GraphicAllocation> *allocation) {
1388 return mImpl->newGraphicAllocation(width, height, format, usage, allocation);
1389}
1390
1391c2_status_t C2AllocatorGralloc::priorGraphicAllocation(
1392 const C2Handle *handle,
1393 std::shared_ptr<C2GraphicAllocation> *allocation) {
1394 return mImpl->priorGraphicAllocation(handle, allocation);
1395}
1396
1397c2_status_t C2AllocatorGralloc::status() const {
1398 return mImpl->status();
1399}
1400
1401bool C2AllocatorGralloc::isValid(const C2Handle* const o) {
1402 return C2HandleGralloc::isValid(o);
1403}
1404
1405} // namespace android