Android OpenGL:GLSurfaceView.Renderer.onDrawFrame() 在启动时调用了两次
Android OpenGL: GLSurfaceView.Renderer.onDrawFrame() called twice at startup
我有一个简单的 Android 应用程序,它使用 OpenGL(通过 GLSurfaceView)。
代码如下:
public class MainActivity extends Activity {
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(new MyGLSurfaceView(this));
}
class MyGLSurfaceView extends GLSurfaceView implements GLSurfaceView.Renderer {
MyGLSurfaceView(Context context) {
super(context);
setEGLContextClientVersion(2); // OpenGL ES 2.0
setRenderer(this); // callbacks go to this class
setRenderMode(RENDERMODE_WHEN_DIRTY); // draw on request
}
public void onSurfaceChanged(GL10 gl, int width, int height) { }
public void onSurfaceCreated(GL10 gl, EGLConfig config) { }
public void onDrawFrame(GL10 gl) {
/* if (startup) do_only_once(); */
try { Thread.sleep(250); } catch (Exception ignored) { }
}
}
}
在应用程序启动时 onDrawFrame()(GLSurfaceView.Renderer)大部分时间调用两次。
据我所知,onSurfaceChanged()(GLSurfaceView.Renderer)应该调用 onDrawFrame(),但我不明白为什么会发生几次。
我想计算和绘制一些 "background" 对象,应该只做一次。我使用 setRenderMode(RENDERMODE_WHEN_DIRTY)。但是 onDrawFrame() 仍然被调用了几次。 如何让它只被调用一次?如此重复调用的原因是什么?
在每个函数的开头和结尾为这些函数(以及一些默认的 Activity 回调添加日志记录将导致以下输出。 Activity 生命周期似乎工作正常:
// Example of function with Logging:
protected void onCreate(Bundle savedInstanceState) {
Log.d("__DEBUG__", "onCreate() {");
super.onCreate(savedInstanceState);
setContentView(new MyGLSurfaceView(this));
Log.d("__DEBUG__", "onCreate() }");
}
22:12:46.361 __DEBUG__: onCreate() {
22:12:46.376 __DEBUG__: MyGLSurfaceView() {
22:12:46.376 __DEBUG__: MyGLSurfaceView() }
22:12:46.430 __DEBUG__: onCreate() }
22:12:46.431 __DEBUG__: onStart() {
22:12:46.431 __DEBUG__: onStart() }
22:12:46.432 __DEBUG__: onResume() {
22:12:46.433 __DEBUG__: onResume() }
22:12:46.498 __DEBUG__: onSurfaceCreated() {
22:12:46.498 __DEBUG__: onSurfaceCreated() }
22:12:46.498 __DEBUG__: onSurfaceChanged() {
22:12:46.498 __DEBUG__: onSurfaceChanged() }
22:12:46.498 __DEBUG__: onDrawFrame() {
22:12:46.748 __DEBUG__: onDrawFrame() }
22:12:46.754 __DEBUG__: onDrawFrame() {
22:12:47.004 __DEBUG__: onDrawFrame() }
我研究了 GLSurfaceView 的平台代码,发现 onDrawFrame() 可以触发两次,其中一次在 ctor 中。
我创建了一个 AOSP 合并请求,其中包含可以在此处找到的建议修复:https://android-review.googlesource.com/c/platform/frameworks/base/+/858050。
然而,考虑到可能的风险,它并不太重要,因此被“拒绝”...
处理此问题的唯一方法是在 onDrawFrame() 内实现带有 switch-case 的简单状态机。需要保持“初始”状态并重新绘制初始元素(在我的例子中是背景)直到真正的绘制请求到来(第一个请求将状态机切换到“正常”状态)。
我有一个简单的 Android 应用程序,它使用 OpenGL(通过 GLSurfaceView)。 代码如下:
public class MainActivity extends Activity {
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(new MyGLSurfaceView(this));
}
class MyGLSurfaceView extends GLSurfaceView implements GLSurfaceView.Renderer {
MyGLSurfaceView(Context context) {
super(context);
setEGLContextClientVersion(2); // OpenGL ES 2.0
setRenderer(this); // callbacks go to this class
setRenderMode(RENDERMODE_WHEN_DIRTY); // draw on request
}
public void onSurfaceChanged(GL10 gl, int width, int height) { }
public void onSurfaceCreated(GL10 gl, EGLConfig config) { }
public void onDrawFrame(GL10 gl) {
/* if (startup) do_only_once(); */
try { Thread.sleep(250); } catch (Exception ignored) { }
}
}
}
在应用程序启动时 onDrawFrame()(GLSurfaceView.Renderer)大部分时间调用两次。 据我所知,onSurfaceChanged()(GLSurfaceView.Renderer)应该调用 onDrawFrame(),但我不明白为什么会发生几次。
我想计算和绘制一些 "background" 对象,应该只做一次。我使用 setRenderMode(RENDERMODE_WHEN_DIRTY)。但是 onDrawFrame() 仍然被调用了几次。 如何让它只被调用一次?如此重复调用的原因是什么?
在每个函数的开头和结尾为这些函数(以及一些默认的 Activity 回调添加日志记录将导致以下输出。 Activity 生命周期似乎工作正常:
// Example of function with Logging:
protected void onCreate(Bundle savedInstanceState) {
Log.d("__DEBUG__", "onCreate() {");
super.onCreate(savedInstanceState);
setContentView(new MyGLSurfaceView(this));
Log.d("__DEBUG__", "onCreate() }");
}
22:12:46.361 __DEBUG__: onCreate() {
22:12:46.376 __DEBUG__: MyGLSurfaceView() {
22:12:46.376 __DEBUG__: MyGLSurfaceView() }
22:12:46.430 __DEBUG__: onCreate() }
22:12:46.431 __DEBUG__: onStart() {
22:12:46.431 __DEBUG__: onStart() }
22:12:46.432 __DEBUG__: onResume() {
22:12:46.433 __DEBUG__: onResume() }
22:12:46.498 __DEBUG__: onSurfaceCreated() {
22:12:46.498 __DEBUG__: onSurfaceCreated() }
22:12:46.498 __DEBUG__: onSurfaceChanged() {
22:12:46.498 __DEBUG__: onSurfaceChanged() }
22:12:46.498 __DEBUG__: onDrawFrame() {
22:12:46.748 __DEBUG__: onDrawFrame() }
22:12:46.754 __DEBUG__: onDrawFrame() {
22:12:47.004 __DEBUG__: onDrawFrame() }
我研究了 GLSurfaceView 的平台代码,发现 onDrawFrame() 可以触发两次,其中一次在 ctor 中。
我创建了一个 AOSP 合并请求,其中包含可以在此处找到的建议修复:https://android-review.googlesource.com/c/platform/frameworks/base/+/858050。 然而,考虑到可能的风险,它并不太重要,因此被“拒绝”...
处理此问题的唯一方法是在 onDrawFrame() 内实现带有 switch-case 的简单状态机。需要保持“初始”状态并重新绘制初始元素(在我的例子中是背景)直到真正的绘制请求到来(第一个请求将状态机切换到“正常”状态)。