Asynchronous streaming and memory management improvements in progress.

--HG--
branch : async_streaming
This commit is contained in:
2013-11-13 23:52:17 -08:00
parent 05626214d4
commit cf732a6721
9 changed files with 82 additions and 16 deletions

View File

@@ -27,6 +27,7 @@ const char *KRContext::extension_names[KRENGINE_NUM_EXTENSIONS] = {
}; };
KRContext::KRContext() { KRContext::KRContext() {
m_streamingEnabled = false;
mach_timebase_info(&m_timebase_info); mach_timebase_info(&m_timebase_info);
m_bDetectedExtensions = false; m_bDetectedExtensions = false;
@@ -43,7 +44,7 @@ KRContext::KRContext() {
m_pAnimationCurveManager = new KRAnimationCurveManager(*this); m_pAnimationCurveManager = new KRAnimationCurveManager(*this);
m_pSoundManager = new KRAudioManager(*this); m_pSoundManager = new KRAudioManager(*this);
m_pUnknownManager = new KRUnknownManager(*this); m_pUnknownManager = new KRUnknownManager(*this);
m_streamingEnabled = true;
} }
KRContext::~KRContext() { KRContext::~KRContext() {
@@ -271,3 +272,12 @@ long KRContext::getAbsoluteTimeMilliseconds()
return (long)(mach_absolute_time() / 1000 * m_timebase_info.numer / m_timebase_info.denom); // Division done first to avoid potential overflow return (long)(mach_absolute_time() / 1000 * m_timebase_info.numer / m_timebase_info.denom); // Division done first to avoid potential overflow
} }
bool KRContext::getStreamingEnabled()
{
return m_streamingEnabled;
}
void KRContext::setStreamingEnabled(bool enable)
{
m_streamingEnabled = enable;
}

View File

@@ -73,6 +73,8 @@ public:
long getAbsoluteTimeMilliseconds(); long getAbsoluteTimeMilliseconds();
std::vector<KRResource *> getResources(); std::vector<KRResource *> getResources();
bool getStreamingEnabled();
void setStreamingEnabled(bool enable);
private: private:
KRBundleManager *m_pBundleManager; KRBundleManager *m_pBundleManager;
@@ -93,6 +95,8 @@ private:
float m_absolute_time; float m_absolute_time;
mach_timebase_info_data_t m_timebase_info; mach_timebase_info_data_t m_timebase_info;
std::atomic<bool> m_streamingEnabled;
}; };
#endif #endif

View File

@@ -14,6 +14,7 @@
float const PI = 3.141592653589793f; float const PI = 3.141592653589793f;
float const D2R = PI * 2 / 360; float const D2R = PI * 2 / 360;
#include <stdint.h> #include <stdint.h>
#include <vector> #include <vector>
#include <string> #include <string>

View File

@@ -9,6 +9,7 @@
#include "KRMeshStreamer.h" #include "KRMeshStreamer.h"
#include "KREngine-common.h" #include "KREngine-common.h"
#include "KRContext.h"
#include <chrono> #include <chrono>
@@ -36,6 +37,9 @@ void KRMeshStreamer::run()
while(!m_stop) while(!m_stop)
{ {
if(m_context.getStreamingEnabled()) {
}
std::this_thread::sleep_for( sleep_duration ); std::this_thread::sleep_for( sleep_duration );
} }
} }

View File

