现象

总体而言,iOS 14 渲染性能变差,可以从以下三个测试看出。

测试1:
简单demo,使用egret引擎显示3000个图(都是同一个100*100 png 纹理),逐帧做旋转。(博客园视频播放可能有问题,视频地址:https://github.com/kenkozheng/kenkozheng.github.com/blob/master/WebGL/ios14/video/1.mp4?raw=true)

视频中,黑色机器是iOS14.0,白色是iOS13.7,都是iphone 7plus。

虽然从视频中来看,iOS 14的fps还要高一些,但实际上14明显卡顿。原因是:Egret检测的fps是web层面通过requestAnimationFrame得到的,实际上和画面渲染没有严格对等关系。

改为通过perfDog,从native层面看帧频,看到iOS14只有13fps,而旧版本有40+,这也解释了为什么肉眼看起来14的渲染要更卡顿。

测试2:
复杂demo,使用egret引擎显示candy爆炸龙骨动画100个。(博客园视频播放可能有问题,视频地址:https://github.com/kenkozheng/kenkozheng.github.com/blob/master/WebGL/ios14/video/2.mp4?raw=true)

和上边测试1类似,egret左上角的fps显示并不准确,通过perfDog检测,实际帧频只有7fps左右。

测试3:
在复杂demo基础上(还是100个爆炸动画),修改egret代码,禁用颜色混合shader,所有元素渲染都统一使用普通shader。
由于龙骨设定为24fps,而实际fps有40,从视频中肉眼无法看出卡顿。所以这里视频省去。

也是类似的情况,iOS14比iOS13渲染fps低,iOS14只有8fps左右,而iOS13有40+fps。

测试4:

使用自研的简单webgl引擎(min2d),显示15000个100*100的png。(博客园视频播放可能有问题,视频地址:https://github.com/kenkozheng/kenkozheng.github.com/blob/master/WebGL/ios14/video/3.mp4?raw=true)

情况和egret引擎类似,还是iOS14明显卡顿,虽然界面显示fps较大,但实际帧率只有10fps左右。题外话:自研引擎性能略比egret好10%左右,但上边测试中能支持15000个图片,只是因为自研引擎没有做像素密度加倍尺寸渲染。

由此可见,iOS14 webgl性能确实比iOS13有明显下降。

分析

从egret的监控来看,js层面的耗时(包括顶点计算、调用webgl)都没有明显问题,iOS14比iOS13甚至还有一些优化。但实际渲染帧频,iOS14又明显比iOS13更低,问题应该出于safari内部对webgl接口的具体实现上有一些改变。

调试过程中,发现两个比较奇怪的现象:

1、本来满帧运行,但运行一段时间后,会下降到40-50fps。

2、50个爆炸动画播放时能稳定在50fps,但增加到60个爆炸动画之后,fps会断崖式下跌,到14fps左右。

从这个现象,推测内部实现在显存管理上,可能出了较大变化,可能有一些缓存,数据达到阈值后,可能有反复的数据交换。

首先,排查了几个方面:

1、drawCall推送vertex buffer的方式(webgl.bufferData vs webgl.bufferSubData)

egret每次drawCall使用webgl.bufferData推送顶点数据,这个方法每次推送覆盖整个bufferData;而webgl.bufferSubData可以指定offset,只覆盖部分数据。

但由于每次修改的数据量并不多,两者从理论和实际测试来看,都没有区别。

2、推送纹理、webgl初始化设定(抗锯齿等)、frameBuffer

上述方面,egret的设置都属于通用做法,并没有特殊,而且调整了参数后,性能并没有提升。

3、去除shader的alpha计算

也没有明显变化

4、去除blendMode处理

虽然有明显的性能提升,但在iOS14上的性能提升并不比iOS13上的提升更大,blendMode并不是iOS14变慢的主要因素。

而且BlendMode是游戏素材制作的必需选项,影响到透明叠加效果,无法简单去除。

上述几个方面都没有找到解决方式。

另外,另外的游戏引擎cocos creator,官方提出在cocos引擎中使用了多次drawCall共享vertex buffer和index buffer的优化技术(也是常规的优化手段),但在iOS14中反而变成了性能瓶颈,已针对做了处理(针对iOS14,每次drawCall使用不同的vertex buffer)。

参考:

https://forum.cocos.org/t/ios-14-web/97808

https://github.com/cocos-creator/engine/pull/7415/files#

分析egret的实现,设置了默认每次drawcall最多同时批处理2048个元素,对于一般sprite来说,一个元素就等于一个图,等于一个长方形,等于两个三角形,也等于六个顶点。

进一步,egret在初始化时,会创建一个12288个unsigned short组成的index buffer,然后bindBuffer到GPU。这个过程一般只执行一次,后续不会再绑定,也不会再创建新的buffer(网格拉伸情况除外,会换一个indexbuffer数据内容)。

那么,每次drawcall时,无论是多少个元素,哪怕只有1个元素(6个顶点)都会使用这个12288长度的index buffer。

从这个角度来看,确实可能存在优化的可能。

引擎改进

从现象和分析过程得出,iOS14确实有性能下降,我们可以从一些维度,尽可能挽回一些性能下降。

目前确认可以从引擎层面改进的是index buffer问题。

改进的策略是:判断是否iOS14,如果是,就在每个drawcall前,推送新的index buffer和vertex buffer数据,这些数据只包括本次渲染所需,没有多余数据。

具体改动:

WebGLRenderContext的$drawWebGL方法中,判断是否Mesh绘制,在非Mesh绘制情况下,切分vao中的indices array和vertices array,取出本次drawcall所需部分,上传给gpu。而且,在这个情况下,drawData要忽略offset,改为固定的0(offset是对应vertex buffer中包含多次drawcall数据时才使用,现在每次按需推送,所以就不需要offset了)。

同样渲染50个爆炸龙骨动画,修改后的版本性能有明显提升。 如下图,左侧1分钟是原有版本下绘制50个爆炸龙骨动画的fps情况,右侧是优化后版本的fps情况。原有版本平均10fps,而优化后平均20fps(这个帧率可能和前边测试demo略有差异,是由于iphone渲染一段时间后变慢有关)。

index buffer的使用调整,确实能解决上述爆炸龙骨动画在iOS14的性能问题。

另外,排查过程中,还发现一些值得探索的方向:

1、带filter和不带filter的图元,如何批处理。egret引擎原来没有做批处理。如果能实现这个优化,将极大减少龙骨的渲染drawCall。

2、调整像素密度绘制策略。egret引擎默认以屏幕像素密度作为倍数绘制webgl画布,但游戏素材并没有这么大,这个扩大渲染对性能有影响,但视觉效果没有提升。

第2点,尤其可以针对低端机型,例如系统版本在6.x或以下的android,这部分机型本来性能就较差,但还可能按2-3倍像素去绘制webgl,渲染帧率就更低。

例如,oppo r9 系统版本5.1,屏幕像素密度3,强制以密度1绘制,性能能够提升30%。

除上述提到的方向外,针对iOS14,可能还存在更多针对性优化的方向,但还需要针对具体的场景,逐个分析。

性能结论

iOS14对比iOS13和以前版本,在webgl渲染性能上有明显下降,尤其在drawcall次数较大、渲染面积较大或使用较多颜色混合滤镜情况下,下降尤其明显。

针对iOS14,虽然能在一些方面改善性能,但单纯从js角度,无法让webgl渲染性能恢复到iOS13的水平,只能寄望于苹果官方自行修复底层问题(已有不少反馈到苹果论坛)。

素材开发建议

除了从引擎底层解决iOS14卡顿问题,另外,针对游戏业务素材,还可以做一些改动,提高渲染性能:

1、减少龙骨动画层级,减少图元个数;

2、避免使用颜色混合和BlendMode(混合模式);

3、避免使用有大面积透明区域的图片,可以把图片切分为只有有效内容的多个小图。

另外,iOS14在js层面监控到的帧频不是真正的webgl渲染帧频,性能优化需要直接连接perfDog做监控。

iOS 14 egret 游戏卡顿问题分析和部分解决办法的更多相关文章

  1. H5:加载原理,慢加载和卡顿原因分析,

    前端H5工作原理: 请求和显示原理 H5页面卡顿原因分析: 1.动画太多:渲染重绘占用GPU 2.页面操作导致重绘频繁 3.页面元素复杂:资源类标签太多(图像/视频/dom树太长) 4.内置webvi ...

  2. 基于webstorm卡顿问题的2种解决方法

    基于webstorm卡顿问题的2种解决方法:https://www.jb51.net/article/128441.htm

  3. android studio 一直卡在Gradle:Build Running的解决办法

    转:android studio 一直卡在Gradle:Build Running的解决办法   在使用AS开发安卓应用程序的时候经常会遇到Gradle build running一直在运行甚至卡死的 ...

  4. ios iphone ipad上iframe的宽度会扩大的解决办法

    这个问题,我从网上查了下,好像是属于ios的bug,android,windows都没有问题. 解决办法,就是在iframe加载完成后,设置 iframe里面body的宽度为多少PX. $(" ...

  5. Android中app卡顿原因分析示例

    在知乎回答了一个“为什么微博的app在iPhone比Android上流畅”的问题.后面部分是一个典型的动画卡顿的性能分析过程,因此帖在这里.有编程问题可以在这里交流.知乎链接. =========== ...

  6. ios添加-webkit-overflow-scrolling依然卡顿

    项目由vue-cli2创建 在overflow: auto区域内滑动ios手机出现卡顿,搜索资料后添加-webkit-overflow-scrolling: touch ios bug: 1.滑动区域 ...

  7. 【bug清除】Surface Pro系列使用Drawboard PDF出现手写偏移、卡顿、延迟现象的解决方式

    最近自己新买的New Surface Pro在使用Drawboard PDF时,出现了性能问题,即笔迹延迟偏移,卡顿的问题. 排查驱动问题之后,确认解决方案如下: 将Surface的电池调到性能模式, ...

  8. DEDE织梦 后台特别卡,有时响应超时的解决办法

    跟大家一样,大致情况是: 1.打开后台首页第一次没问题,但是刷新或者点其他菜单就一直卡着了. 2.关掉浏览器重新进首页没问题,但是一旦进了首页再打开php页面就卡死了. 3.服务器返回Maximum ...

  9. ios 页面过长卡顿的情况

    解决方案如下: -webkit-overflow-scrolling: touch;

随机推荐

  1. Java源码赏析(六)Java String 三顾

    在大致了解了String之后,可能有的读者发现了,我们并没有谈到CharSequence接口. 原因是在这一节,CharSequence要和StringBuilder(Java1.5).StringB ...

  2. Oracle添加键值对盲注

    前言 遇到一种注入点,存在于POST参数中,却不能用sqlmap扫出: 分析 request参数格式: %24Q_value1=test1&orderCol=&order=+ASC+& ...

  3. 自定义带边框TextView--边框粗细不一的问题

    自定义带边框TextView 给textview加边框 最low的做法.textview外层套一层布局,然后给布局加边框样式(这么弱的做法,不能这么干) 自定义控件 canvas.drawLines ...

  4. Spring AOP系列(二) — 动态代理引言

    接上一篇Spring AOP系列(一)- 代理模式,本篇来聊聊动态代理. 动态代理与静态代理的区别 要想了解动态代理与静态代理的区别,需要有两个前置知识点:java程序是如何执行的以及类加载机制. j ...

  5. 编程体系结构(05):Java多线程并发

    本文源码:GitHub·点这里 || GitEE·点这里 一.多线程导图 二.多线程基础 1.基础概念 线程是操作系统能够进行运算调度的最小单位,包含在进程之中,是进程中的实际运作单位.一条线程指的是 ...

  6. unity 3d 三、空间与运动

    3D游戏编程第三次作业 简答并用程序验证[建议做] 游戏对象运动的本质是什么? 游戏对象运动的本质是游戏对象Position.Rotate.Scale属性数值的变化. 请用三种方法以上方法,实现物体的 ...

  7. NMOS和PMOS区别

    在很多电路途中会出现NMOS和PMOS管,因为不是中文那么直接,都说管压降之类的,但其实它的导通很重要以及区别,关系到你点亮电子元件> 参考: 1.https://blog.csdn.net/l ...

  8. P4821 [中山市选]生成树

    题目链接 我们可以看一下题目中给的这张图. 首先,树是没有环的,所以我们要把所有的环上的边都删去一条. 我们可以现在每个五边形上删去一条边. 但删完之后我们会发现,里面还有一圈. 这时候,我们就要在这 ...

  9. .NET Standard 简介

    系列目录     [已更新最新开发文章,点击查看详细] .NET Standard 是一套正式的 .NET API 规范,有望在所有 .NET 实现中推出. 推出 .NET Standard 的背后动 ...

  10. IOS使用UITextView进行富文本编辑|纯干货

    看了好多blog介绍富文本编辑,有很多很好的开源项目,比如:YYText.FastTextView.ZSSRichTextEditor等等.本着学习的目的还是选择用UITextView来实现简单的富文 ...