将SurfaceView Surface从画布切换到opengl后的EGL_BAD_ALLOC

时间:2017-02-24 19:07:18

标签: android android-canvas surfaceview egl

如标题所述,即使我使用Surface.lockCanvas(null)

发布了Surface,也无法在使用Surface.unlockCanvasAndPost()绘制后将Surface锁定到EGL(使用eglCreateWindowSurface)

错误代码:

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

我不需要在画布上保持画面,我只需要能够更新SurfaceView曲面并显示它

如果我没有绘制到Surface使用EGL之前它可以正常工作,如果我只是放

Canvas c = mSurface.lockCanvas(null);
c.drawColor(Color.RED);
mSurface.unlockCanvasAndPost(c);

我收到此错误

这是预期的行为吗?这在真实设备4.1.2和AVD API25

上都会发生

有没有办法从Canvas绘图中完全解锁Surface(如果需要,甚至使用原生)?

Opposite正常工作(EGL to Canvas)

---------编辑---------------

TextureView

的行为相同

---------解决方法---------------

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

1 个答案:

答案 0 :(得分:1)

这是预期的行为,如官方文档中所述

  

当您锁定Surface for Canvas访问时,“CPU渲染器”连接到BufferQueue的生产者端,并且在Surface被销毁之前不会断开连接。大多数其他生产者(如GLES)可以断开连接并重新连接到Surface,但基于Canvas的“CPU渲染器”不能。这意味着如果您已经将其锁定为Canvas,则无法使用GLES在曲面上绘制或从视频解码器发送帧。

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

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

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

我找到了另一种方法:如果你需要使用Canvas进行绘制,则必须创建一个EGL/OpenGL上下文,并Canvas来自Bitmap (你必须创建相同大小的表面, 因此,您可以绘制到此画布,将位图作为opengl纹理加载并从OpenGL中绘制