@@ -52,13 +52,14 @@ long KRTexture::getReferencedMemSize() {
void KRTexture::resize(int max_dim) void KRTexture::resize(int max_dim)
{ {
assert(m_iHandle == m_iNewHandle); // Only allow one resize() per frame if(m_iHandle != m_iNewHandle) return; // Only allow one resize() per frame
if(max_dim == 0) { if(max_dim == 0) {
m_iNewHandle = 0; m_iNewHandle = 0;
} else { } else {
int target_dim = max_dim; int target_dim = max_dim;
if(target_dim < m_min_lod_max_dim) target_dim = m_min_lod_max_dim; if(target_dim < m_min_lod_max_dim) target_dim = m_min_lod_max_dim;
/*
int requiredMemoryTransfer = getThroughputRequiredForResize(target_dim); int requiredMemoryTransfer = getThroughputRequiredForResize(target_dim);
int requiredMemoryDelta = getMemRequiredForSize(target_dim) - getMemSize() - getReferencedMemSize(); int requiredMemoryDelta = getMemRequiredForSize(target_dim) - getMemSize() - getReferencedMemSize();
@@ -74,13 +75,13 @@ void KRTexture::resize(int max_dim)
// Exceeding total memory allocated to textures; can't resize now // Exceeding total memory allocated to textures; can't resize now
return; return;
} }
*/
if(m_current_lod_max_dim != target_dim || (m_iHandle == 0 && m_iNewHandle == 0)) { if(m_current_lod_max_dim != target_dim || (m_iHandle == 0 && m_iNewHandle == 0)) {
if(!createGLTexture(target_dim)) { if(!createGLTexture(target_dim)) {
assert(false); assert(false);
} }
} }
} // }
} }
} }

View File

