diff --git a/gsk/gpu/gskgpunodeprocessor.c b/gsk/gpu/gskgpunodeprocessor.c index 15cbabdbdd..5dc5dd7ab1 100644 --- a/gsk/gpu/gskgpunodeprocessor.c +++ b/gsk/gpu/gskgpunodeprocessor.c @@ -313,8 +313,8 @@ gsk_gpu_node_processor_init_draw (GskGpuNodeProcessor *self, area.x = 0; area.y = 0; - area.width = ceilf (scale->x * viewport->size.width); - area.height = ceilf (scale->y * viewport->size.height); + area.width = ceilf (gsk_scale_get_x (*scale) * viewport->size.width); + area.height = ceilf (gsk_scale_get_y (*scale) * viewport->size.height); image = gsk_gpu_device_create_offscreen_image (gsk_gpu_frame_get_device (frame), FALSE, @@ -534,8 +534,8 @@ gsk_gpu_node_processor_rect_is_integer (GskGpuNodeProcessor *self, cairo_rectangle_int_t *int_rect) { graphene_rect_t transformed_rect; - float scale_x = self->scale.x; - float scale_y = self->scale.y; + float scale_x = gsk_scale_get_x (self->scale); + float scale_y = gsk_scale_get_y (self->scale); switch (gsk_transform_get_category (self->modelview)) { @@ -904,8 +904,8 @@ gsk_gpu_node_processor_blur_op (GskGpuNodeProcessor *self, if (!gsk_rect_intersection (rect, &clip_rect, &intermediate_rect)) return; - width = ceilf (self->scale.x * intermediate_rect.size.width); - height = ceilf (self->scale.y * intermediate_rect.size.height); + width = ceilf (gsk_scale_get_x (self->scale) * intermediate_rect.size.width); + height = ceilf (gsk_scale_get_y (self->scale) * intermediate_rect.size.height); intermediate = gsk_gpu_device_create_offscreen_image (gsk_gpu_frame_get_device (self->frame), FALSE, @@ -1479,8 +1479,7 @@ gsk_gpu_node_processor_add_transform_node (GskGpuNodeProcessor *self, gsk_gpu_clip_scale (&self->clip, &old_clip, scale_x, scale_y); self->offset = GRAPHENE_POINT_INIT ((self->offset.x + dx) / scale_x, (self->offset.y + dy) / scale_y); - self->scale = GSK_SCALE_INIT (fabsf (scale_x) * old_scale.x, - fabsf (scale_y) * old_scale.y); + self->scale = gsk_scale_multiply (old_scale, gsk_scale_init (fabsf (scale_x), fabsf (scale_y))); self->modelview = gsk_transform_scale (self->modelview, scale_x / fabsf (scale_x), scale_y / fabsf (scale_y)); @@ -1541,23 +1540,23 @@ gsk_gpu_node_processor_add_transform_node (GskGpuNodeProcessor *self, old_modelview = gsk_transform_ref (self->modelview); self->modelview = gsk_transform_scale (self->modelview, - self->scale.x, self->scale.y); + gsk_scale_get_x (self->scale), + gsk_scale_get_y (self->scale)); self->modelview = gsk_transform_transform (self->modelview, clip_transform); gsk_transform_unref (clip_transform); - gsk_scale_extract_from_transform (self->modelview, &scale); + scale = gsk_scale_extract_from_transform (self->modelview); - old_pixels = old_scale.x * old_scale.y * + old_pixels = gsk_scale_get_x (old_scale) * gsk_scale_get_y (old_scale) * old_clip.rect.bounds.size.width * old_clip.rect.bounds.size.height; - new_pixels = scale.x * scale.y * self->clip.rect.bounds.size.width * self->clip.rect.bounds.size.height; + new_pixels = gsk_scale_get_x (scale) * gsk_scale_get_y (scale) * + self->clip.rect.bounds.size.width * self->clip.rect.bounds.size.height; if (new_pixels > 2 * old_pixels) - { - float forced_downscale = 2 * old_pixels / new_pixels; - scale.x *= forced_downscale; - scale.y *= forced_downscale; - } + scale = gsk_scale_multiply (scale, gsk_scale_init_uniform (2 * old_pixels / new_pixels)); - self->modelview = gsk_transform_scale (self->modelview, 1 / scale.x, 1 / scale.y); + self->modelview = gsk_transform_scale (self->modelview, + 1 / gsk_scale_get_x (scale), + 1 / gsk_scale_get_y (scale)); self->scale = scale; self->offset = *graphene_point_zero (); } @@ -1630,7 +1629,7 @@ gsk_gpu_node_processor_create_transform_pattern (GskGpuPatternWriter *self, self->bounds.size.width *= inv_sx; self->bounds.size.height *= inv_sy; self->offset = GRAPHENE_POINT_INIT (0, 0); - self->scale = GSK_SCALE_INIT(fabsf (sx) * old_scale.x, fabsf (sy) * old_scale.y); + self->scale = gsk_scale_multiply (gsk_scale_init (fabsf (sx), fabsf (sy)), old_scale); } break; @@ -1714,8 +1713,8 @@ gsk_gpu_node_processor_add_color_node (GskGpuNodeProcessor *self, return; } - scale_x = self->scale.x; - scale_y = self->scale.y; + scale_x = gsk_scale_get_x (self->scale); + scale_y = gsk_scale_get_y (self->scale); clipped = GRAPHENE_RECT_INIT (int_clipped.x / scale_x, int_clipped.y / scale_y, int_clipped.width / scale_x, int_clipped.height / scale_y); shader_clip = gsk_gpu_clip_get_shader_clip (&self->clip, graphene_point_zero(), &clipped); @@ -1842,8 +1841,8 @@ gsk_gpu_node_processor_add_texture_node (GskGpuNodeProcessor *self, } if (gsk_gpu_frame_should_optimize (self->frame, GSK_GPU_OPTIMIZE_MIPMAP) && - (gdk_texture_get_width (texture) > 2 * node->bounds.size.width * self->scale.x || - gdk_texture_get_height (texture) > 2 * node->bounds.size.height * self->scale.y)) + (gdk_texture_get_width (texture) > 2 * node->bounds.size.width * gsk_scale_get_x (self->scale) || + gdk_texture_get_height (texture) > 2 * node->bounds.size.height * gsk_scale_get_y (self->scale))) { guint32 descriptor; @@ -1909,8 +1908,8 @@ gsk_gpu_node_processor_create_texture_pattern (GskGpuPatternWriter *self, } if (gsk_gpu_frame_should_optimize (self->frame, GSK_GPU_OPTIMIZE_MIPMAP) && - (gdk_texture_get_width (texture) > 2 * node->bounds.size.width * self->scale.x || - gdk_texture_get_height (texture) > 2 * node->bounds.size.height * self->scale.y)) + (gdk_texture_get_width (texture) > 2 * node->bounds.size.width * gsk_scale_get_x (self->scale) || + gdk_texture_get_height (texture) > 2 * node->bounds.size.height * gsk_scale_get_y (self->scale))) { image = gsk_gpu_node_processor_ensure_image (self->frame, image, @@ -1958,12 +1957,13 @@ gsk_gpu_node_processor_add_texture_scale_node (GskGpuNodeProcessor *self, { GskGpuImage *offscreen; graphene_rect_t clip_bounds; + GskScale one = gsk_scale_init (1, 1); if (!gsk_gpu_node_processor_clip_node_bounds (self, node, &clip_bounds)) return; clip_bounds = gsk_rect_round_larger (clip_bounds); offscreen = gsk_gpu_render_pass_op_offscreen (self->frame, - &GSK_SCALE_INIT (1, 1), + &one, &clip_bounds, node); descriptor = gsk_gpu_node_processor_add_image (self, offscreen, GSK_GPU_SAMPLER_DEFAULT); @@ -2917,7 +2917,7 @@ gsk_gpu_node_processor_add_glyph_node (GskGpuNodeProcessor *self, font, glyphs[i].glyph, 0, - scale.x, + gsk_scale_get_x (scale), &glyph_bounds, &glyph_offset); @@ -2986,13 +2986,14 @@ gsk_gpu_node_processor_create_glyph_pattern (GskGpuPatternWriter *self, GskGpuImage *image; graphene_rect_t glyph_bounds; graphene_point_t glyph_offset; + graphene_rect_t rect; image = gsk_gpu_device_lookup_glyph_image (device, self->frame, font, glyphs[i].glyph, 0, - scale.x, + gsk_scale_get_x (scale), &glyph_bounds, &glyph_offset); @@ -3009,22 +3010,15 @@ gsk_gpu_node_processor_create_glyph_pattern (GskGpuPatternWriter *self, glyphs[i].geometry.y_offset / (float)PANGO_SCALE)); gsk_gpu_pattern_writer_append_uint (self, tex_id); - gsk_gpu_pattern_writer_append_rect (self, - &GRAPHENE_RECT_INIT ( - 0, - 0, - glyph_bounds.size.width * inv.x, - glyph_bounds.size.height * inv.y - ), - &glyph_offset); - gsk_gpu_pattern_writer_append_rect (self, - &GRAPHENE_RECT_INIT ( - - glyph_bounds.origin.x * inv.x, - - glyph_bounds.origin.y * inv.y, - gsk_gpu_image_get_width (image) * inv.x, - gsk_gpu_image_get_height (image) * inv.y - ), - &glyph_offset); + rect = gsk_rect_scale (GRAPHENE_RECT_INIT (0, 0, glyph_bounds.size.width, glyph_bounds.size.height), + inv); + gsk_gpu_pattern_writer_append_rect (self, &rect, &glyph_offset); + rect = gsk_rect_scale (GRAPHENE_RECT_INIT (- glyph_bounds.origin.x, + - glyph_bounds.origin.y, + gsk_gpu_image_get_width (image), + gsk_gpu_image_get_height (image)), + inv); + gsk_gpu_pattern_writer_append_rect (self, &rect, &glyph_offset); offset.x += (float) glyphs[i].geometry.width / PANGO_SCALE; } diff --git a/gsk/gpu/gskgpurenderpassop.c b/gsk/gpu/gskgpurenderpassop.c index 4c5667e8c5..fb9c974ff7 100644 --- a/gsk/gpu/gskgpurenderpassop.c +++ b/gsk/gpu/gskgpurenderpassop.c @@ -343,8 +343,8 @@ gsk_gpu_render_pass_op_offscreen (GskGpuFrame *frame, GskGpuImage *image; int width, height; - width = ceil (scale->x * viewport->size.width); - height = ceil (scale->y * viewport->size.height); + width = ceil (gsk_scale_get_x (*scale) * viewport->size.width); + height = ceil (gsk_scale_get_y (*scale) * viewport->size.height); image = gsk_gpu_device_create_offscreen_image (gsk_gpu_frame_get_device (frame), FALSE, diff --git a/gsk/gpu/gskgpuuploadop.c b/gsk/gpu/gskgpuuploadop.c index 7cd75946bc..56e804bd11 100644 --- a/gsk/gpu/gskgpuuploadop.c +++ b/gsk/gpu/gskgpuuploadop.c @@ -465,8 +465,8 @@ gsk_gpu_upload_cairo_op (GskGpuFrame *frame, self->image = gsk_gpu_device_create_upload_image (gsk_gpu_frame_get_device (frame), FALSE, GDK_MEMORY_DEFAULT, - ceil (scale->x * viewport->size.width), - ceil (scale->y * viewport->size.height)); + ceil (gsk_scale_get_x (*scale) * viewport->size.width), + ceil (gsk_scale_get_y (*scale) * viewport->size.height)); self->viewport = *viewport; self->func = func; self->user_data = user_data; diff --git a/gsk/gskrectprivate.h b/gsk/gskrectprivate.h index 297a1902f7..7ab98fe170 100644 --- a/gsk/gskrectprivate.h +++ b/gsk/gskrectprivate.h @@ -145,17 +145,20 @@ static inline graphene_rect_t gsk_rect_scale (const graphene_rect_t r, const GskScale scale) { - if (G_UNLIKELY (scale.x < 0 || scale.y < 0)) + float sx = gsk_scale_get_x (scale); + float sy = gsk_scale_get_y (scale); + + if (G_UNLIKELY (sx < 0 || sy < 0)) { graphene_rect_t res; - graphene_rect_scale (&r, scale.x, scale.y, &res); + graphene_rect_scale (&r, sx, sy, &res); return res; } - return GRAPHENE_RECT_INIT (r.origin.x * scale.x, - r.origin.y * scale.y, - r.size.width * scale.x, - r.size.height * scale.y); + return GRAPHENE_RECT_INIT (r.origin.x * sx, + r.origin.y * sy, + r.size.width * sx, + r.size.height * sy); } static inline graphene_rect_t diff --git a/gsk/gskscale.c b/gsk/gskscale.c index 990c2acc8b..a6946e36b1 100644 --- a/gsk/gskscale.c +++ b/gsk/gskscale.c @@ -2,9 +2,8 @@ #include "gskscaleprivate.h" #include "gsktransform.h" -void -gsk_scale_extract_from_transform (GskTransform *transform, - GskScale *scale) +GskScale +gsk_scale_extract_from_transform (GskTransform *transform) { switch (gsk_transform_get_category (transform)) { @@ -14,16 +13,14 @@ gsk_scale_extract_from_transform (GskTransform *transform, case GSK_TRANSFORM_CATEGORY_IDENTITY: case GSK_TRANSFORM_CATEGORY_2D_TRANSLATE: - *scale = gsk_scale_init (1, 1); - return; + return gsk_scale_init (1, 1); case GSK_TRANSFORM_CATEGORY_2D_AFFINE: { float scale_x, scale_y, dx, dy; gsk_transform_to_affine (transform, &scale_x, &scale_y, &dx, &dy); - *scale = gsk_scale_init (fabsf (scale_x), fabsf (scale_y)); + return gsk_scale_init (fabsf (scale_x), fabsf (scale_y)); } - return; case GSK_TRANSFORM_CATEGORY_2D: { @@ -33,9 +30,8 @@ gsk_scale_extract_from_transform (GskTransform *transform, &scale_x, &scale_y, &angle, &dx, &dy); - *scale = gsk_scale_init (fabsf (scale_x), fabsf (scale_y)); + return gsk_scale_init (fabsf (scale_x), fabsf (scale_y)); } - return; case GSK_TRANSFORM_CATEGORY_UNKNOWN: case GSK_TRANSFORM_CATEGORY_ANY: @@ -56,10 +52,9 @@ gsk_scale_extract_from_transform (GskTransform *transform, &shear, &perspective); - *scale = gsk_scale_init (fabsf (graphene_vec3_get_x (&matrix_scale)), - fabsf (graphene_vec3_get_y (&matrix_scale))); + return gsk_scale_init (fabsf (graphene_vec3_get_x (&matrix_scale)), + fabsf (graphene_vec3_get_y (&matrix_scale))); } - return; } } diff --git a/gsk/gskscaleprivate.h b/gsk/gskscaleprivate.h index 6236ff25ac..4c59c8130c 100644 --- a/gsk/gskscaleprivate.h +++ b/gsk/gskscaleprivate.h @@ -6,17 +6,30 @@ struct _GskScale { - float x; - float y; + GRAPHENE_ALIGNED_DECL (graphene_simd4f_t v, 16); }; -#define GSK_SCALE_INIT(x,y) (GskScale) { (x), (y) } +static inline float +gsk_scale_get_x (const GskScale scale) +{ + return graphene_simd4f_get_x (scale.v); +} + +static inline float +gsk_scale_get_y (const GskScale scale) +{ + return graphene_simd4f_get_y (scale.v); +} static inline GskScale -gsk_scale_init (float x, - float y) +gsk_scale_init (float x, + float y) { - return (GskScale) { x, y }; + GskScale scale; + + scale.v = graphene_simd4f_init (x, y, 0.f, 0.f); + + return scale; } static inline GskScale @@ -29,48 +42,69 @@ static inline void gsk_scale_to_float (const GskScale *scale, float values[2]) { - values[0] = scale->x; - values[1] = scale->y; + graphene_simd4f_dup_2f (scale->v, values); } static inline gboolean gsk_scale_is_one (const GskScale scale) { - return scale.x == 1 && scale.y == 1; + const graphene_vec2_t *one = graphene_vec2_one (); + + return (gboolean) graphene_simd4f_cmp_eq (scale.v, one->__graphene_private_value); } static inline gboolean gsk_scale_is_uniform (const GskScale scale) { - return scale.x == scale.y; + return gsk_scale_get_x (scale) == gsk_scale_get_y (scale); } static inline GskScale gsk_scale_invert (const GskScale scale) { - return (GskScale) { 1 / scale.x, 1 / scale.y }; + GskScale inv; + + inv.v = graphene_simd4f_reciprocal (scale.v); + + return inv; } static inline GskScale gsk_scale_multiply (const GskScale scale1, const GskScale scale2) { - return (GskScale) { scale1.x * scale2.x, scale1.y * scale2.y }; + GskScale scale; + + scale.v = graphene_simd4f_mul (scale1.v, scale2.v); + + return scale; } static inline GskScale gsk_scale_divide (const GskScale scale1, const GskScale scale2) { - return (GskScale) { scale1.x / scale2.x, scale1.y / scale2.y }; + GskScale scale; + + scale.v = graphene_simd4f_div (scale1.v, scale2.v); + + return scale; } +# define graphene_simd4f_shuffle_yxzw(v) \ + (__extension__ ({ \ + (graphene_simd4f_t) _mm_shuffle_ps ((v), (v), _MM_SHUFFLE (1, 0, 2, 3)); \ + })) + + static inline GskScale gsk_scale_max (const GskScale scale) { - float s = MAX (scale.x, scale.y); + GskScale m; - return (GskScale) { s, s }; + m.v = graphene_simd4f_max (graphene_simd4f_shuffle_yxzw (scale.v), scale.v); + + return m; } static inline graphene_point_t @@ -96,14 +130,14 @@ static inline graphene_point_t gsk_point_multiply (const graphene_point_t point, const GskScale scale) { - return (graphene_point_t) { point.x * scale.x, point.y * scale.y }; + return (graphene_point_t) { point.x * gsk_scale_get_x (scale), point.y * gsk_scale_get_y (scale) }; } static inline graphene_point_t gsk_point_divide (const graphene_point_t point, const GskScale scale) { - return (graphene_point_t) { point.x / scale.x, point.y / scale.y }; + return (graphene_point_t) { point.x / gsk_scale_get_x (scale), point.y / gsk_scale_get_y (scale) }; } static inline graphene_point_t @@ -131,6 +165,5 @@ gsk_point_ceil (const graphene_point_t point) { return (graphene_point_t) { ceilf (point.x), ceilf (point.y) }; } -void -gsk_scale_extract_from_transform (GskTransform *transform, - GskScale *scale); + +GskScale gsk_scale_extract_from_transform (GskTransform *transform);