Merge change 21660 into eclair
* changes:
Optimized Galaxy
diff --git a/graphics/java/android/renderscript/Element.java b/graphics/java/android/renderscript/Element.java
index 3061b1e..cf181b7 100644
--- a/graphics/java/android/renderscript/Element.java
+++ b/graphics/java/android/renderscript/Element.java
@@ -245,6 +245,12 @@
add(DataType.FLOAT, DataKind.Z, false, 32, null);
return this;
}
+
+ public Builder addFloatST() {
+ add(DataType.FLOAT, DataKind.S, false, 32, null);
+ add(DataType.FLOAT, DataKind.T, false, 32, null);
+ return this;
+ }
public Builder addFloatRGB() {
add(DataType.FLOAT, DataKind.RED, false, 32, null);
diff --git a/libs/rs/java/Galaxy/res/drawable-hdpi/flares.png b/libs/rs/java/Galaxy/res/drawable-hdpi/flares.png
index fbaaafb..e1c7010 100644
--- a/libs/rs/java/Galaxy/res/drawable-hdpi/flares.png
+++ b/libs/rs/java/Galaxy/res/drawable-hdpi/flares.png
Binary files differ
diff --git a/libs/rs/java/Galaxy/res/drawable-hdpi/light1.png b/libs/rs/java/Galaxy/res/drawable-hdpi/light1.png
index 9d5a795..4ffb1ee 100644
--- a/libs/rs/java/Galaxy/res/drawable-hdpi/light1.png
+++ b/libs/rs/java/Galaxy/res/drawable-hdpi/light1.png
Binary files differ
diff --git a/libs/rs/java/Galaxy/res/drawable-hdpi/light2.png b/libs/rs/java/Galaxy/res/drawable-hdpi/light2.png
deleted file mode 100644
index 86a6d2e..0000000
--- a/libs/rs/java/Galaxy/res/drawable-hdpi/light2.png
+++ /dev/null
Binary files differ
diff --git a/libs/rs/java/Galaxy/res/raw/galaxy.c b/libs/rs/java/Galaxy/res/raw/galaxy.c
index ab82b58..8575712 100644
--- a/libs/rs/java/Galaxy/res/raw/galaxy.c
+++ b/libs/rs/java/Galaxy/res/raw/galaxy.c
@@ -17,26 +17,16 @@
#pragma stateFragment(PFBackground)
#pragma stateFragmentStore(PFSBackground)
-#define RSID_STATE 0
-#define RSID_FRAME_COUNT 0
-#define RSID_WIDTH 1
-#define RSID_HEIGHT 2
-#define RSID_PARTICLES_COUNT 3
-#define RSID_GALAXY_RADIUS 4
-
#define RSID_PARTICLES 1
-#define PARTICLE_STRUCT_FIELDS_COUNT 7
+#define PARTICLE_STRUCT_FIELDS_COUNT 4
#define PARTICLE_STRUCT_ANGLE 0
#define PARTICLE_STRUCT_DISTANCE 1
#define PARTICLE_STRUCT_SPEED 2
-#define PARTICLE_STRUCT_Z 3
-#define PARTICLE_STRUCT_RADIUS 4
-#define PARTICLE_STRUCT_U1 5
-#define PARTICLE_STRUCT_U2 6
+#define PARTICLE_STRUCT_RADIUS 3
#define RSID_PARTICLES_BUFFER 2
-#define PARTICLE_BUFFER_COMPONENTS_COUNT 6
+#define PARTICLE_BUFFER_COMPONENTS_COUNT 5
#define PARTICLES_TEXTURES_COUNT 2
@@ -57,121 +47,82 @@
}
void drawLights(int width, int height) {
- bindProgramFragment(NAMED_PFBackground);
- bindProgramFragmentStore(NAMED_PFSLights);
-
float x = (width - 512.0f) / 2.0f;
float y = (height - 512.0f) / 2.0f;
+ bindProgramFragment(NAMED_PFBackground);
bindTexture(NAMED_PFBackground, 0, NAMED_TLight1);
drawQuad(x + 512.0f, y , 0.0f,
x , y , 0.0f,
x , y + 512.0f, 0.0f,
x + 512.0f, y + 512.0f, 0.0f);
-
- bindTexture(NAMED_PFBackground, 0, NAMED_TLight2);
- drawQuad(x + 512.0f, y , 0.0f,
- x , y , 0.0f,
- x , y + 512.0f, 0.0f,
- x + 512.0f, y + 512.0f, 0.0f);
}
-void drawParticle(int index, int bufferIndex, int width, int height, int radius) {
- float *particle = loadArrayF(RSID_PARTICLES, index);
+void drawParticle(float *particle, int index, float *particleBuffer, int bufferIndex,
+ float w, float h) {
- float distance = particle[PARTICLE_STRUCT_DISTANCE];
- float angle = particle[PARTICLE_STRUCT_ANGLE];
- float speed = particle[PARTICLE_STRUCT_SPEED];
- float r = particle[PARTICLE_STRUCT_RADIUS];
+ float distance = particle[index + PARTICLE_STRUCT_DISTANCE];
+ float angle = particle[index + PARTICLE_STRUCT_ANGLE];
+ float speed = particle[index + PARTICLE_STRUCT_SPEED];
+ float r = particle[index + PARTICLE_STRUCT_RADIUS];
- int red;
- int green;
- int blue;
-
- if (distance < radius / 3.0f) {
- red = 220 + (distance / (float) radius) * 35;
- green = 220;
- blue = 220;
- } else {
- red = 180;
- green = 180;
- blue = clamp(140 + (distance / (float) radius) * 115, 140, 255);
- }
-
- int color = 0xFF000000 | red | green << 8 | blue << 16;
-
- float a = angle + speed * (0.5f + (0.5f * radius / distance));
+ float a = angle + speed;
float x = distance * sinf(a);
float y = distance * cosf(a) * ELLIPSE_RATIO;
float z = distance * ELLIPSE_TWIST;
float s = cosf(z);
float t = sinf(z);
- float sX = t * x + s * y + width / 2.0f;
- float sY = s * x - t * y + height / 2.0f;
- float sZ = particle[PARTICLE_STRUCT_Z];
-
- float u1 = particle[PARTICLE_STRUCT_U1];
- float u2 = particle[PARTICLE_STRUCT_U2];
+ float sX = t * x + s * y + w;
+ float sY = s * x - t * y + h;
// lower left vertex of the particle's triangle
- storeI32(RSID_PARTICLES_BUFFER, bufferIndex, color); // ABGR
-
- storeF(RSID_PARTICLES_BUFFER, bufferIndex + 1, sX - r); // X
- storeF(RSID_PARTICLES_BUFFER, bufferIndex + 2, sY + r); // Y
- storeF(RSID_PARTICLES_BUFFER, bufferIndex + 3, sZ); // Z
-
- storeF(RSID_PARTICLES_BUFFER, bufferIndex + 4, u1); // S
- storeF(RSID_PARTICLES_BUFFER, bufferIndex + 5, 1.0f); // T
+ particleBuffer[bufferIndex + 1] = sX - r; // X
+ particleBuffer[bufferIndex + 2] = sY + r; // Y
// lower right vertex of the particle's triangle
bufferIndex += PARTICLE_BUFFER_COMPONENTS_COUNT;
- storeI32(RSID_PARTICLES_BUFFER, bufferIndex, color);
-
- storeF(RSID_PARTICLES_BUFFER, bufferIndex + 1, sX + r);
- storeF(RSID_PARTICLES_BUFFER, bufferIndex + 2, sY + r);
- storeF(RSID_PARTICLES_BUFFER, bufferIndex + 3, sZ);
-
- storeF(RSID_PARTICLES_BUFFER, bufferIndex + 4, u2);
- storeF(RSID_PARTICLES_BUFFER, bufferIndex + 5, 1.0f);
+ particleBuffer[bufferIndex + 1] = sX + r; // X
+ particleBuffer[bufferIndex + 2] = sY + r; // Y
// upper middle vertex of the particle's triangle
bufferIndex += PARTICLE_BUFFER_COMPONENTS_COUNT;
- storeI32(RSID_PARTICLES_BUFFER, bufferIndex, color);
+ particleBuffer[bufferIndex + 1] = sX; // X
+ particleBuffer[bufferIndex + 2] = sY - r; // Y
- storeF(RSID_PARTICLES_BUFFER, bufferIndex + 1, sX);
- storeF(RSID_PARTICLES_BUFFER, bufferIndex + 2, sY - r);
- storeF(RSID_PARTICLES_BUFFER, bufferIndex + 3, sZ);
-
- storeF(RSID_PARTICLES_BUFFER, bufferIndex + 4, u1 + (u2 - u1) / 2.0f);
- storeF(RSID_PARTICLES_BUFFER, bufferIndex + 5, 0.0f);
-
- particle[PARTICLE_STRUCT_ANGLE] = a;
+ particle[index + PARTICLE_STRUCT_ANGLE] = a;
}
void drawParticles(int width, int height) {
bindProgramFragment(NAMED_PFLighting);
+ bindProgramFragmentStore(NAMED_PFSLights);
bindTexture(NAMED_PFLighting, 0, NAMED_TFlares);
- int radius = loadI32(RSID_STATE, RSID_GALAXY_RADIUS);
- int particlesCount = loadI32(RSID_STATE, RSID_PARTICLES_COUNT);
+ int radius = State_galaxyRadius;
+ int particlesCount = State_particlesCount;
int count = particlesCount * PARTICLE_STRUCT_FIELDS_COUNT;
+ float *particle = loadArrayF(RSID_PARTICLES, 0);
+ float *particleBuffer = loadArrayF(RSID_PARTICLES_BUFFER, 0);
+
+ float w = width * 0.5f;
+ float h = height * 0.5f;
+
int i = 0;
int bufferIndex = 0;
for ( ; i < count; i += PARTICLE_STRUCT_FIELDS_COUNT) {
- drawParticle(i, bufferIndex, width, height, radius);
+ drawParticle(particle, i, particleBuffer, bufferIndex, w, h);
// each particle is a triangle (3 vertices) of 6 properties (ABGR, X, Y, Z, S, T)
bufferIndex += 3 * PARTICLE_BUFFER_COMPONENTS_COUNT;
}
- uploadToBufferObject(NAMED_BParticles);
- drawSimpleMeshRange(NAMED_MParticles, 0, particlesCount * 3);
+ uploadToBufferObject(NAMED_ParticlesBuffer);
+ drawSimpleMeshRange(NAMED_ParticlesMesh, 0, particlesCount * 3);
}
int main(int index) {
- int width = loadI32(RSID_STATE, RSID_WIDTH);
- int height = loadI32(RSID_STATE, RSID_HEIGHT);
+ int width = State_width;
+ int height = State_height;
drawSpace(width, height);
drawParticles(width, height);
diff --git a/libs/rs/java/Galaxy/src/com/android/galaxy/rs/GalaxyRS.java b/libs/rs/java/Galaxy/src/com/android/galaxy/rs/GalaxyRS.java
index 33de229..1b9e349 100644
--- a/libs/rs/java/Galaxy/src/com/android/galaxy/rs/GalaxyRS.java
+++ b/libs/rs/java/Galaxy/src/com/android/galaxy/rs/GalaxyRS.java
@@ -27,8 +27,9 @@
import android.renderscript.Element;
import android.renderscript.SimpleMesh;
import android.renderscript.Primitive;
+import android.renderscript.Type;
import static android.renderscript.Sampler.Value.LINEAR;
-import static android.renderscript.Sampler.Value.CLAMP;
+import static android.renderscript.Sampler.Value.NEAREST;
import static android.renderscript.Sampler.Value.WRAP;
import static android.renderscript.ProgramStore.DepthFunc.*;
import static android.renderscript.ProgramStore.BlendDstFunc;
@@ -44,31 +45,21 @@
class GalaxyRS {
private static final int GALAXY_RADIUS = 300;
private static final int PARTICLES_COUNT = 12000;
- private static final float GALAXY_HEIGHT = 0.1f;
private static final int RSID_STATE = 0;
- private static final int RSID_STATE_FRAMECOUNT = 0;
- private static final int RSID_STATE_WIDTH = 1;
- private static final int RSID_STATE_HEIGHT = 2;
- private static final int RSID_STATE_PARTICLES_COUNT = 3;
- private static final int RSID_STATE_GALAXY_RADIUS = 4;
- private static final int TEXTURES_COUNT = 4;
+ private static final int TEXTURES_COUNT = 3;
private static final int PARTICLES_TEXTURES_COUNT = 2;
private static final int RSID_TEXTURE_SPACE = 0;
private static final int RSID_TEXTURE_LIGHT1 = 1;
- private static final int RSID_TEXTURE_LIGHT2 = 2;
- private static final int RSID_TEXTURE_FLARES = 3;
+ private static final int RSID_TEXTURE_FLARES = 2;
private static final int RSID_PARTICLES = 1;
- private static final int PARTICLE_STRUCT_FIELDS_COUNT = 7;
+ private static final int PARTICLE_STRUCT_FIELDS_COUNT = 4;
private static final int PARTICLE_STRUCT_ANGLE = 0;
private static final int PARTICLE_STRUCT_DISTANCE = 1;
private static final int PARTICLE_STRUCT_SPEED = 2;
- private static final int PARTICLE_STRUCT_Z = 3;
- private static final int PARTICLE_STRUCT_RADIUS = 4;
- private static final int PARTICLE_STRUCT_U1 = 5;
- private static final int PARTICLE_STRUCT_U2 = 6;
+ private static final int PARTICLE_STRUCT_RADIUS = 3;
private static final int RSID_PARTICLES_BUFFER = 2;
@@ -92,11 +83,14 @@
private Allocation[] mTextures;
+ private Type mStateType;
private Allocation mState;
private Allocation mParticles;
private Allocation mParticlesBuffer;
private SimpleMesh mParticlesMesh;
+ private final float[] mFloatData5 = new float[5];
+
public GalaxyRS(int width, int height) {
mWidth = width;
mHeight = height;
@@ -127,6 +121,7 @@
mPfsLights.destroy();
mParticlesMesh.destroy();
mParticlesBuffer.destroy();
+ mStateType.destroy();
}
@Override
@@ -146,8 +141,10 @@
loadTextures();
ScriptC.Builder sb = new ScriptC.Builder(mRS);
+ sb.setType(mStateType, "State", 0);
sb.setScript(mResources, R.raw.galaxy);
sb.setRoot(true);
+
mScript = sb.create();
mScript.setClearColor(0.0f, 0.0f, 0.0f, 1.0f);
mScript.setTimeZone(TimeZone.getDefault().getID());
@@ -161,68 +158,105 @@
private void createScriptStructures() {
createState();
- createParticles();
createParticlesMesh();
+ createParticles();
}
private void createParticlesMesh() {
final Element.Builder elementBuilder = new Element.Builder(mRS);
- elementBuilder.add(Element.DataType.UNSIGNED, Element.DataKind.RED, true, 8);
- elementBuilder.add(Element.DataType.UNSIGNED, Element.DataKind.GREEN, true, 8);
- elementBuilder.add(Element.DataType.UNSIGNED, Element.DataKind.BLUE, true, 8);
- elementBuilder.add(Element.DataType.UNSIGNED, Element.DataKind.ALPHA, true, 8);
- elementBuilder.add(Element.DataType.FLOAT, Element.DataKind.X, false, 32);
- elementBuilder.add(Element.DataType.FLOAT, Element.DataKind.Y, false, 32);
- elementBuilder.add(Element.DataType.FLOAT, Element.DataKind.Z, false, 32);
- elementBuilder.add(Element.DataType.FLOAT, Element.DataKind.S, false, 32);
- elementBuilder.add(Element.DataType.FLOAT, Element.DataKind.T, false, 32);
+ elementBuilder.addUNorm8RGBA();
+ elementBuilder.addFloatXY();
+ elementBuilder.addFloatST();
final Element vertexElement = elementBuilder.create();
final SimpleMesh.Builder meshBuilder = new SimpleMesh.Builder(mRS);
final int vertexSlot = meshBuilder.addVertexType(vertexElement, PARTICLES_COUNT * 3);
meshBuilder.setPrimitive(Primitive.TRIANGLE);
mParticlesMesh = meshBuilder.create();
- mParticlesMesh.setName("MParticles");
+ mParticlesMesh.setName("ParticlesMesh");
mParticlesBuffer = mParticlesMesh.createVertexAllocation(vertexSlot);
- mParticlesBuffer.setName("BParticles");
+ mParticlesBuffer.setName("ParticlesBuffer");
mParticlesMesh.bindVertexAllocation(mParticlesBuffer, 0);
}
+ static class GalaxyState {
+ public int frameCount;
+ public int width;
+ public int height;
+ public int particlesCount;
+ public int galaxyRadius;
+ }
+
+ private void createState() {
+ GalaxyState state = new GalaxyState();
+ state.width = mWidth;
+ state.height = mHeight;
+ state.particlesCount = PARTICLES_COUNT;
+ state.galaxyRadius = GALAXY_RADIUS;
+
+ mStateType = Type.createFromClass(mRS, GalaxyState.class, 1, "GalaxyState");
+ mState = Allocation.createTyped(mRS, mStateType);
+ mState.data(state);
+ }
+
private void createParticles() {
final float[] particles = new float[PARTICLES_COUNT * PARTICLE_STRUCT_FIELDS_COUNT];
- mParticles = Allocation.createSized(mRS, USER_FLOAT, particles.length);
+
+ int bufferIndex = 0;
+
for (int i = 0; i < particles.length; i += PARTICLE_STRUCT_FIELDS_COUNT) {
- createParticle(particles, i);
+ createParticle(particles, i, bufferIndex);
+ bufferIndex += 3;
}
+
+ mParticles = Allocation.createSized(mRS, USER_FLOAT, particles.length);
mParticles.data(particles);
}
- private void createState() {
- final int[] data = new int[5];
-
- mState = Allocation.createSized(mRS, USER_I32, data.length);
- data[RSID_STATE_FRAMECOUNT] = 0;
- data[RSID_STATE_WIDTH] = mWidth;
- data[RSID_STATE_HEIGHT] = mHeight;
- data[RSID_STATE_PARTICLES_COUNT] = PARTICLES_COUNT;
- data[RSID_STATE_GALAXY_RADIUS] = GALAXY_RADIUS;
- mState.data(data);
- }
-
@SuppressWarnings({"PointlessArithmeticExpression"})
- private void createParticle(float[] particles, int index) {
- int sprite = random(PARTICLES_TEXTURES_COUNT);
+ private void createParticle(float[] particles, int index, int bufferIndex) {
float d = abs(randomGauss()) * GALAXY_RADIUS / 2.0f;
particles[index + PARTICLE_STRUCT_ANGLE] = random(0.0f, (float) (Math.PI * 2.0));
particles[index + PARTICLE_STRUCT_DISTANCE] = d;
- particles[index + PARTICLE_STRUCT_SPEED] = random(0.0015f, 0.0025f);
- particles[index + PARTICLE_STRUCT_Z] = randomGauss() * GALAXY_HEIGHT *
- (GALAXY_RADIUS - d) / (float) GALAXY_RADIUS;
- particles[index + PARTICLE_STRUCT_RADIUS] = random(3.0f, 7.5f);
- particles[index + PARTICLE_STRUCT_U1] = sprite / (float) PARTICLES_TEXTURES_COUNT;
- particles[index + PARTICLE_STRUCT_U2] = (sprite + 1) / (float) PARTICLES_TEXTURES_COUNT;
+ particles[index + PARTICLE_STRUCT_SPEED] = random(0.0015f, 0.0025f) *
+ (0.5f + (0.5f * (float) GALAXY_RADIUS / d));
+ particles[index + PARTICLE_STRUCT_RADIUS] = random(1.0f, 2.1f);
+
+ int red, green, blue;
+ if (d < GALAXY_RADIUS / 3.0f) {
+ red = (int) (220 + (d / (float) GALAXY_RADIUS) * 35);
+ green = 220;
+ blue = 220;
+ } else {
+ red = 180;
+ green = 180;
+ blue = (int) constrain(140 + (d / (float) GALAXY_RADIUS) * 115, 140, 255);
+ }
+
+ final int color = 0xFF000000 | red | green << 8 | blue << 16;
+ final int sprite = random(PARTICLES_TEXTURES_COUNT);
+ final float u1 = sprite / (float) PARTICLES_TEXTURES_COUNT;
+ final float u2 = (sprite + 1) / (float) PARTICLES_TEXTURES_COUNT;
+
+ final float[] floatData = mFloatData5;
+ final Allocation buffer = mParticlesBuffer;
+
+ floatData[0] = Float.intBitsToFloat(color);
+ floatData[3] = u1;
+ floatData[4] = 1.0f;
+ buffer.subData1D(bufferIndex, 1, floatData);
+
+ bufferIndex++;
+ floatData[3] = u2;
+ floatData[4] = 1.0f;
+ buffer.subData1D(bufferIndex, 1, floatData);
+
+ bufferIndex++;
+ floatData[3] = u1 + (u2 - u1) / 2.0f;
+ floatData[4] = 0.0f;
+ buffer.subData1D(bufferIndex, 1, floatData);
}
private static float randomGauss() {
@@ -246,7 +280,6 @@
final Allocation[] textures = mTextures;
textures[RSID_TEXTURE_SPACE] = loadTexture(R.drawable.space, "TSpace");
textures[RSID_TEXTURE_LIGHT1] = loadTextureARGB(R.drawable.light1, "TLight1");
- textures[RSID_TEXTURE_LIGHT2] = loadTextureARGB(R.drawable.light2, "TLight2");
textures[RSID_TEXTURE_FLARES] = loadTextureARGB(R.drawable.flares, "TFlares");
final int count = textures.length;
@@ -286,10 +319,10 @@
mPfBackground.bindSampler(mSampler, 0);
sampleBuilder = new Sampler.Builder(mRS);
- sampleBuilder.setMin(LINEAR);
- sampleBuilder.setMag(LINEAR);
- sampleBuilder.setWrapS(CLAMP);
- sampleBuilder.setWrapT(CLAMP);
+ sampleBuilder.setMin(NEAREST);
+ sampleBuilder.setMag(NEAREST);
+ sampleBuilder.setWrapS(WRAP);
+ sampleBuilder.setWrapT(WRAP);
mLightSampler = sampleBuilder.create();
builder = new ProgramFragment.Builder(mRS, null, null);
@@ -303,9 +336,8 @@
private void createProgramFragmentStore() {
ProgramStore.Builder builder = new ProgramStore.Builder(mRS, null, null);
builder.setDepthFunc(ALWAYS);
- builder.setBlendFunc(BlendSrcFunc.SRC_ALPHA, BlendDstFunc.ONE_MINUS_SRC_ALPHA);
+ builder.setBlendFunc(BlendSrcFunc.ONE, BlendDstFunc.ZERO);
builder.setDitherEnable(false);
- builder.setDepthMask(true);
mPfsBackground = builder.create();
mPfsBackground.setName("PFSBackground");
@@ -313,7 +345,6 @@
builder.setDepthFunc(ALWAYS);
builder.setBlendFunc(BlendSrcFunc.ONE, BlendDstFunc.ONE);
builder.setDitherEnable(false);
- builder.setDepthMask(true);
mPfsLights = builder.create();
mPfsLights.setName("PFSLights");
}
@@ -324,7 +355,6 @@
mPvOrthoAlloc.setupOrthoWindow(mWidth, mHeight);
ProgramVertex.Builder builder = new ProgramVertex.Builder(mRS, null, null);
- builder.setTextureMatrixEnable(true);
mPvBackground = builder.create();
mPvBackground.bindAllocation(mPvOrthoAlloc);
mPvBackground.setName("PVBackground");