static struct shm_pool * shm_pool_create(struct wl_shm *shm, int size) { struct shm_pool *pool; pool = malloc(sizeof *pool); if (!pool) return NULL; pool->fd = os_create_anonymous_file(size); if (pool->fd < 0) goto err_free; pool->data = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, pool->fd, 0); if (pool->data == MAP_FAILED) goto err_close; pool->pool = wl_shm_create_pool(shm, pool->fd, size); pool->size = size; pool->used = 0; return pool; err_close: close(pool->fd); err_free: free(pool); return NULL; }
static void create_shm_buffer(struct touch *touch) { struct wl_shm_pool *pool; int fd, size, stride; stride = touch->width * 4; size = stride * touch->height; fd = os_create_anonymous_file(size); if (fd < 0) { fprintf(stderr, "creating a buffer file for %d B failed: %m\n", size); exit(1); } touch->data = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); if (touch->data == MAP_FAILED) { fprintf(stderr, "mmap failed: %m\n"); close(fd); exit(1); } pool = wl_shm_create_pool(touch->shm, fd, size); touch->buffer = wl_shm_pool_create_buffer(pool, 0, touch->width, touch->height, stride, WL_SHM_FORMAT_ARGB8888); wl_shm_pool_destroy(pool); close(fd); }
void ShmBuffer::create() { destroy(); if(!size_.x || !size_.y) throw std::runtime_error("ny::wayland::ShmBuffer invalid size"); if(!stride_) throw std::runtime_error("ny::wayland::ShmBuffer invalid stride"); auto* shm = appContext_->wlShm(); if(!shm) throw std::runtime_error("ny::wayland::ShmBuffer: wlAC has no wl_shm"); auto vecSize = stride_ * size_.y; shmSize_ = std::max(vecSize, shmSize_); auto fd = osCreateAnonymousFile(shmSize_); if (fd < 0) throw std::runtime_error("ny::wayland::ShmBuffer: could not create shm file"); //the fd is not needed here anymore AFTER the pool was created //our access to the file is represented by the pool auto fdGuard = nytl::makeScopeGuard([&]{ close(fd); }); auto ptr = mmap(nullptr, shmSize_, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); if(ptr == MAP_FAILED) throw std::runtime_error("ny::wayland::ShmBuffer: could not mmap file"); data_ = reinterpret_cast<std::uint8_t*>(ptr); pool_ = wl_shm_create_pool(shm, fd, shmSize_); buffer_ = wl_shm_pool_create_buffer(pool_, 0, size_.x, size_.y, stride_, format_); static constexpr wl_buffer_listener listener { memberCallback<decltype(&ShmBuffer::released), &ShmBuffer::released, void(wl_buffer*)> }; wl_buffer_add_listener(buffer_, &listener, this); }
static struct wl_shm_pool * make_shm_pool (struct display *display, int size, void **data) { struct wl_shm_pool *pool; int fd; char filename[1024]; static int init = 0; snprintf (filename, 256, "%s-%d-%s", "/tmp/wayland-shm", init++, "XXXXXX"); fd = mkstemp (filename); if (fd < 0) { GST_ERROR ("open %s failed:", filename); return NULL; } if (ftruncate (fd, size) < 0) { GST_ERROR ("ftruncate failed:..!"); close (fd); return NULL; } *data = mmap (NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); if (*data == MAP_FAILED) { GST_ERROR ("mmap failed: "); close (fd); return NULL; } pool = wl_shm_create_pool (display->shm, fd, size); close (fd); return pool; }
struct wl_buffer * gst_wl_shm_memory_construct_wl_buffer (GstMemory * mem, GstWlDisplay * display, const GstVideoInfo * info) { GstWlShmMemory *shm_mem = (GstWlShmMemory *) mem; gint width, height, stride; gsize size; enum wl_shm_format format; struct wl_shm_pool *wl_pool; struct wl_buffer *wbuffer; width = GST_VIDEO_INFO_WIDTH (info); height = GST_VIDEO_INFO_HEIGHT (info); stride = GST_VIDEO_INFO_PLANE_STRIDE (info, 0); size = GST_VIDEO_INFO_SIZE (info); format = gst_video_format_to_wl_shm_format (GST_VIDEO_INFO_FORMAT (info)); g_return_val_if_fail (gst_is_wl_shm_memory (mem), NULL); g_return_val_if_fail (size <= mem->size, NULL); g_return_val_if_fail (shm_mem->fd != -1, NULL); GST_DEBUG_OBJECT (mem->allocator, "Creating wl_buffer of size %" G_GSSIZE_FORMAT " (%d x %d, stride %d), format %s", size, width, height, stride, gst_wl_shm_format_to_string (format)); wl_pool = wl_shm_create_pool (display->shm, shm_mem->fd, mem->size); wbuffer = wl_shm_pool_create_buffer (wl_pool, 0, width, height, stride, format); close (shm_mem->fd); shm_mem->fd = -1; wl_shm_pool_destroy (wl_pool); return wbuffer; }
ShmBuffer::ShmBuffer(const QSize &size, wl_shm *shm) : handle(0) { int stride = size.width() * 4; int alloc = stride * size.height(); char filename[] = "/tmp/wayland-shm-XXXXXX"; int fd = mkstemp(filename); if (fd < 0) { qWarning("open %s failed: %s", filename, strerror(errno)); return; } if (ftruncate(fd, alloc) < 0) { qWarning("ftruncate failed: %s", strerror(errno)); close(fd); return; } void *data = mmap(0, alloc, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); unlink(filename); if (data == MAP_FAILED) { qWarning("mmap failed: %s", strerror(errno)); close(fd); return; } image = QImage(static_cast<uchar *>(data), size.width(), size.height(), stride, QImage::Format_ARGB32_Premultiplied); shm_pool = wl_shm_create_pool(shm,fd,alloc); handle = wl_shm_pool_create_buffer(shm_pool,0, size.width(), size.height(), stride, WL_SHM_FORMAT_ARGB8888); close(fd); }
void noia_controller_create_shm_buffer(NoiaScreenshooter* shooter, NoiaCtlOutput* ctl_output) { unsigned stride = 4 * ctl_output->w; unsigned size = stride * ctl_output->h; char name[32]; snprintf(name, sizeof(name), "shm-output-%d", ctl_output->id); int fd = noia_environment_open_file(name, size, RUNTIME_PATH); if (fd < 0) { printf("Creating a buffer file for %u bytes failed! (%m)\n", size); return; } ctl_output->data = (uint8_t*) mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); if (ctl_output->data == MAP_FAILED) { printf("Creating shared memory map failed! (%m)\n"); close(fd); return; } struct wl_shm_pool* pool = wl_shm_create_pool(shooter->shm, fd, size); ctl_output->buffer = wl_shm_pool_create_buffer(pool, 0, ctl_output->w, ctl_output->h, stride, WL_SHM_FORMAT_XRGB8888); wl_shm_pool_destroy(pool); close(fd); }
static struct wl_buffer * create_bad_shm_buffer(struct client *client, int width, int height) { struct wl_shm *shm = client->wl_shm; int stride = width * 4; int size = stride * height; struct wl_shm_pool *pool; struct wl_buffer *buffer; int fd; fd = os_create_anonymous_file(size); assert(fd >= 0); pool = wl_shm_create_pool(shm, fd, size); buffer = wl_shm_pool_create_buffer(pool, 0, width, height, stride, WL_SHM_FORMAT_ARGB8888); wl_shm_pool_destroy(pool); /* Truncate the file to a small size, so that the compositor * will access it out-of-bounds, and hit SIGBUS. */ assert(ftruncate(fd, 12) == 0); close(fd); return buffer; }
struct wl_buffer * create_shm_buffer(struct client *client, int width, int height, void **pixels) { struct wl_shm *shm = client->wl_shm; int stride = width * 4; int size = stride * height; struct wl_shm_pool *pool; struct wl_buffer *buffer; int fd; void *data; fd = os_create_anonymous_file(size); assert(fd >= 0); data = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); if (data == MAP_FAILED) { close(fd); assert(data != MAP_FAILED); } pool = wl_shm_create_pool(shm, fd, size); buffer = wl_shm_pool_create_buffer(pool, 0, width, height, stride, WL_SHM_FORMAT_ARGB8888); wl_shm_pool_destroy(pool); close(fd); if (pixels) *pixels = data; return buffer; }
static struct wl_buffer * create_buffer() { struct wl_shm_pool *pool; int stride = WIDTH * 4; // 4 bytes per pixel int size = stride * HEIGHT; int fd; struct wl_buffer *buff; fd = os_create_anonymous_file(size); if (fd < 0) { fprintf(stderr, "creating a buffer file for %d B failed: %m\n", size); exit(1); } shm_data = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); if (shm_data == MAP_FAILED) { fprintf(stderr, "mmap failed: %m\n"); close(fd); exit(1); } pool = wl_shm_create_pool(shm, fd, size); buff = wl_shm_pool_create_buffer(pool, 0, WIDTH, HEIGHT, stride, WL_SHM_FORMAT_XRGB8888); //wl_buffer_add_listener(buffer, &buffer_listener, buffer); wl_shm_pool_destroy(pool); return buff; }
static void wl_callback_done(void* data, struct wl_callback* callback, uint32_t time) { wlfWindow* window = data; wlfBuffer* buffer; struct wl_shm_pool* shm_pool; void* shm_data; void* free_data; int fd; int fdt; if (!window->buffers[0].busy) buffer = &window->buffers[0]; else if (!window->buffers[1].busy) buffer = &window->buffers[1]; else return; if (!buffer->buffer) { fd = shm_open("/wlfreerdp_shm", O_CREAT | O_RDWR, 0666); fdt = ftruncate(fd, window->width * window->height * 4); if (fdt != 0) { WLog_ERR(TAG, "window_redraw: could not allocate memory"); close(fd); return; } shm_data = mmap(NULL, window->width * window->height * 4, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); if (shm_data == MAP_FAILED) { WLog_ERR(TAG, "window_redraw: failed to memory map buffer"); close(fd); return; } shm_pool = wl_shm_create_pool(window->display->shm, fd, window->width * window->height * 4); buffer->buffer = wl_shm_pool_create_buffer(shm_pool, 0, window->width, window->height, window->width* 4, WL_SHM_FORMAT_XRGB8888); wl_buffer_add_listener(buffer->buffer, &wl_buffer_listener, buffer); wl_shm_pool_destroy(shm_pool); shm_unlink("/wlfreerdp_shm"); close(fd); free_data = buffer->shm_data; buffer->shm_data = shm_data; munmap(free_data, window->width * window->height * 4); } /* this is the real surface data */ memcpy(buffer->shm_data, (void*) window->data, window->width * window->height * 4); wl_surface_attach(window->surface, buffer->buffer, 0, 0); wl_surface_damage(window->surface, 0, 0, window->width, window->height); if (callback) wl_callback_destroy(callback); window->callback = wl_surface_frame(window->surface); wl_callback_add_listener(window->callback, &wl_callback_listener, window); wl_surface_commit(window->surface); buffer->busy = TRUE; }
int UwacWindowShmAllocBuffers(UwacWindow* w, int nbuffers, int allocSize, uint32_t width, uint32_t height, enum wl_shm_format format) { int ret = UWAC_SUCCESS; UwacBuffer* newBuffers; int i, fd; void* data; struct wl_shm_pool* pool; newBuffers = realloc(w->buffers, (w->nbuffers + nbuffers) * sizeof(UwacBuffer)); if (!newBuffers) return UWAC_ERROR_NOMEMORY; w->buffers = newBuffers; memset(w->buffers + w->nbuffers, 0, sizeof(UwacBuffer) * nbuffers); fd = uwac_create_anonymous_file(allocSize * nbuffers); if (fd < 0) { return UWAC_ERROR_INTERNAL; } data = mmap(NULL, allocSize * nbuffers, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); if (data == MAP_FAILED) { ret = UWAC_ERROR_NOMEMORY; goto error_mmap; } pool = wl_shm_create_pool(w->display->shm, fd, allocSize * nbuffers); if (!pool) { ret = UWAC_ERROR_NOMEMORY; goto error_mmap; } for (i = 0; i < nbuffers; i++) { UwacBuffer* buffer = &w->buffers[w->nbuffers + i]; #ifdef HAVE_PIXMAN_REGION pixman_region32_init(&buffer->damage); #else region16_init(&buffer->damage); #endif buffer->data = data + (allocSize * i); buffer->wayland_buffer = wl_shm_pool_create_buffer(pool, allocSize * i, width, height, w->stride, format); wl_buffer_add_listener(buffer->wayland_buffer, &buffer_listener, buffer); } wl_shm_pool_destroy(pool); w->nbuffers += nbuffers; error_mmap: close(fd); return ret; }
static void Prepare(vout_display_t *vd, picture_t *pic, subpicture_t *subpic, vlc_tick_t date) { VLC_UNUSED(date); vout_display_sys_t *sys = vd->sys; struct wl_display *display = sys->embed->display.wl; struct wl_surface *surface = sys->embed->handle.wl; struct picture_buffer_t *picbuf = pic->p_sys; if (picbuf->fd == -1) return; struct buffer_data *d = malloc(sizeof (*d)); if (unlikely(d == NULL)) return; d->picture = pic; d->counter = &sys->active_buffers; off_t offset = picbuf->offset; const size_t stride = pic->p->i_pitch; const size_t size = pic->p->i_lines * stride; struct wl_shm_pool *pool; struct wl_buffer *buf; pool = wl_shm_create_pool(sys->shm, picbuf->fd, offset + size); if (pool == NULL) { free(d); return; } if (sys->viewport == NULL) /* Poor man's crop */ offset += 4 * vd->fmt.i_x_offset + pic->p->i_pitch * vd->fmt.i_y_offset; buf = wl_shm_pool_create_buffer(pool, offset, vd->fmt.i_visible_width, vd->fmt.i_visible_height, stride, WL_SHM_FORMAT_XRGB8888); wl_shm_pool_destroy(pool); if (buf == NULL) { free(d); return; } picture_Hold(pic); wl_buffer_add_listener(buf, &buffer_cbs, d); wl_surface_attach(surface, buf, 0, 0); wl_surface_damage(surface, 0, 0, sys->display_width, sys->display_height); wl_display_flush(display); sys->active_buffers++; (void) subpic; }
static block_t *Shoot(demux_t *demux) { demux_sys_t *sys = demux->p_sys; int fd = vlc_memfd(); if (fd == -1) { msg_Err(demux, "buffer creation error: %s", vlc_strerror_c(errno)); return NULL; } /* NOTE: one extra line for overflow if screen-left > 0 */ uint32_t pitch = 4u * sys->width; size_t size = (pitch * (sys->height + 1) + sys->pagemask) & ~sys->pagemask; block_t *block = NULL; if (ftruncate(fd, size) < 0) { msg_Err(demux, "buffer allocation error: %s", vlc_strerror_c(errno)); goto out; } struct wl_shm_pool *pool = wl_shm_create_pool(sys->shm, fd, size); if (pool == NULL) goto out; struct wl_buffer *buffer; buffer = wl_shm_pool_create_buffer(pool, 0, sys->width, sys->height, pitch, WL_SHM_FORMAT_XRGB8888); wl_shm_pool_destroy(pool); if (buffer == NULL) goto out; sys->done = false; screenshooter_shoot(sys->screenshooter, sys->output, buffer); while (!sys->done) wl_display_roundtrip(sys->display); wl_buffer_destroy(buffer); block = block_File(fd, true); if (block != NULL) { size_t skip = (sys->y * sys->width + sys->x) * 4; block->p_buffer += skip; block->i_buffer -= skip; } out: vlc_close(fd); return block; }
static GstWlBuffer * wayland_buffer_create (GstWaylandSink * sink) { char filename[1024]; int fd, size, stride; static void *data; static int init = 0; GstWlBuffer *wbuffer; struct wl_shm_pool *shm_pool; GST_DEBUG_OBJECT (sink, "Creating wayland-shm buffers"); wbuffer = (GstWlBuffer *) gst_mini_object_new (GST_TYPE_WLBUFFER); wbuffer->wlsink = gst_object_ref (sink); snprintf (filename, 256, "%s-%d-%s", "/tmp/wayland-shm", init++, "XXXXXX"); fd = mkstemp (filename); if (fd < 0) { GST_ERROR_OBJECT (sink, "open %s failed:", filename); exit (0); } stride = sink->video_width * 4; size = stride * sink->video_height; if (ftruncate (fd, size) < 0) { GST_ERROR_OBJECT (sink, "ftruncate failed:"); close (fd); exit (0); } data = mmap (NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); unlink (filename); if (data == MAP_FAILED) { GST_ELEMENT_ERROR (sink, LIBRARY, SHUTDOWN, (NULL), ("mmap() failed: %s", strerror (errno))); close (fd); exit (0); } shm_pool = wl_shm_create_pool (sink->display->shm, fd, size); wbuffer->wbuffer = wl_shm_pool_create_buffer (shm_pool, 0, sink->video_width, sink->video_height, stride, WL_SHM_FORMAT_XRGB8888); wbuffer->pool = shm_pool; close (fd); GST_BUFFER_DATA (wbuffer) = data; GST_BUFFER_SIZE (wbuffer) = size; return wbuffer; }
static void draw_initial_frame(struct wayland_output *output) { struct wayland_compositor *c = (struct wayland_compositor *) output->base.compositor; struct wl_shm *shm = c->parent.shm; struct wl_surface *surface = output->parent.surface; struct wl_shm_pool *pool; struct wl_buffer *buffer; int width, height, stride; int size; int fd; void *data; width = output->mode.width + c->border.left + c->border.right; height = output->mode.height + c->border.top + c->border.bottom; stride = width * 4; size = height * stride; fd = os_create_anonymous_file(size); if (fd < 0) { perror("os_create_anonymous_file"); return; } data = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); if (data == MAP_FAILED) { perror("mmap"); close(fd); return; } pool = wl_shm_create_pool(shm, fd, size); buffer = wl_shm_pool_create_buffer(pool, 0, width, height, stride, WL_SHM_FORMAT_ARGB8888); wl_buffer_add_listener(buffer, &buffer_listener, buffer); wl_shm_pool_destroy(pool); close(fd); memset(data, 0, size); wl_surface_attach(surface, buffer, 0, 0); /* We only need to damage some part, as its only transparant * pixels anyway. */ wl_surface_damage(surface, 0, 0, 1, 1); }
/***************************************************************************** * local functions ****************************************************************************/ static void createShmBuffer() { struct wl_shm_pool *pool; char filename[] = "/tmp/wayland-shm-XXXXXX"; int fd = -1; int size = 0; fd = mkstemp(filename); if (fd < 0){ fprintf(stderr, "open %s failed: %m\n", filename); return; } size = g_wlContextStruct.ctx_bmp->stride * g_wlContextStruct.ctx_bmp->height; if (ftruncate(fd, size) < 0){ fprintf(stderr, "ftruncate failed: %m\n"); close(fd); return; } g_wlContextStruct.data = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); if (MAP_FAILED == g_wlContextStruct.data) { fprintf(stderr, "mmap failed: %m\n"); close(fd); return; } pool = wl_shm_create_pool(g_wlContextStruct.wlShm, fd, size); g_wlContextStruct.wlBuffer = wl_shm_pool_create_buffer(pool, 0, g_wlContextStruct.ctx_bmp->width, g_wlContextStruct.ctx_bmp->height, g_wlContextStruct.ctx_bmp->stride, WL_SHM_FORMAT_XRGB8888); if (NULL == g_wlContextStruct.wlBuffer) { fprintf(stderr, "wl_shm_create_buffer failed: %m\n"); close(fd); return; } wl_surface_attach(g_wlContextStruct.wlSurface, g_wlContextStruct.wlBuffer, 0, 0); wl_shm_pool_destroy(pool); close(fd); return; }
wl_buffer* createShmBuffer(wl_shm* shm, uint32_t width, uint32_t height) { int32_t stride = width * 4; int32_t size = stride * height; int fd = createAnonymousFile(size); mData = reinterpret_cast<uint8_t*>( mmap(nullptr, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0)); if (mData == MAP_FAILED) { close(fd); throw WLException("Cannot create shm buffer"); } wl_shm_pool* pool = wl_shm_create_pool(shm, fd, size); wl_buffer* buff = wl_shm_pool_create_buffer(pool, 0, width, height, stride, WL_SHM_FORMAT_XRGB8888); wl_shm_pool_destroy(pool); close(fd); return buff; }
static gboolean gst_wayland_buffer_pool_start (GstBufferPool * pool) { GstWaylandBufferPool *self = GST_WAYLAND_BUFFER_POOL (pool); guint size = 0; int fd; char filename[1024]; static int init = 0; GST_DEBUG_OBJECT (self, "Initializing wayland buffer pool"); /* configure */ size = GST_VIDEO_INFO_SIZE (&self->info) * 15; /* allocate shm pool */ snprintf (filename, 1024, "%s/%s-%d-%s", g_get_user_runtime_dir (), "wayland-shm", init++, "XXXXXX"); fd = mkstemp (filename); if (fd < 0) { GST_ERROR_OBJECT (pool, "opening temp file %s failed: %s", filename, strerror (errno)); return FALSE; } if (ftruncate (fd, size) < 0) { GST_ERROR_OBJECT (pool, "ftruncate failed: %s", strerror (errno)); close (fd); return FALSE; } self->data = mmap (NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); if (self->data == MAP_FAILED) { GST_ERROR_OBJECT (pool, "mmap failed: %s", strerror (errno)); close (fd); return FALSE; } self->wl_pool = wl_shm_create_pool (self->display->shm, fd, size); unlink (filename); close (fd); self->size = size; self->used = 0; return GST_BUFFER_POOL_CLASS (parent_class)->start (pool); }
static BufferData * _create_buffer (gint width, gint height) { MechBackendWayland *backend; BufferData *buffer; gint stride, fd; buffer = g_new0 (BufferData, 1); backend = _mech_backend_wayland_get (); stride = cairo_format_stride_for_width (CAIRO_FORMAT_ARGB32, width); buffer->data_len = stride * height; fd = _create_temporary_file (buffer->data_len); buffer->data = mmap (NULL, buffer->data_len, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); if (buffer->data == MAP_FAILED) { g_critical ("Failed to mmap SHM region: %m"); g_free (buffer); close(fd); return NULL; } buffer->wl_pool = wl_shm_create_pool (backend->wl_shm, fd, buffer->data_len); close (fd); buffer->wl_buffer = wl_shm_pool_create_buffer (buffer->wl_pool, 0, width, height, stride, WL_SHM_FORMAT_ARGB8888); wl_buffer_add_listener (buffer->wl_buffer, &buffer_listener_funcs, buffer); buffer->surface = cairo_image_surface_create_for_data (buffer->data, CAIRO_FORMAT_ARGB32, width, height, stride); buffer->blank = TRUE; buffer->released = TRUE; return buffer; }
static struct wl_buffer * create_shm_buffer(struct display *display, int width, int height, uint32_t format, void **data_out) { char filename[] = "/tmp/wayland-shm-XXXXXX"; struct wl_shm_pool *pool; struct wl_buffer *buffer; int fd, size, stride; void *data; fd = mkstemp(filename); if (fd < 0) { fprintf(stderr, "open %s failed: %m\n", filename); return NULL; } stride = width * 4; size = stride * height; if (ftruncate(fd, size) < 0) { fprintf(stderr, "ftruncate failed: %m\n"); close(fd); return NULL; } data = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); unlink(filename); if (data == MAP_FAILED) { fprintf(stderr, "mmap failed: %m\n"); close(fd); return NULL; } pool = wl_shm_create_pool(display->shm, fd, size); buffer = wl_shm_pool_create_buffer(pool, 0, width, height, stride, format); wl_shm_pool_destroy(pool); close(fd); *data_out = data; return buffer; }
shm_buffer_t* shm_buffer_create(uint32_t width, uint32_t height, format_t fmt, struct wl_shm *shm, const struct wl_buffer_listener *listener) { int8_t bytes = format_get_bytes(&fmt); uint32_t stride = SHM_BUFFER_STRIDE(width, bytes); uint32_t size = stride * height; shm_buffer_t *buffer = calloc(1, sizeof(shm_buffer_t)); int fd = memfile_create(size); if (fd < 0) return NULL; buffer->data = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); if (buffer->data == MAP_FAILED) { close(fd); return NULL; } buffer->shm_pool = wl_shm_create_pool(shm, fd, size); buffer->buffer = wl_shm_pool_create_buffer(buffer->shm_pool, 0, width, height, stride, fmt.wl_format); wl_buffer_add_listener(buffer->buffer, listener, buffer); buffer->fd = fd; buffer->height = height; buffer->stride = stride; buffer->format = fmt; buffer->bytes = bytes; buffer->pool_size = size; buffer->pending_height = 0; buffer->pending_width = 0; return buffer; }
struct wl_buffer * gst_wl_shm_memory_construct_wl_buffer (GstMemory * mem, GstWlDisplay * display, const GstVideoInfo * info) { gint width, height, stride; gsize offset, size, memsize, maxsize; enum wl_shm_format format; struct wl_shm_pool *wl_pool; struct wl_buffer *wbuffer; if (!gst_wl_shm_validate_video_info (info)) { GST_DEBUG_OBJECT (display, "Unsupported strides and offsets."); return NULL; } width = GST_VIDEO_INFO_WIDTH (info); height = GST_VIDEO_INFO_HEIGHT (info); stride = GST_VIDEO_INFO_PLANE_STRIDE (info, 0); size = GST_VIDEO_INFO_SIZE (info); format = gst_video_format_to_wl_shm_format (GST_VIDEO_INFO_FORMAT (info)); memsize = gst_memory_get_sizes (mem, &offset, &maxsize); offset += GST_VIDEO_INFO_PLANE_OFFSET (info, 0); g_return_val_if_fail (gst_is_fd_memory (mem), NULL); g_return_val_if_fail (size <= memsize, NULL); g_return_val_if_fail (gst_wl_display_check_format_for_shm (display, GST_VIDEO_INFO_FORMAT (info)), NULL); GST_DEBUG_OBJECT (display, "Creating wl_buffer from SHM of size %" G_GSSIZE_FORMAT " (%d x %d, stride %d), format %s", size, width, height, stride, gst_wl_shm_format_to_string (format)); wl_pool = wl_shm_create_pool (display->shm, gst_fd_memory_get_fd (mem), memsize); wbuffer = wl_shm_pool_create_buffer (wl_pool, offset, width, height, stride, format); wl_shm_pool_destroy (wl_pool); return wbuffer; }
struct wl_shm_pool *hello_create_memory_pool(int file) { struct pool_data *data; struct wl_shm_pool *pool; struct stat stat; if (fstat(file, &stat) != 0) return NULL; data = malloc(sizeof(struct pool_data)); if (data == NULL) return NULL; data->capacity = stat.st_size; data->size = 0; data->fd = file; data->memory = mmap(0, data->capacity*sizeof(pixel), PROT_READ, MAP_SHARED, data->fd, 0); if (data->memory == MAP_FAILED) goto cleanup_alloc; pool = wl_shm_create_pool(shm, data->fd, data->capacity*sizeof(pixel)); if (pool == NULL) goto cleanup_mmap; wl_shm_pool_set_user_data(pool, data); return pool; cleanup_mmap: munmap(data->memory, data->capacity*sizeof(pixel)); cleanup_alloc: free(data); return NULL; }
QT_BEGIN_NAMESPACE QWaylandShmBuffer::QWaylandShmBuffer(QWaylandDisplay *display, const QSize &size, QImage::Format format) : mMarginsImage(0) { int stride = size.width() * 4; int alloc = stride * size.height(); char filename[] = "/tmp/wayland-shm-XXXXXX"; int fd = mkstemp(filename); if (fd < 0) { qWarning("mkstemp %s failed: %s", filename, strerror(errno)); return; } int flags = fcntl(fd, F_GETFD); if (flags != -1) fcntl(fd, F_SETFD, flags | FD_CLOEXEC); if (ftruncate(fd, alloc) < 0) { qWarning("ftruncate failed: %s", strerror(errno)); close(fd); return; } uchar *data = (uchar *) mmap(NULL, alloc, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); unlink(filename); if (data == (uchar *) MAP_FAILED) { qWarning("mmap /dev/zero failed: %s", strerror(errno)); close(fd); return; } mImage = QImage(data, size.width(), size.height(), stride, format); mShmPool = wl_shm_create_pool(display->shm(), fd, alloc); mBuffer = wl_shm_pool_create_buffer(mShmPool,0, size.width(), size.height(), stride, WL_SHM_FORMAT_ARGB8888); close(fd); }
xdl_int XdevLWindowWayland::createBuffer() { // Couldn't create anonymous file. m_fd = createAnonymousFile(getWidth() * getHeight() * 4); if(-1 == m_fd) { XDEVL_MODULE_ERROR("mmap failed\n"); return ERR_ERROR; } // Couldn't map memory. m_shm_data = (xdl_uint8*)mmap(NULL, getWidth() * getHeight() * 4, PROT_READ | PROT_WRITE, MAP_SHARED, m_fd, 0); if(m_shm_data == MAP_FAILED) { XDEVL_MODULE_ERROR("mmap failed\n"); close(m_fd); return ERR_ERROR; } m_pool = wl_shm_create_pool(m_sharedMemory, m_fd, getWidth() * getHeight() * 4); m_buffer = wl_shm_pool_create_buffer(m_pool, 0, getWidth(), getHeight(), getWidth() * 4, WL_SHM_FORMAT_XRGB8888); wl_shm_pool_destroy(m_pool); return ERR_OK; }
static int create_shm_buffer(struct display *display, struct buffer *buffer, int width, int height, uint32_t format) { struct wl_shm_pool *pool; int fd, size, pitch; void *data; pitch = width * 4; size = pitch * height; fd = os_create_anonymous_file(size); if (fd < 0) { fprintf(stderr, "creating a buffer file for %d B failed: %m\n", size); return -1; } data = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); if (data == MAP_FAILED) { fprintf(stderr, "mmap failed: %m\n"); close(fd); return -1; } pool = wl_shm_create_pool(display->shm, fd, size); buffer->buffer = wl_shm_pool_create_buffer(pool, 0, width, height, pitch, format); wl_buffer_add_listener(buffer->buffer, &buffer_listener, buffer); wl_shm_pool_destroy(pool); close(fd); buffer->shm_data = data; return 0; }
static struct wl_buffer * create_shm_buffer(struct display *display, int width, int height, uint32_t format, void **data_out) { struct wl_shm_pool *pool; struct wl_buffer *buffer; int fd, size, stride; void *data; stride = width * 4; size = stride * height; fd = os_create_anonymous_file(size); if (fd < 0) { fprintf(stderr, "creating a buffer file for %d B failed: %m\n", size); return NULL; } data = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); if (data == MAP_FAILED) { fprintf(stderr, "mmap failed: %m\n"); close(fd); return NULL; } pool = wl_shm_create_pool(display->shm, fd, size); buffer = wl_shm_pool_create_buffer(pool, 0, width, height, stride, format); wl_shm_pool_destroy(pool); close(fd); *data_out = data; return buffer; }
uint8_t init_wayland_buffer(struct wayland *wayland) { wayland->fd = syscall(SYS_memfd_create, "nes-emulator", MFD_CLOEXEC | MFD_ALLOW_SEALING); if (wayland->fd < 0) { return EXIT_CODE_OS_ERROR_BIT; } int32_t stride = wayland->width * sizeof(uint32_t); int32_t single_capacity = stride * wayland->height; wayland->capacity = single_capacity * 2; if (ftruncate(wayland->fd, wayland->capacity) < 0) { uint8_t exit_code = EXIT_CODE_OS_ERROR_BIT; if (close(wayland->fd) < 0) { exit_code |= EXIT_CODE_OS_ERROR_BIT; } return exit_code; } wayland->data = mmap(NULL, wayland->capacity, PROT_WRITE | PROT_READ, MAP_SHARED, wayland->fd, 0); if (wayland->data == MAP_FAILED) { uint8_t exit_code = EXIT_CODE_OS_ERROR_BIT; if (close(wayland->fd) < 0) { exit_code |= EXIT_CODE_OS_ERROR_BIT; } return exit_code; } wayland->front_data = wayland->data; wayland->back_data = wayland->data + (wayland->width * wayland->height); wayland->shm_pool = wl_shm_create_pool(wayland->shm, wayland->fd, wayland->capacity); if (wayland->shm_pool == NULL) { uint8_t exit_code = EXIT_CODE_WAYLAND_BIT; if (munmap(wayland->data, wayland->capacity) < 0) { exit_code |= EXIT_CODE_OS_ERROR_BIT; } if (close(wayland->fd) < 0) { exit_code |= EXIT_CODE_OS_ERROR_BIT; } return exit_code; } wayland->front_buffer = wl_shm_pool_create_buffer( wayland->shm_pool, 0, wayland->width, wayland->height, stride, WL_SHM_FORMAT_ARGB8888); if (wayland->front_buffer == NULL) { uint8_t exit_code = EXIT_CODE_WAYLAND_BIT; wl_shm_pool_destroy(wayland->shm_pool); if (munmap(wayland->data, wayland->capacity) < 0) { exit_code |= EXIT_CODE_OS_ERROR_BIT; } if (close(wayland->fd) < 0) { exit_code |= EXIT_CODE_OS_ERROR_BIT; } return exit_code; } wayland->back_buffer = wl_shm_pool_create_buffer( wayland->shm_pool, single_capacity, wayland->width, wayland->height, stride, WL_SHM_FORMAT_ARGB8888); if (wayland->back_buffer == NULL) { uint8_t exit_code = EXIT_CODE_WAYLAND_BIT; wl_buffer_destroy(wayland->front_buffer); wl_shm_pool_destroy(wayland->shm_pool); if (munmap(wayland->data, wayland->capacity) < 0) { exit_code |= EXIT_CODE_OS_ERROR_BIT; } if (close(wayland->fd) < 0) { exit_code |= EXIT_CODE_OS_ERROR_BIT; } return exit_code; } return 0; }
static gboolean _eventd_nd_wl_create_buffer(EventdNdSurface *self) { struct wl_shm_pool *pool; struct wl_buffer *buffer; gint fd; gpointer data; gint width, height, stride; gsize size; width = self->width * self->context->scale; height = self->height * self->context->scale; stride = cairo_format_stride_for_width(CAIRO_FORMAT_ARGB32, width); size = stride * height; gchar *filename; filename = g_build_filename(g_get_user_runtime_dir(), PACKAGE_NAME G_DIR_SEPARATOR_S "wayland-surface", NULL); fd = g_open(filename, O_CREAT | O_RDWR | O_CLOEXEC, 0); g_unlink(filename); g_free(filename); if ( fd < 0 ) { g_warning("creating a buffer file for %zu B failed: %s\n", size, g_strerror(errno)); return FALSE; } if ( ftruncate(fd, size) < 0 ) { close(fd); return FALSE; } data = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); if ( data == MAP_FAILED ) { g_warning("mmap failed: %s\n", g_strerror(errno)); close(fd); return FALSE; } cairo_surface_t *cairo_surface; cairo_surface = cairo_image_surface_create_for_data(data, CAIRO_FORMAT_ARGB32, width, height, 4 * width); cairo_surface_set_device_scale(cairo_surface, self->context->scale, self->context->scale); self->context->nd->notification_draw(self->notification, cairo_surface, TRUE); cairo_surface_destroy(cairo_surface); munmap(data, size); pool = wl_shm_create_pool(self->context->shm, fd, size); buffer = wl_shm_pool_create_buffer(pool, 0, width, height, stride, WL_SHM_FORMAT_ARGB8888); wl_shm_pool_destroy(pool); close(fd); if ( self->buffer != NULL ) _eventd_nd_wl_buffer_release(self->buffer, self->buffer->buffer); self->buffer = g_new0(EventdNdWlBuffer, 1); self->buffer->buffer = buffer; self->buffer->data = data; self->buffer->size = size; wl_buffer_add_listener(buffer, &_eventd_nd_wl_buffer_listener, self->buffer); wl_surface_damage(self->surface, 0, 0, self->width, self->height); wl_surface_attach(self->surface, self->buffer->buffer, 0, 0); if ( wl_surface_get_version(self->surface) >= WL_SURFACE_SET_BUFFER_SCALE_SINCE_VERSION ) wl_surface_set_buffer_scale(self->surface, self->context->scale); wl_surface_commit(self->surface); return TRUE; }