diff options
-rw-r--r-- | gralloc_drm_intel.c | 71 | ||||
-rw-r--r-- | gralloc_drm_kms.c | 10 | ||||
-rw-r--r-- | gralloc_drm_pipe.c | 27 | ||||
-rw-r--r-- | gralloc_drm_priv.h | 9 |
4 files changed, 74 insertions, 43 deletions
diff --git a/gralloc_drm_intel.c b/gralloc_drm_intel.c index 725334e..50293b9 100644 --- a/gralloc_drm_intel.c +++ b/gralloc_drm_intel.c @@ -130,7 +130,8 @@ batch_flush(struct intel_info *info) ALOGE("failed to subdata batch"); goto fail; } - ret = drm_intel_bo_exec(info->batch_ibo, size, NULL, 0, 0); + ret = drm_intel_bo_mrb_exec(info->batch_ibo, size, + NULL, 0, 0, I915_EXEC_BLT); if (ret) { ALOGE("failed to exec batch"); goto fail; @@ -236,10 +237,14 @@ static void intel_resolve_format(struct gralloc_drm_drv_t *drv, } } -static void intel_copy(struct gralloc_drm_drv_t *drv, + +static void intel_blit(struct gralloc_drm_drv_t *drv, struct gralloc_drm_bo_t *dst, struct gralloc_drm_bo_t *src, - short x1, short y1, short x2, short y2) + uint16_t dst_x1, uint16_t dst_y1, + uint16_t dst_x2, uint16_t dst_y2, + uint16_t src_x1, uint16_t src_y1, + uint16_t src_x2, uint16_t src_y2) { struct intel_info *info = (struct intel_info *) drv; struct intel_buffer *dst_ib = (struct intel_buffer *) dst; @@ -247,26 +252,36 @@ static void intel_copy(struct gralloc_drm_drv_t *drv, drm_intel_bo *bo_table[3]; uint32_t cmd, br13, dst_pitch, src_pitch; - if (dst->handle->width != src->handle->width || - dst->handle->height != src->handle->height || - dst->handle->stride != src->handle->stride || - dst->handle->format != src->handle->format) { - ALOGE("copy between incompatible buffers"); + /* + * XY_SRC_COPY_BLT_CMD does not support scaling, + * rectangle dimensions much match + */ + if (src_x2 - src_x1 != dst_x2 - dst_x1 || + src_y2 - src_y1 != dst_y2 - dst_y1) { + ALOGE("%s, src and dst rect must match", __func__); return; } - if (x1 < 0) - x1 = 0; - if (y1 < 0) - y1 = 0; - if (x2 > dst->handle->width) - x2 = dst->handle->width; - if (y2 > dst->handle->height) - y2 = dst->handle->height; + if (dst->handle->format != src->handle->format) { + ALOGE("%s, src and dst format must match", __func__); + return; + } - if (x2 <= x1 || y2 <= y1) + /* nothing to blit */ + if (src_x2 <= src_x1 || src_y2 <= src_y1) return; + /* clamp x2, y2 to surface size */ + if (src_x2 > src->handle->width) + src_x2 = src->handle->width; + if (src_y2 > src->handle->height) + src_y2 = src->handle->height; + + if (dst_x2 > dst->handle->width) + dst_x2 = dst->handle->width; + if (dst_y2 > dst->handle->height) + dst_y2 = dst->handle->height; + bo_table[0] = info->batch_ibo; bo_table[1] = src_ib->ibo; bo_table[2] = dst_ib->ibo; @@ -281,6 +296,14 @@ static void intel_copy(struct gralloc_drm_drv_t *drv, dst_pitch = dst->handle->stride; src_pitch = src->handle->stride; + /* Blit pitch must be dword-aligned. Otherwise, the hardware appears to + * drop the low bits. + */ + if (src_pitch % 4 != 0 || dst_pitch % 4 != 0) { + ALOGE("%s, src and dst pitch must be dword aligned", __func__); + return; + } + switch (gralloc_drm_get_bpp(dst->handle->format)) { case 1: break; @@ -292,7 +315,7 @@ static void intel_copy(struct gralloc_drm_drv_t *drv, cmd |= XY_SRC_COPY_BLT_WRITE_ALPHA | XY_SRC_COPY_BLT_WRITE_RGB; break; default: - ALOGE("copy with unsupported format"); + ALOGE("%s, copy with unsupported format", __func__); return; } @@ -313,12 +336,12 @@ static void intel_copy(struct gralloc_drm_drv_t *drv, return; batch_dword(info, cmd); - batch_dword(info, br13 | dst_pitch); - batch_dword(info, (y1 << 16) | x1); - batch_dword(info, (y2 << 16) | x2); + batch_dword(info, br13 | (uint16_t)dst_pitch); + batch_dword(info, (dst_y1 << 16) | dst_x1); + batch_dword(info, (dst_y2 << 16) | dst_x2); batch_reloc(info, dst, I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER); - batch_dword(info, (y1 << 16) | x1); - batch_dword(info, src_pitch); + batch_dword(info, (src_y1 << 16) | src_x1); + batch_dword(info, (uint16_t)src_pitch); batch_reloc(info, src, I915_GEM_DOMAIN_RENDER, 0); if (info->gen >= 60) { @@ -638,7 +661,7 @@ struct gralloc_drm_drv_t *gralloc_drm_drv_create_for_intel(int fd) info->base.free = intel_free; info->base.map = intel_map; info->base.unmap = intel_unmap; - info->base.copy = intel_copy; + info->base.blit = intel_blit; info->base.resolve_format = intel_resolve_format; return &info->base; diff --git a/gralloc_drm_kms.c b/gralloc_drm_kms.c index 91e7e63..7c7a903 100644 --- a/gralloc_drm_kms.c +++ b/gralloc_drm_kms.c @@ -309,7 +309,10 @@ int gralloc_drm_bo_post(struct gralloc_drm_bo_t *bo) dst = (drm->next_front) ? drm->next_front : drm->current_front; - drm->drv->copy(drm->drv, dst, bo, 0, 0, + drm->drv->blit(drm->drv, dst, bo, 0, 0, + bo->handle->width, + bo->handle->height, + 0, 0, bo->handle->width, bo->handle->height); bo = dst; @@ -349,9 +352,12 @@ int gralloc_drm_bo_post(struct gralloc_drm_bo_t *bo) break; case DRM_SWAP_COPY: drm_kms_wait_for_post(drm, 0); - drm->drv->copy(drm->drv, drm->current_front, + drm->drv->blit(drm->drv, drm->current_front, bo, 0, 0, bo->handle->width, + bo->handle->height, + 0, 0, + bo->handle->width, bo->handle->height); if (drm->mode_quirk_vmwgfx) ret = drmModeDirtyFB(drm->fd, drm->current_front->fb_id, &drm->clip, 1); diff --git a/gralloc_drm_pipe.c b/gralloc_drm_pipe.c index ee5c4c0..9987d52 100644 --- a/gralloc_drm_pipe.c +++ b/gralloc_drm_pipe.c @@ -285,10 +285,13 @@ 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, +static void pipe_blit(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) + uint16_t dst_x1, uint16_t dst_y1, + uint16_t dst_x2, uint16_t dst_y2, + uint16_t src_x1, uint16_t src_y1, + uint16_t src_x2, uint16_t src_y2) { struct pipe_manager *pm = (struct pipe_manager *) drv; struct pipe_buffer *dst = (struct pipe_buffer *) dst_bo; @@ -303,19 +306,15 @@ static void pipe_copy(struct gralloc_drm_drv_t *drv, 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 (dst_x2 > dst_bo->handle->width) + dst_x2 = dst_bo->handle->width; + if (dst_y2 > dst_bo->handle->height) + dst_y2 = dst_bo->handle->height; - if (x2 <= x1 || y2 <= y1) + if (src_x2 <= src_x1 || src_y2 <= src_y1) return; - u_box_2d(x1, y1, x2 - x1, y2 - y1, &src_box); + u_box_2d(src_x1, src_y1, src_x2 - src_x1, src_y2 - src_y1, &src_box); pthread_mutex_lock(&pm->mutex); @@ -330,7 +329,7 @@ static void pipe_copy(struct gralloc_drm_drv_t *drv, } pm->context->resource_copy_region(pm->context, - dst->resource, 0, x1, y1, 0, + dst->resource, 0, dst_x1, dst_y1, 0, src->resource, 0, &src_box); pm->context->flush(pm->context, NULL); @@ -562,7 +561,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; + pm->base.blit = pipe_blit; return &pm->base; } diff --git a/gralloc_drm_priv.h b/gralloc_drm_priv.h index 66c6dbd..0ab4ea5 100644 --- a/gralloc_drm_priv.h +++ b/gralloc_drm_priv.h @@ -128,11 +128,14 @@ struct gralloc_drm_drv_t { void (*unmap)(struct gralloc_drm_drv_t *drv, struct gralloc_drm_bo_t *bo); - /* copy between two bo's, used for DRM_SWAP_COPY */ - void (*copy)(struct gralloc_drm_drv_t *drv, + /* blit between two bo's, used for DRM_SWAP_COPY and general blitting */ + void (*blit)(struct gralloc_drm_drv_t *drv, struct gralloc_drm_bo_t *dst, struct gralloc_drm_bo_t *src, - short x1, short y1, short x2, short y2); + uint16_t dst_x1, uint16_t dst_y1, + uint16_t dst_x2, uint16_t dst_y2, + uint16_t src_x1, uint16_t src_y1, + uint16_t src_x2, uint16_t src_y2); /* query component offsets, strides and handles for a format */ void (*resolve_format)(struct gralloc_drm_drv_t *drv, |