「 Tegra2 」一覧

NVIDIA Nsight Tegra がすごい その5


あれからもうちょっとだけ、Nsight Tegra を触ってみました。
今回はデバッグによく使うであろう機能についてチェックしてみます。

ブレークポイントが張れて停止するのは今までにしっかりと確認してきました。
今回は、条件付きブレークポイントやメモリ領域の表示、使い慣れたVisualStudioでの変数表示形式指定などを見てみたいと思います。

早速下記のコードを書いてチェックしてみました。

まずメモリ領域の表示について。これは v を確保したときに、メモリウィンドウで表示させてみました。

メモリの表示はうまく動いているようです。
しかし、ウォッチウィンドウでポインタを要素数指定して配列のように表示する機能については、うまく機能しないようです。
画像では、”v,10″としていますが、配列表示できていないことがわかります。

続いて条件付きブレークポイント。
2つめのforの中で、i == 6 の時にブレークするようにして実行してみました。
このときは以下の画像のような結果となり、条件で停止してくれませんでした。

Visual Studioのデバッガを深く慣れていて機能を使いこなしている人にとっては、ちょっと不満が残りそうです。
その一方で、単純にブレーク設定できればいいという人にとっては十分役立ってくれそうです。

gdb を直接触るタイプ(ndk-gdb)との差が付いてきてしまったように感じました。
そこでそろそろndk-gdbでは今現在どのくらい使い物になるのか、確かめてみたいと思います。


NVIDIA Nsight Tegra がすごい その4


前回、JniProxyタイプではうまくいかないです~の続きです。

動作させるためには、JavaJniAppのパッケージ(APK)に libNativeAppMain.so を含められればそれで完了です。
これをどうやって行うかですが、強引には以下の手順で実現することが可能です。

  • NativeAppMainをビルド。soファイルが出来る
  • JavaJniAppのビルド1。まず libJavaJniApp.soが作成される
  • JavaJniAppのビルド2。Java部分のコンパイルが実行される

上記のJavaJniAppのビルド1 or 2のタイミングで NativeAppMainの so ファイルを JavaJniApp/libs/armeabi-v7a の中にコピーしてあげればよいです。

成功すれば Apkファイルの中に libNativeAppMain.so が入っています。

一度実行してログを確認してみます。(起動後、戻るボタンでホームに戻るという操作を行っています)
うまく動いていればこのようにログが出ているはずです。

この時に、アプリケーション本体である nativeappmain.c の各関数にブレークポイントを仕掛けて、同じように実行してみます。
下記のスクリーンショットに示すように、ちゃんとブレークポイントが有効となって停止します!すばらしい。

タイミングコピーの自動化を狙う

先ほどの、手動でlibNativeAppMain.soを強引にタイミングを見計らってコピーするという方法はちょっと手間です。
タイミング失敗によるとまたビルドし直しになるし、ここは何とかして自動で解決するようにしたいです。

Nsight Tegra は、どうやら vs-android をも取り込んでいるようです。vs-androidではAntを使用していましたし、よくよく動作を見るとビルドのタスクをこなしているのはAntのようです。
ということは Ant の設定やスクリプトを変更すれば、この自動化も出来そうな気がします。

そこで build.xml の中身を覗いてみると、以下のようになっており、どうやらカスタマイズの余地がありそうです。

まずは JavaJniApp の build.xmlと同じ場所で custom_rules.xml を作成して、中身を以下のように設定します。

そうして、ビルドを実行してみると、以下のように上記の設定が実行されたことが確認できます。

JavaJniAppのsoが出来たタイミングが良さそうだろうと思うので、post-complie タイミングで実行されるように、下記の設定を custom_rules.xmlに記載します。

これで JavaJniApp をビルドして、既にできあがっている本体のsoをコピーすることが出来るようになります。

改善点は、上記の場合コピー元フォルダが Debug と決めうちしてあるため、構成に応じて変更できればさらに便利になりそうです。
改良した custom_rules.xml を下記に示します。これでビルド構成Debug/Releaseに対応できます。

まとめ

Eclipse+NDKでは苦しい JniProxy タイプのソースコードレベルのデバッグもNsight Tegraならば可能でした。
最近のWinGDB for Mobile Systems では試していないですが、このタイプのデバッグも出来るとなるとかなり便利です。
個人的には開発においては、Tegra(ICS以降)のAndroidを準備すると幸せになれると感じました。


NVIDIA Nsight Tegra がすごい その3


今回はNDKの開発で、割と使われるJNIProxyという手法で Nshight Tegra のデバッグブレーク機能は有効になるか?を確かめてみたいと思います。

