blob: cbe33c72fd1b992913cec27eee8e723f9edf2eac [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 Sams7dad9c32009-12-17 16:55:08 -080041 rsAssert(paramLength = 5);
42
43 mEnvModes[0] = (RsTexEnvMode)params[0];
44 mTextureFormats[0] = params[1];
45 mEnvModes[1] = (RsTexEnvMode)params[2];
46 mTextureFormats[1] = params[3];
47 mPointSpriteEnable = params[4] != 0;
48
Jason Sams326e0dd2009-05-22 14:03:28 -070049 mTextureEnableMask = 0;
Jason Sams7dad9c32009-12-17 16:55:08 -080050 if (mEnvModes[0]) {
51 mTextureEnableMask |= 1;
52 }
53 if (mEnvModes[1]) {
54 mTextureEnableMask |= 2;
55 }
56 init(rsc);
Jason Sams326e0dd2009-05-22 14:03:28 -070057}
58
Jason Samsf2e4fa22009-12-15 13:27:04 -080059ProgramFragment::ProgramFragment(Context *rsc, const char * shaderText,
60 uint32_t shaderLength, const uint32_t * params,
61 uint32_t paramLength) :
62 Program(rsc, shaderText, shaderLength, params, paramLength)
63{
64 mAllocFile = __FILE__;
65 mAllocLine = __LINE__;
66
67 init(rsc);
68 mTextureEnableMask = (1 << mTextureCount) -1;
69}
70
71
Jason Sams326e0dd2009-05-22 14:03:28 -070072ProgramFragment::~ProgramFragment()
73{
74}
75
Jason Samsafcb25c2009-08-25 11:34:49 -070076void ProgramFragment::setupGL(const Context *rsc, ProgramFragmentState *state)
Jason Sams326e0dd2009-05-22 14:03:28 -070077{
Jason Samscfb1d112009-08-05 13:57:03 -070078 if ((state->mLast.get() == this) && !mDirty) {
79 return;
80 }
81 state->mLast.set(this);
82
Jason Sams326e0dd2009-05-22 14:03:28 -070083 for (uint32_t ct=0; ct < MAX_TEXTURE; ct++) {
84 glActiveTexture(GL_TEXTURE0 + ct);
Jason Sams334fd9a2009-07-02 15:09:27 -070085 if (!(mTextureEnableMask & (1 << ct)) || !mTextures[ct].get()) {
Jason Sams326e0dd2009-05-22 14:03:28 -070086 glDisable(GL_TEXTURE_2D);
87 continue;
88 }
89
90 glEnable(GL_TEXTURE_2D);
Jason Samsafcb25c2009-08-25 11:34:49 -070091 if (rsc->checkVersion1_1()) {
Alex Sakhartchoukfb6b6142010-05-21 12:53:13 -070092#ifndef ANDROID_RS_BUILD_FOR_HOST // These are GLES only
Romain Guye62cc902009-09-04 17:55:41 -070093 if (mPointSpriteEnable) {
94 glEnable(GL_POINT_SPRITE_OES);
95 } else {
96 glDisable(GL_POINT_SPRITE_OES);
97 }
Jason Samsafcb25c2009-08-25 11:34:49 -070098 glTexEnvi(GL_POINT_SPRITE_OES, GL_COORD_REPLACE_OES, mPointSpriteEnable);
Alex Sakhartchoukfb6b6142010-05-21 12:53:13 -070099#endif //ANDROID_RS_BUILD_FOR_HOST
Jason Samse64c2f12010-06-22 17:22:13 -0700100
Jason Samsafcb25c2009-08-25 11:34:49 -0700101 }
Jason Samscf4c7c92009-12-14 12:57:40 -0800102 mTextures[ct]->uploadCheck(rsc);
Jason Sams326e0dd2009-05-22 14:03:28 -0700103 glBindTexture(GL_TEXTURE_2D, mTextures[ct]->getTextureID());
104
105 switch(mEnvModes[ct]) {
Jason Sams7dad9c32009-12-17 16:55:08 -0800106 case RS_TEX_ENV_MODE_NONE:
107 rsAssert(0);
108 break;
Jason Sams326e0dd2009-05-22 14:03:28 -0700109 case RS_TEX_ENV_MODE_REPLACE:
Jason Sams334fd9a2009-07-02 15:09:27 -0700110 glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
Jason Sams326e0dd2009-05-22 14:03:28 -0700111 break;
112 case RS_TEX_ENV_MODE_MODULATE:
Jason Sams334fd9a2009-07-02 15:09:27 -0700113 glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
Jason Sams326e0dd2009-05-22 14:03:28 -0700114 break;
115 case RS_TEX_ENV_MODE_DECAL:
Jason Sams334fd9a2009-07-02 15:09:27 -0700116 glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);
Jason Sams326e0dd2009-05-22 14:03:28 -0700117 break;
118 }
119
Jason Sams39c8bc72009-05-28 15:37:57 -0700120 if (mSamplers[ct].get()) {
Jason Samsef21edc2010-02-22 15:37:51 -0800121 mSamplers[ct]->setupGL(rsc, mTextures[ct]->getType()->getIsNp2());
Jason Sams39c8bc72009-05-28 15:37:57 -0700122 } else {
Jason Sams6678e9b2009-05-27 14:45:32 -0700123 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
124 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
Jason Sams334fd9a2009-07-02 15:09:27 -0700125 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
Jason Sams6678e9b2009-05-27 14:45:32 -0700126 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
Jason Sams39c8bc72009-05-28 15:37:57 -0700127 }
Jason Sams334fd9a2009-07-02 15:09:27 -0700128
129 // Gross hack.
130 if (ct == 2) {
131 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);
132
133 glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_ADD);
134 glTexEnvi(GL_TEXTURE_ENV, GL_SRC0_RGB, GL_PREVIOUS);
135 glTexEnvi(GL_TEXTURE_ENV, GL_SRC1_RGB, GL_TEXTURE);
136 glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB, GL_SRC_COLOR);
137 glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB, GL_SRC_COLOR);
138
139 glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA, GL_ADD);
140 glTexEnvi(GL_TEXTURE_ENV, GL_SRC0_ALPHA, GL_PREVIOUS);
141 glTexEnvi(GL_TEXTURE_ENV, GL_SRC1_ALPHA, GL_TEXTURE);
142 glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA, GL_SRC_ALPHA);
143 glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_ALPHA, GL_SRC_ALPHA);
144 }
Jason Sams326e0dd2009-05-22 14:03:28 -0700145 }
146 glActiveTexture(GL_TEXTURE0);
Jason Samscfb1d112009-08-05 13:57:03 -0700147 mDirty = false;
Jason Sams433eca32010-01-06 11:57:52 -0800148 rsc->checkError("ProgramFragment::setupGL");
Jason Sams326e0dd2009-05-22 14:03:28 -0700149}
150
Jason Samsc460e552009-11-25 13:22:07 -0800151void ProgramFragment::setupGL2(const Context *rsc, ProgramFragmentState *state, ShaderCache *sc)
152{
Jason Sams3eb28f02010-01-27 14:41:43 -0800153
Jason Samsc460e552009-11-25 13:22:07 -0800154 //LOGE("sgl2 frag1 %x", glGetError());
155 if ((state->mLast.get() == this) && !mDirty) {
Jason Samse64c2f12010-06-22 17:22:13 -0700156 return;
Jason Samsc460e552009-11-25 13:22:07 -0800157 }
158 state->mLast.set(this);
159
Jason Sams3eb28f02010-01-27 14:41:43 -0800160 rsc->checkError("ProgramFragment::setupGL2 start");
Jason Samsc460e552009-11-25 13:22:07 -0800161 for (uint32_t ct=0; ct < MAX_TEXTURE; ct++) {
162 glActiveTexture(GL_TEXTURE0 + ct);
163 if (!(mTextureEnableMask & (1 << ct)) || !mTextures[ct].get()) {
Jason Samsc460e552009-11-25 13:22:07 -0800164 continue;
165 }
166
Jason Samscf4c7c92009-12-14 12:57:40 -0800167 mTextures[ct]->uploadCheck(rsc);
Jason Samsc460e552009-11-25 13:22:07 -0800168 glBindTexture(GL_TEXTURE_2D, mTextures[ct]->getTextureID());
Jason Sams3eb28f02010-01-27 14:41:43 -0800169 rsc->checkError("ProgramFragment::setupGL2 tex bind");
Jason Samsc460e552009-11-25 13:22:07 -0800170 if (mSamplers[ct].get()) {
Jason Samsef21edc2010-02-22 15:37:51 -0800171 mSamplers[ct]->setupGL(rsc, mTextures[ct]->getType()->getIsNp2());
Jason Samsc460e552009-11-25 13:22:07 -0800172 } else {
173 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
174 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
175 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
176 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
Jason Sams3eb28f02010-01-27 14:41:43 -0800177 rsc->checkError("ProgramFragment::setupGL2 tex env");
Jason Samsc460e552009-11-25 13:22:07 -0800178 }
179
Jason Samsc460e552009-11-25 13:22:07 -0800180 glUniform1i(sc->fragUniformSlot(ct), ct);
Jason Sams3eb28f02010-01-27 14:41:43 -0800181 rsc->checkError("ProgramFragment::setupGL2 uniforms");
Jason Samsc460e552009-11-25 13:22:07 -0800182 }
183
184 glActiveTexture(GL_TEXTURE0);
185 mDirty = false;
Jason Sams433eca32010-01-06 11:57:52 -0800186 rsc->checkError("ProgramFragment::setupGL2");
Jason Samsc460e552009-11-25 13:22:07 -0800187}
188
Jason Samscd506532009-12-15 19:10:11 -0800189void ProgramFragment::loadShader(Context *rsc) {
190 Program::loadShader(rsc, GL_FRAGMENT_SHADER);
Jason Samsc460e552009-11-25 13:22:07 -0800191}
192
193void ProgramFragment::createShader()
194{
195 mShader.setTo("precision mediump float;\n");
196 mShader.append("varying vec4 varColor;\n");
197 mShader.append("varying vec4 varTex0;\n");
198
Jason Samsf2e4fa22009-12-15 13:27:04 -0800199 if (mUserShader.length() > 1) {
200 for (uint32_t ct=0; ct < mTextureCount; ct++) {
201 char buf[256];
202 sprintf(buf, "uniform sampler2D uni_Tex%i;\n", ct);
Jason Samsc460e552009-11-25 13:22:07 -0800203 mShader.append(buf);
Jason Samsc460e552009-11-25 13:22:07 -0800204 }
Jason Samsc460e552009-11-25 13:22:07 -0800205
Jason Samsf2e4fa22009-12-15 13:27:04 -0800206 mShader.append(mUserShader);
207 } else {
208 uint32_t mask = mTextureEnableMask;
209 uint32_t texNum = 0;
210 while (mask) {
211 if (mask & 1) {
212 char buf[64];
213 mShader.append("uniform sampler2D uni_Tex");
214 sprintf(buf, "%i", texNum);
215 mShader.append(buf);
216 mShader.append(";\n");
Jason Samsc460e552009-11-25 13:22:07 -0800217 }
Jason Samsf2e4fa22009-12-15 13:27:04 -0800218 mask >>= 1;
219 texNum++;
Jason Samsc460e552009-11-25 13:22:07 -0800220 }
Jason Samsf2e4fa22009-12-15 13:27:04 -0800221
222
223 mShader.append("void main() {\n");
224 mShader.append(" vec4 col = varColor;\n");
225
226 if (mTextureEnableMask) {
227 if (mPointSpriteEnable) {
Jason Samsd01d9702009-12-23 14:35:29 -0800228 mShader.append(" vec2 t0 = gl_PointCoord;\n");
Jason Samsf2e4fa22009-12-15 13:27:04 -0800229 } else {
Jason Samsd01d9702009-12-23 14:35:29 -0800230 mShader.append(" vec2 t0 = varTex0.xy;\n");
Jason Samsf2e4fa22009-12-15 13:27:04 -0800231 }
232 }
233
234 mask = mTextureEnableMask;
235 texNum = 0;
236 while (mask) {
237 if (mask & 1) {
238 switch(mEnvModes[texNum]) {
Jason Sams7dad9c32009-12-17 16:55:08 -0800239 case RS_TEX_ENV_MODE_NONE:
240 rsAssert(0);
241 break;
Jason Samsf2e4fa22009-12-15 13:27:04 -0800242 case RS_TEX_ENV_MODE_REPLACE:
Jason Samsd01d9702009-12-23 14:35:29 -0800243 switch(mTextureFormats[texNum]) {
244 case 1:
245 mShader.append(" col.a = texture2D(uni_Tex0, t0).a;\n");
246 break;
247 case 2:
248 mShader.append(" col.rgba = texture2D(uni_Tex0, t0).rgba;\n");
249 break;
250 case 3:
251 mShader.append(" col.rgb = texture2D(uni_Tex0, t0).rgb;\n");
252 break;
253 case 4:
254 mShader.append(" col.rgba = texture2D(uni_Tex0, t0).rgba;\n");
255 break;
256 }
Jason Samsf2e4fa22009-12-15 13:27:04 -0800257 break;
258 case RS_TEX_ENV_MODE_MODULATE:
Jason Samsd01d9702009-12-23 14:35:29 -0800259 switch(mTextureFormats[texNum]) {
260 case 1:
261 mShader.append(" col.a *= texture2D(uni_Tex0, t0).a;\n");
262 break;
263 case 2:
264 mShader.append(" col.rgba *= texture2D(uni_Tex0, t0).rgba;\n");
265 break;
266 case 3:
267 mShader.append(" col.rgb *= texture2D(uni_Tex0, t0).rgb;\n");
268 break;
269 case 4:
270 mShader.append(" col.rgba *= texture2D(uni_Tex0, t0).rgba;\n");
271 break;
272 }
Jason Samsf2e4fa22009-12-15 13:27:04 -0800273 break;
274 case RS_TEX_ENV_MODE_DECAL:
Jason Samsd01d9702009-12-23 14:35:29 -0800275 mShader.append(" col = texture2D(uni_Tex0, t0);\n");
Jason Samsf2e4fa22009-12-15 13:27:04 -0800276 break;
277 }
278
279 }
280 mask >>= 1;
281 texNum++;
282 }
283
284 //mShader.append(" col.a = 1.0;\n");
285 //mShader.append(" col.r = 0.5;\n");
286
287 mShader.append(" gl_FragColor = col;\n");
288 mShader.append("}\n");
Jason Samsc460e552009-11-25 13:22:07 -0800289 }
Jason Samsc460e552009-11-25 13:22:07 -0800290}
Jason Sams326e0dd2009-05-22 14:03:28 -0700291
Jason Samsc460e552009-11-25 13:22:07 -0800292void ProgramFragment::init(Context *rsc)
293{
294 mUniformCount = 2;
295 mUniformNames[0].setTo("uni_Tex0");
296 mUniformNames[1].setTo("uni_Tex1");
Jason Sams326e0dd2009-05-22 14:03:28 -0700297
Jason Samsc460e552009-11-25 13:22:07 -0800298 createShader();
299}
Jason Sams326e0dd2009-05-22 14:03:28 -0700300
Alex Sakhartchoukfb6b6142010-05-21 12:53:13 -0700301void ProgramFragment::serialize(OStream *stream) const
302{
Jason Samse64c2f12010-06-22 17:22:13 -0700303
Alex Sakhartchoukfb6b6142010-05-21 12:53:13 -0700304}
305
306ProgramFragment *ProgramFragment::createFromStream(Context *rsc, IStream *stream)
307{
308 return NULL;
309}
310
Jason Sams326e0dd2009-05-22 14:03:28 -0700311ProgramFragmentState::ProgramFragmentState()
312{
313 mPF = NULL;
314}
315
316ProgramFragmentState::~ProgramFragmentState()
317{
318 delete mPF;
319
320}
321
Jason Sams771565f2010-05-14 15:30:29 -0700322void ProgramFragmentState::init(Context *rsc)
Jason Sams8ce125b2009-06-17 16:52:59 -0700323{
Jason Sams7dad9c32009-12-17 16:55:08 -0800324 uint32_t tmp[5] = {
325 RS_TEX_ENV_MODE_NONE, 0,
326 RS_TEX_ENV_MODE_NONE, 0,
327 0
328 };
329 ProgramFragment *pf = new ProgramFragment(rsc, tmp, 5);
Jason Sams8ce125b2009-06-17 16:52:59 -0700330 mDefault.set(pf);
Jason Samsc460e552009-11-25 13:22:07 -0800331 pf->init(rsc);
Jason Sams8ce125b2009-06-17 16:52:59 -0700332}
Jason Sams326e0dd2009-05-22 14:03:28 -0700333
Jason Samsf2649a92009-09-25 16:37:33 -0700334void ProgramFragmentState::deinit(Context *rsc)
335{
336 mDefault.clear();
337 mLast.clear();
338}
339
Jason Sams326e0dd2009-05-22 14:03:28 -0700340
341namespace android {
342namespace renderscript {
343
Jason Sams7dad9c32009-12-17 16:55:08 -0800344RsProgramFragment rsi_ProgramFragmentCreate(Context *rsc,
345 const uint32_t * params,
346 uint32_t paramLength)
Jason Sams326e0dd2009-05-22 14:03:28 -0700347{
Jason Sams7dad9c32009-12-17 16:55:08 -0800348 ProgramFragment *pf = new ProgramFragment(rsc, params, paramLength);
Jason Sams9397e302009-08-27 20:23:34 -0700349 pf->incUserRef();
Jason Sams5a279172010-05-17 17:28:12 -0700350 //LOGE("rsi_ProgramFragmentCreate %p", pf);
Jason Sams326e0dd2009-05-22 14:03:28 -0700351 return pf;
352}
353
Jason Samsf2e4fa22009-12-15 13:27:04 -0800354RsProgramFragment rsi_ProgramFragmentCreate2(Context *rsc, const char * shaderText,
355 uint32_t shaderLength, const uint32_t * params,
356 uint32_t paramLength)
357{
358 ProgramFragment *pf = new ProgramFragment(rsc, shaderText, shaderLength, params, paramLength);
359 pf->incUserRef();
Jason Sams5a279172010-05-17 17:28:12 -0700360 //LOGE("rsi_ProgramFragmentCreate2 %p", pf);
Jason Samsf2e4fa22009-12-15 13:27:04 -0800361 return pf;
362}
Jason Sams326e0dd2009-05-22 14:03:28 -0700363
364}
365}
366