blob: a045043147c9ade87605d206d7098c49c059ee02 [file] [log] [blame]
Jason Sams326e0dd2009-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 Sakhartchoukfb6b6142010-05-21 12:53:13 -070017#ifndef ANDROID_RS_BUILD_FOR_HOST
Jason Sams326e0dd2009-05-22 14:03:28 -070018#include "rsContext.h"
Jason Sams1aa5a4e2009-06-22 17:15:15 -070019#include <GLES/gl.h>
20#include <GLES/glext.h>
Jason Samsc460e552009-11-25 13:22:07 -080021#include <GLES2/gl2.h>
22#include <GLES2/gl2ext.h>
Alex Sakhartchoukfb6b6142010-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 Sams1aa5a4e2009-06-22 17:15:15 -070030
Jason Sams326e0dd2009-05-22 14:03:28 -070031using namespace android;
32using namespace android::renderscript;
33
34
Jason Sams7dad9c32009-12-17 16:55:08 -080035ProgramFragment::ProgramFragment(Context *rsc, const uint32_t * params,
36 uint32_t paramLength) :
Jason Sams4815c0d2009-12-15 12:58:36 -080037 Program(rsc)
Jason Sams326e0dd2009-05-22 14:03:28 -070038{
Jason Samsf2649a92009-09-25 16:37:33 -070039 mAllocFile = __FILE__;
40 mAllocLine = __LINE__;
Jason Sams6445e522010-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 Sams7dad9c32009-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 Sams6445e522010-08-04 17:50:20 -070053 mVaryingColor = false;
54 if (paramLength > 5)
55 mVaryingColor = params[5] != 0;
Jason Sams7dad9c32009-12-17 16:55:08 -080056
Jason Sams326e0dd2009-05-22 14:03:28 -070057 mTextureEnableMask = 0;
Jason Sams7dad9c32009-12-17 16:55:08 -080058 if (mEnvModes[0]) {
59 mTextureEnableMask |= 1;
60 }
61 if (mEnvModes[1]) {
62 mTextureEnableMask |= 2;
63 }
Jason Sams6445e522010-08-04 17:50:20 -070064
65 mUniformCount = 0;
66 mUniformNames[mUniformCount++].setTo("uni_Tex0");
67 mUniformNames[mUniformCount++].setTo("uni_Tex1");
68
69 mConstantColorUniformIndex = -1;
70 //if (!mVaryingColor) {
71 mConstantColorUniformIndex = mUniformCount;
72 mUniformNames[mUniformCount++].setTo("uni_Color");
73 //}
74 createShader();
Jason Sams326e0dd2009-05-22 14:03:28 -070075}
76
Jason Samsf2e4fa22009-12-15 13:27:04 -080077ProgramFragment::ProgramFragment(Context *rsc, const char * shaderText,
78 uint32_t shaderLength, const uint32_t * params,
79 uint32_t paramLength) :
80 Program(rsc, shaderText, shaderLength, params, paramLength)
81{
82 mAllocFile = __FILE__;
83 mAllocLine = __LINE__;
84
Jason Sams6445e522010-08-04 17:50:20 -070085 mConstantColor[0] = 1.f;
86 mConstantColor[1] = 1.f;
87 mConstantColor[2] = 1.f;
88 mConstantColor[3] = 1.f;
89
90 LOGE("Custom FP");
91
92 mUniformCount = 2;
93 mUniformNames[0].setTo("uni_Tex0");
94 mUniformNames[1].setTo("uni_Tex1");
95
96 createShader();
97
Jason Samsf2e4fa22009-12-15 13:27:04 -080098 mTextureEnableMask = (1 << mTextureCount) -1;
99}
100
101
Jason Sams326e0dd2009-05-22 14:03:28 -0700102ProgramFragment::~ProgramFragment()
103{
104}
105
Jason Sams6445e522010-08-04 17:50:20 -0700106void ProgramFragment::setConstantColor(float r, float g, float b, float a)
107{
108 mConstantColor[0] = r;
109 mConstantColor[1] = g;
110 mConstantColor[2] = b;
111 mConstantColor[3] = a;
112 mDirty = true;
113}
114
Jason Samsafcb25c2009-08-25 11:34:49 -0700115void ProgramFragment::setupGL(const Context *rsc, ProgramFragmentState *state)
Jason Sams326e0dd2009-05-22 14:03:28 -0700116{
Jason Sams326e0dd2009-05-22 14:03:28 -0700117}
118
Jason Samsc460e552009-11-25 13:22:07 -0800119void ProgramFragment::setupGL2(const Context *rsc, ProgramFragmentState *state, ShaderCache *sc)
120{
Jason Sams3eb28f02010-01-27 14:41:43 -0800121
Jason Samsc460e552009-11-25 13:22:07 -0800122 //LOGE("sgl2 frag1 %x", glGetError());
123 if ((state->mLast.get() == this) && !mDirty) {
Jason Samse64c2f12010-06-22 17:22:13 -0700124 return;
Jason Samsc460e552009-11-25 13:22:07 -0800125 }
126 state->mLast.set(this);
127
Jason Sams3eb28f02010-01-27 14:41:43 -0800128 rsc->checkError("ProgramFragment::setupGL2 start");
Jason Sams6445e522010-08-04 17:50:20 -0700129
130 if (!mVaryingColor &&
131 (sc->fragUniformSlot(mConstantColorUniformIndex) >= 0)) {
132 //LOGE("mConstantColorUniformIndex %i %i", mConstantColorUniformIndex, sc->fragUniformSlot(mConstantColorUniformIndex));
133 glUniform4fv(sc->fragUniformSlot(mConstantColorUniformIndex), 1, mConstantColor);
134 rsc->checkError("ProgramFragment::color setup");
135 }
136
Jason Samsc460e552009-11-25 13:22:07 -0800137 for (uint32_t ct=0; ct < MAX_TEXTURE; ct++) {
138 glActiveTexture(GL_TEXTURE0 + ct);
139 if (!(mTextureEnableMask & (1 << ct)) || !mTextures[ct].get()) {
Jason Samsc460e552009-11-25 13:22:07 -0800140 continue;
141 }
142
Jason Samscf4c7c92009-12-14 12:57:40 -0800143 mTextures[ct]->uploadCheck(rsc);
Jason Samsc460e552009-11-25 13:22:07 -0800144 glBindTexture(GL_TEXTURE_2D, mTextures[ct]->getTextureID());
Jason Sams3eb28f02010-01-27 14:41:43 -0800145 rsc->checkError("ProgramFragment::setupGL2 tex bind");
Jason Samsc460e552009-11-25 13:22:07 -0800146 if (mSamplers[ct].get()) {
Jason Samsef21edc2010-02-22 15:37:51 -0800147 mSamplers[ct]->setupGL(rsc, mTextures[ct]->getType()->getIsNp2());
Jason Samsc460e552009-11-25 13:22:07 -0800148 } else {
149 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
150 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
151 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
152 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
Jason Sams3eb28f02010-01-27 14:41:43 -0800153 rsc->checkError("ProgramFragment::setupGL2 tex env");
Jason Samsc460e552009-11-25 13:22:07 -0800154 }
155
Jason Samsc460e552009-11-25 13:22:07 -0800156 glUniform1i(sc->fragUniformSlot(ct), ct);
Jason Sams3eb28f02010-01-27 14:41:43 -0800157 rsc->checkError("ProgramFragment::setupGL2 uniforms");
Jason Samsc460e552009-11-25 13:22:07 -0800158 }
159
160 glActiveTexture(GL_TEXTURE0);
161 mDirty = false;
Jason Sams433eca32010-01-06 11:57:52 -0800162 rsc->checkError("ProgramFragment::setupGL2");
Jason Samsc460e552009-11-25 13:22:07 -0800163}
164
Jason Samscd506532009-12-15 19:10:11 -0800165void ProgramFragment::loadShader(Context *rsc) {
166 Program::loadShader(rsc, GL_FRAGMENT_SHADER);
Jason Samsc460e552009-11-25 13:22:07 -0800167}
168
169void ProgramFragment::createShader()
170{
171 mShader.setTo("precision mediump float;\n");
Jason Sams0002a172010-08-05 17:38:29 -0700172 mShader.append("varying lowp vec4 varColor;\n");
Jason Samsc460e552009-11-25 13:22:07 -0800173 mShader.append("varying vec4 varTex0;\n");
Jason Sams6445e522010-08-04 17:50:20 -0700174 mShader.append("uniform vec4 uni_Color;\n");
Jason Samsc460e552009-11-25 13:22:07 -0800175
Jason Samsf2e4fa22009-12-15 13:27:04 -0800176 if (mUserShader.length() > 1) {
177 for (uint32_t ct=0; ct < mTextureCount; ct++) {
178 char buf[256];
179 sprintf(buf, "uniform sampler2D uni_Tex%i;\n", ct);
Jason Samsc460e552009-11-25 13:22:07 -0800180 mShader.append(buf);
Jason Samsc460e552009-11-25 13:22:07 -0800181 }
Jason Samsc460e552009-11-25 13:22:07 -0800182
Jason Samsf2e4fa22009-12-15 13:27:04 -0800183 mShader.append(mUserShader);
184 } else {
185 uint32_t mask = mTextureEnableMask;
186 uint32_t texNum = 0;
187 while (mask) {
188 if (mask & 1) {
189 char buf[64];
190 mShader.append("uniform sampler2D uni_Tex");
191 sprintf(buf, "%i", texNum);
192 mShader.append(buf);
193 mShader.append(";\n");
Jason Samsc460e552009-11-25 13:22:07 -0800194 }
Jason Samsf2e4fa22009-12-15 13:27:04 -0800195 mask >>= 1;
196 texNum++;
Jason Samsc460e552009-11-25 13:22:07 -0800197 }
Jason Samsf2e4fa22009-12-15 13:27:04 -0800198
199
200 mShader.append("void main() {\n");
Jason Sams6445e522010-08-04 17:50:20 -0700201 if (mVaryingColor) {
Jason Sams0002a172010-08-05 17:38:29 -0700202 mShader.append(" lowp vec4 col = varColor;\n");
Jason Sams6445e522010-08-04 17:50:20 -0700203 } else {
Jason Sams0002a172010-08-05 17:38:29 -0700204 mShader.append(" lowp vec4 col = uni_Color;\n");
Jason Sams6445e522010-08-04 17:50:20 -0700205 }
Jason Samsf2e4fa22009-12-15 13:27:04 -0800206
207 if (mTextureEnableMask) {
208 if (mPointSpriteEnable) {
Jason Samsd01d9702009-12-23 14:35:29 -0800209 mShader.append(" vec2 t0 = gl_PointCoord;\n");
Jason Samsf2e4fa22009-12-15 13:27:04 -0800210 } else {
Jason Samsd01d9702009-12-23 14:35:29 -0800211 mShader.append(" vec2 t0 = varTex0.xy;\n");
Jason Samsf2e4fa22009-12-15 13:27:04 -0800212 }
213 }
214
215 mask = mTextureEnableMask;
216 texNum = 0;
217 while (mask) {
218 if (mask & 1) {
219 switch(mEnvModes[texNum]) {
Jason Sams7dad9c32009-12-17 16:55:08 -0800220 case RS_TEX_ENV_MODE_NONE:
221 rsAssert(0);
222 break;
Jason Samsf2e4fa22009-12-15 13:27:04 -0800223 case RS_TEX_ENV_MODE_REPLACE:
Jason Samsd01d9702009-12-23 14:35:29 -0800224 switch(mTextureFormats[texNum]) {
225 case 1:
226 mShader.append(" col.a = texture2D(uni_Tex0, t0).a;\n");
227 break;
228 case 2:
229 mShader.append(" col.rgba = texture2D(uni_Tex0, t0).rgba;\n");
230 break;
231 case 3:
232 mShader.append(" col.rgb = texture2D(uni_Tex0, t0).rgb;\n");
233 break;
234 case 4:
235 mShader.append(" col.rgba = texture2D(uni_Tex0, t0).rgba;\n");
236 break;
237 }
Jason Samsf2e4fa22009-12-15 13:27:04 -0800238 break;
239 case RS_TEX_ENV_MODE_MODULATE:
Jason Samsd01d9702009-12-23 14:35:29 -0800240 switch(mTextureFormats[texNum]) {
241 case 1:
242 mShader.append(" col.a *= texture2D(uni_Tex0, t0).a;\n");
243 break;
244 case 2:
245 mShader.append(" col.rgba *= texture2D(uni_Tex0, t0).rgba;\n");
246 break;
247 case 3:
248 mShader.append(" col.rgb *= texture2D(uni_Tex0, t0).rgb;\n");
249 break;
250 case 4:
251 mShader.append(" col.rgba *= texture2D(uni_Tex0, t0).rgba;\n");
252 break;
253 }
Jason Samsf2e4fa22009-12-15 13:27:04 -0800254 break;
255 case RS_TEX_ENV_MODE_DECAL:
Jason Samsd01d9702009-12-23 14:35:29 -0800256 mShader.append(" col = texture2D(uni_Tex0, t0);\n");
Jason Samsf2e4fa22009-12-15 13:27:04 -0800257 break;
258 }
259
260 }
261 mask >>= 1;
262 texNum++;
263 }
264
265 //mShader.append(" col.a = 1.0;\n");
266 //mShader.append(" col.r = 0.5;\n");
267
268 mShader.append(" gl_FragColor = col;\n");
269 mShader.append("}\n");
Jason Samsc460e552009-11-25 13:22:07 -0800270 }
Jason Samsc460e552009-11-25 13:22:07 -0800271}
Jason Sams326e0dd2009-05-22 14:03:28 -0700272
Jason Samsc460e552009-11-25 13:22:07 -0800273void ProgramFragment::init(Context *rsc)
274{
Jason Samsc460e552009-11-25 13:22:07 -0800275}
Jason Sams326e0dd2009-05-22 14:03:28 -0700276
Alex Sakhartchoukfb6b6142010-05-21 12:53:13 -0700277void ProgramFragment::serialize(OStream *stream) const
278{
Jason Samse64c2f12010-06-22 17:22:13 -0700279
Alex Sakhartchoukfb6b6142010-05-21 12:53:13 -0700280}
281
282ProgramFragment *ProgramFragment::createFromStream(Context *rsc, IStream *stream)
283{
284 return NULL;
285}
286
Jason Sams326e0dd2009-05-22 14:03:28 -0700287ProgramFragmentState::ProgramFragmentState()
288{
289 mPF = NULL;
290}
291
292ProgramFragmentState::~ProgramFragmentState()
293{
294 delete mPF;
295
296}
297
Jason Sams771565f2010-05-14 15:30:29 -0700298void ProgramFragmentState::init(Context *rsc)
Jason Sams8ce125b2009-06-17 16:52:59 -0700299{
Jason Sams6445e522010-08-04 17:50:20 -0700300 uint32_t tmp[] = {
Jason Sams7dad9c32009-12-17 16:55:08 -0800301 RS_TEX_ENV_MODE_NONE, 0,
302 RS_TEX_ENV_MODE_NONE, 0,
Jason Sams6445e522010-08-04 17:50:20 -0700303 0, 0
Jason Sams7dad9c32009-12-17 16:55:08 -0800304 };
Jason Sams6445e522010-08-04 17:50:20 -0700305 ProgramFragment *pf = new ProgramFragment(rsc, tmp, 6);
Jason Sams8ce125b2009-06-17 16:52:59 -0700306 mDefault.set(pf);
Jason Samsc460e552009-11-25 13:22:07 -0800307 pf->init(rsc);
Jason Sams8ce125b2009-06-17 16:52:59 -0700308}
Jason Sams326e0dd2009-05-22 14:03:28 -0700309
Jason Samsf2649a92009-09-25 16:37:33 -0700310void ProgramFragmentState::deinit(Context *rsc)
311{
312 mDefault.clear();
313 mLast.clear();
314}
315
Jason Sams326e0dd2009-05-22 14:03:28 -0700316
317namespace android {
318namespace renderscript {
319
Jason Sams7dad9c32009-12-17 16:55:08 -0800320RsProgramFragment rsi_ProgramFragmentCreate(Context *rsc,
321 const uint32_t * params,
322 uint32_t paramLength)
Jason Sams326e0dd2009-05-22 14:03:28 -0700323{
Jason Sams7dad9c32009-12-17 16:55:08 -0800324 ProgramFragment *pf = new ProgramFragment(rsc, params, paramLength);
Jason Sams9397e302009-08-27 20:23:34 -0700325 pf->incUserRef();
Jason Sams5a279172010-05-17 17:28:12 -0700326 //LOGE("rsi_ProgramFragmentCreate %p", pf);
Jason Sams326e0dd2009-05-22 14:03:28 -0700327 return pf;
328}
329
Jason Samsf2e4fa22009-12-15 13:27:04 -0800330RsProgramFragment rsi_ProgramFragmentCreate2(Context *rsc, const char * shaderText,
331 uint32_t shaderLength, const uint32_t * params,
332 uint32_t paramLength)
333{
334 ProgramFragment *pf = new ProgramFragment(rsc, shaderText, shaderLength, params, paramLength);
335 pf->incUserRef();
Jason Sams5a279172010-05-17 17:28:12 -0700336 //LOGE("rsi_ProgramFragmentCreate2 %p", pf);
Jason Samsf2e4fa22009-12-15 13:27:04 -0800337 return pf;
338}
Jason Sams326e0dd2009-05-22 14:03:28 -0700339
340}
341}
342