1 #include <clutter/clutter.h>
2 #include <cogl/cogl.h>
3 #include <string.h>
4
5 #include "test-conform-common.h"
6
7 static const ClutterColor stage_color = { 0x00, 0x00, 0x00, 0xff };
8
9 #define TEX_SIZE 64
10
11 typedef struct _TestState
12 {
13 unsigned int padding;
14 } TestState;
15
16 /* Creates a texture where the pixels are evenly divided between
17 selecting just one of the R,G and B components */
18 static CoglHandle
make_texture(void)19 make_texture (void)
20 {
21 guchar *tex_data = g_malloc (TEX_SIZE * TEX_SIZE * 3), *p = tex_data;
22 CoglHandle tex;
23 int x, y;
24
25 for (y = 0; y < TEX_SIZE; y++)
26 for (x = 0; x < TEX_SIZE; x++)
27 {
28 memset (p, 0, 3);
29 /* Set one of the components to full. The components should be
30 evenly represented so that each gets a third of the
31 texture */
32 p[(p - tex_data) / (TEX_SIZE * TEX_SIZE * 3 / 3)] = 255;
33 p += 3;
34 }
35
36 tex = test_utils_texture_new_from_data (TEX_SIZE, TEX_SIZE, TEST_UTILS_TEXTURE_NONE,
37 COGL_PIXEL_FORMAT_RGB_888,
38 COGL_PIXEL_FORMAT_ANY,
39 TEX_SIZE * 3,
40 tex_data);
41
42 g_free (tex_data);
43
44 return tex;
45 }
46
47 static void
on_paint(ClutterActor * actor,ClutterPaintContext * paint_context,TestState * state)48 on_paint (ClutterActor *actor,
49 ClutterPaintContext *paint_context,
50 TestState *state)
51 {
52 CoglHandle tex;
53 CoglHandle material;
54 uint8_t pixels[8];
55
56 tex = make_texture ();
57 material = cogl_material_new ();
58 cogl_material_set_layer (material, 0, tex);
59 cogl_object_unref (tex);
60
61 /* Render a 1x1 pixel quad without mipmaps */
62 cogl_set_source (material);
63 cogl_material_set_layer_filters (material, 0,
64 COGL_MATERIAL_FILTER_NEAREST,
65 COGL_MATERIAL_FILTER_NEAREST);
66 cogl_rectangle (0, 0, 1, 1);
67 /* Then with mipmaps */
68 cogl_material_set_layer_filters (material, 0,
69 COGL_MATERIAL_FILTER_NEAREST_MIPMAP_NEAREST,
70 COGL_MATERIAL_FILTER_NEAREST);
71 cogl_rectangle (1, 0, 2, 1);
72
73 cogl_object_unref (material);
74
75 /* Read back the two pixels we rendered */
76 cogl_read_pixels (0, 0, 2, 1,
77 COGL_READ_PIXELS_COLOR_BUFFER,
78 COGL_PIXEL_FORMAT_RGBA_8888_PRE,
79 pixels);
80
81 /* The first pixel should be just one of the colors from the
82 texture. It doesn't matter which one */
83 g_assert ((pixels[0] == 255 && pixels[1] == 0 && pixels[2] == 0) ||
84 (pixels[0] == 0 && pixels[1] == 255 && pixels[2] == 0) ||
85 (pixels[0] == 0 && pixels[1] == 0 && pixels[2] == 255));
86 /* The second pixel should be more or less the average of all of the
87 pixels in the texture. Each component gets a third of the image
88 so each component should be approximately 255/3 */
89 g_assert (ABS (pixels[4] - 255 / 3) <= 3 &&
90 ABS (pixels[5] - 255 / 3) <= 3 &&
91 ABS (pixels[6] - 255 / 3) <= 3);
92
93 /* Comment this out if you want visual feedback for what this test paints */
94 #if 1
95 clutter_test_quit ();
96 #endif
97 }
98
99 static gboolean
queue_redraw(void * stage)100 queue_redraw (void *stage)
101 {
102 clutter_actor_queue_redraw (CLUTTER_ACTOR (stage));
103
104 return TRUE;
105 }
106
107 void
test_texture_mipmaps(TestUtilsGTestFixture * fixture,void * data)108 test_texture_mipmaps (TestUtilsGTestFixture *fixture,
109 void *data)
110 {
111 TestState state;
112 ClutterActor *stage;
113 ClutterActor *group;
114 unsigned int idle_source;
115
116 stage = clutter_stage_get_default ();
117
118 clutter_actor_set_background_color (CLUTTER_ACTOR (stage), &stage_color);
119
120 group = clutter_actor_new ();
121 clutter_container_add_actor (CLUTTER_CONTAINER (stage), group);
122
123 /* We force continuous redrawing of the stage, since we need to skip
124 * the first few frames, and we won't be doing anything else that
125 * will trigger redrawing. */
126 idle_source = g_idle_add (queue_redraw, stage);
127
128 g_signal_connect (group, "paint", G_CALLBACK (on_paint), &state);
129
130 clutter_actor_show (stage);
131
132 clutter_test_main ();
133
134 g_clear_handle_id (&idle_source, g_source_remove);
135
136 if (cogl_test_verbose ())
137 g_print ("OK\n");
138 }
139