diff options
133 files changed, 10140 insertions, 199 deletions
diff --git a/graphics/java/android/renderscript/Allocation.java b/graphics/java/android/renderscript/Allocation.java index 509b972..88ee362 100644 --- a/graphics/java/android/renderscript/Allocation.java +++ b/graphics/java/android/renderscript/Allocation.java @@ -921,7 +921,31 @@ public class Allocation extends BaseObj { 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."); } @@ -976,7 +1000,7 @@ public class Allocation extends BaseObj { 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."); } 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 @@ public class Element extends BaseObj { 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 @@ public class Element extends BaseObj { * 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 @@ public class Element extends BaseObj { * @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 @@ public class Element extends BaseObj { * @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 @@ public class Element extends BaseObj { * @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 @@ public class Element extends BaseObj { * @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 @@ public class Element extends BaseObj { * @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 @@ public class Element extends BaseObj { 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 @@ public class Element extends BaseObj { 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 @@ public class Program extends BaseObj { } /** + * @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 @@ public class ProgramVertex extends Program { } /** + * @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 3f3033b..d3c801f 100644 --- a/graphics/java/android/renderscript/RenderScript.java +++ b/graphics/java/android/renderscript/RenderScript.java @@ -231,10 +231,10 @@ public class RenderScript { 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) { @@ -590,6 +590,11 @@ public class RenderScript { 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 a9f0f1f..94f19b3 100644 --- a/graphics/jni/android_renderscript_RenderScript.cpp +++ b/graphics/jni/android_renderscript_RenderScript.cpp @@ -430,10 +430,10 @@ nTypeGetNativeData(JNIEnv *_env, jobject _this, RsContext con, jint id, jintArra // ----------------------------------- 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 @@ -1129,6 +1129,17 @@ nSamplerCreate(JNIEnv *_env, jobject _this, RsContext con, jint magFilter, jint // --------------------------------------------------------------------------- +//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) { @@ -1257,7 +1268,7 @@ static JNINativeMethod methods[] = { {"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 }, @@ -1318,6 +1329,7 @@ static JNINativeMethod methods[] = { {"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 2166ce7..9c5d06b 100644 --- a/libs/rs/Android.mk +++ b/libs/rs/Android.mk @@ -95,6 +95,7 @@ LOCAL_SRC_FILES:= \ rsMatrix4x4.cpp \ rsMesh.cpp \ rsMutex.cpp \ + rsPath.cpp \ rsProgram.cpp \ rsProgramFragment.cpp \ rsProgramStore.cpp \ @@ -117,6 +118,7 @@ LOCAL_SRC_FILES:= \ driver/rsdGL.cpp \ driver/rsdMesh.cpp \ driver/rsdMeshObj.cpp \ + driver/rsdPath.cpp \ driver/rsdProgram.cpp \ driver/rsdProgramRaster.cpp \ driver/rsdProgramStore.cpp \ @@ -201,6 +203,7 @@ LOCAL_SRC_FILES:= \ 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 5b0a3da..990ef26 100644 --- a/libs/rs/RenderScriptDefines.h +++ b/libs/rs/RenderScriptDefines.h @@ -41,6 +41,7 @@ typedef void * RsFont; typedef void * RsSampler; typedef void * RsScript; typedef void * RsMesh; +typedef void * RsPath; typedef void * RsType; typedef void * RsObjectBase; @@ -155,6 +156,8 @@ enum RsDataType { RS_TYPE_PROGRAM_VERTEX, RS_TYPE_PROGRAM_RASTER, RS_TYPE_PROGRAM_STORE, + + RS_TYPE_INVALID = 10000, }; enum RsDataKind { @@ -166,6 +169,8 @@ enum RsDataKind { RS_KIND_PIXEL_RGB, RS_KIND_PIXEL_RGBA, RS_KIND_PIXEL_DEPTH, + + RS_KIND_INVALID = 100, }; enum RsSamplerParam { @@ -184,6 +189,8 @@ enum RsSamplerValue { RS_SAMPLER_WRAP, RS_SAMPLER_CLAMP, RS_SAMPLER_LINEAR_MIP_NEAREST, + + RS_SAMPLER_INVALID = 100, }; enum RsTextureTarget { @@ -224,7 +231,8 @@ enum RsBlendSrcFunc { 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 { @@ -235,7 +243,9 @@ enum RsBlendDstFunc { 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 { @@ -258,7 +268,14 @@ enum RsPrimitive { 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 { @@ -312,7 +329,8 @@ enum RsA3DClassID { 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 fac40f2..ea92192 100644 --- a/libs/rs/driver/rsdAllocation.cpp +++ b/libs/rs/driver/rsdAllocation.cpp @@ -219,10 +219,13 @@ bool rsdAllocationInit(const Context *rsc, Allocation *alloc, bool forceZero) { 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; @@ -276,7 +279,7 @@ void rsdAllocationDestroy(const Context *rsc, Allocation *alloc) { drv->renderTargetID = 0; } - if (drv->mallocPtr) { + if (drv->mallocPtr && !alloc->mHal.state.usrPtr) { free(drv->mallocPtr); drv->mallocPtr = NULL; } diff --git a/libs/rs/driver/rsdCore.cpp b/libs/rs/driver/rsdCore.cpp index 9987027..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" @@ -115,6 +116,13 @@ static RsdHalFunctions FunctionTable = { }, { + rsdPathInitStatic, + rsdPathInitDynamic, + rsdPathDraw, + rsdPathDestroy + }, + + { rsdSamplerInit, rsdSamplerDestroy }, @@ -260,6 +268,9 @@ void SetPriority(const Context *rsc, int32_t priority) { 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 ScriptTLSStructRec { 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 368dd71..b136cc7 100644 --- a/libs/rs/driver/rsdGL.cpp +++ b/libs/rs/driver/rsdGL.cpp @@ -361,6 +361,7 @@ bool rsdGLInit(const Context *rsc) { 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); @@ -421,6 +422,15 @@ void rsdGLSwap(const android::renderscript::Context *rsc) { 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 @@ bool rsdGLSetSurface(const android::renderscript::Context *rsc, 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 @@ bool rsdMeshInit(const Context *rsc, const Mesh *m) { } 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 @@ RsdMeshObj::~RsdMeshObj() { } 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 @@ bool RsdMeshObj::isValidGLComponent(const Element *elem, uint32_t fieldIdx) { } // 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 @@ bool RsdMeshObj::isValidGLComponent(const Element *elem, uint32_t fieldIdx) { 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 @@ bool RsdMeshObj::init() { 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 @@ bool RsdMeshObj::init() { 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 @@ void RsdMeshObj::renderPrimitiveRange(const Context *rsc, uint32_t primIndex, 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 @@ void RsdMeshObj::updateGLPrimitives() { 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 @@ public: 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 @@ void rsdProgramRasterSetActive(const Context *rsc, const ProgramRaster *pr) { 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 @@ bool rsdProgramStoreInit(const Context *rsc, const ProgramStore *ps) { 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 @@ bool rsdProgramStoreInit(const Context *rsc, const ProgramStore *ps) { 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 @@ static void SC_BindTexture(ProgramFragment *pf, uint32_t slot, Allocation *a) { 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 @@ static void SC_DrawRect(float x1, float y1, float x2, float y2, float z) { 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 @@ static RsdSymbolTable gSyms[] = { { "_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 @@ static RsdSymbolTable gSyms[] = { { "_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 @@ static RsdSymbolTable gSyms[] = { { "_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 056a33a..3bca794 100644 --- a/libs/rs/driver/rsdShader.cpp +++ b/libs/rs/driver/rsdShader.cpp @@ -90,12 +90,12 @@ String8 RsdShader::getGLSLInputString() const { 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 @@ String8 RsdShader::getGLSLInputString() const { rsAssert(0); } - s.append(e->getFieldName(field)); + s.append(e->mHal.state.fieldNames[field]); s.append(";\n"); } } @@ -114,17 +114,13 @@ String8 RsdShader::getGLSLInputString() const { 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; @@ -215,24 +211,20 @@ bool RsdShader::loadShader(const Context *rsc) { 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; @@ -243,8 +235,8 @@ void RsdShader::appendUserConstants() { } 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"); } @@ -252,8 +244,8 @@ void RsdShader::appendUserConstants() { } 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); @@ -274,7 +266,7 @@ void RsdShader::logUniform(const Element *field, const float *fd, uint32_t array 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; @@ -299,7 +291,7 @@ void RsdShader::logUniform(const Element *field, const float *fd, uint32_t array 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) { @@ -307,7 +299,7 @@ void RsdShader::setUniform(const Context *rsc, const Element *field, const float } 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; @@ -462,15 +454,11 @@ void RsdShader::setupUserConstants(const Context *rsc, RsdShaderCache *sc, bool 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; @@ -509,22 +497,13 @@ void RsdShader::initAttribAndUniformArray() { 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; @@ -544,17 +523,17 @@ void RsdShader::initAttribAndUniformArray() { 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/rs.spec b/libs/rs/rs.spec index 09a2986..6759bc7 100644 --- a/libs/rs/rs.spec +++ b/libs/rs/rs.spec @@ -42,6 +42,7 @@ AllocationCreateTyped { param RsType vtype param RsAllocationMipmapControl mips param uint32_t usages + param uint32_t ptr ret RsAllocation } @@ -392,3 +393,13 @@ MeshCreate { 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 5f45abf..02c6809 100644 --- a/libs/rs/rsAllocation.cpp +++ b/libs/rs/rsAllocation.cpp @@ -22,21 +22,22 @@ using namespace android; 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"); @@ -577,8 +578,8 @@ static void AllocationGenerateScriptMips(RsContext con, RsAllocation va) { 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; } @@ -591,7 +592,7 @@ RsAllocation rsi_AllocationCreateFromBitmap(Context *rsc, RsType vtype, 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"); @@ -615,7 +616,7 @@ RsAllocation rsi_AllocationCubeCreateFromBitmap(Context *rsc, RsType vtype, // 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"); diff --git a/libs/rs/rsAllocation.h b/libs/rs/rsAllocation.h index a26d835..58a582b 100644 --- a/libs/rs/rsAllocation.h +++ b/libs/rs/rsAllocation.h @@ -68,7 +68,8 @@ public: 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(); @@ -137,7 +138,7 @@ protected: 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 @@ void Component::set(RsDataType dt, RsDataKind dk, bool norm, uint32_t vecSize) { rsAssert(mNormalized == true); break; default: + rsAssert(mKind != RS_KIND_INVALID); break; } @@ -167,6 +168,9 @@ void Component::set(RsDataType dt, RsDataKind dk, bool norm, uint32_t vecSize) { 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 1a34bd5..adaefc6 100644 --- a/libs/rs/rsContext.cpp +++ b/libs/rs/rsContext.cpp @@ -361,6 +361,7 @@ void Context::setPriority(int32_t p) { #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 a844a20..05c799e 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 @@ Element::Element(Context *rsc) : ObjectBase(rsc) { mFields = NULL; mFieldCount = 0; mHasReference = false; + memset(&mHal, 0, sizeof(mHal)); } Element::~Element() { @@ -47,6 +48,12 @@ void Element::clear() { 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 @@ Element *Element::createFromStream(Context *rsc, IStream *stream) { } 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 @@ void Element::compute() { 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 @@ public: }; 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 @@ namespace renderscript { ////////////////////////////////////////////////////////////////////////////// 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 rsrDrawQuad(Context *, Script *, 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 @@ void rsrBindTexture(Context *rsc, Script *sc, ProgramFragment *pf, uint32_t slot 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 @@ void rsrDrawRect(Context *rsc, Script *sc, float x1, float y1, float x2, float y 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/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 @@ void Type::clear() { 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 @@ TypeState::~TypeState() { } 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 @@ void Type::compute() { 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 @@ void Type::compute() { // 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 @@ uint32_t Type::getLODOffset(uint32_t lod, uint32_t x, uint32_t y, uint32_t z) co 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 @@ uint32_t Type::getLODFaceOffset(uint32_t lod, RsAllocationCubemapFace face, uint 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 @@ void Type::serialize(OStream *stream) const { 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 @@ ObjectBaseRef<Type> Type::getTypeRef(Context *rsc, const Element *e, 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::getTypeRef(Context *rsc, const Element *e, 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 @@ RsType rsi_TypeCreate(Context *rsc, RsElement _e, uint32_t dimX, 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 @@ public: 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 @@ protected: 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 0afc94b..1e222e1 100644 --- a/libs/rs/rs_hal.h +++ b/libs/rs/rs_hal.h @@ -29,6 +29,7 @@ class Type; class Allocation; class Script; class ScriptC; +class Path; class Program; class ProgramStore; class ProgramRaster; @@ -190,6 +191,13 @@ typedef struct { } 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)) 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)) 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 @@ extern void __attribute__((overloadable)) 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 @@ extern void __attribute__((overloadable)) 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 @@ extern void __attribute__((overloadable)) 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)) 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 @@ extern void __attribute__((overloadable)) * \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 @@ extern void __attribute__((overloadable)) * \overload */ extern void __attribute__((overloadable)) + rsClearObject(rs_path *dst); +/** + * \overload + */ +extern void __attribute__((overloadable)) rsClearObject(rs_mesh *dst); /** * \overload @@ -175,6 +185,11 @@ extern bool __attribute__((overloadable)) * \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_sc */ 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 @@ typedef enum { #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 @@ void root(uchar4 *v_out, uint32_t x, uint32_t y) { 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 @@ public class ImageProcessingActivity extends Activity 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 @@ public class FillTest implements RsBenchBaseTest{ // 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 @@ public class FillTest implements RsBenchBaseTest{ 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 @@ public class FillTest implements RsBenchBaseTest{ 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 @@ public class FillTest implements RsBenchBaseTest{ 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 @@ public class FillTest implements RsBenchBaseTest{ 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 @@ typedef struct FillTestData_s { } FillTestData; FillTestData *gData; +typedef struct FillTestFragData_s { + float4 modulate; +} FillTestFragData; +FillTestFragData *gFragData; + static float gDt = 0.0f; void init() { @@ -58,7 +64,7 @@ static void bindProgramVertexOrtho() { 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 @@ static void displaySingletexFill(bool blend, int quadCount) { } 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 @@ void root(const void *v_in, void *v_out, const void *usrData, uint32_t x, uint32 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 Binary files differnew file mode 100644 index 0000000..494e77a --- /dev/null +++ b/tests/RenderScriptTests/SceneGraph/assets/blue.jpg diff --git a/tests/RenderScriptTests/SceneGraph/assets/carbonfiber.jpg b/tests/RenderScriptTests/SceneGraph/assets/carbonfiber.jpg Binary files differnew file mode 100644 index 0000000..2fcecb0 --- /dev/null +++ b/tests/RenderScriptTests/SceneGraph/assets/carbonfiber.jpg diff --git a/tests/RenderScriptTests/SceneGraph/assets/green.jpg b/tests/RenderScriptTests/SceneGraph/assets/green.jpg Binary files differnew file mode 100644 index 0000000..a86a754 --- /dev/null +++ b/tests/RenderScriptTests/SceneGraph/assets/green.jpg diff --git a/tests/RenderScriptTests/SceneGraph/assets/grey.jpg b/tests/RenderScriptTests/SceneGraph/assets/grey.jpg Binary files differnew file mode 100644 index 0000000..5870b1a --- /dev/null +++ b/tests/RenderScriptTests/SceneGraph/assets/grey.jpg diff --git a/tests/RenderScriptTests/SceneGraph/assets/orange.jpg b/tests/RenderScriptTests/SceneGraph/assets/orange.jpg Binary files differnew file mode 100644 index 0000000..7dbe942 --- /dev/null +++ b/tests/RenderScriptTests/SceneGraph/assets/orange.jpg diff --git a/tests/RenderScriptTests/SceneGraph/assets/orientation_test.a3d b/tests/RenderScriptTests/SceneGraph/assets/orientation_test.a3d Binary files differnew file mode 100644 index 0000000..07318ae --- /dev/null +++ b/tests/RenderScriptTests/SceneGraph/assets/orientation_test.a3d diff --git a/tests/RenderScriptTests/SceneGraph/assets/orientation_test.dae b/tests/RenderScriptTests/SceneGraph/assets/orientation_test.dae new file mode 100644 index 0000000..7eef443 --- /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 Binary files differnew file mode 100644 index 0000000..0791045 --- /dev/null +++ b/tests/RenderScriptTests/SceneGraph/assets/paint.jpg diff --git a/tests/RenderScriptTests/SceneGraph/assets/red.jpg b/tests/RenderScriptTests/SceneGraph/assets/red.jpg Binary files differnew file mode 100644 index 0000000..320a2a6 --- /dev/null +++ b/tests/RenderScriptTests/SceneGraph/assets/red.jpg diff --git a/tests/RenderScriptTests/SceneGraph/res/drawable-nodpi/robot.png b/tests/RenderScriptTests/SceneGraph/res/drawable-nodpi/robot.png Binary files differnew file mode 100644 index 0000000..f7353fd --- /dev/null +++ b/tests/RenderScriptTests/SceneGraph/res/drawable-nodpi/robot.png 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 Binary files differnew file mode 100644 index 0000000..f48895c --- /dev/null +++ b/tests/RenderScriptTests/SceneGraph/res/raw/robot.a3d 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..42f2be5 --- /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 = 1000.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..c8cc3ac --- /dev/null +++ b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/FragmentShader.java @@ -0,0 +1,167 @@ +/* + * 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; + } + + ScriptField_ShaderParam_s getTextureParams() { + RenderScriptGL rs = SceneManager.getRS(); + Resources res = SceneManager.getRes(); + if (rs == null || res == null) { + return null; + } + + ArrayList<ScriptField_ShaderParam_s.Item> paramList; + paramList = new ArrayList<ScriptField_ShaderParam_s.Item>(); + + 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; + ScriptField_ShaderParam_s.Item paramRS = new ScriptField_ShaderParam_s.Item(); + paramRS.bufferOffset = shaderTextureStart + i; + paramRS.transformTimestamp = 0; + paramRS.dataTimestamp = 0; + paramRS.data = p.getRSData().getAllocation(); + 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; + } + + 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; + + ScriptField_ShaderParam_s texParams = getTextureParams(); + if (texParams != null) { + item.shaderTextureParams = texParams.getAllocation(); + } + + 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..02fd69d --- /dev/null +++ b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/RenderPass.java @@ -0,0 +1,124 @@ +/* + * 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 { + + TextureRenderTarget mColorTarget; + Float4 mClearColor; + boolean mShouldClearColor; + + TextureRenderTarget 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(TextureRenderTarget colorTarget) { + mColorTarget = colorTarget; + } + public void setClearColor(Float4 clearColor) { + mClearColor = clearColor; + } + public void setShouldClearColor(boolean shouldClearColor) { + mShouldClearColor = shouldClearColor; + } + + public void setDepthTarget(TextureRenderTarget 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(); + if (mColorTarget != null) { + mRsField.color_target = mColorTarget.getRsData(true).get_texture(0); + } + if (mColorTarget != null) { + mRsField.depth_target = mDepthTarget.getRsData(true).get_texture(0); + } + 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..9f7ab41 --- /dev/null +++ b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/Renderable.java @@ -0,0 +1,214 @@ +/* + * 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) { + 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(false).getAllocation(); + } + } + } + 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); + updateTextures(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..8c09860 --- /dev/null +++ b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/Scene.java @@ -0,0 +1,308 @@ +/* + * 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 com.android.scenegraph.TextureBase; + +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"; + + 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) { + 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); + } + mRenderPassAlloc.copyAll(); + sceneManager.mRenderLoop.set_gRenderPasses(mRenderPassAlloc.getAllocation()); + } + } + + 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() { + SceneManager sceneManager = SceneManager.getInstance(); + mRS = SceneManager.getRS(); + mRes = SceneManager.getRes(); + 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(mRS, mRes, sceneManager); + end = System.currentTimeMillis(); + Log.v(TIMER_TAG, "Renderable init time: " + (end - start)); + + addShaders(mRS, mRes, sceneManager); + + Allocation opaqueBuffer = null; + if (mRenderables.size() > 0) { + opaqueBuffer = Allocation.createSized(mRS, Element.U32(mRS), mRenderables.size()); + } + Allocation transparentBuffer = null; + if (mRenderables.size() > 0) { + transparentBuffer = Allocation.createSized(mRS, Element.U32(mRS), mRenderables.size()); + } + + sceneManager.mRenderLoop.bind_gFrontToBack(opaqueBuffer); + sceneManager.mRenderLoop.bind_gBackToFront(transparentBuffer); + + if (mCameras.size() > 0) { + Allocation cameraData; + cameraData = Allocation.createSized(mRS, Element.ALLOCATION(mRS), 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(mRS, + Element.ALLOCATION(mRS), + mLights.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..f77f483 --- /dev/null +++ b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/SceneManager.java @@ -0,0 +1,355 @@ +/* + * 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.Camera; +import com.android.scenegraph.MatrixTransform; +import com.android.scenegraph.Scene; +import com.android.testapp.R; + +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.renderscript.Type.Builder; +import android.util.Log; +import android.view.SurfaceHolder; + +/** + * @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; + + private Allocation sDefault2D; + private Allocation sDefaultCube; + + private static Allocation getDefault(boolean isCube) { + final int dimension = 4; + final int bytesPerPixel = 4; + int arraySize = dimension * dimension * bytesPerPixel; + + RenderScriptGL rs = sSceneManager.mRS; + Type.Builder b = new Type.Builder(rs, Element.RGBA_8888(rs)); + b.setX(dimension).setY(dimension); + if (isCube) { + b.setFaces(true); + arraySize *= 6; + } + Type bitmapType = b.create(); + + Allocation.MipmapControl mip = Allocation.MipmapControl.MIPMAP_ON_SYNC_TO_TEXTURE; + int usage = Allocation.USAGE_GRAPHICS_TEXTURE; + Allocation defaultImage = Allocation.createTyped(rs, bitmapType, mip, usage); + + byte imageData[] = new byte[arraySize]; + defaultImage.copyFrom(imageData); + return defaultImage; + } + + static Allocation getDefaultTex2D() { + if (sSceneManager == null) { + return null; + } + if (sSceneManager.sDefault2D == null) { + sSceneManager.sDefault2D = getDefault(false); + } + return sSceneManager.sDefault2D; + } + + static Allocation getDefaultTexCube() { + if (sSceneManager == null) { + return null; + } + if (sSceneManager.sDefaultCube == null) { + sSceneManager.sDefaultCube = getDefault(true); + } + return sSceneManager.sDefaultCube; + } + + 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); + if (b == null) { + return null; + } + 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); + if (b == null) { + return null; + } + 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; + + // Do some sanity checking + if (mActiveScene.getCameras().size() == 0) { + Matrix4f camPos = new Matrix4f(); + camPos.translate(0, 0, 10); + MatrixTransform cameraTransform = new MatrixTransform(); + cameraTransform.setName("_DefaultCameraTransform"); + cameraTransform.setMatrix(camPos); + mActiveScene.appendTransform(cameraTransform); + Camera cam = new Camera(); + cam.setName("_DefaultCamera"); + cam.setTransform(cameraTransform); + mActiveScene.appendCamera(cam); + } + } + + 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); + + 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..8fae9d9 --- /dev/null +++ b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/Texture2D.java @@ -0,0 +1,97 @@ +/* + * 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() { + super(ScriptC_export.const_TextureType_TEXTURE_2D); + } + + public Texture2D(Allocation tex) { + super(ScriptC_export.const_TextureType_TEXTURE_2D); + 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) { + mData.texture = tex != null ? tex : SceneManager.getDefaultTex2D(); + if (mField != null) { + mField.set_texture(0, mData.texture, true); + } + } + + void load() { + RenderScriptGL rs = SceneManager.getRS(); + Resources res = SceneManager.getRes(); + String shortName = mFileName.substring(mFileName.lastIndexOf('/') + 1); + setTexture(SceneManager.loadTexture2D(mFileDir + shortName, rs, res)); + } + + ScriptField_Texture_s getRsData(boolean loadNow) { + if (mField != null) { + return mField; + } + + RenderScriptGL rs = SceneManager.getRS(); + Resources res = SceneManager.getRes(); + if (rs == null || res == null) { + return null; + } + + mField = new ScriptField_Texture_s(rs, 1); + + if (loadNow) { + load(); + } else { + mData.texture = SceneManager.getDefaultTex2D(); + new SingleImageLoaderTask().execute(this); + } + + mField.set(mData, 0, true); + return mField; + } +} + + + + + 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..ba49d4e --- /dev/null +++ b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/TextureBase.java @@ -0,0 +1,57 @@ +/* + * 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.os.AsyncTask; +import android.content.res.Resources; +import android.renderscript.*; +import android.util.Log; + +/** + * @hide + */ +public abstract class TextureBase extends SceneGraphBase { + + class SingleImageLoaderTask extends AsyncTask<TextureBase, Void, Boolean> { + protected Boolean doInBackground(TextureBase... objects) { + TextureBase tex = objects[0]; + tex.load(); + return new Boolean(true); + } + protected void onPostExecute(Boolean result) { + } + } + + ScriptField_Texture_s.Item mData; + ScriptField_Texture_s mField; + TextureBase(int type) { + mData = new ScriptField_Texture_s.Item(); + mData.type = type; + } + + protected Allocation mRsTexture; + abstract ScriptField_Texture_s getRsData(boolean loadNow); + abstract void load(); +} + + + + + 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..12c81c2 --- /dev/null +++ b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/TextureCube.java @@ -0,0 +1,104 @@ +/* + * 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() { + super(ScriptC_export.const_TextureType_TEXTURE_CUBE); + } + + public TextureCube(Allocation tex) { + super(ScriptC_export.const_TextureType_TEXTURE_CUBE); + setTexture(tex); + } + + public TextureCube(String dir, String file) { + super(ScriptC_export.const_TextureType_TEXTURE_CUBE); + 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) { + mData.texture = tex != null ? tex : SceneManager.getDefaultTexCube(); + if (mField != null) { + mField.set_texture(0, mData.texture, true); + } + } + + void load() { + RenderScriptGL rs = SceneManager.getRS(); + Resources res = SceneManager.getRes(); + String shortName = mFileName.substring(mFileName.lastIndexOf('/') + 1); + setTexture(SceneManager.loadCubemap(mFileDir + shortName, rs, res)); + } + + ScriptField_Texture_s getRsData(boolean loadNow) { + if (mField != null) { + return mField; + } + + RenderScriptGL rs = SceneManager.getRS(); + Resources res = SceneManager.getRes(); + if (rs == null || res == null) { + return null; + } + + mField = new ScriptField_Texture_s(rs, 1); + + if (loadNow) { + load(); + } else { + mData.texture = SceneManager.getDefaultTexCube(); + new SingleImageLoaderTask().execute(this); + } + + mField.set(mData, 0, true); + return mField; + } +} + + + + + 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..e656ed2 --- /dev/null +++ b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/TextureParam.java @@ -0,0 +1,67 @@ +/* + * 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() { + mData.type = ScriptC_export.const_ShaderParam_TEXTURE; + if (mTexture != null) { + mData.texture = mTexture.getRsData(false).getAllocation(); + } + } +} + + + + + diff --git a/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/TextureRenderTarget.java b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/TextureRenderTarget.java new file mode 100644 index 0000000..6aa29a5 --- /dev/null +++ b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/TextureRenderTarget.java @@ -0,0 +1,69 @@ +/* + * 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 class TextureRenderTarget extends TextureBase { + public TextureRenderTarget() { + super(ScriptC_export.const_TextureType_TEXTURE_RENDER_TARGET); + } + + public TextureRenderTarget(Allocation tex) { + super(ScriptC_export.const_TextureType_TEXTURE_RENDER_TARGET); + setTexture(tex); + } + + public void setTexture(Allocation tex) { + mData.texture = tex; + if (mField != null) { + mField.set_texture(0, mData.texture, true); + } + } + + void load() { + } + + ScriptField_Texture_s getRsData(boolean loadNow) { + if (mField != null) { + return mField; + } + + RenderScriptGL rs = SceneManager.getRS(); + if (rs == null) { + return null; + } + + mField = new ScriptField_Texture_s(rs, 1); + mField.set(mData, 0, true); + return mField; + } +} + + + + + 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..b438a43 --- /dev/null +++ b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/export.rs @@ -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. + +#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; + +const int TextureType_TEXTURE_2D = TEXTURE_2D; +const int TextureType_TEXTURE_CUBE = TEXTURE_CUBE; +const int TextureType_TEXTURE_RENDER_TARGET = TEXTURE_RENDER_TARGET; + +SgTransform *exportPtr; +SgTransformComponent *componentPtr; +SgRenderState *sExport; +SgRenderable *drExport; +SgRenderPass *pExport; +SgCamera *exportPtrCam; +SgLight *exportPtrLight; +SgShaderParam *spExport; +SgShaderParamData *spDataExport; +SgVertexShader *pvExport; +SgFragmentShader *pfExport; +SgTexture *texExport; 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..7202285 --- /dev/null +++ b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/fragment_params.rs @@ -0,0 +1,30 @@ +// 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); + processTextureParams(shader); +} 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..575794b --- /dev/null +++ b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/params.rsh @@ -0,0 +1,193 @@ +// 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) { + rsDebug("____________ Param ____________", p); + printName(pData->paramName); + rsDebug("bufferOffset", p->bufferOffset); + rsDebug("type ", pData->type); + rsDebug("data timestamp ", pData->timestamp); + rsDebug("param timestamp", p->dataTimestamp); + + 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, + SgFragmentShader *shader) { + 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 = NULL; + const SgTexture *tex = NULL; + if (pData->type == SHADER_PARAM_TEXTURE) { + tex = rsGetElementAt(pData->texture, 0); + } else { + dataPtr = constantBuffer + p->bufferOffset; + } + + switch (pData->type) { + case SHADER_PARAM_TEXTURE: + rsgBindTexture(shader->program, p->bufferOffset, tex->texture); + break; + 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); +#endif // DEBUG_PARAMS + updated = processParam(current, currentData, constantBuffer, camera, NULL) || updated; + } + } +} + +static void processTextureParams(SgFragmentShader *shader) { + int numParams = 0; + if (rsIsObject(shader->shaderTextureParams)) { + numParams = rsAllocationGetDimX(shader->shaderTextureParams); + } + for (int i = 0; i < numParams; i ++) { + SgShaderParam *current = (SgShaderParam*)rsGetElementAt(shader->shaderTextureParams, i); + SgShaderParamData *currentData = (SgShaderParamData*)rsGetElementAt(current->data, 0); +#ifdef DEBUG_PARAMS + debugParam(current, currentData); +#endif // DEBUG_PARAMS + processParam(current, currentData, NULL, NULL, shader); + } +} 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..d8d48b3 --- /dev/null +++ b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/render.rs @@ -0,0 +1,240 @@ +// 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_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 ++) { + const SgTexture *tex = rsGetElementAt(obj->pf_textures[i], 0); + rsgBindTexture(pf->program, i, tex->texture); + } + + 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 + if (rsIsObject(gCameras)) { + 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(); +} + +int root(void) { +#ifdef DEBUG_RENDERABLES + rsDebug("=============================================================================", 0); +#endif // DEBUG_RENDERABLES + + // first step is to update the transform hierachy + if (gRootNode && rsIsObject(gRootNode->children)) { + rsForEach(gTransformScript, gRootNode->children, nullAlloc, 0, 0); + } + + prepareCameras(); + prepareLights(); + + if (rsIsObject(gRenderPasses)) { + rsgClearDepth(1.0f); + 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); + + if (rsIsObject(gCameras)) { + rs_allocation *camAlloc = (rs_allocation*)rsGetElementAt(gCameras, 0); + updateActiveCamera(*camAlloc); + } + drawAllObjects(gRenderableObjects); + } + return 10; +} + +// 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..bdca3ab --- /dev/null +++ b/tests/RenderScriptTests/SceneGraph/src/com/android/scenegraph/scenegraph_objects.rsh @@ -0,0 +1,323 @@ +// 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 +#define TEXTURE_RENDER_TARGET 3 + +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; + // ShaderParam's that set textures + rs_allocation shaderTextureParams; + // 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..28f916c --- /dev/null +++ b/tests/RenderScriptTests/SceneGraph/src/com/android/testapp/FullscreenBlur.java @@ -0,0 +1,192 @@ +/*
+ * 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 TextureRenderTarget sRenderTargetBlur0Color;
+ static TextureRenderTarget sRenderTargetBlur0Depth;
+ static TextureRenderTarget sRenderTargetBlur1Color;
+ static TextureRenderTarget sRenderTargetBlur1Depth;
+ static TextureRenderTarget sRenderTargetBlur2Color;
+ static TextureRenderTarget 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;
+
+ static int targetWidth;
+ static int targetHeight;
+
+ // 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) {
+ targetWidth = w/8;
+ targetHeight = h/8;
+ Type.Builder b = new Type.Builder(rs, Element.RGBA_8888(rs));
+ Type renderType = b.setX(targetWidth).setY(targetHeight).create();
+ int usage = Allocation.USAGE_GRAPHICS_TEXTURE | Allocation.USAGE_GRAPHICS_RENDER_TARGET;
+ sRenderTargetBlur0Color = new TextureRenderTarget(Allocation.createTyped(rs, renderType, usage));
+ sRenderTargetBlur1Color = new TextureRenderTarget(Allocation.createTyped(rs, renderType, usage));
+ sRenderTargetBlur2Color = new TextureRenderTarget(Allocation.createTyped(rs, renderType, usage));
+
+ b = new Type.Builder(rs, Element.createPixel(rs, Element.DataType.UNSIGNED_16,
+ Element.DataKind.PIXEL_DEPTH));
+ renderType = b.setX(targetWidth).setY(targetHeight).create();
+ usage = Allocation.USAGE_GRAPHICS_RENDER_TARGET;
+ sRenderTargetBlur0Depth = new TextureRenderTarget(Allocation.createTyped(rs, renderType, usage));
+ sRenderTargetBlur1Depth = new TextureRenderTarget(Allocation.createTyped(rs, renderType, usage));
+ sRenderTargetBlur2Depth = new TextureRenderTarget(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, Camera cam, TextureRenderTarget color, TextureRenderTarget depth) {
+ RenderPass pass = new RenderPass();
+ pass.setColorTarget(color);
+ pass.setDepthTarget(depth);
+ pass.setShouldClearColor(false);
+ pass.setShouldClearDepth(false);
+ pass.setCamera(cam);
+ scene.appendRenderPass(pass);
+ return pass;
+ }
+
+ static void addBlurPasses(Scene scene, RenderScriptGL rs, Camera cam) {
+ 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, cam,
+ 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, cam,
+ sRenderTargetBlur2Color,
+ sRenderTargetBlur2Depth);
+ Renderable quad = sceneManager.getRenderableQuad("ScreenAlignedQuadS", selectCol);
+ quad.appendSourceParams(new TextureParam("color", sRenderTargetBlur0Color));
+ selectColorPass.appendRenderable(quad);
+
+ // Horizontal blur
+ RenderPass horizontalBlurPass = addPass(scene, cam,
+ sRenderTargetBlur1Color,
+ sRenderTargetBlur1Depth);
+ quad = sceneManager.getRenderableQuad("ScreenAlignedQuadH", hBlur);
+ quad.appendSourceParams(new TextureParam("color", sRenderTargetBlur2Color));
+ addOffsets(quad, 1.0f / (float)targetWidth);
+ horizontalBlurPass.appendRenderable(quad);
+
+ // Vertical Blur
+ RenderPass verticalBlurPass = addPass(scene, cam,
+ sRenderTargetBlur2Color,
+ sRenderTargetBlur2Depth);
+ quad = sceneManager.getRenderableQuad("ScreenAlignedQuadV", vBlur);
+ quad.appendSourceParams(new TextureParam("color", sRenderTargetBlur1Color));
+ addOffsets(quad, 1.0f / (float)targetHeight);
+ verticalBlurPass.appendRenderable(quad);
+ }
+
+ // Additively renders the blurred colors on top of the scene
+ static void addCompositePass(Scene scene, RenderScriptGL rs, Camera cam) {
+ 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, cam, null, null);
+ Renderable quad = sceneManager.getRenderableQuad("ScreenAlignedQuadComposite", drawTex);
+ quad.appendSourceParams(new TextureParam("color", 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..5bd8f0b --- /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 com.android.scenegraph.SceneManager; + +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) { + if (show) { + mRS.bindRootScript(mScript); + } else { + mRS.bindRootScript(SceneManager.getInstance().getRenderLoop()); + } + } + + // 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); + } +} 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..7bf7812 --- /dev/null +++ b/tests/RenderScriptTests/SceneGraph/src/com/android/testapp/TestAppRS.java @@ -0,0 +1,265 @@ +/* + * 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(); + + // 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, mTouchHandler.getCamera()); + } + + 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(mTouchHandler.getCamera()); + for (int i = 0; i < numDraw; i ++) { + mainPass.appendRenderable((Renderable)allDraw.get(i)); + } + mActiveScene.appendRenderPass(mainPass); + + if (mUseBlur) { + FullscreenBlur.addCompositePass(mActiveScene, mRS, mTouchHandler.getCamera()); + } + } + + 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; + mTouchHandler.init(mActiveScene); + 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); + } + + long start = System.currentTimeMillis(); + mActiveScene.initRS(); + 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..d8e48e8 --- /dev/null +++ b/tests/RenderScriptTests/SceneGraph/src/com/android/testapp/TouchHandler.java @@ -0,0 +1,114 @@ +/* + * 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; + + float mRotateXValue; + float mRotateYValue; + Float3 mDistValue; + Float3 mPosValue; + + CompoundTransform mCameraRig; + RotateComponent mRotateX; + RotateComponent mRotateY; + TranslateComponent mDist; + TranslateComponent mPosition; + Camera mCamera; + + public void init(Scene scene) { + // Some initial values for camera position + mRotateXValue = -20; + mRotateYValue = 45; + mDistValue = new Float3(0, 0, 45); + mPosValue = new Float3(0, 4, 0); + + mRotateX = new RotateComponent("RotateX", new Float3(1, 0, 0), mRotateXValue); + mRotateY = new RotateComponent("RotateY", new Float3(0, 1, 0), mRotateYValue); + mDist = new TranslateComponent("Distance", mDistValue); + mPosition = new TranslateComponent("Distance", mPosValue); + + // Make a camera transform we can manipulate + mCameraRig = new CompoundTransform(); + mCameraRig.setName("CameraRig"); + mCameraRig.addComponent(mPosition); + mCameraRig.addComponent(mRotateY); + mCameraRig.addComponent(mRotateX); + mCameraRig.addComponent(mDist); + scene.appendTransform(mCameraRig); + mCamera = new Camera(); + mCamera.setTransform(mCameraRig); + scene.appendCamera(mCamera); + } + + public Camera getCamera() { + return mCamera; + } + + 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(10.0f, Math.min(mDistValue.z, 150.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..997a1a7 --- /dev/null +++ b/tests/RenderScriptTests/SceneGraph/src/com/android/testapp/test_app.rs @@ -0,0 +1,86 @@ +// 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; + +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) { + rsgClearColor(1.0f, 1.0f, 1.0f, 1.0f); + rsgClearDepth(1.0f); + displayLoading(); + return 30; +} 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..81f773c 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 @@ public class RSTestCore { 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 @@ public class UnitTest extends Thread { 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); + } +} + |