/*
 * 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 !");
            }
        }
    }
}
示例#2
0
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);
}