miniblink修复3D变换的两处渲染Bug
2016-06-06 21:21
501 查看
情况是这样的,有个群友让我试了下http://2.swiper.com.cn/demo/3dflow/index.html 里面的3D flow效果,发现miniblink画出来是个平的,没有3D效果···
于是赶紧调了下。原因很快就找到了,是我自己写的渲染层,对于layer的处理有问题。
详细来讲,是这样,blink在碰到这种3d网页,会开启硬件加速渲染模式,创建N个platform layer(平台相关层)。而这个 blink只负责告诉这些layer他们的位置、坐标变换,但具体怎么显示这些layer完全靠外部代码来实现,也就是说blink不管了。这也就是miniblink之所以搞了我这么久的原因,我完全自己撸了一个layer系统,而之前,这部分代码是chromium里的cc目录(cc的意思是chromium composition )实现的。
回到这个问题,这些3D 图形,导致blink创建的layer的坐标变换都是SkMatrix44的矩阵,这只是第一步,拿到矩阵后 ,还要考虑页面滚动、层的相对位置,再经过一系列运算才能得出层的屏幕位置。而这部分代码,在cc里,是一个超级复杂的函数来计算的:cc\trees\layer_tree_host_common.cc里的CalculateDrawPropertiesInternal。这个函数复杂到什么程度呢,光注释就100多行,整个函数超过1000行!整个函数的流程大概就是不挺根据各种坐标变换、位置等参数计算各种layer的真实位置之类的。之前也
研究过此函数,那时候就是为了把此函数精简,提取出一个最简化cc层真正需要的算法。但我之前的理解不够深刻,
看这个函数其中一个矩阵运算部分,这里combined_transform应该会得出屏幕坐标系的矩阵。而我的精简版cc层里,拿到这个矩阵后,复制给了绘制的canvas。这里我犯了一个错误,就是canvas最终接收到的矩阵,不是4X4,而是退化成3x3了。也不知道谷歌为啥要这样搞,总之这里就丢失了部分矩阵数据。而chromium里的是把一系列数据,包括这个矩阵,存在一个从顶层传下来的数据结构data_from_ancestor里(这样说明一下,CalculateDrawPropertiesInternal是个递归调用的函数,用来不停计算所有layer的数据),所以这个4x4的矩阵就没丢失精度,只是最后绘制的是再退化。而我是给了canvas保存这个4x4矩阵。所以相当于丢失矩阵信息了。
这是第一个bug。第二个bug也让我改的很痛苦。
看这个效果图
可以看到,第二张图在第一张图的下面。
而实际上,这两个图,每张图是一个layer。而且第二个layer,在blink里应该是在第一个之上的。
那么肯定,从blink到cc里,cc会在某个时刻调整这两个layer的绘制顺序。
这个点找了半天,终于在CalculateDrawPropertiesInternal这个极其复杂的函数的最下方找到。
这里可以看到对layer会进行重新排序。
而这个函数里面也非常复杂·····因为3D的重叠计算本来就很复杂,大意是检测变换之后的四边形的边界,看是怎么个交叉逻辑。不过这里谷歌偷懒了,两个layer可能会
交叉,而不是覆盖。
把相关代码LayerSorter移植到miniblink,终于把这两个bug给修复了,花了整整两天时间
于是赶紧调了下。原因很快就找到了,是我自己写的渲染层,对于layer的处理有问题。
详细来讲,是这样,blink在碰到这种3d网页,会开启硬件加速渲染模式,创建N个platform layer(平台相关层)。而这个 blink只负责告诉这些layer他们的位置、坐标变换,但具体怎么显示这些layer完全靠外部代码来实现,也就是说blink不管了。这也就是miniblink之所以搞了我这么久的原因,我完全自己撸了一个layer系统,而之前,这部分代码是chromium里的cc目录(cc的意思是chromium composition )实现的。
回到这个问题,这些3D 图形,导致blink创建的layer的坐标变换都是SkMatrix44的矩阵,这只是第一步,拿到矩阵后 ,还要考虑页面滚动、层的相对位置,再经过一系列运算才能得出层的屏幕位置。而这部分代码,在cc里,是一个超级复杂的函数来计算的:cc\trees\layer_tree_host_common.cc里的CalculateDrawPropertiesInternal。这个函数复杂到什么程度呢,光注释就100多行,整个函数超过1000行!整个函数的流程大概就是不挺根据各种坐标变换、位置等参数计算各种layer的真实位置之类的。之前也
研究过此函数,那时候就是为了把此函数精简,提取出一个最简化cc层真正需要的算法。但我之前的理解不够深刻,
看这个函数其中一个矩阵运算部分,这里combined_transform应该会得出屏幕坐标系的矩阵。而我的精简版cc层里,拿到这个矩阵后,复制给了绘制的canvas。这里我犯了一个错误,就是canvas最终接收到的矩阵,不是4X4,而是退化成3x3了。也不知道谷歌为啥要这样搞,总之这里就丢失了部分矩阵数据。而chromium里的是把一系列数据,包括这个矩阵,存在一个从顶层传下来的数据结构data_from_ancestor里(这样说明一下,CalculateDrawPropertiesInternal是个递归调用的函数,用来不停计算所有layer的数据),所以这个4x4的矩阵就没丢失精度,只是最后绘制的是再退化。而我是给了canvas保存这个4x4矩阵。所以相当于丢失矩阵信息了。
这是第一个bug。第二个bug也让我改的很痛苦。
看这个效果图
可以看到,第二张图在第一张图的下面。
而实际上,这两个图,每张图是一个layer。而且第二个layer,在blink里应该是在第一个之上的。
那么肯定,从blink到cc里,cc会在某个时刻调整这两个layer的绘制顺序。
这个点找了半天,终于在CalculateDrawPropertiesInternal这个极其复杂的函数的最下方找到。
这里可以看到对layer会进行重新排序。
而这个函数里面也非常复杂·····因为3D的重叠计算本来就很复杂,大意是检测变换之后的四边形的边界,看是怎么个交叉逻辑。不过这里谷歌偷懒了,两个layer可能会
交叉,而不是覆盖。
把相关代码LayerSorter移植到miniblink,终于把这两个bug给修复了,花了整整两天时间
相关文章推荐
- Android学习笔记(二九):嵌入浏览器
- 超过 77% 的桌面计算机运行基于 Chromium 的浏览器
- 微软发布令牌漏洞公告:可绕过 Chromium 沙盒执行任意代码
- 受 Mozilla 启发,苹果宣布更新 WebKit 反跟踪政策
- Apple宣布推出WebKit跟踪预防政策以保护用户隐私
- 详解JavaScript中的blink()方法的使用
- C#在WinForm中使用WebKit传递js对象实现与网页交互的方法
- android WebView组件使用总结
- 解决video标签在安卓webview下无法自动播放问题
- Android webview与js交换JSON对象数据示例
- android中WebView和javascript实现数据交互实例
- Android的webview支持HTML5的离线应用功能详细配置
- Android开发之WebView组件的使用解析
- Android中实现Webview顶部带进度条的方法
- Android WebView控件捕获用户输入的信息
- Android中访问证书有问题的SSL网页的方法
- 基于Android中Webview使用自定义的javascript进行回调的问题详解
- Android webview用法实例简析
- Android编程实现WebView自适应全屏方法小结
- Android编程使WebView支持HTML5 Video全屏播放的解决方法