• 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         case GL_COMPRESSED_RED_RGTC1_EXT:               // BC4U
347             return GL_R8;
348         case GL_COMPRESSED_SIGNED_RED_RGTC1_EXT:        // BC4S
349             return GL_R8_SNORM;
350         case GL_COMPRESSED_RED_GREEN_RGTC2_EXT:         // BC5U
351             return GL_RG8;
352         case GL_COMPRESSED_SIGNED_RED_GREEN_RGTC2_EXT:  // BC5S
353             return GL_RG8_SNORM;
354         default:
355             return compressedFormat;
356     }
357 }
358 
359 class ScopedFetchUnpackData {
360     public:
ScopedFetchUnpackData(GLEScontext * ctx,GLintptr offset,GLsizei dataSize)361         ScopedFetchUnpackData(GLEScontext* ctx, GLintptr offset,
362             GLsizei dataSize) : mCtx(ctx) {
363             mData = ctx->dispatcher().glMapBufferRange(
364                     GL_PIXEL_UNPACK_BUFFER,
365                     offset, dataSize, GL_MAP_READ_BIT);
366             if (mData) {
367                 ctx->dispatcher().glGetIntegerv(GL_PIXEL_UNPACK_BUFFER_BINDING,
368                         &mUnpackBuffer);
369                 ctx->dispatcher().glBindBuffer(GL_PIXEL_UNPACK_BUFFER,
370                         0);
371             }
372         }
~ScopedFetchUnpackData()373         ~ScopedFetchUnpackData() {
374             if (mData) {
375                 mCtx->dispatcher().glBindBuffer(GL_PIXEL_UNPACK_BUFFER,
376                         mUnpackBuffer);
377                 mCtx->dispatcher().glUnmapBuffer(GL_PIXEL_UNPACK_BUFFER);
378             }
379         }
data()380         void* data() {
381             return mData;
382         }
383     private:
384         const GLEScontext* mCtx;
385         void* mData = nullptr;
386         GLint mUnpackBuffer = 0;
387 };
388 
doCompressedTexImage2D(GLEScontext * ctx,GLenum target,GLint level,GLenum internalformat,GLsizei width,GLsizei height,GLint border,GLsizei imageSize,const GLvoid * data,glTexImage2D_t glTexImage2DPtr)389 void doCompressedTexImage2D(GLEScontext* ctx, GLenum target, GLint level,
390                             GLenum internalformat, GLsizei width,
391                             GLsizei height, GLint border,
392                             GLsizei imageSize, const GLvoid* data,
393                             glTexImage2D_t glTexImage2DPtr) {
394     /* XXX: This is just a hack to fix the resolve of glTexImage2D problem
395        It will be removed when we'll no longer link against ligGL */
396     /*typedef void (GLAPIENTRY *glTexImage2DPtr_t ) (
397             GLenum target, GLint level, GLint internalformat,
398             GLsizei width, GLsizei height, GLint border,
399             GLenum format, GLenum type, const GLvoid *pixels);
400 
401     glTexImage2DPtr_t glTexImage2DPtr;
402     glTexImage2DPtr = (glTexImage2DPtr_t)funcPtr;*/
403     bool needUnpackBuffer = false;
404     if (ctx->getMajorVersion() >= 3) {
405         GLint unpackBuffer = 0;
406         ctx->dispatcher().glGetIntegerv(GL_PIXEL_UNPACK_BUFFER_BINDING,
407                 &unpackBuffer);
408         needUnpackBuffer = unpackBuffer;
409     }
410     TextureUnpackReset unpack(ctx);
411     const int32_t unpackAlignment = TextureUnpackReset::kUnpackAlignment;
412     if (isEtcFormat(internalformat)) {
413         GLint format = GL_RGB;
414         GLint type = GL_UNSIGNED_BYTE;
415         GLint convertedInternalFormat = decompressedInternalFormat(ctx, internalformat);
416         ETC2ImageFormat etcFormat = EtcRGB8;
417         switch (internalformat) {
418             case GL_COMPRESSED_RGB8_ETC2:
419             case GL_ETC1_RGB8_OES:
420                 break;
421             case GL_COMPRESSED_RGBA8_ETC2_EAC:
422                 etcFormat = EtcRGBA8;
423                 format = GL_RGBA;
424                 break;
425             case GL_COMPRESSED_SRGB8_ETC2:
426                 break;
427             case GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC:
428                 etcFormat = EtcRGBA8;
429                 format = GL_RGBA;
430                 break;
431             case GL_COMPRESSED_R11_EAC:
432                 etcFormat = EtcR11;
433                 format = GL_RED;
434                 type = GL_FLOAT;
435                 break;
436             case GL_COMPRESSED_SIGNED_R11_EAC:
437                 etcFormat = EtcSignedR11;
438                 format = GL_RED;
439                 type = GL_FLOAT;
440                 break;
441             case GL_COMPRESSED_RG11_EAC:
442                 etcFormat = EtcRG11;
443                 format = GL_RG;
444                 type = GL_FLOAT;
445                 break;
446             case GL_COMPRESSED_SIGNED_RG11_EAC:
447                 etcFormat = EtcSignedRG11;
448                 format = GL_RG;
449                 type = GL_FLOAT;
450                 break;
451             case GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2:
452                 etcFormat = EtcRGB8A1;
453                 format = GL_RGBA;
454                 break;
455             case GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2:
456                 etcFormat = EtcRGB8A1;
457                 format = GL_RGBA;
458                 break;
459         }
460         int pixelSize = etc_get_decoded_pixel_size(etcFormat);
461         GLsizei compressedSize =
462             etc_get_encoded_data_size(etcFormat, width, height);
463         SET_ERROR_IF((compressedSize != imageSize), GL_INVALID_VALUE);
464         std::unique_ptr<ScopedFetchUnpackData> unpackData;
465         bool emulateCompressedData = false;
466         if (needUnpackBuffer) {
467             unpackData.reset(new ScopedFetchUnpackData(ctx,
468                     reinterpret_cast<GLintptr>(data), compressedSize));
469             data = unpackData->data();
470             SET_ERROR_IF(!data, GL_INVALID_OPERATION);
471         } else {
472             if (!data) {
473                 emulateCompressedData = true;
474                 data = new char[compressedSize];
475             }
476         }
477 
478         const int32_t align = unpackAlignment - 1;
479         const int32_t bpr = ((width * pixelSize) + align) & ~align;
480         const size_t size = bpr * height;
481         std::unique_ptr<etc1_byte[]> pOut(new etc1_byte[size]);
482 
483         int res =
484             etc2_decode_image(
485                     (const etc1_byte*)data, etcFormat, pOut.get(),
486                     width, height, bpr);
487         SET_ERROR_IF(res!=0, GL_INVALID_VALUE);
488 
489         glTexImage2DPtr(target, level, convertedInternalFormat,
490                         width, height, border, format, type, pOut.get());
491         if (emulateCompressedData) {
492             delete [] (char*)data;
493         }
494     } else if (isAstcFormat(internalformat)) {
495         // TODO: fix the case when GL_PIXEL_UNPACK_BUFFER is bound
496         astc_codec::FootprintType footprint;
497         bool srgb;
498         getAstcFormatInfo(internalformat, &footprint, &srgb);
499 
500         const int32_t align = unpackAlignment - 1;
501         const int32_t stride = ((width * 4) + align) & ~align;
502         const size_t size = stride * height;
503 
504         AlignedBuf<uint8_t, 64> alignedUncompressedData(size);
505 
506         const bool result = astc_codec::ASTCDecompressToRGBA(
507                 reinterpret_cast<const uint8_t*>(data), imageSize, width,
508                 height, footprint, alignedUncompressedData.data(), size,
509                 stride);
510         SET_ERROR_IF(!result, GL_INVALID_VALUE);
511 
512         glTexImage2DPtr(target, level, srgb ? GL_SRGB8_ALPHA8 : GL_RGBA8, width,
513                         height, border, GL_RGBA, GL_UNSIGNED_BYTE,
514                         alignedUncompressedData.data());
515 
516     } else if (isPaletteFormat(internalformat)) {
517         // TODO: fix the case when GL_PIXEL_UNPACK_BUFFER is bound
518         SET_ERROR_IF(
519             level > log2(ctx->getMaxTexSize()) ||
520             border !=0 || level > 0 ||
521             !GLESvalidate::texImgDim(
522                 width, height, ctx->getMaxTexSize() + 2),
523             GL_INVALID_VALUE);
524         SET_ERROR_IF(!data,GL_INVALID_OPERATION);
525         //the decoder fully packed the pixels.
526         ctx->dispatcher().glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
527         int nMipmaps = -level + 1;
528         GLsizei tmpWidth  = width;
529         GLsizei tmpHeight = height;
530 
531         for(int i = 0; i < nMipmaps; i++)
532         {
533             GLenum uncompressedFrmt;
534             unsigned char* uncompressed =
535                 uncompressTexture(internalformat, uncompressedFrmt,
536                                   width, height, imageSize, data, i);
537             glTexImage2DPtr(target, i, uncompressedFrmt,
538                             tmpWidth, tmpHeight, border,
539                             uncompressedFrmt, GL_UNSIGNED_BYTE, uncompressed);
540             tmpWidth /= 2;
541             tmpHeight /= 2;
542             delete [] uncompressed;
543         }
544     } else if (isRgtcFormat(internalformat)) {
545         GLint format, type;
546         GLint convertedInternalFormat = decompressedInternalFormat(ctx, internalformat);
547         RGTCImageFormat rgtcFormat;
548         switch (internalformat) {
549             case GL_COMPRESSED_RED_RGTC1_EXT:               // BC4U
550                 format = GL_RED;
551                 type = GL_UNSIGNED_BYTE;
552                 rgtcFormat = BC4_UNORM;
553                 break;
554             case GL_COMPRESSED_SIGNED_RED_RGTC1_EXT:        // BC4S
555                 format = GL_RED;
556                 type = GL_BYTE;
557                 rgtcFormat = BC4_SNORM;
558                 break;
559             case GL_COMPRESSED_RED_GREEN_RGTC2_EXT:         // BC5U
560                 format = GL_RG;
561                 type = GL_UNSIGNED_BYTE;
562                 rgtcFormat = BC5_UNORM;
563                 break;
564             case GL_COMPRESSED_SIGNED_RED_GREEN_RGTC2_EXT:  // BC5S
565                 format = GL_RG;
566                 type = GL_BYTE;
567                 rgtcFormat = BC5_SNORM;
568                 break;
569         }
570         size_t pixelSize = rgtc_get_decoded_pixel_size(rgtcFormat);
571         GLsizei compressedSize = rgtc_get_encoded_image_size(rgtcFormat, width, height);
572         SET_ERROR_IF((compressedSize != imageSize), GL_INVALID_VALUE);
573         std::unique_ptr<ScopedFetchUnpackData> unpackData;
574         bool emulateCompressedData = false;
575         if (needUnpackBuffer) {
576             unpackData.reset(
577                 new ScopedFetchUnpackData(ctx, reinterpret_cast<GLintptr>(data), compressedSize));
578             data = unpackData->data();
579             SET_ERROR_IF(!data, GL_INVALID_OPERATION);
580         } else {
581             if (!data) {
582                 emulateCompressedData = true;
583                 data = new char[compressedSize];
584             }
585         }
586         const int32_t align = unpackAlignment - 1;
587         const int32_t bpr = ((width * pixelSize) + align) & ~align;
588         const size_t size = bpr * height;
589         std::unique_ptr<uint8_t[]> pOut(new uint8_t[size]);
590 
591         int res =
592             rgtc_decode_image((const uint8_t*)data, rgtcFormat, pOut.get(), width, height, bpr);
593         SET_ERROR_IF(res != 0, GL_INVALID_VALUE);
594         glTexImage2DPtr(target, level, convertedInternalFormat, width, height, border, format, type,
595                         pOut.get());
596         if (emulateCompressedData) {
597             delete[](char*) data;
598         }
599     } else {
600         SET_ERROR_IF(1, GL_INVALID_ENUM);
601     }
602 }
603 
deleteRenderbufferGlobal(GLuint rbo)604 void deleteRenderbufferGlobal(GLuint rbo) {
605     if (rbo) {
606         GLEScontext::dispatcher().glDeleteRenderbuffers(1, &rbo);
607     }
608 }
609 
isCubeMapFaceTarget(GLenum target)610 bool isCubeMapFaceTarget(GLenum target) {
611     switch (target) {
612         case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
613         case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
614         case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
615         case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
616         case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
617         case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
618             return true;
619     }
620     return false;
621 }
622 
isCoreProfileEmulatedFormat(GLenum format)623 bool isCoreProfileEmulatedFormat(GLenum format) {
624     switch (format) {
625     case GL_ALPHA:
626     case GL_LUMINANCE:
627     case GL_LUMINANCE_ALPHA:
628         return true;
629     default:
630         return false;
631     }
632 }
633 
getCoreProfileEmulatedFormat(GLenum format)634 GLenum getCoreProfileEmulatedFormat(GLenum format) {
635     switch (format) {
636         case GL_ALPHA:
637         case GL_LUMINANCE:
638             return GL_RED;
639         case GL_LUMINANCE_ALPHA:
640             return GL_RG;
641     }
642     return format;
643 }
644 
getCoreProfileEmulatedInternalFormat(GLint internalformat,GLenum type)645 GLint getCoreProfileEmulatedInternalFormat(GLint internalformat, GLenum type) {
646     switch (internalformat) {
647         case GL_ALPHA:
648         case GL_LUMINANCE:
649             switch (type) {
650                 case GL_UNSIGNED_BYTE:
651                     return GL_R8;
652                 case GL_FLOAT:
653                     return GL_R32F;
654                 case GL_HALF_FLOAT:
655                     return GL_R16F;
656             }
657             return GL_R8;
658         case GL_LUMINANCE_ALPHA:
659             switch (type) {
660                 case GL_UNSIGNED_BYTE:
661                     return GL_RG8;
662                 case GL_FLOAT:
663                     return GL_RG32F;
664                 case GL_HALF_FLOAT:
665                     return GL_RG16F;
666             }
667             return GL_RG8;
668     }
669     fprintf(stderr,
670             "%s: warning: unsupported alpha/luminance internal format 0x%x type 0x%x\n",
671             __func__, internalformat, type);
672     return GL_R8;
673 }
674 
getSwizzleForEmulatedFormat(GLenum format)675 TextureSwizzle getSwizzleForEmulatedFormat(GLenum format) {
676     TextureSwizzle res;
677     switch (format) {
678         case GL_ALPHA:
679             res.toRed   = GL_ZERO;
680             res.toGreen = GL_ZERO;
681             res.toBlue  = GL_ZERO;
682             res.toAlpha = GL_RED;
683             break;
684         case GL_LUMINANCE:
685             res.toRed   = GL_RED;
686             res.toGreen = GL_RED;
687             res.toBlue  = GL_RED;
688             res.toAlpha = GL_ONE;
689             break;
690         case GL_LUMINANCE_ALPHA:
691             res.toRed   = GL_RED;
692             res.toGreen = GL_RED;
693             res.toBlue  = GL_RED;
694             res.toAlpha = GL_GREEN;
695             break;
696         default:
697             break;
698     }
699     return res;
700 }
701 
702 // Inverse swizzle: if we were writing fragments back to this texture,
703 // how should the components be re-arranged?
getInverseSwizzleForEmulatedFormat(GLenum format)704 TextureSwizzle getInverseSwizzleForEmulatedFormat(GLenum format) {
705     TextureSwizzle res;
706     switch (format) {
707         case GL_ALPHA:
708             res.toRed   = GL_ALPHA;
709             res.toGreen = GL_ZERO;
710             res.toBlue  = GL_ZERO;
711             res.toAlpha = GL_ZERO;
712             break;
713         case GL_LUMINANCE:
714             res.toRed   = GL_RED;
715             res.toGreen = GL_ZERO;
716             res.toBlue  = GL_ZERO;
717             res.toAlpha = GL_ZERO;
718             break;
719         case GL_LUMINANCE_ALPHA:
720             res.toRed   = GL_RED;
721             res.toGreen = GL_ALPHA;
722             res.toBlue  = GL_ZERO;
723             res.toAlpha = GL_ZERO;
724             break;
725         default:
726             break;
727     }
728     return res;
729 }
730 
swizzleComponentOf(const TextureSwizzle & s,GLenum component)731 GLenum swizzleComponentOf(const TextureSwizzle& s, GLenum component) {
732     switch (component) {
733     case GL_RED: return s.toRed;
734     case GL_GREEN: return s.toGreen;
735     case GL_BLUE: return s.toBlue;
736     case GL_ALPHA: return s.toAlpha;
737     }
738     // Identity map for GL_ZERO / GL_ONE
739     return component;
740 }
741 
concatSwizzles(const TextureSwizzle & first,const TextureSwizzle & next)742 TextureSwizzle concatSwizzles(const TextureSwizzle& first,
743                               const TextureSwizzle& next) {
744 
745     TextureSwizzle result;
746     result.toRed = swizzleComponentOf(first, next.toRed);
747     result.toGreen = swizzleComponentOf(first, next.toGreen);
748     result.toBlue = swizzleComponentOf(first, next.toBlue);
749     result.toAlpha = swizzleComponentOf(first, next.toAlpha);
750     return result;
751 }
752 
isSwizzleParam(GLenum pname)753 bool isSwizzleParam(GLenum pname) {
754     switch (pname) {
755     case GL_TEXTURE_SWIZZLE_R:
756     case GL_TEXTURE_SWIZZLE_G:
757     case GL_TEXTURE_SWIZZLE_B:
758     case GL_TEXTURE_SWIZZLE_A:
759         return true;
760     default:
761         return false;
762     }
763 }
764 
isIntegerInternalFormat(GLint internalformat)765 bool isIntegerInternalFormat(GLint internalformat) {
766     switch (internalformat) {
767         case GL_R8I:
768         case GL_R8UI:
769         case GL_R16I:
770         case GL_R16UI:
771         case GL_R32I:
772         case GL_R32UI:
773         case GL_RG8I:
774         case GL_RG8UI:
775         case GL_RG16I:
776         case GL_RG16UI:
777         case GL_RG32I:
778         case GL_RG32UI:
779         case GL_RGB8I:
780         case GL_RGB8UI:
781         case GL_RGB16I:
782         case GL_RGB16UI:
783         case GL_RGB32I:
784         case GL_RGB32UI:
785         case GL_RGBA8I:
786         case GL_RGBA8UI:
787         case GL_RGBA16I:
788         case GL_RGBA16UI:
789         case GL_RGBA32I:
790         case GL_RGBA32UI:
791             return true;
792         default:
793             return false;
794     }
795 }
796 
doCompressedTexImage2DNative(GLEScontext * ctx,GLenum target,GLint level,GLenum internalformat,GLsizei width,GLsizei height,GLint border,GLsizei imageSize,const GLvoid * data)797 void doCompressedTexImage2DNative(GLEScontext* ctx, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const GLvoid* data) {
798     // AlignedBuf<uint8_t, 64> alignedData(imageSize);
799     // memcpy(alignedData.data(), data, imageSize);
800     // GLint err = ctx->dispatcher().glGetError();
801     ctx->dispatcher().glCompressedTexImage2D(target, level, internalformat, width, height, border, imageSize, data);
802     //     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);
803     // err = ctx->dispatcher().glGetError(); if (err) {
804     //     fprintf(stderr, "%s:%d err 0x%x\n", __func__, __LINE__, err);
805     // }
806 }
807 
doCompressedTexSubImage2DNative(GLEScontext * ctx,GLenum target,GLint level,GLint xoffset,GLint yoffset,GLsizei width,GLsizei height,GLenum format,GLsizei imageSize,const GLvoid * data)808 void doCompressedTexSubImage2DNative(GLEScontext* ctx, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const GLvoid* data) {
809     // AlignedBuf<uint8_t, 64> alignedData(imageSize);
810     // memcpy(alignedData.data(), data, imageSize);
811     // GLint err = ctx->dispatcher().glGetError();
812     ctx->dispatcher().glCompressedTexSubImage2D(target, level, xoffset, yoffset, width, height, format, imageSize, data);
813     //     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);
814     // err = ctx->dispatcher().glGetError(); if (err) {
815     //     fprintf(stderr, "%s:%d err 0x%x\n", __func__, __LINE__, err);
816     // }
817 }
818 
forEachEtc2Format(std::function<void (GLint format)> f)819 void forEachEtc2Format(std::function<void(GLint format)> f) {
820     f(GL_COMPRESSED_RGB8_ETC2);
821     f(GL_COMPRESSED_SRGB8_ETC2);
822     f(GL_COMPRESSED_RGBA8_ETC2_EAC);
823     f(GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC);
824     f(GL_COMPRESSED_R11_EAC);
825     f(GL_COMPRESSED_SIGNED_R11_EAC);
826     f(GL_COMPRESSED_RG11_EAC);
827     f(GL_COMPRESSED_SIGNED_RG11_EAC);
828     f(GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2);
829     f(GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2);
830 }
831 
forEachAstcFormat(std::function<void (GLint format)> f)832 void forEachAstcFormat(std::function<void(GLint format)> f) {
833 
834 #define CALL_ON_ASTC_FORMAT(typeName, footprintType, srgbValue) \
835     f(typeName);
836 
837     ASTC_FORMATS_LIST(CALL_ON_ASTC_FORMAT)
838 }
839 
forEachBptcFormat(std::function<void (GLint format)> f)840 void forEachBptcFormat(std::function<void(GLint format)> f) {
841     f(GL_COMPRESSED_RGBA_BPTC_UNORM_EXT);
842     f(GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM_EXT);
843     f(GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT_EXT);
844     f(GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT_EXT);
845 }
846 
forEachS3tcFormat(std::function<void (GLint format)> f)847 void forEachS3tcFormat(std::function<void(GLint format)> f) {
848     f(GL_COMPRESSED_RGB_S3TC_DXT1_EXT);
849     f(GL_COMPRESSED_RGBA_S3TC_DXT1_EXT);
850     f(GL_COMPRESSED_RGBA_S3TC_DXT3_EXT);
851     f(GL_COMPRESSED_RGBA_S3TC_DXT5_EXT);
852     f(GL_COMPRESSED_SRGB_S3TC_DXT1_EXT);
853     f(GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT);
854     f(GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT);
855     f(GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT);
856 }
857 
isRgtcFormat(GLenum format)858 bool isRgtcFormat(GLenum format) {
859     switch (format) {
860         case GL_COMPRESSED_RED_RGTC1_EXT: // BC4U
861         case GL_COMPRESSED_SIGNED_RED_RGTC1_EXT: // BC4S
862         case GL_COMPRESSED_RED_GREEN_RGTC2_EXT: // BC5U
863         case GL_COMPRESSED_SIGNED_RED_GREEN_RGTC2_EXT: // BC5S
864             return true;
865         default:
866             break;
867     }
868     return false;
869 }
870 
isEtc2OrAstcFormat(GLenum format)871 bool isEtc2OrAstcFormat(GLenum format) {
872     switch (format) {
873     case GL_COMPRESSED_RGB8_ETC2:
874     case GL_COMPRESSED_SRGB8_ETC2:
875     case GL_COMPRESSED_RGBA8_ETC2_EAC:
876     case GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC:
877     case GL_COMPRESSED_R11_EAC:
878     case GL_COMPRESSED_SIGNED_R11_EAC:
879     case GL_COMPRESSED_RG11_EAC:
880     case GL_COMPRESSED_SIGNED_RG11_EAC:
881     case GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2:
882     case GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2:
883         return true;
884     default:
885         break;
886     }
887     return isAstcFormat(format);
888 }
889 
shouldPassthroughCompressedFormat(GLEScontext * ctx,GLenum internalformat)890 bool shouldPassthroughCompressedFormat(GLEScontext* ctx, GLenum internalformat) {
891     if (isEtc2Format(internalformat)) {
892         return ctx->getCaps()->hasEtc2Support;
893     } else if (isAstcFormat(internalformat)) {
894         return ctx->getCaps()->hasAstcSupport;
895     } else if (isBptcFormat(internalformat)) {
896         return ctx->getCaps()->hasBptcSupport;
897     } else if (isS3tcFormat(internalformat)) {
898         return ctx->getCaps()->hasS3tcSupport;
899     } else if (isRgtcFormat(internalformat)) {
900         return ctx->getCaps()->hasRgtcSupport;
901     }
902     return false;
903 }
904 
s_texAlign(uint32_t v,uint32_t align)905 static uint32_t s_texAlign(uint32_t v, uint32_t align) {
906     uint32_t rem = v % align;
907     return rem ? (v + (align - rem)) : v;
908 }
909 
910 // s_computePixelSize is both in the host and the guest. Consider moving it to
911 // android-emugl/shared
912 
s_computePixelSize(GLenum format,GLenum type)913 static int s_computePixelSize(GLenum format, GLenum type) {
914 #define FORMAT_ERROR(format, type)                                         \
915     fprintf(stderr, "%s:%d unknown format/type 0x%x 0x%x\n", __FUNCTION__, \
916             __LINE__, format, type);
917 
918     switch (type) {
919         case GL_BYTE:
920             switch (format) {
921                 case GL_R8:
922                 case GL_R8I:
923                 case GL_R8_SNORM:
924                 case GL_RED:
925                     return 1;
926                 case GL_RED_INTEGER:
927                     return 1;
928                 case GL_RG8:
929                 case GL_RG8I:
930                 case GL_RG8_SNORM:
931                 case GL_RG:
932                     return 1 * 2;
933                 case GL_RG_INTEGER:
934                     return 1 * 2;
935                 case GL_RGB8:
936                 case GL_RGB8I:
937                 case GL_RGB8_SNORM:
938                 case GL_RGB:
939                     return 1 * 3;
940                 case GL_RGB_INTEGER:
941                     return 1 * 3;
942                 case GL_RGBA8:
943                 case GL_RGBA8I:
944                 case GL_RGBA8_SNORM:
945                 case GL_RGBA:
946                     return 1 * 4;
947                 case GL_RGBA_INTEGER:
948                     return 1 * 4;
949                 default:
950                     FORMAT_ERROR(format, type);
951             }
952             break;
953         case GL_UNSIGNED_BYTE:
954             switch (format) {
955                 case GL_R8:
956                 case GL_R8UI:
957                 case GL_RED:
958                     return 1;
959                 case GL_RED_INTEGER:
960                     return 1;
961                 case GL_ALPHA8_EXT:
962                 case GL_ALPHA:
963                     return 1;
964                 case GL_LUMINANCE8_EXT:
965                 case GL_LUMINANCE:
966                     return 1;
967                 case GL_LUMINANCE8_ALPHA8_EXT:
968                 case GL_LUMINANCE_ALPHA:
969                     return 1 * 2;
970                 case GL_RG8:
971                 case GL_RG8UI:
972                 case GL_RG:
973                     return 1 * 2;
974                 case GL_RG_INTEGER:
975                     return 1 * 2;
976                 case GL_RGB8:
977                 case GL_RGB8UI:
978                 case GL_SRGB8:
979                 case GL_RGB:
980                     return 1 * 3;
981                 case GL_RGB_INTEGER:
982                     return 1 * 3;
983                 case GL_RGBA8:
984                 case GL_RGBA8UI:
985                 case GL_SRGB8_ALPHA8:
986                 case GL_RGBA:
987                     return 1 * 4;
988                 case GL_RGBA_INTEGER:
989                     return 1 * 4;
990                 case GL_BGRA_EXT:
991                 case GL_BGRA8_EXT:
992                     return 1 * 4;
993                 default:
994                     FORMAT_ERROR(format, type);
995             }
996             break;
997         case GL_SHORT:
998             switch (format) {
999                 case GL_R16I:
1000                 case GL_RED_INTEGER:
1001                     return 2;
1002                 case GL_RG16I:
1003                 case GL_RG_INTEGER:
1004                     return 2 * 2;
1005                 case GL_RGB16I:
1006                 case GL_RGB_INTEGER:
1007                     return 2 * 3;
1008                 case GL_RGBA16I:
1009                 case GL_RGBA_INTEGER:
1010                     return 2 * 4;
1011                 default:
1012                     FORMAT_ERROR(format, type);
1013             }
1014             break;
1015         case GL_UNSIGNED_SHORT:
1016             switch (format) {
1017                 case GL_DEPTH_COMPONENT16:
1018                 case GL_DEPTH_COMPONENT:
1019                     return 2;
1020                 case GL_R16UI:
1021                 case GL_RED_INTEGER:
1022                     return 2;
1023                 case GL_RG16UI:
1024                 case GL_RG_INTEGER:
1025                     return 2 * 2;
1026                 case GL_RGB16UI:
1027                 case GL_RGB_INTEGER:
1028                     return 2 * 3;
1029                 case GL_RGBA16UI:
1030                 case GL_RGBA_INTEGER:
1031                     return 2 * 4;
1032                 default:
1033                     FORMAT_ERROR(format, type);
1034             }
1035             break;
1036         case GL_INT:
1037             switch (format) {
1038                 case GL_R32I:
1039                 case GL_RED_INTEGER:
1040                     return 4;
1041                 case GL_RG32I:
1042                 case GL_RG_INTEGER:
1043                     return 4 * 2;
1044                 case GL_RGB32I:
1045                 case GL_RGB_INTEGER:
1046                     return 4 * 3;
1047                 case GL_RGBA32I:
1048                 case GL_RGBA_INTEGER:
1049                     return 4 * 4;
1050                 default:
1051                     FORMAT_ERROR(format, type);
1052             }
1053             break;
1054         case GL_UNSIGNED_INT:
1055             switch (format) {
1056                 case GL_DEPTH_COMPONENT16:
1057                 case GL_DEPTH_COMPONENT24:
1058                 case GL_DEPTH_COMPONENT32_OES:
1059                 case GL_DEPTH_COMPONENT:
1060                     return 4;
1061                 case GL_R32UI:
1062                 case GL_RED_INTEGER:
1063                     return 4;
1064                 case GL_RG32UI:
1065                 case GL_RG_INTEGER:
1066                     return 4 * 2;
1067                 case GL_RGB32UI:
1068                 case GL_RGB_INTEGER:
1069                     return 4 * 3;
1070                 case GL_RGBA32UI:
1071                 case GL_RGBA_INTEGER:
1072                     return 4 * 4;
1073                 default:
1074                     FORMAT_ERROR(format, type);
1075             }
1076             break;
1077         case GL_UNSIGNED_SHORT_4_4_4_4:
1078         case GL_UNSIGNED_SHORT_5_5_5_1:
1079         case GL_UNSIGNED_SHORT_5_6_5:
1080         case GL_UNSIGNED_SHORT_4_4_4_4_REV_EXT:
1081         case GL_UNSIGNED_SHORT_1_5_5_5_REV_EXT:
1082             return 2;
1083         case GL_UNSIGNED_INT_10F_11F_11F_REV:
1084         case GL_UNSIGNED_INT_5_9_9_9_REV:
1085         case GL_UNSIGNED_INT_2_10_10_10_REV:
1086         case GL_UNSIGNED_INT_24_8_OES:
1087             return 4;
1088         case GL_FLOAT_32_UNSIGNED_INT_24_8_REV:
1089             return 4 + 4;
1090         case GL_FLOAT:
1091             switch (format) {
1092                 case GL_DEPTH_COMPONENT32F:
1093                 case GL_DEPTH_COMPONENT:
1094                     return 4;
1095                 case GL_ALPHA32F_EXT:
1096                 case GL_ALPHA:
1097                     return 4;
1098                 case GL_LUMINANCE32F_EXT:
1099                 case GL_LUMINANCE:
1100                     return 4;
1101                 case GL_LUMINANCE_ALPHA32F_EXT:
1102                 case GL_LUMINANCE_ALPHA:
1103                     return 4 * 2;
1104                 case GL_RED:
1105                     return 4;
1106                 case GL_R32F:
1107                     return 4;
1108                 case GL_RG:
1109                     return 4 * 2;
1110                 case GL_RG32F:
1111                     return 4 * 2;
1112                 case GL_RGB:
1113                     return 4 * 3;
1114                 case GL_RGB32F:
1115                     return 4 * 3;
1116                 case GL_RGBA:
1117                     return 4 * 4;
1118                 case GL_RGBA32F:
1119                     return 4 * 4;
1120                 default:
1121                     FORMAT_ERROR(format, type);
1122             }
1123             break;
1124         case GL_HALF_FLOAT:
1125         case GL_HALF_FLOAT_OES:
1126             switch (format) {
1127                 case GL_ALPHA16F_EXT:
1128                 case GL_ALPHA:
1129                     return 2;
1130                 case GL_LUMINANCE16F_EXT:
1131                 case GL_LUMINANCE:
1132                     return 2;
1133                 case GL_LUMINANCE_ALPHA16F_EXT:
1134                 case GL_LUMINANCE_ALPHA:
1135                     return 2 * 2;
1136                 case GL_RED:
1137                     return 2;
1138                 case GL_R16F:
1139                     return 2;
1140                 case GL_RG:
1141                     return 2 * 2;
1142                 case GL_RG16F:
1143                     return 2 * 2;
1144                 case GL_RGB:
1145                     return 2 * 3;
1146                 case GL_RGB16F:
1147                     return 2 * 3;
1148                 case GL_RGBA:
1149                     return 2 * 4;
1150                 case GL_RGBA16F:
1151                     return 2 * 4;
1152                 default:
1153                     FORMAT_ERROR(format, type);
1154             }
1155             break;
1156         default:
1157             FORMAT_ERROR(format, type);
1158     }
1159 
1160     return 0;
1161 }
1162 
texImageSize(GLenum internalformat,GLenum type,int unpackAlignment,GLsizei width,GLsizei height)1163 uint32_t texImageSize(GLenum internalformat,
1164                       GLenum type,
1165                       int unpackAlignment,
1166                       GLsizei width,
1167                       GLsizei height) {
1168 
1169     uint32_t alignedWidth = s_texAlign(width, unpackAlignment);
1170     uint32_t pixelSize = s_computePixelSize(internalformat, type);
1171     uint32_t totalSize = pixelSize * alignedWidth * height;
1172 
1173     return totalSize;
1174 }
1175 
getFormatFromInternalFormat(GLint internalFormat)1176 GLenum getFormatFromInternalFormat(GLint internalFormat) {
1177     switch (internalFormat) {
1178         case GL_R8:
1179             return GL_RED;
1180         case GL_RG8:
1181             return GL_RG;
1182         case GL_RGB8:
1183         case GL_RGB565:
1184         case GL_RGB16F:
1185             return GL_RGB;
1186         case GL_RGBA8:
1187         case GL_RGB5_A1_OES:
1188         case GL_RGBA4_OES:
1189         case GL_UNSIGNED_INT_10_10_10_2_OES:
1190         case GL_RGB10_A2:
1191         case GL_RGBA16F:
1192             return GL_RGBA;
1193         case GL_BGRA8_EXT:
1194             return GL_BGRA_EXT;
1195         default: // already unsized
1196             return internalFormat;
1197     }
1198 }
1199 
getTypeFromInternalFormat(GLint internalFormat)1200 GLenum getTypeFromInternalFormat(GLint internalFormat) {
1201     switch (internalFormat) {
1202         case GL_RGB:
1203         case GL_RGB8:
1204             return GL_UNSIGNED_BYTE;
1205         case GL_RGB565_OES:
1206             return GL_UNSIGNED_SHORT_5_6_5;
1207         case GL_RGBA:
1208         case GL_RGBA8:
1209         case GL_RGB5_A1_OES:
1210         case GL_RGBA4_OES:
1211             return GL_UNSIGNED_BYTE;
1212         case GL_UNSIGNED_INT_10_10_10_2_OES:
1213             return GL_UNSIGNED_SHORT;
1214         case GL_RGB10_A2:
1215             return GL_UNSIGNED_INT_2_10_10_10_REV;
1216         case GL_RGB16F:
1217             return GL_HALF_FLOAT;
1218         case GL_RGBA16F:
1219             return GL_HALF_FLOAT;
1220         case GL_LUMINANCE:
1221             return GL_UNSIGNED_SHORT;
1222         case GL_BGRA_EXT:
1223             return GL_UNSIGNED_BYTE;
1224         case GL_R8:
1225         case GL_RED:
1226             return GL_UNSIGNED_BYTE;
1227         case GL_RG8:
1228         case GL_RG:
1229             return GL_UNSIGNED_BYTE;
1230         default:
1231             fprintf(stderr, "%s: Unknown format 0x%x\n", __func__,
1232                     internalFormat);
1233             return GL_UNSIGNED_BYTE;
1234     }
1235 }
1236 
1237 
unpackCheckAndUpdate(GLenum name,GLint newValue)1238 GLint TextureUnpackReset::unpackCheckAndUpdate(GLenum name, GLint newValue) {
1239     GLint curValue;
1240     glesContext->dispatcher().glGetIntegerv(name, &curValue);
1241     if (curValue != newValue) {
1242         glesContext->dispatcher().glPixelStorei(name, newValue);
1243     }
1244     return curValue;
1245 }
1246 
TextureUnpackReset(GLEScontext * ctx)1247 TextureUnpackReset::TextureUnpackReset(GLEScontext* ctx) : glesContext(ctx) {
1248     unpackAlignment = unpackCheckAndUpdate(GL_UNPACK_ALIGNMENT, kUnpackAlignment);
1249     if (glesContext->getMajorVersion() >= 3) {
1250         unpackRowLength = unpackCheckAndUpdate(GL_UNPACK_ROW_LENGTH, kUnpackRowLength);
1251         unpackImageHeight = unpackCheckAndUpdate(GL_UNPACK_IMAGE_HEIGHT, kUnpackImageHeight);
1252         unpackSkipRows = unpackCheckAndUpdate(GL_UNPACK_SKIP_ROWS, kUnpackSkipRows);
1253         unpackSkipPixels = unpackCheckAndUpdate(GL_UNPACK_SKIP_PIXELS, kUnpackSkipPixels);
1254         unpackSkipImages = unpackCheckAndUpdate(GL_UNPACK_SKIP_IMAGES, kUnpackSkipImages);
1255     }
1256 }
~TextureUnpackReset()1257 TextureUnpackReset::~TextureUnpackReset() {
1258     unpackCheckAndUpdate(GL_UNPACK_ALIGNMENT, unpackAlignment);
1259     if (glesContext->getMajorVersion() >= 3) {
1260         unpackCheckAndUpdate(GL_UNPACK_ROW_LENGTH, unpackRowLength);
1261         unpackCheckAndUpdate(GL_UNPACK_IMAGE_HEIGHT, unpackImageHeight);
1262         unpackCheckAndUpdate(GL_UNPACK_SKIP_ROWS, unpackSkipRows);
1263         unpackCheckAndUpdate(GL_UNPACK_SKIP_PIXELS, unpackSkipPixels);
1264         unpackCheckAndUpdate(GL_UNPACK_SKIP_IMAGES, unpackSkipImages);
1265     }
1266 }
1267 
1268