Refactor RenderScript wallpapers to share more code between the implementations.
Change-Id: I5995f68438531396cfae80c27e5d7781effaaa31
diff --git a/res/raw/grass.rs b/res/raw/grass.rs
index b3846c2..696ef75 100644
--- a/res/raw/grass.rs
+++ b/res/raw/grass.rs
@@ -53,11 +53,12 @@
#define REAL_TIME 0
-float time(int frameCount) {
+float time() {
if (REAL_TIME) {
return (hour() * 3600.0f + minute() * 60.0f + second()) / SECONDS_IN_DAY;
}
- return (frameCount % 180) / 180.0f;
+ float t = uptimeMillis() / 20000.0f;
+ return t - (int) t;
}
void alpha(float a) {
@@ -92,14 +93,14 @@
drawRect(0.0f, 0.0f, width, height, 0.0f);
}
-int drawBlade(float *bladeStruct, float *bladeBuffer, int *bladeColor, float now, int frameCount) {
+int drawBlade(float *bladeStruct, float *bladeBuffer, int *bladeColor, float now, float xOffset) {
float offset = bladeStruct[BLADE_STRUCT_OFFSET];
float scale = bladeStruct[BLADE_STRUCT_SCALE];
float angle = bladeStruct[BLADE_STRUCT_ANGLE];
float hardness = bladeStruct[BLADE_STRUCT_HARDNESS];
float turbulenceX = bladeStruct[BLADE_STRUCT_TURBULENCEX];
- float xpos = bladeStruct[BLADE_STRUCT_XPOS];
+ float xpos = bladeStruct[BLADE_STRUCT_XPOS] + xOffset;
float ypos = bladeStruct[BLADE_STRUCT_YPOS];
float lengthX = bladeStruct[BLADE_STRUCT_LENGTHX];
@@ -126,7 +127,7 @@
int color = hsbToAbgr(h, s, lerpf(0, b, newB), 1.0f);
- float newAngle = turbulencef2(turbulenceX, frameCount * 0.006f, 4.0f) - 0.5f;
+ float newAngle = turbulencef2(turbulenceX, uptimeMillis() * 0.00004f, 4.0f) - 0.5f;
newAngle *= 0.5f;
angle = clampf(angle + (newAngle + offset - angle) * 0.15f, -MAX_BEND, MAX_BEND);
@@ -202,7 +203,7 @@
return triangles * 15;
}
-void drawBlades(float now, int frameCount) {
+void drawBlades(float now, float xOffset) {
// For anti-aliasing
bindTexture(NAMED_PFBackground, 0, NAMED_TAa);
@@ -215,7 +216,7 @@
int *bladeColor = loadArrayI32(RSID_BLADES_BUFFER, 0);
for ( ; i < bladesCount; i += 1) {
- int offset = drawBlade(bladeStruct, bladeBuffer, bladeColor, now, frameCount);
+ int offset = drawBlade(bladeStruct, bladeBuffer, bladeColor, now, xOffset);
bladeBuffer += offset;
bladeColor += offset;
bladeStruct += BLADE_STRUCT_FIELDS_COUNT;
@@ -229,8 +230,9 @@
int width = State_width;
int height = State_height;
- int frameCount = State_frameCount;
- float now = time(frameCount);
+ float x = lerpf(width, 0, State_xOffset);
+
+ float now = time();
alpha(1.0f);
if (now >= MIDNIGHT && now < MORNING) {
@@ -251,10 +253,7 @@
drawSunset(width, height);
}
- drawBlades(now, frameCount);
-
- frameCount++;
- storeI32(RSID_STATE, OFFSETOF_WorldState_frameCount, frameCount);
+ drawBlades(now, x);
return 1;
}
diff --git a/src/com/android/wallpaper/RenderScriptScene.java b/src/com/android/wallpaper/RenderScriptScene.java
new file mode 100644
index 0000000..01c551c
--- /dev/null
+++ b/src/com/android/wallpaper/RenderScriptScene.java
@@ -0,0 +1,80 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+package com.android.wallpaper;
+
+import android.content.res.Resources;
+import android.renderscript.RenderScript;
+import android.renderscript.ScriptC;
+
+public abstract class RenderScriptScene {
+ protected int mWidth;
+ protected int mHeight;
+ protected Resources mResources;
+ protected RenderScript mRS;
+ protected ScriptC mScript;
+
+ public RenderScriptScene(int width, int height) {
+ mWidth = width;
+ mHeight = height;
+ }
+
+ public void init(RenderScript rs, Resources res) {
+ mRS = rs;
+ mResources = res;
+ mScript = createScript();
+ }
+
+ public int getWidth() {
+ return mWidth;
+ }
+
+ public int getHeight() {
+ return mHeight;
+ }
+
+ public Resources getResources() {
+ return mResources;
+ }
+
+ public RenderScript getRS() {
+ return mRS;
+ }
+
+ public ScriptC getScript() {
+ return mScript;
+ }
+
+ protected abstract ScriptC createScript();
+
+ public void stop() {
+ mRS.contextBindRootScript(null);
+ }
+
+ public void start() {
+ mRS.contextBindRootScript(mScript);
+ }
+
+ public void resize(int width, int height) {
+ mWidth = width;
+ mHeight = height;
+ }
+
+ @SuppressWarnings({"UnusedDeclaration"})
+ public void setOffset(float xOffset, float yOffset, int xPixels, int yPixels) {
+ }
+}
diff --git a/src/com/android/wallpaper/RenderScriptWallpaper.java b/src/com/android/wallpaper/RenderScriptWallpaper.java
new file mode 100644
index 0000000..f40bf41
--- /dev/null
+++ b/src/com/android/wallpaper/RenderScriptWallpaper.java
@@ -0,0 +1,104 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+package com.android.wallpaper;
+
+import android.service.wallpaper.WallpaperService;
+import android.renderscript.RenderScript;
+import android.view.SurfaceHolder;
+import android.view.Surface;
+
+public abstract class RenderScriptWallpaper<T extends RenderScriptScene> extends WallpaperService {
+ public Engine onCreateEngine() {
+ return new RenderScriptEngine();
+ }
+
+ protected abstract T createScene(int width, int height);
+
+ private class RenderScriptEngine extends Engine {
+ private RenderScript mRs;
+ private T mRenderer;
+
+ @Override
+ public void onCreate(SurfaceHolder surfaceHolder) {
+ super.onCreate(surfaceHolder);
+ setTouchEventsEnabled(false);
+ surfaceHolder.setSizeFromLayout();
+ }
+
+ @Override
+ public void onDestroy() {
+ super.onDestroy();
+ destroyRenderer();
+ }
+
+ private void destroyRenderer() {
+ if (mRenderer != null) {
+ mRenderer.stop();
+ mRenderer = null;
+ }
+ if (mRs != null) {
+ mRs.destroy();
+ mRs = null;
+ }
+ }
+
+ @Override
+ public void onVisibilityChanged(boolean visible) {
+ super.onVisibilityChanged(visible);
+ if (visible) {
+ mRenderer.start();
+ } else {
+ mRenderer.stop();
+ }
+ }
+
+ @Override
+ public void onSurfaceChanged(SurfaceHolder holder, int format, int width, int height) {
+ super.onSurfaceChanged(holder, format, width, height);
+ if (mRenderer == null) {
+ mRenderer = createScene(width, height);
+ mRenderer.init(mRs, getResources());
+ mRenderer.start();
+ } else {
+ mRenderer.resize(width, height);
+ }
+ }
+
+ @Override
+ public void onOffsetsChanged(float xOffset, float yOffset, int xPixels, int yPixels) {
+ mRenderer.setOffset(xOffset, yOffset, xPixels, yPixels);
+ }
+
+ @Override
+ public void onSurfaceCreated(SurfaceHolder holder) {
+ super.onSurfaceCreated(holder);
+
+ Surface surface = null;
+ while (surface == null) {
+ surface = holder.getSurface();
+ }
+ mRs = new RenderScript(surface, false);
+ }
+
+ @Override
+ public void onSurfaceDestroyed(SurfaceHolder holder) {
+ super.onSurfaceDestroyed(holder);
+ destroyRenderer();
+ }
+ }
+}
diff --git a/src/com/android/wallpaper/galaxy/GalaxyRS.java b/src/com/android/wallpaper/galaxy/GalaxyRS.java
index 93d9143..145faf5 100644
--- a/src/com/android/wallpaper/galaxy/GalaxyRS.java
+++ b/src/com/android/wallpaper/galaxy/GalaxyRS.java
@@ -16,8 +16,6 @@
package com.android.wallpaper.galaxy;
-import android.content.res.Resources;
-import android.renderscript.RenderScript;
import android.renderscript.ScriptC;
import android.renderscript.ProgramFragment;
import android.renderscript.ProgramStore;
@@ -43,8 +41,9 @@
import java.util.TimeZone;
import com.android.wallpaper.R;
+import com.android.wallpaper.RenderScriptScene;
-class GalaxyRS {
+class GalaxyRS extends RenderScriptScene {
private static final int GALAXY_RADIUS = 300;
private static final int PARTICLES_COUNT = 12000;
private static final float ELLIPSE_TWIST = 0.023333333f;
@@ -67,16 +66,8 @@
private static final int RSID_PARTICLES_BUFFER = 2;
- private Resources mResources;
- private RenderScript mRS;
-
private final BitmapFactory.Options mOptionsARGB = new BitmapFactory.Options();
- private int mWidth;
- private int mHeight;
-
- @SuppressWarnings({"FieldCanBeLocal"})
- private ScriptC mScript;
@SuppressWarnings({"FieldCanBeLocal"})
private ProgramFragment mPfBackground;
@SuppressWarnings({"FieldCanBeLocal"})
@@ -107,28 +98,14 @@
private final float[] mFloatData5 = new float[5];
- public GalaxyRS(int width, int height) {
- mWidth = width;
- mHeight = height;
+ GalaxyRS(int width, int height) {
+ super(width, height);
mOptionsARGB.inScaled = false;
mOptionsARGB.inPreferredConfig = Bitmap.Config.ARGB_8888;
}
- public void init(RenderScript rs, Resources res) {
- mRS = rs;
- mResources = res;
- initRS();
- }
-
- void stop() {
- mRS.contextBindRootScript(null);
- }
-
- void start() {
- mRS.contextBindRootScript(mScript);
- }
-
- private void initRS() {
+ @Override
+ protected ScriptC createScript() {
createProgramVertex();
createProgramFragmentStore();
createProgramFragment();
@@ -140,13 +117,15 @@
sb.setScript(mResources, R.raw.galaxy);
sb.setRoot(true);
- mScript = sb.create();
- mScript.setClearColor(1.0f, 0.0f, 0.0f, 1.0f);
- mScript.setTimeZone(TimeZone.getDefault().getID());
+ ScriptC script = sb.create();
+ script.setClearColor(1.0f, 0.0f, 0.0f, 1.0f);
+ script.setTimeZone(TimeZone.getDefault().getID());
- mScript.bindAllocation(mState, RSID_STATE);
- mScript.bindAllocation(mParticles, RSID_PARTICLES);
- mScript.bindAllocation(mParticlesBuffer, RSID_PARTICLES_BUFFER);
+ script.bindAllocation(mState, RSID_STATE);
+ script.bindAllocation(mParticles, RSID_PARTICLES);
+ script.bindAllocation(mParticlesBuffer, RSID_PARTICLES_BUFFER);
+
+ return script;
}
private void createScriptStructures() {
@@ -173,14 +152,15 @@
mParticlesMesh.bindVertexAllocation(mParticlesBuffer, 0);
}
- void setOffsetX(float xOffset) {
+ @Override
+ public void setOffset(float xOffset, float yOffset, int xPixels, int yPixels) {
mGalaxyState.xOffset = xOffset;
mState.data(mGalaxyState);
}
- void resize(int width, int height) {
- mWidth = width;
- mHeight = height;
+ @Override
+ public void resize(int width, int height) {
+ super.resize(width, height);
mGalaxyState.width = width;
mGalaxyState.height = height;
diff --git a/src/com/android/wallpaper/galaxy/GalaxyWallpaper.java b/src/com/android/wallpaper/galaxy/GalaxyWallpaper.java
index 1dbf09a..1c86eea 100644
--- a/src/com/android/wallpaper/galaxy/GalaxyWallpaper.java
+++ b/src/com/android/wallpaper/galaxy/GalaxyWallpaper.java
@@ -16,85 +16,10 @@
package com.android.wallpaper.galaxy;
-import android.service.wallpaper.WallpaperService;
-import android.view.SurfaceHolder;
-import android.view.Surface;
-import android.renderscript.RenderScript;
+import com.android.wallpaper.RenderScriptWallpaper;
-public class GalaxyWallpaper extends WallpaperService {
- public Engine onCreateEngine() {
- return new RenderScriptEngine();
+public class GalaxyWallpaper extends RenderScriptWallpaper<GalaxyRS> {
+ protected GalaxyRS createScene(int width, int height) {
+ return new GalaxyRS(width, height);
}
-
- private class RenderScriptEngine extends Engine {
- private RenderScript mRs;
- private GalaxyRS mRenderer;
-
- @Override
- public void onCreate(SurfaceHolder surfaceHolder) {
- super.onCreate(surfaceHolder);
- surfaceHolder.setSizeFromLayout();
- }
-
- @Override
- public void onDestroy() {
- super.onDestroy();
- destroyRenderer();
- }
-
- private void destroyRenderer() {
- if (mRenderer != null) {
- mRenderer.stop();
- mRenderer = null;
- }
- if (mRs != null) {
- mRs.destroy();
- mRs = null;
- }
- }
-
- @Override
- public void onVisibilityChanged(boolean visible) {
- super.onVisibilityChanged(visible);
- if (visible) {
- mRenderer.start();
- } else {
- mRenderer.stop();
- }
- }
-
- @Override
- public void onSurfaceChanged(SurfaceHolder holder, int format, int width, int height) {
- super.onSurfaceChanged(holder, format, width, height);
- if (mRenderer == null) {
- mRenderer = new GalaxyRS(width, height);
- mRenderer.init(mRs, getResources());
- mRenderer.start();
- } else {
- mRenderer.resize(width, height);
- }
- }
-
- @Override
- public void onOffsetsChanged(float xOffset, float yOffset, int xPixels, int yPixels) {
- mRenderer.setOffsetX(xOffset);
- }
-
- @Override
- public void onSurfaceCreated(SurfaceHolder holder) {
- super.onSurfaceCreated(holder);
-
- Surface surface = null;
- while (surface == null) {
- surface = holder.getSurface();
- }
- mRs = new RenderScript(surface, false);
- }
-
- @Override
- public void onSurfaceDestroyed(SurfaceHolder holder) {
- super.onSurfaceDestroyed(holder);
- destroyRenderer();
- }
- }
-}
\ No newline at end of file
+}
diff --git a/src/com/android/wallpaper/grass/GrassRS.java b/src/com/android/wallpaper/grass/GrassRS.java
index f16bd31..e249b03 100644
--- a/src/com/android/wallpaper/grass/GrassRS.java
+++ b/src/com/android/wallpaper/grass/GrassRS.java
@@ -16,13 +16,11 @@
package com.android.wallpaper.grass;
-import android.content.res.Resources;
import android.renderscript.Sampler;
import static android.renderscript.ProgramFragment.EnvMode.*;
import static android.renderscript.ProgramStore.DepthFunc.*;
import static android.renderscript.ProgramStore.BlendSrcFunc;
import static android.renderscript.ProgramStore.BlendDstFunc;
-import android.renderscript.RenderScript;
import android.renderscript.ProgramFragment;
import android.renderscript.ProgramStore;
import android.renderscript.Allocation;
@@ -37,10 +35,11 @@
import android.renderscript.Primitive;
import static android.renderscript.Sampler.Value.*;
import com.android.wallpaper.R;
+import com.android.wallpaper.RenderScriptScene;
import java.util.TimeZone;
-class GrassRS {
+class GrassRS extends RenderScriptScene {
private static final float TESSELATION = 0.5f;
private static final int RSID_STATE = 0;
@@ -66,14 +65,6 @@
private static final int RSID_BLADES_BUFFER = 2;
- private Resources mResources;
- private RenderScript mRS;
-
- private int mWidth;
- private int mHeight;
-
- @SuppressWarnings({ "FieldCanBeLocal" })
- private ScriptC mScript;
@SuppressWarnings({ "FieldCanBeLocal" })
private ProgramFragment mPfBackground;
@SuppressWarnings({ "FieldCanBeLocal" })
@@ -100,39 +91,25 @@
private final float[] mFloatData5 = new float[5];
private WorldState mWorldState;
- public GrassRS(int width, int height) {
- mWidth = width;
- mHeight = height;
+ GrassRS(int width, int height) {
+ super(width, height);
}
- public void init(RenderScript rs, Resources res) {
- mRS = rs;
- mResources = res;
- initRS();
- }
-
- void stop() {
- mRS.contextBindRootScript(null);
- }
-
- void start() {
- mRS.contextBindRootScript(mScript);
- }
-
- void resize(int width, int height) {
- mWidth = width;
- mHeight = height;
-
+ @Override
+ public void resize(int width, int height) {
+ super.resize(width, height);
+
mWorldState.width = width;
mWorldState.height = height;
mState.data(mWorldState);
mPvOrthoAlloc.setupOrthoWindow(mWidth, mHeight);
- // TODO: REPOSITION BLADES
+ // TODO: REPOSITION BLADES
}
-
- private void initRS() {
+
+ @Override
+ protected ScriptC createScript() {
createProgramVertex();
createProgramFragmentStore();
createProgramFragment();
@@ -144,13 +121,15 @@
sb.setScript(mResources, R.raw.grass);
sb.setRoot(true);
- mScript = sb.create();
- mScript.setClearColor(0.0f, 0.0f, 0.0f, 1.0f);
- mScript.setTimeZone(TimeZone.getDefault().getID());
+ ScriptC script = sb.create();
+ script.setClearColor(0.0f, 0.0f, 0.0f, 1.0f);
+ script.setTimeZone(TimeZone.getDefault().getID());
- mScript.bindAllocation(mState, RSID_STATE);
- mScript.bindAllocation(mBlades, RSID_BLADES);
- mScript.bindAllocation(mBladesBuffer, RSID_BLADES_BUFFER);
+ script.bindAllocation(mState, RSID_STATE);
+ script.bindAllocation(mBlades, RSID_BLADES);
+ script.bindAllocation(mBladesBuffer, RSID_BLADES_BUFFER);
+
+ return script;
}
private void createScriptStructures() {
@@ -158,12 +137,18 @@
createState();
}
+ @Override
+ public void setOffset(float xOffset, float yOffset, int xPixels, int yPixels) {
+ mWorldState.xOffset = xOffset;
+ mState.data(mWorldState);
+ }
+
static class WorldState {
- public int frameCount;
public int bladesCount;
public int trianglesCount;
public int width;
public int height;
+ public float xOffset;
}
private void createState() {
@@ -251,7 +236,7 @@
private int createBlade(float[] blades, int index) {
final float size = random(4.0f) + 4.0f;
- final int xpos = random(mWidth);
+ final int xpos = random(-mWidth, mWidth);
//noinspection PointlessArithmeticExpression
blades[index + BLADE_STRUCT_ANGLE] = 0.0f;
diff --git a/src/com/android/wallpaper/grass/GrassWallpaper.java b/src/com/android/wallpaper/grass/GrassWallpaper.java
index 3ee83b1..eabc170 100644
--- a/src/com/android/wallpaper/grass/GrassWallpaper.java
+++ b/src/com/android/wallpaper/grass/GrassWallpaper.java
@@ -16,80 +16,12 @@
package com.android.wallpaper.grass;
-import android.service.wallpaper.WallpaperService;
-import android.view.SurfaceHolder;
-import android.view.Surface;
-import android.renderscript.RenderScript;
+import com.android.wallpaper.RenderScriptWallpaper;
+import com.android.wallpaper.RenderScriptScene;
-public class GrassWallpaper extends WallpaperService {
- public Engine onCreateEngine() {
- return new RenderScriptEngine();
- }
-
- private class RenderScriptEngine extends Engine {
- private RenderScript mRs;
- private GrassRS mRenderer;
-
- @Override
- public void onCreate(SurfaceHolder surfaceHolder) {
- super.onCreate(surfaceHolder);
- }
-
- @Override
- public void onDestroy() {
- super.onDestroy();
- destroyRenderer();
- }
-
- private void destroyRenderer() {
- if (mRenderer != null) {
- mRenderer.stop();
- mRenderer = null;
- }
- if (mRs != null) {
- mRs.destroy();
- mRs = null;
- }
- }
-
- @Override
- public void onVisibilityChanged(boolean visible) {
- super.onVisibilityChanged(visible);
- if (visible) {
- mRenderer.start();
- } else {
- mRenderer.stop();
- }
- }
-
- @Override
- public void onSurfaceChanged(SurfaceHolder holder, int format, int width, int height) {
- super.onSurfaceChanged(holder, format, width, height);
- if (mRenderer == null) {
- mRenderer = new GrassRS(width, height);
- mRenderer.init(mRs, getResources());
- mRenderer.start();
- } else {
- mRenderer.resize(width, height);
- }
- }
-
- @Override
- public void onSurfaceCreated(SurfaceHolder holder) {
- super.onSurfaceCreated(holder);
-
- Surface surface = null;
- while (surface == null) {
- surface = holder.getSurface();
- }
- mRs = new RenderScript(surface, false);
- }
-
- @Override
- public void onSurfaceDestroyed(SurfaceHolder holder) {
- super.onSurfaceDestroyed(holder);
- destroyRenderer();
- }
+public class GrassWallpaper extends RenderScriptWallpaper {
+ protected RenderScriptScene createScene(int width, int height) {
+ return new GrassRS(width, height);
}
}