/*---------------------------------------------------------------------------* Project: NintendoWare File: demo_AutoTester.cpp Copyright (C)2009-2010 Nintendo Co., Ltd./HAL Laboratory, Inc. All rights reserved. These coded instructions, statements, and computer programs contain proprietary information of Nintendo of America Inc. and/or Nintendo Company Ltd., and are protected by Federal copyright law. They may not be disclosed to third parties or copied or duplicated in any form, in whole or in part, without the prior written consent of Nintendo. $Revision: 18943 $ *---------------------------------------------------------------------------*/ #include #include #include #include #include namespace nw { namespace demo { DebugUtility::AutoTester* DebugUtility::s_AutoTester = NULL; //---------------------------------------- DebugUtility::AutoTester* DebugUtility::AutoTester::Create( os::IAllocator* allocator, os::IAllocator* deviceAllocator ) { void* memory = allocator->Alloc(sizeof(AutoTester)); NW_NULL_ASSERT(memory); AutoTester* autoTester = new(memory) AutoTester(allocator, deviceAllocator); return autoTester; } //---------------------------------------- int DebugUtility::AutoTester::Initialize( s32 channelNumber, bool needCustom, nw::demo::RenderSystem** renderSystem, const u32* correctHashDisplay0, const u32* correctHashDisplay1 ) { m_RenderSystem = renderSystem; nw::demo::HioPacketChannel::Initialize(m_DeviceAllocator); m_HioPacketChannel = nw::demo::HioPacketChannel::Builder() .ChannelNumber(channelNumber) .Create(m_Allocator, m_DeviceAllocator); NW_NULL_ASSERT(m_HioPacketChannel); if (m_HioPacketChannel->Listen(needCustom ? -1 : 0)) { // 接続に成功したので、カスタムテストの初期化を開始します。 size_t headerWrittenSize; size_t dataWrittenSize; TestInfoHeader testInfoHeader; m_HioPacketChannel->ReceivePacket( &headerWrittenSize, &dataWrittenSize, &testInfoHeader, sizeof(testInfoHeader), NULL, 0, -1 ); NW_ASSERT(testInfoHeader.packetType == TestInfoHeader::PACKET_TYPE_ID); // シナリオを受信します m_Scenario = nw::ut::MoveArray(testInfoHeader.eventCount, m_Allocator); m_Scenario.resize(testInfoHeader.eventCount); ScenarioHeader scenarioHeader; m_HioPacketChannel->ReceivePacket( &headerWrittenSize, &dataWrittenSize, &scenarioHeader, sizeof(scenarioHeader), &m_Scenario[0], sizeof(TestEvent) * m_Scenario.size(), -1 ); NW_ASSERT(scenarioHeader.packetType == ScenarioHeader::PACKET_TYPE_ID); DebugUtility::SetSilentMode(true); nw::demo::PadFactory::GetPad()->EnableTestMode(true); } else { // 接続できなかったので、デフォルトテストの初期化を開始します。 nw::ut::SafeDestroy(m_HioPacketChannel); nw::demo::HioPacketChannel::Finalize(); m_Scenario = nw::ut::MoveArray(2, m_Allocator); TestEvent event; event.frameCount = 60; event.eventType = EVENT_SCREENSHOT; event.param.screenshot.display = ScreenshotParam::DISPLAY_0; for (int i=0;i<5;++i) { if (correctHashDisplay0) { event.param.screenshot.hash[i] = correctHashDisplay0[i]; } else { event.param.screenshot.hash[i] = 0; } } m_Scenario.push_back(event); event.param.screenshot.display = ScreenshotParam::DISPLAY_1; for (int i=0;i<5;++i) { if (correctHashDisplay1) { event.param.screenshot.hash[i] = correctHashDisplay1[i]; } else { event.param.screenshot.hash[i] = 0; } } m_Scenario.push_back(event); nw::demo::PadFactory::GetPad()->EnableTestMode(false); } m_ScreenshotManager = nw::dev::ScreenshotManager::Create( m_Allocator, 1, nw::dev::CalcMemorySize(GL_RGBA8_OES, 400, 320) ); NW_POINTER_ASSERT(m_ScreenshotManager); m_FrameCount = 0; m_CurrentEvent = m_Scenario.begin(); return 0; } //---------------------------------------- void DebugUtility::AutoTester::Finalize() { if (m_HioPacketChannel) { m_HioPacketChannel->Disconnect(); nw::ut::SafeDestroy(m_HioPacketChannel); nw::demo::HioPacketChannel::Finalize(); } } //---------------------------------------- void DebugUtility::AutoTester::Destroy() { nw::os::IAllocator* allocator = m_Allocator; this->~AutoTester(); allocator->Free(this); } //---------------------------------------- void DebugUtility::AutoTester::AdvanceFrame() { while (m_CurrentEvent != m_Scenario.end() && m_CurrentEvent->frameCount == m_FrameCount) { switch (m_CurrentEvent->eventType) { case EVENT_SCREENSHOT: SendScreenshot(m_CurrentEvent->param.screenshot); break; case EVENT_SET_PAD_STATUS: SetPadStatus(m_CurrentEvent->param.setPadStatus); break; case EVENT_BEACON: SendBeacon(m_CurrentEvent->param.beacon); break; case EVENT_SEND_LOAD_METER: SendLoadMeter(m_CurrentEvent->param.sendLoadMeter); break; case EVENT_RESET_LOAD_METER: if (m_RenderSystem) { (*m_RenderSystem)->ResetCumulativeLoadMeter(); } break; case EVENT_TEST_DONE: NotifyDone(); break; case EVENT_SWITCH_CPU_PROFILING_MODE: SwitchCpuProfilingMode(m_CurrentEvent->param.switchCpuProfilingMode); break; default: NW_FATAL_ERROR("Unsupported test event"); } ++m_CurrentEvent; } ++m_FrameCount; } //---------------------------------------- void DebugUtility::AutoTester::SendScreenshot( const ScreenshotParam& param ) { int screenshotIndex; switch (param.display) { case ScreenshotParam::DISPLAY_0: screenshotIndex = m_ScreenshotManager->Take(NN_GX_DISPLAY0); break; case ScreenshotParam::DISPLAY_0_EXT: screenshotIndex = m_ScreenshotManager->Take(NN_GX_DISPLAY0_EXT); break; case ScreenshotParam::DISPLAY_1: screenshotIndex = m_ScreenshotManager->Take(NN_GX_DISPLAY1); break; case ScreenshotParam::DISPLAY_0_BOTH: { ScreenshotParam eachParam = param; eachParam.display = ScreenshotParam::DISPLAY_0; SendScreenshot(eachParam); eachParam.display = ScreenshotParam::DISPLAY_0_EXT; SendScreenshot(eachParam); return; } case ScreenshotParam::DISPLAY_ALL: { ScreenshotParam eachParam = param; eachParam.display = ScreenshotParam::DISPLAY_0; SendScreenshot(eachParam); eachParam.display = ScreenshotParam::DISPLAY_0_EXT; SendScreenshot(eachParam); eachParam.display = ScreenshotParam::DISPLAY_1; SendScreenshot(eachParam); return; } default: NW_ASSERT(false); } if (screenshotIndex < 0) { if (m_HioPacketChannel) { ScreenshotHeader header; header.frameCount = m_FrameCount; header.width = 0; header.height = 0; header.display = param.display; m_HioPacketChannel->SendPacket( &header, sizeof(header), NULL, 0 ); } return; } nw::dev::Screenshot* shotDisplay = m_ScreenshotManager->GetScreenshot(screenshotIndex); if (m_HioPacketChannel) { ScreenshotHeader header; header.frameCount = m_FrameCount; header.width = shotDisplay->GetWidth(); header.height = shotDisplay->GetHeight(); header.display = param.display; m_HioPacketChannel->SendPacket( &header, sizeof(header), shotDisplay->GetBuffer(), shotDisplay->GetBufferLength() ); } else { if (m_CurrentEvent->param.screenshot.hash[0] || m_CurrentEvent->param.screenshot.hash[0] || m_CurrentEvent->param.screenshot.hash[0] || m_CurrentEvent->param.screenshot.hash[0] || m_CurrentEvent->param.screenshot.hash[0] ) { const bool result = shotDisplay->Equal(m_CurrentEvent->param.screenshot.hash); if (result) { NW_DEV_LOG("NW_SCREENSHOT_TEST: OK\n"); shotDisplay->DumpHash(); } else { NW_DEV_LOG("NW_SCREENSHOT_TEST: NG\n"); shotDisplay->DumpHash(); } } } } //---------------------------------------- void DebugUtility::AutoTester::SetPadStatus( const SetPadStatusParam& param ) { nw::demo::PadFactory::GetPad()->SetTestPadStatus(param.padStatus); } //---------------------------------------- void DebugUtility::AutoTester::SendBeacon( const BeaconParam& param ) { NW_UNUSED_VARIABLE(param); if (m_HioPacketChannel) { BeaconHeader header; header.frameCount = m_FrameCount; m_HioPacketChannel->SendPacket( &header, sizeof(header), NULL, 0 ); } } //---------------------------------------- void DebugUtility::AutoTester::SendLoadMeter( const SendLoadMeterParam& param ) { NW_UNUSED_VARIABLE(param); if (m_HioPacketChannel) { LoadMeterHeader header; header.frameCount = m_FrameCount; LoadMeterData data; if (m_RenderSystem) { data.callCount = (*m_RenderSystem)->GetCumulativeLoadMeter().callCount; data.cpuTime = static_cast( (*m_RenderSystem)->GetCumulativeLoadMeter().cumulativeTime * 1000 ); data.gpuTime = static_cast( (*m_RenderSystem)->GetCumulativeLoadMeter().cumulativeGpuTime * 1000 ); data.otherGpuTime = 0; data.cmdSize = static_cast( (*m_RenderSystem)->GetCumulativeLoadMeter().drawCommandBufferSize ); } else { data.callCount = 0; data.cpuTime = 0; data.gpuTime = 0; data.otherGpuTime = 0; data.cmdSize = 0; } m_HioPacketChannel->SendPacket( &header, sizeof(header), &data, sizeof(data) ); } } //---------------------------------------- void DebugUtility::AutoTester::NotifyDone() { if (m_HioPacketChannel) { DoneHeader header; header.frameCount = m_FrameCount; m_HioPacketChannel->SendPacket( &header, sizeof(header), NULL, 0 ); } } //---------------------------------------- void DebugUtility::AutoTester::SwitchCpuProfilingMode(const SwitchCpuProfilingModeParam& param) { DebugUtility::s_IsForceCpuProfilingMode = bool(param.isModeEnabled); } //---------------------------------------- void DebugUtility::AutoTester::NotifyMemoryLeak( s32 deviceLeakSize, s32 particleLeakSize ) { if (m_HioPacketChannel) { MemoryLeakHeader header; header.frameCount = 0; MemoryLeakData data; data.deviceLeakSize = deviceLeakSize; data.particleLeakSize = particleLeakSize; m_HioPacketChannel->SendPacket( &header, sizeof(header), &data, sizeof(data) ); } } //---------------------------------------------------------- void DebugUtility::AutoTester::NotifyMemoryStatus( nw::demo::DemoAllocator* deviceAllocator, nw::demo::DemoAllocator* particleAllocator, NOTIFY_TIMING timing ) { if (m_HioPacketChannel) { MemoryStatusHeader header; header.frameCount = 0; header.timing = timing; MemoryStatusData data; data.deviceMemoryUsed = deviceAllocator->GetTotalSize() - deviceAllocator->GetFreeSize(); if (particleAllocator) { data.particleMemoryUsed = particleAllocator->GetTotalSize() - particleAllocator->GetFreeSize(); } else { data.particleMemoryUsed = 0; } m_HioPacketChannel->SendPacket( &header, sizeof(header), &data, sizeof(data) ); } } //---------------------------------------- DebugUtility::AutoTester::AutoTester( os::IAllocator* allocator, os::IAllocator* deviceAllocator ) : m_Allocator(allocator), m_DeviceAllocator(deviceAllocator), m_ScreenshotManager(NULL), m_HioPacketChannel(NULL), m_FrameCount(0), m_RenderSystem(NULL) { } //---------------------------------------- DebugUtility::AutoTester::~AutoTester() { m_ScreenshotManager->Destroy(m_Allocator); } } // namespace demo } // namespace nw