epic: refactor SDL2_Renderer usage to IRenderer and queued texture rendering

- Updated the testing guide to clarify the testing framework's organization and execution methods, improving user understanding.
- Refactored CMakeLists to include new platform-specific files, ensuring proper integration of the rendering backend.
- Modified main application files to utilize the new IRenderer interface, enhancing flexibility in rendering operations.
- Implemented deferred texture management in various components, allowing for more efficient graphics handling and improved performance.
- Introduced new methods for texture creation and updates, streamlining the rendering process across the application.
- Enhanced logging and error handling in the rendering pipeline to facilitate better debugging and diagnostics.
This commit is contained in:
scawful
2025-10-07 17:15:11 -04:00
parent 9e6f538520
commit 6c331f1fd0
101 changed files with 1401 additions and 2677 deletions

View File

@@ -1,5 +1,5 @@
#if __APPLE__
#include "app/core/platform/app_delegate.h"
#include "app/platform/app_delegate.h"
#endif
#include <SDL.h>
@@ -14,6 +14,8 @@
#include "absl/flags/parse.h"
#include "app/emu/snes.h"
#include "app/rom.h"
#include "app/gfx/backend/irenderer.h"
#include "app/gfx/backend/sdl2_renderer.h"
#include "util/sdl_deleter.h"
ABSL_FLAG(std::string, emu_rom, "", "Path to the ROM file to load.");
@@ -86,17 +88,13 @@ int main(int argc, char **argv) {
return EXIT_FAILURE;
}
std::unique_ptr<SDL_Renderer, SDL_Deleter> renderer_(
SDL_CreateRenderer(window_.get(), -1,
SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC),
SDL_Deleter());
if (!renderer_) {
printf("SDL_CreateRenderer failed: %s\n", SDL_GetError());
SDL_Quit();
return EXIT_FAILURE;
// Create and initialize the renderer
auto renderer = std::make_unique<yaze::gfx::SDL2Renderer>();
if (!renderer->Initialize(window_.get())) {
printf("Failed to initialize renderer\n");
SDL_Quit();
return EXIT_FAILURE;
}
SDL_SetRenderDrawBlendMode(renderer_.get(), SDL_BLENDMODE_BLEND);
SDL_SetRenderDrawColor(renderer_.get(), 0x00, 0x00, 0x00, 0xFF);
// Initialize audio system
constexpr int kAudioFrequency = 48000;
@@ -120,10 +118,7 @@ int main(int argc, char **argv) {
SDL_PauseAudioDevice(audio_device, 0);
// Create PPU texture for rendering
SDL_Texture* ppu_texture = SDL_CreateTexture(renderer_.get(),
SDL_PIXELFORMAT_RGBX8888,
SDL_TEXTUREACCESS_STREAMING,
512, 480);
void* ppu_texture = renderer->CreateTexture(512, 480);
if (!ppu_texture) {
printf("SDL_CreateTexture failed: %s\n", SDL_GetError());
SDL_CloseAudioDevice(audio_device);
@@ -271,20 +266,17 @@ int main(int argc, char **argv) {
// Render PPU output to texture
void *ppu_pixels = nullptr;
int ppu_pitch = 0;
if (SDL_LockTexture(ppu_texture, nullptr, &ppu_pixels, &ppu_pitch) != 0) {
printf("Failed to lock texture: %s\n", SDL_GetError());
running = false;
break;
if (renderer->LockTexture(ppu_texture, nullptr, &ppu_pixels, &ppu_pitch)) {
snes_.SetPixels(static_cast<uint8_t*>(ppu_pixels));
renderer->UnlockTexture(ppu_texture);
}
snes_.SetPixels(static_cast<uint8_t*>(ppu_pixels));
SDL_UnlockTexture(ppu_texture);
}
}
// Present rendered frame
SDL_RenderClear(renderer_.get());
SDL_RenderCopy(renderer_.get(), ppu_texture, nullptr, nullptr);
SDL_RenderPresent(renderer_.get());
renderer->Clear();
renderer->RenderCopy(ppu_texture, nullptr, nullptr);
renderer->Present();
}
// === Cleanup SDL resources (in reverse order of initialization) ===
@@ -292,7 +284,7 @@ int main(int argc, char **argv) {
// Clean up texture
if (ppu_texture) {
SDL_DestroyTexture(ppu_texture);
renderer->DestroyTexture(ppu_texture);
ppu_texture = nullptr;
}
@@ -302,7 +294,7 @@ int main(int argc, char **argv) {
SDL_CloseAudioDevice(audio_device);
// Clean up renderer and window (done automatically by unique_ptr destructors)
renderer_.reset();
renderer->Shutdown();
window_.reset();
// Quit SDL subsystems

View File

@@ -5,7 +5,7 @@ if (NOT YAZE_MINIMAL_BUILD AND APPLE)
MACOSX_BUNDLE
app/main.cc
app/rom.cc
app/core/platform/app_delegate.mm
app/platform/app_delegate.mm
${YAZE_APP_EMU_SRC}
${YAZE_APP_CORE_SRC}
${YAZE_APP_EDITOR_SRC}

View File

@@ -49,21 +49,24 @@ using ImGui::Separator;
using ImGui::TableNextColumn;
using ImGui::Text;
void Emulator::Initialize(gfx::IRenderer* renderer, const std::vector<uint8_t>& rom_data) {
renderer_ = renderer;
rom_data_ = rom_data;
snes_.Init(rom_data_);
initialized_ = true;
}
void Emulator::Run(Rom* rom) {
static bool loaded = false;
if (!snes_.running() && rom->is_loaded()) {
// Use ARGB8888 format to match PPU output (XBGR layout with format=1)
// Add better error handling and texture optimization
ppu_texture_ = SDL_CreateTexture(core::Renderer::Get().renderer(),
SDL_PIXELFORMAT_ARGB8888,
SDL_TEXTUREACCESS_STREAMING, 512, 480);
ppu_texture_ = renderer_->CreateTexture(512, 480);
if (ppu_texture_ == NULL) {
printf("Failed to create texture: %s\n", SDL_GetError());
return;
}
// Optimize texture for better performance
SDL_SetTextureBlendMode(ppu_texture_, SDL_BLENDMODE_NONE);
// renderer_->SetTextureBlendMode(ppu_texture_, SDL_BLENDMODE_NONE);
rom_data_ = rom->vector();
snes_.Init(rom_data_);
@@ -149,10 +152,9 @@ void Emulator::Run(Rom* rom) {
// Update PPU texture only on rendered frames
void* ppu_pixels_;
int ppu_pitch_;
if (SDL_LockTexture(ppu_texture_, NULL, &ppu_pixels_, &ppu_pitch_) ==
0) {
if (renderer_->LockTexture(ppu_texture_, NULL, &ppu_pixels_, &ppu_pitch_)) {
snes_.SetPixels(static_cast<uint8_t*>(ppu_pixels_));
SDL_UnlockTexture(ppu_texture_);
renderer_->UnlockTexture(ppu_texture_);
}
}
}

View File

@@ -6,9 +6,11 @@
#include "app/emu/snes.h"
#include "app/rom.h"
#include "imgui/imgui.h"
namespace yaze {
namespace gfx {
class IRenderer;
} // namespace gfx
/**
* @namespace yaze::emu
@@ -39,6 +41,7 @@ class Emulator {
public:
Emulator() = default;
~Emulator() = default;
void Initialize(gfx::IRenderer* renderer, const std::vector<uint8_t>& rom_data);
void Run(Rom* rom);
auto snes() -> Snes& { return snes_; }
@@ -129,7 +132,9 @@ class Emulator {
SDL_AudioDeviceID audio_device_;
Snes snes_;
SDL_Texture* ppu_texture_;
bool initialized_ = false;
gfx::IRenderer* renderer_ = nullptr;
void* ppu_texture_ = nullptr;
std::vector<uint8_t> rom_data_;