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