瀏覽代碼

Add resource memory usage display to DebugHud

JSandusky 10 年之前
父節點
當前提交
44aac796fb

+ 3 - 0
Source/Urho3D/AngelScript/EngineAPI.cpp

@@ -76,7 +76,9 @@ static void RegisterDebugHud(asIScriptEngine* engine)
     engine->RegisterGlobalProperty("const uint DEBUGHUD_SHOW_STATS", (void*)&DEBUGHUD_SHOW_STATS);
     engine->RegisterGlobalProperty("const uint DEBUGHUD_SHOW_MODE", (void*)&DEBUGHUD_SHOW_MODE);
     engine->RegisterGlobalProperty("const uint DEBUGHUD_SHOW_PROFILER", (void*)&DEBUGHUD_SHOW_PROFILER);
+    engine->RegisterGlobalProperty("const uint DEBUGHUD_SHOW_MEMORY", (void*)&DEBUGHUD_SHOW_MEMORY);
     engine->RegisterGlobalProperty("const uint DEBUGHUD_SHOW_ALL", (void*)&DEBUGHUD_SHOW_ALL);
+    engine->RegisterGlobalProperty("const uint DEBUGHUD_SHOW_ALL_MEMORY", (void*)&DEBUGHUD_SHOW_ALL_MEMORY);
 
     RegisterObject<Console>(engine, "DebugHud");
     engine->RegisterObjectMethod("DebugHud", "void Update()", asMETHOD(DebugHud, Update), asCALL_THISCALL);
@@ -95,6 +97,7 @@ static void RegisterDebugHud(asIScriptEngine* engine)
     engine->RegisterObjectMethod("DebugHud", "Text@+ get_statsText() const", asMETHOD(DebugHud, GetStatsText), asCALL_THISCALL);
     engine->RegisterObjectMethod("DebugHud", "Text@+ get_modeText() const", asMETHOD(DebugHud, GetModeText), asCALL_THISCALL);
     engine->RegisterObjectMethod("DebugHud", "Text@+ get_profilerText() const", asMETHOD(DebugHud, GetProfilerText), asCALL_THISCALL);
+    engine->RegisterObjectMethod("DebugHud", "Text@+ get_memoryText() const", asMETHOD(DebugHud, GetMemoryText), asCALL_THISCALL);
     engine->RegisterObjectMethod("DebugHud", "void SetAppStats(const String&in, const Variant&in)", asMETHODPR(DebugHud, SetAppStats, (const String&, const Variant&), void), asCALL_THISCALL);
     engine->RegisterObjectMethod("DebugHud", "void SetAppStats(const String&in, const String&in)", asMETHODPR(DebugHud, SetAppStats, (const String&, const String&), void), asCALL_THISCALL);
     engine->RegisterObjectMethod("DebugHud", "void ResetAppStats(const String&in)", asMETHOD(DebugHud, ResetAppStats), asCALL_THISCALL);

+ 17 - 0
Source/Urho3D/Engine/DebugHud.cpp

@@ -28,6 +28,7 @@
 #include "../Engine/Engine.h"
 #include "../Graphics/Graphics.h"
 #include "../Graphics/Renderer.h"
+#include "../Resource/ResourceCache.h"
 #include "../IO/Log.h"
 #include "../UI/Font.h"
 #include "../UI/Text.h"
@@ -81,6 +82,12 @@ DebugHud::DebugHud(Context* context) :
     profilerText_->SetVisible(false);
     uiRoot->AddChild(profilerText_);
 
+    memoryText_ = new Text(context_);
+    memoryText_->SetAlignment(HA_RIGHT, VA_TOP);
+    memoryText_->SetPriority(100);
+    memoryText_->SetVisible(false);
+    uiRoot->AddChild(memoryText_);
+
     SubscribeToEvent(E_POSTUPDATE, HANDLER(DebugHud, HandlePostUpdate));
 }
 
@@ -89,6 +96,7 @@ DebugHud::~DebugHud()
     statsText_->Remove();
     modeText_->Remove();
     profilerText_->Remove();
+    memoryText_->Remove();
 }
 
 void DebugHud::Update()
@@ -174,6 +182,12 @@ void DebugHud::Update()
             profiler->BeginInterval();
         }
     }
+
+    if (memoryText_->IsVisible())
+    {
+        ResourceCache* cache = GetSubsystem<ResourceCache>();
+        memoryText_->SetText(cache->PrintMemoryUsage());
+    }
 }
 
 void DebugHud::SetDefaultStyle(XMLFile* style)
@@ -187,6 +201,8 @@ void DebugHud::SetDefaultStyle(XMLFile* style)
     modeText_->SetStyle("DebugHudText");
     profilerText_->SetDefaultStyle(style);
     profilerText_->SetStyle("DebugHudText");
+    memoryText_->SetDefaultStyle(style);
+    memoryText_->SetStyle("DebugHudText");
 }
 
 void DebugHud::SetMode(unsigned mode)
@@ -194,6 +210,7 @@ void DebugHud::SetMode(unsigned mode)
     statsText_->SetVisible((mode & DEBUGHUD_SHOW_STATS) != 0);
     modeText_->SetVisible((mode & DEBUGHUD_SHOW_MODE) != 0);
     profilerText_->SetVisible((mode & DEBUGHUD_SHOW_PROFILER) != 0);
+    memoryText_->SetVisible((mode & DEBUGHUD_SHOW_MEMORY) != 0);
 
     mode_ = mode;
 }

+ 7 - 0
Source/Urho3D/Engine/DebugHud.h

