Merge change 1747 into donut
* changes: Fixes #1846038. The dirty region can sometimes be modified by SurfaceFlinger. When this happens, force the view hierarchy to ignore the dirty flags.
This commit is contained in:
@@ -1449,7 +1449,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback {
|
|||||||
@ViewDebug.FlagToString(mask = LAYOUT_REQUIRED, equals = LAYOUT_REQUIRED,
|
@ViewDebug.FlagToString(mask = LAYOUT_REQUIRED, equals = LAYOUT_REQUIRED,
|
||||||
name = "LAYOUT_REQUIRED"),
|
name = "LAYOUT_REQUIRED"),
|
||||||
@ViewDebug.FlagToString(mask = DRAWING_CACHE_VALID, equals = DRAWING_CACHE_VALID,
|
@ViewDebug.FlagToString(mask = DRAWING_CACHE_VALID, equals = DRAWING_CACHE_VALID,
|
||||||
name = "DRAWING_CACHE_VALID", outputIf = false),
|
name = "DRAWING_CACHE_INVALID", outputIf = false),
|
||||||
@ViewDebug.FlagToString(mask = DRAWN, equals = DRAWN, name = "DRAWN", outputIf = true),
|
@ViewDebug.FlagToString(mask = DRAWN, equals = DRAWN, name = "DRAWN", outputIf = true),
|
||||||
@ViewDebug.FlagToString(mask = DRAWN, equals = DRAWN, name = "NOT_DRAWN", outputIf = false),
|
@ViewDebug.FlagToString(mask = DRAWN, equals = DRAWN, name = "NOT_DRAWN", outputIf = false),
|
||||||
@ViewDebug.FlagToString(mask = DIRTY_MASK, equals = DIRTY_OPAQUE, name = "DIRTY_OPAQUE"),
|
@ViewDebug.FlagToString(mask = DIRTY_MASK, equals = DIRTY_OPAQUE, name = "DIRTY_OPAQUE"),
|
||||||
@@ -5739,13 +5739,14 @@ public class View implements Drawable.Callback, KeyEvent.Callback {
|
|||||||
final int restoreCount = canvas.save();
|
final int restoreCount = canvas.save();
|
||||||
canvas.translate(-mScrollX, -mScrollY);
|
canvas.translate(-mScrollX, -mScrollY);
|
||||||
|
|
||||||
mPrivateFlags = (mPrivateFlags & ~DIRTY_MASK) | DRAWN;
|
mPrivateFlags |= DRAWN;
|
||||||
|
|
||||||
// Fast path for layouts with no backgrounds
|
// Fast path for layouts with no backgrounds
|
||||||
if ((mPrivateFlags & SKIP_DRAW) == SKIP_DRAW) {
|
if ((mPrivateFlags & SKIP_DRAW) == SKIP_DRAW) {
|
||||||
if (ViewDebug.TRACE_HIERARCHY) {
|
if (ViewDebug.TRACE_HIERARCHY) {
|
||||||
ViewDebug.trace(this, ViewDebug.HierarchyTraceType.DRAW);
|
ViewDebug.trace(this, ViewDebug.HierarchyTraceType.DRAW);
|
||||||
}
|
}
|
||||||
|
mPrivateFlags &= ~DIRTY_MASK;
|
||||||
dispatchDraw(canvas);
|
dispatchDraw(canvas);
|
||||||
} else {
|
} else {
|
||||||
draw(canvas);
|
draw(canvas);
|
||||||
@@ -5800,6 +5801,10 @@ public class View implements Drawable.Callback, KeyEvent.Callback {
|
|||||||
final int restoreCount = canvas.save();
|
final int restoreCount = canvas.save();
|
||||||
canvas.translate(-mScrollX, -mScrollY);
|
canvas.translate(-mScrollX, -mScrollY);
|
||||||
|
|
||||||
|
// Temporarily remove the dirty mask
|
||||||
|
int flags = mPrivateFlags;
|
||||||
|
mPrivateFlags &= ~DIRTY_MASK;
|
||||||
|
|
||||||
// Fast path for layouts with no backgrounds
|
// Fast path for layouts with no backgrounds
|
||||||
if ((mPrivateFlags & SKIP_DRAW) == SKIP_DRAW) {
|
if ((mPrivateFlags & SKIP_DRAW) == SKIP_DRAW) {
|
||||||
dispatchDraw(canvas);
|
dispatchDraw(canvas);
|
||||||
@@ -5807,6 +5812,8 @@ public class View implements Drawable.Callback, KeyEvent.Callback {
|
|||||||
draw(canvas);
|
draw(canvas);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mPrivateFlags = flags;
|
||||||
|
|
||||||
canvas.restoreToCount(restoreCount);
|
canvas.restoreToCount(restoreCount);
|
||||||
|
|
||||||
if (attachInfo != null) {
|
if (attachInfo != null) {
|
||||||
@@ -5927,8 +5934,10 @@ public class View implements Drawable.Callback, KeyEvent.Callback {
|
|||||||
ViewDebug.trace(this, ViewDebug.HierarchyTraceType.DRAW);
|
ViewDebug.trace(this, ViewDebug.HierarchyTraceType.DRAW);
|
||||||
}
|
}
|
||||||
|
|
||||||
final boolean dirtyOpaque = (mPrivateFlags & DIRTY_MASK) == DIRTY_OPAQUE;
|
final int privateFlags = mPrivateFlags;
|
||||||
mPrivateFlags = (mPrivateFlags & ~DIRTY_MASK) | DRAWN;
|
final boolean dirtyOpaque = (privateFlags & DIRTY_MASK) == DIRTY_OPAQUE &&
|
||||||
|
(mAttachInfo == null || !mAttachInfo.mIgnoreDirtyState);
|
||||||
|
mPrivateFlags = (privateFlags & ~DIRTY_MASK) | DRAWN;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Draw traversal performs several drawing steps which must be executed
|
* Draw traversal performs several drawing steps which must be executed
|
||||||
@@ -8158,7 +8167,6 @@ public class View implements Drawable.Callback, KeyEvent.Callback {
|
|||||||
* window.
|
* window.
|
||||||
*/
|
*/
|
||||||
static class AttachInfo {
|
static class AttachInfo {
|
||||||
|
|
||||||
interface Callbacks {
|
interface Callbacks {
|
||||||
void playSoundEffect(int effectId);
|
void playSoundEffect(int effectId);
|
||||||
boolean performHapticFeedback(int effectId, boolean always);
|
boolean performHapticFeedback(int effectId, boolean always);
|
||||||
@@ -8287,6 +8295,11 @@ public class View implements Drawable.Callback, KeyEvent.Callback {
|
|||||||
*/
|
*/
|
||||||
long mDrawingTime;
|
long mDrawingTime;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Indicates whether or not ignoring the DIRTY_MASK flags.
|
||||||
|
*/
|
||||||
|
boolean mIgnoreDirtyState;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Indicates whether the view's window is currently in touch mode.
|
* Indicates whether the view's window is currently in touch mode.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -1235,10 +1235,11 @@ public class ViewDebug {
|
|||||||
for (int j = 0; j < count; j++) {
|
for (int j = 0; j < count; j++) {
|
||||||
final FlagToString flagMapping = mapping[j];
|
final FlagToString flagMapping = mapping[j];
|
||||||
final boolean ifTrue = flagMapping.outputIf();
|
final boolean ifTrue = flagMapping.outputIf();
|
||||||
final boolean test = (intValue & flagMapping.mask()) == flagMapping.equals();
|
final int maskResult = intValue & flagMapping.mask();
|
||||||
|
final boolean test = maskResult == flagMapping.equals();
|
||||||
if ((test && ifTrue) || (!test && !ifTrue)) {
|
if ((test && ifTrue) || (!test && !ifTrue)) {
|
||||||
final String name = flagMapping.name();
|
final String name = flagMapping.name();
|
||||||
final String value = ifTrue ? "true" : "false";
|
final String value = "0x" + Integer.toHexString(maskResult);
|
||||||
writeEntry(out, prefix, name, "", value);
|
writeEntry(out, prefix, name, "", value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1403,9 +1403,9 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Clear the flag as early as possible to allow draw() implementations
|
// Sets the flag as early as possible to allow draw() implementations
|
||||||
// to call invalidate() successfully when doing animations
|
// to call invalidate() successfully when doing animations
|
||||||
child.mPrivateFlags = (child.mPrivateFlags & ~DIRTY_MASK) | DRAWN;
|
child.mPrivateFlags |= DRAWN;
|
||||||
|
|
||||||
if (!concatMatrix && canvas.quickReject(cl, ct, cr, cb, Canvas.EdgeType.BW) &&
|
if (!concatMatrix && canvas.quickReject(cl, ct, cr, cb, Canvas.EdgeType.BW) &&
|
||||||
(child.mPrivateFlags & DRAW_ANIMATION) == 0) {
|
(child.mPrivateFlags & DRAW_ANIMATION) == 0) {
|
||||||
@@ -1482,6 +1482,7 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
|
|||||||
if (ViewDebug.TRACE_HIERARCHY) {
|
if (ViewDebug.TRACE_HIERARCHY) {
|
||||||
ViewDebug.trace(this, ViewDebug.HierarchyTraceType.DRAW);
|
ViewDebug.trace(this, ViewDebug.HierarchyTraceType.DRAW);
|
||||||
}
|
}
|
||||||
|
child.mPrivateFlags &= ~DIRTY_MASK;
|
||||||
child.dispatchDraw(canvas);
|
child.dispatchDraw(canvas);
|
||||||
} else {
|
} else {
|
||||||
child.draw(canvas);
|
child.draw(canvas);
|
||||||
|
|||||||
@@ -537,7 +537,6 @@ public final class ViewRoot extends Handler implements ViewParent,
|
|||||||
}
|
}
|
||||||
dirty = mTempRect;
|
dirty = mTempRect;
|
||||||
}
|
}
|
||||||
// TODO: When doing a union with mDirty != empty, we must cancel all the DIRTY_OPAQUE flags
|
|
||||||
mDirty.union(dirty);
|
mDirty.union(dirty);
|
||||||
if (!mWillDrawSoon) {
|
if (!mWillDrawSoon) {
|
||||||
scheduleTraversals();
|
scheduleTraversals();
|
||||||
@@ -1142,8 +1141,7 @@ public final class ViewRoot extends Handler implements ViewParent,
|
|||||||
}
|
}
|
||||||
|
|
||||||
int yoff;
|
int yoff;
|
||||||
final boolean scrolling = mScroller != null
|
final boolean scrolling = mScroller != null && mScroller.computeScrollOffset();
|
||||||
&& mScroller.computeScrollOffset();
|
|
||||||
if (scrolling) {
|
if (scrolling) {
|
||||||
yoff = mScroller.getCurrY();
|
yoff = mScroller.getCurrY();
|
||||||
} else {
|
} else {
|
||||||
@@ -1165,6 +1163,7 @@ public final class ViewRoot extends Handler implements ViewParent,
|
|||||||
mGL.glEnable(GL_SCISSOR_TEST);
|
mGL.glEnable(GL_SCISSOR_TEST);
|
||||||
|
|
||||||
mAttachInfo.mDrawingTime = SystemClock.uptimeMillis();
|
mAttachInfo.mDrawingTime = SystemClock.uptimeMillis();
|
||||||
|
mAttachInfo.mIgnoreDirtyState = true;
|
||||||
mView.mPrivateFlags |= View.DRAWN;
|
mView.mPrivateFlags |= View.DRAWN;
|
||||||
|
|
||||||
float scale = mAppScale;
|
float scale = mAppScale;
|
||||||
@@ -1182,6 +1181,8 @@ public final class ViewRoot extends Handler implements ViewParent,
|
|||||||
canvas.restoreToCount(saveCount);
|
canvas.restoreToCount(saveCount);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mAttachInfo.mIgnoreDirtyState = false;
|
||||||
|
|
||||||
mEgl.eglSwapBuffers(mEglDisplay, mEglSurface);
|
mEgl.eglSwapBuffers(mEglDisplay, mEglSurface);
|
||||||
checkEglErrors();
|
checkEglErrors();
|
||||||
|
|
||||||
@@ -1201,8 +1202,10 @@ public final class ViewRoot extends Handler implements ViewParent,
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fullRedrawNeeded)
|
if (fullRedrawNeeded) {
|
||||||
|
mAttachInfo.mIgnoreDirtyState = true;
|
||||||
dirty.union(0, 0, (int) (mWidth * mAppScale), (int) (mHeight * mAppScale));
|
dirty.union(0, 0, (int) (mWidth * mAppScale), (int) (mHeight * mAppScale));
|
||||||
|
}
|
||||||
|
|
||||||
if (DEBUG_ORIENTATION || DEBUG_DRAW) {
|
if (DEBUG_ORIENTATION || DEBUG_DRAW) {
|
||||||
Log.v("ViewRoot", "Draw " + mView + "/"
|
Log.v("ViewRoot", "Draw " + mView + "/"
|
||||||
@@ -1214,7 +1217,18 @@ public final class ViewRoot extends Handler implements ViewParent,
|
|||||||
|
|
||||||
Canvas canvas;
|
Canvas canvas;
|
||||||
try {
|
try {
|
||||||
|
int left = dirty.left;
|
||||||
|
int top = dirty.top;
|
||||||
|
int right = dirty.right;
|
||||||
|
int bottom = dirty.bottom;
|
||||||
|
|
||||||
canvas = surface.lockCanvas(dirty);
|
canvas = surface.lockCanvas(dirty);
|
||||||
|
|
||||||
|
if (left != dirty.left || top != dirty.top || right != dirty.right ||
|
||||||
|
bottom != dirty.bottom) {
|
||||||
|
mAttachInfo.mIgnoreDirtyState = true;
|
||||||
|
}
|
||||||
|
|
||||||
// TODO: Do this in native
|
// TODO: Do this in native
|
||||||
canvas.setDensityScale(mDensity);
|
canvas.setDensityScale(mDensity);
|
||||||
} catch (Surface.OutOfResourcesException e) {
|
} catch (Surface.OutOfResourcesException e) {
|
||||||
@@ -1242,12 +1256,11 @@ public final class ViewRoot extends Handler implements ViewParent,
|
|||||||
// need to clear it before drawing so that the child will
|
// need to clear it before drawing so that the child will
|
||||||
// properly re-composite its drawing on a transparent
|
// properly re-composite its drawing on a transparent
|
||||||
// background. This automatically respects the clip/dirty region
|
// background. This automatically respects the clip/dirty region
|
||||||
if (!canvas.isOpaque()) {
|
// or
|
||||||
canvas.drawColor(0x00000000, PorterDuff.Mode.CLEAR);
|
|
||||||
} else if (yoff != 0) {
|
|
||||||
// If we are applying an offset, we need to clear the area
|
// If we are applying an offset, we need to clear the area
|
||||||
// where the offset doesn't appear to avoid having garbage
|
// where the offset doesn't appear to avoid having garbage
|
||||||
// left in the blank areas.
|
// left in the blank areas.
|
||||||
|
if (!canvas.isOpaque() || yoff != 0) {
|
||||||
canvas.drawColor(0, PorterDuff.Mode.CLEAR);
|
canvas.drawColor(0, PorterDuff.Mode.CLEAR);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1257,9 +1270,10 @@ public final class ViewRoot extends Handler implements ViewParent,
|
|||||||
mView.mPrivateFlags |= View.DRAWN;
|
mView.mPrivateFlags |= View.DRAWN;
|
||||||
|
|
||||||
float scale = mAppScale;
|
float scale = mAppScale;
|
||||||
Context cxt = mView.getContext();
|
|
||||||
if (DEBUG_DRAW) {
|
if (DEBUG_DRAW) {
|
||||||
Log.i(TAG, "Drawing: package:" + cxt.getPackageName() + ", appScale=" + mAppScale);
|
Context cxt = mView.getContext();
|
||||||
|
Log.i(TAG, "Drawing: package:" + cxt.getPackageName() +
|
||||||
|
", appScale=" + mAppScale);
|
||||||
}
|
}
|
||||||
int saveCount = canvas.save(Canvas.MATRIX_SAVE_FLAG);
|
int saveCount = canvas.save(Canvas.MATRIX_SAVE_FLAG);
|
||||||
try {
|
try {
|
||||||
@@ -1269,13 +1283,14 @@ public final class ViewRoot extends Handler implements ViewParent,
|
|||||||
canvas.scale(scale, scale);
|
canvas.scale(scale, scale);
|
||||||
}
|
}
|
||||||
mView.draw(canvas);
|
mView.draw(canvas);
|
||||||
|
} finally {
|
||||||
|
mAttachInfo.mIgnoreDirtyState = false;
|
||||||
|
canvas.restoreToCount(saveCount);
|
||||||
|
}
|
||||||
|
|
||||||
if (Config.DEBUG && ViewDebug.consistencyCheckEnabled) {
|
if (Config.DEBUG && ViewDebug.consistencyCheckEnabled) {
|
||||||
mView.dispatchConsistencyCheck(ViewDebug.CONSISTENCY_DRAWING);
|
mView.dispatchConsistencyCheck(ViewDebug.CONSISTENCY_DRAWING);
|
||||||
}
|
}
|
||||||
} finally {
|
|
||||||
canvas.restoreToCount(saveCount);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Config.DEBUG && ViewDebug.showFps) {
|
if (Config.DEBUG && ViewDebug.showFps) {
|
||||||
int now = (int)SystemClock.elapsedRealtime();
|
int now = (int)SystemClock.elapsedRealtime();
|
||||||
|
|||||||
Reference in New Issue
Block a user