我正在使用 Java 作为用户界面,使用 C ++ 和NDK作为渲染线程为 Android 编写游戏。如果可用,它将使用 Vulkan ,否则将使用 OpenGL ES 。此错误仅在 Vulkan 中发生。
在游戏中调整表面大小有多种原因。例如,如果用户在分屏模式下使用该应用程序,则转到全屏模式。对于这种情况,我不会关闭整个应用程序然后重新启动,而是通过调用SurfaceHolder.Callback.surfaceChanged
来自己处理调整大小。
调整表面大小后,我接到了SurfaceHolder.Callback.surfaceChanged
的电话。我将事件传递给C ++渲染线程。渲染线程等待设备变为空闲状态(通过调用vkDeviceWaitIdle
),然后销毁交换链,深度图像,渲染通道,图形管道,帧缓冲区和交换链命令。重新创建交换链时,它将调用:vkGetPhysicalDeviceSurfaceCapabilitiesKHR
以获取表面的当前范围,并将当前范围通过vkCreateSwapchainKHR
传递到VkSwapchainCreateInfoKHR.imageExtent
中。重新创建交换链,更新透视图矩阵等之后,我立即绘制了一个框架。
我的问题是VkSurfaceCapabilitiesKHR.currentExtent
从vkGetPhysicalDeviceSurfaceCapabilitiesKHR
返回,具有先前的表面尺寸。仅当游戏中什么都没有发生并且暂时没有绘制新框架时,才会出现此问题。
我可以通过将SurfaceHolder.Callback.surfaceChanged
接收到的宽度和高度的值传递给渲染线程,然后传递给swapchain娱乐来解决此问题。但是我认为这是错误的解决方案。为什么currentExtent
的表面尺寸不像文档中所说的那样? SurfaceHolder.Callback.surfaceChanged
应该在表面发生所有更改后被调用。
我还可以通过在重新创建交换链之前画一个框架来解决此问题。但是,除非我理解为什么会这样,否则我认为这也是错误的解决方案。在重新创建交换链之前,我是否需要做其他事情,而不是等待设备变为空闲状态?
我启用了验证层(并且知道它们正在工作),并且它们什么也不报告。
让我知道是否需要更多信息。感谢您的所有帮助。