1 /*---------------------------------------------------------------------------*
2 Project: NintendoWare
3 File: demo_AutoTester.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
18 #include <nw/types.h>
19 #include <nw/os.h>
20 #include <nw/ut/ut_Inlines.h>
21 #include <nw/demo/demo_DebugUtility.h>
22
23 #include <nn/fs.h>
24
25
26 namespace nw {
27 namespace demo {
28
29 DebugUtility::AutoTester* DebugUtility::s_AutoTester = NULL;
30
31 //----------------------------------------
32 DebugUtility::AutoTester*
Create(os::IAllocator * allocator,os::IAllocator * deviceAllocator)33 DebugUtility::AutoTester::Create(
34 os::IAllocator* allocator,
35 os::IAllocator* deviceAllocator
36 )
37 {
38 void* memory = allocator->Alloc(sizeof(AutoTester));
39
40 NW_NULL_ASSERT(memory);
41
42 AutoTester* autoTester = new(memory) AutoTester(allocator, deviceAllocator);
43
44 return autoTester;
45 }
46
47 //----------------------------------------
48 int
Initialize(s32 channelNumber,bool needCustom,nw::demo::RenderSystem ** renderSystem,const u32 * correctHashDisplay0,const u32 * correctHashDisplay1)49 DebugUtility::AutoTester::Initialize(
50 s32 channelNumber,
51 bool needCustom,
52 nw::demo::RenderSystem** renderSystem,
53 const u32* correctHashDisplay0,
54 const u32* correctHashDisplay1
55 )
56 {
57 m_RenderSystem = renderSystem;
58
59 nw::demo::HioPacketChannel::Initialize(m_DeviceAllocator);
60
61 m_HioPacketChannel = nw::demo::HioPacketChannel::Builder()
62 .ChannelNumber(channelNumber)
63 .Create(m_Allocator, m_DeviceAllocator);
64
65 NW_NULL_ASSERT(m_HioPacketChannel);
66
67 if (m_HioPacketChannel->Listen(needCustom ? -1 : 0)) {
68 // 接続に成功したので、カスタムテストの初期化を開始します。
69 size_t headerWrittenSize;
70 size_t dataWrittenSize;
71
72 TestInfoHeader testInfoHeader;
73 m_HioPacketChannel->ReceivePacket(
74 &headerWrittenSize,
75 &dataWrittenSize,
76 &testInfoHeader,
77 sizeof(testInfoHeader),
78 NULL,
79 0,
80 -1
81 );
82
83 NW_ASSERT(testInfoHeader.packetType == TestInfoHeader::PACKET_TYPE_ID);
84
85 // シナリオを受信します
86 m_Scenario = nw::ut::MoveArray<TestEvent>(testInfoHeader.eventCount, m_Allocator);
87 m_Scenario.resize(testInfoHeader.eventCount);
88
89 ScenarioHeader scenarioHeader;
90 m_HioPacketChannel->ReceivePacket(
91 &headerWrittenSize,
92 &dataWrittenSize,
93 &scenarioHeader,
94 sizeof(scenarioHeader),
95 &m_Scenario[0],
96 sizeof(TestEvent) * m_Scenario.size(),
97 -1
98 );
99 NW_ASSERT(scenarioHeader.packetType == ScenarioHeader::PACKET_TYPE_ID);
100
101 DebugUtility::SetSilentMode(true);
102
103 nw::demo::PadFactory::GetPad()->EnableTestMode(true);
104 }
105 else
106 {
107 // 接続できなかったので、デフォルトテストの初期化を開始します。
108 nw::ut::SafeDestroy(m_HioPacketChannel);
109 nw::demo::HioPacketChannel::Finalize();
110
111 m_Scenario = nw::ut::MoveArray<TestEvent>(2, m_Allocator);
112
113 TestEvent event;
114
115 event.frameCount = 60;
116 event.eventType = EVENT_SCREENSHOT;
117 event.param.screenshot.display = ScreenshotParam::DISPLAY_0;
118 for (int i=0;i<5;++i)
119 {
120 if (correctHashDisplay0)
121 {
122 event.param.screenshot.hash[i] = correctHashDisplay0[i];
123 }
124 else
125 {
126 event.param.screenshot.hash[i] = 0;
127 }
128 }
129 m_Scenario.push_back(event);
130
131 event.param.screenshot.display = ScreenshotParam::DISPLAY_1;
132 for (int i=0;i<5;++i)
133 {
134 if (correctHashDisplay1)
135 {
136 event.param.screenshot.hash[i] = correctHashDisplay1[i];
137 }
138 else
139 {
140 event.param.screenshot.hash[i] = 0;
141 }
142 }
143 m_Scenario.push_back(event);
144
145 nw::demo::PadFactory::GetPad()->EnableTestMode(false);
146 }
147
148 m_ScreenshotManager = nw::dev::ScreenshotManager::Create(
149 m_Allocator,
150 1,
151 nw::dev::CalcMemorySize(GL_RGBA8_OES, 400, 320)
152 );
153 NW_POINTER_ASSERT(m_ScreenshotManager);
154
155 m_FrameCount = 0;
156 m_CurrentEvent = m_Scenario.begin();
157
158 return 0;
159 }
160
161 //----------------------------------------
162 void
Finalize()163 DebugUtility::AutoTester::Finalize()
164 {
165 if (m_HioPacketChannel)
166 {
167 m_HioPacketChannel->Disconnect();
168 nw::ut::SafeDestroy(m_HioPacketChannel);
169 nw::demo::HioPacketChannel::Finalize();
170 }
171 }
172
173 //----------------------------------------
174 void
Destroy()175 DebugUtility::AutoTester::Destroy()
176 {
177 nw::os::IAllocator* allocator = m_Allocator;
178
179 this->~AutoTester();
180 allocator->Free(this);
181 }
182
183 //----------------------------------------
184 void
AdvanceFrame()185 DebugUtility::AutoTester::AdvanceFrame()
186 {
187 while (m_CurrentEvent != m_Scenario.end() && m_CurrentEvent->frameCount == m_FrameCount)
188 {
189 switch (m_CurrentEvent->eventType)
190 {
191 case EVENT_SCREENSHOT:
192 SendScreenshot(m_CurrentEvent->param.screenshot);
193 break;
194 case EVENT_SET_PAD_STATUS:
195 SetPadStatus(m_CurrentEvent->param.setPadStatus);
196 break;
197 case EVENT_BEACON:
198 SendBeacon(m_CurrentEvent->param.beacon);
199 break;
200 case EVENT_SEND_LOAD_METER:
201 SendLoadMeter(m_CurrentEvent->param.sendLoadMeter);
202 break;
203 case EVENT_RESET_LOAD_METER:
204 if (m_RenderSystem)
205 {
206 (*m_RenderSystem)->ResetCumulativeLoadMeter();
207 }
208 break;
209 case EVENT_TEST_DONE:
210 NotifyDone();
211 break;
212 case EVENT_SWITCH_CPU_PROFILING_MODE:
213 SwitchCpuProfilingMode(m_CurrentEvent->param.switchCpuProfilingMode);
214 break;
215 default:
216 NW_FATAL_ERROR("Unsupported test event");
217 }
218
219 ++m_CurrentEvent;
220 }
221
222 ++m_FrameCount;
223 }
224
225 //----------------------------------------
226 void
SendScreenshot(const ScreenshotParam & param)227 DebugUtility::AutoTester::SendScreenshot(
228 const ScreenshotParam& param
229 )
230 {
231 int screenshotIndex;
232
233 switch (param.display)
234 {
235 case ScreenshotParam::DISPLAY_0:
236 screenshotIndex = m_ScreenshotManager->Take(NN_GX_DISPLAY0);
237 break;
238 case ScreenshotParam::DISPLAY_0_EXT:
239 screenshotIndex = m_ScreenshotManager->Take(NN_GX_DISPLAY0_EXT);
240 break;
241 case ScreenshotParam::DISPLAY_1:
242 screenshotIndex = m_ScreenshotManager->Take(NN_GX_DISPLAY1);
243 break;
244 case ScreenshotParam::DISPLAY_0_BOTH:
245 {
246 ScreenshotParam eachParam = param;
247 eachParam.display = ScreenshotParam::DISPLAY_0;
248 SendScreenshot(eachParam);
249 eachParam.display = ScreenshotParam::DISPLAY_0_EXT;
250 SendScreenshot(eachParam);
251 return;
252 }
253 case ScreenshotParam::DISPLAY_ALL:
254 {
255 ScreenshotParam eachParam = param;
256 eachParam.display = ScreenshotParam::DISPLAY_0;
257 SendScreenshot(eachParam);
258 eachParam.display = ScreenshotParam::DISPLAY_0_EXT;
259 SendScreenshot(eachParam);
260 eachParam.display = ScreenshotParam::DISPLAY_1;
261 SendScreenshot(eachParam);
262 return;
263 }
264 default:
265 NW_ASSERT(false);
266 }
267
268 if (screenshotIndex < 0)
269 {
270 if (m_HioPacketChannel)
271 {
272 ScreenshotHeader header;
273 header.frameCount = m_FrameCount;
274 header.width = 0;
275 header.height = 0;
276 header.display = param.display;
277 m_HioPacketChannel->SendPacket(
278 &header,
279 sizeof(header),
280 NULL,
281 0
282 );
283 }
284 return;
285 }
286
287 nw::dev::Screenshot* shotDisplay = m_ScreenshotManager->GetScreenshot(screenshotIndex);
288
289 if (m_HioPacketChannel)
290 {
291 ScreenshotHeader header;
292 header.frameCount = m_FrameCount;
293 header.width = shotDisplay->GetWidth();
294 header.height = shotDisplay->GetHeight();
295 header.display = param.display;
296 m_HioPacketChannel->SendPacket(
297 &header,
298 sizeof(header),
299 shotDisplay->GetBuffer(),
300 shotDisplay->GetBufferLength()
301 );
302 }
303 else
304 {
305 if (m_CurrentEvent->param.screenshot.hash[0] ||
306 m_CurrentEvent->param.screenshot.hash[0] ||
307 m_CurrentEvent->param.screenshot.hash[0] ||
308 m_CurrentEvent->param.screenshot.hash[0] ||
309 m_CurrentEvent->param.screenshot.hash[0] )
310 {
311
312 const bool result = shotDisplay->Equal(m_CurrentEvent->param.screenshot.hash);
313
314 if (result)
315 {
316 NW_DEV_LOG("NW_SCREENSHOT_TEST: OK\n");
317 shotDisplay->DumpHash();
318 }
319 else
320 {
321 NW_DEV_LOG("NW_SCREENSHOT_TEST: NG\n");
322 shotDisplay->DumpHash();
323 }
324 }
325 }
326 }
327
328 //----------------------------------------
329 void
SetPadStatus(const SetPadStatusParam & param)330 DebugUtility::AutoTester::SetPadStatus(
331 const SetPadStatusParam& param
332 )
333 {
334 nw::demo::PadFactory::GetPad()->SetTestPadStatus(param.padStatus);
335 }
336
337 //----------------------------------------
338 void
SendBeacon(const BeaconParam & param)339 DebugUtility::AutoTester::SendBeacon(
340 const BeaconParam& param
341 )
342 {
343 NW_UNUSED_VARIABLE(param);
344 if (m_HioPacketChannel)
345 {
346 BeaconHeader header;
347 header.frameCount = m_FrameCount;
348 m_HioPacketChannel->SendPacket(
349 &header,
350 sizeof(header),
351 NULL,
352 0
353 );
354 }
355 }
356
357 //----------------------------------------
358 void
SendLoadMeter(const SendLoadMeterParam & param)359 DebugUtility::AutoTester::SendLoadMeter(
360 const SendLoadMeterParam& param
361 )
362 {
363 NW_UNUSED_VARIABLE(param);
364 if (m_HioPacketChannel)
365 {
366 LoadMeterHeader header;
367 header.frameCount = m_FrameCount;
368
369 LoadMeterData data;
370 if (m_RenderSystem)
371 {
372 data.callCount = (*m_RenderSystem)->GetCumulativeLoadMeter().callCount;
373 data.cpuTime = static_cast<s32>( (*m_RenderSystem)->GetCumulativeLoadMeter().cumulativeTime * 1000 );
374 data.gpuTime = static_cast<s32>( (*m_RenderSystem)->GetCumulativeLoadMeter().cumulativeGpuTime * 1000 );
375 data.otherGpuTime = 0;
376 data.cmdSize = static_cast<s32>( (*m_RenderSystem)->GetCumulativeLoadMeter().drawCommandBufferSize );
377 }
378 else
379 {
380 data.callCount = 0;
381 data.cpuTime = 0;
382 data.gpuTime = 0;
383 data.otherGpuTime = 0;
384 data.cmdSize = 0;
385 }
386
387 m_HioPacketChannel->SendPacket(
388 &header,
389 sizeof(header),
390 &data,
391 sizeof(data)
392 );
393 }
394 }
395
396 //----------------------------------------
397 void
NotifyDone()398 DebugUtility::AutoTester::NotifyDone()
399 {
400 if (m_HioPacketChannel)
401 {
402 DoneHeader header;
403 header.frameCount = m_FrameCount;
404 m_HioPacketChannel->SendPacket(
405 &header,
406 sizeof(header),
407 NULL,
408 0
409 );
410 }
411 }
412
413 //----------------------------------------
414 void
SwitchCpuProfilingMode(const SwitchCpuProfilingModeParam & param)415 DebugUtility::AutoTester::SwitchCpuProfilingMode(const SwitchCpuProfilingModeParam& param)
416 {
417 DebugUtility::s_IsForceCpuProfilingMode = bool(param.isModeEnabled);
418 }
419
420 //----------------------------------------
421 void
NotifyMemoryLeak(s32 deviceLeakSize,s32 particleLeakSize)422 DebugUtility::AutoTester::NotifyMemoryLeak(
423 s32 deviceLeakSize,
424 s32 particleLeakSize
425 )
426 {
427 if (m_HioPacketChannel)
428 {
429 MemoryLeakHeader header;
430 header.frameCount = 0;
431
432 MemoryLeakData data;
433 data.deviceLeakSize = deviceLeakSize;
434 data.particleLeakSize = particleLeakSize;
435
436 m_HioPacketChannel->SendPacket(
437 &header,
438 sizeof(header),
439 &data,
440 sizeof(data)
441 );
442 }
443 }
444
445 //----------------------------------------------------------
446 void
NotifyMemoryStatus(nw::demo::DemoAllocator * deviceAllocator,nw::demo::DemoAllocator * particleAllocator,NOTIFY_TIMING timing)447 DebugUtility::AutoTester::NotifyMemoryStatus(
448 nw::demo::DemoAllocator* deviceAllocator,
449 nw::demo::DemoAllocator* particleAllocator,
450 NOTIFY_TIMING timing
451 )
452 {
453 if (m_HioPacketChannel)
454 {
455 MemoryStatusHeader header;
456 header.frameCount = 0;
457 header.timing = timing;
458
459 MemoryStatusData data;
460 data.deviceMemoryUsed = deviceAllocator->GetTotalSize() - deviceAllocator->GetFreeSize();
461 if (particleAllocator)
462 {
463 data.particleMemoryUsed = particleAllocator->GetTotalSize() - particleAllocator->GetFreeSize();
464 }
465 else
466 {
467 data.particleMemoryUsed = 0;
468 }
469
470 m_HioPacketChannel->SendPacket(
471 &header,
472 sizeof(header),
473 &data,
474 sizeof(data)
475 );
476 }
477 }
478
479 //----------------------------------------
AutoTester(os::IAllocator * allocator,os::IAllocator * deviceAllocator)480 DebugUtility::AutoTester::AutoTester(
481 os::IAllocator* allocator,
482 os::IAllocator* deviceAllocator
483 )
484 : m_Allocator(allocator),
485 m_DeviceAllocator(deviceAllocator),
486 m_ScreenshotManager(NULL),
487 m_HioPacketChannel(NULL),
488 m_FrameCount(0),
489 m_RenderSystem(NULL)
490 {
491 }
492
493 //----------------------------------------
~AutoTester()494 DebugUtility::AutoTester::~AutoTester()
495 {
496 m_ScreenshotManager->Destroy(m_Allocator);
497 }
498
499 } // namespace demo
500 } // namespace nw
501