3177a2b1f39199266f27259b449c738e4cea34bf
[platform/framework/web/crosswalk.git] / src / third_party / angle / src / libGLESv2 / renderer / generatemip.h
1 //
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.
5 //
6
7 // generatemip.h: Defines the GenerateMip function, templated on the format
8 // type of the image for which mip levels are being generated.
9
10 #ifndef LIBGLESV2_RENDERER_GENERATEMIP_H_
11 #define LIBGLESV2_RENDERER_GENERATEMIP_H_
12
13 #include "common/mathutil.h"
14 #include "imageformats.h"
15
16 namespace rx
17 {
18
19 namespace priv
20 {
21
22 template <typename T>
23 static inline T *GetPixel(void *data, unsigned int x, unsigned int y, unsigned int z, unsigned int rowPitch, unsigned int depthPitch)
24 {
25     return reinterpret_cast<T*>(reinterpret_cast<unsigned char*>(data) + (x * sizeof(T)) + (y * rowPitch) + (z * depthPitch));
26 }
27
28 template <typename T>
29 static inline const T *GetPixel(const void *data, unsigned int x, unsigned int y, unsigned int z, unsigned int rowPitch, unsigned int depthPitch)
30 {
31     return reinterpret_cast<const T*>(reinterpret_cast<const unsigned char*>(data) + (x * sizeof(T)) + (y * rowPitch) + (z * depthPitch));
32 }
33
34 template <typename T>
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)
39 {
40     ASSERT(sourceWidth == 1);
41     ASSERT(sourceHeight > 1);
42     ASSERT(sourceDepth == 1);
43
44     for (unsigned int y = 0; y < destHeight; y++)
45     {
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);
49
50         T::average(dst, src0, src1);
51     }
52 }
53
54 template <typename T>
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)
59 {
60     ASSERT(sourceWidth > 1);
61     ASSERT(sourceHeight == 1);
62     ASSERT(sourceDepth == 1);
63
64     for (unsigned int x = 0; x < destWidth; x++)
65     {
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);
69
70         T::average(dst, src0, src1);
71     }
72 }
73
74 template <typename T>
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)
79 {
80     ASSERT(sourceWidth == 1);
81     ASSERT(sourceHeight == 1);
82     ASSERT(sourceDepth > 1);
83
84     for (unsigned int z = 0; z < destDepth; z++)
85     {
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);
89
90         T::average(dst, src0, src1);
91     }
92 }
93
94 template <typename T>
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)
99 {
100     ASSERT(sourceWidth > 1);
101     ASSERT(sourceHeight > 1);
102     ASSERT(sourceDepth == 1);
103
104     for (unsigned int y = 0; y < destHeight; y++)
105     {
106         for (unsigned int x = 0; x < destWidth; x++)
107         {
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);
113
114             T tmp0, tmp1;
115
116             T::average(&tmp0, src0, src1);
117             T::average(&tmp1, src2, src3);
118             T::average(dst, &tmp0, &tmp1);
119         }
120     }
121 }
122
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)
128 {
129     ASSERT(sourceWidth == 1);
130     ASSERT(sourceHeight > 1);
131     ASSERT(sourceDepth > 1);
132
133     for (unsigned int z = 0; z < destDepth; z++)
134     {
135         for (unsigned int y = 0; y < destHeight; y++)
136         {
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);
142
143             T tmp0, tmp1;
144
145             T::average(&tmp0, src0, src1);
146             T::average(&tmp1, src2, src3);
147             T::average(dst, &tmp0, &tmp1);
148         }
149     }
150 }
151
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)
157 {
158     ASSERT(sourceWidth > 1);
159     ASSERT(sourceHeight == 1);
160     ASSERT(sourceDepth > 1);
161
162     for (unsigned int z = 0; z < destDepth; z++)
163     {
164         for (unsigned int x = 0; x < destWidth; x++)
165         {
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);
171
172             T tmp0, tmp1;
173
174             T::average(&tmp0, src0, src1);
175             T::average(&tmp1, src2, src3);
176             T::average(dst, &tmp0, &tmp1);
177         }
178     }
179 }
180
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)
186 {
187     ASSERT(sourceWidth > 1);
188     ASSERT(sourceHeight > 1);
189     ASSERT(sourceDepth > 1);
190
191     for (unsigned int z = 0; z < destDepth; z++)
192     {
193         for (unsigned int y = 0; y < destHeight; y++)
194         {
195             for (unsigned int x = 0; x < destWidth; x++)
196             {
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);
206
207                 T tmp0, tmp1, tmp2, tmp3, tmp4, tmp5;
208
209                 T::average(&tmp0, src0, src1);
210                 T::average(&tmp1, src2, src3);
211                 T::average(&tmp2, src4, src5);
212                 T::average(&tmp3, src6, src7);
213
214                 T::average(&tmp4, &tmp0, &tmp1);
215                 T::average(&tmp5, &tmp2, &tmp3);
216
217                 T::average(dst, &tmp4, &tmp5);
218             }
219         }
220     }
221 }
222
223
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);
228
229 template <typename T>
230 static MipGenerationFunction GetMipGenerationFunction(unsigned int sourceWidth, unsigned int sourceHeight, unsigned int sourceDepth)
231 {
232     unsigned char index = ((sourceWidth > 1)  ? 1 : 0) |
233                           ((sourceHeight > 1) ? 2 : 0) |
234                           ((sourceDepth > 1)  ? 4 : 0);
235
236     switch (index)
237     {
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;
246     }
247 }
248
249 }
250
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)
255 {
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);
259
260     priv::MipGenerationFunction generationFunction = priv::GetMipGenerationFunction<T>(sourceWidth, sourceHeight, sourceDepth);
261     ASSERT(generationFunction != NULL);
262
263     generationFunction(sourceWidth, sourceHeight, sourceDepth, sourceData, sourceRowPitch, sourceDepthPitch,
264                        mipWidth, mipHeight, mipDepth, destData, destRowPitch, destDepthPitch);
265 }
266
267 }
268
269 #endif // LIBGLESV2_RENDERER_GENERATEMIP_H_