Add "boxed" bitmap uploads which simply place a non-pow2 bitmap into the smallest larger pow texture.  The added space is filled black.
diff --git a/graphics/java/android/renderscript/RenderScript.java b/graphics/java/android/renderscript/RenderScript.java
index f829b08..2b9e448 100644
--- a/graphics/java/android/renderscript/RenderScript.java
+++ b/graphics/java/android/renderscript/RenderScript.java
@@ -96,6 +96,7 @@
     native private int  nAllocationCreatePredefSized(int predef, int count);
     native private int  nAllocationCreateSized(int elem, int count);
     native private int  nAllocationCreateFromBitmap(int dstFmt, boolean genMips, Bitmap bmp);
+    native private int  nAllocationCreateFromBitmapBoxed(int dstFmt, boolean genMips, Bitmap bmp);
 
     native private void nAllocationUploadToTexture(int alloc, int baseMioLevel);
     native private void nAllocationDestroy(int alloc);
@@ -529,7 +530,12 @@
     }
 
     public Allocation allocationCreateFromBitmap(Bitmap b, ElementPredefined dstFmt, boolean genMips) {
-        int id = nAllocationCreateFromBitmap(dstFmt.mID, genMips, b); 
+        int id = nAllocationCreateFromBitmap(dstFmt.mID, genMips, b);
+        return new Allocation(id);
+    }
+
+    public Allocation allocationCreateFromBitmapBoxed(Bitmap b, ElementPredefined dstFmt, boolean genMips) {
+        int id = nAllocationCreateFromBitmapBoxed(dstFmt.mID, genMips, b);
         return new Allocation(id);
     }
 
diff --git a/graphics/jni/android_renderscript_RenderScript.cpp b/graphics/jni/android_renderscript_RenderScript.cpp
index 573610c..6f781a0 100644
--- a/graphics/jni/android_renderscript_RenderScript.cpp
+++ b/graphics/jni/android_renderscript_RenderScript.cpp
@@ -291,6 +291,29 @@
     return 0;
 }
 
+static int
+nAllocationCreateFromBitmapBoxed(JNIEnv *_env, jobject _this, jint dstFmt, jboolean genMips, jobject jbitmap)
+{
+    RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
+    SkBitmap const * nativeBitmap =
+            (SkBitmap const *)_env->GetIntField(jbitmap, gNativeBitmapID);
+    const SkBitmap& bitmap(*nativeBitmap);
+    SkBitmap::Config config = bitmap.getConfig();
+
+    RsElementPredefined e = SkBitmapToPredefined(config);
+
+    if (e != RS_ELEMENT_USER_U8) {
+        bitmap.lockPixels();
+        const int w = bitmap.width();
+        const int h = bitmap.height();
+        const void* ptr = bitmap.getPixels();
+        jint id = (jint)rsAllocationCreateFromBitmapBoxed(w, h, (RsElementPredefined)dstFmt, e, genMips, ptr);
+        bitmap.unlockPixels();
+        return id;
+    }
+    return 0;
+}
+
 
 static void
 nAllocationDestroy(JNIEnv *_env, jobject _this, jint a)
@@ -994,6 +1017,7 @@
 {"nAllocationCreatePredefSized",   "(II)I",                                (void*)nAllocationCreatePredefSized },
 {"nAllocationCreateSized",         "(II)I",                                (void*)nAllocationCreateSized },
 {"nAllocationCreateFromBitmap",    "(IZLandroid/graphics/Bitmap;)I",       (void*)nAllocationCreateFromBitmap },
+{"nAllocationCreateFromBitmapBoxed","(IZLandroid/graphics/Bitmap;)I",       (void*)nAllocationCreateFromBitmapBoxed },
 {"nAllocationUploadToTexture",     "(II)V",                                (void*)nAllocationUploadToTexture },
 {"nAllocationDestroy",             "(I)V",                                 (void*)nAllocationDestroy },
 {"nAllocationData",                "(I[I)V",                               (void*)nAllocationData_i },
diff --git a/libs/rs/RenderScript.h b/libs/rs/RenderScript.h
index 855ea63..1d14f70 100644
--- a/libs/rs/RenderScript.h
+++ b/libs/rs/RenderScript.h
@@ -146,26 +146,26 @@
 };
 
 enum RsBlendSrcFunc {
-    RS_BLEND_SRC_ZERO, 
-    RS_BLEND_SRC_ONE, 
-    RS_BLEND_SRC_DST_COLOR, 
-    RS_BLEND_SRC_ONE_MINUS_DST_COLOR, 
-    RS_BLEND_SRC_SRC_ALPHA, 
-    RS_BLEND_SRC_ONE_MINUS_SRC_ALPHA, 
-    RS_BLEND_SRC_DST_ALPHA, 
-    RS_BLEND_SRC_ONE_MINUS_DST_ALPHA, 
-    RS_BLEND_SRC_SRC_ALPHA_SATURATE
+    RS_BLEND_SRC_ZERO,                  // 0
+    RS_BLEND_SRC_ONE,                   // 1
+    RS_BLEND_SRC_DST_COLOR,             // 2
+    RS_BLEND_SRC_ONE_MINUS_DST_COLOR,   // 3
+    RS_BLEND_SRC_SRC_ALPHA,             // 4
+    RS_BLEND_SRC_ONE_MINUS_SRC_ALPHA,   // 5
+    RS_BLEND_SRC_DST_ALPHA,             // 6
+    RS_BLEND_SRC_ONE_MINUS_DST_ALPHA,   // 7
+    RS_BLEND_SRC_SRC_ALPHA_SATURATE     // 8
 };
 
 enum RsBlendDstFunc {
-    RS_BLEND_DST_ZERO, 
-    RS_BLEND_DST_ONE, 
-    RS_BLEND_DST_SRC_COLOR, 
-    RS_BLEND_DST_ONE_MINUS_SRC_COLOR, 
-    RS_BLEND_DST_SRC_ALPHA, 
-    RS_BLEND_DST_ONE_MINUS_SRC_ALPHA, 
-    RS_BLEND_DST_DST_ALPHA, 
-    RS_BLEND_DST_ONE_MINUS_DST_ALPHA
+    RS_BLEND_DST_ZERO,                  // 0
+    RS_BLEND_DST_ONE,                   // 1
+    RS_BLEND_DST_SRC_COLOR,             // 2
+    RS_BLEND_DST_ONE_MINUS_SRC_COLOR,   // 3
+    RS_BLEND_DST_SRC_ALPHA,             // 4
+    RS_BLEND_DST_ONE_MINUS_SRC_ALPHA,   // 5
+    RS_BLEND_DST_DST_ALPHA,             // 6
+    RS_BLEND_DST_ONE_MINUS_DST_ALPHA    // 7
 };
 
 enum RsTexEnvMode {
diff --git a/libs/rs/RenderScriptEnv.h b/libs/rs/RenderScriptEnv.h
index 0789301..7a5556e 100644
--- a/libs/rs/RenderScriptEnv.h
+++ b/libs/rs/RenderScriptEnv.h
@@ -30,11 +30,3 @@
 #define RS_PROGRAM_VERTEX_PROJECTION_OFFSET 16
 #define RS_PROGRAM_VERTEX_TEXTURE_OFFSET 32
 
-//typedef int (*rsc_RunScript)(uint32_t launchIndex, const rsc_FunctionTable *);
-
-
-/* EnableCap */
-#define GL_LIGHTING                       0x0B50
-
-/* LightName */
-#define GL_LIGHT0                         0x4000
diff --git a/libs/rs/java/Film/res/raw/filmstrip.c b/libs/rs/java/Film/res/raw/filmstrip.c
index 6885251..495fe55 100644
--- a/libs/rs/java/Film/res/raw/filmstrip.c
+++ b/libs/rs/java/Film/res/raw/filmstrip.c
@@ -11,29 +11,29 @@
     int32_t triangleOffsets[64];
     float triangleOffsetsTex[64];
     int32_t triangleOffsetsCount;
-} FilmScriptUserEnv; 
-*/ 
+} FilmScriptUserEnv;
+*/
+
+#define POS_TRANSLATE 0
+#define POS_ROTATE 1
+#define POS_FOCUS 2
+
+#define STATE_TRIANGLE_OFFSET_COUNT 0
+#define STATE_LAST_FOCUS 1
+
 
 // The script enviroment has 3 env allocations.
 // bank0: (r) The enviroment structure
 // bank1: (r) The position information
 // bank2: (rw) The temporary texture state
 
