9

drawRect毎回何千ものポイントを再描画する代わりに、 「画面上の画像をキャッシュする」方法と追加の描画を行う方法がいくつかあると思います。その画像に追加し、必要なときにその画像を表示しdrawRectます。

  1. BitmapContext を使用してビットマップにdrawRect描画し、 でこのビットマップを描画します。

  2. を使用CGLayerして描画しCGLayerますdrawRect。この画像はグラフィックス カードにキャッシュされるため、方法 1 よりも高速になる可能性があります (iOS の「メモリ警告」の RAM 使用量にはカウントされませんか?)

  3. に描画しCGImage、ビューのレイヤーを使用します。view.layer.contents = (id) cgimage;

CALayerしたがって、3つの方法があるようですが、方法(3)では a のみを使用しCGImageてそれを達成 できると思います。(2)CALayerのように、それ自体では画面イメージをキャッシュできません。CGLayer

方法 (2) は 3 つすべての中で最速であり、これを達成できる他の方法はありますか? 私は実際にいくつかの画面イメージをアニメーション化することを計画しており (そのうちの 5 つまたは 6 つをループします)、CADisplayLink60fps の最高フレーム レートを試してみます。方法 (1)、(2)、または (3) のいずれかがグラフィックス カードのメモリを使用するため、RAM を使用しないため、iOS からもメモリ警告が表示される可能性は低くなりますか?

4

2 に答える 2

12

あなたが尋ねた最近のいくつかの質問に基づいて、CGLayers と CALayers を完全に混同しているようです。これらは異なる概念であり、実際には互いに関連していません。CGLayer は、コア グラフィックス コンテキストのキャンバス内で繰り返しコンテンツをレンダリングするのに役立つコア グラフィックス コンストラクトであり、単一のビュー、ビットマップ、または PDF コンテキスト内に限定されます。CGLayer を使用する必要があったことはめったにありません。

CALayer はコア アニメーション レイヤーであり、iOS 内のすべての UIView (および Mac 上のレイヤーでサポートされた NSView) をサポートする 1 つのレイヤーがあります。これらは UI アーキテクチャの基本的な部分であるため、iOS では常にこれらに対処します。各 UIView は事実上 CALayer の軽量ラッパーであり、各 CALayer は事実上 GPU 上のテクスチャ付きクワッドのラッパーです。

画面上に UIView を表示するとき、コンテンツを初めてレンダリングする必要があるとき (または完全な再描画がトリガーされるとき)、線、弧、およびその他のベクトル描画 (場合によってはラスター ビットマップも含む) を取り、ラスタライズするためにコア グラフィックスが使用されます。それらをビットマップに。このビットマップはアップロードされ、CALayer を介して GPU にキャッシュされます。

ビューの移動、回転、スケーリングなどのインターフェイスの変更の場合、これらのビューまたはレイヤーを再描画する必要はありません。これはコストのかかるプロセスです。代わりに、GPU で変換され、新しい場所で合成されます。これにより、iOS インターフェイス全体で見られるスムーズなアニメーションとスクロールが可能になります。

したがって、最高のパフォーマンスが必要な場合は、Core Graphics を使用して何かを再描画することは避けてください。CALayers または UIView 内でシーンのどの部分をキャッシュできるか。古いスタイルのアニメーションでは、アニメーターがシーン内のすべての変更を再描画する代わりに、セルを使用してシーンの一部を移動する方法を考えてみてください。

最新の iOS デバイスでは、何百もの CALayer を画面上でスムーズにアニメーション化することが簡単にできます。ただし、パーティクル システムなどで何千ものポイントを処理したい場合は、そのために OpenGL ES に移行し、GL_POINTS を使用してレンダリングすることで、より適切に処理できるようになります。セットアップにはさらに多くのコードが必要になりますが、あなたが求める「何千ものポイント」に対して許容できるパフォーマンスを得るための唯一の方法かもしれません。

于 2012-05-27T21:47:13.490 に答える
5

グラフィックのキャッシュとキャッシュされたグラフィック コンテンツの変更の両方を可能にする 1 つの高速な方法は、メソッド (1) と (3) のマッシュアップです。

(1) ビットマップに裏打ちされた独自のグラフィックス コンテキストを作成し、それに描画し、後で必要に応じていつでも変更します (1 つまたは数千のポイントを時々段階的に追加するなど)。残念ながら、iOS デバイスのディスプレイにビットマップを直接取得する方法がないため、表示されません。

さらに、

(3) あるフレーム レート (60 Hz、30 Hz など) で、ビットマップが汚れている (変更されている) 場合、ビットマップ コンテキストを CGImage に変換し、その画像を CALayer のコンテンツに割り当てます。これにより、ビットマップのメモリ全体が変換され、GPU テクスチャ キャッシュにコピーされます (これは遅い部分です)。次に、コア アニメーションを使用してレイヤーで必要なことを行い (フラッシュ、合成、ウィンドウの周りに飛ばすなど)、ビットマップから作成されたテクスチャを表示します。舞台裏で、コア アニメーションは最終的に、GPU がそのテクスチャを使用していくつかの合成ウィンドウ タイルにクワッドをスローし、最終的にはデバイス ディスプレイに送信されます (この説明では、おそらくグラフィックスと GPU パイプラインのステージ全体が省略されています)。メインの UI 実行ループで、必要に応じてすすいで繰り返します。この方法に関する私のブログ投稿はこちら.

使用中の既存の GPU テクスチャの内容を部分的に変更する方法はありません。完全に新しいテクスチャのアップロードに置き換えるか、テクスチャのレイヤーの上に別のレイヤーを合成する必要があります。そのため、使用中のメモリの 2 倍を保持することになり、一部は CPU のアドレス空間に、一部は GPU テクスチャ キャッシュに保持されます。

于 2012-05-28T06:28:22.533 に答える