"Initial commit to Gerrit"
[profile/ivi/cogl.git] / tests / conform / test-snippets.c
1 #include <cogl/cogl.h>
2
3 #include <string.h>
4
5 #include "test-utils.h"
6
7 typedef struct _TestState
8 {
9   int padding;
10 } TestState;
11
12 typedef void (* SnippetTestFunc) (TestState *state);
13
14 static CoglPipeline *
15 create_texture_pipeline (TestState *state)
16 {
17   CoglPipeline *pipeline;
18   CoglTexture *tex;
19   static const guint8 tex_data[] =
20     {
21       0xff, 0x00, 0x00, 0xff, /* red */  0x00, 0xff, 0x00, 0xff, /* green */
22       0x00, 0x00, 0xff, 0xff, /* blue */ 0xff, 0xff, 0x00, 0xff, /* yellow */
23     };
24
25   tex = cogl_texture_new_from_data (2, 2, /* width/height */
26                                     COGL_TEXTURE_NO_ATLAS,
27                                     COGL_PIXEL_FORMAT_RGBA_8888_PRE,
28                                     COGL_PIXEL_FORMAT_ANY,
29                                     8, /* rowstride */
30                                     tex_data);
31
32   pipeline = cogl_pipeline_new (ctx);
33
34   cogl_pipeline_set_layer_texture (pipeline, 0, tex);
35
36   cogl_pipeline_set_layer_filters (pipeline, 0,
37                                    COGL_PIPELINE_FILTER_NEAREST,
38                                    COGL_PIPELINE_FILTER_NEAREST);
39
40   cogl_object_unref (tex);
41
42   return pipeline;
43 }
44
45 static void
46 simple_fragment_snippet (TestState *state)
47 {
48   CoglPipeline *pipeline;
49   CoglSnippet *snippet;
50
51   /* Simple fragment snippet */
52   pipeline = cogl_pipeline_new (ctx);
53
54   cogl_pipeline_set_color4ub (pipeline, 255, 0, 0, 255);
55
56   snippet = cogl_snippet_new (COGL_SNIPPET_HOOK_FRAGMENT,
57                               NULL, /* declarations */
58                               "cogl_color_out.g += 1.0;");
59   cogl_pipeline_add_snippet (pipeline, snippet);
60   cogl_object_unref (snippet);
61
62   cogl_framebuffer_draw_rectangle (fb, pipeline, 0, 0, 10, 10);
63
64   cogl_object_unref (pipeline);
65
66   test_utils_check_pixel (fb, 5, 5, 0xffff00ff);
67 }
68
69 static void
70 simple_vertex_snippet (TestState *state)
71 {
72   CoglPipeline *pipeline;
73   CoglSnippet *snippet;
74
75   /* Simple vertex snippet */
76   pipeline = cogl_pipeline_new (ctx);
77
78   cogl_pipeline_set_color4ub (pipeline, 255, 0, 0, 255);
79
80   snippet = cogl_snippet_new (COGL_SNIPPET_HOOK_VERTEX,
81                               NULL,
82                               "cogl_color_out.b += 1.0;");
83   cogl_pipeline_add_snippet (pipeline, snippet);
84   cogl_object_unref (snippet);
85
86   cogl_framebuffer_draw_rectangle (fb, pipeline, 10, 0, 20, 10);
87
88   cogl_object_unref (pipeline);
89
90   test_utils_check_pixel (fb, 15, 5, 0xff00ffff);
91 }
92
93 static void
94 shared_uniform (TestState *state)
95 {
96   CoglPipeline *pipeline;
97   CoglSnippet *snippet;
98   int location;
99
100   /* Snippets sharing a uniform across the vertex and fragment
101      hooks */
102   pipeline = cogl_pipeline_new (ctx);
103
104   location = cogl_pipeline_get_uniform_location (pipeline, "a_value");
105   cogl_pipeline_set_uniform_1f (pipeline, location, 0.25f);
106
107   cogl_pipeline_set_color4ub (pipeline, 255, 0, 0, 255);
108
109   snippet = cogl_snippet_new (COGL_SNIPPET_HOOK_VERTEX,
110                               "uniform float a_value;",
111                               "cogl_color_out.b += a_value;");
112   cogl_pipeline_add_snippet (pipeline, snippet);
113   cogl_object_unref (snippet);
114   snippet = cogl_snippet_new (COGL_SNIPPET_HOOK_FRAGMENT,
115                               "uniform float a_value;",
116                               "cogl_color_out.b += a_value;");
117   cogl_pipeline_add_snippet (pipeline, snippet);
118   cogl_object_unref (snippet);
119
120   cogl_framebuffer_draw_rectangle (fb,
121                                    pipeline,
122                                    20, 0, 30, 10);
123
124   cogl_object_unref (pipeline);
125
126   test_utils_check_pixel (fb, 25, 5, 0xff0080ff);
127 }
128
129 static void
130 lots_snippets (TestState *state)
131 {
132   CoglPipeline *pipeline;
133   CoglSnippet *snippet;
134   int location;
135   int i;
136
137   /* Lots of snippets on one pipeline */
138   pipeline = cogl_pipeline_new (ctx);
139
140   cogl_pipeline_set_color4ub (pipeline, 0, 0, 0, 255);
141
142   for (i = 0; i < 3; i++)
143     {
144       char letter = 'x' + i;
145       char *uniform_name = g_strdup_printf ("%c_value", letter);
146       char *declarations = g_strdup_printf ("uniform float %s;\n",
147                                             uniform_name);
148       char *code = g_strdup_printf ("cogl_color_out.%c = %s;\n",
149                                     letter,
150                                     uniform_name);
151
152       location = cogl_pipeline_get_uniform_location (pipeline, uniform_name);
153       cogl_pipeline_set_uniform_1f (pipeline, location, (i + 1) * 0.1f);
154
155       snippet = cogl_snippet_new (COGL_SNIPPET_HOOK_FRAGMENT,
156                                   declarations,
157                                   code);
158       cogl_pipeline_add_snippet (pipeline, snippet);
159       cogl_object_unref (snippet);
160
161       g_free (code);
162       g_free (uniform_name);
163       g_free (declarations);
164     }
165
166   cogl_framebuffer_draw_rectangle (fb, pipeline, 30, 0, 40, 10);
167
168   cogl_object_unref (pipeline);
169
170   test_utils_check_pixel (fb, 35, 5, 0x19334cff);
171 }
172
173 static void
174 shared_variable_pre_post (TestState *state)
175 {
176   CoglPipeline *pipeline;
177   CoglSnippet *snippet;
178
179   /* Test that the pre string can declare variables used by the post
180      string */
181   pipeline = cogl_pipeline_new (ctx);
182
183   cogl_pipeline_set_color4ub (pipeline, 255, 255, 255, 255);
184
185   snippet = cogl_snippet_new (COGL_SNIPPET_HOOK_FRAGMENT,
186                               NULL, /* declarations */
187                               "cogl_color_out = redvec;");
188   cogl_snippet_set_pre (snippet, "vec4 redvec = vec4 (1.0, 0.0, 0.0, 1.0);");
189   cogl_pipeline_add_snippet (pipeline, snippet);
190   cogl_object_unref (snippet);
191
192   cogl_framebuffer_draw_rectangle (fb, pipeline, 40, 0, 50, 10);
193
194   cogl_object_unref (pipeline);
195
196   test_utils_check_pixel (fb, 45, 5, 0xff0000ff);
197 }
198
199 static void
200 test_pipeline_caching (TestState *state)
201 {
202   CoglPipeline *pipeline;
203   CoglSnippet *snippet;
204
205   /* Check that the pipeline caching works when unrelated pipelines
206      share snippets state. It's too hard to actually assert this in
207      the conformance test but at least it should be possible to see by
208      setting COGL_DEBUG=show-source to check whether this shader gets
209      generated twice */
210   snippet = cogl_snippet_new (COGL_SNIPPET_HOOK_FRAGMENT,
211                               "/* This comment should only be seen ONCE\n"
212                               "   when COGL_DEBUG=show-source is TRUE\n"
213                               "   even though it is used in two different\n"
214                               "   unrelated pipelines */",
215                               "cogl_color_out = vec4 (0.0, 1.0, 0.0, 1.0);\n");
216
217   pipeline = cogl_pipeline_new (ctx);
218   cogl_pipeline_add_snippet (pipeline, snippet);
219   cogl_framebuffer_draw_rectangle (fb, pipeline, 50, 0, 60, 10);
220   cogl_object_unref (pipeline);
221
222   pipeline = cogl_pipeline_new (ctx);
223   cogl_pipeline_add_snippet (pipeline, snippet);
224   cogl_framebuffer_draw_rectangle (fb, pipeline, 60, 0, 70, 10);
225   cogl_object_unref (pipeline);
226
227   cogl_object_unref (snippet);
228
229   test_utils_check_pixel (fb, 55, 5, 0x00ff00ff);
230   test_utils_check_pixel (fb, 65, 5, 0x00ff00ff);
231 }
232
233 static void
234 test_replace_string (TestState *state)
235 {
236   CoglPipeline *pipeline;
237   CoglSnippet *snippet;
238
239   /* Check the replace string */
240   snippet = cogl_snippet_new (COGL_SNIPPET_HOOK_FRAGMENT, NULL, NULL);
241   cogl_snippet_set_pre (snippet,
242                         "cogl_color_out = vec4 (0.0, 0.5, 0.0, 1.0);");
243   /* Remove the generated output. If the replace string isn't working
244      then the code from the pre string would get overwritten with
245      white */
246   cogl_snippet_set_replace (snippet, "/* do nothing */");
247   cogl_snippet_set_post (snippet,
248                          "cogl_color_out += vec4 (0.5, 0.0, 0.0, 1.0);");
249
250   pipeline = cogl_pipeline_new (ctx);
251   cogl_pipeline_add_snippet (pipeline, snippet);
252   cogl_framebuffer_draw_rectangle (fb, pipeline, 70, 0, 80, 10);
253   cogl_object_unref (pipeline);
254
255   cogl_object_unref (snippet);
256
257   test_utils_check_pixel (fb, 75, 5, 0x808000ff);
258 }
259
260 static void
261 test_texture_lookup_hook (TestState *state)
262 {
263   CoglPipeline *pipeline;
264   CoglSnippet *snippet;
265
266   /* Check the texture lookup hook */
267   snippet = cogl_snippet_new (COGL_SNIPPET_HOOK_TEXTURE_LOOKUP,
268                               NULL,
269                               "cogl_texel.b += 1.0;");
270   /* Flip the texture coordinates around the y axis so that it will
271      get the green texel */
272   cogl_snippet_set_pre (snippet, "cogl_tex_coord.x = 1.0 - cogl_tex_coord.x;");
273
274   pipeline = create_texture_pipeline (state);
275   cogl_pipeline_add_layer_snippet (pipeline, 0, snippet);
276   cogl_framebuffer_draw_textured_rectangle (fb,
277                                             pipeline,
278                                             80, 0, 90, 10,
279                                             0, 0, 0, 0);
280   cogl_object_unref (pipeline);
281
282   cogl_object_unref (snippet);
283
284   test_utils_check_pixel (fb, 85, 5, 0x00ffffff);
285 }
286
287 static void
288 test_multiple_samples (TestState *state)
289 {
290   CoglPipeline *pipeline;
291   CoglSnippet *snippet;
292
293   /* Check that we can use the passed in sampler in the texture lookup
294      to sample multiple times */
295   snippet = cogl_snippet_new (COGL_SNIPPET_HOOK_TEXTURE_LOOKUP,
296                               NULL,
297                               NULL);
298   cogl_snippet_set_replace (snippet,
299                             "cogl_texel = "
300                             "texture2D (cogl_sampler, vec2 (0.25, 0.25)) + "
301                             "texture2D (cogl_sampler, vec2 (0.75, 0.25));");
302
303   pipeline = create_texture_pipeline (state);
304   cogl_pipeline_add_layer_snippet (pipeline, 0, snippet);
305   cogl_framebuffer_draw_rectangle (fb, pipeline, 0, 0, 10, 10);
306   cogl_object_unref (pipeline);
307
308   cogl_object_unref (snippet);
309
310   test_utils_check_pixel (fb, 5, 5, 0xffff00ff);
311 }
312
313 static void
314 test_replace_lookup_hook (TestState *state)
315 {
316   CoglPipeline *pipeline;
317   CoglSnippet *snippet;
318
319   /* Check replacing the texture lookup hook */
320   snippet = cogl_snippet_new (COGL_SNIPPET_HOOK_TEXTURE_LOOKUP, NULL, NULL);
321   cogl_snippet_set_replace (snippet, "cogl_texel = vec4 (0.0, 0.0, 1.0, 0.0);");
322
323   pipeline = create_texture_pipeline (state);
324   cogl_pipeline_add_layer_snippet (pipeline, 0, snippet);
325   cogl_framebuffer_draw_textured_rectangle (fb,
326                                             pipeline,
327                                             90, 0, 100, 10,
328                                             0, 0, 0, 0);
329   cogl_object_unref (pipeline);
330
331   cogl_object_unref (snippet);
332
333   test_utils_check_pixel (fb, 95, 5, 0x0000ffff);
334 }
335
336 static void
337 test_replace_snippet (TestState *state)
338 {
339   CoglPipeline *pipeline;
340   CoglSnippet *snippet;
341
342   /* Test replacing a previous snippet */
343   pipeline = create_texture_pipeline (state);
344
345   snippet = cogl_snippet_new (COGL_SNIPPET_HOOK_FRAGMENT,
346                               NULL,
347                               "cogl_color_out = vec4 (0.5, 0.5, 0.5, 1.0);");
348   cogl_pipeline_add_snippet (pipeline, snippet);
349   cogl_object_unref (snippet);
350
351   snippet = cogl_snippet_new (COGL_SNIPPET_HOOK_FRAGMENT, NULL, NULL);
352   cogl_snippet_set_pre (snippet, "cogl_color_out = vec4 (1.0, 1.0, 1.0, 1.0);");
353   cogl_snippet_set_replace (snippet,
354                             "cogl_color_out *= vec4 (1.0, 0.0, 0.0, 1.0);");
355   cogl_pipeline_add_snippet (pipeline, snippet);
356   cogl_object_unref (snippet);
357
358   cogl_framebuffer_draw_textured_rectangle (fb,
359                                             pipeline,
360                                             100, 0, 110, 10,
361                                             0, 0, 0, 0);
362   cogl_object_unref (pipeline);
363
364   test_utils_check_pixel (fb, 105, 5, 0xff0000ff);
365 }
366
367 static void
368 test_replace_fragment_layer (TestState *state)
369 {
370   CoglPipeline *pipeline;
371   CoglSnippet *snippet;
372
373   /* Test replacing the fragment layer code */
374   pipeline = create_texture_pipeline (state);
375
376   snippet = cogl_snippet_new (COGL_SNIPPET_HOOK_LAYER_FRAGMENT, NULL, NULL);
377   cogl_snippet_set_replace (snippet, "cogl_layer = vec4 (0.0, 0.0, 1.0, 1.0);");
378   cogl_pipeline_add_layer_snippet (pipeline, 0, snippet);
379   cogl_object_unref (snippet);
380
381   /* Add a second layer which samples from the texture in the first
382      layer. The snippet override should cause the first layer not to
383      generate the code for the texture lookup but this second layer
384      should still be able to cause it to be generated */
385   cogl_pipeline_set_layer_combine (pipeline, 1,
386                                    "RGB = ADD(TEXTURE_0, PREVIOUS)"
387                                    "A = REPLACE(PREVIOUS)",
388                                    NULL);
389
390   cogl_framebuffer_draw_textured_rectangle (fb,
391                                             pipeline,
392                                             110, 0, 120, 10,
393                                             0, 0, 0, 0);
394   cogl_object_unref (pipeline);
395
396   test_utils_check_pixel (fb, 115, 5, 0xff00ffff);
397 }
398
399 static void
400 test_modify_fragment_layer (TestState *state)
401 {
402   CoglPipeline *pipeline;
403   CoglSnippet *snippet;
404
405   /* Test modifying the fragment layer code */
406   pipeline = cogl_pipeline_new (ctx);
407
408   cogl_pipeline_set_uniform_1f (pipeline,
409                                 cogl_pipeline_get_uniform_location (pipeline,
410                                                                     "a_value"),
411                                 0.5);
412
413   snippet = cogl_snippet_new (COGL_SNIPPET_HOOK_LAYER_FRAGMENT,
414                               "uniform float a_value;",
415                               "cogl_layer.g = a_value;");
416   cogl_pipeline_add_layer_snippet (pipeline, 0, snippet);
417   cogl_object_unref (snippet);
418
419   cogl_framebuffer_draw_textured_rectangle (fb,
420                                             pipeline,
421                                             120, 0, 130, 10,
422                                             0, 0, 0, 0);
423   cogl_object_unref (pipeline);
424
425   test_utils_check_pixel (fb, 125, 5, 0xff80ffff);
426 }
427
428 static void
429 test_modify_vertex_layer (TestState *state)
430 {
431   CoglPipeline *pipeline;
432   CoglSnippet *snippet;
433   CoglMatrix matrix;
434
435   /* Test modifying the vertex layer code */
436   pipeline = create_texture_pipeline (state);
437
438   cogl_matrix_init_identity (&matrix);
439   cogl_matrix_translate (&matrix, 0.0f, 1.0f, 0.0f);
440   cogl_pipeline_set_layer_matrix (pipeline, 0, &matrix);
441
442   snippet = cogl_snippet_new (COGL_SNIPPET_HOOK_TEXTURE_COORD_TRANSFORM,
443                               NULL,
444                               "cogl_tex_coord.x = 1.0;");
445   cogl_pipeline_add_layer_snippet (pipeline, 0, snippet);
446   cogl_object_unref (snippet);
447
448   cogl_framebuffer_draw_textured_rectangle (fb,
449                                             pipeline,
450                                             130, 0, 140, 10,
451                                             0, 0, 0, 0);
452   cogl_object_unref (pipeline);
453
454   test_utils_check_pixel (fb, 135, 5, 0xffff00ff);
455 }
456
457 static void
458 test_replace_vertex_layer (TestState *state)
459 {
460   CoglPipeline *pipeline;
461   CoglSnippet *snippet;
462   CoglMatrix matrix;
463
464   /* Test replacing the vertex layer code */
465   pipeline = create_texture_pipeline (state);
466
467   cogl_matrix_init_identity (&matrix);
468   cogl_matrix_translate (&matrix, 0.0f, 1.0f, 0.0f);
469   cogl_pipeline_set_layer_matrix (pipeline, 0, &matrix);
470
471   snippet = cogl_snippet_new (COGL_SNIPPET_HOOK_TEXTURE_COORD_TRANSFORM,
472                               NULL,
473                               NULL);
474   cogl_snippet_set_replace (snippet, "cogl_tex_coord.x = 1.0;\n");
475   cogl_pipeline_add_layer_snippet (pipeline, 0, snippet);
476   cogl_object_unref (snippet);
477
478   cogl_framebuffer_draw_textured_rectangle (fb,
479                                             pipeline,
480                                             140, 0, 150, 10,
481                                             0, 0, 0, 0);
482   cogl_object_unref (pipeline);
483
484   test_utils_check_pixel (fb, 145, 5, 0x00ff00ff);
485 }
486
487 static void
488 test_vertex_transform_hook (TestState *state)
489 {
490   CoglPipeline *pipeline;
491   CoglSnippet *snippet;
492   CoglMatrix identity_matrix;
493   CoglMatrix matrix;
494   int location;
495
496   /* Test the vertex transform hook */
497
498   cogl_matrix_init_identity (&identity_matrix);
499
500   pipeline = cogl_pipeline_new (ctx);
501
502   cogl_pipeline_set_color4ub (pipeline, 255, 0, 255, 255);
503
504   snippet = cogl_snippet_new (COGL_SNIPPET_HOOK_VERTEX_TRANSFORM,
505                               "uniform mat4 pmat;",
506                               NULL);
507   cogl_snippet_set_replace (snippet, "cogl_position_out = "
508                             "pmat * cogl_position_in;");
509   cogl_pipeline_add_snippet (pipeline, snippet);
510   cogl_object_unref (snippet);
511
512   /* Copy the current projection matrix to a uniform */
513   cogl_framebuffer_get_projection_matrix (fb, &matrix);
514   location = cogl_pipeline_get_uniform_location (pipeline, "pmat");
515   cogl_pipeline_set_uniform_matrix (pipeline,
516                                     location,
517                                     4, /* dimensions */
518                                     1, /* count */
519                                     FALSE, /* don't transpose */
520                                     cogl_matrix_get_array (&matrix));
521
522   /* Replace the real projection matrix with the identity. This should
523      mess up the drawing unless the snippet replacement is working */
524   cogl_framebuffer_set_projection_matrix (fb, &identity_matrix);
525
526   cogl_framebuffer_draw_rectangle (fb, pipeline, 150, 0, 160, 10);
527   cogl_object_unref (pipeline);
528
529   /* Restore the projection matrix */
530   cogl_framebuffer_set_projection_matrix (fb, &matrix);
531
532   test_utils_check_pixel (fb, 155, 5, 0xff00ffff);
533 }
534
535 static void
536 test_snippet_order (TestState *state)
537 {
538   CoglPipeline *pipeline;
539   CoglSnippet *snippet;
540
541   /* Verify that the snippets are executed in the right order. We'll
542      replace the r component of the color in the pre sections of the
543      snippets and the g component in the post. The pre sections should
544      be executed in the reverse order they were added and the post
545      sections in the same order as they were added. Therefore the r
546      component should be taken from the the second snippet and the g
547      component from the first */
548   pipeline = cogl_pipeline_new (ctx);
549
550   cogl_pipeline_set_color4ub (pipeline, 0, 0, 0, 255);
551
552   snippet = cogl_snippet_new (COGL_SNIPPET_HOOK_FRAGMENT,
553                               NULL,
554                               "cogl_color_out.g = 0.5;\n");
555   cogl_snippet_set_pre (snippet, "cogl_color_out.r = 0.5;\n");
556   cogl_snippet_set_replace (snippet, "cogl_color_out.ba = vec2 (0.0, 1.0);");
557   cogl_pipeline_add_snippet (pipeline, snippet);
558   cogl_object_unref (snippet);
559
560   snippet = cogl_snippet_new (COGL_SNIPPET_HOOK_FRAGMENT,
561                               NULL,
562                               "cogl_color_out.g = 1.0;\n");
563   cogl_snippet_set_pre (snippet, "cogl_color_out.r = 1.0;\n");
564   cogl_pipeline_add_snippet (pipeline, snippet);
565   cogl_object_unref (snippet);
566
567   cogl_framebuffer_draw_rectangle (fb, pipeline, 160, 0, 170, 10);
568   cogl_object_unref (pipeline);
569
570   test_utils_check_pixel (fb, 165, 5, 0x80ff00ff);
571 }
572
573 static void
574 test_naming_texture_units (TestState *state)
575 {
576   CoglPipeline *pipeline;
577   CoglSnippet *snippet;
578   CoglTexture *tex1, *tex2;
579
580   /* Test that we can sample from an arbitrary texture unit by naming
581      its layer number */
582
583   snippet = cogl_snippet_new (COGL_SNIPPET_HOOK_FRAGMENT,
584                               NULL,
585                               NULL);
586   cogl_snippet_set_replace (snippet,
587                             "cogl_color_out = "
588                             "texture2D (cogl_sampler100, vec2 (0.0, 0.0)) + "
589                             "texture2D (cogl_sampler200, vec2 (0.0, 0.0));");
590
591   tex1 = test_utils_create_color_texture (ctx, 0xff0000ff);
592   tex2 = test_utils_create_color_texture (ctx, 0x00ff00ff);
593
594   pipeline = cogl_pipeline_new (ctx);
595
596   cogl_pipeline_set_layer_texture (pipeline, 100, tex1);
597   cogl_pipeline_set_layer_texture (pipeline, 200, tex2);
598
599   cogl_pipeline_add_snippet (pipeline, snippet);
600
601   cogl_framebuffer_draw_rectangle (fb, pipeline, 0, 0, 10, 10);
602
603   cogl_object_unref (pipeline);
604   cogl_object_unref (snippet);
605   cogl_object_unref (tex1);
606   cogl_object_unref (tex2);
607
608   test_utils_check_pixel (fb, 5, 5, 0xffff00ff);
609 }
610
611 static void
612 test_snippet_properties (TestState *state)
613 {
614   CoglSnippet *snippet;
615
616   /* Sanity check modifying the snippet */
617   snippet = cogl_snippet_new (COGL_SNIPPET_HOOK_FRAGMENT, "foo", "bar");
618   g_assert_cmpstr (cogl_snippet_get_declarations (snippet), ==, "foo");
619   g_assert_cmpstr (cogl_snippet_get_post (snippet), ==, "bar");
620   g_assert_cmpstr (cogl_snippet_get_replace (snippet), ==, NULL);
621   g_assert_cmpstr (cogl_snippet_get_pre (snippet), ==, NULL);
622
623   cogl_snippet_set_declarations (snippet, "fu");
624   g_assert_cmpstr (cogl_snippet_get_declarations (snippet), ==, "fu");
625   g_assert_cmpstr (cogl_snippet_get_post (snippet), ==, "bar");
626   g_assert_cmpstr (cogl_snippet_get_replace (snippet), ==, NULL);
627   g_assert_cmpstr (cogl_snippet_get_pre (snippet), ==, NULL);
628
629   cogl_snippet_set_post (snippet, "ba");
630   g_assert_cmpstr (cogl_snippet_get_declarations (snippet), ==, "fu");
631   g_assert_cmpstr (cogl_snippet_get_post (snippet), ==, "ba");
632   g_assert_cmpstr (cogl_snippet_get_replace (snippet), ==, NULL);
633   g_assert_cmpstr (cogl_snippet_get_pre (snippet), ==, NULL);
634
635   cogl_snippet_set_pre (snippet, "fuba");
636   g_assert_cmpstr (cogl_snippet_get_declarations (snippet), ==, "fu");
637   g_assert_cmpstr (cogl_snippet_get_post (snippet), ==, "ba");
638   g_assert_cmpstr (cogl_snippet_get_replace (snippet), ==, NULL);
639   g_assert_cmpstr (cogl_snippet_get_pre (snippet), ==, "fuba");
640
641   cogl_snippet_set_replace (snippet, "baba");
642   g_assert_cmpstr (cogl_snippet_get_declarations (snippet), ==, "fu");
643   g_assert_cmpstr (cogl_snippet_get_post (snippet), ==, "ba");
644   g_assert_cmpstr (cogl_snippet_get_replace (snippet), ==, "baba");
645   g_assert_cmpstr (cogl_snippet_get_pre (snippet), ==, "fuba");
646
647   g_assert_cmpint (cogl_snippet_get_hook (snippet),
648                    ==,
649                    COGL_SNIPPET_HOOK_FRAGMENT);
650 }
651
652 static SnippetTestFunc
653 tests[] =
654   {
655     simple_fragment_snippet,
656     simple_vertex_snippet,
657     shared_uniform,
658     lots_snippets,
659     shared_variable_pre_post,
660     test_pipeline_caching,
661     test_replace_string,
662     test_texture_lookup_hook,
663     test_multiple_samples,
664     test_replace_lookup_hook,
665     test_replace_snippet,
666     test_replace_fragment_layer,
667     test_modify_fragment_layer,
668     test_modify_vertex_layer,
669     test_replace_vertex_layer,
670     test_vertex_transform_hook,
671     test_snippet_order,
672     test_naming_texture_units,
673     test_snippet_properties
674   };
675
676 static void
677 run_tests (TestState *state)
678 {
679   int i;
680
681   for (i = 0; i < G_N_ELEMENTS (tests); i++)
682     {
683       cogl_framebuffer_clear4f (fb,
684                                 COGL_BUFFER_BIT_COLOR,
685                                 0, 0, 0, 1);
686
687       tests[i] (state);
688     }
689 }
690
691 void
692 test_snippets (void)
693 {
694   /* If shaders aren't supported then we can't run the test */
695   if (cogl_features_available (COGL_FEATURE_SHADERS_GLSL))
696     {
697       TestState state;
698
699       cogl_framebuffer_orthographic (fb,
700                                      0, 0,
701                                      cogl_framebuffer_get_width (fb),
702                                      cogl_framebuffer_get_height (fb),
703                                      -1,
704                                      100);
705
706       run_tests (&state);
707
708       if (cogl_test_verbose ())
709         g_print ("OK\n");
710     }
711   else if (cogl_test_verbose ())
712     g_print ("Skipping\n");
713 }