-int main(int index) 
+int main(int index)
 {
     int f1,f2,f3,f4, f5,f6,f7,f8, f9,f10,f11,f12, f13,f14,f15,f16;
     int g1,g2,g3,g4, g5,g6,g7,g8, g9,g10,g11,g12, g13,g14,g15,g16;
-    float trans;
-    float rot;
-    int x;
-    float focusPos;  // float
-    int focusID;
-    int lastFocusID;
-    int imgCount;
 
-    trans = loadF(1, 0);
-    rot = loadF(1, 1);
-
+    float trans = loadF(1, POS_TRANSLATE);
+    float rot = loadF(1, POS_ROTATE);
     matrixLoadScale(&f16, 2.f, 2.f, 2.f);
     matrixTranslate(&f16, 0.f, 0.f, trans);
     matrixRotate(&f16, 90.f, 0.f, 0.f, 1.f);
@@ -46,24 +46,18 @@
     drawTriangleMesh(NAMED_mesh);
 
 
-
-    //int imgId = 0;
-
+    // Start of images.
     bindProgramFragmentStore(NAMED_PFImages);
     bindProgramFragment(NAMED_PFSImages);
     bindProgramVertex(NAMED_PVImages);
 
-    //focusPos = loadF(1, 2);
-    //focusID = 0;
-    //lastFocusID = loadI32(2, 0);
-    //imgCount = 13;
+    float focusPos = loadF(1, POS_FOCUS);
+    int focusID = 0;
+    int lastFocusID = loadI32(2, STATE_LAST_FOCUS);
+    int imgCount = 13;
 
-    /*
-    disable(GL_LIGHTING);
-
-
-    if (trans > (-.3)) {
-        focusID = -1.0 - focusPos;
+    if (trans > (-.3f)) {
+        focusID = -1.0f - focusPos;
         if (focusID >= imgCount) {
             focusID = -1;
         }
@@ -71,6 +65,7 @@
         focusID = -1;
     }
 
+    /*
     if (focusID != lastFocusID) {
         if (lastFocusID >= 0) {
             uploadToTexture(con, env->tex[lastFocusID], 1);
@@ -79,36 +74,38 @@
             uploadToTexture(con, env->tex[focusID], 0);
         }
     }
-    storeEnvI32(con, 2, 0, focusID);
+    */
+    storeI32(2, STATE_LAST_FOCUS, focusID);
 
+    int triangleOffsetsCount = loadI32(2, STATE_TRIANGLE_OFFSET_COUNT);
 
+    int imgId = 0;
     for (imgId=1; imgId <= imgCount; imgId++) {
-        float pos = focusPos + imgId + .4f;
-        int offset = (int)floor(pos*2);
-        pos -= 0.75;
-    
-        offset += env->triangleOffsetsCount / 2;
-    
-        if ((offset < 0) || (offset >= env->triangleOffsetsCount)) {
-            continue;
+        float pos = focusPos + imgId + 0.4f;
+        int offset = (int)floorf(pos * 2.f);
+        pos = pos - 0.75f;
+
+        offset = offset + triangleOffsetsCount / 2;
+
+        if (!((offset < 0) || (offset >= triangleOffsetsCount))) {
+            int start = offset -2;
+            int end = offset + 2;
+
+            if (start < 0) {
+                start = 0;
+            }
+            if (end > triangleOffsetsCount) {
+                end = triangleOffsetsCount;
+            }
+
+            bindTexture(NAMED_PFImages, 0, loadI32(0, imgId - 1));
+    /*
+            matrixLoadTranslate(con, &m, -pos - env->triangleOffsetsTex[env->triangleOffsetsCount / 2], 0, 0);
+            storeEnvMatrix(con, 3, RS_PROGRAM_VERTEX_TEXTURE_OFFSET, &m);
+            renderTriangleMeshRange(con, env->mesh, env->triangleOffsets[start], env->triangleOffsets[end] - env->triangleOffsets[start]);
+    */
         }
-    
-        int start = offset -2;
-        int end = offset + 2;
-    
-        if (start < 0) {
-            start = 0;
-        }
-        if (end > env->triangleOffsetsCount) {
-            end = env->triangleOffsetsCount;
-        }
-    
-        programFragmentBindTexture(con, env->fpImages, 0, env->tex[imgId - 1]);
-        matrixLoadTranslate(con, &m, -pos - env->triangleOffsetsTex[env->triangleOffsetsCount / 2], 0, 0); 
-        storeEnvMatrix(con, 3, RS_PROGRAM_VERTEX_TEXTURE_OFFSET, &m);
-        renderTriangleMeshRange(con, env->mesh, env->triangleOffsets[start], env->triangleOffsets[end] - env->triangleOffsets[start]);
-    } 
-*/
+    }
     return 0;
 }
 
diff --git a/libs/rs/java/Film/src/com/android/film/FilmRS.java b/libs/rs/java/Film/src/com/android/film/FilmRS.java
index fca0818..395bd35 100644
--- a/libs/rs/java/Film/src/com/android/film/FilmRS.java
+++ b/libs/rs/java/Film/src/com/android/film/FilmRS.java
@@ -25,6 +25,7 @@
 import android.content.Context;
 import android.content.res.Resources;
 import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
 import android.graphics.drawable.BitmapDrawable;
 import android.graphics.drawable.Drawable;
 import android.os.Handler;
@@ -38,6 +39,12 @@
 import android.view.MotionEvent;
 
 public class FilmRS {
+    private final int POS_TRANSLATE = 0;
+    private final int POS_ROTATE = 1;
+    private final int POS_FOCUS = 2;
+
+    private final int STATE_TRIANGLE_OFFSET_COUNT = 0;
+    private final int STATE_LAST_FOCUS = 1;
 
     public FilmRS() {
     }
@@ -56,11 +63,11 @@
         if (x > 270) {
             x = 270;
         }
-    
+
         float anim = ((float)x-50) / 270.f;
-        mBufferPos[0] = 2f * anim + 0.5f;   // translation
-        mBufferPos[1] = (anim * 40);  // rotation
-        mBufferPos[2] = ((float)y) / 16.f - 8;  // focusPos
+        mBufferPos[POS_TRANSLATE] = 2f * anim + 0.5f;   // translation
+        mBufferPos[POS_ROTATE] = (anim * 40);  // rotation
+        mBufferPos[POS_FOCUS] = ((float)y) / 16.f - 8;  // focusPos
         mAllocPos.data(mBufferPos);
     }
 
