#include <linux/stddef.h>
#include <errno.h>
#include <sys/mman.h>
+#include <fcntl.h>
+#include <unistd.h>
#include <xf86drm.h>
uint32_t handle;
uint32_t name; /* flink global handle (DRI2 name) */
uint64_t offset; /* offset to mmap() */
+ int fd; /* dmabuf handle */
};
struct omap_device * omap_device_new(int fd)
static struct omap_bo * omap_bo_new_impl(struct omap_device *dev,
union omap_gem_size size, uint32_t flags)
{
- struct omap_bo *bo;
+ struct omap_bo *bo = NULL;
struct drm_omap_gem_new req = {
.size = size,
.flags = flags,
return NULL;
}
+/* import a buffer from dmabuf fd, does not take ownership of the
+ * fd so caller should close() the fd when it is otherwise done
+ * with it (even if it is still using the 'struct omap_bo *')
+ */
+struct omap_bo * omap_bo_from_dmabuf(struct omap_device *dev, int fd)
+{
+ struct omap_bo *bo;
+ struct drm_prime_handle req = {
+ .fd = fd,
+ };
+ int ret;
+
+ bo = calloc(sizeof(*bo), 1);
+ if (!bo) {
+ goto fail;
+ }
+
+ ret = drmIoctl(dev->fd, DRM_IOCTL_PRIME_FD_TO_HANDLE, &req);
+ if (ret) {
+ goto fail;
+ }
+
+ bo->dev = dev;
+ bo->handle = req.handle;
+
+ return bo;
+
+fail:
+ free(bo);
+ return NULL;
+}
+
/* destroy a buffer object */
void omap_bo_del(struct omap_bo *bo)
{
munmap(bo->map, bo->size);
}
+ if (bo->fd) {
+ close(bo->fd);
+ }
+
if (bo->handle) {
struct drm_gem_close req = {
.handle = bo->handle,
return bo->handle;
}
+/* caller owns the dmabuf fd that is returned and is responsible
+ * to close() it when done
+ */
+int omap_bo_dmabuf(struct omap_bo *bo)
+{
+ if (!bo->fd) {
+ struct drm_prime_handle req = {
+ .handle = bo->handle,
+ .flags = DRM_CLOEXEC,
+ };
+ int ret;
+
+ ret = drmIoctl(bo->dev->fd, DRM_IOCTL_PRIME_HANDLE_TO_FD, &req);
+ if (ret) {
+ return ret;
+ }
+
+ bo->fd = req.fd;
+ }
+ return dup(bo->fd);
+}
+
uint32_t omap_bo_size(struct omap_bo *bo)
{
if (!bo->size) {