blob: 96eb19adac71c8c9cdee90efad008a7c749a56d2 [file] [log] [blame]
#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;
}
}