clutter/view: Make it possible to assign a temporary direct scanout

Make it possible to cause the next frame to scan out directly from the
passed CoglScannout. This makes it possible to completely bypass
compositing for the following frame.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/798
This commit is contained in:
Jonas Ådahl 2019-09-12 11:28:50 +02:00
parent 3da8c1bfdc
commit 753066598f
5 changed files with 58 additions and 2 deletions

View File

@ -57,6 +57,10 @@ void clutter_stage_thaw_updates (ClutterStage *stage);
CLUTTER_EXPORT
void clutter_stage_update_resource_scales (ClutterStage *stage);
CLUTTER_EXPORT
void clutter_stage_view_assign_next_scanout (ClutterStageView *stage_view,
CoglScanout *scanout);
CLUTTER_EXPORT
gboolean clutter_actor_has_damage (ClutterActor *actor);

View File

@ -43,4 +43,6 @@ const cairo_region_t * clutter_stage_view_peek_redraw_clip (ClutterStageView *vi
cairo_region_t * clutter_stage_view_take_redraw_clip (ClutterStageView *view);
CoglScanout * clutter_stage_view_take_scanout (ClutterStageView *view);
#endif /* __CLUTTER_STAGE_VIEW_PRIVATE_H__ */

View File

@ -24,6 +24,8 @@
#include <math.h>
#include "clutter/clutter-private.h"
#include "clutter/clutter-mutter.h"
#include "cogl/cogl.h"
enum
{
@ -52,6 +54,8 @@ typedef struct _ClutterStageViewPrivate
CoglOffscreen *shadowfb;
CoglPipeline *shadowfb_pipeline;
CoglScanout *next_scanout;
gboolean has_redraw_clip;
cairo_region_t *redraw_clip;
@ -407,6 +411,26 @@ clutter_stage_default_get_offscreen_transformation_matrix (ClutterStageView *vie
cogl_matrix_init_identity (matrix);
}
void
clutter_stage_view_assign_next_scanout (ClutterStageView *view,
CoglScanout *scanout)
{
ClutterStageViewPrivate *priv =
clutter_stage_view_get_instance_private (view);
g_clear_object (&priv->next_scanout);
priv->next_scanout = scanout;
}
CoglScanout *
clutter_stage_view_take_scanout (ClutterStageView *view)
{
ClutterStageViewPrivate *priv =
clutter_stage_view_get_instance_private (view);
return g_steal_pointer (&priv->next_scanout);
}
static void
clutter_stage_view_get_property (GObject *object,
guint prop_id,

View File

@ -959,6 +959,20 @@ clutter_stage_cogl_redraw_view (ClutterStageWindow *stage_window,
}
}
static void
clutter_stage_cogl_scanout_view (ClutterStageCogl *stage_cogl,
ClutterStageView *view,
CoglScanout *scanout)
{
CoglFramebuffer *framebuffer = clutter_stage_view_get_framebuffer (view);
CoglOnscreen *onscreen;
g_return_if_fail (cogl_is_onscreen (framebuffer));
onscreen = COGL_ONSCREEN (framebuffer);
cogl_onscreen_direct_scanout (onscreen, scanout);
}
static void
clutter_stage_cogl_redraw (ClutterStageWindow *stage_window)
{
@ -971,11 +985,23 @@ clutter_stage_cogl_redraw (ClutterStageWindow *stage_window)
for (l = _clutter_stage_window_get_views (stage_window); l; l = l->next)
{
ClutterStageView *view = l->data;
g_autoptr (CoglScanout) scanout = NULL;
if (!clutter_stage_view_has_redraw_clip (view))
continue;
swap_event |= clutter_stage_cogl_redraw_view (stage_window, view);
scanout = clutter_stage_view_take_scanout (view);
if (scanout)
{
clutter_stage_cogl_scanout_view (stage_cogl,
view,
scanout);
swap_event = TRUE;
}
else
{
swap_event |= clutter_stage_cogl_redraw_view (stage_window, view);
}
}
_clutter_stage_emit_after_paint (stage_cogl->wrapper);

View File

@ -289,7 +289,7 @@ cogl_onscreen_swap_buffers_with_damage (CoglOnscreen *onscreen,
/**
* cogl_onscreen_direct_scanout: (skip)
*/
void
COGL_EXPORT void
cogl_onscreen_direct_scanout (CoglOnscreen *onscreen,
CoglScanout *scanout);