Merge "Rework Outline API, remove isolatedZVolume remnants"
This commit is contained in:
@ -9798,6 +9798,13 @@ package android.graphics {
|
|||||||
method public void setPaint(android.graphics.Paint);
|
method public void setPaint(android.graphics.Paint);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public class Outline {
|
||||||
|
ctor public Outline();
|
||||||
|
method public final boolean isValid();
|
||||||
|
method public void set(android.graphics.Outline);
|
||||||
|
method public void setRoundRect(int, int, int, int, float);
|
||||||
|
}
|
||||||
|
|
||||||
public class Paint {
|
public class Paint {
|
||||||
ctor public Paint();
|
ctor public Paint();
|
||||||
ctor public Paint(int);
|
ctor public Paint(int);
|
||||||
@ -10507,6 +10514,7 @@ package android.graphics.drawable {
|
|||||||
method public int getMinimumHeight();
|
method public int getMinimumHeight();
|
||||||
method public int getMinimumWidth();
|
method public int getMinimumWidth();
|
||||||
method public abstract int getOpacity();
|
method public abstract int getOpacity();
|
||||||
|
method public android.graphics.Outline getOutline();
|
||||||
method public boolean getPadding(android.graphics.Rect);
|
method public boolean getPadding(android.graphics.Rect);
|
||||||
method public int[] getState();
|
method public int[] getState();
|
||||||
method public android.graphics.Region getTransparentRegion();
|
method public android.graphics.Region getTransparentRegion();
|
||||||
@ -29151,7 +29159,6 @@ package android.view {
|
|||||||
method public int getNextFocusRightId();
|
method public int getNextFocusRightId();
|
||||||
method public int getNextFocusUpId();
|
method public int getNextFocusUpId();
|
||||||
method public android.view.View.OnFocusChangeListener getOnFocusChangeListener();
|
method public android.view.View.OnFocusChangeListener getOnFocusChangeListener();
|
||||||
method public final void getOutline(android.graphics.Path);
|
|
||||||
method public int getOverScrollMode();
|
method public int getOverScrollMode();
|
||||||
method public android.view.ViewOverlay getOverlay();
|
method public android.view.ViewOverlay getOverlay();
|
||||||
method public int getPaddingBottom();
|
method public int getPaddingBottom();
|
||||||
@ -29415,7 +29422,7 @@ package android.view {
|
|||||||
method public void setOnLongClickListener(android.view.View.OnLongClickListener);
|
method public void setOnLongClickListener(android.view.View.OnLongClickListener);
|
||||||
method public void setOnSystemUiVisibilityChangeListener(android.view.View.OnSystemUiVisibilityChangeListener);
|
method public void setOnSystemUiVisibilityChangeListener(android.view.View.OnSystemUiVisibilityChangeListener);
|
||||||
method public void setOnTouchListener(android.view.View.OnTouchListener);
|
method public void setOnTouchListener(android.view.View.OnTouchListener);
|
||||||
method public void setOutline(android.graphics.Path);
|
method public void setOutline(android.graphics.Outline);
|
||||||
method public void setOverScrollMode(int);
|
method public void setOverScrollMode(int);
|
||||||
method public void setPadding(int, int, int, int);
|
method public void setPadding(int, int, int, int);
|
||||||
method public void setPaddingRelative(int, int, int, int);
|
method public void setPaddingRelative(int, int, int, int);
|
||||||
|
@ -17,7 +17,7 @@
|
|||||||
package android.view;
|
package android.view;
|
||||||
|
|
||||||
import android.graphics.Matrix;
|
import android.graphics.Matrix;
|
||||||
import android.graphics.Path;
|
import android.graphics.Outline;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* <p>A display list records a series of graphics related operations and can replay
|
* <p>A display list records a series of graphics related operations and can replay
|
||||||
@ -310,16 +310,6 @@ public class RenderNode {
|
|||||||
nSetClipToBounds(mNativeDisplayList, clipToBounds);
|
nSetClipToBounds(mNativeDisplayList, clipToBounds);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Set whether the display list should collect and Z order all 3d composited descendents, and
|
|
||||||
* draw them in order with the default Z=0 content.
|
|
||||||
*
|
|
||||||
* @param isolatedZVolume true if the display list should collect and Z order descendents.
|
|
||||||
*/
|
|
||||||
public void setIsolatedZVolume(boolean isolatedZVolume) {
|
|
||||||
nSetIsolatedZVolume(mNativeDisplayList, isolatedZVolume);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets whether the display list should be drawn immediately after the
|
* Sets whether the display list should be drawn immediately after the
|
||||||
* closest ancestor display list where isolateZVolume is true. If the
|
* closest ancestor display list where isolateZVolume is true. If the
|
||||||
@ -346,13 +336,19 @@ public class RenderNode {
|
|||||||
* Sets the outline, defining the shape that casts a shadow, and the path to
|
* Sets the outline, defining the shape that casts a shadow, and the path to
|
||||||
* be clipped if setClipToOutline is set.
|
* be clipped if setClipToOutline is set.
|
||||||
*
|
*
|
||||||
* Deep copies the native path to simplify reference ownership.
|
* Deep copies the data into native to simplify reference ownership.
|
||||||
*
|
|
||||||
* @param outline Convex, CW Path to store in the DisplayList. May be null.
|
|
||||||
*/
|
*/
|
||||||
public void setOutline(Path outline) {
|
public void setOutline(Outline outline) {
|
||||||
long nativePath = (outline == null) ? 0 : outline.mNativePath;
|
if (outline == null) {
|
||||||
nSetOutline(mNativeDisplayList, nativePath);
|
nSetOutlineEmpty(mNativeDisplayList);
|
||||||
|
} else if (!outline.isValid()) {
|
||||||
|
throw new IllegalArgumentException("Outline must be valid");
|
||||||
|
} else if (outline.mRect != null) {
|
||||||
|
nSetOutlineRoundRect(mNativeDisplayList, outline.mRect.left, outline.mRect.top,
|
||||||
|
outline.mRect.right, outline.mRect.bottom, outline.mRadius);
|
||||||
|
} else if (outline.mPath != null) {
|
||||||
|
nSetOutlineConvexPath(mNativeDisplayList, outline.mPath.mNativePath);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -855,8 +851,10 @@ public class RenderNode {
|
|||||||
private static native void nSetClipToBounds(long displayList, boolean clipToBounds);
|
private static native void nSetClipToBounds(long displayList, boolean clipToBounds);
|
||||||
private static native void nSetProjectBackwards(long displayList, boolean shouldProject);
|
private static native void nSetProjectBackwards(long displayList, boolean shouldProject);
|
||||||
private static native void nSetProjectionReceiver(long displayList, boolean shouldRecieve);
|
private static native void nSetProjectionReceiver(long displayList, boolean shouldRecieve);
|
||||||
private static native void nSetIsolatedZVolume(long displayList, boolean isolateZVolume);
|
private static native void nSetOutlineRoundRect(long displayList, int left, int top,
|
||||||
private static native void nSetOutline(long displayList, long nativePath);
|
int right, int bottom, float radius);
|
||||||
|
private static native void nSetOutlineConvexPath(long displayList, long nativePath);
|
||||||
|
private static native void nSetOutlineEmpty(long displayList);
|
||||||
private static native void nSetClipToOutline(long displayList, boolean clipToOutline);
|
private static native void nSetClipToOutline(long displayList, boolean clipToOutline);
|
||||||
private static native void nSetAlpha(long displayList, float alpha);
|
private static native void nSetAlpha(long displayList, float alpha);
|
||||||
private static native void nSetHasOverlappingRendering(long displayList,
|
private static native void nSetHasOverlappingRendering(long displayList,
|
||||||
|
@ -31,6 +31,7 @@ import android.graphics.Insets;
|
|||||||
import android.graphics.Interpolator;
|
import android.graphics.Interpolator;
|
||||||
import android.graphics.LinearGradient;
|
import android.graphics.LinearGradient;
|
||||||
import android.graphics.Matrix;
|
import android.graphics.Matrix;
|
||||||
|
import android.graphics.Outline;
|
||||||
import android.graphics.Paint;
|
import android.graphics.Paint;
|
||||||
import android.graphics.Path;
|
import android.graphics.Path;
|
||||||
import android.graphics.PixelFormat;
|
import android.graphics.PixelFormat;
|
||||||
@ -2376,15 +2377,20 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
|
|||||||
*/
|
*/
|
||||||
static final int PFLAG3_CLIP_TO_OUTLINE = 0x20;
|
static final int PFLAG3_CLIP_TO_OUTLINE = 0x20;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Flag indicating that a view's outline has been specifically defined.
|
||||||
|
*/
|
||||||
|
static final int PFLAG3_OUTLINE_DEFINED = 0x40;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Flag indicating that we're in the process of applying window insets.
|
* Flag indicating that we're in the process of applying window insets.
|
||||||
*/
|
*/
|
||||||
static final int PFLAG3_APPLYING_INSETS = 0x40;
|
static final int PFLAG3_APPLYING_INSETS = 0x80;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Flag indicating that we're in the process of fitting system windows using the old method.
|
* Flag indicating that we're in the process of fitting system windows using the old method.
|
||||||
*/
|
*/
|
||||||
static final int PFLAG3_FITTING_SYSTEM_WINDOWS = 0x80;
|
static final int PFLAG3_FITTING_SYSTEM_WINDOWS = 0x100;
|
||||||
|
|
||||||
/* End of masks for mPrivateFlags3 */
|
/* End of masks for mPrivateFlags3 */
|
||||||
|
|
||||||
@ -3335,8 +3341,10 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
|
|||||||
/**
|
/**
|
||||||
* Stores the outline of the view, passed down to the DisplayList level for
|
* Stores the outline of the view, passed down to the DisplayList level for
|
||||||
* defining shadow shape and clipping.
|
* defining shadow shape and clipping.
|
||||||
|
*
|
||||||
|
* TODO: once RenderNode is long-lived, remove this and rely on native copy.
|
||||||
*/
|
*/
|
||||||
private Path mOutline;
|
private Outline mOutline;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* When this view has focus and the next focus is {@link #FOCUS_LEFT},
|
* When this view has focus and the next focus is {@link #FOCUS_LEFT},
|
||||||
@ -10801,67 +10809,45 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Copies the Outline of the View into the Path parameter.
|
|
||||||
* <p>
|
|
||||||
* If the outline is not set, the parameter Path is set to empty.
|
|
||||||
*
|
|
||||||
* @param outline Path into which View's outline will be copied. Must be non-null.
|
|
||||||
*
|
|
||||||
* @see #setOutline(Path)
|
|
||||||
* @see #getClipToOutline()
|
|
||||||
* @see #setClipToOutline(boolean)
|
|
||||||
*/
|
|
||||||
public final void getOutline(@NonNull Path outline) {
|
|
||||||
if (outline == null) {
|
|
||||||
throw new IllegalArgumentException("Path must be non-null");
|
|
||||||
}
|
|
||||||
if (mOutline == null) {
|
|
||||||
outline.reset();
|
|
||||||
} else {
|
|
||||||
outline.set(mOutline);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the outline of the view, which defines the shape of the shadow it
|
* Sets the outline of the view, which defines the shape of the shadow it
|
||||||
* casts, and can used for clipping.
|
* casts, and can used for clipping.
|
||||||
* <p>
|
* <p>
|
||||||
* The outline path of a View must be {@link android.graphics.Path#isConvex() convex}.
|
* If the outline is not set or is null, shadows will be cast from the
|
||||||
* <p>
|
* bounds of the View, and clipToOutline will be ignored.
|
||||||
* If the outline is not set, or {@link Path#isEmpty()}, shadows will be
|
|
||||||
* cast from the bounds of the View, and clipToOutline will be ignored.
|
|
||||||
*
|
*
|
||||||
* @param outline The new outline of the view. Must be non-null, and convex.
|
* @param outline The new outline of the view.
|
||||||
|
* Must be {@link android.view.Outline#isValid() valid.}
|
||||||
*
|
*
|
||||||
* @see #getOutline(Path)
|
|
||||||
* @see #getClipToOutline()
|
* @see #getClipToOutline()
|
||||||
* @see #setClipToOutline(boolean)
|
* @see #setClipToOutline(boolean)
|
||||||
*/
|
*/
|
||||||
public void setOutline(@NonNull Path outline) {
|
public void setOutline(@Nullable Outline outline) {
|
||||||
|
if (outline != null && !outline.isValid()) {
|
||||||
|
throw new IllegalArgumentException("Outline must not be invalid");
|
||||||
|
}
|
||||||
|
|
||||||
|
mPrivateFlags3 |= PFLAG3_OUTLINE_DEFINED;
|
||||||
|
|
||||||
if (outline == null) {
|
if (outline == null) {
|
||||||
throw new IllegalArgumentException("Path must be non-null");
|
mOutline = null;
|
||||||
}
|
} else {
|
||||||
if (!outline.isConvex()) {
|
|
||||||
throw new IllegalArgumentException("Path must be convex");
|
|
||||||
}
|
|
||||||
// always copy the path since caller may reuse
|
// always copy the path since caller may reuse
|
||||||
if (mOutline == null) {
|
if (mOutline == null) {
|
||||||
mOutline = new Path(outline);
|
mOutline = new Outline();
|
||||||
} else {
|
}
|
||||||
mOutline.set(outline);
|
mOutline.set(outline);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mDisplayList != null) {
|
if (mDisplayList != null) {
|
||||||
mDisplayList.setOutline(outline);
|
mDisplayList.setOutline(mOutline);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns whether the outline of the View will be used for clipping.
|
* Returns whether the outline of the View will be used for clipping.
|
||||||
*
|
*
|
||||||
* @see #getOutline(Path)
|
* @see #setOutline(Outline)
|
||||||
* @see #setOutline(Path)
|
|
||||||
*/
|
*/
|
||||||
public final boolean getClipToOutline() {
|
public final boolean getClipToOutline() {
|
||||||
return ((mPrivateFlags3 & PFLAG3_CLIP_TO_OUTLINE) != 0);
|
return ((mPrivateFlags3 & PFLAG3_CLIP_TO_OUTLINE) != 0);
|
||||||
@ -10879,8 +10865,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
|
|||||||
* If the outline of the view is not set or is empty, no clipping will be
|
* If the outline of the view is not set or is empty, no clipping will be
|
||||||
* performed.
|
* performed.
|
||||||
*
|
*
|
||||||
* @see #getOutline(Path)
|
* @see #setOutline(Outline)
|
||||||
* @see #setOutline(Path)
|
|
||||||
*/
|
*/
|
||||||
public void setClipToOutline(boolean clipToOutline) {
|
public void setClipToOutline(boolean clipToOutline) {
|
||||||
// TODO : Add a fast invalidation here.
|
// TODO : Add a fast invalidation here.
|
||||||
@ -11460,7 +11445,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
|
|||||||
|
|
||||||
// Damage the entire IsolatedZVolume recieving this view's shadow.
|
// Damage the entire IsolatedZVolume recieving this view's shadow.
|
||||||
if (getTranslationZ() != 0) {
|
if (getTranslationZ() != 0) {
|
||||||
damageIsolatedZVolume();
|
damageShadowReceiver();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -11489,24 +11474,18 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Damage area of the screen covered by the current isolated Z volume
|
* Damage area of the screen that can be covered by this View's shadow.
|
||||||
*
|
*
|
||||||
* This method will guarantee that any changes to shadows cast by a View
|
* This method will guarantee that any changes to shadows cast by a View
|
||||||
* are damaged on the screen for future redraw.
|
* are damaged on the screen for future redraw.
|
||||||
*/
|
*/
|
||||||
private void damageIsolatedZVolume() {
|
private void damageShadowReceiver() {
|
||||||
final AttachInfo ai = mAttachInfo;
|
final AttachInfo ai = mAttachInfo;
|
||||||
if (ai != null) {
|
if (ai != null) {
|
||||||
ViewParent p = getParent();
|
ViewParent p = getParent();
|
||||||
while (p != null) {
|
if (p != null && p instanceof ViewGroup) {
|
||||||
if (p instanceof ViewGroup) {
|
|
||||||
final ViewGroup vg = (ViewGroup) p;
|
final ViewGroup vg = (ViewGroup) p;
|
||||||
if (vg.hasIsolatedZVolume()) {
|
|
||||||
vg.damageInParent();
|
vg.damageInParent();
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
p = p.getParent();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -11540,7 +11519,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
|
|||||||
damageInParent();
|
damageInParent();
|
||||||
}
|
}
|
||||||
if (invalidateParent && getTranslationZ() != 0) {
|
if (invalidateParent && getTranslationZ() != 0) {
|
||||||
damageIsolatedZVolume();
|
damageShadowReceiver();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -14571,10 +14550,6 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
|
|||||||
displayList.setClipToBounds(
|
displayList.setClipToBounds(
|
||||||
(((ViewGroup) mParent).mGroupFlags & ViewGroup.FLAG_CLIP_CHILDREN) != 0);
|
(((ViewGroup) mParent).mGroupFlags & ViewGroup.FLAG_CLIP_CHILDREN) != 0);
|
||||||
}
|
}
|
||||||
if (this instanceof ViewGroup) {
|
|
||||||
displayList.setIsolatedZVolume(
|
|
||||||
(((ViewGroup) this).mGroupFlags & ViewGroup.FLAG_ISOLATED_Z_VOLUME) != 0);
|
|
||||||
}
|
|
||||||
displayList.setOutline(mOutline);
|
displayList.setOutline(mOutline);
|
||||||
displayList.setClipToOutline(getClipToOutline());
|
displayList.setClipToOutline(getClipToOutline());
|
||||||
float alpha = 1;
|
float alpha = 1;
|
||||||
@ -15178,6 +15153,13 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
|
|||||||
if (mBackgroundSizeChanged) {
|
if (mBackgroundSizeChanged) {
|
||||||
background.setBounds(0, 0, mRight - mLeft, mBottom - mTop);
|
background.setBounds(0, 0, mRight - mLeft, mBottom - mTop);
|
||||||
mBackgroundSizeChanged = false;
|
mBackgroundSizeChanged = false;
|
||||||
|
if ((mPrivateFlags3 & PFLAG3_OUTLINE_DEFINED) == 0) {
|
||||||
|
// Outline not currently define, query from background
|
||||||
|
mOutline = background.getOutline();
|
||||||
|
if (mDisplayList != null) {
|
||||||
|
mDisplayList.setOutline(mOutline);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Attempt to use a display list if requested.
|
// Attempt to use a display list if requested.
|
||||||
|
@ -357,15 +357,9 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
|
|||||||
*/
|
*/
|
||||||
private static final int FLAG_LAYOUT_MODE_WAS_EXPLICITLY_SET = 0x800000;
|
private static final int FLAG_LAYOUT_MODE_WAS_EXPLICITLY_SET = 0x800000;
|
||||||
|
|
||||||
/**
|
static final int FLAG_IS_TRANSITION_GROUP = 0x1000000;
|
||||||
* When true, indicates that all 3d composited descendents are contained within this group, and
|
|
||||||
* will not be interleaved with other 3d composited content.
|
|
||||||
*/
|
|
||||||
static final int FLAG_ISOLATED_Z_VOLUME = 0x1000000;
|
|
||||||
|
|
||||||
static final int FLAG_IS_TRANSITION_GROUP = 0x2000000;
|
static final int FLAG_IS_TRANSITION_GROUP_SET = 0x2000000;
|
||||||
|
|
||||||
static final int FLAG_IS_TRANSITION_GROUP_SET = 0x4000000;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Indicates which types of drawing caches are to be kept in memory.
|
* Indicates which types of drawing caches are to be kept in memory.
|
||||||
@ -499,7 +493,6 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
|
|||||||
mGroupFlags |= FLAG_ANIMATION_DONE;
|
mGroupFlags |= FLAG_ANIMATION_DONE;
|
||||||
mGroupFlags |= FLAG_ANIMATION_CACHE;
|
mGroupFlags |= FLAG_ANIMATION_CACHE;
|
||||||
mGroupFlags |= FLAG_ALWAYS_DRAWN_WITH_CACHE;
|
mGroupFlags |= FLAG_ALWAYS_DRAWN_WITH_CACHE;
|
||||||
mGroupFlags |= FLAG_ISOLATED_Z_VOLUME;
|
|
||||||
|
|
||||||
if (mContext.getApplicationInfo().targetSdkVersion >= Build.VERSION_CODES.HONEYCOMB) {
|
if (mContext.getApplicationInfo().targetSdkVersion >= Build.VERSION_CODES.HONEYCOMB) {
|
||||||
mGroupFlags |= FLAG_SPLIT_MOTION_EVENTS;
|
mGroupFlags |= FLAG_SPLIT_MOTION_EVENTS;
|
||||||
@ -528,9 +521,6 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
|
|||||||
case R.styleable.ViewGroup_clipToPadding:
|
case R.styleable.ViewGroup_clipToPadding:
|
||||||
setClipToPadding(a.getBoolean(attr, true));
|
setClipToPadding(a.getBoolean(attr, true));
|
||||||
break;
|
break;
|
||||||
case R.styleable.ViewGroup_isolatedZVolume:
|
|
||||||
setIsolatedZVolume(a.getBoolean(attr, true));
|
|
||||||
break;
|
|
||||||
case R.styleable.ViewGroup_animationCache:
|
case R.styleable.ViewGroup_animationCache:
|
||||||
setAnimationCacheEnabled(a.getBoolean(attr, true));
|
setAnimationCacheEnabled(a.getBoolean(attr, true));
|
||||||
break;
|
break;
|
||||||
@ -3158,43 +3148,6 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
|
|||||||
return child.draw(canvas, this, drawingTime);
|
return child.draw(canvas, this, drawingTime);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns whether this group's descendents are drawn in their own
|
|
||||||
* independent Z volume. Views drawn in one contained volume will not
|
|
||||||
* interleave with views in another, even if their Z values are interleaved.
|
|
||||||
* The default value is true.
|
|
||||||
* @see #setIsolatedZVolume(boolean)
|
|
||||||
*
|
|
||||||
* @return True if the ViewGroup has an isolated Z volume.
|
|
||||||
*
|
|
||||||
* @hide
|
|
||||||
*/
|
|
||||||
public boolean hasIsolatedZVolume() {
|
|
||||||
return ((mGroupFlags & FLAG_ISOLATED_Z_VOLUME) != 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* By default, only direct children of a group can interleave drawing order
|
|
||||||
* by interleaving Z values. Set to false on individual groups to enable Z
|
|
||||||
* interleaving of views that aren't direct siblings.
|
|
||||||
*
|
|
||||||
* @return True if the group should be an isolated Z volume with its own Z
|
|
||||||
* ordering space, false if its decendents should inhabit the
|
|
||||||
* inherited Z ordering volume.
|
|
||||||
* @attr ref android.R.styleable#ViewGroup_isolatedZVolume
|
|
||||||
*
|
|
||||||
* @hide
|
|
||||||
*/
|
|
||||||
public void setIsolatedZVolume(boolean isolateZVolume) {
|
|
||||||
boolean previousValue = (mGroupFlags & FLAG_ISOLATED_Z_VOLUME) != 0;
|
|
||||||
if (isolateZVolume != previousValue) {
|
|
||||||
setBooleanFlag(FLAG_ISOLATED_Z_VOLUME, isolateZVolume);
|
|
||||||
if (mDisplayList != null) {
|
|
||||||
mDisplayList.setIsolatedZVolume(isolateZVolume);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns whether this group's children are clipped to their bounds before drawing.
|
* Returns whether this group's children are clipped to their bounds before drawing.
|
||||||
* The default value is true.
|
* The default value is true.
|
||||||
|
@ -69,7 +69,7 @@ static void android_view_RenderNode_destroyDisplayList(JNIEnv* env,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
// DisplayList view properties
|
// RenderProperties
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
static void android_view_RenderNode_setCaching(JNIEnv* env,
|
static void android_view_RenderNode_setCaching(JNIEnv* env,
|
||||||
@ -98,11 +98,6 @@ static void android_view_RenderNode_setClipToBounds(JNIEnv* env,
|
|||||||
displayList->properties().setClipToBounds(clipToBounds);
|
displayList->properties().setClipToBounds(clipToBounds);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void android_view_RenderNode_setIsolatedZVolume(JNIEnv* env,
|
|
||||||
jobject clazz, jlong displayListPtr, jboolean shouldIsolate) {
|
|
||||||
// No-op, TODO: Remove Java usage of this method
|
|
||||||
}
|
|
||||||
|
|
||||||
static void android_view_RenderNode_setProjectBackwards(JNIEnv* env,
|
static void android_view_RenderNode_setProjectBackwards(JNIEnv* env,
|
||||||
jobject clazz, jlong displayListPtr, jboolean shouldProject) {
|
jobject clazz, jlong displayListPtr, jboolean shouldProject) {
|
||||||
RenderNode* displayList = reinterpret_cast<RenderNode*>(displayListPtr);
|
RenderNode* displayList = reinterpret_cast<RenderNode*>(displayListPtr);
|
||||||
@ -115,17 +110,28 @@ static void android_view_RenderNode_setProjectionReceiver(JNIEnv* env,
|
|||||||
displayList->properties().setProjectionReceiver(shouldRecieve);
|
displayList->properties().setProjectionReceiver(shouldRecieve);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void android_view_RenderNode_setOutline(JNIEnv* env,
|
static void android_view_RenderNode_setOutlineRoundRect(JNIEnv* env,
|
||||||
|
jobject clazz, jlong displayListPtr, jint left, jint top,
|
||||||
|
jint right, jint bottom, jfloat radius) {
|
||||||
|
RenderNode* displayList = reinterpret_cast<RenderNode*>(displayListPtr);
|
||||||
|
displayList->properties().outline().setRoundRect(left, top, right, bottom, radius);
|
||||||
|
}
|
||||||
|
static void android_view_RenderNode_setOutlineConvexPath(JNIEnv* env,
|
||||||
jobject clazz, jlong displayListPtr, jlong outlinePathPtr) {
|
jobject clazz, jlong displayListPtr, jlong outlinePathPtr) {
|
||||||
RenderNode* displayList = reinterpret_cast<RenderNode*>(displayListPtr);
|
RenderNode* displayList = reinterpret_cast<RenderNode*>(displayListPtr);
|
||||||
SkPath* outline = reinterpret_cast<SkPath*>(outlinePathPtr);
|
SkPath* outlinePath = reinterpret_cast<SkPath*>(outlinePathPtr);
|
||||||
displayList->properties().setOutline(outline);
|
displayList->properties().outline().setConvexPath(outlinePath);
|
||||||
|
}
|
||||||
|
static void android_view_RenderNode_setOutlineEmpty(JNIEnv* env,
|
||||||
|
jobject clazz, jlong displayListPtr) {
|
||||||
|
RenderNode* displayList = reinterpret_cast<RenderNode*>(displayListPtr);
|
||||||
|
displayList->properties().outline().setEmpty();
|
||||||
}
|
}
|
||||||
|
|
||||||
static void android_view_RenderNode_setClipToOutline(JNIEnv* env,
|
static void android_view_RenderNode_setClipToOutline(JNIEnv* env,
|
||||||
jobject clazz, jlong displayListPtr, jboolean clipToOutline) {
|
jobject clazz, jlong displayListPtr, jboolean clipToOutline) {
|
||||||
RenderNode* displayList = reinterpret_cast<RenderNode*>(displayListPtr);
|
RenderNode* displayList = reinterpret_cast<RenderNode*>(displayListPtr);
|
||||||
displayList->properties().setClipToOutline(clipToOutline);
|
displayList->properties().outline().setShouldClip(clipToOutline);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void android_view_RenderNode_setAlpha(JNIEnv* env,
|
static void android_view_RenderNode_setAlpha(JNIEnv* env,
|
||||||
@ -381,11 +387,14 @@ static JNINativeMethod gMethods[] = {
|
|||||||
{ "nSetStaticMatrix", "(JJ)V", (void*) android_view_RenderNode_setStaticMatrix },
|
{ "nSetStaticMatrix", "(JJ)V", (void*) android_view_RenderNode_setStaticMatrix },
|
||||||
{ "nSetAnimationMatrix", "(JJ)V", (void*) android_view_RenderNode_setAnimationMatrix },
|
{ "nSetAnimationMatrix", "(JJ)V", (void*) android_view_RenderNode_setAnimationMatrix },
|
||||||
{ "nSetClipToBounds", "(JZ)V", (void*) android_view_RenderNode_setClipToBounds },
|
{ "nSetClipToBounds", "(JZ)V", (void*) android_view_RenderNode_setClipToBounds },
|
||||||
{ "nSetIsolatedZVolume", "(JZ)V", (void*) android_view_RenderNode_setIsolatedZVolume },
|
|
||||||
{ "nSetProjectBackwards", "(JZ)V", (void*) android_view_RenderNode_setProjectBackwards },
|
{ "nSetProjectBackwards", "(JZ)V", (void*) android_view_RenderNode_setProjectBackwards },
|
||||||
{ "nSetProjectionReceiver","(JZ)V", (void*) android_view_RenderNode_setProjectionReceiver },
|
{ "nSetProjectionReceiver","(JZ)V", (void*) android_view_RenderNode_setProjectionReceiver },
|
||||||
{ "nSetOutline", "(JJ)V", (void*) android_view_RenderNode_setOutline },
|
|
||||||
|
{ "nSetOutlineRoundRect", "(JIIIIF)V", (void*) android_view_RenderNode_setOutlineRoundRect },
|
||||||
|
{ "nSetOutlineConvexPath", "(JJ)V", (void*) android_view_RenderNode_setOutlineConvexPath },
|
||||||
|
{ "nSetOutlineEmpty", "(J)V", (void*) android_view_RenderNode_setOutlineEmpty },
|
||||||
{ "nSetClipToOutline", "(JZ)V", (void*) android_view_RenderNode_setClipToOutline },
|
{ "nSetClipToOutline", "(JZ)V", (void*) android_view_RenderNode_setClipToOutline },
|
||||||
|
|
||||||
{ "nSetAlpha", "(JF)V", (void*) android_view_RenderNode_setAlpha },
|
{ "nSetAlpha", "(JF)V", (void*) android_view_RenderNode_setAlpha },
|
||||||
{ "nSetHasOverlappingRendering", "(JZ)V",
|
{ "nSetHasOverlappingRendering", "(JZ)V",
|
||||||
(void*) android_view_RenderNode_setHasOverlappingRendering },
|
(void*) android_view_RenderNode_setHasOverlappingRendering },
|
||||||
|
@ -2292,9 +2292,6 @@
|
|||||||
<!-- Defines whether the ViewGroup will clip its drawing surface so as to exclude
|
<!-- Defines whether the ViewGroup will clip its drawing surface so as to exclude
|
||||||
the padding area. This property is set to true by default. -->
|
the padding area. This property is set to true by default. -->
|
||||||
<attr name="clipToPadding" format="boolean" />
|
<attr name="clipToPadding" format="boolean" />
|
||||||
<!-- Defines whether 3d composited descendents of the ViewGroup will be reordered into their
|
|
||||||
own independent Z volume. This property is set to true by default. -->
|
|
||||||
<attr name="isolatedZVolume" format="boolean" />
|
|
||||||
<!-- Defines the layout animation to use the first time the ViewGroup is laid out.
|
<!-- Defines the layout animation to use the first time the ViewGroup is laid out.
|
||||||
Layout animations can also be started manually after the first layout. -->
|
Layout animations can also be started manually after the first layout. -->
|
||||||
<attr name="layoutAnimation" format="reference" />
|
<attr name="layoutAnimation" format="reference" />
|
||||||
|
108
graphics/java/android/graphics/Outline.java
Normal file
108
graphics/java/android/graphics/Outline.java
Normal file
@ -0,0 +1,108 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2014 The Android Open Source Project
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package android.graphics;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Defines an area of content.
|
||||||
|
*
|
||||||
|
* Can be used with a View or Drawable to drive the shape of shadows cast by a
|
||||||
|
* View, and allowing Views to clip inner content.
|
||||||
|
*
|
||||||
|
* @see View#setOutline(Outline)
|
||||||
|
* @see View#setClipToOutline(boolean)
|
||||||
|
*/
|
||||||
|
public class Outline {
|
||||||
|
/** @hide */
|
||||||
|
public Rect mRect;
|
||||||
|
|
||||||
|
/** @hide */
|
||||||
|
public float mRadius;
|
||||||
|
|
||||||
|
/** @hide */
|
||||||
|
public Path mPath;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructs an invalid Outline. Call one of the setter methods to make
|
||||||
|
* the outline valid for use with a View.
|
||||||
|
*/
|
||||||
|
public Outline() {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns whether the Outline is valid for use with a View.
|
||||||
|
* <p>
|
||||||
|
* Outlines are invalid when constructed until a setter method is called.
|
||||||
|
*/
|
||||||
|
public final boolean isValid() {
|
||||||
|
return mRect != null || mPath != null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @hide
|
||||||
|
*/
|
||||||
|
public final boolean canClip() {
|
||||||
|
return mPath == null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Replace the contents of this Outline with the contents of src.
|
||||||
|
*/
|
||||||
|
public void set(Outline src) {
|
||||||
|
if (src.mPath != null) {
|
||||||
|
if (mPath == null) {
|
||||||
|
mPath = new Path();
|
||||||
|
}
|
||||||
|
mPath.set(src.mPath);
|
||||||
|
mRect = null;
|
||||||
|
}
|
||||||
|
if (src.mRect != null) {
|
||||||
|
if (mRect == null) {
|
||||||
|
mRect = new Rect();
|
||||||
|
}
|
||||||
|
mRect.set(src.mRect);
|
||||||
|
}
|
||||||
|
mRadius = src.mRadius;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the Outline to the rounded rect defined by the input rect, and corner radius.
|
||||||
|
* <p>
|
||||||
|
* Outlines produced by this method support
|
||||||
|
* {@link View#setClipToOutline(boolean) View clipping.}
|
||||||
|
*/
|
||||||
|
public void setRoundRect(int left, int top, int right, int bottom, float radius) {
|
||||||
|
if (mRect == null) mRect = new Rect();
|
||||||
|
mRect.set(left, top, right, bottom);
|
||||||
|
mRadius = radius;
|
||||||
|
mPath = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the Constructs an Outline from a {@link android.graphics.Path#isConvex() convex path}.
|
||||||
|
*
|
||||||
|
* @hide
|
||||||
|
*/
|
||||||
|
public void setConvexPath(Path convexPath) {
|
||||||
|
if (!convexPath.isConvex()) {
|
||||||
|
throw new IllegalArgumentException("path must be convex");
|
||||||
|
}
|
||||||
|
if (mPath == null) mPath = new Path();
|
||||||
|
|
||||||
|
mRect = null;
|
||||||
|
mRadius = -1.0f;
|
||||||
|
mPath.set(convexPath);
|
||||||
|
}
|
||||||
|
}
|
@ -30,6 +30,7 @@ import android.graphics.BitmapFactory;
|
|||||||
import android.graphics.Canvas;
|
import android.graphics.Canvas;
|
||||||
import android.graphics.ColorFilter;
|
import android.graphics.ColorFilter;
|
||||||
import android.graphics.NinePatch;
|
import android.graphics.NinePatch;
|
||||||
|
import android.graphics.Outline;
|
||||||
import android.graphics.PixelFormat;
|
import android.graphics.PixelFormat;
|
||||||
import android.graphics.PorterDuff;
|
import android.graphics.PorterDuff;
|
||||||
import android.graphics.PorterDuffColorFilter;
|
import android.graphics.PorterDuffColorFilter;
|
||||||
@ -859,6 +860,24 @@ public abstract class Drawable {
|
|||||||
return Insets.NONE;
|
return Insets.NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the outline for this drawable if defined, null if not.
|
||||||
|
* <p>
|
||||||
|
* This method will be called by a View on its background Drawable after
|
||||||
|
* bounds change, if the View's Outline isn't set explicitly. This allows
|
||||||
|
* the background Drawable to provide the shape of the shadow casting
|
||||||
|
* portion of the View. It can also serve to clip the area of the View if
|
||||||
|
* if {@link View#setClipToOutline(boolean)} is set on the View.
|
||||||
|
* <p>
|
||||||
|
* The Outline queried by the View will not be modified, and is treated as
|
||||||
|
* a static shape that only needs to be requeried when the drawable's bounds
|
||||||
|
* change.
|
||||||
|
*
|
||||||
|
* @see View#setOutline(android.view.Outline)
|
||||||
|
* @see View#setClipToOutline(boolean)
|
||||||
|
*/
|
||||||
|
public Outline getOutline() { return null; }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Make this drawable mutable. This operation cannot be reversed. A mutable
|
* Make this drawable mutable. This operation cannot be reversed. A mutable
|
||||||
* drawable is guaranteed to not share its state with any other drawable.
|
* drawable is guaranteed to not share its state with any other drawable.
|
||||||
|
@ -24,6 +24,7 @@ import android.graphics.Color;
|
|||||||
import android.graphics.ColorFilter;
|
import android.graphics.ColorFilter;
|
||||||
import android.graphics.DashPathEffect;
|
import android.graphics.DashPathEffect;
|
||||||
import android.graphics.LinearGradient;
|
import android.graphics.LinearGradient;
|
||||||
|
import android.graphics.Outline;
|
||||||
import android.graphics.Paint;
|
import android.graphics.Paint;
|
||||||
import android.graphics.Path;
|
import android.graphics.Path;
|
||||||
import android.graphics.PixelFormat;
|
import android.graphics.PixelFormat;
|
||||||
@ -133,6 +134,7 @@ public class GradientDrawable extends Drawable {
|
|||||||
|
|
||||||
private final Path mPath = new Path();
|
private final Path mPath = new Path();
|
||||||
private final RectF mRect = new RectF();
|
private final RectF mRect = new RectF();
|
||||||
|
private Outline mOutline;
|
||||||
|
|
||||||
private Paint mLayerPaint; // internal, used if we use saveLayer()
|
private Paint mLayerPaint; // internal, used if we use saveLayer()
|
||||||
private boolean mRectIsDirty; // internal state
|
private boolean mRectIsDirty; // internal state
|
||||||
@ -585,11 +587,8 @@ public class GradientDrawable extends Drawable {
|
|||||||
// to show it. If we did nothing, Skia would clamp the rad
|
// to show it. If we did nothing, Skia would clamp the rad
|
||||||
// independently along each axis, giving us a thin ellipse
|
// independently along each axis, giving us a thin ellipse
|
||||||
// if the rect were very wide but not very tall
|
// if the rect were very wide but not very tall
|
||||||
float rad = st.mRadius;
|
float rad = Math.min(st.mRadius,
|
||||||
float r = Math.min(mRect.width(), mRect.height()) * 0.5f;
|
Math.min(mRect.width(), mRect.height()) * 0.5f);
|
||||||
if (rad > r) {
|
|
||||||
rad = r;
|
|
||||||
}
|
|
||||||
canvas.drawRoundRect(mRect, rad, rad, mFillPaint);
|
canvas.drawRoundRect(mRect, rad, rad, mFillPaint);
|
||||||
if (haveStroke) {
|
if (haveStroke) {
|
||||||
canvas.drawRoundRect(mRect, rad, rad, mStrokePaint);
|
canvas.drawRoundRect(mRect, rad, rad, mStrokePaint);
|
||||||
@ -1242,6 +1241,46 @@ public class GradientDrawable extends Drawable {
|
|||||||
return mGradientState;
|
return mGradientState;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Outline getOutline() {
|
||||||
|
final GradientState st = mGradientState;
|
||||||
|
final Rect bounds = getBounds();
|
||||||
|
|
||||||
|
switch (st.mShape) {
|
||||||
|
case RECTANGLE:
|
||||||
|
if (st.mRadiusArray != null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
float rad = 0;
|
||||||
|
if (st.mRadius > 0.0f) {
|
||||||
|
// clamp the radius based on width & height, matching behavior in draw()
|
||||||
|
rad = Math.min(st.mRadius,
|
||||||
|
Math.min(bounds.width(), bounds.height()) * 0.5f);
|
||||||
|
}
|
||||||
|
if (mOutline == null) {
|
||||||
|
mOutline = new Outline();
|
||||||
|
}
|
||||||
|
mOutline.setRoundRect(bounds.left, bounds.top,
|
||||||
|
bounds.right, bounds.bottom, rad);
|
||||||
|
return mOutline;
|
||||||
|
case LINE: {
|
||||||
|
float halfStrokeWidth = mStrokePaint.getStrokeWidth() * 0.5f;
|
||||||
|
float centerY = bounds.centerY();
|
||||||
|
int top = (int) Math.floor(centerY - halfStrokeWidth);
|
||||||
|
int bottom = (int) Math.ceil(centerY + halfStrokeWidth);
|
||||||
|
|
||||||
|
if (mOutline == null) {
|
||||||
|
mOutline = new Outline();
|
||||||
|
}
|
||||||
|
mOutline.setRoundRect(bounds.left, top, bounds.right, bottom, 0);
|
||||||
|
return mOutline;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
// TODO: investigate
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Drawable mutate() {
|
public Drawable mutate() {
|
||||||
if (!mMutated && super.mutate() == this) {
|
if (!mMutated && super.mutate() == this) {
|
||||||
|
90
libs/hwui/Outline.h
Normal file
90
libs/hwui/Outline.h
Normal file
@ -0,0 +1,90 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2014 The Android Open Source Project
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
#ifndef OUTLINE_H
|
||||||
|
#define OUTLINE_H
|
||||||
|
|
||||||
|
#include <SkPath.h>
|
||||||
|
|
||||||
|
#include "Rect.h"
|
||||||
|
|
||||||
|
namespace android {
|
||||||
|
namespace uirenderer {
|
||||||
|
|
||||||
|
class Outline {
|
||||||
|
public:
|
||||||
|
Outline()
|
||||||
|
: mShouldClip(false)
|
||||||
|
, mType(kOutlineType_None)
|
||||||
|
, mRadius(0) {}
|
||||||
|
|
||||||
|
void setRoundRect(int left, int top, int right, int bottom, int radius) {
|
||||||
|
mType = kOutlineType_RoundRect;
|
||||||
|
mBounds.set(left, top, right, bottom);
|
||||||
|
mRadius = radius;
|
||||||
|
mPath.reset();
|
||||||
|
mPath.addRoundRect(SkRect::MakeLTRB(left, top, right, bottom),
|
||||||
|
radius, radius);
|
||||||
|
}
|
||||||
|
|
||||||
|
void setConvexPath(const SkPath* outline) {
|
||||||
|
if (!outline) {
|
||||||
|
setEmpty();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
mType = kOutlineType_ConvexPath;
|
||||||
|
mPath = *outline;
|
||||||
|
mBounds.set(outline->getBounds());
|
||||||
|
}
|
||||||
|
|
||||||
|
void setEmpty() {
|
||||||
|
mType = kOutlineType_None;
|
||||||
|
mPath.reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
void setShouldClip(bool clip) {
|
||||||
|
mShouldClip = clip;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool willClip() const {
|
||||||
|
// only round rect outlines can be used for clipping
|
||||||
|
return mShouldClip && (mType == kOutlineType_RoundRect);
|
||||||
|
}
|
||||||
|
|
||||||
|
const SkPath* getPath() {
|
||||||
|
if (mType == kOutlineType_None) return NULL;
|
||||||
|
|
||||||
|
return &mPath;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
enum OutlineType {
|
||||||
|
kOutlineType_None = 0,
|
||||||
|
kOutlineType_ConvexPath = 1,
|
||||||
|
kOutlineType_RoundRect = 2
|
||||||
|
};
|
||||||
|
|
||||||
|
bool mShouldClip;
|
||||||
|
OutlineType mType;
|
||||||
|
Rect mBounds;
|
||||||
|
float mRadius;
|
||||||
|
SkPath mPath;
|
||||||
|
};
|
||||||
|
|
||||||
|
} /* namespace uirenderer */
|
||||||
|
} /* namespace android */
|
||||||
|
|
||||||
|
#endif /* OUTLINE_H */
|
@ -128,14 +128,14 @@ void RenderNode::outputViewProperties(const int level) {
|
|||||||
flags |= SkCanvas::kClipToLayer_SaveFlag;
|
flags |= SkCanvas::kClipToLayer_SaveFlag;
|
||||||
clipToBoundsNeeded = false; // clipping done by save layer
|
clipToBoundsNeeded = false; // clipping done by save layer
|
||||||
}
|
}
|
||||||
ALOGD("%*sSaveLayerAlpha %.2f, %.2f, %.2f, %.2f, %d, 0x%x", level * 2, "",
|
ALOGD("%*sSaveLayerAlpha %d, %d, %d, %d, %d, 0x%x", level * 2, "",
|
||||||
(float) 0, (float) 0, (float) properties().mRight - properties().mLeft, (float) properties().mBottom - properties().mTop,
|
0, 0, properties().mWidth, properties().mHeight,
|
||||||
(int)(properties().mAlpha * 255), flags);
|
(int)(properties().mAlpha * 255), flags);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (clipToBoundsNeeded) {
|
if (clipToBoundsNeeded) {
|
||||||
ALOGD("%*sClipRect %.2f, %.2f, %.2f, %.2f", level * 2, "", 0.0f, 0.0f,
|
ALOGD("%*sClipRect %d, %d, %d, %d", level * 2, "",
|
||||||
(float) properties().mRight - properties().mLeft, (float) properties().mBottom - properties().mTop);
|
0, 0, properties().mWidth, properties().mHeight);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -185,17 +185,20 @@ void RenderNode::setViewProperties(OpenGLRenderer& renderer, T& handler,
|
|||||||
}
|
}
|
||||||
|
|
||||||
SaveLayerOp* op = new (handler.allocator()) SaveLayerOp(
|
SaveLayerOp* op = new (handler.allocator()) SaveLayerOp(
|
||||||
0, 0, properties().mRight - properties().mLeft, properties().mBottom - properties().mTop, properties().mAlpha * 255, saveFlags);
|
0, 0, properties().mWidth, properties().mHeight,
|
||||||
|
properties().mAlpha * 255, saveFlags);
|
||||||
handler(op, PROPERTY_SAVECOUNT, properties().mClipToBounds);
|
handler(op, PROPERTY_SAVECOUNT, properties().mClipToBounds);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (clipToBoundsNeeded) {
|
if (clipToBoundsNeeded) {
|
||||||
ClipRectOp* op = new (handler.allocator()) ClipRectOp(0, 0,
|
ClipRectOp* op = new (handler.allocator()) ClipRectOp(
|
||||||
properties().mRight - properties().mLeft, properties().mBottom - properties().mTop, SkRegion::kIntersect_Op);
|
0, 0, properties().mWidth, properties().mHeight, SkRegion::kIntersect_Op);
|
||||||
handler(op, PROPERTY_SAVECOUNT, properties().mClipToBounds);
|
handler(op, PROPERTY_SAVECOUNT, properties().mClipToBounds);
|
||||||
}
|
}
|
||||||
if (CC_UNLIKELY(properties().mClipToOutline && !properties().mOutline.isEmpty())) {
|
if (CC_UNLIKELY(properties().mOutline.willClip())) {
|
||||||
ClipPathOp* op = new (handler.allocator()) ClipPathOp(&properties().mOutline, SkRegion::kIntersect_Op);
|
// TODO: optimize RR case
|
||||||
|
ClipPathOp* op = new (handler.allocator()) ClipPathOp(properties().mOutline.getPath(),
|
||||||
|
SkRegion::kIntersect_Op);
|
||||||
handler(op, PROPERTY_SAVECOUNT, properties().mClipToBounds);
|
handler(op, PROPERTY_SAVECOUNT, properties().mClipToBounds);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -443,7 +446,7 @@ void RenderNode::iterate3dChildren(const Vector<ZDrawDisplayListOpPair>& zTransl
|
|||||||
|
|
||||||
DisplayListOp* shadowOp = new (alloc) DrawShadowOp(
|
DisplayListOp* shadowOp = new (alloc) DrawShadowOp(
|
||||||
shadowMatrixXY, shadowMatrixZ,
|
shadowMatrixXY, shadowMatrixZ,
|
||||||
caster->properties().mAlpha, &(caster->properties().mOutline),
|
caster->properties().mAlpha, caster->properties().mOutline.getPath(),
|
||||||
caster->properties().mWidth, caster->properties().mHeight);
|
caster->properties().mWidth, caster->properties().mHeight);
|
||||||
handler(shadowOp, PROPERTY_SAVECOUNT, properties().mClipToBounds);
|
handler(shadowOp, PROPERTY_SAVECOUNT, properties().mClipToBounds);
|
||||||
}
|
}
|
||||||
|
@ -26,7 +26,6 @@ RenderProperties::RenderProperties()
|
|||||||
: mClipToBounds(true)
|
: mClipToBounds(true)
|
||||||
, mProjectBackwards(false)
|
, mProjectBackwards(false)
|
||||||
, mProjectionReceiver(false)
|
, mProjectionReceiver(false)
|
||||||
, mClipToOutline(false)
|
|
||||||
, mAlpha(1)
|
, mAlpha(1)
|
||||||
, mHasOverlappingRendering(true)
|
, mHasOverlappingRendering(true)
|
||||||
, mTranslationX(0), mTranslationY(0), mTranslationZ(0)
|
, mTranslationX(0), mTranslationY(0), mTranslationZ(0)
|
||||||
@ -47,7 +46,6 @@ RenderProperties::RenderProperties()
|
|||||||
, mStaticMatrix(NULL)
|
, mStaticMatrix(NULL)
|
||||||
, mAnimationMatrix(NULL)
|
, mAnimationMatrix(NULL)
|
||||||
, mCaching(false) {
|
, mCaching(false) {
|
||||||
mOutline.rewind();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
RenderProperties::~RenderProperties() {
|
RenderProperties::~RenderProperties() {
|
||||||
|
@ -13,8 +13,8 @@
|
|||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
#ifndef RENDERNODEPROPERTIES_H_
|
#ifndef RENDERNODEPROPERTIES_H
|
||||||
#define RENDERNODEPROPERTIES_H_
|
#define RENDERNODEPROPERTIES_H
|
||||||
|
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
#include <cutils/compiler.h>
|
#include <cutils/compiler.h>
|
||||||
@ -22,7 +22,9 @@
|
|||||||
|
|
||||||
#include <SkCamera.h>
|
#include <SkCamera.h>
|
||||||
#include <SkMatrix.h>
|
#include <SkMatrix.h>
|
||||||
#include <SkPath.h>
|
|
||||||
|
#include "Rect.h"
|
||||||
|
#include "Outline.h"
|
||||||
|
|
||||||
#define TRANSLATION 0x0001
|
#define TRANSLATION 0x0001
|
||||||
#define ROTATION 0x0002
|
#define ROTATION 0x0002
|
||||||
@ -64,18 +66,6 @@ public:
|
|||||||
return mProjectionReceiver;
|
return mProjectionReceiver;
|
||||||
}
|
}
|
||||||
|
|
||||||
void setOutline(const SkPath* outline) {
|
|
||||||
if (!outline) {
|
|
||||||
mOutline.reset();
|
|
||||||
} else {
|
|
||||||
mOutline = *outline;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void setClipToOutline(bool clipToOutline) {
|
|
||||||
mClipToOutline = clipToOutline;
|
|
||||||
}
|
|
||||||
|
|
||||||
void setStaticMatrix(SkMatrix* matrix) {
|
void setStaticMatrix(SkMatrix* matrix) {
|
||||||
delete mStaticMatrix;
|
delete mStaticMatrix;
|
||||||
mStaticMatrix = new SkMatrix(*matrix);
|
mStaticMatrix = new SkMatrix(*matrix);
|
||||||
@ -375,14 +365,18 @@ public:
|
|||||||
mCaching = caching;
|
mCaching = caching;
|
||||||
}
|
}
|
||||||
|
|
||||||
int getWidth() {
|
int getWidth() const {
|
||||||
return mWidth;
|
return mWidth;
|
||||||
}
|
}
|
||||||
|
|
||||||
int getHeight() {
|
int getHeight() const {
|
||||||
return mHeight;
|
return mHeight;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Outline& outline() {
|
||||||
|
return mOutline;
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void onTranslationUpdate() {
|
void onTranslationUpdate() {
|
||||||
mMatrixDirty = true;
|
mMatrixDirty = true;
|
||||||
@ -396,11 +390,10 @@ private:
|
|||||||
void updateMatrix();
|
void updateMatrix();
|
||||||
|
|
||||||
// Rendering properties
|
// Rendering properties
|
||||||
|
Outline mOutline;
|
||||||
bool mClipToBounds;
|
bool mClipToBounds;
|
||||||
bool mProjectBackwards;
|
bool mProjectBackwards;
|
||||||
bool mProjectionReceiver;
|
bool mProjectionReceiver;
|
||||||
SkPath mOutline;
|
|
||||||
bool mClipToOutline;
|
|
||||||
float mAlpha;
|
float mAlpha;
|
||||||
bool mHasOverlappingRendering;
|
bool mHasOverlappingRendering;
|
||||||
float mTranslationX, mTranslationY, mTranslationZ;
|
float mTranslationX, mTranslationY, mTranslationZ;
|
||||||
@ -436,4 +429,4 @@ private:
|
|||||||
} /* namespace uirenderer */
|
} /* namespace uirenderer */
|
||||||
} /* namespace android */
|
} /* namespace android */
|
||||||
|
|
||||||
#endif /* RENDERNODEPROPERTIES_H_ */
|
#endif /* RENDERNODEPROPERTIES_H */
|
||||||
|
Reference in New Issue
Block a user