Asynchronous streaming and memory management improvements in progress.

--HG--
branch : async_streaming
This commit is contained in:
2013-11-02 16:27:24 -07:00
parent 06436d72f5
commit 48d3a6a2c8
18 changed files with 167 additions and 75 deletions

View File

@@ -77,12 +77,12 @@
E43F70DD181B20E400136169 /* KRLODSet.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E43F70DA181B20E300136169 /* KRLODSet.cpp */; };
E43F70DE181B20E400136169 /* KRLODSet.h in Headers */ = {isa = PBXBuildFile; fileRef = E43F70DB181B20E400136169 /* KRLODSet.h */; };
E43F70DF181B20E400136169 /* KRLODSet.h in Headers */ = {isa = PBXBuildFile; fileRef = E43F70DB181B20E400136169 /* KRLODSet.h */; };
E43F70E51824D9AB00136169 /* KRTextureStreamer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E43F70E31824D9AB00136169 /* KRTextureStreamer.cpp */; };
E43F70E61824D9AB00136169 /* KRTextureStreamer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E43F70E31824D9AB00136169 /* KRTextureStreamer.cpp */; };
E43F70E51824D9AB00136169 /* KRTextureStreamer.mm in Sources */ = {isa = PBXBuildFile; fileRef = E43F70E31824D9AB00136169 /* KRTextureStreamer.mm */; };
E43F70E61824D9AB00136169 /* KRTextureStreamer.mm in Sources */ = {isa = PBXBuildFile; fileRef = E43F70E31824D9AB00136169 /* KRTextureStreamer.mm */; };
E43F70E71824D9AB00136169 /* KRTextureStreamer.h in Headers */ = {isa = PBXBuildFile; fileRef = E43F70E41824D9AB00136169 /* KRTextureStreamer.h */; };
E43F70E81824D9AB00136169 /* KRTextureStreamer.h in Headers */ = {isa = PBXBuildFile; fileRef = E43F70E41824D9AB00136169 /* KRTextureStreamer.h */; };
E43F70FF1824E73100136169 /* KRMeshStreamer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E43F70FD1824E73100136169 /* KRMeshStreamer.cpp */; };
E43F71001824E73100136169 /* KRMeshStreamer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E43F70FD1824E73100136169 /* KRMeshStreamer.cpp */; };
E43F70FF1824E73100136169 /* KRMeshStreamer.mm in Sources */ = {isa = PBXBuildFile; fileRef = E43F70FD1824E73100136169 /* KRMeshStreamer.mm */; };
E43F71001824E73100136169 /* KRMeshStreamer.mm in Sources */ = {isa = PBXBuildFile; fileRef = E43F70FD1824E73100136169 /* KRMeshStreamer.mm */; };
E43F71011824E73100136169 /* KRMeshStreamer.h in Headers */ = {isa = PBXBuildFile; fileRef = E43F70FE1824E73100136169 /* KRMeshStreamer.h */; };
E43F71021824E73100136169 /* KRMeshStreamer.h in Headers */ = {isa = PBXBuildFile; fileRef = E43F70FE1824E73100136169 /* KRMeshStreamer.h */; };
E4409D2916FA748700310F76 /* font.tga in Resources */ = {isa = PBXBuildFile; fileRef = E41AE1DD16B124CA00980428 /* font.tga */; };
@@ -437,9 +437,9 @@
E43B0AD515DDCA0D00A5CB9F /* KRContextObject.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = KRContextObject.h; sourceTree = "<group>"; };
E43F70DA181B20E300136169 /* KRLODSet.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = KRLODSet.cpp; sourceTree = "<group>"; };
E43F70DB181B20E400136169 /* KRLODSet.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = KRLODSet.h; sourceTree = "<group>"; };
E43F70E31824D9AB00136169 /* KRTextureStreamer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = KRTextureStreamer.cpp; sourceTree = "<group>"; };
E43F70E31824D9AB00136169 /* KRTextureStreamer.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = KRTextureStreamer.mm; sourceTree = "<group>"; };
E43F70E41824D9AB00136169 /* KRTextureStreamer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = KRTextureStreamer.h; sourceTree = "<group>"; };
E43F70FD1824E73100136169 /* KRMeshStreamer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = KRMeshStreamer.cpp; sourceTree = "<group>"; };
E43F70FD1824E73100136169 /* KRMeshStreamer.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = KRMeshStreamer.mm; sourceTree = "<group>"; };
E43F70FE1824E73100136169 /* KRMeshStreamer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = KRMeshStreamer.h; sourceTree = "<group>"; };
E44F38231683B22C00399B5D /* KRRenderSettings.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = KRRenderSettings.h; sourceTree = "<group>"; };
E44F38271683B24400399B5D /* KRRenderSettings.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = KRRenderSettings.cpp; sourceTree = "<group>"; };
@@ -902,7 +902,7 @@
E4CA10EE1637BD58005D9400 /* KRTextureTGA.cpp */,
E460292516681CFE00261BB9 /* KRTextureAnimated.h */,
E460292716681D1000261BB9 /* KRTextureAnimated.cpp */,
E43F70E31824D9AB00136169 /* KRTextureStreamer.cpp */,
E43F70E31824D9AB00136169 /* KRTextureStreamer.mm */,
E43F70E41824D9AB00136169 /* KRTextureStreamer.h */,
);
name = Texture;
@@ -919,7 +919,7 @@
E4C454AE167BB8FC003586CD /* KRMeshCube.cpp */,
E4C454B1167BC04B003586CD /* KRMeshSphere.h */,
E4C454B4167BC05C003586CD /* KRMeshSphere.cpp */,
E43F70FD1824E73100136169 /* KRMeshStreamer.cpp */,
E43F70FD1824E73100136169 /* KRMeshStreamer.mm */,
E43F70FE1824E73100136169 /* KRMeshStreamer.h */,
);
name = Mesh;
@@ -1583,7 +1583,7 @@
E497B946151BA99500D3DC67 /* KRVector2.cpp in Sources */,
E497B94D151BCF2500D3DC67 /* KRResource.cpp in Sources */,
E497B950151BD2CE00D3DC67 /* KRResource+obj.cpp in Sources */,
E43F70FF1824E73100136169 /* KRMeshStreamer.cpp in Sources */,
E43F70FF1824E73100136169 /* KRMeshStreamer.mm in Sources */,
E461A156152E54F800F2044A /* KRLight.cpp in Sources */,
E461A159152E557E00F2044A /* KRPointLight.cpp in Sources */,
E468447F17FFDF51001F1FA1 /* KRLocator.cpp in Sources */,
@@ -1609,7 +1609,7 @@
E4324BA816444C230043185B /* KRParticleSystem.cpp in Sources */,
E4324BAE16444E120043185B /* KRParticleSystemNewtonian.cpp in Sources */,
E460292816681D1000261BB9 /* KRTextureAnimated.cpp in Sources */,
E43F70E51824D9AB00136169 /* KRTextureStreamer.cpp in Sources */,
E43F70E51824D9AB00136169 /* KRTextureStreamer.mm in Sources */,
E428C2F51669611600A16EDF /* KRAnimationManager.cpp in Sources */,
E428C2FB1669613200A16EDF /* KRAnimation.cpp in Sources */,
E428C3071669628A00A16EDF /* KRAnimationCurve.cpp in Sources */,
@@ -1682,7 +1682,7 @@
E488399515F928CA00BD66D5 /* KRBundle.cpp in Sources */,
E488399D15F92BE000BD66D5 /* KRBundleManager.cpp in Sources */,
E43F70DD181B20E400136169 /* KRLODSet.cpp in Sources */,
E43F71001824E73100136169 /* KRMeshStreamer.cpp in Sources */,
E43F71001824E73100136169 /* KRMeshStreamer.mm in Sources */,
E4B175AD161F5A1000B8FB80 /* KRTexture.cpp in Sources */,
E4B175B3161F5FAF00B8FB80 /* KRTextureCube.cpp in Sources */,
E4CA10EA1637BD2B005D9400 /* KRTexturePVR.cpp in Sources */,
@@ -1698,7 +1698,7 @@
E428C31A1669A25D00A16EDF /* KRAnimationAttribute.cpp in Sources */,
E416AA9D1671375C000F6786 /* KRAnimationCurveManager.cpp in Sources */,
E480BE6D1671C653004EC8AD /* KRBone.cpp in Sources */,
E43F70E61824D9AB00136169 /* KRTextureStreamer.cpp in Sources */,
E43F70E61824D9AB00136169 /* KRTextureStreamer.mm in Sources */,
E4C454B0167BB8FC003586CD /* KRMeshCube.cpp in Sources */,
E4C454B6167BC05C003586CD /* KRMeshSphere.cpp in Sources */,
E4C454BC167BD248003586CD /* KRHitInfo.cpp in Sources */,

