native: Consolidate DRM buffer management to MetaDrmBuffer types
This commit consolidates DRM buffer management to the MetaDrmBuffer types, where the base type handles the common functionality (such as managing the framebuffer id using drmModeAdd*/RMFb()), and the sub types their corresponding type specific behavior. This means that drmModeAdd*/RmFB() handling is moved from meta-gpu-kms.c to meta-drm-buffer.c; dumb buffer allocation/management from meta-renderer-native.c. Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1488>
This commit is contained in:
parent
40e5633fab
commit
84bde805fe
@ -25,41 +25,322 @@
|
||||
|
||||
#include "backends/native/meta-drm-buffer-dumb.h"
|
||||
|
||||
#include <xf86drm.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/mman.h>
|
||||
|
||||
#include "backends/native/meta-kms-device-private.h"
|
||||
#include "backends/native/meta-kms-impl-device.h"
|
||||
#include "backends/native/meta-kms-private.h"
|
||||
|
||||
struct _MetaDrmBufferDumb
|
||||
{
|
||||
MetaDrmBuffer parent;
|
||||
|
||||
uint32_t fb_id;
|
||||
uint32_t handle;
|
||||
void *map;
|
||||
uint64_t map_size;
|
||||
int width;
|
||||
int height;
|
||||
int stride_bytes;
|
||||
uint32_t drm_format;
|
||||
int dmabuf_fd;
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE (MetaDrmBufferDumb, meta_drm_buffer_dumb, META_TYPE_DRM_BUFFER)
|
||||
|
||||
MetaDrmBufferDumb *
|
||||
meta_drm_buffer_dumb_new (uint32_t dumb_fb_id)
|
||||
static int
|
||||
meta_drm_buffer_dumb_get_width (MetaDrmBuffer *buffer)
|
||||
{
|
||||
MetaDrmBufferDumb *buffer_dumb = META_DRM_BUFFER_DUMB (buffer);
|
||||
|
||||
return buffer_dumb->width;
|
||||
}
|
||||
|
||||
static int
|
||||
meta_drm_buffer_dumb_get_height (MetaDrmBuffer *buffer)
|
||||
{
|
||||
MetaDrmBufferDumb *buffer_dumb = META_DRM_BUFFER_DUMB (buffer);
|
||||
|
||||
return buffer_dumb->height;
|
||||
}
|
||||
|
||||
static int
|
||||
meta_drm_buffer_dumb_get_stride (MetaDrmBuffer *buffer)
|
||||
{
|
||||
MetaDrmBufferDumb *buffer_dumb = META_DRM_BUFFER_DUMB (buffer);
|
||||
|
||||
return buffer_dumb->stride_bytes;
|
||||
}
|
||||
|
||||
static uint32_t
|
||||
meta_drm_buffer_dumb_get_format (MetaDrmBuffer *buffer)
|
||||
{
|
||||
MetaDrmBufferDumb *buffer_dumb = META_DRM_BUFFER_DUMB (buffer);
|
||||
|
||||
return buffer_dumb->drm_format;
|
||||
}
|
||||
|
||||
typedef struct
|
||||
{
|
||||
MetaDrmBufferDumb *buffer_dumb;
|
||||
|
||||
buffer_dumb = g_object_new (META_TYPE_DRM_BUFFER_DUMB, NULL);
|
||||
buffer_dumb->fb_id = dumb_fb_id;
|
||||
int out_dmabuf_fd;
|
||||
} HandleToFdData;
|
||||
|
||||
static gpointer
|
||||
handle_to_fd_in_impl (MetaKmsImpl *impl,
|
||||
gpointer user_data,
|
||||
GError **error)
|
||||
{
|
||||
HandleToFdData *data = user_data;
|
||||
MetaDrmBufferDumb *buffer_dumb = data->buffer_dumb;
|
||||
MetaDrmBuffer *buffer = META_DRM_BUFFER (buffer_dumb);
|
||||
MetaKmsDevice *device = meta_drm_buffer_get_device (buffer);
|
||||
MetaKmsImplDevice *impl_device = meta_kms_device_get_impl_device (device);
|
||||
int fd;
|
||||
int ret;
|
||||
int dmabuf_fd;
|
||||
|
||||
fd = meta_kms_impl_device_get_fd (impl_device);
|
||||
|
||||
ret = drmPrimeHandleToFD (fd, buffer_dumb->handle, DRM_CLOEXEC,
|
||||
&dmabuf_fd);
|
||||
if (ret)
|
||||
{
|
||||
g_set_error (error, G_IO_ERROR, g_io_error_from_errno (-ret),
|
||||
"drmPrimeHandleToFd: %s", g_strerror (-ret));
|
||||
return GINT_TO_POINTER (FALSE);
|
||||
}
|
||||
|
||||
data->out_dmabuf_fd = dmabuf_fd;
|
||||
|
||||
return GINT_TO_POINTER (TRUE);
|
||||
}
|
||||
|
||||
int
|
||||
meta_drm_buffer_dumb_ensure_dmabuf_fd (MetaDrmBufferDumb *buffer_dumb,
|
||||
GError **error)
|
||||
{
|
||||
MetaDrmBuffer *buffer = META_DRM_BUFFER (buffer_dumb);
|
||||
MetaKmsDevice *device = meta_drm_buffer_get_device (buffer);
|
||||
HandleToFdData data;
|
||||
|
||||
if (buffer_dumb->dmabuf_fd != -1)
|
||||
return buffer_dumb->dmabuf_fd;
|
||||
|
||||
data = (HandleToFdData) {
|
||||
.buffer_dumb = buffer_dumb,
|
||||
};
|
||||
|
||||
if (!meta_kms_run_impl_task_sync (meta_kms_device_get_kms (device),
|
||||
handle_to_fd_in_impl,
|
||||
&data,
|
||||
error))
|
||||
return -1;
|
||||
|
||||
buffer_dumb->dmabuf_fd = data.out_dmabuf_fd;
|
||||
return buffer_dumb->dmabuf_fd;
|
||||
}
|
||||
|
||||
void *
|
||||
meta_drm_buffer_dumb_get_data (MetaDrmBufferDumb *buffer_dumb)
|
||||
{
|
||||
return buffer_dumb->map;
|
||||
}
|
||||
|
||||
typedef struct
|
||||
{
|
||||
MetaDrmBufferDumb *buffer_dumb;
|
||||
int width;
|
||||
int height;
|
||||
uint32_t format;
|
||||
} InitDumbData;
|
||||
|
||||
static gpointer
|
||||
init_dumb_buffer_in_impl (MetaKmsImpl *impl,
|
||||
gpointer user_data,
|
||||
GError **error)
|
||||
{
|
||||
InitDumbData *data = user_data;
|
||||
MetaDrmBufferDumb *buffer_dumb = data->buffer_dumb;
|
||||
MetaDrmBuffer *buffer = META_DRM_BUFFER (buffer_dumb);
|
||||
MetaKmsDevice *device = meta_drm_buffer_get_device (buffer);
|
||||
MetaKmsImplDevice *impl_device = meta_kms_device_get_impl_device (device);
|
||||
int fd;
|
||||
struct drm_mode_create_dumb create_arg;
|
||||
struct drm_mode_destroy_dumb destroy_arg;
|
||||
struct drm_mode_map_dumb map_arg;
|
||||
void *map;
|
||||
MetaDrmFbArgs fb_args;
|
||||
|
||||
fd = meta_kms_impl_device_get_fd (impl_device);
|
||||
|
||||
create_arg = (struct drm_mode_create_dumb) {
|
||||
.bpp = 32, /* RGBX8888 */
|
||||
.width = data->width,
|
||||
.height = data->height
|
||||
};
|
||||
if (drmIoctl (fd, DRM_IOCTL_MODE_CREATE_DUMB, &create_arg) != 0)
|
||||
{
|
||||
g_set_error (error, G_IO_ERROR,
|
||||
G_IO_ERROR_FAILED,
|
||||
"Failed to create dumb drm buffer: %s",
|
||||
g_strerror (errno));
|
||||
goto err_ioctl;
|
||||
}
|
||||
|
||||
fb_args = (MetaDrmFbArgs) {
|
||||
.width = data->width,
|
||||
.height = data->height,
|
||||
.format = data->format,
|
||||
.handles = { create_arg.handle },
|
||||
.strides = { create_arg.pitch },
|
||||
};
|
||||
if (!meta_drm_buffer_ensure_fb_id (buffer, FALSE, &fb_args, error))
|
||||
goto err_add_fb;
|
||||
|
||||
map_arg = (struct drm_mode_map_dumb) {
|
||||
.handle = create_arg.handle
|
||||
};
|
||||
if (drmIoctl (fd, DRM_IOCTL_MODE_MAP_DUMB,
|
||||
&map_arg) != 0)
|
||||
{
|
||||
g_set_error (error, G_IO_ERROR,
|
||||
G_IO_ERROR_FAILED,
|
||||
"Failed to map dumb drm buffer: %s",
|
||||
g_strerror (errno));
|
||||
goto err_map_dumb;
|
||||
}
|
||||
|
||||
map = mmap (NULL, create_arg.size, PROT_WRITE, MAP_SHARED,
|
||||
fd, map_arg.offset);
|
||||
if (map == MAP_FAILED)
|
||||
{
|
||||
g_set_error (error, G_IO_ERROR,
|
||||
G_IO_ERROR_FAILED,
|
||||
"Failed to mmap dumb drm buffer memory: %s",
|
||||
g_strerror (errno));
|
||||
goto err_mmap;
|
||||
}
|
||||
|
||||
buffer_dumb->handle = create_arg.handle;
|
||||
buffer_dumb->map = map;
|
||||
buffer_dumb->map_size = create_arg.size;
|
||||
buffer_dumb->width = data->width;
|
||||
buffer_dumb->height = data->height;
|
||||
buffer_dumb->stride_bytes = create_arg.pitch;
|
||||
buffer_dumb->drm_format = data->format;
|
||||
|
||||
return FALSE;
|
||||
|
||||
err_mmap:
|
||||
err_map_dumb:
|
||||
err_add_fb:
|
||||
destroy_arg = (struct drm_mode_destroy_dumb) {
|
||||
.handle = create_arg.handle
|
||||
};
|
||||
drmIoctl (fd, DRM_IOCTL_MODE_DESTROY_DUMB, &destroy_arg);
|
||||
|
||||
err_ioctl:
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
MetaDrmBufferDumb *
|
||||
meta_drm_buffer_dumb_new (MetaKmsDevice *device,
|
||||
int width,
|
||||
int height,
|
||||
uint32_t format,
|
||||
GError **error)
|
||||
{
|
||||
MetaDrmBufferDumb *buffer_dumb;
|
||||
InitDumbData data;
|
||||
|
||||
buffer_dumb = g_object_new (META_TYPE_DRM_BUFFER_DUMB,
|
||||
"device", device,
|
||||
NULL);
|
||||
|
||||
data = (InitDumbData) {
|
||||
.buffer_dumb = buffer_dumb,
|
||||
.width = width,
|
||||
.height = height,
|
||||
.format = format,
|
||||
};
|
||||
|
||||
if (meta_kms_run_impl_task_sync (meta_kms_device_get_kms (device),
|
||||
init_dumb_buffer_in_impl,
|
||||
&data,
|
||||
error))
|
||||
{
|
||||
g_object_unref (buffer_dumb);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return buffer_dumb;
|
||||
}
|
||||
|
||||
static uint32_t
|
||||
meta_drm_buffer_dumb_get_fb_id (MetaDrmBuffer *buffer)
|
||||
static gpointer
|
||||
destroy_dumb_in_impl (MetaKmsImpl *impl,
|
||||
gpointer user_data,
|
||||
GError **error)
|
||||
{
|
||||
return META_DRM_BUFFER_DUMB (buffer)->fb_id;
|
||||
MetaDrmBufferDumb *buffer_dumb = user_data;
|
||||
MetaDrmBuffer *buffer = META_DRM_BUFFER (buffer_dumb);
|
||||
MetaKmsDevice *device = meta_drm_buffer_get_device (buffer);
|
||||
MetaKmsImplDevice *impl_device = meta_kms_device_get_impl_device (device);
|
||||
int fd;
|
||||
struct drm_mode_destroy_dumb destroy_arg;
|
||||
|
||||
fd = meta_kms_impl_device_get_fd (impl_device);
|
||||
|
||||
munmap (buffer_dumb->map, buffer_dumb->map_size);
|
||||
|
||||
destroy_arg = (struct drm_mode_destroy_dumb) {
|
||||
.handle = buffer_dumb->handle
|
||||
};
|
||||
drmIoctl (fd, DRM_IOCTL_MODE_DESTROY_DUMB, &destroy_arg);
|
||||
|
||||
if (buffer_dumb->dmabuf_fd != -1)
|
||||
close (buffer_dumb->dmabuf_fd);
|
||||
|
||||
return GINT_TO_POINTER (TRUE);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_drm_buffer_dumb_finalize (GObject *object)
|
||||
{
|
||||
MetaDrmBufferDumb *buffer_dumb = META_DRM_BUFFER_DUMB (object);
|
||||
|
||||
if (buffer_dumb->handle)
|
||||
{
|
||||
MetaDrmBuffer *buffer = META_DRM_BUFFER (buffer_dumb);
|
||||
MetaKmsDevice *device = meta_drm_buffer_get_device (buffer);
|
||||
|
||||
meta_kms_run_impl_task_sync (meta_kms_device_get_kms (device),
|
||||
destroy_dumb_in_impl,
|
||||
buffer_dumb,
|
||||
NULL);
|
||||
}
|
||||
|
||||
G_OBJECT_CLASS (meta_drm_buffer_dumb_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_drm_buffer_dumb_init (MetaDrmBufferDumb *buffer_dumb)
|
||||
{
|
||||
buffer_dumb->dmabuf_fd = -1;
|
||||
}
|
||||
|
||||
static void
|
||||
meta_drm_buffer_dumb_class_init (MetaDrmBufferDumbClass *klass)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
MetaDrmBufferClass *buffer_class = META_DRM_BUFFER_CLASS (klass);
|
||||
|
||||
buffer_class->get_fb_id = meta_drm_buffer_dumb_get_fb_id;
|
||||
object_class->finalize = meta_drm_buffer_dumb_finalize;
|
||||
|
||||
buffer_class->get_width = meta_drm_buffer_dumb_get_width;
|
||||
buffer_class->get_height = meta_drm_buffer_dumb_get_height;
|
||||
buffer_class->get_stride = meta_drm_buffer_dumb_get_stride;
|
||||
buffer_class->get_format = meta_drm_buffer_dumb_get_format;
|
||||
}
|
||||
|
@ -22,7 +22,8 @@
|
||||
#ifndef META_DRM_BUFFER_DUMB_H
|
||||
#define META_DRM_BUFFER_DUMB_H
|
||||
|
||||
#include "backends/native/meta-drm-buffer.h"
|
||||
#include "backends/native/meta-drm-buffer-private.h"
|
||||
#include "backends/native/meta-kms-device.h"
|
||||
|
||||
#define META_TYPE_DRM_BUFFER_DUMB (meta_drm_buffer_dumb_get_type ())
|
||||
G_DECLARE_FINAL_TYPE (MetaDrmBufferDumb,
|
||||
@ -30,6 +31,15 @@ G_DECLARE_FINAL_TYPE (MetaDrmBufferDumb,
|
||||
META, DRM_BUFFER_DUMB,
|
||||
MetaDrmBuffer)
|
||||
|
||||
MetaDrmBufferDumb * meta_drm_buffer_dumb_new (uint32_t dumb_fb_id);
|
||||
MetaDrmBufferDumb * meta_drm_buffer_dumb_new (MetaKmsDevice *device,
|
||||
int width,
|
||||
int height,
|
||||
uint32_t format,
|
||||
GError **error);
|
||||
|
||||
int meta_drm_buffer_dumb_ensure_dmabuf_fd (MetaDrmBufferDumb *buffer_dumb,
|
||||
GError **error);
|
||||
|
||||
void * meta_drm_buffer_dumb_get_data (MetaDrmBufferDumb *buffer_dumb);
|
||||
|
||||
#endif /* META_DRM_BUFFER_DUMB_H */
|
||||
|
@ -23,7 +23,6 @@
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "backends/native/meta-cogl-utils.h"
|
||||
#include "backends/native/meta-drm-buffer-gbm.h"
|
||||
|
||||
#include <drm_fourcc.h>
|
||||
@ -31,18 +30,16 @@
|
||||
#include <xf86drm.h>
|
||||
#include <xf86drmMode.h>
|
||||
|
||||
#define INVALID_FB_ID 0U
|
||||
#include "backends/native/meta-drm-buffer-private.h"
|
||||
#include "backends/native/meta-cogl-utils.h"
|
||||
|
||||
struct _MetaDrmBufferGbm
|
||||
{
|
||||
MetaDrmBuffer parent;
|
||||
|
||||
MetaGpuKms *gpu_kms;
|
||||
|
||||
struct gbm_surface *surface;
|
||||
|
||||
struct gbm_bo *bo;
|
||||
uint32_t fb_id;
|
||||
};
|
||||
|
||||
static void
|
||||
@ -58,13 +55,45 @@ meta_drm_buffer_gbm_get_bo (MetaDrmBufferGbm *buffer_gbm)
|
||||
return buffer_gbm->bo;
|
||||
}
|
||||
|
||||
static int
|
||||
meta_drm_buffer_gbm_get_width (MetaDrmBuffer *buffer)
|
||||
{
|
||||
MetaDrmBufferGbm *buffer_gbm = META_DRM_BUFFER_GBM (buffer);
|
||||
|
||||
return gbm_bo_get_width (buffer_gbm->bo);
|
||||
}
|
||||
|
||||
static int
|
||||
meta_drm_buffer_gbm_get_height (MetaDrmBuffer *buffer)
|
||||
{
|
||||
MetaDrmBufferGbm *buffer_gbm = META_DRM_BUFFER_GBM (buffer);
|
||||
|
||||
return gbm_bo_get_height (buffer_gbm->bo);
|
||||
}
|
||||
|
||||
static int
|
||||
meta_drm_buffer_gbm_get_stride (MetaDrmBuffer *buffer)
|
||||
{
|
||||
MetaDrmBufferGbm *buffer_gbm = META_DRM_BUFFER_GBM (buffer);
|
||||
|
||||
return gbm_bo_get_stride (buffer_gbm->bo);
|
||||
}
|
||||
|
||||
static uint32_t
|
||||
meta_drm_buffer_gbm_get_format (MetaDrmBuffer *buffer)
|
||||
{
|
||||
MetaDrmBufferGbm *buffer_gbm = META_DRM_BUFFER_GBM (buffer);
|
||||
|
||||
return gbm_bo_get_format (buffer_gbm->bo);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
init_fb_id (MetaDrmBufferGbm *buffer_gbm,
|
||||
struct gbm_bo *bo,
|
||||
gboolean use_modifiers,
|
||||
GError **error)
|
||||
{
|
||||
MetaGpuKmsFBArgs fb_args = { 0, };
|
||||
MetaDrmFbArgs fb_args = { 0, };
|
||||
|
||||
if (gbm_bo_get_handle_for_plane (bo, 0).s32 == -1)
|
||||
{
|
||||
@ -91,10 +120,8 @@ init_fb_id (MetaDrmBufferGbm *buffer_gbm,
|
||||
fb_args.height = gbm_bo_get_height (bo);
|
||||
fb_args.format = gbm_bo_get_format (bo);
|
||||
|
||||
if (!meta_gpu_kms_add_fb (buffer_gbm->gpu_kms,
|
||||
use_modifiers,
|
||||
&fb_args,
|
||||
&buffer_gbm->fb_id, error))
|
||||
if (!meta_drm_buffer_ensure_fb_id (META_DRM_BUFFER (buffer_gbm),
|
||||
use_modifiers, &fb_args, error))
|
||||
return FALSE;
|
||||
|
||||
return TRUE;
|
||||
@ -119,15 +146,16 @@ lock_front_buffer (MetaDrmBufferGbm *buffer_gbm,
|
||||
}
|
||||
|
||||
MetaDrmBufferGbm *
|
||||
meta_drm_buffer_gbm_new_lock_front (MetaGpuKms *gpu_kms,
|
||||
meta_drm_buffer_gbm_new_lock_front (MetaKmsDevice *device,
|
||||
struct gbm_surface *gbm_surface,
|
||||
gboolean use_modifiers,
|
||||
GError **error)
|
||||
{
|
||||
MetaDrmBufferGbm *buffer_gbm;
|
||||
|
||||
buffer_gbm = g_object_new (META_TYPE_DRM_BUFFER_GBM, NULL);
|
||||
buffer_gbm->gpu_kms = gpu_kms;
|
||||
buffer_gbm = g_object_new (META_TYPE_DRM_BUFFER_GBM,
|
||||
"device", device,
|
||||
NULL);
|
||||
buffer_gbm->surface = gbm_surface;
|
||||
|
||||
if (!lock_front_buffer (buffer_gbm, use_modifiers, error))
|
||||
@ -140,15 +168,16 @@ meta_drm_buffer_gbm_new_lock_front (MetaGpuKms *gpu_kms,
|
||||
}
|
||||
|
||||
MetaDrmBufferGbm *
|
||||
meta_drm_buffer_gbm_new_take (MetaGpuKms *gpu_kms,
|
||||
meta_drm_buffer_gbm_new_take (MetaKmsDevice *device,
|
||||
struct gbm_bo *bo,
|
||||
gboolean use_modifiers,
|
||||
GError **error)
|
||||
{
|
||||
MetaDrmBufferGbm *buffer_gbm;
|
||||
|
||||
buffer_gbm = g_object_new (META_TYPE_DRM_BUFFER_GBM, NULL);
|
||||
buffer_gbm->gpu_kms = gpu_kms;
|
||||
buffer_gbm = g_object_new (META_TYPE_DRM_BUFFER_GBM,
|
||||
"device", device,
|
||||
NULL);
|
||||
|
||||
if (!init_fb_id (buffer_gbm, bo, use_modifiers, error))
|
||||
{
|
||||
@ -161,12 +190,6 @@ meta_drm_buffer_gbm_new_take (MetaGpuKms *gpu_kms,
|
||||
return buffer_gbm;
|
||||
}
|
||||
|
||||
static uint32_t
|
||||
meta_drm_buffer_gbm_get_fb_id (MetaDrmBuffer *buffer)
|
||||
{
|
||||
return META_DRM_BUFFER_GBM (buffer)->fb_id;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
meta_drm_buffer_gbm_blit_to_framebuffer (CoglScanout *scanout,
|
||||
CoglFramebuffer *framebuffer,
|
||||
@ -308,14 +331,6 @@ meta_drm_buffer_gbm_finalize (GObject *object)
|
||||
{
|
||||
MetaDrmBufferGbm *buffer_gbm = META_DRM_BUFFER_GBM (object);
|
||||
|
||||
if (buffer_gbm->fb_id != INVALID_FB_ID)
|
||||
{
|
||||
int kms_fd;
|
||||
|
||||
kms_fd = meta_gpu_kms_get_fd (buffer_gbm->gpu_kms);
|
||||
drmModeRmFB (kms_fd, buffer_gbm->fb_id);
|
||||
}
|
||||
|
||||
if (buffer_gbm->bo)
|
||||
{
|
||||
if (buffer_gbm->surface)
|
||||
@ -340,5 +355,8 @@ meta_drm_buffer_gbm_class_init (MetaDrmBufferGbmClass *klass)
|
||||
|
||||
object_class->finalize = meta_drm_buffer_gbm_finalize;
|
||||
|
||||
buffer_class->get_fb_id = meta_drm_buffer_gbm_get_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_stride = meta_drm_buffer_gbm_get_stride;
|
||||
buffer_class->get_format = meta_drm_buffer_gbm_get_format;
|
||||
}
|
||||
|
@ -24,7 +24,7 @@
|
||||
|
||||
#include <gbm.h>
|
||||
|
||||
#include "backends/native/meta-drm-buffer.h"
|
||||
#include "backends/native/meta-drm-buffer-private.h"
|
||||
#include "backends/native/meta-gpu-kms.h"
|
||||
|
||||
#define META_TYPE_DRM_BUFFER_GBM (meta_drm_buffer_gbm_get_type ())
|
||||
@ -33,13 +33,13 @@ G_DECLARE_FINAL_TYPE (MetaDrmBufferGbm,
|
||||
META, DRM_BUFFER_GBM,
|
||||
MetaDrmBuffer)
|
||||
|
||||
MetaDrmBufferGbm * meta_drm_buffer_gbm_new_lock_front (MetaGpuKms *gpu_kms,
|
||||
MetaDrmBufferGbm * meta_drm_buffer_gbm_new_lock_front (MetaKmsDevice *device,
|
||||
struct gbm_surface *gbm_surface,
|
||||
gboolean use_modifiers,
|
||||
GError **error);
|
||||
|
||||
|
||||
MetaDrmBufferGbm * meta_drm_buffer_gbm_new_take (MetaGpuKms *gpu_kms,
|
||||
MetaDrmBufferGbm * meta_drm_buffer_gbm_new_take (MetaKmsDevice *device,
|
||||
struct gbm_bo *gbm_bo,
|
||||
gboolean use_modifiers,
|
||||
GError **error);
|
||||
|
@ -34,22 +34,48 @@
|
||||
#include "backends/native/meta-kms-utils.h"
|
||||
#include "backends/native/meta-renderer-native.h"
|
||||
|
||||
#define INVALID_FB_ID 0U
|
||||
|
||||
struct _MetaDrmBufferImport
|
||||
{
|
||||
MetaDrmBuffer parent;
|
||||
|
||||
MetaGpuKms *gpu_kms;
|
||||
|
||||
MetaDrmBufferGbm *importee;
|
||||
|
||||
uint32_t fb_id;
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE (MetaDrmBufferImport, meta_drm_buffer_import,
|
||||
META_TYPE_DRM_BUFFER)
|
||||
|
||||
static int
|
||||
meta_drm_buffer_import_get_width (MetaDrmBuffer *buffer)
|
||||
{
|
||||
MetaDrmBufferImport *buffer_import = META_DRM_BUFFER_IMPORT (buffer);
|
||||
|
||||
return meta_drm_buffer_get_width (META_DRM_BUFFER (buffer_import->importee));
|
||||
}
|
||||
|
||||
static int
|
||||
meta_drm_buffer_import_get_height (MetaDrmBuffer *buffer)
|
||||
{
|
||||
MetaDrmBufferImport *buffer_import = META_DRM_BUFFER_IMPORT (buffer);
|
||||
|
||||
return meta_drm_buffer_get_height (META_DRM_BUFFER (buffer_import->importee));
|
||||
}
|
||||
|
||||
static int
|
||||
meta_drm_buffer_import_get_stride (MetaDrmBuffer *buffer)
|
||||
{
|
||||
MetaDrmBufferImport *buffer_import = META_DRM_BUFFER_IMPORT (buffer);
|
||||
|
||||
return meta_drm_buffer_get_stride (META_DRM_BUFFER (buffer_import->importee));
|
||||
}
|
||||
|
||||
static uint32_t
|
||||
meta_drm_buffer_import_get_format (MetaDrmBuffer *buffer)
|
||||
{
|
||||
MetaDrmBufferImport *buffer_import = META_DRM_BUFFER_IMPORT (buffer);
|
||||
|
||||
return meta_drm_buffer_get_format (META_DRM_BUFFER (buffer_import->importee));
|
||||
}
|
||||
|
||||
static struct gbm_bo *
|
||||
dmabuf_to_gbm_bo (struct gbm_device *importer,
|
||||
int dmabuf_fd,
|
||||
@ -74,19 +100,15 @@ dmabuf_to_gbm_bo (struct gbm_device *importer,
|
||||
|
||||
static gboolean
|
||||
import_gbm_buffer (MetaDrmBufferImport *buffer_import,
|
||||
struct gbm_device *importer,
|
||||
GError **error)
|
||||
{
|
||||
MetaGpuKmsFBArgs fb_args = { 0, };
|
||||
MetaDrmFbArgs fb_args = { 0, };
|
||||
struct gbm_bo *primary_bo;
|
||||
struct gbm_device *importer;
|
||||
struct gbm_bo *imported_bo;
|
||||
int dmabuf_fd;
|
||||
gboolean ret;
|
||||
|
||||
g_assert (buffer_import->fb_id == INVALID_FB_ID);
|
||||
|
||||
importer = meta_gbm_device_from_gpu (buffer_import->gpu_kms);
|
||||
|
||||
primary_bo = meta_drm_buffer_gbm_get_bo (buffer_import->importee);
|
||||
|
||||
dmabuf_fd = gbm_bo_get_fd (primary_bo);
|
||||
@ -122,11 +144,10 @@ import_gbm_buffer (MetaDrmBufferImport *buffer_import,
|
||||
|
||||
fb_args.handles[0] = gbm_bo_get_handle (imported_bo).u32;
|
||||
|
||||
ret = meta_gpu_kms_add_fb (buffer_import->gpu_kms,
|
||||
FALSE /* use_modifiers */,
|
||||
&fb_args,
|
||||
&buffer_import->fb_id,
|
||||
error);
|
||||
ret = meta_drm_buffer_ensure_fb_id (META_DRM_BUFFER (buffer_import),
|
||||
FALSE /* use_modifiers */,
|
||||
&fb_args,
|
||||
error);
|
||||
|
||||
gbm_bo_destroy (imported_bo);
|
||||
|
||||
@ -137,17 +158,19 @@ out_close:
|
||||
}
|
||||
|
||||
MetaDrmBufferImport *
|
||||
meta_drm_buffer_import_new (MetaGpuKms *gpu_kms,
|
||||
MetaDrmBufferGbm *buffer_gbm,
|
||||
GError **error)
|
||||
meta_drm_buffer_import_new (MetaKmsDevice *device,
|
||||
struct gbm_device *gbm_device,
|
||||
MetaDrmBufferGbm *buffer_gbm,
|
||||
GError **error)
|
||||
{
|
||||
MetaDrmBufferImport *buffer_import;
|
||||
|
||||
buffer_import = g_object_new (META_TYPE_DRM_BUFFER_IMPORT, NULL);
|
||||
buffer_import->gpu_kms = gpu_kms;
|
||||
buffer_import = g_object_new (META_TYPE_DRM_BUFFER_IMPORT,
|
||||
"device", device,
|
||||
NULL);
|
||||
g_set_object (&buffer_import->importee, buffer_gbm);
|
||||
|
||||
if (!import_gbm_buffer (buffer_import, error))
|
||||
if (!import_gbm_buffer (buffer_import, gbm_device, error))
|
||||
{
|
||||
g_object_unref (buffer_import);
|
||||
return NULL;
|
||||
@ -156,25 +179,11 @@ meta_drm_buffer_import_new (MetaGpuKms *gpu_kms,
|
||||
return buffer_import;
|
||||
}
|
||||
|
||||
static uint32_t
|
||||
meta_drm_buffer_import_get_fb_id (MetaDrmBuffer *buffer)
|
||||
{
|
||||
return META_DRM_BUFFER_IMPORT (buffer)->fb_id;
|
||||
}
|
||||
|
||||
static void
|
||||
meta_drm_buffer_import_finalize (GObject *object)
|
||||
{
|
||||
MetaDrmBufferImport *buffer_import = META_DRM_BUFFER_IMPORT (object);
|
||||
|
||||
if (buffer_import->fb_id != INVALID_FB_ID)
|
||||
{
|
||||
int kms_fd;
|
||||
|
||||
kms_fd = meta_gpu_kms_get_fd (buffer_import->gpu_kms);
|
||||
drmModeRmFB (kms_fd, buffer_import->fb_id);
|
||||
}
|
||||
|
||||
g_clear_object (&buffer_import->importee);
|
||||
|
||||
G_OBJECT_CLASS (meta_drm_buffer_import_parent_class)->finalize (object);
|
||||
@ -193,5 +202,8 @@ meta_drm_buffer_import_class_init (MetaDrmBufferImportClass *klass)
|
||||
|
||||
object_class->finalize = meta_drm_buffer_import_finalize;
|
||||
|
||||
buffer_class->get_fb_id = meta_drm_buffer_import_get_fb_id;
|
||||
buffer_class->get_width = meta_drm_buffer_import_get_width;
|
||||
buffer_class->get_height = meta_drm_buffer_import_get_height;
|
||||
buffer_class->get_stride = meta_drm_buffer_import_get_stride;
|
||||
buffer_class->get_format = meta_drm_buffer_import_get_format;
|
||||
}
|
||||
|
@ -47,8 +47,9 @@ G_DECLARE_FINAL_TYPE (MetaDrmBufferImport,
|
||||
* The import has a high chance of failing under normal operating
|
||||
* conditions and needs to be handled with fallbacks to something else.
|
||||
*/
|
||||
MetaDrmBufferImport * meta_drm_buffer_import_new (MetaGpuKms *gpu_kms,
|
||||
MetaDrmBufferGbm *buffer_gbm,
|
||||
GError **error);
|
||||
MetaDrmBufferImport * meta_drm_buffer_import_new (MetaKmsDevice *device,
|
||||
struct gbm_device *gbm_device,
|
||||
MetaDrmBufferGbm *buffer_gbm,
|
||||
GError **error);
|
||||
|
||||
#endif /* META_DRM_BUFFER_IMPORT_H */
|
||||
|
60
src/backends/native/meta-drm-buffer-private.h
Normal file
60
src/backends/native/meta-drm-buffer-private.h
Normal file
@ -0,0 +1,60 @@
|
||||
/*
|
||||
* Copyright (C) 2018 Canonical Ltd.
|
||||
* Copyright (C) 2019-2020 Red Hat Inc.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
* 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifndef META_DRM_BUFFER_PRIVATE_H
|
||||
#define META_DRM_BUFFER_PRIVATE_H
|
||||
|
||||
#include "backends/native/meta-drm-buffer.h"
|
||||
#include "backends/native/meta-kms-device.h"
|
||||
|
||||
typedef struct _MetaDrmFbArgs
|
||||
{
|
||||
uint32_t width;
|
||||
uint32_t height;
|
||||
uint32_t format;
|
||||
uint32_t handles[4];
|
||||
uint32_t offsets[4];
|
||||
uint32_t strides[4];
|
||||
uint64_t modifiers[4];
|
||||
} MetaDrmFbArgs;
|
||||
|
||||
struct _MetaDrmBufferClass
|
||||
{
|
||||
GObjectClass parent_class;
|
||||
|
||||
int (* get_width) (MetaDrmBuffer *buffer);
|
||||
int (* get_height) (MetaDrmBuffer *buffer);
|
||||
int (* get_stride) (MetaDrmBuffer *buffer);
|
||||
uint32_t (* get_format) (MetaDrmBuffer *buffer);
|
||||
};
|
||||
|
||||
MetaKmsDevice * meta_drm_buffer_get_device (MetaDrmBuffer *buffer);
|
||||
|
||||
gboolean meta_drm_buffer_ensure_fb_id (MetaDrmBuffer *buffer,
|
||||
gboolean use_modifiers,
|
||||
const MetaDrmFbArgs *fb_args,
|
||||
GError **error);
|
||||
|
||||
gboolean meta_drm_buffer_ensure_fb_in_impl (MetaDrmBuffer *buffer,
|
||||
gboolean use_modifiers,
|
||||
const MetaDrmFbArgs *fb_args,
|
||||
GError **error);
|
||||
|
||||
#endif /* META_DRM_BUFFER_PRIVATE_H */
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Copyright (C) 2011 Intel Corporation.
|
||||
* Copyright (C) 2016 Red Hat
|
||||
* Copyright (C) 2016-2020 Red Hat
|
||||
* Copyright (C) 2018 DisplayLink (UK) Ltd.
|
||||
* Copyright (C) 2018 Canonical Ltd.
|
||||
*
|
||||
@ -24,14 +24,298 @@
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "backends/native/meta-drm-buffer.h"
|
||||
#include "backends/native/meta-drm-buffer-private.h"
|
||||
|
||||
G_DEFINE_ABSTRACT_TYPE (MetaDrmBuffer, meta_drm_buffer, G_TYPE_OBJECT)
|
||||
#include <drm_fourcc.h>
|
||||
|
||||
#include "backends/native/meta-kms-device-private.h"
|
||||
#include "backends/native/meta-kms-impl-device.h"
|
||||
#include "backends/native/meta-kms-utils.h"
|
||||
#include "backends/native/meta-kms-private.h"
|
||||
|
||||
#define INVALID_FB_ID 0U
|
||||
|
||||
enum
|
||||
{
|
||||
PROP_0,
|
||||
|
||||
PROP_DEVICE,
|
||||
|
||||
N_PROPS
|
||||
};
|
||||
|
||||
static GParamSpec *obj_props[N_PROPS];
|
||||
|
||||
typedef struct _MetaDrmBufferPrivate
|
||||
{
|
||||
MetaKmsDevice *device;
|
||||
uint32_t fb_id;
|
||||
} MetaDrmBufferPrivate;
|
||||
|
||||
G_DEFINE_ABSTRACT_TYPE_WITH_PRIVATE (MetaDrmBuffer, meta_drm_buffer,
|
||||
G_TYPE_OBJECT)
|
||||
|
||||
MetaKmsDevice *
|
||||
meta_drm_buffer_get_device (MetaDrmBuffer *buffer)
|
||||
{
|
||||
MetaDrmBufferPrivate *priv = meta_drm_buffer_get_instance_private (buffer);
|
||||
|
||||
return priv->device;
|
||||
}
|
||||
|
||||
gboolean
|
||||
meta_drm_buffer_ensure_fb_in_impl (MetaDrmBuffer *buffer,
|
||||
gboolean use_modifiers,
|
||||
const MetaDrmFbArgs *fb_args,
|
||||
GError **error)
|
||||
{
|
||||
MetaDrmBufferPrivate *priv = meta_drm_buffer_get_instance_private (buffer);
|
||||
MetaKmsDevice *device = priv->device;
|
||||
MetaKmsImplDevice *impl_device = meta_kms_device_get_impl_device (device);
|
||||
int fd;
|
||||
MetaDrmFormatBuf tmp;
|
||||
uint32_t fb_id;
|
||||
|
||||
fd = meta_kms_impl_device_get_fd (impl_device);
|
||||
|
||||
if (use_modifiers && fb_args->modifiers[0] != DRM_FORMAT_MOD_INVALID)
|
||||
{
|
||||
if (drmModeAddFB2WithModifiers (fd,
|
||||
fb_args->width,
|
||||
fb_args->height,
|
||||
fb_args->format,
|
||||
fb_args->handles,
|
||||
fb_args->strides,
|
||||
fb_args->offsets,
|
||||
fb_args->modifiers,
|
||||
&fb_id,
|
||||
DRM_MODE_FB_MODIFIERS))
|
||||
{
|
||||
g_set_error (error,
|
||||
G_IO_ERROR,
|
||||
g_io_error_from_errno (errno),
|
||||
"drmModeAddFB2WithModifiers failed: %s",
|
||||
g_strerror (errno));
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
else if (drmModeAddFB2 (fd,
|
||||
fb_args->width,
|
||||
fb_args->height,
|
||||
fb_args->format,
|
||||
fb_args->handles,
|
||||
fb_args->strides,
|
||||
fb_args->offsets,
|
||||
&fb_id,
|
||||
0))
|
||||
{
|
||||
if (fb_args->format != DRM_FORMAT_XRGB8888)
|
||||
{
|
||||
g_set_error (error,
|
||||
G_IO_ERROR,
|
||||
G_IO_ERROR_FAILED,
|
||||
"drmModeAddFB does not support format '%s' (0x%x)",
|
||||
meta_drm_format_to_string (&tmp, fb_args->format),
|
||||
fb_args->format);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (drmModeAddFB (fd,
|
||||
fb_args->width,
|
||||
fb_args->height,
|
||||
24,
|
||||
32,
|
||||
fb_args->strides[0],
|
||||
fb_args->handles[0],
|
||||
&fb_id))
|
||||
{
|
||||
g_set_error (error,
|
||||
G_IO_ERROR,
|
||||
g_io_error_from_errno (errno),
|
||||
"drmModeAddFB failed: %s",
|
||||
g_strerror (errno));
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
priv->fb_id = fb_id;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
typedef struct
|
||||
{
|
||||
MetaDrmBuffer *buffer;
|
||||
gboolean use_modifiers;
|
||||
MetaDrmFbArgs fb_args;
|
||||
} AddFbData;
|
||||
|
||||
static gpointer
|
||||
add_fb_in_impl (MetaKmsImpl *impl,
|
||||
gpointer user_data,
|
||||
GError **error)
|
||||
{
|
||||
AddFbData *data = user_data;
|
||||
|
||||
if (meta_drm_buffer_ensure_fb_in_impl (data->buffer,
|
||||
data->use_modifiers,
|
||||
&data->fb_args,
|
||||
error))
|
||||
return GINT_TO_POINTER (TRUE);
|
||||
else
|
||||
return GINT_TO_POINTER (FALSE);
|
||||
}
|
||||
|
||||
gboolean
|
||||
meta_drm_buffer_ensure_fb_id (MetaDrmBuffer *buffer,
|
||||
gboolean use_modifiers,
|
||||
const MetaDrmFbArgs *fb_args,
|
||||
GError **error)
|
||||
{
|
||||
MetaDrmBufferPrivate *priv = meta_drm_buffer_get_instance_private (buffer);
|
||||
AddFbData data;
|
||||
|
||||
data = (AddFbData) {
|
||||
.buffer = buffer,
|
||||
.use_modifiers = use_modifiers,
|
||||
.fb_args = *fb_args,
|
||||
};
|
||||
|
||||
if (!meta_kms_run_impl_task_sync (meta_kms_device_get_kms (priv->device),
|
||||
add_fb_in_impl,
|
||||
&data,
|
||||
error))
|
||||
return FALSE;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
typedef struct
|
||||
{
|
||||
MetaKmsDevice *device;
|
||||
uint32_t fb_id;
|
||||
} RmFbData;
|
||||
|
||||
static gpointer
|
||||
rm_fb_in_impl (MetaKmsImpl *impl,
|
||||
gpointer user_data,
|
||||
GError **error)
|
||||
{
|
||||
RmFbData *data = user_data;
|
||||
MetaKmsDevice *device = data->device;
|
||||
MetaKmsImplDevice *impl_device = meta_kms_device_get_impl_device (device);
|
||||
uint32_t fb_id = data->fb_id;
|
||||
int fd;
|
||||
int ret;
|
||||
|
||||
fd = meta_kms_impl_device_get_fd (impl_device);
|
||||
ret = drmModeRmFB (fd, fb_id);
|
||||
if (ret != 0)
|
||||
g_warning ("drmModeRmFB: %s", g_strerror (-ret));
|
||||
|
||||
return GINT_TO_POINTER (TRUE);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_drm_buffer_release_fb_id (MetaDrmBuffer *buffer)
|
||||
{
|
||||
MetaDrmBufferPrivate *priv = meta_drm_buffer_get_instance_private (buffer);
|
||||
RmFbData data;
|
||||
|
||||
data = (RmFbData) {
|
||||
.device = priv->device,
|
||||
.fb_id = priv->fb_id,
|
||||
};
|
||||
|
||||
meta_kms_run_impl_task_sync (meta_kms_device_get_kms (priv->device),
|
||||
rm_fb_in_impl,
|
||||
&data,
|
||||
NULL);
|
||||
priv->fb_id = 0;
|
||||
}
|
||||
|
||||
uint32_t
|
||||
meta_drm_buffer_get_fb_id (MetaDrmBuffer *buffer)
|
||||
{
|
||||
return META_DRM_BUFFER_GET_CLASS (buffer)->get_fb_id (buffer);
|
||||
MetaDrmBufferPrivate *priv = meta_drm_buffer_get_instance_private (buffer);
|
||||
|
||||
return priv->fb_id;
|
||||
}
|
||||
|
||||
int
|
||||
meta_drm_buffer_get_width (MetaDrmBuffer *buffer)
|
||||
{
|
||||
return META_DRM_BUFFER_GET_CLASS (buffer)->get_width (buffer);
|
||||
}
|
||||
|
||||
int
|
||||
meta_drm_buffer_get_height (MetaDrmBuffer *buffer)
|
||||
{
|
||||
return META_DRM_BUFFER_GET_CLASS (buffer)->get_height (buffer);
|
||||
}
|
||||
|
||||
int
|
||||
meta_drm_buffer_get_stride (MetaDrmBuffer *buffer)
|
||||
{
|
||||
return META_DRM_BUFFER_GET_CLASS (buffer)->get_stride (buffer);
|
||||
}
|
||||
|
||||
uint32_t
|
||||
meta_drm_buffer_get_format (MetaDrmBuffer *buffer)
|
||||
{
|
||||
return META_DRM_BUFFER_GET_CLASS (buffer)->get_format (buffer);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_drm_buffer_get_property (GObject *object,
|
||||
guint prop_id,
|
||||
GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
MetaDrmBuffer *buffer = META_DRM_BUFFER (object);
|
||||
MetaDrmBufferPrivate *priv = meta_drm_buffer_get_instance_private (buffer);
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_DEVICE:
|
||||
g_value_set_object (value, priv->device);
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
meta_drm_buffer_set_property (GObject *object,
|
||||
guint prop_id,
|
||||
const GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
MetaDrmBuffer *buffer = META_DRM_BUFFER (object);
|
||||
MetaDrmBufferPrivate *priv = meta_drm_buffer_get_instance_private (buffer);
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_DEVICE:
|
||||
priv->device = g_value_get_object (value);
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
meta_drm_buffer_finalize (GObject *object)
|
||||
{
|
||||
MetaDrmBuffer *buffer = META_DRM_BUFFER (object);
|
||||
MetaDrmBufferPrivate *priv = meta_drm_buffer_get_instance_private (buffer);
|
||||
|
||||
if (priv->fb_id != INVALID_FB_ID)
|
||||
meta_drm_buffer_release_fb_id (buffer);
|
||||
|
||||
G_OBJECT_CLASS (meta_drm_buffer_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -42,4 +326,19 @@ meta_drm_buffer_init (MetaDrmBuffer *buffer)
|
||||
static void
|
||||
meta_drm_buffer_class_init (MetaDrmBufferClass *klass)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
|
||||
object_class->get_property = meta_drm_buffer_get_property;
|
||||
object_class->set_property = meta_drm_buffer_set_property;
|
||||
object_class->finalize = meta_drm_buffer_finalize;
|
||||
|
||||
obj_props[PROP_DEVICE] =
|
||||
g_param_spec_object ("device",
|
||||
"device",
|
||||
"MetaKmsDevice",
|
||||
META_TYPE_KMS_DEVICE,
|
||||
G_PARAM_READWRITE |
|
||||
G_PARAM_CONSTRUCT_ONLY |
|
||||
G_PARAM_STATIC_STRINGS);
|
||||
g_object_class_install_properties (object_class, N_PROPS, obj_props);
|
||||
}
|
||||
|
@ -1,5 +1,6 @@
|
||||
/*
|
||||
* Copyright (C) 2018 Canonical Ltd.
|
||||
* Copyright (C) 2019-2020 Red Hat Inc.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
@ -31,16 +32,14 @@ G_DECLARE_DERIVABLE_TYPE (MetaDrmBuffer,
|
||||
META, DRM_BUFFER,
|
||||
GObject)
|
||||
|
||||
struct _MetaDrmBufferClass
|
||||
{
|
||||
GObjectClass parent_class;
|
||||
|
||||
uint32_t (* get_fb_id) (MetaDrmBuffer *buffer);
|
||||
};
|
||||
|
||||
MetaDrmBuffer *
|
||||
meta_drm_buffer_new_from_dumb (uint32_t dumb_fb_id);
|
||||
|
||||
uint32_t meta_drm_buffer_get_fb_id (MetaDrmBuffer *buffer);
|
||||
|
||||
int meta_drm_buffer_get_width (MetaDrmBuffer *buffer);
|
||||
|
||||
int meta_drm_buffer_get_height (MetaDrmBuffer *buffer);
|
||||
|
||||
int meta_drm_buffer_get_stride (MetaDrmBuffer *buffer);
|
||||
|
||||
uint32_t meta_drm_buffer_get_format (MetaDrmBuffer *buffer);
|
||||
|
||||
#endif /* META_DRM_BUFFER_H */
|
||||
|
@ -64,80 +64,6 @@ struct _MetaGpuKms
|
||||
|
||||
G_DEFINE_TYPE (MetaGpuKms, meta_gpu_kms, META_TYPE_GPU)
|
||||
|
||||
gboolean
|
||||
meta_gpu_kms_add_fb (MetaGpuKms *gpu_kms,
|
||||
gboolean use_modifiers,
|
||||
const MetaGpuKmsFBArgs *args,
|
||||
uint32_t *fb_id_out,
|
||||
GError **error)
|
||||
{
|
||||
MetaDrmFormatBuf tmp;
|
||||
uint32_t fb_id;
|
||||
|
||||
if (use_modifiers && args->modifiers[0] != DRM_FORMAT_MOD_INVALID)
|
||||
{
|
||||
if (drmModeAddFB2WithModifiers (gpu_kms->fd,
|
||||
args->width,
|
||||
args->height,
|
||||
args->format,
|
||||
args->handles,
|
||||
args->strides,
|
||||
args->offsets,
|
||||
args->modifiers,
|
||||
&fb_id,
|
||||
DRM_MODE_FB_MODIFIERS))
|
||||
{
|
||||
g_set_error (error,
|
||||
G_IO_ERROR,
|
||||
g_io_error_from_errno (errno),
|
||||
"drmModeAddFB2WithModifiers failed: %s",
|
||||
g_strerror (errno));
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
else if (drmModeAddFB2 (gpu_kms->fd,
|
||||
args->width,
|
||||
args->height,
|
||||
args->format,
|
||||
args->handles,
|
||||
args->strides,
|
||||
args->offsets,
|
||||
&fb_id,
|
||||
0))
|
||||
{
|
||||
if (args->format != DRM_FORMAT_XRGB8888)
|
||||
{
|
||||
g_set_error (error,
|
||||
G_IO_ERROR,
|
||||
G_IO_ERROR_FAILED,
|
||||
"drmModeAddFB does not support format '%s' (0x%x)",
|
||||
meta_drm_format_to_string (&tmp, args->format),
|
||||
args->format);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (drmModeAddFB (gpu_kms->fd,
|
||||
args->width,
|
||||
args->height,
|
||||
24,
|
||||
32,
|
||||
args->strides[0],
|
||||
args->handles[0],
|
||||
&fb_id))
|
||||
{
|
||||
g_set_error (error,
|
||||
G_IO_ERROR,
|
||||
g_io_error_from_errno (errno),
|
||||
"drmModeAddFB failed: %s",
|
||||
g_strerror (errno));
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
*fb_id_out = fb_id;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
gboolean
|
||||
meta_gpu_kms_is_crtc_active (MetaGpuKms *gpu_kms,
|
||||
MetaCrtc *crtc)
|
||||
|
@ -75,21 +75,4 @@ MetaGpuKmsFlipClosureContainer * meta_gpu_kms_wrap_flip_closure (MetaGpuKms *gpu
|
||||
|
||||
void meta_gpu_kms_flip_closure_container_free (MetaGpuKmsFlipClosureContainer *closure_container);
|
||||
|
||||
typedef struct _MetaGpuKmsFBArgs
|
||||
{
|
||||
uint32_t width;
|
||||
uint32_t height;
|
||||
uint32_t format;
|
||||
uint32_t handles[4];
|
||||
uint32_t offsets[4];
|
||||
uint32_t strides[4];
|
||||
uint64_t modifiers[4];
|
||||
} MetaGpuKmsFBArgs;
|
||||
|
||||
gboolean meta_gpu_kms_add_fb (MetaGpuKms *gpu_kms,
|
||||
gboolean use_modifiers,
|
||||
const MetaGpuKmsFBArgs *args,
|
||||
uint32_t *fb_id_out,
|
||||
GError **error);
|
||||
|
||||
#endif /* META_GPU_KMS_H */
|
||||
|
@ -39,15 +39,12 @@
|
||||
|
||||
#include <drm_fourcc.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <gbm.h>
|
||||
#include <gio/gio.h>
|
||||
#include <glib-object.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sys/mman.h>
|
||||
#include <unistd.h>
|
||||
#include <xf86drm.h>
|
||||
|
||||
#include "backends/meta-backend-private.h"
|
||||
#include "backends/meta-crtc.h"
|
||||
@ -129,19 +126,6 @@ typedef struct _MetaRendererNativeGpuData
|
||||
} secondary;
|
||||
} MetaRendererNativeGpuData;
|
||||
|
||||
typedef struct _MetaDumbBuffer
|
||||
{
|
||||
uint32_t fb_id;
|
||||
uint32_t handle;
|
||||
void *map;
|
||||
uint64_t map_size;
|
||||
int width;
|
||||
int height;
|
||||
int stride_bytes;
|
||||
uint32_t drm_format;
|
||||
int dmabuf_fd;
|
||||
} MetaDumbBuffer;
|
||||
|
||||
typedef enum _MetaSharedFramebufferImportStatus
|
||||
{
|
||||
/* Not tried importing yet. */
|
||||
@ -166,8 +150,8 @@ typedef struct _MetaOnscreenNativeSecondaryGpuState
|
||||
} gbm;
|
||||
|
||||
struct {
|
||||
MetaDumbBuffer *dumb_fb;
|
||||
MetaDumbBuffer dumb_fbs[2];
|
||||
MetaDrmBufferDumb *current_dumb_fb;
|
||||
MetaDrmBufferDumb *dumb_fbs[2];
|
||||
} cpu;
|
||||
|
||||
gboolean noted_primary_gpu_copy_ok;
|
||||
@ -194,7 +178,7 @@ typedef struct _MetaOnscreenNative
|
||||
struct {
|
||||
EGLStreamKHR stream;
|
||||
|
||||
MetaDumbBuffer dumb_fb;
|
||||
MetaDrmBufferDumb *dumb_fb;
|
||||
} egl;
|
||||
#endif
|
||||
|
||||
@ -235,22 +219,6 @@ G_DEFINE_TYPE_WITH_CODE (MetaRendererNative,
|
||||
static const CoglWinsysEGLVtable _cogl_winsys_egl_vtable;
|
||||
static const CoglWinsysVtable *parent_vtable;
|
||||
|
||||
static void
|
||||
release_dumb_fb (MetaDumbBuffer *dumb_fb,
|
||||
MetaGpuKms *gpu_kms);
|
||||
|
||||
static gboolean
|
||||
init_dumb_fb (MetaDumbBuffer *dumb_fb,
|
||||
MetaGpuKms *gpu_kms,
|
||||
int width,
|
||||
int height,
|
||||
uint32_t format,
|
||||
GError **error);
|
||||
|
||||
static int
|
||||
meta_dumb_buffer_ensure_dmabuf_fd (MetaDumbBuffer *dumb_fb,
|
||||
MetaGpuKms *gpu_kms);
|
||||
|
||||
static MetaEgl *
|
||||
meta_renderer_native_get_egl (MetaRendererNative *renderer_native);
|
||||
|
||||
@ -530,11 +498,10 @@ init_secondary_gpu_state_gpu_copy_mode (MetaRendererNative *renderer_nat
|
||||
static void
|
||||
secondary_gpu_release_dumb (MetaOnscreenNativeSecondaryGpuState *secondary_gpu_state)
|
||||
{
|
||||
MetaGpuKms *gpu_kms = secondary_gpu_state->gpu_kms;
|
||||
unsigned i;
|
||||
|
||||
for (i = 0; i < G_N_ELEMENTS (secondary_gpu_state->cpu.dumb_fbs); i++)
|
||||
release_dumb_fb (&secondary_gpu_state->cpu.dumb_fbs[i], gpu_kms);
|
||||
g_clear_object (&secondary_gpu_state->cpu.dumb_fbs[i]);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -635,6 +602,7 @@ init_secondary_gpu_state_cpu_copy_mode (MetaRendererNative *renderer_nat
|
||||
MetaOnscreenNative *onscreen_native = onscreen_egl->platform;
|
||||
MetaOnscreenNativeSecondaryGpuState *secondary_gpu_state;
|
||||
MetaGpuKms *gpu_kms;
|
||||
MetaKmsDevice *kms_device;
|
||||
int width, height;
|
||||
unsigned int i;
|
||||
uint32_t drm_format;
|
||||
@ -652,6 +620,7 @@ init_secondary_gpu_state_cpu_copy_mode (MetaRendererNative *renderer_nat
|
||||
height = cogl_framebuffer_get_height (framebuffer);
|
||||
|
||||
gpu_kms = META_GPU_KMS (meta_crtc_get_gpu (onscreen_native->crtc));
|
||||
kms_device = meta_gpu_kms_get_kms_device (gpu_kms);
|
||||
g_debug ("Secondary GPU %s using DRM format '%s' (0x%x) for a %dx%d output.",
|
||||
meta_gpu_kms_get_file_path (gpu_kms),
|
||||
meta_drm_format_to_string (&tmp, drm_format),
|
||||
@ -665,13 +634,12 @@ init_secondary_gpu_state_cpu_copy_mode (MetaRendererNative *renderer_nat
|
||||
|
||||
for (i = 0; i < G_N_ELEMENTS (secondary_gpu_state->cpu.dumb_fbs); i++)
|
||||
{
|
||||
MetaDumbBuffer *dumb_fb = &secondary_gpu_state->cpu.dumb_fbs[i];
|
||||
|
||||
if (!init_dumb_fb (dumb_fb,
|
||||
gpu_kms,
|
||||
width, height,
|
||||
drm_format,
|
||||
error))
|
||||
secondary_gpu_state->cpu.dumb_fbs[i] =
|
||||
meta_drm_buffer_dumb_new (kms_device,
|
||||
width, height,
|
||||
drm_format,
|
||||
error);
|
||||
if (!secondary_gpu_state->cpu.dumb_fbs[i])
|
||||
{
|
||||
secondary_gpu_state_free (secondary_gpu_state);
|
||||
return FALSE;
|
||||
@ -1367,11 +1335,12 @@ meta_onscreen_native_set_crtc_mode (CoglOnscreen *onscreen,
|
||||
#ifdef HAVE_EGL_DEVICE
|
||||
case META_RENDERER_NATIVE_MODE_EGL_DEVICE:
|
||||
{
|
||||
uint32_t fb_id;
|
||||
MetaDrmBuffer *buffer;
|
||||
|
||||
fb_id = onscreen_native->egl.dumb_fb.fb_id;
|
||||
buffer = META_DRM_BUFFER (onscreen_native->egl.dumb_fb);
|
||||
meta_crtc_kms_assign_primary_plane (crtc_kms,
|
||||
fb_id, kms_update);
|
||||
meta_drm_buffer_get_fb_id (buffer),
|
||||
kms_update);
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
@ -1403,13 +1372,20 @@ import_shared_framebuffer (CoglOnscreen *onscreen,
|
||||
{
|
||||
CoglOnscreenEGL *onscreen_egl = onscreen->winsys;
|
||||
MetaOnscreenNative *onscreen_native = onscreen_egl->platform;
|
||||
MetaGpuKms *gpu_kms;
|
||||
MetaKmsDevice *kms_device;
|
||||
struct gbm_device *gbm_device;
|
||||
MetaDrmBufferGbm *buffer_gbm;
|
||||
MetaDrmBufferImport *buffer_import;
|
||||
g_autoptr (GError) error = NULL;
|
||||
|
||||
buffer_gbm = META_DRM_BUFFER_GBM (onscreen_native->gbm.next_fb);
|
||||
|
||||
buffer_import = meta_drm_buffer_import_new (secondary_gpu_state->gpu_kms,
|
||||
gpu_kms = secondary_gpu_state->gpu_kms;
|
||||
kms_device = meta_gpu_kms_get_kms_device (gpu_kms);
|
||||
gbm_device = meta_gbm_device_from_gpu (gpu_kms);
|
||||
buffer_import = meta_drm_buffer_import_new (kms_device,
|
||||
gbm_device,
|
||||
buffer_gbm,
|
||||
&error);
|
||||
if (!buffer_import)
|
||||
@ -1475,6 +1451,7 @@ copy_shared_framebuffer_gpu (CoglOnscreen *onscreen,
|
||||
MetaRendererNative *renderer_native = renderer_gpu_data->renderer_native;
|
||||
MetaEgl *egl = meta_renderer_native_get_egl (renderer_native);
|
||||
GError *error = NULL;
|
||||
MetaKmsDevice *kms_device;
|
||||
MetaDrmBufferGbm *buffer_gbm;
|
||||
struct gbm_bo *bo;
|
||||
|
||||
@ -1523,8 +1500,9 @@ copy_shared_framebuffer_gpu (CoglOnscreen *onscreen,
|
||||
return;
|
||||
}
|
||||
|
||||
kms_device = meta_gpu_kms_get_kms_device (secondary_gpu_state->gpu_kms);
|
||||
buffer_gbm =
|
||||
meta_drm_buffer_gbm_new_lock_front (secondary_gpu_state->gpu_kms,
|
||||
meta_drm_buffer_gbm_new_lock_front (kms_device,
|
||||
secondary_gpu_state->gbm.surface,
|
||||
renderer_native->use_modifiers,
|
||||
&error);
|
||||
@ -1539,16 +1517,16 @@ copy_shared_framebuffer_gpu (CoglOnscreen *onscreen,
|
||||
secondary_gpu_state->gbm.next_fb = META_DRM_BUFFER (buffer_gbm);
|
||||
}
|
||||
|
||||
static MetaDumbBuffer *
|
||||
static MetaDrmBufferDumb *
|
||||
secondary_gpu_get_next_dumb_buffer (MetaOnscreenNativeSecondaryGpuState *secondary_gpu_state)
|
||||
{
|
||||
MetaDumbBuffer *current_dumb_fb;
|
||||
MetaDrmBufferDumb *current_dumb_fb;
|
||||
|
||||
current_dumb_fb = secondary_gpu_state->cpu.dumb_fb;
|
||||
if (current_dumb_fb == &secondary_gpu_state->cpu.dumb_fbs[0])
|
||||
return &secondary_gpu_state->cpu.dumb_fbs[1];
|
||||
current_dumb_fb = secondary_gpu_state->cpu.current_dumb_fb;
|
||||
if (current_dumb_fb == secondary_gpu_state->cpu.dumb_fbs[0])
|
||||
return secondary_gpu_state->cpu.dumb_fbs[1];
|
||||
else
|
||||
return &secondary_gpu_state->cpu.dumb_fbs[0];
|
||||
return secondary_gpu_state->cpu.dumb_fbs[0];
|
||||
}
|
||||
|
||||
static CoglContext *
|
||||
@ -1648,7 +1626,9 @@ copy_shared_framebuffer_primary_gpu (CoglOnscreen *onscre
|
||||
MetaRendererNative *renderer_native = onscreen_native->renderer_native;
|
||||
MetaRendererNativeGpuData *primary_gpu_data;
|
||||
MetaDrmBufferDumb *buffer_dumb;
|
||||
MetaDumbBuffer *dumb_fb;
|
||||
MetaDrmBuffer *buffer;
|
||||
int width, height, stride;
|
||||
uint32_t drm_format;
|
||||
CoglFramebuffer *dmabuf_fb;
|
||||
int dmabuf_fd;
|
||||
g_autoptr (GError) error = NULL;
|
||||
@ -1664,28 +1644,36 @@ copy_shared_framebuffer_primary_gpu (CoglOnscreen *onscre
|
||||
if (!primary_gpu_data->secondary.has_EGL_EXT_image_dma_buf_import_modifiers)
|
||||
return FALSE;
|
||||
|
||||
dumb_fb = secondary_gpu_get_next_dumb_buffer (secondary_gpu_state);
|
||||
buffer_dumb = secondary_gpu_get_next_dumb_buffer (secondary_gpu_state);
|
||||
buffer = META_DRM_BUFFER (buffer_dumb);
|
||||
|
||||
g_assert (cogl_framebuffer_get_width (framebuffer) == dumb_fb->width);
|
||||
g_assert (cogl_framebuffer_get_height (framebuffer) == dumb_fb->height);
|
||||
width = meta_drm_buffer_get_width (buffer);
|
||||
height = meta_drm_buffer_get_height (buffer);
|
||||
stride = meta_drm_buffer_get_stride (buffer);
|
||||
drm_format = meta_drm_buffer_get_format (buffer);
|
||||
|
||||
ret = meta_cogl_pixel_format_from_drm_format (dumb_fb->drm_format,
|
||||
g_assert (cogl_framebuffer_get_width (framebuffer) == width);
|
||||
g_assert (cogl_framebuffer_get_height (framebuffer) == height);
|
||||
|
||||
ret = meta_cogl_pixel_format_from_drm_format (drm_format,
|
||||
&cogl_format,
|
||||
NULL);
|
||||
g_assert (ret);
|
||||
|
||||
dmabuf_fd = meta_dumb_buffer_ensure_dmabuf_fd (dumb_fb,
|
||||
secondary_gpu_state->gpu_kms);
|
||||
if (dmabuf_fd == -1)
|
||||
return FALSE;
|
||||
dmabuf_fd = meta_drm_buffer_dumb_ensure_dmabuf_fd (buffer_dumb, &error);
|
||||
if (!dmabuf_fd)
|
||||
{
|
||||
g_debug ("Failed to create DMA buffer: %s", error->message);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
dmabuf_fb = create_dma_buf_framebuffer (renderer_native,
|
||||
dmabuf_fd,
|
||||
dumb_fb->width,
|
||||
dumb_fb->height,
|
||||
dumb_fb->stride_bytes,
|
||||
width,
|
||||
height,
|
||||
stride,
|
||||
0, DRM_FORMAT_MOD_LINEAR,
|
||||
dumb_fb->drm_format,
|
||||
drm_format,
|
||||
&error);
|
||||
|
||||
if (error)
|
||||
@ -1697,8 +1685,7 @@ copy_shared_framebuffer_primary_gpu (CoglOnscreen *onscre
|
||||
|
||||
if (!cogl_blit_framebuffer (framebuffer, COGL_FRAMEBUFFER (dmabuf_fb),
|
||||
0, 0, 0, 0,
|
||||
dumb_fb->width,
|
||||
dumb_fb->height,
|
||||
width, height,
|
||||
&error))
|
||||
{
|
||||
g_object_unref (dmabuf_fb);
|
||||
@ -1708,9 +1695,8 @@ copy_shared_framebuffer_primary_gpu (CoglOnscreen *onscre
|
||||
g_object_unref (dmabuf_fb);
|
||||
|
||||
g_clear_object (&secondary_gpu_state->gbm.next_fb);
|
||||
buffer_dumb = meta_drm_buffer_dumb_new (dumb_fb->fb_id);
|
||||
secondary_gpu_state->gbm.next_fb = META_DRM_BUFFER (buffer_dumb);
|
||||
secondary_gpu_state->cpu.dumb_fb = dumb_fb;
|
||||
secondary_gpu_state->gbm.next_fb = buffer;
|
||||
secondary_gpu_state->cpu.current_dumb_fb = buffer_dumb;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
@ -1722,31 +1708,41 @@ copy_shared_framebuffer_cpu (CoglOnscreen *onscreen,
|
||||
{
|
||||
CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen);
|
||||
CoglContext *cogl_context = cogl_framebuffer_get_context (framebuffer);
|
||||
MetaDumbBuffer *dumb_fb;
|
||||
MetaDrmBufferDumb *buffer_dumb;
|
||||
MetaDrmBuffer *buffer;
|
||||
int width, height, stride;
|
||||
uint32_t drm_format;
|
||||
void *buffer_data;
|
||||
CoglBitmap *dumb_bitmap;
|
||||
CoglPixelFormat cogl_format;
|
||||
gboolean ret;
|
||||
MetaDrmBufferDumb *buffer_dumb;
|
||||
|
||||
COGL_TRACE_BEGIN_SCOPED (CopySharedFramebufferCpu,
|
||||
"FB Copy (CPU)");
|
||||
|
||||
dumb_fb = secondary_gpu_get_next_dumb_buffer (secondary_gpu_state);
|
||||
buffer_dumb = secondary_gpu_get_next_dumb_buffer (secondary_gpu_state);
|
||||
buffer = META_DRM_BUFFER (buffer_dumb);
|
||||
|
||||
g_assert (cogl_framebuffer_get_width (framebuffer) == dumb_fb->width);
|
||||
g_assert (cogl_framebuffer_get_height (framebuffer) == dumb_fb->height);
|
||||
width = meta_drm_buffer_get_width (buffer);
|
||||
height = meta_drm_buffer_get_height (buffer);
|
||||
stride = meta_drm_buffer_get_stride (buffer);
|
||||
drm_format = meta_drm_buffer_get_format (buffer);
|
||||
buffer_data = meta_drm_buffer_dumb_get_data (buffer_dumb);
|
||||
|
||||
ret = meta_cogl_pixel_format_from_drm_format (dumb_fb->drm_format,
|
||||
g_assert (cogl_framebuffer_get_width (framebuffer) == width);
|
||||
g_assert (cogl_framebuffer_get_height (framebuffer) == height);
|
||||
|
||||
ret = meta_cogl_pixel_format_from_drm_format (drm_format,
|
||||
&cogl_format,
|
||||
NULL);
|
||||
g_assert (ret);
|
||||
|
||||
dumb_bitmap = cogl_bitmap_new_for_data (cogl_context,
|
||||
dumb_fb->width,
|
||||
dumb_fb->height,
|
||||
width,
|
||||
height,
|
||||
cogl_format,
|
||||
dumb_fb->stride_bytes,
|
||||
dumb_fb->map);
|
||||
stride,
|
||||
buffer_data);
|
||||
|
||||
if (!cogl_framebuffer_read_pixels_into_bitmap (framebuffer,
|
||||
0 /* x */,
|
||||
@ -1758,9 +1754,8 @@ copy_shared_framebuffer_cpu (CoglOnscreen *onscreen,
|
||||
cogl_object_unref (dumb_bitmap);
|
||||
|
||||
g_clear_object (&secondary_gpu_state->gbm.next_fb);
|
||||
buffer_dumb = meta_drm_buffer_dumb_new (dumb_fb->fb_id);
|
||||
secondary_gpu_state->gbm.next_fb = META_DRM_BUFFER (buffer_dumb);
|
||||
secondary_gpu_state->cpu.dumb_fb = dumb_fb;
|
||||
secondary_gpu_state->gbm.next_fb = buffer;
|
||||
secondary_gpu_state->cpu.current_dumb_fb = buffer_dumb;
|
||||
}
|
||||
|
||||
static void
|
||||
@ -1946,6 +1941,7 @@ meta_onscreen_native_swap_buffers_with_damage (CoglOnscreen *onscreen,
|
||||
CoglOnscreenEGL *onscreen_egl = onscreen->winsys;
|
||||
MetaOnscreenNative *onscreen_native = onscreen_egl->platform;
|
||||
MetaGpuKms *render_gpu = onscreen_native->render_gpu;
|
||||
MetaKmsDevice *render_kms_device = meta_gpu_kms_get_kms_device (render_gpu);
|
||||
gboolean egl_context_changed = FALSE;
|
||||
MetaPowerSave power_save_mode;
|
||||
g_autoptr (GError) error = NULL;
|
||||
@ -1971,7 +1967,7 @@ meta_onscreen_native_swap_buffers_with_damage (CoglOnscreen *onscreen,
|
||||
g_clear_object (&onscreen_native->gbm.next_fb);
|
||||
|
||||
buffer_gbm =
|
||||
meta_drm_buffer_gbm_new_lock_front (render_gpu,
|
||||
meta_drm_buffer_gbm_new_lock_front (render_kms_device,
|
||||
onscreen_native->gbm.surface,
|
||||
renderer_native->use_modifiers,
|
||||
&error);
|
||||
@ -2427,154 +2423,6 @@ meta_renderer_native_create_surface_egl_device (CoglOnscreen *onscreen,
|
||||
}
|
||||
#endif /* HAVE_EGL_DEVICE */
|
||||
|
||||
static gboolean
|
||||
init_dumb_fb (MetaDumbBuffer *dumb_fb,
|
||||
MetaGpuKms *gpu_kms,
|
||||
int width,
|
||||
int height,
|
||||
uint32_t format,
|
||||
GError **error)
|
||||
{
|
||||
struct drm_mode_create_dumb create_arg;
|
||||
struct drm_mode_destroy_dumb destroy_arg;
|
||||
struct drm_mode_map_dumb map_arg;
|
||||
uint32_t fb_id = 0;
|
||||
void *map;
|
||||
int kms_fd;
|
||||
MetaGpuKmsFBArgs fb_args = {
|
||||
.width = width,
|
||||
.height = height,
|
||||
.format = format,
|
||||
};
|
||||
|
||||
kms_fd = meta_gpu_kms_get_fd (gpu_kms);
|
||||
|
||||
create_arg = (struct drm_mode_create_dumb) {
|
||||
.bpp = 32, /* RGBX8888 */
|
||||
.width = width,
|
||||
.height = height
|
||||
};
|
||||
if (drmIoctl (kms_fd, DRM_IOCTL_MODE_CREATE_DUMB, &create_arg) != 0)
|
||||
{
|
||||
g_set_error (error, G_IO_ERROR,
|
||||
G_IO_ERROR_FAILED,
|
||||
"Failed to create dumb drm buffer: %s",
|
||||
g_strerror (errno));
|
||||
goto err_ioctl;
|
||||
}
|
||||
|
||||
fb_args.handles[0] = create_arg.handle;
|
||||
fb_args.strides[0] = create_arg.pitch;
|
||||
|
||||
if (!meta_gpu_kms_add_fb (gpu_kms, FALSE, &fb_args, &fb_id, error))
|
||||
goto err_add_fb;
|
||||
|
||||
map_arg = (struct drm_mode_map_dumb) {
|
||||
.handle = create_arg.handle
|
||||
};
|
||||
if (drmIoctl (kms_fd, DRM_IOCTL_MODE_MAP_DUMB,
|
||||
&map_arg) != 0)
|
||||
{
|
||||
g_set_error (error, G_IO_ERROR,
|
||||
G_IO_ERROR_FAILED,
|
||||
"Failed to map dumb drm buffer: %s",
|
||||
g_strerror (errno));
|
||||
goto err_map_dumb;
|
||||
}
|
||||
|
||||
map = mmap (NULL, create_arg.size, PROT_WRITE, MAP_SHARED,
|
||||
kms_fd, map_arg.offset);
|
||||
if (map == MAP_FAILED)
|
||||
{
|
||||
g_set_error (error, G_IO_ERROR,
|
||||
G_IO_ERROR_FAILED,
|
||||
"Failed to mmap dumb drm buffer memory: %s",
|
||||
g_strerror (errno));
|
||||
goto err_mmap;
|
||||
}
|
||||
|
||||
dumb_fb->fb_id = fb_id;
|
||||
dumb_fb->handle = create_arg.handle;
|
||||
dumb_fb->map = map;
|
||||
dumb_fb->map_size = create_arg.size;
|
||||
dumb_fb->width = width;
|
||||
dumb_fb->height = height;
|
||||
dumb_fb->stride_bytes = create_arg.pitch;
|
||||
dumb_fb->drm_format = format;
|
||||
dumb_fb->dmabuf_fd = -1;
|
||||
|
||||
return TRUE;
|
||||
|
||||
err_mmap:
|
||||
err_map_dumb:
|
||||
drmModeRmFB (kms_fd, fb_id);
|
||||
|
||||
err_add_fb:
|
||||
destroy_arg = (struct drm_mode_destroy_dumb) {
|
||||
.handle = create_arg.handle
|
||||
};
|
||||
drmIoctl (kms_fd, DRM_IOCTL_MODE_DESTROY_DUMB, &destroy_arg);
|
||||
|
||||
err_ioctl:
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static int
|
||||
meta_dumb_buffer_ensure_dmabuf_fd (MetaDumbBuffer *dumb_fb,
|
||||
MetaGpuKms *gpu_kms)
|
||||
{
|
||||
int ret;
|
||||
int kms_fd;
|
||||
int dmabuf_fd;
|
||||
|
||||
if (dumb_fb->dmabuf_fd != -1)
|
||||
return dumb_fb->dmabuf_fd;
|
||||
|
||||
kms_fd = meta_gpu_kms_get_fd (gpu_kms);
|
||||
|
||||
ret = drmPrimeHandleToFD (kms_fd, dumb_fb->handle, DRM_CLOEXEC,
|
||||
&dmabuf_fd);
|
||||
if (ret)
|
||||
{
|
||||
g_debug ("Failed to export dumb drm buffer: %s",
|
||||
g_strerror (errno));
|
||||
return -1;
|
||||
}
|
||||
|
||||
dumb_fb->dmabuf_fd = dmabuf_fd;
|
||||
|
||||
return dumb_fb->dmabuf_fd;
|
||||
}
|
||||
|
||||
static void
|
||||
release_dumb_fb (MetaDumbBuffer *dumb_fb,
|
||||
MetaGpuKms *gpu_kms)
|
||||
{
|
||||
struct drm_mode_destroy_dumb destroy_arg;
|
||||
int kms_fd;
|
||||
|
||||
if (!dumb_fb->map)
|
||||
return;
|
||||
|
||||
if (dumb_fb->dmabuf_fd != -1)
|
||||
close (dumb_fb->dmabuf_fd);
|
||||
|
||||
munmap (dumb_fb->map, dumb_fb->map_size);
|
||||
|
||||
kms_fd = meta_gpu_kms_get_fd (gpu_kms);
|
||||
|
||||
drmModeRmFB (kms_fd, dumb_fb->fb_id);
|
||||
|
||||
destroy_arg = (struct drm_mode_destroy_dumb) {
|
||||
.handle = dumb_fb->handle
|
||||
};
|
||||
drmIoctl (kms_fd, DRM_IOCTL_MODE_DESTROY_DUMB, &destroy_arg);
|
||||
|
||||
*dumb_fb = (MetaDumbBuffer) {
|
||||
.dmabuf_fd = -1,
|
||||
};
|
||||
}
|
||||
|
||||
static gboolean
|
||||
meta_renderer_native_init_onscreen (CoglOnscreen *onscreen,
|
||||
GError **error)
|
||||
@ -2620,6 +2468,7 @@ meta_onscreen_native_allocate (CoglOnscreen *onscreen,
|
||||
int width;
|
||||
int height;
|
||||
#ifdef HAVE_EGL_DEVICE
|
||||
MetaKmsDevice *render_kms_device;
|
||||
EGLStreamKHR egl_stream;
|
||||
#endif
|
||||
|
||||
@ -2653,11 +2502,14 @@ meta_onscreen_native_allocate (CoglOnscreen *onscreen,
|
||||
break;
|
||||
#ifdef HAVE_EGL_DEVICE
|
||||
case META_RENDERER_NATIVE_MODE_EGL_DEVICE:
|
||||
if (!init_dumb_fb (&onscreen_native->egl.dumb_fb,
|
||||
onscreen_native->render_gpu,
|
||||
width, height,
|
||||
DRM_FORMAT_XRGB8888,
|
||||
error))
|
||||
render_kms_device =
|
||||
meta_gpu_kms_get_kms_device (onscreen_native->render_gpu);
|
||||
onscreen_native->egl.dumb_fb =
|
||||
meta_drm_buffer_dumb_new (render_kms_device,
|
||||
width, height,
|
||||
DRM_FORMAT_XRGB8888,
|
||||
error);
|
||||
if (!onscreen_native->egl.dumb_fb)
|
||||
return FALSE;
|
||||
|
||||
if (!meta_renderer_native_create_surface_egl_device (onscreen,
|
||||
@ -2750,8 +2602,7 @@ meta_renderer_native_release_onscreen (CoglOnscreen *onscreen)
|
||||
break;
|
||||
#ifdef HAVE_EGL_DEVICE
|
||||
case META_RENDERER_NATIVE_MODE_EGL_DEVICE:
|
||||
release_dumb_fb (&onscreen_native->egl.dumb_fb,
|
||||
onscreen_native->render_gpu);
|
||||
g_clear_object (&onscreen_native->egl.dumb_fb);
|
||||
|
||||
destroy_egl_surface (onscreen);
|
||||
|
||||
|
@ -650,6 +650,7 @@ if have_native_backend
|
||||
'backends/native/meta-drm-buffer-gbm.h',
|
||||
'backends/native/meta-drm-buffer-import.c',
|
||||
'backends/native/meta-drm-buffer-import.h',
|
||||
'backends/native/meta-drm-buffer-private.h',
|
||||
'backends/native/meta-drm-buffer.c',
|
||||
'backends/native/meta-drm-buffer.h',
|
||||
'backends/native/meta-gpu-kms.c',
|
||||
|
@ -687,6 +687,7 @@ try_acquire_egl_image_scanout (MetaWaylandBuffer *buffer,
|
||||
MetaRenderer *renderer = meta_backend_get_renderer (backend);
|
||||
MetaRendererNative *renderer_native = META_RENDERER_NATIVE (renderer);
|
||||
MetaGpuKms *gpu_kms;
|
||||
MetaKmsDevice *kms_device;
|
||||
struct gbm_device *gbm_device;
|
||||
struct gbm_bo *gbm_bo;
|
||||
uint32_t drm_format;
|
||||
@ -696,6 +697,7 @@ try_acquire_egl_image_scanout (MetaWaylandBuffer *buffer,
|
||||
g_autoptr (GError) error = NULL;
|
||||
|
||||
gpu_kms = meta_renderer_native_get_primary_gpu (renderer_native);
|
||||
kms_device = meta_gpu_kms_get_kms_device (gpu_kms);
|
||||
gbm_device = meta_gbm_device_from_gpu (gpu_kms);
|
||||
|
||||
gbm_bo = gbm_bo_import (gbm_device,
|
||||
@ -716,7 +718,7 @@ try_acquire_egl_image_scanout (MetaWaylandBuffer *buffer,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
fb = meta_drm_buffer_gbm_new_take (gpu_kms, gbm_bo,
|
||||
fb = meta_drm_buffer_gbm_new_take (kms_device, gbm_bo,
|
||||
drm_modifier != DRM_FORMAT_MOD_INVALID,
|
||||
&error);
|
||||
if (!fb)
|
||||
|
@ -270,6 +270,7 @@ meta_wayland_dma_buf_try_acquire_scanout (MetaWaylandDmaBufBuffer *dma_buf,
|
||||
MetaRenderer *renderer = meta_backend_get_renderer (backend);
|
||||
MetaRendererNative *renderer_native = META_RENDERER_NATIVE (renderer);
|
||||
MetaGpuKms *gpu_kms;
|
||||
MetaKmsDevice *kms_device;
|
||||
int n_planes;
|
||||
uint32_t drm_format;
|
||||
uint64_t drm_modifier;
|
||||
@ -295,6 +296,7 @@ meta_wayland_dma_buf_try_acquire_scanout (MetaWaylandDmaBufBuffer *dma_buf,
|
||||
return NULL;
|
||||
|
||||
gpu_kms = meta_renderer_native_get_primary_gpu (renderer_native);
|
||||
kms_device = meta_gpu_kms_get_kms_device (gpu_kms);
|
||||
gbm_bo = import_scanout_gbm_bo (dma_buf, gpu_kms, n_planes, &use_modifier);
|
||||
if (!gbm_bo)
|
||||
{
|
||||
@ -302,7 +304,7 @@ meta_wayland_dma_buf_try_acquire_scanout (MetaWaylandDmaBufBuffer *dma_buf,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
fb = meta_drm_buffer_gbm_new_take (gpu_kms, gbm_bo,
|
||||
fb = meta_drm_buffer_gbm_new_take (kms_device, gbm_bo,
|
||||
use_modifier,
|
||||
&error);
|
||||
if (!fb)
|
||||
|
Loading…
Reference in New Issue
Block a user