Merge "Optimization of alpha with DisplayList properties"
This commit is contained in:
@@ -148,6 +148,15 @@ public abstract class DisplayList {
|
||||
*/
|
||||
public abstract void setAlpha(float alpha);
|
||||
|
||||
/**
|
||||
* Sets whether the DisplayList renders content which overlaps. Non-overlapping rendering
|
||||
* can use a fast path for alpha that avoids rendering to an offscreen buffer.
|
||||
*
|
||||
* @param hasOverlappingRendering
|
||||
* @see android.view.View#hasOverlappingRendering()
|
||||
*/
|
||||
public abstract void setHasOverlappingRendering(boolean hasOverlappingRendering);
|
||||
|
||||
/**
|
||||
* Sets the translationX value for the DisplayList
|
||||
*
|
||||
|
||||
@@ -146,6 +146,15 @@ class GLES20DisplayList extends DisplayList {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setHasOverlappingRendering(boolean hasOverlappingRendering) {
|
||||
try {
|
||||
nSetHasOverlappingRendering(getNativeDisplayList(), hasOverlappingRendering);
|
||||
} catch (IllegalStateException e) {
|
||||
// invalid DisplayList okay: we'll set current values the next time we render to it
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setTranslationX(float translationX) {
|
||||
try {
|
||||
@@ -335,6 +344,8 @@ class GLES20DisplayList extends DisplayList {
|
||||
private static native void nSetClipChildren(int displayList, boolean clipChildren);
|
||||
private static native void nSetApplicationScale(int displayList, float scale);
|
||||
private static native void nSetAlpha(int displayList, float alpha);
|
||||
private static native void nSetHasOverlappingRendering(int displayList,
|
||||
boolean hasOverlappingRendering);
|
||||
private static native void nSetTranslationX(int displayList, float translationX);
|
||||
private static native void nSetTranslationY(int displayList, float translationY);
|
||||
private static native void nSetRotation(int displayList, float rotation);
|
||||
|
||||
@@ -134,7 +134,7 @@ public abstract class HardwareRenderer {
|
||||
/**
|
||||
* Number of frames to profile.
|
||||
*/
|
||||
private static final int PROFILE_MAX_FRAMES = 64;
|
||||
private static final int PROFILE_MAX_FRAMES = 120;
|
||||
|
||||
/**
|
||||
* Number of floats per profiled frame.
|
||||
@@ -1046,10 +1046,6 @@ public abstract class HardwareRenderer {
|
||||
Log.d(ViewDebug.DEBUG_LATENCY_TAG, "- getDisplayList() took " +
|
||||
total + "ms");
|
||||
}
|
||||
if (View.USE_DISPLAY_LIST_PROPERTIES) {
|
||||
Log.d("DLProperties", "getDisplayList():\t" +
|
||||
mProfileData[mProfileCurrentFrame]);
|
||||
}
|
||||
}
|
||||
|
||||
if (displayList != null) {
|
||||
|
||||
@@ -2829,19 +2829,6 @@ public class View implements Drawable.Callback, Drawable.Callback2, KeyEvent.Cal
|
||||
*/
|
||||
private boolean mSendingHoverAccessibilityEvents;
|
||||
|
||||
/**
|
||||
* Delegate for injecting accessiblity functionality.
|
||||
*/
|
||||
AccessibilityDelegate mAccessibilityDelegate;
|
||||
|
||||
/**
|
||||
* Consistency verifier for debugging purposes.
|
||||
* @hide
|
||||
*/
|
||||
protected final InputEventConsistencyVerifier mInputEventConsistencyVerifier =
|
||||
InputEventConsistencyVerifier.isInstrumentationEnabled() ?
|
||||
new InputEventConsistencyVerifier(this, 0) : null;
|
||||
|
||||
/**
|
||||
* Simple constructor to use when creating a view from code.
|
||||
*
|
||||
@@ -2862,6 +2849,19 @@ public class View implements Drawable.Callback, Drawable.Callback2, KeyEvent.Cal
|
||||
mUserPaddingRelative = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Delegate for injecting accessiblity functionality.
|
||||
*/
|
||||
AccessibilityDelegate mAccessibilityDelegate;
|
||||
|
||||
/**
|
||||
* Consistency verifier for debugging purposes.
|
||||
* @hide
|
||||
*/
|
||||
protected final InputEventConsistencyVerifier mInputEventConsistencyVerifier =
|
||||
InputEventConsistencyVerifier.isInstrumentationEnabled() ?
|
||||
new InputEventConsistencyVerifier(this, 0) : null;
|
||||
|
||||
/**
|
||||
* Constructor that is called when inflating a view from XML. This is called
|
||||
* when a view is being constructed from an XML file, supplying attributes
|
||||
@@ -7854,6 +7854,23 @@ public class View implements Drawable.Callback, Drawable.Callback2, KeyEvent.Cal
|
||||
return mTransformationInfo != null ? mTransformationInfo.mAlpha : 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether this View has content which overlaps. This function, intended to be
|
||||
* overridden by specific View types, is an optimization when alpha is set on a view. If
|
||||
* rendering overlaps in a view with alpha < 1, that view is drawn to an offscreen buffer
|
||||
* and then composited it into place, which can be expensive. If the view has no overlapping
|
||||
* rendering, the view can draw each primitive with the appropriate alpha value directly.
|
||||
* An example of overlapping rendering is a TextView with a background image, such as a
|
||||
* Button. An example of non-overlapping rendering is a TextView with no background, or
|
||||
* an ImageView with only the foreground image. The default implementation returns true;
|
||||
* subclasses should override if they have cases which can be optimized.
|
||||
*
|
||||
* @return true if the content in this view might overlap, false otherwise.
|
||||
*/
|
||||
public boolean hasOverlappingRendering() {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Sets the opacity of the view. This is a value from 0 to 1, where 0 means the view is
|
||||
* completely transparent and 1 means the view is completely opaque.</p>
|
||||
@@ -11534,6 +11551,7 @@ public class View implements Drawable.Callback, Drawable.Callback2, KeyEvent.Cal
|
||||
void setDisplayListProperties(DisplayList displayList) {
|
||||
if (USE_DISPLAY_LIST_PROPERTIES && displayList != null) {
|
||||
displayList.setLeftTopRightBottom(mLeft, mTop, mRight, mBottom);
|
||||
displayList.setHasOverlappingRendering(hasOverlappingRendering());
|
||||
if (mParent instanceof ViewGroup) {
|
||||
displayList.setClipChildren(
|
||||
(((ViewGroup)mParent).mGroupFlags & ViewGroup.FLAG_CLIP_CHILDREN) != 0);
|
||||
|
||||
@@ -834,40 +834,49 @@ public class ViewPropertyAnimator {
|
||||
*/
|
||||
private void setValue(int propertyConstant, float value) {
|
||||
final View.TransformationInfo info = mView.mTransformationInfo;
|
||||
DisplayList displayList = View.USE_DISPLAY_LIST_PROPERTIES ? mView.mDisplayList : null;
|
||||
switch (propertyConstant) {
|
||||
case TRANSLATION_X:
|
||||
info.mTranslationX = value;
|
||||
if (displayList != null) displayList.setTranslationX(value);
|
||||
break;
|
||||
case TRANSLATION_Y:
|
||||
info.mTranslationY = value;
|
||||
if (displayList != null) displayList.setTranslationY(value);
|
||||
break;
|
||||
case ROTATION:
|
||||
info.mRotation = value;
|
||||
if (displayList != null) displayList.setRotation(value);
|
||||
break;
|
||||
case ROTATION_X:
|
||||
info.mRotationX = value;
|
||||
if (displayList != null) displayList.setRotationX(value);
|
||||
break;
|
||||
case ROTATION_Y:
|
||||
info.mRotationY = value;
|
||||
if (displayList != null) displayList.setRotationY(value);
|
||||
break;
|
||||
case SCALE_X:
|
||||
info.mScaleX = value;
|
||||
if (displayList != null) displayList.setScaleX(value);
|
||||
break;
|
||||
case SCALE_Y:
|
||||
info.mScaleY = value;
|
||||
if (displayList != null) displayList.setScaleY(value);
|
||||
break;
|
||||
case X:
|
||||
info.mTranslationX = value - mView.mLeft;
|
||||
if (displayList != null) displayList.setTranslationX(value - mView.mLeft);
|
||||
break;
|
||||
case Y:
|
||||
info.mTranslationY = value - mView.mTop;
|
||||
if (displayList != null) displayList.setTranslationY(value - mView.mTop);
|
||||
break;
|
||||
case ALPHA:
|
||||
info.mAlpha = value;
|
||||
if (displayList != null) displayList.setAlpha(value);
|
||||
break;
|
||||
}
|
||||
// TODO: optimize to set only the properties that have changed
|
||||
mView.setDisplayListProperties();
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -201,7 +201,7 @@ public class ImageView extends View {
|
||||
|
||||
@Override
|
||||
protected boolean onSetAlpha(int alpha) {
|
||||
if (getBackground() == null) {
|
||||
if (!USE_DISPLAY_LIST_PROPERTIES && getBackground() == null) {
|
||||
int scale = alpha + (alpha >> 7);
|
||||
if (mViewAlphaScale != scale) {
|
||||
mViewAlphaScale = scale;
|
||||
@@ -213,6 +213,15 @@ public class ImageView extends View {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasOverlappingRendering() {
|
||||
if (!USE_DISPLAY_LIST_PROPERTIES) {
|
||||
return super.hasOverlappingRendering();
|
||||
} else {
|
||||
return (getBackground() != null);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPopulateAccessibilityEvent(AccessibilityEvent event) {
|
||||
super.onPopulateAccessibilityEvent(event);
|
||||
|
||||
@@ -4268,7 +4268,8 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
|
||||
protected boolean onSetAlpha(int alpha) {
|
||||
// Alpha is supported if and only if the drawing can be done in one pass.
|
||||
// TODO text with spans with a background color currently do not respect this alpha.
|
||||
if (getBackground() == null) {
|
||||
if (!USE_DISPLAY_LIST_PROPERTIES &&
|
||||
(getBackground() != null || mText instanceof Spannable || hasSelection())) {
|
||||
if (mCurrentAlpha != alpha) {
|
||||
mCurrentAlpha = alpha;
|
||||
final Drawables dr = mDrawables;
|
||||
@@ -4292,6 +4293,15 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasOverlappingRendering() {
|
||||
if (!USE_DISPLAY_LIST_PROPERTIES) {
|
||||
return super.hasOverlappingRendering();
|
||||
} else {
|
||||
return (getBackground() != null || mText instanceof Spannable || hasSelection());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* When a TextView is used to display a useful piece of information to the user (such as a
|
||||
* contact's address), it should be made selectable, so that the user can select and copy this
|
||||
|
||||
Reference in New Issue
Block a user