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