我在未压缩的RGBA 8888格式中有大约2 GiB的纹理(都是256x256图块)(RGB 565纹理格式不是一个选项,因为有很多平滑的渐变和灰色阴影,它们具有565格式的绿色色调)。所以我按需加载它们,当它们变得可见并删除旧的时。问题是,当我上传OpenGL时,会出现恼人的FPS下降。目前正在使用OpenGL ES 1.1。
我在一个单独的线程(即BitmapFactory.decodeStream(...))中解码纹理,然后将Bitmap发送到GL线程并将其作为纹理上传。当发生这种情况时,GL线程有时为此上传减慢了一点。我测量了纹理上传时间,主要是从1-8ms变化,平均为~2ms。但有时它是40-70毫秒。什么会导致这种下降?
我还在GPU上生成mipmap(禁用mipmap不会影响此行为),这里是所有纹理参数:
GLES11.glTexParameterf(GLES11.GL_TEXTURE_2D, GLES11.GL_TEXTURE_MIN_FILTER, GLES11.GL_LINEAR_MIPMAP_NEAREST);
GLES11.glTexParameterf(GLES11.GL_TEXTURE_2D, GLES11.GL_TEXTURE_MAG_FILTER, GLES11.GL_LINEAR);
GLES11.glTexParameterf(GLES11.GL_TEXTURE_2D, GLES11.GL_TEXTURE_WRAP_S, GLES11.GL_CLAMP_TO_EDGE);
GLES11.glTexParameterf(GLES11.GL_TEXTURE_2D, GLES11.GL_TEXTURE_WRAP_T, GLES11.GL_CLAMP_TO_EDGE);
GLES11.glTexParameterf(GLES11.GL_TEXTURE_2D, GLES11.GL_GENERATE_MIPMAP, GLES11.GL_TRUE);
GLES11.glTexEnvx(GLES11.GL_TEXTURE_ENV, GLES11.GL_TEXTURE_ENV_MODE, GLES11.GL_MODULATE);
GLUtils.texImage2D(GLES11.GL_TEXTURE_2D, 0, GLES11.GL_RGBA, bmp, 0);
我怎样才能更好地做到这一点?例如。当Open GL视频播放器需要加载并显示每秒多帧时,它们是如何完成的?或者当前的网页浏览器将网页呈现为瓷砖? EGL_image是值得关注的好选择吗?将OpenGL ES 2.0与众不同吗?
修改 加载速度减慢是因为GL线程上的GC-ing。
答案 0 :(得分:1)
除了确保GC没有启动之外,你可以在一个单独的线程上完成所有位图生成和纹理上传,如我对类似问题的回答中所述:Threading textures load process for android opengl game
当上传本身需要很长时间时,这会阻止您丢失小帧。
答案 1 :(得分:0)
最后我解决了它,但不是使用本机代码,也不使用EGL_image,但感谢video。幸运的是,我有256x256的几乎所有纹理,我的目标是Android 3.2及更新,所以对于这种情况,有一个简单的解决方案:
BitmapOptions.inBitmap,它会为每个新磁贴重复使用一个Bitmap
,因此不再需要使用真实的GC-ing。我不得不放大小于256x256的几个位图。