[杂谈] 使用 Delphi 在 Vivo Y51A 手机上 Delphi 应用故障的一处问题的简单研究

这个问题,实际上北京老猫在它的 FireMonkey 移动开发中已经给出了一个解决方案,要求修改 FMX.Canvas.GPU,因为实际遇到了这个情况,所以我就特意跟踪了下,我觉得真正的问题应该是出在 Vivo,或者是高通提供的驱动上的问题。FMX.Canvas.GPU 实际上低层调用的是 FMX.Context.GLES 中的 MaxTextureSize 方法来获取图片的最大允许大小, Delphi 的实现代码为:

class function TCustomContextOpenGL.MaxTextureSize: Integer;
begin
  CreateSharedContext;
  glGetIntegerv(GL_MAX_TEXTURE_SIZE, @Result);
end;

单步执行的结果,发现 Result 的值返回的是 0。那么尝试看 GL_MAX_TEXTURE_SIZE 啥时候会返回 0 呢?

我们在这块以微软的文档来看看 glGetIntergerv 到底怎么说的:

GL_MAX_TEXTURE_SIZE
The params parameter returns one value: the maximum width or height of any texture image (without borders). See glTexImage1D and glTexImage2D.

好吧,让我们看 glTextImage1D 和 glTextImage2D,找到下面一段话:

GL_INVALID_VALUE
width or height was less than zero or greater than 2 + GL_MAX_TEXTURE_SIZE, or it could not be represented as 2ⁿ + 2(border) for some integer value of n.

好吧,我是没看它官方说啥时候应该返回0。不过在 Stackflow  的一篇问答里,它说了一句话:

maxTextureSize stores the size limit for decoded image such as 4096×4096, 8192×8192 . Remember to run this piece of code in the MainThread or you will get Zero.

简单说来,就是说这段代码如果不是运行在主线程,将会返回 0。因为着急,我直接处理了 MaxTextureSize 函数,直接返回了一个固定值 8192(一般是8192/16384的居多:数据来源)。但这个问题的原因到底是什么,我现在因为没有测试环境,无法确定问题的真正原因,如果那位朋友有这款手机,欢迎联系我大家一起测试下问题到底出在那里,会不会是某些特定情况下,OpenGL 的上下文真的创建在了后台线程造成的。

另外,这个问题仅存在于 Android 中,iOS 中暂时至少我是没有遇到。

附:Android 调试日志,可以看到 eglCreateWindowSurface 调用失败造成后面 GL_MAX_TEXTURE_SIZE 为 0 造成此问题。

08-11 13:02:40.284: I/Adreno-EGL(22385): Reconstruct Branch: NOTHING
08-11 13:02:40.294: D/StatusBarColorManager(3760): SystemUI|notifyStatusBarColorInfo: iconColor = -1, bgColor = ffededed, bgVisible = true
08-11 13:02:40.324: E/BufferQueueProducer(249): [com.jlgoldenbay.ddb/com.embarcadero.firemonkey.FMXNativeActivity] connect(P): BufferQueue has been abandoned
08-11 13:02:40.324: E/libEGL(22385): eglCreateWindowSurface: native_window_api_connect (win=0xb96fa290) failed (0xffffffed) (already connected to another API?)
08-11 13:02:40.324: E/libEGL(22385): eglCreateWindowSurface:417 error 3003 (EGL_BAD_ALLOC)
08-11 13:02:40.324: W/Adreno-EGL(22385): <qeglDrvAPI_eglMakeCurrent:2963>: EGL_BAD_MATCH
08-11 13:02:40.324: E/libEGL(22385): eglMakeCurrent:792 error 3009 (EGL_BAD_MATCH)
08-11 13:02:40.324: E/libEGL(22385): eglDestroySurface:587 error 300d (EGL_BAD_SURFACE)
08-11 13:02:40.324: I/info(22385): FMX: 顶顶棒: [Context Exception]: Cannot create OpenGL context for 'eglMakeCurrent'.
08-11 13:02:40.444: E/libEGL(22385): call to OpenGL ES API with no current context (logged once per thread)
08-11 13:02:40.444: E/libEGL(22385): validate_display:255 error 3008 (EGL_BAD_DISPLAY)
08-11 13:02:40.444: E/libEGL(22385): validate_display:255 error 3008 (EGL_BAD_DISPLAY)
08-11 13:02:40.444: E/BufferQueueProducer(249): [com.jlgoldenbay.ddb/com.embarcadero.firemonkey.FMXNativeActivity] connect(P): BufferQueue has been abandoned
08-11 13:02:40.444: E/libEGL(22385): eglCreateWindowSurface: native_window_api_connect (win=0xb96fa290) failed (0xffffffed) (already connected to another API?)
08-11 13:02:40.444: E/libEGL(22385): eglCreateWindowSurface:417 error 3003 (EGL_BAD_ALLOC)
08-11 13:02:40.444: W/Adreno-EGL(22385): <qeglDrvAPI_eglMakeCurrent:2963>: EGL_BAD_MATCH
08-11 13:02:40.444: E/libEGL(22385): eglMakeCurrent:792 error 3009 (EGL_BAD_MATCH)
08-11 13:02:40.444: I/info(22385): FMX: 顶顶棒: [Context Exception]: Cannot create OpenGL context for 'CreateDummyContext'.
08-11 13:02:40.444: E/libEGL(22385): eglDestroySurface:587 error 300d (EGL_BAD_SURFACE)
08-11 13:02:40.444: E/BufferQueueProducer(249): [com.jlgoldenbay.ddb/com.embarcadero.firemonkey.FMXNativeActivity] connect(P): BufferQueue has been abandoned
08-11 13:02:40.444: E/libEGL(22385): eglCreateWindowSurface: native_window_api_connect (win=0xb96fa290) failed (0xffffffed) (already connected to another API?)
08-11 13:02:40.444: E/libEGL(22385): eglCreateWindowSurface:417 error 3003 (EGL_BAD_ALLOC)
08-11 13:02:40.454: W/Adreno-EGL(22385): <qeglDrvAPI_eglMakeCurrent:2963>: EGL_BAD_MATCH
08-11 13:02:40.454: E/libEGL(22385): eglMakeCurrent:792 error 3009 (EGL_BAD_MATCH)
08-11 13:02:40.454: E/libEGL(22385): eglDestroySurface:587 error 300d (EGL_BAD_SURFACE)
08-11 13:02:40.454: I/info(22385): FMX: 顶顶棒: [Context Exception]: Cannot create OpenGL context for 'eglMakeCurrent'.
08-11 13:02:40.484: E/libEGL(22385): validate_display:255 error 3008 (EGL_BAD_DISPLAY)
08-11 13:02:40.494: E/libEGL(22385): validate_display:255 error 3008 (EGL_BAD_DISPLAY)
08-11 13:02:40.494: E/libEGL(22385): validate_display:255 error 3008 (EGL_BAD_DISPLAY)
08-11 13:02:40.504: D/debug(22385): OpenGLES.GL_MAX_TEXTURE_SIZE:0
08-11 13:02:40.504: D/debug(22385): OpenGLES.GL_MAX_TEXTURE_SIZE:0

 

分享到: