blob: d8d6f0690646aa38826f3f0d20c52c1128e70cf2 [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
57C2MemoryUsage C2AndroidMemoryUsage::FromGrallocUsage(uint64_t usage) {
58 // gralloc does not support WRITE_PROTECTED
59 return C2MemoryUsage(
60 ((usage & GRALLOC_USAGE_SW_READ_MASK) ? C2MemoryUsage::CPU_READ : 0) |
61 ((usage & GRALLOC_USAGE_SW_WRITE_MASK) ? C2MemoryUsage::CPU_WRITE : 0) |
62 ((usage & GRALLOC_USAGE_PROTECTED) ? C2MemoryUsage::READ_PROTECTED : 0) |
63 (usage & PASSTHROUGH_USAGE_MASK));
64}
65
66uint64_t C2AndroidMemoryUsage::asGrallocUsage() const {
67 // gralloc does not support WRITE_PROTECTED
68 return (((expected & C2MemoryUsage::CPU_READ) ? GRALLOC_USAGE_SW_READ_OFTEN : 0) |
69 ((expected & C2MemoryUsage::CPU_WRITE) ? GRALLOC_USAGE_SW_WRITE_OFTEN : 0) |
70 ((expected & C2MemoryUsage::READ_PROTECTED) ? GRALLOC_USAGE_PROTECTED : 0) |
71 (expected & PASSTHROUGH_USAGE_MASK));
72}
73
Pawin Vongmasad032f2d2019-05-15 08:42:44 -070074namespace /* unnamed */ {
75
Pawin Vongmasa36653902018-11-15 00:10:25 -080076/* ===================================== GRALLOC ALLOCATION ==================================== */
Pawin Vongmasa36653902018-11-15 00:10:25 -080077bool native_handle_is_invalid(const native_handle_t *const handle) {
78 // perform basic validation of a native handle
79 if (handle == nullptr) {
80 // null handle is considered valid
81 return false;
82 }
83 return ((size_t)handle->version != sizeof(native_handle_t) ||
84 handle->numFds < 0 ||
85 handle->numInts < 0 ||
86 // for sanity assume handles must occupy less memory than INT_MAX bytes
87 handle->numFds > int((INT_MAX - handle->version) / sizeof(int)) - handle->numInts);
88}
89
90class C2HandleGralloc : public C2Handle {
91private:
92 struct ExtraData {
93 uint32_t width;
94 uint32_t height;
95 uint32_t format;
96 uint32_t usage_lo;
97 uint32_t usage_hi;
98 uint32_t stride;
99 uint32_t generation;
100 uint32_t igbp_id_lo;
101 uint32_t igbp_id_hi;
102 uint32_t igbp_slot;
103 uint32_t magic;
104 };
105
106 enum {
107 NUM_INTS = sizeof(ExtraData) / sizeof(int),
108 };
109 const static uint32_t MAGIC = '\xc2gr\x00';
110
111 static
John Stultz653ddd12020-09-19 05:26:24 +0000112 const ExtraData* GetExtraData(const C2Handle *const handle) {
Pawin Vongmasa36653902018-11-15 00:10:25 -0800113 if (handle == nullptr
114 || native_handle_is_invalid(handle)
115 || handle->numInts < NUM_INTS) {
116 return nullptr;
117 }
118 return reinterpret_cast<const ExtraData*>(
119 &handle->data[handle->numFds + handle->numInts - NUM_INTS]);
120 }
121
122 static
John Stultz653ddd12020-09-19 05:26:24 +0000123 ExtraData *GetExtraData(C2Handle *const handle) {
124 return const_cast<ExtraData *>(GetExtraData(const_cast<const C2Handle *const>(handle)));
Pawin Vongmasa36653902018-11-15 00:10:25 -0800125 }
126
127public:
128 void getIgbpData(uint32_t *generation, uint64_t *igbp_id, uint32_t *igbp_slot) const {
John Stultz653ddd12020-09-19 05:26:24 +0000129 const ExtraData *ed = GetExtraData(this);
Pawin Vongmasa36653902018-11-15 00:10:25 -0800130 *generation = ed->generation;
131 *igbp_id = unsigned(ed->igbp_id_lo) | uint64_t(unsigned(ed->igbp_id_hi)) << 32;
132 *igbp_slot = ed->igbp_slot;
133 }
134
John Stultz653ddd12020-09-19 05:26:24 +0000135 static bool IsValid(const C2Handle *const o) {
Pawin Vongmasa36653902018-11-15 00:10:25 -0800136 if (o == nullptr) { // null handle is always valid
137 return true;
138 }
John Stultz653ddd12020-09-19 05:26:24 +0000139 const ExtraData *xd = GetExtraData(o);
Pawin Vongmasa36653902018-11-15 00:10:25 -0800140 // we cannot validate width/height/format/usage without accessing gralloc driver
141 return xd != nullptr && xd->magic == MAGIC;
142 }
143
Sungtak Leea4d13be2019-01-23 15:24:46 -0800144 static C2HandleGralloc* WrapAndMoveNativeHandle(
Pawin Vongmasa36653902018-11-15 00:10:25 -0800145 const native_handle_t *const handle,
146 uint32_t width, uint32_t height, uint32_t format, uint64_t usage,
147 uint32_t stride, uint32_t generation, uint64_t igbp_id = 0, uint32_t igbp_slot = 0) {
148 //CHECK(handle != nullptr);
149 if (native_handle_is_invalid(handle) ||
150 handle->numInts > int((INT_MAX - handle->version) / sizeof(int)) - NUM_INTS - handle->numFds) {
151 return nullptr;
152 }
153 ExtraData xd = {
154 width, height, format, uint32_t(usage & 0xFFFFFFFF), uint32_t(usage >> 32),
155 stride, generation, uint32_t(igbp_id & 0xFFFFFFFF), uint32_t(igbp_id >> 32),
156 igbp_slot, MAGIC
157 };
158 native_handle_t *res = native_handle_create(handle->numFds, handle->numInts + NUM_INTS);
159 if (res != nullptr) {
160 memcpy(&res->data, &handle->data, sizeof(int) * (handle->numFds + handle->numInts));
John Stultz653ddd12020-09-19 05:26:24 +0000161 *GetExtraData(res) = xd;
Pawin Vongmasa36653902018-11-15 00:10:25 -0800162 }
163 return reinterpret_cast<C2HandleGralloc *>(res);
164 }
165
Sungtak Leea4d13be2019-01-23 15:24:46 -0800166 static C2HandleGralloc* WrapNativeHandle(
167 const native_handle_t *const handle,
168 uint32_t width, uint32_t height, uint32_t format, uint64_t usage,
169 uint32_t stride, uint32_t generation, uint64_t igbp_id = 0, uint32_t igbp_slot = 0) {
170 if (handle == nullptr) {
171 return nullptr;
172 }
173 native_handle_t *clone = native_handle_clone(handle);
174 if (clone == nullptr) {
175 return nullptr;
176 }
177 C2HandleGralloc *res = WrapAndMoveNativeHandle(
178 clone, width, height, format, usage, stride, generation, igbp_id, igbp_slot);
179 if (res == nullptr) {
180 native_handle_close(clone);
181 }
182 native_handle_delete(clone);
183 return res;
184 }
185
Sungtak Lee08515812019-06-05 11:16:32 -0700186 static bool MigrateNativeHandle(
187 native_handle_t *handle,
188 uint32_t generation, uint64_t igbp_id, uint32_t igbp_slot) {
John Stultz653ddd12020-09-19 05:26:24 +0000189 if (handle == nullptr || !IsValid(handle)) {
Sungtak Lee08515812019-06-05 11:16:32 -0700190 return false;
191 }
John Stultz653ddd12020-09-19 05:26:24 +0000192 ExtraData *ed = GetExtraData(handle);
Sungtak Lee08515812019-06-05 11:16:32 -0700193 if (!ed) return false;
194 ed->generation = generation;
195 ed->igbp_id_lo = uint32_t(igbp_id & 0xFFFFFFFF);
196 ed->igbp_id_hi = uint32_t(igbp_id >> 32);
197 ed->igbp_slot = igbp_slot;
198 return true;
199 }
200
201
Pawin Vongmasa36653902018-11-15 00:10:25 -0800202 static native_handle_t* UnwrapNativeHandle(
203 const C2Handle *const handle) {
John Stultz653ddd12020-09-19 05:26:24 +0000204 const ExtraData *xd = GetExtraData(handle);
Pawin Vongmasa36653902018-11-15 00:10:25 -0800205 if (xd == nullptr || xd->magic != MAGIC) {
206 return nullptr;
207 }
208 native_handle_t *res = native_handle_create(handle->numFds, handle->numInts - NUM_INTS);
209 if (res != nullptr) {
210 memcpy(&res->data, &handle->data, sizeof(int) * (res->numFds + res->numInts));
211 }
212 return res;
213 }
214
Pawin Vongmasa36653902018-11-15 00:10:25 -0800215 static const C2HandleGralloc* Import(
216 const C2Handle *const handle,
217 uint32_t *width, uint32_t *height, uint32_t *format,
218 uint64_t *usage, uint32_t *stride,
219 uint32_t *generation, uint64_t *igbp_id, uint32_t *igbp_slot) {
John Stultz653ddd12020-09-19 05:26:24 +0000220 const ExtraData *xd = GetExtraData(handle);
Pawin Vongmasa36653902018-11-15 00:10:25 -0800221 if (xd == nullptr) {
222 return nullptr;
223 }
224 *width = xd->width;
225 *height = xd->height;
226 *format = xd->format;
227 *usage = xd->usage_lo | (uint64_t(xd->usage_hi) << 32);
228 *stride = xd->stride;
229 *generation = xd->generation;
230 *igbp_id = xd->igbp_id_lo | (uint64_t(xd->igbp_id_hi) << 32);
231 *igbp_slot = xd->igbp_slot;
232 return reinterpret_cast<const C2HandleGralloc *>(handle);
233 }
234};
235
Praveen Chavan34493f12021-02-18 00:51:50 -0800236static
237c2_status_t Gralloc4Mapper_lock(native_handle_t *handle, uint64_t usage, const Rect& bounds,
238 C2PlanarLayout *layout, uint8_t **addr) {
239 GraphicBufferMapper &mapper = GraphicBufferMapper::get();
240
241 std::vector<ui::PlaneLayout> planes;
242 // this method is only supported on Gralloc 4 or later
243 status_t err = mapper.getPlaneLayouts(handle, &planes);
244 if (err != NO_ERROR || planes.empty()) {
245 return C2_CANNOT_DO;
246 }
247
248 uint8_t *pointer = nullptr;
249 err = mapper.lock(handle, usage, bounds, (void **)&pointer, nullptr, nullptr);
250 if (err != NO_ERROR || pointer == nullptr) {
251 return C2_CORRUPTED;
252 }
253
254 using aidl::android::hardware::graphics::common::PlaneLayoutComponentType;
255 using aidl::android::hardware::graphics::common::PlaneLayoutComponent;
256
257 layout->type = C2PlanarLayout::TYPE_YUV;
258 layout->numPlanes = 0;
259 layout->rootPlanes = 0;
260
261 for (const ui::PlaneLayout &plane : planes) {
262 layout->rootPlanes++;
263 uint32_t lastOffsetInBits = 0;
264 uint32_t rootIx = 0;
265
266 for (const PlaneLayoutComponent &component : plane.components) {
267 if (!gralloc4::isStandardPlaneLayoutComponentType(component.type)) {
Praveen Chavan2c580d92022-02-24 12:23:46 -0800268 mapper.unlock(handle);
Praveen Chavan34493f12021-02-18 00:51:50 -0800269 return C2_CANNOT_DO;
270 }
271
272 uint32_t rightShiftBits = component.offsetInBits - lastOffsetInBits;
273 uint32_t allocatedDepthInBits = component.sizeInBits + rightShiftBits;
274 C2PlanarLayout::plane_index_t planeId;
275 C2PlaneInfo::channel_t channel;
276
277 switch (static_cast<PlaneLayoutComponentType>(component.type.value)) {
278 case PlaneLayoutComponentType::Y:
279 planeId = C2PlanarLayout::PLANE_Y;
280 channel = C2PlaneInfo::CHANNEL_Y;
281 break;
282 case PlaneLayoutComponentType::CB:
283 planeId = C2PlanarLayout::PLANE_U;
284 channel = C2PlaneInfo::CHANNEL_CB;
285 break;
286 case PlaneLayoutComponentType::CR:
287 planeId = C2PlanarLayout::PLANE_V;
288 channel = C2PlaneInfo::CHANNEL_CR;
289 break;
290 default:
Praveen Chavan2c580d92022-02-24 12:23:46 -0800291 mapper.unlock(handle);
Praveen Chavan34493f12021-02-18 00:51:50 -0800292 return C2_CORRUPTED;
293 }
294
295 addr[planeId] = pointer + plane.offsetInBytes + (component.offsetInBits / 8);
296 layout->planes[planeId] = {
297 channel, // channel
298 static_cast<int32_t>(plane.sampleIncrementInBits / 8), // colInc
299 static_cast<int32_t>(plane.strideInBytes), // rowInc
300 static_cast<uint32_t>(plane.horizontalSubsampling), // mColSampling
301 static_cast<uint32_t>(plane.verticalSubsampling), // mRowSampling
302 allocatedDepthInBits, // allocatedDepth (bits)
303 static_cast<uint32_t>(component.sizeInBits), // bitDepth (bits)
304 rightShiftBits, // rightShift (bits)
305 C2PlaneInfo::NATIVE, // endianness
306 rootIx, // rootIx
307 static_cast<uint32_t>(component.offsetInBits / 8), // offset (bytes)
308 };
309
310 layout->numPlanes++;
311 lastOffsetInBits = component.offsetInBits + component.sizeInBits;
312 rootIx++;
313 }
314 }
315 return C2_OK;
316}
317
Pawin Vongmasad032f2d2019-05-15 08:42:44 -0700318} // unnamed namespace
319
Praveen Chavan34493f12021-02-18 00:51:50 -0800320
Pawin Vongmasa36653902018-11-15 00:10:25 -0800321native_handle_t *UnwrapNativeCodec2GrallocHandle(const C2Handle *const handle) {
322 return C2HandleGralloc::UnwrapNativeHandle(handle);
323}
324
Pawin Vongmasa36653902018-11-15 00:10:25 -0800325C2Handle *WrapNativeCodec2GrallocHandle(
326 const native_handle_t *const handle,
327 uint32_t width, uint32_t height, uint32_t format, uint64_t usage, uint32_t stride,
328 uint32_t generation, uint64_t igbp_id, uint32_t igbp_slot) {
329 return C2HandleGralloc::WrapNativeHandle(handle, width, height, format, usage, stride,
330 generation, igbp_id, igbp_slot);
331}
332
Sungtak Lee08515812019-06-05 11:16:32 -0700333bool MigrateNativeCodec2GrallocHandle(
334 native_handle_t *handle,
335 uint32_t generation, uint64_t igbp_id, uint32_t igbp_slot) {
336 return C2HandleGralloc::MigrateNativeHandle(handle, generation, igbp_id, igbp_slot);
337}
338
339
Pawin Vongmasa36653902018-11-15 00:10:25 -0800340class C2AllocationGralloc : public C2GraphicAllocation {
341public:
342 virtual ~C2AllocationGralloc() override;
343
344 virtual c2_status_t map(
Chih-Yu Huang486aa5d2020-10-13 16:22:58 +0900345 C2Rect c2Rect, C2MemoryUsage usage, C2Fence *fence,
Pawin Vongmasa36653902018-11-15 00:10:25 -0800346 C2PlanarLayout *layout /* nonnull */, uint8_t **addr /* nonnull */) override;
347 virtual c2_status_t unmap(
348 uint8_t **addr /* nonnull */, C2Rect rect, C2Fence *fence /* nullable */) override;
349 virtual C2Allocator::id_t getAllocatorId() const override { return mAllocatorId; }
350 virtual const C2Handle *handle() const override { return mLockedHandle ? : mHandle; }
351 virtual bool equals(const std::shared_ptr<const C2GraphicAllocation> &other) const override;
352
353 // internal methods
354 // |handle| will be moved.
Marissa Wall2a24a302019-11-25 11:19:18 -0800355
Pawin Vongmasa36653902018-11-15 00:10:25 -0800356 C2AllocationGralloc(
Marissa Wall2a24a302019-11-25 11:19:18 -0800357 uint32_t width, uint32_t height,
358 uint32_t format, uint32_t layerCount,
359 uint64_t grallocUsage, uint32_t stride,
Marissa Wall8806edc2019-06-21 09:50:47 -0700360 hidl_handle &hidlHandle,
361 const C2HandleGralloc *const handle,
362 C2Allocator::id_t allocatorId);
Pawin Vongmasa36653902018-11-15 00:10:25 -0800363 int dup() const;
364 c2_status_t status() const;
365
366private:
Marissa Wall2a24a302019-11-25 11:19:18 -0800367 const uint32_t mWidth;
368 const uint32_t mHeight;
369 const uint32_t mFormat;
370 const uint32_t mLayerCount;
371 const uint64_t mGrallocUsage;
372 const uint32_t mStride;
Pawin Vongmasa36653902018-11-15 00:10:25 -0800373 const hidl_handle mHidlHandle;
374 const C2HandleGralloc *mHandle;
375 buffer_handle_t mBuffer;
376 const C2HandleGralloc *mLockedHandle;
377 bool mLocked;
378 C2Allocator::id_t mAllocatorId;
379 std::mutex mMappedLock;
380};
381
382C2AllocationGralloc::C2AllocationGralloc(
Marissa Wall2a24a302019-11-25 11:19:18 -0800383 uint32_t width, uint32_t height,
384 uint32_t format, uint32_t layerCount,
385 uint64_t grallocUsage, uint32_t stride,
Pawin Vongmasa36653902018-11-15 00:10:25 -0800386 hidl_handle &hidlHandle,
387 const C2HandleGralloc *const handle,
388 C2Allocator::id_t allocatorId)
Marissa Wall2a24a302019-11-25 11:19:18 -0800389 : C2GraphicAllocation(width, height),
390 mWidth(width),
391 mHeight(height),
392 mFormat(format),
393 mLayerCount(layerCount),
394 mGrallocUsage(grallocUsage),
395 mStride(stride),
Marissa Wall8806edc2019-06-21 09:50:47 -0700396 mHidlHandle(std::move(hidlHandle)),
397 mHandle(handle),
398 mBuffer(nullptr),
399 mLockedHandle(nullptr),
400 mLocked(false),
401 mAllocatorId(allocatorId) {
402}
403
Pawin Vongmasa36653902018-11-15 00:10:25 -0800404C2AllocationGralloc::~C2AllocationGralloc() {
Yichi Chenfa94a3b2018-12-08 00:06:25 +0800405 if (mBuffer && mLocked) {
Pawin Vongmasa36653902018-11-15 00:10:25 -0800406 // implementation ignores addresss and rect
407 uint8_t* addr[C2PlanarLayout::MAX_NUM_PLANES] = {};
408 unmap(addr, C2Rect(), nullptr);
409 }
Yichi Chenfa94a3b2018-12-08 00:06:25 +0800410 if (mBuffer) {
Marissa Wall2a24a302019-11-25 11:19:18 -0800411 status_t err = GraphicBufferMapper::get().freeBuffer(mBuffer);
412 if (err) {
413 ALOGE("failed transaction: freeBuffer");
Pawin Vongmasad032f2d2019-05-15 08:42:44 -0700414 }
Yichi Chenfa94a3b2018-12-08 00:06:25 +0800415 }
416 if (mHandle) {
417 native_handle_delete(
418 const_cast<native_handle_t *>(reinterpret_cast<const native_handle_t *>(mHandle)));
419 }
Sungtak Lee2729dcf2019-01-18 13:15:07 -0800420 if (mLockedHandle) {
421 native_handle_delete(
422 const_cast<native_handle_t *>(
423 reinterpret_cast<const native_handle_t *>(mLockedHandle)));
424 }
Pawin Vongmasa36653902018-11-15 00:10:25 -0800425}
426
427c2_status_t C2AllocationGralloc::map(
Chih-Yu Huang486aa5d2020-10-13 16:22:58 +0900428 C2Rect c2Rect, C2MemoryUsage usage, C2Fence *fence,
Pawin Vongmasa36653902018-11-15 00:10:25 -0800429 C2PlanarLayout *layout /* nonnull */, uint8_t **addr /* nonnull */) {
Chih-Yu Huang486aa5d2020-10-13 16:22:58 +0900430 const Rect rect{(int32_t)c2Rect.left, (int32_t)c2Rect.top,
431 (int32_t)(c2Rect.left + c2Rect.width) /* right */,
432 (int32_t)(c2Rect.top + c2Rect.height) /* bottom */};
433
Pawin Vongmasa36653902018-11-15 00:10:25 -0800434 uint64_t grallocUsage = static_cast<C2AndroidMemoryUsage>(usage).asGrallocUsage();
435 ALOGV("mapping buffer with usage %#llx => %#llx",
436 (long long)usage.expected, (long long)grallocUsage);
437
438 // TODO
Marissa Wall2a24a302019-11-25 11:19:18 -0800439 (void)fence;
Pawin Vongmasa36653902018-11-15 00:10:25 -0800440
441 std::lock_guard<std::mutex> lock(mMappedLock);
442 if (mBuffer && mLocked) {
443 ALOGD("already mapped");
444 return C2_DUPLICATE;
445 }
446 if (!layout || !addr) {
447 ALOGD("wrong param");
448 return C2_BAD_VALUE;
449 }
450
Pawin Vongmasa36653902018-11-15 00:10:25 -0800451 if (!mBuffer) {
Marissa Wall2a24a302019-11-25 11:19:18 -0800452 status_t err = GraphicBufferMapper::get().importBuffer(
453 mHidlHandle.getNativeHandle(), mWidth, mHeight, mLayerCount,
454 mFormat, mGrallocUsage, mStride, &mBuffer);
455 if (err) {
456 ALOGE("failed transaction: importBuffer");
457 return C2_CORRUPTED;
Pawin Vongmasa36653902018-11-15 00:10:25 -0800458 }
459 if (mBuffer == nullptr) {
460 ALOGD("importBuffer returned null buffer");
461 return C2_CORRUPTED;
462 }
463 uint32_t generation = 0;
464 uint64_t igbp_id = 0;
465 uint32_t igbp_slot = 0;
466 if (mHandle) {
467 mHandle->getIgbpData(&generation, &igbp_id, &igbp_slot);
468 }
Pawin Vongmasa36653902018-11-15 00:10:25 -0800469
Marissa Wall2a24a302019-11-25 11:19:18 -0800470 mLockedHandle = C2HandleGralloc::WrapAndMoveNativeHandle(
471 mBuffer, mWidth, mHeight, mFormat, mGrallocUsage,
472 mStride, generation, igbp_id, igbp_slot);
Marissa Wall8806edc2019-06-21 09:50:47 -0700473 }
Praveen Chavan34493f12021-02-18 00:51:50 -0800474
475 // 'NATIVE' on Android means LITTLE_ENDIAN
476 constexpr C2PlaneInfo::endianness_t kEndianness = C2PlaneInfo::NATIVE;
477
Marissa Wall2a24a302019-11-25 11:19:18 -0800478 switch (mFormat) {
479 case static_cast<uint32_t>(PixelFormat4::RGBA_1010102): {
Lajos Molnar35d36cb2018-10-12 15:10:56 -0700480 // TRICKY: this is used for media as YUV444 in the case when it is queued directly to a
481 // Surface. In all other cases it is RGBA. We don't know which case it is here, so
482 // default to YUV for now.
483 void *pointer = nullptr;
Marissa Wall2a24a302019-11-25 11:19:18 -0800484 // TODO: fence
485 status_t err = GraphicBufferMapper::get().lock(
Chih-Yu Huang486aa5d2020-10-13 16:22:58 +0900486 const_cast<native_handle_t *>(mBuffer), grallocUsage, rect, &pointer);
Marissa Wall2a24a302019-11-25 11:19:18 -0800487 if (err) {
488 ALOGE("failed transaction: lock(RGBA_1010102)");
489 return C2_CORRUPTED;
Lajos Molnar35d36cb2018-10-12 15:10:56 -0700490 }
491 // treat as 32-bit values
492 addr[C2PlanarLayout::PLANE_Y] = (uint8_t *)pointer;
493 addr[C2PlanarLayout::PLANE_U] = (uint8_t *)pointer;
494 addr[C2PlanarLayout::PLANE_V] = (uint8_t *)pointer;
495 addr[C2PlanarLayout::PLANE_A] = (uint8_t *)pointer;
496 layout->type = C2PlanarLayout::TYPE_YUVA;
497 layout->numPlanes = 4;
498 layout->rootPlanes = 1;
499 layout->planes[C2PlanarLayout::PLANE_Y] = {
500 C2PlaneInfo::CHANNEL_Y, // channel
501 4, // colInc
Marissa Wall2a24a302019-11-25 11:19:18 -0800502 static_cast<int32_t>(4 * mStride), // rowInc
Lajos Molnar35d36cb2018-10-12 15:10:56 -0700503 1, // mColSampling
504 1, // mRowSampling
505 32, // allocatedDepth
506 10, // bitDepth
507 10, // rightShift
508 C2PlaneInfo::LITTLE_END, // endianness
509 C2PlanarLayout::PLANE_Y, // rootIx
510 0, // offset
511 };
512 layout->planes[C2PlanarLayout::PLANE_U] = {
513 C2PlaneInfo::CHANNEL_CB, // channel
514 4, // colInc
Marissa Wall2a24a302019-11-25 11:19:18 -0800515 static_cast<int32_t>(4 * mStride), // rowInc
Lajos Molnar35d36cb2018-10-12 15:10:56 -0700516 1, // mColSampling
517 1, // mRowSampling
518 32, // allocatedDepth
519 10, // bitDepth
520 0, // rightShift
521 C2PlaneInfo::LITTLE_END, // endianness
522 C2PlanarLayout::PLANE_Y, // rootIx
523 0, // offset
524 };
525 layout->planes[C2PlanarLayout::PLANE_V] = {
526 C2PlaneInfo::CHANNEL_CR, // channel
527 4, // colInc
Marissa Wall2a24a302019-11-25 11:19:18 -0800528 static_cast<int32_t>(4 * mStride), // rowInc
Lajos Molnar35d36cb2018-10-12 15:10:56 -0700529 1, // mColSampling
530 1, // mRowSampling
531 32, // allocatedDepth
532 10, // bitDepth
533 20, // rightShift
534 C2PlaneInfo::LITTLE_END, // endianness
535 C2PlanarLayout::PLANE_Y, // rootIx
536 0, // offset
537 };
538 layout->planes[C2PlanarLayout::PLANE_A] = {
539 C2PlaneInfo::CHANNEL_A, // channel
540 4, // colInc
Marissa Wall2a24a302019-11-25 11:19:18 -0800541 static_cast<int32_t>(4 * mStride), // rowInc
Lajos Molnar35d36cb2018-10-12 15:10:56 -0700542 1, // mColSampling
543 1, // mRowSampling
544 32, // allocatedDepth
545 2, // bitDepth
546 30, // rightShift
547 C2PlaneInfo::LITTLE_END, // endianness
548 C2PlanarLayout::PLANE_Y, // rootIx
549 0, // offset
550 };
551 break;
552 }
Pawin Vongmasa36653902018-11-15 00:10:25 -0800553
Marissa Wall2a24a302019-11-25 11:19:18 -0800554 case static_cast<uint32_t>(PixelFormat4::RGBA_8888):
Lajos Molnar35d36cb2018-10-12 15:10:56 -0700555 // TODO: alpha channel
556 // fall-through
Marissa Wall2a24a302019-11-25 11:19:18 -0800557 case static_cast<uint32_t>(PixelFormat4::RGBX_8888): {
Lajos Molnar35d36cb2018-10-12 15:10:56 -0700558 void *pointer = nullptr;
Marissa Wall2a24a302019-11-25 11:19:18 -0800559 // TODO: fence
560 status_t err = GraphicBufferMapper::get().lock(
Chih-Yu Huang486aa5d2020-10-13 16:22:58 +0900561 const_cast<native_handle_t*>(mBuffer), grallocUsage, rect, &pointer);
Marissa Wall2a24a302019-11-25 11:19:18 -0800562 if (err) {
563 ALOGE("failed transaction: lock(RGBA_8888)");
564 return C2_CORRUPTED;
Lajos Molnar35d36cb2018-10-12 15:10:56 -0700565 }
566 addr[C2PlanarLayout::PLANE_R] = (uint8_t *)pointer;
567 addr[C2PlanarLayout::PLANE_G] = (uint8_t *)pointer + 1;
568 addr[C2PlanarLayout::PLANE_B] = (uint8_t *)pointer + 2;
569 layout->type = C2PlanarLayout::TYPE_RGB;
570 layout->numPlanes = 3;
571 layout->rootPlanes = 1;
572 layout->planes[C2PlanarLayout::PLANE_R] = {
573 C2PlaneInfo::CHANNEL_R, // channel
574 4, // colInc
Marissa Wall2a24a302019-11-25 11:19:18 -0800575 static_cast<int32_t>(4 * mStride), // rowInc
Lajos Molnar35d36cb2018-10-12 15:10:56 -0700576 1, // mColSampling
577 1, // mRowSampling
578 8, // allocatedDepth
579 8, // bitDepth
580 0, // rightShift
581 C2PlaneInfo::NATIVE, // endianness
582 C2PlanarLayout::PLANE_R, // rootIx
583 0, // offset
584 };
585 layout->planes[C2PlanarLayout::PLANE_G] = {
586 C2PlaneInfo::CHANNEL_G, // channel
587 4, // colInc
Marissa Wall2a24a302019-11-25 11:19:18 -0800588 static_cast<int32_t>(4 * mStride), // rowInc
Lajos Molnar35d36cb2018-10-12 15:10:56 -0700589 1, // mColSampling
590 1, // mRowSampling
591 8, // allocatedDepth
592 8, // bitDepth
593 0, // rightShift
594 C2PlaneInfo::NATIVE, // endianness
595 C2PlanarLayout::PLANE_R, // rootIx
596 1, // offset
597 };
598 layout->planes[C2PlanarLayout::PLANE_B] = {
599 C2PlaneInfo::CHANNEL_B, // channel
600 4, // colInc
Marissa Wall2a24a302019-11-25 11:19:18 -0800601 static_cast<int32_t>(4 * mStride), // rowInc
Lajos Molnar35d36cb2018-10-12 15:10:56 -0700602 1, // mColSampling
603 1, // mRowSampling
604 8, // allocatedDepth
605 8, // bitDepth
606 0, // rightShift
607 C2PlaneInfo::NATIVE, // endianness
608 C2PlanarLayout::PLANE_R, // rootIx
609 2, // offset
610 };
611 break;
612 }
613
David Stevens1cadc75d2020-04-03 10:50:51 +0900614 case static_cast<uint32_t>(PixelFormat4::BLOB): {
615 void *pointer = nullptr;
616 // TODO: fence
617 status_t err = GraphicBufferMapper::get().lock(
Chih-Yu Huang486aa5d2020-10-13 16:22:58 +0900618 const_cast<native_handle_t*>(mBuffer), grallocUsage, rect, &pointer);
David Stevens1cadc75d2020-04-03 10:50:51 +0900619 if (err) {
620 ALOGE("failed transaction: lock(BLOB)");
621 return C2_CORRUPTED;
622 }
623 *addr = (uint8_t *)pointer;
624 break;
625 }
626
Wonsik Kim29e3c4d2020-09-02 12:19:44 -0700627 case static_cast<uint32_t>(PixelFormat4::YCBCR_422_SP):
628 // fall-through
629 case static_cast<uint32_t>(PixelFormat4::YCRCB_420_SP):
630 // fall-through
631 case static_cast<uint32_t>(PixelFormat4::YCBCR_422_I):
632 // fall-through
Marissa Wall2a24a302019-11-25 11:19:18 -0800633 case static_cast<uint32_t>(PixelFormat4::YCBCR_420_888):
Lajos Molnar35d36cb2018-10-12 15:10:56 -0700634 // fall-through
Wonsik Kim29e3c4d2020-09-02 12:19:44 -0700635 case static_cast<uint32_t>(PixelFormat4::YV12): {
Marissa Wall2a24a302019-11-25 11:19:18 -0800636 android_ycbcr ycbcrLayout;
637
638 status_t err = GraphicBufferMapper::get().lockYCbCr(
Chih-Yu Huang486aa5d2020-10-13 16:22:58 +0900639 const_cast<native_handle_t*>(mBuffer), grallocUsage, rect, &ycbcrLayout);
Marissa Wall2a24a302019-11-25 11:19:18 -0800640 if (err) {
Wonsik Kimd91f3fb2021-02-24 12:35:31 -0800641 ALOGE("failed transaction: lockYCbCr (err=%d)", err);
642 return C2_CORRUPTED;
643 }
644 if (!ycbcrLayout.y || !ycbcrLayout.cb || !ycbcrLayout.cr
645 || ycbcrLayout.ystride == 0
646 || ycbcrLayout.cstride == 0
647 || ycbcrLayout.chroma_step == 0) {
648 ALOGE("invalid layout: lockYCbCr (y=%s cb=%s cr=%s "
649 "ystride=%zu cstride=%zu chroma_step=%zu)",
650 ycbcrLayout.y ? "(non-null)" : "(null)",
651 ycbcrLayout.cb ? "(non-null)" : "(null)",
652 ycbcrLayout.cr ? "(non-null)" : "(null)",
653 ycbcrLayout.ystride, ycbcrLayout.cstride, ycbcrLayout.chroma_step);
Marissa Wall469b90a2019-11-06 10:12:43 -0800654 return C2_CORRUPTED;
Pawin Vongmasad032f2d2019-05-15 08:42:44 -0700655 }
Marissa Wall2a24a302019-11-25 11:19:18 -0800656
Pawin Vongmasa36653902018-11-15 00:10:25 -0800657 addr[C2PlanarLayout::PLANE_Y] = (uint8_t *)ycbcrLayout.y;
658 addr[C2PlanarLayout::PLANE_U] = (uint8_t *)ycbcrLayout.cb;
659 addr[C2PlanarLayout::PLANE_V] = (uint8_t *)ycbcrLayout.cr;
660 layout->type = C2PlanarLayout::TYPE_YUV;
661 layout->numPlanes = 3;
662 layout->rootPlanes = 3;
663 layout->planes[C2PlanarLayout::PLANE_Y] = {
664 C2PlaneInfo::CHANNEL_Y, // channel
665 1, // colInc
Marissa Wall2a24a302019-11-25 11:19:18 -0800666 (int32_t)ycbcrLayout.ystride, // rowInc
Pawin Vongmasa36653902018-11-15 00:10:25 -0800667 1, // mColSampling
668 1, // mRowSampling
669 8, // allocatedDepth
670 8, // bitDepth
671 0, // rightShift
672 C2PlaneInfo::NATIVE, // endianness
673 C2PlanarLayout::PLANE_Y, // rootIx
674 0, // offset
675 };
676 layout->planes[C2PlanarLayout::PLANE_U] = {
677 C2PlaneInfo::CHANNEL_CB, // channel
Marissa Wall2a24a302019-11-25 11:19:18 -0800678 (int32_t)ycbcrLayout.chroma_step, // colInc
679 (int32_t)ycbcrLayout.cstride, // rowInc
Pawin Vongmasa36653902018-11-15 00:10:25 -0800680 2, // mColSampling
681 2, // mRowSampling
682 8, // allocatedDepth
683 8, // bitDepth
684 0, // rightShift
685 C2PlaneInfo::NATIVE, // endianness
686 C2PlanarLayout::PLANE_U, // rootIx
687 0, // offset
688 };
689 layout->planes[C2PlanarLayout::PLANE_V] = {
690 C2PlaneInfo::CHANNEL_CR, // channel
Marissa Wall2a24a302019-11-25 11:19:18 -0800691 (int32_t)ycbcrLayout.chroma_step, // colInc
692 (int32_t)ycbcrLayout.cstride, // rowInc
Pawin Vongmasa36653902018-11-15 00:10:25 -0800693 2, // mColSampling
694 2, // mRowSampling
695 8, // allocatedDepth
696 8, // bitDepth
697 0, // rightShift
698 C2PlaneInfo::NATIVE, // endianness
699 C2PlanarLayout::PLANE_V, // rootIx
700 0, // offset
701 };
702 // handle interleaved formats
703 intptr_t uvOffset = addr[C2PlanarLayout::PLANE_V] - addr[C2PlanarLayout::PLANE_U];
Marissa Wall2a24a302019-11-25 11:19:18 -0800704 if (uvOffset > 0 && uvOffset < (intptr_t)ycbcrLayout.chroma_step) {
Pawin Vongmasa36653902018-11-15 00:10:25 -0800705 layout->rootPlanes = 2;
706 layout->planes[C2PlanarLayout::PLANE_V].rootIx = C2PlanarLayout::PLANE_U;
707 layout->planes[C2PlanarLayout::PLANE_V].offset = uvOffset;
Marissa Wall2a24a302019-11-25 11:19:18 -0800708 } else if (uvOffset < 0 && uvOffset > -(intptr_t)ycbcrLayout.chroma_step) {
Pawin Vongmasa36653902018-11-15 00:10:25 -0800709 layout->rootPlanes = 2;
710 layout->planes[C2PlanarLayout::PLANE_U].rootIx = C2PlanarLayout::PLANE_V;
711 layout->planes[C2PlanarLayout::PLANE_U].offset = -uvOffset;
712 }
713 break;
714 }
Wonsik Kim29e3c4d2020-09-02 12:19:44 -0700715
716 case static_cast<uint32_t>(PixelFormat4::YCBCR_P010): {
717 void *pointer = nullptr;
718 status_t err = GraphicBufferMapper::get().lock(
719 const_cast<native_handle_t *>(mBuffer), grallocUsage, rect, &pointer);
720 if (err) {
721 ALOGE("failed transaction: lock(YCBCR_P010)");
722 return C2_CORRUPTED;
723 }
724 addr[C2PlanarLayout::PLANE_Y] = (uint8_t *)pointer;
725 addr[C2PlanarLayout::PLANE_U] = (uint8_t *)pointer + mStride * 2 * rect.height();
726 addr[C2PlanarLayout::PLANE_V] = addr[C2PlanarLayout::PLANE_U] + 2;
727 layout->type = C2PlanarLayout::TYPE_YUV;
728 layout->numPlanes = 3;
729 layout->rootPlanes = 2;
730 layout->planes[C2PlanarLayout::PLANE_Y] = {
731 C2PlaneInfo::CHANNEL_Y, // channel
732 2, // colInc
733 static_cast<int32_t>(2 * mStride), // rowInc
734 1, // mColSampling
735 1, // mRowSampling
736 16, // allocatedDepth
737 10, // bitDepth
738 6, // rightShift
Praveen Chavan34493f12021-02-18 00:51:50 -0800739 kEndianness, // endianness
Wonsik Kim29e3c4d2020-09-02 12:19:44 -0700740 C2PlanarLayout::PLANE_Y, // rootIx
741 0, // offset
742 };
743 layout->planes[C2PlanarLayout::PLANE_U] = {
744 C2PlaneInfo::CHANNEL_CB, // channel
745 4, // colInc
746 static_cast<int32_t>(2 * mStride), // rowInc
747 2, // mColSampling
748 2, // mRowSampling
749 16, // allocatedDepth
750 10, // bitDepth
751 6, // rightShift
Praveen Chavan34493f12021-02-18 00:51:50 -0800752 kEndianness, // endianness
Wonsik Kim29e3c4d2020-09-02 12:19:44 -0700753 C2PlanarLayout::PLANE_U, // rootIx
754 0, // offset
755 };
756 layout->planes[C2PlanarLayout::PLANE_V] = {
757 C2PlaneInfo::CHANNEL_CR, // channel
758 4, // colInc
759 static_cast<int32_t>(2 * mStride), // rowInc
760 2, // mColSampling
761 2, // mRowSampling
762 16, // allocatedDepth
763 10, // bitDepth
764 6, // rightShift
Praveen Chavan34493f12021-02-18 00:51:50 -0800765 kEndianness, // endianness
Wonsik Kim29e3c4d2020-09-02 12:19:44 -0700766 C2PlanarLayout::PLANE_U, // rootIx
767 2, // offset
768 };
769 break;
770 }
771
772 default: {
Praveen Chavan34493f12021-02-18 00:51:50 -0800773 // We don't know what it is, let's try to lock it with gralloc4
Wonsik Kim29e3c4d2020-09-02 12:19:44 -0700774 android_ycbcr ycbcrLayout;
Praveen Chavan34493f12021-02-18 00:51:50 -0800775 c2_status_t status = Gralloc4Mapper_lock(
776 const_cast<native_handle_t*>(mBuffer), grallocUsage, rect, layout, addr);
777 if (status == C2_OK) {
778 break;
779 }
Wonsik Kim29e3c4d2020-09-02 12:19:44 -0700780
Praveen Chavan34493f12021-02-18 00:51:50 -0800781 // fallback to lockYCbCr
Wonsik Kim29e3c4d2020-09-02 12:19:44 -0700782 status_t err = GraphicBufferMapper::get().lockYCbCr(
783 const_cast<native_handle_t*>(mBuffer), grallocUsage, rect, &ycbcrLayout);
Wonsik Kimd91f3fb2021-02-24 12:35:31 -0800784 if (err == OK && ycbcrLayout.y && ycbcrLayout.cb && ycbcrLayout.cr
785 && ycbcrLayout.ystride > 0
786 && ycbcrLayout.cstride > 0
787 && ycbcrLayout.chroma_step > 0) {
Wonsik Kim29e3c4d2020-09-02 12:19:44 -0700788 addr[C2PlanarLayout::PLANE_Y] = (uint8_t *)ycbcrLayout.y;
789 addr[C2PlanarLayout::PLANE_U] = (uint8_t *)ycbcrLayout.cb;
790 addr[C2PlanarLayout::PLANE_V] = (uint8_t *)ycbcrLayout.cr;
791 layout->type = C2PlanarLayout::TYPE_YUV;
792 layout->numPlanes = 3;
793 layout->rootPlanes = 3;
794 layout->planes[C2PlanarLayout::PLANE_Y] = {
795 C2PlaneInfo::CHANNEL_Y, // channel
796 1, // colInc
797 (int32_t)ycbcrLayout.ystride, // rowInc
798 1, // mColSampling
799 1, // mRowSampling
800 8, // allocatedDepth
801 8, // bitDepth
802 0, // rightShift
803 C2PlaneInfo::NATIVE, // endianness
804 C2PlanarLayout::PLANE_Y, // rootIx
805 0, // offset
806 };
807 layout->planes[C2PlanarLayout::PLANE_U] = {
808 C2PlaneInfo::CHANNEL_CB, // channel
809 (int32_t)ycbcrLayout.chroma_step, // colInc
810 (int32_t)ycbcrLayout.cstride, // rowInc
811 2, // mColSampling
812 2, // mRowSampling
813 8, // allocatedDepth
814 8, // bitDepth
815 0, // rightShift
816 C2PlaneInfo::NATIVE, // endianness
817 C2PlanarLayout::PLANE_U, // rootIx
818 0, // offset
819 };
820 layout->planes[C2PlanarLayout::PLANE_V] = {
821 C2PlaneInfo::CHANNEL_CR, // channel
822 (int32_t)ycbcrLayout.chroma_step, // colInc
823 (int32_t)ycbcrLayout.cstride, // rowInc
824 2, // mColSampling
825 2, // mRowSampling
826 8, // allocatedDepth
827 8, // bitDepth
828 0, // rightShift
829 C2PlaneInfo::NATIVE, // endianness
830 C2PlanarLayout::PLANE_V, // rootIx
831 0, // offset
832 };
833 // handle interleaved formats
834 intptr_t uvOffset = addr[C2PlanarLayout::PLANE_V] - addr[C2PlanarLayout::PLANE_U];
835 if (uvOffset > 0 && uvOffset < (intptr_t)ycbcrLayout.chroma_step) {
836 layout->rootPlanes = 2;
837 layout->planes[C2PlanarLayout::PLANE_V].rootIx = C2PlanarLayout::PLANE_U;
838 layout->planes[C2PlanarLayout::PLANE_V].offset = uvOffset;
839 } else if (uvOffset < 0 && uvOffset > -(intptr_t)ycbcrLayout.chroma_step) {
840 layout->rootPlanes = 2;
841 layout->planes[C2PlanarLayout::PLANE_U].rootIx = C2PlanarLayout::PLANE_V;
842 layout->planes[C2PlanarLayout::PLANE_U].offset = -uvOffset;
843 }
844 break;
845 }
846
847 // We really don't know what this is; lock the buffer and pass it through ---
848 // the client may know how to interpret it.
Lajos Molnar8faebbc2021-06-30 17:07:42 -0700849
850 // unlock previous allocation if it was successful
851 if (err == OK) {
852 err = GraphicBufferMapper::get().unlock(mBuffer);
853 if (err) {
854 ALOGE("failed transaction: unlock");
855 return C2_CORRUPTED;
856 }
857 }
858
Wonsik Kim29e3c4d2020-09-02 12:19:44 -0700859 void *pointer = nullptr;
860 err = GraphicBufferMapper::get().lock(
861 const_cast<native_handle_t *>(mBuffer), grallocUsage, rect, &pointer);
862 if (err) {
863 ALOGE("failed transaction: lock(??? %x)", mFormat);
864 return C2_CORRUPTED;
865 }
866 addr[0] = (uint8_t *)pointer;
867 layout->type = C2PlanarLayout::TYPE_UNKNOWN;
868 layout->numPlanes = 1;
869 layout->rootPlanes = 1;
870 layout->planes[0] = {
871 // TODO: CHANNEL_UNKNOWN?
872 C2PlaneInfo::channel_t(0xFF), // channel
873 1, // colInc
874 int32_t(mStride), // rowInc
875 1, // mColSampling
876 1, // mRowSampling
877 8, // allocatedDepth
878 8, // bitDepth
879 0, // rightShift
880 C2PlaneInfo::NATIVE, // endianness
881 0, // rootIx
882 0, // offset
883 };
884 break;
885 }
Pawin Vongmasa36653902018-11-15 00:10:25 -0800886 }
887 mLocked = true;
888
889 return C2_OK;
890}
891
892c2_status_t C2AllocationGralloc::unmap(
893 uint8_t **addr, C2Rect rect, C2Fence *fence /* nullable */) {
894 // TODO: check addr and size, use fence
895 (void)addr;
896 (void)rect;
Marissa Wall2a24a302019-11-25 11:19:18 -0800897 (void)fence;
Pawin Vongmasa36653902018-11-15 00:10:25 -0800898
899 std::lock_guard<std::mutex> lock(mMappedLock);
Marissa Wall2a24a302019-11-25 11:19:18 -0800900 // TODO: fence
901 status_t err = GraphicBufferMapper::get().unlock(mBuffer);
902 if (err) {
903 ALOGE("failed transaction: unlock");
904 return C2_CORRUPTED;
Pawin Vongmasad032f2d2019-05-15 08:42:44 -0700905 }
Marissa Wall2a24a302019-11-25 11:19:18 -0800906
907 mLocked = false;
908 return C2_OK;
Pawin Vongmasa36653902018-11-15 00:10:25 -0800909}
910
911bool C2AllocationGralloc::equals(const std::shared_ptr<const C2GraphicAllocation> &other) const {
912 return other && other->handle() == handle();
913}
914
915/* ===================================== GRALLOC ALLOCATOR ==================================== */
916class C2AllocatorGralloc::Impl {
917public:
918 Impl(id_t id, bool bufferQueue);
919
920 id_t getId() const {
921 return mTraits->id;
922 }
923
924 C2String getName() const {
925 return mTraits->name;
926 }
927
928 std::shared_ptr<const C2Allocator::Traits> getTraits() const {
929 return mTraits;
930 }
931
932 c2_status_t newGraphicAllocation(
933 uint32_t width, uint32_t height, uint32_t format, const C2MemoryUsage &usage,
934 std::shared_ptr<C2GraphicAllocation> *allocation);
935
936 c2_status_t priorGraphicAllocation(
937 const C2Handle *handle,
938 std::shared_ptr<C2GraphicAllocation> *allocation);
939
940 c2_status_t status() const { return mInit; }
941
942private:
943 std::shared_ptr<C2Allocator::Traits> mTraits;
944 c2_status_t mInit;
Pawin Vongmasa36653902018-11-15 00:10:25 -0800945 const bool mBufferQueue;
946};
947
948void _UnwrapNativeCodec2GrallocMetadata(
949 const C2Handle *const handle,
950 uint32_t *width, uint32_t *height, uint32_t *format,uint64_t *usage, uint32_t *stride,
951 uint32_t *generation, uint64_t *igbp_id, uint32_t *igbp_slot) {
952 (void)C2HandleGralloc::Import(handle, width, height, format, usage, stride,
953 generation, igbp_id, igbp_slot);
954}
955
956C2AllocatorGralloc::Impl::Impl(id_t id, bool bufferQueue)
957 : mInit(C2_OK), mBufferQueue(bufferQueue) {
958 // TODO: get this from allocator
959 C2MemoryUsage minUsage = { 0, 0 }, maxUsage = { ~(uint64_t)0, ~(uint64_t)0 };
960 Traits traits = { "android.allocator.gralloc", id, C2Allocator::GRAPHIC, minUsage, maxUsage };
961 mTraits = std::make_shared<C2Allocator::Traits>(traits);
Pawin Vongmasa36653902018-11-15 00:10:25 -0800962}
963
964c2_status_t C2AllocatorGralloc::Impl::newGraphicAllocation(
965 uint32_t width, uint32_t height, uint32_t format, const C2MemoryUsage &usage,
966 std::shared_ptr<C2GraphicAllocation> *allocation) {
967 uint64_t grallocUsage = static_cast<C2AndroidMemoryUsage>(usage).asGrallocUsage();
968 ALOGV("allocating buffer with usage %#llx => %#llx",
969 (long long)usage.expected, (long long)grallocUsage);
970
Marissa Wall2a24a302019-11-25 11:19:18 -0800971 buffer_handle_t buffer;
Pawin Vongmasad032f2d2019-05-15 08:42:44 -0700972
Marissa Wall2a24a302019-11-25 11:19:18 -0800973 uint32_t stride = 0;
Pawin Vongmasad032f2d2019-05-15 08:42:44 -0700974
Marissa Wall2a24a302019-11-25 11:19:18 -0800975 status_t err = GraphicBufferAllocator::get().allocateRawHandle(width, height, format,
976 1u /* layer count */, grallocUsage, &buffer, &stride, "C2GrallocAllocation");
977 if (err) {
978 ALOGE("failed transaction: allocate");
979 return C2_CORRUPTED;
Pawin Vongmasa36653902018-11-15 00:10:25 -0800980 }
Marissa Wall2a24a302019-11-25 11:19:18 -0800981
982 hidl_handle hidlHandle;
983 hidlHandle.setTo(const_cast<native_handle_t*>(buffer), true);
984
985 allocation->reset(new C2AllocationGralloc(
986 width, height, format, 1u /* layer count */, grallocUsage, stride, hidlHandle,
987 C2HandleGralloc::WrapAndMoveNativeHandle(
988 hidlHandle, width, height,
989 format, grallocUsage, stride,
990 0, 0, mBufferQueue ? ~0 : 0),
991 mTraits->id));
992 return C2_OK;
Pawin Vongmasa36653902018-11-15 00:10:25 -0800993}
994
995c2_status_t C2AllocatorGralloc::Impl::priorGraphicAllocation(
996 const C2Handle *handle,
997 std::shared_ptr<C2GraphicAllocation> *allocation) {
Pawin Vongmasad032f2d2019-05-15 08:42:44 -0700998
Marissa Wall2a24a302019-11-25 11:19:18 -0800999 uint32_t generation;
1000 uint64_t igbp_id;
1001 uint32_t igbp_slot;
Pawin Vongmasad032f2d2019-05-15 08:42:44 -07001002
Marissa Wall2a24a302019-11-25 11:19:18 -08001003 uint32_t width;
1004 uint32_t height;
1005 uint32_t format;
1006 uint32_t layerCount = 1;
1007 uint64_t grallocUsage;
1008 uint32_t stride;
Pawin Vongmasad032f2d2019-05-15 08:42:44 -07001009
Marissa Wall2a24a302019-11-25 11:19:18 -08001010 const C2HandleGralloc *grallocHandle = C2HandleGralloc::Import(
1011 handle, &width, &height, &format, &grallocUsage, &stride,
1012 &generation, &igbp_id, &igbp_slot);
1013 if (grallocHandle == nullptr) {
1014 return C2_BAD_VALUE;
Pawin Vongmasa36653902018-11-15 00:10:25 -08001015 }
Marissa Wall2a24a302019-11-25 11:19:18 -08001016
1017 hidl_handle hidlHandle;
1018 hidlHandle.setTo(C2HandleGralloc::UnwrapNativeHandle(grallocHandle), true);
1019
1020 allocation->reset(new C2AllocationGralloc(
1021 width, height, format, layerCount,
1022 grallocUsage, stride, hidlHandle, grallocHandle, mTraits->id));
1023 return C2_OK;
Pawin Vongmasa36653902018-11-15 00:10:25 -08001024}
1025
1026C2AllocatorGralloc::C2AllocatorGralloc(id_t id, bool bufferQueue)
1027 : mImpl(new Impl(id, bufferQueue)) {}
1028
1029C2AllocatorGralloc::~C2AllocatorGralloc() { delete mImpl; }
1030
1031C2Allocator::id_t C2AllocatorGralloc::getId() const {
1032 return mImpl->getId();
1033}
1034
1035C2String C2AllocatorGralloc::getName() const {
1036 return mImpl->getName();
1037}
1038
1039std::shared_ptr<const C2Allocator::Traits> C2AllocatorGralloc::getTraits() const {
1040 return mImpl->getTraits();
1041}
1042
1043c2_status_t C2AllocatorGralloc::newGraphicAllocation(
1044 uint32_t width, uint32_t height, uint32_t format, C2MemoryUsage usage,
1045 std::shared_ptr<C2GraphicAllocation> *allocation) {
1046 return mImpl->newGraphicAllocation(width, height, format, usage, allocation);
1047}
1048
1049c2_status_t C2AllocatorGralloc::priorGraphicAllocation(
1050 const C2Handle *handle,
1051 std::shared_ptr<C2GraphicAllocation> *allocation) {
1052 return mImpl->priorGraphicAllocation(handle, allocation);
1053}
1054
1055c2_status_t C2AllocatorGralloc::status() const {
1056 return mImpl->status();
1057}
1058
John Stultz653ddd12020-09-19 05:26:24 +00001059// static
1060bool C2AllocatorGralloc::CheckHandle(const C2Handle* const o) {
1061 return C2HandleGralloc::IsValid(o);
Pawin Vongmasa36653902018-11-15 00:10:25 -08001062}
1063
1064} // namespace android