Added new debug function: console.writeMemoryStats(). Estimates total memory use by entities and textures, and how much texture data is visible (i.e. relevant to GPU swapping).

git-svn-id: http://svn.berlios.de/svnroot/repos/oolite-linux/trunk@3434 127b21dd-08f5-0310-b4b7-95ae10353056
This commit is contained in:
Jens Ayton 2010-05-30 14:51:13 +00:00
parent e532171d9d
commit 8a9a1e7b83
32 changed files with 662 additions and 30 deletions

View File

@ -346,7 +346,8 @@ OO_UTILITY_FILES = \
OOWeakReference.m \
OOXMLExtensions.m \
OODeepCopy.m \
OORegExpMatcher.m
OORegExpMatcher.m \
NSObjectOOExtensions.m
OOLITE_MISC_FILES = \
AI.m \

View File

@ -48,6 +48,8 @@
1A047A460DCA0F4F00EE1CD0 /* NSDictionaryOOExtensions.m in Sources */ = {isa = PBXBuildFile; fileRef = 1A047A440DCA0F4F00EE1CD0 /* NSDictionaryOOExtensions.m */; };
1A047B7E0DCB3D7500EE1CD0 /* OOProbabilitySet.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A047B7C0DCB3D7500EE1CD0 /* OOProbabilitySet.h */; };
1A047B7F0DCB3D7500EE1CD0 /* OOProbabilitySet.m in Sources */ = {isa = PBXBuildFile; fileRef = 1A047B7D0DCB3D7500EE1CD0 /* OOProbabilitySet.m */; };
1A062C8911B28D8A00727C1D /* NSObjectOOExtensions.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A062C8711B28D8A00727C1D /* NSObjectOOExtensions.h */; };
1A062C8A11B28D8A00727C1D /* NSObjectOOExtensions.m in Sources */ = {isa = PBXBuildFile; fileRef = 1A062C8811B28D8A00727C1D /* NSObjectOOExtensions.m */; };
1A06F2861196E5B100AFA5B4 /* OOCASoundDebugMonitor.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A06F2851196E5B100AFA5B4 /* OOCASoundDebugMonitor.h */; };
1A06F3151196FB6F00AFA5B4 /* oolite-player-AI.plist in Copy AIs */ = {isa = PBXBuildFile; fileRef = 1A06F3141196FB6F00AFA5B4 /* oolite-player-AI.plist */; };
1A0729D90EF56D1200B0F925 /* OOConvertSystemDescriptions.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A0729D70EF56D1200B0F925 /* OOConvertSystemDescriptions.h */; };
@ -1166,6 +1168,8 @@
1A047B7D0DCB3D7500EE1CD0 /* OOProbabilitySet.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OOProbabilitySet.m; sourceTree = "<group>"; };
1A0517D10C7B376700BA5CCA /* debug-exports.exp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.exports; path = "debug-exports.exp"; sourceTree = "<group>"; };
1A0519340C7CCAC900BA5CCA /* DebugOXP.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = DebugOXP.xcodeproj; path = DebugOXP/DebugOXP.xcodeproj; sourceTree = SOURCE_ROOT; };
1A062C8711B28D8A00727C1D /* NSObjectOOExtensions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NSObjectOOExtensions.h; sourceTree = "<group>"; };
1A062C8811B28D8A00727C1D /* NSObjectOOExtensions.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = NSObjectOOExtensions.m; sourceTree = "<group>"; };
1A06F2851196E5B100AFA5B4 /* OOCASoundDebugMonitor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OOCASoundDebugMonitor.h; sourceTree = "<group>"; };
1A06F3141196FB6F00AFA5B4 /* oolite-player-AI.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist; path = "oolite-player-AI.plist"; sourceTree = "<group>"; };
1A0729D70EF56D1200B0F925 /* OOConvertSystemDescriptions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OOConvertSystemDescriptions.h; sourceTree = "<group>"; };
@ -2754,6 +2758,8 @@
1A00C65410663D3700A8737D /* OOProfilingStopwatch.m */,
1AEB4918119D5AAA007BD514 /* OORegExpMatcher.h */,
1AEB4919119D5AAA007BD514 /* OORegExpMatcher.m */,
1A062C8711B28D8A00727C1D /* NSObjectOOExtensions.h */,
1A062C8811B28D8A00727C1D /* NSObjectOOExtensions.m */,
);
name = Utilities;
sourceTree = "<group>";
@ -3287,6 +3293,7 @@
1ACB1D1C118DCE5A007B9A1F /* OOTextureInternal.h in Headers */,
1A06F2861196E5B100AFA5B4 /* OOCASoundDebugMonitor.h in Headers */,
1AEB491A119D5AAA007BD514 /* OORegExpMatcher.h in Headers */,
1A062C8911B28D8A00727C1D /* NSObjectOOExtensions.h in Headers */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@ -3654,6 +3661,7 @@
1A95C041118A450E002EE302 /* OOConvertCubeMapToLatLong.m in Sources */,
1ACB1D19118DCBC0007B9A1F /* OOConcreteTexture.m in Sources */,
1AEB491B119D5AAA007BD514 /* OORegExpMatcher.m in Sources */,
1A062C8A11B28D8A00727C1D /* NSObjectOOExtensions.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};

View File

@ -11,9 +11,9 @@ itself (as in the Mac Debug OXP), or provide communications with an external
debugger (for instance, over Distributed Objects or TCP/IP).
Oolite Debug OXP
Oolite debug support
Copyright (C) 2007 Jens Ayton
Copyright (C) 2007-2010 Jens Ayton
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
@ -100,5 +100,7 @@ SOFTWARE.
- (BOOL) debuggerConnected;
- (void) dumpMemoryStatistics;
@end

View File

@ -3,7 +3,7 @@
OODebugMonitor.m
Oolite Debug OXP
Oolite debug support
Copyright (C) 2007-2010 Jens Ayton
@ -42,6 +42,10 @@ SOFTWARE.
#import "OOJavaScriptEngine.h"
#import "OOJSSpecialFunctions.h"
#import "NSObjectOOExtensions.h"
#import "OOTexture.h"
#import "OOConcreteTexture.h"
static OODebugMonitor *sSingleton = nil;
@ -332,6 +336,237 @@ static OODebugMonitor *sSingleton = nil;
}
- (void) writeMemStat:(NSString *)format, ...
{
va_list args;
va_start(args, format);
NSString *message = [[NSString alloc] initWithFormat:format arguments:args];
va_end(args);
OOLog(@"debug.memStats", @"%@", message);
[self appendJSConsoleLine:message colorKey:@"command-result"];
[message release];
}
static NSString *SizeString(size_t size)
{
enum
{
kThreshold = 2 // 2 KiB, 2 MiB etc.
};
unsigned magnitude = 0;
NSString *suffix = @"";
if (size < kThreshold << 10)
{
return [NSString stringWithFormat:@"%zu bytes", size];
}
if (size < kThreshold << 20)
{
magnitude = 1;
suffix = @"KiB";
}
else if (size < (size_t)(kThreshold << 30))
{
magnitude = 2;
suffix = @"MiB";
}
else
{
magnitude = 3;
suffix = @"GiB";
}
float unit = 1 << (magnitude * 10);
float sizef = (float)size / unit;
sizef = roundf(sizef * 100.0f) / 100.f;
return [NSString stringWithFormat:@"%.2f %@", sizef, suffix];
}
typedef struct
{
NSMutableSet *entityTextures;
NSMutableSet *visibleEntityTextures;
unsigned seenCount;
size_t totalEntityObjSize;
size_t totalDrawableSize;
} EntityDumpState;
- (void) dumpEntity:(id)entity withState:(EntityDumpState *)state parentVisible:(BOOL)parentVisible
{
state->seenCount++;
size_t entitySize = [entity oo_objectSize];
size_t drawableSize = 0;
if ([entity isKindOfClass:[OOEntityWithDrawable class]])
{
OODrawable *drawable = [entity drawable];
drawableSize = [drawable totalSize];
}
BOOL visible = parentVisible && [entity isVisible];
NSSet *textures = [entity allTextures];
if (textures != nil)
{
[state->entityTextures unionSet:textures];
if (visible) [state->visibleEntityTextures unionSet:textures];
}
NSString *extra = @"";
if (visible)
{
extra = [extra stringByAppendingString:@", visible"];
}
if (drawableSize != 0)
{
extra = [extra stringByAppendingFormat:@", drawable: %@", SizeString(drawableSize)];
}
[self writeMemStat:@"%@: %@%@", [entity shortDescription], SizeString(entitySize), extra];
state->totalEntityObjSize += entitySize;
state->totalDrawableSize += drawableSize;
if ([entity isShip])
{
OOLogIndent();
NSEnumerator *subEnum = nil;
id subentity;
for (subEnum = [entity subEntityEnumerator]; (subentity = [subEnum nextObject]); )
{
[self dumpEntity:subentity withState:state parentVisible:visible];
}
OOLogOutdent();
}
}
- (void) dumpMemoryStatistics
{
OOLog(@"debug.memStats", @"Memory statistics:");
OOLogIndent();
// Get texture retain counts before the entity dumper starts messing with them.
NSArray *inUseTextures = [OOTexture inUseTextures];
NSMutableDictionary *textureRefCounts = [NSMutableDictionary dictionaryWithCapacity:[inUseTextures count]];
OOTexture *tex = nil;
NSEnumerator *texEnum = nil;
for (texEnum = [inUseTextures objectEnumerator]; (tex = [texEnum nextObject]); )
{
// We subtract one because the inUseTextures array retains the textures.
[textureRefCounts setObject:[NSNumber numberWithUnsignedInt:[tex retainCount] - 1] forKey:[NSValue valueWithNonretainedObject:tex]];
}
[self writeMemStat:@"Entitites:"];
OOLogIndent();
NSArray *entities = [UNIVERSE entityList];
EntityDumpState entityDumpState =
{
.entityTextures = [NSMutableSet set],
.visibleEntityTextures = [NSMutableSet set]
};
id entity = nil;
NSEnumerator *entityEnum = nil;
for (entityEnum = [entities objectEnumerator]; (entity = [entityEnum nextObject]); )
{
[self dumpEntity:entity withState:&entityDumpState parentVisible:YES];
}
OOLogOutdent();
[self writeMemStat:@"Total entity size (excluding %u entities not accounted for): %@ (%@ entity objects, %@ drawables)",
gLiveEntityCount - entityDumpState.seenCount,
SizeString(entityDumpState.totalEntityObjSize + entityDumpState.totalDrawableSize),
SizeString(entityDumpState.totalEntityObjSize),
SizeString(entityDumpState.totalDrawableSize)];
NSMutableArray *textures = [[[OOTexture cachedTexturesByAge] mutableCopy] autorelease];
/* inUseTextures contains all the cached textures by definition. However,
we use this merging approach so that textures that cached textures are
listed by age (freshest first) followed by any live textures not in
the cache.
*/
for (texEnum = [inUseTextures objectEnumerator]; (tex = [texEnum nextObject]); )
{
if ([textures indexOfObject:tex] == NSNotFound)
{
[textures addObject:tex];
}
}
size_t totalTextureObjSize = 0;
size_t totalTextureDataSize = 0;
size_t visibleTextureDataSize = 0;
[self writeMemStat:@"Textures:"];
OOLogIndent();
for (texEnum = [textures objectEnumerator]; (tex = [texEnum nextObject]); )
{
size_t objSize = [tex oo_objectSize];
size_t dataSize = [tex dataSize];
#if OOTEXTURE_RELOADABLE
NSString *byteCountSuffix = @"";
#else
NSString *byteCountSuffix = @" (* 2)";
#endif
NSString *usage = @"";
if ([entityDumpState.visibleEntityTextures containsObject:tex])
{
visibleTextureDataSize += dataSize; // NOT doubled if !OOTEXTURE_RELOADABLE, because we're interested in what the GPU sees.
usage = @", visible";
}
else if ([entityDumpState.entityTextures containsObject:tex])
{
usage = @", active";
}
unsigned refCount = [textureRefCounts oo_unsignedIntForKey:[NSValue valueWithNonretainedObject:tex]];
[self writeMemStat:@"%@: [%u refs%@] %@%@",
[tex name],
refCount,
usage,
SizeString(objSize + dataSize),
byteCountSuffix];
totalTextureDataSize += dataSize;
totalTextureObjSize += objSize;
}
OOLogOutdent();
#if !OOTEXTURE_RELOADABLE
totalTextureDataSize *= 2;
#endif
[self writeMemStat:@"Total texture size: %@ (%@ object overhead, %@ data, %@ visible texture data)",
SizeString(totalTextureObjSize + totalTextureDataSize),
SizeString(totalTextureObjSize),
SizeString(totalTextureDataSize),
SizeString(visibleTextureDataSize)];
[self writeMemStat:@"Total entity + texture size: %@", SizeString(totalTextureObjSize + totalTextureDataSize + entityDumpState.totalEntityObjSize + entityDumpState.totalDrawableSize)];
OOLogOutdent();
}
- (NSString *)sourceCodeForFile:(in NSString *)filePath line:(in unsigned)line
{
id linesForFile = nil;

View File

@ -42,6 +42,7 @@ SOFTWARE.
#import "OOConstToString.h"
#import "OOOpenGLExtensionManager.h"
#import "OODebugFlags.h"
#import "OODebugMonitor.h"
@interface Entity (OODebugInspector)
@ -73,6 +74,7 @@ static JSBool ConsoleIsExecutableJavaScript(JSContext *context, JSObject *this,
static JSBool ConsoleDisplayMessagesInClass(JSContext *context, JSObject *this, uintN argc, jsval *argv, jsval *outResult);
static JSBool ConsoleSetDisplayMessagesInClass(JSContext *context, JSObject *this, uintN argc, jsval *argv, jsval *outResult);
static JSBool ConsoleWriteLogMarker(JSContext *context, JSObject *this, uintN argc, jsval *argv, jsval *outResult);
static JSBool ConsoleWriteMemoryStats(JSContext *context, JSObject *this, uintN argc, jsval *argv, jsval *outResult);
static JSBool ConsoleSettingsDeleteProperty(JSContext *context, JSObject *this, jsval name, jsval *outValue);
static JSBool ConsoleSettingsGetProperty(JSContext *context, JSObject *this, jsval name, jsval *outValue);
@ -84,14 +86,14 @@ static JSClass sConsoleClass =
"Console",
JSCLASS_HAS_PRIVATE | JSCLASS_IS_ANONYMOUS,
JS_PropertyStub, // addProperty
JS_PropertyStub, // delProperty
ConsoleGetProperty, // getProperty
ConsoleSetProperty, // setProperty
JS_EnumerateStub, // enumerate
JS_ResolveStub, // resolve
JS_ConvertStub, // convert
ConsoleFinalize, // finalize
JS_PropertyStub, // addProperty
JS_PropertyStub, // delProperty
ConsoleGetProperty, // getProperty
ConsoleSetProperty, // setProperty
JS_EnumerateStub, // enumerate
JS_ResolveStub, // resolve
JS_ConvertStub, // convert
ConsoleFinalize, // finalize
JSCLASS_NO_OPTIONAL_MEMBERS
};
@ -162,16 +164,17 @@ static JSPropertySpec sConsoleProperties[] =
static JSFunctionSpec sConsoleMethods[] =
{
// JS name Function min args
{ "consoleMessage", ConsoleConsoleMessage, 2 },
{ "clearConsole", ConsoleClearConsole, 0 },
{ "scriptStack", ConsoleScriptStack, 0 },
{ "inspectEntity", ConsoleInspectEntity, 1 },
{ "__callObjCMethod", ConsoleCallObjCMethod, 1 },
{ "isExecutableJavaScript", ConsoleIsExecutableJavaScript, 2 },
{ "displayMessagesInClass", ConsoleDisplayMessagesInClass, 1 },
{ "setDisplayMessagesInClass", ConsoleSetDisplayMessagesInClass, 2 },
{ "writeLogMarker", ConsoleWriteLogMarker, 0 },
// JS name Function min args
{ "consoleMessage", ConsoleConsoleMessage, 2 },
{ "clearConsole", ConsoleClearConsole, 0 },
{ "scriptStack", ConsoleScriptStack, 0 },
{ "inspectEntity", ConsoleInspectEntity, 1 },
{ "__callObjCMethod", ConsoleCallObjCMethod, 1 },
{ "isExecutableJavaScript", ConsoleIsExecutableJavaScript, 2 },
{ "displayMessagesInClass", ConsoleDisplayMessagesInClass, 1 },
{ "setDisplayMessagesInClass", ConsoleSetDisplayMessagesInClass, 2 },
{ "writeLogMarker", ConsoleWriteLogMarker, 0 },
{ "writeMemoryStats", ConsoleWriteMemoryStats, 0 },
{ 0 }
};
@ -181,14 +184,14 @@ static JSClass sConsoleSettingsClass =
"ConsoleSettings",
JSCLASS_HAS_PRIVATE,
JS_PropertyStub, // addProperty
ConsoleSettingsDeleteProperty, // delProperty
ConsoleSettingsGetProperty, // getProperty
ConsoleSettingsSetProperty, // setProperty
JS_EnumerateStub, // enumerate. FIXME: this should work.
JS_ResolveStub, // resolve
JS_ConvertStub, // convert
ConsoleFinalize, // finalize (same as Console)
JS_PropertyStub, // addProperty
ConsoleSettingsDeleteProperty, // delProperty
ConsoleSettingsGetProperty, // getProperty
ConsoleSettingsSetProperty, // setProperty
JS_EnumerateStub, // enumerate. FIXME: this should work.
JS_ResolveStub, // resolve
JS_ConvertStub, // convert
ConsoleFinalize, // finalize (same as Console)
JSCLASS_NO_OPTIONAL_MEMBERS
};
@ -659,4 +662,12 @@ static JSBool ConsoleWriteLogMarker(JSContext *context, JSObject *this, uintN ar
return YES;
}
// function writeMemoryStats() : void
static JSBool ConsoleWriteMemoryStats(JSContext *context, JSObject *this, uintN argc, jsval *argv, jsval *outResult)
{
[[OODebugMonitor sharedDebugMonitor] dumpMemoryStatistics];
return YES;
}
#endif /* OO_EXCLUDE_DEBUG_SUPPORT */

