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