From 3881c1f952241e7a2f61164d4c1f7a51aef161b4 Mon Sep 17 00:00:00 2001 From: Georges Basile Stavracas Neto Date: Mon, 9 Dec 2019 10:03:07 -0300 Subject: [PATCH] cogl/context: Add cogl_renderer_create_dma_buf() and family This is a winsys-specific API that allows exporting a DMA buffer fd. The CoglDmaBufHandle structure allows passing the ownership of the DMA buffer to whoever is using it, so the winsys doesn't need to manually track it. https://gitlab.gnome.org/GNOME/mutter/merge_requests/1086 --- cogl/cogl/cogl-dma-buf-handle.c | 94 ++++++++++++++++++++++++++ cogl/cogl/cogl-dma-buf-handle.h | 83 +++++++++++++++++++++++ cogl/cogl/cogl-renderer.c | 14 ++++ cogl/cogl/cogl-renderer.h | 21 ++++++ cogl/cogl/cogl-types.h | 8 +++ cogl/cogl/cogl.h | 1 + cogl/cogl/meson.build | 2 + cogl/cogl/winsys/cogl-winsys-private.h | 6 ++ 8 files changed, 229 insertions(+) create mode 100644 cogl/cogl/cogl-dma-buf-handle.c create mode 100644 cogl/cogl/cogl-dma-buf-handle.h diff --git a/cogl/cogl/cogl-dma-buf-handle.c b/cogl/cogl/cogl-dma-buf-handle.c new file mode 100644 index 000000000..4a8f709f2 --- /dev/null +++ b/cogl/cogl/cogl-dma-buf-handle.c @@ -0,0 +1,94 @@ +/* + * Cogl + * + * A Low Level GPU Graphics and Utilities API + * + * Copyright (C) 2020 Endless, Inc. + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * Authors: + * Georges Basile Stavracas Neto + */ + +#include "cogl-config.h" + +#include "cogl-dma-buf-handle.h" +#include "cogl-object.h" + +#include + +struct _CoglDmaBufHandle +{ + CoglFramebuffer *framebuffer; + int dmabuf_fd; + gpointer user_data; + GDestroyNotify destroy_func; +}; + +CoglDmaBufHandle * +cogl_dma_buf_handle_new (CoglFramebuffer *framebuffer, + int dmabuf_fd, + gpointer user_data, + GDestroyNotify destroy_func) +{ + CoglDmaBufHandle *dmabuf_handle; + + g_assert (framebuffer); + g_assert (dmabuf_fd != -1); + + dmabuf_handle = g_new0 (CoglDmaBufHandle, 1); + dmabuf_handle->framebuffer = cogl_object_ref (framebuffer); + dmabuf_handle->dmabuf_fd = dmabuf_fd; + dmabuf_handle->user_data = user_data; + dmabuf_handle->destroy_func = destroy_func; + + return dmabuf_handle; +} + +void +cogl_dma_buf_handle_free (CoglDmaBufHandle *dmabuf_handle) +{ + g_return_if_fail (dmabuf_handle != NULL); + + g_clear_pointer (&dmabuf_handle->framebuffer, cogl_object_unref); + + if (dmabuf_handle->destroy_func) + g_clear_pointer (&dmabuf_handle->user_data, dmabuf_handle->destroy_func); + + if (dmabuf_handle->dmabuf_fd != -1) + close (dmabuf_handle->dmabuf_fd); + + g_free (dmabuf_handle); +} + +CoglFramebuffer * +cogl_dma_buf_handle_get_framebuffer (CoglDmaBufHandle *dmabuf_handle) +{ + return dmabuf_handle->framebuffer; +} + +int +cogl_dma_buf_handle_get_fd (CoglDmaBufHandle *dmabuf_handle) +{ + return dmabuf_handle->dmabuf_fd; +} + diff --git a/cogl/cogl/cogl-dma-buf-handle.h b/cogl/cogl/cogl-dma-buf-handle.h new file mode 100644 index 000000000..25b9b0ccb --- /dev/null +++ b/cogl/cogl/cogl-dma-buf-handle.h @@ -0,0 +1,83 @@ +/* + * Cogl + * + * A Low Level GPU Graphics and Utilities API + * + * Copyright (C) 2020 Endless, Inc. + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * Authors: + * Georges Basile Stavracas Neto + */ + + +#if !defined(__COGL_H_INSIDE__) && !defined(COGL_COMPILATION) +#error "Only can be included directly." +#endif + +#ifndef __COGL_DMA_BUF_HANDLE_H__ +#define __COGL_DMA_BUF_HANDLE_H__ + +#include +#include + +/** + * cogl_dma_buf_handle_new: (skip) + */ +CoglDmaBufHandle * +cogl_dma_buf_handle_new (CoglFramebuffer *framebuffer, + int dmabuf_fd, + gpointer data, + GDestroyNotify destroy_func); + +/** + * cogl_dma_buf_handle_free: (skip) + * + * Releases @dmabuf_handle; it is a programming error to release + * an already released handle. + */ +void +cogl_dma_buf_handle_free (CoglDmaBufHandle *dmabuf_handle); + +/** + * cogl_dma_buf_handle_get_framebuffer: (skip) + * + * Retrieves the #CoglFramebuffer, backed by an exported DMABuf buffer, + * of @dmabuf_handle. + * + * Returns: (transfer none): a #CoglFramebuffer + */ +CoglFramebuffer * +cogl_dma_buf_handle_get_framebuffer (CoglDmaBufHandle *dmabuf_handle); + +/** + * cogl_dma_buf_handle_get_fd: (skip) + * + * Retrieves the file descriptor of @dmabuf_handle. + * + * Returns: a valid file descriptor + */ +int +cogl_dma_buf_handle_get_fd (CoglDmaBufHandle *dmabuf_handle); + + +#endif /* __COGL_DMA_BUF_HANDLE_H__ */ diff --git a/cogl/cogl/cogl-renderer.c b/cogl/cogl/cogl-renderer.c index 37c7443b3..3dc22c190 100644 --- a/cogl/cogl/cogl-renderer.c +++ b/cogl/cogl/cogl-renderer.c @@ -756,3 +756,17 @@ cogl_renderer_foreach_output (CoglRenderer *renderer, for (l = renderer->outputs; l; l = l->next) callback (l->data, user_data); } + +CoglDmaBufHandle * +cogl_renderer_create_dma_buf (CoglRenderer *renderer, + int width, + int height, + GError **error) +{ + const CoglWinsysVtable *winsys = _cogl_renderer_get_winsys (renderer); + + if (winsys->renderer_create_dma_buf) + return winsys->renderer_create_dma_buf (renderer, width, height, error); + + return NULL; +} diff --git a/cogl/cogl/cogl-renderer.h b/cogl/cogl/cogl-renderer.h index be446b089..a438e30b7 100644 --- a/cogl/cogl/cogl-renderer.h +++ b/cogl/cogl/cogl-renderer.h @@ -398,6 +398,27 @@ cogl_renderer_foreach_output (CoglRenderer *renderer, CoglOutputCallback callback, void *user_data); +/** + * cogl_renderer_create_dma_buf: (skip) + * @renderer: A #CoglRenderer + * @width: width of the new + * @height: height of the new + * @error: (nullable): return location for a #GError + * + * Creates a new #CoglFramebuffer with @width x @height, and format + * hardcoded to XRGB, and exports the new framebuffer's DMA buffer + * handle. + * + * Returns: (nullable)(transfer full): a #CoglDmaBufHandle. The + * return result must be released with cogl_dma_buf_handle_free() + * after use. + */ +CoglDmaBufHandle * +cogl_renderer_create_dma_buf (CoglRenderer *renderer, + int width, + int height, + GError **error); + G_END_DECLS #endif /* __COGL_RENDERER_H__ */ diff --git a/cogl/cogl/cogl-types.h b/cogl/cogl/cogl-types.h index f3d0b816d..d24683999 100644 --- a/cogl/cogl/cogl-types.h +++ b/cogl/cogl/cogl-types.h @@ -101,6 +101,14 @@ typedef int32_t CoglAngle; typedef struct _CoglColor CoglColor; typedef struct _CoglTextureVertex CoglTextureVertex; +/** + * CoglDmaBufHandle: (skip) + * + * An opaque type that tracks the lifetime of a DMA buffer fd. Release + * with cogl_dma_buf_handle_free(). + */ +typedef struct _CoglDmaBufHandle CoglDmaBufHandle; + /* Enum declarations */ #define COGL_A_BIT (1 << 4) diff --git a/cogl/cogl/cogl.h b/cogl/cogl/cogl.h index 17c59d66e..a71d09fbf 100644 --- a/cogl/cogl/cogl.h +++ b/cogl/cogl/cogl.h @@ -61,6 +61,7 @@ #include #include #include +#include #include #include #include diff --git a/cogl/cogl/meson.build b/cogl/cogl/meson.build index b9ff59b75..0297a2485 100644 --- a/cogl/cogl/meson.build +++ b/cogl/cogl/meson.build @@ -96,6 +96,7 @@ cogl_nonintrospected_headers = [ 'cogl-renderer.h', 'cogl-swap-chain.h', 'cogl-onscreen-template.h', + 'cogl-dma-buf-handle.h', 'cogl-display.h', 'cogl-snippet.h', 'cogl-index-buffer.h', @@ -203,6 +204,7 @@ cogl_sources = [ 'cogl-i18n-private.h', 'cogl-debug.h', 'cogl-debug-options.h', + 'cogl-dma-buf-handle.c', 'cogl-gpu-info.c', 'cogl-gpu-info-private.h', 'cogl-context-private.h', diff --git a/cogl/cogl/winsys/cogl-winsys-private.h b/cogl/cogl/winsys/cogl-winsys-private.h index 1ed7bf4fb..9dcf384e2 100644 --- a/cogl/cogl/winsys/cogl-winsys-private.h +++ b/cogl/cogl/winsys/cogl-winsys-private.h @@ -91,6 +91,12 @@ typedef struct _CoglWinsysVtable void (*display_destroy) (CoglDisplay *display); + CoglDmaBufHandle * + (*renderer_create_dma_buf) (CoglRenderer *renderer, + int width, + int height, + GError **error); + gboolean (*context_init) (CoglContext *context, GError **error);