View File

@@ -40,7 +40,6 @@
KRAudioSample::KRAudioSample(KRContext &context, std::string name, std::string extension) : KRResource(context, name)
{
m_pData = new KRDataBlock();
m_pData->lock();
m_extension = extension;
m_audio_file_id = 0;
@@ -56,7 +55,6 @@ KRAudioSample::KRAudioSample(KRContext &context, std::string name, std::string e
KRAudioSample::KRAudioSample(KRContext &context, std::string name, std::string extension, KRDataBlock *data) : KRResource(context, name)
{
m_pData = data;
m_pData->lock();
m_extension = extension;
m_audio_file_id = 0;
@@ -73,7 +71,6 @@ KRAudioSample::KRAudioSample(KRContext &context, std::string name, std::string e
KRAudioSample::~KRAudioSample()
{
closeFile();
m_pData->unlock();
delete m_pData;
}
@@ -202,7 +199,6 @@ OSStatus KRAudioSample::ReadProc( // AudioFile_ReadProc
UInt32 max_count = sound->m_pData->getSize() - inPosition;
*actualCount = requestCount < max_count ? requestCount : max_count;
sound->m_pData->copy(buffer, inPosition, *actualCount);
//memcpy(buffer, (unsigned char *)sound->m_pData->getStart() + inPosition, *actualCount);
return noErr;
}

View File

@@ -33,6 +33,12 @@
#include "KREngine-common.h"
#include "KRResource.h"
#include <errno.h>
int m_mapCount = 0;
size_t m_mapSize = 0;
size_t m_mapOverhead = 0;
KRDataBlock::KRDataBlock() {
m_data = NULL;
m_data_size = 0;
@@ -271,17 +277,49 @@ void KRDataBlock::lock()
{
m_lockCount++;
if(m_lockCount == 1) {
// Memory mapped file; ensure data is mapped to ram
if(m_fdPackFile) {
fprintf(stderr, "KRDataBlock::lock - \"%s\" (%i)\n", m_fileOwnerDataBlock->m_fileName.c_str(), m_lockCount);
//fprintf(stderr, "KRDataBlock::lock - \"%s\" (%i)\n", m_fileOwnerDataBlock->m_fileName.c_str(), m_lockCount);
// Round m_data_offset down to the next memory page, as required by mmap
size_t alignment_offset = m_data_offset & (KRAKEN_MEM_PAGE_SIZE - 1);
if ((m_mmapData = mmap(0, m_data_size + alignment_offset, m_bReadOnly ? PROT_READ : PROT_WRITE, MAP_SHARED, m_fdPackFile, m_data_offset - alignment_offset)) == (caddr_t) -1) {
int iError = errno;
switch(iError) {
case EACCES:
fprintf(stderr, "mmap failed with EACCES\n");
break;
case EBADF:
fprintf(stderr, "mmap failed with EBADF\n");
break;
case EMFILE:
fprintf(stderr, "mmap failed with EMFILE\n");
break;
case EINVAL:
fprintf(stderr, "mmap failed with EINVAL\n");
break;
case ENOMEM:
fprintf(stderr, "mmap failed with ENOMEM\n");
break;
case ENXIO:
fprintf(stderr, "mmap failed with ENXIO\n");
break;
case EOVERFLOW:
fprintf(stderr, "mmap failed with EOVERFLOW\n");
break;
default:
fprintf(stderr, "mmap failed with errno: %i\n", iError);
break;
}
assert(false); // mmap() failed.
}
m_mapCount++;
m_mapSize += m_data_size;
m_mapOverhead += alignment_offset + KRAKEN_MEM_ROUND_UP_PAGE(m_data_size + alignment_offset) - m_data_size + alignment_offset;
fprintf(stderr, "Mapped: %i Size: %d Overhead: %d\n", m_mapCount, m_mapSize, m_mapOverhead);
m_data = (unsigned char *)m_mmapData + alignment_offset;
}
@@ -299,11 +337,16 @@ void KRDataBlock::unlock()
// Memory mapped file; ensure data is unmapped from ram
if(m_fdPackFile) {
fprintf(stderr, "KRDataBlock::unlock - \"%s\" (%i)\n", m_fileOwnerDataBlock->m_fileName.c_str(), m_lockCount);
//fprintf(stderr, "KRDataBlock::unlock - \"%s\" (%i)\n", m_fileOwnerDataBlock->m_fileName.c_str(), m_lockCount);
munmap(m_mmapData, m_data_size);
m_data = NULL;
m_mmapData = NULL;
m_mapCount--;
m_mapSize -= m_data_size;
size_t alignment_offset = m_data_offset & (KRAKEN_MEM_PAGE_SIZE - 1);
m_mapOverhead -= alignment_offset + KRAKEN_MEM_ROUND_UP_PAGE(m_data_size + alignment_offset) - m_data_size + alignment_offset;
fprintf(stderr, "Mapped: %i Size: %d Overhead: %d\n", m_mapCount, m_mapSize, m_mapOverhead);
}
}

View File

@@ -72,7 +72,8 @@ using std::queue;
int KRAKEN_MEM_PAGE_SIZE = getpagesize();
#define KRAKEN_MEM_ROUND_DOWN_PAGE(x) (x & ~(KRAKEN_MEM_PAGE_SIZE - 1))
#define KRAKEN_MEM_ROUND_DOWN_PAGE(x) ((x) & ~(KRAKEN_MEM_PAGE_SIZE - 1))
#define KRAKEN_MEM_ROUND_UP_PAGE(x) ((((x) - 1) & ~(KRAKEN_MEM_PAGE_SIZE - 1)) + KRAKEN_MEM_PAGE_SIZE)
#define KRENGINE_MAX_TEXTURE_UNITS 8

View File

@@ -110,7 +110,6 @@ public:
void log_draw_call(KRNode::RenderPass pass, const std::string &object_name, const std::string &material_name, int vertex_count);
std::vector<draw_call_info> getDrawCalls();
private:
unordered_multimap<std::string, KRMesh *> m_models; // Multiple models with the same name/key may be inserted, representing multiple LOD levels of the model

View File

@@ -8,10 +8,15 @@
#include "KRMeshStreamer.h"
#include "KREngine-common.h"
#include <chrono>
EAGLContext *gMeshStreamerContext;
KRMeshStreamer::KRMeshStreamer(KRContext &context) : m_context(context)
{
gMeshStreamerContext = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2 sharegroup: [EAGLContext currentContext].sharegroup];
m_stop = false;
m_thread = std::thread(&KRMeshStreamer::run, this);
}
@@ -20,11 +25,14 @@ KRMeshStreamer::~KRMeshStreamer()
{
m_stop = true;
m_thread.join();
[gMeshStreamerContext release];
}
void KRMeshStreamer::run()
{
std::chrono::microseconds sleep_duration( 100 );
[EAGLContext setCurrentContext: gMeshStreamerContext];
while(!m_stop)
{

View File

@@ -15,16 +15,24 @@
KRTexture::KRTexture(KRContext &context, std::string name) : KRResource(context, name)
{
m_iHandle = 0;
m_iNewHandle = 0;
m_textureMemUsed = 0;
m_newTextureMemUsed = 0;
m_last_frame_used = 0;
m_last_frame_bound = 0;
}
KRTexture::~KRTexture()
{
releaseHandle();
releaseHandles();
}
void KRTexture::releaseHandle() {
void KRTexture::releaseHandles() {
if(m_iNewHandle != 0) {
GLDEBUG(glDeleteTextures(1, &m_iNewHandle));
m_iNewHandle = 0;
m_newTextureMemUsed = 0;
}
if(m_iHandle != 0) {
GLDEBUG(glDeleteTextures(1, &m_iHandle));
getContext().getTextureManager()->memoryChanged(-getMemSize());
@@ -34,7 +42,7 @@ void KRTexture::releaseHandle() {
}
long KRTexture::getMemSize() {
return m_textureMemUsed; // TODO - This is not 100% accurate, as loaded format may differ in size while in GPU memory
return m_textureMemUsed + m_newTextureMemUsed; // TODO - This is not 100% accurate, as loaded format may differ in size while in GPU memory
}
long KRTexture::getReferencedMemSize() {
@@ -44,8 +52,10 @@ long KRTexture::getReferencedMemSize() {
void KRTexture::resize(int max_dim)
{
assert(m_iHandle == m_iNewHandle); // Only allow one resize() per frame
if(max_dim == 0) {
releaseHandle();
m_iNewHandle = 0;
} else {
int target_dim = max_dim;
if(target_dim < m_min_lod_max_dim) target_dim = m_min_lod_max_dim;
@@ -65,7 +75,7 @@ void KRTexture::resize(int max_dim)
return;
}
if(m_current_lod_max_dim != target_dim || m_iHandle == 0) {
if(m_current_lod_max_dim != target_dim || (m_iHandle == 0 && m_iNewHandle == 0)) {
if(!createGLTexture(target_dim)) {
assert(false);
}
@@ -74,12 +84,12 @@ void KRTexture::resize(int max_dim)
}
}
GLuint KRTexture::getHandle() {
if(m_iHandle == 0) {
//resize(getContext().KRENGINE_MIN_TEXTURE_DIM);
/*
if(m_iHandle == 0 && m_iNewHandle == 0) {
resize(m_min_lod_max_dim);
}
*/
resetPoolExpiry();
return m_iHandle;
}
@@ -147,3 +157,25 @@ int KRTexture::getMinMipMap() {
bool KRTexture::hasMipmaps() {
return m_max_lod_max_dim != m_min_lod_max_dim;
}
void KRTexture::bind(GLuint texture_unit) {
m_last_frame_bound = getContext().getCurrentFrame();
}
bool KRTexture::canStreamOut() const {
return (m_last_frame_bound + 2 > getContext().getCurrentFrame());
}
void KRTexture::_swapHandles()
{
if(m_iNewHandle != m_iHandle) {
if(m_iHandle != 0) {
GLDEBUG(glDeleteTextures(1, &m_iHandle));
getContext().getTextureManager()->memoryChanged(m_newTextureMemUsed - m_textureMemUsed);
m_textureMemUsed = m_newTextureMemUsed;
m_newTextureMemUsed = 0;
}
m_iHandle = m_iNewHandle;
}
}

View File

@@ -46,8 +46,8 @@ public:
KRTexture(KRContext &context, std::string name);
virtual ~KRTexture();
virtual void bind(GLuint texture_unit) = 0;
void releaseHandle();
virtual void bind(GLuint texture_unit);
void releaseHandles();
long getMemSize();
virtual long getReferencedMemSize();
@@ -66,13 +66,18 @@ public:
int getMinMipMap();
bool hasMipmaps();
bool canStreamOut() const;
void _swapHandles();
protected:
virtual bool createGLTexture(int lod_max_dim) = 0;
GLuint getHandle();
GLuint m_iHandle;
GLuint m_iNewHandle;
long m_textureMemUsed;
long m_newTextureMemUsed;
int m_current_lod_max_dim;
@@ -80,6 +85,7 @@ protected:
uint32_t m_min_lod_max_dim;
long m_last_frame_used;
long m_last_frame_bound;
};

View File

@@ -43,54 +43,52 @@ KRTexture2D::~KRTexture2D() {
}
bool KRTexture2D::createGLTexture(int lod_max_dim) {
if(m_iHandle != m_iNewHandle) {
return true;
}
bool success = true;
GLuint prev_handle = 0;
int prev_lod_max_dim = 0;
long prev_mem_size = 0;
#if GL_APPLE_copy_texture_levels && GL_EXT_texture_storage
if(m_iHandle != 0) {
prev_handle = m_iHandle;
prev_mem_size = getMemSize();
m_iHandle = 0;
m_textureMemUsed = 0;
prev_lod_max_dim = m_current_lod_max_dim;
}
#else
releaseHandle();
#endif
m_iNewHandle = 0;
m_current_lod_max_dim = 0;
GLDEBUG(glGenTextures(1, &m_iHandle));
GLDEBUG(glGenTextures(1, &m_iNewHandle));
if(m_iHandle == 0) {
if(m_iNewHandle == 0) {
success = false;
} else {
GLDEBUG(glBindTexture(GL_TEXTURE_2D, m_iHandle));
GLDEBUG(glBindTexture(GL_TEXTURE_2D, m_iNewHandle));
if (hasMipmaps()) {
GLDEBUG(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR));
} else {
GLDEBUG(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR));
}
if(!uploadTexture(GL_TEXTURE_2D, lod_max_dim, m_current_lod_max_dim, m_textureMemUsed, prev_lod_max_dim, prev_handle)) {
GLDEBUG(glDeleteTextures(1, &m_iHandle));
m_iHandle = 0;
m_current_lod_max_dim = 0;
if(!uploadTexture(GL_TEXTURE_2D, lod_max_dim, m_current_lod_max_dim, m_newTextureMemUsed, prev_lod_max_dim)) {
GLDEBUG(glDeleteTextures(1, &m_iNewHandle));
getContext().getTextureManager()->memoryChanged(-m_newTextureMemUsed);
m_newTextureMemUsed = 0;
m_iNewHandle = m_iHandle;
m_current_lod_max_dim = prev_lod_max_dim;
success = false;
}
}
if(prev_handle != 0) {
getContext().getTextureManager()->memoryChanged(-prev_mem_size);
GLDEBUG(glDeleteTextures(1, &prev_handle));
}
return success;
}
void KRTexture2D::bind(GLuint texture_unit) {
KRTexture::bind(texture_unit);
GLuint handle = getHandle();
GLDEBUG(glBindTexture(GL_TEXTURE_2D, handle));
@@ -101,7 +99,6 @@ void KRTexture2D::bind(GLuint texture_unit) {
}
}
bool KRTexture2D::save(const std::string& path)
{
if(m_pData) {

View File

@@ -46,7 +46,7 @@ public:
virtual bool save(const std::string& path);
virtual bool save(KRDataBlock &data);
virtual bool uploadTexture(GLenum target, int lod_max_dim, int &current_lod_max_dim, long &textureMemUsed, int prev_lod_max_dim, GLuint prev_handle) = 0;
virtual bool uploadTexture(GLenum target, int lod_max_dim, int &current_lod_max_dim, long &textureMemUsed, int prev_lod_max_dim) = 0;
virtual void bind(GLuint texture_unit);
protected:

View File

@@ -114,6 +114,7 @@ void KRTextureAnimated::resetPoolExpiry()
void KRTextureAnimated::bind(GLuint texture_unit)
{
KRTexture::bind(texture_unit);
int frame_number = (int)floor(fmodf(getContext().getAbsoluteTime() * m_frame_rate,m_frame_count));
KRTexture2D *frame_texture = textureForFrame(frame_number);
if(frame_texture) {

View File

@@ -55,32 +55,30 @@ KRTextureCube::~KRTextureCube()
bool KRTextureCube::createGLTexture(int lod_max_dim)
{
assert(m_iNewHandle == m_iHandle); // Only allow one resize per frame
bool success = true;
GLuint prev_handle = 0;
int prev_lod_max_dim = 0;
long prev_mem_size = 0;
#if GL_APPLE_copy_texture_levels && GL_EXT_texture_storage
if(m_iHandle != 0) {
prev_handle = m_iHandle;
prev_mem_size = getMemSize();
m_iHandle = 0;
m_textureMemUsed = 0;
prev_lod_max_dim = m_current_lod_max_dim;
}
#else
releaseHandle();
#endif
m_current_lod_max_dim = 0;
GLDEBUG(glGenTextures(1, &m_iHandle));
if(m_iHandle == 0) {
m_iNewHandle = 0;
GLDEBUG(glGenTextures(1, &m_iNewHandle));
if(m_iNewHandle == 0) {
m_iNewHandle = m_iHandle;
success = false;
} else {
GLDEBUG(glBindTexture(GL_TEXTURE_CUBE_MAP, m_iHandle));
m_current_lod_max_dim = 0;
GLDEBUG(glBindTexture(GL_TEXTURE_CUBE_MAP, m_iNewHandle));
bool bMipMaps = false;
@@ -89,7 +87,7 @@ bool KRTextureCube::createGLTexture(int lod_max_dim)
KRTexture2D *faceTexture = (KRTexture2D *)getContext().getTextureManager()->getTexture(faceName);
if(faceTexture) {
if(faceTexture->hasMipmaps()) bMipMaps = true;
faceTexture->uploadTexture(TARGETS[i], lod_max_dim, m_current_lod_max_dim, m_textureMemUsed, prev_lod_max_dim, prev_handle);
faceTexture->uploadTexture(TARGETS[i], lod_max_dim, m_current_lod_max_dim, m_newTextureMemUsed, prev_lod_max_dim);
}
}
@@ -101,11 +99,7 @@ bool KRTextureCube::createGLTexture(int lod_max_dim)
GLDEBUG(glGenerateMipmap(GL_TEXTURE_CUBE_MAP));
}
}
if(prev_handle != 0) {
getContext().getTextureManager()->memoryChanged(-prev_mem_size);
GLDEBUG(glDeleteTextures(1, &prev_handle));
}
return success;
}
@@ -141,6 +135,7 @@ void KRTextureCube::resetPoolExpiry()
void KRTextureCube::bind(GLuint texture_unit)
{
KRTexture::bind(texture_unit);
GLuint handle = getHandle();
GLDEBUG(glBindTexture(GL_TEXTURE_CUBE_MAP, handle));
if(handle) {

View File

@@ -216,6 +216,10 @@ long KRTextureManager::getMemActive() {
void KRTextureManager::startFrame(float deltaTime)
{
_clearGLState();
for(std::set<KRTexture *>::iterator itr=m_activeTextures.begin(); itr != m_activeTextures.end(); itr++) {
KRTexture *activeTexture = *itr;
activeTexture->_swapHandles();
}
m_memoryTransferredThisFrame = 0;
balanceTextureMemory();
rotateBuffers();
@@ -310,7 +314,7 @@ void KRTextureManager::rotateBuffers()
KRTexture *poolTexture = *itr;
if(poolTexture->getLastFrameUsed() + KRENGINE_TEXTURE_EXPIRY_FRAMES < getContext().getCurrentFrame()) {
expiredTextures.insert(poolTexture);
poolTexture->releaseHandle();
poolTexture->releaseHandles();
}
}
for(std::set<KRTexture *>::iterator itr=expiredTextures.begin(); itr != expiredTextures.end(); itr++) {
@@ -318,6 +322,7 @@ void KRTextureManager::rotateBuffers()
}
// ----====---- Swap the buffers ----====----
m_poolTextures.insert(m_activeTextures.begin(), m_activeTextures.end());
m_activeTextures.clear();
}

View File

@@ -135,6 +135,7 @@ KRTexturePVR::KRTexturePVR(KRContext &context, KRDataBlock *data, std::string na
m_max_lod_max_dim = m_iWidth > m_iHeight ? m_iWidth : m_iHeight;
m_min_lod_max_dim = width > height ? width : height;
m_pData->unlock();
#endif
}
@@ -172,7 +173,7 @@ long KRTexturePVR::getMemRequiredForSize(int max_dim)
return memoryRequired;
}
bool KRTexturePVR::uploadTexture(GLenum target, int lod_max_dim, int &current_lod_max_dim, long &textureMemUsed, int prev_lod_max_dim, GLuint prev_handle)
bool KRTexturePVR::uploadTexture(GLenum target, int lod_max_dim, int &current_lod_max_dim, long &textureMemUsed, int prev_lod_max_dim)
{
int target_dim = lod_max_dim;
if(target_dim < m_min_lod_max_dim) target_dim = m_min_lod_max_dim;
@@ -242,7 +243,7 @@ bool KRTexturePVR::uploadTexture(GLenum target, int lod_max_dim, int &current_lo
if(target == GL_TEXTURE_2D && width <= prev_lod_max_dim && height <= prev_lod_max_dim) {
//GLDEBUG(glCompressedTexImage2D(target, i, m_internalFormat, width, height, 0, block.length, NULL)); // Allocate, but don't copy
// GLDEBUG(glTexImage2D(target, 0, GL_RGBA, width, height, 0, GL_BGRA, GL_UNSIGNED_BYTE, NULL));
GLDEBUG(glCopyTextureLevelsAPPLE(m_iHandle, prev_handle, source_level, 1));
GLDEBUG(glCopyTextureLevelsAPPLE(m_iNewHandle, m_iHandle, source_level, 1));
} else {
// glCompressedTexSubImage2D (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const GLvoid* data);
m_pData->lock();
@@ -288,7 +289,7 @@ bool KRTexturePVR::uploadTexture(GLenum target, int lod_max_dim, int &current_lo
}
textureMemUsed += memoryRequired;
getContext().getTextureManager()->memoryChanged(memoryTransferred);
getContext().getTextureManager()->memoryChanged(memoryRequired);
getContext().getTextureManager()->addMemoryTransferredThisFrame(memoryTransferred);
return true;

View File

@@ -18,7 +18,7 @@ public:
virtual ~KRTexturePVR();
virtual std::string getExtension();
bool uploadTexture(GLenum target, int lod_max_dim, int &current_lod_max_dim, long &textureMemUsed, int prev_lod_max_dim, GLuint prev_handle);
bool uploadTexture(GLenum target, int lod_max_dim, int &current_lod_max_dim, long &textureMemUsed, int prev_lod_max_dim);
virtual long getMemRequiredForSize(int max_dim);

View File

@@ -6,12 +6,17 @@
// Copyright (c) 2013 Kearwood Software. All rights reserved.
//
#include "KREngine-common.h"
#include "KRTextureStreamer.h"
#include <chrono>
EAGLContext *gTextureStreamerContext;
KRTextureStreamer::KRTextureStreamer(KRContext &context) : m_context(context)
{
gTextureStreamerContext = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2 sharegroup: [EAGLContext currentContext].sharegroup];
m_stop = false;
m_thread = std::thread(&KRTextureStreamer::run, this);
}
@@ -20,11 +25,14 @@ KRTextureStreamer::~KRTextureStreamer()
{
m_stop = true;
m_thread.join();
[gTextureStreamerContext release];
}
void KRTextureStreamer::run()
{
std::chrono::microseconds sleep_duration( 100 );
[EAGLContext setCurrentContext: gTextureStreamerContext];
while(!m_stop)
{

View File

@@ -41,7 +41,7 @@ KRTextureTGA::~KRTextureTGA()
}
bool KRTextureTGA::uploadTexture(GLenum target, int lod_max_dim, int &current_lod_max_dim, long &textureMemUsed, int prev_lod_max_dim, GLuint prev_handle)
bool KRTextureTGA::uploadTexture(GLenum target, int lod_max_dim, int &current_lod_max_dim, long &textureMemUsed, int prev_lod_max_dim)
{
m_pData->lock();
TGA_HEADER *pHeader = (TGA_HEADER *)m_pData->getStart();

View File

@@ -18,7 +18,7 @@ public:
virtual ~KRTextureTGA();
virtual std::string getExtension();
bool uploadTexture(GLenum target, int lod_max_dim, int &current_lod_max_dim, long &textureMemUsed, int prev_lod_max_dim, GLuint prev_handle);
bool uploadTexture(GLenum target, int lod_max_dim, int &current_lod_max_dim, long &textureMemUsed, int prev_lod_max_dim);
virtual long getMemRequiredForSize(int max_dim);
};