[PATCH v2 02/11] gbm: add gbm_surface interface

Ander Conselvan de Oliveira ander.conselvan.de.oliveira at intel.com
Wed Jan 25 06:24:14 PST 2012


The implementation is empty for now, but the idea here is to be able
to create an egl window surface from a gbm_surface and let the EGL
platform handle buffer allocation but keeping the user in charge of
page flipping.

gbm_surface_lock_front_buffer() locks a surface's front buffer and
returns a bo representing it. This bo should later be released with
gbm_surface_release_buffer(). This locking mechanism can be used by
the egl platform to implement triple buffering.
---
 src/gbm/backends/dri/gbm_dri.c |   29 +++++++++++++++
 src/gbm/main/gbm.c             |   74 ++++++++++++++++++++++++++++++++++++++++
 src/gbm/main/gbm.h             |   15 ++++++++
 src/gbm/main/gbmint.h          |   15 ++++++++
 4 files changed, 133 insertions(+), 0 deletions(-)

diff --git a/src/gbm/backends/dri/gbm_dri.c b/src/gbm/backends/dri/gbm_dri.c
index 9de8cb6..831d264 100644
--- a/src/gbm/backends/dri/gbm_dri.c
+++ b/src/gbm/backends/dri/gbm_dri.c
@@ -334,6 +334,30 @@ gbm_dri_bo_create(struct gbm_device *gbm,
    return &bo->base.base;
 }
 
