Cleanup lots of things related to IO_OUTPUT and error checking.

Change-Id: Ic6802dd0ba9d3edc8c53f99002cdd905214a515c
diff --git a/cpu_ref/rsCpuScript.cpp b/cpu_ref/rsCpuScript.cpp
index 257655a..80f8ea0 100644
--- a/cpu_ref/rsCpuScript.cpp
+++ b/cpu_ref/rsCpuScript.cpp
@@ -175,6 +175,16 @@
 
     memset(mtls, 0, sizeof(MTLaunchStruct));
 
+    // possible for this to occur if IO_OUTPUT/IO_INPUT with no bound surface
+    if (ain && (const uint8_t *)ain->mHal.drvState.lod[0].mallocPtr == NULL) {
+        mCtx->getContext()->setError(RS_ERROR_BAD_SCRIPT, "rsForEach called with null allocations");
+        return;
+    }
+    if (aout && (const uint8_t *)aout->mHal.drvState.lod[0].mallocPtr == NULL) {
+        mCtx->getContext()->setError(RS_ERROR_BAD_SCRIPT, "rsForEach called with null allocations");
+        return;
+    }
+
     if (ain) {
         mtls->fep.dimX = ain->getType()->getDimX();
         mtls->fep.dimY = ain->getType()->getDimY();
diff --git a/driver/rsdAllocation.cpp b/driver/rsdAllocation.cpp
index 3e695ea..28d8aad 100644
--- a/driver/rsdAllocation.cpp
+++ b/driver/rsdAllocation.cpp
@@ -475,11 +475,12 @@
         (alloc->mHal.state.usageFlags & RS_ALLOCATION_USAGE_SCRIPT)) {
 
         DrvAllocation *drv = (DrvAllocation *)alloc->mHal.drv;
-        ANativeWindow *nw = alloc->mHal.state.wndSurface;
-
-        GraphicBufferMapper &mapper = GraphicBufferMapper::get();
-        mapper.unlock(drv->wndBuffer->handle);
-        int32_t r = nw->queueBuffer(nw, drv->wndBuffer, -1);
+        ANativeWindow *nw = drv->wndSurface;
+        if (nw) {
+            GraphicBufferMapper &mapper = GraphicBufferMapper::get();
+            mapper.unlock(drv->wndBuffer->handle);
+            int32_t r = nw->queueBuffer(nw, drv->wndBuffer, -1);
+        }
     }
 #endif
 
