Merge "Teach AssetAtlas about more drawables" into lmp-mr1-dev

This commit is contained in:
John Reck
2014-12-09 23:12:41 +00:00
committed by Android (Google) Code Review
10 changed files with 102 additions and 20 deletions

View File

@@ -37,6 +37,7 @@ import android.view.View.AttachInfo;
import java.io.FileDescriptor; import java.io.FileDescriptor;
import java.io.PrintWriter; import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.HashSet; import java.util.HashSet;
/** /**
@@ -465,11 +466,13 @@ public class ThreadedRenderer extends HardwareRenderer {
final LongSparseArray<Drawable.ConstantState> drawables = resources.getPreloadedDrawables(); final LongSparseArray<Drawable.ConstantState> drawables = resources.getPreloadedDrawables();
final int count = drawables.size(); final int count = drawables.size();
ArrayList<Bitmap> tmpList = new ArrayList<Bitmap>();
for (int i = 0; i < count; i++) { for (int i = 0; i < count; i++) {
final Bitmap bitmap = drawables.valueAt(i).getBitmap(); drawables.valueAt(i).addAtlasableBitmaps(tmpList);
if (bitmap != null && bitmap.getConfig() == Bitmap.Config.ARGB_8888) { for (int j = 0; j < tmpList.size(); j++) {
preloadedPointers.add(bitmap.mNativeBitmap); preloadedPointers.add(tmpList.get(j).mNativeBitmap);
} }
tmpList.clear();
} }
for (int i = 0; i < map.length; i += 4) { for (int i = 0; i < map.length; i += 4) {

View File

@@ -48,6 +48,7 @@ import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException; import org.xmlpull.v1.XmlPullParserException;
import java.io.IOException; import java.io.IOException;
import java.util.Collection;
/** /**
* A Drawable that wraps a bitmap and can be tiled, stretched, or aligned. You can create a * A Drawable that wraps a bitmap and can be tiled, stretched, or aligned. You can create a
@@ -913,8 +914,11 @@ public class BitmapDrawable extends Drawable {
} }
@Override @Override
public Bitmap getBitmap() { public int addAtlasableBitmaps(Collection<Bitmap> atlasList) {
return mBitmap; if (isAtlasable(mBitmap) && atlasList.add(mBitmap)) {
return mBitmap.getWidth() * mBitmap.getHeight();
}
return 0;
} }
@Override @Override

View File

@@ -51,6 +51,7 @@ import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.lang.ref.WeakReference; import java.lang.ref.WeakReference;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collection;
/** /**
* A Drawable is a general abstraction for "something that can be drawn." Most * A Drawable is a general abstraction for "something that can be drawn." Most
@@ -1244,10 +1245,16 @@ public abstract class Drawable {
public abstract int getChangingConfigurations(); public abstract int getChangingConfigurations();
/** /**
* @return Total pixel count
* @hide * @hide
*/ */
public Bitmap getBitmap() { public int addAtlasableBitmaps(Collection<Bitmap> atlasList) {
return null; return 0;
}
/** @hide */
protected final boolean isAtlasable(Bitmap bitmap) {
return bitmap != null && bitmap.getConfig() == Bitmap.Config.ARGB_8888;
} }
/** /**

View File

@@ -20,6 +20,7 @@ import android.annotation.NonNull;
import android.content.res.ColorStateList; import android.content.res.ColorStateList;
import android.content.res.Resources; import android.content.res.Resources;
import android.content.res.Resources.Theme; import android.content.res.Resources.Theme;
import android.graphics.Bitmap;
import android.graphics.Canvas; import android.graphics.Canvas;
import android.graphics.ColorFilter; import android.graphics.ColorFilter;
import android.graphics.Insets; import android.graphics.Insets;
@@ -31,6 +32,8 @@ import android.os.SystemClock;
import android.util.LayoutDirection; import android.util.LayoutDirection;
import android.util.SparseArray; import android.util.SparseArray;
import java.util.Collection;
/** /**
* A helper class that contains several {@link Drawable}s and selects which one to use. * A helper class that contains several {@link Drawable}s and selects which one to use.
* *
@@ -1062,6 +1065,20 @@ public class DrawableContainer extends Drawable implements Drawable.Callback {
return true; return true;
} }
/** @hide */
@Override
public int addAtlasableBitmaps(Collection<Bitmap> atlasList) {
final int N = mNumChildren;
int pixelCount = 0;
for (int i = 0; i < N; i++) {
final ConstantState state = getChild(i).getConstantState();
if (state != null) {
pixelCount += state.addAtlasableBitmaps(atlasList);
}
}
return pixelCount;
}
/** /**
* Class capable of cloning a Drawable from another Drawable's * Class capable of cloning a Drawable from another Drawable's
* ConstantState. * ConstantState.

View File

@@ -19,6 +19,7 @@ package android.graphics.drawable;
import com.android.internal.R; import com.android.internal.R;
import android.annotation.NonNull; import android.annotation.NonNull;
import org.xmlpull.v1.XmlPullParser; import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException; import org.xmlpull.v1.XmlPullParserException;
@@ -26,16 +27,19 @@ import android.content.res.ColorStateList;
import android.content.res.Resources; import android.content.res.Resources;
import android.content.res.TypedArray; import android.content.res.TypedArray;
import android.content.res.Resources.Theme; import android.content.res.Resources.Theme;
import android.graphics.Bitmap;
import android.graphics.Canvas; import android.graphics.Canvas;
import android.graphics.ColorFilter; import android.graphics.ColorFilter;
import android.graphics.Insets; import android.graphics.Insets;
import android.graphics.Outline; import android.graphics.Outline;
import android.graphics.PixelFormat; import android.graphics.PixelFormat;
import android.graphics.PorterDuff.Mode; import android.graphics.PorterDuff.Mode;
import android.graphics.drawable.Drawable.ConstantState;
import android.graphics.Rect; import android.graphics.Rect;
import android.util.AttributeSet; import android.util.AttributeSet;
import java.io.IOException; import java.io.IOException;
import java.util.Collection;
/** /**
* A Drawable that insets another Drawable by a specified distance. * A Drawable that insets another Drawable by a specified distance.
@@ -472,6 +476,15 @@ public class InsetDrawable extends Drawable implements Drawable.Callback {
return mCanConstantState; return mCanConstantState;
} }
@Override
public int addAtlasableBitmaps(Collection<Bitmap> atlasList) {
final ConstantState state = mDrawable.getConstantState();
if (state != null) {
return state.addAtlasableBitmaps(atlasList);
}
return 0;
}
} }
private InsetDrawable(InsetState state, Resources res) { private InsetDrawable(InsetState state, Resources res) {

View File

@@ -21,6 +21,7 @@ import android.content.res.ColorStateList;
import android.content.res.Resources; import android.content.res.Resources;
import android.content.res.Resources.Theme; import android.content.res.Resources.Theme;
import android.content.res.TypedArray; import android.content.res.TypedArray;
import android.graphics.Bitmap;
import android.graphics.Canvas; import android.graphics.Canvas;
import android.graphics.ColorFilter; import android.graphics.ColorFilter;
import android.graphics.Outline; import android.graphics.Outline;
@@ -36,6 +37,7 @@ import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException; import org.xmlpull.v1.XmlPullParserException;
import java.io.IOException; import java.io.IOException;
import java.util.Collection;
/** /**
* A Drawable that manages an array of other Drawables. These are drawn in array * A Drawable that manages an array of other Drawables. These are drawn in array
@@ -1105,6 +1107,20 @@ public class LayerDrawable extends Drawable implements Drawable.Callback {
mHaveOpacity = false; mHaveOpacity = false;
mHaveIsStateful = false; mHaveIsStateful = false;
} }
@Override
public int addAtlasableBitmaps(Collection<Bitmap> atlasList) {
final ChildDrawable[] array = mChildren;
final int N = mNum;
int pixelCount = 0;
for (int i = 0; i < N; i++) {
final ConstantState state = array[i].mDrawable.getConstantState();
if (state != null) {
pixelCount += state.addAtlasableBitmaps(atlasList);
}
}
return pixelCount;
}
} }
} }

View File

@@ -48,6 +48,7 @@ import org.xmlpull.v1.XmlPullParserException;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.util.Collection;
/** /**
* *
@@ -289,7 +290,7 @@ public class NinePatchDrawable extends Drawable {
if (bounds.isEmpty()) return; if (bounds.isEmpty()) return;
if (mNinePatchState != null) { if (mNinePatchState != null) {
NinePatch.InsetStruct insets = mNinePatchState.getBitmap().getNinePatchInsets(); NinePatch.InsetStruct insets = mNinePatchState.mNinePatch.getBitmap().getNinePatchInsets();
if (insets != null) { if (insets != null) {
final Rect outlineInsets = insets.outlineRect; final Rect outlineInsets = insets.outlineRect;
outline.setRoundRect(bounds.left + outlineInsets.left, outline.setRoundRect(bounds.left + outlineInsets.left,
@@ -648,8 +649,12 @@ public class NinePatchDrawable extends Drawable {
} }
@Override @Override
public Bitmap getBitmap() { public int addAtlasableBitmaps(Collection<Bitmap> atlasList) {
return mNinePatch.getBitmap(); final Bitmap bitmap = mNinePatch.getBitmap();
if (isAtlasable(bitmap) && atlasList.add(bitmap)) {
return bitmap.getWidth() * bitmap.getHeight();
}
return 0;
} }
@Override @Override

View File

@@ -31,6 +31,7 @@ import android.view.Gravity;
import android.util.AttributeSet; import android.util.AttributeSet;
import java.io.IOException; import java.io.IOException;
import java.util.Collection;
/** /**
* A Drawable that changes the size of another Drawable based on its current * A Drawable that changes the size of another Drawable based on its current
@@ -413,6 +414,15 @@ public class ScaleDrawable extends Drawable implements Drawable.Callback {
return mCanConstantState; return mCanConstantState;
} }
@Override
public int addAtlasableBitmaps(Collection<Bitmap> atlasList) {
final ConstantState state = mDrawable.getConstantState();
if (state != null) {
return state.addAtlasableBitmaps(atlasList);
}
return 0;
}
} }
private ScaleDrawable(ScaleState state, Resources res) { private ScaleDrawable(ScaleState state, Resources res) {

View File

@@ -720,7 +720,8 @@ public:
} }
virtual void output(int level, uint32_t logFlags) const { virtual void output(int level, uint32_t logFlags) const {
OP_LOG("Draw bitmap %p at %f %f", mBitmap, mLocalBounds.left, mLocalBounds.top); OP_LOG("Draw bitmap %p at %f %f%s", mBitmap, mLocalBounds.left, mLocalBounds.top,
mEntry ? " using AssetAtlas" : "");
} }
virtual const char* name() { return "DrawBitmap"; } virtual const char* name() { return "DrawBitmap"; }
@@ -954,7 +955,8 @@ public:
} }
virtual void output(int level, uint32_t logFlags) const { virtual void output(int level, uint32_t logFlags) const {
OP_LOG("Draw patch " RECT_STRING, RECT_ARGS(mLocalBounds)); OP_LOG("Draw patch " RECT_STRING "%s", RECT_ARGS(mLocalBounds),
mEntry ? " with AssetAtlas" : "");
} }
virtual const char* name() { return "DrawPatch"; } virtual const char* name() { return "DrawPatch"; }

View File

@@ -46,8 +46,11 @@ import java.io.IOException;
import java.io.InputStreamReader; import java.io.InputStreamReader;
import java.io.OutputStreamWriter; import java.io.OutputStreamWriter;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections; import java.util.Collections;
import java.util.Comparator; import java.util.Comparator;
import java.util.HashSet;
import java.util.List; import java.util.List;
import java.util.concurrent.CountDownLatch; import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
@@ -66,7 +69,7 @@ public class AssetAtlasService extends IAssetAtlas.Stub {
*/ */
public static final String ASSET_ATLAS_SERVICE = "assetatlas"; public static final String ASSET_ATLAS_SERVICE = "assetatlas";
private static final String LOG_TAG = "Atlas"; private static final String LOG_TAG = "AssetAtlas";
// Turns debug logs on/off. Debug logs are kept to a minimum and should // Turns debug logs on/off. Debug logs are kept to a minimum and should
// remain on to diagnose issues // remain on to diagnose issues
@@ -131,7 +134,7 @@ public class AssetAtlasService extends IAssetAtlas.Stub {
mContext = context; mContext = context;
mVersionName = queryVersionName(context); mVersionName = queryVersionName(context);
ArrayList<Bitmap> bitmaps = new ArrayList<Bitmap>(300); Collection<Bitmap> bitmaps = new HashSet<Bitmap>(300);
int totalPixelCount = 0; int totalPixelCount = 0;
// We only care about drawables that hold bitmaps // We only care about drawables that hold bitmaps
@@ -140,16 +143,18 @@ public class AssetAtlasService extends IAssetAtlas.Stub {
final int count = drawables.size(); final int count = drawables.size();
for (int i = 0; i < count; i++) { for (int i = 0; i < count; i++) {
final Bitmap bitmap = drawables.valueAt(i).getBitmap(); try {
if (bitmap != null && bitmap.getConfig() == Bitmap.Config.ARGB_8888) { totalPixelCount += drawables.valueAt(i).addAtlasableBitmaps(bitmaps);
bitmaps.add(bitmap); } catch (Throwable t) {
totalPixelCount += bitmap.getWidth() * bitmap.getHeight(); Log.e("AssetAtlas", "Failed to fetch preloaded drawable state", t);
throw t;
} }
} }
ArrayList<Bitmap> sortedBitmaps = new ArrayList<Bitmap>(bitmaps);
// Our algorithms perform better when the bitmaps are first sorted // Our algorithms perform better when the bitmaps are first sorted
// The comparator will sort the bitmap by width first, then by height // The comparator will sort the bitmap by width first, then by height
Collections.sort(bitmaps, new Comparator<Bitmap>() { Collections.sort(sortedBitmaps, new Comparator<Bitmap>() {
@Override @Override
public int compare(Bitmap b1, Bitmap b2) { public int compare(Bitmap b1, Bitmap b2) {
if (b1.getWidth() == b2.getWidth()) { if (b1.getWidth() == b2.getWidth()) {
@@ -160,7 +165,7 @@ public class AssetAtlasService extends IAssetAtlas.Stub {
}); });
// Kick off the packing work on a worker thread // Kick off the packing work on a worker thread
new Thread(new Renderer(bitmaps, totalPixelCount)).start(); new Thread(new Renderer(sortedBitmaps, totalPixelCount)).start();
} }
/** /**