2013-06-23 13 views
8

Próbuję więc zrozumieć, w jaki sposób mogę właściwie użyć przyspieszania sprzętowego (jeśli jest dostępne) w niestandardowym View, który jest nieustannie animowany. Jest to podstawowa przesłanka moich onDraw():Używanie warstwy sprzętowej w widoku niestandardowym 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); 

mam umożliwiając warstw sprzętowych w onAttachedToWindow() i wyłączając je w onDetachedFromWindow(), ale staram się zrozumieć, czy ja rzeczywiście go używać. Zasadniczo, pętla i/j, która wywołuje drawBitmap() nigdy się nie zmienia; jedyną zmianą jest tłumaczenie Canvas. Czy Bitmap jest automatycznie zapisywany na GPU jako tekstura za kulisami, czy też jest coś, co muszę zrobić ręcznie, aby to zrobić?

+0

mógłbym źle pytanie ale czy ustawiłeś "setLayerType (View.LAYER_TYPE_HARDWARE, null);" dla twojego widoku? GPU buforuje obrazy tylko tak długo, jak użytkownik aktywnie przewija, ale nie robi inaczej, jako kompromis dla zużywania mniejszych zasobów. – Slartibartfast

+0

@Slartibartfast Tak, ustawiłem typ warstwy na sprzęt. Użytkownik nigdy nie będzie przewijany; widok cały czas przewija własną treść. Być może nie rozumiem akceleracji HW, ale czuję, że siatka rysowanych bitmap powinna być w stanie zostać przekształcona w warstwę sprzętową i po prostu przetłumaczyć zamiast przerysować mapy bitowe w każdej klatce. – kcoppock

Odpowiedz

6

W jakich widokach ustawiasz dokładnie View.LAYER_TYPE_HARDWARE? Jeśli ustawiasz warstwę sprzętową w widoku zawierającym powyższy kod rysunku, powodujesz, że system wykonuje znacznie więcej pracy, niż to konieczne. Ponieważ rysujesz tylko bitmapy, nie musisz tutaj nic robić. Jeśli zadzwonisz pod numer Canvas.drawBitmap(), framework będzie buforował wynikową teksturę OpenGL w Twoim imieniu.

Można jednak zoptymalizować swój kod nieco więcej. Zamiast wywoływać numer drawBitmap(), można użyć widoków podrzędnych. Jeśli przeniesiesz te dzieci za pomocą metod offset*() (lub setX()/setY()), framework zastosuje dalsze optymalizacje, aby ponownie wywoływać metody draw().

Generalnie warstwy metalowe powinny być ustawione na widoki, które są drogie, aby rysować i którego treść nie będzie często zmieniać (więc dość dużo przeciwieństwem tego, co robisz :)

+0

Dzięki @RomainGuy. Ustawiłem "LAYER_TYPE_HARDWARE" na "widoku" pokazanym powyżej. Czy tekstura zostanie automatycznie zapisana w pamięci podręcznej? Tego właśnie szukałem. Więc mówisz, że bardziej wydajne jest dodawanie dwóch widoków podrzędnych i używanie tłumaczeń na widokach potomnych, zamiast rysowania bitmap bezpośrednio na płótnie? Zajrzę w to. Dzięki! – kcoppock

+1

Tak, tekstury będą automatycznie buforowane. Możesz zapytać o stan różnych pamięci podręcznych z wiersza poleceń za pomocą adb shell dumpsys gfxinfo com.your.app.Bardziej efektywne jest korzystanie z Widoku * w twoim przypadku *, ponieważ często przesuwasz mapy bitowe. Wykrywamy tę sytuację za pomocą widoków i zamiast ponownie wywoływać metody draw(), po prostu ustawiamy wewnętrzne właściwości w rendererze. To prawie za darmo. –

1

Możesz użyć Androida Tracer for OpenGL ES, aby sprawdzić, czy Twój widok wydaje polecenia OpenGL.

Od developer.android.com

Tracer jest narzędziem do analizowania OpenGL do wbudowania Systems (ES) kodu w aplikacji Android. Narzędzie pozwala przechwytywać polecenia OpenGL ES i obrazy klatka po klatce, aby pomóc ci zrozumieć, w jaki sposób wykonywane są polecenia graficzne.

Jest też poradnik o Android Performance Study Romain Guy, który opisuje jej zastosowanie niemal krok po kroku.

Powiązane problemy