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 12using namespace android; 13using namespace android::renderscript; 14 15static 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 33extern "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 71extern "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 96extern "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