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