如何在暂停Android NDK应用程序时保留EGL上下文

3
我正在改进openframeworks,使得当我暂停和恢复我的游戏时GL上下文得到保留,这样我就不必在每次暂停后重新加载所有纹理。以下是我的问题的独立描述,与openframeworks代码无关,希望您能够理解。
我有一个Java活动(activity),它加载一个main_layout.xml文件,其中包含一个内部RelativeLayout。然后我实例化一个GLSurfaceView,并使用“glContainer.addView(glView, new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));”方法将其添加到内部RelativeLayout中。在onPause函数中,我会在GLSurfaceView上调用“glView.onPause();”,而在onResume函数中,我会在GLSurfaceView上调用“glView.onResume();”。
该代码可以正常工作,但是它会在onPause中销毁GL surface(GLSurfaceView.surfaceDestroyed被调用)。为了解决这个问题,我在初始化GLSurfaceView时添加了调用GLSurfaceView.setPreserveEGLContextOnPause参数设置为'true'。现在,在暂停和恢复游戏后,我只能看到黑屏。我发现,我可以通过在onResume函数中将GLSurfaceView从父RelativeLayout中移除并立即添加回来来解决这个问题:“glContainer.removeView(glView); glContainer.addView(glView, new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));”。但是这样又会破坏GL surface,并迫使我重新加载纹理。
请注意,RelativeLayouts和GLSurfaceView都没有重新实例化(我通过查看代码和使用System.identityHashCode检查这些实例的标识来进行验证)。
main_layout.xml:
<?xml version="1.0" encoding="utf-8"?>
   <RelativeLayout android:id="@+id/relativeLayout1" android:layout_width="fill_parent" android:layout_height="fill_parent" xmlns:android="http://schemas.android.com/apk/res/android">
        <RelativeLayout android:id="@+id/of_gl_surface_container" android:layout_width="fill_parent" android:layout_height="fill_parent"/>
        <!-- add here other views' layouts -->
    </RelativeLayout>

OFAndroidLifeCycle.java中处理来自Activity的事件的代码:

public static void glCreateSurface()
{
    if(mGLView == null)
    {
        mGLView = new OFGLSurfaceView(m_activity);

        OFGLSurfaceView glView = getGLView();

        glView.setPreserveEGLContextOnPause( true );

        ViewGroup parent = (ViewGroup)glView.getParent();
        if( parent == null )
        {
            ViewGroup glContainer = getActivity().getSurfaceContainer();
            glContainer.addView(glView, new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));
        }
    }
}

public static void glPause()
{
    OFGLSurfaceView glView = getGLView();
    if( glView != null )
        glView.onPause();   
}

public static void glResume(ViewGroup glContainer)
{
    OFGLSurfaceView glView = getGLView();

    if( glView != null )
    {
        glView.onResume();

        glContainer.removeView( glView );
        glContainer.addView( glView, new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT) );
    }
}

嗯,我有些困惑。能否有人详细解释一下如何完成这个任务,注意事项或者应该尝试的方法?

谢谢。


一般来说,这是不好的做法。手机用户可能会打开很多挂起的应用程序,当它们实际上没有运行时,应用程序保留所有内存并不“好”。这种模型的整个原因是为了为前台进程释放内存。 - solidpixel
1
我并不强制手机将我的资源保留在内存中。一旦Android内存不足,它可以自由地杀死我的应用程序或者销毁EGL上下文。我认为每次用户暂停然后恢复游戏快速检查新邮件时,花费4秒重新加载所有纹理是更糟糕的做法。 - Ivorne
1个回答

2

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接