TLDR 版本:由在 OpenGL ES 的 onDrawFrame() 中调用 Thread.sleep() 引起。
我通过查看下面链接中的代码来了解其中的一部分。
https://android.googlesource.com/platform/frameworks/native/+/9cce325fae8adcf7560a28eef394489f09bad74d/libs/surfaceflinger_client/SharedBufferStack.cpp
所以这个 SharedBufferStack 是 Android 的 SurfaceFlinger 的一部分,在http://rahulonblog.blogspot.sg/2013/06/an-overview-of-surfaceflinger.html 中有描述
Surfaceflinger :它是一个系统范围的表面作曲家功能,驻留在 android 框架中。它从可能是 2D 或 3D 的不同应用程序中获取数据(即表面),最后将其组合以获得将被馈送到内存(即帧缓冲区)的主表面。
Surfaceflinger根据其位置、大小等参数合成所有表面,虽然这个合成是由OpenGL完成的(由Surfaceflinger调用),但我们需要Surfaceflinger计算相关参数,如重叠函数。
也就是说SharedBufferStack是供不同应用程序共享内存供图形界面使用的(如果我错了请纠正我)。
在第 281 和 282 行,它调用了 LOGW(Logcat 调用警告)。
LOGW("dequeue: tail=%d, head=%d, avail=%d, queued=%d",
tail, stack.head, stack.available, stack.queued);
如果您阅读功能块的其余部分,SharedBufferClient::dequeue 会尝试警告堆栈为空/接近为空。
如果我做出一个疯狂的猜测,我认为“图形”堆栈至少需要有一些东西,否则它就没有什么可显示的了。我仍然不知道为什么它在tail = 0 和stack.head = 1 时调用stack.head==tail。我看不出它实际上是一个堆栈。
=== 更新 1
显然经过更多测试,它恰好是我在 OpenGL ES 循环的 onDrawFrame 中调用的 Thread.sleep。由于 RENDERMODE_CONTINUOUSLY 不能正确控制帧速率(因为我想将其限制为每秒 30 帧而不是让它快速运行),所以我让线程在剩余的时间内休眠。
Thread.sleep(16 - diffTime);
如果我是正确的,它会使 opengl 线程休眠。显然,它会导致上面的消息出现并且听起来不太好,因为您将图形线程从堆栈中取出。我认为我可以做的一种方法是运行一个单独的线程,该线程调用 onDrawFrame 以使用 RENDERMODE_WHEN_DIRTY 进行渲染。另一种方法是让它运行得尽可能快,但每隔 0.017 秒(60 fps)间隔调用一次逻辑循环或控制器来处理动画和其他内容。
=== 更新 2
我做了一个允许尽可能快地渲染图像的方法,但要花时间找出运行逻辑的时间。