gfx/angle/src/libGLESv2/renderer/vertexconversion.h

changeset 0
6474c204b198
     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_

mercurial