blob: 995dded1f71c81e5f287dd6ca2f32dfe4cc04493 [file] [log] [blame]
Chia-I Wu5bac7f32017-04-06 12:34:32 -07001/*
2 * Copyright 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_TAG "Gralloc2"
18
Jesse Hall5dac7812017-07-06 14:02:29 -070019#include <hidl/ServiceManagement.h>
Chia-I Wud8091b92017-05-16 14:30:34 -070020#include <hwbinder/IPCThreadState.h>
Chia-I Wu5bac7f32017-04-06 12:34:32 -070021#include <ui/Gralloc2.h>
22
Craig Donnere6ecb922017-12-27 14:59:29 -080023#include <inttypes.h>
Chia-I Wu5bac7f32017-04-06 12:34:32 -070024#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 Wall925bf7f2018-12-29 14:27:11 -080030using android::hardware::graphics::allocator::V2_0::IAllocator;
Marissa Wall1e779252018-12-29 12:01:57 -080031using android::hardware::graphics::common::V1_1::BufferUsage;
32using android::hardware::graphics::common::V1_1::PixelFormat;
33using android::hardware::graphics::mapper::V2_0::BufferDescriptor;
34using android::hardware::graphics::mapper::V2_0::Error;
35using android::hardware::graphics::mapper::V2_0::YCbCrLayout;
Marissa Wall925bf7f2018-12-29 14:27:11 -080036using android::hardware::graphics::mapper::V2_1::IMapper;
Marissa Wall1e779252018-12-29 12:01:57 -080037
Chia-I Wu5bac7f32017-04-06 12:34:32 -070038namespace android {
39
Craig Donnere6ecb922017-12-27 14:59:29 -080040namespace {
41
Chia-I Wu5bac7f32017-04-06 12:34:32 -070042static constexpr Error kTransactionError = Error::NO_RESOURCES;
43
Craig Donnere6ecb922017-12-27 14:59:29 -080044uint64_t getValid10UsageBits() {
45 static const uint64_t valid10UsageBits = []() -> uint64_t {
46 using hardware::graphics::common::V1_0::BufferUsage;
47 uint64_t bits = 0;
Steven Moreland3cde8752018-05-01 16:54:17 -070048 for (const auto bit : hardware::hidl_enum_range<BufferUsage>()) {
Craig Donnere6ecb922017-12-27 14:59:29 -080049 bits = bits | bit;
50 }
Kevin F. Haggertydc5fbd42021-10-27 23:02:31 +010051
Michael Bestas627a7332024-01-11 00:27:37 +020052 if (ADDNL_GRALLOC_10_USAGE_BITS) {
53 uint64_t addnl_bits = static_cast<uint64_t>(ADDNL_GRALLOC_10_USAGE_BITS);
54 ALOGI("Adding additional valid usage bits: 0x%" PRIx64, addnl_bits);
55 bits = bits | addnl_bits;
56 }
Kevin F. Haggertydc5fbd42021-10-27 23:02:31 +010057
Craig Donnere6ecb922017-12-27 14:59:29 -080058 return bits;
59 }();
60 return valid10UsageBits;
61}
62
63uint64_t getValid11UsageBits() {
64 static const uint64_t valid11UsageBits = []() -> uint64_t {
65 using hardware::graphics::common::V1_1::BufferUsage;
66 uint64_t bits = 0;
Steven Moreland3cde8752018-05-01 16:54:17 -070067 for (const auto bit : hardware::hidl_enum_range<BufferUsage>()) {
Craig Donnere6ecb922017-12-27 14:59:29 -080068 bits = bits | bit;
69 }
Chia-I Wu4f55f162018-01-16 21:58:18 -080070 return bits;
Craig Donnere6ecb922017-12-27 14:59:29 -080071 }();
72 return valid11UsageBits;
73}
74
Marissa Walld380e2c2018-12-29 14:17:29 -080075static inline IMapper::Rect sGralloc2Rect(const Rect& rect) {
76 IMapper::Rect outRect{};
Marissa Wall1e779252018-12-29 12:01:57 -080077 outRect.left = rect.left;
78 outRect.top = rect.top;
79 outRect.width = rect.width();
80 outRect.height = rect.height();
81 return outRect;
82}
83
Craig Donnere6ecb922017-12-27 14:59:29 -080084} // anonymous namespace
85
Marissa Walld380e2c2018-12-29 14:17:29 -080086void Gralloc2Mapper::preload() {
Jesse Hall5dac7812017-07-06 14:02:29 -070087 android::hardware::preloadPassthroughService<hardware::graphics::mapper::V2_0::IMapper>();
88}
89
Marissa Walld380e2c2018-12-29 14:17:29 -080090Gralloc2Mapper::Gralloc2Mapper() {
Chia-I Wu4f55f162018-01-16 21:58:18 -080091 mMapper = hardware::graphics::mapper::V2_0::IMapper::getService();
Chia-I Wudbbe33b2017-09-27 15:22:21 -070092 if (mMapper == nullptr) {
Marissa Wall925bf7f2018-12-29 14:27:11 -080093 ALOGW("mapper 2.x is not supported");
94 return;
Chia-I Wudbbe33b2017-09-27 15:22:21 -070095 }
96 if (mMapper->isRemote()) {
Chia-I Wu5bac7f32017-04-06 12:34:32 -070097 LOG_ALWAYS_FATAL("gralloc-mapper must be in passthrough mode");
98 }
Chia-I Wudbbe33b2017-09-27 15:22:21 -070099
100 // IMapper 2.1 is optional
Chia-I Wu4f55f162018-01-16 21:58:18 -0800101 mMapperV2_1 = IMapper::castFrom(mMapper);
Chia-I Wu5bac7f32017-04-06 12:34:32 -0700102}
103
Valerie Hau250c6542019-01-31 14:23:43 -0800104bool Gralloc2Mapper::isLoaded() const {
Marissa Wall925bf7f2018-12-29 14:27:11 -0800105 return mMapper != nullptr;
106}
107
Marissa Walld380e2c2018-12-29 14:17:29 -0800108status_t Gralloc2Mapper::validateBufferDescriptorInfo(
109 IMapper::BufferDescriptorInfo* descriptorInfo) const {
Craig Donnere6ecb922017-12-27 14:59:29 -0800110 uint64_t validUsageBits = getValid10UsageBits();
111 if (mMapperV2_1 != nullptr) {
112 validUsageBits = validUsageBits | getValid11UsageBits();
113 }
114
Marissa Wall1e779252018-12-29 12:01:57 -0800115 if (descriptorInfo->usage & ~validUsageBits) {
Craig Donnere6ecb922017-12-27 14:59:29 -0800116 ALOGE("buffer descriptor contains invalid usage bits 0x%" PRIx64,
Marissa Wall1e779252018-12-29 12:01:57 -0800117 descriptorInfo->usage & ~validUsageBits);
118 return BAD_VALUE;
Craig Donnere6ecb922017-12-27 14:59:29 -0800119 }
Chris Forbes6c09ee72022-01-26 18:48:55 +1300120
121 // Gralloc2 implementations never understand non-BLOB with GPU_DATA_BUFFER
122 // and do not reliably reject it.
123 if (descriptorInfo->usage & BufferUsage::GPU_DATA_BUFFER &&
124 descriptorInfo->format != hardware::graphics::common::V1_1::PixelFormat::BLOB) {
125 ALOGE("gralloc2 does not support non-BLOB pixel formats with GPU_DATA_BUFFER usage");
126 return BAD_VALUE;
127 }
128
Marissa Wall1e779252018-12-29 12:01:57 -0800129 return NO_ERROR;
Craig Donnere6ecb922017-12-27 14:59:29 -0800130}
131
Marissa Walld380e2c2018-12-29 14:17:29 -0800132status_t Gralloc2Mapper::createDescriptor(void* bufferDescriptorInfo,
133 void* outBufferDescriptor) const {
Marissa Wall1e779252018-12-29 12:01:57 -0800134 IMapper::BufferDescriptorInfo* descriptorInfo =
135 static_cast<IMapper::BufferDescriptorInfo*>(bufferDescriptorInfo);
136 BufferDescriptor* outDescriptor = static_cast<BufferDescriptor*>(outBufferDescriptor);
137
138 status_t status = validateBufferDescriptorInfo(descriptorInfo);
139 if (status != NO_ERROR) {
140 return status;
Craig Donnere6ecb922017-12-27 14:59:29 -0800141 }
142
Marissa Wall1e779252018-12-29 12:01:57 -0800143 Error error;
Chia-I Wu4f55f162018-01-16 21:58:18 -0800144 auto hidl_cb = [&](const auto& tmpError, const auto& tmpDescriptor)
145 {
146 error = tmpError;
147 if (error != Error::NONE) {
148 return;
149 }
Chia-I Wu5bac7f32017-04-06 12:34:32 -0700150
Chia-I Wu4f55f162018-01-16 21:58:18 -0800151 *outDescriptor = tmpDescriptor;
152 };
153
154 hardware::Return<void> ret;
155 if (mMapperV2_1 != nullptr) {
Marissa Wall1e779252018-12-29 12:01:57 -0800156 ret = mMapperV2_1->createDescriptor_2_1(*descriptorInfo, hidl_cb);
Chia-I Wu4f55f162018-01-16 21:58:18 -0800157 } else {
158 const hardware::graphics::mapper::V2_0::IMapper::BufferDescriptorInfo info = {
Marissa Wall1e779252018-12-29 12:01:57 -0800159 descriptorInfo->width,
160 descriptorInfo->height,
161 descriptorInfo->layerCount,
162 static_cast<hardware::graphics::common::V1_0::PixelFormat>(descriptorInfo->format),
163 descriptorInfo->usage,
Chia-I Wu4f55f162018-01-16 21:58:18 -0800164 };
165 ret = mMapper->createDescriptor(info, hidl_cb);
166 }
Chia-I Wu5bac7f32017-04-06 12:34:32 -0700167
Marissa Wall1e779252018-12-29 12:01:57 -0800168 return static_cast<status_t>((ret.isOk()) ? error : kTransactionError);
Chia-I Wu5bac7f32017-04-06 12:34:32 -0700169}
170
Marissa Walld380e2c2018-12-29 14:17:29 -0800171status_t Gralloc2Mapper::importBuffer(const hardware::hidl_handle& rawHandle,
172 buffer_handle_t* outBufferHandle) const {
Chia-I Wu5bac7f32017-04-06 12:34:32 -0700173 Error error;
174 auto ret = mMapper->importBuffer(rawHandle,
175 [&](const auto& tmpError, const auto& tmpBuffer)
176 {
177 error = tmpError;
178 if (error != Error::NONE) {
179 return;
180 }
181
182 *outBufferHandle = static_cast<buffer_handle_t>(tmpBuffer);
183 });
184
Marissa Wall1e779252018-12-29 12:01:57 -0800185 return static_cast<status_t>((ret.isOk()) ? error : kTransactionError);
Chia-I Wu5bac7f32017-04-06 12:34:32 -0700186}
187
Marissa Walld380e2c2018-12-29 14:17:29 -0800188void Gralloc2Mapper::freeBuffer(buffer_handle_t bufferHandle) const {
Chia-I Wu5bac7f32017-04-06 12:34:32 -0700189 auto buffer = const_cast<native_handle_t*>(bufferHandle);
190 auto ret = mMapper->freeBuffer(buffer);
191
192 auto error = (ret.isOk()) ? static_cast<Error>(ret) : kTransactionError;
193 ALOGE_IF(error != Error::NONE, "freeBuffer(%p) failed with %d",
194 buffer, error);
195}
196
Marissa Walld380e2c2018-12-29 14:17:29 -0800197status_t Gralloc2Mapper::validateBufferSize(buffer_handle_t bufferHandle, uint32_t width,
198 uint32_t height, android::PixelFormat format,
199 uint32_t layerCount, uint64_t usage,
200 uint32_t stride) const {
Chia-I Wudbbe33b2017-09-27 15:22:21 -0700201 if (mMapperV2_1 == nullptr) {
Marissa Wall1e779252018-12-29 12:01:57 -0800202 return NO_ERROR;
Chia-I Wudbbe33b2017-09-27 15:22:21 -0700203 }
204
Marissa Wall1e779252018-12-29 12:01:57 -0800205 IMapper::BufferDescriptorInfo descriptorInfo = {};
206 descriptorInfo.width = width;
207 descriptorInfo.height = height;
208 descriptorInfo.layerCount = layerCount;
209 descriptorInfo.format = static_cast<hardware::graphics::common::V1_1::PixelFormat>(format);
210 descriptorInfo.usage = usage;
211
Chia-I Wudbbe33b2017-09-27 15:22:21 -0700212 auto buffer = const_cast<native_handle_t*>(bufferHandle);
213 auto ret = mMapperV2_1->validateBufferSize(buffer, descriptorInfo, stride);
214
Marissa Wall1e779252018-12-29 12:01:57 -0800215 return static_cast<status_t>((ret.isOk()) ? static_cast<Error>(ret) : kTransactionError);
Chia-I Wudbbe33b2017-09-27 15:22:21 -0700216}
217
Marissa Walld380e2c2018-12-29 14:17:29 -0800218void Gralloc2Mapper::getTransportSize(buffer_handle_t bufferHandle, uint32_t* outNumFds,
219 uint32_t* outNumInts) const {
Chia-I Wudbbe33b2017-09-27 15:22:21 -0700220 *outNumFds = uint32_t(bufferHandle->numFds);
221 *outNumInts = uint32_t(bufferHandle->numInts);
222
223 if (mMapperV2_1 == nullptr) {
224 return;
225 }
226
227 Error error;
228 auto buffer = const_cast<native_handle_t*>(bufferHandle);
229 auto ret = mMapperV2_1->getTransportSize(buffer,
230 [&](const auto& tmpError, const auto& tmpNumFds, const auto& tmpNumInts) {
231 error = tmpError;
232 if (error != Error::NONE) {
233 return;
234 }
235
236 *outNumFds = tmpNumFds;
237 *outNumInts = tmpNumInts;
238 });
239
Marissa Wall1e779252018-12-29 12:01:57 -0800240 error = (ret.isOk()) ? error : kTransactionError;
241
242 ALOGE_IF(error != Error::NONE, "getTransportSize(%p) failed with %d", buffer, error);
Chia-I Wudbbe33b2017-09-27 15:22:21 -0700243}
244
Marissa Walld380e2c2018-12-29 14:17:29 -0800245status_t Gralloc2Mapper::lock(buffer_handle_t bufferHandle, uint64_t usage, const Rect& bounds,
Valerie Hau0c9fc362019-01-22 09:17:19 -0800246 int acquireFence, void** outData, int32_t* outBytesPerPixel,
247 int32_t* outBytesPerStride) const {
248 if (outBytesPerPixel) {
249 *outBytesPerPixel = -1;
250 }
251 if (outBytesPerStride) {
252 *outBytesPerStride = -1;
253 }
Chia-I Wu5bac7f32017-04-06 12:34:32 -0700254 auto buffer = const_cast<native_handle_t*>(bufferHandle);
255
Marissa Wall1e779252018-12-29 12:01:57 -0800256 IMapper::Rect accessRegion = sGralloc2Rect(bounds);
257
Chia-I Wu5bac7f32017-04-06 12:34:32 -0700258 // put acquireFence in a hidl_handle
259 hardware::hidl_handle acquireFenceHandle;
260 NATIVE_HANDLE_DECLARE_STORAGE(acquireFenceStorage, 1, 0);
261 if (acquireFence >= 0) {
262 auto h = native_handle_init(acquireFenceStorage, 1, 0);
263 h->data[0] = acquireFence;
264 acquireFenceHandle = h;
265 }
266
267 Error error;
268 auto ret = mMapper->lock(buffer, usage, accessRegion, acquireFenceHandle,
269 [&](const auto& tmpError, const auto& tmpData)
270 {
271 error = tmpError;
272 if (error != Error::NONE) {
273 return;
274 }
275
276 *outData = tmpData;
277 });
278
279 // we own acquireFence even on errors
280 if (acquireFence >= 0) {
281 close(acquireFence);
282 }
283
Marissa Wall1e779252018-12-29 12:01:57 -0800284 error = (ret.isOk()) ? error : kTransactionError;
285
286 ALOGW_IF(error != Error::NONE, "lock(%p, ...) failed: %d", bufferHandle, error);
287
288 return static_cast<status_t>(error);
Chia-I Wu5bac7f32017-04-06 12:34:32 -0700289}
290
Marissa Walld380e2c2018-12-29 14:17:29 -0800291status_t Gralloc2Mapper::lock(buffer_handle_t bufferHandle, uint64_t usage, const Rect& bounds,
292 int acquireFence, android_ycbcr* ycbcr) const {
Chia-I Wu5bac7f32017-04-06 12:34:32 -0700293 auto buffer = const_cast<native_handle_t*>(bufferHandle);
294
Marissa Wall1e779252018-12-29 12:01:57 -0800295 IMapper::Rect accessRegion = sGralloc2Rect(bounds);
296
Chia-I Wu5bac7f32017-04-06 12:34:32 -0700297 // put acquireFence in a hidl_handle
298 hardware::hidl_handle acquireFenceHandle;
299 NATIVE_HANDLE_DECLARE_STORAGE(acquireFenceStorage, 1, 0);
300 if (acquireFence >= 0) {
301 auto h = native_handle_init(acquireFenceStorage, 1, 0);
302 h->data[0] = acquireFence;
303 acquireFenceHandle = h;
304 }
305
Marissa Wall1e779252018-12-29 12:01:57 -0800306 YCbCrLayout layout;
Chia-I Wu5bac7f32017-04-06 12:34:32 -0700307 Error error;
308 auto ret = mMapper->lockYCbCr(buffer, usage, accessRegion,
309 acquireFenceHandle,
310 [&](const auto& tmpError, const auto& tmpLayout)
311 {
312 error = tmpError;
313 if (error != Error::NONE) {
314 return;
315 }
316
Marissa Wall1e779252018-12-29 12:01:57 -0800317 layout = tmpLayout;
Chia-I Wu5bac7f32017-04-06 12:34:32 -0700318 });
319
Marissa Wall1e779252018-12-29 12:01:57 -0800320 if (error == Error::NONE) {
321 ycbcr->y = layout.y;
322 ycbcr->cb = layout.cb;
323 ycbcr->cr = layout.cr;
324 ycbcr->ystride = static_cast<size_t>(layout.yStride);
325 ycbcr->cstride = static_cast<size_t>(layout.cStride);
326 ycbcr->chroma_step = static_cast<size_t>(layout.chromaStep);
327 }
328
Chia-I Wu5bac7f32017-04-06 12:34:32 -0700329 // we own acquireFence even on errors
330 if (acquireFence >= 0) {
331 close(acquireFence);
332 }
333
Marissa Wall1e779252018-12-29 12:01:57 -0800334 return static_cast<status_t>((ret.isOk()) ? error : kTransactionError);
Chia-I Wu5bac7f32017-04-06 12:34:32 -0700335}
336
Marissa Walld380e2c2018-12-29 14:17:29 -0800337int Gralloc2Mapper::unlock(buffer_handle_t bufferHandle) const {
Chia-I Wu5bac7f32017-04-06 12:34:32 -0700338 auto buffer = const_cast<native_handle_t*>(bufferHandle);
339
340 int releaseFence = -1;
341 Error error;
342 auto ret = mMapper->unlock(buffer,
343 [&](const auto& tmpError, const auto& tmpReleaseFence)
344 {
345 error = tmpError;
346 if (error != Error::NONE) {
347 return;
348 }
349
350 auto fenceHandle = tmpReleaseFence.getNativeHandle();
351 if (fenceHandle && fenceHandle->numFds == 1) {
352 int fd = dup(fenceHandle->data[0]);
353 if (fd >= 0) {
354 releaseFence = fd;
355 } else {
356 ALOGD("failed to dup unlock release fence");
357 sync_wait(fenceHandle->data[0], -1);
358 }
359 }
360 });
361
Marissa Wall1e779252018-12-29 12:01:57 -0800362 error = (ret.isOk()) ? error : kTransactionError;
Chia-I Wu5bac7f32017-04-06 12:34:32 -0700363 if (error != Error::NONE) {
364 ALOGE("unlock(%p) failed with %d", buffer, error);
365 }
366
367 return releaseFence;
368}
369
Marissa Walld380e2c2018-12-29 14:17:29 -0800370Gralloc2Allocator::Gralloc2Allocator(const Gralloc2Mapper& mapper) : mMapper(mapper) {
Chia-I Wucb8405e2017-04-17 15:20:19 -0700371 mAllocator = IAllocator::getService();
372 if (mAllocator == nullptr) {
Marissa Wall925bf7f2018-12-29 14:27:11 -0800373 ALOGW("allocator 2.x is not supported");
374 return;
Chia-I Wu5bac7f32017-04-06 12:34:32 -0700375 }
376}
377
Valerie Hau250c6542019-01-31 14:23:43 -0800378bool Gralloc2Allocator::isLoaded() const {
Marissa Wall925bf7f2018-12-29 14:27:11 -0800379 return mAllocator != nullptr;
380}
381
Marissa Wall22b2de12019-12-02 18:11:43 -0800382std::string Gralloc2Allocator::dumpDebugInfo(bool /*less*/) const {
Chia-I Wu5bac7f32017-04-06 12:34:32 -0700383 std::string debugInfo;
384
385 mAllocator->dumpDebugInfo([&](const auto& tmpDebugInfo) {
386 debugInfo = tmpDebugInfo.c_str();
387 });
388
389 return debugInfo;
390}
391
Marissa Wall22b2de12019-12-02 18:11:43 -0800392status_t Gralloc2Allocator::allocate(std::string /*requestorName*/, uint32_t width, uint32_t height,
393 PixelFormat format, uint32_t layerCount, uint64_t usage,
394 uint32_t bufferCount, uint32_t* outStride,
395 buffer_handle_t* outBufferHandles, bool importBuffers) const {
Marissa Wall1e779252018-12-29 12:01:57 -0800396 IMapper::BufferDescriptorInfo descriptorInfo = {};
397 descriptorInfo.width = width;
398 descriptorInfo.height = height;
399 descriptorInfo.layerCount = layerCount;
400 descriptorInfo.format = static_cast<hardware::graphics::common::V1_1::PixelFormat>(format);
401 descriptorInfo.usage = usage;
Chia-I Wu5bac7f32017-04-06 12:34:32 -0700402
Marissa Wall1e779252018-12-29 12:01:57 -0800403 BufferDescriptor descriptor;
404 status_t error = mMapper.createDescriptor(static_cast<void*>(&descriptorInfo),
405 static_cast<void*>(&descriptor));
406 if (error != NO_ERROR) {
407 return error;
408 }
Chia-I Wu5bac7f32017-04-06 12:34:32 -0700409
Marissa Wall1e779252018-12-29 12:01:57 -0800410 auto ret = mAllocator->allocate(descriptor, bufferCount,
411 [&](const auto& tmpError, const auto& tmpStride,
412 const auto& tmpBuffers) {
413 error = static_cast<status_t>(tmpError);
414 if (tmpError != Error::NONE) {
415 return;
416 }
417
Marissa Wallbfcf81f2019-11-27 10:36:29 -0800418 if (importBuffers) {
419 for (uint32_t i = 0; i < bufferCount; i++) {
420 error = mMapper.importBuffer(tmpBuffers[i],
421 &outBufferHandles[i]);
422 if (error != NO_ERROR) {
423 for (uint32_t j = 0; j < i; j++) {
424 mMapper.freeBuffer(outBufferHandles[j]);
425 outBufferHandles[j] = nullptr;
426 }
427 return;
Marissa Wall1e779252018-12-29 12:01:57 -0800428 }
Marissa Wallbfcf81f2019-11-27 10:36:29 -0800429 }
430 } else {
431 for (uint32_t i = 0; i < bufferCount; i++) {
432 outBufferHandles[i] = native_handle_clone(
433 tmpBuffers[i].getNativeHandle());
434 if (!outBufferHandles[i]) {
435 for (uint32_t j = 0; j < i; j++) {
436 auto buffer = const_cast<native_handle_t*>(
437 outBufferHandles[j]);
438 native_handle_close(buffer);
439 native_handle_delete(buffer);
440 outBufferHandles[j] = nullptr;
441 }
442 }
Marissa Wall1e779252018-12-29 12:01:57 -0800443 }
444 }
Marissa Wall1e779252018-12-29 12:01:57 -0800445 *outStride = tmpStride;
446 });
Chia-I Wu5bac7f32017-04-06 12:34:32 -0700447
Chia-I Wud8091b92017-05-16 14:30:34 -0700448 // make sure the kernel driver sees BC_FREE_BUFFER and closes the fds now
449 hardware::IPCThreadState::self()->flushCommands();
450
Marissa Wall1e779252018-12-29 12:01:57 -0800451 return (ret.isOk()) ? error : static_cast<status_t>(kTransactionError);
Chia-I Wu5bac7f32017-04-06 12:34:32 -0700452}
453
Chia-I Wu5bac7f32017-04-06 12:34:32 -0700454} // namespace android