@@ -80,15 +87,19 @@
     private RenderScript.ProgramVertex mPVImages;
     private ProgramVertexAlloc mPVA;
 
-    private RenderScript.Allocation mAllocEnv;
+    private RenderScript.Allocation mImages[];
+    private RenderScript.Allocation mAllocIDs;
     private RenderScript.Allocation mAllocPos;
     private RenderScript.Allocation mAllocState;
     private RenderScript.Allocation mAllocPV;
     private RenderScript.TriangleMesh mMesh;
     private RenderScript.Light mLight;
 
-    private float[] mBufferPos;
-    private float[] mBufferPV;
+    private FilmStripMesh mFSM;
+
+    private int[] mBufferIDs;
+    private float[] mBufferPos = new float[3];
+    private int[] mBufferState;
 
     private void initSamplers() {
         mRS.samplerBegin();
@@ -112,7 +123,7 @@
         mRS.programFragmentStoreDepthFunc(RenderScript.DepthFunc.EQUAL);
         mRS.programFragmentStoreDitherEnable(false);
         mRS.programFragmentStoreDepthMask(false);
-        mRS.programFragmentStoreBlendFunc(RenderScript.BlendSrcFunc.ONE, 
+        mRS.programFragmentStoreBlendFunc(RenderScript.BlendSrcFunc.ONE,
                                           RenderScript.BlendDstFunc.ONE);
         mPFSImages = mRS.programFragmentStoreCreate();
         mPFSImages.setName("PFSImages");
@@ -148,7 +159,75 @@
     }
 
 
-    int mParams[] = new int[10];
+    private void loadImages() {
+        mBufferIDs = new int[13];
+        mImages = new RenderScript.Allocation[13];
+        mAllocIDs = mRS.allocationCreatePredefSized(
+            RenderScript.ElementPredefined.USER_FLOAT,
+            mBufferIDs.length);
+
+        Bitmap b;
+        BitmapFactory.Options opts = new BitmapFactory.Options();
+        opts.inScaled = false;
+
+        b = BitmapFactory.decodeResource(mRes, R.drawable.p01, opts);
+        mImages[0] = mRS.allocationCreateFromBitmapBoxed(b, RenderScript.ElementPredefined.RGB_565, true);
+
+        b = BitmapFactory.decodeResource(mRes, R.drawable.p02, opts);
+        mImages[1] = mRS.allocationCreateFromBitmapBoxed(b, RenderScript.ElementPredefined.RGB_565, true);
+
+        b = BitmapFactory.decodeResource(mRes, R.drawable.p03, opts);
+        mImages[2] = mRS.allocationCreateFromBitmapBoxed(b, RenderScript.ElementPredefined.RGB_565, true);
+
+        b = BitmapFactory.decodeResource(mRes, R.drawable.p04, opts);
+        mImages[3] = mRS.allocationCreateFromBitmapBoxed(b, RenderScript.ElementPredefined.RGB_565, true);
+
+        b = BitmapFactory.decodeResource(mRes, R.drawable.p05, opts);
+        mImages[4] = mRS.allocationCreateFromBitmapBoxed(b, RenderScript.ElementPredefined.RGB_565, true);
+
+        b = BitmapFactory.decodeResource(mRes, R.drawable.p06, opts);
+        mImages[5] = mRS.allocationCreateFromBitmapBoxed(b, RenderScript.ElementPredefined.RGB_565, true);
+
+        b = BitmapFactory.decodeResource(mRes, R.drawable.p07, opts);
+        mImages[6] = mRS.allocationCreateFromBitmapBoxed(b, RenderScript.ElementPredefined.RGB_565, true);
+
+        b = BitmapFactory.decodeResource(mRes, R.drawable.p08, opts);
+        mImages[7] = mRS.allocationCreateFromBitmapBoxed(b, RenderScript.ElementPredefined.RGB_565, true);
+
+        b = BitmapFactory.decodeResource(mRes, R.drawable.p09, opts);
+        mImages[8] = mRS.allocationCreateFromBitmapBoxed(b, RenderScript.ElementPredefined.RGB_565, true);
+
+        b = BitmapFactory.decodeResource(mRes, R.drawable.p10, opts);
+        mImages[9] = mRS.allocationCreateFromBitmapBoxed(b, RenderScript.ElementPredefined.RGB_565, true);
+
+        b = BitmapFactory.decodeResource(mRes, R.drawable.p11, opts);
+        mImages[10] = mRS.allocationCreateFromBitmapBoxed(b, RenderScript.ElementPredefined.RGB_565, true);
+
+        b = BitmapFactory.decodeResource(mRes, R.drawable.p12, opts);
+        mImages[11] = mRS.allocationCreateFromBitmapBoxed(b, RenderScript.ElementPredefined.RGB_565, true);
+
+        b = BitmapFactory.decodeResource(mRes, R.drawable.p13, opts);
+        mImages[12] = mRS.allocationCreateFromBitmapBoxed(b, RenderScript.ElementPredefined.RGB_565, true);
+
+        for(int ct=0; ct < mImages.length; ct++) {
+            mImages[ct].uploadToTexture(1);
+            mBufferIDs[ct] = mImages[ct].getID();
+        }
+        mAllocIDs.data(mBufferIDs);
+    }
+
+    private void initState()
+    {
+        mBufferState = new int[10];
+        mAllocState = mRS.allocationCreatePredefSized(
+            RenderScript.ElementPredefined.USER_FLOAT,
+            mBufferState.length);
+
+        mBufferState[STATE_TRIANGLE_OFFSET_COUNT] = mFSM.mTriangleOffsetsCount;
+        mBufferState[STATE_LAST_FOCUS] = -1;
+
+        mAllocState.data(mBufferState);
+    }
 
     private void initRS() {
         mElementVertex = mRS.elementGetPredefined(
@@ -157,8 +236,8 @@
             RenderScript.ElementPredefined.INDEX_16);
 
         mRS.triangleMeshBegin(mElementVertex, mElementIndex);
-        FilmStripMesh fsm = new FilmStripMesh();
-        fsm.init(mRS);
+        mFSM = new FilmStripMesh();
+        mFSM.init(mRS);
         mMesh = mRS.triangleMeshCreate();
         mMesh.setName("mesh");
 
@@ -176,19 +255,22 @@
         mRS.scriptCSetRoot(true);
         mScriptStrip = mRS.scriptCCreate();
 
-        mBufferPos = new float[3];
         mAllocPos = mRS.allocationCreatePredefSized(
-            RenderScript.ElementPredefined.USER_FLOAT, 
+            RenderScript.ElementPredefined.USER_FLOAT,
             mBufferPos.length);
 
+        loadImages();
+        initState();
+
         mPVA = new ProgramVertexAlloc(mRS);
         mPVBackground.bindAllocation(0, mPVA.mAlloc);
         mPVImages.bindAllocation(0, mPVA.mAlloc);
         mPVA.setupProjectionNormalized(320, 480);
 
 
+        mScriptStrip.bindAllocation(mAllocIDs, 0);
         mScriptStrip.bindAllocation(mAllocPos, 1);
-       //mScriptStrip.bindAllocation(gStateAlloc, 2);
+        mScriptStrip.bindAllocation(mAllocState, 2);
         mScriptStrip.bindAllocation(mPVA.mAlloc, 3);
 
 
diff --git a/libs/rs/java/Rollo/res/raw/rollo.c b/libs/rs/java/Rollo/res/raw/rollo.c
index d338d0d..960fdf0 100644
--- a/libs/rs/java/Rollo/res/raw/rollo.c
+++ b/libs/rs/java/Rollo/res/raw/rollo.c
@@ -51,7 +51,7 @@
 
     float touchCut = 1.f;
     if (loadI32(0, STATE_TOUCH)) {
-        touchCut = 5.f;
+        touchCut = 4.f;
     }
 
 
@@ -60,14 +60,17 @@
     storeF(2, SCRATCH_ZOOM, zoom);
 
     float targetRot = loadI32(0, STATE_FIRST_VISIBLE) / 180.0f * 3.14f;
-    float rot = filter(loadF(2, SCRATCH_ROT), targetRot, 0.1f * touchCut);
-    storeF(2, SCRATCH_ROT, rot);
+    float drawRot = filter(loadF(2, SCRATCH_ROT), targetRot, 0.1f * touchCut);
+    storeF(2, SCRATCH_ROT, drawRot);
 
-    float diam = 8.f;// + curve * 2.f;
+    float diam = 10.f;
     float scale = 1.0f / zoom;
 
-    rot = rot * scale;
-    float rotStep = 20.0f / 180.0f * 3.14f * scale;
+    // Bug makes 1.0f alpha fail.
+    color(1.0f, 1.0f, 1.0f, 0.99f);
+
+    float rot = drawRot * scale;
+    float rotStep = 16.0f / 180.0f * 3.14f * scale;
     rowCount = 4;
     int index = 0;
     int iconCount = loadI32(0, STATE_COUNT);
@@ -82,24 +85,55 @@
 
         int y;
         for (y = rowCount -1; (y >= 0) && iconCount; y--) {
-            float ty1 = ((y * 3.0f) - 4.5f) * scale;
+            float ty1 = ((y * 3.5f) - 6.f) * scale;
             float ty2 = ty1 + scale * 2.f;
-            bindTexture(NAMED_PF, 0, loadI32(1, y));
-            color(1.0f, 1.0f, 1.0f, 1.0f);
-            if (done && (index != selectedID)) {
-                color(0.4f, 0.4f, 0.4f, 1.0f);
-            }
+            bindTexture(NAMED_PF, 0, loadI32(1, index));
+            //if (done && (index != selectedID)) {
+                //color(0.4f, 0.4f, 0.4f, 1.0f);
+            //}
             drawQuad(tx1, ty1, tz1,
                      tx2, ty1, tz2,
                      tx2, ty2, tz2,
                      tx1, ty2, tz1);
+
             iconCount--;
             index++;
         }
         rot = rot + rotStep;
     }
 
-    return 0;
+    // Draw the selected icon
+    color(1.0f, 1.0f, 1.0f, 0.9f);
+    rot = drawRot * scale;
+    index = 0;
+    iconCount = loadI32(0, STATE_COUNT);
+    while (iconCount) {
+        int y;
+        for (y = rowCount -1; (y >= 0) && iconCount; y--) {
+            if (index == selectedID) {
+
+                float tmpSin = sinf(rot) * scale;
+                float tmpCos = cosf(rot) * scale;
+                float tx1 = tmpSin * diam * 0.9f - tmpCos * 2.f;
+                float tx2 = tx1 + (tmpCos * 4.f);
+                float tz1 = tmpCos * diam * 0.9f + tmpSin * 2.f;
+                float tz2 = tz1 - (tmpSin * 4.f);
+
+                float ty1 = ((y * 3.5f) - 5.f) * scale;
+                float ty2 = ty1 + scale * 4.f;
+                bindTexture(NAMED_PF, 0, loadI32(1, index));
+                drawQuad(tx1, ty1, tz1,
+                         tx2, ty1, tz2,
+                         tx2, ty2, tz2,
+                         tx1, ty2, tz1);
+            }
+            iconCount--;
+            index++;
+        }
+        rot = rot + rotStep;
+    }
+
+    return 1;
 }
 
 
