blob: 80f6c82bb0d3ab866098e704444e99806e1a4b7f [file] [log] [blame]
Marissa Wall87c8ba72019-06-20 14:20:52 -07001/*
2 * Copyright 2019 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_TAG "Gralloc4"
18
19#include <hidl/ServiceManagement.h>
20#include <hwbinder/IPCThreadState.h>
21#include <ui/Gralloc4.h>
22
23#include <inttypes.h>
24#include <log/log.h>
25#pragma clang diagnostic push
26#pragma clang diagnostic ignored "-Wzero-length-array"
27#include <sync/sync.h>
28#pragma clang diagnostic pop
29
Marissa Wall22b2de12019-12-02 18:11:43 -080030using aidl::android::hardware::graphics::common::ExtendableType;
31using aidl::android::hardware::graphics::common::PlaneLayoutComponentType;
32using aidl::android::hardware::graphics::common::StandardMetadataType;
33using android::hardware::hidl_vec;
Marissa Wall87c8ba72019-06-20 14:20:52 -070034using android::hardware::graphics::allocator::V4_0::IAllocator;
35using android::hardware::graphics::common::V1_2::BufferUsage;
36using android::hardware::graphics::mapper::V4_0::BufferDescriptor;
37using android::hardware::graphics::mapper::V4_0::Error;
38using android::hardware::graphics::mapper::V4_0::IMapper;
Yichi Chenba40db52021-04-30 00:18:32 +080039using AidlDataspace = ::aidl::android::hardware::graphics::common::Dataspace;
Marissa Wall22b2de12019-12-02 18:11:43 -080040using BufferDump = android::hardware::graphics::mapper::V4_0::IMapper::BufferDump;
41using MetadataDump = android::hardware::graphics::mapper::V4_0::IMapper::MetadataDump;
42using MetadataType = android::hardware::graphics::mapper::V4_0::IMapper::MetadataType;
43using MetadataTypeDescription =
44 android::hardware::graphics::mapper::V4_0::IMapper::MetadataTypeDescription;
Marissa Wall87c8ba72019-06-20 14:20:52 -070045
46namespace android {
47
48namespace {
49
50static constexpr Error kTransactionError = Error::NO_RESOURCES;
51
52uint64_t getValidUsageBits() {
53 static const uint64_t validUsageBits = []() -> uint64_t {
54 uint64_t bits = 0;
55 for (const auto bit :
56 hardware::hidl_enum_range<hardware::graphics::common::V1_2::BufferUsage>()) {
57 bits = bits | bit;
58 }
59 return bits;
60 }();
61 return validUsageBits;
62}
63
64static inline IMapper::Rect sGralloc4Rect(const Rect& rect) {
65 IMapper::Rect outRect{};
66 outRect.left = rect.left;
67 outRect.top = rect.top;
68 outRect.width = rect.width();
69 outRect.height = rect.height();
70 return outRect;
71}
Marissa Wall22b2de12019-12-02 18:11:43 -080072static inline void sBufferDescriptorInfo(std::string name, uint32_t width, uint32_t height,
73 PixelFormat format, uint32_t layerCount, uint64_t usage,
Marissa Wall87c8ba72019-06-20 14:20:52 -070074 IMapper::BufferDescriptorInfo* outDescriptorInfo) {
Marissa Wall22b2de12019-12-02 18:11:43 -080075 outDescriptorInfo->name = name;
Marissa Wall87c8ba72019-06-20 14:20:52 -070076 outDescriptorInfo->width = width;
77 outDescriptorInfo->height = height;
78 outDescriptorInfo->layerCount = layerCount;
79 outDescriptorInfo->format = static_cast<hardware::graphics::common::V1_2::PixelFormat>(format);
80 outDescriptorInfo->usage = usage;
Valerie Hau23392792020-03-09 14:01:06 -070081 outDescriptorInfo->reservedSize = 0;
Marissa Wall87c8ba72019-06-20 14:20:52 -070082}
83
84} // anonymous namespace
85
86void Gralloc4Mapper::preload() {
87 android::hardware::preloadPassthroughService<IMapper>();
88}
89
90Gralloc4Mapper::Gralloc4Mapper() {
91 mMapper = IMapper::getService();
92 if (mMapper == nullptr) {
93 ALOGI("mapper 4.x is not supported");
94 return;
95 }
96 if (mMapper->isRemote()) {
97 LOG_ALWAYS_FATAL("gralloc-mapper must be in passthrough mode");
98 }
99}
100
101bool Gralloc4Mapper::isLoaded() const {
102 return mMapper != nullptr;
103}
104
105status_t Gralloc4Mapper::validateBufferDescriptorInfo(
106 IMapper::BufferDescriptorInfo* descriptorInfo) const {
107 uint64_t validUsageBits = getValidUsageBits();
108
109 if (descriptorInfo->usage & ~validUsageBits) {
110 ALOGE("buffer descriptor contains invalid usage bits 0x%" PRIx64,
111 descriptorInfo->usage & ~validUsageBits);
112 return BAD_VALUE;
113 }
114 return NO_ERROR;
115}
116
117status_t Gralloc4Mapper::createDescriptor(void* bufferDescriptorInfo,
118 void* outBufferDescriptor) const {
119 IMapper::BufferDescriptorInfo* descriptorInfo =
120 static_cast<IMapper::BufferDescriptorInfo*>(bufferDescriptorInfo);
121 BufferDescriptor* outDescriptor = static_cast<BufferDescriptor*>(outBufferDescriptor);
122
123 status_t status = validateBufferDescriptorInfo(descriptorInfo);
124 if (status != NO_ERROR) {
125 return status;
126 }
127
128 Error error;
129 auto hidl_cb = [&](const auto& tmpError, const auto& tmpDescriptor) {
130 error = tmpError;
131 if (error != Error::NONE) {
132 return;
133 }
134 *outDescriptor = tmpDescriptor;
135 };
136
137 hardware::Return<void> ret = mMapper->createDescriptor(*descriptorInfo, hidl_cb);
138
139 return static_cast<status_t>((ret.isOk()) ? error : kTransactionError);
140}
141
142status_t Gralloc4Mapper::importBuffer(const hardware::hidl_handle& rawHandle,
143 buffer_handle_t* outBufferHandle) const {
144 Error error;
145 auto ret = mMapper->importBuffer(rawHandle, [&](const auto& tmpError, const auto& tmpBuffer) {
146 error = tmpError;
147 if (error != Error::NONE) {
148 return;
149 }
150 *outBufferHandle = static_cast<buffer_handle_t>(tmpBuffer);
151 });
152
153 return static_cast<status_t>((ret.isOk()) ? error : kTransactionError);
154}
155
156void Gralloc4Mapper::freeBuffer(buffer_handle_t bufferHandle) const {
157 auto buffer = const_cast<native_handle_t*>(bufferHandle);
158 auto ret = mMapper->freeBuffer(buffer);
159
160 auto error = (ret.isOk()) ? static_cast<Error>(ret) : kTransactionError;
161 ALOGE_IF(error != Error::NONE, "freeBuffer(%p) failed with %d", buffer, error);
162}
163
164status_t Gralloc4Mapper::validateBufferSize(buffer_handle_t bufferHandle, uint32_t width,
Marissa Wall22b2de12019-12-02 18:11:43 -0800165 uint32_t height, PixelFormat format,
Marissa Wall87c8ba72019-06-20 14:20:52 -0700166 uint32_t layerCount, uint64_t usage,
167 uint32_t stride) const {
168 IMapper::BufferDescriptorInfo descriptorInfo;
Marissa Wall22b2de12019-12-02 18:11:43 -0800169 sBufferDescriptorInfo("validateBufferSize", width, height, format, layerCount, usage,
170 &descriptorInfo);
Marissa Wall87c8ba72019-06-20 14:20:52 -0700171
172 auto buffer = const_cast<native_handle_t*>(bufferHandle);
173 auto ret = mMapper->validateBufferSize(buffer, descriptorInfo, stride);
174
175 return static_cast<status_t>((ret.isOk()) ? static_cast<Error>(ret) : kTransactionError);
176}
177
178void Gralloc4Mapper::getTransportSize(buffer_handle_t bufferHandle, uint32_t* outNumFds,
179 uint32_t* outNumInts) const {
180 *outNumFds = uint32_t(bufferHandle->numFds);
181 *outNumInts = uint32_t(bufferHandle->numInts);
182
183 Error error;
184 auto buffer = const_cast<native_handle_t*>(bufferHandle);
185 auto ret = mMapper->getTransportSize(buffer,
186 [&](const auto& tmpError, const auto& tmpNumFds,
187 const auto& tmpNumInts) {
188 error = tmpError;
189 if (error != Error::NONE) {
190 return;
191 }
192 *outNumFds = tmpNumFds;
193 *outNumInts = tmpNumInts;
194 });
195
196 error = (ret.isOk()) ? error : kTransactionError;
197
198 ALOGE_IF(error != Error::NONE, "getTransportSize(%p) failed with %d", buffer, error);
199}
200
201status_t Gralloc4Mapper::lock(buffer_handle_t bufferHandle, uint64_t usage, const Rect& bounds,
202 int acquireFence, void** outData, int32_t* outBytesPerPixel,
203 int32_t* outBytesPerStride) const {
Marissa Wall22b2de12019-12-02 18:11:43 -0800204 std::vector<ui::PlaneLayout> planeLayouts;
205 status_t err = getPlaneLayouts(bufferHandle, &planeLayouts);
206
Valerie Hau3bb97912020-04-09 10:40:10 -0700207 if (err == NO_ERROR && !planeLayouts.empty()) {
Marissa Wall22b2de12019-12-02 18:11:43 -0800208 if (outBytesPerPixel) {
209 int32_t bitsPerPixel = planeLayouts.front().sampleIncrementInBits;
210 for (const auto& planeLayout : planeLayouts) {
211 if (bitsPerPixel != planeLayout.sampleIncrementInBits) {
212 bitsPerPixel = -1;
213 }
214 }
215 if (bitsPerPixel >= 0 && bitsPerPixel % 8 == 0) {
216 *outBytesPerPixel = bitsPerPixel / 8;
217 } else {
218 *outBytesPerPixel = -1;
219 }
220 }
221 if (outBytesPerStride) {
222 int32_t bytesPerStride = planeLayouts.front().strideInBytes;
223 for (const auto& planeLayout : planeLayouts) {
224 if (bytesPerStride != planeLayout.strideInBytes) {
225 bytesPerStride = -1;
226 }
227 }
228 if (bytesPerStride >= 0) {
229 *outBytesPerStride = bytesPerStride;
230 } else {
231 *outBytesPerStride = -1;
232 }
233 }
Marissa Wall20611c62019-11-05 15:06:24 -0800234 }
235
Marissa Wall87c8ba72019-06-20 14:20:52 -0700236 auto buffer = const_cast<native_handle_t*>(bufferHandle);
237
238 IMapper::Rect accessRegion = sGralloc4Rect(bounds);
239
240 // put acquireFence in a hidl_handle
241 hardware::hidl_handle acquireFenceHandle;
242 NATIVE_HANDLE_DECLARE_STORAGE(acquireFenceStorage, 1, 0);
243 if (acquireFence >= 0) {
244 auto h = native_handle_init(acquireFenceStorage, 1, 0);
245 h->data[0] = acquireFence;
246 acquireFenceHandle = h;
247 }
248
249 Error error;
250 auto ret = mMapper->lock(buffer, usage, accessRegion, acquireFenceHandle,
Marissa Wall20611c62019-11-05 15:06:24 -0800251 [&](const auto& tmpError, const auto& tmpData) {
Marissa Wall87c8ba72019-06-20 14:20:52 -0700252 error = tmpError;
253 if (error != Error::NONE) {
254 return;
255 }
256 *outData = tmpData;
Marissa Wall87c8ba72019-06-20 14:20:52 -0700257 });
258
259 // we own acquireFence even on errors
260 if (acquireFence >= 0) {
261 close(acquireFence);
262 }
263
264 error = (ret.isOk()) ? error : kTransactionError;
265
266 ALOGW_IF(error != Error::NONE, "lock(%p, ...) failed: %d", bufferHandle, error);
267
268 return static_cast<status_t>(error);
269}
270
Marissa Wall22b2de12019-12-02 18:11:43 -0800271status_t Gralloc4Mapper::lock(buffer_handle_t bufferHandle, uint64_t usage, const Rect& bounds,
272 int acquireFence, android_ycbcr* outYcbcr) const {
273 if (!outYcbcr) {
274 return BAD_VALUE;
275 }
276
277 std::vector<ui::PlaneLayout> planeLayouts;
278 status_t error = getPlaneLayouts(bufferHandle, &planeLayouts);
279 if (error != NO_ERROR) {
280 return error;
281 }
282
283 void* data = nullptr;
284 error = lock(bufferHandle, usage, bounds, acquireFence, &data, nullptr, nullptr);
285 if (error != NO_ERROR) {
286 return error;
287 }
288
289 android_ycbcr ycbcr;
290
291 ycbcr.y = nullptr;
292 ycbcr.cb = nullptr;
293 ycbcr.cr = nullptr;
294 ycbcr.ystride = 0;
295 ycbcr.cstride = 0;
296 ycbcr.chroma_step = 0;
297
298 for (const auto& planeLayout : planeLayouts) {
299 for (const auto& planeLayoutComponent : planeLayout.components) {
300 if (!gralloc4::isStandardPlaneLayoutComponentType(planeLayoutComponent.type)) {
301 continue;
302 }
303 if (0 != planeLayoutComponent.offsetInBits % 8) {
304 unlock(bufferHandle);
305 return BAD_VALUE;
306 }
307
308 uint8_t* tmpData = static_cast<uint8_t*>(data) + planeLayout.offsetInBytes +
309 (planeLayoutComponent.offsetInBits / 8);
310 uint64_t sampleIncrementInBytes;
311
312 auto type = static_cast<PlaneLayoutComponentType>(planeLayoutComponent.type.value);
313 switch (type) {
314 case PlaneLayoutComponentType::Y:
315 if ((ycbcr.y != nullptr) || (planeLayoutComponent.sizeInBits != 8) ||
316 (planeLayout.sampleIncrementInBits != 8)) {
317 unlock(bufferHandle);
318 return BAD_VALUE;
319 }
320 ycbcr.y = tmpData;
321 ycbcr.ystride = planeLayout.strideInBytes;
322 break;
323
324 case PlaneLayoutComponentType::CB:
325 case PlaneLayoutComponentType::CR:
326 if (planeLayout.sampleIncrementInBits % 8 != 0) {
327 unlock(bufferHandle);
328 return BAD_VALUE;
329 }
330
331 sampleIncrementInBytes = planeLayout.sampleIncrementInBits / 8;
332 if ((sampleIncrementInBytes != 1) && (sampleIncrementInBytes != 2)) {
333 unlock(bufferHandle);
334 return BAD_VALUE;
335 }
336
337 if (ycbcr.cstride == 0 && ycbcr.chroma_step == 0) {
338 ycbcr.cstride = planeLayout.strideInBytes;
339 ycbcr.chroma_step = sampleIncrementInBytes;
340 } else {
341 if ((static_cast<int64_t>(ycbcr.cstride) != planeLayout.strideInBytes) ||
342 (ycbcr.chroma_step != sampleIncrementInBytes)) {
343 unlock(bufferHandle);
344 return BAD_VALUE;
345 }
346 }
347
348 if (type == PlaneLayoutComponentType::CB) {
349 if (ycbcr.cb != nullptr) {
350 unlock(bufferHandle);
351 return BAD_VALUE;
352 }
353 ycbcr.cb = tmpData;
354 } else {
355 if (ycbcr.cr != nullptr) {
356 unlock(bufferHandle);
357 return BAD_VALUE;
358 }
359 ycbcr.cr = tmpData;
360 }
361 break;
362 default:
363 break;
364 };
365 }
366 }
367
368 *outYcbcr = ycbcr;
Marissa Wall90df5852020-02-27 10:17:02 -0800369 return static_cast<status_t>(Error::NONE);
Marissa Wall87c8ba72019-06-20 14:20:52 -0700370}
371
372int Gralloc4Mapper::unlock(buffer_handle_t bufferHandle) const {
373 auto buffer = const_cast<native_handle_t*>(bufferHandle);
374
375 int releaseFence = -1;
376 Error error;
377 auto ret = mMapper->unlock(buffer, [&](const auto& tmpError, const auto& tmpReleaseFence) {
378 error = tmpError;
379 if (error != Error::NONE) {
380 return;
381 }
382
383 auto fenceHandle = tmpReleaseFence.getNativeHandle();
384 if (fenceHandle && fenceHandle->numFds == 1) {
385 int fd = dup(fenceHandle->data[0]);
386 if (fd >= 0) {
387 releaseFence = fd;
388 } else {
389 ALOGD("failed to dup unlock release fence");
390 sync_wait(fenceHandle->data[0], -1);
391 }
392 }
393 });
394
395 if (!ret.isOk()) {
396 error = kTransactionError;
397 }
398
399 if (error != Error::NONE) {
400 ALOGE("unlock(%p) failed with %d", buffer, error);
401 }
402
403 return releaseFence;
404}
405
Marissa Wall22b2de12019-12-02 18:11:43 -0800406status_t Gralloc4Mapper::isSupported(uint32_t width, uint32_t height, PixelFormat format,
Marissa Wall87c8ba72019-06-20 14:20:52 -0700407 uint32_t layerCount, uint64_t usage,
408 bool* outSupported) const {
409 IMapper::BufferDescriptorInfo descriptorInfo;
Marissa Wall22b2de12019-12-02 18:11:43 -0800410 sBufferDescriptorInfo("isSupported", width, height, format, layerCount, usage, &descriptorInfo);
Marissa Wall87c8ba72019-06-20 14:20:52 -0700411
412 Error error;
413 auto ret = mMapper->isSupported(descriptorInfo,
414 [&](const auto& tmpError, const auto& tmpSupported) {
415 error = tmpError;
416 if (error != Error::NONE) {
417 return;
418 }
419 if (outSupported) {
420 *outSupported = tmpSupported;
421 }
422 });
423
424 if (!ret.isOk()) {
425 error = kTransactionError;
426 }
427
428 if (error != Error::NONE) {
429 ALOGE("isSupported(%u, %u, %d, %u, ...) failed with %d", width, height, format, layerCount,
430 error);
431 }
432
433 return static_cast<status_t>(error);
434}
435
Marissa Wall22b2de12019-12-02 18:11:43 -0800436template <class T>
437status_t Gralloc4Mapper::get(buffer_handle_t bufferHandle, const MetadataType& metadataType,
438 DecodeFunction<T> decodeFunction, T* outMetadata) const {
439 if (!outMetadata) {
440 return BAD_VALUE;
441 }
442
443 hidl_vec<uint8_t> vec;
444 Error error;
445 auto ret = mMapper->get(const_cast<native_handle_t*>(bufferHandle), metadataType,
446 [&](const auto& tmpError, const hidl_vec<uint8_t>& tmpVec) {
447 error = tmpError;
448 vec = tmpVec;
449 });
450
451 if (!ret.isOk()) {
452 error = kTransactionError;
453 }
454
455 if (error != Error::NONE) {
456 ALOGE("get(%s, %" PRIu64 ", ...) failed with %d", metadataType.name.c_str(),
457 metadataType.value, error);
458 return static_cast<status_t>(error);
459 }
460
461 return decodeFunction(vec, outMetadata);
462}
463
464status_t Gralloc4Mapper::getBufferId(buffer_handle_t bufferHandle, uint64_t* outBufferId) const {
465 return get(bufferHandle, gralloc4::MetadataType_BufferId, gralloc4::decodeBufferId,
466 outBufferId);
467}
468
469status_t Gralloc4Mapper::getName(buffer_handle_t bufferHandle, std::string* outName) const {
470 return get(bufferHandle, gralloc4::MetadataType_Name, gralloc4::decodeName, outName);
471}
472
473status_t Gralloc4Mapper::getWidth(buffer_handle_t bufferHandle, uint64_t* outWidth) const {
474 return get(bufferHandle, gralloc4::MetadataType_Width, gralloc4::decodeWidth, outWidth);
475}
476
477status_t Gralloc4Mapper::getHeight(buffer_handle_t bufferHandle, uint64_t* outHeight) const {
478 return get(bufferHandle, gralloc4::MetadataType_Height, gralloc4::decodeHeight, outHeight);
479}
480
481status_t Gralloc4Mapper::getLayerCount(buffer_handle_t bufferHandle,
482 uint64_t* outLayerCount) const {
483 return get(bufferHandle, gralloc4::MetadataType_LayerCount, gralloc4::decodeLayerCount,
484 outLayerCount);
485}
486
487status_t Gralloc4Mapper::getPixelFormatRequested(buffer_handle_t bufferHandle,
488 ui::PixelFormat* outPixelFormatRequested) const {
489 return get(bufferHandle, gralloc4::MetadataType_PixelFormatRequested,
490 gralloc4::decodePixelFormatRequested, outPixelFormatRequested);
491}
492
493status_t Gralloc4Mapper::getPixelFormatFourCC(buffer_handle_t bufferHandle,
494 uint32_t* outPixelFormatFourCC) const {
495 return get(bufferHandle, gralloc4::MetadataType_PixelFormatFourCC,
496 gralloc4::decodePixelFormatFourCC, outPixelFormatFourCC);
497}
498
499status_t Gralloc4Mapper::getPixelFormatModifier(buffer_handle_t bufferHandle,
500 uint64_t* outPixelFormatModifier) const {
501 return get(bufferHandle, gralloc4::MetadataType_PixelFormatModifier,
502 gralloc4::decodePixelFormatModifier, outPixelFormatModifier);
503}
504
505status_t Gralloc4Mapper::getUsage(buffer_handle_t bufferHandle, uint64_t* outUsage) const {
506 return get(bufferHandle, gralloc4::MetadataType_Usage, gralloc4::decodeUsage, outUsage);
507}
508
509status_t Gralloc4Mapper::getAllocationSize(buffer_handle_t bufferHandle,
510 uint64_t* outAllocationSize) const {
511 return get(bufferHandle, gralloc4::MetadataType_AllocationSize, gralloc4::decodeAllocationSize,
512 outAllocationSize);
513}
514
515status_t Gralloc4Mapper::getProtectedContent(buffer_handle_t bufferHandle,
516 uint64_t* outProtectedContent) const {
517 return get(bufferHandle, gralloc4::MetadataType_ProtectedContent,
518 gralloc4::decodeProtectedContent, outProtectedContent);
519}
520
521status_t Gralloc4Mapper::getCompression(buffer_handle_t bufferHandle,
522 ExtendableType* outCompression) const {
523 return get(bufferHandle, gralloc4::MetadataType_Compression, gralloc4::decodeCompression,
524 outCompression);
525}
526
527status_t Gralloc4Mapper::getCompression(buffer_handle_t bufferHandle,
528 ui::Compression* outCompression) const {
529 if (!outCompression) {
530 return BAD_VALUE;
531 }
532 ExtendableType compression;
533 status_t error = getCompression(bufferHandle, &compression);
534 if (error) {
535 return error;
536 }
537 if (!gralloc4::isStandardCompression(compression)) {
538 return BAD_TYPE;
539 }
540 *outCompression = gralloc4::getStandardCompressionValue(compression);
541 return NO_ERROR;
542}
543
544status_t Gralloc4Mapper::getInterlaced(buffer_handle_t bufferHandle,
545 ExtendableType* outInterlaced) const {
546 return get(bufferHandle, gralloc4::MetadataType_Interlaced, gralloc4::decodeInterlaced,
547 outInterlaced);
548}
549
550status_t Gralloc4Mapper::getInterlaced(buffer_handle_t bufferHandle,
551 ui::Interlaced* outInterlaced) const {
552 if (!outInterlaced) {
553 return BAD_VALUE;
554 }
555 ExtendableType interlaced;
556 status_t error = getInterlaced(bufferHandle, &interlaced);
557 if (error) {
558 return error;
559 }
560 if (!gralloc4::isStandardInterlaced(interlaced)) {
561 return BAD_TYPE;
562 }
563 *outInterlaced = gralloc4::getStandardInterlacedValue(interlaced);
564 return NO_ERROR;
565}
566
567status_t Gralloc4Mapper::getChromaSiting(buffer_handle_t bufferHandle,
568 ExtendableType* outChromaSiting) const {
569 return get(bufferHandle, gralloc4::MetadataType_ChromaSiting, gralloc4::decodeChromaSiting,
570 outChromaSiting);
571}
572
573status_t Gralloc4Mapper::getChromaSiting(buffer_handle_t bufferHandle,
574 ui::ChromaSiting* outChromaSiting) const {
575 if (!outChromaSiting) {
576 return BAD_VALUE;
577 }
578 ExtendableType chromaSiting;
579 status_t error = getChromaSiting(bufferHandle, &chromaSiting);
580 if (error) {
581 return error;
582 }
583 if (!gralloc4::isStandardChromaSiting(chromaSiting)) {
584 return BAD_TYPE;
585 }
586 *outChromaSiting = gralloc4::getStandardChromaSitingValue(chromaSiting);
587 return NO_ERROR;
588}
589
590status_t Gralloc4Mapper::getPlaneLayouts(buffer_handle_t bufferHandle,
591 std::vector<ui::PlaneLayout>* outPlaneLayouts) const {
592 return get(bufferHandle, gralloc4::MetadataType_PlaneLayouts, gralloc4::decodePlaneLayouts,
593 outPlaneLayouts);
594}
595
596status_t Gralloc4Mapper::getDataspace(buffer_handle_t bufferHandle,
597 ui::Dataspace* outDataspace) const {
598 if (!outDataspace) {
599 return BAD_VALUE;
600 }
Yichi Chenba40db52021-04-30 00:18:32 +0800601 AidlDataspace dataspace;
Marissa Wall22b2de12019-12-02 18:11:43 -0800602 status_t error = get(bufferHandle, gralloc4::MetadataType_Dataspace, gralloc4::decodeDataspace,
603 &dataspace);
604 if (error) {
605 return error;
606 }
607
608 // Gralloc4 uses stable AIDL dataspace but the rest of the system still uses HIDL dataspace
609 *outDataspace = static_cast<ui::Dataspace>(dataspace);
610 return NO_ERROR;
611}
612
613status_t Gralloc4Mapper::getBlendMode(buffer_handle_t bufferHandle,
614 ui::BlendMode* outBlendMode) const {
615 return get(bufferHandle, gralloc4::MetadataType_BlendMode, gralloc4::decodeBlendMode,
616 outBlendMode);
617}
618
Marissa Wallef785e12019-12-12 14:26:59 -0800619status_t Gralloc4Mapper::getSmpte2086(buffer_handle_t bufferHandle,
620 std::optional<ui::Smpte2086>* outSmpte2086) const {
621 return get(bufferHandle, gralloc4::MetadataType_Smpte2086, gralloc4::decodeSmpte2086,
622 outSmpte2086);
623}
624
625status_t Gralloc4Mapper::getCta861_3(buffer_handle_t bufferHandle,
626 std::optional<ui::Cta861_3>* outCta861_3) const {
627 return get(bufferHandle, gralloc4::MetadataType_Cta861_3, gralloc4::decodeCta861_3,
628 outCta861_3);
629}
630
631status_t Gralloc4Mapper::getSmpte2094_40(
632 buffer_handle_t bufferHandle, std::optional<std::vector<uint8_t>>* outSmpte2094_40) const {
633 return get(bufferHandle, gralloc4::MetadataType_Smpte2094_40, gralloc4::decodeSmpte2094_40,
634 outSmpte2094_40);
635}
636
Marissa Wall22b2de12019-12-02 18:11:43 -0800637template <class T>
638status_t Gralloc4Mapper::getDefault(uint32_t width, uint32_t height, PixelFormat format,
639 uint32_t layerCount, uint64_t usage,
640 const MetadataType& metadataType,
641 DecodeFunction<T> decodeFunction, T* outMetadata) const {
642 if (!outMetadata) {
643 return BAD_VALUE;
644 }
645
646 IMapper::BufferDescriptorInfo descriptorInfo;
647 sBufferDescriptorInfo("getDefault", width, height, format, layerCount, usage, &descriptorInfo);
648
649 hidl_vec<uint8_t> vec;
650 Error error;
651 auto ret = mMapper->getFromBufferDescriptorInfo(descriptorInfo, metadataType,
652 [&](const auto& tmpError,
653 const hidl_vec<uint8_t>& tmpVec) {
654 error = tmpError;
655 vec = tmpVec;
656 });
657
658 if (!ret.isOk()) {
659 error = kTransactionError;
660 }
661
662 if (error != Error::NONE) {
663 ALOGE("getDefault(%s, %" PRIu64 ", ...) failed with %d", metadataType.name.c_str(),
664 metadataType.value, error);
665 return static_cast<status_t>(error);
666 }
667
668 return decodeFunction(vec, outMetadata);
669}
670
671status_t Gralloc4Mapper::getDefaultPixelFormatFourCC(uint32_t width, uint32_t height,
672 PixelFormat format, uint32_t layerCount,
673 uint64_t usage,
674 uint32_t* outPixelFormatFourCC) const {
675 return getDefault(width, height, format, layerCount, usage,
676 gralloc4::MetadataType_PixelFormatFourCC, gralloc4::decodePixelFormatFourCC,
677 outPixelFormatFourCC);
678}
679
680status_t Gralloc4Mapper::getDefaultPixelFormatModifier(uint32_t width, uint32_t height,
681 PixelFormat format, uint32_t layerCount,
682 uint64_t usage,
683 uint64_t* outPixelFormatModifier) const {
684 return getDefault(width, height, format, layerCount, usage,
685 gralloc4::MetadataType_PixelFormatModifier,
686 gralloc4::decodePixelFormatModifier, outPixelFormatModifier);
687}
688
689status_t Gralloc4Mapper::getDefaultAllocationSize(uint32_t width, uint32_t height,
690 PixelFormat format, uint32_t layerCount,
691 uint64_t usage,
692 uint64_t* outAllocationSize) const {
693 return getDefault(width, height, format, layerCount, usage,
694 gralloc4::MetadataType_AllocationSize, gralloc4::decodeAllocationSize,
695 outAllocationSize);
696}
697
698status_t Gralloc4Mapper::getDefaultProtectedContent(uint32_t width, uint32_t height,
699 PixelFormat format, uint32_t layerCount,
700 uint64_t usage,
701 uint64_t* outProtectedContent) const {
702 return getDefault(width, height, format, layerCount, usage,
703 gralloc4::MetadataType_ProtectedContent, gralloc4::decodeProtectedContent,
704 outProtectedContent);
705}
706
707status_t Gralloc4Mapper::getDefaultCompression(uint32_t width, uint32_t height, PixelFormat format,
708 uint32_t layerCount, uint64_t usage,
709 ExtendableType* outCompression) const {
710 return getDefault(width, height, format, layerCount, usage, gralloc4::MetadataType_Compression,
711 gralloc4::decodeCompression, outCompression);
712}
713
714status_t Gralloc4Mapper::getDefaultCompression(uint32_t width, uint32_t height, PixelFormat format,
715 uint32_t layerCount, uint64_t usage,
716 ui::Compression* outCompression) const {
717 if (!outCompression) {
718 return BAD_VALUE;
719 }
720 ExtendableType compression;
721 status_t error = getDefaultCompression(width, height, format, layerCount, usage, &compression);
722 if (error) {
723 return error;
724 }
725 if (!gralloc4::isStandardCompression(compression)) {
726 return BAD_TYPE;
727 }
728 *outCompression = gralloc4::getStandardCompressionValue(compression);
729 return NO_ERROR;
730}
731
732status_t Gralloc4Mapper::getDefaultInterlaced(uint32_t width, uint32_t height, PixelFormat format,
733 uint32_t layerCount, uint64_t usage,
734 ExtendableType* outInterlaced) const {
735 return getDefault(width, height, format, layerCount, usage, gralloc4::MetadataType_Interlaced,
736 gralloc4::decodeInterlaced, outInterlaced);
737}
738
739status_t Gralloc4Mapper::getDefaultInterlaced(uint32_t width, uint32_t height, PixelFormat format,
740 uint32_t layerCount, uint64_t usage,
741 ui::Interlaced* outInterlaced) const {
742 if (!outInterlaced) {
743 return BAD_VALUE;
744 }
745 ExtendableType interlaced;
746 status_t error = getDefaultInterlaced(width, height, format, layerCount, usage, &interlaced);
747 if (error) {
748 return error;
749 }
750 if (!gralloc4::isStandardInterlaced(interlaced)) {
751 return BAD_TYPE;
752 }
753 *outInterlaced = gralloc4::getStandardInterlacedValue(interlaced);
754 return NO_ERROR;
755}
756
757status_t Gralloc4Mapper::getDefaultChromaSiting(uint32_t width, uint32_t height, PixelFormat format,
758 uint32_t layerCount, uint64_t usage,
759 ExtendableType* outChromaSiting) const {
760 return getDefault(width, height, format, layerCount, usage, gralloc4::MetadataType_ChromaSiting,
761 gralloc4::decodeChromaSiting, outChromaSiting);
762}
763
764status_t Gralloc4Mapper::getDefaultChromaSiting(uint32_t width, uint32_t height, PixelFormat format,
765 uint32_t layerCount, uint64_t usage,
766 ui::ChromaSiting* outChromaSiting) const {
767 if (!outChromaSiting) {
768 return BAD_VALUE;
769 }
770 ExtendableType chromaSiting;
771 status_t error =
772 getDefaultChromaSiting(width, height, format, layerCount, usage, &chromaSiting);
773 if (error) {
774 return error;
775 }
776 if (!gralloc4::isStandardChromaSiting(chromaSiting)) {
777 return BAD_TYPE;
778 }
779 *outChromaSiting = gralloc4::getStandardChromaSitingValue(chromaSiting);
780 return NO_ERROR;
781}
782
783status_t Gralloc4Mapper::getDefaultPlaneLayouts(
784 uint32_t width, uint32_t height, PixelFormat format, uint32_t layerCount, uint64_t usage,
785 std::vector<ui::PlaneLayout>* outPlaneLayouts) const {
786 return getDefault(width, height, format, layerCount, usage, gralloc4::MetadataType_PlaneLayouts,
787 gralloc4::decodePlaneLayouts, outPlaneLayouts);
788}
789
790std::vector<MetadataTypeDescription> Gralloc4Mapper::listSupportedMetadataTypes() const {
791 hidl_vec<MetadataTypeDescription> descriptions;
792 Error error;
793 auto ret = mMapper->listSupportedMetadataTypes(
794 [&](const auto& tmpError, const auto& tmpDescriptions) {
795 error = tmpError;
796 descriptions = tmpDescriptions;
797 });
798
799 if (!ret.isOk()) {
800 error = kTransactionError;
801 }
802
803 if (error != Error::NONE) {
804 ALOGE("listSupportedMetadataType() failed with %d", error);
805 return {};
806 }
807
808 return static_cast<std::vector<MetadataTypeDescription>>(descriptions);
809}
810
811template <class T>
812status_t Gralloc4Mapper::metadataDumpHelper(const BufferDump& bufferDump,
813 StandardMetadataType metadataType,
814 DecodeFunction<T> decodeFunction, T* outT) const {
815 const auto& metadataDump = bufferDump.metadataDump;
816
817 auto itr =
818 std::find_if(metadataDump.begin(), metadataDump.end(),
819 [&](const MetadataDump& tmpMetadataDump) {
820 if (!gralloc4::isStandardMetadataType(tmpMetadataDump.metadataType)) {
821 return false;
822 }
823 return metadataType ==
824 gralloc4::getStandardMetadataTypeValue(
825 tmpMetadataDump.metadataType);
826 });
827 if (itr == metadataDump.end()) {
828 return BAD_VALUE;
829 }
830
831 return decodeFunction(itr->metadata, outT);
832}
833
834status_t Gralloc4Mapper::bufferDumpHelper(const BufferDump& bufferDump, std::ostringstream* outDump,
835 uint64_t* outAllocationSize, bool less) const {
836 uint64_t bufferId;
837 std::string name;
838 uint64_t width;
839 uint64_t height;
840 uint64_t layerCount;
841 ui::PixelFormat pixelFormatRequested;
842 uint32_t pixelFormatFourCC;
843 uint64_t pixelFormatModifier;
844 uint64_t usage;
Yichi Chenba40db52021-04-30 00:18:32 +0800845 AidlDataspace dataspace;
Marissa Wall22b2de12019-12-02 18:11:43 -0800846 uint64_t allocationSize;
847 uint64_t protectedContent;
848 ExtendableType compression;
849 ExtendableType interlaced;
850 ExtendableType chromaSiting;
851 std::vector<ui::PlaneLayout> planeLayouts;
852
853 status_t error = metadataDumpHelper(bufferDump, StandardMetadataType::BUFFER_ID,
854 gralloc4::decodeBufferId, &bufferId);
855 if (error != NO_ERROR) {
856 return error;
857 }
858 error = metadataDumpHelper(bufferDump, StandardMetadataType::NAME, gralloc4::decodeName, &name);
859 if (error != NO_ERROR) {
860 return error;
861 }
862 error = metadataDumpHelper(bufferDump, StandardMetadataType::WIDTH, gralloc4::decodeWidth,
863 &width);
864 if (error != NO_ERROR) {
865 return error;
866 }
867 error = metadataDumpHelper(bufferDump, StandardMetadataType::HEIGHT, gralloc4::decodeHeight,
868 &height);
869 if (error != NO_ERROR) {
870 return error;
871 }
872 error = metadataDumpHelper(bufferDump, StandardMetadataType::LAYER_COUNT,
873 gralloc4::decodeLayerCount, &layerCount);
874 if (error != NO_ERROR) {
875 return error;
876 }
877 error = metadataDumpHelper(bufferDump, StandardMetadataType::PIXEL_FORMAT_REQUESTED,
878 gralloc4::decodePixelFormatRequested, &pixelFormatRequested);
879 if (error != NO_ERROR) {
880 return error;
881 }
882 error = metadataDumpHelper(bufferDump, StandardMetadataType::PIXEL_FORMAT_FOURCC,
883 gralloc4::decodePixelFormatFourCC, &pixelFormatFourCC);
884 if (error != NO_ERROR) {
885 return error;
886 }
887 error = metadataDumpHelper(bufferDump, StandardMetadataType::PIXEL_FORMAT_MODIFIER,
888 gralloc4::decodePixelFormatModifier, &pixelFormatModifier);
889 if (error != NO_ERROR) {
890 return error;
891 }
892 error = metadataDumpHelper(bufferDump, StandardMetadataType::USAGE, gralloc4::decodeUsage,
893 &usage);
894 if (error != NO_ERROR) {
895 return error;
896 }
Yichi Chenba40db52021-04-30 00:18:32 +0800897 error = metadataDumpHelper(bufferDump, StandardMetadataType::DATASPACE,
898 gralloc4::decodeDataspace, &dataspace);
899 if (error != NO_ERROR) {
900 return error;
901 }
Marissa Wall22b2de12019-12-02 18:11:43 -0800902 error = metadataDumpHelper(bufferDump, StandardMetadataType::ALLOCATION_SIZE,
903 gralloc4::decodeAllocationSize, &allocationSize);
904 if (error != NO_ERROR) {
905 return error;
906 }
907 error = metadataDumpHelper(bufferDump, StandardMetadataType::PROTECTED_CONTENT,
908 gralloc4::decodeProtectedContent, &protectedContent);
909 if (error != NO_ERROR) {
910 return error;
911 }
912 error = metadataDumpHelper(bufferDump, StandardMetadataType::COMPRESSION,
913 gralloc4::decodeCompression, &compression);
914 if (error != NO_ERROR) {
915 return error;
916 }
917 error = metadataDumpHelper(bufferDump, StandardMetadataType::INTERLACED,
918 gralloc4::decodeInterlaced, &interlaced);
919 if (error != NO_ERROR) {
920 return error;
921 }
922 error = metadataDumpHelper(bufferDump, StandardMetadataType::CHROMA_SITING,
923 gralloc4::decodeChromaSiting, &chromaSiting);
924 if (error != NO_ERROR) {
925 return error;
926 }
927 error = metadataDumpHelper(bufferDump, StandardMetadataType::PLANE_LAYOUTS,
928 gralloc4::decodePlaneLayouts, &planeLayouts);
929 if (error != NO_ERROR) {
930 return error;
931 }
932
933 if (outAllocationSize) {
934 *outAllocationSize = allocationSize;
935 }
936 double allocationSizeKiB = static_cast<double>(allocationSize) / 1024;
937
938 *outDump << "+ name:" << name << ", id:" << bufferId << ", size:" << allocationSizeKiB
939 << "KiB, w/h:" << width << "x" << height << ", usage: 0x" << std::hex << usage
940 << std::dec << ", req fmt:" << static_cast<int32_t>(pixelFormatRequested)
941 << ", fourcc/mod:" << pixelFormatFourCC << "/" << pixelFormatModifier
Yichi Chen6de5b582021-09-13 20:00:52 +0800942 << ", dataspace: 0x" << std::hex << static_cast<uint32_t>(dataspace) << std::dec
Marissa Wall22b2de12019-12-02 18:11:43 -0800943 << ", compressed: ";
944
945 if (less) {
946 bool isCompressed = !gralloc4::isStandardCompression(compression) ||
947 (gralloc4::getStandardCompressionValue(compression) != ui::Compression::NONE);
948 *outDump << std::boolalpha << isCompressed << "\n";
949 } else {
950 *outDump << gralloc4::getCompressionName(compression) << "\n";
951 }
952
953 bool firstPlane = true;
954 for (const auto& planeLayout : planeLayouts) {
955 if (firstPlane) {
956 firstPlane = false;
957 *outDump << "\tplanes: ";
958 } else {
959 *outDump << "\t ";
960 }
961
962 for (size_t i = 0; i < planeLayout.components.size(); i++) {
963 const auto& planeLayoutComponent = planeLayout.components[i];
964 *outDump << gralloc4::getPlaneLayoutComponentTypeName(planeLayoutComponent.type);
965 if (i < planeLayout.components.size() - 1) {
966 *outDump << "/";
967 } else {
968 *outDump << ":\t";
969 }
970 }
971 *outDump << " w/h:" << planeLayout.widthInSamples << "x" << planeLayout.heightInSamples
972 << ", stride:" << planeLayout.strideInBytes
973 << " bytes, size:" << planeLayout.totalSizeInBytes;
974 if (!less) {
975 *outDump << ", inc:" << planeLayout.sampleIncrementInBits
976 << " bits, subsampling w/h:" << planeLayout.horizontalSubsampling << "x"
977 << planeLayout.verticalSubsampling;
978 }
979 *outDump << "\n";
980 }
981
982 if (!less) {
983 *outDump << "\tlayer cnt: " << layerCount << ", protected content: " << protectedContent
984 << ", interlaced: " << gralloc4::getInterlacedName(interlaced)
985 << ", chroma siting:" << gralloc4::getChromaSitingName(chromaSiting) << "\n";
986 }
987
988 return NO_ERROR;
989}
990
991std::string Gralloc4Mapper::dumpBuffer(buffer_handle_t bufferHandle, bool less) const {
992 auto buffer = const_cast<native_handle_t*>(bufferHandle);
993
994 BufferDump bufferDump;
995 Error error;
996 auto ret = mMapper->dumpBuffer(buffer, [&](const auto& tmpError, const auto& tmpBufferDump) {
997 error = tmpError;
998 bufferDump = tmpBufferDump;
999 });
1000
1001 if (!ret.isOk()) {
1002 error = kTransactionError;
1003 }
1004
1005 if (error != Error::NONE) {
1006 ALOGE("dumpBuffer() failed with %d", error);
1007 return "";
1008 }
1009
1010 std::ostringstream stream;
1011 stream.precision(2);
1012
1013 status_t err = bufferDumpHelper(bufferDump, &stream, nullptr, less);
1014 if (err != NO_ERROR) {
1015 ALOGE("bufferDumpHelper() failed with %d", err);
1016 return "";
1017 }
1018
1019 return stream.str();
1020}
1021
1022std::string Gralloc4Mapper::dumpBuffers(bool less) const {
1023 hidl_vec<BufferDump> bufferDumps;
1024 Error error;
1025 auto ret = mMapper->dumpBuffers([&](const auto& tmpError, const auto& tmpBufferDump) {
1026 error = tmpError;
1027 bufferDumps = tmpBufferDump;
1028 });
1029
1030 if (!ret.isOk()) {
1031 error = kTransactionError;
1032 }
1033
1034 if (error != Error::NONE) {
1035 ALOGE("dumpBuffer() failed with %d", error);
1036 return "";
1037 }
1038
1039 uint64_t totalAllocationSize = 0;
1040 std::ostringstream stream;
1041 stream.precision(2);
1042
1043 stream << "Imported gralloc buffers:\n";
1044
1045 for (const auto& bufferDump : bufferDumps) {
1046 uint64_t allocationSize = 0;
1047 status_t err = bufferDumpHelper(bufferDump, &stream, &allocationSize, less);
1048 if (err != NO_ERROR) {
1049 ALOGE("bufferDumpHelper() failed with %d", err);
1050 return "";
1051 }
1052 totalAllocationSize += allocationSize;
1053 }
1054
1055 double totalAllocationSizeKiB = static_cast<double>(totalAllocationSize) / 1024;
1056 stream << "Total imported by gralloc: " << totalAllocationSizeKiB << "KiB\n";
1057 return stream.str();
1058}
1059
Marissa Wall87c8ba72019-06-20 14:20:52 -07001060Gralloc4Allocator::Gralloc4Allocator(const Gralloc4Mapper& mapper) : mMapper(mapper) {
1061 mAllocator = IAllocator::getService();
1062 if (mAllocator == nullptr) {
Yiwei Zhange6124d92020-11-16 02:52:51 +00001063 ALOGW("allocator 4.x is not supported");
Marissa Wall87c8ba72019-06-20 14:20:52 -07001064 return;
1065 }
1066}
1067
1068bool Gralloc4Allocator::isLoaded() const {
1069 return mAllocator != nullptr;
1070}
1071
Marissa Wall22b2de12019-12-02 18:11:43 -08001072std::string Gralloc4Allocator::dumpDebugInfo(bool less) const {
1073 return mMapper.dumpBuffers(less);
Marissa Wall87c8ba72019-06-20 14:20:52 -07001074}
1075
Marissa Wall22b2de12019-12-02 18:11:43 -08001076status_t Gralloc4Allocator::allocate(std::string requestorName, uint32_t width, uint32_t height,
1077 android::PixelFormat format, uint32_t layerCount,
1078 uint64_t usage, uint32_t bufferCount, uint32_t* outStride,
1079 buffer_handle_t* outBufferHandles, bool importBuffers) const {
Marissa Wall87c8ba72019-06-20 14:20:52 -07001080 IMapper::BufferDescriptorInfo descriptorInfo;
Marissa Wall22b2de12019-12-02 18:11:43 -08001081 sBufferDescriptorInfo(requestorName, width, height, format, layerCount, usage, &descriptorInfo);
Marissa Wall87c8ba72019-06-20 14:20:52 -07001082
1083 BufferDescriptor descriptor;
1084 status_t error = mMapper.createDescriptor(static_cast<void*>(&descriptorInfo),
1085 static_cast<void*>(&descriptor));
1086 if (error != NO_ERROR) {
1087 return error;
1088 }
1089
1090 auto ret = mAllocator->allocate(descriptor, bufferCount,
1091 [&](const auto& tmpError, const auto& tmpStride,
1092 const auto& tmpBuffers) {
1093 error = static_cast<status_t>(tmpError);
1094 if (tmpError != Error::NONE) {
1095 return;
1096 }
1097
Marissa Wallbfcf81f2019-11-27 10:36:29 -08001098 if (importBuffers) {
1099 for (uint32_t i = 0; i < bufferCount; i++) {
1100 error = mMapper.importBuffer(tmpBuffers[i],
1101 &outBufferHandles[i]);
1102 if (error != NO_ERROR) {
1103 for (uint32_t j = 0; j < i; j++) {
1104 mMapper.freeBuffer(outBufferHandles[j]);
1105 outBufferHandles[j] = nullptr;
1106 }
1107 return;
Marissa Wall87c8ba72019-06-20 14:20:52 -07001108 }
Marissa Wallbfcf81f2019-11-27 10:36:29 -08001109 }
1110 } else {
1111 for (uint32_t i = 0; i < bufferCount; i++) {
1112 outBufferHandles[i] = native_handle_clone(
1113 tmpBuffers[i].getNativeHandle());
1114 if (!outBufferHandles[i]) {
1115 for (uint32_t j = 0; j < i; j++) {
1116 auto buffer = const_cast<native_handle_t*>(
1117 outBufferHandles[j]);
1118 native_handle_close(buffer);
1119 native_handle_delete(buffer);
1120 outBufferHandles[j] = nullptr;
1121 }
1122 }
Marissa Wall87c8ba72019-06-20 14:20:52 -07001123 }
1124 }
1125 *outStride = tmpStride;
1126 });
1127
1128 // make sure the kernel driver sees BC_FREE_BUFFER and closes the fds now
1129 hardware::IPCThreadState::self()->flushCommands();
1130
1131 return (ret.isOk()) ? error : static_cast<status_t>(kTransactionError);
1132}
1133
1134} // namespace android