summaryrefslogtreecommitdiffstats
path: root/src/gbm
diff options
context:
space:
mode:
Diffstat (limited to 'src/gbm')
-rw-r--r--src/gbm/Makefile14
-rw-r--r--src/gbm/backends/Makefile14
-rw-r--r--src/gbm/backends/Makefile.template65
-rw-r--r--src/gbm/backends/dri/Makefile22
-rw-r--r--src/gbm/backends/dri/driver_name.c89
-rw-r--r--src/gbm/backends/dri/gbm_dri.c378
-rw-r--r--src/gbm/backends/dri/gbm_driint.h78
-rw-r--r--src/gbm/main/Makefile90
-rw-r--r--src/gbm/main/backend.c128
-rw-r--r--src/gbm/main/backend.h36
-rw-r--r--src/gbm/main/common.c88
-rw-r--r--src/gbm/main/common.h42
-rw-r--r--src/gbm/main/common_drm.h48
-rw-r--r--src/gbm/main/gbm.c190
-rw-r--r--src/gbm/main/gbm.h100
-rw-r--r--src/gbm/main/gbm.pc.in12
-rw-r--r--src/gbm/main/gbmint.h82
17 files changed, 1476 insertions, 0 deletions
diff --git a/src/gbm/Makefile b/src/gbm/Makefile
new file mode 100644
index 00000000000..4769a97b699
--- /dev/null
+++ b/src/gbm/Makefile
@@ -0,0 +1,14 @@
+# src/gbm/Makefile
+
+TOP = ../..
+include $(TOP)/configs/current
+
+SUBDIRS = backends main
+
+
+default install clean:
+ @for dir in $(SUBDIRS) ; do \
+ if [ -d $$dir ] ; then \
+ (cd $$dir && $(MAKE) $@) || exit 1 ; \
+ fi \
+ done
diff --git a/src/gbm/backends/Makefile b/src/gbm/backends/Makefile
new file mode 100644
index 00000000000..97eaac496d2
--- /dev/null
+++ b/src/gbm/backends/Makefile
@@ -0,0 +1,14 @@
+# src/gbm/backends/Makefile
+
+TOP = ../../..
+include $(TOP)/configs/current
+
+SUBDIRS = $(GBM_BACKEND_DIRS)
+
+
+default install clean:
+ @for dir in $(SUBDIRS) ; do \
+ if [ -d $$dir ] ; then \
+ (cd $$dir ; $(MAKE) $@) || exit 1 ; \
+ fi \
+ done
diff --git a/src/gbm/backends/Makefile.template b/src/gbm/backends/Makefile.template
new file mode 100644
index 00000000000..851e5c56217
--- /dev/null
+++ b/src/gbm/backends/Makefile.template
@@ -0,0 +1,65 @@
+# src/gbm/backends/Makefile.template
+#
+# Backends should define
+#
+# GBM_BACKEND, the driver name
+# GBM_SOURCES, the driver sources
+# GBM_INCLUDES, the include pathes
+# GBM_CFLAGS, additional CFLAGS
+# GBM_LIBS, additional LIBS
+#
+# before including this template.
+#
+
+
+GBM_BACKEND_PATH = $(TOP)/$(LIB_DIR)/gbm/$(GBM_BACKEND).so
+GBM_OBJECTS = $(GBM_SOURCES:.c=.o)
+
+# built-in or external
+ifeq ($(GBM_BUILTIN), true)
+GBM_TARGET = lib$(GBM_BACKEND).a
+GBM_INSTALL =
+else
+GBM_TARGET = $(GBM_BACKEND_PATH)
+GBM_INSTALL = install-so
+endif
+
+default: depend $(GBM_TARGET) $(GBM_EXTRA_TARGETS)
+
+$(GBM_BACKEND_PATH): $(GBM_BACKEND).so
+ @$(INSTALL) -d $(TOP)/$(LIB_DIR)/gbm
+ $(INSTALL) $< $(TOP)/$(LIB_DIR)/gbm
+
+$(GBM_BACKEND).so: $(GBM_OBJECTS) Makefile $(TOP)/src/gbm/backends/Makefile.template
+ @$(MKLIB) -o $(GBM_BACKEND).so -noprefix \
+ -linker '$(CC)' -ldflags '-L$(TOP)/$(LIB_DIR) $(LDFLAGS)' \
+ $(MKLIB_OPTIONS) \
+ $(GBM_OBJECTS) $(GBM_LIBS) -l$(GBM_LIB)
+
+lib$(GBM_BACKEND).a: $(GBM_OBJECTS) Makefile $(TOP)/src/gbm/backends/Makefile.template
+ @$(MKLIB) -o $(GBM_BACKEND) -static $(GBM_OBJECTS)
+
+.c.o:
+ $(CC) -c $(GBM_INCLUDES) $(CFLAGS) $(GBM_CFLAGS) $< -o $@
+
+install-so: $(GBM_BACKEND_PATH)
+ $(INSTALL) -d $(DESTDIR)$(GBM_BACKEND_INSTALL_DIR)
+ $(MINSTALL) $(GBM_BACKEND_PATH) $(DESTDIR)$(GBM_BACKEND_INSTALL_DIR)
+
+install: $(GBM_INSTALL) $(GBM_EXTRA_INSTALL)
+
+clean: $(GBM_EXTRA_CLEAN)
+ rm -f $(GBM_BACKEND).so
+ rm -f lib$(GBM_BACKEND).a
+ rm -f $(GBM_OBJECTS)
+ rm -f depend depend.bak
+
+depend: $(GBM_SOURCES) $(GBM_EXTRA_SOURCES)
+ @ echo "running $(MKDEP)"
+ @ rm -f depend
+ @ touch depend
+ $(MKDEP) $(MKDEP_OPTIONS) $(GBM_INCLUDES) $(GBM_SOURCES) \
+ $(GBM_EXTRA_SOURCES) >/dev/null 2>/dev/null
+
+sinclude depend
+# DO NOT DELETE
diff --git a/src/gbm/backends/dri/Makefile b/src/gbm/backends/dri/Makefile
new file mode 100644
index 00000000000..78fb3291227
--- /dev/null
+++ b/src/gbm/backends/dri/Makefile
@@ -0,0 +1,22 @@
+# src/gbm/backends/dri/Makefile
+
+TOP = ../../../..
+include $(TOP)/configs/current
+
+GBM_BACKEND = gbm_dri
+GBM_SOURCES = gbm_dri.c driver_name.c
+
+GBM_INCLUDES = \
+ -I$(TOP)/include \
+ -I$(TOP)/src/gbm/main \
+
+GBM_LIBS = $(LIBUDEV_LIBS) $(LIBDRM_LIB) -L$(TOP)/lib -lglapi
+
+GBM_CFLAGS = \
+ -DDEFAULT_DRIVER_DIR=\"$(DRI_DRIVER_SEARCH_DIR)\" \
+ $(LIBUDEV_CFLAGS) \
+ $(LIBDRM_CFLAGS)
+
+GBM_BUILTIN=true
+
+include ../Makefile.template
diff --git a/src/gbm/backends/dri/driver_name.c b/src/gbm/backends/dri/driver_name.c
new file mode 100644
index 00000000000..2ed209fa438
--- /dev/null
+++ b/src/gbm/backends/dri/driver_name.c
@@ -0,0 +1,89 @@
+/*
+ * Copyright © 2011 Intel Corporation
+ *
+ * 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:
+ * Kristian Høgsberg <[email protected]>
+ * Benjamin Franzke <[email protected]>
+ */
+
+#include <stdio.h>
+#include <string.h>
+
+#include <libudev.h>
+
+#include "gbm_driint.h"
+#define DRIVER_MAP_DRI2_ONLY
+#include "pci_ids/pci_id_driver_map.h"
+
+char *
+dri_fd_get_driver_name(int fd)
+{
+ struct udev *udev;
+ struct udev_device *device, *parent;
+ const char *pci_id;
+ char *driver = NULL;
+ int vendor_id, chip_id, i, j;
+
+ udev = udev_new();
+ device = _gbm_udev_device_new_from_fd(udev, fd);
+ if (device == NULL)
+ return NULL;
+
+ parent = udev_device_get_parent(device);
+ if (parent == NULL) {
+ fprintf(stderr, "gbm: could not get parent device");
+ goto out;
+ }
+
+ pci_id = udev_device_get_property_value(parent, "PCI_ID");
+ if (pci_id == NULL ||
+ sscanf(pci_id, "%x:%x", &vendor_id, &chip_id) != 2) {
+ fprintf(stderr, "gbm: malformed or no PCI ID");
+ goto out;
+ }
+
+ for (i = 0; driver_map[i].driver; i++) {
+ if (vendor_id != driver_map[i].vendor_id)
+ continue;
+ if (driver_map[i].num_chips_ids == -1) {
+ driver = strdup(driver_map[i].driver);
+ _gbm_log("pci id for %d: %04x:%04x, driver %s",
+ fd, vendor_id, chip_id, driver);
+ goto out;
+ }
+
+ for (j = 0; j < driver_map[i].num_chips_ids; j++)
+ if (driver_map[i].chip_ids[j] == chip_id) {
+ driver = strdup(driver_map[i].driver);
+ _gbm_log("pci id for %d: %04x:%04x, driver %s",
+ fd, vendor_id, chip_id, driver);
+ goto out;
+ }
+ }
+
+out:
+ udev_device_unref(device);
+ udev_unref(udev);
+
+ return driver;
+}
diff --git a/src/gbm/backends/dri/gbm_dri.c b/src/gbm/backends/dri/gbm_dri.c
new file mode 100644
index 00000000000..6bb7848d830
--- /dev/null
+++ b/src/gbm/backends/dri/gbm_dri.c
@@ -0,0 +1,378 @@
+/*
+ * Copyright © 2011 Intel Corporation
+ *
+ * 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:
+ * Benjamin Franzke <[email protected]>
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stddef.h>
+#include <stdint.h>
+#include <string.h>
+#include <limits.h>
+
+#include <sys/types.h>
+#include <unistd.h>
+#include <dlfcn.h>
+
+#include <GL/gl.h> /* dri_interface needs GL types */
+#include <GL/internal/dri_interface.h>
+
+#include "gbm_driint.h"
+
+#include "gbmint.h"
+
+static __DRIimage *
+dri_lookup_egl_image(__DRIscreen *screen, void *image, void *data)
+{
+ struct gbm_dri_device *dri = data;
+
+ if (dri->lookup_image == NULL)
+ return NULL;
+
+ return dri->lookup_image(screen, image, dri->lookup_user_data);
+}
+
+const __DRIuseInvalidateExtension use_invalidate = {
+ { __DRI_USE_INVALIDATE, 1 }
+};
+
+const __DRIimageLookupExtension image_lookup_extension = {
+ { __DRI_IMAGE_LOOKUP, 1 },
+ dri_lookup_egl_image
+};
+
+struct dri_extension_match {
+ const char *name;
+ int version;
+ int offset;
+};
+
+static struct dri_extension_match dri_core_extensions[] = {
+ { __DRI_IMAGE, 1, offsetof(struct gbm_dri_device, image) },
+ { NULL, 0, 0 }
+};
+
+static struct dri_extension_match gbm_dri_device_extensions[] = {
+ { __DRI_CORE, 1, offsetof(struct gbm_dri_device, core) },
+ { __DRI_DRI2, 1, offsetof(struct gbm_dri_device, dri2) },
+ { NULL, 0, 0 }
+};
+
+static int
+dri_bind_extensions(struct gbm_dri_device *dri,
+ struct dri_extension_match *matches,
+ const __DRIextension **extensions)
+{
+ int i, j, ret = 0;
+ void *field;
+
+ for (i = 0; extensions[i]; i++) {
+ for (j = 0; matches[j].name; j++) {
+ if (strcmp(extensions[i]->name, matches[j].name) == 0 &&
+ extensions[i]->version >= matches[j].version) {
+ field = ((char *) dri + matches[j].offset);
+ *(const __DRIextension **) field = extensions[i];
+ }
+ }
+ }
+
+ for (j = 0; matches[j].name; j++) {
+ field = ((char *) dri + matches[j].offset);
+ if (*(const __DRIextension **) field == NULL) {
+ ret = -1;
+ }
+ }
+
+ return ret;
+}
+
+static int
+dri_load_driver(struct gbm_dri_device *dri)
+{
+ const __DRIextension **extensions;
+ char path[PATH_MAX], *search_paths, *p, *next, *end;
+
+ search_paths = NULL;
+ if (geteuid() == getuid()) {
+ /* don't allow setuid apps to use GBM_DRIVERS_PATH */
+ search_paths = getenv("GBM_DRIVERS_PATH");
+ }
+ if (search_paths == NULL)
+ search_paths = DEFAULT_DRIVER_DIR;
+
+ dri->driver = NULL;
+ end = search_paths + strlen(search_paths);
+ for (p = search_paths; p < end && dri->driver == NULL; p = next + 1) {
+ int len;
+ next = strchr(p, ':');
+ if (next == NULL)
+ next = end;
+
+ len = next - p;
+#if GLX_USE_TLS
+ snprintf(path, sizeof path,
+ "%.*s/tls/%s_dri.so", len, p, dri->base.driver_name);
+ dri->driver = dlopen(path, RTLD_NOW | RTLD_GLOBAL);
+#endif
+ if (dri->driver == NULL) {
+ snprintf(path, sizeof path,
+ "%.*s/%s_dri.so", len, p, dri->base.driver_name);
+ dri->driver = dlopen(path, RTLD_NOW | RTLD_GLOBAL);
+ if (dri->driver == NULL)
+ fprintf(stderr, "failed to open %s: %s\n", path, dlerror());
+ }
+ }
+
+ if (dri->driver == NULL) {
+ fprintf(stderr, "gbm: failed to open any driver (search paths %s)",
+ search_paths);
+ return -1;
+ }
+
+ extensions = dlsym(dri->driver, __DRI_DRIVER_EXTENSIONS);
+ if (extensions == NULL) {
+ fprintf(stderr, "gbm: driver exports no extensions (%s)", dlerror());
+ dlclose(dri->driver);
+ return -1;
+ }
+
+
+ if (dri_bind_extensions(dri, gbm_dri_device_extensions, extensions) < 0) {
+ dlclose(dri->driver);
+ fprintf(stderr, "failed to bind extensions\n");
+ return -1;
+ }
+
+ return 0;
+}
+
+static int
+dri_screen_create(struct gbm_dri_device *dri)
+{
+ const __DRIextension **extensions;
+ int ret = 0;
+
+ dri->base.driver_name = dri_fd_get_driver_name(dri->base.base.fd);
+ if (dri->base.driver_name == NULL)
+ return -1;
+
+ ret = dri_load_driver(dri);
+ if (ret) {
+ fprintf(stderr, "failed to load driver: %s\n", dri->base.driver_name);
+ return ret;
+ };
+
+ dri->extensions[0] = &image_lookup_extension.base;
+ dri->extensions[1] = &use_invalidate.base;
+ dri->extensions[2] = NULL;
+
+ if (dri->dri2 == NULL)
+ return -1;
+
+ dri->screen = dri->dri2->createNewScreen(0, dri->base.base.fd,
+ dri->extensions,
+ &dri->driver_configs, dri);
+
+ extensions = dri->core->getExtensions(dri->screen);
+ if (dri_bind_extensions(dri, dri_core_extensions, extensions) < 0) {
+ ret = -1;
+ goto free_screen;
+ }
+
+ dri->lookup_image = NULL;
+ dri->lookup_user_data = NULL;
+
+ return 0;
+
+free_screen:
+ dri->core->destroyScreen(dri->screen);
+
+ return ret;
+}
+
+static int
+gbm_dri_is_format_supported(struct gbm_device *gbm,
+ enum gbm_bo_format format,
+ uint32_t usage)
+{
+ switch (format) {
+ case GBM_BO_FORMAT_XRGB8888:
+ break;
+ case GBM_BO_FORMAT_ARGB8888:
+ if (usage & GBM_BO_USE_SCANOUT)
+ return 0;
+ break;
+ default:
+ return 0;
+ }
+
+ if (usage & GBM_BO_USE_CURSOR_64X64 &&
+ usage & GBM_BO_USE_RENDERING)
+ return 0;
+
+ return 1;
+}
+
+static void
+gbm_dri_bo_destroy(struct gbm_bo *_bo)
+{
+ struct gbm_dri_device *dri = gbm_dri_device(_bo->gbm);
+ struct gbm_dri_bo *bo = gbm_dri_bo(_bo);
+
+ dri->image->destroyImage(bo->image);
+ free(bo);
+}
+
+static struct gbm_bo *
+gbm_dri_bo_create_from_egl_image(struct gbm_device *gbm,
+ void *egl_dpy, void *egl_img,
+ uint32_t width, uint32_t height,
+ uint32_t usage)
+{
+ struct gbm_dri_device *dri = gbm_dri_device(gbm);
+ struct gbm_dri_bo *bo;
+
+ (void) egl_dpy;
+
+ if (dri->lookup_image == NULL)
+ return NULL;
+
+ bo = calloc(1, sizeof *bo);
+ if (bo == NULL)
+ return NULL;
+
+ bo->base.base.gbm = gbm;
+ bo->base.base.width = width;
+ bo->base.base.height = height;
+
+ __DRIimage *tmp = dri->lookup_image(dri->screen, egl_img,
+ dri->lookup_user_data);
+
+ bo->image = dri->image->dupImage(tmp, bo);
+ if (bo->image == NULL)
+ return NULL;
+
+ dri->image->queryImage(bo->image, __DRI_IMAGE_ATTRIB_HANDLE,
+ &bo->base.base.handle.s32);
+ dri->image->queryImage(bo->image, __DRI_IMAGE_ATTRIB_STRIDE,
+ (int *) &bo->base.base.pitch);
+
+ return &bo->base.base;
+}
+
+static struct gbm_bo *
+gbm_dri_bo_create(struct gbm_device *gbm,
+ uint32_t width, uint32_t height,
+ enum gbm_bo_format format, uint32_t usage)
+{
+ struct gbm_dri_device *dri = gbm_dri_device(gbm);
+ struct gbm_dri_bo *bo;
+ int dri_format;
+ unsigned dri_use = 0;
+
+ bo = calloc(1, sizeof *bo);
+ if (bo == NULL)
+ return NULL;
+
+ bo->base.base.gbm = gbm;
+ bo->base.base.width = width;
+ bo->base.base.height = height;
+
+ switch (format) {
+ case GBM_BO_FORMAT_XRGB8888:
+ dri_format = __DRI_IMAGE_FORMAT_XRGB8888;
+ break;
+ case GBM_BO_FORMAT_ARGB8888:
+ dri_format = __DRI_IMAGE_FORMAT_ARGB8888;
+ break;
+ default:
+ return NULL;
+ }
+
+ if (usage & GBM_BO_USE_SCANOUT)
+ dri_use |= __DRI_IMAGE_USE_SCANOUT;
+ if (usage & GBM_BO_USE_CURSOR_64X64)
+ dri_use |= __DRI_IMAGE_USE_CURSOR;
+
+ bo->image =
+ dri->image->createImage(dri->screen,
+ width, height,
+ dri_format, dri_use,
+ bo);
+ if (bo->image == NULL)
+ return NULL;
+
+ dri->image->queryImage(bo->image, __DRI_IMAGE_ATTRIB_HANDLE,
+ &bo->base.base.handle.s32);
+ dri->image->queryImage(bo->image, __DRI_IMAGE_ATTRIB_STRIDE,
+ (int *) &bo->base.base.pitch);
+
+ return &bo->base.base;
+}
+
+static void
+dri_destroy(struct gbm_device *gbm)
+{
+ struct gbm_dri_device *dri = gbm_dri_device(gbm);
+
+ dri->core->destroyScreen(dri->screen);
+ free(dri->driver_configs);
+ dlclose(dri->driver);
+ free(dri->base.driver_name);
+
+ free(dri);
+}
+
+static struct gbm_device *
+dri_device_create(int fd)
+{
+ struct gbm_dri_device *dri;
+ int ret;
+
+ dri = calloc(1, sizeof *dri);
+
+ dri->base.base.fd = fd;
+ dri->base.base.bo_create = gbm_dri_bo_create;
+ dri->base.base.bo_create_from_egl_image = gbm_dri_bo_create_from_egl_image;
+ dri->base.base.is_format_supported = gbm_dri_is_format_supported;
+ dri->base.base.bo_destroy = gbm_dri_bo_destroy;
+ dri->base.base.destroy = dri_destroy;
+
+ dri->base.type = GBM_DRM_DRIVER_TYPE_DRI;
+ dri->base.base.name = "drm";
+
+ ret = dri_screen_create(dri);
+ if (ret) {
+ free(dri);
+ return NULL;
+ }
+
+ return &dri->base.base;
+}
+
+struct gbm_backend gbm_dri_backend = {
+ .backend_name = "dri",
+ .create_device = dri_device_create,
+};
diff --git a/src/gbm/backends/dri/gbm_driint.h b/src/gbm/backends/dri/gbm_driint.h
new file mode 100644
index 00000000000..c5b5e17a4ee
--- /dev/null
+++ b/src/gbm/backends/dri/gbm_driint.h
@@ -0,0 +1,78 @@
+/*
+ * Copyright © 2011 Intel Corporation
+ *
+ * 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:
+ * Benjamin Franzke <[email protected]>
+ */
+
+#ifndef _GBM_DRI_INTERNAL_H_
+#define _GBM_DRI_INTERNAL_H_
+
+#include "gbmint.h"
+
+#include "common.h"
+#include "common_drm.h"
+
+#include <GL/gl.h> /* dri_interface needs GL types */
+#include "GL/internal/dri_interface.h"
+
+struct gbm_dri_device {
+ struct gbm_drm_device base;
+
+ void *driver;
+
+ __DRIscreen *screen;
+
+ __DRIcoreExtension *core;
+ __DRIdri2Extension *dri2;
+ __DRIimageExtension *image;
+
+ const __DRIconfig **driver_configs;
+ const __DRIextension *extensions[3];
+
+ __DRIimage *(*lookup_image)(__DRIscreen *screen, void *image, void *data);
+ void *lookup_user_data;
+};
+
+struct gbm_dri_bo {
+ struct gbm_drm_bo base;
+
+ __DRIimage *image;
+};
+
+static inline struct gbm_dri_device *
+gbm_dri_device(struct gbm_device *gbm)
+{
+ return (struct gbm_dri_device *) gbm;
+}
+
+static inline struct gbm_dri_bo *
+gbm_dri_bo(struct gbm_bo *bo)
+{
+ return (struct gbm_dri_bo *) bo;
+}
+
+char *
+dri_fd_get_driver_name(int fd);
+
+#endif
diff --git a/src/gbm/main/Makefile b/src/gbm/main/Makefile
new file mode 100644
index 00000000000..5130b9b5df2
--- /dev/null
+++ b/src/gbm/main/Makefile
@@ -0,0 +1,90 @@
+# src/gbm/main/Makefile
+
+TOP = ../../..
+include $(TOP)/configs/current
+
+INCLUDE_DIRS = -I$(TOP)/include
+
+HEADERS = \
+ common.h \
+ backend.h \
+ gbmint.h \
+ gbm.h
+
+SOURCES = \
+ gbm.c \
+ backend.c \
+ common.c
+
+OBJECTS = $(SOURCES:.c=.o)
+
+# use dl*() to load drivers
+LOCAL_CFLAGS = $(LIBUDEV_CFLAGS) $(DLOPEN_CFLAGS) \
+ -D_OS_UNIX=1 -DMODULEDIR='"$(GBM_BACKEND_INSTALL_DIR)"'
+LOCAL_LIBS =
+
+# Builtin backends
+ifeq ($(filter dri, $(GBM_BACKEND_DIRS)),dri)
+LOCAL_LIBS += $(TOP)/src/gbm/backends/dri/libgbm_dri.a
+endif
+
+.c.o:
+ $(CC) -c $(INCLUDE_DIRS) $(CFLAGS) $(LOCAL_CFLAGS) $< -o $@
+
+
+default: depend library
+
+
+library: $(TOP)/$(LIB_DIR)/libgbm.so
+
+$(TOP)/$(LIB_DIR)/libgbm.so: $(OBJECTS) $(LOCAL_LIBS)
+ $(MKLIB) -o gbm -linker '$(CC)' -ldflags '$(LDFLAGS)' \
+ -major 1 -minor 0 \
+ -install $(TOP)/$(LIB_DIR) $(MKLIB_OPTIONS) \
+ -L$(TOP)/$(LIB_DIR) $(GBM_LIB_DEPS) \
+ $(OBJECTS) $(LOCAL_LIBS)
+
+install-headers:
+ $(INSTALL) -d $(DESTDIR)$(INSTALL_INC_DIR)/
+ $(INSTALL) -m 644 $(TOP)/src/gbm/main/gbm.h \
+ $(DESTDIR)$(INSTALL_INC_DIR)
+
+
+PKG_CONFIG_DIR = $(INSTALL_LIB_DIR)/pkgconfig
+
+gbm_pcedit = sed \
+ -e 's,@INSTALL_DIR@,$(INSTALL_DIR),' \
+ -e 's,@INSTALL_LIB_DIR@,$(INSTALL_LIB_DIR),' \
+ -e 's,@INSTALL_INC_DIR@,$(INSTALL_INC_DIR),' \
+ -e 's,@VERSION@,0.0.0,' \
+ -e 's,@GBM_PC_REQ_PRIV@,$(GBM_PC_REQ_PRIV),' \
+ -e 's,@GBM_PC_LIB_PRIV@,$(GBM_PC_LIB_PRIV),' \
+ -e 's,@GBM_PC_CFLAGS@,$(GBM_PC_CFLAGS),' \
+ -e 's,@GBM_LIB@,$(GBM_LIB),'
+
+gbm.pc: gbm.pc.in
+ $(gbm_pcedit) $< > $@
+
+install: default install-headers gbm.pc
+ $(INSTALL) -d $(DESTDIR)$(INSTALL_LIB_DIR)
+ $(MINSTALL) $(TOP)/$(LIB_DIR)/libgbm.so* \
+ $(DESTDIR)$(INSTALL_LIB_DIR)
+ $(INSTALL) -d $(DESTDIR)$(PKG_CONFIG_DIR)
+ $(INSTALL) -m 644 gbm.pc $(DESTDIR)$(PKG_CONFIG_DIR)
+
+clean:
+ -rm -f *.o
+ -rm -f depend depend.bak
+ -rm -f gbm.pc
+
+
+depend: $(SOURCES) $(HEADERS)
+ @ echo "running $(MKDEP)"
+ @ rm -f depend
+ @ touch depend
+ $(MKDEP) $(MKDEP_OPTIONS) $(DEFINES) $(INCLUDE_DIRS) \
+ $(SOURCES) $(HEADERS) > /dev/null 2>/dev/null
+
+
+-include depend
+# DO NOT DELETE
diff --git a/src/gbm/main/backend.c b/src/gbm/main/backend.c
new file mode 100644
index 00000000000..aceb6621f96
--- /dev/null
+++ b/src/gbm/main/backend.c
@@ -0,0 +1,128 @@
+/*
+ * Copyright © 2011 Intel Corporation
+ *
+ * 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:
+ * Benjamin Franzke <[email protected]>
+ */
+
+#include <stdio.h>
+#include <stddef.h>
+#include <stdlib.h>
+#include <string.h>
+#include <limits.h>
+#include <dlfcn.h>
+
+#include "backend.h"
+
+#define ARRAY_SIZE(a) (sizeof(a)/sizeof((a)[0]))
+
+extern const struct gbm_backend gbm_dri_backend;
+
+struct backend_desc {
+ const char *name;
+ const struct gbm_backend *builtin;
+};
+
+static const struct backend_desc backends[] = {
+ { "gbm_dri.so", &gbm_dri_backend },
+ { "gbm_gallium_drm.so", NULL },
+};
+
+static const void *
+load_backend(const struct backend_desc *backend)
+{
+ char path[PATH_MAX];
+ const void *init = NULL;
+ void *module;
+ const char *name;
+ const char *entrypoint = "gbm_backend";
+
+ if (backend == NULL)
+ return NULL;
+
+ name = backend->name;
+
+ if (backend->builtin) {
+ init = backend->builtin;
+ } else {
+ if (name[0] != '/')
+ snprintf(path, sizeof path, MODULEDIR "/%s", name);
+ else
+ snprintf(path, sizeof path, "%s", name);
+
+ module = dlopen(path, RTLD_NOW | RTLD_GLOBAL);
+ if (!module) {
+ fprintf(stderr,
+ "failed to load module: %s\n", dlerror());
+ return NULL;
+ }
+
+ init = dlsym(module, entrypoint);
+ if (!init)
+ return NULL;
+ }
+
+ return init;
+}
+
+static const struct backend_desc *
+find_backend(const char *name)
+{
+ const struct backend_desc *backend = NULL;
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(backends); ++i) {
+ if (strcmp(backends[i].name, name) == 0) {
+ backend = &backends[i];
+ break;
+ }
+ }
+
+ return backend;
+}
+
+struct gbm_device *
+_gbm_create_device(int fd)
+{
+ const struct gbm_backend *backend = NULL;
+ struct gbm_device *dev = NULL;
+ int i;
+ const char *b;
+
+ b = getenv("GBM_BACKEND");
+ if (b)
+ backend = load_backend(find_backend(b));
+
+ if (backend)
+ dev = backend->create_device(fd);
+
+ for (i = 0; i < ARRAY_SIZE(backends) && dev == NULL; ++i) {
+ backend = load_backend(&backends[i]);
+ if (backend == NULL)
+ continue;
+
+ dev = backend->create_device(fd);
+ }
+
+ return dev;
+}
diff --git a/src/gbm/main/backend.h b/src/gbm/main/backend.h
new file mode 100644
index 00000000000..4a643750333
--- /dev/null
+++ b/src/gbm/main/backend.h
@@ -0,0 +1,36 @@
+/*
+ * Copyright © 2011 Intel Corporation
+ *
+ * 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:
+ * Benjamin Franzke <[email protected]>
+ */
+
+#ifndef MODULE_H_
+#define MODULE_H_
+
+#include "gbmint.h"
+
+struct gbm_device *
+_gbm_create_device(int fd);
+
+#endif
diff --git a/src/gbm/main/common.c b/src/gbm/main/common.c
new file mode 100644
index 00000000000..f02162df292
--- /dev/null
+++ b/src/gbm/main/common.c
@@ -0,0 +1,88 @@
+/*
+ * Copyright © 2011 Intel Corporation
+ *
+ * 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:
+ * Benjamin Franzke <[email protected]>
+ */
+
+#include <stdio.h>
+#include <string.h>
+
+#include <libudev.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+
+#include "common.h"
+#include "gbmint.h"
+
+GBM_EXPORT struct udev_device *
+_gbm_udev_device_new_from_fd(struct udev *udev, int fd)
+{
+ struct udev_device *device;
+ struct stat buf;
+
+ if (fstat(fd, &buf) < 0) {
+ fprintf(stderr, "gbm: failed to stat fd %d", fd);
+ return NULL;
+ }
+
+ device = udev_device_new_from_devnum(udev, 'c', buf.st_rdev);
+ if (device == NULL) {
+ fprintf(stderr,
+ "gbm: could not create udev device for fd %d", fd);
+ return NULL;
+ }
+
+ return device;
+}
+
+GBM_EXPORT char *
+_gbm_fd_get_device_name(int fd)
+{
+ struct udev *udev;
+ struct udev_device *device;
+ const char *const_device_name;
+ char *device_name = NULL;
+
+ udev = udev_new();
+ device = _gbm_udev_device_new_from_fd(udev, fd);
+ if (device == NULL)
+ return NULL;
+
+ const_device_name = udev_device_get_devnode(device);
+ if (!const_device_name)
+ goto out;
+ device_name = strdup(const_device_name);
+
+out:
+ udev_device_unref(device);
+ udev_unref(udev);
+
+ return device_name;
+}
+
+GBM_EXPORT void
+_gbm_log(const char *fmt_str, ...)
+{
+}
diff --git a/src/gbm/main/common.h b/src/gbm/main/common.h
new file mode 100644
index 00000000000..1fcdfcac30d
--- /dev/null
+++ b/src/gbm/main/common.h
@@ -0,0 +1,42 @@
+/*
+ * Copyright © 2011 Intel Corporation
+ *
+ * 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:
+ * Benjamin Franzke <[email protected]>
+ */
+
+#ifndef _COMMON_H_
+#define _COMMON_H_
+
+#include <libudev.h>
+
+struct udev_device *
+_gbm_udev_device_new_from_fd(struct udev *udev, int fd);
+
+char *
+_gbm_fd_get_device_name(int fd);
+
+void
+_gbm_log(const char *fmt_str, ...);
+
+#endif
diff --git a/src/gbm/main/common_drm.h b/src/gbm/main/common_drm.h
new file mode 100644
index 00000000000..d28c3f01f48
--- /dev/null
+++ b/src/gbm/main/common_drm.h
@@ -0,0 +1,48 @@
+/*
+ * Copyright © 2011 Intel Corporation
+ *
+ * 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:
+ * Benjamin Franzke <[email protected]>
+ */
+
+#ifndef _COMMON_DRM_H_
+#define _COMMON_DRM_H_
+
+#include "gbmint.h"
+
+enum gbm_drm_driver_type {
+ GBM_DRM_DRIVER_TYPE_DRI,
+ GBM_DRM_DRIVER_TYPE_GALLIUM,
+};
+
+struct gbm_drm_device {
+ struct gbm_device base;
+ enum gbm_drm_driver_type type;
+ char *driver_name;
+};
+
+struct gbm_drm_bo {
+ struct gbm_bo base;
+};
+
+#endif
diff --git a/src/gbm/main/gbm.c b/src/gbm/main/gbm.c
new file mode 100644
index 00000000000..8440b2c6ae3
--- /dev/null
+++ b/src/gbm/main/gbm.c
@@ -0,0 +1,190 @@
+/*
+ * Copyright © 2011 Intel Corporation
+ *
+ * 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:
+ * Benjamin Franzke <[email protected]>
+ */
+
+#define _BSD_SOURCE
+
+#include <stddef.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdint.h>
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+
+#include "gbm.h"
+#include "gbmint.h"
+#include "common.h"
+#include "backend.h"
+
+#define ARRAY_SIZE(a) (sizeof(a)/sizeof((a)[0]))
+
+struct gbm_device *devices[16];
+
+static int device_num = 0;
+
+GBM_EXPORT int
+gbm_device_get_fd(struct gbm_device *gbm)
+{
+ return gbm->fd;
+}
+
+/* FIXME: maybe superfluous, use udev subclass from the fd? */
+GBM_EXPORT const char *
+gbm_device_get_backend_name(struct gbm_device *gbm)
+{
+ return gbm->name;
+}
+
+int
+gbm_device_is_format_supported(struct gbm_device *gbm,
+ enum gbm_bo_format format,
+ uint32_t usage)
+{
+ return gbm->is_format_supported(gbm, format, usage);
+}
+
+GBM_EXPORT void
+gbm_device_destroy(struct gbm_device *gbm)
+{
+ gbm->refcount--;
+ if (gbm->refcount == 0)
+ gbm->destroy(gbm);
+}
+
+GBM_EXPORT struct gbm_device *
+_gbm_mesa_get_device(int fd)
+{
+ struct gbm_device *gbm = NULL;
+ struct stat buf;
+ dev_t dev;
+ int i;
+
+ if (fd < 0 || fstat(fd, &buf) < 0 || !S_ISCHR(buf.st_mode)) {
+ fprintf(stderr, "_gbm_mesa_get_device: invalid fd: %d\n", fd);
+ return NULL;
+ }
+
+ for (i = 0; i < device_num; ++i) {
+ dev = devices[i]->stat.st_rdev;
+ if (major(dev) == major(buf.st_rdev) &&
+ minor(dev) == minor(buf.st_rdev)) {
+ gbm = devices[i];
+ gbm->refcount++;
+ break;
+ }
+ }
+
+ return gbm;
+}
+
+GBM_EXPORT struct gbm_device *
+gbm_create_device(int fd)
+{
+ struct gbm_device *gbm = NULL;
+ struct stat buf;
+
+ if (fd < 0 || fstat(fd, &buf) < 0 || !S_ISCHR(buf.st_mode)) {
+ fprintf(stderr, "gbm_create_device: invalid fd: %d\n", fd);
+ return NULL;
+ }
+
+ if (device_num == 0)
+ memset(devices, 0, sizeof devices);
+
+ gbm = _gbm_create_device(fd);
+ if (gbm == NULL)
+ return NULL;
+
+ gbm->dummy = gbm_create_device;
+ gbm->stat = buf;
+ gbm->refcount = 1;
+
+ if (device_num < ARRAY_SIZE(devices)-1)
+ devices[device_num++] = gbm;
+
+ return gbm;
+}
+
+GBM_EXPORT unsigned int
+gbm_bo_get_width(struct gbm_bo *bo)
+{
+ return bo->width;
+}
+
+GBM_EXPORT unsigned int
+gbm_bo_get_height(struct gbm_bo *bo)
+{
+ return bo->height;
+}
+
+GBM_EXPORT uint32_t
+gbm_bo_get_pitch(struct gbm_bo *bo)
+{
+ return bo->pitch;
+}
+
+GBM_EXPORT union gbm_bo_handle
+gbm_bo_get_handle(struct gbm_bo *bo)
+{
+ return bo->handle;
+}
+
+GBM_EXPORT void
+gbm_bo_destroy(struct gbm_bo *bo)
+{
+ bo->gbm->bo_destroy(bo);
+}
+
+GBM_EXPORT struct gbm_bo *
+gbm_bo_create(struct gbm_device *gbm,
+ uint32_t width, uint32_t height,
+ enum gbm_bo_format format, uint32_t usage)
+{
+ if (width == 0 || height == 0)
+ return NULL;
+
+ if (usage & GBM_BO_USE_CURSOR_64X64 &&
+ (width != 64 || height != 64))
+ return NULL;
+
+ return gbm->bo_create(gbm, width, height, format, usage);
+}
+
+GBM_EXPORT struct gbm_bo *
+gbm_bo_create_from_egl_image(struct gbm_device *gbm,
+ void *egl_dpy, void *egl_image,
+ uint32_t width, uint32_t height,
+ uint32_t usage)
+{
+ if (width == 0 || height == 0)
+ return NULL;
+
+ return gbm->bo_create_from_egl_image(gbm, egl_dpy, egl_image,
+ width, height, usage);
+}
diff --git a/src/gbm/main/gbm.h b/src/gbm/main/gbm.h
new file mode 100644
index 00000000000..d79a03e4b3f
--- /dev/null
+++ b/src/gbm/main/gbm.h
@@ -0,0 +1,100 @@
+/*
+ * Copyright © 2011 Intel Corporation
+ *
+ * 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:
+ * Benjamin Franzke <[email protected]>
+ */
+
+#ifndef _GBM_H_
+#define _GBM_H_
+
+#define __GBM__ 1
+
+#include <stdint.h>
+
+struct gbm_device;
+struct gbm_bo;
+
+union gbm_bo_handle {
+ void *ptr;
+ int32_t s32;
+ uint32_t u32;
+ int64_t s64;
+ uint64_t u64;
+};
+
+enum gbm_bo_format {
+ GBM_BO_FORMAT_XRGB8888,
+ GBM_BO_FORMAT_ARGB8888,
+};
+
+enum gbm_bo_flags {
+ GBM_BO_USE_SCANOUT = (1 << 0),
+ GBM_BO_USE_CURSOR_64X64 = (1 << 1),
+ GBM_BO_USE_RENDERING = (1 << 2),
+};
+
+int
+gbm_device_get_fd(struct gbm_device *gbm);
+
+const char *
+gbm_device_get_backend_name(struct gbm_device *gbm);
+
+int
+gbm_device_is_format_supported(struct gbm_device *gbm,
+ enum gbm_bo_format format,
+ uint32_t usage);
+
+void
+gbm_device_destroy(struct gbm_device *gbm);
+
+struct gbm_device *
+gbm_create_device(int fd);
+
+struct gbm_bo *
+gbm_bo_create(struct gbm_device *gbm,
+ uint32_t width, uint32_t height,
+ enum gbm_bo_format format, uint32_t flags);
+
+struct gbm_bo *
+gbm_bo_create_from_egl_image(struct gbm_device *gbm,
+ void *egl_dpy, void *egl_img,
+ uint32_t width, uint32_t height,
+ uint32_t usage);
+
+uint32_t
+gbm_bo_get_width(struct gbm_bo *bo);
+
+uint32_t
+gbm_bo_get_height(struct gbm_bo *bo);
+
+uint32_t
+gbm_bo_get_pitch(struct gbm_bo *bo);
+
+union gbm_bo_handle
+gbm_bo_get_handle(struct gbm_bo *bo);
+
+void
+gbm_bo_destroy(struct gbm_bo *bo);
+
+#endif
diff --git a/src/gbm/main/gbm.pc.in b/src/gbm/main/gbm.pc.in
new file mode 100644
index 00000000000..76299e77f83
--- /dev/null
+++ b/src/gbm/main/gbm.pc.in
@@ -0,0 +1,12 @@
+prefix=@INSTALL_DIR@
+exec_prefix=${prefix}
+libdir=@INSTALL_LIB_DIR@
+includedir=@INSTALL_INC_DIR@
+
+Name: gbm
+Description: Mesa gbm library
+Requires.private: @GBM_PC_REQ_PRIV@
+Version: @VERSION@
+Libs: -L${libdir} -l@GBM_LIB@
+Libs.private: @GBM_PC_LIB_PRIV@
+Cflags: -I${includedir} @GBM_PC_CFLAGS@
diff --git a/src/gbm/main/gbmint.h b/src/gbm/main/gbmint.h
new file mode 100644
index 00000000000..fb8db804c1b
--- /dev/null
+++ b/src/gbm/main/gbmint.h
@@ -0,0 +1,82 @@
+/*
+ * Copyright © 2011 Intel Corporation
+ *
+ * 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:
+ * Benjamin Franzke <[email protected]>
+ */
+
+#ifndef INTERNAL_H_
+#define INTERNAL_H_
+
+#include "gbm.h"
+#include <sys/stat.h>
+
+/* GCC visibility */
+#if defined(__GNUC__) && __GNUC__ >= 4
+#define GBM_EXPORT __attribute__ ((visibility("default")))
+#else
+#define GBM_EXPORT
+#endif
+
+struct gbm_device {
+ /* Hack to make a gbm_device detectable by its first element. */
+ struct gbm_device *(*dummy)(int);
+
+ int fd;
+ const char *name;
+ unsigned int refcount;
+ struct stat stat;
+
+ void (*destroy)(struct gbm_device *gbm);
+ int (*is_format_supported)(struct gbm_device *gbm,
+ enum gbm_bo_format format,
+ uint32_t usage);
+
+ struct gbm_bo *(*bo_create)(struct gbm_device *gbm,
+ uint32_t width, uint32_t height,
+ enum gbm_bo_format format,
+ uint32_t usage);
+ struct gbm_bo *(*bo_create_from_egl_image)(struct gbm_device *gbm,
+ void *egl_dpy, void *egl_img,
+ uint32_t width, uint32_t height,
+ uint32_t usage);
+ void (*bo_destroy)(struct gbm_bo *bo);
+};
+
+struct gbm_bo {
+ struct gbm_device *gbm;
+ uint32_t width;
+ uint32_t height;
+ uint32_t pitch;
+ union gbm_bo_handle handle;
+};
+
+struct gbm_backend {
+ const char *backend_name;
+ struct gbm_device *(*create_device)(int fd);
+};
+
+GBM_EXPORT struct gbm_device *
+_gbm_mesa_get_device(int fd);
+
+#endif