Implement first pass bitmap to allocation support. The Java bindings can create a 2D allocation by passing in a Bitmap object.

This commit is contained in:
Jason Sams
2009-05-27 14:45:32 -07:00
parent cc77841f64
commit fe08d99725
10 changed files with 249 additions and 33 deletions

View File

@@ -86,6 +86,7 @@ enum RsElementPredefined {
RS_ELEMENT_USER_I32,
RS_ELEMENT_USER_FLOAT,
RS_ELEMENT_A_8,
RS_ELEMENT_RGB_565,
RS_ELEMENT_RGBA_5551,
RS_ELEMENT_RGBA_4444,

View File

@@ -58,12 +58,9 @@ typedef struct {
void (*color)(void *con, float r, float g, float b, float a);
void (*renderTriangleMesh)(void *con, RsTriangleMesh);
void (*renderTriangleMeshRange)(void *con, RsTriangleMesh, uint32_t start, uint32_t count);
void (*programFragmentBindTexture)(void *con, RsProgramFragment, uint32_t slot, RsAllocation);
void (*programFragmentBindSampler)(void *con, RsProgramFragment, uint32_t slot, RsAllocation);
void (*materialDiffuse)(void *con, float r, float g, float b, float a);
void (*materialSpecular)(void *con, float r, float g, float b, float a);
void (*lightPosition)(void *con, float x, float y, float z, float w);
@@ -76,11 +73,18 @@ typedef struct {
uint32_t (*rand)(void *con, uint32_t max);
void (*contextBindProgramFragment)(void *con, RsProgramFragment pf);
void (*contextBindProgramFragmentStore)(void *con, RsProgramFragmentStore pfs);
// Drawing funcs
void (*renderTriangleMesh)(void *con, RsTriangleMesh);
void (*renderTriangleMeshRange)(void *con, RsTriangleMesh, uint32_t start, uint32_t count);
// Assumes (GL_FIXED) x,y,z (GL_UNSIGNED_BYTE)r,g,b,a
void (*drawTriangleArray)(void *con, RsAllocation alloc, uint32_t count);
void (*contextBindProgramFragment)(void *con, RsProgramFragment pf);
void (*contextBindProgramFragmentStore)(void *con, RsProgramFragmentStore pfs);
void (*drawRect)(void *con, int32_t x1, int32_t x2, int32_t y1, int32_t y2);
} rsc_FunctionTable;
typedef void (*rsc_RunScript)(void *con, const rsc_FunctionTable *, uint32_t launchID);

View File

@@ -24,6 +24,8 @@ import android.view.MenuItem;
import android.view.Window;
import android.view.View;
import android.view.Surface;
import android.graphics.Bitmap;
import android.graphics.Color;
public class RenderScript {
private static final String LOG_TAG = "libRS_jni";
@@ -79,6 +81,8 @@ public class RenderScript {
native private int nAllocationCreateTyped(int type);
native private int nAllocationCreatePredefSized(int predef, int count);
native private int nAllocationCreateSized(int elem, int count);
native private int nAllocationCreateFromBitmap(int w, int h, int dstFmt, int srcFmt, boolean genMips, int[] data);
//native private int nAllocationCreateFromBitmap(type.mID);
native private void nAllocationUploadToTexture(int alloc, int baseMioLevel);
native private void nAllocationDestroy(int alloc);
@@ -180,20 +184,21 @@ public class RenderScript {
USER_I32 (5),
USER_FLOAT (6),
RGB_565 (7),
RGBA_5551 (8),
RGBA_4444 (9),
RGB_888 (10),
RGBA_8888 (11),
A_8 (7),
RGB_565 (8),
RGBA_5551 (9),
RGBA_4444 (10),
RGB_888 (11),
RGBA_8888 (12),
INDEX_16 (12),
INDEX_32 (13),
XY_F32 (14),
XYZ_F32 (15),
ST_XY_F32 (16),
ST_XYZ_F32 (17),
NORM_XYZ_F32 (18),
NORM_ST_XYZ_F32 (19);
INDEX_16 (13),
INDEX_32 (14),
XY_F32 (15),
XYZ_F32 (16),
ST_XY_F32 (17),
ST_XYZ_F32 (18),
NORM_XYZ_F32 (19),
NORM_ST_XYZ_F32 (20);
int mID;
ElementPredefined(int id) {
@@ -435,10 +440,44 @@ public class RenderScript {
return new Allocation(id);
}
//public Allocation allocationCreateFromBitmap(string file, boolean genMips) {
//int id = nAllocationCreateTyped(type.mID);
//return new Allocation(id);
//}
public Allocation allocationCreateFromBitmap(Bitmap b, ElementPredefined dstFmt, boolean genMips) {
int w = b.getWidth();
int h = b.getHeight();
int[] data = new int[w * h];
int outPtr = 0;
for(int y=0; y < h; y++) {
for(int x=0; x < w; x++) {
data[outPtr] = b.getPixel(x, y);
outPtr++;
}
}
int srcFmt = 0;
/*
switch(b.getConfig()) {
case ALPHA_8:
srcFmt = ElementPredefined.A_8.mID;
break;
case ARGB_4444:
srcFmt = ElementPredefined.RGBA_4444.mID;
break;
case ARGB_8888:
srcFmt = ElementPredefined.RGBA_8888.mID;
break;
case RGB_565:
srcFmt = ElementPredefined.RGB_565.mID;
break;
default:
Log.e(LOG_TAG, "allocationCreateFromBitmap, unknown bitmap format");
}
*/
srcFmt = ElementPredefined.RGBA_8888.mID;
int id = nAllocationCreateFromBitmap(w, h, dstFmt.mID, srcFmt, genMips, data);
return new Allocation(id);
}
//////////////////////////////////////////////////////////////////////////////////
// Adapter1D

View File

@@ -195,6 +195,10 @@ void test_script(void *con, const rsc_FunctionTable *ft, uint32_t launchID)
}
}
ft->contextBindProgramFragment(con, (RsProgramFragment)ft->loadEnvI32(con, 0, 7));
ft->drawRect(con, 0, 256, 0, 512);
ft->contextBindProgramFragment(con, (RsProgramFragment)ft->loadEnvI32(con, 0, 6));
if (touch) {
int newPart = ft->loadEnvI32(con, 2, 0);
for (int ct2=0; ct2<rate; ct2++) {
@@ -453,6 +457,21 @@ nAllocationUploadToTexture(JNIEnv *_env, jobject _this, jint a, jint mip)
rsAllocationUploadToTexture((RsAllocation)a, mip);
}
static int
nAllocationCreateFromBitmap(JNIEnv *_env, jobject _this, jint w, jint h, jint dstFmt, jint srcFmt, jboolean genMips, jintArray data)
{
RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
jint len = _env->GetArrayLength(data);
LOG_API("nAllocationCreateFromBitmap, con(%p), w(%i), h(%i), dstFmt(%i), srcFmt(%i), mip(%i), len(%i)", con, w, h, dstFmt, srcFmt, genMips, len);
jint *ptr = _env->GetIntArrayElements(data, NULL);
jint id = (jint)rsAllocationCreateFromBitmap(w, h, (RsElementPredefined)dstFmt, (RsElementPredefined)srcFmt, genMips, ptr);
_env->ReleaseIntArrayElements(data, ptr, JNI_ABORT);
return id;
}
static void
nAllocationDestroy(JNIEnv *_env, jobject _this, jint a)
{
@@ -939,7 +958,7 @@ static JNINativeMethod methods[] = {
{"nAllocationCreateTyped", "(I)I", (void*)nAllocationCreateTyped },
{"nAllocationCreatePredefSized", "(II)I", (void*)nAllocationCreatePredefSized },
{"nAllocationCreateSized", "(II)I", (void*)nAllocationCreateSized },
//{"nAllocationCreateFromBitmap", "(I)V", (void*)nAllocationCreateFromBitmap },
{"nAllocationCreateFromBitmap", "(IIIIZ[I)I", (void*)nAllocationCreateFromBitmap },
{"nAllocationUploadToTexture", "(II)V", (void*)nAllocationUploadToTexture },
{"nAllocationDestroy", "(I)V", (void*)nAllocationDestroy },
{"nAllocationData", "(I[I)V", (void*)nAllocationData_i },

View File

@@ -83,12 +83,23 @@ AllocationCreateSized {
ret RsAllocation
}
AllocationCreateFromBitmap {
AllocationCreateFromFile {
param const char *file
param bool genMips
ret RsAllocation
}
AllocationCreateFromBitmap {
param uint32_t width
param uint32_t height
param RsElementPredefined dstFmt
param RsElementPredefined srcFmt
param bool genMips
param const void * data
ret RsAllocation
}
AllocationUploadToTexture {
param RsAllocation alloc
param uint32_t baseMipLevel

View File

@@ -213,7 +213,104 @@ static void mip(const Adapter2D &out, const Adapter2D &in)
}
RsAllocation rsi_AllocationCreateFromBitmap(Context *rsc, const char *file, bool genMips)
typedef void (*ElementConverter_t)(void *dst, const void *src, uint32_t count);
static void elementConverter_cpy_16(void *dst, const void *src, uint32_t count)
{
memcpy(dst, src, count * 2);
}
static void elementConverter_cpy_8(void *dst, const void *src, uint32_t count)
{
memcpy(dst, src, count);
}
static void elementConverter_cpy_32(void *dst, const void *src, uint32_t count)
{
memcpy(dst, src, count * 4);
}
static void elementConverter_888_to_565(void *dst, const void *src, uint32_t count)
{
uint16_t *d = static_cast<uint16_t *>(dst);
const uint8_t *s = static_cast<const uint8_t *>(src);
while(count--) {
*d = rs888to565(s[0], s[1], s[2]);
d++;
s+= 3;
}
}
static void elementConverter_8888_to_565(void *dst, const void *src, uint32_t count)
{
uint16_t *d = static_cast<uint16_t *>(dst);
const uint8_t *s = static_cast<const uint8_t *>(src);
while(count--) {
*d = rs888to565(s[0], s[1], s[2]);
d++;
s+= 4;
}
}
static ElementConverter_t pickConverter(RsElementPredefined dstFmt, RsElementPredefined srcFmt)
{
if ((dstFmt == RS_ELEMENT_RGB_565) &&
(srcFmt == RS_ELEMENT_RGB_565)) {
return elementConverter_cpy_16;
}
if ((dstFmt == RS_ELEMENT_RGB_565) &&
(srcFmt == RS_ELEMENT_RGB_888)) {
return elementConverter_888_to_565;
}
if ((dstFmt == RS_ELEMENT_RGB_565) &&
(srcFmt == RS_ELEMENT_RGBA_8888)) {
return elementConverter_8888_to_565;
}
LOGE("pickConverter, unsuported combo");
return 0;
}
RsAllocation rsi_AllocationCreateFromBitmap(Context *rsc, uint32_t w, uint32_t h, RsElementPredefined dstFmt, RsElementPredefined srcFmt, bool genMips, const void *data)
{
rsi_TypeBegin(rsc, rsi_ElementGetPredefined(rsc, RS_ELEMENT_RGB_565));
rsi_TypeAdd(rsc, RS_DIMENSION_X, w);
rsi_TypeAdd(rsc, RS_DIMENSION_Y, h);
if (genMips) {
rsi_TypeAdd(rsc, RS_DIMENSION_LOD, 1);
}
RsType type = rsi_TypeCreate(rsc);
RsAllocation vTexAlloc = rsi_AllocationCreateTyped(rsc, type);
Allocation *texAlloc = static_cast<Allocation *>(vTexAlloc);
if (texAlloc == NULL) {
LOGE("Memory allocation failure");
return NULL;
}
texAlloc->incRef();
ElementConverter_t cvt = pickConverter(dstFmt, srcFmt);
cvt(texAlloc->getPtr(), data, w * h);
if (genMips) {
Adapter2D adapt(texAlloc);
Adapter2D adapt2(texAlloc);
for(uint32_t lod=0; lod < (texAlloc->getType()->getLODCount() -1); lod++) {
adapt.setLOD(lod);
adapt2.setLOD(lod + 1);
mip(adapt2, adapt);
}
}
return texAlloc;
}
RsAllocation rsi_AllocationCreateFromFile(Context *rsc, const char *file, bool genMips)
{
typedef struct _Win3xBitmapHeader
{

View File

@@ -74,7 +74,7 @@ void Context::runRootScript()
if(mRootScript->mIsOrtho) {
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrthof(0, 320, 0, 480, 0, 1);
glOrthof(0, 320, 480, 0, 0, 1);
glMatrixMode(GL_MODELVIEW);
} else {
glMatrixMode(GL_PROJECTION);

View File

@@ -91,6 +91,10 @@ void ElementState::initPredefined()
e->setComponent(0, f_32);
mPredefinedList.add(Predefined(RS_ELEMENT_USER_FLOAT, e));
e = new Element(1);
e->setComponent(0, a_8);
mPredefinedList.add(Predefined(RS_ELEMENT_A_8, e));
e = new Element(3);
e->setComponent(0, r_5);
e->setComponent(1, g_6);

View File

@@ -40,7 +40,7 @@ void ProgramFragment::setupGL()
for (uint32_t ct=0; ct < MAX_TEXTURE; ct++) {
glActiveTexture(GL_TEXTURE0 + ct);
if (!(mTextureEnableMask & (1 << ct)) ||
!mSamplers[ct].get() ||
//!mSamplers[ct].get() ||
!mTextures[ct].get()) {
glDisable(GL_TEXTURE_2D);
@@ -62,7 +62,14 @@ void ProgramFragment::setupGL()
break;
}
mSamplers[ct]->setupGL();
// if (mSamplers[ct].get()) {
//mSamplers[ct]->setupGL();
// } else {
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
//}
}
glActiveTexture(GL_TEXTURE0);
}

View File

@@ -261,6 +261,35 @@ extern "C" void drawTriangleArray(void *vp, RsAllocation alloc, uint32_t count)
glDrawArrays(GL_TRIANGLES, 0, count * 3);
}
extern "C" void drawRect(void *vp, int32_t x1, int32_t x2, int32_t y1, int32_t y2)
{
x1 = (x1 << 16);
x2 = (x2 << 16);
y1 = (y1 << 16);
y2 = (y2 << 16);
int32_t vtx[] = {x1,y1, x1,y2, x2,y1, x2,y2};
static const int32_t tex[] = {0,0, 0,0x10000, 0x10000,0, 0x10000,0x10000};
ScriptC::Env * env = static_cast<ScriptC::Env *>(vp);
env->mContext->setupCheck();
glBindBuffer(GL_ARRAY_BUFFER, 0);
//glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, tm->mBufferObjects[1]);
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glDisableClientState(GL_NORMAL_ARRAY);
glDisableClientState(GL_COLOR_ARRAY);
glVertexPointer(2, GL_FIXED, 8, vtx);
glTexCoordPointer(2, GL_FIXED, 8, tex);
//glColorPointer(4, GL_UNSIGNED_BYTE, 12, ptr);
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
}
extern "C" void pfBindTexture(void *vp, RsProgramFragment vpf, uint32_t slot, RsAllocation va)
{
//LOGE("pfBindTexture %p", vpf);
@@ -326,8 +355,6 @@ static rsc_FunctionTable scriptCPtrTable = {
matrixTranslate,
color,
renderTriangleMesh,
renderTriangleMeshRange,
pfBindTexture,
pfBindSampler,
@@ -341,9 +368,16 @@ static rsc_FunctionTable scriptCPtrTable = {
disable,
scriptRand,
drawTriangleArray,
contextBindProgramFragment,
contextBindProgramFragmentStore
contextBindProgramFragmentStore,
renderTriangleMesh,
renderTriangleMeshRange,
drawTriangleArray,
drawRect
};