initial import
[vuplus_webkit] / Source / ThirdParty / ANGLE / src / libGLESv2 / geometry / vertexconversion.h
1 //
2 // Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved.
3 // Use of this source code is governed by a BSD-style license that can be
4 // found in the LICENSE file.
5 //
6
7 // geometry/vertexconversion.h: A library of vertex conversion classes that can be used to build
8 // the FormatConverter objects used by the buffer conversion system.
9
10 #ifndef LIBGLESV2_GEOMETRY_VERTEXCONVERSION_H_
11 #define LIBGLESV2_GEOMETRY_VERTEXCONVERSION_H_
12
13 #include <cstddef>
14 #include <limits>
15
16 #include "libGLESv2/Context.h" // Defines Index
17
18 namespace gl
19 {
20
21 // Conversion types:
22 // static const bool identity: true if this is an identity transform, false otherwise
23 // static U convert(T): convert a single element from the input type to the output type
24 // typedef ... OutputType: the type produced by this conversion
25
26 template <class T>
27 struct Identity
28 {
29     static const bool identity = true;
30
31     typedef T OutputType;
32
33     static T convert(T x)
34     {
35         return x;
36     }
37 };
38
39 template <class FromT, class ToT>
40 struct Cast
41 {
42     static const bool identity = false;
43
44     typedef ToT OutputType;
45
46     static ToT convert(FromT x)
47     {
48         return static_cast<ToT>(x);
49     }
50 };
51
52 template <class T>
53 struct Cast<T, T>
54 {
55     static const bool identity = true;
56
57     typedef T OutputType;
58
59     static T convert(T x)
60     {
61         return static_cast<T>(x);
62     }
63 };
64
65 template <class T>
66 struct Normalize
67 {
68     static const bool identity = false;
69
70     typedef float OutputType;
71
72     static float convert(T x)
73     {
74         typedef std::numeric_limits<T> NL;
75         float f = static_cast<float>(x);
76
77         if (NL::is_signed)
78         {
79             // const float => VC2008 computes it at compile time
80             // static const float => VC2008 computes it the first time we get here, stores it to memory with static guard and all that.
81             const float divisor = 1.0f/(2*static_cast<float>(NL::max())+1);
82             return (2*f+1)*divisor;
83         }
84         else
85         {
86             return f/NL::max();
87         }
88     }
89 };
90
91 template <class FromType, std::size_t ScaleBits>
92 struct FixedToFloat
93 {
94     static const bool identity = false;
95
96     typedef float OutputType;
97
98     static float convert(FromType x)
99     {
100         const float divisor = 1.0f / static_cast<float>(static_cast<FromType>(1) << ScaleBits);
101         return static_cast<float>(x) * divisor;
102     }
103 };
104
105 // Widen types:
106 // static const unsigned int initialWidth: number of components before conversion
107 // static const unsigned int finalWidth: number of components after conversion
108
109 // Float is supported at any size.
110 template <std::size_t N>
111 struct NoWiden
112 {
113     static const std::size_t initialWidth = N;
114     static const std::size_t finalWidth = N;
115 };
116
117 // SHORT, norm-SHORT, norm-UNSIGNED_SHORT are supported but only with 2 or 4 components
118 template <std::size_t N>
119 struct WidenToEven
120 {
121     static const std::size_t initialWidth = N;
122     static const std::size_t finalWidth = N+(N&1);
123 };
124
125 template <std::size_t N>
126 struct WidenToFour
127 {
128     static const std::size_t initialWidth = N;
129     static const std::size_t finalWidth = 4;
130 };
131
132 // Most types have 0 and 1 that are just that.
133 template <class T>
134 struct SimpleDefaultValues
135 {
136     static T zero() { return static_cast<T>(0); }
137     static T one() { return static_cast<T>(1); }
138 };
139
140 // But normalised types only store [0,1] or [-1,1] so 1.0 is represented by the max value.
141 template <class T>
142 struct NormalizedDefaultValues
143 {
144     static T zero() { return static_cast<T>(0); }
145     static T one() { return std::numeric_limits<T>::max(); }
146 };
147
148 // Converter:
149 // static const bool identity: true if this is an identity transform (with no widening)
150 // static const std::size_t finalSize: number of bytes per output vertex
151 // static void convertArray(const void *in, std::size_t stride, std::size_t n, void *out): convert an array of vertices. Input may be strided, but output will be unstrided.
152
153 template <class InT, class WidenRule, class Converter, class DefaultValueRule = SimpleDefaultValues<InT> >
154 struct VertexDataConverter
155 {
156     typedef typename Converter::OutputType OutputType;
157     typedef InT InputType;
158
159     static const bool identity = (WidenRule::initialWidth == WidenRule::finalWidth) && Converter::identity;
160     static const std::size_t finalSize = WidenRule::finalWidth * sizeof(OutputType);
161
162     static void convertArray(const InputType *in, std::size_t stride, std::size_t n, OutputType *out)
163     {
164         for (std::size_t i = 0; i < n; i++)
165         {
166             const InputType *ein = pointerAddBytes(in, i * stride);
167
168             copyComponent(out, ein, 0, static_cast<OutputType>(DefaultValueRule::zero()));
169             copyComponent(out, ein, 1, static_cast<OutputType>(DefaultValueRule::zero()));
170             copyComponent(out, ein, 2, static_cast<OutputType>(DefaultValueRule::zero()));
171             copyComponent(out, ein, 3, static_cast<OutputType>(DefaultValueRule::one()));
172
173             out += WidenRule::finalWidth;
174         }
175     }
176
177     static void convertArray(const void *in, std::size_t stride, std::size_t n, void *out)
178     {
179         return convertArray(static_cast<const InputType*>(in), stride, n, static_cast<OutputType*>(out));
180     }
181
182   private:
183     // Advance the given pointer by a number of bytes (not pointed-to elements).
184     template <class T>
185     static T *pointerAddBytes(T *basePtr, std::size_t numBytes)
186     {
187         return reinterpret_cast<T *>(reinterpret_cast<uintptr_t>(basePtr) + numBytes);
188     }
189
190     static void copyComponent(OutputType *out, const InputType *in, std::size_t elementindex, OutputType defaultvalue)
191     {
192         if (WidenRule::finalWidth > elementindex)
193         {
194             if (WidenRule::initialWidth > elementindex)
195             {
196                 out[elementindex] = Converter::convert(in[elementindex]);
197             }
198             else
199             {
200                 out[elementindex] = defaultvalue;
201             }
202         }
203     }
204 };
205
206 }
207
208 #endif   // LIBGLESV2_GEOMETRY_VERTEXCONVERSION_H_