+static struct gbm_surface *
+gbm_dri_surface_create(struct gbm_device *gbm,
+                       uint32_t width, uint32_t height,
+                       enum gbm_bo_format format)
+{
+   return NULL;
+}
+
+static void
+gbm_dri_surface_destroy(struct gbm_surface *_surf)
+{
+}
+
+static struct gbm_bo *
+gbm_dri_surface_lock_front_buffer(struct gbm_surface *_surf)
+{
+   return NULL;
+}
+
+static void
+gbm_dri_surface_release_buffer(struct gbm_surface *_surf, struct gbm_bo *_bo)
+{
+}
+
 static void
 dri_destroy(struct gbm_device *gbm)
 {
@@ -361,6 +385,11 @@ dri_device_create(int fd)
    dri->base.base.is_format_supported = gbm_dri_is_format_supported;
    dri->base.base.bo_destroy = gbm_dri_bo_destroy;
    dri->base.base.destroy = dri_destroy;
+   dri->base.base.surface_create = gbm_dri_surface_create;
+   dri->base.base.surface_destroy = gbm_dri_surface_destroy;
+   dri->base.base.surface_lock_front_buffer =
+      gbm_dri_surface_lock_front_buffer;
+   dri->base.base.surface_release_buffer = gbm_dri_surface_release_buffer;
 
    dri->base.type = GBM_DRM_DRIVER_TYPE_DRI;
    dri->base.base.name = "drm";
diff --git a/src/gbm/main/gbm.c b/src/gbm/main/gbm.c
index 03fc52b..211e931 100644
--- a/src/gbm/main/gbm.c
+++ b/src/gbm/main/gbm.c
@@ -292,3 +292,77 @@ gbm_bo_create_from_egl_image(struct gbm_device *gbm,
    return gbm->bo_create_from_egl_image(gbm, egl_dpy, egl_image,
                                         width, height, usage);
 }
+
+/**
+ * Allocate a surface object
+ *
+ * \param gbm The gbm device returned from gbm_create_device()
+ * \param width The width for the surface
+ * \param height The height for the surface
+ * \param format The format to use for the surface
+ *
+ * \return A newly allocated surface that should be freed with
+ * gbm_surface_destroy() when no longer needed. If an error occurs
+ * during allocation %NULL will be returned.
+ *
+ * \sa enum gbm_bo_format for the list of formats
+ */
+GBM_EXPORT struct gbm_surface *
+gbm_surface_create(struct gbm_device *gbm,
+                   uint32_t width, uint32_t height,
+                   enum gbm_bo_format format)
+{
+   return gbm->surface_create(gbm, width, height, format);
+}
+
+/**
+ * Destroys the given surface and frees all resources associated with
+ * it.
+ *
+ * All buffers locked with gbm_surface_lock_front_buffer() should be
+ * released prior to calling this function.
+ *
+ * \param surf The surface
+ */
+GBM_EXPORT void
+gbm_surface_destroy(struct gbm_surface *surf)
+{
+   surf->gbm->surface_destroy(surf);
+}
+
+/**
+ * Lock the surface's current front buffer
+ *
+ * Lock rendering to the surface's current front buffer until it is
+ * released with gbm_surface_release_buffer().
+ *
+ * Each time this funcion is called, a new bo representing the front buffer
+ * is returned. On multiple invocations, all the returned bos must be
+ * released in order to release the actual surface buffer.
+ *
+ * \param surf The surface
+ *
+ * \return A newly allocated buffer object that should be released with
+ * gbm_surface_release_buffer() when no longer needed. This bo should
+ * not be destroyed using gbm_bo_destroy(). If an error occurs this
+ * function returns %NULL.
+ */
+GBM_EXPORT struct gbm_bo *
+gbm_surface_lock_front_buffer(struct gbm_surface *surf)
+{
+   return surf->gbm->surface_lock_front_buffer(surf);
+}
+
+/**
+ * Release a locked buffer obtained with gbm_surface_lock_front_buffer()
+ *
+ * The bo is destroyed after a call to this function.
+ *
+ * \param surf The surface
+ * \param bo The buffer object
+ */
+GBM_EXPORT void
+gbm_surface_release_buffer(struct gbm_surface *surf, struct gbm_bo *bo)
+{
+   surf->gbm->surface_release_buffer(surf, bo);
+}
diff --git a/src/gbm/main/gbm.h b/src/gbm/main/gbm.h
index c4ae51d..5ffe3dd 100644
--- a/src/gbm/main/gbm.h
+++ b/src/gbm/main/gbm.h
@@ -44,6 +44,7 @@ extern "C" {
 
 struct gbm_device;
 struct gbm_bo;
+struct gbm_surface;
 
 /**
  * \mainpage The Generic Buffer Manager
@@ -143,6 +144,20 @@ gbm_bo_get_handle(struct gbm_bo *bo);
 void
 gbm_bo_destroy(struct gbm_bo *bo);
 
+struct gbm_surface *
+gbm_surface_create(struct gbm_device *gbm,
+                   uint32_t width, uint32_t height,
+                   enum gbm_bo_format format);
+
+struct gbm_bo *
+gbm_surface_lock_front_buffer(struct gbm_surface *surface);
+
+void
+gbm_surface_release_buffer(struct gbm_surface *surface, struct gbm_bo *bo);
+
+void
+gbm_surface_destroy(struct gbm_surface *surface);
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/src/gbm/main/gbmint.h b/src/gbm/main/gbmint.h
index 9e4072e..d24ea7a 100644
--- a/src/gbm/main/gbmint.h
+++ b/src/gbm/main/gbmint.h
@@ -71,6 +71,14 @@ struct gbm_device {
                                               uint32_t width, uint32_t height,
                                               uint32_t usage);
    void (*bo_destroy)(struct gbm_bo *bo);
+
+   struct gbm_surface *(*surface_create)(struct gbm_device *gbm,
+                                         uint32_t width, uint32_t height,
+                                         enum gbm_bo_format format);
+   struct gbm_bo *(*surface_lock_front_buffer)(struct gbm_surface *surface);
+   void (*surface_release_buffer)(struct gbm_surface *surface,
+                                  struct gbm_bo *bo);
+   void (*surface_destroy)(struct gbm_surface *surface);
 };
 
 /**
@@ -86,6 +94,13 @@ struct gbm_bo {
    union gbm_bo_handle  handle;
 };
 
+struct gbm_surface {
+   struct gbm_device *gbm;
+   uint32_t width;
+   uint32_t height;
+   enum gbm_bo_format format;
+};
+
 struct gbm_backend {
    const char *backend_name;
    struct gbm_device *(*create_device)(int fd);
-- 
1.7.4.1



More information about the wayland-devel mailing list