Asynchronous streaming and memory management improvements in progress.
--HG-- branch : async_streaming
This commit is contained in:
@@ -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 */,
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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 ¤t_lod_max_dim, long &textureMemUsed, int prev_lod_max_dim, GLuint prev_handle) = 0;
|
||||
virtual bool uploadTexture(GLenum target, int lod_max_dim, int ¤t_lod_max_dim, long &textureMemUsed, int prev_lod_max_dim) = 0;
|
||||
virtual void bind(GLuint texture_unit);
|
||||
|
||||
protected:
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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 ¤t_lod_max_dim, long &textureMemUsed, int prev_lod_max_dim, GLuint prev_handle)
|
||||
bool KRTexturePVR::uploadTexture(GLenum target, int lod_max_dim, int ¤t_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 ¤t_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 ¤t_lo
|
||||
}
|
||||
|
||||
textureMemUsed += memoryRequired;
|
||||
getContext().getTextureManager()->memoryChanged(memoryTransferred);
|
||||
getContext().getTextureManager()->memoryChanged(memoryRequired);
|
||||
getContext().getTextureManager()->addMemoryTransferredThisFrame(memoryTransferred);
|
||||
|
||||
return true;
|
||||
|
||||
@@ -18,7 +18,7 @@ public:
|
||||
virtual ~KRTexturePVR();
|
||||
virtual std::string getExtension();
|
||||
|
||||
bool uploadTexture(GLenum target, int lod_max_dim, int ¤t_lod_max_dim, long &textureMemUsed, int prev_lod_max_dim, GLuint prev_handle);
|
||||
bool uploadTexture(GLenum target, int lod_max_dim, int ¤t_lod_max_dim, long &textureMemUsed, int prev_lod_max_dim);
|
||||
|
||||
virtual long getMemRequiredForSize(int max_dim);
|
||||
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
@@ -41,7 +41,7 @@ KRTextureTGA::~KRTextureTGA()
|
||||
|
||||
}
|
||||
|
||||
bool KRTextureTGA::uploadTexture(GLenum target, int lod_max_dim, int ¤t_lod_max_dim, long &textureMemUsed, int prev_lod_max_dim, GLuint prev_handle)
|
||||
bool KRTextureTGA::uploadTexture(GLenum target, int lod_max_dim, int ¤t_lod_max_dim, long &textureMemUsed, int prev_lod_max_dim)
|
||||
{
|
||||
m_pData->lock();
|
||||
TGA_HEADER *pHeader = (TGA_HEADER *)m_pData->getStart();
|
||||
|
||||
@@ -18,7 +18,7 @@ public:
|
||||
virtual ~KRTextureTGA();
|
||||
virtual std::string getExtension();
|
||||
|
||||
bool uploadTexture(GLenum target, int lod_max_dim, int ¤t_lod_max_dim, long &textureMemUsed, int prev_lod_max_dim, GLuint prev_handle);
|
||||
bool uploadTexture(GLenum target, int lod_max_dim, int ¤t_lod_max_dim, long &textureMemUsed, int prev_lod_max_dim);
|
||||
|
||||
virtual long getMemRequiredForSize(int max_dim);
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user