swizzle.h

Engine/source/core/util/swizzle.h

More...

Classes:

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