1 /*---------------------------------------------------------------------------*
2   Project:  NintendoWare
3   File:     dev_CallbackChain.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/dev/dev_CallbackChain.h>
19 
20 #if defined(NW_DEV_ENABLED) && defined(NW_PLATFORM_CTR)
21 #include <nn/os/os_Tick.h>
22 #endif
23 
24 namespace nw
25 {
26 namespace dev
27 {
28 
29 #if defined(NW_DEV_ENABLED) && defined(NW_PLATFORM_CTR)
30 
31 CallbackChain* CallbackChain::s_CallbackChain = NULL;
32 
33 //! @brief コンストラクタです。
CallbackChain(nw::os::IAllocator * allocator)34 CallbackChain::CallbackChain( nw::os::IAllocator* allocator )
35 : m_Cost( 0.f ),
36 m_StartReqCount( 0 ),
37 m_EndReqCount( 0 ),
38 m_CurrentReqCount( 0 ),
39 m_MicroSecArray( NULL ),
40 m_Allocator( allocator )
41 {
42     NW_ASSERT( !s_CallbackChain );
43     NW_NULL_ASSERT( m_Allocator );
44 
45     GLint maxRequestCount = 0;
46 
47     s_CallbackChain = this;
48 
49     nngxGetCmdlistParameteri(NN_GX_CMDLIST_MAX_REQCOUNT, &maxRequestCount);
50     m_MaxRequestCount = maxRequestCount;
51 
52     m_MicroSecArray = static_cast<s64*>( m_Allocator->Alloc( sizeof(s64) * m_MaxRequestCount ) );
53     NW_NULL_ASSERT( m_MicroSecArray );
54 }
55 
56 
57 //! @brief デストラクタです。
~CallbackChain()58 CallbackChain::~CallbackChain()
59 {
60     m_Allocator->Free( m_MicroSecArray );
61     s_CallbackChain = NULL;
62 
63     nngxSetCmdlistCallback(NULL);
64 }
65 
66 
67 //! @brief インスタンスを破棄します。
68 void
Destroy()69 CallbackChain::Destroy()
70 {
71     if (m_Allocator != NULL)
72     {
73         void* memory = reinterpret_cast<void*>(this);
74         this->~CallbackChain();
75         m_Allocator->Free(memory);
76     }
77 }
78 
79 //! @brief バインドされているコマンドリストにコールバックを設定します。
80 void
SetCallback()81 CallbackChain::SetCallback()
82 {
83     nngxStopCmdlist();
84     nngxSetCmdlistCallback(CallbackChain::CommandListCallback);
85     nngxRunCmdlist();
86 }
87 
88 //! @brief コールバックチェイン処理を開始します。
89 void
Begin()90 CallbackChain::Begin()
91 {
92     int i = 0;
93     s64 costMicro = 0;
94     GLint requestCount = 0;
95 
96     for ( i = m_StartReqCount; i < m_EndReqCount; ++i )
97     {
98         if ( m_MicroSecArray[i+1] != 0 && m_MicroSecArray[i] != 0 )
99         {
100             costMicro += m_MicroSecArray[i+1] - m_MicroSecArray[i];
101         }
102     }
103 
104     m_Cost = static_cast<f32>(costMicro) / 1000.f;
105 
106     for ( i = 0; i<m_MaxRequestCount; ++i ) { m_MicroSecArray[i] = 0; }
107 
108     nngxGetCmdlistParameteri(NN_GX_CMDLIST_USED_REQCOUNT, &requestCount);
109 
110     m_StartReqCount     = requestCount + 1;
111     m_CurrentReqCount   = m_StartReqCount;
112     m_EndReqCount       = 0;
113 
114     nngxEnableCmdlistCallback( m_CurrentReqCount );
115     nngxSplitDrawCmdlist();
116 
117     NW_GL_ASSERT();
118 }
119 
120 
121 //! @brief コールバックチェイン処理を終了します。
End()122 void CallbackChain::End()
123 {
124     GLint requestCount = 0;
125     nngxGetCmdlistParameteri(NN_GX_CMDLIST_USED_REQCOUNT, &requestCount);
126     m_EndReqCount = requestCount + 1;
127     nngxSplitDrawCmdlist();
128 
129     NW_GL_ASSERT();
130 }
131 
132 
133 //! @brief コールバックの呼び出しです。
134 void
Invoke(GLint id)135 CallbackChain::Invoke(GLint id)
136 {
137     NW_UNUSED_VARIABLE(id);
138 
139     m_MicroSecArray[m_CurrentReqCount] = nn::os::Tick::GetSystemCurrent().ToTimeSpan().GetMicroSeconds();
140 
141     m_CurrentReqCount++;
142     nngxEnableCmdlistCallback(m_CurrentReqCount);
143 
144     NW_GL_ASSERT();
145 }
146 
147 
148 //! @brief 登録されるコールバック関数です。
149 void
CommandListCallback(GLint id)150 CallbackChain::CommandListCallback(GLint id)
151 {
152     if ( s_CallbackChain )
153     {
154         s_CallbackChain->Invoke(id);
155     }
156 }
157 
158 #endif // defined(NW_DEV_ENABLED) && defined(NW_PLATFORM_CTR)
159 
160 } // namespace nw::dev
161 } // namespace nw
162