@@ -37,7 +37,9 @@ static const unsigned DEBUGHUD_SHOW_NONE = 0x0;
 static const unsigned DEBUGHUD_SHOW_STATS = 0x1;
 static const unsigned DEBUGHUD_SHOW_MODE = 0x2;
 static const unsigned DEBUGHUD_SHOW_PROFILER = 0x4;
+static const unsigned DEBUGHUD_SHOW_MEMORY = 0x8;
 static const unsigned DEBUGHUD_SHOW_ALL = 0x7;
+static const unsigned DEBUGHUD_SHOW_ALL_MEMORY = 0xB;
 
 /// Displays rendering stats and profiling information.
 class URHO3D_API DebugHud : public Object
@@ -79,6 +81,9 @@ public:
     /// Return profiler text.
     Text* GetProfilerText() const { return profilerText_; }
 
+    /// Return memory text.
+    Text* GetMemoryText() const { return memoryText_; }
+
     /// Return currently shown elements.
     unsigned GetMode() const { return mode_; }
 
@@ -110,6 +115,8 @@ private:
     SharedPtr<Text> modeText_;
     /// Profiling information text.
     SharedPtr<Text> profilerText_;
+    /// Memory stats text.
+    SharedPtr<Text> memoryText_;
     /// Hashmap containing application specific stats.
     HashMap<String, String> appStats_;
     /// Profiler timer.

+ 26 - 0
Source/Urho3D/IO/FileSystem.cpp

@@ -1068,4 +1068,30 @@ bool IsAbsolutePath(const String& pathName)
     return false;
 }
 
+/// Convert a memory size into a formatted size string, of the style "1.5 Mb"
+String GetFileSizeString(unsigned long memorySize)
+{
+    const char* memorySizeStrings = "kMGTPE";
+
+    String output;
+
+    if (memorySize < 1024)
+    {
+        output = String(memorySize) + " b";
+    }
+    else
+    {
+        const int exponent = (int)(log(memorySize) / log(1024));
+        const double majorValue = ((double)memorySize) / pow(1024, exponent);
+        char buffer[64];
+        memset(buffer, 0, 64);
+        sprintf(buffer, "%.1f", majorValue);
+        output = buffer;
+        output += " ";
+        output += (char)(memorySizeStrings[exponent - 1]);
+    }
+
+    return output;
+}
+
 }

+ 2 - 0
Source/Urho3D/IO/FileSystem.h

@@ -150,5 +150,7 @@ URHO3D_API String GetNativePath(const String& pathName);
 URHO3D_API WString GetWideNativePath(const String& pathName);
 /// Return whether a path is absolute.
 URHO3D_API bool IsAbsolutePath(const String& pathName);
+/// Convert a memory size into a formatted size string, of the style "1.5 Mb"
+URHO3D_API String GetFileSizeString(unsigned long memorySize);
 
 }

+ 47 - 0
Source/Urho3D/Resource/ResourceCache.cpp

@@ -36,10 +36,14 @@
 #include "../Resource/PListFile.h"
 #include "../Resource/ResourceCache.h"
 #include "../Resource/ResourceEvents.h"
+#include "../Container/Sort.h"
 #include "../Resource/XMLFile.h"
 
 #include "../DebugNew.h"
 
+#include <cstring>
+#include <cstdio>
+
 namespace Urho3D
 {
 
@@ -907,6 +911,49 @@ void ResourceCache::ResetDependencies(Resource* resource)
     }
 }
 
+String ResourceCache::PrintMemoryUsage() const
+{
+    String output = "Resource Type                            Cnt     Avg      Max     Budget    Total\n\n";
+
+    for (HashMap<StringHash, ResourceGroup>::ConstIterator cit = resourceGroups_.Begin(); cit != resourceGroups_.End(); ++cit)
+    {        
+        const unsigned resourceCt = cit->second_.resources_.Size();
+        unsigned average = 0;
+        if (resourceCt > 0)
+            average = cit->second_.memoryUse_ / resourceCt;
+        else
+            average = 0;
+        unsigned long largest = 0;
+        for (HashMap<StringHash, SharedPtr<Resource> >::ConstIterator resIt = cit->second_.resources_.Begin(); resIt != cit->second_.resources_.End(); ++resIt)
+        {
+            if (resIt->second_->GetMemoryUse() > largest)
+                largest = resIt->second_->GetMemoryUse();
+        }
+        
+        char outputLine[256];
+        memset(outputLine, ' ', 256);
+        outputLine[255] = 0;
+        
+        const String countString(cit->second_.resources_.Size());
+
+        const String memUseString = GetFileSizeString(average);
+
+        const String memMaxString = GetFileSizeString(largest);
+
+        const String memBudgetString = GetFileSizeString(cit->second_.memoryBudget_);
+
+        const String memTotalString = GetFileSizeString(cit->second_.memoryUse_);
+
+        const String resTypeName = context_->GetTypeName(cit->first_);
+
+        sprintf(outputLine, "%-38s %4s %9s %9s %9s %9s\n", resTypeName.CString(), countString.CString(), memUseString.CString(), memMaxString.CString(), memBudgetString.CString(), memTotalString.CString());
+
+        output += outputLine;
+    }
+
+    return output;
+}
+
 const SharedPtr<Resource>& ResourceCache::FindResource(StringHash type, StringHash nameHash)
 {
     MutexLock lock(resourceMutex_);

+ 3 - 0
Source/Urho3D/Resource/ResourceCache.h

@@ -205,6 +205,9 @@ public:
     /// Reset dependencies for a resource.
     void ResetDependencies(Resource* resource);
 
+    /// Returns a formatted string containing the memory actively used.
+    String PrintMemoryUsage() const;
+
 private:
     /// Find a resource.
     const SharedPtr<Resource>& FindResource(StringHash type, StringHash nameHash);