2 * Copyright (C) 2011 The Android Open Source Project
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
17 #ifndef ANDROID_FILTERFW_CORE_SHADER_PROGRAM_H
18 #define ANDROID_FILTERFW_CORE_SHADER_PROGRAM_H
24 #include <GLES2/gl2.h>
25 #include <GLES2/gl2ext.h>
28 #include "core/gl_env.h"
29 #include "core/value.h"
35 class GLFrameBufferHandle;
36 class GLTextureHandle;
40 typedef GLint ProgramVar;
42 // A ShaderProgram is a Program object that holds a GLSL shader implementation.
43 // It provides functionality for compiling, linking, and executing the shader.
44 // On top of that, it provides access to the shaders source code, uniforms,
45 // attributes, and other properties.
46 // By default a ShaderProgram provides its own vertex shader. However, a custom
47 // vertex shader may be passed and used instead.
48 // When implementing a vertex shader, the following attribute names have special
51 // - a_position: The vertex position
52 // - a_texcoord: The texture cooridnates
54 // The shader program will bind these attributes to the correct values, if they
55 // are present in the vertex shader source code.
57 // When implementing the fragment shader, the following variable names must be
60 // - tex_sampler_<n>: The n'th input texture. For instance, use tex_sampler_0
61 // for the first input texture. Must be a uniform sampler2D.
62 // - v_texcoord: The current texture coordinate.
64 // If more input textures are given than the shader can handle, this will result
69 // General Functionality ///////////////////////////////////////////////////
70 // Create a new shader program with the given fragment shader source code.
71 // A default vertex shader is used, which renders the input texture to a
72 // rectangular region of the output texture. You can modify the input and
73 // output regions by using the SetSourceRegion(...) and SetTargetRegion(...)
74 // (and related) functions below.
75 // This program will not be executable until you have compiled and linked
77 // Note, that the ShaderProgram does NOT take ownership of the GLEnv. The
78 // caller must make sure the GLEnv stays valid as long as the GLFrame is
80 explicit ShaderProgram(GLEnv* gl_env, const std::string& fragment_shader);
82 // Create a new shader program with the given fragment and vertex shader
83 // source code. This program will not be executable until you have compiled
85 // Note, that the ShaderProgram does NOT take ownership of the GLEnv. The
86 // caller must make sure the GLEnv stays valid as long as the GLFrame is
88 ShaderProgram(GLEnv* gl_env,
89 const std::string& vertex_shader,
90 const std::string& fragment_shader);
95 // Process the given input frames and write the result to the output frame.
96 // Returns false if there was an error processing.
97 bool Process(const std::vector<const GLFrame*>& inputs, GLFrame* output);
99 // Same as above, but pass GL interfaces rather than frame objects. Use this
100 // only if you are not working on Frame objects, but rather directly on GL
101 // textures and FBOs.
102 bool Process(const std::vector<const GLTextureHandle*>& input,
103 GLFrameBufferHandle* output);
105 // Compile and link the shader source code. Returns true if compilation
106 // and linkage was successful. Compilation and linking error messages are
107 // written to the error log.
108 bool CompileAndLink();
110 // Returns true if this Program has been compiled and linked successfully.
111 bool IsExecutable() const {
112 return program_ != 0;
115 // Returns true if the shader program variable is valid.
116 static bool IsVarValid(ProgramVar var);
118 // Special ShaderPrograms //////////////////////////////////////////////////
119 // A (compiled) shader program which assigns the sampled pixels from the
120 // input to the output. Note that transformations may be applied to achieve
121 // effects such as cropping, scaling or rotation.
122 // The caller takes ownership of the result!
123 static ShaderProgram* CreateIdentity(GLEnv* env);
125 // Geometry ////////////////////////////////////////////////////////////////
126 // These functions modify the source and target regions used during
127 // rasterization. Note, that these functions will ONLY take effect if
128 // the default vertex shader is used, or your custom vertex shader defines
129 // the a_position and a_texcoord attributes.
131 // Set the program to read from a subregion of the input frame, given by
132 // the origin (x, y) and dimensions (width, height). Values are considered
133 // normalized between 0.0 and 1.0. If this region exceeds the input frame
134 // dimensions the results are undefined.
135 void SetSourceRect(float x, float y, float width, float height) ;
137 // Set the program to read from a subregion of the input frame, given by
138 // the passed Quad. Values are considered normalized between 0.0 and 1.0.
139 // The Quad points are expected to be in the order top-left, top-right,
140 // bottom-left, bottom-right.
141 // If this region exceeds the input frame dimensions the results are
143 void SetSourceRegion(const Quad& quad);
145 // Set the program to write to a subregion of the output frame, given by
146 // the origin (x, y) and dimensions (width, height). Values are considered
147 // normalized between 0.0 and 1.0. If this region exceeds the output frame
148 // dimensions the image will be clipped.
149 void SetTargetRect(float x, float y, float width, float height);
151 // Set the program to write to a subregion of the output frame, given by
152 // the passed Quad. Values are considered normalized between 0.0 and 1.0.
153 // The Quad points are expected to be in the order top-left, top-right,
154 // bottom-left, bottom-right.
155 // If this region exceeds the output frame dimensions the image will be
157 void SetTargetRegion(const Quad& quad);
159 // Uniform Variable access /////////////////////////////////////////////////
160 // Note: In order to get and set uniforms, the program must have been
161 // successfully compiled and linked. Otherwise, the getters will return an
162 // invalid ProgramVar variable (check with IsVarValid()).
163 // When setting values, the value type must be match the type of the uniform
164 // in the shader. For instance, a vector of 3 elements cannot be assigned to
165 // a vec2. Similarly, an integer value cannot be assigned to a float value.
166 // Such a type mismatch will result in failure to set the value (which will
167 // remain untouched). Check the return value of the setters to determine
170 // Returns the maximum number of uniforms supported by this implementation.
171 static int MaxUniformCount();
173 // Returns a handle to the uniform with the given name, or invalid if no
174 // such uniform variable exists in the shader.
175 ProgramVar GetUniform(const std::string& name) const;
177 // Set the specified uniform value to the given integer value. Returns true
178 // if the assignment was successful.
179 bool SetUniformValue(ProgramVar var, int value);
181 // Set the specified uniform value to the given float value. Returns true
182 // if the assignment was successful.
183 bool SetUniformValue(ProgramVar var, float value);
185 // Set the specified uniform value to the given values. Returns true
186 // if the assignment was successful.
187 bool SetUniformValue(ProgramVar var, const int* values, int count);
189 // Set the specified uniform value to the given values. Returns true
190 // if the assignment was successful.
191 bool SetUniformValue(ProgramVar var, const float* values, int count);
193 // Set the specified uniform value to the given vector value. Returns true
194 // if the assignment was successful.
195 bool SetUniformValue(ProgramVar var, const std::vector<int>& values);
197 // Set the specified uniform value to the given vector value. Returns true
198 // if the assignment was successful.
199 bool SetUniformValue(ProgramVar var, const std::vector<float>& values);
201 // Generic variable setter, which in the case of GL programs always attempts
202 // to set the value of a uniform variable with the given name. Only values
203 // of type float, float array (or vector), and int are supported.
204 bool SetUniformValue(const std::string& name, const Value& value);
206 // Generic variable getter, which in the case of GL programs always attempts
207 // to get the value of a uniform variable with the given name.
208 Value GetUniformValue(const std::string& name);
210 // Returns the default name of the input texture uniform variable for the
211 // given input index.
212 static std::string InputTextureUniformName(int index);
214 // Attribute access ////////////////////////////////////////////////////////
215 // Note: In order to get and set attributes, the program must have been
216 // successfully compiled and linked. Otherwise, the getters will return an
217 // invalid ProgramVar variable (check with IsVarValid()). Constant attribute
218 // values must be floats. Attribute pointers must be associated with a
219 // specific type, which can be any of the following:
220 // GL_BYTE, GL_UNSIGNED_BYTE, GL_SHORT, GL_UNSIGNED_SHORT, GL_FLOAT,
221 // GL_FIXED, GL_HALF_FLOAT_OES.
222 // When storing vertex data, it is recommended to use VertexFrames when
223 // possible as these will be kept in GPU memory, and no copying of vertex
224 // attributes between system and GPU memory needs to take place.
226 // Returns the maximum number of attributes supported by this
228 static int MaxAttributeCount();
230 // Returns a handle to the attribute with the given name, or invalid if no
231 // such attribute exists in the vertex shader.
232 ProgramVar GetAttribute(const std::string& name) const;
234 // Set an attribute value that will be constant for each vertex. Returns
235 // true if the assignment was successful.
236 bool SetConstAttributeValue(ProgramVar var, float value);
238 // Set an attribute vector value that will be constant for each vertex.
239 // Returns true if the assignment was successful.
240 bool SetConstAttributeValue(ProgramVar var, const std::vector<float>& value);
242 // Set attribute values that differ across vertexes, using a VertexFrame.
243 // This is the recommended method of specifying vertex data, that does not
244 // change from iteration to iteration. The parameters are as follows:
245 // var: The shader variable to bind the values to.
246 // data: The vertex frame which holds the vertex data. This may be a
247 // superset of the data required for this particular vertex. Use the
248 // offset and stride to select the correct data portion.
249 // type: The type of the data values. This may differ from the type of the
250 // shader variables. See the normalize flag on how values are
252 // components: The number of components per value. Valid values are 1-4.
253 // stride: The delta of one element to the next in bytes.
254 // offset: The offset of the first element.
255 // normalize: True, if not float values should be normalized to the range
256 // 0-1, when converted to a float.
257 // Returns true, if the assignment was successful.
258 bool SetAttributeValues(ProgramVar var,
259 const VertexFrame* data,
266 // Set attribute values that differ across vertexes, using a data buffer.
267 // This is the recommended method of specifying vertex data, if your data
268 // changes often. Note that this data may need to be copied to GPU memory
269 // for each render pass. Please see above for a description of the
271 // Note: The data passed here MUST be valid until all executions of this
272 // Program instance have been completed!
273 bool SetAttributeValues(ProgramVar var,
281 // Convenience method for setting vertex values using a vector of floats.
282 // The components parameter specifies how many elements per variable should
283 // be assigned (The variable must be able to fit the number of components).
284 // It must be a value between 1 and 4.
285 // While this method is not as flexible as the methods above, this can be
286 // used when more advanced methods are not necessary. Note, that if your
287 // vertex data does not change, it is recommended to use a VertexFrame.
288 bool SetAttributeValues(ProgramVar var,
289 const std::vector<float>& data,
292 // Same as above, but using a float pointer instead of vector. Pass the
293 // total number of elements in total.
294 bool SetAttributeValues(ProgramVar var,
299 // By default, rendering only uses the first 4 vertices. You should only
300 // adjust this value if you are providing your own vertex attributes with
301 // a count unequal to 4. Adjust this value before calling Process().
302 void SetVertexCount(int count);
304 // Returns the default name of the attribute used to hold the texture
305 // coordinates. Use this when you need to access the texture coordinate
306 // attribute of the shader's default vertex shader.
307 static const std::string& TexCoordAttributeName() {
308 static std::string s_texcoord("a_texcoord");
312 // Returns the default name of the attribute used to hold the output
313 // coordinates. Use this when you need to access the output coordinate
314 // attribute of the shader's default vertex shader.
315 static const std::string& PositionAttributeName() {
316 static std::string s_position("a_position");
320 // Rendering ///////////////////////////////////////////////////////////////
321 // Set the draw mode, which can be any of GL_POINTS, GL_LINES,
322 // GL_LINE_STRIP, GL_LINE_LOOP, GL_TRIANGLES, GL_TRIANGLE_STRIP,
323 // GL_TRIANGLE_FAN. The default is GL_TRIANGLE_STRIP.
324 // Warning: Do NOT change this if you are not specifying your own vertex
325 // data with SetAttributeValues(...).
326 void SetDrawMode(GLenum mode);
328 // If you are doing your own drawing you should call this before beginning
329 // to draw. This will activate the program, push all used attributes, and
330 // clear the frame if requested. You do not need to call this if you are
331 // not doing your own GL drawing!
334 // Render a single frame with the given input textures. You may override
335 // this, if you need custom rendering behavior. However, you must take
336 // care of the following things when overriding:
337 // - Use the correct program (e.g. by calling UseProgram()).
338 // - Bind the given textures
339 // - Bind vertex attributes
341 bool RenderFrame(const std::vector<GLuint>& textures,
342 const std::vector<GLenum>& targets);
344 // Pass true to clear the output frame before rendering. The color used
345 // to clear is set in SetClearColor().
346 void SetClearsOutput(bool clears);
348 // Set the color used to clear the output frame before rendering. You
349 // must activate clearing by calling SetClearsOutput(true).
350 void SetClearColor(float red, float green, float blue, float alpha);
352 // Set the number of tiles to split rendering into. Higher tile numbers
353 // will affect performance negatively, but will allow other GPU threads
354 // to render more frequently. Defaults to 1, 1.
355 void SetTileCounts(int x_count, int y_count);
357 // Enable or Disable Blending
358 // Set to true to enable, false to disable.
359 void SetBlendEnabled(bool enable) {
363 // Specify pixel arithmetic for blending
364 // The values of sfactor and dfactor can be:
365 // GL_ZERO, GL_ONE, GL_SRC_COLOR, GL_ONE_MINUS_SRC_COLOR, GL_SRC_ALPHA,
366 // GL_ONE_MINUS_SRC_ALPHA, GL_DST_ALPHA, GL_ONE_MINUS_DST_ALPHA,
367 // GL_DST_COLOR, GL_ONE_MINUS_DST_COLOR, GL_SRC_ALPHA_SATURATE
368 // Default values for blending are set to:
369 // sfactor = GL_SRC_ALPHA
370 // dfactor = GL_ONE_MINUS_SRC_ALPHA
371 void SetBlendFunc(int sfactor, int dfactor) {
376 // Accessing the Compiled Program //////////////////////////////////////////
377 // Use the compiled and linked program for rendering. You should not need
378 // to call this, unless you are implementing your own rendering method.
381 // Other Properties ////////////////////////////////////////////////////////
382 // Returns the maximum number of varyings supported by this implementation.
383 static int MaxVaryingCount();
385 // Returns the maximum number of texture units supported by this
387 static int MaxTextureUnits();
389 // Lower level functionality ///////////////////////////////////////////////
390 // Compile the shader with the given source. The shader_type must be either
391 // GL_VERTEX_SHADER or GL_FRAGMENT_SHADER.
392 static GLuint CompileShader(GLenum shader_type, const char* source);
394 // Link the compiled shader objects and return the resulting program.
395 static GLuint LinkProgram(GLuint* shaders, GLuint count);
397 // Returns the lowest texture unit that will be used to bind textures.
398 GLuint BaseTextureUnit() const {
399 return base_texture_unit_;
402 // Sets the lowest texture unit that will be used to bind textures. The
403 // default value is GL_TEXTURE0.
404 void SetBaseTextureUnit(GLuint texture_unit) {
405 base_texture_unit_ = texture_unit;
409 // Structure to store vertex attribute data.
410 struct VertexAttrib {
424 typedef std::map<ProgramVar, VertexAttrib> VertexAttribMap;
432 RGBAColor() : red(0), green(0), blue(0), alpha(1) {
436 // Scans for all uniforms in the shader and creates index -> id map.
439 // Returns the index of the given uniform. The caller must make sure
440 // that the variable id passed is valid.
441 GLuint IndexOfUniform(ProgramVar var);
443 // Binds the given input textures.
444 bool BindInputTextures(const std::vector<GLuint>& textures,
445 const std::vector<GLenum>& targets);
447 // Sets the default source and target coordinates.
448 void SetDefaultCoords();
450 // Pushes the specified coordinates to the shader attribute.
451 bool PushCoords(ProgramVar attr, float* coords);
453 // Pushes the source coordinates.
454 bool PushSourceCoords(float* coords);
456 // Pushes the target coordinates.
457 bool PushTargetCoords(float* coords);
459 // Performs (simple) GL drawing.
462 // Performs tiled GL drawing.
465 // Yields to other GPU threads.
468 // Helper method to assert that the variable value passed has the correct
470 static bool CheckValueCount(const std::string& var_type,
471 const std::string& var_name,
476 // Helper method to assert that the variable value passed has a size, that
477 // is compatible with the type size (must be divisible).
478 static bool CheckValueMult(const std::string& var_type,
479 const std::string& var_name,
483 // Checks that the variable is valid. Logs an error and returns false if
485 static bool CheckVarValid(ProgramVar var);
487 // Returns true if the uniform specified by var is an active uniform in the
489 bool CheckUniformValid(ProgramVar var);
491 // Store an attribute to use when rendering.
492 bool StoreAttribute(VertexAttrib attrib);
494 // Push all assigned attributes before rendering.
495 bool PushAttributes();
497 // Pop all assigned attributes after rendering.
498 bool PopAttributes();
500 // The shader source code
501 std::string fragment_shader_source_;
502 std::string vertex_shader_source_;
504 // The compiled shaders and linked program
505 GLuint fragment_shader_;
506 GLuint vertex_shader_;
509 // The GL environment this shader lives in.
512 // The lowest texture unit this program will use
513 GLuint base_texture_unit_;
515 // The current source and target coordinates to render from/to.
516 float* source_coords_;
517 float* target_coords_;
519 // True, if the program has control over both source and target coordinates.
520 bool manage_coordinates_;
522 // The number of tiles to split rendering into.
526 // List of attribute data that we need to set before rendering
527 VertexAttribMap attrib_values_;
529 // The number of vertices to render
532 // The draw mode used during rendering
535 // True, iff the output frame is cleared before rendering
538 // The color used to clear the output frame.
539 RGBAColor clear_color_;
541 // Set to true to enable blending.
546 // Map from uniform ids to indices
547 std::map<ProgramVar, GLuint> uniform_indices_;
550 } // namespace filterfw
551 } // namespace android
553 #endif // ANDROID_FILTERFW_CORE_SHADER_PROGRAM_H