summaryrefslogtreecommitdiff
path: root/Runtime/Graphics/ProceduralCache.cpp
diff options
context:
space:
mode:
authorchai <chaifix@163.com>2019-08-14 22:50:43 +0800
committerchai <chaifix@163.com>2019-08-14 22:50:43 +0800
commit15740faf9fe9fe4be08965098bbf2947e096aeeb (patch)
treea730ec236656cc8cab5b13f088adfaed6bb218fb /Runtime/Graphics/ProceduralCache.cpp
+Unity Runtime codeHEADmaster
Diffstat (limited to 'Runtime/Graphics/ProceduralCache.cpp')
-rw-r--r--Runtime/Graphics/ProceduralCache.cpp154
1 files changed, 154 insertions, 0 deletions
diff --git a/Runtime/Graphics/ProceduralCache.cpp b/Runtime/Graphics/ProceduralCache.cpp
new file mode 100644
index 0000000..9ae3176
--- /dev/null
+++ b/Runtime/Graphics/ProceduralCache.cpp
@@ -0,0 +1,154 @@
+#include "UnityPrefix.h"
+#include "ProceduralMaterial.h"
+#include "SubstanceSystem.h"
+#include "Runtime/Misc/CachingManager.h"
+#include "Runtime/Utilities/FileUtilities.h"
+#include "Runtime/Graphics/Image.h"
+
+#if ENABLE_SUBSTANCE && ENABLE_CACHING && !UNITY_EDITOR
+bool ProceduralMaterial::PreProcess(std::set<unsigned int>& cachedTextureIDs)
+{
+ if (m_LoadingBehavior!=ProceduralLoadingBehavior_Cache)
+ return false;
+
+ std::string cacheFolder = GetCacheFolder();
+ std::vector<string> fileNames;
+ CachingManager::ReadInfoFile(cacheFolder, NULL, &fileNames);
+ if (fileNames.size()==0)
+ return false;
+
+ bool success = true;
+ std::map<ProceduralTexture*, SubstanceTexture> cachedTextures;
+ for (PingedTextures::iterator it=m_PingedTextures.begin();it!=m_PingedTextures.end() ; ++it)
+ {
+ if (*it!=NULL)
+ {
+ std::string fileName;
+ if (ReadCachedTexture(fileName, cachedTextures, cacheFolder, **it))
+ {
+ cachedTextureIDs.insert((*it)->GetSubstanceBaseTextureUID());
+ }
+ else
+ {
+ success = false;
+ DeleteFileOrDirectory(fileName);
+ std::vector<string>::iterator it = std::find(fileNames.begin(), fileNames.end(), fileName);
+ if (it!=fileNames.end())
+ fileNames.erase(it);
+ }
+ }
+ }
+ GetSubstanceSystem().ForceSubstanceResults(cachedTextures);
+
+ if (fileNames.size()==0)
+ {
+ DeleteFileOrDirectory(cacheFolder);
+ return false;
+ }
+
+ time_t timestamp = CachingManager::GenerateTimeStamp();
+ CachingManager::WriteInfoFile(cacheFolder, fileNames, timestamp);
+ GetCachingManager().GetCurrentCache().UpdateTimestamp(cacheFolder, timestamp);
+
+ if (success)
+ m_LoadingBehavior = ProceduralLoadingBehavior_Generate;
+ return success;
+}
+
+void ProceduralMaterial::PostProcess(const std::map<ProceduralTexture*, SubstanceTexture>& textures, const std::set<unsigned int>& cachedTextureIDs)
+{
+ if (m_LoadingBehavior!=ProceduralLoadingBehavior_Cache)
+ return;
+ m_LoadingBehavior = ProceduralLoadingBehavior_Generate;
+
+ std::string cacheFolder = GetCacheFolder();
+ std::vector<string> fileNames;
+ CachingManager::ReadInfoFile(cacheFolder, NULL, &fileNames);
+ for (std::map<ProceduralTexture*, SubstanceTexture>::const_iterator it=textures.begin() ; it!=textures.end() ; ++it)
+ {
+ if (it->first!=NULL && cachedTextureIDs.find(it->first->GetSubstanceBaseTextureUID())==cachedTextureIDs.end())
+ {
+ std::string fileName;
+ bool result = WriteCachedTexture(fileName, cacheFolder, *it->first, it->second);
+ std::vector<string>::iterator it = std::find(fileNames.begin(), fileNames.end(), fileName);
+ if (result)
+ {
+ if (it==fileNames.end())
+ fileNames.push_back(fileName);
+ }
+ else
+ {
+ DeleteFileOrDirectory(fileName);
+ if (it!=fileNames.end())
+ fileNames.erase(it);
+ }
+ }
+ }
+ if (fileNames.size()==0)
+ {
+ DeleteFileOrDirectory(cacheFolder);
+ }
+ else
+ {
+ GetCachingManager().WriteInfoFile(cacheFolder, fileNames);
+ }
+}
+
+std::string ProceduralMaterial::GetCacheFolder() const
+{
+ std::string hash;
+ char hashValue[6];
+ for (int i=0 ; i<16 ; ++i)
+ {
+ snprintf(hashValue, 6, "%d", (int)m_Hash.hashData.bytes[i]);
+ hash += hashValue;
+ }
+ return GetCachingManager().GetCurrentCache().GetFolder(hash.c_str(), true);
+}
+
+std::string ProceduralMaterial::GetCacheFilename(const ProceduralTexture& texture) const
+{
+ char filename[24];
+ snprintf(filename, 24, "%u.cache", texture.GetSubstanceBaseTextureUID());
+ return filename;
+}
+
+bool ProceduralMaterial::ReadCachedTexture(string& fileName, std::map<ProceduralTexture*, SubstanceTexture>& cachedTextures, const std::string& folder, const ProceduralTexture& texture)
+{
+ fileName = folder+"/"+GetCacheFilename(texture);
+ File file;
+ if (!file.Open(fileName, File::kReadPermission, File::kSilentReturnOnOpenFail))
+ return false;
+ unsigned int infoSize = sizeof(SubstanceTexture);
+ unsigned int textureSize;
+ SubstanceTexture& data = cachedTextures[(ProceduralTexture*)&texture];
+ bool result = file.Read(&data, infoSize)
+ && file.Read(&textureSize, 4)
+ && (data.buffer=SubstanceSystem::OnMalloc(textureSize))!=NULL
+ && file.Read(data.buffer, textureSize);
+ file.Close();
+ return result;
+}
+
+bool ProceduralMaterial::WriteCachedTexture(string& fileName, const std::string& folder, const ProceduralTexture& texture, const SubstanceTexture& data)
+{
+ fileName = folder+"/"+GetCacheFilename(texture);
+ if (IsFileCreated(fileName) && texture.HasBeenUploaded())
+ return true;
+ unsigned int infoSize = sizeof(SubstanceTexture);
+ int mipLevels = data.mipmapCount;
+ if (mipLevels==0)
+ mipLevels = CalculateMipMapCount3D(data.level0Width, data.level0Height, 1);
+ unsigned int textureSize = CalculateMipMapOffset(data.level0Width, data.level0Height, texture.GetSubstanceFormat(), mipLevels+1);
+ if (!GetCachingManager().GetCurrentCache().FreeSpace(infoSize+4+textureSize))
+ return false;
+ File file;
+ if (!file.Open(fileName, File::kWritePermission, File::kSilentReturnOnOpenFail))
+ return false;
+ bool result = file.Write(&data, infoSize)
+ && file.Write(&textureSize, 4)
+ && file.Write(data.buffer, textureSize);
+ file.Close();
+ return result;
+}
+#endif