summaryrefslogtreecommitdiff
path: root/src/tests/clutter/performance/test-common.h
blob: ef90ce10996cd05408ad385bf95858e2b2da38b0 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
#include <stdlib.h>
#include <glib.h>
#include <clutter/clutter.h>
#include <clutter/clutter-mutter.h>

#include "tests/clutter-test-utils.h"

static GTimer *testtimer = NULL;
static gint testframes = 0;
static float testmaxtime = 1.0;

/* initialize environment to be suitable for fps testing */
static inline void
clutter_perf_fps_init (void)
{
  /* Force not syncing to vblank, we want free-running maximum FPS */
  g_setenv ("vblank_mode", "0", FALSE);
  g_setenv ("CLUTTER_VBLANK", "none", FALSE);

  /* also override internal default FPS */
  g_setenv ("CLUTTER_DEFAULT_FPS", "1000", FALSE);

  if (g_getenv ("CLUTTER_PERFORMANCE_TEST_DURATION"))
    testmaxtime = atof(g_getenv("CLUTTER_PERFORMANCE_TEST_DURATION"));
  else
    testmaxtime = 10.0;

  g_random_set_seed (12345678);
}

static void perf_stage_after_paint_cb (ClutterStage        *stage,
                                       ClutterPaintContext *paint_context,
                                       gpointer            *data);
static gboolean perf_fake_mouse_cb (gpointer stage);

static inline void
clutter_perf_fps_start (ClutterStage *stage)
{
  g_signal_connect (stage, "after-paint", G_CALLBACK (perf_stage_after_paint_cb), NULL);
}

static inline void
clutter_perf_fake_mouse (ClutterStage *stage)
{
  clutter_threads_add_timeout (1000/60, perf_fake_mouse_cb, stage);
}

static inline void
clutter_perf_fps_report (const gchar *id)
{
  g_print ("\n@ %s: %.2f fps \n",
       id, testframes / g_timer_elapsed (testtimer, NULL));
}

static void
perf_stage_after_paint_cb (ClutterStage        *stage,
                           ClutterPaintContext *paint_context,
                           gpointer            *data)
{
  if (!testtimer)
    testtimer = g_timer_new ();
  testframes ++;
  if (g_timer_elapsed (testtimer, NULL) > testmaxtime)
    {
      clutter_test_quit ();
    }
}

static void wrap (gfloat *value, gfloat min, gfloat max)
{
  if (*value > max)
    *value = min;
  else if (*value < min)
    *value = max;
}

static gboolean perf_fake_mouse_cb (gpointer stage)
{
  ClutterEvent *event = clutter_event_new (CLUTTER_MOTION);
  static ClutterInputDevice *device = NULL;
  int i;
  static float x = 0.0;
  static float y = 0.0;
  static float xd = 0.0;
  static float yd = 0.0;
  static gboolean inited = FALSE;

  gfloat w, h;

  if (!inited) /* XXX:
                  force clutter to do handle our motion events,
                  by forcibly updating the input device's state
                  this should be possible to do in a better
                  manner in the future, a versioning check
                  will have to be added when this is possible
                  without a hack... and the means to do the
                  hack is deprecated
                */
    {
      ClutterEvent *event2 = clutter_event_new (CLUTTER_ENTER);
      ClutterBackend *backend = clutter_get_default_backend ();
      ClutterSeat *seat = clutter_backend_get_default_seat (backend);

      device = clutter_seat_get_pointer (seat);

      event2->crossing.stage = stage;
      event2->crossing.source = stage;
      event2->crossing.x = 10;
      event2->crossing.y = 10;
      event2->crossing.related = NULL;

      clutter_event_set_device (event2, device);
      clutter_input_device_update_from_event (device, event2);

      clutter_event_put (event2);
      clutter_event_free (event2);
      inited = TRUE;
    }

  clutter_actor_get_size (stage, &w, &h);
  event->motion.stage = stage;
  clutter_event_set_device (event, device);

  /* called about every 60fps, and do 10 picks per stage */
  for (i = 0; i < 10; i++)
    {
      event->motion.x = x;
      event->motion.y = y;

      clutter_event_put (event);

      x += xd;
      y += yd;
      xd += g_random_double_range (-0.1, 0.1);
      yd += g_random_double_range (-0.1, 0.1);

      wrap (&x, 0, w);
      wrap (&y, 0, h);

      xd = CLAMP(xd, -1.3, 1.3);
      yd = CLAMP(yd, -1.3, 1.3);
    }
  clutter_event_free (event);
  return G_SOURCE_CONTINUE;
}