blob: d011219dd0cf0e6886963f6cd46b3402fb07785e [file] [log] [blame]
Alex Sakhartchoukb4d7bb62010-12-21 14:42:26 -08001/*
2 * Copyright (C) 2008 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
17package android.renderscript;
18
19
20import android.util.Config;
21import android.util.Log;
22
23
24/**
25 * @hide
26 *
27 **/
28public class ProgramFragmentFixedFunction extends ProgramFragment {
29 ProgramFragmentFixedFunction(int id, RenderScript rs) {
30 super(id, rs);
31 }
32
33 static class InternalBuilder extends BaseProgramBuilder {
34 public InternalBuilder(RenderScript rs) {
35 super(rs);
36 }
37
38 public ProgramFragmentFixedFunction create() {
39 mRS.validate();
40 int[] tmp = new int[(mInputCount + mOutputCount + mConstantCount + mTextureCount) * 2];
41 int idx = 0;
42
43 for (int i=0; i < mInputCount; i++) {
44 tmp[idx++] = ProgramParam.INPUT.mID;
45 tmp[idx++] = mInputs[i].getID();
46 }
47 for (int i=0; i < mOutputCount; i++) {
48 tmp[idx++] = ProgramParam.OUTPUT.mID;
49 tmp[idx++] = mOutputs[i].getID();
50 }
51 for (int i=0; i < mConstantCount; i++) {
52 tmp[idx++] = ProgramParam.CONSTANT.mID;
53 tmp[idx++] = mConstants[i].getID();
54 }
55 for (int i=0; i < mTextureCount; i++) {
56 tmp[idx++] = ProgramParam.TEXTURE_TYPE.mID;
57 tmp[idx++] = mTextureTypes[i].mID;
58 }
59
60 int id = mRS.nProgramFragmentCreate(mShader, tmp);
61 ProgramFragmentFixedFunction pf = new ProgramFragmentFixedFunction(id, mRS);
62 initProgram(pf);
63 return pf;
64 }
65 }
66
67 public static class Builder {
68 public static final int MAX_TEXTURE = 2;
69 int mNumTextures;
70 boolean mPointSpriteEnable;
71 boolean mVaryingColorEnable;
72 String mShader;
73 RenderScript mRS;
74
75 public enum EnvMode {
76 REPLACE (1),
77 MODULATE (2),
78 DECAL (3);
79
80 int mID;
81 EnvMode(int id) {
82 mID = id;
83 }
84 }
85
86 public enum Format {
87 ALPHA (1),
88 LUMINANCE_ALPHA (2),
89 RGB (3),
90 RGBA (4);
91
92 int mID;
93 Format(int id) {
94 mID = id;
95 }
96 }
97
98 private class Slot {
99 EnvMode env;
100 Format format;
101 Slot(EnvMode _env, Format _fmt) {
102 env = _env;
103 format = _fmt;
104 }
105 }
106 Slot[] mSlots;
107
108 private void buildShaderString() {
109 mShader = "//rs_shader_internal\n";
110 mShader += "varying lowp vec4 varColor;\n";
111 mShader += "varying vec2 varTex0;\n";
112
113 mShader += "void main() {\n";
114 if (mVaryingColorEnable) {
115 mShader += " lowp vec4 col = varColor;\n";
116 } else {
117 mShader += " lowp vec4 col = UNI_Color;\n";
118 }
119
120 if (mNumTextures != 0) {
121 if (mPointSpriteEnable) {
122 mShader += " vec2 t0 = gl_PointCoord;\n";
123 } else {
124 mShader += " vec2 t0 = varTex0.xy;\n";
125 }
126 }
127
128 for(int i = 0; i < mNumTextures; i ++) {
129 switch(mSlots[i].env) {
130 case REPLACE:
131 switch (mSlots[i].format) {
132 case ALPHA:
133 mShader += " col.a = texture2D(UNI_Tex0, t0).a;\n";
134 break;
135 case LUMINANCE_ALPHA:
136 mShader += " col.rgba = texture2D(UNI_Tex0, t0).rgba;\n";
137 break;
138 case RGB:
139 mShader += " col.rgb = texture2D(UNI_Tex0, t0).rgb;\n";
140 break;
141 case RGBA:
142 mShader += " col.rgba = texture2D(UNI_Tex0, t0).rgba;\n";
143 break;
144 }
145 break;
146 case MODULATE:
147 switch (mSlots[i].format) {
148 case ALPHA:
149 mShader += " col.a *= texture2D(UNI_Tex0, t0).a;\n";
150 break;
151 case LUMINANCE_ALPHA:
152 mShader += " col.rgba *= texture2D(UNI_Tex0, t0).rgba;\n";
153 break;
154 case RGB:
155 mShader += " col.rgb *= texture2D(UNI_Tex0, t0).rgb;\n";
156 break;
157 case RGBA:
158 mShader += " col.rgba *= texture2D(UNI_Tex0, t0).rgba;\n";
159 break;
160 }
161 break;
162 case DECAL:
163 mShader += " col = texture2D(UNI_Tex0, t0);\n";
164 break;
165 }
166 }
167
168 mShader += " gl_FragColor = col;\n";
169 mShader += "}\n";
170 }
171
172 public Builder(RenderScript rs) {
173 mRS = rs;
174 mSlots = new Slot[MAX_TEXTURE];
175 mPointSpriteEnable = false;
176 }
177
178 public Builder setTexture(EnvMode env, Format fmt, int slot)
179 throws IllegalArgumentException {
180 if((slot < 0) || (slot >= MAX_TEXTURE)) {
181 throw new IllegalArgumentException("MAX_TEXTURE exceeded.");
182 }
183 mSlots[slot] = new Slot(env, fmt);
184 return this;
185 }
186
187 public Builder setPointSpriteTexCoordinateReplacement(boolean enable) {
188 mPointSpriteEnable = enable;
189 return this;
190 }
191
192 public Builder setVaryingColor(boolean enable) {
193 mVaryingColorEnable = enable;
194 return this;
195 }
196
197 public ProgramFragmentFixedFunction create() {
198 InternalBuilder sb = new InternalBuilder(mRS);
199 mNumTextures = 0;
200 for(int i = 0; i < MAX_TEXTURE; i ++) {
201 if(mSlots[i] != null) {
202 mNumTextures ++;
203 }
204 }
205 buildShaderString();
206 sb.setShader(mShader);
207
208 Type constType = null;
209 if (!mVaryingColorEnable) {
210 Element.Builder b = new Element.Builder(mRS);
211 b.add(Element.F32_4(mRS), "Color");
212 Type.Builder typeBuilder = new Type.Builder(mRS, b.create());
213 typeBuilder.setX(1);
214 constType = typeBuilder.create();
215 sb.addConstant(constType);
216 }
217 for (int i = 0; i < mNumTextures; i ++) {
218 sb.addTexture(TextureType.TEXTURE_2D);
219 }
220
221 ProgramFragmentFixedFunction pf = sb.create();
222 pf.mTextureCount = MAX_TEXTURE;
223 if (!mVaryingColorEnable) {
224 Allocation constantData = Allocation.createTyped(mRS,constType);
225 float[] data = new float[4];
226 data[0] = data[1] = data[2] = data[3] = 1.0f;
227 constantData.copyFrom(data);
228 pf.bindConstants(constantData, 0);
229 }
230 return pf;
231 }
232 }
233}
234
235
236
237