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