~oem-solutions-group/unity-2d/clutter-1.0

« back to all changes in this revision

Viewing changes to tests/conform/test-cogl-pixel-buffer.c

  • Committer: Bazaar Package Importer
  • Author(s): Emilio Pozuelo Monfort
  • Date: 2010-03-21 13:27:56 UTC
  • mto: (2.1.3 experimental)
  • mto: This revision was merged to the branch mainline in revision 8.
  • Revision ID: james.westby@ubuntu.com-20100321132756-nf8yd30yxo3zzwcm
Tags: upstream-1.2.2
ImportĀ upstreamĀ versionĀ 1.2.2

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#include <clutter/clutter.h>
 
2
#include <cogl/cogl.h>
 
3
#include <string.h>
 
4
 
 
5
#include "test-conform-common.h"
 
6
 
 
7
#define TILE_SIZE        32.0f
 
8
 
 
9
enum
 
10
{
 
11
  TILE_MAP,
 
12
  TILE_SET_DATA,
 
13
  NB_TILES,
 
14
  TILE_SET_REGION,
 
15
};
 
16
 
 
17
typedef struct test_tile
 
18
{
 
19
  ClutterColor color;
 
20
  gfloat x, y;
 
21
  CoglHandle buffer;
 
22
  CoglHandle texture;
 
23
} TestTile;
 
24
 
 
25
static const ClutterColor
 
26
buffer_colors[] =
 
27
  {
 
28
  };
 
29
 
 
30
static const ClutterColor stage_color = { 0x0, 0x0, 0x0, 0xff };
 
31
 
 
32
typedef struct _TestState
 
33
{
 
34
  ClutterActor *stage;
 
35
  guint frame;
 
36
 
 
37
  TestTile *tiles;
 
38
 
 
39
} TestState;
 
40
 
 
41
static CoglHandle
 
42
create_texture_from_buffer (CoglHandle buffer)
 
43
{
 
44
  CoglHandle texture;
 
45
 
 
46
  texture = cogl_texture_new_from_buffer (buffer,
 
47
                                          TILE_SIZE, TILE_SIZE,
 
48
                                          COGL_TEXTURE_NO_SLICING,
 
49
                                          COGL_PIXEL_FORMAT_RGBA_8888,
 
50
                                          COGL_PIXEL_FORMAT_RGBA_8888,
 
51
                                          TILE_SIZE * 4,
 
52
                                          0);
 
53
 
 
54
  g_assert (texture != COGL_INVALID_HANDLE);
 
55
 
 
56
  return texture;
 
57
}
 
58
 
 
59
static void
 
60
create_map_tile (TestTile *tile)
 
61
{
 
62
  CoglHandle buffer;
 
63
  guchar *map;
 
64
  guint i;
 
65
 
 
66
  buffer = cogl_pixel_buffer_new (TILE_SIZE * TILE_SIZE * 4);
 
67
 
 
68
  g_assert (cogl_is_pixel_buffer (buffer));
 
69
  g_assert (cogl_is_buffer (buffer));
 
70
 
 
71
  /* while at it, set/get the hints */
 
72
  cogl_buffer_set_usage_hint (buffer, COGL_BUFFER_USAGE_HINT_TEXTURE);
 
73
  g_assert_cmpint (cogl_buffer_get_usage_hint (buffer),
 
74
                   ==,
 
75
                   COGL_BUFFER_USAGE_HINT_TEXTURE);
 
76
  cogl_buffer_set_update_hint (buffer, COGL_BUFFER_UPDATE_HINT_DYNAMIC);
 
77
  g_assert_cmpint (cogl_buffer_get_update_hint (buffer),
 
78
            ==,
 
79
            COGL_BUFFER_UPDATE_HINT_DYNAMIC);
 
80
 
 
81
  map = cogl_buffer_map (buffer, COGL_BUFFER_ACCESS_WRITE);
 
82
  g_assert (map);
 
83
 
 
84
  for (i = 0; i < TILE_SIZE * TILE_SIZE * 4; i += 4)
 
85
      memcpy (map + i, &tile->color, 4);
 
86
 
 
87
  cogl_buffer_unmap (buffer);
 
88
 
 
89
  tile->buffer = buffer;
 
90
  tile->texture = create_texture_from_buffer (tile->buffer);
 
91
}
 
92
 
 
93
#if 0
 
94
static void
 
95
create_set_region_tile (TestTile *tile)
 
