2
#include <clutter/clutter.h>
5
#include "test-conform-common.h"
12
#define FRAMEBUFFER_WIDTH 640
13
#define FRAMEBUFFER_HEIGHT 480
15
static const ClutterColor stage_color = { 0x0, 0x0, 0x0, 0xff };
18
assert_region_color (int x,
27
uint8_t *data = g_malloc0 (width * height * 4);
28
cogl_read_pixels (x, y, width, height,
29
COGL_READ_PIXELS_COLOR_BUFFER,
30
COGL_PIXEL_FORMAT_RGBA_8888_PRE,
32
for (y = 0; y < height; y++)
33
for (x = 0; x < width; x++)
35
uint8_t *pixel = &data[y*width*4 + x*4];
37
g_assert (pixel[RED] == red &&
38
pixel[GREEN] == green &&
39
pixel[BLUE] == blue &&
40
pixel[ALPHA] == alpha);
47
assert_rectangle_color_and_black_border (int x,
55
/* check the rectangle itself... */
56
assert_region_color (x, y, width, height, red, green, blue, 0xff);
57
/* black to left of the rectangle */
58
assert_region_color (x-10, y-10, 10, height+20, 0x00, 0x00, 0x00, 0xff);
59
/* black to right of the rectangle */
60
assert_region_color (x+width, y-10, 10, height+20, 0x00, 0x00, 0x00, 0xff);
61
/* black above the rectangle */
62
assert_region_color (x-10, y-10, width+20, 10, 0x00, 0x00, 0x00, 0xff);
63
/* and black below the rectangle */
64
assert_region_color (x-10, y+height, width+20, 10, 0x00, 0x00, 0x00, 0xff);
69
on_paint (ClutterActor *actor, void *state)
71
float saved_viewport[4];
72
CoglMatrix saved_projection;
73
CoglMatrix projection;
84
/* for clearing the offscreen framebuffer to black... */
85
cogl_color_init_from_4ub (&black, 0x00, 0x00, 0x00, 0xff);
87
cogl_get_viewport (saved_viewport);
88
cogl_get_projection_matrix (&saved_projection);
91
cogl_matrix_init_identity (&projection);
92
cogl_matrix_init_identity (&modelview);
94
cogl_set_projection_matrix (&projection);
95
cogl_set_modelview_matrix (&modelview);
97
/* - Create a 100x200 viewport (i.e. smaller than the onscreen framebuffer)
98
* and position it a (20, 10) inside the framebuffer.
99
* - Fill the whole viewport with a purple rectangle
100
* - Verify that the framebuffer is black with a 100x200 purple rectangle at
103
cogl_set_viewport (20, /* x */
107
/* clear everything... */
108
cogl_clear (&black, COGL_BUFFER_BIT_COLOR);
109
/* fill the viewport with purple.. */
110
cogl_set_source_color4ub (0xff, 0x00, 0xff, 0xff);
111
cogl_rectangle (-1, 1, 1, -1);
112
assert_rectangle_color_and_black_border (20, 10, 100, 200,
116
/* - Create a viewport twice the size of the onscreen framebuffer with
117
* a negative offset positioning it at (-20, -10) relative to the
119
* - Draw a 100x200 green rectangle at (40, 20) within the viewport (which
120
* is (20, 10) within the framebuffer)
121
* - Verify that the framebuffer is black with a 100x200 green rectangle at
124
cogl_set_viewport (-20, /* x */
126
FRAMEBUFFER_WIDTH * 2, /* width */
127
FRAMEBUFFER_HEIGHT * 2); /* height */
128
/* clear everything... */
129
cogl_clear (&black, COGL_BUFFER_BIT_COLOR);
130
/* draw a 100x200 green rectangle offset into the viewport such that its
131
* top left corner should be found at (20, 10) in the offscreen buffer */
132
/* (offset 40 pixels right from the left of the viewport) */
133
x0 = -1.0f + (1.0f / FRAMEBUFFER_WIDTH) * 40.f;
134
/* (offset 20 pixels down from the top of the viewport) */
135
y0 = 1.0f - (1.0f / FRAMEBUFFER_HEIGHT) * 20.0f;
136
width = (1.0f / FRAMEBUFFER_WIDTH) * 100;
137
height = (1.0f / FRAMEBUFFER_HEIGHT) * 200;
138
cogl_set_source_color4ub (0x00, 0xff, 0x00, 0xff);
139
cogl_rectangle (x0, y0, x0 + width, y0 - height);
140
assert_rectangle_color_and_black_border (20, 10, 100, 200,
144
/* - Create a 200x400 viewport and position it a (20, 10) inside the draw
146
* - Push a 100x200 window space clip rectangle at (20, 10)
147
* - Fill the whole viewport with a blue rectangle
148
* - Verify that the framebuffer is black with a 100x200 blue rectangle at
151
cogl_set_viewport (20, /* x */
155
/* clear everything... */
156
cogl_clear (&black, COGL_BUFFER_BIT_COLOR);
157
cogl_clip_push_window_rectangle (20, 10, 100, 200);
158
/* fill the viewport with blue.. */
159
cogl_set_source_color4ub (0x00, 0x00, 0xff, 0xff);
160
cogl_rectangle (-1, 1, 1, -1);
162
assert_rectangle_color_and_black_border (20, 10, 100, 200,
166
/* - Create a 200x400 viewport and position it a (20, 10) inside the draw
168
* - Push a 100x200 model space clip rectangle at (20, 10) in the viewport
169
* (i.e. (40, 20) inside the framebuffer)
170
* - Fill the whole viewport with a green rectangle
171
* - Verify that the framebuffer is black with a 100x200 green rectangle at
174
cogl_set_viewport (20, /* x */
178
/* clear everything... */
179
cogl_clear (&black, COGL_BUFFER_BIT_COLOR);
180
/* figure out where to position our clip rectangle in model space
182
/* (offset 40 pixels right from the left of the viewport) */
183
x0 = -1.0f + (2.0f / 200) * 20.f;
184
/* (offset 20 pixels down from the top of the viewport) */
185
y0 = 1.0f - (2.0f / 400) * 10.0f;
186
width = (2.0f / 200) * 100;
187
height = (2.0f / 400) * 200;
188
/* add the clip rectangle... */
190
cogl_translate (x0 + (width/2.0), y0 - (height/2.0), 0);
191
/* XXX: Rotate just enough to stop Cogl from converting our model space
192
* rectangle into a window space rectangle.. */
193
cogl_rotate (0.1, 0, 0, 1);
194
cogl_clip_push_rectangle (-(width/2.0), -(height/2.0),
195
width/2.0, height/2.0);
197
/* fill the viewport with green.. */
198
cogl_set_source_color4ub (0x00, 0xff, 0x00, 0xff);
199
cogl_rectangle (-1, 1, 1, -1);
201
assert_rectangle_color_and_black_border (40, 20, 100, 200,
205
/* Set the viewport to something specific so we can verify that it gets
206
* restored after we are done testing with an offscreen framebuffer... */
207
cogl_set_viewport (20, 10, 100, 200);
210
* Next test offscreen drawing...
212
data = g_malloc (FRAMEBUFFER_WIDTH * 4 * FRAMEBUFFER_HEIGHT);
213
tex = test_utils_texture_new_from_data (FRAMEBUFFER_WIDTH, FRAMEBUFFER_HEIGHT,
214
TEST_UTILS_TEXTURE_NO_SLICING,
215
COGL_PIXEL_FORMAT_RGBA_8888, /* data fmt */
216
COGL_PIXEL_FORMAT_ANY, /* internal fmt */
217
FRAMEBUFFER_WIDTH * 4, /* rowstride */
220
offscreen = cogl_offscreen_new_with_texture (tex);
222
cogl_push_framebuffer (offscreen);
225
/* - Create a 100x200 viewport (i.e. smaller than the offscreen framebuffer)
226
* and position it a (20, 10) inside the framebuffer.
227
* - Fill the whole viewport with a blue rectangle
228
* - Verify that the framebuffer is black with a 100x200 blue rectangle at
231
cogl_set_viewport (20, /* x */
235
/* clear everything... */
236
cogl_clear (&black, COGL_BUFFER_BIT_COLOR);
237
/* fill the viewport with blue.. */
238
cogl_set_source_color4ub (0x00, 0x00, 0xff, 0xff);
239
cogl_rectangle (-1, 1, 1, -1);
240
assert_rectangle_color_and_black_border (20, 10, 100, 200,
244
/* - Create a viewport twice the size of the offscreen framebuffer with
245
* a negative offset positioning it at (-20, -10) relative to the
247
* - Draw a 100x200 red rectangle at (40, 20) within the viewport (which
248
* is (20, 10) within the framebuffer)
249
* - Verify that the framebuffer is black with a 100x200 red rectangle at
252
cogl_set_viewport (-20, /* x */
254
FRAMEBUFFER_WIDTH * 2, /* width */
255
FRAMEBUFFER_HEIGHT * 2); /* height */
256
/* clear everything... */
257
cogl_clear (&black, COGL_BUFFER_BIT_COLOR);
258
/* draw a 100x200 red rectangle offset into the viewport such that its
259
* top left corner should be found at (20, 10) in the offscreen buffer */
260
/* (offset 40 pixels right from the left of the viewport) */
261
x0 = -1.0f + (1.0f / FRAMEBUFFER_WIDTH) * 40.f;
262
/* (offset 20 pixels down from the top of the viewport) */
263
y0 = 1.0f - (1.0f / FRAMEBUFFER_HEIGHT) * 20.0f;
264
width = (1.0f / FRAMEBUFFER_WIDTH) * 100;
265
height = (1.0f / FRAMEBUFFER_HEIGHT) * 200;
266
cogl_set_source_color4ub (0xff, 0x00, 0x00, 0xff);
267
cogl_rectangle (x0, y0, x0 + width, y0 - height);
268
assert_rectangle_color_and_black_border (20, 10, 100, 200,
272
/* - Create a 200x400 viewport and position it a (20, 10) inside the draw
274
* - Push a 100x200 window space clip rectangle at (20, 10)
275
* - Fill the whole viewport with a blue rectangle
276
* - Verify that the framebuffer is black with a 100x200 blue rectangle at
279
cogl_set_viewport (20, /* x */
283
/* clear everything... */
284
cogl_clear (&black, COGL_BUFFER_BIT_COLOR);
285
cogl_clip_push_window_rectangle (20, 10, 100, 200);
286
/* fill the viewport with blue.. */
287
cogl_set_source_color4ub (0x00, 0x00, 0xff, 0xff);
288
cogl_rectangle (-1, 1, 1, -1);
290
assert_rectangle_color_and_black_border (20, 10, 100, 200,
294
/* - Create a 200x400 viewport and position it a (20, 10) inside the draw
296
* - Push a 100x200 model space clip rectangle at (20, 10) in the viewport
297
* (i.e. (40, 20) inside the framebuffer)
298
* - Fill the whole viewport with a green rectangle
299
* - Verify that the framebuffer is black with a 100x200 green rectangle at
302
cogl_set_viewport (20, /* x */
306
/* clear everything... */
307
cogl_clear (&black, COGL_BUFFER_BIT_COLOR);
308
/* figure out where to position our clip rectangle in model space
310
/* (offset 40 pixels right from the left of the viewport) */
311
x0 = -1.0f + (2.0f / 200) * 20.f;
312
/* (offset 20 pixels down from the top of the viewport) */
313
y0 = 1.0f - (2.0f / 400) * 10.0f;
314
width = (2.0f / 200) * 100;
315
height = (2.0f / 400) * 200;
316
/* add the clip rectangle... */
318
cogl_translate (x0 + (width/2.0), y0 - (height/2.0), 0);
319
/* XXX: Rotate just enough to stop Cogl from converting our model space
320
* rectangle into a window space rectangle.. */
321
cogl_rotate (0.1, 0, 0, 1);
322
cogl_clip_push_rectangle (-(width/2.0), -(height/2.0),
325
/* fill the viewport with green.. */
326
cogl_set_source_color4ub (0x00, 0xff, 0x00, 0xff);
327
cogl_rectangle (-1, 1, 1, -1);
329
assert_rectangle_color_and_black_border (40, 20, 100, 200,
333
/* Set the viewport to something obscure to verify that it gets
334
* replace when we switch back to the onscreen framebuffer... */
335
cogl_set_viewport (0, 0, 10, 10);
337
cogl_pop_framebuffer ();
338
cogl_handle_unref (offscreen);
341
* Verify that the previous onscreen framebuffer's viewport was restored
342
* by drawing a white rectangle across the whole viewport. This should
343
* draw a 100x200 rectangle at (20,10) relative to the onscreen draw
346
cogl_clear (&black, COGL_BUFFER_BIT_COLOR);
347
cogl_set_source_color4ub (0xff, 0xff, 0xff, 0xff);
348
cogl_rectangle (-1, 1, 1, -1);
349
assert_rectangle_color_and_black_border (20, 10, 100, 200,
353
/* Uncomment to display the last contents of the offscreen framebuffer */
355
cogl_matrix_init_identity (&projection);
356
cogl_matrix_init_identity (&modelview);
357
cogl_set_viewport (0, 0, FRAMEBUFFER_WIDTH, FRAMEBUFFER_HEIGHT);
358
cogl_set_projection_matrix (&projection);
359
cogl_set_modelview_matrix (&modelview);
360
cogl_set_source_texture (tex);
361
cogl_rectangle (-1, 1, 1, -1);
364
cogl_handle_unref (tex);
366
/* Finally restore the stage's original state... */
368
cogl_set_projection_matrix (&saved_projection);
369
cogl_set_viewport (saved_viewport[0], saved_viewport[1],
370
saved_viewport[2], saved_viewport[3]);
373
/* Comment this out if you want visual feedback of what this test
376
clutter_main_quit ();
380
queue_redraw (void *stage)
382
clutter_actor_queue_redraw (CLUTTER_ACTOR (stage));
388
test_viewport (TestUtilsGTestFixture *fixture,
391
unsigned int idle_source;
394
stage = clutter_stage_get_default ();
395
clutter_stage_set_color (CLUTTER_STAGE (stage), &stage_color);
397
/* We force continuous redrawing of the stage, since we need to skip
398
* the first few frames, and we wont be doing anything else that
399
* will trigger redrawing. */
400
idle_source = g_idle_add (queue_redraw, stage);
401
g_signal_connect_after (stage, "paint", G_CALLBACK (on_paint), NULL);
403
clutter_actor_show (stage);
406
g_source_remove (idle_source);
408
/* Remove all of the actors from the stage */
409
clutter_container_foreach (CLUTTER_CONTAINER (stage),
410
(ClutterCallback) clutter_actor_destroy,
413
if (cogl_test_verbose ())