The icons are 3d
diff --git a/res/raw/rollo.c b/res/raw/rollo.c
index b8f3341..c109d29 100644
--- a/res/raw/rollo.c
+++ b/res/raw/rollo.c
@@ -30,11 +30,10 @@
 #define SCRATCH_ADJUSTED_DECELERATION   0
 
 // Drawing constants, should be parameters ======
-#define SCREEN_WIDTH 480
+#define SCREEN_WIDTH_PX 480
 #define SCREEN_HEIGHT 854
 #define COLUMNS_PER_PAGE 4
 #define ROWS_PER_PAGE 4
-#define DIAMETER 8.0f
 
 #define PAGE_PADDING_TOP_PX 80
 #define CELL_PADDING_TOP_PX 5
@@ -48,8 +47,9 @@
 #define CELL_WIDTH_PX 105
 #define ICON_WIDTH_PX 64
 #define ICON_TEXTURE_WIDTH_PX 128
-#define COLUMN_GUTTER_PX 5
-#define LABEL_WIDTH_PX 105
+
+#define VIEW_ANGLE 1.28700222f
+#define RADIUS 4.0f
 
 int
 count_pages(int iconCount)
@@ -62,17 +62,70 @@
     return pages;
 }
 
-int current_page(float scrollXPx)
-{
-    return -scrollXPx / SCREEN_WIDTH;
-}
-
 float
 modf(float x, float y)
 {
     return x-(y*floorf(x/y));
 }
 
+void
+draw_page(int icon, int lastIcon, float centerAngle)
+{
+    int row;
+    int col;
+
+    float iconTextureWidth = ICON_WIDTH_PX / (float)ICON_TEXTURE_WIDTH_PX;
+    float iconTextureHeight = ICON_HEIGHT_PX / (float)ICON_TEXTURE_HEIGHT_PX;
+
+    float iconWidthAngle = VIEW_ANGLE * ICON_WIDTH_PX / SCREEN_WIDTH_PX;
+    float columnGutterAngle = iconWidthAngle * 0.5f;
+
+    float normalizedIconSize = 2 * ICON_WIDTH_PX / (float)SCREEN_WIDTH_PX;
+    float farIconSize = normalizedIconSize * (RADIUS+2) / 2; // -2 is the camera z=(z-camZ)/z
+
+    for (row=0; row<ROWS_PER_PAGE && icon<=lastIcon; row++) {
+        float angle = centerAngle;
+        angle -= (columnGutterAngle + iconWidthAngle) * 1.5f;
+
+        float iconTop = (farIconSize + (.5*farIconSize)) * 1.5
+                - row * (farIconSize + (.5*farIconSize));
+        float iconBottom = iconTop - farIconSize;
+
+        for (col=0; col<COLUMNS_PER_PAGE && icon<=lastIcon; col++) {
+            // icon
+            float sine = sinf(angle);
+            float cosine = cosf(angle);
+
+            float iconLeftX = sine * RADIUS  - (cosine * farIconSize * .5);
+            float iconRightX = iconLeftX + (cosine * farIconSize);
+            float iconLeftZ = (cosine * RADIUS) + (sine * farIconSize * .5);
+            float iconRightZ = (iconLeftZ - (sine * farIconSize));
+
+            bindTexture(NAMED_PF, 0, loadI32(ALLOC_ICON_IDS, icon));
+            drawQuadTexCoords(
+                    iconLeftX, iconTop, iconLeftZ,       0.0f, 0.0f,
+                    iconRightX, iconTop, iconRightZ,     iconTextureWidth, 0.0f,
+                    iconRightX, iconBottom, iconRightZ,  iconTextureWidth, iconTextureHeight,
+                    iconLeftX, iconBottom, iconLeftZ,    0.0f, iconTextureHeight);
+
+            // label
+            /*
+            float labelLeft = s + ((cellWidth-labelWidth)/2.0f);
+            float labelTop = iconTop - iconHeight - iconLabelGutter;
+
+            bindProgramFragment(NAMED_PFText);
+            bindProgramFragmentStore(NAMED_PFSText);
+
+            bindTexture(NAMED_PFText, 0, loadI32(ALLOC_LABEL_IDS, icon));
+            drawRect(labelLeft, labelTop, labelLeft+labelTextureWidth,
+                    labelTop-labelTextureHeight, 0.0f);
+            */
+            angle += columnGutterAngle + iconWidthAngle;
+            icon++;
+        }
+    }
+}
+
 int
 main(int launchID)
 {
@@ -83,8 +136,8 @@
     int iconCount = loadI32(ALLOC_STATE, STATE_ICON_COUNT);
     int pageCount = count_pages(iconCount);
 
-    float densityScale = 2.0f / SCREEN_WIDTH;
-    float screenTop = SCREEN_HEIGHT/(float)SCREEN_WIDTH; // == (SCREEN_HEIGHT/2)*densityScale;
+    float densityScale = 2.0f / SCREEN_WIDTH_PX;
+    float screenTop = SCREEN_HEIGHT/(float)SCREEN_WIDTH_PX; // == (SCREEN_HEIGHT/2)*densityScale;
 
     float pagePaddingTop = screenTop - (PAGE_PADDING_TOP_PX * densityScale);
     float pageGutterY = ROW_GUTTER_PX * densityScale;
@@ -92,23 +145,14 @@
             + loadI32(ALLOC_PARAMS, PARAM_BUBBLE_HEIGHT)
             + CELL_PADDING_BOTTOM_PX + ROW_GUTTER_PX) * densityScale;
     float cellPaddingTop = CELL_PADDING_TOP_PX * densityScale;
