From 7b733f4e2b20614d9f367186810c4fcac4aa820c Mon Sep 17 00:00:00 2001 From: Brendan King Date: Tue, 28 Nov 2017 16:27:38 +0000 Subject: [PATCH 25/50] gbm: add gbm_bo_blit For the GBM DRI backend, gbm_bo_blit is a wrapper around blitImage in the DRI Image extension. --- src/gbm/backends/dri/gbm_dri.c | 32 ++++++++++++++++++++++++++++++++ src/gbm/main/gbm.c | 28 ++++++++++++++++++++++++++++ src/gbm/main/gbm.h | 21 +++++++++++++++++++++ src/gbm/main/gbmint.h | 4 ++++ 4 files changed, 85 insertions(+) diff --git a/src/gbm/backends/dri/gbm_dri.c b/src/gbm/backends/dri/gbm_dri.c index b5634741554..ca865f4df9c 100644 --- a/src/gbm/backends/dri/gbm_dri.c +++ b/src/gbm/backends/dri/gbm_dri.c @@ -1334,6 +1334,37 @@ gbm_dri_surface_destroy(struct gbm_surface *_surf) free(surf); } +static int +gbm_dri_bo_blit(struct gbm_bo *_dst_bo, struct gbm_bo *_src_bo, + int dst_x0, int dst_y0, int dst_width, int dst_height, + int src_x0, int src_y0, int src_width, int src_height, + enum gbm_blit_flags flags) +{ + struct gbm_dri_device *dri = gbm_dri_device(_dst_bo->gbm); + struct gbm_dri_bo *dst_bo = gbm_dri_bo(_dst_bo); + struct gbm_dri_bo *src_bo = gbm_dri_bo(_src_bo); + + if (!dri->image || dri->image->base.version < 9 || !dri->image->blitImage) { + errno = ENOSYS; + return 0; + } + + mtx_lock(&dri->mutex); + if (!dri->context) + dri->context = dri->dri2->createNewContext(dri->screen, NULL, + NULL, NULL); + assert(dri->context); + mtx_unlock(&dri->mutex); + + /* GBM flags and DRI flags are the same, so just pass them on */ + dri->image->blitImage(dri->context, dst_bo->image, src_bo->image, + dst_x0, dst_y0, dst_width, dst_height, + src_x0, src_y0, src_width, src_height, + flags); + + return 1; +} + static void dri_destroy(struct gbm_device *gbm) { @@ -1383,6 +1414,7 @@ dri_device_create(int fd) dri->base.destroy = dri_destroy; dri->base.surface_create = gbm_dri_surface_create; dri->base.surface_destroy = gbm_dri_surface_destroy; + dri->base.bo_blit = gbm_dri_bo_blit; dri->base.name = "drm"; diff --git a/src/gbm/main/gbm.c b/src/gbm/main/gbm.c index 954b3c35b0d..78de34286bd 100644 --- a/src/gbm/main/gbm.c +++ b/src/gbm/main/gbm.c @@ -741,3 +741,31 @@ gbm_format_get_name(uint32_t gbm_format, struct gbm_format_name_desc *desc) return desc->name; } + +/** + * Blit from one buffer object to another + * + * \param dst_bo The destination buffer object + * \param src_bo The source buffer object + * \param dst_x0 The X coordinate (top left origin) of the destination rectangle + * \param dst_y0 The Y coordinate (top left origin) of the destination rectangle + * \param dst_width The width of the destination rectangle + * \param dst_height The height of the destination rectangle + * \param src_x0 The X coordinate (top left origin) of the source rectangle + * \param src_y0 The Y coordinate (top left origin) of the source rectangle + * \param src_width The width of the source rectangle + * \param src_height The height of the source rectangle + * \param flags The flags for the blit + * \return 1 on success, 0 otherwise + */ +GBM_EXPORT int +gbm_bo_blit(struct gbm_bo *dst_bo, struct gbm_bo *src_bo, + int dst_x0, int dst_y0, int dst_width, int dst_height, + int src_x0, int src_y0, int src_width, int src_height, + enum gbm_blit_flags flags) +{ + return dst_bo->gbm->bo_blit(dst_bo, src_bo, + dst_x0, dst_y0, dst_width, dst_height, + src_x0, src_y0, src_width, src_height, + flags); +} diff --git a/src/gbm/main/gbm.h b/src/gbm/main/gbm.h index 5801cd526a0..e754edd5654 100644 --- a/src/gbm/main/gbm.h +++ b/src/gbm/main/gbm.h @@ -246,6 +246,21 @@ enum gbm_bo_flags { GBM_BO_USE_PROTECTED = (1 << 5), }; +/** + * Flags to control the behaviour of a blit - these are passed to + * gbm_bo_blit(). + */ +enum gbm_blit_flags { + /** + * Force blit execution in finite time + */ + GBM_BLIT_FLAG_FLUSH = 0x0001, + /** + * Flush, and wait for the blit to complete + */ + GBM_BLIT_FLAG_FINISH = 0x0002 +}; + int gbm_device_get_fd(struct gbm_device *gbm); @@ -422,6 +437,12 @@ gbm_surface_destroy(struct gbm_surface *surface); char * gbm_format_get_name(uint32_t gbm_format, struct gbm_format_name_desc *desc); +int +gbm_bo_blit(struct gbm_bo *dst_bo, struct gbm_bo *src_bo, + int dst_x0, int dst_y0, int dst_width, int dst_height, + int src_x0, int src_y0, int src_width, int src_height, + enum gbm_blit_flags flags); + #ifdef __cplusplus } #endif diff --git a/src/gbm/main/gbmint.h b/src/gbm/main/gbmint.h index 192577431e2..fb95954ab32 100644 --- a/src/gbm/main/gbmint.h +++ b/src/gbm/main/gbmint.h @@ -98,6 +98,10 @@ struct gbm_device { struct gbm_bo *bo); int (*surface_has_free_buffers)(struct gbm_surface *surface); void (*surface_destroy)(struct gbm_surface *surface); + int (*bo_blit)(struct gbm_bo *dst_bo, struct gbm_bo *src_bo, + int dst_x0, int dst_y0, int dst_width, int dst_height, + int src_x0, int src_y0, int src_width, int src_height, + enum gbm_blit_flags flags); }; /** -- 2.17.1