Start implementing SurfaceTexture streaming into RS allocations.

Change-Id: I561fbb63c63371ea59047c07fb2d68c21d16e76b
diff --git a/libs/rs/RenderScriptDefines.h b/libs/rs/RenderScriptDefines.h
index 49c75c5..990ef26 100644
--- a/libs/rs/RenderScriptDefines.h
+++ b/libs/rs/RenderScriptDefines.h
@@ -100,8 +100,11 @@
     RS_ALLOCATION_USAGE_GRAPHICS_VERTEX = 0x0004,
     RS_ALLOCATION_USAGE_GRAPHICS_CONSTANTS = 0x0008,
     RS_ALLOCATION_USAGE_GRAPHICS_RENDER_TARGET = 0x0010,
+    RS_ALLOCATION_USAGE_GRAPHICS_SURFACE_TEXTURE_INPUT_OPAQUE = 0x0020,
+    RS_ALLOCATION_USAGE_IO_INPUT = 0x0040,
+    RS_ALLOCATION_USAGE_IO_OUTPUT = 0x0080,
 
-    RS_ALLOCATION_USAGE_ALL = 0x000F
+    RS_ALLOCATION_USAGE_ALL = 0x00FF
 };
 
 enum RsAllocationMipmapControl {
diff --git a/libs/rs/driver/rsdAllocation.cpp b/libs/rs/driver/rsdAllocation.cpp
index cc79366..ea92192 100644
--- a/libs/rs/driver/rsdAllocation.cpp
+++ b/libs/rs/driver/rsdAllocation.cpp
@@ -134,6 +134,13 @@
 static void UploadToTexture(const Context *rsc, const Allocation *alloc) {
     DrvAllocation *drv = (DrvAllocation *)alloc->mHal.drv;
 
+    if (alloc->mHal.state.usageFlags & RS_ALLOCATION_USAGE_GRAPHICS_SURFACE_TEXTURE_INPUT_OPAQUE) {
+        if (!drv->textureID) {
+            RSD_CALL_GL(glGenTextures, 1, &drv->textureID);
+        }
+        return;
+    }
+
     if (!drv->glType || !drv->glFormat) {
         return;
     }
@@ -373,6 +380,12 @@
     drv->uploadDeferred = true;
 }
 
+int32_t rsdAllocationInitSurfaceTexture(const Context *rsc, const Allocation *alloc) {
+    DrvAllocation *drv = (DrvAllocation *)alloc->mHal.drv;
+    UploadToTexture(rsc, alloc);
+    return drv->textureID;
+}
+
 void rsdAllocationData1D(const Context *rsc, const Allocation *alloc,
                          uint32_t xoff, uint32_t lod, uint32_t count,
                          const void *data, uint32_t sizeBytes) {
diff --git a/libs/rs/driver/rsdAllocation.h b/libs/rs/driver/rsdAllocation.h
index 4fc4419..230804b 100644
--- a/libs/rs/driver/rsdAllocation.h
+++ b/libs/rs/driver/rsdAllocation.h
@@ -67,6 +67,8 @@
                           RsAllocationUsageType src);
 void rsdAllocationMarkDirty(const android::renderscript::Context *rsc,
                             const android::renderscript::Allocation *alloc);
+int32_t rsdAllocationInitSurfaceTexture(const android::renderscript::Context *rsc,
+                                        const android::renderscript::Allocation *alloc);
 
 void rsdAllocationData1D(const android::renderscript::Context *rsc,
                          const android::renderscript::Allocation *alloc,
diff --git a/libs/rs/driver/rsdCore.cpp b/libs/rs/driver/rsdCore.cpp
index 9b79900..8c80a52 100644
--- a/libs/rs/driver/rsdCore.cpp
+++ b/libs/rs/driver/rsdCore.cpp
@@ -74,6 +74,7 @@
         rsdAllocationResize,
         rsdAllocationSyncAll,
         rsdAllocationMarkDirty,
+        rsdAllocationInitSurfaceTexture,
         rsdAllocationData1D,
         rsdAllocationData2D,
         rsdAllocationData3D,
diff --git a/libs/rs/driver/rsdShader.cpp b/libs/rs/driver/rsdShader.cpp
index 8bf3207..dc7f8ab 100644
--- a/libs/rs/driver/rsdShader.cpp
+++ b/libs/rs/driver/rsdShader.cpp
@@ -139,7 +139,12 @@
     char buf[256];
     for (uint32_t ct=0; ct < mRSProgram->mHal.state.texturesCount; ct++) {
         if (mRSProgram->mHal.state.textureTargets[ct] == RS_TEXTURE_2D) {
-            snprintf(buf, sizeof(buf), "uniform sampler2D UNI_Tex%i;\n", ct);
+            Allocation *a = mRSProgram->mHal.state.textures[ct];
+            if (a && a->mHal.state.surfaceTextureID) {
+                snprintf(buf, sizeof(buf), "uniform samplerExternalOES UNI_Tex%i;\n", ct);
+            } else {
+                snprintf(buf, sizeof(buf), "uniform sampler2D UNI_Tex%i;\n", ct);
+            }
             mTextureTargets[ct] = GL_TEXTURE_2D;
         } else {
             snprintf(buf, sizeof(buf), "uniform samplerCube UNI_Tex%i;\n", ct);
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 d60db7e..7913a97 100644
--- a/libs/rs/rs.spec
+++ b/libs/rs/rs.spec
@@ -64,7 +64,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 d7e8933..1cf386e 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 0f7ed42..6cf2c6c 100644
--- a/libs/rs/rsAllocation.h
+++ b/libs/rs/rsAllocation.h
@@ -55,6 +55,7 @@
             bool hasMipmaps;
             bool hasFaces;
             bool hasReferences;
+            int32_t surfaceTextureID;
 
             void * usrPtr;
         };
@@ -126,6 +127,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 a5df600..1e222e1 100644
--- a/libs/rs/rs_hal.h
+++ b/libs/rs/rs_hal.h
@@ -115,6 +115,7 @@
                        bool zeroNew);
         void (*syncAll)(const Context *rsc, const Allocation *alloc, RsAllocationUsageType src);
         void (*markDirty)(const Context *rsc, const Allocation *alloc);
+        int32_t (*initSurfaceTexture)(const Context *rsc, const Allocation *alloc);
 
         void (*data1D)(const Context *rsc, const Allocation *alloc,
                        uint32_t xoff, uint32_t lod, uint32_t count,