GNOME Bugzilla – Bug 656426
Improve the generated GLSL code
Last modified: 2011-09-05 19:49:08 UTC
The code generated by the GLSL fragend isn't at all optimized and totally relies on the compiler to optimize out redundant code. For example, here is reasonably common use of a material which can interpolate between two textures based on the alpha channel of a third texture: /* Attach the two images to the first two layers. We need these layers for the texture but we're not actually going to use the combine mode from it */ cogl_material_set_layer (priv->material, 0, tex); cogl_material_set_layer (priv->material, 1, another_tex); /* The third layer has the interpolation texture and sets up a combine layer which accesses the textures from the previous directly */ cogl_material_set_layer (priv->material, 2, mask); cogl_material_set_layer_combine (priv->material, 2, /* layer_index */ "RGBA = INTERPOLATE (TEXTURE_0," " TEXTURE_1," " TEXTURE[A])", NULL); This generates the following code (with added comments): void main () { /* This does a texture lookup to calculate the first layer */ cogl_color_out.rgba = (cogl_color_in.rgba) * (texture2D (_cogl_sampler_0, cogl_tex_coord_in[0].st).rgba); /* This does another texture lookup for the second layer */ cogl_color_out.rgba = (cogl_color_out.rgba) * (texture2D (_cogl_sampler_1, cogl_tex_coord_in[1].st).rgba); /* This discards the two previous layers to calculate the third layer. Note that it also does the texture lookups again and also does a lookup for the third texure twice */ cogl_color_out.rgba = texture2D (_cogl_sampler_0, cogl_tex_coord_in[0].st).rgba) * texture2D (_cogl_sampler_2, cogl_tex_coord_in[2].st).aaaa) + (texture2D (_cogl_sampler_1, cogl_tex_coord_in[1].st).rgba) * (vec4(1.0, 1.0, 1.0, 1.0).rgba - (texture2D (_cogl_sampler_2, cogl_tex_coord_in[2].st).aaaa)); }
Created attachment 193732 [details] [review] fragend-glsl: Don't generate code for ignored layers This patch changes it so that code for each layer is generated on demand instead of directly in the add_layer implementation. The pipeline only explicitly generates code for the last layer. If this layer references the result from any other layers, these will also be recursively generated. This means that if a layer is using 'REPLACE' then it won't redundantly generate the code for the previous layers. The result for each layer is generated into a variable called layer%i where %i is the layer index (not the unit index). Therefore to get the result from layer n we just have to refer to the varible layern.
Created attachment 193733 [details] [review] cogl-pipeline-fragend-glsl: Cache the results of texture lookups Whenever a texture lookup is performed for a layer the result is now stored in a variable and used repeatedly instead of generating the code for the lookup every time it is accessed. This means for example when using the INTERPOLATE function with a texture lookup for the third parameter it will only generate one texture lookup instead of two.
With the patches, the generated code is: void main () { vec4 layer2; vec4 texel0 = texture2D (_cogl_sampler_0, cogl_tex_coord_in[0].st); vec4 texel1 = texture2D (_cogl_sampler_1, cogl_tex_coord_in[1].st); vec4 texel2 = texture2D (_cogl_sampler_2, cogl_tex_coord_in[2].st); layer2.rgba = (texel0.rgba) * (texel2.aaaa) + (texel1.rgba) * (vec4(1.0, 1.0, 1.0, 1.0).rgba - (texel2.aaaa)); cogl_color_out = layer2; }
thanks these have landed in master now