前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >miniblink修复3D变换的两处渲染Bug

miniblink修复3D变换的两处渲染Bug

作者头像
龙泉寺扫地僧
发布2019-02-20 14:55:59
5140
发布2019-02-20 14:55:59
举报
文章被收录于专栏:盟主来了盟主来了

情况是这样的,有个群友让我试了下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给修复了,花了整整两天时间

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2016年06月06日,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档