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