Merge "Update allocation from bitmap. GL attribute cleanup in type."

This commit is contained in:
Alex Sakhartchouk
2010-10-11 15:03:29 -07:00
committed by Android (Google) Code Review
9 changed files with 113 additions and 10 deletions

View File

@@ -90,6 +90,18 @@ public class Allocation extends BaseObj {
subData1D(0, mType.getElementCount(), d);
}
public void updateFromBitmap(Bitmap b)
throws IllegalArgumentException {
mRS.validate();
if(mType.getX() != b.getWidth() ||
mType.getY() != b.getHeight()) {
throw new IllegalArgumentException("Cannot update allocation from bitmap, sizes mismatch");
}
mRS.nAllocationUpdateFromBitmap(mID, b);
}
public void subData(int xoff, FieldPacker fp) {
int eSize = mType.mElement.getSizeBytes();
final byte[] data = fp.getData();

View File

@@ -186,6 +186,10 @@ public class RenderScript {
synchronized int nAllocationCreateTyped(int type) {
return rsnAllocationCreateTyped(mContext, type);
}
native void rsnAllocationUpdateFromBitmap(int con, int alloc, Bitmap bmp);
synchronized void nAllocationUpdateFromBitmap(int alloc, Bitmap bmp) {
rsnAllocationUpdateFromBitmap(mContext, alloc, bmp);
}
native int rsnAllocationCreateFromBitmap(int con, int dstFmt, boolean genMips, Bitmap bmp);
synchronized int nAllocationCreateFromBitmap(int dstFmt, boolean genMips, Bitmap bmp) {
return rsnAllocationCreateFromBitmap(mContext, dstFmt, genMips, bmp);

View File

@@ -423,6 +423,23 @@ nAllocationCreateFromBitmap(JNIEnv *_env, jobject _this, RsContext con, jint dst
return 0;
}
static void
nAllocationUpdateFromBitmap(JNIEnv *_env, jobject _this, RsContext con, jint alloc, jobject jbitmap)
{
SkBitmap const * nativeBitmap =
(SkBitmap const *)_env->GetIntField(jbitmap, gNativeBitmapID);
const SkBitmap& bitmap(*nativeBitmap);
SkBitmap::Config config = bitmap.getConfig();
RsElement e = SkBitmapToPredefined(config);
if (e) {
bitmap.lockPixels();
const void* ptr = bitmap.getPixels();
rsAllocationUpdateFromBitmap(con, (RsAllocation)alloc, e, ptr);
bitmap.unlockPixels();
}
}
static void ReleaseBitmapCallback(void *bmp)
{
SkBitmap const * nativeBitmap = (SkBitmap const *)bmp;
@@ -1234,6 +1251,7 @@ static JNINativeMethod methods[] = {
{"rsnTypeGetNativeData", "(II[I)V", (void*)nTypeGetNativeData },
{"rsnAllocationCreateTyped", "(II)I", (void*)nAllocationCreateTyped },
{"rsnAllocationUpdateFromBitmap", "(IILandroid/graphics/Bitmap;)V", (void*)nAllocationUpdateFromBitmap },
{"rsnAllocationCreateFromBitmap", "(IIZLandroid/graphics/Bitmap;)I", (void*)nAllocationCreateFromBitmap },
{"rsnAllocationCreateBitmapRef", "(IILandroid/graphics/Bitmap;)I", (void*)nAllocationCreateBitmapRef },
{"rsnAllocationCreateFromAssetStream","(IIZI)I", (void*)nAllocationCreateFromAssetStream },

View File

@@ -127,6 +127,12 @@ AllocationCreateSized {
ret RsAllocation
}
AllocationUpdateFromBitmap {
param RsAllocation alloc
param RsElement srcFmt
param const void * data
}
AllocationCreateBitmapRef {
param RsType type
param void * bmpPtr

View File

@@ -26,6 +26,8 @@
#include <OpenGl/glext.h>
#endif
#include "utils/StopWatch.h"
using namespace android;
using namespace android::renderscript;
@@ -150,6 +152,8 @@ void Allocation::uploadToTexture(const Context *rsc)
return;
}
bool isFirstUpload = false;
if (!mTextureID) {
glGenTextures(1, &mTextureID);
@@ -162,6 +166,7 @@ void Allocation::uploadToTexture(const Context *rsc)
mUploadDefered = true;
return;
}
isFirstUpload = true;
}
glBindTexture(GL_TEXTURE_2D, mTextureID);
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
@@ -171,9 +176,15 @@ void Allocation::uploadToTexture(const Context *rsc)
adapt.setLOD(lod+mTextureLOD);
uint16_t * ptr = static_cast<uint16_t *>(adapt.getElement(0,0));
glTexImage2D(GL_TEXTURE_2D, lod, format,
adapt.getDimX(), adapt.getDimY(),
0, format, type, ptr);
if(isFirstUpload) {
glTexImage2D(GL_TEXTURE_2D, lod, format,
adapt.getDimX(), adapt.getDimY(),
0, format, type, ptr);
} else {
glTexSubImage2D(GL_TEXTURE_2D, lod, 0, 0,
adapt.getDimX(), adapt.getDimY(),
format, type, ptr);
}
}
if (mTextureGenMipmap) {
#ifndef ANDROID_RS_BUILD_FOR_HOST
@@ -751,6 +762,32 @@ RsAllocation rsi_AllocationCreateBitmapRef(Context *rsc, RsType vtype,
return alloc;
}
void rsi_AllocationUpdateFromBitmap(Context *rsc, RsAllocation va, RsElement _src, const void *data)
{
Allocation *texAlloc = static_cast<Allocation *>(va);
const Element *src = static_cast<const Element *>(_src);
const Element *dst = texAlloc->getType()->getElement();
uint32_t w = texAlloc->getType()->getDimX();
uint32_t h = texAlloc->getType()->getDimY();
bool genMips = texAlloc->getType()->getDimLOD();
ElementConverter_t cvt = pickConverter(dst, src);
if (cvt) {
cvt(texAlloc->getPtr(), data, w * h);
if (genMips) {
Adapter2D adapt(rsc, texAlloc);
Adapter2D adapt2(rsc, texAlloc);
for(uint32_t lod=0; lod < (texAlloc->getType()->getLODCount() -1); lod++) {
adapt.setLOD(lod);
adapt2.setLOD(lod + 1);
mip(adapt2, adapt);
}
}
} else {
rsc->setError(RS_ERROR_BAD_VALUE, "Unsupported bitmap format");
}
}
RsAllocation rsi_AllocationCreateFromBitmap(Context *rsc, uint32_t w, uint32_t h, RsElement _dst, RsElement _src, bool genMips, const void *data)
{
const Element *src = static_cast<const Element *>(_src);

View File

@@ -65,7 +65,7 @@ size_t Element::getSizeBits() const
size_t total = 0;
for (size_t ct=0; ct < mFieldCount; ct++) {
total += mFields[ct].e->mBits * mFields[ct].arraySize;;
total += mFields[ct].e->mBits * mFields[ct].arraySize;
}
return total;
}

View File

@@ -50,6 +50,7 @@ public:
uint32_t getFieldCount() const {return mFieldCount;}
const Element * getField(uint32_t idx) const {return mFields[idx].e.get();}
const char * getFieldName(uint32_t idx) const {return mFields[idx].name.string();}
uint32_t getFieldArraySize(uint32_t idx) const {return mFields[idx].arraySize;}
const Component & getComponent() const {return mComponent;}
RsDataType getType() const {return mComponent.getType();}

View File

@@ -149,13 +149,37 @@ uint32_t Type::getLODOffset(uint32_t lod, uint32_t x, uint32_t y, uint32_t z) co
return offset;
}
bool Type::isValidGLComponent(uint32_t fieldIdx) {
// Do not create attribs for padding
if(mElement->getFieldName(fieldIdx)[0] == '#') {
return false;
}
// Only GL_BYTE, GL_UNSIGNED_BYTE, GL_SHORT, GL_UNSIGNED_SHORT, GL_FIXED, GL_FLOAT are accepted.
// Filter rs types accordingly
RsDataType dt = mElement->getField(fieldIdx)->getComponent().getType();
if(dt != RS_TYPE_FLOAT_32 && dt != RS_TYPE_UNSIGNED_8 &&
dt != RS_TYPE_UNSIGNED_16 && dt != RS_TYPE_SIGNED_8 &&
dt != RS_TYPE_SIGNED_16) {
return false;
}
// Now make sure they are not arrays
uint32_t arraySize = mElement->getFieldArraySize(fieldIdx);
if(arraySize != 1) {
return false;
}
return true;
}
void Type::makeGLComponents()
{
// Count the number of gl attrs to initialize
mAttribsSize = 0;
for (uint32_t ct=0; ct < getElement()->getFieldCount(); ct++) {
if(getElement()->getFieldName(ct)[0] != '#') {
for (uint32_t ct=0; ct < mElement->getFieldCount(); ct++) {
if(isValidGLComponent(ct)) {
mAttribsSize ++;
}
}
@@ -168,10 +192,10 @@ void Type::makeGLComponents()
}
uint32_t userNum = 0;
for (uint32_t ct=0; ct < getElement()->getFieldCount(); ct++) {
const Component &c = getElement()->getField(ct)->getComponent();
for (uint32_t ct=0; ct < mElement->getFieldCount(); ct++) {
const Component &c = mElement->getField(ct)->getComponent();
if(getElement()->getFieldName(ct)[0] == '#') {
if(!isValidGLComponent(ct)) {
continue;
}
@@ -180,7 +204,7 @@ void Type::makeGLComponents()
mAttribs[userNum].type = c.getGLType();
mAttribs[userNum].normalized = c.getType() != RS_TYPE_FLOAT_32;//c.getIsNormalized();
String8 tmp(RS_SHADER_ATTR);
tmp.append(getElement()->getFieldName(ct));
tmp.append(mElement->getFieldName(ct));
mAttribs[userNum].name.setTo(tmp.string());
userNum ++;

View File

@@ -121,6 +121,7 @@ protected:
VertexArray::Attrib *mAttribs;
uint32_t mAttribsSize;
bool isValidGLComponent(uint32_t fieldIdx);
void makeGLComponents();
private: