blob: 8f5c653794125fb3e26cc1de30c040ab22ed8ac6 [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
Jason Sams7e5ab3b2009-12-15 13:27:04 -080081 mTextureEnableMask = (1 << mTextureCount) -1;
Alex Sakhartchouk8442e0b2010-08-31 12:02:01 -070082
83 init(rsc);
Jason Sams7e5ab3b2009-12-15 13:27:04 -080084}
85
86
Jason Samsd19f10d2009-05-22 14:03:28 -070087ProgramFragment::~ProgramFragment()
88{
89}
90
Jason Sams442a6472010-08-04 17:50:20 -070091void ProgramFragment::setConstantColor(float r, float g, float b, float a)
92{
Alex Sakhartchoukc984dd72010-09-14 09:50:43 -070093 if(isUserProgram()) {
94 return;
95 }
Jason Sams442a6472010-08-04 17:50:20 -070096 mConstantColor[0] = r;
97 mConstantColor[1] = g;
98 mConstantColor[2] = b;
99 mConstantColor[3] = a;
Alex Sakhartchoukc984dd72010-09-14 09:50:43 -0700100 memcpy(mConstants[0]->getPtr(), mConstantColor, 4*sizeof(float));
Jason Sams442a6472010-08-04 17:50:20 -0700101 mDirty = true;
102}
103
Jason Samsbb51c402009-11-25 13:22:07 -0800104void ProgramFragment::setupGL2(const Context *rsc, ProgramFragmentState *state, ShaderCache *sc)
105{
106 //LOGE("sgl2 frag1 %x", glGetError());
107 if ((state->mLast.get() == this) && !mDirty) {
Jason Sams7c1f4c32010-06-22 17:22:13 -0700108 return;
Jason Samsbb51c402009-11-25 13:22:07 -0800109 }
110 state->mLast.set(this);
111
Jason Sams5dbfe932010-01-27 14:41:43 -0800112 rsc->checkError("ProgramFragment::setupGL2 start");
Jason Sams442a6472010-08-04 17:50:20 -0700113
Alex Sakhartchouk8442e0b2010-08-31 12:02:01 -0700114 rsc->checkError("ProgramFragment::setupGL2 begin uniforms");
115 setupUserConstants(sc, true);
116
Jason Samsbb51c402009-11-25 13:22:07 -0800117 for (uint32_t ct=0; ct < MAX_TEXTURE; ct++) {
118 glActiveTexture(GL_TEXTURE0 + ct);
119 if (!(mTextureEnableMask & (1 << ct)) || !mTextures[ct].get()) {
Jason Samsbb51c402009-11-25 13:22:07 -0800120 continue;
121 }
122
Jason Sams3b7d39b2009-12-14 12:57:40 -0800123 mTextures[ct]->uploadCheck(rsc);
Jason Samsbb51c402009-11-25 13:22:07 -0800124 glBindTexture(GL_TEXTURE_2D, mTextures[ct]->getTextureID());
Jason Sams5dbfe932010-01-27 14:41:43 -0800125 rsc->checkError("ProgramFragment::setupGL2 tex bind");
Jason Samsbb51c402009-11-25 13:22:07 -0800126 if (mSamplers[ct].get()) {
Jason Samsd081fff2010-09-16 18:18:29 -0700127 mSamplers[ct]->setupGL(rsc, mTextures[ct].get());
Jason Samsbb51c402009-11-25 13:22:07 -0800128 } else {
129 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
130 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
Jason Samsd081fff2010-09-16 18:18:29 -0700131 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
132 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
Jason Sams5dbfe932010-01-27 14:41:43 -0800133 rsc->checkError("ProgramFragment::setupGL2 tex env");
Jason Samsbb51c402009-11-25 13:22:07 -0800134 }
135
Alex Sakhartchoukcaaac0f82010-09-02 18:43:24 -0700136 glUniform1i(sc->fragUniformSlot(mTextureUniformIndexStart + ct), ct);
Jason Sams5dbfe932010-01-27 14:41:43 -0800137 rsc->checkError("ProgramFragment::setupGL2 uniforms");
Jason Samsbb51c402009-11-25 13:22:07 -0800138 }
139
140 glActiveTexture(GL_TEXTURE0);
141 mDirty = false;
Jason Samsa09a6e12010-01-06 11:57:52 -0800142 rsc->checkError("ProgramFragment::setupGL2");
Jason Samsbb51c402009-11-25 13:22:07 -0800143}
144
Jason Sams5dad8b42009-12-15 19:10:11 -0800145void ProgramFragment::loadShader(Context *rsc) {
146 Program::loadShader(rsc, GL_FRAGMENT_SHADER);
Jason Samsbb51c402009-11-25 13:22:07 -0800147}
148
149void ProgramFragment::createShader()
150{
Jason Sams7e5ab3b2009-12-15 13:27:04 -0800151 if (mUserShader.length() > 1) {
Alex Sakhartchoukc984dd72010-09-14 09:50:43 -0700152 mShader.append("precision mediump float;\n");
Alex Sakhartchoukcaaac0f82010-09-02 18:43:24 -0700153 appendUserConstants();
Jason Sams7e5ab3b2009-12-15 13:27:04 -0800154 for (uint32_t ct=0; ct < mTextureCount; ct++) {
155 char buf[256];
Alex Sakhartchoukc984dd72010-09-14 09:50:43 -0700156 sprintf(buf, "uniform sampler2D UNI_Tex%i;\n", ct);
Jason Samsbb51c402009-11-25 13:22:07 -0800157 mShader.append(buf);
Jason Samsbb51c402009-11-25 13:22:07 -0800158 }
Jason Sams7e5ab3b2009-12-15 13:27:04 -0800159 mShader.append(mUserShader);
160 } else {
Alex Sakhartchoukc984dd72010-09-14 09:50:43 -0700161 LOGE("ProgramFragment::createShader cannot create program, shader code not defined");
162 rsAssert(0);
Jason Samsbb51c402009-11-25 13:22:07 -0800163 }
Jason Samsbb51c402009-11-25 13:22:07 -0800164}
Jason Samsd19f10d2009-05-22 14:03:28 -0700165
Jason Samsbb51c402009-11-25 13:22:07 -0800166void ProgramFragment::init(Context *rsc)
167{
Alex Sakhartchoukcaaac0f82010-09-02 18:43:24 -0700168 mUniformCount = 0;
Alex Sakhartchouk8442e0b2010-08-31 12:02:01 -0700169 if (mUserShader.size() > 0) {
170 for (uint32_t ct=0; ct < mConstantCount; ct++) {
171 initAddUserElement(mConstantTypes[ct]->getElement(), mUniformNames, &mUniformCount, "UNI_");
172 }
173 }
Alex Sakhartchoukcaaac0f82010-09-02 18:43:24 -0700174 mTextureUniformIndexStart = mUniformCount;
Alex Sakhartchoukc984dd72010-09-14 09:50:43 -0700175 mUniformNames[mUniformCount++].setTo("UNI_Tex0");
176 mUniformNames[mUniformCount++].setTo("UNI_Tex1");
Alex Sakhartchouk8442e0b2010-08-31 12:02:01 -0700177
178 createShader();
Jason Samsbb51c402009-11-25 13:22:07 -0800179}
Jason Samsd19f10d2009-05-22 14:03:28 -0700180
Alex Sakhartchoukaa7d2882010-05-21 12:53:13 -0700181void ProgramFragment::serialize(OStream *stream) const
182{
Jason Sams7c1f4c32010-06-22 17:22:13 -0700183
Alex Sakhartchoukaa7d2882010-05-21 12:53:13 -0700184}
185
186ProgramFragment *ProgramFragment::createFromStream(Context *rsc, IStream *stream)
187{
188 return NULL;
189}
190
Jason Samsd19f10d2009-05-22 14:03:28 -0700191ProgramFragmentState::ProgramFragmentState()
192{
193 mPF = NULL;
194}
195
196ProgramFragmentState::~ProgramFragmentState()
197{
198 delete mPF;
199
200}
201
Jason Samsf603d212010-05-14 15:30:29 -0700202void ProgramFragmentState::init(Context *rsc)
Jason Sams9c54bdb2009-06-17 16:52:59 -0700203{
Alex Sakhartchoukc984dd72010-09-14 09:50:43 -0700204 String8 shaderString(RS_SHADER_INTERNAL);
205 shaderString.append("varying lowp vec4 varColor;\n");
206 shaderString.append("varying vec4 varTex0;\n");
207 shaderString.append("void main() {\n");
208 shaderString.append(" lowp vec4 col = UNI_Color;\n");
209 shaderString.append(" gl_FragColor = col;\n");
210 shaderString.append("}\n");
211
212 const Element *colorElem = Element::create(rsc, RS_TYPE_FLOAT_32, RS_KIND_USER, false, 4);
213 rsc->mStateElement.elementBuilderBegin();
214 rsc->mStateElement.elementBuilderAdd(colorElem, "Color", 1);
215 const Element *constInput = rsc->mStateElement.elementBuilderCreate(rsc);
216
217 Type *inputType = new Type(rsc);
218 inputType->setElement(constInput);
219 inputType->setDimX(1);
220 inputType->compute();
221
222 uint32_t tmp[4];
223 tmp[0] = RS_PROGRAM_PARAM_CONSTANT;
224 tmp[1] = (uint32_t)inputType;
225 tmp[2] = RS_PROGRAM_PARAM_TEXTURE_COUNT;
226 tmp[3] = 0;
227
228 Allocation *constAlloc = new Allocation(rsc, inputType);
229 ProgramFragment *pf = new ProgramFragment(rsc, shaderString.string(),
230 shaderString.length(), tmp, 4);
231 pf->bindAllocation(constAlloc, 0);
232 pf->setConstantColor(1.0f, 1.0f, 1.0f, 1.0f);
233
Jason Sams9c54bdb2009-06-17 16:52:59 -0700234 mDefault.set(pf);
235}
Jason Samsd19f10d2009-05-22 14:03:28 -0700236
Jason Sams61f08d62009-09-25 16:37:33 -0700237void ProgramFragmentState::deinit(Context *rsc)
238{
239 mDefault.clear();
240 mLast.clear();
241}
242
Jason Samsd19f10d2009-05-22 14:03:28 -0700243
244namespace android {
245namespace renderscript {
246
Jason Sams68afd012009-12-17 16:55:08 -0800247RsProgramFragment rsi_ProgramFragmentCreate(Context *rsc,
248 const uint32_t * params,
249 uint32_t paramLength)
Jason Samsd19f10d2009-05-22 14:03:28 -0700250{
Jason Sams68afd012009-12-17 16:55:08 -0800251 ProgramFragment *pf = new ProgramFragment(rsc, params, paramLength);
Jason Sams07ae4062009-08-27 20:23:34 -0700252 pf->incUserRef();
Jason Samsc378dab2010-05-17 17:28:12 -0700253 //LOGE("rsi_ProgramFragmentCreate %p", pf);
Jason Samsd19f10d2009-05-22 14:03:28 -0700254 return pf;
255}
256
Jason Sams7e5ab3b2009-12-15 13:27:04 -0800257RsProgramFragment rsi_ProgramFragmentCreate2(Context *rsc, const char * shaderText,
258 uint32_t shaderLength, const uint32_t * params,
259 uint32_t paramLength)
260{
261 ProgramFragment *pf = new ProgramFragment(rsc, shaderText, shaderLength, params, paramLength);
262 pf->incUserRef();
Jason Samsc378dab2010-05-17 17:28:12 -0700263 //LOGE("rsi_ProgramFragmentCreate2 %p", pf);
Jason Sams7e5ab3b2009-12-15 13:27:04 -0800264 return pf;
265}
Jason Samsd19f10d2009-05-22 14:03:28 -0700266
267}
268}
269