Implement first pass bitmap to allocation support.  The Java bindings can create a 2D allocation by passing in a Bitmap object.
diff --git a/RenderScript.h b/RenderScript.h
index e1a4b6d..378fccc 100644
--- a/RenderScript.h
+++ b/RenderScript.h
@@ -86,6 +86,7 @@
     RS_ELEMENT_USER_I32,
     RS_ELEMENT_USER_FLOAT, 
 
+    RS_ELEMENT_A_8, 
     RS_ELEMENT_RGB_565, 
     RS_ELEMENT_RGBA_5551, 
     RS_ELEMENT_RGBA_4444, 
diff --git a/RenderScriptEnv.h b/RenderScriptEnv.h
index 9ba1a00..dfca56c 100644
--- a/RenderScriptEnv.h
+++ b/RenderScriptEnv.h
@@ -58,12 +58,9 @@
 
     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 @@
 
     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);
diff --git a/java/Fountain/src/com/android/fountain/RenderScript.java b/java/Fountain/src/com/android/fountain/RenderScript.java
index bab9666..ffde1a2 100644
--- a/java/Fountain/src/com/android/fountain/RenderScript.java
+++ b/java/Fountain/src/com/android/fountain/RenderScript.java
@@ -24,6 +24,8 @@
 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 @@
     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 @@
         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 @@
         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
diff --git a/jni/RenderScript_jni.cpp b/jni/RenderScript_jni.cpp
index b3444c0..f3502e1 100644
--- a/jni/RenderScript_jni.cpp
+++ b/jni/RenderScript_jni.cpp
@@ -195,6 +195,10 @@
         }
     }
 
+    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 @@
     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 @@
 {"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 },
diff --git a/rs.spec b/rs.spec
index 6168bd7..65a4a82 100644
--- a/rs.spec
+++ b/rs.spec
@@ -83,12 +83,23 @@
 	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
diff --git a/rsAllocation.cpp b/rsAllocation.cpp
index f3f2e46..7b8bc80 100644
--- a/rsAllocation.cpp
+++ b/rsAllocation.cpp
@@ -213,7 +213,104 @@
 }
 
 
-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
     {
diff --git a/rsContext.cpp b/rsContext.cpp
index 163cf4d..abc5f45 100644
--- a/rsContext.cpp
+++ b/rsContext.cpp
@@ -74,7 +74,7 @@
     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);
diff --git a/rsElement.cpp b/rsElement.cpp
index 1637544..bd11f72 100644
--- a/rsElement.cpp
+++ b/rsElement.cpp
@@ -91,6 +91,10 @@
     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);
diff --git a/rsProgramFragment.cpp b/rsProgramFragment.cpp
index 5367c53..1a6e2c7 100644
--- a/rsProgramFragment.cpp
+++ b/rsProgramFragment.cpp
@@ -40,7 +40,7 @@
     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 @@
             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);
 }
diff --git a/rsScriptC.cpp b/rsScriptC.cpp
index 3c4bfa2..60339ec 100644
--- a/rsScriptC.cpp
+++ b/rsScriptC.cpp
@@ -261,6 +261,35 @@
     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 @@
     matrixTranslate,
 
     color,
-    renderTriangleMesh,
-    renderTriangleMeshRange,
 
     pfBindTexture,
     pfBindSampler,
@@ -341,9 +368,16 @@
     disable,
 
     scriptRand,
-    drawTriangleArray,
     contextBindProgramFragment,
-    contextBindProgramFragmentStore
+    contextBindProgramFragmentStore,
+
+
+    renderTriangleMesh,
+    renderTriangleMeshRange,
+
+    drawTriangleArray,
+    drawRect
+
 };