#include #include #include "rsCompatibilityLib.h" #include "rsdCore.h" #include "rsdAllocation.h" #include "rsAllocation.h" #define LOG_API(...) using namespace android; using namespace android::renderscript; static bool IoGetBuffer(const Context *rsc, Allocation *alloc, ANativeWindow *nw) { DrvAllocation *drv = (DrvAllocation *)alloc->mHal.drv; // Must lock the whole surface if(drv->wndBuffer == NULL) { drv->wndBuffer = new ANativeWindow_Buffer; } int32_t r = ANativeWindow_lock(nw, drv->wndBuffer, NULL); if (r) { LOG_API("Error Locking IO output buffer."); return false; } void *dst = drv->wndBuffer->bits; alloc->mHal.drvState.lod[0].mallocPtr = dst; alloc->mHal.drvState.lod[0].stride = drv->wndBuffer->stride * alloc->mHal.state.elementSizeBytes; return true; } extern "C" void rscAllocationSetSurface(RsContext rscR, RsAllocation allocR, ANativeWindow *nw) { Context *rsc = (Context *)rscR; Allocation *alloc = (Allocation *)allocR; DrvAllocation *drv = (DrvAllocation *)alloc->mHal.drv; // Cleanup old surface if there is one. if (drv->wndSurface) { ANativeWindow *old = drv->wndSurface; ANativeWindow_unlockAndPost(old); drv->wndSurface = NULL; ANativeWindow_release(old); old = NULL; } if (nw != NULL) { int32_t r; r = ANativeWindow_setBuffersGeometry(nw, alloc->mHal.drvState.lod[0].dimX, alloc->mHal.drvState.lod[0].dimY, WINDOW_FORMAT_RGBA_8888); if (r) { LOG_API("Error setting IO output buffer geometry."); goto errorcmp; } IoGetBuffer(rsc, alloc, nw); drv->wndSurface = nw; } return; errorcmp: if (nw) { nw = NULL; } } extern "C" void rscAllocationDestroy(const Context *rsc, Allocation *alloc) { DrvAllocation *drv = (DrvAllocation *)alloc->mHal.drv; if (alloc->mHal.drvState.lod[0].mallocPtr) { // don't free user-allocated ptrs or IO_OUTPUT buffers if (!(drv->useUserProvidedPtr) && !(alloc->mHal.state.usageFlags & RS_ALLOCATION_USAGE_IO_INPUT) && !(alloc->mHal.state.usageFlags & RS_ALLOCATION_USAGE_IO_OUTPUT)) { free(alloc->mHal.drvState.lod[0].mallocPtr); } alloc->mHal.drvState.lod[0].mallocPtr = NULL; } if ((alloc->mHal.state.usageFlags & RS_ALLOCATION_USAGE_IO_OUTPUT) && (alloc->mHal.state.usageFlags & RS_ALLOCATION_USAGE_SCRIPT)) { ANativeWindow *nw = drv->wndSurface; if (nw) { //If we have an attached surface, need to release it. ANativeWindow_unlockAndPost(nw); drv->wndSurface = NULL; ANativeWindow_release(nw); nw = NULL; } } } extern "C" void rscAllocationIoSend(const Context *rsc, Allocation *alloc) { DrvAllocation *drv = (DrvAllocation *)alloc->mHal.drv; ANativeWindow *nw = drv->wndSurface; if (nw) { if (alloc->mHal.state.usageFlags & RS_ALLOCATION_USAGE_SCRIPT) { int32_t r = ANativeWindow_unlockAndPost(nw); if (r) { LOG_API("Error sending IO output buffer."); return; } IoGetBuffer(rsc, alloc, nw); } } else { LOG_API("Sent IO buffer with no attached surface."); return; } }