• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2 * Copyright (C) 2011 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16 #include <GLcommon/TextureUtils.h>
17 #include <GLcommon/GLESmacros.h>
18 #include <GLcommon/GLDispatch.h>
19 #include <GLcommon/GLESvalidate.h>
20 #include <stdio.h>
21 #include <cmath>
22 #include <memory>
23 
24 #include "base/AlignedBuf.h"
25 
26 #include <astc-codec/astc-codec.h>
27 
28 using android::AlignedBuf;
29 
30 #define GL_R16 0x822A
31 #define GL_RG16 0x822C
32 #define GL_R16_SNORM 0x8F98
33 #define GL_RG16_SNORM 0x8F99
34 
35 static constexpr size_t kASTCFormatsCount = 28;
36 
37 #define ASTC_FORMATS_LIST(EXPAND_MACRO) \
38     EXPAND_MACRO(GL_COMPRESSED_RGBA_ASTC_4x4_KHR, astc_codec::FootprintType::k4x4, false) \
39     EXPAND_MACRO(GL_COMPRESSED_RGBA_ASTC_5x4_KHR, astc_codec::FootprintType::k5x4, false) \
40     EXPAND_MACRO(GL_COMPRESSED_RGBA_ASTC_5x5_KHR, astc_codec::FootprintType::k5x5, false) \
41     EXPAND_MACRO(GL_COMPRESSED_RGBA_ASTC_6x5_KHR, astc_codec::FootprintType::k6x5, false) \
42     EXPAND_MACRO(GL_COMPRESSED_RGBA_ASTC_6x6_KHR, astc_codec::FootprintType::k6x6, false) \
43     EXPAND_MACRO(GL_COMPRESSED_RGBA_ASTC_8x5_KHR, astc_codec::FootprintType::k8x5, false) \
44     EXPAND_MACRO(GL_COMPRESSED_RGBA_ASTC_8x6_KHR, astc_codec::FootprintType::k8x6, false) \
45     EXPAND_MACRO(GL_COMPRESSED_RGBA_ASTC_8x8_KHR, astc_codec::FootprintType::k8x8, false) \
46     EXPAND_MACRO(GL_COMPRESSED_RGBA_ASTC_10x5_KHR, astc_codec::FootprintType::k10x5, false) \
47     EXPAND_MACRO(GL_COMPRESSED_RGBA_ASTC_10x6_KHR, astc_codec::FootprintType::k10x6, false) \
48     EXPAND_MACRO(GL_COMPRESSED_RGBA_ASTC_10x8_KHR, astc_codec::FootprintType::k10x8, false) \
49     EXPAND_MACRO(GL_COMPRESSED_RGBA_ASTC_10x10_KHR, astc_codec::FootprintType::k10x10, false) \
50     EXPAND_MACRO(GL_COMPRESSED_RGBA_ASTC_12x10_KHR, astc_codec::FootprintType::k12x10, false) \
51     EXPAND_MACRO(GL_COMPRESSED_RGBA_ASTC_12x12_KHR, astc_codec::FootprintType::k12x12, false) \
52     EXPAND_MACRO(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR, astc_codec::FootprintType::k4x4, true) \
53     EXPAND_MACRO(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR, astc_codec::FootprintType::k5x4, true) \
54     EXPAND_MACRO(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR, astc_codec::FootprintType::k5x5, true) \
55     EXPAND_MACRO(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR, astc_codec::FootprintType::k6x5, true) \
56     EXPAND_MACRO(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR, astc_codec::FootprintType::k6x6, true) \
57     EXPAND_MACRO(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR, astc_codec::FootprintType::k8x5, true) \
58     EXPAND_MACRO(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR, astc_codec::FootprintType::k8x6, true) \
59     EXPAND_MACRO(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR, astc_codec::FootprintType::k8x8, true) \
60     EXPAND_MACRO(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR, astc_codec::FootprintType::k10x5, true) \
61     EXPAND_MACRO(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR, astc_codec::FootprintType::k10x6, true) \
62     EXPAND_MACRO(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR, astc_codec::FootprintType::k10x8, true) \
63     EXPAND_MACRO(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR, astc_codec::FootprintType::k10x10, true) \
64     EXPAND_MACRO(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR, astc_codec::FootprintType::k12x10, true) \
65     EXPAND_MACRO(GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR, astc_codec::FootprintType::k12x12, true) \
66 
getCompressedFormats(int majorVersion,int * formats)67 int getCompressedFormats(int majorVersion, int* formats) {
68     static constexpr size_t kCount = MAX_SUPPORTED_PALETTE + MAX_ETC_SUPPORTED + kASTCFormatsCount;
69     int res = kCount;
70 
71     if (majorVersion > 1) {
72         res -= MAX_SUPPORTED_PALETTE;
73     }
74 
75     if (formats) {
76         size_t i = 0;
77 
78         if (1 == majorVersion) {
79             // Palette
80             formats[i++] = GL_PALETTE4_RGBA8_OES;
81             formats[i++] = GL_PALETTE4_RGBA4_OES;
82             formats[i++] = GL_PALETTE8_RGBA8_OES;
83             formats[i++] = GL_PALETTE8_RGBA4_OES;
84             formats[i++] = GL_PALETTE4_RGB8_OES;
85             formats[i++] = GL_PALETTE8_RGB8_OES;
86             formats[i++] = GL_PALETTE4_RGB5_A1_OES;
87             formats[i++] = GL_PALETTE8_RGB5_A1_OES;
88             formats[i++] = GL_PALETTE4_R5_G6_B5_OES;
89             formats[i++] = GL_PALETTE8_R5_G6_B5_OES;
90         }
91 
92         // ETC
93         formats[i++] = GL_ETC1_RGB8_OES;
94         formats[i++] = GL_COMPRESSED_RGB8_ETC2;
95         formats[i++] = GL_COMPRESSED_SIGNED_R11_EAC;
96         formats[i++] = GL_COMPRESSED_RG11_EAC;
97         formats[i++] = GL_COMPRESSED_SIGNED_RG11_EAC;
98         formats[i++] = GL_COMPRESSED_RGB8_ETC2;
99         formats[i++] = GL_COMPRESSED_SRGB8_ETC2;
100         formats[i++] = GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2;
101         formats[i++] = GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2;
102         formats[i++] = GL_COMPRESSED_RGBA8_ETC2_EAC;
103         formats[i++] = GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC;
104         formats[i++] = GL_COMPRESSED_R11_EAC;
105 
106         // ASTC
107 #define ASTC_FORMAT(typeName, footprintType, srgbValue) \
108         formats[i++] = typeName;
109 
110         ASTC_FORMATS_LIST(ASTC_FORMAT)
111 #undef ASTC_FORMAT
112 
113     }
114 
115     return res;
116 }
117 
getEtcFormat(GLenum internalformat)118 ETC2ImageFormat getEtcFormat(GLenum internalformat) {
119     ETC2ImageFormat etcFormat = EtcRGB8;
120     switch (internalformat) {
121         case GL_COMPRESSED_RGB8_ETC2:
122         case GL_ETC1_RGB8_OES:
123             break;
124         case GL_COMPRESSED_RGBA8_ETC2_EAC:
125             etcFormat = EtcRGBA8;
126             break;
127         case GL_COMPRESSED_SRGB8_ETC2:
128             break;
129         case GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC:
130             etcFormat = EtcRGBA8;
131             break;
132         case GL_COMPRESSED_R11_EAC:
133             etcFormat = EtcR11;
134             break;
135         case GL_COMPRESSED_SIGNED_R11_EAC:
136             etcFormat = EtcSignedR11;
137             break;
138         case GL_COMPRESSED_RG11_EAC:
139             etcFormat = EtcRG11;
140             break;
141         case GL_COMPRESSED_SIGNED_RG11_EAC:
142             etcFormat = EtcSignedRG11;
143             break;
144         case GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2:
145             etcFormat = EtcRGB8A1;
146             break;
147         case GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2:
148             etcFormat = EtcRGB8A1;
149             break;
150     }
151     return etcFormat;
152 }
153 
getAstcFormatInfo(GLenum internalformat,astc_codec::FootprintType * footprint,bool * srgb)154 void getAstcFormatInfo(GLenum internalformat,
155                        astc_codec::FootprintType* footprint,
156                        bool* srgb) {
157     switch (internalformat) {
158 #define ASTC_FORMAT(typeName, footprintType, srgbValue) \
159         case typeName: \
160             *footprint = footprintType; *srgb = srgbValue; break; \
161 
162         ASTC_FORMATS_LIST(ASTC_FORMAT)
163 #undef ASTC_FORMAT
164         default:
165             assert(false && "Invalid ASTC format");
166             break;
167     }
168 }
169 
getAstcFormats(const GLint ** formats,size_t * formatsCount)170 void getAstcFormats(const GLint** formats, size_t* formatsCount) {
171     static constexpr GLint kATSCFormats[] = {
172 #define ASTC_FORMAT(typeName, footprintType, srgbValue) \
173         typeName,
174 
175         ASTC_FORMATS_LIST(ASTC_FORMAT)
176 #undef ASTC_FORMAT
177     };
178 
179     *formats = kATSCFormats;
180     *formatsCount = sizeof(kATSCFormats) / sizeof(kATSCFormats[0]);
181 }
182 
isAstcFormat(GLenum internalformat)183 bool isAstcFormat(GLenum internalformat) {
184     switch (internalformat) {
185 #define ASTC_FORMAT(typeName, footprintType, srgbValue) \
186         case typeName:
187 
188         ASTC_FORMATS_LIST(ASTC_FORMAT)
189 #undef ASTC_FORMAT
190             return true;
191         default:
192             return false;
193     }
194 }
195 
isEtcFormat(GLenum internalformat)196 bool isEtcFormat(GLenum internalformat) {
197     switch (internalformat) {
198     case GL_ETC1_RGB8_OES:
199     case GL_COMPRESSED_RGB8_ETC2:
200     case GL_COMPRESSED_SRGB8_ETC2:
201     case GL_COMPRESSED_RGBA8_ETC2_EAC:
202     case GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC:
203     case GL_COMPRESSED_R11_EAC:
204     case GL_COMPRESSED_SIGNED_R11_EAC:
205     case GL_COMPRESSED_RG11_EAC:
206     case GL_COMPRESSED_SIGNED_RG11_EAC:
207     case GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2:
208     case GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2:
209         return true;
210     }
211     return false;
212 }
213 
isEtc2Format(GLenum internalformat)214 bool isEtc2Format(GLenum internalformat) {
215     switch (internalformat) {
216     case GL_COMPRESSED_RGB8_ETC2:
217     case GL_COMPRESSED_SRGB8_ETC2:
218     case GL_COMPRESSED_RGBA8_ETC2_EAC:
219     case GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC:
220     case GL_COMPRESSED_R11_EAC:
221     case GL_COMPRESSED_SIGNED_R11_EAC:
222     case GL_COMPRESSED_RG11_EAC:
223     case GL_COMPRESSED_SIGNED_RG11_EAC:
224     case GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2:
225     case GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2:
226         return true;
227     }
228     return false;
229 }
230 
isBptcFormat(GLenum internalformat)231 bool isBptcFormat(GLenum internalformat) {
232     switch (internalformat) {
233     case GL_COMPRESSED_RGBA_BPTC_UNORM_EXT:
234     case GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM_EXT:
235     case GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT_EXT:
236     case GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT_EXT:
237         return true;
238     }
239     return false;
240 }
241 
isS3tcFormat(GLenum internalformat)242 bool isS3tcFormat(GLenum internalformat) {
243     switch (internalformat) {
244     case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
245     case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
246     case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
247     case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT:
248     case GL_COMPRESSED_SRGB_S3TC_DXT1_EXT:
249     case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT:
250     case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT:
251     case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT:
252         return true;
253   }
254   return false;
255 }
256 
isPaletteFormat(GLenum internalformat)257 bool isPaletteFormat(GLenum internalformat)  {
258     switch (internalformat) {
259     case GL_PALETTE4_RGB8_OES:
260     case GL_PALETTE4_RGBA8_OES:
261     case GL_PALETTE4_R5_G6_B5_OES:
262     case GL_PALETTE4_RGBA4_OES:
263     case GL_PALETTE4_RGB5_A1_OES:
264     case GL_PALETTE8_RGB8_OES:
265     case GL_PALETTE8_RGBA8_OES:
266     case GL_PALETTE8_R5_G6_B5_OES:
267     case GL_PALETTE8_RGBA4_OES:
268     case GL_PALETTE8_RGB5_A1_OES:
269         return true;
270     }
271     return false;
272 }
273 
decompressedInternalFormat(GLEScontext * ctx,GLenum compressedFormat)274 GLenum decompressedInternalFormat(GLEScontext* ctx, GLenum compressedFormat) {
275     bool needSizedInternalFormat =
276         isCoreProfile() ||
277         (ctx->getMajorVersion() >= 3);
278 
279     GLenum glrgb = needSizedInternalFormat ? GL_RGB8 : GL_RGB;
280     GLenum glrgba = needSizedInternalFormat ? GL_RGBA8 : GL_RGBA;
281 
282     switch (compressedFormat) {
283         // ETC2 formats
284         case GL_COMPRESSED_RGB8_ETC2:
285         case GL_ETC1_RGB8_OES:
286             return glrgb;
287         case GL_COMPRESSED_RGBA8_ETC2_EAC:
288         case GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2:
289             return glrgba;
290         case GL_COMPRESSED_SRGB8_ETC2:
291             return GL_SRGB8;
292         case GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC:
293             return GL_SRGB8_ALPHA8;
294         case GL_COMPRESSED_R11_EAC:
295         case GL_COMPRESSED_SIGNED_R11_EAC:
296             return GL_R32F;
297         case GL_COMPRESSED_RG11_EAC:
298         case GL_COMPRESSED_SIGNED_RG11_EAC:
299             return GL_RG32F;
300         case GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2:
301             return GL_SRGB8_ALPHA8;
302         // ASTC formats
303         case GL_COMPRESSED_RGBA_ASTC_4x4_KHR:
304         case GL_COMPRESSED_RGBA_ASTC_5x4_KHR:
305         case GL_COMPRESSED_RGBA_ASTC_5x5_KHR:
306         case GL_COMPRESSED_RGBA_ASTC_6x5_KHR:
307         case GL_COMPRESSED_RGBA_ASTC_6x6_KHR:
308         case GL_COMPRESSED_RGBA_ASTC_8x5_KHR:
309         case GL_COMPRESSED_RGBA_ASTC_8x6_KHR:
310         case GL_COMPRESSED_RGBA_ASTC_8x8_KHR:
311         case GL_COMPRESSED_RGBA_ASTC_10x5_KHR:
312         case GL_COMPRESSED_RGBA_ASTC_10x6_KHR:
313         case GL_COMPRESSED_RGBA_ASTC_10x8_KHR:
314         case GL_COMPRESSED_RGBA_ASTC_10x10_KHR:
315         case GL_COMPRESSED_RGBA_ASTC_12x10_KHR:
316         case GL_COMPRESSED_RGBA_ASTC_12x12_KHR:
317             return glrgba;
318         case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR:
319         case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR:
320         case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR:
321         case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR:
322         case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR:
323         case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR:
324         case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR:
325         case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR:
326         case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR:
327         case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR:
328         case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR:
329         case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR:
330         case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR:
331         case GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR:
332             return GL_SRGB8_ALPHA8;
333         // palette formats
334         case GL_PALETTE4_RGB8_OES:
335         case GL_PALETTE4_R5_G6_B5_OES:
336         case GL_PALETTE8_RGB8_OES:
337         case GL_PALETTE8_R5_G6_B5_OES:
338             return glrgb;
339         case GL_PALETTE4_RGBA8_OES:
340         case GL_PALETTE4_RGBA4_OES:
341         case GL_PALETTE4_RGB5_A1_OES:
342         case GL_PALETTE8_RGBA8_OES:
343         case GL_PALETTE8_RGBA4_OES:
344         case GL_PALETTE8_RGB5_A1_OES:
345             return glrgba;
346 
347         default:
348             return compressedFormat;
349     }
350 }
351 
352 class ScopedFetchUnpackData {
353     public:
ScopedFetchUnpackData(GLEScontext * ctx,GLintptr offset,GLsizei dataSize)354         ScopedFetchUnpackData(GLEScontext* ctx, GLintptr offset,
355             GLsizei dataSize) : mCtx(ctx) {
356             mData = ctx->dispatcher().glMapBufferRange(
357                     GL_PIXEL_UNPACK_BUFFER,
358                     offset, dataSize, GL_MAP_READ_BIT);
359             if (mData) {
360                 ctx->dispatcher().glGetIntegerv(GL_PIXEL_UNPACK_BUFFER_BINDING,
361                         &mUnpackBuffer);
362                 ctx->dispatcher().glBindBuffer(GL_PIXEL_UNPACK_BUFFER,
363                         0);
364             }
365         }
~ScopedFetchUnpackData()366         ~ScopedFetchUnpackData() {
367             if (mData) {
368                 mCtx->dispatcher().glBindBuffer(GL_PIXEL_UNPACK_BUFFER,
369                         mUnpackBuffer);
370                 mCtx->dispatcher().glUnmapBuffer(GL_PIXEL_UNPACK_BUFFER);
371             }
372         }
data()373         void* data() {
374             return mData;
375         }
376     private:
377         const GLEScontext* mCtx;
378         void* mData = nullptr;
379         GLint mUnpackBuffer = 0;
380 };
381 
doCompressedTexImage2D(GLEScontext * ctx,GLenum target,GLint level,GLenum internalformat,GLsizei width,GLsizei height,GLint border,GLsizei imageSize,const GLvoid * data,glTexImage2D_t glTexImage2DPtr)382 void doCompressedTexImage2D(GLEScontext* ctx, GLenum target, GLint level,
383                             GLenum internalformat, GLsizei width,
384                             GLsizei height, GLint border,
385                             GLsizei imageSize, const GLvoid* data,
386                             glTexImage2D_t glTexImage2DPtr) {
387     /* XXX: This is just a hack to fix the resolve of glTexImage2D problem
388        It will be removed when we'll no longer link against ligGL */
389     /*typedef void (GLAPIENTRY *glTexImage2DPtr_t ) (
390             GLenum target, GLint level, GLint internalformat,
391             GLsizei width, GLsizei height, GLint border,
392             GLenum format, GLenum type, const GLvoid *pixels);
393 
394     glTexImage2DPtr_t glTexImage2DPtr;
395     glTexImage2DPtr = (glTexImage2DPtr_t)funcPtr;*/
396     bool needUnpackBuffer = false;
397     if (ctx->getMajorVersion() >= 3) {
398         GLint unpackBuffer = 0;
399         ctx->dispatcher().glGetIntegerv(GL_PIXEL_UNPACK_BUFFER_BINDING,
400                 &unpackBuffer);
401         needUnpackBuffer = unpackBuffer;
402     }
403 
404     if (isEtcFormat(internalformat)) {
405         GLint format = GL_RGB;
406         GLint type = GL_UNSIGNED_BYTE;
407         GLint convertedInternalFormat = decompressedInternalFormat(ctx, internalformat);
408         ETC2ImageFormat etcFormat = EtcRGB8;
409         switch (internalformat) {
410             case GL_COMPRESSED_RGB8_ETC2:
411             case GL_ETC1_RGB8_OES:
412                 break;
413             case GL_COMPRESSED_RGBA8_ETC2_EAC:
414                 etcFormat = EtcRGBA8;
415                 format = GL_RGBA;
416                 break;
417             case GL_COMPRESSED_SRGB8_ETC2:
418                 break;
419             case GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC:
420                 etcFormat = EtcRGBA8;
421                 format = GL_RGBA;
422                 break;
423             case GL_COMPRESSED_R11_EAC:
424                 etcFormat = EtcR11;
425                 format = GL_RED;
426                 type = GL_FLOAT;
427                 break;
428             case GL_COMPRESSED_SIGNED_R11_EAC:
429                 etcFormat = EtcSignedR11;
430                 format = GL_RED;
431                 type = GL_FLOAT;
432                 break;
433             case GL_COMPRESSED_RG11_EAC:
434                 etcFormat = EtcRG11;
435                 format = GL_RG;
436                 type = GL_FLOAT;
437                 break;
438             case GL_COMPRESSED_SIGNED_RG11_EAC:
439                 etcFormat = EtcSignedRG11;
440                 format = GL_RG;
441                 type = GL_FLOAT;
442                 break;
443             case GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2:
444                 etcFormat = EtcRGB8A1;
445                 format = GL_RGBA;
446                 break;
447             case GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2:
448                 etcFormat = EtcRGB8A1;
449                 format = GL_RGBA;
450                 break;
451         }
452         int pixelSize = etc_get_decoded_pixel_size(etcFormat);
453         GLsizei compressedSize =
454             etc_get_encoded_data_size(etcFormat, width, height);
455         SET_ERROR_IF((compressedSize != imageSize), GL_INVALID_VALUE);
456         std::unique_ptr<ScopedFetchUnpackData> unpackData;
457         bool emulateCompressedData = false;
458         if (needUnpackBuffer) {
459             unpackData.reset(new ScopedFetchUnpackData(ctx,
460                     reinterpret_cast<GLintptr>(data), compressedSize));
461             data = unpackData->data();
462             SET_ERROR_IF(!data, GL_INVALID_OPERATION);
463         } else {
464             if (!data) {
465                 emulateCompressedData = true;
466                 data = new char[compressedSize];
467             }
468         }
469 
470         const int32_t align = ctx->getUnpackAlignment()-1;
471         const int32_t bpr = ((width * pixelSize) + align) & ~align;
472         const size_t size = bpr * height;
473         std::unique_ptr<etc1_byte[]> pOut(new etc1_byte[size]);
474 
475         int res =
476             etc2_decode_image(
477                     (const etc1_byte*)data, etcFormat, pOut.get(),
478                     width, height, bpr);
479         SET_ERROR_IF(res!=0, GL_INVALID_VALUE);
480 
481         glTexImage2DPtr(target, level, convertedInternalFormat,
482                         width, height, border, format, type, pOut.get());
483         if (emulateCompressedData) {
484             delete [] (char*)data;
485         }
486     } else if (isAstcFormat(internalformat)) {
487         // TODO: fix the case when GL_PIXEL_UNPACK_BUFFER is bound
488         astc_codec::FootprintType footprint;
489         bool srgb;
490         getAstcFormatInfo(internalformat, &footprint, &srgb);
491 
492         const int32_t align = ctx->getUnpackAlignment() - 1;
493         const int32_t stride = ((width * 4) + align) & ~align;
494         const size_t size = stride * height;
495 
496         AlignedBuf<uint8_t, 64> alignedUncompressedData(size);
497 
498         const bool result = astc_codec::ASTCDecompressToRGBA(
499                 reinterpret_cast<const uint8_t*>(data), imageSize, width,
500                 height, footprint, alignedUncompressedData.data(), size,
501                 stride);
502         SET_ERROR_IF(!result, GL_INVALID_VALUE);
503 
504         glTexImage2DPtr(target, level, srgb ? GL_SRGB8_ALPHA8 : GL_RGBA8, width,
505                         height, border, GL_RGBA, GL_UNSIGNED_BYTE,
506                         alignedUncompressedData.data());
507 
508     } else if (isPaletteFormat(internalformat)) {
509         // TODO: fix the case when GL_PIXEL_UNPACK_BUFFER is bound
510         SET_ERROR_IF(
511             level > log2(ctx->getMaxTexSize()) ||
512             border !=0 || level > 0 ||
513             !GLESvalidate::texImgDim(
514                 width, height, ctx->getMaxTexSize() + 2),
515             GL_INVALID_VALUE);
516         SET_ERROR_IF(!data,GL_INVALID_OPERATION);
517 
518         int nMipmaps = -level + 1;
519         GLsizei tmpWidth  = width;
520         GLsizei tmpHeight = height;
521 
522         for(int i = 0; i < nMipmaps; i++)
523         {
524             GLenum uncompressedFrmt;
525             unsigned char* uncompressed =
526                 uncompressTexture(internalformat, uncompressedFrmt,
527                                   width, height, imageSize, data, i);
528             glTexImage2DPtr(target, i, uncompressedFrmt,
529                             tmpWidth, tmpHeight, border,
530                             uncompressedFrmt, GL_UNSIGNED_BYTE, uncompressed);
531             tmpWidth /= 2;
532             tmpHeight /= 2;
533             delete [] uncompressed;
534         }
535     } else {
536         SET_ERROR_IF(1, GL_INVALID_ENUM);
537     }
538 }
539 
deleteRenderbufferGlobal(GLuint rbo)540 void deleteRenderbufferGlobal(GLuint rbo) {
541     if (rbo) {
542         GLEScontext::dispatcher().glDeleteRenderbuffers(1, &rbo);
543     }
544 }
545 
isCubeMapFaceTarget(GLenum target)546 bool isCubeMapFaceTarget(GLenum target) {
547     switch (target) {
548         case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
549         case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
550         case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
551         case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
552         case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
553         case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
554             return true;
555     }
556     return false;
557 }
558 
isCoreProfileEmulatedFormat(GLenum format)559 bool isCoreProfileEmulatedFormat(GLenum format) {
560     switch (format) {
561     case GL_ALPHA:
562     case GL_LUMINANCE:
563     case GL_LUMINANCE_ALPHA:
564         return true;
565     default:
566         return false;
567     }
568 }
569 
getCoreProfileEmulatedFormat(GLenum format)570 GLenum getCoreProfileEmulatedFormat(GLenum format) {
571     switch (format) {
572         case GL_ALPHA:
573         case GL_LUMINANCE:
574             return GL_RED;
575         case GL_LUMINANCE_ALPHA:
576             return GL_RG;
577     }
578     return format;
579 }
580 
getCoreProfileEmulatedInternalFormat(GLint internalformat,GLenum type)581 GLint getCoreProfileEmulatedInternalFormat(GLint internalformat, GLenum type) {
582     switch (internalformat) {
583         case GL_ALPHA:
584         case GL_LUMINANCE:
585             switch (type) {
586                 case GL_UNSIGNED_BYTE:
587                     return GL_R8;
588                 case GL_FLOAT:
589                     return GL_R32F;
590                 case GL_HALF_FLOAT:
591                     return GL_R16F;
592             }
593             return GL_R8;
594         case GL_LUMINANCE_ALPHA:
595             switch (type) {
596                 case GL_UNSIGNED_BYTE:
597                     return GL_RG8;
598                 case GL_FLOAT:
599                     return GL_RG32F;
600                 case GL_HALF_FLOAT:
601                     return GL_RG16F;
602             }
603             return GL_RG8;
604     }
605     fprintf(stderr,
606             "%s: warning: unsupported alpha/luminance internal format 0x%x type 0x%x\n",
607             __func__, internalformat, type);
608     return GL_R8;
609 }
610 
getSwizzleForEmulatedFormat(GLenum format)611 TextureSwizzle getSwizzleForEmulatedFormat(GLenum format) {
612     TextureSwizzle res;
613     switch (format) {
614         case GL_ALPHA:
615             res.toRed   = GL_ZERO;
616             res.toGreen = GL_ZERO;
617             res.toBlue  = GL_ZERO;
618             res.toAlpha = GL_RED;
619             break;
620         case GL_LUMINANCE:
621             res.toRed   = GL_RED;
622             res.toGreen = GL_RED;
623             res.toBlue  = GL_RED;
624             res.toAlpha = GL_ONE;
625             break;
626         case GL_LUMINANCE_ALPHA:
627             res.toRed   = GL_RED;
628             res.toGreen = GL_RED;
629             res.toBlue  = GL_RED;
630             res.toAlpha = GL_GREEN;
631             break;
632         default:
633             break;
634     }
635     return res;
636 }
637 
638 // Inverse swizzle: if we were writing fragments back to this texture,
639 // how should the components be re-arranged?
getInverseSwizzleForEmulatedFormat(GLenum format)640 TextureSwizzle getInverseSwizzleForEmulatedFormat(GLenum format) {
641     TextureSwizzle res;
642     switch (format) {
643         case GL_ALPHA:
644             res.toRed   = GL_ALPHA;
645             res.toGreen = GL_ZERO;
646             res.toBlue  = GL_ZERO;
647             res.toAlpha = GL_ZERO;
648             break;
649         case GL_LUMINANCE:
650             res.toRed   = GL_RED;
651             res.toGreen = GL_ZERO;
652             res.toBlue  = GL_ZERO;
653             res.toAlpha = GL_ZERO;
654             break;
655         case GL_LUMINANCE_ALPHA:
656             res.toRed   = GL_RED;
657             res.toGreen = GL_ALPHA;
658             res.toBlue  = GL_ZERO;
659             res.toAlpha = GL_ZERO;
660             break;
661         default:
662             break;
663     }
664     return res;
665 }
666 
swizzleComponentOf(const TextureSwizzle & s,GLenum component)667 GLenum swizzleComponentOf(const TextureSwizzle& s, GLenum component) {
668     switch (component) {
669     case GL_RED: return s.toRed;
670     case GL_GREEN: return s.toGreen;
671     case GL_BLUE: return s.toBlue;
672     case GL_ALPHA: return s.toAlpha;
673     }
674     // Identity map for GL_ZERO / GL_ONE
675     return component;
676 }
677 
concatSwizzles(const TextureSwizzle & first,const TextureSwizzle & next)678 TextureSwizzle concatSwizzles(const TextureSwizzle& first,
679                               const TextureSwizzle& next) {
680 
681     TextureSwizzle result;
682     result.toRed = swizzleComponentOf(first, next.toRed);
683     result.toGreen = swizzleComponentOf(first, next.toGreen);
684     result.toBlue = swizzleComponentOf(first, next.toBlue);
685     result.toAlpha = swizzleComponentOf(first, next.toAlpha);
686     return result;
687 }
688 
isSwizzleParam(GLenum pname)689 bool isSwizzleParam(GLenum pname) {
690     switch (pname) {
691     case GL_TEXTURE_SWIZZLE_R:
692     case GL_TEXTURE_SWIZZLE_G:
693     case GL_TEXTURE_SWIZZLE_B:
694     case GL_TEXTURE_SWIZZLE_A:
695         return true;
696     default:
697         return false;
698     }
699 }
700 
isIntegerInternalFormat(GLint internalformat)701 bool isIntegerInternalFormat(GLint internalformat) {
702     switch (internalformat) {
703         case GL_R8I:
704         case GL_R8UI:
705         case GL_R16I:
706         case GL_R16UI:
707         case GL_R32I:
708         case GL_R32UI:
709         case GL_RG8I:
710         case GL_RG8UI:
711         case GL_RG16I:
712         case GL_RG16UI:
713         case GL_RG32I:
714         case GL_RG32UI:
715         case GL_RGB8I:
716         case GL_RGB8UI:
717         case GL_RGB16I:
718         case GL_RGB16UI:
719         case GL_RGB32I:
720         case GL_RGB32UI:
721         case GL_RGBA8I:
722         case GL_RGBA8UI:
723         case GL_RGBA16I:
724         case GL_RGBA16UI:
725         case GL_RGBA32I:
726         case GL_RGBA32UI:
727             return true;
728         default:
729             return false;
730     }
731 }
732 
doCompressedTexImage2DNative(GLEScontext * ctx,GLenum target,GLint level,GLenum internalformat,GLsizei width,GLsizei height,GLint border,GLsizei imageSize,const GLvoid * data)733 void doCompressedTexImage2DNative(GLEScontext* ctx, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const GLvoid* data) {
734     // AlignedBuf<uint8_t, 64> alignedData(imageSize);
735     // memcpy(alignedData.data(), data, imageSize);
736     // GLint err = ctx->dispatcher().glGetError();
737     ctx->dispatcher().glCompressedTexImage2D(target, level, internalformat, width, height, border, imageSize, data);
738     //     fprintf(stderr, "%s: tex %u target 0x%x level 0x%x iformat 0x%x w h b %d %d %d imgSize %d\n", __func__, ctx->getBindedTexture(target), target, level, internalformat, width, height, border, imageSize);
739     // err = ctx->dispatcher().glGetError(); if (err) {
740     //     fprintf(stderr, "%s:%d err 0x%x\n", __func__, __LINE__, err);
741     // }
742 }
743 
doCompressedTexSubImage2DNative(GLEScontext * ctx,GLenum target,GLint level,GLint xoffset,GLint yoffset,GLsizei width,GLsizei height,GLenum format,GLsizei imageSize,const GLvoid * data)744 void doCompressedTexSubImage2DNative(GLEScontext* ctx, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const GLvoid* data) {
745     // AlignedBuf<uint8_t, 64> alignedData(imageSize);
746     // memcpy(alignedData.data(), data, imageSize);
747     // GLint err = ctx->dispatcher().glGetError();
748     ctx->dispatcher().glCompressedTexSubImage2D(target, level, xoffset, yoffset, width, height, format, imageSize, data);
749     //     fprintf(stderr, "%s: tex %u target 0x%x level 0x%x format 0x%x x y w h %d %d %d %d imgSize %d\n", __func__, ctx->getBindedTexture(target), target, level, format, xoffset, yoffset, width, height, imageSize);
750     // err = ctx->dispatcher().glGetError(); if (err) {
751     //     fprintf(stderr, "%s:%d err 0x%x\n", __func__, __LINE__, err);
752     // }
753 }
754 
forEachEtc2Format(std::function<void (GLint format)> f)755 void forEachEtc2Format(std::function<void(GLint format)> f) {
756     f(GL_COMPRESSED_RGB8_ETC2);
757     f(GL_COMPRESSED_SRGB8_ETC2);
758     f(GL_COMPRESSED_RGBA8_ETC2_EAC);
759     f(GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC);
760     f(GL_COMPRESSED_R11_EAC);
761     f(GL_COMPRESSED_SIGNED_R11_EAC);
762     f(GL_COMPRESSED_RG11_EAC);
763     f(GL_COMPRESSED_SIGNED_RG11_EAC);
764     f(GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2);
765     f(GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2);
766 }
767 
forEachAstcFormat(std::function<void (GLint format)> f)768 void forEachAstcFormat(std::function<void(GLint format)> f) {
769 
770 #define CALL_ON_ASTC_FORMAT(typeName, footprintType, srgbValue) \
771     f(typeName);
772 
773     ASTC_FORMATS_LIST(CALL_ON_ASTC_FORMAT)
774 }
775 
forEachBptcFormat(std::function<void (GLint format)> f)776 void forEachBptcFormat(std::function<void(GLint format)> f) {
777     f(GL_COMPRESSED_RGBA_BPTC_UNORM_EXT);
778     f(GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM_EXT);
779     f(GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT_EXT);
780     f(GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT_EXT);
781 }
782 
forEachS3tcFormat(std::function<void (GLint format)> f)783 void forEachS3tcFormat(std::function<void(GLint format)> f) {
784     f(GL_COMPRESSED_RGB_S3TC_DXT1_EXT);
785     f(GL_COMPRESSED_RGBA_S3TC_DXT1_EXT);
786     f(GL_COMPRESSED_RGBA_S3TC_DXT3_EXT);
787     f(GL_COMPRESSED_RGBA_S3TC_DXT5_EXT);
788     f(GL_COMPRESSED_SRGB_S3TC_DXT1_EXT);
789     f(GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT);
790     f(GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT);
791     f(GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT);
792 }
793 
isEtc2OrAstcFormat(GLenum format)794 bool isEtc2OrAstcFormat(GLenum format) {
795     switch (format) {
796     case GL_COMPRESSED_RGB8_ETC2:
797     case GL_COMPRESSED_SRGB8_ETC2:
798     case GL_COMPRESSED_RGBA8_ETC2_EAC:
799     case GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC:
800     case GL_COMPRESSED_R11_EAC:
801     case GL_COMPRESSED_SIGNED_R11_EAC:
802     case GL_COMPRESSED_RG11_EAC:
803     case GL_COMPRESSED_SIGNED_RG11_EAC:
804     case GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2:
805     case GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2:
806         return true;
807     default:
808         break;
809     }
810     return isAstcFormat(format);
811 }
812 
shouldPassthroughCompressedFormat(GLEScontext * ctx,GLenum internalformat)813 bool shouldPassthroughCompressedFormat(GLEScontext* ctx, GLenum internalformat) {
814     if (isEtc2Format(internalformat)) {
815         return ctx->getCaps()->hasEtc2Support;
816     } else if (isAstcFormat(internalformat)) {
817         return ctx->getCaps()->hasAstcSupport;
818     } else if (isBptcFormat(internalformat)) {
819         return ctx->getCaps()->hasBptcSupport;
820     } else if (isS3tcFormat(internalformat)) {
821         return ctx->getCaps()->hasS3tcSupport;
822     }
823     return false;
824 }
825 
s_texAlign(uint32_t v,uint32_t align)826 static uint32_t s_texAlign(uint32_t v, uint32_t align) {
827     uint32_t rem = v % align;
828     return rem ? (v + (align - rem)) : v;
829 }
830 
831 // s_computePixelSize is both in the host and the guest. Consider moving it to
832 // android-emugl/shared
833 
s_computePixelSize(GLenum format,GLenum type)834 static int s_computePixelSize(GLenum format, GLenum type) {
835 #define FORMAT_ERROR(format, type)                                         \
836     fprintf(stderr, "%s:%d unknown format/type 0x%x 0x%x\n", __FUNCTION__, \
837             __LINE__, format, type);
838 
839     switch (type) {
840         case GL_BYTE:
841             switch (format) {
842                 case GL_R8:
843                 case GL_R8I:
844                 case GL_R8_SNORM:
845                 case GL_RED:
846                     return 1;
847                 case GL_RED_INTEGER:
848                     return 1;
849                 case GL_RG8:
850                 case GL_RG8I:
851                 case GL_RG8_SNORM:
852                 case GL_RG:
853                     return 1 * 2;
854                 case GL_RG_INTEGER:
855                     return 1 * 2;
856                 case GL_RGB8:
857                 case GL_RGB8I:
858                 case GL_RGB8_SNORM:
859                 case GL_RGB:
860                     return 1 * 3;
861                 case GL_RGB_INTEGER:
862                     return 1 * 3;
863                 case GL_RGBA8:
864                 case GL_RGBA8I:
865                 case GL_RGBA8_SNORM:
866                 case GL_RGBA:
867                     return 1 * 4;
868                 case GL_RGBA_INTEGER:
869                     return 1 * 4;
870                 default:
871                     FORMAT_ERROR(format, type);
872             }
873             break;
874         case GL_UNSIGNED_BYTE:
875             switch (format) {
876                 case GL_R8:
877                 case GL_R8UI:
878                 case GL_RED:
879                     return 1;
880                 case GL_RED_INTEGER:
881                     return 1;
882                 case GL_ALPHA8_EXT:
883                 case GL_ALPHA:
884                     return 1;
885                 case GL_LUMINANCE8_EXT:
886                 case GL_LUMINANCE:
887                     return 1;
888                 case GL_LUMINANCE8_ALPHA8_EXT:
889                 case GL_LUMINANCE_ALPHA:
890                     return 1 * 2;
891                 case GL_RG8:
892                 case GL_RG8UI:
893                 case GL_RG:
894                     return 1 * 2;
895                 case GL_RG_INTEGER:
896                     return 1 * 2;
897                 case GL_RGB8:
898                 case GL_RGB8UI:
899                 case GL_SRGB8:
900                 case GL_RGB:
901                     return 1 * 3;
902                 case GL_RGB_INTEGER:
903                     return 1 * 3;
904                 case GL_RGBA8:
905                 case GL_RGBA8UI:
906                 case GL_SRGB8_ALPHA8:
907                 case GL_RGBA:
908                     return 1 * 4;
909                 case GL_RGBA_INTEGER:
910                     return 1 * 4;
911                 case GL_BGRA_EXT:
912                 case GL_BGRA8_EXT:
913                     return 1 * 4;
914                 default:
915                     FORMAT_ERROR(format, type);
916             }
917             break;
918         case GL_SHORT:
919             switch (format) {
920                 case GL_R16I:
921                 case GL_RED_INTEGER:
922                     return 2;
923                 case GL_RG16I:
924                 case GL_RG_INTEGER:
925                     return 2 * 2;
926                 case GL_RGB16I:
927                 case GL_RGB_INTEGER:
928                     return 2 * 3;
929                 case GL_RGBA16I:
930                 case GL_RGBA_INTEGER:
931                     return 2 * 4;
932                 default:
933                     FORMAT_ERROR(format, type);
934             }
935             break;
936         case GL_UNSIGNED_SHORT:
937             switch (format) {
938                 case GL_DEPTH_COMPONENT16:
939                 case GL_DEPTH_COMPONENT:
940                     return 2;
941                 case GL_R16UI:
942                 case GL_RED_INTEGER:
943                     return 2;
944                 case GL_RG16UI:
945                 case GL_RG_INTEGER:
946                     return 2 * 2;
947                 case GL_RGB16UI:
948                 case GL_RGB_INTEGER:
949                     return 2 * 3;
950                 case GL_RGBA16UI:
951                 case GL_RGBA_INTEGER:
952                     return 2 * 4;
953                 default:
954                     FORMAT_ERROR(format, type);
955             }
956             break;
957         case GL_INT:
958             switch (format) {
959                 case GL_R32I:
960                 case GL_RED_INTEGER:
961                     return 4;
962                 case GL_RG32I:
963                 case GL_RG_INTEGER:
964                     return 4 * 2;
965                 case GL_RGB32I:
966                 case GL_RGB_INTEGER:
967                     return 4 * 3;
968                 case GL_RGBA32I:
969                 case GL_RGBA_INTEGER:
970                     return 4 * 4;
971                 default:
972                     FORMAT_ERROR(format, type);
973             }
974             break;
975         case GL_UNSIGNED_INT:
976             switch (format) {
977                 case GL_DEPTH_COMPONENT16:
978                 case GL_DEPTH_COMPONENT24:
979                 case GL_DEPTH_COMPONENT32_OES:
980                 case GL_DEPTH_COMPONENT:
981                     return 4;
982                 case GL_R32UI:
983                 case GL_RED_INTEGER:
984                     return 4;
985                 case GL_RG32UI:
986                 case GL_RG_INTEGER:
987                     return 4 * 2;
988                 case GL_RGB32UI:
989                 case GL_RGB_INTEGER:
990                     return 4 * 3;
991                 case GL_RGBA32UI:
992                 case GL_RGBA_INTEGER:
993                     return 4 * 4;
994                 default:
995                     FORMAT_ERROR(format, type);
996             }
997             break;
998         case GL_UNSIGNED_SHORT_4_4_4_4:
999         case GL_UNSIGNED_SHORT_5_5_5_1:
1000         case GL_UNSIGNED_SHORT_5_6_5:
1001         case GL_UNSIGNED_SHORT_4_4_4_4_REV_EXT:
1002         case GL_UNSIGNED_SHORT_1_5_5_5_REV_EXT:
1003             return 2;
1004         case GL_UNSIGNED_INT_10F_11F_11F_REV:
1005         case GL_UNSIGNED_INT_5_9_9_9_REV:
1006         case GL_UNSIGNED_INT_2_10_10_10_REV:
1007         case GL_UNSIGNED_INT_24_8_OES:
1008             return 4;
1009         case GL_FLOAT_32_UNSIGNED_INT_24_8_REV:
1010             return 4 + 4;
1011         case GL_FLOAT:
1012             switch (format) {
1013                 case GL_DEPTH_COMPONENT32F:
1014                 case GL_DEPTH_COMPONENT:
1015                     return 4;
1016                 case GL_ALPHA32F_EXT:
1017                 case GL_ALPHA:
1018                     return 4;
1019                 case GL_LUMINANCE32F_EXT:
1020                 case GL_LUMINANCE:
1021                     return 4;
1022                 case GL_LUMINANCE_ALPHA32F_EXT:
1023                 case GL_LUMINANCE_ALPHA:
1024                     return 4 * 2;
1025                 case GL_RED:
1026                     return 4;
1027                 case GL_R32F:
1028                     return 4;
1029                 case GL_RG:
1030                     return 4 * 2;
1031                 case GL_RG32F:
1032                     return 4 * 2;
1033                 case GL_RGB:
1034                     return 4 * 3;
1035                 case GL_RGB32F:
1036                     return 4 * 3;
1037                 case GL_RGBA:
1038                     return 4 * 4;
1039                 case GL_RGBA32F:
1040                     return 4 * 4;
1041                 default:
1042                     FORMAT_ERROR(format, type);
1043             }
1044             break;
1045         case GL_HALF_FLOAT:
1046         case GL_HALF_FLOAT_OES:
1047             switch (format) {
1048                 case GL_ALPHA16F_EXT:
1049                 case GL_ALPHA:
1050                     return 2;
1051                 case GL_LUMINANCE16F_EXT:
1052                 case GL_LUMINANCE:
1053                     return 2;
1054                 case GL_LUMINANCE_ALPHA16F_EXT:
1055                 case GL_LUMINANCE_ALPHA:
1056                     return 2 * 2;
1057                 case GL_RED:
1058                     return 2;
1059                 case GL_R16F:
1060                     return 2;
1061                 case GL_RG:
1062                     return 2 * 2;
1063                 case GL_RG16F:
1064                     return 2 * 2;
1065                 case GL_RGB:
1066                     return 2 * 3;
1067                 case GL_RGB16F:
1068                     return 2 * 3;
1069                 case GL_RGBA:
1070                     return 2 * 4;
1071                 case GL_RGBA16F:
1072                     return 2 * 4;
1073                 default:
1074                     FORMAT_ERROR(format, type);
1075             }
1076             break;
1077         default:
1078             FORMAT_ERROR(format, type);
1079     }
1080 
1081     return 0;
1082 }
1083 
texImageSize(GLenum internalformat,GLenum type,int unpackAlignment,GLsizei width,GLsizei height)1084 uint32_t texImageSize(GLenum internalformat,
1085                       GLenum type,
1086                       int unpackAlignment,
1087                       GLsizei width,
1088                       GLsizei height) {
1089 
1090     uint32_t alignedWidth = s_texAlign(width, unpackAlignment);
1091     uint32_t pixelSize = s_computePixelSize(internalformat, type);
1092     uint32_t totalSize = pixelSize * alignedWidth * height;
1093 
1094     return totalSize;
1095 }
1096