blob: 83321d3c4601b34399ddf1bd73014893d87f44d9 [file] [log] [blame]
Jason Samsd19f10d2009-05-22 14:03:28 -07001/*
2 * Copyright (C) 2009 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
Alex Sakhartchoukaa7d2882010-05-21 12:53:13 -070017#ifndef ANDROID_RS_BUILD_FOR_HOST
Jason Samsd19f10d2009-05-22 14:03:28 -070018#include "rsContext.h"
Jason Sams4b962e52009-06-22 17:15:15 -070019#include <GLES/gl.h>
20#include <GLES/glext.h>
Jason Samsbb51c402009-11-25 13:22:07 -080021#include <GLES2/gl2.h>
22#include <GLES2/gl2ext.h>
Alex Sakhartchoukaa7d2882010-05-21 12:53:13 -070023#else
24#include "rsContextHostStub.h"
25#include <OpenGL/gl.h>
26#include <OpenGL/glext.h>
27#endif //ANDROID_RS_BUILD_FOR_HOST
28
29#include "rsProgramFragment.h"
Jason Sams4b962e52009-06-22 17:15:15 -070030
Jason Samsd19f10d2009-05-22 14:03:28 -070031using namespace android;
32using namespace android::renderscript;
33
34
Jason Sams68afd012009-12-17 16:55:08 -080035ProgramFragment::ProgramFragment(Context *rsc, const uint32_t * params,
36 uint32_t paramLength) :
Jason Sams0011bcf2009-12-15 12:58:36 -080037 Program(rsc)
Jason Samsd19f10d2009-05-22 14:03:28 -070038{
Jason Sams61f08d62009-09-25 16:37:33 -070039 mAllocFile = __FILE__;
40 mAllocLine = __LINE__;
Jason Sams442a6472010-08-04 17:50:20 -070041 rsAssert(paramLength == 6);
42
43 mConstantColor[0] = 1.f;
44 mConstantColor[1] = 1.f;
45 mConstantColor[2] = 1.f;
46 mConstantColor[3] = 1.f;
Jason Sams68afd012009-12-17 16:55:08 -080047
48 mEnvModes[0] = (RsTexEnvMode)params[0];
49 mTextureFormats[0] = params[1];
50 mEnvModes[1] = (RsTexEnvMode)params[2];
51 mTextureFormats[1] = params[3];
52 mPointSpriteEnable = params[4] != 0;
Jason Sams442a6472010-08-04 17:50:20 -070053 mVaryingColor = false;
54 if (paramLength > 5)
55 mVaryingColor = params[5] != 0;
Jason Sams68afd012009-12-17 16:55:08 -080056
Jason Samsd19f10d2009-05-22 14:03:28 -070057 mTextureEnableMask = 0;
Jason Sams68afd012009-12-17 16:55:08 -080058 if (mEnvModes[0]) {
59 mTextureEnableMask |= 1;
60 }
61 if (mEnvModes[1]) {
62 mTextureEnableMask |= 2;
63 }
Jason Sams442a6472010-08-04 17:50:20 -070064
Alex Sakhartchouk8442e0b2010-08-31 12:02:01 -070065 init(rsc);
Jason Samsd19f10d2009-05-22 14:03:28 -070066}
67
Jason Sams7e5ab3b2009-12-15 13:27:04 -080068ProgramFragment::ProgramFragment(Context *rsc, const char * shaderText,
69 uint32_t shaderLength, const uint32_t * params,
70 uint32_t paramLength) :
71 Program(rsc, shaderText, shaderLength, params, paramLength)
72{
73 mAllocFile = __FILE__;
74 mAllocLine = __LINE__;
75
Jason Sams442a6472010-08-04 17:50:20 -070076 mConstantColor[0] = 1.f;
77 mConstantColor[1] = 1.f;
78 mConstantColor[2] = 1.f;
79 mConstantColor[3] = 1.f;
80
81 LOGE("Custom FP");
82
Jason Sams7e5ab3b2009-12-15 13:27:04 -080083 mTextureEnableMask = (1 << mTextureCount) -1;
Alex Sakhartchouk8442e0b2010-08-31 12:02:01 -070084
85 init(rsc);
Jason Sams7e5ab3b2009-12-15 13:27:04 -080086}
87
88
Jason Samsd19f10d2009-05-22 14:03:28 -070089ProgramFragment::~ProgramFragment()
90{
91}
92
Jason Sams442a6472010-08-04 17:50:20 -070093void ProgramFragment::setConstantColor(float r, float g, float b, float a)
94{
95 mConstantColor[0] = r;
96 mConstantColor[1] = g;
97 mConstantColor[2] = b;
98 mConstantColor[3] = a;
99 mDirty = true;
100}
101
Jason Samsb13ada52009-08-25 11:34:49 -0700102void ProgramFragment::setupGL(const Context *rsc, ProgramFragmentState *state)
Jason Samsd19f10d2009-05-22 14:03:28 -0700103{
Jason Samsd19f10d2009-05-22 14:03:28 -0700104}
105
Jason Samsbb51c402009-11-25 13:22:07 -0800106void ProgramFragment::setupGL2(const Context *rsc, ProgramFragmentState *state, ShaderCache *sc)
107{
Jason Sams5dbfe932010-01-27 14:41:43 -0800108
Jason Samsbb51c402009-11-25 13:22:07 -0800109 //LOGE("sgl2 frag1 %x", glGetError());
110 if ((state->mLast.get() == this) && !mDirty) {
Jason Sams7c1f4c32010-06-22 17:22:13 -0700111 return;
Jason Samsbb51c402009-11-25 13:22:07 -0800112 }
113 state->mLast.set(this);
114
Jason Sams5dbfe932010-01-27 14:41:43 -0800115 rsc->checkError("ProgramFragment::setupGL2 start");
Jason Sams442a6472010-08-04 17:50:20 -0700116
117 if (!mVaryingColor &&
118 (sc->fragUniformSlot(mConstantColorUniformIndex) >= 0)) {
119 //LOGE("mConstantColorUniformIndex %i %i", mConstantColorUniformIndex, sc->fragUniformSlot(mConstantColorUniformIndex));
120 glUniform4fv(sc->fragUniformSlot(mConstantColorUniformIndex), 1, mConstantColor);
121 rsc->checkError("ProgramFragment::color setup");
122 }
123
Alex Sakhartchouk8442e0b2010-08-31 12:02:01 -0700124 rsc->checkError("ProgramFragment::setupGL2 begin uniforms");
125 setupUserConstants(sc, true);
126
Jason Samsbb51c402009-11-25 13:22:07 -0800127 for (uint32_t ct=0; ct < MAX_TEXTURE; ct++) {
128 glActiveTexture(GL_TEXTURE0 + ct);
129 if (!(mTextureEnableMask & (1 << ct)) || !mTextures[ct].get()) {
Jason Samsbb51c402009-11-25 13:22:07 -0800130 continue;
131 }
132
Jason Sams3b7d39b2009-12-14 12:57:40 -0800133 mTextures[ct]->uploadCheck(rsc);
Jason Samsbb51c402009-11-25 13:22:07 -0800134 glBindTexture(GL_TEXTURE_2D, mTextures[ct]->getTextureID());
Jason Sams5dbfe932010-01-27 14:41:43 -0800135 rsc->checkError("ProgramFragment::setupGL2 tex bind");
Jason Samsbb51c402009-11-25 13:22:07 -0800136 if (mSamplers[ct].get()) {
Jason Sams2978bfc2010-02-22 15:37:51 -0800137 mSamplers[ct]->setupGL(rsc, mTextures[ct]->getType()->getIsNp2());
Jason Samsbb51c402009-11-25 13:22:07 -0800138 } else {
139 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
140 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
141 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
142 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
Jason Sams5dbfe932010-01-27 14:41:43 -0800143 rsc->checkError("ProgramFragment::setupGL2 tex env");
Jason Samsbb51c402009-11-25 13:22:07 -0800144 }
145
Alex Sakhartchoukcaaac0f82010-09-02 18:43:24 -0700146 glUniform1i(sc->fragUniformSlot(mTextureUniformIndexStart + ct), ct);
Jason Sams5dbfe932010-01-27 14:41:43 -0800147 rsc->checkError("ProgramFragment::setupGL2 uniforms");
Jason Samsbb51c402009-11-25 13:22:07 -0800148 }
149
150 glActiveTexture(GL_TEXTURE0);
151 mDirty = false;
Jason Samsa09a6e12010-01-06 11:57:52 -0800152 rsc->checkError("ProgramFragment::setupGL2");
Jason Samsbb51c402009-11-25 13:22:07 -0800153}
154
Jason Sams5dad8b42009-12-15 19:10:11 -0800155void ProgramFragment::loadShader(Context *rsc) {
156 Program::loadShader(rsc, GL_FRAGMENT_SHADER);
Jason Samsbb51c402009-11-25 13:22:07 -0800157}
158
159void ProgramFragment::createShader()
160{
161 mShader.setTo("precision mediump float;\n");
Jason Sams1911c602010-08-05 17:38:29 -0700162 mShader.append("varying lowp vec4 varColor;\n");
Jason Samsbb51c402009-11-25 13:22:07 -0800163 mShader.append("varying vec4 varTex0;\n");
Jason Sams442a6472010-08-04 17:50:20 -0700164 mShader.append("uniform vec4 uni_Color;\n");
Jason Samsbb51c402009-11-25 13:22:07 -0800165
Jason Sams7e5ab3b2009-12-15 13:27:04 -0800166 if (mUserShader.length() > 1) {
Alex Sakhartchoukcaaac0f82010-09-02 18:43:24 -0700167 appendUserConstants();
Jason Sams7e5ab3b2009-12-15 13:27:04 -0800168 for (uint32_t ct=0; ct < mTextureCount; ct++) {
169 char buf[256];
170 sprintf(buf, "uniform sampler2D uni_Tex%i;\n", ct);
Jason Samsbb51c402009-11-25 13:22:07 -0800171 mShader.append(buf);
Jason Samsbb51c402009-11-25 13:22:07 -0800172 }
Jason Sams7e5ab3b2009-12-15 13:27:04 -0800173 mShader.append(mUserShader);
174 } else {
175 uint32_t mask = mTextureEnableMask;
176 uint32_t texNum = 0;
177 while (mask) {
178 if (mask & 1) {
179 char buf[64];
180 mShader.append("uniform sampler2D uni_Tex");
181 sprintf(buf, "%i", texNum);
182 mShader.append(buf);
183 mShader.append(";\n");
Jason Samsbb51c402009-11-25 13:22:07 -0800184 }
Jason Sams7e5ab3b2009-12-15 13:27:04 -0800185 mask >>= 1;
186 texNum++;
Jason Samsbb51c402009-11-25 13:22:07 -0800187 }
Jason Sams7e5ab3b2009-12-15 13:27:04 -0800188
189
190 mShader.append("void main() {\n");
Jason Sams442a6472010-08-04 17:50:20 -0700191 if (mVaryingColor) {
Jason Sams1911c602010-08-05 17:38:29 -0700192 mShader.append(" lowp vec4 col = varColor;\n");
Jason Sams442a6472010-08-04 17:50:20 -0700193 } else {
Jason Sams1911c602010-08-05 17:38:29 -0700194 mShader.append(" lowp vec4 col = uni_Color;\n");
Jason Sams442a6472010-08-04 17:50:20 -0700195 }
Jason Sams7e5ab3b2009-12-15 13:27:04 -0800196
197 if (mTextureEnableMask) {
198 if (mPointSpriteEnable) {
Jason Sams718cd1f2009-12-23 14:35:29 -0800199 mShader.append(" vec2 t0 = gl_PointCoord;\n");
Jason Sams7e5ab3b2009-12-15 13:27:04 -0800200 } else {
Jason Sams718cd1f2009-12-23 14:35:29 -0800201 mShader.append(" vec2 t0 = varTex0.xy;\n");
Jason Sams7e5ab3b2009-12-15 13:27:04 -0800202 }
203 }
204
205 mask = mTextureEnableMask;
206 texNum = 0;
207 while (mask) {
208 if (mask & 1) {
209 switch(mEnvModes[texNum]) {
Jason Sams68afd012009-12-17 16:55:08 -0800210 case RS_TEX_ENV_MODE_NONE:
211 rsAssert(0);
212 break;
Jason Sams7e5ab3b2009-12-15 13:27:04 -0800213 case RS_TEX_ENV_MODE_REPLACE:
Jason Sams718cd1f2009-12-23 14:35:29 -0800214 switch(mTextureFormats[texNum]) {
215 case 1:
216 mShader.append(" col.a = texture2D(uni_Tex0, t0).a;\n");
217 break;
218 case 2:
219 mShader.append(" col.rgba = texture2D(uni_Tex0, t0).rgba;\n");
220 break;
221 case 3:
222 mShader.append(" col.rgb = texture2D(uni_Tex0, t0).rgb;\n");
223 break;
224 case 4:
225 mShader.append(" col.rgba = texture2D(uni_Tex0, t0).rgba;\n");
226 break;
227 }
Jason Sams7e5ab3b2009-12-15 13:27:04 -0800228 break;
229 case RS_TEX_ENV_MODE_MODULATE:
Jason Sams718cd1f2009-12-23 14:35:29 -0800230 switch(mTextureFormats[texNum]) {
231 case 1:
232 mShader.append(" col.a *= texture2D(uni_Tex0, t0).a;\n");
233 break;
234 case 2:
235 mShader.append(" col.rgba *= texture2D(uni_Tex0, t0).rgba;\n");
236 break;
237 case 3:
238 mShader.append(" col.rgb *= texture2D(uni_Tex0, t0).rgb;\n");
239 break;
240 case 4:
241 mShader.append(" col.rgba *= texture2D(uni_Tex0, t0).rgba;\n");
242 break;
243 }
Jason Sams7e5ab3b2009-12-15 13:27:04 -0800244 break;
245 case RS_TEX_ENV_MODE_DECAL:
Jason Sams718cd1f2009-12-23 14:35:29 -0800246 mShader.append(" col = texture2D(uni_Tex0, t0);\n");
Jason Sams7e5ab3b2009-12-15 13:27:04 -0800247 break;
248 }
249
250 }
251 mask >>= 1;
252 texNum++;
253 }
254
255 //mShader.append(" col.a = 1.0;\n");
256 //mShader.append(" col.r = 0.5;\n");
257
258 mShader.append(" gl_FragColor = col;\n");
259 mShader.append("}\n");
Jason Samsbb51c402009-11-25 13:22:07 -0800260 }
Jason Samsbb51c402009-11-25 13:22:07 -0800261}
Jason Samsd19f10d2009-05-22 14:03:28 -0700262
Jason Samsbb51c402009-11-25 13:22:07 -0800263void ProgramFragment::init(Context *rsc)
264{
Alex Sakhartchoukcaaac0f82010-09-02 18:43:24 -0700265 mUniformCount = 0;
266 //if (!mVaryingColor) {
267 mConstantColorUniformIndex = mUniformCount;
268 mUniformNames[mUniformCount++].setTo("uni_Color");
269 //}
270
Alex Sakhartchouk8442e0b2010-08-31 12:02:01 -0700271 if (mUserShader.size() > 0) {
272 for (uint32_t ct=0; ct < mConstantCount; ct++) {
273 initAddUserElement(mConstantTypes[ct]->getElement(), mUniformNames, &mUniformCount, "UNI_");
274 }
275 }
Alex Sakhartchoukcaaac0f82010-09-02 18:43:24 -0700276 mTextureUniformIndexStart = mUniformCount;
277 mUniformNames[mUniformCount++].setTo("uni_Tex0");
278 mUniformNames[mUniformCount++].setTo("uni_Tex1");
Alex Sakhartchouk8442e0b2010-08-31 12:02:01 -0700279
280 createShader();
Jason Samsbb51c402009-11-25 13:22:07 -0800281}
Jason Samsd19f10d2009-05-22 14:03:28 -0700282
Alex Sakhartchoukaa7d2882010-05-21 12:53:13 -0700283void ProgramFragment::serialize(OStream *stream) const
284{
Jason Sams7c1f4c32010-06-22 17:22:13 -0700285
Alex Sakhartchoukaa7d2882010-05-21 12:53:13 -0700286}
287
288ProgramFragment *ProgramFragment::createFromStream(Context *rsc, IStream *stream)
289{
290 return NULL;
291}
292
Jason Samsd19f10d2009-05-22 14:03:28 -0700293ProgramFragmentState::ProgramFragmentState()
294{
295 mPF = NULL;
296}
297
298ProgramFragmentState::~ProgramFragmentState()
299{
300 delete mPF;
301
302}
303
Jason Samsf603d212010-05-14 15:30:29 -0700304void ProgramFragmentState::init(Context *rsc)
Jason Sams9c54bdb2009-06-17 16:52:59 -0700305{
Jason Sams442a6472010-08-04 17:50:20 -0700306 uint32_t tmp[] = {
Jason Sams68afd012009-12-17 16:55:08 -0800307 RS_TEX_ENV_MODE_NONE, 0,
308 RS_TEX_ENV_MODE_NONE, 0,
Jason Sams442a6472010-08-04 17:50:20 -0700309 0, 0
Jason Sams68afd012009-12-17 16:55:08 -0800310 };
Jason Sams442a6472010-08-04 17:50:20 -0700311 ProgramFragment *pf = new ProgramFragment(rsc, tmp, 6);
Jason Sams9c54bdb2009-06-17 16:52:59 -0700312 mDefault.set(pf);
313}
Jason Samsd19f10d2009-05-22 14:03:28 -0700314
Jason Sams61f08d62009-09-25 16:37:33 -0700315void ProgramFragmentState::deinit(Context *rsc)
316{
317 mDefault.clear();
318 mLast.clear();
319}
320
Jason Samsd19f10d2009-05-22 14:03:28 -0700321
322namespace android {
323namespace renderscript {
324
Jason Sams68afd012009-12-17 16:55:08 -0800325RsProgramFragment rsi_ProgramFragmentCreate(Context *rsc,
326 const uint32_t * params,
327 uint32_t paramLength)
Jason Samsd19f10d2009-05-22 14:03:28 -0700328{
Jason Sams68afd012009-12-17 16:55:08 -0800329 ProgramFragment *pf = new ProgramFragment(rsc, params, paramLength);
Jason Sams07ae4062009-08-27 20:23:34 -0700330 pf->incUserRef();
Jason Samsc378dab2010-05-17 17:28:12 -0700331 //LOGE("rsi_ProgramFragmentCreate %p", pf);
Jason Samsd19f10d2009-05-22 14:03:28 -0700332 return pf;
333}
334
Jason Sams7e5ab3b2009-12-15 13:27:04 -0800335RsProgramFragment rsi_ProgramFragmentCreate2(Context *rsc, const char * shaderText,
336 uint32_t shaderLength, const uint32_t * params,
337 uint32_t paramLength)
338{
339 ProgramFragment *pf = new ProgramFragment(rsc, shaderText, shaderLength, params, paramLength);
340 pf->incUserRef();
Jason Samsc378dab2010-05-17 17:28:12 -0700341 //LOGE("rsi_ProgramFragmentCreate2 %p", pf);
Jason Sams7e5ab3b2009-12-15 13:27:04 -0800342 return pf;
343}
Jason Samsd19f10d2009-05-22 14:03:28 -0700344
345}
346}
347