Add support for 2D copies to arbitrary data pointers.

Change-Id: Id92eb508efa9bc85d812b3f41faf98dd74c0c503
diff --git a/cpp/Allocation.cpp b/cpp/Allocation.cpp
index 15df82a..2e3597e 100644
--- a/cpp/Allocation.cpp
+++ b/cpp/Allocation.cpp
@@ -233,6 +233,13 @@
                             data->mSelectedLOD, data->mSelectedFace);
 }
 
+void Allocation::copy2DRangeTo(uint32_t xoff, uint32_t yoff, uint32_t w, uint32_t h,
+                               void* data) {
+    validate2DRange(xoff, yoff, w, h);
+    rsAllocation2DRead(mRS->getContext(), getIDSafe(), xoff, yoff, mSelectedLOD, mSelectedFace,
+                       w, h, data, w * h * mType->getElement()->getSizeBytes());
+}
+
 /*
 void resize(int dimX) {
     if ((mType.getY() > 0)|| (mType.getZ() > 0) || mType.hasFaces() || mType.hasMipmaps()) {
diff --git a/cpp/rsCppStructs.h b/cpp/rsCppStructs.h
index 80118f6..8d3a9af 100644
--- a/cpp/rsCppStructs.h
+++ b/cpp/rsCppStructs.h
@@ -231,6 +231,10 @@
 
     void copy2DRangeFrom(uint32_t xoff, uint32_t yoff, uint32_t w, uint32_t h,
                          const void *data);
+
+    void copy2DRangeTo(uint32_t xoff, uint32_t yoff, uint32_t w, uint32_t h,
+                       void *data);
+
     void copy2DRangeFrom(uint32_t xoff, uint32_t yoff, uint32_t w, uint32_t h,
                          sp<const Allocation> data, uint32_t dataXoff, uint32_t dataYoff);
 
diff --git a/rs.spec b/rs.spec
index bd0827a..679b481 100644
--- a/rs.spec
+++ b/rs.spec
@@ -229,6 +229,16 @@
     param void *data
     }
 
+Allocation2DRead {
+    param RsAllocation va
+    param uint32_t xoff
+    param uint32_t yoff
+    param uint32_t lod
+    param RsAllocationCubemapFace face
+    param uint32_t w
+    param uint32_t h
+    param void *data
+}
 
 AllocationSyncAll {
     param RsAllocation va
diff --git a/rsAllocation.cpp b/rsAllocation.cpp
index 79a4808..259c3f8 100644
--- a/rsAllocation.cpp
+++ b/rsAllocation.cpp
@@ -672,6 +672,13 @@
     a->readUnchecked(rsc, xoff, lod, count, data, sizeBytes);
 }
 
+void rsi_Allocation2DRead(Context *rsc, RsAllocation va, uint32_t xoff, uint32_t yoff,
+                          uint32_t lod, RsAllocationCubemapFace face, uint32_t w,
+                          uint32_t h, void *data, size_t sizeBytes) {
+    Allocation *a = static_cast<Allocation *>(va);
+    a->read(rsc, xoff, yoff, lod, face, w, h, data, sizeBytes);
+}
+
 }
 }