derekf pushed a commit to branch master.

http://git.enlightenment.org/core/efl.git/commit/?id=821aada3c442af82339b01df036fa13aa086491a

commit 821aada3c442af82339b01df036fa13aa086491a
Author: Derek Foreman <der...@osg.samsung.com>
Date:   Thu Jun 2 07:06:26 2016 -0500

    wayland_shm: Add exynos allocator for dmabuf
    
    Allows clients on exynos hardware to allocate GEM buffer objects
    to back DMAbuf buffers.
---
 src/modules/evas/engines/wayland_shm/evas_dmabuf.c |  99 ++++++++++++
 src/static_libs/libdrm/exynos_drm.h                | 172 +++++++++++++++++++++
 src/static_libs/libdrm/exynos_drmif.h              | 112 ++++++++++++++
 3 files changed, 383 insertions(+)

diff --git a/src/modules/evas/engines/wayland_shm/evas_dmabuf.c 
b/src/modules/evas/engines/wayland_shm/evas_dmabuf.c
index 60093ae..3cb112c 100644
--- a/src/modules/evas/engines/wayland_shm/evas_dmabuf.c
+++ b/src/modules/evas/engines/wayland_shm/evas_dmabuf.c
@@ -10,6 +10,10 @@
 #include <intel_bufmgr.h>
 #include <i915_drm.h>
 
+#include <exynos_drm.h>
+#include <exynos_drmif.h>
+#include <sys/mman.h>
+
 #include "linux-dmabuf-unstable-v1-client-protocol.h"
 
 #define SYM(lib, xx)               \
@@ -88,6 +92,11 @@ drm_intel_bo 
*(*sym_drm_intel_bo_alloc_tiled)(drm_intel_bufmgr *mgr, const char
 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);
 
+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;
+
 static Buffer_Handle *
 _intel_alloc(Buffer_Manager *self, const char *name, int w, int h, unsigned 
long *stride, int32_t *fd)
 {
@@ -179,6 +188,95 @@ err:
    return EINA_FALSE;
 }
 
