【问题标题】:Low FPS with android SurfaceView使用 android SurfaceView 的低 FPS
【发布时间】:2011-11-28 12:10:53
【问题描述】:

我在使用 SurfaceView 的帧率方面存在一些问题。我正在做我在一些教程中找到的典型内容(所有教程都说相同),但我无法在我的三星 Galaxy S(旧版 i9000)上达到不错的帧速率。

这是我用于循环线程的代码。 FPS 初始化为 30。

@Override
public void run() {
    long ticksPS = 1000/FPS;
    long startTime;
    long sleepTime;
    //fps checker
    long contms=0;
    long lasttimecheck = System.currentTimeMillis();
    int fps=0;
    while (running) {
        long time =  System.currentTimeMillis();
        if(contms>1000) {
            Log.v("FPS",String.valueOf(fps));
            contms=time-lasttimecheck;
            fps=1;
        }
        else {
            fps++;
            contms+=time-lasttimecheck;
        }
        lasttimecheck = time;

        Canvas c = null;
        startTime =time;
        try {
            c = view.getHolder().lockCanvas();
            synchronized (view.getHolder()) {
                view.onDraw(c);
            }
        } finally {
            if (c != null) {
                view.getHolder().unlockCanvasAndPost(c);
            }
        }
        sleepTime = ticksPS-(System.currentTimeMillis() - startTime);
        try {
            if (sleepTime > 10)
                   sleep(sleepTime);
            else {
                Log.w("LOWFPS",String.valueOf(contms));
                sleep(10);
            }
     } catch (Exception e) {}
    }
}

在surfaceView中,我用holder.setFormat(PixelFormat.RGBA_8888);但我不知道我是否必须对位图做一些事情以避免无用的 CPU 工作(我将位图保存在局部变量中,然后绘制它们)。游戏很简单,应该跑得更快。

帧率很随机,有时可以流畅,有时不行,但总是在30FPS以下。

有什么想法吗???

用 ONDRAW 解释编辑

@Override
protected void onDraw(Canvas canvas) {
    canvas.drawBitmap(bg, 0, 0, null); //1
    stars.draw(canvas,dx,dy);      //2
    if(playing.on()) reactors.draw_reaccio(canvas,dx,dy); //3
    gotes.draw(canvas,dx,dy);     //4
    reactors.draw(canvas,dx,dy);  //5
    sg.draw(canvas);  //6         
    sr.draw(canvas);  //7
    eraser.draw(canvas);  //8
    playing.draw(canvas); //9
    opcions.draw(canvas); //10
}

1) 绘制背景 (480x800) 2)这是一个包含“getHeight()”基本对象(星)列表及其坐标(x,y)和相关图像的ID(大约9个不同的星图像)的类 3)它绘制n * 2个圆圈,一个带有填充,另一个带有每个相关对象的描边(大约20个左右) 4)它绘制了游戏的主要对象,带有动画的小水滴。有 9 种不同的水滴,每一种都有 5 个相关的动画图像(我应该把 5 个图像放在 1 个中吗?) 5) 与 drop 相同但没有动画 6到10)无关紧要,它只是画一个图像

我猜缓慢的原因是:(2)因为星星的数量(4)因为动画,女巫每 2-3 帧改变一次不同的图像,也许这对记忆来说太多了,我猜我应该将所有图像合并到 1 个中。

S. Galaxy S i9000 帧率约为 20-22 FPS

【问题讨论】:

  • 我在全新的 Galaxy Nexus 上遇到了类似的问题。我的应用大量使用 SurfaceView,并且在其他所有设备上都可以正常工作。在 ICS 上它无法使用,即使在设置中强制硬件加速也是如此。
  • 您可以发布绘图代码本身吗?要确定应用的时间/CPU 密集型部分,请使用 TraceView:developer.android.com/guide/developing/debugging/…
  • 请把全班贴出来,否则没人能明智地分析你的代码流。
  • 原来我有一个不同的问题。如果位图经常更改,则启用了 hardwareAcceleration(默认在 ICS 上)的 SurfaceViews 会变慢。

标签: android bitmap surfaceview frame-rate


【解决方案1】:

如果你禁用绘图,你能达到多少 fps? 只是为了检查显示管道占用了多少。

我曾尝试关注 创建 5 个大小为 720 x 480 的位图:像素格式 RGB565 从类似于您的循环中将它们显示在 SurfaceView 上。 唯一的区别是我已经“准备好位图”并且没有在循环中绘制它们。 这是在 Nexus-S 手机上实现的

FPS : 55(我试图以最快的速度运行循环,没有调节)

CPU 负载:85%

这是我决定从 JNI 渲染我的 SurfaceView 的时候 :) !!

做一个类似的实验,看看你的设备在“没有”绘图操作的情况下能够节流多少。如果它看起来不错,那么您可以分析您是否可以在预算范围内适应您的绘图操作。

【讨论】:

  • 我实际上遇到了一个不同的问题,但我会奖励你,因为这可能是解决原始海报问题的最佳方法。
【解决方案2】:

需要考虑的事项:您的日常绘画需要多长时间?

如果您在 30 FPS 下运行时遇到问题,我会重新考虑让它休眠。这不是一个确切的东西,根据 API 可以睡得更少或更多,所以我现在会删除它,让它尽可能快地运行。

我同意上述观点,请发布绘图代码或在调用绘图例程时将其注释掉,然后查看您运行的 FPS。

一般来说,从采样的角度来看,如果仅测量超过 1 秒,您可能会看到它的值抖动。

许多绘图后端仅适用于 60 的偶数除数。因此,如果您做很多事情,可能一两个额外的调用将使您从 60/1 = 60 fps 提高到 60/2 = 30 fps。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-01-14
    • 1970-01-01
    • 2012-08-08
    • 2019-06-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多