blob: 724cd47aab681a604f2007b75f4ad84eb840da7b [file] [log] [blame]
Chia-I Wu109571a2016-09-05 11:46:36 +08001/*
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 "Gralloc1Adapter"
18
19#include <stdatomic.h>
20#include <stdlib.h>
21#include <string.h>
22
23#include <pthread.h>
24
25#include <cutils/native_handle.h>
26#include <hardware/gralloc1.h>
27#include <sync/sync.h>
28#include <log/log.h>
29
30#include "gralloc1-adapter.h"
31
32struct gralloc1_adapter_module {
33 struct gralloc_module_t base;
34 struct gralloc1_adapter adapter;
35};
36
37struct gralloc1_adapter_device {
38 struct gralloc1_device base;
39
40 struct alloc_device_t* alloc_dev;
41
42 /* fixed size for thread safety */
43 char saved_dump[4096];
44 size_t saved_dump_size;
45};
46
47/* additional data associated with registered buffer_handle_t */
48struct gralloc1_adapter_buffer_data {
49 struct gralloc1_adapter_buffer_info info;
50
51 atomic_int refcount;
52 bool owned;
53};
54
55struct gralloc1_adapter_buffer_descriptor {
56 int width;
57 int height;
58 int format;
59 int producer_usage;
60 int consumer_usage;
61};
62
63static const struct gralloc1_adapter_module* gralloc1_adapter_module(
64 struct gralloc1_device* dev)
65{
66 return (const struct gralloc1_adapter_module*) dev->common.module;
67}
68
69static struct gralloc1_adapter_device* gralloc1_adapter_device(
70 struct gralloc1_device* dev)
71{
72 return (struct gralloc1_adapter_device*) dev;
73}
74
75static struct gralloc1_adapter_buffer_data* lookup_buffer_data(
76 struct gralloc1_device* dev, buffer_handle_t buffer)
77{
78 const struct gralloc1_adapter_module* mod = gralloc1_adapter_module(dev);
79 if (!mod->adapter.is_registered(&mod->base, buffer))
80 return NULL;
81
82 return mod->adapter.get_data(&mod->base, buffer);
83}
84
85static struct gralloc1_adapter_buffer_descriptor* lookup_buffer_descriptor(
86 struct gralloc1_device* dev, gralloc1_buffer_descriptor_t id)
87{
88 /* do we want to validate? */
89 return (struct gralloc1_adapter_buffer_descriptor*) ((uintptr_t) id);
90}
91
92static void device_dump(struct gralloc1_device* device,
93 uint32_t* outSize, char* outBuffer)
94{
95 struct gralloc1_adapter_device* dev = gralloc1_adapter_device(device);
96
97 if (outBuffer) {
98 uint32_t copy = (uint32_t) dev->saved_dump_size;
99 if (*outSize < copy) {
100 copy = *outSize;
101 } else {
102 *outSize = copy;
103 }
104
105 memcpy(outBuffer, dev->saved_dump, copy);
106 } else {
107 /* dump is optional and may not null-terminate */
108 if (dev->alloc_dev->dump) {
109 dev->alloc_dev->dump(dev->alloc_dev, dev->saved_dump,
110 sizeof(dev->saved_dump) - 1);
111 dev->saved_dump_size = strlen(dev->saved_dump);
112 }
113
114 *outSize = (uint32_t) dev->saved_dump_size;
115 }
116}
117
118static int32_t device_create_descriptor(struct gralloc1_device* device,
119 gralloc1_buffer_descriptor_t* outDescriptor)
120{
121 struct gralloc1_adapter_buffer_descriptor* desc;
122
123 desc = calloc(1, sizeof(*desc));
124 if (!desc) {
125 return GRALLOC1_ERROR_NO_RESOURCES;
126 }
127
128 *outDescriptor = (gralloc1_buffer_descriptor_t) (uintptr_t) desc;
129
130 return GRALLOC1_ERROR_NONE;
131}
132
133static int32_t device_destroy_descriptor(struct gralloc1_device* device,
134 gralloc1_buffer_descriptor_t descriptor)
135{
136 struct gralloc1_adapter_buffer_descriptor* desc =
137 lookup_buffer_descriptor(device, descriptor);
138 if (!desc) {
139 return GRALLOC1_ERROR_BAD_DESCRIPTOR;
140 }
141
142 free(desc);
143
144 return GRALLOC1_ERROR_NONE;
145}
146
147static int32_t device_set_consumer_usage(struct gralloc1_device* device,
148 gralloc1_buffer_descriptor_t descriptor, uint64_t usage)
149{
150 struct gralloc1_adapter_buffer_descriptor* desc =
151 lookup_buffer_descriptor(device, descriptor);
152 if (!desc) {
153 return GRALLOC1_ERROR_BAD_DESCRIPTOR;
154 }
155
156 desc->consumer_usage = (int) usage;
157
158 return GRALLOC1_ERROR_NONE;
159}
160
161static int32_t device_set_dimensions(struct gralloc1_device* device,
162 gralloc1_buffer_descriptor_t descriptor,
163 uint32_t width, uint32_t height)
164{
165 struct gralloc1_adapter_buffer_descriptor* desc =
166 lookup_buffer_descriptor(device, descriptor);
167 if (!desc) {
168 return GRALLOC1_ERROR_BAD_DESCRIPTOR;
169 }
170
171 desc->width = (int) width;
172 desc->height = (int) height;
173
174 return GRALLOC1_ERROR_NONE;
175}
176
177static int32_t device_set_format(struct gralloc1_device* device,
178 gralloc1_buffer_descriptor_t descriptor, int32_t format)
179{
180 struct gralloc1_adapter_buffer_descriptor* desc =
181 lookup_buffer_descriptor(device, descriptor);
182 if (!desc) {
183 return GRALLOC1_ERROR_BAD_DESCRIPTOR;
184 }
185
186 desc->format = format;
187
188 return GRALLOC1_ERROR_NONE;
189}
190
191static int32_t device_set_producer_usage(struct gralloc1_device* device,
192 gralloc1_buffer_descriptor_t descriptor, uint64_t usage)
193{
194 struct gralloc1_adapter_buffer_descriptor* desc =
195 lookup_buffer_descriptor(device, descriptor);
196 if (!desc) {
197 return GRALLOC1_ERROR_BAD_DESCRIPTOR;
198 }
199
200 desc->producer_usage = (int) usage;
201
202 return GRALLOC1_ERROR_NONE;
203}
204
205static int32_t device_get_backing_store(struct gralloc1_device* device,
206 buffer_handle_t buffer, gralloc1_backing_store_t* outStore)
207{
208 /* we never share backing store */
209 *outStore = (gralloc1_backing_store_t) (uintptr_t) buffer;
210
211 return GRALLOC1_ERROR_NONE;
212}
213
214static int32_t device_get_consumer_usage(struct gralloc1_device* device,
215 buffer_handle_t buffer, uint64_t* outUsage)
216{
217 const struct gralloc1_adapter_buffer_data* data =
218 lookup_buffer_data(device, buffer);
219 if (!data) {
220 return GRALLOC1_ERROR_BAD_HANDLE;
221 }
222
223 *outUsage = data->info.usage;
224
225 return GRALLOC1_ERROR_NONE;
226}
227
228static int32_t device_get_dimensions(struct gralloc1_device* device,
229 buffer_handle_t buffer, uint32_t* outWidth, uint32_t* outHeight)
230{
231 const struct gralloc1_adapter_buffer_data* data =
232 lookup_buffer_data(device, buffer);
233 if (!data) {
234 return GRALLOC1_ERROR_BAD_HANDLE;
235 }
236
237 *outWidth = data->info.width;
238 *outHeight = data->info.height;
239
240 return GRALLOC1_ERROR_NONE;
241}
242
243static int32_t device_get_format(struct gralloc1_device* device,
244 buffer_handle_t buffer, int32_t* outFormat)
245{
246 const struct gralloc1_adapter_buffer_data* data =
247 lookup_buffer_data(device, buffer);
248 if (!data) {
249 return GRALLOC1_ERROR_BAD_HANDLE;
250 }
251
252 *outFormat = data->info.format;
253
254 return GRALLOC1_ERROR_NONE;
255}
256
257static int32_t device_get_producer_usage(struct gralloc1_device* device,
258 buffer_handle_t buffer, uint64_t* outUsage)
259{
260 const struct gralloc1_adapter_buffer_data* data =
261 lookup_buffer_data(device, buffer);
262 if (!data) {
263 return GRALLOC1_ERROR_BAD_HANDLE;
264 }
265
266 *outUsage = data->info.usage;
267
268 return GRALLOC1_ERROR_NONE;
269}
270
271static int32_t device_get_stride(struct gralloc1_device* device,
272 buffer_handle_t buffer, uint32_t* outStride)
273{
274 const struct gralloc1_adapter_buffer_data* data =
275 lookup_buffer_data(device, buffer);
276 if (!data) {
277 return GRALLOC1_ERROR_BAD_HANDLE;
278 }
279
280 *outStride = data->info.stride;
281
282 return GRALLOC1_ERROR_NONE;
283}
284
285static int32_t device_allocate(struct gralloc1_device* device,
286 uint32_t numDescriptors,
287 const gralloc1_buffer_descriptor_t* descriptors,
288 buffer_handle_t* outBuffers)
289{
290 const struct gralloc1_adapter_module* mod =
291 gralloc1_adapter_module(device);
292 struct gralloc1_adapter_device* dev = gralloc1_adapter_device(device);
293 gralloc1_error_t err = GRALLOC1_ERROR_NONE;
294 uint32_t i;
295
296 for (i = 0; i < numDescriptors; i++) {
297 const struct gralloc1_adapter_buffer_descriptor* desc =
298 lookup_buffer_descriptor(device, descriptors[i]);
299 struct gralloc1_adapter_buffer_data* data;
300 buffer_handle_t buffer;
301 int dummy_stride;
302 int ret;
303
304 if (!desc) {
305 err = GRALLOC1_ERROR_BAD_DESCRIPTOR;
306 break;
307 }
308
309 data = calloc(1, sizeof(*data));
310 if (!data) {
311 err = GRALLOC1_ERROR_NO_RESOURCES;
312 break;
313 }
314
315 ret = dev->alloc_dev->alloc(dev->alloc_dev, desc->width, desc->height,
316 desc->format, desc->producer_usage | desc->consumer_usage,
317 &buffer, &dummy_stride);
318 if (ret) {
319 free(data);
320 err = GRALLOC1_ERROR_NO_RESOURCES;
321 break;
322 }
323
324 mod->adapter.get_info(&mod->base, buffer, &data->info);
325 data->refcount = 1;
326 data->owned = true;
327
328 mod->adapter.set_data(&mod->base, buffer, data);
329
330 outBuffers[i] = buffer;
331 }
332
333 if (err != GRALLOC1_ERROR_NONE) {
334 uint32_t j;
335 for (j = 0; j < i; j++) {
336 free(mod->adapter.get_data(&mod->base, outBuffers[i]));
337 dev->alloc_dev->free(dev->alloc_dev, outBuffers[i]);
338 }
339
340 return err;
341 }
342
343 return (numDescriptors > 1) ?
344 GRALLOC1_ERROR_NOT_SHARED : GRALLOC1_ERROR_NONE;
345}
346
347static int32_t device_retain(struct gralloc1_device* device,
348 buffer_handle_t buffer)
349{
350 static pthread_mutex_t register_mutex = PTHREAD_MUTEX_INITIALIZER;
351 const struct gralloc1_adapter_module* mod =
352 gralloc1_adapter_module(device);
353 struct gralloc1_adapter_buffer_data* data;
354
355 pthread_mutex_lock(&register_mutex);
356
357 if (mod->adapter.is_registered(&mod->base, buffer)) {
358 data = mod->adapter.get_data(&mod->base, buffer);
359 data->refcount++;
360 } else {
361 int ret;
362
363 data = calloc(1, sizeof(*data));
364 if (!data) {
365 pthread_mutex_unlock(&register_mutex);
366 return GRALLOC1_ERROR_NO_RESOURCES;
367 }
368
369 ret = mod->base.registerBuffer(&mod->base, buffer);
370 if (ret) {
371 pthread_mutex_unlock(&register_mutex);
372 free(data);
373
374 return GRALLOC1_ERROR_NO_RESOURCES;
375 }
376
377 mod->adapter.get_info(&mod->base, buffer, &data->info);
378 data->refcount = 1;
379 data->owned = false;
380
381 mod->adapter.set_data(&mod->base, buffer, data);
382 }
383
384 pthread_mutex_unlock(&register_mutex);
385
386 return GRALLOC1_ERROR_NONE;
387}
388
389static int32_t device_release(struct gralloc1_device* device,
390 buffer_handle_t buffer)
391{
392 struct gralloc1_adapter_buffer_data* data =
393 lookup_buffer_data(device, buffer);
394 if (!data) {
395 ALOGE("unable to release unregistered buffer %p", buffer);
396 return GRALLOC1_ERROR_BAD_HANDLE;
397 }
398
399 data->refcount--;
400 if (!data->refcount) {
401 if (data->owned) {
402 struct gralloc1_adapter_device* dev =
403 gralloc1_adapter_device(device);
404 dev->alloc_dev->free(dev->alloc_dev, buffer);
405 } else {
406 const struct gralloc1_adapter_module* mod =
407 gralloc1_adapter_module(device);
408 mod->base.unregisterBuffer(&mod->base, buffer);
409
410 native_handle_close(buffer);
411 native_handle_delete((native_handle_t*) buffer);
412 }
413
414 free(data);
415 }
416
417 return GRALLOC1_ERROR_NONE;
418}
419
420static int32_t device_get_num_flex_planes(struct gralloc1_device* device,
421 buffer_handle_t buffer, uint32_t* outNumPlanes)
422{
423 const struct gralloc1_adapter_buffer_data* data =
424 lookup_buffer_data(device, buffer);
425 if (!data) {
426 return GRALLOC1_ERROR_BAD_HANDLE;
427 }
428
429 *outNumPlanes = data->info.num_flex_planes;
430
431 return GRALLOC1_ERROR_NONE;
432}
433
434static int32_t device_lock(struct gralloc1_device* device,
435 buffer_handle_t buffer,
436 uint64_t producerUsage, uint64_t consumerUsage,
437 const gralloc1_rect_t* accessRegion, void** outData,
438 int32_t acquireFence)
439{
440 const struct gralloc1_adapter_module* mod =
441 gralloc1_adapter_module(device);
442 const int usage = (int) (producerUsage | consumerUsage);
443 const struct gralloc1_adapter_buffer_data* data =
444 lookup_buffer_data(device, buffer);
445 int ret;
446
447 if (!data) {
448 ALOGE("unable to lock unregistered buffer %p", buffer);
449 return GRALLOC1_ERROR_BAD_HANDLE;
450 }
451
452 if (mod->adapter.real_module_api_version >=
453 GRALLOC_MODULE_API_VERSION_0_3) {
454 ret = mod->base.lockAsync(&mod->base,
455 buffer, usage,
456 accessRegion->left,
457 accessRegion->top,
458 accessRegion->width,
459 accessRegion->height,
460 outData, acquireFence);
461 } else {
462 if (acquireFence >= 0) {
463 sync_wait(acquireFence, -1);
464 }
465
466 ret = mod->base.lock(&mod->base,
467 buffer, usage,
468 accessRegion->left,
469 accessRegion->top,
470 accessRegion->width,
471 accessRegion->height,
472 outData);
473
474 if (acquireFence >= 0 && !ret) {
475 close(acquireFence);
476 }
477 }
478
479 return (ret) ? GRALLOC1_ERROR_NO_RESOURCES : GRALLOC1_ERROR_NONE;
480}
481
482static int32_t device_lock_flex(struct gralloc1_device* device,
483 buffer_handle_t buffer,
484 uint64_t producerUsage, uint64_t consumerUsage,
485 const gralloc1_rect_t* accessRegion,
486 struct android_flex_layout* outFlexLayout,
487 int32_t acquireFence)
488{
489 const struct gralloc1_adapter_module* mod =
490 gralloc1_adapter_module(device);
491 const int usage = (int) (producerUsage | consumerUsage);
492 const struct gralloc1_adapter_buffer_data* data =
493 lookup_buffer_data(device, buffer);
494 struct android_ycbcr ycbcr;
495 int ret;
496
497 if (!data) {
498 ALOGE("unable to lockFlex unregistered buffer %p", buffer);
499 return GRALLOC1_ERROR_BAD_HANDLE;
500 }
501
502 if (outFlexLayout->num_planes < data->info.num_flex_planes) {
503 return GRALLOC1_ERROR_BAD_VALUE;
504 }
505
506 if (mod->adapter.real_module_api_version >=
507 GRALLOC_MODULE_API_VERSION_0_3 && mod->base.lockAsync_ycbcr) {
508 ret = mod->base.lockAsync_ycbcr(&mod->base,
509 buffer, usage,
510 accessRegion->left,
511 accessRegion->top,
512 accessRegion->width,
513 accessRegion->height,
514 &ycbcr, acquireFence);
515 } else if (mod->base.lock_ycbcr) {
516 if (acquireFence >= 0) {
517 sync_wait(acquireFence, -1);
518 }
519
520 ret = mod->base.lock_ycbcr(&mod->base,
521 buffer, usage,
522 accessRegion->left,
523 accessRegion->top,
524 accessRegion->width,
525 accessRegion->height,
526 &ycbcr);
527
528 if (acquireFence >= 0 && !ret) {
529 close(acquireFence);
530 }
531 } else {
532 return GRALLOC1_ERROR_UNSUPPORTED;
533 }
534
535 if (ret) {
536 return GRALLOC1_ERROR_NO_RESOURCES;
537 }
538
539 mod->adapter.get_flexible_layout(&mod->base, buffer,
540 &ycbcr, outFlexLayout);
541
542 return GRALLOC1_ERROR_NONE;
543}
544
545static int32_t device_unlock(struct gralloc1_device* device,
546 buffer_handle_t buffer, int32_t* outReleaseFence)
547{
548 const struct gralloc1_adapter_module* mod =
549 gralloc1_adapter_module(device);
550 int ret;
551
552 if (mod->adapter.real_module_api_version >=
553 GRALLOC_MODULE_API_VERSION_0_3) {
554 ret = mod->base.unlockAsync(&mod->base, buffer, outReleaseFence);
555 } else {
556 ret = mod->base.unlock(&mod->base, buffer);
557 if (!ret) {
558 *outReleaseFence = -1;
559 }
560 }
561
562 return (ret) ? GRALLOC1_ERROR_BAD_HANDLE : GRALLOC1_ERROR_NONE;
563}
564
565static gralloc1_function_pointer_t device_get_function(
566 struct gralloc1_device* device, int32_t descriptor)
567{
568 switch ((gralloc1_function_descriptor_t) descriptor) {
569#define CASE(id, ptr) \
570 case GRALLOC1_FUNCTION_ ## id: \
571 return (gralloc1_function_pointer_t) device_ ## ptr
572 CASE(DUMP, dump);
573 CASE(CREATE_DESCRIPTOR, create_descriptor);
574 CASE(DESTROY_DESCRIPTOR, destroy_descriptor);
575 CASE(SET_CONSUMER_USAGE, set_consumer_usage);
576 CASE(SET_DIMENSIONS, set_dimensions);
577 CASE(SET_FORMAT, set_format);
578 CASE(SET_PRODUCER_USAGE, set_producer_usage);
579 CASE(GET_BACKING_STORE, get_backing_store);
580 CASE(GET_CONSUMER_USAGE, get_consumer_usage);
581 CASE(GET_DIMENSIONS, get_dimensions);
582 CASE(GET_FORMAT, get_format);
583 CASE(GET_PRODUCER_USAGE, get_producer_usage);
584 CASE(GET_STRIDE, get_stride);
585 CASE(ALLOCATE, allocate);
586 CASE(RETAIN, retain);
587 CASE(RELEASE, release);
588 CASE(GET_NUM_FLEX_PLANES, get_num_flex_planes);
589 CASE(LOCK, lock);
590 CASE(LOCK_FLEX, lock_flex);
591 CASE(UNLOCK, unlock);
592#undef CASE
593 default: return NULL;
594 }
595}
596
597static void device_get_capabilities(struct gralloc1_device* device,
598 uint32_t* outCount, int32_t* outCapabilities)
599{
600 *outCount = 0;
601}
602
603static int device_close(struct hw_device_t* device)
604{
605 struct gralloc1_adapter_device* dev =
606 (struct gralloc1_adapter_device*) device;
607 int ret;
608
609 ret = dev->alloc_dev->common.close(&dev->alloc_dev->common);
610 if (!ret) {
611 free(dev);
612 }
613
614 return ret;
615}
616
617int gralloc1_adapter_device_open(const struct hw_module_t* module,
618 const char* id, struct hw_device_t** device)
619{
620 const struct gralloc1_adapter_module* mod =
621 (const struct gralloc1_adapter_module*) module;
622 struct alloc_device_t* alloc_dev;
623 struct gralloc1_adapter_device* dev;
624 int ret;
625
626 if (strcmp(id, GRALLOC_HARDWARE_MODULE_ID) != 0) {
627 ALOGE("unknown gralloc1 device id: %s", id);
628 return -EINVAL;
629 }
630
631 ret = module->methods->open(module, GRALLOC_HARDWARE_GPU0,
632 (struct hw_device_t**) &alloc_dev);
633 if (ret) {
634 return ret;
635 }
636
637 dev = malloc(sizeof(*dev));
638 if (!dev) {
639 alloc_dev->common.close(&alloc_dev->common);
640 return -ENOMEM;
641 }
642
643 *dev = (struct gralloc1_adapter_device) {
644 .base = {
645 .common = {
646 .tag = HARDWARE_DEVICE_TAG,
647 .version = HARDWARE_DEVICE_API_VERSION(0, 0),
648 .module = (struct hw_module_t*) mod,
649 .close = device_close,
650 },
651 .getCapabilities = device_get_capabilities,
652 .getFunction = device_get_function,
653 },
654 .alloc_dev = alloc_dev,
655 };
656
657 *device = (struct hw_device_t*) dev;
658
659 return 0;
660}