resolved conflicts for merge of 9c9958ca to mnc-dev-plus-aosp
Change-Id: Id3203fa190b351074a56195b8dfea4f6cee9a767
diff --git a/framesequence/jni/FrameSequence_gif.cpp b/framesequence/jni/FrameSequence_gif.cpp
index 2188c53..f8d37f4 100644
--- a/framesequence/jni/FrameSequence_gif.cpp
+++ b/framesequence/jni/FrameSequence_gif.cpp
@@ -23,11 +23,6 @@
#define GIF_DEBUG 0
-// These constants are chosen to imitate common browser behavior
-// Note that 0 delay is undefined behavior in the gif standard
-static const long MIN_DELAY_MS = 20;
-static const long DEFAULT_DELAY_MS = 100;
-
static int streamReader(GifFileType* fileType, GifByteType* out, int size) {
Stream* stream = (Stream*) fileType->UserData;
return (int) stream->read(out, size);
@@ -38,11 +33,7 @@
}
static long getDelayMs(GraphicsControlBlock& gcb) {
- long delayMs = gcb.DelayTime * 10;
- if (delayMs < MIN_DELAY_MS) {
- return DEFAULT_DELAY_MS;
- }
- return delayMs;
+ return gcb.DelayTime * 10;
}
static bool willBeCleared(const GraphicsControlBlock& gcb) {
diff --git a/framesequence/src/android/support/rastermill/FrameSequenceDrawable.java b/framesequence/src/android/support/rastermill/FrameSequenceDrawable.java
index 2228b1d..c4ce0ce 100644
--- a/framesequence/src/android/support/rastermill/FrameSequenceDrawable.java
+++ b/framesequence/src/android/support/rastermill/FrameSequenceDrawable.java
@@ -17,11 +17,14 @@
package android.support.rastermill;
import android.graphics.Bitmap;
+import android.graphics.BitmapShader;
import android.graphics.Canvas;
import android.graphics.ColorFilter;
import android.graphics.Paint;
import android.graphics.PixelFormat;
import android.graphics.Rect;
+import android.graphics.RectF;
+import android.graphics.Shader;
import android.graphics.drawable.Animatable;
import android.graphics.drawable.Drawable;
import android.os.Handler;
@@ -30,6 +33,15 @@
import android.os.SystemClock;
public class FrameSequenceDrawable extends Drawable implements Animatable, Runnable {
+ /**
+ * These constants are chosen to imitate common browser behavior for WebP/GIF.
+ * If other decoders are added, this behavior should be moved into the WebP/GIF decoders.
+ *
+ * Note that 0 delay is undefined behavior in the GIF standard.
+ */
+ private static final long MIN_DELAY_MS = 20;
+ private static final long DEFAULT_DELAY_MS = 100;
+
private static final Object sLock = new Object();
private static HandlerThread sDecodingThread;
private static Handler sDecodingThreadHandler;
@@ -116,7 +128,10 @@
private final FrameSequence.State mFrameSequenceState;
private final Paint mPaint;
- private final Rect mSrcRect;
+ private BitmapShader mFrontBitmapShader;
+ private BitmapShader mBackBitmapShader;
+ private final Rect mSrcRect;
+ private boolean mCircleMaskEnabled;
//Protects the fields below
private final Object mLock = new Object();
@@ -161,6 +176,10 @@
int lastFrame = nextFrame - 2;
long invalidateTimeMs = mFrameSequenceState.getFrame(nextFrame, bitmap, lastFrame);
+ if (invalidateTimeMs < MIN_DELAY_MS) {
+ invalidateTimeMs = DEFAULT_DELAY_MS;
+ }
+
boolean schedule = false;
Bitmap bitmapToRelease = null;
synchronized (mLock) {
@@ -225,6 +244,11 @@
mPaint = new Paint();
mPaint.setFilterBitmap(true);
+ mFrontBitmapShader
+ = new BitmapShader(mFrontBitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);
+ mBackBitmapShader
+ = new BitmapShader(mBackBitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);
+
mLastSwap = 0;
mNextFrameToDecode = -1;
@@ -232,6 +256,18 @@
initializeDecodingThread();
}
+ /**
+ * Pass true to mask the shape of the animated drawing content to a circle.
+ *
+ * <p> The masking circle will be the largest circle contained in the Drawable's bounds.
+ * Masking is done with BitmapShader, incurring minimal additional draw cost.
+ */
+ public final void setCircleMaskEnabled(boolean circleMaskEnabled) {
+ mCircleMaskEnabled = circleMaskEnabled;
+ // Anti alias only necessary when using circular mask
+ mPaint.setAntiAlias(circleMaskEnabled);
+ }
+
private void checkDestroyedLocked() {
if (mDestroyed) {
throw new IllegalStateException("Cannot perform operation on recycled drawable");
@@ -306,6 +342,10 @@
mBackBitmap = mFrontBitmap;
mFrontBitmap = tmp;
+ BitmapShader tmpShader = mBackBitmapShader;
+ mBackBitmapShader = mFrontBitmapShader;
+ mFrontBitmapShader = tmpShader;
+
mLastSwap = SystemClock.uptimeMillis();
boolean continueLooping = true;
@@ -325,7 +365,17 @@
}
}
- canvas.drawBitmap(mFrontBitmap, mSrcRect, getBounds(), mPaint);
+ if (mCircleMaskEnabled) {
+ Rect bounds = getBounds();
+ mPaint.setShader(mFrontBitmapShader);
+ float width = bounds.width();
+ float height = bounds.height();
+ float circleRadius = (Math.min(width, height)) / 2f;
+ canvas.drawCircle(width / 2f, height / 2f, circleRadius, mPaint);
+ } else {
+ mPaint.setShader(null);
+ canvas.drawBitmap(mFrontBitmap, mSrcRect, getBounds(), mPaint);
+ }
}
private void scheduleDecodeLocked() {
@@ -379,6 +429,7 @@
public void unscheduleSelf(Runnable what) {
synchronized (mLock) {
mNextFrameToDecode = -1;
+ mState = 0;
}
super.unscheduleSelf(what);
}