Add a E_TEXTURE_CREATION_FLAG called ETCF_ALLOW_MEMORY_COPY to allow keeping texture copies in memory for fast locking.

It's disabled by default, but always used for fonts.
Also return now 0 for mipmaps when locking as that part was/is not yet supported.


git-svn-id: svn://svn.code.sf.net/p/irrlicht/code/branches/ogl-es@5037 dfc29bdd-3216-0410-991c-e03cc46cb475
master
cutealien 2015-02-11 13:19:05 +00:00
parent c40929096b
commit b0217b078d
6 changed files with 66 additions and 26 deletions

View File

@ -65,6 +65,12 @@ enum E_TEXTURE_CREATION_FLAG
/** BurningVideo can handle Non-Power-2 Textures in 2D (GUI), but not in 3D. */
ETCF_ALLOW_NON_POWER_2 = 0x00000040,
//! Allow the driver to keep a copy of the texture in memory
/** This makes calls to ITexture::lock a lot faster, but costs main memory.
Default is off, except for font-texture which always enable this flag.
Currently only used in combination with OpenGL-ES2. */
ETCF_ALLOW_MEMORY_COPY = 0x00000080,
/** This flag is never used, it only forces the compiler to compile
these enumeration values to 32 bit. */
ETCF_FORCE_32_BIT_DO_NOT_USE = 0x7fffffff
@ -234,7 +240,7 @@ public:
//! Get name of texture (in most cases this is the filename)
const io::SNamedPath& getName() const { return NamedPath; }
//! Returns the type of texture
E_TEXTURE_TYPE getType() const { return Type; }

View File

@ -85,16 +85,14 @@ bool CGUIFont::load(io::IXMLReader* xml, const io::path& directory)
while (i+1 > SpriteBank->getTextureCount())
SpriteBank->addTexture(0);
// disable mipmaps+filtering
bool mipmap = Driver->getTextureCreationFlag(video::ETCF_CREATE_MIP_MAPS);
Driver->setTextureCreationFlag(video::ETCF_CREATE_MIP_MAPS, false);
bool flags[3];
pushTextureCreationFlags(flags);
// load texture
io::path textureFullName = core::mergeFilename(directory, fn);
SpriteBank->setTexture(i, Driver->getTexture(textureFullName));
// set previous mip-map+filter state
Driver->setTextureCreationFlag(video::ETCF_CREATE_MIP_MAPS, mipmap);
popTextureCreationFlags(flags);
// couldn't load texture, abort.
if (!SpriteBank->getTexture(i))
@ -219,6 +217,23 @@ void CGUIFont::setMaxHeight()
}
void CGUIFont::pushTextureCreationFlags(bool (&flags)[3])
{
flags[0] = Driver->getTextureCreationFlag ( video::ETCF_ALLOW_NON_POWER_2 );
flags[1] = Driver->getTextureCreationFlag ( video::ETCF_CREATE_MIP_MAPS );
flags[2] = Driver->getTextureCreationFlag ( video::ETCF_ALLOW_MEMORY_COPY );
Driver->setTextureCreationFlag(video::ETCF_ALLOW_NON_POWER_2, true);
Driver->setTextureCreationFlag(video::ETCF_CREATE_MIP_MAPS, false );
Driver->setTextureCreationFlag(video::ETCF_ALLOW_MEMORY_COPY, true);
}
void CGUIFont::popTextureCreationFlags(bool (&flags)[3])
{
Driver->setTextureCreationFlag( video::ETCF_ALLOW_NON_POWER_2, flags[0] );
Driver->setTextureCreationFlag( video::ETCF_CREATE_MIP_MAPS, flags[1] );
Driver->setTextureCreationFlag( video::ETCF_ALLOW_MEMORY_COPY, flags[2] );
}
//! loads a font file, native file needed, for texture parsing
bool CGUIFont::load(io::IReadFile* file)
@ -286,17 +301,12 @@ bool CGUIFont::loadTexture(video::IImage* image, const io::path& name)
if ( ret )
{
bool flag[2];
flag[0] = Driver->getTextureCreationFlag ( video::ETCF_ALLOW_NON_POWER_2 );
flag[1] = Driver->getTextureCreationFlag ( video::ETCF_CREATE_MIP_MAPS );
Driver->setTextureCreationFlag(video::ETCF_ALLOW_NON_POWER_2, true);
Driver->setTextureCreationFlag(video::ETCF_CREATE_MIP_MAPS, false );
bool flags[3];
pushTextureCreationFlags(flags);
SpriteBank->addTexture(Driver->addTexture(name, tmpImage));
Driver->setTextureCreationFlag(video::ETCF_ALLOW_NON_POWER_2, flag[0] );
Driver->setTextureCreationFlag(video::ETCF_CREATE_MIP_MAPS, flag[1] );
popTextureCreationFlags(flags);
}
if (deleteTmpImage)
tmpImage->drop();

View File

@ -98,6 +98,9 @@ private:
s32 getAreaFromCharacter (const wchar_t c) const;
void setMaxHeight();
void pushTextureCreationFlags(bool (&flags)[3]);
void popTextureCreationFlags(bool (&flags)[3]);
core::array<SFontArea> Areas;
core::map<wchar_t, s32> CharacterMap;
video::IVideoDriver* Driver;