diff --git a/libs/rs/java/Rollo/res/raw/rollo2.c b/libs/rs/java/Rollo/res/raw/rollo2.c
index b04ea73..256fa3c 100644
--- a/libs/rs/java/Rollo/res/raw/rollo2.c
+++ b/libs/rs/java/Rollo/res/raw/rollo2.c
@@ -3,65 +3,153 @@
 #pragma stateFragment(PF)
 #pragma stateFragmentStore(PFS)
 
-void drawLoop(int x, int y, int z, int rot)
+// Scratch buffer layout
+#define SCRATCH_FADE 0
+#define SCRATCH_ZOOM 1
+#define SCRATCH_ROT 2
+
+//#define STATE_POS_X             0
+#define STATE_DONE              1
+//#define STATE_PRESSURE          2
+#define STATE_ZOOM              3
+//#define STATE_WARP              4
+#define STATE_ORIENTATION       5
+#define STATE_SELECTION         6
+#define STATE_FIRST_VISIBLE     7
+#define STATE_COUNT             8
+#define STATE_TOUCH             9
+
+float filter(float val, float target, float str)
 {
-    int ct;
-    int tx;
-    int ty;
-    int tmpSin;
-    int tmpCos;
-    int sz;
-
-    for (ct = 0; ct < 10; ct ++) {
-        tmpSin = sinx((ct * 36 + rot) * 0x10000);
-        tmpCos = cosx((ct * 36 + rot) * 0x10000);
-
-        ty = y + tmpCos * 4;
-        tx = x + tmpSin * 4;
-        pfBindTexture(NAMED_PF, 0, loadI32(1, ct & 3));
-
-        sz = 0xc000;
-        drawQuad(tx - sz, ty - sz, z,
-                 tx + sz, ty - sz, z,
-                 tx + sz, ty + sz, z,
-                 tx - sz, ty + sz, z);
-    }
+    float delta = (target - val);
+    return val + delta * str;
 }
 
