blob: 9817fcab0d07709f617f87536bea4f849c2ae59d [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{
Alex Sakhartchoukc984dd72010-09-14 09:50:43 -070095 if(isUserProgram()) {
96 return;
97 }
Jason Sams442a6472010-08-04 17:50:20 -070098 mConstantColor[0] = r;
99 mConstantColor[1] = g;
100 mConstantColor[2] = b;
101 mConstantColor[3] = a;
Alex Sakhartchoukc984dd72010-09-14 09:50:43 -0700102 memcpy(mConstants[0]->getPtr(), mConstantColor, 4*sizeof(float));
Jason Sams442a6472010-08-04 17:50:20 -0700103 mDirty = true;
104}
105
Jason Samsbb51c402009-11-25 13:22:07 -0800106void ProgramFragment::setupGL2(const Context *rsc, ProgramFragmentState *state, ShaderCache *sc)
107{
108 //LOGE("sgl2 frag1 %x", glGetError());
109 if ((state->mLast.get() == this) && !mDirty) {
Jason Sams7c1f4c32010-06-22 17:22:13 -0700110 return;
Jason Samsbb51c402009-11-25 13:22:07 -0800111 }
112 state->mLast.set(this);
113
Jason Sams5dbfe932010-01-27 14:41:43 -0800114 rsc->checkError("ProgramFragment::setupGL2 start");
Jason Sams442a6472010-08-04 17:50:20 -0700115
Alex Sakhartchouk8442e0b2010-08-31 12:02:01 -0700116 rsc->checkError("ProgramFragment::setupGL2 begin uniforms");
117 setupUserConstants(sc, true);
118
Jason Samsbb51c402009-11-25 13:22:07 -0800119 for (uint32_t ct=0; ct < MAX_TEXTURE; ct++) {
120 glActiveTexture(GL_TEXTURE0 + ct);
121 if (!(mTextureEnableMask & (1 << ct)) || !mTextures[ct].get()) {
Jason Samsbb51c402009-11-25 13:22:07 -0800122 continue;
123 }
124
Jason Sams3b7d39b2009-12-14 12:57:40 -0800125 mTextures[ct]->uploadCheck(rsc);
Jason Samsbb51c402009-11-25 13:22:07 -0800126 glBindTexture(GL_TEXTURE_2D, mTextures[ct]->getTextureID());
Jason Sams5dbfe932010-01-27 14:41:43 -0800127 rsc->checkError("ProgramFragment::setupGL2 tex bind");
Jason Samsbb51c402009-11-25 13:22:07 -0800128 if (mSamplers[ct].get()) {
Jason Samsd081fff2010-09-16 18:18:29 -0700129 mSamplers[ct]->setupGL(rsc, mTextures[ct].get());
Jason Samsbb51c402009-11-25 13:22:07 -0800130 } else {
131 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
132 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
Jason Samsd081fff2010-09-16 18:18:29 -0700133 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
134 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
Jason Sams5dbfe932010-01-27 14:41:43 -0800135 rsc->checkError("ProgramFragment::setupGL2 tex env");
Jason Samsbb51c402009-11-25 13:22:07 -0800136 }
137
Alex Sakhartchoukcaaac0f82010-09-02 18:43:24 -0700138 glUniform1i(sc->fragUniformSlot(mTextureUniformIndexStart + ct), ct);
Jason Sams5dbfe932010-01-27 14:41:43 -0800139 rsc->checkError("ProgramFragment::setupGL2 uniforms");
Jason Samsbb51c402009-11-25 13:22:07 -0800140 }
141
142 glActiveTexture(GL_TEXTURE0);
143 mDirty = false;
Jason Samsa09a6e12010-01-06 11:57:52 -0800144 rsc->checkError("ProgramFragment::setupGL2");
Jason Samsbb51c402009-11-25 13:22:07 -0800145}
146
Jason Sams5dad8b42009-12-15 19:10:11 -0800147void ProgramFragment::loadShader(Context *rsc) {
148 Program::loadShader(rsc, GL_FRAGMENT_SHADER);
Jason Samsbb51c402009-11-25 13:22:07 -0800149}
150
151void ProgramFragment::createShader()
152{
Jason Sams7e5ab3b2009-12-15 13:27:04 -0800153 if (mUserShader.length() > 1) {
Alex Sakhartchoukc984dd72010-09-14 09:50:43 -0700154 mShader.append("precision mediump float;\n");
Alex Sakhartchoukcaaac0f82010-09-02 18:43:24 -0700155 appendUserConstants();
Jason Sams7e5ab3b2009-12-15 13:27:04 -0800156 for (uint32_t ct=0; ct < mTextureCount; ct++) {
157 char buf[256];
Alex Sakhartchoukc984dd72010-09-14 09:50:43 -0700158 sprintf(buf, "uniform sampler2D UNI_Tex%i;\n", ct);
Jason Samsbb51c402009-11-25 13:22:07 -0800159 mShader.append(buf);
Jason Samsbb51c402009-11-25 13:22:07 -0800160 }
Jason Sams7e5ab3b2009-12-15 13:27:04 -0800161 mShader.append(mUserShader);
162 } else {
Alex Sakhartchoukc984dd72010-09-14 09:50:43 -0700163 LOGE("ProgramFragment::createShader cannot create program, shader code not defined");
164 rsAssert(0);
Jason Samsbb51c402009-11-25 13:22:07 -0800165 }
Jason Samsbb51c402009-11-25 13:22:07 -0800166}
Jason Samsd19f10d2009-05-22 14:03:28 -0700167
Jason Samsbb51c402009-11-25 13:22:07 -0800168void ProgramFragment::init(Context *rsc)
169{
Alex Sakhartchoukcaaac0f82010-09-02 18:43:24 -0700170 mUniformCount = 0;
Alex Sakhartchouk8442e0b2010-08-31 12:02:01 -0700171 if (mUserShader.size() > 0) {
172 for (uint32_t ct=0; ct < mConstantCount; ct++) {
173 initAddUserElement(mConstantTypes[ct]->getElement(), mUniformNames, &mUniformCount, "UNI_");
174 }
175 }
Alex Sakhartchoukcaaac0f82010-09-02 18:43:24 -0700176 mTextureUniformIndexStart = mUniformCount;
Alex Sakhartchoukc984dd72010-09-14 09:50:43 -0700177 mUniformNames[mUniformCount++].setTo("UNI_Tex0");
178 mUniformNames[mUniformCount++].setTo("UNI_Tex1");
Alex Sakhartchouk8442e0b2010-08-31 12:02:01 -0700179
180 createShader();
Jason Samsbb51c402009-11-25 13:22:07 -0800181}
Jason Samsd19f10d2009-05-22 14:03:28 -0700182
Alex Sakhartchoukaa7d2882010-05-21 12:53:13 -0700183void ProgramFragment::serialize(OStream *stream) const
184{
Jason Sams7c1f4c32010-06-22 17:22:13 -0700185
Alex Sakhartchoukaa7d2882010-05-21 12:53:13 -0700186}
187
188ProgramFragment *ProgramFragment::createFromStream(Context *rsc, IStream *stream)
189{
190 return NULL;
191}
192
Jason Samsd19f10d2009-05-22 14:03:28 -0700193ProgramFragmentState::ProgramFragmentState()
194{
195 mPF = NULL;
196}
197
198ProgramFragmentState::~ProgramFragmentState()
199{
200 delete mPF;
201
202}
203
Jason Samsf603d212010-05-14 15:30:29 -0700204void ProgramFragmentState::init(Context *rsc)
Jason Sams9c54bdb2009-06-17 16:52:59 -0700205{
Alex Sakhartchoukc984dd72010-09-14 09:50:43 -0700206 String8 shaderString(RS_SHADER_INTERNAL);
207 shaderString.append("varying lowp vec4 varColor;\n");
208 shaderString.append("varying vec4 varTex0;\n");
209 shaderString.append("void main() {\n");
210 shaderString.append(" lowp vec4 col = UNI_Color;\n");
211 shaderString.append(" gl_FragColor = col;\n");
212 shaderString.append("}\n");
213
214 const Element *colorElem = Element::create(rsc, RS_TYPE_FLOAT_32, RS_KIND_USER, false, 4);
215 rsc->mStateElement.elementBuilderBegin();
216 rsc->mStateElement.elementBuilderAdd(colorElem, "Color", 1);
217 const Element *constInput = rsc->mStateElement.elementBuilderCreate(rsc);
218
219 Type *inputType = new Type(rsc);
220 inputType->setElement(constInput);
221 inputType->setDimX(1);
222 inputType->compute();
223
224 uint32_t tmp[4];
225 tmp[0] = RS_PROGRAM_PARAM_CONSTANT;
226 tmp[1] = (uint32_t)inputType;
227 tmp[2] = RS_PROGRAM_PARAM_TEXTURE_COUNT;
228 tmp[3] = 0;
229
230 Allocation *constAlloc = new Allocation(rsc, inputType);
231 ProgramFragment *pf = new ProgramFragment(rsc, shaderString.string(),
232 shaderString.length(), tmp, 4);
233 pf->bindAllocation(constAlloc, 0);
234 pf->setConstantColor(1.0f, 1.0f, 1.0f, 1.0f);
235
Jason Sams9c54bdb2009-06-17 16:52:59 -0700236 mDefault.set(pf);
237}
Jason Samsd19f10d2009-05-22 14:03:28 -0700238
Jason Sams61f08d62009-09-25 16:37:33 -0700239void ProgramFragmentState::deinit(Context *rsc)
240{
241 mDefault.clear();
242 mLast.clear();
243}
244
Jason Samsd19f10d2009-05-22 14:03:28 -0700245
246namespace android {
247namespace renderscript {
248
Jason Sams68afd012009-12-17 16:55:08 -0800249RsProgramFragment rsi_ProgramFragmentCreate(Context *rsc,
250 const uint32_t * params,
251 uint32_t paramLength)
Jason Samsd19f10d2009-05-22 14:03:28 -0700252{
Jason Sams68afd012009-12-17 16:55:08 -0800253 ProgramFragment *pf = new ProgramFragment(rsc, params, paramLength);
Jason Sams07ae4062009-08-27 20:23:34 -0700254 pf->incUserRef();
Jason Samsc378dab2010-05-17 17:28:12 -0700255 //LOGE("rsi_ProgramFragmentCreate %p", pf);
Jason Samsd19f10d2009-05-22 14:03:28 -0700256 return pf;
257}
258
Jason Sams7e5ab3b2009-12-15 13:27:04 -0800259RsProgramFragment rsi_ProgramFragmentCreate2(Context *rsc, const char * shaderText,
260 uint32_t shaderLength, const uint32_t * params,
261 uint32_t paramLength)
262{
263 ProgramFragment *pf = new ProgramFragment(rsc, shaderText, shaderLength, params, paramLength);
264 pf->incUserRef();
Jason Samsc378dab2010-05-17 17:28:12 -0700265 //LOGE("rsi_ProgramFragmentCreate2 %p", pf);
Jason Sams7e5ab3b2009-12-15 13:27:04 -0800266 return pf;
267}
Jason Samsd19f10d2009-05-22 14:03:28 -0700268
269}
270}
271