1 /* 2 * Copyright (C) 2013 ARM Limited. All rights reserved. 3 * 4 * Copyright (C) 2008 The Android Open Source Project 5 * 6 * Licensed under the Apache License, Version 2.0 (the "License"); 7 * You may not use this file except in compliance with the License. 8 * You may obtain a copy of the License at 9 * 10 * http://www.apache.org/licenses/LICENSE-2.0 11 * 12 * Unless required by applicable law or agreed to in writing, software 13 * distributed under the License is distributed on an "AS IS" BASIS, 14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 * See the License for the specific language governing permissions and 16 * limitations under the License. 17 */ 18 19 #include <errno.h> 20 #include <pthread.h> 21 #include <string.h> 22 23 #include <cutils/log.h> 24 #include <cutils/atomic.h> 25 #include <hardware/hardware.h> 26 #include <hardware/gralloc.h> 27 28 #include "gralloc_priv.h" 29 #include "alloc_device.h" 30 #include "framebuffer_device.h" 31 #include "ion_4.12.h" 32 33 #include <linux/ion.h> 34 #include <ion/ion.h> 35 #include <sys/mman.h> 36 37 int gralloc_backend_register(private_handle_t* hnd) 38 { 39 int retval = -EINVAL; 40 41 switch (hnd->flags & private_handle_t::PRIV_FLAGS_USES_ION) 42 { 43 case private_handle_t::PRIV_FLAGS_USES_ION: 44 unsigned char *mappedAddress; 45 size_t size = hnd->size; 46 hw_module_t * pmodule = NULL; 47 private_module_t *m=NULL; 48 if (hw_get_module(GRALLOC_HARDWARE_MODULE_ID, (const hw_module_t **)&pmodule) == 0) 49 { 50 m = reinterpret_cast<private_module_t *>(pmodule); 51 } 52 else 53 { 54 AERR("Could not get gralloc module for handle: %p", hnd); 55 retval = -errno; 56 break; 57 } 58 /* the test condition is set to m->ion_client <= 0 here, because: 59 * 1) module structure are initialized to 0 if no initial value is applied 60 * 2) a second user process should get a ion fd greater than 0. 61 */ 62 if (m->ion_client <= 0) 63 { 64 /* a second user process must obtain a client handle first via ion_open before it can obtain the shared ion buffer*/ 65 m->ion_client = ion_open(); 66 67 if (m->ion_client < 0) 68 { 69 AERR( "Could not open ion device for handle: %p", hnd ); 70 retval = -errno; 71 break; 72 } 73 } 74 75 mappedAddress = (unsigned char*)mmap( NULL, size, PROT_READ | PROT_WRITE, 76 MAP_SHARED, hnd->share_fd, 0 ); 77 78 if ( MAP_FAILED == mappedAddress ) 79 { 80 AERR( "mmap( share_fd:%d ) failed with %s", hnd->share_fd, strerror( errno ) ); 81 retval = -errno; 82 break; 83 } 84 85 hnd->base = (void*)(uintptr_t(mappedAddress) + hnd->offset); 86 retval = 0; 87 break; 88 } 89 90 return retval; 91 } 92 93 void gralloc_backend_unregister(private_handle_t* hnd) 94 { 95 switch (hnd->flags & private_handle_t::PRIV_FLAGS_USES_ION) 96 { 97 case private_handle_t::PRIV_FLAGS_USES_ION: 98 void* base = (void*)hnd->base; 99 size_t size = hnd->size; 100 101 if ( munmap( base,size ) < 0 ) 102 { 103 AERR("Could not munmap base:%p size:%zd '%s'", base, size, strerror(errno)); 104 } 105 break; 106 } 107 } 108 109 void gralloc_backend_sync(private_handle_t* hnd) 110 { 111 switch (hnd->flags & private_handle_t::PRIV_FLAGS_USES_ION) 112 { 113 case private_handle_t::PRIV_FLAGS_USES_ION: 114 hw_module_t * pmodule = NULL; 115 if (hw_get_module(GRALLOC_HARDWARE_MODULE_ID, (const hw_module_t **)&pmodule) == 0) 116 { 117 private_module_t *m = reinterpret_cast<private_module_t *>(pmodule); 118 if (m->gralloc_legacy_ion) 119 { 120 if(!(hnd->flags & private_handle_t::PRIV_FLAGS_USES_ION_DMA_HEAP)) 121 { 122 ion_sync_fd(m->ion_client, hnd->share_fd); 123 } 124 } 125 } 126 else 127 { 128 AERR("Could not get gralloc module for handle %p\n", hnd); 129 } 130 break; 131 } 132 } 133