View File

@ -40,7 +40,7 @@ COGLES2Texture::COGLES2Texture(IImage* origImage, const io::path& name, void* mi
TextureName(0), TextureType(GL_TEXTURE_2D), InternalFormat(GL_RGBA), PixelFormat(GL_RGBA),
PixelType(GL_UNSIGNED_BYTE), MipLevelStored(0),
IsRenderTarget(false), IsCompressed(false), AutomaticMipmapUpdate(false),
ReadOnlyLock(false), LockImage(0)
ReadOnlyLock(false), KeepImage(true), LockImage(0)
{
#ifdef _DEBUG
setDebugName("COGLES2Texture");
@ -63,6 +63,7 @@ COGLES2Texture::COGLES2Texture(IImage* origImage, const io::path& name, void* mi
{
Image.push_back(origImage);
Image[0]->grab();
KeepImage = false;
}
else if (ImageSize==TextureSize)
{
@ -80,6 +81,16 @@ COGLES2Texture::COGLES2Texture(IImage* origImage, const io::path& name, void* mi
glGenTextures(1, &TextureName);
uploadTexture(true, 0, true, mipmapData);
if ( KeepImage )
{
KeepImage = Driver->getTextureCreationFlag(ETCF_ALLOW_MEMORY_COPY);
if ( KeepImage )
{
LockImage = Image[0];
LockImage->grab();
}
}
Image[0]->drop();
Image.clear();
}
@ -91,7 +102,7 @@ COGLES2Texture::COGLES2Texture(const io::path& name, IImage* posXImage, IImage*
: ITexture(name, ETT_CUBE), Pitch(0), ColorFormat(ECF_A8R8G8B8), Driver(driver), Image(0), MipImage(0),
TextureName(0), TextureType(GL_TEXTURE_CUBE_MAP), InternalFormat(GL_RGBA), PixelFormat(GL_RGBA),
PixelType(GL_UNSIGNED_BYTE), MipLevelStored(0), IsRenderTarget(false), IsCompressed(false),
AutomaticMipmapUpdate(false), ReadOnlyLock(false), LockImage(0)
AutomaticMipmapUpdate(false), ReadOnlyLock(false), KeepImage(false), LockImage(0)
{
#ifdef _DEBUG
setDebugName("COpenGLTexture");
@ -169,7 +180,7 @@ COGLES2Texture::COGLES2Texture(const io::path& name, COGLES2Driver* driver)
TextureName(0), TextureType(GL_TEXTURE_2D), InternalFormat(GL_RGBA), PixelFormat(GL_RGBA),
PixelType(GL_UNSIGNED_BYTE), MipLevelStored(0), HasMipMaps(true),
IsRenderTarget(false), IsCompressed(false), AutomaticMipmapUpdate(false),
ReadOnlyLock(false), LockImage(0)
ReadOnlyLock(false), KeepImage(false), LockImage(0)
{
#ifdef _DEBUG
setDebugName("COGLES2Texture");
@ -618,15 +629,15 @@ void COGLES2Texture::uploadTexture(bool newTexture, u32 imageNumber, bool regMip
//! lock function
void* COGLES2Texture::lock(E_TEXTURE_LOCK_MODE mode, u32 mipmapLevel)
{
if (IsCompressed || IsRenderTarget || Type != ETT_2D) // TO-DO
if (IsCompressed || IsRenderTarget || Type != ETT_2D || mipmapLevel > 0) // TO-DO
return 0;
if (LockImage)
return LockImage;
ReadOnlyLock |= (mode==ETLM_READ_ONLY);
MipLevelStored = mipmapLevel;
if (LockImage)
return LockImage->lock();
IImage* tmpImage = 0;
if (mipmapLevel)
@ -799,8 +810,11 @@ void COGLES2Texture::unlock()
ReadOnlyLock = false;
LockImage->drop();
LockImage = 0;
if ( !KeepImage )
{
LockImage->drop();
LockImage = 0;
}
}

View File

@ -157,6 +157,7 @@ protected:
bool IsCompressed;
bool AutomaticMipmapUpdate;
bool ReadOnlyLock;
bool KeepImage;
IImage* LockImage;
mutable SStatesCache StatesCache;

View File

@ -477,6 +477,9 @@ void COGLES1Texture::uploadTexture(bool newTexture, void* mipmapData, u32 level)
//! lock function
void* COGLES1Texture::lock(E_TEXTURE_LOCK_MODE mode, u32 mipmapLevel)
{
if ( mipmapLevel > 0 ) // TODO: this does not yet seem to be supported for ES1, so quit.
return 0;
// store info about which image is locked
IImage* image = (mipmapLevel==0)?Image:MipImage;
@ -525,9 +528,12 @@ void* COGLES1Texture::lock(E_TEXTURE_LOCK_MODE mode, u32 mipmapLevel)
//! unlock function
void COGLES1Texture::unlock()
{
Image->unlock();
if (!ReadOnlyLock)
uploadTexture(false);
if ( Image )
{
Image->unlock();
if (!ReadOnlyLock)
uploadTexture(false);
}
ReadOnlyLock = false;
}