Imported Upstream version 2.81
[platform/upstream/libbullet.git] / src / BulletMultiThreaded / SpuDoubleBuffer.h
1 /*
2 Bullet Continuous Collision Detection and Physics Library
3 Copyright (c) 2003-2007 Erwin Coumans  http://bulletphysics.com
4
5 This software is provided 'as-is', without any express or implied warranty.
6 In no event will the authors be held liable for any damages arising from the use of this software.
7 Permission is granted to anyone to use this software for any purpose, 
8 including commercial applications, and to alter it and redistribute it freely, 
9 subject to the following restrictions:
10
11 1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
12 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
13 3. This notice may not be removed or altered from any source distribution.
14 */
15
16
17 #ifndef BT_DOUBLE_BUFFER_H
18 #define BT_DOUBLE_BUFFER_H
19
20 #include "SpuFakeDma.h"
21 #include "LinearMath/btScalar.h"
22
23
24 ///DoubleBuffer
25 template<class T, int size>
26 class DoubleBuffer
27 {
28 #if defined(__SPU__) || defined(USE_LIBSPE2)
29         ATTRIBUTE_ALIGNED128( T m_buffer0[size] ) ;
30         ATTRIBUTE_ALIGNED128( T m_buffer1[size] ) ;
31 #else
32         T m_buffer0[size];
33         T m_buffer1[size];
34 #endif
35         
36         T *m_frontBuffer;
37         T *m_backBuffer;
38
39         unsigned int m_dmaTag;
40         bool m_dmaPending;
41 public:
42         bool    isPending() const { return m_dmaPending;}
43         DoubleBuffer();
44
45         void init ();
46
47         // dma get and put commands
48         void backBufferDmaGet(uint64_t ea, unsigned int numBytes, unsigned int tag);
49         void backBufferDmaPut(uint64_t ea, unsigned int numBytes, unsigned int tag);
50
51         // gets pointer to a buffer
52         T *getFront();
53         T *getBack();
54
55         // if back buffer dma was started, wait for it to complete
56         // then move back to front and vice versa
57         T *swapBuffers();
58 };
59
60 template<class T, int size>
61 DoubleBuffer<T,size>::DoubleBuffer()
62 {
63         init ();
64 }
65
66 template<class T, int size>
67 void DoubleBuffer<T,size>::init()
68 {
69         this->m_dmaPending = false;
70         this->m_frontBuffer = &this->m_buffer0[0];
71         this->m_backBuffer = &this->m_buffer1[0];
72 }
73
74 template<class T, int size>
75 void
76 DoubleBuffer<T,size>::backBufferDmaGet(uint64_t ea, unsigned int numBytes, unsigned int tag)
77 {
78         m_dmaPending = true;
79         m_dmaTag = tag;
80         if (numBytes)
81         {
82                 m_backBuffer = (T*)cellDmaLargeGetReadOnly(m_backBuffer, ea, numBytes, tag, 0, 0);
83         }
84 }
85
86 template<class T, int size>
87 void
88 DoubleBuffer<T,size>::backBufferDmaPut(uint64_t ea, unsigned int numBytes, unsigned int tag)
89 {
90         m_dmaPending = true;
91         m_dmaTag = tag;
92         cellDmaLargePut(m_backBuffer, ea, numBytes, tag, 0, 0);
93 }
94
95 template<class T, int size>
96 T *
97 DoubleBuffer<T,size>::getFront()
98 {
99         return m_frontBuffer;
100 }
101
102 template<class T, int size>
103 T *
104 DoubleBuffer<T,size>::getBack()
105 {
106         return m_backBuffer;
107 }
108
109 template<class T, int size>
110 T *
111 DoubleBuffer<T,size>::swapBuffers()
112 {
113         if (m_dmaPending)
114         {
115                 cellDmaWaitTagStatusAll(1<<m_dmaTag);
116                 m_dmaPending = false;
117         }
118
119         T *tmp = m_backBuffer;
120         m_backBuffer = m_frontBuffer;
121         m_frontBuffer = tmp;
122
123         return m_frontBuffer;
124 }
125
126 #endif