Android: Canvas.DrawBitmap VS Drawable.Draw – Aumento de rendimiento enorme

Acabo de descubrir algo y me preguntaba cómo y por qué. Estoy desarrollando un pequeño juego de arcade para Android. Decidí ignorar OpenGL y utilizar el estándar SurfaceView y Drawables para hacerlo, ya que se supone que debe ser luz (10 sprites o menos). Tengo dibujos que carga, y utilizo el método Dibujar y pasarles mi lienzo. Así se dibuja cada sprite en la pantalla. Bueno, resulta que el dibujo de 4-5 grandes sprites (200X400 o menos) lleva mucho tiempo en los modelos de teléfono menos que la marca. Lo suficiente como para que mi juego sea injugable. Estamos hablando de 50-60 milisegundos para dibujar una sola trama utilizando este método. Y realmente no hago nada allí aparte del dibujo, en ninguna parte puedo cortar costes. Así que decidí probar y utilizar Bitmaps en su lugar. Aquí, sin embargo, tengo que pre-establecer el tamaño, ya que no hay ningún método 'setBounds' en un mapa de bits. Ningún problema, los cambie de tamaño para caber mi pantalla actual en la carga, problema resuelto.

DE ACUERDO. Así que tengo bitmaps. Uso Canvas.DrawBitmap ahora para dibujar. Me banco el nuevo método de sorteo .. y me dan un aumento de 400% de rendimiento de chispas! En lugar de 50-60ms, el bucle de dibujo entero toma ahora 8-12ms. ¿¿Que demonios?? Para descartarlo, cronometré los setBounds también, toma <1ms así que no es culpar. Es el Drawable.Draw real que ralentiza las cosas.

Para mí esto es una gran noticia, ya que realmente no quería aprender OpenGL para hacer mi juego jugable, pero no puedo dejar de preguntarme sobre él – ¿Está bien? ¿Hay problemas con mi método? ¿Por qué no se menciona en ninguna parte?

El SurfaceView de su Canvas está destinado a ser utilizado cuando debe iterar constantemente y Drawable no es para ese propósito.

Canvas.drawBitmap está haciendo mucho menos trabajo que Drawable.draw por lo que es más rápido.

Drawable.draw

Dado que Drawable es una clase abstracta, veamos BitmapDrawable :

BitmapDrawable.draw (lienzo)

 public void draw(Canvas canvas) { final Bitmap bitmap = mBitmapState.mBitmap; if (bitmap == null) { return; } final BitmapState state = mBitmapState; final Paint paint = state.mPaint; if (state.mRebuildShader) { final Shader.TileMode tmx = state.mTileModeX; final Shader.TileMode tmy = state.mTileModeY; if (tmx == null && tmy == null) { paint.setShader(null); } else { paint.setShader(new BitmapShader(bitmap, tmx == null ? Shader.TileMode.CLAMP : tmx, tmy == null ? Shader.TileMode.CLAMP : tmy)); } state.mRebuildShader = false; } final int restoreAlpha; if (state.mBaseAlpha != 1.0f) { final Paint p = getPaint(); restoreAlpha = p.getAlpha(); p.setAlpha((int) (restoreAlpha * state.mBaseAlpha + 0.5f)); } else { restoreAlpha = -1; } final boolean clearColorFilter; if (mTintFilter != null && paint.getColorFilter() == null) { paint.setColorFilter(mTintFilter); clearColorFilter = true; } else { clearColorFilter = false; } updateDstRectAndInsetsIfDirty(); final Shader shader = paint.getShader(); final boolean needMirroring = needMirroring(); if (shader == null) { if (needMirroring) { canvas.save(); // Mirror the bitmap canvas.translate(mDstRect.right - mDstRect.left, 0); canvas.scale(-1.0f, 1.0f); } canvas.drawBitmap(bitmap, null, mDstRect, paint); if (needMirroring) { canvas.restore(); } } else { updateShaderMatrix(bitmap, paint, shader, needMirroring); canvas.drawRect(mDstRect, paint); } if (clearColorFilter) { paint.setColorFilter(null); } if (restoreAlpha >= 0) { paint.setAlpha(restoreAlpha); } } 

Puede ver que incluso llama a canvas.drawBitmap internamente.

Canvas.drawBitmap

Compare eso con Canvas.drawBitmap . Es mucho más corto.

Canvas.drawBitmap

 public void drawBitmap(@NonNull Bitmap bitmap, float left, float top, @Nullable Paint paint) { throwIfCannotDraw(bitmap); native_drawBitmap(mNativeCanvasWrapper, bitmap, left, top, paint != null ? paint.getNativeInstance() : 0, mDensity, mScreenDensity, bitmap.mDensity); } 

Hay algunos métodos diferentes de drawBitmap , pero todos ellos son más cortos que el método Drawable.draw . Cuidado con las trampas como esta para mantener su mapa de bits de dibujo rápido.

FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.