1dd12e72228ea20b7fdea4dbf32c88291aef6d552Miao Wang#include <android/native_window.h>
2dd12e72228ea20b7fdea4dbf32c88291aef6d552Miao Wang#include <android/log.h>
3dd12e72228ea20b7fdea4dbf32c88291aef6d552Miao Wang
4dd12e72228ea20b7fdea4dbf32c88291aef6d552Miao Wang#include "rsCompatibilityLib.h"
5dd12e72228ea20b7fdea4dbf32c88291aef6d552Miao Wang
6dd12e72228ea20b7fdea4dbf32c88291aef6d552Miao Wang#include "rsdCore.h"
7dd12e72228ea20b7fdea4dbf32c88291aef6d552Miao Wang#include "rsdAllocation.h"
8dd12e72228ea20b7fdea4dbf32c88291aef6d552Miao Wang#include "rsAllocation.h"
9dd12e72228ea20b7fdea4dbf32c88291aef6d552Miao Wang
10dd12e72228ea20b7fdea4dbf32c88291aef6d552Miao Wang#define LOG_API(...)
11dd12e72228ea20b7fdea4dbf32c88291aef6d552Miao Wang
12dd12e72228ea20b7fdea4dbf32c88291aef6d552Miao Wangusing namespace android;
13dd12e72228ea20b7fdea4dbf32c88291aef6d552Miao Wangusing namespace android::renderscript;
14dd12e72228ea20b7fdea4dbf32c88291aef6d552Miao Wang
15dd12e72228ea20b7fdea4dbf32c88291aef6d552Miao Wangstatic bool IoGetBuffer(const Context *rsc, Allocation *alloc, ANativeWindow *nw) {
16dd12e72228ea20b7fdea4dbf32c88291aef6d552Miao Wang    DrvAllocation *drv = (DrvAllocation *)alloc->mHal.drv;
17dd12e72228ea20b7fdea4dbf32c88291aef6d552Miao Wang    // Must lock the whole surface
18dd12e72228ea20b7fdea4dbf32c88291aef6d552Miao Wang    if(drv->wndBuffer == NULL) {
19dd12e72228ea20b7fdea4dbf32c88291aef6d552Miao Wang        drv->wndBuffer = new ANativeWindow_Buffer;
20dd12e72228ea20b7fdea4dbf32c88291aef6d552Miao Wang    }
21dd12e72228ea20b7fdea4dbf32c88291aef6d552Miao Wang    int32_t r = ANativeWindow_lock(nw, drv->wndBuffer, NULL);
22dd12e72228ea20b7fdea4dbf32c88291aef6d552Miao Wang    if (r) {
23dd12e72228ea20b7fdea4dbf32c88291aef6d552Miao Wang        LOG_API("Error Locking IO output buffer.");
24dd12e72228ea20b7fdea4dbf32c88291aef6d552Miao Wang        return false;
25dd12e72228ea20b7fdea4dbf32c88291aef6d552Miao Wang    }
26dd12e72228ea20b7fdea4dbf32c88291aef6d552Miao Wang
27dd12e72228ea20b7fdea4dbf32c88291aef6d552Miao Wang    void *dst = drv->wndBuffer->bits;
28dd12e72228ea20b7fdea4dbf32c88291aef6d552Miao Wang    alloc->mHal.drvState.lod[0].mallocPtr = dst;
29dd12e72228ea20b7fdea4dbf32c88291aef6d552Miao Wang    alloc->mHal.drvState.lod[0].stride = drv->wndBuffer->stride * alloc->mHal.state.elementSizeBytes;
30dd12e72228ea20b7fdea4dbf32c88291aef6d552Miao Wang    return true;
31dd12e72228ea20b7fdea4dbf32c88291aef6d552Miao Wang}
32dd12e72228ea20b7fdea4dbf32c88291aef6d552Miao Wang
33dd12e72228ea20b7fdea4dbf32c88291aef6d552Miao Wangextern "C" void rscAllocationSetSurface(RsContext rscR, RsAllocation allocR, ANativeWindow *nw) {
34dd12e72228ea20b7fdea4dbf32c88291aef6d552Miao Wang    Context *rsc = (Context *)rscR;
35dd12e72228ea20b7fdea4dbf32c88291aef6d552Miao Wang    Allocation *alloc = (Allocation *)allocR;
36dd12e72228ea20b7fdea4dbf32c88291aef6d552Miao Wang    DrvAllocation *drv = (DrvAllocation *)alloc->mHal.drv;
37dd12e72228ea20b7fdea4dbf32c88291aef6d552Miao Wang
38dd12e72228ea20b7fdea4dbf32c88291aef6d552Miao Wang    // Cleanup old surface if there is one.
39dd12e72228ea20b7fdea4dbf32c88291aef6d552Miao Wang    if (drv->wndSurface) {
40dd12e72228ea20b7fdea4dbf32c88291aef6d552Miao Wang        ANativeWindow *old = drv->wndSurface;
41dd12e72228ea20b7fdea4dbf32c88291aef6d552Miao Wang        ANativeWindow_unlockAndPost(old);
42dd12e72228ea20b7fdea4dbf32c88291aef6d552Miao Wang        drv->wndSurface = NULL;
43dd12e72228ea20b7fdea4dbf32c88291aef6d552Miao Wang        ANativeWindow_release(old);
44dd12e72228ea20b7fdea4dbf32c88291aef6d552Miao Wang        old = NULL;
45dd12e72228ea20b7fdea4dbf32c88291aef6d552Miao Wang    }
46dd12e72228ea20b7fdea4dbf32c88291aef6d552Miao Wang
47dd12e72228ea20b7fdea4dbf32c88291aef6d552Miao Wang    if (nw != NULL) {
48dd12e72228ea20b7fdea4dbf32c88291aef6d552Miao Wang        int32_t r;
49dd12e72228ea20b7fdea4dbf32c88291aef6d552Miao Wang        r = ANativeWindow_setBuffersGeometry(nw, alloc->mHal.drvState.lod[0].dimX,
50dd12e72228ea20b7fdea4dbf32c88291aef6d552Miao Wang                                                 alloc->mHal.drvState.lod[0].dimY,
51dd12e72228ea20b7fdea4dbf32c88291aef6d552Miao Wang                                                 WINDOW_FORMAT_RGBA_8888);
52dd12e72228ea20b7fdea4dbf32c88291aef6d552Miao Wang        if (r) {
53dd12e72228ea20b7fdea4dbf32c88291aef6d552Miao Wang            LOG_API("Error setting IO output buffer geometry.");
54dd12e72228ea20b7fdea4dbf32c88291aef6d552Miao Wang            goto errorcmp;
55dd12e72228ea20b7fdea4dbf32c88291aef6d552Miao Wang        }
56dd12e72228ea20b7fdea4dbf32c88291aef6d552Miao Wang
57dd12e72228ea20b7fdea4dbf32c88291aef6d552Miao Wang        IoGetBuffer(rsc, alloc, nw);
58dd12e72228ea20b7fdea4dbf32c88291aef6d552Miao Wang        drv->wndSurface = nw;
59dd12e72228ea20b7fdea4dbf32c88291aef6d552Miao Wang    }
60dd12e72228ea20b7fdea4dbf32c88291aef6d552Miao Wang
61dd12e72228ea20b7fdea4dbf32c88291aef6d552Miao Wang    return;
62dd12e72228ea20b7fdea4dbf32c88291aef6d552Miao Wang
63dd12e72228ea20b7fdea4dbf32c88291aef6d552Miao Wang errorcmp:
64dd12e72228ea20b7fdea4dbf32c88291aef6d552Miao Wang
65dd12e72228ea20b7fdea4dbf32c88291aef6d552Miao Wang    if (nw) {
66dd12e72228ea20b7fdea4dbf32c88291aef6d552Miao Wang        nw = NULL;
67dd12e72228ea20b7fdea4dbf32c88291aef6d552Miao Wang    }
68dd12e72228ea20b7fdea4dbf32c88291aef6d552Miao Wang
69dd12e72228ea20b7fdea4dbf32c88291aef6d552Miao Wang}
70dd12e72228ea20b7fdea4dbf32c88291aef6d552Miao Wang
71dd12e72228ea20b7fdea4dbf32c88291aef6d552Miao Wangextern "C" void rscAllocationDestroy(const Context *rsc, Allocation *alloc) {
72dd12e72228ea20b7fdea4dbf32c88291aef6d552Miao Wang    DrvAllocation *drv = (DrvAllocation *)alloc->mHal.drv;
73dd12e72228ea20b7fdea4dbf32c88291aef6d552Miao Wang    if (alloc->mHal.drvState.lod[0].mallocPtr) {
74dd12e72228ea20b7fdea4dbf32c88291aef6d552Miao Wang        // don't free user-allocated ptrs or IO_OUTPUT buffers
75dd12e72228ea20b7fdea4dbf32c88291aef6d552Miao Wang        if (!(drv->useUserProvidedPtr) &&
76dd12e72228ea20b7fdea4dbf32c88291aef6d552Miao Wang            !(alloc->mHal.state.usageFlags & RS_ALLOCATION_USAGE_IO_INPUT) &&
77dd12e72228ea20b7fdea4dbf32c88291aef6d552Miao Wang            !(alloc->mHal.state.usageFlags & RS_ALLOCATION_USAGE_IO_OUTPUT)) {
78dd12e72228ea20b7fdea4dbf32c88291aef6d552Miao Wang                free(alloc->mHal.drvState.lod[0].mallocPtr);
79dd12e72228ea20b7fdea4dbf32c88291aef6d552Miao Wang        }
80dd12e72228ea20b7fdea4dbf32c88291aef6d552Miao Wang        alloc->mHal.drvState.lod[0].mallocPtr = NULL;
81dd12e72228ea20b7fdea4dbf32c88291aef6d552Miao Wang    }
82dd12e72228ea20b7fdea4dbf32c88291aef6d552Miao Wang
83dd12e72228ea20b7fdea4dbf32c88291aef6d552Miao Wang    if ((alloc->mHal.state.usageFlags & RS_ALLOCATION_USAGE_IO_OUTPUT) &&
84dd12e72228ea20b7fdea4dbf32c88291aef6d552Miao Wang        (alloc->mHal.state.usageFlags & RS_ALLOCATION_USAGE_SCRIPT)) {
85dd12e72228ea20b7fdea4dbf32c88291aef6d552Miao Wang        ANativeWindow *nw = drv->wndSurface;
86dd12e72228ea20b7fdea4dbf32c88291aef6d552Miao Wang        if (nw) {
87dd12e72228ea20b7fdea4dbf32c88291aef6d552Miao Wang            //If we have an attached surface, need to release it.
88dd12e72228ea20b7fdea4dbf32c88291aef6d552Miao Wang            ANativeWindow_unlockAndPost(nw);
89dd12e72228ea20b7fdea4dbf32c88291aef6d552Miao Wang            drv->wndSurface = NULL;
90dd12e72228ea20b7fdea4dbf32c88291aef6d552Miao Wang            ANativeWindow_release(nw);
91dd12e72228ea20b7fdea4dbf32c88291aef6d552Miao Wang            nw = NULL;
92dd12e72228ea20b7fdea4dbf32c88291aef6d552Miao Wang        }
93dd12e72228ea20b7fdea4dbf32c88291aef6d552Miao Wang    }
94dd12e72228ea20b7fdea4dbf32c88291aef6d552Miao Wang}
95dd12e72228ea20b7fdea4dbf32c88291aef6d552Miao Wang
96dd12e72228ea20b7fdea4dbf32c88291aef6d552Miao Wangextern "C" void rscAllocationIoSend(const Context *rsc, Allocation *alloc) {
97dd12e72228ea20b7fdea4dbf32c88291aef6d552Miao Wang    DrvAllocation *drv = (DrvAllocation *)alloc->mHal.drv;
98dd12e72228ea20b7fdea4dbf32c88291aef6d552Miao Wang    ANativeWindow *nw = drv->wndSurface;
99dd12e72228ea20b7fdea4dbf32c88291aef6d552Miao Wang    if (nw) {
100dd12e72228ea20b7fdea4dbf32c88291aef6d552Miao Wang        if (alloc->mHal.state.usageFlags & RS_ALLOCATION_USAGE_SCRIPT) {
101dd12e72228ea20b7fdea4dbf32c88291aef6d552Miao Wang            int32_t r = ANativeWindow_unlockAndPost(nw);
102dd12e72228ea20b7fdea4dbf32c88291aef6d552Miao Wang            if (r) {
103dd12e72228ea20b7fdea4dbf32c88291aef6d552Miao Wang                LOG_API("Error sending IO output buffer.");
104dd12e72228ea20b7fdea4dbf32c88291aef6d552Miao Wang                return;
105dd12e72228ea20b7fdea4dbf32c88291aef6d552Miao Wang            }
106dd12e72228ea20b7fdea4dbf32c88291aef6d552Miao Wang            IoGetBuffer(rsc, alloc, nw);
107dd12e72228ea20b7fdea4dbf32c88291aef6d552Miao Wang        }
108dd12e72228ea20b7fdea4dbf32c88291aef6d552Miao Wang    } else {
109dd12e72228ea20b7fdea4dbf32c88291aef6d552Miao Wang        LOG_API("Sent IO buffer with no attached surface.");
110dd12e72228ea20b7fdea4dbf32c88291aef6d552Miao Wang        return;
111dd12e72228ea20b7fdea4dbf32c88291aef6d552Miao Wang    }
112dd12e72228ea20b7fdea4dbf32c88291aef6d552Miao Wang}
113dd12e72228ea20b7fdea4dbf32c88291aef6d552Miao Wang
114