4 * An object oriented GL/GLES Abstraction/Utility Layer
6 * Copyright (C) 2011 Intel Corporation.
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; either
11 * version 2 of the License, or (at your option) any later version.
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library. If not, see
20 * <http://www.gnu.org/licenses/>.
25 * Neil Roberts <neil@linux.intel.com>
34 #include "cogl-pipeline-snippet-private.h"
35 #include "cogl-snippet-private.h"
36 #include "cogl-util.h"
38 /* Helper functions that are used by both GLSL pipeline backends */
41 _cogl_pipeline_snippet_generate_code (const CoglPipelineSnippetData *data)
43 CoglPipelineSnippet *first_snippet, *snippet;
47 first_snippet = COGL_LIST_FIRST (data->snippets);
49 /* First count the number of snippets so we can easily tell when
50 we're at the last one */
51 COGL_LIST_FOREACH (snippet, data->snippets, list_node)
52 if (snippet->snippet->hook == data->hook)
54 /* Don't bother processing any previous snippets if we reach
55 one that has a replacement */
56 if (snippet->snippet->replace)
59 first_snippet = snippet;
65 /* If there weren't any snippets then generate a stub function with
69 if (data->return_type)
70 g_string_append_printf (data->source_buf,
79 data->argument_declarations ?
80 data->argument_declarations : "",
82 data->arguments ? data->arguments : "");
84 g_string_append_printf (data->source_buf,
92 data->argument_declarations ?
93 data->argument_declarations : "",
95 data->arguments ? data->arguments : "");
100 for (snippet = first_snippet, snippet_num = 0;
101 snippet_num < n_snippets;
102 snippet = COGL_LIST_NEXT (snippet, list_node), snippet_num++)
103 if (snippet->snippet->hook == data->hook)
107 if ((source = cogl_snippet_get_declarations (snippet->snippet)))
108 g_string_append (data->source_buf, source);
110 g_string_append_printf (data->source_buf,
117 if (snippet_num + 1 < n_snippets)
118 g_string_append_printf (data->source_buf,
120 data->function_prefix,
123 g_string_append (data->source_buf, data->final_name);
125 g_string_append (data->source_buf, " (");
127 if (data->argument_declarations)
128 g_string_append (data->source_buf, data->argument_declarations);
130 g_string_append (data->source_buf,
134 if (data->return_type && !data->return_variable_is_argument)
135 g_string_append_printf (data->source_buf,
139 data->return_variable);
141 if ((source = cogl_snippet_get_pre (snippet->snippet)))
142 g_string_append (data->source_buf, source);
144 /* Chain on to the next function, or bypass it if there is
146 if ((source = cogl_snippet_get_replace (snippet->snippet)))
147 g_string_append (data->source_buf, source);
150 g_string_append (data->source_buf, " ");
152 if (data->return_type)
153 g_string_append_printf (data->source_buf,
155 data->return_variable);
158 g_string_append_printf (data->source_buf,
160 data->function_prefix,
163 g_string_append (data->source_buf, data->chain_function);
165 g_string_append (data->source_buf, " (");
168 g_string_append (data->source_buf, data->arguments);
170 g_string_append (data->source_buf, ");\n");
173 if ((source = cogl_snippet_get_post (snippet->snippet)))
174 g_string_append (data->source_buf, source);
176 if (data->return_type)
177 g_string_append_printf (data->source_buf,
179 data->return_variable);
181 g_string_append (data->source_buf, "}\n");
186 _cogl_pipeline_snippet_free (CoglPipelineSnippet *pipeline_snippet)
188 cogl_object_unref (pipeline_snippet->snippet);
189 g_slice_free (CoglPipelineSnippet, pipeline_snippet);
193 _cogl_pipeline_snippet_list_free (CoglPipelineSnippetList *list)
195 CoglPipelineSnippet *pipeline_snippet, *tmp;
197 COGL_LIST_FOREACH_SAFE (pipeline_snippet, list, list_node, tmp)
198 _cogl_pipeline_snippet_free (pipeline_snippet);
202 _cogl_pipeline_snippet_list_add (CoglPipelineSnippetList *list,
203 CoglSnippet *snippet)
205 CoglPipelineSnippet *pipeline_snippet = g_slice_new (CoglPipelineSnippet);
207 pipeline_snippet->snippet = cogl_object_ref (snippet);
209 _cogl_snippet_make_immutable (pipeline_snippet->snippet);
211 if (COGL_LIST_EMPTY (list))
212 COGL_LIST_INSERT_HEAD (list, pipeline_snippet, list_node);
215 CoglPipelineSnippet *tail;
217 for (tail = COGL_LIST_FIRST (list);
218 COGL_LIST_NEXT (tail, list_node);
219 tail = COGL_LIST_NEXT (tail, list_node));
221 COGL_LIST_INSERT_AFTER (tail, pipeline_snippet, list_node);
226 _cogl_pipeline_snippet_list_copy (CoglPipelineSnippetList *dst,
227 const CoglPipelineSnippetList *src)
229 CoglPipelineSnippet *tail = NULL;
230 const CoglPipelineSnippet *l;
232 COGL_LIST_INIT (dst);
234 COGL_LIST_FOREACH (l, src, list_node)
236 CoglPipelineSnippet *copy = g_slice_dup (CoglPipelineSnippet, l);
238 cogl_object_ref (copy->snippet);
241 COGL_LIST_INSERT_AFTER (tail, copy, list_node);
243 COGL_LIST_INSERT_HEAD (dst, copy, list_node);
250 _cogl_pipeline_snippet_list_hash (CoglPipelineSnippetList *list,
253 CoglPipelineSnippet *l;
255 COGL_LIST_FOREACH (l, list, list_node)
257 *hash = _cogl_util_one_at_a_time_hash (*hash,
259 sizeof (CoglSnippet *));
264 _cogl_pipeline_snippet_list_equal (CoglPipelineSnippetList *list0,
265 CoglPipelineSnippetList *list1)
267 CoglPipelineSnippet *l0, *l1;
269 for (l0 = COGL_LIST_FIRST (list0), l1 = COGL_LIST_FIRST (list1);
271 l0 = COGL_LIST_NEXT (l0, list_node), l1 = COGL_LIST_NEXT (l1, list_node))
272 if (l0->snippet != l1->snippet)
275 return l0 == NULL && l1 == NULL;