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