Add API entry points for clipped kernels.

Change-Id: Idf474a5ac391c41e9215cd2f03e7f8c4bfb875fa
diff --git a/api/current.txt b/api/current.txt
index fcbe24f..caa3e0c 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -20098,6 +20098,7 @@
     method protected android.renderscript.Script.FieldID createFieldID(int, android.renderscript.Element);
     method protected android.renderscript.Script.KernelID createKernelID(int, int, android.renderscript.Element, android.renderscript.Element);
     method protected void forEach(int, android.renderscript.Allocation, android.renderscript.Allocation, android.renderscript.FieldPacker);
+    method protected void forEach(int, android.renderscript.Allocation, android.renderscript.Allocation, android.renderscript.FieldPacker, android.renderscript.Script.LaunchOptions);
     method protected void invoke(int);
     method protected void invoke(int, android.renderscript.FieldPacker);
     method public void setTimeZone(java.lang.String);
@@ -20138,13 +20139,18 @@
     method public int getXStart();
     method public int getYEnd();
     method public int getYStart();
-    method public void setX(int, int);
-    method public void setY(int, int);
+    method public int getZEnd();
+    method public int getZStart();
+    method public android.renderscript.Script.LaunchOptions setX(int, int);
+    method public android.renderscript.Script.LaunchOptions setY(int, int);
+    method public android.renderscript.Script.LaunchOptions setZ(int, int);
     field protected int strategy;
     field protected int xend;
     field protected int xstart;
     field protected int yend;
     field protected int ystart;
+    field protected int zend;
+    field protected int zstart;
   }
 
   public class ScriptC extends android.renderscript.Script {
diff --git a/graphics/java/android/renderscript/RenderScript.java b/graphics/java/android/renderscript/RenderScript.java
index 00e8769..50d888f 100644
--- a/graphics/java/android/renderscript/RenderScript.java
+++ b/graphics/java/android/renderscript/RenderScript.java
@@ -517,6 +517,8 @@
     }
     native void rsnScriptForEach(int con, int id, int slot, int ain, int aout, byte[] params);
     native void rsnScriptForEach(int con, int id, int slot, int ain, int aout);
+    native void rsnScriptForEachClipped(int con, int id, int slot, int ain, int aout, byte[] params,
+                                        int xstart, int xend, int ystart, int yend, int zstart, int zend);
     synchronized void nScriptForEach(int id, int slot, int ain, int aout, byte[] params) {
         validate();
         if (params == null) {
@@ -525,6 +527,13 @@
             rsnScriptForEach(mContext, id, slot, ain, aout, params);
         }
     }
+
+    synchronized void nScriptForEachClipped(int id, int slot, int ain, int aout, byte[] params,
+                                            int xstart, int xend, int ystart, int yend, int zstart, int zend) {
+        validate();
+        rsnScriptForEachClipped(mContext, id, slot, ain, aout, params, xstart, xend, ystart, yend, zstart, zend);
+    }
+
     native void rsnScriptInvokeV(int con, int id, int slot, byte[] params);
     synchronized void nScriptInvokeV(int id, int slot, byte[] params) {
         validate();
diff --git a/graphics/java/android/renderscript/Script.java b/graphics/java/android/renderscript/Script.java
index fe80967..b53ba0d 100644
--- a/graphics/java/android/renderscript/Script.java
+++ b/graphics/java/android/renderscript/Script.java
@@ -166,6 +166,25 @@
         mRS.nScriptForEach(getID(mRS), slot, in_id, out_id, params);
     }
 
