gfxTextureObject.cpp
Engine/source/gfx/gfxTextureObject.cpp
Public Functions
DefineEngineFunction(dumpTextureObjects , void , () , "Dumps <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> list of all active texture objects <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> the <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">console.\n</a>" "@note This function is only available in debug <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">builds.\n</a>" "@ingroup <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">GFX\n</a>" )
Detailed Description
Public Functions
DefineEngineFunction(dumpTextureObjects , void , () , "Dumps <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> list of all active texture objects <a href="/coding/file/cmdgram_8cpp/#cmdgram_8cpp_1a5bafda9519252aa2d0fd038153f77dca">to</a> the <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">console.\n</a>" "@note This function is only available in debug <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">builds.\n</a>" "@ingroup <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">GFX\n</a>" )
1 2//----------------------------------------------------------------------------- 3// Copyright (c) 2012 GarageGames, LLC 4// 5// Permission is hereby granted, free of charge, to any person obtaining a copy 6// of this software and associated documentation files (the "Software"), to 7// deal in the Software without restriction, including without limitation the 8// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 9// sell copies of the Software, and to permit persons to whom the Software is 10// furnished to do so, subject to the following conditions: 11// 12// The above copyright notice and this permission notice shall be included in 13// all copies or substantial portions of the Software. 14// 15// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 20// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 21// IN THE SOFTWARE. 22//----------------------------------------------------------------------------- 23 24#include "platform/platform.h" 25#include "gfx/gfxTextureObject.h" 26 27#include "gfx/gfxDevice.h" 28#include "gfx/gfxTextureManager.h" 29#include "core/util/safeDelete.h" 30#include "core/strings/stringFunctions.h" 31#include "core/stream/fileStream.h" 32#include "console/console.h" 33#include "console/engineAPI.h" 34 35 36// TODO: Change this to be in non-shipping builds maybe? 37#ifdef TORQUE_DEBUG 38 39GFXTextureObject *GFXTextureObject::smHead = NULL; 40U32 GFXTextureObject::smActiveTOCount = 0; 41 42U32 GFXTextureObject::dumpActiveTOs() 43{ 44 if(!smActiveTOCount) 45 { 46 Con::printf( "GFXTextureObject::dumpActiveTOs - no active TOs to dump." ); 47 return 0; 48 } 49 50 Con::printf("GFXTextureObject Usage Report - %d active TOs", smActiveTOCount); 51 Con::printf("---------------------------------------------------------------"); 52 Con::printf(" Addr Dim. GFXTextureProfile ProfilerPath DebugDescription"); 53 54 for(GFXTextureObject *walk = smHead; walk; walk=walk->mDebugNext) 55 Con::printf(" %x (%4d, %4d) %s %s %s", walk, walk->getWidth(), 56 walk->getHeight(), walk->mProfile->getName().c_str(), walk->mDebugCreationPath.c_str(), walk->mDebugDescription.c_str()); 57 58 Con::printf("----- dump complete -------------------------------------------"); 59 return smActiveTOCount; 60} 61 62 63 64#endif // TORQUE_DEBUG 65 66DefineEngineFunction( dumpTextureObjects, void, (),, 67 "Dumps a list of all active texture objects to the console.\n" 68 "@note This function is only available in debug builds.\n" 69 "@ingroup GFX\n" ) 70{ 71#ifdef TORQUE_DEBUG 72 GFXTextureObject::dumpActiveTOs(); 73#endif 74} 75 76//----------------------------------------------------------------------------- 77// GFXTextureObject 78//----------------------------------------------------------------------------- 79GFXTextureObject::GFXTextureObject(GFXDevice *aDevice, GFXTextureProfile *aProfile) 80{ 81 mHashNext = mNext = mPrev = NULL; 82 83 mDevice = aDevice; 84 mProfile = aProfile; 85 86 mBitmap = NULL; 87 mMipLevels = 1; 88 mAntialiasLevel = 0; 89 90 mTextureSize.set( 0, 0, 0 ); 91 92 mDead = false; 93 94 mDeleteTime = 0; 95 96 mBitmap = NULL; 97 mDDS = NULL; 98 99 mFormat = GFXFormatR8G8B8; 100 101 mHasTransparency = false; 102 103#if defined(TORQUE_DEBUG) 104 // Active object tracking. 105 smActiveTOCount++; 106 mDebugDescription = "Anonymous Texture Object"; 107#if defined(TORQUE_ENABLE_PROFILE_PATH) 108 mDebugCreationPath = gProfiler->getProfilePath(); 109#endif 110 mDebugNext = smHead; 111 mDebugPrev = NULL; 112 113 if(smHead) 114 { 115 AssertFatal(smHead->mDebugPrev == NULL, "GFXTextureObject::GFXTextureObject - found unexpected previous in current head!"); 116 smHead->mDebugPrev = this; 117 } 118 119 smHead = this; 120#endif 121} 122 123//----------------------------------------------------------------------------- 124// Destructor 125//----------------------------------------------------------------------------- 126GFXTextureObject::~GFXTextureObject() 127{ 128 kill(); 129 130#ifdef TORQUE_DEBUG 131 if(smHead == this) 132 smHead = this->mDebugNext; 133 134 if(mDebugNext) 135 mDebugNext->mDebugPrev = mDebugPrev; 136 137 if(mDebugPrev) 138 mDebugPrev->mDebugNext = mDebugNext; 139 140 mDebugPrev = mDebugNext = NULL; 141 142 smActiveTOCount--; 143#endif 144} 145 146void GFXTextureObject::destroySelf() 147{ 148 mDevice->mTextureManager->requestDeleteTexture(this); 149} 150 151//----------------------------------------------------------------------------- 152// kill - this function clears out the data in texture object. It's done like 153// this because the texture object needs to release its pointers to textures 154// before the GFXDevice is shut down. The texture objects themselves get 155// deleted by the refcount structure - which may be after the GFXDevice has 156// been destroyed. 157//----------------------------------------------------------------------------- 158void GFXTextureObject::kill() 159{ 160 if( mDead ) 161 return; 162 163#ifdef TORQUE_DEBUG 164 // This makes sure that nobody is forgetting to call kill from the derived 165 // destructor. If they are, then we should get a pure virtual function 166 // call here. 167 pureVirtualCrash(); 168#endif 169 170 // If we're a dummy, don't do anything... 171 if( !mDevice || !mDevice->mTextureManager ) 172 { 173 mDead = true; 174 return; 175 } 176 177 // Remove ourselves from the texture list and hash 178 mDevice->mTextureManager->deleteTexture(this); 179 180 // Delete the stored bitmap. 181 SAFE_DELETE(mBitmap) 182 SAFE_DELETE(mDDS); 183 184 // Clean up linked list 185 if(mNext) 186 mNext->mPrev = mPrev; 187 if(mPrev) 188 mPrev->mNext = mNext; 189 190 mDead = true; 191} 192 193const String GFXTextureObject::describeSelf() const 194{ 195 return String::ToString(" (width: %4d, height: %4d) profile: %s creation path: %s", getWidth(), 196#if defined(TORQUE_DEBUG) && defined(TORQUE_ENABLE_PROFILER) 197 getHeight(), mProfile->getName().c_str(), mDebugCreationPath.c_str()); 198#else 199 getHeight(), mProfile->getName().c_str(), ""); 200#endif 201} 202 203F32 GFXTextureObject::getMaxUCoord() const 204{ 205 return 1.0f; 206} 207 208F32 GFXTextureObject::getMaxVCoord() const 209{ 210 return 1.0f; 211} 212 213U32 GFXTextureObject::getEstimatedSizeInBytes() const 214{ 215 // We have to deal with DDS specially. 216 if ( mFormat >= GFXFormatBC1 ) 217 return DDSFile::getSizeInBytes( mFormat, mTextureSize.x, mTextureSize.y, mMipLevels ); 218 219 // Else we need to calculate the size ourselves. 220 S32 texSizeX = mTextureSize.x; 221 S32 texSizeY = mTextureSize.y; 222 S32 volDepth = getMax( 1, mTextureSize.z ); 223 U32 byteSize = GFXFormat_getByteSize( mFormat ); 224 U32 totalBytes = texSizeX * texSizeY * volDepth * byteSize; 225 226 // Without mips we're done. 227 if ( mProfile->noMip() ) 228 return totalBytes; 229 230 // NOTE: While we have mMipLevels, at the time of this 231 // comment it only stores the accessable mip levels and 232 // not the count of the autogen mips. 233 // 234 // So we figure out the mip count ourselves assuming its 235 // a complete mip chain. 236 while ( texSizeX > 1 || texSizeY > 1 ) 237 { 238 texSizeX = getMax( texSizeX >> 1, 1 ); 239 texSizeY = getMax( texSizeY >> 1, 1 ); 240 volDepth = getMax( volDepth >> 1, 1 ); 241 242 totalBytes += texSizeX * texSizeY * volDepth * byteSize; 243 } 244 245 return totalBytes; 246} 247 248bool GFXTextureObject::dumpToDisk( const String &bmType, const String &path ) 249{ 250 FileStream stream; 251 if ( !stream.open( path, Torque::FS::File::Write ) ) 252 return false; 253 254 if ( mBitmap ) 255 return mBitmap->writeBitmap( bmType, stream ); 256 257 GBitmap bitmap( getWidth(), getHeight(), false, getFormat() ); 258 copyToBmp( &bitmap ); 259 return bitmap.writeBitmap( bmType, stream ); 260} 261