+
 int main(void* con, int ft, int launchID)
 {
     int rowCount;
-    int x;
-    int y;
-    int row;
-    int col;
     int imageID;
-    int tx1;
-    int ty1;
-    int tz1;
-    int tx2;
-    int ty2;
-    int tz2;
-    int tmpSin;
-    int tmpCos;
-    int iconCount;
-    int pressure;
+    int done = loadI32(0, STATE_DONE);
+    int selectedID = loadI32(0, STATE_SELECTION);
+    int iconCount = loadI32(0, STATE_COUNT);
 
-    int ringCount;
+    float f = loadF(2, 0);
 
+    float iconSize = 1.f;
+    float iconSpacing = 0.2f;
+    float z = 4.f;
 
-
-    rotStep = 16 * 0x10000;
-    pressure = loadI32(0, 2);
-    rowCount = 4;
-
-    iconCount = loadI32(0, 1);
-    rot = (-20 + loadI32(0, 0)) * 0x10000;
-
-    for (ringCount = 0; ringCount < 5; ringCount++) {
-        drawLoop(0, 0, 0x90000 + (ringCount * 0x80000));
+    pfClearColor(0.0f, 0.0f, 0.0f, f);
+    if (done) {
+    } else {
+        if (f < 0.8f) {
+            f = f + 0.02f;
+            storeF(2, 0, f);
+        }
     }
 
-    return 0;
+    float touchCut = 1.f;
+    if (loadI32(0, STATE_TOUCH)) {
+        touchCut = 5.f;
+    }
+
+
+    float targetZoom = ((float)loadI32(0, STATE_ZOOM)) / 1000.f;
+    float zoom = filter(loadF(2, SCRATCH_ZOOM), targetZoom, 0.15 * touchCut);
+    storeF(2, SCRATCH_ZOOM, zoom);
+
+    float targetPos = loadI32(0, STATE_FIRST_VISIBLE) / (-20.0f);
+    float pos = filter(loadF(2, SCRATCH_ROT), targetPos, 0.1f * touchCut);
+    storeF(2, SCRATCH_ROT, pos);
+    pos = pos - 1.f;
+
+    color(1.0f, 1.0f, 1.0f, 1.0f);
+
+
+    // Draw flat icons first
+    int index = ((int)pos) * 4;
+    int row;
+    int col;
+    float xoffset = -0.3f;
+    float gridSize = iconSize * 4.f + iconSpacing * 3.f;
+    float yoffset = (pos - ((int)pos));
+    for (row = 0; row < 4; row ++) {
+        float ty1 = (gridSize / 2.f) - ((float)row - yoffset) * (iconSize + iconSpacing) - iconSize;
+        float ty2 = ty1 + iconSize;
+
+        for (col = 0; (col < 4) && (index < iconCount); col ++) {
+            if (index >= 0) {
+                bindTexture(NAMED_PF, 0, loadI32(1, index));
+                float fcol = col;
+                float tx1 = xoffset + (-gridSize / 2.f) + (fcol * (iconSize + iconSpacing));
+                float tx2 = tx1 + iconSize;
+
+                drawQuad(tx1, ty1, z,
+                         tx2, ty1, z,
+                         tx2, ty2, z,
+                         tx1, ty2, z);
+            }
+            index++;
+        }
+    }
+
+    // bottom roller
+    {
+        float roll = (1.f - yoffset) * 0.5f * 3.14f;
+        float tmpSin = sinf(roll);
+        float tmpCos = cosf(roll);
+
+        for (col = 0; (col < 4) && (index < iconCount) && (index >= 0); col ++) {
+            float ty2 = (gridSize / 2.f) - ((float)row - yoffset) * (iconSize + iconSpacing);
+            float ty1 = ty2 - tmpCos * iconSize;
+
+            float tz1 = z + tmpSin * iconSize;
+            float tz2 = z;
+
+            float tx1 = xoffset + (-gridSize / 2.f) + ((float)col * (iconSize + iconSpacing));
+            float tx2 = tx1 + iconSize;
+
+            bindTexture(NAMED_PF, 0, loadI32(1, index));
+            drawQuad(tx1, ty1, tz1,
+                     tx2, ty1, tz1,
+                     tx2, ty2, tz2,
+                     tx1, ty2, tz2);
+            index++;
+        }
+    }
+
+    // Top roller
+    {
+        index = (((int)pos) * 4) - 4;
+        float roll = yoffset * 0.5f * 3.14f;
+        float tmpSin = sinf(roll);
+        float tmpCos = cosf(roll);
+
+        for (col = 0; (col < 4) && (index < iconCount) && (index >= 0); col ++) {
+            float ty1 = (gridSize / 2.f) - ((float)-1.f - yoffset) * (iconSize + iconSpacing) - iconSize;
+            float ty2 = ty1 + tmpCos * iconSize;
+
+            float tz1 = z;
+            float tz2 = z + tmpSin * iconSize;
+
+            float tx1 = xoffset + (-gridSize / 2.f) + ((float)col * (iconSize + iconSpacing));
+            float tx2 = tx1 + iconSize;
+
+            bindTexture(NAMED_PF, 0, loadI32(1, index));
+            drawQuad(tx1, ty1, tz1,
+                     tx2, ty1, tz1,
+                     tx2, ty2, tz2,
+                     tx1, ty2, tz2);
+            index++;
+        }
+    }
+
+
+
+
+    return 1;
 }
 
+
+
diff --git a/libs/rs/java/Rollo/src/com/android/rollo/RolloRS.java b/libs/rs/java/Rollo/src/com/android/rollo/RolloRS.java
index 8f48335..14afaf8 100644
--- a/libs/rs/java/Rollo/src/com/android/rollo/RolloRS.java
+++ b/libs/rs/java/Rollo/src/com/android/rollo/RolloRS.java
@@ -18,6 +18,7 @@
 
 import java.io.Writer;
 
+import android.renderscript.RSSurfaceView;
 import android.renderscript.RenderScript;
 import android.renderscript.ProgramVertexAlloc;
 
@@ -95,8 +96,11 @@
     private RenderScript.ProgramFragment mPFImages;
     private RenderScript.ProgramVertex mPV;
     private ProgramVertexAlloc mPVAlloc;
+    private RenderScript.ProgramVertex mPVOrtho;
+    private ProgramVertexAlloc mPVOrthoAlloc;
     private RenderScript.Allocation[] mIcons;
     private RenderScript.Allocation mIconPlate;
+    private RenderScript.Allocation mBackground;
 
     private int[] mAllocStateBuf;
     private RenderScript.Allocation mAllocState;
@@ -130,23 +134,28 @@
         mRS.programFragmentStoreBegin(null, null);
         mRS.programFragmentStoreDepthFunc(RenderScript.DepthFunc.LESS);
         mRS.programFragmentStoreDitherEnable(false);
-        mRS.programFragmentStoreDepthMask(false);
-        mRS.programFragmentStoreBlendFunc(RenderScript.BlendSrcFunc.ONE, 
-                                          RenderScript.BlendDstFunc.ONE);
+        mRS.programFragmentStoreDepthMask(true);
+        mRS.programFragmentStoreBlendFunc(RenderScript.BlendSrcFunc.SRC_ALPHA,
+                                          RenderScript.BlendDstFunc.ONE_MINUS_SRC_ALPHA);
         mPFSBackground = mRS.programFragmentStoreCreate();
         mPFSBackground.setName("PFS");
 
         mPVAlloc = new ProgramVertexAlloc(mRS);
         mRS.programVertexBegin(null, null);
-        mRS.programVertexSetTextureMatrixEnable(true);
+        mRS.programVertexSetTextureMatrixEnable(false);
         mPV = mRS.programVertexCreate();
         mPV.setName("PV");
         mPV.bindAllocation(0, mPVAlloc.mAlloc);
-
-
-
         mPVAlloc.setupProjectionNormalized(320, 480);
-        //mPVAlloc.setupOrthoNormalized(320, 480);
+
+        mPVOrthoAlloc = new ProgramVertexAlloc(mRS);
+        mRS.programVertexBegin(null, null);
+        mRS.programVertexSetTextureMatrixEnable(true);
+        mPVOrtho = mRS.programVertexCreate();
+        mPVOrtho.setName("PVOrtho");
+        mPVOrtho.bindAllocation(0, mPVOrthoAlloc.mAlloc);
+        mPVOrthoAlloc.setupOrthoWindow(320, 480);
+
         mRS.contextBindProgramVertex(mPV);
 
         mAllocScratchBuf = new int[32];
@@ -162,16 +171,21 @@
 
 
         {
-            mIcons = new RenderScript.Allocation[4];
+            mIcons = new RenderScript.Allocation[29];
             mAllocIconIDBuf = new int[mIcons.length];
             mAllocIconID = mRS.allocationCreatePredefSized(
                 RenderScript.ElementPredefined.USER_I32, mAllocIconIDBuf.length);
 
-            
+
             Bitmap b;
             BitmapFactory.Options opts = new BitmapFactory.Options();
             opts.inScaled = false;
 
+            b = BitmapFactory.decodeResource(mRes, R.raw.cf_background, opts);
+            mBackground = mRS.allocationCreateFromBitmap(b, RenderScript.ElementPredefined.RGB_565, true);
+            mBackground.setName("TexBk");
+
+
             b = BitmapFactory.decodeResource(mRes, R.raw.browser, opts);
             mIcons[0] = mRS.allocationCreateFromBitmap(b, RenderScript.ElementPredefined.RGB_565, true);
 
@@ -184,6 +198,112 @@
             b = BitmapFactory.decodeResource(mRes, R.raw.settings, opts);
             mIcons[3] = mRS.allocationCreateFromBitmap(b, RenderScript.ElementPredefined.RGB_565, true);
 
+/*
+            b = BitmapFactory.decodeResource(mRes, R.raw.assasins_creed, opts);
+            mIcons[4] = mRS.allocationCreateFromBitmap(b, RenderScript.ElementPredefined.RGB_565, true);
+
+            b = BitmapFactory.decodeResource(mRes, R.raw.bankofamerica, opts);
+            mIcons[5] = mRS.allocationCreateFromBitmap(b, RenderScript.ElementPredefined.RGB_565, true);
+
+            b = BitmapFactory.decodeResource(mRes, R.raw.chess, opts);
+            mIcons[6] = mRS.allocationCreateFromBitmap(b, RenderScript.ElementPredefined.RGB_565, true);
+
+            b = BitmapFactory.decodeResource(mRes, R.raw.dictionary, opts);
+            mIcons[7] = mRS.allocationCreateFromBitmap(b, RenderScript.ElementPredefined.RGB_565, true);
+
+            b = BitmapFactory.decodeResource(mRes, R.raw.facebook, opts);
+            mIcons[8] = mRS.allocationCreateFromBitmap(b, RenderScript.ElementPredefined.RGB_565, true);
+
+            b = BitmapFactory.decodeResource(mRes, R.raw.flashlight, opts);
+            mIcons[9] = mRS.allocationCreateFromBitmap(b, RenderScript.ElementPredefined.RGB_565, true);
+
+            b = BitmapFactory.decodeResource(mRes, R.raw.flight_control, opts);
+            mIcons[10] = mRS.allocationCreateFromBitmap(b, RenderScript.ElementPredefined.RGB_565, true);
+
+            b = BitmapFactory.decodeResource(mRes, R.raw.google_earth, opts);
+            mIcons[11] = mRS.allocationCreateFromBitmap(b, RenderScript.ElementPredefined.RGB_565, true);
+
+            b = BitmapFactory.decodeResource(mRes, R.raw.harry_potter, opts);
+            mIcons[12] = mRS.allocationCreateFromBitmap(b, RenderScript.ElementPredefined.RGB_565, true);
+
+            b = BitmapFactory.decodeResource(mRes, R.raw.movies, opts);
+            mIcons[13] = mRS.allocationCreateFromBitmap(b, RenderScript.ElementPredefined.RGB_565, true);
+
+            b = BitmapFactory.decodeResource(mRes, R.raw.nytimes, opts);
+            mIcons[14] = mRS.allocationCreateFromBitmap(b, RenderScript.ElementPredefined.RGB_565, true);
+
+            b = BitmapFactory.decodeResource(mRes, R.raw.pandora, opts);
+            mIcons[15] = mRS.allocationCreateFromBitmap(b, RenderScript.ElementPredefined.RGB_565, true);
+
+
+
+            b = BitmapFactory.decodeResource(mRes, R.raw.public_radio, opts);
+            mIcons[16] = mRS.allocationCreateFromBitmap(b, RenderScript.ElementPredefined.RGB_565, true);
+
+            b = BitmapFactory.decodeResource(mRes, R.raw.shazam, opts);
+            mIcons[17] = mRS.allocationCreateFromBitmap(b, RenderScript.ElementPredefined.RGB_565, true);
+
+            b = BitmapFactory.decodeResource(mRes, R.raw.skype, opts);
+            mIcons[18] = mRS.allocationCreateFromBitmap(b, RenderScript.ElementPredefined.RGB_565, true);
+
+            b = BitmapFactory.decodeResource(mRes, R.raw.solitaire, opts);
+            mIcons[19] = mRS.allocationCreateFromBitmap(b, RenderScript.ElementPredefined.RGB_565, true);
+
+            b = BitmapFactory.decodeResource(mRes, R.raw.sudoku, opts);
+            mIcons[20] = mRS.allocationCreateFromBitmap(b, RenderScript.ElementPredefined.RGB_565, true);
+
+            b = BitmapFactory.decodeResource(mRes, R.raw.taptaprevenge, opts);
+            mIcons[21] = mRS.allocationCreateFromBitmap(b, RenderScript.ElementPredefined.RGB_565, true);
+
+            b = BitmapFactory.decodeResource(mRes, R.raw.tetris, opts);
+            mIcons[22] = mRS.allocationCreateFromBitmap(b, RenderScript.ElementPredefined.RGB_565, true);
+
+            b = BitmapFactory.decodeResource(mRes, R.raw.tictactoe, opts);
+            mIcons[23] = mRS.allocationCreateFromBitmap(b, RenderScript.ElementPredefined.RGB_565, true);
+
+            b = BitmapFactory.decodeResource(mRes, R.raw.tweetie, opts);
+            mIcons[24] = mRS.allocationCreateFromBitmap(b, RenderScript.ElementPredefined.RGB_565, true);
+
+            b = BitmapFactory.decodeResource(mRes, R.raw.urbanspoon, opts);
+            mIcons[25] = mRS.allocationCreateFromBitmap(b, RenderScript.ElementPredefined.RGB_565, true);
+
+            b = BitmapFactory.decodeResource(mRes, R.raw.waterslide_extreme, opts);
+            mIcons[26] = mRS.allocationCreateFromBitmap(b, RenderScript.ElementPredefined.RGB_565, true);
+
+            b = BitmapFactory.decodeResource(mRes, R.raw.weather_channel, opts);
+            mIcons[27] = mRS.allocationCreateFromBitmap(b, RenderScript.ElementPredefined.RGB_565, true);
+
+            b = BitmapFactory.decodeResource(mRes, R.raw.zippo, opts);
+            mIcons[28] = mRS.allocationCreateFromBitmap(b, RenderScript.ElementPredefined.RGB_565, true);
+*/
+            mIcons[4] =  mIcons[3];
+            mIcons[5] =  mIcons[2];
+            mIcons[6] =  mIcons[1];
+            mIcons[7] =  mIcons[0];
+            mIcons[8] =  mIcons[1];
+            mIcons[9] =  mIcons[2];
+            mIcons[10] = mIcons[3];
+            mIcons[11] = mIcons[2];
+            mIcons[12] = mIcons[1];
+            mIcons[13] = mIcons[0];
+            mIcons[14] = mIcons[1];
+            mIcons[15] = mIcons[2];
+            mIcons[16] = mIcons[3];
+            mIcons[17] = mIcons[2];
+            mIcons[18] = mIcons[1];
+            mIcons[19] = mIcons[0];
+            mIcons[20] = mIcons[1];
+            mIcons[21] = mIcons[2];
+            mIcons[22] = mIcons[3];
+            mIcons[23] = mIcons[2];
+            mIcons[24] = mIcons[1];
+            mIcons[25] = mIcons[0];
+            mIcons[26] = mIcons[1];
+            mIcons[27] = mIcons[2];
+            mIcons[28] = mIcons[3];
+
+
+
             for(int ct=0; ct < mIcons.length; ct++) {
                 mIcons[ct].uploadToTexture(0);
                 mAllocIconIDBuf[ct] = mIcons[ct].getID();
@@ -221,6 +341,11 @@
 
     }
 
+    private void makeTextBitmap() {
+        //Bitmap.createBitmap(width, height, Bitmap.Config);
+        //new Canvas(theBitmap);
+        //canvas.drawText();
+    }
 
 
     private void initRS() {
@@ -232,7 +357,7 @@
         //mRS.scriptCSetClearDepth(0);
         mScript = mRS.scriptCCreate();
 
-        mAllocStateBuf = new int[] {0, 0, 0, 8, 0, 0, 0, 0, 38, 0, 0};
+        mAllocStateBuf = new int[] {0, 0, 0, 8, 0, 0, -1, 0, mAllocIconIDBuf.length, 0, 0};
         mAllocState = mRS.allocationCreatePredefSized(
             RenderScript.ElementPredefined.USER_I32, mAllocStateBuf.length);
         mScript.bindAllocation(mAllocState, 0);
@@ -248,4 +373,3 @@
 }
 
 
-
diff --git a/libs/rs/java/Rollo/src/com/android/rollo/RolloView.java b/libs/rs/java/Rollo/src/com/android/rollo/RolloView.java
index b5e02af..27f1584 100644
--- a/libs/rs/java/Rollo/src/com/android/rollo/RolloView.java
+++ b/libs/rs/java/Rollo/src/com/android/rollo/RolloView.java
@@ -76,7 +76,7 @@
     float mOldColumn;
     float mZoom = 1;
 
-    int mIconCount = 38;
+    int mIconCount = 29;
     int mRows = 4;
     int mColumns = (mIconCount + mRows - 1) / mRows;
 
@@ -101,7 +101,7 @@
 
     void computeSelection(float x, float y)
     {
-        float col = mColumn + (x - 0.5f) * 3;
+        float col = mColumn + (x - 0.5f) * 4 + 1;
         int iCol = (int)(col + 0.25f);
 
         float row = (y / 0.8f) * mRows;
@@ -158,13 +158,14 @@
                     mZoom = zoom;
                     mFlingX = nx;
                     mRender.setZoom(zoom);
-                } else {
-                    if(mControlMode && (mZoom < 1.01f)) {
+                    if(mZoom < 1.01f) {
                         computeSelection(nx, ny);
                     }
+                } else {
                     mControlMode = false;
                     mColumn = mOldColumn;
                     mRender.setZoom(1.f);
+                    mRender.setSelected(-1);
                 }
             } else {
                 // Do something with corners here....
diff --git a/libs/rs/rs.spec b/libs/rs/rs.spec
index 2f99808..45e6d1b 100644
--- a/libs/rs/rs.spec
+++ b/libs/rs/rs.spec
@@ -99,6 +99,16 @@
 	ret RsAllocation
 	}
 
+AllocationCreateFromBitmapBoxed {
+	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
diff --git a/libs/rs/rsAllocation.cpp b/libs/rs/rsAllocation.cpp
index c143307..a2e3babc 100644
--- a/libs/rs/rsAllocation.cpp
+++ b/libs/rs/rsAllocation.cpp
@@ -301,14 +301,18 @@
         return elementConverter_cpy_32;
     }
 
-    LOGE("pickConverter, unsuported combo");
+    LOGE("pickConverter, unsuported combo, src %i,  dst %i", srcFmt, dstFmt);
     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));
