多くのことが関係し、特に以来、特定のソースコード解析をアップロードした後
参照
https://blog.csdn.net/OneDeveloper/article/details/79791302
https://www.jianshu.com/p/f1feafffc365
コンセプト
そうではないので、以前の数年間の内容がハードウェアアクセラレーション技術的なポイントが、一部の読者に関与しているので、公式の開始前に、ちょうど補足するコンテンツの完全性のために、図面の最後の部分として、この問題を説明する必要がありますハードウェアアクセラレーションについて学ぶには、いくつかの疑問を持っていました。だからコンテンツのこの問題の面で難しさからは難しいことではありませんが、この問題のほとんどは、あなたは、これらの2つのページを見つけることができます。
https://developer.android.google.cn/guide/topics/graphics/hardware-accel.html
https://www.youtube.com/watch?v=v9S5EO7CLjo
入力した次の。
いわゆるハードウェアアクセラレーション、処理するCPUへと行うには専用のハードウェアではなく、通常の計算に、コンピューティング作業の一部を参照します。これは、CPUへの圧力を軽減しますだけでなく、この作品の「手」を処理するためのおかげでスピードが加速される計算です。これは、「ハードウェアアクセラレーション」です。
Androidの場合、ハードウェアアクセラレーションは、独自の意味を持つ:アンドロイドでは、ハードウェアアクセラレーションは、具体的にビューを参照する計算をレンダリング処理するためにGPUに。
また、この詳細については、明示的な「計算作業を描く」()メソッドを描いたものCanvas.drawXXXを指し、実際のピクセルそれになります。
原則
閉じたときにハードウェアアクセラレーションでは、キャンバスの描画作業は:コンテンツが描画ビットマップに書き込まれ、その後、レンダリング処理後、このビットマップのピクセルの内容は画面に直接描画するために使用されます。このアプローチを描く主計算作業は、描画処理動作が(画素情報の特定の円を得るために例えばCanvas.drawCircle())画素に変換されることで、演算処理をCPUによって達成されます。大体このように:
ハードウェアアクセラレーションをオンにしたときと、キャンバスが変更された作品:それは単にその後、GPUにそれを与える、描かれた内容は、GPUの動作のために保存変換し、最終的に行うために、実際の作業は、GPUによって表示されます。大体このように:
ハードウェアアクセラレーションをオンにすると、図に示すように、CPUがGPUを動作させるために図面を変換するだけの仕事をし、作業負荷が相対的に非常に小さいです。
どのように「加速」するには?
上記の図から分かるように、CPUの演算により描画されたオープンハードウェアアクセラレーションは、GPUに移しました。しかし、これは、それは速く描くとなるように、あなたは、「加速」役割を担うことができる方法ですか?
ハードウェアアクセラレーションは、3つの主要な理由のために、より高速にレンダリングできます。
-
もともと自然増加効率のGPU部分に配分自分のことを行うためのCPU、から。
-
CPUに対しては、GPU自体が既にコンテンツの多くの一般的なタイプの計算のために設計されていると(例えば、単純な円形、単純な四角)は、利点を有します。
-
異なるハードウェアの描画処理プロセスをレンダリング加速ので、画面の内容を再描画するときに発生が大幅にレンダリング効率を向上させる、いくつかの重複作業を避けるために最適化することができます。
最初の二つは、1のようにまとめることができますGPUを使用して、レンダリングが高速です。理由は非常に直感的ですが、私はこれ以上言うことはありません。
第三の点で、それは私が一般の話を原則です。
-
ハードウェアアクセラレーションがオフ、描画内容が画面描画に直接、実際の画素CPUに変換されたとき。具体的には、「実際の画素」、閉じられたときに(ハードウェアアクセラレーションをビットマップを運ぶためになされたものであり、キャンバス作品を描くことである:コンテンツが描画ビットマップに書き込まれ、その後、レンダリング処理後にしますこの画素コンテンツビットマップ)が画面に直接描画するために使用されます。ときに、Viewインタフェース内容の変更や呼び出しは()メソッドを無効にするので、何のハードウェアアクセラレーションが存在しない場合はオンにし、その後、順番に正しくビットマップのピクセルを計算するために、ビュー父ビュー、父ビュー父ビューもアップトップまでのすべての方法見るだけでなく、すべての兄弟と、それはビューを交差し、再描画する)(無効に呼び出される必要があります。インタフェースの変更のビューでも、この作業負荷が非常に大きく、画面全体の半分が再び再描画されるようにしてください。
-
ハードウェアアクセラレーションでオンに記憶され、図面の内容はGPUダウン操作に変換され、次いで、GPUに移し、(ディスプレイリストの形で、キャリアと呼ばれる、またクラスに対応するDISPLAYLISTと呼ばれます)。すべての描画内容があるので 、最終的な画素とはならない ので、インタフェースの変更内容は、限りは、その対応するGPUを更新するコールが無効表示()メソッドを変更し、その後とき、それらの間で独立していますそれは同じように、その親と兄弟ビュービューとして、のように作動します。そして、小さな上のワークロード。
これは、ハードウェアアクセラレーションにより、効率を改善するためにレンダリングGPUの導入のみならずによる描画機構の変化に、大幅インタフェースリフレッシュコンテンツ変更の効率を向上させ、上記の理由のためです。
ここでは、加速のための理由は、ディスプレイリストの画面上のUIを描きながら、ハードウェアアクセラレーションの有無にかかわらず、注意すべきポイント、または再描画画面全体の内容ではなく、描画内容の変更のほんの一部に必要ですキャッシュされた関連の操作は、操作を毎回繰り返しではなく上がるします。
したがって、上記の3つの圧縮は、2つのハードウェアアクセラレーション高速な理由があり、要約します:
-
GPUと、より高速な描画。
-
場合内容変更画面を更新大幅に改善された効率が得られ、チェンジ機構を描きます。
層型
コンテンツの前に数年の期間で、私はあなたがハードウェアアクセラレーションをサポートしていない操作を描画している場合は、手動でのコード行を介して行われ、シャットダウン、インターフェースを描画するために、ハードウェアアクセラレーションをオフにする必要があり、何度か言及しました。
view.setLayerType(LAYER_TYPE_SOFTWARE、NULL);
ハードウェアアクセラレーションは、ハードウェアアクセラレーションをオフにするsetLayerTypeを()を使用することができるが、実際にこの方法では、表示レイヤを設定するために使用されます。
-
パラメータは、ビットマップを描画するために、表示レイヤを描画するためのソフトウェアを使用して、そして道オフハードウェアアクセラレーション、LAYER_TYPE_SOFTWAREである場合には、
-
パラメータは、OpenGLのテクスチャ(ハードウェアアクセラレーションをオフであれば、その後、VIEW_TYPE_SOFTWARE一貫性のある動作)を描画するために、GPUの描画ビュー・レイヤーを使用して、LAYER_TYPE_HARDWAREである場合には、
-
パラメータは、表示レイヤを閉じ、LAYER_TYPE_NONEです。
ビュー・レイヤー)は、(無効化せずにリフレッシュ効率を加速することができますが、無効化を(呼び出す必要があります)リフレッシュ加速することができません。
ビュー・レイヤーは、実際に消費時間は、ビュー・レイヤーを使用しない場合よりも高くなるので、使用するように注意してください描きます。
多くの人が疑問を持っていた:層の種類は何ですか?この方法は、ハードウェアアクセラレーションスイッチであれば、それはLAYER_TYPE_SOFTWAREは、ハードウェアアクセラレーションをオフにする理由を引数とハードウェアアクセラレーションを開くためにLAYER_TYPE_HARDWAREので、2つのパラメータが、3つのパラメータだけでなく、ソフトウェアとハードウェアの外LAYER_TYPE_NONEではありませんか?ソフトウェアは、どちらもそれを描画するためのハードウェアを持っていない、描くことはできませんされていますか?
実際には、このメソッドの役割はしていたされていない引数が「であることをLAYER_TYPE_SOFTWAREあるちょうどその時、スイッチのハードウェアアクセラレーションに使用方法およびこの方法に加えて、Androidは特別に用意されていません。唯一のハードウェアアクセラレーションをオフにします」それがあるので、ビューレベルのハードウェア・アクセラレーション・スイッチは、「道」のアプローチは、スイッチのハードウェアアクセラレーションになりました。
ビューレイヤーの表示レイヤーは、ハードウェアアクセラレーションハードウェアアクセラレーションで、両方の二つの概念が、交差する場所が存在していました。
いわゆるビュー・レイヤー、また、オフスクリーンバッファ(オフスクリーンバッファ)として知られているが、その役割は、代わりにビットマップ描画ソフトウェアまたはハードウェアアクセラレーションGPUを使用しての、この場所のビューを描画するために個人を可能にするためです。この「場所」は、別個のビットマップであってもよく、OpenGLテクスチャ(質感、OpenGLのテクスチャ画像を単に意味すると理解することができる)、ハードウェアアクセラレーションに応じがオンになっているかもしれません。
setLayerType()メソッドを使用した後、それが何であるか良い、それが設定されたビュー・レイヤーである、あなたは(元に基づいて加速を開くには何のハードウェアが存在しない場合、電源がオンにならない基づいていることができ、あなたは、ハードウェアアクセラレーションを有効にした場合、その根拠を開設しました)に、さらなる改善が効率ビューを再描画します。
ビューレイヤーの時間(非NONE)を設定するときにキーがあり、キーではない、キャッシュされる図面のビューを描画するものの使用は、オフスクリーンバッファを使用することで、キャッシュは、最終的な描画結果であるハードウェアのようではありません単にハードウェアアクセラレーションがオンになっているため、コンテンツを描画する必要がある、計算するダウン再びGPUのGPUアクセラレーション動作を保存したがストアGPUの操作をダウンコンバートされるように、キャリアの形状は、表示リストと呼ばれ、また、対応するクラスと呼ばれあなたが描くたびに、またはDISPLAYLISTを変換する必要がピクセルの最終コンテンツを保存し、DISPLAYLISTは、その後、GPUに転送しますが、すべての描画内容は、最終的なピクセルになっていません。
さらにキャッシュとして、さらに再描画ビューの効率改善:限り、図面の内容が変更されていないとして、その後、CPUをどちらかのドロー(ソフトウェアベースのレンダリングモデル)やGPU(ハードウェアアクセラレーションモデル)を描画するために、彼らは再計算する必要はありません、そして限り、その上に描画結果で使用する前にキャッシュとして。
この原理に基づいて、移動中に、()(無効呼び出さず)など、回転プロパティアニメーションのアニメーションプロセスビュー自体には変化がないため、オープンハードウェアレイヤが大幅に、アニメーションの効率を強化する際に、その位置や角度が変化し、この変更が完了し、GPUによって、簡単な計算により全体のビューを再描画する必要はありません。したがって、このアニメーション処理ではハードウェアレイヤを開くには、すでにハードウェアアクセラレーションに依存していると流暢なアニメーションがより流動的になるになることができます。このような実装の何か:
view.setLayerType(LAYER_TYPE_HARDWARE、NULL ); ObjectAnimatorアニメーター = ObjectAnimator.ofFloat(ビュー、 "rotationY"、180 ); animator.addListener(新しいAnimatorListenerAdapter(){ @Override 公共 ボイドonAnimationEnd(アニメーターアニメーション){ view.setLayerType(LAYER_TYPE_NONE、NULL ); } })。 animator.start();
それとも、ViewPropertyAnimatorを使用している場合は、よりシンプル:
view.animate() .rotationY( 90 ) .withLayer(); // withLayer()は、上記の複雑な操作コードを自動化することができ
しかし、私たちがいることに注意しなければならないあなたは()属性アニメーションの時間を行う無効呼び出さずtranslationX translationY回転アルファなどにのみ、この方法は、キャッシュが更新されていない場合は、この方法自体が発生しないインタフェースを使用することであるためにのみ適用されます貯蓄は、時間によってもたらされます。
-だから、簡単に言えば、この方法でカスタムプロパティベースのアニメーションのレンダリングには適用されません。あなたはこの文を覚えておく必要があります。
また、初期のたびに描画し、再描画(後)無効にすると、Viewレイヤーを設定した後、ビューは、ので(から引き分けを表示するには、レイヤ、レイヤを描画するために一度)を2回動作するように描画する必要があるので、実際にはそれ各図面の効率が低下します。だから、あなたがそれを使用する必要があるときに使用する行く、慎重にビュー・レイヤーを使用してください。
さらに、そのような表示の設定など、レイヤビューがレンダリング効果の数を増加させるためにも使用することができ、閉鎖用のハードウェアアクセラレーションと二つの補助プロパティアニメーション機能に加えてはColorMatrixColorFilterが白黒にするために次のようになります。
ColorMatrix colorMatrix = 新しいColorMatrix(); colorMatrix.setSaturation( 0 )。 ペイント塗料 = 新しいペイント(); paint.setColorFilter(新しいColorMatrixColorFilter(colorMatrix)); view.setLayerType(LAYER_TYPE_HARDWARE、塗料);
の開口部と窓ハードウェア加速層型の関係
-
??ハードウェアアクセラレーション、ビットマップ、すなわち、オフスクリーンバッファを作成する方法、セットアップ層タイプを開くかどうかをcanvas.savelayer。
-
ウィンドウには、ハードウェアアクセラレーションを開かない場合は、
LAYER_TYPE_NONEは、それに関係なく、ビューが再び最初から最後までのコードの実行を描画されます無効かどうかの、描画キャッシュを作成しないでしょう。
LAYER_TYPE_HARDWARE、およびLAYER_TYPE_SOFTWARE同じ。
LAYER_TYPE_SOFTWARE、ビットマップを描画するために描画キャッシュ(buildDrawingCache)、描画操作を作成し、
-
ウィンドウのオープンハードウェアアクセラレーションの場合
LAYER_TYPE_NONEは、それは、つまり、ハードウェアアクセラレーションレンダリング処理をハードウェア層を作成しないでしょう
さらには、これらのプロパティを無効に呼び出さないようLAYER_TYPE_HARDWAREは、あまりにも長い間、ビットマップと同様のハードウェア層に描画します、およびその他のプロパティを変更した後に再描画されます。
LAYER_TYPE_SOFTWAREは、ビットマップを描画するために描画キャッシュ(buildDrawingCache)、描画操作を作成します
公共 ボイド setLayerType(int型layerType、@Nullableペイントペイント){ IF(layerType <LAYER_TYPE_NONE || layerType> LAYER_TYPE_HARDWARE){ スロー 新新はIllegalArgumentException( "のみ可能なのレイヤ一つのタイプ:LAYER_TYPE_NONE、" + "またはLAYER_TYPE_HARDWARE LAYER_TYPE_SOFTWAREを" ); } //それは、このハードウェア層の上に描画した後に行われ、オンになっている場合は、その基盤となるハードウェア層は、オンになって言います。 ブール typeChanged = mRenderNode.setLayerType(layerType); IF(!{typeChanged) setLayerPaint(塗料); リターン; } IF(layerType =!LAYER_TYPE_SOFTWARE){ // 存在する場合、キャッシュを描く以前のソフトウェア破壊 // 注:前の層の種類がHWであったとしても、我々はクリーンアップしましたことを確認するためにこれを行う // SWキャンバスに描画するときの表示#ドローで作成した図面のキャッシュを。 destroyDrawingCache(); } mLayerType = layerType。 mLayerPaint = mLayerType == LAYER_TYPE_NONE?ナル:ペイント; mRenderNode.setLayerPaint(mLayerPaint)。 // 私たちはレイヤー上にある場合は動作が異なりますので、我々はする必要があります)(描画 // (無効化)をここに )invalidateParentCaches(; (無効真の); }
注意
すべてのキャッシュが懸念され、キャッシュの失敗の可能性があります。)(アニメーションコールview.invalidate中の任意の時点であれば、再レンダリングする必要がある層。前述したようにキャッシュを設定する際に、ハードウェア層は、追加の費用を必要とするだろう、ので、多くの場合、放棄されたハードウェア層は、事態の層が存在しない場合よりも悪くなります。あなたが頻繁に再バッファ層に必要がある場合は、大きな破損があるでしょう。
多くの場合、いくつかのより多くのアニメーションの動きがあるため、この問題が、また非常に脆弱です。今ならば3つの一部のモバイルアニメーションがあります:
ViewGroup親 - - > 子View1を(左に移動) - - > 子VIEW2(右に移動) - - >子View3(上方へ移動)
あなただけの親レイアウトのViewGroup上の層を設定した場合、それは多くの場合、キャッシュの無効化、のViewGroupは、子ビューのように変化していきますますので。しかし、個々のサブビューのために、彼らは単にシフトします。この場合、好ましくは各サブ表示ハードウェアレイヤ(よりむしろ親レイアウト上)に設けられ。
ここでも、通常、適切な設定のハードウェアレイヤ上のサブビューの複数なので、彼らは、実行時のアニメーションでは失敗しません。
いくつかの層タイプのパフォーマンス
-
ハードウェアレイヤ> =ソフトウェア層>ノーマルレイヤー:あなただけの単純なアニメーションを行う場合は、動的に、パフォーマンスなどのコンテンツ表示を変更しません
-
動的コンテンツビューを変更しながら、アニメーションを行う場合、パフォーマンスは次のとおりです。通常のレイヤ>ソフトウェアレイヤー=ハードウェアレイヤ
-
ハードウェアレイヤアニメーションが大幅に改善された性能を持っていますが、あなたは良い使用している場合、その後、同様に行う可能性があります
-
あなたはSYSTRACEアニメーションによってbuildDrawingCache / SW(メインスレッド)またはbuildLayer(スレッドレンダリング)の各フレームは、あなたのコードのロジックを参照してくださいするときことを発見した場合は
-
画像は、ロジックの問題を無効に、キャッシュよりも大きくなるなどの原因システムにはいくつかのケースでは、あなたが一緒に変更するために、携帯電話メーカーに連絡することができます
問題
LAYER_TYPE_SOFTWAREは、呼び出された場合setAlpah / setTranslationXおよび他の方法は、キャッシュを描画に使用される、または再描画されますか?
上から下へのトラバースが、しかし、任意の再描画や復興DISPLAYLISTをしませんでした。
ハードウェアアクセラレーションをオンにした後、それを再描画するために、親ビューを作成するsetAlpah / setTranslationX他のメソッドを呼び出しますか?
ありません