Android-Choreographer 垂直同步 Vsync
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Android-Choreographer 垂直同步 Vsync相关的知识,希望对你有一定的参考价值。
参考技术Aview.requestLayout 调用的是 parent.requestLayout,直到 DecorView 最终到 ViewRootImpl.requestLayout 方法。
提示: requestLayout() 跟 invalidate() 区别在于 PFLAG_FORCE_LAYOUT、PFLAG_INVALIDATED,invalidate 不会重新测量布局,只会重新绘制
调用栈:mChoreographer.postCallback(int callbackType, Runnable action, Object token) --> postCallbackDelayed() --> postCallbackDelayedInternal()
至此从调用 requestLayout 到请求 Vsync 信号过程已经结束。
下面看收到 Vsync 信号后,如何处理 mTraversalRunnable 任务。
doTraversal()方法则是 测量、布局、绘制 入口,此处不做分析。
Vsync 垂直同步:
涉及到垂直刷新脉冲、vsync 、gpu 缓冲区 Frame Buffer、Back Buffer 三重缓存,跟 Choreographer
gpu 像素栅格化
垂直同步使得显卡的输出帧数和屏幕的刷新速度保持一致,其中 vsync 用来同步信息,buffer 缓存数据,当 vsync 出现时,cpu 会立即处理下一帧数据写入到缓存中,
之后gpu再渲染数据写在同一个缓存中,当vsync时,下一帧的 buffer 跟当前帧所在的buffer数据交换,当如果之前帧未显示完,是不会进行数据交换的。屏幕扫描下一次的数据显示。
当一个信号来时,假设a b buffer都被占用,此时gpu使用c缓存下一帧的数据,可以有效减少掉帧的几率。
1、view.requestLayout 调用的是 parent.requestLayout ,直到 DecorView 最终到 ViewRootImpl.requestLayout 方法。
2、首先判断正在测量布局,没有则 checkThread 检验当前是否在主线程。在 scheduleTraversals 首先中执行同步屏障,其次再将任务 postCallback 给 Choreographer,Choreographer 将任务保存在 mCallbackQueues 中,同时发送 MSG_DO_SCHEDULE_CALLBACK 的同步消息给FrameHandler。FrameHandler 的优先执行 CALLBACK 同步消息调用 doScheduleCallback,mCallbackQueues 不为空且 callback 不是延迟执行,调用 scheduleFrameLocked 方法请求 Vsync 信号。当运行在 Looper 线程,则立刻调度 vsync,否则,发送消息到UI线程再调度 vsync。其中是通过 FrameDisplayEventReceiver 调度 vysnc。
FrameDisplayEventReceiver 有两个作用,一个是 scheduleVsync 请求调度,另一个是接收 vsync 信号回调 onVsync,当接收到 vsync 信号时,调用doFrame 方法,开始渲染下一帧。
doFrame 可以分为三步:一是计算掉帧逻辑,二是记录帧绘制信息,三是处理多种 callback,依次是 input 调用栈,会回调到 DecorView 的 dispatchTouchEvent。
二是 animation 调用栈,执行动画;三是 Traversal 调用栈,即最发送给 Choreographer 的任务
动画如何流畅执行: 调用animation.start时,最终在AnimationHandler会给Choreographer.FrameCallback 回调 doFrame,里面 post了自己。
如何在 MFC 中垂直同步两个列表控件
【中文标题】如何在 MFC 中垂直同步两个列表控件【英文标题】:How synchronize two list controls vertically in MFC 【发布时间】:2016-03-30 05:50:09 【问题描述】:我有两个列表控件,它们都可以分别垂直滚动。
但是我想同步滚动也想隐藏列表控件 1 中的垂直滚动条。
另一方面,如果您垂直滚动列表 control-2,则列表 control-1 应自动向下滚动相同数量的项目,这样两个列表框上的选项应始终显示在同一行中.
如何在 MFC 中实现这一点?
【问题讨论】:
对于同步,您可以使用CListBox::SetTopIndex
和CListBox::SetTopIndex
。将滚动条隐藏在具有比显示更多项目的列表框中是另一回事,我不确定这是否可能。您可以尝试所有者绘制列表控件,然后您可以完全控制列表控件 1 中显示的内容,但这需要一些工作。
更正:您可以通过将列表框的“垂直滚动条”属性设置为False来移除垂直滚动条。
@MichaelWalz 感谢您的回复。是否可以冻结(修复)列表控件的第一列?我的意思是与 Excel 中的冻结列相同。
不太清楚你所说的第一列是什么意思,我以为你有两个列表控件。也许你应该编辑你的问题,更清楚你到底想要什么。
对不起,我误读了您的问题,以为您在谈论列表框而不是列表控件。看看this SO question。
【参考方案1】:
我通过文档在两个列表视图之间建立连接,但最终结果是对从属列表控件的 Scroll 成员发出的命令。
所以在 master 中处理 ON_WM_VSCROLL(),我实际上有一个自定义通知,但您可能只想从 master 中的类似处快捷方式:
if( pS->nSBCode == SB_THUMBTRACK )
GetDocument( )->SetSplitScrollPos( pS->nPos );
无论你如何工作到 'SetSplitScrollPos' 之类的东西,它都会在从属设备上结束:
void CLCtrl::ScrollToVPosition( long inPos )
long scroll= ( inPos - curVScrollPos );
Scroll( scroll << 20 );
curVScrollPos= inPos;
“滚动”调用是 CListCtrl 成员,因此您可以:
mySlaveCtrl.Scroll( ... );
现在,我很抱歉,但我不记得为什么将 20 转换为 '
也就是说,您可以简单地处理主 ON_WM_VSCROLL 和:
if( pS->nSBCode == SB_THUMBTRACK )
mySlaveCtrl.Scroll( ( ps->pos - curVScrollPos ) << 20 );
【讨论】:
非常感谢您的重播。我参考link以上是关于Android-Choreographer 垂直同步 Vsync的主要内容,如果未能解决你的问题,请参考以下文章
Bootstrap 3.0 - 垂直对齐同一行中的 3 个面板(自动高度)
有几张高度不一样的小图片,如何用html+css实现在同一行垂直居中对齐?