[mutter] clutter: Add ability to scale stage views
- From: Jonas Ådahl <jadahl src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [mutter] clutter: Add ability to scale stage views
- Date: Fri, 7 Apr 2017 14:34:44 +0000 (UTC)
commit 63450d69d38faee9aa2b6e7e419ee10a9d6d6d4b
Author: Jonas Ådahl <jadahl gmail com>
Date: Fri Feb 24 17:38:47 2017 +0800
clutter: Add ability to scale stage views
This commit adds the ability to set a scale on a scale view. This will
cause the content in the stage view to be painted with the given scale,
while still keeping the configured layout on the stage. In effect, for
a stage view with scale 'n', this means the framebuffer of a given stage
will 'n' times larger, keeping the same size on the stage.
https://bugzilla.gnome.org/show_bug.cgi?id=777732
clutter/clutter/clutter-stage-view.c | 26 ++++++++++++
clutter/clutter/clutter-stage-view.h | 3 +
clutter/clutter/clutter-stage.c | 64 ++++++++++++++++-------------
clutter/clutter/cogl/clutter-stage-cogl.c | 30 +++++++------
4 files changed, 80 insertions(+), 43 deletions(-)
---
diff --git a/clutter/clutter/clutter-stage-view.c b/clutter/clutter/clutter-stage-view.c
index e399278..a584b81 100644
--- a/clutter/clutter/clutter-stage-view.c
+++ b/clutter/clutter/clutter-stage-view.c
@@ -28,6 +28,7 @@ enum
PROP_LAYOUT,
PROP_FRAMEBUFFER,
PROP_OFFSCREEN,
+ PROP_SCALE,
PROP_LAST
};
@@ -37,6 +38,7 @@ static GParamSpec *obj_props[PROP_LAST];
typedef struct _ClutterStageViewPrivate
{
cairo_rectangle_int_t layout;
+ int scale;
CoglFramebuffer *framebuffer;
CoglOffscreen *offscreen;
@@ -141,6 +143,15 @@ clutter_stage_view_blit_offscreen (ClutterStageView *view,
cogl_framebuffer_pop_matrix (priv->framebuffer);
}
+int
+clutter_stage_view_get_scale (ClutterStageView *view)
+{
+ ClutterStageViewPrivate *priv =
+ clutter_stage_view_get_instance_private (view);
+
+ return priv->scale;
+}
+
gboolean
clutter_stage_view_is_dirty_viewport (ClutterStageView *view)
{
@@ -229,6 +240,9 @@ clutter_stage_view_get_property (GObject *object,
case PROP_OFFSCREEN:
g_value_set_boxed (value, priv->offscreen);
break;
+ case PROP_SCALE:
+ g_value_set_int (value, priv->scale);
+ break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
}
@@ -257,6 +271,9 @@ clutter_stage_view_set_property (GObject *object,
case PROP_OFFSCREEN:
priv->offscreen = g_value_dup_boxed (value);
break;
+ case PROP_SCALE:
+ priv->scale = g_value_get_int (value);
+ break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
}
@@ -284,6 +301,7 @@ clutter_stage_view_init (ClutterStageView *view)
priv->dirty_viewport = TRUE;
priv->dirty_projection = TRUE;
+ priv->scale = 1;
}
static void
@@ -323,5 +341,13 @@ clutter_stage_view_class_init (ClutterStageViewClass *klass)
G_PARAM_CONSTRUCT_ONLY |
G_PARAM_STATIC_STRINGS);
+ obj_props[PROP_SCALE] =
+ g_param_spec_int ("scale",
+ "View scale",
+ "The view scale",
+ 1, G_MAXINT, 1,
+ G_PARAM_READWRITE |
+ G_PARAM_STATIC_STRINGS);
+
g_object_class_install_properties (object_class, PROP_LAST, obj_props);
}
diff --git a/clutter/clutter/clutter-stage-view.h b/clutter/clutter/clutter-stage-view.h
index 3eb8da4..a358d4d 100644
--- a/clutter/clutter/clutter-stage-view.h
+++ b/clutter/clutter/clutter-stage-view.h
@@ -60,6 +60,9 @@ void clutter_stage_view_transform_to_onscreen (ClutterStageView *vie
void clutter_stage_view_blit_offscreen (ClutterStageView *view,
const cairo_rectangle_int_t *clip);
+CLUTTER_AVAILABLE_IN_MUTTER
+int clutter_stage_view_get_scale (ClutterStageView *view);
+
gboolean clutter_stage_view_is_dirty_viewport (ClutterStageView *view);
void clutter_stage_view_set_dirty_viewport (ClutterStageView *view,
diff --git a/clutter/clutter/clutter-stage.c b/clutter/clutter/clutter-stage.c
index 21968b9..a43f3b7 100644
--- a/clutter/clutter/clutter-stage.c
+++ b/clutter/clutter/clutter-stage.c
@@ -1380,6 +1380,8 @@ _clutter_stage_do_pick_on_view (ClutterStage *stage,
gint read_y;
int window_scale;
float fb_width, fb_height;
+ int view_scale;
+ int fb_scale;
int viewport_offset_x;
int viewport_offset_y;
@@ -1387,10 +1389,12 @@ _clutter_stage_do_pick_on_view (ClutterStage *stage,
context = _clutter_context_get_default ();
window_scale = _clutter_stage_window_get_scale_factor (priv->impl);
+ view_scale = clutter_stage_view_get_scale (view);
+ fb_scale = window_scale * view_scale;
clutter_stage_view_get_layout (view, &view_layout);
- fb_width = view_layout.width;
- fb_height = view_layout.height;
+ fb_width = view_layout.width * view_scale;
+ fb_height = view_layout.height * view_scale;
cogl_push_framebuffer (fb);
/* needed for when a context switch happens */
@@ -1400,38 +1404,38 @@ _clutter_stage_do_pick_on_view (ClutterStage *stage,
* picking to not work at all, so setting it the whole framebuffer content
* for now. */
cogl_framebuffer_push_scissor_clip (fb, 0, 0,
- view_layout.width,
- view_layout.height);
+ view_layout.width * view_scale,
+ view_layout.height * view_scale);
_clutter_stage_window_get_dirty_pixel (priv->impl, view, &dirty_x, &dirty_y);
if (G_LIKELY (!(clutter_pick_debug_flags & CLUTTER_DEBUG_DUMP_PICK_BUFFERS)))
{
CLUTTER_NOTE (PICK, "Pushing pick scissor clip x: %d, y: %d, 1x1",
- dirty_x * window_scale,
- dirty_y * window_scale);
- cogl_framebuffer_push_scissor_clip (fb, dirty_x * window_scale, dirty_y * window_scale, 1, 1);
+ dirty_x * fb_scale,
+ dirty_y * fb_scale);
+ cogl_framebuffer_push_scissor_clip (fb, dirty_x * fb_scale, dirty_y * fb_scale, 1, 1);
}
- viewport_offset_x = x * window_scale - dirty_x * window_scale;
- viewport_offset_y = y * window_scale - dirty_y * window_scale;
+ viewport_offset_x = x * fb_scale - dirty_x * fb_scale;
+ viewport_offset_y = y * fb_scale - dirty_y * fb_scale;
CLUTTER_NOTE (PICK, "Setting viewport to %f, %f, %f, %f",
- priv->viewport[0] * window_scale - viewport_offset_x,
- priv->viewport[1] * window_scale - viewport_offset_y,
- priv->viewport[2] * window_scale,
- priv->viewport[3] * window_scale);
- cogl_set_viewport (priv->viewport[0] * window_scale - viewport_offset_x,
- priv->viewport[1] * window_scale - viewport_offset_y,
- priv->viewport[2] * window_scale,
- priv->viewport[3] * window_scale);
-
- read_x = dirty_x * window_scale;
- read_y = dirty_y * window_scale;
-
- CLUTTER_NOTE (PICK, "Performing pick at %i,%i on view %dx%d+%d+%d",
+ priv->viewport[0] * fb_scale - viewport_offset_x,
+ priv->viewport[1] * fb_scale - viewport_offset_y,
+ priv->viewport[2] * fb_scale,
+ priv->viewport[3] * fb_scale);
+ cogl_set_viewport (priv->viewport[0] * fb_scale - viewport_offset_x,
+ priv->viewport[1] * fb_scale - viewport_offset_y,
+ priv->viewport[2] * fb_scale,
+ priv->viewport[3] * fb_scale);
+
+ read_x = dirty_x * fb_scale;
+ read_y = dirty_y * fb_scale;
+
+ CLUTTER_NOTE (PICK, "Performing pick at %i,%i on view %dx%d+%d+%d s: %d",
x, y,
view_layout.width, view_layout.height,
- view_layout.x, view_layout.y);
+ view_layout.x, view_layout.y, view_scale);
cogl_color_init_from_4ub (&stage_pick_id, 255, 255, 255, 255);
cogl_clear (&stage_pick_id, COGL_BUFFER_BIT_COLOR | COGL_BUFFER_BIT_DEPTH);
@@ -3569,6 +3573,7 @@ _clutter_stage_maybe_setup_viewport (ClutterStage *stage,
cairo_rectangle_int_t view_layout;
ClutterPerspective perspective;
int window_scale;
+ int fb_scale;
int viewport_offset_x;
int viewport_offset_y;
float z_2d;
@@ -3579,14 +3584,15 @@ _clutter_stage_maybe_setup_viewport (ClutterStage *stage,
priv->viewport[3]);
window_scale = _clutter_stage_window_get_scale_factor (priv->impl);
+ fb_scale = window_scale * clutter_stage_view_get_scale (view);
clutter_stage_view_get_layout (view, &view_layout);
- viewport_offset_x = view_layout.x * window_scale;
- viewport_offset_y = view_layout.y * window_scale;
- cogl_set_viewport (priv->viewport[0] * window_scale - viewport_offset_x,
- priv->viewport[1] * window_scale - viewport_offset_y,
- priv->viewport[2] * window_scale,
- priv->viewport[3] * window_scale);
+ viewport_offset_x = view_layout.x * fb_scale;
+ viewport_offset_y = view_layout.y * fb_scale;
+ cogl_set_viewport (priv->viewport[0] * fb_scale - viewport_offset_x,
+ priv->viewport[1] * fb_scale - viewport_offset_y,
+ priv->viewport[2] * fb_scale,
+ priv->viewport[3] * fb_scale);
perspective = priv->perspective;
diff --git a/clutter/clutter/cogl/clutter-stage-cogl.c b/clutter/clutter/cogl/clutter-stage-cogl.c
index 2c525af..1d626f6 100644
--- a/clutter/clutter/cogl/clutter-stage-cogl.c
+++ b/clutter/clutter/cogl/clutter-stage-cogl.c
@@ -504,6 +504,7 @@ clutter_stage_cogl_redraw_view (ClutterStageWindow *stage_window,
cairo_rectangle_int_t clip_region;
gboolean clip_region_empty;
int window_scale;
+ int fb_scale;
wrapper = CLUTTER_ACTOR (stage_cogl->wrapper);
@@ -558,6 +559,7 @@ clutter_stage_cogl_redraw_view (ClutterStageWindow *stage_window,
clip_region_empty = may_use_clipped_redraw && clip_region.width == 0;
window_scale = _clutter_stage_window_get_scale_factor (stage_window);
+ fb_scale = window_scale * clutter_stage_view_get_scale (view);
swap_with_damage = FALSE;
if (has_buffer_age)
@@ -628,13 +630,13 @@ clutter_stage_cogl_redraw_view (ClutterStageWindow *stage_window,
stage_cogl->using_clipped_redraw = TRUE;
- scissor_x = (clip_region.x - view_rect.x) * window_scale;
- scissor_y = (clip_region.y - view_rect.y) * window_scale;
+ scissor_x = (clip_region.x - view_rect.x) * fb_scale;
+ scissor_y = (clip_region.y - view_rect.y) * fb_scale;
cogl_framebuffer_push_scissor_clip (fb,
scissor_x,
scissor_y,
- clip_region.width * window_scale,
- clip_region.height * window_scale);
+ clip_region.width * fb_scale,
+ clip_region.height * fb_scale);
paint_stage (stage_cogl, view, &clip_region);
cogl_framebuffer_pop_clip (fb);
@@ -653,13 +655,13 @@ clutter_stage_cogl_redraw_view (ClutterStageWindow *stage_window,
int scissor_x;
int scissor_y;
- scissor_x = (clip_region.x - view_rect.x) * window_scale;;
- scissor_y = (clip_region.y - view_rect.y) * window_scale;
+ scissor_x = (clip_region.x - view_rect.x) * fb_scale;;
+ scissor_y = (clip_region.y - view_rect.y) * fb_scale;
cogl_framebuffer_push_scissor_clip (fb,
scissor_x,
scissor_y,
- clip_region.width * window_scale,
- clip_region.height * window_scale);
+ clip_region.width * fb_scale,
+ clip_region.height * fb_scale);
paint_stage (stage_cogl, view, &clip_region);
cogl_framebuffer_pop_clip (fb);
}
@@ -724,10 +726,10 @@ clutter_stage_cogl_redraw_view (ClutterStageWindow *stage_window,
else if (use_clipped_redraw)
{
swap_region = (cairo_rectangle_int_t) {
- .x = (clip_region.x - view_rect.x) * window_scale,
- .y = (clip_region.y - view_rect.y) * window_scale,
- .width = clip_region.width * window_scale,
- .height = clip_region.height * window_scale,
+ .x = (clip_region.x - view_rect.x) * fb_scale,
+ .y = (clip_region.y - view_rect.y) * fb_scale,
+ .width = clip_region.width * fb_scale,
+ .height = clip_region.height * fb_scale,
};
g_assert (swap_region.width > 0);
do_swap_buffer = TRUE;
@@ -737,8 +739,8 @@ clutter_stage_cogl_redraw_view (ClutterStageWindow *stage_window,
swap_region = (cairo_rectangle_int_t) {
.x = 0,
.y = 0,
- .width = view_rect.width * window_scale,
- .height = view_rect.height * window_scale,
+ .width = view_rect.width * fb_scale,
+ .height = view_rect.height * fb_scale,
};
do_swap_buffer = TRUE;
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]