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.PrintWriter;
import java.util.ArrayList;
import java.util.HashSet;
/**
@@ -465,11 +466,13 @@ public class ThreadedRenderer extends HardwareRenderer {
final LongSparseArray<Drawable.ConstantState> drawables = resources.getPreloadedDrawables();
final int count = drawables.size();
ArrayList<Bitmap> tmpList = new ArrayList<Bitmap>();
for (int i = 0; i < count; i++) {
final Bitmap bitmap = drawables.valueAt(i).getBitmap();
if (bitmap != null && bitmap.getConfig() == Bitmap.Config.ARGB_8888) {
preloadedPointers.add(bitmap.mNativeBitmap);
drawables.valueAt(i).addAtlasableBitmaps(tmpList);
for (int j = 0; j < tmpList.size(); j++) {
preloadedPointers.add(tmpList.get(j).mNativeBitmap);
}
tmpList.clear();
}
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 java.io.IOException;
import java.util.Collection;
/**
* 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
public Bitmap getBitmap() {
return mBitmap;
public int addAtlasableBitmaps(Collection<Bitmap> atlasList) {
if (isAtlasable(mBitmap) && atlasList.add(mBitmap)) {
return mBitmap.getWidth() * mBitmap.getHeight();
}
return 0;
}
@Override

View File

@@ -51,6 +51,7 @@ import java.io.IOException;
import java.io.InputStream;
import java.lang.ref.WeakReference;
import java.util.Arrays;
import java.util.Collection;
/**
* 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();
/**
* @return Total pixel count
* @hide
*/
public Bitmap getBitmap() {
return null;
public int addAtlasableBitmaps(Collection<Bitmap> atlasList) {
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.Resources;
import android.content.res.Resources.Theme;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.ColorFilter;
import android.graphics.Insets;
@@ -31,6 +32,8 @@ import android.os.SystemClock;
import android.util.LayoutDirection;
import android.util.SparseArray;
import java.util.Collection;
/**
* 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;
}
/** @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
* ConstantState.

View File

@@ -19,6 +19,7 @@ package android.graphics.drawable;
import com.android.internal.R;
import android.annotation.NonNull;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
@@ -26,16 +27,19 @@ import android.content.res.ColorStateList;
import android.content.res.Resources;
import android.content.res.TypedArray;
import android.content.res.Resources.Theme;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.ColorFilter;
import android.graphics.Insets;
import android.graphics.Outline;
import android.graphics.PixelFormat;
import android.graphics.PorterDuff.Mode;
import android.graphics.drawable.Drawable.ConstantState;
import android.graphics.Rect;
import android.util.AttributeSet;
import java.io.IOException;
import java.util.Collection;
/**
* A Drawable that insets another Drawable by a specified distance.
@@ -472,6 +476,15 @@ public class InsetDrawable extends Drawable implements Drawable.Callback {
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) {

View File

@@ -21,6 +21,7 @@ import android.content.res.ColorStateList;
import android.content.res.Resources;
import android.content.res.Resources.Theme;
import android.content.res.TypedArray;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.ColorFilter;
import android.graphics.Outline;
@@ -36,6 +37,7 @@ import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
import java.io.IOException;
import java.util.Collection;
/**
* 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;
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.InputStream;
import java.util.Collection;
/**
*
@@ -289,7 +290,7 @@ public class NinePatchDrawable extends Drawable {
if (bounds.isEmpty()) return;
if (mNinePatchState != null) {
NinePatch.InsetStruct insets = mNinePatchState.getBitmap().getNinePatchInsets();
NinePatch.InsetStruct insets = mNinePatchState.mNinePatch.getBitmap().getNinePatchInsets();
if (insets != null) {
final Rect outlineInsets = insets.outlineRect;
outline.setRoundRect(bounds.left + outlineInsets.left,
@@ -648,8 +649,12 @@ public class NinePatchDrawable extends Drawable {
}
@Override
public Bitmap getBitmap() {
return mNinePatch.getBitmap();
public int addAtlasableBitmaps(Collection<Bitmap> atlasList) {
final Bitmap bitmap = mNinePatch.getBitmap();
if (isAtlasable(bitmap) && atlasList.add(bitmap)) {
return bitmap.getWidth() * bitmap.getHeight();
}
return 0;
}
@Override

View File

@@ -31,6 +31,7 @@ import android.view.Gravity;
import android.util.AttributeSet;
import java.io.IOException;
import java.util.Collection;
/**
* 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;
}
@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) {

View File

@@ -720,7 +720,8 @@ public:
}
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"; }
@@ -954,7 +955,8 @@ public:
}
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"; }

View File

@@ -46,8 +46,11 @@ import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashSet;
import java.util.List;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
@@ -66,7 +69,7 @@ public class AssetAtlasService extends IAssetAtlas.Stub {
*/
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
// remain on to diagnose issues
@@ -131,7 +134,7 @@ public class AssetAtlasService extends IAssetAtlas.Stub {
mContext = context;
mVersionName = queryVersionName(context);
ArrayList<Bitmap> bitmaps = new ArrayList<Bitmap>(300);
Collection<Bitmap> bitmaps = new HashSet<Bitmap>(300);
int totalPixelCount = 0;
// We only care about drawables that hold bitmaps
@@ -140,16 +143,18 @@ public class AssetAtlasService extends IAssetAtlas.Stub {
final int count = drawables.size();
for (int i = 0; i < count; i++) {
final Bitmap bitmap = drawables.valueAt(i).getBitmap();
if (bitmap != null && bitmap.getConfig() == Bitmap.Config.ARGB_8888) {
bitmaps.add(bitmap);
totalPixelCount += bitmap.getWidth() * bitmap.getHeight();
try {
totalPixelCount += drawables.valueAt(i).addAtlasableBitmaps(bitmaps);
} catch (Throwable t) {
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
// 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
public int compare(Bitmap b1, Bitmap b2) {
if (b1.getWidth() == b2.getWidth()) {
@@ -160,7 +165,7 @@ public class AssetAtlasService extends IAssetAtlas.Stub {
});
// Kick off the packing work on a worker thread
new Thread(new Renderer(bitmaps, totalPixelCount)).start();
new Thread(new Renderer(sortedBitmaps, totalPixelCount)).start();
}
/**