Android6.0 WMS(十一) WMS窗口动画生成及播放
2017-01-12 15:13
846 查看
上一篇我们我们分析到有VSync信号过来,最后会调用WindowAnimator的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://blog.csdn.net/kc58236582/article/details/53835998博客中我们分析过WindowStateAnimator的stepAnimationLocked函数。
然后调用setSurfaceBoundariesLocked到SurfaceControl中设置窗口大小、位置等。
最后会调用showSurfaceRobustlyLocked函数来输出动画帧。这个函数(也在http://blog.csdn.net/kc58236582/article/details/53835998博客中分析过)。
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://blog.csdn.net/kc58236582/article/details/53835998博客中我们分析过WindowStateAnimator的stepAnimationLocked函数。
prepareSurfaceLocked函数输出动画
而动画输出函数prepareSurfaceLocked我们也在博客http://blog.csdn.net/kc58236582/article/details/53835998分析过了,这个函数先会调用computeShownFrameLocked函数负责合成窗口的动画,包括窗口本身所设置的进入(退出)动画、从被附加窗口传递过来的动画,以及宿主Activity组件传递过来的切换动画。窗口的这三个动画合成之后,就可以得到一个变换矩阵。将这个变换矩阵应用到窗口的原始大小和位置上去,就可以得到窗口经过动画变换后所得到的位置和大小。然后调用setSurfaceBoundariesLocked到SurfaceControl中设置窗口大小、位置等。
最后会调用showSurfaceRobustlyLocked函数来输出动画帧。这个函数(也在http://blog.csdn.net/kc58236582/article/details/53835998博客中分析过)。
相关文章推荐
- QGIS如何使用WMS图层
- QGIS如何使用WMS图层
- ERP系统咨文
- 欢迎使用CSDN-markdown编辑器
- WMS WFS WCS 的区别
- WindowManagerService如何管理应用程序窗口
- leaflet
- Mule—应用
- GeoServer-WMS,WFS,WCS
- wms根据sld,sld_body请求地图
- GeoServer的WMS服务加载到天地图
- WMS网站开发框架
- Google earth中调用ArcGIS server的REST服务和WMS服务
- Activity WMS ViewRootImpl三者关系(Activity创建窗口 按键分发等)
- android6.0 Activity(三) Activity与WMS通信过程
- Android6.0 WMS(二) WMS创建窗口与创建Surface的关系
- Android6.0 WMS(三) WMS窗口次序
- Android6.0 WMS(四) WMS中常用变量分析
- Android6.0 旋转屏幕(一)WMS注册传感器回调
- Android6.0 旋转屏幕(三)应用是否要重启