Hi, we currently have a zoo of shaders to render layers:
RGBALayerProgramType, BGRALayerProgramType, RGBXLayerProgramType, BGRXLayerProgramType, RGBARectLayerProgramType, RGBXRectLayerProgramType, BGRARectLayerProgramType, RGBAExternalLayerProgramType, ColorLayerProgramType, YCbCrLayerProgramType, ComponentAlphaPass1ProgramType, ComponentAlphaPass1RGBProgramType, ComponentAlphaPass2ProgramType, ComponentAlphaPass2RGBProgramType, (I have just eliminated the Copy2D variants, so omitted here.) Next, I would like to replace everything but the YCbCr and ComponentAlpha shaders with one unified shader (attached below). Rationale: Most of our shader programs only differ minimally in cycle count, and we are generally memory bound, not GPU cycle bound (even on mobile). In addition, GPUs are actually are very efficient at branching, as long the branch is uniform and doesn't change direction per pixel or vertex (the driver compiles essentially variants and runs that). Last but not least, switching shaders tends to be expensive. Proposed approach: We use a single shader to replace the current 8 layer shaders. I verified with the mali shader compiler that the shortest path (color layer) is pretty close to the old color shader (is now 3, due to the opacity multiplication, was 1). For a lot of scenes we will be able to render without ever switching shaders, so that should more than make up for the extra cycles, especially since we are memory bound anyway. More uniforms have to be set per shader invocation, but that should be pretty cheap. I completely dropped the distinction of 2D and 3D masks. 3D masks should be able to handle the 2D case and the cycle savings are minimal, and as mentioned before, irrelevant. An important advantage is that with this approach we can now easily add additional layer effects to the pipeline without exponentially exploding the number of programs (RGBXRectLayerProgramWithGrayscaleAndWithoutOpacityButMaskAndNotMask3D…). Also, last but not least, this reduces code complexity quite a bit. Feedback welcome. Thanks, Andreas --- // Base color (will be rendered if layer texture is not read). uniform vec4 uColor; // Layer texture (disabled for color layers). uniform bool uTextureEnabled; uniform vec2 uTexCoordMultiplier; uniform bool uTextureBGRA; // Default is RGBA. uniform bool uTextureNoAlpha; uniform float uTextureOpacity; uniform sampler2D uTexture; uniform bool uTextureUseExternalOES; uniform samplerExternalOES uTextureExternalOES; #ifndef GL_ES uniform bool uTextureUseRect; uniform sampler2DRect uTextureRect; #endif // Masking (optional) uniform bool uMaskEnabled; varying vec3 vMaskCoord; uniform sampler2D uMaskTexture; void main() { vec4 color = uColor; if (uTextureEnabled) { vec2 texCoord = vTexCoord * uTexCoordMultiplier; if (uTextureUseExternalOES) { color = texture2D(uTextureExternalOES, texCoord); #ifndef GL_ES } else if (uTextureUseRect) { color = texture2DRect(uTexture, texCoord); #endif } else { color = texture2D(uTexture, texCoord); } if (uTextureBGRA) { color = color.bgra; } if (uTextureNoAlpha) { color = vec4(color.rgb, 1.0); } color *= uTextureOpacity; } if (uMaskEnabled) { color *= texture2D(uMaskTexture, vMaskCoord.xy / vMaskCoord.z).r; } gl_FragColor = color; } _______________________________________________ dev-platform mailing list dev-platform@lists.mozilla.org https://lists.mozilla.org/listinfo/dev-platform