繁体   English   中英

旋转画布和绘图位图的性能

[英]Rotating canvas and drawing bitmap performance

我正在尝试制作一个游戏,使行星位于用户屏幕的中心,并像行星一样缓慢旋转。.因此,我首先决定测试一下它是否可以正常工作,但不能正常工作。像这样的简单“行星”图像:

Bitmap image = BitmapFactory.decodeResource(getResources(),R.mipmap.totone);

我也有一个存储角度的变量。 然后在绘图功能中,我只是旋转画布,绘制行星(现在已旋转),然后将画布旋转回去。 像这样:

//the planet's image is 512x512px
canvas.rotate(ang,256,256); //256, 256 is the center of rotation
canvas.drawBitmap(image, 0,0, null);
canvas.rotate(-ang,256,256); //rotate back

我不知道为什么,但是当图像旋转90度和270度时,游戏fps会降低一点? 我做了一点gif来显示问题。 fps一直都是完美的60,但随后几毫秒就下降到50ish了吗? 是什么原因造成的? 我试图将线程的目标fps更改为30,然后看起来没有fps下降。。所以这可能是性能问题。 请注意,我尝试使用不同的方法旋转位图,但fps下降效果仍然相同。

Gif

这很可能是设备的固定屏幕刷新率与以特定角度绘制位图所需时间的微小变化之间的相互作用。

我猜想你在onDraw()中将ang增加一个恒定的数量。 这个事实可以用来解释转速的急剧变化。

说明

您的设备以60Hz刷新屏幕。 这意味着在理想条件下onDraw()最大调用频率为60Hz:大约每16.7ms调用一次。

假设onDraw()需要大约15毫秒的时间来执行。 剩下1.7毫秒; 一切安好! 您将获得一个流畅,平滑的60Hz旋转。

然后假设,在ang某些值处, onDraw()花费的时间稍长一些; 比方说18毫秒 (我将推测为什么drawBitmap()的执行时间会随瞬间的角度而变化。现在,让我们看一下这18ms的绘制时间会发生什么。)

理想情况下, onDraw()的调用频率为60Hz。 但是现在你花太长时间了; 超过1个周期。 现在, 合成器必须从您的应用程序中删除帧,因为您无法提供足够快的帧! 因此,现在只能每33.4ms调用一次onDraw() ,而不是每16.7ms执行一次。

换句话说,屏幕硬件以恒定速率刷新,并且当您的onDraw()超过该16.7ms阈值时,您的更新速率将精确地减半。

这是在您的GIF中暗示的。 显示的帧速率从60变为51,但是对我来说,很明显实际旋转速率几乎下降了50%。 我怀疑差异仅是由于您计算显示帧速率的方式造成的。

drawBitmap()执行时间中的变化的规范化

可能是处理器的缓存性能。 在某些旋转角度下,图形逻辑可能以对L1缓存/预取逻辑不理想的方式访问位图内存。 换句话说,从这些角度来看,您可能会遇到很多缓存未命中的情况。

推荐的可玩性修复

  1. 使用更快的图形管线,例如OpenGL,和/或:
  2. 基地ang在一次黑客( uptimeMillis()而不是一个增量。 您仍然会丢帧,但视在旋转速率将得到纠正。
  3. 如果您想发疯,则可以提供第二个位图,该位图会与第一个位图预先旋转90度,并使用该位图进行以接近90/270度的角度进行绘制。 如果我对高速缓存未命中的判断是正确的,则可以缓解此问题。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM