blob: f04674ea091d14d952e6f6b26f2c6477236d4b3e [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
Marissa Wall2a24a302019-11-25 11:19:18 -080021#include <mutex>
22
Praveen Chavan34493f12021-02-18 00:51:50 -080023#include <aidl/android/hardware/graphics/common/PlaneLayoutComponentType.h>
Marissa Wall2a24a302019-11-25 11:19:18 -080024#include <android/hardware/graphics/common/1.2/types.h>
Pawin Vongmasa36653902018-11-15 00:10:25 -080025#include <cutils/native_handle.h>
Praveen Chavan34493f12021-02-18 00:51:50 -080026#include <gralloctypes/Gralloc4.h>
Pawin Vongmasa36653902018-11-15 00:10:25 -080027#include <hardware/gralloc.h>
Marissa Wall2a24a302019-11-25 11:19:18 -080028#include <ui/GraphicBufferAllocator.h>
29#include <ui/GraphicBufferMapper.h>
Chih-Yu Huang486aa5d2020-10-13 16:22:58 +090030#include <ui/Rect.h>
Pawin Vongmasa36653902018-11-15 00:10:25 -080031
32#include <C2AllocatorGralloc.h>
33#include <C2Buffer.h>
Praveen Chavan34493f12021-02-18 00:51:50 -080034#include <C2Debug.h>
Pawin Vongmasa36653902018-11-15 00:10:25 -080035#include <C2PlatformSupport.h>
36
Marissa Wall2a24a302019-11-25 11:19:18 -080037using ::android::hardware::hidl_handle;
38using PixelFormat4 = ::android::hardware::graphics::common::V1_2::PixelFormat;
39
Pawin Vongmasa36653902018-11-15 00:10:25 -080040namespace android {
41
Pawin Vongmasad032f2d2019-05-15 08:42:44 -070042namespace /* unnamed */ {
Pawin Vongmasa36653902018-11-15 00:10:25 -080043 enum : uint64_t {
44 /**
45 * Usage mask that is passed through from gralloc to Codec 2.0 usage.
46 */
47 PASSTHROUGH_USAGE_MASK =
Charlie Chen49d3fe72021-03-25 20:02:37 +080048 ~static_cast<uint64_t>(GRALLOC_USAGE_SW_READ_MASK |
49 GRALLOC_USAGE_SW_WRITE_MASK |
50 GRALLOC_USAGE_PROTECTED)
Pawin Vongmasa36653902018-11-15 00:10:25 -080051 };
52
53 // verify that passthrough mask is within the platform mask
54 static_assert((~C2MemoryUsage::PLATFORM_MASK & PASSTHROUGH_USAGE_MASK) == 0, "");
Pawin Vongmasad032f2d2019-05-15 08:42:44 -070055} // unnamed
Pawin Vongmasa36653902018-11-15 00:10:25 -080056
Harish Mahendrakar7dc54f92022-06-30 20:36:23 -070057static bool isAtLeastT() {
58 return android_get_device_api_level() >= __ANDROID_API_T__;
59}
60
Pawin Vongmasa36653902018-11-15 00:10:25 -080061C2MemoryUsage C2AndroidMemoryUsage::FromGrallocUsage(uint64_t usage) {
62 // gralloc does not support WRITE_PROTECTED
63 return C2MemoryUsage(
64 ((usage & GRALLOC_USAGE_SW_READ_MASK) ? C2MemoryUsage::CPU_READ : 0) |
65 ((usage & GRALLOC_USAGE_SW_WRITE_MASK) ? C2MemoryUsage::CPU_WRITE : 0) |
66 ((usage & GRALLOC_USAGE_PROTECTED) ? C2MemoryUsage::READ_PROTECTED : 0) |
67 (usage & PASSTHROUGH_USAGE_MASK));
68}
69
70uint64_t C2AndroidMemoryUsage::asGrallocUsage() const {
71 // gralloc does not support WRITE_PROTECTED
72 return (((expected & C2MemoryUsage::CPU_READ) ? GRALLOC_USAGE_SW_READ_OFTEN : 0) |
73 ((expected & C2MemoryUsage::CPU_WRITE) ? GRALLOC_USAGE_SW_WRITE_OFTEN : 0) |
74 ((expected & C2MemoryUsage::READ_PROTECTED) ? GRALLOC_USAGE_PROTECTED : 0) |
75 (expected & PASSTHROUGH_USAGE_MASK));
76}
77
Pawin Vongmasad032f2d2019-05-15 08:42:44 -070078namespace /* unnamed */ {
79
Pawin Vongmasa36653902018-11-15 00:10:25 -080080/* ===================================== GRALLOC ALLOCATION ==================================== */
Pawin Vongmasa36653902018-11-15 00:10:25 -080081bool native_handle_is_invalid(const native_handle_t *const handle) {
82 // perform basic validation of a native handle
83 if (handle == nullptr) {
84 // null handle is considered valid
85 return false;
86 }
87 return ((size_t)handle->version != sizeof(native_handle_t) ||
88 handle->numFds < 0 ||
89 handle->numInts < 0 ||
90 // for sanity assume handles must occupy less memory than INT_MAX bytes
91 handle->numFds > int((INT_MAX - handle->version) / sizeof(int)) - handle->numInts);
92}
93
94class C2HandleGralloc : public C2Handle {
95private:
96 struct ExtraData {
97 uint32_t width;
98 uint32_t height;
99 uint32_t format;
100 uint32_t usage_lo;
101 uint32_t usage_hi;
102 uint32_t stride;
103 uint32_t generation;
104 uint32_t igbp_id_lo;
105 uint32_t igbp_id_hi;
106 uint32_t igbp_slot;
107 uint32_t magic;
108 };
109
110 enum {
111 NUM_INTS = sizeof(ExtraData) / sizeof(int),
112 };
113 const static uint32_t MAGIC = '\xc2gr\x00';
114
115 static
John Stultz653ddd12020-09-19 05:26:24 +0000116 const ExtraData* GetExtraData(const C2Handle *const handle) {
Pawin Vongmasa36653902018-11-15 00:10:25 -0800117 if (handle == nullptr
118 || native_handle_is_invalid(handle)
119 || handle->numInts < NUM_INTS) {
120 return nullptr;
121 }
122 return reinterpret_cast<const ExtraData*>(
123 &handle->data[handle->numFds + handle->numInts - NUM_INTS]);
124 }
125
126 static
John Stultz653ddd12020-09-19 05:26:24 +0000127 ExtraData *GetExtraData(C2Handle *const handle) {
128 return const_cast<ExtraData *>(GetExtraData(const_cast<const C2Handle *const>(handle)));
Pawin Vongmasa36653902018-11-15 00:10:25 -0800129 }
130
131public:
132 void getIgbpData(uint32_t *generation, uint64_t *igbp_id, uint32_t *igbp_slot) const {
John Stultz653ddd12020-09-19 05:26:24 +0000133 const ExtraData *ed = GetExtraData(this);
Pawin Vongmasa36653902018-11-15 00:10:25 -0800134 *generation = ed->generation;
135 *igbp_id = unsigned(ed->igbp_id_lo) | uint64_t(unsigned(ed->igbp_id_hi)) << 32;
136 *igbp_slot = ed->igbp_slot;
137 }
138
John Stultz653ddd12020-09-19 05:26:24 +0000139 static bool IsValid(const C2Handle *const o) {
Pawin Vongmasa36653902018-11-15 00:10:25 -0800140 if (o == nullptr) { // null handle is always valid
141 return true;
142 }
John Stultz653ddd12020-09-19 05:26:24 +0000143 const ExtraData *xd = GetExtraData(o);
Pawin Vongmasa36653902018-11-15 00:10:25 -0800144 // we cannot validate width/height/format/usage without accessing gralloc driver
145 return xd != nullptr && xd->magic == MAGIC;
146 }
147
Sungtak Leea4d13be2019-01-23 15:24:46 -0800148 static C2HandleGralloc* WrapAndMoveNativeHandle(
Pawin Vongmasa36653902018-11-15 00:10:25 -0800149 const native_handle_t *const handle,
150 uint32_t width, uint32_t height, uint32_t format, uint64_t usage,
151 uint32_t stride, uint32_t generation, uint64_t igbp_id = 0, uint32_t igbp_slot = 0) {
152 //CHECK(handle != nullptr);
153 if (native_handle_is_invalid(handle) ||
154 handle->numInts > int((INT_MAX - handle->version) / sizeof(int)) - NUM_INTS - handle->numFds) {
155 return nullptr;
156 }
157 ExtraData xd = {
158 width, height, format, uint32_t(usage & 0xFFFFFFFF), uint32_t(usage >> 32),
159 stride, generation, uint32_t(igbp_id & 0xFFFFFFFF), uint32_t(igbp_id >> 32),
160 igbp_slot, MAGIC
161 };
162 native_handle_t *res = native_handle_create(handle->numFds, handle->numInts + NUM_INTS);
163 if (res != nullptr) {
164 memcpy(&res->data, &handle->data, sizeof(int) * (handle->numFds + handle->numInts));
John Stultz653ddd12020-09-19 05:26:24 +0000165 *GetExtraData(res) = xd;
Pawin Vongmasa36653902018-11-15 00:10:25 -0800166 }
167 return reinterpret_cast<C2HandleGralloc *>(res);
168 }
169
Sungtak Leea4d13be2019-01-23 15:24:46 -0800170 static C2HandleGralloc* WrapNativeHandle(
171 const native_handle_t *const handle,
172 uint32_t width, uint32_t height, uint32_t format, uint64_t usage,
173 uint32_t stride, uint32_t generation, uint64_t igbp_id = 0, uint32_t igbp_slot = 0) {
174 if (handle == nullptr) {
175 return nullptr;
176 }
177 native_handle_t *clone = native_handle_clone(handle);
178 if (clone == nullptr) {
179 return nullptr;
180 }
181 C2HandleGralloc *res = WrapAndMoveNativeHandle(
182 clone, width, height, format, usage, stride, generation, igbp_id, igbp_slot);
183 if (res == nullptr) {
184 native_handle_close(clone);
185 }
186 native_handle_delete(clone);
187 return res;
188 }
189
Songyue Han1e6769b2023-08-30 18:09:27 +0000190 static uint32_t getPixelFormat(const C2Handle *const handle) {
191 if (handle == nullptr) {
192 return 0;
193 }
194 const ExtraData *xd = GetExtraData(handle);
195 return xd->format;
196 }
197
Sungtak Lee08515812019-06-05 11:16:32 -0700198 static bool MigrateNativeHandle(
199 native_handle_t *handle,
200 uint32_t generation, uint64_t igbp_id, uint32_t igbp_slot) {
John Stultz653ddd12020-09-19 05:26:24 +0000201 if (handle == nullptr || !IsValid(handle)) {
Sungtak Lee08515812019-06-05 11:16:32 -0700202 return false;
203 }
John Stultz653ddd12020-09-19 05:26:24 +0000204 ExtraData *ed = GetExtraData(handle);
Sungtak Lee08515812019-06-05 11:16:32 -0700205 if (!ed) return false;
206 ed->generation = generation;
207 ed->igbp_id_lo = uint32_t(igbp_id & 0xFFFFFFFF);
208 ed->igbp_id_hi = uint32_t(igbp_id >> 32);
209 ed->igbp_slot = igbp_slot;
210 return true;
211 }
212
213
Pawin Vongmasa36653902018-11-15 00:10:25 -0800214 static native_handle_t* UnwrapNativeHandle(
215 const C2Handle *const handle) {
John Stultz653ddd12020-09-19 05:26:24 +0000216 const ExtraData *xd = GetExtraData(handle);
Pawin Vongmasa36653902018-11-15 00:10:25 -0800217 if (xd == nullptr || xd->magic != MAGIC) {
218 return nullptr;
219 }
220 native_handle_t *res = native_handle_create(handle->numFds, handle->numInts - NUM_INTS);
221 if (res != nullptr) {
222 memcpy(&res->data, &handle->data, sizeof(int) * (res->numFds + res->numInts));
223 }
224 return res;
225 }
226
Pawin Vongmasa36653902018-11-15 00:10:25 -0800227 static const C2HandleGralloc* Import(
228 const C2Handle *const handle,
229 uint32_t *width, uint32_t *height, uint32_t *format,
230 uint64_t *usage, uint32_t *stride,
231 uint32_t *generation, uint64_t *igbp_id, uint32_t *igbp_slot) {
John Stultz653ddd12020-09-19 05:26:24 +0000232 const ExtraData *xd = GetExtraData(handle);
Pawin Vongmasa36653902018-11-15 00:10:25 -0800233 if (xd == nullptr) {
234 return nullptr;
235 }
236 *width = xd->width;
237 *height = xd->height;
238 *format = xd->format;
239 *usage = xd->usage_lo | (uint64_t(xd->usage_hi) << 32);
240 *stride = xd->stride;
241 *generation = xd->generation;
242 *igbp_id = xd->igbp_id_lo | (uint64_t(xd->igbp_id_hi) << 32);
243 *igbp_slot = xd->igbp_slot;
244 return reinterpret_cast<const C2HandleGralloc *>(handle);
245 }
246};
247
Praveen Chavan34493f12021-02-18 00:51:50 -0800248static
249c2_status_t Gralloc4Mapper_lock(native_handle_t *handle, uint64_t usage, const Rect& bounds,
250 C2PlanarLayout *layout, uint8_t **addr) {
251 GraphicBufferMapper &mapper = GraphicBufferMapper::get();
252
253 std::vector<ui::PlaneLayout> planes;
254 // this method is only supported on Gralloc 4 or later
255 status_t err = mapper.getPlaneLayouts(handle, &planes);
256 if (err != NO_ERROR || planes.empty()) {
257 return C2_CANNOT_DO;
258 }
259
260 uint8_t *pointer = nullptr;
261 err = mapper.lock(handle, usage, bounds, (void **)&pointer, nullptr, nullptr);
262 if (err != NO_ERROR || pointer == nullptr) {
263 return C2_CORRUPTED;
264 }
265
266 using aidl::android::hardware::graphics::common::PlaneLayoutComponentType;
267 using aidl::android::hardware::graphics::common::PlaneLayoutComponent;
268
269 layout->type = C2PlanarLayout::TYPE_YUV;
270 layout->numPlanes = 0;
271 layout->rootPlanes = 0;
272
273 for (const ui::PlaneLayout &plane : planes) {
274 layout->rootPlanes++;
275 uint32_t lastOffsetInBits = 0;
Wonsik Kimf12bebc2022-03-24 16:25:03 -0700276 uint32_t rootIx = layout->numPlanes;
Praveen Chavan34493f12021-02-18 00:51:50 -0800277
278 for (const PlaneLayoutComponent &component : plane.components) {
279 if (!gralloc4::isStandardPlaneLayoutComponentType(component.type)) {
Praveen Chavan2c580d92022-02-24 12:23:46 -0800280 mapper.unlock(handle);
Praveen Chavan34493f12021-02-18 00:51:50 -0800281 return C2_CANNOT_DO;
282 }
283
284 uint32_t rightShiftBits = component.offsetInBits - lastOffsetInBits;
285 uint32_t allocatedDepthInBits = component.sizeInBits + rightShiftBits;
286 C2PlanarLayout::plane_index_t planeId;
287 C2PlaneInfo::channel_t channel;
288
289 switch (static_cast<PlaneLayoutComponentType>(component.type.value)) {
290 case PlaneLayoutComponentType::Y:
291 planeId = C2PlanarLayout::PLANE_Y;
292 channel = C2PlaneInfo::CHANNEL_Y;
293 break;
294 case PlaneLayoutComponentType::CB:
295 planeId = C2PlanarLayout::PLANE_U;
296 channel = C2PlaneInfo::CHANNEL_CB;
297 break;
298 case PlaneLayoutComponentType::CR:
299 planeId = C2PlanarLayout::PLANE_V;
300 channel = C2PlaneInfo::CHANNEL_CR;
301 break;
302 default:
Praveen Chavan2c580d92022-02-24 12:23:46 -0800303 mapper.unlock(handle);
Praveen Chavan34493f12021-02-18 00:51:50 -0800304 return C2_CORRUPTED;
305 }
306
307 addr[planeId] = pointer + plane.offsetInBytes + (component.offsetInBits / 8);
308 layout->planes[planeId] = {
309 channel, // channel
310 static_cast<int32_t>(plane.sampleIncrementInBits / 8), // colInc
311 static_cast<int32_t>(plane.strideInBytes), // rowInc
312 static_cast<uint32_t>(plane.horizontalSubsampling), // mColSampling
313 static_cast<uint32_t>(plane.verticalSubsampling), // mRowSampling
314 allocatedDepthInBits, // allocatedDepth (bits)
315 static_cast<uint32_t>(component.sizeInBits), // bitDepth (bits)
316 rightShiftBits, // rightShift (bits)
317 C2PlaneInfo::NATIVE, // endianness
318 rootIx, // rootIx
319 static_cast<uint32_t>(component.offsetInBits / 8), // offset (bytes)
320 };
321
322 layout->numPlanes++;
323 lastOffsetInBits = component.offsetInBits + component.sizeInBits;
Praveen Chavan34493f12021-02-18 00:51:50 -0800324 }
325 }
326 return C2_OK;
327}
328
Pawin Vongmasad032f2d2019-05-15 08:42:44 -0700329} // unnamed namespace
330
Praveen Chavan34493f12021-02-18 00:51:50 -0800331
Pawin Vongmasa36653902018-11-15 00:10:25 -0800332native_handle_t *UnwrapNativeCodec2GrallocHandle(const C2Handle *const handle) {
333 return C2HandleGralloc::UnwrapNativeHandle(handle);
334}
335
Pawin Vongmasa36653902018-11-15 00:10:25 -0800336C2Handle *WrapNativeCodec2GrallocHandle(
337 const native_handle_t *const handle,
338 uint32_t width, uint32_t height, uint32_t format, uint64_t usage, uint32_t stride,
339 uint32_t generation, uint64_t igbp_id, uint32_t igbp_slot) {
340 return C2HandleGralloc::WrapNativeHandle(handle, width, height, format, usage, stride,
341 generation, igbp_id, igbp_slot);
342}
343
Songyue Han1e6769b2023-08-30 18:09:27 +0000344uint32_t ExtractFormatFromCodec2GrallocHandle(const C2Handle *const handle) {
345 return C2HandleGralloc::getPixelFormat(handle);
346}
347
Sungtak Lee08515812019-06-05 11:16:32 -0700348bool MigrateNativeCodec2GrallocHandle(
349 native_handle_t *handle,
350 uint32_t generation, uint64_t igbp_id, uint32_t igbp_slot) {
351 return C2HandleGralloc::MigrateNativeHandle(handle, generation, igbp_id, igbp_slot);
352}
353
354
Pawin Vongmasa36653902018-11-15 00:10:25 -0800355class C2AllocationGralloc : public C2GraphicAllocation {
356public:
357 virtual ~C2AllocationGralloc() override;
358
359 virtual c2_status_t map(
Chih-Yu Huang486aa5d2020-10-13 16:22:58 +0900360 C2Rect c2Rect, C2MemoryUsage usage, C2Fence *fence,
Pawin Vongmasa36653902018-11-15 00:10:25 -0800361 C2PlanarLayout *layout /* nonnull */, uint8_t **addr /* nonnull */) override;
362 virtual c2_status_t unmap(
363 uint8_t **addr /* nonnull */, C2Rect rect, C2Fence *fence /* nullable */) override;
364 virtual C2Allocator::id_t getAllocatorId() const override { return mAllocatorId; }
365 virtual const C2Handle *handle() const override { return mLockedHandle ? : mHandle; }
366 virtual bool equals(const std::shared_ptr<const C2GraphicAllocation> &other) const override;
367
368 // internal methods
369 // |handle| will be moved.
Marissa Wall2a24a302019-11-25 11:19:18 -0800370
Pawin Vongmasa36653902018-11-15 00:10:25 -0800371 C2AllocationGralloc(
Marissa Wall2a24a302019-11-25 11:19:18 -0800372 uint32_t width, uint32_t height,
373 uint32_t format, uint32_t layerCount,
374 uint64_t grallocUsage, uint32_t stride,
Marissa Wall8806edc2019-06-21 09:50:47 -0700375 hidl_handle &hidlHandle,
376 const C2HandleGralloc *const handle,
377 C2Allocator::id_t allocatorId);
Pawin Vongmasa36653902018-11-15 00:10:25 -0800378 int dup() const;
379 c2_status_t status() const;
380
381private:
Marissa Wall2a24a302019-11-25 11:19:18 -0800382 const uint32_t mWidth;
383 const uint32_t mHeight;
384 const uint32_t mFormat;
385 const uint32_t mLayerCount;
386 const uint64_t mGrallocUsage;
387 const uint32_t mStride;
Pawin Vongmasa36653902018-11-15 00:10:25 -0800388 const hidl_handle mHidlHandle;
389 const C2HandleGralloc *mHandle;
390 buffer_handle_t mBuffer;
391 const C2HandleGralloc *mLockedHandle;
392 bool mLocked;
393 C2Allocator::id_t mAllocatorId;
394 std::mutex mMappedLock;
395};
396
397C2AllocationGralloc::C2AllocationGralloc(
Marissa Wall2a24a302019-11-25 11:19:18 -0800398 uint32_t width, uint32_t height,
399 uint32_t format, uint32_t layerCount,
400 uint64_t grallocUsage, uint32_t stride,
Pawin Vongmasa36653902018-11-15 00:10:25 -0800401 hidl_handle &hidlHandle,
402 const C2HandleGralloc *const handle,
403 C2Allocator::id_t allocatorId)
Marissa Wall2a24a302019-11-25 11:19:18 -0800404 : C2GraphicAllocation(width, height),
405 mWidth(width),
406 mHeight(height),
407 mFormat(format),
408 mLayerCount(layerCount),
409 mGrallocUsage(grallocUsage),
410 mStride(stride),
Marissa Wall8806edc2019-06-21 09:50:47 -0700411 mHidlHandle(std::move(hidlHandle)),
412 mHandle(handle),
413 mBuffer(nullptr),
414 mLockedHandle(nullptr),
415 mLocked(false),
416 mAllocatorId(allocatorId) {
417}
418
Pawin Vongmasa36653902018-11-15 00:10:25 -0800419C2AllocationGralloc::~C2AllocationGralloc() {
Yichi Chenfa94a3b2018-12-08 00:06:25 +0800420 if (mBuffer && mLocked) {
Pawin Vongmasa36653902018-11-15 00:10:25 -0800421 // implementation ignores addresss and rect
422 uint8_t* addr[C2PlanarLayout::MAX_NUM_PLANES] = {};
423 unmap(addr, C2Rect(), nullptr);
424 }
Yichi Chenfa94a3b2018-12-08 00:06:25 +0800425 if (mBuffer) {
Marissa Wall2a24a302019-11-25 11:19:18 -0800426 status_t err = GraphicBufferMapper::get().freeBuffer(mBuffer);
427 if (err) {
428 ALOGE("failed transaction: freeBuffer");
Pawin Vongmasad032f2d2019-05-15 08:42:44 -0700429 }
Yichi Chenfa94a3b2018-12-08 00:06:25 +0800430 }
431 if (mHandle) {
432 native_handle_delete(
433 const_cast<native_handle_t *>(reinterpret_cast<const native_handle_t *>(mHandle)));
434 }
Sungtak Lee2729dcf2019-01-18 13:15:07 -0800435 if (mLockedHandle) {
436 native_handle_delete(
437 const_cast<native_handle_t *>(
438 reinterpret_cast<const native_handle_t *>(mLockedHandle)));
439 }
Pawin Vongmasa36653902018-11-15 00:10:25 -0800440}
441
442c2_status_t C2AllocationGralloc::map(
Chih-Yu Huang486aa5d2020-10-13 16:22:58 +0900443 C2Rect c2Rect, C2MemoryUsage usage, C2Fence *fence,
Pawin Vongmasa36653902018-11-15 00:10:25 -0800444 C2PlanarLayout *layout /* nonnull */, uint8_t **addr /* nonnull */) {
Chih-Yu Huang486aa5d2020-10-13 16:22:58 +0900445 const Rect rect{(int32_t)c2Rect.left, (int32_t)c2Rect.top,
446 (int32_t)(c2Rect.left + c2Rect.width) /* right */,
447 (int32_t)(c2Rect.top + c2Rect.height) /* bottom */};
448
Pawin Vongmasa36653902018-11-15 00:10:25 -0800449 uint64_t grallocUsage = static_cast<C2AndroidMemoryUsage>(usage).asGrallocUsage();
450 ALOGV("mapping buffer with usage %#llx => %#llx",
451 (long long)usage.expected, (long long)grallocUsage);
452
453 // TODO
Marissa Wall2a24a302019-11-25 11:19:18 -0800454 (void)fence;
Pawin Vongmasa36653902018-11-15 00:10:25 -0800455
456 std::lock_guard<std::mutex> lock(mMappedLock);
457 if (mBuffer && mLocked) {
458 ALOGD("already mapped");
459 return C2_DUPLICATE;
460 }
461 if (!layout || !addr) {
462 ALOGD("wrong param");
463 return C2_BAD_VALUE;
464 }
465
Pawin Vongmasa36653902018-11-15 00:10:25 -0800466 if (!mBuffer) {
Marissa Wall2a24a302019-11-25 11:19:18 -0800467 status_t err = GraphicBufferMapper::get().importBuffer(
468 mHidlHandle.getNativeHandle(), mWidth, mHeight, mLayerCount,
469 mFormat, mGrallocUsage, mStride, &mBuffer);
470 if (err) {
471 ALOGE("failed transaction: importBuffer");
472 return C2_CORRUPTED;
Pawin Vongmasa36653902018-11-15 00:10:25 -0800473 }
474 if (mBuffer == nullptr) {
475 ALOGD("importBuffer returned null buffer");
476 return C2_CORRUPTED;
477 }
478 uint32_t generation = 0;
479 uint64_t igbp_id = 0;
480 uint32_t igbp_slot = 0;
481 if (mHandle) {
482 mHandle->getIgbpData(&generation, &igbp_id, &igbp_slot);
483 }
Pawin Vongmasa36653902018-11-15 00:10:25 -0800484
Marissa Wall2a24a302019-11-25 11:19:18 -0800485 mLockedHandle = C2HandleGralloc::WrapAndMoveNativeHandle(
486 mBuffer, mWidth, mHeight, mFormat, mGrallocUsage,
487 mStride, generation, igbp_id, igbp_slot);
Marissa Wall8806edc2019-06-21 09:50:47 -0700488 }
Praveen Chavan34493f12021-02-18 00:51:50 -0800489
490 // 'NATIVE' on Android means LITTLE_ENDIAN
491 constexpr C2PlaneInfo::endianness_t kEndianness = C2PlaneInfo::NATIVE;
492
Marissa Wall2a24a302019-11-25 11:19:18 -0800493 switch (mFormat) {
494 case static_cast<uint32_t>(PixelFormat4::RGBA_1010102): {
Lajos Molnar35d36cb2018-10-12 15:10:56 -0700495 // TRICKY: this is used for media as YUV444 in the case when it is queued directly to a
496 // Surface. In all other cases it is RGBA. We don't know which case it is here, so
497 // default to YUV for now.
498 void *pointer = nullptr;
Marissa Wall2a24a302019-11-25 11:19:18 -0800499 // TODO: fence
500 status_t err = GraphicBufferMapper::get().lock(
Chih-Yu Huang486aa5d2020-10-13 16:22:58 +0900501 const_cast<native_handle_t *>(mBuffer), grallocUsage, rect, &pointer);
Marissa Wall2a24a302019-11-25 11:19:18 -0800502 if (err) {
503 ALOGE("failed transaction: lock(RGBA_1010102)");
504 return C2_CORRUPTED;
Lajos Molnar35d36cb2018-10-12 15:10:56 -0700505 }
506 // treat as 32-bit values
507 addr[C2PlanarLayout::PLANE_Y] = (uint8_t *)pointer;
508 addr[C2PlanarLayout::PLANE_U] = (uint8_t *)pointer;
509 addr[C2PlanarLayout::PLANE_V] = (uint8_t *)pointer;
510 addr[C2PlanarLayout::PLANE_A] = (uint8_t *)pointer;
511 layout->type = C2PlanarLayout::TYPE_YUVA;
512 layout->numPlanes = 4;
513 layout->rootPlanes = 1;
514 layout->planes[C2PlanarLayout::PLANE_Y] = {
515 C2PlaneInfo::CHANNEL_Y, // channel
516 4, // colInc
Marissa Wall2a24a302019-11-25 11:19:18 -0800517 static_cast<int32_t>(4 * mStride), // rowInc
Lajos Molnar35d36cb2018-10-12 15:10:56 -0700518 1, // mColSampling
519 1, // mRowSampling
520 32, // allocatedDepth
521 10, // bitDepth
522 10, // rightShift
523 C2PlaneInfo::LITTLE_END, // endianness
524 C2PlanarLayout::PLANE_Y, // rootIx
525 0, // offset
526 };
527 layout->planes[C2PlanarLayout::PLANE_U] = {
528 C2PlaneInfo::CHANNEL_CB, // channel
529 4, // colInc
Marissa Wall2a24a302019-11-25 11:19:18 -0800530 static_cast<int32_t>(4 * mStride), // rowInc
Lajos Molnar35d36cb2018-10-12 15:10:56 -0700531 1, // mColSampling
532 1, // mRowSampling
533 32, // allocatedDepth
534 10, // bitDepth
535 0, // rightShift
536 C2PlaneInfo::LITTLE_END, // endianness
537 C2PlanarLayout::PLANE_Y, // rootIx
538 0, // offset
539 };
540 layout->planes[C2PlanarLayout::PLANE_V] = {
541 C2PlaneInfo::CHANNEL_CR, // channel
542 4, // colInc
Marissa Wall2a24a302019-11-25 11:19:18 -0800543 static_cast<int32_t>(4 * mStride), // rowInc
Lajos Molnar35d36cb2018-10-12 15:10:56 -0700544 1, // mColSampling
545 1, // mRowSampling
546 32, // allocatedDepth
547 10, // bitDepth
548 20, // rightShift
549 C2PlaneInfo::LITTLE_END, // endianness
550 C2PlanarLayout::PLANE_Y, // rootIx
551 0, // offset
552 };
553 layout->planes[C2PlanarLayout::PLANE_A] = {
554 C2PlaneInfo::CHANNEL_A, // channel
555 4, // colInc
Marissa Wall2a24a302019-11-25 11:19:18 -0800556 static_cast<int32_t>(4 * mStride), // rowInc
Lajos Molnar35d36cb2018-10-12 15:10:56 -0700557 1, // mColSampling
558 1, // mRowSampling
559 32, // allocatedDepth
560 2, // bitDepth
561 30, // rightShift
562 C2PlaneInfo::LITTLE_END, // endianness
563 C2PlanarLayout::PLANE_Y, // rootIx
564 0, // offset
565 };
566 break;
567 }
Pawin Vongmasa36653902018-11-15 00:10:25 -0800568
Marissa Wall2a24a302019-11-25 11:19:18 -0800569 case static_cast<uint32_t>(PixelFormat4::RGBA_8888):
Lajos Molnar35d36cb2018-10-12 15:10:56 -0700570 // TODO: alpha channel
571 // fall-through
Marissa Wall2a24a302019-11-25 11:19:18 -0800572 case static_cast<uint32_t>(PixelFormat4::RGBX_8888): {
Lajos Molnar35d36cb2018-10-12 15:10:56 -0700573 void *pointer = nullptr;
Marissa Wall2a24a302019-11-25 11:19:18 -0800574 // TODO: fence
575 status_t err = GraphicBufferMapper::get().lock(
Chih-Yu Huang486aa5d2020-10-13 16:22:58 +0900576 const_cast<native_handle_t*>(mBuffer), grallocUsage, rect, &pointer);
Marissa Wall2a24a302019-11-25 11:19:18 -0800577 if (err) {
578 ALOGE("failed transaction: lock(RGBA_8888)");
579 return C2_CORRUPTED;
Lajos Molnar35d36cb2018-10-12 15:10:56 -0700580 }
581 addr[C2PlanarLayout::PLANE_R] = (uint8_t *)pointer;
582 addr[C2PlanarLayout::PLANE_G] = (uint8_t *)pointer + 1;
583 addr[C2PlanarLayout::PLANE_B] = (uint8_t *)pointer + 2;
584 layout->type = C2PlanarLayout::TYPE_RGB;
585 layout->numPlanes = 3;
586 layout->rootPlanes = 1;
587 layout->planes[C2PlanarLayout::PLANE_R] = {
588 C2PlaneInfo::CHANNEL_R, // channel
589 4, // colInc
Marissa Wall2a24a302019-11-25 11:19:18 -0800590 static_cast<int32_t>(4 * mStride), // rowInc
Lajos Molnar35d36cb2018-10-12 15:10:56 -0700591 1, // mColSampling
592 1, // mRowSampling
593 8, // allocatedDepth
594 8, // bitDepth
595 0, // rightShift
596 C2PlaneInfo::NATIVE, // endianness
597 C2PlanarLayout::PLANE_R, // rootIx
598 0, // offset
599 };
600 layout->planes[C2PlanarLayout::PLANE_G] = {
601 C2PlaneInfo::CHANNEL_G, // channel
602 4, // colInc
Marissa Wall2a24a302019-11-25 11:19:18 -0800603 static_cast<int32_t>(4 * mStride), // rowInc
Lajos Molnar35d36cb2018-10-12 15:10:56 -0700604 1, // mColSampling
605 1, // mRowSampling
606 8, // allocatedDepth
607 8, // bitDepth
608 0, // rightShift
609 C2PlaneInfo::NATIVE, // endianness
610 C2PlanarLayout::PLANE_R, // rootIx
611 1, // offset
612 };
613 layout->planes[C2PlanarLayout::PLANE_B] = {
614 C2PlaneInfo::CHANNEL_B, // channel
615 4, // colInc
Marissa Wall2a24a302019-11-25 11:19:18 -0800616 static_cast<int32_t>(4 * mStride), // rowInc
Lajos Molnar35d36cb2018-10-12 15:10:56 -0700617 1, // mColSampling
618 1, // mRowSampling
619 8, // allocatedDepth
620 8, // bitDepth
621 0, // rightShift
622 C2PlaneInfo::NATIVE, // endianness
623 C2PlanarLayout::PLANE_R, // rootIx
624 2, // offset
625 };
626 break;
627 }
628
David Stevens1cadc75d2020-04-03 10:50:51 +0900629 case static_cast<uint32_t>(PixelFormat4::BLOB): {
630 void *pointer = nullptr;
631 // TODO: fence
632 status_t err = GraphicBufferMapper::get().lock(
Chih-Yu Huang486aa5d2020-10-13 16:22:58 +0900633 const_cast<native_handle_t*>(mBuffer), grallocUsage, rect, &pointer);
David Stevens1cadc75d2020-04-03 10:50:51 +0900634 if (err) {
635 ALOGE("failed transaction: lock(BLOB)");
636 return C2_CORRUPTED;
637 }
638 *addr = (uint8_t *)pointer;
639 break;
640 }
641
Wonsik Kim29e3c4d2020-09-02 12:19:44 -0700642 case static_cast<uint32_t>(PixelFormat4::YCBCR_422_SP):
643 // fall-through
644 case static_cast<uint32_t>(PixelFormat4::YCRCB_420_SP):
645 // fall-through
646 case static_cast<uint32_t>(PixelFormat4::YCBCR_422_I):
647 // fall-through
Marissa Wall2a24a302019-11-25 11:19:18 -0800648 case static_cast<uint32_t>(PixelFormat4::YCBCR_420_888):
Lajos Molnar35d36cb2018-10-12 15:10:56 -0700649 // fall-through
Wonsik Kim29e3c4d2020-09-02 12:19:44 -0700650 case static_cast<uint32_t>(PixelFormat4::YV12): {
Marissa Wall2a24a302019-11-25 11:19:18 -0800651 android_ycbcr ycbcrLayout;
652
653 status_t err = GraphicBufferMapper::get().lockYCbCr(
Chih-Yu Huang486aa5d2020-10-13 16:22:58 +0900654 const_cast<native_handle_t*>(mBuffer), grallocUsage, rect, &ycbcrLayout);
Marissa Wall2a24a302019-11-25 11:19:18 -0800655 if (err) {
Wonsik Kimd91f3fb2021-02-24 12:35:31 -0800656 ALOGE("failed transaction: lockYCbCr (err=%d)", err);
657 return C2_CORRUPTED;
658 }
659 if (!ycbcrLayout.y || !ycbcrLayout.cb || !ycbcrLayout.cr
660 || ycbcrLayout.ystride == 0
661 || ycbcrLayout.cstride == 0
662 || ycbcrLayout.chroma_step == 0) {
663 ALOGE("invalid layout: lockYCbCr (y=%s cb=%s cr=%s "
664 "ystride=%zu cstride=%zu chroma_step=%zu)",
665 ycbcrLayout.y ? "(non-null)" : "(null)",
666 ycbcrLayout.cb ? "(non-null)" : "(null)",
667 ycbcrLayout.cr ? "(non-null)" : "(null)",
668 ycbcrLayout.ystride, ycbcrLayout.cstride, ycbcrLayout.chroma_step);
Marissa Wall469b90a2019-11-06 10:12:43 -0800669 return C2_CORRUPTED;
Pawin Vongmasad032f2d2019-05-15 08:42:44 -0700670 }
Marissa Wall2a24a302019-11-25 11:19:18 -0800671
Pawin Vongmasa36653902018-11-15 00:10:25 -0800672 addr[C2PlanarLayout::PLANE_Y] = (uint8_t *)ycbcrLayout.y;
673 addr[C2PlanarLayout::PLANE_U] = (uint8_t *)ycbcrLayout.cb;
674 addr[C2PlanarLayout::PLANE_V] = (uint8_t *)ycbcrLayout.cr;
675 layout->type = C2PlanarLayout::TYPE_YUV;
676 layout->numPlanes = 3;
677 layout->rootPlanes = 3;
678 layout->planes[C2PlanarLayout::PLANE_Y] = {
679 C2PlaneInfo::CHANNEL_Y, // channel
680 1, // colInc
Marissa Wall2a24a302019-11-25 11:19:18 -0800681 (int32_t)ycbcrLayout.ystride, // rowInc
Pawin Vongmasa36653902018-11-15 00:10:25 -0800682 1, // mColSampling
683 1, // mRowSampling
684 8, // allocatedDepth
685 8, // bitDepth
686 0, // rightShift
687 C2PlaneInfo::NATIVE, // endianness
688 C2PlanarLayout::PLANE_Y, // rootIx
689 0, // offset
690 };
691 layout->planes[C2PlanarLayout::PLANE_U] = {
692 C2PlaneInfo::CHANNEL_CB, // channel
Marissa Wall2a24a302019-11-25 11:19:18 -0800693 (int32_t)ycbcrLayout.chroma_step, // colInc
694 (int32_t)ycbcrLayout.cstride, // rowInc
Pawin Vongmasa36653902018-11-15 00:10:25 -0800695 2, // mColSampling
696 2, // mRowSampling
697 8, // allocatedDepth
698 8, // bitDepth
699 0, // rightShift
700 C2PlaneInfo::NATIVE, // endianness
701 C2PlanarLayout::PLANE_U, // rootIx
702 0, // offset
703 };
704 layout->planes[C2PlanarLayout::PLANE_V] = {
705 C2PlaneInfo::CHANNEL_CR, // channel
Marissa Wall2a24a302019-11-25 11:19:18 -0800706 (int32_t)ycbcrLayout.chroma_step, // colInc
707 (int32_t)ycbcrLayout.cstride, // rowInc
Pawin Vongmasa36653902018-11-15 00:10:25 -0800708 2, // mColSampling
709 2, // mRowSampling
710 8, // allocatedDepth
711 8, // bitDepth
712 0, // rightShift
713 C2PlaneInfo::NATIVE, // endianness
714 C2PlanarLayout::PLANE_V, // rootIx
715 0, // offset
716 };
Pawin Vongmasa36653902018-11-15 00:10:25 -0800717 break;
718 }
Wonsik Kim29e3c4d2020-09-02 12:19:44 -0700719
720 case static_cast<uint32_t>(PixelFormat4::YCBCR_P010): {
Praveen Chavan6380fff2022-06-22 10:49:48 -0700721 // In Android T, P010 is relaxed to allow arbitrary stride for the Y and UV planes,
722 // try locking with the gralloc4 mapper first.
723 c2_status_t status = Gralloc4Mapper_lock(
724 const_cast<native_handle_t*>(mBuffer), grallocUsage, rect, layout, addr);
725 if (status == C2_OK) {
726 break;
727 }
728
Wonsik Kim29e3c4d2020-09-02 12:19:44 -0700729 void *pointer = nullptr;
730 status_t err = GraphicBufferMapper::get().lock(
731 const_cast<native_handle_t *>(mBuffer), grallocUsage, rect, &pointer);
732 if (err) {
733 ALOGE("failed transaction: lock(YCBCR_P010)");
734 return C2_CORRUPTED;
735 }
736 addr[C2PlanarLayout::PLANE_Y] = (uint8_t *)pointer;
737 addr[C2PlanarLayout::PLANE_U] = (uint8_t *)pointer + mStride * 2 * rect.height();
738 addr[C2PlanarLayout::PLANE_V] = addr[C2PlanarLayout::PLANE_U] + 2;
739 layout->type = C2PlanarLayout::TYPE_YUV;
740 layout->numPlanes = 3;
741 layout->rootPlanes = 2;
742 layout->planes[C2PlanarLayout::PLANE_Y] = {
743 C2PlaneInfo::CHANNEL_Y, // channel
744 2, // colInc
745 static_cast<int32_t>(2 * mStride), // rowInc
746 1, // mColSampling
747 1, // mRowSampling
748 16, // allocatedDepth
749 10, // bitDepth
750 6, // rightShift
Praveen Chavan34493f12021-02-18 00:51:50 -0800751 kEndianness, // endianness
Wonsik Kim29e3c4d2020-09-02 12:19:44 -0700752 C2PlanarLayout::PLANE_Y, // rootIx
753 0, // offset
754 };
755 layout->planes[C2PlanarLayout::PLANE_U] = {
756 C2PlaneInfo::CHANNEL_CB, // channel
757 4, // colInc
758 static_cast<int32_t>(2 * mStride), // rowInc
759 2, // mColSampling
760 2, // mRowSampling
761 16, // allocatedDepth
762 10, // bitDepth
763 6, // rightShift
Praveen Chavan34493f12021-02-18 00:51:50 -0800764 kEndianness, // endianness
Wonsik Kim29e3c4d2020-09-02 12:19:44 -0700765 C2PlanarLayout::PLANE_U, // rootIx
766 0, // offset
767 };
768 layout->planes[C2PlanarLayout::PLANE_V] = {
769 C2PlaneInfo::CHANNEL_CR, // channel
770 4, // colInc
771 static_cast<int32_t>(2 * mStride), // rowInc
772 2, // mColSampling
773 2, // mRowSampling
774 16, // allocatedDepth
775 10, // bitDepth
776 6, // rightShift
Praveen Chavan34493f12021-02-18 00:51:50 -0800777 kEndianness, // endianness
Wonsik Kim29e3c4d2020-09-02 12:19:44 -0700778 C2PlanarLayout::PLANE_U, // rootIx
779 2, // offset
780 };
781 break;
782 }
783
784 default: {
Praveen Chavan34493f12021-02-18 00:51:50 -0800785 // We don't know what it is, let's try to lock it with gralloc4
Wonsik Kim29e3c4d2020-09-02 12:19:44 -0700786 android_ycbcr ycbcrLayout;
Harish Mahendrakar7dc54f92022-06-30 20:36:23 -0700787 if (isAtLeastT()) {
788 c2_status_t status = Gralloc4Mapper_lock(
789 const_cast<native_handle_t*>(mBuffer), grallocUsage, rect, layout, addr);
790 if (status == C2_OK) {
791 break;
792 }
Praveen Chavan34493f12021-02-18 00:51:50 -0800793 }
Wonsik Kim29e3c4d2020-09-02 12:19:44 -0700794
Praveen Chavan34493f12021-02-18 00:51:50 -0800795 // fallback to lockYCbCr
Wonsik Kim29e3c4d2020-09-02 12:19:44 -0700796 status_t err = GraphicBufferMapper::get().lockYCbCr(
797 const_cast<native_handle_t*>(mBuffer), grallocUsage, rect, &ycbcrLayout);
Wonsik Kimd91f3fb2021-02-24 12:35:31 -0800798 if (err == OK && ycbcrLayout.y && ycbcrLayout.cb && ycbcrLayout.cr
799 && ycbcrLayout.ystride > 0
800 && ycbcrLayout.cstride > 0
801 && ycbcrLayout.chroma_step > 0) {
Wonsik Kim29e3c4d2020-09-02 12:19:44 -0700802 addr[C2PlanarLayout::PLANE_Y] = (uint8_t *)ycbcrLayout.y;
803 addr[C2PlanarLayout::PLANE_U] = (uint8_t *)ycbcrLayout.cb;
804 addr[C2PlanarLayout::PLANE_V] = (uint8_t *)ycbcrLayout.cr;
805 layout->type = C2PlanarLayout::TYPE_YUV;
806 layout->numPlanes = 3;
807 layout->rootPlanes = 3;
808 layout->planes[C2PlanarLayout::PLANE_Y] = {
809 C2PlaneInfo::CHANNEL_Y, // channel
810 1, // colInc
811 (int32_t)ycbcrLayout.ystride, // rowInc
812 1, // mColSampling
813 1, // mRowSampling
814 8, // allocatedDepth
815 8, // bitDepth
816 0, // rightShift
817 C2PlaneInfo::NATIVE, // endianness
818 C2PlanarLayout::PLANE_Y, // rootIx
819 0, // offset
820 };
821 layout->planes[C2PlanarLayout::PLANE_U] = {
822 C2PlaneInfo::CHANNEL_CB, // channel
823 (int32_t)ycbcrLayout.chroma_step, // colInc
824 (int32_t)ycbcrLayout.cstride, // rowInc
825 2, // mColSampling
826 2, // mRowSampling
827 8, // allocatedDepth
828 8, // bitDepth
829 0, // rightShift
830 C2PlaneInfo::NATIVE, // endianness
831 C2PlanarLayout::PLANE_U, // rootIx
832 0, // offset
833 };
834 layout->planes[C2PlanarLayout::PLANE_V] = {
835 C2PlaneInfo::CHANNEL_CR, // channel
836 (int32_t)ycbcrLayout.chroma_step, // colInc
837 (int32_t)ycbcrLayout.cstride, // rowInc
838 2, // mColSampling
839 2, // mRowSampling
840 8, // allocatedDepth
841 8, // bitDepth
842 0, // rightShift
843 C2PlaneInfo::NATIVE, // endianness
844 C2PlanarLayout::PLANE_V, // rootIx
845 0, // offset
846 };
Wonsik Kim29e3c4d2020-09-02 12:19:44 -0700847 break;
848 }
849
850 // We really don't know what this is; lock the buffer and pass it through ---
851 // the client may know how to interpret it.
Lajos Molnar8faebbc2021-06-30 17:07:42 -0700852
853 // unlock previous allocation if it was successful
854 if (err == OK) {
855 err = GraphicBufferMapper::get().unlock(mBuffer);
856 if (err) {
857 ALOGE("failed transaction: unlock");
858 return C2_CORRUPTED;
859 }
860 }
861
Wonsik Kim29e3c4d2020-09-02 12:19:44 -0700862 void *pointer = nullptr;
863 err = GraphicBufferMapper::get().lock(
864 const_cast<native_handle_t *>(mBuffer), grallocUsage, rect, &pointer);
865 if (err) {
866 ALOGE("failed transaction: lock(??? %x)", mFormat);
867 return C2_CORRUPTED;
868 }
869 addr[0] = (uint8_t *)pointer;
870 layout->type = C2PlanarLayout::TYPE_UNKNOWN;
871 layout->numPlanes = 1;
872 layout->rootPlanes = 1;
873 layout->planes[0] = {
874 // TODO: CHANNEL_UNKNOWN?
875 C2PlaneInfo::channel_t(0xFF), // channel
876 1, // colInc
877 int32_t(mStride), // rowInc
878 1, // mColSampling
879 1, // mRowSampling
880 8, // allocatedDepth
881 8, // bitDepth
882 0, // rightShift
883 C2PlaneInfo::NATIVE, // endianness
884 0, // rootIx
885 0, // offset
886 };
887 break;
888 }
Pawin Vongmasa36653902018-11-15 00:10:25 -0800889 }
890 mLocked = true;
891
Wonsik Kimf12bebc2022-03-24 16:25:03 -0700892 // handle interleaved formats
893 if (layout->type == C2PlanarLayout::TYPE_YUV && layout->rootPlanes == 3) {
894 intptr_t uvOffset = addr[C2PlanarLayout::PLANE_V] - addr[C2PlanarLayout::PLANE_U];
895 intptr_t uvColInc = layout->planes[C2PlanarLayout::PLANE_U].colInc;
896 if (uvOffset > 0 && uvOffset < uvColInc) {
897 layout->rootPlanes = 2;
898 layout->planes[C2PlanarLayout::PLANE_V].rootIx = C2PlanarLayout::PLANE_U;
899 layout->planes[C2PlanarLayout::PLANE_V].offset = uvOffset;
900 } else if (uvOffset < 0 && uvOffset > -uvColInc) {
901 layout->rootPlanes = 2;
902 layout->planes[C2PlanarLayout::PLANE_U].rootIx = C2PlanarLayout::PLANE_V;
903 layout->planes[C2PlanarLayout::PLANE_U].offset = -uvOffset;
904 }
905 }
906
907 ALOGV("C2AllocationGralloc::map: layout: type=%d numPlanes=%d rootPlanes=%d",
908 layout->type, layout->numPlanes, layout->rootPlanes);
909 for (int i = 0; i < layout->numPlanes; ++i) {
910 const C2PlaneInfo &plane = layout->planes[i];
911 ALOGV("C2AllocationGralloc::map: plane[%d]: colInc=%d rowInc=%d rootIx=%u offset=%u",
912 i, plane.colInc, plane.rowInc, plane.rootIx, plane.offset);
913 }
914
Pawin Vongmasa36653902018-11-15 00:10:25 -0800915 return C2_OK;
916}
917
918c2_status_t C2AllocationGralloc::unmap(
919 uint8_t **addr, C2Rect rect, C2Fence *fence /* nullable */) {
920 // TODO: check addr and size, use fence
921 (void)addr;
922 (void)rect;
Marissa Wall2a24a302019-11-25 11:19:18 -0800923 (void)fence;
Pawin Vongmasa36653902018-11-15 00:10:25 -0800924
925 std::lock_guard<std::mutex> lock(mMappedLock);
Marissa Wall2a24a302019-11-25 11:19:18 -0800926 // TODO: fence
927 status_t err = GraphicBufferMapper::get().unlock(mBuffer);
928 if (err) {
929 ALOGE("failed transaction: unlock");
930 return C2_CORRUPTED;
Pawin Vongmasad032f2d2019-05-15 08:42:44 -0700931 }
Marissa Wall2a24a302019-11-25 11:19:18 -0800932
933 mLocked = false;
934 return C2_OK;
Pawin Vongmasa36653902018-11-15 00:10:25 -0800935}
936
937bool C2AllocationGralloc::equals(const std::shared_ptr<const C2GraphicAllocation> &other) const {
938 return other && other->handle() == handle();
939}
940
941/* ===================================== GRALLOC ALLOCATOR ==================================== */
942class C2AllocatorGralloc::Impl {
943public:
944 Impl(id_t id, bool bufferQueue);
945
946 id_t getId() const {
947 return mTraits->id;
948 }
949
950 C2String getName() const {
951 return mTraits->name;
952 }
953
954 std::shared_ptr<const C2Allocator::Traits> getTraits() const {
955 return mTraits;
956 }
957
958 c2_status_t newGraphicAllocation(
959 uint32_t width, uint32_t height, uint32_t format, const C2MemoryUsage &usage,
960 std::shared_ptr<C2GraphicAllocation> *allocation);
961
962 c2_status_t priorGraphicAllocation(
963 const C2Handle *handle,
964 std::shared_ptr<C2GraphicAllocation> *allocation);
965
966 c2_status_t status() const { return mInit; }
967
968private:
969 std::shared_ptr<C2Allocator::Traits> mTraits;
970 c2_status_t mInit;
Pawin Vongmasa36653902018-11-15 00:10:25 -0800971 const bool mBufferQueue;
972};
973
974void _UnwrapNativeCodec2GrallocMetadata(
975 const C2Handle *const handle,
976 uint32_t *width, uint32_t *height, uint32_t *format,uint64_t *usage, uint32_t *stride,
977 uint32_t *generation, uint64_t *igbp_id, uint32_t *igbp_slot) {
978 (void)C2HandleGralloc::Import(handle, width, height, format, usage, stride,
979 generation, igbp_id, igbp_slot);
980}
981
982C2AllocatorGralloc::Impl::Impl(id_t id, bool bufferQueue)
983 : mInit(C2_OK), mBufferQueue(bufferQueue) {
984 // TODO: get this from allocator
985 C2MemoryUsage minUsage = { 0, 0 }, maxUsage = { ~(uint64_t)0, ~(uint64_t)0 };
986 Traits traits = { "android.allocator.gralloc", id, C2Allocator::GRAPHIC, minUsage, maxUsage };
987 mTraits = std::make_shared<C2Allocator::Traits>(traits);
Pawin Vongmasa36653902018-11-15 00:10:25 -0800988}
989
990c2_status_t C2AllocatorGralloc::Impl::newGraphicAllocation(
991 uint32_t width, uint32_t height, uint32_t format, const C2MemoryUsage &usage,
992 std::shared_ptr<C2GraphicAllocation> *allocation) {
993 uint64_t grallocUsage = static_cast<C2AndroidMemoryUsage>(usage).asGrallocUsage();
994 ALOGV("allocating buffer with usage %#llx => %#llx",
995 (long long)usage.expected, (long long)grallocUsage);
996
Marissa Wall2a24a302019-11-25 11:19:18 -0800997 buffer_handle_t buffer;
Pawin Vongmasad032f2d2019-05-15 08:42:44 -0700998
Marissa Wall2a24a302019-11-25 11:19:18 -0800999 uint32_t stride = 0;
Pawin Vongmasad032f2d2019-05-15 08:42:44 -07001000
Marissa Wall2a24a302019-11-25 11:19:18 -08001001 status_t err = GraphicBufferAllocator::get().allocateRawHandle(width, height, format,
1002 1u /* layer count */, grallocUsage, &buffer, &stride, "C2GrallocAllocation");
1003 if (err) {
1004 ALOGE("failed transaction: allocate");
1005 return C2_CORRUPTED;
Pawin Vongmasa36653902018-11-15 00:10:25 -08001006 }
Marissa Wall2a24a302019-11-25 11:19:18 -08001007
1008 hidl_handle hidlHandle;
1009 hidlHandle.setTo(const_cast<native_handle_t*>(buffer), true);
1010
1011 allocation->reset(new C2AllocationGralloc(
1012 width, height, format, 1u /* layer count */, grallocUsage, stride, hidlHandle,
1013 C2HandleGralloc::WrapAndMoveNativeHandle(
1014 hidlHandle, width, height,
1015 format, grallocUsage, stride,
1016 0, 0, mBufferQueue ? ~0 : 0),
1017 mTraits->id));
1018 return C2_OK;
Pawin Vongmasa36653902018-11-15 00:10:25 -08001019}
1020
1021c2_status_t C2AllocatorGralloc::Impl::priorGraphicAllocation(
1022 const C2Handle *handle,
1023 std::shared_ptr<C2GraphicAllocation> *allocation) {
Pawin Vongmasad032f2d2019-05-15 08:42:44 -07001024
Marissa Wall2a24a302019-11-25 11:19:18 -08001025 uint32_t generation;
1026 uint64_t igbp_id;
1027 uint32_t igbp_slot;
Pawin Vongmasad032f2d2019-05-15 08:42:44 -07001028
Marissa Wall2a24a302019-11-25 11:19:18 -08001029 uint32_t width;
1030 uint32_t height;
1031 uint32_t format;
1032 uint32_t layerCount = 1;
1033 uint64_t grallocUsage;
1034 uint32_t stride;
Pawin Vongmasad032f2d2019-05-15 08:42:44 -07001035
Marissa Wall2a24a302019-11-25 11:19:18 -08001036 const C2HandleGralloc *grallocHandle = C2HandleGralloc::Import(
1037 handle, &width, &height, &format, &grallocUsage, &stride,
1038 &generation, &igbp_id, &igbp_slot);
1039 if (grallocHandle == nullptr) {
1040 return C2_BAD_VALUE;
Pawin Vongmasa36653902018-11-15 00:10:25 -08001041 }
Marissa Wall2a24a302019-11-25 11:19:18 -08001042
1043 hidl_handle hidlHandle;
1044 hidlHandle.setTo(C2HandleGralloc::UnwrapNativeHandle(grallocHandle), true);
1045
1046 allocation->reset(new C2AllocationGralloc(
1047 width, height, format, layerCount,
1048 grallocUsage, stride, hidlHandle, grallocHandle, mTraits->id));
1049 return C2_OK;
Pawin Vongmasa36653902018-11-15 00:10:25 -08001050}
1051
1052C2AllocatorGralloc::C2AllocatorGralloc(id_t id, bool bufferQueue)
1053 : mImpl(new Impl(id, bufferQueue)) {}
1054
1055C2AllocatorGralloc::~C2AllocatorGralloc() { delete mImpl; }
1056
1057C2Allocator::id_t C2AllocatorGralloc::getId() const {
1058 return mImpl->getId();
1059}
1060
1061C2String C2AllocatorGralloc::getName() const {
1062 return mImpl->getName();
1063}
1064
1065std::shared_ptr<const C2Allocator::Traits> C2AllocatorGralloc::getTraits() const {
1066 return mImpl->getTraits();
1067}
1068
1069c2_status_t C2AllocatorGralloc::newGraphicAllocation(
1070 uint32_t width, uint32_t height, uint32_t format, C2MemoryUsage usage,
1071 std::shared_ptr<C2GraphicAllocation> *allocation) {
1072 return mImpl->newGraphicAllocation(width, height, format, usage, allocation);
1073}
1074
1075c2_status_t C2AllocatorGralloc::priorGraphicAllocation(
1076 const C2Handle *handle,
1077 std::shared_ptr<C2GraphicAllocation> *allocation) {
1078 return mImpl->priorGraphicAllocation(handle, allocation);
1079}
1080
1081c2_status_t C2AllocatorGralloc::status() const {
1082 return mImpl->status();
1083}
1084
John Stultz653ddd12020-09-19 05:26:24 +00001085// static
1086bool C2AllocatorGralloc::CheckHandle(const C2Handle* const o) {
1087 return C2HandleGralloc::IsValid(o);
Pawin Vongmasa36653902018-11-15 00:10:25 -08001088}
1089
1090} // namespace android