From 5dddfa859139597d6751f0d982ef84901d1298e0 Mon Sep 17 00:00:00 2001 From: Chia-I Wu Date: Sat, 19 Mar 2011 22:07:51 +0800 Subject: gralloc: add multiple driver support --- src/gralloc/gralloc_gem.c | 63 ++++++++++++++++++++++++++++++++++++++++++ src/gralloc/gralloc_gem.h | 51 ++++++++++++++++++++++++++++------ src/gralloc/gralloc_gem_i915.c | 50 ++++++++++++++------------------- src/gralloc/gralloc_gem_pipe.c | 53 +++++++++++++++-------------------- src/gralloc/gralloc_mod.h | 1 + 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; -- cgit v1.2.3