View File

@ -248,6 +248,8 @@ extern size_t gTotalEntityMemory;
#ifndef NDEBUG
- (NSString *) descriptionForObjDumpBasic;
- (NSString *) descriptionForObjDump;
- (NSSet *) allTextures;
#endif
@end

View File

@ -1005,6 +1005,12 @@ static NSString * const kOOLogEntityUpdateError = @"entity.linkedList.update.
return result;
}
- (NSSet *) allTextures
{
return nil;
}
#endif

View File

@ -88,4 +88,12 @@ MA 02110-1301, USA.
if ([UNIVERSE wireframeGraphics]) GLDebugWireframeModeOff();
}
#ifndef NDEBUG
- (NSSet *) allTextures
{
return [[self drawable] allTextures];
}
#endif
@end

View File

@ -297,6 +297,14 @@ static OOTexture *sBlobTexture = nil;
return YES;
}
#ifndef NDEBUG
- (NSSet *) allTextures
{
return [NSSet setWithObject:[self texture]];
}
#endif
@end

View File

@ -980,6 +980,14 @@ static void DrawQuadForView(GLfloat x, GLfloat y, GLfloat z, GLfloat xx, GLfloat
return YES;
}
#ifndef NDEBUG
- (NSSet *) allTextures
{
return [NSSet setWithObject:texture];
}
#endif
@end

