216 lines
7.3 KiB
Diff
216 lines
7.3 KiB
Diff
From 4e73467f49320e7647ec8e95a754f7574733838f Mon Sep 17 00:00:00 2001
|
|
From: Imagination Technologies <powervr@imgtec.com>
|
|
Date: Tue, 28 Nov 2017 16:27:38 +0000
|
|
Subject: [PATCH 017/168] 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 | 33 +++++++++++++++++++++++++++++++++
|
|
src/gbm/main/gbm.c | 31 +++++++++++++++++++++++++++++++
|
|
src/gbm/main/gbm.h | 21 +++++++++++++++++++++
|
|
src/gbm/main/gbm_abi_check.c | 20 +++++++++++++++++++-
|
|
src/gbm/main/gbm_backend_abi.h | 8 ++++++++
|
|
5 files changed, 112 insertions(+), 1 deletion(-)
|
|
|
|
diff --git a/src/gbm/backends/dri/gbm_dri.c b/src/gbm/backends/dri/gbm_dri.c
|
|
index 36cee87a2fd..6dad8d97d17 100644
|
|
--- a/src/gbm/backends/dri/gbm_dri.c
|
|
+++ b/src/gbm/backends/dri/gbm_dri.c
|
|
@@ -1412,6 +1412,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)
|
|
{
|
|
@@ -1473,6 +1504,8 @@ dri_device_create(int fd, uint32_t gbm_backend_version)
|
|
|
|
dri->base.v0.name = "drm";
|
|
|
|
+ dri->base.v1.bo_blit = gbm_dri_bo_blit;
|
|
+
|
|
dri->visual_table = gbm_dri_visuals_table;
|
|
dri->num_visuals = ARRAY_SIZE(gbm_dri_visuals_table);
|
|
|
|
diff --git a/src/gbm/main/gbm.c b/src/gbm/main/gbm.c
|
|
index 599f7aae9b6..27e9f5bcd03 100644
|
|
--- a/src/gbm/main/gbm.c
|
|
+++ b/src/gbm/main/gbm.c
|
|
@@ -827,6 +827,37 @@ 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)
|
|
+{
|
|
+ if (dst_bo->gbm->v0.backend_version >= 1)
|
|
+ return dst_bo->gbm->v1.bo_blit(dst_bo, src_bo,
|
|
+ dst_x0, dst_y0, dst_width, dst_height,
|
|
+ src_x0, src_y0, src_width, src_height,
|
|
+ flags);
|
|
+ else
|
|
+ return 0;
|
|
+}
|
|
+
|
|
/**
|
|
* A global table of functions and global variables defined in the core GBM
|
|
* code that need to be accessed directly by GBM backends.
|
|
diff --git a/src/gbm/main/gbm.h b/src/gbm/main/gbm.h
|
|
index 1a1e2caecb4..207b6cf9d74 100644
|
|
--- a/src/gbm/main/gbm.h
|
|
+++ b/src/gbm/main/gbm.h
|
|
@@ -266,6 +266,21 @@ enum gbm_bo_flags {
|
|
GBM_BO_USE_FRONT_RENDERING = (1 << 6),
|
|
};
|
|
|
|
+/**
|
|
+ * 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);
|
|
|
|
@@ -462,6 +477,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/gbm_abi_check.c b/src/gbm/main/gbm_abi_check.c
|
|
index feca0998d9d..0153b5a8754 100644
|
|
--- a/src/gbm/main/gbm_abi_check.c
|
|
+++ b/src/gbm/main/gbm_abi_check.c
|
|
@@ -106,6 +106,21 @@ struct gbm_device_abi0 {
|
|
struct gbm_device_v0_abi0 v0;
|
|
};
|
|
|
|
+#define GBM_BACKEND_ABI_VERSION_abi1 1
|
|
+struct gbm_device_v1_abi1 {
|
|
+ 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);
|
|
+};
|
|
+
|
|
+struct gbm_device_abi1 {
|
|
+ /* Hack to make a gbm_device detectable by its first element. */
|
|
+ struct gbm_device *(*dummy)(int);
|
|
+ struct gbm_device_v0_abi0 v0;
|
|
+ struct gbm_device_v1_abi1 v1;
|
|
+};
|
|
+
|
|
/**
|
|
* GBM buffer object interface corresponding to GBM_BACKEND_ABI_VERSION = 0
|
|
*
|
|
@@ -364,8 +379,11 @@ int main(int argc, char **argv)
|
|
CHECK_MEMBER_CURRENT(gbm_device_v0, _abi0, surface_has_free_buffers);
|
|
CHECK_MEMBER_CURRENT(gbm_device_v0, _abi0, surface_destroy);
|
|
|
|
+ CHECK_MEMBER_CURRENT(gbm_device_v1, _abi1, bo_blit);
|
|
+
|
|
/* Size of ABI-versioned substructures verified by above member checks */
|
|
- CHECK_SIZE_CURRENT (gbm_device, _abi0);
|
|
+ CHECK_SIZE (gbm_device, _abi0, _abi1);
|
|
+ CHECK_SIZE_CURRENT (gbm_device, _abi1);
|
|
|
|
|
|
/* Check current gbm_bo ABI against gbm_bo_abi0*/
|
|
diff --git a/src/gbm/main/gbm_backend_abi.h b/src/gbm/main/gbm_backend_abi.h
|
|
index 222ce3404cb..17f5e0ca808 100644
|
|
--- a/src/gbm/main/gbm_backend_abi.h
|
|
+++ b/src/gbm/main/gbm_backend_abi.h
|
|
@@ -157,6 +157,13 @@ struct gbm_device_v0 {
|
|
void (*surface_destroy)(struct gbm_surface *surface);
|
|
};
|
|
|
|
+struct gbm_device_v1 {
|
|
+ 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);
|
|
+};
|
|
+
|
|
/**
|
|
* The device used for the memory allocation.
|
|
*
|
|
@@ -169,6 +176,7 @@ struct gbm_device {
|
|
/* Hack to make a gbm_device detectable by its first element. */
|
|
struct gbm_device *(*dummy)(int);
|
|
struct gbm_device_v0 v0;
|
|
+ struct gbm_device_v1 v1;
|
|
};
|
|
|
|
/**
|
|
--
|
|
2.17.1
|
|
|