96
{
 
97
  CoglHandle buffer;
 
98
  ClutterColor bottom_color;
 
99
  guint rowstride = 0;
 
100
  guchar *data;
 
101
  guint i;
 
102
 
 
103
  buffer = cogl_pixel_buffer_new_for_size (TILE_SIZE,
 
104
                                           TILE_SIZE,
 
105
                                           COGL_PIXEL_FORMAT_RGBA_8888,
 
106
                                           &rowstride);
 
107
 
 
108
  g_assert (cogl_is_pixel_buffer (buffer));
 
109
  g_assert (cogl_is_buffer (buffer));
 
110
 
 
111
  /* while at it, set/get the hint */
 
112
  cogl_buffer_set_hint (buffer, COGL_BUFFER_HINT_STATIC_TEXTURE);
 
113
  g_assert (cogl_buffer_get_hint (buffer) == COGL_BUFFER_HINT_STATIC_TEXTURE);
 
114
 
 
115
  data = g_malloc (TILE_SIZE * TILE_SIZE * 4);
 
116
  /* create a buffer with the data we want to copy to the buffer */
 
117
  for (i = 0; i < TILE_SIZE * TILE_SIZE * 4; i += 4)
 
118
      memcpy (data + i, &tile->color, 4);
 
119
 
 
120
  cogl_pixel_buffer_set_region (buffer,
 
121
                                data,
 
122
                                TILE_SIZE, TILE_SIZE,
 
123
                                TILE_SIZE,
 
124
                                0, 0);
 
125
 
 
126
  bottom_color.red = tile->color.red;
 
127
  bottom_color.green = tile->color.blue;
 
128
  bottom_color.blue = tile->color.green;
 
129
  bottom_color.alpha = tile->color.alpha;
 
130
  for (i = 0; i < TILE_SIZE / 2; i++)
 
131
    memcpy (data + i, &bottom_color, 4);
 
132
 
 
133
  cogl_buffer_set_data (buffer, data, 0, TILE_SIZE * TILE_SIZE * 4 / 2);
 
134
 
 
135
  g_free (data);
 
136
 
 
137
  tile->buffer = buffer;
 
138
  tile->texture = create_texture_from_buffer (tile->buffer);
 
139
}
 
140
#endif
 
141
 
 
142
static void
 
143
create_set_data_tile (TestTile *tile)
 
144
{
 
145
  CoglHandle buffer;
 
146
  guint rowstride = 0;
 
147
  gboolean res;
 
148
  guchar *data;
 
149
  guint i;
 
150
 
 
151
  buffer = cogl_pixel_buffer_new_for_size (TILE_SIZE,
 
152
                                           TILE_SIZE,
 
153
                                           COGL_PIXEL_FORMAT_RGBA_8888,
 
154
                                           &rowstride);
 
155
 
 
156
  g_assert (cogl_is_pixel_buffer (buffer));
 
157
  g_assert (cogl_is_buffer (buffer));
 
158
  g_assert_cmpint (cogl_buffer_get_size (buffer), ==, rowstride * TILE_SIZE);
 
159
 
 
160
  /* while at it, set/get the hint */
 
161
  cogl_buffer_set_usage_hint (buffer, COGL_BUFFER_USAGE_HINT_TEXTURE);
 
162
  g_assert_cmpint (cogl_buffer_get_usage_hint (buffer),
 
163
                   ==,
 
164
                   COGL_BUFFER_USAGE_HINT_TEXTURE);
 
165
 
 
166
  /* create a buffer with the data we want to copy to the buffer */
 
167
  data = g_malloc (TILE_SIZE * TILE_SIZE * 4);
 
168
  for (i = 0; i < TILE_SIZE * TILE_SIZE * 4; i += 4)
 
169
      memcpy (data + i, &tile->color, 4);
 
170
 
 
171
  res = cogl_buffer_set_data (buffer, 0, data, TILE_SIZE * TILE_SIZE * 4);
 
172
  g_assert (res);
 
173
 
 
174
  g_free (data);
 
175
 
 
176
  tile->buffer = buffer;
 
177
  tile->texture = create_texture_from_buffer (tile->buffer);
 
178
}
 
179
 
 
180
static void
 
181
draw_frame (TestState *state)
 
182
{
 
183
  guint i;
 
184
 
 
185
  /* Paint the textures */
 
186
  for (i = 0; i < NB_TILES; i++)
 
187
    {
 
188
      cogl_set_source_texture (state->tiles[i].texture);
 
189
      cogl_rectangle (state->tiles[i].x,
 
190
                      state->tiles[i].y,
 
191
                      state->tiles[i].x + TILE_SIZE,
 
192
                      state->tiles[i].y + TILE_SIZE);
 
193
    }
 
194
 
 
195
}
 
196
 
 
197
static gboolean
 
198
validate_tile (TestState *state,
 
199
               TestTile  *tile)
 
