static Eina_Bool _evas_swapper_buffer_new(Wl_Swapper *ws, Wl_Buffer *wb) { unsigned int format = WL_SHM_FORMAT_XRGB8888; size_t size; LOGFN(__FILE__, __LINE__, __FUNCTION__); /* make sure swapper has a shm */ if (!ws->shm) return EINA_FALSE; wb->w = ws->w; wb->h = ws->h; /* calculate new required size */ size = ((wb->w * sizeof(int)) * wb->h); /* check pool size to see if we need to realloc the pool */ if (ws->used_size + size > ws->pool_size) { size_t newsize; /* calculate new required size */ newsize = (ws->pool_size + size); /* resize the shm pool */ wl_shm_pool_resize(ws->pool, newsize); ws->pool_size = newsize; } /* check if this buffer needs argb and set format */ if (ws->alpha) format = WL_SHM_FORMAT_ARGB8888; /* create actual wl_buffer */ wb->buffer = wl_shm_pool_create_buffer(ws->pool, ws->used_size, wb->w, wb->h, (wb->w * sizeof(int)), format); /* add wayland buffer listener */ wl_buffer_add_listener(wb->buffer, &_evas_swapper_buffer_listener, wb); wb->data = (char *)ws->data + ws->used_size; wb->size = size; ws->used_size += size; wb->ws = ws; /* return allocated buffer */ return EINA_TRUE; }
int shm_buffer_resize(shm_buffer_t *buffer, uint32_t width, uint32_t height) { uint32_t new_stride = SHM_BUFFER_STRIDE(width, buffer->bytes); uint32_t new_size = new_stride * height; if (SHM_BUFFER_IS_BUSY(buffer)) { SHM_BUFFER_SET_PNDNG_RSZ(buffer); buffer->pending_width = width; buffer->pending_height = height; return SHM_BUFFER_BUSY; } SHM_BUFFER_CLEAR_PNDNG_RSZ(buffer); if (new_size > buffer->pool_size) { munmap(buffer->data, buffer->pool_size); ftruncate(buffer->fd, new_size); buffer->data = mmap(NULL, new_size, PROT_READ | PROT_WRITE, MAP_SHARED, buffer->fd, 0); // TODO: the buffer should be destroyed when -1 is return if (buffer->data == MAP_FAILED) return -1; wl_shm_pool_resize(buffer->shm_pool, new_size); buffer->pool_size = new_size; } const void *listener = wl_proxy_get_listener((struct wl_proxy*)buffer->buffer); wl_buffer_destroy(buffer->buffer); buffer->buffer = wl_shm_pool_create_buffer(buffer->shm_pool, 0, width, height, new_stride, buffer->format.wl_format); wl_buffer_add_listener(buffer->buffer, listener, buffer); buffer->height = height; buffer->stride = new_stride; return 0; }
static int shm_pool_resize(struct shm_pool *pool, int size) { if (ftruncate(pool->fd, size) < 0) return 0; #ifdef HAVE_POSIX_FALLOCATE errno = posix_fallocate(pool->fd, 0, size); if (errno != 0) return 0; #endif wl_shm_pool_resize(pool->pool, size); munmap(pool->data, pool->size); pool->data = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, pool->fd, 0); pool->size = size; return 1; }