예제 #1
0
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;
}
예제 #2
0
파일: simple-touch.c 프로젝트: RAOF/weston
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);
}
예제 #3
0
파일: util.cpp 프로젝트: nyorain/ny
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);
}
예제 #4
0
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;
}
예제 #5
0
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;
}
예제 #6
0
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);
}
예제 #7
0
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);
}
예제 #8
0
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;
}
예제 #9
0
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;
}
예제 #10
0
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;
}
예제 #11
0
파일: wlf_window.c 프로젝트: AMV007/FreeRDP
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;
}
예제 #12
0
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;
}
예제 #13
0
파일: shm.c 프로젝트: videolan/vlc
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;
}
예제 #14
0
파일: wayland.c 프로젝트: mstorsjo/vlc
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;
}
예제 #16
0
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);
}
예제 #17
0
파일: chromakey.c 프로젝트: Airtau/genivi
/*****************************************************************************
 *  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;
}
예제 #18
0
 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;
 }
예제 #19
0
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);
}
예제 #20
0
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;
}
예제 #21
0
파일: simple-shm.c 프로젝트: N8Fear/adwc
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;
}
예제 #22
0
파일: buffer.c 프로젝트: 0x0all/mpv
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;
}
예제 #23
0
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;
}
예제 #24
0
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;
}
예제 #25
0
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);
}
예제 #26
0
	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;
	}
예제 #27
0
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;
}
예제 #28
0
파일: simple-shm.c 프로젝트: Blei/weston
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;
}
예제 #29
0
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;
}
예제 #30
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;
}