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