View File

@ -337,4 +337,12 @@ static OOBasicMaterial *sDefaultMaterial = nil;
return ![UNIVERSE reducedDetail];
}
#ifndef NDEBUG
- (NSSet *) allTextures
{
return [NSSet set];
}
#endif
@end

View File

@ -67,6 +67,10 @@ SOFTWARE.
#if GL_EXT_texture_filter_anisotropic
float _anisotropy;
#endif
#ifndef NDEBUG
NSString *_name;
#endif
}
- (id) initWithLoader:(OOTextureLoader *)loader

View File

@ -38,6 +38,10 @@
#import "OOCache.h"
#import "OOPixMap.h"
#ifndef NDEBUG
#import "OOTextureGenerator.h"
#endif
#if OOLITE_BIG_ENDIAN
#define RGBA_IMAGE_TYPE GL_UNSIGNED_INT_8_8_8_8_REV
@ -104,6 +108,13 @@ static BOOL DecodeFormat(OOTextureDataFormat format, uint32_t options, GLenum *o
_lodBias = lodBias;
#endif
#ifndef NDEBUG
if ([loader isKindOfClass:[OOTextureGenerator class]])
{
_name = [[NSString alloc] initWithFormat:@"<%@>", [loader class]];
}
#endif
_key = [key copy];
[self addToCaches];
@ -163,6 +174,10 @@ static BOOL DecodeFormat(OOTextureDataFormat format, uint32_t options, GLenum *o
DESTROY(_loader);
#ifndef NDEBUG
DESTROY(_name);
#endif
[super dealloc];
}
@ -197,6 +212,44 @@ static BOOL DecodeFormat(OOTextureDataFormat format, uint32_t options, GLenum *o
}
#ifndef NDEBUG
- (NSString *) name
{
if (_name != nil) return _name;
#if OOTEXTURE_RELOADABLE
NSString *name = [_path lastPathComponent];
#else
name = [[[self cacheKey] substringToIndex:@":"] lastPathComponent];
#endif
NSString *channelSuffix = nil;
switch (_options & kOOTextureExtractChannelMask)
{
case kOOTextureExtractChannelR:
channelSuffix = @":r";
break;
case kOOTextureExtractChannelG:
channelSuffix = @":g";
break;
case kOOTextureExtractChannelB:
channelSuffix = @":b";
break;
case kOOTextureExtractChannelA:
channelSuffix = @":a";
break;
}
if (channelSuffix != nil) name = [name stringByAppendingString:channelSuffix];
return name;
}
#endif
- (void)apply
{
OO_ENTER_OPENGL();
@ -237,6 +290,14 @@ static BOOL DecodeFormat(OOTextureDataFormat format, uint32_t options, GLenum *o
}
- (BOOL) isMipMapped
{
[self ensureFinishedLoading];
return _mipLevels != 0;
}
- (struct OOPixMap) copyPixMapRepresentation
{
[self ensureFinishedLoading];

View File

@ -76,6 +76,10 @@ SOFTWARE.
- (OOUInteger) countOfTextureUnitsWithBaseCoordinates;
#endif
#ifndef NDEBUG
- (NSSet *) allTextures;
#endif
@end

View File

@ -122,6 +122,14 @@ static OOMaterial *sActiveMaterial = nil;
}
#endif
#ifndef NDEBUG
- (NSSet *) allTextures
{
return nil;
}
#endif
@end

View File

@ -207,6 +207,15 @@ SOFTWARE.
OOGL(glActiveTextureARB(GL_TEXTURE0_ARB));
}
#ifndef NDEBUG
- (NSSet *) allTextures
{
if (_diffuseMap == nil) return [NSSet setWithObject:_emissionMap];
return [NSSet setWithObjects:_diffuseMap, _emissionMap, nil];
}
#endif
@end
#endif /* OO_MULTITEXTURE */

View File

@ -59,11 +59,25 @@ static OONullTexture *sSingleton = nil;
}
- (BOOL) isMipMapped
{
return NO;
}
- (void) forceRebind
{
}
#ifndef NDEBUG
- (NSString *) name
{
return @"<null texture>";
}
#endif
@end

