Happy My Life

日常とか技術とか

RenderScriptまわりを調べてみたメモ

以前から興味があったHoneyCombから含まれたRenderScriptについて調べてみた。ここでは、RenderScriptのドキュメントを読んで、ソースコード(サンプルのBalls)を見てみて動かしてみてのメモ(Android 3.2にて)。事実誤認も含まれている可能性があるのでその点は指摘していただけるとありがたい。

RenderScriptとは

簡単にいうと、GPU依存しないレンダリングエンジン。OpenGL|ESを利用するとGPU依存したコードになりがちだが、RenderScriptではそのようなGPUに依存せずにコードを書ける、ということらしい。

ただしOpenGL|ESよりは機能は少ない。RenderScriptの内部では、OpenGL|ES2.0が動作している。

RenderScript と OpenGL|ES

RenderScriptとOpenGL|ESは似たような利用目的となる。では、これらはどのように使い分けるべきか。それもマニュアルに書かれている。

かいつまんで言うと、アプリケーション内部でのUIで利用する程(多機能を要求しない、パフォーマンスを要求しない)であれば、機種依存しない分RenderScriptが有利。ただし、ゲームのような性能重視、パフォーマンス重視な場合は、OpenGL|ESとJavaやNDKを利用してね、とのこと。

プロジェクト構成

ちょっと意表をつかれるのが、このファイル構成。

基本的にJava、rsファイル(RenderScriptファイル)、rsh(RenderScript Headerファイル)から構成される。rsファイルの文法は基本的にC言語で書ける(厳密にはC99)

rsファイルには表示物の座標演算に必要なコード記述し、llvmコンパイラでビルドされ、/res/rawフォルダ以下にbcファイルとして配置される(rsファイルのビルドはEclipseがしてくれる)。ファイル実行に利用されるのは、このbcファイルの方。

あと、/genフォルダ以下にrsファイルと同名のjavaファイルが自動生成される。これは、タッチ操作の位置情報など、JavaのコードからRenderScript側にデータを渡すときに、このjavaファイルで定義されたメソッドを利用して渡す。このあたりのノリは、サービスを作成するときのaidlファイルに近いものがある。

ソースコード

実際にソースコードを読んでみの感想。RenderScriptのリファレンスマニュアルはちゃんと読んでないのでコードの雰囲気だけで。

RenderScriptの内部ではOpenGL|ES2.0をつかって動作しているとドキュメントに書いてあったが、RenderScriptのコードを初期化や呼出しているJavaコードを見てみるとOpenGL|ES2.0でよく見かけるのパラメータ設定などが見て取れる。

たとえばサンプルにあるBalls/BallsRS.javaを見てみると

        ProgramVertex.Builder sb = new ProgramVertex.Builder(mRS);
        String t =  "varying vec4 varColor;n" +
                    "void main() {n" +
                    "  vec4 pos = vec4(0.0, 0.0, 0.0, 1.0);n" +
                    "  pos.xy = ATTRIB_position;n" +
                    "  gl_Position = UNI_MVP * pos;n" +
                    "  varColor = vec4(1.0, 1.0, 1.0, 1.0);n" +
                    "  gl_PointSize = ATTRIB_size;n" +
                    "}n";
        sb.setShader(t);

これは、OpenGL|ES 2.0によく出てくるコード。

あとは

        ProgramStore.Builder builder = new ProgramStore.Builder(rs);
        builder.setDepthFunc(ProgramStore.DepthFunc.ALWAYS);
        builder.setBlendFunc(ProgramStore.BlendSrcFunc.ONE, ProgramStore.BlendDstFunc.ONE);
        builder.setDitherEnabled(false);
        builder.setDepthMaskEnabled(false);
        return builder.create();

も記述方法は違えど設定内容はOpenGL|ES2.0によく登場する内容。

そういう意味ではRenderScriptはOpenGL|ES2.0の機能の一部を取り出してラッピングしたライブラリという印象が。なので、RenderScriptを使いこなしたい時はRenderScriptのみならずOpenGL|ES2.0も理解した上で作成する必要があるんでないかなーと思う。OpenGL|ES2.0自体解説している書籍やサイトって少ないけど…。

私は、この本を参考にしている。