Better implementation to clear display lists

Change-Id: I58f9af4bae70a8117db1455a50c0c5daf19b2f4a
This commit is contained in:
Romain Guy
2012-03-15 18:30:47 -07:00
parent cde6adf45c
commit 51e4d4db29
3 changed files with 59 additions and 33 deletions

View File

@@ -28,13 +28,6 @@ import android.os.Handler;
* @hide
*/
public abstract class DisplayList {
private final Runnable mInvalidate = new Runnable() {
@Override
public void run() {
invalidate();
}
};
/**
* Flag used when calling
* {@link HardwareCanvas#drawDisplayList(DisplayList, int, int, android.graphics.Rect, int)}.
@@ -65,13 +58,6 @@ public abstract class DisplayList {
*/
public abstract void invalidate();
/**
* Posts a call to {@link #invalidate()} in the specified handler.
*/
final void postInvalidate(Handler handler) {
handler.post(mInvalidate);
}
/**
* Returns whether the display list is currently usable. If this returns false,
* the display list should be re-recorded prior to replaying it.

View File

@@ -9974,12 +9974,16 @@ public class View implements Drawable.Callback, Drawable.Callback2, KeyEvent.Cal
destroyLayer();
if (mDisplayList != null) {
mDisplayList.postInvalidate(mAttachInfo.mHandler);
}
if (mAttachInfo != null) {
if (mDisplayList != null) {
mAttachInfo.mViewRootImpl.invalidateDisplayList(mDisplayList);
}
mAttachInfo.mViewRootImpl.cancelInvalidate(this);
} else {
if (mDisplayList != null) {
// Should never happen
mDisplayList.invalidate();
}
}
mCurrentAnimation = null;

View File

@@ -117,6 +117,8 @@ public final class ViewRootImpl implements ViewParent,
private static final boolean DEBUG_CONFIGURATION = false || LOCAL_LOGV;
private static final boolean DEBUG_FPS = false;
private static final boolean USE_RENDER_THREAD = false;
/**
* Set this system property to true to force the view hierarchy to render
* at 60 Hz. This can be used to measure the potential framerate.
@@ -300,6 +302,8 @@ public final class ViewRootImpl implements ViewParent,
private long mFpsPrevTime = -1;
private int mFpsNumFrames;
private final ArrayList<DisplayList> mDisplayLists = new ArrayList<DisplayList>(24);
/**
* see {@link #playSoundEffect(int)}
*/
@@ -402,23 +406,27 @@ public final class ViewRootImpl implements ViewParent,
* false otherwise
*/
private static boolean isRenderThreadRequested(Context context) {
synchronized (sRenderThreadQueryLock) {
if (!sRenderThreadQueried) {
final PackageManager packageManager = context.getPackageManager();
final String packageName = context.getApplicationInfo().packageName;
try {
ApplicationInfo applicationInfo = packageManager.getApplicationInfo(packageName,
PackageManager.GET_META_DATA);
if (applicationInfo.metaData != null) {
sUseRenderThread = applicationInfo.metaData.getBoolean(
"android.graphics.renderThread", false);
if (USE_RENDER_THREAD) {
synchronized (sRenderThreadQueryLock) {
if (!sRenderThreadQueried) {
final PackageManager packageManager = context.getPackageManager();
final String packageName = context.getApplicationInfo().packageName;
try {
ApplicationInfo applicationInfo = packageManager.getApplicationInfo(packageName,
PackageManager.GET_META_DATA);
if (applicationInfo.metaData != null) {
sUseRenderThread = applicationInfo.metaData.getBoolean(
"android.graphics.renderThread", false);
}
} catch (PackageManager.NameNotFoundException e) {
} finally {
sRenderThreadQueried = true;
}
} catch (PackageManager.NameNotFoundException e) {
} finally {
sRenderThreadQueried = true;
}
return sUseRenderThread;
}
return sUseRenderThread;
} else {
return false;
}
}
@@ -690,7 +698,7 @@ public final class ViewRootImpl implements ViewParent,
return;
}
boolean renderThread = isRenderThreadRequested(context);
final boolean renderThread = isRenderThreadRequested(context);
if (renderThread) {
Log.i(HardwareRenderer.LOG_TAG, "Render threat initiated");
}
@@ -2210,6 +2218,17 @@ public final class ViewRootImpl implements ViewParent,
}
}
void invalidateDisplayLists() {
final ArrayList<DisplayList> displayLists = mDisplayLists;
final int count = displayLists.size();
for (int i = 0; i < count; i++) {
displayLists.get(i).invalidate();
}
displayLists.clear();
}
boolean scrollToRectOrFocus(Rect rectangle, boolean immediate) {
final View.AttachInfo attachInfo = mAttachInfo;
final Rect ci = attachInfo.mContentInsets;
@@ -2516,6 +2535,7 @@ public final class ViewRootImpl implements ViewParent,
private final static int MSG_FIND_ACCESSIBLITY_NODE_INFO_BY_TEXT = 22;
private final static int MSG_PROCESS_INPUT_EVENTS = 23;
private final static int MSG_DISPATCH_SCREEN_STATE = 24;
private final static int MSG_INVALIDATE_DISPLAY_LIST = 25;
final class ViewRootHandler extends Handler {
@Override
@@ -2567,6 +2587,10 @@ public final class ViewRootImpl implements ViewParent,
return "MSG_FIND_ACCESSIBLITY_NODE_INFO_BY_TEXT";
case MSG_PROCESS_INPUT_EVENTS:
return "MSG_PROCESS_INPUT_EVENTS";
case MSG_DISPATCH_SCREEN_STATE:
return "MSG_DISPATCH_SCREEN_STATE";
case MSG_INVALIDATE_DISPLAY_LIST:
return "MSG_INVALIDATE_DISPLAY_LIST";
}
return super.getMessageName(message);
}
@@ -2777,9 +2801,13 @@ public final class ViewRootImpl implements ViewParent,
handleScreenStateChange(msg.arg1 == 1);
}
} break;
case MSG_INVALIDATE_DISPLAY_LIST: {
invalidateDisplayLists();
} break;
}
}
}
final ViewRootHandler mHandler = new ViewRootHandler();
/**
@@ -4136,6 +4164,14 @@ public final class ViewRootImpl implements ViewParent,
mInvalidateOnAnimationRunnable.addViewRect(info);
}
public void invalidateDisplayList(DisplayList displayList) {
mDisplayLists.add(displayList);
mHandler.removeMessages(MSG_INVALIDATE_DISPLAY_LIST);
Message msg = mHandler.obtainMessage(MSG_INVALIDATE_DISPLAY_LIST);
mHandler.sendMessage(msg);
}
public void cancelInvalidate(View view) {
mHandler.removeMessages(MSG_INVALIDATE, view);
// fixme: might leak the AttachInfo.InvalidateInfo objects instead of returning