mirror of
https://github.com/brl/mutter.git
synced 2024-12-22 19:12:04 +00:00
renderer-native: Move shadow fb construction to the stage view
The stage view will need a more involved approach to shadow buffers, in order to implement things such double buffered shadow buffers and damage detection. https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1237
This commit is contained in:
parent
6db94a0b77
commit
f4d9953b9c
@ -35,7 +35,7 @@ enum
|
||||
PROP_LAYOUT,
|
||||
PROP_FRAMEBUFFER,
|
||||
PROP_OFFSCREEN,
|
||||
PROP_SHADOWFB,
|
||||
PROP_USE_SHADOWFB,
|
||||
PROP_SCALE,
|
||||
|
||||
PROP_LAST
|
||||
@ -54,6 +54,7 @@ typedef struct _ClutterStageViewPrivate
|
||||
CoglOffscreen *offscreen;
|
||||
CoglPipeline *offscreen_pipeline;
|
||||
|
||||
gboolean use_shadowfb;
|
||||
CoglOffscreen *shadowfb;
|
||||
CoglPipeline *shadowfb_pipeline;
|
||||
|
||||
@ -214,6 +215,80 @@ clutter_stage_view_copy_to_framebuffer (ClutterStageView *view,
|
||||
cogl_framebuffer_pop_matrix (dst_framebuffer);
|
||||
}
|
||||
|
||||
static CoglOffscreen *
|
||||
create_offscreen_framebuffer (CoglContext *context,
|
||||
int width,
|
||||
int height,
|
||||
GError **error)
|
||||
{
|
||||
CoglOffscreen *framebuffer;
|
||||
CoglTexture2D *texture;
|
||||
|
||||
texture = cogl_texture_2d_new_with_size (context, width, height);
|
||||
cogl_primitive_texture_set_auto_mipmap (COGL_PRIMITIVE_TEXTURE (texture),
|
||||
FALSE);
|
||||
|
||||
if (!cogl_texture_allocate (COGL_TEXTURE (texture), error))
|
||||
{
|
||||
cogl_object_unref (texture);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
framebuffer = cogl_offscreen_new_with_texture (COGL_TEXTURE (texture));
|
||||
cogl_object_unref (texture);
|
||||
if (!cogl_framebuffer_allocate (COGL_FRAMEBUFFER (framebuffer), error))
|
||||
{
|
||||
cogl_object_unref (framebuffer);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return framebuffer;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
init_offscreen_shadowfb (ClutterStageView *view,
|
||||
CoglContext *cogl_context,
|
||||
int width,
|
||||
int height,
|
||||
GError **error)
|
||||
{
|
||||
ClutterStageViewPrivate *priv =
|
||||
clutter_stage_view_get_instance_private (view);
|
||||
CoglOffscreen *offscreen;
|
||||
|
||||
offscreen = create_offscreen_framebuffer (cogl_context, width, height, error);
|
||||
if (!offscreen)
|
||||
return FALSE;
|
||||
|
||||
priv->shadowfb = offscreen;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
init_shadowfb (ClutterStageView *view)
|
||||
{
|
||||
ClutterStageViewPrivate *priv =
|
||||
clutter_stage_view_get_instance_private (view);
|
||||
g_autoptr (GError) error = NULL;
|
||||
int width;
|
||||
int height;
|
||||
CoglContext *cogl_context;
|
||||
|
||||
width = cogl_framebuffer_get_width (priv->framebuffer);
|
||||
height = cogl_framebuffer_get_height (priv->framebuffer);
|
||||
cogl_context = cogl_framebuffer_get_context (priv->framebuffer);
|
||||
|
||||
if (!init_offscreen_shadowfb (view, cogl_context, width, height, &error))
|
||||
{
|
||||
g_warning ("Failed to initialize single buffered shadow fb for %s: %s",
|
||||
priv->name, error->message);
|
||||
}
|
||||
else
|
||||
{
|
||||
g_message ("Initialized single buffered shadow fb for %s", priv->name);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
clutter_stage_view_after_paint (ClutterStageView *view)
|
||||
{
|
||||
@ -457,8 +532,8 @@ clutter_stage_view_get_property (GObject *object,
|
||||
case PROP_OFFSCREEN:
|
||||
g_value_set_boxed (value, priv->offscreen);
|
||||
break;
|
||||
case PROP_SHADOWFB:
|
||||
g_value_set_boxed (value, priv->shadowfb);
|
||||
case PROP_USE_SHADOWFB:
|
||||
g_value_set_boolean (value, priv->use_shadowfb);
|
||||
break;
|
||||
case PROP_SCALE:
|
||||
g_value_set_float (value, priv->scale);
|
||||
@ -508,8 +583,8 @@ clutter_stage_view_set_property (GObject *object,
|
||||
case PROP_OFFSCREEN:
|
||||
priv->offscreen = g_value_dup_boxed (value);
|
||||
break;
|
||||
case PROP_SHADOWFB:
|
||||
priv->shadowfb = g_value_dup_boxed (value);
|
||||
case PROP_USE_SHADOWFB:
|
||||
priv->use_shadowfb = g_value_get_boolean (value);
|
||||
break;
|
||||
case PROP_SCALE:
|
||||
priv->scale = g_value_get_float (value);
|
||||
@ -519,6 +594,19 @@ clutter_stage_view_set_property (GObject *object,
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_stage_view_constructed (GObject *object)
|
||||
{
|
||||
ClutterStageView *view = CLUTTER_STAGE_VIEW (object);
|
||||
ClutterStageViewPrivate *priv =
|
||||
clutter_stage_view_get_instance_private (view);
|
||||
|
||||
if (priv->use_shadowfb)
|
||||
init_shadowfb (view);
|
||||
|
||||
G_OBJECT_CLASS (clutter_stage_view_parent_class)->constructed (object);
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_stage_view_dispose (GObject *object)
|
||||
{
|
||||
@ -558,6 +646,7 @@ clutter_stage_view_class_init (ClutterStageViewClass *klass)
|
||||
|
||||
object_class->get_property = clutter_stage_view_get_property;
|
||||
object_class->set_property = clutter_stage_view_set_property;
|
||||
object_class->constructed = clutter_stage_view_constructed;
|
||||
object_class->dispose = clutter_stage_view_dispose;
|
||||
|
||||
obj_props[PROP_NAME] =
|
||||
@ -595,14 +684,14 @@ clutter_stage_view_class_init (ClutterStageViewClass *klass)
|
||||
G_PARAM_CONSTRUCT_ONLY |
|
||||
G_PARAM_STATIC_STRINGS);
|
||||
|
||||
obj_props[PROP_SHADOWFB] =
|
||||
g_param_spec_boxed ("shadowfb",
|
||||
"Shadow framebuffer",
|
||||
"Framebuffer used as intermediate shadow buffer",
|
||||
COGL_TYPE_HANDLE,
|
||||
G_PARAM_READWRITE |
|
||||
G_PARAM_CONSTRUCT_ONLY |
|
||||
G_PARAM_STATIC_STRINGS);
|
||||
obj_props[PROP_USE_SHADOWFB] =
|
||||
g_param_spec_boolean ("use-shadowfb",
|
||||
"Use shadowfb",
|
||||
"Whether to use one or more shadow framebuffers",
|
||||
FALSE,
|
||||
G_PARAM_READWRITE |
|
||||
G_PARAM_CONSTRUCT_ONLY |
|
||||
G_PARAM_STATIC_STRINGS);
|
||||
|
||||
obj_props[PROP_SCALE] =
|
||||
g_param_spec_float ("scale",
|
||||
|
@ -3150,7 +3150,7 @@ meta_renderer_native_create_view (MetaRenderer *renderer,
|
||||
MetaMonitorTransform view_transform;
|
||||
CoglOnscreen *onscreen = NULL;
|
||||
CoglOffscreen *offscreen = NULL;
|
||||
CoglOffscreen *shadowfb = NULL;
|
||||
gboolean use_shadowfb;
|
||||
float scale;
|
||||
int onscreen_width;
|
||||
int onscreen_height;
|
||||
@ -3202,24 +3202,8 @@ meta_renderer_native_create_view (MetaRenderer *renderer,
|
||||
g_error ("Failed to allocate back buffer texture: %s", error->message);
|
||||
}
|
||||
|
||||
if (should_force_shadow_fb (renderer_native,
|
||||
renderer_native->primary_gpu_kms))
|
||||
{
|
||||
int shadow_width;
|
||||
int shadow_height;
|
||||
|
||||
/* The shadowfb must be the same size as the on-screen framebuffer */
|
||||
shadow_width = cogl_framebuffer_get_width (COGL_FRAMEBUFFER (onscreen));
|
||||
shadow_height = cogl_framebuffer_get_height (COGL_FRAMEBUFFER (onscreen));
|
||||
|
||||
shadowfb = meta_renderer_native_create_offscreen (renderer_native,
|
||||
cogl_context,
|
||||
shadow_width,
|
||||
shadow_height,
|
||||
&error);
|
||||
if (!shadowfb)
|
||||
g_error ("Failed to allocate shadow buffer texture: %s", error->message);
|
||||
}
|
||||
use_shadowfb = should_force_shadow_fb (renderer_native,
|
||||
renderer_native->primary_gpu_kms);
|
||||
|
||||
if (meta_is_stage_views_scaled ())
|
||||
scale = meta_logical_monitor_get_scale (logical_monitor);
|
||||
@ -3235,11 +3219,10 @@ meta_renderer_native_create_view (MetaRenderer *renderer,
|
||||
"scale", scale,
|
||||
"framebuffer", onscreen,
|
||||
"offscreen", offscreen,
|
||||
"shadowfb", shadowfb,
|
||||
"use-shadowfb", use_shadowfb,
|
||||
"transform", view_transform,
|
||||
NULL);
|
||||
g_clear_pointer (&offscreen, cogl_object_unref);
|
||||
g_clear_pointer (&shadowfb, cogl_object_unref);
|
||||
|
||||
meta_onscreen_native_set_view (onscreen, view);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user