clutter/stage: Use graphene_frustum_t for clipping

Instead of 4 planes, use a graphene_frustum_t to store the clipping
planes.

The cautious reviewer might noticed that we are now setting up 6
planes: the 4 planes we were doing before, plus 2 extra planes in
the Z axis. These extra planes simulate an "infinite" Z far, and
an "on-camera" Z near.

https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1489
This commit is contained in:
Georges Basile Stavracas Neto 2020-10-09 19:08:47 -03:00
parent 338a9275b4
commit a84dccfd64
5 changed files with 39 additions and 40 deletions

View File

@ -3444,7 +3444,7 @@ cull_actor (ClutterActor *self,
{ {
ClutterActorPrivate *priv = self->priv; ClutterActorPrivate *priv = self->priv;
ClutterStage *stage; ClutterStage *stage;
const graphene_plane_t *stage_clip; const graphene_frustum_t *clip_frustum;
if (!priv->last_paint_volume_valid) if (!priv->last_paint_volume_valid)
{ {
@ -3466,10 +3466,10 @@ cull_actor (ClutterActor *self,
} }
stage = (ClutterStage *) _clutter_actor_get_stage_internal (self); stage = (ClutterStage *) _clutter_actor_get_stage_internal (self);
stage_clip = _clutter_stage_get_clip (stage); clip_frustum = _clutter_stage_get_clip (stage);
*result_out = *result_out =
_clutter_paint_volume_cull (&priv->last_paint_volume, stage_clip); _clutter_paint_volume_cull (&priv->last_paint_volume, clip_frustum);
if (*result_out != CLUTTER_CULL_RESULT_OUT) if (*result_out != CLUTTER_CULL_RESULT_OUT)
{ {

View File

@ -124,7 +124,7 @@ void _clutter_paint_volume_set_reference_actor (ClutterPaintVolu
ClutterActor *actor); ClutterActor *actor);
ClutterCullResult _clutter_paint_volume_cull (ClutterPaintVolume *pv, ClutterCullResult _clutter_paint_volume_cull (ClutterPaintVolume *pv,
const graphene_plane_t *planes); const graphene_frustum_t *frustum);
void _clutter_paint_volume_get_stage_paint_box (ClutterPaintVolume *pv, void _clutter_paint_volume_get_stage_paint_box (ClutterPaintVolume *pv,
ClutterStage *stage, ClutterStage *stage,

View File

@ -1072,13 +1072,10 @@ _clutter_paint_volume_set_reference_actor (ClutterPaintVolume *pv,
ClutterCullResult ClutterCullResult
_clutter_paint_volume_cull (ClutterPaintVolume *pv, _clutter_paint_volume_cull (ClutterPaintVolume *pv,
const graphene_plane_t *planes) const graphene_frustum_t *frustum)
{ {
int vertex_count; int vertex_count;
graphene_point3d_t *vertices = pv->vertices; graphene_box_t box;
gboolean partial = FALSE;
int i;
int j;
if (pv->is_empty) if (pv->is_empty)
return CLUTTER_CULL_RESULT_OUT; return CLUTTER_CULL_RESULT_OUT;
@ -1095,26 +1092,12 @@ _clutter_paint_volume_cull (ClutterPaintVolume *pv,
else else
vertex_count = 8; vertex_count = 8;
for (i = 0; i < 4; i++) graphene_box_init_from_points (&box, vertex_count, pv->vertices);
{
const graphene_plane_t *plane = &planes[i];
int out = 0;
for (j = 0; j < vertex_count; j++)
{
if (graphene_plane_distance (plane, &vertices[j]) < 0)
out++;
}
if (out == vertex_count) if (graphene_frustum_intersects_box (frustum, &box))
return CLUTTER_CULL_RESULT_OUT;
else if (out != 0)
partial = TRUE;
}
if (partial)
return CLUTTER_CULL_RESULT_PARTIAL;
else
return CLUTTER_CULL_RESULT_IN; return CLUTTER_CULL_RESULT_IN;
else
return CLUTTER_CULL_RESULT_OUT;
} }
void void

View File

@ -98,7 +98,7 @@ ClutterActor *_clutter_stage_do_pick (ClutterStage *stage,
ClutterPaintVolume *_clutter_stage_paint_volume_stack_allocate (ClutterStage *stage); ClutterPaintVolume *_clutter_stage_paint_volume_stack_allocate (ClutterStage *stage);
void _clutter_stage_paint_volume_stack_free_all (ClutterStage *stage); void _clutter_stage_paint_volume_stack_free_all (ClutterStage *stage);
const graphene_plane_t *_clutter_stage_get_clip (ClutterStage *stage); const graphene_frustum_t *_clutter_stage_get_clip (ClutterStage *stage);
ClutterStageQueueRedrawEntry *_clutter_stage_queue_actor_redraw (ClutterStage *stage, ClutterStageQueueRedrawEntry *_clutter_stage_queue_actor_redraw (ClutterStage *stage,
ClutterStageQueueRedrawEntry *entry, ClutterStageQueueRedrawEntry *entry,

View File

@ -115,7 +115,7 @@ struct _ClutterStagePrivate
GArray *paint_volume_stack; GArray *paint_volume_stack;
graphene_plane_t current_clip_planes[4]; graphene_frustum_t clip_frustum;
GSList *pending_relayouts; GSList *pending_relayouts;
GList *pending_queue_redraws; GList *pending_queue_redraws;
@ -664,8 +664,11 @@ _cogl_util_get_eye_planes_for_screen_poly (float *polygon,
float *viewport, float *viewport,
const graphene_matrix_t *projection, const graphene_matrix_t *projection,
const graphene_matrix_t *inverse_project, const graphene_matrix_t *inverse_project,
graphene_plane_t *planes) const ClutterPerspective *perspective,
graphene_frustum_t *frustum)
{ {
graphene_plane_t planes[6];
graphene_vec4_t v;
float Wc; float Wc;
Vector4 *tmp_poly; Vector4 *tmp_poly;
int i; int i;
@ -749,6 +752,18 @@ _cogl_util_get_eye_planes_for_screen_poly (float *polygon,
graphene_plane_init_from_points (&planes[i], &p[0], &p[1], &p[2]); graphene_plane_init_from_points (&planes[i], &p[0], &p[1], &p[2]);
} }
graphene_plane_init_from_vec4 (&planes[4],
graphene_vec4_init (&v, 0.f, 0.f, -1.f,
perspective->z_near));
graphene_plane_init_from_vec4 (&planes[5],
graphene_vec4_init (&v, 0.f, 0.f, 1.f,
perspective->z_far));
graphene_frustum_init (frustum,
&planes[0], &planes[1],
&planes[2], &planes[3],
&planes[4], &planes[5]);
} }
/* XXX: Instead of having a toplevel 2D clip region, it might be /* XXX: Instead of having a toplevel 2D clip region, it might be
@ -809,7 +824,8 @@ setup_view_for_pick_or_paint (ClutterStage *stage,
viewport, viewport,
&priv->projection, &priv->projection,
&priv->inverse_projection, &priv->inverse_projection,
priv->current_clip_planes); &priv->perspective,
&priv->clip_frustum);
_clutter_stage_paint_volume_stack_free_all (stage); _clutter_stage_paint_volume_stack_free_all (stage);
} }
@ -3075,10 +3091,10 @@ _clutter_stage_paint_volume_stack_free_all (ClutterStage *stage)
/* The is an out-of-band parameter available while painting that /* The is an out-of-band parameter available while painting that
* can be used to cull actors. */ * can be used to cull actors. */
const graphene_plane_t * const graphene_frustum_t *
_clutter_stage_get_clip (ClutterStage *stage) _clutter_stage_get_clip (ClutterStage *stage)
{ {
return stage->priv->current_clip_planes; return &stage->priv->clip_frustum;
} }
/* When an actor queues a redraw we add it to a list on the stage that /* When an actor queues a redraw we add it to a list on the stage that