rsProgramFragment.cpp revision 0002a17db181f2276464fe5d6caaa9d869ef7e7b
1/*
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#ifndef ANDROID_RS_BUILD_FOR_HOST
18#include "rsContext.h"
19#include <GLES/gl.h>
20#include <GLES/glext.h>
21#include <GLES2/gl2.h>
22#include <GLES2/gl2ext.h>
23#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"
30
31using namespace android;
32using namespace android::renderscript;
33
34
35ProgramFragment::ProgramFragment(Context *rsc, const uint32_t * params,
36                                 uint32_t paramLength) :
37    Program(rsc)
38{
39    mAllocFile = __FILE__;
40    mAllocLine = __LINE__;
41    rsAssert(paramLength == 6);
42
43    mConstantColor[0] = 1.f;
44    mConstantColor[1] = 1.f;
45    mConstantColor[2] = 1.f;
46    mConstantColor[3] = 1.f;
47
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;
53    mVaryingColor = false;
54    if (paramLength > 5)
55        mVaryingColor = params[5] != 0;
56
57    mTextureEnableMask = 0;
58    if (mEnvModes[0]) {
59        mTextureEnableMask |= 1;
60    }
61    if (mEnvModes[1]) {
62        mTextureEnableMask |= 2;
63    }
64
65    mUniformCount = 0;
66    mUniformNames[mUniformCount++].setTo("uni_Tex0");
67    mUniformNames[mUniformCount++].setTo("uni_Tex1");
68
69    mConstantColorUniformIndex = -1;
70    //if (!mVaryingColor) {
71        mConstantColorUniformIndex = mUniformCount;
72        mUniformNames[mUniformCount++].setTo("uni_Color");
73    //}
74    createShader();
75}
76
77ProgramFragment::ProgramFragment(Context *rsc, const char * shaderText,
78                                 uint32_t shaderLength, const uint32_t * params,
79                                 uint32_t paramLength) :
80    Program(rsc, shaderText, shaderLength, params, paramLength)
81{
82    mAllocFile = __FILE__;
83    mAllocLine = __LINE__;
84
85    mConstantColor[0] = 1.f;
86    mConstantColor[1] = 1.f;
87    mConstantColor[2] = 1.f;
88    mConstantColor[3] = 1.f;
89
90    LOGE("Custom FP");
91
92    mUniformCount = 2;
93    mUniformNames[0].setTo("uni_Tex0");
94    mUniformNames[1].setTo("uni_Tex1");
95
96    createShader();
97
98    mTextureEnableMask = (1 << mTextureCount) -1;
99}
100
101
102ProgramFragment::~ProgramFragment()
103{
104}
105
106void ProgramFragment::setConstantColor(float r, float g, float b, float a)
107{
108    mConstantColor[0] = r;
109    mConstantColor[1] = g;
110    mConstantColor[2] = b;
111    mConstantColor[3] = a;
112    mDirty = true;
113}
114
115void ProgramFragment::setupGL(const Context *rsc, ProgramFragmentState *state)
116{
117}
118
119void ProgramFragment::setupGL2(const Context *rsc, ProgramFragmentState *state, ShaderCache *sc)
120{
121
122    //LOGE("sgl2 frag1 %x", glGetError());
123    if ((state->mLast.get() == this) && !mDirty) {
124        return;
125    }
126    state->mLast.set(this);
127
128    rsc->checkError("ProgramFragment::setupGL2 start");
129
130    if (!mVaryingColor &&
131        (sc->fragUniformSlot(mConstantColorUniformIndex) >= 0)) {
132        //LOGE("mConstantColorUniformIndex %i %i", mConstantColorUniformIndex, sc->fragUniformSlot(mConstantColorUniformIndex));
133        glUniform4fv(sc->fragUniformSlot(mConstantColorUniformIndex), 1, mConstantColor);
134        rsc->checkError("ProgramFragment::color setup");
135    }
136
137    for (uint32_t ct=0; ct < MAX_TEXTURE; ct++) {
138        glActiveTexture(GL_TEXTURE0 + ct);
139        if (!(mTextureEnableMask & (1 << ct)) || !mTextures[ct].get()) {
140            continue;
141        }
142
143        mTextures[ct]->uploadCheck(rsc);
144        glBindTexture(GL_TEXTURE_2D, mTextures[ct]->getTextureID());
145        rsc->checkError("ProgramFragment::setupGL2 tex bind");
146        if (mSamplers[ct].get()) {
147            mSamplers[ct]->setupGL(rsc, mTextures[ct]->getType()->getIsNp2());
148        } else {
149            glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
150            glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
151            glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
152            glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
153            rsc->checkError("ProgramFragment::setupGL2 tex env");
154        }
155
156        glUniform1i(sc->fragUniformSlot(ct), ct);
157        rsc->checkError("ProgramFragment::setupGL2 uniforms");
158    }
159
160    glActiveTexture(GL_TEXTURE0);
161    mDirty = false;
162    rsc->checkError("ProgramFragment::setupGL2");
163}
164
165void ProgramFragment::loadShader(Context *rsc) {
166    Program::loadShader(rsc, GL_FRAGMENT_SHADER);
167}
168
169void ProgramFragment::createShader()
170{
171    mShader.setTo("precision mediump float;\n");
172    mShader.append("varying lowp vec4 varColor;\n");
173    mShader.append("varying vec4 varTex0;\n");
174    mShader.append("uniform vec4 uni_Color;\n");
175
176    if (mUserShader.length() > 1) {
177        for (uint32_t ct=0; ct < mTextureCount; ct++) {
178            char buf[256];
179            sprintf(buf, "uniform sampler2D uni_Tex%i;\n", ct);
180            mShader.append(buf);
181        }
182
183        mShader.append(mUserShader);
184    } else {
185        uint32_t mask = mTextureEnableMask;
186        uint32_t texNum = 0;
187        while (mask) {
188            if (mask & 1) {
189                char buf[64];
190                mShader.append("uniform sampler2D uni_Tex");
191                sprintf(buf, "%i", texNum);
192                mShader.append(buf);
193                mShader.append(";\n");
194            }
195            mask >>= 1;
196            texNum++;
197        }
198
199
200        mShader.append("void main() {\n");
201        if (mVaryingColor) {
202            mShader.append("  lowp vec4 col = varColor;\n");
203        } else {
204            mShader.append("  lowp vec4 col = uni_Color;\n");
205        }
206
207        if (mTextureEnableMask) {
208            if (mPointSpriteEnable) {
209                mShader.append("  vec2 t0 = gl_PointCoord;\n");
210            } else {
211                mShader.append("  vec2 t0 = varTex0.xy;\n");
212            }
213        }
214
215        mask = mTextureEnableMask;
216        texNum = 0;
217        while (mask) {
218            if (mask & 1) {
219                switch(mEnvModes[texNum]) {
220                case RS_TEX_ENV_MODE_NONE:
221                    rsAssert(0);
222                    break;
223                case RS_TEX_ENV_MODE_REPLACE:
224                    switch(mTextureFormats[texNum]) {
225                    case 1:
226                        mShader.append("  col.a = texture2D(uni_Tex0, t0).a;\n");
227                        break;
228                    case 2:
229                        mShader.append("  col.rgba = texture2D(uni_Tex0, t0).rgba;\n");
230                        break;
231                    case 3:
232                        mShader.append("  col.rgb = texture2D(uni_Tex0, t0).rgb;\n");
233                        break;
234                    case 4:
235                        mShader.append("  col.rgba = texture2D(uni_Tex0, t0).rgba;\n");
236                        break;
237                    }
238                    break;
239                case RS_TEX_ENV_MODE_MODULATE:
240                    switch(mTextureFormats[texNum]) {
241                    case 1:
242                        mShader.append("  col.a *= texture2D(uni_Tex0, t0).a;\n");
243                        break;
244                    case 2:
245                        mShader.append("  col.rgba *= texture2D(uni_Tex0, t0).rgba;\n");
246                        break;
247                    case 3:
248                        mShader.append("  col.rgb *= texture2D(uni_Tex0, t0).rgb;\n");
249                        break;
250                    case 4:
251                        mShader.append("  col.rgba *= texture2D(uni_Tex0, t0).rgba;\n");
252                        break;
253                    }
254                    break;
255                case RS_TEX_ENV_MODE_DECAL:
256                    mShader.append("  col = texture2D(uni_Tex0, t0);\n");
257                    break;
258                }
259
260            }
261            mask >>= 1;
262            texNum++;
263        }
264
265        //mShader.append("  col.a = 1.0;\n");
266        //mShader.append("  col.r = 0.5;\n");
267
268        mShader.append("  gl_FragColor = col;\n");
269        mShader.append("}\n");
270    }
271}
272
273void ProgramFragment::init(Context *rsc)
274{
275}
276
277void ProgramFragment::serialize(OStream *stream) const
278{
279
280}
281
282ProgramFragment *ProgramFragment::createFromStream(Context *rsc, IStream *stream)
283{
284    return NULL;
285}
286
287ProgramFragmentState::ProgramFragmentState()
288{
289    mPF = NULL;
290}
291
292ProgramFragmentState::~ProgramFragmentState()
293{
294    delete mPF;
295
296}
297
298void ProgramFragmentState::init(Context *rsc)
299{
300    uint32_t tmp[] = {
301        RS_TEX_ENV_MODE_NONE, 0,
302        RS_TEX_ENV_MODE_NONE, 0,
303        0, 0
304    };
305    ProgramFragment *pf = new ProgramFragment(rsc, tmp, 6);
306    mDefault.set(pf);
307    pf->init(rsc);
308}
309
310void ProgramFragmentState::deinit(Context *rsc)
311{
312    mDefault.clear();
313    mLast.clear();
314}
315
316
317namespace android {
318namespace renderscript {
319
320RsProgramFragment rsi_ProgramFragmentCreate(Context *rsc,
321                                            const uint32_t * params,
322                                            uint32_t paramLength)
323{
324    ProgramFragment *pf = new ProgramFragment(rsc, params, paramLength);
325    pf->incUserRef();
326    //LOGE("rsi_ProgramFragmentCreate %p", pf);
327    return pf;
328}
329
330RsProgramFragment rsi_ProgramFragmentCreate2(Context *rsc, const char * shaderText,
331                             uint32_t shaderLength, const uint32_t * params,
332                             uint32_t paramLength)
333{
334    ProgramFragment *pf = new ProgramFragment(rsc, shaderText, shaderLength, params, paramLength);
335    pf->incUserRef();
336    //LOGE("rsi_ProgramFragmentCreate2 %p", pf);
337    return pf;
338}
339
340}
341}
342
343