Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1)

Side by Side Diff: src/gpu/gl/GrGLGpu.cpp

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

Powered by Google App Engine
This is Rietveld 408576698