CanvasとSurfaceの概念を理解する


114

Androidで使用される/ / システムSurfaceView全体への描画プロセスを理解するのに苦労しています。SurfaceCanvasBitmap

私は、android-developersサイトで見つけたすべての記事とAPIドキュメントページ、androidグラフィックのいくつかのチュートリアル、LunarLanderソースコード、およびこの質問を読みました。

これらのステートメントのうち、どれが正しいか、どちらが正しくないか、そしてその理由を教えてください。

  1. CanvasそれにBitmap接続されています。SurfaceそれにCanvas接続されています。
  2. Viewウィンドウのすべてが同じSurfaceを共有するため、同じを共有しCanvasます。
  3. SurfaceViewのサブクラスでViewあり、他ViewののサブクラスやViewそれ自体とは異なり、独自Surfaceに描画する必要があります。

また、もう1つ質問があります。

  • SurfaceすでにCanvasビットマップを使用した高レベルの操作が存在するのに、なぜクラスが必要なのですか。できるCanvas仕事をSurfaceするのに適さない状況の例を挙げてください。

2
グラフィックアーキテクチャドキュメント:source.android.com/devices/graphics/architecture.html
流行

回答:


223

ここにいくつかの定義があります:

  • サーフェスは、画面に合成されるピクセルを保持するオブジェクトです。画面に表示されるすべてのウィンドウ(ダイアログ、フルスクリーンアクティビティ、ステータスバー)には、描画する独自のサーフェスがあり、Surface Flingerはこれらを正しいZオーダーで最終的な表示にレンダリングします。サーフェスには通常、ダブルバッファレンダリングを実行するために複数のバッファ(通常は2つ)があります。アプリケーションが終了するのを待たずに、最後のバッファを使用してサーフェスフリンガが画面を合成している間、アプリケーションは次のUI状態を描画できます。お絵かき。

  • ウィンドウは、基本的にはデスクトップ上のウィンドウと同じです。ウィンドウのコンテンツがレンダリングされる単一のサーフェスがあります。アプリケーションは、ウィンドウマネージャーと対話してウィンドウを作成します。ウィンドウマネージャーは、ウィンドウごとにサーフェスを作成し、描画のためにアプリケーションに渡します。アプリケーションは、Surfaceで必要なものを何でも描画できます。ウィンドウマネージャにとっては、それは単なる不透明な長方形です。

  • ビューは、ウィンドウ内のインタラクティブなUI要素です。ウィンドウには1つのビュー階層がアタッチされており、ウィンドウのすべての動作を提供します。ウィンドウを再描画する必要があるときはいつでも(ビューがそれ自体を無効にしたためなど)、これはウィンドウのSurfaceに対して行われます。サーフェスがロックされ、描画に使用できるキャンバスが返されます。描画トラバーサルは階層を下って行われ、UIの一部を描画するために各ビューのCanvasを下に渡します。完了すると、Surfaceのロックが解除されてポストされ、描画されたばかりのバッファがフォアグラウンドにスワップされて、Surface Flingerによって画面に合成されます。

  • SurfaceViewはViewの特別な実装であり、アプリケーションが直接描画するための独自の専用Surfaceも作成します(通常のビュー階層の外、それ以外の場合はウィンドウの単一のSurfaceを共有する必要があります)。これが機能する方法は予想よりも簡単です。SurfaceViewが行うことはすべて、ウィンドウマネージャーに新しいウィンドウを作成するように依頼し、SurfaceViewのウィンドウのすぐ後ろまたは前にそのウィンドウをZオーダーするように指示し、それに合わせて配置することです。含まれているウィンドウでSurfaceViewが表示される場所。サーフェスがメインウィンドウの後ろ(Z順)に配置されている場合、SurfaceViewはメインウィンドウの一部を透明度で塗りつぶして、サーフェスが見えるようにします。

  • ビットマップは、一部のピクセルデータへの単なるインターフェイスです。ピクセルは、直接作成するときにビットマップ自体によって割り当てられる場合と、描画のためにCanvasをSurfaceにフックする際に内部的に発生するような、所有していないピクセルを指している場合があります。(ビットマップが作成され、Surfaceの現在の描画バッファーをポイントします。)

また、これが意味するように、SurfaceViewはかなり重いオブジェクトであることにも注意してください。特定のUIに複数のSurfaceViewがある場合は、停止して、これが本当に必要かどうかを検討してください。3つ以上ある場合は、ほとんど確実に多すぎます。