200
{
 
201
  int x, y;
 
202
  guchar *pixels, *p;
 
203
 
 
204
  p = pixels = clutter_stage_read_pixels (CLUTTER_STAGE (state->stage),
 
205
                                          tile->x,
 
206
                                          tile->y,
 
207
                                          TILE_SIZE,
 
208
                                          TILE_SIZE);
 
209
 
 
210
  /* Check whether the center of each division is the right color */
 
211
  for (y = 0; y < TILE_SIZE; y++)
 
212
    for (x = 0; x < TILE_SIZE; x++)
 
213
      {
 
214
        if (p[0] != tile->color.red ||
 
215
            p[1] != tile->color.green ||
 
216
            p[2] != tile->color.blue ||
 
217
            p[3] != tile->color.alpha)
 
218
          {
 
219
            return FALSE;
 
220
          }
 
221
 
 
222
        p += 4;
 
223
      }
 
224
 
 
225
  return TRUE;
 
226
}
 
227
 
 
228
static void
 
229
validate_result (TestState *state)
 
230
{
 
231
  guint i;
 
232
 
 
233
  for (i = 0; i < NB_TILES; i++)
 
234
    g_assert (validate_tile (state, &state->tiles[i]));
 
235
 
 
236
  /* comment this if you want to see what's being drawn */
 
237
#if 1
 
238
  clutter_main_quit ();
 
239
#endif
 
240
}
 
241
 
 
242
static void
 
243
on_paint (ClutterActor *actor, TestState *state)
 
244
{
 
245
  int frame_num;
 
246
 
 
247
  draw_frame (state);
 
248
 
 
249
  /* XXX: Experiments have shown that for some buggy drivers, when using
 
250
   * glReadPixels there is some kind of race, so we delay our test for a
 
251
   * few frames and a few seconds:
 
252
   */
 
253
  /* Need to increment frame first because clutter_stage_read_pixels
 
254
     fires a redraw */
 
255
  frame_num = state->frame++;
 
256
  if (frame_num == 2)
 
257
    validate_result (state);
 
258
  else if (frame_num < 2)
 
259
    g_usleep (G_USEC_PER_SEC);
 
260
}
 
261
 
 
262
static gboolean
 
263
queue_redraw (gpointer stage)
 
264
{
 
265
  clutter_actor_queue_redraw (CLUTTER_ACTOR (stage));
 
266
 
 
267
  return TRUE;
 
268
}
 
269
 
 
270
void
 
271
test_cogl_pixel_buffer (TestConformSimpleFixture *fixture,
 
272
                        gconstpointer             data)
 
273
{
 
274
  TestState state;
 
275
  guint idle_source;
 
276
  guint paint_handler, i;
 
277
  static TestTile tiles[NB_TILES] =
 
278
    {
 
279
        /*         color             x  y buffer tex */
 
280
 
 
281
        /* MAP */
 
282
        { { 0xff, 0x00, 0x00, 0xff }, 0.0f, 0.0f, NULL, NULL },
 
283
#if 0
 
284
        /* SET_REGION */
 
285
        { { 0x7e, 0x7e, 0xff, 0x7e }, 0.0f, TILE_SIZE, NULL, NULL },
 
286
#endif
 
287
        /* SET_DATA */
 
288
        { { 0x7e, 0xff, 0x7e, 0xff }, 0.0f, TILE_SIZE, NULL, NULL }
 
289
    };
 
290
 
 
291
  state.frame = 0;
 
292
 
 
293
  state.stage = clutter_stage_get_default ();
 
294
 
 
295
  create_map_tile (&tiles[TILE_MAP]);
 
296
#if 0
 
297
  create_set_region_tile (&tiles[TILE_SET_REGION]);
 
298
#endif
 
299
  create_set_data_tile (&tiles[TILE_SET_DATA]);
 
300
 
 
301
  state.tiles = tiles;
 
302
 
 
303
  clutter_stage_set_color (CLUTTER_STAGE (state.stage), &stage_color);
 
304
 
 
305
  /* We force continuous redrawing of the stage, since we need to skip
 
306
   * the first few frames, and we wont be doing anything else that
 
307
   * will trigger redrawing. */
 
308
  idle_source = g_idle_add (queue_redraw, state.stage);
 
309
 
 
310
  paint_handler = g_signal_connect_after (state.stage, "paint",
 
311
                                          G_CALLBACK (on_paint), &state);
 
312
 
 
313
  clutter_actor_show_all (state.stage);
 
314
 
 
315
  clutter_main ();
 
316
 
 
317
  g_source_remove (idle_source);
 
318
  g_signal_handler_disconnect (state.stage, paint_handler);
 
319
 
 
320
  for (i = 0; i < NB_TILES; i++)
 
321
    {
 
322
      cogl_handle_unref (state.tiles[i].buffer);
 
323
      cogl_handle_unref (state.tiles[i].texture);
 
324
    }
 
325
 
 
326
  /* Remove all of the actors from the stage */
 
327
  clutter_container_foreach (CLUTTER_CONTAINER (state.stage),
 
328
                             (ClutterCallback) clutter_actor_destroy,
 
329
                             NULL);
 
330
 
 
331
  if (g_test_verbose ())
 
332
    g_print ("OK\n");
 
333
}
 
334