summaryrefslogtreecommitdiffstats
path: root/libs/rs/rsProgramFragment.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'libs/rs/rsProgramFragment.cpp')
-rw-r--r--libs/rs/rsProgramFragment.cpp368
1 files changed, 129 insertions, 239 deletions
diff --git a/libs/rs/rsProgramFragment.cpp b/libs/rs/rsProgramFragment.cpp
index c17b94c..0713fb3 100644
--- a/libs/rs/rsProgramFragment.cpp
+++ b/libs/rs/rsProgramFragment.cpp
@@ -14,161 +14,109 @@
* limitations under the License.
*/
+#ifndef ANDROID_RS_BUILD_FOR_HOST
#include "rsContext.h"
-#include "rsProgramFragment.h"
-
#include <GLES/gl.h>
#include <GLES/glext.h>
#include <GLES2/gl2.h>
#include <GLES2/gl2ext.h>
+#else
+#include "rsContextHostStub.h"
+#include <OpenGL/gl.h>
+#include <OpenGL/glext.h>
+#endif //ANDROID_RS_BUILD_FOR_HOST
+
+#include "rsProgramFragment.h"
using namespace android;
using namespace android::renderscript;
-
-ProgramFragment::ProgramFragment(Context *rsc, const uint32_t * params,
- uint32_t paramLength) :
- Program(rsc)
-{
- mAllocFile = __FILE__;
- mAllocLine = __LINE__;
- rsAssert(paramLength = 5);
-
- mEnvModes[0] = (RsTexEnvMode)params[0];
- mTextureFormats[0] = params[1];
- mEnvModes[1] = (RsTexEnvMode)params[2];
- mTextureFormats[1] = params[3];
- mPointSpriteEnable = params[4] != 0;
-
- mTextureEnableMask = 0;
- if (mEnvModes[0]) {
- mTextureEnableMask |= 1;
- }
- if (mEnvModes[1]) {
- mTextureEnableMask |= 2;
- }
- init(rsc);
-}
-
ProgramFragment::ProgramFragment(Context *rsc, const char * shaderText,
uint32_t shaderLength, const uint32_t * params,
- uint32_t paramLength) :
- Program(rsc, shaderText, shaderLength, params, paramLength)
-{
- mAllocFile = __FILE__;
- mAllocLine = __LINE__;
+ uint32_t paramLength)
+ : Program(rsc, shaderText, shaderLength, params, paramLength) {
+
+ mConstantColor[0] = 1.f;
+ mConstantColor[1] = 1.f;
+ mConstantColor[2] = 1.f;
+ mConstantColor[3] = 1.f;
init(rsc);
- mTextureEnableMask = (1 << mTextureCount) -1;
}
-
-ProgramFragment::~ProgramFragment()
-{
+ProgramFragment::~ProgramFragment() {
+ if (mShaderID) {
+ mRSC->mShaderCache.cleanupFragment(mShaderID);
+ }
}
-void ProgramFragment::setupGL(const Context *rsc, ProgramFragmentState *state)
-{
- if ((state->mLast.get() == this) && !mDirty) {
+void ProgramFragment::setConstantColor(Context *rsc, float r, float g, float b, float a) {
+ if (isUserProgram()) {
+ LOGE("Attempting to set fixed function emulation color on user program");
+ rsc->setError(RS_ERROR_BAD_SHADER, "Cannot set fixed function emulation color on user program");
return;
}
- state->mLast.set(this);
-
- for (uint32_t ct=0; ct < MAX_TEXTURE; ct++) {
- glActiveTexture(GL_TEXTURE0 + ct);
- if (!(mTextureEnableMask & (1 << ct)) || !mTextures[ct].get()) {
- glDisable(GL_TEXTURE_2D);
- continue;
- }
-
- glEnable(GL_TEXTURE_2D);
- if (rsc->checkVersion1_1()) {
- if (mPointSpriteEnable) {
- glEnable(GL_POINT_SPRITE_OES);
- } else {
- glDisable(GL_POINT_SPRITE_OES);
- }
- glTexEnvi(GL_POINT_SPRITE_OES, GL_COORD_REPLACE_OES, mPointSpriteEnable);
- }
- mTextures[ct]->uploadCheck(rsc);
- glBindTexture(GL_TEXTURE_2D, mTextures[ct]->getTextureID());
-
- switch(mEnvModes[ct]) {
- case RS_TEX_ENV_MODE_NONE:
- rsAssert(0);
- break;
- case RS_TEX_ENV_MODE_REPLACE:
- glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
- break;
- case RS_TEX_ENV_MODE_MODULATE:
- glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
- break;
- case RS_TEX_ENV_MODE_DECAL:
- glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);
- break;
- }
-
- if (mSamplers[ct].get()) {
- mSamplers[ct]->setupGL(rsc, mTextures[ct]->getType()->getIsNp2());
- } else {
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
- }
-
- // Gross hack.
- if (ct == 2) {
- glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);
-
- glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_ADD);
- glTexEnvi(GL_TEXTURE_ENV, GL_SRC0_RGB, GL_PREVIOUS);
- glTexEnvi(GL_TEXTURE_ENV, GL_SRC1_RGB, GL_TEXTURE);
- glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB, GL_SRC_COLOR);
- glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB, GL_SRC_COLOR);
-
- glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA, GL_ADD);
- glTexEnvi(GL_TEXTURE_ENV, GL_SRC0_ALPHA, GL_PREVIOUS);
- glTexEnvi(GL_TEXTURE_ENV, GL_SRC1_ALPHA, GL_TEXTURE);
- glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA, GL_SRC_ALPHA);
- glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_ALPHA, GL_SRC_ALPHA);
- }
+ if (mConstants[0].get() == NULL) {
+ LOGE("Unable to set fixed function emulation color because allocation is missing");
+ rsc->setError(RS_ERROR_BAD_SHADER, "Unable to set fixed function emulation color because allocation is missing");
+ return;
}
- glActiveTexture(GL_TEXTURE0);
- mDirty = false;
- rsc->checkError("ProgramFragment::setupGL");
+ mConstantColor[0] = r;
+ mConstantColor[1] = g;
+ mConstantColor[2] = b;
+ mConstantColor[3] = a;
+ memcpy(mConstants[0]->getPtr(), mConstantColor, 4*sizeof(float));
+ mDirty = true;
}
-void ProgramFragment::setupGL2(const Context *rsc, ProgramFragmentState *state, ShaderCache *sc)
-{
-
+void ProgramFragment::setupGL2(Context *rsc, ProgramFragmentState *state, ShaderCache *sc) {
//LOGE("sgl2 frag1 %x", glGetError());
if ((state->mLast.get() == this) && !mDirty) {
- //return;
+ return;
}
state->mLast.set(this);
rsc->checkError("ProgramFragment::setupGL2 start");
- for (uint32_t ct=0; ct < MAX_TEXTURE; ct++) {
+
+ rsc->checkError("ProgramFragment::setupGL2 begin uniforms");
+ setupUserConstants(rsc, sc, true);
+
+ uint32_t numTexturesToBind = mTextureCount;
+ uint32_t numTexturesAvailable = rsc->getMaxFragmentTextures();
+ if (numTexturesToBind >= numTexturesAvailable) {
+ LOGE("Attempting to bind %u textures on shader id %u, but only %u are available",
+ mTextureCount, (uint32_t)this, numTexturesAvailable);
+ rsc->setError(RS_ERROR_BAD_SHADER, "Cannot bind more textuers than available");
+ numTexturesToBind = numTexturesAvailable;
+ }
+
+ for (uint32_t ct=0; ct < numTexturesToBind; ct++) {
glActiveTexture(GL_TEXTURE0 + ct);
- if (!(mTextureEnableMask & (1 << ct)) || !mTextures[ct].get()) {
+ if (!mTextures[ct].get()) {
+ LOGE("No texture bound for shader id %u, texture unit %u", (uint)this, ct);
+ rsc->setError(RS_ERROR_BAD_SHADER, "No texture bound");
continue;
}
mTextures[ct]->uploadCheck(rsc);
- glBindTexture(GL_TEXTURE_2D, mTextures[ct]->getTextureID());
+ GLenum target = (GLenum)mTextures[ct]->getGLTarget();
+ if (target != GL_TEXTURE_2D && target != GL_TEXTURE_CUBE_MAP) {
+ LOGE("Attempting to bind unknown texture to shader id %u, texture unit %u", (uint)this, ct);
+ rsc->setError(RS_ERROR_BAD_SHADER, "Non-texture allocation bound to a shader");
+ }
+ glBindTexture(target, mTextures[ct]->getTextureID());
rsc->checkError("ProgramFragment::setupGL2 tex bind");
if (mSamplers[ct].get()) {
- mSamplers[ct]->setupGL(rsc, mTextures[ct]->getType()->getIsNp2());
+ mSamplers[ct]->setupGL(rsc, mTextures[ct].get());
} else {
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
+ glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+ glTexParameteri(target, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+ glTexParameteri(target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+ glTexParameteri(target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
rsc->checkError("ProgramFragment::setupGL2 tex env");
}
- glUniform1i(sc->fragUniformSlot(ct), ct);
+ glUniform1i(sc->fragUniformSlot(mTextureUniformIndexStart + ct), ct);
rsc->checkError("ProgramFragment::setupGL2 uniforms");
}
@@ -181,162 +129,104 @@ void ProgramFragment::loadShader(Context *rsc) {
Program::loadShader(rsc, GL_FRAGMENT_SHADER);
}
-void ProgramFragment::createShader()
-{
- mShader.setTo("precision mediump float;\n");
- mShader.append("varying vec4 varColor;\n");
- mShader.append("varying vec4 varTex0;\n");
-
+void ProgramFragment::createShader() {
if (mUserShader.length() > 1) {
+ mShader.append("precision mediump float;\n");
+ appendUserConstants();
+ char buf[256];
for (uint32_t ct=0; ct < mTextureCount; ct++) {
- char buf[256];
- sprintf(buf, "uniform sampler2D uni_Tex%i;\n", ct);
+ if (mTextureTargets[ct] == RS_TEXTURE_2D) {
+ snprintf(buf, sizeof(buf), "uniform sampler2D UNI_Tex%i;\n", ct);
+ } else {
+ snprintf(buf, sizeof(buf), "uniform samplerCube UNI_Tex%i;\n", ct);
+ }
mShader.append(buf);
}
-
mShader.append(mUserShader);
} else {
- uint32_t mask = mTextureEnableMask;
- uint32_t texNum = 0;
- while (mask) {
- if (mask & 1) {
- char buf[64];
- mShader.append("uniform sampler2D uni_Tex");
- sprintf(buf, "%i", texNum);
- mShader.append(buf);
- mShader.append(";\n");
- }
- mask >>= 1;
- texNum++;
- }
-
-
- mShader.append("void main() {\n");
- mShader.append(" vec4 col = varColor;\n");
-
- if (mTextureEnableMask) {
- if (mPointSpriteEnable) {
- mShader.append(" vec2 t0 = gl_PointCoord;\n");
- } else {
- mShader.append(" vec2 t0 = varTex0.xy;\n");
- }
- }
-
- mask = mTextureEnableMask;
- texNum = 0;
- while (mask) {
- if (mask & 1) {
- switch(mEnvModes[texNum]) {
- case RS_TEX_ENV_MODE_NONE:
- rsAssert(0);
- break;
- case RS_TEX_ENV_MODE_REPLACE:
- switch(mTextureFormats[texNum]) {
- case 1:
- mShader.append(" col.a = texture2D(uni_Tex0, t0).a;\n");
- break;
- case 2:
- mShader.append(" col.rgba = texture2D(uni_Tex0, t0).rgba;\n");
- break;
- case 3:
- mShader.append(" col.rgb = texture2D(uni_Tex0, t0).rgb;\n");
- break;
- case 4:
- mShader.append(" col.rgba = texture2D(uni_Tex0, t0).rgba;\n");
- break;
- }
- break;
- case RS_TEX_ENV_MODE_MODULATE:
- switch(mTextureFormats[texNum]) {
- case 1:
- mShader.append(" col.a *= texture2D(uni_Tex0, t0).a;\n");
- break;
- case 2:
- mShader.append(" col.rgba *= texture2D(uni_Tex0, t0).rgba;\n");
- break;
- case 3:
- mShader.append(" col.rgb *= texture2D(uni_Tex0, t0).rgb;\n");
- break;
- case 4:
- mShader.append(" col.rgba *= texture2D(uni_Tex0, t0).rgba;\n");
- break;
- }
- break;
- case RS_TEX_ENV_MODE_DECAL:
- mShader.append(" col = texture2D(uni_Tex0, t0);\n");
- break;
- }
+ LOGE("ProgramFragment::createShader cannot create program, shader code not defined");
+ rsAssert(0);
+ }
+}
- }
- mask >>= 1;
- texNum++;
+void ProgramFragment::init(Context *rsc) {
+ uint32_t uniformIndex = 0;
+ if (mUserShader.size() > 0) {
+ for (uint32_t ct=0; ct < mConstantCount; ct++) {
+ initAddUserElement(mConstantTypes[ct]->getElement(), mUniformNames, mUniformArraySizes, &uniformIndex, RS_SHADER_UNI);
}
+ }
+ mTextureUniformIndexStart = uniformIndex;
+ char buf[256];
+ for (uint32_t ct=0; ct < mTextureCount; ct++) {
+ snprintf(buf, sizeof(buf), "UNI_Tex%i", ct);
+ mUniformNames[uniformIndex].setTo(buf);
+ mUniformArraySizes[uniformIndex] = 1;
+ uniformIndex++;
+ }
- //mShader.append(" col.a = 1.0;\n");
- //mShader.append(" col.r = 0.5;\n");
+ createShader();
+}
- mShader.append(" gl_FragColor = col;\n");
- mShader.append("}\n");
- }
+void ProgramFragment::serialize(OStream *stream) const {
}
-void ProgramFragment::init(Context *rsc)
-{
- mUniformCount = 2;
- mUniformNames[0].setTo("uni_Tex0");
- mUniformNames[1].setTo("uni_Tex1");
+ProgramFragment *ProgramFragment::createFromStream(Context *rsc, IStream *stream) {
+ return NULL;
+}
- createShader();
+ProgramFragmentState::ProgramFragmentState() {
+ mPF = NULL;
}
-ProgramFragmentState::ProgramFragmentState()
-{
+ProgramFragmentState::~ProgramFragmentState() {
+ ObjectBase::checkDelete(mPF);
mPF = NULL;
}
-ProgramFragmentState::~ProgramFragmentState()
-{
- delete mPF;
+void ProgramFragmentState::init(Context *rsc) {
+ String8 shaderString(RS_SHADER_INTERNAL);
+ shaderString.append("varying lowp vec4 varColor;\n");
+ shaderString.append("varying vec2 varTex0;\n");
+ shaderString.append("void main() {\n");
+ shaderString.append(" lowp vec4 col = UNI_Color;\n");
+ shaderString.append(" gl_FragColor = col;\n");
+ shaderString.append("}\n");
-}
+ const Element *colorElem = Element::create(rsc, RS_TYPE_FLOAT_32, RS_KIND_USER, false, 4);
+ rsc->mStateElement.elementBuilderBegin();
+ rsc->mStateElement.elementBuilderAdd(colorElem, "Color", 1);
+ const Element *constInput = rsc->mStateElement.elementBuilderCreate(rsc);
+
+ Type *inputType = Type::getType(rsc, constInput, 1, 0, 0, false, false);
+
+ uint32_t tmp[2];
+ tmp[0] = RS_PROGRAM_PARAM_CONSTANT;
+ tmp[1] = (uint32_t)inputType;
+
+ Allocation *constAlloc = new Allocation(rsc, inputType);
+ ProgramFragment *pf = new ProgramFragment(rsc, shaderString.string(),
+ shaderString.length(), tmp, 2);
+ pf->bindAllocation(rsc, constAlloc, 0);
+ pf->setConstantColor(rsc, 1.0f, 1.0f, 1.0f, 1.0f);
-void ProgramFragmentState::init(Context *rsc, int32_t w, int32_t h)
-{
- uint32_t tmp[5] = {
- RS_TEX_ENV_MODE_NONE, 0,
- RS_TEX_ENV_MODE_NONE, 0,
- 0
- };
- ProgramFragment *pf = new ProgramFragment(rsc, tmp, 5);
mDefault.set(pf);
- pf->init(rsc);
}
-void ProgramFragmentState::deinit(Context *rsc)
-{
+void ProgramFragmentState::deinit(Context *rsc) {
mDefault.clear();
mLast.clear();
}
-
namespace android {
namespace renderscript {
-RsProgramFragment rsi_ProgramFragmentCreate(Context *rsc,
- const uint32_t * params,
- uint32_t paramLength)
-{
- ProgramFragment *pf = new ProgramFragment(rsc, params, paramLength);
- pf->incUserRef();
- return pf;
-}
-
-RsProgramFragment rsi_ProgramFragmentCreate2(Context *rsc, const char * shaderText,
+RsProgramFragment rsi_ProgramFragmentCreate(Context *rsc, const char * shaderText,
uint32_t shaderLength, const uint32_t * params,
- uint32_t paramLength)
-{
+ uint32_t paramLength) {
ProgramFragment *pf = new ProgramFragment(rsc, shaderText, shaderLength, params, paramLength);
pf->incUserRef();
+ //LOGE("rsi_ProgramFragmentCreate %p", pf);
return pf;
}