Merge "Add support for synchronous get()." into jb-mr2-dev
diff --git a/cpu_ref/rsCpuScript.cpp b/cpu_ref/rsCpuScript.cpp
index b182efb..0b8dff7 100644
--- a/cpu_ref/rsCpuScript.cpp
+++ b/cpu_ref/rsCpuScript.cpp
@@ -359,14 +359,12 @@
                 mForEachSignatures[i] = tmpSig;
                 mForEachFunctions[i] =
                         (ForEachFunc_t) dlsym(mScriptSO, tmpName);
-                if (mForEachFunctions[i] == NULL) {
-                    ALOGE("Failed to find forEach function address for %s: %s",
-                          tmpName, dlerror());
+                if (i != 0 && mForEachFunctions[i] == NULL) {
                     // Ignore missing root.expand functions.
                     // root() is always specified at location 0.
-                    if (i != 0) {
-                        goto error;
-                    }
+                    ALOGE("Failed to find forEach function address for %s: %s",
+                          tmpName, dlerror());
+                    goto error;
                 }
                 else {
                     //ALOGE("Found forEach %s at %p", tmpName, mForEachFunctions[i]);
diff --git a/driver/rsdAllocation.cpp b/driver/rsdAllocation.cpp
index 231ce12..28b71ce 100644
--- a/driver/rsdAllocation.cpp
+++ b/driver/rsdAllocation.cpp
@@ -256,20 +256,20 @@
 #ifndef RS_SERVER
     switch(yuv) {
     case HAL_PIXEL_FORMAT_YV12:
-        state->lod[1].dimX = state->lod[0].dimX / 2;
-        state->lod[1].dimY = state->lod[0].dimY / 2;
-        state->lod[1].stride = rsRound(state->lod[0].stride >> 1, 16);
-        state->lod[1].mallocPtr = ((uint8_t *)state->lod[0].mallocPtr) +
+        state->lod[2].dimX = state->lod[0].dimX / 2;
+        state->lod[2].dimY = state->lod[0].dimY / 2;
+        state->lod[2].stride = rsRound(state->lod[0].stride >> 1, 16);
+        state->lod[2].mallocPtr = ((uint8_t *)state->lod[0].mallocPtr) +
                 (state->lod[0].stride * state->lod[0].dimY);
-        uvSize += state->lod[1].stride * state->lod[1].dimY;
-
-        state->lod[2].dimX = state->lod[1].dimX;
-        state->lod[2].dimY = state->lod[1].dimY;
-        state->lod[2].stride = state->lod[1].stride;
-        state->lod[2].mallocPtr = ((uint8_t *)state->lod[1].mallocPtr) +
-                (state->lod[1].stride * state->lod[1].dimY);
         uvSize += state->lod[2].stride * state->lod[2].dimY;
 
+        state->lod[1].dimX = state->lod[2].dimX;
+        state->lod[1].dimY = state->lod[2].dimY;
+        state->lod[1].stride = state->lod[2].stride;
+        state->lod[1].mallocPtr = ((uint8_t *)state->lod[2].mallocPtr) +
+                (state->lod[2].stride * state->lod[2].dimY);
+        uvSize += state->lod[1].stride * state->lod[2].dimY;
+
         state->lodCount = 3;
         break;
     case HAL_PIXEL_FORMAT_YCrCb_420_SP:  // NV21
@@ -612,6 +612,13 @@
     drv->uploadDeferred = true;
 }
 
+#ifndef RS_COMPATIBILITY_LIB
+void DrvAllocation::NewBufferListener::onFrameAvailable() {
+    intptr_t ip = (intptr_t)alloc;
+    rsc->sendMessageToClient(NULL, RS_MESSAGE_TO_CLIENT_NEW_BUFFER, ip, 0, true);
+}
+#endif
+
 void* rsdAllocationGetSurface(const Context *rsc, const Allocation *alloc) {
 #ifndef RS_COMPATIBILITY_LIB
     DrvAllocation *drv = (DrvAllocation *)alloc->mHal.drv;
@@ -620,6 +627,13 @@
     drv->cpuConsumer = new CpuConsumer(2, false);
     sp<IGraphicBufferProducer> bp = drv->cpuConsumer->getProducerInterface();
     bp->incStrong(NULL);
+
+    drv->mBufferListener = new DrvAllocation::NewBufferListener();
+    drv->mBufferListener->rsc = rsc;
+    drv->mBufferListener->alloc = alloc;
+
+    drv->cpuConsumer->setFrameAvailableListener(drv->mBufferListener);
+
     return bp.get();
 #else
     return NULL;
diff --git a/driver/rsdAllocation.h b/driver/rsdAllocation.h
index a3f62a1..97e0d6a 100644
--- a/driver/rsdAllocation.h
+++ b/driver/rsdAllocation.h
@@ -48,6 +48,16 @@
     uint32_t renderTargetID;
 
 #ifndef RS_COMPATIBILITY_LIB
+    class NewBufferListener : public android::ConsumerBase::FrameAvailableListener {
+    public:
+        const android::renderscript::Context *rsc;
+        const android::renderscript::Allocation *alloc;
+
+        virtual void onFrameAvailable();
+    };
+    android::sp<NewBufferListener> mBufferListener;
+
+
     GLenum glTarget;
     GLenum glType;
     GLenum glFormat;
diff --git a/driver/rsdGL.cpp b/driver/rsdGL.cpp
index 58c52e2..0a23a44 100644
--- a/driver/rsdGL.cpp
+++ b/driver/rsdGL.cpp
@@ -267,8 +267,6 @@
         }
     }
 
-    eglSwapInterval(dc->gl.egl.display, 0);
-
     if (numConfigs) {
         EGLConfig* const configs = new EGLConfig[numConfigs];
 
diff --git a/rsContext.cpp b/rsContext.cpp
index eec2dcd..749973a 100644
--- a/rsContext.cpp
+++ b/rsContext.cpp
@@ -48,6 +48,7 @@
 using namespace android::renderscript;
 
 pthread_mutex_t Context::gInitMutex = PTHREAD_MUTEX_INITIALIZER;
+pthread_mutex_t Context::gMessageMutex = PTHREAD_MUTEX_INITIALIZER;
 pthread_mutex_t Context::gLibMutex = PTHREAD_MUTEX_INITIALIZER;
 
 bool Context::initGLThread() {
@@ -732,7 +733,10 @@
 bool Context::sendMessageToClient(const void *data, RsMessageToClientType cmdID,
                                   uint32_t subID, size_t len, bool waitForSpace) const {
 
-    return mIO.sendToClient(cmdID, subID, data, len, waitForSpace);
+    pthread_mutex_lock(&gMessageMutex);
+    bool ret = mIO.sendToClient(cmdID, subID, data, len, waitForSpace);
+    pthread_mutex_unlock(&gMessageMutex);
+    return ret;
 }
 
 void Context::initToClient() {
diff --git a/rsContext.h b/rsContext.h
index df10d33..5b1f50c 100644
--- a/rsContext.h
+++ b/rsContext.h
@@ -75,6 +75,7 @@
     static Context * createContextLite();
     ~Context();
 
+    static pthread_mutex_t gMessageMutex;
     static pthread_mutex_t gInitMutex;
     // Library mutex (for providing thread-safe calls from the runtime)
     static pthread_mutex_t gLibMutex;
diff --git a/rsDefines.h b/rsDefines.h
index 52f7d83..242d649 100644
--- a/rsDefines.h
+++ b/rsDefines.h
@@ -101,7 +101,8 @@
     RS_MESSAGE_TO_CLIENT_EXCEPTION = 1,
     RS_MESSAGE_TO_CLIENT_RESIZE = 2,
     RS_MESSAGE_TO_CLIENT_ERROR = 3,
-    RS_MESSAGE_TO_CLIENT_USER = 4
+    RS_MESSAGE_TO_CLIENT_USER = 4,
+    RS_MESSAGE_TO_CLIENT_NEW_BUFFER = 5
 };
 
 enum RsAllocationUsageType {