1d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams/*
2d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams * Copyright (C) 2009 The Android Open Source Project
3d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams *
4d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams * Licensed under the Apache License, Version 2.0 (the "License");
5d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams * you may not use this file except in compliance with the License.
6d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams * You may obtain a copy of the License at
7d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams *
8d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams *      http://www.apache.org/licenses/LICENSE-2.0
9d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams *
10d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams * Unless required by applicable law or agreed to in writing, software
11d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams * distributed under the License is distributed on an "AS IS" BASIS,
12d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams * See the License for the specific language governing permissions and
14d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams * limitations under the License.
15d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams */
16d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams
17d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams#include "rsContext.h"
18d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams#include "rsProgramFragment.h"
19d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams
204b962e57a9a1fa923283f2d76855c1c68449564fJason Sams#include <GLES/gl.h>
214b962e57a9a1fa923283f2d76855c1c68449564fJason Sams#include <GLES/glext.h>
22bb51c40d89c7dbdee7d7507fdfe0a64e8f4f87a9Jason Sams#include <GLES2/gl2.h>
23bb51c40d89c7dbdee7d7507fdfe0a64e8f4f87a9Jason Sams#include <GLES2/gl2ext.h>
244b962e57a9a1fa923283f2d76855c1c68449564fJason Sams
25d19f10d43aa400e1183aa21a97099d02074131a2Jason Samsusing namespace android;
26d19f10d43aa400e1183aa21a97099d02074131a2Jason Samsusing namespace android::renderscript;
27d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams
28d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams
2968afd01ec9fd37774d8291192952a25e5605b6fbJason SamsProgramFragment::ProgramFragment(Context *rsc, const uint32_t * params,
3068afd01ec9fd37774d8291192952a25e5605b6fbJason Sams                                 uint32_t paramLength) :
310011bcf57ff711a221a3a4c73f2a79125111647dJason Sams    Program(rsc)
32d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams{
3361f08d6fa7c7657e9fbcd17e9a1c5b9114bb3844Jason Sams    mAllocFile = __FILE__;
3461f08d6fa7c7657e9fbcd17e9a1c5b9114bb3844Jason Sams    mAllocLine = __LINE__;
3568afd01ec9fd37774d8291192952a25e5605b6fbJason Sams    rsAssert(paramLength = 5);
3668afd01ec9fd37774d8291192952a25e5605b6fbJason Sams
3768afd01ec9fd37774d8291192952a25e5605b6fbJason Sams    mEnvModes[0] = (RsTexEnvMode)params[0];
3868afd01ec9fd37774d8291192952a25e5605b6fbJason Sams    mTextureFormats[0] = params[1];
3968afd01ec9fd37774d8291192952a25e5605b6fbJason Sams    mEnvModes[1] = (RsTexEnvMode)params[2];
4068afd01ec9fd37774d8291192952a25e5605b6fbJason Sams    mTextureFormats[1] = params[3];
4168afd01ec9fd37774d8291192952a25e5605b6fbJason Sams    mPointSpriteEnable = params[4] != 0;
4268afd01ec9fd37774d8291192952a25e5605b6fbJason Sams
43d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams    mTextureEnableMask = 0;
4468afd01ec9fd37774d8291192952a25e5605b6fbJason Sams    if (mEnvModes[0]) {
4568afd01ec9fd37774d8291192952a25e5605b6fbJason Sams        mTextureEnableMask |= 1;
4668afd01ec9fd37774d8291192952a25e5605b6fbJason Sams    }
4768afd01ec9fd37774d8291192952a25e5605b6fbJason Sams    if (mEnvModes[1]) {
4868afd01ec9fd37774d8291192952a25e5605b6fbJason Sams        mTextureEnableMask |= 2;
4968afd01ec9fd37774d8291192952a25e5605b6fbJason Sams    }
5068afd01ec9fd37774d8291192952a25e5605b6fbJason Sams    init(rsc);
51d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams}
52d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams
537e5ab3b177b10fee304d011b3a4b9ee03e2b18b5Jason SamsProgramFragment::ProgramFragment(Context *rsc, const char * shaderText,
547e5ab3b177b10fee304d011b3a4b9ee03e2b18b5Jason Sams                                 uint32_t shaderLength, const uint32_t * params,
557e5ab3b177b10fee304d011b3a4b9ee03e2b18b5Jason Sams                                 uint32_t paramLength) :
567e5ab3b177b10fee304d011b3a4b9ee03e2b18b5Jason Sams    Program(rsc, shaderText, shaderLength, params, paramLength)
577e5ab3b177b10fee304d011b3a4b9ee03e2b18b5Jason Sams{
587e5ab3b177b10fee304d011b3a4b9ee03e2b18b5Jason Sams    mAllocFile = __FILE__;
597e5ab3b177b10fee304d011b3a4b9ee03e2b18b5Jason Sams    mAllocLine = __LINE__;
607e5ab3b177b10fee304d011b3a4b9ee03e2b18b5Jason Sams
617e5ab3b177b10fee304d011b3a4b9ee03e2b18b5Jason Sams    init(rsc);
627e5ab3b177b10fee304d011b3a4b9ee03e2b18b5Jason Sams    mTextureEnableMask = (1 << mTextureCount) -1;
637e5ab3b177b10fee304d011b3a4b9ee03e2b18b5Jason Sams}
647e5ab3b177b10fee304d011b3a4b9ee03e2b18b5Jason Sams
657e5ab3b177b10fee304d011b3a4b9ee03e2b18b5Jason Sams
66d19f10d43aa400e1183aa21a97099d02074131a2Jason SamsProgramFragment::~ProgramFragment()
67d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams{
68d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams}
69d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams
70b13ada5071f55c96054c47bbd88d8801cd2c0f15Jason Samsvoid ProgramFragment::setupGL(const Context *rsc, ProgramFragmentState *state)
71d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams{
729bee51c42eb8c3daffe7d6fa483edbb1689b94d2Jason Sams    if ((state->mLast.get() == this) && !mDirty) {
739bee51c42eb8c3daffe7d6fa483edbb1689b94d2Jason Sams        return;
749bee51c42eb8c3daffe7d6fa483edbb1689b94d2Jason Sams    }
759bee51c42eb8c3daffe7d6fa483edbb1689b94d2Jason Sams    state->mLast.set(this);
769bee51c42eb8c3daffe7d6fa483edbb1689b94d2Jason Sams
77d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams    for (uint32_t ct=0; ct < MAX_TEXTURE; ct++) {
78d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams        glActiveTexture(GL_TEXTURE0 + ct);
794244afa87edf8f2dde0f053f31f39f54c0fa1783Jason Sams        if (!(mTextureEnableMask & (1 << ct)) || !mTextures[ct].get()) {
80d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams            glDisable(GL_TEXTURE_2D);
81d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams            continue;
82d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams        }
83d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams
84d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams        glEnable(GL_TEXTURE_2D);
85b13ada5071f55c96054c47bbd88d8801cd2c0f15Jason Sams        if (rsc->checkVersion1_1()) {
862d496bfebc010f26d65dd5e3a3c4a8170919cf0aRomain Guy            if (mPointSpriteEnable) {
872d496bfebc010f26d65dd5e3a3c4a8170919cf0aRomain Guy                glEnable(GL_POINT_SPRITE_OES);
882d496bfebc010f26d65dd5e3a3c4a8170919cf0aRomain Guy            } else {
892d496bfebc010f26d65dd5e3a3c4a8170919cf0aRomain Guy                glDisable(GL_POINT_SPRITE_OES);
902d496bfebc010f26d65dd5e3a3c4a8170919cf0aRomain Guy            }
91b13ada5071f55c96054c47bbd88d8801cd2c0f15Jason Sams            glTexEnvi(GL_POINT_SPRITE_OES, GL_COORD_REPLACE_OES, mPointSpriteEnable);
92b13ada5071f55c96054c47bbd88d8801cd2c0f15Jason Sams        }
933b7d39bb51f851ddee441fa34884495217e477f9Jason Sams        mTextures[ct]->uploadCheck(rsc);
94d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams        glBindTexture(GL_TEXTURE_2D, mTextures[ct]->getTextureID());
95d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams
96d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams        switch(mEnvModes[ct]) {
9768afd01ec9fd37774d8291192952a25e5605b6fbJason Sams        case RS_TEX_ENV_MODE_NONE:
9868afd01ec9fd37774d8291192952a25e5605b6fbJason Sams            rsAssert(0);
9968afd01ec9fd37774d8291192952a25e5605b6fbJason Sams            break;
100d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams        case RS_TEX_ENV_MODE_REPLACE:
1014244afa87edf8f2dde0f053f31f39f54c0fa1783Jason Sams            glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
102d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams            break;
103d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams        case RS_TEX_ENV_MODE_MODULATE:
1044244afa87edf8f2dde0f053f31f39f54c0fa1783Jason Sams            glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
105d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams            break;
106d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams        case RS_TEX_ENV_MODE_DECAL:
1074244afa87edf8f2dde0f053f31f39f54c0fa1783Jason Sams            glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);
108d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams            break;
109d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams        }
110d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams
11102fb2cb531035779a25dbf9595e0628ea40585b0Jason Sams        if (mSamplers[ct].get()) {
1122978bfc6ad79c8f1138d34a704ce5b3d3d70d2c1Jason Sams            mSamplers[ct]->setupGL(rsc, mTextures[ct]->getType()->getIsNp2());
11302fb2cb531035779a25dbf9595e0628ea40585b0Jason Sams        } else {
114fe08d99725efd0dde7ba67ff1979a04fec2ba99fJason Sams            glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
115fe08d99725efd0dde7ba67ff1979a04fec2ba99fJason Sams            glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
1164244afa87edf8f2dde0f053f31f39f54c0fa1783Jason Sams            glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
117fe08d99725efd0dde7ba67ff1979a04fec2ba99fJason Sams            glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
11802fb2cb531035779a25dbf9595e0628ea40585b0Jason Sams        }
1194244afa87edf8f2dde0f053f31f39f54c0fa1783Jason Sams
1204244afa87edf8f2dde0f053f31f39f54c0fa1783Jason Sams        // Gross hack.
1214244afa87edf8f2dde0f053f31f39f54c0fa1783Jason Sams        if (ct == 2) {
1224244afa87edf8f2dde0f053f31f39f54c0fa1783Jason Sams            glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);
1234244afa87edf8f2dde0f053f31f39f54c0fa1783Jason Sams
1244244afa87edf8f2dde0f053f31f39f54c0fa1783Jason Sams            glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_ADD);
1254244afa87edf8f2dde0f053f31f39f54c0fa1783Jason Sams            glTexEnvi(GL_TEXTURE_ENV, GL_SRC0_RGB, GL_PREVIOUS);
1264244afa87edf8f2dde0f053f31f39f54c0fa1783Jason Sams            glTexEnvi(GL_TEXTURE_ENV, GL_SRC1_RGB, GL_TEXTURE);
1274244afa87edf8f2dde0f053f31f39f54c0fa1783Jason Sams            glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB, GL_SRC_COLOR);
1284244afa87edf8f2dde0f053f31f39f54c0fa1783Jason Sams            glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB, GL_SRC_COLOR);
1294244afa87edf8f2dde0f053f31f39f54c0fa1783Jason Sams
1304244afa87edf8f2dde0f053f31f39f54c0fa1783Jason Sams            glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA, GL_ADD);
1314244afa87edf8f2dde0f053f31f39f54c0fa1783Jason Sams            glTexEnvi(GL_TEXTURE_ENV, GL_SRC0_ALPHA, GL_PREVIOUS);
1324244afa87edf8f2dde0f053f31f39f54c0fa1783Jason Sams            glTexEnvi(GL_TEXTURE_ENV, GL_SRC1_ALPHA, GL_TEXTURE);
1334244afa87edf8f2dde0f053f31f39f54c0fa1783Jason Sams            glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA, GL_SRC_ALPHA);
1344244afa87edf8f2dde0f053f31f39f54c0fa1783Jason Sams            glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_ALPHA, GL_SRC_ALPHA);
1354244afa87edf8f2dde0f053f31f39f54c0fa1783Jason Sams        }
136d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams    }
137d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams    glActiveTexture(GL_TEXTURE0);
1389bee51c42eb8c3daffe7d6fa483edbb1689b94d2Jason Sams    mDirty = false;
139a09a6e145b778861f7abee86ce17e59507ed221eJason Sams    rsc->checkError("ProgramFragment::setupGL");
140d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams}
141d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams
142bb51c40d89c7dbdee7d7507fdfe0a64e8f4f87a9Jason Samsvoid ProgramFragment::setupGL2(const Context *rsc, ProgramFragmentState *state, ShaderCache *sc)
143bb51c40d89c7dbdee7d7507fdfe0a64e8f4f87a9Jason Sams{
1445dbfe93b3f15f3a837836d024958635fd8f9ad14Jason Sams
145bb51c40d89c7dbdee7d7507fdfe0a64e8f4f87a9Jason Sams    //LOGE("sgl2 frag1 %x", glGetError());
146bb51c40d89c7dbdee7d7507fdfe0a64e8f4f87a9Jason Sams    if ((state->mLast.get() == this) && !mDirty) {
147bb51c40d89c7dbdee7d7507fdfe0a64e8f4f87a9Jason Sams        //return;
148bb51c40d89c7dbdee7d7507fdfe0a64e8f4f87a9Jason Sams    }
149bb51c40d89c7dbdee7d7507fdfe0a64e8f4f87a9Jason Sams    state->mLast.set(this);
150bb51c40d89c7dbdee7d7507fdfe0a64e8f4f87a9Jason Sams
1515dbfe93b3f15f3a837836d024958635fd8f9ad14Jason Sams    rsc->checkError("ProgramFragment::setupGL2 start");
152bb51c40d89c7dbdee7d7507fdfe0a64e8f4f87a9Jason Sams    for (uint32_t ct=0; ct < MAX_TEXTURE; ct++) {
153bb51c40d89c7dbdee7d7507fdfe0a64e8f4f87a9Jason Sams        glActiveTexture(GL_TEXTURE0 + ct);
154bb51c40d89c7dbdee7d7507fdfe0a64e8f4f87a9Jason Sams        if (!(mTextureEnableMask & (1 << ct)) || !mTextures[ct].get()) {
155bb51c40d89c7dbdee7d7507fdfe0a64e8f4f87a9Jason Sams            continue;
156bb51c40d89c7dbdee7d7507fdfe0a64e8f4f87a9Jason Sams        }
157bb51c40d89c7dbdee7d7507fdfe0a64e8f4f87a9Jason Sams
1583b7d39bb51f851ddee441fa34884495217e477f9Jason Sams        mTextures[ct]->uploadCheck(rsc);
159bb51c40d89c7dbdee7d7507fdfe0a64e8f4f87a9Jason Sams        glBindTexture(GL_TEXTURE_2D, mTextures[ct]->getTextureID());
1605dbfe93b3f15f3a837836d024958635fd8f9ad14Jason Sams        rsc->checkError("ProgramFragment::setupGL2 tex bind");
161bb51c40d89c7dbdee7d7507fdfe0a64e8f4f87a9Jason Sams        if (mSamplers[ct].get()) {
1622978bfc6ad79c8f1138d34a704ce5b3d3d70d2c1Jason Sams            mSamplers[ct]->setupGL(rsc, mTextures[ct]->getType()->getIsNp2());
163bb51c40d89c7dbdee7d7507fdfe0a64e8f4f87a9Jason Sams        } else {
164bb51c40d89c7dbdee7d7507fdfe0a64e8f4f87a9Jason Sams            glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
165bb51c40d89c7dbdee7d7507fdfe0a64e8f4f87a9Jason Sams            glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
166bb51c40d89c7dbdee7d7507fdfe0a64e8f4f87a9Jason Sams            glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
167bb51c40d89c7dbdee7d7507fdfe0a64e8f4f87a9Jason Sams            glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
1685dbfe93b3f15f3a837836d024958635fd8f9ad14Jason Sams            rsc->checkError("ProgramFragment::setupGL2 tex env");
169bb51c40d89c7dbdee7d7507fdfe0a64e8f4f87a9Jason Sams        }
170bb51c40d89c7dbdee7d7507fdfe0a64e8f4f87a9Jason Sams
171bb51c40d89c7dbdee7d7507fdfe0a64e8f4f87a9Jason Sams        glUniform1i(sc->fragUniformSlot(ct), ct);
1725dbfe93b3f15f3a837836d024958635fd8f9ad14Jason Sams        rsc->checkError("ProgramFragment::setupGL2 uniforms");
173bb51c40d89c7dbdee7d7507fdfe0a64e8f4f87a9Jason Sams    }
174bb51c40d89c7dbdee7d7507fdfe0a64e8f4f87a9Jason Sams
175bb51c40d89c7dbdee7d7507fdfe0a64e8f4f87a9Jason Sams    glActiveTexture(GL_TEXTURE0);
176bb51c40d89c7dbdee7d7507fdfe0a64e8f4f87a9Jason Sams    mDirty = false;
177a09a6e145b778861f7abee86ce17e59507ed221eJason Sams    rsc->checkError("ProgramFragment::setupGL2");
178bb51c40d89c7dbdee7d7507fdfe0a64e8f4f87a9Jason Sams}
179bb51c40d89c7dbdee7d7507fdfe0a64e8f4f87a9Jason Sams
1805dad8b4d1fda37b7b4763ef7361c5eb92131cb7eJason Samsvoid ProgramFragment::loadShader(Context *rsc) {
1815dad8b4d1fda37b7b4763ef7361c5eb92131cb7eJason Sams    Program::loadShader(rsc, GL_FRAGMENT_SHADER);
182bb51c40d89c7dbdee7d7507fdfe0a64e8f4f87a9Jason Sams}
183bb51c40d89c7dbdee7d7507fdfe0a64e8f4f87a9Jason Sams
184bb51c40d89c7dbdee7d7507fdfe0a64e8f4f87a9Jason Samsvoid ProgramFragment::createShader()
185bb51c40d89c7dbdee7d7507fdfe0a64e8f4f87a9Jason Sams{
186bb51c40d89c7dbdee7d7507fdfe0a64e8f4f87a9Jason Sams    mShader.setTo("precision mediump float;\n");
187bb51c40d89c7dbdee7d7507fdfe0a64e8f4f87a9Jason Sams    mShader.append("varying vec4 varColor;\n");
188bb51c40d89c7dbdee7d7507fdfe0a64e8f4f87a9Jason Sams    mShader.append("varying vec4 varTex0;\n");
189bb51c40d89c7dbdee7d7507fdfe0a64e8f4f87a9Jason Sams
1907e5ab3b177b10fee304d011b3a4b9ee03e2b18b5Jason Sams    if (mUserShader.length() > 1) {
1917e5ab3b177b10fee304d011b3a4b9ee03e2b18b5Jason Sams        for (uint32_t ct=0; ct < mTextureCount; ct++) {
1927e5ab3b177b10fee304d011b3a4b9ee03e2b18b5Jason Sams            char buf[256];
1937e5ab3b177b10fee304d011b3a4b9ee03e2b18b5Jason Sams            sprintf(buf, "uniform sampler2D uni_Tex%i;\n", ct);
194bb51c40d89c7dbdee7d7507fdfe0a64e8f4f87a9Jason Sams            mShader.append(buf);
195bb51c40d89c7dbdee7d7507fdfe0a64e8f4f87a9Jason Sams        }
196bb51c40d89c7dbdee7d7507fdfe0a64e8f4f87a9Jason Sams
1977e5ab3b177b10fee304d011b3a4b9ee03e2b18b5Jason Sams        mShader.append(mUserShader);
1987e5ab3b177b10fee304d011b3a4b9ee03e2b18b5Jason Sams    } else {
1997e5ab3b177b10fee304d011b3a4b9ee03e2b18b5Jason Sams        uint32_t mask = mTextureEnableMask;
2007e5ab3b177b10fee304d011b3a4b9ee03e2b18b5Jason Sams        uint32_t texNum = 0;
2017e5ab3b177b10fee304d011b3a4b9ee03e2b18b5Jason Sams        while (mask) {
2027e5ab3b177b10fee304d011b3a4b9ee03e2b18b5Jason Sams            if (mask & 1) {
2037e5ab3b177b10fee304d011b3a4b9ee03e2b18b5Jason Sams                char buf[64];
2047e5ab3b177b10fee304d011b3a4b9ee03e2b18b5Jason Sams                mShader.append("uniform sampler2D uni_Tex");
2057e5ab3b177b10fee304d011b3a4b9ee03e2b18b5Jason Sams                sprintf(buf, "%i", texNum);
2067e5ab3b177b10fee304d011b3a4b9ee03e2b18b5Jason Sams                mShader.append(buf);
2077e5ab3b177b10fee304d011b3a4b9ee03e2b18b5Jason Sams                mShader.append(";\n");
2087e5ab3b177b10fee304d011b3a4b9ee03e2b18b5Jason Sams            }
2097e5ab3b177b10fee304d011b3a4b9ee03e2b18b5Jason Sams            mask >>= 1;
2107e5ab3b177b10fee304d011b3a4b9ee03e2b18b5Jason Sams            texNum++;
2117e5ab3b177b10fee304d011b3a4b9ee03e2b18b5Jason Sams        }
212bb51c40d89c7dbdee7d7507fdfe0a64e8f4f87a9Jason Sams
213bb51c40d89c7dbdee7d7507fdfe0a64e8f4f87a9Jason Sams
2147e5ab3b177b10fee304d011b3a4b9ee03e2b18b5Jason Sams        mShader.append("void main() {\n");
2157e5ab3b177b10fee304d011b3a4b9ee03e2b18b5Jason Sams        mShader.append("  vec4 col = varColor;\n");
21654c0ec14e016e4a1bf3ceab40ed6ca5447da4725Jason Sams
2177e5ab3b177b10fee304d011b3a4b9ee03e2b18b5Jason Sams        if (mTextureEnableMask) {
2187e5ab3b177b10fee304d011b3a4b9ee03e2b18b5Jason Sams            if (mPointSpriteEnable) {
219718cd1f322ee5b62b6a49cb36195bcb18a5ab711Jason Sams                mShader.append("  vec2 t0 = gl_PointCoord;\n");
2207e5ab3b177b10fee304d011b3a4b9ee03e2b18b5Jason Sams            } else {
221718cd1f322ee5b62b6a49cb36195bcb18a5ab711Jason Sams                mShader.append("  vec2 t0 = varTex0.xy;\n");
222bb51c40d89c7dbdee7d7507fdfe0a64e8f4f87a9Jason Sams            }
2237e5ab3b177b10fee304d011b3a4b9ee03e2b18b5Jason Sams        }
2247e5ab3b177b10fee304d011b3a4b9ee03e2b18b5Jason Sams
2257e5ab3b177b10fee304d011b3a4b9ee03e2b18b5Jason Sams        mask = mTextureEnableMask;
2267e5ab3b177b10fee304d011b3a4b9ee03e2b18b5Jason Sams        texNum = 0;
2277e5ab3b177b10fee304d011b3a4b9ee03e2b18b5Jason Sams        while (mask) {
2287e5ab3b177b10fee304d011b3a4b9ee03e2b18b5Jason Sams            if (mask & 1) {
2297e5ab3b177b10fee304d011b3a4b9ee03e2b18b5Jason Sams                switch(mEnvModes[texNum]) {
23068afd01ec9fd37774d8291192952a25e5605b6fbJason Sams                case RS_TEX_ENV_MODE_NONE:
23168afd01ec9fd37774d8291192952a25e5605b6fbJason Sams                    rsAssert(0);
23268afd01ec9fd37774d8291192952a25e5605b6fbJason Sams                    break;
2337e5ab3b177b10fee304d011b3a4b9ee03e2b18b5Jason Sams                case RS_TEX_ENV_MODE_REPLACE:
234718cd1f322ee5b62b6a49cb36195bcb18a5ab711Jason Sams                    switch(mTextureFormats[texNum]) {
235718cd1f322ee5b62b6a49cb36195bcb18a5ab711Jason Sams                    case 1:
236718cd1f322ee5b62b6a49cb36195bcb18a5ab711Jason Sams                        mShader.append("  col.a = texture2D(uni_Tex0, t0).a;\n");
237718cd1f322ee5b62b6a49cb36195bcb18a5ab711Jason Sams                        break;
238718cd1f322ee5b62b6a49cb36195bcb18a5ab711Jason Sams                    case 2:
239718cd1f322ee5b62b6a49cb36195bcb18a5ab711Jason Sams                        mShader.append("  col.rgba = texture2D(uni_Tex0, t0).rgba;\n");
240718cd1f322ee5b62b6a49cb36195bcb18a5ab711Jason Sams                        break;
241718cd1f322ee5b62b6a49cb36195bcb18a5ab711Jason Sams                    case 3:
242718cd1f322ee5b62b6a49cb36195bcb18a5ab711Jason Sams                        mShader.append("  col.rgb = texture2D(uni_Tex0, t0).rgb;\n");
243718cd1f322ee5b62b6a49cb36195bcb18a5ab711Jason Sams                        break;
244718cd1f322ee5b62b6a49cb36195bcb18a5ab711Jason Sams                    case 4:
245718cd1f322ee5b62b6a49cb36195bcb18a5ab711Jason Sams                        mShader.append("  col.rgba = texture2D(uni_Tex0, t0).rgba;\n");
246718cd1f322ee5b62b6a49cb36195bcb18a5ab711Jason Sams                        break;
247718cd1f322ee5b62b6a49cb36195bcb18a5ab711Jason Sams                    }
2487e5ab3b177b10fee304d011b3a4b9ee03e2b18b5Jason Sams                    break;
2497e5ab3b177b10fee304d011b3a4b9ee03e2b18b5Jason Sams                case RS_TEX_ENV_MODE_MODULATE:
250718cd1f322ee5b62b6a49cb36195bcb18a5ab711Jason Sams                    switch(mTextureFormats[texNum]) {
251718cd1f322ee5b62b6a49cb36195bcb18a5ab711Jason Sams                    case 1:
252718cd1f322ee5b62b6a49cb36195bcb18a5ab711Jason Sams                        mShader.append("  col.a *= texture2D(uni_Tex0, t0).a;\n");
253718cd1f322ee5b62b6a49cb36195bcb18a5ab711Jason Sams                        break;
254718cd1f322ee5b62b6a49cb36195bcb18a5ab711Jason Sams                    case 2:
255718cd1f322ee5b62b6a49cb36195bcb18a5ab711Jason Sams                        mShader.append("  col.rgba *= texture2D(uni_Tex0, t0).rgba;\n");
256718cd1f322ee5b62b6a49cb36195bcb18a5ab711Jason Sams                        break;
257718cd1f322ee5b62b6a49cb36195bcb18a5ab711Jason Sams                    case 3:
258718cd1f322ee5b62b6a49cb36195bcb18a5ab711Jason Sams                        mShader.append("  col.rgb *= texture2D(uni_Tex0, t0).rgb;\n");
259718cd1f322ee5b62b6a49cb36195bcb18a5ab711Jason Sams                        break;
260718cd1f322ee5b62b6a49cb36195bcb18a5ab711Jason Sams                    case 4:
261718cd1f322ee5b62b6a49cb36195bcb18a5ab711Jason Sams                        mShader.append("  col.rgba *= texture2D(uni_Tex0, t0).rgba;\n");
262718cd1f322ee5b62b6a49cb36195bcb18a5ab711Jason Sams                        break;
263718cd1f322ee5b62b6a49cb36195bcb18a5ab711Jason Sams                    }
2647e5ab3b177b10fee304d011b3a4b9ee03e2b18b5Jason Sams                    break;
2657e5ab3b177b10fee304d011b3a4b9ee03e2b18b5Jason Sams                case RS_TEX_ENV_MODE_DECAL:
266718cd1f322ee5b62b6a49cb36195bcb18a5ab711Jason Sams                    mShader.append("  col = texture2D(uni_Tex0, t0);\n");
2677e5ab3b177b10fee304d011b3a4b9ee03e2b18b5Jason Sams                    break;
2687e5ab3b177b10fee304d011b3a4b9ee03e2b18b5Jason Sams                }
269bb51c40d89c7dbdee7d7507fdfe0a64e8f4f87a9Jason Sams
2707e5ab3b177b10fee304d011b3a4b9ee03e2b18b5Jason Sams            }
2717e5ab3b177b10fee304d011b3a4b9ee03e2b18b5Jason Sams            mask >>= 1;
2727e5ab3b177b10fee304d011b3a4b9ee03e2b18b5Jason Sams            texNum++;
273bb51c40d89c7dbdee7d7507fdfe0a64e8f4f87a9Jason Sams        }
274bb51c40d89c7dbdee7d7507fdfe0a64e8f4f87a9Jason Sams
2757e5ab3b177b10fee304d011b3a4b9ee03e2b18b5Jason Sams        //mShader.append("  col.a = 1.0;\n");
2767e5ab3b177b10fee304d011b3a4b9ee03e2b18b5Jason Sams        //mShader.append("  col.r = 0.5;\n");
277bb51c40d89c7dbdee7d7507fdfe0a64e8f4f87a9Jason Sams
2787e5ab3b177b10fee304d011b3a4b9ee03e2b18b5Jason Sams        mShader.append("  gl_FragColor = col;\n");
2797e5ab3b177b10fee304d011b3a4b9ee03e2b18b5Jason Sams        mShader.append("}\n");
2807e5ab3b177b10fee304d011b3a4b9ee03e2b18b5Jason Sams    }
281bb51c40d89c7dbdee7d7507fdfe0a64e8f4f87a9Jason Sams}
282d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams
283bb51c40d89c7dbdee7d7507fdfe0a64e8f4f87a9Jason Samsvoid ProgramFragment::init(Context *rsc)
284bb51c40d89c7dbdee7d7507fdfe0a64e8f4f87a9Jason Sams{
285bb51c40d89c7dbdee7d7507fdfe0a64e8f4f87a9Jason Sams    mUniformCount = 2;
286bb51c40d89c7dbdee7d7507fdfe0a64e8f4f87a9Jason Sams    mUniformNames[0].setTo("uni_Tex0");
287bb51c40d89c7dbdee7d7507fdfe0a64e8f4f87a9Jason Sams    mUniformNames[1].setTo("uni_Tex1");
288d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams
289bb51c40d89c7dbdee7d7507fdfe0a64e8f4f87a9Jason Sams    createShader();
290bb51c40d89c7dbdee7d7507fdfe0a64e8f4f87a9Jason Sams}
291d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams
292d19f10d43aa400e1183aa21a97099d02074131a2Jason SamsProgramFragmentState::ProgramFragmentState()
293d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams{
294d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams    mPF = NULL;
295d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams}
296d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams
297d19f10d43aa400e1183aa21a97099d02074131a2Jason SamsProgramFragmentState::~ProgramFragmentState()
298d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams{
299d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams    delete mPF;
300d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams
301d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams}
302d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams
3039c54bdbf458e3c9433d237ae71cf47c4ec47d852Jason Samsvoid ProgramFragmentState::init(Context *rsc, int32_t w, int32_t h)
3049c54bdbf458e3c9433d237ae71cf47c4ec47d852Jason Sams{
30568afd01ec9fd37774d8291192952a25e5605b6fbJason Sams    uint32_t tmp[5] = {
30668afd01ec9fd37774d8291192952a25e5605b6fbJason Sams        RS_TEX_ENV_MODE_NONE, 0,
30768afd01ec9fd37774d8291192952a25e5605b6fbJason Sams        RS_TEX_ENV_MODE_NONE, 0,
30868afd01ec9fd37774d8291192952a25e5605b6fbJason Sams        0
30968afd01ec9fd37774d8291192952a25e5605b6fbJason Sams    };
31068afd01ec9fd37774d8291192952a25e5605b6fbJason Sams    ProgramFragment *pf = new ProgramFragment(rsc, tmp, 5);
3119c54bdbf458e3c9433d237ae71cf47c4ec47d852Jason Sams    mDefault.set(pf);
312bb51c40d89c7dbdee7d7507fdfe0a64e8f4f87a9Jason Sams    pf->init(rsc);
3139c54bdbf458e3c9433d237ae71cf47c4ec47d852Jason Sams}
314d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams
31561f08d6fa7c7657e9fbcd17e9a1c5b9114bb3844Jason Samsvoid ProgramFragmentState::deinit(Context *rsc)
31661f08d6fa7c7657e9fbcd17e9a1c5b9114bb3844Jason Sams{
31761f08d6fa7c7657e9fbcd17e9a1c5b9114bb3844Jason Sams    mDefault.clear();
31861f08d6fa7c7657e9fbcd17e9a1c5b9114bb3844Jason Sams    mLast.clear();
31961f08d6fa7c7657e9fbcd17e9a1c5b9114bb3844Jason Sams}
32061f08d6fa7c7657e9fbcd17e9a1c5b9114bb3844Jason Sams
321d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams
322d19f10d43aa400e1183aa21a97099d02074131a2Jason Samsnamespace android {
323d19f10d43aa400e1183aa21a97099d02074131a2Jason Samsnamespace renderscript {
324d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams
32568afd01ec9fd37774d8291192952a25e5605b6fbJason SamsRsProgramFragment rsi_ProgramFragmentCreate(Context *rsc,
32668afd01ec9fd37774d8291192952a25e5605b6fbJason Sams                                            const uint32_t * params,
32768afd01ec9fd37774d8291192952a25e5605b6fbJason Sams                                            uint32_t paramLength)
328d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams{
32968afd01ec9fd37774d8291192952a25e5605b6fbJason Sams    ProgramFragment *pf = new ProgramFragment(rsc, params, paramLength);
33007ae40623737a6060b8a925fd2e6bba76780dcd4Jason Sams    pf->incUserRef();
331d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams    return pf;
332d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams}
333d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams
3347e5ab3b177b10fee304d011b3a4b9ee03e2b18b5Jason SamsRsProgramFragment rsi_ProgramFragmentCreate2(Context *rsc, const char * shaderText,
3357e5ab3b177b10fee304d011b3a4b9ee03e2b18b5Jason Sams                             uint32_t shaderLength, const uint32_t * params,
3367e5ab3b177b10fee304d011b3a4b9ee03e2b18b5Jason Sams                             uint32_t paramLength)
3377e5ab3b177b10fee304d011b3a4b9ee03e2b18b5Jason Sams{
3387e5ab3b177b10fee304d011b3a4b9ee03e2b18b5Jason Sams    ProgramFragment *pf = new ProgramFragment(rsc, shaderText, shaderLength, params, paramLength);
3397e5ab3b177b10fee304d011b3a4b9ee03e2b18b5Jason Sams    pf->incUserRef();
3407e5ab3b177b10fee304d011b3a4b9ee03e2b18b5Jason Sams    return pf;
3417e5ab3b177b10fee304d011b3a4b9ee03e2b18b5Jason Sams}
342d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams
343d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams}
344d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams}
345d19f10d43aa400e1183aa21a97099d02074131a2Jason Sams
346