| #include <android/native_window.h> |
| #include <android/log.h> |
| |
| #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; |
| } |
| } |
| |