专栏首页盟主来了miniblink修复3D变换的两处渲染Bug

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

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

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 18.3.17日报

    5,修复cookie路径问题。COOKIEJAR这个curl宏的意思是存cookie。如果先调用这玩意,会导致cookie.data被清空

    龙泉寺扫地僧
  • 18.1.1日报

    1,修复汤不热点击用户头像崩溃的bug,原因是weblayerimpl用到的m_scrollParent在析构时没通知父节点。现在把这个成员变量删了算了,反应暂...

    龙泉寺扫地僧
  • 史上最小巧的blink+cc(硬件合成层)出炉

    发现其实cc依赖的不多,也就稍微用到了base目录下的,连content层都没怎么用到。

    龙泉寺扫地僧
  • circos 可视化手册-tile 篇

    tile用来展示基因组上区域的分布,和之前介绍过的highlight不同,这些区域在图中并不是位于同一层的。为了避免不同区域之间的重叠,tile会将有重叠的区域...

    生信修炼手册
  • CAGradientLayer颜色渐变器

    下面是我用上面的代码实现的最终效果,startPoint是(0,0),endPoint是(1,1)。

    周希
  • node.js中this指向失效解决

    原因:虽然类默认的方法指向类的实例,但是如果在外部单独使用该方法,this会指向该方法运行时所在的环境,不再指向对象

    雪山飞猪
  • Layer弹层组件

    前几天了解到这个不错的弹层插件,样式好看,用起来也方便。喜欢的人看完我的博客也可以看官方网站哦:http://www.layui.com 在这个官方网站里有关于...

    benny
  • Pytorch 各种奇葩古怪的使用方法

    不间断更新。。。 增减layer 增加layer 增加layer很方便,可以使用model.add_module('layer name', layer)。 ...

    marsggbo
  • linux下查看磁盘分区的文件系统格式 原

    Filesystem Type 1K-blocks Used Available Use% Mounted on /dev/sda1 ext4 2064242...

    拓荒者
  • (三十一)c#Winform自定义控件-文本框(四)

    GitHub:https://github.com/kwwwvagaa/NetWinformControl

    冰封一夏

扫码关注云+社区

领取腾讯云代金券