在将SurfaceView从canvas切换到OpenGL后出现EGL_BAD_ALLOC错误

3

即使使用Surface.lockCanvas(null)并释放Surface.unlockCanvasAndPost(),我也无法将Surface锁定到EGL(使用eglCreateWindowSurface()

错误代码:

EGLNativeWindowType 0x61dff830 already connected to another API
eglCreateWindowSurface:414 error 3003 (EGL_BAD_ALLOC)

我不需要保留Canvas绘制的表面,只需要能够更新SurfaceView表面并显示它。
如果在使用EGL之前不绘制到Surface,则它可以正常工作,如果我只放置:
Canvas c = mSurface.lockCanvas(null);
c.drawColor(Color.RED);
mSurface.unlockCanvasAndPost(c);

...我遇到了这个错误

这是预期的行为吗?这在真实设备4.1.2和AVD API25上都会发生。

有没有一种方法可以完全解锁Surface,使其不受Canvas绘图的影响(即使需要使用本机代码)?

相反的操作是有效的(EGL到Canvas)

TextureView的行为相同

解决方法:

如果在我的TextureView中,我销毁本地Surface对象并使用new Surface(mOldSurfaceTexture)从先前的Surface所拥有的相同SurfaceTexture重新创建它,则该错误不会出现。

1个回答

1
这是预期行为,正如官方文档所述。
当您锁定一个Surface以进行Canvas访问时,“CPU渲染器”连接到BufferQueue的生产者端,并且直到Surface被销毁才断开连接。大多数其他生产者(如GLES)可以断开并重新连接到Surface,但基于Canvas的“CPU渲染器”无法这样做。这意味着如果您曾经锁定过Surface进行Canvas操作,则无法使用GLES绘制表面或向其发送来自视频解码器的帧。

https://source.android.com/devices/graphics/arch-sh.html#canvas

所以唯一的方法就是使用我在问题中发布的解决方法

------------------ 编辑: -----------------

我发现另一种方法:如果需要使用Canvas绘图,则必须创建一个EGL/OpenGL上下文和一个Canvas,从Bitmap(您必须创建与您的表面相同大小的位图)创建Canvas,这样您就可以向此Canvas绘制,将位图作为OpenGL纹理加载并从OpenGL绘制它


1
你能否再详细解释一下你的解决方案(或两个方案)?我遇到了完全相同的问题。也许你现在有一个最喜欢的解决方案? - Veit

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