「 2014年04月 」一覧

Android 4.3あたりから外部SDのパスが変わった? その2


前回の内容でパス決めうちはちょっと・・・。ということで終わっていましたが、あれからもうすこし悪あがきをしてみました。

「vold.fstab の設定がダメならば環境変数のほうではどうだろうか?」ということで Galaxy S4 4.4.2 のもので環境変数を表示させてみました。
一部抜粋ですがこんな結果になりました。

Galaxy S4 (4.4.2)の場合

framework/stayrotation.jar:/system/framework/smartfaceservice.jar:/system/framew
ork/commonimsinterface.jar:/system/framework/org.codeaurora.Performance.jar
EMULATED_STORAGE_SOURCE=/mnt/shell/emulated
ANDROID_SOCKET_adbd=11
EMULATED_STORAGE_TARGET=/storage/emulated
ANDROID_STORAGE=/storage
MKSH=/system/bin/sh
EXTERNAL_STORAGE=/storage/emulated/legacy
RANDOM=22529
ASEC_MOUNTPOINT=/mnt/asec
SECONDARY_STORAGE=/storage/extSdCard
USER=shell
HOME=/data

見事に extSdCard のマウントポイント示す環境変数が存在していました。これを使えば少なくとも S4 ではパスのハードコードを避けられそうです。
従来も環境変数で外部SDのパスを取得する方法があったようですが、それは EXTERNAL_STORAGE の参照を取得するものがほとんどで、これだと期待した動きにはなりません。ポイントは SECONDARY_STORAGE の環境変数を見にいくことが必要、ということでしょうか。

他の機種では?

手元にある XPERIA Z1 Compact ではどうなっているか確認してみました。

XPERIA Z1 Compact(4.3)の場合

y-msim.jar:/system/framework/com.sonyericsson.uxpres.jar:/system/framework/qcom.
fmradio.jar:/system/framework/oem-services.jar:/system/framework/WfdCommon.jar:/
system/framework/qcmediaplayer.jar
EMULATED_STORAGE_SOURCE=/mnt/shell/emulated
ANDROID_SOCKET_adbd=13
EMULATED_STORAGE_TARGET=/storage/emulated
ANDROID_STORAGE=/storage
MKSH=/system/bin/sh
EXTERNAL_STORAGE=/storage/emulated/legacy
LD_PRELOAD=/vendor/lib/libNimsWrap.so
EXTERNAL_STORAGE_USB=/storage/removable/usbdisk
RANDOM=14748
ASEC_MOUNTPOINT=/mnt/asec
SECONDARY_STORAGE=/storage/removable/sdcard1
USER=shell
HOME=/data

ICONIA TAB A500 (4.2.2)の場合

ちょっと前のICONIA TAB A500の 4.2.2 へバージョン更新したものがあったのでこれでも確認してみました。
rootを取得状態なので一部参考にならないかも・・・。

PATH=/sbin:/vendor/bin:/system/sbin:/system/bin:/system/xbin
LOOP_MOUNTPOINT=/mnt/obb
MKSH=/system/bin/sh
ANDROID_DATA=/data
ANDROID_ROOT=/system
EMULATED_STORAGE_TARGET=/storage/emulated
ANDROID_CACHE=/cache
SHELL=/system/bin/sh
ANDROID_STORAGE=/storage
ANDROID_SOCKET_adbd=10
USER=root
HOME=/data
EXTERNAL_STORAGE=/storage/emulated/legacy
ANDROID_ASSETS=/system/app
TERM=linux
RANDOM=22311
ASEC_MOUNTPOINT=/mnt/asec
SECONDARY_STORAGE=/storage/sdcard1
ANDROID_PROPERTY_WORKSPACE=9,49152
ANDROID_BOOTLOGO=1

やはり結果が違いました。しかし、SECONDARY_STORAGE という環境変数は存在しており、これが外部SDカードへのマウントポイントとなっていそうです。

対処コード

これらの問題に対応するために、環境変数から外部SDカードのパスを取得するコードを書いてみました。
手元にあったGalaxy S2,S4、XPERIA Z1 Compact,ICONIA TAB A500 で動作確認しています。ただし、ネットの情報をみているとこれだけの環境変数参照では全然ダメらしいですが。

