Merge "Start implementing SurfaceTexture streaming into RS allocations."
diff --git a/graphics/java/android/renderscript/Allocation.java b/graphics/java/android/renderscript/Allocation.java
index 11c2427..509b972 100644
--- a/graphics/java/android/renderscript/Allocation.java
+++ b/graphics/java/android/renderscript/Allocation.java
@@ -22,6 +22,7 @@
 import android.content.res.AssetManager;
 import android.graphics.Bitmap;
 import android.graphics.BitmapFactory;
+import android.graphics.SurfaceTexture;
 import android.util.Log;
 import android.util.TypedValue;
 
@@ -78,6 +79,8 @@
     boolean mConstrainedFace;
     boolean mConstrainedY;
     boolean mConstrainedZ;
+    boolean mReadAllowed = true;
+    boolean mWriteAllowed = true;
     int mSelectedY;
     int mSelectedZ;
     int mSelectedLOD;
@@ -127,6 +130,32 @@
      */
     public static final int USAGE_GRAPHICS_RENDER_TARGET = 0x0010;
 
+    /**
+     * USAGE_GRAPHICS_SURFACE_TEXTURE_INPUT The allcation will be
+     * used with a SurfaceTexture object.  This usage will cause the
+     * allocation to be created read only.
+     *
+     * @hide
+     */
+    public static final int USAGE_GRAPHICS_SURFACE_TEXTURE_INPUT_OPAQUE = 0x0020;
+
+    /**
+     * USAGE_GRAPHICS_SURFACE_TEXTURE_INPUT The allcation will be
+     * used with a SurfaceTexture object.  This usage will cause the
+     * allocation to be created read only.
+     *
+     * @hide
+     */
+
+    public static final int USAGE_IO_INPUT = 0x0040;
+    /**
+     * USAGE_GRAPHICS_SURFACE_TEXTURE_INPUT The allcation will be
+     * used with a SurfaceTexture object.  This usage will cause the
+     * allocation to be created read only.
+     *
+     * @hide
+     */
+    public static final int USAGE_IO_OUTPUT = 0x0080;
 
     /**
      * Controls mipmap behavior when using the bitmap creation and
@@ -187,10 +216,26 @@
                        USAGE_GRAPHICS_TEXTURE |
                        USAGE_GRAPHICS_VERTEX |
                        USAGE_GRAPHICS_CONSTANTS |
-                       USAGE_GRAPHICS_RENDER_TARGET)) != 0) {
+                       USAGE_GRAPHICS_RENDER_TARGET |
+                       USAGE_GRAPHICS_SURFACE_TEXTURE_INPUT_OPAQUE |
+                       USAGE_IO_INPUT |
+                       USAGE_IO_OUTPUT)) != 0) {
             throw new RSIllegalArgumentException("Unknown usage specified.");
         }
+
+        if ((usage & (USAGE_GRAPHICS_SURFACE_TEXTURE_INPUT_OPAQUE | USAGE_IO_INPUT)) != 0) {
+            mWriteAllowed = false;
+
+            if ((usage & ~(USAGE_GRAPHICS_SURFACE_TEXTURE_INPUT_OPAQUE |
+                           USAGE_IO_INPUT |
+                           USAGE_GRAPHICS_TEXTURE |
+                           USAGE_SCRIPT)) != 0) {
+                throw new RSIllegalArgumentException("Invalid usage combination.");
+            }
+        }
+
         mType = t;
+        mUsage = usage;
 
         if (t != null) {
             updateCacheInfo(t);
@@ -1006,6 +1051,23 @@
     }
 
     /**
+     *
+     *
+     * @hide
+     *
+     */
+    public SurfaceTexture getSurfaceTexture() {
+        if ((mUsage & USAGE_GRAPHICS_SURFACE_TEXTURE_INPUT_OPAQUE) == 0) {
+            throw new RSInvalidStateException("Allocation is not a surface texture.");
+        }
+
+        int id = mRS.nAllocationGetSurfaceTextureID(getID());
+        return new SurfaceTexture(id);
+
+    }
+
+
+    /**
      * Creates a non-mipmapped renderscript allocation to use as a
      * graphics texture
      *
diff --git a/graphics/java/android/renderscript/RenderScript.java b/graphics/java/android/renderscript/RenderScript.java
index bfe412c..3f3033b 100644
--- a/graphics/java/android/renderscript/RenderScript.java
+++ b/graphics/java/android/renderscript/RenderScript.java
@@ -269,6 +269,12 @@
         validate();
         rsnAllocationSyncAll(mContext, alloc, src);
     }
+    native int rsnAllocationGetSurfaceTextureID(int con, int alloc);
+    synchronized int nAllocationGetSurfaceTextureID(int alloc) {
+        validate();
+        return rsnAllocationGetSurfaceTextureID(mContext, alloc);
+    }
+
     native void rsnAllocationGenerateMipmaps(int con, int alloc);
     synchronized void nAllocationGenerateMipmaps(int alloc) {
         validate();
diff --git a/graphics/jni/android_renderscript_RenderScript.cpp b/graphics/jni/android_renderscript_RenderScript.cpp
index 9622bd2..a9f0f1f 100644
--- a/graphics/jni/android_renderscript_RenderScript.cpp
+++ b/graphics/jni/android_renderscript_RenderScript.cpp
@@ -443,6 +443,13 @@
     rsAllocationSyncAll(con, (RsAllocation)a, (RsAllocationUsageType)bits);
 }
 
+static jint
+nAllocationGetSurfaceTextureID(JNIEnv *_env, jobject _this, RsContext con, jint a)
+{
+    LOG_API("nAllocationGetSurfaceTextureID, con(%p), a(%p)", con, (RsAllocation)a);
+    return rsAllocationGetSurfaceTextureID(con, (RsAllocation)a);
+}
+
 static void
 nAllocationGenerateMipmaps(JNIEnv *_env, jobject _this, RsContext con, jint alloc)
 {
@@ -1258,6 +1265,7 @@
 {"rsnAllocationCopyToBitmap",        "(IILandroid/graphics/Bitmap;)V",        (void*)nAllocationCopyToBitmap },
 
 {"rsnAllocationSyncAll",             "(III)V",                                (void*)nAllocationSyncAll },
+{"rsnAllocationGetSurfaceTextureID", "(II)I",                                 (void*)nAllocationGetSurfaceTextureID },
 {"rsnAllocationData1D",              "(IIIII[II)V",                           (void*)nAllocationData1D_i },
 {"rsnAllocationData1D",              "(IIIII[SI)V",                           (void*)nAllocationData1D_s },
 {"rsnAllocationData1D",              "(IIIII[BI)V",                           (void*)nAllocationData1D_b },
diff --git a/libs/rs/RenderScriptDefines.h b/libs/rs/RenderScriptDefines.h
index d092520..5b0a3da 100644
--- a/libs/rs/RenderScriptDefines.h
+++ b/libs/rs/RenderScriptDefines.h
@@ -99,8 +99,11 @@
     RS_ALLOCATION_USAGE_GRAPHICS_VERTEX = 0x0004,
     RS_ALLOCATION_USAGE_GRAPHICS_CONSTANTS = 0x0008,
     RS_ALLOCATION_USAGE_GRAPHICS_RENDER_TARGET = 0x0010,
+    RS_ALLOCATION_USAGE_GRAPHICS_SURFACE_TEXTURE_INPUT_OPAQUE = 0x0020,
+    RS_ALLOCATION_USAGE_IO_INPUT = 0x0040,
+    RS_ALLOCATION_USAGE_IO_OUTPUT = 0x0080,
 
-    RS_ALLOCATION_USAGE_ALL = 0x000F
+    RS_ALLOCATION_USAGE_ALL = 0x00FF
 };
 
 enum RsAllocationMipmapControl {
diff --git a/libs/rs/driver/rsdAllocation.cpp b/libs/rs/driver/rsdAllocation.cpp
index 1f70e66..fac40f2 100644
--- a/libs/rs/driver/rsdAllocation.cpp
+++ b/libs/rs/driver/rsdAllocation.cpp
@@ -134,6 +134,13 @@
 static void UploadToTexture(const Context *rsc, const Allocation *alloc) {
     DrvAllocation *drv = (DrvAllocation *)alloc->mHal.drv;
 
+    if (alloc->mHal.state.usageFlags & RS_ALLOCATION_USAGE_GRAPHICS_SURFACE_TEXTURE_INPUT_OPAQUE) {
+        if (!drv->textureID) {
+            RSD_CALL_GL(glGenTextures, 1, &drv->textureID);
+        }
+        return;
+    }
+
     if (!drv->glType || !drv->glFormat) {
         return;
     }
@@ -370,6 +377,12 @@
     drv->uploadDeferred = true;
 }
 
+int32_t rsdAllocationInitSurfaceTexture(const Context *rsc, const Allocation *alloc) {
+    DrvAllocation *drv = (DrvAllocation *)alloc->mHal.drv;
+    UploadToTexture(rsc, alloc);
+    return drv->textureID;
+}
+
 void rsdAllocationData1D(const Context *rsc, const Allocation *alloc,
                          uint32_t xoff, uint32_t lod, uint32_t count,
                          const void *data, uint32_t sizeBytes) {
diff --git a/libs/rs/driver/rsdAllocation.h b/libs/rs/driver/rsdAllocation.h
index 4fc4419..230804b 100644
--- a/libs/rs/driver/rsdAllocation.h
+++ b/libs/rs/driver/rsdAllocation.h
@@ -67,6 +67,8 @@
                           RsAllocationUsageType src);
 void rsdAllocationMarkDirty(const android::renderscript::Context *rsc,
                             const android::renderscript::Allocation *alloc);
+int32_t rsdAllocationInitSurfaceTexture(const android::renderscript::Context *rsc,
+                                        const android::renderscript::Allocation *alloc);
 
 void rsdAllocationData1D(const android::renderscript::Context *rsc,
                          const android::renderscript::Allocation *alloc,
diff --git a/libs/rs/driver/rsdCore.cpp b/libs/rs/driver/rsdCore.cpp
index 1a535d0..9987027 100644
--- a/libs/rs/driver/rsdCore.cpp
+++ b/libs/rs/driver/rsdCore.cpp
@@ -72,6 +72,7 @@
         rsdAllocationResize,
         rsdAllocationSyncAll,
         rsdAllocationMarkDirty,
+        rsdAllocationInitSurfaceTexture,
         rsdAllocationData1D,
         rsdAllocationData2D,
         rsdAllocationData3D,
diff --git a/libs/rs/driver/rsdShader.cpp b/libs/rs/driver/rsdShader.cpp
index c70193ae..482f3b8 100644
--- a/libs/rs/driver/rsdShader.cpp
+++ b/libs/rs/driver/rsdShader.cpp
@@ -143,7 +143,12 @@
     char buf[256];
     for (uint32_t ct=0; ct < mRSProgram->mHal.state.texturesCount; ct++) {
         if (mRSProgram->mHal.state.textureTargets[ct] == RS_TEXTURE_2D) {
-            snprintf(buf, sizeof(buf), "uniform sampler2D UNI_Tex%i;\n", ct);
+            Allocation *a = mRSProgram->mHal.state.textures[ct];
+            if (a && a->mHal.state.surfaceTextureID) {
+                snprintf(buf, sizeof(buf), "uniform samplerExternalOES UNI_Tex%i;\n", ct);
+            } else {
+                snprintf(buf, sizeof(buf), "uniform sampler2D UNI_Tex%i;\n", ct);
+            }
             mTextureTargets[ct] = GL_TEXTURE_2D;
         } else {
             snprintf(buf, sizeof(buf), "uniform samplerCube UNI_Tex%i;\n", ct);
diff --git a/libs/rs/driver/rsdShaderCache.h b/libs/rs/driver/rsdShaderCache.h
index 17ee3e8..d64780b 100644
--- a/libs/rs/driver/rsdShaderCache.h
+++ b/libs/rs/driver/rsdShaderCache.h
@@ -108,6 +108,7 @@
             }
             if (numFragUnis) {
                 fragUniforms = new UniformData[numFragUnis];
+                fragUniformIsSTO = new bool[numFragUnis];
             }
         }
         ~ProgramEntry() {
@@ -123,6 +124,10 @@
                 delete[] fragUniforms;
                 fragUniforms = NULL;
             }
+            if (fragUniformIsSTO) {
+                delete[] fragUniformIsSTO;
+                fragUniformIsSTO = NULL;
+            }
         }
         uint32_t vtx;
         uint32_t frag;
@@ -131,6 +136,7 @@
         AttrData *vtxAttrs;
         UniformData *vtxUniforms;
         UniformData *fragUniforms;
+        bool *fragUniformIsSTO;
     };
     android::Vector<ProgramEntry*> mEntries;
     ProgramEntry *mCurrent;
diff --git a/libs/rs/rs.spec b/libs/rs/rs.spec
index ffb1196..09a2986 100644
--- a/libs/rs/rs.spec
+++ b/libs/rs/rs.spec
@@ -63,7 +63,10 @@
     ret RsAllocation
 }
 
-
+AllocationGetSurfaceTextureID {
+    param RsAllocation alloc
+    ret int32_t
+}
 
 ContextFinish {
 	sync
diff --git a/libs/rs/rsAllocation.cpp b/libs/rs/rsAllocation.cpp
index fd85b07..5f45abf 100644
--- a/libs/rs/rsAllocation.cpp
+++ b/libs/rs/rsAllocation.cpp
@@ -413,6 +413,12 @@
     ALOGE("not implemented");
 }
 
+int32_t Allocation::getSurfaceTextureID(const Context *rsc) {
+    int32_t id = rsc->mHal.funcs.allocation.initSurfaceTexture(rsc, this);
+    mHal.state.surfaceTextureID = id;
+    return id;
+}
+
 /////////////////
 //
 
@@ -658,6 +664,11 @@
                                            (RsAllocationCubemapFace)srcFace);
 }
 
+int32_t rsi_AllocationGetSurfaceTextureID(Context *rsc, RsAllocation valloc) {
+    Allocation *alloc = static_cast<Allocation *>(valloc);
+    return alloc->getSurfaceTextureID(rsc);
+}
+
 }
 }
 
diff --git a/libs/rs/rsAllocation.h b/libs/rs/rsAllocation.h
index 20201ca..a26d835 100644
--- a/libs/rs/rsAllocation.h
+++ b/libs/rs/rsAllocation.h
@@ -55,6 +55,8 @@
             bool hasMipmaps;
             bool hasFaces;
             bool hasReferences;
+            void * usrPtr;
+            int32_t surfaceTextureID;
         };
         State state;
 
@@ -123,6 +125,7 @@
         return mHal.state.mipmapControl != RS_ALLOCATION_MIPMAP_NONE;
     }
 
+    int32_t getSurfaceTextureID(const Context *rsc);
 
 protected:
     Vector<const Program *> mToDirtyList;
diff --git a/libs/rs/rs_hal.h b/libs/rs/rs_hal.h
index b8d7351..0afc94b 100644
--- a/libs/rs/rs_hal.h
+++ b/libs/rs/rs_hal.h
@@ -114,6 +114,7 @@
                        bool zeroNew);
         void (*syncAll)(const Context *rsc, const Allocation *alloc, RsAllocationUsageType src);
         void (*markDirty)(const Context *rsc, const Allocation *alloc);
+        int32_t (*initSurfaceTexture)(const Context *rsc, const Allocation *alloc);
 
         void (*data1D)(const Context *rsc, const Allocation *alloc,
                        uint32_t xoff, uint32_t lod, uint32_t count,