+static Buffer_Handle *
+_exynos_alloc(Buffer_Manager *self, const char *name EINA_UNUSED, int w, int 
h, unsigned long *stride, int32_t *fd)
+{
+   size_t size = w * h * 4;
+   struct exynos_bo *out;
+
+   *stride = w * 4;
+   out = sym_exynos_bo_create(self->priv, size, 0);
+   if (!out) return NULL;
+   /* First try to allocate an mmapable buffer with O_RDWR,
+    * if that fails retry unmappable - if the compositor is
+    * using GL it won't need to mmap the buffer and this can
+    * work - otherwise it'll reject this buffer and we'll
+    * have to fall back to shm rendering.
+    */
+   if (sym_drmPrimeHandleToFD(drm_fd, out->handle,
+                              DRM_CLOEXEC | O_RDWR, fd) != 0)
+     if (sym_drmPrimeHandleToFD(drm_fd, out->handle,
+                                DRM_CLOEXEC, fd) != 0) goto err;
+
+   return (Buffer_Handle *)out;
+
+err:
+   sym_exynos_bo_destroy(out);
+   return NULL;
+}
+
+static void *
+_exynos_map(Dmabuf_Buffer *buf)
+{
+   struct exynos_bo *bo;
+   void *ptr;
+
+   bo = (struct exynos_bo *)buf->bh;
+   ptr = mmap(0, bo->size, PROT_READ | PROT_WRITE, MAP_SHARED, buf->fd, 0);
+   if (ptr == MAP_FAILED) return NULL;
+   return ptr;
+}
+
+static void
+_exynos_unmap(Dmabuf_Buffer *buf)
+{
+   struct exynos_bo *bo;
+
+   bo = (struct exynos_bo *)buf->bh;
+   munmap(buf->mapping, bo->size);
+}
+
+static void
+_exynos_discard(Dmabuf_Buffer *buf)
+{
+   struct exynos_bo *bo;
+
+   bo = (struct exynos_bo *)buf->bh;
+   sym_exynos_bo_destroy(bo);
+}
+
+static Eina_Bool
+_exynos_buffer_manager_setup(int fd)
+{
+   Eina_Bool fail = EINA_FALSE;
+   void *drm_exynos_lib;
+
+   drm_exynos_lib = dlopen("libdrm_exynos.so", RTLD_LAZY | RTLD_GLOBAL);
+   if (!drm_exynos_lib) return EINA_FALSE;
+
+   SYM(drm_exynos_lib, exynos_device_create);
+   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, drmPrimeHandleToFD);
+
+   if (fail) goto err;
+
+   buffer_manager->priv = sym_exynos_device_create(fd);
+   if (!buffer_manager->priv) goto err;
+
+   buffer_manager->alloc = _exynos_alloc;
+   buffer_manager->map = _exynos_map;
+   buffer_manager->unmap = _exynos_unmap;
+   buffer_manager->discard = _exynos_discard;
+
+   return EINA_TRUE;
+
+err:
+   dlclose(drm_exynos_lib);
+   return EINA_FALSE;
+}
+
 static Buffer_Manager *
 _buffer_manager_get(void)
 {
@@ -194,6 +292,7 @@ _buffer_manager_get(void)
    if (fd < 0) goto err_drm;
 
    success = _intel_buffer_manager_setup(fd);
+   if (!success) success = _exynos_buffer_manager_setup(fd);
    if (!success) goto err_bm;
 
    drm_fd = fd;
diff --git a/src/static_libs/libdrm/exynos_drm.h 
b/src/static_libs/libdrm/exynos_drm.h
new file mode 100644
index 0000000..c3af0ac
--- /dev/null
+++ b/src/static_libs/libdrm/exynos_drm.h
@@ -0,0 +1,172 @@
+/* exynos_drm.h
+ *
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd.
+ * Authors:
+ *     Inki Dae <inki....@samsung.com>
+ *     Joonyoung Shim <jy0922.s...@samsung.com>
+ *     Seung-Woo Kim <sw0312....@samsung.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#ifndef _EXYNOS_DRM_H_
+#define _EXYNOS_DRM_H_
+
+#include "drm.h"
+
+/**
+ * User-desired buffer creation information structure.
+ *
+ * @size: user-desired memory allocation size.
+ *     - this size value would be page-aligned internally.
+ * @flags: user request for setting memory type or cache attributes.
+ * @handle: returned a handle to created gem object.
+ *     - this handle will be set by gem module of kernel side.
+ */
+struct drm_exynos_gem_create {
+       uint64_t size;
+       unsigned int flags;
+       unsigned int handle;
+};
+
+/**
+ * A structure to gem information.
+ *
+ * @handle: a handle to gem object created.
+ * @flags: flag value including memory type and cache attribute and
+ *     this value would be set by driver.
+ * @size: size to memory region allocated by gem and this size would
+ *     be set by driver.
+ */
+struct drm_exynos_gem_info {
+       unsigned int handle;
+       unsigned int flags;
+       uint64_t size;
+};
+
+/**
+ * A structure for user connection request of virtual display.
+ *
+ * @connection: indicate whether doing connetion or not by user.
+ * @extensions: if this value is 1 then the vidi driver would need additional
+ *     128bytes edid data.
+ * @edid: the edid data pointer from user side.
+ */
+struct drm_exynos_vidi_connection {
+       unsigned int connection;
+       unsigned int extensions;
+       uint64_t edid;
+};
+
+/* memory type definitions. */
+enum e_drm_exynos_gem_mem_type {
+       /* Physically Continuous memory and used as default. */
+       EXYNOS_BO_CONTIG        = 0 << 0,
+       /* Physically Non-Continuous memory. */
+       EXYNOS_BO_NONCONTIG     = 1 << 0,
+       /* non-cachable mapping and used as default. */
+       EXYNOS_BO_NONCACHABLE   = 0 << 1,
+       /* cachable mapping. */
+       EXYNOS_BO_CACHABLE      = 1 << 1,
+       /* write-combine mapping. */
+       EXYNOS_BO_WC            = 1 << 2,
+       EXYNOS_BO_MASK          = EXYNOS_BO_NONCONTIG | EXYNOS_BO_CACHABLE |
+                                       EXYNOS_BO_WC
+};
+
+struct drm_exynos_g2d_get_ver {
+       __u32   major;
+       __u32   minor;
+};
+
+struct drm_exynos_g2d_cmd {
+       __u32   offset;
+       __u32   data;
+};
+
+enum drm_exynos_g2d_buf_type {
+       G2D_BUF_USERPTR = 1 << 31,
+};
+
+enum drm_exynos_g2d_event_type {
+       G2D_EVENT_NOT,
+       G2D_EVENT_NONSTOP,
+       G2D_EVENT_STOP,         /* not yet */
+};
+
+struct drm_exynos_g2d_userptr {
+       unsigned long userptr;
+       unsigned long size;
+};
+
+struct drm_exynos_g2d_set_cmdlist {
+       __u64                                   cmd;
+       __u64                                   cmd_buf;
+       __u32                                   cmd_nr;
+       __u32                                   cmd_buf_nr;
+
+       /* for g2d event */
+       __u64                                   event_type;
+       __u64                                   user_data;
+};
+
+struct drm_exynos_g2d_exec {
+       __u64                                   async;
+};
+
+#define DRM_EXYNOS_GEM_CREATE          0x00
+/* Reserved 0x04 ~ 0x05 for exynos specific gem ioctl */
+#define DRM_EXYNOS_GEM_GET             0x04
+#define DRM_EXYNOS_VIDI_CONNECTION     0x07
+
+/* G2D */
+#define DRM_EXYNOS_G2D_GET_VER         0x20
+#define DRM_EXYNOS_G2D_SET_CMDLIST     0x21
+#define DRM_EXYNOS_G2D_EXEC            0x22
+
+#define DRM_IOCTL_EXYNOS_GEM_CREATE            DRM_IOWR(DRM_COMMAND_BASE + \
+               DRM_EXYNOS_GEM_CREATE, struct drm_exynos_gem_create)
+
+#define DRM_IOCTL_EXYNOS_GEM_GET       DRM_IOWR(DRM_COMMAND_BASE + \
+               DRM_EXYNOS_GEM_GET,     struct drm_exynos_gem_info)
+
+#define DRM_IOCTL_EXYNOS_VIDI_CONNECTION       DRM_IOWR(DRM_COMMAND_BASE + \
+               DRM_EXYNOS_VIDI_CONNECTION, struct drm_exynos_vidi_connection)
+
+#define DRM_IOCTL_EXYNOS_G2D_GET_VER           DRM_IOWR(DRM_COMMAND_BASE + \
+               DRM_EXYNOS_G2D_GET_VER, struct drm_exynos_g2d_get_ver)
+#define DRM_IOCTL_EXYNOS_G2D_SET_CMDLIST       DRM_IOWR(DRM_COMMAND_BASE + \
+               DRM_EXYNOS_G2D_SET_CMDLIST, struct drm_exynos_g2d_set_cmdlist)
+#define DRM_IOCTL_EXYNOS_G2D_EXEC              DRM_IOWR(DRM_COMMAND_BASE + \
+               DRM_EXYNOS_G2D_EXEC, struct drm_exynos_g2d_exec)
+
+/* EXYNOS specific events */
+#define DRM_EXYNOS_G2D_EVENT           0x80000000
+
+struct drm_exynos_g2d_event {
+       struct drm_event        base;
+       __u64                           user_data;
+       __u32                           tv_sec;
+       __u32                           tv_usec;
+       __u32                           cmdlist_no;
+       __u32                           reserved;
+};
+
+#endif
diff --git a/src/static_libs/libdrm/exynos_drmif.h 
b/src/static_libs/libdrm/exynos_drmif.h
new file mode 100644
index 0000000..626e399
--- /dev/null
+++ b/src/static_libs/libdrm/exynos_drmif.h
@@ -0,0 +1,112 @@
+/*
+ * Copyright (C) 2012 Samsung Electronics Co., Ltd.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 
FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 
THE
+ * SOFTWARE.
+ *
+ * Authors:
+ *    Inki Dae <inki....@samsung.com>
+ */
+
+#ifndef EXYNOS_DRMIF_H_
+#define EXYNOS_DRMIF_H_
+
+#include <xf86drm.h>
+#include <stdint.h>
+#include "exynos_drm.h"
+
+struct exynos_device {
+       int fd;
+};
+
+/*
+ * Exynos Buffer Object structure.
+ *
+ * @dev: exynos device object allocated.
+ * @handle: a gem handle to gem object created.
+ * @flags: indicate memory allocation and cache attribute types.
+ * @size: size to the buffer created.
+ * @vaddr: user space address to a gem buffer mmaped.
+ * @name: a gem global handle from flink request.
+ */
+struct exynos_bo {
+       struct exynos_device    *dev;
+       uint32_t                handle;
+       uint32_t                flags;
+       size_t                  size;
+       void                    *vaddr;
+       uint32_t                name;
+};
+
+#define EXYNOS_EVENT_CONTEXT_VERSION 1
+
+/*
+ * Exynos Event Context structure.
+ *
+ * @base: base context (for core events).
+ * @version: version info similar to the one in 'drmEventContext'.
+ * @g2d_event_handler: handler for G2D events.
+ */
+struct exynos_event_context {
+       drmEventContext base;
+
+       int version;
+
+       void (*g2d_event_handler)(int fd, unsigned int cmdlist_no,
+                                                         unsigned int tv_sec, 
unsigned int tv_usec,
+                                                         void *user_data);
+};
+
+/*
+ * device related functions:
+ */
+struct exynos_device * exynos_device_create(int fd);
+void exynos_device_destroy(struct exynos_device *dev);
+
+/*
+ * buffer-object related functions:
+ */
+struct exynos_bo * exynos_bo_create(struct exynos_device *dev,
+               size_t size, uint32_t flags);
+int exynos_bo_get_info(struct exynos_device *dev, uint32_t handle,
+                       size_t *size, uint32_t *flags);
+void exynos_bo_destroy(struct exynos_bo *bo);
+struct exynos_bo * exynos_bo_from_name(struct exynos_device *dev, uint32_t 
name);
+int exynos_bo_get_name(struct exynos_bo *bo, uint32_t *name);
+uint32_t exynos_bo_handle(struct exynos_bo *bo);
+void * exynos_bo_map(struct exynos_bo *bo);
+int exynos_prime_handle_to_fd(struct exynos_device *dev, uint32_t handle,
+                                       int *fd);
+int exynos_prime_fd_to_handle(struct exynos_device *dev, int fd,
+                                       uint32_t *handle);
+
+/*
+ * Virtual Display related functions:
+ */
+int exynos_vidi_connection(struct exynos_device *dev, uint32_t connect,
+                               uint32_t ext, void *edid);
+
+/*
+ * event handling related functions:
+ */
+int exynos_handle_event(struct exynos_device *dev,
+                               struct exynos_event_context *ctx);
+
+
+#endif /* EXYNOS_DRMIF_H_ */

-- 


Reply via email to