GalaxyS2というか Android 2.x系の話だと思いますが、USBでPCと接続の際にPCにマウントされている状態では上記で取得したパスにアクセスすることができません。これは既知の内容となっているかもしれませんが、ご注意下さい。


Android 4.3あたりから外部SDのパスが変わった?


巷ではマルチユーザーの対応が入ったために4.2から変更されたと言われています。手元では4.3,4.4の端末があるのでこれで現象を確認しました。

androidのプログラム作成時において、多くの場合はリソースとして本体と同じ場所の resや assetsの中に配置するでしょう。ただ頻繁に更新されるファイル”群”や、更新頻度の低い巨大なファイルの場合、毎回APK作成されるのもちょっと無駄です。

このように考えて自分では、ファイルの差し替えがPCから楽にできるように外部SDカードのほうに各種リソースを配置していました(開発時に限る、配布時はこれではマズイと思います)。
このとき、配置してほしい場所がわかるようにパスを表示していたのですがこれが 4.3以降妙なパスになっていることに気付きました。

そのパスがこんな感じです。
”/storage/emulated/0/com.example.testandroid/”
外部SDのマウントポイント+パッケージ名を自分ルールのパスとしていたのですが、今回から emulated とか /0 とか妙な物がみえています。

そして律儀にこのパスにファイルを書き込もうとPCから操作してみたのですが、なんと書き込みができません!
DDMSで上記のファイルパスが出来るようにディレクトリ作成しようとしてNGでした。
この結果、ファイルの書き込みが出来なくなった!とちょっと大騒ぎでした。
しかもこの emulated/0 がリードオンリーでマウントされているのでホントに任意ファイルがおけなくなったか、と思いました。

4.4.2の端末での結果

Environment.getExternalStorageDirectory() 関数では、/storage/emulated/0 が取得できました。getExternalStoragePublicDirectory(Environment.DIRECTORY_MOVIES) などとすると、/storage/emulated/0/Movies が取得できました。

先ほどの話にもありましたが、このフォルダパスは DDMS では辿ることができません。
adb shell でシェルに入ってそのパスを覗こうとしても同様にパスが存在しないと言われてしまいます。

取得できるパスについて

TechBoosterさんの記事”マルチユーザ対応 Android 4.2以降の内部ストレージと外部ストレージ (4.4対応を追記)”によるとこう書かれています。

「ExternalStorageで統一されており内部・外部の区別はありません(区別なく扱えるように内部/外部を判定するメソッドがあります)。過去、フラッシュメモリ容量が少ない時代はExternalStorage(拡張ストレージ)としてSDカードが活用されていましたが内蔵メモリが増えるに従ってSDカードが不要となり、現在のようなアプリケーション領域・内部ストレージ・外部ストレージの3つが入り組んだ構成に至っています。」

結局 getExternalStorageDirectory も内部ストレージの絶対パスを取得するという状態のようです。
関数の名前とこちらが期待する実際の動きは違っていて、内部ストレージに関するものとなっています。

GalaxyS4 4.4.2 の場合

結局一番有効であると言われている vold.fstab の記述からパスを抜いてくればいいのか?と考えて、シェルでそのファイルの中身を見てみましたがこれでもダメなようです。
下記に示す1行のみしかマウントポイントがありませんでしたし、/storage/sdcard1というパスがそもそも存在していないようで cd で移動すらできません。

”dev_mount sdcard /storage/sdcard1 auto /devices/platform/msm_sdcc.3/mmc_host”

実デバイスのフォルダを丁寧に調べてみると、本物の外部SDカードは /storage/extSdCard にマウントされていて、これがPCから接続したときにも “Card” で表示される中身となっているようです。さすがにこのパスを決めうちで使うのも気が引けます・・・。


VS-Droidを試してみる


前回概要だけだったので今回は早速VS-Droidを触ってみようと思います。

VSDroidのインストール

vsdroid
インストール画面ではこのように表示されました。
Visual Studio 2005 から 2012 まで対応しているようです。またMSBuildを使ったビルドシステムのために VS-Android をインストールできるようになっているようです。ただここでは素のVSDroidを確認したいので、導入しないでおきます。

