10f7aaf530b2aad644d4aab01c493517dedf3f62fdaniel@transgaming.com// 20f7aaf530b2aad644d4aab01c493517dedf3f62fdaniel@transgaming.com// Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved. 30f7aaf530b2aad644d4aab01c493517dedf3f62fdaniel@transgaming.com// Use of this source code is governed by a BSD-style license that can be 40f7aaf530b2aad644d4aab01c493517dedf3f62fdaniel@transgaming.com// found in the LICENSE file. 50f7aaf530b2aad644d4aab01c493517dedf3f62fdaniel@transgaming.com// 60f7aaf530b2aad644d4aab01c493517dedf3f62fdaniel@transgaming.com 78fd34bd649a855dab9f5dc3505e40ecb14a01d70daniel@transgaming.com// vertexconversion.h: A library of vertex conversion classes that can be used to build 80f7aaf530b2aad644d4aab01c493517dedf3f62fdaniel@transgaming.com// the FormatConverter objects used by the buffer conversion system. 90f7aaf530b2aad644d4aab01c493517dedf3f62fdaniel@transgaming.com 108fd34bd649a855dab9f5dc3505e40ecb14a01d70daniel@transgaming.com#ifndef LIBGLESV2_VERTEXCONVERSION_H_ 118fd34bd649a855dab9f5dc3505e40ecb14a01d70daniel@transgaming.com#define LIBGLESV2_VERTEXCONVERSION_H_ 120f7aaf530b2aad644d4aab01c493517dedf3f62fdaniel@transgaming.com 130b7eef7c469bf717f7e1b57c6273f00d88e8b1d9Geoff Lang#include <limits> 140b7eef7c469bf717f7e1b57c6273f00d88e8b1d9Geoff Lang#include <cstdint> 150b7eef7c469bf717f7e1b57c6273f00d88e8b1d9Geoff Lang#include <cstddef> 160b7eef7c469bf717f7e1b57c6273f00d88e8b1d9Geoff Lang 17312404870905e1eff46e21632c1c2f2143af4694daniel@transgaming.comnamespace rx 180f7aaf530b2aad644d4aab01c493517dedf3f62fdaniel@transgaming.com{ 190f7aaf530b2aad644d4aab01c493517dedf3f62fdaniel@transgaming.com 200f7aaf530b2aad644d4aab01c493517dedf3f62fdaniel@transgaming.com// Conversion types: 210f7aaf530b2aad644d4aab01c493517dedf3f62fdaniel@transgaming.com// static const bool identity: true if this is an identity transform, false otherwise 220f7aaf530b2aad644d4aab01c493517dedf3f62fdaniel@transgaming.com// static U convert(T): convert a single element from the input type to the output type 230f7aaf530b2aad644d4aab01c493517dedf3f62fdaniel@transgaming.com// typedef ... OutputType: the type produced by this conversion 240f7aaf530b2aad644d4aab01c493517dedf3f62fdaniel@transgaming.com 250f7aaf530b2aad644d4aab01c493517dedf3f62fdaniel@transgaming.comtemplate <class T> 260f7aaf530b2aad644d4aab01c493517dedf3f62fdaniel@transgaming.comstruct Identity 270f7aaf530b2aad644d4aab01c493517dedf3f62fdaniel@transgaming.com{ 280f7aaf530b2aad644d4aab01c493517dedf3f62fdaniel@transgaming.com static const bool identity = true; 290f7aaf530b2aad644d4aab01c493517dedf3f62fdaniel@transgaming.com 300f7aaf530b2aad644d4aab01c493517dedf3f62fdaniel@transgaming.com typedef T OutputType; 310f7aaf530b2aad644d4aab01c493517dedf3f62fdaniel@transgaming.com 320f7aaf530b2aad644d4aab01c493517dedf3f62fdaniel@transgaming.com static T convert(T x) 330f7aaf530b2aad644d4aab01c493517dedf3f62fdaniel@transgaming.com { 340f7aaf530b2aad644d4aab01c493517dedf3f62fdaniel@transgaming.com return x; 350f7aaf530b2aad644d4aab01c493517dedf3f62fdaniel@transgaming.com } 360f7aaf530b2aad644d4aab01c493517dedf3f62fdaniel@transgaming.com}; 370f7aaf530b2aad644d4aab01c493517dedf3f62fdaniel@transgaming.com 380f7aaf530b2aad644d4aab01c493517dedf3f62fdaniel@transgaming.comtemplate <class FromT, class ToT> 390f7aaf530b2aad644d4aab01c493517dedf3f62fdaniel@transgaming.comstruct Cast 400f7aaf530b2aad644d4aab01c493517dedf3f62fdaniel@transgaming.com{ 410f7aaf530b2aad644d4aab01c493517dedf3f62fdaniel@transgaming.com static const bool identity = false; 420f7aaf530b2aad644d4aab01c493517dedf3f62fdaniel@transgaming.com 430f7aaf530b2aad644d4aab01c493517dedf3f62fdaniel@transgaming.com typedef ToT OutputType; 440f7aaf530b2aad644d4aab01c493517dedf3f62fdaniel@transgaming.com 450f7aaf530b2aad644d4aab01c493517dedf3f62fdaniel@transgaming.com static ToT convert(FromT x) 460f7aaf530b2aad644d4aab01c493517dedf3f62fdaniel@transgaming.com { 470f7aaf530b2aad644d4aab01c493517dedf3f62fdaniel@transgaming.com return static_cast<ToT>(x); 480f7aaf530b2aad644d4aab01c493517dedf3f62fdaniel@transgaming.com } 490f7aaf530b2aad644d4aab01c493517dedf3f62fdaniel@transgaming.com}; 500f7aaf530b2aad644d4aab01c493517dedf3f62fdaniel@transgaming.com 510f7aaf530b2aad644d4aab01c493517dedf3f62fdaniel@transgaming.comtemplate <class T> 520f7aaf530b2aad644d4aab01c493517dedf3f62fdaniel@transgaming.comstruct Cast<T, T> 530f7aaf530b2aad644d4aab01c493517dedf3f62fdaniel@transgaming.com{ 540f7aaf530b2aad644d4aab01c493517dedf3f62fdaniel@transgaming.com static const bool identity = true; 550f7aaf530b2aad644d4aab01c493517dedf3f62fdaniel@transgaming.com 560f7aaf530b2aad644d4aab01c493517dedf3f62fdaniel@transgaming.com typedef T OutputType; 570f7aaf530b2aad644d4aab01c493517dedf3f62fdaniel@transgaming.com 580f7aaf530b2aad644d4aab01c493517dedf3f62fdaniel@transgaming.com static T convert(T x) 590f7aaf530b2aad644d4aab01c493517dedf3f62fdaniel@transgaming.com { 600f7aaf530b2aad644d4aab01c493517dedf3f62fdaniel@transgaming.com return static_cast<T>(x); 610f7aaf530b2aad644d4aab01c493517dedf3f62fdaniel@transgaming.com } 620f7aaf530b2aad644d4aab01c493517dedf3f62fdaniel@transgaming.com}; 630f7aaf530b2aad644d4aab01c493517dedf3f62fdaniel@transgaming.com 640f7aaf530b2aad644d4aab01c493517dedf3f62fdaniel@transgaming.comtemplate <class T> 650f7aaf530b2aad644d4aab01c493517dedf3f62fdaniel@transgaming.comstruct Normalize 660f7aaf530b2aad644d4aab01c493517dedf3f62fdaniel@transgaming.com{ 670f7aaf530b2aad644d4aab01c493517dedf3f62fdaniel@transgaming.com static const bool identity = false; 680f7aaf530b2aad644d4aab01c493517dedf3f62fdaniel@transgaming.com 690f7aaf530b2aad644d4aab01c493517dedf3f62fdaniel@transgaming.com typedef float OutputType; 700f7aaf530b2aad644d4aab01c493517dedf3f62fdaniel@transgaming.com 710f7aaf530b2aad644d4aab01c493517dedf3f62fdaniel@transgaming.com static float convert(T x) 720f7aaf530b2aad644d4aab01c493517dedf3f62fdaniel@transgaming.com { 730f7aaf530b2aad644d4aab01c493517dedf3f62fdaniel@transgaming.com typedef std::numeric_limits<T> NL; 740f7aaf530b2aad644d4aab01c493517dedf3f62fdaniel@transgaming.com float f = static_cast<float>(x); 750f7aaf530b2aad644d4aab01c493517dedf3f62fdaniel@transgaming.com 760f7aaf530b2aad644d4aab01c493517dedf3f62fdaniel@transgaming.com if (NL::is_signed) 770f7aaf530b2aad644d4aab01c493517dedf3f62fdaniel@transgaming.com { 780f7aaf530b2aad644d4aab01c493517dedf3f62fdaniel@transgaming.com // const float => VC2008 computes it at compile time 790f7aaf530b2aad644d4aab01c493517dedf3f62fdaniel@transgaming.com // static const float => VC2008 computes it the first time we get here, stores it to memory with static guard and all that. 800f7aaf530b2aad644d4aab01c493517dedf3f62fdaniel@transgaming.com const float divisor = 1.0f/(2*static_cast<float>(NL::max())+1); 810f7aaf530b2aad644d4aab01c493517dedf3f62fdaniel@transgaming.com return (2*f+1)*divisor; 820f7aaf530b2aad644d4aab01c493517dedf3f62fdaniel@transgaming.com } 830f7aaf530b2aad644d4aab01c493517dedf3f62fdaniel@transgaming.com else 840f7aaf530b2aad644d4aab01c493517dedf3f62fdaniel@transgaming.com { 850f7aaf530b2aad644d4aab01c493517dedf3f62fdaniel@transgaming.com return f/NL::max(); 860f7aaf530b2aad644d4aab01c493517dedf3f62fdaniel@transgaming.com } 870f7aaf530b2aad644d4aab01c493517dedf3f62fdaniel@transgaming.com } 880f7aaf530b2aad644d4aab01c493517dedf3f62fdaniel@transgaming.com}; 890f7aaf530b2aad644d4aab01c493517dedf3f62fdaniel@transgaming.com 900f7aaf530b2aad644d4aab01c493517dedf3f62fdaniel@transgaming.comtemplate <class FromType, std::size_t ScaleBits> 910f7aaf530b2aad644d4aab01c493517dedf3f62fdaniel@transgaming.comstruct FixedToFloat 920f7aaf530b2aad644d4aab01c493517dedf3f62fdaniel@transgaming.com{ 930f7aaf530b2aad644d4aab01c493517dedf3f62fdaniel@transgaming.com static const bool identity = false; 940f7aaf530b2aad644d4aab01c493517dedf3f62fdaniel@transgaming.com 950f7aaf530b2aad644d4aab01c493517dedf3f62fdaniel@transgaming.com typedef float OutputType; 960f7aaf530b2aad644d4aab01c493517dedf3f62fdaniel@transgaming.com 970f7aaf530b2aad644d4aab01c493517dedf3f62fdaniel@transgaming.com static float convert(FromType x) 980f7aaf530b2aad644d4aab01c493517dedf3f62fdaniel@transgaming.com { 990f7aaf530b2aad644d4aab01c493517dedf3f62fdaniel@transgaming.com const float divisor = 1.0f / static_cast<float>(static_cast<FromType>(1) << ScaleBits); 1000f7aaf530b2aad644d4aab01c493517dedf3f62fdaniel@transgaming.com return static_cast<float>(x) * divisor; 1010f7aaf530b2aad644d4aab01c493517dedf3f62fdaniel@transgaming.com } 1020f7aaf530b2aad644d4aab01c493517dedf3f62fdaniel@transgaming.com}; 1030f7aaf530b2aad644d4aab01c493517dedf3f62fdaniel@transgaming.com 1040f7aaf530b2aad644d4aab01c493517dedf3f62fdaniel@transgaming.com// Widen types: 1050f7aaf530b2aad644d4aab01c493517dedf3f62fdaniel@transgaming.com// static const unsigned int initialWidth: number of components before conversion 1060f7aaf530b2aad644d4aab01c493517dedf3f62fdaniel@transgaming.com// static const unsigned int finalWidth: number of components after conversion 1070f7aaf530b2aad644d4aab01c493517dedf3f62fdaniel@transgaming.com 1080f7aaf530b2aad644d4aab01c493517dedf3f62fdaniel@transgaming.com// Float is supported at any size. 1090f7aaf530b2aad644d4aab01c493517dedf3f62fdaniel@transgaming.comtemplate <std::size_t N> 1100f7aaf530b2aad644d4aab01c493517dedf3f62fdaniel@transgaming.comstruct NoWiden 1110f7aaf530b2aad644d4aab01c493517dedf3f62fdaniel@transgaming.com{ 1120f7aaf530b2aad644d4aab01c493517dedf3f62fdaniel@transgaming.com static const std::size_t initialWidth = N; 1130f7aaf530b2aad644d4aab01c493517dedf3f62fdaniel@transgaming.com static const std::size_t finalWidth = N; 1140f7aaf530b2aad644d4aab01c493517dedf3f62fdaniel@transgaming.com}; 1150f7aaf530b2aad644d4aab01c493517dedf3f62fdaniel@transgaming.com 1160f7aaf530b2aad644d4aab01c493517dedf3f62fdaniel@transgaming.com// SHORT, norm-SHORT, norm-UNSIGNED_SHORT are supported but only with 2 or 4 components 1170f7aaf530b2aad644d4aab01c493517dedf3f62fdaniel@transgaming.comtemplate <std::size_t N> 1180f7aaf530b2aad644d4aab01c493517dedf3f62fdaniel@transgaming.comstruct WidenToEven 1190f7aaf530b2aad644d4aab01c493517dedf3f62fdaniel@transgaming.com{ 1200f7aaf530b2aad644d4aab01c493517dedf3f62fdaniel@transgaming.com static const std::size_t initialWidth = N; 1210f7aaf530b2aad644d4aab01c493517dedf3f62fdaniel@transgaming.com static const std::size_t finalWidth = N+(N&1); 1220f7aaf530b2aad644d4aab01c493517dedf3f62fdaniel@transgaming.com}; 1230f7aaf530b2aad644d4aab01c493517dedf3f62fdaniel@transgaming.com 12413881545ced98cd2ec7b175389c95bf23574bf53daniel@transgaming.comtemplate <std::size_t N> 1250f7aaf530b2aad644d4aab01c493517dedf3f62fdaniel@transgaming.comstruct WidenToFour 1260f7aaf530b2aad644d4aab01c493517dedf3f62fdaniel@transgaming.com{ 1270f7aaf530b2aad644d4aab01c493517dedf3f62fdaniel@transgaming.com static const std::size_t initialWidth = N; 1280f7aaf530b2aad644d4aab01c493517dedf3f62fdaniel@transgaming.com static const std::size_t finalWidth = 4; 1290f7aaf530b2aad644d4aab01c493517dedf3f62fdaniel@transgaming.com}; 1300f7aaf530b2aad644d4aab01c493517dedf3f62fdaniel@transgaming.com 1310f7aaf530b2aad644d4aab01c493517dedf3f62fdaniel@transgaming.com// Most types have 0 and 1 that are just that. 1320f7aaf530b2aad644d4aab01c493517dedf3f62fdaniel@transgaming.comtemplate <class T> 1330f7aaf530b2aad644d4aab01c493517dedf3f62fdaniel@transgaming.comstruct SimpleDefaultValues 1340f7aaf530b2aad644d4aab01c493517dedf3f62fdaniel@transgaming.com{ 1350f7aaf530b2aad644d4aab01c493517dedf3f62fdaniel@transgaming.com static T zero() { return static_cast<T>(0); } 1360f7aaf530b2aad644d4aab01c493517dedf3f62fdaniel@transgaming.com static T one() { return static_cast<T>(1); } 1370f7aaf530b2aad644d4aab01c493517dedf3f62fdaniel@transgaming.com}; 1380f7aaf530b2aad644d4aab01c493517dedf3f62fdaniel@transgaming.com 1390f7aaf530b2aad644d4aab01c493517dedf3f62fdaniel@transgaming.com// But normalised types only store [0,1] or [-1,1] so 1.0 is represented by the max value. 1400f7aaf530b2aad644d4aab01c493517dedf3f62fdaniel@transgaming.comtemplate <class T> 1410f7aaf530b2aad644d4aab01c493517dedf3f62fdaniel@transgaming.comstruct NormalizedDefaultValues 1420f7aaf530b2aad644d4aab01c493517dedf3f62fdaniel@transgaming.com{ 1430f7aaf530b2aad644d4aab01c493517dedf3f62fdaniel@transgaming.com static T zero() { return static_cast<T>(0); } 1440f7aaf530b2aad644d4aab01c493517dedf3f62fdaniel@transgaming.com static T one() { return std::numeric_limits<T>::max(); } 1450f7aaf530b2aad644d4aab01c493517dedf3f62fdaniel@transgaming.com}; 1460f7aaf530b2aad644d4aab01c493517dedf3f62fdaniel@transgaming.com 1470f7aaf530b2aad644d4aab01c493517dedf3f62fdaniel@transgaming.com// Converter: 1480f7aaf530b2aad644d4aab01c493517dedf3f62fdaniel@transgaming.com// static const bool identity: true if this is an identity transform (with no widening) 1490f7aaf530b2aad644d4aab01c493517dedf3f62fdaniel@transgaming.com// static const std::size_t finalSize: number of bytes per output vertex 1500f7aaf530b2aad644d4aab01c493517dedf3f62fdaniel@transgaming.com// 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. 1510f7aaf530b2aad644d4aab01c493517dedf3f62fdaniel@transgaming.com 1520f7aaf530b2aad644d4aab01c493517dedf3f62fdaniel@transgaming.comtemplate <class InT, class WidenRule, class Converter, class DefaultValueRule = SimpleDefaultValues<InT> > 1530f7aaf530b2aad644d4aab01c493517dedf3f62fdaniel@transgaming.comstruct VertexDataConverter 1540f7aaf530b2aad644d4aab01c493517dedf3f62fdaniel@transgaming.com{ 1550f7aaf530b2aad644d4aab01c493517dedf3f62fdaniel@transgaming.com typedef typename Converter::OutputType OutputType; 1560f7aaf530b2aad644d4aab01c493517dedf3f62fdaniel@transgaming.com typedef InT InputType; 1570f7aaf530b2aad644d4aab01c493517dedf3f62fdaniel@transgaming.com 1580f7aaf530b2aad644d4aab01c493517dedf3f62fdaniel@transgaming.com static const bool identity = (WidenRule::initialWidth == WidenRule::finalWidth) && Converter::identity; 1590f7aaf530b2aad644d4aab01c493517dedf3f62fdaniel@transgaming.com static const std::size_t finalSize = WidenRule::finalWidth * sizeof(OutputType); 1600f7aaf530b2aad644d4aab01c493517dedf3f62fdaniel@transgaming.com 16145965b102fbff399c3e39aeeabf55f146c75caabGeoff Lang static void convertArray(const uint8_t *input, size_t stride, size_t n, uint8_t *output) 1620f7aaf530b2aad644d4aab01c493517dedf3f62fdaniel@transgaming.com { 16345965b102fbff399c3e39aeeabf55f146c75caabGeoff Lang OutputType *out = reinterpret_cast<OutputType*>(output); 16445965b102fbff399c3e39aeeabf55f146c75caabGeoff Lang 1650f7aaf530b2aad644d4aab01c493517dedf3f62fdaniel@transgaming.com for (std::size_t i = 0; i < n; i++) 1660f7aaf530b2aad644d4aab01c493517dedf3f62fdaniel@transgaming.com { 16745965b102fbff399c3e39aeeabf55f146c75caabGeoff Lang const InputType *ein = reinterpret_cast<const InputType*>(input + i * stride); 1680f7aaf530b2aad644d4aab01c493517dedf3f62fdaniel@transgaming.com 1690f7aaf530b2aad644d4aab01c493517dedf3f62fdaniel@transgaming.com copyComponent(out, ein, 0, static_cast<OutputType>(DefaultValueRule::zero())); 1700f7aaf530b2aad644d4aab01c493517dedf3f62fdaniel@transgaming.com copyComponent(out, ein, 1, static_cast<OutputType>(DefaultValueRule::zero())); 1710f7aaf530b2aad644d4aab01c493517dedf3f62fdaniel@transgaming.com copyComponent(out, ein, 2, static_cast<OutputType>(DefaultValueRule::zero())); 1720f7aaf530b2aad644d4aab01c493517dedf3f62fdaniel@transgaming.com copyComponent(out, ein, 3, static_cast<OutputType>(DefaultValueRule::one())); 1730f7aaf530b2aad644d4aab01c493517dedf3f62fdaniel@transgaming.com 1740f7aaf530b2aad644d4aab01c493517dedf3f62fdaniel@transgaming.com out += WidenRule::finalWidth; 1750f7aaf530b2aad644d4aab01c493517dedf3f62fdaniel@transgaming.com } 1760f7aaf530b2aad644d4aab01c493517dedf3f62fdaniel@transgaming.com } 1770f7aaf530b2aad644d4aab01c493517dedf3f62fdaniel@transgaming.com 1780f7aaf530b2aad644d4aab01c493517dedf3f62fdaniel@transgaming.com private: 1790f7aaf530b2aad644d4aab01c493517dedf3f62fdaniel@transgaming.com static void copyComponent(OutputType *out, const InputType *in, std::size_t elementindex, OutputType defaultvalue) 1800f7aaf530b2aad644d4aab01c493517dedf3f62fdaniel@transgaming.com { 1810f7aaf530b2aad644d4aab01c493517dedf3f62fdaniel@transgaming.com if (WidenRule::finalWidth > elementindex) 1820f7aaf530b2aad644d4aab01c493517dedf3f62fdaniel@transgaming.com { 1830f7aaf530b2aad644d4aab01c493517dedf3f62fdaniel@transgaming.com if (WidenRule::initialWidth > elementindex) 1840f7aaf530b2aad644d4aab01c493517dedf3f62fdaniel@transgaming.com { 185c21c227174ae9b23d4b719ca42694646d8dea122daniel@transgaming.com out[elementindex] = Converter::convert(in[elementindex]); 1860f7aaf530b2aad644d4aab01c493517dedf3f62fdaniel@transgaming.com } 1870f7aaf530b2aad644d4aab01c493517dedf3f62fdaniel@transgaming.com else 1880f7aaf530b2aad644d4aab01c493517dedf3f62fdaniel@transgaming.com { 189c21c227174ae9b23d4b719ca42694646d8dea122daniel@transgaming.com out[elementindex] = defaultvalue; 1900f7aaf530b2aad644d4aab01c493517dedf3f62fdaniel@transgaming.com } 1910f7aaf530b2aad644d4aab01c493517dedf3f62fdaniel@transgaming.com } 1920f7aaf530b2aad644d4aab01c493517dedf3f62fdaniel@transgaming.com } 1930f7aaf530b2aad644d4aab01c493517dedf3f62fdaniel@transgaming.com}; 1940f7aaf530b2aad644d4aab01c493517dedf3f62fdaniel@transgaming.com 1950f7aaf530b2aad644d4aab01c493517dedf3f62fdaniel@transgaming.com} 1960f7aaf530b2aad644d4aab01c493517dedf3f62fdaniel@transgaming.com 1978fd34bd649a855dab9f5dc3505e40ecb14a01d70daniel@transgaming.com#endif // LIBGLESV2_VERTEXCONVERSION_H_ 198