mirror of
https://github.com/brl/mutter.git
synced 2024-11-21 23:50:41 -05:00
cogl/onscreen: Add API to scanout a buffer directly
Instead of always swapping buffers and flipping the back buffer, make it possible to scan out a provided buffer directly without swapping any EGL buffers. A buffer is passed as an object implementing the empty CoglScanout interface. It is only possible to do this in the native backend; and the interface is implemented by MetaDrmBufferGbm. When directly scanned out, instead of calling gbm_surface_lock_front_buffer() to get the gbm_bo and fbid, get it directly from the MetaDrmBufferGbm, and use that to create the page flip KMS update. https://gitlab.gnome.org/GNOME/mutter/merge_requests/798
This commit is contained in:
parent
f8ee974628
commit
3da8c1bfdc
@ -405,6 +405,27 @@ cogl_onscreen_get_buffer_age (CoglOnscreen *onscreen)
|
|||||||
return winsys->onscreen_get_buffer_age (onscreen);
|
return winsys->onscreen_get_buffer_age (onscreen);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
cogl_onscreen_direct_scanout (CoglOnscreen *onscreen,
|
||||||
|
CoglScanout *scanout)
|
||||||
|
{
|
||||||
|
CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen);
|
||||||
|
const CoglWinsysVtable *winsys;
|
||||||
|
CoglFrameInfo *info;
|
||||||
|
|
||||||
|
g_return_if_fail (framebuffer->type == COGL_FRAMEBUFFER_TYPE_ONSCREEN);
|
||||||
|
g_return_if_fail (_cogl_winsys_has_feature (COGL_WINSYS_FEATURE_SYNC_AND_COMPLETE_EVENT));
|
||||||
|
|
||||||
|
info = _cogl_frame_info_new ();
|
||||||
|
info->frame_counter = onscreen->frame_counter;
|
||||||
|
g_queue_push_tail (&onscreen->pending_frame_infos, info);
|
||||||
|
|
||||||
|
winsys = _cogl_framebuffer_get_winsys (framebuffer);
|
||||||
|
winsys->onscreen_direct_scanout (onscreen, scanout);
|
||||||
|
|
||||||
|
onscreen->frame_counter++;
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef COGL_HAS_X11_SUPPORT
|
#ifdef COGL_HAS_X11_SUPPORT
|
||||||
uint32_t
|
uint32_t
|
||||||
cogl_x11_onscreen_get_window_xid (CoglOnscreen *onscreen)
|
cogl_x11_onscreen_get_window_xid (CoglOnscreen *onscreen)
|
||||||
|
@ -50,6 +50,8 @@ G_BEGIN_DECLS
|
|||||||
typedef struct _CoglOnscreen CoglOnscreen;
|
typedef struct _CoglOnscreen CoglOnscreen;
|
||||||
#define COGL_ONSCREEN(X) ((CoglOnscreen *)(X))
|
#define COGL_ONSCREEN(X) ((CoglOnscreen *)(X))
|
||||||
|
|
||||||
|
typedef struct _CoglScanout CoglScanout;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* cogl_onscreen_get_gtype:
|
* cogl_onscreen_get_gtype:
|
||||||
*
|
*
|
||||||
@ -284,6 +286,13 @@ cogl_onscreen_swap_buffers_with_damage (CoglOnscreen *onscreen,
|
|||||||
const int *rectangles,
|
const int *rectangles,
|
||||||
int n_rectangles);
|
int n_rectangles);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* cogl_onscreen_direct_scanout: (skip)
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
cogl_onscreen_direct_scanout (CoglOnscreen *onscreen,
|
||||||
|
CoglScanout *scanout);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* cogl_onscreen_swap_region:
|
* cogl_onscreen_swap_region:
|
||||||
* @onscreen: A #CoglOnscreen framebuffer
|
* @onscreen: A #CoglOnscreen framebuffer
|
||||||
|
27
cogl/cogl/cogl-scanout.c
Normal file
27
cogl/cogl/cogl-scanout.c
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2019 Red Hat Inc.
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
* License as published by the Free Software Foundation; either
|
||||||
|
* version 2 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library 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
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "cogl-config.h"
|
||||||
|
|
||||||
|
#include "cogl-scanout.h"
|
||||||
|
|
||||||
|
G_DEFINE_INTERFACE (CoglScanout, cogl_scanout, G_TYPE_OBJECT)
|
||||||
|
|
||||||
|
static void
|
||||||
|
cogl_scanout_default_init (CoglScanoutInterface *iface)
|
||||||
|
{
|
||||||
|
}
|
35
cogl/cogl/cogl-scanout.h
Normal file
35
cogl/cogl/cogl-scanout.h
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2019 Red Hat Inc.
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
* License as published by the Free Software Foundation; either
|
||||||
|
* version 2 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library 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
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef COGL_SCANOUT_H
|
||||||
|
#define COGL_SCANOUT_H
|
||||||
|
|
||||||
|
#include "cogl/cogl-types.h"
|
||||||
|
|
||||||
|
#include <glib-object.h>
|
||||||
|
|
||||||
|
#define COGL_TYPE_SCANOUT (cogl_scanout_get_type ())
|
||||||
|
COGL_EXPORT
|
||||||
|
G_DECLARE_INTERFACE (CoglScanout, cogl_scanout,
|
||||||
|
COGL, SCANOUT, GObject)
|
||||||
|
|
||||||
|
struct _CoglScanoutInterface
|
||||||
|
{
|
||||||
|
GTypeInterface parent_iface;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /* COGL_SCANOUT_H */
|
@ -122,6 +122,7 @@
|
|||||||
#include <cogl/cogl-fence.h>
|
#include <cogl/cogl-fence.h>
|
||||||
#include <cogl/cogl-glib-source.h>
|
#include <cogl/cogl-glib-source.h>
|
||||||
#include <cogl/cogl-trace.h>
|
#include <cogl/cogl-trace.h>
|
||||||
|
#include <cogl/cogl-scanout.h>
|
||||||
/* XXX: This will definitly go away once all the Clutter winsys
|
/* XXX: This will definitly go away once all the Clutter winsys
|
||||||
* code has been migrated down into Cogl! */
|
* code has been migrated down into Cogl! */
|
||||||
#include <cogl/deprecated/cogl-clutter.h>
|
#include <cogl/deprecated/cogl-clutter.h>
|
||||||
|
@ -122,6 +122,7 @@ cogl_nonintrospected_headers = [
|
|||||||
'cogl-version.h',
|
'cogl-version.h',
|
||||||
'cogl-gtype-private.h',
|
'cogl-gtype-private.h',
|
||||||
'cogl-glib-source.h',
|
'cogl-glib-source.h',
|
||||||
|
'cogl-scanout.h',
|
||||||
]
|
]
|
||||||
|
|
||||||
cogl_nodist_headers = [
|
cogl_nodist_headers = [
|
||||||
@ -347,6 +348,7 @@ cogl_sources = [
|
|||||||
'cogl-closure-list.c',
|
'cogl-closure-list.c',
|
||||||
'cogl-fence.c',
|
'cogl-fence.c',
|
||||||
'cogl-fence-private.h',
|
'cogl-fence-private.h',
|
||||||
|
'cogl-scanout.c',
|
||||||
'deprecated/cogl-material-compat.c',
|
'deprecated/cogl-material-compat.c',
|
||||||
'deprecated/cogl-program.c',
|
'deprecated/cogl-program.c',
|
||||||
'deprecated/cogl-program-private.h',
|
'deprecated/cogl-program-private.h',
|
||||||
|
@ -33,6 +33,7 @@
|
|||||||
|
|
||||||
#include "cogl-renderer.h"
|
#include "cogl-renderer.h"
|
||||||
#include "cogl-onscreen.h"
|
#include "cogl-onscreen.h"
|
||||||
|
#include "cogl-scanout.h"
|
||||||
|
|
||||||
#ifdef COGL_HAS_XLIB_SUPPORT
|
#ifdef COGL_HAS_XLIB_SUPPORT
|
||||||
#include "cogl-texture-pixmap-x11-private.h"
|
#include "cogl-texture-pixmap-x11-private.h"
|
||||||
@ -117,6 +118,10 @@ typedef struct _CoglWinsysVtable
|
|||||||
const int *rectangles,
|
const int *rectangles,
|
||||||
int n_rectangles);
|
int n_rectangles);
|
||||||
|
|
||||||
|
void
|
||||||
|
(*onscreen_direct_scanout) (CoglOnscreen *onscreen,
|
||||||
|
CoglScanout *scanout);
|
||||||
|
|
||||||
void
|
void
|
||||||
(*onscreen_set_visibility) (CoglOnscreen *onscreen,
|
(*onscreen_set_visibility) (CoglOnscreen *onscreen,
|
||||||
gboolean visibility);
|
gboolean visibility);
|
||||||
|
@ -44,7 +44,12 @@ struct _MetaDrmBufferGbm
|
|||||||
uint32_t fb_id;
|
uint32_t fb_id;
|
||||||
};
|
};
|
||||||
|
|
||||||
G_DEFINE_TYPE (MetaDrmBufferGbm, meta_drm_buffer_gbm, META_TYPE_DRM_BUFFER)
|
static void
|
||||||
|
cogl_scanout_iface_init (CoglScanoutInterface *iface);
|
||||||
|
|
||||||
|
G_DEFINE_TYPE_WITH_CODE (MetaDrmBufferGbm, meta_drm_buffer_gbm, META_TYPE_DRM_BUFFER,
|
||||||
|
G_IMPLEMENT_INTERFACE (COGL_TYPE_SCANOUT,
|
||||||
|
cogl_scanout_iface_init))
|
||||||
|
|
||||||
struct gbm_bo *
|
struct gbm_bo *
|
||||||
meta_drm_buffer_gbm_get_bo (MetaDrmBufferGbm *buffer_gbm)
|
meta_drm_buffer_gbm_get_bo (MetaDrmBufferGbm *buffer_gbm)
|
||||||
@ -161,6 +166,11 @@ meta_drm_buffer_gbm_get_fb_id (MetaDrmBuffer *buffer)
|
|||||||
return META_DRM_BUFFER_GBM (buffer)->fb_id;
|
return META_DRM_BUFFER_GBM (buffer)->fb_id;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
cogl_scanout_iface_init (CoglScanoutInterface *iface)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
meta_drm_buffer_gbm_finalize (GObject *object)
|
meta_drm_buffer_gbm_finalize (GObject *object)
|
||||||
{
|
{
|
||||||
|
@ -2013,6 +2013,34 @@ retry:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
ensure_crtc_modes (CoglOnscreen *onscreen,
|
||||||
|
MetaKmsUpdate *kms_update)
|
||||||
|
{
|
||||||
|
CoglOnscreenEGL *onscreen_egl = onscreen->winsys;
|
||||||
|
MetaOnscreenNative *onscreen_native = onscreen_egl->platform;
|
||||||
|
CoglContext *cogl_context = COGL_FRAMEBUFFER (onscreen)->context;
|
||||||
|
CoglRenderer *cogl_renderer = cogl_context->display->renderer;
|
||||||
|
CoglRendererEGL *cogl_renderer_egl = cogl_renderer->winsys;
|
||||||
|
MetaRendererNativeGpuData *renderer_gpu_data = cogl_renderer_egl->platform;
|
||||||
|
MetaRendererNative *renderer_native = renderer_gpu_data->renderer_native;
|
||||||
|
MetaRenderer *renderer = META_RENDERER (renderer_native);
|
||||||
|
MetaBackend *backend = meta_renderer_get_backend (renderer);
|
||||||
|
MetaMonitorManager *monitor_manager =
|
||||||
|
meta_backend_get_monitor_manager (backend);
|
||||||
|
MetaPowerSave power_save_mode;
|
||||||
|
|
||||||
|
power_save_mode = meta_monitor_manager_get_power_save_mode (monitor_manager);
|
||||||
|
if (onscreen_native->pending_set_crtc &&
|
||||||
|
power_save_mode == META_POWER_SAVE_ON)
|
||||||
|
{
|
||||||
|
meta_onscreen_native_set_crtc_mode (onscreen,
|
||||||
|
renderer_gpu_data,
|
||||||
|
kms_update);
|
||||||
|
onscreen_native->pending_set_crtc = FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
meta_onscreen_native_swap_buffers_with_damage (CoglOnscreen *onscreen,
|
meta_onscreen_native_swap_buffers_with_damage (CoglOnscreen *onscreen,
|
||||||
const int *rectangles,
|
const int *rectangles,
|
||||||
@ -2026,8 +2054,6 @@ meta_onscreen_native_swap_buffers_with_damage (CoglOnscreen *onscreen,
|
|||||||
MetaRendererNative *renderer_native = renderer_gpu_data->renderer_native;
|
MetaRendererNative *renderer_native = renderer_gpu_data->renderer_native;
|
||||||
MetaRenderer *renderer = META_RENDERER (renderer_native);
|
MetaRenderer *renderer = META_RENDERER (renderer_native);
|
||||||
MetaBackend *backend = meta_renderer_get_backend (renderer);
|
MetaBackend *backend = meta_renderer_get_backend (renderer);
|
||||||
MetaMonitorManager *monitor_manager =
|
|
||||||
meta_backend_get_monitor_manager (backend);
|
|
||||||
MetaBackendNative *backend_native = META_BACKEND_NATIVE (backend);
|
MetaBackendNative *backend_native = META_BACKEND_NATIVE (backend);
|
||||||
MetaKms *kms = meta_backend_native_get_kms (backend_native);
|
MetaKms *kms = meta_backend_native_get_kms (backend_native);
|
||||||
CoglOnscreenEGL *onscreen_egl = onscreen->winsys;
|
CoglOnscreenEGL *onscreen_egl = onscreen->winsys;
|
||||||
@ -2036,7 +2062,6 @@ meta_onscreen_native_swap_buffers_with_damage (CoglOnscreen *onscreen,
|
|||||||
CoglFrameInfo *frame_info;
|
CoglFrameInfo *frame_info;
|
||||||
gboolean egl_context_changed = FALSE;
|
gboolean egl_context_changed = FALSE;
|
||||||
MetaKmsUpdate *kms_update;
|
MetaKmsUpdate *kms_update;
|
||||||
MetaPowerSave power_save_mode;
|
|
||||||
g_autoptr (GError) error = NULL;
|
g_autoptr (GError) error = NULL;
|
||||||
MetaDrmBufferGbm *buffer_gbm;
|
MetaDrmBufferGbm *buffer_gbm;
|
||||||
g_autoptr (MetaKmsFeedback) kms_feedback = NULL;
|
g_autoptr (MetaKmsFeedback) kms_feedback = NULL;
|
||||||
@ -2095,18 +2120,7 @@ meta_onscreen_native_swap_buffers_with_damage (CoglOnscreen *onscreen,
|
|||||||
|
|
||||||
update_secondary_gpu_state_post_swap_buffers (onscreen, &egl_context_changed);
|
update_secondary_gpu_state_post_swap_buffers (onscreen, &egl_context_changed);
|
||||||
|
|
||||||
/* If this is the first framebuffer to be presented then we now setup the
|
ensure_crtc_modes (onscreen, kms_update);
|
||||||
* crtc modes, else we flip from the previous buffer */
|
|
||||||
|
|
||||||
power_save_mode = meta_monitor_manager_get_power_save_mode (monitor_manager);
|
|
||||||
if (onscreen_native->pending_set_crtc &&
|
|
||||||
power_save_mode == META_POWER_SAVE_ON)
|
|
||||||
{
|
|
||||||
meta_onscreen_native_set_crtc_mode (onscreen,
|
|
||||||
renderer_gpu_data,
|
|
||||||
kms_update);
|
|
||||||
onscreen_native->pending_set_crtc = FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
onscreen_native->pending_queue_swap_notify_frame_count = renderer_native->frame_counter;
|
onscreen_native->pending_queue_swap_notify_frame_count = renderer_native->frame_counter;
|
||||||
meta_onscreen_native_flip_crtcs (onscreen, kms_update);
|
meta_onscreen_native_flip_crtcs (onscreen, kms_update);
|
||||||
@ -2200,6 +2214,50 @@ meta_renderer_native_create_dma_buf (CoglRenderer *cogl_renderer,
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
meta_onscreen_native_direct_scanout (CoglOnscreen *onscreen,
|
||||||
|
CoglScanout *scanout)
|
||||||
|
{
|
||||||
|
CoglOnscreenEGL *onscreen_egl = onscreen->winsys;
|
||||||
|
MetaOnscreenNative *onscreen_native = onscreen_egl->platform;
|
||||||
|
MetaGpuKms *render_gpu = onscreen_native->render_gpu;
|
||||||
|
CoglContext *cogl_context = COGL_FRAMEBUFFER (onscreen)->context;
|
||||||
|
CoglRenderer *cogl_renderer = cogl_context->display->renderer;
|
||||||
|
CoglRendererEGL *cogl_renderer_egl = cogl_renderer->winsys;
|
||||||
|
MetaRendererNativeGpuData *renderer_gpu_data = cogl_renderer_egl->platform;
|
||||||
|
MetaRendererNative *renderer_native = renderer_gpu_data->renderer_native;
|
||||||
|
MetaRenderer *renderer = META_RENDERER (renderer_native);
|
||||||
|
MetaBackend *backend = meta_renderer_get_backend (renderer);
|
||||||
|
MetaBackendNative *backend_native = META_BACKEND_NATIVE (backend);
|
||||||
|
MetaKms *kms = meta_backend_native_get_kms (backend_native);
|
||||||
|
CoglFrameInfo *frame_info;
|
||||||
|
MetaKmsUpdate *kms_update;
|
||||||
|
g_autoptr (GError) error = NULL;
|
||||||
|
|
||||||
|
kms_update = meta_kms_ensure_pending_update (kms);
|
||||||
|
|
||||||
|
wait_for_pending_flips (onscreen);
|
||||||
|
|
||||||
|
frame_info = g_queue_peek_tail (&onscreen->pending_frame_infos);
|
||||||
|
frame_info->global_frame_counter = renderer_native->frame_counter;
|
||||||
|
|
||||||
|
renderer_gpu_data = meta_renderer_native_get_gpu_data (renderer_native,
|
||||||
|
render_gpu);
|
||||||
|
|
||||||
|
g_return_if_fail (renderer_gpu_data->mode == META_RENDERER_NATIVE_MODE_GBM);
|
||||||
|
|
||||||
|
g_warn_if_fail (!onscreen_native->gbm.next_fb);
|
||||||
|
g_set_object (&onscreen_native->gbm.next_fb, META_DRM_BUFFER (scanout));
|
||||||
|
|
||||||
|
ensure_crtc_modes (onscreen, kms_update);
|
||||||
|
|
||||||
|
onscreen_native->pending_queue_swap_notify_frame_count =
|
||||||
|
renderer_native->frame_counter;
|
||||||
|
meta_onscreen_native_flip_crtcs (onscreen, kms_update);
|
||||||
|
|
||||||
|
meta_kms_post_pending_update_sync (kms);
|
||||||
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
meta_renderer_native_init_egl_context (CoglContext *cogl_context,
|
meta_renderer_native_init_egl_context (CoglContext *cogl_context,
|
||||||
GError **error)
|
GError **error)
|
||||||
@ -2923,6 +2981,7 @@ get_native_cogl_winsys_vtable (CoglRenderer *cogl_renderer)
|
|||||||
vtable.onscreen_swap_region = NULL;
|
vtable.onscreen_swap_region = NULL;
|
||||||
vtable.onscreen_swap_buffers_with_damage =
|
vtable.onscreen_swap_buffers_with_damage =
|
||||||
meta_onscreen_native_swap_buffers_with_damage;
|
meta_onscreen_native_swap_buffers_with_damage;
|
||||||
|
vtable.onscreen_direct_scanout = meta_onscreen_native_direct_scanout;
|
||||||
|
|
||||||
vtable.context_get_clock_time = meta_renderer_native_get_clock_time;
|
vtable.context_get_clock_time = meta_renderer_native_get_clock_time;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user