動作確認

Visual Studio 2012 を起動して結果を確認してみます。
下記に示すように構成が増えていました。また上部のメニュー部分にも VSDROID という項目が見えます。

vsdroid-visualstudio-1

HelloJni のサンプルをまずインポートしてみようと思います。
「Import Java+native Android project」の構成を選んで実行します。

するとインポート元の Android.mk を指定するように聞かれるので、Android NDKに含まれていた hello-jni(android-ndk-r9b\samples\hello-jni\jni) を開くことにします。

下記のような画面が現れて、各ファイルをread-only にするかどうか選択できます。
ここではチェックを入れずに続行してみました。

vsdroid-visualstudio-2

最後にソリューションファイル(sln)の保存場所を聞かれるので、そもそも最初の段階で決めて vcxprojが保存される場所に一緒に保存されるようにしました。

てっきりコピーされるかと思ったのですが、Importではあくまでインポート位置のものが使用されるようです。とりあえずここでは気にしないことにして各ファイルを開いてみたのが以下の図になります。

vsdroid-visualstudio-3

まずはVSDROIDの設定をするために、メニューからVSDROID/Preferences を開きます。
すると下記のような画面が出てきます。

vsdroid-preferences

CygwinのパスやJDKのパス、Android SDK,NDKのパス, Antのパスを入力していきます。
このことからわかるように現在の状態では Cygwin,Ant が必要ということですね。

これらの設定が終わったらプロジェクトをビルドしてみます。

error: Target id 'android-3' is not valid. Use 'android.bat list targets' to get the target ids.
Error: could not prepare project for build.TestVSDroid-1 - 3 error(s), 0 warning(s)

このようなエラーが発生してしまいました.

TestVSDroid-1のプロジェクトのプロパティを開いて、Common/Target platform で示される項目を編集します。
下記に示すように手元では android-10 と入力して、再度ビルドを実行したところうまくいったようです。

vsdroid-visualstudio-4

実行&デバッグ

ビルドができたところで実行をテストしてみます。
端末を接続して、プロジェクトの設定から Configuration内の Debug を開き、Debug target device で目的のデバイスを選択しておきます。デバイスが1種しかない場合には device を選択しておけば良さそうです。
また、Target 内にある Optimization の項目を No にしておきます。

vsdroid-visualstudio-5

設定できたらそのまま F5(デバッグ開始) で実行してみます。
すると下記のような画面に遷移しました。また実機上ではプログラムが起動してHello from JNI の文字列が表示されていました。

vsdroid-visualstudio-6

今度はブレークポイントを仕掛けてみることにします。
Java側では、HelloJniクラスの onCreate に、ネイティブ側では、Java_com_example_hellojni_HelloJni_stringFromJNI 関数に仕掛けておきます。設定はいつものVisualStudioの使用時と変わらない設定で F9 にてブレークポイントを仕掛けました。

これで F5実行 で実行してみます。

vsdroid-visualstudio-7
上記の図を見てわかるとおり、ネイティブ側のブレークポイントで停止しました。
混在のケースではまだ開発途中ということもあり片方で(この場合ネイティブ側)で止まるようです。

ウォッチで変数の値を見ることはできますし、呼び出し履歴についてもそこそこ見られるようです。

vsdroid-visualstudio-8

ただ気になった点としては、デバッグの停止で Visual Studio が応答停止する状態になることです。自分の端末(GalaxyS2)の問題なのかもしれませんが・・・。


WinGDB MSE から VS-Droid へ


WinGDB for Mobile Systems はプロダクトが変わって、VS-Droid for Visual Studio というプロダクトになったようです。しかも色々とあってフリーのリリースとなっている模様です。その色々については本家ページの方を参照してください。

