OMAP3530下bc-cat 编程
bc-cat 设计的主要目的是优化OPenGL ES(1.1 和2.0)纹理流的。目前版本0.2 , 不支持RGB8888的格式,有点杯具了。RGB只支持565,而且还没测试过, 有点小小的心痛。不过也有意外收获,支持NV12,YUV422的格式。很显然,这玩意是专门为视频准备的。。。
Bc-cat基本思路是这样的:将纹理缓冲直接映射到进程空间中,程序直接写缓冲以更新纹理,然后正常调用OpenGL ES 的绘图和Shader完成渲染。
看了一下Demo,基本编程过程小结如下:
- 首先打开 /dev/bccatX 设备。
- ioctl BCIOREQ_BUFFERS 申请内存。 申请信息主要是 宽、高、格式、缓冲数量。
- 使用 BCIOGET_BUFFERCOUNT 返回实际可用的缓冲数量。
- 初始化EGL,调用EGL扩展函数 ,传入/dev/bccatX设备序号X,获取缓冲数量,宽高,格式等。 这里主要用于确认。
- 根据缓冲数目创建对应的数目的纹理句柄。
- 激活纹理 glActiveTexture(GL_TEXTURE0); 然后对每个纹理ptex_objs调用glBindTexture (GL_TEXTURE_STREAM_IMG, ptex_objs[idx]); 绑定到GL_TEXTURE0。
- 缓冲绑定 glTexBindStreamIMG(bcdev_id, idx); 将/dev/bccatX的缓冲序号idx绑定纹理ptex_objs[idx] , 其中bcdev_id就是/dev/bccatX中的X序号,0~9。
OK,剩下的工作就比较简单了。
- 使用BCIOGET_BUFFERPHYADDR 获取一个idx序号对应的缓冲物理地址。
- 对物理地址调用 mmap 映射到进程中的虚拟地址空间。也就是得到一个缓冲区了。
到此, GLES中的纹理与进程中的一个缓冲区通过序号idx一一对应了。
OK,当需要更新显示纹理的时候,直接对缓冲区写就行了。
写完了然后去调用OPenGL ES 2.0 的绘图。 在调用glDrawArrays这类接口之前,必须绑定当前缓冲idx对应的纹理句柄:
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_STREAM_IMG, ptex_objs[idx]);//如果更新了第idx对应的缓冲,
使用bc-cat 的主要目的就是不必再使用glTexSubImage2D 或者 glTexImage2D 这种低效率的接口去更新纹理内容。避免了内存的二次拷贝,其性能提高相当显著了。
对于OpenGL ES2.0 ,必须使用Shader控制绘制管线。在Fragment Shader中,使用texture stream 扩展的纹理与使用标准纹理不一样。 首先是定义类型不同: "uniform samplerStreamIMG streamtexture;/n" ,标准纹理定义是"uniform sampler2D s_texture; /n" ; 其次是纹理引用不同:gl_FragColor = textureStreamIMG(streamtexture, texcoord); 标准纹理引用是gl_FragColor= texture2D( s_texture, v_texCoord );
最后就是在Fragment shader 一开始要声明使用texturestream2扩展:
"#ifdef GL_IMG_texture_stream2/n"
"#extension GL_IMG_texture_stream2 : enable/n"
"#endif/n"
对于OpenGL ES1.1 ,要调用 glEnable(GL_TEXTURE_STREAM_IMG);来使能GL_TEXTURE_STREAM_IMG扩展。