diff options
author | 2010-09-14 09:50:43 -0700 | |
---|---|---|
committer | 2010-09-14 09:50:43 -0700 | |
commit | c984dd73c6f96d16e11813ae433ef70f7648ae77 (patch) | |
tree | a40cb9dc5d1b3020e4cf33f575714e72ef3e805f | |
parent | bcd3387eed8910c540d92f26fb6680e9e0ce0588 (diff) |
Shader changes to allow for more flexible constant binding.
Change-Id: Ic66e6e2a371c6e3d5dce1b00f63acab8c09bd110
-rw-r--r-- | graphics/java/android/renderscript/ProgramFragment.java | 106 | ||||
-rw-r--r-- | graphics/java/android/renderscript/ProgramVertex.java | 113 | ||||
-rw-r--r-- | libs/rs/RenderScriptEnv.h | 2 | ||||
-rw-r--r-- | libs/rs/java/Samples/res/raw/shaderf.glsl | 3 | ||||
-rw-r--r-- | libs/rs/java/Samples/res/raw/shaderv.glsl | 16 | ||||
-rw-r--r-- | libs/rs/java/Samples/src/com/android/samples/RsRenderStatesRS.java | 7 | ||||
-rw-r--r-- | libs/rs/java/Samples/src/com/android/samples/rsrenderstates.rs | 10 | ||||
-rw-r--r-- | libs/rs/java/Samples/src/com/android/samples/shader_def.rsh | 4 | ||||
-rw-r--r-- | libs/rs/rsElement.cpp | 28 | ||||
-rw-r--r-- | libs/rs/rsElement.h | 9 | ||||
-rw-r--r-- | libs/rs/rsFont.cpp | 36 | ||||
-rw-r--r-- | libs/rs/rsFont.h | 1 | ||||
-rw-r--r-- | libs/rs/rsProgram.cpp | 16 | ||||
-rw-r--r-- | libs/rs/rsProgram.h | 7 | ||||
-rw-r--r-- | libs/rs/rsProgramFragment.cpp | 151 | ||||
-rw-r--r-- | libs/rs/rsProgramVertex.cpp | 142 | ||||
-rw-r--r-- | libs/rs/rsProgramVertex.h | 2 |
17 files changed, 391 insertions, 262 deletions
diff --git a/graphics/java/android/renderscript/ProgramFragment.java b/graphics/java/android/renderscript/ProgramFragment.java index 04091a39abc2..00c5cf1f18b9 100644 --- a/graphics/java/android/renderscript/ProgramFragment.java +++ b/graphics/java/android/renderscript/ProgramFragment.java @@ -62,9 +62,9 @@ public class ProgramFragment extends Program { } } - public static class Builder { + public static class Builder extends ShaderBuilder { public static final int MAX_TEXTURE = 2; - RenderScript mRS; + int mNumTextures; boolean mPointSpriteEnable; boolean mVaryingColorEnable; @@ -101,7 +101,72 @@ public class ProgramFragment extends Program { } Slot[] mSlots; + private void buildShaderString() { + mShader = "//rs_shader_internal\n"; + mShader += "varying lowp vec4 varColor;\n"; + mShader += "varying vec4 varTex0;\n"; + + mShader += "void main() {\n"; + if (mVaryingColorEnable) { + mShader += " lowp vec4 col = varColor;\n"; + } else { + mShader += " lowp vec4 col = UNI_Color;\n"; + } + + if (mNumTextures != 0) { + if (mPointSpriteEnable) { + mShader += " vec2 t0 = gl_PointCoord;\n"; + } else { + mShader += " vec2 t0 = varTex0.xy;\n"; + } + } + + for(int i = 0; i < mNumTextures; i ++) { + switch(mSlots[i].env) { + case REPLACE: + switch (mSlots[i].format) { + case ALPHA: + mShader += " col.a = texture2D(UNI_Tex0, t0).a;\n"; + break; + case LUMINANCE_ALPHA: + mShader += " col.rgba = texture2D(UNI_Tex0, t0).rgba;\n"; + break; + case RGB: + mShader += " col.rgb = texture2D(UNI_Tex0, t0).rgb;\n"; + break; + case RGBA: + mShader += " col.rgba = texture2D(UNI_Tex0, t0).rgba;\n"; + break; + } + break; + case MODULATE: + switch (mSlots[i].format) { + case ALPHA: + mShader += " col.a *= texture2D(UNI_Tex0, t0).a;\n"; + break; + case LUMINANCE_ALPHA: + mShader += " col.rgba *= texture2D(UNI_Tex0, t0).rgba;\n"; + break; + case RGB: + mShader += " col.rgb *= texture2D(UNI_Tex0, t0).rgb;\n"; + break; + case RGBA: + mShader += " col.rgba *= texture2D(UNI_Tex0, t0).rgba;\n"; + break; + } + break; + case DECAL: + mShader += " col = texture2D(UNI_Tex0, t0);\n"; + break; + } + } + + mShader += " gl_FragColor = col;\n"; + mShader += "}\n"; + } + public Builder(RenderScript rs) { + super(rs); mRS = rs; mSlots = new Slot[MAX_TEXTURE]; mPointSpriteEnable = false; @@ -126,22 +191,35 @@ public class ProgramFragment extends Program { return this; } + @Override public ProgramFragment create() { - mRS.validate(); - int[] tmp = new int[MAX_TEXTURE * 2 + 2]; - if (mSlots[0] != null) { - tmp[0] = mSlots[0].env.mID; - tmp[1] = mSlots[0].format.mID; + mNumTextures = 0; + for(int i = 0; i < MAX_TEXTURE; i ++) { + if(mSlots[i] != null) { + mNumTextures ++; + } } - if (mSlots[1] != null) { - tmp[2] = mSlots[1].env.mID; - tmp[3] = mSlots[1].format.mID; + buildShaderString(); + Type constType = null; + if (!mVaryingColorEnable) { + Element.Builder b = new Element.Builder(mRS); + b.add(Element.F32_4(mRS), "Color"); + Type.Builder typeBuilder = new Type.Builder(mRS, b.create()); + typeBuilder.add(Dimension.X, 1); + constType = typeBuilder.create(); + addConstant(constType); } - tmp[4] = mPointSpriteEnable ? 1 : 0; - tmp[5] = mVaryingColorEnable ? 1 : 0; - int id = mRS.nProgramFragmentCreate(tmp); - ProgramFragment pf = new ProgramFragment(id, mRS); + setTextureCount(mNumTextures); + + ProgramFragment pf = super.create(); pf.mTextureCount = MAX_TEXTURE; + if (!mVaryingColorEnable) { + Allocation constantData = Allocation.createTyped(mRS,constType); + float[] data = new float[4]; + data[0] = data[1] = data[2] = data[3] = 1.0f; + constantData.data(data); + pf.bindConstants(constantData, 0); + } return pf; } } diff --git a/graphics/java/android/renderscript/ProgramVertex.java b/graphics/java/android/renderscript/ProgramVertex.java index b072433cdafb..119db69598e1 100644 --- a/graphics/java/android/renderscript/ProgramVertex.java +++ b/graphics/java/android/renderscript/ProgramVertex.java @@ -17,6 +17,7 @@ package android.renderscript; +import android.graphics.Matrix; import android.util.Config; import android.util.Log; @@ -38,29 +39,6 @@ public class ProgramVertex extends Program { bindConstants(va.mAlloc, 0); } - - public static class Builder { - RenderScript mRS; - boolean mTextureMatrixEnable; - - public Builder(RenderScript rs, Element in, Element out) { - mRS = rs; - } - public Builder(RenderScript rs) { - mRS = rs; - } - - public Builder setTextureMatrixEnable(boolean enable) { - mTextureMatrixEnable = enable; - return this; - } - - public ProgramVertex create() { - int id = mRS.nProgramVertexCreate(mTextureMatrixEnable); - return new ProgramVertex(id, mRS); - } - } - public static class ShaderBuilder extends BaseProgramBuilder { public ShaderBuilder(RenderScript rs) { super(rs); @@ -93,6 +71,68 @@ public class ProgramVertex extends Program { } } + public static class Builder extends ShaderBuilder { + boolean mTextureMatrixEnable; + + public Builder(RenderScript rs, Element in, Element out) { + super(rs); + } + public Builder(RenderScript rs) { + super(rs); + } + + public Builder setTextureMatrixEnable(boolean enable) { + mTextureMatrixEnable = enable; + return this; + } + static Type getConstantInputType(RenderScript rs) { + Element.Builder b = new Element.Builder(rs); + b.add(Element.MATRIX4X4(rs), "MV"); + b.add(Element.MATRIX4X4(rs), "P"); + b.add(Element.MATRIX4X4(rs), "TexMatrix"); + b.add(Element.MATRIX4X4(rs), "MVP"); + + Type.Builder typeBuilder = new Type.Builder(rs, b.create()); + typeBuilder.add(Dimension.X, 1); + return typeBuilder.create(); + } + + private void buildShaderString() { + + mShader = "//rs_shader_internal\n"; + mShader += "varying vec4 varColor;\n"; + mShader += "varying vec4 varTex0;\n"; + + mShader += "void main() {\n"; + mShader += " gl_Position = UNI_MVP * ATTRIB_position;\n"; + mShader += " gl_PointSize = 1.0;\n"; + + mShader += " varColor = ATTRIB_color;\n"; + if (mTextureMatrixEnable) { + mShader += " varTex0 = UNI_TexMatrix * ATTRIB_texture0;\n"; + } else { + mShader += " varTex0 = ATTRIB_texture0;\n"; + } + mShader += "}\n"; + } + + @Override + public ProgramVertex create() { + buildShaderString(); + + addConstant(getConstantInputType(mRS)); + + Element.Builder b = new Element.Builder(mRS); + b.add(Element.F32_4(mRS), "position"); + b.add(Element.F32_4(mRS), "color"); + b.add(Element.F32_3(mRS), "normal"); + b.add(Element.F32_4(mRS), "texture0"); + addInput(b.create()); + + return super.create(); + } + } + public static class MatrixAllocation { @@ -105,9 +145,14 @@ public class ProgramVertex extends Program { Matrix4f mTexture; public Allocation mAlloc; + private FieldPacker mIOBuffer; public MatrixAllocation(RenderScript rs) { - mAlloc = Allocation.createSized(rs, Element.createUser(rs, Element.DataType.FLOAT_32), 48); + Type constInputType = ProgramVertex.Builder.getConstantInputType(rs); + mAlloc = Allocation.createTyped(rs, constInputType); + int bufferSize = constInputType.getElement().getSizeBytes()* + constInputType.getElementCount(); + mIOBuffer = new FieldPacker(bufferSize); loadModelview(new Matrix4f()); loadProjection(new Matrix4f()); loadTexture(new Matrix4f()); @@ -118,24 +163,32 @@ public class ProgramVertex extends Program { mAlloc = null; } + private void addToBuffer(int offset, Matrix4f m) { + mIOBuffer.reset(offset); + for(int i = 0; i < 16; i ++) { + mIOBuffer.addF32(m.mMat[i]); + } + mAlloc.data(mIOBuffer.getData()); + } + public void loadModelview(Matrix4f m) { mModel = m; - mAlloc.subData1D(MODELVIEW_OFFSET, 16, m.mMat); + addToBuffer(MODELVIEW_OFFSET*4, m); } public void loadProjection(Matrix4f m) { mProjection = m; - mAlloc.subData1D(PROJECTION_OFFSET, 16, m.mMat); + addToBuffer(PROJECTION_OFFSET*4, m); } public void loadTexture(Matrix4f m) { mTexture = m; - mAlloc.subData1D(TEXTURE_OFFSET, 16, m.mMat); + addToBuffer(TEXTURE_OFFSET*4, m); } public void setupOrthoWindow(int w, int h) { mProjection.loadOrtho(0,w, h,0, -1,1); - mAlloc.subData1D(PROJECTION_OFFSET, 16, mProjection.mMat); + addToBuffer(PROJECTION_OFFSET*4, mProjection); } public void setupOrthoNormalized(int w, int h) { @@ -147,7 +200,7 @@ public class ProgramVertex extends Program { float aspect = ((float)h) / w; mProjection.loadOrtho(-1,1, -aspect,aspect, -1,1); } - mAlloc.subData1D(PROJECTION_OFFSET, 16, mProjection.mMat); + addToBuffer(PROJECTION_OFFSET*4, mProjection); } public void setupProjectionNormalized(int w, int h) { @@ -173,7 +226,7 @@ public class ProgramVertex extends Program { m1.loadMultiply(m1, m2); mProjection = m1; - mAlloc.subData1D(PROJECTION_OFFSET, 16, mProjection.mMat); + addToBuffer(PROJECTION_OFFSET*4, mProjection); } } diff --git a/libs/rs/RenderScriptEnv.h b/libs/rs/RenderScriptEnv.h index 92259041b73f..c83ece452382 100644 --- a/libs/rs/RenderScriptEnv.h +++ b/libs/rs/RenderScriptEnv.h @@ -28,4 +28,4 @@ typedef struct { #define RS_PROGRAM_VERTEX_MODELVIEW_OFFSET 0 #define RS_PROGRAM_VERTEX_PROJECTION_OFFSET 16 #define RS_PROGRAM_VERTEX_TEXTURE_OFFSET 32 - +#define RS_PROGRAM_VERTEX_MVP_OFFSET 48 diff --git a/libs/rs/java/Samples/res/raw/shaderf.glsl b/libs/rs/java/Samples/res/raw/shaderf.glsl index fdcf48199027..fcbe7ee5af16 100644 --- a/libs/rs/java/Samples/res/raw/shaderf.glsl +++ b/libs/rs/java/Samples/res/raw/shaderf.glsl @@ -3,10 +3,11 @@ varying lowp float light0_Diffuse; varying lowp float light0_Specular; varying lowp float light1_Diffuse; varying lowp float light1_Specular; +varying vec2 varTex0; void main() { vec2 t0 = varTex0.xy; - lowp vec4 col = texture2D(uni_Tex0, t0).rgba; + lowp vec4 col = texture2D(UNI_Tex0, t0).rgba; col.xyz = col.xyz * (light0_Diffuse * UNI_light0_DiffuseColor + light1_Diffuse * UNI_light1_DiffuseColor); col.xyz += light0_Specular * UNI_light0_SpecularColor; col.xyz += light1_Specular * UNI_light1_SpecularColor; diff --git a/libs/rs/java/Samples/res/raw/shaderv.glsl b/libs/rs/java/Samples/res/raw/shaderv.glsl index 7f611978c570..867589cf336d 100644 --- a/libs/rs/java/Samples/res/raw/shaderv.glsl +++ b/libs/rs/java/Samples/res/raw/shaderv.glsl @@ -2,24 +2,12 @@ varying float light0_Diffuse; varying float light0_Specular; varying float light1_Diffuse; varying float light1_Specular; - -/* -rs_matrix4x4 model; - float3 light0_Posision; - float light0_Diffuse; - float light0_Specular; - float light0_CosinePower; - - float3 light1_Posision; - float light1_Diffuse; - float light1_Specular; - float light1_CosinePower; -*/ +varying vec2 varTex0; // This is where actual shader code begins void main() { vec4 worldPos = UNI_model * ATTRIB_position; - gl_Position = UNI_MVP * worldPos; + gl_Position = UNI_proj * worldPos; mat3 model3 = mat3(UNI_model[0].xyz, UNI_model[1].xyz, UNI_model[2].xyz); vec3 worldNorm = model3 * ATTRIB_normal; diff --git a/libs/rs/java/Samples/src/com/android/samples/RsRenderStatesRS.java b/libs/rs/java/Samples/src/com/android/samples/RsRenderStatesRS.java index e76e740ed0fa..d920527f2a75 100644 --- a/libs/rs/java/Samples/src/com/android/samples/RsRenderStatesRS.java +++ b/libs/rs/java/Samples/src/com/android/samples/RsRenderStatesRS.java @@ -67,7 +67,6 @@ public class RsRenderStatesRS { // Custom shaders private ProgramVertex mProgVertexCustom; - private ProgramVertex.MatrixAllocation mPVACustom; private ProgramFragment mProgFragmentCustom; private ScriptField_VertexShaderConstants_s mVSConst; private ScriptField_FragentShaderConstants_s mFSConst; @@ -202,9 +201,7 @@ public class RsRenderStatesRS { pvbCustom.addConstant(mVSConst.getAllocation().getType()); mProgVertexCustom = pvbCustom.create(); // Bind the source of constant data - mProgVertexCustom.bindConstants(mVSConst.getAllocation(), 1); - mPVACustom = new ProgramVertex.MatrixAllocation(mRS); - mProgVertexCustom.bindAllocation(mPVACustom); + mProgVertexCustom.bindConstants(mVSConst.getAllocation(), 0); ProgramFragment.ShaderBuilder pfbCustom = new ProgramFragment.ShaderBuilder(mRS); // Specify the resource that contains the shader string @@ -215,7 +212,7 @@ public class RsRenderStatesRS { pfbCustom.addConstant(mFSConst.getAllocation().getType()); mProgFragmentCustom = pfbCustom.create(); // Bind the source of constant data - mProgFragmentCustom.bindConstants(mFSConst.getAllocation(), 1); + mProgFragmentCustom.bindConstants(mFSConst.getAllocation(), 0); mScript.set_gProgVertexCustom(mProgVertexCustom); mScript.set_gProgFragmentCustom(mProgFragmentCustom); diff --git a/libs/rs/java/Samples/src/com/android/samples/rsrenderstates.rs b/libs/rs/java/Samples/src/com/android/samples/rsrenderstates.rs index 4bcf7f55d9c3..c7bea93c9d44 100644 --- a/libs/rs/java/Samples/src/com/android/samples/rsrenderstates.rs +++ b/libs/rs/java/Samples/src/com/android/samples/rsrenderstates.rs @@ -395,14 +395,12 @@ void displayCustomShaderSamples() { rsMatrixLoadTranslate(&gVSConstants->model, 0.0f, 0.0f, -10.0f); rsMatrixRotate(&gVSConstants->model, gTorusRotation, 1.0f, 0.0f, 0.0f); rsMatrixRotate(&gVSConstants->model, gTorusRotation, 0.0f, 0.0f, 1.0f); + // Setup the projectioni matrix + float aspect = (float)rsgGetWidth() / (float)rsgGetHeight(); + rsMatrixLoadPerspective(&gVSConstants->proj, 30.0f, aspect, 0.1f, 100.0f); setupCustomShaderLights(); rsgBindProgramVertex(gProgVertexCustom); - // Setup the projectioni matrix with 60 degree field of view - rs_matrix4x4 proj; - float aspect = (float)rsgGetWidth() / (float)rsgGetHeight(); - rsMatrixLoadPerspective(&proj, 30.0f, aspect, 0.1f, 100.0f); - rsgProgramVertexLoadProjectionMatrix(&proj); // Fragment shader with texture rsgBindProgramStore(gProgStoreBlendNoneDepth); @@ -416,7 +414,7 @@ void displayCustomShaderSamples() { rsgFontColor(1.0f, 1.0f, 1.0f, 1.0f); rsgBindFont(gFontMono); - rsgDrawText("Custom shader sample", 10, rsgGetHeight() - 10); + //rsgDrawText("Custom shader sample", 10, rsgGetHeight() - 10); } int root(int launchID) { diff --git a/libs/rs/java/Samples/src/com/android/samples/shader_def.rsh b/libs/rs/java/Samples/src/com/android/samples/shader_def.rsh index 1b697cab4b41..e3f62063bdd2 100644 --- a/libs/rs/java/Samples/src/com/android/samples/shader_def.rsh +++ b/libs/rs/java/Samples/src/com/android/samples/shader_def.rsh @@ -18,6 +18,7 @@ typedef struct VertexShaderConstants_s { rs_matrix4x4 model; + rs_matrix4x4 proj; float3 light0_Posision; float light0_Diffuse; float light0_Specular; @@ -27,7 +28,6 @@ typedef struct VertexShaderConstants_s { float light1_Diffuse; float light1_Specular; float light1_CosinePower; - } VertexShaderConstants; typedef struct FragentShaderConstants_s { @@ -42,6 +42,6 @@ typedef struct FragentShaderConstants_s { typedef struct VertexShaderInputs_s { float4 position; float3 normal; - float4 texture0; + float2 texture0; } VertexShaderInputs; diff --git a/libs/rs/rsElement.cpp b/libs/rs/rsElement.cpp index 0b7bb27a1f57..d0909c824df0 100644 --- a/libs/rs/rsElement.cpp +++ b/libs/rs/rsElement.cpp @@ -314,6 +314,11 @@ void Element::decRefs(const void *ptr) const ElementState::ElementState() { + const uint32_t initialCapacity = 32; + mBuilderElements.setCapacity(initialCapacity); + mBuilderNameStrings.setCapacity(initialCapacity); + mBuilderNameLengths.setCapacity(initialCapacity); + mBuilderArrays.setCapacity(initialCapacity); } ElementState::~ElementState() @@ -321,6 +326,29 @@ ElementState::~ElementState() rsAssert(!mElements.size()); } +void ElementState::elementBuilderBegin() { + mBuilderElements.clear(); + mBuilderNameStrings.clear(); + mBuilderNameLengths.clear(); + mBuilderArrays.clear(); +} + +void ElementState::elementBuilderAdd(const Element *e, const char *nameStr, uint32_t arraySize) { + mBuilderElements.push(e); + mBuilderNameStrings.push(nameStr); + mBuilderNameLengths.push(strlen(nameStr)); + mBuilderArrays.push(arraySize); + +} + +const Element *ElementState::elementBuilderCreate(Context *rsc) { + return Element::create(rsc, mBuilderElements.size(), + &(mBuilderElements.editArray()[0]), + &(mBuilderNameStrings.editArray()[0]), + mBuilderNameLengths.editArray(), + mBuilderArrays.editArray()); +} + ///////////////////////////////////////// // diff --git a/libs/rs/rsElement.h b/libs/rs/rsElement.h index 42eef4adcb0f..ae6a6ccb2ea7 100644 --- a/libs/rs/rsElement.h +++ b/libs/rs/rsElement.h @@ -99,8 +99,17 @@ public: ElementState(); ~ElementState(); + void elementBuilderBegin(); + void elementBuilderAdd(const Element *e, const char *nameStr, uint32_t arraySize); + const Element *elementBuilderCreate(Context *rsc); + // Cache of all existing elements. Vector<Element *> mElements; +private: + Vector<const Element *> mBuilderElements; + Vector<const char*> mBuilderNameStrings; + Vector<size_t> mBuilderNameLengths; + Vector<uint32_t> mBuilderArrays; }; diff --git a/libs/rs/rsFont.cpp b/libs/rs/rsFont.cpp index 5889bfb23976..0f815a2fa199 100644 --- a/libs/rs/rsFont.cpp +++ b/libs/rs/rsFont.cpp @@ -387,14 +387,34 @@ bool FontState::cacheBitmap(FT_Bitmap *bitmap, uint32_t *retOriginX, uint32_t *r void FontState::initRenderState() { - uint32_t tmp[] = { - RS_TEX_ENV_MODE_REPLACE, 1, - RS_TEX_ENV_MODE_NONE, 0, - 0, 0 - }; - ProgramFragment *pf = new ProgramFragment(mRSC, tmp, 6); + String8 shaderString("varying vec4 varTex0;\n"); + shaderString.append("void main() {\n"); + shaderString.append(" lowp vec4 col = UNI_Color;\n"); + shaderString.append(" col.a = texture2D(UNI_Tex0, varTex0.xy).a;\n"); + shaderString.append(" gl_FragColor = col;\n"); + shaderString.append("}\n"); + + const Element *colorElem = Element::create(mRSC, RS_TYPE_FLOAT_32, RS_KIND_USER, false, 4); + mRSC->mStateElement.elementBuilderBegin(); + mRSC->mStateElement.elementBuilderAdd(colorElem, "Color", 1); + const Element *constInput = mRSC->mStateElement.elementBuilderCreate(mRSC); + + Type *inputType = new Type(mRSC); + inputType->setElement(constInput); + inputType->setDimX(1); + inputType->compute(); + + uint32_t tmp[4]; + tmp[0] = RS_PROGRAM_PARAM_CONSTANT; + tmp[1] = (uint32_t)inputType; + tmp[2] = RS_PROGRAM_PARAM_TEXTURE_COUNT; + tmp[3] = 1; + + mFontShaderFConstant.set(new Allocation(mRSC, inputType)); + ProgramFragment *pf = new ProgramFragment(mRSC, shaderString.string(), + shaderString.length(), tmp, 4); mFontShaderF.set(pf); - mFontShaderF->init(mRSC); + mFontShaderF->bindAllocation(mFontShaderFConstant.get(), 0); Sampler *sampler = new Sampler(mRSC, RS_SAMPLER_NEAREST, RS_SAMPLER_NEAREST, RS_SAMPLER_CLAMP, RS_SAMPLER_CLAMP, RS_SAMPLER_CLAMP); @@ -539,7 +559,7 @@ void FontState::issueDrawCommand() { mRSC->setFragmentStore(mFontProgramStore.get()); if(mFontColorDirty) { - mFontShaderF->setConstantColor(mFontColor[0], mFontColor[1], mFontColor[2], mFontColor[3]); + mFontShaderFConstant->data(mRSC, &mFontColor, 4*sizeof(float)); mFontColorDirty = false; } diff --git a/libs/rs/rsFont.h b/libs/rs/rsFont.h index defe38b9a781..027ed1d98e83 100644 --- a/libs/rs/rsFont.h +++ b/libs/rs/rsFont.h @@ -171,6 +171,7 @@ protected: Vector<Font*> mActiveFonts; // Render state for the font + ObjectBaseRef<Allocation> mFontShaderFConstant; ObjectBaseRef<ProgramFragment> mFontShaderF; ObjectBaseRef<Sampler> mFontSampler; ObjectBaseRef<ProgramStore> mFontProgramStore; diff --git a/libs/rs/rsProgram.cpp b/libs/rs/rsProgram.cpp index 6041db80b279..24414912fbc8 100644 --- a/libs/rs/rsProgram.cpp +++ b/libs/rs/rsProgram.cpp @@ -46,6 +46,7 @@ Program::Program(Context *rsc) : ObjectBase(rsc) mOutputCount = 0; mConstantCount = 0; mIsValid = false; + mIsInternal = false; } Program::Program(Context *rsc, const char * shaderText, uint32_t shaderLength, @@ -97,6 +98,14 @@ Program::Program(Context *rsc, const char * shaderText, uint32_t shaderLength, mConstantTypes[constant++].set(reinterpret_cast<Type *>(params[ct+1])); } } + mIsInternal = false; + uint32_t internalTokenLen = strlen(RS_SHADER_INTERNAL); + if(shaderLength > internalTokenLen && + strncmp(RS_SHADER_INTERNAL, shaderText, internalTokenLen) == 0) { + mIsInternal = true; + shaderText += internalTokenLen; + shaderLength -= internalTokenLen; + } mUserShader.setTo(shaderText, shaderLength); } @@ -281,9 +290,9 @@ void Program::appendUserConstants() { } void Program::setupUserConstants(ShaderCache *sc, bool isFragment) { - uint32_t uidx = 1; + uint32_t uidx = 0; for (uint32_t ct=0; ct < mConstantCount; ct++) { - Allocation *alloc = mConstants[ct+1].get(); + Allocation *alloc = mConstants[ct].get(); if (!alloc) { continue; } @@ -313,6 +322,9 @@ void Program::setupUserConstants(ShaderCache *sc, bool isFragment) { if (slot >= 0) { if(f->getType() == RS_TYPE_MATRIX_4X4) { glUniformMatrix4fv(slot, 1, GL_FALSE, fd); + /*for(int i = 0; i < 4; i++) { + LOGE("Mat = %f %f %f %f", fd[i*4 + 0], fd[i*4 + 1], fd[i*4 + 2], fd[i*4 + 3]); + }*/ } else if(f->getType() == RS_TYPE_MATRIX_3X3) { glUniformMatrix3fv(slot, 1, GL_FALSE, fd); diff --git a/libs/rs/rsProgram.h b/libs/rs/rsProgram.h index ddc5e8a4d0fb..e7329c250d5e 100644 --- a/libs/rs/rsProgram.h +++ b/libs/rs/rsProgram.h @@ -23,10 +23,10 @@ // --------------------------------------------------------------------------- namespace android { namespace renderscript { - - class ShaderCache; +#define RS_SHADER_INTERNAL "//rs_shader_internal\n" + class Program : public ObjectBase { public: @@ -42,7 +42,7 @@ public: void bindAllocation(Allocation *, uint32_t slot); virtual void createShader(); - bool isUserProgram() const {return mUserShader.size() > 0;} + bool isUserProgram() const {return !mIsInternal;} void bindTexture(uint32_t slot, Allocation *); void bindSampler(uint32_t slot, Sampler *); @@ -71,6 +71,7 @@ protected: uint32_t mOutputCount; uint32_t mConstantCount; bool mIsValid; + bool mIsInternal; // Applies to vertex and fragment shaders only void appendUserConstants(); diff --git a/libs/rs/rsProgramFragment.cpp b/libs/rs/rsProgramFragment.cpp index 83321d3c4601..3174e82df86d 100644 --- a/libs/rs/rsProgramFragment.cpp +++ b/libs/rs/rsProgramFragment.cpp @@ -92,10 +92,14 @@ ProgramFragment::~ProgramFragment() void ProgramFragment::setConstantColor(float r, float g, float b, float a) { + if(isUserProgram()) { + return; + } mConstantColor[0] = r; mConstantColor[1] = g; mConstantColor[2] = b; mConstantColor[3] = a; + memcpy(mConstants[0]->getPtr(), mConstantColor, 4*sizeof(float)); mDirty = true; } @@ -114,13 +118,6 @@ void ProgramFragment::setupGL2(const Context *rsc, ProgramFragmentState *state, 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"); - } - rsc->checkError("ProgramFragment::setupGL2 begin uniforms"); setupUserConstants(sc, true); @@ -158,124 +155,32 @@ void ProgramFragment::loadShader(Context *rsc) { void ProgramFragment::createShader() { - mShader.setTo("precision mediump float;\n"); - mShader.append("varying lowp vec4 varColor;\n"); - mShader.append("varying vec4 varTex0;\n"); - mShader.append("uniform vec4 uni_Color;\n"); - if (mUserShader.length() > 1) { + mShader.append("precision mediump float;\n"); appendUserConstants(); for (uint32_t ct=0; ct < mTextureCount; ct++) { char buf[256]; - sprintf(buf, "uniform sampler2D uni_Tex%i;\n", ct); + sprintf(buf, "uniform sampler2D 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"); - if (mVaryingColor) { - mShader.append(" lowp vec4 col = varColor;\n"); - } else { - mShader.append(" lowp vec4 col = uni_Color;\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; - } - - } - mask >>= 1; - texNum++; - } - - //mShader.append(" col.a = 1.0;\n"); - //mShader.append(" col.r = 0.5;\n"); - - mShader.append(" gl_FragColor = col;\n"); - mShader.append("}\n"); + LOGE("ProgramFragment::createShader cannot create program, shader code not defined"); + rsAssert(0); } } void ProgramFragment::init(Context *rsc) { mUniformCount = 0; - //if (!mVaryingColor) { - mConstantColorUniformIndex = mUniformCount; - mUniformNames[mUniformCount++].setTo("uni_Color"); - //} - if (mUserShader.size() > 0) { for (uint32_t ct=0; ct < mConstantCount; ct++) { initAddUserElement(mConstantTypes[ct]->getElement(), mUniformNames, &mUniformCount, "UNI_"); } } mTextureUniformIndexStart = mUniformCount; - mUniformNames[mUniformCount++].setTo("uni_Tex0"); - mUniformNames[mUniformCount++].setTo("uni_Tex1"); + mUniformNames[mUniformCount++].setTo("UNI_Tex0"); + mUniformNames[mUniformCount++].setTo("UNI_Tex1"); createShader(); } @@ -303,12 +208,36 @@ ProgramFragmentState::~ProgramFragmentState() void ProgramFragmentState::init(Context *rsc) { - uint32_t tmp[] = { - RS_TEX_ENV_MODE_NONE, 0, - RS_TEX_ENV_MODE_NONE, 0, - 0, 0 - }; - ProgramFragment *pf = new ProgramFragment(rsc, tmp, 6); + String8 shaderString(RS_SHADER_INTERNAL); + shaderString.append("varying lowp vec4 varColor;\n"); + shaderString.append("varying vec4 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 = new Type(rsc); + inputType->setElement(constInput); + inputType->setDimX(1); + inputType->compute(); + + uint32_t tmp[4]; + tmp[0] = RS_PROGRAM_PARAM_CONSTANT; + tmp[1] = (uint32_t)inputType; + tmp[2] = RS_PROGRAM_PARAM_TEXTURE_COUNT; + tmp[3] = 0; + + Allocation *constAlloc = new Allocation(rsc, inputType); + ProgramFragment *pf = new ProgramFragment(rsc, shaderString.string(), + shaderString.length(), tmp, 4); + pf->bindAllocation(constAlloc, 0); + pf->setConstantColor(1.0f, 1.0f, 1.0f, 1.0f); + mDefault.set(pf); } diff --git a/libs/rs/rsProgramVertex.cpp b/libs/rs/rsProgramVertex.cpp index 68e370597edc..28084d7fbccb 100644 --- a/libs/rs/rsProgramVertex.cpp +++ b/libs/rs/rsProgramVertex.cpp @@ -79,15 +79,7 @@ void ProgramVertex::loadShader(Context *rsc) { void ProgramVertex::createShader() { - mShader.setTo(""); - - mShader.append("varying vec4 varColor;\n"); - mShader.append("varying vec4 varTex0;\n"); - if (mUserShader.length() > 1) { - mShader.append("uniform mat4 "); - mShader.append(mUniformNames[0]); - mShader.append(";\n"); appendUserConstants(); @@ -118,28 +110,8 @@ void ProgramVertex::createShader() } mShader.append(mUserShader); } else { - mShader.append("attribute vec4 ATTRIB_position;\n"); - mShader.append("attribute vec4 ATTRIB_color;\n"); - mShader.append("attribute vec3 ATTRIB_normal;\n"); - mShader.append("attribute vec4 ATTRIB_texture0;\n"); - - for (uint32_t ct=0; ct < mUniformCount; ct++) { - mShader.append("uniform mat4 "); - mShader.append(mUniformNames[ct]); - mShader.append(";\n"); - } - - mShader.append("void main() {\n"); - mShader.append(" gl_Position = UNI_MVP * ATTRIB_position;\n"); - mShader.append(" gl_PointSize = 1.0;\n"); - - mShader.append(" varColor = ATTRIB_color;\n"); - if (mTextureMatrixEnable) { - mShader.append(" varTex0 = UNI_TexMatrix * ATTRIB_texture0;\n"); - } else { - mShader.append(" varTex0 = ATTRIB_texture0;\n"); - } - mShader.append("}\n"); + LOGE("ProgramFragment::createShader cannot create program, shader code not defined"); + rsAssert(0); } } @@ -152,18 +124,16 @@ void ProgramVertex::setupGL2(const Context *rsc, ProgramVertexState *state, Shad rsc->checkError("ProgramVertex::setupGL2 start"); - const float *f = static_cast<const float *>(mConstants[0]->getPtr()); - - Matrix mvp; - mvp.load(&f[RS_PROGRAM_VERTEX_PROJECTION_OFFSET]); - Matrix t; - t.load(&f[RS_PROGRAM_VERTEX_MODELVIEW_OFFSET]); - mvp.multiply(&t); - - glUniformMatrix4fv(sc->vtxUniformSlot(0), 1, GL_FALSE, mvp.m); - if (mTextureMatrixEnable) { - glUniformMatrix4fv(sc->vtxUniformSlot(1), 1, GL_FALSE, - &f[RS_PROGRAM_VERTEX_TEXTURE_OFFSET]); + if(!isUserProgram()) { + float *f = static_cast<float *>(mConstants[0]->getPtr()); + Matrix mvp; + mvp.load(&f[RS_PROGRAM_VERTEX_PROJECTION_OFFSET]); + Matrix t; + t.load(&f[RS_PROGRAM_VERTEX_MODELVIEW_OFFSET]); + mvp.multiply(&t); + for(uint32_t i = 0; i < 16; i ++) { + f[RS_PROGRAM_VERTEX_MVP_OFFSET + i] = mvp.m[i]; + } } rsc->checkError("ProgramVertex::setupGL2 begin uniforms"); @@ -183,6 +153,9 @@ void ProgramVertex::addLight(const Light *l) void ProgramVertex::setProjectionMatrix(const rsc_Matrix *m) const { + if(isUserProgram()) { + return; + } float *f = static_cast<float *>(mConstants[0]->getPtr()); memcpy(&f[RS_PROGRAM_VERTEX_PROJECTION_OFFSET], m, sizeof(rsc_Matrix)); mDirty = true; @@ -190,6 +163,9 @@ void ProgramVertex::setProjectionMatrix(const rsc_Matrix *m) const void ProgramVertex::setModelviewMatrix(const rsc_Matrix *m) const { + if(isUserProgram()) { + return; + } float *f = static_cast<float *>(mConstants[0]->getPtr()); memcpy(&f[RS_PROGRAM_VERTEX_MODELVIEW_OFFSET], m, sizeof(rsc_Matrix)); mDirty = true; @@ -197,6 +173,9 @@ void ProgramVertex::setModelviewMatrix(const rsc_Matrix *m) const void ProgramVertex::setTextureMatrix(const rsc_Matrix *m) const { + if(isUserProgram()) { + return; + } float *f = static_cast<float *>(mConstants[0]->getPtr()); memcpy(&f[RS_PROGRAM_VERTEX_TEXTURE_OFFSET], m, sizeof(rsc_Matrix)); mDirty = true; @@ -204,12 +183,18 @@ void ProgramVertex::setTextureMatrix(const rsc_Matrix *m) const void ProgramVertex::getProjectionMatrix(rsc_Matrix *m) const { + if(isUserProgram()) { + return; + } float *f = static_cast<float *>(mConstants[0]->getPtr()); memcpy(m, &f[RS_PROGRAM_VERTEX_PROJECTION_OFFSET], sizeof(rsc_Matrix)); } void ProgramVertex::transformToScreen(const Context *rsc, float *v4out, const float *v3in) const { + if(isUserProgram()) { + return; + } float *f = static_cast<float *>(mConstants[0]->getPtr()); Matrix mvp; mvp.loadMultiply((Matrix *)&f[RS_PROGRAM_VERTEX_MODELVIEW_OFFSET], @@ -225,17 +210,11 @@ void ProgramVertex::init(Context *rsc) initAddUserElement(mInputElements[ct].get(), mAttribNames, &mAttribCount, "ATTRIB_"); } - mUniformCount = 1; - mUniformNames[0].setTo("UNI_MVP"); + mUniformCount = 0; for (uint32_t ct=0; ct < mConstantCount; ct++) { initAddUserElement(mConstantTypes[ct]->getElement(), mUniformNames, &mUniformCount, "UNI_"); } - } else { - mUniformCount = 2; - mUniformNames[0].setTo("UNI_MVP"); - mUniformNames[1].setTo("UNI_TexMatrix"); } - createShader(); } @@ -262,41 +241,78 @@ ProgramVertexState::~ProgramVertexState() void ProgramVertexState::init(Context *rsc) { -#ifndef ANDROID_RS_BUILD_FOR_HOST - RsElement e = (RsElement) Element::create(rsc, RS_TYPE_FLOAT_32, RS_KIND_USER, false, 1); - - rsi_TypeBegin(rsc, e); - rsi_TypeAdd(rsc, RS_DIMENSION_X, 48); - mAllocType.set((Type *)rsi_TypeCreate(rsc)); - - ProgramVertex *pv = new ProgramVertex(rsc, false); - Allocation *alloc = (Allocation *)rsi_AllocationCreateTyped(rsc, mAllocType.get()); + const Element *matrixElem = Element::create(rsc, RS_TYPE_MATRIX_4X4, RS_KIND_USER, false, 1); + const Element *f3Elem = Element::create(rsc, RS_TYPE_FLOAT_32, RS_KIND_USER, false, 3); + const Element *f4Elem = Element::create(rsc, RS_TYPE_FLOAT_32, RS_KIND_USER, false, 4); + + rsc->mStateElement.elementBuilderBegin(); + rsc->mStateElement.elementBuilderAdd(matrixElem, "MV", 1); + rsc->mStateElement.elementBuilderAdd(matrixElem, "P", 1); + rsc->mStateElement.elementBuilderAdd(matrixElem, "TexMatrix", 1); + rsc->mStateElement.elementBuilderAdd(matrixElem, "MVP", 1); + const Element *constInput = rsc->mStateElement.elementBuilderCreate(rsc); + + rsc->mStateElement.elementBuilderBegin(); + rsc->mStateElement.elementBuilderAdd(f4Elem, "position", 1); + rsc->mStateElement.elementBuilderAdd(f4Elem, "color", 1); + rsc->mStateElement.elementBuilderAdd(f3Elem, "normal", 1); + rsc->mStateElement.elementBuilderAdd(f4Elem, "texture0", 1); + const Element *attrElem = rsc->mStateElement.elementBuilderCreate(rsc); + + Type *inputType = new Type(rsc); + inputType->setElement(constInput); + inputType->setDimX(1); + inputType->compute(); + + String8 shaderString(RS_SHADER_INTERNAL); + shaderString.append("varying vec4 varColor;\n"); + shaderString.append("varying vec4 varTex0;\n"); + shaderString.append("void main() {\n"); + shaderString.append(" gl_Position = UNI_MVP * ATTRIB_position;\n"); + shaderString.append(" gl_PointSize = 1.0;\n"); + shaderString.append(" varColor = ATTRIB_color;\n"); + shaderString.append(" varTex0 = ATTRIB_texture0;\n"); + shaderString.append("}\n"); + + uint32_t tmp[6]; + tmp[0] = RS_PROGRAM_PARAM_CONSTANT; + tmp[1] = (uint32_t)inputType; + tmp[2] = RS_PROGRAM_PARAM_INPUT; + tmp[3] = (uint32_t)attrElem; + tmp[4] = RS_PROGRAM_PARAM_TEXTURE_COUNT; + tmp[5] = 0; + + ProgramVertex *pv = new ProgramVertex(rsc, shaderString.string(), + shaderString.length(), tmp, 6); + Allocation *alloc = new Allocation(rsc, inputType); + pv->bindAllocation(alloc, 0); mDefaultAlloc.set(alloc); mDefault.set(pv); - pv->init(rsc); pv->bindAllocation(alloc, 0); updateSize(rsc); -#endif //ANDROID_RS_BUILD_FOR_HOST } void ProgramVertexState::updateSize(Context *rsc) { + float *f = static_cast<float *>(mDefaultAlloc->getPtr()); + Matrix m; m.loadOrtho(0,rsc->getWidth(), rsc->getHeight(),0, -1,1); - mDefaultAlloc->subData(rsc, RS_PROGRAM_VERTEX_PROJECTION_OFFSET, 16, &m.m[0], 16*4); + memcpy(&f[RS_PROGRAM_VERTEX_PROJECTION_OFFSET], m.m, sizeof(m)); + memcpy(&f[RS_PROGRAM_VERTEX_MVP_OFFSET], m.m, sizeof(m)); m.loadIdentity(); - mDefaultAlloc->subData(rsc, RS_PROGRAM_VERTEX_MODELVIEW_OFFSET, 16, &m.m[0], 16*4); + memcpy(&f[RS_PROGRAM_VERTEX_MODELVIEW_OFFSET], m.m, sizeof(m)); + memcpy(&f[RS_PROGRAM_VERTEX_TEXTURE_OFFSET], m.m, sizeof(m)); } void ProgramVertexState::deinit(Context *rsc) { mDefaultAlloc.clear(); mDefault.clear(); - mAllocType.clear(); mLast.clear(); } diff --git a/libs/rs/rsProgramVertex.h b/libs/rs/rsProgramVertex.h index 59fd31958550..d6b3f5af5e2b 100644 --- a/libs/rs/rsProgramVertex.h +++ b/libs/rs/rsProgramVertex.h @@ -79,8 +79,6 @@ public: ObjectBaseRef<ProgramVertex> mDefault; ObjectBaseRef<ProgramVertex> mLast; ObjectBaseRef<Allocation> mDefaultAlloc; - - ObjectBaseRef<Type> mAllocType; }; |