RsAllocation rsi_AllocationCreateFromBitmap(Context *rsc, RsType vtype,
                                            RsAllocationMipmapControl mips,
                                            const void *data, size_t data_length, uint32_t usages) {
    Type *t = static_cast<Type *>(vtype);

    RsAllocation vTexAlloc = rsi_AllocationCreateTyped(rsc, vtype, mips, usages);
    Allocation *texAlloc = static_cast<Allocation *>(vTexAlloc);
    if (texAlloc == NULL) {
        ALOGE("Memory allocation failure");
        return NULL;
    }

    memcpy(texAlloc->getPtr(), data, t->getDimX() * t->getDimY() * t->getElementSizeBytes());
    if (mips == RS_ALLOCATION_MIPMAP_FULL) {
        AllocationGenerateScriptMips(rsc, texAlloc);
    }

    texAlloc->sendDirty(rsc);
    return texAlloc;
}
RsAllocation rsi_AllocationCreateFromBitmap(Context *rsc, RsType vtype,
                                            RsAllocationMipmapControl mipmaps,
                                            const void *data, size_t sizeBytes, uint32_t usages) {
    Type *t = static_cast<Type *>(vtype);

    RsAllocation vTexAlloc = rsi_AllocationCreateTyped(rsc, vtype, mipmaps, usages, 0);
    Allocation *texAlloc = static_cast<Allocation *>(vTexAlloc);
    if (texAlloc == nullptr) {
        ALOGE("Memory allocation failure");
        return nullptr;
    }

    texAlloc->data(rsc, 0, 0, 0, RS_ALLOCATION_CUBEMAP_FACE_POSITIVE_X,
                   t->getDimX(), t->getDimY(), data, sizeBytes, 0);
    if (mipmaps == RS_ALLOCATION_MIPMAP_FULL) {
        rsc->mHal.funcs.allocation.generateMipmaps(rsc, texAlloc);
    }

    texAlloc->sendDirty(rsc);
    return texAlloc;
}
RsAllocation rsi_AllocationCubeCreateFromBitmap(Context *rsc, RsType vtype,
                                                RsAllocationMipmapControl mips,
                                                const void *data, size_t data_length, uint32_t usages) {
    Type *t = static_cast<Type *>(vtype);

    // Cubemap allocation's faces should be Width by Width each.
    // Source data should have 6 * Width by Width pixels
    // Error checking is done in the java layer
    RsAllocation vTexAlloc = rsi_AllocationCreateTyped(rsc, vtype, mips, usages);
    Allocation *texAlloc = static_cast<Allocation *>(vTexAlloc);
    if (texAlloc == NULL) {
        ALOGE("Memory allocation failure");
        return NULL;
    }

    uint32_t faceSize = t->getDimX();
    uint32_t strideBytes = faceSize * 6 * t->getElementSizeBytes();
    uint32_t copySize = faceSize * t->getElementSizeBytes();

    uint8_t *sourcePtr = (uint8_t*)data;
    for (uint32_t face = 0; face < 6; face ++) {
        Adapter2D faceAdapter(rsc, texAlloc);
        faceAdapter.setFace(face);

        for (uint32_t dI = 0; dI < faceSize; dI ++) {
            memcpy(faceAdapter.getElement(0, dI), sourcePtr + strideBytes * dI, copySize);
        }

        // Move the data pointer to the next cube face
        sourcePtr += copySize;
    }

    if (mips == RS_ALLOCATION_MIPMAP_FULL) {
        AllocationGenerateScriptMips(rsc, texAlloc);
    }

    texAlloc->sendDirty(rsc);
    return texAlloc;
}
RsAllocation rsi_AllocationCubeCreateFromBitmap(Context *rsc, RsType vtype,
                                                RsAllocationMipmapControl mipmaps,
                                                const void *data, size_t sizeBytes, uint32_t usages) {
    Type *t = static_cast<Type *>(vtype);

    // Cubemap allocation's faces should be Width by Width each.
    // Source data should have 6 * Width by Width pixels
    // Error checking is done in the java layer
    RsAllocation vTexAlloc = rsi_AllocationCreateTyped(rsc, vtype, mipmaps, usages, 0);
    Allocation *texAlloc = static_cast<Allocation *>(vTexAlloc);
    if (texAlloc == nullptr) {
        ALOGE("Memory allocation failure");
        return nullptr;
    }

    uint32_t faceSize = t->getDimX();
    uint32_t strideBytes = faceSize * 6 * t->getElementSizeBytes();
    uint32_t copySize = faceSize * t->getElementSizeBytes();

    uint8_t *sourcePtr = (uint8_t*)data;
    for (uint32_t face = 0; face < 6; face ++) {
        for (uint32_t dI = 0; dI < faceSize; dI ++) {
            texAlloc->data(rsc, 0, dI, 0, (RsAllocationCubemapFace)face,
                           t->getDimX(), 1, sourcePtr + strideBytes * dI, copySize, 0);
        }

        // Move the data pointer to the next cube face
        sourcePtr += copySize;
    }

    if (mipmaps == RS_ALLOCATION_MIPMAP_FULL) {
        rsc->mHal.funcs.allocation.generateMipmaps(rsc, texAlloc);
    }

    texAlloc->sendDirty(rsc);
    return texAlloc;
}