adding getters to Sampler ProgramRaster, ProgramStore, Element.
Element adds ability to get subelement info. Tests for new stuff.

Change-Id: I4a77b91e4e0e73c95ab28b42c50732a64e71e7b9
diff --git a/graphics/java/android/renderscript/Element.java b/graphics/java/android/renderscript/Element.java
index f844331..8a9ca85 100644
--- a/graphics/java/android/renderscript/Element.java
+++ b/graphics/java/android/renderscript/Element.java
@@ -46,13 +46,18 @@
     Element[] mElements;
     String[] mElementNames;
     int[] mArraySizes;
+    int[] mOffsetInBytes;
 
     DataType mType;
     DataKind mKind;
     boolean mNormalized;
     int mVectorSize;
 
-    int getSizeBytes() {return mSize;}
+    /**
+    * @hide
+    * @return element size in bytes
+    */
+    public int getSizeBytes() {return mSize;}
 
 
     /**
@@ -152,6 +157,77 @@
     }
 
     /**
+    * @hide
+    * @return number of sub-elements in this element
+    */
+    public int getSubElementCount() {
+        if (mElements == null) {
+            return 0;
+        }
+        return mElements.length;
+    }
+
+    /**
+    * @hide
+    * @param index index of the sub-element to return
+    * @return sub-element in this element at given index
+    */
+    public Element getSubElement(int index) {
+        if (mElements == null) {
+            throw new RSIllegalArgumentException("Element contains no sub-elements");
+        }
+        if (index < 0 || index >= mElements.length) {
+            throw new RSIllegalArgumentException("Illegal sub-element index");
+        }
+        return mElements[index];
+    }
+
+    /**
+    * @hide
+    * @param index index of the sub-element
+    * @return sub-element in this element at given index
+    */
+    public String getSubElementName(int index) {
+        if (mElements == null) {
+            throw new RSIllegalArgumentException("Element contains no sub-elements");
+        }
+        if (index < 0 || index >= mElements.length) {
+            throw new RSIllegalArgumentException("Illegal sub-element index");
+        }
+        return mElementNames[index];
+    }
+
+    /**
+    * @hide
+    * @param index index of the sub-element
+    * @return array size of sub-element in this element at given index
+    */
+    public int getSubElementArraySize(int index) {
+        if (mElements == null) {
+            throw new RSIllegalArgumentException("Element contains no sub-elements");
+        }
+        if (index < 0 || index >= mElements.length) {
+            throw new RSIllegalArgumentException("Illegal sub-element index");
+        }
+        return mArraySizes[index];
+    }
+
+    /**
+    * @hide
+    * @param index index of the sub-element
+    * @return offset in bytes of sub-element in this element at given index
+    */
+    public int getSubElementOffsetBytes(int index) {
+        if (mElements == null) {
+            throw new RSIllegalArgumentException("Element contains no sub-elements");
+        }
+        if (index < 0 || index >= mElements.length) {
+            throw new RSIllegalArgumentException("Illegal sub-element index");
+        }
+        return mOffsetInBytes[index];
+    }
+
+    /**
      * Utility function for returning an Element containing a single Boolean.
      *
      * @param rs Context to which the element will belong.
@@ -602,7 +678,9 @@
         mElements = e;
         mElementNames = n;
         mArraySizes = as;
+        mOffsetInBytes = new int[mElements.length];
         for (int ct = 0; ct < mElements.length; ct++ ) {
+            mOffsetInBytes[ct] = mSize;
             mSize += mElements[ct].mSize * mArraySizes[ct];
         }
     }
@@ -653,13 +731,16 @@
         if(numSubElements > 0) {
             mElements = new Element[numSubElements];
             mElementNames = new String[numSubElements];
+            mArraySizes = new int[numSubElements];
+            mOffsetInBytes = new int[numSubElements];
 
             int[] subElementIds = new int[numSubElements];
-            mRS.nElementGetSubElements(getID(), subElementIds, mElementNames);
+            mRS.nElementGetSubElements(getID(), subElementIds, mElementNames, mArraySizes);
             for(int i = 0; i < numSubElements; i ++) {
                 mElements[i] = new Element(subElementIds[i], mRS);
                 mElements[i].updateFromNative();
-                mSize += mElements[i].mSize;
+                mOffsetInBytes[i] = mSize;
+                mSize += mElements[i].mSize * mArraySizes[i];
             }
         }
 
diff --git a/graphics/java/android/renderscript/ProgramRaster.java b/graphics/java/android/renderscript/ProgramRaster.java
index 60d9698..93ee0ce 100644
--- a/graphics/java/android/renderscript/ProgramRaster.java
+++ b/graphics/java/android/renderscript/ProgramRaster.java
@@ -37,23 +37,32 @@
         }
     }
 
-    boolean mPointSmooth;
-    boolean mLineSmooth;
     boolean mPointSprite;
-    float mLineWidth;
     CullMode mCullMode;
 
     ProgramRaster(int id, RenderScript rs) {
         super(id, rs);
 
-        mLineWidth = 1.0f;
-        mPointSmooth = false;
-        mLineSmooth = false;
         mPointSprite = false;
-
         mCullMode = CullMode.BACK;
     }
 
+    /**
+     * @hide
+     * @return whether point sprites are enabled
+     */
+    public boolean getPointSpriteEnabled() {
+        return mPointSprite;
+    }
+
+    /**
+     * @hide
+     * @return cull mode
+     */
+    public CullMode getCullMode() {
+        return mCullMode;
+    }
+
     public static ProgramRaster CULL_BACK(RenderScript rs) {
         if(rs.mProgramRaster_CULL_BACK == null) {
             ProgramRaster.Builder builder = new ProgramRaster.Builder(rs);
@@ -105,7 +114,10 @@
         public ProgramRaster create() {
             mRS.validate();
             int id = mRS.nProgramRasterCreate(mPointSprite, mCullMode.mID);
-            return new ProgramRaster(id, mRS);
+            ProgramRaster programRaster = new ProgramRaster(id, mRS);
+            programRaster.mPointSprite = mPointSprite;
+            programRaster.mCullMode = mCullMode;
+            return programRaster;
         }
     }
 
diff --git a/graphics/java/android/renderscript/ProgramStore.java b/graphics/java/android/renderscript/ProgramStore.java
index fb7c8ca..677dadd 100644
--- a/graphics/java/android/renderscript/ProgramStore.java
+++ b/graphics/java/android/renderscript/ProgramStore.java
@@ -135,12 +135,93 @@
         }
     }
 