View File

@ -662,6 +662,14 @@ static NSString *MacrosToString(NSDictionary *macros);
return YES;
}
#ifndef NDEBUG
- (NSSet *) allTextures
{
return [NSSet setWithObjects:textures count:texCount];
}
#endif
@end

View File

@ -121,4 +121,12 @@ SOFTWARE.
return [_texture isCubeMap];
}
#ifndef NDEBUG
- (NSSet *) allTextures
{
return [NSSet setWithObject:_texture];
}
#endif
@end

View File

@ -188,6 +188,11 @@ typedef enum
*/
- (NSSize) dimensions;
/* Check whether texture is mip-mapped.
This will block until loading is completed.
*/
- (BOOL) isMipMapped;
/* Create a new pixmap with a copy of the texture data. The caller is
responsible for free()ing the resulting buffer.
*/
@ -238,6 +243,13 @@ typedef enum
#ifndef NDEBUG
- (void) setTrace:(BOOL)trace;
+ (NSArray *) cachedTexturesByAge;
+ (NSArray *) inUseTextures;
- (size_t) dataSize;
- (NSString *) name;
#endif
@end

View File

@ -314,6 +314,13 @@ static NSString *sGlobalTraceContext = nil;
}
- (BOOL) isMipMapped
{
OOLogGenericSubclassResponsibility();
return NO;
}
- (struct OOPixMap) copyPixMapRepresentation
{
return kOONullPixMap;
@ -382,11 +389,50 @@ static NSString *sGlobalTraceContext = nil;
}
_trace = trace;
}
+ (NSArray *) cachedTexturesByAge
{
return [sRecentTextures objectsByAge];
}
+ (NSArray *) inUseTextures
{
NSMutableArray *result = [NSMutableArray arrayWithCapacity:[sInUseTextures count]];
NSValue *box = nil;
NSEnumerator *texEnum = nil;
for (texEnum = [sInUseTextures objectEnumerator]; (box = [texEnum nextObject]); )
{
[result addObject:[box pointerValue]];
}
return result;
}
- (size_t) dataSize
{
NSSize dimensions = [self dimensions];
size_t size = dimensions.width * dimensions.height;
if ([self isCubeMap]) size *= 6;
if ([self isMipMapped]) size = size * 4 / 3;
return size;
}
- (NSString *) name
{
OOLogGenericSubclassResponsibility();
return nil;
}
#endif
- (void) forceRebind
{
OOLogGenericSubclassResponsibility();
}

