1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/gfx/angle/src/libGLESv2/renderer/vertexconversion.h Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,203 @@ 1.4 +// 1.5 +// Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved. 1.6 +// Use of this source code is governed by a BSD-style license that can be 1.7 +// found in the LICENSE file. 1.8 +// 1.9 + 1.10 +// vertexconversion.h: A library of vertex conversion classes that can be used to build 1.11 +// the FormatConverter objects used by the buffer conversion system. 1.12 + 1.13 +#ifndef LIBGLESV2_VERTEXCONVERSION_H_ 1.14 +#define LIBGLESV2_VERTEXCONVERSION_H_ 1.15 + 1.16 +namespace rx 1.17 +{ 1.18 + 1.19 +// Conversion types: 1.20 +// static const bool identity: true if this is an identity transform, false otherwise 1.21 +// static U convert(T): convert a single element from the input type to the output type 1.22 +// typedef ... OutputType: the type produced by this conversion 1.23 + 1.24 +template <class T> 1.25 +struct Identity 1.26 +{ 1.27 + static const bool identity = true; 1.28 + 1.29 + typedef T OutputType; 1.30 + 1.31 + static T convert(T x) 1.32 + { 1.33 + return x; 1.34 + } 1.35 +}; 1.36 + 1.37 +template <class FromT, class ToT> 1.38 +struct Cast 1.39 +{ 1.40 + static const bool identity = false; 1.41 + 1.42 + typedef ToT OutputType; 1.43 + 1.44 + static ToT convert(FromT x) 1.45 + { 1.46 + return static_cast<ToT>(x); 1.47 + } 1.48 +}; 1.49 + 1.50 +template <class T> 1.51 +struct Cast<T, T> 1.52 +{ 1.53 + static const bool identity = true; 1.54 + 1.55 + typedef T OutputType; 1.56 + 1.57 + static T convert(T x) 1.58 + { 1.59 + return static_cast<T>(x); 1.60 + } 1.61 +}; 1.62 + 1.63 +template <class T> 1.64 +struct Normalize 1.65 +{ 1.66 + static const bool identity = false; 1.67 + 1.68 + typedef float OutputType; 1.69 + 1.70 + static float convert(T x) 1.71 + { 1.72 + typedef std::numeric_limits<T> NL; 1.73 + float f = static_cast<float>(x); 1.74 + 1.75 + if (NL::is_signed) 1.76 + { 1.77 + // const float => VC2008 computes it at compile time 1.78 + // static const float => VC2008 computes it the first time we get here, stores it to memory with static guard and all that. 1.79 + const float divisor = 1.0f/(2*static_cast<float>(NL::max())+1); 1.80 + return (2*f+1)*divisor; 1.81 + } 1.82 + else 1.83 + { 1.84 + return f/NL::max(); 1.85 + } 1.86 + } 1.87 +}; 1.88 + 1.89 +template <class FromType, std::size_t ScaleBits> 1.90 +struct FixedToFloat 1.91 +{ 1.92 + static const bool identity = false; 1.93 + 1.94 + typedef float OutputType; 1.95 + 1.96 + static float convert(FromType x) 1.97 + { 1.98 + const float divisor = 1.0f / static_cast<float>(static_cast<FromType>(1) << ScaleBits); 1.99 + return static_cast<float>(x) * divisor; 1.100 + } 1.101 +}; 1.102 + 1.103 +// Widen types: 1.104 +// static const unsigned int initialWidth: number of components before conversion 1.105 +// static const unsigned int finalWidth: number of components after conversion 1.106 + 1.107 +// Float is supported at any size. 1.108 +template <std::size_t N> 1.109 +struct NoWiden 1.110 +{ 1.111 + static const std::size_t initialWidth = N; 1.112 + static const std::size_t finalWidth = N; 1.113 +}; 1.114 + 1.115 +// SHORT, norm-SHORT, norm-UNSIGNED_SHORT are supported but only with 2 or 4 components 1.116 +template <std::size_t N> 1.117 +struct WidenToEven 1.118 +{ 1.119 + static const std::size_t initialWidth = N; 1.120 + static const std::size_t finalWidth = N+(N&1); 1.121 +}; 1.122 + 1.123 +template <std::size_t N> 1.124 +struct WidenToFour 1.125 +{ 1.126 + static const std::size_t initialWidth = N; 1.127 + static const std::size_t finalWidth = 4; 1.128 +}; 1.129 + 1.130 +// Most types have 0 and 1 that are just that. 1.131 +template <class T> 1.132 +struct SimpleDefaultValues 1.133 +{ 1.134 + static T zero() { return static_cast<T>(0); } 1.135 + static T one() { return static_cast<T>(1); } 1.136 +}; 1.137 + 1.138 +// But normalised types only store [0,1] or [-1,1] so 1.0 is represented by the max value. 1.139 +template <class T> 1.140 +struct NormalizedDefaultValues 1.141 +{ 1.142 + static T zero() { return static_cast<T>(0); } 1.143 + static T one() { return std::numeric_limits<T>::max(); } 1.144 +}; 1.145 + 1.146 +// Converter: 1.147 +// static const bool identity: true if this is an identity transform (with no widening) 1.148 +// static const std::size_t finalSize: number of bytes per output vertex 1.149 +// 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. 1.150 + 1.151 +template <class InT, class WidenRule, class Converter, class DefaultValueRule = SimpleDefaultValues<InT> > 1.152 +struct VertexDataConverter 1.153 +{ 1.154 + typedef typename Converter::OutputType OutputType; 1.155 + typedef InT InputType; 1.156 + 1.157 + static const bool identity = (WidenRule::initialWidth == WidenRule::finalWidth) && Converter::identity; 1.158 + static const std::size_t finalSize = WidenRule::finalWidth * sizeof(OutputType); 1.159 + 1.160 + static void convertArray(const InputType *in, std::size_t stride, std::size_t n, OutputType *out) 1.161 + { 1.162 + for (std::size_t i = 0; i < n; i++) 1.163 + { 1.164 + const InputType *ein = pointerAddBytes(in, i * stride); 1.165 + 1.166 + copyComponent(out, ein, 0, static_cast<OutputType>(DefaultValueRule::zero())); 1.167 + copyComponent(out, ein, 1, static_cast<OutputType>(DefaultValueRule::zero())); 1.168 + copyComponent(out, ein, 2, static_cast<OutputType>(DefaultValueRule::zero())); 1.169 + copyComponent(out, ein, 3, static_cast<OutputType>(DefaultValueRule::one())); 1.170 + 1.171 + out += WidenRule::finalWidth; 1.172 + } 1.173 + } 1.174 + 1.175 + static void convertArray(const void *in, std::size_t stride, std::size_t n, void *out) 1.176 + { 1.177 + return convertArray(static_cast<const InputType*>(in), stride, n, static_cast<OutputType*>(out)); 1.178 + } 1.179 + 1.180 + private: 1.181 + // Advance the given pointer by a number of bytes (not pointed-to elements). 1.182 + template <class T> 1.183 + static T *pointerAddBytes(T *basePtr, std::size_t numBytes) 1.184 + { 1.185 + return reinterpret_cast<T *>(reinterpret_cast<uintptr_t>(basePtr) + numBytes); 1.186 + } 1.187 + 1.188 + static void copyComponent(OutputType *out, const InputType *in, std::size_t elementindex, OutputType defaultvalue) 1.189 + { 1.190 + if (WidenRule::finalWidth > elementindex) 1.191 + { 1.192 + if (WidenRule::initialWidth > elementindex) 1.193 + { 1.194 + out[elementindex] = Converter::convert(in[elementindex]); 1.195 + } 1.196 + else 1.197 + { 1.198 + out[elementindex] = defaultvalue; 1.199 + } 1.200 + } 1.201 + } 1.202 +}; 1.203 + 1.204 +} 1.205 + 1.206 +#endif // LIBGLESV2_VERTEXCONVERSION_H_