| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright 2011 Google Inc. | 2 * Copyright 2011 Google Inc. |
| 3 * | 3 * |
| 4 * Use of this source code is governed by a BSD-style license that can be | 4 * Use of this source code is governed by a BSD-style license that can be |
| 5 * found in the LICENSE file. | 5 * found in the LICENSE file. |
| 6 */ | 6 */ |
| 7 | 7 |
| 8 #include "GrGLGpu.h" | 8 #include "GrGLGpu.h" |
| 9 #include "GrGLGLSL.h" | 9 #include "GrGLGLSL.h" |
| 10 #include "GrGLStencilAttachment.h" | 10 #include "GrGLStencilAttachment.h" |
| (...skipping 898 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 909 } else { | 909 } else { |
| 910 return CHECK_ALLOC_ERROR(interface); | 910 return CHECK_ALLOC_ERROR(interface); |
| 911 } | 911 } |
| 912 } | 912 } |
| 913 | 913 |
| 914 /** | 914 /** |
| 915 * Creates storage space for the texture and fills it with texels. | 915 * Creates storage space for the texture and fills it with texels. |
| 916 * | 916 * |
| 917 * @param desc The surface descriptor for the texture being created. | 917 * @param desc The surface descriptor for the texture being created. |
| 918 * @param interface The GL interface in use. | 918 * @param interface The GL interface in use. |
| 919 * @param target The GL target to which the texture is bound | 919 * @param caps The capabilities of the GL device. |
| 920 * @param internalFormat The data format used for the internal storage of the te
xture. | 920 * @param internalFormat The data format used for the internal storage of the te
xture. |
| 921 * @param externalFormat The data format used for the external storage of the te
xture. | 921 * @param externalFormat The data format used for the external storage of the te
xture. |
| 922 * @param externalType The type of the data used for the external storage of t
he texture. | 922 * @param externalType The type of the data used for the external storage of t
he texture. |
| 923 * @param texels The texel data of the texture being created. | 923 * @param texels The texel data of the texture being created. |
| 924 * @param baseWidth The width of the texture's base mipmap level | 924 * @param baseWidth The width of the texture's base mipmap level |
| 925 * @param baseHeight The height of the texture's base mipmap level | 925 * @param baseHeight The height of the texture's base mipmap level |
| 926 * @param succeeded Set to true if allocating and populating the texture co
mpleted | 926 * @param succeeded Set to true if allocating and populating the texture co
mpleted |
| 927 * without error. | 927 * without error. |
| 928 */ | 928 */ |
| 929 static void allocate_and_populate_uncompressed_texture(const GrSurfaceDesc& desc
, | 929 static void allocate_and_populate_uncompressed_texture(const GrSurfaceDesc& desc
, |
| 930 const GrGLInterface& inte
rface, | 930 const GrGLInterface& inte
rface, |
| 931 const GrGLCaps& caps, |
| 931 GrGLenum target, | 932 GrGLenum target, |
| 932 GrGLenum internalFormat, | 933 GrGLenum internalFormat, |
| 933 GrGLenum externalFormat, | 934 GrGLenum externalFormat, |
| 934 GrGLenum externalType, | 935 GrGLenum externalType, |
| 935 const SkTArray<GrMipLevel
>& texels, | 936 const SkTArray<GrMipLevel
>& texels, |
| 936 int baseWidth, int baseHe
ight, | 937 int baseWidth, int baseHe
ight, |
| 937 bool* succeeded) { | 938 bool* succeeded) { |
| 938 CLEAR_ERROR_BEFORE_ALLOC(&interface); | 939 CLEAR_ERROR_BEFORE_ALLOC(&interface); |
| 939 *succeeded = true; | 940 |
| 940 for (int currentMipLevel = 0; currentMipLevel < texels.count(); currentMipLe
vel++) { | 941 bool useTexStorage = caps.isConfigTexSupportEnabled(desc.fConfig); |
| 941 int twoToTheMipLevel = 1 << currentMipLevel; | 942 // We can only use TexStorage if we know we will not later change the storag
e requirements. |
| 942 int currentWidth = SkTMax(1, baseWidth / twoToTheMipLevel); | 943 // This means if we may later want to add mipmaps, we cannot use TexStorage. |
| 943 int currentHeight = SkTMax(1, baseHeight / twoToTheMipLevel); | 944 // Right now, we cannot know if we will later add mipmaps or not. |
| 944 const void* currentMipData = texels[currentMipLevel].fPixels; | 945 // The only time we can use TexStorage is when we already have the |
| 945 // Even if curremtMipData is nullptr, continue to call TexImage2D. | 946 // mipmaps. |
| 946 // This will allocate texture memory which we can later populate. | 947 useTexStorage &= texels.count() > 1; |
| 948 |
| 949 if (useTexStorage) { |
| 950 // We never resize or change formats of textures. |
| 947 GL_ALLOC_CALL(&interface, | 951 GL_ALLOC_CALL(&interface, |
| 948 TexImage2D(target, | 952 TexStorage2D(target, |
| 949 currentMipLevel, | 953 texels.count(), |
| 950 internalFormat, | 954 internalFormat, |
| 951 currentWidth, | 955 desc.fWidth, desc.fHeight)); |
| 952 currentHeight, | |
| 953 0, // border | |
| 954 externalFormat, externalType, | |
| 955 currentMipData)); | |
| 956 GrGLenum error = check_alloc_error(desc, &interface); | 956 GrGLenum error = check_alloc_error(desc, &interface); |
| 957 if (error != GR_GL_NO_ERROR) { | 957 if (error != GR_GL_NO_ERROR) { |
| 958 *succeeded = false; | 958 *succeeded = false; |
| 959 break; | 959 } else { |
| 960 for (int currentMipLevel = 0; currentMipLevel < texels.count(); curr
entMipLevel++) { |
| 961 const void* currentMipData = texels[currentMipLevel].fPixels; |
| 962 if (currentMipData == nullptr) { |
| 963 continue; |
| 964 } |
| 965 int twoToTheMipLevel = 1 << currentMipLevel; |
| 966 int currentWidth = SkTMax(1, desc.fWidth / twoToTheMipLevel); |
| 967 int currentHeight = SkTMax(1, desc.fHeight / twoToTheMipLevel); |
| 968 |
| 969 GR_GL_CALL(&interface, |
| 970 TexSubImage2D(target, |
| 971 currentMipLevel, |
| 972 0, // left |
| 973 0, // top |
| 974 currentWidth, |
| 975 currentHeight, |
| 976 externalFormat, externalType, |
| 977 currentMipData)); |
| 978 } |
| 979 *succeeded = true; |
| 980 } |
| 981 } else { |
| 982 *succeeded = true; |
| 983 for (int currentMipLevel = 0; currentMipLevel < texels.count(); currentM
ipLevel++) { |
| 984 int twoToTheMipLevel = 1 << currentMipLevel; |
| 985 int currentWidth = SkTMax(1, baseWidth / twoToTheMipLevel); |
| 986 int currentHeight = SkTMax(1, baseHeight / twoToTheMipLevel); |
| 987 const void* currentMipData = texels[currentMipLevel].fPixels; |
| 988 // Even if curremtMipData is nullptr, continue to call TexImage2D. |
| 989 // This will allocate texture memory which we can later populate. |
| 990 GL_ALLOC_CALL(&interface, |
| 991 TexImage2D(target, |
| 992 currentMipLevel, |
| 993 internalFormat, |
| 994 currentWidth, |
| 995 currentHeight, |
| 996 0, // border |
| 997 externalFormat, externalType, |
| 998 currentMipData)); |
| 999 GrGLenum error = check_alloc_error(desc, &interface); |
| 1000 if (error != GR_GL_NO_ERROR) { |
| 1001 *succeeded = false; |
| 1002 break; |
| 1003 } |
| 960 } | 1004 } |
| 961 } | 1005 } |
| 962 } | 1006 } |
| 963 | 1007 |
| 964 /** | 1008 /** |
| 965 * Creates storage space for the texture and fills it with texels. | 1009 * Creates storage space for the texture and fills it with texels. |
| 966 * | 1010 * |
| 967 * @param desc The surface descriptor for the texture being created. | 1011 * @param desc The surface descriptor for the texture being created. |
| 968 * @param interface The GL interface in use. | 1012 * @param interface The GL interface in use. |
| 969 * @param target The GL target to which the texture is bound | 1013 * @param caps The capabilities of the GL device. |
| 970 * @param internalFormat The data format used for the internal storage of the te
xture. | 1014 * @param internalFormat The data format used for the internal storage of the te
xture. |
| 971 * @param texels The texel data of the texture being created. | 1015 * @param texels The texel data of the texture being created. |
| 972 * @param baseWidth The width of the texture's base mipmap level | |
| 973 * @param baseHeight The height of the texture's base mipmap level | |
| 974 */ | 1016 */ |
| 975 static bool allocate_and_populate_compressed_texture(const GrSurfaceDesc& desc, | 1017 static bool allocate_and_populate_compressed_texture(const GrSurfaceDesc& desc, |
| 976 const GrGLInterface& interf
ace, | 1018 const GrGLInterface& interf
ace, |
| 1019 const GrGLCaps& caps, |
| 977 GrGLenum target, GrGLenum i
nternalFormat, | 1020 GrGLenum target, GrGLenum i
nternalFormat, |
| 978 const SkTArray<GrMipLevel>&
texels, | 1021 const SkTArray<GrMipLevel>&
texels, |
| 979 int baseWidth, int baseHeig
ht) { | 1022 int baseWidth, int baseHeig
ht) { |
| 980 CLEAR_ERROR_BEFORE_ALLOC(&interface); | 1023 CLEAR_ERROR_BEFORE_ALLOC(&interface); |
| 981 for (int currentMipLevel = 0; currentMipLevel < texels.count(); currentMipLe
vel++) { | |
| 982 int twoToTheMipLevel = 1 << currentMipLevel; | |
| 983 int currentWidth = SkTMax(1, baseWidth / twoToTheMipLevel); | |
| 984 int currentHeight = SkTMax(1, baseHeight / twoToTheMipLevel); | |
| 985 | 1024 |
| 986 // Make sure that the width and height that we pass to OpenGL | 1025 bool useTexStorage = caps.isConfigTexSupportEnabled(desc.fConfig); |
| 987 // is a multiple of the block size. | 1026 // We can only use TexStorage if we know we will not later change the storag
e requirements. |
| 988 size_t dataSize = GrCompressedFormatDataSize(desc.fConfig, baseWidth, ba
seHeight); | 1027 // This means if we may later want to add mipmaps, we cannot use TexStorage. |
| 1028 // Right now, we cannot know if we will later add mipmaps or not. |
| 1029 // The only time we can use TexStorage is when we already have the |
| 1030 // mipmaps. |
| 1031 useTexStorage &= texels.count() > 1; |
| 989 | 1032 |
| 1033 if (useTexStorage) { |
| 1034 // We never resize or change formats of textures. |
| 990 GL_ALLOC_CALL(&interface, | 1035 GL_ALLOC_CALL(&interface, |
| 991 CompressedTexImage2D(target, | 1036 TexStorage2D(target, |
| 992 currentMipLevel, | 1037 texels.count(), |
| 993 internalFormat, | 1038 internalFormat, |
| 994 currentWidth, | 1039 baseWidth, baseHeight)); |
| 995 currentHeight, | |
| 996 0, // border | |
| 997 SkToInt(dataSize), | |
| 998 texels[currentMipLevel].fPixels)); | |
| 999 | |
| 1000 GrGLenum error = check_alloc_error(desc, &interface); | 1040 GrGLenum error = check_alloc_error(desc, &interface); |
| 1001 if (error != GR_GL_NO_ERROR) { | 1041 if (error != GR_GL_NO_ERROR) { |
| 1002 return false; | 1042 return false; |
| 1043 } else { |
| 1044 for (int currentMipLevel = 0; currentMipLevel < texels.count(); curr
entMipLevel++) { |
| 1045 const void* currentMipData = texels[currentMipLevel].fPixels; |
| 1046 if (currentMipData == nullptr) { |
| 1047 continue; |
| 1048 } |
| 1049 |
| 1050 int twoToTheMipLevel = 1 << currentMipLevel; |
| 1051 int currentWidth = SkTMax(1, baseWidth / twoToTheMipLevel); |
| 1052 int currentHeight = SkTMax(1, baseHeight / twoToTheMipLevel); |
| 1053 |
| 1054 // Make sure that the width and height that we pass to OpenGL |
| 1055 // is a multiple of the block size. |
| 1056 size_t dataSize = GrCompressedFormatDataSize(desc.fConfig, curre
ntWidth, |
| 1057 currentHeight); |
| 1058 GR_GL_CALL(&interface, CompressedTexSubImage2D(target, |
| 1059 currentMipLevel, |
| 1060 0, // left |
| 1061 0, // top |
| 1062 currentWidth, |
| 1063 currentHeight, |
| 1064 internalFormat, |
| 1065 SkToInt(dataSize)
, |
| 1066 currentMipData)); |
| 1067 } |
| 1068 } |
| 1069 } else { |
| 1070 for (int currentMipLevel = 0; currentMipLevel < texels.count(); currentM
ipLevel++) { |
| 1071 int twoToTheMipLevel = 1 << currentMipLevel; |
| 1072 int currentWidth = SkTMax(1, baseWidth / twoToTheMipLevel); |
| 1073 int currentHeight = SkTMax(1, baseHeight / twoToTheMipLevel); |
| 1074 |
| 1075 // Make sure that the width and height that we pass to OpenGL |
| 1076 // is a multiple of the block size. |
| 1077 size_t dataSize = GrCompressedFormatDataSize(desc.fConfig, baseWidth
, baseHeight); |
| 1078 |
| 1079 GL_ALLOC_CALL(&interface, |
| 1080 CompressedTexImage2D(target, |
| 1081 currentMipLevel, |
| 1082 internalFormat, |
| 1083 currentWidth, |
| 1084 currentHeight, |
| 1085 0, // border |
| 1086 SkToInt(dataSize), |
| 1087 texels[currentMipLevel].fPixels))
; |
| 1088 |
| 1089 GrGLenum error = check_alloc_error(desc, &interface); |
| 1090 if (error != GR_GL_NO_ERROR) { |
| 1091 return false; |
| 1092 } |
| 1003 } | 1093 } |
| 1004 } | 1094 } |
| 1005 | 1095 |
| 1006 return true; | 1096 return true; |
| 1007 } | 1097 } |
| 1008 | 1098 |
| 1009 /** | 1099 /** |
| 1010 * After a texture is created, any state which was altered during its creation | 1100 * After a texture is created, any state which was altered during its creation |
| 1011 * needs to be restored. | 1101 * needs to be restored. |
| 1012 * | 1102 * |
| (...skipping 171 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1184 } | 1274 } |
| 1185 GR_GL_CALL(interface, PixelStorei(GR_GL_UNPACK_ALIGNMENT, | 1275 GR_GL_CALL(interface, PixelStorei(GR_GL_UNPACK_ALIGNMENT, |
| 1186 config_alignment(desc.fConfig))); | 1276 config_alignment(desc.fConfig))); |
| 1187 } | 1277 } |
| 1188 | 1278 |
| 1189 bool succeeded = true; | 1279 bool succeeded = true; |
| 1190 if (kNewTexture_UploadType == uploadType && | 1280 if (kNewTexture_UploadType == uploadType && |
| 1191 0 == left && 0 == top && | 1281 0 == left && 0 == top && |
| 1192 desc.fWidth == width && desc.fHeight == height && | 1282 desc.fWidth == width && desc.fHeight == height && |
| 1193 !desc.fTextureStorageAllocator.fAllocateTextureStorage) { | 1283 !desc.fTextureStorageAllocator.fAllocateTextureStorage) { |
| 1194 allocate_and_populate_uncompressed_texture(desc, *interface, target, | 1284 allocate_and_populate_uncompressed_texture(desc, *interface, caps, targe
t, |
| 1195 internalFormat, externalForma
t, | 1285 internalFormat, externalForma
t, |
| 1196 externalType, texelsShallowCo
py, | 1286 externalType, texelsShallowCo
py, |
| 1197 width, height, &succeeded); | 1287 width, height, &succeeded); |
| 1198 } else { | 1288 } else { |
| 1199 if (swFlipY || glFlipY) { | 1289 if (swFlipY || glFlipY) { |
| 1200 top = desc.fHeight - (top + height); | 1290 top = desc.fHeight - (top + height); |
| 1201 } | 1291 } |
| 1202 for (int currentMipLevel = 0; currentMipLevel < texelsShallowCopy.count(
); | 1292 for (int currentMipLevel = 0; currentMipLevel < texelsShallowCopy.count(
); |
| 1203 currentMipLevel++) { | 1293 currentMipLevel++) { |
| 1204 int twoToTheMipLevel = 1 << currentMipLevel; | 1294 int twoToTheMipLevel = 1 << currentMipLevel; |
| (...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1261 } | 1351 } |
| 1262 #endif | 1352 #endif |
| 1263 | 1353 |
| 1264 // We only need the internal format for compressed 2D textures. | 1354 // We only need the internal format for compressed 2D textures. |
| 1265 GrGLenum internalFormat; | 1355 GrGLenum internalFormat; |
| 1266 if (!caps.getCompressedTexImageFormats(desc.fConfig, &internalFormat)) { | 1356 if (!caps.getCompressedTexImageFormats(desc.fConfig, &internalFormat)) { |
| 1267 return false; | 1357 return false; |
| 1268 } | 1358 } |
| 1269 | 1359 |
| 1270 if (kNewTexture_UploadType == uploadType) { | 1360 if (kNewTexture_UploadType == uploadType) { |
| 1271 return allocate_and_populate_compressed_texture(desc, *interface, target
, internalFormat, | 1361 return allocate_and_populate_compressed_texture(desc, *interface, caps,
target, |
| 1272 texels, width, height); | 1362 internalFormat, texels,
width, height); |
| 1273 } else { | 1363 } else { |
| 1274 // Paletted textures can't be updated. | 1364 // Paletted textures can't be updated. |
| 1275 if (GR_GL_PALETTE8_RGBA8 == internalFormat) { | 1365 if (GR_GL_PALETTE8_RGBA8 == internalFormat) { |
| 1276 return false; | 1366 return false; |
| 1277 } | 1367 } |
| 1278 for (int currentMipLevel = 0; currentMipLevel < texels.count(); currentM
ipLevel++) { | 1368 for (int currentMipLevel = 0; currentMipLevel < texels.count(); currentM
ipLevel++) { |
| 1279 if (texels[currentMipLevel].fPixels == nullptr) { | 1369 if (texels[currentMipLevel].fPixels == nullptr) { |
| 1280 continue; | 1370 continue; |
| 1281 } | 1371 } |
| 1282 | 1372 |
| (...skipping 2934 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4217 if (GR_GL_TEXTURE_EXTERNAL == glTexture->target() || | 4307 if (GR_GL_TEXTURE_EXTERNAL == glTexture->target() || |
| 4218 GR_GL_TEXTURE_RECTANGLE == glTexture->target()) { | 4308 GR_GL_TEXTURE_RECTANGLE == glTexture->target()) { |
| 4219 copyParams->fFilter = GrTextureParams::kNone_FilterMode; | 4309 copyParams->fFilter = GrTextureParams::kNone_FilterMode; |
| 4220 copyParams->fWidth = texture->width(); | 4310 copyParams->fWidth = texture->width(); |
| 4221 copyParams->fHeight = texture->height(); | 4311 copyParams->fHeight = texture->height(); |
| 4222 return true; | 4312 return true; |
| 4223 } | 4313 } |
| 4224 } | 4314 } |
| 4225 return false; | 4315 return false; |
| 4226 } | 4316 } |
| OLD | NEW |