From 8203055211962d6d383dd2738f08456be9266229 Mon Sep 17 00:00:00 2001 From: Roman Kuznetsov Date: Wed, 20 Feb 2019 00:03:27 +0300 Subject: [PATCH] [vulkan] Fixed surface changing --- android/jni/com/mapswithme/maps/Framework.cpp | 18 ++++- android/jni/com/mapswithme/maps/Framework.hpp | 2 +- .../jni/com/mapswithme/maps/MapFragment.cpp | 5 +- .../vulkan/android_vulkan_context_factory.cpp | 75 ++++++++++--------- .../vulkan/android_vulkan_context_factory.hpp | 4 +- .../src/com/mapswithme/maps/MapFragment.java | 8 +- drape/render_state.cpp | 6 ++ drape/vulkan/vulkan_base_context.cpp | 16 ++-- drape/vulkan/vulkan_base_context.hpp | 5 +- drape/vulkan/vulkan_mesh_object_impl.cpp | 2 +- 10 files changed, 80 insertions(+), 61 deletions(-) diff --git a/android/jni/com/mapswithme/maps/Framework.cpp b/android/jni/com/mapswithme/maps/Framework.cpp index 825ed30ea2..df98407f11 100644 --- a/android/jni/com/mapswithme/maps/Framework.cpp +++ b/android/jni/com/mapswithme/maps/Framework.cpp @@ -248,12 +248,26 @@ bool Framework::IsDrapeEngineCreated() return m_work.IsDrapeEngineCreated(); } -void Framework::Resize(int w, int h) +void Framework::Resize(JNIEnv * env, jobject jSurface, int w, int h) { if (m_vulkanContextFactory) - CastFactory(m_vulkanContextFactory)->UpdateSurfaceSize(w, h); + { + auto vulkanContextFactory = CastFactory(m_vulkanContextFactory); + if (vulkanContextFactory->GetWidth() != w || vulkanContextFactory->GetHeight() != h) + { + m_vulkanContextFactory->SetPresentAvailable(false); + m_work.SetRenderingDisabled(false /* destroyContext */); + + vulkanContextFactory->ChangeSurface(env, jSurface, w, h); + + vulkanContextFactory->SetPresentAvailable(true); + m_work.SetRenderingEnabled(); + } + } else + { m_oglContextFactory->CastFactory()->UpdateSurfaceSize(w, h); + } m_work.OnSize(w, h); //TODO: remove after correct visible rect calculation. diff --git a/android/jni/com/mapswithme/maps/Framework.hpp b/android/jni/com/mapswithme/maps/Framework.hpp index fc71102422..77429eed5e 100644 --- a/android/jni/com/mapswithme/maps/Framework.hpp +++ b/android/jni/com/mapswithme/maps/Framework.hpp @@ -117,7 +117,7 @@ namespace android return m_work.GetRoutingManager().GetLastUsedRouter(); } - void Resize(int w, int h); + void Resize(JNIEnv * env, jobject jSurface, int w, int h); struct Finger { diff --git a/android/jni/com/mapswithme/maps/MapFragment.cpp b/android/jni/com/mapswithme/maps/MapFragment.cpp index d39ab443ee..927eca9041 100644 --- a/android/jni/com/mapswithme/maps/MapFragment.cpp +++ b/android/jni/com/mapswithme/maps/MapFragment.cpp @@ -107,9 +107,10 @@ Java_com_mapswithme_maps_MapFragment_nativeResumeSurfaceRendering(JNIEnv *, jcla } JNIEXPORT void JNICALL -Java_com_mapswithme_maps_MapFragment_nativeSurfaceChanged(JNIEnv * env, jclass clazz, jint w, jint h) +Java_com_mapswithme_maps_MapFragment_nativeSurfaceChanged(JNIEnv * env, jclass, jobject surface, + jint w, jint h) { - g_framework->Resize(w, h); + g_framework->Resize(env, surface, w, h); } JNIEXPORT void JNICALL diff --git a/android/jni/com/mapswithme/vulkan/android_vulkan_context_factory.cpp b/android/jni/com/mapswithme/vulkan/android_vulkan_context_factory.cpp index 942ed80284..659b0e2646 100644 --- a/android/jni/com/mapswithme/vulkan/android_vulkan_context_factory.cpp +++ b/android/jni/com/mapswithme/vulkan/android_vulkan_context_factory.cpp @@ -180,8 +180,8 @@ AndroidVulkanContextFactory::AndroidVulkanContextFactory(int appVersionCode) return; } - std::array depthFormats = {dp::vulkan::UnpackFormat(dp::TextureFormat::Depth), - dp::vulkan::UnpackFormat(dp::TextureFormat::DepthStencil)}; + std::array depthFormats = {{dp::vulkan::UnpackFormat(dp::TextureFormat::Depth), + dp::vulkan::UnpackFormat(dp::TextureFormat::DepthStencil)}}; VkFormatProperties formatProperties; for (auto depthFormat : depthFormats) { @@ -243,6 +243,14 @@ void AndroidVulkanContextFactory::SetSurface(JNIEnv * env, jobject jsurface) return; } + SetVulkanSurface(); +} + +void AndroidVulkanContextFactory::SetVulkanSurface() +{ + if (m_windowSurfaceValid) + return; + VkAndroidSurfaceCreateInfoKHR createInfo = {}; createInfo.sType = VK_STRUCTURE_TYPE_ANDROID_SURFACE_CREATE_INFO_KHR; createInfo.pNext = nullptr; @@ -268,13 +276,10 @@ void AndroidVulkanContextFactory::SetSurface(JNIEnv * env, jobject jsurface) } CHECK_EQUAL(supportsPresent, VK_TRUE, ()); - if (!QuerySurfaceSize()) - return; + CHECK(QuerySurfaceSize(), ()); if (m_drawContext) - { - m_drawContext->SetSurface(m_surface, m_surfaceFormat, m_surfaceCapabilities, m_surfaceWidth, m_surfaceHeight); - } + m_drawContext->SetSurface(m_surface, m_surfaceFormat, m_surfaceCapabilities); m_windowSurfaceValid = true; } @@ -331,20 +336,36 @@ bool AndroidVulkanContextFactory::QuerySurfaceSize() void AndroidVulkanContextFactory::ResetSurface() { + ResetVulkanSurface(true /* allowPipelineDump */); + + ANativeWindow_release(m_nativeWindow); + m_nativeWindow = nullptr; +} + +void AndroidVulkanContextFactory::ResetVulkanSurface(bool allowPipelineDump) +{ + if (!m_windowSurfaceValid) + return; + if (m_drawContext) - m_drawContext->ResetSurface(); + m_drawContext->ResetSurface(allowPipelineDump); - if (m_windowSurfaceValid) - { - ASSERT(m_vulkanInstance != nullptr,()); - vkDestroySurfaceKHR(m_vulkanInstance, m_surface, nullptr); - m_surface = 0; + vkDestroySurfaceKHR(m_vulkanInstance, m_surface, nullptr); + m_surface = 0; + m_windowSurfaceValid = false; +} - ANativeWindow_release(m_nativeWindow); - m_nativeWindow = nullptr; +void AndroidVulkanContextFactory::ChangeSurface(JNIEnv * env, jobject jsurface, int w, int h) +{ + if (w == m_surfaceWidth && m_surfaceHeight == h) + return; - m_windowSurfaceValid = false; - } + auto nativeWindow = ANativeWindow_fromSurface(env, jsurface); + CHECK(nativeWindow == m_nativeWindow, ("Native window changing is not supported.")); + + ResetVulkanSurface(false /* allowPipelineDump */); + SetVulkanSurface(); + LOG(LINFO, ("Surface changed", m_surfaceWidth, m_surfaceHeight)); } bool AndroidVulkanContextFactory::IsVulkanSupported() const @@ -369,26 +390,6 @@ int AndroidVulkanContextFactory::GetHeight() const return m_surfaceHeight; } -void AndroidVulkanContextFactory::UpdateSurfaceSize(int w, int h) -{ - ASSERT(IsValid(), ()); - if ((m_surfaceWidth != w && m_surfaceWidth != h) || - (m_surfaceHeight != w && m_surfaceHeight != h)) - { - LOG(LINFO, ("Surface size changed and must be re-queried.")); - if (!QuerySurfaceSize()) - { - m_surfaceWidth = w; - m_surfaceHeight = h; - } - } - else - { - m_surfaceWidth = w; - m_surfaceHeight = h; - } -} - dp::GraphicsContext * AndroidVulkanContextFactory::GetDrawContext() { return m_drawContext.get(); diff --git a/android/jni/com/mapswithme/vulkan/android_vulkan_context_factory.hpp b/android/jni/com/mapswithme/vulkan/android_vulkan_context_factory.hpp index 900f43f3df..49ed3f23ca 100644 --- a/android/jni/com/mapswithme/vulkan/android_vulkan_context_factory.hpp +++ b/android/jni/com/mapswithme/vulkan/android_vulkan_context_factory.hpp @@ -33,12 +33,14 @@ public: void SetSurface(JNIEnv * env, jobject jsurface); void ResetSurface(); + void ChangeSurface(JNIEnv * env, jobject jsurface, int w, int h); int GetWidth() const; int GetHeight() const; - void UpdateSurfaceSize(int w, int h); private: + void SetVulkanSurface(); + void ResetVulkanSurface(bool allowPipelineDump); bool QuerySurfaceSize(); VkInstance m_vulkanInstance = nullptr; diff --git a/android/src/com/mapswithme/maps/MapFragment.java b/android/src/com/mapswithme/maps/MapFragment.java index 934e21350a..dcb37a8dbc 100644 --- a/android/src/com/mapswithme/maps/MapFragment.java +++ b/android/src/com/mapswithme/maps/MapFragment.java @@ -230,11 +230,11 @@ public class MapFragment extends BaseMwmFragment } LOGGER.d(TAG, "surfaceChanged, mContextCreated = " + mContextCreated); - if (!mContextCreated || - (!mRequireResize && surfaceHolder.isCreating())) + if (!mContextCreated || (!mRequireResize && surfaceHolder.isCreating())) return; - nativeSurfaceChanged(width, height); + final Surface surface = surfaceHolder.getSurface(); + nativeSurfaceChanged(surface, width, height); mRequireResize = false; setupWidgets(width, height); @@ -373,7 +373,7 @@ public class MapFragment extends BaseMwmFragment private static native void nativeDetachSurface(boolean destroyContext); private static native void nativePauseSurfaceRendering(); private static native void nativeResumeSurfaceRendering(); - private static native void nativeSurfaceChanged(int w, int h); + private static native void nativeSurfaceChanged(Surface surface, int w, int h); private static native void nativeOnTouch(int actionType, int id1, float x1, float y1, int id2, float x2, float y2, int maskedPointer); private static native void nativeSetupWidget(int widget, float x, float y, int anchor); private static native void nativeApplyWidgets(); diff --git a/drape/render_state.cpp b/drape/render_state.cpp index a945368bae..3e5174090d 100644 --- a/drape/render_state.cpp +++ b/drape/render_state.cpp @@ -238,6 +238,12 @@ void TextureState::ApplyTextures(ref_ptr context, RenderState c CHECK(it != bindings.end(), ("Texture bindings inconsistency.")); ref_ptr t = texture.second->GetHardwareTexture(); + if (t == nullptr) + { + texture.second->UpdateState(context); + t = texture.second->GetHardwareTexture(); + CHECK(t != nullptr, ()); + } t->Bind(context); t->SetFilter(state.GetTextureFilter()); diff --git a/drape/vulkan/vulkan_base_context.cpp b/drape/vulkan/vulkan_base_context.cpp index 0947797245..f1612bf094 100644 --- a/drape/vulkan/vulkan_base_context.cpp +++ b/drape/vulkan/vulkan_base_context.cpp @@ -105,7 +105,7 @@ void VulkanBaseContext::Init(ApiVersion apiVersion) } void VulkanBaseContext::SetSurface(VkSurfaceKHR surface, VkSurfaceFormatKHR surfaceFormat, - VkSurfaceCapabilitiesKHR surfaceCapabilities, int width, int height) + VkSurfaceCapabilitiesKHR const & surfaceCapabilities) { m_surface = surface; m_surfaceFormat = surfaceFormat; @@ -115,7 +115,7 @@ void VulkanBaseContext::SetSurface(VkSurfaceKHR surface, VkSurfaceFormatKHR surf RecreateSwapchain(); } -void VulkanBaseContext::ResetSurface() +void VulkanBaseContext::ResetSurface(bool allowPipelineDump) { vkDeviceWaitIdle(m_device); @@ -130,13 +130,14 @@ void VulkanBaseContext::ResetSurface() m_surface.reset(); - if (m_pipeline) + if (m_pipeline && allowPipelineDump) m_pipeline->Dump(m_device); } void VulkanBaseContext::Resize(int w, int h) { - if (m_depthTexture != nullptr && m_surfaceCapabilities.currentExtent.width == w && + if (m_depthTexture != nullptr && + m_surfaceCapabilities.currentExtent.width == w && m_surfaceCapabilities.currentExtent.height == h) { return; @@ -305,7 +306,7 @@ void VulkanBaseContext::ApplyFramebuffer(std::string const & framebufferLabel) VkClearValue clearValues[2]; clearValues[0].color = {{m_clearColor.GetRedF(), m_clearColor.GetGreenF(), m_clearColor.GetBlueF(), m_clearColor.GetAlphaF()}}; - clearValues[1].depthStencil = {1.0f, m_stencilReferenceValue}; + clearValues[1].depthStencil = {1.0f, 0}; VkRenderPassBeginInfo renderPassBeginInfo = {}; renderPassBeginInfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO; @@ -808,11 +809,6 @@ void VulkanBaseContext::RecreateDepthTexture() m_depthTexture = make_unique_dp(params.m_allocator); m_depthTexture->Create(this, params, nullptr); - - //m_depthTexture = m_objectManager->CreateImage(VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT, - // UnpackFormat(TextureFormat::Depth), VK_IMAGE_ASPECT_DEPTH_BIT, - // m_surfaceCapabilities.currentExtent.width, - // m_surfaceCapabilities.currentExtent.height); } VkRenderPass VulkanBaseContext::CreateRenderPass(uint32_t attachmentsCount, AttachmentsOperations const & attachmentsOp, diff --git a/drape/vulkan/vulkan_base_context.hpp b/drape/vulkan/vulkan_base_context.hpp index e6877a2d0a..a487addcde 100644 --- a/drape/vulkan/vulkan_base_context.hpp +++ b/drape/vulkan/vulkan_base_context.hpp @@ -9,7 +9,6 @@ #include "drape/vulkan/vulkan_utils.hpp" #include "geometry/point2d.hpp" -#include "vulkan_texture.hpp" #include #include @@ -76,8 +75,8 @@ public: void ClearParamDescriptors(); void SetSurface(VkSurfaceKHR surface, VkSurfaceFormatKHR surfaceFormat, - VkSurfaceCapabilitiesKHR surfaceCapabilities, int width, int height); - void ResetSurface(); + VkSurfaceCapabilitiesKHR const & surfaceCapabilities); + void ResetSurface(bool allowPipelineDump); VkPhysicalDevice const GetPhysicalDevice() const { return m_gpu; } VkDevice GetDevice() const { return m_device; } diff --git a/drape/vulkan/vulkan_mesh_object_impl.cpp b/drape/vulkan/vulkan_mesh_object_impl.cpp index 09f161ac38..f02baf9b10 100644 --- a/drape/vulkan/vulkan_mesh_object_impl.cpp +++ b/drape/vulkan/vulkan_mesh_object_impl.cpp @@ -86,7 +86,7 @@ public: { if (state.GetColorTexture() != m_lastColorTexture) { - m_lastColorTexture == state.GetColorTexture(); + m_lastColorTexture = state.GetColorTexture(); ResetDescriptorSetGroup(); } }