== SoC Bullet - Bullet Upgrade to 2.76 ==
[blender.git] / extern / bullet2 / BulletMultiThreaded / SpuDoubleBuffer.h
1 #ifndef DOUBLE_BUFFER_H
2 #define DOUBLE_BUFFER_H
3
4 #include "SpuFakeDma.h"
5 #include "LinearMath/btScalar.h"
6
7
8 ///DoubleBuffer
9 template<class T, int size>
10 class DoubleBuffer
11 {
12 #if defined(__SPU__) || defined(USE_LIBSPE2)
13         ATTRIBUTE_ALIGNED128( T m_buffer0[size] ) ;
14         ATTRIBUTE_ALIGNED128( T m_buffer1[size] ) ;
15 #else
16         T m_buffer0[size];
17         T m_buffer1[size];
18 #endif
19         
20         T *m_frontBuffer;
21         T *m_backBuffer;
22
23         unsigned int m_dmaTag;
24         bool m_dmaPending;
25 public:
26         bool    isPending() const { return m_dmaPending;}
27         DoubleBuffer();
28
29         void init ();
30
31         // dma get and put commands
32         void backBufferDmaGet(uint64_t ea, unsigned int numBytes, unsigned int tag);
33         void backBufferDmaPut(uint64_t ea, unsigned int numBytes, unsigned int tag);
34
35         // gets pointer to a buffer
36         T *getFront();
37         T *getBack();
38
39         // if back buffer dma was started, wait for it to complete
40         // then move back to front and vice versa
41         T *swapBuffers();
42 };
43
44 template<class T, int size>
45 DoubleBuffer<T,size>::DoubleBuffer()
46 {
47         init ();
48 }
49
50 template<class T, int size>
51 void DoubleBuffer<T,size>::init()
52 {
53         this->m_dmaPending = false;
54         this->m_frontBuffer = &this->m_buffer0[0];
55         this->m_backBuffer = &this->m_buffer1[0];
56 }
57
58 template<class T, int size>
59 void
60 DoubleBuffer<T,size>::backBufferDmaGet(uint64_t ea, unsigned int numBytes, unsigned int tag)
61 {
62         m_dmaPending = true;
63         m_dmaTag = tag;
64         if (numBytes)
65         {
66                 m_backBuffer = (T*)cellDmaLargeGetReadOnly(m_backBuffer, ea, numBytes, tag, 0, 0);
67         }
68 }
69
70 template<class T, int size>
71 void
72 DoubleBuffer<T,size>::backBufferDmaPut(uint64_t ea, unsigned int numBytes, unsigned int tag)
73 {
74         m_dmaPending = true;
75         m_dmaTag = tag;
76         cellDmaLargePut(m_backBuffer, ea, numBytes, tag, 0, 0);
77 }
78
79 template<class T, int size>
80 T *
81 DoubleBuffer<T,size>::getFront()
82 {
83         return m_frontBuffer;
84 }
85
86 template<class T, int size>
87 T *
88 DoubleBuffer<T,size>::getBack()
89 {
90         return m_backBuffer;
91 }
92
93 template<class T, int size>
94 T *
95 DoubleBuffer<T,size>::swapBuffers()
96 {
97         if (m_dmaPending)
98         {
99                 cellDmaWaitTagStatusAll(1<<m_dmaTag);
100                 m_dmaPending = false;
101         }
102
103         T *tmp = m_backBuffer;
104         m_backBuffer = m_frontBuffer;
105         m_frontBuffer = tmp;
106
107         return m_frontBuffer;
108 }
109
110 #endif