2012/05/08

Android:ハードウェアアクセラレーション

Android3.0からサポートされたハードウェアアクセラレーションについて覚書。

より優れた2Dレンダリングはハードウェアアクセラレーション(以降HWアクセラレーション)
機能を使用することで実現できます。

HWアクセラレーションを有効にすると、Viewのcanvas描画処理でGPUを利用するようにな
ります。
HWアクセラレーションの有効or無効は下記の粒度で指定が可能です。
  • Application
  • Activity
  • Window
  • View

各コンポーネント毎にHWアクセラレーションを設定する例)
  • Application
<application ...="" android:hardwareaccelerated="true">
  • Window
getWindow().setFlags(
    WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED,
    WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED);
  • View
myView.setLayerType(View.LAYER_TYPE_SOFTWARE, null);

ただし、HWアクセラレーションは全ての2D描画をサポートしていません。
下記はサポートされていないAPIです。
  • Canvas
    •  clipPath()
    •  clipRegion()
    •  drawPicture()
    •  drawPosText()
    •  drawTextOnPath()
    •  drawVertices()
  • Paint 
    •  setLinearText()
    •  setMaskFilter()
    •  setRasterizer()

また、カスタムViewや描画処理を独自に実装していると
  • 例外が発生する
  • 描画が反映されない
  • 描画される内容が不正
といった悪影響を及ぼす可能性があります。
下記はHWアクセラレーションを有効にすることで異なる動作となるAPIです。
  • Canvas 
    • clipRect(): XOR, Difference and ReverseDifference は無視される。
             3D変換は、クリップ領域に対して適用されない。
    • drawBitmapMesh(): 色配列は無視される。
    • drawLines(): アンチエイリアスはサポートされない。
    • setDrawFilter(): セットはできるが無視される。
  • Paint 
    • setDither(): 無視される。
    • setFilterBitmap(): フィルタリングは常にONされます。
    • setShadowLayer(): テキストのみ動作します。
  • ComposeShader 
    • 異なった型のシェーダーを含むことしかできない。
    • ComposeShaderはComposeShaderを含む事ができない。

問題を解決するためには、setLayerType(View.LAYER_TYPE_SOFTWARE, null)を呼び出して、
影響を受けている部分のHWアクセラレートをオフにします。

ViewあるいはCanvasがHWアクセラレートされているかを判定する場合は下記を使用します。
  • View.isHardwareAccelerated()
  • Canvas.isHardwareAccelerated()

以上です。