diff options
author | Fredrik Ehnbom <fehnbom@nvidia.com> | 2010-10-12 09:34:04 -0700 |
---|---|---|
committer | Marco Nelissen <marcone@google.com> | 2010-10-13 09:55:17 -0700 |
commit | 229c496d4a47bd610c97af0578ce6b1e2a982c57 (patch) | |
tree | 28155fdf543f80c64cc728340cfb7651b6c520da | |
parent | ca13e07c26186e2b82721564f63108c286b5216d (diff) | |
download | android_packages_wallpapers_MagicSmoke-229c496d4a47bd610c97af0578ce6b1e2a982c57.tar.gz android_packages_wallpapers_MagicSmoke-229c496d4a47bd610c97af0578ce6b1e2a982c57.tar.bz2 android_packages_wallpapers_MagicSmoke-229c496d4a47bd610c97af0578ce6b1e2a982c57.zip |
Performance optimizations for MagicSmoke
The MagicSmoke wallpaper was modified to be single pass
multi texture rather than blended multipass.
Change-Id: If838a4abd2c3fa73def46c47d1f362c8a2af3363
-rw-r--r-- | res/raw/pf4tex.glslf | 23 | ||||
-rw-r--r-- | res/raw/pf5tex.glslf | 26 | ||||
-rw-r--r-- | res/raw/pv4tex.glslv | 20 | ||||
-rw-r--r-- | res/raw/pv5tex.glslv | 22 | ||||
-rw-r--r-- | src/com/android/magicsmoke/MagicSmokeRS.java | 82 | ||||
-rw-r--r-- | src/com/android/magicsmoke/RenderScriptWallpaper.java | 2 | ||||
-rw-r--r-- | src/com/android/magicsmoke/clouds.rs | 176 |
7 files changed, 261 insertions, 90 deletions
diff --git a/res/raw/pf4tex.glslf b/res/raw/pf4tex.glslf new file mode 100644 index 0000000..32810dc --- /dev/null +++ b/res/raw/pf4tex.glslf @@ -0,0 +1,23 @@ +precision mediump float; + +varying vec2 varTex0; +varying vec2 varTex1; +varying vec2 varTex2; +varying vec2 varTex3; + +void main() { + lowp vec4 tex = texture2D(UNI_Tex0, varTex0); + lowp vec4 col = mix(UNI_clearColor, tex.rgba, tex.a); + + tex = texture2D(UNI_Tex1, varTex1); + col = mix(col, tex.rgba, tex.a); + + tex = texture2D(UNI_Tex2, varTex2); + col = mix(col, tex.rgba, tex.a); + + tex = texture2D(UNI_Tex3, varTex3); + col = mix(col, tex.rgba, tex.a); + + gl_FragColor = col; +} + diff --git a/res/raw/pf5tex.glslf b/res/raw/pf5tex.glslf new file mode 100644 index 0000000..b1da1f6 --- /dev/null +++ b/res/raw/pf5tex.glslf @@ -0,0 +1,26 @@ +precision mediump float; + +varying vec2 varTex0; +varying vec2 varTex1; +varying vec2 varTex2; +varying vec2 varTex3; +varying vec2 varTex4; + +void main() { + lowp vec4 tex = texture2D(UNI_Tex0, varTex0); + lowp vec4 col = mix(UNI_clearColor, tex.rgba, tex.a); + + tex = texture2D(UNI_Tex1, varTex1); + col = mix(col, tex.rgba, tex.a); + + tex = texture2D(UNI_Tex2, varTex2); + col = mix(col, tex.rgba, tex.a); + + tex = texture2D(UNI_Tex3, varTex3); + col = mix(col, tex.rgba, tex.a); + + tex = texture2D(UNI_Tex4, varTex4); + col = mix(col, tex.rgba, tex.a); + gl_FragColor = col; +} + diff --git a/res/raw/pv4tex.glslv b/res/raw/pv4tex.glslv new file mode 100644 index 0000000..9fd1f04 --- /dev/null +++ b/res/raw/pv4tex.glslv @@ -0,0 +1,20 @@ +varying vec2 varTex0; +varying vec2 varTex1; +varying vec2 varTex2; +varying vec2 varTex3; + +vec2 mul(vec4 uni, vec2 attr, float idx) +{ + float invz = 0.35 + idx*0.05; + return vec2( + 0.5 + 0.5 * invz * (uni.z * ( uni.y * attr.x + uni.x * attr.y)) + uni.w, + 0.5 + 0.5 * invz * (uni.z * (-uni.x * attr.x + uni.y * attr.y))); +} + +void main() { + varTex0 = mul(UNI_layer0, ATTRIB_position.xy, 1.0); + varTex1 = mul(UNI_layer1, ATTRIB_position.xy, 2.0); + varTex2 = mul(UNI_layer2, ATTRIB_position.xy, 3.0); + varTex3 = mul(UNI_layer3, ATTRIB_position.xy, 4.0); + gl_Position = ATTRIB_position; +} diff --git a/res/raw/pv5tex.glslv b/res/raw/pv5tex.glslv new file mode 100644 index 0000000..998f209 --- /dev/null +++ b/res/raw/pv5tex.glslv @@ -0,0 +1,22 @@ +varying vec2 varTex0; +varying vec2 varTex1; +varying vec2 varTex2; +varying vec2 varTex3; +varying vec2 varTex4; + +vec2 mul(vec4 uni, vec2 attr, float idx) +{ + float invz = 0.5 + idx*0.05; + return vec2( + 0.5 + 0.5 * invz * (uni.z * ( uni.y * attr.x + uni.x * attr.y)) + uni.w, + 0.5 + 0.5 * invz * (uni.z * (-uni.x * attr.x + uni.y * attr.y))); +} + +void main() { + varTex0 = mul(UNI_layer0, ATTRIB_position.xy, 1.0); + varTex1 = mul(UNI_layer1, ATTRIB_position.xy, 2.0); + varTex2 = mul(UNI_layer2, ATTRIB_position.xy, 3.0); + varTex3 = mul(UNI_layer3, ATTRIB_position.xy, 4.0); + varTex4 = mul(UNI_layer4, ATTRIB_position.xy, 5.0); + gl_Position = ATTRIB_position; +} diff --git a/src/com/android/magicsmoke/MagicSmokeRS.java b/src/com/android/magicsmoke/MagicSmokeRS.java index 6183ec3..076453c 100644 --- a/src/com/android/magicsmoke/MagicSmokeRS.java +++ b/src/com/android/magicsmoke/MagicSmokeRS.java @@ -32,6 +32,7 @@ import android.os.Handler; import android.renderscript.Allocation; import android.renderscript.Dimension; import android.renderscript.Element; +import android.renderscript.Mesh; import android.renderscript.Primitive; import android.renderscript.ProgramFragment; import android.renderscript.ProgramStore; @@ -69,16 +70,20 @@ class MagicSmokeRS extends RenderScriptScene implements OnSharedPreferenceChange //private Type mStateType; //private Allocation mState; - private ProgramStore mPfsBackgroundOne; - private ProgramStore mPfsBackgroundSrc; - private ProgramFragment mPfBackground; - private Sampler mSampler; + private ProgramStore mPStore; + private ProgramFragment mPF5tex; + private ProgramFragment mPF4tex; + private Sampler[] mSampler; private Allocation[] mSourceTextures; private Allocation[] mRealTextures; private ScriptC_clouds mScript; - private ProgramVertex mPVBackground; + private ScriptField_VertexShaderConstants_s mVSConst; + private ScriptField_FragmentShaderConstants_s mFSConst; + + private ProgramVertex mPV5tex; + private ProgramVertex mPV4tex; private ProgramVertex.MatrixAllocation mPVAlloc; private static final int RSID_STATE = 0; @@ -314,14 +319,24 @@ class MagicSmokeRS extends RenderScriptScene implements OnSharedPreferenceChange mScript = new ScriptC_clouds(mRS, mResources, R.raw.clouds, true); - // First set up the coordinate system and such - ProgramVertex.Builder pvb = new ProgramVertex.Builder(mRS, null, null); - mPVBackground = pvb.create(); - mPVAlloc = new ProgramVertex.MatrixAllocation(mRS); - mPVBackground.bindAllocation(mPVAlloc); - mPVAlloc.setupProjectionNormalized(mWidth, mHeight); + mVSConst = new ScriptField_VertexShaderConstants_s(mRS, 1); + mScript.bind_gVSConstants(mVSConst); + + { + ProgramVertex.ShaderBuilder builder = new ProgramVertex.ShaderBuilder(mRS); + builder.setShader(mResources, R.raw.pv5tex); + builder.addConstant(mVSConst.getAllocation().getType()); + builder.addInput(ScriptField_VertexInputs_s.createElement(mRS)); + + mPV5tex = builder.create(); + mPV5tex.bindConstants(mVSConst.getAllocation(), 0); - mScript.set_gPVBackground(mPVBackground); + builder.setShader(mResources, R.raw.pv4tex); + mPV4tex = builder.create(); + mPV4tex.bindConstants(mVSConst.getAllocation(), 0); + } + mScript.set_gPV5tex(mPV5tex); + mScript.set_gPV4tex(mPV4tex); mSourceTextures = new Allocation[5]; mRealTextures = new Allocation[5]; @@ -337,31 +352,46 @@ class MagicSmokeRS extends RenderScriptScene implements OnSharedPreferenceChange samplerBuilder.setMag(LINEAR); samplerBuilder.setWrapS(WRAP); samplerBuilder.setWrapT(WRAP); - mSampler = samplerBuilder.create(); + mSampler = new Sampler[5]; + for (int i = 0; i < 5; i++) + mSampler[i] = samplerBuilder.create(); { - ProgramFragment.Builder builder = new ProgramFragment.Builder(mRS); - builder.setTexture(ProgramFragment.Builder.EnvMode.REPLACE, - ProgramFragment.Builder.Format.RGBA, 0); - mPfBackground = builder.create(); - mPfBackground.bindSampler(mSampler, 0); + mFSConst = new ScriptField_FragmentShaderConstants_s(mRS, 1); + mScript.bind_gFSConstants(mFSConst); + + ProgramFragment.ShaderBuilder builder = new ProgramFragment.ShaderBuilder(mRS); + builder.setShader(mResources, R.raw.pf5tex); + builder.setTextureCount(5); + builder.addConstant(mFSConst.getAllocation().getType()); + + mPF5tex = builder.create(); + for (int i = 0; i < 5; i++) + mPF5tex.bindSampler(mSampler[i], i); + mPF5tex.bindConstants(mFSConst.getAllocation(), 0); + + builder.setShader(mResources, R.raw.pf4tex); + builder.setTextureCount(4); + mPF4tex = builder.create(); + for (int i = 0; i < 4; i++) + mPF4tex.bindSampler(mSampler[i], i); + mPF4tex.bindConstants(mFSConst.getAllocation(), 0); } - mScript.set_gPFBackground(mPfBackground); + mScript.set_gPF5tex(mPF5tex); + mScript.set_gPF4tex(mPF4tex); + { ProgramStore.Builder builder = new ProgramStore.Builder(mRS, null, null); - builder.setDepthFunc(ProgramStore.DepthFunc.EQUAL); - builder.setBlendFunc(BlendSrcFunc.ONE, BlendDstFunc.ONE_MINUS_SRC_ALPHA); + builder.setDepthFunc(ProgramStore.DepthFunc.ALWAYS); + builder.setBlendFunc(BlendSrcFunc.ONE, BlendDstFunc.ZERO); builder.setDitherEnable(true); // without dithering there is severe banding builder.setDepthMask(false); - mPfsBackgroundOne = builder.create(); - builder.setBlendFunc(BlendSrcFunc.SRC_ALPHA, BlendDstFunc.ONE_MINUS_SRC_ALPHA); - mPfsBackgroundSrc = builder.create(); + mPStore = builder.create(); } - mScript.set_gPFSBackgroundOne(mPfsBackgroundOne); - mScript.set_gPFSBackgroundSrc(mPfsBackgroundSrc); + mScript.set_gPStore(mPStore); mScript.set_gPreset(mWorldState.mPreset); mScript.set_gTextureMask(mWorldState.mTextureMask); diff --git a/src/com/android/magicsmoke/RenderScriptWallpaper.java b/src/com/android/magicsmoke/RenderScriptWallpaper.java index 676ac1b..0a6136a 100644 --- a/src/com/android/magicsmoke/RenderScriptWallpaper.java +++ b/src/com/android/magicsmoke/RenderScriptWallpaper.java @@ -43,7 +43,7 @@ public abstract class RenderScriptWallpaper<T extends RenderScriptScene> extends super.onCreate(surfaceHolder); setTouchEventsEnabled(false); surfaceHolder.setSizeFromLayout(); - surfaceHolder.setFormat(PixelFormat.RGBX_8888); + surfaceHolder.setFormat(PixelFormat.RGB_565); } @Override diff --git a/src/com/android/magicsmoke/clouds.rs b/src/com/android/magicsmoke/clouds.rs index 9cd28cc..5e67950 100644 --- a/src/com/android/magicsmoke/clouds.rs +++ b/src/com/android/magicsmoke/clouds.rs @@ -44,10 +44,33 @@ float gAlphaMul; int gPreMul; int gBlendFunc; -rs_program_vertex gPVBackground; -rs_program_fragment gPFBackground; -rs_program_store gPFSBackgroundOne; -rs_program_store gPFSBackgroundSrc; +typedef struct VertexShaderConstants_s { + float4 layer0; + float4 layer1; + float4 layer2; + float4 layer3; + float4 layer4; +} VertexShaderConstants; +VertexShaderConstants *gVSConstants; + +typedef struct FragmentShaderConstants_s { + float4 clearColor; +} FragmentShaderConstants; +FragmentShaderConstants *gFSConstants; + +typedef struct VertexInputs_s { + float4 position; + float2 texture0; +} VertexInputs; +VertexInputs *gVS; + + +rs_program_fragment gPF5tex; +rs_program_vertex gPV5tex; +rs_program_fragment gPF4tex; +rs_program_vertex gPV4tex; + +rs_program_store gPStore; rs_allocation gTnoise1; rs_allocation gTnoise2; @@ -78,33 +101,81 @@ static int currentpreset; static int lastuptime; static float timedelta; static float4 clearColor = {0.5f, 0.0f, 0.0f, 1.0f}; - -void drawCloud(rs_matrix4x4 *ident, rs_allocation allocat, int idx) { - rs_matrix4x4 mat1; - float z = -8.f * idx; - rsMatrixLoad(&mat1, ident); - rsMatrixTranslate(&mat1, -gXOffset * 8.f * idx, -gTilt * idx / 3.f, 0.f); - rsMatrixRotate(&mat1, rotation[idx], 0.f, 0.f, 1.f); - rsgProgramVertexLoadModelMatrix(&mat1); - - rsgBindTexture(gPFBackground, 0, allocat); - rsgDrawQuadTexCoords( - -1200.0f, -1200.0f, z, // space - 0.f + xshift[idx], 0.f, // texture - 1200, -1200.0f, z, // space - scale[idx] + xshift[idx], 0.f, // texture - 1200, 1200.0f, z, // space - scale[idx] + xshift[idx], scale[idx], // texture - -1200.0f, 1200.0f, z, // space - 0.f + xshift[idx], scale[idx]); // texture +int countTextures() +{ + int pos = 0; + for (int i = 0; i < 5; i++) + { + if (gTextureMask & (1<<i)) + pos++; + } + return pos; +} +#define rotate(s, a) \ +do { \ + float __agl = (3.1415927f / 180.0f) * a; \ + s.x = sin(__agl); \ + s.y = cos(__agl); \ +} while (0) + +void update() +{ + rs_program_vertex pv = gPV5tex; + rs_program_fragment pf = gPF5tex; + + if (countTextures() == 4) + { + pv = gPV4tex; + pf = gPF4tex; + } + rsgBindProgramFragment(pf); + rsgBindProgramVertex(pv); + rsgBindProgramStore(gPStore); + + rotate(gVSConstants->layer0, rotation[0]); + rotate(gVSConstants->layer1, rotation[1]); + rotate(gVSConstants->layer2, rotation[2]); + rotate(gVSConstants->layer3, rotation[3]); + rotate(gVSConstants->layer4, rotation[4]); + + gVSConstants->layer0.w = -gXOffset * 0 + xshift[0]; + gVSConstants->layer1.w = -gXOffset * 8 + xshift[1]; + gVSConstants->layer2.w = -gXOffset * 16 + xshift[2]; + gVSConstants->layer3.w = -gXOffset * 24 + xshift[3]; + gVSConstants->layer4.w = -gXOffset * 32 + xshift[4]; + + float m = 0.35f; + gVSConstants->layer0.z = m * scale[0]; + gVSConstants->layer1.z = m * scale[1]; + gVSConstants->layer2.z = m * scale[2]; + gVSConstants->layer3.z = m * scale[3]; + gVSConstants->layer4.z = m * scale[4]; + + gFSConstants->clearColor = clearColor; + + int pos = 0; + for (int i = 0; i < 5; i++) + { + if (gTextureMask & (1<<i)) + { + switch (i) + { + case 0: rsgBindTexture(pf, pos, gTextureSwap != 0 ? gTnoise5 : gTnoise1); break; + case 1: rsgBindTexture(pf, pos, gTnoise2); break; + case 2: rsgBindTexture(pf, pos, gTnoise3); break; + case 3: rsgBindTexture(pf, pos, gTnoise4); break; + case 4: rsgBindTexture(pf, pos, gTnoise5); break; + default: break; + } + pos++; + } + } } -void drawClouds(rs_matrix4x4 *ident) { - rs_matrix4x4 mat1; - rsMatrixLoad(&mat1, ident); - - if (gRotate != 0) { - rotation[0] += 0.10 * timedelta; +void drawClouds() { + if (gRotate != 0) + { + rotation[0] += 0.100f * timedelta; rotation[1] += 0.102f * timedelta; rotation[2] += 0.106f * timedelta; rotation[3] += 0.114f * timedelta; @@ -113,34 +184,31 @@ void drawClouds(rs_matrix4x4 *ident) { int mask = gTextureMask; if (mask & 1) { - xshift[0] += 0.0010f * timedelta; - if (gTextureSwap != 0) { - drawCloud(&mat1, gTnoise5, 0); - } else { - drawCloud(&mat1, gTnoise1, 0); - } + xshift[0] += 0.00100f * timedelta; } - if (mask & 2) { - xshift[1] += 0.00106 * timedelta; - drawCloud(&mat1, gTnoise2, 1); + xshift[1] += 0.00106f * timedelta; } - if (mask & 4) { xshift[2] += 0.00114f * timedelta; - drawCloud(&mat1, gTnoise3, 2); } - if (mask & 8) { xshift[3] += 0.00118f * timedelta; - drawCloud(&mat1, gTnoise4, 3); } - if (mask & 16) { xshift[4] += 0.00127f * timedelta; - drawCloud(&mat1, gTnoise5, 4); } + update(); + + float z = 0; + rsgDrawQuad( + -1.0f, -1.0f, z, + 1.0f, -1.0f, z, + 1.0f, 1.0f, z, + -1.0f, 1.0f, z + ); + // Make sure the texture coordinates don't continuously increase int i; for(i = 0; i < 5; i++) { @@ -303,23 +371,6 @@ void init() { int root(int launchID) { int i; - rs_matrix4x4 ident; - float masterscale = 0.0041f;// / (gXOffset * 4.f + 1.f); - - rsgBindProgramVertex(gPVBackground); - rsgBindProgramFragment(gPFBackground); - - rsMatrixLoadIdentity(&ident); - rsMatrixTranslate(&ident, -gXOffset, 0.f, 0.f); - rsMatrixScale(&ident, masterscale, masterscale, masterscale); - //rsMatrixRotate(&ident, 0.f, 0.f, 0.f, 1.f); - rsMatrixRotate(&ident, -gTilt, 1.f, 0.f, 0.f); - - if (gBlendFunc) { - rsgBindProgramStore(gPFSBackgroundOne); - } else { - rsgBindProgramStore(gPFSBackgroundSrc); - } int now = (int)rsUptimeMillis(); timedelta = ((float)(now - lastuptime)) / 44.f; @@ -338,14 +389,13 @@ int root(int launchID) { clearColor.z = ((float)(gBackCol & 0xff)) / 255.0f; makeTextures(); } - rsgClearColor(clearColor.x, clearColor.y, clearColor.z, clearColor.w); if (gTextureSwap != 0) { scale[0] = .25f; } else { scale[0] = 4.f; } - drawClouds(&ident); + drawClouds(); return 55; } |