1 /*---------------------------------------------------------------------------*
2   Project:  Horizon
3   File:     font_RectDrawer.h
4 
5   Copyright (C)2009-2012 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: 46347 $
14  *---------------------------------------------------------------------------*/
15 
16 #ifndef NN_FONT_CTR_FONT_RECT_DRAWER_H_
17 #define NN_FONT_CTR_FONT_RECT_DRAWER_H_
18 
19 //--------------------------------------
20 // Operation Settings
21 
22 // Faster to render using glDrawArrays?
23 #define NN_FONT_RECTDRAWER_USE_DRAW_ARRAYS 1
24 
25 // If it can be stored in the Buffer, store it and render simultaneously
26 #define NN_FONT_RECTDRAWER_USE_DRAW_BUFFER 1
27 
28 
29 #include <nn/assert.h>
30 #include <nn/font/CTR/font_RectDrawerCommand.h>
31 #include <nn/font/CTR/font_CmdCache.h>
32 #if defined(NN_PLATFORM_CTR)
33     #include <nn/gx/CTR/gx_CommandAccess.h>
34 #endif
35 #include <nn/util/util_Color.h>
36 
37 #define NN_FONT_COMMAND_SET_BLEND_FUNC( eq, src, dst ) \
38     PICA_CMD_DATA_COLOR_OPERATION( \
39         PICA_DATA_FRAGOP_MODE_DMP, \
40         PICA_DATA_ENABLE_BLEND ), \
41     PICA_CMD_HEADER_SINGLE( PICA_REG_COLOR_OPERATION ), \
42     PICA_CMD_DATA_BLEND_FUNC( eq, src, dst ), \
43     PICA_CMD_HEADER_SINGLE( PICA_REG_BLEND_FUNC )
44 
45 #define NN_FONT_COMMAND_SET_BLEND_DEFAULT \
46     NN_FONT_COMMAND_SET_BLEND_FUNC( \
47         PICA_DATA_BLEND_EQUATION_ADD, \
48         PICA_DATA_BLEND_FUNC_SRC_ALPHA, \
49         PICA_DATA_BLEND_FUNC_ONE_MINUS_SRC_ALPHA )
50 
51 namespace nn {
52 namespace font {
53 namespace CTR {
54 
55 struct DispStringBuffer;
56 class CharWriter;
57 
58 //---------------------------------------------------------------------------
59 //
60 //---------------------------------------------------------------------------
61 class RectDrawer
62 {
63 public:
64     enum
65     {
66         DONT_USE_SETUP_COMMAND = 0x1
67     };
68 
69     //
70     //
71     //
72     //
73     //
74     //
75     //
76     static u32          GetVertexBufferCommandBufferSize(
77                             const void* shaderBinary,
78                             u32         size);
79 
80     //
81     //
82     //
83     //
84     static void*        GetVertexBufferData();
85 
86     //
87     //
88     //
89     //
90     static u32          GetVertexBufferSize();
91 
92     //
93     //
94     //
95     //
96     //
97     //
98     //
99     static u32          GetCommandBufferSize(
100                             const void* shaderBinary,
101                             u32         size);
102 
103     //
104     //
105 
106     //
107                         RectDrawer();
108 
109     //
110     //
111     //
112     //
113     //
114     //
115     //
116     //
117     virtual             ~RectDrawer();
118 
119     //
120 
121     //
122     //
123 
124     //
125     //
126     //
127     //
128     //
129     //
130     //
131     //
132     //
133     //
134     //
135     void                Initialize(
136                             void*       vtxBufCmdBuf,
137                             const void* shaderBinary,
138                             u32         size);
139 
140     //
141     //
142     //
143     //
144     //
145     //
146     //
147     //
148     //
149     //
150     //
151     //
152     void                Initialize(
153                             void*       vertexBuffer,
154                             void*       commandBuffer,
155                             const void* shaderBinary,
156                             u32         size);
157 
158     //
159     //
160     //
161     //
162     //
163     //
164     virtual void        Finalize();
165 
166     //
167 
168     //
169     //
170     //
171     //
172     //
173     //
174     //
175     //
176     virtual void        DrawBegin(u32 flag = 0);
177 
178     //
179     //
180     //
181     //
182     //
183     //
184     //
185     //
186     virtual void        DrawEnd(u32 flag = 0);
187 
188     //
189     //
190     //
191     //
192     void                SetProjectionMtx(const nn::math::MTX44& mtx);
193 
194     //
195     //
196     //
197     //
198     void                SetViewMtxForText(const nn::math::MTX34& mtx);
199 
200     //
201     //
202     //
203     //
204     //
205     //
206     void                SetParallax(
207                             f32     parallax,
208                             f32     dLevel,
209                             f32     addDist     = 0.0f
210                         );
211 
212     //
213     //
214     //
215     //
216     void                BuildTextCommand(CharWriter* pCharWriter);
217 
218     //
219     void                UniformAndDrawText(DispStringBuffer* pDispStringBuffer);
220 
221     //
222     void                UseBeginCommand();
223 
224     //
225     void                UseEndCommand();
226 
227 protected:
228 
229     //
SetUniformCommand(u32 * buffer,u32 num)230     static u32          SetUniformCommand(
231                             u32*    buffer,
232                             u32     num
233                         )
234     {
235 #if defined(NN_PLATFORM_CTR)
236         buffer[2] = buffer[3];
237         buffer[3] = PICA_CMD_HEADER_VS_F32(num);
238 #else
239         NN_ASSERT(false);
240         (void)buffer;
241 #endif
242         return sizeof(u32) * (4 + 4 * num);
243     }
244 
245     //
246     void                DisableTextures();
247 
248     //
249     void                AddUniformMtx();
250 
251 #if defined(NN_FONT_RECTDRAWER_USE_DRAW_ARRAYS)
252     //
253     u32                 GetVertexIndexAddressOffset(u32 vtxNum) const;
254 #endif
255 
256     //
257     const u32*          GetDrawCommands() const;
258 
259     //
260     u32                 GetDrawCommandSize() const;
261 
262 private:
263     static void         InitializeStatic();
264 
265     void                InitializeCMD(
266                             void*       vertexBuffer,
267                             void*       commandBuffer,
268                             const void* shaderBinary,
269                             u32         size,
270                             bool        initVertexBuffer);
271 
272     void                InitUniformBuffer(
273                             u32* __restrict buf,
274                             u32             addr);
275 
276     void                AddTextColor(
277                             math::VEC4* __restrict          dst,
278                             const util::Color8* __restrict  src,
279                             int                             mode);
280 
281 protected:
282     ////////////////////////////// Vertex Shader Info
283 
284     //
285     enum
286     {
287         UNIFORM_MTX_USE_MAX     =  3 /* mtx row */ + 4 /* vtx color */,
288         UNIFORM_DATA_USE_MAX    =  1 /* rect */ + 3/* TexMapMax */ * 2,
289 
290         UNIFORM_TEXT_MTX_MAX    =  3,   // mtx34 row
291 
292         UNIFORM_PROJ_NUM        =  4,   // mtx44 row
293 
294         UNIFORM_PROJ_START      =  0,
295         UNIFORM_ULCDDATA_START  = UNIFORM_PROJ_START + UNIFORM_PROJ_NUM,
296         UNIFORM_CONST_START,
297         UNIFORM_ADDR_START,
298         UNIFORM_MTX_START       = 32,
299         UNIFORM_DATA_START      = 64,
300 
301         UNIFORM_TEXTCOLOR_START = UNIFORM_MTX_START + UNIFORM_TEXT_MTX_MAX,
302 
303         UNIFORM_MAX             = 96
304     };
305 
306     //
307     enum
308     {
309 #ifdef NN_FONT_RECTDRAWER_USE_DRAW_BUFFER
310 
311         UNIFORM_ADDR_NUM        = UNIFORM_MTX_START  - UNIFORM_ADDR_START,
312         UNIFORM_MTX_NUM         = UNIFORM_DATA_START - UNIFORM_MTX_START,
313         UNIFORM_DATA_NUM        = UNIFORM_MAX        - UNIFORM_DATA_START,
314 
315         UNIFORM_TEXTCOLOR_NUM   = (UNIFORM_DATA_START - UNIFORM_TEXTCOLOR_START) & ~((1 << 2) - 1),
316 #else
317 
318         UNIFORM_RESISTER_ADDR = 5,
319 
320         // If they cannot be rendered together, maximum of 8 registers
321         UNIFORM_DATA_NUM  = 8,
322 
323         UNIFORM_ADDR_NUM      = UNIFORM_DATA_NUM - UNIFORM_RESISTER_ADDR,
324 #endif
325 
326         DRAW_VTX_NUM          = 6,
327         BIND_ATTRIB_LOCATION  = 0
328     };
329 
330 
331     ////////////////////////////// Command
332 
333     //
334     CmdCache            m_CmdCacheDrawBegin;
335 
336     //
337     CmdCache            m_CmdCacheDrawEnd;
338 
339     //
340     u8                  m_UniformAddrIndex;
341 
342     //
343     u8                  m_UniformMtxIndex;
344 
345     //
346     u8                  m_UniformDataIndex;
347 
348     //
349     u8                  m_UniformTextColorIndex;
350 
351     //
352     u32                 m_UniformProjBuffer[ 4 + 4 * (UNIFORM_PROJ_NUM + 1) ];
353 
354     //
355     u32                 m_UniformAddrBuffer[ 4 + 4 * UNIFORM_ADDR_NUM ];
356 
357     //
358     union
359     {
360         //
361         u32                 buffer[ 4 + 4 * UNIFORM_MTX_NUM  ];
362 
363         //
364         struct
365         {
366 
367             //
368             u32                 mtx  [ 4 + 4 * UNIFORM_TEXT_MTX_MAX ];
369 
370             //
371             u32                 color[ 4 + 4 * UNIFORM_TEXTCOLOR_NUM ];
372         } text;
373     } m_UniformMtxBuffer;
374 
375     //
376     u32                 m_UniformDataBuffer[ 4 + 4 * UNIFORM_DATA_NUM ];
377 
378     //
379     struct UniformAddress
380     {
381         //
UniformAddressUniformAddress382                             UniformAddress()
383                             :   addrMtx(0.f),
384                                 addrSizeAndVtx(0.f),
385                                 addrTexCoord(0.f),
386                                 addrColor(0.f)
387                             {}
388 
389         //
390         f32                 addrMtx;
391 
392         //
393         f32                 addrSizeAndVtx;
394 
395         //
396         f32                 addrTexCoord;
397 
398         //
399         f32                 addrColor;
400     };
401 
402     //
403     UniformAddress      m_UniformAddress;
404 
405     //
406     UniformAddress *const
407                         m_UniformAddr;
408 
409     //
410     math::VEC4 *const   m_UniformMtx;
411 
412     //
413     math::VEC4 *const   m_UniformData;
414 
415     //
416     math::VEC4 *const   m_UniformTextColor;
417 
418     //
419     void*               m_CommandBuffer;
420 
421     ////////////////////////////// Vertex Buffer Object
422 
423     //
424     void*               m_VertexBufferArray;
425 
426     ////////////////////////////// Uniform
427 
428 #if defined(NN_FONT_RECTDRAWER_USE_DRAW_ARRAYS)
429     //
430     u32                 m_VertexBufferBaseAddr;
431 #endif
432 
433     //
434     //
435     bool                m_IsColorDirty;
436     NN_PADDING3;
437 
438 private:
439     struct VertexBuffer
440     {
441 #if defined(NN_FONT_RECTDRAWER_USE_DRAW_ARRAYS)
442         f32                 position[UNIFORM_ADDR_NUM][DRAW_VTX_NUM][4];
443 #else
444         f32                 position[UNIFORM_ADDR_NUM][VERTEX_MAX][4];
445         u16                 indexes[UNIFORM_ADDR_NUM][DRAW_VTX_NUM];
446 #endif
447     };
448 
449     static bool         s_StaticInitialized;
450     static VertexBuffer s_VertexBuffer;
451 };
452 
453 inline
454 u32
GetVertexBufferSize()455 RectDrawer::GetVertexBufferSize()
456 {
457     return sizeof(s_VertexBuffer);
458 }
459 
460 
461 #if defined(NN_PLATFORM_CTR)
462 inline
463 u32*
SetVertexNumCmd(u32 ** pCmdPtr,u32 addrOffset,u32 vtxNum)464 SetVertexNumCmd(
465     u32**   pCmdPtr,
466     u32     addrOffset,
467     u32     vtxNum
468     )
469 {
470 #if defined(NN_FONT_RECTDRAWER_USE_DRAW_ARRAYS)
471     // Address/type of vertex index
472     // 0x227
473     NN_FONT_ADD_SINGLE_COMMAND_PTR(
474         *pCmdPtr,
475         PICA_CMD_HEADER_SINGLE( PICA_REG_INDEX_ARRAY_ADDR_OFFSET ),
476         PICA_CMD_DATA_INDEX_ARRAY_ADDR_OFFSET( addrOffset, 1 /* type */ ));
477 #else
478     (void)addrOffset;
479 #endif
480 
481     // Number of vertices to render
482     // 0x228
483     NN_FONT_ADD_SINGLE_COMMAND_PTR(
484         *pCmdPtr,
485         PICA_CMD_HEADER_SINGLE( PICA_REG_DRAW_VERTEX_NUM ),
486         PICA_CMD_DATA_DRAW_VERTEX_NUM( vtxNum ));
487 
488     return *pCmdPtr;
489 }
490 #endif
491 
492 }   // namespace CTR
493 }   // namespace font
494 }   // namespace nn
495 
496 #endif //  NN_FONT_CTR_FONT_RECT_DRAWER_H_
497