当android:hardwareAccelerated设置为false进入清单文件时,我的问题只出现在最新的三星Galaxy系列中
据我所知(我自己试过),它发生在Galaxy S9,J6和Note 8上,但不是在Galaxy S8上。其他手机似乎根本没有受到影响。
问题是我得到了一个没有显示任何内容的GLSurfaceView(黑屏),但如果我在活动之间切换,它会再次开始工作,我猜是因为它更新了View而没有错误。
这是我发现的可疑对数线
01-13 14:39:47.813 25013 25080 E libEGL : eglCreateWindowSurface: native_window_api_connect (win=0xc166b808) failed (0xffffffed) (already connected to another API?)
01-13 14:39:47.813 25013 25080 E libEGL : eglCreateWindowSurface:679 error 3003 (EGL_BAD_ALLOC)
这些是我的代码的关键部分:
GLSurf glsurf;
public void onPause() {
super.onPause();
// stop
if (glsurf != null) {
glsurf.onPause();
}
}
@Override
public void onResume() {
super.onResume();
if (glsurf != null)
glsurf.onResume();
}
public class GLSurf extends GLSurfaceView {
public GLSurf(Context context) {
super(context);
/* Create an OpenGL ES 2.0 context. */
setEGLContextClientVersion(2);
setEGLConfigChooser(8, 8, 8, 8, 16, 0);
// Set the Renderer for drawing on the GLSurfaceView
mRenderer = new GLRenderer(context);
setRenderer(mRenderer);
setRenderMode(GLSurfaceView.RENDERMODE_CONTINUOUSLY);
}
}
public class GLRenderer implements Renderer {
GLRenderer(Context c){
// does nothing
}
@Override
public void onDrawFrame(GL10 unused) {
// i've copied it but it's not even reached
// call jni function updating the single texture filling the screen
nativeGLRender();
// Draw the triangles
GLES20.glDrawElements(GLES20.GL_TRIANGLES, indices.length,
GLES20.GL_UNSIGNED_SHORT, drawListBuffer);
}
@Override
public void onSurfaceChanged(GL10 gl, int width, int height) {
// We need to know the current width and height.
mScreenWidth = width;
mScreenHeight = height;
// Redo the Viewport.
GLES20.glViewport(0, 0, (int)mScreenWidth, (int)mScreenHeight);
}
@Override
public void onSurfaceCreated(GL10 gl, EGLConfig config) {
// Set the clear color to black
GLES20.glClearColor(0.0f, 0.0f, 0.0f, 1);
}
}
一些信息更多:
EGL_BAD_ALLOC始终在具有有意义(至少我认为)的日志的事件序列之后出现
onCreate
onResume
onPause
GLSurfaceView: Warning, !readyToDraw() but waiting for draw finished! Early reporting draw finished.
onResume
libEGL : eglCreateWindowSurface: native_window_api_connect (win=0xc166b808) failed (0xffffffed) (already connected to another API?)
libEGL : eglCreateWindowSurface:679 error 3003 (EGL_BAD_ALLOC)
onPause
onStop
onDestroy
onCreate
onResume
onSurfaceCreated
: NULL == surf->write_back_color_buffer
: NULL == surf->write_back_color_buffer
GLThread: eglSwapBuffers failed: EGL_BAD_SURFACE
... black screen ...
请注意,上述事件在没有用户交互的情况下发生,并且持续1-2秒。关于发生了什么的任何想法?
为了完成信息,以下是工作电话的顺序(例如我的nexus 6)
onCreate
onResume
onSurfaceCreated
... working screen
编辑1月16日:
关于这个问题的新信息:
编辑1月18日
我也发现了BUG的原因
不知道为什么,但我只是改变了这部分代码
@Override
public void onAttachedToWindow() {
super.onAttachedToWindow();
getWindow().setFormat(PixelFormat.RGB_565);
}
有了这个
@Override
public void onAttachedToWindow() {
super.onAttachedToWindow();
}
一切都很好。三星驱动程序中的错误?也许...
我希望这对某些人有用
eglCreateWindowSurface:native_window_api_connect失败任何关于发生了什么的想法?
来自eglApi.cpp的被调用函数是:
/*
* native_window_api_connect(..., int api)
* connects an API to this window. only one API can be connected at a time.
* Returns -EINVAL if for some reason the window cannot be connected, which
* can happen if it's connected to some other API.
*/
static inline int native_window_api_connect(
struct ANativeWindow* window, int api)
{
return window->perform(window, NATIVE_WINDOW_API_CONNECT, api);
}
以下是来自WindowSurface.recreate()
方法的WindowSurface.java的注释块,其中说:
/*
* If the previous EGLSurface isn't fully destroyed, e.g. it's still current on a
* context somewhere, the create call will fail with complaints from the Surface
* about already being connected.
*/
来自Opengls eglCreateWindowSurface GL Error EGL_BAD_ALLOC 的Jitesh Dalsaniya:
我解决了错误GL错误EGL_BAD_ALLOC。由于我没有正确处理活动生命周期的渲染器,因此发生此错误。
活动生命周期
必须通知
GLSurfaceView
何时暂停和恢复渲染。GLSurfaceView
客户必须在活动停止时调用onPause()
,并在活动开始时调用onResume()
。这些调用允许GLSurfaceView
暂停和恢复渲染线程,并允许GLSurfaceView
释放并重新创建OpenGL
显示。
EGL背景丢失
在某些情况下,
EGL
渲染上下文将丢失。这通常发生在设备进入睡眠状态后唤醒时。当EGL
上下文丢失时,将自动删除与该OpenGL
相关联的所有context
资源(例如纹理)。为了保持正确渲染,渲染器必须重新创建它仍然需要的任何丢失的资源。onSurfaceCreated
(GL10,EGLConfig)方法是一个方便的地方。
所以你的Activity's
onPause()
应该是这样的:
@Override
public void onPause() {
glsurf.setVisibility(View.GONE);
super.onPause();
...
}
并且你将GLSurfaceView
恢复到层次结构而不是来自onResume()
但是来自onWindowFocusChanged()
:
@Override
public void onWindowFocusChanged(boolean hasFocus) {
super.onWindowFocusChanged(hasFocus);
if (hasFocus && glsurf.getVisibility() == View.GONE) {
glsurf.setVisibility(View.VISIBLE);
}
...
}
OpenglView
可见总是和startPreview
获得权限。一个看不见的持有者对opengl无效,这可能会导致你的崩溃。onSurfaceTextureSizeChanged
处理TextureViewGLActivity
?EGL_BAD_ALLOC
和eglSwapBuffers failed:
EGL_BAD_SURFACE
是一个很大的线索......!readyToDraw()
删除并重新创建Surface?观察:
如果我把
android:hardwareAccelerated
设置为true,那么错误永远不会发生如果您的
Target API
级别为is >=14
,则默认启用硬件加速,但也可以显式启用(在应用程序或活动级别)。
在glsurf.setVisibility(View.GONE)
中调用onPause()
可以为我的应用程序工作,但是当我在glsurf.setVisibility(View.VISIBLE)
中调用onWindowFocusChanged()
时它将无效。
当我在glsurf.setVisibility(View.VISIBLE)
打电话给onResume()
时,它对我有用。