Implement dark background, adjust spacing, remove skia scaling for performance during zoom.
diff --git a/res/raw/rollo.c b/res/raw/rollo.c
index 98e5738..5dcb16c 100644
--- a/res/raw/rollo.c
+++ b/res/raw/rollo.c
@@ -17,8 +17,9 @@
 int g_LastTouchDown;
 float g_DT;
 int g_LastTime;
-int g_Rendering;
 int g_PageCount;
+float g_Zoom;
+float g_ZoomTarget;
 
 // Drawing constants, should be parameters ======
 #define VIEW_ANGLE 1.28700222f
@@ -48,17 +49,8 @@
     g_PosPage = 0;
     g_LastTouchDown = 0;
     g_LastPositionX = 0;
-}
-
-void clampPosition() {
-    if (g_PosPage < 0) {
-        g_PosPage = 0;
-        g_PosVelocity = 0;
-    }
-    if (g_PosPage > (g_PageCount - 1)) {
-        g_PosPage = (g_PageCount - 1);
-        g_PosVelocity = 0;
-    }
+    g_Zoom = 0;
+    g_ZoomTarget = 0;
 }
 
 void move() {
@@ -66,31 +58,44 @@
         float dx = -(state->newPositionX - g_LastPositionX);
         g_PosVelocity = 0;
         g_PosPage += dx;
+
+        float pmin = -0.25f;
+        float pmax = (g_PageCount - 1) + 0.25f;
+        g_PosPage = clampf(g_PosPage, pmin, pmax);
     }
     g_LastTouchDown = state->newTouchDown;
     g_LastPositionX = state->newPositionX;
-    clampPosition();
 }
 
 void fling() {
     g_LastTouchDown = 0;
     g_PosVelocity = -state->flingVelocityX;
+    float av = fabsf(g_PosVelocity);
+    float minVel = 3f;
+
+    minVel *= 1.f - (fabsf(fracf(g_PosPage + 0.5f) - 0.5f) * 0.45f);
+
+    if (av < minVel && av > 0.2f) {
+        if (g_PosVelocity > 0) {
+            g_PosVelocity = minVel;
+        } else {
+            g_PosVelocity = -minVel;
+        }
+    }
+
     if (g_PosPage <= 0) {
         g_PosVelocity = maxf(0, g_PosVelocity);
     }
     if (g_PosPage > (g_PageCount - 1)) {
-        g_PosVelocity = minf(0, (g_PageCount - 1) - g_PosPage);
+        g_PosVelocity = minf(0, g_PosVelocity);
     }
+    //g_Zoom += (maxf(fabsf(g_PosVelocity), 3) - 3) / 2.f;
 }
 
-int g_lastFrameTime = 0;
-void print_frame_rate()
-{
-    int now = uptimeMillis();
-    if (g_lastFrameTime != 0) {
-        debugI32("frame_rate", 1000/(now-g_lastFrameTime));
-    }
-    g_lastFrameTime = now;
+
+void setZoomTarget() {
+    g_ZoomTarget = state->zoom;
+    //debugF("zoom target", g_ZoomTarget);
 }
 
 int
@@ -136,7 +141,11 @@
     //debugF("  accel", accel);
     //debugF("  friction", friction);
 
-    g_PosVelocity += accel;
+    // If our velocity is low OR acceleration is opposing it, apply it.
+    if (fabsf(g_PosVelocity) < 0.5f || (g_PosVelocity * accel) < 0) {
+        g_PosVelocity += accel;
+    }
+
     if ((friction > fabsf(g_PosVelocity)) && (friction > fabsf(accel))) {
         // Special get back to center and overcome friction physics.
         float t = tablePosNorm - 0.5f;
@@ -155,14 +164,10 @@
         // Normal physics
         if (g_PosVelocity > 0) {
             g_PosVelocity -= friction;
-            if (g_PosVelocity < 0) {
-                g_PosVelocity = 0;
-            }
+            g_PosVelocity = maxf(g_PosVelocity, 0);
         } else {
             g_PosVelocity += friction;
-            if (g_PosVelocity > 0) {
-                g_PosVelocity = 0;
-            }
+            g_PosVelocity = minf(g_PosVelocity, 0);
         }
     }
     g_PosPage += g_PosVelocity * g_DT;
@@ -187,22 +192,21 @@
 }
 
 void
