4
* An object oriented GL/GLES Abstraction/Utility Layer
6
* Copyright (C) 2008,2009 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 <http://www.gnu.org/licenses/>.
30
#include "cogl-internal.h"
31
#include "cogl-context.h"
32
#include "cogl-handle.h"
34
#ifdef HAVE_COGL_GLES2
38
#include "cogl-shader-private.h"
39
#include "cogl-program.h"
41
static void _cogl_program_free (CoglProgram *program);
43
COGL_HANDLE_DEFINE (Program, program);
46
_cogl_program_free (CoglProgram *program)
50
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
52
/* Unref all of the attached shaders */
53
g_slist_foreach (program->attached_shaders, (GFunc) cogl_handle_unref, NULL);
54
/* Destroy the list */
55
g_slist_free (program->attached_shaders);
57
_cogl_gles2_clear_cache_for_program ((CoglHandle) program);
59
if (ctx->drv.gles2.settings.user_program == (CoglHandle) program)
61
ctx->drv.gles2.settings.user_program = COGL_INVALID_HANDLE;
62
ctx->drv.gles2.settings_dirty = TRUE;
65
for (i = 0; i < COGL_GLES2_NUM_CUSTOM_UNIFORMS; i++)
66
if (program->custom_uniform_names[i])
67
g_free (program->custom_uniform_names[i]);
71
cogl_create_program (void)
75
program = g_slice_new (CoglProgram);
76
program->attached_shaders = NULL;
77
memset (program->custom_uniform_names, 0,
78
COGL_GLES2_NUM_CUSTOM_UNIFORMS * sizeof (char *));
80
return _cogl_program_handle_new (program);
84
cogl_program_attach_shader (CoglHandle program_handle,
85
CoglHandle shader_handle)
89
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
91
if (!cogl_is_program (program_handle) || !cogl_is_shader (shader_handle))
94
program = _cogl_program_pointer_from_handle (program_handle);
95
program->attached_shaders
96
= g_slist_prepend (program->attached_shaders,
97
cogl_handle_ref (shader_handle));
99
/* Whenever the shader changes we will need to relink the program
100
with the fixed functionality shaders so we should forget the
102
_cogl_gles2_clear_cache_for_program (program);
106
cogl_program_link (CoglHandle handle)
108
/* There's no point in linking the program here because it will have
109
to be relinked with a different fixed functionality shader
110
whenever the settings change */
114
cogl_program_use (CoglHandle handle)
116
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
118
if (handle != COGL_INVALID_HANDLE && !cogl_is_program (handle))
121
ctx->drv.gles2.settings.user_program = handle;
122
ctx->drv.gles2.settings_dirty = TRUE;
126
cogl_program_get_uniform_location (CoglHandle handle,
127
const char *uniform_name)
130
CoglProgram *program;
132
if (!cogl_is_program (handle))
135
program = _cogl_program_pointer_from_handle (handle);
137
/* We can't just ask the GL program object for the uniform location
138
directly because it will change every time the program is linked
139
with a new fixed functionality shader. Instead we make our own
140
mapping of uniform numbers and cache the names */
141
for (i = 0; program->custom_uniform_names[i]
142
&& i < COGL_GLES2_NUM_CUSTOM_UNIFORMS; i++)
143
if (!strcmp (program->custom_uniform_names[i], uniform_name))
146
if (i < COGL_GLES2_NUM_CUSTOM_UNIFORMS)
148
program->custom_uniform_names[i] = g_strdup (uniform_name);
152
/* We've run out of space for new uniform names so just pretend it
158
cogl_program_uniform_1f (int uniform_no,
161
cogl_program_uniform_float (uniform_no, 1, 1, &value);
165
cogl_program_uniform_1i (int uniform_no,
168
cogl_program_uniform_int (uniform_no, 1, 1, &value);
172
cogl_program_uniform_x (int uniform_no,
179
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
181
if (uniform_no >= 0 && uniform_no < COGL_GLES2_NUM_CUSTOM_UNIFORMS
182
&& size >= 1 && size <= 4 && count >= 1)
184
CoglBoxedValue *bv = ctx->drv.gles2.custom_uniforms + uniform_no;
189
g_free (bv->v.array);
191
memcpy (bv->v.float_value, value, value_size);
197
if (bv->count != count || bv->size != size || bv->type != type)
199
g_free (bv->v.array);
200
bv->v.array = g_malloc (count * value_size);
204
bv->v.array = g_malloc (count * value_size);
206
memcpy (bv->v.array, value, count * value_size);
213
ctx->drv.gles2.dirty_custom_uniforms |= 1 << uniform_no;
218
cogl_program_uniform_float (int uniform_no,
221
const GLfloat *value)
223
cogl_program_uniform_x (uniform_no, size, count, COGL_BOXED_FLOAT,
224
sizeof (float) * size, value);
228
cogl_program_uniform_int (int uniform_no,
233
cogl_program_uniform_x (uniform_no, size, count, COGL_BOXED_INT,
234
sizeof (int) * size, value);
238
cogl_program_uniform_matrix (int uniform_no,
242
const GLfloat *value)
246
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
248
bv = ctx->drv.gles2.custom_uniforms + uniform_no;
250
cogl_program_uniform_x (uniform_no, size, count, COGL_BOXED_MATRIX,
251
sizeof (float) * size * size, value);
253
bv->transpose = transpose;
256
#else /* HAVE_COGL_GLES2 */
258
/* No support on regular OpenGL 1.1 */
261
cogl_create_program (void)
263
return COGL_INVALID_HANDLE;
267
cogl_is_program (CoglHandle handle)
273
cogl_program_ref (CoglHandle handle)
275
return COGL_INVALID_HANDLE;
279
cogl_program_unref (CoglHandle handle)
284
cogl_program_attach_shader (CoglHandle program_handle,
285
CoglHandle shader_handle)
290
cogl_program_link (CoglHandle program_handle)
295
cogl_program_use (CoglHandle program_handle)
300
cogl_program_get_uniform_location (CoglHandle program_handle,
301
const char *uniform_name)
307
cogl_program_uniform_1f (int uniform_no,
313
cogl_program_uniform_float (int uniform_no,
316
const GLfloat *value)
321
cogl_program_uniform_int (int uniform_no,
329
cogl_program_uniform_matrix (int uniform_no,
333
const GLfloat *value)
338
#endif /* HAVE_COGL_GLES2 */