summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/jni/android/graphics/AnimatedImageDrawable.cpp7
-rw-r--r--graphics/java/android/graphics/drawable/AnimatedImageDrawable.java19
-rw-r--r--libs/hwui/hwui/AnimatedImageDrawable.cpp27
-rw-r--r--libs/hwui/hwui/AnimatedImageDrawable.h24
4 files changed, 60 insertions, 17 deletions
diff --git a/core/jni/android/graphics/AnimatedImageDrawable.cpp b/core/jni/android/graphics/AnimatedImageDrawable.cpp
index d5cad029a934..d6496cdf499a 100644
--- a/core/jni/android/graphics/AnimatedImageDrawable.cpp
+++ b/core/jni/android/graphics/AnimatedImageDrawable.cpp
@@ -213,6 +213,12 @@ static void AnimatedImageDrawable_nMarkInvisible(JNIEnv* env, jobject /*clazz*/,
drawable->markInvisible();
}
+static void AnimatedImageDrawable_nSetMirrored(JNIEnv* env, jobject /*clazz*/, jlong nativePtr,
+ jboolean mirrored) {
+ auto* drawable = reinterpret_cast<AnimatedImageDrawable*>(nativePtr);
+ drawable->setStagingMirrored(mirrored);
+}
+
static const JNINativeMethod gAnimatedImageDrawableMethods[] = {
{ "nCreate", "(JLandroid/graphics/ImageDecoder;IILandroid/graphics/Rect;)J", (void*) AnimatedImageDrawable_nCreate },
{ "nGetNativeFinalizer", "()J", (void*) AnimatedImageDrawable_nGetNativeFinalizer },
@@ -228,6 +234,7 @@ static const JNINativeMethod gAnimatedImageDrawableMethods[] = {
{ "nSetOnAnimationEndListener", "(JLandroid/graphics/drawable/AnimatedImageDrawable;)V", (void*) AnimatedImageDrawable_nSetOnAnimationEndListener },
{ "nNativeByteSize", "(J)J", (void*) AnimatedImageDrawable_nNativeByteSize },
{ "nMarkInvisible", "(J)V", (void*) AnimatedImageDrawable_nMarkInvisible },
+ { "nSetMirrored", "(JZ)V", (void*) AnimatedImageDrawable_nSetMirrored },
};
int register_android_graphics_drawable_AnimatedImageDrawable(JNIEnv* env) {
diff --git a/graphics/java/android/graphics/drawable/AnimatedImageDrawable.java b/graphics/java/android/graphics/drawable/AnimatedImageDrawable.java
index 2ea745c6f49e..c0f49208e27e 100644
--- a/graphics/java/android/graphics/drawable/AnimatedImageDrawable.java
+++ b/graphics/java/android/graphics/drawable/AnimatedImageDrawable.java
@@ -34,6 +34,7 @@ import android.os.Looper;
import android.util.AttributeSet;
import android.util.DisplayMetrics;
import android.util.TypedValue;
+import android.view.View;
import com.android.internal.R;
@@ -389,8 +390,22 @@ public class AnimatedImageDrawable extends Drawable implements Animatable2 {
public void setAutoMirrored(boolean mirrored) {
if (mState.mAutoMirrored != mirrored) {
mState.mAutoMirrored = mirrored;
- invalidateSelf();
+ if (getLayoutDirection() == View.LAYOUT_DIRECTION_RTL && mState.mNativePtr != 0) {
+ nSetMirrored(mState.mNativePtr, mirrored);
+ invalidateSelf();
+ }
+ }
+ }
+
+ @Override
+ public boolean onLayoutDirectionChanged(int layoutDirection) {
+ if (!mState.mAutoMirrored || mState.mNativePtr == 0) {
+ return false;
}
+
+ final boolean mirror = layoutDirection == View.LAYOUT_DIRECTION_RTL;
+ nSetMirrored(mState.mNativePtr, mirror);
+ return true;
}
@Override
@@ -585,4 +600,6 @@ public class AnimatedImageDrawable extends Drawable implements Animatable2 {
private static native long nNativeByteSize(long nativePtr);
@FastNative
private static native void nMarkInvisible(long nativePtr);
+ @FastNative
+ private static native void nSetMirrored(long nativePtr, boolean mirror);
}
diff --git a/libs/hwui/hwui/AnimatedImageDrawable.cpp b/libs/hwui/hwui/AnimatedImageDrawable.cpp
index 7e4f755643bc..28d0bc42ad2f 100644
--- a/libs/hwui/hwui/AnimatedImageDrawable.cpp
+++ b/libs/hwui/hwui/AnimatedImageDrawable.cpp
@@ -32,8 +32,7 @@ AnimatedImageDrawable::AnimatedImageDrawable(sk_sp<SkAnimatedImage> animatedImag
}
void AnimatedImageDrawable::syncProperties() {
- mAlpha = mStagingAlpha;
- mColorFilter = mStagingColorFilter;
+ mProperties = mStagingProperties;
}
bool AnimatedImageDrawable::start() {
@@ -115,12 +114,18 @@ AnimatedImageDrawable::Snapshot AnimatedImageDrawable::reset() {
// Only called on the RenderThread.
void AnimatedImageDrawable::onDraw(SkCanvas* canvas) {
SkTLazy<SkPaint> lazyPaint;
- if (mAlpha != SK_AlphaOPAQUE || mColorFilter.get()) {
+ SkAutoCanvasRestore acr(canvas, false);
+ if (mProperties.mAlpha != SK_AlphaOPAQUE || mProperties.mColorFilter.get()) {
lazyPaint.init();
- lazyPaint.get()->setAlpha(mAlpha);
- lazyPaint.get()->setColorFilter(mColorFilter);
+ lazyPaint.get()->setAlpha(mProperties.mAlpha);
+ lazyPaint.get()->setColorFilter(mProperties.mColorFilter);
lazyPaint.get()->setFilterQuality(kLow_SkFilterQuality);
}
+ if (mProperties.mMirrored) {
+ canvas->save();
+ canvas->translate(mSkAnimatedImage->getBounds().width(), 0);
+ canvas->scale(-1, 1);
+ }
mDidDraw = true;
@@ -131,7 +136,6 @@ void AnimatedImageDrawable::onDraw(SkCanvas* canvas) {
if (drawDirectly) {
// The image is not animating, and never was. Draw directly from
// mSkAnimatedImage.
- SkAutoCanvasRestore acr(canvas, false);
if (lazyPaint.isValid()) {
canvas->saveLayer(mSkAnimatedImage->getBounds(), lazyPaint.get());
}
@@ -190,12 +194,17 @@ void AnimatedImageDrawable::onDraw(SkCanvas* canvas) {
double AnimatedImageDrawable::drawStaging(SkCanvas* canvas) {
SkAutoCanvasRestore acr(canvas, false);
- if (mStagingAlpha != SK_AlphaOPAQUE || mStagingColorFilter.get()) {
+ if (mStagingProperties.mAlpha != SK_AlphaOPAQUE || mStagingProperties.mColorFilter.get()) {
SkPaint paint;
- paint.setAlpha(mStagingAlpha);
- paint.setColorFilter(mStagingColorFilter);
+ paint.setAlpha(mStagingProperties.mAlpha);
+ paint.setColorFilter(mStagingProperties.mColorFilter);
canvas->saveLayer(mSkAnimatedImage->getBounds(), &paint);
}
+ if (mStagingProperties.mMirrored) {
+ canvas->save();
+ canvas->translate(mSkAnimatedImage->getBounds().width(), 0);
+ canvas->scale(-1, 1);
+ }
if (!mRunning) {
// Continue drawing the current frame, and return 0 to indicate no need
diff --git a/libs/hwui/hwui/AnimatedImageDrawable.h b/libs/hwui/hwui/AnimatedImageDrawable.h
index a5260be0097e..f4e2ba751b70 100644
--- a/libs/hwui/hwui/AnimatedImageDrawable.h
+++ b/libs/hwui/hwui/AnimatedImageDrawable.h
@@ -55,9 +55,12 @@ public:
*/
bool isDirty();
- int getStagingAlpha() const { return mStagingAlpha; }
- void setStagingAlpha(int alpha) { mStagingAlpha = alpha; }
- void setStagingColorFilter(sk_sp<SkColorFilter> filter) { mStagingColorFilter = filter; }
+ int getStagingAlpha() const { return mStagingProperties.mAlpha; }
+ void setStagingAlpha(int alpha) { mStagingProperties.mAlpha = alpha; }
+ void setStagingColorFilter(sk_sp<SkColorFilter> filter) {
+ mStagingProperties.mColorFilter = filter;
+ }
+ void setStagingMirrored(bool mirrored) { mStagingProperties.mMirrored = mirrored; }
void syncProperties();
virtual SkRect onGetBounds() override { return mSkAnimatedImage->getBounds(); }
@@ -131,11 +134,18 @@ private:
// Locked when mSkAnimatedImage is being updated or drawn.
std::mutex mImageLock;
- int mStagingAlpha = SK_AlphaOPAQUE;
- sk_sp<SkColorFilter> mStagingColorFilter;
+ struct Properties {
+ int mAlpha = SK_AlphaOPAQUE;
+ sk_sp<SkColorFilter> mColorFilter;
+ bool mMirrored = false;
+
+ Properties() = default;
+ Properties(Properties&) = default;
+ Properties& operator=(Properties&) = default;
+ };
- int mAlpha = SK_AlphaOPAQUE;
- sk_sp<SkColorFilter> mColorFilter;
+ Properties mStagingProperties;
+ Properties mProperties;
std::unique_ptr<OnAnimationEndListener> mEndListener;
};