问题
I am porting my game to android and decided to go with NativeActivity instead of Java activity and JNI calls (I am not avoiding JNI, just though it would be more convenient to set up callbacks and opengl context creation/destruction purely in c/c++).
I know that GLSurfaceView has a setPreserveEGLContextOnPause function, but that is in Java, not in native app. I create my context with the following code:
EGLConfig config;
EGLSurface surface;
EGLContext context;
EGLDisplay display = eglGetDisplay(EGL_DEFAULT_DISPLAY);
eglInitialize(display, 0, 0);
eglChooseConfig(display, attribs, &config, 1, &numConfigs);
eglGetConfigAttrib(display, config, EGL_NATIVE_VISUAL_ID, &format);
ANativeWindow_setBuffersGeometry(engine->app->window, 0, 0, format);
surface = eglCreateWindowSurface(display, config, engine->app->window, NULL);
const EGLint contextAttribs[] = {
EGL_CONTEXT_CLIENT_VERSION, 2,
EGL_NONE
};
context = eglCreateContext(display, config, NULL, contextAttribs);
if (eglMakeCurrent(display, surface, surface, context) == EGL_FALSE) {
ERR("Unable to eglMakeCurrent");
return -1;
}
I also know that setPreserveEGLContextOnPause is not 100% reliable and I should check if stuff is destroyed manually, but if it's not - I'd like to skip the asset reloading part for the sake of faster loading.
Basically what I want to do is to use setPreserveEGLContextOnPause (or it's equivalent for ndk world). Is it possible? Is GLSurfaceView being instantiated behind the curtains of android's egl calls?
回答1:
GLSurfaceView
is a Java-language utility class that sits on top of SurfaceView
and GLES. Nothing is creating or calling into GLSurfaceView
from EGL.
The "preserve EGL context" code in GLSurfaceView
exists because GLSurfaceView
does its own management of the EGL context on the render thread. The idea was to set things up so the app doesn't have to deal with it if it wants to use GLSurfaceView
. If you want to do your own EGL management, don't use GLSurfaceView
; when writing code in Java you'd use SurfaceView
or TextureView
instead.
You can see multiple examples in Grafika. The Java-language GLES implementation is a thin wrapper around the native implementation, so the way EGL is used in Grafika closely mirrors how you would use it in native code.
If you manage the EGL context yourself, it will not go away when Activities are torn down and recreated, but it will go away if the process is killed, so it's best to create it on the activity onPause()
/ onResume()
. It's also bad form to continue holding contexts (and their associated textures and buffers) while the app is in the background. See this article on SurfaceView and Activity lifecycle interaction for some notes about working with surfaces. (And read the rest of the article if you'd like to understand how the Android graphics architecture works.)
来源:https://stackoverflow.com/questions/25935735/preserving-egl-context-created-via-native-code