View File

@ -79,4 +79,6 @@ MA 02110-1301, USA.
- (NSString *)name;
- (void)setName:(NSString *)name;
- (NSArray *) objectsByAge;
@end

View File

@ -146,6 +146,7 @@ static BOOL CacheRemove(OOCacheImpl *cache, id key);
static BOOL CacheRemoveOldest(OOCacheImpl *cache, NSString *logKey);
static id CacheRetrieve(OOCacheImpl *cache, id key);
static unsigned CacheGetCount(OOCacheImpl *cache);
static NSArray *CacheArrayOfContentsByAge(OOCacheImpl *cache);
static NSArray *CacheArrayOfNodesByAge(OOCacheImpl *cache);
static NSString *CacheGetName(OOCacheImpl *cache);
static void CacheSetName(OOCacheImpl *cache, NSString *name);
@ -352,6 +353,12 @@ static void CacheSetName(OOCacheImpl *cache, NSString *name);
CacheSetName(cache, name);
}
- (NSArray *) objectsByAge
{
return CacheArrayOfContentsByAge(cache);
}
@end
@ -526,6 +533,23 @@ static id CacheRetrieve(OOCacheImpl *cache, id key)
}
static NSArray *CacheArrayOfContentsByAge(OOCacheImpl *cache)
{
OOCacheNode *node = NULL;
NSMutableArray *result = nil;
if (cache == NULL || cache->count == 0) return nil;
result = [NSMutableArray arrayWithCapacity:cache->count];
for (node = cache->youngest; node != NULL; node = node->older)
{
[result addObject:node->value];
}
return result;
}
static NSArray *CacheArrayOfNodesByAge(OOCacheImpl *cache)
{
OOCacheNode *node = NULL;

View File

@ -53,4 +53,9 @@ SOFTWARE.
- (void)dumpSelfState;
#ifndef NDEBUG
- (NSSet *) allTextures;
- (size_t) totalSize; // Size including dynamic data, not counting textures.
#endif
@end

View File

@ -26,6 +26,7 @@ SOFTWARE.
*/
#import "OODrawable.h"
#import "NSObjectOOExtensions.h"
@implementation OODrawable
@ -89,4 +90,18 @@ SOFTWARE.
}
#ifndef NDEBUG
- (NSSet *) allTextures
{
return nil;
}
- (size_t) totalSize
{
return [self oo_objectSize];
}
#endif
@end

