/*
 * Copyright (C) 2013 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "rsdCore.h"
#include "rsdAllocation.h"

#include "rsAllocation.h"

#ifndef RS_SERVER
#include "system/window.h"
#include "ui/Rect.h"
#include "ui/GraphicBufferMapper.h"
#endif

#ifndef RS_COMPATIBILITY_LIB
#include "rsdFrameBufferObj.h"
#include "gui/GLConsumer.h"
#include "gui/CpuConsumer.h"
#include "gui/Surface.h"
#include "hardware/gralloc.h"

#include <GLES/gl.h>
#include <GLES2/gl2.h>
#include <GLES/glext.h>
#endif

#ifdef RS_SERVER
// server requires malloc.h for memalign
#include <malloc.h>
#endif

using namespace android;
using namespace android::renderscript;


#ifndef RS_COMPATIBILITY_LIB
const static GLenum gFaceOrder[] = {
    GL_TEXTURE_CUBE_MAP_POSITIVE_X,
    GL_TEXTURE_CUBE_MAP_NEGATIVE_X,
    GL_TEXTURE_CUBE_MAP_POSITIVE_Y,
    GL_TEXTURE_CUBE_MAP_NEGATIVE_Y,
    GL_TEXTURE_CUBE_MAP_POSITIVE_Z,
    GL_TEXTURE_CUBE_MAP_NEGATIVE_Z
};

GLenum rsdTypeToGLType(RsDataType t) {
    switch (t) {
    case RS_TYPE_UNSIGNED_5_6_5:    return GL_UNSIGNED_SHORT_5_6_5;
    case RS_TYPE_UNSIGNED_5_5_5_1:  return GL_UNSIGNED_SHORT_5_5_5_1;
    case RS_TYPE_UNSIGNED_4_4_4_4:  return GL_UNSIGNED_SHORT_4_4_4_4;

    //case RS_TYPE_FLOAT_16:      return GL_HALF_FLOAT;
    case RS_TYPE_FLOAT_32:      return GL_FLOAT;
    case RS_TYPE_UNSIGNED_8:    return GL_UNSIGNED_BYTE;
    case RS_TYPE_UNSIGNED_16:   return GL_UNSIGNED_SHORT;
    case RS_TYPE_SIGNED_8:      return GL_BYTE;
    case RS_TYPE_SIGNED_16:     return GL_SHORT;
    default:    break;
    }
    return 0;
}

GLenum rsdKindToGLFormat(RsDataKind k) {
    switch (k) {
    case RS_KIND_PIXEL_L: return GL_LUMINANCE;
    case RS_KIND_PIXEL_A: return GL_ALPHA;
    case RS_KIND_PIXEL_LA: return GL_LUMINANCE_ALPHA;
    case RS_KIND_PIXEL_RGB: return GL_RGB;
    case RS_KIND_PIXEL_RGBA: return GL_RGBA;
    case RS_KIND_PIXEL_DEPTH: return GL_DEPTH_COMPONENT16;
    default: break;
    }
    return 0;
}
#endif

uint8_t *GetOffsetPtr(const android::renderscript::Allocation *alloc,
                      uint32_t xoff, uint32_t yoff, uint32_t zoff,
                      uint32_t lod, RsAllocationCubemapFace face) {
    uint8_t *ptr = (uint8_t *)alloc->mHal.drvState.lod[lod].mallocPtr;
    ptr += face * alloc->mHal.drvState.faceOffset;
    ptr += zoff * alloc->mHal.drvState.lod[lod].dimY * alloc->mHal.drvState.lod[lod].stride;
    ptr += yoff * alloc->mHal.drvState.lod[lod].stride;
    ptr += xoff * alloc->mHal.state.elementSizeBytes;
    return ptr;
}


static void Update2DTexture(const Context *rsc, const Allocation *alloc, const void *ptr,
                            uint32_t xoff, uint32_t yoff, uint32_t lod,
                            RsAllocationCubemapFace face, uint32_t w, uint32_t h) {
#ifndef RS_COMPATIBILITY_LIB
    DrvAllocation *drv = (DrvAllocation *)alloc->mHal.drv;

    rsAssert(drv->textureID);
    RSD_CALL_GL(glBindTexture, drv->glTarget, drv->textureID);
    RSD_CALL_GL(glPixelStorei, GL_UNPACK_ALIGNMENT, 1);
    GLenum t = GL_TEXTURE_2D;
    if (alloc->mHal.state.hasFaces) {
        t = gFaceOrder[face];
    }
    RSD_CALL_GL(glTexSubImage2D, t, lod, xoff, yoff, w, h, drv->glFormat, drv->glType, ptr);
#endif
}


#ifndef RS_COMPATIBILITY_LIB
static void Upload2DTexture(const Context *rsc, const Allocation *alloc, bool isFirstUpload) {
    DrvAllocation *drv = (DrvAllocation *)alloc->mHal.drv;

    RSD_CALL_GL(glBindTexture, drv->glTarget, drv->textureID);
    RSD_CALL_GL(glPixelStorei, GL_UNPACK_ALIGNMENT, 1);

    uint32_t faceCount = 1;
    if (alloc->mHal.state.hasFaces) {
        faceCount = 6;
    }

    rsdGLCheckError(rsc, "Upload2DTexture 1 ");
    for (uint32_t face = 0; face < faceCount; face ++) {
        for (uint32_t lod = 0; lod < alloc->mHal.state.type->getLODCount(); lod++) {
            const uint8_t *p = GetOffsetPtr(alloc, 0, 0, 0, lod, (RsAllocationCubemapFace)face);

            GLenum t = GL_TEXTURE_2D;
            if (alloc->mHal.state.hasFaces) {
                t = gFaceOrder[face];
            }

            if (isFirstUpload) {
                RSD_CALL_GL(glTexImage2D, t, lod, drv->glFormat,
                             alloc->mHal.state.type->getLODDimX(lod),
                             alloc->mHal.state.type->getLODDimY(lod),
                             0, drv->glFormat, drv->glType, p);
            } else {
                RSD_CALL_GL(glTexSubImage2D, t, lod, 0, 0,
                                alloc->mHal.state.type->getLODDimX(lod),
                                alloc->mHal.state.type->getLODDimY(lod),
                                drv->glFormat, drv->glType, p);
            }
        }
    }

    if (alloc->mHal.state.mipmapControl == RS_ALLOCATION_MIPMAP_ON_SYNC_TO_TEXTURE) {
        RSD_CALL_GL(glGenerateMipmap, drv->glTarget);
    }
    rsdGLCheckError(rsc, "Upload2DTexture");
}
#endif

static void UploadToTexture(const Context *rsc, const Allocation *alloc) {
#ifndef RS_COMPATIBILITY_LIB
    DrvAllocation *drv = (DrvAllocation *)alloc->mHal.drv;

    if (alloc->mHal.state.usageFlags & RS_ALLOCATION_USAGE_IO_INPUT) {
        if (!drv->textureID) {
            RSD_CALL_GL(glGenTextures, 1, &drv->textureID);
        }
        return;
    }

    if (!drv->glType || !drv->glFormat) {
        return;
    }

    if (!alloc->mHal.drvState.lod[0].mallocPtr) {
        return;
    }

    bool isFirstUpload = false;

    if (!drv->textureID) {
        RSD_CALL_GL(glGenTextures, 1, &drv->textureID);
        isFirstUpload = true;
    }

    Upload2DTexture(rsc, alloc, isFirstUpload);

    if (!(alloc->mHal.state.usageFlags & RS_ALLOCATION_USAGE_SCRIPT)) {
        if (alloc->mHal.drvState.lod[0].mallocPtr) {
            free(alloc->mHal.drvState.lod[0].mallocPtr);
            alloc->mHal.drvState.lod[0].mallocPtr = NULL;
        }
    }
    rsdGLCheckError(rsc, "UploadToTexture");
#endif
}

static void AllocateRenderTarget(const Context *rsc, const Allocation *alloc) {
#ifndef RS_COMPATIBILITY_LIB
    DrvAllocation *drv = (DrvAllocation *)alloc->mHal.drv;

    if (!drv->glFormat) {
        return;
    }

    if (!drv->renderTargetID) {
        RSD_CALL_GL(glGenRenderbuffers, 1, &drv->renderTargetID);

        if (!drv->renderTargetID) {
            // This should generally not happen
            ALOGE("allocateRenderTarget failed to gen mRenderTargetID");
            rsc->dumpDebug();
            return;
        }
        RSD_CALL_GL(glBindRenderbuffer, GL_RENDERBUFFER, drv->renderTargetID);
        RSD_CALL_GL(glRenderbufferStorage, GL_RENDERBUFFER, drv->glFormat,
                    alloc->mHal.drvState.lod[0].dimX, alloc->mHal.drvState.lod[0].dimY);
    }
    rsdGLCheckError(rsc, "AllocateRenderTarget");
#endif
}

static void UploadToBufferObject(const Context *rsc, const Allocation *alloc) {
#ifndef RS_COMPATIBILITY_LIB
    DrvAllocation *drv = (DrvAllocation *)alloc->mHal.drv;

    rsAssert(!alloc->mHal.state.type->getDimY());
    rsAssert(!alloc->mHal.state.type->getDimZ());

    //alloc->mHal.state.usageFlags |= RS_ALLOCATION_USAGE_GRAPHICS_VERTEX;

    if (!drv->bufferID) {
        RSD_CALL_GL(glGenBuffers, 1, &drv->bufferID);
    }
    if (!drv->bufferID) {
        ALOGE("Upload to buffer object failed");
        drv->uploadDeferred = true;
        return;
    }
    RSD_CALL_GL(glBindBuffer, drv->glTarget, drv->bufferID);
    RSD_CALL_GL(glBufferData, drv->glTarget, alloc->mHal.state.type->getSizeBytes(),
                 alloc->mHal.drvState.lod[0].mallocPtr, GL_DYNAMIC_DRAW);
    RSD_CALL_GL(glBindBuffer, drv->glTarget, 0);
    rsdGLCheckError(rsc, "UploadToBufferObject");
#endif
}


static size_t DeriveYUVLayout(int yuv, Allocation::Hal::DrvState *state) {
    // YUV only supports basic 2d
    // so we can stash the plane pointers in the mipmap levels.
    size_t uvSize = 0;
#ifndef RS_SERVER
    switch(yuv) {
    case HAL_PIXEL_FORMAT_YV12:
        state->lod[2].dimX = state->lod[0].dimX / 2;
        state->lod[2].dimY = state->lod[0].dimY / 2;
        state->lod[2].stride = rsRound(state->lod[0].stride >> 1, 16);
        state->lod[2].mallocPtr = ((uint8_t *)state->lod[0].mallocPtr) +
                (state->lod[0].stride * state->lod[0].dimY);
        uvSize += state->lod[2].stride * state->lod[2].dimY;

        state->lod[1].dimX = state->lod[2].dimX;
        state->lod[1].dimY = state->lod[2].dimY;
        state->lod[1].stride = state->lod[2].stride;
        state->lod[1].mallocPtr = ((uint8_t *)state->lod[2].mallocPtr) +
                (state->lod[2].stride * state->lod[2].dimY);
        uvSize += state->lod[1].stride * state->lod[2].dimY;

        state->lodCount = 3;
        break;
    case HAL_PIXEL_FORMAT_YCrCb_420_SP:  // NV21
        state->lod[1].dimX = state->lod[0].dimX;
        state->lod[1].dimY = state->lod[0].dimY / 2;
        state->lod[1].stride = state->lod[0].stride;
        state->lod[1].mallocPtr = ((uint8_t *)state->lod[0].mallocPtr) +
                (state->lod[0].stride * state->lod[0].dimY);
        uvSize += state->lod[1].stride * state->lod[1].dimY;
        state->lodCount = 2;
        break;
    default:
        rsAssert(0);
    }
#endif
    return uvSize;
}


static size_t AllocationBuildPointerTable(const Context *rsc, const Allocation *alloc,
        const Type *type, uint8_t *ptr) {
    alloc->mHal.drvState.lod[0].dimX = type->getDimX();
    alloc->mHal.drvState.lod[0].dimY = type->getDimY();
    alloc->mHal.drvState.lod[0].dimZ = type->getDimZ();
    alloc->mHal.drvState.lod[0].mallocPtr = 0;
    // Stride needs to be 16-byte aligned too!
    size_t stride = alloc->mHal.drvState.lod[0].dimX * type->getElementSizeBytes();
    alloc->mHal.drvState.lod[0].stride = rsRound(stride, 16);
    alloc->mHal.drvState.lodCount = type->getLODCount();
    alloc->mHal.drvState.faceCount = type->getDimFaces();

    size_t offsets[Allocation::MAX_LOD];
    memset(offsets, 0, sizeof(offsets));

    size_t o = alloc->mHal.drvState.lod[0].stride * rsMax(alloc->mHal.drvState.lod[0].dimY, 1u) *
            rsMax(alloc->mHal.drvState.lod[0].dimZ, 1u);
    if(alloc->mHal.drvState.lodCount > 1) {
        uint32_t tx = alloc->mHal.drvState.lod[0].dimX;
        uint32_t ty = alloc->mHal.drvState.lod[0].dimY;
        uint32_t tz = alloc->mHal.drvState.lod[0].dimZ;
        for (uint32_t lod=1; lod < alloc->mHal.drvState.lodCount; lod++) {
            alloc->mHal.drvState.lod[lod].dimX = tx;
            alloc->mHal.drvState.lod[lod].dimY = ty;
            alloc->mHal.drvState.lod[lod].dimZ = tz;
            alloc->mHal.drvState.lod[lod].stride =
                    rsRound(tx * type->getElementSizeBytes(), 16);
            offsets[lod] = o;
            o += alloc->mHal.drvState.lod[lod].stride * rsMax(ty, 1u) * rsMax(tz, 1u);
            if (tx > 1) tx >>= 1;
            if (ty > 1) ty >>= 1;
            if (tz > 1) tz >>= 1;
        }
    } else if (alloc->mHal.state.yuv) {
        o += DeriveYUVLayout(alloc->mHal.state.yuv, &alloc->mHal.drvState);

        for (uint32_t ct = 1; ct < alloc->mHal.drvState.lodCount; ct++) {
            offsets[ct] = (size_t)alloc->mHal.drvState.lod[ct].mallocPtr;
        }
    }

    alloc->mHal.drvState.faceOffset = o;

    alloc->mHal.drvState.lod[0].mallocPtr = ptr;
    for (uint32_t lod=1; lod < alloc->mHal.drvState.lodCount; lod++) {
        alloc->mHal.drvState.lod[lod].mallocPtr = ptr + offsets[lod];
    }

    size_t allocSize = alloc->mHal.drvState.faceOffset;
    if(alloc->mHal.drvState.faceCount) {
        allocSize *= 6;
    }

    return allocSize;
}

static uint8_t* allocAlignedMemory(size_t allocSize, bool forceZero) {
    // We align all allocations to a 16-byte boundary.
    uint8_t* ptr = (uint8_t *)memalign(16, allocSize);
    if (!ptr) {
        return NULL;
    }
    if (forceZero) {
        memset(ptr, 0, allocSize);
    }
    return ptr;
}

bool rsdAllocationInit(const Context *rsc, Allocation *alloc, bool forceZero) {
    DrvAllocation *drv = (DrvAllocation *)calloc(1, sizeof(DrvAllocation));
    if (!drv) {
        return false;
    }
    alloc->mHal.drv = drv;

    // Calculate the object size.
    size_t allocSize = AllocationBuildPointerTable(rsc, alloc, alloc->getType(), NULL);

    uint8_t * ptr = NULL;
    if (alloc->mHal.state.usageFlags & RS_ALLOCATION_USAGE_IO_OUTPUT) {

    } else if (alloc->mHal.state.usageFlags & RS_ALLOCATION_USAGE_IO_INPUT) {
        // Allocation is allocated when the surface is created
        // in getSurface
    } else if (alloc->mHal.state.userProvidedPtr != NULL) {
        // user-provided allocation
        // limitations: no faces, no LOD, USAGE_SCRIPT or SCRIPT+TEXTURE only
        if (!(alloc->mHal.state.usageFlags == (RS_ALLOCATION_USAGE_SCRIPT | RS_ALLOCATION_USAGE_SHARED) ||
              alloc->mHal.state.usageFlags == (RS_ALLOCATION_USAGE_SCRIPT | RS_ALLOCATION_USAGE_SHARED | RS_ALLOCATION_USAGE_GRAPHICS_TEXTURE))) {
            ALOGE("Can't use user-allocated buffers if usage is not USAGE_SCRIPT | USAGE_SHARED or USAGE_SCRIPT | USAGE_SHARED | USAGE_GRAPHICS_TEXTURE");
            return false;
        }
        if (alloc->getType()->getDimLOD() || alloc->getType()->getDimFaces()) {
            ALOGE("User-allocated buffers must not have multiple faces or LODs");
            return false;
        }

        // rows must be 16-byte aligned
        // validate that here, otherwise fall back to not use the user-backed allocation
        if (((alloc->getType()->getDimX() * alloc->getType()->getElement()->getSizeBytes()) % 16) != 0) {
            ALOGV("User-backed allocation failed stride requirement, falling back to separate allocation");
            drv->useUserProvidedPtr = false;

            ptr = allocAlignedMemory(allocSize, forceZero);
            if (!ptr) {
                alloc->mHal.drv = NULL;
                free(drv);
                return false;
            }

        } else {
            drv->useUserProvidedPtr = true;
            ptr = (uint8_t*)alloc->mHal.state.userProvidedPtr;
        }
    } else {
        ptr = allocAlignedMemory(allocSize, forceZero);
        if (!ptr) {
            alloc->mHal.drv = NULL;
            free(drv);
            return false;
        }
    }
    // Build the pointer tables
    size_t verifySize = AllocationBuildPointerTable(rsc, alloc, alloc->getType(), ptr);
    if(allocSize != verifySize) {
        rsAssert(!"Size mismatch");
    }

#ifndef RS_SERVER
    drv->glTarget = GL_NONE;
    if (alloc->mHal.state.usageFlags & RS_ALLOCATION_USAGE_GRAPHICS_TEXTURE) {
        if (alloc->mHal.state.hasFaces) {
            drv->glTarget = GL_TEXTURE_CUBE_MAP;
        } else {
            drv->glTarget = GL_TEXTURE_2D;
        }
    } else {
        if (alloc->mHal.state.usageFlags & RS_ALLOCATION_USAGE_GRAPHICS_VERTEX) {
            drv->glTarget = GL_ARRAY_BUFFER;
        }
    }
#endif

#ifndef RS_COMPATIBILITY_LIB
    drv->glType = rsdTypeToGLType(alloc->mHal.state.type->getElement()->getComponent().getType());
    drv->glFormat = rsdKindToGLFormat(alloc->mHal.state.type->getElement()->getComponent().getKind());
#else
    drv->glType = 0;
    drv->glFormat = 0;
#endif

    if (alloc->mHal.state.usageFlags & ~RS_ALLOCATION_USAGE_SCRIPT) {
        drv->uploadDeferred = true;
    }


    drv->readBackFBO = NULL;

    // fill out the initial state of the buffer if we couldn't use the user-provided ptr and USAGE_SHARED was accepted
    if ((alloc->mHal.state.userProvidedPtr != 0) && (drv->useUserProvidedPtr == false)) {
        rsdAllocationData2D(rsc, alloc, 0, 0, 0, RS_ALLOCATION_CUBEMAP_FACE_POSITIVE_X, alloc->getType()->getDimX(), alloc->getType()->getDimY(), alloc->mHal.state.userProvidedPtr, allocSize, 0);
    }

    return true;
}

void rsdAllocationDestroy(const Context *rsc, Allocation *alloc) {
    DrvAllocation *drv = (DrvAllocation *)alloc->mHal.drv;

#ifndef RS_COMPATIBILITY_LIB
    if (drv->bufferID) {
        // Causes a SW crash....
        //ALOGV(" mBufferID %i", mBufferID);
        //glDeleteBuffers(1, &mBufferID);
        //mBufferID = 0;
    }
    if (drv->textureID) {
        RSD_CALL_GL(glDeleteTextures, 1, &drv->textureID);
        drv->textureID = 0;
    }
    if (drv->renderTargetID) {
        RSD_CALL_GL(glDeleteRenderbuffers, 1, &drv->renderTargetID);
        drv->renderTargetID = 0;
    }
#endif

    if (alloc->mHal.drvState.lod[0].mallocPtr) {
        // don't free user-allocated ptrs
        if (!(drv->useUserProvidedPtr)) {
            free(alloc->mHal.drvState.lod[0].mallocPtr);
        }
        alloc->mHal.drvState.lod[0].mallocPtr = NULL;
    }

#ifndef RS_COMPATIBILITY_LIB
    if (drv->readBackFBO != NULL) {
        delete drv->readBackFBO;
        drv->readBackFBO = NULL;
    }

    if ((alloc->mHal.state.usageFlags & RS_ALLOCATION_USAGE_IO_OUTPUT) &&
        (alloc->mHal.state.usageFlags & RS_ALLOCATION_USAGE_SCRIPT)) {

        DrvAllocation *drv = (DrvAllocation *)alloc->mHal.drv;
        ANativeWindow *nw = drv->wndSurface;
        if (nw) {
            GraphicBufferMapper &mapper = GraphicBufferMapper::get();
            mapper.unlock(drv->wndBuffer->handle);
            int32_t r = nw->queueBuffer(nw, drv->wndBuffer, -1);
        }
    }
#endif

    free(drv);
    alloc->mHal.drv = NULL;
}

void rsdAllocationResize(const Context *rsc, const Allocation *alloc,
                         const Type *newType, bool zeroNew) {
    const uint32_t oldDimX = alloc->mHal.drvState.lod[0].dimX;
    const uint32_t dimX = newType->getDimX();

    // can't resize Allocations with user-allocated buffers
    if (alloc->mHal.state.usageFlags & RS_ALLOCATION_USAGE_SHARED) {
        ALOGE("Resize cannot be called on a USAGE_SHARED allocation");
        return;
    }
    void * oldPtr = alloc->mHal.drvState.lod[0].mallocPtr;
    // Calculate the object size
    size_t s = AllocationBuildPointerTable(rsc, alloc, newType, NULL);
    uint8_t *ptr = (uint8_t *)realloc(oldPtr, s);
    // Build the relative pointer tables.
    size_t verifySize = AllocationBuildPointerTable(rsc, alloc, newType, ptr);
    if(s != verifySize) {
        rsAssert(!"Size mismatch");
    }


    if (dimX > oldDimX) {
        size_t stride = alloc->mHal.state.elementSizeBytes;
        memset(((uint8_t *)alloc->mHal.drvState.lod[0].mallocPtr) + stride * oldDimX,
                 0, stride * (dimX - oldDimX));
    }
}

static void rsdAllocationSyncFromFBO(const Context *rsc, const Allocation *alloc) {
#ifndef RS_COMPATIBILITY_LIB
    if (!alloc->getIsScript()) {
        return; // nothing to sync
    }

    RsdHal *dc = (RsdHal *)rsc->mHal.drv;
    RsdFrameBufferObj *lastFbo = dc->gl.currentFrameBuffer;

    DrvAllocation *drv = (DrvAllocation *)alloc->mHal.drv;
    if (!drv->textureID && !drv->renderTargetID) {
        return; // nothing was rendered here yet, so nothing to sync
    }
    if (drv->readBackFBO == NULL) {
        drv->readBackFBO = new RsdFrameBufferObj();
        drv->readBackFBO->setColorTarget(drv, 0);
        drv->readBackFBO->setDimensions(alloc->getType()->getDimX(),
                                        alloc->getType()->getDimY());
    }

    // Bind the framebuffer object so we can read back from it
    drv->readBackFBO->setActive(rsc);

    // Do the readback
    RSD_CALL_GL(glReadPixels, 0, 0, alloc->mHal.drvState.lod[0].dimX,
                alloc->mHal.drvState.lod[0].dimY,
                drv->glFormat, drv->glType, alloc->mHal.drvState.lod[0].mallocPtr);

    // Revert framebuffer to its original
    lastFbo->setActive(rsc);
#endif
}


void rsdAllocationSyncAll(const Context *rsc, const Allocation *alloc,
                         RsAllocationUsageType src) {
    DrvAllocation *drv = (DrvAllocation *)alloc->mHal.drv;

    if (src == RS_ALLOCATION_USAGE_GRAPHICS_RENDER_TARGET) {
        if(!alloc->getIsRenderTarget()) {
            rsc->setError(RS_ERROR_FATAL_DRIVER,
                          "Attempting to sync allocation from render target, "
                          "for non-render target allocation");
        } else if (alloc->getType()->getElement()->getKind() != RS_KIND_PIXEL_RGBA) {
            rsc->setError(RS_ERROR_FATAL_DRIVER, "Cannot only sync from RGBA"
                                                 "render target");
        } else {
            rsdAllocationSyncFromFBO(rsc, alloc);
        }
        return;
    }

    rsAssert(src == RS_ALLOCATION_USAGE_SCRIPT);

    if (alloc->mHal.state.usageFlags & RS_ALLOCATION_USAGE_GRAPHICS_TEXTURE) {
        UploadToTexture(rsc, alloc);
    } else {
        if ((alloc->mHal.state.usageFlags & RS_ALLOCATION_USAGE_GRAPHICS_RENDER_TARGET) &&
            !(alloc->mHal.state.usageFlags & RS_ALLOCATION_USAGE_IO_OUTPUT)) {
            AllocateRenderTarget(rsc, alloc);
        }
    }
    if (alloc->mHal.state.usageFlags & RS_ALLOCATION_USAGE_GRAPHICS_VERTEX) {
        UploadToBufferObject(rsc, alloc);
    }

    if (alloc->mHal.state.usageFlags & RS_ALLOCATION_USAGE_SHARED) {
        // NOP in CPU driver for now
    }

    drv->uploadDeferred = false;
}

void rsdAllocationMarkDirty(const Context *rsc, const Allocation *alloc) {
    DrvAllocation *drv = (DrvAllocation *)alloc->mHal.drv;
    drv->uploadDeferred = true;
}

#ifndef RS_COMPATIBILITY_LIB
void DrvAllocation::NewBufferListener::onFrameAvailable() {
    intptr_t ip = (intptr_t)alloc;
    rsc->sendMessageToClient(NULL, RS_MESSAGE_TO_CLIENT_NEW_BUFFER, ip, 0, true);
}
#endif

void* rsdAllocationGetSurface(const Context *rsc, const Allocation *alloc) {
#ifndef RS_COMPATIBILITY_LIB
    DrvAllocation *drv = (DrvAllocation *)alloc->mHal.drv;

    // Configure CpuConsumer to be in asynchronous mode
    drv->cpuConsumer = new CpuConsumer(2, false);
    sp<IGraphicBufferProducer> bp = drv->cpuConsumer->getProducerInterface();
    bp->incStrong(NULL);

    drv->mBufferListener = new DrvAllocation::NewBufferListener();
    drv->mBufferListener->rsc = rsc;
    drv->mBufferListener->alloc = alloc;

    drv->cpuConsumer->setFrameAvailableListener(drv->mBufferListener);

    return bp.get();
#else
    return NULL;
#endif
}

#ifndef RS_COMPATIBILITY_LIB
static bool IoGetBuffer(const Context *rsc, Allocation *alloc, ANativeWindow *nw) {
    DrvAllocation *drv = (DrvAllocation *)alloc->mHal.drv;

    int32_t r = native_window_dequeue_buffer_and_wait(nw, &drv->wndBuffer);
    if (r) {
        rsc->setError(RS_ERROR_DRIVER, "Error getting next IO output buffer.");
        return false;
    }

    // Must lock the whole surface
    GraphicBufferMapper &mapper = GraphicBufferMapper::get();
    Rect bounds(drv->wndBuffer->width, drv->wndBuffer->height);

    void *dst = NULL;
    mapper.lock(drv->wndBuffer->handle,
            GRALLOC_USAGE_SW_READ_NEVER | GRALLOC_USAGE_SW_WRITE_OFTEN,
            bounds, &dst);
    alloc->mHal.drvState.lod[0].mallocPtr = dst;
    alloc->mHal.drvState.lod[0].stride = drv->wndBuffer->stride * alloc->mHal.state.elementSizeBytes;
    rsAssert((alloc->mHal.drvState.lod[0].stride & 0xf) == 0);

    return true;
}
#endif

void rsdAllocationSetSurface(const Context *rsc, Allocation *alloc, ANativeWindow *nw) {
#ifndef RS_COMPATIBILITY_LIB
    DrvAllocation *drv = (DrvAllocation *)alloc->mHal.drv;
    ANativeWindow *old = drv->wndSurface;

    if (nw) {
        nw->incStrong(NULL);
    }

    if (alloc->mHal.state.usageFlags & RS_ALLOCATION_USAGE_GRAPHICS_RENDER_TARGET) {
        //TODO finish support for render target + script
        drv->wnd = nw;
        return;
    }

    // Cleanup old surface if there is one.
    if (drv->wndSurface) {
        ANativeWindow *old = drv->wndSurface;
        GraphicBufferMapper &mapper = GraphicBufferMapper::get();
        mapper.unlock(drv->wndBuffer->handle);
        old->cancelBuffer(old, drv->wndBuffer, -1);
        drv->wndSurface = NULL;
        old->decStrong(NULL);
    }

    if (nw != NULL) {
        int32_t r;
        uint32_t flags = 0;
        r = native_window_set_buffer_count(nw, 3);
        if (r) {
            rsc->setError(RS_ERROR_DRIVER, "Error setting IO output buffer count.");
            goto error;
        }

        if (alloc->mHal.state.usageFlags & RS_ALLOCATION_USAGE_SCRIPT) {
            flags |= GRALLOC_USAGE_SW_READ_RARELY | GRALLOC_USAGE_SW_WRITE_OFTEN;
        }
        if (alloc->mHal.state.usageFlags & RS_ALLOCATION_USAGE_GRAPHICS_RENDER_TARGET) {
            flags |= GRALLOC_USAGE_HW_RENDER;
        }

        r = native_window_set_usage(nw, flags);
        if (r) {
            rsc->setError(RS_ERROR_DRIVER, "Error setting IO output buffer usage.");
            goto error;
        }

        r = native_window_set_buffers_dimensions(nw, alloc->mHal.drvState.lod[0].dimX,
                                                 alloc->mHal.drvState.lod[0].dimY);
        if (r) {
            rsc->setError(RS_ERROR_DRIVER, "Error setting IO output buffer dimensions.");
            goto error;
        }

        int format = 0;
        const Element *e = alloc->mHal.state.type->getElement();
        switch(e->getType()) {
        case RS_TYPE_UNSIGNED_8:
            switch (e->getVectorSize()) {
            case 1:
                rsAssert(e->getKind() == RS_KIND_PIXEL_A);
                format = PIXEL_FORMAT_A_8;
                break;
            case 4:
                rsAssert(e->getKind() == RS_KIND_PIXEL_RGBA);
                format = PIXEL_FORMAT_RGBA_8888;
                break;
            default:
                rsAssert(0);
            }
            break;
        default:
            rsAssert(0);
        }

        r = native_window_set_buffers_format(nw, format);
        if (r) {
            rsc->setError(RS_ERROR_DRIVER, "Error setting IO output buffer format.");
            goto error;
        }

        IoGetBuffer(rsc, alloc, nw);
        drv->wndSurface = nw;
    }

    return;

 error:

    if (nw) {
        nw->decStrong(NULL);
    }


#endif
}

void rsdAllocationIoSend(const Context *rsc, Allocation *alloc) {
#ifndef RS_COMPATIBILITY_LIB
    DrvAllocation *drv = (DrvAllocation *)alloc->mHal.drv;
    ANativeWindow *nw = drv->wndSurface;
    if (alloc->mHal.state.usageFlags & RS_ALLOCATION_USAGE_GRAPHICS_RENDER_TARGET) {
        RsdHal *dc = (RsdHal *)rsc->mHal.drv;
        RSD_CALL_GL(eglSwapBuffers, dc->gl.egl.display, dc->gl.egl.surface);
        return;
    }
    if (nw) {
        if (alloc->mHal.state.usageFlags & RS_ALLOCATION_USAGE_SCRIPT) {
            GraphicBufferMapper &mapper = GraphicBufferMapper::get();
            mapper.unlock(drv->wndBuffer->handle);
            int32_t r = nw->queueBuffer(nw, drv->wndBuffer, -1);
            if (r) {
                rsc->setError(RS_ERROR_DRIVER, "Error sending IO output buffer.");
                return;
            }

            IoGetBuffer(rsc, alloc, nw);
        }
    } else {
        rsc->setError(RS_ERROR_DRIVER, "Sent IO buffer with no attached surface.");
        return;
    }
#endif
}

void rsdAllocationIoReceive(const Context *rsc, Allocation *alloc) {
#ifndef RS_COMPATIBILITY_LIB
    DrvAllocation *drv = (DrvAllocation *)alloc->mHal.drv;

    if (alloc->mHal.state.usageFlags & RS_ALLOCATION_USAGE_SCRIPT) {
        CpuConsumer::LockedBuffer lb;
        status_t ret = drv->cpuConsumer->lockNextBuffer(&lb);
        if (ret == OK) {
            if (drv->lb.data != NULL) {
                drv->cpuConsumer->unlockBuffer(drv->lb);
            }
            drv->lb = lb;
            alloc->mHal.drvState.lod[0].mallocPtr = drv->lb.data;
            alloc->mHal.drvState.lod[0].stride = drv->lb.stride *
                    alloc->mHal.state.elementSizeBytes;

            if (alloc->mHal.state.yuv) {
                DeriveYUVLayout(alloc->mHal.state.yuv, &alloc->mHal.drvState);
            }
        } else if (ret == BAD_VALUE) {
            // No new frame, don't do anything
        } else {
            rsc->setError(RS_ERROR_DRIVER, "Error receiving IO input buffer.");
        }

    } else {
        drv->surfaceTexture->updateTexImage();
    }


#endif
}


void rsdAllocationData1D(const Context *rsc, const Allocation *alloc,
                         uint32_t xoff, uint32_t lod, size_t count,
                         const void *data, size_t sizeBytes) {
    DrvAllocation *drv = (DrvAllocation *)alloc->mHal.drv;

    const size_t eSize = alloc->mHal.state.type->getElementSizeBytes();
    uint8_t * ptr = GetOffsetPtr(alloc, xoff, 0, 0, 0, RS_ALLOCATION_CUBEMAP_FACE_POSITIVE_X);
    size_t size = count * eSize;

    if (ptr != data) {
        // Skip the copy if we are the same allocation. This can arise from
        // our Bitmap optimization, where we share the same storage.
        if (alloc->mHal.state.hasReferences) {
            alloc->incRefs(data, count);
            alloc->decRefs(ptr, count);
        }
        memcpy(ptr, data, size);
    }
    drv->uploadDeferred = true;
}

void rsdAllocationData2D(const Context *rsc, const Allocation *alloc,
                         uint32_t xoff, uint32_t yoff, uint32_t lod, RsAllocationCubemapFace face,
                         uint32_t w, uint32_t h, const void *data, size_t sizeBytes, size_t stride) {
    DrvAllocation *drv = (DrvAllocation *)alloc->mHal.drv;

    size_t eSize = alloc->mHal.state.elementSizeBytes;
    size_t lineSize = eSize * w;
    if (!stride) {
        stride = lineSize;
    }

    if (alloc->mHal.drvState.lod[0].mallocPtr) {
        const uint8_t *src = static_cast<const uint8_t *>(data);
        uint8_t *dst = GetOffsetPtr(alloc, xoff, yoff, 0, lod, face);
        if (dst == src) {
            // Skip the copy if we are the same allocation. This can arise from
            // our Bitmap optimization, where we share the same storage.
            drv->uploadDeferred = true;
            return;
        }

        for (uint32_t line=yoff; line < (yoff+h); line++) {
            if (alloc->mHal.state.hasReferences) {
                alloc->incRefs(src, w);
                alloc->decRefs(dst, w);
            }
            memcpy(dst, src, lineSize);
            src += stride;
            dst += alloc->mHal.drvState.lod[lod].stride;
        }
        if (alloc->mHal.state.yuv) {
            int lod = 1;
            while (alloc->mHal.drvState.lod[lod].mallocPtr) {
                size_t lineSize = alloc->mHal.drvState.lod[lod].dimX;
                uint8_t *dst = GetOffsetPtr(alloc, xoff, yoff, 0, lod, face);

                for (uint32_t line=(yoff >> 1); line < ((yoff+h)>>1); line++) {
                    memcpy(dst, src, lineSize);
                    src += lineSize;
                    dst += alloc->mHal.drvState.lod[lod].stride;
                }
                lod++;
            }

        }
        drv->uploadDeferred = true;
    } else {
        Update2DTexture(rsc, alloc, data, xoff, yoff, lod, face, w, h);
    }
}

void rsdAllocationData3D(const Context *rsc, const Allocation *alloc,
                         uint32_t xoff, uint32_t yoff, uint32_t zoff,
                         uint32_t lod,
                         uint32_t w, uint32_t h, uint32_t d, const void *data,
                         size_t sizeBytes, size_t stride) {
    DrvAllocation *drv = (DrvAllocation *)alloc->mHal.drv;

    uint32_t eSize = alloc->mHal.state.elementSizeBytes;
    uint32_t lineSize = eSize * w;
    if (!stride) {
        stride = lineSize;
    }

    if (alloc->mHal.drvState.lod[0].mallocPtr) {
        const uint8_t *src = static_cast<const uint8_t *>(data);
        for (uint32_t z = zoff; z < d; z++) {
            uint8_t *dst = GetOffsetPtr(alloc, xoff, yoff, z, lod,
                                        RS_ALLOCATION_CUBEMAP_FACE_POSITIVE_X);
            if (dst == src) {
                // Skip the copy if we are the same allocation. This can arise from
                // our Bitmap optimization, where we share the same storage.
                drv->uploadDeferred = true;
                return;
            }

            for (uint32_t line=yoff; line < (yoff+h); line++) {
                if (alloc->mHal.state.hasReferences) {
                    alloc->incRefs(src, w);
                    alloc->decRefs(dst, w);
                }
                memcpy(dst, src, lineSize);
                src += stride;
                dst += alloc->mHal.drvState.lod[lod].stride;
            }
        }
        drv->uploadDeferred = true;
    }
}

void rsdAllocationRead1D(const Context *rsc, const Allocation *alloc,
                         uint32_t xoff, uint32_t lod, size_t count,
                         void *data, size_t sizeBytes) {
    const size_t eSize = alloc->mHal.state.type->getElementSizeBytes();
    const uint8_t * ptr = GetOffsetPtr(alloc, xoff, 0, 0, 0, RS_ALLOCATION_CUBEMAP_FACE_POSITIVE_X);
    if (data != ptr) {
        // Skip the copy if we are the same allocation. This can arise from
        // our Bitmap optimization, where we share the same storage.
        memcpy(data, ptr, count * eSize);
    }
}

void rsdAllocationRead2D(const Context *rsc, const Allocation *alloc,
                                uint32_t xoff, uint32_t yoff, uint32_t lod, RsAllocationCubemapFace face,
                                uint32_t w, uint32_t h, void *data, size_t sizeBytes, size_t stride) {
    size_t eSize = alloc->mHal.state.elementSizeBytes;
    size_t lineSize = eSize * w;
    if (!stride) {
        stride = lineSize;
    }

    if (alloc->mHal.drvState.lod[0].mallocPtr) {
        uint8_t *dst = static_cast<uint8_t *>(data);
        const uint8_t *src = GetOffsetPtr(alloc, xoff, yoff, 0, lod, face);
        if (dst == src) {
            // Skip the copy if we are the same allocation. This can arise from
            // our Bitmap optimization, where we share the same storage.
            return;
        }

        for (uint32_t line=yoff; line < (yoff+h); line++) {
            memcpy(dst, src, lineSize);
            dst += stride;
            src += alloc->mHal.drvState.lod[lod].stride;
        }
    } else {
        ALOGE("Add code to readback from non-script memory");
    }
}


void rsdAllocationRead3D(const Context *rsc, const Allocation *alloc,
                         uint32_t xoff, uint32_t yoff, uint32_t zoff,
                         uint32_t lod,
                         uint32_t w, uint32_t h, uint32_t d, void *data, size_t sizeBytes, size_t stride) {
    uint32_t eSize = alloc->mHal.state.elementSizeBytes;
    uint32_t lineSize = eSize * w;
    if (!stride) {
        stride = lineSize;
    }

    if (alloc->mHal.drvState.lod[0].mallocPtr) {
        uint8_t *dst = static_cast<uint8_t *>(data);
        for (uint32_t z = zoff; z < d; z++) {
            const uint8_t *src = GetOffsetPtr(alloc, xoff, yoff, z, lod,
                                              RS_ALLOCATION_CUBEMAP_FACE_POSITIVE_X);
            if (dst == src) {
                // Skip the copy if we are the same allocation. This can arise from
                // our Bitmap optimization, where we share the same storage.
                return;
            }

            for (uint32_t line=yoff; line < (yoff+h); line++) {
                memcpy(dst, src, lineSize);
                dst += stride;
                src += alloc->mHal.drvState.lod[lod].stride;
            }
        }
    }
}

void * rsdAllocationLock1D(const android::renderscript::Context *rsc,
                          const android::renderscript::Allocation *alloc) {
    return alloc->mHal.drvState.lod[0].mallocPtr;
}

void rsdAllocationUnlock1D(const android::renderscript::Context *rsc,
                          const android::renderscript::Allocation *alloc) {

}

void rsdAllocationData1D_alloc(const android::renderscript::Context *rsc,
                               const android::renderscript::Allocation *dstAlloc,
                               uint32_t dstXoff, uint32_t dstLod, size_t count,
                               const android::renderscript::Allocation *srcAlloc,
                               uint32_t srcXoff, uint32_t srcLod) {
}


void rsdAllocationData2D_alloc_script(const android::renderscript::Context *rsc,
                                      const android::renderscript::Allocation *dstAlloc,
                                      uint32_t dstXoff, uint32_t dstYoff, uint32_t dstLod,
                                      RsAllocationCubemapFace dstFace, uint32_t w, uint32_t h,
                                      const android::renderscript::Allocation *srcAlloc,
                                      uint32_t srcXoff, uint32_t srcYoff, uint32_t srcLod,
                                      RsAllocationCubemapFace srcFace) {
    size_t elementSize = dstAlloc->getType()->getElementSizeBytes();
    for (uint32_t i = 0; i < h; i ++) {
        uint8_t *dstPtr = GetOffsetPtr(dstAlloc, dstXoff, dstYoff + i, 0, dstLod, dstFace);
        uint8_t *srcPtr = GetOffsetPtr(srcAlloc, srcXoff, srcYoff + i, 0, srcLod, srcFace);
        memcpy(dstPtr, srcPtr, w * elementSize);

        //ALOGE("COPIED dstXoff(%u), dstYoff(%u), dstLod(%u), dstFace(%u), w(%u), h(%u), srcXoff(%u), srcYoff(%u), srcLod(%u), srcFace(%u)",
        //     dstXoff, dstYoff, dstLod, dstFace, w, h, srcXoff, srcYoff, srcLod, srcFace);
    }
}

void rsdAllocationData3D_alloc_script(const android::renderscript::Context *rsc,
                                      const android::renderscript::Allocation *dstAlloc,
                                      uint32_t dstXoff, uint32_t dstYoff, uint32_t dstZoff, uint32_t dstLod,
                                      uint32_t w, uint32_t h, uint32_t d,
                                      const android::renderscript::Allocation *srcAlloc,
                                      uint32_t srcXoff, uint32_t srcYoff, uint32_t srcZoff, uint32_t srcLod) {
    uint32_t elementSize = dstAlloc->getType()->getElementSizeBytes();
    for (uint32_t j = 0; j < d; j++) {
        for (uint32_t i = 0; i < h; i ++) {
            uint8_t *dstPtr = GetOffsetPtr(dstAlloc, dstXoff, dstYoff + i, dstZoff + j,
                                           dstLod, RS_ALLOCATION_CUBEMAP_FACE_POSITIVE_X);
            uint8_t *srcPtr = GetOffsetPtr(srcAlloc, srcXoff, srcYoff + i, srcZoff + j,
                                           srcLod, RS_ALLOCATION_CUBEMAP_FACE_POSITIVE_X);
            memcpy(dstPtr, srcPtr, w * elementSize);

            //ALOGE("COPIED dstXoff(%u), dstYoff(%u), dstLod(%u), dstFace(%u), w(%u), h(%u), srcXoff(%u), srcYoff(%u), srcLod(%u), srcFace(%u)",
            //     dstXoff, dstYoff, dstLod, dstFace, w, h, srcXoff, srcYoff, srcLod, srcFace);
        }
    }
}

void rsdAllocationData2D_alloc(const android::renderscript::Context *rsc,
                               const android::renderscript::Allocation *dstAlloc,
                               uint32_t dstXoff, uint32_t dstYoff, uint32_t dstLod,
                               RsAllocationCubemapFace dstFace, uint32_t w, uint32_t h,
                               const android::renderscript::Allocation *srcAlloc,
                               uint32_t srcXoff, uint32_t srcYoff, uint32_t srcLod,
                               RsAllocationCubemapFace srcFace) {
    if (!dstAlloc->getIsScript() && !srcAlloc->getIsScript()) {
        rsc->setError(RS_ERROR_FATAL_DRIVER, "Non-script allocation copies not "
                                             "yet implemented.");
        return;
    }
    rsdAllocationData2D_alloc_script(rsc, dstAlloc, dstXoff, dstYoff,
                                     dstLod, dstFace, w, h, srcAlloc,
                                     srcXoff, srcYoff, srcLod, srcFace);
}

void rsdAllocationData3D_alloc(const android::renderscript::Context *rsc,
                               const android::renderscript::Allocation *dstAlloc,
                               uint32_t dstXoff, uint32_t dstYoff, uint32_t dstZoff,
                               uint32_t dstLod,
                               uint32_t w, uint32_t h, uint32_t d,
                               const android::renderscript::Allocation *srcAlloc,
                               uint32_t srcXoff, uint32_t srcYoff, uint32_t srcZoff,
                               uint32_t srcLod) {
    if (!dstAlloc->getIsScript() && !srcAlloc->getIsScript()) {
        rsc->setError(RS_ERROR_FATAL_DRIVER, "Non-script allocation copies not "
                                             "yet implemented.");
        return;
    }
    rsdAllocationData3D_alloc_script(rsc, dstAlloc, dstXoff, dstYoff, dstZoff,
                                     dstLod, w, h, d, srcAlloc,
                                     srcXoff, srcYoff, srcZoff, srcLod);
}

void rsdAllocationElementData1D(const Context *rsc, const Allocation *alloc,
                                uint32_t x,
                                const void *data, uint32_t cIdx, size_t sizeBytes) {
    DrvAllocation *drv = (DrvAllocation *)alloc->mHal.drv;

    size_t eSize = alloc->mHal.state.elementSizeBytes;
    uint8_t * ptr = GetOffsetPtr(alloc, x, 0, 0, 0, RS_ALLOCATION_CUBEMAP_FACE_POSITIVE_X);

    const Element * e = alloc->mHal.state.type->getElement()->getField(cIdx);
    ptr += alloc->mHal.state.type->getElement()->getFieldOffsetBytes(cIdx);

    if (alloc->mHal.state.hasReferences) {
        e->incRefs(data);
        e->decRefs(ptr);
    }

    memcpy(ptr, data, sizeBytes);
    drv->uploadDeferred = true;
}

void rsdAllocationElementData2D(const Context *rsc, const Allocation *alloc,
                                uint32_t x, uint32_t y,
                                const void *data, uint32_t cIdx, size_t sizeBytes) {
    DrvAllocation *drv = (DrvAllocation *)alloc->mHal.drv;

    size_t eSize = alloc->mHal.state.elementSizeBytes;
    uint8_t * ptr = GetOffsetPtr(alloc, x, y, 0, 0, RS_ALLOCATION_CUBEMAP_FACE_POSITIVE_X);

    const Element * e = alloc->mHal.state.type->getElement()->getField(cIdx);
    ptr += alloc->mHal.state.type->getElement()->getFieldOffsetBytes(cIdx);

    if (alloc->mHal.state.hasReferences) {
        e->incRefs(data);
        e->decRefs(ptr);
    }

    memcpy(ptr, data, sizeBytes);
    drv->uploadDeferred = true;
}

static void mip565(const Allocation *alloc, int lod, RsAllocationCubemapFace face) {
    uint32_t w = alloc->mHal.drvState.lod[lod + 1].dimX;
    uint32_t h = alloc->mHal.drvState.lod[lod + 1].dimY;

    for (uint32_t y=0; y < h; y++) {
        uint16_t *oPtr = (uint16_t *)GetOffsetPtr(alloc, 0, y, 0, lod + 1, face);
        const uint16_t *i1 = (uint16_t *)GetOffsetPtr(alloc, 0, 0, y*2, lod, face);
        const uint16_t *i2 = (uint16_t *)GetOffsetPtr(alloc, 0, 0, y*2+1, lod, face);

        for (uint32_t x=0; x < w; x++) {
            *oPtr = rsBoxFilter565(i1[0], i1[1], i2[0], i2[1]);
            oPtr ++;
            i1 += 2;
            i2 += 2;
        }
    }
}

static void mip8888(const Allocation *alloc, int lod, RsAllocationCubemapFace face) {
    uint32_t w = alloc->mHal.drvState.lod[lod + 1].dimX;
    uint32_t h = alloc->mHal.drvState.lod[lod + 1].dimY;

    for (uint32_t y=0; y < h; y++) {
        uint32_t *oPtr = (uint32_t *)GetOffsetPtr(alloc, 0, y, 0, lod + 1, face);
        const uint32_t *i1 = (uint32_t *)GetOffsetPtr(alloc, 0, y*2, 0, lod, face);
        const uint32_t *i2 = (uint32_t *)GetOffsetPtr(alloc, 0, y*2+1, 0, lod, face);

        for (uint32_t x=0; x < w; x++) {
            *oPtr = rsBoxFilter8888(i1[0], i1[1], i2[0], i2[1]);
            oPtr ++;
            i1 += 2;
            i2 += 2;
        }
    }
}

static void mip8(const Allocation *alloc, int lod, RsAllocationCubemapFace face) {
    uint32_t w = alloc->mHal.drvState.lod[lod + 1].dimX;
    uint32_t h = alloc->mHal.drvState.lod[lod + 1].dimY;

    for (uint32_t y=0; y < h; y++) {
        uint8_t *oPtr = GetOffsetPtr(alloc, 0, y, 0, lod + 1, face);
        const uint8_t *i1 = GetOffsetPtr(alloc, 0, y*2, 0, lod, face);
        const uint8_t *i2 = GetOffsetPtr(alloc, 0, y*2+1, 0, lod, face);

        for (uint32_t x=0; x < w; x++) {
            *oPtr = (uint8_t)(((uint32_t)i1[0] + i1[1] + i2[0] + i2[1]) * 0.25f);
            oPtr ++;
            i1 += 2;
            i2 += 2;
        }
    }
}

void rsdAllocationGenerateMipmaps(const Context *rsc, const Allocation *alloc) {
    if(!alloc->mHal.drvState.lod[0].mallocPtr) {
        return;
    }
    uint32_t numFaces = alloc->getType()->getDimFaces() ? 6 : 1;
    for (uint32_t face = 0; face < numFaces; face ++) {
        for (uint32_t lod=0; lod < (alloc->getType()->getLODCount() -1); lod++) {
            switch (alloc->getType()->getElement()->getSizeBits()) {
            case 32:
                mip8888(alloc, lod, (RsAllocationCubemapFace)face);
                break;
            case 16:
                mip565(alloc, lod, (RsAllocationCubemapFace)face);
                break;
            case 8:
                mip8(alloc, lod, (RsAllocationCubemapFace)face);
                break;
            }
        }
    }
}
