Home | History | Annotate | Download | only in OpenglCodecCommon
      1 #include "GLESTextureUtils.h"
      2 
      3 #include "glUtils.h"
      4 
      5 #if PLATFORM_SDK_VERSION < 26
      6 #include <cutils/log.h>
      7 #else
      8 #include <log/log.h>
      9 #endif
     10 
     11 namespace GLESTextureUtils {
     12 
     13 // Based on computations in
     14 // https://swiftshader.googlesource.com/SwiftShader/+/master/src/OpenGL/common/Image.cpp
     15 // such as Image::loadImageData,
     16 // ComputePitch/ComputePackingOffset
     17 
     18 #define HIGHEST_MULTIPLE_OF(align, x) \
     19     (( ( x ) + ( align ) - 1) & ~( ( align ) - 1)) \
     20 
     21 static int computePixelSize(GLenum format, GLenum type) {
     22 
     23 #define FORMAT_ERROR(format, type) \
     24     ALOGE("%s:%d unknown format/type 0x%x 0x%x", __FUNCTION__, __LINE__, format, type) \
     25 
     26     switch(type) {
     27     case GL_BYTE:
     28         switch(format) {
     29         case GL_R8:
     30         case GL_R8I:
     31         case GL_R8_SNORM:
     32         case GL_RED:             return sizeof(char);
     33         case GL_RED_INTEGER:     return sizeof(char);
     34         case GL_RG8:
     35         case GL_RG8I:
     36         case GL_RG8_SNORM:
     37         case GL_RG:              return sizeof(char) * 2;
     38         case GL_RG_INTEGER:      return sizeof(char) * 2;
     39         case GL_RGB8:
     40         case GL_RGB8I:
     41         case GL_RGB8_SNORM:
     42         case GL_RGB:             return sizeof(char) * 3;
     43         case GL_RGB_INTEGER:     return sizeof(char) * 3;
     44         case GL_RGBA8:
     45         case GL_RGBA8I:
     46         case GL_RGBA8_SNORM:
     47         case GL_RGBA:            return sizeof(char) * 4;
     48         case GL_RGBA_INTEGER:    return sizeof(char) * 4;
     49         default: FORMAT_ERROR(format, type);
     50         }
     51         break;
     52     case GL_UNSIGNED_BYTE:
     53         switch(format) {
     54         case GL_R8:
     55         case GL_R8UI:
     56         case GL_RED:             return sizeof(unsigned char);
     57         case GL_RED_INTEGER:     return sizeof(unsigned char);
     58         case GL_ALPHA8_EXT:
     59         case GL_ALPHA:           return sizeof(unsigned char);
     60         case GL_LUMINANCE8_EXT:
     61         case GL_LUMINANCE:       return sizeof(unsigned char);
     62         case GL_LUMINANCE8_ALPHA8_EXT:
     63         case GL_LUMINANCE_ALPHA: return sizeof(unsigned char) * 2;
     64         case GL_RG8:
     65         case GL_RG8UI:
     66         case GL_RG:              return sizeof(unsigned char) * 2;
     67         case GL_RG_INTEGER:      return sizeof(unsigned char) * 2;
     68         case GL_RGB8:
     69         case GL_RGB8UI:
     70         case GL_SRGB8:
     71         case GL_RGB:             return sizeof(unsigned char) * 3;
     72         case GL_RGB_INTEGER:     return sizeof(unsigned char) * 3;
     73         case GL_RGBA8:
     74         case GL_RGBA8UI:
     75         case GL_SRGB8_ALPHA8:
     76         case GL_RGBA:            return sizeof(unsigned char) * 4;
     77         case GL_RGBA_INTEGER:    return sizeof(unsigned char) * 4;
     78         case GL_BGRA_EXT:
     79         case GL_BGRA8_EXT:       return sizeof(unsigned char)* 4;
     80         default: FORMAT_ERROR(format, type);
     81         }
     82         break;
     83     case GL_SHORT:
     84         switch(format) {
     85         case GL_R16I:
     86         case GL_RED_INTEGER:     return sizeof(short);
     87         case GL_RG16I:
     88         case GL_RG_INTEGER:      return sizeof(short) * 2;
     89         case GL_RGB16I:
     90         case GL_RGB_INTEGER:     return sizeof(short) * 3;
     91         case GL_RGBA16I:
     92         case GL_RGBA_INTEGER:    return sizeof(short) * 4;
     93         default: FORMAT_ERROR(format, type);
     94         }
     95         break;
     96     case GL_UNSIGNED_SHORT:
     97         switch(format) {
     98         case GL_DEPTH_COMPONENT16:
     99         case GL_DEPTH_COMPONENT: return sizeof(unsigned short);
    100         case GL_R16UI:
    101         case GL_RED_INTEGER:     return sizeof(unsigned short);
    102         case GL_RG16UI:
    103         case GL_RG_INTEGER:      return sizeof(unsigned short) * 2;
    104         case GL_RGB16UI:
    105         case GL_RGB_INTEGER:     return sizeof(unsigned short) * 3;
    106         case GL_RGBA16UI:
    107         case GL_RGBA_INTEGER:    return sizeof(unsigned short) * 4;
    108         default: FORMAT_ERROR(format, type);
    109         }
    110         break;
    111     case GL_INT:
    112         switch(format) {
    113         case GL_R32I:
    114         case GL_RED_INTEGER:     return sizeof(int);
    115         case GL_RG32I:
    116         case GL_RG_INTEGER:      return sizeof(int) * 2;
    117         case GL_RGB32I:
    118         case GL_RGB_INTEGER:     return sizeof(int) * 3;
    119         case GL_RGBA32I:
    120         case GL_RGBA_INTEGER:    return sizeof(int) * 4;
    121         default: FORMAT_ERROR(format, type);
    122         }
    123         break;
    124     case GL_UNSIGNED_INT:
    125         switch(format) {
    126         case GL_DEPTH_COMPONENT16:
    127         case GL_DEPTH_COMPONENT24:
    128         case GL_DEPTH_COMPONENT32_OES:
    129         case GL_DEPTH_COMPONENT: return sizeof(unsigned int);
    130         case GL_R32UI:
    131         case GL_RED_INTEGER:     return sizeof(unsigned int);
    132         case GL_RG32UI:
    133         case GL_RG_INTEGER:      return sizeof(unsigned int) * 2;
    134         case GL_RGB32UI:
    135         case GL_RGB_INTEGER:     return sizeof(unsigned int) * 3;
    136         case GL_RGBA32UI:
    137         case GL_RGBA_INTEGER:    return sizeof(unsigned int) * 4;
    138         default: FORMAT_ERROR(format, type);
    139         }
    140         break;
    141     case GL_UNSIGNED_SHORT_4_4_4_4:
    142     case GL_UNSIGNED_SHORT_5_5_5_1:
    143     case GL_UNSIGNED_SHORT_5_6_5:
    144     case GL_UNSIGNED_SHORT_4_4_4_4_REV_EXT:
    145     case GL_UNSIGNED_SHORT_1_5_5_5_REV_EXT:
    146         return sizeof(unsigned short);
    147     case GL_UNSIGNED_INT_10F_11F_11F_REV:
    148     case GL_UNSIGNED_INT_5_9_9_9_REV:
    149     case GL_UNSIGNED_INT_2_10_10_10_REV:
    150     case GL_UNSIGNED_INT_24_8_OES:
    151         return sizeof(unsigned int);
    152     case GL_FLOAT_32_UNSIGNED_INT_24_8_REV:
    153         return sizeof(float) + sizeof(unsigned int);
    154     case GL_FLOAT:
    155         switch(format) {
    156         case GL_DEPTH_COMPONENT32F:
    157         case GL_DEPTH_COMPONENT: return sizeof(float);
    158         case GL_ALPHA32F_EXT:
    159         case GL_ALPHA:           return sizeof(float);
    160         case GL_LUMINANCE32F_EXT:
    161         case GL_LUMINANCE:       return sizeof(float);
    162         case GL_LUMINANCE_ALPHA32F_EXT:
    163         case GL_LUMINANCE_ALPHA: return sizeof(float) * 2;
    164         case GL_RED:             return sizeof(float);
    165         case GL_R32F:            return sizeof(float);
    166         case GL_RG:              return sizeof(float) * 2;
    167         case GL_RG32F:           return sizeof(float) * 2;
    168         case GL_RGB:             return sizeof(float) * 3;
    169         case GL_RGB32F:          return sizeof(float) * 3;
    170         case GL_RGBA:            return sizeof(float) * 4;
    171         case GL_RGBA32F:         return sizeof(float) * 4;
    172         default: FORMAT_ERROR(format, type);
    173         }
    174         break;
    175     case GL_HALF_FLOAT:
    176     case GL_HALF_FLOAT_OES:
    177         switch(format) {
    178         case GL_ALPHA16F_EXT:
    179         case GL_ALPHA:           return sizeof(unsigned short);
    180         case GL_LUMINANCE16F_EXT:
    181         case GL_LUMINANCE:       return sizeof(unsigned short);
    182         case GL_LUMINANCE_ALPHA16F_EXT:
    183         case GL_LUMINANCE_ALPHA: return sizeof(unsigned short) * 2;
    184         case GL_RED:             return sizeof(unsigned short);
    185         case GL_R16F:            return sizeof(unsigned short);
    186         case GL_RG:              return sizeof(unsigned short) * 2;
    187         case GL_RG16F:           return sizeof(unsigned short) * 2;
    188         case GL_RGB:             return sizeof(unsigned short) * 3;
    189         case GL_RGB16F:          return sizeof(unsigned short) * 3;
    190         case GL_RGBA:            return sizeof(unsigned short) * 4;
    191         case GL_RGBA16F:         return sizeof(unsigned short) * 4;
    192         default: FORMAT_ERROR(format, type);
    193         }
    194         break;
    195     default: FORMAT_ERROR(format, type);
    196     }
    197 
    198     return 0;
    199 }
    200 
    201 static int computePitch(GLsizei inputWidth, GLenum format, GLenum type, int align) {
    202     GLsizei unaligned_width = computePixelSize(format, type) * inputWidth;
    203     return HIGHEST_MULTIPLE_OF(align, unaligned_width);
    204 }
    205 
    206 static int computePackingOffset(GLenum format, GLenum type, GLsizei width, GLsizei height, int align, int skipPixels, int skipRows, int skipImages) {
    207     GLsizei alignedPitch = computePitch(width, format, type, align);
    208     int packingOffsetRows =
    209         (skipImages * height + skipRows);
    210     return packingOffsetRows * alignedPitch + skipPixels * computePixelSize(format, type);
    211 }
    212 
    213 void computeTextureStartEnd(
    214         GLsizei width, GLsizei height, GLsizei depth,
    215         GLenum format, GLenum type,
    216         int unpackAlignment,
    217         int unpackRowLength,
    218         int unpackImageHeight,
    219         int unpackSkipPixels,
    220         int unpackSkipRows,
    221         int unpackSkipImages,
    222         int* start,
    223         int* end) {
    224 
    225     GLsizei inputWidth = (unpackRowLength == 0) ? width : unpackRowLength;
    226     GLsizei inputPitch = computePitch(inputWidth, format, type, unpackAlignment);
    227     GLsizei inputHeight = (unpackImageHeight == 0) ? height : unpackImageHeight;
    228 
    229     ALOGV("%s: input idim %d %d %d w p h %d %d %d:", __FUNCTION__, width, height, depth, inputWidth, inputPitch, inputHeight);
    230 
    231     int startVal = computePackingOffset(format, type, inputWidth, inputHeight, unpackAlignment, unpackSkipPixels, unpackSkipRows, unpackSkipImages);
    232     int endVal = startVal + inputPitch * inputHeight * depth;
    233 
    234     if (start) *start = startVal;
    235     if (end) *end = endVal;
    236 
    237     ALOGV("%s: start/end: %d %d", __FUNCTION__, *start, *end);
    238 
    239 }
    240 
    241 int computeTotalImageSize(
    242         GLsizei width, GLsizei height, GLsizei depth,
    243         GLenum format, GLenum type,
    244         int unpackAlignment,
    245         int unpackRowLength,
    246         int unpackImageHeight,
    247         int unpackSkipPixels,
    248         int unpackSkipRows,
    249         int unpackSkipImages) {
    250 
    251     int start, end;
    252     computeTextureStartEnd(
    253             width, height, depth,
    254             format, type,
    255             unpackAlignment,
    256             unpackRowLength,
    257             unpackImageHeight,
    258             unpackSkipPixels,
    259             unpackSkipRows,
    260             unpackSkipImages,
    261             &start,
    262             &end);
    263     return end;
    264 }
    265 
    266 int computeNeededBufferSize(
    267         GLsizei width, GLsizei height, GLsizei depth,
    268         GLenum format, GLenum type,
    269         int unpackAlignment,
    270         int unpackRowLength,
    271         int unpackImageHeight,
    272         int unpackSkipPixels,
    273         int unpackSkipRows,
    274         int unpackSkipImages) {
    275 
    276     int start, end;
    277     computeTextureStartEnd(
    278             width, height, depth,
    279             format, type,
    280             unpackAlignment,
    281             unpackRowLength,
    282             unpackImageHeight,
    283             unpackSkipPixels,
    284             unpackSkipRows,
    285             unpackSkipImages,
    286             &start,
    287             &end);
    288     return end - start;
    289 }
    290 
    291 void computePackingOffsets2D(
    292         GLsizei width, GLsizei height,
    293         GLenum format, GLenum type,
    294         int packAlignment,
    295         int packRowLength,
    296         int packSkipPixels,
    297         int packSkipRows,
    298         int* startOffset,
    299         int* packingPixelRowSize,
    300         int* packingTotalRowSize) {
    301 
    302     int widthTotal = (packRowLength == 0) ? width : packRowLength;
    303     int totalRowSize = computePitch(widthTotal, format, type, packAlignment);
    304     int pixelsOnlyRowSize = computePitch(width, format, type, packAlignment);
    305 
    306     int packingOffsetStart =
    307         computePackingOffset(
    308                 format, type, widthTotal, height, packAlignment, packSkipPixels, packSkipRows, 0 /* skip images = 0 */);
    309 
    310     if (startOffset) *startOffset = packingOffsetStart;
    311     if (packingPixelRowSize) *packingPixelRowSize = pixelsOnlyRowSize;
    312     if (packingTotalRowSize) *packingTotalRowSize = totalRowSize;
    313 }
    314 
    315 
    316 } // namespace GLESTextureUtils
    317