blob: 78ac35507f09f245b846e8fd0fe2a43808f6f14c [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(),
Marissa Wall469b90a2019-11-06 10:12:43 -0800608 [&err, &pointer](const auto &maperr, const auto &mapPointer) {
Marissa Wall8806edc2019-06-21 09:50:47 -0700609 err = maperr2error(maperr);
610 if (err == C2_OK) {
611 pointer = mapPointer;
612 }
Marissa Wall8806edc2019-06-21 09:50:47 -0700613 }).isOk()) {
614 ALOGE("failed transaction: lock(RGBA_1010102) (@4.0)");
615 return C2_CORRUPTED;
616 }
Pawin Vongmasad032f2d2019-05-15 08:42:44 -0700617 }
Lajos Molnar35d36cb2018-10-12 15:10:56 -0700618 if (err != C2_OK) {
619 ALOGD("lock failed: %d", err);
620 return err;
621 }
622 // treat as 32-bit values
623 addr[C2PlanarLayout::PLANE_Y] = (uint8_t *)pointer;
624 addr[C2PlanarLayout::PLANE_U] = (uint8_t *)pointer;
625 addr[C2PlanarLayout::PLANE_V] = (uint8_t *)pointer;
626 addr[C2PlanarLayout::PLANE_A] = (uint8_t *)pointer;
627 layout->type = C2PlanarLayout::TYPE_YUVA;
628 layout->numPlanes = 4;
629 layout->rootPlanes = 1;
Marissa Wall8806edc2019-06-21 09:50:47 -0700630 int32_t stride;
631 if (mMapper2) {
632 stride = int32_t(mInfo2.stride);
Chong Zhang7875f682019-10-29 17:06:14 -0700633 } else if (mMapper3) {
Marissa Wall8806edc2019-06-21 09:50:47 -0700634 stride = int32_t(mInfo3.stride);
635 } else {
636 stride = int32_t(mInfo4.stride);
637 }
Lajos Molnar35d36cb2018-10-12 15:10:56 -0700638 layout->planes[C2PlanarLayout::PLANE_Y] = {
639 C2PlaneInfo::CHANNEL_Y, // channel
640 4, // colInc
Pawin Vongmasad032f2d2019-05-15 08:42:44 -0700641 4 * stride, // rowInc
Lajos Molnar35d36cb2018-10-12 15:10:56 -0700642 1, // mColSampling
643 1, // mRowSampling
644 32, // allocatedDepth
645 10, // bitDepth
646 10, // rightShift
647 C2PlaneInfo::LITTLE_END, // endianness
648 C2PlanarLayout::PLANE_Y, // rootIx
649 0, // offset
650 };
651 layout->planes[C2PlanarLayout::PLANE_U] = {
652 C2PlaneInfo::CHANNEL_CB, // channel
653 4, // colInc
Pawin Vongmasad032f2d2019-05-15 08:42:44 -0700654 4 * stride, // rowInc
Lajos Molnar35d36cb2018-10-12 15:10:56 -0700655 1, // mColSampling
656 1, // mRowSampling
657 32, // allocatedDepth
658 10, // bitDepth
659 0, // rightShift
660 C2PlaneInfo::LITTLE_END, // endianness
661 C2PlanarLayout::PLANE_Y, // rootIx
662 0, // offset
663 };
664 layout->planes[C2PlanarLayout::PLANE_V] = {
665 C2PlaneInfo::CHANNEL_CR, // channel
666 4, // colInc
Pawin Vongmasad032f2d2019-05-15 08:42:44 -0700667 4 * stride, // rowInc
Lajos Molnar35d36cb2018-10-12 15:10:56 -0700668 1, // mColSampling
669 1, // mRowSampling
670 32, // allocatedDepth
671 10, // bitDepth
672 20, // rightShift
673 C2PlaneInfo::LITTLE_END, // endianness
674 C2PlanarLayout::PLANE_Y, // rootIx
675 0, // offset
676 };
677 layout->planes[C2PlanarLayout::PLANE_A] = {
678 C2PlaneInfo::CHANNEL_A, // channel
679 4, // colInc
Pawin Vongmasad032f2d2019-05-15 08:42:44 -0700680 4 * stride, // rowInc
Lajos Molnar35d36cb2018-10-12 15:10:56 -0700681 1, // mColSampling
682 1, // mRowSampling
683 32, // allocatedDepth
684 2, // bitDepth
685 30, // rightShift
686 C2PlaneInfo::LITTLE_END, // endianness
687 C2PlanarLayout::PLANE_Y, // rootIx
688 0, // offset
689 };
690 break;
691 }
Pawin Vongmasa36653902018-11-15 00:10:25 -0800692
Marissa Wall8806edc2019-06-21 09:50:47 -0700693 case PixelFormat4::RGBA_8888:
Lajos Molnar35d36cb2018-10-12 15:10:56 -0700694 // TODO: alpha channel
695 // fall-through
Marissa Wall8806edc2019-06-21 09:50:47 -0700696 case PixelFormat4::RGBX_8888: {
Lajos Molnar35d36cb2018-10-12 15:10:56 -0700697 void *pointer = nullptr;
Pawin Vongmasad032f2d2019-05-15 08:42:44 -0700698 if (mMapper2) {
699 if (!mMapper2->lock(
700 const_cast<native_handle_t *>(mBuffer),
701 grallocUsage,
702 { (int32_t)rect.left, (int32_t)rect.top,
703 (int32_t)rect.width, (int32_t)rect.height },
704 // TODO: fence
705 hidl_handle(),
706 [&err, &pointer](const auto &maperr, const auto &mapPointer) {
707 err = maperr2error(maperr);
708 if (err == C2_OK) {
709 pointer = mapPointer;
710 }
711 }).isOk()) {
712 ALOGE("failed transaction: lock(RGBA_8888)");
713 return C2_CORRUPTED;
714 }
Marissa Wall8806edc2019-06-21 09:50:47 -0700715 } else if (mMapper3) {
Pawin Vongmasad032f2d2019-05-15 08:42:44 -0700716 if (!mMapper3->lock(
717 const_cast<native_handle_t *>(mBuffer),
718 grallocUsage,
719 { (int32_t)rect.left, (int32_t)rect.top,
720 (int32_t)rect.width, (int32_t)rect.height },
721 // TODO: fence
722 hidl_handle(),
723 [&err, &pointer](const auto &maperr, const auto &mapPointer,
724 int32_t bytesPerPixel, int32_t bytesPerStride) {
725 err = maperr2error(maperr);
726 if (err == C2_OK) {
727 pointer = mapPointer;
728 }
729 (void)bytesPerPixel;
730 (void)bytesPerStride;
731 }).isOk()) {
732 ALOGE("failed transaction: lock(RGBA_8888) (@3.0)");
733 return C2_CORRUPTED;
734 }
Marissa Wall8806edc2019-06-21 09:50:47 -0700735 } else {
736 if (!mMapper4->lock(
737 const_cast<native_handle_t *>(mBuffer),
738 grallocUsage,
739 { (int32_t)rect.left, (int32_t)rect.top,
740 (int32_t)rect.width, (int32_t)rect.height },
741 // TODO: fence
742 hidl_handle(),
Marissa Wall469b90a2019-11-06 10:12:43 -0800743 [&err, &pointer](const auto &maperr, const auto &mapPointer) {
Marissa Wall8806edc2019-06-21 09:50:47 -0700744 err = maperr2error(maperr);
745 if (err == C2_OK) {
746 pointer = mapPointer;
747 }
Marissa Wall8806edc2019-06-21 09:50:47 -0700748 }).isOk()) {
749 ALOGE("failed transaction: lock(RGBA_8888) (@4.0)");
750 return C2_CORRUPTED;
751 }
Pawin Vongmasad032f2d2019-05-15 08:42:44 -0700752 }
Lajos Molnar35d36cb2018-10-12 15:10:56 -0700753 if (err != C2_OK) {
754 ALOGD("lock failed: %d", err);
755 return err;
756 }
757 addr[C2PlanarLayout::PLANE_R] = (uint8_t *)pointer;
758 addr[C2PlanarLayout::PLANE_G] = (uint8_t *)pointer + 1;
759 addr[C2PlanarLayout::PLANE_B] = (uint8_t *)pointer + 2;
760 layout->type = C2PlanarLayout::TYPE_RGB;
761 layout->numPlanes = 3;
762 layout->rootPlanes = 1;
Marissa Wall8806edc2019-06-21 09:50:47 -0700763 int32_t stride;
764 if (mMapper2) {
765 stride = int32_t(mInfo2.stride);
Chong Zhangfad4c792019-10-30 06:37:48 -0700766 } else if (mMapper3) {
Marissa Wall8806edc2019-06-21 09:50:47 -0700767 stride = int32_t(mInfo3.stride);
768 } else {
769 stride = int32_t(mInfo4.stride);
770 }
Lajos Molnar35d36cb2018-10-12 15:10:56 -0700771 layout->planes[C2PlanarLayout::PLANE_R] = {
772 C2PlaneInfo::CHANNEL_R, // channel
773 4, // colInc
Pawin Vongmasad032f2d2019-05-15 08:42:44 -0700774 4 * stride, // rowInc
Lajos Molnar35d36cb2018-10-12 15:10:56 -0700775 1, // mColSampling
776 1, // mRowSampling
777 8, // allocatedDepth
778 8, // bitDepth
779 0, // rightShift
780 C2PlaneInfo::NATIVE, // endianness
781 C2PlanarLayout::PLANE_R, // rootIx
782 0, // offset
783 };
784 layout->planes[C2PlanarLayout::PLANE_G] = {
785 C2PlaneInfo::CHANNEL_G, // channel
786 4, // colInc
Pawin Vongmasad032f2d2019-05-15 08:42:44 -0700787 4 * stride, // rowInc
Lajos Molnar35d36cb2018-10-12 15:10:56 -0700788 1, // mColSampling
789 1, // mRowSampling
790 8, // allocatedDepth
791 8, // bitDepth
792 0, // rightShift
793 C2PlaneInfo::NATIVE, // endianness
794 C2PlanarLayout::PLANE_R, // rootIx
795 1, // offset
796 };
797 layout->planes[C2PlanarLayout::PLANE_B] = {
798 C2PlaneInfo::CHANNEL_B, // channel
799 4, // colInc
Pawin Vongmasad032f2d2019-05-15 08:42:44 -0700800 4 * stride, // rowInc
Lajos Molnar35d36cb2018-10-12 15:10:56 -0700801 1, // mColSampling
802 1, // mRowSampling
803 8, // allocatedDepth
804 8, // bitDepth
805 0, // rightShift
806 C2PlaneInfo::NATIVE, // endianness
807 C2PlanarLayout::PLANE_R, // rootIx
808 2, // offset
809 };
810 break;
811 }
812
Pin-chih Linf72774b2019-11-19 18:26:47 +0800813 case PixelFormat4::BLOB: {
814 void* pointer = nullptr;
815 if (mMapper2) {
816 if (!mMapper2->lock(const_cast<native_handle_t*>(mBuffer), grallocUsage,
817 {(int32_t)rect.left, (int32_t)rect.top, (int32_t)rect.width,
818 (int32_t)rect.height},
819 // TODO: fence
820 hidl_handle(),
821 [&err, &pointer](const auto& maperr, const auto& mapPointer) {
822 err = maperr2error(maperr);
823 if (err == C2_OK) {
824 pointer = mapPointer;
825 }
826 }).isOk()) {
827 ALOGE("failed transaction: lock(BLOB)");
828 return C2_CORRUPTED;
829 }
830 } else if (mMapper3) {
831 if (!mMapper3->lock(
832 const_cast<native_handle_t*>(mBuffer),
833 grallocUsage,
834 { (int32_t)rect.left, (int32_t)rect.top,
835 (int32_t)rect.width, (int32_t)rect.height },
836 // TODO: fence
837 hidl_handle(),
838 [&err, &pointer](const auto &maperr, const auto &mapPointer,
839 int32_t bytesPerPixel, int32_t bytesPerStride) {
840 err = maperr2error(maperr);
841 if (err == C2_OK) {
842 pointer = mapPointer;
843 }
844 (void)bytesPerPixel;
845 (void)bytesPerStride;
846 }).isOk()) {
847 ALOGE("failed transaction: lock(BLOB) (@3.0)");
848 return C2_CORRUPTED;
849 }
850 } else {
851 if (!mMapper4->lock(
852 const_cast<native_handle_t *>(mBuffer),
853 grallocUsage,
854 { (int32_t)rect.left, (int32_t)rect.top,
855 (int32_t)rect.width, (int32_t)rect.height },
856 // TODO: fence
857 hidl_handle(),
858 [&err, &pointer](const auto &maperr, const auto &mapPointer) {
859 err = maperr2error(maperr);
860 if (err == C2_OK) {
861 pointer = mapPointer;
862 }
863 }).isOk()) {
864 ALOGE("failed transaction: lock(BLOB) (@4.0)");
865 return C2_CORRUPTED;
866 }
867 }
868 if (err != C2_OK) {
869 ALOGD("lock failed: %d", err);
870 return err;
871 }
872
873 *addr = static_cast<uint8_t*>(pointer);
874 break;
875 }
876
Marissa Wall8806edc2019-06-21 09:50:47 -0700877 case PixelFormat4::YCBCR_420_888:
Lajos Molnar35d36cb2018-10-12 15:10:56 -0700878 // fall-through
Marissa Wall8806edc2019-06-21 09:50:47 -0700879 case PixelFormat4::YV12:
Lajos Molnar35d36cb2018-10-12 15:10:56 -0700880 // fall-through
881 default: {
Pawin Vongmasad032f2d2019-05-15 08:42:44 -0700882 struct YCbCrLayout {
883 void* y;
884 void* cb;
885 void* cr;
886 uint32_t yStride;
887 uint32_t cStride;
888 uint32_t chromaStep;
889 };
Pawin Vongmasa36653902018-11-15 00:10:25 -0800890 YCbCrLayout ycbcrLayout;
Pawin Vongmasad032f2d2019-05-15 08:42:44 -0700891 if (mMapper2) {
892 if (!mMapper2->lockYCbCr(
893 const_cast<native_handle_t *>(mBuffer), grallocUsage,
894 { (int32_t)rect.left, (int32_t)rect.top,
895 (int32_t)rect.width, (int32_t)rect.height },
896 // TODO: fence
897 hidl_handle(),
898 [&err, &ycbcrLayout](const auto &maperr, const auto &mapLayout) {
899 err = maperr2error(maperr);
900 if (err == C2_OK) {
901 ycbcrLayout = YCbCrLayout{
902 mapLayout.y,
903 mapLayout.cb,
904 mapLayout.cr,
905 mapLayout.yStride,
906 mapLayout.cStride,
907 mapLayout.chromaStep};
908 }
909 }).isOk()) {
910 ALOGE("failed transaction: lockYCbCr");
911 return C2_CORRUPTED;
912 }
Marissa Wall8806edc2019-06-21 09:50:47 -0700913 } else if (mMapper3) {
Pawin Vongmasad032f2d2019-05-15 08:42:44 -0700914 if (!mMapper3->lockYCbCr(
915 const_cast<native_handle_t *>(mBuffer), grallocUsage,
916 { (int32_t)rect.left, (int32_t)rect.top,
917 (int32_t)rect.width, (int32_t)rect.height },
918 // TODO: fence
919 hidl_handle(),
920 [&err, &ycbcrLayout](const auto &maperr, const auto &mapLayout) {
921 err = maperr2error(maperr);
922 if (err == C2_OK) {
923 ycbcrLayout = YCbCrLayout{
924 mapLayout.y,
925 mapLayout.cb,
926 mapLayout.cr,
927 mapLayout.yStride,
928 mapLayout.cStride,
929 mapLayout.chromaStep};
930 }
931 }).isOk()) {
932 ALOGE("failed transaction: lockYCbCr (@3.0)");
933 return C2_CORRUPTED;
934 }
Marissa Wall8806edc2019-06-21 09:50:47 -0700935 } else {
Marissa Wall469b90a2019-11-06 10:12:43 -0800936 // No device currently supports IMapper 4.0 so it is safe to just return an error
937 // code here.
938 //
939 // This will be supported by a combination of lock and BufferMetadata getters.
940 // We are going to refactor all the IAllocator/IMapper versioning code into a
941 // shared library. We will then add the IMapper 4.0 lockYCbCr support then.
942 ALOGE("failed transaction: lockYCbCr (@4.0)");
943 return C2_CORRUPTED;
Pawin Vongmasad032f2d2019-05-15 08:42:44 -0700944 }
Pawin Vongmasa36653902018-11-15 00:10:25 -0800945 if (err != C2_OK) {
946 ALOGD("lockYCbCr failed: %d", err);
947 return err;
948 }
949 addr[C2PlanarLayout::PLANE_Y] = (uint8_t *)ycbcrLayout.y;
950 addr[C2PlanarLayout::PLANE_U] = (uint8_t *)ycbcrLayout.cb;
951 addr[C2PlanarLayout::PLANE_V] = (uint8_t *)ycbcrLayout.cr;
952 layout->type = C2PlanarLayout::TYPE_YUV;
953 layout->numPlanes = 3;
954 layout->rootPlanes = 3;
955 layout->planes[C2PlanarLayout::PLANE_Y] = {
956 C2PlaneInfo::CHANNEL_Y, // channel
957 1, // colInc
958 (int32_t)ycbcrLayout.yStride, // rowInc
959 1, // mColSampling
960 1, // mRowSampling
961 8, // allocatedDepth
962 8, // bitDepth
963 0, // rightShift
964 C2PlaneInfo::NATIVE, // endianness
965 C2PlanarLayout::PLANE_Y, // rootIx
966 0, // offset
967 };
968 layout->planes[C2PlanarLayout::PLANE_U] = {
969 C2PlaneInfo::CHANNEL_CB, // channel
970 (int32_t)ycbcrLayout.chromaStep, // colInc
971 (int32_t)ycbcrLayout.cStride, // rowInc
972 2, // mColSampling
973 2, // mRowSampling
974 8, // allocatedDepth
975 8, // bitDepth
976 0, // rightShift
977 C2PlaneInfo::NATIVE, // endianness
978 C2PlanarLayout::PLANE_U, // rootIx
979 0, // offset
980 };
981 layout->planes[C2PlanarLayout::PLANE_V] = {
982 C2PlaneInfo::CHANNEL_CR, // channel
983 (int32_t)ycbcrLayout.chromaStep, // colInc
984 (int32_t)ycbcrLayout.cStride, // rowInc
985 2, // mColSampling
986 2, // mRowSampling
987 8, // allocatedDepth
988 8, // bitDepth
989 0, // rightShift
990 C2PlaneInfo::NATIVE, // endianness
991 C2PlanarLayout::PLANE_V, // rootIx
992 0, // offset
993 };
994 // handle interleaved formats
995 intptr_t uvOffset = addr[C2PlanarLayout::PLANE_V] - addr[C2PlanarLayout::PLANE_U];
996 if (uvOffset > 0 && uvOffset < (intptr_t)ycbcrLayout.chromaStep) {
997 layout->rootPlanes = 2;
998 layout->planes[C2PlanarLayout::PLANE_V].rootIx = C2PlanarLayout::PLANE_U;
999 layout->planes[C2PlanarLayout::PLANE_V].offset = uvOffset;
1000 } else if (uvOffset < 0 && uvOffset > -(intptr_t)ycbcrLayout.chromaStep) {
1001 layout->rootPlanes = 2;
1002 layout->planes[C2PlanarLayout::PLANE_U].rootIx = C2PlanarLayout::PLANE_V;
1003 layout->planes[C2PlanarLayout::PLANE_U].offset = -uvOffset;
1004 }
1005 break;
1006 }
Pawin Vongmasa36653902018-11-15 00:10:25 -08001007 }
1008 mLocked = true;
1009
1010 return C2_OK;
1011}
1012
1013c2_status_t C2AllocationGralloc::unmap(
1014 uint8_t **addr, C2Rect rect, C2Fence *fence /* nullable */) {
1015 // TODO: check addr and size, use fence
1016 (void)addr;
1017 (void)rect;
1018
1019 std::lock_guard<std::mutex> lock(mMappedLock);
1020 c2_status_t err = C2_OK;
Pawin Vongmasad032f2d2019-05-15 08:42:44 -07001021 if (mMapper2) {
1022 if (!mMapper2->unlock(
1023 const_cast<native_handle_t *>(mBuffer),
1024 [&err, &fence](const auto &maperr, const auto &releaseFence) {
1025 // TODO
1026 (void) fence;
1027 (void) releaseFence;
1028 err = maperr2error(maperr);
1029 if (err == C2_OK) {
1030 // TODO: fence
1031 }
1032 }).isOk()) {
1033 ALOGE("failed transaction: unlock");
1034 return C2_CORRUPTED;
1035 }
Marissa Wall8806edc2019-06-21 09:50:47 -07001036 } else if (mMapper3) {
Pawin Vongmasad032f2d2019-05-15 08:42:44 -07001037 if (!mMapper3->unlock(
1038 const_cast<native_handle_t *>(mBuffer),
1039 [&err, &fence](const auto &maperr, const auto &releaseFence) {
1040 // TODO
1041 (void) fence;
1042 (void) releaseFence;
1043 err = maperr2error(maperr);
1044 if (err == C2_OK) {
1045 // TODO: fence
1046 }
1047 }).isOk()) {
1048 ALOGE("failed transaction: unlock (@3.0)");
1049 return C2_CORRUPTED;
1050 }
Marissa Wall8806edc2019-06-21 09:50:47 -07001051 } else {
1052 if (!mMapper4->unlock(
1053 const_cast<native_handle_t *>(mBuffer),
1054 [&err, &fence](const auto &maperr, const auto &releaseFence) {
1055 // TODO
1056 (void) fence;
1057 (void) releaseFence;
1058 err = maperr2error(maperr);
1059 if (err == C2_OK) {
1060 // TODO: fence
1061 }
1062 }).isOk()) {
1063 ALOGE("failed transaction: unlock (@4.0)");
1064 return C2_CORRUPTED;
1065 }
Pawin Vongmasad032f2d2019-05-15 08:42:44 -07001066 }
Pawin Vongmasa36653902018-11-15 00:10:25 -08001067 if (err == C2_OK) {
1068 mLocked = false;
1069 }
1070 return err;
1071}
1072
1073bool C2AllocationGralloc::equals(const std::shared_ptr<const C2GraphicAllocation> &other) const {
1074 return other && other->handle() == handle();
1075}
1076
1077/* ===================================== GRALLOC ALLOCATOR ==================================== */
1078class C2AllocatorGralloc::Impl {
1079public:
1080 Impl(id_t id, bool bufferQueue);
1081
1082 id_t getId() const {
1083 return mTraits->id;
1084 }
1085
1086 C2String getName() const {
1087 return mTraits->name;
1088 }
1089
1090 std::shared_ptr<const C2Allocator::Traits> getTraits() const {
1091 return mTraits;
1092 }
1093
1094 c2_status_t newGraphicAllocation(
1095 uint32_t width, uint32_t height, uint32_t format, const C2MemoryUsage &usage,
1096 std::shared_ptr<C2GraphicAllocation> *allocation);
1097
1098 c2_status_t priorGraphicAllocation(
1099 const C2Handle *handle,
1100 std::shared_ptr<C2GraphicAllocation> *allocation);
1101
1102 c2_status_t status() const { return mInit; }
1103
1104private:
1105 std::shared_ptr<C2Allocator::Traits> mTraits;
1106 c2_status_t mInit;
Pawin Vongmasad032f2d2019-05-15 08:42:44 -07001107 sp<IAllocator2> mAllocator2;
1108 sp<IMapper2> mMapper2;
1109 sp<IAllocator3> mAllocator3;
1110 sp<IMapper3> mMapper3;
Marissa Wall8806edc2019-06-21 09:50:47 -07001111 sp<IAllocator4> mAllocator4;
1112 sp<IMapper4> mMapper4;
Pawin Vongmasa36653902018-11-15 00:10:25 -08001113 const bool mBufferQueue;
1114};
1115
1116void _UnwrapNativeCodec2GrallocMetadata(
1117 const C2Handle *const handle,
1118 uint32_t *width, uint32_t *height, uint32_t *format,uint64_t *usage, uint32_t *stride,
1119 uint32_t *generation, uint64_t *igbp_id, uint32_t *igbp_slot) {
1120 (void)C2HandleGralloc::Import(handle, width, height, format, usage, stride,
1121 generation, igbp_id, igbp_slot);
1122}
1123
1124C2AllocatorGralloc::Impl::Impl(id_t id, bool bufferQueue)
1125 : mInit(C2_OK), mBufferQueue(bufferQueue) {
1126 // TODO: get this from allocator
1127 C2MemoryUsage minUsage = { 0, 0 }, maxUsage = { ~(uint64_t)0, ~(uint64_t)0 };
1128 Traits traits = { "android.allocator.gralloc", id, C2Allocator::GRAPHIC, minUsage, maxUsage };
1129 mTraits = std::make_shared<C2Allocator::Traits>(traits);
1130
1131 // gralloc allocator is a singleton, so all objects share a global service
Marissa Wall8806edc2019-06-21 09:50:47 -07001132 mAllocator4 = IAllocator4::getService();
1133 mMapper4 = IMapper4::getService();
1134 if (!mAllocator4 || !mMapper4) {
1135 mAllocator4 = nullptr;
1136 mMapper4 = nullptr;
1137 mAllocator3 = IAllocator3::getService();
1138 mMapper3 = IMapper3::getService();
1139 if (!mAllocator3 || !mMapper3) {
1140 mAllocator3 = nullptr;
1141 mMapper3 = nullptr;
1142 mAllocator2 = IAllocator2::getService();
1143 mMapper2 = IMapper2::getService();
1144 if (!mAllocator2 || !mMapper2) {
1145 mAllocator2 = nullptr;
1146 mMapper2 = nullptr;
1147 mInit = C2_CORRUPTED;
1148 }
Pawin Vongmasad032f2d2019-05-15 08:42:44 -07001149 }
Pawin Vongmasa36653902018-11-15 00:10:25 -08001150 }
1151}
1152
1153c2_status_t C2AllocatorGralloc::Impl::newGraphicAllocation(
1154 uint32_t width, uint32_t height, uint32_t format, const C2MemoryUsage &usage,
1155 std::shared_ptr<C2GraphicAllocation> *allocation) {
1156 uint64_t grallocUsage = static_cast<C2AndroidMemoryUsage>(usage).asGrallocUsage();
1157 ALOGV("allocating buffer with usage %#llx => %#llx",
1158 (long long)usage.expected, (long long)grallocUsage);
1159
Pawin Vongmasa36653902018-11-15 00:10:25 -08001160 c2_status_t err = C2_OK;
Pawin Vongmasad032f2d2019-05-15 08:42:44 -07001161 hidl_handle buffer{};
1162
1163 if (mMapper2) {
1164 BufferDescriptorInfo2 info = {
1165 {
1166 width,
1167 height,
1168 1u, // layerCount
1169 PixelFormat2(format),
1170 grallocUsage,
1171 },
1172 0u, // stride placeholder
1173 };
1174 BufferDescriptor2 desc;
1175 if (!mMapper2->createDescriptor(
1176 info.mapperInfo, [&err, &desc](const auto &maperr, const auto &descriptor) {
1177 err = maperr2error(maperr);
1178 if (err == C2_OK) {
1179 desc = descriptor;
1180 }
1181 }).isOk()) {
1182 ALOGE("failed transaction: createDescriptor");
1183 return C2_CORRUPTED;
1184 }
1185 if (err != C2_OK) {
1186 return err;
1187 }
1188
1189 // IAllocator shares IMapper error codes.
1190 if (!mAllocator2->allocate(
1191 desc,
1192 1u,
1193 [&err, &buffer, &info](const auto &maperr, const auto &stride, auto &buffers) {
1194 err = maperr2error(maperr);
1195 if (err != C2_OK) {
1196 return;
1197 }
1198 if (buffers.size() != 1u) {
1199 err = C2_CORRUPTED;
1200 return;
1201 }
1202 info.stride = stride;
1203 buffer = buffers[0];
1204 }).isOk()) {
1205 ALOGE("failed transaction: allocate");
1206 return C2_CORRUPTED;
1207 }
1208 if (err != C2_OK) {
1209 return err;
1210 }
1211 allocation->reset(new C2AllocationGralloc(
1212 info, mMapper2, buffer,
1213 C2HandleGralloc::WrapAndMoveNativeHandle(
1214 buffer.getNativeHandle(),
1215 width, height,
1216 format, grallocUsage, info.stride,
1217 0, 0, mBufferQueue ? ~0 : 0),
1218 mTraits->id));
1219 return C2_OK;
Marissa Wall8806edc2019-06-21 09:50:47 -07001220 } else if (mMapper3) {
Pawin Vongmasad032f2d2019-05-15 08:42:44 -07001221 BufferDescriptorInfo3 info = {
1222 {
1223 width,
1224 height,
1225 1u, // layerCount
Marissa Wall8806edc2019-06-21 09:50:47 -07001226 PixelFormat4(format),
Pawin Vongmasad032f2d2019-05-15 08:42:44 -07001227 grallocUsage,
1228 },
1229 0u, // stride placeholder
1230 };
1231 BufferDescriptor3 desc;
1232 if (!mMapper3->createDescriptor(
1233 info.mapperInfo, [&err, &desc](const auto &maperr, const auto &descriptor) {
1234 err = maperr2error(maperr);
1235 if (err == C2_OK) {
1236 desc = descriptor;
1237 }
1238 }).isOk()) {
1239 ALOGE("failed transaction: createDescriptor");
1240 return C2_CORRUPTED;
1241 }
1242 if (err != C2_OK) {
1243 return err;
1244 }
1245
1246 // IAllocator shares IMapper error codes.
1247 if (!mAllocator3->allocate(
1248 desc,
1249 1u,
1250 [&err, &buffer, &info](const auto &maperr, const auto &stride, auto &buffers) {
1251 err = maperr2error(maperr);
1252 if (err != C2_OK) {
1253 return;
1254 }
1255 if (buffers.size() != 1u) {
1256 err = C2_CORRUPTED;
1257 return;
1258 }
1259 info.stride = stride;
1260 buffer = buffers[0];
1261 }).isOk()) {
1262 ALOGE("failed transaction: allocate");
1263 return C2_CORRUPTED;
1264 }
1265 if (err != C2_OK) {
1266 return err;
1267 }
1268 allocation->reset(new C2AllocationGralloc(
1269 info, mMapper3, buffer,
1270 C2HandleGralloc::WrapAndMoveNativeHandle(
1271 buffer.getNativeHandle(),
1272 width, height,
1273 format, grallocUsage, info.stride,
1274 0, 0, mBufferQueue ? ~0 : 0),
1275 mTraits->id));
1276 return C2_OK;
Marissa Wall8806edc2019-06-21 09:50:47 -07001277 } else {
1278 BufferDescriptorInfo4 info = {
1279 {
Marissa Wallc759fc52019-11-06 10:11:11 -08001280 "C2GrallocAllocation",
Marissa Wall8806edc2019-06-21 09:50:47 -07001281 width,
1282 height,
1283 1u, // layerCount
1284 PixelFormat4(format),
1285 grallocUsage,
1286 },
1287 0u, // stride placeholder
1288 };
1289 BufferDescriptor4 desc;
1290 if (!mMapper4->createDescriptor(
1291 info.mapperInfo, [&err, &desc](const auto &maperr, const auto &descriptor) {
1292 err = maperr2error(maperr);
1293 if (err == C2_OK) {
1294 desc = descriptor;
1295 }
1296 }).isOk()) {
1297 ALOGE("failed transaction: createDescriptor");
1298 return C2_CORRUPTED;
1299 }
1300 if (err != C2_OK) {
1301 return err;
1302 }
1303
1304 // IAllocator shares IMapper error codes.
1305 if (!mAllocator4->allocate(
1306 desc,
1307 1u,
1308 [&err, &buffer, &info](const auto &maperr, const auto &stride, auto &buffers) {
1309 err = maperr2error(maperr);
1310 if (err != C2_OK) {
1311 return;
1312 }
1313 if (buffers.size() != 1u) {
1314 err = C2_CORRUPTED;
1315 return;
1316 }
1317 info.stride = stride;
1318 buffer = buffers[0];
1319 }).isOk()) {
1320 ALOGE("failed transaction: allocate");
1321 return C2_CORRUPTED;
1322 }
1323 if (err != C2_OK) {
1324 return err;
1325 }
1326 allocation->reset(new C2AllocationGralloc(
1327 info, mMapper4, buffer,
1328 C2HandleGralloc::WrapAndMoveNativeHandle(
1329 buffer.getNativeHandle(),
1330 width, height,
1331 format, grallocUsage, info.stride,
1332 0, 0, mBufferQueue ? ~0 : 0),
1333 mTraits->id));
1334 return C2_OK;
Pawin Vongmasa36653902018-11-15 00:10:25 -08001335 }
Pawin Vongmasa36653902018-11-15 00:10:25 -08001336}
1337
1338c2_status_t C2AllocatorGralloc::Impl::priorGraphicAllocation(
1339 const C2Handle *handle,
1340 std::shared_ptr<C2GraphicAllocation> *allocation) {
Pawin Vongmasad032f2d2019-05-15 08:42:44 -07001341 if (mMapper2) {
1342 BufferDescriptorInfo2 info;
1343 info.mapperInfo.layerCount = 1u;
1344 uint32_t generation;
1345 uint64_t igbp_id;
1346 uint32_t igbp_slot;
1347 const C2HandleGralloc *grallocHandle = C2HandleGralloc::Import(
1348 handle,
1349 &info.mapperInfo.width, &info.mapperInfo.height,
1350 (uint32_t *)&info.mapperInfo.format,
1351 (uint64_t *)&info.mapperInfo.usage,
1352 &info.stride,
1353 &generation, &igbp_id, &igbp_slot);
1354 if (grallocHandle == nullptr) {
1355 return C2_BAD_VALUE;
1356 }
1357
1358 hidl_handle hidlHandle;
1359 hidlHandle.setTo(C2HandleGralloc::UnwrapNativeHandle(grallocHandle), true);
1360
1361 allocation->reset(new C2AllocationGralloc(
1362 info, mMapper2, hidlHandle, grallocHandle, mTraits->id));
1363 return C2_OK;
Marissa Wall8806edc2019-06-21 09:50:47 -07001364 } else if (mMapper3) {
Pawin Vongmasad032f2d2019-05-15 08:42:44 -07001365 BufferDescriptorInfo3 info;
1366 info.mapperInfo.layerCount = 1u;
1367 uint32_t generation;
1368 uint64_t igbp_id;
1369 uint32_t igbp_slot;
1370 const C2HandleGralloc *grallocHandle = C2HandleGralloc::Import(
1371 handle,
1372 &info.mapperInfo.width, &info.mapperInfo.height,
1373 (uint32_t *)&info.mapperInfo.format,
1374 (uint64_t *)&info.mapperInfo.usage,
1375 &info.stride,
1376 &generation, &igbp_id, &igbp_slot);
1377 if (grallocHandle == nullptr) {
1378 return C2_BAD_VALUE;
1379 }
1380
1381 hidl_handle hidlHandle;
1382 hidlHandle.setTo(C2HandleGralloc::UnwrapNativeHandle(grallocHandle), true);
1383
1384 allocation->reset(new C2AllocationGralloc(
1385 info, mMapper3, hidlHandle, grallocHandle, mTraits->id));
1386 return C2_OK;
Marissa Wall8806edc2019-06-21 09:50:47 -07001387 } else {
1388 BufferDescriptorInfo4 info;
1389 info.mapperInfo.layerCount = 1u;
1390 uint32_t generation;
1391 uint64_t igbp_id;
1392 uint32_t igbp_slot;
1393 const C2HandleGralloc *grallocHandle = C2HandleGralloc::Import(
1394 handle,
1395 &info.mapperInfo.width, &info.mapperInfo.height,
1396 (uint32_t *)&info.mapperInfo.format,
1397 (uint64_t *)&info.mapperInfo.usage,
1398 &info.stride,
1399 &generation, &igbp_id, &igbp_slot);
1400 if (grallocHandle == nullptr) {
1401 return C2_BAD_VALUE;
1402 }
1403
1404 hidl_handle hidlHandle;
1405 hidlHandle.setTo(C2HandleGralloc::UnwrapNativeHandle(grallocHandle), true);
1406
1407 allocation->reset(new C2AllocationGralloc(
1408 info, mMapper4, hidlHandle, grallocHandle, mTraits->id));
1409 return C2_OK;
Pawin Vongmasa36653902018-11-15 00:10:25 -08001410 }
Pawin Vongmasa36653902018-11-15 00:10:25 -08001411}
1412
1413C2AllocatorGralloc::C2AllocatorGralloc(id_t id, bool bufferQueue)
1414 : mImpl(new Impl(id, bufferQueue)) {}
1415
1416C2AllocatorGralloc::~C2AllocatorGralloc() { delete mImpl; }
1417
1418C2Allocator::id_t C2AllocatorGralloc::getId() const {
1419 return mImpl->getId();
1420}
1421
1422C2String C2AllocatorGralloc::getName() const {
1423 return mImpl->getName();
1424}
1425
1426std::shared_ptr<const C2Allocator::Traits> C2AllocatorGralloc::getTraits() const {
1427 return mImpl->getTraits();
1428}
1429
1430c2_status_t C2AllocatorGralloc::newGraphicAllocation(
1431 uint32_t width, uint32_t height, uint32_t format, C2MemoryUsage usage,
1432 std::shared_ptr<C2GraphicAllocation> *allocation) {
1433 return mImpl->newGraphicAllocation(width, height, format, usage, allocation);
1434}
1435
1436c2_status_t C2AllocatorGralloc::priorGraphicAllocation(
1437 const C2Handle *handle,
1438 std::shared_ptr<C2GraphicAllocation> *allocation) {
1439 return mImpl->priorGraphicAllocation(handle, allocation);
1440}
1441
1442c2_status_t C2AllocatorGralloc::status() const {
1443 return mImpl->status();
1444}
1445
1446bool C2AllocatorGralloc::isValid(const C2Handle* const o) {
1447 return C2HandleGralloc::isValid(o);
1448}
1449
1450} // namespace android