[Mesa-dev] [PATCH RFC 1/2] GBM: add KMS provider interface
Lucas Stach
l.stach at pengutronix.de
Fri Mar 4 13:49:15 UTC 2016
The GBM device, which is used to bootstrap the EGL context
should always be constructed atop a render capable DRM device.
If this device is a render node or a standalone renderonly DRM
device, we need a way to set the actual KMS output device to
allow for proper allocations of the buffer objects backing the
window surface and hiding the needed PRIME import/export.
This interface allows this by constructing a second GBM device
on top of the KMS capable DRM device and binding this as the
KMS provider to the render GBM device.
Signed-off-by: Lucas Stach <l.stach at pengutronix.de>
---
src/gbm/main/gbm.c | 35 ++++++++++++++++++++++++++++++++++-
src/gbm/main/gbm.h | 7 +++++++
src/gbm/main/gbmint.h | 5 +++++
3 files changed, 46 insertions(+), 1 deletion(-)
diff --git a/src/gbm/main/gbm.c b/src/gbm/main/gbm.c
index c046b1ad7c8a..26339747f3a1 100644
--- a/src/gbm/main/gbm.c
+++ b/src/gbm/main/gbm.c
@@ -90,6 +90,25 @@ gbm_device_is_format_supported(struct gbm_device *gbm,
return gbm->is_format_supported(gbm, format, usage);
}
+/** Set the KMS provider device used for scanout and cursor BO allocations
+ *
+ * \param gbm The created buffer manager
+ * \param provider The buffer manager that should be used for KMS buffers
+ * \return 0 if successful
+ */
+GBM_EXPORT int
+gbm_device_set_kms_provider(struct gbm_device *gbm,
+ struct gbm_device *provider)
+{
+ /* Changing the provider on the fly is not supported */
+ if (gbm->kms_provider)
+ return -1;
+ else
+ gbm->kms_provider = provider;
+
+ return 0;
+}
+
/** Destroy the gbm device and free all resources associated with it.
*
* \param gbm The device created using gbm_create_device()
@@ -344,12 +363,17 @@ gbm_bo_create(struct gbm_device *gbm,
uint32_t width, uint32_t height,
uint32_t format, uint32_t usage)
{
+ struct gbm_bo *bo;
+
if (width == 0 || height == 0) {
errno = EINVAL;
return NULL;
}
- return gbm->bo_create(gbm, width, height, format, usage);
+ bo = gbm->bo_create(gbm, width, height, format, usage);
+ bo->type = GBM_BO_TYPE_RENDER | GBM_BO_TYPE_KMS;
+
+ return bo;
}
/**
@@ -385,6 +409,15 @@ gbm_bo_import(struct gbm_device *gbm,
return gbm->bo_import(gbm, type, buffer, usage);
}
+GBM_EXPORT struct gbm_bo *
+gbm_bo_get_kms_bo(struct gbm_bo *bo)
+{
+ if (!bo || !(bo->type & GBM_BO_TYPE_KMS))
+ return NULL;
+
+ return bo;
+}
+
/**
* Allocate a surface object
*
diff --git a/src/gbm/main/gbm.h b/src/gbm/main/gbm.h
index 8db2153e84bb..1faff360130b 100644
--- a/src/gbm/main/gbm.h
+++ b/src/gbm/main/gbm.h
@@ -226,6 +226,10 @@ int
gbm_device_is_format_supported(struct gbm_device *gbm,
uint32_t format, uint32_t usage);
+int
+gbm_device_set_kms_provider(struct gbm_device *gbm,
+ struct gbm_device *provider);
+
void
gbm_device_destroy(struct gbm_device *gbm);
@@ -274,6 +278,9 @@ gbm_bo_get_handle(struct gbm_bo *bo);
int
gbm_bo_get_fd(struct gbm_bo *bo);
+struct gbm_bo *
+gbm_bo_get_kms_bo(struct gbm_bo *bo);
+
int
gbm_bo_write(struct gbm_bo *bo, const void *buf, size_t count);
diff --git a/src/gbm/main/gbmint.h b/src/gbm/main/gbmint.h
index 155eb12b06bc..218ecf66c0fd 100644
--- a/src/gbm/main/gbmint.h
+++ b/src/gbm/main/gbmint.h
@@ -52,6 +52,7 @@ struct gbm_device {
/* Hack to make a gbm_device detectable by its first element. */
struct gbm_device *(*dummy)(int);
+ struct gbm_device *kms_provider;
int fd;
const char *name;
unsigned int refcount;
@@ -87,8 +88,12 @@ struct gbm_device {
*
* The members in this structure should not be accessed directly.
*/
+#define GBM_BO_TYPE_KMS (1 << 0)
+#define GBM_BO_TYPE_RENDER (1 << 1)
+
struct gbm_bo {
struct gbm_device *gbm;
+ uint32_t type;
uint32_t width;
uint32_t height;
uint32_t stride;
--
2.7.0
More information about the mesa-dev
mailing list