diff options
-rw-r--r-- | gralloc_drm.c | 25 | ||||
-rw-r--r-- | gralloc_drm.h | 3 | ||||
-rw-r--r-- | gralloc_drm_handle.h | 22 | ||||
-rw-r--r-- | gralloc_drm_intel.c | 47 | ||||
-rw-r--r-- | gralloc_drm_kms.c | 58 | ||||
-rw-r--r-- | gralloc_drm_priv.h | 5 |
6 files changed, 111 insertions, 49 deletions
diff --git a/gralloc_drm.c b/gralloc_drm.c index 5912ba6..27a49c5 100644 --- a/gralloc_drm.c +++ b/gralloc_drm.c @@ -262,6 +262,7 @@ static struct gralloc_drm_handle_t *create_bo_handle(int width, handle->height = height; handle->format = format; handle->usage = usage; + handle->plane_mask = 0; return handle; } @@ -279,6 +280,8 @@ struct gralloc_drm_bo_t *gralloc_drm_bo_create(struct gralloc_drm_t *drm, if (!handle) return NULL; + handle->plane_mask = planes_for_format(drm, format); + bo = drm->drv->alloc(drm->drv, handle); if (!bo) { free(handle); @@ -348,6 +351,28 @@ buffer_handle_t gralloc_drm_bo_get_handle(struct gralloc_drm_bo_t *bo, int *stri return &bo->handle->base; } +int gralloc_drm_get_gem_handle(buffer_handle_t _handle) +{ + struct gralloc_drm_handle_t *handle = gralloc_drm_handle(_handle); + return (handle) ? handle->name : 0; +} + +/* + * Query YUV component offsets for a buffer handle + */ +void gralloc_drm_resolve_format(buffer_handle_t _handle, + uint32_t *pitches, uint32_t *offsets, uint32_t *handles) +{ + struct gralloc_drm_handle_t *handle = gralloc_drm_handle(_handle); + struct gralloc_drm_bo_t *bo = (struct gralloc_drm_bo_t *) handle->data; + struct gralloc_drm_t *drm = bo->drm; + + /* if handle exists and driver implements resolve_format */ + if (handle && drm->drv->resolve_format) + drm->drv->resolve_format(drm->drv, bo, + pitches, offsets, handles); +} + /* * Lock a bo. XXX thread-safety? */ diff --git a/gralloc_drm.h b/gralloc_drm.h index 716173a..8059907 100644 --- a/gralloc_drm.h +++ b/gralloc_drm.h @@ -120,6 +120,9 @@ void gralloc_drm_bo_decref(struct gralloc_drm_bo_t *bo); struct gralloc_drm_bo_t *gralloc_drm_bo_from_handle(buffer_handle_t handle); buffer_handle_t gralloc_drm_bo_get_handle(struct gralloc_drm_bo_t *bo, int *stride); +int gralloc_drm_get_gem_handle(buffer_handle_t handle); +void gralloc_drm_resolve_format(buffer_handle_t _handle, uint32_t *pitches, uint32_t *offsets, uint32_t *handles); +unsigned int planes_for_format(struct gralloc_drm_t *drm, int hal_format); int gralloc_drm_bo_lock(struct gralloc_drm_bo_t *bo, int x, int y, int w, int h, int enable_write, void **addr); void gralloc_drm_bo_unlock(struct gralloc_drm_bo_t *bo); diff --git a/gralloc_drm_handle.h b/gralloc_drm_handle.h index 621f500..70a1ae8 100644 --- a/gralloc_drm_handle.h +++ b/gralloc_drm_handle.h @@ -31,7 +31,7 @@ struct gralloc_drm_handle_t { native_handle_t base; #define GRALLOC_DRM_HANDLE_MAGIC 0x12345678 -#define GRALLOC_DRM_HANDLE_NUM_INTS 9 +#define GRALLOC_DRM_HANDLE_NUM_INTS 10 #define GRALLOC_DRM_HANDLE_NUM_FDS 0 int magic; @@ -40,6 +40,8 @@ struct gralloc_drm_handle_t { int format; int usage; + unsigned int plane_mask; /* planes that support handle */ + int name; /* the name of the bo */ int stride; /* the stride in bytes */ @@ -61,22 +63,4 @@ static inline struct gralloc_drm_handle_t *gralloc_drm_handle(buffer_handle_t _h return handle; } -static inline void gralloc_drm_yuv_offsets(buffer_handle_t _handle, - int *y, int *u, int *v) -{ - struct gralloc_drm_handle_t *handle = gralloc_drm_handle(_handle); - if (handle && *y && *u && *v) { - *y = 0; - switch (handle->format) { - case HAL_PIXEL_FORMAT_YV12: - *v = handle->stride * handle->height; - *u = *v + handle->height/2; - break; - case HAL_PIXEL_FORMAT_DRM_NV12: - *u = *v = handle->stride * handle->height; - break; - } - } -} - #endif /* _GRALLOC_DRM_HANDLE_H_ */ diff --git a/gralloc_drm_intel.c b/gralloc_drm_intel.c index 649c6ff..725334e 100644 --- a/gralloc_drm_intel.c +++ b/gralloc_drm_intel.c @@ -190,6 +190,52 @@ batch_init(struct intel_info *info) return ret; } +static void intel_resolve_format(struct gralloc_drm_drv_t *drv, + struct gralloc_drm_bo_t *bo, + uint32_t *pitches, uint32_t *offsets, uint32_t *handles) +{ + /* + * TODO - should take account hw specific padding, alignment + * for camera, video decoder etc. + */ + + struct intel_buffer *ib = (struct intel_buffer *) bo; + + memset(pitches, 0, 4 * sizeof(uint32_t)); + memset(offsets, 0, 4 * sizeof(uint32_t)); + memset(handles, 0, 4 * sizeof(uint32_t)); + + pitches[0] = ib->base.handle->stride; + handles[0] = ib->base.fb_handle; + + switch(ib->base.handle->format) { + case HAL_PIXEL_FORMAT_YV12: + + // U and V stride are half of Y plane + pitches[2] = pitches[0]/2; + pitches[1] = pitches[0]/2; + + // like I420 but U and V are in reverse order + offsets[2] = offsets[0] + + pitches[0] * ib->base.handle->height; + offsets[1] = offsets[2] + + pitches[2] * ib->base.handle->height/2; + + handles[1] = handles[2] = handles[0]; + break; + + case HAL_PIXEL_FORMAT_DRM_NV12: + + // U and V are interleaved in 2nd plane + pitches[1] = pitches[0]; + offsets[1] = offsets[0] + + pitches[0] * ib->base.handle->height; + + handles[1] = handles[0]; + break; + } +} + static void intel_copy(struct gralloc_drm_drv_t *drv, struct gralloc_drm_bo_t *dst, struct gralloc_drm_bo_t *src, @@ -593,6 +639,7 @@ struct gralloc_drm_drv_t *gralloc_drm_drv_create_for_intel(int fd) info->base.map = intel_map; info->base.unmap = intel_unmap; info->base.copy = intel_copy; + info->base.resolve_format = intel_resolve_format; return &info->base; } diff --git a/gralloc_drm_kms.c b/gralloc_drm_kms.c index 3310807..91e7e63 100644 --- a/gralloc_drm_kms.c +++ b/gralloc_drm_kms.c @@ -73,42 +73,40 @@ static unsigned int drm_format_from_hal(int hal_format) static int resolve_drm_format(struct gralloc_drm_bo_t *bo, uint32_t *pitches, uint32_t *offsets, uint32_t *handles) { - memset(pitches, 0, 4 * sizeof(uint32_t)); - memset(offsets, 0, 4 * sizeof(uint32_t)); - memset(handles, 0, 4 * sizeof(uint32_t)); + struct gralloc_drm_t *drm = bo->drm; pitches[0] = bo->handle->stride; handles[0] = bo->fb_handle; - int format = drm_format_from_hal(bo->handle->format); - - // handle 'special formats' - switch(bo->handle->format) { - case HAL_PIXEL_FORMAT_YV12: + /* driver takes care of HW specific padding, alignment etc. */ + if (drm->drv->resolve_format) + drm->drv->resolve_format(drm->drv, bo, + pitches, offsets, handles); - // U and V stride are half of Y plane - pitches[2] = pitches[0]/2; - pitches[1] = pitches[0]/2; + return drm_format_from_hal(bo->handle->format); +} - // like I420 but U and V are in reverse order - offsets[2] = offsets[0] + - pitches[0] * bo->handle->height; - offsets[1] = offsets[2] + - pitches[2] * bo->handle->height/2; +/* + * Returns planes that are supported for a particular format + */ +unsigned int planes_for_format(struct gralloc_drm_t *drm, + int hal_format) +{ + unsigned int i, j, mask = 0; + unsigned int drm_format = drm_format_from_hal(hal_format); + struct gralloc_drm_plane_t *plane = drm->planes; - handles[1] = handles[2] = handles[0]; - break; + /* no planes available */ + if (!plane) + return 0; - case HAL_PIXEL_FORMAT_DRM_NV12: + /* iterate through planes, mark those that match format */ + for (i=0; i<drm->plane_resources->count_planes; i++, plane++) + for (j=0; j<plane->drm_plane->count_formats; j++) + if (plane->drm_plane->formats[j] == drm_format) + mask |= (2 << plane->drm_plane->plane_id); - // U and V are interleaved in 2nd plane - pitches[1] = pitches[0]; - offsets[1] = offsets[0] + - pitches[0] * bo->handle->height; - handles[1] = handles[0]; - break; - } - return format; + return mask; } /* @@ -116,9 +114,9 @@ static int resolve_drm_format(struct gralloc_drm_bo_t *bo, */ int gralloc_drm_bo_add_fb(struct gralloc_drm_bo_t *bo) { - uint32_t pitches[4]; - uint32_t offsets[4]; - uint32_t handles[4]; + uint32_t pitches[4] = { 0, 0, 0, 0 }; + uint32_t offsets[4] = { 0, 0, 0, 0 }; + uint32_t handles[4] = { 0, 0, 0, 0 }; if (bo->fb_id) return 0; diff --git a/gralloc_drm_priv.h b/gralloc_drm_priv.h index 7a93a1e..eb2450d 100644 --- a/gralloc_drm_priv.h +++ b/gralloc_drm_priv.h @@ -126,6 +126,11 @@ struct gralloc_drm_drv_t { struct gralloc_drm_bo_t *dst, struct gralloc_drm_bo_t *src, short x1, short y1, short x2, short y2); + + /* query component offsets, strides and handles for a format */ + void (*resolve_format)(struct gralloc_drm_drv_t *drv, + struct gralloc_drm_bo_t *bo, + uint32_t *pitches, uint32_t *offsets, uint32_t *handles); }; struct gralloc_drm_bo_t { |