-draw_page(int icon, int lastIcon, float centerAngle)
+draw_page(int icon, int lastIcon, float centerAngle, float scale)
 {
     int row;
     int col;
 
     //debugF("center angle", centerAngle);
-    float scale = 1.0f - state->zoom;
 
     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.70f;
+    float columnGutterAngle = iconWidthAngle * 0.9f;
 
     float farIconSize = FAR_ICON_SIZE;
-    float iconGutterHeight = farIconSize * 1.1f;
+    float iconGutterHeight = farIconSize * 1.3f;
 
     float farIconTextureSize = far_size(2 * ICON_TEXTURE_WIDTH_PX / (float)SCREEN_WIDTH_PX);
 
@@ -216,9 +220,8 @@
         float angle = centerAngle;
         angle -= (columnGutterAngle + iconWidthAngle) * 1.5f;
 
-        float iconTop = (farIconSize + iconGutterHeight) * (2.0f + ICON_TOP_OFFSET)
+        float iconTop = (farIconSize + iconGutterHeight) * (1.85f + ICON_TOP_OFFSET)
                 - row * (farIconSize + iconGutterHeight);
-        iconTop -= 6 * scale; // make the zoom point below center
         float iconBottom = iconTop - farIconSize;
 
         float labelTop = iconBottom - (.1 * farLabelHeight);
@@ -233,14 +236,18 @@
             float cosine = cosf(angle);
 
             float centerX = sine * RADIUS;
-            float centerZ = cosine * RADIUS;
-            centerZ -= ((RADIUS+2+1)*scale); // 2 is camera loc, 1 put it slightly behind that.
+            float centerZ = cosine * RADIUS / scale;
+
+            if (scale > 1.f) {
+                centerX *= scale;
+            }
 
             float iconLeftX = centerX  - (cosine * farIconTextureSize * .5);
             float iconRightX = centerX + (cosine * farIconTextureSize * .5);
             float iconLeftZ = centerZ + (sine * farIconTextureSize * .5);
             float iconRightZ = centerZ - (sine * farIconTextureSize * .5);
 
+            color(1.0f, 1.0f, 1.0f, 0.99f);
             if (state->selectedIconIndex == icon) {
                 bindTexture(NAMED_PF, 0, state->selectedIconTexture);
                 drawQuadTexCoords(
@@ -258,7 +265,11 @@
             }
 
             // label
-            if (scale <= 0.1f) {
+            if (scale < 1.2f) {
+                float a = maxf(scale, 1.0f);
+                a = (1.2f - a) * 5;
+                color(1.0f, 1.0f, 1.0f, a);
+
                 float labelLeftX = centerX - farLabelWidth * 0.5f;
                 float labelRightX = centerX + farLabelWidth * 0.5f;
 
@@ -279,19 +290,41 @@
 int
 main(int launchID)
 {
-    // Clear to transparent
-    pfClearColor(0.0f, 0.0f, 0.0f, 0.0f);
-
+    // Compute dt in seconds.
     int newTime = uptimeMillis();
     g_DT = (newTime - g_LastTime) / 1000.f;
     g_LastTime = newTime;
-    //debugF("*** dt ", g_DT);
 
-    // If we're not supposed to be showing, don't do anything.
-    if (!state->visible) {
-        return 0;
+    debugF("zoom", g_Zoom);
+    if (g_Zoom != g_ZoomTarget) {
+        float dz = (g_ZoomTarget - g_Zoom) * g_DT * 5;
+        if (dz && (fabsf(dz) < 0.03f)) {
+            if (dz > 0) {
+                dz = 0.03f;
+            } else {
+                dz = -0.03f;
+            }
+        }
+        if (fabsf(g_Zoom - g_ZoomTarget) < fabsf(dz)) {
+            g_Zoom = g_ZoomTarget;
+        } else {
+            g_Zoom += dz;
+        }
     }
 
+    // Set clear value to dim the background based on the zoom position.
+    if (g_Zoom < 0.8f) {
+        pfClearColor(0.0f, 0.0f, 0.0f, g_Zoom);
+        if (g_Zoom == 0) {
+            // Nothing else to do if fully zoomed out.
+            return 1;
+        }
+    } else {
+        pfClearColor(0.0f, 0.0f, 0.0f, 0.80f);
+    }
+
+
+
     // icons & labels
     int iconCount = state->iconCount;
     g_PageCount = count_pages(iconCount);
@@ -318,27 +351,12 @@
     int iconsPerPage = COLUMNS_PER_PAGE * ROWS_PER_PAGE;
     int icon = clamp(iconsPerPage * page, 0, lastIcon);
 
-    draw_page(icon, lastIcon, -VIEW_ANGLE*currentPagePosition);
-    draw_page(icon+iconsPerPage, lastIcon, (-VIEW_ANGLE*currentPagePosition)+VIEW_ANGLE);
+    float scale = (1 / g_Zoom);
 
+    float pageAngle = VIEW_ANGLE * 1.2f;
+    draw_page(icon, lastIcon, -pageAngle*currentPagePosition, scale);
+    draw_page(icon+iconsPerPage, lastIcon, (-pageAngle*currentPagePosition)+pageAngle, scale);
 
-    // Draw the border lines for debugging ========================================
-    /*
-    bindProgramVertex(NAMED_PVOrtho);
-    bindProgramFragment(NAMED_PFText);
-    bindProgramFragmentStore(NAMED_PFSText);
-
-    color(1.0f, 1.0f, 0.0f, 0.99f);
-    int i;
-    for (i=0; i<ROWS_PER_PAGE+1; i++) {
-        int y = loadI32(ALLOC_Y_BORDERS, i);
-        drawRect(0, y, SCREEN_WIDTH_PX, y+1, 0.0f);
-    }
-    for (i=0; i<COLUMNS_PER_PAGE+1; i++) {
-        int x = loadI32(ALLOC_X_BORDERS, i);
-        drawRect(x, 0, x+1, SCREEN_HEIGHT_PX, 0.0f);
-    }
-    */
 
     // Draw the scroll handle ========================================
     /*
@@ -350,13 +368,8 @@
     drawRect(handleLeft, handleTop, handleLeft+handleWidth, handleTop+handleHeight, 0.0f);
     */
 
-    //print_frame_rate();
-
     // Bug workaround where the last frame is not always displayed
-    // So we render the last frame twice.
-    int rendering = g_Rendering;
-    g_Rendering = (g_PosVelocity != 0) || fracf(g_PosPage);
-    rendering |= g_Rendering;
-    return rendering;
+    // So we keep rendering until the bug is fixed.
+    return 1;//(g_PosVelocity != 0) || fracf(g_PosPage);
 }
 
diff --git a/src/com/android/launcher2/AllAppsGridView.java b/src/com/android/launcher2/AllAppsGridView.java
index 6606cc9..71cd952 100644
--- a/src/com/android/launcher2/AllAppsGridView.java
+++ b/src/com/android/launcher2/AllAppsGridView.java
@@ -66,7 +66,7 @@
         app = new ApplicationInfo(app);
 
         mDragController.startDrag(view, this, app, DragController.DRAG_ACTION_COPY);
-        mLauncher.closeAllApps(true);
+        mLauncher.closeAllApps();
         mDraw = false;
         invalidate();
         return true;
@@ -84,7 +84,7 @@
     }
 
     public void onDropCompleted(View target, boolean success) {
-        mLauncher.closeAllApps(false);
+        mLauncher.closeAllApps();
     }
 
     void setLauncher(Launcher launcher) {
diff --git a/src/com/android/launcher2/AllAppsView.java b/src/com/android/launcher2/AllAppsView.java
index 03734c0..9f9018e 100644
--- a/src/com/android/launcher2/AllAppsView.java
+++ b/src/com/android/launcher2/AllAppsView.java
@@ -131,6 +131,7 @@
         setOnClickListener(this);
         setOnLongClickListener(this);
         setOnTop(true);
+        getHolder().setFormat(PixelFormat.TRANSLUCENT);
     }
 
     public AllAppsView(Context context, AttributeSet attrs, int defStyle) {
@@ -277,7 +278,7 @@
                     left, top, Defines.ICON_WIDTH_PX, Defines.ICON_HEIGHT_PX,
                     this, app, DragController.DRAG_ACTION_COPY);
 
-            mLauncher.closeAllApps(true);
+            mLauncher.closeAllApps();
         }
         return true;
     }
@@ -289,6 +290,12 @@
     public void onDropCompleted(View target, boolean success) {
     }
 
+    public void setZoom(float v) {
+        mRollo.mState.zoom = v;
+        mRollo.mState.save();
+        mRollo.mInvokeZoom.execute();
+    }
+
     public void setScale(float amount) {
         cancelLongPress();
         mRollo.mState.read();
@@ -306,6 +313,7 @@
             mLocks &= ~LOCK_ZOOMING;
         }
         mRollo.mState.save();
+        mRollo.mInvokeZoom.execute();
     }
 
     public boolean isZooming() {
@@ -364,6 +372,7 @@
 
         private Script.Invokable mInvokeMove;
         private Script.Invokable mInvokeFling;
+        private Script.Invokable mInvokeZoom;
 
         private Sampler mSampler;
         private Sampler mSamplerText;
@@ -576,6 +585,7 @@
             sb.setType(mState.mType, "state", Defines.ALLOC_STATE);
             mInvokeMove = sb.addInvokable("move");
             mInvokeFling = sb.addInvokable("fling");
+            mInvokeZoom = sb.addInvokable("setZoomTarget");
             mScript = sb.create();
             mScript.setClearColor(0.0f, 0.0f, 0.0f, 0.0f);
 
diff --git a/src/com/android/launcher2/Launcher.java b/src/com/android/launcher2/Launcher.java
index 3e3ff06..3813afe 100644
--- a/src/com/android/launcher2/Launcher.java
+++ b/src/com/android/launcher2/Launcher.java
@@ -193,7 +193,7 @@
 
     private boolean mHomeDown;
     private boolean mBackDown;
-    
+
     private Bundle mSavedInstanceState;
 
     private LauncherModel mModel;
@@ -245,7 +245,7 @@
     private void checkForLocaleChange() {
         final LocaleConfiguration localeConfiguration = new LocaleConfiguration();
         readConfiguration(this, localeConfiguration);
-        
+
         final Configuration configuration = getResources().getConfiguration();
 
         final String previousLocale = localeConfiguration.locale;
@@ -274,7 +274,7 @@
         public int mcc = -1;
         public int mnc = -1;
     }
-    
+
     private static void readConfiguration(Context context, LocaleConfiguration configuration) {
         DataInputStream in = null;
         try {
@@ -397,7 +397,7 @@
             mModel.startLoader(this, true);
             mRestoring = false;
         }
-        
+
         // If this was a new intent (i.e., the mIsNewIntent flag got set to true by
         // onNewIntent), then close the search dialog if needed, because it probably
         // came from the user pressing 'home' (rather than, for example, pressing 'back').
@@ -412,18 +412,18 @@
                         searchManagerService.stopSearch();
                     } catch (RemoteException e) {
                         e(LOG_TAG, "error stopping search", e);
-                    }    
+                    }
                 }
             });
         }
