PageRenderTime 507ms CodeModel.GetById 120ms app.highlight 92ms RepoModel.GetById 153ms app.codeStats 57ms

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