/*---------------------------------------------------------------------------* Project: NintendoWare File: SmPerf.cpp Copyright (C)2009-2011 Nintendo/HAL Laboratory, Inc. All rights reserved. These coded instructions, statements, and computer programs contain proprietary information of Nintendo and/or its licensed developers and are protected by national and international copyright laws. They may not be disclosed to third parties or copied or duplicated in any form, in whole or in part, without the prior written consent of Nintendo. The content herein is highly confidential and should be handled accordingly. $Revision: $ *---------------------------------------------------------------------------*/ #include #include #include #include "../include/SmPerf.h" namespace { SmGpuPerf* s_GpuPerf = NULL; //---------------------------------------- // コンストラクタ SmCpuPerf::SmCpuPerf() : SmPerf(){} //---------------------------------------- // 計測を開始する void SmCpuPerf::Begin( const char* costName, u32 costColor ) { NW_NULL_ASSERT( costName ); { Cost addCost; addCost.init(); nw::ut::strncpy( addCost.costName, 32, costName, strlen( costName ) ); addCost.costStart = this->GetTime(); addCost.costColor = costColor; bool isPushed = m_CostArray[m_CostArrayFlip].push_back( addCost ); NW_ASSERT(isPushed); m_CurrentCost = m_CostArray[m_CostArrayFlip].size() - 1; } } //---------------------------------------- // 計測を終了する void SmCpuPerf::End() { if ( m_CurrentCost != -1 ) { m_CostArray[m_CostArrayFlip][m_CurrentCost].costEnd = this->GetTime(); m_CostArray[m_CostArrayFlip][m_CurrentCost].costMicro += m_CostArray[m_CostArrayFlip][m_CurrentCost].costEnd - m_CostArray[m_CostArrayFlip][m_CurrentCost].costStart; } } //---------------------------------------- // コンストラクタ SmGpuPerf::SmGpuPerf() : SmPerf() { if ( s_GpuPerf ) { NW_FATAL_ERROR("SmGpuPerf instance is exsit.\n"); } // コールバック関数を登録 nngxSetCmdlistCallback(SmGpuPerf::Callback); // 自身を登録 s_GpuPerf = this; } //---------------------------------------- // デストラクタ SmGpuPerf::~SmGpuPerf() { nngxSetCmdlistCallback(NULL); s_GpuPerf = NULL; } //---------------------------------------- // 計測を開始する void SmGpuPerf::Begin( const char* costName, u32 costColor ) { Cost addCost; addCost.init(); nw::ut::strncpy( addCost.costName, 32, costName, strlen( costName ) ); addCost.costColor = costColor; GLint requestCount = 0; nngxGetCmdlistParameteri(NN_GX_CMDLIST_USED_REQCOUNT, &requestCount); // スタート位置 addCost.gpuStart = requestCount + 1; m_CurrentReqCount = addCost.gpuStart; addCost.constId = m_CostArray[m_CostArrayFlip].size(); m_CurrentCost = addCost.constId; bool isPushed = m_CostArray[m_CostArrayFlip].push_back( addCost ); NW_ASSERT(isPushed); // コールバックを登録 nngxEnableCmdlistCallback( m_CurrentReqCount ); nngxSplitDrawCmdlist(); NW_GL_ASSERT(); } //---------------------------------------- // 計測を終了する void SmGpuPerf::End() { GLint requestCount = 0; nngxGetCmdlistParameteri(NN_GX_CMDLIST_USED_REQCOUNT, &requestCount); m_CostArray[m_CostArrayFlip][m_CurrentCost].gpuEnd = requestCount + 1; m_CurrentReqCount = m_CostArray[m_CostArrayFlip][m_CurrentCost].gpuEnd; nngxEnableCmdlistCallback( m_CurrentReqCount ); nngxSplitDrawCmdlist(); NW_GL_ASSERT(); } //---------------------------------------- // コールバックの呼び出しです。 void SmGpuPerf::Invoke(GLint id) { // id で指定されるコストがあるか検索 uint i = 0; for ( i=0; iGetTime(); } if ( m_CostArray[m_CostArrayFlip][i].gpuEnd == id ) { m_CostArray[m_CostArrayFlip][i].costEnd = this->GetTime(); } } } //---------------------------------------- // 登録するコールバック関数です void SmGpuPerf::Callback(GLint id) { if ( s_GpuPerf ) { s_GpuPerf->Invoke(id); } } //---------------------------------------- // リセットする void SmGpuPerf::Reset() { uint i = 0; s64 cost = 0; for ( i = 0; i < m_CostArray[m_CostArrayFlip].size(); i++ ) { cost = m_CostArray[m_CostArrayFlip][i].costEnd - m_CostArray[m_CostArrayFlip][i].costStart; m_CostArray[m_CostArrayFlip][i].costMicro = cost; } SmPerf::Reset(); } // 登録されているコスト(msec)を取得する f32 SmGpuPerf::GetCost( uint costNo ) { f32 millisec = 0.f; if ( m_CostArrayFlip ) { if ( m_CostArray[0].size() > costNo ) { millisec = static_cast(m_CostArray[0][costNo].costMicro) / 1000.f; } } else { if ( m_CostArray[1].size() > costNo ) { millisec = static_cast(m_CostArray[1][costNo].costMicro) / 1000.f; } } return millisec; } //---------------------------------------- // コンストラクタ SmPerfDrawer::SmPerfDrawer() : m_pPerfBarSplit( NULL ) { } //---------------------------------------- // デストラクタ SmPerfDrawer::~SmPerfDrawer() { } //---------------------------------------- // 処理バーを描画する void SmPerfDrawer::Render( SmPerf* cpuPerf, SmPerf* gpuPerf ) { NW_NULL_ASSERT( cpuPerf ); NW_NULL_ASSERT( gpuPerf ); // rectの登録 #define _SET_BAR_RECT( prim, x, y, w, h, color ) \ prim.SetVertex( x, y, color ); \ prim.SetVertex( x, y + h, color ); \ prim.SetVertex( x + w, y + h, color ); \ prim.SetVertex( x + w, y + h, color ); \ prim.SetVertex( x + w, y, color ); \ prim.SetVertex( x, y, color ); \ uint i=0; f32 costLength = 0.f; f32 costLengthTemp = 0.f; f32 cost = 0.f; // 処理バー if ( m_PerfBar.Begin( cpuPerf->GetCostCount() * 6 + gpuPerf->GetCostCount() * 6, GL_TRIANGLES, 0.f, 0.f ) ) { // CPU処理バー for ( i=0; iGetCostCount(); i++ ) { cost = cpuPerf->GetCost(i); costLength = cost/16.f * PERF_ONE_FRAME_WIDTH; _SET_BAR_RECT( m_PerfBar, costLengthTemp, 5.f, costLength, 4.f, cpuPerf->GetCostColor(i) ); costLengthTemp += costLength; } costLengthTemp = 0.f; // GPU処理バー for ( i=0; iGetCostCount(); i++ ) { cost = gpuPerf->GetCost(i); costLength = cost/16.f * PERF_ONE_FRAME_WIDTH; _SET_BAR_RECT( m_PerfBar, costLengthTemp, 20.f, costLength, 4.f, gpuPerf->GetCostColor(i) ); costLengthTemp += costLength; } m_PerfBar.End(); } } } // namespace