Вопрос

I am getting confused with EGL.

My GLSurfaceView creates an EGLContext. Now I create a shared context. Now I need to use a EGLExtension.

The Method I have to use is called (>=API18):

EGLExt.eglPresentationTimeANDROID(android.opengl.EGLDisplay display, android.opengl.EGLSurface surface, long time);

The Problem is, that the GLSurfaceView does only creates javax.microedition.khronos.egl.EGLContext s.

Which tells me, NOT to use GLSurfaceView. So I tried TextureView, which is slightly similar, with the difference that you have to handle your own EGL stuff. Which is good for that purpose.

But: The TextureView is slower, at least it looked like that, so I recorded some diagrams with the Method Profiler:

Here the TextureView with own EGL Handling: enter image description here The Thread on the top is a clock that wakes the Thread in the middle, which renders onto the TextureView. The main Thread will be called after that, for redrawing the TextureView.

... and here the GLSurfaceView with their own EGL Handling The clock is in the middle this time, it calls the Thread on the top to render my image into a framebuffer, which I give directly into the SurfaceView (RENDERMODE_WHEN_DIRTY) and call requestRender to request the view to render. enter image description here

As you can see with a short look already that with the GLSurfaceView it looks way cleaner that with the TextureView.

On both Examples I havn't had anything else on the screen and they rendered exactly the same Meshes with the same shader.

To my question: Is there a way to use GLSurfaceView with EGL14 Contexts?

Did I do something wrong?

Это было полезно?

Решение

What you probably want to do is use a plain SurfaceView.

Here's the short version:

  • SurfaceView has two parts, the Surface and a bit of fake stuff in the View. The Surface gets passed directly to the surface compositor (SurfaceFlinger), so when you draw on it with OpenGL there's relatively little overhead. This makes it fast, but it also makes it not play quite right with the View hierarchy, because the Surface is on one layer and the View-based UI is on a different layer.
  • TextureView also has two parts, but the part you draw on lives behind the scenes (that's where the SurfaceTexture comes in). When the frame is complete, the stuff you drew is blitted onto the View layer. The GPU can do this quickly, but "some work" is always slower than "no work".
  • GLSurfaceView is a SurfaceView with a wrapper class that does all the EGL setup and inter-thread messaging for you.

Edit: the long version is available here.

If you can do the GL/EGL setup and thread management yourself -- which, if you're now running on a TextureView, you clearly can -- then you should probably use a plain SurfaceView.

Having said all that, it should be possible to make your original code work with GLSurfaceView. I expect you want to call eglPresentationTimeANDROID() on the EGL context that's shared with the GLSurfaceView, not from within GLSurfaceView itself, so it doesn't matter that GLSurfaceView is using EGL10 internally. What matters for sharing the context is the context client version (e.g. GLES2 vs. GLES3), not the EGL interface version used to configure the context.

You can see examples of all of this working in Grafika. In particular:

  • "Show + capture camera" uses a GLSurfaceView, the camera, and the video encoder. Note the EGL context is shared. The example is convoluted and somewhat painful, mostly because it's deliberately trying to use GLSurfaceView and a shared EGL context. (Update: note this issue about race conditions with shared contexts.)
  • "Play video (TextureView)" and "Basic GL in TextureView" show TextureView in action.
  • "Record GL app with FBO" uses a plain SurfaceView.

Другие советы

Thanks to fadden! It worked as expected.

To everyone who thinks about doing something similar:

It has advantages AND disadvantages using the (GL)SurfaceView to render images on it.

My testresults in the post above do not have anything else on the screen than the rendered image itself. If you have other UI elements on the screen, especially if they get updated frequently, you should reconsider my choice of prefering the (GL)SurfaceView.

The SurfaceView creates a new window in the Android Windowsystem. Its advantage is, that if the SurfaceView gets refreshed, only this window will be refreshed. If you additionally update UI Elements (which are in another window of the windowsystem), then both refresh operations block themselfes (especially when ui drawing is hardwaresupported) because opengl cannot handle multi thread drawing properly.

For such a case it could be better using the TextureView, cause it's not another window of the Android Windowsystem. so if you refresh your View, all UI elements get refreshed as well. (Probably) everything in one Thread.

Hope I could help some of you!

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top