+    rsAssert(!(w & (w-1)));
+    rsAssert(!(h & (h-1)));
+
+    //LOGE("rsi_AllocationCreateFromBitmap %i %i %i %i %i", w, h, dstFmt, srcFmt, genMips);
+    rsi_TypeBegin(rsc, rsi_ElementGetPredefined(rsc, dstFmt));
     rsi_TypeAdd(rsc, RS_DIMENSION_X, w);
     rsi_TypeAdd(rsc, RS_DIMENSION_Y, h);
     if (genMips) {
@@ -340,6 +344,42 @@
     return texAlloc;
 }
 
+static uint32_t fmtToBits(RsElementPredefined fmt)
+{
+    return 16;
+}
+
+RsAllocation rsi_AllocationCreateFromBitmapBoxed(Context *rsc, uint32_t w, uint32_t h, RsElementPredefined dstFmt, RsElementPredefined srcFmt, bool genMips, const void *data)
+{
+    uint32_t w2 = rsHigherPow2(w);
+    uint32_t h2 = rsHigherPow2(h);
+
+    if ((w2 == w) && (h2 == h)) {
+        return rsi_AllocationCreateFromBitmap(rsc, w, h, dstFmt, srcFmt, genMips, data);
+    }
+
+    uint32_t bpp = fmtToBits(srcFmt) >> 3;
+    size_t size = w2 * h2 * bpp;
+    uint8_t *tmp = static_cast<uint8_t *>(malloc(size));
+    memset(tmp, 0, size);
+
+    const uint8_t * src = static_cast<const uint8_t *>(data);
+    for (uint32_t y = 0; y < h; y++) {
+        uint8_t * ydst = &tmp[y + ((h2 - h) >> 1)];
+        memcpy(&ydst[(w2 - w) >> 1], src, w * bpp);
+        src += h * bpp;
+    }
+
+    RsAllocation ret = rsi_AllocationCreateFromBitmap(rsc, w2, h2, dstFmt, srcFmt, genMips, tmp);
+    free(tmp);
+    return ret;
+
+
+
+
+}
+
+
 RsAllocation rsi_AllocationCreateFromFile(Context *rsc, const char *file, bool genMips)
 {
     bool use32bpp = false;
diff --git a/libs/rs/rsContext.cpp b/libs/rs/rsContext.cpp
index 78b8bf8..e52b0e0 100644
--- a/libs/rs/rsContext.cpp
+++ b/libs/rs/rsContext.cpp
@@ -79,8 +79,7 @@
     mFragment.set(frag);
     mVertex.set(vtx);
     mFragmentStore.set(store);
-    return true;
-
+    return ret;
 }
 
 
