收藏
回答

Canvas.getContext执行不符合预期, 执行后偶尔发生间歇性卡顿现象

框架类型 问题类型 API/组件名称 终端类型 微信版本 基础库版本
小游戏 Bug Canvas.getContext 微信安卓客户端 7.0.10 2.10.1

Wechat Lib 2.10.1

getContext相关代码:

const glInstance = canvas.getContext('webgl', {

preserveDrawingBuffer: true,

antialias: false

})

const ctxAttrs = glInstance.getContextAttributes()

console.info('gl context attr antialias:', ctxAttrs.antialias)

console.info('gl context attr preserveDrawingBuffer:', ctxAttrs.preserveDrawingBuffer)

在开发工具中(打印):

gl context attr antialias: false

gl context attr preserveDrawingBuffer: true


在微信7.0.10, android(华为honor, 荣耀8青春版4G+32G)平台上(打印):

gl context attr antialias: false

gl context attr preserveDrawingBuffer: false


偶尔出现卡顿:

现象: 每隔20sec左右, 卡顿720ms左右

概率: 偶尔。有时连续重启几次游戏都不发生, 有时连续重启几次游戏都发生。

备注: 在调用getContext后,只要卡顿一次, 则之后每隔20sec左右卡顿720ms左右; 如果隔大约20sec后没发生卡顿,则不会再出现隔20sec卡顿现象。

卡顿期间目测“性能数据”面板:卡顿发生时native-heap断崖式增,接着断崖式减少(变动有时超过8M)。

空逻辑代码示例:

let lastMs = Date.now()

const oriMs = Date.now()

function tick() {

const now = Date.now()

if (now - lastMs > 200) {

console.error('tick elapse:', now - lastMs)

}

lastMs = now

if (now - oriMs > 42000) {

// 离开空逻辑测试

} else {

requestAnimationFrame(tick)

}

}

tick()


在微信7.0.10, android(华为麦芒5)平台上(打印):

gl context attr antialias: false

gl context attr preserveDrawingBuffer: false

未发现隔20sec卡顿现象


在微信7.0.10, android(红米6)平台上(打印):

gl context attr antialias: false

gl context attr preserveDrawingBuffer: false

未发现隔20sec卡顿现象


针对卡顿现象的尝试和分析:

  1. getContext函数调用前未发现卡顿现象,执行后偶尔发生卡顿现象(如上述);
  2. 尝试过用setTimeout和setInterval替换requestAnimationFrame, 结果还是卡顿;
  3. 尝试过gl.finish 和 gl.flush, 也没用;
  4. 通过cpu profile分析, 有如下情况(第1种情况概率高):

1) 卡顿时_vsync和卡顿时间接近,非卡顿时_vsync正常;

2) 卡顿时随机一个函数执行时间和卡顿时间接近, 非卡顿时正常。

疑问:

  1. preserveDrawingBuffer属性是不是android平台无效?
  2. 为什么空逻辑也会卡顿, 是不是用法不对?

有感:

  1. 感觉不像游戏业务层的GC问题(空逻辑也会发生卡顿);
  2. 感觉不像游戏业务层webgl的使用问题(空逻辑也会发生卡顿);
  3. 感觉和渲染引擎无关, 测试过渲染引擎启动前卡顿情况(同样卡顿)。

总结:

  1. 卡顿是否可能发生, 和getContext是否调用有关;
  2. 即使空逻辑也可能卡顿;
  3. 卡顿不是必现;
  4. preserveDrawingBuffer在所测试平台上无效。
回答关注问题邀请回答
收藏

2 个回答

  • 叶轩
    叶轩
    2020-02-11

    preserveDrawingBuffer属性是不是android平台无效?

    是的,目前preserveDrawingBuffer Android上不支持


    为什么空逻辑也会卡顿, 是不是用法不对?

    在极低概率下会有一些内部检测逻辑


    2020-02-11
    有用
    回复 2
    • biehs
      biehs
      2020-02-11
      请问怎么避免这个极低概率呢?
      2020-02-11
      回复
    • biehs
      biehs
      2020-02-11
      这些检测逻辑检测的内容是什么,有没有可能,在业务层通过逻辑规避?
      发现把canvas.width放大sysInfo.pixelRatio倍和2倍卡顿时间不一样, 放大sysInfo.pixelRatio倍卡顿1.5sec, 放大2倍卡顿720ms左右。sysInfo.pixelRatio测试机上是3。
      2020-02-11
      回复
  • 黄勇强
    黄勇强
    2020-09-28

    这个问题一直存在,帧率不稳定.

    Redmi Note 8 Pro也存在这个问题.

    出现的现象一模一样.

    2020-09-28
    有用
    回复
登录 后发表内容
问题标签