| 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 908 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 919 * @param caps The capabilities of the GL device. | 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 bool 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 const GrGLCaps& caps, |
| 932 GrGLenum target, | 932 GrGLenum target, |
| 933 GrGLenum internalFormat, | 933 GrGLenum internalFormat, |
| 934 GrGLenum externalFormat, | 934 GrGLenum externalFormat, |
| 935 GrGLenum externalType, | 935 GrGLenum externalType, |
| 936 const SkTArray<GrMipLevel
>& texels, | 936 const SkTArray<GrMipLevel
>& texels, |
| 937 int baseWidth, int baseHe
ight) { | 937 int baseWidth, int baseHe
ight, |
| 938 bool* succeeded) { |
| 938 CLEAR_ERROR_BEFORE_ALLOC(&interface); | 939 CLEAR_ERROR_BEFORE_ALLOC(&interface); |
| 939 | 940 |
| 940 bool useTexStorage = caps.isConfigTexSupportEnabled(desc.fConfig); | 941 bool useTexStorage = caps.isConfigTexSupportEnabled(desc.fConfig); |
| 941 // We can only use TexStorage if we know we will not later change the storag
e requirements. | 942 // We can only use TexStorage if we know we will not later change the storag
e requirements. |
| 942 // This means if we may later want to add mipmaps, we cannot use TexStorage. | 943 // This means if we may later want to add mipmaps, we cannot use TexStorage. |
| 943 // Right now, we cannot know if we will later add mipmaps or not. | 944 // Right now, we cannot know if we will later add mipmaps or not. |
| 944 // The only time we can use TexStorage is when we already have the | 945 // The only time we can use TexStorage is when we already have the |
| 945 // mipmaps. | 946 // mipmaps. |
| 946 useTexStorage &= texels.count() > 1; | 947 useTexStorage &= texels.count() > 1; |
| 947 | 948 |
| 948 if (useTexStorage) { | 949 if (useTexStorage) { |
| 949 // We never resize or change formats of textures. | 950 // We never resize or change formats of textures. |
| 950 GL_ALLOC_CALL(&interface, | 951 GL_ALLOC_CALL(&interface, |
| 951 TexStorage2D(target, | 952 TexStorage2D(target, |
| 952 texels.count(), | 953 texels.count(), |
| 953 internalFormat, | 954 internalFormat, |
| 954 desc.fWidth, desc.fHeight)); | 955 desc.fWidth, desc.fHeight)); |
| 955 GrGLenum error = check_alloc_error(desc, &interface); | 956 GrGLenum error = check_alloc_error(desc, &interface); |
| 956 if (error != GR_GL_NO_ERROR) { | 957 if (error != GR_GL_NO_ERROR) { |
| 957 return false; | 958 *succeeded = false; |
| 958 } else { | 959 } else { |
| 959 for (int currentMipLevel = 0; currentMipLevel < texels.count(); curr
entMipLevel++) { | 960 for (int currentMipLevel = 0; currentMipLevel < texels.count(); curr
entMipLevel++) { |
| 960 const void* currentMipData = texels[currentMipLevel].fPixels; | 961 const void* currentMipData = texels[currentMipLevel].fPixels; |
| 961 if (currentMipData == nullptr) { | 962 if (currentMipData == nullptr) { |
| 962 continue; | 963 continue; |
| 963 } | 964 } |
| 964 int twoToTheMipLevel = 1 << currentMipLevel; | 965 int twoToTheMipLevel = 1 << currentMipLevel; |
| 965 int currentWidth = SkTMax(1, desc.fWidth / twoToTheMipLevel); | 966 int currentWidth = SkTMax(1, desc.fWidth / twoToTheMipLevel); |
| 966 int currentHeight = SkTMax(1, desc.fHeight / twoToTheMipLevel); | 967 int currentHeight = SkTMax(1, desc.fHeight / twoToTheMipLevel); |
| 967 | 968 |
| 968 GR_GL_CALL(&interface, | 969 GR_GL_CALL(&interface, |
| 969 TexSubImage2D(target, | 970 TexSubImage2D(target, |
| 970 currentMipLevel, | 971 currentMipLevel, |
| 971 0, // left | 972 0, // left |
| 972 0, // top | 973 0, // top |
| 973 currentWidth, | 974 currentWidth, |
| 974 currentHeight, | 975 currentHeight, |
| 975 externalFormat, externalType, | 976 externalFormat, externalType, |
| 976 currentMipData)); | 977 currentMipData)); |
| 977 } | 978 } |
| 978 return true; | 979 *succeeded = true; |
| 979 } | 980 } |
| 980 } else { | 981 } else { |
| 981 if (texels.empty()) { | 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. |
| 982 GL_ALLOC_CALL(&interface, | 990 GL_ALLOC_CALL(&interface, |
| 983 TexImage2D(target, | 991 TexImage2D(target, |
| 984 0, | 992 currentMipLevel, |
| 985 internalFormat, | 993 internalFormat, |
| 986 baseWidth, | 994 currentWidth, |
| 987 baseHeight, | 995 currentHeight, |
| 988 0, // border | 996 0, // border |
| 989 externalFormat, externalType, | 997 externalFormat, externalType, |
| 990 nullptr)); | 998 currentMipData)); |
| 991 GrGLenum error = check_alloc_error(desc, &interface); | 999 GrGLenum error = check_alloc_error(desc, &interface); |
| 992 if (error != GR_GL_NO_ERROR) { | 1000 if (error != GR_GL_NO_ERROR) { |
| 993 return false; | 1001 *succeeded = false; |
| 994 } | 1002 break; |
| 995 } else { | |
| 996 for (int currentMipLevel = 0; currentMipLevel < texels.count(); curr
entMipLevel++) { | |
| 997 int twoToTheMipLevel = 1 << currentMipLevel; | |
| 998 int currentWidth = SkTMax(1, baseWidth / twoToTheMipLevel); | |
| 999 int currentHeight = SkTMax(1, baseHeight / twoToTheMipLevel); | |
| 1000 const void* currentMipData = texels[currentMipLevel].fPixels; | |
| 1001 // Even if curremtMipData is nullptr, continue to call TexImage2
D. | |
| 1002 // This will allocate texture memory which we can later populate
. | |
| 1003 GL_ALLOC_CALL(&interface, | |
| 1004 TexImage2D(target, | |
| 1005 currentMipLevel, | |
| 1006 internalFormat, | |
| 1007 currentWidth, | |
| 1008 currentHeight, | |
| 1009 0, // border | |
| 1010 externalFormat, externalType, | |
| 1011 currentMipData)); | |
| 1012 GrGLenum error = check_alloc_error(desc, &interface); | |
| 1013 if (error != GR_GL_NO_ERROR) { | |
| 1014 return false; | |
| 1015 } | |
| 1016 } | 1003 } |
| 1017 } | 1004 } |
| 1018 } | 1005 } |
| 1019 return true; | |
| 1020 } | 1006 } |
| 1021 | 1007 |
| 1022 /** | 1008 /** |
| 1023 * Creates storage space for the texture and fills it with texels. | 1009 * Creates storage space for the texture and fills it with texels. |
| 1024 * | 1010 * |
| 1025 * @param desc The surface descriptor for the texture being created. | 1011 * @param desc The surface descriptor for the texture being created. |
| 1026 * @param interface The GL interface in use. | 1012 * @param interface The GL interface in use. |
| 1027 * @param caps The capabilities of the GL device. | 1013 * @param caps The capabilities of the GL device. |
| 1028 * @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. |
| 1029 * @param texels The texel data of the texture being created. | 1015 * @param texels The texel data of the texture being created. |
| (...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1143 | 1129 |
| 1144 // texels is const. | 1130 // texels is const. |
| 1145 // But we may need to flip the texture vertically to prepare it. | 1131 // But we may need to flip the texture vertically to prepare it. |
| 1146 // Rather than flip in place and alter the incoming data, | 1132 // Rather than flip in place and alter the incoming data, |
| 1147 // we allocate a new buffer to flip into. | 1133 // we allocate a new buffer to flip into. |
| 1148 // This means we need to make a non-const shallow copy of texels. | 1134 // This means we need to make a non-const shallow copy of texels. |
| 1149 SkTArray<GrMipLevel> texelsShallowCopy(texels); | 1135 SkTArray<GrMipLevel> texelsShallowCopy(texels); |
| 1150 | 1136 |
| 1151 for (int currentMipLevel = texelsShallowCopy.count() - 1; currentMipLevel >=
0; | 1137 for (int currentMipLevel = texelsShallowCopy.count() - 1; currentMipLevel >=
0; |
| 1152 currentMipLevel--) { | 1138 currentMipLevel--) { |
| 1153 SkASSERT(texelsShallowCopy[currentMipLevel].fPixels || kTransfer_UploadT
ype == uploadType); | 1139 SkASSERT(texelsShallowCopy[currentMipLevel].fPixels || |
| 1140 kNewTexture_UploadType == uploadType || kTransfer_UploadType ==
uploadType); |
| 1154 } | 1141 } |
| 1155 | 1142 |
| 1156 const GrGLInterface* interface = this->glInterface(); | 1143 const GrGLInterface* interface = this->glInterface(); |
| 1157 const GrGLCaps& caps = this->glCaps(); | 1144 const GrGLCaps& caps = this->glCaps(); |
| 1158 | 1145 |
| 1159 size_t bpp = GrBytesPerPixel(dataConfig); | 1146 size_t bpp = GrBytesPerPixel(dataConfig); |
| 1160 | 1147 |
| 1161 if (width == 0 || height == 0) { | 1148 if (width == 0 || height == 0) { |
| 1162 return false; | 1149 return false; |
| 1163 } | 1150 } |
| 1164 | 1151 |
| 1165 for (int currentMipLevel = 0; currentMipLevel < texelsShallowCopy.count(); c
urrentMipLevel++) { | 1152 for (int currentMipLevel = 0; currentMipLevel < texelsShallowCopy.count(); c
urrentMipLevel++) { |
| 1166 int twoToTheMipLevel = 1 << currentMipLevel; | 1153 int twoToTheMipLevel = 1 << currentMipLevel; |
| 1167 int currentWidth = SkTMax(1, width / twoToTheMipLevel); | 1154 int currentWidth = SkTMax(1, width / twoToTheMipLevel); |
| 1168 int currentHeight = SkTMax(1, height / twoToTheMipLevel); | 1155 int currentHeight = SkTMax(1, height / twoToTheMipLevel); |
| 1169 | 1156 |
| 1157 if (texelsShallowCopy[currentMipLevel].fPixels == nullptr) { |
| 1158 continue; |
| 1159 } |
| 1160 |
| 1170 if (currentHeight > SK_MaxS32 || | 1161 if (currentHeight > SK_MaxS32 || |
| 1171 currentWidth > SK_MaxS32) { | 1162 currentWidth > SK_MaxS32) { |
| 1172 return false; | 1163 return false; |
| 1173 } | 1164 } |
| 1174 if (!GrSurfacePriv::AdjustWritePixelParams(desc.fWidth, desc.fHeight, bp
p, &left, &top, | 1165 if (!GrSurfacePriv::AdjustWritePixelParams(desc.fWidth, desc.fHeight, bp
p, &left, &top, |
| 1175 ¤tWidth, | 1166 ¤tWidth, |
| 1176 ¤tHeight, | 1167 ¤tHeight, |
| 1177 &texelsShallowCopy[currentMipLeve
l].fPixels, | 1168 &texelsShallowCopy[currentMipLeve
l].fPixels, |
| 1178 &texelsShallowCopy[currentMipLeve
l].fRowBytes)) { | 1169 &texelsShallowCopy[currentMipLeve
l].fRowBytes)) { |
| 1179 return false; | 1170 return false; |
| (...skipping 15 matching lines...) Expand all Loading... |
| 1195 /* | 1186 /* |
| 1196 * Check whether to allocate a temporary buffer for flipping y or | 1187 * Check whether to allocate a temporary buffer for flipping y or |
| 1197 * because our srcData has extra bytes past each row. If so, we need | 1188 * because our srcData has extra bytes past each row. If so, we need |
| 1198 * to trim those off here, since GL ES may not let us specify | 1189 * to trim those off here, since GL ES may not let us specify |
| 1199 * GL_UNPACK_ROW_LENGTH. | 1190 * GL_UNPACK_ROW_LENGTH. |
| 1200 */ | 1191 */ |
| 1201 bool restoreGLRowLength = false; | 1192 bool restoreGLRowLength = false; |
| 1202 bool swFlipY = false; | 1193 bool swFlipY = false; |
| 1203 bool glFlipY = false; | 1194 bool glFlipY = false; |
| 1204 | 1195 |
| 1205 if (kBottomLeft_GrSurfaceOrigin == desc.fOrigin && !texelsShallowCopy.empty(
)) { | 1196 if (kBottomLeft_GrSurfaceOrigin == desc.fOrigin) { |
| 1206 if (caps.unpackFlipYSupport()) { | 1197 if (caps.unpackFlipYSupport()) { |
| 1207 glFlipY = true; | 1198 glFlipY = true; |
| 1208 } else { | 1199 } else { |
| 1209 swFlipY = true; | 1200 swFlipY = true; |
| 1210 } | 1201 } |
| 1211 } | 1202 } |
| 1212 | 1203 |
| 1213 // in case we need a temporary, trimmed copy of the src pixels | 1204 // in case we need a temporary, trimmed copy of the src pixels |
| 1214 SkAutoSMalloc<128 * 128> tempStorage; | 1205 SkAutoSMalloc<128 * 128> tempStorage; |
| 1215 | 1206 |
| 1216 // find the combined size of all the mip levels and the relative offset of | 1207 // find the combined size of all the mip levels and the relative offset of |
| 1217 // each into the collective buffer | 1208 // each into the collective buffer |
| 1218 size_t combined_buffer_size = 0; | 1209 size_t combined_buffer_size = 0; |
| 1219 SkTArray<size_t> individual_mip_offsets(texelsShallowCopy.count()); | 1210 SkTArray<size_t> individual_mip_offsets(texelsShallowCopy.count()); |
| 1220 for (int currentMipLevel = 0; currentMipLevel < texelsShallowCopy.count(); c
urrentMipLevel++) { | 1211 for (int currentMipLevel = 0; currentMipLevel < texelsShallowCopy.count(); c
urrentMipLevel++) { |
| 1221 int twoToTheMipLevel = 1 << currentMipLevel; | 1212 int twoToTheMipLevel = 1 << currentMipLevel; |
| 1222 int currentWidth = SkTMax(1, width / twoToTheMipLevel); | 1213 int currentWidth = SkTMax(1, width / twoToTheMipLevel); |
| 1223 int currentHeight = SkTMax(1, height / twoToTheMipLevel); | 1214 int currentHeight = SkTMax(1, height / twoToTheMipLevel); |
| 1224 const size_t trimmedSize = currentWidth * bpp * currentHeight; | 1215 const size_t trimmedSize = currentWidth * bpp * currentHeight; |
| 1225 individual_mip_offsets.push_back(combined_buffer_size); | 1216 individual_mip_offsets.push_back(combined_buffer_size); |
| 1226 combined_buffer_size += trimmedSize; | 1217 combined_buffer_size += trimmedSize; |
| 1227 } | 1218 } |
| 1228 char* buffer = (char*)tempStorage.reset(combined_buffer_size); | 1219 char* buffer = (char*)tempStorage.reset(combined_buffer_size); |
| 1229 | 1220 |
| 1230 for (int currentMipLevel = 0; currentMipLevel < texelsShallowCopy.count(); c
urrentMipLevel++) { | 1221 for (int currentMipLevel = 0; currentMipLevel < texelsShallowCopy.count(); c
urrentMipLevel++) { |
| 1222 if (texelsShallowCopy[currentMipLevel].fPixels == nullptr) { |
| 1223 continue; |
| 1224 } |
| 1225 |
| 1231 int twoToTheMipLevel = 1 << currentMipLevel; | 1226 int twoToTheMipLevel = 1 << currentMipLevel; |
| 1232 int currentWidth = SkTMax(1, width / twoToTheMipLevel); | 1227 int currentWidth = SkTMax(1, width / twoToTheMipLevel); |
| 1233 int currentHeight = SkTMax(1, height / twoToTheMipLevel); | 1228 int currentHeight = SkTMax(1, height / twoToTheMipLevel); |
| 1234 const size_t trimRowBytes = currentWidth * bpp; | 1229 const size_t trimRowBytes = currentWidth * bpp; |
| 1235 | 1230 |
| 1236 /* | 1231 /* |
| 1237 * check whether to allocate a temporary buffer for flipping y or | 1232 * check whether to allocate a temporary buffer for flipping y or |
| 1238 * because our srcData has extra bytes past each row. If so, we need | 1233 * because our srcData has extra bytes past each row. If so, we need |
| 1239 * to trim those off here, since GL ES may not let us specify | 1234 * to trim those off here, since GL ES may not let us specify |
| 1240 * GL_UNPACK_ROW_LENGTH. | 1235 * GL_UNPACK_ROW_LENGTH. |
| (...skipping 26 matching lines...) Expand all Loading... |
| 1267 dst += trimRowBytes; | 1262 dst += trimRowBytes; |
| 1268 } | 1263 } |
| 1269 // now point data to our copied version | 1264 // now point data to our copied version |
| 1270 texelsShallowCopy[currentMipLevel].fPixels = buffer + | 1265 texelsShallowCopy[currentMipLevel].fPixels = buffer + |
| 1271 individual_mip_offsets[currentMipLevel]; | 1266 individual_mip_offsets[currentMipLevel]; |
| 1272 texelsShallowCopy[currentMipLevel].fRowBytes = trimRowBytes; | 1267 texelsShallowCopy[currentMipLevel].fRowBytes = trimRowBytes; |
| 1273 } | 1268 } |
| 1274 } else { | 1269 } else { |
| 1275 return false; | 1270 return false; |
| 1276 } | 1271 } |
| 1277 } | |
| 1278 | |
| 1279 if (!texelsShallowCopy.empty()) { | |
| 1280 if (glFlipY) { | 1272 if (glFlipY) { |
| 1281 GR_GL_CALL(interface, PixelStorei(GR_GL_UNPACK_FLIP_Y, GR_GL_TRUE)); | 1273 GR_GL_CALL(interface, PixelStorei(GR_GL_UNPACK_FLIP_Y, GR_GL_TRUE)); |
| 1282 } | 1274 } |
| 1283 GR_GL_CALL(interface, PixelStorei(GR_GL_UNPACK_ALIGNMENT, | 1275 GR_GL_CALL(interface, PixelStorei(GR_GL_UNPACK_ALIGNMENT, |
| 1284 config_alignment(desc.fConfig))); | 1276 config_alignment(desc.fConfig))); |
| 1285 } | 1277 } |
| 1286 | 1278 |
| 1287 bool succeeded = true; | 1279 bool succeeded = true; |
| 1288 if (kNewTexture_UploadType == uploadType && | 1280 if (kNewTexture_UploadType == uploadType && |
| 1289 0 == left && 0 == top && | 1281 0 == left && 0 == top && |
| 1290 desc.fWidth == width && desc.fHeight == height && | 1282 desc.fWidth == width && desc.fHeight == height && |
| 1291 !desc.fTextureStorageAllocator.fAllocateTextureStorage) { | 1283 !desc.fTextureStorageAllocator.fAllocateTextureStorage) { |
| 1292 succeeded = allocate_and_populate_uncompressed_texture(desc, *interface,
caps, target, | 1284 allocate_and_populate_uncompressed_texture(desc, *interface, caps, targe
t, |
| 1293 internalFormat, e
xternalFormat, | 1285 internalFormat, externalForma
t, |
| 1294 externalType, tex
elsShallowCopy, | 1286 externalType, texelsShallowCo
py, |
| 1295 width, height); | 1287 width, height, &succeeded); |
| 1296 } else { | 1288 } else { |
| 1297 if (swFlipY || glFlipY) { | 1289 if (swFlipY || glFlipY) { |
| 1298 top = desc.fHeight - (top + height); | 1290 top = desc.fHeight - (top + height); |
| 1299 } | 1291 } |
| 1300 for (int currentMipLevel = 0; currentMipLevel < texelsShallowCopy.count(
); | 1292 for (int currentMipLevel = 0; currentMipLevel < texelsShallowCopy.count(
); |
| 1301 currentMipLevel++) { | 1293 currentMipLevel++) { |
| 1302 int twoToTheMipLevel = 1 << currentMipLevel; | 1294 int twoToTheMipLevel = 1 << currentMipLevel; |
| 1303 int currentWidth = SkTMax(1, width / twoToTheMipLevel); | 1295 int currentWidth = SkTMax(1, width / twoToTheMipLevel); |
| 1304 int currentHeight = SkTMax(1, height / twoToTheMipLevel); | 1296 int currentHeight = SkTMax(1, height / twoToTheMipLevel); |
| 1297 if (texelsShallowCopy[currentMipLevel].fPixels == nullptr) { |
| 1298 continue; |
| 1299 } |
| 1305 | 1300 |
| 1306 GL_CALL(TexSubImage2D(target, | 1301 GL_CALL(TexSubImage2D(target, |
| 1307 currentMipLevel, | 1302 currentMipLevel, |
| 1308 left, top, | 1303 left, top, |
| 1309 currentWidth, | 1304 currentWidth, |
| 1310 currentHeight, | 1305 currentHeight, |
| 1311 externalFormat, externalType, | 1306 externalFormat, externalType, |
| 1312 texelsShallowCopy[currentMipLevel].fPixels)); | 1307 texelsShallowCopy[currentMipLevel].fPixels)); |
| 1313 } | 1308 } |
| 1314 } | 1309 } |
| 1315 | 1310 |
| 1316 restore_pixelstore_state(*interface, caps, restoreGLRowLength, glFlipY); | 1311 restore_pixelstore_state(*interface, caps, restoreGLRowLength, glFlipY); |
| 1317 | 1312 |
| 1318 return succeeded; | 1313 return succeeded; |
| 1319 } | 1314 } |
| 1320 | 1315 |
| 1321 // TODO: This function is using a lot of wonky semantics like, if width == -1 | 1316 // TODO: This function is using a lot of wonky semantics like, if width == -1 |
| 1322 // then set width = desc.fWdith ... blah. A better way to do it might be to | 1317 // then set width = desc.fWdith ... blah. A better way to do it might be to |
| 1323 // create a CompressedTexData struct that takes a desc/ptr and figures out | 1318 // create a CompressedTexData struct that takes a desc/ptr and figures out |
| 1324 // the proper upload semantics. Then users can construct this function how they | 1319 // the proper upload semantics. Then users can construct this function how they |
| 1325 // see fit if they want to go against the "standard" way to do it. | 1320 // see fit if they want to go against the "standard" way to do it. |
| 1326 bool GrGLGpu::uploadCompressedTexData(const GrSurfaceDesc& desc, | 1321 bool GrGLGpu::uploadCompressedTexData(const GrSurfaceDesc& desc, |
| 1327 GrGLenum target, | 1322 GrGLenum target, |
| 1328 const SkTArray<GrMipLevel>& texels, | 1323 const SkTArray<GrMipLevel>& texels, |
| 1329 UploadType uploadType, | 1324 UploadType uploadType, |
| 1330 int left, int top, int width, int height)
{ | 1325 int left, int top, int width, int height)
{ |
| 1331 SkASSERT(this->caps()->isConfigTexturable(desc.fConfig)); | 1326 SkASSERT(this->caps()->isConfigTexturable(desc.fConfig)); |
| 1327 SkASSERT(kTransfer_UploadType != uploadType && |
| 1328 (texels[0].fPixels || kNewTexture_UploadType != uploadType)); |
| 1332 | 1329 |
| 1333 // No support for software flip y, yet... | 1330 // No support for software flip y, yet... |
| 1334 SkASSERT(kBottomLeft_GrSurfaceOrigin != desc.fOrigin); | 1331 SkASSERT(kBottomLeft_GrSurfaceOrigin != desc.fOrigin); |
| 1335 | 1332 |
| 1336 const GrGLInterface* interface = this->glInterface(); | 1333 const GrGLInterface* interface = this->glInterface(); |
| 1337 const GrGLCaps& caps = this->glCaps(); | 1334 const GrGLCaps& caps = this->glCaps(); |
| 1338 | 1335 |
| 1339 if (-1 == width) { | 1336 if (-1 == width) { |
| 1340 width = desc.fWidth; | 1337 width = desc.fWidth; |
| 1341 } | 1338 } |
| (...skipping 20 matching lines...) Expand all Loading... |
| 1362 | 1359 |
| 1363 if (kNewTexture_UploadType == uploadType) { | 1360 if (kNewTexture_UploadType == uploadType) { |
| 1364 return allocate_and_populate_compressed_texture(desc, *interface, caps,
target, | 1361 return allocate_and_populate_compressed_texture(desc, *interface, caps,
target, |
| 1365 internalFormat, texels,
width, height); | 1362 internalFormat, texels,
width, height); |
| 1366 } else { | 1363 } else { |
| 1367 // Paletted textures can't be updated. | 1364 // Paletted textures can't be updated. |
| 1368 if (GR_GL_PALETTE8_RGBA8 == internalFormat) { | 1365 if (GR_GL_PALETTE8_RGBA8 == internalFormat) { |
| 1369 return false; | 1366 return false; |
| 1370 } | 1367 } |
| 1371 for (int currentMipLevel = 0; currentMipLevel < texels.count(); currentM
ipLevel++) { | 1368 for (int currentMipLevel = 0; currentMipLevel < texels.count(); currentM
ipLevel++) { |
| 1372 SkASSERT(texels[currentMipLevel].fPixels || kTransfer_UploadType ==
uploadType); | 1369 if (texels[currentMipLevel].fPixels == nullptr) { |
| 1370 continue; |
| 1371 } |
| 1373 | 1372 |
| 1374 int twoToTheMipLevel = 1 << currentMipLevel; | 1373 int twoToTheMipLevel = 1 << currentMipLevel; |
| 1375 int currentWidth = SkTMax(1, width / twoToTheMipLevel); | 1374 int currentWidth = SkTMax(1, width / twoToTheMipLevel); |
| 1376 int currentHeight = SkTMax(1, height / twoToTheMipLevel); | 1375 int currentHeight = SkTMax(1, height / twoToTheMipLevel); |
| 1377 | 1376 |
| 1378 // Make sure that the width and height that we pass to OpenGL | 1377 // Make sure that the width and height that we pass to OpenGL |
| 1379 // is a multiple of the block size. | 1378 // is a multiple of the block size. |
| 1380 size_t dataSize = GrCompressedFormatDataSize(desc.fConfig, currentWi
dth, | 1379 size_t dataSize = GrCompressedFormatDataSize(desc.fConfig, currentWi
dth, |
| 1381 currentHeight); | 1380 currentHeight); |
| 1382 GL_CALL(CompressedTexSubImage2D(target, | 1381 GL_CALL(CompressedTexSubImage2D(target, |
| (...skipping 458 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1841 } | 1840 } |
| 1842 return true; | 1841 return true; |
| 1843 } | 1842 } |
| 1844 | 1843 |
| 1845 bool GrGLGpu::createTextureExternalAllocatorImpl(const GrSurfaceDesc& desc, | 1844 bool GrGLGpu::createTextureExternalAllocatorImpl(const GrSurfaceDesc& desc, |
| 1846 GrGLTextureInfo* info, | 1845 GrGLTextureInfo* info, |
| 1847 const SkTArray<GrMipLevel>& tex
els) { | 1846 const SkTArray<GrMipLevel>& tex
els) { |
| 1848 // We do not make SkTArray available outside of Skia, | 1847 // We do not make SkTArray available outside of Skia, |
| 1849 // and so we do not want to allow mipmaps to external | 1848 // and so we do not want to allow mipmaps to external |
| 1850 // allocators just yet. | 1849 // allocators just yet. |
| 1851 SkASSERT(texels.count() < 2); | 1850 SkASSERT(texels.count() == 1); |
| 1851 SkSTArray<1, GrMipLevel> texelsShallowCopy(1); |
| 1852 texelsShallowCopy.push_back(texels[0]); |
| 1852 | 1853 |
| 1853 const void* pixels = nullptr; | |
| 1854 if (!texels.empty()) { | |
| 1855 pixels = texels.begin()->fPixels; | |
| 1856 } | |
| 1857 switch (desc.fTextureStorageAllocator.fAllocateTextureStorage( | 1854 switch (desc.fTextureStorageAllocator.fAllocateTextureStorage( |
| 1858 desc.fTextureStorageAllocator.fCtx, reinterpret_cast<GrBacke
ndObject>(info), | 1855 desc.fTextureStorageAllocator.fCtx, reinterpret_cast<GrBacke
ndObject>(info), |
| 1859 desc.fWidth, desc.fHeight, desc.fConfig, pixels, desc.fOrigi
n)) { | 1856 desc.fWidth, desc.fHeight, desc.fConfig, texelsShallowCopy[0
].fPixels, |
| 1857 desc.fOrigin)) { |
| 1860 case GrTextureStorageAllocator::Result::kSucceededAndUploaded: | 1858 case GrTextureStorageAllocator::Result::kSucceededAndUploaded: |
| 1861 return true; | 1859 return true; |
| 1862 case GrTextureStorageAllocator::Result::kFailed: | 1860 case GrTextureStorageAllocator::Result::kFailed: |
| 1863 return false; | 1861 return false; |
| 1864 case GrTextureStorageAllocator::Result::kSucceededWithoutUpload: | 1862 case GrTextureStorageAllocator::Result::kSucceededWithoutUpload: |
| 1865 break; | 1863 break; |
| 1866 } | 1864 } |
| 1867 | 1865 |
| 1868 if (!this->uploadTexData(desc, info->fTarget, kNewTexture_UploadType, 0, 0, | 1866 if (!this->uploadTexData(desc, info->fTarget, kNewTexture_UploadType, 0, 0, |
| 1869 desc.fWidth, desc.fHeight, | 1867 desc.fWidth, desc.fHeight, |
| 1870 desc.fConfig, texels)) { | 1868 desc.fConfig, texelsShallowCopy)) { |
| 1871 desc.fTextureStorageAllocator.fDeallocateTextureStorage( | 1869 desc.fTextureStorageAllocator.fDeallocateTextureStorage( |
| 1872 desc.fTextureStorageAllocator.fCtx, reinterpret_cast<GrBackendOb
ject>(info)); | 1870 desc.fTextureStorageAllocator.fCtx, reinterpret_cast<GrBackendOb
ject>(info)); |
| 1873 return false; | 1871 return false; |
| 1874 } | 1872 } |
| 1875 return true; | 1873 return true; |
| 1876 } | 1874 } |
| 1877 | 1875 |
| 1878 GrStencilAttachment* GrGLGpu::createStencilAttachmentForRenderTarget(const GrRen
derTarget* rt, | 1876 GrStencilAttachment* GrGLGpu::createStencilAttachmentForRenderTarget(const GrRen
derTarget* rt, |
| 1879 int width, | 1877 int width, |
| 1880 int height)
{ | 1878 int height)
{ |
| (...skipping 593 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2474 GrPixelConfig rtConfig = target->config(); | 2472 GrPixelConfig rtConfig = target->config(); |
| 2475 return this->glCaps().readPixelsSupported(rtConfig, readConfig, getIntegerv,
bindRenderTarget); | 2473 return this->glCaps().readPixelsSupported(rtConfig, readConfig, getIntegerv,
bindRenderTarget); |
| 2476 } | 2474 } |
| 2477 | 2475 |
| 2478 bool GrGLGpu::readPixelsSupported(GrPixelConfig rtConfig, GrPixelConfig readConf
ig) { | 2476 bool GrGLGpu::readPixelsSupported(GrPixelConfig rtConfig, GrPixelConfig readConf
ig) { |
| 2479 auto bindRenderTarget = [this, rtConfig]() -> bool { | 2477 auto bindRenderTarget = [this, rtConfig]() -> bool { |
| 2480 GrTextureDesc desc; | 2478 GrTextureDesc desc; |
| 2481 desc.fConfig = rtConfig; | 2479 desc.fConfig = rtConfig; |
| 2482 desc.fWidth = desc.fHeight = 16; | 2480 desc.fWidth = desc.fHeight = 16; |
| 2483 desc.fFlags = kRenderTarget_GrSurfaceFlag; | 2481 desc.fFlags = kRenderTarget_GrSurfaceFlag; |
| 2484 SkAutoTUnref<GrTexture> temp(this->createTexture(desc, | 2482 SkAutoTUnref<GrTexture> temp(this->createTexture(desc, SkBudgeted::kNo,
nullptr, 0)); |
| 2485 SkBudgeted::kNo)); | |
| 2486 if (!temp) { | 2483 if (!temp) { |
| 2487 return false; | 2484 return false; |
| 2488 } | 2485 } |
| 2489 GrGLRenderTarget* glrt = static_cast<GrGLRenderTarget*>(temp->asRenderTa
rget()); | 2486 GrGLRenderTarget* glrt = static_cast<GrGLRenderTarget*>(temp->asRenderTa
rget()); |
| 2490 this->flushRenderTarget(glrt, &SkIRect::EmptyIRect()); | 2487 this->flushRenderTarget(glrt, &SkIRect::EmptyIRect()); |
| 2491 return true; | 2488 return true; |
| 2492 }; | 2489 }; |
| 2493 auto getIntegerv = [this](GrGLenum query, GrGLint* value) { | 2490 auto getIntegerv = [this](GrGLenum query, GrGLint* value) { |
| 2494 GR_GL_GetIntegerv(this->glInterface(), query, value); | 2491 GR_GL_GetIntegerv(this->glInterface(), query, value); |
| 2495 }; | 2492 }; |
| (...skipping 1817 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4313 if (GR_GL_TEXTURE_EXTERNAL == glTexture->target() || | 4310 if (GR_GL_TEXTURE_EXTERNAL == glTexture->target() || |
| 4314 GR_GL_TEXTURE_RECTANGLE == glTexture->target()) { | 4311 GR_GL_TEXTURE_RECTANGLE == glTexture->target()) { |
| 4315 copyParams->fFilter = GrTextureParams::kNone_FilterMode; | 4312 copyParams->fFilter = GrTextureParams::kNone_FilterMode; |
| 4316 copyParams->fWidth = texture->width(); | 4313 copyParams->fWidth = texture->width(); |
| 4317 copyParams->fHeight = texture->height(); | 4314 copyParams->fHeight = texture->height(); |
| 4318 return true; | 4315 return true; |
| 4319 } | 4316 } |
| 4320 } | 4317 } |
| 4321 return false; | 4318 return false; |
| 4322 } | 4319 } |
| OLD | NEW |