From d455b61d5ed6c5baf027b8a788a6a67e798aa6ac Mon Sep 17 00:00:00 2001 From: Connor McLaughlin Date: Fri, 5 Feb 2021 02:16:45 +1000 Subject: [PATCH] OpenGLHostDisplay: Fix interlaced software renderer output --- src/frontend-common/opengl_host_display.cpp | 26 ++++++++++++++++++++- src/frontend-common/opengl_host_display.h | 1 + 2 files changed, 26 insertions(+), 1 deletion(-) diff --git a/src/frontend-common/opengl_host_display.cpp b/src/frontend-common/opengl_host_display.cpp index eab67f865..be4a7c0a2 100644 --- a/src/frontend-common/opengl_host_display.cpp +++ b/src/frontend-common/opengl_host_display.cpp @@ -2,6 +2,7 @@ #include "common/align.h" #include "common/assert.h" #include "common/log.h" +#include "common/string_util.h" #include "imgui.h" #include "imgui_impl_opengl3.h" #include "postprocessing_shadergen.h" @@ -238,8 +239,31 @@ bool OpenGLHostDisplay::SetDisplayPixels(HostDisplayPixelFormat format, u32 widt } const auto [gl_internal_format, gl_format, gl_type] = s_display_pixel_format_mapping[static_cast(format)]; + const u32 pixel_size = GetDisplayPixelFormatSize(format); + const bool is_packed_tightly = (pitch == (pixel_size * width)); - glTexImage2D(GL_TEXTURE_2D, 0, gl_internal_format, width, height, 0, gl_format, gl_type, buffer); + // If we have GLES3, we can set row_length. + if (!m_use_gles2_draw_path || is_packed_tightly) + { + if (!is_packed_tightly) + glPixelStorei(GL_UNPACK_ROW_LENGTH, pitch / pixel_size); + + glTexImage2D(GL_TEXTURE_2D, 0, gl_internal_format, width, height, 0, gl_format, gl_type, buffer); + + if (!is_packed_tightly) + glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); + } + else + { + // Otherwise, we need to repack the image. + const u32 packed_pitch = width * pixel_size; + const u32 repack_size = packed_pitch * height; + if (m_gles2_pixels_repack_buffer.size() < repack_size) + m_gles2_pixels_repack_buffer.resize(repack_size); + StringUtil::StrideMemCpy(m_gles2_pixels_repack_buffer.data(), packed_pitch, buffer, pitch, packed_pitch, height); + glTexImage2D(GL_TEXTURE_2D, 0, gl_internal_format, width, height, 0, gl_format, gl_type, + m_gles2_pixels_repack_buffer.data()); + } glBindTexture(GL_TEXTURE_2D, 0); diff --git a/src/frontend-common/opengl_host_display.h b/src/frontend-common/opengl_host_display.h index 34b9b6c07..17a9cd3a2 100644 --- a/src/frontend-common/opengl_host_display.h +++ b/src/frontend-common/opengl_host_display.h @@ -117,6 +117,7 @@ protected: std::vector m_post_processing_stages; bool m_use_gles2_draw_path = false; + std::vector m_gles2_pixels_repack_buffer; }; } // namespace FrontendCommon \ No newline at end of file