summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel van Vugt <daniel.van.vugt@canonical.com>2018-01-30 17:47:17 +0800
committerJonas Ã…dahl <jadahl@gmail.com>2019-05-21 15:49:42 +0200
commitfecc57ddf0d56e8893c0f44ea0b8af9dc76576cd (patch)
treec8984fb09452af9029fd0f9961bb10ad7cd3ddd7
parent0d7a929b831e34fe730b6eedc4357c6c47c37385 (diff)
downloadmutter-fecc57ddf0d56e8893c0f44ea0b8af9dc76576cd.tar.gz
renderer-native: Reference count front buffers
Start reference counting front buffers instead of assuming we know their (scanout) lifetimes. Functionally, this should not change anything. https://gitlab.gnome.org/GNOME/mutter/merge_requests/119
-rw-r--r--src/backends/native/meta-kms-buffer.c287
-rw-r--r--src/backends/native/meta-kms-buffer.h50
-rw-r--r--src/backends/native/meta-renderer-native.c235
-rw-r--r--src/meson.build2
4 files changed, 390 insertions, 184 deletions
diff --git a/src/backends/native/meta-kms-buffer.c b/src/backends/native/meta-kms-buffer.c
new file mode 100644
index 000000000..3527735f6
--- /dev/null
+++ b/src/backends/native/meta-kms-buffer.c
@@ -0,0 +1,287 @@
+/*
+ * Copyright (C) 2011 Intel Corporation.
+ * Copyright (C) 2016 Red Hat
+ * Copyright (C) 2018 DisplayLink (UK) Ltd.
+ * Copyright (C) 2018 Canonical Ltd.
+ *
+ * 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.
+ *
+ * Author: Daniel van Vugt <daniel.van.vugt@canonical.com>
+ */
+
+#include "backends/native/meta-kms-buffer.h"
+
+#include "config.h"
+
+#include <xf86drm.h>
+#include <xf86drmMode.h>
+#include <drm_fourcc.h>
+#include <errno.h>
+
+#define INVALID_FB_ID 0U
+
+typedef enum _MetaKmsBufferType
+{
+ META_KMS_BUFFER_TYPE_GBM,
+ META_KMS_BUFFER_TYPE_WRAPPED_DUMB
+} MetaKmsBufferType;
+
+struct _MetaKmsBuffer
+{
+ GObject parent;
+
+ MetaKmsBufferType type;
+
+ union
+ {
+ uint32_t fb_id;
+
+ struct
+ {
+ uint32_t fb_id;
+ struct gbm_surface *surface;
+ struct gbm_bo *bo;
+ MetaGpuKms *gpu_kms;
+ } gbm;
+
+ struct
+ {
+ uint32_t fb_id;
+ } wrapped_dumb;
+ };
+};
+
+G_DEFINE_TYPE (MetaKmsBuffer, meta_kms_buffer, G_TYPE_OBJECT)
+
+static gboolean
+meta_kms_buffer_acquire_swapped_buffer (MetaKmsBuffer *kms_buffer,
+ gboolean use_modifiers,
+ GError **error)
+{
+ uint32_t handles[4] = {0, 0, 0, 0};
+ uint32_t strides[4] = {0, 0, 0, 0};
+ uint32_t offsets[4] = {0, 0, 0, 0};
+ uint64_t modifiers[4] = {0, 0, 0, 0};
+ uint32_t width, height, format;
+ struct gbm_bo *bo;
+ int i;
+ int drm_fd;
+
+ g_return_val_if_fail (META_IS_KMS_BUFFER (kms_buffer), FALSE);
+ g_return_val_if_fail (kms_buffer->type == META_KMS_BUFFER_TYPE_GBM, FALSE);
+ g_return_val_if_fail (kms_buffer->gbm.bo == NULL, FALSE);
+ g_return_val_if_fail (kms_buffer->gbm.surface != NULL, FALSE);
+ g_return_val_if_fail (kms_buffer->gbm.gpu_kms != NULL, FALSE);
+ g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
+
+ drm_fd = meta_gpu_kms_get_fd (kms_buffer->gbm.gpu_kms);
+ g_return_val_if_fail (drm_fd >= 0, FALSE);
+
+ bo = gbm_surface_lock_front_buffer (kms_buffer->gbm.surface);
+ if (!bo)
+ {
+ g_set_error (error,
+ G_IO_ERROR,
+ G_IO_ERROR_FAILED,
+ "gbm_surface_lock_front_buffer failed");
+ return FALSE;
+ }
+
+ if (gbm_bo_get_handle_for_plane (bo, 0).s32 == -1)
+ {
+ /* Failed to fetch handle to plane, falling back to old method */
+ strides[0] = gbm_bo_get_stride (bo);
+ handles[0] = gbm_bo_get_handle (bo).u32;
+ offsets[0] = 0;
+ modifiers[0] = DRM_FORMAT_MOD_INVALID;
+ }
+ else
+ {
+ for (i = 0; i < gbm_bo_get_plane_count (bo); i++)
+ {
+ strides[i] = gbm_bo_get_stride_for_plane (bo, i);
+ handles[i] = gbm_bo_get_handle_for_plane (bo, i).u32;
+ offsets[i] = gbm_bo_get_offset (bo, i);
+ modifiers[i] = gbm_bo_get_modifier (bo);
+ }
+ }
+
+ width = gbm_bo_get_width (bo);
+ height = gbm_bo_get_height (bo);
+ format = gbm_bo_get_format (bo);
+
+ if (use_modifiers && modifiers[0] != DRM_FORMAT_MOD_INVALID)
+ {
+ if (drmModeAddFB2WithModifiers (drm_fd,
+ width,
+ height,
+ format,
+ handles,
+ strides,
+ offsets,
+ modifiers,
+ &kms_buffer->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));
+ gbm_surface_release_buffer (kms_buffer->gbm.surface, bo);
+ return FALSE;
+ }
+ }
+ else if (drmModeAddFB2 (drm_fd,
+ width,
+ height,
+ format,
+ handles,
+ strides,
+ offsets,
+ &kms_buffer->fb_id,
+ 0))
+ {
+ if (format != DRM_FORMAT_XRGB8888)
+ {
+ g_set_error (error,
+ G_IO_ERROR,
+ G_IO_ERROR_FAILED,
+ "drmModeAddFB does not support format 0x%x",
+ format);
+ gbm_surface_release_buffer (kms_buffer->gbm.surface, bo);
+ return FALSE;
+ }
+
+ if (drmModeAddFB (drm_fd,
+ width,
+ height,
+ 24,
+ 32,
+ strides[0],
+ handles[0],
+ &kms_buffer->fb_id))
+ {
+ g_set_error (error,
+ G_IO_ERROR,
+ g_io_error_from_errno (errno),
+ "drmModeAddFB failed: %s",
+ g_strerror (errno));
+ gbm_surface_release_buffer (kms_buffer->gbm.surface, bo);
+ return FALSE;
+ }
+ }
+
+ kms_buffer->gbm.bo = bo;
+
+ return TRUE;
+}
+
+static void
+meta_kms_buffer_init (MetaKmsBuffer *kms_buffer)
+{
+}
+
+static void
+meta_kms_buffer_finalize (GObject *object)
+{
+ MetaKmsBuffer *kms_buffer = META_KMS_BUFFER (object);
+
+ if (kms_buffer->type == META_KMS_BUFFER_TYPE_GBM)
+ {
+ if (kms_buffer->gbm.gpu_kms != NULL &&
+ kms_buffer->gbm.fb_id != INVALID_FB_ID)
+ {
+ int drm_fd = meta_gpu_kms_get_fd (kms_buffer->gbm.gpu_kms);
+
+ drmModeRmFB (drm_fd, kms_buffer->fb_id);
+ kms_buffer->fb_id = INVALID_FB_ID;
+ }
+
+ if (kms_buffer->gbm.surface &&
+ kms_buffer->gbm.bo)
+ {
+ gbm_surface_release_buffer (kms_buffer->gbm.surface,
+ kms_buffer->gbm.bo);
+ }
+ }
+
+ G_OBJECT_CLASS (meta_kms_buffer_parent_class)->finalize (object);
+}
+
+static void
+meta_kms_buffer_class_init (MetaKmsBufferClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+ object_class->finalize = meta_kms_buffer_finalize;
+}
+
+MetaKmsBuffer *
+meta_kms_buffer_new_from_gbm (MetaGpuKms *gpu_kms,
+ struct gbm_surface *gbm_surface,
+ gboolean use_modifiers,
+ GError **error)
+{
+ MetaKmsBuffer *kms_buffer;
+
+ g_return_val_if_fail (META_IS_GPU_KMS (gpu_kms), NULL);
+ g_return_val_if_fail (error == NULL || *error == NULL, NULL);
+
+ kms_buffer = g_object_new (META_TYPE_KMS_BUFFER, NULL);
+ kms_buffer->type = META_KMS_BUFFER_TYPE_GBM;
+ kms_buffer->gbm.gpu_kms = gpu_kms;
+ kms_buffer->gbm.surface = gbm_surface;
+
+ if (!meta_kms_buffer_acquire_swapped_buffer (kms_buffer,
+ use_modifiers,
+ error))
+ {
+ g_object_unref (kms_buffer);
+ return NULL;
+ }
+
+ return kms_buffer;
+}
+
+MetaKmsBuffer *
+meta_kms_buffer_new_from_dumb (uint32_t dumb_fb_id)
+{
+ MetaKmsBuffer *kms_buffer;
+
+ kms_buffer = g_object_new (META_TYPE_KMS_BUFFER, NULL);
+ kms_buffer->type = META_KMS_BUFFER_TYPE_WRAPPED_DUMB;
+ kms_buffer->wrapped_dumb.fb_id = dumb_fb_id;
+
+ return kms_buffer;
+}
+
+uint32_t
+meta_kms_buffer_get_fb_id (const MetaKmsBuffer *kms_buffer)
+{
+ g_return_val_if_fail (kms_buffer != NULL, INVALID_FB_ID);
+
+ return kms_buffer->fb_id;
+}
+
+struct gbm_bo *
+meta_kms_buffer_get_bo (const MetaKmsBuffer *kms_buffer)
+{
+ g_return_val_if_fail (kms_buffer != NULL, NULL);
+ g_return_val_if_fail (kms_buffer->type == META_KMS_BUFFER_TYPE_GBM, NULL);
+
+ return kms_buffer->gbm.bo;
+}
diff --git a/src/backends/native/meta-kms-buffer.h b/src/backends/native/meta-kms-buffer.h
new file mode 100644
index 000000000..74d02d543
--- /dev/null
+++ b/src/backends/native/meta-kms-buffer.h
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2018 Canonical Ltd.
+ *
+ * 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.
+ *
+ * Author: Daniel van Vugt <daniel.van.vugt@canonical.com>
+ */
+
+#ifndef META_KMS_BUFFER_H
+#define META_KMS_BUFFER_H
+
+#include <gbm.h>
+#include <glib-object.h>
+
+#include "backends/native/meta-gpu-kms.h"
+
+#define META_TYPE_KMS_BUFFER (meta_kms_buffer_get_type ())
+G_DECLARE_FINAL_TYPE (MetaKmsBuffer,
+ meta_kms_buffer,
+ META,
+ KMS_BUFFER,
+ GObject)
+
+MetaKmsBuffer *
+meta_kms_buffer_new_from_gbm (MetaGpuKms *gpu_kms,
+ struct gbm_surface *gbm_surface,
+ gboolean use_modifiers,
+ GError **error);
+
+MetaKmsBuffer *
+meta_kms_buffer_new_from_dumb (uint32_t dumb_fb_id);
+
+uint32_t meta_kms_buffer_get_fb_id (const MetaKmsBuffer *kms_buffer);
+
+struct gbm_bo *meta_kms_buffer_get_bo (const MetaKmsBuffer *kms_buffer);
+
+#endif /* META_KMS_BUFFER_H */
diff --git a/src/backends/native/meta-renderer-native.c b/src/backends/native/meta-renderer-native.c
index dbfc97aae..94b7f290b 100644
--- a/src/backends/native/meta-renderer-native.c
+++ b/src/backends/native/meta-renderer-native.c
@@ -59,6 +59,7 @@
#include "backends/meta-renderer-view.h"
#include "backends/native/meta-crtc-kms.h"
#include "backends/native/meta-gpu-kms.h"
+#include "backends/native/meta-kms-buffer.h"
#include "backends/native/meta-monitor-manager-kms.h"
#include "backends/native/meta-renderer-native-gles3.h"
#include "backends/native/meta-renderer-native.h"
@@ -144,10 +145,8 @@ typedef struct _MetaOnscreenNativeSecondaryGpuState
struct {
struct gbm_surface *surface;
- uint32_t current_fb_id;
- uint32_t next_fb_id;
- struct gbm_bo *current_bo;
- struct gbm_bo *next_bo;
+ MetaKmsBuffer *current_fb;
+ MetaKmsBuffer *next_fb;
} gbm;
struct {
@@ -168,10 +167,8 @@ typedef struct _MetaOnscreenNative
struct {
struct gbm_surface *surface;
- uint32_t current_fb_id;
- uint32_t next_fb_id;
- struct gbm_bo *current_bo;
- struct gbm_bo *next_bo;
+ MetaKmsBuffer *current_fb;
+ MetaKmsBuffer *next_fb;
} gbm;
#ifdef HAVE_EGL_DEVICE
@@ -971,25 +968,12 @@ free_current_secondary_bo (MetaGpuKms *gpu_kms,
MetaOnscreenNativeSecondaryGpuState *secondary_gpu_state)
{
MetaRendererNativeGpuData *renderer_gpu_data;
- int kms_fd;
-
- kms_fd = meta_gpu_kms_get_fd (gpu_kms);
renderer_gpu_data = secondary_gpu_state->renderer_gpu_data;
switch (renderer_gpu_data->secondary.copy_mode)
{
case META_SHARED_FRAMEBUFFER_COPY_MODE_GPU:
- if (secondary_gpu_state->gbm.current_fb_id)
- {
- drmModeRmFB (kms_fd, secondary_gpu_state->gbm.current_fb_id);
- secondary_gpu_state->gbm.current_fb_id = 0;
- }
- if (secondary_gpu_state->gbm.current_bo)
- {
- gbm_surface_release_buffer (secondary_gpu_state->gbm.surface,
- secondary_gpu_state->gbm.current_bo);
- secondary_gpu_state->gbm.current_bo = NULL;
- }
+ g_clear_object (&secondary_gpu_state->gbm.current_fb);
break;
case META_SHARED_FRAMEBUFFER_COPY_MODE_CPU:
break;
@@ -1001,22 +985,8 @@ free_current_bo (CoglOnscreen *onscreen)
{
CoglOnscreenEGL *onscreen_egl = onscreen->winsys;
MetaOnscreenNative *onscreen_native = onscreen_egl->platform;
- MetaGpuKms *render_gpu = onscreen_native->render_gpu;
- int kms_fd;
-
- kms_fd = meta_gpu_kms_get_fd (render_gpu);
- if (onscreen_native->gbm.current_fb_id)
- {
- drmModeRmFB (kms_fd, onscreen_native->gbm.current_fb_id);
- onscreen_native->gbm.current_fb_id = 0;
- }
- if (onscreen_native->gbm.current_bo)
- {
- gbm_surface_release_buffer (onscreen_native->gbm.surface,
- onscreen_native->gbm.current_bo);
- onscreen_native->gbm.current_bo = NULL;
- }
+ g_clear_object (&onscreen_native->gbm.current_fb);
g_hash_table_foreach (onscreen_native->secondary_gpu_states,
(GHFunc) free_current_secondary_bo,
@@ -1310,11 +1280,9 @@ static void
swap_secondary_drm_fb (MetaGpuKms *gpu_kms,
MetaOnscreenNativeSecondaryGpuState *secondary_gpu_state)
{
- secondary_gpu_state->gbm.current_fb_id = secondary_gpu_state->gbm.next_fb_id;
- secondary_gpu_state->gbm.next_fb_id = 0;
-
- secondary_gpu_state->gbm.current_bo = secondary_gpu_state->gbm.next_bo;
- secondary_gpu_state->gbm.next_bo = NULL;
+ g_set_object (&secondary_gpu_state->gbm.current_fb,
+ secondary_gpu_state->gbm.next_fb);
+ g_clear_object (&secondary_gpu_state->gbm.next_fb);
}
static void
@@ -1325,11 +1293,8 @@ meta_onscreen_native_swap_drm_fb (CoglOnscreen *onscreen)
free_current_bo (onscreen);
- onscreen_native->gbm.current_fb_id = onscreen_native->gbm.next_fb_id;
- onscreen_native->gbm.next_fb_id = 0;
-
- onscreen_native->gbm.current_bo = onscreen_native->gbm.next_bo;
- onscreen_native->gbm.next_bo = NULL;
+ g_set_object (&onscreen_native->gbm.current_fb, onscreen_native->gbm.next_fb);
+ g_clear_object (&onscreen_native->gbm.next_fb);
g_hash_table_foreach (onscreen_native->secondary_gpu_states,
(GHFunc) swap_secondary_drm_fb,
@@ -1413,17 +1378,7 @@ free_next_secondary_bo (MetaGpuKms *gpu_kms,
switch (renderer_gpu_data->secondary.copy_mode)
{
case META_SHARED_FRAMEBUFFER_COPY_MODE_GPU:
- if (secondary_gpu_state->gbm.next_fb_id)
- {
- int kms_fd;
-
- kms_fd = meta_gpu_kms_get_fd (gpu_kms);
- drmModeRmFB (kms_fd, secondary_gpu_state->gbm.next_fb_id);
- gbm_surface_release_buffer (secondary_gpu_state->gbm.surface,
- secondary_gpu_state->gbm.next_bo);
- secondary_gpu_state->gbm.next_fb_id = 0;
- secondary_gpu_state->gbm.next_bo = NULL;
- }
+ g_clear_object (&secondary_gpu_state->gbm.next_fb);
break;
case META_SHARED_FRAMEBUFFER_COPY_MODE_CPU:
break;
@@ -1448,17 +1403,7 @@ flip_closure_destroyed (MetaRendererView *view)
switch (renderer_gpu_data->mode)
{
case META_RENDERER_NATIVE_MODE_GBM:
- if (onscreen_native->gbm.next_fb_id)
- {
- int kms_fd;
-
- kms_fd = meta_gpu_kms_get_fd (render_gpu);
- drmModeRmFB (kms_fd, onscreen_native->gbm.next_fb_id);
- gbm_surface_release_buffer (onscreen_native->gbm.surface,
- onscreen_native->gbm.next_bo);
- onscreen_native->gbm.next_bo = NULL;
- onscreen_native->gbm.next_fb_id = 0;
- }
+ g_clear_object (&onscreen_native->gbm.next_fb);
g_hash_table_foreach (onscreen_native->secondary_gpu_states,
(GHFunc) free_next_secondary_bo,
@@ -1808,12 +1753,12 @@ meta_onscreen_native_flip_crtc (CoglOnscreen *onscreen,
case META_RENDERER_NATIVE_MODE_GBM:
if (gpu_kms == render_gpu)
{
- fb_id = onscreen_native->gbm.next_fb_id;
+ fb_id = meta_kms_buffer_get_fb_id (onscreen_native->gbm.next_fb);
}
else
{
secondary_gpu_state = get_secondary_gpu_state (onscreen, gpu_kms);
- fb_id = secondary_gpu_state->gbm.next_fb_id;
+ fb_id = meta_kms_buffer_get_fb_id (secondary_gpu_state->gbm.next_fb);
}
if (!meta_gpu_kms_flip_crtc (gpu_kms,
@@ -1879,7 +1824,7 @@ set_crtc_fb (CoglOnscreen *onscreen,
if (!secondary_gpu_state)
return;
- fb_id = secondary_gpu_state->gbm.next_fb_id;
+ fb_id = meta_kms_buffer_get_fb_id (secondary_gpu_state->gbm.next_fb);
}
x = crtc->rect.x - logical_monitor->rect.x;
@@ -1922,7 +1867,7 @@ meta_onscreen_native_set_crtc_modes (CoglOnscreen *onscreen)
switch (renderer_gpu_data->mode)
{
case META_RENDERER_NATIVE_MODE_GBM:
- fb_id = onscreen_native->gbm.next_fb_id;
+ fb_id = meta_kms_buffer_get_fb_id (onscreen_native->gbm.next_fb);
break;
#ifdef HAVE_EGL_DEVICE
case META_RENDERER_NATIVE_MODE_EGL_DEVICE:
@@ -1990,7 +1935,7 @@ crtc_mode_set_fallback (CoglOnscreen *onscreen,
return FALSE;
}
- fb_id = onscreen_native->gbm.next_fb_id;
+ fb_id = meta_kms_buffer_get_fb_id (onscreen_native->gbm.next_fb);
set_crtc_fb (onscreen, logical_monitor, crtc, fb_id);
return TRUE;
}
@@ -2090,101 +2035,6 @@ meta_onscreen_native_flip_crtcs (CoglOnscreen *onscreen)
g_closure_unref (flip_closure);
}
-static gboolean
-gbm_get_next_fb_id (MetaGpuKms *gpu_kms,
- struct gbm_surface *gbm_surface,
- struct gbm_bo **out_next_bo,
- uint32_t *out_next_fb_id)
-{
- MetaRendererNative *renderer_native = meta_renderer_native_from_gpu (gpu_kms);
- struct gbm_bo *next_bo;
- uint32_t next_fb_id;
- int kms_fd;
- uint32_t handles[4] = { 0, };
- uint32_t strides[4] = { 0, };
- uint32_t offsets[4] = { 0, };
- uint64_t modifiers[4] = { 0, };
- int i;
-
- /* Now we need to set the CRTC to whatever is the front buffer */
- next_bo = gbm_surface_lock_front_buffer (gbm_surface);
-
- if (!next_bo)
- {
- g_error ("Impossible to lock surface front buffer: %m");
- return FALSE;
- }
-
- if (gbm_bo_get_handle_for_plane (next_bo, 0).s32 == -1)
- {
- /* Failed to fetch handle to plane, falling back to old method */
- strides[0] = gbm_bo_get_stride (next_bo);
- handles[0] = gbm_bo_get_handle (next_bo).u32;
- offsets[0] = 0;
- modifiers[0] = DRM_FORMAT_MOD_INVALID;
- }
- else
- {
- for (i = 0; i < gbm_bo_get_plane_count (next_bo); i++)
- {
- strides[i] = gbm_bo_get_stride_for_plane (next_bo, i);
- handles[i] = gbm_bo_get_handle_for_plane (next_bo, i).u32;
- offsets[i] = gbm_bo_get_offset (next_bo, i);
- modifiers[i] = gbm_bo_get_modifier (next_bo);
- }
- }
-
- kms_fd = meta_gpu_kms_get_fd (gpu_kms);
-
- if (renderer_native->use_modifiers &&
- modifiers[0] != DRM_FORMAT_MOD_INVALID)
- {
- if (drmModeAddFB2WithModifiers (kms_fd,
- gbm_bo_get_width (next_bo),
- gbm_bo_get_height (next_bo),
- gbm_bo_get_format (next_bo),
- handles,
- strides,
- offsets,
- modifiers,
- &next_fb_id,
- DRM_MODE_FB_MODIFIERS))
- {
- g_warning ("Failed to create new back buffer handle: %m");
- gbm_surface_release_buffer (gbm_surface, next_bo);
- return FALSE;
- }
- }
- else if (drmModeAddFB2 (kms_fd,
- gbm_bo_get_width (next_bo),
- gbm_bo_get_height (next_bo),
- gbm_bo_get_format (next_bo),
- handles,
- strides,
- offsets,
- &next_fb_id,
- 0))
- {
- if (drmModeAddFB (kms_fd,
- gbm_bo_get_width (next_bo),
- gbm_bo_get_height (next_bo),
- 24, /* depth */
- 32, /* bpp */
- strides[0],
- handles[0],
- &next_fb_id))
- {
- g_warning ("Failed to create new back buffer handle: %m");
- gbm_surface_release_buffer (gbm_surface, next_bo);
- return FALSE;
- }
- }
-
- *out_next_bo = next_bo;
- *out_next_fb_id = next_fb_id;
- return TRUE;
-}
-
static void
wait_for_pending_flips (CoglOnscreen *onscreen)
{
@@ -2237,7 +2087,7 @@ copy_shared_framebuffer_gpu (CoglOnscreen *onscreen,
renderer_gpu_data->egl_display,
renderer_gpu_data->secondary.egl_context,
secondary_gpu_state->egl_surface,
- onscreen_native->gbm.next_bo,
+ meta_kms_buffer_get_bo (onscreen_native->gbm.next_fb),
&error))
{
g_warning ("Failed to blit shared framebuffer: %s", error->message);
@@ -2255,10 +2105,19 @@ copy_shared_framebuffer_gpu (CoglOnscreen *onscreen,
return;
}
- gbm_get_next_fb_id (secondary_gpu_state->gpu_kms,
- secondary_gpu_state->gbm.surface,
- &secondary_gpu_state->gbm.next_bo,
- &secondary_gpu_state->gbm.next_fb_id);
+ g_clear_object (&secondary_gpu_state->gbm.next_fb);
+ secondary_gpu_state->gbm.next_fb =
+ meta_kms_buffer_new_from_gbm (secondary_gpu_state->gpu_kms,
+ secondary_gpu_state->gbm.surface,
+ renderer_native->use_modifiers,
+ &error);
+ if (!secondary_gpu_state->gbm.next_fb)
+ {
+ g_warning ("meta_kms_buffer_new_from_gbm failed: %s",
+ error->message);
+ g_error_free (error);
+ return;
+ }
}
typedef struct _PixelFormatMap {
@@ -2377,7 +2236,9 @@ copy_shared_framebuffer_cpu (CoglOnscreen *onscreen,
cogl_object_unref (dumb_bitmap);
- secondary_gpu_state->gbm.next_fb_id = target_fb_id;
+ g_clear_object (&secondary_gpu_state->gbm.next_fb);
+ secondary_gpu_state->gbm.next_fb =
+ meta_kms_buffer_new_from_dumb (target_fb_id);
}
static void
@@ -2464,6 +2325,7 @@ meta_onscreen_native_swap_buffers_with_damage (CoglOnscreen *onscreen,
CoglFrameInfo *frame_info;
gboolean egl_context_changed = FALSE;
MetaPowerSave power_save_mode;
+ g_autoptr (GError) error = NULL;
/*
* Wait for the flip callback before continuing, as we might have started the
@@ -2485,14 +2347,19 @@ meta_onscreen_native_swap_buffers_with_damage (CoglOnscreen *onscreen,
switch (renderer_gpu_data->mode)
{
case META_RENDERER_NATIVE_MODE_GBM:
- g_warn_if_fail (onscreen_native->gbm.next_bo == NULL &&
- onscreen_native->gbm.next_fb_id == 0);
-
- if (!gbm_get_next_fb_id (render_gpu,
- onscreen_native->gbm.surface,
- &onscreen_native->gbm.next_bo,
- &onscreen_native->gbm.next_fb_id))
- return;
+ g_warn_if_fail (onscreen_native->gbm.next_fb == NULL);
+ g_clear_object (&onscreen_native->gbm.next_fb);
+ onscreen_native->gbm.next_fb =
+ meta_kms_buffer_new_from_gbm (render_gpu,
+ onscreen_native->gbm.surface,
+ renderer_native->use_modifiers,
+ &error);
+ if (!onscreen_native->gbm.next_fb)
+ {
+ g_warning ("meta_kms_buffer_new_from_gbm failed: %s",
+ error->message);
+ return;
+ }
break;
#ifdef HAVE_EGL_DEVICE
@@ -3083,7 +2950,7 @@ meta_renderer_native_release_onscreen (CoglOnscreen *onscreen)
case META_RENDERER_NATIVE_MODE_GBM:
/* flip state takes a reference on the onscreen so there should
* never be outstanding flips when we reach here. */
- g_return_if_fail (onscreen_native->gbm.next_fb_id == 0);
+ g_return_if_fail (onscreen_native->gbm.next_fb == NULL);
free_current_bo (onscreen);
diff --git a/src/meson.build b/src/meson.build
index cc0fa25ce..74fe879d8 100644
--- a/src/meson.build
+++ b/src/meson.build
@@ -578,6 +578,8 @@ if have_native_backend
'backends/native/meta-gpu-kms.h',
'backends/native/meta-input-settings-native.c',
'backends/native/meta-input-settings-native.h',
+ 'backends/native/meta-kms-buffer.c',
+ 'backends/native/meta-kms-buffer.h',
'backends/native/meta-launcher.c',
'backends/native/meta-launcher.h',
'backends/native/meta-monitor-manager-kms.c',