Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 6cb7b46c authored by Jeff Brown's avatar Jeff Brown
Browse files

Change widgets to post invalidate to the animation timer.

Change-Id: I8377e924529fb9d8afd8a834003a17de616e8e87
parent baefdfad
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -247,7 +247,7 @@ package android {
    field public static final int animationCache = 16842989; // 0x10100ed
    field public static final int animationDuration = 16843026; // 0x1010112
    field public static final int animationOrder = 16843214; // 0x10101ce
    field public static final int animationResolution = 16843546; // 0x101031a
    field public static final deprecated int animationResolution = 16843546; // 0x101031a
    field public static final int antialias = 16843034; // 0x101011a
    field public static final int anyDensity = 16843372; // 0x101026c
    field public static final int apiKey = 16843281; // 0x1010211
+1 −1
Original line number Diff line number Diff line
@@ -334,7 +334,7 @@ public class TextureView extends View {
                    synchronized (mLock) {
                        mUpdateLayer = true;
                    }
                    postInvalidateDelayed(0);
                    postInvalidate();
                }
            };
            mSurface.setOnFrameAvailableListener(mUpdateListener);
+48 −0
Original line number Diff line number Diff line
@@ -8880,6 +8880,54 @@ public class View implements Drawable.Callback, Drawable.Callback2, KeyEvent.Cal
        }
    }
    /**
     * <p>Cause an invalidate to happen on the next animation time step, typically the
     * next display frame.</p>
     *
     * <p>This method can be invoked from outside of the UI thread
     * only when this View is attached to a window.</p>
     *
     * @hide
     */
    public void postInvalidateOnAnimation() {
        // We try only with the AttachInfo because there's no point in invalidating
        // if we are not attached to our window
        final AttachInfo attachInfo = mAttachInfo;
        if (attachInfo != null) {
            attachInfo.mViewRootImpl.dispatchInvalidateOnAnimation(this);
        }
    }
    /**
     * <p>Cause an invalidate of the specified area to happen on the next animation
     * time step, typically the next display frame.</p>
     *
     * <p>This method can be invoked from outside of the UI thread
     * only when this View is attached to a window.</p>
     *
     * @param left The left coordinate of the rectangle to invalidate.
     * @param top The top coordinate of the rectangle to invalidate.
     * @param right The right coordinate of the rectangle to invalidate.
     * @param bottom The bottom coordinate of the rectangle to invalidate.
     *
     * @hide
     */
    public void postInvalidateOnAnimation(int left, int top, int right, int bottom) {
        // We try only with the AttachInfo because there's no point in invalidating
        // if we are not attached to our window
        final AttachInfo attachInfo = mAttachInfo;
        if (attachInfo != null) {
            final AttachInfo.InvalidateInfo info = AttachInfo.InvalidateInfo.acquire();
            info.target = this;
            info.left = left;
            info.top = top;
            info.right = right;
            info.bottom = bottom;
            attachInfo.mViewRootImpl.dispatchInvalidateRectOnAnimation(info);
        }
    }
    /**
     * Post a callback to send a {@link AccessibilityEvent#TYPE_VIEW_SCROLLED} event.
     * This event is sent at most once every
+100 −4
Original line number Diff line number Diff line
@@ -3992,21 +3992,117 @@ public final class ViewRootImpl implements ViewParent,
    }
    WindowInputEventReceiver mInputEventReceiver;

    final class InvalidateOnAnimationRunnable implements Runnable {
        private boolean mPosted;
        private ArrayList<View> mViews = new ArrayList<View>();
        private ArrayList<AttachInfo.InvalidateInfo> mViewRects =
                new ArrayList<AttachInfo.InvalidateInfo>();
        private View[] mTempViews;
        private AttachInfo.InvalidateInfo[] mTempViewRects;

        public void addView(View view) {
            synchronized (this) {
                mViews.add(view);
                postIfNeededLocked();
            }
        }

        public void addViewRect(AttachInfo.InvalidateInfo info) {
            synchronized (this) {
                mViewRects.add(info);
                postIfNeededLocked();
            }
        }

        public void removeView(View view) {
            synchronized (this) {
                mViews.remove(view);

                for (int i = mViewRects.size(); i-- > 0; ) {
                    AttachInfo.InvalidateInfo info = mViewRects.get(i);
                    if (info.target == view) {
                        mViewRects.remove(i);
                        info.release();
                    }
                }

                if (mPosted && mViews.isEmpty() && mViewRects.isEmpty()) {
                    mChoreographer.removeAnimationCallback(this);
                    mPosted = false;
                }
            }
        }

        @Override
        public void run() {
            final int viewCount;
            final int viewRectCount;
            synchronized (this) {
                mPosted = false;

                viewCount = mViews.size();
                if (viewCount != 0) {
                    mTempViews = mViews.toArray(mTempViews != null
                            ? mTempViews : new View[viewCount]);
                    mViews.clear();
                }

                viewRectCount = mViewRects.size();
                if (viewRectCount != 0) {
                    mTempViewRects = mViewRects.toArray(mTempViewRects != null
                            ? mTempViewRects : new AttachInfo.InvalidateInfo[viewRectCount]);
                    mViewRects.clear();
                }
            }

            for (int i = 0; i < viewCount; i++) {
                mTempViews[i].invalidate();
            }

            for (int i = 0; i < viewRectCount; i++) {
                final View.AttachInfo.InvalidateInfo info = mTempViewRects[i];
                info.target.invalidate(info.left, info.top, info.right, info.bottom);
                info.release();
            }
        }

        private void postIfNeededLocked() {
            if (!mPosted) {
                mChoreographer.postAnimationCallback(this);
                mPosted = true;
            }
        }
    }
    final InvalidateOnAnimationRunnable mInvalidateOnAnimationRunnable =
            new InvalidateOnAnimationRunnable();

    public void dispatchInvalidateDelayed(View view, long delayMilliseconds) {
        Message msg = mHandler.obtainMessage(MSG_INVALIDATE, view);
        mHandler.sendMessageDelayed(msg, delayMilliseconds);
    }

    public void cancelInvalidate(View view) {
        mHandler.removeMessages(MSG_INVALIDATE, view);
    }

    public void dispatchInvalidateRectDelayed(AttachInfo.InvalidateInfo info,
            long delayMilliseconds) {
        final Message msg = mHandler.obtainMessage(MSG_INVALIDATE_RECT, info);
        mHandler.sendMessageDelayed(msg, delayMilliseconds);
    }

    public void dispatchInvalidateOnAnimation(View view) {
        mInvalidateOnAnimationRunnable.addView(view);
    }

    public void dispatchInvalidateRectOnAnimation(AttachInfo.InvalidateInfo info) {
        mInvalidateOnAnimationRunnable.addViewRect(info);
    }

    public void cancelInvalidate(View view) {
        mHandler.removeMessages(MSG_INVALIDATE, view);
        // fixme: might leak the AttachInfo.InvalidateInfo objects instead of returning
        // them to the pool
        mHandler.removeMessages(MSG_INVALIDATE_RECT, view);
        mInvalidateOnAnimationRunnable.removeView(view);
    }

    public void dispatchKey(KeyEvent event) {
        Message msg = mHandler.obtainMessage(MSG_DISPATCH_KEY, event);
        msg.setAsynchronous(true);
+2 −11
Original line number Diff line number Diff line
@@ -39,6 +39,7 @@ import android.os.Parcel;
import android.os.Parcelable;
import android.os.SystemClock;
import android.util.AttributeSet;
import android.view.Choreographer;
import android.view.Gravity;
import android.view.RemotableViewMethod;
import android.view.View;
@@ -189,7 +190,6 @@ import android.widget.RemoteViews.RemoteView;
@RemoteView
public class ProgressBar extends View {
    private static final int MAX_LEVEL = 10000;
    private static final int ANIMATION_RESOLUTION = 200;
    private static final int TIMEOUT_SEND_ACCESSIBILITY_EVENT = 200;

    int mMinWidth;
@@ -216,12 +216,9 @@ public class ProgressBar extends View {
    private RefreshProgressRunnable mRefreshProgressRunnable;
    private long mUiThreadId;
    private boolean mShouldStartAnimationDrawable;
    private long mLastDrawTime;

    private boolean mInDrawing;

    private int mAnimationResolution;

    private AccessibilityEventSender mAccessibilityEventSender;

    /**
@@ -299,9 +296,6 @@ public class ProgressBar extends View {
        setIndeterminate(mOnlyIndeterminate || a.getBoolean(
                R.styleable.ProgressBar_indeterminate, mIndeterminate));

        mAnimationResolution = a.getInteger(R.styleable.ProgressBar_animationResolution,
                ANIMATION_RESOLUTION);

        a.recycle();
    }

@@ -988,10 +982,7 @@ public class ProgressBar extends View {
                } finally {
                    mInDrawing = false;
                }
                if (SystemClock.uptimeMillis() - mLastDrawTime >= mAnimationResolution) {
                    mLastDrawTime = SystemClock.uptimeMillis();
                    postInvalidateDelayed(mAnimationResolution);
                }
                postInvalidateOnAnimation();
            }
            d.draw(canvas);
            canvas.restore();
Loading