mirror of
https://github.com/hrydgard/ppsspp.git
synced 2026-10-15 07:20:31 +02:00
System_AudioPushSamples converts straight into the output buffer: the block loop never advanced the source pointer and copied numSamples*2 int16s out of a 2048-sample stack buffer, a stack OOB read for any push over 1024 frames. Realloc failure drops samples instead of crashing and log_cb is NULL-checked. retro_serialize refuses to write a state larger than the frontend's buffer, retro_get_memory_data/size return nothing until PSP memory is mapped, deferred unserialize no longer leaks the previous buffer, and the cheat entry points stop leaking a CWCheatEngine per call. The emu thread acknowledges a pause with a CAS so it cannot clobber a concurrent quit request. EmuThreadStop stops and joins from any live state, so unloading while paused no longer leaves a thread running over freed state. EmuThreadPause pumps queued frames until the thread parks, via a new non-blocking GLRenderManager::HasQueuedThreadWork() check, instead of draining one frame, which deadlocked when the thread was blocked on a readback sync in the next frame. retro_run resumes a paused thread and pauses it before check_variables() rewrites g_Config, retro_reset stops it before PSP_Shutdown(), and the sleep_ms(4) after resume is gone.
44 lines
1.3 KiB
C++
44 lines
1.3 KiB
C++
#pragma once
|
|
|
|
#include "Common/GPU/OpenGL/GLCommon.h"
|
|
#include "libretro/LibretroGraphicsContext.h"
|
|
#include "Common/GPU/OpenGL/GLRenderManager.h"
|
|
|
|
class LibretroGLContext : public LibretroHWRenderContext {
|
|
public:
|
|
LibretroGLContext()
|
|
#ifdef USING_GLES2
|
|
: LibretroHWRenderContext(RETRO_HW_CONTEXT_OPENGLES2)
|
|
#else
|
|
: LibretroHWRenderContext(RETRO_HW_CONTEXT_OPENGL)
|
|
#endif
|
|
{
|
|
hw_render_.bottom_left_origin = true;
|
|
}
|
|
|
|
bool NeedsSeparateEmuThread() const override { return true; }
|
|
|
|
bool InitAPI(void *wnd, std::string *deviceName, std::string *error_message) override;
|
|
void CreateDrawContext() override;
|
|
void DestroyDrawContext() override;
|
|
void SetRenderTarget() override {
|
|
extern GLuint g_defaultFBO;
|
|
g_defaultFBO = hw_render_.get_current_framebuffer();
|
|
}
|
|
|
|
void ThreadStart() override { renderManager_->ThreadStart(draw_); }
|
|
bool ThreadFrame() override { return renderManager_->ThreadFrame(); }
|
|
bool ThreadFramePending() override { return renderManager_->HasQueuedThreadWork(); }
|
|
void ThreadEnd() override { renderManager_->ThreadEnd(); }
|
|
|
|
GPUCore GetGPUCore() override { return GPUCORE_GLES; }
|
|
const char *Ident() override { return "OpenGL"; }
|
|
|
|
// Call from emu thread
|
|
void NotifyEmuThreadExit() override;
|
|
|
|
private:
|
|
GLRenderManager *renderManager_ = nullptr;
|
|
bool glewInitDone = false;
|
|
};
|