Make DMA buffer allocation format and modifier aware

This makes DMA buffer allocation in all layers take an array of possible
modifiers to allocate using, or zero modifiers if implicit modifiers
should be used.

The format hard coding previously used is moved to the screen cast code,
or in case of the (unused by default) shadow buffer buffers use the same
format as the the CoglOnscreen.

This also means the CoglDmaBufHandle and MetaDrmBuffer got taught how to
distinguish between planes. It's mostly unused in practice, so rather
untested.

Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/3900>
This commit is contained in:
Jonas Ådahl
2022-12-16 17:18:20 +01:00
committed by Marge Bot
parent a4ddba44e9
commit 8509b74532
14 changed files with 351 additions and 114 deletions

View File

@ -44,23 +44,29 @@
struct _CoglDmaBufHandle
{
CoglFramebuffer *framebuffer;
int dmabuf_fd;
int width;
int height;
int stride;
int offset;
int *fds;
uint32_t *strides;
uint32_t *offsets;
int bpp;
int n_planes;
uint32_t format;
uint64_t modifier;
gpointer user_data;
GDestroyNotify destroy_func;
};
CoglDmaBufHandle *
cogl_dma_buf_handle_new (CoglFramebuffer *framebuffer,
int dmabuf_fd,
int width,
int height,
int stride,
int offset,
uint32_t format,
uint64_t modifier,
int n_planes,
int *fds,
uint32_t *strides,
uint32_t *offsets,
int bpp,
gpointer user_data,
GDestroyNotify destroy_func)
@ -68,19 +74,21 @@ cogl_dma_buf_handle_new (CoglFramebuffer *framebuffer,
CoglDmaBufHandle *dmabuf_handle;
g_assert (framebuffer);
g_assert (dmabuf_fd != -1);
dmabuf_handle = g_new0 (CoglDmaBufHandle, 1);
dmabuf_handle->framebuffer = g_object_ref (framebuffer);
dmabuf_handle->dmabuf_fd = dmabuf_fd;
dmabuf_handle->user_data = user_data;
dmabuf_handle->destroy_func = destroy_func;
dmabuf_handle->width = width;
dmabuf_handle->height = height;
dmabuf_handle->stride = stride;
dmabuf_handle->offset = offset;
dmabuf_handle->fds = g_memdup2 (fds, sizeof (*fds) * n_planes);
dmabuf_handle->strides = g_memdup2 (strides, sizeof (*strides) * n_planes);
dmabuf_handle->offsets = g_memdup2 (offsets, sizeof (*offsets) * n_planes);
dmabuf_handle->bpp = bpp;
dmabuf_handle->n_planes = n_planes;
dmabuf_handle->format = format;
dmabuf_handle->modifier = modifier;
return dmabuf_handle;
}
@ -88,6 +96,8 @@ cogl_dma_buf_handle_new (CoglFramebuffer *framebuffer,
void
cogl_dma_buf_handle_free (CoglDmaBufHandle *dmabuf_handle)
{
int i;
g_return_if_fail (dmabuf_handle != NULL);
g_clear_object (&dmabuf_handle->framebuffer);
@ -95,7 +105,12 @@ cogl_dma_buf_handle_free (CoglDmaBufHandle *dmabuf_handle)
if (dmabuf_handle->destroy_func)
g_clear_pointer (&dmabuf_handle->user_data, dmabuf_handle->destroy_func);
g_clear_fd (&dmabuf_handle->dmabuf_fd, NULL);
for (i = 0; i < dmabuf_handle->n_planes; i++)
g_clear_fd (&dmabuf_handle->fds[i], NULL);
g_clear_pointer (&dmabuf_handle->fds, g_free);
g_clear_pointer (&dmabuf_handle->strides, g_free);
g_clear_pointer (&dmabuf_handle->offsets, g_free);
g_free (dmabuf_handle);
}
@ -107,13 +122,15 @@ sync_read (CoglDmaBufHandle *dmabuf_handle,
{
struct dma_buf_sync sync = { 0 };
g_assert (dmabuf_handle->n_planes == 1);
sync.flags = start_or_end | DMA_BUF_SYNC_READ;
while (TRUE)
{
int ret;
ret = ioctl (dmabuf_handle->dmabuf_fd, DMA_BUF_IOCTL_SYNC, &sync);
ret = ioctl (dmabuf_handle->fds[0], DMA_BUF_IOCTL_SYNC, &sync);
if (ret == -1 && errno == EINTR)
{
continue;
@ -154,11 +171,13 @@ cogl_dma_buf_handle_mmap (CoglDmaBufHandle *dmabuf_handle,
size_t size;
gpointer data;
size = dmabuf_handle->height * dmabuf_handle->stride;
g_assert (dmabuf_handle->n_planes == 1);
size = dmabuf_handle->height * dmabuf_handle->strides[0];
data = mmap (NULL, size, PROT_READ, MAP_PRIVATE,
dmabuf_handle->dmabuf_fd,
dmabuf_handle->offset);
dmabuf_handle->fds[0],
dmabuf_handle->offsets[0]);
if (data == MAP_FAILED)
{
g_set_error (error, G_IO_ERROR, g_io_error_from_errno (errno),
@ -176,7 +195,9 @@ cogl_dma_buf_handle_munmap (CoglDmaBufHandle *dmabuf_handle,
{
size_t size;
size = dmabuf_handle->height * dmabuf_handle->stride;
g_assert (dmabuf_handle->n_planes == 1);
size = dmabuf_handle->height * dmabuf_handle->strides[0];
if (munmap (data, size) != 0)
{
g_set_error (error, G_IO_ERROR, g_io_error_from_errno (errno),
@ -194,9 +215,12 @@ cogl_dma_buf_handle_get_framebuffer (CoglDmaBufHandle *dmabuf_handle)
}
int
cogl_dma_buf_handle_get_fd (CoglDmaBufHandle *dmabuf_handle)
cogl_dma_buf_handle_get_fd (CoglDmaBufHandle *dmabuf_handle,
int plane)
{
return dmabuf_handle->dmabuf_fd;
g_return_val_if_fail (plane < dmabuf_handle->n_planes, -1);
return dmabuf_handle->fds[plane];
}
int
@ -212,15 +236,17 @@ cogl_dma_buf_handle_get_height (CoglDmaBufHandle *dmabuf_handle)
}
int
cogl_dma_buf_handle_get_stride (CoglDmaBufHandle *dmabuf_handle)
cogl_dma_buf_handle_get_stride (CoglDmaBufHandle *dmabuf_handle,
int plane)
{
return dmabuf_handle->stride;
return dmabuf_handle->strides[plane];
}
int
cogl_dma_buf_handle_get_offset (CoglDmaBufHandle *dmabuf_handle)
cogl_dma_buf_handle_get_offset (CoglDmaBufHandle *dmabuf_handle,
int plane)
{
return dmabuf_handle->offset;
return dmabuf_handle->offsets[plane];
}
int
@ -228,3 +254,15 @@ cogl_dma_buf_handle_get_bpp (CoglDmaBufHandle *dmabuf_handle)
{
return dmabuf_handle->bpp;
}
int
cogl_dma_buf_handle_get_n_planes (CoglDmaBufHandle *dmabuf_handle)
{
return dmabuf_handle->n_planes;
}
uint64_t
cogl_dma_buf_handle_get_modifier (CoglDmaBufHandle *dmabuf_handle)
{
return dmabuf_handle->modifier;
}

View File

@ -43,11 +43,14 @@
*/
COGL_EXPORT CoglDmaBufHandle *
cogl_dma_buf_handle_new (CoglFramebuffer *framebuffer,
int dmabuf_fd,
int width,
int height,
int stride,
int offset,
uint32_t format,
uint64_t modifier,
int n_planes,
int *fds,
uint32_t *strides,
uint32_t *offsets,
int bpp,
gpointer user_data,
GDestroyNotify destroy_func);
@ -98,7 +101,8 @@ cogl_dma_buf_handle_get_framebuffer (CoglDmaBufHandle *dmabuf_handle);
* Returns: a valid file descriptor
*/
COGL_EXPORT int
cogl_dma_buf_handle_get_fd (CoglDmaBufHandle *dmabuf_handle);
cogl_dma_buf_handle_get_fd (CoglDmaBufHandle *dmabuf_handle,
int plane);
/**
* cogl_dmabuf_handle_get_width:
@ -122,7 +126,8 @@ cogl_dma_buf_handle_get_height (CoglDmaBufHandle *dmabuf_handle);
* Returns: the buffer stride
*/
COGL_EXPORT int
cogl_dma_buf_handle_get_stride (CoglDmaBufHandle *dmabuf_handle);
cogl_dma_buf_handle_get_stride (CoglDmaBufHandle *dmabuf_handle,
int plane);
/**
* cogl_dmabuf_handle_get_offset:
@ -130,7 +135,8 @@ cogl_dma_buf_handle_get_stride (CoglDmaBufHandle *dmabuf_handle);
* Returns: the buffer offset
*/
COGL_EXPORT int
cogl_dma_buf_handle_get_offset (CoglDmaBufHandle *dmabuf_handle);
cogl_dma_buf_handle_get_offset (CoglDmaBufHandle *dmabuf_handle,
int plane);
/**
* cogl_dmabuf_handle_get_bpp:
@ -140,4 +146,20 @@ cogl_dma_buf_handle_get_offset (CoglDmaBufHandle *dmabuf_handle);
COGL_EXPORT int
cogl_dma_buf_handle_get_bpp (CoglDmaBufHandle *dmabuf_handle);
/**
* cogl_dmabuf_handle_get_n_planes: (skip)
*
* Returns: the number of planes
*/
COGL_EXPORT int
cogl_dma_buf_handle_get_n_planes (CoglDmaBufHandle *dmabuf_handle);
/**
* cogl_dmabuf_handle_get_modifier: (skip)
*
* Returns: the the format modifier
*/
COGL_EXPORT uint64_t
cogl_dma_buf_handle_get_modifier (CoglDmaBufHandle *dmabuf_handle);
G_DEFINE_AUTOPTR_CLEANUP_FUNC (CoglDmaBufHandle, cogl_dma_buf_handle_free)

View File

@ -636,7 +636,7 @@ meta_screen_cast_stream_src_calculate_stride (MetaScreenCastStreamSrc *src,
dmabuf_handle = g_hash_table_lookup (priv->dmabuf_handles,
GINT_TO_POINTER (spa_data->fd));
g_assert (dmabuf_handle != NULL);
return cogl_dma_buf_handle_get_stride (dmabuf_handle);
return cogl_dma_buf_handle_get_stride (dmabuf_handle, 0);
}
if (!cogl_pixel_format_from_spa_video_format (priv->video_format.format,
@ -1700,7 +1700,7 @@ on_stream_add_buffer (void *data,
spa_data->type = SPA_DATA_DmaBuf;
spa_data->flags = SPA_DATA_FLAG_READWRITE;
spa_data->fd = cogl_dma_buf_handle_get_fd (dmabuf_handle);
spa_data->fd = cogl_dma_buf_handle_get_fd (dmabuf_handle, 0);
g_hash_table_insert (priv->dmabuf_handles,
GINT_TO_POINTER (spa_data->fd),

View File

@ -115,7 +115,7 @@ meta_screen_cast_get_preferred_modifier (MetaScreenCast *screen_cast,
break;
stride = meta_drm_buffer_get_stride (dmabuf);
offset = meta_drm_buffer_get_offset (dmabuf, 0);
offset = meta_drm_buffer_get_offset_for_plane (dmabuf, 0);
dmabuf_fd = meta_drm_buffer_export_fd (dmabuf, &error);
if (dmabuf_fd == -1)
@ -125,24 +125,26 @@ meta_screen_cast_get_preferred_modifier (MetaScreenCast *screen_cast,
{
*preferred_modifier = DRM_FORMAT_MOD_INVALID;
fb = meta_renderer_native_create_dma_buf_framebuffer (renderer_native,
dmabuf_fd,
width, height,
stride,
offset,
NULL,
format_info->drm_format,
1,
&dmabuf_fd,
&stride,
&offset,
NULL,
&error);
}
else
{
*preferred_modifier = meta_drm_buffer_get_modifier (dmabuf);
fb = meta_renderer_native_create_dma_buf_framebuffer (renderer_native,
dmabuf_fd,
width, height,
stride,
offset,
preferred_modifier,
format_info->drm_format,
1,
&dmabuf_fd,
&stride,
&offset,
preferred_modifier,
&error);
}
close (dmabuf_fd);

View File

@ -36,6 +36,7 @@
#include "backends/native/meta-backend-native-private.h"
#include "backends/native/meta-input-thread.h"
#include <drm_fourcc.h>
#include <stdlib.h>
#include "backends/meta-color-manager.h"

View File

@ -58,6 +58,16 @@ meta_drm_buffer_dumb_export_fd (MetaDrmBuffer *buffer,
return -1;
}
static int
meta_drm_buffer_dumb_export_fd_for_plane (MetaDrmBuffer *buffer,
int plane,
GError **error)
{
g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
"Can't export fd for dumb buffer");
return -1;
}
static int
meta_drm_buffer_dumb_get_width (MetaDrmBuffer *buffer)
{
@ -74,6 +84,12 @@ meta_drm_buffer_dumb_get_height (MetaDrmBuffer *buffer)
return buffer_dumb->height;
}
static int
meta_drm_buffer_dumb_get_n_planes (MetaDrmBuffer *buffer)
{
return 1;
}
static int
meta_drm_buffer_dumb_get_stride (MetaDrmBuffer *buffer)
{
@ -82,6 +98,17 @@ meta_drm_buffer_dumb_get_stride (MetaDrmBuffer *buffer)
return buffer_dumb->stride_bytes;
}
static int
meta_drm_buffer_dumb_get_stride_for_plane (MetaDrmBuffer *buffer,
int plane)
{
MetaDrmBufferDumb *buffer_dumb = META_DRM_BUFFER_DUMB (buffer);
g_warn_if_fail (plane == 0);
return buffer_dumb->stride_bytes;
}
static uint32_t
meta_drm_buffer_dumb_get_format (MetaDrmBuffer *buffer)
{
@ -152,8 +179,8 @@ meta_drm_buffer_dumb_get_bpp (MetaDrmBuffer *buffer)
}
static int
meta_drm_buffer_dumb_get_offset (MetaDrmBuffer *buffer,
int plane)
meta_drm_buffer_dumb_get_offset_for_plane (MetaDrmBuffer *buffer,
int plane)
{
MetaDrmBufferDumb *buffer_dumb = META_DRM_BUFFER_DUMB (buffer);
@ -371,11 +398,14 @@ meta_drm_buffer_dumb_class_init (MetaDrmBufferDumbClass *klass)
object_class->finalize = meta_drm_buffer_dumb_finalize;
buffer_class->export_fd = meta_drm_buffer_dumb_export_fd;
buffer_class->export_fd_for_plane = meta_drm_buffer_dumb_export_fd_for_plane;
buffer_class->get_width = meta_drm_buffer_dumb_get_width;
buffer_class->get_height = meta_drm_buffer_dumb_get_height;
buffer_class->get_n_planes = meta_drm_buffer_dumb_get_n_planes;
buffer_class->get_stride = meta_drm_buffer_dumb_get_stride;
buffer_class->get_stride_for_plane = meta_drm_buffer_dumb_get_stride_for_plane;
buffer_class->get_bpp = meta_drm_buffer_dumb_get_bpp;
buffer_class->get_format = meta_drm_buffer_dumb_get_format;
buffer_class->get_offset = meta_drm_buffer_dumb_get_offset;
buffer_class->get_offset_for_plane = meta_drm_buffer_dumb_get_offset_for_plane;
buffer_class->get_modifier = meta_drm_buffer_dumb_get_modifier;
}

View File

@ -74,6 +74,25 @@ meta_drm_buffer_gbm_export_fd (MetaDrmBuffer *buffer,
return fd;
}
static int
meta_drm_buffer_gbm_export_fd_for_plane (MetaDrmBuffer *buffer,
int plane,
GError **error)
{
MetaDrmBufferGbm *buffer_gbm = META_DRM_BUFFER_GBM (buffer);
int fd;
fd = gbm_bo_get_fd_for_plane (buffer_gbm->bo, plane);
if (fd == -1)
{
g_set_error (error, G_IO_ERROR, g_io_error_from_errno (errno),
"Failed to export buffer fd: %s", g_strerror (errno));
return -1;
}
return fd;
}
static int
meta_drm_buffer_gbm_get_width (MetaDrmBuffer *buffer)
{
@ -90,6 +109,14 @@ meta_drm_buffer_gbm_get_height (MetaDrmBuffer *buffer)
return gbm_bo_get_height (buffer_gbm->bo);
}
static int
meta_drm_buffer_gbm_get_n_planes (MetaDrmBuffer *buffer)
{
MetaDrmBufferGbm *buffer_gbm = META_DRM_BUFFER_GBM (buffer);
return gbm_bo_get_plane_count (buffer_gbm->bo);
}
static int
meta_drm_buffer_gbm_get_stride (MetaDrmBuffer *buffer)
{
@ -98,6 +125,15 @@ meta_drm_buffer_gbm_get_stride (MetaDrmBuffer *buffer)
return gbm_bo_get_stride (buffer_gbm->bo);
}
static int
meta_drm_buffer_gbm_get_stride_for_plane (MetaDrmBuffer *buffer,
int plane)
{
MetaDrmBufferGbm *buffer_gbm = META_DRM_BUFFER_GBM (buffer);
return gbm_bo_get_stride_for_plane (buffer_gbm->bo, plane);
}
static int
meta_drm_buffer_gbm_get_bpp (MetaDrmBuffer *buffer)
{
@ -115,8 +151,8 @@ meta_drm_buffer_gbm_get_format (MetaDrmBuffer *buffer)
}
static int
meta_drm_buffer_gbm_get_offset (MetaDrmBuffer *buffer,
int plane)
meta_drm_buffer_gbm_get_offset_for_plane (MetaDrmBuffer *buffer,
int plane)
{
MetaDrmBufferGbm *buffer_gbm = META_DRM_BUFFER_GBM (buffer);
@ -411,12 +447,15 @@ meta_drm_buffer_gbm_class_init (MetaDrmBufferGbmClass *klass)
object_class->finalize = meta_drm_buffer_gbm_finalize;
buffer_class->export_fd = meta_drm_buffer_gbm_export_fd;
buffer_class->export_fd_for_plane = meta_drm_buffer_gbm_export_fd_for_plane;
buffer_class->ensure_fb_id = meta_drm_buffer_gbm_ensure_fb_id;
buffer_class->get_width = meta_drm_buffer_gbm_get_width;
buffer_class->get_height = meta_drm_buffer_gbm_get_height;
buffer_class->get_n_planes = meta_drm_buffer_gbm_get_n_planes;
buffer_class->get_stride = meta_drm_buffer_gbm_get_stride;
buffer_class->get_stride_for_plane = meta_drm_buffer_gbm_get_stride_for_plane;
buffer_class->get_bpp = meta_drm_buffer_gbm_get_bpp;
buffer_class->get_format = meta_drm_buffer_gbm_get_format;
buffer_class->get_offset = meta_drm_buffer_gbm_get_offset;
buffer_class->get_offset_for_plane = meta_drm_buffer_gbm_get_offset_for_plane;
buffer_class->get_modifier = meta_drm_buffer_gbm_get_modifier;
}

View File

@ -52,6 +52,17 @@ meta_drm_buffer_import_export_fd (MetaDrmBuffer *buffer,
error);
}
static int
meta_drm_buffer_import_export_fd_for_plane (MetaDrmBuffer *buffer,
int plane,
GError **error)
{
MetaDrmBufferImport *buffer_import = META_DRM_BUFFER_IMPORT (buffer);
MetaDrmBuffer *importee = META_DRM_BUFFER (buffer_import->importee);
return meta_drm_buffer_export_fd_for_plane (importee, plane, error);
}
static int
meta_drm_buffer_import_get_width (MetaDrmBuffer *buffer)
{
@ -68,6 +79,15 @@ meta_drm_buffer_import_get_height (MetaDrmBuffer *buffer)
return meta_drm_buffer_get_height (META_DRM_BUFFER (buffer_import->importee));
}
static int
meta_drm_buffer_import_get_n_planes (MetaDrmBuffer *buffer)
{
MetaDrmBufferImport *buffer_import = META_DRM_BUFFER_IMPORT (buffer);
MetaDrmBuffer *importee = META_DRM_BUFFER (buffer_import->importee);
return meta_drm_buffer_get_n_planes (importee);
}
static int
meta_drm_buffer_import_get_stride (MetaDrmBuffer *buffer)
{
@ -76,6 +96,16 @@ meta_drm_buffer_import_get_stride (MetaDrmBuffer *buffer)
return meta_drm_buffer_get_stride (META_DRM_BUFFER (buffer_import->importee));
}
static int
meta_drm_buffer_import_get_stride_for_plane (MetaDrmBuffer *buffer,
int plane)
{
MetaDrmBufferImport *buffer_import = META_DRM_BUFFER_IMPORT (buffer);
MetaDrmBuffer *importee = META_DRM_BUFFER (buffer_import->importee);
return meta_drm_buffer_get_stride_for_plane (importee, plane);
}
static int
meta_drm_buffer_import_get_bpp (MetaDrmBuffer *buffer)
{
@ -93,13 +123,13 @@ meta_drm_buffer_import_get_format (MetaDrmBuffer *buffer)
}
static int
meta_drm_buffer_import_get_offset (MetaDrmBuffer *buffer,
int offset)
meta_drm_buffer_import_get_offset_for_plane (MetaDrmBuffer *buffer,
int plane)
{
MetaDrmBufferImport *buffer_import = META_DRM_BUFFER_IMPORT (buffer);
MetaDrmBuffer *importee = META_DRM_BUFFER (buffer_import->importee);
return meta_drm_buffer_get_offset (importee, offset);
return meta_drm_buffer_get_offset_for_plane (importee, plane);
}
static uint64_t
@ -239,11 +269,14 @@ meta_drm_buffer_import_class_init (MetaDrmBufferImportClass *klass)
object_class->finalize = meta_drm_buffer_import_finalize;
buffer_class->export_fd = meta_drm_buffer_import_export_fd;
buffer_class->export_fd_for_plane = meta_drm_buffer_import_export_fd_for_plane;
buffer_class->get_width = meta_drm_buffer_import_get_width;
buffer_class->get_height = meta_drm_buffer_import_get_height;
buffer_class->get_n_planes = meta_drm_buffer_import_get_n_planes;
buffer_class->get_stride = meta_drm_buffer_import_get_stride;
buffer_class->get_stride_for_plane = meta_drm_buffer_import_get_stride_for_plane;
buffer_class->get_bpp = meta_drm_buffer_import_get_bpp;
buffer_class->get_format = meta_drm_buffer_import_get_format;
buffer_class->get_offset = meta_drm_buffer_import_get_offset;
buffer_class->get_offset_for_plane = meta_drm_buffer_import_get_offset_for_plane;
buffer_class->get_modifier = meta_drm_buffer_import_get_modifier;
}

View File

@ -40,16 +40,26 @@ struct _MetaDrmBufferClass
int (* export_fd) (MetaDrmBuffer *buffer,
GError **error);
int (* export_fd_for_plane) (MetaDrmBuffer *buffer,
int plane,
GError **error);
gboolean (* ensure_fb_id) (MetaDrmBuffer *buffer,
GError **error);
int (* get_width) (MetaDrmBuffer *buffer);
int (* get_height) (MetaDrmBuffer *buffer);
int (* get_n_planes) (MetaDrmBuffer *buffer);
int (* get_stride) (MetaDrmBuffer *buffer);
int (* get_stride_for_plane) (MetaDrmBuffer *buffer,
int plane);
int (* get_bpp) (MetaDrmBuffer *buffer);
uint32_t (* get_format) (MetaDrmBuffer *buffer);
int (* get_offset) (MetaDrmBuffer *buffer,
int plane);
int (* get_offset_for_plane) (MetaDrmBuffer *buffer,
int plane);
uint64_t (* get_modifier) (MetaDrmBuffer *buffer);
};

View File

@ -199,6 +199,16 @@ meta_drm_buffer_export_fd (MetaDrmBuffer *buffer,
return META_DRM_BUFFER_GET_CLASS (buffer)->export_fd (buffer, error);
}
int
meta_drm_buffer_export_fd_for_plane (MetaDrmBuffer *buffer,
int plane,
GError **error)
{
return META_DRM_BUFFER_GET_CLASS (buffer)->export_fd_for_plane (buffer,
plane,
error);
}
uint32_t
meta_drm_buffer_get_fb_id (MetaDrmBuffer *buffer)
{
@ -227,12 +237,26 @@ meta_drm_buffer_get_height (MetaDrmBuffer *buffer)
return META_DRM_BUFFER_GET_CLASS (buffer)->get_height (buffer);
}
int
meta_drm_buffer_get_n_planes (MetaDrmBuffer *buffer)
{
return META_DRM_BUFFER_GET_CLASS (buffer)->get_n_planes (buffer);
}
int
meta_drm_buffer_get_stride (MetaDrmBuffer *buffer)
{
return META_DRM_BUFFER_GET_CLASS (buffer)->get_stride (buffer);
}
int
meta_drm_buffer_get_stride_for_plane (MetaDrmBuffer *buffer,
int plane)
{
return META_DRM_BUFFER_GET_CLASS (buffer)->get_stride_for_plane (buffer,
plane);
}
int
meta_drm_buffer_get_bpp (MetaDrmBuffer *buffer)
{
@ -246,10 +270,11 @@ meta_drm_buffer_get_format (MetaDrmBuffer *buffer)
}
int
meta_drm_buffer_get_offset (MetaDrmBuffer *buffer,
int plane)
meta_drm_buffer_get_offset_for_plane (MetaDrmBuffer *buffer,
int plane)
{
return META_DRM_BUFFER_GET_CLASS (buffer)->get_offset (buffer, plane);
return META_DRM_BUFFER_GET_CLASS (buffer)->get_offset_for_plane (buffer,
plane);
}
uint64_t

View File

@ -42,6 +42,10 @@ G_DECLARE_DERIVABLE_TYPE (MetaDrmBuffer,
int meta_drm_buffer_export_fd (MetaDrmBuffer *buffer,
GError **error);
int meta_drm_buffer_export_fd_for_plane (MetaDrmBuffer *buffer,
int plane,
GError **error);
gboolean meta_drm_buffer_ensure_fb_id (MetaDrmBuffer *buffer,
GError **error);
@ -54,13 +58,18 @@ int meta_drm_buffer_get_width (MetaDrmBuffer *buffer);
int meta_drm_buffer_get_height (MetaDrmBuffer *buffer);
int meta_drm_buffer_get_n_planes (MetaDrmBuffer *buffer);
int meta_drm_buffer_get_stride (MetaDrmBuffer *buffer);
int meta_drm_buffer_get_stride_for_plane (MetaDrmBuffer *buffer,
int plane);
int meta_drm_buffer_get_bpp (MetaDrmBuffer *buffer);
uint32_t meta_drm_buffer_get_format (MetaDrmBuffer *buffer);
int meta_drm_buffer_get_offset (MetaDrmBuffer *buffer,
int plane);
int meta_drm_buffer_get_offset_for_plane (MetaDrmBuffer *buffer,
int plane);
uint64_t meta_drm_buffer_get_modifier (MetaDrmBuffer *buffer);

View File

@ -988,12 +988,14 @@ copy_shared_framebuffer_primary_gpu (CoglOnscreen *onscre
MetaRendererNativeGpuData *primary_gpu_data;
MetaDrmBufferDumb *buffer_dumb;
MetaDrmBuffer *buffer;
int width, height, stride;
uint32_t drm_format;
int width, height;
CoglFramebuffer *dmabuf_fb;
int dmabuf_fd;
g_autoptr (GError) error = NULL;
const MetaFormatInfo *format_info;
uint32_t stride;
uint32_t offset;
uint32_t drm_format;
uint64_t modifier;
int n_rectangles;
@ -1015,6 +1017,8 @@ copy_shared_framebuffer_primary_gpu (CoglOnscreen *onscre
width = meta_drm_buffer_get_width (buffer);
height = meta_drm_buffer_get_height (buffer);
stride = meta_drm_buffer_get_stride (buffer);
offset = 0;
modifier = DRM_FORMAT_MOD_LINEAR;
drm_format = meta_drm_buffer_get_format (buffer);
g_assert (cogl_framebuffer_get_width (framebuffer) == width);
@ -1034,12 +1038,14 @@ copy_shared_framebuffer_primary_gpu (CoglOnscreen *onscre
modifier = DRM_FORMAT_MOD_LINEAR;
dmabuf_fb =
meta_renderer_native_create_dma_buf_framebuffer (renderer_native,
dmabuf_fd,
width,
height,
stride,
0, &modifier,
drm_format,
1,
&dmabuf_fd,
&stride,
&offset,
&modifier,
&error);
if (error)

View File

@ -93,13 +93,14 @@ void meta_renderer_native_queue_power_save_page_flip (MetaRendererNative *render
CoglOnscreen *onscreen);
CoglFramebuffer * meta_renderer_native_create_dma_buf_framebuffer (MetaRendererNative *renderer_native,
int dmabuf_fd,
uint32_t width,
uint32_t height,
uint32_t stride,
uint32_t offset,
uint64_t *modifier,
uint32_t drm_format,
int n_planes,
int *fds,
uint32_t *strides,
uint32_t *offsets,
uint64_t *modifiers,
GError **error);
gboolean meta_renderer_native_pop_pending_mode_set (MetaRendererNative *renderer_native,

View File

@ -649,13 +649,14 @@ cogl_context_from_renderer_native (MetaRendererNative *renderer_native)
CoglFramebuffer *
meta_renderer_native_create_dma_buf_framebuffer (MetaRendererNative *renderer_native,
int dmabuf_fd,
uint32_t width,
uint32_t height,
uint32_t stride,
uint32_t offset,
uint64_t *modifier,
uint32_t drm_format,
int n_planes,
int *fds,
uint32_t *strides,
uint32_t *offsets,
uint64_t *modifiers,
GError **error)
{
CoglContext *cogl_context =
@ -666,8 +667,6 @@ meta_renderer_native_create_dma_buf_framebuffer (MetaRendererNative *renderer_n
EGLDisplay egl_display = cogl_renderer_egl->edpy;
MetaEgl *egl = meta_renderer_native_get_egl (renderer_native);
EGLImageKHR egl_image;
uint32_t strides[1];
uint32_t offsets[1];
CoglPixelFormat cogl_format;
CoglEglImageFlags flags;
CoglTexture *cogl_tex;
@ -678,18 +677,16 @@ meta_renderer_native_create_dma_buf_framebuffer (MetaRendererNative *renderer_n
g_assert (format_info);
cogl_format = format_info->cogl_format;
strides[0] = stride;
offsets[0] = offset;
egl_image = meta_egl_create_dmabuf_image (egl,
egl_display,
width,
height,
drm_format,
1 /* n_planes */,
&dmabuf_fd,
n_planes,
fds,
strides,
offsets,
modifier,
modifiers,
error);
if (egl_image == EGL_NO_IMAGE_KHR)
return NULL;
@ -957,6 +954,16 @@ meta_renderer_native_queue_mode_set_update (MetaRendererNative *renderer_native,
meta_kms_update_free (new_kms_update);
}
static void
close_fds (int *fds,
int n_fds)
{
int i;
for (i = 0; i < n_fds; i++)
close (fds[i]);
}
static CoglDmaBufHandle *
meta_renderer_native_create_dma_buf (CoglRenderer *cogl_renderer,
CoglPixelFormat format,
@ -977,11 +984,15 @@ meta_renderer_native_create_dma_buf (CoglRenderer *cogl_renderer,
MetaRenderDevice *render_device;
MetaDrmBufferFlags flags;
g_autoptr (MetaDrmBuffer) buffer = NULL;
int dmabuf_fd;
uint32_t stride;
uint32_t offset;
uint64_t buffer_modifier;
int n_planes;
int *fds;
uint32_t *offsets;
uint32_t *strides;
uint64_t *plane_modifiers = NULL;
uint32_t bpp;
uint32_t drm_format;
int i;
CoglFramebuffer *dmabuf_fb;
CoglDmaBufHandle *dmabuf_handle;
const MetaFormatInfo *format_info;
@ -1007,49 +1018,59 @@ meta_renderer_native_create_dma_buf (CoglRenderer *cogl_renderer,
if (!buffer)
return NULL;
dmabuf_fd = meta_drm_buffer_export_fd (buffer, error);
if (dmabuf_fd == -1)
return NULL;
stride = meta_drm_buffer_get_stride (buffer);
offset = meta_drm_buffer_get_offset (buffer, 0);
buffer_modifier = meta_drm_buffer_get_modifier (buffer);
bpp = meta_drm_buffer_get_bpp (buffer);
if (n_modifiers)
{
uint64_t modifier = meta_drm_buffer_get_modifier (buffer);
dmabuf_fb =
meta_renderer_native_create_dma_buf_framebuffer (renderer_native,
dmabuf_fd,
width, height,
stride,
offset,
&modifier,
drm_format,
error);
}
else
n_planes = meta_drm_buffer_get_n_planes (buffer);
fds = g_newa (int, n_planes);
offsets = g_newa (uint32_t, n_planes);
strides = g_newa (uint32_t, n_planes);
if (n_modifiers > 0)
plane_modifiers = g_newa (uint64_t, n_planes);
for (i = 0; i < n_planes; i++)
{
dmabuf_fb =
meta_renderer_native_create_dma_buf_framebuffer (renderer_native,
dmabuf_fd,
width, height,
stride,
offset,
NULL,
drm_format,
error);
fds[i] = meta_drm_buffer_export_fd_for_plane (buffer, i, error);
if (fds[i] == -1)
{
close_fds (fds, i);
return NULL;
}
offsets[i] = meta_drm_buffer_get_offset_for_plane (buffer, i);
strides[i] = meta_drm_buffer_get_stride_for_plane (buffer, i);
if (n_modifiers > 0)
plane_modifiers[i] = buffer_modifier;
}
dmabuf_fb =
meta_renderer_native_create_dma_buf_framebuffer (renderer_native,
width,
height,
drm_format,
n_planes,
fds,
strides,
offsets,
plane_modifiers,
error);
close_fds (fds, n_planes);
if (!dmabuf_fb)
{
close (dmabuf_fd);
return NULL;
}
return NULL;
dmabuf_handle =
cogl_dma_buf_handle_new (dmabuf_fb, dmabuf_fd,
width, height, stride, offset, bpp,
cogl_dma_buf_handle_new (dmabuf_fb,
width, height,
format,
buffer_modifier,
n_planes,
fds,
strides,
offsets,
bpp,
g_steal_pointer (&buffer),
g_object_unref);
g_object_unref (dmabuf_fb);