12

私は2Dチュートリアルに取り組んでおり、SamsungGalaxyTabで現在のチュートリアル部分をテストすることができました。

チュートリアルでは、デフォルトのアイコンを画面上でランダムに移動するだけです。タップするだけで、新しい動くアイコンを作成します。画面に25個以下の要素がある限り、Galaxyではすべてが正常に機能します(常に60 fps)。

26番目の要素を使用すると、フレームレートは25fpsに低下します。

画像のサイズ/サイズをはるかに大きいものに変更すると、26番目の要素の前に25fps未満に達します。それで大丈夫です。しかし、実際には再現性のない要素の数では、フレームが10fpsから1fpsに(ほとんどの場合)低下します。

Nexus Oneでは、150個の要素を追加しても、50fpsを維持できます。

私が行ったこと:ビットマップ変数を静的なものに変更したので、すべての要素が独自の画像を持っているわけではありませんが、すべて同じものを使用しています。それは振る舞いを取り除きました、しかし私はこの解決策が良いものであるとは思えません。マジックナンバー25は、そのように25の異なる画像しか使用できないことを示唆しています。

誰かがこの動作を引き起こす可能性があるものを知っていますか?サムスンの修正されたAndroidバージョンのバグですか?

私のサンプルEclipseプロジェクトが利用可能です。サムスンの所有者がサンプルでパフォーマンスを確認していただければ幸いです。

編集

同僚が解決策を見つけました。彼はビットマップのロード方法を変更しました

mBitmap = BitmapFactory.decodeResource(res, R.drawable.icon);

mBitmap = BitmapFactory.decodeStream(new BufferedInputStream(res.openRawResource(R.drawable.icon)));

しかし、なぜそれがこのように機能するのか、まだ実際にはわかりません...

4

3 に答える 3

5

さて、私はあなたのプロジェクトを見てきましたが、すべて問題ないように見えますが、フレーム レートの低下の原因について 1 つの考えがあります。

実行時にオブジェクトを割り当てています。そうしないと、開始時にすべてのオブジェクトを作成することになるため、大幅な低下に直接気付くはずです (私の解決策で問題が解決しない場合)。

そうは言っても; オブジェクト プールで問題が解決するかどうかはわかりませんが、試してみてください。コンストラクターでオブジェクトを初期化し、この呼び出しを行う代わりにonTouchEvent():

new Element(getResources(), (int) event.getX(), (int) event.getY())

mElement.add(objectPool.allocate())オブジェクトプールがプール内の未使用のオブジェクトを見つける場合、 のようなものが必要です。また、そのオブジェクト プールには指定された量のオブジェクトが必要であり、そこから、このエラーの原因が割り当てであるか、それ以外であるかを確認できます。

26 番目の要素では、フレーム レートは 25 fps に低下します。

これを実装するとき (または実装する場合) は、フレーム レートが直接低下するのを確認する必要があります (ただし、これで問題が解決しない場合)。これは、オブジェクト プールにより、開始時に固定量 (たとえば 100 要素?) が割り当てられるためです (しかし、視覚的には使用していません)。

また、Android 用のサンプル アプリケーションの 1 つでメモリ プール パターン (オブジェクト プール) を使用しました。そのサンプルでは。オブジェクト プールを使用して (実行時に割り当てずに)Canvasに行を追加します。onTouchEvent()そのソース コードでは、オブジェクトの合計量を簡単に変更し、チェックアウトして自分で試すことができます。私のサンプル アプリケーション (およびソース コード) を見たい場合は、コメントを書いてください。まだ公開されていないので、喜んで共有します。私のコメントはスウェーデン語ですが、変数とメソッドは英語なので理解できるはずです。:)

サイドノート:あなたは、あなたのBitmap static. 現在のように、要素には の異なるインスタンスがあり、新しいオブジェクトを構築するたびBitmapに new を割り当てる必要があります。これは、同じリソースを使用している場合、Bitmapすべてのオブジェクトが異なるオブジェクトを指していることを意味します。は完全に有効な解決策です (ただし、マジック ナンバー 25 は奇妙に思えます)。Bitmapstatic

このBitmapケースは、システムと比較することができますOpenGL。すべてが同じリソースを使用する必要がある 20 個のオブジェクトがある場合、2 つの解決策があります。それらは同じ VRAM テクスチャを指すか、別の VRAM テクスチャを指すことができます (使用していない場合のようにstatic)。まだ同じリソース。

編集

これは、メモリ プールを示すAndroid 用のサンプル アプリケーションです。

を使用したソリューションに関してはBitmapFactory、おそらくそのクラスがどのように機能するかによって異なります。よくわかりませんが、同じリソースでもいずれかのdecode...()方法で new を生成していると思います。メモリから再利用してBitmapいる可能性がありますが、それは大きな推測です。new BufferedInputStream(res.openRawResource(R.drawable.icon))BufferedInputStream

(その場合) すべきことは、リソースをデコードし、そこからの参照を Panel クラスに格納し、new Element(bitmapReference, ...)代わりにその参照を に渡すことです。Bitmapそのようにして、一度だけ割り当てるだけで、すべての要素がメモリ内の同じものを指しています。

于 2011-04-20T14:12:00.567 に答える
3

HTC Desire HDでコードを試しましたが、Android 2.2ターゲットを使用して20番目の画像を追加すると、フレームレートが使用できなくなります。androidバージョン2.1と同じコードをエクスポートすると、正常に動作し、200を超えるインスタンスを処理できました。2.2でGraphicObjectクラスのインスタンスを作成することと関係があると思いますが、よくわかりません...

于 2011-03-18T11:38:49.207 に答える
1

私はこの問題に光を当てることができると信じています。

少なくとも私の Galaxy S、Gingerbread 2.3.5 では、最初のコードは私の test.png を Bitmap.Config = ARGB_8888 で Bitmap にロードし、2 番目のコードは Bitmap.Config = RGB565 でロードします。奇妙なことに、Gingerbread はデフォルトで 32 ビット サーフェスを作成するはずですが、RGB565 の「レンダリング」(drawBitmap のネイティブ呼び出しをプロファイリングして比較しました) ははるかに高速です。

したがって、全体としてあなたの例により適切な2番目のアイデアは、ARGB888ビットマップにはアルファがあるということです。その場合、25以上のスプライトの重なり合う画像をレンダリングすると、アルファ計算アルゴリズムにボトルネックが発生する可能性がありますが、RGB565画像は問題ありませんそして速い。

于 2012-05-20T17:52:03.623 に答える