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