2 // Copyright (c) 2002-2012 The ANGLE Project Authors. All rights reserved.
3 // Use of this source code is governed by a BSD-style license that can be
4 // found in the LICENSE file.
7 // generatemip.h: Defines the GenerateMip function, templated on the format
8 // type of the image for which mip levels are being generated.
10 #ifndef LIBGLESV2_RENDERER_GENERATEMIP_H_
11 #define LIBGLESV2_RENDERER_GENERATEMIP_H_
13 #include "common/mathutil.h"
14 #include "imageformats.h"
23 static inline T *GetPixel(void *data, unsigned int x, unsigned int y, unsigned int z, unsigned int rowPitch, unsigned int depthPitch)
25 return reinterpret_cast<T*>(reinterpret_cast<unsigned char*>(data) + (x * sizeof(T)) + (y * rowPitch) + (z * depthPitch));
29 static inline const T *GetPixel(const void *data, unsigned int x, unsigned int y, unsigned int z, unsigned int rowPitch, unsigned int depthPitch)
31 return reinterpret_cast<const T*>(reinterpret_cast<const unsigned char*>(data) + (x * sizeof(T)) + (y * rowPitch) + (z * depthPitch));
35 static void GenerateMip_Y(unsigned int sourceWidth, unsigned int sourceHeight, unsigned int sourceDepth,
36 const unsigned char *sourceData, int sourceRowPitch, int sourceDepthPitch,
37 unsigned int destWidth, unsigned int destHeight, unsigned int destDepth,
38 unsigned char *destData, int destRowPitch, int destDepthPitch)
40 ASSERT(sourceWidth == 1);
41 ASSERT(sourceHeight > 1);
42 ASSERT(sourceDepth == 1);
44 for (unsigned int y = 0; y < destHeight; y++)
46 const T *src0 = GetPixel<T>(sourceData, 0, y * 2, 0, sourceRowPitch, sourceDepthPitch);
47 const T *src1 = GetPixel<T>(sourceData, 0, y * 2 + 1, 0, sourceRowPitch, sourceDepthPitch);
48 T *dst = GetPixel<T>(destData, 0, y, 0, destRowPitch, destDepthPitch);
50 T::average(dst, src0, src1);
55 static void GenerateMip_X(unsigned int sourceWidth, unsigned int sourceHeight, unsigned int sourceDepth,
56 const unsigned char *sourceData, int sourceRowPitch, int sourceDepthPitch,
57 unsigned int destWidth, unsigned int destHeight, unsigned int destDepth,
58 unsigned char *destData, int destRowPitch, int destDepthPitch)
60 ASSERT(sourceWidth > 1);
61 ASSERT(sourceHeight == 1);
62 ASSERT(sourceDepth == 1);
64 for (unsigned int x = 0; x < destWidth; x++)
66 const T *src0 = GetPixel<T>(sourceData, x * 2, 0, 0, sourceRowPitch, sourceDepthPitch);
67 const T *src1 = GetPixel<T>(sourceData, x * 2 + 1, 0, 0, sourceRowPitch, sourceDepthPitch);
68 T *dst = GetPixel<T>(destData, x, 0, 0, destRowPitch, destDepthPitch);
70 T::average(dst, src0, src1);
75 static void GenerateMip_Z(unsigned int sourceWidth, unsigned int sourceHeight, unsigned int sourceDepth,
76 const unsigned char *sourceData, int sourceRowPitch, int sourceDepthPitch,
77 unsigned int destWidth, unsigned int destHeight, unsigned int destDepth,
78 unsigned char *destData, int destRowPitch, int destDepthPitch)
80 ASSERT(sourceWidth == 1);
81 ASSERT(sourceHeight == 1);
82 ASSERT(sourceDepth > 1);
84 for (unsigned int z = 0; z < destDepth; z++)
86 const T *src0 = GetPixel<T>(sourceData, 0, 0, z * 2, sourceRowPitch, sourceDepthPitch);
87 const T *src1 = GetPixel<T>(sourceData, 0, 0, z * 2 + 1, sourceRowPitch, sourceDepthPitch);
88 T *dst = GetPixel<T>(destData, 0, 0, z, destRowPitch, destDepthPitch);
90 T::average(dst, src0, src1);
95 static void GenerateMip_XY(unsigned int sourceWidth, unsigned int sourceHeight, unsigned int sourceDepth,
96 const unsigned char *sourceData, int sourceRowPitch, int sourceDepthPitch,
97 unsigned int destWidth, unsigned int destHeight, unsigned int destDepth,
98 unsigned char *destData, int destRowPitch, int destDepthPitch)
100 ASSERT(sourceWidth > 1);
101 ASSERT(sourceHeight > 1);
102 ASSERT(sourceDepth == 1);
104 for (unsigned int y = 0; y < destHeight; y++)
106 for (unsigned int x = 0; x < destWidth; x++)
108 const T *src0 = GetPixel<T>(sourceData, x * 2, y * 2, 0, sourceRowPitch, sourceDepthPitch);
109 const T *src1 = GetPixel<T>(sourceData, x * 2, y * 2 + 1, 0, sourceRowPitch, sourceDepthPitch);
110 const T *src2 = GetPixel<T>(sourceData, x * 2 + 1, y * 2, 0, sourceRowPitch, sourceDepthPitch);
111 const T *src3 = GetPixel<T>(sourceData, x * 2 + 1, y * 2 + 1, 0, sourceRowPitch, sourceDepthPitch);
112 T *dst = GetPixel<T>(destData, x, y, 0, destRowPitch, destDepthPitch);
116 T::average(&tmp0, src0, src1);
117 T::average(&tmp1, src2, src3);
118 T::average(dst, &tmp0, &tmp1);
123 template <typename T>
124 static void GenerateMip_YZ(unsigned int sourceWidth, unsigned int sourceHeight, unsigned int sourceDepth,
125 const unsigned char *sourceData, int sourceRowPitch, int sourceDepthPitch,
126 unsigned int destWidth, unsigned int destHeight, unsigned int destDepth,
127 unsigned char *destData, int destRowPitch, int destDepthPitch)
129 ASSERT(sourceWidth == 1);
130 ASSERT(sourceHeight > 1);
131 ASSERT(sourceDepth > 1);
133 for (unsigned int z = 0; z < destDepth; z++)
135 for (unsigned int y = 0; y < destHeight; y++)
137 const T *src0 = GetPixel<T>(sourceData, 0, y * 2, z * 2, sourceRowPitch, sourceDepthPitch);
138 const T *src1 = GetPixel<T>(sourceData, 0, y * 2, z * 2 + 1, sourceRowPitch, sourceDepthPitch);
139 const T *src2 = GetPixel<T>(sourceData, 0, y * 2 + 1, z * 2, sourceRowPitch, sourceDepthPitch);
140 const T *src3 = GetPixel<T>(sourceData, 0, y * 2 + 1, z * 2 + 1, sourceRowPitch, sourceDepthPitch);
141 T *dst = GetPixel<T>(destData, 0, y, z, destRowPitch, destDepthPitch);
145 T::average(&tmp0, src0, src1);
146 T::average(&tmp1, src2, src3);
147 T::average(dst, &tmp0, &tmp1);
152 template <typename T>
153 static void GenerateMip_XZ(unsigned int sourceWidth, unsigned int sourceHeight, unsigned int sourceDepth,
154 const unsigned char *sourceData, int sourceRowPitch, int sourceDepthPitch,
155 unsigned int destWidth, unsigned int destHeight, unsigned int destDepth,
156 unsigned char *destData, int destRowPitch, int destDepthPitch)
158 ASSERT(sourceWidth > 1);
159 ASSERT(sourceHeight == 1);
160 ASSERT(sourceDepth > 1);
162 for (unsigned int z = 0; z < destDepth; z++)
164 for (unsigned int x = 0; x < destWidth; x++)
166 const T *src0 = GetPixel<T>(sourceData, x * 2, 0, z * 2, sourceRowPitch, sourceDepthPitch);
167 const T *src1 = GetPixel<T>(sourceData, x * 2, 0, z * 2 + 1, sourceRowPitch, sourceDepthPitch);
168 const T *src2 = GetPixel<T>(sourceData, x * 2 + 1, 0, z * 2, sourceRowPitch, sourceDepthPitch);
169 const T *src3 = GetPixel<T>(sourceData, x * 2 + 1, 0, z * 2 + 1, sourceRowPitch, sourceDepthPitch);
170 T *dst = GetPixel<T>(destData, x, 0, z, destRowPitch, destDepthPitch);
174 T::average(&tmp0, src0, src1);
175 T::average(&tmp1, src2, src3);
176 T::average(dst, &tmp0, &tmp1);
181 template <typename T>
182 static void GenerateMip_XYZ(unsigned int sourceWidth, unsigned int sourceHeight, unsigned int sourceDepth,
183 const unsigned char *sourceData, int sourceRowPitch, int sourceDepthPitch,
184 unsigned int destWidth, unsigned int destHeight, unsigned int destDepth,
185 unsigned char *destData, int destRowPitch, int destDepthPitch)
187 ASSERT(sourceWidth > 1);
188 ASSERT(sourceHeight > 1);
189 ASSERT(sourceDepth > 1);
191 for (unsigned int z = 0; z < destDepth; z++)
193 for (unsigned int y = 0; y < destHeight; y++)
195 for (unsigned int x = 0; x < destWidth; x++)
197 const T *src0 = GetPixel<T>(sourceData, x * 2, y * 2, z * 2, sourceRowPitch, sourceDepthPitch);
198 const T *src1 = GetPixel<T>(sourceData, x * 2, y * 2, z * 2 + 1, sourceRowPitch, sourceDepthPitch);
199 const T *src2 = GetPixel<T>(sourceData, x * 2, y * 2 + 1, z * 2, sourceRowPitch, sourceDepthPitch);
200 const T *src3 = GetPixel<T>(sourceData, x * 2, y * 2 + 1, z * 2 + 1, sourceRowPitch, sourceDepthPitch);
201 const T *src4 = GetPixel<T>(sourceData, x * 2 + 1, y * 2, z * 2, sourceRowPitch, sourceDepthPitch);
202 const T *src5 = GetPixel<T>(sourceData, x * 2 + 1, y * 2, z * 2 + 1, sourceRowPitch, sourceDepthPitch);
203 const T *src6 = GetPixel<T>(sourceData, x * 2 + 1, y * 2 + 1, z * 2, sourceRowPitch, sourceDepthPitch);
204 const T *src7 = GetPixel<T>(sourceData, x * 2 + 1, y * 2 + 1, z * 2 + 1, sourceRowPitch, sourceDepthPitch);
205 T *dst = GetPixel<T>(destData, x, y, z, destRowPitch, destDepthPitch);
207 T tmp0, tmp1, tmp2, tmp3, tmp4, tmp5;
209 T::average(&tmp0, src0, src1);
210 T::average(&tmp1, src2, src3);
211 T::average(&tmp2, src4, src5);
212 T::average(&tmp3, src6, src7);
214 T::average(&tmp4, &tmp0, &tmp1);
215 T::average(&tmp5, &tmp2, &tmp3);
217 T::average(dst, &tmp4, &tmp5);
224 typedef void (*MipGenerationFunction)(unsigned int sourceWidth, unsigned int sourceHeight, unsigned int sourceDepth,
225 const unsigned char *sourceData, int sourceRowPitch, int sourceDepthPitch,
226 unsigned int destWidth, unsigned int destHeight, unsigned int destDepth,
227 unsigned char *destData, int destRowPitch, int destDepthPitch);
229 template <typename T>
230 static MipGenerationFunction GetMipGenerationFunction(unsigned int sourceWidth, unsigned int sourceHeight, unsigned int sourceDepth)
232 unsigned char index = ((sourceWidth > 1) ? 1 : 0) |
233 ((sourceHeight > 1) ? 2 : 0) |
234 ((sourceDepth > 1) ? 4 : 0);
238 case 1: return GenerateMip_X<T>; // W x 1 x 1
239 case 2: return GenerateMip_Y<T>; // 1 x H x 1
240 case 3: return GenerateMip_XY<T>; // W x H x 1
241 case 4: return GenerateMip_Z<T>; // 1 x 1 x D
242 case 5: return GenerateMip_XZ<T>; // W x 1 x D
243 case 6: return GenerateMip_YZ<T>; // 1 x H x D
244 case 7: return GenerateMip_XYZ<T>; // W x H x D
245 default: return NULL;
251 template <typename T>
252 static void GenerateMip(unsigned int sourceWidth, unsigned int sourceHeight, unsigned int sourceDepth,
253 const unsigned char *sourceData, int sourceRowPitch, int sourceDepthPitch,
254 unsigned char *destData, int destRowPitch, int destDepthPitch)
256 unsigned int mipWidth = std::max(1U, sourceWidth >> 1);
257 unsigned int mipHeight = std::max(1U, sourceHeight >> 1);
258 unsigned int mipDepth = std::max(1U, sourceDepth >> 1);
260 priv::MipGenerationFunction generationFunction = priv::GetMipGenerationFunction<T>(sourceWidth, sourceHeight, sourceDepth);
261 ASSERT(generationFunction != NULL);
263 generationFunction(sourceWidth, sourceHeight, sourceDepth, sourceData, sourceRowPitch, sourceDepthPitch,
264 mipWidth, mipHeight, mipDepth, destData, destRowPitch, destDepthPitch);
269 #endif // LIBGLESV2_RENDERER_GENERATEMIP_H_