1 /*---------------------------------------------------------------------------*
2 Project: NintendoWare
3 File: demo_DisplayBufferSwapper.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: 31311 $
16 *---------------------------------------------------------------------------*/
17
18 #include <nw/demo/demo_DisplayBufferSwapper.h>
19 #include <nn/gx.h>
20
21
22 namespace nw
23 {
24 namespace demo
25 {
26
27 NW_UT_RUNTIME_TYPEINFO_ROOT_DEFINITION(DisplayBufferSwapper);
28
29 //----------------------------------------
30 DisplayBufferSwapper*
Create(os::IAllocator * allocator)31 DisplayBufferSwapper::Builder::Create(
32 os::IAllocator* allocator
33 )
34 {
35 NW_ASSERT(0 < m_Description.bufferCount);
36
37 void* memory = allocator->Alloc(sizeof(DisplayBufferSwapper));
38 DisplayBufferSwapper* bufferSwapper =
39 new(memory) DisplayBufferSwapper(allocator, m_Description);
40
41 return bufferSwapper;
42 }
43
44 //----------------------------------------
DisplayBufferSwapper(os::IAllocator * allocator,const Description & description)45 DisplayBufferSwapper::DisplayBufferSwapper(
46 os::IAllocator* allocator,
47 const Description& description
48 )
49 : GfxObject(allocator),
50 m_Description(description),
51 m_CurrentDisplay(0),
52 m_DisplayBuffers(0)
53 {
54 NW_ASSERT(0 <= m_Description.screenKind < BOTH_SCREENS);
55 NW_ASSERT(m_Description.bufferCount);
56 NW_ASSERT(0 <= m_Description.memoryArea < nw::gfx::GRAPHICS_MEMORY_AREA_COUNT);
57 NW_ASSERT(0 <= m_Description.displayOffsetX);
58 NW_ASSERT(0 <= m_Description.displayOffsetY);
59
60 GLenum display = 0;
61 if (m_Description.screenKind == UPPER_SCREEN)
62 {
63 display = NN_GX_DISPLAY0;
64 }
65 else if (m_Description.screenKind == LOWER_SCREEN)
66 {
67 display = NN_GX_DISPLAY1;
68 }
69 else if (m_Description.screenKind == EXTENSION_SCREEN)
70 {
71 display = NN_GX_DISPLAY0_EXT;
72 }
73 else
74 {
75 NW_FATAL_ERROR();
76 }
77
78 nngxActiveDisplay(display);
79
80 NW_ASSERT(m_Description.bufferCount != 0);
81
82 void* memory = allocator->Alloc(sizeof(GLuint) * m_Description.bufferCount);
83 m_DisplayBuffers = static_cast<GLuint*>(memory);
84 nngxGenDisplaybuffers(m_Description.bufferCount, m_DisplayBuffers);
85
86 for (s32 i = 0; i < m_Description.bufferCount; ++i)
87 {
88 nngxBindDisplaybuffer(m_DisplayBuffers[i]);
89
90 nngxDisplaybufferStorage(
91 m_Description.format,
92 m_Description.height,
93 m_Description.width,
94 m_Description.memoryArea);
95 }
96
97 nngxDisplayEnv(m_Description.displayOffsetY, m_Description.displayOffsetX);
98 nngxBindDisplaybuffer(0);
99 m_CurrentDisplay = 0;
100 }
101
102 //----------------------------------------
103 void
MakeTransferBufferCommand(gfx::IRenderTarget * target,bool isMultiCommandList)104 DisplayBufferSwapper::MakeTransferBufferCommand(
105 gfx::IRenderTarget* target,
106 bool isMultiCommandList
107 ){
108 if (target == NULL)
109 {
110 return;
111 }
112
113 NW_ASSERT(m_Description.transferMode < TRANSFER_MODE_ANTIALIASE_COUNT);
114 NW_ASSERT(0 <= m_Description.transferOffsetX && m_Description.transferOffsetX % 8 == 0);
115 NW_ASSERT(0 <= m_Description.transferOffsetY && m_Description.transferOffsetY % 8 == 0);
116
117 GLuint bufferObject = target->GetBufferObject();
118
119 NW_NULL_ASSERT(bufferObject);
120
121 glBindFramebuffer(GL_FRAMEBUFFER, bufferObject);
122
123 GLenum mode = NULL;
124 if (m_Description.transferMode == TRANSFER_MODE_ANTIALIASE_NOT_USED)
125 {
126 mode = NN_GX_ANTIALIASE_NOT_USED;
127 }
128 else if (m_Description.transferMode == TRANSFER_MODE_ANTIALIASE_2x1)
129 {
130 mode = NN_GX_ANTIALIASE_2x1;
131 }
132 else if (m_Description.transferMode == TRANSFER_MODE_ANTIALIASE_2x2)
133 {
134 mode = NN_GX_ANTIALIASE_2x2;
135 }
136
137 unsigned int targetCount =
138 (m_CurrentDisplay + (isMultiCommandList ? 1 : 0)) % m_Description.bufferCount;
139
140 nngxTransferRenderImage(
141 m_DisplayBuffers[targetCount],
142 mode,
143 m_Description.isTransferFlipX,
144 m_Description.transferOffsetY,
145 m_Description.transferOffsetX);
146
147 nngxSplitDrawCmdlist();
148 }
149
150 //----------------------------------------
151 void
ActivateBuffer()152 DisplayBufferSwapper::ActivateBuffer()
153 {
154 GLenum display = NULL;
155
156 if(m_Description.screenKind == UPPER_SCREEN)
157 {
158 display = NN_GX_DISPLAY0;
159 }
160 else if(m_Description.screenKind == LOWER_SCREEN)
161 {
162 display = NN_GX_DISPLAY1;
163 }
164 else if(m_Description.screenKind == EXTENSION_SCREEN)
165 {
166 display = NN_GX_DISPLAY0_EXT;
167 }
168 else
169 {
170 NW_FATAL_ERROR();
171 }
172
173 nngxActiveDisplay(display);
174 nngxBindDisplaybuffer(m_DisplayBuffers[m_CurrentDisplay]);
175
176 ++m_CurrentDisplay;
177 if (m_CurrentDisplay == m_Description.bufferCount)
178 {
179 m_CurrentDisplay = 0;
180 }
181 }
182
183 } // namespace demo
184 } // namespace nw
185