WMS->动画执行过程中位移的计算

mWin.mShownPosition为最终window的位置,计算过程主要参考了app transition动画,屏幕旋转动画,attach的window的动画,目标墙纸的动画进行计算,最终计算出动画窗口的位置,大小alpha值,函数很简单主要使用了一些线性代数的矩阵变换,只是简单的缩放平移旋转操作.

void computeShownFrameLocked() {
        final boolean selfTransformation = mHasLocalTransformation;
        Transformation attachedTransformation =
                (mAttachedWinAnimator != null && mAttachedWinAnimator.mHasLocalTransformation)
                ? mAttachedWinAnimator.mTransformation : null;
        Transformation appTransformation = (mAppAnimator != null && mAppAnimator.hasTransformation)
                ? mAppAnimator.transformation : null;

        //1 对壁纸窗口的处理,先计算出目标窗口的appTransformation,attachedTransformation
        // 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();

        // 2 自己有动画或者父窗口父appwindow包含动画,更新坐标
        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;

            // 3 转屏的时候读窗口进行缩小,防止出现错乱的效果
            // 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();
            }
        //4 添加窗口缩放
            tmpMatrix.postScale(mWin.mGlobalScale, mWin.mGlobalScale);
            if (selfTransformation) { //5 点乘 window动画矩阵
                tmpMatrix.postConcat(mTransformation.getMatrix());
            }

            if (attachedTransformation != null) { //6 点乘attach 的window矩阵
                tmpMatrix.postConcat(attachedTransformation.getMatrix());
            }
            if (appTransformation != null) { // 7 点乘appwindow动画
                tmpMatrix.postConcat(appTransformation.getMatrix());
            }

            //7 平移动画
            // The translation that applies the position of the window needs to be applied at the
            // end in case that other translations include scaling. Otherwise the scaling will
            // affect this translation. But it needs to be set before the screen rotation animation
            // so the pivot point is at the center of the screen for all windows.
            tmpMatrix.postTranslate(frame.left + mWin.mXOffset, frame.top + mWin.mYOffset);
            if (screenAnimation) { //8 屏幕旋转矩阵,注意是进入的动画
                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);
                if (spec != null && !spec.isNop()) {
                    tmpMatrix.postScale(spec.scale, spec.scale);
                    tmpMatrix.postTranslate(spec.offsetX, spec.offsetY);
                }
            }

            // "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)); //9变换后的x坐标y坐标

            10 alpha值的计算 
            // 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;
                        // The app transformation clip will be in the coordinate space of the main
                        // activity window, which the animation correctly assumes will be placed at
                        // (0,0)+(insets) relative to the containing frame. This isn't necessarily
                        // true for child windows though which can have an arbitrary frame position
                        // relative to their containing frame. We need to offset the difference
                        // between the containing frame as used to calculate the crop and our
                        // 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()) {
            // This window is awaiting a relayout because user just started (or ended)
            // drag-resizing. The shown frame (which affects surface size and pos)
            // should not be updated until we get next finished draw with the new surface.
            // Otherwise one or two frames rendered with old settings would be displayed
            // with new geometry.
            return;
        }

    //11 后面这些针对动画完成或者不包含动画的情况
        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) { //12 mAccessibilityController 指定特殊变换的
            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);

            if (spec != null && !spec.isNop()) {
                tmpMatrix.postScale(spec.scale, spec.scale);
                tmpMatrix.postTranslate(spec.offsetX, spec.offsetY);
            }

            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 { //13 设置位置
            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;
        }
    }

Matrix{[1.0, 0.0, 517.0][0.0, 1.0, 1448.0][0.0, 0.0, 1.0]}

Matrix{[0.48888886, 0.0, -269.99997][0.0, 0.48888886, 556.66675][0.0, 0.0, 1.0]}
Matrix{[0.48888886, 0.0, 247.00003][0.0, 0.48888886, 2004.6667][0.0, 0.0, 1.0]}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值