mirror of
https://github.com/brl/mutter.git
synced 2024-11-21 15:40:41 -05:00
clutter/stage: Use multiple frusta depending on the redraw clip
The redraw clip region may contain multiple clip rectangles. We currently only use the extents of this region, but having multiple frusta for each rectangle is a better alternative, and will allow us to remove the extra projection we currently do. Make the clip frustum an array, with multiple frusta. https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1489
This commit is contained in:
parent
63d05565f6
commit
d1d3ac6b20
@ -3449,7 +3449,9 @@ cull_actor (ClutterActor *self,
|
||||
ClutterCullResult *result_out)
|
||||
{
|
||||
ClutterActorPrivate *priv = self->priv;
|
||||
const graphene_frustum_t *clip_frustum;
|
||||
const GArray *clip_frusta;
|
||||
ClutterCullResult result;
|
||||
int i;
|
||||
|
||||
if (!priv->last_paint_volume_valid)
|
||||
{
|
||||
@ -3470,12 +3472,26 @@ cull_actor (ClutterActor *self,
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
clip_frustum = clutter_paint_context_get_clip_frustum (paint_context);
|
||||
clip_frusta = clutter_paint_context_get_clip_frusta (paint_context);
|
||||
if (!clip_frusta)
|
||||
{
|
||||
*result_out = CLUTTER_CULL_RESULT_IN;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
*result_out =
|
||||
_clutter_paint_volume_cull (&priv->last_paint_volume, clip_frustum);
|
||||
for (i = 0; i < clip_frusta->len; i++)
|
||||
{
|
||||
const graphene_frustum_t *clip_frustum =
|
||||
&g_array_index (clip_frusta, graphene_frustum_t, i);
|
||||
|
||||
if (*result_out != CLUTTER_CULL_RESULT_OUT)
|
||||
result = _clutter_paint_volume_cull (&priv->last_paint_volume,
|
||||
clip_frustum);
|
||||
|
||||
if (result != CLUTTER_CULL_RESULT_OUT)
|
||||
break;
|
||||
}
|
||||
|
||||
if (result != CLUTTER_CULL_RESULT_OUT)
|
||||
{
|
||||
const cairo_region_t *redraw_clip;
|
||||
|
||||
@ -3504,15 +3520,17 @@ cull_actor (ClutterActor *self,
|
||||
{
|
||||
case CAIRO_REGION_OVERLAP_IN:
|
||||
case CAIRO_REGION_OVERLAP_PART:
|
||||
*result_out = CLUTTER_CULL_RESULT_IN;
|
||||
result = CLUTTER_CULL_RESULT_IN;
|
||||
break;
|
||||
case CAIRO_REGION_OVERLAP_OUT:
|
||||
*result_out = CLUTTER_CULL_RESULT_OUT;
|
||||
result = CLUTTER_CULL_RESULT_OUT;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
*result_out = result;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
@ -21,16 +21,16 @@
|
||||
#include "clutter-paint-context.h"
|
||||
|
||||
ClutterPaintContext *
|
||||
clutter_paint_context_new_for_view (ClutterStageView *view,
|
||||
const cairo_region_t *redraw_clip,
|
||||
const graphene_frustum_t *clip_frustum,
|
||||
ClutterPaintFlag paint_flags);
|
||||
clutter_paint_context_new_for_view (ClutterStageView *view,
|
||||
const cairo_region_t *redraw_clip,
|
||||
GArray *clip_frusta,
|
||||
ClutterPaintFlag paint_flags);
|
||||
|
||||
gboolean clutter_paint_context_is_drawing_off_stage (ClutterPaintContext *paint_context);
|
||||
|
||||
CoglFramebuffer * clutter_paint_context_get_base_framebuffer (ClutterPaintContext *paint_context);
|
||||
|
||||
const graphene_frustum_t *
|
||||
clutter_paint_context_get_clip_frustum (ClutterPaintContext *paint_context);
|
||||
const GArray *
|
||||
clutter_paint_context_get_clip_frusta (ClutterPaintContext *paint_context);
|
||||
|
||||
#endif /* CLUTTER_PAINT_CONTEXT_PRIVATE_H */
|
||||
|
@ -30,7 +30,7 @@ struct _ClutterPaintContext
|
||||
ClutterStageView *view;
|
||||
|
||||
cairo_region_t *redraw_clip;
|
||||
graphene_frustum_t clip_frustum;
|
||||
GArray *clip_frusta;
|
||||
};
|
||||
|
||||
G_DEFINE_BOXED_TYPE (ClutterPaintContext, clutter_paint_context,
|
||||
@ -38,10 +38,10 @@ G_DEFINE_BOXED_TYPE (ClutterPaintContext, clutter_paint_context,
|
||||
clutter_paint_context_unref)
|
||||
|
||||
ClutterPaintContext *
|
||||
clutter_paint_context_new_for_view (ClutterStageView *view,
|
||||
const cairo_region_t *redraw_clip,
|
||||
const graphene_frustum_t *clip_frustum,
|
||||
ClutterPaintFlag paint_flags)
|
||||
clutter_paint_context_new_for_view (ClutterStageView *view,
|
||||
const cairo_region_t *redraw_clip,
|
||||
GArray *clip_frusta,
|
||||
ClutterPaintFlag paint_flags)
|
||||
{
|
||||
ClutterPaintContext *paint_context;
|
||||
CoglFramebuffer *framebuffer;
|
||||
@ -50,9 +50,8 @@ clutter_paint_context_new_for_view (ClutterStageView *view,
|
||||
g_ref_count_init (&paint_context->ref_count);
|
||||
paint_context->view = view;
|
||||
paint_context->redraw_clip = cairo_region_copy (redraw_clip);
|
||||
paint_context->clip_frusta = g_array_ref (clip_frusta);
|
||||
paint_context->paint_flags = paint_flags;
|
||||
graphene_frustum_init_from_frustum (&paint_context->clip_frustum,
|
||||
clip_frustum);
|
||||
|
||||
framebuffer = clutter_stage_view_get_framebuffer (view);
|
||||
clutter_paint_context_push_framebuffer (paint_context, framebuffer);
|
||||
@ -93,6 +92,7 @@ clutter_paint_context_dispose (ClutterPaintContext *paint_context)
|
||||
g_list_free_full (paint_context->framebuffers, g_object_unref);
|
||||
paint_context->framebuffers = NULL;
|
||||
g_clear_pointer (&paint_context->redraw_clip, cairo_region_destroy);
|
||||
g_clear_pointer (&paint_context->clip_frusta, g_array_unref);
|
||||
}
|
||||
|
||||
void
|
||||
@ -137,10 +137,10 @@ clutter_paint_context_get_redraw_clip (ClutterPaintContext *paint_context)
|
||||
return paint_context->redraw_clip;
|
||||
}
|
||||
|
||||
const graphene_frustum_t *
|
||||
clutter_paint_context_get_clip_frustum (ClutterPaintContext *paint_context)
|
||||
const GArray *
|
||||
clutter_paint_context_get_clip_frusta (ClutterPaintContext *paint_context)
|
||||
{
|
||||
return &paint_context->clip_frustum;
|
||||
return paint_context->clip_frusta;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -77,6 +77,8 @@
|
||||
|
||||
#include "cogl/cogl.h"
|
||||
|
||||
#define MAX_FRUSTA 64
|
||||
|
||||
struct _ClutterStageQueueRedrawEntry
|
||||
{
|
||||
ClutterActor *actor;
|
||||
@ -814,8 +816,6 @@ setup_view_for_paint (ClutterStage *stage,
|
||||
&priv->inverse_projection,
|
||||
&priv->perspective,
|
||||
out_frustum);
|
||||
|
||||
_clutter_stage_paint_volume_stack_free_all (stage);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -826,7 +826,9 @@ clutter_stage_do_paint_view (ClutterStage *stage,
|
||||
ClutterStagePrivate *priv = stage->priv;
|
||||
ClutterPaintContext *paint_context;
|
||||
cairo_rectangle_int_t clip_rect;
|
||||
g_autoptr (GArray) clip_frusta = NULL;
|
||||
graphene_frustum_t clip_frustum;
|
||||
int n_rectangles;
|
||||
|
||||
/* Any mode of painting/picking invalidates the pick cache, unless we're
|
||||
* in the middle of building it. So we reset the cached flag but don't
|
||||
@ -834,12 +836,41 @@ clutter_stage_do_paint_view (ClutterStage *stage,
|
||||
*/
|
||||
priv->cached_pick_mode = CLUTTER_PICK_NONE;
|
||||
|
||||
cairo_region_get_extents (redraw_clip, &clip_rect);
|
||||
setup_view_for_paint (stage, view, &clip_rect, &clip_frustum);
|
||||
n_rectangles = redraw_clip ? cairo_region_num_rectangles (redraw_clip) : 0;
|
||||
if (redraw_clip && n_rectangles < MAX_FRUSTA)
|
||||
{
|
||||
int i;
|
||||
|
||||
clip_frusta = g_array_sized_new (FALSE, FALSE,
|
||||
sizeof (graphene_frustum_t),
|
||||
n_rectangles);
|
||||
|
||||
for (i = 0; i < n_rectangles; i++)
|
||||
{
|
||||
cairo_region_get_rectangle (redraw_clip, i, &clip_rect);
|
||||
setup_view_for_paint (stage, view, &clip_rect, &clip_frustum);
|
||||
g_array_append_val (clip_frusta, clip_frustum);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
clip_frusta = g_array_sized_new (FALSE, FALSE,
|
||||
sizeof (graphene_frustum_t),
|
||||
1);
|
||||
if (redraw_clip)
|
||||
cairo_region_get_extents (redraw_clip, &clip_rect);
|
||||
else
|
||||
clutter_stage_view_get_layout (view, &clip_rect);
|
||||
|
||||
setup_view_for_paint (stage, view, &clip_rect, &clip_frustum);
|
||||
g_array_append_val (clip_frusta, clip_frustum);
|
||||
}
|
||||
|
||||
_clutter_stage_paint_volume_stack_free_all (stage);
|
||||
|
||||
paint_context = clutter_paint_context_new_for_view (view,
|
||||
redraw_clip,
|
||||
&clip_frustum,
|
||||
clip_frusta,
|
||||
CLUTTER_PAINT_FLAG_NONE);
|
||||
|
||||
clutter_actor_paint (CLUTTER_ACTOR (stage), paint_context);
|
||||
|
Loading…
Reference in New Issue
Block a user