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