Почему lockCanvas () работает медленно? - PullRequest
8 голосов
/ 16 мая 2011

Я реализую подкласс SurfaceView, где я запускаю отдельный поток для рисования на холсте SurfaceHolders.Я измеряю время до и после звонка на lockCanvas() и получаю от 70 до 100 мс.Кто-нибудь может указать мне, почему я получаю такие высокие сроки?Вот соответствующая часть кода:

public class TestView extends SurfaceView implements SurfaceHolder.Callback {

....

boolean created;
public void surfaceChanged(SurfaceHolder holder, int format, int width,
            int height) {

   mThread = new DrawingThread(mHolder, true);
   mThread.onWindowResize(width, height);
   mThread.start();
}

public void surfaceCreated(SurfaceHolder holder) {

    created = true;
}

public void surfaceDestroyed(SurfaceHolder holder) {
    created = false;

}
class DrawingThread extends Thread {
public void run() {
while(created) {



            Canvas canvas = null;
            try {
                            long t0 = System.currentTimeMillis();
            canvas = holder.lockCanvas(null);
            long t1 = System.currentTimeMillis();
                            Log.i(TAG, "Timing: " + ( t1 - t0) );
            } finally {
                holder.unlockCanvasAndPost(canvas);
            }
}

Ответы [ 3 ]

5 голосов
/ 09 августа 2011

Вы создаете нить каждый раз, когда изменяется поверхность. Вы должны начать свой поток в surfaceCreated и убить его в surfaceDestroyed. surfaceChanged для случаев, когда размеры вашей поверхности изменяются.

Из SurfaceView. SurfaceCreated Документы:

Вызывается сразу после первого создания поверхности. Реализация этого должна запускать любой желаемый код рендеринга . Обратите внимание, что только один поток может рисовать в Surface , поэтому вы не должны рисовать здесь, если ваш обычный рендеринг будет в другом потоке.

Несколько потоков, вероятно, приводят вас в тупик. Из SurfaceHolder. lockCanvas документы:

Если вы вызываете это несколько раз, когда Surface не готов (до Callback.surfaceCreated или после Callback.surfaceDestroyed), ваши вызовы будут замедляться с медленной скоростью, чтобы избежать использования ЦП. *

Однако я не уверен, что это единственная проблема. * На самом деле surfaceChanged вызывается несколько раз?

2 голосов
/ 07 августа 2013

Это связано с тем, как lockCanvas действительно реализовано в графической структуре Android.

Вы, вероятно, уже знаете, что lockCanvas вернет вам свободный фрагмент памяти, к которому вы будете обращаться. free означает, что эта память не использовалась для композиции и не для отображения. Внутренне, проще говоря, SurfaceView поддерживается двойным буфером, один для рисования, другой для композиции / отображения. Этот двойной буфер управляется BufferQueque. Если композиция / отображение медленнее, чем рисование, нам нужно подождать, пока у нас будет свободный буфер.

1 голос
/ 16 мая 2011
...