diff options
| -rw-r--r-- | core/jni/android/graphics/AnimatedImageDrawable.cpp | 7 | ||||
| -rw-r--r-- | graphics/java/android/graphics/drawable/AnimatedImageDrawable.java | 19 | ||||
| -rw-r--r-- | libs/hwui/hwui/AnimatedImageDrawable.cpp | 27 | ||||
| -rw-r--r-- | libs/hwui/hwui/AnimatedImageDrawable.h | 24 |
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; }; |