+    DepthFunc mDepthFunc;
+    boolean mDepthMask;
+    boolean mColorMaskR;
+    boolean mColorMaskG;
+    boolean mColorMaskB;
+    boolean mColorMaskA;
+    BlendSrcFunc mBlendSrc;
+    BlendDstFunc mBlendDst;
+    boolean mDither;
 
     ProgramStore(int id, RenderScript rs) {
         super(id, rs);
     }
 
     /**
+    * @hide
+    * @return depth function
+    */
+    public DepthFunc getDepthFunc() {
+        return mDepthFunc;
+    }
+
+    /**
+    * @hide
+    * @return whether depth writes are enabled
+    */
+    public boolean getDepthMaskEnabled() {
+        return mDepthMask;
+    }
+
+    /**
+    * @hide
+    * @return red color channel mask
+    */
+    public boolean getColorMaskREnabled() {
+        return mColorMaskR;
+    }
+
+    /**
+    * @hide
+    * @return green color channel mask
+    */
+    public boolean getColorMaskGEnabled() {
+        return mColorMaskG;
+    }
+
+    /**
+    * @hide
+    * @return blue color channel mask
+    */
+    public boolean getColorMaskBEnabled() {
+        return mColorMaskB;
+    }
+
+    /**
+    * @hide
+    * @return alpha channel mask
+    */
+    public boolean getColorMaskAEnabled() {
+        return mColorMaskA;
+    }
+
+    /**
+    * @hide
+    * @return source blend function
+    */
+    public BlendSrcFunc getBlendSrcFunc() {
+        return mBlendSrc;
+    }
+
+    /**
+    * @hide
+    * @return destination blend function
+    */
+    public BlendDstFunc getBlendDstFunc() {
+        return mBlendDst;
+    }
+
+    /**
+    * @hide
+    * @return whether dither is enabled
+    */
+    public boolean getDitherEnabled() {
+        return mDither;
+    }
+
+    /**
     * Returns a pre-defined program store object with the following
     * characteristics:
     *  - incoming pixels are drawn if their depth value is less than
@@ -340,7 +421,17 @@
             int id = mRS.nProgramStoreCreate(mColorMaskR, mColorMaskG, mColorMaskB, mColorMaskA,
                                              mDepthMask, mDither,
                                              mBlendSrc.mID, mBlendDst.mID, mDepthFunc.mID);
-            return new ProgramStore(id, mRS);
+            ProgramStore programStore = new ProgramStore(id, mRS);
+            programStore.mDepthFunc = mDepthFunc;
+            programStore.mDepthMask = mDepthMask;
+            programStore.mColorMaskR = mColorMaskR;
+            programStore.mColorMaskG = mColorMaskG;
+            programStore.mColorMaskB = mColorMaskB;
+            programStore.mColorMaskA = mColorMaskA;
+            programStore.mBlendSrc = mBlendSrc;
+            programStore.mBlendDst = mBlendDst;
+            programStore.mDither = mDither;
+            return programStore;
         }
     }
 
diff --git a/graphics/java/android/renderscript/RenderScript.java b/graphics/java/android/renderscript/RenderScript.java
index d3d65a3..1305633 100644
--- a/graphics/java/android/renderscript/RenderScript.java
+++ b/graphics/java/android/renderscript/RenderScript.java
@@ -210,10 +210,11 @@
         validate();
         rsnElementGetNativeData(mContext, id, elementData);
     }
-    native void rsnElementGetSubElements(int con, int id, int[] IDs, String[] names);
-    synchronized void nElementGetSubElements(int id, int[] IDs, String[] names) {
+    native void rsnElementGetSubElements(int con, int id,
+                                         int[] IDs, String[] names, int[] arraySizes);
+    synchronized void nElementGetSubElements(int id, int[] IDs, String[] names, int[] arraySizes) {
         validate();
-        rsnElementGetSubElements(mContext, id, IDs, names);
+        rsnElementGetSubElements(mContext, id, IDs, names, arraySizes);
     }
 
     native int rsnTypeCreate(int con, int eid, int x, int y, int z, boolean mips, boolean faces);
diff --git a/graphics/java/android/renderscript/Sampler.java b/graphics/java/android/renderscript/Sampler.java
index 98943a1..0a3c91d 100644
--- a/graphics/java/android/renderscript/Sampler.java
+++ b/graphics/java/android/renderscript/Sampler.java
@@ -47,11 +47,58 @@
         }
     }
 
+    Value mMin;
+    Value mMag;
+    Value mWrapS;
+    Value mWrapT;
+    Value mWrapR;
+    float mAniso;
+
     Sampler(int id, RenderScript rs) {
         super(id, rs);
     }
 
     /**
+     * @hide
+     * @return minification setting for the sampler
+     */
+    public Value getMinification() {
+        return mMin;
+    }
+
+    /**
+     * @hide
+     * @return magnification setting for the sampler
+     */
+    public Value getMagnification() {
+        return mMag;
+    }
+
+    /**
+     * @hide
+     * @return S wrapping mode for the sampler
+     */
+    public Value getWrapS() {
+        return mWrapS;
+    }
+
+    /**
+     * @hide
+     * @return T wrapping mode for the sampler
+     */
+    public Value getWrapT() {
+        return mWrapT;
+    }
+
+    /**
+     * @hide
+     * @return anisotropy setting for the sampler
+     */
+    public float getAnisotropy() {
+        return mAniso;
+    }
+
+    /**
      * Retrieve a sampler with min and mag set to nearest and wrap modes set to
      * clamp.
      *
@@ -241,8 +288,16 @@
 
         public Sampler create() {
             mRS.validate();
-            int id = mRS.nSamplerCreate(mMag.mID, mMin.mID, mWrapS.mID, mWrapT.mID, mWrapR.mID, mAniso);
-            return new Sampler(id, mRS);
+            int id = mRS.nSamplerCreate(mMag.mID, mMin.mID, 
+                                        mWrapS.mID, mWrapT.mID, mWrapR.mID, mAniso);
+            Sampler sampler = new Sampler(id, mRS);
+            sampler.mMin = mMin;
+            sampler.mMag = mMag;
+            sampler.mWrapS = mWrapS;
+            sampler.mWrapT = mWrapT;
+            sampler.mWrapR = mWrapR;
+            sampler.mAniso = mAniso;
+            return sampler;
         }
     }
 
diff --git a/graphics/jni/android_renderscript_RenderScript.cpp b/graphics/jni/android_renderscript_RenderScript.cpp
index ec1f8de..af03ee2 100644
--- a/graphics/jni/android_renderscript_RenderScript.cpp
+++ b/graphics/jni/android_renderscript_RenderScript.cpp
@@ -371,23 +371,29 @@
 
 
 static void
-nElementGetSubElements(JNIEnv *_env, jobject _this, RsContext con, jint id, jintArray _IDs, jobjectArray _names)
+nElementGetSubElements(JNIEnv *_env, jobject _this, RsContext con, jint id,
+                       jintArray _IDs,
+                       jobjectArray _names,
+                       jintArray _arraySizes)
 {
     int dataSize = _env->GetArrayLength(_IDs);
     LOG_API("nElementGetSubElements, con(%p)", con);
 
     uint32_t *ids = (uint32_t *)malloc((uint32_t)dataSize * sizeof(uint32_t));
     const char **names = (const char **)malloc((uint32_t)dataSize * sizeof(const char *));
+    uint32_t *arraySizes = (uint32_t *)malloc((uint32_t)dataSize * sizeof(uint32_t));
 
-    rsaElementGetSubElements(con, (RsElement)id, ids, names, (uint32_t)dataSize);
+    rsaElementGetSubElements(con, (RsElement)id, ids, names, arraySizes, (uint32_t)dataSize);
 
     for(jint i = 0; i < dataSize; i++) {
         _env->SetObjectArrayElement(_names, i, _env->NewStringUTF(names[i]));
         _env->SetIntArrayRegion(_IDs, i, 1, (const jint*)&ids[i]);
+        _env->SetIntArrayRegion(_arraySizes, i, 1, (const jint*)&arraySizes[i]);
     }
 
     free(ids);
     free(names);
+    free(arraySizes);
 }
 
 // -----------------------------------
@@ -1239,7 +1245,7 @@
 {"rsnElementCreate",                 "(IIIZI)I",                              (void*)nElementCreate },
 {"rsnElementCreate2",                "(I[I[Ljava/lang/String;[I)I",           (void*)nElementCreate2 },
 {"rsnElementGetNativeData",          "(II[I)V",                               (void*)nElementGetNativeData },
-{"rsnElementGetSubElements",         "(II[I[Ljava/lang/String;)V",            (void*)nElementGetSubElements },
+{"rsnElementGetSubElements",         "(II[I[Ljava/lang/String;[I)V",          (void*)nElementGetSubElements },
 
 {"rsnTypeCreate",                    "(IIIIIZZ)I",                            (void*)nTypeCreate },
 {"rsnTypeGetNativeData",             "(II[I)V",                               (void*)nTypeGetNativeData },
diff --git a/libs/rs/RenderScript.h b/libs/rs/RenderScript.h
index 3ba0123..6d54268 100644
--- a/libs/rs/RenderScript.h
+++ b/libs/rs/RenderScript.h
@@ -34,26 +34,30 @@
 RsFile rsaFileA3DCreateFromAsset(RsContext, void *asset);
 RsFile rsaFileA3DCreateFromFile(RsContext, const char *path);
 void rsaFileA3DGetNumIndexEntries(RsContext, int32_t *numEntries, RsFile);
-void rsaFileA3DGetIndexEntries(RsContext, RsFileIndexEntry *fileEntries,uint32_t numEntries, RsFile);
+void rsaFileA3DGetIndexEntries(RsContext, RsFileIndexEntry *fileEntries,
+                               uint32_t numEntries, RsFile);
 void rsaGetName(RsContext, void * obj, const char **name);
 // Mesh update functions
 void rsaMeshGetVertexBufferCount(RsContext, RsMesh, int32_t *vtxCount);
 void rsaMeshGetIndexCount(RsContext, RsMesh, int32_t *idxCount);
 void rsaMeshGetVertices(RsContext, RsMesh, RsAllocation *vtxData, uint32_t vtxDataCount);
-void rsaMeshGetIndices(RsContext, RsMesh, RsAllocation *va, uint32_t *primType, uint32_t idxDataCount);
+void rsaMeshGetIndices(RsContext, RsMesh, RsAllocation *va,
+                       uint32_t *primType, uint32_t idxDataCount);
 // Allocation update
 const void* rsaAllocationGetType(RsContext con, RsAllocation va);
 // Type update
 void rsaTypeGetNativeData(RsContext, RsType, uint32_t *typeData, uint32_t typeDataSize);
 // Element update
 void rsaElementGetNativeData(RsContext, RsElement, uint32_t *elemData, uint32_t elemDataSize);
-void rsaElementGetSubElements(RsContext, RsElement, uint32_t *ids, const char **names, uint32_t dataSize);
+void rsaElementGetSubElements(RsContext, RsElement, uint32_t *ids, const char **names,
+                              uint32_t *arraySizes, uint32_t dataSize);
 
 RsDevice rsDeviceCreate();
 void rsDeviceDestroy(RsDevice dev);
 void rsDeviceSetConfig(RsDevice dev, RsDeviceParam p, int32_t value);
 RsContext rsContextCreate(RsDevice dev, uint32_t version, uint32_t sdkVersion);
-RsContext rsContextCreateGL(RsDevice dev, uint32_t version, uint32_t sdkVersion, RsSurfaceConfig sc, uint32_t dpi);
+RsContext rsContextCreateGL(RsDevice dev, uint32_t version, uint32_t sdkVersion,
+                            RsSurfaceConfig sc, uint32_t dpi);
 
 #include "rsgApiFuncDecl.h"
 
diff --git a/libs/rs/rsElement.cpp b/libs/rs/rsElement.cpp
index d6ab0da..71e1b91 100644
--- a/libs/rs/rsElement.cpp
+++ b/libs/rs/rsElement.cpp
@@ -364,7 +364,7 @@
 }
 
 void rsaElementGetSubElements(RsContext con, RsElement elem, uint32_t *ids,
-                              const char **names, uint32_t dataSize) {
+                              const char **names, uint32_t *arraySizes, uint32_t dataSize) {
     Element *e = static_cast<Element *>(elem);
     rsAssert(e->getFieldCount() == dataSize);
 
@@ -372,5 +372,6 @@
         e->getField(i)->incUserRef();
         ids[i] = (uint32_t)e->getField(i);
         names[i] = e->getFieldName(i);
+        arraySizes[i] = e->getFieldArraySize(i);
     }
 }
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
index 1fbf97a..2bfb6b1 100644
--- 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
@@ -25,6 +25,9 @@
 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;
@@ -39,20 +42,41 @@
 
     private void initializeGlobals(RenderScript RS, ScriptC_program_raster s) {
         ProgramRaster.Builder b = getDefaultBuilder(RS);
-        s.set_pointSpriteEnabled(b.setPointSpriteEnabled(true).create());
+        pointSpriteEnabled = b.setPointSpriteEnabled(true).create();
         b = getDefaultBuilder(RS);
-        s.set_cullMode(b.setCullMode(CullMode.FRONT).create());
-        return;
+        cullMode = b.setCullMode(CullMode.FRONT).create();
+
+        s.set_pointSpriteEnabled(pointSpriteEnabled);
+        s.set_cullMode(cullMode);
     }
 
-    public void run() {
-        RenderScript pRS = RenderScript.create(mCtx);
+    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);
+
+        updateUI();
+    }
+
+    public void run() {
+        RenderScript pRS = RenderScript.create(mCtx);
+        testScriptSide(pRS);
+        testJavaSide(pRS);
         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
index e06112c..72a401d 100644
--- 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
@@ -27,6 +27,16 @@
 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;
@@ -44,44 +54,122 @@
 
     private void initializeGlobals(RenderScript RS, ScriptC_program_store s) {
         ProgramStore.Builder b = getDefaultBuilder(RS);
-        s.set_ditherEnable(b.setDitherEnabled(true).create());
+        ditherEnable = b.setDitherEnabled(true).create();
 
         b = getDefaultBuilder(RS);
-        s.set_colorRWriteEnable(b.setColorMaskEnabled(true,  false, false, false).create());
+        colorRWriteEnable = b.setColorMaskEnabled(true,  false, false, false).create();
 
         b = getDefaultBuilder(RS);
-        s.set_colorGWriteEnable(b.setColorMaskEnabled(false, true,  false, false).create());
+        colorGWriteEnable = b.setColorMaskEnabled(false, true,  false, false).create();
 
         b = getDefaultBuilder(RS);
-        s.set_colorBWriteEnable(b.setColorMaskEnabled(false, false, true,  false).create());
+        colorBWriteEnable = b.setColorMaskEnabled(false, false, true,  false).create();
 
         b = getDefaultBuilder(RS);
-        s.set_colorAWriteEnable(b.setColorMaskEnabled(false, false, false, true).create());
+        colorAWriteEnable = b.setColorMaskEnabled(false, false, false, true).create();
 
         b = getDefaultBuilder(RS);
-        s.set_blendSrc(b.setBlendFunc(ProgramStore.BlendSrcFunc.DST_COLOR,
-                                      ProgramStore.BlendDstFunc.ZERO).create());
+        blendSrc = b.setBlendFunc(ProgramStore.BlendSrcFunc.DST_COLOR,
+                                  ProgramStore.BlendDstFunc.ZERO).create();
 
         b = getDefaultBuilder(RS);
-        s.set_blendDst(b.setBlendFunc(ProgramStore.BlendSrcFunc.ZERO,
-                                      ProgramStore.BlendDstFunc.DST_ALPHA).create());
+        blendDst = b.setBlendFunc(ProgramStore.BlendSrcFunc.ZERO,
+                                  ProgramStore.BlendDstFunc.DST_ALPHA).create();
 
         b = getDefaultBuilder(RS);
-        s.set_depthWriteEnable(b.setDepthMaskEnabled(true).create());
+        depthWriteEnable = b.setDepthMaskEnabled(true).create();
 
         b = getDefaultBuilder(RS);
-        s.set_depthFunc(b.setDepthFunc(ProgramStore.DepthFunc.GREATER).create());
-        return;
+        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);
     }
 
-    public void run() {
-        RenderScript pRS = RenderScript.create(mCtx);
+    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
index b0ccf9d..030b3ff 100644
--- a/tests/RenderScriptTests/tests/src/com/android/rs/test/UT_sampler.java
+++ b/tests/RenderScriptTests/tests/src/com/android/rs/test/UT_sampler.java
@@ -25,6 +25,12 @@
 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;
@@ -43,34 +49,103 @@
     private void initializeGlobals(RenderScript RS, ScriptC_sampler s) {
         Sampler.Builder b = getDefaultBuilder(RS);
         b.setMinification(Value.LINEAR_MIP_LINEAR);
-        s.set_minification(b.create());
+        minification = b.create();
 
         b = getDefaultBuilder(RS);
         b.setMagnification(Value.LINEAR);
-        s.set_magnification(b.create());
+        magnification = b.create();
 
         b = getDefaultBuilder(RS);
         b.setWrapS(Value.WRAP);
-        s.set_wrapS(b.create());
+        wrapS = b.create();
 
         b = getDefaultBuilder(RS);
         b.setWrapT(Value.WRAP);
-        s.set_wrapT(b.create());
+        wrapT = b.create();
 
         b = getDefaultBuilder(RS);
         b.setAnisotropy(8.0f);
-        s.set_anisotropy(b.create());
-        return;
+        anisotropy = b.create();
+
+        s.set_minification(minification);
+        s.set_magnification(magnification);
+        s.set_wrapS(wrapS);
+        s.set_wrapT(wrapT);
+        s.set_anisotropy(anisotropy);
     }
 
-    public void run() {
-        RenderScript pRS = RenderScript.create(mCtx);
+    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);
+
+        updateUI();
+    }
+
+    public void run() {
+        RenderScript pRS = RenderScript.create(mCtx);
+        testScriptSide(pRS);
+        testJavaSide(pRS);
         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 6151431..a97ffa7 100644
--- a/tests/RenderScriptTests/tests/src/com/android/rs/test/UnitTest.java
+++ b/tests/RenderScriptTests/tests/src/com/android/rs/test/UnitTest.java
@@ -16,6 +16,7 @@
 
 package com.android.rs.test;
 import android.content.Context;
+import android.util.Log;
 import android.renderscript.RenderScript.RSMessageHandler;
 
 public class UnitTest extends Thread {
@@ -55,6 +56,28 @@
         this (null, ctx);
     }
 
+    protected void _RS_ASSERT(String message, boolean b) {
+        if(b == false) {
+            result = -1;
+            Log.e(name, message + " FAILED");
+        }
+    }
+
+    protected void updateUI() {
+        if (mItem != null) {
+            mItem.result = result;
+            msgHandled = true;
+            try {
+                mRSTC.refreshTestResults();
+            }
+            catch (IllegalStateException e) {
+                /* Ignore the case where our message receiver has been
+                   disconnected. This happens when we leave the application
+                   before it finishes running all of the unit tests. */
+            }
+        }
+    }
+
     protected RSMessageHandler mRsMessage = new RSMessageHandler() {
         public void run() {
             if (result == 0) {
@@ -71,18 +94,7 @@
                 }
             }
 
-            if (mItem != null) {
-                mItem.result = result;
-                msgHandled = true;
-                try {
-                    mRSTC.refreshTestResults();
-                }
-                catch (IllegalStateException e) {
-                    /* Ignore the case where our message receiver has been
-                       disconnected. This happens when we leave the application
-                       before it finishes running all of the unit tests. */
-                }
-            }
+            updateUI();
         }
     };