Fixing performance issues with drawing all visible pages.

Change-Id: I17736c1e6afa1f4a961c136fe82bf1d632cbe6cc
diff --git a/src/com/android/launcher3/DragLayer.java b/src/com/android/launcher3/DragLayer.java
index 11539e9..3c064ba 100644
--- a/src/com/android/launcher3/DragLayer.java
+++ b/src/com/android/launcher3/DragLayer.java
@@ -327,16 +327,22 @@
      */
     public float getDescendantCoordRelativeToSelf(View descendant, int[] coord,
             boolean includeRootScroll) {
+        return DragLayer.getDescendantCoordRelativeToParent(descendant, this,
+                coord, includeRootScroll);
+    }
+
+    public static float getDescendantCoordRelativeToParent(View descendant, View root,
+            int[] coord, boolean includeRootScroll) {
         ArrayList<View> ancestorChain = new ArrayList<View>();
 
         float[] pt = {coord[0], coord[1]};
 
         View v = descendant;
-        while(v != this && v != null) {
+        while(v != root && v != null) {
             ancestorChain.add(v);
             v = (View) v.getParent();
         }
-        ancestorChain.add(this);
+        ancestorChain.add(root);
 
         float scale = 1.0f;
         int count = ancestorChain.size();
diff --git a/src/com/android/launcher3/PagedView.java b/src/com/android/launcher3/PagedView.java
index e97bf8d..cb75f2a 100644
--- a/src/com/android/launcher3/PagedView.java
+++ b/src/com/android/launcher3/PagedView.java
@@ -229,6 +229,7 @@
     // Convenience/caching
     private Matrix mTmpInvMatrix = new Matrix();
     private float[] mTmpPoint = new float[2];
+    private int[] mTmpIntPoint = new int[2];
     private Rect mTmpRect = new Rect();
     private Rect mAltTmpRect = new Rect();
 
@@ -266,6 +267,7 @@
 
     public PagedView(Context context, AttributeSet attrs, int defStyle) {
         super(context, attrs, defStyle);
+
         TypedArray a = context.obtainStyledAttributes(attrs,
                 R.styleable.PagedView, defStyle, 0);
         setPageSpacing(a.getDimensionPixelSize(R.styleable.PagedView_pageSpacing, 0));
@@ -955,47 +957,46 @@
         return offset;
     }
 
-    void boundByReorderablePages(boolean isReordering, int[] range) {
-        // Do nothing
+    void getReorderablePages(int[] range) {
+        range[0] = 0;
+        range[1] = getChildCount() - 1;
     }
 
-    // TODO: Fix this
     protected void getVisiblePages(int[] range) {
-        range[0] = 0;
-        range[1] = getPageCount() - 1;
-
-        /*
         final int pageCount = getChildCount();
+        mTmpIntPoint[0] = mTmpIntPoint[1] = 0;
 
         if (pageCount > 0) {
-            final int screenWidth = getViewportWidth();
+            int viewportWidth = getViewportWidth();
             int leftScreen = 0;
             int rightScreen = 0;
-            int offsetX = getViewportOffsetX() + getScrollX();
-            View currPage = getPageAt(leftScreen);
-            while (leftScreen < pageCount - 1 &&
-                    currPage.getX() + currPage.getWidth() -
-                    currPage.getPaddingRight() < offsetX) {
-                leftScreen++;
-                currPage = getPageAt(leftScreen);
-            }
-            rightScreen = leftScreen;
-            currPage = getPageAt(rightScreen + 1);
-            while (rightScreen < pageCount - 1 &&
-                    currPage.getX() - currPage.getPaddingLeft() < offsetX + screenWidth) {
-                rightScreen++;
-                currPage = getPageAt(rightScreen + 1);
-            }
 
-            // TEMP: this is a hacky way to ensure that animations to new pages are not clipped
-            // because we don't draw them while scrolling?
-            range[0] = Math.max(0, leftScreen - 1);
-            range[1] = Math.min(rightScreen + 1, getChildCount() - 1);
+            for (leftScreen = getNextPage(); leftScreen >= 0; --leftScreen) {
+                View currPage = getPageAt(leftScreen);
+
+                // Check if the right edge of the page is in the viewport
+                mTmpIntPoint[0] = currPage.getMeasuredWidth();
+                DragLayer.getDescendantCoordRelativeToParent(currPage, this, mTmpIntPoint, false);
+                if (mTmpIntPoint[0] < 0) {
+                    break;
+                }
+            }
+            for (rightScreen = getNextPage(); rightScreen < getChildCount(); ++rightScreen) {
+                View currPage = getPageAt(rightScreen);
+
+                // Check if the left edge of the page is in the viewport
+                mTmpIntPoint[0] = 0;
+                DragLayer.getDescendantCoordRelativeToParent(currPage, this, mTmpIntPoint, false);
+                if (mTmpIntPoint[0] >= viewportWidth) {
+                    break;
+                }
+            }
+            range[0] = Math.max(0, leftScreen);
+            range[1] = Math.min(rightScreen, getChildCount() - 1);
         } else {
             range[0] = -1;
             range[1] = -1;
         }
-        */
     }
 
     protected boolean shouldDrawChild(View child) {
@@ -1594,7 +1595,7 @@
                 if (pageUnderPointIndex > -1 && !isHoveringOverDelete) {
                     mTempVisiblePagesRange[0] = 0;
                     mTempVisiblePagesRange[1] = getPageCount() - 1;
-                    boundByReorderablePages(true, mTempVisiblePagesRange);
+                    getReorderablePages(mTempVisiblePagesRange);
                     if (mTempVisiblePagesRange[0] <= pageUnderPointIndex &&
                             pageUnderPointIndex <= mTempVisiblePagesRange[1] &&
                             pageUnderPointIndex != mSidePageHoverIndex && mScroller.isFinished()) {
@@ -2232,6 +2233,11 @@
                             });
                     }
                 }
+                @Override
+                public void onAnimationEnd(Animator animation) {
+                    // Update the visible pages
+                    invalidate();
+                }
             });
             mZoomInOutAnim.start();
             return true;
