SurfaceHolder.lockCanvas () слишком дорогой - PullRequest
3 голосов
/ 05 января 2012

Каждый раз, когда я вызываю эти методы, требуется 14-20 мсек.

Canvas canvas = holder.lockCanvas();
holder.unlockCanvasAndPost(canvas);

Это нормальное поведение? Стоит ли использовать другой подход?

Вот весь код

public class Render extends SurfaceView {
    Context c = null;
    SurfaceHolder holder;
    volatile boolean running = true;

    public Render(Context c) {
        super(c);
        this.c = c;
        this.holder = getHolder();
    }

    public void run() {
        if(running) { 
            if(!holder.getSurface().isValid()){
                System.out.println("not valid");
                return;          
            }

            Canvas canvas = holder.lockCanvas();
            holder.unlockCanvasAndPost(canvas);

        }
    }
}

Трассировка:

01-05 15: 49: 20.322: I / System.out (4892): время кадра: 0 мс frame291
01-05 15: 49: 20.322: I / System.out (4892): недействительно
01-05 15: 49: 20.322: I / System.out (4892): время кадра: 0 мс frame292
01-05 15: 49: 20.332: I / System.out (4892): время кадра: 2 мс frame293
01-05 15: 49: 20.357: I / System.out (4892): время кадра: 22 мс. Frame294
01-05 15: 49: 20.357: I / System.out (4892): время кадра: 1 мс frame295
01-05 15: 49: 20.362: I / System.out (4892): время кадра: 1 мс frame296
01-05 15: 49: 20.367: D / CLIPBOARD (4892): скрыть диалоговое окно буфера обмена при запуске ввода: завершено кем-то другим ...!
01-05 15: 49: 20.367: I / System.out (4892): время кадра: 8 мс frame297
01-05 15: 49: 20.377: I / System.out (4892): время кадра: 10 мс frame298
01-05 15: 49: 20.397: I / System.out (4892): время кадра: 16 мс frame299
01-05 15: 49: 20.412: I / System.out (4892): время кадра: 16 мс фрейм 300
01-05 15: 49: 20.427: I / System.out (4892): время кадра: 16 мс frame301

UPDATE


То же самое происходит, когда я использую OpenGL
package android.apps.td;

import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.opengles.GL10;

import android.content.Context;
import android.opengl.GLSurfaceView;
import android.opengl.GLSurfaceView.Renderer;

public class Render extends GLSurfaceView implements Renderer {

    private final int MILLION = 1000000;
    private long frame;

    public Render(Context context) {
        super(context);
        setRenderer(this);
        // TODO Auto-generated constructor stub
    }

    public void onDrawFrame(GL10 arg0) {
        System.out.println("Frame "+(System.nanoTime()-frame)/MILLION+" ms");
        frame = System.nanoTime();
    }

    public void onSurfaceChanged(GL10 gl, int width, int height) {
        System.out.println("Surface changed w:"+width+" h:"+height);
    }

    public void onSurfaceCreated(GL10 gl, EGLConfig config) {
        System.out.println("Surface created");
    }
}

Ответы [ 2 ]

2 голосов
/ 07 января 2012

Я обнаружил эту статью: http://replicaisland.blogspot.com/2009/10/rendering-with-two-threads.html

eglSwapBuffers (), вероятно, вызывается после onDrawFrame и блокируется до тех пор, пока аппаратное обеспечение не завершит рисование, а затем не заменит буферы, что занимает минимальную задержку 16,67 мс.

0 голосов
/ 28 апреля 2012

Я сам изучал эту проблему.На Galaxy Tab GT-P7500 я обнаружил, что

  • Минимальное время между парами unlockCanvasAndPost + lockCanvas составляет 1/60 секунды или 17 мс.
  • Однако выможет выполнять до 6 мс работы, а частота кадров будет оставаться на уровне 60 кадров в секунду.
  • Минимальное время, необходимое для переворачивания страницы (unlockCanvasAndPost + lockCanvas), составляет около 3 мсек.
  • Выше 6 мсработы функция lockCanvas () МОЖЕТ ввести дополнительную задержку, которая понижает частоту кадров до 40 кадров в секунду, 30 кадров в секунду, 20 кадров в секунду или 15 кадров в секунду.В худшем случае переворот страницы может занять больше 1/60 секунды.Например, если вы выполняете 48 мсек работы на кадр (когда вы добавляете 3 мсек для переворачивания страницы, это не достаточно быстро для 20 кадров в секунду), переворот страницы тратит 19-20 мс, чтобы снизить частоту кадров до 15кадров в секунду.При скорости ниже 15 кадров в секунду переворот страницы может занимать 17 мсек последовательно.
  • Это явление не всегда происходит.Наблюдая за этим поведением в эталонном тесте, я создал отдельное действие для дальнейшего изучения, и в этом специальном упражнении явление не произошло.До сих пор я не смог выяснить разницу между моим исходным тестом и новым: оба они рисуют кадры на SurfaceView в рабочем потоке, но во втором упражнении переворот страницы занимает 3 мс последовательно, а впервое, перелистывание страницы занимает 3 мс вначале, но внезапно возрастает примерно через полсекунды, максимум до 20 мс в устойчивом состоянии.
  • Подключение к сети питания не имело значения.
...