mirror of
https://github.com/brl/mutter.git
synced 2024-11-22 08:00:42 -05: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_LAYOUT,
|
||||||
PROP_FRAMEBUFFER,
|
PROP_FRAMEBUFFER,
|
||||||
PROP_OFFSCREEN,
|
PROP_OFFSCREEN,
|
||||||
PROP_SHADOWFB,
|
PROP_USE_SHADOWFB,
|
||||||
PROP_SCALE,
|
PROP_SCALE,
|
||||||
|
|
||||||
PROP_LAST
|
PROP_LAST
|
||||||
@ -54,6 +54,7 @@ typedef struct _ClutterStageViewPrivate
|
|||||||
CoglOffscreen *offscreen;
|
CoglOffscreen *offscreen;
|
||||||
CoglPipeline *offscreen_pipeline;
|
CoglPipeline *offscreen_pipeline;
|
||||||
|
|
||||||
|
gboolean use_shadowfb;
|
||||||
CoglOffscreen *shadowfb;
|
CoglOffscreen *shadowfb;
|
||||||
CoglPipeline *shadowfb_pipeline;
|
CoglPipeline *shadowfb_pipeline;
|
||||||
|
|
||||||
@ -214,6 +215,80 @@ clutter_stage_view_copy_to_framebuffer (ClutterStageView *view,
|
|||||||
cogl_framebuffer_pop_matrix (dst_framebuffer);
|
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
|
void
|
||||||
clutter_stage_view_after_paint (ClutterStageView *view)
|
clutter_stage_view_after_paint (ClutterStageView *view)
|
||||||
{
|
{
|
||||||
@ -457,8 +532,8 @@ clutter_stage_view_get_property (GObject *object,
|
|||||||
case PROP_OFFSCREEN:
|
case PROP_OFFSCREEN:
|
||||||
g_value_set_boxed (value, priv->offscreen);
|
g_value_set_boxed (value, priv->offscreen);
|
||||||
break;
|
break;
|
||||||
case PROP_SHADOWFB:
|
case PROP_USE_SHADOWFB:
|
||||||
g_value_set_boxed (value, priv->shadowfb);
|
g_value_set_boolean (value, priv->use_shadowfb);
|
||||||
break;
|
break;
|
||||||
case PROP_SCALE:
|
case PROP_SCALE:
|
||||||
g_value_set_float (value, priv->scale);
|
g_value_set_float (value, priv->scale);
|
||||||
@ -508,8 +583,8 @@ clutter_stage_view_set_property (GObject *object,
|
|||||||
case PROP_OFFSCREEN:
|
case PROP_OFFSCREEN:
|
||||||
priv->offscreen = g_value_dup_boxed (value);
|
priv->offscreen = g_value_dup_boxed (value);
|
||||||
break;
|
break;
|
||||||
case PROP_SHADOWFB:
|
case PROP_USE_SHADOWFB:
|
||||||
priv->shadowfb = g_value_dup_boxed (value);
|
priv->use_shadowfb = g_value_get_boolean (value);
|
||||||
break;
|
break;
|
||||||
case PROP_SCALE:
|
case PROP_SCALE:
|
||||||
priv->scale = g_value_get_float (value);
|
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
|
static void
|
||||||
clutter_stage_view_dispose (GObject *object)
|
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->get_property = clutter_stage_view_get_property;
|
||||||
object_class->set_property = clutter_stage_view_set_property;
|
object_class->set_property = clutter_stage_view_set_property;
|
||||||
|
object_class->constructed = clutter_stage_view_constructed;
|
||||||
object_class->dispose = clutter_stage_view_dispose;
|
object_class->dispose = clutter_stage_view_dispose;
|
||||||
|
|
||||||
obj_props[PROP_NAME] =
|
obj_props[PROP_NAME] =
|
||||||
@ -595,14 +684,14 @@ clutter_stage_view_class_init (ClutterStageViewClass *klass)
|
|||||||
G_PARAM_CONSTRUCT_ONLY |
|
G_PARAM_CONSTRUCT_ONLY |
|
||||||
G_PARAM_STATIC_STRINGS);
|
G_PARAM_STATIC_STRINGS);
|
||||||
|
|
||||||
obj_props[PROP_SHADOWFB] =
|
obj_props[PROP_USE_SHADOWFB] =
|
||||||
g_param_spec_boxed ("shadowfb",
|
g_param_spec_boolean ("use-shadowfb",
|
||||||
"Shadow framebuffer",
|
"Use shadowfb",
|
||||||
"Framebuffer used as intermediate shadow buffer",
|
"Whether to use one or more shadow framebuffers",
|
||||||
COGL_TYPE_HANDLE,
|
FALSE,
|
||||||
G_PARAM_READWRITE |
|
G_PARAM_READWRITE |
|
||||||
G_PARAM_CONSTRUCT_ONLY |
|
G_PARAM_CONSTRUCT_ONLY |
|
||||||
G_PARAM_STATIC_STRINGS);
|
G_PARAM_STATIC_STRINGS);
|
||||||
|
|
||||||
obj_props[PROP_SCALE] =
|
obj_props[PROP_SCALE] =
|
||||||
g_param_spec_float ("scale",
|
g_param_spec_float ("scale",
|
||||||
|
@ -3150,7 +3150,7 @@ meta_renderer_native_create_view (MetaRenderer *renderer,
|
|||||||
MetaMonitorTransform view_transform;
|
MetaMonitorTransform view_transform;
|
||||||
CoglOnscreen *onscreen = NULL;
|
CoglOnscreen *onscreen = NULL;
|
||||||
CoglOffscreen *offscreen = NULL;
|
CoglOffscreen *offscreen = NULL;
|
||||||
CoglOffscreen *shadowfb = NULL;
|
gboolean use_shadowfb;
|
||||||
float scale;
|
float scale;
|
||||||
int onscreen_width;
|
int onscreen_width;
|
||||||
int onscreen_height;
|
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);
|
g_error ("Failed to allocate back buffer texture: %s", error->message);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (should_force_shadow_fb (renderer_native,
|
use_shadowfb = should_force_shadow_fb (renderer_native,
|
||||||
renderer_native->primary_gpu_kms))
|
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (meta_is_stage_views_scaled ())
|
if (meta_is_stage_views_scaled ())
|
||||||
scale = meta_logical_monitor_get_scale (logical_monitor);
|
scale = meta_logical_monitor_get_scale (logical_monitor);
|
||||||
@ -3235,11 +3219,10 @@ meta_renderer_native_create_view (MetaRenderer *renderer,
|
|||||||
"scale", scale,
|
"scale", scale,
|
||||||
"framebuffer", onscreen,
|
"framebuffer", onscreen,
|
||||||
"offscreen", offscreen,
|
"offscreen", offscreen,
|
||||||
"shadowfb", shadowfb,
|
"use-shadowfb", use_shadowfb,
|
||||||
"transform", view_transform,
|
"transform", view_transform,
|
||||||
NULL);
|
NULL);
|
||||||
g_clear_pointer (&offscreen, cogl_object_unref);
|
g_clear_pointer (&offscreen, cogl_object_unref);
|
||||||
g_clear_pointer (&shadowfb, cogl_object_unref);
|
|
||||||
|
|
||||||
meta_onscreen_native_set_view (onscreen, view);
|
meta_onscreen_native_set_view (onscreen, view);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user