blob: 00f19ae8dc31c48204c2cf1228f0aff7c29591e8 [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
17#include "rsContext.h"
18#include "rsProgramFragment.h"
19
Jason Sams1aa5a4e2009-06-22 17:15:15 -070020#include <GLES/gl.h>
21#include <GLES/glext.h>
Jason Samsc460e552009-11-25 13:22:07 -080022#include <GLES2/gl2.h>
23#include <GLES2/gl2ext.h>
Jason Sams1aa5a4e2009-06-22 17:15:15 -070024
Jason Sams326e0dd2009-05-22 14:03:28 -070025using namespace android;
26using namespace android::renderscript;
27
28
Jason Sams7dad9c32009-12-17 16:55:08 -080029ProgramFragment::ProgramFragment(Context *rsc, const uint32_t * params,
30 uint32_t paramLength) :
Jason Sams4815c0d2009-12-15 12:58:36 -080031 Program(rsc)
Jason Sams326e0dd2009-05-22 14:03:28 -070032{
Jason Samsf2649a92009-09-25 16:37:33 -070033 mAllocFile = __FILE__;
34 mAllocLine = __LINE__;
Jason Sams7dad9c32009-12-17 16:55:08 -080035 rsAssert(paramLength = 5);
36
37 mEnvModes[0] = (RsTexEnvMode)params[0];
38 mTextureFormats[0] = params[1];
39 mEnvModes[1] = (RsTexEnvMode)params[2];
40 mTextureFormats[1] = params[3];
41 mPointSpriteEnable = params[4] != 0;
42
Jason Sams326e0dd2009-05-22 14:03:28 -070043 mTextureEnableMask = 0;
Jason Sams7dad9c32009-12-17 16:55:08 -080044 if (mEnvModes[0]) {
45 mTextureEnableMask |= 1;
46 }
47 if (mEnvModes[1]) {
48 mTextureEnableMask |= 2;
49 }
50 init(rsc);
Jason Sams326e0dd2009-05-22 14:03:28 -070051}
52
Jason Samsf2e4fa22009-12-15 13:27:04 -080053ProgramFragment::ProgramFragment(Context *rsc, const char * shaderText,
54 uint32_t shaderLength, const uint32_t * params,
55 uint32_t paramLength) :
56 Program(rsc, shaderText, shaderLength, params, paramLength)
57{
58 mAllocFile = __FILE__;
59 mAllocLine = __LINE__;
60
61 init(rsc);
62 mTextureEnableMask = (1 << mTextureCount) -1;
63}
64
65
Jason Sams326e0dd2009-05-22 14:03:28 -070066ProgramFragment::~ProgramFragment()
67{
68}
69
Jason Samsafcb25c2009-08-25 11:34:49 -070070void ProgramFragment::setupGL(const Context *rsc, ProgramFragmentState *state)
Jason Sams326e0dd2009-05-22 14:03:28 -070071{
Jason Samscfb1d112009-08-05 13:57:03 -070072 if ((state->mLast.get() == this) && !mDirty) {
73 return;
74 }
75 state->mLast.set(this);
76
Jason Sams326e0dd2009-05-22 14:03:28 -070077 for (uint32_t ct=0; ct < MAX_TEXTURE; ct++) {
78 glActiveTexture(GL_TEXTURE0 + ct);
Jason Sams334fd9a2009-07-02 15:09:27 -070079 if (!(mTextureEnableMask & (1 << ct)) || !mTextures[ct].get()) {
Jason Sams326e0dd2009-05-22 14:03:28 -070080 glDisable(GL_TEXTURE_2D);
81 continue;
82 }
83
84 glEnable(GL_TEXTURE_2D);
Jason Samsafcb25c2009-08-25 11:34:49 -070085 if (rsc->checkVersion1_1()) {
Romain Guye62cc902009-09-04 17:55:41 -070086 if (mPointSpriteEnable) {
87 glEnable(GL_POINT_SPRITE_OES);
88 } else {
89 glDisable(GL_POINT_SPRITE_OES);
90 }
Jason Samsafcb25c2009-08-25 11:34:49 -070091 glTexEnvi(GL_POINT_SPRITE_OES, GL_COORD_REPLACE_OES, mPointSpriteEnable);
92 }
Jason Samscf4c7c92009-12-14 12:57:40 -080093 mTextures[ct]->uploadCheck(rsc);
Jason Sams326e0dd2009-05-22 14:03:28 -070094 glBindTexture(GL_TEXTURE_2D, mTextures[ct]->getTextureID());
95
96 switch(mEnvModes[ct]) {
Jason Sams7dad9c32009-12-17 16:55:08 -080097 case RS_TEX_ENV_MODE_NONE:
98 rsAssert(0);
99 break;
Jason Sams326e0dd2009-05-22 14:03:28 -0700100 case RS_TEX_ENV_MODE_REPLACE:
Jason Sams334fd9a2009-07-02 15:09:27 -0700101 glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
Jason Sams326e0dd2009-05-22 14:03:28 -0700102 break;
103 case RS_TEX_ENV_MODE_MODULATE:
Jason Sams334fd9a2009-07-02 15:09:27 -0700104 glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
Jason Sams326e0dd2009-05-22 14:03:28 -0700105 break;
106 case RS_TEX_ENV_MODE_DECAL:
Jason Sams334fd9a2009-07-02 15:09:27 -0700107 glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);
Jason Sams326e0dd2009-05-22 14:03:28 -0700108 break;
109 }
110
Jason Sams39c8bc72009-05-28 15:37:57 -0700111 if (mSamplers[ct].get()) {
112 mSamplers[ct]->setupGL();
113 } else {
Jason Sams6678e9b2009-05-27 14:45:32 -0700114 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
115 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
Jason Sams334fd9a2009-07-02 15:09:27 -0700116 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
Jason Sams6678e9b2009-05-27 14:45:32 -0700117 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
Jason Sams39c8bc72009-05-28 15:37:57 -0700118 }
Jason Sams334fd9a2009-07-02 15:09:27 -0700119
120 // Gross hack.
121 if (ct == 2) {
122 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);
123
124 glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_ADD);
125 glTexEnvi(GL_TEXTURE_ENV, GL_SRC0_RGB, GL_PREVIOUS);
126 glTexEnvi(GL_TEXTURE_ENV, GL_SRC1_RGB, GL_TEXTURE);
127 glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB, GL_SRC_COLOR);
128 glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB, GL_SRC_COLOR);
129
130 glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA, GL_ADD);
131 glTexEnvi(GL_TEXTURE_ENV, GL_SRC0_ALPHA, GL_PREVIOUS);
132 glTexEnvi(GL_TEXTURE_ENV, GL_SRC1_ALPHA, GL_TEXTURE);
133 glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA, GL_SRC_ALPHA);
134 glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_ALPHA, GL_SRC_ALPHA);
135 }
Jason Sams326e0dd2009-05-22 14:03:28 -0700136 }
137 glActiveTexture(GL_TEXTURE0);
Jason Samscfb1d112009-08-05 13:57:03 -0700138 mDirty = false;
Jason Sams433eca32010-01-06 11:57:52 -0800139 rsc->checkError("ProgramFragment::setupGL");
Jason Sams326e0dd2009-05-22 14:03:28 -0700140}
141
Jason Samsc460e552009-11-25 13:22:07 -0800142void ProgramFragment::setupGL2(const Context *rsc, ProgramFragmentState *state, ShaderCache *sc)
143{
144 //LOGE("sgl2 frag1 %x", glGetError());
145 if ((state->mLast.get() == this) && !mDirty) {
146 //return;
147 }
148 state->mLast.set(this);
149
150 for (uint32_t ct=0; ct < MAX_TEXTURE; ct++) {
151 glActiveTexture(GL_TEXTURE0 + ct);
152 if (!(mTextureEnableMask & (1 << ct)) || !mTextures[ct].get()) {
153 glDisable(GL_TEXTURE_2D);
154 continue;
155 }
156
Jason Samscf4c7c92009-12-14 12:57:40 -0800157 mTextures[ct]->uploadCheck(rsc);
Jason Samsc460e552009-11-25 13:22:07 -0800158 glBindTexture(GL_TEXTURE_2D, mTextures[ct]->getTextureID());
159 if (mSamplers[ct].get()) {
160 mSamplers[ct]->setupGL();
161 } else {
162 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
163 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
164 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
165 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
166 }
167
168 glEnable(GL_TEXTURE_2D);
169 glUniform1i(sc->fragUniformSlot(ct), ct);
170 }
171
172 glActiveTexture(GL_TEXTURE0);
173 mDirty = false;
Jason Sams433eca32010-01-06 11:57:52 -0800174 rsc->checkError("ProgramFragment::setupGL2");
Jason Samsc460e552009-11-25 13:22:07 -0800175}
176
Jason Samscd506532009-12-15 19:10:11 -0800177void ProgramFragment::loadShader(Context *rsc) {
178 Program::loadShader(rsc, GL_FRAGMENT_SHADER);
Jason Samsc460e552009-11-25 13:22:07 -0800179}
180
181void ProgramFragment::createShader()
182{
183 mShader.setTo("precision mediump float;\n");
184 mShader.append("varying vec4 varColor;\n");
185 mShader.append("varying vec4 varTex0;\n");
186
Jason Samsf2e4fa22009-12-15 13:27:04 -0800187 if (mUserShader.length() > 1) {
188 for (uint32_t ct=0; ct < mTextureCount; ct++) {
189 char buf[256];
190 sprintf(buf, "uniform sampler2D uni_Tex%i;\n", ct);
Jason Samsc460e552009-11-25 13:22:07 -0800191 mShader.append(buf);
Jason Samsc460e552009-11-25 13:22:07 -0800192 }
Jason Samsc460e552009-11-25 13:22:07 -0800193
Jason Samsf2e4fa22009-12-15 13:27:04 -0800194 mShader.append(mUserShader);
195 } else {
196 uint32_t mask = mTextureEnableMask;
197 uint32_t texNum = 0;
198 while (mask) {
199 if (mask & 1) {
200 char buf[64];
201 mShader.append("uniform sampler2D uni_Tex");
202 sprintf(buf, "%i", texNum);
203 mShader.append(buf);
204 mShader.append(";\n");
Jason Samsc460e552009-11-25 13:22:07 -0800205 }
Jason Samsf2e4fa22009-12-15 13:27:04 -0800206 mask >>= 1;
207 texNum++;
Jason Samsc460e552009-11-25 13:22:07 -0800208 }
Jason Samsf2e4fa22009-12-15 13:27:04 -0800209
210
211 mShader.append("void main() {\n");
212 mShader.append(" vec4 col = varColor;\n");
213
214 if (mTextureEnableMask) {
215 if (mPointSpriteEnable) {
Jason Samsd01d9702009-12-23 14:35:29 -0800216 mShader.append(" vec2 t0 = gl_PointCoord;\n");
Jason Samsf2e4fa22009-12-15 13:27:04 -0800217 } else {
Jason Samsd01d9702009-12-23 14:35:29 -0800218 mShader.append(" vec2 t0 = varTex0.xy;\n");
Jason Samsf2e4fa22009-12-15 13:27:04 -0800219 }
220 }
221
222 mask = mTextureEnableMask;
223 texNum = 0;
224 while (mask) {
225 if (mask & 1) {
226 switch(mEnvModes[texNum]) {
Jason Sams7dad9c32009-12-17 16:55:08 -0800227 case RS_TEX_ENV_MODE_NONE:
228 rsAssert(0);
229 break;
Jason Samsf2e4fa22009-12-15 13:27:04 -0800230 case RS_TEX_ENV_MODE_REPLACE:
Jason Samsd01d9702009-12-23 14:35:29 -0800231 switch(mTextureFormats[texNum]) {
232 case 1:
233 mShader.append(" col.a = texture2D(uni_Tex0, t0).a;\n");
234 break;
235 case 2:
236 mShader.append(" col.rgba = texture2D(uni_Tex0, t0).rgba;\n");
237 break;
238 case 3:
239 mShader.append(" col.rgb = texture2D(uni_Tex0, t0).rgb;\n");
240 break;
241 case 4:
242 mShader.append(" col.rgba = texture2D(uni_Tex0, t0).rgba;\n");
243 break;
244 }
Jason Samsf2e4fa22009-12-15 13:27:04 -0800245 break;
246 case RS_TEX_ENV_MODE_MODULATE:
Jason Samsd01d9702009-12-23 14:35:29 -0800247 switch(mTextureFormats[texNum]) {
248 case 1:
249 mShader.append(" col.a *= texture2D(uni_Tex0, t0).a;\n");
250 break;
251 case 2:
252 mShader.append(" col.rgba *= texture2D(uni_Tex0, t0).rgba;\n");
253 break;
254 case 3:
255 mShader.append(" col.rgb *= texture2D(uni_Tex0, t0).rgb;\n");
256 break;
257 case 4:
258 mShader.append(" col.rgba *= texture2D(uni_Tex0, t0).rgba;\n");
259 break;
260 }
Jason Samsf2e4fa22009-12-15 13:27:04 -0800261 break;
262 case RS_TEX_ENV_MODE_DECAL:
Jason Samsd01d9702009-12-23 14:35:29 -0800263 mShader.append(" col = texture2D(uni_Tex0, t0);\n");
Jason Samsf2e4fa22009-12-15 13:27:04 -0800264 break;
265 }
266
267 }
268 mask >>= 1;
269 texNum++;
270 }
271
272 //mShader.append(" col.a = 1.0;\n");
273 //mShader.append(" col.r = 0.5;\n");
274
275 mShader.append(" gl_FragColor = col;\n");
276 mShader.append("}\n");
Jason Samsc460e552009-11-25 13:22:07 -0800277 }
Jason Samsc460e552009-11-25 13:22:07 -0800278}
Jason Sams326e0dd2009-05-22 14:03:28 -0700279
Jason Samsc460e552009-11-25 13:22:07 -0800280void ProgramFragment::init(Context *rsc)
281{
282 mUniformCount = 2;
283 mUniformNames[0].setTo("uni_Tex0");
284 mUniformNames[1].setTo("uni_Tex1");
Jason Sams326e0dd2009-05-22 14:03:28 -0700285
Jason Samsc460e552009-11-25 13:22:07 -0800286 createShader();
287}
Jason Sams326e0dd2009-05-22 14:03:28 -0700288
289ProgramFragmentState::ProgramFragmentState()
290{
291 mPF = NULL;
292}
293
294ProgramFragmentState::~ProgramFragmentState()
295{
296 delete mPF;
297
298}
299
Jason Sams8ce125b2009-06-17 16:52:59 -0700300void ProgramFragmentState::init(Context *rsc, int32_t w, int32_t h)
301{
Jason Sams7dad9c32009-12-17 16:55:08 -0800302 uint32_t tmp[5] = {
303 RS_TEX_ENV_MODE_NONE, 0,
304 RS_TEX_ENV_MODE_NONE, 0,
305 0
306 };
307 ProgramFragment *pf = new ProgramFragment(rsc, tmp, 5);
Jason Sams8ce125b2009-06-17 16:52:59 -0700308 mDefault.set(pf);
Jason Samsc460e552009-11-25 13:22:07 -0800309 pf->init(rsc);
Jason Sams8ce125b2009-06-17 16:52:59 -0700310}
Jason Sams326e0dd2009-05-22 14:03:28 -0700311
Jason Samsf2649a92009-09-25 16:37:33 -0700312void ProgramFragmentState::deinit(Context *rsc)
313{
314 mDefault.clear();
315 mLast.clear();
316}
317
Jason Sams326e0dd2009-05-22 14:03:28 -0700318
319namespace android {
320namespace renderscript {
321
Jason Sams7dad9c32009-12-17 16:55:08 -0800322RsProgramFragment rsi_ProgramFragmentCreate(Context *rsc,
323 const uint32_t * params,
324 uint32_t paramLength)
Jason Sams326e0dd2009-05-22 14:03:28 -0700325{
Jason Sams7dad9c32009-12-17 16:55:08 -0800326 ProgramFragment *pf = new ProgramFragment(rsc, params, paramLength);
Jason Sams9397e302009-08-27 20:23:34 -0700327 pf->incUserRef();
Jason Sams326e0dd2009-05-22 14:03:28 -0700328 return pf;
329}
330
Jason Samsf2e4fa22009-12-15 13:27:04 -0800331RsProgramFragment rsi_ProgramFragmentCreate2(Context *rsc, const char * shaderText,
332 uint32_t shaderLength, const uint32_t * params,
333 uint32_t paramLength)
334{
335 ProgramFragment *pf = new ProgramFragment(rsc, shaderText, shaderLength, params, paramLength);
336 pf->incUserRef();
337 return pf;
338}
Jason Sams326e0dd2009-05-22 14:03:28 -0700339
340}
341}
342