Add ability to load arrays in RenderScript.

This commit is contained in:
Romain Guy
2009-08-04 17:19:48 -07:00
parent ead2758ce2
commit a2136d6b18
9 changed files with 417 additions and 22 deletions

View File

@@ -0,0 +1,25 @@
#
# 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.
#
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_SRC_FILES := $(call all-java-files-under, src)
#LOCAL_STATIC_JAVA_LIBRARIES := android.renderscript
LOCAL_PACKAGE_NAME := FallRS
include $(BUILD_PACKAGE)

View File

@@ -0,0 +1,20 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.android.fall.rs">
<application android:label="FallRS">
<activity
android:name="Fall"
android:theme="@android:style/Theme.NoTitleBar">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>

View File

View File

@@ -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.
*/
package com.android.fall.rs;
import android.app.Activity;
import android.os.Bundle;
public class Fall extends Activity {
private FallView mView;
@Override
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
mView = new FallView(this);
setContentView(mView);
}
@Override
protected void onResume() {
super.onResume();
mView.onResume();
}
@Override
protected void onPause() {
super.onPause();
mView.onPause();
Runtime.getRuntime().exit(0);
}
}

View File

@@ -0,0 +1,216 @@
/*
* 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.fall.rs;
import android.content.res.Resources;
import android.renderscript.RenderScript;
import android.renderscript.ScriptC;
import android.renderscript.ProgramFragment;
import android.renderscript.ProgramStore;
import android.renderscript.ProgramVertexAlloc;
import android.renderscript.Allocation;
import android.renderscript.Sampler;
import static android.renderscript.Sampler.Value.LINEAR;
import static android.renderscript.Sampler.Value.CLAMP;
import static android.renderscript.ProgramStore.DepthFunc.*;
import static android.renderscript.ProgramStore.BlendDstFunc;
import static android.renderscript.ProgramStore.BlendSrcFunc;
import static android.renderscript.ProgramFragment.EnvMode.*;
import static android.renderscript.Element.*;
import android.graphics.BitmapFactory;
import android.graphics.Bitmap;
import java.util.TimeZone;
class FallRS {
private static final int MESH_RESOLUTION = 64;
private static final int RSID_STATE = 0;
private static final int RSID_STATE_FRAMECOUNT = 0;
private static final int RSID_STATE_WIDTH = 1;
private static final int RSID_STATE_HEIGHT = 2;
private static final int RSID_TEXTURES = 1;
private static final int TEXTURES_COUNT = 0;
private Resources mResources;
private RenderScript mRS;
private final BitmapFactory.Options mBitmapOptions = new BitmapFactory.Options();
private final int mWidth;
private final int mHeight;
private ScriptC mScript;
private Sampler mSampler;
private ProgramFragment mPfBackground;
private ProgramStore mPfsBackground;
private RenderScript.ProgramVertex mPvBackground;
private ProgramVertexAlloc mPvOrthoAlloc;
private Allocation mTexturesIDs;
private Allocation[] mTextures;
private int[] mTextureBufferIDs;
private Allocation mState;
public FallRS(int width, int height) {
mWidth = width;
mHeight = height;
mBitmapOptions.inScaled = false;
mBitmapOptions.inPreferredConfig = Bitmap.Config.ARGB_8888;
}
public void init(RenderScript rs, Resources res) {
mRS = rs;
mResources = res;
initRS();
}
public void destroy() {
mScript.destroy();
mSampler.destroy();
mPfBackground.destroy();
mPfsBackground.destroy();
mPvBackground.destroy();
mPvOrthoAlloc.mAlloc.destroy();
mTexturesIDs.destroy();
for (Allocation a : mTextures) {
a.destroy();
}
mState.destroy();
mTextureBufferIDs = null;
}
@Override
protected void finalize() throws Throwable {
try {
destroy();
} finally {
super.finalize();
}
}
private void initRS() {
createProgramVertex();
createProgramFragmentStore();
createProgramFragment();
createScriptStructures();
createMesh();
ScriptC.Builder sb = new ScriptC.Builder(mRS);
sb.setScript(mResources, R.raw.fall);
sb.setRoot(true);
mScript = sb.create();
mScript.setClearColor(0.0f, 0.0f, 0.0f, 1.0f);
mScript.setTimeZone(TimeZone.getDefault().getID());
loadSkyTextures();
mScript.bindAllocation(mState, RSID_STATE);
mScript.bindAllocation(mTexturesIDs, RSID_TEXTURES);
mRS.contextBindRootScript(mScript);
}
private void createMesh() {
}
private void createScriptStructures() {
final int[] data = new int[3];
mState = Allocation.createSized(mRS, USER_I32, data.length);
data[RSID_STATE_FRAMECOUNT] = 0;
data[RSID_STATE_WIDTH] = mWidth;
data[RSID_STATE_HEIGHT] = mHeight;
mState.data(data);
}
private void loadSkyTextures() {
mTextureBufferIDs = new int[TEXTURES_COUNT];
mTextures = new Allocation[TEXTURES_COUNT];
mTexturesIDs = Allocation.createSized(mRS, USER_FLOAT, TEXTURES_COUNT);
final Allocation[] textures = mTextures;
// TOOD: Load textures
final int[] bufferIds = mTextureBufferIDs;
final int count = textures.length;
for (int i = 0; i < count; i++) {
final Allocation texture = textures[i];
texture.uploadToTexture(0);
bufferIds[i] = texture.getID();
}
mTexturesIDs.data(bufferIds);
}
private Allocation loadTexture(int id, String name) {
final Allocation allocation = Allocation.createFromBitmapResource(mRS, mResources,
id, RGB_565, false);
allocation.setName(name);
return allocation;
}
private Allocation loadTextureARGB(int id, String name) {
// Forces ARGB 32 bits, because pngcrush sometimes optimize our PNGs to
// indexed pictures, which are not well supported
final Bitmap b = BitmapFactory.decodeResource(mResources, id, mBitmapOptions);
final Allocation allocation = Allocation.createFromBitmap(mRS, b, RGBA_8888, false);
allocation.setName(name);
return allocation;
}
private void createProgramFragment() {
Sampler.Builder bs = new Sampler.Builder(mRS);
bs.setMin(LINEAR);
bs.setMag(LINEAR);
bs.setWrapS(CLAMP);
bs.setWrapT(CLAMP);
mSampler = bs.create();
ProgramFragment.Builder b;
b = new ProgramFragment.Builder(mRS, null, null);
b.setTexEnable(true, 0);
b.setTexEnvMode(REPLACE, 0);
mPfBackground = b.create();
mPfBackground.setName("PFBackground");
mPfBackground.bindSampler(mSampler, 0);
}
private void createProgramFragmentStore() {
ProgramStore.Builder b;
b = new ProgramStore.Builder(mRS, null, null);
b.setDepthFunc(ALWAYS);
b.setBlendFunc(BlendSrcFunc.SRC_ALPHA, BlendDstFunc.ONE_MINUS_SRC_ALPHA);
b.setDitherEnable(true);
b.setDepthMask(false);
mPfsBackground = b.create();
mPfsBackground.setName("PFSBackground");
}
private void createProgramVertex() {
mPvOrthoAlloc = new ProgramVertexAlloc(mRS);
mPvOrthoAlloc.setupOrthoWindow(mWidth, mHeight);
mRS.programVertexBegin(null, null);
mRS.programVertexSetTextureMatrixEnable(true);
mPvBackground = mRS.programVertexCreate();
mPvBackground.bindAllocation(0, mPvOrthoAlloc.mAlloc);
mPvBackground.setName("PVBackground");
}
}

View File

@@ -0,0 +1,44 @@
/*
* 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.fall.rs;
import android.content.Context;
import android.view.SurfaceHolder;
import android.renderscript.RenderScript;
import android.renderscript.RSSurfaceView;
class FallView extends RSSurfaceView {
private FallRS mRender;
public FallView(Context context) {
super(context);
}
public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
super.surfaceChanged(holder, format, w, h);
RenderScript RS = createRenderScript();
mRender = new FallRS(w, h);
mRender.init(RS, getResources());
}
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
if (mRender != null) mRender.destroy();
}
}

View File

@@ -18,7 +18,6 @@ package com.android.grass.rs;
import android.content.res.Resources;
import android.renderscript.Sampler;
import static android.renderscript.Sampler.Value.*;
import static android.renderscript.ProgramFragment.EnvMode.*;
import static android.renderscript.ProgramStore.DepthFunc.*;
import static android.renderscript.ProgramStore.BlendSrcFunc;
@@ -33,6 +32,7 @@ import static android.util.MathUtils.*;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.renderscript.ScriptC;
import static android.renderscript.Sampler.Value.*;
import java.util.TimeZone;
@@ -43,8 +43,8 @@ class GrassRS {
private static final int RSID_STATE_WIDTH = 2;
private static final int RSID_STATE_HEIGHT = 3;
private static final int RSID_SKY_TEXTURES = 1;
private static final int SKY_TEXTURES_COUNT = 5;
private static final int RSID_TEXTURES = 1;
private static final int TEXTURES_COUNT = 5;
private static final int RSID_BLADES = 2;
private static final int BLADES_COUNT = 100;
@@ -69,32 +69,21 @@ class GrassRS {
private final int mWidth;
private final int mHeight;
@SuppressWarnings({"FieldCanBeLocal"})
private ScriptC mScript;
@SuppressWarnings({"FieldCanBeLocal"})
private Sampler mSampler;
@SuppressWarnings({"FieldCanBeLocal"})
private ProgramFragment mPfBackground;
@SuppressWarnings({"FieldCanBeLocal"})
private ProgramStore mPfsBackground;
@SuppressWarnings({"FieldCanBeLocal"})
private RenderScript.ProgramVertex mPvBackground;
@SuppressWarnings({"FieldCanBeLocal"})
private ProgramVertexAlloc mPvOrthoAlloc;
@SuppressWarnings({"FieldCanBeLocal"})
private Allocation mTexturesIDs;
@SuppressWarnings({"FieldCanBeLocal"})
private Allocation[] mTextures;
@SuppressWarnings({"FieldCanBeLocal"})
private int[] mTextureBufferIDs;
@SuppressWarnings({"FieldCanBeLocal"})
private Allocation mState;
@SuppressWarnings({"FieldCanBeLocal"})
private Allocation mBlades;
@SuppressWarnings({"FieldCanBeLocal"})
private ProgramFragment mPfGrass;
@SuppressWarnings({"FieldCanBeLocal"})
private ProgramStore mPfsGrass;
public GrassRS(int width, int height) {
@@ -109,6 +98,33 @@ class GrassRS {
mResources = res;
initRS();
}
public void destroy() {
mScript.destroy();
mSampler.destroy();
mPfBackground.destroy();
mPfsBackground.destroy();
mPvBackground.destroy();
mPvOrthoAlloc.mAlloc.destroy();
mTexturesIDs.destroy();
for (Allocation a : mTextures) {
a.destroy();
}
mState.destroy();
mBlades.destroy();
mPfGrass.destroy();
mPfsGrass.destroy();
mTextureBufferIDs = null;
}
@Override
protected void finalize() throws Throwable {
try {
destroy();
} finally {
super.finalize();
}
}
private void initRS() {
createProgramVertex();
@@ -125,7 +141,7 @@ class GrassRS {
loadSkyTextures();
mScript.bindAllocation(mState, RSID_STATE);
mScript.bindAllocation(mTexturesIDs, RSID_SKY_TEXTURES);
mScript.bindAllocation(mTexturesIDs, RSID_TEXTURES);
mScript.bindAllocation(mBlades, RSID_BLADES);
mRS.contextBindRootScript(mScript);
@@ -165,9 +181,9 @@ class GrassRS {
}
private void loadSkyTextures() {
mTextureBufferIDs = new int[SKY_TEXTURES_COUNT];
mTextures = new Allocation[SKY_TEXTURES_COUNT];
mTexturesIDs = Allocation.createSized(mRS, USER_FLOAT, SKY_TEXTURES_COUNT);
mTextureBufferIDs = new int[TEXTURES_COUNT];
mTextures = new Allocation[TEXTURES_COUNT];
mTexturesIDs = Allocation.createSized(mRS, USER_FLOAT, TEXTURES_COUNT);
final Allocation[] textures = mTextures;
textures[0] = loadTexture(R.drawable.night, "night");

View File

@@ -22,6 +22,8 @@ import android.renderscript.RenderScript;
import android.view.SurfaceHolder;
class GrassView extends RSSurfaceView {
private GrassRS mRender;
public GrassView(Context context) {
super(context);
}
@@ -30,7 +32,12 @@ class GrassView extends RSSurfaceView {
super.surfaceChanged(holder, format, w, h);
RenderScript RS = createRenderScript();
GrassRS render = new GrassRS(w, h);
render.init(RS, getResources());
mRender = new GrassRS(w, h);
mRender.init(RS, getResources());
}
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
if (mRender != null) mRender.destroy();
}
}

View File

@@ -59,6 +59,22 @@ static int32_t SC_loadI32(uint32_t bank, uint32_t offset)
return i[offset];
}
static float* SC_loadArrayF(uint32_t bank)
{
GET_TLS();
void *vp = sc->mSlots[bank]->getPtr();
float *f = static_cast<float *>(vp);
return f;
}
static int32_t* SC_loadArrayI32(uint32_t bank)
{
GET_TLS();
void *vp = sc->mSlots[bank]->getPtr();
int32_t *i = static_cast<int32_t *>(vp);
return i;
}
static uint32_t SC_loadU32(uint32_t bank, uint32_t offset)
{
GET_TLS();
@@ -678,6 +694,10 @@ ScriptCState::SymbolTable_t ScriptCState::gSyms[] = {
//{ "loadU32", (void *)&SC_loadU32, "unsigned int", "(int, int)" },
{ "loadF", (void *)&SC_loadF,
"float", "(int, int)" },
{ "loadArrayF", (void *)&SC_loadArrayF,
"float*", "(int)" },
{ "loadArrayI32", (void *)&SC_loadArrayI32,
"int*", "(int)" },
{ "loadVec4", (void *)&SC_loadVec4,
"void", "(int, int, float *)" },
{ "loadMatrix", (void *)&SC_loadMatrix,