From fecc57ddf0d56e8893c0f44ea0b8af9dc76576cd Mon Sep 17 00:00:00 2001 From: Daniel van Vugt Date: Tue, 30 Jan 2018 17:47:17 +0800 Subject: [PATCH] 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 --- src/backends/native/meta-kms-buffer.c | 287 +++++++++++++++++++++ src/backends/native/meta-kms-buffer.h | 50 ++++ src/backends/native/meta-renderer-native.c | 235 ++++------------- src/meson.build | 2 + 4 files changed, 390 insertions(+), 184 deletions(-) create mode 100644 src/backends/native/meta-kms-buffer.c create mode 100644 src/backends/native/meta-kms-buffer.h 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 + */ + +#include "backends/native/meta-kms-buffer.h" + +#include "config.h" + +#include +#include +#include +#include + +#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 + */ + +#ifndef META_KMS_BUFFER_H +#define META_KMS_BUFFER_H + +#include +#include + +#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',