我有一个问题,当android:hardwareAccelerated设置为false到清单文件中时,最新的Samsung Galaxy系列会出现
据我所知(我自己尝试过),它发生在Galaxy S9,J6和Note 8上,例如发生在Galaxy S8上。其他电话似乎根本不受影响。
问题是我得到了一个GLSurfaceView,它什么也不显示(黑屏),但是如果我在活动之间进行切换,它将重新开始工作,我想是因为它可以无错误地更新视图。
这是我发现的可疑日志行
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日
我也发现了错误的原因
不知道为什么,但是我只是更改了这部分代码
@Override
public void onAttachedToWindow() {
super.onAttachedToWindow();
getWindow().setFormat(PixelFormat.RGB_565);
}
与此
@Override
public void onAttachedToWindow() {
super.onAttachedToWindow();
}
,一切顺利。三星驱动程序中的错误?也许...
我希望这对某人有用
答案 0 :(得分:1)
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.java方法的WindowSurface.recreate()
的注释块,内容为:
/*
* 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。由于我是 在活动生命周期中无法正确处理Renderer。
活动生命周期
GLSurfaceView
必须何时暂停和 恢复渲染。活动停止时,GLSurfaceView
个客户端必须呼叫onPause()
,活动结束时,{@ 1} 开始。这些呼叫允许onResume()
暂停并恢复 渲染线程,还允许GLSurfaceView
释放和 重新创建GLSurfaceView
显示。
EGL上下文丢失
在某些情况下
OpenGL
呈现上下文将丢失。 通常在设备进入睡眠状态后唤醒时会发生这种情况。什么时候EGL
上下文丢失,所有EGL
资源(例如纹理) 与该OpenGL
关联的文件将被自动删除。 为了保持正确渲染,渲染器必须重新创建任何 丢失了仍然需要的资源。context
(GL10, EGLConfig)方法是执行此操作的便利位置。
因此,您的onSurfaceCreated
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
。隐形持有人不适用于opengl,这可能会导致您崩溃。startPreview
中处理onSurfaceTextureSizeChanged
吗?TextureViewGLActivity
和EGL_BAD_ALLOC
eglSwapBuffers failed:
是一个重要线索... EGL_BAD_SURFACE
删除并重新创建Surface?观察:
如果我将
如果您的!readyToDraw()
设为true,则错误永远不会发生android:hardwareAccelerated
级别,默认情况下启用了硬件加速功能
Target API
,但也可以显式启用(在应用程序或活动级别)。
答案 1 :(得分:0)
在glsurf.setVisibility(View.GONE)
中调用onPause()
适用于我的应用程序,但是当我在glsurf.setVisibility(View.VISIBLE)
中调用onWindowFocusChanged()
时则无效。
当我在glsurf.setVisibility(View.VISIBLE)
中呼叫onResume()
时,它对我有用。