Ejemplo n.º 1
0
static int realloc_buffer(struct exynos_data *pdata,
                          enum exynos_buffer_type type, unsigned size) {
  struct exynos_bo *buf = pdata->buf[type];
  unsigned i;

  if (size > buf->size) {
#if (EXYNOS_GFX_DEBUG_LOG == 1)
    RARCH_LOG("video_exynos: reallocating %s buffer (%u -> %u bytes)\n",
              buffer_name(type), buf->size, size);
#endif

    exynos_bo_destroy(buf);
    buf = create_mapped_buffer(pdata->device, size);

    if (buf == NULL) {
      RARCH_ERR("video_exynos: reallocation failed\n");
      return -1;
    }

    pdata->buf[type] = buf;

    /* Map new GEM buffer to the G2D images backed by it. */
    for (i = 0; i < exynos_image_count; ++i) {
      if (defaults[i].buf_type == type)
        pdata->src[i]->bo[0] = buf->handle;
    }
  }

  return 0;
}
Ejemplo n.º 2
0
static void clean_up_pages(struct exynos_page *p, unsigned cnt) {
  unsigned i;

  for (i = 0; i < cnt; ++i) {
    if (p[i].bo != NULL) {
      if (p[i].buf_id != 0)
        drmModeRmFB(p[i].buf_id, p[i].bo->handle);

      exynos_bo_destroy(p[i].bo);
    }
  }
}
Ejemplo n.º 3
0
static struct exynos_bo *exynos_create_buffer(struct exynos_device *dev,
						unsigned long size,
						unsigned int flags)
{
	struct exynos_bo *bo;

	bo = exynos_bo_create(dev, size, flags);
	if (!bo)
		return bo;

	if (!exynos_bo_map(bo)) {
		exynos_bo_destroy(bo);
		return NULL;
	}

	return bo;
}
Ejemplo n.º 4
0
/* Create a GEM buffer with userspace mapping. Buffer is cleared after creation. */
static struct exynos_bo *create_mapped_buffer(struct exynos_device *dev, unsigned size) {
  struct exynos_bo *buf;
  const unsigned flags = 0;

  buf = exynos_bo_create(dev, size, flags);
  if (buf == NULL) {
    RARCH_ERR("video_exynos: failed to create temp buffer object\n");
    return NULL;
  }

  if (exynos_bo_map(buf) == NULL) {
    RARCH_ERR("video_exynos: failed to map temp buffer object\n");
    exynos_bo_destroy(buf);
    return NULL;
  }

  memset(buf->vaddr, 0, size);

  return buf;
}
Ejemplo n.º 5
0
static void exynos_destroy_buffer(struct exynos_bo *bo)
{
	exynos_bo_destroy(bo);
}
Ejemplo n.º 6
0
static int exynos_alloc(struct hook_data *data) {
  struct exynos_device *device;
  struct exynos_bo *bo;
  struct exynos_page *pages;
  struct drm_prime_handle req = { 0 };
  unsigned i;

  const unsigned flags = 0;

  device = exynos_device_create(data->drm_fd);
  if (device == NULL) {
    fprintf(stderr, "[exynos_init] error: failed to create device from fd\n");
    return -1;
  }

  pages = calloc(data->num_pages, sizeof(struct exynos_page));
  if (pages == NULL) {
    fprintf(stderr, "[exynos_init] error: failed to allocate pages\n");
    goto fail_alloc;
  }

  for (i = 0; i < data->num_pages; ++i) {
    bo = exynos_bo_create(device, data->size, flags);
    if (bo == NULL) {
      fprintf(stderr, "[exynos_init] error: failed to create buffer object\n");
      goto fail;
    }

    req.handle = bo->handle;

    if (drmIoctl(data->drm_fd, DRM_IOCTL_PRIME_HANDLE_TO_FD, &req) < 0) {
      fprintf(stderr, "[exynos_init] error: failed to get fd from bo\n");
      exynos_bo_destroy(bo);
      goto fail;
    }

    /* Don't map the BO, since we don't access it through userspace. */

    pages[i].bo = bo;
    pages[i].fd = req.fd;
    pages[i].base = data;

    pages[i].used = false;
    pages[i].clear = true;
  }

  if (vconf.use_screen == 1) {
    const uint32_t pixel_format = (data->bpp == 2) ? DRM_FORMAT_RGB565 : DRM_FORMAT_XRGB8888;
    uint32_t handles[4] = {0}, pitches[4] = {0}, offsets[4] = {0};

    pitches[0] = data->pitch;
    offsets[0] = 0;

    for (i = 0; i < data->num_pages; ++i) {
      handles[0] = pages[i].bo->handle;

      if (drmModeAddFB2(data->drm_fd, data->width, data->height,
                        pixel_format, handles, pitches, offsets,
                        &pages[i].buf_id, flags)) {
        fprintf(stderr, "[exynos_init] error: failed to add bo %u to fb\n", i);
        goto fail;
      }
    }
  }

  if (vconf.use_screen == 1) {
    /* Setup CRTC: display the last allocated page. */
    if (drmModeSetCrtc(data->drm_fd, data->drm->crtc_id, pages[data->num_pages - 1].buf_id,
                       0, 0, &data->drm->connector_id, 1, data->drm->mode)) {
      fprintf(stderr, "[exynos_init] error: drmModeSetCrtc failed\n");
      goto fail;
    }
  }

  data->pages = pages;
  data->device = device;

  return 0;

fail:
  clean_up_pages(pages, data->num_pages);

fail_alloc:
  exynos_device_destroy(device);

  return -1;
}