-        
+
         mIsNewIntent = false;
     }
 
     @Override
     protected void onPause() {
         super.onPause();
-        closeAllApps(false);
+        closeAllApps();
     }
 
     @Override
@@ -557,7 +557,7 @@
         dragController.setDragScoller(workspace);
         dragController.setDragListener(deleteZone);
         dragController.setScrollView(dragLayer);
-        
+
         // The order here is bottom to top.
         dragController.addDropTarget(workspace);
         dragController.addDropTarget(deleteZone);
@@ -784,7 +784,7 @@
         // Close the menu
         if (Intent.ACTION_MAIN.equals(intent.getAction())) {
             getWindow().closeAllPanels();
-            
+
             // Set this flag so that onResume knows to close the search dialog if it's open,
             // because this was a new intent (thus a press of 'home' or some such) rather than
             // for example onResume being called when the user pressed the 'back' button.
@@ -811,7 +811,7 @@
                     mWorkspace.moveToDefaultScreen();
                 }
 
-                closeAllApps(true);
+                closeAllApps();
 
                 final View v = getWindow().peekDecorView();
                 if (v != null && v.getWindowToken() != null) {
@@ -820,7 +820,7 @@
                     imm.hideSoftInputFromWindow(v.getWindowToken(), 0);
                 }
             } else {
-                closeAllApps(false);
+                closeAllApps();
             }
         }
     }
