Avoid unnecessary sync
This commit is contained in:
parent
68e36268aa
commit
553c483bf4
@ -490,7 +490,7 @@ bool CentralVideoSettings::isARBPixelBufferObjectUsable() const
|
||||
|
||||
bool CentralVideoSettings::supportsThreadedTextureLoading() const
|
||||
{
|
||||
return isARBPixelBufferObjectUsable() && supportsAsyncInstanceUpload();
|
||||
return isARBPixelBufferObjectUsable() && isARBBufferStorageUsable();
|
||||
}
|
||||
|
||||
#endif // !SERVER_ONLY
|
||||
|
@ -24,11 +24,11 @@
|
||||
#include "utils/string_utils.hpp"
|
||||
#include "utils/log.hpp"
|
||||
|
||||
#include <algorithm>
|
||||
#include <thread>
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
STKTexManager::STKTexManager() : m_pbo(0), m_pbo_ptr(NULL), m_pbo_size(0),
|
||||
m_thread_size(0), m_tlt_added(0)
|
||||
STKTexManager::STKTexManager() : m_pbo(0), m_thread_size(0), m_tlt_added(0)
|
||||
{
|
||||
#ifndef SERVER_ONLY
|
||||
if (CVS->supportsThreadedTextureLoading())
|
||||
@ -40,18 +40,20 @@ STKTexManager::STKTexManager() : m_pbo(0), m_pbo_ptr(NULL), m_pbo_size(0),
|
||||
Log::info("STKTexManager", "%d thread(s) for texture loading,"
|
||||
" each capacity %d MB", m_thread_size,
|
||||
each_capacity / 1024 / 1024);
|
||||
GLuint pbo;
|
||||
uint8_t* pbo_ptr;
|
||||
glGenBuffers(1, &m_pbo);
|
||||
glBindBuffer(GL_PIXEL_UNPACK_BUFFER, m_pbo);
|
||||
glBufferStorage(GL_PIXEL_UNPACK_BUFFER, max_pbo_size, NULL,
|
||||
GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT |
|
||||
GL_MAP_COHERENT_BIT);
|
||||
uint8_t* pbo_ptr = (uint8_t*)glMapBufferRange(GL_PIXEL_UNPACK_BUFFER,
|
||||
0, max_pbo_size, GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT |
|
||||
GL_MAP_COHERENT_BIT);
|
||||
size_t offset = 0;
|
||||
for (unsigned i = 0; i < m_thread_size; i++)
|
||||
{
|
||||
glGenBuffers(1, &pbo);
|
||||
glBindBuffer(GL_PIXEL_UNPACK_BUFFER, pbo);
|
||||
glBufferStorage(GL_PIXEL_UNPACK_BUFFER, each_capacity, NULL,
|
||||
GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT);
|
||||
pbo_ptr = (uint8_t*)glMapBufferRange(GL_PIXEL_UNPACK_BUFFER, 0,
|
||||
each_capacity, GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT);
|
||||
m_all_tex_loaders.push_back(new ThreadedTexLoader(each_capacity,
|
||||
pbo, pbo_ptr));
|
||||
offset, pbo_ptr + offset));
|
||||
offset += each_capacity;
|
||||
}
|
||||
glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
|
||||
}
|
||||
@ -285,6 +287,7 @@ core::stringw STKTexManager::reloadTexture(const irr::core::stringw& name)
|
||||
// ----------------------------------------------------------------------------
|
||||
void STKTexManager::reset()
|
||||
{
|
||||
m_tlt_added = 0;
|
||||
#if !(defined(SERVER_ONLY) || defined(USE_GLES2))
|
||||
if (!CVS->isAZDOEnabled()) return;
|
||||
for (auto p : m_all_textures)
|
||||
@ -321,10 +324,36 @@ void STKTexManager::uploadBatch()
|
||||
{
|
||||
#if !(defined(SERVER_ONLY) || defined(USE_GLES2))
|
||||
if (!CVS->supportsThreadedTextureLoading()) return;
|
||||
bool uploaded = false;
|
||||
for (ThreadedTexLoader* ttl : m_all_tex_loaders)
|
||||
{
|
||||
if (ttl->finishedLoading())
|
||||
{
|
||||
if (!uploaded)
|
||||
{
|
||||
glBindBuffer(GL_PIXEL_UNPACK_BUFFER, m_pbo);
|
||||
uploaded = true;
|
||||
}
|
||||
ttl->handleCompletedTextures();
|
||||
}
|
||||
}
|
||||
if (uploaded)
|
||||
{
|
||||
GLsync sync = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0);
|
||||
GLenum reason = glClientWaitSync(sync, GL_SYNC_FLUSH_COMMANDS_BIT, 0);
|
||||
if (reason != GL_ALREADY_SIGNALED)
|
||||
{
|
||||
do
|
||||
{
|
||||
reason = glClientWaitSync(sync, GL_SYNC_FLUSH_COMMANDS_BIT,
|
||||
1000000);
|
||||
}
|
||||
while (reason == GL_TIMEOUT_EXPIRED);
|
||||
}
|
||||
glDeleteSync(sync);
|
||||
glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
|
||||
for (ThreadedTexLoader* ttl : m_all_tex_loaders)
|
||||
ttl->unlockCompletedTextures();
|
||||
}
|
||||
#endif
|
||||
} // uploadBatch
|
||||
|
@ -21,12 +21,9 @@
|
||||
#include "graphics/gl_headers.hpp"
|
||||
#include "utils/no_copy.hpp"
|
||||
#include "utils/singleton.hpp"
|
||||
#include "utils/synchronised.hpp"
|
||||
|
||||
#include "irrString.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <cassert>
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
#include <vector>
|
||||
@ -47,15 +44,11 @@ private:
|
||||
* This is used to specify details like: "while loading kart '...'" */
|
||||
std::string m_texture_error_message;
|
||||
|
||||
Synchronised<std::vector<STKTexture*> > m_threaded_loading_textures;
|
||||
|
||||
std::vector<ThreadedTexLoader*> m_all_tex_loaders;
|
||||
|
||||
GLuint m_pbo;
|
||||
|
||||
uint8_t* m_pbo_ptr;
|
||||
|
||||
unsigned m_pbo_size, m_thread_size, m_tlt_added;
|
||||
unsigned m_thread_size, m_tlt_added;
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
STKTexture* findTextureInFileSystem(const std::string& filename,
|
||||
@ -143,35 +136,6 @@ public:
|
||||
} // getTexture
|
||||
// ------------------------------------------------------------------------
|
||||
void uploadBatch();
|
||||
// ------------------------------------------------------------------------
|
||||
const unsigned getThreadedLoadingTextureNum() const
|
||||
{
|
||||
m_threaded_loading_textures.lock();
|
||||
const unsigned num = m_threaded_loading_textures.getData().size();
|
||||
m_threaded_loading_textures.unlock();
|
||||
return num;
|
||||
}
|
||||
// ------------------------------------------------------------------------
|
||||
STKTexture* getThreadedLoadingTexture(unsigned num) const
|
||||
{
|
||||
m_threaded_loading_textures.lock();
|
||||
assert(num < m_threaded_loading_textures.getData().size());
|
||||
STKTexture* t = m_threaded_loading_textures.getData()[num];
|
||||
m_threaded_loading_textures.unlock();
|
||||
return t;
|
||||
}
|
||||
// ------------------------------------------------------------------------
|
||||
const bool isThreadedLoaderEmpty() const
|
||||
{
|
||||
m_threaded_loading_textures.lock();
|
||||
const bool empty = m_threaded_loading_textures.getData().empty();
|
||||
m_threaded_loading_textures.unlock();
|
||||
return empty;
|
||||
}
|
||||
// ------------------------------------------------------------------------
|
||||
uint8_t* getPBOPtr() { return m_pbo_ptr; }
|
||||
// ------------------------------------------------------------------------
|
||||
unsigned getNumLoadingThread() const { return m_thread_size; }
|
||||
|
||||
}; // STKTexManager
|
||||
|
||||
|
@ -86,8 +86,7 @@ void ThreadedTexLoader::handleCompletedTextures()
|
||||
{
|
||||
#if !(defined(SERVER_ONLY) || defined(USE_GLES2))
|
||||
m_completed_textures.lock();
|
||||
glMemoryBarrier(GL_CLIENT_MAPPED_BUFFER_BARRIER_BIT);
|
||||
glBindBuffer(GL_PIXEL_UNPACK_BUFFER, m_pbo);
|
||||
m_locked = true;
|
||||
size_t offset = 0;
|
||||
for (STKTexture* stkt : m_completed_textures.getData())
|
||||
{
|
||||
@ -95,26 +94,11 @@ void ThreadedTexLoader::handleCompletedTextures()
|
||||
glBindTexture(GL_TEXTURE_2D, stkt->getOpenGLTextureName());
|
||||
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, stkt->getSize().Width,
|
||||
stkt->getSize().Height, stkt->isSingleChannel() ? GL_RED : GL_BGRA,
|
||||
GL_UNSIGNED_BYTE, (const void*)offset);
|
||||
GL_UNSIGNED_BYTE, (const void*)(m_pbo_offset + offset));
|
||||
if (stkt->hasMipMaps())
|
||||
glGenerateMipmap(GL_TEXTURE_2D);
|
||||
offset += stkt->getTextureSize();
|
||||
}
|
||||
glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
|
||||
m_completed_textures.getData().clear();
|
||||
GLsync sync = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0);
|
||||
GLenum reason = glClientWaitSync(sync, GL_SYNC_FLUSH_COMMANDS_BIT, 0);
|
||||
if (reason != GL_ALREADY_SIGNALED)
|
||||
{
|
||||
do
|
||||
{
|
||||
reason =
|
||||
glClientWaitSync(sync, GL_SYNC_FLUSH_COMMANDS_BIT, 1000000);
|
||||
}
|
||||
while (reason == GL_TIMEOUT_EXPIRED);
|
||||
}
|
||||
glDeleteSync(sync);
|
||||
m_finished_loading.setAtomic(false);
|
||||
m_completed_textures.unlock();
|
||||
#endif
|
||||
} // handleCompletedTextures
|
||||
|
@ -18,7 +18,6 @@
|
||||
#ifndef HEADER_THREADED_TEX_LOADER_HPP
|
||||
#define HEADER_THREADED_TEX_LOADER_HPP
|
||||
|
||||
#include "graphics/gl_headers.hpp"
|
||||
#include "utils/no_copy.hpp"
|
||||
#include "utils/synchronised.hpp"
|
||||
#include "utils/types.hpp"
|
||||
@ -33,7 +32,7 @@ class ThreadedTexLoader : public NoCopy
|
||||
private:
|
||||
const unsigned m_tex_capacity;
|
||||
|
||||
GLuint m_pbo;
|
||||
const size_t m_pbo_offset;
|
||||
|
||||
uint8_t* m_pbo_ptr;
|
||||
|
||||
@ -45,7 +44,7 @@ private:
|
||||
|
||||
Synchronised<bool> m_finished_loading;
|
||||
|
||||
bool m_destroy;
|
||||
bool m_destroy, m_locked;
|
||||
|
||||
Synchronised<std::vector<STKTexture*> >
|
||||
m_threaded_loading_textures, m_completed_textures;
|
||||
@ -54,10 +53,11 @@ public:
|
||||
// ------------------------------------------------------------------------
|
||||
static void* startRoutine(void *obj);
|
||||
// ------------------------------------------------------------------------
|
||||
ThreadedTexLoader(unsigned capacity, GLuint pbo, uint8_t* pbo_ptr)
|
||||
: m_tex_capacity(capacity), m_pbo(pbo), m_pbo_ptr(pbo_ptr),
|
||||
m_tex_size_loaded(0), m_waiting_timeout(0),
|
||||
m_finished_loading(false), m_destroy(false)
|
||||
ThreadedTexLoader(unsigned capacity, size_t offset, uint8_t* pbo_ptr)
|
||||
: m_tex_capacity(capacity), m_pbo_offset(offset),
|
||||
m_pbo_ptr(pbo_ptr), m_tex_size_loaded(0),
|
||||
m_waiting_timeout(0), m_finished_loading(false),
|
||||
m_destroy(false), m_locked(false)
|
||||
{
|
||||
pthread_cond_init(&m_cond_request, NULL);
|
||||
pthread_create(&m_thread, NULL, &startRoutine, this);
|
||||
@ -81,6 +81,14 @@ public:
|
||||
bool finishedLoading() const { return m_finished_loading.getAtomic(); }
|
||||
// ------------------------------------------------------------------------
|
||||
void handleCompletedTextures();
|
||||
// ------------------------------------------------------------------------
|
||||
void unlockCompletedTextures()
|
||||
{
|
||||
if (!m_locked) return;
|
||||
m_locked = false;
|
||||
m_finished_loading.setAtomic(false);
|
||||
m_completed_textures.unlock();
|
||||
}
|
||||
|
||||
}; // ThreadedTexLoader
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user