1 /*---------------------------------------------------------------------------*
2   Project:  NintendoWare
3   File:     SmPerf.cpp
4 
5   Copyright (C)2009-2010 Nintendo Co., Ltd./HAL Laboratory, Inc.  All rights reserved.
6 
7   These coded instructions, statements, and computer programs contain
8   proprietary information of Nintendo of America Inc. and/or Nintendo
9   Company Ltd., and are protected by Federal copyright law.  They may
10   not be disclosed to third parties or copied or duplicated in any form,
11   in whole or in part, without the prior written consent of Nintendo.
12 
13   $Revision: 1 $
14  *---------------------------------------------------------------------------*/
15 #include <nn/os.h>
16 
17 #include <nw/types.h>
18 #include <nw/ut.h>
19 
20 #include "../include/SmPerf.h"
21 
22 namespace
23 {
24 
25 
26 SmGpuPerf* s_GpuPerf = NULL;
27 
28 //----------------------------------------
29 // コンストラクタ
SmCpuPerf()30 SmCpuPerf::SmCpuPerf()
31 : SmPerf(){}
32 
33 
34 //----------------------------------------
35 // 計測を開始する
36 void
Begin(const char * costName,u32 costColor)37 SmCpuPerf::Begin( const char* costName, u32 costColor  )
38 {
39     NW_NULL_ASSERT( costName );
40 
41     {
42         Cost addCost;
43         addCost.init();
44 
45         nw::ut::strncpy( addCost.costName, 32, costName, strlen( costName ) );
46         addCost.costStart = this->GetTime();
47         addCost.costColor = costColor;
48         bool isPushed = m_CostArray[m_CostArrayFlip].push_back( addCost );
49         NW_ASSERT(isPushed);
50 
51         m_CurrentCost = m_CostArray[m_CostArrayFlip].size() - 1;
52     }
53 }
54 
55 
56 //----------------------------------------
57 // 計測を終了する
58 void
End()59 SmCpuPerf::End()
60 {
61     if ( m_CurrentCost != -1 )
62     {
63         m_CostArray[m_CostArrayFlip][m_CurrentCost].costEnd = this->GetTime();
64         m_CostArray[m_CostArrayFlip][m_CurrentCost].costMicro +=
65             m_CostArray[m_CostArrayFlip][m_CurrentCost].costEnd
66                 - m_CostArray[m_CostArrayFlip][m_CurrentCost].costStart;
67     }
68 }
69 
70 
71 
72 
73 //----------------------------------------
74 // コンストラクタ
SmGpuPerf()75 SmGpuPerf::SmGpuPerf()
76 : SmPerf()
77 {
78     if ( s_GpuPerf )
79     {
80         NW_FATAL_ERROR("SmGpuPerf instance is exsit.\n");
81     }
82 
83     // コールバック関数を登録
84     nngxSetCmdlistCallback(SmGpuPerf::Callback);
85 
86     // 自身を登録
87     s_GpuPerf = this;
88 }
89 
90 
91 //----------------------------------------
92 // デストラクタ
~SmGpuPerf()93 SmGpuPerf::~SmGpuPerf()
94 {
95     nngxSetCmdlistCallback(NULL);
96     s_GpuPerf = NULL;
97 }
98 
99 
100 //----------------------------------------
101 // 計測を開始する
102 void
Begin(const char * costName,u32 costColor)103 SmGpuPerf::Begin( const char* costName, u32 costColor  )
104 {
105     Cost addCost;
106     addCost.init();
107 
108     nw::ut::strncpy( addCost.costName, 32, costName, strlen( costName ) );
109     addCost.costColor = costColor;
110 
111     GLint requestCount = 0;
112     nngxGetCmdlistParameteri(NN_GX_CMDLIST_USED_REQCOUNT, &requestCount);
113 
114     // スタート位置
115     addCost.gpuStart    = requestCount + 1;
116     m_CurrentReqCount   = addCost.gpuStart;
117     addCost.constId     = m_CostArray[m_CostArrayFlip].size();
118     m_CurrentCost       = addCost.constId;
119 
120     bool isPushed = m_CostArray[m_CostArrayFlip].push_back( addCost );
121     NW_ASSERT(isPushed);
122 
123     // コールバックを登録
124     nngxEnableCmdlistCallback( m_CurrentReqCount );
125     nngxSplitDrawCmdlist();
126     NW_GL_ASSERT();
127 }
128 
129 
130 //----------------------------------------
131 // 計測を終了する
132 void
End()133 SmGpuPerf::End()
134 {
135     GLint requestCount = 0;
136     nngxGetCmdlistParameteri(NN_GX_CMDLIST_USED_REQCOUNT, &requestCount);
137     m_CostArray[m_CostArrayFlip][m_CurrentCost].gpuEnd = requestCount + 1;
138     m_CurrentReqCount   = m_CostArray[m_CostArrayFlip][m_CurrentCost].gpuEnd;
139     nngxEnableCmdlistCallback( m_CurrentReqCount );
140     nngxSplitDrawCmdlist();
141     NW_GL_ASSERT();
142 }
143 
144 
145 //----------------------------------------
146 // コールバックの呼び出しです。
147 void
Invoke(GLint id)148 SmGpuPerf::Invoke(GLint id)
149 {
150     // id で指定されるコストがあるか検索
151     uint i = 0;
152 
153     for ( i=0; i<m_CostArray[m_CostArrayFlip].size(); i++ )
154     {
155          if ( m_CostArray[m_CostArrayFlip][i].gpuStart == id )
156         {
157             m_CostArray[m_CostArrayFlip][i].costStart = this->GetTime();
158         }
159          if ( m_CostArray[m_CostArrayFlip][i].gpuEnd == id )
160         {
161             m_CostArray[m_CostArrayFlip][i].costEnd = this->GetTime();
162         }
163     }
164 }
165 
166 
167 //----------------------------------------
168 // 登録するコールバック関数です
169 void
Callback(GLint id)170 SmGpuPerf::Callback(GLint id)
171 {
172     if ( s_GpuPerf )
173     {
174         s_GpuPerf->Invoke(id);
175     }
176 }
177 
178 
179 //----------------------------------------
180 // リセットする
181 void
Reset()182 SmGpuPerf::Reset()
183 {
184     uint i = 0;
185     s64 cost = 0;
186 
187     for ( i = 0; i < m_CostArray[m_CostArrayFlip].size(); i++ )
188     {
189         cost = m_CostArray[m_CostArrayFlip][i].costEnd - m_CostArray[m_CostArrayFlip][i].costStart;
190 
191         m_CostArray[m_CostArrayFlip][i].costMicro = cost;
192     }
193 
194     SmPerf::Reset();
195 }
196 
197 // 登録されているコスト(msec)を取得する
198 f32
GetCost(uint costNo)199 SmGpuPerf::GetCost( uint costNo )
200 {
201     f32 millisec = 0.f;
202 
203     if ( m_CostArrayFlip )
204     {
205          if ( m_CostArray[0].size() > costNo )
206         {
207             millisec = static_cast<f32>(m_CostArray[0][costNo].costMicro) / 1000.f;
208         }
209     }
210     else
211     {
212          if ( m_CostArray[1].size() > costNo )
213         {
214             millisec = static_cast<f32>(m_CostArray[1][costNo].costMicro) / 1000.f;
215         }
216     }
217 
218     return millisec;
219 }
220 
221 
222 
223 
224 //----------------------------------------
225 // コンストラクタ
SmPerfDrawer()226 SmPerfDrawer::SmPerfDrawer()
227 : m_pPerfBarSplit( NULL )
228 {
229 
230 }
231 
232 
233 //----------------------------------------
234 // デストラクタ
~SmPerfDrawer()235 SmPerfDrawer::~SmPerfDrawer()
236 {
237 
238 }
239 
240 
241 
242 
243 //----------------------------------------
244 // 処理バーを描画する
245 void
Render(SmPerf * cpuPerf,SmPerf * gpuPerf)246 SmPerfDrawer::Render( SmPerf* cpuPerf, SmPerf* gpuPerf )
247 {
248     NW_NULL_ASSERT( cpuPerf );
249     NW_NULL_ASSERT( gpuPerf );
250 
251     // rectの登録
252     #define _SET_BAR_RECT( prim, x, y, w, h, color ) \
253         prim.SetVertex( x,     y,     color ); \
254         prim.SetVertex( x,     y + h, color ); \
255         prim.SetVertex( x + w, y + h, color ); \
256         prim.SetVertex( x + w, y + h, color ); \
257         prim.SetVertex( x + w, y,     color ); \
258         prim.SetVertex( x,     y,     color ); \
259 
260     uint i=0;
261     f32 costLength = 0.f;
262     f32 costLengthTemp = 0.f;
263     f32 cost = 0.f;
264 
265     // 処理バー
266      if ( m_PerfBar.Begin( cpuPerf->GetCostCount() * 6 + gpuPerf->GetCostCount() * 6, GL_TRIANGLES, 0.f, 0.f ) )
267     {
268         // CPU処理バー
269         for ( i=0; i<cpuPerf->GetCostCount(); i++ )
270         {
271             cost = cpuPerf->GetCost(i);
272 
273             costLength = cost/16.f * PERF_ONE_FRAME_WIDTH;
274             _SET_BAR_RECT( m_PerfBar, costLengthTemp, 5.f, costLength, 4.f, cpuPerf->GetCostColor(i) );
275             costLengthTemp += costLength;
276         }
277 
278         costLengthTemp = 0.f;
279 
280         // GPU処理バー
281         for ( i=0; i<gpuPerf->GetCostCount(); i++ )
282         {
283             cost = gpuPerf->GetCost(i);
284 
285             costLength = cost/16.f * PERF_ONE_FRAME_WIDTH;
286             _SET_BAR_RECT( m_PerfBar, costLengthTemp, 20.f, costLength, 4.f, gpuPerf->GetCostColor(i) );
287             costLengthTemp += costLength;
288         }
289 
290         m_PerfBar.End();
291     }
292 }
293 
294 
295 
296 
297 
298 } // namespace
299 
300 
301