diff --git a/src/core/fullscreenui_widgets.cpp b/src/core/fullscreenui_widgets.cpp index 3fe950f9b..a2a3b4c36 100644 --- a/src/core/fullscreenui_widgets.cpp +++ b/src/core/fullscreenui_widgets.cpp @@ -852,7 +852,7 @@ FullscreenUI::TransitionState FullscreenUI::GetTransitionState() return s_state.transition_state; } -GPUTexture* FullscreenUI::GetTransitionRenderTexture(GPUSwapChain* swap_chain) +GPUTexture* FullscreenUI::GetTransitionRenderTexture(GPUSwapChain* const swap_chain) { if (!g_gpu_device->ResizeTexture(&s_state.transition_current_texture, swap_chain->GetWidth(), swap_chain->GetHeight(), GPUTexture::Type::RenderTarget, swap_chain->GetFormat(), GPUTexture::Flags::None, @@ -961,24 +961,23 @@ bool FullscreenUI::CompilePipelines(Error* error) return true; } -void FullscreenUI::RenderTransitionBlend(GPUSwapChain* swap_chain) +void FullscreenUI::RenderTransitionBlend(GPUSwapChain* swap_chain, GPUTexture* const transition_texture) { - GPUTexture* const curr = s_state.transition_current_texture.get(); - DebugAssert(curr); - if (s_state.transition_state == TransitionState::Starting) { // copy current frame - if (!g_gpu_device->ResizeTexture(&s_state.transition_prev_texture, curr->GetWidth(), curr->GetHeight(), - GPUTexture::Type::RenderTarget, curr->GetFormat(), GPUTexture::Flags::None, false)) + if (!g_gpu_device->ResizeTexture(&s_state.transition_prev_texture, transition_texture->GetWidth(), + transition_texture->GetHeight(), GPUTexture::Type::RenderTarget, + transition_texture->GetFormat(), GPUTexture::Flags::None, false)) { - ERROR_LOG("Failed to allocate {}x{} texture for transition, cancelling.", curr->GetWidth(), curr->GetHeight()); + ERROR_LOG("Failed to allocate {}x{} texture for transition, cancelling.", transition_texture->GetWidth(), + transition_texture->GetHeight()); s_state.transition_state = TransitionState::Inactive; return; } - g_gpu_device->CopyTextureRegion(s_state.transition_prev_texture.get(), 0, 0, 0, 0, curr, 0, 0, 0, 0, - curr->GetWidth(), curr->GetHeight()); + g_gpu_device->CopyTextureRegion(s_state.transition_prev_texture.get(), 0, 0, 0, 0, transition_texture, 0, 0, 0, 0, + transition_texture->GetWidth(), transition_texture->GetHeight()); s_state.transition_state = TransitionState::Active; } @@ -987,7 +986,7 @@ void FullscreenUI::RenderTransitionBlend(GPUSwapChain* swap_chain) const float uniforms[2] = {1.0f - transition_alpha, transition_alpha}; g_gpu_device->SetPipeline(s_state.transition_blend_pipeline.get()); g_gpu_device->SetViewportAndScissor(0, 0, swap_chain->GetPostRotatedWidth(), swap_chain->GetPostRotatedHeight()); - g_gpu_device->SetTextureSampler(0, curr, g_gpu_device->GetNearestSampler()); + g_gpu_device->SetTextureSampler(0, transition_texture, g_gpu_device->GetNearestSampler()); g_gpu_device->SetTextureSampler(1, s_state.transition_prev_texture.get(), g_gpu_device->GetNearestSampler()); const GSVector2i size = swap_chain->GetSizeVec(); diff --git a/src/core/fullscreenui_widgets.h b/src/core/fullscreenui_widgets.h index 006e3ed3b..35d423387 100644 --- a/src/core/fullscreenui_widgets.h +++ b/src/core/fullscreenui_widgets.h @@ -276,8 +276,8 @@ void BeginTransition(float time, TransitionStartCallback func); void CancelTransition(); bool IsTransitionActive(); TransitionState GetTransitionState(); -GPUTexture* GetTransitionRenderTexture(GPUSwapChain* swap_chain); -void RenderTransitionBlend(GPUSwapChain* swap_chain); +GPUTexture* GetTransitionRenderTexture(GPUSwapChain* const swap_chain); +void RenderTransitionBlend(GPUSwapChain* const swap_chain, GPUTexture* const transition_texture); void UpdateTransitionState(); /// Screen blurring. diff --git a/src/core/video_presenter.cpp b/src/core/video_presenter.cpp index 56bc2d547..85fb1af3a 100644 --- a/src/core/video_presenter.cpp +++ b/src/core/video_presenter.cpp @@ -1517,24 +1517,31 @@ bool VideoPresenter::PresentFrame(GPUBackend* backend, u64 present_time) FullscreenUI::RenderBlur(blur_target); } - GPUTexture* const transition_target = FullscreenUI::IsTransitionActive() ? - FullscreenUI::GetTransitionRenderTexture(g_gpu_device->GetMainSwapChain()) : - nullptr; GPUPresentResult pres; - if (transition_target) + if (GPUTexture* transition_target = FullscreenUI::IsTransitionActive() ? + FullscreenUI::GetTransitionRenderTexture(g_gpu_device->GetMainSwapChain()) : + nullptr) { if (blur_target) - DrawDisplayCopy(blur_target, transition_target, swap_chain); - else if (backend) - RenderDisplay(transition_target, transition_target->GetSizeVec(), true, true); + { + // Avoid a copy by drawing on top of the blur source, since it's already been consumed. + GL_INS("Using blur target as transition target"); + transition_target = blur_target; + } else - g_gpu_device->ClearRenderTarget(transition_target, GPUDevice::DEFAULT_CLEAR_COLOR); + { + // Display still needs rendering. + if (backend) + RenderDisplay(transition_target, transition_target->GetSizeVec(), true, true); + else + g_gpu_device->ClearRenderTarget(transition_target, GPUDevice::DEFAULT_CLEAR_COLOR); + } g_gpu_device->SetRenderTarget(transition_target); ImGuiManager::RenderDrawLists(transition_target); if ((pres = g_gpu_device->BeginPresent(swap_chain)) == GPUPresentResult::OK) - FullscreenUI::RenderTransitionBlend(swap_chain); + FullscreenUI::RenderTransitionBlend(swap_chain, transition_target); } else {