am 4d10ed32: Merge "fix a dead-lock in eglMakeCurrent"
* commit '4d10ed3210ef6beb28f525d1a064268b149f0736':
fix a dead-lock in eglMakeCurrent
diff --git a/graphics/java/android/renderscript/Allocation.java b/graphics/java/android/renderscript/Allocation.java
index 11c2427..88ee362 100644
--- a/graphics/java/android/renderscript/Allocation.java
+++ b/graphics/java/android/renderscript/Allocation.java
@@ -22,6 +22,7 @@
import android.content.res.AssetManager;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
+import android.graphics.SurfaceTexture;
import android.util.Log;
import android.util.TypedValue;
@@ -78,6 +79,8 @@
boolean mConstrainedFace;
boolean mConstrainedY;
boolean mConstrainedZ;
+ boolean mReadAllowed = true;
+ boolean mWriteAllowed = true;
int mSelectedY;
int mSelectedZ;
int mSelectedLOD;
@@ -127,6 +130,32 @@
*/
public static final int USAGE_GRAPHICS_RENDER_TARGET = 0x0010;
+ /**
+ * USAGE_GRAPHICS_SURFACE_TEXTURE_INPUT The allcation will be
+ * used with a SurfaceTexture object. This usage will cause the
+ * allocation to be created read only.
+ *
+ * @hide
+ */
+ public static final int USAGE_GRAPHICS_SURFACE_TEXTURE_INPUT_OPAQUE = 0x0020;
+
+ /**
+ * USAGE_GRAPHICS_SURFACE_TEXTURE_INPUT The allcation will be
+ * used with a SurfaceTexture object. This usage will cause the
+ * allocation to be created read only.
+ *
+ * @hide
+ */
+
+ public static final int USAGE_IO_INPUT = 0x0040;
+ /**
+ * USAGE_GRAPHICS_SURFACE_TEXTURE_INPUT The allcation will be
+ * used with a SurfaceTexture object. This usage will cause the
+ * allocation to be created read only.
+ *
+ * @hide
+ */
+ public static final int USAGE_IO_OUTPUT = 0x0080;
/**
* Controls mipmap behavior when using the bitmap creation and
@@ -187,10 +216,26 @@
USAGE_GRAPHICS_TEXTURE |
USAGE_GRAPHICS_VERTEX |
USAGE_GRAPHICS_CONSTANTS |
- USAGE_GRAPHICS_RENDER_TARGET)) != 0) {
+ USAGE_GRAPHICS_RENDER_TARGET |
+ USAGE_GRAPHICS_SURFACE_TEXTURE_INPUT_OPAQUE |
+ USAGE_IO_INPUT |
+ USAGE_IO_OUTPUT)) != 0) {
throw new RSIllegalArgumentException("Unknown usage specified.");
}
+
+ if ((usage & (USAGE_GRAPHICS_SURFACE_TEXTURE_INPUT_OPAQUE | USAGE_IO_INPUT)) != 0) {
+ mWriteAllowed = false;
+
+ if ((usage & ~(USAGE_GRAPHICS_SURFACE_TEXTURE_INPUT_OPAQUE |
+ USAGE_IO_INPUT |
+ USAGE_GRAPHICS_TEXTURE |
+ USAGE_SCRIPT)) != 0) {
+ throw new RSIllegalArgumentException("Invalid usage combination.");
+ }
+ }
+
mType = t;
+ mUsage = usage;
if (t != null) {
updateCacheInfo(t);
@@ -876,7 +921,31 @@
if (type.getID() == 0) {
throw new RSInvalidStateException("Bad Type");
}
- int id = rs.nAllocationCreateTyped(type.getID(), mips.mID, usage);
+ int id = rs.nAllocationCreateTyped(type.getID(), mips.mID, usage, 0);
+ if (id == 0) {
+ throw new RSRuntimeException("Allocation creation failed.");
+ }
+ return new Allocation(id, rs, type, usage);
+ }
+
+ /**
+ * @hide
+ * This API is hidden and only intended to be used for
+ * transitional purposes.
+ *
+ * @param type renderscript type describing data layout
+ * @param mips specifies desired mipmap behaviour for the
+ * allocation
+ * @param usage bit field specifying how the allocation is
+ * utilized
+ */
+ static public Allocation createTyped(RenderScript rs, Type type, MipmapControl mips,
+ int usage, int pointer) {
+ rs.validate();
+ if (type.getID() == 0) {
+ throw new RSInvalidStateException("Bad Type");
+ }
+ int id = rs.nAllocationCreateTyped(type.getID(), mips.mID, usage, pointer);
if (id == 0) {
throw new RSRuntimeException("Allocation creation failed.");
}
@@ -931,7 +1000,7 @@
b.setX(count);
Type t = b.create();
- int id = rs.nAllocationCreateTyped(t.getID(), MipmapControl.MIPMAP_NONE.mID, usage);
+ int id = rs.nAllocationCreateTyped(t.getID(), MipmapControl.MIPMAP_NONE.mID, usage, 0);
if (id == 0) {
throw new RSRuntimeException("Allocation creation failed.");
}
@@ -1006,6 +1075,23 @@
}
/**
+ *
+ *
+ * @hide
+ *
+ */
+ public SurfaceTexture getSurfaceTexture() {
+ if ((mUsage & USAGE_GRAPHICS_SURFACE_TEXTURE_INPUT_OPAQUE) == 0) {
+ throw new RSInvalidStateException("Allocation is not a surface texture.");
+ }
+
+ int id = mRS.nAllocationGetSurfaceTextureID(getID());
+ return new SurfaceTexture(id);
+
+ }
+
+
+ /**
* Creates a non-mipmapped renderscript allocation to use as a
* graphics texture
*
diff --git a/graphics/java/android/renderscript/Element.java b/graphics/java/android/renderscript/Element.java
index 22ef7bb..f6a0281 100644
--- a/graphics/java/android/renderscript/Element.java
+++ b/graphics/java/android/renderscript/Element.java
@@ -54,26 +54,59 @@
int[] mArraySizes;
int[] mOffsetInBytes;
+ int[] mVisibleElementMap;
+
DataType mType;
DataKind mKind;
boolean mNormalized;
int mVectorSize;
+ private void updateVisibleSubElements() {
+ if (mElements == null) {
+ return;
+ }
+
+ int noPaddingFieldCount = 0;
+ int fieldCount = mElementNames.length;
+ // Find out how many elements are not padding
+ for (int ct = 0; ct < fieldCount; ct ++) {
+ if (mElementNames[ct].charAt(0) != '#') {
+ noPaddingFieldCount ++;
+ }
+ }
+ mVisibleElementMap = new int[noPaddingFieldCount];
+
+ // Make a map that points us at non-padding elements
+ for (int ct = 0, ctNoPadding = 0; ct < fieldCount; ct ++) {
+ if (mElementNames[ct].charAt(0) != '#') {
+ mVisibleElementMap[ctNoPadding ++] = ct;
+ }
+ }
+ }
+
/**
* @hide
* @return element size in bytes
*/
public int getSizeBytes() {return mSize;}
+ /**
+ * @hide
+ * @return element vector size
+ */
+ public int getVectorSize() {return mVectorSize;}
+
/**
* DataType represents the basic type information for a basic element. The
- * naming convention follows. For numeric types its FLOAT, SIGNED, UNSIGNED
- * followed by the _BITS where BITS is the size of the data. BOOLEAN is a
- * true / false (1,0) represented in an 8 bit container. The UNSIGNED
- * variants with multiple bit definitions are for packed graphical data
- * formats and represents vectors with per vector member sizes which are
- * treated as a single unit for packing and alignment purposes.
+ * naming convention follows. For numeric types it is FLOAT,
+ * SIGNED, or UNSIGNED followed by the _BITS where BITS is the
+ * size of the data. BOOLEAN is a true / false (1,0)
+ * represented in an 8 bit container. The UNSIGNED variants
+ * with multiple bit definitions are for packed graphical data
+ * formats and represent vectors with per vector member sizes
+ * which are treated as a single unit for packing and alignment
+ * purposes.
*
* MATRIX the three matrix types contain FLOAT_32 elements and are treated
* as 32 bits for alignment purposes.
@@ -81,6 +114,11 @@
* RS_* objects. 32 bit opaque handles.
*/
public enum DataType {
+ /**
+ * @hide
+ * new enum
+ */
+ NONE (0, 0),
//FLOAT_16 (1, 2),
FLOAT_32 (2, 4),
FLOAT_64 (3, 8),
@@ -167,10 +205,10 @@
* @return number of sub-elements in this element
*/
public int getSubElementCount() {
- if (mElements == null) {
+ if (mVisibleElementMap == null) {
return 0;
}
- return mElements.length;
+ return mVisibleElementMap.length;
}
/**
@@ -179,13 +217,13 @@
* @return sub-element in this element at given index
*/
public Element getSubElement(int index) {
- if (mElements == null) {
+ if (mVisibleElementMap == null) {
throw new RSIllegalArgumentException("Element contains no sub-elements");
}
- if (index < 0 || index >= mElements.length) {
+ if (index < 0 || index >= mVisibleElementMap.length) {
throw new RSIllegalArgumentException("Illegal sub-element index");
}
- return mElements[index];
+ return mElements[mVisibleElementMap[index]];
}
/**
@@ -194,13 +232,13 @@
* @return sub-element in this element at given index
*/
public String getSubElementName(int index) {
- if (mElements == null) {
+ if (mVisibleElementMap == null) {
throw new RSIllegalArgumentException("Element contains no sub-elements");
}
- if (index < 0 || index >= mElements.length) {
+ if (index < 0 || index >= mVisibleElementMap.length) {
throw new RSIllegalArgumentException("Illegal sub-element index");
}
- return mElementNames[index];
+ return mElementNames[mVisibleElementMap[index]];
}
/**
@@ -209,13 +247,13 @@
* @return array size of sub-element in this element at given index
*/
public int getSubElementArraySize(int index) {
- if (mElements == null) {
+ if (mVisibleElementMap == null) {
throw new RSIllegalArgumentException("Element contains no sub-elements");
}
- if (index < 0 || index >= mElements.length) {
+ if (index < 0 || index >= mVisibleElementMap.length) {
throw new RSIllegalArgumentException("Illegal sub-element index");
}
- return mArraySizes[index];
+ return mArraySizes[mVisibleElementMap[index]];
}
/**
@@ -224,13 +262,29 @@
* @return offset in bytes of sub-element in this element at given index
*/
public int getSubElementOffsetBytes(int index) {
- if (mElements == null) {
+ if (mVisibleElementMap == null) {
throw new RSIllegalArgumentException("Element contains no sub-elements");
}
- if (index < 0 || index >= mElements.length) {
+ if (index < 0 || index >= mVisibleElementMap.length) {
throw new RSIllegalArgumentException("Illegal sub-element index");
}
- return mOffsetInBytes[index];
+ return mOffsetInBytes[mVisibleElementMap[index]];
+ }
+
+ /**
+ * @hide
+ * @return element data type
+ */
+ public DataType getDataType() {
+ return mType;
+ }
+
+ /**
+ * @hide
+ * @return element data kind
+ */
+ public DataKind getDataKind() {
+ return mKind;
}
/**
@@ -681,14 +735,18 @@
Element(int id, RenderScript rs, Element[] e, String[] n, int[] as) {
super(id, rs);
mSize = 0;
+ mVectorSize = 1;
mElements = e;
mElementNames = n;
mArraySizes = as;
+ mType = DataType.NONE;
+ mKind = DataKind.USER;
mOffsetInBytes = new int[mElements.length];
for (int ct = 0; ct < mElements.length; ct++ ) {
mOffsetInBytes[ct] = mSize;
mSize += mElements[ct].mSize * mArraySizes[ct];
}
+ updateVisibleSubElements();
}
Element(int id, RenderScript rs, DataType dt, DataKind dk, boolean norm, int size) {
@@ -753,7 +811,7 @@
mSize += mElements[i].mSize * mArraySizes[i];
}
}
-
+ updateVisibleSubElements();
}
/**
diff --git a/graphics/java/android/renderscript/Path.java b/graphics/java/android/renderscript/Path.java
new file mode 100644
index 0000000..83ae150
--- /dev/null
+++ b/graphics/java/android/renderscript/Path.java
@@ -0,0 +1,90 @@
+/*
+ * 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 android.renderscript;
+
+import java.util.Vector;
+import android.util.Log;
+
+/**
+ * @hide
+ *
+ */
+public class Path extends BaseObj {
+
+ public enum Primitive {
+ QUADRATIC_BEZIER(0),
+ CUBIC_BEZIER(1);
+
+ int mID;
+ Primitive(int id) {
+ mID = id;
+ }
+ }
+
+ Allocation mVertexBuffer;
+ Allocation mLoopBuffer;
+ Primitive mPrimitive;
+ float mQuality;
+ boolean mCoverageToAlpha;
+
+ Path(int id, RenderScript rs, Primitive p, Allocation vtx, Allocation loop, float q) {
+ super(id, rs);
+ mVertexBuffer = vtx;
+ mLoopBuffer = loop;
+ mPrimitive = p;
+ mQuality = q;
+ }
+
+ public Allocation getVertexAllocation() {
+ return mVertexBuffer;
+ }
+
+ public Allocation getLoopAllocation() {
+ return mLoopBuffer;
+ }
+
+ public Primitive getPrimitive() {
+ return mPrimitive;
+ }
+
+ @Override
+ void updateFromNative() {
+ }
+
+
+ public static Path createStaticPath(RenderScript rs, Primitive p, float quality, Allocation vtx) {
+ int id = rs.nPathCreate(p.mID, false, vtx.getID(), 0, quality);
+ Path newPath = new Path(id, rs, p, null, null, quality);
+ return newPath;
+ }
+
+ public static Path createStaticPath(RenderScript rs, Primitive p, float quality, Allocation vtx, Allocation loops) {
+ return null;
+ }
+
+ public static Path createDynamicPath(RenderScript rs, Primitive p, float quality, Allocation vtx) {
+ return null;
+ }
+
+ public static Path createDynamicPath(RenderScript rs, Primitive p, float quality, Allocation vtx, Allocation loops) {
+ return null;
+ }
+
+
+}
+
+
diff --git a/graphics/java/android/renderscript/Program.java b/graphics/java/android/renderscript/Program.java
index a1b1ba3..3f769ee 100644
--- a/graphics/java/android/renderscript/Program.java
+++ b/graphics/java/android/renderscript/Program.java
@@ -77,6 +77,40 @@
}
/**
+ * @hide
+ */
+ public int getConstantCount() {
+ return mConstants != null ? mConstants.length : 0;
+ }
+
+ /**
+ * @hide
+ */
+ public Type getConstant(int slot) {
+ if (slot < 0 || slot >= mConstants.length) {
+ throw new IllegalArgumentException("Slot ID out of range.");
+ }
+ return mConstants[slot];
+ }
+
+ /**
+ * @hide
+ */
+ public int getTextureCount() {
+ return mTextureCount;
+ }
+
+ /**
+ * @hide
+ */
+ public TextureType getTextureType(int slot) {
+ if ((slot < 0) || (slot >= mTextureCount)) {
+ throw new IllegalArgumentException("Slot ID out of range.");
+ }
+ return mTextures[slot];
+ }
+
+ /**
* Binds a constant buffer to be used as uniform inputs to the
* program
*
diff --git a/graphics/java/android/renderscript/ProgramVertex.java b/graphics/java/android/renderscript/ProgramVertex.java
index 56bb836..b3c1bd9 100644
--- a/graphics/java/android/renderscript/ProgramVertex.java
+++ b/graphics/java/android/renderscript/ProgramVertex.java
@@ -55,6 +55,23 @@
}
/**
+ * @hide
+ */
+ public int getInputCount() {
+ return mInputs != null ? mInputs.length : 0;
+ }
+
+ /**
+ * @hide
+ */
+ public Element getInput(int slot) {
+ if (slot < 0 || slot >= mInputs.length) {
+ throw new IllegalArgumentException("Slot ID out of range.");
+ }
+ return mInputs[slot];
+ }
+
+ /**
* Builder class for creating ProgramVertex objects.
* The builder starts empty and the user must minimally provide
* the GLSL shader code, and the varying inputs. Constant, or
diff --git a/graphics/java/android/renderscript/RenderScript.java b/graphics/java/android/renderscript/RenderScript.java
index bfe412c..d3c801f2 100644
--- a/graphics/java/android/renderscript/RenderScript.java
+++ b/graphics/java/android/renderscript/RenderScript.java
@@ -231,10 +231,10 @@
rsnTypeGetNativeData(mContext, id, typeData);
}
- native int rsnAllocationCreateTyped(int con, int type, int mip, int usage);
- synchronized int nAllocationCreateTyped(int type, int mip, int usage) {
+ native int rsnAllocationCreateTyped(int con, int type, int mip, int usage, int pointer);
+ synchronized int nAllocationCreateTyped(int type, int mip, int usage, int pointer) {
validate();
- return rsnAllocationCreateTyped(mContext, type, mip, usage);
+ return rsnAllocationCreateTyped(mContext, type, mip, usage, pointer);
}
native int rsnAllocationCreateFromBitmap(int con, int type, int mip, Bitmap bmp, int usage);
synchronized int nAllocationCreateFromBitmap(int type, int mip, Bitmap bmp, int usage) {
@@ -269,6 +269,12 @@
validate();
rsnAllocationSyncAll(mContext, alloc, src);
}
+ native int rsnAllocationGetSurfaceTextureID(int con, int alloc);
+ synchronized int nAllocationGetSurfaceTextureID(int alloc) {
+ validate();
+ return rsnAllocationGetSurfaceTextureID(mContext, alloc);
+ }
+
native void rsnAllocationGenerateMipmaps(int con, int alloc);
synchronized void nAllocationGenerateMipmaps(int alloc) {
validate();
@@ -584,6 +590,11 @@
rsnMeshGetIndices(mContext, id, idxIds, primitives, vtxIdCount);
}
+ native int rsnPathCreate(int con, int prim, boolean isStatic, int vtx, int loop, float q);
+ synchronized int nPathCreate(int prim, boolean isStatic, int vtx, int loop, float q) {
+ validate();
+ return rsnPathCreate(mContext, prim, isStatic, vtx, loop, q);
+ }
int mDev;
int mContext;
diff --git a/graphics/jni/android_renderscript_RenderScript.cpp b/graphics/jni/android_renderscript_RenderScript.cpp
index 07bf7bf..40dc980 100644
--- a/graphics/jni/android_renderscript_RenderScript.cpp
+++ b/graphics/jni/android_renderscript_RenderScript.cpp
@@ -430,10 +430,10 @@
// -----------------------------------
static jint
-nAllocationCreateTyped(JNIEnv *_env, jobject _this, RsContext con, jint type, jint mips, jint usage)
+nAllocationCreateTyped(JNIEnv *_env, jobject _this, RsContext con, jint type, jint mips, jint usage, jint pointer)
{
- LOG_API("nAllocationCreateTyped, con(%p), type(%p), mip(%i), usage(%i)", con, (RsElement)type, mips, usage);
- return (jint) rsAllocationCreateTyped(con, (RsType)type, (RsAllocationMipmapControl)mips, (uint32_t)usage);
+ LOG_API("nAllocationCreateTyped, con(%p), type(%p), mip(%i), usage(%i), ptr(%p)", con, (RsElement)type, mips, usage, (void *)pointer);
+ return (jint) rsAllocationCreateTyped(con, (RsType)type, (RsAllocationMipmapControl)mips, (uint32_t)usage, (uint32_t)pointer);
}
static void
@@ -443,6 +443,13 @@
rsAllocationSyncAll(con, (RsAllocation)a, (RsAllocationUsageType)bits);
}
+static jint
+nAllocationGetSurfaceTextureID(JNIEnv *_env, jobject _this, RsContext con, jint a)
+{
+ LOG_API("nAllocationGetSurfaceTextureID, con(%p), a(%p)", con, (RsAllocation)a);
+ return rsAllocationGetSurfaceTextureID(con, (RsAllocation)a);
+}
+
static void
nAllocationGenerateMipmaps(JNIEnv *_env, jobject _this, RsContext con, jint alloc)
{
@@ -1122,6 +1129,17 @@
// ---------------------------------------------------------------------------
+//native int rsnPathCreate(int con, int prim, boolean isStatic, int vtx, int loop, float q);
+static jint
+nPathCreate(JNIEnv *_env, jobject _this, RsContext con, jint prim, jboolean isStatic, jint _vtx, jint _loop, jfloat q) {
+ LOG_API("nPathCreate, con(%p)", con);
+
+ int id = (int)rsPathCreate(con, (RsPathPrimitive)prim, isStatic,
+ (RsAllocation)_vtx,
+ (RsAllocation)_loop, q);
+ return id;
+}
+
static jint
nMeshCreate(JNIEnv *_env, jobject _this, RsContext con, jintArray _vtx, jintArray _idx, jintArray _prim)
{
@@ -1250,7 +1268,7 @@
{"rsnTypeCreate", "(IIIIIZZ)I", (void*)nTypeCreate },
{"rsnTypeGetNativeData", "(II[I)V", (void*)nTypeGetNativeData },
-{"rsnAllocationCreateTyped", "(IIII)I", (void*)nAllocationCreateTyped },
+{"rsnAllocationCreateTyped", "(IIIII)I", (void*)nAllocationCreateTyped },
{"rsnAllocationCreateFromBitmap", "(IIILandroid/graphics/Bitmap;I)I", (void*)nAllocationCreateFromBitmap },
{"rsnAllocationCubeCreateFromBitmap","(IIILandroid/graphics/Bitmap;I)I", (void*)nAllocationCubeCreateFromBitmap },
@@ -1258,6 +1276,7 @@
{"rsnAllocationCopyToBitmap", "(IILandroid/graphics/Bitmap;)V", (void*)nAllocationCopyToBitmap },
{"rsnAllocationSyncAll", "(III)V", (void*)nAllocationSyncAll },
+{"rsnAllocationGetSurfaceTextureID", "(II)I", (void*)nAllocationGetSurfaceTextureID },
{"rsnAllocationData1D", "(IIIII[II)V", (void*)nAllocationData1D_i },
{"rsnAllocationData1D", "(IIIII[SI)V", (void*)nAllocationData1D_s },
{"rsnAllocationData1D", "(IIIII[BI)V", (void*)nAllocationData1D_b },
@@ -1310,6 +1329,7 @@
{"rsnSamplerCreate", "(IIIIIIF)I", (void*)nSamplerCreate },
+{"rsnPathCreate", "(IIZIIF)I", (void*)nPathCreate },
{"rsnMeshCreate", "(I[I[I[I)I", (void*)nMeshCreate },
{"rsnMeshGetVertexBufferCount", "(II)I", (void*)nMeshGetVertexBufferCount },
diff --git a/libs/rs/Android.mk b/libs/rs/Android.mk
index 58d3e5c..7f0cbeb 100644
--- a/libs/rs/Android.mk
+++ b/libs/rs/Android.mk
@@ -96,6 +96,7 @@
rsMatrix4x4.cpp \
rsMesh.cpp \
rsMutex.cpp \
+ rsPath.cpp \
rsProgram.cpp \
rsProgramFragment.cpp \
rsProgramStore.cpp \
@@ -118,6 +119,7 @@
driver/rsdGL.cpp \
driver/rsdMesh.cpp \
driver/rsdMeshObj.cpp \
+ driver/rsdPath.cpp \
driver/rsdProgram.cpp \
driver/rsdProgramRaster.cpp \
driver/rsdProgramStore.cpp \
@@ -203,6 +205,7 @@
rsMatrix4x4.cpp \
rsMesh.cpp \
rsMutex.cpp \
+ rsPath.cpp \
rsProgram.cpp \
rsProgramFragment.cpp \
rsProgramStore.cpp \
diff --git a/libs/rs/RenderScriptDefines.h b/libs/rs/RenderScriptDefines.h
index d092520..990ef26 100644
--- a/libs/rs/RenderScriptDefines.h
+++ b/libs/rs/RenderScriptDefines.h
@@ -41,6 +41,7 @@
typedef void * RsSampler;
typedef void * RsScript;
typedef void * RsMesh;
+typedef void * RsPath;
typedef void * RsType;
typedef void * RsObjectBase;
@@ -99,8 +100,11 @@
RS_ALLOCATION_USAGE_GRAPHICS_VERTEX = 0x0004,
RS_ALLOCATION_USAGE_GRAPHICS_CONSTANTS = 0x0008,
RS_ALLOCATION_USAGE_GRAPHICS_RENDER_TARGET = 0x0010,
+ RS_ALLOCATION_USAGE_GRAPHICS_SURFACE_TEXTURE_INPUT_OPAQUE = 0x0020,
+ RS_ALLOCATION_USAGE_IO_INPUT = 0x0040,
+ RS_ALLOCATION_USAGE_IO_OUTPUT = 0x0080,
- RS_ALLOCATION_USAGE_ALL = 0x000F
+ RS_ALLOCATION_USAGE_ALL = 0x00FF
};
enum RsAllocationMipmapControl {
@@ -152,6 +156,8 @@
RS_TYPE_PROGRAM_VERTEX,
RS_TYPE_PROGRAM_RASTER,
RS_TYPE_PROGRAM_STORE,
+
+ RS_TYPE_INVALID = 10000,
};
enum RsDataKind {
@@ -163,6 +169,8 @@
RS_KIND_PIXEL_RGB,
RS_KIND_PIXEL_RGBA,
RS_KIND_PIXEL_DEPTH,
+
+ RS_KIND_INVALID = 100,
};
enum RsSamplerParam {
@@ -181,6 +189,8 @@
RS_SAMPLER_WRAP,
RS_SAMPLER_CLAMP,
RS_SAMPLER_LINEAR_MIP_NEAREST,
+
+ RS_SAMPLER_INVALID = 100,
};
enum RsTextureTarget {
@@ -221,7 +231,8 @@
RS_BLEND_SRC_ONE_MINUS_SRC_ALPHA, // 5
RS_BLEND_SRC_DST_ALPHA, // 6
RS_BLEND_SRC_ONE_MINUS_DST_ALPHA, // 7
- RS_BLEND_SRC_SRC_ALPHA_SATURATE // 8
+ RS_BLEND_SRC_SRC_ALPHA_SATURATE, // 8
+ RS_BLEND_SRC_INVALID = 100,
};
enum RsBlendDstFunc {
@@ -232,7 +243,9 @@
RS_BLEND_DST_SRC_ALPHA, // 4
RS_BLEND_DST_ONE_MINUS_SRC_ALPHA, // 5
RS_BLEND_DST_DST_ALPHA, // 6
- RS_BLEND_DST_ONE_MINUS_DST_ALPHA // 7
+ RS_BLEND_DST_ONE_MINUS_DST_ALPHA, // 7
+
+ RS_BLEND_DST_INVALID = 100,
};
enum RsTexEnvMode {
@@ -255,7 +268,14 @@
RS_PRIMITIVE_LINE_STRIP,
RS_PRIMITIVE_TRIANGLE,
RS_PRIMITIVE_TRIANGLE_STRIP,
- RS_PRIMITIVE_TRIANGLE_FAN
+ RS_PRIMITIVE_TRIANGLE_FAN,
+
+ RS_PRIMITIVE_INVALID = 100,
+};
+
+enum RsPathPrimitive {
+ RS_PATH_PRIMITIVE_QUADRATIC_BEZIER,
+ RS_PATH_PRIMITIVE_CUBIC_BEZIER
};
enum RsError {
@@ -309,7 +329,8 @@
enum RsCullMode {
RS_CULL_BACK,
RS_CULL_FRONT,
- RS_CULL_NONE
+ RS_CULL_NONE,
+ RS_CULL_INVALID = 100,
};
typedef struct {
diff --git a/libs/rs/driver/rsdAllocation.cpp b/libs/rs/driver/rsdAllocation.cpp
index 1f70e66..ea92192 100644
--- a/libs/rs/driver/rsdAllocation.cpp
+++ b/libs/rs/driver/rsdAllocation.cpp
@@ -134,6 +134,13 @@
static void UploadToTexture(const Context *rsc, const Allocation *alloc) {
DrvAllocation *drv = (DrvAllocation *)alloc->mHal.drv;
+ if (alloc->mHal.state.usageFlags & RS_ALLOCATION_USAGE_GRAPHICS_SURFACE_TEXTURE_INPUT_OPAQUE) {
+ if (!drv->textureID) {
+ RSD_CALL_GL(glGenTextures, 1, &drv->textureID);
+ }
+ return;
+ }
+
if (!drv->glType || !drv->glFormat) {
return;
}
@@ -212,10 +219,13 @@
return false;
}
- void * ptr = malloc(alloc->mHal.state.type->getSizeBytes());
+ void * ptr = alloc->mHal.state.usrPtr;
if (!ptr) {
- free(drv);
- return false;
+ ptr = malloc(alloc->mHal.state.type->getSizeBytes());
+ if (!ptr) {
+ free(drv);
+ return false;
+ }
}
drv->glTarget = GL_NONE;
@@ -269,7 +279,7 @@
drv->renderTargetID = 0;
}
- if (drv->mallocPtr) {
+ if (drv->mallocPtr && !alloc->mHal.state.usrPtr) {
free(drv->mallocPtr);
drv->mallocPtr = NULL;
}
@@ -370,6 +380,12 @@
drv->uploadDeferred = true;
}
+int32_t rsdAllocationInitSurfaceTexture(const Context *rsc, const Allocation *alloc) {
+ DrvAllocation *drv = (DrvAllocation *)alloc->mHal.drv;
+ UploadToTexture(rsc, alloc);
+ return drv->textureID;
+}
+
void rsdAllocationData1D(const Context *rsc, const Allocation *alloc,
uint32_t xoff, uint32_t lod, uint32_t count,
const void *data, uint32_t sizeBytes) {
diff --git a/libs/rs/driver/rsdAllocation.h b/libs/rs/driver/rsdAllocation.h
index 4fc4419..230804b 100644
--- a/libs/rs/driver/rsdAllocation.h
+++ b/libs/rs/driver/rsdAllocation.h
@@ -67,6 +67,8 @@
RsAllocationUsageType src);
void rsdAllocationMarkDirty(const android::renderscript::Context *rsc,
const android::renderscript::Allocation *alloc);
+int32_t rsdAllocationInitSurfaceTexture(const android::renderscript::Context *rsc,
+ const android::renderscript::Allocation *alloc);
void rsdAllocationData1D(const android::renderscript::Context *rsc,
const android::renderscript::Allocation *alloc,
diff --git a/libs/rs/driver/rsdCore.cpp b/libs/rs/driver/rsdCore.cpp
index 1a535d0..e011955 100644
--- a/libs/rs/driver/rsdCore.cpp
+++ b/libs/rs/driver/rsdCore.cpp
@@ -18,6 +18,7 @@
#include "rsdAllocation.h"
#include "rsdBcc.h"
#include "rsdGL.h"
+#include "rsdPath.h"
#include "rsdProgramStore.h"
#include "rsdProgramRaster.h"
#include "rsdProgramVertex.h"
@@ -72,6 +73,7 @@
rsdAllocationResize,
rsdAllocationSyncAll,
rsdAllocationMarkDirty,
+ rsdAllocationInitSurfaceTexture,
rsdAllocationData1D,
rsdAllocationData2D,
rsdAllocationData3D,
@@ -114,6 +116,13 @@
},
{
+ rsdPathInitStatic,
+ rsdPathInitDynamic,
+ rsdPathDraw,
+ rsdPathDestroy
+ },
+
+ {
rsdSamplerInit,
rsdSamplerDestroy
},
@@ -259,6 +268,9 @@
for (uint32_t ct=0; ct < dc->mWorkers.mCount; ct++) {
setpriority(PRIO_PROCESS, dc->mWorkers.mNativeThreadId[ct], priority);
}
+ if (dc->mHasGraphics) {
+ rsdGLSetPriority(rsc, priority);
+ }
}
void Shutdown(Context *rsc) {
diff --git a/libs/rs/driver/rsdCore.h b/libs/rs/driver/rsdCore.h
index 126c87a..168bdf3 100644
--- a/libs/rs/driver/rsdCore.h
+++ b/libs/rs/driver/rsdCore.h
@@ -41,6 +41,7 @@
typedef struct RsdHalRec {
uint32_t version_major;
uint32_t version_minor;
+ bool mHasGraphics;
struct Workers {
volatile int mRunningCount;
diff --git a/libs/rs/driver/rsdGL.cpp b/libs/rs/driver/rsdGL.cpp
index 7acc054..25b3990 100644
--- a/libs/rs/driver/rsdGL.cpp
+++ b/libs/rs/driver/rsdGL.cpp
@@ -359,6 +359,7 @@
dc->gl.vertexArrayState = new RsdVertexArrayState();
dc->gl.vertexArrayState->init(dc->gl.gl.maxVertexAttribs);
dc->gl.currentFrameBuffer = NULL;
+ dc->mHasGraphics = true;
ALOGV("%p initGLThread end", rsc);
rsc->setWatchdogGL(NULL, 0, NULL);
@@ -419,6 +420,15 @@
RSD_CALL_GL(eglSwapBuffers, dc->gl.egl.display, dc->gl.egl.surface);
}
+void rsdGLSetPriority(const Context *rsc, int32_t priority) {
+ if (priority > 0) {
+ // Mark context as low priority.
+ ALOGV("low pri");
+ } else {
+ ALOGV("normal pri");
+ }
+}
+
void rsdGLCheckError(const android::renderscript::Context *rsc,
const char *msg, bool isFatal) {
GLenum err = glGetError();
diff --git a/libs/rs/driver/rsdGL.h b/libs/rs/driver/rsdGL.h
index 51893c3..e015cb1 100644
--- a/libs/rs/driver/rsdGL.h
+++ b/libs/rs/driver/rsdGL.h
@@ -82,6 +82,8 @@
void rsdGLSwap(const android::renderscript::Context *rsc);
void rsdGLCheckError(const android::renderscript::Context *rsc,
const char *msg, bool isFatal = false);
+void rsdGLSetPriority(const android::renderscript::Context *rsc,
+ int32_t priority);
#endif
diff --git a/libs/rs/driver/rsdMesh.cpp b/libs/rs/driver/rsdMesh.cpp
index eb62ddb..50daf3e 100644
--- a/libs/rs/driver/rsdMesh.cpp
+++ b/libs/rs/driver/rsdMesh.cpp
@@ -35,7 +35,7 @@
}
drv = new RsdMeshObj(rsc, m);
m->mHal.drv = drv;
- return drv->init();
+ return drv->init(rsc);
}
void rsdMeshDraw(const Context *rsc, const Mesh *m, uint32_t primIndex, uint32_t start, uint32_t len) {
diff --git a/libs/rs/driver/rsdMeshObj.cpp b/libs/rs/driver/rsdMeshObj.cpp
index 99d79dc..893f046 100644
--- a/libs/rs/driver/rsdMeshObj.cpp
+++ b/libs/rs/driver/rsdMeshObj.cpp
@@ -50,14 +50,9 @@
}
bool RsdMeshObj::isValidGLComponent(const Element *elem, uint32_t fieldIdx) {
- // Do not create attribs for padding
- if (elem->getFieldName(fieldIdx)[0] == '#') {
- return false;
- }
-
// Only GL_BYTE, GL_UNSIGNED_BYTE, GL_SHORT, GL_UNSIGNED_SHORT, GL_FIXED, GL_FLOAT are accepted.
// Filter rs types accordingly
- RsDataType dt = elem->getField(fieldIdx)->getComponent().getType();
+ RsDataType dt = elem->mHal.state.fields[fieldIdx]->mHal.state.dataType;
if (dt != RS_TYPE_FLOAT_32 && dt != RS_TYPE_UNSIGNED_8 &&
dt != RS_TYPE_UNSIGNED_16 && dt != RS_TYPE_SIGNED_8 &&
dt != RS_TYPE_SIGNED_16) {
@@ -65,7 +60,7 @@
}
// Now make sure they are not arrays
- uint32_t arraySize = elem->getFieldArraySize(fieldIdx);
+ uint32_t arraySize = elem->mHal.state.fieldArraySizes[fieldIdx];
if (arraySize != 1) {
return false;
}
@@ -73,15 +68,15 @@
return true;
}
-bool RsdMeshObj::init() {
+bool RsdMeshObj::init(const Context *rsc) {
- updateGLPrimitives();
+ updateGLPrimitives(rsc);
// Count the number of gl attrs to initialize
mAttribCount = 0;
for (uint32_t ct=0; ct < mRSMesh->mHal.state.vertexBuffersCount; ct++) {
const Element *elem = mRSMesh->mHal.state.vertexBuffers[ct]->getType()->getElement();
- for (uint32_t ct=0; ct < elem->getFieldCount(); ct++) {
+ for (uint32_t ct=0; ct < elem->mHal.state.fieldsCount; ct++) {
if (isValidGLComponent(elem, ct)) {
mAttribCount ++;
}
@@ -104,21 +99,21 @@
uint32_t userNum = 0;
for (uint32_t ct=0; ct < mRSMesh->mHal.state.vertexBuffersCount; ct++) {
const Element *elem = mRSMesh->mHal.state.vertexBuffers[ct]->getType()->getElement();
- uint32_t stride = elem->getSizeBytes();
- for (uint32_t fieldI=0; fieldI < elem->getFieldCount(); fieldI++) {
- const Component &c = elem->getField(fieldI)->getComponent();
+ uint32_t stride = elem->mHal.state.elementSizeBytes;
+ for (uint32_t fieldI=0; fieldI < elem->mHal.state.fieldsCount; fieldI++) {
+ const Element *f = elem->mHal.state.fields[fieldI];
if (!isValidGLComponent(elem, fieldI)) {
continue;
}
- mAttribs[userNum].size = c.getVectorSize();
- mAttribs[userNum].offset = elem->getFieldOffsetBytes(fieldI);
- mAttribs[userNum].type = rsdTypeToGLType(c.getType());
- mAttribs[userNum].normalized = c.getType() != RS_TYPE_FLOAT_32;//c.getIsNormalized();
+ mAttribs[userNum].size = f->mHal.state.vectorSize;
+ mAttribs[userNum].offset = elem->mHal.state.fieldOffsetBytes[fieldI];
+ mAttribs[userNum].type = rsdTypeToGLType(f->mHal.state.dataType);
+ mAttribs[userNum].normalized = f->mHal.state.dataType != RS_TYPE_FLOAT_32;
mAttribs[userNum].stride = stride;
String8 tmp(RS_SHADER_ATTR);
- tmp.append(elem->getFieldName(fieldI));
+ tmp.append(elem->mHal.state.fieldNames[fieldI]);
mAttribs[userNum].name.setTo(tmp.string());
// Remember which allocation this attribute came from
@@ -133,7 +128,7 @@
void RsdMeshObj::renderPrimitiveRange(const Context *rsc, uint32_t primIndex,
uint32_t start, uint32_t len) const {
if (len < 1 || primIndex >= mRSMesh->mHal.state.primitivesCount || mAttribCount == 0) {
- ALOGE("Invalid mesh or parameters");
+ rsc->setError(RS_ERROR_FATAL_DRIVER, "Invalid mesh or parameters");
return;
}
@@ -186,7 +181,7 @@
rsdGLCheckError(rsc, "Mesh::renderPrimitiveRange");
}
-void RsdMeshObj::updateGLPrimitives() {
+void RsdMeshObj::updateGLPrimitives(const Context *rsc) {
mGLPrimitives = new uint32_t[mRSMesh->mHal.state.primitivesCount];
for (uint32_t i = 0; i < mRSMesh->mHal.state.primitivesCount; i ++) {
switch (mRSMesh->mHal.state.primitives[i]) {
@@ -196,6 +191,7 @@
case RS_PRIMITIVE_TRIANGLE: mGLPrimitives[i] = GL_TRIANGLES; break;
case RS_PRIMITIVE_TRIANGLE_STRIP: mGLPrimitives[i] = GL_TRIANGLE_STRIP; break;
case RS_PRIMITIVE_TRIANGLE_FAN: mGLPrimitives[i] = GL_TRIANGLE_FAN; break;
+ default: rsc->setError(RS_ERROR_FATAL_DRIVER, "Invalid mesh primitive"); break;
}
}
}
diff --git a/libs/rs/driver/rsdMeshObj.h b/libs/rs/driver/rsdMeshObj.h
index 8b1271b..1370f01 100644
--- a/libs/rs/driver/rsdMeshObj.h
+++ b/libs/rs/driver/rsdMeshObj.h
@@ -37,15 +37,16 @@
const android::renderscript::Mesh *);
~RsdMeshObj();
- void renderPrimitiveRange(const android::renderscript::Context *, uint32_t primIndex, uint32_t start, uint32_t len) const;
+ void renderPrimitiveRange(const android::renderscript::Context *,
+ uint32_t primIndex, uint32_t start, uint32_t len) const;
- bool init();
+ bool init(const android::renderscript::Context *rsc);
protected:
const android::renderscript::Mesh *mRSMesh;
uint32_t *mGLPrimitives;
- void updateGLPrimitives();
+ void updateGLPrimitives(const android::renderscript::Context *rsc);
bool isValidGLComponent(const android::renderscript::Element *elem, uint32_t fieldIdx);
// Attribues that allow us to map to GL
diff --git a/libs/rs/driver/rsdPath.cpp b/libs/rs/driver/rsdPath.cpp
new file mode 100644
index 0000000..e04bc02
--- /dev/null
+++ b/libs/rs/driver/rsdPath.cpp
@@ -0,0 +1,185 @@
+/*
+ * Copyright (C) 2011 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.
+ */
+
+#include <GLES/gl.h>
+#include <GLES2/gl2.h>
+#include <GLES/glext.h>
+
+#include <rs_hal.h>
+#include <rsContext.h>
+#include <rsPath.h>
+
+#include "rsdCore.h"
+#include "rsdPath.h"
+#include "rsdAllocation.h"
+#include "rsdGL.h"
+#include "rsdVertexArray.h"
+#include "rsdShaderCache.h"
+
+using namespace android;
+using namespace android::renderscript;
+
+class DrvPath {
+protected:
+ DrvPath();
+public:
+ virtual ~DrvPath();
+ virtual void draw(Context *) = 0;
+};
+
+class DrvPathStatic : public DrvPath {
+public:
+ typedef struct {
+ float x1, xc, x2;
+ float y1, yc, y2;
+ } segment_t;
+
+ segment_t *mSegments;
+ uint32_t mSegmentCount;
+
+ DrvPathStatic(const Allocation *vtx, const Allocation *loops);
+ virtual ~DrvPathStatic();
+
+ virtual void draw(Context *);
+};
+
+class DrvPathDynamic : public DrvPath {
+public:
+ DrvPathDynamic();
+ virtual ~DrvPathDynamic();
+};
+
+static void cleanup(const Context *rsc, const Path *m) {
+ DrvPath *dp = (DrvPath *)m->mHal.drv;
+ if (dp) {
+ delete dp;
+ }
+}
+
+bool rsdPathInitStatic(const Context *rsc, const Path *m,
+ const Allocation *vtx, const Allocation *loops) {
+ DrvPathStatic *drv = NULL;
+ cleanup(rsc, m);
+
+ DrvPathStatic *dps = new DrvPathStatic(vtx, loops);
+ //LOGE("init path m %p, %p", m, dps);
+ m->mHal.drv = dps;
+ return dps != NULL;
+}
+
+bool rsdPathInitDynamic(const Context *rsc, const Path *m) {
+ return false;
+}
+
+
+void rsdPathDraw(const Context *rsc, const Path *m) {
+ //LOGE("render m=%p", m);
+
+ DrvPath *drv = (DrvPath *)m->mHal.drv;
+ if(drv) {
+ //LOGE("render 2 drv=%p", drv);
+ drv->draw((Context *)rsc);
+ }
+}
+
+void rsdPathDestroy(const Context *rsc, const Path *m) {
+ cleanup(rsc, m);
+ m->mHal.drv = NULL;
+}
+
+
+
+
+DrvPath::DrvPath() {
+}
+
+DrvPath::~DrvPath() {
+}
+
+DrvPathStatic::DrvPathStatic(const Allocation *vtx, const Allocation *loops) {
+ mSegmentCount = vtx->getType()->getDimX() / 3;
+ mSegments = new segment_t[mSegmentCount];
+
+ const float *fin = (const float *)vtx->getPtr();
+ for (uint32_t ct=0; ct < mSegmentCount; ct++) {
+ segment_t *s = &mSegments[ct];
+ s->x1 = fin[0];
+ s->y1 = fin[1];
+
+ s->xc = fin[2];
+ s->yc = fin[3];
+
+ s->x2 = fin[4];
+ s->y2 = fin[5];
+ fin += 6;
+ }
+}
+
+DrvPathStatic::~DrvPathStatic() {
+}
+
+void DrvPathStatic::draw(Context *rsc) {
+ const static float color[24] = {
+ 1.f, 0.f, 0.f, 1.f, 0.5f, 0.f, 0.f, 1.f,
+ 1.f, 0.f, 0.f, 1.f, 0.5f, 0.f, 0.f, 1.f,
+ 1.f, 1.f, 1.f, 1.f, 1.f, 1.f, 1.f, 1.f};
+ float vtx[12];
+
+ //LOGE("draw");
+ if (!rsc->setupCheck()) {
+ return;
+ }
+
+ RsdHal *dc = (RsdHal *)rsc->mHal.drv;
+ if (!dc->gl.shaderCache->setup(rsc)) {
+ return;
+ }
+
+ RsdVertexArray::Attrib attribs[2];
+ attribs[0].set(GL_FLOAT, 2, 8, false, (uint32_t)vtx, "ATTRIB_position");
+ attribs[1].set(GL_FLOAT, 4, 16, false, (uint32_t)color, "ATTRIB_color");
+ RsdVertexArray va(attribs, 2);
+ va.setup(rsc);
+
+ //LOGE("mSegmentCount %i", mSegmentCount);
+ for (uint32_t ct=0; ct < mSegmentCount; ct++) {
+ segment_t *s = &mSegments[ct];
+
+ vtx[0] = s->x1;
+ vtx[1] = s->y1;
+ vtx[2] = s->xc;
+ vtx[3] = s->yc;
+
+ vtx[4] = s->x2;
+ vtx[5] = s->y2;
+ vtx[6] = s->xc;
+ vtx[7] = s->yc;
+
+ vtx[8] = s->x1;
+ vtx[9] = s->y1;
+ vtx[10] = s->x2;
+ vtx[11] = s->y2;
+
+ RSD_CALL_GL(glDrawArrays, GL_LINES, 0, 6);
+ }
+
+}
+
+DrvPathDynamic::DrvPathDynamic() {
+}
+
+DrvPathDynamic::~DrvPathDynamic() {
+}
diff --git a/libs/rs/driver/rsdPath.h b/libs/rs/driver/rsdPath.h
new file mode 100644
index 0000000..fa00972
--- /dev/null
+++ b/libs/rs/driver/rsdPath.h
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2011 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.
+ */
+
+#ifndef RSD_PATH_H
+#define RSD_PATH_H
+
+#include <rs_hal.h>
+
+
+bool rsdPathInitStatic(const android::renderscript::Context *rsc,
+ const android::renderscript::Path *m,
+ const android::renderscript::Allocation *vertex,
+ const android::renderscript::Allocation *loops);
+bool rsdPathInitDynamic(const android::renderscript::Context *rsc,
+ const android::renderscript::Path *m);
+void rsdPathDraw(const android::renderscript::Context *rsc,
+ const android::renderscript::Path *m);
+void rsdPathDestroy(const android::renderscript::Context *rsc,
+ const android::renderscript::Path *m);
+
+
+#endif
diff --git a/libs/rs/driver/rsdProgramRaster.cpp b/libs/rs/driver/rsdProgramRaster.cpp
index b493759..e5a0291 100644
--- a/libs/rs/driver/rsdProgramRaster.cpp
+++ b/libs/rs/driver/rsdProgramRaster.cpp
@@ -45,6 +45,9 @@
case RS_CULL_NONE:
RSD_CALL_GL(glDisable, GL_CULL_FACE);
break;
+ default:
+ rsc->setError(RS_ERROR_FATAL_DRIVER, "Invalid cull type");
+ break;
}
}
diff --git a/libs/rs/driver/rsdProgramStore.cpp b/libs/rs/driver/rsdProgramStore.cpp
index fca9ba9..c1295e8 100644
--- a/libs/rs/driver/rsdProgramStore.cpp
+++ b/libs/rs/driver/rsdProgramStore.cpp
@@ -111,7 +111,7 @@
drv->blendSrc = GL_SRC_ALPHA_SATURATE;
break;
default:
- ALOGE("Unknown blend src mode.");
+ rsc->setError(RS_ERROR_FATAL_DRIVER, "Unknown blend src mode.");
goto error;
}
@@ -141,7 +141,7 @@
drv->blendDst = GL_ONE_MINUS_DST_ALPHA;
break;
default:
- ALOGE("Unknown blend dst mode.");
+ rsc->setError(RS_ERROR_FATAL_DRIVER, "Unknown blend dst mode.");
goto error;
}
diff --git a/libs/rs/driver/rsdRuntimeStubs.cpp b/libs/rs/driver/rsdRuntimeStubs.cpp
index 14c2970..44bfb1c 100644
--- a/libs/rs/driver/rsdRuntimeStubs.cpp
+++ b/libs/rs/driver/rsdRuntimeStubs.cpp
@@ -25,6 +25,7 @@
#include "rsdCore.h"
#include "rsdRuntime.h"
+#include "rsdPath.h"
#include <time.h>
@@ -89,6 +90,16 @@
rsrBindTexture(rsc, sc, pf, slot, a);
}
+static void SC_BindVertexConstant(ProgramVertex *pv, uint32_t slot, Allocation *a) {
+ GET_TLS();
+ rsrBindConstant(rsc, sc, pv, slot, a);
+}
+
+static void SC_BindFragmentConstant(ProgramFragment *pf, uint32_t slot, Allocation *a) {
+ GET_TLS();
+ rsrBindConstant(rsc, sc, pf, slot, a);
+}
+
static void SC_BindSampler(ProgramFragment *pf, uint32_t slot, Sampler *s) {
GET_TLS();
rsrBindSampler(rsc, sc, pf, slot, s);
@@ -204,6 +215,12 @@
rsrDrawRect(rsc, sc, x1, y1, x2, y2, z);
}
+static void SC_DrawPath(Path *p) {
+ GET_TLS();
+ //rsrDrawPath(rsc, sc, p);
+ rsdPathDraw(rsc, p);
+}
+
static void SC_DrawMesh(Mesh *m) {
GET_TLS();
rsrDrawMesh(rsc, sc, m);
@@ -533,6 +550,10 @@
{ "_Z13rsClearObjectP9rs_script", (void *)&SC_ClearObject, true },
{ "_Z10rsIsObject9rs_script", (void *)&SC_IsObject, true },
+ { "_Z11rsSetObjectP7rs_pathS_", (void *)&SC_SetObject, true },
+ { "_Z13rsClearObjectP7rs_path", (void *)&SC_ClearObject, true },
+ { "_Z10rsIsObject7rs_path", (void *)&SC_IsObject, true },
+
{ "_Z11rsSetObjectP7rs_meshS_", (void *)&SC_SetObject, true },
{ "_Z13rsClearObjectP7rs_mesh", (void *)&SC_ClearObject, true },
{ "_Z10rsIsObject7rs_mesh", (void *)&SC_IsObject, true },
@@ -580,6 +601,8 @@
{ "_Z20rsgBindProgramRaster17rs_program_raster", (void *)&SC_BindProgramRaster, false },
{ "_Z14rsgBindSampler19rs_program_fragmentj10rs_sampler", (void *)&SC_BindSampler, false },
{ "_Z14rsgBindTexture19rs_program_fragmentj13rs_allocation", (void *)&SC_BindTexture, false },
+ { "_Z15rsgBindConstant19rs_program_fragmentj13rs_allocation", (void *)&SC_BindFragmentConstant, false },
+ { "_Z15rsgBindConstant17rs_program_vertexj13rs_allocation", (void *)&SC_BindVertexConstant, false },
{ "_Z36rsgProgramVertexLoadProjectionMatrixPK12rs_matrix4x4", (void *)&SC_VpLoadProjectionMatrix, false },
{ "_Z31rsgProgramVertexLoadModelMatrixPK12rs_matrix4x4", (void *)&SC_VpLoadModelMatrix, false },
@@ -603,6 +626,8 @@
{ "_Z11rsgDrawMesh7rs_meshjjj", (void *)&SC_DrawMeshPrimitiveRange, false },
{ "_Z25rsgMeshComputeBoundingBox7rs_meshPfS0_S0_S0_S0_S0_", (void *)&SC_MeshComputeBoundingBox, false },
+ { "_Z11rsgDrawPath7rs_path", (void *)&SC_DrawPath, false },
+
{ "_Z13rsgClearColorffff", (void *)&SC_ClearColor, false },
{ "_Z13rsgClearDepthf", (void *)&SC_ClearDepth, false },
diff --git a/libs/rs/driver/rsdShader.cpp b/libs/rs/driver/rsdShader.cpp
index c70193ae..ef8516f 100644
--- a/libs/rs/driver/rsdShader.cpp
+++ b/libs/rs/driver/rsdShader.cpp
@@ -90,12 +90,12 @@
String8 s;
for (uint32_t ct=0; ct < mRSProgram->mHal.state.inputElementsCount; ct++) {
const Element *e = mRSProgram->mHal.state.inputElements[ct];
- for (uint32_t field=0; field < e->getFieldCount(); field++) {
- const Element *f = e->getField(field);
+ for (uint32_t field=0; field < e->mHal.state.fieldsCount; field++) {
+ const Element *f = e->mHal.state.fields[field];
// Cannot be complex
- rsAssert(!f->getFieldCount());
- switch (f->getComponent().getVectorSize()) {
+ rsAssert(!f->mHal.state.fieldsCount);
+ switch (f->mHal.state.vectorSize) {
case 1: s.append("attribute float ATTRIB_"); break;
case 2: s.append("attribute vec2 ATTRIB_"); break;
case 3: s.append("attribute vec3 ATTRIB_"); break;
@@ -104,7 +104,7 @@
rsAssert(0);
}
- s.append(e->getFieldName(field));
+ s.append(e->mHal.state.fieldNames[field]);
s.append(";\n");
}
}
@@ -114,17 +114,13 @@
void RsdShader::appendAttributes() {
for (uint32_t ct=0; ct < mRSProgram->mHal.state.inputElementsCount; ct++) {
const Element *e = mRSProgram->mHal.state.inputElements[ct];
- for (uint32_t field=0; field < e->getFieldCount(); field++) {
- const Element *f = e->getField(field);
- const char *fn = e->getFieldName(field);
-
- if (fn[0] == '#') {
- continue;
- }
+ for (uint32_t field=0; field < e->mHal.state.fieldsCount; field++) {
+ const Element *f = e->mHal.state.fields[field];
+ const char *fn = e->mHal.state.fieldNames[field];
// Cannot be complex
- rsAssert(!f->getFieldCount());
- switch (f->getComponent().getVectorSize()) {
+ rsAssert(!f->mHal.state.fieldsCount);
+ switch (f->mHal.state.vectorSize) {
case 1: mShader.append("attribute float ATTRIB_"); break;
case 2: mShader.append("attribute vec2 ATTRIB_"); break;
case 3: mShader.append("attribute vec3 ATTRIB_"); break;
@@ -143,7 +139,12 @@
char buf[256];
for (uint32_t ct=0; ct < mRSProgram->mHal.state.texturesCount; ct++) {
if (mRSProgram->mHal.state.textureTargets[ct] == RS_TEXTURE_2D) {
- snprintf(buf, sizeof(buf), "uniform sampler2D UNI_Tex%i;\n", ct);
+ Allocation *a = mRSProgram->mHal.state.textures[ct];
+ if (a && a->mHal.state.surfaceTextureID) {
+ snprintf(buf, sizeof(buf), "uniform samplerExternalOES UNI_Tex%i;\n", ct);
+ } else {
+ snprintf(buf, sizeof(buf), "uniform sampler2D UNI_Tex%i;\n", ct);
+ }
mTextureTargets[ct] = GL_TEXTURE_2D;
} else {
snprintf(buf, sizeof(buf), "uniform samplerCube UNI_Tex%i;\n", ct);
@@ -211,24 +212,20 @@
void RsdShader::appendUserConstants() {
for (uint32_t ct=0; ct < mRSProgram->mHal.state.constantsCount; ct++) {
const Element *e = mRSProgram->mHal.state.constantTypes[ct]->getElement();
- for (uint32_t field=0; field < e->getFieldCount(); field++) {
- const Element *f = e->getField(field);
- const char *fn = e->getFieldName(field);
-
- if (fn[0] == '#') {
- continue;
- }
+ for (uint32_t field=0; field < e->mHal.state.fieldsCount; field++) {
+ const Element *f = e->mHal.state.fields[field];
+ const char *fn = e->mHal.state.fieldNames[field];
// Cannot be complex
- rsAssert(!f->getFieldCount());
- if (f->getType() == RS_TYPE_MATRIX_4X4) {
+ rsAssert(!f->mHal.state.fieldsCount);
+ if (f->mHal.state.dataType == RS_TYPE_MATRIX_4X4) {
mShader.append("uniform mat4 UNI_");
- } else if (f->getType() == RS_TYPE_MATRIX_3X3) {
+ } else if (f->mHal.state.dataType == RS_TYPE_MATRIX_3X3) {
mShader.append("uniform mat3 UNI_");
- } else if (f->getType() == RS_TYPE_MATRIX_2X2) {
+ } else if (f->mHal.state.dataType == RS_TYPE_MATRIX_2X2) {
mShader.append("uniform mat2 UNI_");
} else {
- switch (f->getComponent().getVectorSize()) {
+ switch (f->mHal.state.vectorSize) {
case 1: mShader.append("uniform float UNI_"); break;
case 2: mShader.append("uniform vec2 UNI_"); break;
case 3: mShader.append("uniform vec3 UNI_"); break;
@@ -239,8 +236,8 @@
}
mShader.append(fn);
- if (e->getFieldArraySize(field) > 1) {
- mShader.appendFormat("[%d]", e->getFieldArraySize(field));
+ if (e->mHal.state.fieldArraySizes[field] > 1) {
+ mShader.appendFormat("[%d]", e->mHal.state.fieldArraySizes[field]);
}
mShader.append(";\n");
}
@@ -248,8 +245,8 @@
}
void RsdShader::logUniform(const Element *field, const float *fd, uint32_t arraySize ) {
- RsDataType dataType = field->getType();
- uint32_t elementSize = field->getSizeBytes() / sizeof(float);
+ RsDataType dataType = field->mHal.state.dataType;
+ uint32_t elementSize = field->mHal.state.elementSizeBytes / sizeof(float);
for (uint32_t i = 0; i < arraySize; i ++) {
if (arraySize > 1) {
ALOGV("Array Element [%u]", i);
@@ -270,7 +267,7 @@
ALOGV("{%f, %f", fd[0], fd[2]);
ALOGV(" %f, %f}", fd[1], fd[3]);
} else {
- switch (field->getComponent().getVectorSize()) {
+ switch (field->mHal.state.vectorSize) {
case 1:
ALOGV("Uniform 1 = %f", fd[0]);
break;
@@ -295,7 +292,7 @@
void RsdShader::setUniform(const Context *rsc, const Element *field, const float *fd,
int32_t slot, uint32_t arraySize ) {
- RsDataType dataType = field->getType();
+ RsDataType dataType = field->mHal.state.dataType;
if (dataType == RS_TYPE_MATRIX_4X4) {
RSD_CALL_GL(glUniformMatrix4fv, slot, arraySize, GL_FALSE, fd);
} else if (dataType == RS_TYPE_MATRIX_3X3) {
@@ -303,7 +300,7 @@
} else if (dataType == RS_TYPE_MATRIX_2X2) {
RSD_CALL_GL(glUniformMatrix2fv, slot, arraySize, GL_FALSE, fd);
} else {
- switch (field->getComponent().getVectorSize()) {
+ switch (field->mHal.state.vectorSize) {
case 1:
RSD_CALL_GL(glUniform1fv, slot, arraySize, fd);
break;
@@ -458,15 +455,11 @@
const uint8_t *data = static_cast<const uint8_t *>(alloc->getPtr());
const Element *e = mRSProgram->mHal.state.constantTypes[ct]->getElement();
- for (uint32_t field=0; field < e->getFieldCount(); field++) {
- const Element *f = e->getField(field);
- const char *fieldName = e->getFieldName(field);
- // If this field is padding, skip it
- if (fieldName[0] == '#') {
- continue;
- }
+ for (uint32_t field=0; field < e->mHal.state.fieldsCount; field++) {
+ const Element *f = e->mHal.state.fields[field];
+ const char *fieldName = e->mHal.state.fieldNames[field];
- uint32_t offset = e->getFieldOffsetBytes(field);
+ uint32_t offset = e->mHal.state.fieldOffsetBytes[field];
const float *fd = reinterpret_cast<const float *>(&data[offset]);
int32_t slot = -1;
@@ -505,22 +498,13 @@
mAttribCount = 0;
for (uint32_t ct=0; ct < mRSProgram->mHal.state.inputElementsCount; ct++) {
const Element *elem = mRSProgram->mHal.state.inputElements[ct];
- for (uint32_t field=0; field < elem->getFieldCount(); field++) {
- if (elem->getFieldName(field)[0] != '#') {
- mAttribCount ++;
- }
- }
+ mAttribCount += elem->mHal.state.fieldsCount;
}
mUniformCount = 0;
for (uint32_t ct=0; ct < mRSProgram->mHal.state.constantsCount; ct++) {
const Element *elem = mRSProgram->mHal.state.constantTypes[ct]->getElement();
-
- for (uint32_t field=0; field < elem->getFieldCount(); field++) {
- if (elem->getFieldName(field)[0] != '#') {
- mUniformCount ++;
- }
- }
+ mUniformCount += elem->mHal.state.fieldsCount;
}
mUniformCount += mRSProgram->mHal.state.texturesCount;
@@ -540,17 +524,17 @@
void RsdShader::initAddUserElement(const Element *e, String8 *names, uint32_t *arrayLengths,
uint32_t *count, const char *prefix) {
- rsAssert(e->getFieldCount());
- for (uint32_t ct=0; ct < e->getFieldCount(); ct++) {
- const Element *ce = e->getField(ct);
- if (ce->getFieldCount()) {
+ rsAssert(e->mHal.state.fieldsCount);
+ for (uint32_t ct=0; ct < e->mHal.state.fieldsCount; ct++) {
+ const Element *ce = e->mHal.state.fields[ct];
+ if (ce->mHal.state.fieldsCount) {
initAddUserElement(ce, names, arrayLengths, count, prefix);
- } else if (e->getFieldName(ct)[0] != '#') {
+ } else {
String8 tmp(prefix);
- tmp.append(e->getFieldName(ct));
+ tmp.append(e->mHal.state.fieldNames[ct]);
names[*count].setTo(tmp.string());
if (arrayLengths) {
- arrayLengths[*count] = e->getFieldArraySize(ct);
+ arrayLengths[*count] = e->mHal.state.fieldArraySizes[ct];
}
(*count)++;
}
diff --git a/libs/rs/driver/rsdShaderCache.h b/libs/rs/driver/rsdShaderCache.h
index 17ee3e8..d64780b 100644
--- a/libs/rs/driver/rsdShaderCache.h
+++ b/libs/rs/driver/rsdShaderCache.h
@@ -108,6 +108,7 @@
}
if (numFragUnis) {
fragUniforms = new UniformData[numFragUnis];
+ fragUniformIsSTO = new bool[numFragUnis];
}
}
~ProgramEntry() {
@@ -123,6 +124,10 @@
delete[] fragUniforms;
fragUniforms = NULL;
}
+ if (fragUniformIsSTO) {
+ delete[] fragUniformIsSTO;
+ fragUniformIsSTO = NULL;
+ }
}
uint32_t vtx;
uint32_t frag;
@@ -131,6 +136,7 @@
AttrData *vtxAttrs;
UniformData *vtxUniforms;
UniformData *fragUniforms;
+ bool *fragUniformIsSTO;
};
android::Vector<ProgramEntry*> mEntries;
ProgramEntry *mCurrent;
diff --git a/libs/rs/rs.spec b/libs/rs/rs.spec
index 6887b22..44fd266 100644
--- a/libs/rs/rs.spec
+++ b/libs/rs/rs.spec
@@ -42,6 +42,7 @@
param RsType vtype
param RsAllocationMipmapControl mips
param uint32_t usages
+ param uint32_t ptr
ret RsAllocation
}
@@ -63,7 +64,10 @@
ret RsAllocation
}
-
+AllocationGetSurfaceTextureID {
+ param RsAllocation alloc
+ ret int32_t
+}
ContextFinish {
sync
@@ -388,3 +392,13 @@
param uint32_t *primType
ret RsMesh
}
+
+PathCreate {
+ param RsPathPrimitive pp
+ param bool isStatic
+ param RsAllocation vertex
+ param RsAllocation loops
+ param float quality
+ ret RsPath
+ }
+
diff --git a/libs/rs/rsAllocation.cpp b/libs/rs/rsAllocation.cpp
index fd85b07..02c6809 100644
--- a/libs/rs/rsAllocation.cpp
+++ b/libs/rs/rsAllocation.cpp
@@ -22,21 +22,22 @@
using namespace android::renderscript;
Allocation::Allocation(Context *rsc, const Type *type, uint32_t usages,
- RsAllocationMipmapControl mc)
+ RsAllocationMipmapControl mc, void * ptr)
: ObjectBase(rsc) {
memset(&mHal, 0, sizeof(mHal));
mHal.state.mipmapControl = RS_ALLOCATION_MIPMAP_NONE;
mHal.state.usageFlags = usages;
mHal.state.mipmapControl = mc;
+ mHal.state.usrPtr = ptr;
setType(type);
updateCache();
}
Allocation * Allocation::createAllocation(Context *rsc, const Type *type, uint32_t usages,
- RsAllocationMipmapControl mc) {
- Allocation *a = new Allocation(rsc, type, usages, mc);
+ RsAllocationMipmapControl mc, void * ptr) {
+ Allocation *a = new Allocation(rsc, type, usages, mc, ptr);
if (!rsc->mHal.funcs.allocation.init(rsc, a, type->getElement()->getHasReferences())) {
rsc->setError(RS_ERROR_FATAL_DRIVER, "Allocation::Allocation, alloc failure");
@@ -413,6 +414,12 @@
ALOGE("not implemented");
}
+int32_t Allocation::getSurfaceTextureID(const Context *rsc) {
+ int32_t id = rsc->mHal.funcs.allocation.initSurfaceTexture(rsc, this);
+ mHal.state.surfaceTextureID = id;
+ return id;
+}
+
/////////////////
//
@@ -571,8 +578,8 @@
RsAllocation rsi_AllocationCreateTyped(Context *rsc, RsType vtype,
RsAllocationMipmapControl mips,
- uint32_t usages) {
- Allocation * alloc = Allocation::createAllocation(rsc, static_cast<Type *>(vtype), usages, mips);
+ uint32_t usages, uint32_t ptr) {
+ Allocation * alloc = Allocation::createAllocation(rsc, static_cast<Type *>(vtype), usages, mips, (void *)ptr);
if (!alloc) {
return NULL;
}
@@ -585,7 +592,7 @@
const void *data, size_t data_length, uint32_t usages) {
Type *t = static_cast<Type *>(vtype);
- RsAllocation vTexAlloc = rsi_AllocationCreateTyped(rsc, vtype, mips, usages);
+ RsAllocation vTexAlloc = rsi_AllocationCreateTyped(rsc, vtype, mips, usages, 0);
Allocation *texAlloc = static_cast<Allocation *>(vTexAlloc);
if (texAlloc == NULL) {
ALOGE("Memory allocation failure");
@@ -609,7 +616,7 @@
// Cubemap allocation's faces should be Width by Width each.
// Source data should have 6 * Width by Width pixels
// Error checking is done in the java layer
- RsAllocation vTexAlloc = rsi_AllocationCreateTyped(rsc, vtype, mips, usages);
+ RsAllocation vTexAlloc = rsi_AllocationCreateTyped(rsc, vtype, mips, usages, 0);
Allocation *texAlloc = static_cast<Allocation *>(vTexAlloc);
if (texAlloc == NULL) {
ALOGE("Memory allocation failure");
@@ -658,6 +665,11 @@
(RsAllocationCubemapFace)srcFace);
}
+int32_t rsi_AllocationGetSurfaceTextureID(Context *rsc, RsAllocation valloc) {
+ Allocation *alloc = static_cast<Allocation *>(valloc);
+ return alloc->getSurfaceTextureID(rsc);
+}
+
}
}
diff --git a/libs/rs/rsAllocation.h b/libs/rs/rsAllocation.h
index 20201ca..6838759 100644
--- a/libs/rs/rsAllocation.h
+++ b/libs/rs/rsAllocation.h
@@ -55,6 +55,9 @@
bool hasMipmaps;
bool hasFaces;
bool hasReferences;
+ int32_t surfaceTextureID;
+
+ void * usrPtr;
};
State state;
@@ -66,7 +69,8 @@
Hal mHal;
static Allocation * createAllocation(Context *rsc, const Type *, uint32_t usages,
- RsAllocationMipmapControl mc = RS_ALLOCATION_MIPMAP_NONE);
+ RsAllocationMipmapControl mc = RS_ALLOCATION_MIPMAP_NONE,
+ void *ptr = 0);
virtual ~Allocation();
void updateCache();
@@ -123,6 +127,7 @@
return mHal.state.mipmapControl != RS_ALLOCATION_MIPMAP_NONE;
}
+ int32_t getSurfaceTextureID(const Context *rsc);
protected:
Vector<const Program *> mToDirtyList;
@@ -134,7 +139,7 @@
private:
void freeChildrenUnlocked();
- Allocation(Context *rsc, const Type *, uint32_t usages, RsAllocationMipmapControl mc);
+ Allocation(Context *rsc, const Type *, uint32_t usages, RsAllocationMipmapControl mc, void *ptr);
uint32_t getPackedSize() const;
static void writePackedData(const Type *type, uint8_t *dst, const uint8_t *src, bool dstPadded);
diff --git a/libs/rs/rsComponent.cpp b/libs/rs/rsComponent.cpp
index 21b98f6..9c2c200 100644
--- a/libs/rs/rsComponent.cpp
+++ b/libs/rs/rsComponent.cpp
@@ -62,6 +62,7 @@
rsAssert(mNormalized == true);
break;
default:
+ rsAssert(mKind != RS_KIND_INVALID);
break;
}
@@ -167,6 +168,9 @@
case RS_TYPE_BOOLEAN:
mTypeBits = 8;
break;
+ default:
+ rsAssert(mType != RS_TYPE_INVALID);
+ break;
}
mBitsUnpadded = mTypeBits * mVectorSize;
diff --git a/libs/rs/rsContext.cpp b/libs/rs/rsContext.cpp
index ad2ff0f..62b3c5c 100644
--- a/libs/rs/rsContext.cpp
+++ b/libs/rs/rsContext.cpp
@@ -347,6 +347,7 @@
#else
setpriority(PRIO_PROCESS, mNativeThreadId, p);
#endif
+ mHal.funcs.setPriority(this, mThreadPriority);
}
Context::Context() {
diff --git a/libs/rs/rsContext.h b/libs/rs/rsContext.h
index 61c29f9..2989c53 100644
--- a/libs/rs/rsContext.h
+++ b/libs/rs/rsContext.h
@@ -32,6 +32,7 @@
#include "rsAdapter.h"
#include "rsSampler.h"
#include "rsFont.h"
+#include "rsPath.h"
#include "rsProgramFragment.h"
#include "rsProgramStore.h"
#include "rsProgramRaster.h"
diff --git a/libs/rs/rsElement.cpp b/libs/rs/rsElement.cpp
index dff9585..fb2892c 100644
--- a/libs/rs/rsElement.cpp
+++ b/libs/rs/rsElement.cpp
@@ -27,6 +27,7 @@
mFields = NULL;
mFieldCount = 0;
mHasReference = false;
+ memset(&mHal, 0, sizeof(mHal));
}
Element::~Element() {
@@ -47,6 +48,12 @@
mFields = NULL;
mFieldCount = 0;
mHasReference = false;
+
+ delete [] mHal.state.fields;
+ delete [] mHal.state.fieldArraySizes;
+ delete [] mHal.state.fieldNames;
+ delete [] mHal.state.fieldNameLengths;
+ delete [] mHal.state.fieldOffsetBytes;
}
size_t Element::getSizeBits() const {
@@ -157,16 +164,36 @@
}
void Element::compute() {
+ mHal.state.dataType = mComponent.getType();
+ mHal.state.dataKind = mComponent.getKind();
+ mHal.state.vectorSize = mComponent.getVectorSize();
+
if (mFieldCount == 0) {
mBits = mComponent.getBits();
mBitsUnpadded = mComponent.getBitsUnpadded();
mHasReference = mComponent.isReference();
+
+ mHal.state.elementSizeBytes = getSizeBytes();
return;
}
+ uint32_t noPaddingFieldCount = 0;
+ for (uint32_t ct = 0; ct < mFieldCount; ct ++) {
+ if (mFields[ct].name.string()[0] != '#') {
+ noPaddingFieldCount ++;
+ }
+ }
+
+ mHal.state.fields = new const Element*[noPaddingFieldCount];
+ mHal.state.fieldArraySizes = new uint32_t[noPaddingFieldCount];
+ mHal.state.fieldNames = new const char*[noPaddingFieldCount];
+ mHal.state.fieldNameLengths = new uint32_t[noPaddingFieldCount];
+ mHal.state.fieldOffsetBytes = new uint32_t[noPaddingFieldCount];
+ mHal.state.fieldsCount = noPaddingFieldCount;
+
size_t bits = 0;
size_t bitsUnpadded = 0;
- for (size_t ct=0; ct < mFieldCount; ct++) {
+ for (size_t ct = 0, ctNoPadding = 0; ct < mFieldCount; ct++) {
mFields[ct].offsetBits = bits;
mFields[ct].offsetBitsUnpadded = bitsUnpadded;
bits += mFields[ct].e->getSizeBits() * mFields[ct].arraySize;
@@ -175,8 +202,21 @@
if (mFields[ct].e->mHasReference) {
mHasReference = true;
}
+
+ if (mFields[ct].name.string()[0] == '#') {
+ continue;
+ }
+
+ mHal.state.fields[ctNoPadding] = mFields[ct].e.get();
+ mHal.state.fieldArraySizes[ctNoPadding] = mFields[ct].arraySize;
+ mHal.state.fieldNames[ctNoPadding] = mFields[ct].name.string();
+ mHal.state.fieldNameLengths[ctNoPadding] = mFields[ct].name.length() + 1; // to include 0
+ mHal.state.fieldOffsetBytes[ctNoPadding] = mFields[ct].offsetBits >> 3;
+
+ ctNoPadding ++;
}
+ mHal.state.elementSizeBytes = getSizeBytes();
}
ObjectBaseRef<const Element> Element::createRef(Context *rsc, RsDataType dt, RsDataKind dk,
diff --git a/libs/rs/rsElement.h b/libs/rs/rsElement.h
index 04010fa..4b6b460 100644
--- a/libs/rs/rsElement.h
+++ b/libs/rs/rsElement.h
@@ -24,10 +24,38 @@
// ---------------------------------------------------------------------------
namespace android {
namespace renderscript {
-
+/*****************************************************************************
+ * CAUTION
+ *
+ * Any layout changes for this class may require a corresponding change to be
+ * made to frameworks/compile/libbcc/lib/ScriptCRT/rs_core.c, which contains
+ * a partial copy of the information below.
+ *
+ *****************************************************************************/
// An element is a group of Components that occupies one cell in a structure.
class Element : public ObjectBase {
public:
+ struct Hal {
+ mutable void *drv;
+
+ struct State {
+ RsDataType dataType;
+ RsDataKind dataKind;
+ uint32_t vectorSize;
+ uint32_t elementSizeBytes;
+
+ // Subelements
+ const Element **fields;
+ uint32_t *fieldArraySizes;
+ const char **fieldNames;
+ uint32_t *fieldNameLengths;
+ uint32_t *fieldOffsetBytes;
+ uint32_t fieldsCount;
+ };
+ State state;
+ };
+ Hal mHal;
+
class Builder {
public:
Builder();
diff --git a/libs/rs/rsMesh.h b/libs/rs/rsMesh.h
index 0fc73fb..166b5d3 100644
--- a/libs/rs/rsMesh.h
+++ b/libs/rs/rsMesh.h
@@ -23,20 +23,18 @@
// ---------------------------------------------------------------------------
namespace android {
namespace renderscript {
-
+/*****************************************************************************
+ * CAUTION
+ *
+ * Any layout changes for this class may require a corresponding change to be
+ * made to frameworks/compile/libbcc/lib/ScriptCRT/rs_core.c, which contains
+ * a partial copy of the information below.
+ *
+ *****************************************************************************/
// An element is a group of Components that occupies one cell in a structure.
class Mesh : public ObjectBase {
public:
- Mesh(Context *);
- Mesh(Context *, uint32_t vertexBuffersCount, uint32_t primitivesCount);
- ~Mesh();
-
- virtual void serialize(OStream *stream) const;
- virtual RsA3DClassID getClassId() const { return RS_A3D_CLASS_ID_MESH; }
- static Mesh *createFromStream(Context *rsc, IStream *stream);
- void init();
-
struct Hal {
mutable void *drv;
@@ -57,6 +55,15 @@
};
Hal mHal;
+ Mesh(Context *);
+ Mesh(Context *, uint32_t vertexBuffersCount, uint32_t primitivesCount);
+ ~Mesh();
+
+ virtual void serialize(OStream *stream) const;
+ virtual RsA3DClassID getClassId() const { return RS_A3D_CLASS_ID_MESH; }
+ static Mesh *createFromStream(Context *rsc, IStream *stream);
+ void init();
+
void setVertexBuffer(Allocation *vb, uint32_t index) {
mVertexBuffers[index].set(vb);
mHal.state.vertexBuffers[index] = vb;
diff --git a/libs/rs/rsPath.cpp b/libs/rs/rsPath.cpp
new file mode 100644
index 0000000..c4f4978
--- /dev/null
+++ b/libs/rs/rsPath.cpp
@@ -0,0 +1,78 @@
+/*
+ * Copyright (C) 2011 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.
+ */
+
+#include "rsContext.h"
+
+using namespace android;
+using namespace android::renderscript;
+
+
+Path::Path(Context *rsc) : ObjectBase(rsc) {
+}
+
+Path::Path(Context *rsc, RsPathPrimitive pp, bool isStatic,
+ Allocation *vtx, Allocation *loops, float quality)
+: ObjectBase(rsc) {
+
+ memset(&mHal, 0, sizeof(mHal));
+ mHal.state.quality = quality;
+ mHal.state.primitive = pp;
+
+ //LOGE("i1");
+ rsc->mHal.funcs.path.initStatic(rsc, this, vtx, loops);
+
+ //LOGE("i2");
+}
+
+Path::Path(Context *rsc, uint32_t vertexBuffersCount, uint32_t primitivesCount)
+: ObjectBase(rsc) {
+
+}
+
+Path::~Path() {
+
+}
+
+
+void Path::rasterize(const BezierSegment_t *s, uint32_t num, Allocation *alloc) {
+
+ for (uint32_t i=0; i < num; i++) {
+
+ }
+
+}
+
+void Path::render(Context *rsc) {
+}
+
+void Path::serialize(OStream *stream) const {
+
+}
+
+RsA3DClassID Path::getClassId() const {
+ return RS_A3D_CLASS_ID_UNKNOWN;
+}
+
+namespace android {
+namespace renderscript {
+
+RsPath rsi_PathCreate(Context *rsc, RsPathPrimitive pp, bool isStatic,
+ RsAllocation vtx, RsAllocation loops, float quality) {
+ return new Path(rsc, pp, isStatic, (Allocation *)vtx, (Allocation *)loops, quality);
+}
+
+}
+}
diff --git a/libs/rs/rsPath.h b/libs/rs/rsPath.h
new file mode 100644
index 0000000..dac795e
--- /dev/null
+++ b/libs/rs/rsPath.h
@@ -0,0 +1,69 @@
+/*
+ * Copyright (C) 2011 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.
+ */
+
+#ifndef ANDROID_RS_PATH_H
+#define ANDROID_RS_PATH_H
+
+
+#include "RenderScript.h"
+
+// ---------------------------------------------------------------------------
+namespace android {
+namespace renderscript {
+
+class Path : public ObjectBase {
+public:
+ struct {
+ mutable void * drv;
+
+ struct State {
+ RsPathPrimitive primitive;
+ float quality;
+ };
+ State state;
+ } mHal;
+
+ Path(Context *);
+ Path(Context *, uint32_t vertexBuffersCount, uint32_t primitivesCount);
+ Path(Context *, RsPathPrimitive pp, bool isStatic, Allocation *vtx, Allocation *loop, float q);
+
+ ~Path();
+
+ void render(Context *);
+ virtual void serialize(OStream *stream) const;
+ virtual RsA3DClassID getClassId() const;
+
+private:
+
+
+ typedef struct {
+ float x[4];
+ float y[4];
+ } BezierSegment_t;
+
+ bool subdivideCheck(const BezierSegment_t *s, float u1, float u2);
+
+ void rasterize(const BezierSegment_t *s, uint32_t num, Allocation *alloc);
+
+
+};
+
+}
+}
+#endif //ANDROID_RS_PATH_H
+
+
+
diff --git a/libs/rs/rsRuntime.h b/libs/rs/rsRuntime.h
index cb962a8..3bded62 100644
--- a/libs/rs/rsRuntime.h
+++ b/libs/rs/rsRuntime.h
@@ -30,6 +30,8 @@
//////////////////////////////////////////////////////////////////////////////
void rsrBindTexture(Context *, Script *, ProgramFragment *, uint32_t slot, Allocation *);
+void rsrBindConstant(Context *, Script *, ProgramFragment *, uint32_t slot, Allocation *);
+void rsrBindConstant(Context *, Script *, ProgramVertex*, uint32_t slot, Allocation *);
void rsrBindSampler(Context *, Script *, ProgramFragment *, uint32_t slot, Sampler *);
void rsrBindProgramStore(Context *, Script *, ProgramStore *);
void rsrBindProgramFragment(Context *, Script *, ProgramFragment *);
@@ -68,6 +70,7 @@
void rsrDrawSpriteScreenspace(Context *, Script *,
float x, float y, float z, float w, float h);
void rsrDrawRect(Context *, Script *, float x1, float y1, float x2, float y2, float z);
+void rsrDrawPath(Context *, Script *, Path *);
void rsrDrawMesh(Context *, Script *, Mesh *);
void rsrDrawMeshPrimitive(Context *, Script *, Mesh *, uint32_t primIndex);
void rsrDrawMeshPrimitiveRange(Context *, Script *, Mesh *,
diff --git a/libs/rs/rsScriptC_LibGL.cpp b/libs/rs/rsScriptC_LibGL.cpp
index 7964792..97469d3 100644
--- a/libs/rs/rsScriptC_LibGL.cpp
+++ b/libs/rs/rsScriptC_LibGL.cpp
@@ -50,6 +50,18 @@
pf->bindTexture(rsc, slot, a);
}
+void rsrBindConstant(Context *rsc, Script *sc, ProgramFragment *pf, uint32_t slot, Allocation *a) {
+ CHECK_OBJ_OR_NULL(a);
+ CHECK_OBJ(pf);
+ pf->bindAllocation(rsc, a, slot);
+}
+
+void rsrBindConstant(Context *rsc, Script *sc, ProgramVertex *pv, uint32_t slot, Allocation *a) {
+ CHECK_OBJ_OR_NULL(a);
+ CHECK_OBJ(pv);
+ pv->bindAllocation(rsc, a, slot);
+}
+
void rsrBindSampler(Context *rsc, Script *sc, ProgramFragment *pf, uint32_t slot, Sampler *s) {
CHECK_OBJ_OR_NULL(vs);
CHECK_OBJ(vpf);
@@ -200,6 +212,14 @@
rsrDrawQuad(rsc, sc, x1, y2, z, x2, y2, z, x2, y1, z, x1, y1, z);
}
+void rsrDrawPath(Context *rsc, Script *sc, Path *sm) {
+ CHECK_OBJ(sm);
+ if (!rsc->setupCheck()) {
+ return;
+ }
+ sm->render(rsc);
+}
+
void rsrDrawMesh(Context *rsc, Script *sc, Mesh *sm) {
CHECK_OBJ(sm);
if (!rsc->setupCheck()) {
diff --git a/libs/rs/rsThreadIO.h b/libs/rs/rsThreadIO.h
index ebce0ab..7e730df 100644
--- a/libs/rs/rsThreadIO.h
+++ b/libs/rs/rsThreadIO.h
@@ -37,6 +37,12 @@
// Plays back commands from the client.
// Returns true if any commands were processed.
+ //
+ // waitForCommand: true, block until a command arrives or
+ // the specified time expires.
+ //
+ // timeToWait: Max time to block in microseconds. A value of zero indicates
+ // an indefinite wait.
bool playCoreCommands(Context *con, bool waitForCommand, uint64_t timeToWait);
void setTimoutCallback(void (*)(void *), void *, uint64_t timeout);
diff --git a/libs/rs/rsType.cpp b/libs/rs/rsType.cpp
index 7966470..70ab7b7 100644
--- a/libs/rs/rsType.cpp
+++ b/libs/rs/rsType.cpp
@@ -46,12 +46,8 @@
delete [] mLODs;
mLODs = NULL;
}
- mDimX = 0;
- mDimY = 0;
- mDimZ = 0;
- mDimLOD = 0;
- mFaces = false;
mElement.clear();
+ memset(&mHal, 0, sizeof(mHal));
}
TypeState::TypeState() {
@@ -62,16 +58,16 @@
}
size_t Type::getOffsetForFace(uint32_t face) const {
- rsAssert(mFaces);
+ rsAssert(mHal.state.faces);
return 0;
}
void Type::compute() {
uint32_t oldLODCount = mLODCount;
- if (mDimLOD) {
- uint32_t l2x = rsFindHighBit(mDimX) + 1;
- uint32_t l2y = rsFindHighBit(mDimY) + 1;
- uint32_t l2z = rsFindHighBit(mDimZ) + 1;
+ if (mHal.state.dimLOD) {
+ uint32_t l2x = rsFindHighBit(mHal.state.dimX) + 1;
+ uint32_t l2y = rsFindHighBit(mHal.state.dimY) + 1;
+ uint32_t l2z = rsFindHighBit(mHal.state.dimZ) + 1;
mLODCount = rsMax(l2x, l2y);
mLODCount = rsMax(mLODCount, l2z);
@@ -85,9 +81,9 @@
mLODs = new LOD[mLODCount];
}
- uint32_t tx = mDimX;
- uint32_t ty = mDimY;
- uint32_t tz = mDimZ;
+ uint32_t tx = mHal.state.dimX;
+ uint32_t ty = mHal.state.dimY;
+ uint32_t tz = mHal.state.dimZ;
size_t offset = 0;
for (uint32_t lod=0; lod < mLODCount; lod++) {
mLODs[lod].mX = tx;
@@ -103,10 +99,11 @@
// At this point the offset is the size of a mipmap chain;
mMipChainSizeBytes = offset;
- if (mFaces) {
+ if (mHal.state.faces) {
offset *= 6;
}
mTotalSizeBytes = offset;
+ mHal.state.element = mElement.get();
}
uint32_t Type::getLODOffset(uint32_t lod, uint32_t x) const {
@@ -127,7 +124,8 @@
return offset;
}
-uint32_t Type::getLODFaceOffset(uint32_t lod, RsAllocationCubemapFace face, uint32_t x, uint32_t y) const {
+uint32_t Type::getLODFaceOffset(uint32_t lod, RsAllocationCubemapFace face,
+ uint32_t x, uint32_t y) const {
uint32_t offset = mLODs[lod].mOffset;
offset += (x + y * mLODs[lod].mX) * mElement->getSizeBytes();
@@ -141,7 +139,12 @@
void Type::dumpLOGV(const char *prefix) const {
char buf[1024];
ObjectBase::dumpLOGV(prefix);
- ALOGV("%s Type: x=%zu y=%zu z=%zu mip=%i face=%i", prefix, mDimX, mDimY, mDimZ, mDimLOD, mFaces);
+ ALOGV("%s Type: x=%u y=%u z=%u mip=%i face=%i", prefix,
+ mHal.state.dimX,
+ mHal.state.dimY,
+ mHal.state.dimZ,
+ mHal.state.dimLOD,
+ mHal.state.faces);
snprintf(buf, sizeof(buf), "%s element: ", prefix);
mElement->dumpLOGV(buf);
}
@@ -155,12 +158,12 @@
mElement->serialize(stream);
- stream->addU32(mDimX);
- stream->addU32(mDimY);
- stream->addU32(mDimZ);
+ stream->addU32(mHal.state.dimX);
+ stream->addU32(mHal.state.dimY);
+ stream->addU32(mHal.state.dimZ);
- stream->addU8((uint8_t)(mDimLOD ? 1 : 0));
- stream->addU8((uint8_t)(mFaces ? 1 : 0));
+ stream->addU8((uint8_t)(mHal.state.dimLOD ? 1 : 0));
+ stream->addU8((uint8_t)(mHal.state.faces ? 1 : 0));
}
Type *Type::createFromStream(Context *rsc, IStream *stream) {
@@ -232,11 +235,11 @@
Type *nt = new Type(rsc);
returnRef.set(nt);
nt->mElement.set(e);
- nt->mDimX = dimX;
- nt->mDimY = dimY;
- nt->mDimZ = dimZ;
- nt->mDimLOD = dimLOD;
- nt->mFaces = dimFaces;
+ nt->mHal.state.dimX = dimX;
+ nt->mHal.state.dimY = dimY;
+ nt->mHal.state.dimZ = dimZ;
+ nt->mHal.state.dimLOD = dimLOD;
+ nt->mHal.state.faces = dimFaces;
nt->compute();
ObjectBase::asyncLock();
@@ -248,14 +251,14 @@
ObjectBaseRef<Type> Type::cloneAndResize1D(Context *rsc, uint32_t dimX) const {
return getTypeRef(rsc, mElement.get(), dimX,
- mDimY, mDimZ, mDimLOD, mFaces);
+ mHal.state.dimY, mHal.state.dimZ, mHal.state.dimLOD, mHal.state.faces);
}
ObjectBaseRef<Type> Type::cloneAndResize2D(Context *rsc,
uint32_t dimX,
uint32_t dimY) const {
return getTypeRef(rsc, mElement.get(), dimX, dimY,
- mDimZ, mDimLOD, mFaces);
+ mHal.state.dimZ, mHal.state.dimLOD, mHal.state.faces);
}
@@ -276,8 +279,8 @@
void rsaTypeGetNativeData(RsContext con, RsType type, uint32_t *typeData, uint32_t typeDataSize) {
rsAssert(typeDataSize == 6);
- // Pack the data in the follofing way mDimX; mDimY; mDimZ;
- // mDimLOD; mDimFaces; mElement; into typeData
+ // Pack the data in the follofing way mHal.state.dimX; mHal.state.dimY; mHal.state.dimZ;
+ // mHal.state.dimLOD; mHal.state.faces; mElement; into typeData
Type *t = static_cast<Type *>(type);
(*typeData++) = t->getDimX();
diff --git a/libs/rs/rsType.h b/libs/rs/rsType.h
index bc0d9ff..3878156 100644
--- a/libs/rs/rsType.h
+++ b/libs/rs/rsType.h
@@ -22,10 +22,35 @@
// ---------------------------------------------------------------------------
namespace android {
namespace renderscript {
-
+/*****************************************************************************
+ * CAUTION
+ *
+ * Any layout changes for this class may require a corresponding change to be
+ * made to frameworks/compile/libbcc/lib/ScriptCRT/rs_core.c, which contains
+ * a partial copy of the information below.
+ *
+ *****************************************************************************/
class Type : public ObjectBase {
public:
+ struct Hal {
+ mutable void *drv;
+
+ struct State {
+ const Element * element;
+
+ // Size of the structure in the various dimensions. A missing Dimension is
+ // specified as a 0 and not a 1.
+ uint32_t dimX;
+ uint32_t dimY;
+ uint32_t dimZ;
+ bool dimLOD;
+ bool faces;
+ };
+ State state;
+ };
+ Hal mHal;
+
Type * createTex2D(const Element *, size_t w, size_t h, bool mip);
size_t getOffsetForFace(uint32_t face) const;
@@ -34,22 +59,25 @@
size_t getElementSizeBytes() const {return mElement->getSizeBytes();}
const Element * getElement() const {return mElement.get();}
- uint32_t getDimX() const {return mDimX;}
- uint32_t getDimY() const {return mDimY;}
- uint32_t getDimZ() const {return mDimZ;}
- uint32_t getDimLOD() const {return mDimLOD;}
- bool getDimFaces() const {return mFaces;}
+ uint32_t getDimX() const {return mHal.state.dimX;}
+ uint32_t getDimY() const {return mHal.state.dimY;}
+ uint32_t getDimZ() const {return mHal.state.dimZ;}
+ uint32_t getDimLOD() const {return mHal.state.dimLOD;}
+ bool getDimFaces() const {return mHal.state.faces;}
uint32_t getLODDimX(uint32_t lod) const {rsAssert(lod < mLODCount); return mLODs[lod].mX;}
uint32_t getLODDimY(uint32_t lod) const {rsAssert(lod < mLODCount); return mLODs[lod].mY;}
uint32_t getLODDimZ(uint32_t lod) const {rsAssert(lod < mLODCount); return mLODs[lod].mZ;}
- uint32_t getLODOffset(uint32_t lod) const {rsAssert(lod < mLODCount); return mLODs[lod].mOffset;}
+ uint32_t getLODOffset(uint32_t lod) const {
+ rsAssert(lod < mLODCount); return mLODs[lod].mOffset;
+ }
uint32_t getLODOffset(uint32_t lod, uint32_t x) const;
uint32_t getLODOffset(uint32_t lod, uint32_t x, uint32_t y) const;
uint32_t getLODOffset(uint32_t lod, uint32_t x, uint32_t y, uint32_t z) const;
- uint32_t getLODFaceOffset(uint32_t lod, RsAllocationCubemapFace face, uint32_t x, uint32_t y) const;
+ uint32_t getLODFaceOffset(uint32_t lod, RsAllocationCubemapFace face,
+ uint32_t x, uint32_t y) const;
uint32_t getLODCount() const {return mLODCount;}
bool getIsNp2() const;
@@ -95,14 +123,6 @@
ObjectBaseRef<const Element> mElement;
- // Size of the structure in the various dimensions. A missing Dimension is
- // specified as a 0 and not a 1.
- size_t mDimX;
- size_t mDimY;
- size_t mDimZ;
- bool mDimLOD;
- bool mFaces;
-
// count of mipmap levels, 0 indicates no mipmapping
size_t mMipChainSizeBytes;
diff --git a/libs/rs/rs_hal.h b/libs/rs/rs_hal.h
index b8d7351..1e222e1 100644
--- a/libs/rs/rs_hal.h
+++ b/libs/rs/rs_hal.h
@@ -29,6 +29,7 @@
class Allocation;
class Script;
class ScriptC;
+class Path;
class Program;
class ProgramStore;
class ProgramRaster;
@@ -114,6 +115,7 @@
bool zeroNew);
void (*syncAll)(const Context *rsc, const Allocation *alloc, RsAllocationUsageType src);
void (*markDirty)(const Context *rsc, const Allocation *alloc);
+ int32_t (*initSurfaceTexture)(const Context *rsc, const Allocation *alloc);
void (*data1D)(const Context *rsc, const Allocation *alloc,
uint32_t xoff, uint32_t lod, uint32_t count,
@@ -189,6 +191,13 @@
} mesh;
struct {
+ bool (*initStatic)(const Context *rsc, const Path *m, const Allocation *vtx, const Allocation *loops);
+ bool (*initDynamic)(const Context *rsc, const Path *m);
+ void (*draw)(const Context *rsc, const Path *m);
+ void (*destroy)(const Context *rsc, const Path *m);
+ } path;
+
+ struct {
bool (*init)(const Context *rsc, const Sampler *m);
void (*destroy)(const Context *rsc, const Sampler *m);
} sampler;
diff --git a/libs/rs/scriptc/rs_allocation.rsh b/libs/rs/scriptc/rs_allocation.rsh
index 9ec03bf..a2f69d9 100644
--- a/libs/rs/scriptc/rs_allocation.rsh
+++ b/libs/rs/scriptc/rs_allocation.rsh
@@ -168,5 +168,135 @@
extern const void * __attribute__((overloadable))
rsGetElementAt(rs_allocation, uint32_t x, uint32_t y, uint32_t z);
+/**
+ * @param a allocation to get data from
+ * @return element describing allocation layout
+ */
+extern rs_element __attribute__((overloadable))
+ rsAllocationGetElement(rs_allocation a);
+
+/**
+ * @param m mesh to get data from
+ * @return number of allocations in the mesh that contain vertex
+ * data
+ */
+extern uint32_t __attribute__((overloadable))
+ rsMeshGetVertexAllocationCount(rs_mesh m);
+
+/**
+ * @param m mesh to get data from
+ * @return number of primitive groups in the mesh. This would
+ * include simple primitives as well as allocations
+ * containing index data
+ */
+extern uint32_t __attribute__((overloadable))
+ rsMeshGetPrimitiveCount(rs_mesh m);
+
+/**
+ * @param m mesh to get data from
+ * @param index index of the vertex allocation
+ * @return allocation containing vertex data
+ */
+extern rs_allocation __attribute__((overloadable))
+ rsMeshGetVertexAllocation(rs_mesh m, uint32_t index);
+
+/**
+ * @param m mesh to get data from
+ * @param index index of the index allocation
+ * @return allocation containing index data
+ */
+extern rs_allocation __attribute__((overloadable))
+ rsMeshGetIndexAllocation(rs_mesh m, uint32_t index);
+
+/**
+ * @param m mesh to get data from
+ * @param index index of the primitive
+ * @return primitive describing how the mesh is rendered
+ */
+extern rs_primitive __attribute__((overloadable))
+ rsMeshGetPrimitive(rs_mesh m, uint32_t index);
+
+/**
+ * @param e element to get data from
+ * @return number of sub-elements in this element
+ */
+extern uint32_t __attribute__((overloadable))
+ rsElementGetSubElementCount(rs_element e);
+
+/**
+ * @param e element to get data from
+ * @param index index of the sub-element to return
+ * @return sub-element in this element at given index
+ */
+extern rs_element __attribute__((overloadable))
+ rsElementGetSubElement(rs_element, uint32_t index);
+
+/**
+ * @param e element to get data from
+ * @param index index of the sub-element to return
+ * @return length of the sub-element name including the null
+ * terminator (size of buffer needed to write the name)
+ */
+extern uint32_t __attribute__((overloadable))
+ rsElementGetSubElementNameLength(rs_element e, uint32_t index);
+
+/**
+ * @param e element to get data from
+ * @param index index of the sub-element
+ * @param name array to store the name into
+ * @param nameLength length of the provided name array
+ * @return number of characters actually written, excluding the
+ * null terminator
+ */
+extern uint32_t __attribute__((overloadable))
+ rsElementGetSubElementName(rs_element e, uint32_t index, char *name, uint32_t nameLength);
+
+/**
+ * @param e element to get data from
+ * @param index index of the sub-element
+ * @return array size of sub-element in this element at given
+ * index
+ */
+extern uint32_t __attribute__((overloadable))
+ rsElementGetSubElementArraySize(rs_element e, uint32_t index);
+
+/**
+ * @param e element to get data from
+ * @param index index of the sub-element
+ * @return offset in bytes of sub-element in this element at
+ * given index
+ */
+extern uint32_t __attribute__((overloadable))
+ rsElementGetSubElementOffsetBytes(rs_element e, uint32_t index);
+
+/**
+ * @param e element to get data from
+ * @return total size of the element in bytes
+ */
+extern uint32_t __attribute__((overloadable))
+ rsElementGetSizeBytes(rs_element e);
+
+/**
+ * @param e element to get data from
+ * @return element's data type
+ */
+extern rs_data_type __attribute__((overloadable))
+ rsElementGetDataType(rs_element e);
+
+/**
+ * @param e element to get data from
+ * @return element's data size
+ */
+extern rs_data_kind __attribute__((overloadable))
+ rsElementGetDataKind(rs_element e);
+
+/**
+ * @param e element to get data from
+ * @return length of the element vector (for float2, float3,
+ * etc.)
+ */
+extern uint32_t __attribute__((overloadable))
+ rsElementGetVectorSize(rs_element e);
+
#endif
diff --git a/libs/rs/scriptc/rs_graphics.rsh b/libs/rs/scriptc/rs_graphics.rsh
index 2581953..7fdebdc 100644
--- a/libs/rs/scriptc/rs_graphics.rsh
+++ b/libs/rs/scriptc/rs_graphics.rsh
@@ -22,6 +22,66 @@
*/
#ifndef __RS_GRAPHICS_RSH__
#define __RS_GRAPHICS_RSH__
+
+// These are API 15 once it get official
+typedef enum {
+ RS_DEPTH_FUNC_ALWAYS,
+ RS_DEPTH_FUNC_LESS,
+ RS_DEPTH_FUNC_LEQUAL,
+ RS_DEPTH_FUNC_GREATER,
+ RS_DEPTH_FUNC_GEQUAL,
+ RS_DEPTH_FUNC_EQUAL,
+ RS_DEPTH_FUNC_NOTEQUAL,
+
+ RS_DEPTH_FUNC_INVALID = 100,
+} rs_depth_func;
+
+typedef enum {
+ RS_BLEND_SRC_ZERO, // 0
+ RS_BLEND_SRC_ONE, // 1
+ RS_BLEND_SRC_DST_COLOR, // 2
+ RS_BLEND_SRC_ONE_MINUS_DST_COLOR, // 3
+ RS_BLEND_SRC_SRC_ALPHA, // 4
+ RS_BLEND_SRC_ONE_MINUS_SRC_ALPHA, // 5
+ RS_BLEND_SRC_DST_ALPHA, // 6
+ RS_BLEND_SRC_ONE_MINUS_DST_ALPHA, // 7
+ RS_BLEND_SRC_SRC_ALPHA_SATURATE, // 8
+
+ RS_BLEND_SRC_INVALID = 100,
+} rs_blend_src_func;
+
+typedef enum {
+ RS_BLEND_DST_ZERO, // 0
+ RS_BLEND_DST_ONE, // 1
+ RS_BLEND_DST_SRC_COLOR, // 2
+ RS_BLEND_DST_ONE_MINUS_SRC_COLOR, // 3
+ RS_BLEND_DST_SRC_ALPHA, // 4
+ RS_BLEND_DST_ONE_MINUS_SRC_ALPHA, // 5
+ RS_BLEND_DST_DST_ALPHA, // 6
+ RS_BLEND_DST_ONE_MINUS_DST_ALPHA, // 7
+
+ RS_BLEND_DST_INVALID = 100,
+} rs_blend_dst_func;
+
+typedef enum {
+ RS_CULL_BACK,
+ RS_CULL_FRONT,
+ RS_CULL_NONE,
+
+ RS_CULL_INVALID = 100,
+} rs_cull_mode;
+
+typedef enum {
+ RS_SAMPLER_NEAREST,
+ RS_SAMPLER_LINEAR,
+ RS_SAMPLER_LINEAR_MIP_LINEAR,
+ RS_SAMPLER_WRAP,
+ RS_SAMPLER_CLAMP,
+ RS_SAMPLER_LINEAR_MIP_NEAREST,
+
+ RS_SAMPLER_INVALID = 100,
+} rs_sampler_value;
+
#if (defined(RS_VERSION) && (RS_VERSION >= 14))
/**
* Set the color target used for all subsequent rendering calls
@@ -82,6 +142,88 @@
extern void __attribute__((overloadable))
rsgBindProgramStore(rs_program_store ps);
+
+/**
+ * @hide
+ * Get program store depth function
+ *
+ * @param ps
+ */
+extern rs_depth_func __attribute__((overloadable))
+ rsgProgramStoreGetDepthFunc(rs_program_store ps);
+
+/**
+ * @hide
+ * Get program store depth mask
+ *
+ * @param ps
+ */
+extern bool __attribute__((overloadable))
+ rsgProgramStoreGetDepthMask(rs_program_store ps);
+/**
+ * @hide
+ * Get program store red component color mask
+ *
+ * @param ps
+ */
+extern bool __attribute__((overloadable))
+ rsgProgramStoreGetColorMaskR(rs_program_store ps);
+
+/**
+ * @hide
+ * Get program store green component color mask
+ *
+ * @param ps
+ */
+extern bool __attribute__((overloadable))
+ rsgProgramStoreGetColorMaskG(rs_program_store ps);
+
+/**
+ * @hide
+ * Get program store blur component color mask
+ *
+ * @param ps
+ */
+extern bool __attribute__((overloadable))
+ rsgProgramStoreGetColorMaskB(rs_program_store ps);
+
+/**
+ * @hide
+ * Get program store alpha component color mask
+ *
+ * @param ps
+ */
+extern bool __attribute__((overloadable))
+ rsgProgramStoreGetColorMaskA(rs_program_store ps);
+
+/**
+ * @hide
+ * Get program store blend source function
+ *
+ * @param ps
+ */
+extern rs_blend_src_func __attribute__((overloadable))
+ rsgProgramStoreGetBlendSrcFunc(rs_program_store ps);
+
+/**
+ * @hide
+ * Get program store blend destination function
+ *
+ * @param ps
+ */
+extern rs_blend_dst_func __attribute__((overloadable))
+ rsgProgramStoreGetBlendDstFunc(rs_program_store ps);
+
+/**
+ * @hide
+ * Get program store dither state
+ *
+ * @param ps
+ */
+extern bool __attribute__((overloadable))
+ rsgProgramStoreGetDitherEnabled(rs_program_store ps);
+
+
/**
* Bind a new ProgramVertex to the rendering context.
*
@@ -99,6 +241,24 @@
rsgBindProgramRaster(rs_program_raster pr);
/**
+ * @hide
+ * Get program raster point sprite state
+ *
+ * @param pr
+ */
+extern bool __attribute__((overloadable))
+ rsgProgramRasterGetPointSpriteEnabled(rs_program_raster pr);
+
+/**
+ * @hide
+ * Get program raster cull mode
+ *
+ * @param pr
+ */
+extern rs_cull_mode __attribute__((overloadable))
+ rsgProgramRasterGetCullMode(rs_program_raster pr);
+
+/**
* Bind a new Sampler object to a ProgramFragment. The sampler will
* operate on the texture bound at the matching slot.
*
@@ -108,6 +268,51 @@
rsgBindSampler(rs_program_fragment, uint slot, rs_sampler);
/**
+ * @hide
+ * Get sampler minification value
+ *
+ * @param pr
+ */
+extern rs_sampler_value __attribute__((overloadable))
+ rsgSamplerGetMinification(rs_sampler s);
+
+/**
+ * @hide
+ * Get sampler magnification value
+ *
+ * @param pr
+ */
+extern rs_sampler_value __attribute__((overloadable))
+ rsgSamplerGetMagnification(rs_sampler s);
+
+/**
+ * @hide
+ * Get sampler wrap S value
+ *
+ * @param pr
+ */
+extern rs_sampler_value __attribute__((overloadable))
+ rsgSamplerGetWrapS(rs_sampler s);
+
+/**
+ * @hide
+ * Get sampler wrap T value
+ *
+ * @param pr
+ */
+extern rs_sampler_value __attribute__((overloadable))
+ rsgSamplerGetWrapT(rs_sampler s);
+
+/**
+ * @hide
+ * Get sampler anisotropy
+ *
+ * @param pr
+ */
+extern float __attribute__((overloadable))
+ rsgSamplerGetAnisotropy(rs_sampler s);
+
+/**
* Bind a new Allocation object to a ProgramFragment. The
* Allocation must be a valid texture for the Program. The sampling
* of the texture will be controled by the Sampler bound at the
@@ -164,6 +369,28 @@
rsgProgramFragmentConstantColor(rs_program_fragment pf, float r, float g, float b, float a);
/**
+ * Bind a new Allocation object to a ProgramFragment. The
+ * Allocation must be a valid constant input for the Program.
+ *
+ * @param ps program object
+ * @param slot index of the constant buffer on the program
+ * @param c constants to bind
+ */
+extern void __attribute__((overloadable))
+ rsgBindConstant(rs_program_fragment ps, uint slot, rs_allocation c);
+
+/**
+ * Bind a new Allocation object to a ProgramVertex. The
+ * Allocation must be a valid constant input for the Program.
+ *
+ * @param pv program object
+ * @param slot index of the constant buffer on the program
+ * @param c constants to bind
+ */
+extern void __attribute__((overloadable))
+ rsgBindConstant(rs_program_vertex pv, uint slot, rs_allocation c);
+
+/**
* Get the width of the current rendering surface.
*
* @return uint
@@ -288,6 +515,9 @@
extern void __attribute__((overloadable))
rsgDrawSpriteScreenspace(float x, float y, float z, float w, float h);
+extern void __attribute__((overloadable))
+ rsgDrawPath(rs_path p);
+
/**
* Draw a mesh using the current context state. The whole mesh is
* rendered.
diff --git a/libs/rs/scriptc/rs_object.rsh b/libs/rs/scriptc/rs_object.rsh
index a431219..1fc3f83 100644
--- a/libs/rs/scriptc/rs_object.rsh
+++ b/libs/rs/scriptc/rs_object.rsh
@@ -56,6 +56,11 @@
* \overload
*/
extern void __attribute__((overloadable))
+ rsSetObject(rs_path *dst, rs_path src);
+/**
+ * \overload
+ */
+extern void __attribute__((overloadable))
rsSetObject(rs_mesh *dst, rs_mesh src);
/**
* \overload
@@ -114,6 +119,11 @@
* \overload
*/
extern void __attribute__((overloadable))
+ rsClearObject(rs_path *dst);
+/**
+ * \overload
+ */
+extern void __attribute__((overloadable))
rsClearObject(rs_mesh *dst);
/**
* \overload
@@ -175,6 +185,11 @@
* \overload
*/
extern bool __attribute__((overloadable))
+ rsIsObject(rs_path);
+/**
+ * \overload
+ */
+extern bool __attribute__((overloadable))
rsIsObject(rs_mesh);
/**
* \overload
diff --git a/libs/rs/scriptc/rs_types.rsh b/libs/rs/scriptc/rs_types.rsh
index 84bca9c..5345a48 100644
--- a/libs/rs/scriptc/rs_types.rsh
+++ b/libs/rs/scriptc/rs_types.rsh
@@ -138,6 +138,12 @@
*/
typedef struct { const int* const p; } __attribute__((packed, aligned(4))) rs_mesh;
/**
+ * \brief Opaque handle to a Renderscript Path object.
+ *
+ * See: android.renderscript.Path
+ */
+typedef struct { const int* const p; } __attribute__((packed, aligned(4))) rs_path;
+/**
* \brief Opaque handle to a Renderscript ProgramFragment object.
*
* See: android.renderscript.ProgramFragment
@@ -396,4 +402,96 @@
#endif //defined(RS_VERSION) && (RS_VERSION >= 14)
+/**
+ * Describes the way mesh vertex data is interpreted when rendering
+ *
+ **/
+typedef enum {
+ RS_PRIMITIVE_POINT,
+ RS_PRIMITIVE_LINE,
+ RS_PRIMITIVE_LINE_STRIP,
+ RS_PRIMITIVE_TRIANGLE,
+ RS_PRIMITIVE_TRIANGLE_STRIP,
+ RS_PRIMITIVE_TRIANGLE_FAN,
+
+ RS_PRIMITIVE_INVALID = 100,
+} rs_primitive;
+
+/**
+ * \brief Enumeration for possible element data types
+ *
+ * DataType represents the basic type information for a basic element. The
+ * naming convention follows. For numeric types it is FLOAT,
+ * SIGNED, or UNSIGNED followed by the _BITS where BITS is the
+ * size of the data. BOOLEAN is a true / false (1,0)
+ * represented in an 8 bit container. The UNSIGNED variants
+ * with multiple bit definitions are for packed graphical data
+ * formats and represent vectors with per vector member sizes
+ * which are treated as a single unit for packing and alignment
+ * purposes.
+ *
+ * MATRIX the three matrix types contain FLOAT_32 elements and are treated
+ * as 32 bits for alignment purposes.
+ *
+ * RS_* objects. 32 bit opaque handles.
+ */
+typedef enum {
+ RS_TYPE_NONE,
+ //RS_TYPE_FLOAT_16,
+ RS_TYPE_FLOAT_32 = 2,
+ RS_TYPE_FLOAT_64,
+ RS_TYPE_SIGNED_8,
+ RS_TYPE_SIGNED_16,
+ RS_TYPE_SIGNED_32,
+ RS_TYPE_SIGNED_64,
+ RS_TYPE_UNSIGNED_8,
+ RS_TYPE_UNSIGNED_16,
+ RS_TYPE_UNSIGNED_32,
+ RS_TYPE_UNSIGNED_64,
+
+ RS_TYPE_BOOLEAN,
+
+ RS_TYPE_UNSIGNED_5_6_5,
+ RS_TYPE_UNSIGNED_5_5_5_1,
+ RS_TYPE_UNSIGNED_4_4_4_4,
+
+ RS_TYPE_MATRIX_4X4,
+ RS_TYPE_MATRIX_3X3,
+ RS_TYPE_MATRIX_2X2,
+
+ RS_TYPE_ELEMENT = 1000,
+ RS_TYPE_TYPE,
+ RS_TYPE_ALLOCATION,
+ RS_TYPE_SAMPLER,
+ RS_TYPE_SCRIPT,
+ RS_TYPE_MESH,
+ RS_TYPE_PROGRAM_FRAGMENT,
+ RS_TYPE_PROGRAM_VERTEX,
+ RS_TYPE_PROGRAM_RASTER,
+ RS_TYPE_PROGRAM_STORE,
+
+ RS_TYPE_INVALID = 10000,
+} rs_data_type;
+
+/**
+ * \brief Enumeration for possible element data kind
+ *
+ * The special interpretation of the data if required. This is primarly
+ * useful for graphical data. USER indicates no special interpretation is
+ * expected. PIXEL is used in conjunction with the standard data types for
+ * representing texture formats.
+ */
+typedef enum {
+ RS_KIND_USER,
+
+ RS_KIND_PIXEL_L = 7,
+ RS_KIND_PIXEL_A,
+ RS_KIND_PIXEL_LA,
+ RS_KIND_PIXEL_RGB,
+ RS_KIND_PIXEL_RGBA,
+ RS_KIND_PIXEL_DEPTH,
+
+ RS_KIND_INVALID = 100,
+} rs_data_kind;
+
#endif
diff --git a/tests/RenderScriptTests/ComputePerf/src/com/example/android/rs/computeperf/mandelbrot.rs b/tests/RenderScriptTests/ComputePerf/src/com/example/android/rs/computeperf/mandelbrot.rs
index a7987b3..0ffb0e5 100644
--- a/tests/RenderScriptTests/ComputePerf/src/com/example/android/rs/computeperf/mandelbrot.rs
+++ b/tests/RenderScriptTests/ComputePerf/src/com/example/android/rs/computeperf/mandelbrot.rs
@@ -25,13 +25,14 @@
p.y = -1.f + ((float)y / gDimY) * 2.f;
float2 t = 0;
+ float2 t2 = t * t;
int iteration = 0;
- while((t.x*t.x + t.y*t.y < 4.f) && (iteration < gMaxIteration)) {
- float2 t2 = t * t;
+ while((t2.x + t2.y < 4.f) && (iteration < gMaxIteration)) {
float xtemp = t2.x - t2.y + p.x;
t.y = 2 * t.x * t.y + p.y;
t.x = xtemp;
iteration++;
+ t2 = t * t;
}
if(iteration >= gMaxIteration) {
diff --git a/tests/RenderScriptTests/ImageProcessing/src/com/android/rs/image/ImageProcessingActivity.java b/tests/RenderScriptTests/ImageProcessing/src/com/android/rs/image/ImageProcessingActivity.java
index 3615f60..7368260 100644
--- a/tests/RenderScriptTests/ImageProcessing/src/com/android/rs/image/ImageProcessingActivity.java
+++ b/tests/RenderScriptTests/ImageProcessing/src/com/android/rs/image/ImageProcessingActivity.java
@@ -283,6 +283,9 @@
mRadius = MAX_RADIUS;
mScript.set_radius(mRadius);
+ mScript.invoke_filter();
+ mRS.finish();
+
long t = java.lang.System.currentTimeMillis();
mScript.invoke_filter();
diff --git a/tests/RenderScriptTests/PerfTest/res/raw/singletexfm.glsl b/tests/RenderScriptTests/PerfTest/res/raw/singletexfm.glsl
new file mode 100644
index 0000000..656961c
--- /dev/null
+++ b/tests/RenderScriptTests/PerfTest/res/raw/singletexfm.glsl
@@ -0,0 +1,8 @@
+varying vec2 varTex0;
+
+void main() {
+ lowp vec3 col0 = texture2D(UNI_Tex0, varTex0).rgb;
+ gl_FragColor.xyz = col0 * UNI_modulate.rgb;
+ gl_FragColor.w = UNI_modulate.a;
+}
+
diff --git a/tests/RenderScriptTests/PerfTest/src/com/android/perftest/FillTest.java b/tests/RenderScriptTests/PerfTest/src/com/android/perftest/FillTest.java
index ba70c71..41f664a 100644
--- a/tests/RenderScriptTests/PerfTest/src/com/android/perftest/FillTest.java
+++ b/tests/RenderScriptTests/PerfTest/src/com/android/perftest/FillTest.java
@@ -35,18 +35,22 @@
// Custom shaders
private ProgramFragment mProgFragmentMultitex;
private ProgramFragment mProgFragmentSingletex;
+ private ProgramFragment mProgFragmentSingletexModulate;
private final BitmapFactory.Options mOptionsARGB = new BitmapFactory.Options();
int mBenchmarkDimX;
int mBenchmarkDimY;
private ScriptC_fill_test mFillScript;
ScriptField_TestScripts_s.Item[] mTests;
+ ScriptField_FillTestFragData_s mFragData;
private final String[] mNames = {
"Fill screen 10x singletexture",
"Fill screen 10x 3tex multitexture",
"Fill screen 10x blended singletexture",
- "Fill screen 10x blended 3tex multitexture"
+ "Fill screen 10x blended 3tex multitexture",
+ "Fill screen 3x modulate blended singletexture",
+ "Fill screen 1x modulate blended singletexture",
};
public FillTest() {
@@ -88,6 +92,8 @@
addTest(index++, 0 /*testId*/, 0 /*blend*/, 10 /*quadCount*/);
addTest(index++, 1 /*testId*/, 1 /*blend*/, 10 /*quadCount*/);
addTest(index++, 0 /*testId*/, 1 /*blend*/, 10 /*quadCount*/);
+ addTest(index++, 2 /*testId*/, 1 /*blend*/, 3 /*quadCount*/);
+ addTest(index++, 2 /*testId*/, 1 /*blend*/, 1 /*quadCount*/);
return true;
}
@@ -112,6 +118,14 @@
pfbCustom.setShader(mRes, R.raw.singletexf);
pfbCustom.addTexture(Program.TextureType.TEXTURE_2D);
mProgFragmentSingletex = pfbCustom.create();
+
+ pfbCustom = new ProgramFragment.Builder(mRS);
+ pfbCustom.setShader(mRes, R.raw.singletexfm);
+ pfbCustom.addTexture(Program.TextureType.TEXTURE_2D);
+ mFragData = new ScriptField_FillTestFragData_s(mRS, 1);
+ pfbCustom.addConstant(mFragData.getType());
+ mProgFragmentSingletexModulate = pfbCustom.create();
+ mProgFragmentSingletexModulate.bindConstants(mFragData.getAllocation(), 0);
}
private Allocation loadTextureARGB(int id) {
@@ -140,6 +154,7 @@
mFillScript.set_gProgVertex(progVertex);
mFillScript.set_gProgFragmentTexture(mProgFragmentSingletex);
+ mFillScript.set_gProgFragmentTextureModulate(mProgFragmentSingletexModulate);
mFillScript.set_gProgFragmentMultitex(mProgFragmentMultitex);
mFillScript.set_gProgStoreBlendNone(ProgramStore.BLEND_NONE_DEPTH_NONE(mRS));
mFillScript.set_gProgStoreBlendAlpha(ProgramStore.BLEND_ALPHA_DEPTH_NONE(mRS));
@@ -150,5 +165,7 @@
mFillScript.set_gTexOpaque(loadTextureRGB(R.drawable.data));
mFillScript.set_gTexTransparent(loadTextureARGB(R.drawable.leaf));
mFillScript.set_gTexChecker(loadTextureRGB(R.drawable.checker));
+
+ mFillScript.bind_gFragData(mFragData);
}
}
diff --git a/tests/RenderScriptTests/PerfTest/src/com/android/perftest/fill_test.rs b/tests/RenderScriptTests/PerfTest/src/com/android/perftest/fill_test.rs
index 23832d3..281f830 100644
--- a/tests/RenderScriptTests/PerfTest/src/com/android/perftest/fill_test.rs
+++ b/tests/RenderScriptTests/PerfTest/src/com/android/perftest/fill_test.rs
@@ -21,6 +21,7 @@
rs_program_vertex gProgVertex;
rs_program_fragment gProgFragmentTexture;
+rs_program_fragment gProgFragmentTextureModulate;
rs_program_fragment gProgFragmentMultitex;
rs_program_store gProgStoreBlendNone;
@@ -41,6 +42,11 @@
} FillTestData;
FillTestData *gData;
+typedef struct FillTestFragData_s {
+ float4 modulate;
+} FillTestFragData;
+FillTestFragData *gFragData;
+
static float gDt = 0.0f;
void init() {
@@ -58,7 +64,7 @@
rsgProgramVertexLoadProjectionMatrix(&proj);
}
-static void displaySingletexFill(bool blend, int quadCount) {
+static void displaySingletexFill(bool blend, int quadCount, bool modulate) {
bindProgramVertexOrtho();
rs_matrix4x4 matrix;
rsMatrixLoadIdentity(&matrix);
@@ -70,9 +76,21 @@
} else {
rsgBindProgramStore(gProgStoreBlendAlpha);
}
- rsgBindProgramFragment(gProgFragmentTexture);
- rsgBindSampler(gProgFragmentTexture, 0, gLinearClamp);
- rsgBindTexture(gProgFragmentTexture, 0, gTexOpaque);
+ if (modulate) {
+ rsgBindProgramFragment(gProgFragmentTextureModulate);
+ rsgBindSampler(gProgFragmentTextureModulate, 0, gLinearClamp);
+ rsgBindTexture(gProgFragmentTextureModulate, 0, gTexOpaque);
+
+ gFragData->modulate.r = 0.8f;
+ gFragData->modulate.g = 0.7f;
+ gFragData->modulate.b = 0.8f;
+ gFragData->modulate.a = 0.5f;
+ rsgAllocationSyncAll(rsGetAllocation(gFragData));
+ } else {
+ rsgBindProgramFragment(gProgFragmentTexture);
+ rsgBindSampler(gProgFragmentTexture, 0, gLinearClamp);
+ rsgBindTexture(gProgFragmentTexture, 0, gTexOpaque);
+ }
for (int i = 0; i < quadCount; i ++) {
float startX = 5 * i, startY = 5 * i;
@@ -128,7 +146,10 @@
displayMultitextureSample(gData->blend == 1 ? true : false, gData->quadCount);
break;
case 1:
- displaySingletexFill(gData->blend == 1 ? true : false, gData->quadCount);
+ displaySingletexFill(gData->blend == 1 ? true : false, gData->quadCount, false);
+ break;
+ case 2:
+ displaySingletexFill(gData->blend == 1 ? true : false, gData->quadCount, true);
break;
default:
rsDebug("Wrong test number", 0);
diff --git a/tests/RenderScriptTests/SceneGraph/Android.mk b/tests/RenderScriptTests/SceneGraph/Android.mk
new file mode 100644
index 0000000..ba4b3c5
--- /dev/null
+++ b/tests/RenderScriptTests/SceneGraph/Android.mk
@@ -0,0 +1,26 @@
+#
+# Copyright (C) 2011 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_MODULE_TAGS := optional
+
+LOCAL_SRC_FILES := $(call all-java-files-under, src) $(call all-renderscript-files-under, src)
+
+LOCAL_PACKAGE_NAME := SceneGraphTest
+
+include $(BUILD_PACKAGE)
diff --git a/tests/RenderScriptTests/SceneGraph/AndroidManifest.xml b/tests/RenderScriptTests/SceneGraph/AndroidManifest.xml
new file mode 100644
index 0000000..e8d1e8e
--- /dev/null
+++ b/tests/RenderScriptTests/SceneGraph/AndroidManifest.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.android.testapp">
+ <uses-permission
+ android:name="android.permission.INTERNET" />
+ <application android:label="SceneGraphTest">
+ <activity android:name="TestApp"
+ android:label="SceneGraphTest">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.LAUNCHER" />
+ </intent-filter>
+ </activity>
+ <activity android:name="FileSelector"
+ android:label="FileSelector"
+ android:hardwareAccelerated="true">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ </intent-filter>
+ </activity>
+ </application>
+</manifest>
diff --git a/tests/RenderScriptTests/SceneGraph/assets/blue.jpg b/tests/RenderScriptTests/SceneGraph/assets/blue.jpg
new file mode 100644
index 0000000..494e77a
--- /dev/null
+++ b/tests/RenderScriptTests/SceneGraph/assets/blue.jpg
Binary files differ
diff --git a/tests/RenderScriptTests/SceneGraph/assets/carbonfiber.jpg b/tests/RenderScriptTests/SceneGraph/assets/carbonfiber.jpg
new file mode 100644
index 0000000..2fcecb0
--- /dev/null
+++ b/tests/RenderScriptTests/SceneGraph/assets/carbonfiber.jpg
Binary files differ
diff --git a/tests/RenderScriptTests/SceneGraph/assets/green.jpg b/tests/RenderScriptTests/SceneGraph/assets/green.jpg
new file mode 100644
index 0000000..a86a754
--- /dev/null
+++ b/tests/RenderScriptTests/SceneGraph/assets/green.jpg
Binary files differ
diff --git a/tests/RenderScriptTests/SceneGraph/assets/grey.jpg b/tests/RenderScriptTests/SceneGraph/assets/grey.jpg
new file mode 100644
index 0000000..5870b1a
--- /dev/null
+++ b/tests/RenderScriptTests/SceneGraph/assets/grey.jpg
Binary files differ
diff --git a/tests/RenderScriptTests/SceneGraph/assets/orange.jpg b/tests/RenderScriptTests/SceneGraph/assets/orange.jpg
new file mode 100644
index 0000000..7dbe942
--- /dev/null
+++ b/tests/RenderScriptTests/SceneGraph/assets/orange.jpg
Binary files differ
diff --git a/tests/RenderScriptTests/SceneGraph/assets/orientation_test.a3d b/tests/RenderScriptTests/SceneGraph/assets/orientation_test.a3d
new file mode 100644
index 0000000..07318ae
--- /dev/null
+++ b/tests/RenderScriptTests/SceneGraph/assets/orientation_test.a3d
Binary files differ
diff --git a/tests/RenderScriptTests/SceneGraph/assets/orientation_test.dae b/tests/RenderScriptTests/SceneGraph/assets/orientation_test.dae
new file mode 100644
index 0000000..7eef443f
--- /dev/null
+++ b/tests/RenderScriptTests/SceneGraph/assets/orientation_test.dae
@@ -0,0 +1,1102 @@
+<?xml version="1.0" ?>
+<COLLADA xmlns="http://www.collada.org/2005/11/COLLADASchema" version="1.4.1">
+ <asset>
+ <contributor>
+ <author>alexst</author>
+ <authoring_tool>OpenCOLLADA2010</authoring_tool>
+ <comments>ColladaMaya export options: bakeTransforms=0;relativePaths=0;copyTextures=0;exportTriangles=1;exportCgfxFileReferences=0; isSampling=0;curveConstrainSampling=0;removeStaticCurves=1;exportPolygonMeshes=1;exportLights=1; exportCameras=1;exportJointsAndSkin=1;exportAnimations=0;exportInvisibleNodes=0;exportDefaultCameras=0; exportTexCoords=1;exportNormals=1;exportNormalsPerVertex=1;exportVertexColors=0;exportVertexColorsPerVertex=0; exportTexTangents=0;exportTangents=0;exportReferencedMaterials=1;exportMaterialsOnly=0; exportXRefs=1;dereferenceXRefs=1;exportCameraAsLookat=0;cameraXFov=0;cameraYFov=1;doublePrecision=0</comments>
+ <source_data>file:///Volumes/Android/art/orientation_test.mb</source_data>
+ </contributor>
+ <created>2011-09-30T15:31:38</created>
+ <modified>2011-09-30T15:31:38</modified>
+ <unit meter="0.01" name="centimeter" />
+ <up_axis>Y_UP</up_axis>
+ </asset>
+ <library_cameras>
+ <camera id="cameraShape1" name="cameraShape1">
+ <optics>
+ <technique_common>
+ <perspective>
+ <yfov>37.8493</yfov>
+ <aspect_ratio>1.5</aspect_ratio>
+ <znear>1</znear>
+ <zfar>400</zfar>
+ </perspective>
+ </technique_common>
+ </optics>
+ <extra>
+ <technique profile="OpenCOLLADAMaya">
+ <film_fit>0</film_fit>
+ <film_fit_offset>0</film_fit_offset>
+ <film_offsetX>0</film_offsetX>
+ <film_offsetY>0</film_offsetY>
+ <horizontal_aperture>3.599993</horizontal_aperture>
+ <lens_squeeze>1</lens_squeeze>
+ <originalMayaNodeId>cameraShape1</originalMayaNodeId>
+ <vertical_aperture>2.399995</vertical_aperture>
+ </technique>
+ </extra>
+ </camera>
+ <camera id="CameraDistShape" name="CameraDistShape">
+ <optics>
+ <technique_common>
+ <perspective>
+ <yfov>37.8493</yfov>
+ <aspect_ratio>1.5</aspect_ratio>
+ <znear>1</znear>
+ <zfar>1000</zfar>
+ </perspective>
+ </technique_common>
+ </optics>
+ <extra>
+ <technique profile="OpenCOLLADAMaya">
+ <film_fit>0</film_fit>
+ <film_fit_offset>0</film_fit_offset>
+ <film_offsetX>0</film_offsetX>
+ <film_offsetY>0</film_offsetY>
+ <horizontal_aperture>3.599993</horizontal_aperture>
+ <lens_squeeze>1</lens_squeeze>
+ <originalMayaNodeId>CameraDistShape</originalMayaNodeId>
+ <vertical_aperture>2.399995</vertical_aperture>
+ </technique>
+ </extra>
+ </camera>
+ </library_cameras>
+ <library_materials>
+ <material id="Paint1" name="Paint1">
+ <instance_effect url="#Paint1-fx" />
+ </material>
+ <material id="lambert2" name="lambert2">
+ <instance_effect url="#lambert2-fx" />
+ </material>
+ <material id="Plastic" name="Plastic">
+ <instance_effect url="#Plastic-fx" />
+ </material>
+ <material id="Metal" name="Metal">
+ <instance_effect url="#Metal-fx" />
+ </material>
+ <material id="PlasticCenter" name="PlasticCenter">
+ <instance_effect url="#PlasticCenter-fx" />
+ </material>
+ <material id="PlasticRed" name="PlasticRed">
+ <instance_effect url="#PlasticRed-fx" />
+ </material>
+ <material id="lambert10" name="lambert10">
+ <instance_effect url="#lambert10-fx" />
+ </material>
+ <material id="lambert11" name="lambert11">
+ <instance_effect url="#lambert11-fx" />
+ </material>
+ </library_materials>
+ <library_effects>
+ <effect id="Metal-fx">
+ <profile_COMMON>
+ <newparam sid="file23-surface">
+ <surface type="2D">
+ <init_from>file23</init_from>
+ </surface>
+ </newparam>
+ <newparam sid="file23-sampler">
+ <sampler2D>
+ <source>file23-surface</source>
+ </sampler2D>
+ </newparam>
+ <technique sid="common">
+ <lambert>
+ <emission>
+ <color>0 0 0 1</color>
+ </emission>
+ <ambient>
+ <color>0 0 0 1</color>
+ </ambient>
+ <diffuse>
+ <texture texture="file23-sampler" texcoord="TEX0">
+ <extra>
+ <technique profile="OpenCOLLADAMaya">
+ <blend_mode>NONE</blend_mode>
+ <coverageU>1</coverageU>
+ <coverageV>1</coverageV>
+ <fast>0</fast>
+ <mirrorU>0</mirrorU>
+ <mirrorV>0</mirrorV>
+ <noiseU>0</noiseU>
+ <noiseV>0</noiseV>
+ <offsetU>0</offsetU>
+ <offsetV>0</offsetV>
+ <repeatU>1</repeatU>
+ <repeatV>1</repeatV>
+ <rotateFrame>0</rotateFrame>
+ <rotateUV>0</rotateUV>
+ <stagger>0</stagger>
+ <translateFrameU>0</translateFrameU>
+ <translateFrameV>0</translateFrameV>
+ <wrapU>1</wrapU>
+ <wrapV>1</wrapV>
+ </technique>
+ </extra>
+ </texture>
+ </diffuse>
+ <transparent opaque="RGB_ZERO">
+ <color>0 0 0 1</color>
+ </transparent>
+ <transparency>
+ <float>1</float>
+ </transparency>
+ </lambert>
+ </technique>
+ </profile_COMMON>
+ </effect>
+ <effect id="Paint1-fx">
+ <profile_COMMON>
+ <newparam sid="file25-surface">
+ <surface type="2D">
+ <init_from>file25</init_from>
+ </surface>
+ </newparam>
+ <newparam sid="file25-sampler">
+ <sampler2D>
+ <source>file25-surface</source>
+ </sampler2D>
+ </newparam>
+ <technique sid="common">
+ <lambert>
+ <emission>
+ <color>0 0 0 1</color>
+ </emission>
+ <ambient>
+ <color>0 0 0 1</color>
+ </ambient>
+ <diffuse>
+ <texture texture="file25-sampler" texcoord="TEX0">
+ <extra>
+ <technique profile="OpenCOLLADAMaya">
+ <blend_mode>NONE</blend_mode>
+ <coverageU>1</coverageU>
+ <coverageV>1</coverageV>
+ <fast>0</fast>
+ <mirrorU>0</mirrorU>
+ <mirrorV>0</mirrorV>
+ <noiseU>0</noiseU>
+ <noiseV>0</noiseV>
+ <offsetU>0</offsetU>
+ <offsetV>0</offsetV>
+ <repeatU>1</repeatU>
+ <repeatV>1</repeatV>
+ <rotateFrame>0</rotateFrame>
+ <rotateUV>0</rotateUV>
+ <stagger>0</stagger>
+ <translateFrameU>0</translateFrameU>
+ <translateFrameV>0</translateFrameV>
+ <wrapU>1</wrapU>
+ <wrapV>1</wrapV>
+ </technique>
+ </extra>
+ </texture>
+ </diffuse>
+ <transparent opaque="RGB_ZERO">
+ <color>0 0 0 1</color>
+ </transparent>
+ <transparency>
+ <float>1</float>
+ </transparency>
+ </lambert>
+ </technique>
+ </profile_COMMON>
+ </effect>
+ <effect id="Plastic-fx">
+ <profile_COMMON>
+ <newparam sid="file24-surface">
+ <surface type="2D">
+ <init_from>file24</init_from>
+ </surface>
+ </newparam>
+ <newparam sid="file24-sampler">
+ <sampler2D>
+ <source>file24-surface</source>
+ </sampler2D>
+ </newparam>
+ <technique sid="common">
+ <lambert>
+ <emission>
+ <color>0 0 0 1</color>
+ </emission>
+ <ambient>
+ <color>0 0 0 1</color>
+ </ambient>
+ <diffuse>
+ <texture texture="file24-sampler" texcoord="TEX0">
+ <extra>
+ <technique profile="OpenCOLLADAMaya">
+ <blend_mode>NONE</blend_mode>
+ <coverageU>1</coverageU>
+ <coverageV>1</coverageV>
+ <fast>0</fast>
+ <mirrorU>0</mirrorU>
+ <mirrorV>0</mirrorV>
+ <noiseU>0</noiseU>
+ <noiseV>0</noiseV>
+ <offsetU>0</offsetU>
+ <offsetV>0</offsetV>
+ <repeatU>1</repeatU>
+ <repeatV>1</repeatV>
+ <rotateFrame>0</rotateFrame>
+ <rotateUV>0</rotateUV>
+ <stagger>0</stagger>
+ <translateFrameU>0</translateFrameU>
+ <translateFrameV>0</translateFrameV>
+ <wrapU>1</wrapU>
+ <wrapV>1</wrapV>
+ </technique>
+ </extra>
+ </texture>
+ </diffuse>
+ <transparent opaque="RGB_ZERO">
+ <color>0 0 0 1</color>
+ </transparent>
+ <transparency>
+ <float>1</float>
+ </transparency>
+ </lambert>
+ </technique>
+ </profile_COMMON>
+ </effect>
+ <effect id="PlasticCenter-fx">
+ <profile_COMMON>
+ <newparam sid="file24-surface">
+ <surface type="2D">
+ <init_from>file24</init_from>
+ </surface>
+ </newparam>
+ <newparam sid="file24-sampler">
+ <sampler2D>
+ <source>file24-surface</source>
+ </sampler2D>
+ </newparam>
+ <technique sid="common">
+ <lambert>
+ <emission>
+ <color>0 0 0 1</color>
+ </emission>
+ <ambient>
+ <color>0 0 0 1</color>
+ </ambient>
+ <diffuse>
+ <texture texture="file24-sampler" texcoord="TEX0">
+ <extra>
+ <technique profile="OpenCOLLADAMaya">
+ <blend_mode>NONE</blend_mode>
+ <coverageU>1</coverageU>
+ <coverageV>1</coverageV>
+ <fast>0</fast>
+ <mirrorU>0</mirrorU>
+ <mirrorV>0</mirrorV>
+ <noiseU>0</noiseU>
+ <noiseV>0</noiseV>
+ <offsetU>0</offsetU>
+ <offsetV>0</offsetV>
+ <repeatU>1</repeatU>
+ <repeatV>1</repeatV>
+ <rotateFrame>0</rotateFrame>
+ <rotateUV>0</rotateUV>
+ <stagger>0</stagger>
+ <translateFrameU>0</translateFrameU>
+ <translateFrameV>0</translateFrameV>
+ <wrapU>1</wrapU>
+ <wrapV>1</wrapV>
+ </technique>
+ </extra>
+ </texture>
+ </diffuse>
+ <transparent opaque="RGB_ZERO">
+ <color>0 0 0 1</color>
+ </transparent>
+ <transparency>
+ <float>1</float>
+ </transparency>
+ </lambert>
+ </technique>
+ </profile_COMMON>
+ </effect>
+ <effect id="PlasticRed-fx">
+ <profile_COMMON>
+ <newparam sid="file23-surface">
+ <surface type="2D">
+ <init_from>file23</init_from>
+ </surface>
+ </newparam>
+ <newparam sid="file23-sampler">
+ <sampler2D>
+ <source>file23-surface</source>
+ </sampler2D>
+ </newparam>
+ <technique sid="common">
+ <lambert>
+ <emission>
+ <color>0 0 0 1</color>
+ </emission>
+ <ambient>
+ <color>0 0 0 1</color>
+ </ambient>
+ <diffuse>
+ <texture texture="file23-sampler" texcoord="TEX0">
+ <extra>
+ <technique profile="OpenCOLLADAMaya">
+ <blend_mode>NONE</blend_mode>
+ <coverageU>1</coverageU>
+ <coverageV>1</coverageV>
+ <fast>0</fast>
+ <mirrorU>0</mirrorU>
+ <mirrorV>0</mirrorV>
+ <noiseU>0</noiseU>
+ <noiseV>0</noiseV>
+ <offsetU>0</offsetU>
+ <offsetV>0</offsetV>
+ <repeatU>1</repeatU>
+ <repeatV>1</repeatV>
+ <rotateFrame>0</rotateFrame>
+ <rotateUV>0</rotateUV>
+ <stagger>0</stagger>
+ <translateFrameU>0</translateFrameU>
+ <translateFrameV>0</translateFrameV>
+ <wrapU>1</wrapU>
+ <wrapV>1</wrapV>
+ </technique>
+ </extra>
+ </texture>
+ </diffuse>
+ <transparent opaque="RGB_ZERO">
+ <color>0 0 0 1</color>
+ </transparent>
+ <transparency>
+ <float>1</float>
+ </transparency>
+ </lambert>
+ </technique>
+ </profile_COMMON>
+ </effect>
+ <effect id="lambert10-fx">
+ <profile_COMMON>
+ <newparam sid="file28-surface">
+ <surface type="2D">
+ <init_from>file28</init_from>
+ </surface>
+ </newparam>
+ <newparam sid="file28-sampler">
+ <sampler2D>
+ <source>file28-surface</source>
+ </sampler2D>
+ </newparam>
+ <technique sid="common">
+ <lambert>
+ <emission>
+ <color>0 0 0 1</color>
+ </emission>
+ <ambient>
+ <color>0 0 0 1</color>
+ </ambient>
+ <diffuse>
+ <texture texture="file28-sampler" texcoord="TEX0">
+ <extra>
+ <technique profile="OpenCOLLADAMaya">
+ <blend_mode>NONE</blend_mode>
+ <coverageU>1</coverageU>
+ <coverageV>1</coverageV>
+ <fast>0</fast>
+ <mirrorU>0</mirrorU>
+ <mirrorV>0</mirrorV>
+ <noiseU>0</noiseU>
+ <noiseV>0</noiseV>
+ <offsetU>0</offsetU>
+ <offsetV>0</offsetV>
+ <repeatU>1</repeatU>
+ <repeatV>1</repeatV>
+ <rotateFrame>0</rotateFrame>
+ <rotateUV>0</rotateUV>
+ <stagger>0</stagger>
+ <translateFrameU>0</translateFrameU>
+ <translateFrameV>0</translateFrameV>
+ <wrapU>1</wrapU>
+ <wrapV>1</wrapV>
+ </technique>
+ </extra>
+ </texture>
+ </diffuse>
+ <transparent opaque="RGB_ZERO">
+ <color>0 0 0 1</color>
+ </transparent>
+ <transparency>
+ <float>1</float>
+ </transparency>
+ </lambert>
+ </technique>
+ </profile_COMMON>
+ </effect>
+ <effect id="lambert11-fx">
+ <profile_COMMON>
+ <newparam sid="file29-surface">
+ <surface type="2D">
+ <init_from>file29</init_from>
+ </surface>
+ </newparam>
+ <newparam sid="file29-sampler">
+ <sampler2D>
+ <source>file29-surface</source>
+ </sampler2D>
+ </newparam>
+ <technique sid="common">
+ <lambert>
+ <emission>
+ <color>0 0 0 1</color>
+ </emission>
+ <ambient>
+ <color>0 0 0 1</color>
+ </ambient>
+ <diffuse>
+ <texture texture="file29-sampler" texcoord="TEX0">
+ <extra>
+ <technique profile="OpenCOLLADAMaya">
+ <blend_mode>NONE</blend_mode>
+ <coverageU>1</coverageU>
+ <coverageV>1</coverageV>
+ <fast>0</fast>
+ <mirrorU>0</mirrorU>
+ <mirrorV>0</mirrorV>
+ <noiseU>0</noiseU>
+ <noiseV>0</noiseV>
+ <offsetU>0</offsetU>
+ <offsetV>0</offsetV>
+ <repeatU>1</repeatU>
+ <repeatV>1</repeatV>
+ <rotateFrame>0</rotateFrame>
+ <rotateUV>0</rotateUV>
+ <stagger>0</stagger>
+ <translateFrameU>0</translateFrameU>
+ <translateFrameV>0</translateFrameV>
+ <wrapU>1</wrapU>
+ <wrapV>1</wrapV>
+ </technique>
+ </extra>
+ </texture>
+ </diffuse>
+ <transparent opaque="RGB_ZERO">
+ <color>0 0 0 1</color>
+ </transparent>
+ <transparency>
+ <float>1</float>
+ </transparency>
+ </lambert>
+ </technique>
+ </profile_COMMON>
+ </effect>
+ <effect id="lambert2-fx">
+ <profile_COMMON>
+ <newparam sid="file22-surface">
+ <surface type="2D">
+ <init_from>file22</init_from>
+ </surface>
+ </newparam>
+ <newparam sid="file22-sampler">
+ <sampler2D>
+ <source>file22-surface</source>
+ </sampler2D>
+ </newparam>
+ <technique sid="common">
+ <lambert>
+ <emission>
+ <color>0 0 0 1</color>
+ </emission>
+ <ambient>
+ <color>0 0 0 1</color>
+ </ambient>
+ <diffuse>
+ <texture texture="file22-sampler" texcoord="TEX0">
+ <extra>
+ <technique profile="OpenCOLLADAMaya">
+ <blend_mode>NONE</blend_mode>
+ <coverageU>1</coverageU>
+ <coverageV>1</coverageV>
+ <fast>0</fast>
+ <mirrorU>0</mirrorU>
+ <mirrorV>0</mirrorV>
+ <noiseU>0</noiseU>
+ <noiseV>0</noiseV>
+ <offsetU>0</offsetU>
+ <offsetV>0</offsetV>
+ <repeatU>1</repeatU>
+ <repeatV>1</repeatV>
+ <rotateFrame>0</rotateFrame>
+ <rotateUV>0</rotateUV>
+ <stagger>0</stagger>
+ <translateFrameU>0</translateFrameU>
+ <translateFrameV>0</translateFrameV>
+ <wrapU>1</wrapU>
+ <wrapV>1</wrapV>
+ </technique>
+ </extra>
+ </texture>
+ </diffuse>
+ <transparent opaque="RGB_ZERO">
+ <color>0 0 0 1</color>
+ </transparent>
+ <transparency>
+ <float>1</float>
+ </transparency>
+ </lambert>
+ </technique>
+ </profile_COMMON>
+ </effect>
+ </library_effects>
+ <library_images>
+ <image id="file29" name="file29" height="0" width="0">
+ <init_from>file:///Volumes/Android/Sanity/SceneGraph/assets/blue.jpg</init_from>
+ <extra>
+ <technique profile="OpenCOLLADAMaya">
+ <dgnode_type>kFile</dgnode_type>
+ <image_sequence>0</image_sequence>
+ <originalMayaNodeId>file29</originalMayaNodeId>
+ </technique>
+ </extra>
+ </image>
+ <image id="file25" name="file25" height="0" width="0">
+ <init_from>file:///Volumes/Android/Sanity/SceneGraph/assets/carbonfiber.jpg</init_from>
+ <extra>
+ <technique profile="OpenCOLLADAMaya">
+ <dgnode_type>kFile</dgnode_type>
+ <image_sequence>0</image_sequence>
+ <originalMayaNodeId>file25</originalMayaNodeId>
+ </technique>
+ </extra>
+ </image>
+ <image id="file28" name="file28" height="0" width="0">
+ <init_from>file:///Volumes/Android/Sanity/SceneGraph/assets/green.jpg</init_from>
+ <extra>
+ <technique profile="OpenCOLLADAMaya">
+ <dgnode_type>kFile</dgnode_type>
+ <image_sequence>0</image_sequence>
+ <originalMayaNodeId>file28</originalMayaNodeId>
+ </technique>
+ </extra>
+ </image>
+ <image id="file22" name="file22" height="0" width="0">
+ <init_from>file:///Volumes/Android/Sanity/SceneGraph/assets/grey.jpg</init_from>
+ <extra>
+ <technique profile="OpenCOLLADAMaya">
+ <dgnode_type>kFile</dgnode_type>
+ <image_sequence>0</image_sequence>
+ <originalMayaNodeId>file22</originalMayaNodeId>
+ </technique>
+ </extra>
+ </image>
+ <image id="file24" name="file24" height="0" width="0">
+ <init_from>file:///Volumes/Android/Sanity/SceneGraph/assets/orange.jpg</init_from>
+ <extra>
+ <technique profile="OpenCOLLADAMaya">
+ <dgnode_type>kFile</dgnode_type>
+ <image_sequence>0</image_sequence>
+ <originalMayaNodeId>file24</originalMayaNodeId>
+ </technique>
+ </extra>
+ </image>
+ <image id="file23" name="file23" height="0" width="0">
+ <init_from>file:///Volumes/Android/Sanity/SceneGraph/assets/red.jpg</init_from>
+ <extra>
+ <technique profile="OpenCOLLADAMaya">
+ <dgnode_type>kFile</dgnode_type>
+ <image_sequence>0</image_sequence>
+ <originalMayaNodeId>file23</originalMayaNodeId>
+ </technique>
+ </extra>
+ </image>
+ </library_images>
+ <library_visual_scenes>
+ <visual_scene id="VisualSceneNode" name="orientation_test">
+ <node id="camera1" name="camera1">
+ <translate sid="translate">24.5791 14.1321 31.4654</translate>
+ <rotate sid="rotateZ">0 0 1 0</rotate>
+ <rotate sid="rotateY">0 1 0 42</rotate>
+ <rotate sid="rotateX">1 0 0 -16.2</rotate>
+ <scale sid="scale">1 1 1</scale>
+ <instance_camera url="#cameraShape1" />
+ <extra>
+ <technique profile="OpenCOLLADAMaya">
+ <originalMayaNodeId>camera1</originalMayaNodeId>
+ </technique>
+ </extra>
+ </node>
+ <node id="CameraAim" name="CameraAim">
+ <translate sid="translate">0.0209301 3.68542 2.06912</translate>
+ <rotate sid="rotateY">0 1 0 43.2561</rotate>
+ <rotate sid="rotateX">1 0 0 -20</rotate>
+ <scale sid="scale">1 1 1</scale>
+ <node id="CameraDist" name="CameraDist">
+ <translate sid="translate">0 0 45</translate>
+ <scale sid="scale">1 1 1</scale>
+ <instance_camera url="#CameraDistShape" />
+ <extra>
+ <technique profile="OpenCOLLADAMaya">
+ <originalMayaNodeId>CameraDist</originalMayaNodeId>
+ </technique>
+ </extra>
+ </node>
+ <extra>
+ <technique profile="OpenCOLLADAMaya">
+ <originalMayaNodeId>CameraAim</originalMayaNodeId>
+ </technique>
+ </extra>
+ </node>
+ <node id="pSphere4" name="pSphere4">
+ <translate sid="translate">-9.69237 0 7.70498</translate>
+ <scale sid="scale">1 1 1</scale>
+ <instance_geometry url="#pSphereShape4">
+ <bind_material>
+ <technique_common>
+ <instance_material symbol="lambert7SG" target="#Paint1">
+ <bind_vertex_input semantic="TEX0" input_semantic="TEXCOORD" input_set="0" />
+ </instance_material>
+ </technique_common>
+ </bind_material>
+ </instance_geometry>
+ <extra>
+ <technique profile="OpenCOLLADAMaya">
+ <originalMayaNodeId>pSphere4</originalMayaNodeId>
+ </technique>
+ </extra>
+ </node>
+ <node id="pSphere1" name="pSphere1">
+ <translate sid="translate">13.0966 0 5.76254</translate>
+ <scale sid="scale">1 1 1</scale>
+ <instance_geometry url="#pSphereShape1">
+ <bind_material>
+ <technique_common>
+ <instance_material symbol="lambert7SG" target="#Paint1">
+ <bind_vertex_input semantic="TEX0" input_semantic="TEXCOORD" input_set="0" />
+ </instance_material>
+ </technique_common>
+ </bind_material>
+ </instance_geometry>
+ <extra>
+ <technique profile="OpenCOLLADAMaya">
+ <originalMayaNodeId>pSphere1</originalMayaNodeId>
+ </technique>
+ </extra>
+ </node>
+ <node id="pSphere2" name="pSphere2">
+ <translate sid="translate">21.7661 0 -13.6375</translate>
+ <scale sid="scale">1 1 1</scale>
+ <instance_geometry url="#pSphereShape2">
+ <bind_material>
+ <technique_common>
+ <instance_material symbol="lambert7SG" target="#Paint1">
+ <bind_vertex_input semantic="TEX0" input_semantic="TEXCOORD" input_set="0" />
+ </instance_material>
+ </technique_common>
+ </bind_material>
+ </instance_geometry>
+ <extra>
+ <technique profile="OpenCOLLADAMaya">
+ <originalMayaNodeId>pSphere2</originalMayaNodeId>
+ </technique>
+ </extra>
+ </node>
+ <node id="pSphere3" name="pSphere3">
+ <translate sid="translate">-13.862 0 -13.6154</translate>
+ <scale sid="scale">1 1 1</scale>
+ <instance_geometry url="#pSphereShape3">
+ <bind_material>
+ <technique_common>
+ <instance_material symbol="lambert7SG" target="#Paint1">
+ <bind_vertex_input semantic="TEX0" input_semantic="TEXCOORD" input_set="0" />
+ </instance_material>
+ </technique_common>
+ </bind_material>
+ </instance_geometry>
+ <extra>
+ <technique profile="OpenCOLLADAMaya">
+ <originalMayaNodeId>pSphere3</originalMayaNodeId>
+ </technique>
+ </extra>
+ </node>
+ <node id="pSphere5" name="pSphere5">
+ <translate sid="translate">31.0862 0 18.5992</translate>
+ <scale sid="scale">1 1 1</scale>
+ <instance_geometry url="#pSphereShape5">
+ <bind_material>
+ <technique_common>
+ <instance_material symbol="lambert7SG" target="#Paint1">
+ <bind_vertex_input semantic="TEX0" input_semantic="TEXCOORD" input_set="0" />
+ </instance_material>
+ </technique_common>
+ </bind_material>
+ </instance_geometry>
+ <extra>
+ <technique profile="OpenCOLLADAMaya">
+ <originalMayaNodeId>pSphere5</originalMayaNodeId>
+ </technique>
+ </extra>
+ </node>
+ <node id="pCube1" name="pCube1">
+ <translate sid="translate">0 0 0</translate>
+ <scale sid="scale">1 1 1</scale>
+ <instance_geometry url="#pCubeShape1">
+ <bind_material>
+ <technique_common>
+ <instance_material symbol="lambert4SG" target="#lambert2">
+ <bind_vertex_input semantic="TEX0" input_semantic="TEXCOORD" input_set="0" />
+ </instance_material>
+ </technique_common>
+ </bind_material>
+ </instance_geometry>
+ <extra>
+ <technique profile="OpenCOLLADAMaya">
+ <originalMayaNodeId>pCube1</originalMayaNodeId>
+ </technique>
+ </extra>
+ </node>
+ <node id="group1" name="group1">
+ <translate sid="translate">0 0 0</translate>
+ <rotate sid="rotateZ">0 0 1 -162.693</rotate>
+ <rotate sid="rotateY">0 1 0 21.3345</rotate>
+ <rotate sid="rotateX">1 0 0 -100.567</rotate>
+ <scale sid="scale">1 1 1</scale>
+ <node id="pSphere6" name="pSphere6">
+ <translate sid="translate">-13.862 0 -13.6154</translate>
+ <scale sid="scale">1 1 1</scale>
+ <instance_geometry url="#pSphereShape6">
+ <bind_material>
+ <technique_common>
+ <instance_material symbol="lambert6SG" target="#Plastic">
+ <bind_vertex_input semantic="TEX0" input_semantic="TEXCOORD" input_set="0" />
+ </instance_material>
+ </technique_common>
+ </bind_material>
+ </instance_geometry>
+ <extra>
+ <technique profile="OpenCOLLADAMaya">
+ <originalMayaNodeId>pSphere6</originalMayaNodeId>
+ </technique>
+ </extra>
+ </node>
+ <node id="pSphere7" name="pSphere7">
+ <translate sid="translate">-9.69237 0 7.70498</translate>
+ <scale sid="scale">1 1 1</scale>
+ <instance_geometry url="#pSphereShape7">
+ <bind_material>
+ <technique_common>
+ <instance_material symbol="lambert6SG" target="#Plastic">
+ <bind_vertex_input semantic="TEX0" input_semantic="TEXCOORD" input_set="0" />
+ </instance_material>
+ </technique_common>
+ </bind_material>
+ </instance_geometry>
+ <extra>
+ <technique profile="OpenCOLLADAMaya">
+ <originalMayaNodeId>pSphere7</originalMayaNodeId>
+ </technique>
+ </extra>
+ </node>
+ <node id="pSphere8" name="pSphere8">
+ <translate sid="translate">21.7661 0 -13.6375</translate>
+ <scale sid="scale">1 1 1</scale>
+ <instance_geometry url="#pSphereShape8">
+ <bind_material>
+ <technique_common>
+ <instance_material symbol="lambert6SG" target="#Plastic">
+ <bind_vertex_input semantic="TEX0" input_semantic="TEXCOORD" input_set="0" />
+ </instance_material>
+ </technique_common>
+ </bind_material>
+ </instance_geometry>
+ <extra>
+ <technique profile="OpenCOLLADAMaya">
+ <originalMayaNodeId>pSphere8</originalMayaNodeId>
+ </technique>
+ </extra>
+ </node>
+ <node id="pSphere9" name="pSphere9">
+ <translate sid="translate">13.0966 0 5.76254</translate>
+ <scale sid="scale">1 1 1</scale>
+ <instance_geometry url="#pSphereShape9">
+ <bind_material>
+ <technique_common>
+ <instance_material symbol="lambert6SG" target="#Plastic">
+ <bind_vertex_input semantic="TEX0" input_semantic="TEXCOORD" input_set="0" />
+ </instance_material>
+ </technique_common>
+ </bind_material>
+ </instance_geometry>
+ <extra>
+ <technique profile="OpenCOLLADAMaya">
+ <originalMayaNodeId>pSphere9</originalMayaNodeId>
+ </technique>
+ </extra>
+ </node>
+ <extra>
+ <technique profile="OpenCOLLADAMaya">
+ <originalMayaNodeId>group1</originalMayaNodeId>
+ </technique>
+ </extra>
+ </node>
+ <node id="group2" name="group2">
+ <translate sid="translate">0 0 0</translate>
+ <rotate sid="rotateZ">0 0 1 45.4017</rotate>
+ <rotate sid="rotateY">0 1 0 79.393</rotate>
+ <rotate sid="rotateX">1 0 0 5.10889</rotate>
+ <scale sid="scale">1 1 1</scale>
+ <node id="pSphere10" name="pSphere10">
+ <translate sid="translate">31.0862 0 18.5992</translate>
+ <scale sid="scale">1 1 1</scale>
+ <instance_geometry url="#pSphereShape10">
+ <bind_material>
+ <technique_common>
+ <instance_material symbol="lambert5SG" target="#Metal">
+ <bind_vertex_input semantic="TEX0" input_semantic="TEXCOORD" input_set="0" />
+ </instance_material>
+ </technique_common>
+ </bind_material>
+ </instance_geometry>
+ <extra>
+ <technique profile="OpenCOLLADAMaya">
+ <originalMayaNodeId>pSphere10</originalMayaNodeId>
+ </technique>
+ </extra>
+ </node>
+ <node id="pSphere11" name="pSphere11">
+ <translate sid="translate">13.0966 0 5.76254</translate>
+ <scale sid="scale">1 1 1</scale>
+ <instance_geometry url="#pSphereShape11">
+ <bind_material>
+ <technique_common>
+ <instance_material symbol="lambert5SG" target="#Metal">
+ <bind_vertex_input semantic="TEX0" input_semantic="TEXCOORD" input_set="0" />
+ </instance_material>
+ </technique_common>
+ </bind_material>
+ </instance_geometry>
+ <extra>
+ <technique profile="OpenCOLLADAMaya">
+ <originalMayaNodeId>pSphere11</originalMayaNodeId>
+ </technique>
+ </extra>
+ </node>
+ <node id="pSphere12" name="pSphere12">
+ <translate sid="translate">7.4784 16.3496 7.36882</translate>
+ <rotate sid="rotateZ">0 0 1 17.3073</rotate>
+ <rotate sid="rotateY">0 1 0 158.666</rotate>
+ <rotate sid="rotateX">1 0 0 79.4335</rotate>
+ <scale sid="scale">1 1 1</scale>
+ <instance_geometry url="#pSphereShape12">
+ <bind_material>
+ <technique_common>
+ <instance_material symbol="lambert5SG" target="#Metal">
+ <bind_vertex_input semantic="TEX0" input_semantic="TEXCOORD" input_set="0" />
+ </instance_material>
+ </technique_common>
+ </bind_material>
+ </instance_geometry>
+ <extra>
+ <technique profile="OpenCOLLADAMaya">
+ <originalMayaNodeId>pSphere12</originalMayaNodeId>
+ </technique>
+ </extra>
+ </node>
+ <node id="pSphere13" name="pSphere13">
+ <translate sid="translate">-9.69237 0 7.70498</translate>
+ <scale sid="scale">1 1 1</scale>
+ <instance_geometry url="#pSphereShape13">
+ <bind_material>
+ <technique_common>
+ <instance_material symbol="lambert5SG" target="#Metal">
+ <bind_vertex_input semantic="TEX0" input_semantic="TEXCOORD" input_set="0" />
+ </instance_material>
+ </technique_common>
+ </bind_material>
+ </instance_geometry>
+ <extra>
+ <technique profile="OpenCOLLADAMaya">
+ <originalMayaNodeId>pSphere13</originalMayaNodeId>
+ </technique>
+ </extra>
+ </node>
+ <node id="pSphere14" name="pSphere14">
+ <translate sid="translate">11.3635 -4.3926 2.21012</translate>
+ <rotate sid="rotateZ">0 0 1 17.3073</rotate>
+ <rotate sid="rotateY">0 1 0 158.666</rotate>
+ <rotate sid="rotateX">1 0 0 79.4335</rotate>
+ <scale sid="scale">1 1 1</scale>
+ <instance_geometry url="#pSphereShape14">
+ <bind_material>
+ <technique_common>
+ <instance_material symbol="lambert5SG" target="#Metal">
+ <bind_vertex_input semantic="TEX0" input_semantic="TEXCOORD" input_set="0" />
+ </instance_material>
+ </technique_common>
+ </bind_material>
+ </instance_geometry>
+ <extra>
+ <technique profile="OpenCOLLADAMaya">
+ <originalMayaNodeId>pSphere14</originalMayaNodeId>
+ </technique>
+ </extra>
+ </node>
+ <node id="pSphere15" name="pSphere15">
+ <translate sid="translate">21.7661 0 -13.6375</translate>
+ <scale sid="scale">1 1 1</scale>
+ <instance_geometry url="#pSphereShape15">
+ <bind_material>
+ <technique_common>
+ <instance_material symbol="lambert5SG" target="#Metal">
+ <bind_vertex_input semantic="TEX0" input_semantic="TEXCOORD" input_set="0" />
+ </instance_material>
+ </technique_common>
+ </bind_material>
+ </instance_geometry>
+ <extra>
+ <technique profile="OpenCOLLADAMaya">
+ <originalMayaNodeId>pSphere15</originalMayaNodeId>
+ </technique>
+ </extra>
+ </node>
+ <node id="pSphere16" name="pSphere16">
+ <translate sid="translate">-9.5945 -8.92317 -5.74901</translate>
+ <rotate sid="rotateZ">0 0 1 17.3073</rotate>
+ <rotate sid="rotateY">0 1 0 158.666</rotate>
+ <rotate sid="rotateX">1 0 0 79.4335</rotate>
+ <scale sid="scale">1 1 1</scale>
+ <instance_geometry url="#pSphereShape16">
+ <bind_material>
+ <technique_common>
+ <instance_material symbol="lambert5SG" target="#Metal">
+ <bind_vertex_input semantic="TEX0" input_semantic="TEXCOORD" input_set="0" />
+ </instance_material>
+ </technique_common>
+ </bind_material>
+ </instance_geometry>
+ <extra>
+ <technique profile="OpenCOLLADAMaya">
+ <originalMayaNodeId>pSphere16</originalMayaNodeId>
+ </technique>
+ </extra>
+ </node>
+ <node id="pSphere17" name="pSphere17">
+ <translate sid="translate">-13.862 0 -13.6154</translate>
+ <scale sid="scale">1 1 1</scale>
+ <instance_geometry url="#pSphereShape17">
+ <bind_material>
+ <technique_common>
+ <instance_material symbol="lambert5SG" target="#Metal">
+ <bind_vertex_input semantic="TEX0" input_semantic="TEXCOORD" input_set="0" />
+ </instance_material>
+ </technique_common>
+ </bind_material>
+ </instance_geometry>
+ <extra>
+ <technique profile="OpenCOLLADAMaya">
+ <originalMayaNodeId>pSphere17</originalMayaNodeId>
+ </technique>
+ </extra>
+ </node>
+ <node id="pSphere18" name="pSphere18">
+ <translate sid="translate">-24.2135 6.497 -5.58935</translate>
+ <rotate sid="rotateZ">0 0 1 17.3073</rotate>
+ <rotate sid="rotateY">0 1 0 158.666</rotate>
+ <rotate sid="rotateX">1 0 0 79.4335</rotate>
+ <scale sid="scale">1 1 1</scale>
+ <instance_geometry url="#pSphereShape18">
+ <bind_material>
+ <technique_common>
+ <instance_material symbol="lambert5SG" target="#Metal">
+ <bind_vertex_input semantic="TEX0" input_semantic="TEXCOORD" input_set="0" />
+ </instance_material>
+ </technique_common>
+ </bind_material>
+ </instance_geometry>
+ <extra>
+ <technique profile="OpenCOLLADAMaya">
+ <originalMayaNodeId>pSphere18</originalMayaNodeId>
+ </technique>
+ </extra>
+ </node>
+ <extra>
+ <technique profile="OpenCOLLADAMaya">
+ <originalMayaNodeId>group2</originalMayaNodeId>
+ </technique>
+ </extra>
+ </node>
+ <node id="pCube2" name="pCube2">
+ <translate sid="translate">0 0 0</translate>
+ <scale sid="scale">1 1 1</scale>
+ <instance_geometry url="#pCubeShape2">
+ <bind_material>
+ <technique_common>
+ <instance_material symbol="lambert8SG" target="#PlasticCenter">
+ <bind_vertex_input semantic="TEX0" input_semantic="TEXCOORD" input_set="0" />
+ </instance_material>
+ </technique_common>
+ </bind_material>
+ </instance_geometry>
+ <extra>
+ <technique profile="OpenCOLLADAMaya">
+ <originalMayaNodeId>pCube2</originalMayaNodeId>
+ </technique>
+ </extra>
+ </node>
+ <node id="pCube3" name="pCube3">
+ <translate sid="translate">15 0 0</translate>
+ <scale sid="scale">1 1 1</scale>
+ <instance_geometry url="#pCubeShape3">
+ <bind_material>
+ <technique_common>
+ <instance_material symbol="lambert9SG" target="#PlasticRed">
+ <bind_vertex_input semantic="TEX0" input_semantic="TEXCOORD" input_set="0" />
+ </instance_material>
+ </technique_common>
+ </bind_material>
+ </instance_geometry>
+ <extra>
+ <technique profile="OpenCOLLADAMaya">
+ <originalMayaNodeId>pCube3</originalMayaNodeId>
+ </technique>
+ </extra>
+ </node>
+ <node id="pCube4" name="pCube4">
+ <translate sid="translate">0 15 0</translate>
+ <scale sid="scale">1 1 1</scale>
+ <instance_geometry url="#pCubeShape4">
+ <bind_material>
+ <technique_common>
+ <instance_material symbol="lambert10SG" target="#lambert10">
+ <bind_vertex_input semantic="TEX0" input_semantic="TEXCOORD" input_set="0" />
+ </instance_material>
+ </technique_common>
+ </bind_material>
+ </instance_geometry>
+ <extra>
+ <technique profile="OpenCOLLADAMaya">
+ <originalMayaNodeId>pCube4</originalMayaNodeId>
+ </technique>
+ </extra>
+ </node>
+ <node id="pCube5" name="pCube5">
+ <translate sid="translate">0 0 15</translate>
+ <scale sid="scale">1 1 1</scale>
+ <instance_geometry url="#pCubeShape5">
+ <bind_material>
+ <technique_common>
+ <instance_material symbol="lambert11SG" target="#lambert11">
+ <bind_vertex_input semantic="TEX0" input_semantic="TEXCOORD" input_set="0" />
+ </instance_material>
+ </technique_common>
+ </bind_material>
+ </instance_geometry>
+ <extra>
+ <technique profile="OpenCOLLADAMaya">
+ <originalMayaNodeId>pCube5</originalMayaNodeId>
+ </technique>
+ </extra>
+ </node>
+ </visual_scene>
+ </library_visual_scenes>
+ <scene>
+ <instance_visual_scene url="#VisualSceneNode" />
+ </scene>
+</COLLADA>
diff --git a/tests/RenderScriptTests/SceneGraph/assets/paint.jpg b/tests/RenderScriptTests/SceneGraph/assets/paint.jpg
new file mode 100644
index 0000000..0791045
--- /dev/null
+++ b/tests/RenderScriptTests/SceneGraph/assets/paint.jpg
Binary files differ
diff --git a/tests/RenderScriptTests/SceneGraph/assets/red.jpg b/tests/RenderScriptTests/SceneGraph/assets/red.jpg
new file mode 100644
index 0000000..320a2a6
--- /dev/null
+++ b/tests/RenderScriptTests/SceneGraph/assets/red.jpg
Binary files differ
diff --git a/tests/RenderScriptTests/SceneGraph/res/drawable-nodpi/checker.png b/tests/RenderScriptTests/SceneGraph/res/drawable-nodpi/checker.png
new file mode 100644
index 0000000..4bf9de5b
--- /dev/null
+++ b/tests/RenderScriptTests/SceneGraph/res/drawable-nodpi/checker.png
Binary files differ
diff --git a/tests/RenderScriptTests/SceneGraph/res/drawable-nodpi/defaultcube.png b/tests/RenderScriptTests/SceneGraph/res/drawable-nodpi/defaultcube.png
new file mode 100644
index 0000000..351fc12
--- /dev/null
+++ b/tests/RenderScriptTests/SceneGraph/res/drawable-nodpi/defaultcube.png
Binary files differ
diff --git a/tests/RenderScriptTests/SceneGraph/res/drawable-nodpi/robot.png b/tests/RenderScriptTests/SceneGraph/res/drawable-nodpi/robot.png
new file mode 100644
index 0000000..f7353fd
--- /dev/null
+++ b/tests/RenderScriptTests/SceneGraph/res/drawable-nodpi/robot.png
Binary files differ
diff --git a/tests/RenderScriptTests/SceneGraph/res/menu/loader_menu.xml b/tests/RenderScriptTests/SceneGraph/res/menu/loader_menu.xml
new file mode 100644
index 0000000..9ea30107
--- /dev/null
+++ b/tests/RenderScriptTests/SceneGraph/res/menu/loader_menu.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+* Copyright (C) 2011 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.
+*/
+-->
+
+<menu xmlns:android="http://schemas.android.com/apk/res/android">
+ <item android:id="@+id/load_model"
+ android:title="@string/load_model" />
+ <item android:id="@+id/use_blur"
+ android:title="@string/use_blur" />
+</menu>
diff --git a/tests/RenderScriptTests/SceneGraph/res/raw/blur_h.glsl b/tests/RenderScriptTests/SceneGraph/res/raw/blur_h.glsl
new file mode 100644
index 0000000..fa468cc
--- /dev/null
+++ b/tests/RenderScriptTests/SceneGraph/res/raw/blur_h.glsl
@@ -0,0 +1,15 @@
+varying vec2 varTex0;
+
+void main() {
+ vec2 blurCoord = varTex0;
+ blurCoord.x = varTex0.x + UNI_blurOffset0;
+ vec3 col = texture2D(UNI_Tex0, blurCoord).rgb;
+ blurCoord.x = varTex0.x + UNI_blurOffset1;
+ col += texture2D(UNI_Tex0, blurCoord).rgb;
+ blurCoord.x = varTex0.x + UNI_blurOffset2;
+ col += texture2D(UNI_Tex0, blurCoord).rgb;
+ blurCoord.x = varTex0.x + UNI_blurOffset3;
+ col += texture2D(UNI_Tex0, blurCoord).rgb;
+
+ gl_FragColor = vec4(col * 0.25, 0.0); //texture2D(UNI_Tex0, varTex0);
+}
diff --git a/tests/RenderScriptTests/SceneGraph/res/raw/blur_v.glsl b/tests/RenderScriptTests/SceneGraph/res/raw/blur_v.glsl
new file mode 100644
index 0000000..a644a3e
--- /dev/null
+++ b/tests/RenderScriptTests/SceneGraph/res/raw/blur_v.glsl
@@ -0,0 +1,17 @@
+varying vec2 varTex0;
+
+void main() {
+ vec2 blurCoord = varTex0;
+ blurCoord.y = varTex0.y + UNI_blurOffset0;
+ vec3 col = texture2D(UNI_Tex0, blurCoord).rgb;
+ blurCoord.y = varTex0.y + UNI_blurOffset1;
+ col += texture2D(UNI_Tex0, blurCoord).rgb;
+ blurCoord.y = varTex0.y + UNI_blurOffset2;
+ col += texture2D(UNI_Tex0, blurCoord).rgb;
+ blurCoord.y = varTex0.y + UNI_blurOffset3;
+ col += texture2D(UNI_Tex0, blurCoord).rgb;
+
+ col = col * 0.25;
+
+ gl_FragColor = vec4(col, 0.0); //texture2D(UNI_Tex0, varTex0);
+}
diff --git a/tests/RenderScriptTests/SceneGraph/res/raw/blur_vertex.glsl b/tests/RenderScriptTests/SceneGraph/res/raw/blur_vertex.glsl
new file mode 100644
index 0000000..bc824b6
--- /dev/null
+++ b/tests/RenderScriptTests/SceneGraph/res/raw/blur_vertex.glsl
@@ -0,0 +1,7 @@
+varying vec2 varTex0;
+
+void main() {
+ gl_Position = ATTRIB_position;
+ varTex0 = ATTRIB_texture0;
+}
+
diff --git a/tests/RenderScriptTests/SceneGraph/res/raw/diffuse.glsl b/tests/RenderScriptTests/SceneGraph/res/raw/diffuse.glsl
new file mode 100644
index 0000000..5d8938b
--- /dev/null
+++ b/tests/RenderScriptTests/SceneGraph/res/raw/diffuse.glsl
@@ -0,0 +1,19 @@
+varying vec3 varWorldPos;
+varying vec3 varWorldNormal;
+varying vec2 varTex0;
+
+void main() {
+
+ vec3 V = normalize(UNI_cameraPos.xyz - varWorldPos.xyz);
+ vec3 worldNorm = (varWorldNormal);
+
+ vec3 light0Vec = V;
+ vec3 light0R = reflect(light0Vec, worldNorm);
+ float light0_Diffuse = dot(worldNorm, light0Vec);
+
+ vec2 t0 = varTex0.xy;
+ lowp vec4 col = texture2D(UNI_Tex0, t0).rgba;
+ col.xyz = col.xyz * light0_Diffuse * 1.2;
+ gl_FragColor = col; //vec4(0.0, 1.0, 0.0, 0.0);
+}
+
diff --git a/tests/RenderScriptTests/SceneGraph/res/raw/metal.glsl b/tests/RenderScriptTests/SceneGraph/res/raw/metal.glsl
new file mode 100644
index 0000000..51f0612
--- /dev/null
+++ b/tests/RenderScriptTests/SceneGraph/res/raw/metal.glsl
@@ -0,0 +1,23 @@
+varying vec3 varWorldPos;
+varying vec3 varWorldNormal;
+varying vec2 varTex0;
+
+void main() {
+
+ vec3 V = normalize(UNI_cameraPos.xyz - varWorldPos.xyz);
+ vec3 worldNorm = normalize(varWorldNormal);
+
+ vec3 light0Vec = V;
+ vec3 light0R = reflect(light0Vec, worldNorm);
+ float light0_Diffuse = clamp(dot(worldNorm, light0Vec), 0.0, 1.0);
+ float light0Spec = clamp(dot(-light0R, V), 0.001, 1.0);
+ float light0_Specular = pow(light0Spec, 15.0) * 0.5;
+
+ vec2 t0 = varTex0.xy;
+ lowp vec4 col = texture2D(UNI_Tex0, t0).rgba;
+ col.xyz = col.xyz * (textureCube(UNI_Tex1, worldNorm).rgb * 0.5 + vec3(light0_Diffuse));
+ col.xyz += light0_Specular * vec3(0.8, 0.8, 1.0);
+
+ gl_FragColor = col;
+}
+
diff --git a/tests/RenderScriptTests/SceneGraph/res/raw/paintf.glsl b/tests/RenderScriptTests/SceneGraph/res/raw/paintf.glsl
new file mode 100644
index 0000000..893d553
--- /dev/null
+++ b/tests/RenderScriptTests/SceneGraph/res/raw/paintf.glsl
@@ -0,0 +1,26 @@
+varying vec3 varWorldPos;
+varying vec3 varWorldNormal;
+varying vec2 varTex0;
+
+void main() {
+
+ vec3 V = normalize(UNI_cameraPos.xyz - varWorldPos.xyz);
+ vec3 worldNorm = normalize(varWorldNormal);
+
+ vec3 light0Vec = V;
+ vec3 light0R = reflect(light0Vec, worldNorm);
+ float light0_Diffuse = clamp(dot(worldNorm, light0Vec), 0.01, 0.99);
+ float light0Spec = clamp(dot(-light0R, V), 0.001, 1.0);
+ float light0_Specular = pow(light0Spec, 150.0) * 0.5;
+
+ vec2 t0 = varTex0.xy;
+ lowp vec4 col = texture2D(UNI_Tex0, t0).rgba;
+ col.xyz = col.xyz * light0_Diffuse * 1.1;
+ col.xyz += light0_Specular * vec3(0.8, 0.8, 1.0);
+
+ float fresnel = mix(pow(1.0 - light0_Diffuse, 15.0), 1.0, 0.1);
+ col.xyz = mix(col.xyz, textureCube(UNI_Tex1, -light0R).rgb * 2.4, fresnel);
+ col.w = 0.8;
+ gl_FragColor = col;
+}
+
diff --git a/tests/RenderScriptTests/SceneGraph/res/raw/plastic.glsl b/tests/RenderScriptTests/SceneGraph/res/raw/plastic.glsl
new file mode 100644
index 0000000..ceb53bd
--- /dev/null
+++ b/tests/RenderScriptTests/SceneGraph/res/raw/plastic.glsl
@@ -0,0 +1,22 @@
+varying vec3 varWorldPos;
+varying vec3 varWorldNormal;
+varying vec2 varTex0;
+
+void main() {
+
+ vec3 V = normalize(UNI_cameraPos.xyz - varWorldPos.xyz);
+ vec3 worldNorm = normalize(varWorldNormal);
+
+ vec3 light0Vec = V;
+ vec3 light0R = reflect(light0Vec, worldNorm);
+ float light0_Diffuse = clamp(dot(worldNorm, light0Vec), 0.0, 1.0);
+ float light0Spec = clamp(dot(-light0R, V), 0.001, 1.0);
+ float light0_Specular = pow(light0Spec, 10.0) * 0.5;
+
+ vec2 t0 = varTex0.xy;
+ lowp vec4 col = texture2D(UNI_Tex0, t0).rgba;
+ col.xyz = col.xyz * light0_Diffuse * 1.2;
+ col.xyz += light0_Specular * vec3(0.8, 0.8, 1.0);
+ gl_FragColor = col;
+}
+
diff --git a/tests/RenderScriptTests/SceneGraph/res/raw/plastic_lights.glsl b/tests/RenderScriptTests/SceneGraph/res/raw/plastic_lights.glsl
new file mode 100644
index 0000000..b253622
--- /dev/null
+++ b/tests/RenderScriptTests/SceneGraph/res/raw/plastic_lights.glsl
@@ -0,0 +1,29 @@
+varying vec3 varWorldPos;
+varying vec3 varWorldNormal;
+varying vec2 varTex0;
+
+void main() {
+
+ vec3 V = normalize(UNI_cameraPos.xyz - varWorldPos.xyz);
+ vec3 worldNorm = normalize(varWorldNormal);
+
+ vec3 light0Vec = normalize(UNI_lightPos_0.xyz - varWorldPos.xyz);
+ vec3 light0R = reflect(light0Vec, worldNorm);
+ float light0_Diffuse = clamp(dot(worldNorm, light0Vec), 0.0, 1.0);
+ float light0Spec = clamp(dot(-light0R, V), 0.001, 1.0);
+ float light0_Specular = pow(light0Spec, 10.0) * 0.7;
+
+ vec3 light1Vec = normalize(UNI_lightPos_1.xyz - varWorldPos.xyz);
+ vec3 light1R = reflect(light1Vec, worldNorm);
+ float light1_Diffuse = clamp(dot(worldNorm, light1Vec), 0.0, 1.0);
+ float light1Spec = clamp(dot(-light1R, V), 0.001, 1.0);
+ float light1_Specular = pow(light1Spec, 10.0) * 0.7;
+
+ vec2 t0 = varTex0.xy;
+ lowp vec4 col = UNI_diffuse;
+ col.xyz = col.xyz * (light0_Diffuse * UNI_lightColor_0.xyz +
+ light1_Diffuse * UNI_lightColor_1.xyz);
+ col.xyz += (light0_Specular + light1_Specular);
+ gl_FragColor = col;
+}
+
diff --git a/tests/RenderScriptTests/SceneGraph/res/raw/robot.a3d b/tests/RenderScriptTests/SceneGraph/res/raw/robot.a3d
new file mode 100644
index 0000000..f48895c
--- /dev/null
+++ b/tests/RenderScriptTests/SceneGraph/res/raw/robot.a3d
Binary files differ
diff --git a/tests/RenderScriptTests/SceneGraph/res/raw/select_color.glsl b/tests/RenderScriptTests/SceneGraph/res/raw/select_color.glsl
new file mode 100644
index 0000000..42b231a
--- /dev/null
+++ b/tests/RenderScriptTests/SceneGraph/res/raw/select_color.glsl
@@ -0,0 +1,13 @@
+varying vec2 varTex0;
+
+void main() {
+ vec3 col = texture2D(UNI_Tex0, varTex0).rgb;
+
+ vec3 desat = vec3(0.299, 0.587, 0.114);
+ float lum = dot(desat, col);
+ float stepVal = step(lum, 0.8);
+ col = mix(col, vec3(0.0), stepVal)*0.5;
+
+ gl_FragColor = vec4(col, 0.0);
+}
+
diff --git a/tests/RenderScriptTests/SceneGraph/res/raw/shader2v.glsl b/tests/RenderScriptTests/SceneGraph/res/raw/shader2v.glsl
new file mode 100644
index 0000000..1ea234f
--- /dev/null
+++ b/tests/RenderScriptTests/SceneGraph/res/raw/shader2v.glsl
@@ -0,0 +1,17 @@
+varying vec3 varWorldPos;
+varying vec3 varWorldNormal;
+varying vec2 varTex0;
+
+// This is where actual shader code begins
+void main() {
+ vec4 objPos = ATTRIB_position;
+ vec4 worldPos = UNI_model * objPos;
+ gl_Position = UNI_viewProj * worldPos;
+
+ mat3 model3 = mat3(UNI_model[0].xyz, UNI_model[1].xyz, UNI_model[2].xyz);
+ vec3 worldNorm = model3 * ATTRIB_normal;
+
+ varWorldPos = worldPos.xyz;
+ varWorldNormal = worldNorm;
+ varTex0 = ATTRIB_texture0;
+}
diff --git a/tests/RenderScriptTests/SceneGraph/res/raw/texture.glsl b/tests/RenderScriptTests/SceneGraph/res/raw/texture.glsl
new file mode 100644
index 0000000..dd709cf
--- /dev/null
+++ b/tests/RenderScriptTests/SceneGraph/res/raw/texture.glsl
@@ -0,0 +1,7 @@
+varying vec2 varTex0;
+
+void main() {
+ lowp vec4 col = texture2D(UNI_Tex0, varTex0).rgba;
+ gl_FragColor = col;
+}
+
diff --git a/tests/RenderScriptTests/SceneGraph/res/values/strings.xml b/tests/RenderScriptTests/SceneGraph/res/values/strings.xml
new file mode 100644
index 0000000..c916d79
--- /dev/null
+++ b/tests/RenderScriptTests/SceneGraph/res/values/strings.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+* Copyright (C) 2011 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">
+ <skip />
+ <string name="load_model">Load Model</string>
+ <string name="use_blur">Use Blur</string>
+</resources>
diff --git a/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/Camera.java b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/Camera.java
new file mode 100644
index 0000000..6e19825
--- /dev/null
+++ b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/Camera.java
@@ -0,0 +1,118 @@
+/*
+ * Copyright (C) 2011 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.scenegraph;
+
+import java.lang.Math;
+import java.util.ArrayList;
+
+import com.android.scenegraph.SceneManager;
+
+import android.renderscript.*;
+import android.renderscript.Matrix4f;
+import android.renderscript.RenderScriptGL;
+import android.util.Log;
+
+/**
+ * @hide
+ */
+public class Camera extends SceneGraphBase {
+
+ Transform mTransform;
+
+ ScriptField_Camera_s.Item mData;
+ ScriptField_Camera_s mField;
+
+ public Camera() {
+ mData = new ScriptField_Camera_s.Item();
+ mData.near = 0.1f;
+ mData.far = 100.0f;
+ mData.horizontalFOV = 60.0f;
+ mData.aspect = 0;
+ }
+
+ public void setTransform(Transform t) {
+ mTransform = t;
+ if (mField != null) {
+ mField.set_transformMatrix(0, mTransform.getRSData().getAllocation(), true);
+ mField.set_isDirty(0, 1, true);
+ }
+ }
+ public void setFOV(float fov) {
+ mData.horizontalFOV = fov;
+ if (mField != null) {
+ mField.set_horizontalFOV(0, fov, true);
+ mField.set_isDirty(0, 1, true);
+ }
+ }
+
+ public void setNear(float n) {
+ mData.near = n;
+ if (mField != null) {
+ mField.set_near(0, n, true);
+ mField.set_isDirty(0, 1, true);
+ }
+ }
+
+ public void setFar(float f) {
+ mData.far = f;
+ if (mField != null) {
+ mField.set_far(0, f, true);
+ mField.set_isDirty(0, 1, true);
+ }
+ }
+
+ public void setName(String n) {
+ super.setName(n);
+ if (mField != null) {
+ RenderScriptGL rs = SceneManager.getRS();
+ mData.name = getNameAlloc(rs);
+ mField.set_name(0, mData.name, true);
+ mField.set_isDirty(0, 1, true);
+ }
+ }
+
+ ScriptField_Camera_s getRSData() {
+ if (mField != null) {
+ return mField;
+ }
+
+ RenderScriptGL rs = SceneManager.getRS();
+ if (rs == null) {
+ return null;
+ }
+
+ if (mTransform == null) {
+ throw new RuntimeException("Cameras without transforms are invalid");
+ }
+
+ mField = new ScriptField_Camera_s(rs, 1);
+
+ mData.transformMatrix = mTransform.getRSData().getAllocation();
+ mData.transformTimestamp = 1;
+ mData.timestamp = 1;
+ mData.isDirty = 1;
+ mData.name = getNameAlloc(rs);
+ mField.set(mData, 0, true);
+
+ return mField;
+ }
+}
+
+
+
+
+
diff --git a/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/ColladaParser.java b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/ColladaParser.java
new file mode 100644
index 0000000..d954313
--- /dev/null
+++ b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/ColladaParser.java
@@ -0,0 +1,563 @@
+/*
+ * Copyright (C) 2011 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.scenegraph;
+import com.android.scenegraph.CompoundTransform.TranslateComponent;
+import com.android.scenegraph.CompoundTransform.RotateComponent;
+import com.android.scenegraph.CompoundTransform.ScaleComponent;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import java.util.StringTokenizer;
+import java.util.HashMap;
+
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
+
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+import org.xml.sax.SAXException;
+
+import android.renderscript.*;
+import android.util.Log;
+
+public class ColladaParser {
+ static final String TAG = "ColladaParser";
+ Document mDom;
+
+ HashMap<String, LightBase> mLights;
+ HashMap<String, Camera> mCameras;
+ HashMap<String, ArrayList<ShaderParam> > mEffectsParams;
+ HashMap<String, Texture2D> mImages;
+ HashMap<String, Texture2D> mSamplerImageMap;
+ HashMap<String, String> mMeshIdNameMap;
+ Scene mScene;
+
+ String mRootDir;
+
+ String toString(Float3 v) {
+ String valueStr = v.x + " " + v.y + " " + v.z;
+ return valueStr;
+ }
+
+ String toString(Float4 v) {
+ String valueStr = v.x + " " + v.y + " " + v.z + " " + v.w;
+ return valueStr;
+ }
+
+ public ColladaParser(){
+ mLights = new HashMap<String, LightBase>();
+ mCameras = new HashMap<String, Camera>();
+ mEffectsParams = new HashMap<String, ArrayList<ShaderParam> >();
+ mImages = new HashMap<String, Texture2D>();
+ mMeshIdNameMap = new HashMap<String, String>();
+ }
+
+ public void init(InputStream is, String rootDir) {
+ mLights.clear();
+ mCameras.clear();
+ mEffectsParams.clear();
+
+ mRootDir = rootDir;
+
+ long start = System.currentTimeMillis();
+ DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
+ try {
+ DocumentBuilder db = dbf.newDocumentBuilder();
+ mDom = db.parse(is);
+ } catch(ParserConfigurationException e) {
+ e.printStackTrace();
+ } catch(SAXException e) {
+ e.printStackTrace();
+ } catch(IOException e) {
+ e.printStackTrace();
+ }
+ long end = System.currentTimeMillis();
+ Log.v("TIMER", " Parse time: " + (end - start));
+ exportSceneData();
+ }
+
+ Scene getScene() {
+ return mScene;
+ }
+
+ private void exportSceneData(){
+ mScene = new Scene();
+
+ Element docEle = mDom.getDocumentElement();
+ NodeList nl = docEle.getElementsByTagName("light");
+ if (nl != null) {
+ for(int i = 0; i < nl.getLength(); i++) {
+ Element l = (Element)nl.item(i);
+ convertLight(l);
+ }
+ }
+
+ nl = docEle.getElementsByTagName("camera");
+ if (nl != null) {
+ for(int i = 0; i < nl.getLength(); i++) {
+ Element c = (Element)nl.item(i);
+ convertCamera(c);
+ }
+ }
+
+ nl = docEle.getElementsByTagName("image");
+ if (nl != null) {
+ for(int i = 0; i < nl.getLength(); i++) {
+ Element img = (Element)nl.item(i);
+ convertImage(img);
+ }
+ }
+
+ nl = docEle.getElementsByTagName("effect");
+ if (nl != null) {
+ for(int i = 0; i < nl.getLength(); i++) {
+ Element e = (Element)nl.item(i);
+ convertEffects(e);
+ }
+ }
+
+ // Material is just a link to the effect
+ nl = docEle.getElementsByTagName("material");
+ if (nl != null) {
+ for(int i = 0; i < nl.getLength(); i++) {
+ Element m = (Element)nl.item(i);
+ convertMaterials(m);
+ }
+ }
+
+ // Look through the geometry list and build up a correlation between id's and names
+ nl = docEle.getElementsByTagName("geometry");
+ if (nl != null) {
+ for(int i = 0; i < nl.getLength(); i++) {
+ Element m = (Element)nl.item(i);
+ convertGeometries(m);
+ }
+ }
+
+
+ nl = docEle.getElementsByTagName("visual_scene");
+ if (nl != null) {
+ for(int i = 0; i < nl.getLength(); i++) {
+ Element s = (Element)nl.item(i);
+ getScene(s);
+ }
+ }
+ }
+
+ private void getRenderable(Element shape, Transform t) {
+ String geoURL = shape.getAttribute("url").substring(1);
+ String geoName = mMeshIdNameMap.get(geoURL);
+ if (geoName != null) {
+ geoURL = geoName;
+ }
+ //RenderableGroup group = new RenderableGroup();
+ //group.setName(geoURL.substring(1));
+ //mScene.appendRenderable(group);
+ NodeList nl = shape.getElementsByTagName("instance_material");
+ if (nl != null) {
+ for(int i = 0; i < nl.getLength(); i++) {
+ Element materialRef = (Element)nl.item(i);
+ String meshIndexName = materialRef.getAttribute("symbol");
+ String materialName = materialRef.getAttribute("target");
+
+ Renderable d = new Renderable();
+ d.setMesh(geoURL, meshIndexName);
+ d.setMaterialName(materialName.substring(1));
+ d.setName(geoURL);
+
+ //Log.v(TAG, "Created drawable geo " + geoURL + " index " + meshIndexName + " material " + materialName);
+
+ d.setTransform(t);
+ //Log.v(TAG, "Set source param " + t.getName());
+
+ // Now find all the parameters that exist on the material
+ ArrayList<ShaderParam> materialParams;
+ materialParams = mEffectsParams.get(materialName.substring(1));
+ for (int pI = 0; pI < materialParams.size(); pI ++) {
+ d.appendSourceParams(materialParams.get(pI));
+ //Log.v(TAG, "Set source param i: " + pI + " name " + materialParams.get(pI).getParamName());
+ }
+ mScene.appendRenderable(d);
+ //group.appendChildren(d);
+ }
+ }
+ }
+
+ private void updateLight(Element shape, Transform t) {
+ String lightURL = shape.getAttribute("url");
+ // collada uses a uri structure to link things,
+ // but we ignore it for now and do a simple search
+ LightBase light = mLights.get(lightURL.substring(1));
+ if (light != null) {
+ light.setTransform(t);
+ //Log.v(TAG, "Set Light " + light.getName() + " " + t.getName());
+ }
+ }
+
+ private void updateCamera(Element shape, Transform t) {
+ String camURL = shape.getAttribute("url");
+ // collada uses a uri structure to link things,
+ // but we ignore it for now and do a simple search
+ Camera cam = mCameras.get(camURL.substring(1));
+ if (cam != null) {
+ cam.setTransform(t);
+ //Log.v(TAG, "Set Camera " + cam.getName() + " " + t.getName());
+ }
+ }
+
+ private void getNode(Element node, Transform parent, String indent) {
+ String name = node.getAttribute("name");
+ String id = node.getAttribute("id");
+ CompoundTransform current = new CompoundTransform();
+ current.setName(name);
+ if (parent != null) {
+ parent.appendChild(current);
+ } else {
+ mScene.appendTransform(current);
+ }
+
+ mScene.addToTransformMap(current);
+
+ //Log.v(TAG, indent + "|");
+ //Log.v(TAG, indent + "[" + name + "]");
+
+ Node childNode = node.getFirstChild();
+ while (childNode != null) {
+ if (childNode.getNodeType() == Node.ELEMENT_NODE) {
+ Element field = (Element)childNode;
+ String fieldName = field.getTagName();
+ String description = field.getAttribute("sid");
+ if (fieldName.equals("translate")) {
+ Float3 value = getFloat3(field);
+ current.addComponent(new TranslateComponent(description, value));
+ //Log.v(TAG, indent + " translate " + description + toString(value));
+ } else if (fieldName.equals("rotate")) {
+ Float4 value = getFloat4(field);
+ //Log.v(TAG, indent + " rotate " + description + toString(value));
+ Float3 axis = new Float3(value.x, value.y, value.z);
+ current.addComponent(new RotateComponent(description, axis, value.w));
+ } else if (fieldName.equals("scale")) {
+ Float3 value = getFloat3(field);
+ //Log.v(TAG, indent + " scale " + description + toString(value));
+ current.addComponent(new ScaleComponent(description, value));
+ } else if (fieldName.equals("instance_geometry")) {
+ getRenderable(field, current);
+ } else if (fieldName.equals("instance_light")) {
+ updateLight(field, current);
+ } else if (fieldName.equals("instance_camera")) {
+ updateCamera(field, current);
+ } else if (fieldName.equals("node")) {
+ getNode(field, current, indent + " ");
+ }
+ }
+ childNode = childNode.getNextSibling();
+ }
+ }
+
+ // This will find the actual texture node, which is sometimes hidden behind a sampler
+ // and sometimes referenced directly
+ Texture2D getTexture(String samplerName) {
+ String texName = samplerName;
+
+ // Check to see if the image file is hidden by a sampler surface link combo
+ Element sampler = mDom.getElementById(samplerName);
+ if (sampler != null) {
+ NodeList nl = sampler.getElementsByTagName("source");
+ if (nl != null && nl.getLength() == 1) {
+ Element ref = (Element)nl.item(0);
+ String surfaceName = getString(ref);
+ if (surfaceName == null) {
+ return null;
+ }
+
+ Element surface = mDom.getElementById(surfaceName);
+ if (surface == null) {
+ return null;
+ }
+ nl = surface.getElementsByTagName("init_from");
+ if (nl != null && nl.getLength() == 1) {
+ ref = (Element)nl.item(0);
+ texName = getString(ref);
+ }
+ }
+ }
+
+ //Log.v(TAG, "Extracted texture name " + texName);
+ return mImages.get(texName);
+ }
+
+ void extractParams(Element fx, ArrayList<ShaderParam> params) {
+ Node paramNode = fx.getFirstChild();
+ while (paramNode != null) {
+ if (paramNode.getNodeType() == Node.ELEMENT_NODE) {
+ String name = paramNode.getNodeName();
+ // Now find what type it is
+ Node typeNode = paramNode.getFirstChild();
+ while (typeNode != null && typeNode.getNodeType() != Node.ELEMENT_NODE) {
+ typeNode = typeNode.getNextSibling();
+ }
+ String paramType = typeNode.getNodeName();
+ Element typeElem = (Element)typeNode;
+ ShaderParam sceneParam = null;
+ if (paramType.equals("color")) {
+ Float4Param f4p = new Float4Param(name);
+ Float4 value = getFloat4(typeElem);
+ f4p.setValue(value);
+ sceneParam = f4p;
+ //Log.v(TAG, "Extracted " + sceneParam.getParamName() + " value " + toString(value));
+ } else if (paramType.equals("float")) {
+ Float4Param f4p = new Float4Param(name);
+ float value = getFloat(typeElem);
+ f4p.setValue(new Float4(value, value, value, value));
+ sceneParam = f4p;
+ //Log.v(TAG, "Extracted " + sceneParam.getParamName() + " value " + value);
+ } else if (paramType.equals("texture")) {
+ String samplerName = typeElem.getAttribute("texture");
+ Texture2D tex = getTexture(samplerName);
+ TextureParam texP = new TextureParam(name);
+ texP.setTexture(tex);
+ sceneParam = texP;
+ //Log.v(TAG, "Extracted texture " + tex);
+ }
+ if (sceneParam != null) {
+ params.add(sceneParam);
+ }
+ }
+ paramNode = paramNode.getNextSibling();
+ }
+ }
+
+ private void convertMaterials(Element mat) {
+ String id = mat.getAttribute("id");
+ NodeList nl = mat.getElementsByTagName("instance_effect");
+ if (nl != null && nl.getLength() == 1) {
+ Element ref = (Element)nl.item(0);
+ String url = ref.getAttribute("url");
+ ArrayList<ShaderParam> params = mEffectsParams.get(url.substring(1));
+ mEffectsParams.put(id, params);
+ }
+ }
+
+ private void convertGeometries(Element geo) {
+ String id = geo.getAttribute("id");
+ String name = geo.getAttribute("name");
+ if (!id.equals(name)) {
+ mMeshIdNameMap.put(id, name);
+ }
+ }
+
+ private void convertEffects(Element fx) {
+ String id = fx.getAttribute("id");
+ ArrayList<ShaderParam> params = new ArrayList<ShaderParam>();
+
+ NodeList nl = fx.getElementsByTagName("newparam");
+ if (nl != null) {
+ for(int i = 0; i < nl.getLength(); i++) {
+ Element field = (Element)nl.item(i);
+ field.setIdAttribute("sid", true);
+ }
+ }
+
+ nl = fx.getElementsByTagName("blinn");
+ if (nl != null) {
+ for(int i = 0; i < nl.getLength(); i++) {
+ Element field = (Element)nl.item(i);
+ //Log.v(TAG, "blinn");
+ extractParams(field, params);
+ }
+ }
+ nl = fx.getElementsByTagName("lambert");
+ if (nl != null) {
+ for(int i = 0; i < nl.getLength(); i++) {
+ Element field = (Element)nl.item(i);
+ //Log.v(TAG, "lambert");
+ extractParams(field, params);
+ }
+ }
+ nl = fx.getElementsByTagName("phong");
+ if (nl != null) {
+ for(int i = 0; i < nl.getLength(); i++) {
+ Element field = (Element)nl.item(i);
+ //Log.v(TAG, "phong");
+ extractParams(field, params);
+ }
+ }
+ mEffectsParams.put(id, params);
+ }
+
+ private void convertLight(Element light) {
+ String name = light.getAttribute("name");
+ String id = light.getAttribute("id");
+
+ // Determine type
+ String[] knownTypes = { "point", "spot", "directional" };
+ final int POINT_LIGHT = 0;
+ final int SPOT_LIGHT = 1;
+ final int DIR_LIGHT = 2;
+ int type = -1;
+ for (int i = 0; i < knownTypes.length; i ++) {
+ NodeList nl = light.getElementsByTagName(knownTypes[i]);
+ if (nl != null && nl.getLength() != 0) {
+ type = i;
+ break;
+ }
+ }
+
+ //Log.v(TAG, "Found Light Type " + type);
+
+ LightBase sceneLight = null;
+ switch (type) {
+ case POINT_LIGHT:
+ sceneLight = new PointLight();
+ break;
+ case SPOT_LIGHT: // TODO: finish light types
+ break;
+ case DIR_LIGHT: // TODO: finish light types
+ break;
+ }
+
+ if (sceneLight == null) {
+ return;
+ }
+
+ Float3 color = getFloat3(light, "color");
+ sceneLight.setColor(color.x, color.y, color.z);
+ sceneLight.setName(name);
+ mScene.appendLight(sceneLight);
+ mLights.put(id, sceneLight);
+
+ //Log.v(TAG, "Light " + name + " color " + toString(color));
+ }
+
+ private void convertCamera(Element camera) {
+ String name = camera.getAttribute("name");
+ String id = camera.getAttribute("id");
+ float fov = 30.0f;
+ if (getString(camera, "yfov") != null) {
+ fov = getFloat(camera, "yfov");
+ } else if(getString(camera, "xfov") != null) {
+ float aspect = getFloat(camera, "aspect_ratio");
+ fov = getFloat(camera, "xfov") / aspect;
+ }
+
+ float near = getFloat(camera, "znear");
+ float far = getFloat(camera, "zfar");
+
+ Camera sceneCamera = new Camera();
+ sceneCamera.setFOV(fov);
+ sceneCamera.setNear(near);
+ sceneCamera.setFar(far);
+ sceneCamera.setName(name);
+ mScene.appendCamera(sceneCamera);
+ mCameras.put(id, sceneCamera);
+ }
+
+ private void convertImage(Element img) {
+ String name = img.getAttribute("name");
+ String id = img.getAttribute("id");
+ String file = getString(img, "init_from");
+
+ Texture2D tex = new Texture2D();
+ tex.setFileName(file);
+ tex.setFileDir(mRootDir);
+ mScene.appendTextures(tex);
+ mImages.put(id, tex);
+ }
+
+ private void getScene(Element scene) {
+ String name = scene.getAttribute("name");
+ String id = scene.getAttribute("id");
+
+ Node childNode = scene.getFirstChild();
+ while (childNode != null) {
+ if (childNode.getNodeType() == Node.ELEMENT_NODE) {
+ String indent = "";
+ getNode((Element)childNode, null, indent);
+ }
+ childNode = childNode.getNextSibling();
+ }
+ }
+
+ private String getString(Element elem, String name) {
+ String text = null;
+ NodeList nl = elem.getElementsByTagName(name);
+ if (nl != null && nl.getLength() != 0) {
+ text = ((Element)nl.item(0)).getFirstChild().getNodeValue();
+ }
+ return text;
+ }
+
+ private String getString(Element elem) {
+ String text = null;
+ text = elem.getFirstChild().getNodeValue();
+ return text;
+ }
+
+ private int getInt(Element elem, String name) {
+ return Integer.parseInt(getString(elem, name));
+ }
+
+ private float getFloat(Element elem, String name) {
+ return Float.parseFloat(getString(elem, name));
+ }
+
+ private float getFloat(Element elem) {
+ return Float.parseFloat(getString(elem));
+ }
+
+ private Float3 parseFloat3(String valueString) {
+ StringTokenizer st = new StringTokenizer(valueString);
+ float x = Float.parseFloat(st.nextToken());
+ float y = Float.parseFloat(st.nextToken());
+ float z = Float.parseFloat(st.nextToken());
+ return new Float3(x, y, z);
+ }
+
+ private Float4 parseFloat4(String valueString) {
+ StringTokenizer st = new StringTokenizer(valueString);
+ float x = Float.parseFloat(st.nextToken());
+ float y = Float.parseFloat(st.nextToken());
+ float z = Float.parseFloat(st.nextToken());
+ float w = Float.parseFloat(st.nextToken());
+ return new Float4(x, y, z, w);
+ }
+
+ private Float3 getFloat3(Element elem, String name) {
+ String valueString = getString(elem, name);
+ return parseFloat3(valueString);
+ }
+
+ private Float4 getFloat4(Element elem, String name) {
+ String valueString = getString(elem, name);
+ return parseFloat4(valueString);
+ }
+
+ private Float3 getFloat3(Element elem) {
+ String valueString = getString(elem);
+ return parseFloat3(valueString);
+ }
+
+ private Float4 getFloat4(Element elem) {
+ String valueString = getString(elem);
+ return parseFloat4(valueString);
+ }
+}
diff --git a/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/ColladaScene.java b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/ColladaScene.java
new file mode 100644
index 0000000..301075e
--- /dev/null
+++ b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/ColladaScene.java
@@ -0,0 +1,139 @@
+/*
+ * Copyright (C) 2011 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.scenegraph;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.FileInputStream;
+import java.io.BufferedInputStream;
+import java.io.Writer;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Vector;
+
+import android.content.res.Resources;
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
+import android.os.AsyncTask;
+import android.renderscript.*;
+import android.renderscript.Allocation.MipmapControl;
+import android.renderscript.Element.Builder;
+import android.renderscript.Font.Style;
+import android.renderscript.Program.TextureType;
+import android.renderscript.ProgramStore.DepthFunc;
+import android.util.Log;
+import com.android.scenegraph.SceneManager.SceneLoadedCallback;
+
+
+public class ColladaScene {
+
+ private String modelName;
+ private static String TAG = "ColladaScene";
+ private final int STATE_LAST_FOCUS = 1;
+ boolean mLoadFromSD = false;
+
+ SceneLoadedCallback mCallback;
+
+ public ColladaScene(String name, SceneLoadedCallback cb) {
+ modelName = name;
+ mCallback = cb;
+ }
+
+ public void init(RenderScriptGL rs, Resources res) {
+ mRS = rs;
+ mRes = res;
+
+ mLoadFromSD = SceneManager.isSDCardPath(modelName);
+
+ new ColladaLoaderTask().execute(modelName);
+ }
+
+ private Resources mRes;
+ private RenderScriptGL mRS;
+ Scene mActiveScene;
+
+ private class ColladaLoaderTask extends AsyncTask<String, Void, Boolean> {
+ ColladaParser sceneSource;
+ protected Boolean doInBackground(String... names) {
+ String rootDir = names[0].substring(0, names[0].lastIndexOf('/') + 1);
+ long start = System.currentTimeMillis();
+ sceneSource = new ColladaParser();
+ InputStream is = null;
+ try {
+ if (!mLoadFromSD) {
+ is = mRes.getAssets().open(names[0]);
+ } else {
+ File f = new File(names[0]);
+ is = new BufferedInputStream(new FileInputStream(f));
+ }
+ } catch (IOException e) {
+ Log.e(TAG, "Could not open collada file");
+ return new Boolean(false);
+ }
+ long end = System.currentTimeMillis();
+ Log.v("TIMER", "Stream load time: " + (end - start));
+
+ start = System.currentTimeMillis();
+ sceneSource.init(is, rootDir);
+ end = System.currentTimeMillis();
+ Log.v("TIMER", "Collada parse time: " + (end - start));
+ return new Boolean(true);
+ }
+
+ protected void onPostExecute(Boolean result) {
+ mActiveScene = sceneSource.getScene();
+ if (mCallback != null) {
+ mCallback.mLoadedScene = mActiveScene;
+ mCallback.run();
+ }
+
+ String shortName = modelName.substring(0, modelName.lastIndexOf('.'));
+ new A3DLoaderTask().execute(shortName + ".a3d");
+ }
+ }
+
+ private class A3DLoaderTask extends AsyncTask<String, Void, Boolean> {
+ protected Boolean doInBackground(String... names) {
+ long start = System.currentTimeMillis();
+ FileA3D model;
+ if (!mLoadFromSD) {
+ model = FileA3D.createFromAsset(mRS, mRes.getAssets(), names[0]);
+ } else {
+ model = FileA3D.createFromFile(mRS, names[0]);
+ }
+ int numModels = model.getIndexEntryCount();
+ for (int i = 0; i < numModels; i ++) {
+ FileA3D.IndexEntry entry = model.getIndexEntry(i);
+ if (entry != null && entry.getEntryType() == FileA3D.EntryType.MESH) {
+ mActiveScene.meshLoaded(entry.getMesh());
+ }
+ }
+ long end = System.currentTimeMillis();
+ Log.v("TIMER", "A3D load time: " + (end - start));
+ return new Boolean(true);
+ }
+
+ protected void onPostExecute(Boolean result) {
+ }
+ }
+
+}
+
+
+
diff --git a/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/CompoundTransform.java b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/CompoundTransform.java
new file mode 100644
index 0000000..d995dd0
--- /dev/null
+++ b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/CompoundTransform.java
@@ -0,0 +1,197 @@
+/*
+ * Copyright (C) 2011 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.scenegraph;
+
+import java.lang.Math;
+import java.util.ArrayList;
+
+import com.android.scenegraph.SceneManager;
+
+import android.renderscript.*;
+import android.renderscript.Float3;
+import android.renderscript.Matrix4f;
+import android.util.Log;
+
+/**
+ * @hide
+ */
+public class CompoundTransform extends Transform {
+
+ public static abstract class Component {
+ String mName;
+ CompoundTransform mParent;
+ int mParentIndex;
+ protected ScriptField_TransformComponent_s.Item mData;
+
+ Component(int type, String name) {
+ mData = new ScriptField_TransformComponent_s.Item();
+ mData.type = type;
+ mName = name;
+ }
+
+ void setNameAlloc() {
+ RenderScriptGL rs = SceneManager.getRS();
+ if (mData.name != null) {
+ return;
+ }
+ mData.name = SceneManager.getCachedAlloc(getName());
+ if (mData.name == null) {
+ mData.name = SceneManager.getStringAsAllocation(rs, getName());
+ SceneManager.cacheAlloc(getName(), mData.name);
+ }
+ }
+
+ ScriptField_TransformComponent_s.Item getRSData() {
+ setNameAlloc();
+ return mData;
+ }
+
+ protected void update() {
+ if (mParent != null) {
+ mParent.updateRSComponent(this);
+ }
+ }
+
+ public String getName() {
+ return mName;
+ }
+ }
+
+ public static class TranslateComponent extends Component {
+ public TranslateComponent(String name, Float3 translate) {
+ super(ScriptC_export.const_Transform_TRANSLATE, name);
+ setValue(translate);
+ }
+ public Float3 getValue() {
+ return new Float3(mData.value.x, mData.value.y, mData.value.z);
+ }
+ public void setValue(Float3 val) {
+ mData.value.x = val.x;
+ mData.value.y = val.y;
+ mData.value.z = val.z;
+ update();
+ }
+ }
+
+ public static class RotateComponent extends Component {
+ public RotateComponent(String name, Float3 axis, float angle) {
+ super(ScriptC_export.const_Transform_ROTATE, name);
+ setAxis(axis);
+ setAngle(angle);
+ }
+ public Float3 getAxis() {
+ return new Float3(mData.value.x, mData.value.y, mData.value.z);
+ }
+ public float getAngle() {
+ return mData.value.w;
+ }
+ public void setAxis(Float3 val) {
+ mData.value.x = val.x;
+ mData.value.y = val.y;
+ mData.value.z = val.z;
+ update();
+ }
+ public void setAngle(float val) {
+ mData.value.w = val;
+ update();
+ }
+ }
+
+ public static class ScaleComponent extends Component {
+ public ScaleComponent(String name, Float3 scale) {
+ super(ScriptC_export.const_Transform_SCALE, name);
+ setValue(scale);
+ }
+ public Float3 getValue() {
+ return new Float3(mData.value.x, mData.value.y, mData.value.z);
+ }
+ public void setValue(Float3 val) {
+ mData.value.x = val.x;
+ mData.value.y = val.y;
+ mData.value.z = val.z;
+ update();
+ }
+ }
+
+ ScriptField_TransformComponent_s mComponentField;
+ public ArrayList<Component> mTransformComponents;
+
+ public CompoundTransform() {
+ mTransformComponents = new ArrayList<Component>();
+ }
+
+ public void addComponent(Component c) {
+ if (c.mParent != null) {
+ throw new IllegalArgumentException("Transform components may not be shared");
+ }
+ c.mParent = this;
+ c.mParentIndex = mTransformComponents.size();
+ mTransformComponents.add(c);
+ updateRSComponentAllocation();
+ }
+
+ public void setComponent(int index, Component c) {
+ if (c.mParent != null) {
+ throw new IllegalArgumentException("Transform components may not be shared");
+ }
+ if (index >= mTransformComponents.size()) {
+ throw new IllegalArgumentException("Invalid component index");
+ }
+ c.mParent = this;
+ c.mParentIndex = index;
+ mTransformComponents.set(index, c);
+ updateRSComponent(c);
+ }
+
+ void updateRSComponent(Component c) {
+ if (mField == null || mComponentField == null) {
+ return;
+ }
+ mComponentField.set(c.getRSData(), c.mParentIndex, true);
+ mField.set_isDirty(0, 1, true);
+ }
+
+ void updateRSComponentAllocation() {
+ if (mField == null) {
+ return;
+ }
+ initLocalData();
+
+ mField.set_components(0, mTransformData.components, false);
+ mField.set_isDirty(0, 1, true);
+ }
+
+ void initLocalData() {
+ RenderScriptGL rs = SceneManager.getRS();
+ int numComponenets = mTransformComponents.size();
+ if (numComponenets > 0) {
+ mComponentField = new ScriptField_TransformComponent_s(rs, numComponenets);
+ for (int i = 0; i < numComponenets; i ++) {
+ Component ith = mTransformComponents.get(i);
+ mComponentField.set(ith.getRSData(), i, false);
+ }
+ mComponentField.copyAll();
+
+ mTransformData.components = mComponentField.getAllocation();
+ }
+ }
+}
+
+
+
+
+
diff --git a/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/Float4Param.java b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/Float4Param.java
new file mode 100644
index 0000000..1502458
--- /dev/null
+++ b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/Float4Param.java
@@ -0,0 +1,146 @@
+/*
+ * Copyright (C) 2011 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.scenegraph;
+
+import java.lang.Math;
+import java.util.ArrayList;
+
+import com.android.scenegraph.Scene;
+import com.android.scenegraph.SceneManager;
+
+import android.renderscript.Element;
+import android.renderscript.Float4;
+import android.renderscript.Matrix4f;
+import android.renderscript.ProgramFragment;
+import android.renderscript.ProgramStore;
+import android.renderscript.ProgramVertex;
+import android.renderscript.RenderScriptGL;
+import android.util.Log;
+
+/**
+ * @hide
+ */
+public class Float4Param extends ShaderParam {
+ private static String TAG = "Float4Param";
+
+ LightBase mLight;
+
+ public Float4Param(String name) {
+ super(name);
+ }
+
+ public Float4Param(String name, float x) {
+ super(name);
+ set(x, 0, 0, 0);
+ }
+
+ public Float4Param(String name, float x, float y) {
+ super(name);
+ set(x, y, 0, 0);
+ }
+
+ public Float4Param(String name, float x, float y, float z) {
+ super(name);
+ set(x, y, z, 0);
+ }
+
+ public Float4Param(String name, float x, float y, float z, float w) {
+ super(name);
+ set(x, y, z, w);
+ }
+
+ void set(float x, float y, float z, float w) {
+ mData.float_value.x = x;
+ mData.float_value.y = y;
+ mData.float_value.z = z;
+ mData.float_value.w = w;
+ if (mField != null) {
+ mField.set_float_value(0, mData.float_value, true);
+ }
+ incTimestamp();
+ }
+
+ public void setValue(Float4 v) {
+ set(v.x, v.y, v.z, v.w);
+ }
+
+ public Float4 getValue() {
+ return mData.float_value;
+ }
+
+ public void setLight(LightBase l) {
+ mLight = l;
+ if (mField != null) {
+ mData.light = mLight.getRSData().getAllocation();
+ mField.set_light(0, mData.light, true);
+ }
+ incTimestamp();
+ }
+
+ boolean findLight(String property) {
+ String indexStr = mParamName.substring(property.length() + 1);
+ if (indexStr == null) {
+ Log.e(TAG, "Invalid light index.");
+ return false;
+ }
+ int index = Integer.parseInt(indexStr);
+ if (index == -1) {
+ return false;
+ }
+ Scene parentScene = SceneManager.getInstance().getActiveScene();
+ ArrayList<LightBase> allLights = parentScene.getLights();
+ if (index >= allLights.size()) {
+ return false;
+ }
+ mLight = allLights.get(index);
+ if (mLight == null) {
+ return false;
+ }
+ return true;
+ }
+
+ int getTypeFromName() {
+ int paramType = ScriptC_export.const_ShaderParam_FLOAT4_DATA;
+ if (mParamName.equalsIgnoreCase(cameraPos)) {
+ paramType = ScriptC_export.const_ShaderParam_FLOAT4_CAMERA_POS;
+ } else if(mParamName.equalsIgnoreCase(cameraDir)) {
+ paramType = ScriptC_export.const_ShaderParam_FLOAT4_CAMERA_DIR;
+ } else if(mParamName.startsWith(lightColor) && findLight(lightColor)) {
+ paramType = ScriptC_export.const_ShaderParam_FLOAT4_LIGHT_COLOR;
+ } else if(mParamName.startsWith(lightPos) && findLight(lightPos)) {
+ paramType = ScriptC_export.const_ShaderParam_FLOAT4_LIGHT_POS;
+ } else if(mParamName.startsWith(lightDir) && findLight(lightDir)) {
+ paramType = ScriptC_export.const_ShaderParam_FLOAT4_LIGHT_DIR;
+ }
+ return paramType;
+ }
+
+ void initLocalData() {
+ mData.type = getTypeFromName();
+ if (mCamera != null) {
+ mData.camera = mCamera.getRSData().getAllocation();
+ }
+ if (mLight != null) {
+ mData.light = mLight.getRSData().getAllocation();
+ }
+ }
+}
+
+
+
+
+
diff --git a/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/FragmentShader.java b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/FragmentShader.java
new file mode 100644
index 0000000..ff6bbba
--- /dev/null
+++ b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/FragmentShader.java
@@ -0,0 +1,145 @@
+/*
+ * Copyright (C) 2011 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.scenegraph;
+
+import java.lang.Math;
+import java.util.ArrayList;
+
+import com.android.scenegraph.TextureBase;
+
+import android.content.res.Resources;
+import android.renderscript.*;
+import android.renderscript.ProgramFragment.Builder;
+import android.util.Log;
+
+/**
+ * @hide
+ */
+public class FragmentShader extends Shader {
+ ProgramFragment mProgram;
+ ScriptField_FragmentShader_s mField;
+
+ public static class Builder {
+
+ FragmentShader mShader;
+ ProgramFragment.Builder mBuilder;
+
+ public Builder(RenderScriptGL rs) {
+ mShader = new FragmentShader();
+ mBuilder = new ProgramFragment.Builder(rs);
+ }
+
+ public Builder setShader(Resources resources, int resourceID) {
+ mBuilder.setShader(resources, resourceID);
+ return this;
+ }
+
+ public Builder setObjectConst(Type type) {
+ mShader.mPerObjConstants = type;
+ return this;
+ }
+
+ public Builder setShaderConst(Type type) {
+ mShader.mPerShaderConstants = type;
+ return this;
+ }
+
+ public Builder addShaderTexture(Program.TextureType texType, String name) {
+ mShader.mShaderTextureNames.add(name);
+ mShader.mShaderTextureTypes.add(texType);
+ return this;
+ }
+
+ public Builder addTexture(Program.TextureType texType, String name) {
+ mShader.mTextureNames.add(name);
+ mShader.mTextureTypes.add(texType);
+ return this;
+ }
+
+ public FragmentShader create() {
+ if (mShader.mPerShaderConstants != null) {
+ mBuilder.addConstant(mShader.mPerShaderConstants);
+ }
+ if (mShader.mPerObjConstants != null) {
+ mBuilder.addConstant(mShader.mPerObjConstants);
+ }
+ for (int i = 0; i < mShader.mTextureTypes.size(); i ++) {
+ mBuilder.addTexture(mShader.mTextureTypes.get(i));
+ }
+ for (int i = 0; i < mShader.mShaderTextureTypes.size(); i ++) {
+ mBuilder.addTexture(mShader.mShaderTextureTypes.get(i));
+ }
+
+ mShader.mProgram = mBuilder.create();
+ return mShader;
+ }
+ }
+
+ public ProgramFragment getProgram() {
+ return mProgram;
+ }
+
+ public void updateTextures() {
+ RenderScriptGL rs = SceneManager.getRS();
+ Resources res = SceneManager.getRes();
+ if (rs == null || res == null) {
+ return;
+ }
+ int shaderTextureStart = mTextureTypes.size();
+ for (int i = 0; i < mShaderTextureNames.size(); i ++) {
+ ShaderParam sp = mSourceParams.get(mShaderTextureNames.get(i));
+ if (sp != null && sp instanceof TextureParam) {
+ TextureParam p = (TextureParam)sp;
+ TextureBase tex = p.getTexture();
+ if (tex != null) {
+ mProgram.bindTexture(tex.getRsData(), shaderTextureStart + i);
+ }
+ }
+ }
+ }
+
+ ScriptField_FragmentShader_s getRSData() {
+ if (mField != null) {
+ return mField;
+ }
+
+ RenderScriptGL rs = SceneManager.getRS();
+ Resources res = SceneManager.getRes();
+ if (rs == null || res == null) {
+ return null;
+ }
+
+ ScriptField_FragmentShader_s.Item item = new ScriptField_FragmentShader_s.Item();
+ item.program = mProgram;
+
+ linkConstants(rs);
+ if (mPerShaderConstants != null) {
+ item.shaderConst = mConstantBuffer;
+ item.shaderConstParams = mConstantBufferParams.getAllocation();
+ mProgram.bindConstants(item.shaderConst, 0);
+ }
+
+ item.objectConstIndex = -1;
+ if (mPerObjConstants != null) {
+ item.objectConstIndex = mPerShaderConstants != null ? 1 : 0;
+ }
+
+ mField = new ScriptField_FragmentShader_s(rs, 1);
+ mField.set(item, 0, true);
+ return mField;
+ }
+}
diff --git a/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/LightBase.java b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/LightBase.java
new file mode 100644
index 0000000..8f5e2e7
--- /dev/null
+++ b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/LightBase.java
@@ -0,0 +1,111 @@
+/*
+ * Copyright (C) 2011 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.scenegraph;
+
+import java.lang.Math;
+import java.util.ArrayList;
+
+import android.renderscript.Float3;
+import android.renderscript.Float4;
+import android.renderscript.Matrix4f;
+import android.renderscript.RenderScriptGL;
+import android.util.Log;
+
+/**
+ * @hide
+ */
+public abstract class LightBase extends SceneGraphBase {
+ static final int RS_LIGHT_POINT = 0;
+ static final int RS_LIGHT_DIRECTIONAL = 1;
+
+ ScriptField_Light_s mField;
+ ScriptField_Light_s.Item mFieldData;
+ Transform mTransform;
+ Float4 mColor;
+ float mIntensity;
+ public LightBase() {
+ mColor = new Float4(0.0f, 0.0f, 0.0f, 0.0f);
+ mIntensity = 1.0f;
+ }
+
+ public void setTransform(Transform t) {
+ mTransform = t;
+ updateRSData();
+ }
+
+ public void setColor(float r, float g, float b) {
+ mColor.x = r;
+ mColor.y = g;
+ mColor.z = b;
+ updateRSData();
+ }
+
+ public void setColor(Float3 c) {
+ setColor(c.x, c.y, c.z);
+ }
+
+ public void setIntensity(float i) {
+ mIntensity = i;
+ updateRSData();
+ }
+
+ public void setName(String n) {
+ super.setName(n);
+ updateRSData();
+ }
+
+ protected void updateRSData() {
+ if (mField == null) {
+ return;
+ }
+ RenderScriptGL rs = SceneManager.getRS();
+ mFieldData.transformMatrix = mTransform.getRSData().getAllocation();
+ mFieldData.name = getNameAlloc(rs);
+ mFieldData.color = mColor;
+ mFieldData.intensity = mIntensity;
+
+ initLocalData();
+
+ mField.set(mFieldData, 0, true);
+ }
+
+ abstract void initLocalData();
+
+ ScriptField_Light_s getRSData() {
+ if (mField != null) {
+ return mField;
+ }
+
+ RenderScriptGL rs = SceneManager.getRS();
+ if (rs == null) {
+ return null;
+ }
+ if (mField == null) {
+ mField = new ScriptField_Light_s(rs, 1);
+ mFieldData = new ScriptField_Light_s.Item();
+ }
+
+ updateRSData();
+
+ return mField;
+ }
+}
+
+
+
+
+
diff --git a/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/MatrixTransform.java b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/MatrixTransform.java
new file mode 100644
index 0000000..6d70bc9
--- /dev/null
+++ b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/MatrixTransform.java
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2011 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.scenegraph;
+
+import java.lang.Math;
+import java.util.ArrayList;
+
+import android.renderscript.Matrix4f;
+import android.util.Log;
+
+/**
+ * @hide
+ */
+public class MatrixTransform extends Transform {
+
+ Matrix4f mLocalMatrix;
+ public MatrixTransform() {
+ mLocalMatrix = new Matrix4f();
+ }
+
+ public void setMatrix(Matrix4f matrix) {
+ mLocalMatrix = matrix;
+ updateRSData();
+ }
+
+ public Matrix4f getMatrix() {
+ return new Matrix4f(mLocalMatrix.getArray());
+ }
+
+ void initLocalData() {
+ mTransformData.localMat = mLocalMatrix;
+ }
+
+ void updateRSData() {
+ if (mField == null) {
+ return;
+ }
+ mField.set_localMat(0, mLocalMatrix, false);
+ mField.set_isDirty(0, 1, true);
+ }
+}
+
+
+
+
+
diff --git a/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/PointLight.java b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/PointLight.java
new file mode 100644
index 0000000..574bafc
--- /dev/null
+++ b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/PointLight.java
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2011 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.scenegraph;
+
+import java.lang.Math;
+import java.util.ArrayList;
+
+import android.renderscript.Matrix4f;
+import android.renderscript.ProgramFragment;
+import android.renderscript.ProgramStore;
+import android.renderscript.ProgramVertex;
+import android.util.Log;
+
+/**
+ * @hide
+ */
+public class PointLight extends LightBase {
+ public PointLight() {
+ }
+
+ void initLocalData() {
+ mFieldData.type = RS_LIGHT_POINT;
+ }
+}
+
+
+
+
+
diff --git a/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/RenderPass.java b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/RenderPass.java
new file mode 100644
index 0000000..3cd70f5
--- /dev/null
+++ b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/RenderPass.java
@@ -0,0 +1,120 @@
+/*
+ * Copyright (C) 2011 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.scenegraph;
+
+import java.lang.Math;
+import java.util.ArrayList;
+
+import android.util.Log;
+
+import android.renderscript.*;
+import android.content.res.Resources;
+
+/**
+ * @hide
+ */
+public class RenderPass extends SceneGraphBase {
+
+ Allocation mColorTarget;
+ Float4 mClearColor;
+ boolean mShouldClearColor;
+
+ Allocation mDepthTarget;
+ float mClearDepth;
+ boolean mShouldClearDepth;
+
+ ArrayList<RenderableBase> mObjectsToDraw;
+
+ Camera mCamera;
+
+ ScriptField_RenderPass_s.Item mRsField;
+
+ public RenderPass() {
+ mObjectsToDraw = new ArrayList<RenderableBase>();
+ mClearColor = new Float4(0.0f, 0.0f, 0.0f, 0.0f);
+ mShouldClearColor = true;
+ mClearDepth = 1.0f;
+ mShouldClearDepth = true;
+ }
+
+ public void appendRenderable(Renderable d) {
+ mObjectsToDraw.add(d);
+ }
+
+ public void setCamera(Camera c) {
+ mCamera = c;
+ }
+
+ public void setColorTarget(Allocation colorTarget) {
+ mColorTarget = colorTarget;
+ }
+ public void setClearColor(Float4 clearColor) {
+ mClearColor = clearColor;
+ }
+ public void setShouldClearColor(boolean shouldClearColor) {
+ mShouldClearColor = shouldClearColor;
+ }
+
+ public void setDepthTarget(Allocation depthTarget) {
+ mDepthTarget = depthTarget;
+ }
+ public void setClearDepth(float clearDepth) {
+ mClearDepth = clearDepth;
+ }
+ public void setShouldClearDepth(boolean shouldClearDepth) {
+ mShouldClearDepth = shouldClearDepth;
+ }
+
+ public ArrayList<RenderableBase> getRenderables() {
+ return mObjectsToDraw;
+ }
+
+ ScriptField_RenderPass_s.Item getRsField(RenderScriptGL rs, Resources res) {
+ if (mRsField != null) {
+ return mRsField;
+ }
+
+ mRsField = new ScriptField_RenderPass_s.Item();
+ mRsField.color_target = mColorTarget;
+ mRsField.depth_target = mDepthTarget;
+ mRsField.camera = mCamera != null ? mCamera.getRSData().getAllocation() : null;
+
+ if (mObjectsToDraw.size() != 0) {
+ Allocation drawableData = Allocation.createSized(rs,
+ Element.ALLOCATION(rs),
+ mObjectsToDraw.size());
+ Allocation[] drawableAllocs = new Allocation[mObjectsToDraw.size()];
+ for (int i = 0; i < mObjectsToDraw.size(); i ++) {
+ Renderable dI = (Renderable)mObjectsToDraw.get(i);
+ drawableAllocs[i] = dI.getRsField(rs, res).getAllocation();
+ }
+ drawableData.copyFrom(drawableAllocs);
+ mRsField.objects = drawableData;
+ }
+
+ mRsField.clear_color = mClearColor;
+ mRsField.clear_depth = mClearDepth;
+ mRsField.should_clear_color = mShouldClearColor;
+ mRsField.should_clear_depth = mShouldClearDepth;
+ return mRsField;
+ }
+}
+
+
+
+
+
diff --git a/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/RenderState.java b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/RenderState.java
new file mode 100644
index 0000000..c08a722
--- /dev/null
+++ b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/RenderState.java
@@ -0,0 +1,111 @@
+/*
+ * Copyright (C) 2011 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.scenegraph;
+
+import java.lang.Math;
+import java.util.ArrayList;
+import android.content.res.Resources;
+
+import android.renderscript.Allocation;
+import android.renderscript.Element;
+import android.renderscript.Matrix4f;
+import android.renderscript.ProgramFragment;
+import android.renderscript.ProgramRaster;
+import android.renderscript.ProgramStore;
+import android.renderscript.ProgramVertex;
+import android.renderscript.RSRuntimeException;
+import android.renderscript.RenderScript;
+import android.renderscript.RenderScriptGL;
+import android.util.Log;
+
+/**
+ * @hide
+ */
+public class RenderState extends SceneGraphBase {
+ VertexShader mVertex;
+ FragmentShader mFragment;
+ ProgramStore mStore;
+ ProgramRaster mRaster;
+
+ ScriptField_RenderState_s mField;
+
+ public RenderState(VertexShader pv,
+ FragmentShader pf,
+ ProgramStore ps,
+ ProgramRaster pr) {
+ mVertex = pv;
+ mFragment = pf;
+ mStore = ps;
+ mRaster = pr;
+ }
+
+ public RenderState(RenderState r) {
+ mVertex = r.mVertex;
+ mFragment = r.mFragment;
+ mStore = r.mStore;
+ mRaster = r.mRaster;
+ }
+
+ public void setProgramVertex(VertexShader pv) {
+ mVertex = pv;
+ updateRSData();
+ }
+
+ public void setProgramFragment(FragmentShader pf) {
+ mFragment = pf;
+ updateRSData();
+ }
+
+ public void setProgramStore(ProgramStore ps) {
+ mStore = ps;
+ updateRSData();
+ }
+
+ public void setProgramRaster(ProgramRaster pr) {
+ mRaster = pr;
+ updateRSData();
+ }
+
+ void updateRSData() {
+ if (mField == null) {
+ return;
+ }
+ ScriptField_RenderState_s.Item item = new ScriptField_RenderState_s.Item();
+ item.pv = mVertex.getRSData().getAllocation();
+ item.pf = mFragment.getRSData().getAllocation();
+ item.ps = mStore;
+ item.pr = mRaster;
+
+ mField.set(item, 0, true);
+ }
+
+ public ScriptField_RenderState_s getRSData() {
+ if (mField != null) {
+ return mField;
+ }
+
+ RenderScriptGL rs = SceneManager.getRS();
+ if (rs == null) {
+ return null;
+ }
+
+ mField = new ScriptField_RenderState_s(rs, 1);
+ updateRSData();
+
+ return mField;
+ }
+}
diff --git a/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/Renderable.java b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/Renderable.java
new file mode 100644
index 0000000..481b2de
--- /dev/null
+++ b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/Renderable.java
@@ -0,0 +1,213 @@
+/*
+ * Copyright (C) 2011 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.scenegraph;
+
+import java.lang.Math;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+
+import com.android.scenegraph.Float4Param;
+import com.android.scenegraph.SceneManager;
+import com.android.scenegraph.ShaderParam;
+import com.android.scenegraph.TransformParam;
+
+import android.content.res.Resources;
+import android.renderscript.Allocation;
+import android.renderscript.Element;
+import android.renderscript.Element.DataType;
+import android.renderscript.Matrix4f;
+import android.renderscript.Mesh;
+import android.renderscript.ProgramFragment;
+import android.renderscript.ProgramStore;
+import android.renderscript.ProgramVertex;
+import android.renderscript.RenderScriptGL;
+import android.util.Log;
+
+/**
+ * @hide
+ */
+public class Renderable extends RenderableBase {
+ HashMap<String, ShaderParam> mSourceParams;
+
+ RenderState mRenderState;
+ Transform mTransform;
+
+ String mMeshName;
+ String mMeshIndexName;
+
+ public String mMaterialName;
+
+ ScriptField_Renderable_s mField;
+ ScriptField_Renderable_s.Item mData;
+
+ public Renderable() {
+ mSourceParams = new HashMap<String, ShaderParam>();
+ mData = new ScriptField_Renderable_s.Item();
+ }
+
+ public void setCullType(int cull) {
+ mData.cullType = cull;
+ }
+
+ public void setRenderState(RenderState renderState) {
+ mRenderState = renderState;
+ if (mField != null) {
+ RenderScriptGL rs = SceneManager.getRS();
+ updateFieldItem(rs);
+ mField.set(mData, 0, true);
+ }
+ }
+
+ public void setMesh(Mesh mesh) {
+ mData.mesh = mesh;
+ if (mField != null) {
+ mField.set_mesh(0, mData.mesh, true);
+ }
+ }
+
+ public void setMesh(String mesh, String indexName) {
+ mMeshName = mesh;
+ mMeshIndexName = indexName;
+ }
+
+ public void setMaterialName(String name) {
+ mMaterialName = name;
+ }
+
+ public void setTransform(Transform t) {
+ mTransform = t;
+ if (mField != null) {
+ RenderScriptGL rs = SceneManager.getRS();
+ updateFieldItem(rs);
+ mField.set(mData, 0, true);
+ }
+ }
+
+ public void appendSourceParams(ShaderParam p) {
+ mSourceParams.put(p.getParamName(), p);
+ // Possibly lift this restriction later
+ if (mField != null) {
+ throw new RuntimeException("Can't add source params to objects that are rendering");
+ }
+ }
+
+ public void resolveMeshData(Mesh mesh) {
+ mData.mesh = mesh;
+ if (mData.mesh == null) {
+ Log.v("DRAWABLE: ", "*** NO MESH *** " + mMeshName);
+ return;
+ }
+ int subIndexCount = mData.mesh.getPrimitiveCount();
+ if (subIndexCount == 1 || mMeshIndexName == null) {
+ mData.meshIndex = 0;
+ } else {
+ for (int i = 0; i < subIndexCount; i ++) {
+ if (mData.mesh.getIndexSetAllocation(i).getName().equals(mMeshIndexName)) {
+ mData.meshIndex = i;
+ break;
+ }
+ }
+ }
+ if (mField != null) {
+ mField.set(mData, 0, true);
+ }
+ }
+
+ void updateTextures(RenderScriptGL rs, Resources res) {
+ Iterator<ShaderParam> allParamsIter = mSourceParams.values().iterator();
+ int paramIndex = 0;
+ while (allParamsIter.hasNext()) {
+ ShaderParam sp = allParamsIter.next();
+ if (sp instanceof TextureParam) {
+ TextureParam p = (TextureParam)sp;
+ TextureBase tex = p.getTexture();
+ if (tex != null) {
+ mData.pf_textures[paramIndex++] = tex.getRsData();
+ }
+ }
+ }
+ ProgramFragment pf = mRenderState.mFragment.mProgram;
+ mData.pf_num_textures = pf != null ? Math.min(pf.getTextureCount(), paramIndex) : 0;
+ if (mField != null) {
+ mField.set_pf_textures(0, mData.pf_textures, true);
+ mField.set_pf_num_textures(0, mData.pf_num_textures, true);
+ }
+ }
+
+ public void setVisible(boolean vis) {
+ mData.cullType = vis ? 0 : 2;
+ if (mField != null) {
+ mField.set_cullType(0, mData.cullType, true);
+ }
+ }
+
+ ScriptField_Renderable_s getRsField(RenderScriptGL rs, Resources res) {
+ if (mField != null) {
+ return mField;
+ }
+ updateFieldItem(rs);
+
+ mField = new ScriptField_Renderable_s(rs, 1);
+ mField.set(mData, 0, true);
+
+ return mField;
+ }
+
+ void updateVertexConstants(RenderScriptGL rs) {
+ Allocation pvParams = null, vertexConstants = null;
+ VertexShader pv = mRenderState.mVertex;
+ if (pv != null && pv.getObjectConstants() != null) {
+ vertexConstants = Allocation.createTyped(rs, pv.getObjectConstants());
+ Element vertexConst = vertexConstants.getType().getElement();
+ pvParams = ShaderParam.fillInParams(vertexConst, mSourceParams,
+ mTransform).getAllocation();
+ }
+ mData.pv_const = vertexConstants;
+ mData.pv_constParams = pvParams;
+ }
+
+ void updateFragmentConstants(RenderScriptGL rs) {
+ Allocation pfParams = null, fragmentConstants = null;
+ FragmentShader pf = mRenderState.mFragment;
+ if (pf != null && pf.getObjectConstants() != null) {
+ fragmentConstants = Allocation.createTyped(rs, pf.getObjectConstants());
+ Element fragmentConst = fragmentConstants.getType().getElement();
+ pfParams = ShaderParam.fillInParams(fragmentConst, mSourceParams,
+ mTransform).getAllocation();
+ }
+ mData.pf_const = fragmentConstants;
+ mData.pf_constParams = pfParams;
+ }
+
+ void updateFieldItem(RenderScriptGL rs) {
+ updateVertexConstants(rs);
+ updateFragmentConstants(rs);
+
+ if (mTransform != null) {
+ mData.transformMatrix = mTransform.getRSData().getAllocation();
+ }
+ mData.name = getNameAlloc(rs);
+ mData.render_state = mRenderState.getRSData().getAllocation();
+ mData.bVolInitialized = 0;
+ }
+}
+
+
+
+
+
diff --git a/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/RenderableBase.java b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/RenderableBase.java
new file mode 100644
index 0000000..74535dd
--- /dev/null
+++ b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/RenderableBase.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2011 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.scenegraph;
+
+import java.lang.Math;
+import java.util.ArrayList;
+
+import android.renderscript.Matrix4f;
+import android.renderscript.ProgramFragment;
+import android.renderscript.ProgramStore;
+import android.renderscript.ProgramVertex;
+import android.util.Log;
+
+/**
+ * @hide
+ */
+public class RenderableBase extends SceneGraphBase {
+ public RenderableBase() {
+ }
+}
+
+
+
+
+
diff --git a/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/RenderableGroup.java b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/RenderableGroup.java
new file mode 100644
index 0000000..590bbab
--- /dev/null
+++ b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/RenderableGroup.java
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2011 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.scenegraph;
+
+import java.lang.Math;
+import java.util.ArrayList;
+
+import android.renderscript.Matrix4f;
+import android.renderscript.ProgramFragment;
+import android.renderscript.ProgramStore;
+import android.renderscript.ProgramVertex;
+import android.util.Log;
+
+/**
+ * @hide
+ */
+public class RenderableGroup extends RenderableBase {
+
+ ArrayList<RenderableBase> mChildren;
+
+ public RenderableGroup() {
+ mChildren = new ArrayList<RenderableBase>();
+ }
+
+ public void appendChildren(RenderableBase d) {
+ mChildren.add(d);
+ }
+}
+
+
+
+
+
diff --git a/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/Scene.java b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/Scene.java
new file mode 100644
index 0000000..79e932d
--- /dev/null
+++ b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/Scene.java
@@ -0,0 +1,334 @@
+/*
+ * Copyright (C) 2011 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.scenegraph;
+
+import java.lang.Math;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import com.android.scenegraph.SceneManager;
+
+import android.content.res.Resources;
+import android.os.AsyncTask;
+import android.renderscript.*;
+import android.renderscript.Mesh;
+import android.renderscript.RenderScriptGL;
+import android.util.Log;
+
+/**
+ * @hide
+ */
+public class Scene extends SceneGraphBase {
+ private static String TIMER_TAG = "TIMER";
+
+ private class ImageLoaderTask extends AsyncTask<ArrayList<RenderableBase>, Void, Boolean> {
+ protected Boolean doInBackground(ArrayList<RenderableBase>... objects) {
+ long start = System.currentTimeMillis();
+ for (int i = 0; i < objects[0].size(); i ++) {
+ Renderable dI = (Renderable)objects[0].get(i);
+ dI.updateTextures(mRS, mRes);
+ }
+ long end = System.currentTimeMillis();
+ Log.v(TIMER_TAG, "Texture init time: " + (end - start));
+ return new Boolean(true);
+ }
+
+ protected void onPostExecute(Boolean result) {
+ }
+ }
+
+ private class ShaderImageLoader extends AsyncTask<ArrayList<FragmentShader>, Void, Boolean> {
+ protected Boolean doInBackground(ArrayList<FragmentShader>... objects) {
+ long start = System.currentTimeMillis();
+ for (int i = 0; i < objects[0].size(); i ++) {
+ FragmentShader sI = objects[0].get(i);
+ sI.updateTextures();
+ }
+ long end = System.currentTimeMillis();
+ Log.v(TIMER_TAG, "Shader texture init time: " + (end - start));
+ return new Boolean(true);
+ }
+
+ protected void onPostExecute(Boolean result) {
+ }
+ }
+
+ CompoundTransform mRootTransforms;
+ HashMap<String, Transform> mTransformMap;
+ ArrayList<RenderPass> mRenderPasses;
+ ArrayList<LightBase> mLights;
+ ArrayList<Camera> mCameras;
+ ArrayList<FragmentShader> mFragmentShaders;
+ ArrayList<VertexShader> mVertexShaders;
+ ArrayList<RenderableBase> mRenderables;
+ HashMap<String, RenderableBase> mRenderableMap;
+ ArrayList<Texture2D> mTextures;
+
+ HashMap<String, ArrayList<Renderable> > mRenderableMeshMap;
+
+ // RS Specific stuff
+ ScriptField_SgTransform mTransformRSData;
+
+ RenderScriptGL mRS;
+ Resources mRes;
+
+ ScriptField_RenderPass_s mRenderPassAlloc;
+
+ public Scene() {
+ mRenderPasses = new ArrayList<RenderPass>();
+ mLights = new ArrayList<LightBase>();
+ mCameras = new ArrayList<Camera>();
+ mFragmentShaders = new ArrayList<FragmentShader>();
+ mVertexShaders = new ArrayList<VertexShader>();
+ mRenderables = new ArrayList<RenderableBase>();
+ mRenderableMap = new HashMap<String, RenderableBase>();
+ mRenderableMeshMap = new HashMap<String, ArrayList<Renderable> >();
+ mTextures = new ArrayList<Texture2D>();
+ mRootTransforms = new CompoundTransform();
+ mRootTransforms.setName("_scene_root_");
+ mTransformMap = new HashMap<String, Transform>();
+ }
+
+ public void appendTransform(Transform t) {
+ mRootTransforms.appendChild(t);
+ }
+
+ // temporary
+ public void addToTransformMap(Transform t) {
+ mTransformMap.put(t.getName(), t);
+ }
+
+ public Transform getTransformByName(String name) {
+ return mTransformMap.get(name);
+ }
+
+ public void appendRenderPass(RenderPass p) {
+ mRenderPasses.add(p);
+ }
+
+ public void clearRenderPasses() {
+ mRenderPasses.clear();
+ }
+
+ public void appendLight(LightBase l) {
+ mLights.add(l);
+ }
+
+ public void appendCamera(Camera c) {
+ mCameras.add(c);
+ }
+
+ public void appendShader(FragmentShader f) {
+ mFragmentShaders.add(f);
+ }
+
+ public void appendShader(VertexShader v) {
+ mVertexShaders.add(v);
+ }
+
+ public ArrayList<Camera> getCameras() {
+ return mCameras;
+ }
+
+ public ArrayList<LightBase> getLights() {
+ return mLights;
+ }
+
+ public void appendRenderable(RenderableBase d) {
+ mRenderables.add(d);
+ mRenderableMap.put(d.getName(), d);
+ }
+
+ public ArrayList<RenderableBase> getRenderables() {
+ return mRenderables;
+ }
+
+ public RenderableBase getRenderableByName(String name) {
+ return mRenderableMap.get(name);
+ }
+
+ public void appendTextures(Texture2D tex) {
+ mTextures.add(tex);
+ }
+
+ public void assignRenderStateToMaterial(RenderState renderState, String regex) {
+ Pattern pattern = Pattern.compile(regex);
+ int numRenderables = mRenderables.size();
+ for (int i = 0; i < numRenderables; i ++) {
+ Renderable shape = (Renderable)mRenderables.get(i);
+ Matcher m = pattern.matcher(shape.mMaterialName);
+ if (m.find()) {
+ shape.setRenderState(renderState);
+ }
+ }
+ }
+
+ public void assignRenderState(RenderState renderState) {
+ int numRenderables = mRenderables.size();
+ for (int i = 0; i < numRenderables; i ++) {
+ Renderable shape = (Renderable)mRenderables.get(i);
+ shape.setRenderState(renderState);
+ }
+ }
+
+ public void meshLoaded(Mesh m) {
+ ArrayList<Renderable> entries = mRenderableMeshMap.get(m.getName());
+ int numEntries = entries.size();
+ for (int i = 0; i < numEntries; i++) {
+ Renderable d = entries.get(i);
+ d.resolveMeshData(m);
+ }
+ }
+
+ void addToMeshMap(Renderable d) {
+ ArrayList<Renderable> entries = mRenderableMeshMap.get(d.mMeshName);
+ if (entries == null) {
+ entries = new ArrayList<Renderable>();
+ mRenderableMeshMap.put(d.mMeshName, entries);
+ }
+ entries.add(d);
+ }
+
+ public void destroyRS() {
+ SceneManager sceneManager = SceneManager.getInstance();
+ mTransformRSData = null;
+ sceneManager.mRenderLoop.bind_gRootNode(mTransformRSData);
+ sceneManager.mRenderLoop.set_gRenderableObjects(null);
+ mRenderPassAlloc = null;
+ sceneManager.mRenderLoop.set_gRenderPasses(null);
+ sceneManager.mRenderLoop.bind_gFrontToBack(null);
+ sceneManager.mRenderLoop.bind_gBackToFront(null);
+ sceneManager.mRenderLoop.set_gCameras(null);
+
+ mTransformMap = null;
+ mRenderPasses = null;
+ mLights = null;
+ mCameras = null;
+ mRenderables = null;
+ mRenderableMap = null;
+ mTextures = null;
+ mRenderableMeshMap = null;
+ mRootTransforms = null;
+ }
+
+ public void initRenderPassRS(RenderScriptGL rs, SceneManager sceneManager) {
+ new ShaderImageLoader().execute(mFragmentShaders);
+ if (mRenderPasses.size() != 0) {
+ mRenderPassAlloc = new ScriptField_RenderPass_s(mRS, mRenderPasses.size());
+ for (int i = 0; i < mRenderPasses.size(); i ++) {
+ mRenderPassAlloc.set(mRenderPasses.get(i).getRsField(mRS, mRes), i, false);
+ new ImageLoaderTask().execute(mRenderPasses.get(i).getRenderables());
+ }
+ mRenderPassAlloc.copyAll();
+ sceneManager.mRenderLoop.set_gRenderPasses(mRenderPassAlloc.getAllocation());
+ } else {
+ new ImageLoaderTask().execute(mRenderables);
+ }
+ }
+
+ private void addDrawables(RenderScriptGL rs, Resources res, SceneManager sceneManager) {
+ Allocation drawableData = Allocation.createSized(rs,
+ Element.ALLOCATION(rs),
+ mRenderables.size());
+ Allocation[] drawableAllocs = new Allocation[mRenderables.size()];
+ for (int i = 0; i < mRenderables.size(); i ++) {
+ Renderable dI = (Renderable)mRenderables.get(i);
+ addToMeshMap(dI);
+ drawableAllocs[i] = dI.getRsField(rs, res).getAllocation();
+ }
+ drawableData.copyFrom(drawableAllocs);
+ sceneManager.mRenderLoop.set_gRenderableObjects(drawableData);
+
+ initRenderPassRS(rs, sceneManager);
+ }
+
+ private void addShaders(RenderScriptGL rs, Resources res, SceneManager sceneManager) {
+ Allocation shaderData = Allocation.createSized(rs, Element.ALLOCATION(rs),
+ mVertexShaders.size());
+ Allocation[] shaderAllocs = new Allocation[mVertexShaders.size()];
+ for (int i = 0; i < mVertexShaders.size(); i ++) {
+ VertexShader sI = mVertexShaders.get(i);
+ shaderAllocs[i] = sI.getRSData().getAllocation();
+ }
+ shaderData.copyFrom(shaderAllocs);
+ sceneManager.mRenderLoop.set_gVertexShaders(shaderData);
+
+ shaderData = Allocation.createSized(rs, Element.ALLOCATION(rs), mFragmentShaders.size());
+ shaderAllocs = new Allocation[mFragmentShaders.size()];
+ for (int i = 0; i < mFragmentShaders.size(); i ++) {
+ FragmentShader sI = mFragmentShaders.get(i);
+ shaderAllocs[i] = sI.getRSData().getAllocation();
+ }
+ shaderData.copyFrom(shaderAllocs);
+ sceneManager.mRenderLoop.set_gFragmentShaders(shaderData);
+ }
+
+ public void initRS(RenderScriptGL rs, Resources res, SceneManager sceneManager) {
+ mRS = rs;
+ mRes = res;
+ long start = System.currentTimeMillis();
+ mTransformRSData = mRootTransforms.getRSData();
+ long end = System.currentTimeMillis();
+ Log.v(TIMER_TAG, "Transform init time: " + (end - start));
+
+ start = System.currentTimeMillis();
+
+ sceneManager.mRenderLoop.bind_gRootNode(mTransformRSData);
+ end = System.currentTimeMillis();
+ Log.v(TIMER_TAG, "Script init time: " + (end - start));
+
+ start = System.currentTimeMillis();
+ addDrawables(rs, res, sceneManager);
+ end = System.currentTimeMillis();
+ Log.v(TIMER_TAG, "Renderable init time: " + (end - start));
+
+ addShaders(rs, res, sceneManager);
+
+ Allocation opaqueBuffer = Allocation.createSized(rs, Element.U32(rs), mRenderables.size());
+ Allocation transparentBuffer = Allocation.createSized(rs,
+ Element.U32(rs), mRenderables.size());
+
+ sceneManager.mRenderLoop.bind_gFrontToBack(opaqueBuffer);
+ sceneManager.mRenderLoop.bind_gBackToFront(transparentBuffer);
+
+ Allocation cameraData = Allocation.createSized(rs, Element.ALLOCATION(rs), mCameras.size());
+ Allocation[] cameraAllocs = new Allocation[mCameras.size()];
+ for (int i = 0; i < mCameras.size(); i ++) {
+ cameraAllocs[i] = mCameras.get(i).getRSData().getAllocation();
+ }
+ cameraData.copyFrom(cameraAllocs);
+ sceneManager.mRenderLoop.set_gCameras(cameraData);
+
+ if (mLights.size() != 0) {
+ Allocation lightData = Allocation.createSized(rs,
+ Element.ALLOCATION(rs),
+ mCameras.size());
+ Allocation[] lightAllocs = new Allocation[mLights.size()];
+ for (int i = 0; i < mLights.size(); i ++) {
+ lightAllocs[i] = mLights.get(i).getRSData().getAllocation();
+ }
+ lightData.copyFrom(lightAllocs);
+ sceneManager.mRenderLoop.set_gLights(lightData);
+ }
+ }
+}
+
+
+
+
diff --git a/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/SceneGraphBase.java b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/SceneGraphBase.java
new file mode 100644
index 0000000..412ffbf
--- /dev/null
+++ b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/SceneGraphBase.java
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2011 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.scenegraph;
+
+import java.lang.Math;
+import java.util.ArrayList;
+
+import com.android.scenegraph.SceneManager;
+
+import android.renderscript.Allocation;
+import android.renderscript.Element;
+import android.renderscript.Matrix4f;
+import android.renderscript.ProgramFragment;
+import android.renderscript.ProgramStore;
+import android.renderscript.ProgramVertex;
+import android.renderscript.RSRuntimeException;
+import android.renderscript.RenderScript;
+import android.renderscript.RenderScriptGL;
+import android.util.Log;
+
+/**
+ * @hide
+ */
+public abstract class SceneGraphBase {
+ String mName;
+ Allocation mNameAlloc;
+ public void setName(String n) {
+ mName = n;
+ mNameAlloc = null;
+ }
+
+ public String getName() {
+ return mName;
+ }
+
+ Allocation getNameAlloc(RenderScriptGL rs) {
+ if (mNameAlloc == null) {
+ mNameAlloc = SceneManager.getStringAsAllocation(rs, getName());
+ }
+ return mNameAlloc;
+ }
+}
+
+
+
+
+
diff --git a/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/SceneManager.java b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/SceneManager.java
new file mode 100644
index 0000000..a9dd8a1
--- /dev/null
+++ b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/SceneManager.java
@@ -0,0 +1,291 @@
+/*
+ * Copyright (C) 2011 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.scenegraph;
+
+import java.io.BufferedInputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.Writer;
+import java.lang.Math;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import com.android.scenegraph.Scene;
+
+import android.content.res.Resources;
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
+import android.os.AsyncTask;
+import android.renderscript.*;
+import android.renderscript.Allocation.MipmapControl;
+import android.renderscript.Mesh;
+import android.renderscript.RenderScriptGL;
+import android.util.Log;
+import android.view.SurfaceHolder;
+
+import com.android.testapp.R;
+
+/**
+ * @hide
+ */
+public class SceneManager extends SceneGraphBase {
+
+ HashMap<String, Allocation> mAllocationMap;
+
+ ScriptC_render mRenderLoop;
+ ScriptC mCameraScript;
+ ScriptC mLightScript;
+ ScriptC mObjectParamsScript;
+ ScriptC mFragmentParamsScript;
+ ScriptC mVertexParamsScript;
+ ScriptC mCullScript;
+ ScriptC_transform mTransformScript;
+ ScriptC_export mExportScript;
+
+ RenderScriptGL mRS;
+ Resources mRes;
+ Mesh mQuad;
+ int mWidth;
+ int mHeight;
+
+ Scene mActiveScene;
+ private static SceneManager sSceneManager;
+
+ public static boolean isSDCardPath(String path) {
+ int sdCardIndex = path.indexOf("sdcard/");
+ // We are looking for /sdcard/ or sdcard/
+ if (sdCardIndex == 0 || sdCardIndex == 1) {
+ return true;
+ }
+ sdCardIndex = path.indexOf("mnt/sdcard/");
+ if (sdCardIndex == 0 || sdCardIndex == 1) {
+ return true;
+ }
+ return false;
+ }
+
+ static Bitmap loadBitmap(String name, Resources res) {
+ InputStream is = null;
+ boolean loadFromSD = isSDCardPath(name);
+ try {
+ if (!loadFromSD) {
+ is = res.getAssets().open(name);
+ } else {
+ File f = new File(name);
+ is = new BufferedInputStream(new FileInputStream(f));
+ }
+ } catch (IOException e) {
+ Log.e("ImageLoaderTask", " Message: " + e.getMessage());
+ return null;
+ }
+
+ Bitmap b = BitmapFactory.decodeStream(is);
+ try {
+ is.close();
+ } catch (IOException e) {
+ Log.e("ImageLoaderTask", " Message: " + e.getMessage());
+ }
+ return b;
+ }
+
+ public static Allocation loadCubemap(String name, RenderScriptGL rs, Resources res) {
+ Bitmap b = loadBitmap(name, res);
+ return Allocation.createCubemapFromBitmap(rs, b,
+ MipmapControl.MIPMAP_ON_SYNC_TO_TEXTURE,
+ Allocation.USAGE_GRAPHICS_TEXTURE);
+ }
+
+ public static Allocation loadTexture2D(String name, RenderScriptGL rs, Resources res) {
+ Bitmap b = loadBitmap(name, res);
+ return Allocation.createFromBitmap(rs, b,
+ Allocation.MipmapControl.MIPMAP_ON_SYNC_TO_TEXTURE,
+ Allocation.USAGE_GRAPHICS_TEXTURE);
+ }
+
+ public static ProgramStore BLEND_ADD_DEPTH_NONE(RenderScript rs) {
+ ProgramStore.Builder builder = new ProgramStore.Builder(rs);
+ builder.setDepthFunc(ProgramStore.DepthFunc.ALWAYS);
+ builder.setBlendFunc(ProgramStore.BlendSrcFunc.ONE, ProgramStore.BlendDstFunc.ONE);
+ builder.setDitherEnabled(false);
+ builder.setDepthMaskEnabled(false);
+ return builder.create();
+ }
+
+ static Allocation getStringAsAllocation(RenderScript rs, String str) {
+ if (str == null) {
+ return null;
+ }
+ if (str.length() == 0) {
+ return null;
+ }
+ byte[] allocArray = null;
+ byte[] nullChar = new byte[1];
+ nullChar[0] = 0;
+ try {
+ allocArray = str.getBytes("UTF-8");
+ Allocation alloc = Allocation.createSized(rs, Element.U8(rs),
+ allocArray.length + 1,
+ Allocation.USAGE_SCRIPT);
+ alloc.copy1DRangeFrom(0, allocArray.length, allocArray);
+ alloc.copy1DRangeFrom(allocArray.length, 1, nullChar);
+ return alloc;
+ }
+ catch (Exception e) {
+ throw new RSRuntimeException("Could not convert string to utf-8.");
+ }
+ }
+
+ static Allocation getCachedAlloc(String str) {
+ if (sSceneManager == null) {
+ throw new RuntimeException("Scene manager not initialized");
+ }
+ return sSceneManager.mAllocationMap.get(str);
+ }
+
+ static void cacheAlloc(String str, Allocation alloc) {
+ if (sSceneManager == null) {
+ throw new RuntimeException("Scene manager not initialized");
+ }
+ sSceneManager.mAllocationMap.put(str, alloc);
+ }
+
+ public static class SceneLoadedCallback implements Runnable {
+ public Scene mLoadedScene;
+ public String mName;
+ public void run() {
+ }
+ }
+
+ public Scene getActiveScene() {
+ return mActiveScene;
+ }
+
+ public void setActiveScene(Scene s) {
+ mActiveScene = s;
+ }
+
+ static RenderScriptGL getRS() {
+ if (sSceneManager == null) {
+ return null;
+ }
+ return sSceneManager.mRS;
+ }
+
+ static Resources getRes() {
+ if (sSceneManager == null) {
+ return null;
+ }
+ return sSceneManager.mRes;
+ }
+
+ public static SceneManager getInstance() {
+ if (sSceneManager == null) {
+ sSceneManager = new SceneManager();
+ }
+ return sSceneManager;
+ }
+
+ protected SceneManager() {
+ }
+
+ public void loadModel(String name, SceneLoadedCallback cb) {
+ ColladaScene scene = new ColladaScene(name, cb);
+ scene.init(mRS, mRes);
+ }
+
+ public Mesh getScreenAlignedQuad() {
+ if (mQuad != null) {
+ return mQuad;
+ }
+
+ Mesh.TriangleMeshBuilder tmb = new Mesh.TriangleMeshBuilder(mRS,
+ 3, Mesh.TriangleMeshBuilder.TEXTURE_0);
+
+ tmb.setTexture(0.0f, 1.0f);
+ tmb.addVertex(-1.0f, 1.0f, 1.0f);
+
+ tmb.setTexture(0.0f, 0.0f);
+ tmb.addVertex(-1.0f, -1.0f, 1.0f);
+
+ tmb.setTexture(1.0f, 0.0f);
+ tmb.addVertex(1.0f, -1.0f, 1.0f);
+
+ tmb.setTexture(1.0f, 1.0f);
+ tmb.addVertex(1.0f, 1.0f, 1.0f);
+
+ tmb.addTriangle(0, 1, 2);
+ tmb.addTriangle(2, 3, 0);
+
+ mQuad = tmb.create(true);
+ return mQuad;
+ }
+
+ public Renderable getRenderableQuad(String name, RenderState state) {
+ Renderable quad = new Renderable();
+ quad.setTransform(new MatrixTransform());
+ quad.setMesh(getScreenAlignedQuad());
+ quad.setName(name);
+ quad.setRenderState(state);
+ quad.setCullType(1);
+ return quad;
+ }
+
+ public void initRS(RenderScriptGL rs, Resources res, int w, int h) {
+ mRS = rs;
+ mRes = res;
+ mAllocationMap = new HashMap<String, Allocation>();
+
+ mExportScript = new ScriptC_export(rs, res, R.raw.export);
+
+ mTransformScript = new ScriptC_transform(rs, res, R.raw.transform);
+ mTransformScript.set_gTransformScript(mTransformScript);
+
+ mCameraScript = new ScriptC_camera(rs, res, R.raw.camera);
+ mLightScript = new ScriptC_light(rs, res, R.raw.light);
+ mObjectParamsScript = new ScriptC_object_params(rs, res, R.raw.object_params);
+ mFragmentParamsScript = new ScriptC_object_params(rs, res, R.raw.fragment_params);
+ mVertexParamsScript = new ScriptC_object_params(rs, res, R.raw.vertex_params);
+ mCullScript = new ScriptC_cull(rs, res, R.raw.cull);
+
+ mRenderLoop = new ScriptC_render(rs, res, R.raw.render);
+ mRenderLoop.set_gTransformScript(mTransformScript);
+ mRenderLoop.set_gCameraScript(mCameraScript);
+ mRenderLoop.set_gLightScript(mLightScript);
+ mRenderLoop.set_gObjectParamsScript(mObjectParamsScript);
+ mRenderLoop.set_gFragmentParamsScript(mFragmentParamsScript);
+ mRenderLoop.set_gVertexParamsScript(mVertexParamsScript);
+ mRenderLoop.set_gCullScript(mCullScript);
+
+ Allocation checker = Allocation.createFromBitmapResource(mRS, mRes, R.drawable.checker,
+ MipmapControl.MIPMAP_ON_SYNC_TO_TEXTURE,
+ Allocation.USAGE_GRAPHICS_TEXTURE);
+ mRenderLoop.set_gTGrid(checker);
+ mRenderLoop.set_gPFSBackground(ProgramStore.BLEND_NONE_DEPTH_TEST(mRS));
+ }
+
+ public ScriptC getRenderLoop() {
+ return mRenderLoop;
+ }
+}
+
+
+
+
diff --git a/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/Shader.java b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/Shader.java
new file mode 100644
index 0000000..4975114
--- /dev/null
+++ b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/Shader.java
@@ -0,0 +1,76 @@
+/*
+ * Copyright (C) 2011 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.scenegraph;
+
+import java.lang.Math;
+import java.util.ArrayList;
+import java.util.HashMap;
+
+import com.android.scenegraph.SceneGraphBase;
+import com.android.scenegraph.ShaderParam;
+
+import android.renderscript.*;
+import android.renderscript.ProgramFragment.Builder;
+import android.util.Log;
+
+/**
+ * @hide
+ */
+public abstract class Shader extends SceneGraphBase {
+ protected Type mPerObjConstants;
+ protected Type mPerShaderConstants;
+
+ protected HashMap<String, ShaderParam> mSourceParams;
+ protected ArrayList<String> mShaderTextureNames;
+ protected ArrayList<Program.TextureType > mShaderTextureTypes;
+ protected ArrayList<String> mTextureNames;
+ protected ArrayList<Program.TextureType > mTextureTypes;
+
+ protected Allocation mConstantBuffer;
+ protected ScriptField_ShaderParam_s mConstantBufferParams;
+
+ public Shader() {
+ mSourceParams = new HashMap<String, ShaderParam>();
+ mShaderTextureNames = new ArrayList<String>();
+ mShaderTextureTypes = new ArrayList<Program.TextureType>();
+ mTextureNames = new ArrayList<String>();
+ mTextureTypes = new ArrayList<Program.TextureType>();
+ }
+
+ public void appendSourceParams(ShaderParam p) {
+ mSourceParams.put(p.getParamName(), p);
+ }
+
+ public Type getObjectConstants() {
+ return mPerObjConstants;
+ }
+
+ public Type getShaderConstants() {
+ return mPerObjConstants;
+ }
+
+ void linkConstants(RenderScriptGL rs) {
+ if (mPerShaderConstants == null) {
+ return;
+ }
+
+ Element constElem = mPerShaderConstants.getElement();
+ mConstantBufferParams = ShaderParam.fillInParams(constElem, mSourceParams, null);
+
+ mConstantBuffer = Allocation.createTyped(rs, mPerShaderConstants);
+ }
+}
diff --git a/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/ShaderParam.java b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/ShaderParam.java
new file mode 100644
index 0000000..8dea535
--- /dev/null
+++ b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/ShaderParam.java
@@ -0,0 +1,162 @@
+/*
+ * Copyright (C) 2011 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.scenegraph;
+
+import java.lang.Math;
+import java.util.ArrayList;
+import java.util.HashMap;
+
+import com.android.scenegraph.SceneManager;
+import com.android.scenegraph.Transform;
+
+import android.renderscript.Element;
+import android.renderscript.Matrix4f;
+import android.renderscript.ProgramFragment;
+import android.renderscript.ProgramStore;
+import android.renderscript.ProgramVertex;
+import android.renderscript.RenderScriptGL;
+import android.util.Log;
+
+/**
+ * @hide
+ */
+public abstract class ShaderParam extends SceneGraphBase {
+
+ static final String cameraPos = "cameraPos";
+ static final String cameraDir = "cameraDir";
+
+ static final String lightColor = "lightColor";
+ static final String lightPos = "lightPos";
+ static final String lightDir = "lightDir";
+
+ static final String view = "view";
+ static final String proj = "proj";
+ static final String viewProj = "viewProj";
+ static final String model = "model";
+ static final String modelView = "modelView";
+ static final String modelViewProj = "modelViewProj";
+
+ static final long sMaxTimeStamp = 0xffffffffL;
+
+ ScriptField_ShaderParamData_s.Item mData;
+ ScriptField_ShaderParamData_s mField;
+
+ String mParamName;
+ Camera mCamera;
+
+ static ScriptField_ShaderParam_s fillInParams(Element constantElem,
+ HashMap<String, ShaderParam> sourceParams,
+ Transform transform) {
+ RenderScriptGL rs = SceneManager.getRS();
+ ArrayList<ScriptField_ShaderParam_s.Item> paramList;
+ paramList = new ArrayList<ScriptField_ShaderParam_s.Item>();
+
+ int subElemCount = constantElem.getSubElementCount();
+ for (int i = 0; i < subElemCount; i ++) {
+ String inputName = constantElem.getSubElementName(i);
+ int offset = constantElem.getSubElementOffsetBytes(i);
+
+ ShaderParam matchingParam = sourceParams.get(inputName);
+ Element subElem = constantElem.getSubElement(i);
+ // Make one if it's not there
+ if (matchingParam == null) {
+ if (subElem.getDataType() == Element.DataType.FLOAT_32) {
+ matchingParam = new Float4Param(inputName);
+ } else if (subElem.getDataType() == Element.DataType.MATRIX_4X4) {
+ TransformParam trParam = new TransformParam(inputName);
+ trParam.setTransform(transform);
+ matchingParam = trParam;
+ }
+ }
+ ScriptField_ShaderParam_s.Item paramRS = new ScriptField_ShaderParam_s.Item();
+ paramRS.bufferOffset = offset;
+ paramRS.transformTimestamp = 0;
+ paramRS.dataTimestamp = 0;
+ paramRS.data = matchingParam.getRSData().getAllocation();
+ if (subElem.getDataType() == Element.DataType.FLOAT_32) {
+ paramRS.float_vecSize = subElem.getVectorSize();
+ }
+
+ paramList.add(paramRS);
+ }
+
+ ScriptField_ShaderParam_s rsParams = null;
+ int paramCount = paramList.size();
+ if (paramCount != 0) {
+ rsParams = new ScriptField_ShaderParam_s(rs, paramCount);
+ for (int i = 0; i < paramCount; i++) {
+ rsParams.set(paramList.get(i), i, false);
+ }
+ rsParams.copyAll();
+ }
+ return rsParams;
+ }
+
+ public ShaderParam(String name) {
+ mParamName = name;
+ mData = new ScriptField_ShaderParamData_s.Item();
+ }
+
+ public String getParamName() {
+ return mParamName;
+ }
+
+ public void setCamera(Camera c) {
+ mCamera = c;
+ if (mField != null) {
+ mData.camera = mCamera.getRSData().getAllocation();
+ mField.set_camera(0, mData.camera, true);
+ }
+ }
+
+ protected void incTimestamp() {
+ if (mField != null) {
+ mData.timestamp ++;
+ mData.timestamp %= sMaxTimeStamp;
+ mField.set_timestamp(0, mData.timestamp, true);
+ }
+ }
+
+ abstract void initLocalData();
+
+ public ScriptField_ShaderParamData_s getRSData() {
+ if (mField != null) {
+ return mField;
+ }
+
+ RenderScriptGL rs = SceneManager.getRS();
+ mField = new ScriptField_ShaderParamData_s(rs, 1);
+
+ if (mParamName != null) {
+ mData.paramName = SceneManager.getCachedAlloc(mParamName);
+ if (mData.paramName == null) {
+ mData.paramName = SceneManager.getStringAsAllocation(rs, mParamName);
+ SceneManager.cacheAlloc(mParamName, mData.paramName);
+ }
+ }
+ initLocalData();
+ mData.timestamp = 1;
+
+ mField.set(mData, 0, true);
+ return mField;
+ }
+}
+
+
+
+
+
diff --git a/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/Texture2D.java b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/Texture2D.java
new file mode 100644
index 0000000..2f04858
--- /dev/null
+++ b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/Texture2D.java
@@ -0,0 +1,78 @@
+/*
+ * Copyright (C) 2011 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.scenegraph;
+
+import java.lang.Math;
+
+import com.android.scenegraph.SceneManager;
+
+import android.content.res.Resources;
+import android.renderscript.*;
+import android.util.Log;
+
+/**
+ * @hide
+ */
+public class Texture2D extends TextureBase {
+ String mFileName;
+ String mFileDir;
+
+ public Texture2D() {
+ }
+
+ public Texture2D(Allocation tex) {
+ setTexture(tex);
+ }
+
+ public void setFileDir(String dir) {
+ mFileDir = dir;
+ }
+
+ public void setFileName(String file) {
+ mFileName = file;
+ }
+
+ public String getFileName() {
+ return mFileName;
+ }
+
+ public void setTexture(Allocation tex) {
+ mRsTexture = tex;
+ }
+
+ Allocation getRsData() {
+ if (mRsTexture != null) {
+ return mRsTexture;
+ }
+
+ RenderScriptGL rs = SceneManager.getRS();
+ Resources res = SceneManager.getRes();
+ if (rs == null || res == null) {
+ return null;
+ }
+
+ String shortName = mFileName.substring(mFileName.lastIndexOf('/') + 1);
+ mRsTexture = SceneManager.loadTexture2D(mFileDir + shortName, rs, res);
+
+ return mRsTexture;
+ }
+}
+
+
+
+
+
diff --git a/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/TextureBase.java b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/TextureBase.java
new file mode 100644
index 0000000..425c6d6
--- /dev/null
+++ b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/TextureBase.java
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2012 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.scenegraph;
+
+import java.lang.Math;
+
+import com.android.scenegraph.SceneManager;
+
+import android.content.res.Resources;
+import android.renderscript.*;
+import android.util.Log;
+
+/**
+ * @hide
+ */
+public abstract class TextureBase extends SceneGraphBase {
+ protected Allocation mRsTexture;
+ abstract Allocation getRsData();
+}
+
+
+
+
+
diff --git a/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/TextureCube.java b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/TextureCube.java
new file mode 100644
index 0000000..ba42494
--- /dev/null
+++ b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/TextureCube.java
@@ -0,0 +1,84 @@
+/*
+ * Copyright (C) 2011 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.scenegraph;
+
+import java.lang.Math;
+
+import com.android.scenegraph.SceneManager;
+import com.android.scenegraph.TextureBase;
+
+import android.content.res.Resources;
+import android.renderscript.*;
+import android.util.Log;
+
+/**
+ * @hide
+ */
+public class TextureCube extends TextureBase {
+ String mFileName;
+ String mFileDir;
+
+ public TextureCube() {
+ }
+
+ public TextureCube(Allocation tex) {
+ setTexture(tex);
+ }
+
+ public TextureCube(String dir, String file) {
+ setFileDir(dir);
+ setFileName(file);
+ }
+
+ public void setFileDir(String dir) {
+ mFileDir = dir;
+ }
+
+ public void setFileName(String file) {
+ mFileName = file;
+ }
+
+ public String getFileName() {
+ return mFileName;
+ }
+
+ public void setTexture(Allocation tex) {
+ mRsTexture = tex;
+ }
+
+ Allocation getRsData() {
+ if (mRsTexture != null) {
+ return mRsTexture;
+ }
+
+ RenderScriptGL rs = SceneManager.getRS();
+ Resources res = SceneManager.getRes();
+ if (rs == null || res == null) {
+ return null;
+ }
+
+ String shortName = mFileName.substring(mFileName.lastIndexOf('/') + 1);
+ mRsTexture = SceneManager.loadCubemap(mFileDir + shortName, rs, res);
+
+ return mRsTexture;
+ }
+}
+
+
+
+
+
diff --git a/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/TextureParam.java b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/TextureParam.java
new file mode 100644
index 0000000..dd6b8f2
--- /dev/null
+++ b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/TextureParam.java
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 2011 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.scenegraph;
+
+import java.lang.Math;
+import java.util.ArrayList;
+
+import android.graphics.Camera;
+import android.renderscript.RenderScriptGL;
+import android.renderscript.Float4;
+import android.renderscript.Matrix4f;
+import android.renderscript.ProgramFragment;
+import android.renderscript.ProgramStore;
+import android.renderscript.ProgramVertex;
+import android.renderscript.Element;
+import android.util.Log;
+
+/**
+ * @hide
+ */
+public class TextureParam extends ShaderParam {
+
+ TextureBase mTexture;
+
+ public TextureParam(String name) {
+ super(name);
+ }
+
+ public TextureParam(String name, TextureBase t) {
+ super(name);
+ setTexture(t);
+ }
+
+ public void setTexture(TextureBase t) {
+ mTexture = t;
+ }
+
+ public TextureBase getTexture() {
+ return mTexture;
+ }
+
+ void initLocalData() {
+ }
+}
+
+
+
+
+
diff --git a/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/Transform.java b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/Transform.java
new file mode 100644
index 0000000..8180bd0
--- /dev/null
+++ b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/Transform.java
@@ -0,0 +1,98 @@
+/*
+ * Copyright (C) 2011 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.scenegraph;
+
+import java.lang.Math;
+import java.util.ArrayList;
+
+import android.renderscript.*;
+import android.renderscript.Matrix4f;
+import android.util.Log;
+
+/**
+ * @hide
+ */
+public abstract class Transform extends SceneGraphBase {
+ Transform mParent;
+ ArrayList<Transform> mChildren;
+
+ ScriptField_SgTransform mField;
+ ScriptField_SgTransform.Item mTransformData;
+
+ public Transform() {
+ mChildren = new ArrayList<Transform>();
+ mParent = null;
+ }
+
+ public void appendChild(Transform t) {
+ mChildren.add(t);
+ t.mParent = this;
+ updateRSChildData(true);
+ }
+
+ abstract void initLocalData();
+
+ void updateRSChildData(boolean copyData) {
+ if (mField == null) {
+ return;
+ }
+ RenderScriptGL rs = SceneManager.getRS();
+ if (mChildren.size() != 0) {
+ Allocation childRSData = Allocation.createSized(rs, Element.ALLOCATION(rs),
+ mChildren.size());
+ mTransformData.children = childRSData;
+
+ Allocation[] childrenAllocs = new Allocation[mChildren.size()];
+ for (int i = 0; i < mChildren.size(); i ++) {
+ Transform child = mChildren.get(i);
+ childrenAllocs[i] = child.getRSData().getAllocation();
+ }
+ childRSData.copyFrom(childrenAllocs);
+ }
+ if (copyData) {
+ mField.set(mTransformData, 0, true);
+ }
+ }
+
+ ScriptField_SgTransform getRSData() {
+ if (mField != null) {
+ return mField;
+ }
+
+ RenderScriptGL rs = SceneManager.getRS();
+ if (rs == null) {
+ return null;
+ }
+ mField = new ScriptField_SgTransform(rs, 1);
+
+ mTransformData = new ScriptField_SgTransform.Item();
+ mTransformData.name = getNameAlloc(rs);
+ mTransformData.isDirty = 1;
+ mTransformData.timestamp = 1;
+
+ initLocalData();
+ updateRSChildData(false);
+
+ mField.set(mTransformData, 0, true);
+ return mField;
+ }
+}
+
+
+
+
+
diff --git a/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/TransformParam.java b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/TransformParam.java
new file mode 100644
index 0000000..d120d5d
--- /dev/null
+++ b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/TransformParam.java
@@ -0,0 +1,85 @@
+/*
+ * Copyright (C) 2011 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.scenegraph;
+
+import java.lang.Math;
+import java.util.ArrayList;
+
+import android.renderscript.RenderScriptGL;
+import android.renderscript.Matrix4f;
+import android.renderscript.ProgramFragment;
+import android.renderscript.ProgramStore;
+import android.renderscript.ProgramVertex;
+import android.renderscript.Element;
+import android.util.Log;
+
+/**
+ * @hide
+ */
+public class TransformParam extends ShaderParam {
+
+ Transform mTransform;
+ LightBase mLight;
+
+ public TransformParam(String name) {
+ super(name);
+ }
+
+ public void setTransform(Transform t) {
+ mTransform = t;
+ if (mField != null && mTransform != null) {
+ mData.transform = mTransform.getRSData().getAllocation();
+ }
+ incTimestamp();
+ }
+
+ int getTypeFromName() {
+ int paramType = ScriptC_export.const_ShaderParam_TRANSFORM_DATA;
+ if (mParamName.equalsIgnoreCase(view)) {
+ paramType = ScriptC_export.const_ShaderParam_TRANSFORM_VIEW;
+ } else if(mParamName.equalsIgnoreCase(proj)) {
+ paramType = ScriptC_export.const_ShaderParam_TRANSFORM_PROJ;
+ } else if(mParamName.equalsIgnoreCase(viewProj)) {
+ paramType = ScriptC_export.const_ShaderParam_TRANSFORM_VIEW_PROJ;
+ } else if(mParamName.equalsIgnoreCase(model)) {
+ paramType = ScriptC_export.const_ShaderParam_TRANSFORM_MODEL;
+ } else if(mParamName.equalsIgnoreCase(modelView)) {
+ paramType = ScriptC_export.const_ShaderParam_TRANSFORM_MODEL_VIEW;
+ } else if(mParamName.equalsIgnoreCase(modelViewProj)) {
+ paramType = ScriptC_export.const_ShaderParam_TRANSFORM_MODEL_VIEW_PROJ;
+ }
+ return paramType;
+ }
+
+ void initLocalData() {
+ mData.type = getTypeFromName();
+ if (mTransform != null) {
+ mData.transform = mTransform.getRSData().getAllocation();
+ }
+ if (mCamera != null) {
+ mData.camera = mCamera.getRSData().getAllocation();
+ }
+ if (mLight != null) {
+ mData.light = mLight.getRSData().getAllocation();
+ }
+ }
+}
+
+
+
+
+
diff --git a/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/VertexShader.java b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/VertexShader.java
new file mode 100644
index 0000000..f7d0e6d
--- /dev/null
+++ b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/VertexShader.java
@@ -0,0 +1,108 @@
+/*
+ * Copyright (C) 2011 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.scenegraph;
+
+import java.lang.Math;
+import java.util.ArrayList;
+
+import android.content.res.Resources;
+import android.renderscript.*;
+import android.util.Log;
+
+/**
+ * @hide
+ */
+public class VertexShader extends Shader {
+ ProgramVertex mProgram;
+ ScriptField_VertexShader_s mField;
+
+ public static class Builder {
+ VertexShader mShader;
+ ProgramVertex.Builder mBuilder;
+
+ public Builder(RenderScriptGL rs) {
+ mShader = new VertexShader();
+ mBuilder = new ProgramVertex.Builder(rs);
+ }
+
+ public Builder setShader(Resources resources, int resourceID) {
+ mBuilder.setShader(resources, resourceID);
+ return this;
+ }
+
+ public Builder setObjectConst(Type type) {
+ mShader.mPerObjConstants = type;
+ return this;
+ }
+
+ public Builder setShaderConst(Type type) {
+ mShader.mPerShaderConstants = type;
+ return this;
+ }
+
+ public Builder addInput(Element e) {
+ mBuilder.addInput(e);
+ return this;
+ }
+
+ public VertexShader create() {
+ if (mShader.mPerShaderConstants != null) {
+ mBuilder.addConstant(mShader.mPerShaderConstants);
+ }
+ if (mShader.mPerObjConstants != null) {
+ mBuilder.addConstant(mShader.mPerObjConstants);
+ }
+ mShader.mProgram = mBuilder.create();
+ return mShader;
+ }
+ }
+
+ public ProgramVertex getProgram() {
+ return mProgram;
+ }
+
+ ScriptField_VertexShader_s getRSData() {
+ if (mField != null) {
+ return mField;
+ }
+
+ RenderScriptGL rs = SceneManager.getRS();
+ Resources res = SceneManager.getRes();
+ if (rs == null || res == null) {
+ return null;
+ }
+
+ ScriptField_VertexShader_s.Item item = new ScriptField_VertexShader_s.Item();
+ item.program = mProgram;
+
+ linkConstants(rs);
+ if (mPerShaderConstants != null) {
+ item.shaderConst = mConstantBuffer;
+ item.shaderConstParams = mConstantBufferParams.getAllocation();
+ mProgram.bindConstants(item.shaderConst, 0);
+ }
+
+ item.objectConstIndex = -1;
+ if (mPerObjConstants != null) {
+ item.objectConstIndex = mPerShaderConstants != null ? 1 : 0;
+ }
+
+ mField = new ScriptField_VertexShader_s(rs, 1);
+ mField.set(item, 0, true);
+ return mField;
+ }
+}
diff --git a/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/camera.rs b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/camera.rs
new file mode 100644
index 0000000..dc0a885
--- /dev/null
+++ b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/camera.rs
@@ -0,0 +1,66 @@
+// Copyright (C) 2011 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.scenegraph)
+
+//#define DEBUG_CAMERA
+#include "scenegraph_objects.rsh"
+
+void root(const rs_allocation *v_in, rs_allocation *v_out, const float *usrData) {
+
+ SgCamera *cam = (SgCamera *)rsGetElementAt(*v_in, 0);
+ float aspect = *usrData;
+ if (cam->aspect != aspect) {
+ cam->isDirty = 1;
+ cam->aspect = aspect;
+ }
+ if (cam->isDirty) {
+ rsMatrixLoadPerspective(&cam->proj, cam->horizontalFOV, cam->aspect, cam->near, cam->far);
+ }
+
+ const SgTransform *camTransform = (const SgTransform *)rsGetElementAt(cam->transformMatrix, 0);
+ //rsDebug("Camera stamp", cam->transformTimestamp);
+ //rsDebug("Transform stamp", camTransform->timestamp);
+ if (camTransform->timestamp != cam->transformTimestamp || cam->isDirty) {
+ cam->isDirty = 1;
+ rs_matrix4x4 camPosMatrix;
+ rsMatrixLoad(&camPosMatrix, &camTransform->globalMat);
+ float4 zero = {0.0f, 0.0f, 0.0f, 1.0f};
+ cam->position = rsMatrixMultiply(&camPosMatrix, zero);
+
+ rsMatrixInverse(&camPosMatrix);
+ rsMatrixLoad(&cam->view, &camPosMatrix);
+
+ rsMatrixLoad(&cam->viewProj, &cam->proj);
+ rsMatrixMultiply(&cam->viewProj, &cam->view);
+
+ rsExtractFrustumPlanes(&cam->viewProj,
+ &cam->frustumPlanes[0], &cam->frustumPlanes[1],
+ &cam->frustumPlanes[2], &cam->frustumPlanes[3],
+ &cam->frustumPlanes[3], &cam->frustumPlanes[4]);
+ }
+
+ if (cam->isDirty) {
+ cam->timestamp ++;
+ }
+
+ cam->isDirty = 0;
+ cam->transformTimestamp = camTransform->timestamp;
+
+#ifdef DEBUG_CAMERA
+ printCameraInfo(cam);
+#endif //DEBUG_CAMERA
+}
diff --git a/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/cull.rs b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/cull.rs
new file mode 100644
index 0000000..024e026
--- /dev/null
+++ b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/cull.rs
@@ -0,0 +1,86 @@
+// Copyright (C) 2012 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.scenegraph)
+
+#include "scenegraph_objects.rsh"
+
+static void getTransformedSphere(SgRenderable *obj) {
+ obj->worldBoundingSphere = obj->boundingSphere;
+ obj->worldBoundingSphere.w = 1.0f;
+ const SgTransform *objTransform = (const SgTransform *)rsGetElementAt(obj->transformMatrix, 0);
+ obj->worldBoundingSphere = rsMatrixMultiply(&objTransform->globalMat, obj->worldBoundingSphere);
+
+ const float4 unitVec = {0.57735f, 0.57735f, 0.57735f, 0.0f};
+ float4 scaledVec = rsMatrixMultiply(&objTransform->globalMat, unitVec);
+ scaledVec.w = 0.0f;
+ obj->worldBoundingSphere.w = obj->boundingSphere.w * length(scaledVec);
+}
+
+static bool frustumCulled(SgRenderable *obj, SgCamera *cam) {
+ if (!obj->bVolInitialized) {
+ float minX, minY, minZ, maxX, maxY, maxZ;
+ rsgMeshComputeBoundingBox(obj->mesh,
+ &minX, &minY, &minZ,
+ &maxX, &maxY, &maxZ);
+ //rsDebug("min", minX, minY, minZ);
+ //rsDebug("max", maxX, maxY, maxZ);
+ float4 sphere;
+ sphere.x = (maxX + minX) * 0.5f;
+ sphere.y = (maxY + minY) * 0.5f;
+ sphere.z = (maxZ + minZ) * 0.5f;
+ float3 radius;
+ radius.x = (maxX - sphere.x);
+ radius.y = (maxY - sphere.y);
+ radius.z = (maxZ - sphere.z);
+
+ sphere.w = length(radius);
+ obj->boundingSphere = sphere;
+ obj->bVolInitialized = 1;
+ //rsDebug("Sphere", sphere);
+ }
+
+ getTransformedSphere(obj);
+
+ return !rsIsSphereInFrustum(&obj->worldBoundingSphere,
+ &cam->frustumPlanes[0], &cam->frustumPlanes[1],
+ &cam->frustumPlanes[2], &cam->frustumPlanes[3],
+ &cam->frustumPlanes[4], &cam->frustumPlanes[5]);
+}
+
+
+void root(rs_allocation *v_out, const void *usrData) {
+
+ SgRenderable *drawable = (SgRenderable *)rsGetElementAt(*v_out, 0);
+ const SgCamera *camera = (const SgCamera*)usrData;
+
+ drawable->isVisible = 0;
+ // Not loaded yet
+ if (!rsIsObject(drawable->mesh) || drawable->cullType == CULL_ALWAYS) {
+ return;
+ }
+
+ // check to see if we are culling this object and if it's
+ // outside the frustum
+ if (drawable->cullType == CULL_FRUSTUM && frustumCulled(drawable, (SgCamera*)camera)) {
+#ifdef DEBUG_RENDERABLES
+ rsDebug("Culled", drawable);
+ printName(drawable->name);
+#endif // DEBUG_RENDERABLES
+ return;
+ }
+ drawable->isVisible = 1;
+}
diff --git a/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/export.rs b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/export.rs
new file mode 100644
index 0000000..c34c91e
--- /dev/null
+++ b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/export.rs
@@ -0,0 +1,56 @@
+// Copyright (C) 2011 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.scenegraph)
+
+// The sole purpose of this script is to have various structs exposed
+// so that java reflected classes are generated
+#include "scenegraph_objects.rsh"
+
+// Export our native constants to java so that we don't have parallel definitions
+const int ShaderParam_FLOAT4_DATA = SHADER_PARAM_FLOAT4_DATA;
+const int ShaderParam_TRANSFORM_DATA = SHADER_PARAM_TRANSFORM_DATA;
+const int ShaderParam_TRANSFORM_MODEL = SHADER_PARAM_TRANSFORM_MODEL;
+
+const int ShaderParam_FLOAT4_CAMERA_POS = SHADER_PARAM_FLOAT4_CAMERA_POS;
+const int ShaderParam_FLOAT4_CAMERA_DIR = SHADER_PARAM_FLOAT4_CAMERA_DIR;
+const int ShaderParam_TRANSFORM_VIEW = SHADER_PARAM_TRANSFORM_VIEW;
+const int ShaderParam_TRANSFORM_PROJ = SHADER_PARAM_TRANSFORM_PROJ;
+const int ShaderParam_TRANSFORM_VIEW_PROJ = SHADER_PARAM_TRANSFORM_VIEW_PROJ;
+const int ShaderParam_TRANSFORM_MODEL_VIEW = SHADER_PARAM_TRANSFORM_MODEL_VIEW;
+const int ShaderParam_TRANSFORM_MODEL_VIEW_PROJ = SHADER_PARAM_TRANSFORM_MODEL_VIEW_PROJ;
+
+const int ShaderParam_FLOAT4_LIGHT_COLOR = SHADER_PARAM_FLOAT4_LIGHT_COLOR;
+const int ShaderParam_FLOAT4_LIGHT_POS = SHADER_PARAM_FLOAT4_LIGHT_POS;
+const int ShaderParam_FLOAT4_LIGHT_DIR = SHADER_PARAM_FLOAT4_LIGHT_DIR;
+
+const int ShaderParam_TEXTURE = SHADER_PARAM_TEXTURE;
+
+const int Transform_TRANSLATE = TRANSFORM_TRANSLATE;
+const int Transform_ROTATE = TRANSFORM_ROTATE;
+const int Transform_SCALE = TRANSFORM_SCALE;
+
+SgTransform *exportPtr;
+SgTransformComponent *componentPtr;
+SgRenderState *sExport;
+SgRenderable *drExport;
+SgRenderPass *pExport;
+SgCamera *exportPtrCam;
+SgLight *exportPtrLight;
+SgShaderParam *spExport;
+SgShaderParamData *spDataExport;
+SgVertexShader *pvExport;
+SgFragmentShader *pfExport;
diff --git a/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/fragment_params.rs b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/fragment_params.rs
new file mode 100644
index 0000000..f5816ed
--- /dev/null
+++ b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/fragment_params.rs
@@ -0,0 +1,29 @@
+// Copyright (C) 2012 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.scenegraph)
+
+#include "scenegraph_objects.rsh"
+
+//#define DEBUG_PARAMS
+
+#include "params.rsh"
+
+void root(rs_allocation *v_out, const void *usrData) {
+ SgFragmentShader *shader = (SgFragmentShader *)rsGetElementAt(*v_out, 0);
+ const SgCamera *camera = (const SgCamera*)usrData;
+ processAllParams(shader->shaderConst, shader->shaderConstParams, camera);
+}
diff --git a/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/light.rs b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/light.rs
new file mode 100644
index 0000000..e11979f
--- /dev/null
+++ b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/light.rs
@@ -0,0 +1,33 @@
+// Copyright (C) 2011 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.scenegraph)
+
+//#define DEBUG_LIGHT
+#include "scenegraph_objects.rsh"
+
+void root(const rs_allocation *v_in, rs_allocation *v_out) {
+
+ SgLight *light = (SgLight *)rsGetElementAt(*v_in, 0);
+ const SgTransform *lTransform = (const SgTransform *)rsGetElementAt(light->transformMatrix, 0);
+
+ float4 zero = {0.0f, 0.0f, 0.0f, 1.0f};
+ light->position = rsMatrixMultiply(&lTransform->globalMat, zero);
+
+#ifdef DEBUG_LIGHT
+ printLightInfo(light);
+#endif //DEBUG_LIGHT
+}
diff --git a/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/object_params.rs b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/object_params.rs
new file mode 100644
index 0000000..0d524a6
--- /dev/null
+++ b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/object_params.rs
@@ -0,0 +1,36 @@
+// Copyright (C) 2012 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.scenegraph)
+
+#include "scenegraph_objects.rsh"
+
+//#define DEBUG_PARAMS
+
+#include "params.rsh"
+
+void root(rs_allocation *v_out, const void *usrData) {
+
+ SgRenderable *drawable = (SgRenderable *)rsGetElementAt(*v_out, 0);
+ // Visibility flag was set earlier in the cull stage
+ if (!drawable->isVisible) {
+ return;
+ }
+
+ const SgCamera *camera = (const SgCamera*)usrData;
+ processAllParams(drawable->pf_const, drawable->pf_constParams, camera);
+ processAllParams(drawable->pv_const, drawable->pv_constParams, camera);
+}
diff --git a/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/params.rsh b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/params.rsh
new file mode 100644
index 0000000..d1edb72
--- /dev/null
+++ b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/params.rsh
@@ -0,0 +1,169 @@
+// Copyright (C) 2012 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.scenegraph)
+
+#include "scenegraph_objects.rsh"
+
+//#define DEBUG_PARAMS
+static void debugParam(SgShaderParam *p, SgShaderParamData *pData,
+ uint8_t *constantBuffer, const SgCamera *currentCam) {
+ rsDebug("____________ Param ____________", p);
+ printName(pData->paramName);
+ rsDebug("bufferOffset", p->bufferOffset);
+ rsDebug("type ", pData->type);
+ rsDebug("data timestamp ", pData->timestamp);
+ rsDebug("param timestamp", p->dataTimestamp);
+
+ uint8_t *dataPtr = constantBuffer + p->bufferOffset;
+ const SgTransform *pTransform = NULL;
+ if (rsIsObject(pData->transform)) {
+ pTransform = (const SgTransform *)rsGetElementAt(pData->transform, 0);
+
+ rsDebug("transform", pTransform);
+ printName(pTransform->name);
+ rsDebug("timestamp", pTransform->timestamp);
+ rsDebug("param timestamp", p->transformTimestamp);
+ }
+
+ const SgLight *pLight = NULL;
+ if (rsIsObject(pData->light)) {
+ pLight = (const SgLight *)rsGetElementAt(pData->light, 0);
+ printLightInfo(pLight);
+ }
+}
+
+
+static void writeFloatData(float *ptr, const float4 *input, uint32_t vecSize) {
+#ifdef DEBUG_PARAMS
+ rsDebug("Writing value ", *input);
+ rsDebug("Writing vec size ", vecSize);
+#endif // DEBUG_PARAMS
+
+ switch (vecSize) {
+ case 1:
+ *ptr = input->x;
+ break;
+ case 2:
+ *((float2*)ptr) = (*input).xy;
+ break;
+ case 3:
+ *((float3*)ptr) = (*input).xyz;
+ break;
+ case 4:
+ *((float4*)ptr) = *input;
+ break;
+ }
+}
+
+static bool processParam(SgShaderParam *p, SgShaderParamData *pData,
+ uint8_t *constantBuffer, const SgCamera *currentCam) {
+ bool isDataOnly = (pData->type > SHADER_PARAM_DATA_ONLY);
+ const SgTransform *pTransform = NULL;
+ if (rsIsObject(pData->transform)) {
+ pTransform = (const SgTransform *)rsGetElementAt(pData->transform, 0);
+ }
+
+ if (isDataOnly) {
+ // If we are a transform param and our transform is unchanged, nothing to do
+ if (pTransform) {
+ if (p->transformTimestamp == pTransform->timestamp) {
+ return false;
+ }
+ p->transformTimestamp = pTransform->timestamp;
+ } else {
+ if (p->dataTimestamp == pData->timestamp) {
+ return false;
+ }
+ p->dataTimestamp = pData->timestamp;
+ }
+ }
+
+ const SgLight *pLight = NULL;
+ if (rsIsObject(pData->light)) {
+ pLight = (const SgLight *)rsGetElementAt(pData->light, 0);
+ }
+
+ uint8_t *dataPtr = constantBuffer + p->bufferOffset;
+
+ switch(pData->type) {
+ case SHADER_PARAM_FLOAT4_DATA:
+ writeFloatData((float*)dataPtr, &pData->float_value, p->float_vecSize);
+ break;
+ case SHADER_PARAM_FLOAT4_CAMERA_POS:
+ writeFloatData((float*)dataPtr, ¤tCam->position, p->float_vecSize);
+ break;
+ case SHADER_PARAM_FLOAT4_CAMERA_DIR: break;
+ case SHADER_PARAM_FLOAT4_LIGHT_COLOR:
+ writeFloatData((float*)dataPtr, &pLight->color, p->float_vecSize);
+ break;
+ case SHADER_PARAM_FLOAT4_LIGHT_POS:
+ writeFloatData((float*)dataPtr, &pLight->position, p->float_vecSize);
+ break;
+ case SHADER_PARAM_FLOAT4_LIGHT_DIR: break;
+
+ case SHADER_PARAM_TRANSFORM_DATA:
+ rsMatrixLoad((rs_matrix4x4*)dataPtr, &pTransform->globalMat);
+ break;
+ case SHADER_PARAM_TRANSFORM_VIEW:
+ rsMatrixLoad((rs_matrix4x4*)dataPtr, ¤tCam->view);
+ break;
+ case SHADER_PARAM_TRANSFORM_PROJ:
+ rsMatrixLoad((rs_matrix4x4*)dataPtr, ¤tCam->proj);
+ break;
+ case SHADER_PARAM_TRANSFORM_VIEW_PROJ:
+ rsMatrixLoad((rs_matrix4x4*)dataPtr, ¤tCam->viewProj);
+ break;
+ case SHADER_PARAM_TRANSFORM_MODEL:
+ rsMatrixLoad((rs_matrix4x4*)dataPtr, &pTransform->globalMat);
+ break;
+ case SHADER_PARAM_TRANSFORM_MODEL_VIEW:
+ rsMatrixLoad((rs_matrix4x4*)dataPtr, ¤tCam->view);
+ rsMatrixLoadMultiply((rs_matrix4x4*)dataPtr,
+ (rs_matrix4x4*)dataPtr,
+ &pTransform->globalMat);
+ break;
+ case SHADER_PARAM_TRANSFORM_MODEL_VIEW_PROJ:
+ rsMatrixLoad((rs_matrix4x4*)dataPtr, ¤tCam->viewProj);
+ rsMatrixLoadMultiply((rs_matrix4x4*)dataPtr,
+ (rs_matrix4x4*)dataPtr,
+ &pTransform->globalMat);
+ break;
+ }
+ return true;
+}
+
+static void processAllParams(rs_allocation shaderConst,
+ rs_allocation allParams,
+ const SgCamera *camera) {
+ if (rsIsObject(shaderConst)) {
+ uint8_t *constantBuffer = (uint8_t*)rsGetElementAt(shaderConst, 0);
+
+ int numParams = 0;
+ if (rsIsObject(allParams)) {
+ numParams = rsAllocationGetDimX(allParams);
+ }
+ bool updated = false;
+ for (int i = 0; i < numParams; i ++) {
+ SgShaderParam *current = (SgShaderParam*)rsGetElementAt(allParams, i);
+ SgShaderParamData *currentData = (SgShaderParamData*)rsGetElementAt(current->data, 0);
+#ifdef DEBUG_PARAMS
+ debugParam(current, currentData, constantBuffer, camera);
+#endif // DEBUG_PARAMS
+ updated = processParam(current, currentData, constantBuffer, camera) || updated;
+ }
+ }
+}
diff --git a/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/render.rs b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/render.rs
new file mode 100644
index 0000000..ecfec08
--- /dev/null
+++ b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/render.rs
@@ -0,0 +1,237 @@
+// Copyright (C) 2011-2012 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.scenegraph)
+
+#include "rs_graphics.rsh"
+#include "scenegraph_objects.rsh"
+
+rs_script gTransformScript;
+rs_script gCameraScript;
+rs_script gLightScript;
+rs_script gObjectParamsScript;
+rs_script gFragmentParamsScript;
+rs_script gVertexParamsScript;
+rs_script gCullScript;
+
+SgTransform *gRootNode;
+rs_allocation gCameras;
+rs_allocation gLights;
+rs_allocation gFragmentShaders;
+rs_allocation gVertexShaders;
+rs_allocation gRenderableObjects;
+
+rs_allocation gRenderPasses;
+
+// Temporary shaders
+rs_allocation gTGrid;
+rs_program_store gPFSBackground;
+
+uint32_t *gFrontToBack;
+static uint32_t gFrontToBackCount = 0;
+uint32_t *gBackToFront;
+static uint32_t gBackToFrontCount = 0;
+
+static SgCamera *gActiveCamera = NULL;
+
+static rs_allocation nullAlloc;
+
+//#define DEBUG_RENDERABLES
+static void draw(SgRenderable *obj) {
+#ifdef DEBUG_RENDERABLES
+ const SgTransform *objTransform = (const SgTransform *)rsGetElementAt(obj->transformMatrix, 0);
+ rsDebug("**** Drawing object with transform", obj);
+ printName(objTransform->name);
+ rsDebug("Model matrix: ", &objTransform->globalMat);
+ printName(obj->name);
+#endif //DEBUG_RENDERABLES
+
+ const SgRenderState *renderState = (const SgRenderState *)rsGetElementAt(obj->render_state, 0);
+ const SgVertexShader *pv = (const SgVertexShader *)rsGetElementAt(renderState->pv, 0);
+ const SgFragmentShader *pf = (const SgFragmentShader *)rsGetElementAt(renderState->pf, 0);
+
+ if (pv->objectConstIndex != -1) {
+ rsgBindConstant(pv->program, pv->objectConstIndex, obj->pv_const);
+ }
+ if (pf->objectConstIndex != -1) {
+ rsgBindConstant(pf->program, pf->objectConstIndex, obj->pf_const);
+ }
+
+ if (rsIsObject(renderState->ps)) {
+ rsgBindProgramStore(renderState->ps);
+ } else {
+ rsgBindProgramStore(gPFSBackground);
+ }
+
+ if (rsIsObject(renderState->pr)) {
+ rsgBindProgramRaster(renderState->pr);
+ } else {
+ rs_program_raster pr;
+ rsgBindProgramRaster(pr);
+ }
+
+ rsgBindProgramVertex(pv->program);
+ rsgBindProgramFragment(pf->program);
+
+ for (uint32_t i = 0; i < obj->pf_num_textures; i ++) {
+ if (rsIsObject(obj->pf_textures[i])) {
+ rsgBindTexture(pf->program, i, obj->pf_textures[i]);
+ } else {
+ rsgBindTexture(pf->program, i, gTGrid);
+ }
+ }
+
+ rsgDrawMesh(obj->mesh, obj->meshIndex);
+}
+
+static void sortToBucket(SgRenderable *obj) {
+ const SgRenderState *renderState = (const SgRenderState *)rsGetElementAt(obj->render_state, 0);
+ if (rsIsObject(renderState->ps)) {
+ bool isOpaque = false;
+ if (isOpaque) {
+ gFrontToBack[gFrontToBackCount++] = (uint32_t)obj;
+ } else {
+ gBackToFront[gBackToFrontCount++] = (uint32_t)obj;
+ }
+ } else {
+ gFrontToBack[gFrontToBackCount++] = (uint32_t)obj;
+ }
+}
+
+static void updateActiveCamera(rs_allocation cam) {
+ gActiveCamera = (SgCamera *)rsGetElementAt(cam, 0);
+}
+
+static void prepareCameras() {
+ // now compute all the camera matrices
+ float aspect = (float)rsgGetWidth() / (float)rsgGetHeight();
+ rsForEach(gCameraScript, gCameras, nullAlloc, &aspect, sizeof(aspect));
+}
+
+static void prepareLights() {
+ if (rsIsObject(gLights)) {
+ rsForEach(gLightScript, gLights, nullAlloc);
+ }
+}
+
+static void drawSorted() {
+ for (int i = 0; i < gFrontToBackCount; i ++) {
+ SgRenderable *current = (SgRenderable*)gFrontToBack[i];
+ draw(current);
+ }
+
+ for (int i = 0; i < gBackToFrontCount; i ++) {
+ SgRenderable *current = (SgRenderable*)gBackToFront[i];
+ draw(current);
+ }
+}
+
+static void drawAllObjects(rs_allocation allObj) {
+ if (!rsIsObject(allObj)) {
+ return;
+ }
+
+ rsForEach(gVertexParamsScript, nullAlloc, gVertexShaders,
+ gActiveCamera, sizeof(gActiveCamera));
+ rsForEach(gFragmentParamsScript, nullAlloc, gFragmentShaders,
+ gActiveCamera, sizeof(gActiveCamera));
+
+ // Run the params and cull script
+ rsForEach(gCullScript, nullAlloc, allObj, gActiveCamera, sizeof(gActiveCamera));
+ rsForEach(gObjectParamsScript, nullAlloc, allObj, gActiveCamera, sizeof(gActiveCamera));
+
+ int numRenderables = rsAllocationGetDimX(allObj);
+ for (int i = 0; i < numRenderables; i ++) {
+ rs_allocation *drawAlloc = (rs_allocation*)rsGetElementAt(allObj, i);
+ SgRenderable *current = (SgRenderable*)rsGetElementAt(*drawAlloc, 0);
+ if (current->isVisible) {
+ sortToBucket(current);
+ }
+ }
+ drawSorted();
+}
+
+void root(const void *v_in, void *v_out) {
+#ifdef DEBUG_RENDERABLES
+ rsDebug("=============================================================================", 0);
+#endif // DEBUG_RENDERABLES
+ // first step is to update the transform hierachy
+ rsForEach(gTransformScript, gRootNode->children, nullAlloc, 0, 0);
+
+ prepareCameras();
+ prepareLights();
+
+ rsgClearDepth(1.0f);
+
+ int numRenderables = rsAllocationGetDimX(gRenderableObjects);
+ if (rsIsObject(gRenderPasses)) {
+ int numPasses = rsAllocationGetDimX(gRenderPasses);
+ for (uint i = 0; i < numPasses; i ++) {
+ gFrontToBackCount = 0;
+ gBackToFrontCount = 0;
+ SgRenderPass *pass = (SgRenderPass*)rsGetElementAt(gRenderPasses, i);
+ if (rsIsObject(pass->color_target)) {
+ rsgBindColorTarget(pass->color_target, 0);
+ }
+ if (rsIsObject(pass->depth_target)) {
+ rsgBindDepthTarget(pass->depth_target);
+ }
+ if (!rsIsObject(pass->color_target) &&
+ !rsIsObject(pass->depth_target)) {
+ rsgClearAllRenderTargets();
+ }
+ updateActiveCamera(pass->camera);
+ if (pass->should_clear_color) {
+ rsgClearColor(pass->clear_color.x, pass->clear_color.y,
+ pass->clear_color.z, pass->clear_color.w);
+ }
+ if (pass->should_clear_depth) {
+ rsgClearDepth(pass->clear_depth);
+ }
+ drawAllObjects(pass->objects);
+ }
+ } else {
+ gFrontToBackCount = 0;
+ gBackToFrontCount = 0;
+ rsgClearColor(1.0f, 1.0f, 1.0f, 1.0f);
+ rsgClearDepth(1.0f);
+ rs_allocation *camAlloc = (rs_allocation*)rsGetElementAt(gCameras, 1);
+ updateActiveCamera(*camAlloc);
+ drawAllObjects(gRenderableObjects);
+ }
+}
+
+// Search through sorted and culled objects
+void pick(int screenX, int screenY) {
+ float3 pnt, vec;
+ getCameraRay(gActiveCamera, screenX, screenY, &pnt, &vec);
+
+ for (int i = 0; i < gFrontToBackCount; i ++) {
+ SgRenderable *current = (SgRenderable*)gFrontToBack[i];
+ bool isPicked = intersect(current, pnt, vec);
+ if (isPicked) {
+ current->cullType = CULL_ALWAYS;
+ }
+ }
+
+ for (int i = 0; i < gBackToFrontCount; i ++) {
+ SgRenderable *current = (SgRenderable*)gBackToFront[i];
+ bool isPicked = intersect(current, pnt, vec);
+ if (isPicked) {
+ current->cullType = CULL_ALWAYS;
+ }
+ }
+}
diff --git a/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/scenegraph_objects.rsh b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/scenegraph_objects.rsh
new file mode 100644
index 0000000..511d78b
--- /dev/null
+++ b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/scenegraph_objects.rsh
@@ -0,0 +1,320 @@
+// Copyright (C) 2011-2012 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.scenegraph)
+
+#ifndef _TRANSFORM_DEF_
+#define _TRANSFORM_DEF_
+
+#include "rs_graphics.rsh"
+
+#define TRANSFORM_NONE 0
+#define TRANSFORM_TRANSLATE 1
+#define TRANSFORM_ROTATE 2
+#define TRANSFORM_SCALE 3
+
+#define CULL_FRUSTUM 0
+#define CULL_ALWAYS 2
+
+#define LIGHT_POINT 0
+#define LIGHT_DIRECTIONAL 1
+
+// Shader params that involve only data
+#define SHADER_PARAM_DATA_ONLY 10000
+#define SHADER_PARAM_FLOAT4_DATA 10001
+#define SHADER_PARAM_TRANSFORM_DATA 10002
+#define SHADER_PARAM_TRANSFORM_MODEL 10003
+
+// Shader params that involve camera
+#define SHADER_PARAM_CAMERA 1000
+#define SHADER_PARAM_FLOAT4_CAMERA_POS 1001
+#define SHADER_PARAM_FLOAT4_CAMERA_DIR 1002
+#define SHADER_PARAM_TRANSFORM_VIEW 1003
+#define SHADER_PARAM_TRANSFORM_PROJ 1004
+#define SHADER_PARAM_TRANSFORM_VIEW_PROJ 1005
+#define SHADER_PARAM_TRANSFORM_MODEL_VIEW 1006
+#define SHADER_PARAM_TRANSFORM_MODEL_VIEW_PROJ 1007
+
+// Shader Params that only involve lights
+#define SHADER_PARAM_LIGHT 100
+#define SHADER_PARAM_FLOAT4_LIGHT_COLOR 103
+#define SHADER_PARAM_FLOAT4_LIGHT_POS 104
+#define SHADER_PARAM_FLOAT4_LIGHT_DIR 105
+
+#define SHADER_PARAM_TEXTURE 10
+
+#define TEXTURE_NONE 0
+#define TEXTURE_2D 1
+#define TEXTURE_CUBE 2
+
+typedef struct TransformComponent_s {
+ float4 value;
+ int type;
+ rs_allocation name;
+} SgTransformComponent;
+
+typedef struct __attribute__((packed, aligned(4))) SgTransform {
+ rs_matrix4x4 globalMat;
+ rs_matrix4x4 localMat;
+
+ rs_allocation components;
+ int isDirty;
+
+ rs_allocation children;
+ rs_allocation name;
+
+ // Used to check whether transform params need to be updated
+ uint32_t timestamp;
+} SgTransform;
+
+typedef struct VertexShader_s {
+ rs_program_vertex program;
+ // Buffer with vertex constant data
+ rs_allocation shaderConst;
+ // ShaderParam's that populate data
+ rs_allocation shaderConstParams;
+ // location of the per object constants on the buffer
+ int objectConstIndex;
+} SgVertexShader;
+
+typedef struct FragmentShader_s {
+ rs_program_fragment program;
+ // Buffer with vertex constant data
+ rs_allocation shaderConst;
+ // ShaderParam's that populate data
+ rs_allocation shaderConstParams;
+ // location of the per object constants on the buffer
+ int objectConstIndex;
+} SgFragmentShader;
+
+typedef struct RenderState_s {
+ rs_allocation pv; // VertexShader struct
+ rs_allocation pf; // FragmentShader struct
+ rs_program_store ps;
+ rs_program_raster pr;
+} SgRenderState;
+
+typedef struct Renderable_s {
+ rs_allocation render_state;
+ // Buffer with vertex constant data
+ rs_allocation pv_const;
+ // ShaderParam's that populate data
+ rs_allocation pv_constParams;
+ // Buffer with fragment constant data
+ rs_allocation pf_const;
+ // ShaderParam's that populate data
+ rs_allocation pf_constParams;
+ rs_allocation pf_textures[8];
+ int pf_num_textures;
+ rs_mesh mesh;
+ int meshIndex;
+ rs_allocation transformMatrix;
+ rs_allocation name;
+ float4 boundingSphere;
+ float4 worldBoundingSphere;
+ int bVolInitialized;
+ int cullType; // specifies whether to frustum cull
+ int isVisible;
+} SgRenderable;
+
+typedef struct RenderPass_s {
+ rs_allocation color_target;
+ rs_allocation depth_target;
+ rs_allocation camera;
+ rs_allocation objects;
+
+ float4 clear_color;
+ float clear_depth;
+ bool should_clear_color;
+ bool should_clear_depth;
+} SgRenderPass;
+
+typedef struct Camera_s {
+ rs_matrix4x4 proj;
+ rs_matrix4x4 view;
+ rs_matrix4x4 viewProj;
+ float4 position;
+ float near;
+ float far;
+ float horizontalFOV;
+ float aspect;
+ rs_allocation name;
+ rs_allocation transformMatrix;
+ float4 frustumPlanes[6];
+
+ int isDirty;
+ // Timestamp of the camera itself to signal params if anything changes
+ uint32_t timestamp;
+ // Timestamp of our transform
+ uint32_t transformTimestamp;
+} SgCamera;
+
+typedef struct Light_s {
+ float4 position;
+ float4 color;
+ float intensity;
+ int type;
+ rs_allocation name;
+ rs_allocation transformMatrix;
+} SgLight;
+
+// This represents the shader parameter data needed to set a float or transform data
+typedef struct ShaderParamData_s {
+ int type;
+ float4 float_value;
+ uint32_t timestamp;
+ rs_allocation paramName;
+ rs_allocation camera;
+ rs_allocation light;
+ rs_allocation transform;
+ rs_allocation texture;
+} SgShaderParamData;
+
+// This represents a shader parameter that knows how to update itself for a given
+// renderable or shader and contains a timestamp for the last time this buffer was updated
+typedef struct ShaderParam_s {
+ // Used to check whether transform params need to be updated
+ uint32_t transformTimestamp;
+ // Used to check whether data params need to be updated
+ // These are used when somebody set the matrix of float value directly in java
+ uint32_t dataTimestamp;
+ // Specifies where in the constant buffer data gets written to
+ int bufferOffset;
+ // An instance of SgShaderParamData that could be shared by multiple objects
+ rs_allocation data;
+ // How many components of the vector we need to write
+ int float_vecSize;
+} SgShaderParam;
+
+// This represents a texture object
+typedef struct Texture_s {
+ uint32_t type;
+ rs_allocation texture;
+} SgTexture;
+
+static void printName(rs_allocation name) {
+ if (!rsIsObject(name)) {
+ rsDebug("no name", 0);
+ return;
+ }
+
+ rsDebug((const char*)rsGetElementAt(name, 0), 0);
+}
+
+static void printCameraInfo(const SgCamera *cam) {
+ rsDebug("***** Camera information. ptr:", cam);
+ printName(cam->name);
+ const SgTransform *camTransform = (const SgTransform *)rsGetElementAt(cam->transformMatrix, 0);
+ rsDebug("Transform name:", camTransform);
+ printName(camTransform->name);
+
+ rsDebug("Aspect: ", cam->aspect);
+ rsDebug("Near: ", cam->near);
+ rsDebug("Far: ", cam->far);
+ rsDebug("Fov: ", cam->horizontalFOV);
+ rsDebug("Position: ", cam->position);
+ rsDebug("Proj: ", &cam->proj);
+ rsDebug("View: ", &cam->view);
+}
+
+static void printLightInfo(const SgLight *light) {
+ rsDebug("***** Light information. ptr:", light);
+ printName(light->name);
+ const SgTransform *lTransform = (const SgTransform *)rsGetElementAt(light->transformMatrix, 0);
+ rsDebug("Transform name:", lTransform);
+ printName(lTransform->name);
+
+ rsDebug("Position: ", light->position);
+ rsDebug("Color : ", light->color);
+ rsDebug("Intensity: ", light->intensity);
+ rsDebug("Type: ", light->type);
+}
+
+static void getCameraRay(const SgCamera *cam, int screenX, int screenY, float3 *pnt, float3 *vec) {
+ rsDebug("=================================", screenX);
+ rsDebug("Point X", screenX);
+ rsDebug("Point Y", screenY);
+
+ rs_matrix4x4 mvpInv;
+ rsMatrixLoad(&mvpInv, &cam->viewProj);
+ rsMatrixInverse(&mvpInv);
+
+ float width = (float)rsgGetWidth();
+ float height = (float)rsgGetHeight();
+
+ float4 pos = {(float)screenX, height - (float)screenY, 0.0f, 1.0f};
+
+ pos.x /= width;
+ pos.y /= height;
+
+ rsDebug("Pre Norm X", pos.x);
+ rsDebug("Pre Norm Y", pos.y);
+
+ pos.xy = pos.xy * 2.0f - 1.0f;
+
+ rsDebug("Norm X", pos.x);
+ rsDebug("Norm Y", pos.y);
+
+ pos = rsMatrixMultiply(&mvpInv, pos);
+ float oneOverW = 1.0f / pos.w;
+ pos.xyz *= oneOverW;
+
+ rsDebug("World X", pos.x);
+ rsDebug("World Y", pos.y);
+ rsDebug("World Z", pos.z);
+
+ rsDebug("Cam X", cam->position.x);
+ rsDebug("Cam Y", cam->position.y);
+ rsDebug("Cam Z", cam->position.z);
+
+ *vec = normalize(pos.xyz - cam->position.xyz);
+ rsDebug("Vec X", vec->x);
+ rsDebug("Vec Y", vec->y);
+ rsDebug("Vec Z", vec->z);
+ *pnt = cam->position.xyz;
+}
+
+static bool intersect(const SgRenderable *obj, float3 pnt, float3 vec) {
+ // Solving for t^2 + Bt + C = 0
+ float3 originMinusCenter = pnt - obj->worldBoundingSphere.xyz;
+ float B = dot(originMinusCenter, vec) * 2.0f;
+ float C = dot(originMinusCenter, originMinusCenter) -
+ obj->worldBoundingSphere.w * obj->worldBoundingSphere.w;
+
+ float discriminant = B * B - 4.0f * C;
+ if (discriminant < 0.0f) {
+ return false;
+ }
+ discriminant = sqrt(discriminant);
+
+ float t0 = (-B - discriminant) * 0.5f;
+ float t1 = (-B + discriminant) * 0.5f;
+
+ if (t0 > t1) {
+ float temp = t0;
+ t0 = t1;
+ t1 = temp;
+ }
+
+ // The sphere is behind us
+ if (t1 < 0.0f) {
+ return false;
+ }
+ return true;
+}
+
+
+#endif // _TRANSFORM_DEF_
diff --git a/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/transform.rs b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/transform.rs
new file mode 100644
index 0000000..941b5a8
--- /dev/null
+++ b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/transform.rs
@@ -0,0 +1,127 @@
+// Copyright (C) 2011 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 "scenegraph_objects.rsh"
+
+rs_script gTransformScript;
+
+typedef struct {
+ int changed;
+ rs_matrix4x4 *mat;
+} ParentData;
+
+//#define DEBUG_TRANSFORMS
+static void debugTransform(SgTransform *data, const ParentData *parent) {
+ rsDebug("****** <Transform> ******", (int)data);
+ printName(data->name);
+ rsDebug("isDirty", data->isDirty);
+ rsDebug("parent", (int)parent);
+ rsDebug("child ", rsIsObject(data->children));
+
+ // Refresh matrices if dirty
+ if (data->isDirty && rsIsObject(data->components)) {
+ uint32_t numComponenets = rsAllocationGetDimX(data->components);
+ for (int i = 0; i < numComponenets; i ++) {
+ const SgTransformComponent *comp = NULL;
+ comp = (const SgTransformComponent *)rsGetElementAt(data->components, i);
+
+ if (rsIsObject(comp->name)) {
+ rsDebug((const char*)rsGetElementAt(comp->name, 0), comp->value);
+ rsDebug("Type", comp->type);
+ } else {
+ rsDebug("no name", comp->value);
+ rsDebug("Type", comp->type);
+ }
+ }
+ }
+
+ rsDebug("timestamp", data->timestamp);
+ rsDebug("****** </Transform> ******", (int)data);
+}
+
+static 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 rs_allocation *v_in, rs_allocation *v_out, const void *usrData) {
+
+ SgTransform *data = (SgTransform *)rsGetElementAt(*v_in, 0);
+ const ParentData *parent = (const ParentData *)usrData;
+
+#ifdef DEBUG_TRANSFORMS
+ debugTransform(data, parent);
+#endif //DEBUG_TRANSFORMS
+
+ rs_matrix4x4 *localMat = &data->localMat;
+ rs_matrix4x4 *globalMat = &data->globalMat;
+
+ // Refresh matrices if dirty
+ if (data->isDirty && rsIsObject(data->components)) {
+ bool resetLocal = false;
+ uint32_t numComponenets = rsAllocationGetDimX(data->components);
+ for (int i = 0; i < numComponenets; i ++) {
+ if (!resetLocal) {
+ // Reset our local matrix only for component transforms
+ rsMatrixLoadIdentity(localMat);
+ resetLocal = true;
+ }
+ const SgTransformComponent *comp = NULL;
+ comp = (const SgTransformComponent *)rsGetElementAt(data->components, i);
+ appendTransformation(comp->type, comp->value, localMat);
+ }
+ }
+
+ if (parent) {
+ data->isDirty = (parent->changed || data->isDirty) ? 1 : 0;
+ if (data->isDirty) {
+ rsMatrixLoad(globalMat, parent->mat);
+ rsMatrixMultiply(globalMat, localMat);
+ }
+ } else if (data->isDirty) {
+ rsMatrixLoad(globalMat, localMat);
+ }
+
+ ParentData toChild;
+ toChild.changed = 0;
+ toChild.mat = globalMat;
+
+ if (data->isDirty) {
+ toChild.changed = 1;
+ data->timestamp ++;
+ }
+
+ if (rsIsObject(data->children)) {
+ rs_allocation nullAlloc;
+ rsForEach(gTransformScript, data->children, nullAlloc, &toChild, sizeof(toChild));
+ }
+
+ data->isDirty = 0;
+}
diff --git a/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/vertex_params.rs b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/vertex_params.rs
new file mode 100644
index 0000000..88955a8
--- /dev/null
+++ b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/vertex_params.rs
@@ -0,0 +1,29 @@
+// Copyright (C) 2012 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.scenegraph)
+
+#include "scenegraph_objects.rsh"
+
+//#define DEBUG_PARAMS
+
+#include "params.rsh"
+
+void root(rs_allocation *v_out, const void *usrData) {
+ SgVertexShader *shader = (SgVertexShader *)rsGetElementAt(*v_out, 0);
+ const SgCamera *camera = (const SgCamera*)usrData;
+ processAllParams(shader->shaderConst, shader->shaderConstParams, camera);
+}
diff --git a/tests/RenderScriptTests/SceneGraph/src/com/android/testapp/FileSelector.java b/tests/RenderScriptTests/SceneGraph/src/com/android/testapp/FileSelector.java
new file mode 100644
index 0000000..420e133
--- /dev/null
+++ b/tests/RenderScriptTests/SceneGraph/src/com/android/testapp/FileSelector.java
@@ -0,0 +1,110 @@
+/*
+ * Copyright (C) 2011 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.testapp;
+
+import java.io.File;
+import java.io.FileFilter;
+import java.util.ArrayList;
+import java.util.List;
+
+import android.app.ListActivity;
+import android.content.Intent;
+import android.net.Uri;
+import android.os.Bundle;
+import android.view.View;
+import android.widget.ArrayAdapter;
+import android.widget.ListView;
+
+/**
+ * A list view where the last item the user clicked is placed in
+ * the "activated" state, causing its background to highlight.
+ */
+public class FileSelector extends ListActivity {
+
+ File[] mCurrentSubList;
+ File mCurrentFile;
+
+ class DAEFilter implements FileFilter {
+ public boolean accept(File file) {
+ if (file.isDirectory()) {
+ return true;
+ }
+ return file.getName().endsWith(".dae");
+ }
+ }
+
+ private void populateList(File file) {
+
+ mCurrentFile = file;
+ setTitle(mCurrentFile.getAbsolutePath() + "/*.dae");
+ List<String> names = new ArrayList<String>();
+ names.add("..");
+
+ mCurrentSubList = mCurrentFile.listFiles(new DAEFilter());
+
+ if (mCurrentSubList != null) {
+ for (int i = 0; i < mCurrentSubList.length; i ++) {
+ String fileName = mCurrentSubList[i].getName();
+ if (mCurrentSubList[i].isDirectory()) {
+ fileName = "/" + fileName;
+ }
+ names.add(fileName);
+ }
+ }
+
+ // Use the built-in layout for showing a list item with a single
+ // line of text whose background is changes when activated.
+ setListAdapter(new ArrayAdapter<String>(this,
+ android.R.layout.simple_list_item_activated_1, names));
+ getListView().setTextFilterEnabled(true);
+
+ // Tell the list view to show one checked/activated item at a time.
+ getListView().setChoiceMode(ListView.CHOICE_MODE_SINGLE);
+ }
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+
+ populateList(new File("/sdcard/"));
+ }
+
+ @Override
+ protected void onListItemClick(ListView l, View v, int position, long id) {
+ if (position == 0) {
+ File parent = mCurrentFile.getParentFile();
+ if (parent == null) {
+ return;
+ }
+ populateList(parent);
+ return;
+ }
+
+ // the first thing in list is parent directory
+ File selectedFile = mCurrentSubList[position - 1];
+ if (selectedFile.isDirectory()) {
+ populateList(selectedFile);
+ return;
+ }
+
+ Intent resultIntent = new Intent();
+ resultIntent.setData(Uri.fromFile(selectedFile));
+ setResult(RESULT_OK, resultIntent);
+ finish();
+ }
+
+}
diff --git a/tests/RenderScriptTests/SceneGraph/src/com/android/testapp/FullscreenBlur.java b/tests/RenderScriptTests/SceneGraph/src/com/android/testapp/FullscreenBlur.java
new file mode 100644
index 0000000..2299b72
--- /dev/null
+++ b/tests/RenderScriptTests/SceneGraph/src/com/android/testapp/FullscreenBlur.java
@@ -0,0 +1,187 @@
+/*
+ * Copyright (C) 2011 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.testapp;
+
+import java.util.ArrayList;
+
+import com.android.scenegraph.*;
+
+import android.content.res.Resources;
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
+import android.os.AsyncTask;
+import android.renderscript.*;
+import android.renderscript.Allocation.MipmapControl;
+import android.renderscript.Element.Builder;
+import android.renderscript.Font.Style;
+import android.renderscript.Program.TextureType;
+import android.renderscript.ProgramStore.DepthFunc;
+import android.util.Log;
+
+class FullscreenBlur {
+
+ static Allocation sRenderTargetBlur0Color;
+ static Allocation sRenderTargetBlur0Depth;
+ static Allocation sRenderTargetBlur1Color;
+ static Allocation sRenderTargetBlur1Depth;
+ static Allocation sRenderTargetBlur2Color;
+ static Allocation sRenderTargetBlur2Depth;
+
+ static FragmentShader mPF_BlurH;
+ static FragmentShader mPF_BlurV;
+ static FragmentShader mPF_SelectColor;
+ static FragmentShader mPF_Texture;
+ static VertexShader mPV_Paint;
+ static VertexShader mPV_Blur;
+
+ // This is only used when full screen blur is enabled
+ // Basically, it's the offscreen render targets
+ static void createRenderTargets(RenderScriptGL rs, int w, int h) {
+ Type.Builder b = new Type.Builder(rs, Element.RGBA_8888(rs));
+ Type renderType = b.setX(w/8).setY(h/8).create();
+ int usage = Allocation.USAGE_GRAPHICS_TEXTURE | Allocation.USAGE_GRAPHICS_RENDER_TARGET;
+ sRenderTargetBlur0Color = Allocation.createTyped(rs, renderType, usage);
+ sRenderTargetBlur1Color = Allocation.createTyped(rs, renderType, usage);
+ sRenderTargetBlur2Color = Allocation.createTyped(rs, renderType, usage);
+
+ b = new Type.Builder(rs, Element.createPixel(rs, Element.DataType.UNSIGNED_16,
+ Element.DataKind.PIXEL_DEPTH));
+ renderType = b.setX(w/8).setY(h/8).create();
+ usage = Allocation.USAGE_GRAPHICS_RENDER_TARGET;
+ sRenderTargetBlur0Depth = Allocation.createTyped(rs, renderType, usage);
+ sRenderTargetBlur1Depth = Allocation.createTyped(rs, renderType, usage);
+ sRenderTargetBlur2Depth = Allocation.createTyped(rs, renderType, usage);
+ }
+
+ static void addOffsets(Renderable quad, float advance) {
+ quad.appendSourceParams(new Float4Param("blurOffset0", - advance * 2.5f));
+ quad.appendSourceParams(new Float4Param("blurOffset1", - advance * 0.5f));
+ quad.appendSourceParams(new Float4Param("blurOffset2", advance * 1.5f));
+ quad.appendSourceParams(new Float4Param("blurOffset3", advance * 3.5f));
+ }
+
+ static RenderPass addPass(Scene scene, Allocation color, Allocation depth) {
+ RenderPass pass = new RenderPass();
+ pass.setColorTarget(color);
+ pass.setDepthTarget(depth);
+ pass.setShouldClearColor(false);
+ pass.setShouldClearDepth(false);
+ pass.setCamera(scene.getCameras().get(1));
+ scene.appendRenderPass(pass);
+ return pass;
+ }
+
+ static void addBlurPasses(Scene scene, RenderScriptGL rs) {
+ SceneManager sceneManager = SceneManager.getInstance();
+ ArrayList<RenderableBase> allDraw = scene.getRenderables();
+ int numDraw = allDraw.size();
+
+ ProgramRaster cullNone = ProgramRaster.CULL_NONE(rs);
+ ProgramStore blendAdd = SceneManager.BLEND_ADD_DEPTH_NONE(rs);
+ ProgramStore blendNone = ProgramStore.BLEND_NONE_DEPTH_NONE(rs);
+
+ RenderState drawTex = new RenderState(mPV_Blur, mPF_Texture, blendAdd, cullNone);
+ RenderState selectCol = new RenderState(mPV_Blur, mPF_SelectColor, blendNone, cullNone);
+ RenderState hBlur = new RenderState(mPV_Blur, mPF_BlurH, blendNone, cullNone);
+ RenderState vBlur = new RenderState(mPV_Blur, mPF_BlurV, blendNone, cullNone);
+
+ // Renders the scene off screen
+ RenderPass blurSourcePass = addPass(scene,
+ sRenderTargetBlur0Color,
+ sRenderTargetBlur0Depth);
+ blurSourcePass.setClearColor(new Float4(1.0f, 1.0f, 1.0f, 1.0f));
+ blurSourcePass.setShouldClearColor(true);
+ blurSourcePass.setClearDepth(1.0f);
+ blurSourcePass.setShouldClearDepth(true);
+ for (int i = 0; i < numDraw; i ++) {
+ blurSourcePass.appendRenderable((Renderable)allDraw.get(i));
+ }
+
+ // Pass for selecting bright colors
+ RenderPass selectColorPass = addPass(scene,
+ sRenderTargetBlur2Color,
+ sRenderTargetBlur2Depth);
+ Renderable quad = sceneManager.getRenderableQuad("ScreenAlignedQuadS", selectCol);
+ quad.appendSourceParams(new TextureParam("tex0", new Texture2D(sRenderTargetBlur0Color)));
+ selectColorPass.appendRenderable(quad);
+
+ // Horizontal blur
+ RenderPass horizontalBlurPass = addPass(scene,
+ sRenderTargetBlur1Color,
+ sRenderTargetBlur1Depth);
+ quad = sceneManager.getRenderableQuad("ScreenAlignedQuadH", hBlur);
+ quad.appendSourceParams(new TextureParam("tex0", new Texture2D(sRenderTargetBlur2Color)));
+ addOffsets(quad, 1.0f / (float)sRenderTargetBlur0Color.getType().getX());
+ horizontalBlurPass.appendRenderable(quad);
+
+ // Vertical Blur
+ RenderPass verticalBlurPass = addPass(scene,
+ sRenderTargetBlur2Color,
+ sRenderTargetBlur2Depth);
+ quad = sceneManager.getRenderableQuad("ScreenAlignedQuadV", vBlur);
+ quad.appendSourceParams(new TextureParam("tex0", new Texture2D(sRenderTargetBlur1Color)));
+ addOffsets(quad, 1.0f / (float)sRenderTargetBlur0Color.getType().getY());
+ verticalBlurPass.appendRenderable(quad);
+ }
+
+ // Additively renders the blurred colors on top of the scene
+ static void addCompositePass(Scene scene, RenderScriptGL rs) {
+ SceneManager sceneManager = SceneManager.getInstance();
+ RenderState drawTex = new RenderState(mPV_Blur, mPF_Texture,
+ SceneManager.BLEND_ADD_DEPTH_NONE(rs),
+ ProgramRaster.CULL_NONE(rs));
+
+ RenderPass compositePass = addPass(scene, null, null);
+ Renderable quad = sceneManager.getRenderableQuad("ScreenAlignedQuad", drawTex);
+ quad.appendSourceParams(new TextureParam("tex0", new Texture2D(sRenderTargetBlur2Color)));
+ compositePass.appendRenderable(quad);
+ }
+
+ static private FragmentShader getShader(Resources res, RenderScriptGL rs,
+ int resID, Type constants) {
+ FragmentShader.Builder fb = new FragmentShader.Builder(rs);
+ fb.setShader(res, resID);
+ fb.addTexture(TextureType.TEXTURE_2D, "color");
+ if (constants != null) {
+ fb.setObjectConst(constants);
+ }
+ FragmentShader prog = fb.create();
+ prog.getProgram().bindSampler(Sampler.CLAMP_LINEAR(rs), 0);
+ return prog;
+ }
+
+ static void initShaders(Resources res, RenderScriptGL rs) {
+ ScriptField_BlurOffsets blurConst = new ScriptField_BlurOffsets(rs, 1);
+ VertexShader.Builder vb = new VertexShader.Builder(rs);
+ vb.addInput(ScriptField_VertexShaderInputs.createElement(rs));
+ vb.setShader(res, R.raw.blur_vertex);
+ mPV_Blur = vb.create();
+
+ mPF_Texture = getShader(res, rs, R.raw.texture, null);
+ mPF_Texture.getProgram().bindSampler(Sampler.WRAP_LINEAR_MIP_LINEAR(rs), 0);
+ mPF_BlurH = getShader(res, rs, R.raw.blur_h, blurConst.getAllocation().getType());
+ mPF_BlurV = getShader(res, rs, R.raw.blur_v, blurConst.getAllocation().getType());
+ mPF_SelectColor = getShader(res, rs, R.raw.select_color, null);
+ }
+
+}
+
+
+
+
+
diff --git a/tests/RenderScriptTests/SceneGraph/src/com/android/testapp/TestApp.java b/tests/RenderScriptTests/SceneGraph/src/com/android/testapp/TestApp.java
new file mode 100644
index 0000000..385a7ab
--- /dev/null
+++ b/tests/RenderScriptTests/SceneGraph/src/com/android/testapp/TestApp.java
@@ -0,0 +1,115 @@
+/*
+ * Copyright (C) 2011 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.testapp;
+
+import android.renderscript.RSSurfaceView;
+import android.renderscript.RenderScript;
+
+import android.app.Activity;
+import android.content.res.Configuration;
+import android.content.Intent;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.Looper;
+import android.os.Message;
+import android.provider.Settings.System;
+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 android.view.MenuInflater;
+import android.view.Window;
+import android.net.Uri;
+
+import java.lang.Runtime;
+
+public class TestApp extends Activity {
+
+ private TestAppView 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 TestAppView(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.resume();
+ }
+
+ @Override
+ protected void onPause() {
+ // Ideally a game should implement onResume() and onPause()
+ // to take appropriate action when the activity looses focus
+ super.onPause();
+ mView.pause();
+ }
+
+ @Override
+ public boolean onCreateOptionsMenu(Menu menu) {
+ MenuInflater inflater = getMenuInflater();
+ inflater.inflate(R.menu.loader_menu, menu);
+ return true;
+ }
+
+ @Override
+ public boolean onOptionsItemSelected(MenuItem item) {
+ // Handle item selection
+ switch (item.getItemId()) {
+ case R.id.load_model:
+ loadModel();
+ return true;
+ case R.id.use_blur:
+ mView.mRender.toggleBlur();
+ return true;
+ default:
+ return super.onOptionsItemSelected(item);
+ }
+ }
+
+ private static final int FIND_DAE_MODEL = 10;
+ public void onActivityResult(int requestCode, int resultCode, Intent data) {
+ if (resultCode == RESULT_OK) {
+ if (requestCode == FIND_DAE_MODEL) {
+ Uri selectedImageUri = data.getData();
+ Log.e("Selected Path: ", selectedImageUri.getPath());
+ mView.mRender.loadModel(selectedImageUri.getPath());
+ }
+ }
+ }
+
+ public void loadModel() {
+ Intent intent = new Intent();
+ intent.setAction(Intent.ACTION_PICK);
+ intent.setClassName("com.android.testapp",
+ "com.android.testapp.FileSelector");
+ startActivityForResult(intent, FIND_DAE_MODEL);
+ }
+
+}
+
diff --git a/tests/RenderScriptTests/SceneGraph/src/com/android/testapp/TestAppLoadingScreen.java b/tests/RenderScriptTests/SceneGraph/src/com/android/testapp/TestAppLoadingScreen.java
new file mode 100644
index 0000000..60616cc
--- /dev/null
+++ b/tests/RenderScriptTests/SceneGraph/src/com/android/testapp/TestAppLoadingScreen.java
@@ -0,0 +1,113 @@
+/*
+ * Copyright (C) 2012 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.testapp;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Vector;
+
+import android.content.res.Resources;
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
+import android.os.AsyncTask;
+import android.renderscript.*;
+import android.renderscript.Allocation.MipmapControl;
+import android.renderscript.Element.Builder;
+import android.renderscript.Font.Style;
+import android.renderscript.Program.TextureType;
+import android.renderscript.ProgramStore.DepthFunc;
+import android.util.Log;
+
+// This is where the scenegraph and the rendered objects are initialized and used
+public class TestAppLoadingScreen {
+
+ private static String TAG = "TestAppLoadingScreen";
+
+ private Resources mRes;
+ private RenderScriptGL mRS;
+ private ScriptC_test_app mScript;
+
+ public TestAppLoadingScreen(RenderScriptGL rs, Resources res) {
+ mRS = rs;
+ mRes = res;
+ // Shows the loading screen with some text
+ renderLoading();
+ // Adds a little 3D bugdroid model to the laoding screen asynchronously.
+ new LoadingScreenLoaderTask().execute();
+ }
+
+ public void showLoadingScreen(boolean show) {
+ mScript.set_gInitialized(!show);
+ }
+
+ // The loading screen has some elements that shouldn't be loaded on the UI thread
+ private class LoadingScreenLoaderTask extends AsyncTask<String, Void, Boolean> {
+ Allocation robotTex;
+ Mesh robotMesh;
+ protected Boolean doInBackground(String... names) {
+ long start = System.currentTimeMillis();
+ robotTex = Allocation.createFromBitmapResource(mRS, mRes, R.drawable.robot,
+ MipmapControl.MIPMAP_ON_SYNC_TO_TEXTURE,
+ Allocation.USAGE_GRAPHICS_TEXTURE);
+
+ FileA3D model = FileA3D.createFromResource(mRS, mRes, R.raw.robot);
+ FileA3D.IndexEntry entry = model.getIndexEntry(0);
+ if (entry != null && entry.getEntryType() == FileA3D.EntryType.MESH) {
+ robotMesh = entry.getMesh();
+ }
+
+ mScript.set_gPFSBackground(ProgramStore.BLEND_NONE_DEPTH_TEST(mRS));
+
+ ProgramFragmentFixedFunction.Builder b = new ProgramFragmentFixedFunction.Builder(mRS);
+ b.setTexture(ProgramFragmentFixedFunction.Builder.EnvMode.REPLACE,
+ ProgramFragmentFixedFunction.Builder.Format.RGBA, 0);
+ ProgramFragment pfDefault = b.create();
+ pfDefault.bindSampler(Sampler.CLAMP_LINEAR(mRS), 0);
+ mScript.set_gPFBackground(pfDefault);
+
+ ProgramVertexFixedFunction.Builder pvb = new ProgramVertexFixedFunction.Builder(mRS);
+ ProgramVertexFixedFunction pvDefault = pvb.create();
+ ProgramVertexFixedFunction.Constants va = new ProgramVertexFixedFunction.Constants(mRS);
+ ((ProgramVertexFixedFunction)pvDefault).bindConstants(va);
+ mScript.set_gPVBackground(pvDefault);
+
+ long end = System.currentTimeMillis();
+ Log.v("TIMER", "Loading load time: " + (end - start));
+ return new Boolean(true);
+ }
+
+ protected void onPostExecute(Boolean result) {
+ mScript.set_gRobotTex(robotTex);
+ mScript.set_gRobotMesh(robotMesh);
+ }
+ }
+
+ // Creates a simple script to show a loding screen until everything is initialized
+ // Could also be used to do some custom renderscript work before handing things over
+ // to the scenegraph
+ void renderLoading() {
+ mScript = new ScriptC_test_app(mRS, mRes, R.raw.test_app);
+ mRS.bindRootScript(mScript);
+ }
+
+ public void setRenderLoop(ScriptC renderLoop) {
+ mScript.set_gRenderLoop(renderLoop);
+ Allocation dummyAlloc = Allocation.createSized(mRS, Element.I32(mRS), 1);
+ mScript.set_gDummyAlloc(dummyAlloc);
+ }
+}
diff --git a/tests/RenderScriptTests/SceneGraph/src/com/android/testapp/TestAppRS.java b/tests/RenderScriptTests/SceneGraph/src/com/android/testapp/TestAppRS.java
new file mode 100644
index 0000000..2757398
--- /dev/null
+++ b/tests/RenderScriptTests/SceneGraph/src/com/android/testapp/TestAppRS.java
@@ -0,0 +1,267 @@
+/*
+ * Copyright (C) 2011-2012 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.testapp;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Vector;
+
+import com.android.scenegraph.*;
+import com.android.scenegraph.SceneManager.SceneLoadedCallback;
+
+import android.content.res.Resources;
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
+import android.os.AsyncTask;
+import android.renderscript.*;
+import android.renderscript.Program.TextureType;
+import android.util.Log;
+
+// This is where the scenegraph and the rendered objects are initialized and used
+public class TestAppRS {
+
+ private static String modelName = "orientation_test.dae";
+ private static String TAG = "TestAppRS";
+ private static String mFilePath = "";
+
+ int mWidth;
+ int mHeight;
+
+ boolean mUseBlur;
+
+ TestAppLoadingScreen mLoadingScreen;
+
+ // Used to asynchronously load scene elements like meshes and transform hierarchies
+ SceneLoadedCallback mLoadedCallback = new SceneLoadedCallback() {
+ public void run() {
+ prepareToRender(mLoadedScene);
+ }
+ };
+
+ // Top level class that initializes all the elements needed to use the scene graph
+ SceneManager mSceneManager;
+
+ // Used to move the camera around in the 3D world
+ TouchHandler mTouchHandler;
+
+ private Resources mRes;
+ private RenderScriptGL mRS;
+
+ // Shaders
+ private FragmentShader mPaintF;
+ private FragmentShader mLightsF;
+ private FragmentShader mAluminumF;
+ private FragmentShader mPlasticF;
+ private FragmentShader mDiffuseF;
+ private FragmentShader mTextureF;
+ private VertexShader mGenericV;
+
+ Scene mActiveScene;
+
+ // This is a part of the test app, it's used to tests multiple render passes and is toggled
+ // on and off in the menu, off by default
+ void toggleBlur() {
+ mUseBlur = !mUseBlur;
+
+ mActiveScene.clearRenderPasses();
+ initRenderPasses();
+ mActiveScene.initRenderPassRS(mRS, mSceneManager);
+
+ // This is just a hardcoded object in the scene that gets turned on and off for the demo
+ // to make things look a bit better. This could be deleted in the cleanup
+ Renderable plane = (Renderable)mActiveScene.getRenderableByName("pPlaneShape1");
+ if (plane != null) {
+ plane.setVisible(!mUseBlur);
+ }
+ }
+
+ public void init(RenderScriptGL rs, Resources res, int width, int height) {
+ mUseBlur = false;
+ mRS = rs;
+ mRes = res;
+ mWidth = width;
+ mHeight = height;
+
+ mTouchHandler = new TouchHandler();
+
+ mSceneManager = SceneManager.getInstance();
+ // Initializes all the RS specific scenegraph elements
+ mSceneManager.initRS(mRS, mRes, mWidth, mHeight);
+
+ mLoadingScreen = new TestAppLoadingScreen(mRS, mRes);
+
+ // Initi renderscript stuff specific to the app. This will need to be abstracted out later.
+ FullscreenBlur.createRenderTargets(mRS, mWidth, mHeight);
+ initPaintShaders();
+ mLoadingScreen.setRenderLoop(mSceneManager.getRenderLoop());
+
+ // Load a scene to render
+ mSceneManager.loadModel(mFilePath + modelName, mLoadedCallback);
+ }
+
+ // When a new model file is selected from the UI, this function gets called to init everything
+ void loadModel(String path) {
+ mLoadingScreen.showLoadingScreen(true);
+ mActiveScene.destroyRS();
+ mSceneManager.loadModel(path, mLoadedCallback);
+ }
+
+ public void onActionDown(float x, float y) {
+ mTouchHandler.onActionDown(x, y);
+ }
+
+ public void onActionScale(float scale) {
+ mTouchHandler.onActionScale(scale);
+ }
+
+ public void onActionMove(float x, float y) {
+ mTouchHandler.onActionMove(x, y);
+ }
+
+ FragmentShader createFromResource(int id, boolean addCubemap, Type constType) {
+ FragmentShader.Builder fb = new FragmentShader.Builder(mRS);
+ fb.setShaderConst(constType);
+ fb.setShader(mRes, id);
+ fb.addTexture(TextureType.TEXTURE_2D, "diffuse");
+ if (addCubemap) {
+ fb.addShaderTexture(TextureType.TEXTURE_CUBE, "reflection");
+ }
+ FragmentShader pf = fb.create();
+ pf.getProgram().bindSampler(Sampler.WRAP_LINEAR_MIP_LINEAR(mRS), 0);
+ if (addCubemap) {
+ pf.getProgram().bindSampler(Sampler.CLAMP_LINEAR_MIP_LINEAR(mRS), 1);
+ }
+ return pf;
+ }
+
+ private void initPaintShaders() {
+ ScriptField_ModelParams objConst = new ScriptField_ModelParams(mRS, 1);
+ ScriptField_ViewProjParams shaderConst = new ScriptField_ViewProjParams(mRS, 1);
+
+ VertexShader.Builder vb = new VertexShader.Builder(mRS);
+ vb.addInput(ScriptField_VertexShaderInputs.createElement(mRS));
+ vb.setShader(mRes, R.raw.shader2v);
+ vb.setObjectConst(objConst.getAllocation().getType());
+ vb.setShaderConst(shaderConst.getAllocation().getType());
+ mGenericV = vb.create();
+
+ ScriptField_CameraParams fsConst = new ScriptField_CameraParams(mRS, 1);
+ ScriptField_LightParams fsConst2 = new ScriptField_LightParams(mRS, 1);
+
+ mPaintF = createFromResource(R.raw.paintf, true, fsConst.getAllocation().getType());
+ // Assign a reflection map
+ TextureCube envCube = new TextureCube("sdcard/scenegraph/", "cube_env.png");
+ mPaintF.appendSourceParams(new TextureParam("reflection", envCube));
+
+ mAluminumF = createFromResource(R.raw.metal, true, fsConst.getAllocation().getType());
+ TextureCube diffCube = new TextureCube("sdcard/scenegraph/", "cube_spec.png");
+ mAluminumF.appendSourceParams(new TextureParam("reflection", diffCube));
+
+ mPlasticF = createFromResource(R.raw.plastic, false, fsConst.getAllocation().getType());
+ mDiffuseF = createFromResource(R.raw.diffuse, false, fsConst.getAllocation().getType());
+ mTextureF = createFromResource(R.raw.texture, false, fsConst.getAllocation().getType());
+
+ FragmentShader.Builder fb = new FragmentShader.Builder(mRS);
+ fb.setObjectConst(fsConst2.getAllocation().getType());
+ fb.setShader(mRes, R.raw.plastic_lights);
+ mLightsF = fb.create();
+
+ FullscreenBlur.initShaders(mRes, mRS);
+ }
+
+ void initRenderPasses() {
+ ArrayList<RenderableBase> allDraw = mActiveScene.getRenderables();
+ int numDraw = allDraw.size();
+
+ if (mUseBlur) {
+ FullscreenBlur.addBlurPasses(mActiveScene, mRS);
+ }
+
+ RenderPass mainPass = new RenderPass();
+ mainPass.setClearColor(new Float4(1.0f, 1.0f, 1.0f, 1.0f));
+ mainPass.setShouldClearColor(true);
+ mainPass.setClearDepth(1.0f);
+ mainPass.setShouldClearDepth(true);
+ mainPass.setCamera(mActiveScene.getCameras().get(1));
+ for (int i = 0; i < numDraw; i ++) {
+ mainPass.appendRenderable((Renderable)allDraw.get(i));
+ }
+ mActiveScene.appendRenderPass(mainPass);
+
+ if (mUseBlur) {
+ FullscreenBlur.addCompositePass(mActiveScene, mRS);
+ }
+ }
+
+ private void addShadersToScene() {
+ mActiveScene.appendShader(mPaintF);
+ mActiveScene.appendShader(mLightsF);
+ mActiveScene.appendShader(mAluminumF);
+ mActiveScene.appendShader(mPlasticF);
+ mActiveScene.appendShader(mDiffuseF);
+ mActiveScene.appendShader(mTextureF);
+ mActiveScene.appendShader(mGenericV);
+ }
+
+ public void prepareToRender(Scene s) {
+ mSceneManager.setActiveScene(s);
+ mActiveScene = s;
+ addShadersToScene();
+ RenderState plastic = new RenderState(mGenericV, mPlasticF, null, null);
+ RenderState diffuse = new RenderState(mGenericV, mDiffuseF, null, null);
+ RenderState paint = new RenderState(mGenericV, mPaintF, null, null);
+ RenderState aluminum = new RenderState(mGenericV, mAluminumF, null, null);
+ RenderState lights = new RenderState(mGenericV, mLightsF, null, null);
+ RenderState glassTransp = new RenderState(mGenericV, mPaintF,
+ ProgramStore.BLEND_ALPHA_DEPTH_TEST(mRS), null);
+
+ initRenderPasses();
+
+ mActiveScene.assignRenderState(plastic);
+
+ mActiveScene.assignRenderStateToMaterial(diffuse, "lambert2$");
+
+ mActiveScene.assignRenderStateToMaterial(paint, "^Paint");
+ mActiveScene.assignRenderStateToMaterial(paint, "^Carbon");
+ mActiveScene.assignRenderStateToMaterial(paint, "^Glass");
+ mActiveScene.assignRenderStateToMaterial(paint, "^MainGlass");
+
+ mActiveScene.assignRenderStateToMaterial(aluminum, "^Metal");
+ mActiveScene.assignRenderStateToMaterial(aluminum, "^Brake");
+
+ mActiveScene.assignRenderStateToMaterial(glassTransp, "^GlassLight");
+
+ mActiveScene.assignRenderStateToMaterial(lights, "^LightBlinn");
+
+ Renderable plane = (Renderable)mActiveScene.getRenderableByName("pPlaneShape1");
+ if (plane != null) {
+ RenderState texState = new RenderState(mGenericV, mTextureF, null, null);
+ plane.setRenderState(texState);
+ plane.setVisible(!mUseBlur);
+ }
+
+ mTouchHandler.init(mActiveScene);
+
+ long start = System.currentTimeMillis();
+ mActiveScene.initRS(mRS, mRes, mSceneManager);
+ long end = System.currentTimeMillis();
+ Log.v("TIMER", "Scene init time: " + (end - start));
+
+ mLoadingScreen.showLoadingScreen(false);
+ }
+}
diff --git a/tests/RenderScriptTests/SceneGraph/src/com/android/testapp/TestAppView.java b/tests/RenderScriptTests/SceneGraph/src/com/android/testapp/TestAppView.java
new file mode 100644
index 0000000..687f35b
--- /dev/null
+++ b/tests/RenderScriptTests/SceneGraph/src/com/android/testapp/TestAppView.java
@@ -0,0 +1,152 @@
+/*
+ * Copyright (C) 2011 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.testapp;
+
+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;
+import android.view.ScaleGestureDetector;
+
+public class TestAppView extends RSSurfaceView {
+
+ public TestAppView(Context context) {
+ super(context);
+ mScaleDetector = new ScaleGestureDetector(context, new ScaleListener());
+ }
+
+ private RenderScriptGL mRS;
+ TestAppRS mRender;
+
+ private ScaleGestureDetector mScaleDetector;
+ private static final int INVALID_POINTER_ID = -1;
+ private int mActivePointerId = INVALID_POINTER_ID;
+
+ public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
+ super.surfaceChanged(holder, format, w, h);
+ if (mRS == null) {
+ RenderScriptGL.SurfaceConfig sc = new RenderScriptGL.SurfaceConfig();
+ sc.setDepth(16, 24);
+ mRS = createRenderScriptGL(sc);
+ mRS.setSurface(holder, w, h);
+ mRender = new TestAppRS();
+ mRender.init(mRS, getResources(), w, h);
+ }
+ }
+
+ @Override
+ protected void onDetachedFromWindow() {
+ if (mRS != null) {
+ mRender = null;
+ mRS = null;
+ destroyRenderScriptGL();
+ }
+ }
+
+ @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) {
+ mScaleDetector.onTouchEvent(ev);
+
+ boolean ret = false;
+ float x = ev.getX();
+ float y = ev.getY();
+
+ final int action = ev.getAction();
+
+ switch (action & MotionEvent.ACTION_MASK) {
+ case MotionEvent.ACTION_DOWN: {
+ mRender.onActionDown(x, y);
+ mActivePointerId = ev.getPointerId(0);
+ ret = true;
+ break;
+ }
+ case MotionEvent.ACTION_MOVE: {
+ if (!mScaleDetector.isInProgress()) {
+ mRender.onActionMove(x, y);
+ }
+ mRender.onActionDown(x, y);
+ ret = true;
+ break;
+ }
+
+ case MotionEvent.ACTION_UP: {
+ mActivePointerId = INVALID_POINTER_ID;
+ break;
+ }
+
+ case MotionEvent.ACTION_CANCEL: {
+ mActivePointerId = INVALID_POINTER_ID;
+ break;
+ }
+
+ case MotionEvent.ACTION_POINTER_UP: {
+ final int pointerIndex = (ev.getAction() & MotionEvent.ACTION_POINTER_INDEX_MASK)
+ >> MotionEvent.ACTION_POINTER_INDEX_SHIFT;
+ final int pointerId = ev.getPointerId(pointerIndex);
+ if (pointerId == mActivePointerId) {
+ // This was our active pointer going up. Choose a new
+ // active pointer and adjust accordingly.
+ final int newPointerIndex = pointerIndex == 0 ? 1 : 0;
+ x = ev.getX(newPointerIndex);
+ y = ev.getY(newPointerIndex);
+ mRender.onActionDown(x, y);
+ mActivePointerId = ev.getPointerId(newPointerIndex);
+ }
+ break;
+ }
+ }
+
+ return ret;
+ }
+
+ private class ScaleListener extends ScaleGestureDetector.SimpleOnScaleGestureListener {
+ @Override
+ public boolean onScale(ScaleGestureDetector detector) {
+ mRender.onActionScale(detector.getScaleFactor());
+ return true;
+ }
+ }
+}
+
+
diff --git a/tests/RenderScriptTests/SceneGraph/src/com/android/testapp/TouchHandler.java b/tests/RenderScriptTests/SceneGraph/src/com/android/testapp/TouchHandler.java
new file mode 100644
index 0000000..5dcc9f8
--- /dev/null
+++ b/tests/RenderScriptTests/SceneGraph/src/com/android/testapp/TouchHandler.java
@@ -0,0 +1,94 @@
+/*
+ * Copyright (C) 2011 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.testapp;
+
+import android.util.Log;
+import android.renderscript.Float3;
+import com.android.scenegraph.*;
+import com.android.scenegraph.CompoundTransform.RotateComponent;
+import com.android.scenegraph.CompoundTransform.TranslateComponent;
+
+public class TouchHandler {
+ private static String TAG = "TouchHandler";
+
+ float mLastX;
+ float mLastY;
+
+ RotateComponent mRotateX;
+ float mRotateXValue;
+ RotateComponent mRotateY;
+ float mRotateYValue;
+ TranslateComponent mDist;
+ Float3 mDistValue;
+
+ public void init(Scene scene) {
+ CompoundTransform cameraRotate = (CompoundTransform)scene.getTransformByName("CameraAim");
+ CompoundTransform cameraDist = (CompoundTransform)scene.getTransformByName("CameraDist");
+
+ if (cameraRotate != null && cameraDist != null) {
+ mRotateX = (RotateComponent)cameraRotate.mTransformComponents.get(2);
+ mRotateXValue = mRotateX.getAngle();
+ mRotateY = (RotateComponent)cameraRotate.mTransformComponents.get(1);
+ mRotateYValue = mRotateY.getAngle();
+ mDist = (TranslateComponent)cameraDist.mTransformComponents.get(0);
+ mDistValue = mDist.getValue();
+ }
+ }
+
+ public void onActionDown(float x, float y) {
+ mLastX = x;
+ mLastY = y;
+ }
+
+ public void onActionScale(float scale) {
+ if (mDist == null) {
+ return;
+ }
+ mDistValue.z *= 1.0f / scale;
+ mDistValue.z = Math.max(20.0f, Math.min(mDistValue.z, 100.0f));
+ mDist.setValue(mDistValue);
+ }
+
+ public void onActionMove(float x, float y) {
+ if (mRotateX == null) {
+ return;
+ }
+
+ float dx = mLastX - x;
+ float dy = mLastY - y;
+
+ if (Math.abs(dy) <= 2.0f) {
+ dy = 0.0f;
+ }
+ if (Math.abs(dx) <= 2.0f) {
+ dx = 0.0f;
+ }
+
+ mRotateYValue += dx * 0.25f;
+ mRotateYValue %= 360.0f;
+
+ mRotateXValue += dy * 0.25f;
+ mRotateXValue = Math.max(mRotateXValue , -80.0f);
+ mRotateXValue = Math.min(mRotateXValue , 0.0f);
+
+ mRotateX.setAngle(mRotateXValue);
+ mRotateY.setAngle(mRotateYValue);
+
+ mLastX = x;
+ mLastY = y;
+ }
+}
diff --git a/tests/RenderScriptTests/SceneGraph/src/com/android/testapp/test_app.rs b/tests/RenderScriptTests/SceneGraph/src/com/android/testapp/test_app.rs
new file mode 100644
index 0000000..e4dcc39
--- /dev/null
+++ b/tests/RenderScriptTests/SceneGraph/src/com/android/testapp/test_app.rs
@@ -0,0 +1,98 @@
+// Copyright (C) 2011 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.testapp)
+
+#include "rs_graphics.rsh"
+#include "test_app.rsh"
+
+// Making sure these get reflected
+FBlurOffsets *blurExport;
+VShaderInputs *iExport;
+FShaderParams *fConst;
+FShaderLightParams *fConts2;
+VSParams *vConst2;
+VObjectParams *vConst3;
+
+rs_program_vertex gPVBackground;
+rs_program_fragment gPFBackground;
+
+rs_allocation gRobotTex;
+rs_mesh gRobotMesh;
+
+rs_program_store gPFSBackground;
+
+rs_allocation gDummyAlloc;
+rs_script gRenderLoop;
+
+bool gInitialized = false;
+
+float gRotate;
+
+void init() {
+ gRotate = 0.0f;
+}
+
+static int pos = 50;
+static float gRotateY = 120.0f;
+static float3 gLookAt = 0;
+static float gZoom = 50.0f;
+static void displayLoading() {
+ if (rsIsObject(gRobotTex) && rsIsObject(gRobotMesh)) {
+ rsgBindProgramVertex(gPVBackground);
+ rs_matrix4x4 proj;
+ float aspect = (float)rsgGetWidth() / (float)rsgGetHeight();
+ rsMatrixLoadPerspective(&proj, 30.0f, aspect, 1.0f, 100.0f);
+ rsgProgramVertexLoadProjectionMatrix(&proj);
+
+ rsgBindProgramFragment(gPFBackground);
+ rsgBindProgramStore(gPFSBackground);
+ rsgBindTexture(gPFBackground, 0, gRobotTex);
+
+ rs_matrix4x4 matrix;
+ rsMatrixLoadIdentity(&matrix);
+ // Position our models on the screen
+ gRotateY += rsGetDt()*100;
+ rsMatrixTranslate(&matrix, 0, 0, -gZoom);
+ rsMatrixRotate(&matrix, 20.0f, 1.0f, 0.0f, 0.0f);
+ rsMatrixRotate(&matrix, gRotateY, 0.0f, 1.0f, 0.0f);
+ rsMatrixScale(&matrix, 0.2f, 0.2f, 0.2f);
+ rsgProgramVertexLoadModelMatrix(&matrix);
+ rsgDrawMesh(gRobotMesh);
+ }
+
+ uint width = rsgGetWidth();
+ uint height = rsgGetHeight();
+ int left = 0, right = 0, top = 0, bottom = 0;
+ const char* text = "Initializing...";
+ rsgMeasureText(text, &left, &right, &top, &bottom);
+ int centeredPos = width / 2 - (right - left) / 2;
+ rsgDrawText(text, centeredPos, height / 2 + height / 10);
+}
+
+int root(void) {
+ rs_allocation nullAlloc;
+ if (!gInitialized) {
+ rsgClearColor(1.0f, 1.0f, 1.0f, 1.0f);
+ rsgClearDepth(1.0f);
+ displayLoading();
+ return 30;
+ }
+
+ rsForEach(gRenderLoop, gDummyAlloc, nullAlloc);
+
+ return 10;
+}
diff --git a/tests/RenderScriptTests/SceneGraph/src/com/android/testapp/test_app.rsh b/tests/RenderScriptTests/SceneGraph/src/com/android/testapp/test_app.rsh
new file mode 100644
index 0000000..5fbcbb2
--- /dev/null
+++ b/tests/RenderScriptTests/SceneGraph/src/com/android/testapp/test_app.rsh
@@ -0,0 +1,52 @@
+// Copyright (C) 2012 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.testapp)
+
+// Helpers
+typedef struct ViewProjParams {
+ rs_matrix4x4 viewProj;
+} VSParams;
+
+typedef struct ModelParams {
+ rs_matrix4x4 model;
+} VObjectParams;
+
+typedef struct CameraParams {
+ float4 cameraPos;
+} FShaderParams;
+
+typedef struct LightParams {
+ float4 lightPos_0;
+ float4 lightColor_0;
+ float4 lightPos_1;
+ float4 lightColor_1;
+ float4 cameraPos;
+ float4 diffuse;
+} FShaderLightParams;
+
+typedef struct BlurOffsets {
+ float blurOffset0;
+ float blurOffset1;
+ float blurOffset2;
+ float blurOffset3;
+} FBlurOffsets;
+
+typedef struct VertexShaderInputs {
+ float4 position;
+ float3 normal;
+ float2 texture0;
+} VShaderInputs;
diff --git a/tests/RenderScriptTests/tests/src/com/android/rs/test/RSTestCore.java b/tests/RenderScriptTests/tests/src/com/android/rs/test/RSTestCore.java
index 2293678..81f773ca 100644
--- a/tests/RenderScriptTests/tests/src/com/android/rs/test/RSTestCore.java
+++ b/tests/RenderScriptTests/tests/src/com/android/rs/test/RSTestCore.java
@@ -64,6 +64,11 @@
unitTests = new ArrayList<UnitTest>();
+ unitTests.add(new UT_mesh(this, mRes, mCtx));
+ unitTests.add(new UT_element(this, mRes, mCtx));
+ unitTests.add(new UT_sampler(this, mRes, mCtx));
+ unitTests.add(new UT_program_store(this, mRes, mCtx));
+ unitTests.add(new UT_program_raster(this, mRes, mCtx));
unitTests.add(new UT_primitives(this, mRes, mCtx));
unitTests.add(new UT_constant(this, mRes, mCtx));
unitTests.add(new UT_vector(this, mRes, mCtx));
diff --git a/tests/RenderScriptTests/tests/src/com/android/rs/test/UT_element.java b/tests/RenderScriptTests/tests/src/com/android/rs/test/UT_element.java
new file mode 100644
index 0000000..3e2a2ca
--- /dev/null
+++ b/tests/RenderScriptTests/tests/src/com/android/rs/test/UT_element.java
@@ -0,0 +1,132 @@
+/*
+ * Copyright (C) 2011 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.Context;
+import android.content.res.Resources;
+import android.renderscript.*;
+import android.renderscript.Element.*;
+import android.renderscript.Element.DataKind.*;
+import android.renderscript.Element.DataType.*;
+
+public class UT_element extends UnitTest {
+ private Resources mRes;
+
+ Element simpleElem;
+ Element complexElem;
+
+ final String subElemNames[] = {
+ "subElem0",
+ "subElem1",
+ "subElem2",
+ "arrayElem0",
+ "arrayElem1",
+ "subElem3",
+ "subElem4",
+ "subElem5",
+ "subElem6",
+ "subElem_7",
+ };
+
+ final int subElemArraySizes[] = {
+ 1,
+ 1,
+ 1,
+ 2,
+ 5,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ };
+
+ final int subElemOffsets[] = {
+ 0,
+ 4,
+ 8,
+ 12,
+ 20,
+ 40,
+ 44,
+ 48,
+ 64,
+ 80,
+ };
+
+ protected UT_element(RSTestCore rstc, Resources res, Context ctx) {
+ super(rstc, "Element", ctx);
+ mRes = res;
+ }
+
+ private void initializeGlobals(RenderScript RS, ScriptC_element s) {
+ simpleElem = Element.F32_3(RS);
+ complexElem = ScriptField_ComplexStruct.createElement(RS);
+ s.set_simpleElem(simpleElem);
+ s.set_complexElem(complexElem);
+
+ ScriptField_ComplexStruct data = new ScriptField_ComplexStruct(RS, 1);
+ s.bind_complexStruct(data);
+ }
+
+ private void testScriptSide(RenderScript pRS) {
+ ScriptC_element s = new ScriptC_element(pRS, mRes, R.raw.element);
+ pRS.setMessageHandler(mRsMessage);
+ initializeGlobals(pRS, s);
+ s.invoke_element_test();
+ pRS.finish();
+ waitForMessage();
+ }
+
+ private void testJavaSide(RenderScript RS) {
+
+ int subElemCount = simpleElem.getSubElementCount();
+ _RS_ASSERT("subElemCount == 0", subElemCount == 0);
+ _RS_ASSERT("simpleElem.getDataKind() == USER",
+ simpleElem.getDataKind() == DataKind.USER);
+ _RS_ASSERT("simpleElem.getDataType() == FLOAT_32",
+ simpleElem.getDataType() == DataType.FLOAT_32);
+
+ subElemCount = complexElem.getSubElementCount();
+ _RS_ASSERT("subElemCount == 10", subElemCount == 10);
+ _RS_ASSERT("complexElem.getDataKind() == USER",
+ complexElem.getDataKind() == DataKind.USER);
+ _RS_ASSERT("complexElemsimpleElem.getDataType() == NONE",
+ complexElem.getDataType() == DataType.NONE);
+ _RS_ASSERT("complexElem.getSizeBytes() == ScriptField_ComplexStruct.Item.sizeof",
+ complexElem.getSizeBytes() == ScriptField_ComplexStruct.Item.sizeof);
+
+ for (int i = 0; i < subElemCount; i ++) {
+ _RS_ASSERT("complexElem.getSubElement(i) != null",
+ complexElem.getSubElement(i) != null);
+ _RS_ASSERT("complexElem.getSubElementName(i).equals(subElemNames[i])",
+ complexElem.getSubElementName(i).equals(subElemNames[i]));
+ _RS_ASSERT("complexElem.getSubElementArraySize(i) == subElemArraySizes[i]",
+ complexElem.getSubElementArraySize(i) == subElemArraySizes[i]);
+ _RS_ASSERT("complexElem.getSubElementOffsetBytes(i) == subElemOffsets[i]",
+ complexElem.getSubElementOffsetBytes(i) == subElemOffsets[i]);
+ }
+ }
+
+ public void run() {
+ RenderScript pRS = RenderScript.create(mCtx);
+ testScriptSide(pRS);
+ testJavaSide(pRS);
+ passTest();
+ pRS.destroy();
+ }
+}
diff --git a/tests/RenderScriptTests/tests/src/com/android/rs/test/UT_mesh.java b/tests/RenderScriptTests/tests/src/com/android/rs/test/UT_mesh.java
new file mode 100644
index 0000000..0c93702
--- /dev/null
+++ b/tests/RenderScriptTests/tests/src/com/android/rs/test/UT_mesh.java
@@ -0,0 +1,75 @@
+/*
+ * Copyright (C) 2011 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.Context;
+import android.content.res.Resources;
+import android.renderscript.*;
+import android.renderscript.Mesh.*;
+
+public class UT_mesh extends UnitTest {
+ private Resources mRes;
+
+ Mesh mesh;
+
+ protected UT_mesh(RSTestCore rstc, Resources res, Context ctx) {
+ super(rstc, "Mesh", ctx);
+ mRes = res;
+ }
+
+ private void initializeGlobals(RenderScript RS, ScriptC_mesh s) {
+ Allocation vAlloc0 = Allocation.createSized(RS, Element.F32(RS), 10);
+ Allocation vAlloc1 = Allocation.createSized(RS, Element.F32_2(RS), 10);
+
+ Allocation iAlloc0 = Allocation.createSized(RS, Element.I16(RS), 10);
+ Allocation iAlloc2 = Allocation.createSized(RS, Element.I16(RS), 10);
+
+ Mesh.AllocationBuilder mBuilder = new Mesh.AllocationBuilder(RS);
+ mBuilder.addVertexAllocation(vAlloc0);
+ mBuilder.addVertexAllocation(vAlloc1);
+
+ mBuilder.addIndexSetAllocation(iAlloc0, Primitive.POINT);
+ mBuilder.addIndexSetType(Primitive.LINE);
+ mBuilder.addIndexSetAllocation(iAlloc2, Primitive.TRIANGLE);
+
+ s.set_mesh(mBuilder.create());
+ s.set_vertexAlloc0(vAlloc0);
+ s.set_vertexAlloc1(vAlloc1);
+ s.set_indexAlloc0(iAlloc0);
+ s.set_indexAlloc2(iAlloc2);
+ }
+
+ private void testScriptSide(RenderScript pRS) {
+ ScriptC_mesh s = new ScriptC_mesh(pRS, mRes, R.raw.mesh);
+ pRS.setMessageHandler(mRsMessage);
+ initializeGlobals(pRS, s);
+ s.invoke_mesh_test();
+ pRS.finish();
+ waitForMessage();
+ }
+
+ private void testJavaSide(RenderScript RS) {
+ }
+
+ public void run() {
+ RenderScript pRS = RenderScript.create(mCtx);
+ testScriptSide(pRS);
+ testJavaSide(pRS);
+ passTest();
+ pRS.destroy();
+ }
+}
diff --git a/tests/RenderScriptTests/tests/src/com/android/rs/test/UT_program_raster.java b/tests/RenderScriptTests/tests/src/com/android/rs/test/UT_program_raster.java
new file mode 100644
index 0000000..1de4d71
--- /dev/null
+++ b/tests/RenderScriptTests/tests/src/com/android/rs/test/UT_program_raster.java
@@ -0,0 +1,81 @@
+/*
+ * Copyright (C) 2011 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.Context;
+import android.content.res.Resources;
+import android.renderscript.*;
+import android.renderscript.ProgramRaster;
+import android.renderscript.ProgramRaster.CullMode;
+
+public class UT_program_raster extends UnitTest {
+ private Resources mRes;
+
+ ProgramRaster pointSpriteEnabled;
+ ProgramRaster cullMode;
+
+ protected UT_program_raster(RSTestCore rstc, Resources res, Context ctx) {
+ super(rstc, "ProgramRaster", ctx);
+ mRes = res;
+ }
+
+ private ProgramRaster.Builder getDefaultBuilder(RenderScript RS) {
+ ProgramRaster.Builder b = new ProgramRaster.Builder(RS);
+ b.setCullMode(CullMode.BACK);
+ b.setPointSpriteEnabled(false);
+ return b;
+ }
+
+ private void initializeGlobals(RenderScript RS, ScriptC_program_raster s) {
+ ProgramRaster.Builder b = getDefaultBuilder(RS);
+ pointSpriteEnabled = b.setPointSpriteEnabled(true).create();
+ b = getDefaultBuilder(RS);
+ cullMode = b.setCullMode(CullMode.FRONT).create();
+
+ s.set_pointSpriteEnabled(pointSpriteEnabled);
+ s.set_cullMode(cullMode);
+ }
+
+ private void testScriptSide(RenderScript pRS) {
+ ScriptC_program_raster s = new ScriptC_program_raster(pRS, mRes, R.raw.program_raster);
+ pRS.setMessageHandler(mRsMessage);
+ initializeGlobals(pRS, s);
+ s.invoke_program_raster_test();
+ pRS.finish();
+ waitForMessage();
+ }
+
+ private void testJavaSide(RenderScript RS) {
+ _RS_ASSERT("pointSpriteEnabled.getPointSpriteEnabled() == true",
+ pointSpriteEnabled.getPointSpriteEnabled() == true);
+ _RS_ASSERT("pointSpriteEnabled.getCullMode() == ProgramRaster.CullMode.BACK",
+ pointSpriteEnabled.getCullMode() == ProgramRaster.CullMode.BACK);
+
+ _RS_ASSERT("cullMode.getPointSpriteEnabled() == false",
+ cullMode.getPointSpriteEnabled() == false);
+ _RS_ASSERT("cullMode.getCullMode() == ProgramRaster.CullMode.FRONT",
+ cullMode.getCullMode() == ProgramRaster.CullMode.FRONT);
+ }
+
+ public void run() {
+ RenderScript pRS = RenderScript.create(mCtx);
+ testScriptSide(pRS);
+ testJavaSide(pRS);
+ passTest();
+ pRS.destroy();
+ }
+}
diff --git a/tests/RenderScriptTests/tests/src/com/android/rs/test/UT_program_store.java b/tests/RenderScriptTests/tests/src/com/android/rs/test/UT_program_store.java
new file mode 100644
index 0000000..72a401d
--- /dev/null
+++ b/tests/RenderScriptTests/tests/src/com/android/rs/test/UT_program_store.java
@@ -0,0 +1,175 @@
+/*
+ * Copyright (C) 2011 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.Context;
+import android.content.res.Resources;
+import android.renderscript.*;
+import android.renderscript.ProgramStore.BlendDstFunc;
+import android.renderscript.ProgramStore.BlendSrcFunc;
+import android.renderscript.ProgramStore.Builder;
+import android.renderscript.ProgramStore.DepthFunc;
+
+public class UT_program_store extends UnitTest {
+ private Resources mRes;
+
+ ProgramStore ditherEnable;
+ ProgramStore colorRWriteEnable;
+ ProgramStore colorGWriteEnable;
+ ProgramStore colorBWriteEnable;
+ ProgramStore colorAWriteEnable;
+ ProgramStore blendSrc;
+ ProgramStore blendDst;
+ ProgramStore depthWriteEnable;
+ ProgramStore depthFunc;
+
+ protected UT_program_store(RSTestCore rstc, Resources res, Context ctx) {
+ super(rstc, "ProgramStore", ctx);
+ mRes = res;
+ }
+
+ private ProgramStore.Builder getDefaultBuilder(RenderScript RS) {
+ ProgramStore.Builder b = new ProgramStore.Builder(RS);
+ b.setBlendFunc(ProgramStore.BlendSrcFunc.ZERO, ProgramStore.BlendDstFunc.ZERO);
+ b.setColorMaskEnabled(false, false, false, false);
+ b.setDepthFunc(ProgramStore.DepthFunc.ALWAYS);
+ b.setDepthMaskEnabled(false);
+ b.setDitherEnabled(false);
+ return b;
+ }
+
+ private void initializeGlobals(RenderScript RS, ScriptC_program_store s) {
+ ProgramStore.Builder b = getDefaultBuilder(RS);
+ ditherEnable = b.setDitherEnabled(true).create();
+
+ b = getDefaultBuilder(RS);
+ colorRWriteEnable = b.setColorMaskEnabled(true, false, false, false).create();
+
+ b = getDefaultBuilder(RS);
+ colorGWriteEnable = b.setColorMaskEnabled(false, true, false, false).create();
+
+ b = getDefaultBuilder(RS);
+ colorBWriteEnable = b.setColorMaskEnabled(false, false, true, false).create();
+
+ b = getDefaultBuilder(RS);
+ colorAWriteEnable = b.setColorMaskEnabled(false, false, false, true).create();
+
+ b = getDefaultBuilder(RS);
+ blendSrc = b.setBlendFunc(ProgramStore.BlendSrcFunc.DST_COLOR,
+ ProgramStore.BlendDstFunc.ZERO).create();
+
+ b = getDefaultBuilder(RS);
+ blendDst = b.setBlendFunc(ProgramStore.BlendSrcFunc.ZERO,
+ ProgramStore.BlendDstFunc.DST_ALPHA).create();
+
+ b = getDefaultBuilder(RS);
+ depthWriteEnable = b.setDepthMaskEnabled(true).create();
+
+ b = getDefaultBuilder(RS);
+ depthFunc = b.setDepthFunc(ProgramStore.DepthFunc.GREATER).create();
+
+ s.set_ditherEnable(ditherEnable);
+ s.set_colorRWriteEnable(colorRWriteEnable);
+ s.set_colorGWriteEnable(colorGWriteEnable);
+ s.set_colorBWriteEnable(colorBWriteEnable);
+ s.set_colorAWriteEnable(colorAWriteEnable);
+ s.set_blendSrc(blendSrc);
+ s.set_blendDst(blendDst);
+ s.set_depthWriteEnable(depthWriteEnable);
+ s.set_depthFunc(depthFunc);
+ }
+
+ private void testScriptSide(RenderScript pRS) {
+ ScriptC_program_store s = new ScriptC_program_store(pRS, mRes, R.raw.program_store);
+ pRS.setMessageHandler(mRsMessage);
+ initializeGlobals(pRS, s);
+ s.invoke_program_store_test();
+ pRS.finish();
+ waitForMessage();
+ }
+
+ void checkObject(ProgramStore ps,
+ boolean depthMask,
+ DepthFunc df,
+ BlendSrcFunc bsf,
+ BlendDstFunc bdf,
+ boolean R,
+ boolean G,
+ boolean B,
+ boolean A,
+ boolean dither) {
+ _RS_ASSERT("ps.getDepthMaskEnabled() == depthMask", ps.getDepthMaskEnabled() == depthMask);
+ _RS_ASSERT("ps.getDepthFunc() == df", ps.getDepthFunc() == df);
+ _RS_ASSERT("ps.getBlendSrcFunc() == bsf", ps.getBlendSrcFunc() == bsf);
+ _RS_ASSERT("ps.getBlendDstFunc() == bdf", ps.getBlendDstFunc() == bdf);
+ _RS_ASSERT("ps.getColorMaskREnabled() == R", ps.getColorMaskREnabled() == R);
+ _RS_ASSERT("ps.getColorMaskGEnabled() == G", ps.getColorMaskGEnabled() == G);
+ _RS_ASSERT("ps.getColorMaskBEnabled() == B", ps.getColorMaskBEnabled() == B);
+ _RS_ASSERT("ps.getColorMaskAEnabled() == A", ps.getColorMaskAEnabled() == A);
+ _RS_ASSERT("ps.getDitherEnabled() == dither", ps.getDitherEnabled() == dither);
+ }
+
+ void varyBuilderColorAndDither(ProgramStore.Builder pb,
+ boolean depthMask,
+ DepthFunc df,
+ BlendSrcFunc bsf,
+ BlendDstFunc bdf) {
+ for (int r = 0; r <= 1; r++) {
+ boolean isR = (r == 1);
+ for (int g = 0; g <= 1; g++) {
+ boolean isG = (g == 1);
+ for (int b = 0; b <= 1; b++) {
+ boolean isB = (b == 1);
+ for (int a = 0; a <= 1; a++) {
+ boolean isA = (a == 1);
+ for (int dither = 0; dither <= 1; dither++) {
+ boolean isDither = (dither == 1);
+ pb.setDitherEnabled(isDither);
+ pb.setColorMaskEnabled(isR, isG, isB, isA);
+ ProgramStore ps = pb.create();
+ checkObject(ps, depthMask, df, bsf, bdf, isR, isG, isB, isA, isDither);
+ }
+ }
+ }
+ }
+ }
+ }
+
+ public void testJavaSide(RenderScript RS) {
+ for (int depth = 0; depth <= 1; depth++) {
+ boolean depthMask = (depth == 1);
+ for (DepthFunc df : DepthFunc.values()) {
+ for (BlendSrcFunc bsf : BlendSrcFunc.values()) {
+ for (BlendDstFunc bdf : BlendDstFunc.values()) {
+ ProgramStore.Builder b = new ProgramStore.Builder(RS);
+ b.setDepthFunc(df);
+ b.setDepthMaskEnabled(depthMask);
+ b.setBlendFunc(bsf, bdf);
+ varyBuilderColorAndDither(b, depthMask, df, bsf, bdf);
+ }
+ }
+ }
+ }
+ }
+
+ public void run() {
+ RenderScript pRS = RenderScript.create(mCtx);
+ testJavaSide(pRS);
+ testScriptSide(pRS);
+ pRS.destroy();
+ }
+}
diff --git a/tests/RenderScriptTests/tests/src/com/android/rs/test/UT_sampler.java b/tests/RenderScriptTests/tests/src/com/android/rs/test/UT_sampler.java
new file mode 100644
index 0000000..c328cf6
--- /dev/null
+++ b/tests/RenderScriptTests/tests/src/com/android/rs/test/UT_sampler.java
@@ -0,0 +1,150 @@
+/*
+ * Copyright (C) 2011 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.Context;
+import android.content.res.Resources;
+import android.renderscript.*;
+import android.renderscript.Sampler;
+import android.renderscript.Sampler.Value;
+
+public class UT_sampler extends UnitTest {
+ private Resources mRes;
+
+ Sampler minification;
+ Sampler magnification;
+ Sampler wrapS;
+ Sampler wrapT;
+ Sampler anisotropy;
+
+ protected UT_sampler(RSTestCore rstc, Resources res, Context ctx) {
+ super(rstc, "Sampler", ctx);
+ mRes = res;
+ }
+
+ private Sampler.Builder getDefaultBuilder(RenderScript RS) {
+ Sampler.Builder b = new Sampler.Builder(RS);
+ b.setMinification(Value.NEAREST);
+ b.setMagnification(Value.NEAREST);
+ b.setWrapS(Value.CLAMP);
+ b.setWrapT(Value.CLAMP);
+ b.setAnisotropy(1.0f);
+ return b;
+ }
+
+ private void initializeGlobals(RenderScript RS, ScriptC_sampler s) {
+ Sampler.Builder b = getDefaultBuilder(RS);
+ b.setMinification(Value.LINEAR_MIP_LINEAR);
+ minification = b.create();
+
+ b = getDefaultBuilder(RS);
+ b.setMagnification(Value.LINEAR);
+ magnification = b.create();
+
+ b = getDefaultBuilder(RS);
+ b.setWrapS(Value.WRAP);
+ wrapS = b.create();
+
+ b = getDefaultBuilder(RS);
+ b.setWrapT(Value.WRAP);
+ wrapT = b.create();
+
+ b = getDefaultBuilder(RS);
+ b.setAnisotropy(8.0f);
+ anisotropy = b.create();
+
+ s.set_minification(minification);
+ s.set_magnification(magnification);
+ s.set_wrapS(wrapS);
+ s.set_wrapT(wrapT);
+ s.set_anisotropy(anisotropy);
+ }
+
+ private void testScriptSide(RenderScript pRS) {
+ ScriptC_sampler s = new ScriptC_sampler(pRS, mRes, R.raw.sampler);
+ pRS.setMessageHandler(mRsMessage);
+ initializeGlobals(pRS, s);
+ s.invoke_sampler_test();
+ pRS.finish();
+ waitForMessage();
+ }
+
+ private void testJavaSide(RenderScript RS) {
+ _RS_ASSERT("minification.getMagnification() == Sampler.Value.NEAREST",
+ minification.getMagnification() == Sampler.Value.NEAREST);
+ _RS_ASSERT("minification.getMinification() == Sampler.Value.LINEAR_MIP_LINEAR",
+ minification.getMinification() == Sampler.Value.LINEAR_MIP_LINEAR);
+ _RS_ASSERT("minification.getWrapS() == Sampler.Value.CLAMP",
+ minification.getWrapS() == Sampler.Value.CLAMP);
+ _RS_ASSERT("minification.getWrapT() == Sampler.Value.CLAMP",
+ minification.getWrapT() == Sampler.Value.CLAMP);
+ _RS_ASSERT("minification.getAnisotropy() == 1.0f",
+ minification.getAnisotropy() == 1.0f);
+
+ _RS_ASSERT("magnification.getMagnification() == Sampler.Value.LINEAR",
+ magnification.getMagnification() == Sampler.Value.LINEAR);
+ _RS_ASSERT("magnification.getMinification() == Sampler.Value.NEAREST",
+ magnification.getMinification() == Sampler.Value.NEAREST);
+ _RS_ASSERT("magnification.getWrapS() == Sampler.Value.CLAMP",
+ magnification.getWrapS() == Sampler.Value.CLAMP);
+ _RS_ASSERT("magnification.getWrapT() == Sampler.Value.CLAMP",
+ magnification.getWrapT() == Sampler.Value.CLAMP);
+ _RS_ASSERT("magnification.getAnisotropy() == 1.0f",
+ magnification.getAnisotropy() == 1.0f);
+
+ _RS_ASSERT("wrapS.getMagnification() == Sampler.Value.NEAREST",
+ wrapS.getMagnification() == Sampler.Value.NEAREST);
+ _RS_ASSERT("wrapS.getMinification() == Sampler.Value.NEAREST",
+ wrapS.getMinification() == Sampler.Value.NEAREST);
+ _RS_ASSERT("wrapS.getWrapS() == Sampler.Value.WRAP",
+ wrapS.getWrapS() == Sampler.Value.WRAP);
+ _RS_ASSERT("wrapS.getWrapT() == Sampler.Value.CLAMP",
+ wrapS.getWrapT() == Sampler.Value.CLAMP);
+ _RS_ASSERT("wrapS.getAnisotropy() == 1.0f",
+ wrapS.getAnisotropy() == 1.0f);
+
+ _RS_ASSERT("wrapT.getMagnification() == Sampler.Value.NEAREST",
+ wrapT.getMagnification() == Sampler.Value.NEAREST);
+ _RS_ASSERT("wrapT.getMinification() == Sampler.Value.NEAREST",
+ wrapT.getMinification() == Sampler.Value.NEAREST);
+ _RS_ASSERT("wrapT.getWrapS() == Sampler.Value.CLAMP",
+ wrapT.getWrapS() == Sampler.Value.CLAMP);
+ _RS_ASSERT("wrapT.getWrapT() == Sampler.Value.WRAP",
+ wrapT.getWrapT() == Sampler.Value.WRAP);
+ _RS_ASSERT("wrapT.getAnisotropy() == 1.0f",
+ wrapT.getAnisotropy() == 1.0f);
+
+ _RS_ASSERT("anisotropy.getMagnification() == Sampler.Value.NEAREST",
+ anisotropy.getMagnification() == Sampler.Value.NEAREST);
+ _RS_ASSERT("anisotropy.getMinification() == Sampler.Value.NEAREST",
+ anisotropy.getMinification() == Sampler.Value.NEAREST);
+ _RS_ASSERT("anisotropy.getWrapS() == Sampler.Value.CLAMP",
+ anisotropy.getWrapS() == Sampler.Value.CLAMP);
+ _RS_ASSERT("anisotropy.getWrapT() == Sampler.Value.CLAMP",
+ anisotropy.getWrapT() == Sampler.Value.CLAMP);
+ _RS_ASSERT("anisotropy.getAnisotropy() == 1.0f",
+ anisotropy.getAnisotropy() == 8.0f);
+ }
+
+ public void run() {
+ RenderScript pRS = RenderScript.create(mCtx);
+ testScriptSide(pRS);
+ testJavaSide(pRS);
+ passTest();
+ pRS.destroy();
+ }
+}
diff --git a/tests/RenderScriptTests/tests/src/com/android/rs/test/UnitTest.java b/tests/RenderScriptTests/tests/src/com/android/rs/test/UnitTest.java
index edff83f..fbac124 100644
--- a/tests/RenderScriptTests/tests/src/com/android/rs/test/UnitTest.java
+++ b/tests/RenderScriptTests/tests/src/com/android/rs/test/UnitTest.java
@@ -58,8 +58,8 @@
protected void _RS_ASSERT(String message, boolean b) {
if(b == false) {
- result = -1;
Log.e(name, message + " FAILED");
+ failTest();
}
}
diff --git a/tests/RenderScriptTests/tests/src/com/android/rs/test/element.rs b/tests/RenderScriptTests/tests/src/com/android/rs/test/element.rs
new file mode 100644
index 0000000..0c42d84
--- /dev/null
+++ b/tests/RenderScriptTests/tests/src/com/android/rs/test/element.rs
@@ -0,0 +1,158 @@
+#include "shared.rsh"
+#include "rs_graphics.rsh"
+
+rs_element simpleElem;
+rs_element complexElem;
+typedef struct ComplexStruct {
+ float subElem0;
+ float subElem1;
+ int subElem2;
+ float arrayElem0[2];
+ int arrayElem1[5];
+ char subElem3;
+ float subElem4;
+ float2 subElem5;
+ float3 subElem6;
+ float4 subElem_7;
+} ComplexStruct_t;
+
+ComplexStruct_t *complexStruct;
+
+static const char *subElemNames[] = {
+ "subElem0",
+ "subElem1",
+ "subElem2",
+ "arrayElem0",
+ "arrayElem1",
+ "subElem3",
+ "subElem4",
+ "subElem5",
+ "subElem6",
+ "subElem_7",
+};
+
+static uint32_t subElemNamesSizes[] = {
+ 8,
+ 8,
+ 8,
+ 10,
+ 10,
+ 8,
+ 8,
+ 8,
+ 8,
+ 9,
+};
+
+static uint32_t subElemArraySizes[] = {
+ 1,
+ 1,
+ 1,
+ 2,
+ 5,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+};
+
+static void resetStruct() {
+ uint8_t *bytePtr = (uint8_t*)complexStruct;
+ uint32_t sizeOfStruct = sizeof(*complexStruct);
+ for(uint32_t i = 0; i < sizeOfStruct; i ++) {
+ bytePtr[i] = 0;
+ }
+}
+
+static bool equals(const char *name0, const char * name1, uint32_t len) {
+ for (uint32_t i = 0; i < len; i ++) {
+ if (name0[i] != name1[i]) {
+ return false;
+ }
+ }
+ return true;
+}
+
+static bool test_element_getters() {
+ bool failed = false;
+
+ uint32_t subElemOffsets[10];
+ uint32_t index = 0;
+ subElemOffsets[index++] = (uint32_t)&complexStruct->subElem0 - (uint32_t)complexStruct;
+ subElemOffsets[index++] = (uint32_t)&complexStruct->subElem1 - (uint32_t)complexStruct;
+ subElemOffsets[index++] = (uint32_t)&complexStruct->subElem2 - (uint32_t)complexStruct;
+ subElemOffsets[index++] = (uint32_t)&complexStruct->arrayElem0 - (uint32_t)complexStruct;
+ subElemOffsets[index++] = (uint32_t)&complexStruct->arrayElem1 - (uint32_t)complexStruct;
+ subElemOffsets[index++] = (uint32_t)&complexStruct->subElem3 - (uint32_t)complexStruct;
+ subElemOffsets[index++] = (uint32_t)&complexStruct->subElem4 - (uint32_t)complexStruct;
+ subElemOffsets[index++] = (uint32_t)&complexStruct->subElem5 - (uint32_t)complexStruct;
+ subElemOffsets[index++] = (uint32_t)&complexStruct->subElem6 - (uint32_t)complexStruct;
+ subElemOffsets[index++] = (uint32_t)&complexStruct->subElem_7 - (uint32_t)complexStruct;
+
+ uint32_t subElemCount = rsElementGetSubElementCount(simpleElem);
+ _RS_ASSERT(subElemCount == 0);
+ _RS_ASSERT(rsElementGetDataKind(simpleElem) == RS_KIND_USER);
+ _RS_ASSERT(rsElementGetDataType(simpleElem) == RS_TYPE_FLOAT_32);
+ _RS_ASSERT(rsElementGetVectorSize(simpleElem) == 3);
+
+ subElemCount = rsElementGetSubElementCount(complexElem);
+ _RS_ASSERT(subElemCount == 10);
+ _RS_ASSERT(rsElementGetDataKind(complexElem) == RS_KIND_USER);
+ _RS_ASSERT(rsElementGetDataType(complexElem) == RS_TYPE_NONE);
+ _RS_ASSERT(rsElementGetVectorSize(complexElem) == 1);
+ _RS_ASSERT(rsElementGetSizeBytes(complexElem) == sizeof(*complexStruct));
+
+ char buffer[64];
+ for (uint32_t i = 0; i < subElemCount; i ++) {
+ rs_element subElem = rsElementGetSubElement(complexElem, i);
+ _RS_ASSERT(rsIsObject(subElem));
+
+ _RS_ASSERT(rsElementGetSubElementNameLength(complexElem, i) == subElemNamesSizes[i] + 1);
+
+ uint32_t written = rsElementGetSubElementName(complexElem, i, buffer, 64);
+ _RS_ASSERT(written == subElemNamesSizes[i]);
+ _RS_ASSERT(equals(buffer, subElemNames[i], written));
+
+ _RS_ASSERT(rsElementGetSubElementArraySize(complexElem, i) == subElemArraySizes[i]);
+ _RS_ASSERT(rsElementGetSubElementOffsetBytes(complexElem, i) == subElemOffsets[i]);
+ }
+
+ // Tests error checking
+ rs_element subElem = rsElementGetSubElement(complexElem, subElemCount);
+ _RS_ASSERT(!rsIsObject(subElem));
+
+ _RS_ASSERT(rsElementGetSubElementNameLength(complexElem, subElemCount) == 0);
+
+ _RS_ASSERT(rsElementGetSubElementName(complexElem, subElemCount, buffer, 64) == 0);
+ _RS_ASSERT(rsElementGetSubElementName(complexElem, 0, NULL, 64) == 0);
+ _RS_ASSERT(rsElementGetSubElementName(complexElem, 0, buffer, 0) == 0);
+ uint32_t written = rsElementGetSubElementName(complexElem, 0, buffer, 5);
+ _RS_ASSERT(written == 4);
+ _RS_ASSERT(buffer[4] == '\0');
+
+ _RS_ASSERT(rsElementGetSubElementArraySize(complexElem, subElemCount) == 0);
+ _RS_ASSERT(rsElementGetSubElementOffsetBytes(complexElem, subElemCount) == 0);
+
+ if (failed) {
+ rsDebug("test_element_getters FAILED", 0);
+ }
+ else {
+ rsDebug("test_element_getters PASSED", 0);
+ }
+
+ return failed;
+}
+
+void element_test() {
+ bool failed = false;
+ failed |= test_element_getters();
+
+ if (failed) {
+ rsSendToClientBlocking(RS_MSG_TEST_FAILED);
+ }
+ else {
+ rsSendToClientBlocking(RS_MSG_TEST_PASSED);
+ }
+}
+
diff --git a/tests/RenderScriptTests/tests/src/com/android/rs/test/mesh.rs b/tests/RenderScriptTests/tests/src/com/android/rs/test/mesh.rs
new file mode 100644
index 0000000..627ab99
--- /dev/null
+++ b/tests/RenderScriptTests/tests/src/com/android/rs/test/mesh.rs
@@ -0,0 +1,64 @@
+#include "shared.rsh"
+#include "rs_graphics.rsh"
+
+rs_mesh mesh;
+rs_allocation vertexAlloc0;
+rs_allocation vertexAlloc1;
+
+rs_allocation indexAlloc0;
+rs_allocation indexAlloc2;
+
+static bool test_mesh_getters() {
+ bool failed = false;
+
+ _RS_ASSERT(rsMeshGetVertexAllocationCount(mesh) == 2);
+ _RS_ASSERT(rsMeshGetPrimitiveCount(mesh) == 3);
+
+ rs_allocation meshV0 = rsMeshGetVertexAllocation(mesh, 0);
+ rs_allocation meshV1 = rsMeshGetVertexAllocation(mesh, 1);
+ rs_allocation meshV2 = rsMeshGetVertexAllocation(mesh, 2);
+ _RS_ASSERT(meshV0.p == vertexAlloc0.p);
+ _RS_ASSERT(meshV1.p == vertexAlloc1.p);
+ _RS_ASSERT(!rsIsObject(meshV2));
+
+ rs_allocation meshI0 = rsMeshGetIndexAllocation(mesh, 0);
+ rs_allocation meshI1 = rsMeshGetIndexAllocation(mesh, 1);
+ rs_allocation meshI2 = rsMeshGetIndexAllocation(mesh, 2);
+ rs_allocation meshI3 = rsMeshGetIndexAllocation(mesh, 3);
+ _RS_ASSERT(meshI0.p == indexAlloc0.p);
+ _RS_ASSERT(!rsIsObject(meshI1));
+ _RS_ASSERT(meshI2.p == indexAlloc2.p);
+ _RS_ASSERT(!rsIsObject(meshI3));
+
+ rs_primitive p0 = rsMeshGetPrimitive(mesh, 0);
+ rs_primitive p1 = rsMeshGetPrimitive(mesh, 1);
+ rs_primitive p2 = rsMeshGetPrimitive(mesh, 2);
+ rs_primitive p3 = rsMeshGetPrimitive(mesh, 3);
+
+ _RS_ASSERT(p0 == RS_PRIMITIVE_POINT);
+ _RS_ASSERT(p1 == RS_PRIMITIVE_LINE);
+ _RS_ASSERT(p2 == RS_PRIMITIVE_TRIANGLE);
+ _RS_ASSERT(p3 == RS_PRIMITIVE_INVALID);
+
+ if (failed) {
+ rsDebug("test_mesh_getters FAILED", 0);
+ }
+ else {
+ rsDebug("test_mesh_getters PASSED", 0);
+ }
+
+ return failed;
+}
+
+void mesh_test() {
+ bool failed = false;
+ failed |= test_mesh_getters();
+
+ if (failed) {
+ rsSendToClientBlocking(RS_MSG_TEST_FAILED);
+ }
+ else {
+ rsSendToClientBlocking(RS_MSG_TEST_PASSED);
+ }
+}
+
diff --git a/tests/RenderScriptTests/tests/src/com/android/rs/test/program_raster.rs b/tests/RenderScriptTests/tests/src/com/android/rs/test/program_raster.rs
new file mode 100644
index 0000000..11b8c30
--- /dev/null
+++ b/tests/RenderScriptTests/tests/src/com/android/rs/test/program_raster.rs
@@ -0,0 +1,37 @@
+#include "shared.rsh"
+#include "rs_graphics.rsh"
+
+rs_program_raster pointSpriteEnabled;
+rs_program_raster cullMode;
+
+static bool test_program_raster_getters() {
+ bool failed = false;
+
+ _RS_ASSERT(rsgProgramRasterGetPointSpriteEnabled(pointSpriteEnabled) == true);
+ _RS_ASSERT(rsgProgramRasterGetCullMode(pointSpriteEnabled) == RS_CULL_BACK);
+
+ _RS_ASSERT(rsgProgramRasterGetPointSpriteEnabled(cullMode) == false);
+ _RS_ASSERT(rsgProgramRasterGetCullMode(cullMode) == RS_CULL_FRONT);
+
+ if (failed) {
+ rsDebug("test_program_raster_getters FAILED", 0);
+ }
+ else {
+ rsDebug("test_program_raster_getters PASSED", 0);
+ }
+
+ return failed;
+}
+
+void program_raster_test() {
+ bool failed = false;
+ failed |= test_program_raster_getters();
+
+ if (failed) {
+ rsSendToClientBlocking(RS_MSG_TEST_FAILED);
+ }
+ else {
+ rsSendToClientBlocking(RS_MSG_TEST_PASSED);
+ }
+}
+
diff --git a/tests/RenderScriptTests/tests/src/com/android/rs/test/program_store.rs b/tests/RenderScriptTests/tests/src/com/android/rs/test/program_store.rs
new file mode 100644
index 0000000..3cd8a20
--- /dev/null
+++ b/tests/RenderScriptTests/tests/src/com/android/rs/test/program_store.rs
@@ -0,0 +1,128 @@
+#include "shared.rsh"
+#include "rs_graphics.rsh"
+
+rs_program_store ditherEnable;
+rs_program_store colorRWriteEnable;
+rs_program_store colorGWriteEnable;
+rs_program_store colorBWriteEnable;
+rs_program_store colorAWriteEnable;
+rs_program_store blendSrc;
+rs_program_store blendDst;
+rs_program_store depthWriteEnable;
+rs_program_store depthFunc;
+
+static bool test_program_store_getters() {
+ bool failed = false;
+
+ _RS_ASSERT(rsgProgramStoreGetDepthFunc(depthFunc) == RS_DEPTH_FUNC_GREATER);
+ _RS_ASSERT(rsgProgramStoreGetDepthMask(depthFunc) == false);
+ _RS_ASSERT(rsgProgramStoreGetColorMaskR(depthFunc) == false);
+ _RS_ASSERT(rsgProgramStoreGetColorMaskG(depthFunc) == false);
+ _RS_ASSERT(rsgProgramStoreGetColorMaskB(depthFunc) == false);
+ _RS_ASSERT(rsgProgramStoreGetColorMaskA(depthFunc) == false);
+ _RS_ASSERT(rsgProgramStoreGetDitherEnabled(depthFunc) == false);
+ _RS_ASSERT(rsgProgramStoreGetBlendSrcFunc(depthFunc) == RS_BLEND_SRC_ZERO);
+ _RS_ASSERT(rsgProgramStoreGetBlendDstFunc(depthFunc) == RS_BLEND_DST_ZERO);
+
+ _RS_ASSERT(rsgProgramStoreGetDepthFunc(depthWriteEnable) == RS_DEPTH_FUNC_ALWAYS);
+ _RS_ASSERT(rsgProgramStoreGetDepthMask(depthWriteEnable) == true);
+ _RS_ASSERT(rsgProgramStoreGetColorMaskR(depthWriteEnable) == false);
+ _RS_ASSERT(rsgProgramStoreGetColorMaskG(depthWriteEnable) == false);
+ _RS_ASSERT(rsgProgramStoreGetColorMaskB(depthWriteEnable) == false);
+ _RS_ASSERT(rsgProgramStoreGetColorMaskA(depthWriteEnable) == false);
+ _RS_ASSERT(rsgProgramStoreGetDitherEnabled(depthWriteEnable) == false);
+ _RS_ASSERT(rsgProgramStoreGetBlendSrcFunc(depthWriteEnable) == RS_BLEND_SRC_ZERO);
+ _RS_ASSERT(rsgProgramStoreGetBlendDstFunc(depthWriteEnable) == RS_BLEND_DST_ZERO);
+
+ _RS_ASSERT(rsgProgramStoreGetDepthFunc(colorRWriteEnable) == RS_DEPTH_FUNC_ALWAYS);
+ _RS_ASSERT(rsgProgramStoreGetDepthMask(colorRWriteEnable) == false);
+ _RS_ASSERT(rsgProgramStoreGetColorMaskR(colorRWriteEnable) == true);
+ _RS_ASSERT(rsgProgramStoreGetColorMaskG(colorRWriteEnable) == false);
+ _RS_ASSERT(rsgProgramStoreGetColorMaskB(colorRWriteEnable) == false);
+ _RS_ASSERT(rsgProgramStoreGetColorMaskA(colorRWriteEnable) == false);
+ _RS_ASSERT(rsgProgramStoreGetDitherEnabled(colorRWriteEnable) == false);
+ _RS_ASSERT(rsgProgramStoreGetBlendSrcFunc(colorRWriteEnable) == RS_BLEND_SRC_ZERO);
+ _RS_ASSERT(rsgProgramStoreGetBlendDstFunc(colorRWriteEnable) == RS_BLEND_DST_ZERO);
+
+ _RS_ASSERT(rsgProgramStoreGetDepthFunc(colorGWriteEnable) == RS_DEPTH_FUNC_ALWAYS);
+ _RS_ASSERT(rsgProgramStoreGetDepthMask(colorGWriteEnable) == false);
+ _RS_ASSERT(rsgProgramStoreGetColorMaskR(colorGWriteEnable) == false);
+ _RS_ASSERT(rsgProgramStoreGetColorMaskG(colorGWriteEnable) == true);
+ _RS_ASSERT(rsgProgramStoreGetColorMaskB(colorGWriteEnable) == false);
+ _RS_ASSERT(rsgProgramStoreGetColorMaskA(colorGWriteEnable) == false);
+ _RS_ASSERT(rsgProgramStoreGetDitherEnabled(colorGWriteEnable) == false);
+ _RS_ASSERT(rsgProgramStoreGetBlendSrcFunc(colorGWriteEnable) == RS_BLEND_SRC_ZERO);
+ _RS_ASSERT(rsgProgramStoreGetBlendDstFunc(colorGWriteEnable) == RS_BLEND_DST_ZERO);
+
+ _RS_ASSERT(rsgProgramStoreGetDepthFunc(colorBWriteEnable) == RS_DEPTH_FUNC_ALWAYS);
+ _RS_ASSERT(rsgProgramStoreGetDepthMask(colorBWriteEnable) == false);
+ _RS_ASSERT(rsgProgramStoreGetColorMaskR(colorBWriteEnable) == false);
+ _RS_ASSERT(rsgProgramStoreGetColorMaskG(colorBWriteEnable) == false);
+ _RS_ASSERT(rsgProgramStoreGetColorMaskB(colorBWriteEnable) == true);
+ _RS_ASSERT(rsgProgramStoreGetColorMaskA(colorBWriteEnable) == false);
+ _RS_ASSERT(rsgProgramStoreGetDitherEnabled(colorBWriteEnable) == false);
+ _RS_ASSERT(rsgProgramStoreGetBlendSrcFunc(colorBWriteEnable) == RS_BLEND_SRC_ZERO);
+ _RS_ASSERT(rsgProgramStoreGetBlendDstFunc(colorBWriteEnable) == RS_BLEND_DST_ZERO);
+
+ _RS_ASSERT(rsgProgramStoreGetDepthFunc(colorAWriteEnable) == RS_DEPTH_FUNC_ALWAYS);
+ _RS_ASSERT(rsgProgramStoreGetDepthMask(colorAWriteEnable) == false);
+ _RS_ASSERT(rsgProgramStoreGetColorMaskR(colorAWriteEnable) == false);
+ _RS_ASSERT(rsgProgramStoreGetColorMaskG(colorAWriteEnable) == false);
+ _RS_ASSERT(rsgProgramStoreGetColorMaskB(colorAWriteEnable) == false);
+ _RS_ASSERT(rsgProgramStoreGetColorMaskA(colorAWriteEnable) == true);
+ _RS_ASSERT(rsgProgramStoreGetDitherEnabled(colorAWriteEnable) == false);
+ _RS_ASSERT(rsgProgramStoreGetBlendSrcFunc(colorAWriteEnable) == RS_BLEND_SRC_ZERO);
+ _RS_ASSERT(rsgProgramStoreGetBlendDstFunc(colorAWriteEnable) == RS_BLEND_DST_ZERO);
+
+ _RS_ASSERT(rsgProgramStoreGetDepthFunc(ditherEnable) == RS_DEPTH_FUNC_ALWAYS);
+ _RS_ASSERT(rsgProgramStoreGetDepthMask(ditherEnable) == false);
+ _RS_ASSERT(rsgProgramStoreGetColorMaskR(ditherEnable) == false);
+ _RS_ASSERT(rsgProgramStoreGetColorMaskG(ditherEnable) == false);
+ _RS_ASSERT(rsgProgramStoreGetColorMaskB(ditherEnable) == false);
+ _RS_ASSERT(rsgProgramStoreGetColorMaskA(ditherEnable) == false);
+ _RS_ASSERT(rsgProgramStoreGetDitherEnabled(ditherEnable) == true);
+ _RS_ASSERT(rsgProgramStoreGetBlendSrcFunc(ditherEnable) == RS_BLEND_SRC_ZERO);
+ _RS_ASSERT(rsgProgramStoreGetBlendDstFunc(ditherEnable) == RS_BLEND_DST_ZERO);
+
+ _RS_ASSERT(rsgProgramStoreGetDepthFunc(blendSrc) == RS_DEPTH_FUNC_ALWAYS);
+ _RS_ASSERT(rsgProgramStoreGetDepthMask(blendSrc) == false);
+ _RS_ASSERT(rsgProgramStoreGetColorMaskR(blendSrc) == false);
+ _RS_ASSERT(rsgProgramStoreGetColorMaskG(blendSrc) == false);
+ _RS_ASSERT(rsgProgramStoreGetColorMaskB(blendSrc) == false);
+ _RS_ASSERT(rsgProgramStoreGetColorMaskA(blendSrc) == false);
+ _RS_ASSERT(rsgProgramStoreGetDitherEnabled(blendSrc) == false);
+ _RS_ASSERT(rsgProgramStoreGetBlendSrcFunc(blendSrc) == RS_BLEND_SRC_DST_COLOR);
+ _RS_ASSERT(rsgProgramStoreGetBlendDstFunc(blendSrc) == RS_BLEND_DST_ZERO);
+
+ _RS_ASSERT(rsgProgramStoreGetDepthFunc(blendDst) == RS_DEPTH_FUNC_ALWAYS);
+ _RS_ASSERT(rsgProgramStoreGetDepthMask(blendDst) == false);
+ _RS_ASSERT(rsgProgramStoreGetColorMaskR(blendDst) == false);
+ _RS_ASSERT(rsgProgramStoreGetColorMaskG(blendDst) == false);
+ _RS_ASSERT(rsgProgramStoreGetColorMaskB(blendDst) == false);
+ _RS_ASSERT(rsgProgramStoreGetColorMaskA(blendDst) == false);
+ _RS_ASSERT(rsgProgramStoreGetDitherEnabled(blendDst) == false);
+ _RS_ASSERT(rsgProgramStoreGetBlendSrcFunc(blendDst) == RS_BLEND_SRC_ZERO);
+ _RS_ASSERT(rsgProgramStoreGetBlendDstFunc(blendDst) == RS_BLEND_DST_DST_ALPHA);
+
+ if (failed) {
+ rsDebug("test_program_store_getters FAILED", 0);
+ }
+ else {
+ rsDebug("test_program_store_getters PASSED", 0);
+ }
+
+ return failed;
+}
+
+void program_store_test() {
+ bool failed = false;
+ failed |= test_program_store_getters();
+
+ if (failed) {
+ rsSendToClientBlocking(RS_MSG_TEST_FAILED);
+ }
+ else {
+ rsSendToClientBlocking(RS_MSG_TEST_PASSED);
+ }
+}
+
diff --git a/tests/RenderScriptTests/tests/src/com/android/rs/test/sampler.rs b/tests/RenderScriptTests/tests/src/com/android/rs/test/sampler.rs
new file mode 100644
index 0000000..ac9a549
--- /dev/null
+++ b/tests/RenderScriptTests/tests/src/com/android/rs/test/sampler.rs
@@ -0,0 +1,63 @@
+#include "shared.rsh"
+#include "rs_graphics.rsh"
+rs_sampler minification;
+rs_sampler magnification;
+rs_sampler wrapS;
+rs_sampler wrapT;
+rs_sampler anisotropy;
+
+static bool test_sampler_getters() {
+ bool failed = false;
+
+ _RS_ASSERT(rsgSamplerGetMagnification(minification) == RS_SAMPLER_NEAREST);
+ _RS_ASSERT(rsgSamplerGetMinification(minification) == RS_SAMPLER_LINEAR_MIP_LINEAR);
+ _RS_ASSERT(rsgSamplerGetWrapS(minification) == RS_SAMPLER_CLAMP);
+ _RS_ASSERT(rsgSamplerGetWrapT(minification) == RS_SAMPLER_CLAMP);
+ _RS_ASSERT(rsgSamplerGetAnisotropy(minification) == 1.0f);
+
+ _RS_ASSERT(rsgSamplerGetMagnification(magnification) == RS_SAMPLER_LINEAR);
+ _RS_ASSERT(rsgSamplerGetMinification(magnification) == RS_SAMPLER_NEAREST);
+ _RS_ASSERT(rsgSamplerGetWrapS(magnification) == RS_SAMPLER_CLAMP);
+ _RS_ASSERT(rsgSamplerGetWrapT(magnification) == RS_SAMPLER_CLAMP);
+ _RS_ASSERT(rsgSamplerGetAnisotropy(magnification) == 1.0f);
+
+ _RS_ASSERT(rsgSamplerGetMagnification(wrapS) == RS_SAMPLER_NEAREST);
+ _RS_ASSERT(rsgSamplerGetMinification(wrapS) == RS_SAMPLER_NEAREST);
+ _RS_ASSERT(rsgSamplerGetWrapS(wrapS) == RS_SAMPLER_WRAP);
+ _RS_ASSERT(rsgSamplerGetWrapT(wrapS) == RS_SAMPLER_CLAMP);
+ _RS_ASSERT(rsgSamplerGetAnisotropy(wrapS) == 1.0f);
+
+ _RS_ASSERT(rsgSamplerGetMagnification(wrapT) == RS_SAMPLER_NEAREST);
+ _RS_ASSERT(rsgSamplerGetMinification(wrapT) == RS_SAMPLER_NEAREST);
+ _RS_ASSERT(rsgSamplerGetWrapS(wrapT) == RS_SAMPLER_CLAMP);
+ _RS_ASSERT(rsgSamplerGetWrapT(wrapT) == RS_SAMPLER_WRAP);
+ _RS_ASSERT(rsgSamplerGetAnisotropy(wrapT) == 1.0f);
+
+ _RS_ASSERT(rsgSamplerGetMagnification(anisotropy) == RS_SAMPLER_NEAREST);
+ _RS_ASSERT(rsgSamplerGetMinification(anisotropy) == RS_SAMPLER_NEAREST);
+ _RS_ASSERT(rsgSamplerGetWrapS(anisotropy) == RS_SAMPLER_CLAMP);
+ _RS_ASSERT(rsgSamplerGetWrapT(anisotropy) == RS_SAMPLER_CLAMP);
+ _RS_ASSERT(rsgSamplerGetAnisotropy(anisotropy) == 8.0f);
+
+ if (failed) {
+ rsDebug("test_sampler_getters FAILED", 0);
+ }
+ else {
+ rsDebug("test_sampler_getters PASSED", 0);
+ }
+
+ return failed;
+}
+
+void sampler_test() {
+ bool failed = false;
+ failed |= test_sampler_getters();
+
+ if (failed) {
+ rsSendToClientBlocking(RS_MSG_TEST_FAILED);
+ }
+ else {
+ rsSendToClientBlocking(RS_MSG_TEST_PASSED);
+ }
+}
+