mirror of
https://github.com/brl/mutter.git
synced 2024-11-25 09:30:45 -05:00
clutter/offscreen-effect: Set the viewport correctly
Previously we were setting the FBO's viewport to be the same dimensions as the stage itself for compatibility. This works for most cases, but not if the actor is larger than the stage. In that case it could cause excessive clipping if the actor's transformed screen position was negative, which is seen in https://gitlab.gnome.org/GNOME/gnome-shell/issues/2087 Also if a small actor paints to its negative dimensions (like a box-shadow) then we might be missing those pixels on the left or top, even though they're inside the paint volume. Now we set the viewport dimensions to match the area we're actually rendering so the FBO contents are never over or under clipped. Fixes: https://gitlab.gnome.org/GNOME/gnome-shell/-/issues/3068 Although if you try using shadows larger than that (like in gnome-shell#1090) then you will also need gnome-shell!1417. Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1053>
This commit is contained in:
parent
f887b02714
commit
41bf0181b9
@ -300,7 +300,7 @@ clutter_offscreen_effect_pre_paint (ClutterEffect *effect,
|
|||||||
CoglFramebuffer *offscreen;
|
CoglFramebuffer *offscreen;
|
||||||
ClutterActorBox raw_box, box;
|
ClutterActorBox raw_box, box;
|
||||||
ClutterActor *stage;
|
ClutterActor *stage;
|
||||||
graphene_matrix_t projection, modelview;
|
graphene_matrix_t projection, modelview, transform;
|
||||||
const ClutterPaintVolume *volume;
|
const ClutterPaintVolume *volume;
|
||||||
gfloat stage_width, stage_height;
|
gfloat stage_width, stage_height;
|
||||||
gfloat target_width = -1, target_height = -1;
|
gfloat target_width = -1, target_height = -1;
|
||||||
@ -368,16 +368,25 @@ clutter_offscreen_effect_pre_paint (ClutterEffect *effect,
|
|||||||
* contents on screen...
|
* contents on screen...
|
||||||
*/
|
*/
|
||||||
clutter_actor_get_transform (priv->stage, &modelview);
|
clutter_actor_get_transform (priv->stage, &modelview);
|
||||||
|
graphene_matrix_init_translate (&transform,
|
||||||
|
&GRAPHENE_POINT3D_INIT (-priv->fbo_offset_x,
|
||||||
|
-priv->fbo_offset_y,
|
||||||
|
0.0));
|
||||||
|
graphene_matrix_scale (&transform,
|
||||||
|
stage_width / target_width,
|
||||||
|
stage_height / target_height,
|
||||||
|
1.0);
|
||||||
|
graphene_matrix_multiply (&transform, &modelview, &modelview);
|
||||||
cogl_framebuffer_set_modelview_matrix (offscreen, &modelview);
|
cogl_framebuffer_set_modelview_matrix (offscreen, &modelview);
|
||||||
|
|
||||||
/* Set up the viewport so that it has the same size as the stage (avoid
|
/* Set up the viewport so that it has the minimal size required to render any
|
||||||
* distortion), but translated to account for the FBO offset...
|
* pixel in the FBO without clipping.
|
||||||
*/
|
*/
|
||||||
cogl_framebuffer_set_viewport (offscreen,
|
cogl_framebuffer_set_viewport (offscreen,
|
||||||
-priv->fbo_offset_x,
|
0,
|
||||||
-priv->fbo_offset_y,
|
0,
|
||||||
stage_width,
|
target_width,
|
||||||
stage_height);
|
target_height);
|
||||||
|
|
||||||
/* Copy the stage's projection matrix across to the offscreen */
|
/* Copy the stage's projection matrix across to the offscreen */
|
||||||
_clutter_stage_get_projection_matrix (CLUTTER_STAGE (priv->stage),
|
_clutter_stage_get_projection_matrix (CLUTTER_STAGE (priv->stage),
|
||||||
|
Loading…
Reference in New Issue
Block a user