Beging IO stream out from allocation to surface texture.

Change-Id: I4d6b7f7740a896d39b811d6fe7532bb00db62373
This commit is contained in:
Jason Sams
2012-02-15 12:04:24 -08:00
parent ea555e2740
commit 163766cbe7
10 changed files with 301 additions and 18 deletions

View File

@@ -102,7 +102,7 @@ public class Allocation extends BaseObj {
public static final int USAGE_SCRIPT = 0x0001;
/**
* GRAPHICS_TEXTURE The allcation will be used as a texture
* GRAPHICS_TEXTURE The allocation will be used as a texture
* source by one or more graphics programs.
*
*/
@@ -124,34 +124,34 @@ public class Allocation extends BaseObj {
public static final int USAGE_GRAPHICS_CONSTANTS = 0x0008;
/**
* USAGE_GRAPHICS_RENDER_TARGET The allcation will be used as a
* USAGE_GRAPHICS_RENDER_TARGET The allocation will be used as a
* target for offscreen rendering
*
*/
public static final int USAGE_GRAPHICS_RENDER_TARGET = 0x0010;
/**
* USAGE_GRAPHICS_SURFACE_TEXTURE_INPUT The allocation will be
* used with a SurfaceTexture object. This usage will cause the
* allocation to be created read only.
* USAGE_GRAPHICS_SURFACE_TEXTURE_INPUT_OPAQUE The allocation
* will be used as a SurfaceTexture graphics consumer. This
* usage may only be used with USAGE_GRAPHICS_TEXTURE.
*
* @hide
*/
public static final int USAGE_GRAPHICS_SURFACE_TEXTURE_INPUT_OPAQUE = 0x0020;
/**
* USAGE_IO_INPUT The allocation will be
* used with a SurfaceTexture object. This usage will cause the
* allocation to be created read only.
* USAGE_IO_INPUT The allocation will be used as SurfaceTexture
* consumer. This usage will cause the allocation to be created
* read only.
*
* @hide
*/
public static final int USAGE_IO_INPUT = 0x0040;
/**
* USAGE_IO_OUTPUT The allocation will be
* used with a SurfaceTexture object. This usage will cause the
* allocation to be created write only.
* USAGE_IO_OUTPUT The allocation will be used as a
* SurfaceTexture producer. The dimensions and format of the
* SurfaceTexture will be forced to those of the allocation.
*
* @hide
*/
@@ -323,6 +323,37 @@ public class Allocation extends BaseObj {
mRS.nAllocationSyncAll(getIDSafe(), srcLocation);
}
/**
* Send a buffer to the output stream. The contents of the
* Allocation will be undefined after this operation.
*
* @hide
*
*/
public void ioSendOutput() {
if ((mUsage & USAGE_IO_OUTPUT) == 0) {
throw new RSIllegalArgumentException(
"Can only send buffer if IO_OUTPUT usage specified.");
}
mRS.validate();
mRS.nAllocationIoSend(getID());
}
/**
* Receive the latest input into the Allocation.
*
* @hide
*
*/
public void ioGetInput() {
if ((mUsage & USAGE_IO_INPUT) == 0) {
throw new RSIllegalArgumentException(
"Can only send buffer if IO_OUTPUT usage specified.");
}
mRS.validate();
mRS.nAllocationIoReceive(getID());
}
public void copyFrom(BaseObj[] d) {
mRS.validate();
validateIsObject();
@@ -887,17 +918,37 @@ public class Allocation extends BaseObj {
updateCacheInfo(mType);
}
/*
/**
* Resize a 2D allocation. The contents of the allocation are
* preserved. If new elements are allocated objects are created
* with null contents and the new region is otherwise undefined.
*
* If the new region is smaller the references of any objects
* outside the new region will be released.
*
* A new type will be created with the new dimension.
*
* @hide
* @param dimX The new size of the allocation.
* @param dimY The new size of the allocation.
*/
public void resize(int dimX, int dimY) {
if ((mType.getZ() > 0) || mType.getFaces() || mType.getLOD()) {
throw new RSIllegalStateException("Resize only support for 2D allocations at this time.");
if ((mType.getZ() > 0) || mType.hasFaces() || mType.hasMipmaps()) {
throw new RSInvalidStateException(
"Resize only support for 2D allocations at this time.");
}
if (mType.getY() == 0) {
throw new RSIllegalStateException("Resize only support for 2D allocations at this time.");
throw new RSInvalidStateException(
"Resize only support for 2D allocations at this time.");
}
mRS.nAllocationResize2D(getID(), dimX, dimY);
mRS.finish(); // Necessary because resize is fifoed and update is async.
int typeID = mRS.nAllocationGetType(getID());
mType = new Type(typeID, mRS);
mType.updateFromNative();
updateCacheInfo(mType);
}
*/
@@ -1090,6 +1141,18 @@ public class Allocation extends BaseObj {
}
/**
* @hide
*/
public void setSurfaceTexture(SurfaceTexture sur) {
if ((mUsage & USAGE_IO_OUTPUT) == 0) {
throw new RSInvalidStateException("Allocation is not USAGE_IO_OUTPUT.");
}
mRS.validate();
mRS.nAllocationSetSurfaceTexture(getID(), sur);
}
/**
* Creates a non-mipmapped renderscript allocation to use as a

View File

@@ -274,6 +274,22 @@ public class RenderScript {
validate();
return rsnAllocationGetSurfaceTextureID(mContext, alloc);
}
native void rsnAllocationSetSurfaceTexture(int con, int alloc, SurfaceTexture sur);
synchronized void nAllocationSetSurfaceTexture(int alloc, SurfaceTexture sur) {
validate();
rsnAllocationSetSurfaceTexture(mContext, alloc, sur);
}
native void rsnAllocationIoSend(int con, int alloc);
synchronized void nAllocationIoSend(int alloc) {
validate();
rsnAllocationIoSend(mContext, alloc);
}
native void rsnAllocationIoReceive(int con, int alloc);
synchronized void nAllocationIoReceive(int alloc) {
validate();
rsnAllocationIoReceive(mContext, alloc);
}
native void rsnAllocationGenerateMipmaps(int con, int alloc);
synchronized void nAllocationGenerateMipmaps(int alloc) {

View File

@@ -450,6 +450,37 @@ nAllocationGetSurfaceTextureID(JNIEnv *_env, jobject _this, RsContext con, jint
return rsAllocationGetSurfaceTextureID(con, (RsAllocation)a);
}
static void
nAllocationSetSurfaceTexture(JNIEnv *_env, jobject _this, RsContext con,
RsAllocation alloc, jobject sur)
{
LOG_API("nAllocationSetSurfaceTexture, con(%p), alloc(%p), surface(%p)",
con, alloc, (Surface *)sur);
sp<ANativeWindow> window;
if (sur != 0) {
sp<SurfaceTexture> st = SurfaceTexture_getSurfaceTexture(_env, sur);
window = new SurfaceTextureClient(st);
}
rsAllocationSetSurface(con, alloc, window.get());
}
static void
nAllocationIoSend(JNIEnv *_env, jobject _this, RsContext con, RsAllocation alloc)
{
LOG_API("nAllocationIoSend, con(%p), alloc(%p)", con, alloc);
rsAllocationIoSend(con, alloc);
}
static void
nAllocationIoReceive(JNIEnv *_env, jobject _this, RsContext con, RsAllocation alloc)
{
LOG_API("nAllocationIoReceive, con(%p), alloc(%p)", con, alloc);
rsAllocationIoReceive(con, alloc);
}
static void
nAllocationGenerateMipmaps(JNIEnv *_env, jobject _this, RsContext con, jint alloc)
{
@@ -1277,6 +1308,9 @@ static JNINativeMethod methods[] = {
{"rsnAllocationSyncAll", "(III)V", (void*)nAllocationSyncAll },
{"rsnAllocationGetSurfaceTextureID", "(II)I", (void*)nAllocationGetSurfaceTextureID },
{"rsnAllocationSetSurfaceTexture", "(IILandroid/graphics/SurfaceTexture;)V", (void*)nAllocationSetSurfaceTexture },
{"rsnAllocationIoSend", "(II)V", (void*)nAllocationIoSend },
{"rsnAllocationIoReceive", "(II)V", (void*)nAllocationIoReceive },
{"rsnAllocationData1D", "(IIIII[II)V", (void*)nAllocationData1D_i },
{"rsnAllocationData1D", "(IIIII[SI)V", (void*)nAllocationData1D_s },
{"rsnAllocationData1D", "(IIIII[BI)V", (void*)nAllocationData1D_b },

View File

@@ -23,6 +23,11 @@
#include "rsAllocation.h"
#include "system/window.h"
#include "hardware/gralloc.h"
#include "ui/Rect.h"
#include "ui/GraphicBufferMapper.h"
#include <GLES/gl.h>
#include <GLES2/gl2.h>
#include <GLES/glext.h>
@@ -220,7 +225,8 @@ bool rsdAllocationInit(const Context *rsc, Allocation *alloc, bool forceZero) {
}
void * ptr = alloc->mHal.state.usrPtr;
if (!ptr) {
if (alloc->mHal.state.usageFlags & RS_ALLOCATION_USAGE_IO_OUTPUT) {
} else {
ptr = malloc(alloc->mHal.state.type->getSizeBytes());
if (!ptr) {
free(drv);
@@ -248,7 +254,7 @@ bool rsdAllocationInit(const Context *rsc, Allocation *alloc, bool forceZero) {
alloc->mHal.drvState.mallocPtr = ptr;
drv->mallocPtr = (uint8_t *)ptr;
alloc->mHal.drv = drv;
if (forceZero) {
if (forceZero && ptr) {
memset(ptr, 0, alloc->mHal.state.type->getSizeBytes());
}
@@ -386,6 +392,93 @@ int32_t rsdAllocationInitSurfaceTexture(const Context *rsc, const Allocation *al
return drv->textureID;
}
static bool IoGetBuffer(const Context *rsc, Allocation *alloc, ANativeWindow *nw) {
DrvAllocation *drv = (DrvAllocation *)alloc->mHal.drv;
int32_t r = nw->dequeueBuffer(nw, &drv->wndBuffer);
if (r) {
rsc->setError(RS_ERROR_DRIVER, "Error getting next IO output buffer.");
return false;
}
// This lock is implicitly released by the queue buffer in IoSend
r = nw->lockBuffer(nw, drv->wndBuffer);
if (r) {
rsc->setError(RS_ERROR_DRIVER, "Error locking next IO output buffer.");
return false;
}
// Must lock the whole surface
GraphicBufferMapper &mapper = GraphicBufferMapper::get();
Rect bounds(drv->wndBuffer->width, drv->wndBuffer->height);
void *dst = NULL;
mapper.lock(drv->wndBuffer->handle,
GRALLOC_USAGE_SW_READ_NEVER | GRALLOC_USAGE_SW_WRITE_OFTEN,
bounds, &dst);
alloc->mHal.drvState.mallocPtr = dst;
return true;
}
void rsdAllocationSetSurfaceTexture(const Context *rsc, Allocation *alloc, ANativeWindow *nw) {
DrvAllocation *drv = (DrvAllocation *)alloc->mHal.drv;
//ALOGE("rsdAllocationSetSurfaceTexture %p %p", alloc, nw);
// Cleanup old surface if there is one.
if (alloc->mHal.state.wndSurface) {
ANativeWindow *old = alloc->mHal.state.wndSurface;
GraphicBufferMapper &mapper = GraphicBufferMapper::get();
mapper.unlock(drv->wndBuffer->handle);
old->queueBuffer(old, drv->wndBuffer);
}
if (nw != NULL) {
int32_t r;
r = native_window_set_usage(nw, GRALLOC_USAGE_SW_READ_RARELY |
GRALLOC_USAGE_SW_WRITE_OFTEN);
if (r) {
rsc->setError(RS_ERROR_DRIVER, "Error setting IO output buffer usage.");
return;
}
r = native_window_set_buffers_dimensions(nw, alloc->mHal.state.dimensionX,
alloc->mHal.state.dimensionY);
if (r) {
rsc->setError(RS_ERROR_DRIVER, "Error setting IO output buffer dimensions.");
return;
}
r = native_window_set_buffer_count(nw, 3);
if (r) {
rsc->setError(RS_ERROR_DRIVER, "Error setting IO output buffer count.");
return;
}
IoGetBuffer(rsc, alloc, nw);
}
}
void rsdAllocationIoSend(const Context *rsc, Allocation *alloc) {
DrvAllocation *drv = (DrvAllocation *)alloc->mHal.drv;
ANativeWindow *nw = alloc->mHal.state.wndSurface;
GraphicBufferMapper &mapper = GraphicBufferMapper::get();
mapper.unlock(drv->wndBuffer->handle);
int32_t r = nw->queueBuffer(nw, drv->wndBuffer);
if (r) {
rsc->setError(RS_ERROR_DRIVER, "Error sending IO output buffer.");
return;
}
IoGetBuffer(rsc, alloc, nw);
}
void rsdAllocationIoReceive(const Context *rsc, Allocation *alloc) {
ALOGE("not implemented");
}
void rsdAllocationData1D(const Context *rsc, const Allocation *alloc,
uint32_t xoff, uint32_t lod, uint32_t count,
const void *data, uint32_t sizeBytes) {

View File

@@ -24,6 +24,7 @@
#include <GLES2/gl2.h>
class RsdFrameBufferObj;
struct ANativeWindowBuffer;
struct DrvAllocation {
// Is this a legal structure to be used as a texture source.
@@ -47,6 +48,7 @@ struct DrvAllocation {
bool uploadDeferred;
RsdFrameBufferObj * readBackFBO;
ANativeWindowBuffer *wndBuffer;
};
GLenum rsdTypeToGLType(RsDataType t);
@@ -69,6 +71,12 @@ void rsdAllocationMarkDirty(const android::renderscript::Context *rsc,
const android::renderscript::Allocation *alloc);
int32_t rsdAllocationInitSurfaceTexture(const android::renderscript::Context *rsc,
const android::renderscript::Allocation *alloc);
void rsdAllocationSetSurfaceTexture(const android::renderscript::Context *rsc,
android::renderscript::Allocation *alloc, ANativeWindow *nw);
void rsdAllocationIoSend(const android::renderscript::Context *rsc,
android::renderscript::Allocation *alloc);
void rsdAllocationIoReceive(const android::renderscript::Context *rsc,
android::renderscript::Allocation *alloc);
void rsdAllocationData1D(const android::renderscript::Context *rsc,
const android::renderscript::Allocation *alloc,

View File

@@ -74,6 +74,9 @@ static RsdHalFunctions FunctionTable = {
rsdAllocationSyncAll,
rsdAllocationMarkDirty,
rsdAllocationInitSurfaceTexture,
rsdAllocationSetSurfaceTexture,
rsdAllocationIoSend,
rsdAllocationIoReceive,
rsdAllocationData1D,
rsdAllocationData2D,
rsdAllocationData3D,

View File

@@ -69,6 +69,21 @@ AllocationGetSurfaceTextureID {
ret int32_t
}
AllocationSetSurface {
param RsAllocation alloc
param RsNativeWindow sur
sync
}
AllocationIoSend {
param RsAllocation alloc
}
AllocationIoReceive {
param RsAllocation alloc
}
ContextFinish {
sync
}

View File

@@ -17,6 +17,7 @@
#include "rsContext.h"
#include "rs_hal.h"
#include "system/window.h"
using namespace android;
using namespace android::renderscript;
@@ -44,6 +45,7 @@ Allocation * Allocation::createAllocation(Context *rsc, const Type *type, uint32
delete a;
return NULL;
}
return a;
}
@@ -420,6 +422,28 @@ int32_t Allocation::getSurfaceTextureID(const Context *rsc) {
return id;
}
void Allocation::setSurface(const Context *rsc, RsNativeWindow sur) {
ANativeWindow *nw = (ANativeWindow *)sur;
ANativeWindow *old = mHal.state.wndSurface;
if (nw) {
nw->incStrong(NULL);
}
rsc->mHal.funcs.allocation.setSurfaceTexture(rsc, this, nw);
mHal.state.wndSurface = nw;
if (old) {
old->decStrong(NULL);
}
}
void Allocation::ioSend(const Context *rsc) {
rsc->mHal.funcs.allocation.ioSend(rsc, this);
}
void Allocation::ioReceive(const Context *rsc) {
rsc->mHal.funcs.allocation.ioReceive(rsc, this);
}
/////////////////
//
@@ -670,6 +694,21 @@ int32_t rsi_AllocationGetSurfaceTextureID(Context *rsc, RsAllocation valloc) {
return alloc->getSurfaceTextureID(rsc);
}
void rsi_AllocationSetSurface(Context *rsc, RsAllocation valloc, RsNativeWindow sur) {
Allocation *alloc = static_cast<Allocation *>(valloc);
alloc->setSurface(rsc, sur);
}
void rsi_AllocationIoSend(Context *rsc, RsAllocation valloc) {
Allocation *alloc = static_cast<Allocation *>(valloc);
alloc->ioSend(rsc);
}
void rsi_AllocationIoReceive(Context *rsc, RsAllocation valloc) {
Allocation *alloc = static_cast<Allocation *>(valloc);
alloc->ioReceive(rsc);
}
}
}

View File

@@ -19,6 +19,8 @@
#include "rsType.h"
struct ANativeWindow;
// ---------------------------------------------------------------------------
namespace android {
namespace renderscript {
@@ -57,6 +59,7 @@ public:
bool hasReferences;
void * usrPtr;
int32_t surfaceTextureID;
ANativeWindow *wndSurface;
};
State state;
@@ -127,6 +130,9 @@ public:
}
int32_t getSurfaceTextureID(const Context *rsc);
void setSurface(const Context *rsc, RsNativeWindow sur);
void ioSend(const Context *rsc);
void ioReceive(const Context *rsc);
protected:
Vector<const Program *> mToDirtyList;

View File

@@ -19,6 +19,8 @@
#include <RenderScriptDefines.h>
struct ANativeWindow;
namespace android {
namespace renderscript {
@@ -115,7 +117,11 @@ typedef struct {
bool zeroNew);
void (*syncAll)(const Context *rsc, const Allocation *alloc, RsAllocationUsageType src);
void (*markDirty)(const Context *rsc, const Allocation *alloc);
int32_t (*initSurfaceTexture)(const Context *rsc, const Allocation *alloc);
void (*setSurfaceTexture)(const Context *rsc, Allocation *alloc, ANativeWindow *sur);
void (*ioSend)(const Context *rsc, Allocation *alloc);
void (*ioReceive)(const Context *rsc, Allocation *alloc);
void (*data1D)(const Context *rsc, const Allocation *alloc,
uint32_t xoff, uint32_t lod, uint32_t count,