diff --git a/UI/EmuScreen.cpp b/UI/EmuScreen.cpp index d9ba778f1b..3d4c791cd2 100644 --- a/UI/EmuScreen.cpp +++ b/UI/EmuScreen.cpp @@ -157,6 +157,9 @@ bool EmuScreen::bootAllowStorage(const std::string &filename) { case PERMISSION_STATUS_GRANTED: return true; } + + _assert_(false); + return false; } void EmuScreen::bootGame(const std::string &filename) { diff --git a/android/jni/app-android.cpp b/android/jni/app-android.cpp index 9ebb82dc0b..602bfd0025 100644 --- a/android/jni/app-android.cpp +++ b/android/jni/app-android.cpp @@ -551,7 +551,6 @@ extern "C" void Java_org_ppsspp_ppsspp_NativeRenderer_displayInit(JNIEnv * env, if (renderer_inited) { // Would be really nice if we could get something on the GL thread immediately when shutting down... ILOG("NativeApp.displayInit() restoring"); - graphicsContext->ThreadEnd(); if (useCPUThread) { EmuThreadStop(); while (graphicsContext->ThreadFrame()) { @@ -561,6 +560,7 @@ extern "C" void Java_org_ppsspp_ppsspp_NativeRenderer_displayInit(JNIEnv * env, } else { NativeShutdownGraphics(); } + graphicsContext->ThreadEnd(); graphicsContext->ShutdownFromRenderThread(); ILOG("Shut down both threads. Now let's bring it up again!"); diff --git a/ext/native/thin3d/GLRenderManager.cpp b/ext/native/thin3d/GLRenderManager.cpp index 94b5e7b664..32936bd4be 100644 --- a/ext/native/thin3d/GLRenderManager.cpp +++ b/ext/native/thin3d/GLRenderManager.cpp @@ -13,6 +13,11 @@ #define VLOG(...) #endif +static std::thread::id renderThreadId; +static bool OnRenderThread() { + return std::this_thread::get_id() == renderThreadId; +} + // Runs on the GPU thread. void GLDeleter::Perform(GLRenderManager *renderManager) { for (auto pushBuffer : pushBuffers) { @@ -65,6 +70,7 @@ GLRenderManager::~GLRenderManager() { void GLRenderManager::ThreadStart() { queueRunner_.CreateDeviceObjects(); threadFrame_ = threadInitFrame_; + renderThreadId = std::this_thread::get_id(); bool mapBuffers = (gl_extensions.bugs & BUG_ANY_MAP_BUFFER_RANGE_SLOW) == 0; bool hasBufferStorage = gl_extensions.ARB_buffer_storage || gl_extensions.EXT_buffer_storage; @@ -574,7 +580,7 @@ GLPushBuffer::GLPushBuffer(GLRenderManager *render, GLuint target, size_t size) } GLPushBuffer::~GLPushBuffer() { - Destroy(); + Destroy(true); } void GLPushBuffer::Map() { @@ -606,6 +612,8 @@ void GLPushBuffer::Unmap() { void GLPushBuffer::Flush() { // Must be called from the render thread. + _dbg_assert_(G3D, OnRenderThread()); + buffers_[buf_].flushOffset = offset_; if (!buffers_[buf_].deviceMemory && writePtr_) { auto &info = buffers_[buf_]; @@ -647,12 +655,18 @@ bool GLPushBuffer::AddBuffer() { } // Executed on the render thread! -void GLPushBuffer::Destroy() { +void GLPushBuffer::Destroy(bool onRenderThread) { for (BufInfo &info : buffers_) { // This will automatically unmap device memory, if needed. - // NOTE: We immediately delete the buffer, don't go through the deleter, since we're on the render thread. - // render_->DeleteBuffer(info.buffer); - delete info.buffer; + // NOTE: We immediately delete the buffer, don't go through the deleter, if we're on the render thread. + if (onRenderThread) { + _dbg_assert_(G3D, OnRenderThread()); + delete info.buffer; + } else { + _dbg_assert_(G3D, !OnRenderThread()); + render_->DeleteBuffer(info.buffer); + } + FreeAlignedMemory(info.localMemory); } buffers_.clear(); @@ -684,6 +698,8 @@ void GLPushBuffer::NextBuffer(size_t minSize) { } void GLPushBuffer::Defragment() { + _dbg_assert_(G3D, std::this_thread::get_id() != renderThreadId); + if (buffers_.size() <= 1) { // Let's take this chance to jetison localMemory we don't need. for (auto &info : buffers_) { @@ -698,7 +714,7 @@ void GLPushBuffer::Defragment() { // Okay, we have more than one. Destroy them all and start over with a larger one. size_t newSize = size_ * buffers_.size(); - Destroy(); + Destroy(false); size_ = newSize; bool res = AddBuffer(); @@ -714,6 +730,8 @@ size_t GLPushBuffer::GetTotalSize() const { } void GLPushBuffer::MapDevice(GLBufferStrategy strategy) { + _dbg_assert_(G3D, OnRenderThread()); + strategy_ = strategy; if (strategy_ == GLBufferStrategy::SUBDATA) { return; @@ -746,6 +764,8 @@ void GLPushBuffer::MapDevice(GLBufferStrategy strategy) { } void GLPushBuffer::UnmapDevice() { + _dbg_assert_(G3D, OnRenderThread()); + for (auto &info : buffers_) { if (info.deviceMemory) { // TODO: Technically this can return false? diff --git a/ext/native/thin3d/GLRenderManager.h b/ext/native/thin3d/GLRenderManager.h index b54697b432..d241812441 100644 --- a/ext/native/thin3d/GLRenderManager.h +++ b/ext/native/thin3d/GLRenderManager.h @@ -288,7 +288,7 @@ private: bool AddBuffer(); void NextBuffer(size_t minSize); void Defragment(); - void Destroy(); + void Destroy(bool onRenderThread); GLRenderManager *render_; std::vector buffers_;