Support constant and varying colors in ProgramFragment.
Change-Id: I16ce84ff427016f3a1923594efc718eca32dd7f2
diff --git a/graphics/java/android/renderscript/ProgramFragment.java b/graphics/java/android/renderscript/ProgramFragment.java
index d06d768..04091a3 100644
--- a/graphics/java/android/renderscript/ProgramFragment.java
+++ b/graphics/java/android/renderscript/ProgramFragment.java
@@ -66,6 +66,7 @@
public static final int MAX_TEXTURE = 2;
RenderScript mRS;
boolean mPointSpriteEnable;
+ boolean mVaryingColorEnable;
public enum EnvMode {
REPLACE (1),
@@ -120,9 +121,14 @@
return this;
}
+ public Builder setVaryingColor(boolean enable) {
+ mVaryingColorEnable = enable;
+ return this;
+ }
+
public ProgramFragment create() {
mRS.validate();
- int[] tmp = new int[MAX_TEXTURE * 2 + 1];
+ int[] tmp = new int[MAX_TEXTURE * 2 + 2];
if (mSlots[0] != null) {
tmp[0] = mSlots[0].env.mID;
tmp[1] = mSlots[0].format.mID;
@@ -132,6 +138,7 @@
tmp[3] = mSlots[1].format.mID;
}
tmp[4] = mPointSpriteEnable ? 1 : 0;
+ tmp[5] = mVaryingColorEnable ? 1 : 0;
int id = mRS.nProgramFragmentCreate(tmp);
ProgramFragment pf = new ProgramFragment(id, mRS);
pf.mTextureCount = MAX_TEXTURE;
diff --git a/libs/rs/java/Fountain/src/com/android/fountain/FountainRS.java b/libs/rs/java/Fountain/src/com/android/fountain/FountainRS.java
index bff7273..297ea07 100644
--- a/libs/rs/java/Fountain/src/com/android/fountain/FountainRS.java
+++ b/libs/rs/java/Fountain/src/com/android/fountain/FountainRS.java
@@ -34,6 +34,10 @@
mRS = rs;
mRes = res;
+ ProgramFragment.Builder pfb = new ProgramFragment.Builder(rs);
+ pfb.setVaryingColor(true);
+ rs.contextBindProgramFragment(pfb.create());
+
ScriptField_Point points = new ScriptField_Point(mRS, PART_COUNT);
Mesh.AllocationBuilder smb = new Mesh.AllocationBuilder(mRS);
diff --git a/libs/rs/java/Fountain/src/com/android/fountain/fountain.rs b/libs/rs/java/Fountain/src/com/android/fountain/fountain.rs
index f87ef59..812cb7a 100644
--- a/libs/rs/java/Fountain/src/com/android/fountain/fountain.rs
+++ b/libs/rs/java/Fountain/src/com/android/fountain/fountain.rs
@@ -3,6 +3,8 @@
#pragma rs java_package_name(com.android.fountain)
+#pragma stateFragment(parent)
+
#include "rs_graphics.rsh"
static int newPart = 0;
diff --git a/libs/rs/rsFont.cpp b/libs/rs/rsFont.cpp
index e58d8b1..a741adc 100644
--- a/libs/rs/rsFont.cpp
+++ b/libs/rs/rsFont.cpp
@@ -379,12 +379,12 @@
void FontState::initRenderState()
{
- uint32_t tmp[5] = {
+ uint32_t tmp[] = {
RS_TEX_ENV_MODE_REPLACE, 1,
RS_TEX_ENV_MODE_NONE, 0,
- 0
+ 0, 0
};
- ProgramFragment *pf = new ProgramFragment(mRSC, tmp, 5);
+ ProgramFragment *pf = new ProgramFragment(mRSC, tmp, 6);
mFontShaderF.set(pf);
mFontShaderF->init(mRSC);
diff --git a/libs/rs/rsProgramFragment.cpp b/libs/rs/rsProgramFragment.cpp
index cbe33c7..056863c 100644
--- a/libs/rs/rsProgramFragment.cpp
+++ b/libs/rs/rsProgramFragment.cpp
@@ -38,13 +38,21 @@
{
mAllocFile = __FILE__;
mAllocLine = __LINE__;
- rsAssert(paramLength = 5);
+ rsAssert(paramLength == 6);
+
+ mConstantColor[0] = 1.f;
+ mConstantColor[1] = 1.f;
+ mConstantColor[2] = 1.f;
+ mConstantColor[3] = 1.f;
mEnvModes[0] = (RsTexEnvMode)params[0];
mTextureFormats[0] = params[1];
mEnvModes[1] = (RsTexEnvMode)params[2];
mTextureFormats[1] = params[3];
mPointSpriteEnable = params[4] != 0;
+ mVaryingColor = false;
+ if (paramLength > 5)
+ mVaryingColor = params[5] != 0;
mTextureEnableMask = 0;
if (mEnvModes[0]) {
@@ -53,7 +61,17 @@
if (mEnvModes[1]) {
mTextureEnableMask |= 2;
}
- init(rsc);
+
+ mUniformCount = 0;
+ mUniformNames[mUniformCount++].setTo("uni_Tex0");
+ mUniformNames[mUniformCount++].setTo("uni_Tex1");
+
+ mConstantColorUniformIndex = -1;
+ //if (!mVaryingColor) {
+ mConstantColorUniformIndex = mUniformCount;
+ mUniformNames[mUniformCount++].setTo("uni_Color");
+ //}
+ createShader();
}
ProgramFragment::ProgramFragment(Context *rsc, const char * shaderText,
@@ -64,7 +82,19 @@
mAllocFile = __FILE__;
mAllocLine = __LINE__;
- init(rsc);
+ mConstantColor[0] = 1.f;
+ mConstantColor[1] = 1.f;
+ mConstantColor[2] = 1.f;
+ mConstantColor[3] = 1.f;
+
+ LOGE("Custom FP");
+
+ mUniformCount = 2;
+ mUniformNames[0].setTo("uni_Tex0");
+ mUniformNames[1].setTo("uni_Tex1");
+
+ createShader();
+
mTextureEnableMask = (1 << mTextureCount) -1;
}
@@ -73,79 +103,17 @@
{
}
+void ProgramFragment::setConstantColor(float r, float g, float b, float a)
+{
+ mConstantColor[0] = r;
+ mConstantColor[1] = g;
+ mConstantColor[2] = b;
+ mConstantColor[3] = a;
+ mDirty = true;
+}
+
void ProgramFragment::setupGL(const Context *rsc, ProgramFragmentState *state)
{
- if ((state->mLast.get() == this) && !mDirty) {
- 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()) {
-#ifndef ANDROID_RS_BUILD_FOR_HOST // These are GLES only
- if (mPointSpriteEnable) {
- glEnable(GL_POINT_SPRITE_OES);
- } else {
- glDisable(GL_POINT_SPRITE_OES);
- }
- glTexEnvi(GL_POINT_SPRITE_OES, GL_COORD_REPLACE_OES, mPointSpriteEnable);
-#endif //ANDROID_RS_BUILD_FOR_HOST
-
- }
- 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);
- }
- }
- glActiveTexture(GL_TEXTURE0);
- mDirty = false;
- rsc->checkError("ProgramFragment::setupGL");
}
void ProgramFragment::setupGL2(const Context *rsc, ProgramFragmentState *state, ShaderCache *sc)
@@ -158,6 +126,14 @@
state->mLast.set(this);
rsc->checkError("ProgramFragment::setupGL2 start");
+
+ if (!mVaryingColor &&
+ (sc->fragUniformSlot(mConstantColorUniformIndex) >= 0)) {
+ //LOGE("mConstantColorUniformIndex %i %i", mConstantColorUniformIndex, sc->fragUniformSlot(mConstantColorUniformIndex));
+ glUniform4fv(sc->fragUniformSlot(mConstantColorUniformIndex), 1, mConstantColor);
+ rsc->checkError("ProgramFragment::color setup");
+ }
+
for (uint32_t ct=0; ct < MAX_TEXTURE; ct++) {
glActiveTexture(GL_TEXTURE0 + ct);
if (!(mTextureEnableMask & (1 << ct)) || !mTextures[ct].get()) {
@@ -195,6 +171,7 @@
mShader.setTo("precision mediump float;\n");
mShader.append("varying vec4 varColor;\n");
mShader.append("varying vec4 varTex0;\n");
+ mShader.append("uniform vec4 uni_Color;\n");
if (mUserShader.length() > 1) {
for (uint32_t ct=0; ct < mTextureCount; ct++) {
@@ -221,7 +198,11 @@
mShader.append("void main() {\n");
- mShader.append(" vec4 col = varColor;\n");
+ if (mVaryingColor) {
+ mShader.append(" vec4 col = varColor;\n");
+ } else {
+ mShader.append(" vec4 col = uni_Color;\n");
+ }
if (mTextureEnableMask) {
if (mPointSpriteEnable) {
@@ -291,11 +272,6 @@
void ProgramFragment::init(Context *rsc)
{
- mUniformCount = 2;
- mUniformNames[0].setTo("uni_Tex0");
- mUniformNames[1].setTo("uni_Tex1");
-
- createShader();
}
void ProgramFragment::serialize(OStream *stream) const
@@ -321,12 +297,12 @@
void ProgramFragmentState::init(Context *rsc)
{
- uint32_t tmp[5] = {
+ uint32_t tmp[] = {
RS_TEX_ENV_MODE_NONE, 0,
RS_TEX_ENV_MODE_NONE, 0,
- 0
+ 0, 0
};
- ProgramFragment *pf = new ProgramFragment(rsc, tmp, 5);
+ ProgramFragment *pf = new ProgramFragment(rsc, tmp, 6);
mDefault.set(pf);
pf->init(rsc);
}
diff --git a/libs/rs/rsProgramFragment.h b/libs/rs/rsProgramFragment.h
index e5bbe1b..7c1598e 100644
--- a/libs/rs/rsProgramFragment.h
+++ b/libs/rs/rsProgramFragment.h
@@ -44,6 +44,8 @@
virtual RsA3DClassID getClassId() const { return RS_A3D_CLASS_ID_PROGRAM_FRAGMENT; }
static ProgramFragment *createFromStream(Context *rsc, IStream *stream);
+ void setConstantColor(float, float, float, float);
+
protected:
// Hacks to create a program for now
uint32_t mTextureFormats[MAX_TEXTURE];
@@ -51,6 +53,10 @@
RsTexEnvMode mEnvModes[MAX_TEXTURE];
uint32_t mTextureEnableMask;
bool mPointSpriteEnable;
+ bool mVaryingColor;
+
+ float mConstantColor[4];
+ int32_t mConstantColorUniformIndex;
};
class ProgramFragmentState
diff --git a/libs/rs/rsProgramVertex.cpp b/libs/rs/rsProgramVertex.cpp
index 5558007..60de04a 100644
--- a/libs/rs/rsProgramVertex.cpp
+++ b/libs/rs/rsProgramVertex.cpp
@@ -221,7 +221,6 @@
}
rsc->checkError("ProgramVertex::setupGL2 start");
- glVertexAttrib4f(1, state->color[0], state->color[1], state->color[2], state->color[3]);
const float *f = static_cast<const float *>(mConstants[0]->getPtr());
@@ -405,11 +404,6 @@
pv->init(rsc);
pv->bindAllocation(alloc, 0);
- color[0] = 1.f;
- color[1] = 1.f;
- color[2] = 1.f;
- color[3] = 1.f;
-
updateSize(rsc);
#endif //ANDROID_RS_BUILD_FOR_HOST
diff --git a/libs/rs/rsProgramVertex.h b/libs/rs/rsProgramVertex.h
index cb93eaf..1c8b9c8 100644
--- a/libs/rs/rsProgramVertex.h
+++ b/libs/rs/rsProgramVertex.h
@@ -83,9 +83,6 @@
ObjectBaseRef<Allocation> mDefaultAlloc;
ObjectBaseRef<Type> mAllocType;
-
-
- float color[4];
};
diff --git a/libs/rs/rsScriptC_LibGL.cpp b/libs/rs/rsScriptC_LibGL.cpp
index 22b0945..f5e59534 100644
--- a/libs/rs/rsScriptC_LibGL.cpp
+++ b/libs/rs/rsScriptC_LibGL.cpp
@@ -110,6 +110,13 @@
}
+static void SC_pfConstantColor(RsProgramFragment vpf, float r, float g, float b, float a)
+{
+ //GET_TLS();
+ ProgramFragment *pf = static_cast<ProgramFragment *>(vpf);
+ pf->setConstantColor(r, g, b, a);
+}
+
//////////////////////////////////////////////////////////////////////////////
// Drawing
@@ -253,13 +260,8 @@
static void SC_color(float r, float g, float b, float a)
{
GET_TLS();
- rsc->mStateVertex.color[0] = r;
- rsc->mStateVertex.color[1] = g;
- rsc->mStateVertex.color[2] = b;
- rsc->mStateVertex.color[3] = a;
- if (!rsc->checkVersion2_0()) {
- glColor4f(r, g, b, a);
- }
+ ProgramFragment *pf = (ProgramFragment *)rsc->getFragment();
+ pf->setConstantColor(r, g, b, a);
}
static void SC_uploadToTexture2(RsAllocation va, uint32_t baseMipLevel)
@@ -371,6 +373,8 @@
{ "_Z31rsgProgramVertexLoadModelMatrixPK12rs_matrix4x4", (void *)&SC_vpLoadModelMatrix },
{ "_Z33rsgProgramVertexLoadTextureMatrixPK12rs_matrix4x4", (void *)&SC_vpLoadTextureMatrix },
+ { "_Z31rsgProgramFragmentConstantColor19rs_program_fragmentffff", (void *)&SC_pfConstantColor },
+
{ "_Z11rsgGetWidthv", (void *)&SC_getWidth },
{ "_Z12rsgGetHeightv", (void *)&SC_getHeight },
diff --git a/libs/rs/scriptc/rs_graphics.rsh b/libs/rs/scriptc/rs_graphics.rsh
index 4f53963..fd0491c 100644
--- a/libs/rs/scriptc/rs_graphics.rsh
+++ b/libs/rs/scriptc/rs_graphics.rsh
@@ -26,6 +26,9 @@
extern void __attribute__((overloadable))
rsgProgramVertexLoadTextureMatrix(const rs_matrix4x4 *);
+extern void __attribute__((overloadable))
+ rsgProgramFragmentConstantColor(rs_program_fragment, float, float, float, float);
+
extern uint __attribute__((overloadable))
rsgGetWidth(void);
extern uint __attribute__((overloadable))
@@ -76,6 +79,8 @@
///////////////////////////////////////////////////////
// misc
+
+// Depricated
extern void __attribute__((overloadable))
color(float, float, float, float);