/* * Initialize the shared memory region for hybris, in order to store * pshared mutex, condition and rwlock */ static void _hybris_shm_init() { if (_hybris_shm_fd < 0) { const size_t size_to_map = HYBRIS_SHM_DATA_HEADER_SIZE + HYBRIS_DATA_SIZE; /* 4000 bytes for the data, plus the header size */ /* initialize or get shared memory segment */ _hybris_shm_fd = shm_open(HYBRIS_SHM_PATH, O_RDWR, 0660); if (_hybris_shm_fd >= 0) { /* Map the memory object */ _hybris_shm_data = (hybris_shm_data_t *)mmap( NULL, size_to_map, PROT_READ | PROT_WRITE, MAP_SHARED, _hybris_shm_fd, 0 ); _current_mapped_size = size_to_map; _sync_mmap_with_shm(); } else { LOGD("Creating a new shared memory segment."); mode_t pumask = umask(0); _hybris_shm_fd = shm_open(HYBRIS_SHM_PATH, O_RDWR | O_CREAT, 0666); umask(pumask); if (_hybris_shm_fd >= 0) { ftruncate( _hybris_shm_fd, size_to_map ); /* Map the memory object */ _hybris_shm_data = (hybris_shm_data_t *)mmap( NULL, size_to_map, PROT_READ | PROT_WRITE, MAP_SHARED, _hybris_shm_fd, 0 ); if (_hybris_shm_data == MAP_FAILED) { HYBRIS_ERROR_LOG(HOOKS, "ERROR: mmap failed: %s\n", strerror(errno)); _release_shm(); } else { _current_mapped_size = size_to_map; /* Initialize the memory object */ memset((void*)_hybris_shm_data, 0, size_to_map); _hybris_shm_data->max_offset = HYBRIS_DATA_SIZE; pthread_mutexattr_t attr; pthread_mutexattr_init(&attr); pthread_mutexattr_setpshared(&attr, PTHREAD_PROCESS_SHARED); pthread_mutex_init(&_hybris_shm_data->access_mutex, &attr); pthread_mutexattr_destroy(&attr); atexit(_release_shm); } } else { HYBRIS_ERROR_LOG(HOOKS, "ERROR: Couldn't create shared memory segment !"); } } } }
static void server_wlegl_get_server_buffer_handle(wl_client *client, wl_resource *res, uint32_t id, int32_t width, int32_t height, int32_t format, int32_t usage) { if (width == 0 || height == 0) { wl_resource_post_error(res, 0, "invalid buffer size: %u,%u\n", width, height); return; } server_wlegl *wlegl = server_wlegl_from(res); wl_resource *resource = wl_resource_create(client, &android_wlegl_server_buffer_handle_interface, wl_resource_get_version(res), id); buffer_handle_t _handle; int _stride; usage |= GRALLOC_USAGE_HW_COMPOSER; int r = hybris_gralloc_allocate(width, height, format, usage, &_handle, (uint32_t*)&_stride); if (r) { HYBRIS_ERROR_LOG(SERVER_WLEGL, "failed to allocate buffer\n"); } server_wlegl_buffer *buffer = server_wlegl_buffer_create_server(client, width, height, _stride, format, usage, _handle, wlegl); struct wl_array ints; int *ints_data; wl_array_init(&ints); ints_data = (int*) wl_array_add(&ints, _handle->numInts * sizeof(int)); memcpy(ints_data, _handle->data + _handle->numFds, _handle->numInts * sizeof(int)); android_wlegl_server_buffer_handle_send_buffer_ints(resource, &ints); wl_array_release(&ints); for (int i = 0; i < _handle->numFds; i++) { android_wlegl_server_buffer_handle_send_buffer_fd(resource, _handle->data[i]); } android_wlegl_server_buffer_handle_send_buffer(resource, buffer->resource, format, _stride); wl_resource_destroy(resource); }