forked from suyu/suyu
282adfc70b
Changes the GraphicsContext to be managed by the GPU core. This eliminates the need for the frontends to fool around with tricky MakeCurrent/DoneCurrent calls that are dependent on the settings (such as async gpu option). This also refactors out the need to use QWidget::fromWindowContainer as that caused issues with focus and input handling. Now we use a regular QWidget and just access the native windowHandle() directly. Another change is removing the debug tool setting in FrameMailbox. Instead of trying to block the frontend until a new frame is ready, the core will now take over presentation and draw directly to the window if the renderer detects that its hooked by NSight or RenderDoc Lastly, since it was in the way, I removed ScopeAcquireWindowContext and replaced it with a simple subclass in GraphicsContext that achieves the same result
126 lines
3.6 KiB
C++
126 lines
3.6 KiB
C++
// Copyright 2014 Citra Emulator Project
|
|
// Licensed under GPLv2 or any later version
|
|
// Refer to the license.txt file included.
|
|
|
|
#pragma once
|
|
|
|
#include <vector>
|
|
#include <glad/glad.h>
|
|
#include "common/common_types.h"
|
|
#include "common/math_util.h"
|
|
#include "video_core/renderer_base.h"
|
|
#include "video_core/renderer_opengl/gl_resource_manager.h"
|
|
#include "video_core/renderer_opengl/gl_shader_manager.h"
|
|
#include "video_core/renderer_opengl/gl_state_tracker.h"
|
|
|
|
namespace Core {
|
|
class System;
|
|
}
|
|
|
|
namespace Core::Frontend {
|
|
class EmuWindow;
|
|
}
|
|
|
|
namespace Layout {
|
|
struct FramebufferLayout;
|
|
}
|
|
|
|
namespace OpenGL {
|
|
|
|
/// Structure used for storing information about the textures for the Switch screen
|
|
struct TextureInfo {
|
|
OGLTexture resource;
|
|
GLsizei width;
|
|
GLsizei height;
|
|
GLenum gl_format;
|
|
GLenum gl_type;
|
|
Tegra::FramebufferConfig::PixelFormat pixel_format;
|
|
};
|
|
|
|
/// Structure used for storing information about the display target for the Switch screen
|
|
struct ScreenInfo {
|
|
GLuint display_texture{};
|
|
bool display_srgb{};
|
|
const Common::Rectangle<float> display_texcoords{0.0f, 0.0f, 1.0f, 1.0f};
|
|
TextureInfo texture;
|
|
};
|
|
|
|
struct PresentationTexture {
|
|
u32 width = 0;
|
|
u32 height = 0;
|
|
OGLTexture texture;
|
|
};
|
|
|
|
class FrameMailbox;
|
|
|
|
class RendererOpenGL final : public VideoCore::RendererBase {
|
|
public:
|
|
explicit RendererOpenGL(Core::Frontend::EmuWindow& emu_window, Core::System& system,
|
|
Core::Frontend::GraphicsContext& context);
|
|
~RendererOpenGL() override;
|
|
|
|
bool Init() override;
|
|
void ShutDown() override;
|
|
void SwapBuffers(const Tegra::FramebufferConfig* framebuffer) override;
|
|
bool TryPresent(int timeout_ms) override;
|
|
|
|
private:
|
|
/// Initializes the OpenGL state and creates persistent objects.
|
|
void InitOpenGLObjects();
|
|
|
|
void AddTelemetryFields();
|
|
|
|
void CreateRasterizer();
|
|
|
|
void ConfigureFramebufferTexture(TextureInfo& texture,
|
|
const Tegra::FramebufferConfig& framebuffer);
|
|
|
|
/// Draws the emulated screens to the emulator window.
|
|
void DrawScreen(const Layout::FramebufferLayout& layout);
|
|
|
|
void RenderScreenshot();
|
|
|
|
/// Loads framebuffer from emulated memory into the active OpenGL texture.
|
|
void LoadFBToScreenInfo(const Tegra::FramebufferConfig& framebuffer);
|
|
|
|
/// Fills active OpenGL texture with the given RGB color.Since the color is solid, the texture
|
|
/// can be 1x1 but will stretch across whatever it's rendered on.
|
|
void LoadColorToActiveGLTexture(u8 color_r, u8 color_g, u8 color_b, u8 color_a,
|
|
const TextureInfo& texture);
|
|
|
|
void PrepareRendertarget(const Tegra::FramebufferConfig* framebuffer);
|
|
|
|
bool Present(int timeout_ms);
|
|
|
|
Core::Frontend::EmuWindow& emu_window;
|
|
Core::System& system;
|
|
Core::Frontend::GraphicsContext& context;
|
|
|
|
StateTracker state_tracker{system};
|
|
|
|
// OpenGL object IDs
|
|
OGLBuffer vertex_buffer;
|
|
OGLProgram vertex_program;
|
|
OGLProgram fragment_program;
|
|
OGLFramebuffer screenshot_framebuffer;
|
|
|
|
/// Display information for Switch screen
|
|
ScreenInfo screen_info;
|
|
|
|
/// Global dummy shader pipeline
|
|
GLShader::ProgramManager program_manager;
|
|
|
|
/// OpenGL framebuffer data
|
|
std::vector<u8> gl_framebuffer_data;
|
|
|
|
/// Used for transforming the framebuffer orientation
|
|
Tegra::FramebufferConfig::TransformFlags framebuffer_transform_flags;
|
|
Common::Rectangle<int> framebuffer_crop_rect;
|
|
|
|
/// Frame presentation mailbox
|
|
std::unique_ptr<FrameMailbox> frame_mailbox;
|
|
|
|
bool has_debug_tool = false;
|
|
};
|
|
|
|
} // namespace OpenGL
|