Implement arrays and allocation adapters

WIP: now passing basic tests

(cherry picked from commit bc9dc27b84f4e5c72d4dbe8a8e01af87dd780f79)

Change-Id: I1ddda310152140c7d7225ba42ef48ff93b30266d
diff --git a/rsAllocation.cpp b/rsAllocation.cpp
index 821ee68..13ac2de 100644
--- a/rsAllocation.cpp
+++ b/rsAllocation.cpp
@@ -41,6 +41,53 @@
     updateCache();
 }
 
+Allocation::Allocation(Context *rsc, const Allocation *alloc, const Type *type)
+    : ObjectBase(rsc) {
+
+    memset(&mHal, 0, sizeof(mHal));
+
+
+    mHal.state.baseAlloc = alloc;
+    mHal.state.type = type;
+    mHal.state.usageFlags = alloc->mHal.state.usageFlags;
+    mHal.state.mipmapControl = RS_ALLOCATION_MIPMAP_NONE;
+
+    setType(type);
+    updateCache();
+
+
+
+
+    struct Hal {
+        void * drv;
+
+        struct DrvState {
+            struct LodState {
+                void * mallocPtr;
+                size_t stride;
+                uint32_t dimX;
+                uint32_t dimY;
+                uint32_t dimZ;
+            } lod[android::renderscript::Allocation::MAX_LOD];
+            size_t faceOffset;
+            uint32_t lodCount;
+            uint32_t faceCount;
+
+            struct YuvState {
+                uint32_t shift;
+                uint32_t step;
+            } yuv;
+
+            int grallocFlags;
+            uint32_t dimArray[Type::mMaxArrays];
+        };
+        mutable DrvState drvState;
+
+    };
+    Hal mHal;
+
+}
+
 void Allocation::operator delete(void* ptr) {
     if (ptr) {
         Allocation *a = (Allocation*) ptr;
@@ -69,6 +116,27 @@
     return a;
 }
 
+Allocation * Allocation::createAdapter(Context *rsc, const Allocation *alloc, const Type *type) {
+    // Allocation objects must use allocator specified by the driver
+    void* allocMem = rsc->mHal.funcs.allocRuntimeMem(sizeof(Allocation), 0);
+
+    if (!allocMem) {
+        rsc->setError(RS_ERROR_FATAL_DRIVER, "Couldn't allocate memory for Allocation");
+        return nullptr;
+    }
+
+    Allocation *a = new (allocMem) Allocation(rsc, alloc, type);
+
+    if (!rsc->mHal.funcs.allocation.initAdapter(rsc, a)) {
+        rsc->setError(RS_ERROR_FATAL_DRIVER, "Allocation::Allocation, alloc failure");
+        delete a;
+        return nullptr;
+    }
+
+    return a;
+}
+
+
 void Allocation::updateCache() {
     const Type *type = mHal.state.type;
     mHal.state.yuv = type->getDimYuv();
@@ -786,6 +854,22 @@
     a->read(rsc, xoff, yoff, lod, face, w, h, data, sizeBytes, stride);
 }
 
+RsAllocation rsi_AllocationAdapterCreate(Context *rsc, RsType vwindow, RsAllocation vbase) {
+
+
+    Allocation * alloc = Allocation::createAdapter(rsc,
+            static_cast<Allocation *>(vbase), static_cast<Type *>(vwindow));
+    if (!alloc) {
+        return nullptr;
+    }
+    alloc->incUserRef();
+    return alloc;
+}
+
+void rsi_AllocationAdapterOffset(Context *rsc, RsAllocation va, const uint32_t *offsets, size_t len) {
+}
+
+
 }
 }