ProgramCache.cpp revision ac670c0433d19397d4e36ced2110475b6f54fe26
1ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy/* 2ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy * Copyright (C) 2010 The Android Open Source Project 3ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy * 4ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy * Licensed under the Apache License, Version 2.0 (the "License"); 5ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy * you may not use this file except in compliance with the License. 6ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy * You may obtain a copy of the License at 7ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy * 8ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy * http://www.apache.org/licenses/LICENSE-2.0 9ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy * 10ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy * Unless required by applicable law or agreed to in writing, software 11ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy * distributed under the License is distributed on an "AS IS" BASIS, 12ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy * See the License for the specific language governing permissions and 14ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy * limitations under the License. 15ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy */ 16ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy 17ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy#define LOG_TAG "OpenGLRenderer" 18ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy 19ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy#include <utils/String8.h> 20ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy 21ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy#include "ProgramCache.h" 22ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy 23ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guynamespace android { 24ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guynamespace uirenderer { 25ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy 26ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy/////////////////////////////////////////////////////////////////////////////// 27ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy// Vertex shaders snippets 28ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy/////////////////////////////////////////////////////////////////////////////// 29ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy 30ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy// TODO: Implement BitmapShader, implement repeat/mirror for npot 31ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy 32ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guyconst char* gVS_Header_Attributes = 33ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy "attribute vec4 position;\n"; 34ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guyconst char* gVS_Header_Attributes_TexCoords = 35ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy "attribute vec2 texCoords;\n"; 36ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guyconst char* gVS_Header_Uniforms = 37ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy "uniform mat4 transform;\n"; 38ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guyconst char* gVS_Header_Uniforms_HasGradient = 39ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy "uniform float gradientLength;\n" 40ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy "uniform vec2 gradient;\n" 41ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy "uniform vec2 gradientStart;\n" 42ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy "uniform mat4 screenSpace;\n"; 43ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guyconst char* gVS_Header_Varyings_HasTexture = 44ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy "varying vec2 outTexCoords;\n"; 45ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guyconst char* gVS_Header_Varyings_HasBitmap = 46ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy "varying vec2 outBitmapTexCoords;\n"; 47ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guyconst char* gVS_Header_Varyings_HasGradient = 48ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy "varying float index;\n"; 49ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guyconst char* gVS_Main = 50ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy "\nvoid main(void) {\n"; 51ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guyconst char* gVS_Main_OutTexCoords = 52ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy " outTexCoords = texCoords;\n"; 53ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guyconst char* gVS_Main_OutGradientIndex = 54ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy " vec4 location = screenSpace * position;\n" 55ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy " index = dot(location.xy - gradientStart, gradient) * gradientLength;\n"; 56ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guyconst char* gVS_Main_Position = 57ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy " gl_Position = transform * position;\n"; 58ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guyconst char* gVS_Footer = 59ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy "}\n\n"; 60ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy 61ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy/////////////////////////////////////////////////////////////////////////////// 62ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy// Fragment shaders snippets 63ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy/////////////////////////////////////////////////////////////////////////////// 64ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy 65ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guyconst char* gFS_Header = 66ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy "precision mediump float;\n\n"; 67ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guyconst char* gFS_Uniforms_Color = 68ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy "uniform vec4 color;\n"; 69ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guyconst char* gFS_Uniforms_TextureSampler = 70ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy "uniform sampler2D sampler;\n"; 71ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guyconst char* gFS_Uniforms_GradientSampler = 72ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy "uniform sampler2D gradientSampler;\n"; 73ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guyconst char* gFS_Uniforms_BitmapSampler = 74ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy "uniform sampler2D bitmapSampler;\n"; 75ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guyconst char* gFS_Uniforms_ColorOp[4] = { 76ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy // None 77ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy "", 78ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy // Matrix 79ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy "uniform mat4 colorMatrix;\n" 80ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy "uniform vec4 colorMatrixVector;\n", 81ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy // Lighting 82ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy "uniform float lightingMul;\n" 83ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy "uniform float lightingAdd;\n", 84ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy // PorterDuff 85ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy "uniform vec4 colorBLend;\n" 86ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy}; 87ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guyconst char* gFS_Main = 88ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy "\nvoid main(void) {\n" 89ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy " vec4 fragColor;\n"; 90ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guyconst char* gFS_Main_FetchColor = 91ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy " fragColor = color;\n"; 92ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guyconst char* gFS_Main_FetchTexture = 93ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy " fragColor = color * texture2D(sampler, outTexCoords);\n"; 94ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guyconst char* gFS_Main_FetchA8Texture = 95ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy " fragColor = color * texture2D(sampler, outTexCoords).a;\n"; 96ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guyconst char* gFS_Main_FetchGradient = 97ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy " vec4 gradientColor = texture2D(gradientSampler, vec2(index, 0.5));\n"; 98ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guyconst char* gFS_Main_FetchBitmap = 99ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy " vec4 bitmapColor = texture2D(bitmapSampler, outBitmapTexCoords);\n"; 100ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guyconst char* gFS_Main_BlendShadersBG = 101ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy " fragColor = blendShaders(bitmapColor, gradientColor)"; 102ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guyconst char* gFS_Main_BlendShadersGB = 103ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy " fragColor = blendShaders(gradientColor, bitmapColor)"; 104ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guyconst char* gFS_Main_BlendShaders_Modulate = 105ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy " * fragColor.a;\n"; 106ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guyconst char* gFS_Main_FragColor = 107ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy " gl_FragColor = fragColor;\n"; 108ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guyconst char* gFS_Main_ApplyColorOp[4] = { 109ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy // None 110ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy "", 111ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy // Matrix 112ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy " fragColor *= colorMatrix;\n" 113ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy " fragColor += colorMatrixVector;\n", 114ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy // Lighting 115ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy " fragColor *= lightingMul;\n" 116ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy " fragColor += lightingAdd;\n", 117ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy // PorterDuff 118ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy " fragColor = blendColors(colorBlend, fragColor);\n" 119ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy}; 120ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guyconst char* gFS_Footer = 121ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy "}\n\n"; 122ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy 123ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy/////////////////////////////////////////////////////////////////////////////// 124ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy// PorterDuff snippets 125ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy/////////////////////////////////////////////////////////////////////////////// 126ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy 127ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guyconst char* gPorterDuff[12] = { 128ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy // Clear 129ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy "return vec4(0.0, 0.0, 0.0, 0.0);\n", 130ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy // Src 131ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy "return src;\n", 132ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy // Dst 133ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy "return dst;\n", 134ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy // SrcOver 135ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy "return vec4(src.rgb + (1.0 - src.a) * dst.rgb, src.a + dst.a - src.a * dst.a);\n", 136ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy // DstOver 137ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy "return vec4(dst.rgb + (1.0 - dst.a) * src.rgb, src.a + dst.a - src.a * dst.a);\n", 138ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy // SrcIn 139ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy "return vec4(src.rgb * dst.a, src.a * dst.a);\n", 140ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy // DstIn 141ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy "return vec4(dst.rgb * src.a, src.a * dst.a);\n", 142ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy // SrcOut 143ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy "return vec4(src.rgb * (1.0 - dst.a), src.a * (1.0 - dst.a));\n", 144ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy // DstOut 145ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy "return vec4(dst.rgb * (1.0 - src.a), dst.a * (1.0 - src.a));\n", 146ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy // SrcAtop 147ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy "return vec4(src.rgb * dst.a + (1.0 - src.a) * dst.rgb, dst.a);\n", 148ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy // DstAtop 149ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy "return vec4(dst.rgb * src.a + (1.0 - dst.a) * src.rgb, src.a);\n", 150ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy // Xor 151ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy "return vec4(src.rgb * (1.0 - dst.a) + (1.0 - src.a) * dst.rgb, " 152ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy "src.a + dst.a - 2.0 * src.a * dst.a);\n", 153ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy}; 154ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy 155ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy/////////////////////////////////////////////////////////////////////////////// 156ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy// Constructors/destructors 157ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy/////////////////////////////////////////////////////////////////////////////// 158ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy 159ac670c0433d19397d4e36ced2110475b6f54fe26Romain GuyProgramCache::ProgramCache() { 160ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy} 161ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy 162ac670c0433d19397d4e36ced2110475b6f54fe26Romain GuyProgramCache::~ProgramCache() { 163ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy clear(); 164ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy} 165ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy 166ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy/////////////////////////////////////////////////////////////////////////////// 167ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy// Cache management 168ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy/////////////////////////////////////////////////////////////////////////////// 169ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy 170ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guyvoid ProgramCache::clear() { 171ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy size_t count = mCache.size(); 172ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy for (size_t i = 0; i < count; i++) { 173ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy delete mCache.valueAt(i); 174ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy } 175ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy mCache.clear(); 176ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy} 177ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy 178ac670c0433d19397d4e36ced2110475b6f54fe26Romain GuyProgram* ProgramCache::get(const ProgramDescription& description) { 179ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy programid key = description.key(); 180ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy ssize_t index = mCache.indexOfKey(key); 181ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy Program* program = NULL; 182ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy if (index < 0) { 183ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy PROGRAM_LOGD("Could not find program with key 0x%x", key); 184ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy program = generateProgram(description, key); 185ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy mCache.add(key, program); 186ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy } else { 187ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy program = mCache.valueAt(index); 188ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy } 189ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy return program; 190ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy} 191ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy 192ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy/////////////////////////////////////////////////////////////////////////////// 193ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy// Program generation 194ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy/////////////////////////////////////////////////////////////////////////////// 195ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy 196ac670c0433d19397d4e36ced2110475b6f54fe26Romain GuyProgram* ProgramCache::generateProgram(const ProgramDescription& description, programid key) { 197ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy String8 vertexShader = generateVertexShader(description); 198ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy String8 fragmentShader = generateFragmentShader(description); 199ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy 200ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy Program* program = new Program(vertexShader.string(), fragmentShader.string()); 201ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy return program; 202ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy} 203ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy 204ac670c0433d19397d4e36ced2110475b6f54fe26Romain GuyString8 ProgramCache::generateVertexShader(const ProgramDescription& description) { 205ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy // Add attributes 206ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy String8 shader(gVS_Header_Attributes); 207ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy if (description.hasTexture || description.hasBitmap) { 208ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy shader.append(gVS_Header_Attributes_TexCoords); 209ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy } 210ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy // Uniforms 211ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy shader.append(gVS_Header_Uniforms); 212ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy if (description.hasGradient) { 213ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy shader.append(gVS_Header_Uniforms_HasGradient); 214ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy } 215ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy // Varyings 216ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy if (description.hasTexture) { 217ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy shader.append(gVS_Header_Varyings_HasTexture); 218ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy } 219ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy if (description.hasGradient) { 220ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy shader.append(gVS_Header_Varyings_HasGradient); 221ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy } 222ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy if (description.hasBitmap) { 223ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy shader.append(gVS_Header_Varyings_HasBitmap); 224ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy } 225ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy 226ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy // Begin the shader 227ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy shader.append(gVS_Main); { 228ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy if (description.hasTexture) { 229ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy shader.append(gVS_Main_OutTexCoords); 230ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy } 231ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy if (description.hasGradient) { 232ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy shader.append(gVS_Main_OutGradientIndex); 233ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy } 234ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy // Output transformed position 235ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy shader.append(gVS_Main_Position); 236ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy } 237ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy // End the shader 238ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy shader.append(gVS_Footer); 239ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy 240ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy PROGRAM_LOGD("*** Generated vertex shader:\n\n%s", shader.string()); 241ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy 242ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy return shader; 243ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy} 244ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy 245ac670c0433d19397d4e36ced2110475b6f54fe26Romain GuyString8 ProgramCache::generateFragmentShader(const ProgramDescription& description) { 246ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy // Set the default precision 247ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy String8 shader(gFS_Header); 248ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy 249ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy // Varyings 250ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy if (description.hasTexture) { 251ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy shader.append(gVS_Header_Varyings_HasTexture); 252ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy } 253ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy if (description.hasGradient) { 254ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy shader.append(gVS_Header_Varyings_HasGradient); 255ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy } 256ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy if (description.hasBitmap) { 257ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy shader.append(gVS_Header_Varyings_HasBitmap); 258ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy } 259ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy 260ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy 261ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy // Uniforms 262ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy shader.append(gFS_Uniforms_Color); 263ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy if (description.hasTexture) { 264ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy shader.append(gFS_Uniforms_TextureSampler); 265ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy } 266ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy if (description.hasGradient) { 267ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy shader.append(gFS_Uniforms_GradientSampler); 268ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy } 269ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy if (description.hasBitmap) { 270ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy shader.append(gFS_Uniforms_BitmapSampler); 271ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy } 272ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy shader.append(gFS_Uniforms_ColorOp[description.colorOp]); 273ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy 274ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy // Generate required functions 275ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy if (description.hasGradient && description.hasBitmap) { 276ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy generatePorterDuffBlend(shader, "blendShaders", description.shadersMode); 277ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy } 278ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy if (description.colorOp == ProgramDescription::kColorBlend) { 279ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy generatePorterDuffBlend(shader, "blendColors", description.colorMode); 280ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy } 281ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy 282ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy // Begin the shader 283ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy shader.append(gFS_Main); { 284ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy // Stores the result in fragColor directly 285ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy if (description.hasTexture) { 286ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy if (description.hasAlpha8Texture) { 287ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy shader.append(gFS_Main_FetchA8Texture); 288ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy } else { 289ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy shader.append(gFS_Main_FetchTexture); 290ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy } 291ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy } else { 292ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy shader.append(gFS_Main_FetchColor); 293ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy } 294ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy if (description.hasGradient) { 295ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy shader.append(gFS_Main_FetchGradient); 296ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy } 297ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy if (description.hasBitmap) { 298ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy shader.append(gFS_Main_FetchBitmap); 299ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy } 300ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy // Case when we have two shaders set 301ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy if (description.hasGradient && description.hasBitmap) { 302ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy if (description.isBitmapFirst) { 303ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy shader.append(gFS_Main_BlendShadersBG); 304ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy } else { 305ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy shader.append(gFS_Main_BlendShadersGB); 306ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy } 307ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy shader.append(gFS_Main_BlendShaders_Modulate); 308ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy } 309ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy // Apply the color op if needed 310ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy shader.append(gFS_Main_ApplyColorOp[description.colorOp]); 311ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy // Output the fragment 312ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy shader.append(gFS_Main_FragColor); 313ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy } 314ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy // End the shader 315ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy shader.append(gFS_Footer); 316ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy 317ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy PROGRAM_LOGD("*** Generated fragment shader:\n\n%s", shader.string()); 318ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy return shader; 319ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy} 320ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy 321ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guyvoid ProgramCache::generatePorterDuffBlend(String8& shader, const char* name, 322ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy SkXfermode::Mode mode) { 323ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy shader.append("\nvec4 "); 324ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy shader.append(name); 325ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy shader.append("(vec4 src, vec4 dst) {\n"); 326ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy shader.append(" "); 327ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy shader.append(gPorterDuff[mode]); 328ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy shader.append("}\n"); 329ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy} 330ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy 331ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy}; // namespace uirenderer 332ac670c0433d19397d4e36ced2110475b6f54fe26Romain Guy}; // namespace android 333