从分屏到全屏后出现幻影
phantom images after going from split screen to full screen
我正在使用 NDK 为 Android 编写游戏。我的游戏使用 vulkan(如果可用),否则使用 OpenGL。
我有一个问题,如果您将游戏设置为分屏模式,设备保持纵向,然后将游戏大小调整为全屏模式,旧视图中的游戏残像仍然可见。注意:使用游戏触发器执行此操作会调用 SurfaceHolder.Callback.surfaceDestroyed(在 Java 中),这反过来会关闭我在 C++ 中的渲染线程。我对 surfaceDestroyed 的回调告诉 C++ 渲染线程停止,然后加入它。
我可以通过使用任何颜色调用 glClearColor,然后在渲染线程关闭之前调用 eglSwapBuffers,在 OpenGL 中解决这个问题。
这是对 OpenGL 的有效修复吗?我还应该做些什么来清理旧表面吗?我
在我退出渲染线程之前,验证了 ANativeWindow_release 在我从 ANativeWindow_fromSurface 获得的 window 上被调用。
然后我尝试在 vulkan 中做同样的事情并且 运行 再次遇到问题......我通过 do 使用了 vkCmdClearColorImage
正在阅读以下内容:
(1) vkQueueWaitIdle(presentQueue)
(2) vkAquireNextImageKHR
(3) 初始化相应的命令缓冲区:
(3a) ImageMemoryBarrier VK_IMAGE_LAYOUT_UNDEFINED -> VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 0 -> VK_ACCESS_TRANSFER_WRITE_BIT
(3b) vkCmdClearColor VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL
(3c) ImageMemoryBarrier VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL -> VK_IMAGE_LAYOUT_PRESENT_SRC_KHR, VK_ACCESS_TRANSFER_WRITE_BIT -> VK_ACCESS_MEMORY_READ_BIT
(4) vkQueueSubmit(图形队列...)
(5) vkQueuePresentKHR(presentQueue...)
(6) vkQueueWaitIdle(presentQueue)
我到了 3a,然后我在验证层中收到一个错误,说图像不是使用 VK_IMAGE_USAGE_TRANSFER_DST_BIT 使用标志创建的。如何使用此用法位创建交换链图像?
如果需要更多信息,请告诉我。谢谢!
Vulkan 部分不言自明;有一个 imageUsage
成员。让我给你代码:
VkSurfaceCapabilitiesKHR caps;
errco = vkGetPhysicalDeviceSurfaceCapabilitiesKHR( pdev, mySurface, &caps ); if(errco) panic();
if( !(caps.supportedUsageFlags & VK_IMAGE_USAGE_TRANSFER_DST_BIT) ) panic();
VkSwapchainCreateInfoKHR sci = {VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR};
sci.surface = mySurface;
sci.imageUsage = VK_IMAGE_USAGE_TRANSFER_DST_BIT; // !
// etc
VkSwapchainKHR mySwapchain;
errco = vkCreateSwapchainKHR( dev, &sci, nullptr, &mySwapchain ); if(errco) panic();
虽然你可能无论如何都不应该这样做。没有理由做vkCmdClearColorImage
。在您打算写入之前使用渲染通道清除彩色图像 (VkAttachmentDescription::loadOp
)。它效率更高,作为奖励,它算作渲染,不需要 TRANSFER
使用。
假设您的应用无法及时提供新图像,windowBackgroundFallback 似乎应该是解决此问题的一般解决方案。
消除幻像的最佳解决方案是告诉 android 如果发生屏幕大小调整,不要关闭应用程序。这样,可以通过重新创建交换链和重新绘制游戏来处理屏幕大小调整。清单文件中的 article talks setting android:configChanges。以下设置阻止 android 在屏幕从分屏调整为全屏时关闭应用程序:
android:configChanges="screenSize|orientation|screenLayout"
我正在使用 NDK 为 Android 编写游戏。我的游戏使用 vulkan(如果可用),否则使用 OpenGL。
我有一个问题,如果您将游戏设置为分屏模式,设备保持纵向,然后将游戏大小调整为全屏模式,旧视图中的游戏残像仍然可见。注意:使用游戏触发器执行此操作会调用 SurfaceHolder.Callback.surfaceDestroyed(在 Java 中),这反过来会关闭我在 C++ 中的渲染线程。我对 surfaceDestroyed 的回调告诉 C++ 渲染线程停止,然后加入它。
我可以通过使用任何颜色调用 glClearColor,然后在渲染线程关闭之前调用 eglSwapBuffers,在 OpenGL 中解决这个问题。
这是对 OpenGL 的有效修复吗?我还应该做些什么来清理旧表面吗?我 在我退出渲染线程之前,验证了 ANativeWindow_release 在我从 ANativeWindow_fromSurface 获得的 window 上被调用。
然后我尝试在 vulkan 中做同样的事情并且 运行 再次遇到问题......我通过 do 使用了 vkCmdClearColorImage 正在阅读以下内容:
(1) vkQueueWaitIdle(presentQueue)
(2) vkAquireNextImageKHR
(3) 初始化相应的命令缓冲区:
(3a) ImageMemoryBarrier VK_IMAGE_LAYOUT_UNDEFINED -> VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 0 -> VK_ACCESS_TRANSFER_WRITE_BIT
(3b) vkCmdClearColor VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL
(3c) ImageMemoryBarrier VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL -> VK_IMAGE_LAYOUT_PRESENT_SRC_KHR, VK_ACCESS_TRANSFER_WRITE_BIT -> VK_ACCESS_MEMORY_READ_BIT
(4) vkQueueSubmit(图形队列...)
(5) vkQueuePresentKHR(presentQueue...)
(6) vkQueueWaitIdle(presentQueue)
我到了 3a,然后我在验证层中收到一个错误,说图像不是使用 VK_IMAGE_USAGE_TRANSFER_DST_BIT 使用标志创建的。如何使用此用法位创建交换链图像?
如果需要更多信息,请告诉我。谢谢!
Vulkan 部分不言自明;有一个 imageUsage
成员。让我给你代码:
VkSurfaceCapabilitiesKHR caps;
errco = vkGetPhysicalDeviceSurfaceCapabilitiesKHR( pdev, mySurface, &caps ); if(errco) panic();
if( !(caps.supportedUsageFlags & VK_IMAGE_USAGE_TRANSFER_DST_BIT) ) panic();
VkSwapchainCreateInfoKHR sci = {VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR};
sci.surface = mySurface;
sci.imageUsage = VK_IMAGE_USAGE_TRANSFER_DST_BIT; // !
// etc
VkSwapchainKHR mySwapchain;
errco = vkCreateSwapchainKHR( dev, &sci, nullptr, &mySwapchain ); if(errco) panic();
虽然你可能无论如何都不应该这样做。没有理由做vkCmdClearColorImage
。在您打算写入之前使用渲染通道清除彩色图像 (VkAttachmentDescription::loadOp
)。它效率更高,作为奖励,它算作渲染,不需要 TRANSFER
使用。
假设您的应用无法及时提供新图像,windowBackgroundFallback 似乎应该是解决此问题的一般解决方案。
消除幻像的最佳解决方案是告诉 android 如果发生屏幕大小调整,不要关闭应用程序。这样,可以通过重新创建交换链和重新绘制游戏来处理屏幕大小调整。清单文件中的 article talks setting android:configChanges。以下设置阻止 android 在屏幕从分屏调整为全屏时关闭应用程序:
android:configChanges="screenSize|orientation|screenLayout"