diff options
Diffstat (limited to 'libs/rs/java')
83 files changed, 4494 insertions, 1142 deletions
diff --git a/libs/rs/java/Film/res/drawable/p01.png b/libs/rs/java/Film/res/drawable/p01.png Binary files differdeleted file mode 100644 index a9b9bdb..0000000 --- a/libs/rs/java/Film/res/drawable/p01.png +++ /dev/null diff --git a/libs/rs/java/Film/res/drawable/p02.png b/libs/rs/java/Film/res/drawable/p02.png Binary files differdeleted file mode 100644 index 8162c82..0000000 --- a/libs/rs/java/Film/res/drawable/p02.png +++ /dev/null diff --git a/libs/rs/java/Film/res/drawable/p03.png b/libs/rs/java/Film/res/drawable/p03.png Binary files differdeleted file mode 100644 index e3e26c0..0000000 --- a/libs/rs/java/Film/res/drawable/p03.png +++ /dev/null diff --git a/libs/rs/java/Film/res/drawable/p04.png b/libs/rs/java/Film/res/drawable/p04.png Binary files differdeleted file mode 100644 index daee603..0000000 --- a/libs/rs/java/Film/res/drawable/p04.png +++ /dev/null diff --git a/libs/rs/java/Film/res/drawable/p05.png b/libs/rs/java/Film/res/drawable/p05.png Binary files differdeleted file mode 100644 index fac5248..0000000 --- a/libs/rs/java/Film/res/drawable/p05.png +++ /dev/null diff --git a/libs/rs/java/Film/res/drawable/p06.png b/libs/rs/java/Film/res/drawable/p06.png Binary files differdeleted file mode 100644 index 3b51261..0000000 --- a/libs/rs/java/Film/res/drawable/p06.png +++ /dev/null diff --git a/libs/rs/java/Film/res/drawable/p07.png b/libs/rs/java/Film/res/drawable/p07.png Binary files differdeleted file mode 100644 index d8bd938..0000000 --- a/libs/rs/java/Film/res/drawable/p07.png +++ /dev/null diff --git a/libs/rs/java/Film/res/drawable/p08.png b/libs/rs/java/Film/res/drawable/p08.png Binary files differdeleted file mode 100644 index ef175e8..0000000 --- a/libs/rs/java/Film/res/drawable/p08.png +++ /dev/null diff --git a/libs/rs/java/Film/res/drawable/p09.png b/libs/rs/java/Film/res/drawable/p09.png Binary files differdeleted file mode 100644 index 7bf3874..0000000 --- a/libs/rs/java/Film/res/drawable/p09.png +++ /dev/null diff --git a/libs/rs/java/Film/res/drawable/p10.png b/libs/rs/java/Film/res/drawable/p10.png Binary files differdeleted file mode 100644 index 908827d..0000000 --- a/libs/rs/java/Film/res/drawable/p10.png +++ /dev/null diff --git a/libs/rs/java/Film/res/drawable/p11.png b/libs/rs/java/Film/res/drawable/p11.png Binary files differdeleted file mode 100644 index 1289f71..0000000 --- a/libs/rs/java/Film/res/drawable/p11.png +++ /dev/null diff --git a/libs/rs/java/Film/res/drawable/p12.png b/libs/rs/java/Film/res/drawable/p12.png Binary files differdeleted file mode 100644 index e1af16a..0000000 --- a/libs/rs/java/Film/res/drawable/p12.png +++ /dev/null diff --git a/libs/rs/java/Film/res/drawable/p13.png b/libs/rs/java/Film/res/drawable/p13.png Binary files differdeleted file mode 100644 index d08bcbe..0000000 --- a/libs/rs/java/Film/res/drawable/p13.png +++ /dev/null diff --git a/libs/rs/java/Film/res/raw/filmimage.c b/libs/rs/java/Film/res/raw/filmimage.c deleted file mode 100644 index d154c68..0000000 --- a/libs/rs/java/Film/res/raw/filmimage.c +++ /dev/null @@ -1,110 +0,0 @@ -// Fountain test script - -#pragma version(1) -#pragma stateVertex(orthoWindow) -#pragma stateRaster(flat) -#pragma stateFragment(PgmFragBackground) -#pragma stateStore(MyBlend) - - -int main(void* con, int ft, int launchID) { - int count, touch, x, y, rate, maxLife, lifeShift; - int life; - int ct, ct2; - int newPart; - int drawCount; - int dx, dy, idx; - int posx,posy; - int c; - int srcIdx; - int dstIdx; - - count = loadI32(con, 0, 1); - touch = loadI32(con, 0, 2); - x = loadI32(con, 0, 3); - y = loadI32(con, 0, 4); - - rate = 4; - maxLife = (count / rate) - 1; - lifeShift = 0; - { - life = maxLife; - while (life > 255) { - life = life >> 1; - lifeShift ++; - } - } - - drawRect(con, 0, 256, 0, 512); - contextBindProgramFragment(con, NAMED_PgmFragParts); - - if (touch) { - newPart = loadI32(con, 2, 0); - for (ct2=0; ct2<rate; ct2++) { - dx = scriptRand(con, 0x10000) - 0x8000; - dy = scriptRand(con, 0x10000) - 0x8000; - - idx = newPart * 5 + 1; - storeI32(con, 2, idx, dx); - storeI32(con, 2, idx + 1, dy); - storeI32(con, 2, idx + 2, maxLife); - storeI32(con, 2, idx + 3, x << 16); - storeI32(con, 2, idx + 4, y << 16); - - newPart++; - if (newPart >= count) { - newPart = 0; - } - } - storeI32(con, 2, 0, newPart); - } - - drawCount = 0; - for (ct=0; ct < count; ct++) { - srcIdx = ct * 5 + 1; - - dx = loadI32(con, 2, srcIdx); - dy = loadI32(con, 2, srcIdx + 1); - life = loadI32(con, 2, srcIdx + 2); - posx = loadI32(con, 2, srcIdx + 3); - posy = loadI32(con, 2, srcIdx + 4); - - if (life) { - if (posy < (480 << 16)) { - dstIdx = drawCount * 9; - c = 0xffafcf | ((life >> lifeShift) << 24); - - storeU32(con, 1, dstIdx, c); - storeI32(con, 1, dstIdx + 1, posx); - storeI32(con, 1, dstIdx + 2, posy); - - storeU32(con, 1, dstIdx + 3, c); - storeI32(con, 1, dstIdx + 4, posx + 0x10000); - storeI32(con, 1, dstIdx + 5, posy + dy * 4); - - storeU32(con, 1, dstIdx + 6, c); - storeI32(con, 1, dstIdx + 7, posx - 0x10000); - storeI32(con, 1, dstIdx + 8, posy + dy * 4); - drawCount ++; - } else { - if (dy > 0) { - dy = (-dy) >> 1; - } - } - - posx = posx + dx; - posy = posy + dy; - dy = dy + 0x400; - life --; - - //storeI32(con, 2, srcIdx, dx); - storeI32(con, 2, srcIdx + 1, dy); - storeI32(con, 2, srcIdx + 2, life); - storeI32(con, 2, srcIdx + 3, posx); - storeI32(con, 2, srcIdx + 4, posy); - } - } - - drawTriangleArray(con, NAMED_PartBuffer, drawCount); - return 1; -} diff --git a/libs/rs/java/Film/res/raw/filmstrip.c b/libs/rs/java/Film/res/raw/filmstrip.c deleted file mode 100644 index bf75675..0000000 --- a/libs/rs/java/Film/res/raw/filmstrip.c +++ /dev/null @@ -1,94 +0,0 @@ -// Fountain test script - -#pragma version(1) -#pragma stateVertex(PVBackground) -#pragma stateFragment(PFBackground) -#pragma stateStore(PSBackground) - -#define STATE_TRIANGLE_OFFSET_COUNT 0 -#define STATE_LAST_FOCUS 1 - - -// The script enviroment has 3 env allocations. -// bank0: (r) The enviroment structure -// bank1: (r) The position information -// bank2: (rw) The temporary texture state - -int lastFocus; - -int main(int index) -{ - float mat1[16]; - - float trans = Pos->translate; - float rot = Pos->rotate; - - matrixLoadScale(mat1, 2.f, 2.f, 2.f); - matrixTranslate(mat1, 0.f, 0.f, trans); - matrixRotate(mat1, 90.f, 0.f, 0.f, 1.f); - matrixRotate(mat1, rot, 1.f, 0.f, 0.f); - vpLoadModelMatrix(mat1); - - // Draw the lighting effect in the strip and fill the Z buffer. - drawSimpleMesh(NAMED_mesh); - - // Start of images. - bindProgramStore(NAMED_PSImages); - bindProgramFragment(NAMED_PFImages); - bindProgramVertex(NAMED_PVImages); - - float focusPos = Pos->focus; - int focusID = 0; - int lastFocusID = loadI32(2, STATE_LAST_FOCUS); - int imgCount = 13; - - if (trans > (-.3f)) { - focusID = -1.0f - focusPos; - if (focusID >= imgCount) { - focusID = -1; - } - } else { - focusID = -1; - } - - /* - if (focusID != lastFocusID) { - if (lastFocusID >= 0) { - uploadToTexture(con, env->tex[lastFocusID], 1); - } - if (focusID >= 0) { - uploadToTexture(con, env->tex[focusID], 0); - } - } - */ - lastFocus = focusID; - - int triangleOffsetsCount = Pos->triangleOffsetCount; - - int imgId = 0; - for (imgId=1; imgId <= imgCount; imgId++) { - float pos = focusPos + imgId + 0.4f; - int offset = (int)floorf(pos * 2.f); - pos = pos - 0.75f; - - offset = offset + triangleOffsetsCount / 2; - if (!((offset < 0) || (offset >= triangleOffsetsCount))) { - int start = offset -2; - int end = offset + 2; - - if (start < 0) { - start = 0; - } - if (end >= triangleOffsetsCount) { - end = triangleOffsetsCount-1; - } - - bindTexture(NAMED_PFImages, 0, loadI32(0, imgId - 1)); - matrixLoadTranslate(mat1, -pos - loadF(5, triangleOffsetsCount / 2), 0, 0); - vpLoadTextureMatrix(mat1); - drawSimpleMeshRange(NAMED_mesh, loadI32(4, start), (loadI32(4, end) - loadI32(4, start))); - } - } - return 0; -} - diff --git a/libs/rs/java/Film/src/com/android/film/FilmRS.java b/libs/rs/java/Film/src/com/android/film/FilmRS.java deleted file mode 100644 index 7d04502..0000000 --- a/libs/rs/java/Film/src/com/android/film/FilmRS.java +++ /dev/null @@ -1,258 +0,0 @@ -/* - * Copyright (C) 2008 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.film; - -import java.io.Writer; - -import android.content.Context; -import android.content.res.Resources; -import android.graphics.Bitmap; -import android.util.Log; - -import android.renderscript.*; - -public class FilmRS { - class StripPosition { - public float translate; - public float rotate; - public float focus; - public int triangleOffsetCount; - } - StripPosition mPos = new StripPosition(); - - - private final int STATE_LAST_FOCUS = 1; - - public FilmRS() { - } - - public void init(RenderScriptGL rs, Resources res, int width, int height) { - mRS = rs; - mRes = res; - initRS(); - } - - public void setFilmStripPosition(int x, int y) - { - if (x < 50) { - x = 50; - } - if (x > 270) { - x = 270; - } - - float anim = ((float)x-50) / 270.f; - mPos.translate = 2f * anim + 0.5f; // translation - mPos.rotate = (anim * 40); // rotation - mPos.focus = ((float)y) / 16.f - 10.f; // focusPos - mPos.triangleOffsetCount = mFSM.mTriangleOffsetsCount; - mAllocPos.data(mPos); - } - - - private Resources mRes; - private RenderScriptGL mRS; - private Script mScriptStrip; - private Script mScriptImage; - private Sampler mSampler; - private ProgramStore mPSBackground; - private ProgramStore mPSImages; - private ProgramFragment mPFBackground; - private ProgramFragment mPFImages; - private ProgramVertex mPVBackground; - private ProgramVertex mPVImages; - private ProgramVertex.MatrixAllocation mPVA; - private Type mStripPositionType; - - private Allocation mImages[]; - private Allocation mAllocIDs; - private Allocation mAllocPos; - private Allocation mAllocState; - private Allocation mAllocPV; - private Allocation mAllocOffsetsTex; - private Allocation mAllocOffsets; - - private SimpleMesh mMesh; - private Light mLight; - - private FilmStripMesh mFSM; - - private int[] mBufferIDs; - private float[] mBufferPos = new float[3]; - private int[] mBufferState; - - private void initPFS() { - ProgramStore.Builder b = new ProgramStore.Builder(mRS, null, null); - - b.setDepthFunc(ProgramStore.DepthFunc.LESS); - b.setDitherEnable(true); - b.setDepthMask(true); - mPSBackground = b.create(); - mPSBackground.setName("PSBackground"); - - b.setDepthFunc(ProgramStore.DepthFunc.EQUAL); - b.setDitherEnable(false); - b.setDepthMask(false); - b.setBlendFunc(ProgramStore.BlendSrcFunc.ONE, - ProgramStore.BlendDstFunc.ONE); - mPSImages = b.create(); - mPSImages.setName("PSImages"); - } - - private void initPF() { - Sampler.Builder bs = new Sampler.Builder(mRS); - bs.setMin(Sampler.Value.LINEAR);//_MIP_LINEAR); - bs.setMag(Sampler.Value.LINEAR); - bs.setWrapS(Sampler.Value.CLAMP); - bs.setWrapT(Sampler.Value.WRAP); - mSampler = bs.create(); - - ProgramFragment.Builder b = new ProgramFragment.Builder(mRS); - mPFBackground = b.create(); - mPFBackground.setName("PFBackground"); - - b = new ProgramFragment.Builder(mRS); - b.setTexture(ProgramFragment.Builder.EnvMode.REPLACE, - ProgramFragment.Builder.Format.RGBA, 0); - mPFImages = b.create(); - mPFImages.bindSampler(mSampler, 0); - mPFImages.setName("PFImages"); - } - - private void initPV() { - mLight = (new Light.Builder(mRS)).create(); - mLight.setPosition(0, -0.5f, -1.0f); - - ProgramVertex.Builder pvb = new ProgramVertex.Builder(mRS, null, null); - //pvb.addLight(mLight); - mPVBackground = pvb.create(); - mPVBackground.setName("PVBackground"); - - pvb = new ProgramVertex.Builder(mRS, null, null); - pvb.setTextureMatrixEnable(true); - mPVImages = pvb.create(); - mPVImages.setName("PVImages"); - } - - private void loadImages() { - mBufferIDs = new int[13]; - mImages = new Allocation[13]; - mAllocIDs = Allocation.createSized(mRS, - Element.createUser(mRS, Element.DataType.FLOAT_32), - mBufferIDs.length); - - Element ie = Element.createPixel(mRS, Element.DataType.UNSIGNED_5_6_5, Element.DataKind.PIXEL_RGB); - mImages[0] = Allocation.createFromBitmapResourceBoxed(mRS, mRes, R.drawable.p01, ie, true); - mImages[1] = Allocation.createFromBitmapResourceBoxed(mRS, mRes, R.drawable.p02, ie, true); - mImages[2] = Allocation.createFromBitmapResourceBoxed(mRS, mRes, R.drawable.p03, ie, true); - mImages[3] = Allocation.createFromBitmapResourceBoxed(mRS, mRes, R.drawable.p04, ie, true); - mImages[4] = Allocation.createFromBitmapResourceBoxed(mRS, mRes, R.drawable.p05, ie, true); - mImages[5] = Allocation.createFromBitmapResourceBoxed(mRS, mRes, R.drawable.p06, ie, true); - mImages[6] = Allocation.createFromBitmapResourceBoxed(mRS, mRes, R.drawable.p07, ie, true); - mImages[7] = Allocation.createFromBitmapResourceBoxed(mRS, mRes, R.drawable.p08, ie, true); - mImages[8] = Allocation.createFromBitmapResourceBoxed(mRS, mRes, R.drawable.p09, ie, true); - mImages[9] = Allocation.createFromBitmapResourceBoxed(mRS, mRes, R.drawable.p10, ie, true); - mImages[10] = Allocation.createFromBitmapResourceBoxed(mRS, mRes, R.drawable.p11, ie, true); - mImages[11] = Allocation.createFromBitmapResourceBoxed(mRS, mRes, R.drawable.p12, ie, true); - mImages[12] = Allocation.createFromBitmapResourceBoxed(mRS, mRes, R.drawable.p13, ie, true); - - int black[] = new int[1024]; - for(int ct=0; ct < mImages.length; ct++) { - Allocation.Adapter2D a = mImages[ct].createAdapter2D(); - - int size = 512; - int mip = 0; - while(size >= 2) { - a.subData(0, 0, 2, size, black); - a.subData(size-2, 0, 2, size, black); - a.subData(0, 0, size, 2, black); - a.subData(0, size-2, size, 2, black); - size >>= 1; - mip++; - a.setConstraint(Dimension.LOD, mip); - } - - mImages[ct].uploadToTexture(1); - mBufferIDs[ct] = mImages[ct].getID(); - } - mAllocIDs.data(mBufferIDs); - } - - private void initState() - { - mBufferState = new int[10]; - mAllocState = Allocation.createSized(mRS, - Element.createUser(mRS, Element.DataType.FLOAT_32), - mBufferState.length); - mBufferState[STATE_LAST_FOCUS] = -1; - mAllocState.data(mBufferState); - } - - private void initRS() { - mFSM = new FilmStripMesh(); - mMesh = mFSM.init(mRS); - mMesh.setName("mesh"); - - initPFS(); - initPF(); - initPV(); - - Log.e("rs", "Done loading named"); - - mStripPositionType = Type.createFromClass(mRS, StripPosition.class, 1); - - ScriptC.Builder sb = new ScriptC.Builder(mRS); - sb.setScript(mRes, R.raw.filmstrip); - sb.setRoot(true); - sb.setType(mStripPositionType, "Pos", 1); - mScriptStrip = sb.create(); - mScriptStrip.setClearColor(0.0f, 0.0f, 0.0f, 1.0f); - - mAllocPos = Allocation.createTyped(mRS, mStripPositionType); - - loadImages(); - initState(); - - mPVA = new ProgramVertex.MatrixAllocation(mRS); - mPVBackground.bindAllocation(mPVA); - mPVImages.bindAllocation(mPVA); - mPVA.setupProjectionNormalized(320, 480); - - - mScriptStrip.bindAllocation(mAllocIDs, 0); - mScriptStrip.bindAllocation(mAllocPos, 1); - mScriptStrip.bindAllocation(mAllocState, 2); - mScriptStrip.bindAllocation(mPVA.mAlloc, 3); - - - mAllocOffsets = Allocation.createSized(mRS, - Element.createUser(mRS, Element.DataType.SIGNED_32), mFSM.mTriangleOffsets.length); - mAllocOffsets.data(mFSM.mTriangleOffsets); - mScriptStrip.bindAllocation(mAllocOffsets, 4); - - mAllocOffsetsTex = Allocation.createSized(mRS, - Element.createUser(mRS, Element.DataType.FLOAT_32), mFSM.mTriangleOffsetsTex.length); - mAllocOffsetsTex.data(mFSM.mTriangleOffsetsTex); - mScriptStrip.bindAllocation(mAllocOffsetsTex, 5); - - setFilmStripPosition(0, 0); - mRS.contextBindRootScript(mScriptStrip); - } -} - - - diff --git a/libs/rs/java/Film/src/com/android/film/FilmStripMesh.java b/libs/rs/java/Film/src/com/android/film/FilmStripMesh.java deleted file mode 100644 index 448cce0..0000000 --- a/libs/rs/java/Film/src/com/android/film/FilmStripMesh.java +++ /dev/null @@ -1,259 +0,0 @@ -/* - * 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.film; - -import java.io.Writer; -import java.lang.Math; -import android.util.Log; - -import android.renderscript.RenderScript; -import android.renderscript.SimpleMesh; - - -class FilmStripMesh { - - class Vertex { - float nx; - float ny; - float nz; - float s; - float t; - float x; - float y; - float z; - - Vertex() { - nx = 0; - ny = 0; - nz = 0; - s = 0; - t = 0; - x = 0; - y = 0; - z = 0; - } - - void xyz(float _x, float _y, float _z) { - x = _x; - y = _y; - z = _z; - } - - void nxyz(float _x, float _y, float _z) { - nx = _x; - ny = _y; - nz = _z; - } - - void st(float _s, float _t) { - s = _s; - t = _t; - } - - void computeNorm(Vertex v1, Vertex v2) { - float dx = v1.x - v2.x; - float dy = v1.y - v2.y; - float dz = v1.z - v2.z; - float len = (float)java.lang.Math.sqrt(dx*dx + dy*dy + dz*dz); - dx /= len; - dy /= len; - dz /= len; - - nx = dx * dz; - ny = dy * dz; - nz = (float)java.lang.Math.sqrt(dx*dx + dy*dy); - - len = (float)java.lang.Math.sqrt(nx*nx + ny*ny + nz*nz); - nx /= len; - ny /= len; - nz /= len; - } - } - - int[] mTriangleOffsets; - float[] mTriangleOffsetsTex; - int mTriangleOffsetsCount; - - SimpleMesh init(RenderScript rs) - { - float vtx[] = new float[] { - 60.431003f, 124.482050f, - 60.862074f, 120.872604f, - 61.705303f, 117.336662f, - 62.949505f, 113.921127f, - 64.578177f, 110.671304f, - 66.569716f, 107.630302f, - 68.897703f, 104.838457f, - 71.531259f, 102.332803f, - 74.435452f, 100.146577f, - 77.571757f, 98.308777f, - 80.898574f, 96.843781f, - 84.371773f, 95.771023f, - 87.945283f, 95.104731f, - 98.958994f, 95.267098f, - 109.489523f, 98.497596f, - 118.699582f, 104.539366f, - 125.856872f, 112.912022f, - 130.392311f, 122.949849f, - 131.945283f, 133.854731f, - 130.392311f, 144.759613f, - 125.856872f, 154.797439f, - 118.699582f, 163.170096f, - 109.489523f, 169.211866f, - 98.958994f, 172.442364f, - 87.945283f, 172.604731f, - 72.507313f, 172.672927f, - 57.678920f, 168.377071f, - 44.668135f, 160.067134f, - 34.534908f, 148.420104f, - 28.104767f, 134.384831f, - 25.901557f, 119.104731f, - 28.104767f, 103.824631f, - 34.534908f, 89.789358f, - 44.668135f, 78.142327f, - 57.678920f, 69.832390f, - 72.507313f, 65.536534f, - 87.945283f, 65.604731f, - 106.918117f, 65.688542f, - 125.141795f, 60.409056f, - 141.131686f, 50.196376f, - 153.585137f, 35.882502f, - 161.487600f, 18.633545f, - 164.195283f, -0.145269f, - 161.487600f, -18.924084f, - 153.585137f, -36.173040f, - 141.131686f, -50.486914f, - 125.141795f, -60.699594f, - 106.918117f, -65.979081f, - 87.945283f, -65.895269f, - 80f, -65.895269f, - 60f, -65.895269f, - 40f, -65.895269f, - 20f, -65.895269f, - 0f, -65.895269f, - -20f, -65.895269f, - -40f, -65.895269f, - -60f, -65.895269f, - -80f, -65.895269f, - -87.945283f, -65.895269f, - -106.918117f, -65.979081f, - -125.141795f, -60.699594f, - -141.131686f, -50.486914f, - -153.585137f, -36.173040f, - -161.487600f, -18.924084f, - -164.195283f, -0.145269f, - -161.487600f, 18.633545f, - -153.585137f, 35.882502f, - -141.131686f, 50.196376f, - -125.141795f, 60.409056f, - -106.918117f, 65.688542f, - -87.945283f, 65.604731f, - -72.507313f, 65.536534f, - -57.678920f, 69.832390f, - -44.668135f, 78.142327f, - -34.534908f, 89.789358f, - -28.104767f, 103.824631f, - -25.901557f, 119.104731f, - -28.104767f, 134.384831f, - -34.534908f, 148.420104f, - -44.668135f, 160.067134f, - -57.678920f, 168.377071f, - -72.507313f, 172.672927f, - -87.945283f, 172.604731f, - -98.958994f, 172.442364f, - -109.489523f, 169.211866f, - -118.699582f, 163.170096f, - -125.856872f, 154.797439f, - -130.392311f, 144.759613f, - -131.945283f, 133.854731f, - -130.392311f, 122.949849f, - -125.856872f, 112.912022f, - -118.699582f, 104.539366f, - -109.489523f, 98.497596f, - -98.958994f, 95.267098f, - -87.945283f, 95.104731f, - -84.371773f, 95.771023f, - -80.898574f, 96.843781f, - -77.571757f, 98.308777f, - -74.435452f, 100.146577f, - -71.531259f, 102.332803f, - -68.897703f, 104.838457f, - -66.569716f, 107.630302f, - -64.578177f, 110.671304f, - -62.949505f, 113.921127f, - -61.705303f, 117.336662f, - -60.862074f, 120.872604f, - -60.431003f, 124.482050f - }; - - - mTriangleOffsets = new int[64]; - mTriangleOffsetsTex = new float[64]; - - mTriangleOffsets[0] = 0; - mTriangleOffsetsCount = 1; - - Vertex t = new Vertex(); - t.nxyz(1, 0, 0); - int count = vtx.length / 2; - - SimpleMesh.TriangleMeshBuilder tm = new SimpleMesh.TriangleMeshBuilder( - rs, 3, - SimpleMesh.TriangleMeshBuilder.NORMAL | SimpleMesh.TriangleMeshBuilder.TEXTURE_0); - - float runningS = 0; - for (int ct=0; ct < (count-1); ct++) { - t.x = -vtx[ct*2] / 100.f; - t.z = vtx[ct*2+1] / 100.f; - t.s = runningS; - t.nx = (vtx[ct*2+3] - vtx[ct*2 +1]); - t.ny = (vtx[ct*2+2] - vtx[ct*2 ]); - float len = (float)java.lang.Math.sqrt(t.nx * t.nx + t.ny * t.ny); - runningS += len / 100; - t.nx /= len; - t.ny /= len; - t.y = -0.5f; - t.t = 0; - tm.setNormal(t.nx, t.ny, t.nz); - tm.setTexture(t.s, t.t); - tm.addVertex(t.x, t.y, t.z); - //android.util.Log.e("rs", "vtx x="+t.x+" y="+t.y+" z="+t.z+" s="+t.s+" t="+t.t); - t.y = .5f; - t.t = 1; - tm.setTexture(t.s, t.t); - tm.addVertex(t.x, t.y, t.z); - //android.util.Log.e("rs", "vtx x="+t.x+" y="+t.y+" z="+t.z+" s="+t.s+" t="+t.t); - - if((runningS*2) > mTriangleOffsetsCount) { - mTriangleOffsets[mTriangleOffsetsCount] = ct*2 * 3; - mTriangleOffsetsTex[mTriangleOffsetsCount] = t.s; - mTriangleOffsetsCount ++; - } - } - - count = (count * 2 - 2); - for (int ct=0; ct < (count-2); ct+= 2) { - tm.addTriangle(ct, ct+1, ct+2); - tm.addTriangle(ct+1, ct+3, ct+2); - } - return tm.create(); - } - - -} - diff --git a/libs/rs/java/Fountain/Android.mk b/libs/rs/java/Fountain/Android.mk index f7e53a8..71944b2 100644 --- a/libs/rs/java/Fountain/Android.mk +++ b/libs/rs/java/Fountain/Android.mk @@ -14,14 +14,18 @@ # limitations under the License. # +ifneq ($(TARGET_SIMULATOR),true) + LOCAL_PATH := $(call my-dir) include $(CLEAR_VARS) LOCAL_MODULE_TAGS := optional -LOCAL_SRC_FILES := $(call all-java-files-under, src) +LOCAL_SRC_FILES := $(call all-java-files-under, src) $(call all-renderscript-files-under, src) #LOCAL_STATIC_JAVA_LIBRARIES := android.renderscript LOCAL_PACKAGE_NAME := Fountain include $(BUILD_PACKAGE) + +endif diff --git a/libs/rs/java/Fountain/res/drawable/gadgets_clock_mp3.png b/libs/rs/java/Fountain/res/drawable/gadgets_clock_mp3.png Binary files differdeleted file mode 100755 index e91bfb4..0000000 --- a/libs/rs/java/Fountain/res/drawable/gadgets_clock_mp3.png +++ /dev/null diff --git a/libs/rs/java/Fountain/res/raw/fountain.c b/libs/rs/java/Fountain/res/raw/fountain.c deleted file mode 100644 index 73b819b..0000000 --- a/libs/rs/java/Fountain/res/raw/fountain.c +++ /dev/null @@ -1,52 +0,0 @@ -// Fountain test script -#pragma version(1) - -int newPart = 0; - -int main(int launchID) { - int ct; - int count = Control->count; - int rate = Control->rate; - float height = getHeight(); - struct point_s * p = (struct point_s *)point; - - if (rate) { - float rMax = ((float)rate) * 0.005f; - int x = Control->x; - int y = Control->y; - int color = ((int)(Control->r * 255.f)) | - ((int)(Control->g * 255.f)) << 8 | - ((int)(Control->b * 255.f)) << 16 | - (0xf0 << 24); - struct point_s * np = &p[newPart]; - - while (rate--) { - vec2Rand((float *)&np->delta.x, rMax); - np->position.x = x; - np->position.y = y; - np->color = color; - newPart++; - np++; - if (newPart >= count) { - newPart = 0; - np = &p[newPart]; - } - } - } - - for (ct=0; ct < count; ct++) { - float dy = p->delta.y + 0.15f; - float posy = p->position.y + dy; - if ((posy > height) && (dy > 0)) { - dy *= -0.3f; - } - p->delta.y = dy; - p->position.x += p->delta.x; - p->position.y = posy; - p++; - } - - uploadToBufferObject(NAMED_PartBuffer); - drawSimpleMesh(NAMED_PartMesh); - return 1; -} diff --git a/libs/rs/java/Fountain/res/raw/fountain2.rs b/libs/rs/java/Fountain/res/raw/fountain2.rs deleted file mode 100644 index 3301140..0000000 --- a/libs/rs/java/Fountain/res/raw/fountain2.rs +++ /dev/null @@ -1,73 +0,0 @@ -// Fountain test script -#pragma version(1) - -#include "rs_types.rsh" -#include "rs_math.rsh" -#include "rs_graphics.rsh" - -static int newPart = 0; - -typedef struct Control_s { - int x, y; - int rate; - int count; - float r, g, b; - rs_allocation partBuffer; - rs_mesh partMesh; -} Control_t; -Control_t *Control; - -typedef struct Point_s{ - float2 delta; - float2 position; - unsigned int color; -} Point_t; -Point_t *point; - -int main(int launchID) { - int ct; - int count = Control->count; - int rate = Control->rate; - float height = getHeight(); - Point_t * p = point; - - if (rate) { - float rMax = ((float)rate) * 0.005f; - int x = Control->x; - int y = Control->y; - int color = ((int)(Control->r * 255.f)) | - ((int)(Control->g * 255.f)) << 8 | - ((int)(Control->b * 255.f)) << 16 | - (0xf0 << 24); - Point_t * np = &p[newPart]; - - while (rate--) { - np->delta = vec2Rand(rMax); - np->position.x = x; - np->position.y = y; - np->color = color; - newPart++; - np++; - if (newPart >= count) { - newPart = 0; - np = &p[newPart]; - } - } - } - - for (ct=0; ct < count; ct++) { - float dy = p->delta.y + 0.15f; - float posy = p->position.y + dy; - if ((posy > height) && (dy > 0)) { - dy *= -0.3f; - } - p->delta.y = dy; - p->position.x += p->delta.x; - p->position.y = posy; - p++; - } - - uploadToBufferObject(Control->partBuffer); - drawSimpleMesh(Control->partMesh); - return 1; -} 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 9356579..0b26cfd 100644 --- a/libs/rs/java/Fountain/src/com/android/fountain/FountainRS.java +++ b/libs/rs/java/Fountain/src/com/android/fountain/FountainRS.java @@ -22,94 +22,50 @@ import android.util.Log; public class FountainRS { - public static final int PART_COUNT = 20000; - - static class SomeData { - public int x; - public int y; - public int rate; - public int count; - public float r; - public float g; - public float b; - } + public static final int PART_COUNT = 50000; public FountainRS() { } + private Resources mRes; + private RenderScriptGL mRS; + private ScriptC_fountain mScript; public void init(RenderScriptGL rs, Resources res, int width, int height) { mRS = rs; mRes = res; - initRS(); - } - - public void newTouchPosition(int x, int y, int rate) { - if (mSD.rate == 0) { - mSD.r = ((x & 0x1) != 0) ? 0.f : 1.f; - mSD.g = ((x & 0x2) != 0) ? 0.f : 1.f; - mSD.b = ((x & 0x4) != 0) ? 0.f : 1.f; - if ((mSD.r + mSD.g + mSD.b) < 0.9f) { - mSD.r = 0.8f; - mSD.g = 0.5f; - mSD.b = 1.f; - } - } - mSD.rate = rate; - mSD.x = x; - mSD.y = y; - mIntAlloc.data(mSD); - } - - - ///////////////////////////////////////// - - private Resources mRes; - - private RenderScriptGL mRS; - private Allocation mIntAlloc; - private SimpleMesh mSM; - private SomeData mSD; - private Type mSDType; - private void initRS() { - mSD = new SomeData(); - mSDType = Type.createFromClass(mRS, SomeData.class, 1, "SomeData"); - mIntAlloc = Allocation.createTyped(mRS, mSDType); - mSD.count = PART_COUNT; - mIntAlloc.data(mSD); + ProgramFragment.Builder pfb = new ProgramFragment.Builder(rs); + pfb.setVaryingColor(true); + rs.contextBindProgramFragment(pfb.create()); - Element.Builder eb = new Element.Builder(mRS); - eb.add(Element.createVector(mRS, Element.DataType.FLOAT_32, 2), "delta"); - eb.add(Element.createAttrib(mRS, Element.DataType.FLOAT_32, Element.DataKind.POSITION, 2), "position"); - eb.add(Element.createAttrib(mRS, Element.DataType.UNSIGNED_8, Element.DataKind.COLOR, 4), "color"); - Element primElement = eb.create(); + ScriptField_Point points = new ScriptField_Point(mRS, PART_COUNT); + Mesh.AllocationBuilder smb = new Mesh.AllocationBuilder(mRS); + smb.addVertexAllocation(points.getAllocation()); + smb.addIndexType(Primitive.POINT); + Mesh sm = smb.create(); - SimpleMesh.Builder smb = new SimpleMesh.Builder(mRS); - int vtxSlot = smb.addVertexType(primElement, PART_COUNT); - smb.setPrimitive(Primitive.POINT); - mSM = smb.create(); - mSM.setName("PartMesh"); - - Allocation partAlloc = mSM.createVertexAllocation(vtxSlot); - partAlloc.setName("PartBuffer"); - mSM.bindVertexAllocation(partAlloc, 0); + mScript = new ScriptC_fountain(mRS, mRes, R.raw.fountain, true); + mScript.set_partMesh(sm); + mScript.bind_point(points); + mRS.contextBindRootScript(mScript); + } - // All setup of named objects should be done by this point - // because we are about to compile the script. - ScriptC.Builder sb = new ScriptC.Builder(mRS); - sb.setScript(mRes, R.raw.fountain); - sb.setRoot(true); - sb.setType(mSDType, "Control", 0); - sb.setType(mSM.getVertexType(0), "point", 1); - Script script = sb.create(); - script.setClearColor(0.0f, 0.0f, 0.0f, 1.0f); + boolean holdingColor[] = new boolean[10]; + public void newTouchPosition(float x, float y, float pressure, int id) { + if (id > holdingColor.length) { + return; + } + int rate = (int)(pressure * pressure * 500.f); + if(rate > 500) { + rate = 500; + } + if (rate > 0) { + mScript.invoke_addParticles(rate, x, y, id, !holdingColor[id]); + holdingColor[id] = true; + } else { + holdingColor[id] = false; + } - script.bindAllocation(mIntAlloc, 0); - script.bindAllocation(partAlloc, 1); - mRS.contextBindRootScript(script); } - } - - diff --git a/libs/rs/java/Fountain/src/com/android/fountain/FountainView.java b/libs/rs/java/Fountain/src/com/android/fountain/FountainView.java index dfd6a49..c141165 100644 --- a/libs/rs/java/Fountain/src/com/android/fountain/FountainView.java +++ b/libs/rs/java/Fountain/src/com/android/fountain/FountainView.java @@ -71,17 +71,33 @@ public class FountainView extends RSSurfaceView { @Override public boolean onTouchEvent(MotionEvent ev) { - int act = ev.getAction(); + int act = ev.getActionMasked(); if (act == ev.ACTION_UP) { - mRender.newTouchPosition(0, 0, 0); + mRender.newTouchPosition(0, 0, 0, ev.getPointerId(0)); return false; + } else if (act == MotionEvent.ACTION_POINTER_UP) { + // only one pointer going up, we can get the index like this + int pointerIndex = ev.getActionIndex(); + int pointerId = ev.getPointerId(pointerIndex); + mRender.newTouchPosition(0, 0, 0, pointerId); } - float rate = (ev.getPressure() * 50.f); - rate *= rate; - if(rate > 2000.f) { - rate = 2000.f; + int count = ev.getHistorySize(); + int pcount = ev.getPointerCount(); + + for (int p=0; p < pcount; p++) { + int id = ev.getPointerId(p); + mRender.newTouchPosition(ev.getX(p), + ev.getY(p), + ev.getPressure(p), + id); + + for (int i=0; i < count; i++) { + mRender.newTouchPosition(ev.getHistoricalX(p, i), + ev.getHistoricalY(p, i), + ev.getHistoricalPressure(p, i), + id); + } } - mRender.newTouchPosition((int)ev.getX(), (int)ev.getY(), (int)rate); return true; } } diff --git a/libs/rs/java/Fountain/src/com/android/fountain/fountain.rs b/libs/rs/java/Fountain/src/com/android/fountain/fountain.rs new file mode 100644 index 0000000..812cb7a --- /dev/null +++ b/libs/rs/java/Fountain/src/com/android/fountain/fountain.rs @@ -0,0 +1,72 @@ +// Fountain test script +#pragma version(1) + +#pragma rs java_package_name(com.android.fountain) + +#pragma stateFragment(parent) + +#include "rs_graphics.rsh" + +static int newPart = 0; +rs_mesh partMesh; + +typedef struct __attribute__((packed, aligned(4))) Point { + float2 delta; + float2 position; + uchar4 color; +} Point_t; +Point_t *point; + +#pragma rs export_var(point, partMesh) +#pragma rs export_func(addParticles) + +int root() { + float dt = min(rsGetDt(), 0.1f); + rsgClearColor(0.f, 0.f, 0.f, 1.f); + const float height = rsgGetHeight(); + const int size = rsAllocationGetDimX(rsGetAllocation(point)); + float dy2 = dt * (10.f); + Point_t * p = point; + for (int ct=0; ct < size; ct++) { + p->delta.y += dy2; + p->position += p->delta; + if ((p->position.y > height) && (p->delta.y > 0)) { + p->delta.y *= -0.3f; + } + p++; + } + + rsgDrawMesh(partMesh); + return 1; +} + +static float4 partColor[10]; +void addParticles(int rate, float x, float y, int index, bool newColor) +{ + if (newColor) { + partColor[index].x = rsRand(0.5f, 1.0f); + partColor[index].y = rsRand(1.0f); + partColor[index].z = rsRand(1.0f); + } + float rMax = ((float)rate) * 0.02f; + int size = rsAllocationGetDimX(rsGetAllocation(point)); + uchar4 c = rsPackColorTo8888(partColor[index]); + + Point_t * np = &point[newPart]; + float2 p = {x, y}; + while (rate--) { + float angle = rsRand(3.14f * 2.f); + float len = rsRand(rMax); + np->delta.x = len * sin(angle); + np->delta.y = len * cos(angle); + np->position = p; + np->color = c; + newPart++; + np++; + if (newPart >= size) { + newPart = 0; + np = &point[newPart]; + } + } +} + diff --git a/libs/rs/java/ImageProcessing/Android.mk b/libs/rs/java/ImageProcessing/Android.mk index 833427b..7fa30d0 100644 --- a/libs/rs/java/ImageProcessing/Android.mk +++ b/libs/rs/java/ImageProcessing/Android.mk @@ -14,14 +14,19 @@ # limitations under the License. # +ifneq ($(TARGET_SIMULATOR),true) + LOCAL_PATH := $(call my-dir) include $(CLEAR_VARS) LOCAL_MODULE_TAGS := optional -LOCAL_SRC_FILES := $(call all-java-files-under, src) +LOCAL_SRC_FILES := $(call all-java-files-under, src) \ + $(call all-renderscript-files-under, src) #LOCAL_STATIC_JAVA_LIBRARIES := android.renderscript LOCAL_PACKAGE_NAME := ImageProcessing include $(BUILD_PACKAGE) + +endif diff --git a/libs/rs/java/ImageProcessing/AndroidManifest.xml b/libs/rs/java/ImageProcessing/AndroidManifest.xml index b48d208..d6a2db4 100644 --- a/libs/rs/java/ImageProcessing/AndroidManifest.xml +++ b/libs/rs/java/ImageProcessing/AndroidManifest.xml @@ -6,7 +6,8 @@ <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> <application android:label="Image Processing"> - <activity android:name="ImageProcessingActivity"> + <activity android:name="ImageProcessingActivity" + android:screenOrientation="portrait"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> diff --git a/libs/rs/java/ImageProcessing/res/drawable/data.jpg b/libs/rs/java/ImageProcessing/res/drawable/data.jpg Binary files differnew file mode 100644 index 0000000..81a87b1 --- /dev/null +++ b/libs/rs/java/ImageProcessing/res/drawable/data.jpg diff --git a/libs/rs/java/ImageProcessing/res/layout/main.xml b/libs/rs/java/ImageProcessing/res/layout/main.xml index 6770c18..c6ec729 100644 --- a/libs/rs/java/ImageProcessing/res/layout/main.xml +++ b/libs/rs/java/ImageProcessing/res/layout/main.xml @@ -25,9 +25,147 @@ android:id="@+id/display" android:layout_width="320dip" android:layout_height="266dip" /> - + + <Button + android:layout_marginBottom="170dip" + android:layout_width="wrap_content" + android:layout_height="40dip" + android:text="@string/benchmark" + android:onClick="benchmark" + android:layout_gravity="bottom"/> + + <TextView + android:id="@+id/benchmarkText" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:textSize="18sp" + android:layout_marginLeft="100dip" + android:layout_marginBottom="175dip" + android:layout_gravity="bottom" + android:text="@string/saturation"/> + + <SeekBar + android:id="@+id/inSaturation" + android:layout_marginBottom="140dip" + android:layout_marginLeft="10dip" + android:layout_marginRight="10dip" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:layout_gravity="bottom" /> + + <TextView + android:id="@+id/inSaturationText" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:textSize="18sp" + android:layout_marginLeft="50dip" + android:layout_marginBottom="142dip" + android:textColor="#000" + android:layout_gravity="bottom" + android:text="@string/saturation"/> + + <SeekBar + android:id="@+id/inGamma" + android:layout_marginBottom="110dip" + android:layout_marginLeft="10dip" + android:layout_marginRight="10dip" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:layout_gravity="bottom" /> + + <TextView + android:id="@+id/inGammaText" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:textSize="18sp" + android:layout_marginLeft="50dip" + android:layout_marginBottom="112dip" + android:textColor="#000" + android:layout_gravity="bottom" + android:text="@string/gamma"/> + <SeekBar - android:id="@+id/threshold" + android:id="@+id/outWhite" + android:layout_marginBottom="80dip" + android:layout_marginLeft="170dip" + android:layout_marginRight="10dip" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:layout_gravity="bottom" /> + + <TextView + android:id="@+id/outWhiteText" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:textSize="18sp" + android:layout_marginLeft="220dip" + android:layout_marginBottom="82dip" + android:textColor="#000" + android:layout_gravity="bottom" + android:text="@string/out_white"/> + + <SeekBar + android:id="@+id/inWhite" + android:layout_marginBottom="80dip" + android:layout_marginLeft="10dip" + android:layout_marginRight="170dip" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:layout_gravity="bottom" /> + + <TextView + android:id="@+id/inWhiteText" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:textSize="18sp" + android:layout_marginLeft="50dip" + android:layout_marginBottom="82dip" + android:textColor="#000" + android:layout_gravity="bottom" + android:text="@string/in_white"/> + + <SeekBar + android:id="@+id/outBlack" + android:layout_marginBottom="50dip" + android:layout_marginLeft="170dip" + android:layout_marginRight="10dip" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:layout_gravity="bottom" /> + + <TextView + android:id="@+id/outBlackText" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:textSize="18sp" + android:layout_marginLeft="220dip" + android:layout_marginBottom="52dip" + android:textColor="#000" + android:layout_gravity="bottom" + android:text="@string/out_black"/> + + <SeekBar + android:id="@+id/inBlack" + android:layout_marginBottom="50dip" + android:layout_marginLeft="10dip" + android:layout_marginRight="170dip" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:layout_gravity="bottom" /> + + <TextView + android:id="@+id/inBlackText" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:textSize="18sp" + android:layout_marginLeft="50dip" + android:layout_marginBottom="52dip" + android:textColor="#000" + android:layout_gravity="bottom" + android:text="@string/in_black"/> + + <SeekBar + android:id="@+id/radius" android:layout_marginBottom="10dip" android:layout_marginLeft="10dip" android:layout_marginRight="10dip" @@ -35,4 +173,15 @@ android:layout_height="wrap_content" android:layout_gravity="bottom" /> + <TextView + android:id="@+id/blurText" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:textSize="18sp" + android:layout_marginLeft="50dip" + android:layout_marginBottom="12dip" + android:textColor="#000" + android:layout_gravity="bottom" + android:text="@string/blur_description"/> + </merge>
\ No newline at end of file diff --git a/libs/rs/java/ImageProcessing/res/raw/threshold.rs b/libs/rs/java/ImageProcessing/res/raw/threshold.rs deleted file mode 100644 index 888f0cd..0000000 --- a/libs/rs/java/ImageProcessing/res/raw/threshold.rs +++ /dev/null @@ -1,62 +0,0 @@ -/* -// block of defines matching what RS will insert at runtime. -struct Params_s{ - int inHeight; - int inWidth; - int outHeight; - int outWidth; - float threshold; -}; -struct Params_s * Params; -struct InPixel_s{ - char a; - char b; - char g; - char r; -}; -struct InPixel_s * InPixel; -struct OutPixel_s{ - char a; - char b; - char g; - char r; -}; -struct OutPixel_s * OutPixel; -*/ - -struct color_s { - char b; - char g; - char r; - char a; -}; - -void main() { - int t = uptimeMillis(); - - struct color_s *in = (struct color_s *) InPixel; - struct color_s *out = (struct color_s *) OutPixel; - - int count = Params->inWidth * Params->inHeight; - int i; - float threshold = (Params->threshold * 255.f); - - for (i = 0; i < count; i++) { - float luminance = 0.2125f * in->r + - 0.7154f * in->g + - 0.0721f * in->b; - if (luminance > threshold) { - *out = *in; - } else { - *((int *)out) = *((int *)in) & 0xff000000; - } - - in++; - out++; - } - - t= uptimeMillis() - t; - debugI32("Filter time", t); - - sendToClient(&count, 1, 4, 0); -} diff --git a/libs/rs/java/ImageProcessing/res/values/strings.xml b/libs/rs/java/ImageProcessing/res/values/strings.xml new file mode 100644 index 0000000..cc5cc4d --- /dev/null +++ b/libs/rs/java/ImageProcessing/res/values/strings.xml @@ -0,0 +1,33 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- +/* +* Copyright (C) 2008 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. +*/ +--> + +<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <!-- General --> + <skip /> + <!--slider label --> + <string name="blur_description">Blur Radius</string> + <string name="in_white">In White</string> + <string name="out_white">Out White</string> + <string name="in_black">In Black</string> + <string name="out_black">Out Black</string> + <string name="gamma">Gamma</string> + <string name="saturation">Saturation</string> + <string name="benchmark">Benchmark</string> + +</resources> diff --git a/libs/rs/java/ImageProcessing/src/com/android/rs/image/ImageProcessingActivity.java b/libs/rs/java/ImageProcessing/src/com/android/rs/image/ImageProcessingActivity.java index 9ce53d8..e806969 100644 --- a/libs/rs/java/ImageProcessing/src/com/android/rs/image/ImageProcessingActivity.java +++ b/libs/rs/java/ImageProcessing/src/com/android/rs/image/ImageProcessingActivity.java @@ -31,53 +31,56 @@ import android.view.SurfaceView; import android.view.SurfaceHolder; import android.widget.ImageView; import android.widget.SeekBar; +import android.widget.TextView; +import android.view.View; import java.lang.Math; -public class ImageProcessingActivity extends Activity implements SurfaceHolder.Callback { - private Bitmap mBitmap; - private Params mParams; - private Script.Invokable mInvokable; - private int[] mInData; - private int[] mOutData; +public class ImageProcessingActivity extends Activity + implements SurfaceHolder.Callback, + SeekBar.OnSeekBarChangeListener { + private Bitmap mBitmapIn; + private Bitmap mBitmapOut; + private Bitmap mBitmapScratch; + private ScriptC_threshold mScript; + private ScriptC_vertical_blur mScriptVBlur; + private ScriptC_horizontal_blur mScriptHBlur; + private int mRadius = 0; + private SeekBar mRadiusSeekBar; + + private float mInBlack = 0.0f; + private SeekBar mInBlackSeekBar; + private float mOutBlack = 0.0f; + private SeekBar mOutBlackSeekBar; + private float mInWhite = 255.0f; + private SeekBar mInWhiteSeekBar; + private float mOutWhite = 255.0f; + private SeekBar mOutWhiteSeekBar; + private float mGamma = 1.0f; + private SeekBar mGammaSeekBar; + + private float mSaturation = 1.0f; + private SeekBar mSaturationSeekBar; + + private TextView mBenchmarkResult; @SuppressWarnings({"FieldCanBeLocal"}) private RenderScript mRS; @SuppressWarnings({"FieldCanBeLocal"}) - private Type mParamsType; - @SuppressWarnings({"FieldCanBeLocal"}) - private Allocation mParamsAllocation; - @SuppressWarnings({"FieldCanBeLocal"}) private Type mPixelType; @SuppressWarnings({"FieldCanBeLocal"}) private Allocation mInPixelsAllocation; @SuppressWarnings({"FieldCanBeLocal"}) private Allocation mOutPixelsAllocation; + @SuppressWarnings({"FieldCanBeLocal"}) + private Allocation mScratchPixelsAllocation1; + private Allocation mScratchPixelsAllocation2; private SurfaceView mSurfaceView; private ImageView mDisplayView; - static class Params { - public int inWidth; - public int outWidth; - public int inHeight; - public int outHeight; - - public float threshold; - } - - static class Pixel { - public byte a; - public byte r; - public byte g; - public byte b; - } - class FilterCallback extends RenderScript.RSMessage { private Runnable mAction = new Runnable() { public void run() { - mOutPixelsAllocation.readData(mOutData); - mBitmap.setPixels(mOutData, 0, mParams.outWidth, 0, 0, - mParams.outWidth, mParams.outHeight); mDisplayView.invalidate(); } }; @@ -89,29 +92,218 @@ public class ImageProcessingActivity extends Activity implements SurfaceHolder.C } } - private void javaFilter() { + int in[]; + int interm[]; + int out[]; + int MAX_RADIUS = 25; + // Store our coefficients here + float gaussian[]; + + private long javaFilter() { + final int width = mBitmapIn.getWidth(); + final int height = mBitmapIn.getHeight(); + final int count = width * height; + + if (in == null) { + in = new int[count]; + interm = new int[count]; + out = new int[count]; + gaussian = new float[MAX_RADIUS * 2 + 1]; + mBitmapIn.getPixels(in, 0, width, 0, 0, width, height); + } + long t = java.lang.System.currentTimeMillis(); - int count = mParams.inWidth * mParams.inHeight; - float threshold = mParams.threshold * 255.f; - - for (int i = 0; i < count; i++) { - final float r = (float)((mInData[i] >> 0) & 0xff); - final float g = (float)((mInData[i] >> 8) & 0xff); - final float b = (float)((mInData[i] >> 16) & 0xff); - - final float luminance = 0.2125f * r + - 0.7154f * g + - 0.0721f * b; - if (luminance > threshold) { - mOutData[i] = mInData[i]; - } else { - mOutData[i] = mInData[i] & 0xff000000; + + int w, h, r; + + float fRadius = (float)mRadius; + int radius = (int)mRadius; + + // Compute gaussian weights for the blur + // e is the euler's number + float e = 2.718281828459045f; + float pi = 3.1415926535897932f; + // g(x) = ( 1 / sqrt( 2 * pi ) * sigma) * e ^ ( -x^2 / 2 * sigma^2 ) + // x is of the form [-radius .. 0 .. radius] + // and sigma varies with radius. + // Based on some experimental radius values and sigma's + // we approximately fit sigma = f(radius) as + // sigma = radius * 0.4 + 0.6 + // The larger the radius gets, the more our gaussian blur + // will resemble a box blur since with large sigma + // the gaussian curve begins to lose its shape + float sigma = 0.4f * fRadius + 0.6f; + // Now compute the coefficints + // We will store some redundant values to save some math during + // the blur calculations + // precompute some values + float coeff1 = 1.0f / (float)(Math.sqrt( 2.0f * pi ) * sigma); + float coeff2 = - 1.0f / (2.0f * sigma * sigma); + float normalizeFactor = 0.0f; + float floatR = 0.0f; + for(r = -radius; r <= radius; r ++) { + floatR = (float)r; + gaussian[r + radius] = coeff1 * (float)Math.pow(e, floatR * floatR * coeff2); + normalizeFactor += gaussian[r + radius]; + } + + //Now we need to normalize the weights because all our coefficients need to add up to one + normalizeFactor = 1.0f / normalizeFactor; + for(r = -radius; r <= radius; r ++) { + floatR = (float)r; + gaussian[r + radius] *= normalizeFactor; + } + + float blurredPixelR = 0.0f; + float blurredPixelG = 0.0f; + float blurredPixelB = 0.0f; + float blurredPixelA = 0.0f; + + for(h = 0; h < height; h ++) { + for(w = 0; w < width; w ++) { + + blurredPixelR = 0.0f; + blurredPixelG = 0.0f; + blurredPixelB = 0.0f; + blurredPixelA = 0.0f; + + for(r = -radius; r <= radius; r ++) { + // Stepping left and right away from the pixel + int validW = w + r; + // Clamp to zero and width max() isn't exposed for ints yet + if(validW < 0) { + validW = 0; + } + if(validW > width - 1) { + validW = width - 1; + } + + int input = in[h*width + validW]; + + int R = ((input >> 24) & 0xff); + int G = ((input >> 16) & 0xff); + int B = ((input >> 8) & 0xff); + int A = (input & 0xff); + + float weight = gaussian[r + radius]; + + blurredPixelR += (float)(R)*weight; + blurredPixelG += (float)(G)*weight; + blurredPixelB += (float)(B)*weight; + blurredPixelA += (float)(A)*weight; + } + + int R = (int)blurredPixelR; + int G = (int)blurredPixelG; + int B = (int)blurredPixelB; + int A = (int)blurredPixelA; + + interm[h*width + w] = (R << 24) | (G << 16) | (B << 8) | (A); + } + } + + for(h = 0; h < height; h ++) { + for(w = 0; w < width; w ++) { + + blurredPixelR = 0.0f; + blurredPixelG = 0.0f; + blurredPixelB = 0.0f; + blurredPixelA = 0.0f; + for(r = -radius; r <= radius; r ++) { + int validH = h + r; + // Clamp to zero and width + if(validH < 0) { + validH = 0; + } + if(validH > height - 1) { + validH = height - 1; + } + + int input = interm[validH*width + w]; + + int R = ((input >> 24) & 0xff); + int G = ((input >> 16) & 0xff); + int B = ((input >> 8) & 0xff); + int A = (input & 0xff); + + float weight = gaussian[r + radius]; + + blurredPixelR += (float)(R)*weight; + blurredPixelG += (float)(G)*weight; + blurredPixelB += (float)(B)*weight; + blurredPixelA += (float)(A)*weight; + } + + int R = (int)blurredPixelR; + int G = (int)blurredPixelG; + int B = (int)blurredPixelB; + int A = (int)blurredPixelA; + + out[h*width + w] = (R << 24) | (G << 16) | (B << 8) | (A); } } t = java.lang.System.currentTimeMillis() - t; + android.util.Log.v("Img", "Java frame time ms " + t); + mBitmapOut.setPixels(out, 0, width, 0, 0, width, height); + return t; + } + + public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) { + if (fromUser) { - android.util.Log.v("Img", "frame time ms " + t); + if(seekBar == mRadiusSeekBar) { + float fRadius = progress / 100.0f; + fRadius *= (float)(MAX_RADIUS); + mRadius = (int)fRadius; + + mScript.set_radius(mRadius); + } + else if(seekBar == mInBlackSeekBar) { + mInBlack = (float)progress; + mScriptVBlur.invoke_setLevels(mInBlack, mOutBlack, mInWhite, mOutWhite); + } + else if(seekBar == mOutBlackSeekBar) { + mOutBlack = (float)progress; + mScriptVBlur.invoke_setLevels(mInBlack, mOutBlack, mInWhite, mOutWhite); + } + else if(seekBar == mInWhiteSeekBar) { + mInWhite = (float)progress + 127.0f; + mScriptVBlur.invoke_setLevels(mInBlack, mOutBlack, mInWhite, mOutWhite); + } + else if(seekBar == mOutWhiteSeekBar) { + mOutWhite = (float)progress + 127.0f; + mScriptVBlur.invoke_setLevels(mInBlack, mOutBlack, mInWhite, mOutWhite); + } + else if(seekBar == mGammaSeekBar) { + mGamma = (float)progress/100.0f; + mGamma = Math.max(mGamma, 0.1f); + mGamma = 1.0f / mGamma; + mScriptVBlur.invoke_setGamma(mGamma); + } + else if(seekBar == mSaturationSeekBar) { + mSaturation = (float)progress / 50.0f; + mScriptVBlur.invoke_setSaturation(mSaturation); + } + + long t = java.lang.System.currentTimeMillis(); + if (true) { + mScript.invoke_filter(); + mRS.finish(); + } else { + javaFilter(); + mDisplayView.invalidate(); + } + + t = java.lang.System.currentTimeMillis() - t; + android.util.Log.v("Img", "Renderscript frame time core ms " + t); + } + } + + public void onStartTrackingTouch(SeekBar seekBar) { + } + + public void onStopTrackingTouch(SeekBar seekBar) { } @Override @@ -119,45 +311,54 @@ public class ImageProcessingActivity extends Activity implements SurfaceHolder.C super.onCreate(savedInstanceState); setContentView(R.layout.main); - mBitmap = loadBitmap(R.drawable.data); + mBitmapIn = loadBitmap(R.drawable.data); + mBitmapOut = loadBitmap(R.drawable.data); + mBitmapScratch = loadBitmap(R.drawable.data); mSurfaceView = (SurfaceView) findViewById(R.id.surface); mSurfaceView.getHolder().addCallback(this); mDisplayView = (ImageView) findViewById(R.id.display); - mDisplayView.setImageBitmap(mBitmap); - - ((SeekBar) findViewById(R.id.threshold)).setOnSeekBarChangeListener( - new SeekBar.OnSeekBarChangeListener() { - public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) { - if (fromUser) { - mParams.threshold = progress / 100.0f; - mParamsAllocation.data(mParams); - - if (true) { - mInvokable.execute(); - } else { - javaFilter(); - mBitmap.setPixels(mOutData, 0, mParams.outWidth, 0, 0, - mParams.outWidth, mParams.outHeight); - mDisplayView.invalidate(); - } - } - } - - public void onStartTrackingTouch(SeekBar seekBar) { - } - - public void onStopTrackingTouch(SeekBar seekBar) { - } - }); + mDisplayView.setImageBitmap(mBitmapOut); + + mRadiusSeekBar = (SeekBar) findViewById(R.id.radius); + mRadiusSeekBar.setOnSeekBarChangeListener(this); + + mInBlackSeekBar = (SeekBar)findViewById(R.id.inBlack); + mInBlackSeekBar.setOnSeekBarChangeListener(this); + mInBlackSeekBar.setMax(128); + mInBlackSeekBar.setProgress(0); + mOutBlackSeekBar = (SeekBar)findViewById(R.id.outBlack); + mOutBlackSeekBar.setOnSeekBarChangeListener(this); + mOutBlackSeekBar.setMax(128); + mOutBlackSeekBar.setProgress(0); + + mInWhiteSeekBar = (SeekBar)findViewById(R.id.inWhite); + mInWhiteSeekBar.setOnSeekBarChangeListener(this); + mInWhiteSeekBar.setMax(128); + mInWhiteSeekBar.setProgress(128); + mOutWhiteSeekBar = (SeekBar)findViewById(R.id.outWhite); + mOutWhiteSeekBar.setOnSeekBarChangeListener(this); + mOutWhiteSeekBar.setMax(128); + mOutWhiteSeekBar.setProgress(128); + + mGammaSeekBar = (SeekBar)findViewById(R.id.inGamma); + mGammaSeekBar.setOnSeekBarChangeListener(this); + mGammaSeekBar.setMax(150); + mGammaSeekBar.setProgress(100); + + mSaturationSeekBar = (SeekBar)findViewById(R.id.inSaturation); + mSaturationSeekBar.setOnSeekBarChangeListener(this); + mSaturationSeekBar.setProgress(50); + + mBenchmarkResult = (TextView) findViewById(R.id.benchmarkText); + mBenchmarkResult.setText("Benchmark not yet run"); } public void surfaceCreated(SurfaceHolder holder) { - mParams = createParams(); - mInvokable = createScript(); - - mInvokable.execute(); + createScript(); + mScript.invoke_filter(); + mRS.finish(); } public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { @@ -166,54 +367,38 @@ public class ImageProcessingActivity extends Activity implements SurfaceHolder.C public void surfaceDestroyed(SurfaceHolder holder) { } - private Script.Invokable createScript() { + private void createScript() { mRS = RenderScript.create(); mRS.mMessageCallback = new FilterCallback(); - mParamsType = Type.createFromClass(mRS, Params.class, 1, "Parameters"); - mParamsAllocation = Allocation.createTyped(mRS, mParamsType); - mParamsAllocation.data(mParams); - - final int pixelCount = mParams.inWidth * mParams.inHeight; - - mPixelType = Type.createFromClass(mRS, Pixel.class, 1, "Pixel"); - mInPixelsAllocation = Allocation.createSized(mRS, - Element.createUser(mRS, Element.DataType.SIGNED_32), - pixelCount); - mOutPixelsAllocation = Allocation.createSized(mRS, - Element.createUser(mRS, Element.DataType.SIGNED_32), - pixelCount); - - mInData = new int[pixelCount]; - mBitmap.getPixels(mInData, 0, mParams.inWidth, 0, 0, mParams.inWidth, mParams.inHeight); - mInPixelsAllocation.data(mInData); - - mOutData = new int[pixelCount]; - mOutPixelsAllocation.data(mOutData); - - ScriptC.Builder sb = new ScriptC.Builder(mRS); - sb.setType(mParamsType, "Params", 0); - sb.setType(mPixelType, "InPixel", 1); - sb.setType(mPixelType, "OutPixel", 2); - sb.setType(true, 2); - Script.Invokable invokable = sb.addInvokable("main"); - sb.setScript(getResources(), R.raw.threshold); - //sb.setRoot(true); - - ScriptC script = sb.create(); - script.bindAllocation(mParamsAllocation, 0); - script.bindAllocation(mInPixelsAllocation, 1); - script.bindAllocation(mOutPixelsAllocation, 2); - - return invokable; - } + mInPixelsAllocation = Allocation.createBitmapRef(mRS, mBitmapIn); + mOutPixelsAllocation = Allocation.createBitmapRef(mRS, mBitmapOut); + + Type.Builder tb = new Type.Builder(mRS, Element.F32_4(mRS)); + tb.add(android.renderscript.Dimension.X, mBitmapIn.getWidth()); + tb.add(android.renderscript.Dimension.Y, mBitmapIn.getHeight()); + mScratchPixelsAllocation1 = Allocation.createTyped(mRS, tb.create()); + mScratchPixelsAllocation2 = Allocation.createTyped(mRS, tb.create()); + + mScriptVBlur = new ScriptC_vertical_blur(mRS, getResources(), R.raw.vertical_blur, false); + mScriptHBlur = new ScriptC_horizontal_blur(mRS, getResources(), R.raw.horizontal_blur, false); + + mScript = new ScriptC_threshold(mRS, getResources(), R.raw.threshold, false); + mScript.set_width(mBitmapIn.getWidth()); + mScript.set_height(mBitmapIn.getHeight()); + mScript.set_radius(mRadius); + + mScriptVBlur.invoke_setLevels(mInBlack, mOutBlack, mInWhite, mOutWhite); + mScriptVBlur.invoke_setGamma(mGamma); + mScriptVBlur.invoke_setSaturation(mSaturation); + + mScript.bind_InPixel(mInPixelsAllocation); + mScript.bind_OutPixel(mOutPixelsAllocation); + mScript.bind_ScratchPixel1(mScratchPixelsAllocation1); + mScript.bind_ScratchPixel2(mScratchPixelsAllocation2); - private Params createParams() { - final Params params = new Params(); - params.inWidth = params.outWidth = mBitmap.getWidth(); - params.inHeight = params.outHeight = mBitmap.getHeight(); - params.threshold = 0.5f; - return params; + mScript.set_vBlurScript(mScriptVBlur); + mScript.set_hBlurScript(mScriptHBlur); } private Bitmap loadBitmap(int resource) { @@ -229,4 +414,30 @@ public class ImageProcessingActivity extends Activity implements SurfaceHolder.C source.recycle(); return b; } + + // button hook + public void benchmark(View v) { + android.util.Log.v("Img", "Benchmarking"); + int oldRadius = mRadius; + mRadius = MAX_RADIUS; + mScript.set_radius(mRadius); + + long t = java.lang.System.currentTimeMillis(); + + mScript.invoke_filter(); + mRS.finish(); + + t = java.lang.System.currentTimeMillis() - t; + android.util.Log.v("Img", "Renderscript frame time core ms " + t); + + //long javaTime = javaFilter(); + //mBenchmarkResult.setText("RS: " + t + " ms Java: " + javaTime + " ms"); + mBenchmarkResult.setText("RS: " + t + " ms"); + + mRadius = oldRadius; + mScript.set_radius(mRadius); + + mScript.invoke_filter(); + mRS.finish(); + } } diff --git a/libs/rs/java/ImageProcessing/src/com/android/rs/image/horizontal_blur.rs b/libs/rs/java/ImageProcessing/src/com/android/rs/image/horizontal_blur.rs new file mode 100644 index 0000000..cfffac8 --- /dev/null +++ b/libs/rs/java/ImageProcessing/src/com/android/rs/image/horizontal_blur.rs @@ -0,0 +1,30 @@ +#pragma version(1) + +#include "ip.rsh" + +void root(const void *v_in, void *v_out, const void *usrData, uint32_t x, uint32_t y) { + float4 *output = (float4 *)v_out; + const FilterStruct *fs = (const FilterStruct *)usrData; + const float4 *input = (const float4 *)rsGetElementAt(fs->ain, 0, y); + + float3 blurredPixel = 0; + const float *gPtr = fs->gaussian; + if ((x > fs->radius) && (x < (fs->width - fs->radius))) { + const float4 *i = input + (x - fs->radius); + for(int r = -fs->radius; r <= fs->radius; r ++) { + blurredPixel += i->xyz * gPtr[0]; + gPtr++; + i++; + } + } else { + for(int r = -fs->radius; r <= fs->radius; r ++) { + // Stepping left and right away from the pixel + int validW = rsClamp(x + r, (uint)0, (uint)(fs->width - 1)); + blurredPixel += input[validW].xyz * gPtr[0]; + gPtr++; + } + } + + output->xyz = blurredPixel; +} + diff --git a/libs/rs/java/ImageProcessing/src/com/android/rs/image/ip.rsh b/libs/rs/java/ImageProcessing/src/com/android/rs/image/ip.rsh new file mode 100644 index 0000000..1d7a719 --- /dev/null +++ b/libs/rs/java/ImageProcessing/src/com/android/rs/image/ip.rsh @@ -0,0 +1,15 @@ +#pragma rs java_package_name(com.android.rs.image) + +#define MAX_RADIUS 25 + +typedef struct FilterStruct_s { + rs_allocation ain; + + float *gaussian; //[MAX_RADIUS * 2 + 1]; + int height; + int width; + int radius; + +} FilterStruct; + + diff --git a/libs/rs/java/ImageProcessing/src/com/android/rs/image/threshold.rs b/libs/rs/java/ImageProcessing/src/com/android/rs/image/threshold.rs new file mode 100644 index 0000000..33945a5 --- /dev/null +++ b/libs/rs/java/ImageProcessing/src/com/android/rs/image/threshold.rs @@ -0,0 +1,97 @@ +#pragma version(1) + +#include "ip.rsh" + +int height; +int width; +int radius; + +uchar4 * InPixel; +uchar4 * OutPixel; +float4 * ScratchPixel1; +float4 * ScratchPixel2; + +#pragma rs export_var(height, width, radius, InPixel, OutPixel, ScratchPixel1, ScratchPixel2, vBlurScript, hBlurScript) +#pragma rs export_func(filter); + +rs_script vBlurScript; +rs_script hBlurScript; + +const int CMD_FINISHED = 1; + +// Store our coefficients here +static float gaussian[MAX_RADIUS * 2 + 1]; + + +static void computeGaussianWeights() { + // Compute gaussian weights for the blur + // e is the euler's number + float e = 2.718281828459045f; + float pi = 3.1415926535897932f; + // g(x) = ( 1 / sqrt( 2 * pi ) * sigma) * e ^ ( -x^2 / 2 * sigma^2 ) + // x is of the form [-radius .. 0 .. radius] + // and sigma varies with radius. + // Based on some experimental radius values and sigma's + // we approximately fit sigma = f(radius) as + // sigma = radius * 0.4 + 0.6 + // The larger the radius gets, the more our gaussian blur + // will resemble a box blur since with large sigma + // the gaussian curve begins to lose its shape + float sigma = 0.4f * (float)radius + 0.6f; + + // Now compute the coefficints + // We will store some redundant values to save some math during + // the blur calculations + // precompute some values + float coeff1 = 1.0f / (sqrt( 2.0f * pi ) * sigma); + float coeff2 = - 1.0f / (2.0f * sigma * sigma); + + float normalizeFactor = 0.0f; + float floatR = 0.0f; + int r; + for(r = -radius; r <= radius; r ++) { + floatR = (float)r; + gaussian[r + radius] = coeff1 * pow(e, floatR * floatR * coeff2); + normalizeFactor += gaussian[r + radius]; + } + + //Now we need to normalize the weights because all our coefficients need to add up to one + normalizeFactor = 1.0f / normalizeFactor; + for(r = -radius; r <= radius; r ++) { + floatR = (float)r; + gaussian[r + radius] *= normalizeFactor; + } +} + + +static void copyInput() { + RS_DEBUG_MARKER; + rs_allocation ain = rsGetAllocation(InPixel); + uint32_t dimx = rsAllocationGetDimX(ain); + uint32_t dimy = rsAllocationGetDimY(ain); + for(uint32_t y = 0; y < dimy; y++) { + for(uint32_t x = 0; x < dimx; x++) { + ScratchPixel1[x + y * dimx] = convert_float4(InPixel[x + y * dimx]); + } + } + RS_DEBUG_MARKER; +} + +void filter() { + copyInput(); + computeGaussianWeights(); + + FilterStruct fs; + fs.gaussian = gaussian; + fs.width = width; + fs.height = height; + fs.radius = radius; + + fs.ain = rsGetAllocation(ScratchPixel1); + rsForEach(hBlurScript, fs.ain, rsGetAllocation(ScratchPixel2), &fs); + + fs.ain = rsGetAllocation(ScratchPixel2); + rsForEach(vBlurScript, fs.ain, rsGetAllocation(OutPixel), &fs); + rsSendToClientBlocking(CMD_FINISHED); +} + diff --git a/libs/rs/java/ImageProcessing/src/com/android/rs/image/vertical_blur.rs b/libs/rs/java/ImageProcessing/src/com/android/rs/image/vertical_blur.rs new file mode 100644 index 0000000..d901d2a --- /dev/null +++ b/libs/rs/java/ImageProcessing/src/com/android/rs/image/vertical_blur.rs @@ -0,0 +1,92 @@ +#pragma version(1) + +#include "ip.rsh" + +static float inBlack; +static float outBlack; +static float inWhite; +static float outWhite; +static float3 gamma; +static float saturation; + +static float inWMinInB; +static float outWMinOutB; +static float overInWMinInB; +static rs_matrix3x3 colorMat; + +#pragma rs export_func(setLevels, setSaturation, setGamma); + +void setLevels(float iBlk, float oBlk, float iWht, float oWht) { + inBlack = iBlk; + outBlack = oBlk; + inWhite = iWht; + outWhite = oWht; + + inWMinInB = inWhite - inBlack; + outWMinOutB = outWhite - outBlack; + overInWMinInB = 1.f / inWMinInB; +} + +void setSaturation(float sat) { + saturation = sat; + + // Saturation + // Linear weights + //float rWeight = 0.3086f; + //float gWeight = 0.6094f; + //float bWeight = 0.0820f; + + // Gamma 2.2 weights (we haven't converted our image to linear space yet for perf reasons) + float rWeight = 0.299f; + float gWeight = 0.587f; + float bWeight = 0.114f; + + float oneMinusS = 1.0f - saturation; + rsMatrixSet(&colorMat, 0, 0, oneMinusS * rWeight + saturation); + rsMatrixSet(&colorMat, 0, 1, oneMinusS * rWeight); + rsMatrixSet(&colorMat, 0, 2, oneMinusS * rWeight); + rsMatrixSet(&colorMat, 1, 0, oneMinusS * gWeight); + rsMatrixSet(&colorMat, 1, 1, oneMinusS * gWeight + saturation); + rsMatrixSet(&colorMat, 1, 2, oneMinusS * gWeight); + rsMatrixSet(&colorMat, 2, 0, oneMinusS * bWeight); + rsMatrixSet(&colorMat, 2, 1, oneMinusS * bWeight); + rsMatrixSet(&colorMat, 2, 2, oneMinusS * bWeight + saturation); +} + +void setGamma(float g) { + gamma = (float3)g; +} + +void root(const void *v_in, void *v_out, const void *usrData, uint32_t x, uint32_t y) { + uchar4 *output = (uchar4 *)v_out; + const FilterStruct *fs = (const FilterStruct *)usrData; + const float4 *input = (const float4 *)rsGetElementAt(fs->ain, x, 0); + + float3 blurredPixel = 0; + const float *gPtr = fs->gaussian; + if ((y > fs->radius) && (y < (fs->height - fs->radius))) { + const float4 *i = input + ((y - fs->radius) * fs->width); + for(int r = -fs->radius; r <= fs->radius; r ++) { + blurredPixel += i->xyz * gPtr[0]; + gPtr++; + i += fs->width; + } + } else { + for(int r = -fs->radius; r <= fs->radius; r ++) { + int validH = rsClamp(y + r, (uint)0, (uint)(fs->height - 1)); + const float4 *i = input + validH * fs->width; + blurredPixel += i->xyz * gPtr[0]; + gPtr++; + } + } + + float3 temp = rsMatrixMultiply(&colorMat, blurredPixel); + temp = (clamp(temp, 0.f, 255.f) - inBlack) * overInWMinInB; + if (gamma.x != 1.0f) + temp = pow(temp, (float3)gamma); + temp = clamp(temp * outWMinOutB + outBlack, 0.f, 255.f); + + output->xyz = convert_uchar3(temp); + //output->w = input->w; +} + diff --git a/libs/rs/java/ModelViewer/Android.mk b/libs/rs/java/ModelViewer/Android.mk new file mode 100644 index 0000000..efe77d7 --- /dev/null +++ b/libs/rs/java/ModelViewer/Android.mk @@ -0,0 +1,31 @@ +# +# Copyright (C) 2008 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. +# + +ifneq ($(TARGET_SIMULATOR),true) + +LOCAL_PATH := $(call my-dir) +include $(CLEAR_VARS) + +LOCAL_MODULE_TAGS := optional + +LOCAL_SRC_FILES := $(call all-java-files-under, src) $(call all-renderscript-files-under, src) +#LOCAL_STATIC_JAVA_LIBRARIES := android.renderscript + +LOCAL_PACKAGE_NAME := ModelViewer + +include $(BUILD_PACKAGE) + +endif diff --git a/libs/rs/java/ModelViewer/AndroidManifest.xml b/libs/rs/java/ModelViewer/AndroidManifest.xml new file mode 100644 index 0000000..959fe53 --- /dev/null +++ b/libs/rs/java/ModelViewer/AndroidManifest.xml @@ -0,0 +1,23 @@ +<?xml version="1.0" encoding="utf-8"?> +<manifest xmlns:android="http://schemas.android.com/apk/res/android" + package="com.android.modelviewer"> + <application android:label="ModelViewer"> + <activity android:name="SimpleModel" + android:label="SimpleModel" + android:screenOrientation="portrait" + android:theme="@android:style/Theme.Black.NoTitleBar"> + <intent-filter> + <action android:name="android.intent.action.MAIN" /> + <category android:name="android.intent.category.LAUNCHER" /> + </intent-filter> + </activity> + <activity android:name="SceneGraph" + android:label="SceneGraph" + android:theme="@android:style/Theme.Black.NoTitleBar"> + <intent-filter> + <action android:name="android.intent.action.MAIN" /> + <category android:name="android.intent.category.LAUNCHER" /> + </intent-filter> + </activity> + </application> +</manifest> diff --git a/libs/rs/java/ModelViewer/res/drawable/robot.png b/libs/rs/java/ModelViewer/res/drawable/robot.png Binary files differnew file mode 100644 index 0000000..f7353fd --- /dev/null +++ b/libs/rs/java/ModelViewer/res/drawable/robot.png diff --git a/libs/rs/java/ModelViewer/res/raw/robot.a3d b/libs/rs/java/ModelViewer/res/raw/robot.a3d Binary files differnew file mode 100644 index 0000000..f48895c --- /dev/null +++ b/libs/rs/java/ModelViewer/res/raw/robot.a3d diff --git a/libs/rs/java/ModelViewer/src/com/android/modelviewer/SceneGraph.java b/libs/rs/java/ModelViewer/src/com/android/modelviewer/SceneGraph.java new file mode 100644 index 0000000..557e0cc --- /dev/null +++ b/libs/rs/java/ModelViewer/src/com/android/modelviewer/SceneGraph.java @@ -0,0 +1,71 @@ +/* + * Copyright (C) 2008 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.modelviewer; + +import android.renderscript.RSSurfaceView; +import android.renderscript.RenderScript; + +import android.app.Activity; +import android.content.res.Configuration; +import android.os.Bundle; +import android.os.Handler; +import android.os.Looper; +import android.os.Message; +import android.provider.Settings.System; +import android.util.Config; +import android.util.Log; +import android.view.Menu; +import android.view.MenuItem; +import android.view.View; +import android.view.Window; +import android.widget.Button; +import android.widget.ListView; + +import java.lang.Runtime; + +public class SceneGraph extends Activity { + + private SceneGraphView mView; + + @Override + public void onCreate(Bundle icicle) { + super.onCreate(icicle); + + // Create our Preview view and set it as the content of our + // Activity + mView = new SceneGraphView(this); + setContentView(mView); + } + + @Override + protected void onResume() { + // Ideally a game should implement onResume() and onPause() + // to take appropriate action when the activity looses focus + super.onResume(); + mView.onResume(); + } + + @Override + protected void onPause() { + // Ideally a game should implement onResume() and onPause() + // to take appropriate action when the activity looses focus + super.onPause(); + mView.onPause(); + } + +} + diff --git a/libs/rs/java/ModelViewer/src/com/android/modelviewer/SceneGraphRS.java b/libs/rs/java/ModelViewer/src/com/android/modelviewer/SceneGraphRS.java new file mode 100644 index 0000000..b5592f0 --- /dev/null +++ b/libs/rs/java/ModelViewer/src/com/android/modelviewer/SceneGraphRS.java @@ -0,0 +1,219 @@ +/* + * Copyright (C) 2008 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.modelviewer; + +import java.io.Writer; +import java.util.Map; +import java.util.Vector; + +import android.content.res.Resources; +import android.renderscript.*; +import android.renderscript.Element.Builder; +import android.renderscript.ProgramStore.DepthFunc; +import android.util.Log; + + +public class SceneGraphRS { + + private final int STATE_LAST_FOCUS = 1; + + int mWidth; + int mHeight; + int mRotation; + + public SceneGraphRS() { + } + + public void init(RenderScriptGL rs, Resources res, int width, int height) { + mRS = rs; + mRes = res; + mWidth = width; + mHeight = height; + mRotation = 0; + initRS(); + } + + private Resources mRes; + private RenderScriptGL mRS; + private Sampler mSampler; + private ProgramStore mPSBackground; + private ProgramFragment mPFBackground; + private ProgramVertex mPVBackground; + private ProgramVertex.MatrixAllocation mPVA; + + private Allocation mGridImage; + private Allocation mAllocPV; + + private Mesh mMesh; + + private Font mItalic; + private Allocation mTextAlloc; + + private ScriptC_scenegraph mScript; + private ScriptC_transform mTransformScript; + + int mLastX; + int mLastY; + + public void touchEvent(int x, int y) { + int dx = mLastX - x; + if(Math.abs(dx) > 50 || Math.abs(dx) < 3) { + dx = 0; + } + + mRotation -= dx; + if(mRotation > 360) { + mRotation -= 360; + } + if(mRotation < 0) { + mRotation += 360; + } + + mScript.set_gRotate(-(float)mRotation); + + mLastX = x; + mLastY = y; + } + + private void initPFS() { + ProgramStore.Builder b = new ProgramStore.Builder(mRS); + + b.setDepthFunc(ProgramStore.DepthFunc.LESS); + b.setDitherEnable(false); + b.setDepthMask(true); + mPSBackground = b.create(); + + mScript.set_gPFSBackground(mPSBackground); + } + + private void initPF() { + Sampler.Builder bs = new Sampler.Builder(mRS); + bs.setMin(Sampler.Value.LINEAR); + bs.setMag(Sampler.Value.LINEAR); + bs.setWrapS(Sampler.Value.CLAMP); + bs.setWrapT(Sampler.Value.CLAMP); + mSampler = bs.create(); + + ProgramFragment.Builder b = new ProgramFragment.Builder(mRS); + b.setTexture(ProgramFragment.Builder.EnvMode.REPLACE, + ProgramFragment.Builder.Format.RGBA, 0); + mPFBackground = b.create(); + mPFBackground.bindSampler(mSampler, 0); + + mScript.set_gPFBackground(mPFBackground); + } + + private void initPV() { + ProgramVertex.Builder pvb = new ProgramVertex.Builder(mRS); + mPVBackground = pvb.create(); + + mPVA = new ProgramVertex.MatrixAllocation(mRS); + mPVBackground.bindAllocation(mPVA); + + mScript.set_gPVBackground(mPVBackground); + } + + private void loadImage() { + mGridImage = Allocation.createFromBitmapResourceBoxed(mRS, mRes, R.drawable.robot, Element.RGB_565(mRS), true); + mGridImage.uploadToTexture(0); + + mScript.set_gTGrid(mGridImage); + } + + private void initTextAllocation() { + String allocString = "Displaying file: R.raw.robot"; + mTextAlloc = Allocation.createFromString(mRS, allocString); + mScript.set_gTextAlloc(mTextAlloc); + } + + SgTransform mRootTransform; + SgTransform mGroup1; + + SgTransform mRobot1; + SgTransform mRobot2; + + void initTransformHierarchy() { + mRootTransform = new SgTransform(mRS); + + mGroup1 = new SgTransform(mRS); + mRootTransform.addChild(mGroup1); + + mRobot1 = new SgTransform(mRS); + mRobot2 = new SgTransform(mRS); + + mGroup1.addChild(mRobot1); + mGroup1.addChild(mRobot2); + + mGroup1.setTransform(0, new Float4(0.0f, 0.0f, -15.0f, 0.0f), TransformType.TRANSLATE); + mGroup1.setTransform(1, new Float4(0.0f, 1.0f, 0.0f, 15.0f), TransformType.ROTATE); + + mRobot1.setTransform(0, new Float4(-3.0f, -0.5f, 0.0f, 0.0f), TransformType.TRANSLATE); + mRobot1.setTransform(1, new Float4(0.0f, 1.0f, 0.0f, 20.0f), TransformType.ROTATE); + mRobot1.setTransform(2, new Float4(0.2f, 0.2f, 0.2f, 0.0f), TransformType.SCALE); + + mRobot2.setTransform(0, new Float4(3.0f, 0.0f, 0.0f, 0.0f), TransformType.TRANSLATE); + mRobot2.setTransform(1, new Float4(0.0f, 1.0f, 0.0f, -20.0f), TransformType.ROTATE); + mRobot2.setTransform(2, new Float4(0.3f, 0.3f, 0.3f, 0.0f), TransformType.SCALE); + } + + private void initRS() { + + mScript = new ScriptC_scenegraph(mRS, mRes, R.raw.scenegraph, true); + mTransformScript = new ScriptC_transform(mRS, mRes, R.raw.transform, false); + mTransformScript.set_transformScript(mTransformScript); + + mScript.set_gTransformRS(mTransformScript); + + initPFS(); + initPF(); + initPV(); + + loadImage(); + + FileA3D model = FileA3D.createFromResource(mRS, mRes, R.raw.robot); + FileA3D.IndexEntry entry = model.getIndexEntry(0); + if(entry == null || entry.getClassID() != FileA3D.ClassID.MESH) { + Log.e("rs", "could not load model"); + } + else { + mMesh = (Mesh)entry.getObject(); + mScript.set_gTestMesh(mMesh); + } + + mItalic = Font.create(mRS, mRes, "DroidSerif-Italic.ttf", 8); + mScript.set_gItalic(mItalic); + + initTextAllocation(); + + initTransformHierarchy(); + + Log.v("========SceneGraph========", "transform hierarchy initialized"); + + mScript.bind_gRootNode(mRootTransform.getField()); + + mScript.bind_gGroup(mGroup1.mParent.mChildField); + mScript.bind_gRobot1(mRobot1.mParent.mChildField); + mScript.set_gRobot1Index(mRobot1.mIndexInParentGroup); + mScript.bind_gRobot2(mRobot2.mParent.mChildField); + mScript.set_gRobot2Index(mRobot2.mIndexInParentGroup); + + mRS.contextBindRootScript(mScript); + } +} + + + diff --git a/libs/rs/java/Film/src/com/android/film/FilmView.java b/libs/rs/java/ModelViewer/src/com/android/modelviewer/SceneGraphView.java index 5bc2811..44a59b2 100644 --- a/libs/rs/java/Film/src/com/android/film/FilmView.java +++ b/libs/rs/java/ModelViewer/src/com/android/modelviewer/SceneGraphView.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.android.film; +package com.android.modelviewer; import java.io.Writer; import java.util.ArrayList; @@ -39,15 +39,15 @@ import android.view.SurfaceView; import android.view.KeyEvent; import android.view.MotionEvent; -public class FilmView extends RSSurfaceView { +public class SceneGraphView extends RSSurfaceView { - public FilmView(Context context) { + public SceneGraphView(Context context) { super(context); //setFocusable(true); } private RenderScriptGL mRS; - private FilmRS mRender; + private SceneGraphRS mRender; public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) { @@ -55,7 +55,7 @@ public class FilmView extends RSSurfaceView { if (mRS == null) { mRS = createRenderScript(true); mRS.contextSetSurface(w, h, holder.getSurface()); - mRender = new FilmRS(); + mRender = new SceneGraphRS(); mRender.init(mRS, getResources(), w, h); } } @@ -85,7 +85,8 @@ public class FilmView extends RSSurfaceView { if (act == ev.ACTION_UP) { ret = false; } - mRender.setFilmStripPosition((int)ev.getX(), (int)ev.getY() / 5); + + mRender.touchEvent((int)ev.getX(), (int)ev.getY()); return ret; } } diff --git a/libs/rs/java/ModelViewer/src/com/android/modelviewer/SgTransform.java b/libs/rs/java/ModelViewer/src/com/android/modelviewer/SgTransform.java new file mode 100644 index 0000000..e70e811 --- /dev/null +++ b/libs/rs/java/ModelViewer/src/com/android/modelviewer/SgTransform.java @@ -0,0 +1,158 @@ +/* + * Copyright (C) 2008 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.modelviewer; + +import java.io.Writer; +import java.util.Map; +import java.util.Vector; + +import android.content.res.Resources; +import android.renderscript.*; +import android.renderscript.Element.Builder; +import android.renderscript.ProgramStore.DepthFunc; +import android.util.Log; + +enum TransformType { + + NONE(0), + TRANSLATE(1), + ROTATE(2), + SCALE(3); + + int mID; + TransformType(int id) { + mID = id; + } +} + +public class SgTransform { + + + ScriptField_SgTransform mTransformField; + ScriptField_SgTransform mChildField; + public ScriptField_SgTransform.Item mTransformData; + + Float4[] mTransforms; + TransformType[] mTransformTypes; + + RenderScript mRS; + + Vector mChildren; + SgTransform mParent; + int mIndexInParentGroup; + + public void setParent(SgTransform parent, int parentIndex) { + mParent = parent; + mIndexInParentGroup = parentIndex; + } + + public void addChild(SgTransform child) { + mChildren.add(child); + child.setParent(this, mChildren.size() - 1); + } + + public void setTransform(int index, Float4 value, TransformType type) { + mTransforms[index] = value; + mTransformTypes[index] = type; + } + + void initData() { + int numTransforms = 16; + mTransforms = new Float4[numTransforms]; + mTransformTypes = new TransformType[numTransforms]; + for(int i = 0; i < numTransforms; i ++) { + mTransforms[i] = new Float4(0, 0, 0, 0); + mTransformTypes[i] = TransformType.NONE; + } + } + + void setData() { + + mTransformData.globalMat = new Matrix4f(); + mTransformData.localMat = new Matrix4f(); + + mTransformData.transforms0 = mTransforms[0]; + mTransformData.transforms1 = mTransforms[1]; + mTransformData.transforms2 = mTransforms[2]; + mTransformData.transforms3 = mTransforms[3]; + mTransformData.transforms4 = mTransforms[4]; + mTransformData.transforms5 = mTransforms[5]; + mTransformData.transforms6 = mTransforms[6]; + mTransformData.transforms7 = mTransforms[7]; + mTransformData.transforms8 = mTransforms[8]; + mTransformData.transforms9 = mTransforms[9]; + mTransformData.transforms10 = mTransforms[10]; + mTransformData.transforms11 = mTransforms[11]; + mTransformData.transforms12 = mTransforms[12]; + mTransformData.transforms13 = mTransforms[13]; + mTransformData.transforms14 = mTransforms[14]; + mTransformData.transforms15 = mTransforms[15]; + + mTransformData.transformType0 = mTransformTypes[0].mID; + mTransformData.transformType1 = mTransformTypes[1].mID; + mTransformData.transformType2 = mTransformTypes[2].mID; + mTransformData.transformType3 = mTransformTypes[3].mID; + mTransformData.transformType4 = mTransformTypes[4].mID; + mTransformData.transformType5 = mTransformTypes[5].mID; + mTransformData.transformType6 = mTransformTypes[6].mID; + mTransformData.transformType7 = mTransformTypes[7].mID; + mTransformData.transformType8 = mTransformTypes[8].mID; + mTransformData.transformType9 = mTransformTypes[9].mID; + mTransformData.transformType10 = mTransformTypes[10].mID; + mTransformData.transformType11 = mTransformTypes[11].mID; + mTransformData.transformType12 = mTransformTypes[12].mID; + mTransformData.transformType13 = mTransformTypes[13].mID; + mTransformData.transformType14 = mTransformTypes[14].mID; + mTransformData.transformType15 = mTransformTypes[15].mID; + + mTransformData.isDirty = 1; + mTransformData.children = null; + + } + + public SgTransform(RenderScript rs) { + mRS = rs; + mTransformData = new ScriptField_SgTransform.Item(); + mChildren = new Vector(); + initData(); + } + + public ScriptField_SgTransform.Item getData() { + setData(); + if(mChildren.size() != 0) { + mChildField = new ScriptField_SgTransform(mRS, mChildren.size()); + mTransformData.children = mChildField.getAllocation(); + + for(int i = 0; i < mChildren.size(); i ++) { + SgTransform child = (SgTransform)mChildren.get(i); + mChildField.set(child.getData(), i, false); + } + mChildField.copyAll(); + } + + return mTransformData; + } + + public ScriptField_SgTransform getField() { + mTransformField = new ScriptField_SgTransform(mRS, 1); + mTransformField.set(getData(), 0, true); + return mTransformField; + } +} + + + diff --git a/libs/rs/java/ModelViewer/src/com/android/modelviewer/SimpleModel.java b/libs/rs/java/ModelViewer/src/com/android/modelviewer/SimpleModel.java new file mode 100644 index 0000000..cb7c39c --- /dev/null +++ b/libs/rs/java/ModelViewer/src/com/android/modelviewer/SimpleModel.java @@ -0,0 +1,71 @@ +/* + * Copyright (C) 2008 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.modelviewer; + +import android.renderscript.RSSurfaceView; +import android.renderscript.RenderScript; + +import android.app.Activity; +import android.content.res.Configuration; +import android.os.Bundle; +import android.os.Handler; +import android.os.Looper; +import android.os.Message; +import android.provider.Settings.System; +import android.util.Config; +import android.util.Log; +import android.view.Menu; +import android.view.MenuItem; +import android.view.View; +import android.view.Window; +import android.widget.Button; +import android.widget.ListView; + +import java.lang.Runtime; + +public class SimpleModel extends Activity { + + private SimpleModelView mView; + + @Override + public void onCreate(Bundle icicle) { + super.onCreate(icicle); + + // Create our Preview view and set it as the content of our + // Activity + mView = new SimpleModelView(this); + setContentView(mView); + } + + @Override + protected void onResume() { + // Ideally a game should implement onResume() and onPause() + // to take appropriate action when the activity looses focus + super.onResume(); + mView.onResume(); + } + + @Override + protected void onPause() { + // Ideally a game should implement onResume() and onPause() + // to take appropriate action when the activity looses focus + super.onPause(); + mView.onPause(); + } + +} + diff --git a/libs/rs/java/ModelViewer/src/com/android/modelviewer/SimpleModelRS.java b/libs/rs/java/ModelViewer/src/com/android/modelviewer/SimpleModelRS.java new file mode 100644 index 0000000..afbf30b --- /dev/null +++ b/libs/rs/java/ModelViewer/src/com/android/modelviewer/SimpleModelRS.java @@ -0,0 +1,169 @@ +/* + * Copyright (C) 2008 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.modelviewer; + +import java.io.Writer; + +import android.content.res.Resources; +import android.renderscript.*; +import android.renderscript.ProgramStore.DepthFunc; +import android.util.Log; + + +public class SimpleModelRS { + + private final int STATE_LAST_FOCUS = 1; + + int mWidth; + int mHeight; + int mRotation; + + public SimpleModelRS() { + } + + public void init(RenderScriptGL rs, Resources res, int width, int height) { + mRS = rs; + mRes = res; + mWidth = width; + mHeight = height; + mRotation = 0; + initRS(); + } + + private Resources mRes; + private RenderScriptGL mRS; + private Sampler mSampler; + private ProgramStore mPSBackground; + private ProgramFragment mPFBackground; + private ProgramVertex mPVBackground; + private ProgramVertex.MatrixAllocation mPVA; + + private Allocation mGridImage; + private Allocation mAllocPV; + + private Mesh mMesh; + + private Font mItalic; + private Allocation mTextAlloc; + + private ScriptC_simplemodel mScript; + + int mLastX; + int mLastY; + + public void touchEvent(int x, int y) { + int dx = mLastX - x; + if(Math.abs(dx) > 50 || Math.abs(dx) < 3) { + dx = 0; + } + + mRotation -= dx; + if(mRotation > 360) { + mRotation -= 360; + } + if(mRotation < 0) { + mRotation += 360; + } + + mScript.set_gRotate((float)mRotation); + + mLastX = x; + mLastY = y; + } + + private void initPFS() { + ProgramStore.Builder b = new ProgramStore.Builder(mRS); + + b.setDepthFunc(ProgramStore.DepthFunc.LESS); + b.setDitherEnable(false); + b.setDepthMask(true); + mPSBackground = b.create(); + + mScript.set_gPFSBackground(mPSBackground); + } + + private void initPF() { + Sampler.Builder bs = new Sampler.Builder(mRS); + bs.setMin(Sampler.Value.LINEAR); + bs.setMag(Sampler.Value.LINEAR); + bs.setWrapS(Sampler.Value.CLAMP); + bs.setWrapT(Sampler.Value.CLAMP); + mSampler = bs.create(); + + ProgramFragment.Builder b = new ProgramFragment.Builder(mRS); + b.setTexture(ProgramFragment.Builder.EnvMode.REPLACE, + ProgramFragment.Builder.Format.RGBA, 0); + mPFBackground = b.create(); + mPFBackground.bindSampler(mSampler, 0); + + mScript.set_gPFBackground(mPFBackground); + } + + private void initPV() { + ProgramVertex.Builder pvb = new ProgramVertex.Builder(mRS); + mPVBackground = pvb.create(); + + mPVA = new ProgramVertex.MatrixAllocation(mRS); + mPVBackground.bindAllocation(mPVA); + + mScript.set_gPVBackground(mPVBackground); + } + + private void loadImage() { + mGridImage = Allocation.createFromBitmapResourceBoxed(mRS, mRes, R.drawable.robot, Element.RGB_565(mRS), true); + mGridImage.uploadToTexture(0); + + mScript.set_gTGrid(mGridImage); + } + + private void initTextAllocation() { + String allocString = "Displaying file: R.raw.robot"; + mTextAlloc = Allocation.createFromString(mRS, allocString); + mScript.set_gTextAlloc(mTextAlloc); + } + + private void initRS() { + + mScript = new ScriptC_simplemodel(mRS, mRes, R.raw.simplemodel, true); + + initPFS(); + initPF(); + initPV(); + + loadImage(); + + FileA3D model = FileA3D.createFromResource(mRS, mRes, R.raw.robot); + FileA3D.IndexEntry entry = model.getIndexEntry(0); + if(entry == null || entry.getClassID() != FileA3D.ClassID.MESH) { + Log.e("rs", "could not load model"); + } + else { + mMesh = (Mesh)entry.getObject(); + mScript.set_gTestMesh(mMesh); + } + + mItalic = Font.create(mRS, mRes, "DroidSerif-Italic.ttf", 8); + mScript.set_gItalic(mItalic); + + initTextAllocation(); + + mRS.contextBindRootScript(mScript); + } +} + + + diff --git a/libs/rs/java/ModelViewer/src/com/android/modelviewer/SimpleModelView.java b/libs/rs/java/ModelViewer/src/com/android/modelviewer/SimpleModelView.java new file mode 100644 index 0000000..2574fdd --- /dev/null +++ b/libs/rs/java/ModelViewer/src/com/android/modelviewer/SimpleModelView.java @@ -0,0 +1,94 @@ +/* + * Copyright (C) 2008 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.modelviewer; + +import java.io.Writer; +import java.util.ArrayList; +import java.util.concurrent.Semaphore; + +import android.renderscript.RSSurfaceView; +import android.renderscript.RenderScript; +import android.renderscript.RenderScriptGL; + +import android.content.Context; +import android.content.res.Resources; +import android.graphics.Bitmap; +import android.graphics.drawable.BitmapDrawable; +import android.graphics.drawable.Drawable; +import android.os.Handler; +import android.os.Message; +import android.util.AttributeSet; +import android.util.Log; +import android.view.Surface; +import android.view.SurfaceHolder; +import android.view.SurfaceView; +import android.view.KeyEvent; +import android.view.MotionEvent; + +public class SimpleModelView extends RSSurfaceView { + + public SimpleModelView(Context context) { + super(context); + //setFocusable(true); + } + + private RenderScriptGL mRS; + private SimpleModelRS mRender; + + + public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) { + super.surfaceChanged(holder, format, w, h); + if (mRS == null) { + mRS = createRenderScript(true); + mRS.contextSetSurface(w, h, holder.getSurface()); + mRender = new SimpleModelRS(); + mRender.init(mRS, getResources(), w, h); + } + } + + @Override + protected void onDetachedFromWindow() { + if(mRS != null) { + mRS = null; + destroyRenderScript(); + } + } + + @Override + public boolean onKeyDown(int keyCode, KeyEvent event) + { + // break point at here + // this method doesn't work when 'extends View' include 'extends ScrollView'. + return super.onKeyDown(keyCode, event); + } + + + @Override + public boolean onTouchEvent(MotionEvent ev) + { + boolean ret = true; + int act = ev.getAction(); + if (act == ev.ACTION_UP) { + ret = false; + } + + mRender.touchEvent((int)ev.getX(), (int)ev.getY()); + return ret; + } +} + + diff --git a/libs/rs/java/ModelViewer/src/com/android/modelviewer/scenegraph.rs b/libs/rs/java/ModelViewer/src/com/android/modelviewer/scenegraph.rs new file mode 100644 index 0000000..ce6bb1e --- /dev/null +++ b/libs/rs/java/ModelViewer/src/com/android/modelviewer/scenegraph.rs @@ -0,0 +1,96 @@ +// 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. + +#pragma version(1) + +#pragma rs java_package_name(com.android.modelviewer) + +#include "rs_graphics.rsh" +#include "transform_def.rsh" + +rs_program_vertex gPVBackground; +rs_program_fragment gPFBackground; + +rs_allocation gTGrid; +rs_mesh gTestMesh; + +rs_program_store gPFSBackground; + +float gRotate; + +rs_font gItalic; +rs_allocation gTextAlloc; + +rs_script gTransformRS; + +SgTransform *gGroup; +SgTransform *gRobot1; +int gRobot1Index; +SgTransform *gRobot2; +int gRobot2Index; + +SgTransform *gRootNode; + +#pragma rs export_var(gPVBackground, gPFBackground, gTGrid, gTestMesh, gPFSBackground, gRotate, gItalic, gTextAlloc, gTransformRS, gGroup, gRobot1, gRobot1Index, gRobot2, gRobot2Index, gRootNode) + +float gDT; +int64_t gLastTime; + +void init() { + gRotate = 0.0f; +} + +int root(int launchID) { + + gGroup->transforms1.w += 0.5f; + gGroup->isDirty = 1; + + SgTransform *robot1Ptr = gRobot1 + gRobot1Index; + + robot1Ptr->transforms1.w -= 1.5f; + robot1Ptr->isDirty = 1; + + SgTransform *robot2Ptr = gRobot2 + gRobot2Index; + robot2Ptr->transforms1.w += 2.5f; + robot2Ptr->isDirty = 1; + + rsForEach(gTransformRS, gRootNode->children, gRootNode->children, 0); + + rsgClearColor(1.0f, 1.0f, 1.0f, 1.0f); + rsgClearDepth(1.0f); + + rsgBindProgramVertex(gPVBackground); + rs_matrix4x4 proj; + float aspect = (float)rsgGetWidth() / (float)rsgGetHeight(); + rsMatrixLoadPerspective(&proj, 30.0f, aspect, 0.1f, 100.0f); + rsgProgramVertexLoadProjectionMatrix(&proj); + + rsgBindProgramFragment(gPFBackground); + rsgBindProgramStore(gPFSBackground); + rsgBindTexture(gPFBackground, 0, gTGrid); + + rsgProgramVertexLoadModelMatrix(&robot1Ptr->globalMat); + rsgDrawMesh(gTestMesh); + + rsgProgramVertexLoadModelMatrix(&robot2Ptr->globalMat); + rsgDrawMesh(gTestMesh); + + color(0.3f, 0.3f, 0.3f, 1.0f); + rsgDrawText("Renderscript transform test", 30, 695); + + rsgBindFont(gItalic); + rsgDrawText(gTextAlloc, 30, 730); + + return 10; +} diff --git a/libs/rs/java/ModelViewer/src/com/android/modelviewer/simplemodel.rs b/libs/rs/java/ModelViewer/src/com/android/modelviewer/simplemodel.rs new file mode 100644 index 0000000..43be266 --- /dev/null +++ b/libs/rs/java/ModelViewer/src/com/android/modelviewer/simplemodel.rs @@ -0,0 +1,76 @@ +// 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. + +#pragma version(1) + +#pragma rs java_package_name(com.android.modelviewer) + +#include "rs_graphics.rsh" + +rs_program_vertex gPVBackground; +rs_program_fragment gPFBackground; + +rs_allocation gTGrid; +rs_mesh gTestMesh; + +rs_program_store gPFSBackground; + +float gRotate; + +rs_font gItalic; +rs_allocation gTextAlloc; + +#pragma rs export_var(gPVBackground, gPFBackground, gTGrid, gTestMesh, gPFSBackground, gRotate, gItalic, gTextAlloc) + +float gDT; +int64_t gLastTime; + +void init() { + gRotate = 0.0f; +} + +int root(int launchID) { + + rsgClearColor(1.0f, 1.0f, 1.0f, 1.0f); + rsgClearDepth(1.0f); + + rsgBindProgramVertex(gPVBackground); + rs_matrix4x4 proj; + float aspect = (float)rsgGetWidth() / (float)rsgGetHeight(); + rsMatrixLoadPerspective(&proj, 30.0f, aspect, 0.1f, 100.0f); + rsgProgramVertexLoadProjectionMatrix(&proj); + + rsgBindProgramFragment(gPFBackground); + rsgBindProgramStore(gPFSBackground); + rsgBindTexture(gPFBackground, 0, gTGrid); + + rs_matrix4x4 matrix; + rsMatrixLoadIdentity(&matrix); + // Position our model on the screen + rsMatrixTranslate(&matrix, 0.0f, -0.3f, -10.0f); + rsMatrixScale(&matrix, 0.2f, 0.2f, 0.2f); + rsMatrixRotate(&matrix, 25.0f, 1.0f, 0.0f, 0.0f); + rsMatrixRotate(&matrix, gRotate, 0.0f, 1.0f, 0.0f); + rsgProgramVertexLoadModelMatrix(&matrix); + + rsgDrawMesh(gTestMesh); + + rsgFontColor(0.3f, 0.3f, 0.3f, 1.0f); + rsgDrawText("Renderscript model test", 30, 695); + + rsgBindFont(gItalic); + rsgDrawText(gTextAlloc, 30, 730); + + return 10; +} diff --git a/libs/rs/java/ModelViewer/src/com/android/modelviewer/transform.rs b/libs/rs/java/ModelViewer/src/com/android/modelviewer/transform.rs new file mode 100644 index 0000000..2ef29cf --- /dev/null +++ b/libs/rs/java/ModelViewer/src/com/android/modelviewer/transform.rs @@ -0,0 +1,102 @@ +// 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. + +#pragma version(1) + +#pragma rs java_package_name(com.android.modelviewer) + +#include "transform_def.rsh" + +rs_script transformScript; + +#pragma rs export_var(transformScript) + +typedef struct { + int changed; + rs_matrix4x4 *mat; +} ParentData; + +void appendTransformation(int type, float4 data, rs_matrix4x4 *mat) { + rs_matrix4x4 temp; + + switch(type) { + case TRANSFORM_TRANSLATE: + rsMatrixLoadTranslate(&temp, data.x, data.y, data.z); + break; + case TRANSFORM_ROTATE: + rsMatrixLoadRotate(&temp, data.w, data.x, data.y, data.z); + break; + case TRANSFORM_SCALE: + rsMatrixLoadScale(&temp, data.x, data.y, data.z); + break; + } + rsMatrixMultiply(mat, &temp); +} + +void root(const void *v_in, void *v_out, const void *usrData, uint32_t x, uint32_t y) { + + SgTransform *data = (SgTransform *)v_out; + const ParentData *parent = (const ParentData *)usrData; + + //rsDebug("Transform data", (int)data); + //rsDebug("Entering parent", (int)parent); + + rs_matrix4x4 *localMat = &data->localMat; + rs_matrix4x4 *globalMat = &data->globalMat; + + ParentData toChild; + toChild.changed = 0; + toChild.mat = globalMat; + + //rsDebug("Transform is dirty", data->isDirty); + + // Refresh matrices if dirty + if(data->isDirty) { + data->isDirty = 0; + toChild.changed = 1; + + // Reset our local matrix + rsMatrixLoadIdentity(localMat); + + float4 *transformSource = &data->transforms0; + int *transformTypes = &data->transformType0; + + for(int i = 0; i < 16; i ++) { + if(transformTypes[i] == TRANSFORM_NONE) { + break; + } + //rsDebug("Transform adding transformation", transformTypes[i]); + appendTransformation(transformTypes[i], transformSource[i], localMat); + } + } + + //rsDebug("Transform checking parent", (int)0); + + if(parent) { + if(parent->changed) { + toChild.changed = 1; + + rsMatrixLoad(globalMat, parent->mat); + rsMatrixMultiply(globalMat, localMat); + } + } + else { + rsMatrixLoad(globalMat, localMat); + } + + //rsDebug("Transform calling self with child ", (int)data->children.p); + if(data->children.p) { + rsForEach(transformScript, data->children, data->children, (void*)&toChild); + } +} diff --git a/libs/rs/java/ModelViewer/src/com/android/modelviewer/transform_def.rsh b/libs/rs/java/ModelViewer/src/com/android/modelviewer/transform_def.rsh new file mode 100644 index 0000000..5c872a7 --- /dev/null +++ b/libs/rs/java/ModelViewer/src/com/android/modelviewer/transform_def.rsh @@ -0,0 +1,66 @@ +// 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. + +#pragma version(1) + +#pragma rs java_package_name(com.android.modelviewer) + +#define TRANSFORM_NONE 0 +#define TRANSFORM_TRANSLATE 1 +#define TRANSFORM_ROTATE 2 +#define TRANSFORM_SCALE 3 + +typedef struct { + rs_matrix4x4 globalMat; + rs_matrix4x4 localMat; + + float4 transforms0; + float4 transforms1; + float4 transforms2; + float4 transforms3; + float4 transforms4; + float4 transforms5; + float4 transforms6; + float4 transforms7; + float4 transforms8; + float4 transforms9; + float4 transforms10; + float4 transforms11; + float4 transforms12; + float4 transforms13; + float4 transforms14; + float4 transforms15; + + int transformType0; + int transformType1; + int transformType2; + int transformType3; + int transformType4; + int transformType5; + int transformType6; + int transformType7; + int transformType8; + int transformType9; + int transformType10; + int transformType11; + int transformType12; + int transformType13; + int transformType14; + int transformType15; + + int isDirty; + + rs_allocation children; + +} SgTransform; diff --git a/libs/rs/java/Film/Android.mk b/libs/rs/java/Samples/Android.mk index 9e6ed7e..65ae734 100644 --- a/libs/rs/java/Film/Android.mk +++ b/libs/rs/java/Samples/Android.mk @@ -14,14 +14,18 @@ # limitations under the License. # +ifneq ($(TARGET_SIMULATOR),true) + LOCAL_PATH := $(call my-dir) include $(CLEAR_VARS) LOCAL_MODULE_TAGS := optional -LOCAL_SRC_FILES := $(call all-java-files-under, src) +LOCAL_SRC_FILES := $(call all-java-files-under, src) $(call all-renderscript-files-under, src) #LOCAL_STATIC_JAVA_LIBRARIES := android.renderscript -LOCAL_PACKAGE_NAME := Film +LOCAL_PACKAGE_NAME := Samples include $(BUILD_PACKAGE) + +endif diff --git a/libs/rs/java/Samples/AndroidManifest.xml b/libs/rs/java/Samples/AndroidManifest.xml new file mode 100644 index 0000000..be191f2 --- /dev/null +++ b/libs/rs/java/Samples/AndroidManifest.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="utf-8"?> +<manifest xmlns:android="http://schemas.android.com/apk/res/android" + package="com.android.samples"> + <application android:label="Samples" + android:icon="@drawable/test_pattern"> + <activity android:name="RsList" + android:label="RsList" + android:theme="@android:style/Theme.Black.NoTitleBar"> + <intent-filter> + <action android:name="android.intent.action.MAIN" /> + <category android:name="android.intent.category.LAUNCHER" /> + </intent-filter> + </activity> + + <activity android:name="RsRenderStates" + android:label="RsStates" + android:theme="@android:style/Theme.Black.NoTitleBar"> + <intent-filter> + <action android:name="android.intent.action.MAIN" /> + <category android:name="android.intent.category.LAUNCHER" /> + </intent-filter> + </activity> + </application> +</manifest> diff --git a/libs/rs/java/Samples/res/drawable/data.png b/libs/rs/java/Samples/res/drawable/data.png Binary files differnew file mode 100644 index 0000000..8e34714 --- /dev/null +++ b/libs/rs/java/Samples/res/drawable/data.png diff --git a/libs/rs/java/Samples/res/drawable/leaf.png b/libs/rs/java/Samples/res/drawable/leaf.png Binary files differnew file mode 100644 index 0000000..3cd3775 --- /dev/null +++ b/libs/rs/java/Samples/res/drawable/leaf.png diff --git a/libs/rs/java/Samples/res/drawable/test_pattern.png b/libs/rs/java/Samples/res/drawable/test_pattern.png Binary files differnew file mode 100644 index 0000000..e7d1455 --- /dev/null +++ b/libs/rs/java/Samples/res/drawable/test_pattern.png diff --git a/libs/rs/java/Samples/res/drawable/torusmap.png b/libs/rs/java/Samples/res/drawable/torusmap.png Binary files differnew file mode 100644 index 0000000..1e08f3b --- /dev/null +++ b/libs/rs/java/Samples/res/drawable/torusmap.png diff --git a/libs/rs/java/Samples/res/raw/multitexf.glsl b/libs/rs/java/Samples/res/raw/multitexf.glsl new file mode 100644 index 0000000..91151ad --- /dev/null +++ b/libs/rs/java/Samples/res/raw/multitexf.glsl @@ -0,0 +1,12 @@ +varying vec4 varTex0; + +void main() { + vec2 t0 = varTex0.xy; + lowp vec4 col0 = texture2D(UNI_Tex0, t0).rgba; + lowp vec4 col1 = texture2D(UNI_Tex1, t0*4.0).rgba; + lowp vec4 col2 = texture2D(UNI_Tex2, t0).rgba; + col0.xyz = col0.xyz*col1.xyz*1.5; + col0.xyz = mix(col0.xyz, col2.xyz, col2.w); + gl_FragColor = col0; +} + diff --git a/libs/rs/java/Samples/res/raw/shaderf.glsl b/libs/rs/java/Samples/res/raw/shaderf.glsl new file mode 100644 index 0000000..fcbe7ee --- /dev/null +++ b/libs/rs/java/Samples/res/raw/shaderf.glsl @@ -0,0 +1,16 @@ + +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; + 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; + gl_FragColor = col; +} + diff --git a/libs/rs/java/Samples/res/raw/shaderv.glsl b/libs/rs/java/Samples/res/raw/shaderv.glsl new file mode 100644 index 0000000..867589c --- /dev/null +++ b/libs/rs/java/Samples/res/raw/shaderv.glsl @@ -0,0 +1,30 @@ +varying float light0_Diffuse; +varying float light0_Specular; +varying float light1_Diffuse; +varying float light1_Specular; +varying vec2 varTex0; + +// This is where actual shader code begins +void main() { + vec4 worldPos = UNI_model * ATTRIB_position; + 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; + vec3 V = normalize(-worldPos.xyz); + + vec3 light0Vec = normalize(UNI_light0_Posision - worldPos.xyz); + vec3 light0R = reflect(light0Vec, worldNorm); + light0_Diffuse = clamp(dot(worldNorm, light0Vec), 0.0, 1.0) * UNI_light0_Diffuse; + float light0Spec = clamp(dot(light0R, V), 0.001, 1.0); + light0_Specular = pow(light0Spec, UNI_light0_CosinePower) * UNI_light0_Specular; + + vec3 light1Vec = normalize(UNI_light1_Posision - worldPos.xyz); + vec3 light1R = reflect(light1Vec, worldNorm); + light1_Diffuse = clamp(dot(worldNorm, light1Vec), 0.0, 1.0) * UNI_light1_Diffuse; + float light1Spec = clamp(dot(light1R, V), 0.001, 1.0); + light1_Specular = pow(light1Spec, UNI_light1_CosinePower) * UNI_light1_Specular; + + gl_PointSize = 1.0; + varTex0 = ATTRIB_texture0; +} diff --git a/libs/rs/java/Samples/res/raw/torus.a3d b/libs/rs/java/Samples/res/raw/torus.a3d Binary files differnew file mode 100644 index 0000000..0322b01 --- /dev/null +++ b/libs/rs/java/Samples/res/raw/torus.a3d diff --git a/libs/rs/java/Samples/src/com/android/samples/RsList.java b/libs/rs/java/Samples/src/com/android/samples/RsList.java new file mode 100644 index 0000000..0f6b1ac --- /dev/null +++ b/libs/rs/java/Samples/src/com/android/samples/RsList.java @@ -0,0 +1,71 @@ +/* + * Copyright (C) 2008 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.samples; + +import android.renderscript.RSSurfaceView; +import android.renderscript.RenderScript; + +import android.app.Activity; +import android.content.res.Configuration; +import android.os.Bundle; +import android.os.Handler; +import android.os.Looper; +import android.os.Message; +import android.provider.Settings.System; +import android.util.Config; +import android.util.Log; +import android.view.Menu; +import android.view.MenuItem; +import android.view.View; +import android.view.Window; +import android.widget.Button; +import android.widget.ListView; + +import java.lang.Runtime; + +public class RsList extends Activity { + + private RsListView mView; + + @Override + public void onCreate(Bundle icicle) { + super.onCreate(icicle); + + // Create our Preview view and set it as the content of our + // Activity + mView = new RsListView(this); + setContentView(mView); + } + + @Override + protected void onResume() { + // Ideally a game should implement onResume() and onPause() + // to take appropriate action when the activity loses focus + super.onResume(); + mView.onResume(); + } + + @Override + protected void onPause() { + // Ideally a game should implement onResume() and onPause() + // to take appropriate action when the activity loses focus + super.onPause(); + mView.onPause(); + } + +} + diff --git a/libs/rs/java/Samples/src/com/android/samples/RsListRS.java b/libs/rs/java/Samples/src/com/android/samples/RsListRS.java new file mode 100644 index 0000000..aaeea87 --- /dev/null +++ b/libs/rs/java/Samples/src/com/android/samples/RsListRS.java @@ -0,0 +1,145 @@ +/* + * Copyright (C) 2008 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.samples; + +import java.io.Writer; +import java.util.Vector; + +import android.content.res.Resources; +import android.renderscript.*; +import android.renderscript.ProgramStore.DepthFunc; +import android.util.Log; + + +public class RsListRS { + + private final int STATE_LAST_FOCUS = 1; + + private static final String[] DATA_LIST = { + "Afghanistan", "Albania", "Algeria", "American Samoa", "Andorra", + "Angola", "Anguilla", "Antarctica", "Antigua and Barbuda", "Argentina", + "Armenia", "Aruba", "Australia", "Austria", "Azerbaijan", + "Bahrain", "Bangladesh", "Barbados", "Belarus", "Belgium", + "Belize", "Benin", "Bermuda", "Bhutan", "Bolivia", + "Bosnia and Herzegovina", "Botswana", "Bouvet Island", "Brazil", + "British Indian Ocean Territory", "British Virgin Islands", "Brunei", "Bulgaria", + "Burkina Faso", "Burundi", "Cote d'Ivoire", "Cambodia", "Cameroon", "Canada", "Cape Verde", + "Cayman Islands", "Central African Republic", "Chad", "Chile", "China", + "Christmas Island", "Cocos (Keeling) Islands", "Colombia", "Comoros", "Congo", + "Cook Islands", "Costa Rica", "Croatia", "Cuba", "Cyprus", "Czech Republic", + "Democratic Republic of the Congo", "Denmark", "Djibouti", "Dominica", "Dominican Republic", + "East Timor", "Ecuador", "Egypt", "El Salvador", "Equatorial Guinea", "Eritrea", + "Estonia", "Ethiopia", "Faeroe Islands", "Falkland Islands", "Fiji", "Finland", + "Former Yugoslav Republic of Macedonia", "France", "French Guiana", "French Polynesia", + "French Southern Territories", "Gabon", "Georgia", "Germany", "Ghana", "Gibraltar", + "Greece", "Greenland", "Grenada", "Guadeloupe", "Guam", "Guatemala", "Guinea", "Guinea-Bissau", + "Guyana", "Haiti", "Heard Island and McDonald Islands", "Honduras", "Hong Kong", "Hungary", + "Iceland", "India", "Indonesia", "Iran", "Iraq", "Ireland", "Israel", "Italy", "Jamaica", + "Japan", "Jordan", "Kazakhstan", "Kenya", "Kiribati", "Kuwait", "Kyrgyzstan", "Laos", + "Latvia", "Lebanon", "Lesotho", "Liberia", "Libya", "Liechtenstein", "Lithuania", "Luxembourg", + "Macau", "Madagascar", "Malawi", "Malaysia", "Maldives", "Mali", "Malta", "Marshall Islands", + "Martinique", "Mauritania", "Mauritius", "Mayotte", "Mexico", "Micronesia", "Moldova", + "Monaco", "Mongolia", "Montserrat", "Morocco", "Mozambique", "Myanmar", "Namibia", + "Nauru", "Nepal", "Netherlands", "Netherlands Antilles", "New Caledonia", "New Zealand", + "Nicaragua", "Niger", "Nigeria", "Niue", "Norfolk Island", "North Korea", "Northern Marianas", + "Norway", "Oman", "Pakistan", "Palau", "Panama", "Papua New Guinea", "Paraguay", "Peru", + "Philippines", "Pitcairn Islands", "Poland", "Portugal", "Puerto Rico", "Qatar", + "Reunion", "Romania", "Russia", "Rwanda", "Sqo Tome and Principe", "Saint Helena", + "Saint Kitts and Nevis", "Saint Lucia", "Saint Pierre and Miquelon", + "Saint Vincent and the Grenadines", "Samoa", "San Marino", "Saudi Arabia", "Senegal", + "Seychelles", "Sierra Leone", "Singapore", "Slovakia", "Slovenia", "Solomon Islands", + "Somalia", "South Africa", "South Georgia and the South Sandwich Islands", "South Korea", + "Spain", "Sri Lanka", "Sudan", "Suriname", "Svalbard and Jan Mayen", "Swaziland", "Sweden", + "Switzerland", "Syria", "Taiwan", "Tajikistan", "Tanzania", "Thailand", "The Bahamas", + "The Gambia", "Togo", "Tokelau", "Tonga", "Trinidad and Tobago", "Tunisia", "Turkey", + "Turkmenistan", "Turks and Caicos Islands", "Tuvalu", "Virgin Islands", "Uganda", + "Ukraine", "United Arab Emirates", "United Kingdom", + "United States", "United States Minor Outlying Islands", "Uruguay", "Uzbekistan", + "Vanuatu", "Vatican City", "Venezuela", "Vietnam", "Wallis and Futuna", "Western Sahara", + "Yemen", "Yugoslavia", "Zambia", "Zimbabwe" + }; + + int mWidth; + int mHeight; + + public RsListRS() { + } + + public void init(RenderScriptGL rs, Resources res, int width, int height) { + mRS = rs; + mRes = res; + mWidth = width; + mHeight = height; + initRS(); + } + + private Resources mRes; + private RenderScriptGL mRS; + private Font mItalic; + + ScriptField_ListAllocs_s mListAllocs; + + private ScriptC_rslist mScript; + + int mLastX; + int mLastY; + + public void onActionDown(int x, int y) { + mScript.set_gDY(0.0f); + + mLastX = x; + mLastY = y; + } + + public void onActionMove(int x, int y) { + int dx = mLastX - x; + int dy = mLastY - y; + + if(Math.abs(dy) <= 2) { + dy = 0; + } + + mScript.set_gDY(dy); + + mLastX = x; + mLastY = y; + } + + private void initRS() { + + mScript = new ScriptC_rslist(mRS, mRes, R.raw.rslist, true); + + mListAllocs = new ScriptField_ListAllocs_s(mRS, DATA_LIST.length); + for(int i = 0; i < DATA_LIST.length; i ++) { + ScriptField_ListAllocs_s.Item listElem = new ScriptField_ListAllocs_s.Item(); + listElem.text = Allocation.createFromString(mRS, DATA_LIST[i]); + mListAllocs.set(listElem, i, false); + } + + mListAllocs.copyAll(); + + mScript.bind_gList(mListAllocs); + + mItalic = Font.createFromFamily(mRS, mRes, "serif", Font.Style.BOLD_ITALIC, 8); + mScript.set_gItalic(mItalic); + + mRS.contextBindRootScript(mScript); + } +} + + + diff --git a/libs/rs/java/Samples/src/com/android/samples/RsListView.java b/libs/rs/java/Samples/src/com/android/samples/RsListView.java new file mode 100644 index 0000000..b98ea08 --- /dev/null +++ b/libs/rs/java/Samples/src/com/android/samples/RsListView.java @@ -0,0 +1,98 @@ +/* + * Copyright (C) 2008 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.samples; + +import java.io.Writer; +import java.util.ArrayList; +import java.util.concurrent.Semaphore; + +import android.renderscript.RSSurfaceView; +import android.renderscript.RenderScript; +import android.renderscript.RenderScriptGL; + +import android.content.Context; +import android.content.res.Resources; +import android.graphics.Bitmap; +import android.graphics.drawable.BitmapDrawable; +import android.graphics.drawable.Drawable; +import android.os.Handler; +import android.os.Message; +import android.util.AttributeSet; +import android.util.Log; +import android.view.Surface; +import android.view.SurfaceHolder; +import android.view.SurfaceView; +import android.view.KeyEvent; +import android.view.MotionEvent; + +public class RsListView extends RSSurfaceView { + + public RsListView(Context context) { + super(context); + //setFocusable(true); + } + + private RenderScriptGL mRS; + private RsListRS mRender; + + + public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) { + super.surfaceChanged(holder, format, w, h); + if (mRS == null) { + mRS = createRenderScript(true); + mRS.contextSetSurface(w, h, holder.getSurface()); + mRender = new RsListRS(); + mRender.init(mRS, getResources(), w, h); + } + } + + @Override + protected void onDetachedFromWindow() { + if(mRS != null) { + mRS = null; + destroyRenderScript(); + } + } + + @Override + public boolean onKeyDown(int keyCode, KeyEvent event) + { + // break point at here + // this method doesn't work when 'extends View' include 'extends ScrollView'. + return super.onKeyDown(keyCode, event); + } + + + @Override + public boolean onTouchEvent(MotionEvent ev) + { + boolean ret = false; + int act = ev.getAction(); + if (act == ev.ACTION_DOWN) { + mRender.onActionDown((int)ev.getX(), (int)ev.getY()); + ret = true; + } + else if (act == ev.ACTION_MOVE) { + mRender.onActionMove((int)ev.getX(), (int)ev.getY()); + ret = true; + } + + return ret; + } +} + + diff --git a/libs/rs/java/Samples/src/com/android/samples/RsRenderStates.java b/libs/rs/java/Samples/src/com/android/samples/RsRenderStates.java new file mode 100644 index 0000000..391007e --- /dev/null +++ b/libs/rs/java/Samples/src/com/android/samples/RsRenderStates.java @@ -0,0 +1,71 @@ +/* + * Copyright (C) 2008 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.samples; + +import android.renderscript.RSSurfaceView; +import android.renderscript.RenderScript; + +import android.app.Activity; +import android.content.res.Configuration; +import android.os.Bundle; +import android.os.Handler; +import android.os.Looper; +import android.os.Message; +import android.provider.Settings.System; +import android.util.Config; +import android.util.Log; +import android.view.Menu; +import android.view.MenuItem; +import android.view.View; +import android.view.Window; +import android.widget.Button; +import android.widget.ListView; + +import java.lang.Runtime; + +public class RsRenderStates extends Activity { + + private RsRenderStatesView mView; + + @Override + public void onCreate(Bundle icicle) { + super.onCreate(icicle); + + // Create our Preview view and set it as the content of our + // Activity + mView = new RsRenderStatesView(this); + setContentView(mView); + } + + @Override + protected void onResume() { + // Ideally a game should implement onResume() and onPause() + // to take appropriate action when the activity looses focus + super.onResume(); + mView.onResume(); + } + + @Override + protected void onPause() { + // Ideally a game should implement onResume() and onPause() + // to take appropriate action when the activity looses focus + super.onPause(); + mView.onPause(); + } + +} + diff --git a/libs/rs/java/Samples/src/com/android/samples/RsRenderStatesRS.java b/libs/rs/java/Samples/src/com/android/samples/RsRenderStatesRS.java new file mode 100644 index 0000000..d4e83d3 --- /dev/null +++ b/libs/rs/java/Samples/src/com/android/samples/RsRenderStatesRS.java @@ -0,0 +1,331 @@ +/* + * Copyright (C) 2008 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.samples; + +import java.io.Writer; + +import android.content.res.Resources; +import android.renderscript.*; +import android.renderscript.ProgramStore.DepthFunc; +import android.util.Log; +import android.graphics.BitmapFactory; +import android.graphics.Bitmap; + + +public class RsRenderStatesRS { + + int mWidth; + int mHeight; + + public RsRenderStatesRS() { + } + + public void init(RenderScriptGL rs, Resources res, int width, int height) { + mRS = rs; + mRes = res; + mWidth = width; + mHeight = height; + mOptionsARGB.inScaled = false; + mOptionsARGB.inPreferredConfig = Bitmap.Config.ARGB_8888; + mMode = 0; + mMaxModes = 8; + initRS(); + } + + private Resources mRes; + private RenderScriptGL mRS; + + private Sampler mLinearClamp; + private Sampler mLinearWrap; + private Sampler mMipLinearWrap; + private Sampler mNearestClamp; + + private ProgramStore mProgStoreBlendNoneDepth; + private ProgramStore mProgStoreBlendNone; + private ProgramStore mProgStoreBlendAlpha; + private ProgramStore mProgStoreBlendAdd; + + private ProgramFragment mProgFragmentTexture; + private ProgramFragment mProgFragmentColor; + + private ProgramVertex mProgVertex; + private ProgramVertex.MatrixAllocation mPVA; + + // Custom shaders + private ProgramVertex mProgVertexCustom; + private ProgramFragment mProgFragmentCustom; + private ProgramFragment mProgFragmentMultitex; + private ScriptField_VertexShaderConstants_s mVSConst; + private ScriptField_FragentShaderConstants_s mFSConst; + + private ProgramRaster mCullBack; + private ProgramRaster mCullFront; + + private Allocation mTexTorus; + private Allocation mTexOpaque; + private Allocation mTexTransparent; + + private Allocation mAllocPV; + + private Mesh mMbyNMesh; + private Mesh mTorus; + + Font mFontSans; + Font mFontSerif; + Font mFontSerifBold; + Font mFontSerifItalic; + Font mFontSerifBoldItalic; + Font mFontMono; + + private Allocation mTextAlloc; + + private ScriptC_rsrenderstates mScript; + + private final BitmapFactory.Options mOptionsARGB = new BitmapFactory.Options(); + + int mMode; + int mMaxModes; + + public void onActionDown(int x, int y) { + mMode ++; + mMode = mMode % mMaxModes; + mScript.set_gDisplayMode(mMode); + } + + private Mesh getMbyNMesh(float width, float height, int wResolution, int hResolution) { + + Mesh.TriangleMeshBuilder tmb = new Mesh.TriangleMeshBuilder(mRS, + 2, Mesh.TriangleMeshBuilder.TEXTURE_0); + + for (int y = 0; y <= hResolution; y++) { + final float normalizedY = (float)y / hResolution; + final float yOffset = (normalizedY - 0.5f) * height; + for (int x = 0; x <= wResolution; x++) { + float normalizedX = (float)x / wResolution; + float xOffset = (normalizedX - 0.5f) * width; + tmb.setTexture(normalizedX, normalizedY); + tmb.addVertex(xOffset, yOffset); + } + } + + for (int y = 0; y < hResolution; y++) { + final int curY = y * (wResolution + 1); + final int belowY = (y + 1) * (wResolution + 1); + for (int x = 0; x < wResolution; x++) { + int curV = curY + x; + int belowV = belowY + x; + tmb.addTriangle(curV, belowV, curV + 1); + tmb.addTriangle(belowV, belowV + 1, curV + 1); + } + } + + return tmb.create(true); + } + + private void initProgramStore() { + // Use stock the stock program store object + mProgStoreBlendNoneDepth = ProgramStore.BLEND_NONE_DEPTH_TEST(mRS); + mProgStoreBlendNone = ProgramStore.BLEND_NONE_DEPTH_NO_DEPTH(mRS); + + // Create a custom program store + ProgramStore.Builder builder = new ProgramStore.Builder(mRS); + builder.setDepthFunc(ProgramStore.DepthFunc.ALWAYS); + builder.setBlendFunc(ProgramStore.BlendSrcFunc.SRC_ALPHA, + ProgramStore.BlendDstFunc.ONE_MINUS_SRC_ALPHA); + builder.setDitherEnable(false); + builder.setDepthMask(false); + mProgStoreBlendAlpha = builder.create(); + + mProgStoreBlendAdd = ProgramStore.BLEND_ADD_DEPTH_NO_DEPTH(mRS); + + mScript.set_gProgStoreBlendNoneDepth(mProgStoreBlendNoneDepth); + mScript.set_gProgStoreBlendNone(mProgStoreBlendNone); + mScript.set_gProgStoreBlendAlpha(mProgStoreBlendAlpha); + mScript.set_gProgStoreBlendAdd(mProgStoreBlendAdd); + } + + private void initProgramFragment() { + + ProgramFragment.Builder texBuilder = new ProgramFragment.Builder(mRS); + texBuilder.setTexture(ProgramFragment.Builder.EnvMode.REPLACE, + ProgramFragment.Builder.Format.RGBA, 0); + mProgFragmentTexture = texBuilder.create(); + mProgFragmentTexture.bindSampler(mLinearClamp, 0); + + ProgramFragment.Builder colBuilder = new ProgramFragment.Builder(mRS); + colBuilder.setVaryingColor(false); + mProgFragmentColor = colBuilder.create(); + + mScript.set_gProgFragmentColor(mProgFragmentColor); + mScript.set_gProgFragmentTexture(mProgFragmentTexture); + } + + private void initProgramVertex() { + ProgramVertex.Builder pvb = new ProgramVertex.Builder(mRS); + mProgVertex = pvb.create(); + + mPVA = new ProgramVertex.MatrixAllocation(mRS); + mProgVertex.bindAllocation(mPVA); + mPVA.setupOrthoWindow(mWidth, mHeight); + + mScript.set_gProgVertex(mProgVertex); + } + + private void initCustomShaders() { + mVSConst = new ScriptField_VertexShaderConstants_s(mRS, 1); + mFSConst = new ScriptField_FragentShaderConstants_s(mRS, 1); + + mScript.bind_gVSConstants(mVSConst); + mScript.bind_gFSConstants(mFSConst); + + // Initialize the shader builder + ProgramVertex.ShaderBuilder pvbCustom = new ProgramVertex.ShaderBuilder(mRS); + // Specify the resource that contains the shader string + pvbCustom.setShader(mRes, R.raw.shaderv); + // Use a script field to spcify the input layout + pvbCustom.addInput(ScriptField_VertexShaderInputs_s.createElement(mRS)); + // Define the constant input layout + pvbCustom.addConstant(mVSConst.getAllocation().getType()); + mProgVertexCustom = pvbCustom.create(); + // Bind the source of constant data + mProgVertexCustom.bindConstants(mVSConst.getAllocation(), 0); + + ProgramFragment.ShaderBuilder pfbCustom = new ProgramFragment.ShaderBuilder(mRS); + // Specify the resource that contains the shader string + pfbCustom.setShader(mRes, R.raw.shaderf); + //Tell the builder how many textures we have + pfbCustom.setTextureCount(1); + // Define the constant input layout + pfbCustom.addConstant(mFSConst.getAllocation().getType()); + mProgFragmentCustom = pfbCustom.create(); + // Bind the source of constant data + mProgFragmentCustom.bindConstants(mFSConst.getAllocation(), 0); + + pfbCustom = new ProgramFragment.ShaderBuilder(mRS); + pfbCustom.setShader(mRes, R.raw.multitexf); + pfbCustom.setTextureCount(3); + mProgFragmentMultitex = pfbCustom.create(); + + mScript.set_gProgVertexCustom(mProgVertexCustom); + mScript.set_gProgFragmentCustom(mProgFragmentCustom); + mScript.set_gProgFragmentMultitex(mProgFragmentMultitex); + } + + private Allocation loadTextureRGB(int id) { + final Allocation allocation = Allocation.createFromBitmapResource(mRS, mRes, + id, Element.RGB_565(mRS), true); + allocation.uploadToTexture(0); + return allocation; + } + + private Allocation loadTextureARGB(int id) { + Bitmap b = BitmapFactory.decodeResource(mRes, id, mOptionsARGB); + final Allocation allocation = Allocation.createFromBitmap(mRS, b, Element.RGBA_8888(mRS), true); + allocation.uploadToTexture(0); + return allocation; + } + + private void loadImages() { + mTexTorus = loadTextureRGB(R.drawable.torusmap); + mTexOpaque = loadTextureRGB(R.drawable.data); + mTexTransparent = loadTextureARGB(R.drawable.leaf); + + mScript.set_gTexTorus(mTexTorus); + mScript.set_gTexOpaque(mTexOpaque); + mScript.set_gTexTransparent(mTexTransparent); + } + + private void initFonts() { + // Sans font by family name + mFontSans = Font.createFromFamily(mRS, mRes, "sans-serif", Font.Style.NORMAL, 8); + // Create font by file name + mFontSerif = Font.create(mRS, mRes, "DroidSerif-Regular.ttf", 8); + // Create fonts by family and style + mFontSerifBold = Font.createFromFamily(mRS, mRes, "serif", Font.Style.BOLD, 8); + mFontSerifItalic = Font.createFromFamily(mRS, mRes, "serif", Font.Style.ITALIC, 8); + mFontSerifBoldItalic = Font.createFromFamily(mRS, mRes, "serif", Font.Style.BOLD_ITALIC, 8); + mFontMono = Font.createFromFamily(mRS, mRes, "mono", Font.Style.NORMAL, 8); + + mScript.set_gFontSans(mFontSans); + mScript.set_gFontSerif(mFontSerif); + mScript.set_gFontSerifBold(mFontSerifBold); + mScript.set_gFontSerifItalic(mFontSerifItalic); + mScript.set_gFontSerifBoldItalic(mFontSerifBoldItalic); + mScript.set_gFontMono(mFontMono); + } + + private void initMesh() { + mMbyNMesh = getMbyNMesh(256, 256, 10, 10); + mScript.set_gMbyNMesh(mMbyNMesh); + + FileA3D model = FileA3D.createFromResource(mRS, mRes, R.raw.torus); + FileA3D.IndexEntry entry = model.getIndexEntry(0); + if(entry == null || entry.getClassID() != FileA3D.ClassID.MESH) { + Log.e("rs", "could not load model"); + } + else { + mTorus = (Mesh)entry.getObject(); + mScript.set_gTorusMesh(mTorus); + } + } + + private void initSamplers() { + Sampler.Builder bs = new Sampler.Builder(mRS); + bs.setMin(Sampler.Value.LINEAR); + bs.setMag(Sampler.Value.LINEAR); + bs.setWrapS(Sampler.Value.WRAP); + bs.setWrapT(Sampler.Value.WRAP); + mLinearWrap = bs.create(); + + mLinearClamp = Sampler.CLAMP_LINEAR(mRS); + mNearestClamp = Sampler.CLAMP_NEAREST(mRS); + mMipLinearWrap = Sampler.WRAP_LINEAR_MIP_LINEAR(mRS); + + mScript.set_gLinearClamp(mLinearClamp); + mScript.set_gLinearWrap(mLinearWrap); + mScript.set_gMipLinearWrap(mMipLinearWrap); + mScript.set_gNearestClamp(mNearestClamp); + } + + private void initProgramRaster() { + mCullBack = ProgramRaster.CULL_BACK(mRS); + mCullFront = ProgramRaster.CULL_FRONT(mRS); + + mScript.set_gCullBack(mCullBack); + mScript.set_gCullFront(mCullFront); + } + + private void initRS() { + + mScript = new ScriptC_rsrenderstates(mRS, mRes, R.raw.rsrenderstates, true); + + initSamplers(); + initProgramStore(); + initProgramFragment(); + initProgramVertex(); + initFonts(); + loadImages(); + initMesh(); + initProgramRaster(); + initCustomShaders(); + + mRS.contextBindRootScript(mScript); + } +} + + + diff --git a/libs/rs/java/Samples/src/com/android/samples/RsRenderStatesView.java b/libs/rs/java/Samples/src/com/android/samples/RsRenderStatesView.java new file mode 100644 index 0000000..5548de3 --- /dev/null +++ b/libs/rs/java/Samples/src/com/android/samples/RsRenderStatesView.java @@ -0,0 +1,94 @@ +/* + * Copyright (C) 2008 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.samples; + +import java.io.Writer; +import java.util.ArrayList; +import java.util.concurrent.Semaphore; + +import android.renderscript.RSSurfaceView; +import android.renderscript.RenderScript; +import android.renderscript.RenderScriptGL; + +import android.content.Context; +import android.content.res.Resources; +import android.graphics.Bitmap; +import android.graphics.drawable.BitmapDrawable; +import android.graphics.drawable.Drawable; +import android.os.Handler; +import android.os.Message; +import android.util.AttributeSet; +import android.util.Log; +import android.view.Surface; +import android.view.SurfaceHolder; +import android.view.SurfaceView; +import android.view.KeyEvent; +import android.view.MotionEvent; + +public class RsRenderStatesView extends RSSurfaceView { + + public RsRenderStatesView(Context context) { + super(context); + //setFocusable(true); + } + + private RenderScriptGL mRS; + private RsRenderStatesRS mRender; + + + public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) { + super.surfaceChanged(holder, format, w, h); + if (mRS == null) { + mRS = createRenderScript(true); + mRS.contextSetSurface(w, h, holder.getSurface()); + mRender = new RsRenderStatesRS(); + mRender.init(mRS, getResources(), w, h); + } + } + + @Override + protected void onDetachedFromWindow() { + if(mRS != null) { + mRS = null; + destroyRenderScript(); + } + } + + @Override + public boolean onKeyDown(int keyCode, KeyEvent event) + { + // break point at here + // this method doesn't work when 'extends View' include 'extends ScrollView'. + return super.onKeyDown(keyCode, event); + } + + + @Override + public boolean onTouchEvent(MotionEvent ev) + { + boolean ret = false; + int act = ev.getAction(); + if (act == ev.ACTION_DOWN) { + mRender.onActionDown((int)ev.getX(), (int)ev.getY()); + ret = true; + } + + return ret; + } +} + + diff --git a/libs/rs/java/Samples/src/com/android/samples/rslist.rs b/libs/rs/java/Samples/src/com/android/samples/rslist.rs new file mode 100644 index 0000000..3c3f463 --- /dev/null +++ b/libs/rs/java/Samples/src/com/android/samples/rslist.rs @@ -0,0 +1,73 @@ +// 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. + +#pragma version(1) + +#pragma rs java_package_name(com.android.samples) + +#include "rs_graphics.rsh" + +float gDY; + +rs_font gItalic; + +typedef struct ListAllocs_s { + rs_allocation text; +} ListAllocs; + +ListAllocs *gList; + +#pragma rs export_var(gDY, gItalic, gList) + +void init() { + gDY = 0.0f; +} + +int textPos = 0; + +int root(int launchID) { + + rsgClearColor(0.0f, 0.0f, 0.0f, 0.0f); + rsgClearDepth(1.0f); + + textPos -= (int)gDY*2; + gDY *= 0.95; + + rsgFontColor(0.9f, 0.9f, 0.9f, 1.0f); + rsgBindFont(gItalic); + color(0.2, 0.2, 0.2, 0); + + rs_allocation listAlloc = rsGetAllocation(gList); + int allocSize = rsAllocationGetDimX(listAlloc); + + int width = rsgGetWidth(); + int height = rsgGetHeight(); + + int itemHeight = 80; + int currentYPos = itemHeight + textPos; + + for(int i = 0; i < allocSize; i ++) { + if(currentYPos - itemHeight > height) { + break; + } + + if(currentYPos > 0) { + rsgDrawRect(0, currentYPos - 1, width, currentYPos, 0); + rsgDrawText(gList[i].text, 30, currentYPos - 32); + } + currentYPos += itemHeight; + } + + return 10; +} diff --git a/libs/rs/java/Samples/src/com/android/samples/rsrenderstates.rs b/libs/rs/java/Samples/src/com/android/samples/rsrenderstates.rs new file mode 100644 index 0000000..659e1e4 --- /dev/null +++ b/libs/rs/java/Samples/src/com/android/samples/rsrenderstates.rs @@ -0,0 +1,485 @@ +// 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. + +#pragma version(1) + +#pragma rs java_package_name(com.android.samples) + +#include "rs_graphics.rsh" +#include "shader_def.rsh" + +rs_program_vertex gProgVertex; +rs_program_fragment gProgFragmentColor; +rs_program_fragment gProgFragmentTexture; + +rs_program_store gProgStoreBlendNoneDepth; +rs_program_store gProgStoreBlendNone; +rs_program_store gProgStoreBlendAlpha; +rs_program_store gProgStoreBlendAdd; + +rs_allocation gTexOpaque; +rs_allocation gTexTorus; +rs_allocation gTexTransparent; + +rs_mesh gMbyNMesh; +rs_mesh gTorusMesh; + +rs_font gFontSans; +rs_font gFontSerif; +rs_font gFontSerifBold; +rs_font gFontSerifItalic; +rs_font gFontSerifBoldItalic; +rs_font gFontMono; + +int gDisplayMode; + +rs_sampler gLinearClamp; +rs_sampler gLinearWrap; +rs_sampler gMipLinearWrap; +rs_sampler gNearestClamp; + +rs_program_raster gCullBack; +rs_program_raster gCullFront; + +// Custom vertex shader compunents +VertexShaderConstants *gVSConstants; +FragentShaderConstants *gFSConstants; +// Export these out to easily set the inputs to shader +VertexShaderInputs *gVSInputs; +// Custom shaders we use for lighting +rs_program_vertex gProgVertexCustom; +rs_program_fragment gProgFragmentCustom; +rs_program_fragment gProgFragmentMultitex; + +#pragma rs export_var(gProgVertex, gProgFragmentColor, gProgFragmentTexture) +#pragma rs export_var(gProgStoreBlendNoneDepth, gProgStoreBlendNone, gProgStoreBlendAlpha, gProgStoreBlendAdd) +#pragma rs export_var(gTexOpaque, gTexTorus, gTexTransparent) +#pragma rs export_var(gMbyNMesh, gTorusMesh) +#pragma rs export_var(gFontSans, gFontSerif, gFontSerifBold, gFontSerifItalic, gFontSerifBoldItalic, gFontMono) +#pragma rs export_var(gLinearClamp, gLinearWrap, gMipLinearWrap, gNearestClamp) +#pragma rs export_var(gCullBack, gCullFront) +#pragma rs export_var(gVSConstants, gFSConstants, gVSInputs, gProgVertexCustom, gProgFragmentCustom, gProgFragmentMultitex) + +//What we are showing +#pragma rs export_var(gDisplayMode) + +float gDt = 0; + +void init() { +} + +void displayFontSamples() { + rsgFontColor(1.0f, 1.0f, 1.0f, 1.0f); + int yPos = 30; + rsgBindFont(gFontSans); + rsgDrawText("Sans font sample", 30, yPos); + yPos += 30; + rsgFontColor(0.5f, 0.9f, 0.5f, 1.0f); + rsgBindFont(gFontSerif); + rsgDrawText("Serif font sample", 30, yPos); + yPos += 30; + rsgFontColor(0.7f, 0.7f, 0.7f, 1.0f); + rsgBindFont(gFontSerifBold); + rsgDrawText("Serif Bold font sample", 30, yPos); + yPos += 30; + rsgFontColor(0.5f, 0.5f, 0.9f, 1.0f); + rsgBindFont(gFontSerifItalic); + rsgDrawText("Serif Italic font sample", 30, yPos); + yPos += 30; + rsgFontColor(1.0f, 1.0f, 1.0f, 1.0f); + rsgBindFont(gFontSerifBoldItalic); + rsgDrawText("Serif Bold Italic font sample", 30, yPos); + yPos += 30; + rsgBindFont(gFontMono); + rsgDrawText("Monospace font sample", 30, yPos); +} + +void bindProgramVertexOrtho() { + // Default vertex sahder + rsgBindProgramVertex(gProgVertex); + // Setup the projectioni matrix + rs_matrix4x4 proj; + rsMatrixLoadOrtho(&proj, 0, rsgGetWidth(), rsgGetHeight(), 0, -1,1); + rsgProgramVertexLoadProjectionMatrix(&proj); +} + +void displayShaderSamples() { + bindProgramVertexOrtho(); + rs_matrix4x4 matrix; + rsMatrixLoadIdentity(&matrix); + rsgProgramVertexLoadModelMatrix(&matrix); + + // Fragment shader with texture + rsgBindProgramStore(gProgStoreBlendNone); + rsgBindProgramFragment(gProgFragmentTexture); + rsgBindSampler(gProgFragmentTexture, 0, gLinearClamp); + rsgBindTexture(gProgFragmentTexture, 0, gTexOpaque); + + float startX = 0, startY = 0; + float width = 256, height = 256; + rsgDrawQuadTexCoords(startX, startY, 0, 0, 0, + startX, startY + height, 0, 0, 1, + startX + width, startY + height, 0, 1, 1, + startX + width, startY, 0, 1, 0); + + startX = 200; startY = 0; + width = 128; height = 128; + rsgDrawQuadTexCoords(startX, startY, 0, 0, 0, + startX, startY + height, 0, 0, 1, + startX + width, startY + height, 0, 1, 1, + startX + width, startY, 0, 1, 0); + + rsgBindProgramStore(gProgStoreBlendAlpha); + rsgBindTexture(gProgFragmentTexture, 0, gTexTransparent); + startX = 0; startY = 200; + width = 128; height = 128; + rsgDrawQuadTexCoords(startX, startY, 0, 0, 0, + startX, startY + height, 0, 0, 1, + startX + width, startY + height, 0, 1, 1, + startX + width, startY, 0, 1, 0); + + // Fragment program with simple color + rsgBindProgramFragment(gProgFragmentColor); + rsgProgramFragmentConstantColor(gProgFragmentColor, 0.9, 0.3, 0.3, 1); + rsgDrawRect(200, 300, 350, 450, 0); + rsgProgramFragmentConstantColor(gProgFragmentColor, 0.3, 0.9, 0.3, 1); + rsgDrawRect(50, 400, 400, 600, 0); + + rsgFontColor(1.0f, 1.0f, 1.0f, 1.0f); + rsgBindFont(gFontMono); + rsgDrawText("Texture shader", 10, 50); + rsgDrawText("Alpha-blended texture shader", 10, 280); + rsgDrawText("Flat color shader", 100, 450); +} + +void displayBlendingSamples() { + int i; + + bindProgramVertexOrtho(); + rs_matrix4x4 matrix; + rsMatrixLoadIdentity(&matrix); + rsgProgramVertexLoadModelMatrix(&matrix); + + rsgBindProgramFragment(gProgFragmentColor); + + rsgBindProgramStore(gProgStoreBlendNone); + for(i = 0; i < 3; i ++) { + float iPlusOne = (float)(i + 1); + rsgProgramFragmentConstantColor(gProgFragmentColor, + 0.1f*iPlusOne, 0.2f*iPlusOne, 0.3f*iPlusOne, 1); + float yPos = 150 * (float)i; + rsgDrawRect(0, yPos, 200, yPos + 200, 0); + } + + rsgBindProgramStore(gProgStoreBlendAlpha); + for(i = 0; i < 3; i ++) { + float iPlusOne = (float)(i + 1); + rsgProgramFragmentConstantColor(gProgFragmentColor, + 0.2f*iPlusOne, 0.3f*iPlusOne, 0.1f*iPlusOne, 0.5); + float yPos = 150 * (float)i; + rsgDrawRect(150, yPos, 350, yPos + 200, 0); + } + + rsgBindProgramStore(gProgStoreBlendAdd); + for(i = 0; i < 3; i ++) { + float iPlusOne = (float)(i + 1); + rsgProgramFragmentConstantColor(gProgFragmentColor, + 0.3f*iPlusOne, 0.1f*iPlusOne, 0.2f*iPlusOne, 0.5); + float yPos = 150 * (float)i; + rsgDrawRect(300, yPos, 500, yPos + 200, 0); + } + + + rsgFontColor(1.0f, 1.0f, 1.0f, 1.0f); + rsgBindFont(gFontMono); + rsgDrawText("No Blending", 10, 50); + rsgDrawText("Alpha Blending", 160, 150); + rsgDrawText("Additive Blending", 320, 250); + +} + +void displayMeshSamples() { + + bindProgramVertexOrtho(); + rs_matrix4x4 matrix; + rsMatrixLoadTranslate(&matrix, 128, 128, 0); + rsgProgramVertexLoadModelMatrix(&matrix); + + // Fragment shader with texture + rsgBindProgramStore(gProgStoreBlendNone); + rsgBindProgramFragment(gProgFragmentTexture); + rsgBindSampler(gProgFragmentTexture, 0, gLinearClamp); + rsgBindTexture(gProgFragmentTexture, 0, gTexOpaque); + + rsgDrawMesh(gMbyNMesh); + + rsgFontColor(1.0f, 1.0f, 1.0f, 1.0f); + rsgBindFont(gFontMono); + rsgDrawText("User gen 10 by 10 grid mesh", 10, 250); +} + +void displayTextureSamplers() { + + bindProgramVertexOrtho(); + rs_matrix4x4 matrix; + rsMatrixLoadIdentity(&matrix); + rsgProgramVertexLoadModelMatrix(&matrix); + + // Fragment shader with texture + rsgBindProgramStore(gProgStoreBlendNone); + rsgBindProgramFragment(gProgFragmentTexture); + rsgBindTexture(gProgFragmentTexture, 0, gTexOpaque); + + // Linear clamp + rsgBindSampler(gProgFragmentTexture, 0, gLinearClamp); + float startX = 0, startY = 0; + float width = 300, height = 300; + rsgDrawQuadTexCoords(startX, startY, 0, 0, 0, + startX, startY + height, 0, 0, 1.1, + startX + width, startY + height, 0, 1.1, 1.1, + startX + width, startY, 0, 1.1, 0); + + // Linear Wrap + rsgBindSampler(gProgFragmentTexture, 0, gLinearWrap); + startX = 0; startY = 300; + width = 300; height = 300; + rsgDrawQuadTexCoords(startX, startY, 0, 0, 0, + startX, startY + height, 0, 0, 1.1, + startX + width, startY + height, 0, 1.1, 1.1, + startX + width, startY, 0, 1.1, 0); + + // Nearest + rsgBindSampler(gProgFragmentTexture, 0, gNearestClamp); + startX = 300; startY = 0; + width = 300; height = 300; + rsgDrawQuadTexCoords(startX, startY, 0, 0, 0, + startX, startY + height, 0, 0, 1.1, + startX + width, startY + height, 0, 1.1, 1.1, + startX + width, startY, 0, 1.1, 0); + + rsgBindSampler(gProgFragmentTexture, 0, gMipLinearWrap); + startX = 300; startY = 300; + width = 300; height = 300; + rsgDrawQuadTexCoords(startX, startY, 0, 0, 0, + startX, startY + height, 0, 0, 1.5, + startX + width, startY + height, 0, 1.5, 1.5, + startX + width, startY, 0, 1.5, 0); + + + rsgFontColor(1.0f, 1.0f, 1.0f, 1.0f); + rsgBindFont(gFontMono); + rsgDrawText("Filtering: linear clamp", 10, 290); + rsgDrawText("Filtering: linear wrap", 10, 590); + rsgDrawText("Filtering: nearest clamp", 310, 290); + rsgDrawText("Filtering: miplinear wrap", 310, 590); + +} + +float gTorusRotation = 0; + +void displayCullingSamples() { + rsgBindProgramVertex(gProgVertex); + // 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); + rsgBindProgramFragment(gProgFragmentTexture); + rsgBindSampler(gProgFragmentTexture, 0, gLinearClamp); + rsgBindTexture(gProgFragmentTexture, 0, gTexTorus); + + // Aplly a rotation to our mesh + gTorusRotation += 50.0f * gDt; + if(gTorusRotation > 360.0f) { + gTorusRotation -= 360.0f; + } + + rs_matrix4x4 matrix; + // Position our model on the screen + rsMatrixLoadTranslate(&matrix, -2.0f, 0.0f, -10.0f); + rsMatrixRotate(&matrix, gTorusRotation, 1.0f, 0.0f, 0.0f); + rsgProgramVertexLoadModelMatrix(&matrix); + // Use front face culling + rsgBindProgramRaster(gCullFront); + rsgDrawMesh(gTorusMesh); + + rsMatrixLoadTranslate(&matrix, 2.0f, 0.0f, -10.0f); + rsMatrixRotate(&matrix, gTorusRotation, 1.0f, 0.0f, 0.0f); + rsgProgramVertexLoadModelMatrix(&matrix); + // Use back face culling + rsgBindProgramRaster(gCullBack); + rsgDrawMesh(gTorusMesh); + + rsgFontColor(1.0f, 1.0f, 1.0f, 1.0f); + rsgBindFont(gFontMono); + rsgDrawText("Displaying mesh front/back face culling", 10, rsgGetHeight() - 10); +} + +float gLight0Rotation = 0; +float gLight1Rotation = 0; + +void setupCustomShaderLights() { + float4 light0Pos = {-5.0f, 5.0f, -10.0f, 1.0f}; + float4 light1Pos = {2.0f, 5.0f, 15.0f, 1.0f}; + float3 light0DiffCol = {0.9f, 0.7f, 0.7f}; + float3 light0SpecCol = {0.9f, 0.6f, 0.6f}; + float3 light1DiffCol = {0.5f, 0.5f, 0.9f}; + float3 light1SpecCol = {0.5f, 0.5f, 0.9f}; + + gLight0Rotation += 50.0f * gDt; + if(gLight0Rotation > 360.0f) { + gLight0Rotation -= 360.0f; + } + gLight1Rotation -= 50.0f * gDt; + if(gLight1Rotation > 360.0f) { + gLight1Rotation -= 360.0f; + } + + rs_matrix4x4 l0Mat; + rsMatrixLoadRotate(&l0Mat, gLight0Rotation, 1.0f, 0.0f, 0.0f); + light0Pos = rsMatrixMultiply(&l0Mat, light0Pos); + rs_matrix4x4 l1Mat; + rsMatrixLoadRotate(&l1Mat, gLight1Rotation, 0.0f, 0.0f, 1.0f); + light1Pos = rsMatrixMultiply(&l1Mat, light1Pos); + + // Set light 0 properties + gVSConstants->light0_Posision.x = light0Pos.x; + gVSConstants->light0_Posision.y = light0Pos.y; + gVSConstants->light0_Posision.z = light0Pos.z; + gVSConstants->light0_Diffuse = 1.0f; + gVSConstants->light0_Specular = 0.5f; + gVSConstants->light0_CosinePower = 40.0f; + // Set light 1 properties + gVSConstants->light1_Posision.x = light1Pos.x; + gVSConstants->light1_Posision.y = light1Pos.y; + gVSConstants->light1_Posision.z = light1Pos.z; + gVSConstants->light1_Diffuse = 1.0f; + gVSConstants->light1_Specular = 0.7f; + gVSConstants->light1_CosinePower = 50.0f; + rsAllocationMarkDirty(rsGetAllocation(gVSConstants)); + + // Update fragmetn shader constants + // Set light 0 colors + gFSConstants->light0_DiffuseColor = light0DiffCol; + gFSConstants->light0_SpecularColor = light0SpecCol; + // Set light 1 colors + gFSConstants->light1_DiffuseColor = light1DiffCol; + gFSConstants->light1_SpecularColor = light1SpecCol; + rsAllocationMarkDirty(rsGetAllocation(gFSConstants)); +} + +void displayCustomShaderSamples() { + + // Update vertex shader constants + // Load model matrix + // Aplly a rotation to our mesh + gTorusRotation += 50.0f * gDt; + if(gTorusRotation > 360.0f) { + gTorusRotation -= 360.0f; + } + + // Position our model on the screen + 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); + + // Fragment shader with texture + rsgBindProgramStore(gProgStoreBlendNoneDepth); + rsgBindProgramFragment(gProgFragmentCustom); + rsgBindSampler(gProgFragmentCustom, 0, gLinearClamp); + rsgBindTexture(gProgFragmentCustom, 0, gTexTorus); + + // Use back face culling + rsgBindProgramRaster(gCullBack); + rsgDrawMesh(gTorusMesh); + + rsgFontColor(1.0f, 1.0f, 1.0f, 1.0f); + rsgBindFont(gFontMono); + rsgDrawText("Custom shader sample", 10, rsgGetHeight() - 10); +} + +void displayMultitextureSample() { + bindProgramVertexOrtho(); + rs_matrix4x4 matrix; + rsMatrixLoadIdentity(&matrix); + rsgProgramVertexLoadModelMatrix(&matrix); + + // Fragment shader with texture + rsgBindProgramStore(gProgStoreBlendNone); + rsgBindProgramFragment(gProgFragmentMultitex); + rsgBindSampler(gProgFragmentMultitex, 0, gLinearClamp); + rsgBindSampler(gProgFragmentMultitex, 1, gLinearWrap); + rsgBindSampler(gProgFragmentMultitex, 2, gLinearClamp); + rsgBindTexture(gProgFragmentMultitex, 0, gTexOpaque); + rsgBindTexture(gProgFragmentMultitex, 1, gTexTorus); + rsgBindTexture(gProgFragmentMultitex, 2, gTexTransparent); + + float startX = 0, startY = 0; + float width = 256, height = 256; + rsgDrawQuadTexCoords(startX, startY, 0, 0, 0, + startX, startY + height, 0, 0, 1, + startX + width, startY + height, 0, 1, 1, + startX + width, startY, 0, 1, 0); + + rsgFontColor(1.0f, 1.0f, 1.0f, 1.0f); + rsgBindFont(gFontMono); + rsgDrawText("Custom shader with multitexturing", 10, 280); +} + + +int root(int launchID) { + + gDt = rsGetDt(); + + rsgClearColor(0.2f, 0.2f, 0.2f, 0.0f); + rsgClearDepth(1.0f); + + switch(gDisplayMode) { + case 0: + displayFontSamples(); + break; + case 1: + displayShaderSamples(); + break; + case 2: + displayBlendingSamples(); + break; + case 3: + displayMeshSamples(); + break; + case 4: + displayTextureSamplers(); + break; + case 5: + displayCullingSamples(); + break; + case 6: + displayCustomShaderSamples(); + break; + case 7: + displayMultitextureSample(); + break; + } + + return 10; +} 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 new file mode 100644 index 0000000..e3f6206 --- /dev/null +++ b/libs/rs/java/Samples/src/com/android/samples/shader_def.rsh @@ -0,0 +1,47 @@ +// 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. + +#pragma version(1) + +#pragma rs java_package_name(com.android.samples) + +typedef struct VertexShaderConstants_s { + rs_matrix4x4 model; + rs_matrix4x4 proj; + float3 light0_Posision; + float light0_Diffuse; + float light0_Specular; + float light0_CosinePower; + + float3 light1_Posision; + float light1_Diffuse; + float light1_Specular; + float light1_CosinePower; +} VertexShaderConstants; + +typedef struct FragentShaderConstants_s { + float3 light0_DiffuseColor; + float3 light0_SpecularColor; + + float3 light1_DiffuseColor; + float3 light1_SpecularColor; + +} FragentShaderConstants; + +typedef struct VertexShaderInputs_s { + float4 position; + float3 normal; + float2 texture0; +} VertexShaderInputs; + diff --git a/libs/rs/java/tests/Android.mk b/libs/rs/java/tests/Android.mk new file mode 100644 index 0000000..6c992d5 --- /dev/null +++ b/libs/rs/java/tests/Android.mk @@ -0,0 +1,30 @@ +# +# Copyright (C) 2008 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. +# + +ifneq ($(TARGET_SIMULATOR),true) + +LOCAL_PATH := $(call my-dir) +include $(CLEAR_VARS) + +LOCAL_MODULE_TAGS := optional + +LOCAL_SRC_FILES := $(call all-java-files-under, src) $(call all-renderscript-files-under, src) + +LOCAL_PACKAGE_NAME := RSTest + +include $(BUILD_PACKAGE) + +endif diff --git a/libs/rs/java/Film/AndroidManifest.xml b/libs/rs/java/tests/AndroidManifest.xml index a5ce8a1..b660398 100644 --- a/libs/rs/java/Film/AndroidManifest.xml +++ b/libs/rs/java/tests/AndroidManifest.xml @@ -1,10 +1,11 @@ <?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" - package="com.android.film"> - <application android:label="Film"> - <activity android:name="Film" - android:screenOrientation="portrait" - android:theme="@android:style/Theme.Black.NoTitleBar"> + package="com.android.rs.test"> + <application + android:label="_RS_Test" + android:icon="@drawable/test_pattern"> + <activity android:name="RSTest" + android:screenOrientation="portrait"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> diff --git a/libs/rs/java/tests/res/drawable/test_pattern.png b/libs/rs/java/tests/res/drawable/test_pattern.png Binary files differnew file mode 100644 index 0000000..e7d1455 --- /dev/null +++ b/libs/rs/java/tests/res/drawable/test_pattern.png diff --git a/libs/rs/java/Film/src/com/android/film/Film.java b/libs/rs/java/tests/src/com/android/rs/test/RSTest.java index 6e99816..c264649 100644 --- a/libs/rs/java/Film/src/com/android/film/Film.java +++ b/libs/rs/java/tests/src/com/android/rs/test/RSTest.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package com.android.film; +package com.android.rs.test; import android.renderscript.RSSurfaceView; import android.renderscript.RenderScript; @@ -37,33 +37,31 @@ import android.widget.ListView; import java.lang.Runtime; -public class Film extends Activity { +public class RSTest extends Activity { //EventListener mListener = new EventListener(); private static final String LOG_TAG = "libRS_jni"; private static final boolean DEBUG = false; private static final boolean LOG_ENABLED = DEBUG ? Config.LOGD : Config.LOGV; - private FilmView mView; + private RSTestView mView; // get the current looper (from your Activity UI thread for instance - - @Override public void onCreate(Bundle icicle) { super.onCreate(icicle); // Create our Preview view and set it as the content of our // Activity - mView = new FilmView(this); + mView = new RSTestView(this); setContentView(mView); } @Override protected void onResume() { // Ideally a game should implement onResume() and onPause() - // to take appropriate action when the activity looses focus + // to take appropriate action when the activity loses focus super.onResume(); mView.onResume(); } @@ -71,14 +69,11 @@ public class Film extends Activity { @Override protected void onPause() { // Ideally a game should implement onResume() and onPause() - // to take appropriate action when the activity looses focus + // to take appropriate action when the activity loses focus super.onPause(); mView.onPause(); - - Runtime.getRuntime().exit(0); } - static void log(String message) { if (LOG_ENABLED) { Log.v(LOG_TAG, message); @@ -87,4 +82,3 @@ public class Film extends Activity { } - diff --git a/libs/rs/java/tests/src/com/android/rs/test/RSTestCore.java b/libs/rs/java/tests/src/com/android/rs/test/RSTestCore.java new file mode 100644 index 0000000..835dea2 --- /dev/null +++ b/libs/rs/java/tests/src/com/android/rs/test/RSTestCore.java @@ -0,0 +1,199 @@ +/* + * Copyright (C) 2008 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.rs.test; + +import android.content.res.Resources; +import android.renderscript.*; +import android.util.Log; +import java.util.ArrayList; +import java.util.ListIterator; +import java.util.Timer; +import java.util.TimerTask; + + +public class RSTestCore { + int mWidth; + int mHeight; + + public RSTestCore() { + } + + private Resources mRes; + private RenderScriptGL mRS; + + private Font mFont; + ScriptField_ListAllocs_s mListAllocs; + int mLastX; + int mLastY; + private ScriptC_rslist mScript; + + private ArrayList<UnitTest> unitTests; + private ListIterator<UnitTest> test_iter; + private UnitTest activeTest; + private boolean stopTesting; + + /* Periodic timer for ensuring future tests get scheduled */ + private Timer mTimer; + public static final int RS_TIMER_PERIOD = 100; + + public void init(RenderScriptGL rs, Resources res, int width, int height) { + mRS = rs; + mRes = res; + mWidth = width; + mHeight = height; + stopTesting = false; + + mScript = new ScriptC_rslist(mRS, mRes, R.raw.rslist, true); + + unitTests = new ArrayList<UnitTest>(); + + unitTests.add(new UT_primitives(this, mRes)); + unitTests.add(new UT_fp_mad(this, mRes)); + /* + unitTests.add(new UnitTest(null, "<Pass>", 1)); + unitTests.add(new UnitTest()); + unitTests.add(new UnitTest(null, "<Fail>", -1)); + + for (int i = 0; i < 20; i++) { + unitTests.add(new UnitTest(null, "<Pass>", 1)); + } + */ + + UnitTest [] uta = new UnitTest[unitTests.size()]; + uta = unitTests.toArray(uta); + + mListAllocs = new ScriptField_ListAllocs_s(mRS, uta.length); + for (int i = 0; i < uta.length; i++) { + ScriptField_ListAllocs_s.Item listElem = new ScriptField_ListAllocs_s.Item(); + listElem.text = Allocation.createFromString(mRS, uta[i].name); + listElem.result = uta[i].result; + mListAllocs.set(listElem, i, false); + uta[i].setItem(listElem); + } + + mListAllocs.copyAll(); + + mScript.bind_gList(mListAllocs); + + mFont = Font.createFromFamily(mRS, mRes, "serif", Font.Style.BOLD, 8); + mScript.set_gFont(mFont); + + mRS.contextBindRootScript(mScript); + + test_iter = unitTests.listIterator(); + refreshTestResults(); /* Kick off the first test */ + + TimerTask pTask = new TimerTask() { + public void run() { + refreshTestResults(); + } + }; + + mTimer = new Timer(); + mTimer.schedule(pTask, RS_TIMER_PERIOD, RS_TIMER_PERIOD); + } + + public void checkAndRunNextTest() { + if (activeTest != null) { + if (!activeTest.isAlive()) { + /* Properly clean up on our last test */ + try { + activeTest.join(); + } + catch (InterruptedException e) { + } + activeTest = null; + } + } + + if (!stopTesting && activeTest == null) { + if (test_iter.hasNext()) { + activeTest = test_iter.next(); + activeTest.start(); + /* This routine will only get called once when a new test + * should start running. The message handler in UnitTest.java + * ensures this. */ + } + else { + if (mTimer != null) { + mTimer.cancel(); + mTimer.purge(); + mTimer = null; + } + } + } + } + + public void refreshTestResults() { + checkAndRunNextTest(); + + if (mListAllocs != null && mScript != null && mRS != null) { + mListAllocs.copyAll(); + + mScript.bind_gList(mListAllocs); + mRS.contextBindRootScript(mScript); + } + } + + public void cleanup() { + stopTesting = true; + UnitTest t = activeTest; + + /* Stop periodic refresh of testing */ + if (mTimer != null) { + mTimer.cancel(); + mTimer.purge(); + mTimer = null; + } + + /* Wait to exit until we finish the current test */ + if (t != null) { + try { + t.join(); + } + catch (InterruptedException e) { + } + t = null; + } + + } + + public void newTouchPosition(float x, float y, float pressure, int id) { + } + + public void onActionDown(int x, int y) { + mScript.set_gDY(0.0f); + mLastX = x; + mLastY = y; + refreshTestResults(); + } + + public void onActionMove(int x, int y) { + int dx = mLastX - x; + int dy = mLastY - y; + + if (Math.abs(dy) <= 2) { + dy = 0; + } + + mScript.set_gDY(dy); + + mLastX = x; + mLastY = y; + refreshTestResults(); + } +} diff --git a/libs/rs/java/tests/src/com/android/rs/test/RSTestView.java b/libs/rs/java/tests/src/com/android/rs/test/RSTestView.java new file mode 100644 index 0000000..b811d48 --- /dev/null +++ b/libs/rs/java/tests/src/com/android/rs/test/RSTestView.java @@ -0,0 +1,95 @@ +/* + * Copyright (C) 2008 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.rs.test; + +import java.io.Writer; +import java.util.ArrayList; +import java.util.concurrent.Semaphore; + +import android.renderscript.RSSurfaceView; +import android.renderscript.RenderScript; +import android.renderscript.RenderScriptGL; + +import android.content.Context; +import android.content.res.Resources; +import android.graphics.Bitmap; +import android.graphics.drawable.BitmapDrawable; +import android.graphics.drawable.Drawable; +import android.os.Handler; +import android.os.Message; +import android.util.AttributeSet; +import android.util.Log; +import android.view.Surface; +import android.view.SurfaceHolder; +import android.view.SurfaceView; +import android.view.KeyEvent; +import android.view.MotionEvent; + +public class RSTestView extends RSSurfaceView { + + public RSTestView(Context context) { + super(context); + //setFocusable(true); + } + + private RenderScriptGL mRS; + private RSTestCore mRender; + + public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) { + super.surfaceChanged(holder, format, w, h); + if (mRS == null) { + mRS = createRenderScript(false); + mRS.contextSetSurface(w, h, holder.getSurface()); + mRender = new RSTestCore(); + mRender.init(mRS, getResources(), w, h); + } + } + + @Override + protected void onDetachedFromWindow() { + if(mRS != null) { + mRender.cleanup(); + mRS = null; + destroyRenderScript(); + } + } + + @Override + public boolean onKeyDown(int keyCode, KeyEvent event) + { + return super.onKeyDown(keyCode, event); + } + + @Override + public boolean onTouchEvent(MotionEvent ev) + { + boolean ret = false; + int act = ev.getAction(); + if (act == ev.ACTION_DOWN) { + mRender.onActionDown((int)ev.getX(), (int)ev.getY()); + ret = true; + } + else if (act == ev.ACTION_MOVE) { + mRender.onActionMove((int)ev.getX(), (int)ev.getY()); + ret = true; + } + + return ret; + } +} + + diff --git a/libs/rs/java/tests/src/com/android/rs/test/UT_fp_mad.java b/libs/rs/java/tests/src/com/android/rs/test/UT_fp_mad.java new file mode 100644 index 0000000..9d57e90 --- /dev/null +++ b/libs/rs/java/tests/src/com/android/rs/test/UT_fp_mad.java @@ -0,0 +1,40 @@ +/* + * Copyright (C) 2010 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.rs.test; + +import android.content.res.Resources; +import android.renderscript.*; + +public class UT_fp_mad extends UnitTest { + private Resources mRes; + + protected UT_fp_mad(RSTestCore rstc, Resources res) { + super(rstc, "Fp_Mad"); + mRes = res; + } + + public void run() { + RenderScript pRS = RenderScript.create(); + ScriptC_fp_mad s = new ScriptC_fp_mad(pRS, mRes, R.raw.fp_mad, true); + pRS.mMessageCallback = mRsMessage; + s.invoke_fp_mad_test(0, 0); + pRS.finish(); + waitForMessage(); + pRS.destroy(); + } +} + diff --git a/libs/rs/java/tests/src/com/android/rs/test/UT_primitives.java b/libs/rs/java/tests/src/com/android/rs/test/UT_primitives.java new file mode 100644 index 0000000..fb355dd --- /dev/null +++ b/libs/rs/java/tests/src/com/android/rs/test/UT_primitives.java @@ -0,0 +1,40 @@ +/* + * Copyright (C) 2010 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.rs.test; + +import android.content.res.Resources; +import android.renderscript.*; + +public class UT_primitives extends UnitTest { + private Resources mRes; + + protected UT_primitives(RSTestCore rstc, Resources res) { + super(rstc, "Primitives"); + mRes = res; + } + + public void run() { + RenderScript pRS = RenderScript.create(); + ScriptC_primitives s = new ScriptC_primitives(pRS, mRes, R.raw.primitives, true); + pRS.mMessageCallback = mRsMessage; + s.invoke_primitives_test(0, 0); + pRS.finish(); + waitForMessage(); + pRS.destroy(); + } +} + diff --git a/libs/rs/java/tests/src/com/android/rs/test/UnitTest.java b/libs/rs/java/tests/src/com/android/rs/test/UnitTest.java new file mode 100644 index 0000000..c9d88a6 --- /dev/null +++ b/libs/rs/java/tests/src/com/android/rs/test/UnitTest.java @@ -0,0 +1,102 @@ +/* + * Copyright (C) 2010 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.rs.test; +import android.renderscript.RenderScript.RSMessage; +import android.util.Log; + +public class UnitTest extends Thread { + public String name; + public int result; + private ScriptField_ListAllocs_s.Item mItem; + private RSTestCore mRSTC; + private boolean msgHandled; + + /* These constants must match those in shared.rsh */ + public static final int RS_MSG_TEST_PASSED = 100; + public static final int RS_MSG_TEST_FAILED = 101; + + private static int numTests = 0; + public int testID; + + protected UnitTest(RSTestCore rstc, String n, int initResult) { + super(); + mRSTC = rstc; + name = n; + msgHandled = false; + result = initResult; + testID = numTests++; + } + + protected UnitTest(RSTestCore rstc, String n) { + this(rstc, n, 0); + } + + protected UnitTest(RSTestCore rstc) { + this (rstc, "<Unknown>"); + } + + protected UnitTest() { + this (null); + } + + protected RSMessage mRsMessage = new RSMessage() { + public void run() { + switch (mID) { + case RS_MSG_TEST_PASSED: + result = 1; + break; + case RS_MSG_TEST_FAILED: + result = -1; + break; + default: + android.util.Log.v("RenderScript", "Unit test got unexpected message"); + return; + } + + if (mItem != null) { + mItem.result = result; + msgHandled = true; + try { + mRSTC.refreshTestResults(); + } + catch (IllegalStateException e) { + /* Ignore the case where our message receiver has been + disconnected. This happens when we leave the application + before it finishes running all of the unit tests. */ + } + } + } + }; + + public void waitForMessage() { + while (!msgHandled) { + yield(); + } + } + + public void setItem(ScriptField_ListAllocs_s.Item item) { + mItem = item; + } + + public void run() { + /* This method needs to be implemented for each subclass */ + if (mRSTC != null) { + mRSTC.refreshTestResults(); + } + } +} + diff --git a/libs/rs/java/tests/src/com/android/rs/test/fp_mad.rs b/libs/rs/java/tests/src/com/android/rs/test/fp_mad.rs new file mode 100644 index 0000000..dfd77e6 --- /dev/null +++ b/libs/rs/java/tests/src/com/android/rs/test/fp_mad.rs @@ -0,0 +1,176 @@ +#include "shared.rsh" + +const int TEST_COUNT = 1; + +#pragma rs export_var(g_results) +#pragma rs export_func(fp_mad_test) + +static float data_f1[1025]; +static float4 data_f4[1025]; + +static void test_mad4(uint32_t index) { + start(); + + float total = 0; + // Do ~1 billion ops + for (int ct=0; ct < 1000 * (1000 / 80); ct++) { + for (int i=0; i < (1000); i++) { + data_f4[i] = (data_f4[i] * 0.02f + + data_f4[i+1] * 0.04f + + data_f4[i+2] * 0.05f + + data_f4[i+3] * 0.1f + + data_f4[i+4] * 0.2f + + data_f4[i+5] * 0.2f + + data_f4[i+6] * 0.1f + + data_f4[i+7] * 0.05f + + data_f4[i+8] * 0.04f + + data_f4[i+9] * 0.02f + 1.f); + } + } + + float time = end(index); + rsDebug("fp_mad4 M ops", 1000.f / time); +} + +static void test_mad(uint32_t index) { + start(); + + float total = 0; + // Do ~1 billion ops + for (int ct=0; ct < 1000 * (1000 / 20); ct++) { + for (int i=0; i < (1000); i++) { + data_f1[i] = (data_f1[i] * 0.02f + + data_f1[i+1] * 0.04f + + data_f1[i+2] * 0.05f + + data_f1[i+3] * 0.1f + + data_f1[i+4] * 0.2f + + data_f1[i+5] * 0.2f + + data_f1[i+6] * 0.1f + + data_f1[i+7] * 0.05f + + data_f1[i+8] * 0.04f + + data_f1[i+9] * 0.02f + 1.f); + } + } + + float time = end(index); + rsDebug("fp_mad M ops", 1000.f / time); +} + +static void test_norm(uint32_t index) { + start(); + + float total = 0; + // Do ~10 M ops + for (int ct=0; ct < 1000 * 10; ct++) { + for (int i=0; i < (1000); i++) { + data_f4[i] = normalize(data_f4[i]); + } + } + + float time = end(index); + rsDebug("fp_norm M ops", 10.f / time); +} + +static void test_sincos4(uint32_t index) { + start(); + + float total = 0; + // Do ~10 M ops + for (int ct=0; ct < 1000 * 10 / 4; ct++) { + for (int i=0; i < (1000); i++) { + data_f4[i] = sin(data_f4[i]) * cos(data_f4[i]); + } + } + + float time = end(index); + rsDebug("fp_sincos4 M ops", 10.f / time); +} + +static void test_sincos(uint32_t index) { + start(); + + float total = 0; + // Do ~10 M ops + for (int ct=0; ct < 1000 * 10; ct++) { + for (int i=0; i < (1000); i++) { + data_f1[i] = sin(data_f1[i]) * cos(data_f1[i]); + } + } + + float time = end(index); + rsDebug("fp_sincos M ops", 10.f / time); +} + +static void test_clamp(uint32_t index) { + start(); + + // Do ~100 M ops + for (int ct=0; ct < 1000 * 100; ct++) { + for (int i=0; i < (1000); i++) { + data_f1[i] = clamp(data_f1[i], -1.f, 1.f); + } + } + + float time = end(index); + rsDebug("fp_clamp M ops", 100.f / time); + + start(); + // Do ~100 M ops + for (ct=0; ct < 1000 * 100; ct++) { + for (int i=0; i < (1000); i++) { + if (data_f1[i] < -1.f) data_f1[i] = -1.f; + if (data_f1[i] > -1.f) data_f1[i] = 1.f; + } + } + + time = end(index); + rsDebug("fp_clamp ref M ops", 100.f / time); +} + +static void test_clamp4(uint32_t index) { + start(); + + float total = 0; + // Do ~100 M ops + for (int ct=0; ct < 1000 * 100 /4; ct++) { + for (int i=0; i < (1000); i++) { + data_f4[i] = clamp(data_f4[i], -1.f, 1.f); + } + } + + float time = end(index); + rsDebug("fp_clamp4 M ops", 100.f / time); +} + +void fp_mad_test(uint32_t index, int test_num) { + for (int x=0; x < 1025; x++) { + data_f1[x] = (x & 0xf) * 0.1f; + data_f4[x].x = (x & 0xf) * 0.1f; + data_f4[x].y = (x & 0xf0) * 0.1f; + data_f4[x].z = (x & 0x33) * 0.1f; + data_f4[x].w = (x & 0x77) * 0.1f; + } + + test_mad4(index); + test_mad(index); + + for (x=0; x < 1025; x++) { + data_f1[x] = (x & 0xf) * 0.1f + 1.f; + data_f4[x].x = (x & 0xf) * 0.1f + 1.f; + data_f4[x].y = (x & 0xf0) * 0.1f + 1.f; + data_f4[x].z = (x & 0x33) * 0.1f + 1.f; + data_f4[x].w = (x & 0x77) * 0.1f + 1.f; + } + + test_norm(index); + test_sincos4(index); + test_sincos(index); + test_clamp4(index); + test_clamp(index); + + // TODO Actually verify test result accuracy + rsDebug("fp_mad_test PASSED", 0); + rsSendToClientBlocking(RS_MSG_TEST_PASSED); +} + + diff --git a/libs/rs/java/tests/src/com/android/rs/test/primitives.rs b/libs/rs/java/tests/src/com/android/rs/test/primitives.rs new file mode 100644 index 0000000..5312bcc --- /dev/null +++ b/libs/rs/java/tests/src/com/android/rs/test/primitives.rs @@ -0,0 +1,51 @@ +#include "shared.rsh" + +#pragma rs export_func(primitives_test) + +// Testing primitive types +static float floatTest = 1.99f; +static double doubleTest = 2.05; +static char charTest = -8; +static short shortTest = -16; +static int intTest = -32; +static uchar ucharTest = 8; +static ushort ushortTest = 16; +static uint uintTest = 32; + +static bool test_primitive_types(uint32_t index) { + bool failed = false; + start(); + + _RS_ASSERT(floatTest == 1.99f); + _RS_ASSERT(doubleTest == 2.05); + _RS_ASSERT(charTest == -8); + _RS_ASSERT(shortTest == -16); + _RS_ASSERT(intTest == -32); + _RS_ASSERT(ucharTest == 8); + _RS_ASSERT(ushortTest == 16); + _RS_ASSERT(uintTest == 32); + + float time = end(index); + + if (failed) { + rsDebug("test_primitives FAILED", time); + } + else { + rsDebug("test_primitives PASSED", time); + } + + return failed; +} + +void primitives_test(uint32_t index, int test_num) { + bool failed = false; + failed |= test_primitive_types(index); + + if (failed) { + rsSendToClientBlocking(RS_MSG_TEST_FAILED); + } + else { + rsSendToClientBlocking(RS_MSG_TEST_PASSED); + } +} + diff --git a/libs/rs/java/tests/src/com/android/rs/test/rslist.rs b/libs/rs/java/tests/src/com/android/rs/test/rslist.rs new file mode 100644 index 0000000..a5f0f6b --- /dev/null +++ b/libs/rs/java/tests/src/com/android/rs/test/rslist.rs @@ -0,0 +1,109 @@ +// 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. + +#pragma version(1) + +#pragma rs java_package_name(com.android.rs.test) + +#include "rs_graphics.rsh" + +float gDY; + +rs_font gFont; + +typedef struct ListAllocs_s { + rs_allocation text; + int result; +} ListAllocs; + +ListAllocs *gList; + +#pragma rs export_var(gDY, gFont, gList) + +void init() { + gDY = 0.0f; +} + +int textPos = 0; + +int root(int launchID) { + + rsgClearColor(0.0f, 0.0f, 0.0f, 0.0f); + rsgClearDepth(1.0f); + + textPos -= (int)gDY*2; + gDY *= 0.95; + + rsgFontColor(0.9f, 0.9f, 0.9f, 1.0f); + rsgBindFont(gFont); + color(0.2, 0.2, 0.2, 0); + + rs_allocation listAlloc = rsGetAllocation(gList); + int allocSize = rsAllocationGetDimX(listAlloc); + + int width = rsgGetWidth(); + int height = rsgGetHeight(); + + int itemHeight = 80; + int totalItemHeight = itemHeight * allocSize; + + /* Prevent scrolling above the top of the list */ + int firstItem = height - totalItemHeight; + if (firstItem < 0) { + firstItem = 0; + } + + /* Prevent scrolling past the last line of the list */ + int lastItem = -1 * (totalItemHeight - height); + if (lastItem > 0) { + lastItem = 0; + } + + if (textPos > firstItem) { + textPos = firstItem; + } + else if (textPos < lastItem) { + textPos = lastItem; + } + + int currentYPos = itemHeight + textPos; + + for(int i = 0; i < allocSize; i ++) { + if(currentYPos - itemHeight > height) { + break; + } + + if(currentYPos > 0) { + switch(gList[i].result) { + case 1: /* Passed */ + rsgFontColor(0.5f, 0.9f, 0.5f, 1.0f); + break; + case -1: /* Failed */ + rsgFontColor(0.9f, 0.5f, 0.5f, 1.0f); + break; + case 0: /* Still Testing */ + rsgFontColor(0.9f, 0.9f, 0.5f, 1.0f); + break; + default: /* Unknown */ + rsgFontColor(0.9f, 0.9f, 0.9f, 1.0f); + break; + } + rsgDrawRect(0, currentYPos - 1, width, currentYPos, 0); + rsgDrawText(gList[i].text, 30, currentYPos - 32); + } + currentYPos += itemHeight; + } + + return 10; +} diff --git a/libs/rs/java/tests/src/com/android/rs/test/shared.rsh b/libs/rs/java/tests/src/com/android/rs/test/shared.rsh new file mode 100644 index 0000000..820fffd --- /dev/null +++ b/libs/rs/java/tests/src/com/android/rs/test/shared.rsh @@ -0,0 +1,38 @@ +#pragma version(1) + +#pragma rs java_package_name(com.android.rs.test) + +typedef struct TestResult_s { + rs_allocation name; + bool pass; + float score; + int64_t time; +} TestResult; +TestResult *g_results; + +static int64_t g_time; + +static void start(void) { + g_time = rsUptimeMillis(); +} + +static float end(uint32_t idx) { + int64_t t = rsUptimeMillis() - g_time; + //g_results[idx].time = t; + //rsDebug("test time", (int)t); + return ((float)t) / 1000.f; +} + +#define _RS_ASSERT(b) \ +do { \ + if (!(b)) { \ + failed = true; \ + rsDebug(#b " FAILED", 0); \ + } \ +\ +} while (0) + +/* These constants must match those in UnitTest.java */ +static const int RS_MSG_TEST_PASSED = 100; +static const int RS_MSG_TEST_FAILED = 101; + diff --git a/libs/rs/java/tests/src/com/android/rs/test/test_root.rs b/libs/rs/java/tests/src/com/android/rs/test/test_root.rs new file mode 100644 index 0000000..72b391d --- /dev/null +++ b/libs/rs/java/tests/src/com/android/rs/test/test_root.rs @@ -0,0 +1,26 @@ +// Fountain test script +#pragma version(1) + +#pragma rs java_package_name(com.android.rs.test) + +#pragma stateFragment(parent) + +#include "rs_graphics.rsh" + + +typedef struct TestResult { + rs_allocation name; + bool pass; + float score; +} TestResult_t; +TestResult_t *results; + +#pragma rs export_var(results) +//#pragma rs export_func(addParticles) + +int root() { + + return 0; +} + + |