android wms 窗口,Android6.0 WMS(十一) WMS窗口动画生成及播放

上一篇我们我们分析到有VSync信号过来,最后会调用WindowAnimator的animateLocked函数来生成和播放动画,这篇我们我们主要从这个函数开始分析。

animateLocked函数

当VSync信号过来后在WMS中如果调用了scheduleAnimationLocked函数。就会调用animateLocked函数

private void animateLocked(long frameTimeNs) {

......

SurfaceControl.openTransaction();

SurfaceControl.setAnimationTransaction();

try {

final int numDisplays = mDisplayContentsAnimators.size();

for (int i = 0; i < numDisplays; i++) {

final int displayId = mDisplayContentsAnimators.keyAt(i);

updateAppWindowsLocked(displayId);//Activity切入动画

DisplayContentsAnimator displayAnimator = mDisplayContentsAnimators.valueAt(i);

final ScreenRotationAnimation screenRotationAnimation =

displayAnimator.mScreenRotationAnimation;

if (screenRotationAnimation != null && screenRotationAnimation.isAnimating()) {

if (screenRotationAnimation.stepAnimationLocked(mCurrentTime)) {

mAnimating = true;

} else {

......

}

}

// Update animations of all applications, including those

// associated with exiting/removed apps

updateWindowsLocked(displayId);//普通窗口的动画

updateWallpaperLocked(displayId);

final WindowList windows = mService.getWindowListLocked(displayId);

final int N = windows.size();

for (int j = 0; j < N; j++) {

windows.get(j).mWinAnimator.prepareSurfaceLocked(true);//输出动画

}

}

for (int i = 0; i < numDisplays; i++) {

final int displayId = mDisplayContentsAnimators.keyAt(i);

testTokenMayBeDrawnLocked(displayId);

final ScreenRotationAnimation screenRotationAnimation =

mDisplayContentsAnimators.valueAt(i).mScreenRotationAnimation;

if (screenRotationAnimation != null) {

screenRotationAnimation.updateSurfacesInTransaction();

}

mAnimating |= mService.getDisplayContentLocked(displayId).animateDimLayers();

//TODO (multidisplay): Magnification is supported only for the default display.

if (mService.mAccessibilityController != null

&& displayId == Display.DEFAULT_DISPLAY) {

mService.mAccessibilityController.drawMagnifiedRegionBorderIfNeededLocked();

}

}

if (mAnimating) {//继续播放下一帧

mService.scheduleAnimationLocked();

}

mService.setFocusedStackLayer();

if (mService.mWatermark != null) {

mService.mWatermark.drawIfNeeded();

}

} catch (RuntimeException e) {

Slog.wtf(TAG, "Unhandled exception in Window Manager", e);

} finally {

SurfaceControl.closeTransaction();

}

boolean hasPendingLayoutChanges = false;

final int numDisplays = mService.mDisplayContents.size();

for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {

final DisplayContent displayContent = mService.mDisplayContents.valueAt(displayNdx);

final int pendingChanges = getPendingLayoutChanges(displayContent.getDisplayId());

if ((pendingChanges & WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER) != 0) {

mBulkUpdateParams |= SET_WALLPAPER_ACTION_PENDING;

}

if (pendingChanges != 0) {

hasPendingLayoutChanges = true;

}

}

boolean doRequest = false;

if (mBulkUpdateParams != 0) {

doRequest = mService.copyAnimToLayoutParamsLocked();

}

if (hasPendingLayoutChanges || doRequest) {

mService.requestTraversalLocked();

}

if (!mAnimating && wasAnimating) {//播放完成重新刷新布局

mService.requestTraversalLocked();

}

}上面函数显示对3种动画(Activity切换动画、屏幕旋转动画、窗口动画)调用其

stepAnimationLocked函数推进(各种状态赋值)具体是在updateWindowsLocked、updateWindowsLocked函数中调用,然后调用每个WindowState的WindowStateAnimator的prepareSurfaceLocked函数来输出动画帧。后面当mAnimating为true代表还要继续输出动画帧,继续调用WMS的scheduleAnimationLocked函数,当VSync信号过来时会继续调用animateLocked函数,最后播放完动画会调用WMS的requestTraversalLocked函数,重新刷新布局。

在updateAppWindowsLocked、updateWindowsLocked函数会调用AppWindowAnimator的stepAnimationLocked和WindowStateAnimator的stepAnimationLocked函数。这两个函数我们就不分析,在http://www.voidcn.com/article/p-aoeynxax-ev.html博客中我们分析过WindowStateAnimator的stepAnimationLocked函数。

prepareSurfaceLocked函数输出动画

而动画输出函数prepareSurfaceLocked我们也在博客http://www.voidcn.com/article/p-aoeynxax-ev.html分析过了,这个函数先会调用computeShownFrameLocked函数负责合成窗口的动画,包括窗口本身所设置的进入(退出)动画、从被附加窗口传递过来的动画,以及宿主Activity组件传递过来的切换动画。窗口的这三个动画合成之后,就可以得到一个变换矩阵。将这个变换矩阵应用到窗口的原始大小和位置上去,就可以得到窗口经过动画变换后所得到的位置和大小。

然后调用setSurfaceBoundariesLocked到SurfaceControl中设置窗口大小、位置等。

最后会调用showSurfaceRobustlyLocked函数来输出动画帧。这个函数(也在http://www.voidcn.com/article/p-aoeynxax-ev.html博客中分析过)。



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值