@@ -906,7 +906,7 @@
     public void startSearch(String initialQuery, boolean selectInitialQuery,
             Bundle appSearchData, boolean globalSearch) {
 
-        closeAllApps(false);
+        closeAllApps();
 
         // Slide the search widget to the top, if it's on the current screen,
         // otherwise show the search dialog immediately.
@@ -1283,7 +1283,7 @@
                     if (!event.isCanceled()) {
                         mWorkspace.dispatchKeyEvent(event);
                         if (isAllAppsVisible()) {
-                            closeAllApps(true);
+                            closeAllApps();
                         } else {
                             closeFolder();
                         }
@@ -1343,9 +1343,9 @@
         } else if (v == mHandleView) {
             Log.d(TAG, "onClick");
             if (isAllAppsVisible()) {
-                closeAllApps(true);
+                closeAllApps();
             } else {
-                showAllApps(true);
+                showAllApps();
             }
         }
     }
@@ -1607,33 +1607,24 @@
         return mAllAppsGrid.isZooming() || mAllAppsGrid.isVisible();
     }
 
-    void showAllApps(boolean animated) {
+    void showAllApps() {
         if (mMode == MODE_ALL_APPS) {
             return;
         }
 
         mSwipeController.setRange(-1, 0);
-        if (animated) {
-            mSwipeController.animate(-1);
-        } else {
-            mSwipeController.setImmediate(-1);
-        }
-
+        mSwipeController.setImmediate(-1);
         mWorkspace.hide();
-        
+
         // TODO: fade these two too
         mDeleteZone.setVisibility(View.GONE);
         //mHandleView.setVisibility(View.GONE);
     }
 
-    void closeAllApps(boolean animated) {
+    void closeAllApps() {
         if (mAllAppsGrid.isVisible()) {
             mSwipeController.setRange(0, 1);
-            if (animated) {
-                mSwipeController.animate(1);
-            } else {
-                mSwipeController.setImmediate(1);
-            }
+            mSwipeController.setImmediate(1);
             mWorkspace.getChildAt(mWorkspace.getCurrentScreen()).requestFocus();
 
             // TODO: fade these two too
@@ -1850,7 +1841,7 @@
         } else {
             mWorkspace.setVisibility(View.VISIBLE);
         }
-        mWorkspace.setScale(1-amount);
+        //mWorkspace.setScale(1-amount);
         mAllAppsGrid.setScale(amount);
     }
 
@@ -2001,7 +1992,7 @@
 
             final boolean allApps = mSavedState.getBoolean(RUNTIME_STATE_ALL_APPS_FOLDER, false);
             if (allApps) {
-                showAllApps(false);
+                showAllApps();
             }
 
             mSavedState = null;
diff --git a/src/com/android/launcher2/Utilities.java b/src/com/android/launcher2/Utilities.java
index ec9fb79..dbb5ac6 100644
--- a/src/com/android/launcher2/Utilities.java
+++ b/src/com/android/launcher2/Utilities.java
@@ -93,7 +93,7 @@
      * @param context The application's context.
      *
      * @return A thumbnail for the specified icon or the icon itself if the
-     *         thumbnail could not be created. 
+     *         thumbnail could not be created.
      */
     static Drawable createIconThumbnail(Drawable icon, Context context) {
         synchronized (sCanvas) { // we share the statics :-(
@@ -411,11 +411,11 @@
             if (lineCount > MAX_LINES) {
                 lineCount = MAX_LINES;
             }
-            if (!TEXT_BURN && lineCount > 0) {
-                RectF bubbleRect = mBubbleRect;
-                bubbleRect.bottom = height(lineCount);
-                c.drawRoundRect(bubbleRect, mCornerRadius, mCornerRadius, mRectPaint);
-            }
+            //if (!TEXT_BURN && lineCount > 0) {
+                //RectF bubbleRect = mBubbleRect;
+                //bubbleRect.bottom = height(lineCount);
+                //c.drawRoundRect(bubbleRect, mCornerRadius, mCornerRadius, mRectPaint);
+            //}
             for (int i=0; i<lineCount; i++) {
                 int x = (int)((mBubbleRect.width() - layout.getLineMax(i)) / 2.0f);
                 int y = mFirstLineY + (i * mLineHeight);