summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--gralloc_drm.c25
-rw-r--r--gralloc_drm.h3
-rw-r--r--gralloc_drm_handle.h22
-rw-r--r--gralloc_drm_intel.c47
-rw-r--r--gralloc_drm_kms.c58
-rw-r--r--gralloc_drm_priv.h5
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 {