mirror of
https://github.com/izzy2lost/WeeU.git
synced 2026-07-06 00:19:59 -07:00
Fix trying to acquire image when the surface is lost
This commit is contained in:
@@ -2631,7 +2631,13 @@ bool VulkanRenderer::AcquireNextSwapchainImage(bool mainWindow)
|
||||
m_padCloseReadySemaphore.notify();
|
||||
return false;
|
||||
}
|
||||
|
||||
#if __ANDROID__
|
||||
std::unique_lock lock(m_surfaceMutex);
|
||||
m_surfaceCondVar.wait(lock,[&](){
|
||||
auto& chainInfo = GetChainInfoPtr(mainWindow);
|
||||
return chainInfo && chainInfo->surface;
|
||||
});
|
||||
#endif // __ANDROID__
|
||||
auto& chainInfo = GetChainInfo(mainWindow);
|
||||
|
||||
if (chainInfo.swapchainImageIndex != -1)
|
||||
@@ -3770,7 +3776,29 @@ void VulkanRenderer::AppendOverlayDebugInfo()
|
||||
ImGui::Text("--- Tex heaps ---");
|
||||
memoryManager->appendOverlayHeapDebugInfo();
|
||||
}
|
||||
|
||||
#if __ANDROID__
|
||||
void VulkanRenderer::ClearSurface(bool mainWindow)
|
||||
{
|
||||
std::lock_guard lock(m_surfaceMutex);
|
||||
auto& chainInfo = GetChainInfoPtr(mainWindow);
|
||||
if(!chainInfo || !chainInfo->surface)
|
||||
return;
|
||||
vkDestroySurfaceKHR(m_instance, chainInfo->surface, nullptr);
|
||||
chainInfo->surface = nullptr;
|
||||
}
|
||||
void VulkanRenderer::NotifySurfaceChanged(bool mainWindow)
|
||||
{
|
||||
std::lock_guard lock(m_surfaceMutex);
|
||||
auto& chainInfo = GetChainInfoPtr(mainWindow);
|
||||
if(!chainInfo)
|
||||
return;
|
||||
if(mainWindow)
|
||||
chainInfo->surface = CreateFramebufferSurface(m_instance, gui_getWindowInfo().canvas_main);
|
||||
else
|
||||
chainInfo->surface = CreateFramebufferSurface(m_instance, gui_getWindowInfo().canvas_pad);
|
||||
m_surfaceCondVar.notify_one();
|
||||
}
|
||||
#endif // __ANDROID__
|
||||
void VKRDestructibleObject::flagForCurrentCommandBuffer()
|
||||
{
|
||||
m_lastCmdBufferId = VulkanRenderer::GetInstance()->GetCurrentCommandBufferId();
|
||||
|
||||
@@ -183,7 +183,10 @@ public:
|
||||
void GetDeviceFeatures();
|
||||
void DetermineVendor();
|
||||
void InitializeSurface(const Vector2i& size, bool mainWindow);
|
||||
|
||||
#if __ANDROID__
|
||||
void ClearSurface(bool mainWindow);
|
||||
void NotifySurfaceChanged(bool mainWindow);
|
||||
#endif // __ANDROID
|
||||
const std::unique_ptr<SwapchainInfoVk>& GetChainInfoPtr(bool mainWindow) const;
|
||||
SwapchainInfoVk& GetChainInfo(bool mainWindow) const;
|
||||
|
||||
@@ -610,6 +613,11 @@ private:
|
||||
VkPipelineLayout m_pipelineLayout{nullptr};
|
||||
VkCommandPool m_commandPool{ nullptr };
|
||||
|
||||
#if __ANDROID__
|
||||
std::mutex m_surfaceMutex;
|
||||
std::condition_variable m_surfaceCondVar;
|
||||
#endif // __ANDROID__
|
||||
|
||||
// buffer to cache uniform vars
|
||||
VkBuffer m_uniformVarBuffer = VK_NULL_HANDLE;
|
||||
VkDeviceMemory m_uniformVarBufferMemory = VK_NULL_HANDLE;
|
||||
|
||||
@@ -180,10 +180,23 @@ Java_info_cemu_Cemu_NativeLibrary_initializeRendererSurface(JNIEnv *env, jclass
|
||||
VulkanRenderer::GetInstance()->InitializeSurface(
|
||||
{width, height},
|
||||
is_main_canvas);
|
||||
|
||||
}
|
||||
extern "C"
|
||||
JNIEXPORT void JNICALL
|
||||
Java_info_cemu_Cemu_NativeLibrary_setDPI(JNIEnv *env, jclass clazz, jfloat dpi) {
|
||||
auto& windowInfo = gui_getWindowInfo();
|
||||
auto &windowInfo = gui_getWindowInfo();
|
||||
windowInfo.dpi_scale = windowInfo.pad_dpi_scale = dpi;
|
||||
}
|
||||
|
||||
extern "C"
|
||||
JNIEXPORT void JNICALL
|
||||
Java_info_cemu_Cemu_NativeLibrary_clearSurface(JNIEnv *env, jclass clazz, jboolean is_main_canvas) {
|
||||
VulkanRenderer::GetInstance()->ClearSurface(is_main_canvas);
|
||||
}
|
||||
extern "C"
|
||||
JNIEXPORT void JNICALL
|
||||
Java_info_cemu_Cemu_NativeLibrary_recreateRenderSurface(JNIEnv *env, jclass clazz,
|
||||
jboolean is_main_canvas) {
|
||||
VulkanRenderer::GetInstance()->NotifySurfaceChanged(is_main_canvas);
|
||||
}
|
||||
@@ -1,24 +1,16 @@
|
||||
package info.cemu.Cemu;
|
||||
|
||||
import android.content.Intent;
|
||||
import android.os.Bundle;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.fragment.app.Fragment;
|
||||
import androidx.recyclerview.widget.LinearLayoutManager;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.SurfaceHolder;
|
||||
import android.view.SurfaceView;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
|
||||
import java.util.Objects;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.fragment.app.Fragment;
|
||||
|
||||
import info.cemu.Cemu.databinding.FragmentEmulationBinding;
|
||||
import info.cemu.Cemu.databinding.FragmentGamesBinding;
|
||||
|
||||
public class EmulationFragment extends Fragment implements SurfaceHolder.Callback {
|
||||
FragmentEmulationBinding binding;
|
||||
@@ -35,7 +27,7 @@ public class EmulationFragment extends Fragment implements SurfaceHolder.Callbac
|
||||
}
|
||||
|
||||
long gameTitleId;
|
||||
boolean isRunning;
|
||||
boolean isGameRunning;
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
@@ -55,15 +47,6 @@ public class EmulationFragment extends Fragment implements SurfaceHolder.Callbac
|
||||
return binding.getRoot();
|
||||
}
|
||||
|
||||
private void startGame() {
|
||||
if (!isRunning) {
|
||||
isRunning = true;
|
||||
NativeLibrary.initializerRenderer();
|
||||
NativeLibrary.initializeRendererSurface(true);
|
||||
NativeLibrary.startGame(gameTitleId);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void surfaceCreated(@NonNull SurfaceHolder surfaceHolder) {
|
||||
|
||||
@@ -73,11 +56,18 @@ public class EmulationFragment extends Fragment implements SurfaceHolder.Callbac
|
||||
public void surfaceChanged(@NonNull SurfaceHolder surfaceHolder, int format, int width, int height) {
|
||||
NativeLibrary.setSurface(surfaceHolder.getSurface(), true);
|
||||
NativeLibrary.setSurfaceSize(width, height, true);
|
||||
startGame();
|
||||
if (!isGameRunning) {
|
||||
isGameRunning = true;
|
||||
NativeLibrary.initializerRenderer();
|
||||
NativeLibrary.initializeRendererSurface(true);
|
||||
NativeLibrary.startGame(gameTitleId);
|
||||
}else{
|
||||
NativeLibrary.recreateRenderSurface(true);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void surfaceDestroyed(@NonNull SurfaceHolder surfaceHolder) {
|
||||
|
||||
NativeLibrary.clearSurface(true);
|
||||
}
|
||||
}
|
||||
@@ -11,6 +11,8 @@ public class NativeLibrary {
|
||||
|
||||
public static native void setSurface(Surface surface, boolean isMainCanvas);
|
||||
|
||||
public static native void clearSurface(boolean isMainCanvas);
|
||||
|
||||
public static native void setSurfaceSize(int width, int height, boolean isMainCanvas);
|
||||
|
||||
public static native void initializerRenderer();
|
||||
@@ -19,6 +21,8 @@ public class NativeLibrary {
|
||||
|
||||
public static native void startGame(long titleId);
|
||||
|
||||
public static native void recreateRenderSurface(boolean isMainCanvas);
|
||||
|
||||
|
||||
public interface GameTitleLoadedCallback {
|
||||
void onGameTitleLoaded(long titleId, String title);
|
||||
|
||||
Reference in New Issue
Block a user