2013-06-23 6 views
8

So versuche ich zu verstehen, wie ich die Hardwarebeschleunigung (wenn verfügbar) in einem benutzerdefinierten View verwenden kann, das ständig animiert. Dies ist die grundlegende Prämisse meines onDraw():Verwenden der Hardwareebene in der benutzerdefinierten Ansicht onDraw

canvas.drawColor(mBackgroundColor); 

for (Layer layer : mLayers) { 
    canvas.save(); 
    canvas.translate(layer.x, layer.y); 

    //Draw that number of images in a grid, offset by -1 
    for (int i = -1; i < layer.xCount - 1; i++) { 
     for (int j = -1; j < layer.yCount - 1; j++) { 
      canvas.drawBitmap(layer.bitmap, layer.w * i, layer.h * j, null); 
     } 
    } 

    //If the layer's x has moved past its width, reset back to a seamless position 
    layer.x += ((difference * layer.xSpeed)/1000f); 
    float xOverlap = layer.x % layer.w; 
    if (xOverlap > 0) { 
     layer.x = xOverlap; 
    } 

    //If the layer's y has moved past its height, reset back to a seamless position 
    layer.y += ((difference * layer.ySpeed)/1000f); 
    float yOverlap = layer.y % layer.h; 
    if (yOverlap > 0) { 
     layer.y = yOverlap; 
    } 

    canvas.restore(); 
} 

//Redraw the view 
ViewCompat.postInvalidateOnAnimation(this); 

Ich ermögliche Hardware-Schichten in onAttachedToWindow() und sie in onDetachedFromWindow() deaktivieren, aber ich versuche, ob zu verstehen oder nicht, ich bin mit ihm tatsächlich. Im Wesentlichen ändert sich die i/j Schleife, die drawBitmap() aufruft, nie; Die einzige Sache, die sich ändert, ist die Canvas Übersetzung. Wird die Bitmap automatisch als Textur hinter den Kulissen auf der GPU gespeichert, oder muss ich etwas manuell machen?

+0

tun ich die Frage falsch verstanden haben könnte aber haben Sie 'setLayerType (View.LAYER_TYPE_HARDWARE, null);' für Ihre Ansicht? Die GPU Zwischenspeichert die Bilder nur so lange, wie der Benutzer aktiv scrollt, tut dies jedoch nicht, was einen Kompromiss darstellt, wenn weniger Ressourcen verbraucht werden. – Slartibartfast

+0

@Slartibartfast Ja, ich habe den Layer-Typ auf Hardware eingestellt. Der Benutzer wird niemals tatsächlich scrollen; Die Ansicht scrollt kontinuierlich ihren eigenen Inhalt. Ich mag HW Acceleration vielleicht falsch verstehen, aber ich denke, dass dieses Raster aus Bitmaps, das ich zeichne, in eine Hardware-Ebene gerendert und einfach übersetzt werden kann, anstatt die Bitmaps in jedem Frame neu zu zeichnen. – kcoppock

Antwort

6

Auf welche Ansicht (en) setzen Sie View.LAYER_TYPE_HARDWARE genau? Wenn Sie in der Ansicht, die den oben gezeigten Zeichnungscode enthält, eine Hardwareschicht festlegen, veranlassen Sie das System dazu, wesentlich mehr als nötig zu arbeiten. Da Sie nur Bitmaps zeichnen, müssen Sie hier nichts machen. Wenn Sie Canvas.drawBitmap() aufrufen, speichert das Framework die resultierende OpenGL-Textur in Ihrem Namen.

Sie könnten jedoch Ihren Code ein wenig mehr optimieren. Anstatt drawBitmap() aufzurufen, können Sie untergeordnete Ansichten verwenden. Wenn Sie diese untergeordneten Elemente mithilfe der Methoden offset*() (oder setX()/setY()) verschieben, wendet das Framework weitere Optimierungen an, um zu vermeiden, dass die Methoden draw() erneut aufgerufen werden.

Im allgemeinen Hardware-Schichten sollten Ansichten eingestellt werden, die teuer sind, zu zeichnen und dessen Inhalt wird nicht oft ändern (so ziemlich das Gegenteil von dem, was Sie :)

+0

Danke @RomainGuy. Ich habe 'LAYER_TYPE_HARDWARE' in der oben gezeigten' Ansicht' eingestellt. Also wird die Textur automatisch zwischengespeichert? Das habe ich gesucht. Sie sagen also, dass es effizienter ist, zwei untergeordnete Ansichten hinzuzufügen und Übersetzungen für diese untergeordneten Ansichten zu verwenden, anstatt die Bitmaps direkt auf der Arbeitsfläche zu zeichnen? Ich werde das untersuchen. Vielen Dank! – kcoppock

+1

Ja, Texturen werden automatisch zwischengespeichert. Sie können den Status der verschiedenen Caches über die Befehlszeile mithilfe der ADB-Shell dumpsys gfxinfo com.your.app abfragen.Es ist effizienter, Views * in Ihrem Fall * zu verwenden, da Sie die Bitmaps viel verschieben. Wir erkennen diese Situation mit Views und anstatt die draw() -Methode erneut aufzurufen, setzen wir nur native Eigenschaften im Renderer. Es ist fast kostenlos. –

1

Sie können Android Tracer for OpenGL ES verwenden, um zu sehen, ob Ihre Ansicht OpenGL-Befehle ausgibt.

Von developer.android.com

Tracer ist ein Werkzeug für OpenGL for Embedded Systems (ES) Code in Ihrer Android-Anwendung zu analysieren. Mit diesem Tool können Sie OpenGL ES-Befehle und Frame-für-Frame-Bilder erfassen, um zu verstehen, wie Ihre Grafikbefehle ausgeführt werden.

Es gibt auch ein Tutorial über Android Performance Study von Romain Guy, die für Schritt seine Verwendung fast Schritt beschreibt.