@@ -631,6 +632,11 @@
 void rsdAllocationSetSurface(const Context *rsc, Allocation *alloc, ANativeWindow *nw) {
 #ifndef RS_COMPATIBILITY_LIB
     DrvAllocation *drv = (DrvAllocation *)alloc->mHal.drv;
+    ANativeWindow *old = drv->wndSurface;
+
+    if (nw) {
+        nw->incStrong(NULL);
+    }
 
     if (alloc->mHal.state.usageFlags & RS_ALLOCATION_USAGE_GRAPHICS_RENDER_TARGET) {
         //TODO finish support for render target + script
@@ -638,18 +644,25 @@
         return;
     }
 
-
     // Cleanup old surface if there is one.
-    if (alloc->mHal.state.wndSurface) {
-        ANativeWindow *old = alloc->mHal.state.wndSurface;
+    if (drv->wndSurface) {
+        ANativeWindow *old = drv->wndSurface;
         GraphicBufferMapper &mapper = GraphicBufferMapper::get();
         mapper.unlock(drv->wndBuffer->handle);
-        old->queueBuffer(old, drv->wndBuffer, -1);
+        old->cancelBuffer(old, drv->wndBuffer, -1);
+        drv->wndSurface = NULL;
+        old->decStrong(NULL);
     }
 
     if (nw != NULL) {
         int32_t r;
         uint32_t flags = 0;
+        r = native_window_set_buffer_count(nw, 3);
+        if (r) {
+            rsc->setError(RS_ERROR_DRIVER, "Error setting IO output buffer count.");
+            goto error;
+        }
+
         if (alloc->mHal.state.usageFlags & RS_ALLOCATION_USAGE_SCRIPT) {
             flags |= GRALLOC_USAGE_SW_READ_RARELY | GRALLOC_USAGE_SW_WRITE_OFTEN;
         }
@@ -660,14 +673,14 @@
         r = native_window_set_usage(nw, flags);
         if (r) {
             rsc->setError(RS_ERROR_DRIVER, "Error setting IO output buffer usage.");
-            return;
+            goto error;
         }
 
         r = native_window_set_buffers_dimensions(nw, alloc->mHal.drvState.lod[0].dimX,
                                                  alloc->mHal.drvState.lod[0].dimY);
         if (r) {
             rsc->setError(RS_ERROR_DRIVER, "Error setting IO output buffer dimensions.");
-            return;
+            goto error;
         }
 
         int format = 0;
@@ -694,41 +707,49 @@
         r = native_window_set_buffers_format(nw, format);
         if (r) {
             rsc->setError(RS_ERROR_DRIVER, "Error setting IO output buffer format.");
-            return;
-        }
-
-        r = native_window_set_buffer_count(nw, 3);
-        if (r) {
-            rsc->setError(RS_ERROR_DRIVER, "Error setting IO output buffer count.");
-            return;
+            goto error;
         }
 
         IoGetBuffer(rsc, alloc, nw);
+        drv->wndSurface = nw;
     }
+
+    return;
+
+ error:
+
+    if (nw) {
+        nw->decStrong(NULL);
+    }
+
+
 #endif
 }
 
 void rsdAllocationIoSend(const Context *rsc, Allocation *alloc) {
 #ifndef RS_COMPATIBILITY_LIB
     DrvAllocation *drv = (DrvAllocation *)alloc->mHal.drv;
-    ANativeWindow *nw = alloc->mHal.state.wndSurface;
-
+    ANativeWindow *nw = drv->wndSurface;
     if (alloc->mHal.state.usageFlags & RS_ALLOCATION_USAGE_GRAPHICS_RENDER_TARGET) {
         RsdHal *dc = (RsdHal *)rsc->mHal.drv;
         RSD_CALL_GL(eglSwapBuffers, dc->gl.egl.display, dc->gl.egl.surface);
         return;
     }
+    if (nw) {
+        if (alloc->mHal.state.usageFlags & RS_ALLOCATION_USAGE_SCRIPT) {
+            GraphicBufferMapper &mapper = GraphicBufferMapper::get();
+            mapper.unlock(drv->wndBuffer->handle);
+            int32_t r = nw->queueBuffer(nw, drv->wndBuffer, -1);
+            if (r) {
+                rsc->setError(RS_ERROR_DRIVER, "Error sending IO output buffer.");
+                return;
+            }
 
-    if (alloc->mHal.state.usageFlags & RS_ALLOCATION_USAGE_SCRIPT) {
-        GraphicBufferMapper &mapper = GraphicBufferMapper::get();
-        mapper.unlock(drv->wndBuffer->handle);
-        int32_t r = nw->queueBuffer(nw, drv->wndBuffer, -1);
-        if (r) {
-            rsc->setError(RS_ERROR_DRIVER, "Error sending IO output buffer.");
-            return;
+            IoGetBuffer(rsc, alloc, nw);
         }
-
-        IoGetBuffer(rsc, alloc, nw);
+    } else {
+        rsc->setError(RS_ERROR_DRIVER, "Sent IO buffer with no attached surface.");
+        return;
     }
 #endif
 }
@@ -751,7 +772,7 @@
         }
 
     } else {
-        alloc->mHal.state.surfaceTexture->updateTexImage();
+        drv->surfaceTexture->updateTexImage();
     }
 
 
diff --git a/driver/rsdAllocation.h b/driver/rsdAllocation.h
index 41ccfe7..d8f46c5 100644
--- a/driver/rsdAllocation.h
+++ b/driver/rsdAllocation.h
@@ -23,14 +23,15 @@
 
 #include "../cpu_ref/rsd_cpu.h"
 #include "gui/CpuConsumer.h"
+#include "gui/GLConsumer.h"
 
 #include <GLES/gl.h>
 #include <GLES2/gl2.h>
 
 class RsdFrameBufferObj;
+struct ANativeWindow;
 struct ANativeWindowBuffer;
 
-
 struct DrvAllocation {
     // Is this a legal structure to be used as a texture source.
     // Initially this will require 1D or 2D and color data
@@ -48,6 +49,9 @@
     GLenum glTarget;
     GLenum glType;
     GLenum glFormat;
+
+    ANativeWindow *wndSurface;
+    android::GLConsumer *surfaceTexture;
 #else
     int glTarget;
     int glType;
diff --git a/rsAllocation.cpp b/rsAllocation.cpp
index f9fc462..9833ab3 100644
--- a/rsAllocation.cpp
+++ b/rsAllocation.cpp
@@ -63,7 +63,6 @@
 
 Allocation::~Allocation() {
     freeChildrenUnlocked();
-    setSurfaceTexture(mRSC, NULL);
     mRSC->mHal.funcs.allocation.destroy(mRSC, this);
 }
 
@@ -447,29 +446,9 @@
     return rsc->mHal.funcs.allocation.getSurface(rsc, this);
 }
 
-void Allocation::setSurfaceTexture(const Context *rsc, GLConsumer *st) {
-    if(st != mHal.state.surfaceTexture) {
-        if(mHal.state.surfaceTexture != NULL) {
-            mHal.state.surfaceTexture->decStrong(NULL);
-        }
-        mHal.state.surfaceTexture = st;
-        if(mHal.state.surfaceTexture != NULL) {
-            mHal.state.surfaceTexture->incStrong(NULL);
-        }
-    }
-}
-
 void Allocation::setSurface(const Context *rsc, RsNativeWindow sur) {
     ANativeWindow *nw = (ANativeWindow *)sur;
-    ANativeWindow *old = mHal.state.wndSurface;
-    if (nw) {
-        nw->incStrong(NULL);
-    }
     rsc->mHal.funcs.allocation.setSurface(rsc, this, nw);
-    mHal.state.wndSurface = nw;
-    if (old) {
-        old->decStrong(NULL);
-    }
 }
 
 void Allocation::ioSend(const Context *rsc) {
diff --git a/rsAllocation.h b/rsAllocation.h
index 3624f67..2938f65 100644
--- a/rsAllocation.h
+++ b/rsAllocation.h
@@ -19,11 +19,8 @@
 
 #include "rsType.h"
 
-struct ANativeWindow;
-
 // ---------------------------------------------------------------------------
 namespace android {
-class GLConsumer;
 
 namespace renderscript {
 
@@ -61,8 +58,8 @@
             bool hasReferences;
             void * userProvidedPtr;
             int32_t surfaceTextureID;
-            ANativeWindow *wndSurface;
-            GLConsumer *surfaceTexture;
+            void *deprecated01;
+            void *deprecated02;
         };
         State state;
 
@@ -151,7 +148,6 @@
     }
 
     void * getSurface(const Context *rsc);
-    void setSurfaceTexture(const Context *rsc, GLConsumer *st);
     void setSurface(const Context *rsc, RsNativeWindow sur);
     void ioSend(const Context *rsc);
     void ioReceive(const Context *rsc);