diff --git a/libs/rs/rsContext.h b/libs/rs/rsContext.h
index 497dbcf..a00b8e8 100644
--- a/libs/rs/rsContext.h
+++ b/libs/rs/rsContext.h
@@ -83,6 +83,7 @@
 
     const ProgramFragment * getFragment() {return mFragment.get();}
     const ProgramFragmentStore * getFragmentStore() {return mFragmentStore.get();}
+    const ProgramVertex * getVertex() {return mVertex.get();}
 
     void setupCheck();
 
diff --git a/libs/rs/rsProgramVertex.cpp b/libs/rs/rsProgramVertex.cpp
index 417ba6a..792135d 100644
--- a/libs/rs/rsProgramVertex.cpp
+++ b/libs/rs/rsProgramVertex.cpp
@@ -55,8 +55,6 @@
         glLoadIdentity();
     }
 
-
-    LOGE("lights %i ", mLightCount);
     glMatrixMode(GL_MODELVIEW);
     glLoadIdentity();
     if (mLightCount) {
@@ -103,6 +101,25 @@
     }
 }
 
+void ProgramVertex::setProjectionMatrix(const rsc_Matrix *m) const
+{
+    float *f = static_cast<float *>(mConstants[0]->getPtr());
+    memcpy(&f[RS_PROGRAM_VERTEX_PROJECTION_OFFSET], m, sizeof(rsc_Matrix));
+}
+
+void ProgramVertex::setModelviewMatrix(const rsc_Matrix *m) const
+{
+    float *f = static_cast<float *>(mConstants[0]->getPtr());
+    memcpy(&f[RS_PROGRAM_VERTEX_MODELVIEW_OFFSET], m, sizeof(rsc_Matrix));
+}
+
+void ProgramVertex::setTextureMatrix(const rsc_Matrix *m) const
+{
+    float *f = static_cast<float *>(mConstants[0]->getPtr());
+    memcpy(&f[RS_PROGRAM_VERTEX_TEXTURE_OFFSET], m, sizeof(rsc_Matrix));
+}
+
+
 
 ProgramVertexState::ProgramVertexState()
 {
diff --git a/libs/rs/rsProgramVertex.h b/libs/rs/rsProgramVertex.h
index ac15b70..da5ed81 100644
--- a/libs/rs/rsProgramVertex.h
+++ b/libs/rs/rsProgramVertex.h
@@ -41,6 +41,10 @@
     void setTextureMatrixEnable(bool e) {mTextureMatrixEnable = e;}
     void addLight(const Light *);
 
+    void setProjectionMatrix(const rsc_Matrix *) const;
+    void setModelviewMatrix(const rsc_Matrix *) const;
+    void setTextureMatrix(const rsc_Matrix *) const;
+
 protected:
     bool mDirty;
     uint32_t mLightCount;
diff --git a/libs/rs/rsScriptC_Lib.cpp b/libs/rs/rsScriptC_Lib.cpp
index 129b19f..10d1120 100644
--- a/libs/rs/rsScriptC_Lib.cpp
+++ b/libs/rs/rsScriptC_Lib.cpp
@@ -135,7 +135,6 @@
 
 
 
-
 //////////////////////////////////////////////////////////////////////////////
 // Matrix routines
 //////////////////////////////////////////////////////////////////////////////
@@ -257,6 +256,24 @@
 }
 
 //////////////////////////////////////////////////////////////////////////////
