168171c40fc9a77c05da83453ac93a380960f36aaMiao Wang#include <android/native_window.h>
268171c40fc9a77c05da83453ac93a380960f36aaMiao Wang#include <android/log.h>
368171c40fc9a77c05da83453ac93a380960f36aaMiao Wang
468171c40fc9a77c05da83453ac93a380960f36aaMiao Wang#include "rsCompatibilityLib.h"
568171c40fc9a77c05da83453ac93a380960f36aaMiao Wang
668171c40fc9a77c05da83453ac93a380960f36aaMiao Wang#include "rsdCore.h"
768171c40fc9a77c05da83453ac93a380960f36aaMiao Wang#include "rsdAllocation.h"
868171c40fc9a77c05da83453ac93a380960f36aaMiao Wang#include "rsAllocation.h"
968171c40fc9a77c05da83453ac93a380960f36aaMiao Wang
1068171c40fc9a77c05da83453ac93a380960f36aaMiao Wang#define LOG_API(...)
1168171c40fc9a77c05da83453ac93a380960f36aaMiao Wang
1268171c40fc9a77c05da83453ac93a380960f36aaMiao Wangusing namespace android;
1368171c40fc9a77c05da83453ac93a380960f36aaMiao Wangusing namespace android::renderscript;
1468171c40fc9a77c05da83453ac93a380960f36aaMiao Wang
1568171c40fc9a77c05da83453ac93a380960f36aaMiao Wangstatic bool IoGetBuffer(const Context *rsc, Allocation *alloc, ANativeWindow *nw) {
1668171c40fc9a77c05da83453ac93a380960f36aaMiao Wang    DrvAllocation *drv = (DrvAllocation *)alloc->mHal.drv;
1768171c40fc9a77c05da83453ac93a380960f36aaMiao Wang    // Must lock the whole surface
1868171c40fc9a77c05da83453ac93a380960f36aaMiao Wang    if(drv->wndBuffer == NULL) {
1968171c40fc9a77c05da83453ac93a380960f36aaMiao Wang        drv->wndBuffer = new ANativeWindow_Buffer;
2068171c40fc9a77c05da83453ac93a380960f36aaMiao Wang    }
2168171c40fc9a77c05da83453ac93a380960f36aaMiao Wang    int32_t r = ANativeWindow_lock(nw, drv->wndBuffer, NULL);
2268171c40fc9a77c05da83453ac93a380960f36aaMiao Wang    if (r) {
2368171c40fc9a77c05da83453ac93a380960f36aaMiao Wang        LOG_API("Error Locking IO output buffer.");
2468171c40fc9a77c05da83453ac93a380960f36aaMiao Wang        return false;
2568171c40fc9a77c05da83453ac93a380960f36aaMiao Wang    }
2668171c40fc9a77c05da83453ac93a380960f36aaMiao Wang
2768171c40fc9a77c05da83453ac93a380960f36aaMiao Wang    void *dst = drv->wndBuffer->bits;
2868171c40fc9a77c05da83453ac93a380960f36aaMiao Wang    alloc->mHal.drvState.lod[0].mallocPtr = dst;
2968171c40fc9a77c05da83453ac93a380960f36aaMiao Wang    alloc->mHal.drvState.lod[0].stride = drv->wndBuffer->stride * alloc->mHal.state.elementSizeBytes;
3068171c40fc9a77c05da83453ac93a380960f36aaMiao Wang    return true;
3168171c40fc9a77c05da83453ac93a380960f36aaMiao Wang}
3268171c40fc9a77c05da83453ac93a380960f36aaMiao Wang
3368171c40fc9a77c05da83453ac93a380960f36aaMiao Wangextern "C" void rscAllocationSetSurface(RsContext rscR, RsAllocation allocR, ANativeWindow *nw) {
3468171c40fc9a77c05da83453ac93a380960f36aaMiao Wang    Context *rsc = (Context *)rscR;
3568171c40fc9a77c05da83453ac93a380960f36aaMiao Wang    Allocation *alloc = (Allocation *)allocR;
3668171c40fc9a77c05da83453ac93a380960f36aaMiao Wang    DrvAllocation *drv = (DrvAllocation *)alloc->mHal.drv;
3768171c40fc9a77c05da83453ac93a380960f36aaMiao Wang
3868171c40fc9a77c05da83453ac93a380960f36aaMiao Wang    // Cleanup old surface if there is one.
3968171c40fc9a77c05da83453ac93a380960f36aaMiao Wang    if (drv->wndSurface) {
4068171c40fc9a77c05da83453ac93a380960f36aaMiao Wang        ANativeWindow *old = drv->wndSurface;
4168171c40fc9a77c05da83453ac93a380960f36aaMiao Wang        ANativeWindow_unlockAndPost(old);
4268171c40fc9a77c05da83453ac93a380960f36aaMiao Wang        drv->wndSurface = NULL;
4368171c40fc9a77c05da83453ac93a380960f36aaMiao Wang        ANativeWindow_release(old);
4468171c40fc9a77c05da83453ac93a380960f36aaMiao Wang        old = NULL;
4568171c40fc9a77c05da83453ac93a380960f36aaMiao Wang    }
4668171c40fc9a77c05da83453ac93a380960f36aaMiao Wang
4768171c40fc9a77c05da83453ac93a380960f36aaMiao Wang    if (nw != NULL) {
4868171c40fc9a77c05da83453ac93a380960f36aaMiao Wang        int32_t r;
4968171c40fc9a77c05da83453ac93a380960f36aaMiao Wang        r = ANativeWindow_setBuffersGeometry(nw, alloc->mHal.drvState.lod[0].dimX,
5068171c40fc9a77c05da83453ac93a380960f36aaMiao Wang                                                 alloc->mHal.drvState.lod[0].dimY,
5168171c40fc9a77c05da83453ac93a380960f36aaMiao Wang                                                 WINDOW_FORMAT_RGBA_8888);
5268171c40fc9a77c05da83453ac93a380960f36aaMiao Wang        if (r) {
5368171c40fc9a77c05da83453ac93a380960f36aaMiao Wang            LOG_API("Error setting IO output buffer geometry.");
5468171c40fc9a77c05da83453ac93a380960f36aaMiao Wang            goto errorcmp;
5568171c40fc9a77c05da83453ac93a380960f36aaMiao Wang        }
5668171c40fc9a77c05da83453ac93a380960f36aaMiao Wang
5768171c40fc9a77c05da83453ac93a380960f36aaMiao Wang        IoGetBuffer(rsc, alloc, nw);
5868171c40fc9a77c05da83453ac93a380960f36aaMiao Wang        drv->wndSurface = nw;
5968171c40fc9a77c05da83453ac93a380960f36aaMiao Wang    }
6068171c40fc9a77c05da83453ac93a380960f36aaMiao Wang
6168171c40fc9a77c05da83453ac93a380960f36aaMiao Wang    return;
6268171c40fc9a77c05da83453ac93a380960f36aaMiao Wang
6368171c40fc9a77c05da83453ac93a380960f36aaMiao Wang errorcmp:
6468171c40fc9a77c05da83453ac93a380960f36aaMiao Wang
6568171c40fc9a77c05da83453ac93a380960f36aaMiao Wang    if (nw) {
6668171c40fc9a77c05da83453ac93a380960f36aaMiao Wang        nw = NULL;
6768171c40fc9a77c05da83453ac93a380960f36aaMiao Wang    }
6868171c40fc9a77c05da83453ac93a380960f36aaMiao Wang
6968171c40fc9a77c05da83453ac93a380960f36aaMiao Wang}
7068171c40fc9a77c05da83453ac93a380960f36aaMiao Wang
7168171c40fc9a77c05da83453ac93a380960f36aaMiao Wangextern "C" void rscAllocationDestroy(const Context *rsc, Allocation *alloc) {
7268171c40fc9a77c05da83453ac93a380960f36aaMiao Wang    DrvAllocation *drv = (DrvAllocation *)alloc->mHal.drv;
7368171c40fc9a77c05da83453ac93a380960f36aaMiao Wang    if (alloc->mHal.drvState.lod[0].mallocPtr) {
7468171c40fc9a77c05da83453ac93a380960f36aaMiao Wang        // don't free user-allocated ptrs or IO_OUTPUT buffers
7568171c40fc9a77c05da83453ac93a380960f36aaMiao Wang        if (!(drv->useUserProvidedPtr) &&
7668171c40fc9a77c05da83453ac93a380960f36aaMiao Wang            !(alloc->mHal.state.usageFlags & RS_ALLOCATION_USAGE_IO_INPUT) &&
7768171c40fc9a77c05da83453ac93a380960f36aaMiao Wang            !(alloc->mHal.state.usageFlags & RS_ALLOCATION_USAGE_IO_OUTPUT)) {
7868171c40fc9a77c05da83453ac93a380960f36aaMiao Wang                free(alloc->mHal.drvState.lod[0].mallocPtr);
7968171c40fc9a77c05da83453ac93a380960f36aaMiao Wang        }
8068171c40fc9a77c05da83453ac93a380960f36aaMiao Wang        alloc->mHal.drvState.lod[0].mallocPtr = NULL;
8168171c40fc9a77c05da83453ac93a380960f36aaMiao Wang    }
8268171c40fc9a77c05da83453ac93a380960f36aaMiao Wang
8368171c40fc9a77c05da83453ac93a380960f36aaMiao Wang    if ((alloc->mHal.state.usageFlags & RS_ALLOCATION_USAGE_IO_OUTPUT) &&
8468171c40fc9a77c05da83453ac93a380960f36aaMiao Wang        (alloc->mHal.state.usageFlags & RS_ALLOCATION_USAGE_SCRIPT)) {
8568171c40fc9a77c05da83453ac93a380960f36aaMiao Wang        ANativeWindow *nw = drv->wndSurface;
8668171c40fc9a77c05da83453ac93a380960f36aaMiao Wang        if (nw) {
8768171c40fc9a77c05da83453ac93a380960f36aaMiao Wang            //If we have an attached surface, need to release it.
8868171c40fc9a77c05da83453ac93a380960f36aaMiao Wang            ANativeWindow_unlockAndPost(nw);
8968171c40fc9a77c05da83453ac93a380960f36aaMiao Wang            drv->wndSurface = NULL;
9068171c40fc9a77c05da83453ac93a380960f36aaMiao Wang            ANativeWindow_release(nw);
9168171c40fc9a77c05da83453ac93a380960f36aaMiao Wang            nw = NULL;
9268171c40fc9a77c05da83453ac93a380960f36aaMiao Wang        }
9368171c40fc9a77c05da83453ac93a380960f36aaMiao Wang    }
9468171c40fc9a77c05da83453ac93a380960f36aaMiao Wang}
9568171c40fc9a77c05da83453ac93a380960f36aaMiao Wang
9668171c40fc9a77c05da83453ac93a380960f36aaMiao Wangextern "C" void rscAllocationIoSend(const Context *rsc, Allocation *alloc) {
9768171c40fc9a77c05da83453ac93a380960f36aaMiao Wang    DrvAllocation *drv = (DrvAllocation *)alloc->mHal.drv;
9868171c40fc9a77c05da83453ac93a380960f36aaMiao Wang    ANativeWindow *nw = drv->wndSurface;
9968171c40fc9a77c05da83453ac93a380960f36aaMiao Wang    if (nw) {
10068171c40fc9a77c05da83453ac93a380960f36aaMiao Wang        if (alloc->mHal.state.usageFlags & RS_ALLOCATION_USAGE_SCRIPT) {
10168171c40fc9a77c05da83453ac93a380960f36aaMiao Wang            int32_t r = ANativeWindow_unlockAndPost(nw);
10268171c40fc9a77c05da83453ac93a380960f36aaMiao Wang            if (r) {
10368171c40fc9a77c05da83453ac93a380960f36aaMiao Wang                LOG_API("Error sending IO output buffer.");
10468171c40fc9a77c05da83453ac93a380960f36aaMiao Wang                return;
10568171c40fc9a77c05da83453ac93a380960f36aaMiao Wang            }
10668171c40fc9a77c05da83453ac93a380960f36aaMiao Wang            IoGetBuffer(rsc, alloc, nw);
10768171c40fc9a77c05da83453ac93a380960f36aaMiao Wang        }
10868171c40fc9a77c05da83453ac93a380960f36aaMiao Wang    } else {
10968171c40fc9a77c05da83453ac93a380960f36aaMiao Wang        LOG_API("Sent IO buffer with no attached surface.");
11068171c40fc9a77c05da83453ac93a380960f36aaMiao Wang        return;
11168171c40fc9a77c05da83453ac93a380960f36aaMiao Wang    }
11268171c40fc9a77c05da83453ac93a380960f36aaMiao Wang}
11368171c40fc9a77c05da83453ac93a380960f36aaMiao Wang
114