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