GalaxyS2のVDPにはARM社のMali-400が使われています。メトセライズデストラクタのユーザから、GalaxyS2で動かないという報告を受けていたので、さっそく、秋葉原のイオシスでGalaxyS2を買ってきました。現金特価49500円、未使用品です。

Mali-400はETC1しかテクスチャ圧縮が使えないというのが有名ですが、メトセラはテクスチャ圧縮を使っていないのに何で動かないのかなと4時間ぐらい戦ってみましたが、原因はDrawTextureExtensionでした。

OpenGL extensions available on different Android devicesでもまとめられているように、Mali-400ではDrawTextureExtensionが使えるというフラグを返します。しかし、実際に使ってみると、他のVDPと違って、例外処理をしないといけないようです。

(1)GL_COLOR_ARRAYの値を参照してしまうので無効化する必要がある
(2)glDrawTexiOESの直後にglTexCoordPointerを再設定する必要がある

具体的に、次のようなコードにする必要があります。

if(m_isMaliVdp){
 gl.glDisableClientState(GL10.GL_COLOR_ARRAY);
}

gl.glColor4f(r,g,b,a);
((GL11)gl).glTexParameteriv(GL10.GL_TEXTURE_2D,GL11Ext.GL_TEXTURE_CROP_RECT_OES,draw_texture_extension_rect,0);
((GL11Ext)gl).glDrawTexiOES((int)(x*m_view_scale_x),(int)(y*m_view_scale_y),0,(int)(width*m_view_scale_x),(int)(height*m_view_scale_y));

if(m_isMaliVdp){
 gl.glTexCoordPointer(2, GL10.GL_FLOAT, 0, texCoords);
 gl.glEnableClientState(GL10.GL_COLOR_ARRAY);
}

Maliかどうかは、次のようなコードで判別できます。

String extensions = gl.glGetString(GL10.GL_EXTENSIONS);
String renderer = gl.glGetString(GL10.GL_RENDERER);
m_supportsDrawTextureExtension = extensions.contains("draw_texture");
m_isMaliVdp=renderer.contains("Mali");

こうすると、メトセラも問題無く動くようになりました。

IMG_0451


Tegra2、Adreno200、Adreno205、PowerVRの四つで動いたのでさすがに大丈夫だろうと思っていたら意外な伏兵でした。DrawTextureExtensionはAndroid1.6の頃からの高速化の定石なので、修正しなければならないコードは多そうですね。

Mali-T604なんてのも開発されているんですね。また端末が増えそうです。