void *(*map)(Dmabuf_Buffer *buf);
void (*unmap)(Dmabuf_Buffer *buf);
void (*discard)(Dmabuf_Buffer *buf);
+ void (*manager_destroy)(void);
void *priv;
+ void *dl_handle;
};
Buffer_Manager *buffer_manager = NULL;
struct _Dmabuf_Buffer
{
- Buffer_Manager *bm;
Dmabuf_Surface *surface;
struct wl_buffer *wl_buffer;
int w, h;
int (*sym_drm_intel_gem_bo_map_gtt)(drm_intel_bo *bo) = NULL;
drm_intel_bo *(*sym_drm_intel_bo_alloc_tiled)(drm_intel_bufmgr *mgr, const char *name, int x, int y, int cpp, uint32_t *tile, unsigned long *pitch, unsigned long flags) = NULL;
void (*sym_drm_intel_bo_unreference)(drm_intel_bo *bo) = NULL;
-int (*sym_drmPrimeHandleToFD)(int fd, uint32_t handle, uint32_t flags, int *prime_fd);
+int (*sym_drmPrimeHandleToFD)(int fd, uint32_t handle, uint32_t flags, int *prime_fd) = NULL;
+void (*sym_drm_intel_bufmgr_destroy)(drm_intel_bufmgr *) = NULL;
struct exynos_device *(*sym_exynos_device_create)(int fd) = NULL;
struct exynos_bo *(*sym_exynos_bo_create)(struct exynos_device *dev, size_t size, uint32_t flags) = NULL;
void *(*sym_exynos_bo_map)(struct exynos_bo *bo) = NULL;
void (*sym_exynos_bo_destroy)(struct exynos_bo *bo) = NULL;
+void (*sym_exynos_device_destroy)(struct exynos_device *) = NULL;
static Buffer_Handle *
_intel_alloc(Buffer_Manager *self, const char *name, int w, int h, unsigned long *stride, int32_t *fd)
sym_drm_intel_bo_unreference(bo);
}
+static void
+_intel_manager_destroy()
+{
+ sym_drm_intel_bufmgr_destroy(buffer_manager->priv);
+}
+
static Eina_Bool
_intel_buffer_manager_setup(int fd)
{
SYM(drm_intel_lib, drm_intel_gem_bo_map_gtt);
SYM(drm_intel_lib, drm_intel_bo_alloc_tiled);
SYM(drm_intel_lib, drm_intel_bo_unreference);
+ SYM(drm_intel_lib, drm_intel_bufmgr_destroy);
SYM(drm_intel_lib, drmPrimeHandleToFD);
if (fail) goto err;
buffer_manager->map = _intel_map;
buffer_manager->unmap = _intel_unmap;
buffer_manager->discard = _intel_discard;
+ buffer_manager->manager_destroy = _intel_manager_destroy;
+ buffer_manager->dl_handle = drm_intel_lib;
return EINA_TRUE;
sym_exynos_bo_destroy(bo);
}
+static void
+_exynos_manager_destroy()
+{
+ sym_exynos_device_destroy(buffer_manager->priv);
+}
+
static Eina_Bool
_exynos_buffer_manager_setup(int fd)
{
SYM(drm_exynos_lib, exynos_bo_create);
SYM(drm_exynos_lib, exynos_bo_map);
SYM(drm_exynos_lib, exynos_bo_destroy);
+ SYM(drm_exynos_lib, exynos_device_destroy);
SYM(drm_exynos_lib, drmPrimeHandleToFD);
if (fail) goto err;
buffer_manager->map = _exynos_map;
buffer_manager->unmap = _exynos_unmap;
buffer_manager->discard = _exynos_discard;
-
+ buffer_manager->manager_destroy = _exynos_manager_destroy;
+ buffer_manager->dl_handle = drm_exynos_lib;
return EINA_TRUE;
err:
}
static void
+_buffer_manager_destroy(void)
+{
+ if (!buffer_manager) return;
+
+ if (buffer_manager->manager_destroy) buffer_manager->manager_destroy();
+ free(buffer_manager);
+ buffer_manager = NULL;
+ close(drm_fd);
+}
+
+static void
buffer_release(void *data, struct wl_buffer *buffer EINA_UNUSED)
{
Dmabuf_Buffer *b = data;
if (!b) b = s->current;
if (!b) goto out;
- if (!b->mapping) b->mapping = b->bm->map(b);
+ if (!b->mapping) b->mapping = buffer_manager->map(b);
if (!b->mapping) goto out;
epd = eo_data_scope_get(surf->info->evas, EVAS_CANVAS_CLASS);
for (y = 0; y < h; y++)
memcpy(new_data + y * w * 4, old_data + y * b->stride, w * 4);
surf->funcs.post(surf, NULL, 0);
- b->bm->unmap(b);
+ buffer_manager->unmap(b);
out:
_internal_evas_dmabuf_surface_destroy(s);
+ _buffer_manager_destroy();
}
static void
static void
_evas_dmabuf_buffer_unlock(Dmabuf_Buffer *b)
{
- b->bm->unmap(b);
+ buffer_manager->unmap(b);
b->mapping = NULL;
b->locked = EINA_FALSE;
}
b->surface = NULL;
return;
}
- b->bm->discard(b);
+ /* The buffer manager may have been destroyed already if we're
+ * doing fallback */
+ if (buffer_manager) buffer_manager->discard(b);
if (b->wl_buffer) wl_buffer_destroy(b->wl_buffer);
b->wl_buffer = NULL;
free(b);
if (h) *h = b->h;
if (b->locked) return b->mapping;
- ptr = b->bm->map(b);
+ ptr = buffer_manager->map(b);
if (!ptr)
return NULL;
out = calloc(1, sizeof(Dmabuf_Buffer));
if (!out) return NULL;
- out->bm = bm;
-
out->surface = s;
out->bh = bm->alloc(bm, "name", w, h, &out->stride, &out->fd);
if (!out->bh)