/opengles/src/Arrays.h

http://ftk.googlecode.com/ · C Header · 414 lines · 276 code · 102 blank · 36 comment · 43 complexity · 1df8dbd965ac608082f6d04fb4701360 MD5 · raw file

  1. #ifndef EGL_ARRAYS_H
  2. #define EGL_ARRAYS_H 1
  3. // ==========================================================================
  4. //
  5. // Arrays.h Array type declarations and helpers
  6. //
  7. // --------------------------------------------------------------------------
  8. //
  9. // 05-26-2004 Hans-Martin Will initial version
  10. //
  11. // --------------------------------------------------------------------------
  12. //
  13. // Copyright (c) 2004, Hans-Martin Will. All rights reserved.
  14. //
  15. // Redistribution and use in source and binary forms, with or without
  16. // modification, are permitted provided that the following conditions are
  17. // met:
  18. //
  19. // * Redistributions of source code must retain the above copyright
  20. // notice, this list of conditions and the following disclaimer.
  21. // * Redistributions in binary form must reproduce the above copyright
  22. // notice, this list of conditions and the following disclaimer in the
  23. // documentation and/or other materials provided with the distribution.
  24. //
  25. // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  26. // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  27. // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  28. // ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
  29. // LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
  30. // OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
  31. // SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
  32. // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
  33. // CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  34. // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
  35. // THE POSSIBILITY OF SUCH DAMAGE.
  36. //
  37. // ==========================================================================
  38. #include "OGLES.h"
  39. #include "GLES/gl.h"
  40. #include "Types.h"
  41. #include "linalg.h"
  42. #include "Buffer.h"
  43. #include "Texture.h"
  44. namespace EGL {
  45. struct VertexArray {
  46. VertexArray() {
  47. pointer = 0;
  48. stride = 0;
  49. size = 4;
  50. type = GL_FIXED;
  51. effectivePointer = 0;
  52. boundBuffer = 0;
  53. fetchFunction = 0;
  54. };
  55. typedef void (VertexArray::*FetchValueFunction)(int row, GLfixed * buffer);
  56. void FetchByteValues(int row, GLfixed * buffer) {
  57. GLsizei rowOffset = row * stride;
  58. const unsigned char * base = reinterpret_cast<const unsigned char *>(effectivePointer) + rowOffset;
  59. size_t count = size;
  60. const GLbyte * byteBase = reinterpret_cast<const GLbyte *>(base);
  61. do {
  62. *buffer++ = EGL_FixedFromInt(*byteBase++);
  63. } while (--count);
  64. #ifdef EGL_XSCALE
  65. _PreLoad(const_cast<unsigned long *>(reinterpret_cast<const unsigned long *>(base + stride)));
  66. #endif
  67. }
  68. void FetchUnsignedByteValues(int row, GLubyte * buffer) {
  69. GLsizei rowOffset = row * stride;
  70. const unsigned char * base = reinterpret_cast<const unsigned char *>(effectivePointer) + rowOffset;
  71. size_t count = size;
  72. const GLubyte * byteBase = reinterpret_cast<const GLubyte *>(base);
  73. do {
  74. *buffer++ = *byteBase++;
  75. } while (--count);
  76. #ifdef EGL_XSCALE
  77. _PreLoad(const_cast<unsigned long *>(reinterpret_cast<const unsigned long *>(base + stride)));
  78. #endif
  79. }
  80. void FetchUnsignedByteValues(int row, GLfixed * buffer) {
  81. GLsizei rowOffset = row * stride;
  82. const unsigned char * base = reinterpret_cast<const unsigned char *>(effectivePointer) + rowOffset;
  83. size_t count = size;
  84. const GLubyte * byteBase = reinterpret_cast<const GLubyte *>(base);
  85. do {
  86. *buffer++ = EGL_FixedFromInt(*byteBase++);
  87. } while (--count);
  88. #ifdef EGL_XSCALE
  89. _PreLoad(const_cast<unsigned long *>(reinterpret_cast<const unsigned long *>(base + stride)));
  90. #endif
  91. }
  92. void FetchByteColorValues(int row, GLfixed * buffer) {
  93. GLsizei rowOffset = row * stride;
  94. const unsigned char * base = reinterpret_cast<const unsigned char *>(effectivePointer) + rowOffset;
  95. size_t count = size;
  96. const GLubyte * byteBase = reinterpret_cast<const GLubyte *>(base);
  97. do {
  98. U8 byteValue = *byteBase++;
  99. *buffer++ = static_cast<GLfixed>(((byteValue << 8) | byteValue) + (byteValue >> 7));
  100. } while (--count);
  101. #ifdef EGL_XSCALE
  102. _PreLoad(const_cast<unsigned long *>(reinterpret_cast<const unsigned long *>(base + stride)));
  103. #endif
  104. }
  105. void FetchShortValues(int row, GLfixed * buffer) {
  106. GLsizei rowOffset = row * stride;
  107. const unsigned char * base = reinterpret_cast<const unsigned char *>(effectivePointer) + rowOffset;
  108. size_t count = size;
  109. const GLshort * shortBase = reinterpret_cast<const GLshort *>(base);
  110. do {
  111. *buffer++ = EGL_FixedFromInt(*shortBase++);
  112. } while (--count);
  113. #ifdef EGL_XSCALE
  114. _PreLoad(const_cast<unsigned long *>(reinterpret_cast<const unsigned long *>(base + stride)));
  115. #endif
  116. }
  117. void FetchFixedValues(int row, GLfixed * buffer) {
  118. GLsizei rowOffset = row * stride;
  119. const unsigned char * base = reinterpret_cast<const unsigned char *>(effectivePointer) + rowOffset;
  120. size_t count = size;
  121. const GLfixed * fixedBase = reinterpret_cast<const GLfixed *>(base);
  122. do {
  123. *buffer++ = *fixedBase++;
  124. } while (--count);
  125. #ifdef EGL_XSCALE
  126. _PreLoad(const_cast<unsigned long *>(reinterpret_cast<const unsigned long *>(base + stride)));
  127. #endif
  128. }
  129. void FetchFloatValues(int row, GLfixed * buffer) {
  130. GLsizei rowOffset = row * stride;
  131. const unsigned char * base = reinterpret_cast<const unsigned char *>(effectivePointer) + rowOffset;
  132. size_t count = size;
  133. const GLfloat * floatBase = reinterpret_cast<const GLfloat *>(base);
  134. do {
  135. *buffer++ = EGL_FixedFromFloat(*floatBase++);
  136. } while (--count);
  137. #ifdef EGL_XSCALE
  138. _PreLoad(const_cast<unsigned long *>(reinterpret_cast<const unsigned long *>(base + stride)));
  139. #endif
  140. }
  141. void PrepareFetchValues(bool colorMode) {
  142. switch (type) {
  143. case GL_BYTE:
  144. fetchFunction = &VertexArray::FetchByteValues;
  145. break;
  146. case GL_UNSIGNED_BYTE:
  147. if (colorMode) {
  148. fetchFunction = &VertexArray::FetchByteColorValues;
  149. } else {
  150. fetchFunction = &VertexArray::FetchUnsignedByteValues;
  151. }
  152. break;
  153. case GL_SHORT:
  154. fetchFunction = &VertexArray::FetchShortValues;
  155. break;
  156. case GL_FIXED:
  157. fetchFunction = &VertexArray::FetchFixedValues;
  158. break;
  159. case GL_FLOAT:
  160. fetchFunction = &VertexArray::FetchFloatValues;
  161. break;
  162. default:
  163. fetchFunction = 0;
  164. break;
  165. }
  166. }
  167. inline void FetchValues(int row, GLfixed * buffer) {
  168. (this->*fetchFunction)(row, buffer);
  169. }
  170. size_t size;
  171. GLenum type;
  172. GLsizei stride;
  173. const GLvoid * pointer;
  174. size_t boundBuffer;
  175. const void * effectivePointer;
  176. FetchValueFunction fetchFunction;
  177. };
  178. template <class ELEMENT>
  179. struct ObjectArray {
  180. enum {
  181. INITIAL_SIZE = 64,
  182. FACTOR = 2
  183. };
  184. struct ObjectRecord {
  185. U32 value;
  186. void SetPointer(ELEMENT * texture) {
  187. value = reinterpret_cast<U32>(texture);
  188. }
  189. ELEMENT * GetPointer() {
  190. assert(IsPointer());
  191. return reinterpret_cast<ELEMENT *>(value);
  192. }
  193. bool IsPointer() {
  194. return (value & 1) == 0;
  195. }
  196. bool IsNil() {
  197. return value == 0xFFFFFFFFu;
  198. }
  199. void SetNil() {
  200. value = 0xFFFFFFFFu;
  201. }
  202. void SetIndex(size_t index) {
  203. value = (index << 1) | 1;
  204. }
  205. size_t GetIndex() {
  206. assert(!IsPointer() && !IsNil());
  207. return (value >> 1);
  208. }
  209. };
  210. ObjectArray() {
  211. m_Objects = new ObjectRecord[INITIAL_SIZE];
  212. for (size_t index = 0; index < INITIAL_SIZE; ++index) {
  213. m_Objects[index].SetIndex(index + 1);
  214. }
  215. m_Objects[INITIAL_SIZE - 1].SetNil();
  216. m_FreeObjects = m_AllocatedObjects = INITIAL_SIZE;
  217. m_FreeListHead = 0;
  218. }
  219. ~ObjectArray() {
  220. if (m_Objects != 0) {
  221. for (size_t index = 0; index < m_AllocatedObjects; ++index) {
  222. if (m_Objects[index].IsPointer() && m_Objects[index].GetPointer())
  223. delete m_Objects[index].GetPointer();
  224. }
  225. delete [] m_Objects;
  226. }
  227. }
  228. void Increase(size_t minSize = 0) {
  229. assert(m_FreeListHead == 0xffffffffu);
  230. size_t newAllocatedObjects = m_AllocatedObjects * FACTOR;
  231. if (newAllocatedObjects < minSize)
  232. newAllocatedObjects = minSize;
  233. ObjectRecord * newObjects = new ObjectRecord[newAllocatedObjects];
  234. size_t index;
  235. for (index = 0; index < m_AllocatedObjects; ++index) {
  236. newObjects[index] = m_Objects[index];
  237. }
  238. for (index = m_AllocatedObjects; index < newAllocatedObjects - 1; ++index) {
  239. newObjects[index].SetIndex(index + 1);
  240. }
  241. newObjects[newAllocatedObjects - 1].SetNil();
  242. delete [] m_Objects;
  243. m_Objects = newObjects;
  244. m_FreeObjects = newAllocatedObjects - m_AllocatedObjects;
  245. m_FreeListHead = m_AllocatedObjects;
  246. m_AllocatedObjects = newAllocatedObjects;
  247. }
  248. size_t Allocate() {
  249. if (m_FreeObjects == 0) {
  250. Increase();
  251. assert(m_FreeObjects != 0);
  252. }
  253. size_t result = m_FreeListHead;
  254. m_FreeListHead = m_Objects[result].IsNil() ? 0xffffffffu : m_Objects[result].GetIndex();
  255. m_FreeObjects--;
  256. m_Objects[result].SetPointer(0);
  257. return result;
  258. }
  259. void Deallocate(size_t index) {
  260. if (m_Objects[index].IsPointer()) {
  261. if (m_Objects[index].GetPointer())
  262. delete m_Objects[index].GetPointer();
  263. m_Objects[index].SetIndex(m_FreeListHead);
  264. m_FreeListHead = index;
  265. m_FreeObjects++;
  266. }
  267. }
  268. ELEMENT * GetObject(size_t index) {
  269. if (index >= m_AllocatedObjects)
  270. Increase(index + 1);
  271. if (!m_Objects[index].IsPointer()) {
  272. // allocate the requested object
  273. if (m_FreeListHead == index) {
  274. m_FreeListHead = m_Objects[index].IsNil() ? 0xffffffffu : m_Objects[index].GetIndex();
  275. } else {
  276. assert(m_FreeListHead != 0xffffffffu);
  277. size_t idx = m_FreeListHead;
  278. while (!m_Objects[idx].IsNil() && m_Objects[idx].GetIndex() != index)
  279. idx = m_Objects[idx].GetIndex();
  280. if (m_Objects[index].IsNil())
  281. m_Objects[idx].SetNil();
  282. else
  283. m_Objects[idx].SetIndex(m_Objects[index].GetIndex());
  284. }
  285. m_Objects[index].SetPointer(0);
  286. }
  287. if (!m_Objects[index].GetPointer()) {
  288. m_Objects[index].SetPointer(new ELEMENT());
  289. }
  290. return m_Objects[index].GetPointer();
  291. }
  292. size_t GetIndex(const ELEMENT * element) const {
  293. for (size_t index = 0; index < m_AllocatedObjects; ++index) {
  294. if (m_Objects[index].IsPointer() &&
  295. m_Objects[index].GetPointer() == element) {
  296. return index;
  297. }
  298. }
  299. return ~0;
  300. }
  301. bool IsObject(size_t index) {
  302. return index < m_AllocatedObjects && m_Objects[index].IsPointer();
  303. }
  304. ObjectRecord * m_Objects;
  305. size_t m_FreeObjects;
  306. size_t m_AllocatedObjects;
  307. size_t m_FreeListHead;
  308. };
  309. typedef ObjectArray<MultiTexture> TextureArray;
  310. typedef ObjectArray<Buffer> BufferArray;
  311. }
  312. #endif //ndef EGL_ARRAYS_H