2013-06-23 6 views
8

ハードウェアアクセラレーション(利用可能な場合)を永続的にアニメートするカスタムViewで正しく使用する方法を理解しようとしています。これは私のonDraw()の基本的な前提である:カスタムビュー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); 

私はonAttachedToWindow()でハードウェアレイヤを有効にしてonDetachedFromWindow()でそれらを無効にしていますが、私は実際にそれを使用しているかどうかを理解しようとしています。基本的にdrawBitmap()を呼び出すi/jループは決して変更されません。変更されるのはCanvasです。 Bitmapは自動的にGPUにテクスチャとして保存されますか、そうするために手動で行う必要がありますか?

+0

をやっていることの反対は変更されませんする必要がありますビューに対して 'setLayerType(View.LAYER_TYPE_HARDWARE、null);'を設定していますか? GPUは、ユーザーが積極的にスクロールしている間だけイメージをキャッシュしますが、それ以外のリソースは消費しません。 – Slartibartfast

+0

@Slartibartfastええ、レイヤータイプをハードウェアに設定しました。ユーザーは実際にはスクロールしません。ビューはそれ自身のコンテンツを連続的にスクロールしています。私はHW Accelerationを誤解しているかもしれませんが、私が描いているビットマップのグリッドをハードウェアレイヤーにレンダリングし、すべてのフレームでビットマップを再描画するのではなく翻訳するだけでいいと思います。 – kcoppock

答えて

6

View.LAYER_TYPE_HARDWAREはどのような視点で正確に設定していますか?上に示した描画コードを含むビュー上にハードウェアレイヤーを設定している場合、システムは必要以上に多くの作業をしています。ビットマップを描画するだけなので、ここで何もする必要はありません。 Canvas.drawBitmap()を呼び出すと、フレームワークは結果として得られるOpenGLテクスチャをあなたのためにキャッシュします。

ただし、コードをもう少し最適化することはできます。 drawBitmap()を呼び出す代わりに、子ビューを使用することもできます。 offset*()メソッド(またはsetX()/setY())を使用してこれらの子を移動する場合、フレームワークはさらにdraw()メソッドを呼び出さないように、さらに最適化を適用します。

一般的には、ハードウェア層は描画する高価なビューに設定し、そのコンテンツので、かなりの(多くの場合、あなたは、私が質問を誤解している場合があります:)

+0

ありがとう@RomainGuy。上記の 'View'に' LAYER_TYPE_HARDWARE'を設定していました。したがって、テクスチャは自動的にキャッシュされますか?それが私が探していたものです。実際には、キャンバスにビットマップを直接描画するのではなく、2つの子ビューを追加し、それらの子ビューで翻訳を使用する方が効率的だと言いますか?私はそれを調べます。ありがとう! – kcoppock

+1

はい、テクスチャは自動的にキャッシュされます。コマンドラインからさまざまなキャッシュの状態を問い合わせるには、adb shell dumpsys gfxinfo com.your.appを使用します。ビットマップをたくさん動かしているので、あなたのケース*でViews *を使う方が効率的です。ビューでこの状況を検出し、再度draw()メソッドを呼び出すのではなく、レンダラーで内部的にネイティブプロパティを設定するだけです。ほとんど無料です。 –

1

あなたのビューがOpenGLコマンドを発行するかどうかは、Androidの​​を使用して確認できます。

developer.android.com

からトレーサーは、あなたのAndroidアプリケーションに組み込みシステム(ES)コードのためのOpenGLを分析するためのツールです。このツールを使用すると、OpenGL ESのコマンドとフレーム単位のイメージをキャプチャし、グラフィックスコマンドの実行方法を理解するのに役立ちます。

ステップバイステップ、ほぼその使用を説明ロマン・ガイAndroid Performance Studyについてのチュートリアルもあります。

関連する問題