android graphic(17)—Using direct textures on Android
来源:互联网 发布:1024邀请码多少钱淘宝 编辑:程序博客网 时间:2024/05/22 17:35
参考文章需翻墙。
I’ve been working at Mozilla on Firefox Mobile for a few months now. One of the goals of the new native UI is to have liquid smooth scrolling and panning at all times. Unsurprisingly, we do this by drawing into an OpenGL texture and moving it around on the screen. This is pretty fast until you run out of content in the texture and need to update it. Gecko runs in a separate thread and can draw to a buffer there without blocking us, but uploading that data into the texture is where problems arise. Right now we use just one very large texture (usually 2048x2048), and glTexSubImage2D can take anywhere from 25ms to 60ms. Given that our target is 60fps, we have about 16ms to draw a frame. This means we’re guaranteed to miss at least one frame every time we upload, but likely more than that. What we need is a way of uploading texture data asynchronously (and preferably quicker). This is where direct textures can help.
If you haven’t read Dianne Hackborn’s recent posts on the Android graphics stack, you’re missing out (part 1, part 2). The window compositing system she describes (called SurfaceFlinger) is particularly interesting because it is close to the problem we have in Firefox. One of the pieces Android uses to to draw windows is the gralloc module. As you may have guessed, gralloc is short for ‘graphics alloc’. You can see the short and simple API for it here. Android has a wrapper class that encapsulates access to this called GraphicBuffer. It has an even nicer API, found here. Usage is very straightforward. Simply create the GraphicBuffer with whatever size and pixel format you need, lock it, write your bits, and unlock. One of the major wins here is that you can use the GraphicBuffer instance from any thread. So not only does this reduce a copy of your image, but it also means you can upload it without blocking the rendering loop!
To get it on the screen using OpenGL, you can create an EGLImageKHR from the GraphicBuffer and bind it to a texture:
#define EGL_NATIVE_BUFFER_ANDROID 0x3140#define EGL_IMAGE_PRESERVED_KHR 0x30D2GraphicBuffer* buffer = new GraphicBuffer(1024, 1024, PIXEL_FORMAT_RGB_565, GraphicBuffer::USAGE_SW_WRITE_OFTEN | GraphicBuffer::USAGE_HW_TEXTURE);unsigned char* bits = NULL;buffer->lock(GraphicBuffer::USAGE_SW_WRITE_OFTEN, (void**)&bits);// Write bitmap data into 'bits' herebuffer->unlock();// Create the EGLImageKHR from the native bufferEGLint eglImgAttrs[] = { EGL_IMAGE_PRESERVED_KHR, EGL_TRUE, EGL_NONE, EGL_NONE };EGLImageKHR img = eglCreateImageKHR(eglGetDisplay(EGL_DEFAULT_DISPLAY), EGL_NO_CONTEXT, EGL_NATIVE_BUFFER_ANDROID, (EGLClientBuffer)buffer->getNativeBuffer(), eglImgAttrs);// Create GL texture, bind to GL_TEXTURE_2D, etc.// Attach the EGLImage to whatever texture is bound to GL_TEXTURE_2DglEGLImageTargetTexture2DOES(GL_TEXTURE_2D, img);
The resulting texture can be used as a regular one, with one caveat. Whenever you manipulate pixel data, the changes will be reflected on the screen immediately after unlock. You probably want to double buffer in order to avoid problems here.
If you’ve ever used the Android NDK, it won’t be surprising that GraphicBuffer (or anything similar) doesn’t exist there. In order to use any of this in your app you’ll need to resort to dlopen hacks. It’s a pretty depressing situation. Google uses this all over the OS, but doesn’t seem to think that apps need a high performance API. But wait, it gets worse. Even after jumping through these hoops, some gralloc drivers don’t allow regular apps to play ball. So far, testing indicates that this is the case on Adreno and Mali GPUs. Thankfully, PowerVR and Tegra allow it, which covers a fair number of devices.
With any luck, I’ll land the patches that use this in Firefox Mobile today. The result should be a much smoother panning and zooming experience on devices where gralloc is allowed to work.
- android graphic(17)—Using direct textures on Android
- Graphic --- Android
- android graphic(1)—轮廓
- android graphic(15)—fence
- android graphic(1)—轮廓
- Using Bootchart on Android
- Using Bootchart on Android
- Using smem on Android
- Unity3D翻译——Using Depth Textures
- android graphic(4)—surfaceflinger和Vsync
- android graphic(6)—surfaceflinger和MessageQueue
- android graphic(11)—底层初始化displays
- android graphic(16)—fence(简化)
- android graphic(4)—surfaceflinger和Vsync
- android graphic(6)—surfaceflinger和MessageQueue
- android graphic(11)—底层初始化displays
- Graphic size in Android
- android.graphic.Path
- linux下查看uuid
- IT公司中最流行的10种编程语言
- MySql绿色版配置及使用详解
- C会否像汇编一样退居幕后?
- CCV库安装
- android graphic(17)—Using direct textures on Android
- 45 个非常有用的 Oracle 查询语句
- java项目debug 的时候总是跳转threadpoolexecutor
- FFmpeg 一些参数的解释
- 白宫决策捕杀拉登现场照片公布
- android中如何判断edittext中数据为空?
- linux kernel的中断子系统之(八):softirq
- 基于Erlang实现的一个简单的并发控制程序
- 安卓触屏进行的图形变换--平移,缩放核心代码