blob: f418f7f015a06b2c8ac595bae58c11f47ddeace9 [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
21#include <stdint.h>
Mathias Agopian076b1cc2009-04-10 14:24:30 -070022#include <errno.h>
Mathias Agopian076b1cc2009-04-10 14:24:30 -070023
Dan Stozad3182402014-11-17 12:03:59 -080024// We would eliminate the non-conforming zero-length array, but we can't since
25// this is effectively included from the Linux kernel
26#pragma clang diagnostic push
27#pragma clang diagnostic ignored "-Wzero-length-array"
Francis Hart8f396012014-04-01 15:30:53 +030028#include <sync/sync.h>
Dan Stozad3182402014-11-17 12:03:59 -080029#pragma clang diagnostic pop
Francis Hart8f396012014-04-01 15:30:53 +030030
Mathias Agopian076b1cc2009-04-10 14:24:30 -070031#include <utils/Errors.h>
Mathias Agopian076b1cc2009-04-10 14:24:30 -070032#include <utils/Log.h>
Mathias Agopiancf563192012-02-29 20:43:29 -080033#include <utils/Trace.h>
Mathias Agopian076b1cc2009-04-10 14:24:30 -070034
Dan Stoza8deb4da2016-06-01 18:21:44 -070035#include <ui/Gralloc1On0Adapter.h>
Chia-I Wu9ba189d2016-09-22 17:13:08 +080036#include <ui/GrallocMapper.h>
Mathias Agopian3330b202009-10-05 17:07:12 -070037#include <ui/GraphicBufferMapper.h>
Mathias Agopiana9347642017-02-13 16:42:28 -080038#include <ui/GraphicBuffer.h>
Mathias Agopian076b1cc2009-04-10 14:24:30 -070039
Dan Stoza8deb4da2016-06-01 18:21:44 -070040#include <system/graphics.h>
Mathias Agopian8b765b72009-04-10 20:34:46 -070041
Mathias Agopian076b1cc2009-04-10 14:24:30 -070042namespace android {
43// ---------------------------------------------------------------------------
44
Mathias Agopian3330b202009-10-05 17:07:12 -070045ANDROID_SINGLETON_STATIC_INSTANCE( GraphicBufferMapper )
Mathias Agopian4243e662009-04-15 18:34:24 -070046
Mathias Agopian3330b202009-10-05 17:07:12 -070047GraphicBufferMapper::GraphicBufferMapper()
Chia-I Wu9ba189d2016-09-22 17:13:08 +080048 : mMapper(std::make_unique<const Gralloc2::Mapper>())
49{
50 if (!mMapper->valid()) {
51 mLoader = std::make_unique<Gralloc1::Loader>();
52 mDevice = mLoader->getDevice();
53 }
54}
Dan Stoza8deb4da2016-06-01 18:21:44 -070055
56
Mathias Agopian076b1cc2009-04-10 14:24:30 -070057
Mathias Agopian3330b202009-10-05 17:07:12 -070058status_t GraphicBufferMapper::registerBuffer(buffer_handle_t handle)
Mathias Agopian076b1cc2009-04-10 14:24:30 -070059{
Mathias Agopiancf563192012-02-29 20:43:29 -080060 ATRACE_CALL();
Mathias Agopian0a757812010-12-08 16:40:01 -080061
Chia-I Wu9ba189d2016-09-22 17:13:08 +080062 gralloc1_error_t error;
63 if (mMapper->valid()) {
64 error = static_cast<gralloc1_error_t>(mMapper->retain(handle));
65 } else {
Chia-I Wu7bd8adb2017-02-10 14:53:12 -080066 // This always returns GRALLOC1_BAD_HANDLE when handle is from a
67 // remote process and mDevice is backed by Gralloc1On0Adapter.
Chia-I Wu9ba189d2016-09-22 17:13:08 +080068 error = mDevice->retain(handle);
Chia-I Wu7bd8adb2017-02-10 14:53:12 -080069 if (error == GRALLOC1_ERROR_BAD_HANDLE &&
70 mDevice->hasCapability(GRALLOC1_CAPABILITY_ON_ADAPTER)) {
71 ALOGE("registerBuffer by handle is not supported with "
72 "Gralloc1On0Adapter");
73 }
Chia-I Wu9ba189d2016-09-22 17:13:08 +080074 }
75
Dan Stoza8deb4da2016-06-01 18:21:44 -070076 ALOGW_IF(error != GRALLOC1_ERROR_NONE, "registerBuffer(%p) failed: %d",
77 handle, error);
Mathias Agopian0a757812010-12-08 16:40:01 -080078
Dan Stoza8deb4da2016-06-01 18:21:44 -070079 return error;
80}
81
82status_t GraphicBufferMapper::registerBuffer(const GraphicBuffer* buffer)
83{
84 ATRACE_CALL();
85
Chia-I Wu9ba189d2016-09-22 17:13:08 +080086 gralloc1_error_t error;
87 if (mMapper->valid()) {
88 error = static_cast<gralloc1_error_t>(
89 mMapper->retain(buffer->getNativeBuffer()->handle));
90 } else {
91 error = mDevice->retain(buffer);
92 }
93
Dan Stoza8deb4da2016-06-01 18:21:44 -070094 ALOGW_IF(error != GRALLOC1_ERROR_NONE, "registerBuffer(%p) failed: %d",
95 buffer->getNativeBuffer()->handle, error);
96
97 return error;
Mathias Agopian076b1cc2009-04-10 14:24:30 -070098}
99
Mathias Agopian3330b202009-10-05 17:07:12 -0700100status_t GraphicBufferMapper::unregisterBuffer(buffer_handle_t handle)
Mathias Agopian076b1cc2009-04-10 14:24:30 -0700101{
Mathias Agopiancf563192012-02-29 20:43:29 -0800102 ATRACE_CALL();
Mathias Agopian0a757812010-12-08 16:40:01 -0800103
Chia-I Wu9ba189d2016-09-22 17:13:08 +0800104 gralloc1_error_t error;
105 if (mMapper->valid()) {
106 mMapper->release(handle);
107 error = GRALLOC1_ERROR_NONE;
108 } else {
109 error = mDevice->release(handle);
110 }
111
Dan Stoza8deb4da2016-06-01 18:21:44 -0700112 ALOGW_IF(error != GRALLOC1_ERROR_NONE, "unregisterBuffer(%p): failed %d",
113 handle, error);
Mathias Agopian0a757812010-12-08 16:40:01 -0800114
Dan Stoza8deb4da2016-06-01 18:21:44 -0700115 return error;
Mathias Agopian076b1cc2009-04-10 14:24:30 -0700116}
117
Dan Stoza8deb4da2016-06-01 18:21:44 -0700118static inline gralloc1_rect_t asGralloc1Rect(const Rect& rect) {
119 gralloc1_rect_t outRect{};
120 outRect.left = rect.left;
121 outRect.top = rect.top;
122 outRect.width = rect.width();
123 outRect.height = rect.height();
124 return outRect;
Mathias Agopian076b1cc2009-04-10 14:24:30 -0700125}
126
Craig Donner58a1ef22017-02-02 12:40:05 -0800127
128status_t GraphicBufferMapper::getDimensions(buffer_handle_t handle,
129 uint32_t* outWidth, uint32_t* outHeight) const
130{
131 ATRACE_CALL();
132
133 gralloc1_error_t error;
134 if (mMapper->valid()) {
135 mMapper->getDimensions(handle, outWidth, outHeight);
136 error = GRALLOC1_ERROR_NONE;
137 } else {
138 error = mDevice->getDimensions(handle, outWidth, outHeight);
139 }
140
141 ALOGW_IF(error != GRALLOC1_ERROR_NONE, "getDimensions(%p, ...): failed %d",
142 handle, error);
143
144 return error;
145}
146
147status_t GraphicBufferMapper::getFormat(buffer_handle_t handle,
148 int32_t* outFormat) const
149{
150 ATRACE_CALL();
151
152 gralloc1_error_t error;
153 if (mMapper->valid()) {
154 mMapper->getFormat(handle, outFormat);
155 error = GRALLOC1_ERROR_NONE;
156 } else {
157 error = mDevice->getFormat(handle, outFormat);
158 }
159
160 ALOGW_IF(error != GRALLOC1_ERROR_NONE, "getFormat(%p, ...): failed %d",
161 handle, error);
162
163 return error;
164}
165
166status_t GraphicBufferMapper::getLayerCount(buffer_handle_t handle,
167 uint32_t* outLayerCount) const
168{
169 ATRACE_CALL();
170
171 gralloc1_error_t error;
172 if (mMapper->valid()) {
173 mMapper->getLayerCount(handle, outLayerCount);
174 error = GRALLOC1_ERROR_NONE;
175 } else {
176 error = mDevice->getLayerCount(handle, outLayerCount);
177 }
178
179 ALOGW_IF(error != GRALLOC1_ERROR_NONE, "getLayerCount(%p, ...): failed %d",
180 handle, error);
181
182 return error;
183}
184
185status_t GraphicBufferMapper::getProducerUsage(buffer_handle_t handle,
186 uint64_t* outProducerUsage) const
187{
188 ATRACE_CALL();
189
190 gralloc1_error_t error;
191 if (mMapper->valid()) {
192 mMapper->getProducerUsage(handle, outProducerUsage);
193 error = GRALLOC1_ERROR_NONE;
194 } else {
195 error = mDevice->getProducerUsage(handle, outProducerUsage);
196 }
197
198 ALOGW_IF(error != GRALLOC1_ERROR_NONE,
199 "getProducerUsage(%p, ...): failed %d", handle, error);
200
201 return error;
202}
203
204status_t GraphicBufferMapper::getConsumerUsage(buffer_handle_t handle,
205 uint64_t* outConsumerUsage) const
206{
207 ATRACE_CALL();
208
209 gralloc1_error_t error;
210 if (mMapper->valid()) {
211 mMapper->getConsumerUsage(handle, outConsumerUsage);
212 error = GRALLOC1_ERROR_NONE;
213 } else {
214 error = mDevice->getConsumerUsage(handle, outConsumerUsage);
215 }
216
217 ALOGW_IF(error != GRALLOC1_ERROR_NONE,
218 "getConsumerUsage(%p, ...): failed %d", handle, error);
219
220 return error;
221}
222
223status_t GraphicBufferMapper::getBackingStore(buffer_handle_t handle,
224 uint64_t* outBackingStore) const
225{
226 ATRACE_CALL();
227
228 gralloc1_error_t error;
229 if (mMapper->valid()) {
230 mMapper->getBackingStore(handle, outBackingStore);
231 error = GRALLOC1_ERROR_NONE;
232 } else {
233 error = mDevice->getBackingStore(handle, outBackingStore);
234 }
235
236 ALOGW_IF(error != GRALLOC1_ERROR_NONE,
237 "getBackingStore(%p, ...): failed %d", handle, error);
238
239 return error;
240}
241
242status_t GraphicBufferMapper::getStride(buffer_handle_t handle,
243 uint32_t* outStride) const
244{
245 ATRACE_CALL();
246
247 gralloc1_error_t error;
248 if (mMapper->valid()) {
249 mMapper->getStride(handle, outStride);
250 error = GRALLOC1_ERROR_NONE;
251 } else {
252 error = mDevice->getStride(handle, outStride);
253 }
254
255 ALOGW_IF(error != GRALLOC1_ERROR_NONE, "getStride(%p, ...): failed %d",
256 handle, error);
257
258 return error;
259}
260
Dan Stoza8deb4da2016-06-01 18:21:44 -0700261status_t GraphicBufferMapper::lock(buffer_handle_t handle, uint32_t usage,
262 const Rect& bounds, void** vaddr)
Eino-Ville Talvalac43946b2013-05-04 18:07:43 -0700263{
Dan Stoza8deb4da2016-06-01 18:21:44 -0700264 return lockAsync(handle, usage, bounds, vaddr, -1);
265}
Eino-Ville Talvalac43946b2013-05-04 18:07:43 -0700266
Dan Stoza8deb4da2016-06-01 18:21:44 -0700267status_t GraphicBufferMapper::lockYCbCr(buffer_handle_t handle, uint32_t usage,
268 const Rect& bounds, android_ycbcr *ycbcr)
269{
270 return lockAsyncYCbCr(handle, usage, bounds, ycbcr, -1);
Eino-Ville Talvalac43946b2013-05-04 18:07:43 -0700271}
272
Mathias Agopian3330b202009-10-05 17:07:12 -0700273status_t GraphicBufferMapper::unlock(buffer_handle_t handle)
Mathias Agopian076b1cc2009-04-10 14:24:30 -0700274{
Dan Stoza8deb4da2016-06-01 18:21:44 -0700275 int32_t fenceFd = -1;
276 status_t error = unlockAsync(handle, &fenceFd);
277 if (error == NO_ERROR) {
278 sync_wait(fenceFd, -1);
279 close(fenceFd);
280 }
281 return error;
Mathias Agopian076b1cc2009-04-10 14:24:30 -0700282}
283
Francis Hart8f396012014-04-01 15:30:53 +0300284status_t GraphicBufferMapper::lockAsync(buffer_handle_t handle,
Dan Stozad3182402014-11-17 12:03:59 -0800285 uint32_t usage, const Rect& bounds, void** vaddr, int fenceFd)
Francis Hart8f396012014-04-01 15:30:53 +0300286{
Craig Donnere96a3252017-02-02 12:13:34 -0800287 return lockAsync(handle, usage, usage, bounds, vaddr, fenceFd);
288}
289
290status_t GraphicBufferMapper::lockAsync(buffer_handle_t handle,
291 uint64_t producerUsage, uint64_t consumerUsage, const Rect& bounds,
292 void** vaddr, int fenceFd)
293{
Francis Hart8f396012014-04-01 15:30:53 +0300294 ATRACE_CALL();
Francis Hart8f396012014-04-01 15:30:53 +0300295
Dan Stoza8deb4da2016-06-01 18:21:44 -0700296 gralloc1_rect_t accessRegion = asGralloc1Rect(bounds);
Chia-I Wu9ba189d2016-09-22 17:13:08 +0800297 gralloc1_error_t error;
298 if (mMapper->valid()) {
Chia-I Wu31669472016-12-07 14:55:24 +0800299 const Gralloc2::IMapper::Rect& accessRect =
300 *reinterpret_cast<Gralloc2::IMapper::Rect*>(&accessRegion);
Chia-I Wu9ba189d2016-09-22 17:13:08 +0800301 error = static_cast<gralloc1_error_t>(mMapper->lock(
Craig Donnere96a3252017-02-02 12:13:34 -0800302 handle, producerUsage, consumerUsage, accessRect,
303 fenceFd, vaddr));
Chia-I Wu9ba189d2016-09-22 17:13:08 +0800304 } else {
305 sp<Fence> fence = new Fence(fenceFd);
306 error = mDevice->lock(handle,
Craig Donnere96a3252017-02-02 12:13:34 -0800307 static_cast<gralloc1_producer_usage_t>(producerUsage),
308 static_cast<gralloc1_consumer_usage_t>(consumerUsage),
Chia-I Wu9ba189d2016-09-22 17:13:08 +0800309 &accessRegion, vaddr, fence);
310 }
311
Dan Stoza8deb4da2016-06-01 18:21:44 -0700312 ALOGW_IF(error != GRALLOC1_ERROR_NONE, "lock(%p, ...) failed: %d", handle,
313 error);
314
315 return error;
316}
317
318static inline bool isValidYCbCrPlane(const android_flex_plane_t& plane) {
319 if (plane.bits_per_component != 8) {
320 ALOGV("Invalid number of bits per component: %d",
321 plane.bits_per_component);
322 return false;
323 }
324 if (plane.bits_used != 8) {
325 ALOGV("Invalid number of bits used: %d", plane.bits_used);
326 return false;
Francis Hart8f396012014-04-01 15:30:53 +0300327 }
328
Dan Stoza8deb4da2016-06-01 18:21:44 -0700329 bool hasValidIncrement = plane.h_increment == 1 ||
330 (plane.component != FLEX_COMPONENT_Y && plane.h_increment == 2);
331 hasValidIncrement = hasValidIncrement && plane.v_increment > 0;
332 if (!hasValidIncrement) {
333 ALOGV("Invalid increment: h %d v %d", plane.h_increment,
334 plane.v_increment);
335 return false;
336 }
337
338 return true;
Francis Hart8f396012014-04-01 15:30:53 +0300339}
340
341status_t GraphicBufferMapper::lockAsyncYCbCr(buffer_handle_t handle,
Dan Stozad3182402014-11-17 12:03:59 -0800342 uint32_t usage, const Rect& bounds, android_ycbcr *ycbcr, int fenceFd)
Francis Hart8f396012014-04-01 15:30:53 +0300343{
344 ATRACE_CALL();
Francis Hart8f396012014-04-01 15:30:53 +0300345
Dan Stoza8deb4da2016-06-01 18:21:44 -0700346 gralloc1_rect_t accessRegion = asGralloc1Rect(bounds);
Dan Stoza8deb4da2016-06-01 18:21:44 -0700347
Chia-I Wu31669472016-12-07 14:55:24 +0800348 std::vector<android_flex_plane_t> planes;
349 android_flex_layout_t flexLayout{};
350 gralloc1_error_t error;
351
352 if (mMapper->valid()) {
353 const Gralloc2::IMapper::Rect& accessRect =
354 *reinterpret_cast<Gralloc2::IMapper::Rect*>(&accessRegion);
355 Gralloc2::FlexLayout layout{};
356 error = static_cast<gralloc1_error_t>(mMapper->lock(
357 handle, usage, usage, accessRect, fenceFd, &layout));
358
359 if (error == GRALLOC1_ERROR_NONE) {
360 planes.resize(layout.planes.size());
361 memcpy(planes.data(), layout.planes.data(),
362 sizeof(planes[0]) * planes.size());
363
364 flexLayout.format = static_cast<android_flex_format_t>(
365 layout.format);
366 flexLayout.num_planes = static_cast<uint32_t>(planes.size());
367 flexLayout.planes = planes.data();
368 }
369 } else {
370 sp<Fence> fence = new Fence(fenceFd);
371
Chia-I Wu9ba189d2016-09-22 17:13:08 +0800372 if (mDevice->hasCapability(GRALLOC1_CAPABILITY_ON_ADAPTER)) {
Chia-I Wu31669472016-12-07 14:55:24 +0800373 error = mDevice->lockYCbCr(handle,
Chia-I Wu9ba189d2016-09-22 17:13:08 +0800374 static_cast<gralloc1_producer_usage_t>(usage),
375 static_cast<gralloc1_consumer_usage_t>(usage),
376 &accessRegion, ycbcr, fence);
377 ALOGW_IF(error != GRALLOC1_ERROR_NONE,
378 "lockYCbCr(%p, ...) failed: %d", handle, error);
379 return error;
380 }
Francis Hart8f396012014-04-01 15:30:53 +0300381
Chia-I Wu31669472016-12-07 14:55:24 +0800382 uint32_t numPlanes = 0;
Chia-I Wu9ba189d2016-09-22 17:13:08 +0800383 error = mDevice->getNumFlexPlanes(handle, &numPlanes);
Chia-I Wu9ba189d2016-09-22 17:13:08 +0800384
Chia-I Wu31669472016-12-07 14:55:24 +0800385 if (error != GRALLOC1_ERROR_NONE) {
386 ALOGV("Failed to retrieve number of flex planes: %d", error);
387 return error;
388 }
389 if (numPlanes < 3) {
390 ALOGV("Not enough planes for YCbCr (%u found)", numPlanes);
391 return GRALLOC1_ERROR_UNSUPPORTED;
392 }
Dan Stoza8deb4da2016-06-01 18:21:44 -0700393
Chia-I Wu31669472016-12-07 14:55:24 +0800394 planes.resize(numPlanes);
395 flexLayout.num_planes = numPlanes;
396 flexLayout.planes = planes.data();
Dan Stoza8deb4da2016-06-01 18:21:44 -0700397
Chia-I Wu9ba189d2016-09-22 17:13:08 +0800398 error = mDevice->lockFlex(handle,
399 static_cast<gralloc1_producer_usage_t>(usage),
400 static_cast<gralloc1_consumer_usage_t>(usage),
401 &accessRegion, &flexLayout, fence);
402 }
403
Dan Stoza8deb4da2016-06-01 18:21:44 -0700404 if (error != GRALLOC1_ERROR_NONE) {
405 ALOGW("lockFlex(%p, ...) failed: %d", handle, error);
406 return error;
407 }
408 if (flexLayout.format != FLEX_FORMAT_YCbCr) {
409 ALOGV("Unable to convert flex-format buffer to YCbCr");
410 unlock(handle);
411 return GRALLOC1_ERROR_UNSUPPORTED;
412 }
413
414 // Find planes
415 auto yPlane = planes.cend();
416 auto cbPlane = planes.cend();
417 auto crPlane = planes.cend();
418 for (auto planeIter = planes.cbegin(); planeIter != planes.cend();
419 ++planeIter) {
420 if (planeIter->component == FLEX_COMPONENT_Y) {
421 yPlane = planeIter;
422 } else if (planeIter->component == FLEX_COMPONENT_Cb) {
423 cbPlane = planeIter;
424 } else if (planeIter->component == FLEX_COMPONENT_Cr) {
425 crPlane = planeIter;
426 }
427 }
428 if (yPlane == planes.cend()) {
429 ALOGV("Unable to find Y plane");
430 unlock(handle);
431 return GRALLOC1_ERROR_UNSUPPORTED;
432 }
433 if (cbPlane == planes.cend()) {
434 ALOGV("Unable to find Cb plane");
435 unlock(handle);
436 return GRALLOC1_ERROR_UNSUPPORTED;
437 }
438 if (crPlane == planes.cend()) {
439 ALOGV("Unable to find Cr plane");
440 unlock(handle);
441 return GRALLOC1_ERROR_UNSUPPORTED;
442 }
443
444 // Validate planes
445 if (!isValidYCbCrPlane(*yPlane)) {
446 ALOGV("Y plane is invalid");
447 unlock(handle);
448 return GRALLOC1_ERROR_UNSUPPORTED;
449 }
450 if (!isValidYCbCrPlane(*cbPlane)) {
451 ALOGV("Cb plane is invalid");
452 unlock(handle);
453 return GRALLOC1_ERROR_UNSUPPORTED;
454 }
455 if (!isValidYCbCrPlane(*crPlane)) {
456 ALOGV("Cr plane is invalid");
457 unlock(handle);
458 return GRALLOC1_ERROR_UNSUPPORTED;
459 }
460 if (cbPlane->v_increment != crPlane->v_increment) {
461 ALOGV("Cb and Cr planes have different step (%d vs. %d)",
462 cbPlane->v_increment, crPlane->v_increment);
463 unlock(handle);
464 return GRALLOC1_ERROR_UNSUPPORTED;
465 }
466 if (cbPlane->h_increment != crPlane->h_increment) {
467 ALOGV("Cb and Cr planes have different stride (%d vs. %d)",
468 cbPlane->h_increment, crPlane->h_increment);
469 unlock(handle);
470 return GRALLOC1_ERROR_UNSUPPORTED;
471 }
472
473 // Pack plane data into android_ycbcr struct
474 ycbcr->y = yPlane->top_left;
475 ycbcr->cb = cbPlane->top_left;
476 ycbcr->cr = crPlane->top_left;
477 ycbcr->ystride = static_cast<size_t>(yPlane->v_increment);
478 ycbcr->cstride = static_cast<size_t>(cbPlane->v_increment);
479 ycbcr->chroma_step = static_cast<size_t>(cbPlane->h_increment);
480
481 return error;
Francis Hart8f396012014-04-01 15:30:53 +0300482}
483
484status_t GraphicBufferMapper::unlockAsync(buffer_handle_t handle, int *fenceFd)
485{
486 ATRACE_CALL();
Francis Hart8f396012014-04-01 15:30:53 +0300487
Chia-I Wu9ba189d2016-09-22 17:13:08 +0800488 gralloc1_error_t error;
489 if (mMapper->valid()) {
490 *fenceFd = mMapper->unlock(handle);
491 error = GRALLOC1_ERROR_NONE;
492 } else {
493 sp<Fence> fence = Fence::NO_FENCE;
494 error = mDevice->unlock(handle, &fence);
495 if (error != GRALLOC1_ERROR_NONE) {
496 ALOGE("unlock(%p) failed: %d", handle, error);
497 return error;
498 }
Francis Hart8f396012014-04-01 15:30:53 +0300499
Chia-I Wu9ba189d2016-09-22 17:13:08 +0800500 *fenceFd = fence->dup();
501 }
Dan Stoza8deb4da2016-06-01 18:21:44 -0700502 return error;
Francis Hart8f396012014-04-01 15:30:53 +0300503}
504
Mathias Agopian076b1cc2009-04-10 14:24:30 -0700505// ---------------------------------------------------------------------------
Mathias Agopian076b1cc2009-04-10 14:24:30 -0700506}; // namespace android