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