-    float iconHeight = ICON_HEIGHT_PX * densityScale;
-    float iconTextureHeight = ICON_HEIGHT_PX / ((float)ICON_TEXTURE_HEIGHT_PX);
     float iconLabelGutter = ICON_LABEL_GUTTER_PX * densityScale;
 
-    float pagePaddingLeft = PAGE_PADDING_LEFT_PX * densityScale;
-    float cellWidth = CELL_WIDTH_PX * densityScale;
-
-    float iconWidth = ICON_WIDTH_PX * densityScale;
-    float iconTextureWidth = ICON_WIDTH_PX / ((float)ICON_TEXTURE_WIDTH_PX);
-    float columnGutter = COLUMN_GUTTER_PX * densityScale;
-
     float labelWidth = loadI32(ALLOC_PARAMS, PARAM_BUBBLE_WIDTH) * densityScale;
     float labelTextureWidth = loadI32(ALLOC_PARAMS, PARAM_BUBBLE_BITMAP_WIDTH) * densityScale;
     float labelTextureHeight = loadI32(ALLOC_PARAMS, PARAM_BUBBLE_BITMAP_HEIGHT) * densityScale;
 
     float scrollXPx = loadI32(ALLOC_STATE, STATE_SCROLL_X);
-    float maxScrollX = -(pageCount-1) * SCREEN_WIDTH;
+    float maxScrollX = -(pageCount-1) * SCREEN_WIDTH_PX;
     int done = 0;
 
     // Clamp -- because java doesn't know how big the icons are
@@ -159,28 +203,28 @@
             if (endPos < maxScrollX) {
                 endPos = maxScrollX;
             }