このJniProxyという方法は、Android上ではアプリケーションの実行体イメージがメモリ上にまだ存在する場合、再利用してアプリケーションが動く、という挙動に対して解決する方法の1種です。
C/C++ネイティブ開発者の間では、.so 内のグローバル変数が初期化されずにアプリケーションが起動したように見えます。

詳しくはこちら(ホイール欲しい ハンドル欲しい: Android NDKの初期化とdllの分離)で説明されている内容です。

Java – JniProxy.so — Application.so というように、
JavaからはJniProxy.soを操作し、JniProxyが本当の意味のアプリであるApplication.soをロード・アンロードします。

Nsight Tegraを導入した Visual Studioでこのようなプロジェクトを作成するには、前回説明した複数のライブラリを用いて .so を作成するという方法に近い物があります。1点違う点があるのは、両者が so となっている点です。まずは、2つのプロジェクトを作成して、今回の概観を作ってみます。

  • NativeAppMain (ネイティブアプリケーションの本体)
  • JavaJniApp (JniProxy.soをもつJavaアプリケーション)

プロジェクトのタイプは、JavaJniApp は Android Application With Native Code で作成し、
NativeAppMainは Android Native Application で作成します。
これらをまとめるソリューションは testJniProxy として作成しました。

作成して、とりあえず必要なファイル名を変更したものが以下のようになります。

続いてプロジェクトの設定を変更します。
NativeAppMain は今回は .so 形式となるので Configuration Type を Dynamic Library(*.so)に変更します。
また JavaJniApp は NativeAppMain に依存するようにしておきます。
そして、JavaJniAppのプロジェクトの設定では、ライブラリ dl を使用するように変更しておきます( -l”dl” を追加のライブラリに入れる)

ここまで設定できたら、各ソースコードを編集します。
ほぼ上記で紹介したサイトのコードのままなのですが以下のようになります。
まずは動作確認の意味もかねて、onCreateでロードして、onPauseで終了が呼ばれるだけの単純なものにしてあります。

JniProxy.cpp

JavaAppMain.java

NativeAppMain.c

ここまででとりあえず必要な物はそろってはいるのですが、このまま実行するとNativeAppMainのロードが実は出来ません。
その理由は、NativeAppMain.so が JavaJniApp の apk の中に取り込まれないからです。
ちなみに libNativeAppMain.so は ソリューション以下の Android/Debug の中に存在はしているのですが、
今回のケースでは取り込まれないんですよね・・・。
VisualStudioのビルド前後のイベントを使用しても、取り込まれるようには設定できませんでした。

(解決策は次回へ続く。)


NVIDIA Nsight Tegra がすごい その2


NVIDIA Nsight Tegra 検証の第2弾です。
前回はほぼデフォルトで作成される状態のサンプルプログラムを実行させての動作確認だったので、今回はもう少し実際にあり得るケースで正常にデバッグが出来るのか、を試してみたいと思います。

今回のケース想定

 

2つのスタティックライブラリを使用して、.so を作成し、Javaから利用する。
要は libXXXX.a を複数リンクして、アプリケーション本体となる.soを作成、Javaはその呼出までの役割に過ぎない、というケースです。
ほぼ定番のケースだと思います。これで実用になるのか、試してみたいと思います。

こんなフォルダ構成で作成します。AppMainは Java+Native の「Android Application with Native code」タイプで作成します。

NVIDIA Nsightでスタティックライブラリ用プロジェクトはどう作成するか、ここが問題です。
現時点では、ウィザード等では設定できないようだったので、やや強引ですが既存のプロジェクトタイプで作成した後、設定を変更して対応することにします。

スタティックライブラリ用プロジェクトの作成方法

 

最初のプロジェクト作成で 「Android Native Application」を選択します。これはNativeActivity用の設定ですが、
ファイルの削除と設定変更だけで割と簡単にネイティブのスタティックライブラリ用に出来るので利用させて貰うことにします。

パッケージ名を聞かれますが、スタティックライブラリには不要なので適当に入力しておきます(例:org.aaa)。
プロジェクトが作成できたら、下記画面の通り、native_app_glue 関連のコードを削除し、デフォルトで作成される main.c の名前を変更しておきます。また、main.c の中身も全部削除して、動作検証用のコードにしておきます。
すでに既存のソースコードを持っているなら、main.cを削除して、それを登録しておくのでも問題ないでしょう。

そして、出力するタイプを “Make Application” から ”Static Libaray(.a)” に変更します。

ここまでの作業を同じように繰り返して、lib2を作成します。

lib1のソースコード内容例