View File

@ -51,6 +51,7 @@ MA 02110-1301, USA.
#import "OOMacroOpenGL.h"
#import "OOProfilingStopwatch.h"
#import "OODebugFlags.h"
#import "NSObjectOOExtensions.h"
// If set, collision octree depth varies depending on the size of the mesh.
@ -741,6 +742,42 @@ static NSString *NormalModeDescription(OOMeshNormalMode mode)
#endif
#ifndef NDEBUG
- (NSSet *) allTextures
{
NSMutableSet *result = [NSMutableSet set];
OOMeshMaterialCount i;
for (i = 0; i != materialCount; i++)
{
[result unionSet:[materials[i] allTextures]];
}
return result;
}
- (size_t) totalSize
{
size_t result = [super totalSize];
if (_vertices != NULL) result += sizeof *_vertices * vertexCount;
if (_normals != NULL) result += sizeof *_normals * vertexCount;
if (_tangents != NULL) result += sizeof *_tangents * vertexCount;
if (_faces != NULL) result += sizeof *_faces * faceCount;
result += _displayLists.count * (sizeof (GLint) + sizeof (GLfloat) + sizeof (Vector) * 3);
OOMeshMaterialCount i;
for (i = 0; i != materialCount; i++)
{
result += [materials[i] oo_objectSize];
}
result += [octree totalSize];
return result;
}
#endif
/* This method exists purely to suppress Clang static analyzer warnings that
these ivars are unused (but may be used by categories, which they are).
FIXME: there must be a feature macro we can use to avoid actually building

View File

@ -374,6 +374,12 @@
OODebugEndWireframe(state);
}
- (NSSet *) allTextures
{
return [[self material] allTextures];
}
#endif
@end

View File

@ -34,6 +34,7 @@ SOFTWARE.
#import "OOGraphicsResetManager.h"
#import "Universe.h"
#import "OOMacroOpenGL.h"
#import "NSObjectOOExtensions.h"
#define SKY_ELEMENT_SCALE_FACTOR (BILLBOARD_DEPTH / 500.0f)
@ -88,6 +89,11 @@ enum
- (void)render;
#ifndef NDEBUG
- (size_t) totalSize;
- (OOTexture *) texture;
#endif
@end
@ -240,6 +246,37 @@ static OOColor *SaturatedColorInRange(OOColor *color1, OOColor *color2);
return INFINITY;
}
#ifndef NDEBUG
- (NSSet *) allTextures
{
NSMutableSet *result = [NSMutableSet setWithCapacity:[_quadSets count]];
NSEnumerator *quadSetEnum = nil;
OOSkyQuadSet *quadSet = nil;
for (quadSetEnum = [_quadSets objectEnumerator]; (quadSet = [quadSetEnum nextObject]); )
{
[result addObject:[quadSet texture]];
}
return result;
}
- (size_t) totalSize
{
size_t result = [super totalSize];
NSEnumerator *quadSetEnum = nil;
OOSkyQuadSet *quadSet = nil;
for (quadSetEnum = [_quadSets objectEnumerator]; (quadSet = [quadSetEnum nextObject]); )
{
result += [quadSet totalSize];
}
return result;
}
#endif
@end
@ -631,6 +668,20 @@ static OOColor *DebugColor(Vector orientation)
OOGL(glDrawArrays(GL_QUADS, 0, 4 * _count));
}
#ifndef NDEBUG
- (size_t) totalSize
{
return [self oo_objectSize] + _count * 4 * (sizeof *_positions + sizeof *_texCoords + sizeof *_colors);
}
- (OOTexture *) texture
{
return _texture;
}
#endif
@end

View File

@ -91,4 +91,9 @@ GLfloat volumeOfOctree(Octree_details octree_details);
Vector randomFullNodeFrom( Octree_details details, Vector offset);
#ifndef NDEBUG
- (size_t) totalSize;
#endif
@end

View File

@ -29,6 +29,7 @@ MA 02110-1301, USA.
#import "OODebugGLDrawing.h"
#import "OOMacroOpenGL.h"
#import "OODebugFlags.h"
#import "NSObjectOOExtensions.h"
#ifndef NDEBUG
@ -768,4 +769,12 @@ Vector randomFullNodeFrom( Octree_details details, Vector offset)
return offset;
}
#ifndef NDEBUG
- (size_t) totalSize
{
return [self oo_objectSize] + leafs * (sizeof *octree + sizeof *octree_collision);
}
#endif
@end

View File

@ -299,6 +299,7 @@ enum
- (int) obj_count;
#ifndef NDEBUG
- (void) obj_dump;
- (NSArray *) entityList;
#endif
- (void) sleepytime:(id) thing;

View File

@ -435,6 +435,12 @@ static OOComparisonResult comparePrice(id dict1, id dict2, void * context);
OOLog(@"universe.objectDump", @"entities = %@", [entities description]);
}
}
- (NSArray *) entityList
{
return [NSArray arrayWithArray:entities];
}
#endif