mirror of
https://github.com/hrydgard/ppsspp.git
synced 2024-12-11 23:53:55 +00:00
GLES: Defrag using deleter off render thread.
Moving it to the render thread was a bit more complex because of localMemory. Fixes #10859.
This commit is contained in:
parent
330bb8158c
commit
32eb483932
@ -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?
|
||||
|
@ -288,7 +288,7 @@ private:
|
||||
bool AddBuffer();
|
||||
void NextBuffer(size_t minSize);
|
||||
void Defragment();
|
||||
void Destroy();
|
||||
void Destroy(bool onRenderThread);
|
||||
|
||||
GLRenderManager *render_;
|
||||
std::vector<BufInfo> buffers_;
|
||||
|
Loading…
Reference in New Issue
Block a user