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

Commit a2d5e7c1 authored by Jeremy Meyer's avatar Jeremy Meyer Committed by Android (Google) Code Review
Browse files

Merge "Improve performance of generations in the resource cache"

parents 4f934588 094f7289
Loading
Loading
Loading
Loading
+12 −12
Original line number Diff line number Diff line
@@ -111,20 +111,20 @@ public class AnimatorInflater {
            float pathErrorScale) throws NotFoundException {
        final ConfigurationBoundResourceCache<Animator> animatorCache = resources
                .getAnimatorCache();
        ConfigurationBoundResourceCache.Entry<Animator> animatorEntry =
                animatorCache.getInstance(id, resources, theme);
        if (animatorEntry.hasValue()) {
        Animator animator = animatorCache.getInstance(id, resources, theme);
        if (animator != null) {
            if (DBG_ANIMATOR_INFLATER) {
                Log.d(TAG, "loaded animator from cache, " + resources.getResourceName(id));
            }
            return animatorEntry.getValue();
            return animator;
        } else if (DBG_ANIMATOR_INFLATER) {
            Log.d(TAG, "cache miss for animator " + resources.getResourceName(id));
        }
        int cacheGeneration = animatorCache.getGeneration();
        XmlResourceParser parser = null;
        try {
            parser = resources.getAnimation(id);
            Animator animator = createAnimatorFromXml(resources, theme, parser, pathErrorScale);
            animator = createAnimatorFromXml(resources, theme, parser, pathErrorScale);
            if (animator != null) {
                animator.appendChangingConfigurations(getChangingConfigs(resources, id));
                final ConstantState<Animator> constantState = animator.createConstantState();
@@ -132,7 +132,7 @@ public class AnimatorInflater {
                    if (DBG_ANIMATOR_INFLATER) {
                        Log.d(TAG, "caching animator for res " + resources.getResourceName(id));
                    }
                    animatorCache.put(id, theme, constantState, animatorEntry.getGeneration());
                    animatorCache.put(id, theme, constantState, cacheGeneration);
                    // create a new animator so that cached version is never used by the user
                    animator = constantState.newInstance(resources, theme);
                }
@@ -161,22 +161,22 @@ public class AnimatorInflater {
        final ConfigurationBoundResourceCache<StateListAnimator> cache = resources
                .getStateListAnimatorCache();
        final Theme theme = context.getTheme();
        ConfigurationBoundResourceCache.Entry<StateListAnimator> animatorEntry =
                cache.getInstance(id, resources, theme);
        if (animatorEntry.hasValue()) {
            return animatorEntry.getValue();
        StateListAnimator animator = cache.getInstance(id, resources, theme);
        if (animator != null) {
            return animator;
        }
        int cacheGeneration = cache.getGeneration();
        XmlResourceParser parser = null;
        try {
            parser = resources.getAnimation(id);
            StateListAnimator animator =
            animator =
                    createStateListAnimatorFromXml(context, parser, Xml.asAttributeSet(parser));
            if (animator != null) {
                animator.appendChangingConfigurations(getChangingConfigs(resources, id));
                final ConstantState<StateListAnimator> constantState = animator
                        .createConstantState();
                if (constantState != null) {
                    cache.put(id, theme, constantState, animatorEntry.getGeneration());
                    cache.put(id, theme, constantState, cacheGeneration);
                    // return a clone so that the animator in constant state is never used.
                    animator = constantState.newInstance(resources, theme);
                }
+6 −6
Original line number Diff line number Diff line
@@ -37,16 +37,16 @@ public class ConfigurationBoundResourceCache<T> extends ThemedResourceCache<Cons
     * @param key a key that uniquely identifies the drawable resource
     * @param resources a Resources object from which to create new instances.
     * @param theme the theme where the resource will be used
     * @return an Entry wrapping a new instance of the resource, or {@code null} if not in
     * @return a new instance of the resource, or {@code null} if not in
     *         the cache
     */
    public Entry<T> getInstance(long key, Resources resources, Resources.Theme theme) {
        final Entry<ConstantState<T>> e = get(key, theme);
        if (e.hasValue()) {
            return new Entry<>(e.getValue().newInstance(resources, theme), e.getGeneration());
    public T getInstance(long key, Resources resources, Resources.Theme theme) {
        final ConstantState<T> entry = get(key, theme);
        if (entry != null) {
            return entry.newInstance(resources, theme);
        }

        return new Entry<>(null, e.getGeneration());
        return null;
    }

    @Override
+3 −21
Original line number Diff line number Diff line
@@ -40,32 +40,14 @@ class DrawableCache extends ThemedResourceCache<Drawable.ConstantState> {
     */
    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
    public Drawable getInstance(long key, Resources resources, Resources.Theme theme) {
        final Entry<Drawable.ConstantState> entry = get(key, theme);
        if (entry.getValue() != null) {
            return entry.getValue().newDrawable(resources, theme);
        final Drawable.ConstantState entry = get(key, theme);
        if (entry != null) {
            return entry.newDrawable(resources, theme);
        }

        return null;
    }

    /**
     * If the resource is cached, creates and returns a new instance of it.
     *
     * @param key a key that uniquely identifies the drawable resource
     * @param resources a Resources object from which to create new instances.
     * @param theme the theme where the resource will be used
     * @return an Entry wrapping a a new instance of the resource, or {@code null} if not in
     *         the cache
     */
    public Entry<Drawable> getDrawable(long key, Resources resources, Resources.Theme theme) {
        final Entry<Drawable.ConstantState> e = get(key, theme);
        if (e.hasValue()) {
            return new Entry<>(e.getValue().newDrawable(resources, theme), e.getGeneration());
        }

        return new Entry<>(null, e.getGeneration());
    }

    @Override
    public boolean shouldInvalidateEntry(Drawable.ConstantState entry, int configChanges) {
        return Configuration.needNewResources(configChanges, entry.getChangingConfigurations());
+10 −17
Original line number Diff line number Diff line
@@ -658,21 +658,16 @@ public class ResourcesImpl {
                key = (((long) value.assetCookie) << 32) | value.data;
            }

            int cacheGeneration;
            int cacheGeneration = caches.getGeneration();
            // First, check whether we have a cached version of this drawable
            // that was inflated against the specified theme. Skip the cache if
            // we're currently preloading or we're not using the cache.
            if (!mPreloading && useCache) {
                final ThemedResourceCache.Entry<Drawable> cachedDrawable =
                        caches.getDrawable(key, wrapper, theme);
                if (cachedDrawable.hasValue()) {
                    cachedDrawable.getValue().setChangingConfigurations(
                            value.changingConfigurations);
                    return cachedDrawable.getValue();
                }
                cacheGeneration = cachedDrawable.getGeneration();
            } else {
                cacheGeneration = ThemedResourceCache.UNDEFINED_GENERATION;
                Drawable cachedDrawable = caches.getInstance(key, wrapper, theme);
                if (cachedDrawable != null) {
                    cachedDrawable.setChangingConfigurations(value.changingConfigurations);
                    return cachedDrawable;
                }
            }

            // Next, check preloaded drawables. Preloaded drawables may contain
@@ -1017,16 +1012,15 @@ public class ResourcesImpl {
            TypedValue value, int id) {
        final long key = (((long) value.assetCookie) << 32) | value.data;
        final ConfigurationBoundResourceCache<ComplexColor> cache = mComplexColorCache;
        ThemedResourceCache.Entry<ComplexColor> complexColorEntry =
                cache.getInstance(key, wrapper, theme);
        if (complexColorEntry.hasValue()) {
            return complexColorEntry.getValue();
        ComplexColor complexColor = cache.getInstance(key, wrapper, theme);
        if (complexColor != null) {
            return complexColor;
        }
        int cacheGeneration = cache.getGeneration();

        final android.content.res.ConstantState<ComplexColor> factory =
                sPreloadedComplexColors.get(key);

        ComplexColor complexColor = null;
        if (factory != null) {
            complexColor = factory.newInstance(wrapper, theme);
        }
@@ -1043,8 +1037,7 @@ public class ResourcesImpl {
                    sPreloadedComplexColors.put(key, complexColor.getConstantState());
                }
            } else {
                cache.put(key, theme, complexColor.getConstantState(),
                        complexColorEntry.getGeneration());
                cache.put(key, theme, complexColor.getConstantState(), cacheGeneration);
            }
        }
        return complexColor;
+14 −27
Original line number Diff line number Diff line
@@ -41,29 +41,6 @@ abstract class ThemedResourceCache<T> {

    private int mGeneration;

    public static class Entry<S> {
        private S mValue;
        private int mGeneration;


        public S getValue() {
            return mValue;
        }

        public boolean hasValue() {
            return mValue != null;
        }

        public int getGeneration() {
            return mGeneration;
        }

        Entry(S value, int generation) {
            this.mValue = value;
            this.mGeneration = generation;
        }
    }

    /**
     * Adds a new theme-dependent entry to the cache.
     *
@@ -108,6 +85,15 @@ abstract class ThemedResourceCache<T> {
        }
    }

    /**
     * Returns the current generation of the cache
     *
     * @return The current generation
     */
    public int getGeneration() {
        return mGeneration;
    }

    /**
     * Returns an entry from the cache.
     *
@@ -116,7 +102,7 @@ abstract class ThemedResourceCache<T> {
     * @return a cached entry, or {@code null} if not in the cache
     */
    @Nullable
    public Entry get(long key, @Nullable Theme theme) {
    public T get(long key, @Nullable Theme theme) {
        // The themed (includes null-themed) and unthemed caches are mutually
        // exclusive, so we'll give priority to whichever one we think we'll
        // hit first. Since most of the framework drawables are themed, that's
@@ -126,7 +112,7 @@ abstract class ThemedResourceCache<T> {
            if (themedEntries != null) {
                final WeakReference<T> themedEntry = themedEntries.get(key);
                if (themedEntry != null) {
                    return new Entry(themedEntry.get(), mGeneration);
                    return themedEntry.get();
                }
            }

@@ -134,14 +120,15 @@ abstract class ThemedResourceCache<T> {
            if (unthemedEntries != null) {
                final WeakReference<T> unthemedEntry = unthemedEntries.get(key);
                if (unthemedEntry != null) {
                    return new Entry(unthemedEntry.get(), mGeneration);
                    return unthemedEntry.get();
                }
            }
        }

        return new Entry(null, mGeneration);
        return null;
    }


    /**
     * Prunes cache entries that have been invalidated by a configuration
     * change.
Loading