summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChia-I Wu <olvaffe@gmail.com>2011-03-19 22:07:51 +0800
committerChia-I Wu <olvaffe@gmail.com>2011-03-25 03:30:43 +0800
commit5dddfa859139597d6751f0d982ef84901d1298e0 (patch)
treea2c01fc097b433f636008ae02ce52dab4f22dc29
parent7baac8d734fa6b5f4b47fb960993bbde12749cbf (diff)
gralloc: add multiple driver support
-rw-r--r--src/gralloc/gralloc_gem.c63
-rw-r--r--src/gralloc/gralloc_gem.h51
-rw-r--r--src/gralloc/gralloc_gem_i915.c50
-rw-r--r--src/gralloc/gralloc_gem_pipe.c53
-rw-r--r--src/gralloc/gralloc_mod.h1
5 files changed, 150 insertions, 68 deletions
diff --git a/src/gralloc/gralloc_gem.c b/src/gralloc/gralloc_gem.c
index a3df97f89b..5b2ddebe55 100644
--- a/src/gralloc/gralloc_gem.c
+++ b/src/gralloc/gralloc_gem.c
@@ -117,3 +117,66 @@ drm_gem_validate(buffer_handle_t handle)
return bo;
}
+
+static const struct drm_gem_drv *
+get_drv_from_fd(int fd)
+{
+ const struct drm_gem_drv *drv = NULL;
+ drmVersionPtr version;
+
+ version = drmGetVersion(fd);
+ if (!version) {
+ LOGE("invalid DRM fd");
+ return NULL;
+ }
+
+ if (version->name) {
+#ifdef ENABLE_INTEL
+ if (!drv && !strcmp(version->name, "intel"))
+ drv = &drm_gem_drv_intel;
+#endif
+#ifdef ENABLE_VMWGFX
+ if (!drv && !strcmp(version->name, "vmwgfx"))
+ drv = &drm_gem_drv_pipe;
+#endif
+ }
+
+ if (!drv)
+ LOGE("unknown driver: %s", (version->name) ? version->name : "NULL");
+
+ drmFreeVersion(version);
+
+ return drv;
+}
+
+static int
+drm_gem_drv_init_locked(struct drm_module_t *drm)
+{
+ const struct drm_gem_drv *drv;
+ int ret;
+
+ if (drm->gem)
+ return 0;
+
+ drv = get_drv_from_fd(drm->fd);
+ if (!drv)
+ return -EINVAL;
+
+ ret = drv->init(drm);
+ if (!ret)
+ drm->drv = (void *) drv;
+
+ return ret;
+}
+
+int
+drm_gem_drv_init(struct drm_module_t *drm)
+{
+ int ret;
+
+ pthread_mutex_lock(&drm->mutex);
+ ret = drm_gem_drv_init_locked(drm);
+ pthread_mutex_unlock(&drm->mutex);
+
+ return ret;
+}
diff --git a/src/gralloc/gralloc_gem.h b/src/gralloc/gralloc_gem.h
index e6ef176efa..c82ea2b720 100644
--- a/src/gralloc/gralloc_gem.h
+++ b/src/gralloc/gralloc_gem.h
@@ -56,22 +56,55 @@ drm_gem_validate(buffer_handle_t handle);
struct drm_bo_t *
drm_gem_create_bo(int width, int height, int format, int usage);
-
int
drm_gem_drv_init(struct drm_module_t *drm);
-struct drm_bo_t *
+
+struct drm_gem_drv {
+ int (*init)(struct drm_module_t *drm);
+
+ struct drm_bo_t *(*alloc)(struct drm_module_t *drm, int width, int height,
+ int format, int usage, int *stride);
+
+ void (*free)(struct drm_module_t *drm, struct drm_bo_t *bo);
+
+ int (*map)(struct drm_module_t *drm, struct drm_bo_t *bo,
+ int x, int y, int w, int h, int enable_write, void **addr);
+
+ void (*unmap)(struct drm_module_t *drm, struct drm_bo_t *bo);
+};
+
+extern const struct drm_gem_drv drm_gem_drv_intel;
+extern const struct drm_gem_drv drm_gem_drv_pipe;
+
+static inline struct drm_bo_t *
drm_gem_drv_alloc(struct drm_module_t *drm, int width, int height,
- int format, int usage, int *stride);
+ int format, int usage, int *stride)
+{
+ const struct drm_gem_drv *drv = (const struct drm_gem_drv *) drm->drv;
+ return drv->alloc(drm, width, height, format, usage, stride);
+}
-void
-drm_gem_drv_free(struct drm_module_t *drm, struct drm_bo_t *bo);
+static inline void
+drm_gem_drv_free(struct drm_module_t *drm, struct drm_bo_t *bo)
+{
+ const struct drm_gem_drv *drv = (const struct drm_gem_drv *) drm->drv;
+ drv->free(drm, bo);
+}
-int
+static inline int
drm_gem_drv_map(struct drm_module_t *drm, struct drm_bo_t *bo,
- int x, int y, int w, int h, int enable_write, void **addr);
+ int x, int y, int w, int h, int enable_write, void **addr)
+{
+ const struct drm_gem_drv *drv = (const struct drm_gem_drv *) drm->drv;
+ return drv->map(drm, bo, x, y, w, h, enable_write, addr);
+}
-void
-drm_gem_drv_unmap(struct drm_module_t *drm, struct drm_bo_t *bo);
+static inline void
+drm_gem_drv_unmap(struct drm_module_t *drm, struct drm_bo_t *bo)
+{
+ const struct drm_gem_drv *drv = (const struct drm_gem_drv *) drm->drv;
+ drv->unmap(drm, bo);
+}
#endif /* _GRALLOC_GEM_H_ */
diff --git a/src/gralloc/gralloc_gem_i915.c b/src/gralloc/gralloc_gem_i915.c
index 2822fe5c12..9159df68c5 100644
--- a/src/gralloc/gralloc_gem_i915.c
+++ b/src/gralloc/gralloc_gem_i915.c
@@ -11,7 +11,7 @@
#include "gralloc_gem.h"
static void
-drm_gem_drv_init_features_locked(struct drm_module_t *drm)
+drm_gem_intel_init_features(struct drm_module_t *drm)
{
struct drm_i915_getparam gp;
@@ -40,38 +40,22 @@ drm_gem_drv_init_features_locked(struct drm_module_t *drm)
/* XXX there is a bug in the kernel module */
drm->mode_page_flip = 0;
-
}
static int
-drm_gem_drv_init_locked(struct drm_module_t *drm)
+drm_gem_intel_init(struct drm_module_t *drm)
{
- if (drm->gem)
- return 0;
-
drm->gem = (void *) drm_intel_bufmgr_gem_init(drm->fd, 16 * 1024);
if (!drm->gem) {
LOGE("failed to create buffer manager");
return -ENOMEM;
}
- drm_gem_drv_init_features_locked(drm);
+ drm_gem_intel_init_features(drm);
return 0;
}
-int
-drm_gem_drv_init(struct drm_module_t *drm)
-{
- int ret;
-
- pthread_mutex_lock(&drm->mutex);
- ret = drm_gem_drv_init_locked(drm);
- pthread_mutex_unlock(&drm->mutex);
-
- return ret;
-}
-
static uint32_t
drm_gem_get_tiling(struct drm_bo_t *bo)
{
@@ -89,9 +73,9 @@ drm_gem_get_tiling(struct drm_bo_t *bo)
return tiling;
}
-struct drm_bo_t *
-drm_gem_drv_alloc(struct drm_module_t *drm, int width, int height,
- int format, int usage, int *stride)
+static struct drm_bo_t *
+drm_gem_intel_alloc(struct drm_module_t *drm, int width, int height,
+ int format, int usage, int *stride)
{
drm_intel_bufmgr *bufmgr = (drm_intel_bufmgr *) drm->gem;
struct drm_bo_t *bo;
@@ -161,16 +145,16 @@ drm_gem_drv_alloc(struct drm_module_t *drm, int width, int height,
return bo;
}
-void
-drm_gem_drv_free(struct drm_module_t *drm, struct drm_bo_t *bo)
+static void
+drm_gem_intel_free(struct drm_module_t *drm, struct drm_bo_t *bo)
{
drm_intel_bo_unreference((drm_intel_bo *) bo->data);
free(bo);
}
-int
-drm_gem_drv_map(struct drm_module_t *drm, struct drm_bo_t *bo,
- int x, int y, int w, int h, int enable_write, void **addr)
+static int
+drm_gem_intel_map(struct drm_module_t *drm, struct drm_bo_t *bo,
+ int x, int y, int w, int h, int enable_write, void **addr)
{
drm_intel_bo *ibo = (drm_intel_bo *) bo->data;
int err;
@@ -198,8 +182,8 @@ drm_gem_drv_map(struct drm_module_t *drm, struct drm_bo_t *bo,
return err;
}
-void
-drm_gem_drv_unmap(struct drm_module_t *drm, struct drm_bo_t *bo)
+static void
+drm_gem_intel_unmap(struct drm_module_t *drm, struct drm_bo_t *bo)
{
drm_intel_bo *ibo = (drm_intel_bo *) bo->data;
@@ -209,3 +193,11 @@ drm_gem_drv_unmap(struct drm_module_t *drm, struct drm_bo_t *bo)
else
drm_intel_bo_unmap(ibo);
}
+
+const struct drm_gem_drv drm_gem_drv_intel = {
+ .init = drm_gem_intel_init,
+ .alloc = drm_gem_intel_alloc,
+ .free = drm_gem_intel_free,
+ .map = drm_gem_intel_map,
+ .unmap = drm_gem_intel_unmap,
+};
diff --git a/src/gralloc/gralloc_gem_pipe.c b/src/gralloc/gralloc_gem_pipe.c
index 99a8461627..1a1856a53b 100644
--- a/src/gralloc/gralloc_gem_pipe.c
+++ b/src/gralloc/gralloc_gem_pipe.c
@@ -26,7 +26,7 @@ struct drm_pipe_buffer {
};
static void
-drm_gem_drv_init_features_locked(struct drm_module_t *drm)
+drm_gem_pipe_init_features(struct drm_module_t *drm)
{
drm->mode_dirty_fb = 0;
drm->mode_page_flip = 0;
@@ -38,13 +38,10 @@ drm_gem_drv_init_features_locked(struct drm_module_t *drm)
}
static int
-drm_gem_drv_init_locked(struct drm_module_t *drm)
+drm_gem_pipe_init(struct drm_module_t *drm)
{
struct drm_pipe_manager *pm;
- if (drm->gem)
- return 0;
-
pm = CALLOC(1, sizeof(*pm));
if (!pm)
return -ENOMEM;
@@ -60,23 +57,11 @@ drm_gem_drv_init_locked(struct drm_module_t *drm)
drm->gem = (void *) pm;
- drm_gem_drv_init_features_locked(drm);
+ drm_gem_pipe_init_features(drm);
return 0;
}
-int
-drm_gem_drv_init(struct drm_module_t *drm)
-{
- int ret;
-
- pthread_mutex_lock(&drm->mutex);
- ret = drm_gem_drv_init_locked(drm);
- pthread_mutex_unlock(&drm->mutex);
-
- return ret;
-}
-
static enum pipe_format
get_pipe_format(int format)
{
@@ -144,7 +129,7 @@ get_pipe_buffer(struct drm_pipe_manager *pm, int width, int height,
if (templ.format == PIPE_FORMAT_NONE ||
!pm->screen->is_format_supported(pm->screen, templ.format,
- templ.target, 0, templ.bind, 0)) {
+ templ.target, 0, templ.bind)) {
LOGE("unsupported format 0x%x", format);
return NULL;
}
@@ -198,9 +183,9 @@ fail:
return NULL;
}
-struct drm_bo_t *
-drm_gem_drv_alloc(struct drm_module_t *drm, int width, int height,
- int format, int usage, int *stride)
+static struct drm_bo_t *
+drm_gem_pipe_alloc(struct drm_module_t *drm, int width, int height,
+ int format, int usage, int *stride)
{
struct drm_pipe_manager *pm = (struct drm_pipe_manager *) drm->gem;
struct drm_pipe_buffer *buf;
@@ -232,8 +217,8 @@ drm_gem_drv_alloc(struct drm_module_t *drm, int width, int height,
return bo;
}
-void
-drm_gem_drv_free(struct drm_module_t *drm, struct drm_bo_t *bo)
+static void
+drm_gem_pipe_free(struct drm_module_t *drm, struct drm_bo_t *bo)
{
struct drm_pipe_manager *pm = (struct drm_pipe_manager *) drm->gem;
struct drm_pipe_buffer *buf = (struct drm_pipe_buffer *) bo->data;
@@ -250,9 +235,9 @@ drm_gem_drv_free(struct drm_module_t *drm, struct drm_bo_t *bo)
free(bo);
}
-int
-drm_gem_drv_map(struct drm_module_t *drm, struct drm_bo_t *bo,
- int x, int y, int w, int h, int enable_write, void **addr)
+static int
+drm_gem_pipe_map(struct drm_module_t *drm, struct drm_bo_t *bo,
+ int x, int y, int w, int h, int enable_write, void **addr)
{
struct drm_pipe_manager *pm = (struct drm_pipe_manager *) drm->gem;
struct drm_pipe_buffer *buf = (struct drm_pipe_buffer *) bo->data;
@@ -313,8 +298,8 @@ drm_gem_drv_map(struct drm_module_t *drm, struct drm_bo_t *bo,
return ret;
}
-void
-drm_gem_drv_unmap(struct drm_module_t *drm, struct drm_bo_t *bo)
+static void
+drm_gem_pipe_unmap(struct drm_module_t *drm, struct drm_bo_t *bo)
{
struct drm_pipe_manager *pm = (struct drm_pipe_manager *) drm->gem;
struct drm_pipe_buffer *buf = (struct drm_pipe_buffer *) bo->data;
@@ -327,7 +312,15 @@ drm_gem_drv_unmap(struct drm_module_t *drm, struct drm_bo_t *bo)
pipe_transfer_destroy(pm->context, buf->transfer);
buf->transfer = NULL;
- pm->context->flush(pm->context, PIPE_FLUSH_RENDER_CACHE, NULL);
+ pm->context->flush(pm->context, NULL);
pthread_mutex_unlock(&pm->mutex);
}
+
+const struct drm_gem_drv drm_gem_drv_pipe = {
+ .init = drm_gem_pipe_init,
+ .alloc = drm_gem_pipe_alloc,
+ .free = drm_gem_pipe_free,
+ .map = drm_gem_pipe_map,
+ .unmap = drm_gem_pipe_unmap,
+};
diff --git a/src/gralloc/gralloc_mod.h b/src/gralloc/gralloc_mod.h
index e06ec864ad..176ea63727 100644
--- a/src/gralloc/gralloc_mod.h
+++ b/src/gralloc/gralloc_mod.h
@@ -26,6 +26,7 @@ struct drm_module_t {
#endif
/* initialized by drm_gem_drv_init */
+ void *drv;
void *gem;
int mode_dirty_fb;
int mode_page_flip;