Estoy trabajando en un fondo de pantalla en vivo con un fondo de desplazamiento. Tengo dos objetos de mapa de bits que alternar entre ellos para mantener los píxeles dibujados previamente para el siguiente fotograma. Dibujé una nueva línea en la parte superior del lienzo, luego llamé a drawBitmap para copiar el resto de los píxeles en el lienzo.Canvas.drawBitmap() se ralentiza intermitentemente, causando flashes blancos
Estoy usando un objeto Runnable para hacer el trabajo pesado. Realiza todas las copias y los cálculos necesarios y luego bloquea el lienzo, ingresa un bloque síncrono en el soporte y realiza una única llamada a Canvas.drawBitmap (mapa de bits, rect, rect, pintura). Ocasionalmente, aparecerá un destello blanco en la pantalla, que parece correlacionarse con una actividad alta de la CPU. Al usar traceview, descubrí que la operación drawBitmap, específicamente Canvas.native_drawBitmap(), está tardando mucho más de lo normal. Normalmente se completa en 2-4 mseg, pero cuando veo un destello blanco, puede tomar de 10 a 100 mseg.
private void draw() {
SurfaceHolder holder = getSurfaceHolder();
Canvas canvas = null;
prepareFrame();
try {
canvas = holder.lockCanvas();
synchronized (holder) {
if (canvas != null) {
drawFrame(canvas);
}
}
} catch (Exception e) {
e.printStackTrace();
} finally {
if (canvas != null)
holder.unlockCanvasAndPost(canvas);
}
afterDrawFrame();
handler.removeCallbacks(drawRunner);
if (visible) {
handler.post(drawRunner);
}
}
La función draw()
se llama en el run()
del Ejecutable.
private void prepareFrame() {
num++;
if (num%2 == 0) {
mainBmp = mainBmp1;
mainCan.setBitmap(mainBmp1);
mainCan.drawBitmap(mainBmp2, source, destination, null);
} else {
mainBmp = mainBmp2;
mainCan.setBitmap(mainBmp2);
mainCan.drawBitmap(mainBmp1, source, destination, null);
}
}
La función prepareFrame()
es cómo mantener la suspensión de los píxeles anteriores que he dibujado. La fuente Rect called tiene una fila menos de pantalla completa en la parte inferior, donde el destino es una fila corta en la parte superior. Las llamadas drawBitmap()
en prepareFrame()
nunca son más largas que 2-4msec.
private void drawFrame(Canvas can) {
can.drawBitmap(mainBmp, source, destination,null);
}
Esta operación individual se realiza en el lienzo mientras se mantiene el bloqueo.
private void afterDrawFrame() {
ca.calcNextRow();
mainBmp.setPixels(ca.getRow(), 0, canWidth, 0, 0, canWidth, 1);
}
Luego, la siguiente fila de píxeles se dibuja en uno de mis bitmaps en la memoria.
He intentado usar las diversas firmas de drawBitmap()
pero solo las he encontrado más lentas en promedio y todavía resulta en los destellos blancos anómalos.
Mi velocidad general es excelente. Sin los flashes intermitentes, funciona realmente bien. ¿Alguien tiene sugerencias sobre cómo eliminar los flashes?