どうもありがとうございました!答えは物事をより明確にしました。ただし、CanvasをSurfaceに接続することに関する部分は不明です。そのような操作が必要な場所を想像することはできません。次に、その操作の例を示します。lockCanvas()メソッドを使用してSurfaceHolderから取得したキャンバス上にビットマップを描画しますか?
fyodorananiev

1
このようにして描画が行われますCanvasは2D描画APIです。oをサーフェスに描画する場合、Canvas 2d描画APIを使用して描画するために、そのバッファーを指すCanvasを作成する必要があります。
11

6
#hackbod's回答に加えてSurfaceViewViewオブジェクトでは不可能な2次スレッドからレンダリングすることもできます
Mohanraj Balasubramaniam

47

ウィンドウ、サーフェス、キャンバス、およびビットマップの概念的な概要

以下は、ウィンドウ、サーフェス、キャンバス、およびビットマップの間で相互作用がどのように発生するかについての非常に基本的で単純な概念的な概要です。
時々、視覚的な表現はねじれた概念を理解するのに大いに役立ちます。
このグラフィックが誰かの役に立つことを願っています。


4
Visualy 画像は、テキストよりも優れている:D
Mavenのツ

18

ビットマップは、単にピクセルのコレクションのラッパーです。他の便利な機能を備えたピクセルの配列と考えてください。

Canvasは、すべての描画メソッドを含むクラスです。それに慣れていれば、AWT / SwingのGraphicsクラスに似ています。円やボックスなどの描画方法に関するすべてのロジックは、Canvas内に含まれています。キャンバスはビットマップまたは開いているGLコンテナーに描画しますが、将来的に他のタイプのラスターに描画するように拡張できる理由はありません。

SurfaceViewは、Surfaceを含むビューです。サーフェスはビットマップに似ています(ピクセルストアがあります)。私はそれがどのように実装されているのかはわかりませんが、画面表示に直接関連するもののための追加のメソッドを備えたある種のビットマップラッパーであると思います(それが表面の理由であり、ビットマップが一般的すぎるためです)。サーフェスからCanvasを取得できます。これは、基になるビットマップに関連付けられたCanvasを取得しています。

あなたの質問。

1.Canvasには独自のビットマップがアタッチされています。Surfaceには独自のCanvasがアタッチされています。

はい、キャンバスはビットマップ(または開いているGLパネル)で動作します。Surfaceは、Surfaceがビットマップスタイルのピクセルストアに使用しているものであれば何でも操作できるCanvasを提供します。

2.ウィンドウのすべてのビューは同じサーフェスを共有するため、同じキャンバスを共有します。

いいえ。サーフェスビューはいくつでも持つことができます。

3.SurfaceViewはViewのサブクラスであり、他のViewのサブクラスやView自体とは異なり、描画する独自のSurfaceを持っています。

はい。ListViewが独自のListデータ構造を持つViewのサブクラスであるように。Viewの各サブクラスは、何か異なることを行います。


1
だから、BitmapおよびSurfaceピクセル店のちょうど異なる種であり、Canvasそれらのいずれかをラップすることができますか?
fyodorananiev 2011年

2
基本的にはい。Canvasがサーフェスに書き込めないことを除いて、それはSurfaceが独自のピクセルストアとして使用しているものに対して機能します(Androidソースを確認しないと、それが何であるか特定できません)。CanvasはビットマップとGLのコンストラクターしか提供しないため、これはおそらく何らかのビットマップ拡張機能です。
sksamuel 2011年

大きな助け、ありがとう!回答について2.私の質問では、SurfaceViewsではなく標準ビューを意味しました。たくさんのフィールドとボタンを持つRelativeLayoutがあるとします。この場合、Surfaceはウィンドウ全体にアタッチされ、ビュー階層のすべてのビューで共有されますか?
fyodorananiev

1
サーフェスは単なるピクセルのコレクションです。したがって、各サーフェスビューには独自のサーフェスがあり、それぞれを画面の異なる部分にレンダリングできます。画面を埋める必要はありません(これは、フルスクリーンゲームでグラフィックをレンダリングするための一般的な使用方法です)。
sksamuel 2011年

1
BitmapとSurfaceを同等のものとは思いません。サーフェスは、ウィンドウコンポジターであるサーフェスフリンガーが認識しているオブジェクトです。即ちなど、それが画面上で直接見るものであるスクリーン上のZオーダーを有する
hackbod
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.