特徴・機能について

  • Visual Studioのプロジェクト統合.
  • AndroidManifest.xmlに記述されるプロジェクト構造だけでなく、ネイティブのサブプロジェクトの情報もまたソリューションエクスプローラーに表示可能. アクティビティは現在デバッグ可能
  • 標準のNDK-Buildのビルドシステムを使用します。WinGDBは *.mk や *.xml のファイルを参照して、他のツールとの連係動作が可能なようにしている。そのため変換は不要.
    ただ独自の設定を保存する wgaproj ファイルをプロジェクトに追加する。
  • エミュレーター上でアプリケーションのデバッグ.起動中のアクティビティへのアタッチや起動時からのデバッグができる。デバッグにはVisual Studioのものが使用できる
  • 物理デバイスで非root取得状態でのデバッグが可能。Nexus Oneをリファレンスとして使用している。全てのデバイスで動作を保証するものではないが、VS-Droidは標準のSDK,adbを用いているのでこれらがうまく動作するのであれば動く
  • 限定的ではあるが Java のサポート。現バージョンでは構文ハイライト機能と簡単な編集が利用可能で、ビルド&実行ができる。
  • まだ実験段階のJavaデバッガを持っており、Java,ネイティブどちらのデバッグセッション開始も可能である
  • ただし、混在するデバッグはできず現在作業中である
  • デバイスモニター機能。接続先デバイスの情報を取得&表示するための機能

ざっくりですが本家ページの内容を意訳してみるとこのような感じかと思います。
まだ開発途中とのことではありますが、これらの機能をフリーで提供する方針に変わってくれたことは開発者としてとても嬉しく思います。

次回以降インストールしてみて使用してみた感じをお知らせできればと思います。


DirectX11でMSAA


DirectX11でMSAA(Multi Sampling Antialias)を試してみました。
検索でよく見つかるのが、プライマリのバッファをMSAA使用する例はよくみかけるのですが、テクスチャレンダリングする場合においてMSAA有効でレンダリングするというサンプルを見つけることはできませんでした。
そんなに難しい話ではないのですが、サンプルプログラムが見つからなかったので今回作成してみました。

まずは結果です。テクスチャを描画先(レンダーターゲット)として三角形を描画しています。その結果をテクスチャとして取得して、四角形のポリゴンに貼り付けて表示しています。
result-msaa

結果を見てもよくわからないので、MSAA OFFの場合の結果を以下に表示します。

msaa-off

これでもよくわからないかもしれません。そこで両者を比較して拡大したものを示してみます。これならば違いがわかるでしょうか?MSAAが有効なものについては、ポリゴン境界がなめらかに見えるように色が補間された結果が見えています。

msaa-comp

手順について

レンダーターゲットとしてテクスチャを使う方法についてはここでは説明しません。
ここではMSAAテクスチャを作成する方法と、それをテクスチャとして使う方法の2つを説明したいと思います。

MSAAテクスチャの生成

描画先となるテクスチャを作成する際に、MSAA用のパラメーターを設定します。
D3D11_TEXTURE2D_DESC 構造体の SampleDesc内のパラメータが該当するのですが、ここにパラメータを指定します。

これらのパラメータの設定がよくわかりませんでしたが、下記に示すように CheckMultisampleQualityLevels から取得できる Quality値を指定しておけばよいようです。

この例だとおそらく 4x の MSAA が有効となるようです。

MSAAテクスチャとして使う

上記の pRenderTargetにたいして描画行われた後でテクスチャとして使用するためにはResolve処理を行わなくてはなりません。またこのときに、Resolve結果格納先として別のテクスチャが必要になります。
普通はこのResolveされたのテクスチャを他の描画で使用します(正確にはこのテクスチャのShaderResourceViewを、ですが)。

まずはそのResolveテクスチャの作成についてはこんな感じになります。

Resolve処理

簡単ですが、D3DDeviceContextについて以下のAPIを呼ぶだけです。

レンダーテクスチャを使う際の注意点といいますかお作法として、
レンダーテクスチャ(RenderTargetViewとして)セットする前に、そのテクスチャがShaderResourceViewとしてセットされていないか確認し、すでにセットされているならば解除しておくことが望ましいようです。
D3Dのデバッグレイヤー有効にするとわかるのですが、シェーダーリソースとして設定されているものをレンダーターゲットとして設定した際に、警告メッセージが表示されます。これはそのシェーダーリソースがシェーダーで使用されていなくても警告がでますので要注意です。

サンプルプログラム

今回のサンプルプログラム全体です。VisualStudio2012で作成しています。
SampleMSAA11サンプルプログラム(Zip)

