Add support for user-allocated buffers from the C++ API.

Bug: 7256604
Change-Id: Ia5d458ebadfd893e41130f90a1650258280a41cd
diff --git a/driver/rsdAllocation.cpp b/driver/rsdAllocation.cpp
index 82d87c2..ef3a707 100644
--- a/driver/rsdAllocation.cpp
+++ b/driver/rsdAllocation.cpp
@@ -283,9 +283,24 @@
 
     uint8_t * ptr = NULL;
     if (alloc->mHal.state.usageFlags & RS_ALLOCATION_USAGE_IO_OUTPUT) {
+    } else if (alloc->mHal.state.userProvidedPtr != NULL) {
+        // user-provided allocation
+        // limitations: no faces, no LOD, USAGE_SCRIPT only
+        if (alloc->mHal.state.usageFlags != RS_ALLOCATION_USAGE_SCRIPT) {
+            ALOGE("Can't use user-allocated buffers if usage is not USAGE_SCRIPT");
+            return false;
+        }
+        if (alloc->getType()->getDimLOD() || alloc->getType()->getDimFaces()) {
+            ALOGE("User-allocated buffers must not have multiple faces or LODs");
+            return false;
+        }
+        ptr = (uint8_t*)alloc->mHal.state.userProvidedPtr;
     } else {
-
-        ptr = (uint8_t *)malloc(allocSize);
+        if (forceZero) {
+            ptr = (uint8_t *)calloc(1, allocSize);
+        } else {
+            ptr = (uint8_t *)malloc(allocSize);
+        }
         if (!ptr) {
             free(drv);
             return false;
@@ -313,10 +328,6 @@
     drv->glType = rsdTypeToGLType(alloc->mHal.state.type->getElement()->getComponent().getType());
     drv->glFormat = rsdKindToGLFormat(alloc->mHal.state.type->getElement()->getComponent().getKind());
 
-    if (forceZero && ptr) {
-        memset(ptr, 0, alloc->mHal.state.type->getSizeBytes());
-    }
-
     if (alloc->mHal.state.usageFlags & ~RS_ALLOCATION_USAGE_SCRIPT) {
         drv->uploadDeferred = true;
     }
@@ -346,7 +357,10 @@
     }
 
     if (alloc->mHal.drvState.lod[0].mallocPtr) {
-        free(alloc->mHal.drvState.lod[0].mallocPtr);
+        // don't free user-allocated ptrs
+        if (!alloc->mHal.state.userProvidedPtr) {
+            free(alloc->mHal.drvState.lod[0].mallocPtr);
+        }
         alloc->mHal.drvState.lod[0].mallocPtr = NULL;
     }
     if (drv->readBackFBO != NULL) {