-            float scrollOnPage = modf(endPos, SCREEN_WIDTH);
-            int endPage = -endPos/SCREEN_WIDTH;
+            float scrollOnPage = modf(endPos, SCREEN_WIDTH_PX);
+            int endPage = -endPos/SCREEN_WIDTH_PX;
 
             if (flingVelocityPxMs < 0) {
-                if (scrollOnPage < (SCREEN_WIDTH/2)) {
+                if (scrollOnPage < (SCREEN_WIDTH_PX/2)) {
                     // adjust the deceleration so we align on the page boundary
                     // a = 2(x-x0-v0t)/t^2
-                    endPos = -(endPage+1) * SCREEN_WIDTH;
+                    endPos = -(endPage+1) * SCREEN_WIDTH_PX;
                     debugI32("endPos case 1", endPos);
                 } else {
                     // TODO: bounce
-                    endPos = -(endPage+1) * SCREEN_WIDTH;
+                    endPos = -(endPage+1) * SCREEN_WIDTH_PX;
                     debugI32("endPos case 2", endPos);
                 }
             } else {
-                if (scrollOnPage >= (SCREEN_WIDTH/2)) {
+                if (scrollOnPage >= (SCREEN_WIDTH_PX/2)) {
                     // adjust the deceleration so we align on the page boundary
-                    endPos = -endPage * SCREEN_WIDTH;
+                    endPos = -endPage * SCREEN_WIDTH_PX;
                     debugI32("endPos case 3", endPos);
                 } else {
                     // TODO: bounce
-                    endPos = -endPage * SCREEN_WIDTH;
+                    endPos = -endPage * SCREEN_WIDTH_PX;
                     debugI32("endPos case 4", endPos);
                 }
             }
@@ -229,60 +273,23 @@
         storeF(ALLOC_STATE, STATE_ADJUSTED_DECELERATION, 0);
     }
 
-    // don't draw everything, just the page before and after what we're viewing.
-    int currentPage = current_page(scrollXPx);
-    float screenWidth = SCREEN_WIDTH * densityScale;
+    bindProgramFragment(NAMED_PF);
+    bindProgramFragmentStore(NAMED_PFS);
+
+    // Bug makes 1.0f alpha fail.
+    color(1.0f, 1.0f, 1.0f, 0.99f);
+
+    int lastIcon = iconCount-1;
+
+    float currentPage = -scrollXPx / (float)SCREEN_WIDTH_PX;
+    int page = currentPage;
+    float currentPagePosition = currentPage - page;
 
     int iconsPerPage = COLUMNS_PER_PAGE * ROWS_PER_PAGE;
-    int icon = 0;
-    int lastIcon = iconCount-1;
-    float pageLeft = -1 + (scrollXPx * densityScale);
-    while (icon <= lastIcon) {
-        // Bug makes 1.0f alpha fail.
-        color(1.0f, 1.0f, 1.0f, 0.99f);
-        
-        float cellTop = pagePaddingTop;
-        int row;
-        for (row=0; row<ROWS_PER_PAGE && icon<=lastIcon; row++) {
-            float s = pageLeft; // distance along the linear strip of icons in normalized coords
-            s += pagePaddingLeft;
-            int col;
-            for (col=0; col<COLUMNS_PER_PAGE && icon<=lastIcon; col++) {
-                // icon
-                float iconLeft = s + ((cellWidth-iconWidth)/2.0f);
-                float iconRight = iconLeft + iconWidth;
-                float iconTop = cellTop - cellPaddingTop;
-                float iconBottom = iconTop - iconHeight;
+    int icon = clamp(iconsPerPage * page, 0, lastIcon);
 
-                bindProgramFragment(NAMED_PF);
-                bindProgramFragmentStore(NAMED_PFS);
-
-                bindTexture(NAMED_PF, 0, loadI32(ALLOC_ICON_IDS, icon));
-                //drawRect(iconLeft, iconTop, iconRight, iconBottom, 0.0f);
-                drawQuadTexCoords(
-                        iconLeft, iconTop, 0.0f,        0.0f, 0.0f,
-                        iconRight, iconTop, 0.0f,       iconTextureWidth, 0.0f,
-                        iconRight, iconBottom, 0.0f,    iconTextureWidth, iconTextureHeight,
-                        iconLeft, iconBottom, 0.0f,     0.0f, iconTextureHeight);
-
-                // label
-                float labelLeft = s + ((cellWidth-labelWidth)/2.0f);
-                float labelTop = iconTop - iconHeight - iconLabelGutter;
-
-                bindProgramFragment(NAMED_PFText);
-                bindProgramFragmentStore(NAMED_PFSText);
-
-                bindTexture(NAMED_PFText, 0, loadI32(ALLOC_LABEL_IDS, icon));
-                drawRect(labelLeft, labelTop, labelLeft+labelTextureWidth,
-                        labelTop-labelTextureHeight, 0.0f);
-
-                s += cellWidth + columnGutter;
-                icon++;
-            }
-            cellTop -= cellHeight;
-        }
-        pageLeft += 2.0f;
-    }
+    draw_page(icon, lastIcon, -VIEW_ANGLE*currentPagePosition);
+    draw_page(icon+iconsPerPage, lastIcon, (-VIEW_ANGLE*currentPagePosition)+VIEW_ANGLE);
 
     return !done;
 }
