renderer: Render previous frame when no new one is available.

master
bunnei 2018-01-14 23:51:54 +07:00
parent 2adde6ae8b
commit ebd613c2cc
4 changed files with 22 additions and 17 deletions

@ -12,6 +12,8 @@
#include "core/hle/service/nvdrv/nvdrv_a.h" #include "core/hle/service/nvdrv/nvdrv_a.h"
#include "core/hle/service/vi/vi.h" #include "core/hle/service/vi/vi.h"
#include "core/hle/service/vi/vi_m.h" #include "core/hle/service/vi/vi_m.h"
#include "video_core/renderer_base.h"
#include "video_core/video_core.h"
namespace Service { namespace Service {
namespace VI { namespace VI {
@ -743,7 +745,8 @@ void NVFlinger::Compose() {
auto buffer = buffer_queue->AcquireBuffer(); auto buffer = buffer_queue->AcquireBuffer();
if (buffer == boost::none) { if (buffer == boost::none) {
// There was no queued buffer to draw. // There was no queued buffer to draw, render previous frame
VideoCore::g_renderer->SwapBuffers({});
continue; continue;
} }

@ -5,6 +5,7 @@
#pragma once #pragma once
#include <memory> #include <memory>
#include <boost/optional.hpp>
#include "common/assert.h" #include "common/assert.h"
#include "common/common_types.h" #include "common/common_types.h"
@ -47,7 +48,7 @@ public:
virtual ~RendererBase() {} virtual ~RendererBase() {}
/// Swap buffers (render frame) /// Swap buffers (render frame)
virtual void SwapBuffers(const FramebufferInfo& framebuffer_info) = 0; virtual void SwapBuffers(boost::optional<const FramebufferInfo&> framebuffer_info) = 0;
/** /**
* Set the emulator window to use for renderer * Set the emulator window to use for renderer

@ -4,8 +4,8 @@
#include <algorithm> #include <algorithm>
#include <cstddef> #include <cstddef>
#include <cstring>
#include <cstdlib> #include <cstdlib>
#include <cstring>
#include <memory> #include <memory>
#include <glad/glad.h> #include <glad/glad.h>
#include "common/assert.h" #include "common/assert.h"
@ -98,20 +98,23 @@ RendererOpenGL::RendererOpenGL() = default;
RendererOpenGL::~RendererOpenGL() = default; RendererOpenGL::~RendererOpenGL() = default;
/// Swap buffers (render frame) /// Swap buffers (render frame)
void RendererOpenGL::SwapBuffers(const FramebufferInfo& framebuffer_info) { void RendererOpenGL::SwapBuffers(boost::optional<const FramebufferInfo&> framebuffer_info) {
// Maintain the rasterizer's state as a priority // Maintain the rasterizer's state as a priority
OpenGLState prev_state = OpenGLState::GetCurState(); OpenGLState prev_state = OpenGLState::GetCurState();
state.Apply(); state.Apply();
if (screen_info.texture.width != (GLsizei)framebuffer_info.width || if (framebuffer_info != boost::none) {
screen_info.texture.height != (GLsizei)framebuffer_info.height || // If framebuffer_info is provided, reload it from memory to a texture
screen_info.texture.pixel_format != framebuffer_info.pixel_format) { if (screen_info.texture.width != (GLsizei)framebuffer_info->width ||
screen_info.texture.height != (GLsizei)framebuffer_info->height ||
screen_info.texture.pixel_format != framebuffer_info->pixel_format) {
// Reallocate texture if the framebuffer size has changed. // Reallocate texture if the framebuffer size has changed.
// This is expected to not happen very often and hence should not be a // This is expected to not happen very often and hence should not be a
// performance problem. // performance problem.
ConfigureFramebufferTexture(screen_info.texture, framebuffer_info); ConfigureFramebufferTexture(screen_info.texture, *framebuffer_info);
}
LoadFBToScreenInfo(*framebuffer_info, screen_info);
} }
LoadFBToScreenInfo(framebuffer_info, screen_info);
DrawScreens(); DrawScreens();

@ -37,7 +37,7 @@ public:
~RendererOpenGL() override; ~RendererOpenGL() override;
/// Swap buffers (render frame) /// Swap buffers (render frame)
void SwapBuffers(const FramebufferInfo& framebuffer_info) override; void SwapBuffers(boost::optional<const FramebufferInfo&> framebuffer_info) override;
/** /**
* Set the emulator window to use for renderer * Set the emulator window to use for renderer
@ -53,15 +53,13 @@ public:
private: private:
void InitOpenGLObjects(); void InitOpenGLObjects();
void ConfigureFramebufferTexture(TextureInfo& texture, void ConfigureFramebufferTexture(TextureInfo& texture, const FramebufferInfo& framebuffer_info);
const FramebufferInfo& framebuffer_info);
void DrawScreens(); void DrawScreens();
void DrawSingleScreen(const ScreenInfo& screen_info, float x, float y, float w, float h); void DrawSingleScreen(const ScreenInfo& screen_info, float x, float y, float w, float h);
void UpdateFramerate(); void UpdateFramerate();
// Loads framebuffer from emulated memory into the display information structure // Loads framebuffer from emulated memory into the display information structure
void LoadFBToScreenInfo(const FramebufferInfo& framebuffer_info, void LoadFBToScreenInfo(const FramebufferInfo& framebuffer_info, ScreenInfo& screen_info);
ScreenInfo& screen_info);
// Fills active OpenGL texture with the given RGB color. // Fills active OpenGL texture with the given RGB color.
void LoadColorToActiveGLTexture(u8 color_r, u8 color_g, u8 color_b, const TextureInfo& texture); void LoadColorToActiveGLTexture(u8 color_r, u8 color_g, u8 color_b, const TextureInfo& texture);