+ }
+
+ return bo->gbm->bo_map(bo, x, y, width, height,
+ flags, stride, map_data);
+}
+
+/**
+ * Unmap a previously mapped region of a gbm buffer object
+ *
+ * This function unmaps a region of a gbm bo for cpu read and/or write
+ * access.
+ *
+ * \param bo The buffer object
+ * \param map_data opaque ptr returned from prior gbm_bo_map
+ */
+GBM_EXPORT void
+gbm_bo_unmap(struct gbm_bo *bo, void *map_data)
+{
+ bo->gbm->bo_unmap(bo, map_data);
+}
+
+/**
+ * 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,
+ uint32_t format, uint32_t flags)
+{
+ return gbm->surface_create(gbm, width, height, format, flags, NULL, 0);
+}
+
+GBM_EXPORT struct gbm_surface *
+gbm_surface_create_with_modifiers(struct gbm_device *gbm,
+ uint32_t width, uint32_t height,
+ uint32_t format,
+ const uint64_t *modifiers,
+ const unsigned int count)
+{
+ if ((count && !modifiers) || (modifiers && !count)) {
+ errno = EINVAL;
+ return NULL;
+ }
+
+ return gbm->surface_create(gbm, width, height, format, 0,
+ modifiers, count);
+}
+
+/**
+ * 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().
+ *
+ * This function must be called exactly once after calling
+ * eglSwapBuffers. Calling it before any eglSwapBuffer has happened
+ * on the surface or two or more times after eglSwapBuffers is an
+ * error. A new bo representing the new 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 buffer object that should be released with
+ * gbm_surface_release_buffer() when no longer needed. The implementation
+ * is free to reuse buffers released with gbm_surface_release_buffer() so
+ * 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()
+ *
+ * Returns the underlying buffer to the gbm surface. Releasing a bo
+ * will typically make gbm_surface_has_free_buffer() return 1 and thus
+ * allow rendering the next frame, but not always. The implementation
+ * may choose to destroy the bo immediately or reuse it, in which case
+ * the user data associated with it is unchanged.
+ *
+ * \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);
+}
+
+/**
+ * Return whether or not a surface has free (non-locked) buffers
+ *
+ * Before starting a new frame, the surface must have a buffer
+ * available for rendering. Initially, a gbm surface will have a free
+ * buffer, but after one or more buffers have been locked (\sa
+ * gbm_surface_lock_front_buffer()), the application must check for a
+ * free buffer before rendering.
+ *
+ * If a surface doesn't have a free buffer, the application must
+ * return a buffer to the surface using gbm_surface_release_buffer()
+ * and after that, the application can query for free buffers again.
+ *
+ * \param surf The surface
+ * \return 1 if the surface has free buffers, 0 otherwise
+ */
+GBM_EXPORT int
+gbm_surface_has_free_buffers(struct gbm_surface *surf)
+{
+ return surf->gbm->surface_has_free_buffers(surf);
+}
+
+/* The two GBM_BO_FORMAT_[XA]RGB8888 formats alias the GBM_FORMAT_*
+ * formats of the same name. We want to accept them whenever someone
+ * has a GBM format, but never return them to the user. */
+uint32_t
+gbm_format_canonicalize(uint32_t gbm_format)
+{
+ switch (gbm_format) {
+ case GBM_BO_FORMAT_XRGB8888:
+ return GBM_FORMAT_XRGB8888;
+ case GBM_BO_FORMAT_ARGB8888:
+ return GBM_FORMAT_ARGB8888;
+ default:
+ return gbm_format;
+ }
+}
+
+/**
+ * Returns a string representing the fourcc format name.
+ *
+ * \param desc Caller-provided storage for the format name string.
+ * \return String containing the fourcc of the format.
+ */
+GBM_EXPORT char *
+gbm_format_get_name(uint32_t gbm_format, struct gbm_format_name_desc *desc)
+{
+ gbm_format = gbm_format_canonicalize(gbm_format);
+
+ desc->name[0] = gbm_format;
+ desc->name[1] = gbm_format >> 8;
+ desc->name[2] = gbm_format >> 16;
+ desc->name[3] = gbm_format >> 24;
+ desc->name[4] = 0;