Compare commits
15 Commits
gpu-drop-v
...
front-cach
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c5988a22a4 | ||
|
|
498bf67cec | ||
|
|
65455cdb91 | ||
|
|
d4963ba2e5 | ||
|
|
ec5fed6cc4 | ||
|
|
b7ae5404a3 | ||
|
|
fb4f210430 | ||
|
|
82df109444 | ||
|
|
bd84142f43 | ||
|
|
65074bbbac | ||
|
|
21fb5ec0b2 | ||
|
|
e57f92b7e9 | ||
|
|
e94e348ad5 | ||
|
|
91234e75f8 | ||
|
|
212e9a6957 |
@@ -830,8 +830,8 @@ rounded_rect_scale_corners (const GskRoundedRect *rect,
|
||||
{
|
||||
for (guint i = 0; i < G_N_ELEMENTS (out_rect->corner); i++)
|
||||
{
|
||||
out_rect->corner[i].width = rect->corner[i].width * fabsf (scale_x);
|
||||
out_rect->corner[i].height = rect->corner[i].height * fabsf (scale_y);
|
||||
out_rect->corner[i].width = rect->corner[i].width * fabs (scale_x);
|
||||
out_rect->corner[i].height = rect->corner[i].height * fabs (scale_y);
|
||||
}
|
||||
|
||||
if (scale_x < 0)
|
||||
@@ -1173,8 +1173,8 @@ gsk_gl_render_job_visit_as_fallback (GskGLRenderJob *job,
|
||||
{
|
||||
float scale_x = job->scale_x;
|
||||
float scale_y = job->scale_y;
|
||||
int surface_width = ceilf (node->bounds.size.width * fabsf (scale_x));
|
||||
int surface_height = ceilf (node->bounds.size.height * fabsf (scale_y));
|
||||
int surface_width = ceilf (node->bounds.size.width * fabs (scale_x));
|
||||
int surface_height = ceilf (node->bounds.size.height * fabs (scale_y));
|
||||
GdkTexture *texture;
|
||||
cairo_surface_t *surface;
|
||||
cairo_surface_t *rendered_surface;
|
||||
@@ -1203,7 +1203,7 @@ gsk_gl_render_job_visit_as_fallback (GskGLRenderJob *job,
|
||||
surface_width,
|
||||
surface_height);
|
||||
|
||||
cairo_surface_set_device_scale (rendered_surface, fabsf (scale_x), fabsf (scale_y));
|
||||
cairo_surface_set_device_scale (rendered_surface, fabs (scale_x), fabs (scale_y));
|
||||
cr = cairo_create (rendered_surface);
|
||||
|
||||
cairo_save (cr);
|
||||
@@ -1217,16 +1217,16 @@ gsk_gl_render_job_visit_as_fallback (GskGLRenderJob *job,
|
||||
surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32,
|
||||
surface_width,
|
||||
surface_height);
|
||||
cairo_surface_set_device_scale (surface, fabsf (scale_x), fabsf (scale_y));
|
||||
cairo_surface_set_device_scale (surface, fabs (scale_x), fabs (scale_y));
|
||||
cr = cairo_create (surface);
|
||||
|
||||
/* We draw upside down here, so it matches what GL does. */
|
||||
cairo_save (cr);
|
||||
cairo_scale (cr, scale_x < 0 ? -1 : 1, scale_y < 0 ? 1 : -1);
|
||||
cairo_translate (cr, scale_x < 0 ? - surface_width / fabsf (scale_x) : 0,
|
||||
scale_y < 0 ? 0 : - surface_height / fabsf (scale_y));
|
||||
cairo_translate (cr, scale_x < 0 ? - surface_width / fabs (scale_x) : 0,
|
||||
scale_y < 0 ? 0 : - surface_height / fabs (scale_y));
|
||||
cairo_set_source_surface (cr, rendered_surface, 0, 0);
|
||||
cairo_rectangle (cr, 0, 0, surface_width / fabsf (scale_x), surface_height / fabsf (scale_y));
|
||||
cairo_rectangle (cr, 0, 0, surface_width / fabs (scale_x), surface_height / fabs (scale_y));
|
||||
cairo_fill (cr);
|
||||
cairo_restore (cr);
|
||||
cairo_destroy (cr);
|
||||
@@ -1432,10 +1432,10 @@ blur_node (GskGLRenderJob *job,
|
||||
|
||||
offscreen->texture_id = blur_offscreen (job,
|
||||
offscreen,
|
||||
texture_width * fabsf (scale_x),
|
||||
texture_height * fabsf (scale_y),
|
||||
blur_radius * fabsf (scale_x),
|
||||
blur_radius * fabsf (scale_y));
|
||||
texture_width * fabs (scale_x),
|
||||
texture_height * fabs (scale_y),
|
||||
blur_radius * fabs (scale_x),
|
||||
blur_radius * fabs (scale_y));
|
||||
init_full_texture_region (offscreen);
|
||||
}
|
||||
|
||||
@@ -2019,9 +2019,9 @@ result_is_axis_aligned (GskTransform *transform,
|
||||
for (guint i = 0; i < 4; i++)
|
||||
{
|
||||
p = graphene_quad_get_point (&q, i);
|
||||
if (fabsf (p->x - b1.x) > FLT_EPSILON && fabsf (p->x - b2.x) > FLT_EPSILON)
|
||||
if (fabs (p->x - b1.x) > FLT_EPSILON && fabs (p->x - b2.x) > FLT_EPSILON)
|
||||
return FALSE;
|
||||
if (fabsf (p->y - b1.y) > FLT_EPSILON && fabsf (p->y - b2.y) > FLT_EPSILON)
|
||||
if (fabs (p->y - b1.y) > FLT_EPSILON && fabs (p->y - b2.y) > FLT_EPSILON)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
@@ -2304,8 +2304,8 @@ gsk_gl_render_job_visit_blurred_inset_shadow_node (GskGLRenderJob *job,
|
||||
&offscreen,
|
||||
texture_width,
|
||||
texture_height,
|
||||
blur_radius * fabsf (scale_x),
|
||||
blur_radius * fabsf (scale_y));
|
||||
blur_radius * fabs (scale_x),
|
||||
blur_radius * fabs (scale_y));
|
||||
|
||||
gsk_gl_driver_release_render_target (job->driver, render_target, TRUE);
|
||||
|
||||
@@ -2501,8 +2501,8 @@ gsk_gl_render_job_visit_blurred_outset_shadow_node (GskGLRenderJob *job,
|
||||
do_slicing = TRUE;
|
||||
}
|
||||
|
||||
texture_width = (int)ceilf ((scaled_outline.bounds.size.width + blur_extra) * scale_x);
|
||||
texture_height = (int)ceilf ((scaled_outline.bounds.size.height + blur_extra) * scale_y);
|
||||
texture_width = (int)ceil ((scaled_outline.bounds.size.width + blur_extra) * scale_x);
|
||||
texture_height = (int)ceil ((scaled_outline.bounds.size.height + blur_extra) * scale_y);
|
||||
|
||||
scaled_outline.bounds.origin.x = extra_blur_pixels_x;
|
||||
scaled_outline.bounds.origin.y = extra_blur_pixels_y;
|
||||
@@ -2577,8 +2577,8 @@ gsk_gl_render_job_visit_blurred_outset_shadow_node (GskGLRenderJob *job,
|
||||
&offscreen,
|
||||
texture_width,
|
||||
texture_height,
|
||||
blur_radius * fabsf (scale_x),
|
||||
blur_radius * fabsf (scale_y));
|
||||
blur_radius * fabs (scale_x),
|
||||
blur_radius * fabs (scale_y));
|
||||
|
||||
gsk_gl_shadow_library_insert (job->driver->shadows_library,
|
||||
&scaled_outline,
|
||||
@@ -2834,7 +2834,7 @@ gsk_gl_render_job_visit_cross_fade_node (GskGLRenderJob *job,
|
||||
offscreen_end.reset_clip = TRUE;
|
||||
offscreen_end.bounds = &node->bounds;
|
||||
|
||||
gsk_gl_render_job_set_modelview (job, gsk_transform_scale (NULL, fabsf (job->scale_x), fabsf (job->scale_y)));
|
||||
gsk_gl_render_job_set_modelview (job, gsk_transform_scale (NULL, fabs (job->scale_x), fabs (job->scale_y)));
|
||||
|
||||
if (!gsk_gl_render_job_visit_node_with_offscreen (job, start_node, &offscreen_start))
|
||||
{
|
||||
@@ -2964,7 +2964,7 @@ gsk_gl_render_job_visit_text_node (GskGLRenderJob *job,
|
||||
const PangoFont *font = gsk_text_node_get_font (node);
|
||||
const PangoGlyphInfo *glyphs = gsk_text_node_get_glyphs (node, NULL);
|
||||
const graphene_point_t *offset = gsk_text_node_get_offset (node);
|
||||
float text_scale = MAX (fabsf (job->scale_x), fabsf (job->scale_y)); /* TODO: Fix for uneven scales? */
|
||||
float text_scale = MAX (fabs (job->scale_x), fabs (job->scale_y)); /* TODO: Fix for uneven scales? */
|
||||
guint num_glyphs = gsk_text_node_get_num_glyphs (node);
|
||||
float x = offset->x + job->offset_x;
|
||||
float y = offset->y + job->offset_y;
|
||||
@@ -3263,7 +3263,7 @@ gsk_gl_render_job_visit_blend_node (GskGLRenderJob *job,
|
||||
bottom_offscreen.force_offscreen = TRUE;
|
||||
bottom_offscreen.reset_clip = TRUE;
|
||||
|
||||
gsk_gl_render_job_set_modelview (job, gsk_transform_scale (NULL, fabsf (job->scale_x), fabsf (job->scale_y)));
|
||||
gsk_gl_render_job_set_modelview (job, gsk_transform_scale (NULL, fabs (job->scale_x), fabs (job->scale_y)));
|
||||
|
||||
/* TODO: We create 2 textures here as big as the blend node, but both the
|
||||
* start and the end node might be a lot smaller than that. */
|
||||
@@ -3344,8 +3344,8 @@ gsk_gl_render_job_texture_mask_for_color (GskGLRenderJob *job,
|
||||
gboolean use_mipmap;
|
||||
guint16 cc[4];
|
||||
|
||||
use_mipmap = (scale_x * fabsf (job->scale_x)) < 0.5 ||
|
||||
(scale_y * fabsf (job->scale_y)) < 0.5;
|
||||
use_mipmap = (scale_x * fabs (job->scale_x)) < 0.5 ||
|
||||
(scale_y * fabs (job->scale_y)) < 0.5;
|
||||
|
||||
rgba_to_half (rgba, cc);
|
||||
gsk_gl_render_job_upload_texture (job, texture, use_mipmap, &offscreen);
|
||||
@@ -3396,7 +3396,7 @@ gsk_gl_render_job_visit_mask_node (GskGLRenderJob *job,
|
||||
mask_offscreen.reset_clip = TRUE;
|
||||
mask_offscreen.do_not_cache = TRUE;
|
||||
|
||||
gsk_gl_render_job_set_modelview (job, gsk_transform_scale (NULL, fabsf (job->scale_x), fabsf (job->scale_y)));
|
||||
gsk_gl_render_job_set_modelview (job, gsk_transform_scale (NULL, fabs (job->scale_x), fabs (job->scale_y)));
|
||||
|
||||
/* TODO: We create 2 textures here as big as the mask node, but both
|
||||
* nodes might be a lot smaller than that.
|
||||
@@ -3664,8 +3664,8 @@ gsk_gl_render_job_visit_texture (GskGLRenderJob *job,
|
||||
float scale_y = bounds->size.height / texture->height;
|
||||
gboolean use_mipmap;
|
||||
|
||||
use_mipmap = (scale_x * fabsf (job->scale_x)) < 0.5 ||
|
||||
(scale_y * fabsf (job->scale_y)) < 0.5;
|
||||
use_mipmap = (scale_x * fabs (job->scale_x)) < 0.5 ||
|
||||
(scale_y * fabs (job->scale_y)) < 0.5;
|
||||
|
||||
if G_LIKELY (texture->width <= max_texture_size &&
|
||||
texture->height <= max_texture_size)
|
||||
|
||||
@@ -117,8 +117,9 @@ gsk_gl_texture_library_real_compact (GskGLTextureLibrary *self,
|
||||
g_hash_table_iter_remove (&iter);
|
||||
dropped++;
|
||||
}
|
||||
else if (periodic_scan)
|
||||
entry->accessed = FALSE;
|
||||
|
||||
if (periodic_scan)
|
||||
entry->accessed = FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -439,6 +440,7 @@ gsk_gl_texture_library_pack (GskGLTextureLibrary *self,
|
||||
|
||||
entry->texture = texture;
|
||||
entry->is_atlased = FALSE;
|
||||
entry->accessed = TRUE;
|
||||
entry->area.x = padding / (float) (padding + width + padding);
|
||||
entry->area.y = padding / (float) (padding + height + padding);
|
||||
entry->area.x2 = (padding + width) / (float) (padding + width + padding);
|
||||
|
||||
@@ -60,7 +60,7 @@ gsk_gpu_blend_mode_op (GskGpuFrame *frame,
|
||||
GskGpuShaderClip clip,
|
||||
GskGpuDescriptors *desc,
|
||||
const graphene_rect_t *rect,
|
||||
const GskPoint *offset,
|
||||
const graphene_point_t *offset,
|
||||
float opacity,
|
||||
GskBlendMode blend_mode,
|
||||
guint32 bottom_descriptor,
|
||||
|
||||
@@ -10,7 +10,7 @@ void gsk_gpu_blend_mode_op (GskGpuF
|
||||
GskGpuShaderClip clip,
|
||||
GskGpuDescriptors *desc,
|
||||
const graphene_rect_t *rect,
|
||||
const GskPoint *offset,
|
||||
const graphene_point_t *offset,
|
||||
float opacity,
|
||||
GskBlendMode blend_mode,
|
||||
guint32 start_descriptor,
|
||||
|
||||
@@ -63,9 +63,9 @@ gsk_gpu_blur_op_full (GskGpuFrame *frame,
|
||||
GskGpuDescriptors *desc,
|
||||
guint32 descriptor,
|
||||
const graphene_rect_t *rect,
|
||||
const GskPoint *offset,
|
||||
const graphene_point_t *offset,
|
||||
const graphene_rect_t *tex_rect,
|
||||
const graphene_point_t *blur_direction,
|
||||
const graphene_vec2_t *blur_direction,
|
||||
const GdkRGBA *blur_color)
|
||||
{
|
||||
GskGpuBlurInstance *instance;
|
||||
@@ -79,8 +79,7 @@ gsk_gpu_blur_op_full (GskGpuFrame *frame,
|
||||
|
||||
gsk_gpu_rect_to_float (rect, offset, instance->rect);
|
||||
gsk_gpu_rect_to_float (tex_rect, offset, instance->tex_rect);
|
||||
instance->blur_direction[0] = blur_direction->x;
|
||||
instance->blur_direction[1] = blur_direction->y;
|
||||
graphene_vec2_to_float (blur_direction, instance->blur_direction);
|
||||
gsk_gpu_rgba_to_float (blur_color, instance->blur_color);
|
||||
instance->tex_id = descriptor;
|
||||
}
|
||||
@@ -91,9 +90,9 @@ gsk_gpu_blur_op (GskGpuFrame *frame,
|
||||
GskGpuDescriptors *desc,
|
||||
guint32 descriptor,
|
||||
const graphene_rect_t *rect,
|
||||
const GskPoint *offset,
|
||||
const graphene_point_t *offset,
|
||||
const graphene_rect_t *tex_rect,
|
||||
const graphene_point_t *blur_direction)
|
||||
const graphene_vec2_t *blur_direction)
|
||||
{
|
||||
gsk_gpu_blur_op_full (frame,
|
||||
0,
|
||||
@@ -113,9 +112,9 @@ gsk_gpu_blur_shadow_op (GskGpuFrame *frame,
|
||||
GskGpuDescriptors *desc,
|
||||
guint32 descriptor,
|
||||
const graphene_rect_t *rect,
|
||||
const GskPoint *offset,
|
||||
const graphene_point_t *offset,
|
||||
const graphene_rect_t *tex_rect,
|
||||
const graphene_point_t *blur_direction,
|
||||
const graphene_vec2_t *blur_direction,
|
||||
const GdkRGBA *shadow_color)
|
||||
{
|
||||
gsk_gpu_blur_op_full (frame,
|
||||
|
||||
@@ -11,18 +11,18 @@ void gsk_gpu_blur_op (GskGpuF
|
||||
GskGpuDescriptors *desc,
|
||||
guint32 descriptor,
|
||||
const graphene_rect_t *rect,
|
||||
const GskPoint *offset,
|
||||
const graphene_point_t *offset,
|
||||
const graphene_rect_t *tex_rect,
|
||||
const graphene_point_t *blur_direction);
|
||||
const graphene_vec2_t *blur_direction);
|
||||
|
||||
void gsk_gpu_blur_shadow_op (GskGpuFrame *frame,
|
||||
GskGpuShaderClip clip,
|
||||
GskGpuDescriptors *desc,
|
||||
guint32 descriptor,
|
||||
const graphene_rect_t *rect,
|
||||
const GskPoint *offset,
|
||||
const graphene_point_t *offset,
|
||||
const graphene_rect_t *tex_rect,
|
||||
const graphene_point_t *blur_direction,
|
||||
const graphene_vec2_t *blur_direction,
|
||||
const GdkRGBA *shadow_color);
|
||||
|
||||
|
||||
|
||||
@@ -103,7 +103,7 @@ void
|
||||
gsk_gpu_border_op (GskGpuFrame *frame,
|
||||
GskGpuShaderClip clip,
|
||||
const GskRoundedRect *outline,
|
||||
const GskPoint *offset,
|
||||
const graphene_point_t *offset,
|
||||
const graphene_point_t *inside_offset,
|
||||
const float widths[4],
|
||||
const GdkRGBA colors[4])
|
||||
@@ -118,7 +118,7 @@ gsk_gpu_border_op (GskGpuFrame *frame,
|
||||
NULL,
|
||||
&instance);
|
||||
|
||||
gsk_gpu_rounded_rect_to_float (outline, offset, instance->outline);
|
||||
gsk_rounded_rect_to_float (outline, offset, instance->outline);
|
||||
|
||||
for (i = 0; i < 4; i++)
|
||||
{
|
||||
|
||||
@@ -10,7 +10,7 @@ G_BEGIN_DECLS
|
||||
void gsk_gpu_border_op (GskGpuFrame *frame,
|
||||
GskGpuShaderClip clip,
|
||||
const GskRoundedRect *outline,
|
||||
const GskPoint *offset,
|
||||
const graphene_point_t *offset,
|
||||
const graphene_point_t *inside_offset,
|
||||
const float widths[4],
|
||||
const GdkRGBA colors[4]);
|
||||
|
||||
@@ -86,7 +86,7 @@ gsk_gpu_box_shadow_op (GskGpuFrame *frame,
|
||||
const graphene_point_t *shadow_offset,
|
||||
float spread,
|
||||
float blur_radius,
|
||||
const GskPoint *offset,
|
||||
const graphene_point_t *offset,
|
||||
const GdkRGBA *color)
|
||||
{
|
||||
GskGpuBoxshadowInstance *instance;
|
||||
@@ -102,10 +102,11 @@ gsk_gpu_box_shadow_op (GskGpuFrame *frame,
|
||||
&instance);
|
||||
|
||||
gsk_gpu_rect_to_float (bounds, offset, instance->bounds);
|
||||
gsk_gpu_rounded_rect_to_float (outline, offset, instance->outline);
|
||||
gsk_rounded_rect_to_float (outline, offset, instance->outline);
|
||||
gsk_gpu_rgba_to_float (color, instance->color);
|
||||
instance->shadow_offset[0] = shadow_offset->x;
|
||||
instance->shadow_offset[1] = shadow_offset->y;
|
||||
instance->shadow_spread = spread;
|
||||
instance->blur_radius = blur_radius;
|
||||
}
|
||||
|
||||
|
||||
@@ -15,7 +15,7 @@ void gsk_gpu_box_shadow_op (
|
||||
const graphene_point_t *shadow_offset,
|
||||
float spread,
|
||||
float blur_radius,
|
||||
const GskPoint *offset,
|
||||
const graphene_point_t *offset,
|
||||
const GdkRGBA *color);
|
||||
|
||||
|
||||
|
||||
@@ -238,10 +238,12 @@ gsk_gpu_clip_transform (GskGpuClip *dest,
|
||||
|
||||
gboolean
|
||||
gsk_gpu_clip_may_intersect_rect (const GskGpuClip *self,
|
||||
const GskPoint *offset,
|
||||
const graphene_point_t *offset,
|
||||
const graphene_rect_t *rect)
|
||||
{
|
||||
graphene_rect_t r = gsk_rect_add_offset (*rect, *offset);
|
||||
graphene_rect_t r = *rect;
|
||||
r.origin.x += offset->x;
|
||||
r.origin.y += offset->y;
|
||||
|
||||
switch (self->type)
|
||||
{
|
||||
@@ -260,10 +262,12 @@ gsk_gpu_clip_may_intersect_rect (const GskGpuClip *self,
|
||||
|
||||
gboolean
|
||||
gsk_gpu_clip_contains_rect (const GskGpuClip *self,
|
||||
const GskPoint *offset,
|
||||
const graphene_point_t *offset,
|
||||
const graphene_rect_t *rect)
|
||||
{
|
||||
graphene_rect_t r = gsk_rect_add_offset (*rect, *offset);
|
||||
graphene_rect_t r = *rect;
|
||||
r.origin.x += offset->x;
|
||||
r.origin.y += offset->y;
|
||||
|
||||
switch (self->type)
|
||||
{
|
||||
@@ -284,7 +288,7 @@ gsk_gpu_clip_contains_rect (const GskGpuClip *self,
|
||||
|
||||
GskGpuShaderClip
|
||||
gsk_gpu_clip_get_shader_clip (const GskGpuClip *self,
|
||||
const GskPoint *offset,
|
||||
const graphene_point_t *offset,
|
||||
const graphene_rect_t *rect)
|
||||
{
|
||||
if (self->type == GSK_GPU_CLIP_NONE ||
|
||||
|
||||
@@ -59,15 +59,15 @@ gboolean gsk_gpu_clip_transform (GskGpuC
|
||||
GskTransform *transform,
|
||||
const graphene_rect_t *viewport) G_GNUC_WARN_UNUSED_RESULT;
|
||||
|
||||
gboolean gsk_gpu_clip_contains_rect (const GskGpuClip *self,
|
||||
const GskPoint *offset,
|
||||
gboolean gsk_gpu_clip_contains_rect (const GskGpuClip *self,
|
||||
const graphene_point_t *offset,
|
||||
const graphene_rect_t *rect) G_GNUC_WARN_UNUSED_RESULT;
|
||||
gboolean gsk_gpu_clip_may_intersect_rect (const GskGpuClip *self,
|
||||
const GskPoint *offset,
|
||||
const graphene_rect_t *rect) G_GNUC_WARN_UNUSED_RESULT;
|
||||
GskGpuShaderClip gsk_gpu_clip_get_shader_clip (const GskGpuClip *self,
|
||||
const GskPoint *offset,
|
||||
const graphene_rect_t *rect);
|
||||
gboolean gsk_gpu_clip_may_intersect_rect (const GskGpuClip *self,
|
||||
const graphene_point_t *offset,
|
||||
const graphene_rect_t *rect) G_GNUC_WARN_UNUSED_RESULT;
|
||||
GskGpuShaderClip gsk_gpu_clip_get_shader_clip (const GskGpuClip *self,
|
||||
const graphene_point_t *offset,
|
||||
const graphene_rect_t *rect);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
|
||||
@@ -59,7 +59,7 @@ gsk_gpu_colorize_op (GskGpuFrame *frame,
|
||||
GskGpuDescriptors *descriptors,
|
||||
guint32 descriptor,
|
||||
const graphene_rect_t *rect,
|
||||
const GskPoint *offset,
|
||||
const graphene_point_t *offset,
|
||||
const graphene_rect_t *tex_rect,
|
||||
const GdkRGBA *color)
|
||||
{
|
||||
|
||||
@@ -11,7 +11,7 @@ void gsk_gpu_colorize_op (GskGpuF
|
||||
GskGpuDescriptors *desc,
|
||||
guint32 descriptor,
|
||||
const graphene_rect_t *rect,
|
||||
const GskPoint *offset,
|
||||
const graphene_point_t *offset,
|
||||
const graphene_rect_t *tex_rect,
|
||||
const GdkRGBA *color);
|
||||
|
||||
|
||||
@@ -58,7 +58,7 @@ gsk_gpu_color_matrix_op (GskGpuFrame *frame,
|
||||
GskGpuDescriptors *desc,
|
||||
guint32 descriptor,
|
||||
const graphene_rect_t *rect,
|
||||
const GskPoint *offset,
|
||||
const graphene_point_t *offset,
|
||||
const graphene_rect_t *tex_rect,
|
||||
const graphene_matrix_t *color_matrix,
|
||||
const graphene_vec4_t *color_offset)
|
||||
@@ -85,7 +85,7 @@ gsk_gpu_color_matrix_op_opacity (GskGpuFrame *frame,
|
||||
GskGpuDescriptors *desc,
|
||||
guint32 descriptor,
|
||||
const graphene_rect_t *rect,
|
||||
const GskPoint *offset,
|
||||
const graphene_point_t *offset,
|
||||
const graphene_rect_t *tex_rect,
|
||||
float opacity)
|
||||
{
|
||||
|
||||
@@ -11,7 +11,7 @@ void gsk_gpu_color_matrix_op (GskGpuF
|
||||
GskGpuDescriptors *desc,
|
||||
guint32 descriptor,
|
||||
const graphene_rect_t *rect,
|
||||
const GskPoint *offset,
|
||||
const graphene_point_t *offset,
|
||||
const graphene_rect_t *tex_rect,
|
||||
const graphene_matrix_t *color_matrix,
|
||||
const graphene_vec4_t *color_offset);
|
||||
@@ -21,7 +21,7 @@ void gsk_gpu_color_matrix_op_opacity (GskGpuF
|
||||
GskGpuDescriptors *desc,
|
||||
guint32 descriptor,
|
||||
const graphene_rect_t *rect,
|
||||
const GskPoint *offset,
|
||||
const graphene_point_t *offset,
|
||||
const graphene_rect_t *tex_rect,
|
||||
float opacity);
|
||||
|
||||
|
||||
@@ -57,7 +57,7 @@ void
|
||||
gsk_gpu_color_op (GskGpuFrame *frame,
|
||||
GskGpuShaderClip clip,
|
||||
const graphene_rect_t *rect,
|
||||
const GskPoint *offset,
|
||||
const graphene_point_t *offset,
|
||||
const GdkRGBA *color)
|
||||
{
|
||||
GskGpuColorInstance *instance;
|
||||
|
||||
@@ -9,7 +9,7 @@ G_BEGIN_DECLS
|
||||
void gsk_gpu_color_op (GskGpuFrame *frame,
|
||||
GskGpuShaderClip clip,
|
||||
const graphene_rect_t *rect,
|
||||
const GskPoint *offset,
|
||||
const graphene_point_t *offset,
|
||||
const GdkRGBA *color);
|
||||
|
||||
|
||||
|
||||
@@ -59,7 +59,7 @@ gsk_gpu_conic_gradient_op (GskGpuFrame *frame,
|
||||
const graphene_rect_t *rect,
|
||||
const graphene_point_t *center,
|
||||
float angle,
|
||||
const GskPoint *offset,
|
||||
const graphene_point_t *offset,
|
||||
const GskColorStop *stops,
|
||||
gsize n_stops)
|
||||
{
|
||||
|
||||
@@ -13,7 +13,7 @@ void gsk_gpu_conic_gradient_op (GskGpuF
|
||||
const graphene_rect_t *rect,
|
||||
const graphene_point_t *center,
|
||||
float angle,
|
||||
const GskPoint *offset,
|
||||
const graphene_point_t *offset,
|
||||
const GskColorStop *stops,
|
||||
gsize n_stops);
|
||||
|
||||
|
||||
@@ -59,7 +59,7 @@ gsk_gpu_cross_fade_op (GskGpuFrame *frame,
|
||||
GskGpuShaderClip clip,
|
||||
GskGpuDescriptors *desc,
|
||||
const graphene_rect_t *rect,
|
||||
const GskPoint *offset,
|
||||
const graphene_point_t *offset,
|
||||
float opacity,
|
||||
float progress,
|
||||
guint32 start_descriptor,
|
||||
|
||||
@@ -10,7 +10,7 @@ void gsk_gpu_cross_fade_op (GskGpuF
|
||||
GskGpuShaderClip clip,
|
||||
GskGpuDescriptors *desc,
|
||||
const graphene_rect_t *rect,
|
||||
const GskPoint *offset,
|
||||
const graphene_point_t *offset,
|
||||
float opacity,
|
||||
float progress,
|
||||
guint32 start_descriptor,
|
||||
|
||||
@@ -3,17 +3,28 @@
|
||||
#include "gskgpudeviceprivate.h"
|
||||
|
||||
#include "gskgpuframeprivate.h"
|
||||
#include "gskgpuimageprivate.h"
|
||||
#include "gskgpuuploadopprivate.h"
|
||||
|
||||
#include "gdk/gdkdisplayprivate.h"
|
||||
#include "gdk/gdktextureprivate.h"
|
||||
|
||||
#include "gsk/gskdebugprivate.h"
|
||||
|
||||
#define MAX_SLICES_PER_ATLAS 64
|
||||
|
||||
#define ATLAS_SIZE 1024
|
||||
|
||||
#define MAX_ATLAS_ITEM_SIZE 256
|
||||
|
||||
G_STATIC_ASSERT (MAX_ATLAS_ITEM_SIZE < ATLAS_SIZE);
|
||||
|
||||
#define MAX_DEAD_PIXELS (ATLAS_SIZE * ATLAS_SIZE / 2)
|
||||
|
||||
#define CACHE_GC_TIMEOUT 1 /* seconds */
|
||||
|
||||
#define CACHE_MAX_AGE (G_TIME_SPAN_SECOND * 4) /* 4 seconds, in µs */
|
||||
|
||||
typedef struct _GskGpuCached GskGpuCached;
|
||||
typedef struct _GskGpuCachedClass GskGpuCachedClass;
|
||||
typedef struct _GskGpuCachedAtlas GskGpuCachedAtlas;
|
||||
@@ -21,6 +32,15 @@ typedef struct _GskGpuCachedGlyph GskGpuCachedGlyph;
|
||||
typedef struct _GskGpuCachedTexture GskGpuCachedTexture;
|
||||
typedef struct _GskGpuDevicePrivate GskGpuDevicePrivate;
|
||||
|
||||
typedef struct _GlyphKey GlyphKey;
|
||||
struct _GlyphKey
|
||||
{
|
||||
PangoFont *font;
|
||||
PangoGlyph glyph;
|
||||
GskGpuGlyphLookupFlags flags;
|
||||
float scale;
|
||||
};
|
||||
|
||||
struct _GskGpuDevicePrivate
|
||||
{
|
||||
GdkDisplay *display;
|
||||
@@ -34,6 +54,11 @@ struct _GskGpuDevicePrivate
|
||||
GHashTable *glyph_cache;
|
||||
|
||||
GskGpuCachedAtlas *current_atlas;
|
||||
|
||||
struct {
|
||||
GlyphKey key;
|
||||
GskGpuCachedGlyph *value;
|
||||
} front[256];
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE_WITH_PRIVATE (GskGpuDevice, gsk_gpu_device, G_TYPE_OBJECT)
|
||||
@@ -54,12 +79,34 @@ struct _GskGpuCachedClass
|
||||
struct _GskGpuCached
|
||||
{
|
||||
const GskGpuCachedClass *class;
|
||||
|
||||
|
||||
GskGpuCachedAtlas *atlas;
|
||||
GskGpuCached *next;
|
||||
GskGpuCached *prev;
|
||||
|
||||
gint64 timestamp;
|
||||
gboolean stale;
|
||||
guint pixels; /* For glyphs, pixels. For atlases, dead pixels */
|
||||
};
|
||||
|
||||
static inline void
|
||||
mark_as_stale (GskGpuCached *cached,
|
||||
gboolean stale)
|
||||
{
|
||||
if (cached->stale != stale)
|
||||
{
|
||||
cached->stale = stale;
|
||||
|
||||
if (cached->atlas)
|
||||
{
|
||||
if (stale)
|
||||
((GskGpuCached *) cached->atlas)->pixels += cached->pixels;
|
||||
else
|
||||
((GskGpuCached *) cached->atlas)->pixels -= cached->pixels;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gsk_gpu_cached_free (GskGpuDevice *device,
|
||||
GskGpuCached *cached)
|
||||
@@ -75,6 +122,8 @@ gsk_gpu_cached_free (GskGpuDevice *device,
|
||||
else
|
||||
priv->first_cached = cached->next;
|
||||
|
||||
mark_as_stale (cached, TRUE);
|
||||
|
||||
cached->class->free (device, cached);
|
||||
}
|
||||
|
||||
@@ -114,7 +163,8 @@ gsk_gpu_cached_use (GskGpuDevice *device,
|
||||
GskGpuCached *cached,
|
||||
gint64 timestamp)
|
||||
{
|
||||
/* FIXME */
|
||||
cached->timestamp = timestamp;
|
||||
mark_as_stale (cached, FALSE);
|
||||
}
|
||||
|
||||
/* }}} */
|
||||
@@ -137,10 +187,23 @@ static void
|
||||
gsk_gpu_cached_atlas_free (GskGpuDevice *device,
|
||||
GskGpuCached *cached)
|
||||
{
|
||||
GskGpuDevicePrivate *priv = gsk_gpu_device_get_instance_private (device);
|
||||
GskGpuCachedAtlas *self = (GskGpuCachedAtlas *) cached;
|
||||
GskGpuCached *c, *next;
|
||||
|
||||
/* Free all remaining glyphs on this atlas */
|
||||
for (c = priv->first_cached; c != NULL; c = next)
|
||||
{
|
||||
next = c->next;
|
||||
if (c->atlas == self)
|
||||
gsk_gpu_cached_free (device, c);
|
||||
}
|
||||
|
||||
if (priv->current_atlas == self)
|
||||
priv->current_atlas = NULL;
|
||||
|
||||
g_object_unref (self->image);
|
||||
|
||||
|
||||
g_free (self);
|
||||
}
|
||||
|
||||
@@ -149,8 +212,7 @@ gsk_gpu_cached_atlas_should_collect (GskGpuDevice *device,
|
||||
GskGpuCached *cached,
|
||||
gint64 timestamp)
|
||||
{
|
||||
/* FIXME */
|
||||
return FALSE;
|
||||
return cached->pixels > MAX_DEAD_PIXELS;
|
||||
}
|
||||
|
||||
static const GskGpuCachedClass GSK_GPU_CACHED_ATLAS_CLASS =
|
||||
@@ -171,298 +233,6 @@ gsk_gpu_cached_atlas_new (GskGpuDevice *device)
|
||||
return self;
|
||||
}
|
||||
|
||||
/* }}} */
|
||||
/* {{{ CachedTexture */
|
||||
|
||||
struct _GskGpuCachedTexture
|
||||
{
|
||||
GskGpuCached parent;
|
||||
|
||||
/* atomic */ GdkTexture *texture;
|
||||
GskGpuImage *image;
|
||||
};
|
||||
|
||||
static void
|
||||
gsk_gpu_cached_texture_free (GskGpuDevice *device,
|
||||
GskGpuCached *cached)
|
||||
{
|
||||
GskGpuCachedTexture *self = (GskGpuCachedTexture *) cached;
|
||||
gboolean texture_still_alive;
|
||||
|
||||
texture_still_alive = g_atomic_pointer_exchange (&self->texture, NULL) != NULL;
|
||||
g_object_unref (self->image);
|
||||
|
||||
if (!texture_still_alive)
|
||||
g_free (self);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gsk_gpu_cached_texture_should_collect (GskGpuDevice *device,
|
||||
GskGpuCached *cached,
|
||||
gint64 timestamp)
|
||||
{
|
||||
/* FIXME */
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static const GskGpuCachedClass GSK_GPU_CACHED_TEXTURE_CLASS =
|
||||
{
|
||||
sizeof (GskGpuCachedTexture),
|
||||
gsk_gpu_cached_texture_free,
|
||||
gsk_gpu_cached_texture_should_collect
|
||||
};
|
||||
|
||||
static void
|
||||
gsk_gpu_cached_texture_destroy_cb (gpointer data)
|
||||
{
|
||||
GskGpuCachedTexture *cache = data;
|
||||
gboolean cache_still_alive;
|
||||
|
||||
cache_still_alive = g_atomic_pointer_exchange (&cache->texture, NULL) != NULL;
|
||||
|
||||
if (!cache_still_alive)
|
||||
g_free (cache);
|
||||
}
|
||||
|
||||
static GskGpuCachedTexture *
|
||||
gsk_gpu_cached_texture_new (GskGpuDevice *device,
|
||||
GdkTexture *texture,
|
||||
GskGpuImage *image)
|
||||
{
|
||||
GskGpuDevicePrivate *priv = gsk_gpu_device_get_instance_private (device);
|
||||
GskGpuCachedTexture *self;
|
||||
|
||||
if (gdk_texture_get_render_data (texture, device))
|
||||
gdk_texture_clear_render_data (texture);
|
||||
else if ((self = g_hash_table_lookup (priv->texture_cache, texture)))
|
||||
{
|
||||
g_hash_table_remove (priv->texture_cache, texture);
|
||||
g_object_weak_unref (G_OBJECT (texture), (GWeakNotify) gsk_gpu_cached_texture_destroy_cb, self);
|
||||
}
|
||||
|
||||
self = gsk_gpu_cached_new (device, &GSK_GPU_CACHED_TEXTURE_CLASS, NULL);
|
||||
self->texture = texture;
|
||||
self->image = g_object_ref (image);
|
||||
|
||||
if (!gdk_texture_set_render_data (texture, device, self, gsk_gpu_cached_texture_destroy_cb))
|
||||
{
|
||||
g_object_weak_ref (G_OBJECT (texture), (GWeakNotify) gsk_gpu_cached_texture_destroy_cb, self);
|
||||
g_hash_table_insert (priv->texture_cache, texture, self);
|
||||
}
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
/* }}} */
|
||||
/* {{{ CachedGlyph */
|
||||
|
||||
struct _GskGpuCachedGlyph
|
||||
{
|
||||
GskGpuCached parent;
|
||||
|
||||
PangoFont *font;
|
||||
PangoGlyph glyph;
|
||||
GskGpuGlyphLookupFlags flags;
|
||||
float scale;
|
||||
|
||||
GskGpuImage *image;
|
||||
graphene_rect_t bounds;
|
||||
graphene_point_t origin;
|
||||
};
|
||||
|
||||
static void
|
||||
gsk_gpu_cached_glyph_free (GskGpuDevice *device,
|
||||
GskGpuCached *cached)
|
||||
{
|
||||
GskGpuCachedGlyph *self = (GskGpuCachedGlyph *) cached;
|
||||
|
||||
g_object_unref (self->font);
|
||||
g_object_unref (self->image);
|
||||
|
||||
g_free (self);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gsk_gpu_cached_glyph_should_collect (GskGpuDevice *device,
|
||||
GskGpuCached *cached,
|
||||
gint64 timestamp)
|
||||
{
|
||||
/* FIXME */
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static guint
|
||||
gsk_gpu_cached_glyph_hash (gconstpointer data)
|
||||
{
|
||||
const GskGpuCachedGlyph *glyph = data;
|
||||
|
||||
return GPOINTER_TO_UINT (glyph->font) ^
|
||||
glyph->glyph ^
|
||||
(glyph->flags << 24) ^
|
||||
((guint) glyph->scale * PANGO_SCALE);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gsk_gpu_cached_glyph_equal (gconstpointer v1,
|
||||
gconstpointer v2)
|
||||
{
|
||||
const GskGpuCachedGlyph *glyph1 = v1;
|
||||
const GskGpuCachedGlyph *glyph2 = v2;
|
||||
|
||||
return glyph1->font == glyph2->font
|
||||
&& glyph1->glyph == glyph2->glyph
|
||||
&& glyph1->flags == glyph2->flags
|
||||
&& glyph1->scale == glyph2->scale;
|
||||
}
|
||||
|
||||
static const GskGpuCachedClass GSK_GPU_CACHED_GLYPH_CLASS =
|
||||
{
|
||||
sizeof (GskGpuCachedGlyph),
|
||||
gsk_gpu_cached_glyph_free,
|
||||
gsk_gpu_cached_glyph_should_collect
|
||||
};
|
||||
|
||||
/* }}} */
|
||||
/* {{{ GskGpuDevice */
|
||||
|
||||
void
|
||||
gsk_gpu_device_gc (GskGpuDevice *self,
|
||||
gint64 timestamp)
|
||||
{
|
||||
GskGpuDevicePrivate *priv = gsk_gpu_device_get_instance_private (self);
|
||||
GskGpuCached *cached, *next;
|
||||
|
||||
for (cached = priv->first_cached; cached != NULL; cached = next)
|
||||
{
|
||||
next = cached->next;
|
||||
if (gsk_gpu_cached_should_collect (self, cached, timestamp))
|
||||
gsk_gpu_cached_free (self, cached);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gsk_gpu_device_clear_cache (GskGpuDevice *self)
|
||||
{
|
||||
GskGpuDevicePrivate *priv = gsk_gpu_device_get_instance_private (self);
|
||||
|
||||
for (GskGpuCached *cached = priv->first_cached; cached; cached = cached->next)
|
||||
{
|
||||
if (cached->prev == NULL)
|
||||
g_assert (priv->first_cached == cached);
|
||||
else
|
||||
g_assert (cached->prev->next == cached);
|
||||
if (cached->next == NULL)
|
||||
g_assert (priv->last_cached == cached);
|
||||
else
|
||||
g_assert (cached->next->prev == cached);
|
||||
}
|
||||
|
||||
while (priv->first_cached)
|
||||
gsk_gpu_cached_free (self, priv->first_cached);
|
||||
|
||||
g_assert (priv->last_cached == NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
gsk_gpu_device_dispose (GObject *object)
|
||||
{
|
||||
GskGpuDevice *self = GSK_GPU_DEVICE (object);
|
||||
GskGpuDevicePrivate *priv = gsk_gpu_device_get_instance_private (self);
|
||||
|
||||
gsk_gpu_device_clear_cache (self);
|
||||
g_hash_table_unref (priv->glyph_cache);
|
||||
g_hash_table_unref (priv->texture_cache);
|
||||
|
||||
G_OBJECT_CLASS (gsk_gpu_device_parent_class)->dispose (object);
|
||||
}
|
||||
|
||||
static void
|
||||
gsk_gpu_device_finalize (GObject *object)
|
||||
{
|
||||
GskGpuDevice *self = GSK_GPU_DEVICE (object);
|
||||
GskGpuDevicePrivate *priv = gsk_gpu_device_get_instance_private (self);
|
||||
|
||||
g_object_unref (priv->display);
|
||||
|
||||
G_OBJECT_CLASS (gsk_gpu_device_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
static void
|
||||
gsk_gpu_device_class_init (GskGpuDeviceClass *klass)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
|
||||
object_class->dispose = gsk_gpu_device_dispose;
|
||||
object_class->finalize = gsk_gpu_device_finalize;
|
||||
}
|
||||
|
||||
static void
|
||||
gsk_gpu_device_init (GskGpuDevice *self)
|
||||
{
|
||||
GskGpuDevicePrivate *priv = gsk_gpu_device_get_instance_private (self);
|
||||
|
||||
priv->glyph_cache = g_hash_table_new (gsk_gpu_cached_glyph_hash,
|
||||
gsk_gpu_cached_glyph_equal);
|
||||
priv->texture_cache = g_hash_table_new (g_direct_hash,
|
||||
g_direct_equal);
|
||||
}
|
||||
|
||||
void
|
||||
gsk_gpu_device_setup (GskGpuDevice *self,
|
||||
GdkDisplay *display,
|
||||
gsize max_image_size)
|
||||
{
|
||||
GskGpuDevicePrivate *priv = gsk_gpu_device_get_instance_private (self);
|
||||
|
||||
priv->display = g_object_ref (display);
|
||||
priv->max_image_size = max_image_size;
|
||||
}
|
||||
|
||||
GdkDisplay *
|
||||
gsk_gpu_device_get_display (GskGpuDevice *self)
|
||||
{
|
||||
GskGpuDevicePrivate *priv = gsk_gpu_device_get_instance_private (self);
|
||||
|
||||
return priv->display;
|
||||
}
|
||||
|
||||
gsize
|
||||
gsk_gpu_device_get_max_image_size (GskGpuDevice *self)
|
||||
{
|
||||
GskGpuDevicePrivate *priv = gsk_gpu_device_get_instance_private (self);
|
||||
|
||||
return priv->max_image_size;
|
||||
}
|
||||
|
||||
GskGpuImage *
|
||||
gsk_gpu_device_create_offscreen_image (GskGpuDevice *self,
|
||||
gboolean with_mipmap,
|
||||
GdkMemoryDepth depth,
|
||||
gsize width,
|
||||
gsize height)
|
||||
{
|
||||
return GSK_GPU_DEVICE_GET_CLASS (self)->create_offscreen_image (self, with_mipmap, depth, width, height);
|
||||
}
|
||||
|
||||
GskGpuImage *
|
||||
gsk_gpu_device_create_upload_image (GskGpuDevice *self,
|
||||
gboolean with_mipmap,
|
||||
GdkMemoryFormat format,
|
||||
gsize width,
|
||||
gsize height)
|
||||
{
|
||||
return GSK_GPU_DEVICE_GET_CLASS (self)->create_upload_image (self, with_mipmap, format, width, height);
|
||||
}
|
||||
|
||||
GskGpuImage *
|
||||
gsk_gpu_device_create_download_image (GskGpuDevice *self,
|
||||
GdkMemoryDepth depth,
|
||||
gsize width,
|
||||
gsize height)
|
||||
{
|
||||
return GSK_GPU_DEVICE_GET_CLASS (self)->create_download_image (self, depth, width, height);
|
||||
}
|
||||
|
||||
/* This rounds up to the next number that has <= 2 bits set:
|
||||
* 1, 2, 3, 4, 6, 8, 12, 16, 24, 32, 48, 64, 96, 128, ...
|
||||
* That is roughly sqrt(2), so it should limit waste
|
||||
@@ -520,25 +290,397 @@ gsk_gpu_cached_atlas_allocate (GskGpuCachedAtlas *atlas,
|
||||
if (!can_add_slice)
|
||||
return FALSE;
|
||||
|
||||
if (y + height > ATLAS_SIZE)
|
||||
return FALSE;
|
||||
|
||||
atlas->n_slices++;
|
||||
if (atlas->n_slices == MAX_SLICES_PER_ATLAS)
|
||||
atlas->slices[i].height = ATLAS_SIZE - y;
|
||||
else
|
||||
atlas->slices[i].height = round_up_atlas_size (MAX (height, 4));
|
||||
atlas->slices[i].height = MIN (round_up_atlas_size (MAX (height, 4)), ATLAS_SIZE - y);
|
||||
|
||||
atlas->slices[i].width = 0;
|
||||
best_y = y;
|
||||
best_slice = i;
|
||||
}
|
||||
|
||||
g_assert (best_slice < MAX_SLICES_PER_ATLAS);
|
||||
|
||||
*out_x = atlas->slices[best_slice].width;
|
||||
*out_y = best_y;
|
||||
|
||||
atlas->slices[best_slice].width += width;
|
||||
|
||||
g_assert (atlas->slices[best_slice].height >= height);
|
||||
g_assert (atlas->slices[best_slice].width <= ATLAS_SIZE);
|
||||
g_assert (best_y + atlas->slices[best_slice].height <= ATLAS_SIZE);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* }}} */
|
||||
/* {{{ CachedTexture */
|
||||
|
||||
struct _GskGpuCachedTexture
|
||||
{
|
||||
GskGpuCached parent;
|
||||
|
||||
/* atomic */ GdkTexture *texture;
|
||||
GskGpuImage *image;
|
||||
};
|
||||
|
||||
static void
|
||||
gsk_gpu_cached_texture_free (GskGpuDevice *device,
|
||||
GskGpuCached *cached)
|
||||
{
|
||||
GskGpuCachedTexture *self = (GskGpuCachedTexture *) cached;
|
||||
gboolean texture_still_alive;
|
||||
|
||||
texture_still_alive = g_atomic_pointer_exchange (&self->texture, NULL) != NULL;
|
||||
g_clear_object (&self->image);
|
||||
|
||||
if (!texture_still_alive)
|
||||
g_free (self);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gsk_gpu_cached_texture_should_collect (GskGpuDevice *device,
|
||||
GskGpuCached *cached,
|
||||
gint64 timestamp)
|
||||
{
|
||||
return timestamp - cached->timestamp > CACHE_MAX_AGE;
|
||||
}
|
||||
|
||||
static const GskGpuCachedClass GSK_GPU_CACHED_TEXTURE_CLASS =
|
||||
{
|
||||
sizeof (GskGpuCachedTexture),
|
||||
gsk_gpu_cached_texture_free,
|
||||
gsk_gpu_cached_texture_should_collect
|
||||
};
|
||||
|
||||
static void
|
||||
gsk_gpu_cached_texture_destroy_cb (gpointer data)
|
||||
{
|
||||
GskGpuCachedTexture *cache = data;
|
||||
gboolean cache_still_alive;
|
||||
|
||||
cache_still_alive = g_atomic_pointer_exchange (&cache->texture, NULL) != NULL;
|
||||
|
||||
if (!cache_still_alive)
|
||||
g_free (cache);
|
||||
}
|
||||
|
||||
static GskGpuCachedTexture *
|
||||
gsk_gpu_cached_texture_new (GskGpuDevice *device,
|
||||
GdkTexture *texture,
|
||||
GskGpuImage *image)
|
||||
{
|
||||
GskGpuDevicePrivate *priv = gsk_gpu_device_get_instance_private (device);
|
||||
GskGpuCachedTexture *self;
|
||||
|
||||
if (gdk_texture_get_render_data (texture, device))
|
||||
gdk_texture_clear_render_data (texture);
|
||||
else if ((self = g_hash_table_lookup (priv->texture_cache, texture)))
|
||||
{
|
||||
g_hash_table_remove (priv->texture_cache, texture);
|
||||
g_object_weak_unref (G_OBJECT (texture), (GWeakNotify) gsk_gpu_cached_texture_destroy_cb, self);
|
||||
}
|
||||
|
||||
self = gsk_gpu_cached_new (device, &GSK_GPU_CACHED_TEXTURE_CLASS, NULL);
|
||||
self->texture = texture;
|
||||
self->image = g_object_ref (image);
|
||||
|
||||
if (!gdk_texture_set_render_data (texture, device, self, gsk_gpu_cached_texture_destroy_cb))
|
||||
{
|
||||
g_object_weak_ref (G_OBJECT (texture), (GWeakNotify) gsk_gpu_cached_texture_destroy_cb, self);
|
||||
g_hash_table_insert (priv->texture_cache, texture, self);
|
||||
}
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
/* }}} */
|
||||
/* {{{ CachedGlyph */
|
||||
|
||||
struct _GskGpuCachedGlyph
|
||||
{
|
||||
GskGpuCached parent;
|
||||
|
||||
GlyphKey key;
|
||||
|
||||
GskGpuImage *image;
|
||||
graphene_rect_t bounds;
|
||||
graphene_point_t origin;
|
||||
};
|
||||
|
||||
static void
|
||||
gsk_gpu_cached_glyph_free (GskGpuDevice *device,
|
||||
GskGpuCached *cached)
|
||||
{
|
||||
GskGpuDevicePrivate *priv = gsk_gpu_device_get_instance_private (device);
|
||||
GskGpuCachedGlyph *self = (GskGpuCachedGlyph *) cached;
|
||||
|
||||
g_hash_table_remove (priv->glyph_cache, self);
|
||||
|
||||
g_object_unref (self->key.font);
|
||||
g_object_unref (self->image);
|
||||
|
||||
g_free (self);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gsk_gpu_cached_glyph_should_collect (GskGpuDevice *device,
|
||||
GskGpuCached *cached,
|
||||
gint64 timestamp)
|
||||
{
|
||||
if (timestamp - cached->timestamp > CACHE_MAX_AGE)
|
||||
mark_as_stale (cached, TRUE);
|
||||
|
||||
/* Glyphs are only collected when their atlas is freed */
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static guint
|
||||
gsk_gpu_cached_glyph_hash (gconstpointer data)
|
||||
{
|
||||
const GskGpuCachedGlyph *glyph = data;
|
||||
|
||||
return GPOINTER_TO_UINT (glyph->key.font) ^
|
||||
glyph->key.glyph ^
|
||||
(glyph->key.flags << 24) ^
|
||||
((guint) glyph->key.scale * PANGO_SCALE);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gsk_gpu_cached_glyph_equal (gconstpointer v1,
|
||||
gconstpointer v2)
|
||||
{
|
||||
const GskGpuCachedGlyph *glyph1 = v1;
|
||||
const GskGpuCachedGlyph *glyph2 = v2;
|
||||
|
||||
return glyph1->key.font == glyph2->key.font
|
||||
&& glyph1->key.glyph == glyph2->key.glyph
|
||||
&& glyph1->key.flags == glyph2->key.flags
|
||||
&& glyph1->key.scale == glyph2->key.scale;
|
||||
}
|
||||
|
||||
static const GskGpuCachedClass GSK_GPU_CACHED_GLYPH_CLASS =
|
||||
{
|
||||
sizeof (GskGpuCachedGlyph),
|
||||
gsk_gpu_cached_glyph_free,
|
||||
gsk_gpu_cached_glyph_should_collect
|
||||
};
|
||||
|
||||
/* }}} */
|
||||
/* {{{ GskGpuDevice */
|
||||
|
||||
static void
|
||||
print_cache_stats (GskGpuDevice *self)
|
||||
{
|
||||
GskGpuDevicePrivate *priv = gsk_gpu_device_get_instance_private (self);
|
||||
GskGpuCached *cached;
|
||||
guint glyphs = 0;
|
||||
guint stale_glyphs = 0;
|
||||
guint textures = 0;
|
||||
guint atlases = 0;
|
||||
GString *ratios = g_string_new ("");
|
||||
|
||||
for (cached = priv->first_cached; cached != NULL; cached = cached->next)
|
||||
{
|
||||
if (cached->class == &GSK_GPU_CACHED_GLYPH_CLASS)
|
||||
{
|
||||
glyphs++;
|
||||
if (cached->stale)
|
||||
stale_glyphs++;
|
||||
}
|
||||
else if (cached->class == &GSK_GPU_CACHED_TEXTURE_CLASS)
|
||||
textures++;
|
||||
else if (cached->class == &GSK_GPU_CACHED_ATLAS_CLASS)
|
||||
{
|
||||
double ratio;
|
||||
|
||||
atlases++;
|
||||
|
||||
ratio = (double) cached->pixels / (double) (ATLAS_SIZE * ATLAS_SIZE);
|
||||
|
||||
if (ratios->len == 0)
|
||||
g_string_append (ratios, " (ratios ");
|
||||
else
|
||||
g_string_append (ratios, ", ");
|
||||
g_string_append_printf (ratios, "%.2f", ratio);
|
||||
}
|
||||
}
|
||||
|
||||
if (ratios->len > 0)
|
||||
g_string_append (ratios, ")");
|
||||
|
||||
gdk_debug_message ("cached items\n"
|
||||
" glyphs: %5u (%u stale)\n"
|
||||
" textures: %5u\n"
|
||||
" atlases: %5u%s",
|
||||
glyphs, stale_glyphs, textures, atlases, ratios->str);
|
||||
|
||||
g_string_free (ratios, TRUE);
|
||||
}
|
||||
|
||||
void
|
||||
gsk_gpu_device_gc (GskGpuDevice *self,
|
||||
gint64 timestamp)
|
||||
{
|
||||
GskGpuDevicePrivate *priv = gsk_gpu_device_get_instance_private (self);
|
||||
GskGpuCached *cached, *prev;
|
||||
|
||||
/* We walk the cache from the end so we don't end up with prev
|
||||
* begin a leftover glyph on the atlas we are freeing
|
||||
*/
|
||||
for (cached = priv->last_cached; cached != NULL; cached = prev)
|
||||
{
|
||||
prev = cached->prev;
|
||||
if (gsk_gpu_cached_should_collect (self, cached, timestamp))
|
||||
gsk_gpu_cached_free (self, cached);
|
||||
}
|
||||
|
||||
if (GSK_DEBUG_CHECK (GLYPH_CACHE))
|
||||
print_cache_stats (self);
|
||||
}
|
||||
|
||||
static void
|
||||
gsk_gpu_device_clear_cache (GskGpuDevice *self)
|
||||
{
|
||||
GskGpuDevicePrivate *priv = gsk_gpu_device_get_instance_private (self);
|
||||
|
||||
for (GskGpuCached *cached = priv->first_cached; cached; cached = cached->next)
|
||||
{
|
||||
if (cached->prev == NULL)
|
||||
g_assert (priv->first_cached == cached);
|
||||
else
|
||||
g_assert (cached->prev->next == cached);
|
||||
if (cached->next == NULL)
|
||||
g_assert (priv->last_cached == cached);
|
||||
else
|
||||
g_assert (cached->next->prev == cached);
|
||||
}
|
||||
|
||||
/* We clear the cache from the end so glyphs get freed before their atlas */
|
||||
while (priv->last_cached)
|
||||
gsk_gpu_cached_free (self, priv->last_cached);
|
||||
|
||||
g_assert (priv->last_cached == NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
gsk_gpu_device_dispose (GObject *object)
|
||||
{
|
||||
GskGpuDevice *self = GSK_GPU_DEVICE (object);
|
||||
GskGpuDevicePrivate *priv = gsk_gpu_device_get_instance_private (self);
|
||||
|
||||
gsk_gpu_device_clear_cache (self);
|
||||
g_hash_table_unref (priv->glyph_cache);
|
||||
g_hash_table_unref (priv->texture_cache);
|
||||
g_clear_handle_id (&priv->cache_gc_source, g_source_remove);
|
||||
|
||||
G_OBJECT_CLASS (gsk_gpu_device_parent_class)->dispose (object);
|
||||
}
|
||||
|
||||
static void
|
||||
gsk_gpu_device_finalize (GObject *object)
|
||||
{
|
||||
GskGpuDevice *self = GSK_GPU_DEVICE (object);
|
||||
GskGpuDevicePrivate *priv = gsk_gpu_device_get_instance_private (self);
|
||||
|
||||
g_object_unref (priv->display);
|
||||
|
||||
G_OBJECT_CLASS (gsk_gpu_device_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
static void
|
||||
gsk_gpu_device_class_init (GskGpuDeviceClass *klass)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
|
||||
object_class->dispose = gsk_gpu_device_dispose;
|
||||
object_class->finalize = gsk_gpu_device_finalize;
|
||||
}
|
||||
|
||||
static void
|
||||
gsk_gpu_device_init (GskGpuDevice *self)
|
||||
{
|
||||
GskGpuDevicePrivate *priv = gsk_gpu_device_get_instance_private (self);
|
||||
|
||||
priv->glyph_cache = g_hash_table_new (gsk_gpu_cached_glyph_hash,
|
||||
gsk_gpu_cached_glyph_equal);
|
||||
priv->texture_cache = g_hash_table_new (g_direct_hash,
|
||||
g_direct_equal);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
cache_gc_source_callback (gpointer data)
|
||||
{
|
||||
GskGpuDevice *self = data;
|
||||
|
||||
gsk_gpu_device_gc (self, g_get_monotonic_time ());
|
||||
|
||||
return G_SOURCE_CONTINUE;
|
||||
}
|
||||
|
||||
void
|
||||
gsk_gpu_device_setup (GskGpuDevice *self,
|
||||
GdkDisplay *display,
|
||||
gsize max_image_size)
|
||||
{
|
||||
GskGpuDevicePrivate *priv = gsk_gpu_device_get_instance_private (self);
|
||||
|
||||
priv->display = g_object_ref (display);
|
||||
priv->max_image_size = max_image_size;
|
||||
|
||||
priv->cache_gc_source = g_timeout_add_seconds (CACHE_GC_TIMEOUT, cache_gc_source_callback, self);
|
||||
}
|
||||
|
||||
GdkDisplay *
|
||||
gsk_gpu_device_get_display (GskGpuDevice *self)
|
||||
{
|
||||
GskGpuDevicePrivate *priv = gsk_gpu_device_get_instance_private (self);
|
||||
|
||||
return priv->display;
|
||||
}
|
||||
|
||||
gsize
|
||||
gsk_gpu_device_get_max_image_size (GskGpuDevice *self)
|
||||
{
|
||||
GskGpuDevicePrivate *priv = gsk_gpu_device_get_instance_private (self);
|
||||
|
||||
return priv->max_image_size;
|
||||
}
|
||||
|
||||
GskGpuImage *
|
||||
gsk_gpu_device_create_offscreen_image (GskGpuDevice *self,
|
||||
gboolean with_mipmap,
|
||||
GdkMemoryDepth depth,
|
||||
gsize width,
|
||||
gsize height)
|
||||
{
|
||||
return GSK_GPU_DEVICE_GET_CLASS (self)->create_offscreen_image (self, with_mipmap, depth, width, height);
|
||||
}
|
||||
|
||||
GskGpuImage *
|
||||
gsk_gpu_device_create_upload_image (GskGpuDevice *self,
|
||||
gboolean with_mipmap,
|
||||
GdkMemoryFormat format,
|
||||
gsize width,
|
||||
gsize height)
|
||||
{
|
||||
return GSK_GPU_DEVICE_GET_CLASS (self)->create_upload_image (self, with_mipmap, format, width, height);
|
||||
}
|
||||
|
||||
GskGpuImage *
|
||||
gsk_gpu_device_create_download_image (GskGpuDevice *self,
|
||||
GdkMemoryDepth depth,
|
||||
gsize width,
|
||||
gsize height)
|
||||
{
|
||||
return GSK_GPU_DEVICE_GET_CLASS (self)->create_download_image (self, depth, width, height);
|
||||
}
|
||||
|
||||
static void
|
||||
gsk_gpu_device_ensure_atlas (GskGpuDevice *self,
|
||||
gboolean recreate,
|
||||
@@ -576,20 +718,14 @@ gsk_gpu_device_add_atlas_image (GskGpuDevice *self,
|
||||
return NULL;
|
||||
|
||||
gsk_gpu_device_ensure_atlas (self, FALSE, timestamp);
|
||||
|
||||
|
||||
if (gsk_gpu_cached_atlas_allocate (priv->current_atlas, width, height, out_x, out_y))
|
||||
{
|
||||
gsk_gpu_cached_use (self, (GskGpuCached *) priv->current_atlas, timestamp);
|
||||
return priv->current_atlas->image;
|
||||
}
|
||||
return priv->current_atlas->image;
|
||||
|
||||
gsk_gpu_device_ensure_atlas (self, TRUE, timestamp);
|
||||
|
||||
if (gsk_gpu_cached_atlas_allocate (priv->current_atlas, width, height, out_x, out_y))
|
||||
{
|
||||
gsk_gpu_cached_use (self, (GskGpuCached *) priv->current_atlas, timestamp);
|
||||
return priv->current_atlas->image;
|
||||
}
|
||||
return priv->current_atlas->image;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
@@ -606,10 +742,8 @@ gsk_gpu_device_lookup_texture_image (GskGpuDevice *self,
|
||||
if (cache == NULL)
|
||||
cache = g_hash_table_lookup (priv->texture_cache, texture);
|
||||
|
||||
if (cache)
|
||||
{
|
||||
return g_object_ref (cache->image);
|
||||
}
|
||||
if (cache && cache->image)
|
||||
return g_object_ref (cache->image);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
@@ -639,10 +773,10 @@ gsk_gpu_device_lookup_glyph_image (GskGpuDevice *self,
|
||||
{
|
||||
GskGpuDevicePrivate *priv = gsk_gpu_device_get_instance_private (self);
|
||||
GskGpuCachedGlyph lookup = {
|
||||
.font = font,
|
||||
.glyph = glyph,
|
||||
.flags = flags,
|
||||
.scale = scale
|
||||
.key.font = font,
|
||||
.key.glyph = glyph,
|
||||
.key.flags = flags,
|
||||
.key.scale = scale
|
||||
};
|
||||
GskGpuCachedGlyph *cache;
|
||||
PangoRectangle ink_rect;
|
||||
@@ -650,14 +784,32 @@ gsk_gpu_device_lookup_glyph_image (GskGpuDevice *self,
|
||||
graphene_point_t origin;
|
||||
GskGpuImage *image;
|
||||
gsize atlas_x, atlas_y, padding;
|
||||
guint64 timestamp = gsk_gpu_frame_get_timestamp (frame);
|
||||
guint front_index = glyph & 0xFF;
|
||||
|
||||
if (memcmp (&lookup.key, &priv->front[front_index], sizeof (GlyphKey)) == 0)
|
||||
{
|
||||
cache = priv->front[front_index].value;
|
||||
|
||||
gsk_gpu_cached_use (self, (GskGpuCached *) cache, timestamp);
|
||||
|
||||
*out_bounds = cache->bounds;
|
||||
*out_origin = cache->origin;
|
||||
|
||||
return cache->image;
|
||||
}
|
||||
|
||||
cache = g_hash_table_lookup (priv->glyph_cache, &lookup);
|
||||
if (cache)
|
||||
{
|
||||
gsk_gpu_cached_use (self, (GskGpuCached *) cache, gsk_gpu_frame_get_timestamp (frame));
|
||||
memcpy (&priv->front[front_index].key, &lookup.key, sizeof (GlyphKey));
|
||||
priv->front[front_index].value = cache;
|
||||
|
||||
gsk_gpu_cached_use (self, (GskGpuCached *) cache, timestamp);
|
||||
|
||||
*out_bounds = cache->bounds;
|
||||
*out_origin = cache->origin;
|
||||
|
||||
return cache->image;
|
||||
}
|
||||
|
||||
@@ -669,7 +821,7 @@ gsk_gpu_device_lookup_glyph_image (GskGpuDevice *self,
|
||||
padding = 1;
|
||||
|
||||
image = gsk_gpu_device_add_atlas_image (self,
|
||||
gsk_gpu_frame_get_timestamp (frame),
|
||||
timestamp,
|
||||
rect.size.width + 2 * padding, rect.size.height + 2 * padding,
|
||||
&atlas_x, &atlas_y);
|
||||
if (image)
|
||||
@@ -688,12 +840,13 @@ gsk_gpu_device_lookup_glyph_image (GskGpuDevice *self,
|
||||
cache = gsk_gpu_cached_new (self, &GSK_GPU_CACHED_GLYPH_CLASS, NULL);
|
||||
}
|
||||
|
||||
cache->font = g_object_ref (font),
|
||||
cache->glyph = glyph,
|
||||
cache->flags = flags,
|
||||
cache->scale = scale,
|
||||
cache->key.font = g_object_ref (font),
|
||||
cache->key.glyph = glyph,
|
||||
cache->key.flags = flags,
|
||||
cache->key.scale = scale,
|
||||
cache->bounds = rect,
|
||||
cache->image = image,
|
||||
((GskGpuCached *) cache)->pixels = (rect.size.width + 2 * padding) * (rect.size.height + 2 * padding);
|
||||
cache->origin = GRAPHENE_POINT_INIT (- origin.x + (flags & 3) / 4.f,
|
||||
- origin.y + ((flags >> 2) & 3) / 4.f);
|
||||
|
||||
@@ -712,10 +865,14 @@ gsk_gpu_device_lookup_glyph_image (GskGpuDevice *self,
|
||||
cache->origin.y + padding));
|
||||
|
||||
g_hash_table_insert (priv->glyph_cache, cache, cache);
|
||||
gsk_gpu_cached_use (self, (GskGpuCached *) cache, gsk_gpu_frame_get_timestamp (frame));
|
||||
gsk_gpu_cached_use (self, (GskGpuCached *) cache, timestamp);
|
||||
|
||||
memcpy (&priv->front[front_index].key, &lookup.key, sizeof (GlyphKey));
|
||||
priv->front[front_index].value = cache;
|
||||
|
||||
*out_bounds = cache->bounds;
|
||||
*out_origin = cache->origin;
|
||||
|
||||
return cache->image;
|
||||
}
|
||||
|
||||
|
||||
@@ -12,8 +12,6 @@
|
||||
#include "gskvulkandescriptorsprivate.h"
|
||||
#endif
|
||||
|
||||
#include "gskrectprivate.h"
|
||||
|
||||
typedef struct _GskGpuGlobalsOp GskGpuGlobalsOp;
|
||||
|
||||
struct _GskGpuGlobalsOp
|
||||
@@ -89,16 +87,15 @@ static const GskGpuOpClass GSK_GPU_GLOBALS_OP_CLASS = {
|
||||
|
||||
void
|
||||
gsk_gpu_globals_op (GskGpuFrame *frame,
|
||||
const GskScale *scale,
|
||||
const graphene_vec2_t *scale,
|
||||
const graphene_matrix_t *mvp,
|
||||
const GskRoundedRect *clip)
|
||||
{
|
||||
GskGpuGlobalsOp *self;
|
||||
GskPoint zero = gsk_point_init (0, 0);
|
||||
|
||||
self = (GskGpuGlobalsOp *) gsk_gpu_op_alloc (frame, &GSK_GPU_GLOBALS_OP_CLASS);
|
||||
|
||||
graphene_matrix_to_float (mvp, self->instance.mvp);
|
||||
gsk_gpu_rounded_rect_to_float (clip, &zero, self->instance.clip);
|
||||
gsk_scale_to_float (scale, self->instance.scale);
|
||||
gsk_rounded_rect_to_float (clip, graphene_point_zero (), self->instance.clip);
|
||||
graphene_vec2_to_float (scale, self->instance.scale);
|
||||
}
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
#include "gskgpuopprivate.h"
|
||||
|
||||
#include <gsk/gskroundedrect.h>
|
||||
#include "gsk/gskscaleprivate.h"
|
||||
#include <graphene.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
@@ -18,7 +17,7 @@ struct _GskGpuGlobalsInstance
|
||||
};
|
||||
|
||||
void gsk_gpu_globals_op (GskGpuFrame *frame,
|
||||
const GskScale *scale,
|
||||
const graphene_vec2_t *scale,
|
||||
const graphene_matrix_t *mvp,
|
||||
const GskRoundedRect *clip);
|
||||
|
||||
|
||||
@@ -64,7 +64,7 @@ gsk_gpu_linear_gradient_op (GskGpuFrame *frame,
|
||||
const graphene_rect_t *rect,
|
||||
const graphene_point_t *start,
|
||||
const graphene_point_t *end,
|
||||
const GskPoint *offset,
|
||||
const graphene_point_t *offset,
|
||||
const GskColorStop *stops,
|
||||
gsize n_stops)
|
||||
{
|
||||
|
||||
@@ -14,7 +14,7 @@ void gsk_gpu_linear_gradient_op (GskGpuF
|
||||
const graphene_rect_t *rect,
|
||||
const graphene_point_t *start,
|
||||
const graphene_point_t *end,
|
||||
const GskPoint *offset,
|
||||
const graphene_point_t *offset,
|
||||
const GskColorStop *stops,
|
||||
gsize n_stops);
|
||||
|
||||
|
||||
@@ -58,7 +58,7 @@ gsk_gpu_mask_op (GskGpuFrame *frame,
|
||||
GskGpuShaderClip clip,
|
||||
GskGpuDescriptors *desc,
|
||||
const graphene_rect_t *rect,
|
||||
const GskPoint *offset,
|
||||
const graphene_point_t *offset,
|
||||
float opacity,
|
||||
GskMaskMode mask_mode,
|
||||
guint32 source_descriptor,
|
||||
|
||||
@@ -10,7 +10,7 @@ void gsk_gpu_mask_op (GskGpuF
|
||||
GskGpuShaderClip clip,
|
||||
GskGpuDescriptors *desc,
|
||||
const graphene_rect_t *rect,
|
||||
const GskPoint *offset,
|
||||
const graphene_point_t *offset,
|
||||
float opacity,
|
||||
GskMaskMode mask_mode,
|
||||
guint32 source_descriptor,
|
||||
|
||||
@@ -40,8 +40,6 @@
|
||||
#include "gskroundedrectprivate.h"
|
||||
#include "gskstrokeprivate.h"
|
||||
#include "gsktransformprivate.h"
|
||||
#include "gskscaleprivate.h"
|
||||
#include "gskpointprivate.h"
|
||||
|
||||
#include "gdk/gdkrgbaprivate.h"
|
||||
|
||||
@@ -106,12 +104,12 @@ struct _GskGpuNodeProcessor
|
||||
GskGpuFrame *frame;
|
||||
GskGpuDescriptors *desc;
|
||||
cairo_rectangle_int_t scissor;
|
||||
GskGpuClip clip;
|
||||
GskGpuBlend blend;
|
||||
GskPoint offset;
|
||||
GskScale scale;
|
||||
GskTransform *modelview;
|
||||
graphene_point_t offset;
|
||||
graphene_matrix_t projection;
|
||||
graphene_vec2_t scale;
|
||||
GskTransform *modelview;
|
||||
GskGpuClip clip;
|
||||
float opacity;
|
||||
|
||||
GskGpuGlobals pending_globals;
|
||||
@@ -131,8 +129,8 @@ struct _GskGpuPatternWriter
|
||||
GskGpuDescriptors *desc;
|
||||
|
||||
graphene_rect_t bounds;
|
||||
GskPoint offset;
|
||||
GskScale scale;
|
||||
graphene_point_t offset;
|
||||
graphene_vec2_t scale;
|
||||
guint stack;
|
||||
|
||||
PatternBuffer buffer;
|
||||
@@ -177,20 +175,24 @@ gsk_gpu_node_processor_init (GskGpuNodeProcessor *self,
|
||||
}
|
||||
else
|
||||
{
|
||||
graphene_rect_t rect;
|
||||
|
||||
rect = gsk_rect_scale (GRAPHENE_RECT_INIT (clip->x, clip->y, clip->width, clip->height),
|
||||
gsk_scale_init (viewport->size.width / width,
|
||||
viewport->size.height / height));
|
||||
gsk_gpu_clip_init_rect (&self->clip, &rect);
|
||||
float scale_x = viewport->size.width / width;
|
||||
float scale_y = viewport->size.height / height;
|
||||
gsk_gpu_clip_init_rect (&self->clip,
|
||||
&GRAPHENE_RECT_INIT (
|
||||
scale_x * clip->x,
|
||||
scale_y * clip->y,
|
||||
scale_x * clip->width,
|
||||
scale_y * clip->height
|
||||
));
|
||||
}
|
||||
|
||||
self->modelview = NULL;
|
||||
gsk_gpu_image_get_projection_matrix (target, &self->projection);
|
||||
self->scale = gsk_scale_init (width / viewport->size.width,
|
||||
height / viewport->size.height);
|
||||
self->offset = gsk_point_init (-viewport->origin.x,
|
||||
-viewport->origin.y);
|
||||
graphene_vec2_init (&self->scale,
|
||||
width / viewport->size.width,
|
||||
height / viewport->size.height);
|
||||
self->offset = GRAPHENE_POINT_INIT (-viewport->origin.x,
|
||||
-viewport->origin.y);
|
||||
self->opacity = 1.0;
|
||||
self->pending_globals = GSK_GPU_GLOBAL_MATRIX | GSK_GPU_GLOBAL_SCALE | GSK_GPU_GLOBAL_CLIP | GSK_GPU_GLOBAL_SCISSOR | GSK_GPU_GLOBAL_BLEND;
|
||||
}
|
||||
@@ -302,20 +304,42 @@ gsk_gpu_node_processor_add_images (GskGpuNodeProcessor *self,
|
||||
while (desc != self->desc);
|
||||
}
|
||||
|
||||
static void
|
||||
rect_round_to_pixels (const graphene_rect_t *src,
|
||||
const graphene_vec2_t *pixel_scale,
|
||||
const graphene_point_t *pixel_offset,
|
||||
graphene_rect_t *dest)
|
||||
{
|
||||
float x, y, xscale, yscale, inv_xscale, inv_yscale;
|
||||
|
||||
xscale = graphene_vec2_get_x (pixel_scale);
|
||||
yscale = graphene_vec2_get_y (pixel_scale);
|
||||
inv_xscale = 1.0f / xscale;
|
||||
inv_yscale = 1.0f / yscale;
|
||||
|
||||
x = floorf ((src->origin.x + pixel_offset->x) * xscale);
|
||||
y = floorf ((src->origin.y + pixel_offset->y) * yscale);
|
||||
*dest = GRAPHENE_RECT_INIT (
|
||||
x * inv_xscale - pixel_offset->x,
|
||||
y * inv_yscale - pixel_offset->y,
|
||||
(ceil ((src->origin.x + pixel_offset->x + src->size.width) * xscale) - x) * inv_xscale,
|
||||
(ceil ((src->origin.y + pixel_offset->y + src->size.height) * yscale) - y) * inv_yscale);
|
||||
}
|
||||
|
||||
static GskGpuImage *
|
||||
gsk_gpu_node_processor_init_draw (GskGpuNodeProcessor *self,
|
||||
GskGpuFrame *frame,
|
||||
GdkMemoryDepth depth,
|
||||
const GskScale *scale,
|
||||
const graphene_rect_t *viewport)
|
||||
gsk_gpu_node_processor_init_draw (GskGpuNodeProcessor *self,
|
||||
GskGpuFrame *frame,
|
||||
GdkMemoryDepth depth,
|
||||
const graphene_vec2_t *scale,
|
||||
const graphene_rect_t *viewport)
|
||||
{
|
||||
GskGpuImage *image;
|
||||
cairo_rectangle_int_t area;
|
||||
|
||||
area.x = 0;
|
||||
area.y = 0;
|
||||
area.width = ceilf (gsk_scale_get_x (*scale) * viewport->size.width);
|
||||
area.height = ceilf (gsk_scale_get_y (*scale) * viewport->size.height);
|
||||
area.width = ceil (graphene_vec2_get_x (scale) * viewport->size.width);
|
||||
area.height = ceil (graphene_vec2_get_y (scale) * viewport->size.height);
|
||||
|
||||
image = gsk_gpu_device_create_offscreen_image (gsk_gpu_frame_get_device (frame),
|
||||
FALSE,
|
||||
@@ -374,13 +398,16 @@ gsk_gpu_node_processor_process (GskGpuFrame *frame,
|
||||
static void
|
||||
gsk_gpu_pattern_writer_init (GskGpuPatternWriter *self,
|
||||
GskGpuFrame *frame,
|
||||
const GskScale *scale,
|
||||
const GskPoint *offset,
|
||||
const graphene_vec2_t *scale,
|
||||
const graphene_point_t *offset,
|
||||
const graphene_rect_t *bounds)
|
||||
{
|
||||
self->frame = frame;
|
||||
self->desc = NULL;
|
||||
self->bounds = gsk_rect_add_offset (*bounds, *offset);
|
||||
self->bounds = GRAPHENE_RECT_INIT (bounds->origin.x + offset->x,
|
||||
bounds->origin.y + offset->y,
|
||||
bounds->size.width,
|
||||
bounds->size.height);
|
||||
self->offset = *offset;
|
||||
self->scale = *scale;
|
||||
self->stack = 0;
|
||||
@@ -449,12 +476,12 @@ gsk_gpu_pattern_writer_append_vec4 (GskGpuPatternWriter *self,
|
||||
static void
|
||||
gsk_gpu_pattern_writer_append_point (GskGpuPatternWriter *self,
|
||||
const graphene_point_t *point,
|
||||
const GskPoint *offset)
|
||||
const graphene_point_t *offset)
|
||||
{
|
||||
float f[2];
|
||||
|
||||
f[0] = point->x + gsk_point_get_x (*offset);
|
||||
f[1] = point->y + gsk_point_get_y (*offset);
|
||||
f[0] = point->x + offset->x;
|
||||
f[1] = point->y + offset->y;
|
||||
|
||||
gsk_gpu_pattern_writer_append (self, G_ALIGNOF (float), (guchar *) f, sizeof (f));
|
||||
}
|
||||
@@ -462,7 +489,7 @@ gsk_gpu_pattern_writer_append_point (GskGpuPatternWriter *self,
|
||||
static void
|
||||
gsk_gpu_pattern_writer_append_rect (GskGpuPatternWriter *self,
|
||||
const graphene_rect_t *rect,
|
||||
const GskPoint *offset)
|
||||
const graphene_point_t *offset)
|
||||
{
|
||||
float f[4];
|
||||
|
||||
@@ -526,14 +553,78 @@ gsk_gpu_pattern_writer_add_image (GskGpuPatternWriter *self,
|
||||
return gsk_gpu_descriptors_add_image (self->desc, image, sampler, out_descriptor);
|
||||
}
|
||||
|
||||
static void
|
||||
extract_scale_from_transform (GskTransform *transform,
|
||||
float *out_scale_x,
|
||||
float *out_scale_y)
|
||||
{
|
||||
switch (gsk_transform_get_category (transform))
|
||||
{
|
||||
default:
|
||||
g_assert_not_reached ();
|
||||
G_GNUC_FALLTHROUGH;
|
||||
case GSK_TRANSFORM_CATEGORY_IDENTITY:
|
||||
case GSK_TRANSFORM_CATEGORY_2D_TRANSLATE:
|
||||
*out_scale_x = 1.0f;
|
||||
*out_scale_y = 1.0f;
|
||||
return;
|
||||
|
||||
case GSK_TRANSFORM_CATEGORY_2D_AFFINE:
|
||||
{
|
||||
float scale_x, scale_y, dx, dy;
|
||||
gsk_transform_to_affine (transform, &scale_x, &scale_y, &dx, &dy);
|
||||
*out_scale_x = fabs (scale_x);
|
||||
*out_scale_y = fabs (scale_y);
|
||||
}
|
||||
return;
|
||||
|
||||
case GSK_TRANSFORM_CATEGORY_2D:
|
||||
{
|
||||
float skew_x, skew_y, scale_x, scale_y, angle, dx, dy;
|
||||
gsk_transform_to_2d_components (transform,
|
||||
&skew_x, &skew_y,
|
||||
&scale_x, &scale_y,
|
||||
&angle,
|
||||
&dx, &dy);
|
||||
*out_scale_x = fabs (scale_x);
|
||||
*out_scale_y = fabs (scale_y);
|
||||
}
|
||||
return;
|
||||
|
||||
case GSK_TRANSFORM_CATEGORY_UNKNOWN:
|
||||
case GSK_TRANSFORM_CATEGORY_ANY:
|
||||
case GSK_TRANSFORM_CATEGORY_3D:
|
||||
{
|
||||
graphene_quaternion_t rotation;
|
||||
graphene_matrix_t matrix;
|
||||
graphene_vec4_t perspective;
|
||||
graphene_vec3_t translation;
|
||||
graphene_vec3_t matrix_scale;
|
||||
graphene_vec3_t shear;
|
||||
|
||||
gsk_transform_to_matrix (transform, &matrix);
|
||||
graphene_matrix_decompose (&matrix,
|
||||
&translation,
|
||||
&matrix_scale,
|
||||
&rotation,
|
||||
&shear,
|
||||
&perspective);
|
||||
|
||||
*out_scale_x = fabs (graphene_vec3_get_x (&matrix_scale));
|
||||
*out_scale_y = fabs (graphene_vec3_get_y (&matrix_scale));
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gsk_gpu_node_processor_rect_is_integer (GskGpuNodeProcessor *self,
|
||||
const graphene_rect_t *rect,
|
||||
cairo_rectangle_int_t *int_rect)
|
||||
{
|
||||
graphene_rect_t transformed_rect;
|
||||
float scale_x = gsk_scale_get_x (self->scale);
|
||||
float scale_y = gsk_scale_get_y (self->scale);
|
||||
float scale_x = graphene_vec2_get_x (&self->scale);
|
||||
float scale_y = graphene_vec2_get_y (&self->scale);
|
||||
|
||||
switch (gsk_transform_get_category (self->modelview))
|
||||
{
|
||||
@@ -571,8 +662,10 @@ static void
|
||||
gsk_gpu_node_processor_get_clip_bounds (GskGpuNodeProcessor *self,
|
||||
graphene_rect_t *out_bounds)
|
||||
{
|
||||
*out_bounds = gsk_rect_init_offset (self->clip.rect.bounds,
|
||||
gsk_point_negate (self->offset));
|
||||
graphene_rect_offset_r (&self->clip.rect.bounds,
|
||||
- self->offset.x,
|
||||
- self->offset.y,
|
||||
out_bounds);
|
||||
|
||||
/* FIXME: We could try the scissor rect here.
|
||||
* But how often is that smaller than the clip bounds?
|
||||
@@ -665,7 +758,7 @@ gsk_gpu_node_processor_image_op (GskGpuNodeProcessor *self,
|
||||
static GskGpuImage *
|
||||
gsk_gpu_get_node_as_image (GskGpuFrame *frame,
|
||||
const graphene_rect_t *clip_bounds,
|
||||
const GskScale *scale,
|
||||
const graphene_vec2_t *scale,
|
||||
GskRenderNode *node,
|
||||
graphene_rect_t *out_bounds)
|
||||
{
|
||||
@@ -845,7 +938,7 @@ gsk_gpu_node_processor_get_node_as_image (GskGpuNodeProcessor *self,
|
||||
return NULL;
|
||||
clip_bounds = &clip;
|
||||
}
|
||||
clip = gsk_rect_round_to_pixels (*clip_bounds, self->scale, self->offset);
|
||||
rect_round_to_pixels (clip_bounds, &self->scale, &self->offset, &clip);
|
||||
|
||||
image = gsk_gpu_get_node_as_image (self->frame,
|
||||
&clip,
|
||||
@@ -887,8 +980,9 @@ gsk_gpu_node_processor_blur_op (GskGpuNodeProcessor *self,
|
||||
GskGpuNodeProcessor other;
|
||||
GskGpuImage *intermediate;
|
||||
guint32 intermediate_descriptor;
|
||||
graphene_vec2_t direction;
|
||||
graphene_rect_t clip_rect, intermediate_rect;
|
||||
GskPoint real_offset;
|
||||
graphene_point_t real_offset;
|
||||
int width, height;
|
||||
float clip_radius;
|
||||
|
||||
@@ -900,8 +994,8 @@ gsk_gpu_node_processor_blur_op (GskGpuNodeProcessor *self,
|
||||
if (!gsk_rect_intersection (rect, &clip_rect, &intermediate_rect))
|
||||
return;
|
||||
|
||||
width = ceilf (gsk_scale_get_x (self->scale) * intermediate_rect.size.width);
|
||||
height = ceilf (gsk_scale_get_y (self->scale) * intermediate_rect.size.height);
|
||||
width = ceil (graphene_vec2_get_x (&self->scale) * intermediate_rect.size.width);
|
||||
height = ceil (graphene_vec2_get_y (&self->scale) * intermediate_rect.size.height);
|
||||
|
||||
intermediate = gsk_gpu_device_create_offscreen_image (gsk_gpu_frame_get_device (self->frame),
|
||||
FALSE,
|
||||
@@ -922,6 +1016,7 @@ gsk_gpu_node_processor_blur_op (GskGpuNodeProcessor *self,
|
||||
|
||||
gsk_gpu_node_processor_sync_globals (&other, 0);
|
||||
|
||||
graphene_vec2_init (&direction, blur_radius, 0.0f);
|
||||
gsk_gpu_blur_op (other.frame,
|
||||
gsk_gpu_clip_get_shader_clip (&other.clip, &other.offset, &intermediate_rect),
|
||||
source_desc,
|
||||
@@ -929,7 +1024,7 @@ gsk_gpu_node_processor_blur_op (GskGpuNodeProcessor *self,
|
||||
&intermediate_rect,
|
||||
&other.offset,
|
||||
source_rect,
|
||||
&GRAPHENE_POINT_INIT (blur_radius, 0));
|
||||
&direction);
|
||||
|
||||
gsk_gpu_render_pass_end_op (other.frame,
|
||||
intermediate,
|
||||
@@ -937,7 +1032,9 @@ gsk_gpu_node_processor_blur_op (GskGpuNodeProcessor *self,
|
||||
|
||||
gsk_gpu_node_processor_finish (&other);
|
||||
|
||||
real_offset = gsk_point_add (self->offset, gsk_point_init (shadow_offset->x, shadow_offset->y));
|
||||
real_offset = GRAPHENE_POINT_INIT (self->offset.x + shadow_offset->x,
|
||||
self->offset.y + shadow_offset->y);
|
||||
graphene_vec2_init (&direction, 0.0f, blur_radius);
|
||||
intermediate_descriptor = gsk_gpu_node_processor_add_image (self, intermediate, GSK_GPU_SAMPLER_TRANSPARENT);
|
||||
if (shadow_color)
|
||||
{
|
||||
@@ -948,7 +1045,7 @@ gsk_gpu_node_processor_blur_op (GskGpuNodeProcessor *self,
|
||||
rect,
|
||||
&real_offset,
|
||||
&intermediate_rect,
|
||||
&GRAPHENE_POINT_INIT (0, blur_radius),
|
||||
&direction,
|
||||
shadow_color);
|
||||
}
|
||||
else
|
||||
@@ -960,7 +1057,7 @@ gsk_gpu_node_processor_blur_op (GskGpuNodeProcessor *self,
|
||||
rect,
|
||||
&real_offset,
|
||||
&intermediate_rect,
|
||||
&GRAPHENE_POINT_INIT (0, blur_radius));
|
||||
&direction);
|
||||
}
|
||||
|
||||
g_object_unref (intermediate);
|
||||
@@ -976,7 +1073,7 @@ gsk_gpu_node_processor_add_fallback_node (GskGpuNodeProcessor *self,
|
||||
if (!gsk_gpu_node_processor_clip_node_bounds (self, node, &clipped_bounds))
|
||||
return;
|
||||
|
||||
clipped_bounds = gsk_rect_round_to_pixels (clipped_bounds, self->scale, self->offset);
|
||||
rect_round_to_pixels (&clipped_bounds, &self->scale, &self->offset, &clipped_bounds);
|
||||
|
||||
gsk_gpu_node_processor_sync_globals (self, 0);
|
||||
|
||||
@@ -1198,7 +1295,9 @@ gsk_gpu_node_processor_add_node_clipped (GskGpuNodeProcessor *self,
|
||||
return;
|
||||
}
|
||||
|
||||
clip = gsk_rect_add_offset (*clip_bounds, self->offset);
|
||||
graphene_rect_offset_r (clip_bounds,
|
||||
self->offset.x, self->offset.y,
|
||||
&clip);
|
||||
|
||||
gsk_gpu_clip_init_copy (&old_clip, &self->clip);
|
||||
|
||||
@@ -1329,8 +1428,7 @@ gsk_gpu_node_processor_add_rounded_clip_node_with_mask (GskGpuNodeProcessor *sel
|
||||
|
||||
if (!gsk_gpu_node_processor_clip_node_bounds (self, node, &clip_bounds))
|
||||
return;
|
||||
|
||||
clip_bounds = gsk_rect_round_to_pixels (clip_bounds, self->scale, self->offset);
|
||||
rect_round_to_pixels (&clip_bounds, &self->scale, &self->offset, &clip_bounds);
|
||||
|
||||
child_image = gsk_gpu_node_processor_get_node_as_image (self,
|
||||
0,
|
||||
@@ -1407,7 +1505,7 @@ gsk_gpu_node_processor_add_rounded_clip_node (GskGpuNodeProcessor *self,
|
||||
gsk_gpu_clip_init_copy (&old_clip, &self->clip);
|
||||
|
||||
clip = *original_clip;
|
||||
gsk_rounded_rect_offset (&clip, gsk_point_get_x (self->offset), gsk_point_get_y (self->offset));
|
||||
gsk_rounded_rect_offset (&clip, self->offset.x, self->offset.y);
|
||||
|
||||
if (!gsk_gpu_clip_intersect_rounded_rect (&self->clip, &old_clip, &clip))
|
||||
{
|
||||
@@ -1436,8 +1534,8 @@ gsk_gpu_node_processor_add_transform_node (GskGpuNodeProcessor *self,
|
||||
{
|
||||
GskRenderNode *child;
|
||||
GskTransform *transform;
|
||||
GskPoint old_offset;
|
||||
GskScale old_scale;
|
||||
graphene_point_t old_offset;
|
||||
graphene_vec2_t old_scale;
|
||||
GskTransform *old_modelview;
|
||||
GskGpuClip old_clip;
|
||||
|
||||
@@ -1452,7 +1550,8 @@ gsk_gpu_node_processor_add_transform_node (GskGpuNodeProcessor *self,
|
||||
float dx, dy;
|
||||
gsk_transform_to_translate (transform, &dx, &dy);
|
||||
old_offset = self->offset;
|
||||
self->offset = gsk_point_add (self->offset, gsk_point_init (dx,dy));
|
||||
self->offset.x += dx;
|
||||
self->offset.y += dy;
|
||||
gsk_gpu_node_processor_add_node (self, child);
|
||||
self->offset = old_offset;
|
||||
}
|
||||
@@ -1469,11 +1568,13 @@ gsk_gpu_node_processor_add_transform_node (GskGpuNodeProcessor *self,
|
||||
|
||||
gsk_transform_to_affine (transform, &scale_x, &scale_y, &dx, &dy);
|
||||
gsk_gpu_clip_scale (&self->clip, &old_clip, scale_x, scale_y);
|
||||
self->offset = gsk_point_divide (gsk_point_add (self->offset, gsk_point_init (dx, dy)), gsk_scale_init (scale_x, scale_y));
|
||||
self->scale = gsk_scale_multiply (old_scale, gsk_scale_init (fabsf (scale_x), fabsf (scale_y)));
|
||||
self->offset.x = (self->offset.x + dx) / scale_x;
|
||||
self->offset.y = (self->offset.y + dy) / scale_y;
|
||||
graphene_vec2_init (&self->scale, fabs (scale_x), fabs (scale_y));
|
||||
graphene_vec2_multiply (&self->scale, &old_scale, &self->scale);
|
||||
self->modelview = gsk_transform_scale (self->modelview,
|
||||
scale_x / fabsf (scale_x),
|
||||
scale_y / fabsf (scale_y));
|
||||
scale_x / fabs (scale_x),
|
||||
scale_y / fabs (scale_y));
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -1483,10 +1584,9 @@ gsk_gpu_node_processor_add_transform_node (GskGpuNodeProcessor *self,
|
||||
case GSK_TRANSFORM_CATEGORY_3D:
|
||||
{
|
||||
GskTransform *clip_transform;
|
||||
float old_pixels, new_pixels;
|
||||
GskScale scale;
|
||||
float scale_x, scale_y, old_pixels, new_pixels;
|
||||
|
||||
clip_transform = gsk_transform_transform (gsk_transform_translate (NULL, &GRAPHENE_POINT_INIT (gsk_point_get_x (self->offset), gsk_point_get_y (self->offset))), transform);
|
||||
clip_transform = gsk_transform_transform (gsk_transform_translate (NULL, &self->offset), transform);
|
||||
gsk_gpu_clip_init_copy (&old_clip, &self->clip);
|
||||
|
||||
if (gsk_gpu_clip_contains_rect (&self->clip, &self->offset, &node->bounds))
|
||||
@@ -1531,25 +1631,26 @@ gsk_gpu_node_processor_add_transform_node (GskGpuNodeProcessor *self,
|
||||
old_modelview = gsk_transform_ref (self->modelview);
|
||||
|
||||
self->modelview = gsk_transform_scale (self->modelview,
|
||||
gsk_scale_get_x (self->scale),
|
||||
gsk_scale_get_y (self->scale));
|
||||
graphene_vec2_get_x (&self->scale),
|
||||
graphene_vec2_get_y (&self->scale));
|
||||
self->modelview = gsk_transform_transform (self->modelview, clip_transform);
|
||||
gsk_transform_unref (clip_transform);
|
||||
|
||||
scale = gsk_scale_extract_from_transform (self->modelview);
|
||||
extract_scale_from_transform (self->modelview, &scale_x, &scale_y);
|
||||
|
||||
old_pixels = gsk_scale_get_x (old_scale) * gsk_scale_get_y (old_scale) *
|
||||
old_pixels = graphene_vec2_get_x (&old_scale) * graphene_vec2_get_y (&old_scale) *
|
||||
old_clip.rect.bounds.size.width * old_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;
|
||||
new_pixels = scale_x * scale_y * self->clip.rect.bounds.size.width * self->clip.rect.bounds.size.height;
|
||||
if (new_pixels > 2 * old_pixels)
|
||||
scale = gsk_scale_multiply (scale, gsk_scale_init_uniform (2 * old_pixels / new_pixels));
|
||||
{
|
||||
float forced_downscale = 2 * old_pixels / new_pixels;
|
||||
scale_x *= forced_downscale;
|
||||
scale_y *= forced_downscale;
|
||||
}
|
||||
|
||||
self->modelview = gsk_transform_scale (self->modelview,
|
||||
1 / gsk_scale_get_x (scale),
|
||||
1 / gsk_scale_get_y (scale));
|
||||
self->scale = scale;
|
||||
self->offset = gsk_point_init (0, 0);
|
||||
self->modelview = gsk_transform_scale (self->modelview, 1 / scale_x, 1 / scale_y);
|
||||
graphene_vec2_init (&self->scale, scale_x, scale_y);
|
||||
self->offset = *graphene_point_zero ();
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -1576,8 +1677,8 @@ gsk_gpu_node_processor_create_transform_pattern (GskGpuPatternWriter *self,
|
||||
{
|
||||
GskRenderNode *child;
|
||||
GskTransform *transform;
|
||||
GskPoint old_offset;
|
||||
GskScale old_scale;
|
||||
graphene_point_t old_offset;
|
||||
graphene_vec2_t old_scale;
|
||||
graphene_rect_t old_bounds;
|
||||
gboolean result;
|
||||
|
||||
@@ -1596,7 +1697,8 @@ gsk_gpu_node_processor_create_transform_pattern (GskGpuPatternWriter *self,
|
||||
{
|
||||
float dx, dy;
|
||||
gsk_transform_to_translate (transform, &dx, &dy);
|
||||
self->offset = gsk_point_add (self->offset, gsk_point_init (dx, dy));
|
||||
self->offset.x += dx;
|
||||
self->offset.y += dy;
|
||||
result = gsk_gpu_node_processor_create_node_pattern (self, child);
|
||||
self->offset = old_offset;
|
||||
return result;
|
||||
@@ -1605,21 +1707,22 @@ gsk_gpu_node_processor_create_transform_pattern (GskGpuPatternWriter *self,
|
||||
case GSK_TRANSFORM_CATEGORY_2D_AFFINE:
|
||||
{
|
||||
float sx, sy, dx, dy, inv_sx, inv_sy;
|
||||
GskPoint p;
|
||||
graphene_vec4_t vec4;
|
||||
if (!gsk_gpu_pattern_writer_push_stack (self))
|
||||
return FALSE;
|
||||
gsk_transform_to_affine (transform, &sx, &sy, &dx, &dy);
|
||||
inv_sx = 1.f / sx;
|
||||
inv_sy = 1.f / sy;
|
||||
p = gsk_point_add (self->offset, gsk_point_init (dx, dy));
|
||||
gsk_gpu_pattern_writer_append_uint (self, GSK_GPU_PATTERN_AFFINE);
|
||||
graphene_vec4_init (&vec4, gsk_point_get_x (p), gsk_point_get_y (p), inv_sx, inv_sy);
|
||||
graphene_vec4_init (&vec4, self->offset.x + dx, self->offset.y + dy, inv_sx, inv_sy);
|
||||
gsk_gpu_pattern_writer_append_vec4 (self, &vec4);
|
||||
self->bounds = gsk_rect_scale (gsk_rect_subtract_offset (self->bounds, p),
|
||||
gsk_scale_init (inv_sx, inv_sy));
|
||||
self->offset = gsk_point_init (0, 0);
|
||||
self->scale = gsk_scale_multiply (gsk_scale_init (fabsf (sx), fabsf (sy)), old_scale);
|
||||
self->bounds.origin.x = (self->bounds.origin.x - self->offset.x - dx) * inv_sx;
|
||||
self->bounds.origin.y = (self->bounds.origin.y - self->offset.y - dy) * inv_sy;
|
||||
self->bounds.size.width *= inv_sx;
|
||||
self->bounds.size.height *= inv_sy;
|
||||
self->offset = GRAPHENE_POINT_INIT (0, 0);
|
||||
graphene_vec2_init (&self->scale, fabs (sx), fabs (sy));
|
||||
graphene_vec2_multiply (&self->scale, &old_scale, &self->scale);
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -1641,9 +1744,9 @@ gsk_gpu_node_processor_create_transform_pattern (GskGpuPatternWriter *self,
|
||||
gsk_gpu_pattern_writer_append_uint (self, GSK_GPU_PATTERN_POSITION_POP);
|
||||
|
||||
gsk_gpu_pattern_writer_pop_stack (self);
|
||||
self->scale = old_scale;
|
||||
self->bounds = old_bounds;
|
||||
self->offset = old_offset;
|
||||
self->scale = old_scale;
|
||||
self->bounds = old_bounds;
|
||||
self->offset = old_offset;
|
||||
|
||||
return result;
|
||||
}
|
||||
@@ -1668,10 +1771,11 @@ gsk_gpu_node_processor_add_color_node (GskGpuNodeProcessor *self,
|
||||
cairo_rectangle_int_t int_clipped;
|
||||
graphene_rect_t rect, clipped;
|
||||
const GdkRGBA *color;
|
||||
GskPoint zero = gsk_point_init (0, 0);
|
||||
|
||||
color = gsk_color_node_get_color (node);
|
||||
rect = gsk_rect_add_offset (node->bounds, self->offset);
|
||||
graphene_rect_offset_r (&node->bounds,
|
||||
self->offset.x, self->offset.y,
|
||||
&rect);
|
||||
gsk_rect_intersection (&self->clip.rect.bounds, &rect, &clipped);
|
||||
|
||||
if (gsk_gpu_frame_should_optimize (self->frame, GSK_GPU_OPTIMIZE_CLEAR) &&
|
||||
@@ -1702,24 +1806,24 @@ gsk_gpu_node_processor_add_color_node (GskGpuNodeProcessor *self,
|
||||
return;
|
||||
}
|
||||
|
||||
scale_x = gsk_scale_get_x (self->scale);
|
||||
scale_y = gsk_scale_get_y (self->scale);
|
||||
scale_x = graphene_vec2_get_x (&self->scale);
|
||||
scale_y = graphene_vec2_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, &zero, &clipped);
|
||||
shader_clip = gsk_gpu_clip_get_shader_clip (&self->clip, graphene_point_zero(), &clipped);
|
||||
if (shader_clip != GSK_GPU_SHADER_CLIP_NONE)
|
||||
{
|
||||
gsk_rounded_rect_get_largest_cover (&self->clip.rect, &clipped, &cover);
|
||||
int_clipped.x = ceilf (cover.origin.x * scale_x);
|
||||
int_clipped.y = ceilf (cover.origin.y * scale_y);
|
||||
int_clipped.width = floorf ((cover.origin.x + cover.size.width) * scale_x) - int_clipped.x;
|
||||
int_clipped.height = floorf ((cover.origin.y + cover.size.height) * scale_y) - int_clipped.y;
|
||||
int_clipped.x = ceil (cover.origin.x * scale_x);
|
||||
int_clipped.y = ceil (cover.origin.y * scale_y);
|
||||
int_clipped.width = floor ((cover.origin.x + cover.size.width) * scale_x) - int_clipped.x;
|
||||
int_clipped.height = floor ((cover.origin.y + cover.size.height) * scale_y) - int_clipped.y;
|
||||
if (int_clipped.width == 0 || int_clipped.height == 0)
|
||||
{
|
||||
gsk_gpu_color_op (self->frame,
|
||||
shader_clip,
|
||||
&clipped,
|
||||
&zero,
|
||||
graphene_point_zero (),
|
||||
color);
|
||||
return;
|
||||
}
|
||||
@@ -1729,13 +1833,13 @@ gsk_gpu_node_processor_add_color_node (GskGpuNodeProcessor *self,
|
||||
gsk_gpu_color_op (self->frame,
|
||||
shader_clip,
|
||||
&GRAPHENE_RECT_INIT (clipped.origin.x, clipped.origin.y, cover.origin.x - clipped.origin.x, clipped.size.height),
|
||||
&zero,
|
||||
graphene_point_zero (),
|
||||
color);
|
||||
if (clipped.origin.y != cover.origin.y)
|
||||
gsk_gpu_color_op (self->frame,
|
||||
shader_clip,
|
||||
&GRAPHENE_RECT_INIT (clipped.origin.x, clipped.origin.y, clipped.size.width, cover.origin.y - clipped.origin.y),
|
||||
&zero,
|
||||
graphene_point_zero (),
|
||||
color);
|
||||
if (clipped.origin.x + clipped.size.width != cover.origin.x + cover.size.width)
|
||||
gsk_gpu_color_op (self->frame,
|
||||
@@ -1744,7 +1848,7 @@ gsk_gpu_node_processor_add_color_node (GskGpuNodeProcessor *self,
|
||||
clipped.origin.y,
|
||||
clipped.origin.x + clipped.size.width - cover.origin.x - cover.size.width,
|
||||
clipped.size.height),
|
||||
&zero,
|
||||
graphene_point_zero (),
|
||||
color);
|
||||
if (clipped.origin.y + clipped.size.height != cover.origin.y + cover.size.height)
|
||||
gsk_gpu_color_op (self->frame,
|
||||
@@ -1753,7 +1857,7 @@ gsk_gpu_node_processor_add_color_node (GskGpuNodeProcessor *self,
|
||||
cover.origin.y + cover.size.height,
|
||||
clipped.size.width,
|
||||
clipped.origin.y + clipped.size.height - cover.origin.y - cover.size.height),
|
||||
&zero,
|
||||
graphene_point_zero (),
|
||||
color);
|
||||
}
|
||||
}
|
||||
@@ -1830,8 +1934,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 * gsk_scale_get_x (self->scale) ||
|
||||
gdk_texture_get_height (texture) > 2 * node->bounds.size.height * gsk_scale_get_y (self->scale)))
|
||||
(gdk_texture_get_width (texture) > 2 * node->bounds.size.width * graphene_vec2_get_x (&self->scale) ||
|
||||
gdk_texture_get_height (texture) > 2 * node->bounds.size.height * graphene_vec2_get_y (&self->scale)))
|
||||
{
|
||||
guint32 descriptor;
|
||||
|
||||
@@ -1897,8 +2001,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 * gsk_scale_get_x (self->scale) ||
|
||||
gdk_texture_get_height (texture) > 2 * node->bounds.size.height * gsk_scale_get_y (self->scale)))
|
||||
(gdk_texture_get_width (texture) > 2 * node->bounds.size.width * graphene_vec2_get_x (&self->scale) ||
|
||||
gdk_texture_get_height (texture) > 2 * node->bounds.size.height * graphene_vec2_get_y (&self->scale)))
|
||||
{
|
||||
image = gsk_gpu_node_processor_ensure_image (self->frame,
|
||||
image,
|
||||
@@ -1941,18 +2045,18 @@ gsk_gpu_node_processor_add_texture_scale_node (GskGpuNodeProcessor *self,
|
||||
guint32 descriptor;
|
||||
gboolean need_mipmap, need_offscreen;
|
||||
|
||||
need_offscreen = self->modelview != NULL || !gsk_scale_is_one (self->scale);
|
||||
need_offscreen = self->modelview != NULL ||
|
||||
!graphene_vec2_equal (&self->scale, graphene_vec2_one ());
|
||||
if (need_offscreen)
|
||||
{
|
||||
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);
|
||||
gsk_rect_round_larger (&clip_bounds);
|
||||
offscreen = gsk_gpu_render_pass_op_offscreen (self->frame,
|
||||
&one,
|
||||
graphene_vec2_one (),
|
||||
&clip_bounds,
|
||||
node);
|
||||
descriptor = gsk_gpu_node_processor_add_image (self, offscreen, GSK_GPU_SAMPLER_DEFAULT);
|
||||
@@ -2148,8 +2252,7 @@ gsk_gpu_node_processor_add_gradient_node (GskGpuNodeProcessor *self,
|
||||
|
||||
if (!gsk_gpu_node_processor_clip_node_bounds (self, node, &bounds))
|
||||
return;
|
||||
|
||||
bounds = gsk_rect_round_to_pixels (bounds, self->scale, self->offset);
|
||||
rect_round_to_pixels (&bounds, &self->scale, &self->offset, &bounds);
|
||||
|
||||
image = gsk_gpu_node_processor_init_draw (&other,
|
||||
self->frame,
|
||||
@@ -2444,7 +2547,8 @@ gsk_gpu_node_processor_add_shadow_node (GskGpuNodeProcessor *self,
|
||||
const GskShadow *shadow = gsk_shadow_node_get_shadow (node, i);
|
||||
if (shadow->radius == 0)
|
||||
{
|
||||
GskPoint shadow_offset = gsk_point_add (self->offset, gsk_point_init (shadow->dx, shadow->dy));
|
||||
graphene_point_t shadow_offset = GRAPHENE_POINT_INIT (self->offset.x + shadow->dx,
|
||||
self->offset.y + shadow->dy);
|
||||
gsk_gpu_colorize_op (self->frame,
|
||||
gsk_gpu_clip_get_shader_clip (&self->clip, &shadow_offset, &child->bounds),
|
||||
desc,
|
||||
@@ -2870,9 +2974,9 @@ gsk_gpu_node_processor_add_glyph_node (GskGpuNodeProcessor *self,
|
||||
GskGpuDevice *device;
|
||||
const PangoGlyphInfo *glyphs;
|
||||
PangoFont *font;
|
||||
GskPoint offset;
|
||||
graphene_point_t offset;
|
||||
guint i, num_glyphs;
|
||||
GskScale scale, inv;
|
||||
float scale, inv_scale;
|
||||
GdkRGBA color;
|
||||
|
||||
if (self->opacity < 1.0 &&
|
||||
@@ -2888,17 +2992,18 @@ gsk_gpu_node_processor_add_glyph_node (GskGpuNodeProcessor *self,
|
||||
num_glyphs = gsk_text_node_get_num_glyphs (node);
|
||||
glyphs = gsk_text_node_get_glyphs (node, NULL);
|
||||
font = gsk_text_node_get_font (node);
|
||||
offset = gsk_point_add (gsk_point_init_from_graphene (gsk_text_node_get_offset (node)), self->offset);
|
||||
offset = *gsk_text_node_get_offset (node);
|
||||
offset.x += self->offset.x;
|
||||
offset.y += self->offset.y;
|
||||
|
||||
scale = gsk_scale_max (self->scale);
|
||||
inv = gsk_scale_invert (scale);
|
||||
scale = MAX (graphene_vec2_get_x (&self->scale), graphene_vec2_get_y (&self->scale));
|
||||
inv_scale = 1.f / scale;
|
||||
|
||||
for (i = 0; i < num_glyphs; i++)
|
||||
{
|
||||
GskGpuImage *image;
|
||||
graphene_rect_t glyph_bounds, glyph_tex_rect;
|
||||
graphene_point_t glyph_offset;
|
||||
GskPoint g_offset;
|
||||
guint32 descriptor;
|
||||
|
||||
image = gsk_gpu_device_lookup_glyph_image (device,
|
||||
@@ -2906,36 +3011,34 @@ gsk_gpu_node_processor_add_glyph_node (GskGpuNodeProcessor *self,
|
||||
font,
|
||||
glyphs[i].glyph,
|
||||
0,
|
||||
gsk_scale_get_x (scale),
|
||||
scale,
|
||||
&glyph_bounds,
|
||||
&glyph_offset);
|
||||
|
||||
glyph_tex_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);
|
||||
glyph_bounds = gsk_rect_scale (GRAPHENE_RECT_INIT (0, 0, glyph_bounds.size.width, glyph_bounds.size.height), inv);
|
||||
g_offset = gsk_point_add (gsk_point_add (offset, gsk_point_divide (gsk_point_init_from_graphene (&glyph_offset), scale)),
|
||||
gsk_point_init (glyphs[i].geometry.x_offset/(float)PANGO_SCALE,
|
||||
glyphs[i].geometry.y_offset/(float)PANGO_SCALE));
|
||||
|
||||
graphene_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_scale, inv_scale, &glyph_tex_rect);
|
||||
graphene_rect_scale (&GRAPHENE_RECT_INIT(0, 0, glyph_bounds.size.width, glyph_bounds.size.height), inv_scale, inv_scale, &glyph_bounds);
|
||||
glyph_offset = GRAPHENE_POINT_INIT (offset.x - glyph_offset.x * inv_scale + (float) glyphs[i].geometry.x_offset / PANGO_SCALE,
|
||||
offset.y - glyph_offset.y * inv_scale + (float) glyphs[i].geometry.y_offset / PANGO_SCALE);
|
||||
descriptor = gsk_gpu_node_processor_add_image (self, image, GSK_GPU_SAMPLER_DEFAULT);
|
||||
if (glyphs[i].attr.is_color)
|
||||
gsk_gpu_texture_op (self->frame,
|
||||
gsk_gpu_clip_get_shader_clip (&self->clip, &g_offset, &glyph_bounds),
|
||||
gsk_gpu_clip_get_shader_clip (&self->clip, &glyph_offset, &glyph_bounds),
|
||||
self->desc,
|
||||
descriptor,
|
||||
&glyph_bounds,
|
||||
&g_offset,
|
||||
&glyph_offset,
|
||||
&glyph_tex_rect);
|
||||
else
|
||||
gsk_gpu_colorize_op (self->frame,
|
||||
gsk_gpu_clip_get_shader_clip (&self->clip, &g_offset, &glyph_bounds),
|
||||
gsk_gpu_clip_get_shader_clip (&self->clip, &glyph_offset, &glyph_bounds),
|
||||
self->desc,
|
||||
descriptor,
|
||||
&glyph_bounds,
|
||||
&g_offset,
|
||||
&glyph_offset,
|
||||
&glyph_tex_rect,
|
||||
&color);
|
||||
|
||||
offset = gsk_point_add (offset, gsk_point_init ((float) glyphs[i].geometry.width / PANGO_SCALE, 0));
|
||||
offset.x += (float) glyphs[i].geometry.width / PANGO_SCALE;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2948,10 +3051,10 @@ gsk_gpu_node_processor_create_glyph_pattern (GskGpuPatternWriter *self,
|
||||
PangoFont *font;
|
||||
guint num_glyphs;
|
||||
gsize i;
|
||||
GskScale scale, inv;
|
||||
float scale, inv_scale;
|
||||
guint32 tex_id;
|
||||
GskGpuImage *last_image;
|
||||
GskPoint offset;
|
||||
graphene_point_t offset;
|
||||
|
||||
if (gsk_text_node_has_color_glyphs (node))
|
||||
return FALSE;
|
||||
@@ -2960,10 +3063,12 @@ gsk_gpu_node_processor_create_glyph_pattern (GskGpuPatternWriter *self,
|
||||
num_glyphs = gsk_text_node_get_num_glyphs (node);
|
||||
glyphs = gsk_text_node_get_glyphs (node, NULL);
|
||||
font = gsk_text_node_get_font (node);
|
||||
offset = gsk_point_add (gsk_point_init_from_graphene (gsk_text_node_get_offset (node)), self->offset);
|
||||
offset = *gsk_text_node_get_offset (node);
|
||||
offset.x += self->offset.x;
|
||||
offset.y += self->offset.y;
|
||||
|
||||
scale = gsk_scale_max (self->scale);
|
||||
inv = gsk_scale_invert (scale);
|
||||
scale = MAX (graphene_vec2_get_x (&self->scale), graphene_vec2_get_y (&self->scale));
|
||||
inv_scale = 1.f / scale;
|
||||
|
||||
gsk_gpu_pattern_writer_append_uint (self, GSK_GPU_PATTERN_GLYPHS);
|
||||
gsk_gpu_pattern_writer_append_rgba (self, gsk_text_node_get_color (node));
|
||||
@@ -2975,15 +3080,13 @@ gsk_gpu_node_processor_create_glyph_pattern (GskGpuPatternWriter *self,
|
||||
GskGpuImage *image;
|
||||
graphene_rect_t glyph_bounds;
|
||||
graphene_point_t glyph_offset;
|
||||
GskPoint g_offset;
|
||||
graphene_rect_t rect;
|
||||
|
||||
image = gsk_gpu_device_lookup_glyph_image (device,
|
||||
self->frame,
|
||||
font,
|
||||
glyphs[i].glyph,
|
||||
0,
|
||||
gsk_scale_get_x (scale),
|
||||
scale,
|
||||
&glyph_bounds,
|
||||
&glyph_offset);
|
||||
|
||||
@@ -2995,22 +3098,28 @@ gsk_gpu_node_processor_create_glyph_pattern (GskGpuPatternWriter *self,
|
||||
last_image = image;
|
||||
}
|
||||
|
||||
g_offset = gsk_point_add (gsk_point_add (offset, gsk_point_divide (gsk_point_init_from_graphene (&glyph_offset), scale)),
|
||||
gsk_point_init (glyphs[i].geometry.x_offset / (float)PANGO_SCALE,
|
||||
glyphs[i].geometry.y_offset / (float)PANGO_SCALE));
|
||||
glyph_offset = GRAPHENE_POINT_INIT (offset.x - glyph_offset.x * inv_scale + (float) glyphs[i].geometry.x_offset / PANGO_SCALE,
|
||||
offset.y - glyph_offset.y * inv_scale + (float) glyphs[i].geometry.y_offset / PANGO_SCALE);
|
||||
|
||||
gsk_gpu_pattern_writer_append_uint (self, tex_id);
|
||||
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, &g_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, &g_offset);
|
||||
gsk_gpu_pattern_writer_append_rect (self,
|
||||
&GRAPHENE_RECT_INIT (
|
||||
0,
|
||||
0,
|
||||
glyph_bounds.size.width * inv_scale,
|
||||
glyph_bounds.size.height * inv_scale
|
||||
),
|
||||
&glyph_offset);
|
||||
gsk_gpu_pattern_writer_append_rect (self,
|
||||
&GRAPHENE_RECT_INIT (
|
||||
- glyph_bounds.origin.x * inv_scale,
|
||||
- glyph_bounds.origin.y * inv_scale,
|
||||
gsk_gpu_image_get_width (image) * inv_scale,
|
||||
gsk_gpu_image_get_height (image) * inv_scale
|
||||
),
|
||||
&glyph_offset);
|
||||
|
||||
offset = gsk_point_add (offset, gsk_point_init ((float) glyphs[i].geometry.width / PANGO_SCALE, 0));
|
||||
offset.x += (float) glyphs[i].geometry.width / PANGO_SCALE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
@@ -3110,10 +3219,10 @@ gsk_gpu_node_processor_repeat_tile (GskGpuNodeProcessor *self,
|
||||
graphene_rect_t clipped_child_bounds, offset_rect;
|
||||
guint32 descriptor;
|
||||
|
||||
offset_rect = gsk_rect_init_offset (*rect,
|
||||
gsk_point_multiply (gsk_point_init (child_bounds->size.width, child_bounds->size.height),
|
||||
gsk_scale_init (-x, -y)));
|
||||
|
||||
gsk_rect_init_offset (&offset_rect,
|
||||
rect,
|
||||
- x * child_bounds->size.width,
|
||||
- y * child_bounds->size.height);
|
||||
if (!gsk_rect_intersection (&offset_rect, child_bounds, &clipped_child_bounds))
|
||||
{
|
||||
/* The math has gone wrong probably, someone should look at this. */
|
||||
@@ -3242,21 +3351,23 @@ gsk_gpu_node_processor_add_repeat_node (GskGpuNodeProcessor *self,
|
||||
else
|
||||
{
|
||||
/* repeat in both directions */
|
||||
GskPoint old_offset, offset;
|
||||
graphene_point_t old_offset, offset;
|
||||
graphene_rect_t clip_bounds;
|
||||
float x, y, offset_x, offset_y;
|
||||
float x, y;
|
||||
|
||||
old_offset = self->offset;
|
||||
|
||||
for (x = floorf (tile_left); x < ceilf (tile_right); x++)
|
||||
{
|
||||
offset_x = x * child_bounds->size.width;
|
||||
offset.x = x * child_bounds->size.width;
|
||||
for (y = floorf (tile_top); y < ceilf (tile_bottom); y++)
|
||||
{
|
||||
offset_y = y * child_bounds->size.height;
|
||||
offset = gsk_point_init (offset_x, offset_y);
|
||||
self->offset = gsk_point_add (old_offset, offset);
|
||||
clip_bounds = gsk_rect_subtract_offset (bounds, offset);
|
||||
offset.y = y * child_bounds->size.height;
|
||||
self->offset = GRAPHENE_POINT_INIT (old_offset.x + offset.x, old_offset.y + offset.y);
|
||||
clip_bounds = GRAPHENE_RECT_INIT (bounds.origin.x - offset.x,
|
||||
bounds.origin.y - offset.y,
|
||||
bounds.size.width,
|
||||
bounds.size.height);
|
||||
if (!gsk_rect_intersection (&clip_bounds, child_bounds, &clip_bounds))
|
||||
continue;
|
||||
gsk_gpu_node_processor_add_node_clipped (self,
|
||||
@@ -3297,7 +3408,10 @@ gsk_gpu_node_processor_create_repeat_pattern (GskGpuPatternWriter *self,
|
||||
gsk_gpu_pattern_writer_append_rect (self, child_bounds, &self->offset);
|
||||
|
||||
old_bounds = self->bounds;
|
||||
self->bounds = gsk_rect_add_offset (*child_bounds, self->offset);
|
||||
self->bounds = GRAPHENE_RECT_INIT (child_bounds->origin.x + self->offset.x,
|
||||
child_bounds->origin.y + self->offset.y,
|
||||
child_bounds->size.width,
|
||||
child_bounds->size.height);
|
||||
|
||||
if (!gsk_gpu_node_processor_create_node_pattern (self, child))
|
||||
{
|
||||
@@ -3369,8 +3483,7 @@ gsk_gpu_node_processor_add_fill_node (GskGpuNodeProcessor *self,
|
||||
|
||||
if (!gsk_gpu_node_processor_clip_node_bounds (self, node, &clip_bounds))
|
||||
return;
|
||||
|
||||
clip_bounds = gsk_rect_round_to_pixels (clip_bounds, self->scale, self->offset);
|
||||
rect_round_to_pixels (&clip_bounds, &self->scale, &self->offset, &clip_bounds);
|
||||
|
||||
child = gsk_fill_node_get_child (node);
|
||||
|
||||
@@ -3467,8 +3580,7 @@ gsk_gpu_node_processor_add_stroke_node (GskGpuNodeProcessor *self,
|
||||
|
||||
if (!gsk_gpu_node_processor_clip_node_bounds (self, node, &clip_bounds))
|
||||
return;
|
||||
|
||||
clip_bounds = gsk_rect_round_to_pixels (clip_bounds, self->scale, self->offset);
|
||||
rect_round_to_pixels (&clip_bounds, &self->scale, &self->offset, &clip_bounds);
|
||||
|
||||
child = gsk_stroke_node_get_child (node);
|
||||
|
||||
@@ -3542,9 +3654,15 @@ gsk_gpu_node_processor_add_subsurface_node (GskGpuNodeProcessor *self,
|
||||
if (!gdk_subsurface_is_above_parent (subsurface))
|
||||
{
|
||||
cairo_rectangle_int_t int_rect;
|
||||
graphene_rect_t r = gsk_rect_add_offset (node->bounds, self->offset);
|
||||
|
||||
if (!gsk_gpu_node_processor_rect_is_integer (self, &r, &int_rect))
|
||||
if (!gsk_gpu_node_processor_rect_is_integer (self,
|
||||
&GRAPHENE_RECT_INIT (
|
||||
node->bounds.origin.x + self->offset.x,
|
||||
node->bounds.origin.y + self->offset.y,
|
||||
node->bounds.size.width,
|
||||
node->bounds.size.height
|
||||
),
|
||||
&int_rect))
|
||||
{
|
||||
g_warning ("FIXME: non-integer aligned subsurface?!");
|
||||
}
|
||||
@@ -3798,7 +3916,6 @@ gsk_gpu_node_processor_add_node (GskGpuNodeProcessor *self,
|
||||
* there's quaranteed to be at least 1 pixel that needs to be drawn */
|
||||
if (node->bounds.size.width == 0 || node->bounds.size.height == 0)
|
||||
return;
|
||||
|
||||
if (!gsk_gpu_clip_may_intersect_rect (&self->clip, &self->offset, &node->bounds))
|
||||
return;
|
||||
|
||||
@@ -3862,9 +3979,15 @@ gsk_gpu_node_processor_create_node_pattern (GskGpuPatternWriter *self,
|
||||
gsk_gpu_descriptors_set_size (self->desc, images_before, buffers_before);
|
||||
}
|
||||
|
||||
bounds = gsk_rect_round_to_pixels (gsk_rect_subtract_offset (self->bounds, self->offset),
|
||||
self->scale,
|
||||
self->offset);
|
||||
rect_round_to_pixels (&GRAPHENE_RECT_INIT (
|
||||
self->bounds.origin.x - self->offset.x,
|
||||
self->bounds.origin.y - self->offset.y,
|
||||
self->bounds.size.width,
|
||||
self->bounds.size.height
|
||||
),
|
||||
&self->scale,
|
||||
&self->offset,
|
||||
&bounds);
|
||||
image = gsk_gpu_get_node_as_image (self->frame,
|
||||
&bounds,
|
||||
&self->scale,
|
||||
|
||||
@@ -66,12 +66,11 @@ gsk_gpu_radial_gradient_op (GskGpuFrame *frame,
|
||||
const graphene_point_t *radius,
|
||||
float start,
|
||||
float end,
|
||||
const GskPoint *offset,
|
||||
const graphene_point_t *offset,
|
||||
const GskColorStop *stops,
|
||||
gsize n_stops)
|
||||
{
|
||||
GskGpuRadialgradientInstance *instance;
|
||||
GskPoint zero = gsk_point_init (0, 0);
|
||||
|
||||
g_assert (n_stops > 1);
|
||||
g_assert (n_stops <= 7);
|
||||
@@ -86,7 +85,7 @@ gsk_gpu_radial_gradient_op (GskGpuFrame *frame,
|
||||
|
||||
gsk_gpu_rect_to_float (rect, offset, instance->rect);
|
||||
gsk_gpu_point_to_float (center, offset, instance->center_radius);
|
||||
gsk_gpu_point_to_float (radius, &zero, &instance->center_radius[2]);
|
||||
gsk_gpu_point_to_float (radius, graphene_point_zero(), &instance->center_radius[2]);
|
||||
instance->startend[0] = start;
|
||||
instance->startend[1] = end;
|
||||
gsk_gpu_rgba_to_float (&stops[MIN (n_stops - 1, 6)].color, instance->color6);
|
||||
|
||||
@@ -16,7 +16,7 @@ void gsk_gpu_radial_gradient_op (GskGpuF
|
||||
const graphene_point_t *radius,
|
||||
float start,
|
||||
float end,
|
||||
const GskPoint *offset,
|
||||
const graphene_point_t *offset,
|
||||
const GskColorStop *stops,
|
||||
gsize n_stops);
|
||||
|
||||
|
||||
@@ -335,16 +335,16 @@ gsk_gpu_render_pass_end_op (GskGpuFrame *frame,
|
||||
}
|
||||
|
||||
GskGpuImage *
|
||||
gsk_gpu_render_pass_op_offscreen (GskGpuFrame *frame,
|
||||
const GskScale *scale,
|
||||
const graphene_rect_t *viewport,
|
||||
GskRenderNode *node)
|
||||
gsk_gpu_render_pass_op_offscreen (GskGpuFrame *frame,
|
||||
const graphene_vec2_t *scale,
|
||||
const graphene_rect_t *viewport,
|
||||
GskRenderNode *node)
|
||||
{
|
||||
GskGpuImage *image;
|
||||
int width, height;
|
||||
|
||||
width = ceil (gsk_scale_get_x (*scale) * viewport->size.width);
|
||||
height = ceil (gsk_scale_get_y (*scale) * viewport->size.height);
|
||||
width = ceil (graphene_vec2_get_x (scale) * viewport->size.width);
|
||||
height = ceil (graphene_vec2_get_y (scale) * viewport->size.height);
|
||||
|
||||
image = gsk_gpu_device_create_offscreen_image (gsk_gpu_frame_get_device (frame),
|
||||
FALSE,
|
||||
|
||||
@@ -6,8 +6,6 @@
|
||||
|
||||
#include <graphene.h>
|
||||
|
||||
#include "gsk/gskscaleprivate.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
/* We only need this for the final VkImageLayout, but don't tell anyone */
|
||||
@@ -26,7 +24,7 @@ void gsk_gpu_render_pass_end_op (GskGpuF
|
||||
GskRenderPassType pass_type);
|
||||
|
||||
GskGpuImage * gsk_gpu_render_pass_op_offscreen (GskGpuFrame *frame,
|
||||
const GskScale *scale,
|
||||
const graphene_vec2_t *scale,
|
||||
const graphene_rect_t *viewport,
|
||||
GskRenderNode *node);
|
||||
|
||||
|
||||
@@ -57,7 +57,7 @@ void
|
||||
gsk_gpu_rounded_color_op (GskGpuFrame *frame,
|
||||
GskGpuShaderClip clip,
|
||||
const GskRoundedRect *outline,
|
||||
const GskPoint *offset,
|
||||
const graphene_point_t *offset,
|
||||
const GdkRGBA *color)
|
||||
{
|
||||
GskGpuRoundedcolorInstance *instance;
|
||||
@@ -69,7 +69,7 @@ gsk_gpu_rounded_color_op (GskGpuFrame *frame,
|
||||
NULL,
|
||||
&instance);
|
||||
|
||||
gsk_gpu_rounded_rect_to_float (outline, offset, instance->outline);
|
||||
gsk_rounded_rect_to_float (outline, offset, instance->outline);
|
||||
gsk_gpu_rgba_to_float (color, instance->color);
|
||||
}
|
||||
|
||||
|
||||
@@ -10,7 +10,7 @@ G_BEGIN_DECLS
|
||||
void gsk_gpu_rounded_color_op (GskGpuFrame *frame,
|
||||
GskGpuShaderClip clip,
|
||||
const GskRoundedRect *outline,
|
||||
const GskPoint *offset,
|
||||
const graphene_point_t *offset,
|
||||
const GdkRGBA *color);
|
||||
|
||||
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
#include "gskgpuopprivate.h"
|
||||
|
||||
#include "gskgputypesprivate.h"
|
||||
#include "gskpointprivate.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
@@ -70,11 +69,11 @@ gsk_gpu_rgba_to_float (const GdkRGBA *rgba,
|
||||
|
||||
static inline void
|
||||
gsk_gpu_point_to_float (const graphene_point_t *point,
|
||||
const GskPoint *offset,
|
||||
const graphene_point_t *offset,
|
||||
float values[2])
|
||||
{
|
||||
values[0] = point->x + gsk_point_get_x (*offset);
|
||||
values[1] = point->y + gsk_point_get_y (*offset);
|
||||
values[0] = point->x + offset->x;
|
||||
values[1] = point->y + offset->y;
|
||||
}
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
@@ -62,7 +62,7 @@ gsk_gpu_straight_alpha_op (GskGpuFrame *frame,
|
||||
GskGpuDescriptors *desc,
|
||||
guint32 descriptor,
|
||||
const graphene_rect_t *rect,
|
||||
const GskPoint *offset,
|
||||
const graphene_point_t *offset,
|
||||
const graphene_rect_t *tex_rect)
|
||||
{
|
||||
GskGpuStraightalphaInstance *instance;
|
||||
|
||||
@@ -12,7 +12,7 @@ void gsk_gpu_straight_alpha_op (GskGpuF
|
||||
GskGpuDescriptors *desc,
|
||||
guint32 descriptor,
|
||||
const graphene_rect_t *rect,
|
||||
const GskPoint *offset,
|
||||
const graphene_point_t *offset,
|
||||
const graphene_rect_t *tex_rect);
|
||||
|
||||
|
||||
|
||||
@@ -58,7 +58,7 @@ gsk_gpu_texture_op (GskGpuFrame *frame,
|
||||
GskGpuDescriptors *desc,
|
||||
guint32 descriptor,
|
||||
const graphene_rect_t *rect,
|
||||
const GskPoint *offset,
|
||||
const graphene_point_t *offset,
|
||||
const graphene_rect_t *tex_rect)
|
||||
{
|
||||
GskGpuTextureInstance *instance;
|
||||
|
||||
@@ -11,7 +11,7 @@ void gsk_gpu_texture_op (GskGpuF
|
||||
GskGpuDescriptors *desc,
|
||||
guint32 descriptor,
|
||||
const graphene_rect_t *rect,
|
||||
const GskPoint *offset,
|
||||
const graphene_point_t *offset,
|
||||
const graphene_rect_t *tex_rect);
|
||||
|
||||
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
|
||||
#include <gdk/gdk.h>
|
||||
#include "gsk/gskenums.h"
|
||||
#include "gsk/gsktypes.h"
|
||||
|
||||
#include "gdk/gdkmemoryformatprivate.h"
|
||||
|
||||
|
||||
@@ -56,7 +56,7 @@ void
|
||||
gsk_gpu_uber_op (GskGpuFrame *frame,
|
||||
GskGpuShaderClip clip,
|
||||
const graphene_rect_t *rect,
|
||||
const GskPoint *offset,
|
||||
const graphene_point_t *offset,
|
||||
GskGpuDescriptors *desc,
|
||||
guint32 pattern_id)
|
||||
{
|
||||
|
||||
@@ -9,7 +9,7 @@ G_BEGIN_DECLS
|
||||
void gsk_gpu_uber_op (GskGpuFrame *frame,
|
||||
GskGpuShaderClip clip,
|
||||
const graphene_rect_t *rect,
|
||||
const GskPoint *offset,
|
||||
const graphene_point_t *offset,
|
||||
GskGpuDescriptors *desc,
|
||||
guint32 pattern_id);
|
||||
|
||||
|
||||
@@ -451,12 +451,12 @@ static const GskGpuOpClass GSK_GPU_UPLOAD_CAIRO_OP_CLASS = {
|
||||
};
|
||||
|
||||
GskGpuImage *
|
||||
gsk_gpu_upload_cairo_op (GskGpuFrame *frame,
|
||||
const GskScale *scale,
|
||||
const graphene_rect_t *viewport,
|
||||
GskGpuCairoFunc func,
|
||||
gpointer user_data,
|
||||
GDestroyNotify user_destroy)
|
||||
gsk_gpu_upload_cairo_op (GskGpuFrame *frame,
|
||||
const graphene_vec2_t *scale,
|
||||
const graphene_rect_t *viewport,
|
||||
GskGpuCairoFunc func,
|
||||
gpointer user_data,
|
||||
GDestroyNotify user_destroy)
|
||||
{
|
||||
GskGpuUploadCairoOp *self;
|
||||
|
||||
@@ -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 (gsk_scale_get_x (*scale) * viewport->size.width),
|
||||
ceil (gsk_scale_get_y (*scale) * viewport->size.height));
|
||||
ceil (graphene_vec2_get_x (scale) * viewport->size.width),
|
||||
ceil (graphene_vec2_get_y (scale) * viewport->size.height));
|
||||
self->viewport = *viewport;
|
||||
self->func = func;
|
||||
self->user_data = user_data;
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
#include "gskgpuopprivate.h"
|
||||
|
||||
#include "gsktypes.h"
|
||||
#include "gsk/gskscaleprivate.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
@@ -15,7 +14,7 @@ GskGpuImage * gsk_gpu_upload_texture_op_try (GskGpuF
|
||||
GdkTexture *texture);
|
||||
|
||||
GskGpuImage * gsk_gpu_upload_cairo_op (GskGpuFrame *frame,
|
||||
const GskScale *scale,
|
||||
const graphene_vec2_t *scale,
|
||||
const graphene_rect_t *viewport,
|
||||
GskGpuCairoFunc func,
|
||||
gpointer user_data,
|
||||
|
||||
@@ -1,157 +1,20 @@
|
||||
#pragma once
|
||||
|
||||
#include "gsktypes.h"
|
||||
#include <graphene.h>
|
||||
#include <math.h>
|
||||
#include <smmintrin.h>
|
||||
|
||||
#include "gskscaleprivate.h"
|
||||
|
||||
struct _GskPoint
|
||||
static inline void G_GNUC_PURE
|
||||
gsk_point_interpolate (const graphene_point_t *p1,
|
||||
const graphene_point_t *p2,
|
||||
float t,
|
||||
graphene_point_t *p)
|
||||
{
|
||||
GRAPHENE_ALIGNED_DECL (graphene_simd4f_t v, 16);
|
||||
};
|
||||
|
||||
static inline float
|
||||
gsk_point_get_x (const GskPoint p)
|
||||
{
|
||||
return graphene_simd4f_get_x (p.v);
|
||||
p->x = p1->x * (1 - t) + p2->x * t;
|
||||
p->Y = p1->y * (1 - t) + p2->y * t;
|
||||
}
|
||||
|
||||
static inline float
|
||||
gsk_point_get_y (const GskPoint p)
|
||||
static inline float G_GNUC_PURE
|
||||
gsk_point_distance (const graphene_point_t *p1,
|
||||
const graphene_point_t *p2)
|
||||
{
|
||||
return graphene_simd4f_get_y (p.v);
|
||||
return sqrtf ((p1->x - p2->x)*(p1->x - p2->x) + (p1->y - p2->y)*(p1->y - p2->y));
|
||||
}
|
||||
|
||||
static inline GskPoint
|
||||
gsk_point_init (float x,
|
||||
float y)
|
||||
{
|
||||
GskPoint p;
|
||||
|
||||
p.v = graphene_simd4f_init (x, y, 0.f, 0.f);
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
static inline GskPoint
|
||||
gsk_point_init_from_graphene (const graphene_point_t *p)
|
||||
{
|
||||
return gsk_point_init (p->x, p->y);
|
||||
}
|
||||
|
||||
static inline void
|
||||
gsk_point_to_float (const GskPoint *p,
|
||||
float v[2])
|
||||
{
|
||||
graphene_simd4f_dup_2f (p->v, v);
|
||||
}
|
||||
|
||||
static inline gboolean
|
||||
gsk_point_is_zero (const GskPoint p)
|
||||
{
|
||||
return gsk_point_get_x (p) == 0 && gsk_point_get_y (p) == 0;
|
||||
}
|
||||
|
||||
static inline GskPoint
|
||||
gsk_point_negate (const GskPoint p)
|
||||
{
|
||||
GskPoint neg;
|
||||
|
||||
neg.v = graphene_simd4f_neg (p.v);
|
||||
|
||||
return neg;
|
||||
}
|
||||
|
||||
static inline GskPoint
|
||||
gsk_point_multiply (const GskPoint p,
|
||||
const GskScale s)
|
||||
{
|
||||
GskPoint q;
|
||||
|
||||
q.v = graphene_simd4f_mul (p.v, s.v);
|
||||
|
||||
return q;
|
||||
}
|
||||
|
||||
static inline GskPoint
|
||||
gsk_point_divide (const GskPoint p,
|
||||
const GskScale s)
|
||||
{
|
||||
GskPoint q;
|
||||
|
||||
q.v = graphene_simd4f_div (p.v, s.v);
|
||||
|
||||
return q;
|
||||
}
|
||||
|
||||
static inline GskPoint
|
||||
gsk_point_add (const GskPoint p1,
|
||||
const GskPoint p2)
|
||||
{
|
||||
GskPoint p;
|
||||
|
||||
p.v = graphene_simd4f_add (p1.v, p2.v);
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
static inline GskPoint
|
||||
gsk_point_subtract (const GskPoint p1,
|
||||
const GskPoint p2)
|
||||
{
|
||||
GskPoint p;
|
||||
|
||||
p.v = graphene_simd4f_sub (p1.v, p2.v);
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
#ifdef HAVE_SSE4
|
||||
|
||||
# define graphene_simd4f_floor(v) \
|
||||
(__extension__ ({ \
|
||||
(graphene_simd4f_t) _mm_floor_ps ((v)); \
|
||||
}))
|
||||
|
||||
# define graphene_simd4f_ceil(v) \
|
||||
(__extension__ ({ \
|
||||
(graphene_simd4f_t) _mm_ceil_ps ((v)); \
|
||||
}))
|
||||
|
||||
static inline GskPoint
|
||||
gsk_point_floor (const GskPoint p)
|
||||
{
|
||||
GskPoint q;
|
||||
|
||||
q.v = graphene_simd4f_floor (p.v);
|
||||
|
||||
return q;
|
||||
}
|
||||
|
||||
static inline GskPoint
|
||||
gsk_point_ceil (const GskPoint p)
|
||||
{
|
||||
GskPoint q;
|
||||
|
||||
q.v = graphene_simd4f_ceil (p.v);
|
||||
|
||||
return q;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
static inline GskPoint
|
||||
gsk_point_floor (const GskPoint p)
|
||||
{
|
||||
return gsk_point_init (floorf (gsk_point_get_x (p)), floorf (gsk_point_get_y (p)));
|
||||
}
|
||||
|
||||
static inline GskPoint
|
||||
gsk_point_ceil (const GskPoint p)
|
||||
{
|
||||
return gsk_point_init (ceilf (gsk_point_get_x (p)), ceilf (gsk_point_get_y (p)));
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -2,9 +2,6 @@
|
||||
|
||||
#include <graphene.h>
|
||||
#include <math.h>
|
||||
#include "gskscaleprivate.h"
|
||||
#include "gskpointprivate.h"
|
||||
|
||||
|
||||
static inline void
|
||||
gsk_rect_init (graphene_rect_t *r,
|
||||
@@ -26,14 +23,13 @@ gsk_rect_init_from_rect (graphene_rect_t *r,
|
||||
gsk_rect_init (r, r1->origin.x, r1->origin.y, r1->size.width, r1->size.height);
|
||||
}
|
||||
|
||||
static inline graphene_rect_t
|
||||
gsk_rect_init_offset (const graphene_rect_t src,
|
||||
const GskPoint offset)
|
||||
static inline void
|
||||
gsk_rect_init_offset (graphene_rect_t *r,
|
||||
const graphene_rect_t *src,
|
||||
float dx,
|
||||
float dy)
|
||||
{
|
||||
return GRAPHENE_RECT_INIT (src.origin.x + gsk_point_get_x (offset),
|
||||
src.origin.y + gsk_point_get_y (offset),
|
||||
src.size.width,
|
||||
src.size.height);
|
||||
gsk_rect_init (r, src->origin.x + dx, src->origin.y + dy, src->size.width, src->size.height);
|
||||
}
|
||||
|
||||
static inline gboolean G_GNUC_PURE
|
||||
@@ -117,98 +113,22 @@ gsk_rect_equal (const graphene_rect_t *r1,
|
||||
|
||||
static inline void
|
||||
gsk_gpu_rect_to_float (const graphene_rect_t *rect,
|
||||
const GskPoint *offset,
|
||||
const graphene_point_t *offset,
|
||||
float values[4])
|
||||
{
|
||||
values[0] = rect->origin.x + gsk_point_get_x (*offset);
|
||||
values[1] = rect->origin.y + gsk_point_get_y (*offset);
|
||||
values[0] = rect->origin.x + offset->x;
|
||||
values[1] = rect->origin.y + offset->y;
|
||||
values[2] = rect->size.width;
|
||||
values[3] = rect->size.height;
|
||||
}
|
||||
|
||||
static inline graphene_rect_t
|
||||
gsk_rect_round_larger (const graphene_rect_t rect)
|
||||
static inline void
|
||||
gsk_rect_round_larger (graphene_rect_t *rect)
|
||||
{
|
||||
float x = floorf (rect.origin.x);
|
||||
float y = floorf (rect.origin.y);
|
||||
|
||||
return GRAPHENE_RECT_INIT (x, y,
|
||||
ceilf (rect.origin.x + rect.size.width) - x,
|
||||
ceilf (rect.origin.y + rect.size.height) - y);
|
||||
float x = floor (rect->origin.x);
|
||||
float y = floor (rect->origin.y);
|
||||
*rect = GRAPHENE_RECT_INIT (x, y,
|
||||
ceil (rect->origin.x + rect->size.width) - x,
|
||||
ceil (rect->origin.y + rect->size.height) - y);
|
||||
}
|
||||
|
||||
static inline graphene_rect_t
|
||||
gsk_rect_scale (const graphene_rect_t r,
|
||||
const GskScale scale)
|
||||
{
|
||||
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, sx, sy, &res);
|
||||
return res;
|
||||
}
|
||||
|
||||
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
|
||||
gsk_rect_add_offset (const graphene_rect_t r,
|
||||
const GskPoint offset)
|
||||
{
|
||||
return GRAPHENE_RECT_INIT (r.origin.x + gsk_point_get_x (offset),
|
||||
r.origin.y + gsk_point_get_y (offset),
|
||||
r.size.width,
|
||||
r.size.height);
|
||||
}
|
||||
|
||||
static inline graphene_rect_t
|
||||
gsk_rect_subtract_offset (const graphene_rect_t r,
|
||||
const GskPoint offset)
|
||||
{
|
||||
return GRAPHENE_RECT_INIT (r.origin.x - gsk_point_get_x (offset),
|
||||
r.origin.y - gsk_point_get_y (offset),
|
||||
r.size.width,
|
||||
r.size.height);
|
||||
}
|
||||
|
||||
static inline graphene_rect_t
|
||||
gsk_rect_from_points (GskPoint p0,
|
||||
GskPoint p1)
|
||||
{
|
||||
return GRAPHENE_RECT_INIT (gsk_point_get_x (p0),
|
||||
gsk_point_get_y (p0),
|
||||
gsk_point_get_x (p1) - gsk_point_get_x (p0),
|
||||
gsk_point_get_y (p1) - gsk_point_get_y (p0));
|
||||
}
|
||||
|
||||
static inline GskPoint
|
||||
gsk_rect_get_origin (const graphene_rect_t rect)
|
||||
{
|
||||
return gsk_point_init (rect.origin.x, rect.origin.y);
|
||||
}
|
||||
|
||||
static inline GskPoint
|
||||
gsk_rect_get_opposite (const graphene_rect_t rect)
|
||||
{
|
||||
return gsk_point_init (rect.origin.x + rect.size.width, rect.origin.y + rect.size.height);
|
||||
}
|
||||
|
||||
static inline graphene_rect_t
|
||||
gsk_rect_round_to_pixels (const graphene_rect_t src,
|
||||
const GskScale scale,
|
||||
const GskPoint offset)
|
||||
{
|
||||
GskPoint p0, p1;
|
||||
|
||||
p0 = gsk_point_subtract (gsk_point_divide (gsk_point_floor (gsk_point_multiply (gsk_point_add (gsk_rect_get_origin (src), offset), scale)), scale), offset);
|
||||
|
||||
p1 = gsk_point_divide (gsk_point_subtract (gsk_point_ceil (gsk_point_multiply (gsk_point_add (gsk_rect_get_opposite (src), offset), scale)), p0), scale);
|
||||
|
||||
return gsk_rect_from_points (p0, p1);
|
||||
}
|
||||
|
||||
@@ -311,8 +311,8 @@ gsk_rounded_rect_scale_affine (GskRoundedRect *dest,
|
||||
graphene_rect_scale (&src->bounds, scale_x, scale_y, &dest->bounds);
|
||||
graphene_rect_offset (&dest->bounds, dx, dy);
|
||||
|
||||
scale_x = fabsf (scale_x);
|
||||
scale_y = fabsf (scale_y);
|
||||
scale_x = fabs (scale_x);
|
||||
scale_y = fabs (scale_y);
|
||||
|
||||
for (guint i = 0; i < 4; i++)
|
||||
{
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
#pragma once
|
||||
|
||||
#include "gskroundedrect.h"
|
||||
#include "gskrectprivate.h"
|
||||
|
||||
#include <cairo.h>
|
||||
|
||||
@@ -49,21 +48,6 @@ void gsk_rounded_rect_path (const GskRounde
|
||||
void gsk_rounded_rect_to_float (const GskRoundedRect *self,
|
||||
const graphene_point_t *offset,
|
||||
float rect[12]);
|
||||
static inline void
|
||||
gsk_gpu_rounded_rect_to_float (const GskRoundedRect *self,
|
||||
const GskPoint *offset,
|
||||
float rect[12])
|
||||
{
|
||||
guint i;
|
||||
|
||||
gsk_gpu_rect_to_float (&self->bounds, offset, rect);
|
||||
|
||||
for (i = 0; i < 4; i++)
|
||||
{
|
||||
rect[4 + i] = self->corner[i].width;
|
||||
rect[8 + i] = self->corner[i].height;
|
||||
}
|
||||
}
|
||||
|
||||
gboolean gsk_rounded_rect_equal (gconstpointer rect1,
|
||||
gconstpointer rect2) G_GNUC_PURE;
|
||||
|
||||
@@ -1,59 +0,0 @@
|
||||
#include "config.h"
|
||||
#include "gskscaleprivate.h"
|
||||
#include "gsktransform.h"
|
||||
|
||||
GskScale
|
||||
gsk_scale_extract_from_transform (GskTransform *transform)
|
||||
{
|
||||
switch (gsk_transform_get_category (transform))
|
||||
{
|
||||
default:
|
||||
g_assert_not_reached ();
|
||||
G_GNUC_FALLTHROUGH;
|
||||
|
||||
case GSK_TRANSFORM_CATEGORY_IDENTITY:
|
||||
case GSK_TRANSFORM_CATEGORY_2D_TRANSLATE:
|
||||
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);
|
||||
return gsk_scale_init (fabsf (scale_x), fabsf (scale_y));
|
||||
}
|
||||
|
||||
case GSK_TRANSFORM_CATEGORY_2D:
|
||||
{
|
||||
float skew_x, skew_y, scale_x, scale_y, angle, dx, dy;
|
||||
gsk_transform_to_2d_components (transform,
|
||||
&skew_x, &skew_y,
|
||||
&scale_x, &scale_y,
|
||||
&angle,
|
||||
&dx, &dy);
|
||||
return gsk_scale_init (fabsf (scale_x), fabsf (scale_y));
|
||||
}
|
||||
|
||||
case GSK_TRANSFORM_CATEGORY_UNKNOWN:
|
||||
case GSK_TRANSFORM_CATEGORY_ANY:
|
||||
case GSK_TRANSFORM_CATEGORY_3D:
|
||||
{
|
||||
graphene_quaternion_t rotation;
|
||||
graphene_matrix_t matrix;
|
||||
graphene_vec4_t perspective;
|
||||
graphene_vec3_t translation;
|
||||
graphene_vec3_t matrix_scale;
|
||||
graphene_vec3_t shear;
|
||||
|
||||
gsk_transform_to_matrix (transform, &matrix);
|
||||
graphene_matrix_decompose (&matrix,
|
||||
&translation,
|
||||
&matrix_scale,
|
||||
&rotation,
|
||||
&shear,
|
||||
&perspective);
|
||||
|
||||
return gsk_scale_init (fabsf (graphene_vec3_get_x (&matrix_scale)),
|
||||
fabsf (graphene_vec3_get_y (&matrix_scale)));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,108 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include "gsktypes.h"
|
||||
#include <graphene.h>
|
||||
#include <math.h>
|
||||
|
||||
struct _GskScale
|
||||
{
|
||||
GRAPHENE_ALIGNED_DECL (graphene_simd4f_t v, 16);
|
||||
};
|
||||
|
||||
static inline float
|
||||
gsk_scale_get_x (const GskScale s)
|
||||
{
|
||||
return graphene_simd4f_get_x (s.v);
|
||||
}
|
||||
|
||||
static inline float
|
||||
gsk_scale_get_y (const GskScale s)
|
||||
{
|
||||
return graphene_simd4f_get_y (s.v);
|
||||
}
|
||||
|
||||
static inline GskScale
|
||||
gsk_scale_init (float x,
|
||||
float y)
|
||||
{
|
||||
GskScale s;
|
||||
|
||||
s.v = graphene_simd4f_init (x, y, 0.f, 0.f);
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
static inline GskScale
|
||||
gsk_scale_init_uniform (float x)
|
||||
{
|
||||
return gsk_scale_init (x, x);
|
||||
}
|
||||
|
||||
static inline void
|
||||
gsk_scale_to_float (const GskScale *s,
|
||||
float v[2])
|
||||
{
|
||||
graphene_simd4f_dup_2f (s->v, v);
|
||||
}
|
||||
|
||||
static inline gboolean
|
||||
gsk_scale_is_one (const GskScale s)
|
||||
{
|
||||
return gsk_scale_get_x (s) == 1 && gsk_scale_get_y (s) == 1;
|
||||
}
|
||||
|
||||
static inline gboolean
|
||||
gsk_scale_is_uniform (const GskScale s)
|
||||
{
|
||||
return gsk_scale_get_x (s) == gsk_scale_get_y (s);
|
||||
}
|
||||
|
||||
static inline GskScale
|
||||
gsk_scale_invert (const GskScale s)
|
||||
{
|
||||
GskScale inv;
|
||||
|
||||
inv.v = graphene_simd4f_reciprocal (s.v);
|
||||
|
||||
return inv;
|
||||
}
|
||||
|
||||
static inline GskScale
|
||||
gsk_scale_multiply (const GskScale s1,
|
||||
const GskScale s2)
|
||||
{
|
||||
GskScale s;
|
||||
|
||||
s.v = graphene_simd4f_mul (s1.v, s2.v);
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
static inline GskScale
|
||||
gsk_scale_divide (const GskScale s1,
|
||||
const GskScale s2)
|
||||
{
|
||||
GskScale s;
|
||||
|
||||
s.v = graphene_simd4f_div (s1.v, s2.v);
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
# 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 s)
|
||||
{
|
||||
GskScale m;
|
||||
|
||||
m.v = graphene_simd4f_max (graphene_simd4f_shuffle_yxzw (s.v), s.v);
|
||||
|
||||
return m;
|
||||
}
|
||||
|
||||
GskScale gsk_scale_extract_from_transform (GskTransform *transform);
|
||||
@@ -34,5 +34,4 @@ typedef struct _GskRenderNode GskRenderNode;
|
||||
typedef struct _GskRoundedRect GskRoundedRect;
|
||||
typedef struct _GskStroke GskStroke;
|
||||
typedef struct _GskTransform GskTransform;
|
||||
typedef struct _GskScale GskScale;
|
||||
typedef struct _GskPoint GskPoint;
|
||||
|
||||
|
||||
@@ -51,7 +51,6 @@ gsk_private_sources = files([
|
||||
'gskdebug.c',
|
||||
'gskprivate.c',
|
||||
'gskprofiler.c',
|
||||
'gskscale.c',
|
||||
'gl/gskglattachmentstate.c',
|
||||
'gl/gskglbuffer.c',
|
||||
'gl/gskglcommandqueue.c',
|
||||
|
||||
@@ -403,7 +403,7 @@ gtk_file_chooser_set_current_folder (GtkFileChooser *chooser,
|
||||
GError **error)
|
||||
{
|
||||
g_return_val_if_fail (GTK_IS_FILE_CHOOSER (chooser), FALSE);
|
||||
g_return_val_if_fail (file == NULL || G_IS_FILE (file), FALSE);
|
||||
g_return_val_if_fail (G_IS_FILE (file), FALSE);
|
||||
g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
|
||||
|
||||
return GTK_FILE_CHOOSER_GET_IFACE (chooser)->set_current_folder (chooser, file, error);
|
||||
|
||||
@@ -44,15 +44,6 @@ void gtk_graphics_offload_set_child (GtkGraphicsOffload *
|
||||
GDK_AVAILABLE_IN_4_14
|
||||
GtkWidget * gtk_graphics_offload_get_child (GtkGraphicsOffload *self);
|
||||
|
||||
/**
|
||||
* GtkGraphicsOffloadEnabled:
|
||||
* @GTK_GRAPHICS_OFFLOAD_ENABLED: Graphics offloading is enabled.
|
||||
* @GTK_GRAPHICS_OFFLOAD_DISABLED: Graphics offloading is disabled.
|
||||
*
|
||||
* Represents the state of graphics offlodading.
|
||||
*
|
||||
* Since: 4.14
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
GTK_GRAPHICS_OFFLOAD_ENABLED,
|
||||
|
||||
@@ -159,7 +159,7 @@
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkCheckButton" id="verbose">
|
||||
<object class="GtkCheckButton" id="verboe">
|
||||
<property name="label">Verbose</property>
|
||||
<signal name="toggled" handler="flag_toggled"/>
|
||||
</object>
|
||||
|
||||
40
po/ru.po
40
po/ru.po
@@ -22,8 +22,8 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: gtk+.master\n"
|
||||
"Report-Msgid-Bugs-To: https://gitlab.gnome.org/GNOME/gtk/-/issues/\n"
|
||||
"POT-Creation-Date: 2024-01-16 17:25+0000\n"
|
||||
"PO-Revision-Date: 2024-01-16 22:49+0300\n"
|
||||
"POT-Creation-Date: 2024-01-08 02:46+0000\n"
|
||||
"PO-Revision-Date: 2024-01-08 15:00+0300\n"
|
||||
"Last-Translator: Artur So <arturios2005@mail.ru>\n"
|
||||
"Language-Team: Русский <gnome-cyr@gnome.org>\n"
|
||||
"Language: ru\n"
|
||||
@@ -867,11 +867,6 @@ msgid "This GLES %d.%d implementation does not support half-float vertex data"
|
||||
msgstr ""
|
||||
"Данная реализация GLES %d.%d не поддерживает полуплавающие вершинные данные"
|
||||
|
||||
#: gsk/gpu/gskgldevice.c:238
|
||||
#, c-format
|
||||
msgid "OpenGL ES 2.0 is not supported by this renderer."
|
||||
msgstr "OpenGL ES 2.0 не поддерживается этим рендерером."
|
||||
|
||||
#: gtk/a11y/gtkatspiaction.c:239
|
||||
msgctxt "accessibility"
|
||||
msgid "Click"
|
||||
@@ -2690,7 +2685,7 @@ msgstr "Вариации стилей"
|
||||
msgid "Character Variations"
|
||||
msgstr "Вариации символов"
|
||||
|
||||
#: gtk/gtkglarea.c:309
|
||||
#: gtk/gtkglarea.c:305
|
||||
msgid "OpenGL context creation failed"
|
||||
msgstr "Не удалось создать контекст OpenGL"
|
||||
|
||||
@@ -7308,7 +7303,7 @@ msgid "Use style from CSS file"
|
||||
msgstr "Использовать стиль из файла CSS"
|
||||
|
||||
#: tools/gtk-builder-tool-preview.c:187 tools/gtk-builder-tool-screenshot.c:370
|
||||
#: tools/gtk-builder-tool-validate.c:268 tools/gtk-rendernode-tool-render.c:203
|
||||
#: tools/gtk-builder-tool-validate.c:268 tools/gtk-rendernode-tool-render.c:204
|
||||
#: tools/gtk-rendernode-tool-show.c:113
|
||||
#, c-format
|
||||
msgid "Could not initialize windowing system\n"
|
||||
@@ -7354,13 +7349,13 @@ msgstr ""
|
||||
"Используйте --force для перезаписи.\n"
|
||||
|
||||
#: tools/gtk-builder-tool-screenshot.c:332
|
||||
#: tools/gtk-rendernode-tool-render.c:171
|
||||
#: tools/gtk-rendernode-tool-render.c:172
|
||||
#, c-format
|
||||
msgid "Output written to %s.\n"
|
||||
msgstr "Выход записывается в %s.\n"
|
||||
|
||||
#: tools/gtk-builder-tool-screenshot.c:336
|
||||
#: tools/gtk-rendernode-tool-render.c:175
|
||||
#: tools/gtk-rendernode-tool-render.c:176
|
||||
#, c-format
|
||||
msgid "Failed to save %s: %s\n"
|
||||
msgstr "Не удалось сохранить %s: %s\n"
|
||||
@@ -7378,7 +7373,7 @@ msgid "Overwrite existing file"
|
||||
msgstr "Перезаписать существующий файл"
|
||||
|
||||
#: tools/gtk-builder-tool-screenshot.c:363
|
||||
#: tools/gtk-rendernode-tool-render.c:196
|
||||
#: tools/gtk-rendernode-tool-render.c:197
|
||||
msgid "FILE…"
|
||||
msgstr "ФАЙЛ…"
|
||||
|
||||
@@ -7849,7 +7844,6 @@ msgid ""
|
||||
"Perform various tasks on GTK render nodes.\n"
|
||||
"\n"
|
||||
"Commands:\n"
|
||||
" benchmark Benchmark rendering of a node\n"
|
||||
" info Provide information about the node\n"
|
||||
" show Show the node\n"
|
||||
" render Take a screenshot of the node\n"
|
||||
@@ -7861,7 +7855,6 @@ msgstr ""
|
||||
"Выполнение различных задач на узлах рендеринга GTK.\n"
|
||||
"\n"
|
||||
"Команды:\n"
|
||||
" benchmark Тест рендеринга узла\n"
|
||||
" info Предоставить информацию об узле\n"
|
||||
" show Показать узел\n"
|
||||
" render Сделать снимок узла\n"
|
||||
@@ -7891,7 +7884,7 @@ msgstr "Источник: %g %g\n"
|
||||
msgid "Provide information about the render node."
|
||||
msgstr "Предоставить информацию об узле рендеринга."
|
||||
|
||||
#: tools/gtk-rendernode-tool-info.c:236 tools/gtk-rendernode-tool-render.c:224
|
||||
#: tools/gtk-rendernode-tool-info.c:236 tools/gtk-rendernode-tool-render.c:225
|
||||
#: tools/gtk-rendernode-tool-show.c:134
|
||||
#, c-format
|
||||
msgid "No .node file specified\n"
|
||||
@@ -7916,24 +7909,19 @@ msgstr ""
|
||||
msgid "Failed to generate SVG: %s\n"
|
||||
msgstr "Не удалось сгенерировать SVG: %s\n"
|
||||
|
||||
#: tools/gtk-rendernode-tool-render.c:150
|
||||
#, c-format
|
||||
msgid "Failed to create renderer: %s\n"
|
||||
msgstr "Не удалось создать рендерер: %s\n"
|
||||
|
||||
#: tools/gtk-rendernode-tool-render.c:195
|
||||
#: tools/gtk-rendernode-tool-render.c:196
|
||||
msgid "Renderer to use"
|
||||
msgstr "Используемый рендерер"
|
||||
|
||||
#: tools/gtk-rendernode-tool-render.c:195
|
||||
#: tools/gtk-rendernode-tool-render.c:196
|
||||
msgid "RENDERER"
|
||||
msgstr "РЕНДЕРЕР"
|
||||
|
||||
#: tools/gtk-rendernode-tool-render.c:211
|
||||
#: tools/gtk-rendernode-tool-render.c:212
|
||||
msgid "Render a .node file to an image."
|
||||
msgstr "Преобразование .node файла в изображение."
|
||||
|
||||
#: tools/gtk-rendernode-tool-render.c:230
|
||||
#: tools/gtk-rendernode-tool-render.c:231
|
||||
#, c-format
|
||||
msgid "Can only render a single .node file to a single output file\n"
|
||||
msgstr "Можно вывести только один файл .node в один выходной файл\n"
|
||||
@@ -7951,12 +7939,12 @@ msgstr "Показать узел рендеринга."
|
||||
msgid "Can only preview a single .node file\n"
|
||||
msgstr "Можно предварительно просмотреть только один .node файл\n"
|
||||
|
||||
#: tools/gtk-rendernode-tool-utils.c:54
|
||||
#: tools/gtk-rendernode-tool-utils.c:51
|
||||
#, c-format
|
||||
msgid "Error at %s: %s\n"
|
||||
msgstr "Ошибка в %s: %s\n"
|
||||
|
||||
#: tools/gtk-rendernode-tool-utils.c:72
|
||||
#: tools/gtk-rendernode-tool-utils.c:69
|
||||
#, c-format
|
||||
msgid "Failed to load node file: %s\n"
|
||||
msgstr "Не удалось загрузить node файл: %s\n"
|
||||
|
||||
Reference in New Issue
Block a user