+// VP
+//////////////////////////////////////////////////////////////////////////////
+
+static void SC_vpLoadModelMatrix(const rsc_Matrix *m)
+{
+    GET_TLS();
+    rsc->getVertex()->setModelviewMatrix(m);
+}
+
+static void SC_vpLoadTextureMatrix(const rsc_Matrix *m)
+{
+    GET_TLS();
+    rsc->getVertex()->setTextureMatrix(m);
+}
+
+
+
+//////////////////////////////////////////////////////////////////////////////
 // Drawing
 //////////////////////////////////////////////////////////////////////////////
 
@@ -343,20 +360,12 @@
 //
 //////////////////////////////////////////////////////////////////////////////
 
-extern "C" const void * loadVp(uint32_t bank, uint32_t offset)
-{
-    GET_TLS();
-    return &static_cast<const uint8_t *>(sc->mSlots[bank]->getPtr())[offset];
-}
-
-
-
 static void SC_color(float r, float g, float b, float a)
 {
     glColor4f(r, g, b, a);
 }
 
-
+/*
 extern "C" void materialDiffuse(float r, float g, float b, float a)
 {
     float v[] = {r, g, b, a};
@@ -369,35 +378,18 @@
     glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, v);
 }
 
-extern "C" void lightPosition(float x, float y, float z, float w)
-{
-    float v[] = {x, y, z, w};
-    glLightfv(GL_LIGHT0, GL_POSITION, v);
-}
-
 extern "C" void materialShininess(float s)
 {
     glMaterialfv(GL_FRONT_AND_BACK, GL_SHININESS, &s);
 }
+*/
 
-extern "C" void uploadToTexture(RsAllocation va, uint32_t baseMipLevel)
+static void SC_uploadToTexture(RsAllocation va, uint32_t baseMipLevel)
 {
     GET_TLS();
     rsi_AllocationUploadToTexture(rsc, va, baseMipLevel);
 }
 
-extern "C" void enable(uint32_t p)
-{
-    glEnable(p);
-}
-
-extern "C" void disable(uint32_t p)
-{
-    glDisable(p);
-}
-
-
-
 static void SC_ClearColor(float r, float g, float b, float a)
 {
     //LOGE("c %f %f %f %f", r, g, b, a);
@@ -408,6 +400,16 @@
     sc->mEnviroment.mClearColor[3] = a;
 }
 
+static void SC_debugF(const char *s, float f)
+{
+    LOGE("%s %f", s, f);
+}
+
+static void SC_debugI32(const char *s, int32_t i)
+{
+    LOGE("%s %i", s, i);
+}
+
 
 
 //////////////////////////////////////////////////////////////////////////////
@@ -444,6 +446,10 @@
         "float", "(float)" },
     { "randf", (void *)&SC_randf,
         "float", "(float)" },
+    { "floorf", (void *)&floorf,
+        "float", "(float)" },
+    { "ceilf", (void *)&ceilf,
+        "float", "(float)" },
 
     // matrix
     { "matrixLoadIdentity", (void *)&SC_matrixLoadIdentity,
@@ -481,6 +487,14 @@
     { "bindTexture", (void *)&SC_bindTexture,
         "void", "(int, int, int)" },
 
+    // vp
+    { "vpLoadModelMatrix", (void *)&SC_bindProgramFragment,
+        "void", "(void *)" },
+    { "vpLoadTextureMatrix", (void *)&SC_bindProgramFragmentStore,
+        "void", "(void *)" },
+
+
+
     // drawing
     { "drawQuad", (void *)&SC_drawQuad,
         "void", "(float x1, float y1, float z1, float x2, float y2, float z2, float x3, float y3, float z3, float x4, float y4, float z4)" },
@@ -495,10 +509,19 @@
     // misc
     { "pfClearColor", (void *)&SC_ClearColor,
         "void", "(float, float, float, float)" },
-
     { "color", (void *)&SC_color,
         "void", "(float, float, float, float)" },
 
+    { "uploadToTexture", (void *)&SC_uploadToTexture,
+        "void", "(int, int)" },
+
+
+    { "debugF", (void *)&SC_debugF,
+        "void", "(void *, float)" },
+    { "debugI32", (void *)&SC_debugI32,
+        "void", "(void *, int)" },
+
+
     { NULL, NULL, NULL, NULL }
 };