From d65f079cc130827112e0e74f787447d01a204ff8 Mon Sep 17 00:00:00 2001
From: bunnei <bunneidev@gmail.com>
Date: Wed, 22 Aug 2018 18:46:05 -0400
Subject: [PATCH] gl_rasterizer_cache: Blit when possible on RecreateSurface.

---
 .../renderer_opengl/gl_rasterizer_cache.cpp     | 17 ++++++++++++-----
 1 file changed, 12 insertions(+), 5 deletions(-)

diff --git a/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp b/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp
index 10b2d8f3c4..83d8d3d94c 100644
--- a/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp
+++ b/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp
@@ -780,7 +780,10 @@ Surface RasterizerCacheOpenGL::GetSurface(const SurfaceParams& params, bool pres
         } else if (preserve_contents) {
             // If surface parameters changed and we care about keeping the previous data, recreate
             // the surface from the old one
-            return RecreateSurface(surface, params);
+            UnregisterSurface(surface);
+            Surface new_surface{RecreateSurface(surface, params)};
+            RegisterSurface(new_surface);
+            return new_surface;
         } else {
             // Delete the old surface before creating a new one to prevent collisions.
             UnregisterSurface(surface);
@@ -813,6 +816,14 @@ Surface RasterizerCacheOpenGL::RecreateSurface(const Surface& surface,
     // Create a new surface with the new parameters, and blit the previous surface to it
     Surface new_surface{std::make_shared<CachedSurface>(new_params)};
 
+    // If format is unchanged, we can do a faster blit without reinterpreting pixel data
+    if (params.pixel_format == new_params.pixel_format) {
+        BlitTextures(surface->Texture().handle, params.GetRect(), new_surface->Texture().handle,
+                     new_surface->GetSurfaceParams().GetRect(), params.type,
+                     read_framebuffer.handle, draw_framebuffer.handle);
+        return new_surface;
+    }
+
     auto source_format = GetFormatTuple(params.pixel_format, params.component_type);
     auto dest_format = GetFormatTuple(new_params.pixel_format, new_params.component_type);
 
@@ -872,10 +883,6 @@ Surface RasterizerCacheOpenGL::RecreateSurface(const Surface& surface,
 
     pbo.Release();
 
-    // Update cache accordingly
-    UnregisterSurface(surface);
-    RegisterSurface(new_surface);
-
     return new_surface;
 }