+    protected void forEach(int slot, Allocation ain, Allocation aout, FieldPacker v, LaunchOptions sc) {
+        if (ain == null && aout == null) {
+            throw new RSIllegalArgumentException(
+                "At least one of ain or aout is required to be non-null.");
+        }
+        int in_id = 0;
+        if (ain != null) {
+            in_id = ain.getID(mRS);
+        }
+        int out_id = 0;
+        if (aout != null) {
+            out_id = aout.getID(mRS);
+        }
+        byte[] params = null;
+        if (v != null) {
+            params = v.getData();
+        }
+        mRS.nScriptForEachClipped(getID(mRS), slot, in_id, out_id, params, sc.xstart, sc.xend, sc.ystart, sc.yend, sc.zstart, sc.zend);
+    }
 
     Script(int id, RenderScript rs) {
         super(id, rs);
@@ -320,29 +339,43 @@
     }
 
     public static final class LaunchOptions {
-        protected int xstart = -1;
-        protected int ystart = -1;
-        protected int xend = -1 ;
-        protected int yend = -1;
+        protected int xstart = 0;
+        protected int ystart = 0;
+        protected int xend = 0;
+        protected int yend = 0;
+        protected int zstart = 0;
+        protected int zend = 0;
 
         protected int strategy;
 
-        public void setX(int xstartArg, int xendArg) {
+        public LaunchOptions setX(int xstartArg, int xendArg) {
             if (xstartArg < 0 || xendArg <= xstartArg) {
                 throw new RSIllegalArgumentException("Invalid dimensions");
             }
             xstart = xstartArg;
             xend = xendArg;
+            return this;
         }
 
-        public void setY(int ystartArg, int yendArg) {
+        public LaunchOptions setY(int ystartArg, int yendArg) {
             if (ystartArg < 0 || yendArg <= ystartArg) {
                 throw new RSIllegalArgumentException("Invalid dimensions");
             }
             ystart = ystartArg;
             yend = yendArg;
+            return this;
         }
 
+        public LaunchOptions setZ(int zstartArg, int zendArg) {
+            if (zstartArg < 0 || zendArg <= zstartArg) {
+                throw new RSIllegalArgumentException("Invalid dimensions");
+            }
+            zstart = zstartArg;
+            zend = zendArg;
+            return this;
+        }
+
+
         public int getXStart() {
             return xstart;
         }
@@ -355,6 +388,12 @@
         public int getYEnd() {
             return yend;
         }
+        public int getZStart() {
+            return zstart;
+        }
+        public int getZEnd() {
+            return zend;
+        }
 
     }
 }
diff --git a/graphics/jni/android_renderscript_RenderScript.cpp b/graphics/jni/android_renderscript_RenderScript.cpp
index 80001a6..9a8a6e8 100644
--- a/graphics/jni/android_renderscript_RenderScript.cpp
+++ b/graphics/jni/android_renderscript_RenderScript.cpp
@@ -1039,7 +1039,7 @@
                jint script, jint slot, jint ain, jint aout)
 {
     LOG_API("nScriptForEach, con(%p), s(%p), slot(%i)", con, (void *)script, slot);
-    rsScriptForEach(con, (RsScript)script, slot, (RsAllocation)ain, (RsAllocation)aout, NULL, 0);
+    rsScriptForEach(con, (RsScript)script, slot, (RsAllocation)ain, (RsAllocation)aout, NULL, 0, NULL, 0);
 }
 static void
 nScriptForEachV(JNIEnv *_env, jobject _this, RsContext con,
@@ -1048,10 +1048,32 @@
     LOG_API("nScriptForEach, con(%p), s(%p), slot(%i)", con, (void *)script, slot);
     jint len = _env->GetArrayLength(params);
     jbyte *ptr = _env->GetByteArrayElements(params, NULL);
-    rsScriptForEach(con, (RsScript)script, slot, (RsAllocation)ain, (RsAllocation)aout, ptr, len);
+    rsScriptForEach(con, (RsScript)script, slot, (RsAllocation)ain, (RsAllocation)aout, ptr, len, NULL, 0);
     _env->ReleaseByteArrayElements(params, ptr, JNI_ABORT);
 }
 
+static void
+nScriptForEachClipped(JNIEnv *_env, jobject _this, RsContext con,
+                      jint script, jint slot, jint ain, jint aout,
+                      jbyteArray params, jint xstart, jint xend,
+                      jint ystart, jint yend, jint zstart, jint zend)
+{
+    LOG_API("nScriptForEachClipped, con(%p), s(%p), slot(%i)", con, (void *)script, slot);
+    jint len = _env->GetArrayLength(params);
+    jbyte *ptr = _env->GetByteArrayElements(params, NULL);
+    RsScriptCall sc;
+    sc.xStart = xstart;
+    sc.xEnd = xend;
+    sc.yStart = ystart;
+    sc.yEnd = yend;
+    sc.zStart = zstart;
+    sc.zEnd = zend;
+    sc.strategy = RS_FOR_EACH_STRATEGY_DONT_CARE;
+    sc.arrayStart = 0;
+    sc.arrayEnd = 0;
+    rsScriptForEach(con, (RsScript)script, slot, (RsAllocation)ain, (RsAllocation)aout, ptr, len, &sc, sizeof(sc));
+    _env->ReleaseByteArrayElements(params, ptr, JNI_ABORT);
+}
 
 // -----------------------------------
 
@@ -1514,6 +1536,7 @@
 {"rsnScriptInvokeV",                 "(III[B)V",                              (void*)nScriptInvokeV },
 {"rsnScriptForEach",                 "(IIIII)V",                              (void*)nScriptForEach },
 {"rsnScriptForEach",                 "(IIIII[B)V",                            (void*)nScriptForEachV },
+{"rsnScriptForEachClipped",          "(IIIII[BIIIIII)V",                      (void*)nScriptForEachClipped },
 {"rsnScriptSetVarI",                 "(IIII)V",                               (void*)nScriptSetVarI },
 {"rsnScriptSetVarJ",                 "(IIIJ)V",                               (void*)nScriptSetVarJ },
 {"rsnScriptSetVarF",                 "(IIIF)V",                               (void*)nScriptSetVarF },