blob: 656472f1a1c40acb9b9b1e0edfbaccb6c0d8b56f [file] [log] [blame]
Mathias Agopian076b1cc2009-04-10 14:24:30 -07001/*
2 * Copyright (C) 2007 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
Mathias Agopian3330b202009-10-05 17:07:12 -070017#define LOG_TAG "GraphicBufferMapper"
Mathias Agopiancf563192012-02-29 20:43:29 -080018#define ATRACE_TAG ATRACE_TAG_GRAPHICS
Dan Stoza8deb4da2016-06-01 18:21:44 -070019//#define LOG_NDEBUG 0
Mathias Agopian076b1cc2009-04-10 14:24:30 -070020
Mathias Agopianfe2f54f2017-02-15 19:48:58 -080021#include <ui/GraphicBufferMapper.h>
Mathias Agopian076b1cc2009-04-10 14:24:30 -070022
Dan Stozad3182402014-11-17 12:03:59 -080023// We would eliminate the non-conforming zero-length array, but we can't since
24// this is effectively included from the Linux kernel
25#pragma clang diagnostic push
26#pragma clang diagnostic ignored "-Wzero-length-array"
Francis Hart8f396012014-04-01 15:30:53 +030027#include <sync/sync.h>
Dan Stozad3182402014-11-17 12:03:59 -080028#pragma clang diagnostic pop
Francis Hart8f396012014-04-01 15:30:53 +030029
Mathias Agopian076b1cc2009-04-10 14:24:30 -070030#include <utils/Log.h>
Mathias Agopiancf563192012-02-29 20:43:29 -080031#include <utils/Trace.h>
Mathias Agopian076b1cc2009-04-10 14:24:30 -070032
Chia-I Wu9ba189d2016-09-22 17:13:08 +080033#include <ui/GrallocMapper.h>
Mathias Agopiana9347642017-02-13 16:42:28 -080034#include <ui/GraphicBuffer.h>
Mathias Agopian076b1cc2009-04-10 14:24:30 -070035
Dan Stoza8deb4da2016-06-01 18:21:44 -070036#include <system/graphics.h>
Mathias Agopian8b765b72009-04-10 20:34:46 -070037
Mathias Agopian076b1cc2009-04-10 14:24:30 -070038namespace android {
39// ---------------------------------------------------------------------------
40
Mathias Agopian3330b202009-10-05 17:07:12 -070041ANDROID_SINGLETON_STATIC_INSTANCE( GraphicBufferMapper )
Mathias Agopian4243e662009-04-15 18:34:24 -070042
Mathias Agopian3330b202009-10-05 17:07:12 -070043GraphicBufferMapper::GraphicBufferMapper()
Chia-I Wu9ba189d2016-09-22 17:13:08 +080044 : mMapper(std::make_unique<const Gralloc2::Mapper>())
45{
46 if (!mMapper->valid()) {
47 mLoader = std::make_unique<Gralloc1::Loader>();
48 mDevice = mLoader->getDevice();
49 }
50}
Dan Stoza8deb4da2016-06-01 18:21:44 -070051
52
Mathias Agopian076b1cc2009-04-10 14:24:30 -070053
Mathias Agopian3330b202009-10-05 17:07:12 -070054status_t GraphicBufferMapper::registerBuffer(buffer_handle_t handle)
Mathias Agopian076b1cc2009-04-10 14:24:30 -070055{
Mathias Agopiancf563192012-02-29 20:43:29 -080056 ATRACE_CALL();
Mathias Agopian0a757812010-12-08 16:40:01 -080057
Chia-I Wu9ba189d2016-09-22 17:13:08 +080058 gralloc1_error_t error;
59 if (mMapper->valid()) {
60 error = static_cast<gralloc1_error_t>(mMapper->retain(handle));
61 } else {
Chia-I Wu7bd8adb2017-02-10 14:53:12 -080062 // This always returns GRALLOC1_BAD_HANDLE when handle is from a
63 // remote process and mDevice is backed by Gralloc1On0Adapter.
Chia-I Wu9ba189d2016-09-22 17:13:08 +080064 error = mDevice->retain(handle);
Chia-I Wu7bd8adb2017-02-10 14:53:12 -080065 if (error == GRALLOC1_ERROR_BAD_HANDLE &&
66 mDevice->hasCapability(GRALLOC1_CAPABILITY_ON_ADAPTER)) {
67 ALOGE("registerBuffer by handle is not supported with "
68 "Gralloc1On0Adapter");
69 }
Chia-I Wu9ba189d2016-09-22 17:13:08 +080070 }
71
Dan Stoza8deb4da2016-06-01 18:21:44 -070072 ALOGW_IF(error != GRALLOC1_ERROR_NONE, "registerBuffer(%p) failed: %d",
73 handle, error);
Mathias Agopian0a757812010-12-08 16:40:01 -080074
Dan Stoza8deb4da2016-06-01 18:21:44 -070075 return error;
76}
77
78status_t GraphicBufferMapper::registerBuffer(const GraphicBuffer* buffer)
79{
80 ATRACE_CALL();
81
Chia-I Wu9ba189d2016-09-22 17:13:08 +080082 gralloc1_error_t error;
83 if (mMapper->valid()) {
84 error = static_cast<gralloc1_error_t>(
85 mMapper->retain(buffer->getNativeBuffer()->handle));
86 } else {
87 error = mDevice->retain(buffer);
88 }
89
Dan Stoza8deb4da2016-06-01 18:21:44 -070090 ALOGW_IF(error != GRALLOC1_ERROR_NONE, "registerBuffer(%p) failed: %d",
91 buffer->getNativeBuffer()->handle, error);
92
93 return error;
Mathias Agopian076b1cc2009-04-10 14:24:30 -070094}
95
Mathias Agopian3330b202009-10-05 17:07:12 -070096status_t GraphicBufferMapper::unregisterBuffer(buffer_handle_t handle)
Mathias Agopian076b1cc2009-04-10 14:24:30 -070097{
Mathias Agopiancf563192012-02-29 20:43:29 -080098 ATRACE_CALL();
Mathias Agopian0a757812010-12-08 16:40:01 -080099
Chia-I Wu9ba189d2016-09-22 17:13:08 +0800100 gralloc1_error_t error;
101 if (mMapper->valid()) {
102 mMapper->release(handle);
103 error = GRALLOC1_ERROR_NONE;
104 } else {
105 error = mDevice->release(handle);
106 }
107
Dan Stoza8deb4da2016-06-01 18:21:44 -0700108 ALOGW_IF(error != GRALLOC1_ERROR_NONE, "unregisterBuffer(%p): failed %d",
109 handle, error);
Mathias Agopian0a757812010-12-08 16:40:01 -0800110
Dan Stoza8deb4da2016-06-01 18:21:44 -0700111 return error;
Mathias Agopian076b1cc2009-04-10 14:24:30 -0700112}
113
Dan Stoza8deb4da2016-06-01 18:21:44 -0700114static inline gralloc1_rect_t asGralloc1Rect(const Rect& rect) {
115 gralloc1_rect_t outRect{};
116 outRect.left = rect.left;
117 outRect.top = rect.top;
118 outRect.width = rect.width();
119 outRect.height = rect.height();
120 return outRect;
Mathias Agopian076b1cc2009-04-10 14:24:30 -0700121}
122
Craig Donner58a1ef22017-02-02 12:40:05 -0800123
124status_t GraphicBufferMapper::getDimensions(buffer_handle_t handle,
125 uint32_t* outWidth, uint32_t* outHeight) const
126{
127 ATRACE_CALL();
128
129 gralloc1_error_t error;
130 if (mMapper->valid()) {
131 mMapper->getDimensions(handle, outWidth, outHeight);
132 error = GRALLOC1_ERROR_NONE;
133 } else {
134 error = mDevice->getDimensions(handle, outWidth, outHeight);
135 }
136
137 ALOGW_IF(error != GRALLOC1_ERROR_NONE, "getDimensions(%p, ...): failed %d",
138 handle, error);
139
140 return error;
141}
142
143status_t GraphicBufferMapper::getFormat(buffer_handle_t handle,
144 int32_t* outFormat) const
145{
146 ATRACE_CALL();
147
148 gralloc1_error_t error;
149 if (mMapper->valid()) {
150 mMapper->getFormat(handle, outFormat);
151 error = GRALLOC1_ERROR_NONE;
152 } else {
153 error = mDevice->getFormat(handle, outFormat);
154 }
155
156 ALOGW_IF(error != GRALLOC1_ERROR_NONE, "getFormat(%p, ...): failed %d",
157 handle, error);
158
159 return error;
160}
161
162status_t GraphicBufferMapper::getLayerCount(buffer_handle_t handle,
163 uint32_t* outLayerCount) const
164{
165 ATRACE_CALL();
166
167 gralloc1_error_t error;
168 if (mMapper->valid()) {
169 mMapper->getLayerCount(handle, outLayerCount);
170 error = GRALLOC1_ERROR_NONE;
171 } else {
172 error = mDevice->getLayerCount(handle, outLayerCount);
173 }
174
175 ALOGW_IF(error != GRALLOC1_ERROR_NONE, "getLayerCount(%p, ...): failed %d",
176 handle, error);
177
178 return error;
179}
180
181status_t GraphicBufferMapper::getProducerUsage(buffer_handle_t handle,
182 uint64_t* outProducerUsage) const
183{
184 ATRACE_CALL();
185
186 gralloc1_error_t error;
187 if (mMapper->valid()) {
188 mMapper->getProducerUsage(handle, outProducerUsage);
189 error = GRALLOC1_ERROR_NONE;
190 } else {
191 error = mDevice->getProducerUsage(handle, outProducerUsage);
192 }
193
194 ALOGW_IF(error != GRALLOC1_ERROR_NONE,
195 "getProducerUsage(%p, ...): failed %d", handle, error);
196
197 return error;
198}
199
200status_t GraphicBufferMapper::getConsumerUsage(buffer_handle_t handle,
201 uint64_t* outConsumerUsage) const
202{
203 ATRACE_CALL();
204
205 gralloc1_error_t error;
206 if (mMapper->valid()) {
207 mMapper->getConsumerUsage(handle, outConsumerUsage);
208 error = GRALLOC1_ERROR_NONE;
209 } else {
210 error = mDevice->getConsumerUsage(handle, outConsumerUsage);
211 }
212
213 ALOGW_IF(error != GRALLOC1_ERROR_NONE,
214 "getConsumerUsage(%p, ...): failed %d", handle, error);
215
216 return error;
217}
218
219status_t GraphicBufferMapper::getBackingStore(buffer_handle_t handle,
220 uint64_t* outBackingStore) const
221{
222 ATRACE_CALL();
223
224 gralloc1_error_t error;
225 if (mMapper->valid()) {
226 mMapper->getBackingStore(handle, outBackingStore);
227 error = GRALLOC1_ERROR_NONE;
228 } else {
229 error = mDevice->getBackingStore(handle, outBackingStore);
230 }
231
232 ALOGW_IF(error != GRALLOC1_ERROR_NONE,
233 "getBackingStore(%p, ...): failed %d", handle, error);
234
235 return error;
236}
237
238status_t GraphicBufferMapper::getStride(buffer_handle_t handle,
239 uint32_t* outStride) const
240{
241 ATRACE_CALL();
242
243 gralloc1_error_t error;
244 if (mMapper->valid()) {
245 mMapper->getStride(handle, outStride);
246 error = GRALLOC1_ERROR_NONE;
247 } else {
248 error = mDevice->getStride(handle, outStride);
249 }
250
251 ALOGW_IF(error != GRALLOC1_ERROR_NONE, "getStride(%p, ...): failed %d",
252 handle, error);
253
254 return error;
255}
256
Dan Stoza8deb4da2016-06-01 18:21:44 -0700257status_t GraphicBufferMapper::lock(buffer_handle_t handle, uint32_t usage,
258 const Rect& bounds, void** vaddr)
Eino-Ville Talvalac43946b2013-05-04 18:07:43 -0700259{
Dan Stoza8deb4da2016-06-01 18:21:44 -0700260 return lockAsync(handle, usage, bounds, vaddr, -1);
261}
Eino-Ville Talvalac43946b2013-05-04 18:07:43 -0700262
Dan Stoza8deb4da2016-06-01 18:21:44 -0700263status_t GraphicBufferMapper::lockYCbCr(buffer_handle_t handle, uint32_t usage,
264 const Rect& bounds, android_ycbcr *ycbcr)
265{
266 return lockAsyncYCbCr(handle, usage, bounds, ycbcr, -1);
Eino-Ville Talvalac43946b2013-05-04 18:07:43 -0700267}
268
Mathias Agopian3330b202009-10-05 17:07:12 -0700269status_t GraphicBufferMapper::unlock(buffer_handle_t handle)
Mathias Agopian076b1cc2009-04-10 14:24:30 -0700270{
Dan Stoza8deb4da2016-06-01 18:21:44 -0700271 int32_t fenceFd = -1;
272 status_t error = unlockAsync(handle, &fenceFd);
273 if (error == NO_ERROR) {
274 sync_wait(fenceFd, -1);
275 close(fenceFd);
276 }
277 return error;
Mathias Agopian076b1cc2009-04-10 14:24:30 -0700278}
279
Francis Hart8f396012014-04-01 15:30:53 +0300280status_t GraphicBufferMapper::lockAsync(buffer_handle_t handle,
Dan Stozad3182402014-11-17 12:03:59 -0800281 uint32_t usage, const Rect& bounds, void** vaddr, int fenceFd)
Francis Hart8f396012014-04-01 15:30:53 +0300282{
Craig Donnere96a3252017-02-02 12:13:34 -0800283 return lockAsync(handle, usage, usage, bounds, vaddr, fenceFd);
284}
285
286status_t GraphicBufferMapper::lockAsync(buffer_handle_t handle,
287 uint64_t producerUsage, uint64_t consumerUsage, const Rect& bounds,
288 void** vaddr, int fenceFd)
289{
Francis Hart8f396012014-04-01 15:30:53 +0300290 ATRACE_CALL();
Francis Hart8f396012014-04-01 15:30:53 +0300291
Dan Stoza8deb4da2016-06-01 18:21:44 -0700292 gralloc1_rect_t accessRegion = asGralloc1Rect(bounds);
Chia-I Wu9ba189d2016-09-22 17:13:08 +0800293 gralloc1_error_t error;
294 if (mMapper->valid()) {
Chia-I Wu31669472016-12-07 14:55:24 +0800295 const Gralloc2::IMapper::Rect& accessRect =
296 *reinterpret_cast<Gralloc2::IMapper::Rect*>(&accessRegion);
Chia-I Wu9ba189d2016-09-22 17:13:08 +0800297 error = static_cast<gralloc1_error_t>(mMapper->lock(
Craig Donnere96a3252017-02-02 12:13:34 -0800298 handle, producerUsage, consumerUsage, accessRect,
299 fenceFd, vaddr));
Chia-I Wu9ba189d2016-09-22 17:13:08 +0800300 } else {
301 sp<Fence> fence = new Fence(fenceFd);
302 error = mDevice->lock(handle,
Craig Donnere96a3252017-02-02 12:13:34 -0800303 static_cast<gralloc1_producer_usage_t>(producerUsage),
304 static_cast<gralloc1_consumer_usage_t>(consumerUsage),
Chia-I Wu9ba189d2016-09-22 17:13:08 +0800305 &accessRegion, vaddr, fence);
306 }
307
Dan Stoza8deb4da2016-06-01 18:21:44 -0700308 ALOGW_IF(error != GRALLOC1_ERROR_NONE, "lock(%p, ...) failed: %d", handle,
309 error);
310
311 return error;
312}
313
314static inline bool isValidYCbCrPlane(const android_flex_plane_t& plane) {
315 if (plane.bits_per_component != 8) {
316 ALOGV("Invalid number of bits per component: %d",
317 plane.bits_per_component);
318 return false;
319 }
320 if (plane.bits_used != 8) {
321 ALOGV("Invalid number of bits used: %d", plane.bits_used);
322 return false;
Francis Hart8f396012014-04-01 15:30:53 +0300323 }
324
Dan Stoza8deb4da2016-06-01 18:21:44 -0700325 bool hasValidIncrement = plane.h_increment == 1 ||
326 (plane.component != FLEX_COMPONENT_Y && plane.h_increment == 2);
327 hasValidIncrement = hasValidIncrement && plane.v_increment > 0;
328 if (!hasValidIncrement) {
329 ALOGV("Invalid increment: h %d v %d", plane.h_increment,
330 plane.v_increment);
331 return false;
332 }
333
334 return true;
Francis Hart8f396012014-04-01 15:30:53 +0300335}
336
337status_t GraphicBufferMapper::lockAsyncYCbCr(buffer_handle_t handle,
Dan Stozad3182402014-11-17 12:03:59 -0800338 uint32_t usage, const Rect& bounds, android_ycbcr *ycbcr, int fenceFd)
Francis Hart8f396012014-04-01 15:30:53 +0300339{
340 ATRACE_CALL();
Francis Hart8f396012014-04-01 15:30:53 +0300341
Dan Stoza8deb4da2016-06-01 18:21:44 -0700342 gralloc1_rect_t accessRegion = asGralloc1Rect(bounds);
Dan Stoza8deb4da2016-06-01 18:21:44 -0700343
Chia-I Wu31669472016-12-07 14:55:24 +0800344 std::vector<android_flex_plane_t> planes;
345 android_flex_layout_t flexLayout{};
346 gralloc1_error_t error;
347
348 if (mMapper->valid()) {
349 const Gralloc2::IMapper::Rect& accessRect =
350 *reinterpret_cast<Gralloc2::IMapper::Rect*>(&accessRegion);
351 Gralloc2::FlexLayout layout{};
352 error = static_cast<gralloc1_error_t>(mMapper->lock(
353 handle, usage, usage, accessRect, fenceFd, &layout));
354
355 if (error == GRALLOC1_ERROR_NONE) {
356 planes.resize(layout.planes.size());
357 memcpy(planes.data(), layout.planes.data(),
358 sizeof(planes[0]) * planes.size());
359
360 flexLayout.format = static_cast<android_flex_format_t>(
361 layout.format);
362 flexLayout.num_planes = static_cast<uint32_t>(planes.size());
363 flexLayout.planes = planes.data();
364 }
365 } else {
366 sp<Fence> fence = new Fence(fenceFd);
367
Chia-I Wu9ba189d2016-09-22 17:13:08 +0800368 if (mDevice->hasCapability(GRALLOC1_CAPABILITY_ON_ADAPTER)) {
Chia-I Wu31669472016-12-07 14:55:24 +0800369 error = mDevice->lockYCbCr(handle,
Chia-I Wu9ba189d2016-09-22 17:13:08 +0800370 static_cast<gralloc1_producer_usage_t>(usage),
371 static_cast<gralloc1_consumer_usage_t>(usage),
372 &accessRegion, ycbcr, fence);
373 ALOGW_IF(error != GRALLOC1_ERROR_NONE,
374 "lockYCbCr(%p, ...) failed: %d", handle, error);
375 return error;
376 }
Francis Hart8f396012014-04-01 15:30:53 +0300377
Chia-I Wu31669472016-12-07 14:55:24 +0800378 uint32_t numPlanes = 0;
Chia-I Wu9ba189d2016-09-22 17:13:08 +0800379 error = mDevice->getNumFlexPlanes(handle, &numPlanes);
Chia-I Wu9ba189d2016-09-22 17:13:08 +0800380
Chia-I Wu31669472016-12-07 14:55:24 +0800381 if (error != GRALLOC1_ERROR_NONE) {
382 ALOGV("Failed to retrieve number of flex planes: %d", error);
383 return error;
384 }
385 if (numPlanes < 3) {
386 ALOGV("Not enough planes for YCbCr (%u found)", numPlanes);
387 return GRALLOC1_ERROR_UNSUPPORTED;
388 }
Dan Stoza8deb4da2016-06-01 18:21:44 -0700389
Chia-I Wu31669472016-12-07 14:55:24 +0800390 planes.resize(numPlanes);
391 flexLayout.num_planes = numPlanes;
392 flexLayout.planes = planes.data();
Dan Stoza8deb4da2016-06-01 18:21:44 -0700393
Chia-I Wu9ba189d2016-09-22 17:13:08 +0800394 error = mDevice->lockFlex(handle,
395 static_cast<gralloc1_producer_usage_t>(usage),
396 static_cast<gralloc1_consumer_usage_t>(usage),
397 &accessRegion, &flexLayout, fence);
398 }
399
Dan Stoza8deb4da2016-06-01 18:21:44 -0700400 if (error != GRALLOC1_ERROR_NONE) {
401 ALOGW("lockFlex(%p, ...) failed: %d", handle, error);
402 return error;
403 }
404 if (flexLayout.format != FLEX_FORMAT_YCbCr) {
405 ALOGV("Unable to convert flex-format buffer to YCbCr");
406 unlock(handle);
407 return GRALLOC1_ERROR_UNSUPPORTED;
408 }
409
410 // Find planes
411 auto yPlane = planes.cend();
412 auto cbPlane = planes.cend();
413 auto crPlane = planes.cend();
414 for (auto planeIter = planes.cbegin(); planeIter != planes.cend();
415 ++planeIter) {
416 if (planeIter->component == FLEX_COMPONENT_Y) {
417 yPlane = planeIter;
418 } else if (planeIter->component == FLEX_COMPONENT_Cb) {
419 cbPlane = planeIter;
420 } else if (planeIter->component == FLEX_COMPONENT_Cr) {
421 crPlane = planeIter;
422 }
423 }
424 if (yPlane == planes.cend()) {
425 ALOGV("Unable to find Y plane");
426 unlock(handle);
427 return GRALLOC1_ERROR_UNSUPPORTED;
428 }
429 if (cbPlane == planes.cend()) {
430 ALOGV("Unable to find Cb plane");
431 unlock(handle);
432 return GRALLOC1_ERROR_UNSUPPORTED;
433 }
434 if (crPlane == planes.cend()) {
435 ALOGV("Unable to find Cr plane");
436 unlock(handle);
437 return GRALLOC1_ERROR_UNSUPPORTED;
438 }
439
440 // Validate planes
441 if (!isValidYCbCrPlane(*yPlane)) {
442 ALOGV("Y plane is invalid");
443 unlock(handle);
444 return GRALLOC1_ERROR_UNSUPPORTED;
445 }
446 if (!isValidYCbCrPlane(*cbPlane)) {
447 ALOGV("Cb plane is invalid");
448 unlock(handle);
449 return GRALLOC1_ERROR_UNSUPPORTED;
450 }
451 if (!isValidYCbCrPlane(*crPlane)) {
452 ALOGV("Cr plane is invalid");
453 unlock(handle);
454 return GRALLOC1_ERROR_UNSUPPORTED;
455 }
456 if (cbPlane->v_increment != crPlane->v_increment) {
457 ALOGV("Cb and Cr planes have different step (%d vs. %d)",
458 cbPlane->v_increment, crPlane->v_increment);
459 unlock(handle);
460 return GRALLOC1_ERROR_UNSUPPORTED;
461 }
462 if (cbPlane->h_increment != crPlane->h_increment) {
463 ALOGV("Cb and Cr planes have different stride (%d vs. %d)",
464 cbPlane->h_increment, crPlane->h_increment);
465 unlock(handle);
466 return GRALLOC1_ERROR_UNSUPPORTED;
467 }
468
469 // Pack plane data into android_ycbcr struct
470 ycbcr->y = yPlane->top_left;
471 ycbcr->cb = cbPlane->top_left;
472 ycbcr->cr = crPlane->top_left;
473 ycbcr->ystride = static_cast<size_t>(yPlane->v_increment);
474 ycbcr->cstride = static_cast<size_t>(cbPlane->v_increment);
475 ycbcr->chroma_step = static_cast<size_t>(cbPlane->h_increment);
476
477 return error;
Francis Hart8f396012014-04-01 15:30:53 +0300478}
479
480status_t GraphicBufferMapper::unlockAsync(buffer_handle_t handle, int *fenceFd)
481{
482 ATRACE_CALL();
Francis Hart8f396012014-04-01 15:30:53 +0300483
Chia-I Wu9ba189d2016-09-22 17:13:08 +0800484 gralloc1_error_t error;
485 if (mMapper->valid()) {
486 *fenceFd = mMapper->unlock(handle);
487 error = GRALLOC1_ERROR_NONE;
488 } else {
489 sp<Fence> fence = Fence::NO_FENCE;
490 error = mDevice->unlock(handle, &fence);
491 if (error != GRALLOC1_ERROR_NONE) {
492 ALOGE("unlock(%p) failed: %d", handle, error);
493 return error;
494 }
Francis Hart8f396012014-04-01 15:30:53 +0300495
Chia-I Wu9ba189d2016-09-22 17:13:08 +0800496 *fenceFd = fence->dup();
497 }
Dan Stoza8deb4da2016-06-01 18:21:44 -0700498 return error;
Francis Hart8f396012014-04-01 15:30:53 +0300499}
500
Mathias Agopian076b1cc2009-04-10 14:24:30 -0700501// ---------------------------------------------------------------------------
Mathias Agopian076b1cc2009-04-10 14:24:30 -0700502}; // namespace android