[gtk/ngl-clip-stats] wip: Classify clips and produce stats
- From: Matthias Clasen <matthiasc src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk/ngl-clip-stats] wip: Classify clips and produce stats
- Date: Sun, 7 Mar 2021 15:03:44 +0000 (UTC)
commit a4676e1109eb9899f427e69e3cfffce0ac4474c5
Author: Matthias Clasen <mclasen redhat com>
Date: Sun Mar 7 10:02:46 2021 -0500
wip: Classify clips and produce stats
This is in preparation for avoiding clipping in
shaders if we don't need to.
gsk/ngl/gsknglrenderer.c | 4 ++
gsk/ngl/gsknglrenderjob.c | 100 ++++++++++++++++++++++++++++++++++++++++++++--
2 files changed, 101 insertions(+), 3 deletions(-)
---
diff --git a/gsk/ngl/gsknglrenderer.c b/gsk/ngl/gsknglrenderer.c
index c20660f09e..a4c9b983fe 100644
--- a/gsk/ngl/gsknglrenderer.c
+++ b/gsk/ngl/gsknglrenderer.c
@@ -277,6 +277,8 @@ gsk_ngl_renderer_dispose (GObject *object)
G_OBJECT_CLASS (gsk_ngl_renderer_parent_class)->dispose (object);
}
+extern void dump_clip_stats (void);
+
static void
gsk_ngl_renderer_class_init (GskNglRendererClass *klass)
{
@@ -289,6 +291,8 @@ gsk_ngl_renderer_class_init (GskNglRendererClass *klass)
renderer_class->unrealize = gsk_ngl_renderer_unrealize;
renderer_class->render = gsk_ngl_renderer_render;
renderer_class->render_texture = gsk_ngl_renderer_render_texture;
+
+ g_atexit (dump_clip_stats);
}
static void
diff --git a/gsk/ngl/gsknglrenderjob.c b/gsk/ngl/gsknglrenderjob.c
index b8f983f862..12d67e036a 100644
--- a/gsk/ngl/gsknglrenderjob.c
+++ b/gsk/ngl/gsknglrenderjob.c
@@ -742,13 +742,107 @@ gsk_ngl_render_job_transform_rounded_rect (GskNglRenderJob *job,
memcpy (out_rect->corner, rect->corner, sizeof rect->corner);
}
+typedef enum {
+ CLIP_ALL_CLIPPED,
+ CLIP_NONE,
+ CLIP_RECT,
+ CLIP_ROUNDED
+} ClipComplexity;
+
+static inline void
+rounded_rect_get_inner (const GskRoundedRect *rect,
+ graphene_rect_t *inner)
+{
+ float left = MAX (rect->corner[GSK_CORNER_TOP_LEFT].width, rect->corner[GSK_CORNER_BOTTOM_LEFT].width);
+ float right = MAX (rect->corner[GSK_CORNER_TOP_RIGHT].width, rect->corner[GSK_CORNER_BOTTOM_RIGHT].width);
+ float top = MAX (rect->corner[GSK_CORNER_TOP_LEFT].height, rect->corner[GSK_CORNER_TOP_RIGHT].height);
+ float bottom = MAX (rect->corner[GSK_CORNER_BOTTOM_LEFT].height,
rect->corner[GSK_CORNER_BOTTOM_RIGHT].height);
+
+ inner->origin.x = rect->bounds.origin.x + left;
+ inner->size.width = rect->bounds.size.width - (left + right);
+
+ inner->origin.y = rect->bounds.origin.y + top;
+ inner->size.height = rect->bounds.size.height - (top + bottom);
+}
+
static inline gboolean
-gsk_ngl_render_job_node_overlaps_clip (GskNglRenderJob *job,
- const GskRenderNode *node)
+interval_contains (float p1, float w1,
+ float p2, float w2)
+{
+ if (p2 < p1)
+ return FALSE;
+
+ if (p2 + w2 > p1 + w1)
+ return FALSE;
+
+ return TRUE;
+}
+
+static ClipComplexity
+classify_clip (GskNglRenderJob *job,
+ const GskRenderNode *node)
{
graphene_rect_t transformed_bounds;
+ graphene_rect_t inner;
+
gsk_ngl_render_job_transform_bounds (job, &node->bounds, &transformed_bounds);
- return rect_intersects (&job->current_clip->rect.bounds, &transformed_bounds);
+
+ if (!rect_intersects (&job->current_clip->rect.bounds, &transformed_bounds))
+ return CLIP_ALL_CLIPPED;
+
+ if (job->current_clip->is_rectilinear)
+ {
+ if (rect_contains_rect (&job->current_clip->rect.bounds, &transformed_bounds))
+ return CLIP_NONE;
+
+ return CLIP_RECT;
+ }
+
+ if (gsk_rounded_rect_contains_rect (&job->current_clip->rect, &transformed_bounds))
+ return CLIP_NONE;
+
+ rounded_rect_get_inner (&job->current_clip->rect, &inner);
+
+ if (interval_contains (inner.origin.x, inner.size.width,
+ transformed_bounds.origin.x, transformed_bounds.size.width))
+ return CLIP_RECT;
+
+ if (interval_contains (inner.origin.y, inner.size.height,
+ transformed_bounds.origin.y, transformed_bounds.size.height))
+ return CLIP_RECT;
+
+ return CLIP_ROUNDED;
+}
+
+static guint64 total_clips;
+static guint64 clips[CLIP_ROUNDED+1];
+
+void dump_clip_stats (void);
+
+void
+dump_clip_stats (void)
+{
+ g_print ("%.2f%% outside\n", clips[CLIP_ALL_CLIPPED] * 100.0 / (double) (total_clips));
+ g_print ("%.2f%% inside\n", clips[CLIP_NONE] * 100.0 / (double) (total_clips));
+ g_print ("%.2f%% rect clip\n", clips[CLIP_RECT] * 100.0 / (double) (total_clips));
+ g_print ("%.2f%% round clip\n", clips[CLIP_ROUNDED] * 100.0 / (double) (total_clips));
+}
+
+static inline gboolean
+gsk_ngl_render_job_node_overlaps_clip (GskNglRenderJob *job,
+ const GskRenderNode *node)
+{
+ ClipComplexity c;
+
+ c = classify_clip (job, node);
+
+ total_clips++;
+ clips[c]++;
+
+ if (c == CLIP_ALL_CLIPPED)
+ return FALSE;
+
+ return TRUE;
}
/* load_vertex_data_with_region */
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]