diff --git a/src/com/android/launcher2/AllAppsView.java b/src/com/android/launcher2/AllAppsView.java
index d9b7b8c..cd66b4f 100644
--- a/src/com/android/launcher2/AllAppsView.java
+++ b/src/com/android/launcher2/AllAppsView.java
@@ -287,7 +287,7 @@
             mPFText.bindSampler(mSamplerText, 0);
 
             ProgramStore.Builder bs = new ProgramStore.Builder(mRS, null, null);
-            bs.setDepthFunc(ProgramStore.DepthFunc.LESS);
+            bs.setDepthFunc(ProgramStore.DepthFunc.ALWAYS);
             bs.setDitherEnable(false);
             bs.setDepthMask(true);
             bs.setBlendFunc(ProgramStore.BlendSrcFunc.SRC_ALPHA,
diff --git a/src/com/android/launcher2/LauncherModel.java b/src/com/android/launcher2/LauncherModel.java
index 36b2090..90722cf 100644
--- a/src/com/android/launcher2/LauncherModel.java
+++ b/src/com/android/launcher2/LauncherModel.java
@@ -296,18 +296,18 @@
 
             if (mAllAppsList.added.size() > 0) {
                 added = mAllAppsList.added;
-                added = new ArrayList();
+                mAllAppsList.added = new ArrayList();
             }
             if (mAllAppsList.removed.size() > 0) {
                 removed = mAllAppsList.removed;
-                removed = new ArrayList();
+                mAllAppsList.removed = new ArrayList();
                 for (ApplicationInfo info: removed) {
                     AppInfoCache.remove(info.intent.getComponent());
                 }
             }
             if (mAllAppsList.modified.size() > 0) {
                 modified = mAllAppsList.modified;
-                modified = new ArrayList();
+                mAllAppsList.modified = new ArrayList();
             }
 
             final Callbacks callbacks = mCallbacks.get();
@@ -438,6 +438,7 @@
                     while (!done) {
                         try {
                             mWaitThread.join();
+                            done = true;
                         } catch (InterruptedException ex) {
                         }
                     }
diff --git a/src/com/android/launcher2/Utilities.java b/src/com/android/launcher2/Utilities.java
index 53e42e3..0c5dbbd 100644
--- a/src/com/android/launcher2/Utilities.java
+++ b/src/com/android/launcher2/Utilities.java
@@ -264,12 +264,14 @@
             mTextWidth = bubbleWidth - mBubblePadding - mBubblePadding;
 
             Paint rectPaint = mRectPaint = new Paint();
-            rectPaint.setColor(0xaa000000);
+            rectPaint.setColor(0xff000000);
             rectPaint.setAntiAlias(true);
 
+            Log.d(Launcher.LOG_TAG, "scale=" + scale + " textSize=" + (13*scale));
+
             TextPaint textPaint = mTextPaint = new TextPaint();
-            textPaint.setTypeface(Typeface.DEFAULT_BOLD);
-            textPaint.setTextSize(20);
+            textPaint.setTypeface(Typeface.DEFAULT);
+            textPaint.setTextSize(13*scale);
             textPaint.setColor(0xffffffff);
             textPaint.setAntiAlias(true);