Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it possible to use pixmaps on Android via Java API for GLES?

I'm trying to implement off-screen rendering with OpenGL ES on Android. My ultimate goal is to improve performance of texture mapping which I do in plain java and Bitmap/int[] APIs. I tried pbuffer approach, similar to the sample code from a relevant forum thread. It shows rather low performance, glReadPixels call takes up to 50 ms on one device and up to 15 ms on another.

There is more modern approach using Frame Buffers. The code samples are rather complicated and I don't expect much faster transfer from Frame Buffer to Android's Bitmaps than it was with pbuffers. Am I right with my estimation?

The third approach is using pixmaps. If I understood the docs right they should utilize more sophisticated memory sharing between OpenGL and Dalvik's memory than plain copy. The problem is that relevant APIs aren't present in the Android SDK.

There is no eglCreateImageKHR and EGLImageKHR structure exposed in Java. All C++ examples I could find rely on them.

There is eglCreatePixmapSurface but I can't figure out how to use it from the docs. Probably it receives some kind of bitmap handle in the native_pixmap parameter, but I can't find any way to create such a handle. Searching for "eglCreatePixmapSurface android" leads only to problem reports.

My main question is: can I use pixmaps on Android from Java without writing native code? If I need to go native is there working code I can use to evaluate performance before diving deep into OpenGL?

like image 332
CheatEx Avatar asked Aug 26 '14 11:08

CheatEx


People also ask

Does Android use OpenGL?

Android includes support for high performance 2D and 3D graphics with the Open Graphics Library (OpenGL®), specifically, the OpenGL ES API. OpenGL is a cross-platform graphics API that specifies a standard software interface for 3D graphics processing hardware.

What is EGL Android?

Android uses the OpenGL ES (GLES) API to render graphics. To create GLES contexts and provide a windowing system for GLES renderings, Android uses the EGL library. GLES calls render textured polygons, while EGL calls put renderings on screens.


1 Answers

The best way to improve texture loading performance on Android is to use the EGL image extensions you sited and EGL_NATIVE_BUFFER_ANDROID with native code. I have a code example of that in this article. I measured major performance improvements with this approach.

Android has no support for Pixmaps and pbuffers do not work on Nvidia Tegra devices. You should use FBO-attached textures instead. That is the way the Android SurfaceTexture class is implemented.

If you need alpha textures, that is another reason to use native code. There is a compatibility problem between Bitmap and OpenGL ES with alpha textures.

Using hardware texture compression formats (ETC/PVR instead of PNG) and mipmaps improves the loading performance and quality of texture rendering a lot too, as discussed in this article.

The big problem is glReadPixels(). EGL_NATIVE_BUFFER_ANDROID only works for writing textures, not for reading them back to a Bitmap. Android's platform code uses glReadPixels() to implement TextureView.getBitmap() and it is very slow. The best solution is to not copy the texture to a Bitmap, but to display the rendered TextureView directly which avoids glReadPixels().

I have been working with OpenGL ES 2.0 and the situation may have been improved with 3.0.

like image 160
ClayMontgomery Avatar answered Sep 28 '22 23:09

ClayMontgomery