summaryrefslogtreecommitdiffstats
path: root/gralloc_drm_pipe.c
diff options
context:
space:
mode:
authorChia-I Wu <olvaffe@gmail.com>2011-06-13 14:34:21 +0800
committerChia-I Wu <olvaffe@gmail.com>2011-06-13 14:39:20 +0800
commit59eb3d82102ecef9302424196bd665a67b937dc0 (patch)
tree1af0ab44e82fb8dc88e154ef18d0d99d69538055 /gralloc_drm_pipe.c
parenta020bfa161805c661b6a1268be62dd1c6c60f1b2 (diff)
downloadexternal_drm_gralloc-59eb3d82102ecef9302424196bd665a67b937dc0.zip
external_drm_gralloc-59eb3d82102ecef9302424196bd665a67b937dc0.tar.gz
external_drm_gralloc-59eb3d82102ecef9302424196bd665a67b937dc0.tar.bz2
add (untested) copy support to pipe
This is why we love pipe.
Diffstat (limited to 'gralloc_drm_pipe.c')
-rw-r--r--gralloc_drm_pipe.c54
1 files changed, 54 insertions, 0 deletions
diff --git a/gralloc_drm_pipe.c b/gralloc_drm_pipe.c
index 0991287..7572d4d 100644
--- a/gralloc_drm_pipe.c
+++ b/gralloc_drm_pipe.c
@@ -132,6 +132,7 @@ static struct pipe_buffer *get_pipe_buffer_locked(struct pipe_manager *pm,
templ.width0 = handle->width;
templ.height0 = handle->height;
templ.depth0 = 1;
+ templ.array_size = 1;
if (handle->name) {
buf->winsys.type = DRM_API_HANDLE_TYPE_SHARED;
@@ -280,6 +281,58 @@ static void pipe_unmap(struct gralloc_drm_drv_t *drv,
pthread_mutex_unlock(&pm->mutex);
}
+static void pipe_copy(struct gralloc_drm_drv_t *drv,
+ struct gralloc_drm_bo_t *dst_bo,
+ struct gralloc_drm_bo_t *src_bo,
+ short x1, short y1, short x2, short y2)
+{
+ struct pipe_manager *pm = (struct pipe_manager *) drv;
+ struct pipe_buffer *dst = (struct pipe_buffer *) dst_bo;
+ struct pipe_buffer *src = (struct pipe_buffer *) src_bo;
+ struct pipe_box src_box;
+
+ if (dst_bo->handle->width != src_bo->handle->width ||
+ dst_bo->handle->height != src_bo->handle->height ||
+ dst_bo->handle->stride != src_bo->handle->stride ||
+ dst_bo->handle->format != src_bo->handle->format) {
+ LOGE("copy between incompatible buffers");
+ return;
+ }
+
+ if (x1 < 0)
+ x1 = 0;
+ if (y1 < 0)
+ y1 = 0;
+ if (x2 > dst_bo->handle->width)
+ x2 = dst_bo->handle->width;
+ if (y2 > dst_bo->handle->height)
+ y2 = dst_bo->handle->height;
+
+ if (x2 <= x1 || y2 <= y1)
+ return;
+
+ u_box_2d(x1, y1, x2 - x1, y2 - y1, &src_box);
+
+ pthread_mutex_lock(&pm->mutex);
+
+ /* need a context for copying */
+ if (!pm->context) {
+ pm->context = pm->screen->context_create(pm->screen, NULL);
+ if (!pm->context) {
+ LOGE("failed to create pipe context");
+ pthread_mutex_unlock(&pm->mutex);
+ return;
+ }
+ }
+
+ pm->context->resource_copy_region(pm->context,
+ dst->resource, 0, x1, y1, 0,
+ src->resource, 0, &src_box);
+ pm->context->flush(pm->context, NULL);
+
+ pthread_mutex_unlock(&pm->mutex);
+}
+
static void pipe_init_kms_features(struct gralloc_drm_drv_t *drv, struct gralloc_drm_t *drm)
{
struct pipe_manager *pm = (struct pipe_manager *) drv;
@@ -356,6 +409,7 @@ struct gralloc_drm_drv_t *gralloc_drm_drv_create_for_pipe(int fd, const char *na
pm->base.free = pipe_free;
pm->base.map = pipe_map;
pm->base.unmap = pipe_unmap;
+ pm->base.copy = pipe_copy;
return &pm->base;
}