summaryrefslogtreecommitdiff
path: root/tests/test-pangocairo-threads.c
blob: e358f743c42a931759566df4767bfef79491eefc (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
#include <stdlib.h>
#include <string.h>
#include <pango/pango.h>
#include <pango/pangocairo.h>

#define WIDTH 100
#define HEIGHT 100
const char *text = "The quick brown fox jumped over the lazy dog!";

int num_iters = 100;

GMutex mutex;

static cairo_surface_t *
create_surface (void)
{
  return cairo_image_surface_create (CAIRO_FORMAT_A8, WIDTH, HEIGHT);
}

static PangoLayout *
create_layout (cairo_t *cr)
{
  PangoLayout *layout = pango_cairo_create_layout (cr);
  pango_layout_set_text (layout, text, -1);
  pango_layout_set_width (layout, WIDTH * PANGO_SCALE);
  return layout;
}

static void
draw (cairo_t *cr, PangoLayout *layout)
{
  cairo_set_source_rgba (cr, 1, 1, 1, 1);
  cairo_paint (cr);
  cairo_set_source_rgba (cr, 1, 1, 1, 0);
  cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);

  /* force a relayout */
  pango_layout_context_changed (layout);

  pango_cairo_show_layout (cr, layout);
}

static gpointer
thread_func (gpointer data)
{
  cairo_surface_t *surface = data;
  PangoLayout *layout;
  int i;

  cairo_t *cr = cairo_create (surface);

  layout = create_layout (cr);

  g_mutex_lock (&mutex);
  g_mutex_unlock (&mutex);

  for (i = 0; i < num_iters; i++)
    draw (cr, layout);

  return 0;
}

int
main (int argc, char **argv)
{
  int num_threads = 100;
  int i;
  GPtrArray *threads = g_ptr_array_new ();
  GPtrArray *surfaces = g_ptr_array_new ();

  if (argc > 1)
    num_threads = atoi (argv[1]);
  if (argc > 2)
    num_iters = atoi (argv[2]);

  g_mutex_lock (&mutex);

  for (i = 0; i < num_threads; i++)
    {
      cairo_surface_t *surface = create_surface ();
      g_ptr_array_add (surfaces, surface);
      g_ptr_array_add (threads,
		       g_thread_new (g_strdup_printf ("%d", i),
				     thread_func,
				     surface));
    }

  /* Let them loose! */
  g_mutex_unlock (&mutex);

  for (i = 0; i < num_threads; i++)
    g_thread_join (g_ptr_array_index (threads, i));

  /* Now, draw a reference image and check results. */
  {
    cairo_surface_t *ref_surface = create_surface ();
    cairo_t *cr = cairo_create (ref_surface);
    PangoLayout *layout = create_layout (cr);
    unsigned char *ref_data = cairo_image_surface_get_data (ref_surface);
    unsigned int len = WIDTH * HEIGHT;

    draw (cr, layout);

    /* cairo_surface_write_to_png (ref_surface, "test-pangocairo-threads-reference.png"); */

    g_assert (WIDTH == cairo_format_stride_for_width (CAIRO_FORMAT_A8, WIDTH));

    for (i = 0; i < num_threads; i++)
      {
	cairo_surface_t *surface = g_ptr_array_index (surfaces, i);
	unsigned char *data = cairo_image_surface_get_data (surface);
	if (memcmp (ref_data, data, len))
	  {
	    fprintf (stderr, "image for thread %d different from reference image.\n", i);
	    cairo_surface_write_to_png (ref_surface, "test-pangocairo-threads-reference.png");
	    cairo_surface_write_to_png (surface, "test-pangocairo-threads-failed.png");
	    return 1;
	  }
      }
  }

  return 0;
}