@@ -2245,8 +2251,7 @@
         mIsReordering = true;
 
         // Mark all the non-widget pages as invisible
-        getVisiblePages(mTempVisiblePagesRange);
-        boundByReorderablePages(true, mTempVisiblePagesRange);
+        getReorderablePages(mTempVisiblePagesRange);
         for (int i = 0; i < getPageCount(); ++i) {
             if (i < mTempVisiblePagesRange[0] || i > mTempVisiblePagesRange[1]) {
                 getPageAt(i).setAlpha(0f);
@@ -2272,8 +2277,7 @@
         mIsReordering = false;
 
         // Mark all the non-widget pages as visible again
-        getVisiblePages(mTempVisiblePagesRange);
-        boundByReorderablePages(true, mTempVisiblePagesRange);
+        getReorderablePages(mTempVisiblePagesRange);
         for (int i = 0; i < getPageCount(); ++i) {
             if (i < mTempVisiblePagesRange[0] || i > mTempVisiblePagesRange[1]) {
                 getPageAt(i).setAlpha(1f);
@@ -2285,7 +2289,7 @@
         int dragViewIndex = getPageNearestToCenterOfScreen();
         mTempVisiblePagesRange[0] = 0;
         mTempVisiblePagesRange[1] = getPageCount() - 1;
-        boundByReorderablePages(true, mTempVisiblePagesRange);
+        getReorderablePages(mTempVisiblePagesRange);
         mReorderingStarted = true;
 
         // Check if we are within the reordering range
@@ -2377,6 +2381,8 @@
                     if (onCompleteRunnable != null) {
                         onCompleteRunnable.run();
                     }
+                    // Update the visible pages
+                    invalidate();
                 }
             });
             mZoomInOutAnim.start();
@@ -2464,8 +2470,7 @@
                 // in the layout)
                 // NOTE: We can make an assumption here because we have side-bound pages that we
                 //       will always have pages to animate in from the left
-                getVisiblePages(mTempVisiblePagesRange);
-                boundByReorderablePages(true, mTempVisiblePagesRange);
+                getReorderablePages(mTempVisiblePagesRange);
                 boolean isLastWidgetPage = (mTempVisiblePagesRange[0] == mTempVisiblePagesRange[1]);
                 boolean slideFromLeft = (isLastWidgetPage ||
                         dragViewIndex > mTempVisiblePagesRange[0]);
diff --git a/src/com/android/launcher3/Workspace.java b/src/com/android/launcher3/Workspace.java
index 7129325..b1a332a 100644
--- a/src/com/android/launcher3/Workspace.java
+++ b/src/com/android/launcher3/Workspace.java
@@ -1659,7 +1659,7 @@
         return getChangeStateAnimation(state, animated, 0);
     }
 
-    void boundByReorderablePages(boolean isReordering, int[] range) {
+    void getReorderablePages(int[] range) {
         int count = mScreenOrder.size();
 
         int start = -1;