use of android.view.animation.Transformation in project platform_frameworks_base by android.
the class WindowStateAnimator method computeShownFrameLocked.
void computeShownFrameLocked() {
final boolean selfTransformation = mHasLocalTransformation;
Transformation attachedTransformation = (mAttachedWinAnimator != null && mAttachedWinAnimator.mHasLocalTransformation) ? mAttachedWinAnimator.mTransformation : null;
Transformation appTransformation = (mAppAnimator != null && mAppAnimator.hasTransformation) ? mAppAnimator.transformation : null;
// Wallpapers are animated based on the "real" window they
// are currently targeting.
final WindowState wallpaperTarget = mWallpaperControllerLocked.getWallpaperTarget();
if (mIsWallpaper && wallpaperTarget != null && mService.mAnimateWallpaperWithTarget) {
final WindowStateAnimator wallpaperAnimator = wallpaperTarget.mWinAnimator;
if (wallpaperAnimator.mHasLocalTransformation && wallpaperAnimator.mAnimation != null && !wallpaperAnimator.mAnimation.getDetachWallpaper()) {
attachedTransformation = wallpaperAnimator.mTransformation;
if (DEBUG_WALLPAPER && attachedTransformation != null) {
Slog.v(TAG, "WP target attached xform: " + attachedTransformation);
}
}
final AppWindowAnimator wpAppAnimator = wallpaperTarget.mAppToken == null ? null : wallpaperTarget.mAppToken.mAppAnimator;
if (wpAppAnimator != null && wpAppAnimator.hasTransformation && wpAppAnimator.animation != null && !wpAppAnimator.animation.getDetachWallpaper()) {
appTransformation = wpAppAnimator.transformation;
if (DEBUG_WALLPAPER && appTransformation != null) {
Slog.v(TAG, "WP target app xform: " + appTransformation);
}
}
}
final int displayId = mWin.getDisplayId();
final ScreenRotationAnimation screenRotationAnimation = mAnimator.getScreenRotationAnimationLocked(displayId);
final boolean screenAnimation = screenRotationAnimation != null && screenRotationAnimation.isAnimating();
mHasClipRect = false;
if (selfTransformation || attachedTransformation != null || appTransformation != null || screenAnimation) {
// cache often used attributes locally
final Rect frame = mWin.mFrame;
final float[] tmpFloats = mService.mTmpFloats;
final Matrix tmpMatrix = mWin.mTmpMatrix;
// Compute the desired transformation.
if (screenAnimation && screenRotationAnimation.isRotating()) {
// If we are doing a screen animation, the global rotation
// applied to windows can result in windows that are carefully
// aligned with each other to slightly separate, allowing you
// to see what is behind them. An unsightly mess. This...
// thing... magically makes it call good: scale each window
// slightly (two pixels larger in each dimension, from the
// window's center).
final float w = frame.width();
final float h = frame.height();
if (w >= 1 && h >= 1) {
tmpMatrix.setScale(1 + 2 / w, 1 + 2 / h, w / 2, h / 2);
} else {
tmpMatrix.reset();
}
} else {
tmpMatrix.reset();
}
tmpMatrix.postScale(mWin.mGlobalScale, mWin.mGlobalScale);
if (selfTransformation) {
tmpMatrix.postConcat(mTransformation.getMatrix());
}
if (attachedTransformation != null) {
tmpMatrix.postConcat(attachedTransformation.getMatrix());
}
tmpMatrix.postTranslate(frame.left + mWin.mXOffset, frame.top + mWin.mYOffset);
if (appTransformation != null) {
tmpMatrix.postConcat(appTransformation.getMatrix());
}
if (screenAnimation) {
tmpMatrix.postConcat(screenRotationAnimation.getEnterTransformation().getMatrix());
}
//TODO (multidisplay): Magnification is supported only for the default display.
if (mService.mAccessibilityController != null && displayId == DEFAULT_DISPLAY) {
MagnificationSpec spec = mService.mAccessibilityController.getMagnificationSpecForWindowLocked(mWin);
applyMagnificationSpec(spec, tmpMatrix);
}
// "convert" it into SurfaceFlinger's format
// (a 2x2 matrix + an offset)
// Here we must not transform the position of the surface
// since it is already included in the transformation.
//Slog.i(TAG_WM, "Transform: " + matrix);
mHaveMatrix = true;
tmpMatrix.getValues(tmpFloats);
mDsDx = tmpFloats[Matrix.MSCALE_X];
mDtDx = tmpFloats[Matrix.MSKEW_Y];
mDsDy = tmpFloats[Matrix.MSKEW_X];
mDtDy = tmpFloats[Matrix.MSCALE_Y];
float x = tmpFloats[Matrix.MTRANS_X];
float y = tmpFloats[Matrix.MTRANS_Y];
mWin.mShownPosition.set(Math.round(x), Math.round(y));
// Now set the alpha... but because our current hardware
// can't do alpha transformation on a non-opaque surface,
// turn it off if we are running an animation that is also
// transforming since it is more important to have that
// animation be smooth.
mShownAlpha = mAlpha;
if (!mService.mLimitedAlphaCompositing || (!PixelFormat.formatHasAlpha(mWin.mAttrs.format) || (mWin.isIdentityMatrix(mDsDx, mDtDx, mDsDy, mDtDy) && x == frame.left && y == frame.top))) {
//Slog.i(TAG_WM, "Applying alpha transform");
if (selfTransformation) {
mShownAlpha *= mTransformation.getAlpha();
}
if (attachedTransformation != null) {
mShownAlpha *= attachedTransformation.getAlpha();
}
if (appTransformation != null) {
mShownAlpha *= appTransformation.getAlpha();
if (appTransformation.hasClipRect()) {
mClipRect.set(appTransformation.getClipRect());
mHasClipRect = true;
// bounds to compensate for this.
if (mWin.layoutInParentFrame()) {
mClipRect.offset((mWin.mContainingFrame.left - mWin.mFrame.left), mWin.mContainingFrame.top - mWin.mFrame.top);
}
}
}
if (screenAnimation) {
mShownAlpha *= screenRotationAnimation.getEnterTransformation().getAlpha();
}
} else {
//Slog.i(TAG_WM, "Not applying alpha transform");
}
if ((DEBUG_SURFACE_TRACE || WindowManagerService.localLOGV) && (mShownAlpha == 1.0 || mShownAlpha == 0.0))
Slog.v(TAG, "computeShownFrameLocked: Animating " + this + " mAlpha=" + mAlpha + " self=" + (selfTransformation ? mTransformation.getAlpha() : "null") + " attached=" + (attachedTransformation == null ? "null" : attachedTransformation.getAlpha()) + " app=" + (appTransformation == null ? "null" : appTransformation.getAlpha()) + " screen=" + (screenAnimation ? screenRotationAnimation.getEnterTransformation().getAlpha() : "null"));
return;
} else if (mIsWallpaper && mService.mWindowPlacerLocked.mWallpaperActionPending) {
return;
} else if (mWin.isDragResizeChanged()) {
// with new geometry.
return;
}
if (WindowManagerService.localLOGV)
Slog.v(TAG, "computeShownFrameLocked: " + this + " not attached, mAlpha=" + mAlpha);
MagnificationSpec spec = null;
//TODO (multidisplay): Magnification is supported only for the default display.
if (mService.mAccessibilityController != null && displayId == DEFAULT_DISPLAY) {
spec = mService.mAccessibilityController.getMagnificationSpecForWindowLocked(mWin);
}
if (spec != null) {
final Rect frame = mWin.mFrame;
final float[] tmpFloats = mService.mTmpFloats;
final Matrix tmpMatrix = mWin.mTmpMatrix;
tmpMatrix.setScale(mWin.mGlobalScale, mWin.mGlobalScale);
tmpMatrix.postTranslate(frame.left + mWin.mXOffset, frame.top + mWin.mYOffset);
applyMagnificationSpec(spec, tmpMatrix);
tmpMatrix.getValues(tmpFloats);
mHaveMatrix = true;
mDsDx = tmpFloats[Matrix.MSCALE_X];
mDtDx = tmpFloats[Matrix.MSKEW_Y];
mDsDy = tmpFloats[Matrix.MSKEW_X];
mDtDy = tmpFloats[Matrix.MSCALE_Y];
float x = tmpFloats[Matrix.MTRANS_X];
float y = tmpFloats[Matrix.MTRANS_Y];
mWin.mShownPosition.set(Math.round(x), Math.round(y));
mShownAlpha = mAlpha;
} else {
mWin.mShownPosition.set(mWin.mFrame.left, mWin.mFrame.top);
if (mWin.mXOffset != 0 || mWin.mYOffset != 0) {
mWin.mShownPosition.offset(mWin.mXOffset, mWin.mYOffset);
}
mShownAlpha = mAlpha;
mHaveMatrix = false;
mDsDx = mWin.mGlobalScale;
mDtDx = 0;
mDsDy = 0;
mDtDy = mWin.mGlobalScale;
}
}
use of android.view.animation.Transformation in project android_frameworks_base by DirtyUnicorns.
the class View method applyLegacyAnimation.
/**
* Utility function, called by draw(canvas, parent, drawingTime) to handle the less common
* case of an active Animation being run on the view.
*/
private boolean applyLegacyAnimation(ViewGroup parent, long drawingTime, Animation a, boolean scalingRequired) {
Transformation invalidationTransform;
final int flags = parent.mGroupFlags;
final boolean initialized = a.isInitialized();
if (!initialized) {
a.initialize(mRight - mLeft, mBottom - mTop, parent.getWidth(), parent.getHeight());
a.initializeInvalidateRegion(0, 0, mRight - mLeft, mBottom - mTop);
if (mAttachInfo != null)
a.setListenerHandler(mAttachInfo.mHandler);
onAnimationStart();
}
final Transformation t = parent.getChildTransformation();
boolean more = a.getTransformation(drawingTime, t, 1f);
if (scalingRequired && mAttachInfo.mApplicationScale != 1f) {
if (parent.mInvalidationTransformation == null) {
parent.mInvalidationTransformation = new Transformation();
}
invalidationTransform = parent.mInvalidationTransformation;
a.getTransformation(drawingTime, invalidationTransform, 1f);
} else {
invalidationTransform = t;
}
if (more) {
if (!a.willChangeBounds()) {
if ((flags & (ViewGroup.FLAG_OPTIMIZE_INVALIDATE | ViewGroup.FLAG_ANIMATION_DONE)) == ViewGroup.FLAG_OPTIMIZE_INVALIDATE) {
parent.mGroupFlags |= ViewGroup.FLAG_INVALIDATE_REQUIRED;
} else if ((flags & ViewGroup.FLAG_INVALIDATE_REQUIRED) == 0) {
// The child need to draw an animation, potentially offscreen, so
// make sure we do not cancel invalidate requests
parent.mPrivateFlags |= PFLAG_DRAW_ANIMATION;
parent.invalidate(mLeft, mTop, mRight, mBottom);
}
} else {
if (parent.mInvalidateRegion == null) {
parent.mInvalidateRegion = new RectF();
}
final RectF region = parent.mInvalidateRegion;
a.getInvalidateRegion(0, 0, mRight - mLeft, mBottom - mTop, region, invalidationTransform);
// The child need to draw an animation, potentially offscreen, so
// make sure we do not cancel invalidate requests
parent.mPrivateFlags |= PFLAG_DRAW_ANIMATION;
final int left = mLeft + (int) region.left;
final int top = mTop + (int) region.top;
parent.invalidate(left, top, left + (int) (region.width() + .5f), top + (int) (region.height() + .5f));
}
}
return more;
}
use of android.view.animation.Transformation in project android_frameworks_base by DirtyUnicorns.
the class View method setDisplayListProperties.
/**
* This method is called by getDisplayList() when a display list is recorded for a View.
* It pushes any properties to the RenderNode that aren't managed by the RenderNode.
*/
void setDisplayListProperties(RenderNode renderNode) {
if (renderNode != null) {
renderNode.setHasOverlappingRendering(getHasOverlappingRendering());
renderNode.setClipToBounds(mParent instanceof ViewGroup && ((ViewGroup) mParent).getClipChildren());
float alpha = 1;
if (mParent instanceof ViewGroup && (((ViewGroup) mParent).mGroupFlags & ViewGroup.FLAG_SUPPORT_STATIC_TRANSFORMATIONS) != 0) {
ViewGroup parentVG = (ViewGroup) mParent;
final Transformation t = parentVG.getChildTransformation();
if (parentVG.getChildStaticTransformation(this, t)) {
final int transformType = t.getTransformationType();
if (transformType != Transformation.TYPE_IDENTITY) {
if ((transformType & Transformation.TYPE_ALPHA) != 0) {
alpha = t.getAlpha();
}
if ((transformType & Transformation.TYPE_MATRIX) != 0) {
renderNode.setStaticMatrix(t.getMatrix());
}
}
}
}
if (mTransformationInfo != null) {
alpha *= getFinalAlpha();
if (alpha < 1) {
final int multipliedAlpha = (int) (255 * alpha);
if (onSetAlpha(multipliedAlpha)) {
alpha = 1;
}
}
renderNode.setAlpha(alpha);
} else if (alpha < 1) {
renderNode.setAlpha(alpha);
}
}
}
use of android.view.animation.Transformation in project android_frameworks_base by DirtyUnicorns.
the class ViewGroup method invalidateChild.
/**
* Don't call or override this method. It is used for the implementation of
* the view hierarchy.
*/
@Override
public final void invalidateChild(View child, final Rect dirty) {
ViewParent parent = this;
final AttachInfo attachInfo = mAttachInfo;
if (attachInfo != null) {
// If the child is drawing an animation, we want to copy this flag onto
// ourselves and the parent to make sure the invalidate request goes
// through
final boolean drawAnimation = (child.mPrivateFlags & PFLAG_DRAW_ANIMATION) == PFLAG_DRAW_ANIMATION;
// Check whether the child that requests the invalidate is fully opaque
// Views being animated or transformed are not considered opaque because we may
// be invalidating their old position and need the parent to paint behind them.
Matrix childMatrix = child.getMatrix();
final boolean isOpaque = child.isOpaque() && !drawAnimation && child.getAnimation() == null && childMatrix.isIdentity();
// Mark the child as dirty, using the appropriate flag
// Make sure we do not set both flags at the same time
int opaqueFlag = isOpaque ? PFLAG_DIRTY_OPAQUE : PFLAG_DIRTY;
if (child.mLayerType != LAYER_TYPE_NONE) {
mPrivateFlags |= PFLAG_INVALIDATED;
mPrivateFlags &= ~PFLAG_DRAWING_CACHE_VALID;
}
final int[] location = attachInfo.mInvalidateChildLocation;
location[CHILD_LEFT_INDEX] = child.mLeft;
location[CHILD_TOP_INDEX] = child.mTop;
if (!childMatrix.isIdentity() || (mGroupFlags & ViewGroup.FLAG_SUPPORT_STATIC_TRANSFORMATIONS) != 0) {
RectF boundingRect = attachInfo.mTmpTransformRect;
boundingRect.set(dirty);
Matrix transformMatrix;
if ((mGroupFlags & ViewGroup.FLAG_SUPPORT_STATIC_TRANSFORMATIONS) != 0) {
Transformation t = attachInfo.mTmpTransformation;
boolean transformed = getChildStaticTransformation(child, t);
if (transformed) {
transformMatrix = attachInfo.mTmpMatrix;
transformMatrix.set(t.getMatrix());
if (!childMatrix.isIdentity()) {
transformMatrix.preConcat(childMatrix);
}
} else {
transformMatrix = childMatrix;
}
} else {
transformMatrix = childMatrix;
}
transformMatrix.mapRect(boundingRect);
dirty.set((int) Math.floor(boundingRect.left), (int) Math.floor(boundingRect.top), (int) Math.ceil(boundingRect.right), (int) Math.ceil(boundingRect.bottom));
}
do {
View view = null;
if (parent instanceof View) {
view = (View) parent;
}
if (drawAnimation) {
if (view != null) {
view.mPrivateFlags |= PFLAG_DRAW_ANIMATION;
} else if (parent instanceof ViewRootImpl) {
((ViewRootImpl) parent).mIsAnimating = true;
}
}
// flag coming from the child that initiated the invalidate
if (view != null) {
if ((view.mViewFlags & FADING_EDGE_MASK) != 0 && view.getSolidColor() == 0) {
opaqueFlag = PFLAG_DIRTY;
}
if ((view.mPrivateFlags & PFLAG_DIRTY_MASK) != PFLAG_DIRTY) {
view.mPrivateFlags = (view.mPrivateFlags & ~PFLAG_DIRTY_MASK) | opaqueFlag;
}
}
parent = parent.invalidateChildInParent(location, dirty);
if (view != null) {
// Account for transform on current parent
Matrix m = view.getMatrix();
if (!m.isIdentity()) {
RectF boundingRect = attachInfo.mTmpTransformRect;
boundingRect.set(dirty);
m.mapRect(boundingRect);
dirty.set((int) Math.floor(boundingRect.left), (int) Math.floor(boundingRect.top), (int) Math.ceil(boundingRect.right), (int) Math.ceil(boundingRect.bottom));
}
}
} while (parent != null);
}
}
use of android.view.animation.Transformation in project SmartAndroidSource by jaychou2012.
the class IcsProgressBar method startAnimation.
/**
* <p>
* Start the indeterminate progress animation.
* </p>
*/
void startAnimation() {
if (getVisibility() != VISIBLE) {
return;
}
if (mIndeterminateDrawable instanceof Animatable) {
mShouldStartAnimationDrawable = true;
mAnimation = null;
} else {
if (mInterpolator == null) {
mInterpolator = new LinearInterpolator();
}
mTransformation = new Transformation();
mAnimation = new AlphaAnimation(0.0f, 1.0f);
mAnimation.setRepeatMode(mBehavior);
mAnimation.setRepeatCount(Animation.INFINITE);
mAnimation.setDuration(mDuration);
mAnimation.setInterpolator(mInterpolator);
mAnimation.setStartTime(Animation.START_ON_FIRST_FRAME);
}
postInvalidate();
}
Aggregations