Add getPointer for USAGE_SHARED allocations.

Change-Id: I13a2af09bbbeec6cc6131b935979ac21c02820be
diff --git a/cpp/Allocation.cpp b/cpp/Allocation.cpp
index 00d207e..de0f229 100644
--- a/cpp/Allocation.cpp
+++ b/cpp/Allocation.cpp
@@ -169,8 +169,26 @@
 #endif
 }
 
-void Allocation::generateMipmaps() {
-    tryDispatch(mRS, RS::dispatch->AllocationGenerateMipmaps(mRS->getContext(), getID()));
+void * Allocation::getPointer(size_t *stride) {
+    void *p = NULL;
+    if (!(mUsage & RS_ALLOCATION_USAGE_SHARED)) {
+        mRS->throwError(RS_ERROR_INVALID_PARAMETER, "Allocation does not support USAGE_SHARED.");
+        return NULL;
+    }
+
+    // FIXME: decide if lack of getPointer should cause compat mode
+    if (RS::dispatch->AllocationGetPointer == NULL) {
+        mRS->throwError(RS_ERROR_RUNTIME_ERROR, "Can't use getPointer on older APIs");
+        return NULL;
+    }
+
+    p = RS::dispatch->AllocationGetPointer(mRS->getContext(), getIDSafe(), 0,
+                                           RS_ALLOCATION_CUBEMAP_FACE_POSITIVE_X, 0, 0, stride);
+    if (mRS->getError() != RS_SUCCESS) {
+        mRS->throwError(RS_ERROR_RUNTIME_ERROR, "Allocation lock failed");
+        p = NULL;
+    }
+    return p;
 }
 
 void Allocation::copy1DRangeFrom(uint32_t off, size_t count, const void *data) {
diff --git a/cpp/RenderScript.cpp b/cpp/RenderScript.cpp
index 04f1e88..5709f79 100644
--- a/cpp/RenderScript.cpp
+++ b/cpp/RenderScript.cpp
@@ -401,6 +401,11 @@
         ALOGV("Couldn't initialize RS::dispatch->AllocationIoReceive");
         return false;
     }
+    RS::dispatch->AllocationGetPointer = (AllocationGetPointerFnPtr)dlsym(handle, "rsAllocationGetPointer");
+    if (RS::dispatch->AllocationGetPointer == NULL) {
+        ALOGV("Couldn't initialize RS::dispatch->AllocationGetPointer");
+        //return false;
+    }
 
     return true;
 }
diff --git a/cpp/rsCppStructs.h b/cpp/rsCppStructs.h
index 70931be..6c14e8c 100644
--- a/cpp/rsCppStructs.h
+++ b/cpp/rsCppStructs.h
@@ -559,6 +559,13 @@
                                         uint32_t usage = RS_ALLOCATION_USAGE_SCRIPT);
 
 
+    /**
+     * Get the backing pointer for a USAGE_SHARED allocation.
+     * @param[in] stride optional parameter. when non-NULL, will contain
+     *   stride in bytes of a 2D Allocation
+     * @return pointer to data
+     */
+    void * getPointer(size_t *stride = NULL);
 };
 
  /**
diff --git a/cpp/rsDispatch.h b/cpp/rsDispatch.h
index 0bd1283..ca708ad 100644
--- a/cpp/rsDispatch.h
+++ b/cpp/rsDispatch.h
@@ -85,6 +85,7 @@
 typedef void (*ScriptGroupExecuteFnPtr) (RsContext, RsScriptGroup);
 typedef void (*AllocationIoSendFnPtr) (RsContext, RsAllocation);
 typedef void (*AllocationIoReceiveFnPtr) (RsContext, RsAllocation);
+typedef void * (*AllocationGetPointerFnPtr) (RsContext, RsAllocation, uint32_t lod, RsAllocationCubemapFace face, uint32_t z, uint32_t array, size_t *stride);
 
 typedef struct {
     // inserted by hand from rs.h
@@ -156,6 +157,7 @@
     ScriptGroupExecuteFnPtr ScriptGroupExecute;
     AllocationIoSendFnPtr AllocationIoSend;
     AllocationIoReceiveFnPtr AllocationIoReceive;
+    AllocationGetPointerFnPtr AllocationGetPointer;
 } dispatchTable;
 
 #endif