168171c40fc9a77c05da83453ac93a380960f36aaMiao Wang#include <android/native_window.h> 268171c40fc9a77c05da83453ac93a380960f36aaMiao Wang#include <android/log.h> 368171c40fc9a77c05da83453ac93a380960f36aaMiao Wang 468171c40fc9a77c05da83453ac93a380960f36aaMiao Wang#include "rsCompatibilityLib.h" 568171c40fc9a77c05da83453ac93a380960f36aaMiao Wang 668171c40fc9a77c05da83453ac93a380960f36aaMiao Wang#include "rsdCore.h" 768171c40fc9a77c05da83453ac93a380960f36aaMiao Wang#include "rsdAllocation.h" 868171c40fc9a77c05da83453ac93a380960f36aaMiao Wang#include "rsAllocation.h" 968171c40fc9a77c05da83453ac93a380960f36aaMiao Wang 1068171c40fc9a77c05da83453ac93a380960f36aaMiao Wang#define LOG_API(...) 1168171c40fc9a77c05da83453ac93a380960f36aaMiao Wang 1268171c40fc9a77c05da83453ac93a380960f36aaMiao Wangusing namespace android; 1368171c40fc9a77c05da83453ac93a380960f36aaMiao Wangusing namespace android::renderscript; 1468171c40fc9a77c05da83453ac93a380960f36aaMiao Wang 1568171c40fc9a77c05da83453ac93a380960f36aaMiao Wangstatic bool IoGetBuffer(const Context *rsc, Allocation *alloc, ANativeWindow *nw) { 1668171c40fc9a77c05da83453ac93a380960f36aaMiao Wang DrvAllocation *drv = (DrvAllocation *)alloc->mHal.drv; 1768171c40fc9a77c05da83453ac93a380960f36aaMiao Wang // Must lock the whole surface 1868171c40fc9a77c05da83453ac93a380960f36aaMiao Wang if(drv->wndBuffer == NULL) { 1968171c40fc9a77c05da83453ac93a380960f36aaMiao Wang drv->wndBuffer = new ANativeWindow_Buffer; 2068171c40fc9a77c05da83453ac93a380960f36aaMiao Wang } 2168171c40fc9a77c05da83453ac93a380960f36aaMiao Wang int32_t r = ANativeWindow_lock(nw, drv->wndBuffer, NULL); 2268171c40fc9a77c05da83453ac93a380960f36aaMiao Wang if (r) { 2368171c40fc9a77c05da83453ac93a380960f36aaMiao Wang LOG_API("Error Locking IO output buffer."); 2468171c40fc9a77c05da83453ac93a380960f36aaMiao Wang return false; 2568171c40fc9a77c05da83453ac93a380960f36aaMiao Wang } 2668171c40fc9a77c05da83453ac93a380960f36aaMiao Wang 2768171c40fc9a77c05da83453ac93a380960f36aaMiao Wang void *dst = drv->wndBuffer->bits; 2868171c40fc9a77c05da83453ac93a380960f36aaMiao Wang alloc->mHal.drvState.lod[0].mallocPtr = dst; 2968171c40fc9a77c05da83453ac93a380960f36aaMiao Wang alloc->mHal.drvState.lod[0].stride = drv->wndBuffer->stride * alloc->mHal.state.elementSizeBytes; 3068171c40fc9a77c05da83453ac93a380960f36aaMiao Wang return true; 3168171c40fc9a77c05da83453ac93a380960f36aaMiao Wang} 3268171c40fc9a77c05da83453ac93a380960f36aaMiao Wang 3368171c40fc9a77c05da83453ac93a380960f36aaMiao Wangextern "C" void rscAllocationSetSurface(RsContext rscR, RsAllocation allocR, ANativeWindow *nw) { 3468171c40fc9a77c05da83453ac93a380960f36aaMiao Wang Context *rsc = (Context *)rscR; 3568171c40fc9a77c05da83453ac93a380960f36aaMiao Wang Allocation *alloc = (Allocation *)allocR; 3668171c40fc9a77c05da83453ac93a380960f36aaMiao Wang DrvAllocation *drv = (DrvAllocation *)alloc->mHal.drv; 3768171c40fc9a77c05da83453ac93a380960f36aaMiao Wang 3868171c40fc9a77c05da83453ac93a380960f36aaMiao Wang // Cleanup old surface if there is one. 3968171c40fc9a77c05da83453ac93a380960f36aaMiao Wang if (drv->wndSurface) { 4068171c40fc9a77c05da83453ac93a380960f36aaMiao Wang ANativeWindow *old = drv->wndSurface; 4168171c40fc9a77c05da83453ac93a380960f36aaMiao Wang ANativeWindow_unlockAndPost(old); 4268171c40fc9a77c05da83453ac93a380960f36aaMiao Wang drv->wndSurface = NULL; 4368171c40fc9a77c05da83453ac93a380960f36aaMiao Wang ANativeWindow_release(old); 4468171c40fc9a77c05da83453ac93a380960f36aaMiao Wang old = NULL; 4568171c40fc9a77c05da83453ac93a380960f36aaMiao Wang } 4668171c40fc9a77c05da83453ac93a380960f36aaMiao Wang 4768171c40fc9a77c05da83453ac93a380960f36aaMiao Wang if (nw != NULL) { 4868171c40fc9a77c05da83453ac93a380960f36aaMiao Wang int32_t r; 4968171c40fc9a77c05da83453ac93a380960f36aaMiao Wang r = ANativeWindow_setBuffersGeometry(nw, alloc->mHal.drvState.lod[0].dimX, 5068171c40fc9a77c05da83453ac93a380960f36aaMiao Wang alloc->mHal.drvState.lod[0].dimY, 5168171c40fc9a77c05da83453ac93a380960f36aaMiao Wang WINDOW_FORMAT_RGBA_8888); 5268171c40fc9a77c05da83453ac93a380960f36aaMiao Wang if (r) { 5368171c40fc9a77c05da83453ac93a380960f36aaMiao Wang LOG_API("Error setting IO output buffer geometry."); 5468171c40fc9a77c05da83453ac93a380960f36aaMiao Wang goto errorcmp; 5568171c40fc9a77c05da83453ac93a380960f36aaMiao Wang } 5668171c40fc9a77c05da83453ac93a380960f36aaMiao Wang 5768171c40fc9a77c05da83453ac93a380960f36aaMiao Wang IoGetBuffer(rsc, alloc, nw); 5868171c40fc9a77c05da83453ac93a380960f36aaMiao Wang drv->wndSurface = nw; 5968171c40fc9a77c05da83453ac93a380960f36aaMiao Wang } 6068171c40fc9a77c05da83453ac93a380960f36aaMiao Wang 6168171c40fc9a77c05da83453ac93a380960f36aaMiao Wang return; 6268171c40fc9a77c05da83453ac93a380960f36aaMiao Wang 6368171c40fc9a77c05da83453ac93a380960f36aaMiao Wang errorcmp: 6468171c40fc9a77c05da83453ac93a380960f36aaMiao Wang 6568171c40fc9a77c05da83453ac93a380960f36aaMiao Wang if (nw) { 6668171c40fc9a77c05da83453ac93a380960f36aaMiao Wang nw = NULL; 6768171c40fc9a77c05da83453ac93a380960f36aaMiao Wang } 6868171c40fc9a77c05da83453ac93a380960f36aaMiao Wang 6968171c40fc9a77c05da83453ac93a380960f36aaMiao Wang} 7068171c40fc9a77c05da83453ac93a380960f36aaMiao Wang 7168171c40fc9a77c05da83453ac93a380960f36aaMiao Wangextern "C" void rscAllocationDestroy(const Context *rsc, Allocation *alloc) { 7268171c40fc9a77c05da83453ac93a380960f36aaMiao Wang DrvAllocation *drv = (DrvAllocation *)alloc->mHal.drv; 7368171c40fc9a77c05da83453ac93a380960f36aaMiao Wang if (alloc->mHal.drvState.lod[0].mallocPtr) { 7468171c40fc9a77c05da83453ac93a380960f36aaMiao Wang // don't free user-allocated ptrs or IO_OUTPUT buffers 7568171c40fc9a77c05da83453ac93a380960f36aaMiao Wang if (!(drv->useUserProvidedPtr) && 7668171c40fc9a77c05da83453ac93a380960f36aaMiao Wang !(alloc->mHal.state.usageFlags & RS_ALLOCATION_USAGE_IO_INPUT) && 7768171c40fc9a77c05da83453ac93a380960f36aaMiao Wang !(alloc->mHal.state.usageFlags & RS_ALLOCATION_USAGE_IO_OUTPUT)) { 7868171c40fc9a77c05da83453ac93a380960f36aaMiao Wang free(alloc->mHal.drvState.lod[0].mallocPtr); 7968171c40fc9a77c05da83453ac93a380960f36aaMiao Wang } 8068171c40fc9a77c05da83453ac93a380960f36aaMiao Wang alloc->mHal.drvState.lod[0].mallocPtr = NULL; 8168171c40fc9a77c05da83453ac93a380960f36aaMiao Wang } 8268171c40fc9a77c05da83453ac93a380960f36aaMiao Wang 8368171c40fc9a77c05da83453ac93a380960f36aaMiao Wang if ((alloc->mHal.state.usageFlags & RS_ALLOCATION_USAGE_IO_OUTPUT) && 8468171c40fc9a77c05da83453ac93a380960f36aaMiao Wang (alloc->mHal.state.usageFlags & RS_ALLOCATION_USAGE_SCRIPT)) { 8568171c40fc9a77c05da83453ac93a380960f36aaMiao Wang ANativeWindow *nw = drv->wndSurface; 8668171c40fc9a77c05da83453ac93a380960f36aaMiao Wang if (nw) { 8768171c40fc9a77c05da83453ac93a380960f36aaMiao Wang //If we have an attached surface, need to release it. 8868171c40fc9a77c05da83453ac93a380960f36aaMiao Wang ANativeWindow_unlockAndPost(nw); 8968171c40fc9a77c05da83453ac93a380960f36aaMiao Wang drv->wndSurface = NULL; 9068171c40fc9a77c05da83453ac93a380960f36aaMiao Wang ANativeWindow_release(nw); 9168171c40fc9a77c05da83453ac93a380960f36aaMiao Wang nw = NULL; 9268171c40fc9a77c05da83453ac93a380960f36aaMiao Wang } 9368171c40fc9a77c05da83453ac93a380960f36aaMiao Wang } 9468171c40fc9a77c05da83453ac93a380960f36aaMiao Wang} 9568171c40fc9a77c05da83453ac93a380960f36aaMiao Wang 9668171c40fc9a77c05da83453ac93a380960f36aaMiao Wangextern "C" void rscAllocationIoSend(const Context *rsc, Allocation *alloc) { 9768171c40fc9a77c05da83453ac93a380960f36aaMiao Wang DrvAllocation *drv = (DrvAllocation *)alloc->mHal.drv; 9868171c40fc9a77c05da83453ac93a380960f36aaMiao Wang ANativeWindow *nw = drv->wndSurface; 9968171c40fc9a77c05da83453ac93a380960f36aaMiao Wang if (nw) { 10068171c40fc9a77c05da83453ac93a380960f36aaMiao Wang if (alloc->mHal.state.usageFlags & RS_ALLOCATION_USAGE_SCRIPT) { 10168171c40fc9a77c05da83453ac93a380960f36aaMiao Wang int32_t r = ANativeWindow_unlockAndPost(nw); 10268171c40fc9a77c05da83453ac93a380960f36aaMiao Wang if (r) { 10368171c40fc9a77c05da83453ac93a380960f36aaMiao Wang LOG_API("Error sending IO output buffer."); 10468171c40fc9a77c05da83453ac93a380960f36aaMiao Wang return; 10568171c40fc9a77c05da83453ac93a380960f36aaMiao Wang } 10668171c40fc9a77c05da83453ac93a380960f36aaMiao Wang IoGetBuffer(rsc, alloc, nw); 10768171c40fc9a77c05da83453ac93a380960f36aaMiao Wang } 10868171c40fc9a77c05da83453ac93a380960f36aaMiao Wang } else { 10968171c40fc9a77c05da83453ac93a380960f36aaMiao Wang LOG_API("Sent IO buffer with no attached surface."); 11068171c40fc9a77c05da83453ac93a380960f36aaMiao Wang return; 11168171c40fc9a77c05da83453ac93a380960f36aaMiao Wang } 11268171c40fc9a77c05da83453ac93a380960f36aaMiao Wang} 11368171c40fc9a77c05da83453ac93a380960f36aaMiao Wang 114