@@ -215,13 +215,20 @@ long KRTextureManager::getMemActive() {
void KRTextureManager::startFrame(float deltaTime) void KRTextureManager::startFrame(float deltaTime)
{ {
m_streamer.startStreamer();
_clearGLState(); _clearGLState();
for(std::set<KRTexture *>::iterator itr=m_activeTextures.begin(); itr != m_activeTextures.end(); itr++) { for(std::set<KRTexture *>::iterator itr=m_activeTextures.begin(); itr != m_activeTextures.end(); itr++) {
KRTexture *activeTexture = *itr; KRTexture *activeTexture = *itr;
activeTexture->_swapHandles(); activeTexture->_swapHandles();
} }
// TODO - Implement proper double-buffering to reduce copy operations
m_streamerFenceMutex.lock();
m_activeTextures_streamer_copy = m_activeTextures;
m_poolTextures_streamer_copy = m_poolTextures;
m_streamerFenceMutex.unlock();
m_memoryTransferredThisFrame = 0; m_memoryTransferredThisFrame = 0;
balanceTextureMemory();
rotateBuffers(); rotateBuffers();
} }
@@ -234,15 +241,25 @@ void KRTextureManager::endFrame(float deltaTime)
} }
} }
void KRTextureManager::doStreaming()
{
// TODO - Implement proper double-buffering to reduce copy operations
m_streamerFenceMutex.lock();
m_activeTextures_streamer = m_activeTextures_streamer_copy;
m_poolTextures_streamer = m_poolTextures_streamer_copy;
m_streamerFenceMutex.unlock();
balanceTextureMemory();
}
void KRTextureManager::balanceTextureMemory() void KRTextureManager::balanceTextureMemory()
{ {
return;
// Balance texture memory by reducing and increasing the maximum mip-map level of both active and inactive textures // Balance texture memory by reducing and increasing the maximum mip-map level of both active and inactive textures
// Favour performance over maximum texture resolution when memory is insufficient for textures at full resolution. // Favour performance over maximum texture resolution when memory is insufficient for textures at full resolution.
// Determine the additional amount of memory required in order to resize all active textures to the maximum size // Determine the additional amount of memory required in order to resize all active textures to the maximum size
long wantedTextureMem = 0; long wantedTextureMem = 0;
for(std::set<KRTexture *>::iterator itr=m_activeTextures.begin(); itr != m_activeTextures.end(); itr++) { for(std::set<KRTexture *>::iterator itr=m_activeTextures_streamer.begin(); itr != m_activeTextures_streamer.end(); itr++) {
KRTexture *activeTexture = *itr; KRTexture *activeTexture = *itr;
wantedTextureMem = activeTexture->getMemRequiredForSize(getContext().KRENGINE_MAX_TEXTURE_DIM) - activeTexture->getMemSize(); wantedTextureMem = activeTexture->getMemRequiredForSize(getContext().KRENGINE_MAX_TEXTURE_DIM) - activeTexture->getMemSize();
@@ -259,7 +276,7 @@ void KRTextureManager::balanceTextureMemory()
maxDimInactive = maxDimInactive >> 1; maxDimInactive = maxDimInactive >> 1;
potentialMemorySaving = 0; potentialMemorySaving = 0;
for(std::set<KRTexture *>::iterator itr=m_poolTextures.begin(); itr != m_poolTextures.end(); itr++) { for(std::set<KRTexture *>::iterator itr=m_poolTextures_streamer.begin(); itr != m_poolTextures_streamer.end(); itr++) {
KRTexture *poolTexture = *itr; KRTexture *poolTexture = *itr;
long potentialMemoryDelta = poolTexture->getMemRequiredForSize(maxDimInactive) - poolTexture->getMemSize(); long potentialMemoryDelta = poolTexture->getMemRequiredForSize(maxDimInactive) - poolTexture->getMemSize();
if(potentialMemoryDelta < 0) { if(potentialMemoryDelta < 0) {
@@ -270,7 +287,7 @@ void KRTextureManager::balanceTextureMemory()
// Strip off mipmap levels of inactive textures to free up memory // Strip off mipmap levels of inactive textures to free up memory
long inactive_texture_mem_used_target = 0; long inactive_texture_mem_used_target = 0;
for(std::set<KRTexture *>::iterator itr=m_poolTextures.begin(); itr != m_poolTextures.end(); itr++) { for(std::set<KRTexture *>::iterator itr=m_poolTextures_streamer.begin(); itr != m_poolTextures_streamer.end(); itr++) {
KRTexture *poolTexture = *itr; KRTexture *poolTexture = *itr;
long potentialMemoryDelta = poolTexture->getMemRequiredForSize(maxDimInactive) - poolTexture->getMemSize(); long potentialMemoryDelta = poolTexture->getMemRequiredForSize(maxDimInactive) - poolTexture->getMemSize();
if(potentialMemoryDelta < 0) { if(potentialMemoryDelta < 0) {
@@ -286,7 +303,7 @@ void KRTextureManager::balanceTextureMemory()
long maxDimActive = getContext().KRENGINE_MAX_TEXTURE_DIM; long maxDimActive = getContext().KRENGINE_MAX_TEXTURE_DIM;
while(memory_available <= 0 && maxDimActive >= getContext().KRENGINE_MIN_TEXTURE_DIM) { while(memory_available <= 0 && maxDimActive >= getContext().KRENGINE_MIN_TEXTURE_DIM) {
memory_available = getContext().KRENGINE_MAX_TEXTURE_MEM - inactive_texture_mem_used_target; memory_available = getContext().KRENGINE_MAX_TEXTURE_MEM - inactive_texture_mem_used_target;
for(std::set<KRTexture *>::iterator itr=m_activeTextures.begin(); itr != m_activeTextures.end() && memory_available > 0; itr++) { for(std::set<KRTexture *>::iterator itr=m_activeTextures_streamer.begin(); itr != m_activeTextures_streamer.end() && memory_available > 0; itr++) {
KRTexture *activeTexture = *itr; KRTexture *activeTexture = *itr;
memory_available -= activeTexture->getMemRequiredForSize(maxDimActive); memory_available -= activeTexture->getMemRequiredForSize(maxDimActive);
} }
@@ -297,7 +314,7 @@ void KRTextureManager::balanceTextureMemory()
} }
// Resize active textures to balance the memory usage and mipmap levels // Resize active textures to balance the memory usage and mipmap levels
for(std::set<KRTexture *>::iterator itr=m_activeTextures.begin(); itr != m_activeTextures.end() && memory_available > 0; itr++) { for(std::set<KRTexture *>::iterator itr=m_activeTextures_streamer.begin(); itr != m_activeTextures_streamer.end() && memory_available > 0; itr++) {
KRTexture *activeTexture = *itr; KRTexture *activeTexture = *itr;
activeTexture->resize(maxDimActive); activeTexture->resize(maxDimActive);
} }

View File

@@ -78,6 +78,8 @@ public:
void _clearGLState(); void _clearGLState();
void setMaxAnisotropy(float max_anisotropy); void setMaxAnisotropy(float max_anisotropy);
void doStreaming();
private: private:
int m_iActiveTexture; int m_iActiveTexture;
@@ -89,15 +91,24 @@ private:
GLuint m_wrapModeS[KRENGINE_MAX_TEXTURE_UNITS]; GLuint m_wrapModeS[KRENGINE_MAX_TEXTURE_UNITS];
GLuint m_wrapModeT[KRENGINE_MAX_TEXTURE_UNITS]; GLuint m_wrapModeT[KRENGINE_MAX_TEXTURE_UNITS];
float m_maxAnisotropy[KRENGINE_MAX_TEXTURE_UNITS]; float m_maxAnisotropy[KRENGINE_MAX_TEXTURE_UNITS];
std::set<KRTexture *> m_activeTextures; std::set<KRTexture *> m_activeTextures;
std::set<KRTexture *> m_poolTextures; std::set<KRTexture *> m_poolTextures;
std::set<KRTexture *> m_activeTextures_streamer;
std::set<KRTexture *> m_poolTextures_streamer;
std::set<KRTexture *> m_activeTextures_streamer_copy;
std::set<KRTexture *> m_poolTextures_streamer_copy;
long m_textureMemUsed; long m_textureMemUsed;
void rotateBuffers(); void rotateBuffers();
void balanceTextureMemory(); void balanceTextureMemory();
KRTextureStreamer m_streamer; KRTextureStreamer m_streamer;
std::mutex m_streamerFenceMutex;
}; };
#endif #endif

View File

@@ -45,13 +45,17 @@ public:
KRTextureStreamer(KRContext &context); KRTextureStreamer(KRContext &context);
~KRTextureStreamer(); ~KRTextureStreamer();
void startStreamer();
private: private:
KRContext &m_context; KRContext &m_context;
std::thread m_thread; std::thread m_thread;
std::atomic<bool> m_stop; std::atomic<bool> m_stop;
std::atomic<bool> m_running;
void run(); void run();
}; };
#endif /* defined(KRTEXTURESTREAMER_H) */ #endif /* defined(KRTEXTURESTREAMER_H) */

View File

@@ -9,16 +9,25 @@
#include "KREngine-common.h" #include "KREngine-common.h"
#include "KRTextureStreamer.h" #include "KRTextureStreamer.h"
#include "KRContext.h"
#include <chrono> #include <chrono>
EAGLContext *gTextureStreamerContext; EAGLContext *gTextureStreamerContext = nil;
KRTextureStreamer::KRTextureStreamer(KRContext &context) : m_context(context) KRTextureStreamer::KRTextureStreamer(KRContext &context) : m_context(context)
{ {
gTextureStreamerContext = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2 sharegroup: [EAGLContext currentContext].sharegroup]; m_running = false;
m_stop = false; m_stop = false;
m_thread = std::thread(&KRTextureStreamer::run, this); }
void KRTextureStreamer::startStreamer()
{
if(!m_running) {
m_running = true;
gTextureStreamerContext = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2 sharegroup: [EAGLContext currentContext].sharegroup];
m_thread = std::thread(&KRTextureStreamer::run, this);
}
} }
KRTextureStreamer::~KRTextureStreamer() KRTextureStreamer::~KRTextureStreamer()
@@ -36,6 +45,11 @@ void KRTextureStreamer::run()
while(!m_stop) while(!m_stop)
{ {
if(m_context.getStreamingEnabled()) {
m_context.getTextureManager()->doStreaming();
}
std::this_thread::sleep_for( sleep_duration ); std::this_thread::sleep_for( sleep_duration );
} }
m_running = false;
} }