1 /*---------------------------------------------------------------------------*
2   Project:  NintendoWare
3   File:     demo_DebugUtility.h
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: 18943 $
14  *---------------------------------------------------------------------------*/
15 
16 #ifndef NW_DEMO_DEBUGUTILITY_H_
17 #define NW_DEMO_DEBUGUTILITY_H_
18 
19 //#include <nw/types.h>
20 
21 #include <nw/dev/dev_Screenshot.h>
22 #include <nw/demo/demo_HioPacketChannel.h>
23 #include <nw/demo/demo_GraphicsDrawing.h>
24 #include <nw/demo/demo_GraphicsSystem.h>
25 #include <nw/demo/demo_Memory.h>
26 #include <nw/demo/demo_Utility.h>
27 
28 namespace nw
29 {
30 
31 namespace demo
32 {
33 
34 //============================================================================
35 //! @name ユーティリティ
36 //@{
37 
38 //---------------------------------------------------------------------------
39 //! @brief        デモのデバッグに使用するユーティリティ関数をまとめたクラスです。
40 //---------------------------------------------------------------------------
41 class DebugUtility
42 {
43 private:
44     static const s32 NW_PROFILE_OUTPUT_INTERVAL = 600;
45     static const s32 NW_LOAD_METER_INTERVAL = 60;
46 
47     static const s32 POS_COMMAND_SIZE_X = 15;
48     static const s32 POS_COMMAND_SIZE_Y = 115;
49     static const s32 POS_LOAD_METER_X = 16;
50     static const s32 POS_LOAD_METER_Y = 140;
51     static const s32 HEIGHT_LOAD_METER = 18;
52     static const s32 POS_BAR_CHART_X = 15;
53     static const s32 POS_BAR_CHART_Y = 188;
54     static const s32 WIDTH_LOAD_METER_BAR_CHART = 256;
55     static const s32 HEIGHT_LOAD_METER_BAR_CHART = 20;
56 
57 public:
58     //=====================
59     //! @name 負荷の表示
60     //@{
61 
62     //---------------------------------------------------------------------------
63     //! @brief        負荷の計算を行います。
64     //!
65     //! @param[in]    renderSystem 負荷計算をしている RenderSystem です。
66     //---------------------------------------------------------------------------
67     static void CalcLoadMeter(
68         nw::demo::RenderSystem* renderSystem
69     );
70 
71     //---------------------------------------------------------------------------
72     //! @brief        負荷計測結果の文字を描画します。
73     //!
74     //!               graphicsDrawing の BeginDrawingString() をあらかじめ実行し、
75     //!               DrawLoadMeterText() 後は EndDrawingString() を実行する必要があります。
76     //!
77     //! @param[in]    renderSystem 負荷計算をしている RenderSystem です。
78     //! @param[in]    graphicsDrawing 文字列表示に使う GraphicsDrawing です。
79     //---------------------------------------------------------------------------
80     static void DrawLoadMeterText(
81         nw::demo::RenderSystem* renderSystem,
82         nw::demo::GraphicsDrawing* graphicsDrawing
83     );
84 
85     //---------------------------------------------------------------------------
86     //! @brief        負荷計測結果の図形部分を描画します。
87     //!
88     //!               graphicsDrawing の BeginDrawingShape() をあらかじめ実行し、
89     //!               DrawLoadMeter() 後は EndDrawingShape() を実行する必要があります。
90     //!
91     //! @param[in]    renderSystem 負荷計算をしている RenderSystem です。
92     //! @param[in]    graphicsDrawing 文字列表示に使う GraphicsDrawing です。
93     //---------------------------------------------------------------------------
94     static void DrawLoadMeter(
95         nw::demo::RenderSystem* renderSystem,
96         nw::demo::GraphicsDrawing* graphicsDrawing
97     );
98 
99     //---------------------------------------------------------------------------
100     //! @brief        負荷計測結果をログに出力します。
101     //!
102     //! @param[in]    renderSystem 負荷計算をしている RenderSystem です。
103     //---------------------------------------------------------------------------
104     static void DumpLoadMeter(
105         nw::demo::RenderSystem* renderSystem
106     );
107 
108     //---------------------------------------------------------------------------
109     //! @brief      CPU パフォーマンス計測モードであるかを取得します。
110     //!
111     //!             DBG スイッチを ON にすることで、CPUパフォーマンス計測モードになります。
112     //!
113     //! @return     CPU パフォーマンス計測モードであれば true を返します。
114     //---------------------------------------------------------------------------
IsCpuProfilingMode()115     static bool IsCpuProfilingMode()
116     {
117         return s_IsForceCpuProfilingMode || nw::demo::PadFactory::GetPad()->IsButtonPress(nw::demo::Pad::BUTTON_DEBUG);
118     }
119 
120     //@}
121 
122     //=====================
123     //! @name テスト
124     //@{
125 
126     //---------------------------------------------------------------------------
127     //! @brief        自動テストを初期化します。
128     //!
129     //!               NW_AUTOTESTが定義されていない場合は何も行われません。
130     //!
131     //! @param[in]    allocator 初期化に使用するアロケーターです。
132     //! @param[in]    deviceAllocator Host IO 接続に使用するデバイスアロケーターです。
133     //---------------------------------------------------------------------------
134     static void InitializeAutoTest(
135         os::IAllocator* allocator,
136         os::IAllocator* deviceAllocator,
137         nw::demo::RenderSystem** renderSystem,
138         const u32* correctHashDisplay0 = NULL,
139         const u32* correctHashDisplay1 = NULL,
140         bool needCustomTest = false
141     )
142     {
143         s_ProfileCallCount = 0;
144         s_DebugFrameCount = 0;
145 
146         #if defined(NW_AUTO_TEST)
147             s_AutoTester = AutoTester::Create(
148                 allocator,
149                 deviceAllocator
150             );
151 
152             s_AutoTester->Initialize(
153                 5,
154                 needCustomTest,
155                 renderSystem,
156                 correctHashDisplay0,
157                 correctHashDisplay1);
158         #else
159             NW_UNUSED_VARIABLE(allocator);
160             NW_UNUSED_VARIABLE(deviceAllocator);
161             NW_UNUSED_VARIABLE(renderSystem);
162             NW_UNUSED_VARIABLE(correctHashDisplay0);
163             NW_UNUSED_VARIABLE(correctHashDisplay1);
164             NW_UNUSED_VARIABLE(needCustomTest);
165         #endif
166     }
167 
168     //---------------------------------------------------------------------------
169     //! @brief        自動テストの終了処理を行います。
170     //!
171     //!               NW_AUTOTESTが定義されていない場合は何も行われません。
172     //---------------------------------------------------------------------------
FinalizeAutoTest()173     static void FinalizeAutoTest()
174     {
175         #if defined(NW_AUTO_TEST)
176         s_AutoTester->Finalize();
177         nw::ut::SafeDestroy(s_AutoTester);
178         #endif
179     }
180 
181     //---------------------------------------------------------------------------
182     //! @brief        自動テストのフレームを進めます。
183     //---------------------------------------------------------------------------
AdvanceAutoTestFrame()184     static void AdvanceAutoTestFrame()
185     {
186         #if defined(NW_AUTO_TEST)
187         NW_ASSERT(s_AutoTester);
188         s_AutoTester->AdvanceFrame();
189         #endif
190         if (!s_SilentMode)
191         {
192             if (s_ProfileCallCount % NW_PROFILE_OUTPUT_INTERVAL == 0)
193             {
194                 NW_DUMP_PROFILE();
195             }
196             else if (s_ProfileCallCount % NW_PROFILE_OUTPUT_INTERVAL == 1)
197             {
198                 NW_CLEAR_PROFILE();
199             }
200             s_ProfileCallCount++;
201         }
202     }
203 
204     //---------------------------------------------------------------------------
205     //! @brief        InitializeScenes 後のテストを行ないます。
206     //---------------------------------------------------------------------------
PostInitializeScenes()207     static void PostInitializeScenes()
208     {
209         // SetAllocatorForTest でセットしたアロケータの状態を PC に送ります。
210         #if defined(NW_AUTO_TEST)
211         NW_ASSERT(s_AutoTester);
212         s_AutoTester->NotifyMemoryStatus(
213             s_DeviceAllocator,
214             s_ParticleAllocator,
215             AutoTester::TIMING_POST_INITIALIZE_SCENES);
216         #endif
217     }
218 
219     //---------------------------------------------------------------------------
220     //! @brief        TerminateScenes 後のテストを行ないます。
221     //---------------------------------------------------------------------------
PreTerminateScenes()222     static void PreTerminateScenes()
223     {
224         // SetAllocatorForTest でセットしたアロケータの状態を PC に送ります。
225         #if defined(NW_AUTO_TEST)
226         NW_ASSERT(s_AutoTester);
227         s_AutoTester->NotifyMemoryStatus(
228             s_DeviceAllocator,
229             s_ParticleAllocator,
230             AutoTester::TIMING_PRE_TERMINATE_SCENES);
231         #endif
232     }
233 
234     //@}
235 
236     //=====================
237     //! @name メモリリーク検出
238     //@{
239 
240     //---------------------------------------------------------------------------
241     //! @brief          メモリリークの検出などの対象となるアロケータを指定します。
242     //!
243     //! @param[in]      deviceAllocator 対象のデバイスメモリアロケータです。
244     //! @param[in]      particleAllocator 対象のパーティクルメモリアロケータです。
245     //---------------------------------------------------------------------------
246     static void
247     SetAllocatorForTest(
248         nw::demo::DemoAllocator* deviceAllocator,
249         nw::demo::DemoAllocator* particleAllocator = NULL
250     )
251     {
252         s_DeviceAllocator = deviceAllocator;
253         s_ParticleAllocator = particleAllocator;
254     }
255 
256     //---------------------------------------------------------------------------
257     //! @brief          メモリリークの検出機能をリセットします。
258     //!
259     //!                 この関数が実行されると、その時点でのメモリ使用量を記憶します。
260     //!                 メモリリークを検出するためには TestMemoryLeak() 関数を実行してください。
261     //!
262     //!                 この関数を複数回実行すると、最後の実行のみが有効になります。
263     //---------------------------------------------------------------------------
264     static void
ResetMemoryLeakTester()265     ResetMemoryLeakTester()
266     {
267         s_DeviceMemoryFreeSize = s_DeviceAllocator->GetFreeSize();
268         if (s_ParticleAllocator)
269         {
270             s_ParticleMemoryFreeSize = s_ParticleAllocator->GetFreeSize();
271         }
272     }
273 
274     //---------------------------------------------------------------------------
275     //! @brief          メモリリークを検出します。
276     //!
277     //!                 最後に ResetMemoryLeakTester() が実行されたときとメモリ使用量を比べます。
278     //!                 メモリ使用量が ResetMemoryLeakTester() 実行時と一致しない場合はヒープのダンプを出力します。
279     //!
280     //! @return         メモリ使用量が ResetMemoryLeakTester() 実行時と一致する場合は true を、そうでない場合は false を返します。
281     //---------------------------------------------------------------------------
282     static bool
TestMemoryLeak()283     TestMemoryLeak()
284     {
285         bool result = true;
286 
287         s32 mainLeakSize = s_DeviceMemoryFreeSize - s_DeviceAllocator->GetFreeSize();
288         s32 particleLeakSize = 0;
289         if (s_ParticleAllocator)
290         {
291             particleLeakSize = s_ParticleMemoryFreeSize - s_ParticleAllocator->GetFreeSize();
292         }
293 
294         if (!s_SilentMode)
295         {
296             if (mainLeakSize)
297             {
298                 NW_DEV_LOG(
299                     "######### Device Memory Leak Detected !! (%d bytes)\n", mainLeakSize);
300                 s_DeviceAllocator->Dump();
301                 result = false;
302             }
303             if (particleLeakSize)
304             {
305                 NW_DEV_LOG(
306                     "######### Particle Memory Leak Detected !! (%d bytes)\n", particleLeakSize);
307                 s_ParticleAllocator->Dump();
308                 result = false;
309             }
310         }
311 
312     #if defined(NW_AUTO_TEST)
313         if (s_AutoTester)
314         {
315             s_AutoTester->NotifyMemoryLeak(mainLeakSize, particleLeakSize);
316         }
317     #endif
318 
319         return result;
320     }
321 
322     //@}
323 
324     //=====================
325     //! @name ログ出力制御
326     //@{
327 
328     //---------------------------------------------------------------------------
329     //! @brief          デバッグユーティリティクラスからのログへの出力を無効にします。
330     //!
331     //!                 isEnabled に true を指定すると、デバッグユーティリティはログへの出力を行わなくなります。
332     //!
333     //! @param          isEnabled true を指定すると、ログへの出力を行わなくなります。
334     //---------------------------------------------------------------------------
SetSilentMode(bool isEnabled)335     static void SetSilentMode(bool isEnabled) {s_SilentMode = isEnabled;}
336 
337     //@}
338 
339 private:
340     static size_t s_DeviceMemoryFreeSize;
341     static size_t s_ParticleMemoryFreeSize;
342     static nw::demo::DemoAllocator* s_DeviceAllocator;
343     static nw::demo::DemoAllocator* s_ParticleAllocator;
344     static bool s_IsForceCpuProfilingMode; //!< 強制的に CPU パフォーマンス計測モードにするフラグです。
345     static bool s_SilentMode; //!< ログへの出力を止めます。
346     static s32 s_ProfileCallCount;
347     static s32 s_DebugFrameCount;
348 
349 #if defined(NW_AUTO_TEST)
350     class AutoTester
351     {
352     public:
353         enum NOTIFY_TIMING
354         {
355             TIMING_POST_INITIALIZE_SCENES = 1,
356             TIMING_PRE_TERMINATE_SCENES
357         };
358 
359         //! @brief 自動テスターを生成します。
360         static AutoTester* Create(
361             os::IAllocator* allocator,
362             os::IAllocator* deviceAllocator
363         );
364 
365         //! @brief      自動テスターを初期化します。
366         //!
367         //!             Host IO を使用し、PC 側の自動テスターとの接続を試みます。
368         //!             接続に成功し、カスタムテストのシナリオを受信できれば、カスタムテストの初期化を行います。
369         //!             接続できなければ再試行することなく接続処理を終了し、デフォルトテストの初期化を行います。
370         //!             そのため、カスタムテストを実行するためには、この関数が実行されるまでに PC 側のテスターを
371         //!             待機状態にしておく必要があります。
372         //!
373         //!             needCustom に true を指定すると、カスタムテストの初期化に成功するまで PC 側への接続を試行し続けます。
374         //!             それまで制御は戻りません。
375         //!
376         //! @param[in]  channelNumber PC 側の自動テスターと接続するための Host IO のチャンネル番号です。
377         //! @param[in]  needCustom カスタムテストを必ず実行する場合は true を指定します。
378         //!
379         //! @return カスタムテストが初期化されたら正の値を、デフォルトテストが初期化されたら 0 を、初期化に失敗したら負の値を返します。
380         int Initialize(
381             s32 channelNumber,
382             bool needCustom,
383             nw::demo::RenderSystem** renderSystem,
384             const u32* correctHashDisplay0,
385             const u32* correctHashDisplay1
386         );
387 
388         //! @brief 自動テスターの終了処理を行います。
389         void Finalize();
390 
391         //! @brief 自動テスターを破棄します。
392         void Destroy();
393 
394         //! @brief テストのフレームを進めます。
395         void AdvanceFrame();
396 
397         //! @brief メモリリークの検出結果を PC に通知します。
398         //!
399         //!        カスタムテスト中であればメモリリーク情報のパケットを送信します。
400         //!
401         //! @param deviceLeakSize デバイスメモリのリーク量です。
402         //! @param particleLeakSize パーティクルメモリのリーク量です。
403         void NotifyMemoryLeak(s32 deviceLeakSize, s32 particleLeakSize);
404 
405         //! @brief メモリ状態を PC に通知します。
406         //!
407         //!        カスタムテスト中であればメモリ状態のパケットを送信します。
408         //!
409         //! @param timing タイミング情報です。
410         void NotifyMemoryStatus(
411             nw::demo::DemoAllocator* deviceAllocator,
412             nw::demo::DemoAllocator* particleAllocator,
413             NOTIFY_TIMING timing
414         );
415 
416     private:
417         //! テストシナリオのイベント種です。
418         enum EventType
419         {
420             EVENT_SCREENSHOT = 1,               //!< スクリーンショットの撮影と送信です。
421             EVENT_SET_PAD_STATUS,               //!< デモパッドの状態指定です。
422             EVENT_BEACON,                       //!< ビーコン送信です。
423             EVENT_SEND_LOAD_METER,              //!< 負荷情報の送信です。
424             EVENT_RESET_LOAD_METER,             //!< 負荷情報のリセットです。
425             EVENT_TEST_DONE,                    //!< テスト完了パケットの送信です。
426             EVENT_SWITCH_CPU_PROFILING_MODE    //!< CPU パフォーマンス計測モードの切り替えです。
427         };
428 
429         struct ScreenshotParam
430         {
431             enum DisplayFlag
432             {
433                 DISPLAY_0 = 1,
434                 DISPLAY_0_EXT,
435                 DISPLAY_1,
436                 DISPLAY_0_BOTH,
437                 DISPLAY_ALL
438             };
439             s32 display;
440             u32 hash[5]; // すべて 0 ならテストを行いません。
441         };
442 
443         struct SetPadStatusParam
444         {
445             u32 padStatus;
446         };
447 
448         struct BeaconParam
449         {
450         };
451 
452         struct SendLoadMeterParam
453         {
454         };
455 
456         struct ResetLoadMeterParam
457         {
458         };
459 
460         struct SwitchCpuProfilingModeParam
461         {
462             s32 isModeEnabled;
463         };
464 
465         struct TestEvent
466         {
467             s32 frameCount;
468             EventType eventType;
469 
470             union
471             {
472                 ScreenshotParam screenshot;
473                 SetPadStatusParam setPadStatus;
474                 BeaconParam beacon;
475                 SendLoadMeterParam sendLoadMeter;
476                 ResetLoadMeterParam resetLoadMeter;
477                 SwitchCpuProfilingModeParam switchCpuProfilingMode;
478             } param;
479         };
480 
481         // 受信パケットの構造体です。
482 
483         //! @brief テスト情報パケットのヘッダです。
484         struct TestInfoHeader
485         {
486             s32 packetType;
487             s32 eventCount;
488             char programName[64];
489             enum { PACKET_TYPE_ID = 0x213FEB92 };
490 
TestInfoHeaderTestInfoHeader491             TestInfoHeader()
492             : packetType(PACKET_TYPE_ID),
493               eventCount(0)
494             {}
495         };
496 
497         //! @brief シナリオパケットのヘッダです。
498         struct ScenarioHeader
499         {
500             s32 packetType;
501             s32 eventCount;
502             enum { PACKET_TYPE_ID = 0x6794C4C8 };
503 
ScenarioHeaderScenarioHeader504             ScenarioHeader()
505             : packetType(PACKET_TYPE_ID),
506               eventCount(0)
507             {}
508 
509         };
510 
511         // 送信パケットの構造体です。
512 
513         //! @brief スクリーンショットパケットのヘッダです。
514         struct ScreenshotHeader
515         {
516             s32 packetType;
517             s32 frameCount;
518             s32 width;
519             s32 height;
520             s32 display;
521 
522             enum { PACKET_TYPE_ID = 0x23848aa6 };
523 
ScreenshotHeaderScreenshotHeader524             ScreenshotHeader()
525             : packetType(PACKET_TYPE_ID),
526               frameCount(0),
527               width(0),
528               height(0)
529             {}
530         };
531 
532         //! @brief ビーコンパケットのヘッダです。
533         struct BeaconHeader
534         {
535             s32 packetType;
536             s32 frameCount;
537 
538             enum { PACKET_TYPE_ID = 0x9538a79a };
539 
BeaconHeaderBeaconHeader540             BeaconHeader()
541             : packetType(PACKET_TYPE_ID),
542               frameCount(0)
543             {}
544         };
545 
546         //! @brief 負荷情報パケットのヘッダです。
547         struct LoadMeterHeader
548         {
549             s32 packetType;
550             s32 frameCount;
551 
552             enum { PACKET_TYPE_ID = 0xc57c557 };
553 
LoadMeterHeaderLoadMeterHeader554             LoadMeterHeader()
555             : packetType(PACKET_TYPE_ID),
556               frameCount(0)
557             {}
558         };
559 
560         //! @brief 負荷情報パケットのデータ構造です。
561         struct LoadMeterData
562         {
563             s32 callCount;
564             s32 cpuTime;
565             s32 gpuTime;
566             s32 otherGpuTime;
567             s32 cmdSize;
568         };
569 
570         //! @brief メモリリーク情報パケットのヘッダです。
571         struct MemoryLeakHeader
572         {
573             s32 packetType;
574             s32 frameCount;
575 
576             enum { PACKET_TYPE_ID = 0x4F1B0AD2 };
577 
MemoryLeakHeaderMemoryLeakHeader578             MemoryLeakHeader()
579             : packetType(PACKET_TYPE_ID),
580               frameCount(0)
581             {}
582         };
583 
584         //! @brief メモリリーク情報パケットのデータ構造です。
585         struct MemoryLeakData
586         {
587             s32 deviceLeakSize;
588             s32 particleLeakSize;
589         };
590 
591         //! @brief テスト終了通知パケットのヘッダです。
592         struct DoneHeader
593         {
594             s32 packetType;
595             s32 frameCount;
596 
597             enum { PACKET_TYPE_ID = 0x916bbe7 };
598 
DoneHeaderDoneHeader599             DoneHeader()
600             : packetType(PACKET_TYPE_ID),
601               frameCount(0)
602             {}
603         };
604 
605         //! @brief メモリ状態通知パケットのヘッダです。
606         struct MemoryStatusHeader
607         {
608             s32 packetType;
609             s32 frameCount;
610             s32 timing;
611 
612             enum { PACKET_TYPE_ID = 0xE568134E };
613 
MemoryStatusHeaderMemoryStatusHeader614             MemoryStatusHeader()
615             : packetType(PACKET_TYPE_ID),
616               frameCount(0)
617             {}
618         };
619 
620         //! @brief メモリ状態通知パケットのデータ構造です。
621         struct MemoryStatusData
622         {
623             s32 deviceMemoryUsed;
624             s32 particleMemoryUsed;
625         };
626 
627         AutoTester(
628             os::IAllocator* allocator,
629             os::IAllocator* deviceAllocator
630         );
631         ~AutoTester();
632 
633         void SendScreenshot(const ScreenshotParam& param);
634         void SetPadStatus(const SetPadStatusParam& param);
635         void SendBeacon(const BeaconParam& param);
636         void SendLoadMeter(const SendLoadMeterParam& param);
637         void NotifyDone();
638         void SwitchCpuProfilingMode(const SwitchCpuProfilingModeParam& param);
639 
640         os::IAllocator* m_Allocator;
641         os::IAllocator* m_DeviceAllocator;
642 
643         nw::dev::ScreenshotManager* m_ScreenshotManager;
644 
645         nw::demo::HioPacketChannel* m_HioPacketChannel;
646 
647         s32 m_FrameCount;
648 
649         nw::ut::MoveArray<TestEvent> m_Scenario;
650         nw::ut::MoveArray<TestEvent>::iterator m_CurrentEvent;
651 
652         nw::demo::RenderSystem** m_RenderSystem;
653     };
654 
655     static AutoTester* s_AutoTester;
656 #else
657     class AutoTester
658     {
659     public:
Create(os::IAllocator *,os::IAllocator *)660         static AutoTester* Create(os::IAllocator*,os::IAllocator*){return NULL;}
Initialize(s32,bool,nw::demo::RenderSystem **,const u32 *,const u32 *)661         int Initialize(s32,bool,nw::demo::RenderSystem**,const u32*,const u32*){return -1;}
Finalize()662         void Finalize(){}
Destroy()663         void Destroy(){}
AdvanceFrame()664         void AdvanceFrame(){}
NotifyMemoryLeak(s32,s32)665         void NotifyMemoryLeak(s32, s32){}
666     };
667 #endif
668 };
669 
670 //@}
671 
672 namespace internal
673 {
674 
675 
676 //! @details :private
677 class DemoTestLoop
678 {
679 private:
680     static const int NW_PROFILE_MAX_REPORT = 60;
681 public:
DemoTestLoop(nw::demo::DemoAllocator * deviceAllocator,nw::demo::DemoAllocator * particleAllocator,nw::demo::RenderSystem ** renderSystem,const u32 * hash1,const u32 * hash2)682     DemoTestLoop(
683         nw::demo::DemoAllocator* deviceAllocator,
684         nw::demo::DemoAllocator* particleAllocator,
685         nw::demo::RenderSystem** renderSystem,
686         const u32* hash1,
687         const u32* hash2
688     )
689     : m_DeviceAllocator(deviceAllocator),
690       m_ParticleAllocator(particleAllocator),
691       m_ContinueFlag(true),
692       m_RenderSystem(renderSystem)
693     {
694         nw::demo::DebugUtility::InitializeAutoTest(m_DeviceAllocator, m_DeviceAllocator, m_RenderSystem, hash1, hash2);
695         NW_INITIALIZE_PROFILE(NW_PROFILE_MAX_REPORT, m_DeviceAllocator);
696 #if defined(NW_DEBUG_CHECK_MEMORY_LEAK)
697         nw::demo::DebugUtility::SetAllocatorForTest(m_DeviceAllocator, m_ParticleAllocator);
698         nw::demo::DebugUtility::ResetMemoryLeakTester();
699 #endif
700     }
~DemoTestLoop()701     ~DemoTestLoop()
702     {
703         NW_FINALIZE_PROFILE(m_DeviceAllocator);
704         nw::demo::DebugUtility::FinalizeAutoTest();
705     }
Continue()706     void Continue() {
707 #if defined(NW_DEBUG_CHECK_MEMORY_LEAK)
708         nw::demo::DebugUtility::TestMemoryLeak();
709 #else
710         m_ContinueFlag = false;
711 #endif
712         nw::demo::DebugUtility::FinalizeAutoTest();
713         // HACK: PC 側の AutoTester から任意の status が渡せないので、実機ではできない操作をトリガーにする。
714         const bool isAutotesting =
715             nw::demo::PadFactory::GetPad()->IsButtonPress(nw::demo::Pad::BUTTON_UP) &&
716             nw::demo::PadFactory::GetPad()->IsButtonPress(nw::demo::Pad::BUTTON_RIGHT) &&
717             nw::demo::PadFactory::GetPad()->IsButtonPress(nw::demo::Pad::BUTTON_DOWN) &&
718             nw::demo::PadFactory::GetPad()->IsButtonPress(nw::demo::Pad::BUTTON_LEFT);
719         nw::demo::DebugUtility::InitializeAutoTest(m_DeviceAllocator, m_DeviceAllocator, m_RenderSystem, NULL, NULL, isAutotesting);
720     }
IsContinuing()721     bool IsContinuing() {
722 #if defined(NW_DEBUG_CHECK_MEMORY_LEAK)
723         return ! ::nw::demo::internal::IsTerminatingImpl();
724 #else
725         return m_ContinueFlag;
726 #endif
727     }
728 private:
729     nw::demo::DemoAllocator* m_DeviceAllocator;
730     nw::demo::DemoAllocator* m_ParticleAllocator;
731     bool m_ContinueFlag;
732     nw::demo::RenderSystem** m_RenderSystem;
733 };
734 
735 } // namespace internal
736 
737 //============================================================================
738 //! @name デモプログラム支援
739 //@{
740 
741 #define NW_DEMO_TEST_LOOP(deviceAllocator, particleAllocator, renderSystem)                                             \
742     for (                                                                                                               \
743         nw::demo::internal::DemoTestLoop demoTestLoop(deviceAllocator, particleAllocator, renderSystem, NULL, NULL) ;   \
744         demoTestLoop.IsContinuing() ;                                                                                   \
745         demoTestLoop.Continue() )
746 
747 //@}
748 
749 } // namespace demo
750 } // namespace nw
751 
752 #endif // NW_DEMO_DEBUGUTILITY_H_
753