blob: 3174e82df86d6a536b481ea8e37662207127a9ac [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
Alex Sakhartchouk6e934212010-08-31 12:02:01 -070065 init(rsc);
Jason Sams326e0dd2009-05-22 14:03:28 -070066}
67
Jason Samsf2e4fa22009-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 Sams6445e522010-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 Samsf2e4fa22009-12-15 13:27:04 -080083 mTextureEnableMask = (1 << mTextureCount) -1;
Alex Sakhartchouk6e934212010-08-31 12:02:01 -070084
85 init(rsc);
Jason Samsf2e4fa22009-12-15 13:27:04 -080086}
87
88
Jason Sams326e0dd2009-05-22 14:03:28 -070089ProgramFragment::~ProgramFragment()
90{
91}
92
Jason Sams6445e522010-08-04 17:50:20 -070093void ProgramFragment::setConstantColor(float r, float g, float b, float a)
94{
Alex Sakhartchouke7ae69f2010-09-14 09:50:43 -070095 if(isUserProgram()) {
96 return;
97 }
Jason Sams6445e522010-08-04 17:50:20 -070098 mConstantColor[0] = r;
99 mConstantColor[1] = g;
100 mConstantColor[2] = b;
101 mConstantColor[3] = a;
Alex Sakhartchouke7ae69f2010-09-14 09:50:43 -0700102 memcpy(mConstants[0]->getPtr(), mConstantColor, 4*sizeof(float));
Jason Sams6445e522010-08-04 17:50:20 -0700103 mDirty = true;
104}
105
Jason Samsafcb25c2009-08-25 11:34:49 -0700106void ProgramFragment::setupGL(const Context *rsc, ProgramFragmentState *state)
Jason Sams326e0dd2009-05-22 14:03:28 -0700107{
Jason Sams326e0dd2009-05-22 14:03:28 -0700108}
109
Jason Samsc460e552009-11-25 13:22:07 -0800110void ProgramFragment::setupGL2(const Context *rsc, ProgramFragmentState *state, ShaderCache *sc)
111{
Jason Sams3eb28f02010-01-27 14:41:43 -0800112
Jason Samsc460e552009-11-25 13:22:07 -0800113 //LOGE("sgl2 frag1 %x", glGetError());
114 if ((state->mLast.get() == this) && !mDirty) {
Jason Samse64c2f12010-06-22 17:22:13 -0700115 return;
Jason Samsc460e552009-11-25 13:22:07 -0800116 }
117 state->mLast.set(this);
118
Jason Sams3eb28f02010-01-27 14:41:43 -0800119 rsc->checkError("ProgramFragment::setupGL2 start");
Jason Sams6445e522010-08-04 17:50:20 -0700120
Alex Sakhartchouk6e934212010-08-31 12:02:01 -0700121 rsc->checkError("ProgramFragment::setupGL2 begin uniforms");
122 setupUserConstants(sc, true);
123
Jason Samsc460e552009-11-25 13:22:07 -0800124 for (uint32_t ct=0; ct < MAX_TEXTURE; ct++) {
125 glActiveTexture(GL_TEXTURE0 + ct);
126 if (!(mTextureEnableMask & (1 << ct)) || !mTextures[ct].get()) {
Jason Samsc460e552009-11-25 13:22:07 -0800127 continue;
128 }
129
Jason Samscf4c7c92009-12-14 12:57:40 -0800130 mTextures[ct]->uploadCheck(rsc);
Jason Samsc460e552009-11-25 13:22:07 -0800131 glBindTexture(GL_TEXTURE_2D, mTextures[ct]->getTextureID());
Jason Sams3eb28f02010-01-27 14:41:43 -0800132 rsc->checkError("ProgramFragment::setupGL2 tex bind");
Jason Samsc460e552009-11-25 13:22:07 -0800133 if (mSamplers[ct].get()) {
Jason Samsef21edc2010-02-22 15:37:51 -0800134 mSamplers[ct]->setupGL(rsc, mTextures[ct]->getType()->getIsNp2());
Jason Samsc460e552009-11-25 13:22:07 -0800135 } else {
136 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
137 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
138 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
139 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
Jason Sams3eb28f02010-01-27 14:41:43 -0800140 rsc->checkError("ProgramFragment::setupGL2 tex env");
Jason Samsc460e552009-11-25 13:22:07 -0800141 }
142
Alex Sakhartchouk660ccc72010-09-02 18:43:24 -0700143 glUniform1i(sc->fragUniformSlot(mTextureUniformIndexStart + ct), ct);
Jason Sams3eb28f02010-01-27 14:41:43 -0800144 rsc->checkError("ProgramFragment::setupGL2 uniforms");
Jason Samsc460e552009-11-25 13:22:07 -0800145 }
146
147 glActiveTexture(GL_TEXTURE0);
148 mDirty = false;
Jason Sams433eca32010-01-06 11:57:52 -0800149 rsc->checkError("ProgramFragment::setupGL2");
Jason Samsc460e552009-11-25 13:22:07 -0800150}
151
Jason Samscd506532009-12-15 19:10:11 -0800152void ProgramFragment::loadShader(Context *rsc) {
153 Program::loadShader(rsc, GL_FRAGMENT_SHADER);
Jason Samsc460e552009-11-25 13:22:07 -0800154}
155
156void ProgramFragment::createShader()
157{
Jason Samsf2e4fa22009-12-15 13:27:04 -0800158 if (mUserShader.length() > 1) {
Alex Sakhartchouke7ae69f2010-09-14 09:50:43 -0700159 mShader.append("precision mediump float;\n");
Alex Sakhartchouk660ccc72010-09-02 18:43:24 -0700160 appendUserConstants();
Jason Samsf2e4fa22009-12-15 13:27:04 -0800161 for (uint32_t ct=0; ct < mTextureCount; ct++) {
162 char buf[256];
Alex Sakhartchouke7ae69f2010-09-14 09:50:43 -0700163 sprintf(buf, "uniform sampler2D UNI_Tex%i;\n", ct);
Jason Samsc460e552009-11-25 13:22:07 -0800164 mShader.append(buf);
Jason Samsc460e552009-11-25 13:22:07 -0800165 }
Jason Samsf2e4fa22009-12-15 13:27:04 -0800166 mShader.append(mUserShader);
167 } else {
Alex Sakhartchouke7ae69f2010-09-14 09:50:43 -0700168 LOGE("ProgramFragment::createShader cannot create program, shader code not defined");
169 rsAssert(0);
Jason Samsc460e552009-11-25 13:22:07 -0800170 }
Jason Samsc460e552009-11-25 13:22:07 -0800171}
Jason Sams326e0dd2009-05-22 14:03:28 -0700172
Jason Samsc460e552009-11-25 13:22:07 -0800173void ProgramFragment::init(Context *rsc)
174{
Alex Sakhartchouk660ccc72010-09-02 18:43:24 -0700175 mUniformCount = 0;
Alex Sakhartchouk6e934212010-08-31 12:02:01 -0700176 if (mUserShader.size() > 0) {
177 for (uint32_t ct=0; ct < mConstantCount; ct++) {
178 initAddUserElement(mConstantTypes[ct]->getElement(), mUniformNames, &mUniformCount, "UNI_");
179 }
180 }
Alex Sakhartchouk660ccc72010-09-02 18:43:24 -0700181 mTextureUniformIndexStart = mUniformCount;
Alex Sakhartchouke7ae69f2010-09-14 09:50:43 -0700182 mUniformNames[mUniformCount++].setTo("UNI_Tex0");
183 mUniformNames[mUniformCount++].setTo("UNI_Tex1");
Alex Sakhartchouk6e934212010-08-31 12:02:01 -0700184
185 createShader();
Jason Samsc460e552009-11-25 13:22:07 -0800186}
Jason Sams326e0dd2009-05-22 14:03:28 -0700187
Alex Sakhartchoukfb6b6142010-05-21 12:53:13 -0700188void ProgramFragment::serialize(OStream *stream) const
189{
Jason Samse64c2f12010-06-22 17:22:13 -0700190
Alex Sakhartchoukfb6b6142010-05-21 12:53:13 -0700191}
192
193ProgramFragment *ProgramFragment::createFromStream(Context *rsc, IStream *stream)
194{
195 return NULL;
196}
197
Jason Sams326e0dd2009-05-22 14:03:28 -0700198ProgramFragmentState::ProgramFragmentState()
199{
200 mPF = NULL;
201}
202
203ProgramFragmentState::~ProgramFragmentState()
204{
205 delete mPF;
206
207}
208
Jason Sams771565f2010-05-14 15:30:29 -0700209void ProgramFragmentState::init(Context *rsc)
Jason Sams8ce125b2009-06-17 16:52:59 -0700210{
Alex Sakhartchouke7ae69f2010-09-14 09:50:43 -0700211 String8 shaderString(RS_SHADER_INTERNAL);
212 shaderString.append("varying lowp vec4 varColor;\n");
213 shaderString.append("varying vec4 varTex0;\n");
214 shaderString.append("void main() {\n");
215 shaderString.append(" lowp vec4 col = UNI_Color;\n");
216 shaderString.append(" gl_FragColor = col;\n");
217 shaderString.append("}\n");
218
219 const Element *colorElem = Element::create(rsc, RS_TYPE_FLOAT_32, RS_KIND_USER, false, 4);
220 rsc->mStateElement.elementBuilderBegin();
221 rsc->mStateElement.elementBuilderAdd(colorElem, "Color", 1);
222 const Element *constInput = rsc->mStateElement.elementBuilderCreate(rsc);
223
224 Type *inputType = new Type(rsc);
225 inputType->setElement(constInput);
226 inputType->setDimX(1);
227 inputType->compute();
228
229 uint32_t tmp[4];
230 tmp[0] = RS_PROGRAM_PARAM_CONSTANT;
231 tmp[1] = (uint32_t)inputType;
232 tmp[2] = RS_PROGRAM_PARAM_TEXTURE_COUNT;
233 tmp[3] = 0;
234
235 Allocation *constAlloc = new Allocation(rsc, inputType);
236 ProgramFragment *pf = new ProgramFragment(rsc, shaderString.string(),
237 shaderString.length(), tmp, 4);
238 pf->bindAllocation(constAlloc, 0);
239 pf->setConstantColor(1.0f, 1.0f, 1.0f, 1.0f);
240
Jason Sams8ce125b2009-06-17 16:52:59 -0700241 mDefault.set(pf);
242}
Jason Sams326e0dd2009-05-22 14:03:28 -0700243
Jason Samsf2649a92009-09-25 16:37:33 -0700244void ProgramFragmentState::deinit(Context *rsc)
245{
246 mDefault.clear();
247 mLast.clear();
248}
249
Jason Sams326e0dd2009-05-22 14:03:28 -0700250
251namespace android {
252namespace renderscript {
253
Jason Sams7dad9c32009-12-17 16:55:08 -0800254RsProgramFragment rsi_ProgramFragmentCreate(Context *rsc,
255 const uint32_t * params,
256 uint32_t paramLength)
Jason Sams326e0dd2009-05-22 14:03:28 -0700257{
Jason Sams7dad9c32009-12-17 16:55:08 -0800258 ProgramFragment *pf = new ProgramFragment(rsc, params, paramLength);
Jason Sams9397e302009-08-27 20:23:34 -0700259 pf->incUserRef();
Jason Sams5a279172010-05-17 17:28:12 -0700260 //LOGE("rsi_ProgramFragmentCreate %p", pf);
Jason Sams326e0dd2009-05-22 14:03:28 -0700261 return pf;
262}
263
Jason Samsf2e4fa22009-12-15 13:27:04 -0800264RsProgramFragment rsi_ProgramFragmentCreate2(Context *rsc, const char * shaderText,
265 uint32_t shaderLength, const uint32_t * params,
266 uint32_t paramLength)
267{
268 ProgramFragment *pf = new ProgramFragment(rsc, shaderText, shaderLength, params, paramLength);
269 pf->incUserRef();
Jason Sams5a279172010-05-17 17:28:12 -0700270 //LOGE("rsi_ProgramFragmentCreate2 %p", pf);
Jason Samsf2e4fa22009-12-15 13:27:04 -0800271 return pf;
272}
Jason Sams326e0dd2009-05-22 14:03:28 -0700273
274}
275}
276