/** * Copyright(c) Live2D Inc. All rights reserved. * * Use of this source code is governed by the Live2D Open Software license * that can be found at https://www.live2d.com/eula/live2d-open-software-license-agreement_en.html. */ #include "CubismFramework.hpp" #include "Utils/CubismDebug.hpp" #include "Utils/CubismJson.hpp" #include "Id/CubismIdManager.hpp" #include "Rendering/CubismRenderer.hpp" #ifdef CSM_DEBUG_MEMORY_LEAKING #include #endif //--------- LIVE2D NAMESPACE ------------ namespace Live2D { namespace Cubism { namespace Framework { // Framework内で使う定数の宣言 namespace Constant { const csmInt32 VertexOffset = 0; const csmInt32 VertexStep = 2; } // ファイルスコープの変数を初期化 namespace { csmBool s_isStarted = false; csmBool s_isInitialized = false; ICubismAllocator* s_allocator = NULL; const CubismFramework::Option* s_option = NULL; CubismIdManager* s_cubismIdManager = NULL; } inline ICubismAllocator* GetAllocator() { return s_allocator; } #ifdef CSM_DEBUG_MEMORY_LEAKING namespace { std::vector* s_allocationList = NULL; } #endif csmBool CubismFramework::StartUp(ICubismAllocator* allocator, const Option* option) { if(s_isStarted) { CubismLogInfo("CubismFramework::StartUp() is already done."); return s_isStarted; } s_option = option; if (s_option != NULL) { Core::csmSetLogFunction(s_option->LogFunction); } if (allocator == NULL) { CubismLogWarning("CubismFramework::StartUp() failed, need allocator instance."); s_isStarted = false; } else { s_allocator = allocator; s_isStarted = true; } // Live2D Cubism Coreバージョン情報を表示 if(s_isStarted) { const Core::csmVersion version = Core::csmGetVersion(); const csmUint32 major = static_cast((version & 0xFF000000) >> 24); const csmUint32 minor = static_cast((version & 0x00FF0000) >> 16); const csmUint32 patch = static_cast((version & 0x0000FFFF)); const csmUint32 vesionNumber = version; CubismLogInfo("Live2D Cubism Core version: %02d.%02d.%04d (%d)", major, minor, patch, vesionNumber); } CubismLogInfo("CubismFramework::StartUp() is complete."); return s_isStarted; } void CubismFramework::CleanUp() { s_isStarted = false; s_isInitialized = false; s_allocator = NULL; s_option = NULL; s_cubismIdManager = NULL; #ifdef CSM_DEBUG_MEMORY_LEAKING s_allocationList = NULL; #endif } csmBool CubismFramework::IsStarted() { return s_isStarted; } void CubismFramework::Initialize() { CSM_ASSERT(s_isStarted); if(!s_isStarted) { CubismLogWarning("CubismFramework is not started."); return; } // --- s_isInitializedによる連続初期化ガード --- // 連続してリソース確保が行われないようにする。 // 再度Initialize()するには先にDispose()を実行する必要がある。 if (s_isInitialized) { CubismLogWarning("CubismFramework::Initialize() skipped, already initialized."); return; } #ifdef CSM_DEBUG_MEMORY_LEAKING s_allocationList = CSM_NEW std::vector(); #endif //---- static 初期化 ---- Utils::Value::StaticInitializeNotForClientCall(); s_cubismIdManager = CSM_NEW CubismIdManager(); s_isInitialized = true; CubismLogInfo("CubismFramework::Initialize() is complete."); } void CubismFramework::Dispose() { CSM_ASSERT(s_isStarted); if (!s_isStarted) { CubismLogWarning("CubismFramework is not started."); return; } // --- s_isInitializedによる未初期化解放ガード --- // Dispose()するには先にInitialize()を実行する必要がある。 if (!s_isInitialized) // false...リソース未確保の場合 { CubismLogWarning("CubismFramework::Dispose() skipped, not initialized."); return; } //---- static 解放 ---- Utils::Value::StaticReleaseNotForClientCall(); CSM_DELETE(s_cubismIdManager); //レンダラの静的リソース(シェーダプログラム他)を解放する Rendering::CubismRenderer::StaticRelease(); #ifdef CSM_DEBUG_MEMORY_LEAKING for (csmUint32 i = 0; i < s_allocationList->size(); ++i) { CubismLogInfo("Memory leaking: 0x%p", s_allocationList->at(i)); } if (s_allocationList->size() == 0) { CubismLogInfo("No memory leaking"); } CSM_DELETE(s_allocationList); #endif s_isInitialized = false; CubismLogInfo("CubismFramework::Dispose() is complete."); } csmBool CubismFramework::IsInitialized() { return s_isInitialized; } void CubismFramework::CoreLogFunction(const csmChar* message) { // Return if logging not possible. if (!Core::csmGetLogFunction()) { return; } Core::csmGetLogFunction()(message); } CubismFramework::Option::LogLevel CubismFramework::GetLoggingLevel() { if (s_option != NULL) { return s_option->LoggingLevel; } return Option::LogLevel_Off; } CubismIdManager* CubismFramework::GetIdManager() { return s_cubismIdManager; } #ifdef CSM_DEBUG_MEMORY_LEAKING void* CubismFramework::Allocate(csmSizeType size, const csmChar* fileName, csmInt32 lineNumber) { void* address = GetAllocator()->Allocate(size); CubismLogVerbose("CubismFramework::Allocate(0x%p, %dbytes) %s(%d)", address, size, fileName, lineNumber); if (s_allocationList) { s_allocationList->push_back(address); } return address; } void* CubismFramework::AllocateAligned(csmSizeType size, csmUint32 alignment, const csmChar* fileName, csmInt32 lineNumber) { void* address = GetAllocator()->AllocateAligned(size, alignment); CubismLogVerbose("CubismFramework::AllocateAligned(0x%p, a:%d, %dbytes) %s(%d)", address, alignment, size, fileName, lineNumber); if (s_allocationList) { s_allocationList->push_back(address); } return address; } void CubismFramework::Deallocate(void* address, const csmChar* fileName, csmInt32 lineNumber) { if (!address) { return; } CubismLogVerbose("CubismFramework::Deallocate(0x%p) %s(%d)", address, fileName, lineNumber); if (s_allocationList) { for (std::vector::iterator iter = s_allocationList->begin(); iter != s_allocationList->end(); ++iter) { if (*iter != address) { continue; } s_allocationList->erase(iter); break; } } GetAllocator()->Deallocate(address); } void CubismFramework::DeallocateAligned(void* address, const csmChar* fileName, csmInt32 lineNumber) { if (!address) { return; } CubismLogVerbose("CubismFramework::DeallocateAligned(0x%p) %s(%d)", address, fileName, lineNumber); if (s_allocationList) { for (std::vector::iterator iter = s_allocationList->begin(); iter != s_allocationList->end(); ++iter) { if (*iter != address) { continue; } s_allocationList->erase(iter); break; } } GetAllocator()->DeallocateAligned(address); } #else void* CubismFramework::Allocate(csmSizeType size) { return GetAllocator()->Allocate(size); } void* CubismFramework::AllocateAligned(csmSizeType size, csmUint32 alignment) { return GetAllocator()->AllocateAligned(size, alignment); } void CubismFramework::Deallocate(void* address) { if (!address) { return; } GetAllocator()->Deallocate(address); } void CubismFramework::DeallocateAligned(void* address) { if (!address) { return; } GetAllocator()->DeallocateAligned(address); } #endif }}} //--------- LIVE2D NAMESPACE ------------ #ifdef CSM_DEBUG_MEMORY_LEAKING void* operator new(Live2D::Cubism::Framework::csmSizeType size, Live2D::Cubism::Framework::CubismAllocationTag tag, const Live2D::Cubism::Framework::csmChar* fileName, Live2D::Cubism::Framework::csmInt32 lineNumber) { return Live2D::Cubism::Framework::CubismFramework::Allocate(size, fileName, lineNumber); } void* operator new (Live2D::Cubism::Framework::csmSizeType size, Live2D::Cubism::Framework::csmUint32 alignment, Live2D::Cubism::Framework::CubismAllocationAlignedTag tag, const Live2D::Cubism::Framework::csmChar* fileName, Live2D::Cubism::Framework::csmInt32 lineNumber) { return Live2D::Cubism::Framework::CubismFramework::AllocateAligned(size, alignment, fileName, lineNumber); } void operator delete(void* address, Live2D::Cubism::Framework::CubismAllocationTag tag, const Live2D::Cubism::Framework::csmChar* fileName, Live2D::Cubism::Framework::csmInt32 lineNumber) { Live2D::Cubism::Framework::CubismFramework::Deallocate(address, fileName, lineNumber); } void operator delete(void* address, Live2D::Cubism::Framework::CubismAllocationAlignedTag tag, const Live2D::Cubism::Framework::csmChar* fileName, Live2D::Cubism::Framework::csmInt32 lineNumber) { Live2D::Cubism::Framework::CubismFramework::DeallocateAligned(address, fileName, lineNumber); } #else void* operator new(Live2D::Cubism::Framework::csmSizeType size, Live2D::Cubism::Framework::CubismAllocationTag tag) { return Live2D::Cubism::Framework::CubismFramework::Allocate(size); } void* operator new (Live2D::Cubism::Framework::csmSizeType size, Live2D::Cubism::Framework::csmUint32 alignment, Live2D::Cubism::Framework::CubismAllocationAlignedTag tag) { return Live2D::Cubism::Framework::CubismFramework::AllocateAligned(size, alignment); } void operator delete(void* address, Live2D::Cubism::Framework::CubismAllocationTag tag) { Live2D::Cubism::Framework::CubismFramework::Deallocate(address); } void operator delete(void* address, Live2D::Cubism::Framework::CubismAllocationAlignedTag tag) { Live2D::Cubism::Framework::CubismFramework::DeallocateAligned(address); } #endif