0

I'm trying to find out whether I need to remake a Surface if I want to call the attachToGLContext method from a SurfaceTexture. I tried to look in the android documentation, but there is no mention.

I'm guessing not because as far as I'm aware, Surface is a buffer for a SurfaceTexture which can act as an external texture for an OpenGL context. So attaching the SurfaceTexture to a different context should not affect this.

Does anybody know for sure?

JasonMArcher
  • 14,195
  • 22
  • 56
  • 52
Kongo
  • 71
  • 1
  • 2
  • 12

1 Answers1

4

The internal name for SurfaceTexture is "GLConsumer". Surfaces have a producer-consumer relationship, and SurfaceTexture is a consumer that takes whatever it gets and makes it available as a GLES texture.

The Surface attached to it (usually by using the Surface constructor that takes a SurfaceTexture as an argument) is the producer side. While there is a queue of buffers involved in the communication between the producer and the consumer, it's not really accurate to describe the Surface as "a buffer". It's more like a communication endpoint that sends graphics data to the consumer.

Changing the EGL context associated with the consumer side will have no effect on the producer side. The attach / detach calls do not disconnect the producer. They only affect what the SurfaceTexture does with the buffers of data it receives.

It's fairly unusual to need to use these calls though, and there may be some overhead associated with manipulating EGL contexts, so make sure it's what you need.

fadden
  • 51,356
  • 5
  • 116
  • 166
  • Yep, I have a service that decodes mediacodec frames into a surfacetexture. I have an application with multiple activities, each with a different number of EGL surfaces. This way I can attach the surfacetexture to different EGLcontexts from different activities. Is there a way to keep the same EGL context and pass it from activity to activity with an intent? I don't know all the threading implications if I try to do this. – Kongo Aug 23 '15 at 10:22
  • An EGL context can only be current in one thread at a time. If you keep a reference to it in a static variable, you can make it un-current in the current thread, and send an intent that tells the next Activity "it's yours now". Alternatively, associate the EGL context with a thread that doesn't die, and just have every Activity interact with that (through Looper/Handler). Sharing the context with others is usually a good idea -- then you can reference the external texture directly in the other contexts. – fadden Aug 23 '15 at 15:37
  • I'm still a bit fuzzy on the nomencature. The EGL context is the EGLcore yes? And your second suggestion about a thread that doesn't die...I have to make sure that that thread does all the drawing work and setting up yes? So I need to have the handler get references to surfaceTextures from the activities, pass it to the thread, set up WindowSurfaces, call makeCurrent(), then draw all on the thread. – Kongo Aug 23 '15 at 23:32
  • I was picturing a dedicated thread that receives the MediaCodec frames with a SurfaceTexture. The associated EGL context is created first. Various other threads that need to do rendering have EGL contexts that share state with the first context, so that they can access the texture from the SurfaceTexture. See Grafika's "show + capture camera" activity, which draws to the GLSurfaceView from one thread, and to the MediaCodec encoder on another, using a texture in a shared context. – fadden Aug 24 '15 at 04:50
  • The EglCore class in Grafika has an EGLContext, and there's a 1:1 relationship, but EglCore is not EGLContext. The EGLContext is a thin wrapper around the native EGL context object, which is defined by OpenGL ES. – fadden Aug 24 '15 at 04:52
  • Thanks. I'll have a look at that. – Kongo Aug 24 '15 at 05:43
  • @fadden In "show + capture camera" , you draw to screen on one thread and draw to encoder on another. And the 2 threads share one opengl context. I am concerned about that the 2 drawing actions will conflict with eath other becasue of a shared context. What's your opinion? – dragonfly Mar 07 '17 at 02:05
  • @dragonfly: you're correct to be concerned; see https://github.com/google/grafika/issues/36 – fadden Mar 07 '17 at 03:23
  • @fadden Right now. I have a work just like this, two external surfacetextures in 2 threads. I want to draw the 2 textures to one FBO for image merge. I have finished the code with shared gl context. But the demo will stuck after several seconds(sometimes more than 10 seconds). What should I do for such multi-thread work? Will API attachToGLContext/detach help me? – dragonfly Mar 07 '17 at 03:44
  • Correct multi-thread shared-context texture handling requires specific behavior on the producer and consumer, noted in the github issue linked earlier. You could check AOSP to see if the texture writer does what you need (i.e. `glFinish()` after `updateTexImage()`). There's no guarantee that the implementation won't change in the future, though I'd say it's unlikely to change in a significant way. You then need to re-bind the texture, which attach/detach should do. (FWIW, I'd be looking for a simpler overall approach.) – fadden Mar 07 '17 at 15:18