lib2のソースコード内容例

続いて、「Android Application with Native Code」タイプで AppMain を作成します。
AppMain.java の onCreateメソッド内で、既に作成されている appmainNative() を呼び出すようにしておきます。
その後、AppMainのネイティブコード部分(AppMain.c)で、今用意したlib1,lib2の関数を呼出して、ブレークポイントがはれるかを確認してみます。
作成したら、AppMainのプロジェクトをスタートアッププロジェクトに指定しておきます。

AppMain.cのコード内容例

コードを作成したら、プロジェクトの設定を開いてで liblib1.a と liblib2.a をリンクするように修正します。
今回のフォルダ構成では、testTwoLibsフォルダ以下に Android/Debug というフォルダが作成され、この中に .a のファイルが出力されるようになっています。
“構成プロパティ” / Linker / Additional Library Directories の部分にこのフォルダを指定します。

そして、リンクするライブラリの指定は、“構成プロパティ” / Linker / Additional Dependencies の部分に指定します。
このときに、従来のVCではライブラリファイル名を設定していましたが、Nsight Tegraの場合では、-l”(ライブラリ名)” と指定するようです。(このやり方がわかる以前は、CommandLineで直接設定してました・・・)
うまくいかない場合には、CommandLineで直接指定するなどで対処できそうです。
gcc環境であることもポイントで、ライブラリファイル名が、libhoge.a の場合、上記のライブラリ名では hoge と指定する点に注意してください。

今回の例では、-l”lib1″ -l”lib2″を指定しておきます。

続いて、ブレークポイントを下記のように設定しておきます。今までの経験から Java – C の接続部である上記のコードにブレークポイントが張れて機能することはわかっているので、次の2点を確認したいと思います。

  • 外部ライブラリへのステップインは出来るか?
  • 直接外部ライブラリのブレークポイント設定は有効になるか?

ここで、外部ライブラリとは AppMain.so が利用している .a のファイルを指しています。

実行して、上記の1つめのブレークポイントで停止した後は、ステップインで lib1 のソースコード内へ突入できるかを確認してみます。

F5で実行して、mylib1Test関数にステップイン(F11)してみると、下記のように正常にステップインできました。

さらにこの後、F5で実行を継続させて様子を見ていると、下記のように正常に lib2 の関数内でブレーク発動できました。

まとめ

複数のスタティックライブラリを使って、soファイルを生成するタイプのアプリケーション開発では、今回試した内容からほぼストレス無く開発が出来るのでは無いかと思います。
また、記事で詳細に触れてはいないですが、lib1,lib2をソリューションから除外して、AppMainだけをリビルドして同様のことを試してみたところ、こちらも正常に関数内へステップインできました。
Nsight Tegraの出来の良さに感激です。

気になった点とか躓いた点とか

上記のテストで、アプリケーションが起動できない、妙な動きをするような場合は以下の点を確認してみてください。
自分でも陥ったポイントです。他にも発見&解決できた人は是非コメントくださいませ。

アプリケーションが起動できない(onCreate以降すすまないっぽい)
純粋にApplication with Native Code のプロジェクトを作成して、それが起動できるかどうかを確認。うまくいけばそれ以降の部分で問題があることになります。この後確認するのは lib1, lib2 が 正しく .a を出力する設定になっているかどうか、です。
自分の場合には、変更することを忘れて、ここを .so のままにしていたことがありました。このとき問題発生でアプリケーション終了という流れで、すごく悩みました。

他には、スタートアッププロジェクトをlib1やlib2のままになっていないかを確認。元々がNativeActivity用のプロジェクトを流用しているので、実は実行させようとすればできちゃうようで・・・。


NVIDIA Nsight Tegra がすごい


NVIDIA Nsight Tegra を導入してみました。これは Tegra Android Development Pack に含まれています。
これが結構便利で、Android のNDK開発では個人的には最有力候補になると思っています。
一昨年くらいの TADP は個人的にはマイナス評価で検証後見送ったのですが、今回は多少のデメリットがあってもこれを選択したい勢いです。

さて入手には登録を必要とするのですが、ちょっとややこしい感じだったので、まずはそれについて説明しておきます。
NVIDIAのDeveloper Programに登録し、ログインを行います。
そして、Tegra Registered Developer Program と Nsight Visual Studio Edition Registered Developer Program の2つを有効化します(ApprovedステータスになっていればOK)。
注意するのはさらに、有効化されたよメールが手元にくるまで、実際には有効化されていないということです。
このメールがくるまでしばらく待ちましょう。