まとめ

意外と使われないのか、テクスチャに対するMSAAをやってみました。


XPERIA Z1 Compact (4.3)で GL Extension


XPERIA Z1 Compact (Android 4.3) にて GL Extension のリストを取得してみました。

OpenGL ES 3.0 V@53.0 AU@04.03.00.146.083 (CL@)
Qualcomm Adreno (TM) 330

GL_AMD_compressed_ATC_texture
GL_AMD_performance_monitor
GL_AMD_program_binary_Z400
GL_EXT_debug_label
GL_EXT_debug_marker
GL_EXT_discard_framebuffer
GL_EXT_robustness
GL_EXT_texture_format_BGRA8888
GL_EXT_texture_type_2_10_10_10_REV
GL_NV_fence
GL_OES_compressed_ETC1_RGB8_texture
GL_OES_depth_texture
GL_OES_depth24
GL_OES_EGL_image
GL_OES_EGL_image_external
GL_OES_element_index_uint
GL_OES_fbo_render_mipmap
GL_OES_fragment_precision_high
GL_OES_get_program_binary
GL_OES_packed_depth_stencil
GL_OES_depth_texture_cube_map
GL_OES_rgb8_rgba8
GL_OES_standard_derivatives
GL_OES_texture_3D
GL_OES_texture_float
GL_OES_texture_half_float
GL_OES_texture_half_float_linear
GL_OES_texture_npot
GL_OES_vertex_half_float
GL_OES_vertex_type_10_10_10_2
GL_OES_vertex_array_object
GL_QCOM_alpha_test
GL_QCOM_binning_control
GL_QCOM_driver_control
GL_QCOM_perfmon_global_mode
GL_QCOM_extended_get
GL_QCOM_extended_get2
GL_QCOM_tiled_rendering
GL_QCOM_writeonly_rendering
GL_EXT_sRGB
GL_EXT_texture_filter_anisotropic
GL_EXT_color_buffer_float
GL_EXT_color_buffer_half_float
GL_EXT_disjoint_timer_query

微妙にですが S4 のものと比べて extension の個数が減っています・・・。


GalaxyS4 Kitkat (4.4) で GL extension


GalaxyS4 について kitkatに更新してからGL Extensionのリストを取得してみました。

OpenGL ES 3.0 V@45.0 AU@  (CL@3869936)
Qualcomm  Adreno (TM) 320

GL_AMD_compressed_ATC_texture
GL_AMD_performance_monitor
GL_AMD_program_binary_Z400
GL_EXT_debug_label
GL_EXT_debug_marker
GL_EXT_discard_framebuffer
GL_EXT_robustness
GL_EXT_texture_format_BGRA8888
GL_EXT_texture_type_2_10_10_10_REV
GL_NV_fence
GL_OES_compressed_ETC1_RGB8_texture
GL_OES_depth_texture
GL_OES_depth24
GL_OES_EGL_image
GL_OES_EGL_image_external
GL_OES_element_index_uint
GL_OES_fbo_render_mipmap
GL_OES_fragment_precision_high
GL_OES_get_program_binary
GL_OES_packed_depth_stencil
GL_OES_depth_texture_cube_map
GL_OES_rgb8_rgba8
GL_OES_standard_derivatives
GL_OES_texture_3D
GL_OES_texture_float
GL_OES_texture_half_float
GL_OES_texture_half_float_linear
GL_OES_texture_npot
GL_OES_vertex_half_float
GL_OES_vertex_type_10_10_10_2
GL_OES_vertex_array_object
GL_QCOM_alpha_test
GL_QCOM_binning_control
GL_QCOM_driver_control
GL_QCOM_perfmon_global_mode
GL_QCOM_extended_get
GL_QCOM_extended_get2
GL_QCOM_tiled_rendering
GL_QCOM_writeonly_rendering
GL_EXT_sRGB
GL_EXT_sRGB_write_control
GL_EXT_texture_sRGB_decode
GL_EXT_texture_filter_anisotropic
GL_EXT_multisampled_render_to_texture
GL_EXT_color_buffer_float
GL_EXT_color_buffer_half_float
GL_EXT_disjoint_timer_query