从分屏到全屏后的幻像图像

时间:2019-03-03 23:48:54

标签: android opengl-es android-ndk vulkan

我正在使用NDK编写Android游戏。我的游戏使用vulkan(如果可用),否则使用OpenGL。

我有一个问题,如果您将游戏以纵向放置在分屏模式下,然后将游戏调整为全屏模式,则旧视图上的游戏残像仍然可见。注意:在游戏中执行此操作会触发SurfaceHolder.Callback.surfaceDestroyed(在Java中)被调用,从而关闭C ++中的渲染线程。我对surfaceDestroyed的回调告诉C ++渲染线程停止,然后加入它。

我可以在OpenGL中解决此问题,方法是使用任意颜色调用glClearColor,然后在渲染线程关闭之前立即调用eglSwapBuffers。

这是OpenGL的有效修复程序吗?我还有其他方法可以清理旧表面吗?一世 验证在退出渲染线程之前,从ANativeWindow_fromSurface获取的窗口上已调用ANativeWindow_release。

然后我尝试在vulkan中执行相同的操作,然后再次遇到问题...我使用了vkCmdClearColorImage by do 如下:

(1)vkQueueWaitIdle(presentQueue)

(2)vkAquireNextImageKHR

(3)使用以下命令初始化相应的命令缓冲区:

(3a)图像内存屏障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(graphicsQueue ...)

(5)vkQueuePresentKHR(presentQueue ...)

(6)vkQueueWaitIdle(presentQueue)

我到达3a,然后在验证层收到一个错误,说该图像不是使用VK_IMAGE_USAGE_TRANSFER_DST_BIT使用标志创建的。我该如何使用此使用位创建交换链图像?

请让我知道是否需要其他信息。谢谢!

1 个答案:

答案 0 :(得分:1)

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讨论清单文件中的设置android:configChanges。当屏幕从分屏更改为全屏时,以下设置可阻止android关闭应用程序:

android:configChanges="screenSize|orientation|screenLayout"