lockCanvas() 真的很慢
在较慢的设备(Orange San Francisco,又名 ZTE Blade)上测试我的游戏,我得到了令人震惊的帧速率。
我将一些调试代码放入绘图循环中,发现以下行花费了 100 毫秒以上:
c = mSurfaceHolder.lockCanvas();
还有其他人看到过这种行为吗?我通过扩展 View 并实现 onDraw() 暂时替换了 SurfaceView,并且获得了更好的帧速率。
虽然总的来说,SurfaceView 在我的 HTC Desire 上要快得多。我怀疑这可能是 Android 2.1 的问题。我正在考虑对手机进行 root 并在可能的情况下将其升级到 2.2,但我确实希望设备运行在 2.1 上,因此从长远来看,这可能会适得其反。
**更新**
我一直在研究这个问题,并发现了一些更令人费解的方面。
我root了手机并安装了2.2,问题仍然存在。当应用程序首次启动时,lockCanvas 按预期工作(0-1 毫秒)。然后在我初始化期间的某个时刻,lockCanvas 突然开始花费大约 100 毫秒。
可能值得指出的是,我正在异步任务中加载资源,以便我可以显示加载屏幕。
尽管我尽最大努力确定程序在发生缓慢时实际在做什么,但我无法做到这一点。事实上,当我在调试模式和单步模式下运行它时,它运行得很快!
现在我发现,如果我在 SurfaceView 的构造函数中添加延迟(大约 10 秒),则不会出现缓慢情况,并且一切正常。
但是,如果您按 Home,然后切换回来,速度又会变慢。
对于这个愚蠢的、不合逻辑的问题,我几乎束手无策了!我想把它归结为设备特定的问题。
我觉得这可能与内存使用有关。也许某些东西被替换并且影响了视频内存?
我至少对理论感兴趣。
Testing my game on a slower device (Orange San Francisco aka ZTE Blade) and I have been getting an appalling frame rate.
I put some debug code into the draw loop and discovered the following line is taking over 100ms:
c = mSurfaceHolder.lockCanvas();
Anyone else seen this behaviour? I temporarily replaced the surfaceview by extending View and implementing onDraw(), and I got a much better framerate.
Although in general surfaceView is much faster on my HTC Desire. I am suspicious this may be a Android 2.1 problem. I'm contemplating rooting the phone and upgrading it to 2.2 if possible, but I did want a device running on 2.1 so that might be counter-productive in the long run.
** update **
I've been working on this some more, and have discovered some more puzzling aspects to it.
I rooted the phone and installed 2.2 and the problem still happens. When the app is first started, the lockCanvas is working as expected (0-1 ms). Then at some point during my initialisation, lockCanvas suddenly starts taking approx 100ms.
It might be worth pointing out that I am loading my assets in an Async task, so that I can display a loading screen.
Despite my best efforts to pin down what the program is actually doing when the slowness occurrs I was not able to do so. In fact when I run it in debug mode and single step, it works fast!
Now I discovered that if I add a delay in the constructor of my SurfaceView (of about 10 seconds), the slowness doesn't occur and all works fine.
However if you press Home, and then switch back, the slowness comes back.
I'm pretty much at the end of my tether on this stupid illogical problem! I've got a mind to put it down to a device specific problem.
I feel it could have something to do with memory usage. Maybe something is being swapped out and it affects the video ram?
I'd be interested in theories at least.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
关于文档中的 lockCanvas() :
对于某些设备,您的绘制循环是否可能启动得太早?我认为这就是问题所在,因为您写道:
About lockCanvas() from docs:
Is it possible that your draw loop is initiated too early for some devices? I think this is the problem, since you wrote:
那么,也许我们可以使用holder.isCreating()来检查状态?
如果画布仍在创建,此方法将返回 true。
像这样的东西
while(holder.isCreating()) {}
可以=holder.lockCanvas();
但我现在有点困惑。据我所知,当创建表面视图时,会调用 colbeck。我们应该实现 SurfaceHolder.Callback 接口。以及表面创建时的回调方法
public void surfaceCreated(SurfaceHolderholder) { } 将被调用。
从 surfaceCreated 方法我正在启动游戏循环线程。
So, maybe we could use holder.isCreating() to check state?
this method will return true if canvas still creating.
Something like
while(holder.isCreating()) {}
can=holder.lockCanvas();
But I'm a bit confuse now. As i know colbeck is called when a surfaceview is creates. We should implement SurfaceHolder.Callback interface. And when surface is created callback method
public void surfaceCreated(SurfaceHolder holder) { } will be called.
From surfaceCreated method I'm starting gameloop thread.
我最近发现,如果使用大位图在画布上绘制并且这些位图存储在活动类中 - “_surfaceHolder.lockCanvas()”命令本身需要很长时间(大约 70 毫秒,具体取决于设备)。但是,将这些位图存储移动到其他类(在不同的文件中,例如 MY_DATA),并且该活动仅引用该新类 - 解决了问题。
我对这种现象没有任何解释。
I have recently discovered that if large bitmaps are used to draw on the canvas and these bitmaps are stored in the activity class - the "_surfaceHolder.lockCanvas()" command itself takes very long (about 70ms depending on device). HOWEVER, moving these bitmaps storage to other class (in different file, say MY_DATA), and the activity has just a reference to that new class - solves the problem.
I'm have no explanation to this phenomenon.
我在使用
Canvas
绘图时遇到了同样的神秘问题,但通过将Canvas
绘图更改为在SurfaceView
上绘图来解决它。但现在我的lockCanvas()
调用一直很慢。这是我的观察结果。
问题仅出现在某些设备上:
我还注意到,三星手机使用
GLES20Canvas
而不是常规的Canvas
以及 < code>onDraw() 绘图,因此性能更好。I was encountered the same mysterious problem with
Canvas
drawing, but solved it by changingCanvas
drawing to drawing on theSurfaceView
. But now I have constantly slowlockCanvas()
call.Here is my observation results.
Problem is only present on some devices:
I also noticed, that Samsung phones using
GLES20Canvas
instead of regularCanvas
withonDraw()
drawing, as a result, better performance.