Tegra Android Development Packは今現在 2.0 で、ダウンロードできた物は 2013-02-06 リリースのもののようです。
これをインストールすると Nsight Tegra もインストールされました。

Nsight Tegra は Visual Studio 2010 SP1 に統合され、対象とするAndroidのバージョンは 4.0以降に対応するようです。
先日のICONIA Tab A500 をICSアップデートの真の目的はこのためだったのです!

Nsight Tegra で出来ること

 

Visual Studio 2010 上で、JavaもC(ネイティブ)も同時に開発可能です。
そしてすごいのはビルドはもちろんのこと、待望のデバッグも可能となっています。今まではEclipseで何とかがんばっていたソースコードデバッグも、これだけで可能になります。Javaの部分ですらブレークポイントが設定できます。そしてデバッグ出力ウィンドウで、”Android Logcat”を選択すれば、ログの確認もVisual Studioで行えます。
ただ、Visual Studio だから仕方の無いことなのかもしれませんが、Javaに対するサポートは弱いようで、インテリセンスが効きませんでした。

インストールして試してみる

 

まずはプロジェクトを新規作成して出来るテンプレで設定および動作の確認をしてみます。
ここでは、Java+Nativeの構成をとれる Android Application with Native Code を選択します。プロジェクトの作成する場所は、スペースを含まないパスにする必要があるようなので、この点にだけ注意します。

続いて、パッケージ名を指定します。

logcatの出力をVisual Studioで確認出来るように有効化します。有効化した後は、出力ウィンドウで 「Android Logcat」 が選べるようになります。

最後に、プロジェクトの設定を開き、Javaもネイティブも両方ともデバッグブレークできるように設定を変更します。

これでひとまずの設定は完了です。

動作を確認するために、Java部分とC言語部分をちょっとコードを変更しておきます。
また、コードを編集した後には、ブレークポイントを仕掛けておきます。

C言語部分

それぞれにブレークポイントを仕掛けて、いつも通り F5 を押してデバッグ実行させてみます。もちろん、対象となるデバイスをUSBで接続しておいてください。

実行開始状態の図。ちょっと時間がかかるようです。

そして、実行後ブレークポイントで停止している図。

まとめ

このNsight TegraはAndroid開発、特にネイティブに重点を置いて開発する場合には、現時点では最強を狙える拡張だと思います。もうしばらく試用&検証してみてどのくらいのポテンシャルを秘めているか、探ってみたいと思います。WinGDB for Mobile Systemsが Androidのネイティブ開発で最強と思っていたのですが、なかなか製品として出てこないですね。そんな中このNVIDIA Nsight Tegra の登場は非常にうれしい限りです。

情報元: https://developer.nvidia.com/nvidia-nsight-tegra


Tegra2での不具合


Tegra2でだけ特定のエラーメッセージが出てうまく動かないということに悩まされていました。調べてみても、日本じゃ該当なし、海外で報告があるけどよくわからないまま終了というやっかいな状態でした。

それが今回ようやく解決方法含めてわかったので、記事にしてみました。
戦っていたエラーメッセージは 、P1202: Texture’s gl states do not match with shader’s というものです。

エラーメッセージのタイミング

このエラーメッセージはどこで出てくるのかを調べてみると、 GL_VALIDATE_STATUS を引数に、glGetProgramiv を呼び出して、エラー時に glGetProgramInfoLog を呼び出して、その中のメッセージに格納されて表示されてくるようです。

つまり、glValidateProgram の部分がまずい!ということです。
このAPIの説明を確認すると、現在のシェーダーが正常に実行できるか検証するという意味合いのAPIとのことです。
通常は、glUseProgramした後で、 glValidateProgramで実行できるかを確認する、という使い方を想定していると思われます。決して、シェーダーのglLinkProgram後に検証というものではなさそうです。

つまり、実行するときの状態がそろった上で 検証をしなくてはなりません。
そのため、使用するテクスチャ の状態が正常か、サンプラーの状態は正しいか、などすべての条件が考慮されます。 今回引っかかってしまったのは、テクスチャを使うシェーダーで、テクスチャを設定していない(バインドしていない)状態で、glValidateProgram を呼び出してエラーとなっていました。

このメッセージで悩まされた場合には、その時の状況が何か正しくないのだと思います。設定されている各種状態を丁寧に見た方がよいと思います。
なお、Mali-400, Adreno, PowerVR あたりの ドライバではこのあたりはきちんと検証してくれないのかエラーとなることは今のところありませんでした。(故に発見がおくれた&Tegra2のバグだ!と考えてしまいました)

最後になりましたが、Javaからだとタイミングが悪くてもこれらのエラーメッセージはでないようです。