1 /*
2 * Copyright (C) 2008 The Android Open Source Project
3 * Copyright (c) 2011-2016, The Linux Foundation. All rights reserved.
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17
18 #define ATRACE_TAG (ATRACE_TAG_GRAPHICS | ATRACE_TAG_HAL)
19
20 #include <errno.h>
21 #include <limits.h>
22 #include <pthread.h>
23 #include <stdarg.h>
24 #include <string.h>
25 #include <sys/ioctl.h>
26 #include <sys/mman.h>
27 #include <sys/stat.h>
28 #include <sys/types.h>
29 #include <unistd.h>
30
31 #include <cutils/atomic.h>
32 #include <log/log.h>
33 #include <utils/Trace.h>
34
35 #include <hardware/hardware.h>
36 #include <hardware/gralloc.h>
37
38 #include <gralloc1-adapter.h>
39
40 #include "gralloc_priv.h"
41 #include "gr.h"
42 #include "alloc_controller.h"
43 #include "memalloc.h"
44 #include <qdMetaData.h>
45
46 using namespace gralloc;
47 /*****************************************************************************/
48
49 // Return the type of allocator -
50 // these are used for mapping/unmapping
getAllocator(int flags)51 static IMemAlloc* getAllocator(int flags)
52 {
53 IMemAlloc* memalloc;
54 IAllocController* alloc_ctrl = IAllocController::getInstance();
55 memalloc = alloc_ctrl->getAllocator(flags);
56 return memalloc;
57 }
58
gralloc_map_metadata(buffer_handle_t handle)59 static int gralloc_map_metadata(buffer_handle_t handle) {
60 private_handle_t* hnd = (private_handle_t*)handle;
61 hnd->base_metadata = 0;
62 IMemAlloc* memalloc = getAllocator(hnd->flags) ;
63 void *mappedAddress = MAP_FAILED;
64 unsigned int size = 0;
65 if (!(hnd->flags & private_handle_t::PRIV_FLAGS_FRAMEBUFFER)) {
66 mappedAddress = MAP_FAILED;
67 size = ROUND_UP_PAGESIZE(sizeof(MetaData_t));
68 int ret = memalloc->map_buffer(&mappedAddress, size,
69 hnd->offset_metadata, hnd->fd_metadata);
70 if(ret || mappedAddress == MAP_FAILED) {
71 ALOGE("Could not mmap metadata for handle %p, fd=%d (%s)",
72 hnd, hnd->fd_metadata, strerror(errno));
73 return -errno;
74 }
75 hnd->base_metadata = uint64_t(mappedAddress);
76 }
77 return 0;
78 }
79
gralloc_map(gralloc_module_t const * module,buffer_handle_t handle)80 static int gralloc_map(gralloc_module_t const* module,
81 buffer_handle_t handle)
82 {
83 ATRACE_CALL();
84 if(!module)
85 return -EINVAL;
86
87 private_handle_t* hnd = (private_handle_t*)handle;
88 unsigned int size = 0;
89 int err = 0;
90 IMemAlloc* memalloc = getAllocator(hnd->flags) ;
91 void *mappedAddress = MAP_FAILED;
92 hnd->base = 0;
93
94 // Dont map framebuffer and secure buffers
95 if (!(hnd->flags & private_handle_t::PRIV_FLAGS_FRAMEBUFFER) &&
96 !(hnd->flags & private_handle_t::PRIV_FLAGS_SECURE_BUFFER)) {
97 size = hnd->size;
98 err = memalloc->map_buffer(&mappedAddress, size,
99 hnd->offset, hnd->fd);
100 if(err || mappedAddress == MAP_FAILED) {
101 ALOGE("Could not mmap handle %p, fd=%d (%s)",
102 handle, hnd->fd, strerror(errno));
103 return -errno;
104 }
105
106 hnd->base = uint64_t(mappedAddress);
107 } else {
108 // Cannot map secure buffers or framebuffers, but still need to map
109 // metadata for secure buffers.
110 // If mapping a secure buffers fails, the framework needs to get
111 // an error code.
112 err = -EACCES;
113 }
114
115 //Allow mapping of metadata for all buffers including secure ones, but not
116 //of framebuffer
117 int metadata_err = gralloc_map_metadata(handle);
118 if (!err) {
119 err = metadata_err;
120 }
121 return err;
122 }
123
gralloc_unmap(gralloc_module_t const * module,buffer_handle_t handle)124 static int gralloc_unmap(gralloc_module_t const* module,
125 buffer_handle_t handle)
126 {
127 ATRACE_CALL();
128 int err = -EINVAL;
129 if(!module)
130 return err;
131
132 private_handle_t* hnd = (private_handle_t*)handle;
133 IMemAlloc* memalloc = getAllocator(hnd->flags) ;
134 if(!memalloc)
135 return err;
136
137 if(hnd->base) {
138 err = memalloc->unmap_buffer((void*)hnd->base, hnd->size, hnd->offset);
139 if (err) {
140 ALOGE("Could not unmap memory at address %p, %s", (void*) hnd->base,
141 strerror(errno));
142 return -errno;
143 }
144 hnd->base = 0;
145 }
146
147 if(hnd->base_metadata) {
148 unsigned int size = ROUND_UP_PAGESIZE(sizeof(MetaData_t));
149 err = memalloc->unmap_buffer((void*)hnd->base_metadata,
150 size, hnd->offset_metadata);
151 if (err) {
152 ALOGE("Could not unmap memory at address %p, %s",
153 (void*) hnd->base_metadata, strerror(errno));
154 return -errno;
155 }
156 hnd->base_metadata = 0;
157 }
158
159 return 0;
160 }
161
162 /*****************************************************************************/
163
164 static pthread_mutex_t sMapLock = PTHREAD_MUTEX_INITIALIZER;
165
166 /*****************************************************************************/
167
gralloc_register_buffer(gralloc_module_t const * module,buffer_handle_t handle)168 int gralloc_register_buffer(gralloc_module_t const* module,
169 buffer_handle_t handle)
170 {
171 ATRACE_CALL();
172 if (!module || private_handle_t::validate(handle) < 0)
173 return -EINVAL;
174
175 int err = gralloc_map(module, handle);
176 /* Do not fail register_buffer for secure buffers*/
177 if (err == -EACCES)
178 err = 0;
179 return err;
180 }
181
gralloc_unregister_buffer(gralloc_module_t const * module,buffer_handle_t handle)182 int gralloc_unregister_buffer(gralloc_module_t const* module,
183 buffer_handle_t handle)
184 {
185 ATRACE_CALL();
186 if (!module || private_handle_t::validate(handle) < 0)
187 return -EINVAL;
188
189 /*
190 * If the buffer has been mapped during a lock operation, it's time
191 * to un-map it. It's an error to be here with a locked buffer.
192 * NOTE: the framebuffer is handled differently and is never unmapped.
193 * Also base and base_metadata are reset.
194 */
195 return gralloc_unmap(module, handle);
196 }
197
terminateBuffer(gralloc_module_t const * module,private_handle_t * hnd)198 int terminateBuffer(gralloc_module_t const* module,
199 private_handle_t* hnd)
200 {
201 ATRACE_CALL();
202 if(!module)
203 return -EINVAL;
204
205 /*
206 * If the buffer has been mapped during a lock operation, it's time
207 * to un-map it. It's an error to be here with a locked buffer.
208 * NOTE: the framebuffer is handled differently and is never unmapped.
209 * Also base and base_metadata are reset.
210 */
211 return gralloc_unmap(module, hnd);
212 }
213
gralloc_map_and_invalidate(gralloc_module_t const * module,buffer_handle_t handle,int usage)214 static int gralloc_map_and_invalidate (gralloc_module_t const* module,
215 buffer_handle_t handle, int usage)
216 {
217 ATRACE_CALL();
218 if (!module || private_handle_t::validate(handle) < 0)
219 return -EINVAL;
220
221 int err = 0;
222 private_handle_t* hnd = (private_handle_t*)handle;
223 if (usage & (GRALLOC_USAGE_SW_READ_MASK | GRALLOC_USAGE_SW_WRITE_MASK)) {
224 if (hnd->base == 0) {
225 // we need to map for real
226 pthread_mutex_t* const lock = &sMapLock;
227 pthread_mutex_lock(lock);
228 err = gralloc_map(module, handle);
229 pthread_mutex_unlock(lock);
230 }
231 if (hnd->flags & private_handle_t::PRIV_FLAGS_USES_ION and
232 hnd->flags & private_handle_t::PRIV_FLAGS_CACHED) {
233 //Invalidate if CPU reads in software and there are non-CPU
234 //writers. No need to do this for the metadata buffer as it is
235 //only read/written in software.
236 if ((usage & GRALLOC_USAGE_SW_READ_MASK) and
237 (hnd->flags & private_handle_t::PRIV_FLAGS_NON_CPU_WRITER))
238 {
239 IMemAlloc* memalloc = getAllocator(hnd->flags) ;
240 err = memalloc->clean_buffer((void*)hnd->base,
241 hnd->size, hnd->offset, hnd->fd,
242 CACHE_INVALIDATE);
243 }
244 //Mark the buffer to be flushed after CPU write.
245 if (usage & GRALLOC_USAGE_SW_WRITE_MASK) {
246 hnd->flags |= private_handle_t::PRIV_FLAGS_NEEDS_FLUSH;
247 }
248 }
249 }
250
251 return err;
252 }
253
gralloc_lock(gralloc_module_t const * module,buffer_handle_t handle,int usage,int,int,int,int,void ** vaddr)254 int gralloc_lock(gralloc_module_t const* module,
255 buffer_handle_t handle, int usage,
256 int /*l*/, int /*t*/, int /*w*/, int /*h*/,
257 void** vaddr)
258 {
259 ATRACE_CALL();
260 private_handle_t* hnd = (private_handle_t*)handle;
261 int err = gralloc_map_and_invalidate(module, handle, usage);
262 if(!err)
263 *vaddr = (void*)hnd->base;
264 return err;
265 }
266
gralloc_lock_ycbcr(gralloc_module_t const * module,buffer_handle_t handle,int usage,int,int,int,int,struct android_ycbcr * ycbcr)267 int gralloc_lock_ycbcr(gralloc_module_t const* module,
268 buffer_handle_t handle, int usage,
269 int /*l*/, int /*t*/, int /*w*/, int /*h*/,
270 struct android_ycbcr *ycbcr)
271 {
272 ATRACE_CALL();
273 private_handle_t* hnd = (private_handle_t*)handle;
274 int err = gralloc_map_and_invalidate(module, handle, usage);
275 if(!err)
276 err = getYUVPlaneInfo(hnd, ycbcr);
277 return err;
278 }
279
gralloc_unlock(gralloc_module_t const * module,buffer_handle_t handle)280 int gralloc_unlock(gralloc_module_t const* module,
281 buffer_handle_t handle)
282 {
283 ATRACE_CALL();
284 if (!module || private_handle_t::validate(handle) < 0)
285 return -EINVAL;
286
287 int err = 0;
288 private_handle_t* hnd = (private_handle_t*)handle;
289
290 IMemAlloc* memalloc = getAllocator(hnd->flags);
291 if (hnd->flags & private_handle_t::PRIV_FLAGS_NEEDS_FLUSH) {
292 err = memalloc->clean_buffer((void*)hnd->base,
293 hnd->size, hnd->offset, hnd->fd,
294 CACHE_CLEAN);
295 hnd->flags &= ~private_handle_t::PRIV_FLAGS_NEEDS_FLUSH;
296 }
297
298 return err;
299 }
300
301 /*****************************************************************************/
302
isYUV(private_handle_t * hnd)303 static bool isYUV(private_handle_t* hnd)
304 {
305 bool is_yuv;
306
307 switch (hnd->format) {
308 //Semiplanar
309 case HAL_PIXEL_FORMAT_YCbCr_420_SP:
310 case HAL_PIXEL_FORMAT_YCbCr_422_SP:
311 case HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS:
312 case HAL_PIXEL_FORMAT_NV12_ENCODEABLE: //Same as YCbCr_420_SP_VENUS
313 case HAL_PIXEL_FORMAT_YCrCb_420_SP:
314 case HAL_PIXEL_FORMAT_YCrCb_422_SP:
315 case HAL_PIXEL_FORMAT_YCrCb_420_SP_ADRENO:
316 case HAL_PIXEL_FORMAT_NV21_ZSL:
317 case HAL_PIXEL_FORMAT_RAW10:
318 case HAL_PIXEL_FORMAT_RAW16:
319 //Planar
320 case HAL_PIXEL_FORMAT_YV12:
321 is_yuv = true;
322 break;
323 //Unsupported formats
324 case HAL_PIXEL_FORMAT_YCbCr_422_I:
325 case HAL_PIXEL_FORMAT_YCrCb_422_I:
326 case HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED:
327 default:
328 is_yuv = false;
329 break;
330 }
331
332 return is_yuv;
333 }
334
ycbcr_to_flexible_layout(const struct android_ycbcr * ycbcr,struct android_flex_layout * layout)335 static void ycbcr_to_flexible_layout(const struct android_ycbcr* ycbcr,
336 struct android_flex_layout* layout)
337 {
338 layout->format = FLEX_FORMAT_YCbCr;
339 layout->num_planes = 3;
340
341 for (uint32_t i = 0; i < layout->num_planes; i++) {
342 layout->planes[i].bits_per_component = 8;
343 layout->planes[i].bits_used = 8;
344 layout->planes[i].h_increment = 1;
345 layout->planes[i].v_increment = 1;
346 layout->planes[i].h_subsampling = 2;
347 layout->planes[i].v_subsampling = 2;
348 }
349
350 layout->planes[0].top_left = (uint8_t*)ycbcr->y;
351 layout->planes[0].component = FLEX_COMPONENT_Y;
352 layout->planes[0].v_increment = (int32_t)ycbcr->ystride;
353
354 layout->planes[1].top_left = (uint8_t*)ycbcr->cb;
355 layout->planes[1].component = FLEX_COMPONENT_Cb;
356 layout->planes[1].h_increment = (int32_t)ycbcr->chroma_step;
357 layout->planes[1].v_increment = (int32_t)ycbcr->cstride;
358
359 layout->planes[2].top_left = (uint8_t*)ycbcr->cr;
360 layout->planes[2].component = FLEX_COMPONENT_Cr;
361 layout->planes[2].h_increment = (int32_t)ycbcr->chroma_step;
362 layout->planes[2].v_increment = (int32_t)ycbcr->cstride;
363 }
364
gralloc_perform(struct gralloc_module_t const * module,int operation,...)365 int gralloc_perform(struct gralloc_module_t const* module,
366 int operation, ... )
367 {
368 int res = -EINVAL;
369 va_list args;
370 if(!module)
371 return res;
372
373 va_start(args, operation);
374 switch (operation) {
375 case GRALLOC_MODULE_PERFORM_CREATE_HANDLE_FROM_BUFFER:
376 {
377 int fd = va_arg(args, int);
378 unsigned int size = va_arg(args, unsigned int);
379 unsigned int offset = va_arg(args, unsigned int);
380 void* base = va_arg(args, void*);
381 int width = va_arg(args, int);
382 int height = va_arg(args, int);
383 int format = va_arg(args, int);
384
385 native_handle_t** handle = va_arg(args, native_handle_t**);
386 private_handle_t* hnd = (private_handle_t*)native_handle_create(
387 private_handle_t::sNumFds, private_handle_t::sNumInts());
388 if (hnd) {
389 hnd->magic = private_handle_t::sMagic;
390 hnd->fd = fd;
391 hnd->flags = private_handle_t::PRIV_FLAGS_USES_ION;
392 hnd->size = size;
393 hnd->offset = offset;
394 hnd->base = uint64_t(base) + offset;
395 hnd->gpuaddr = 0;
396 hnd->width = width;
397 hnd->height = height;
398 hnd->format = format;
399 *handle = (native_handle_t *)hnd;
400 res = 0;
401 }
402 break;
403
404 }
405 case GRALLOC_MODULE_PERFORM_GET_STRIDE:
406 {
407 int width = va_arg(args, int);
408 int format = va_arg(args, int);
409 int *stride = va_arg(args, int *);
410 int alignedw = 0, alignedh = 0;
411 AdrenoMemInfo::getInstance().getAlignedWidthAndHeight(width,
412 0, format, 0, alignedw, alignedh);
413 *stride = alignedw;
414 res = 0;
415 } break;
416
417 case GRALLOC_MODULE_PERFORM_GET_CUSTOM_STRIDE_FROM_HANDLE:
418 {
419 const private_handle_t* hnd = va_arg(args, private_handle_t*);
420 int *stride = va_arg(args, int *);
421 if (private_handle_t::validate(hnd)) {
422 return res;
423 }
424
425 int alignedw = 0, alignedh = 0;
426 AdrenoMemInfo::getInstance().getAlignedWidthAndHeight(hnd, alignedw, alignedh);
427 *stride = alignedw;
428
429 res = 0;
430 } break;
431
432 case GRALLOC_MODULE_PERFORM_GET_CUSTOM_STRIDE_AND_HEIGHT_FROM_HANDLE:
433 {
434 const private_handle_t* hnd = va_arg(args, private_handle_t*);
435 int *stride = va_arg(args, int *);
436 int *height = va_arg(args, int *);
437 if (private_handle_t::validate(hnd)) {
438 return res;
439 }
440
441 int alignedw = 0, alignedh = 0;
442 AdrenoMemInfo::getInstance().getAlignedWidthAndHeight(hnd, alignedw, alignedh);
443 *stride = alignedw;
444 *height = alignedh;
445
446 res = 0;
447 } break;
448
449 case GRALLOC_MODULE_PERFORM_GET_ATTRIBUTES:
450 {
451 int width = va_arg(args, int);
452 int height = va_arg(args, int);
453 int format = va_arg(args, int);
454 int usage = va_arg(args, int);
455 int *alignedWidth = va_arg(args, int *);
456 int *alignedHeight = va_arg(args, int *);
457 int *tileEnabled = va_arg(args,int *);
458 *tileEnabled = isUBwcEnabled(format, usage) ||
459 isMacroTileEnabled(format, usage);
460 AdrenoMemInfo::getInstance().getAlignedWidthAndHeight(width,
461 height, format, usage, *alignedWidth, *alignedHeight);
462 res = 0;
463 } break;
464
465 case GRALLOC_MODULE_PERFORM_GET_COLOR_SPACE_FROM_HANDLE:
466 {
467 private_handle_t* hnd = va_arg(args, private_handle_t*);
468 int *color_space = va_arg(args, int *);
469 if (private_handle_t::validate(hnd)) {
470 return res;
471 }
472 MetaData_t *metadata = (MetaData_t *)hnd->base_metadata;
473 if(metadata && metadata->operation & UPDATE_COLOR_SPACE) {
474 *color_space = metadata->colorSpace;
475 res = 0;
476 }
477 } break;
478
479 case GRALLOC_MODULE_PERFORM_GET_YUV_PLANE_INFO:
480 {
481 private_handle_t* hnd = va_arg(args, private_handle_t*);
482 android_ycbcr* ycbcr = va_arg(args, struct android_ycbcr *);
483 if (!private_handle_t::validate(hnd)) {
484 res = getYUVPlaneInfo(hnd, ycbcr);
485 }
486 } break;
487
488 case GRALLOC_MODULE_PERFORM_GET_MAP_SECURE_BUFFER_INFO:
489 {
490 private_handle_t* hnd = va_arg(args, private_handle_t*);
491 int *map_secure_buffer = va_arg(args, int *);
492 if (private_handle_t::validate(hnd)) {
493 return res;
494 }
495 MetaData_t *metadata = (MetaData_t *)hnd->base_metadata;
496 if(metadata && metadata->operation & MAP_SECURE_BUFFER) {
497 *map_secure_buffer = metadata->mapSecureBuffer;
498 res = 0;
499 } else {
500 *map_secure_buffer = 0;
501 }
502 } break;
503
504 case GRALLOC_MODULE_PERFORM_GET_UBWC_FLAG:
505 {
506 private_handle_t* hnd = va_arg(args, private_handle_t*);
507 int *flag = va_arg(args, int *);
508 if (private_handle_t::validate(hnd)) {
509 return res;
510 }
511 *flag = hnd->flags & private_handle_t::PRIV_FLAGS_UBWC_ALIGNED;
512 MetaData_t *metadata = (MetaData_t *)hnd->base_metadata;
513 if (metadata && (metadata->operation & LINEAR_FORMAT)) {
514 *flag = 0;
515 }
516 res = 0;
517 } break;
518
519 case GRALLOC_MODULE_PERFORM_GET_RGB_DATA_ADDRESS:
520 {
521 private_handle_t* hnd = va_arg(args, private_handle_t*);
522 void** rgb_data = va_arg(args, void**);
523 if (!private_handle_t::validate(hnd)) {
524 res = getRgbDataAddress(hnd, rgb_data);
525 }
526 } break;
527
528 case GRALLOC_MODULE_PERFORM_GET_IGC:
529 {
530 private_handle_t* hnd = va_arg(args, private_handle_t*);
531 uint32_t *igc = va_arg(args, uint32_t *);
532 if (!private_handle_t::validate(hnd) && igc) {
533 MetaData_t *metadata = (MetaData_t *)hnd->base_metadata;
534 if (metadata && (metadata->operation & SET_IGC)) {
535 *igc = metadata->igc;
536 res = 0;
537 }
538 }
539 } break;
540
541 case GRALLOC_MODULE_PERFORM_SET_IGC:
542 res = 0;
543 break;
544
545 case GRALLOC_MODULE_PERFORM_SET_SINGLE_BUFFER_MODE:
546 {
547 private_handle_t* hnd = va_arg(args, private_handle_t*);
548 uint32_t *enable = va_arg(args, uint32_t*);
549 if (!private_handle_t::validate(hnd)) {
550 setMetaData(hnd, SET_SINGLE_BUFFER_MODE, enable);
551 res = 0;
552 }
553 } break;
554
555 case GRALLOC1_ADAPTER_PERFORM_GET_REAL_MODULE_API_VERSION_MINOR:
556 {
557 auto outMinorVersion = va_arg(args, int*);
558 *outMinorVersion = 1; // GRALLOC_MODULE_API_VERSION_0_1
559 } break;
560
561 case GRALLOC1_ADAPTER_PERFORM_SET_USAGES:
562 {
563 auto hnd = va_arg(args, private_handle_t*);
564 auto producerUsage = va_arg(args, int);
565 auto consumerUsage = va_arg(args, int);
566 hnd->producer_usage = producerUsage;
567 hnd->consumer_usage = consumerUsage;
568 } break;
569
570 case GRALLOC1_ADAPTER_PERFORM_GET_DIMENSIONS:
571 {
572 auto hnd = va_arg(args, private_handle_t*);
573 auto outWidth = va_arg(args, int*);
574 auto outHeight = va_arg(args, int*);
575 *outWidth = hnd->original_width;
576 *outHeight = hnd->height;
577 } break;
578
579 case GRALLOC1_ADAPTER_PERFORM_GET_FORMAT:
580 {
581 auto hnd = va_arg(args, private_handle_t*);
582 auto outFormat = va_arg(args, int*);
583 *outFormat = hnd->original_format;
584 } break;
585
586 case GRALLOC1_ADAPTER_PERFORM_GET_PRODUCER_USAGE:
587 {
588 auto hnd = va_arg(args, private_handle_t*);
589 auto outUsage = va_arg(args, int*);
590 *outUsage = hnd->producer_usage;
591 } break;
592
593 case GRALLOC1_ADAPTER_PERFORM_GET_CONSUMER_USAGE:
594 {
595 auto hnd = va_arg(args, private_handle_t*);
596 auto outUsage = va_arg(args, int*);
597 *outUsage = hnd->consumer_usage;
598 } break;
599
600 case GRALLOC1_ADAPTER_PERFORM_GET_BACKING_STORE:
601 {
602 auto hnd = va_arg(args, private_handle_t*);
603 auto outBackingStore = va_arg(args, uint64_t*);
604 *outBackingStore = hnd->backing_store;
605 } break;
606
607 case GRALLOC1_ADAPTER_PERFORM_GET_NUM_FLEX_PLANES:
608 {
609 auto hnd = va_arg(args, private_handle_t*);
610 auto outNumFlexPlanes = va_arg(args, int*);
611
612 (void) hnd;
613 // for simpilicity
614 *outNumFlexPlanes = 4;
615 } break;
616
617 case GRALLOC1_ADAPTER_PERFORM_GET_STRIDE:
618 {
619 auto hnd = va_arg(args, private_handle_t*);
620 auto outStride = va_arg(args, int*);
621 *outStride = hnd->width;
622 } break;
623
624 case GRALLOC1_ADAPTER_PERFORM_LOCK_FLEX:
625 {
626 auto hnd = va_arg(args, private_handle_t*);
627 auto producerUsage = va_arg(args, int);
628 auto consumerUsage = va_arg(args, int);
629 auto left = va_arg(args, int);
630 auto top = va_arg(args, int);
631 auto width = va_arg(args, int);
632 auto height = va_arg(args, int);
633 auto outLayout = va_arg(args, android_flex_layout*);
634 // always -1
635 auto acquireFence = va_arg(args, int);
636 (void) acquireFence;
637
638 // TODO lock RGB as a flexible format
639 if (!isYUV(hnd)) {
640 return -EINVAL;
641 }
642
643 struct android_ycbcr ycbcr;
644 res = gralloc_lock_ycbcr(module, hnd,
645 producerUsage | consumerUsage,
646 left, top, width, height, &ycbcr);
647 if (res != 0) {
648 return res;
649 }
650
651 ycbcr_to_flexible_layout(&ycbcr, outLayout);
652 } break;
653
654 default:
655 break;
656 }
657 va_end(args);
658 return res;
659 }
660