1 /* 2 * Copyright (C) 2011 The Android Open Source Project 3 * 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 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 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. 15 */ 16 17 #ifndef ANDROID_FILTERFW_CORE_SHADER_PROGRAM_H 18 #define ANDROID_FILTERFW_CORE_SHADER_PROGRAM_H 19 20 #include <vector> 21 #include <map> 22 #include <string> 23 24 #include <GLES2/gl2.h> 25 #include <GLES2/gl2ext.h> 26 #include <EGL/egl.h> 27 28 #include "core/gl_env.h" 29 #include "core/value.h" 30 31 namespace android { 32 namespace filterfw { 33 34 class GLFrame; 35 class GLFrameBufferHandle; 36 class GLTextureHandle; 37 class Quad; 38 class VertexFrame; 39 40 typedef GLint ProgramVar; 41 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 49 // meaning: 50 // 51 // - a_position: The vertex position 52 // - a_texcoord: The texture cooridnates 53 // 54 // The shader program will bind these attributes to the correct values, if they 55 // are present in the vertex shader source code. 56 // 57 // When implementing the fragment shader, the following variable names must be 58 // defined: 59 // 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. 63 // 64 // If more input textures are given than the shader can handle, this will result 65 // in an error. 66 // 67 class ShaderProgram { 68 public: 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 76 // it. 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 79 // alive. 80 explicit ShaderProgram(GLEnv* gl_env, const std::string& fragment_shader); 81 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 84 // and linked it. 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 87 // alive. 88 ShaderProgram(GLEnv* gl_env, 89 const std::string& vertex_shader, 90 const std::string& fragment_shader); 91 92 // Destructor. 93 ~ShaderProgram(); 94 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); 98 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); 104 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(); 109 110 // Returns true if this Program has been compiled and linked successfully. IsExecutable()111 bool IsExecutable() const { 112 return program_ != 0; 113 } 114 115 // Returns true if the shader program variable is valid. 116 static bool IsVarValid(ProgramVar var); 117 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); 124 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. 130 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) ; 136 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 142 // undefined. 143 void SetSourceRegion(const Quad& quad); 144 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); 150 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 156 // clipped. 157 void SetTargetRegion(const Quad& quad); 158 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 168 // success. 169 170 // Returns the maximum number of uniforms supported by this implementation. 171 static int MaxUniformCount(); 172 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; 176 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); 180 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); 184 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); 188 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); 192 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); 196 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); 200 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); 205 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); 209 210 // Returns the default name of the input texture uniform variable for the 211 // given input index. 212 static std::string InputTextureUniformName(int index); 213 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. 225 226 // Returns the maximum number of attributes supported by this 227 // implementation. 228 static int MaxAttributeCount(); 229 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; 233 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); 237 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); 241 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 251 // converted. 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, 260 GLenum type, 261 int components, 262 int stride, 263 int offset, 264 bool normalize); 265 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 270 // parameters. 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, 274 const uint8_t* data, 275 GLenum type, 276 int components, 277 int stride, 278 int offset, 279 bool normalize); 280 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, 290 int components); 291 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, 295 const float* data, 296 int total, 297 int components); 298 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); 303 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. TexCoordAttributeName()307 static const std::string& TexCoordAttributeName() { 308 static std::string s_texcoord("a_texcoord"); 309 return s_texcoord; 310 } 311 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. PositionAttributeName()315 static const std::string& PositionAttributeName() { 316 static std::string s_position("a_position"); 317 return s_position; 318 } 319 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); 327 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! 332 bool BeginDraw(); 333 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 340 // - Draw 341 bool RenderFrame(const std::vector<GLuint>& textures, 342 const std::vector<GLenum>& targets); 343 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); 347 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); 351 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); 356 357 // Enable or Disable Blending 358 // Set to true to enable, false to disable. SetBlendEnabled(bool enable)359 void SetBlendEnabled(bool enable) { 360 blending_ = enable; 361 } 362 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 SetBlendFunc(int sfactor,int dfactor)371 void SetBlendFunc(int sfactor, int dfactor) { 372 sfactor_ = sfactor; 373 dfactor_ = dfactor; 374 } 375 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. 379 bool UseProgram(); 380 381 // Other Properties //////////////////////////////////////////////////////// 382 // Returns the maximum number of varyings supported by this implementation. 383 static int MaxVaryingCount(); 384 385 // Returns the maximum number of texture units supported by this 386 // implementation. 387 static int MaxTextureUnits(); 388 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); 393 394 // Link the compiled shader objects and return the resulting program. 395 static GLuint LinkProgram(GLuint* shaders, GLuint count); 396 397 // Returns the lowest texture unit that will be used to bind textures. BaseTextureUnit()398 GLuint BaseTextureUnit() const { 399 return base_texture_unit_; 400 } 401 402 // Sets the lowest texture unit that will be used to bind textures. The 403 // default value is GL_TEXTURE0. SetBaseTextureUnit(GLuint texture_unit)404 void SetBaseTextureUnit(GLuint texture_unit) { 405 base_texture_unit_ = texture_unit; 406 } 407 408 private: 409 // Structure to store vertex attribute data. 410 struct VertexAttrib { 411 bool is_const; 412 int index; 413 bool normalized; 414 int stride; 415 int components; 416 int offset; 417 GLenum type; 418 GLuint vbo; 419 const void* values; 420 float* owned_data; 421 422 VertexAttrib(); 423 }; 424 typedef std::map<ProgramVar, VertexAttrib> VertexAttribMap; 425 426 struct RGBAColor { 427 float red; 428 float green; 429 float blue; 430 float alpha; 431 RGBAColorRGBAColor432 RGBAColor() : red(0), green(0), blue(0), alpha(1) { 433 } 434 }; 435 436 // Scans for all uniforms in the shader and creates index -> id map. 437 void ScanUniforms(); 438 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); 442 443 // Binds the given input textures. 444 bool BindInputTextures(const std::vector<GLuint>& textures, 445 const std::vector<GLenum>& targets); 446 447 // Sets the default source and target coordinates. 448 void SetDefaultCoords(); 449 450 // Pushes the specified coordinates to the shader attribute. 451 bool PushCoords(ProgramVar attr, float* coords); 452 453 // Pushes the source coordinates. 454 bool PushSourceCoords(float* coords); 455 456 // Pushes the target coordinates. 457 bool PushTargetCoords(float* coords); 458 459 // Performs (simple) GL drawing. 460 bool Draw(); 461 462 // Performs tiled GL drawing. 463 bool DrawTiled(); 464 465 // Yields to other GPU threads. 466 void Yield(); 467 468 // Helper method to assert that the variable value passed has the correct 469 // total size. 470 static bool CheckValueCount(const std::string& var_type, 471 const std::string& var_name, 472 int expected_count, 473 int components, 474 int value_size); 475 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, 480 int components, 481 int value_size); 482 483 // Checks that the variable is valid. Logs an error and returns false if 484 // not. 485 static bool CheckVarValid(ProgramVar var); 486 487 // Returns true if the uniform specified by var is an active uniform in the 488 // program. 489 bool CheckUniformValid(ProgramVar var); 490 491 // Store an attribute to use when rendering. 492 bool StoreAttribute(VertexAttrib attrib); 493 494 // Push all assigned attributes before rendering. 495 bool PushAttributes(); 496 497 // Pop all assigned attributes after rendering. 498 bool PopAttributes(); 499 500 // The shader source code 501 std::string fragment_shader_source_; 502 std::string vertex_shader_source_; 503 504 // The compiled shaders and linked program 505 GLuint fragment_shader_; 506 GLuint vertex_shader_; 507 GLuint program_; 508 509 // The GL environment this shader lives in. 510 GLEnv* gl_env_; 511 512 // The lowest texture unit this program will use 513 GLuint base_texture_unit_; 514 515 // The current source and target coordinates to render from/to. 516 float* source_coords_; 517 float* target_coords_; 518 519 // True, if the program has control over both source and target coordinates. 520 bool manage_coordinates_; 521 522 // The number of tiles to split rendering into. 523 int tile_x_count_; 524 int tile_y_count_; 525 526 // List of attribute data that we need to set before rendering 527 VertexAttribMap attrib_values_; 528 529 // The number of vertices to render 530 int vertex_count_; 531 532 // The draw mode used during rendering 533 GLenum draw_mode_; 534 535 // True, iff the output frame is cleared before rendering 536 bool clears_; 537 538 // The color used to clear the output frame. 539 RGBAColor clear_color_; 540 541 // Set to true to enable blending. 542 bool blending_; 543 int sfactor_; 544 int dfactor_; 545 546 // Map from uniform ids to indices 547 std::map<ProgramVar, GLuint> uniform_indices_; 548 }; 549 550 } // namespace filterfw 551 } // namespace android 552 553 #endif // ANDROID_FILTERFW_CORE_SHADER_PROGRAM_H 554