swizzle.h
Engine/source/core/util/swizzle.h
Classes:
class
class
This class will swizzle 'sizeof( T )' length chunks of memory into different patterns which are user described.
Namespaces:
namespace
Detailed Description
1 2//----------------------------------------------------------------------------- 3// Copyright (c) 2012 GarageGames, LLC 4// 5// Permission is hereby granted, free of charge, to any person obtaining a copy 6// of this software and associated documentation files (the "Software"), to 7// deal in the Software without restriction, including without limitation the 8// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 9// sell copies of the Software, and to permit persons to whom the Software is 10// furnished to do so, subject to the following conditions: 11// 12// The above copyright notice and this permission notice shall be included in 13// all copies or substantial portions of the Software. 14// 15// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 20// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 21// IN THE SOFTWARE. 22//----------------------------------------------------------------------------- 23 24#ifndef _SWIZZLE_H_ 25#define _SWIZZLE_H_ 26 27#include "platform/platform.h" 28#include "core/frameAllocator.h" 29 30/// This class will swizzle 'sizeof( T )' length chunks of memory into different 31/// patterns which are user described. The pattern is described by an instance 32/// of Swizzle and this swizzle can then be executed on buffers. The following 33/// must be true of the buffer size: 34/// size % ( sizeof( T ) * mapLength ) == 0 35template<class T, dsize_t mapLength> 36class Swizzle 37{ 38private: 39 /// This is an array from 0..n. Each entry in the array is a dsize_t with values 40 /// in the range 0..n. Each value in the range 0..n can occur any number of times. 41 /// 42 /// For example: 43 /// This is our data set, an array of characters with 4 elements 44 /// { 'a', 'b', 'c', 'd' } 45 /// 46 /// If the map { 3, 2, 1, 0 } was applied to this set, the result would be: 47 /// { 'd', 'c', 'b', 'a' } 48 /// 49 /// If the map { 3, 0, 2, 2 } was applied to the set, the result would be: 50 /// { 'd', 'a', 'c', 'c' } 51 dsize_t mMap[mapLength]; 52 53public: 54 /// Construct a swizzle 55 /// @see Swizzle::mMap 56 Swizzle( const dsize_t *map ); 57 58 virtual ~Swizzle(){} 59 60 /// This method will, in the general case, use the ToBuffer method to swizzle 61 /// the memory specified into a temporary buffer, allocated by FrameTemp, and 62 /// then copy the temporary memory into the source memory. 63 /// 64 /// @param memory Pointer to the start of the buffer to swizzle 65 /// @param size Size of the buffer 66 virtual void InPlace( void *memory, const dsize_t size ) const; 67 68 /// This method copies the data from source to destination while applying the 69 /// re-ordering. This method is, in the non-specalized case, O(N^2) where N 70 /// is sizeof( T ) / size; the number of instances of type 'T' in the buffer 71 /// 72 /// @param destination The destination of the swizzled data 73 /// @param source The source data to be swizzled 74 /// @param size Size of the source and destination buffers. 75 virtual void ToBuffer( void *destination, const void *source, const dsize_t size ) const; 76}; 77 78// Null swizzle 79template<class T, dsize_t mapLength> 80class NullSwizzle : public Swizzle<T, mapLength> 81{ 82public: 83 NullSwizzle( const dsize_t *map = NULL ) : Swizzle<T, mapLength>( map ) {}; 84 85 virtual void InPlace( void *memory, const dsize_t size ) const {} 86 87 virtual void ToBuffer( void *destination, const void *source, const dsize_t size ) const 88 { 89 dMemcpy( destination, source, size ); 90 } 91}; 92 93//------------------------------------------------------------------------------ 94// Common Swizzles 95namespace Swizzles 96{ 97 extern Swizzle<U8, 4> bgra; 98 extern Swizzle<U8, 4> argb; 99 extern Swizzle<U8, 4> rgba; 100 extern Swizzle<U8, 4> abgr; 101 102 extern Swizzle<U8, 3> bgr; 103 extern Swizzle<U8, 3> rgb; 104 105 extern NullSwizzle<U8, 4> null; 106}; 107 108//------------------------------------------------------------------------------ 109 110template<class T, dsize_t mapLength> 111Swizzle<T, mapLength>::Swizzle( const dsize_t *map ) 112{ 113 if( map != NULL ) 114 dMemcpy( mMap, map, sizeof( dsize_t ) * mapLength ); 115} 116 117//------------------------------------------------------------------------------ 118 119template<class T, dsize_t mapLength> 120inline void Swizzle<T, mapLength>::ToBuffer( void *destination, const void *source, const dsize_t size ) const 121{ 122 // TODO: OpenMP? 123 AssertFatal( size % ( sizeof( T ) * mapLength ) == 0, "Bad buffer size for swizzle, see docs." ); 124 if (!destination || !source) return; 125 126 T *dest = reinterpret_cast<T *>( destination ); 127 const T *src = reinterpret_cast<const T *>( source ); 128 129 for( S32 i = 0; i < size / ( mapLength * sizeof( T ) ); i++ ) 130 { 131 for( S32 j = 0; j < mapLength; j++ ) 132 *dest++ = src[mMap[j]]; 133 134 src += mapLength; 135 } 136} 137 138//------------------------------------------------------------------------------ 139 140template<class T, dsize_t mapLength> 141inline void Swizzle<T, mapLength>::InPlace( void *memory, const dsize_t size ) const 142{ 143 // Just in case the inliner messes up the FrameTemp scoping (not sure if it would) -patw 144 { 145 // FrameTemp should work because the PNG loading code uses the FrameAllocator, so 146 // it should only get used on an image w/ that size as max -patw 147 FrameTemp<U8> buffer( size ); 148 dMemcpy( ~buffer, memory, size ); 149 ToBuffer( memory, ~buffer, size ); 150 } 151} 152 153//------------------------------------------------------------------------------ 154 155// Template specializations for certain swizzles 156//#include "core/util/swizzleSpec.h" 157 158#endif 159