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

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

Issue 1570173004: This CL adds glTexStorage support. (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: Fixing rebase mistake. 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 | « no previous file | no next file » | 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 894 matching lines...) Expand 10 before | Expand all | Expand 10 after
905 static inline GrGLenum check_alloc_error(const GrSurfaceDesc& desc, 905 static inline GrGLenum check_alloc_error(const GrSurfaceDesc& desc,
906 const GrGLInterface* interface) { 906 const GrGLInterface* interface) {
907 if (SkToBool(desc.fFlags & kCheckAllocation_GrSurfaceFlag)) { 907 if (SkToBool(desc.fFlags & kCheckAllocation_GrSurfaceFlag)) {
908 return GR_GL_GET_ERROR(interface); 908 return GR_GL_GET_ERROR(interface);
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 * Determines if TexStorage can be used when creating a texture.
916 *
917 * @param caps The capabilities of the GL device.
918 * @param standard The GL standard in use.
919 * @param desc The surface descriptor for the texture being created.
920 */
921 static bool can_use_tex_storage(const GrGLCaps& caps, const GrGLStandard& standa rd,
922 const GrSurfaceDesc& desc) {
923 bool canUseTexStorage = caps.texStorageSupport();
924 if (canUseTexStorage && kGL_GrGLStandard == standard) {
925 // 565 is not a sized internal format on desktop GL. So on desktop with
bsalomon 2016/02/26 22:09:54 We now are making most decisions about configs in
cblume 2016/02/27 00:49:54 Done.
926 // 565 we always use an unsized internal format to let the system pick
927 // the best sized format to convert the 565 data to. Since TexStorage
928 // only allows sized internal formats we will instead use TexImage2D.
929 canUseTexStorage = desc.fConfig != kRGB_565_GrPixelConfig;
930 }
931
932 return canUseTexStorage;
933 }
934
935 /**
915 * Creates storage space for the texture and fills it with texels. 936 * Creates storage space for the texture and fills it with texels.
916 * 937 *
917 * @param desc The surface descriptor for the texture being created. 938 * @param desc The surface descriptor for the texture being created.
918 * @param interface The GL interface in use. 939 * @param interface The GL interface in use.
919 * @param target The GL target to which the texture is bound 940 * @param useTexStorage The result of a call to can_use_tex_storage().
920 * @param internalFormat The data format used for the internal storage of the te xture. 941 * @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. 942 * @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. 943 * @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. 944 * @param texels The texel data of the texture being created.
924 * @param baseWidth The width of the texture's base mipmap level 945 * @param baseWidth The width of the texture's base mipmap level
925 * @param baseHeight The height of the texture's base mipmap level 946 * @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 947 * @param succeeded Set to true if allocating and populating the texture co mpleted
927 * without error. 948 * without error.
928 */ 949 */
929 static void allocate_and_populate_uncompressed_texture(const GrSurfaceDesc& desc , 950 static void allocate_and_populate_uncompressed_texture(const GrSurfaceDesc& desc ,
930 const GrGLInterface& inte rface, 951 const GrGLInterface& inte rface,
952 bool useTexStorage,
931 GrGLenum target, 953 GrGLenum target,
932 GrGLenum internalFormat, 954 GrGLenum internalFormat,
933 GrGLenum externalFormat, 955 GrGLenum externalFormat,
934 GrGLenum externalType, 956 GrGLenum externalType,
935 const SkTArray<GrMipLevel >& texels, 957 const SkTArray<GrMipLevel >& texels,
936 int baseWidth, int baseHe ight, 958 int baseWidth, int baseHe ight,
937 bool* succeeded) { 959 bool* succeeded) {
938 CLEAR_ERROR_BEFORE_ALLOC(&interface); 960 CLEAR_ERROR_BEFORE_ALLOC(&interface);
939 *succeeded = true; 961 if (useTexStorage) {
940 for (int currentMipLevel = 0; currentMipLevel < texels.count(); currentMipLe vel++) { 962 // We never resize or change formats of textures.
941 int twoToTheMipLevel = 1 << currentMipLevel;
942 int currentWidth = SkTMax(1, baseWidth / twoToTheMipLevel);
943 int currentHeight = SkTMax(1, baseHeight / twoToTheMipLevel);
944 const void* currentMipData = texels[currentMipLevel].fPixels;
945 // Even if curremtMipData is nullptr, continue to call TexImage2D.
946 // This will allocate texture memory which we can later populate.
947 GL_ALLOC_CALL(&interface, 963 GL_ALLOC_CALL(&interface,
948 TexImage2D(target, 964 TexStorage2D(target,
bsalomon 2016/02/26 22:09:54 Won't this cause a problem if we later call glGene
cblume 2016/02/27 00:49:54 The calling sites currently only have useTexStorag
949 currentMipLevel, 965 texels.count(),
950 internalFormat, 966 internalFormat,
951 currentWidth, 967 desc.fWidth, desc.fHeight));
952 currentHeight,
953 0, // border
954 externalFormat, externalType,
955 currentMipData));
956 GrGLenum error = check_alloc_error(desc, &interface); 968 GrGLenum error = check_alloc_error(desc, &interface);
957 if (error != GR_GL_NO_ERROR) { 969 if (error != GR_GL_NO_ERROR) {
958 *succeeded = false; 970 *succeeded = false;
959 break; 971 } else {
972 for (int currentMipLevel = 0; currentMipLevel < texels.count(); curr entMipLevel++) {
973 const void* currentMipData = texels[currentMipLevel].fPixels;
974 if (currentMipData == nullptr) {
975 continue;
976 }
977 int twoToTheMipLevel = 1 << currentMipLevel;
978 int currentWidth = SkTMax(1, desc.fWidth / twoToTheMipLevel);
979 int currentHeight = SkTMax(1, desc.fHeight / twoToTheMipLevel);
980
981 GR_GL_CALL(&interface,
982 TexSubImage2D(target,
983 currentMipLevel,
984 0, // left
985 0, // top
986 currentWidth,
987 currentHeight,
988 externalFormat, externalType,
989 currentMipData));
990 }
991 *succeeded = true;
992 }
993 } else {
994 *succeeded = true;
995 for (int currentMipLevel = 0; currentMipLevel < texels.count(); currentM ipLevel++) {
996 int twoToTheMipLevel = 1 << currentMipLevel;
997 int currentWidth = SkTMax(1, baseWidth / twoToTheMipLevel);
998 int currentHeight = SkTMax(1, baseHeight / twoToTheMipLevel);
999 const void* currentMipData = texels[currentMipLevel].fPixels;
1000 // Even if curremtMipData is nullptr, continue to call TexImage2D.
1001 // This will allocate texture memory which we can later populate.
1002 GL_ALLOC_CALL(&interface,
1003 TexImage2D(target,
1004 currentMipLevel,
1005 internalFormat,
1006 currentWidth,
1007 currentHeight,
1008 0, // border
1009 externalFormat, externalType,
1010 currentMipData));
1011 GrGLenum error = check_alloc_error(desc, &interface);
1012 if (error != GR_GL_NO_ERROR) {
1013 *succeeded = false;
1014 break;
1015 }
960 } 1016 }
961 } 1017 }
962 } 1018 }
963 1019
964 /** 1020 /**
965 * Creates storage space for the texture and fills it with texels. 1021 * Creates storage space for the texture and fills it with texels.
966 * 1022 *
967 * @param desc The surface descriptor for the texture being created. 1023 * @param desc The surface descriptor for the texture being created.
968 * @param interface The GL interface in use. 1024 * @param interface The GL interface in use.
969 * @param target The GL target to which the texture is bound 1025 * @param useTexStorage The result of a call to can_use_tex_storage().
970 * @param internalFormat The data format used for the internal storage of the te xture. 1026 * @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. 1027 * @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 */ 1028 */
975 static bool allocate_and_populate_compressed_texture(const GrSurfaceDesc& desc, 1029 static bool allocate_and_populate_compressed_texture(const GrSurfaceDesc& desc,
976 const GrGLInterface& interf ace, 1030 const GrGLInterface& interf ace,
1031 bool useTexStorage,
977 GrGLenum target, GrGLenum i nternalFormat, 1032 GrGLenum target, GrGLenum i nternalFormat,
978 const SkTArray<GrMipLevel>& texels, 1033 const SkTArray<GrMipLevel>& texels,
979 int baseWidth, int baseHeig ht) { 1034 int baseWidth, int baseHeig ht) {
980 CLEAR_ERROR_BEFORE_ALLOC(&interface); 1035 CLEAR_ERROR_BEFORE_ALLOC(&interface);
981 for (int currentMipLevel = 0; currentMipLevel < texels.count(); currentMipLe vel++) { 1036 if (useTexStorage) {
982 int twoToTheMipLevel = 1 << currentMipLevel; 1037 // We never resize or change formats of textures.
983 int currentWidth = SkTMax(1, baseWidth / twoToTheMipLevel);
984 int currentHeight = SkTMax(1, baseHeight / twoToTheMipLevel);
985
986 // Make sure that the width and height that we pass to OpenGL
987 // is a multiple of the block size.
988 size_t dataSize = GrCompressedFormatDataSize(desc.fConfig, baseWidth, ba seHeight);
989
990 GL_ALLOC_CALL(&interface, 1038 GL_ALLOC_CALL(&interface,
991 CompressedTexImage2D(target, 1039 TexStorage2D(target,
992 currentMipLevel, 1040 texels.count(),
993 internalFormat, 1041 internalFormat,
994 currentWidth, 1042 baseWidth, baseHeight));
995 currentHeight,
996 0, // border
997 SkToInt(dataSize),
998 texels[currentMipLevel].fPixels));
999
1000 GrGLenum error = check_alloc_error(desc, &interface); 1043 GrGLenum error = check_alloc_error(desc, &interface);
1001 if (error != GR_GL_NO_ERROR) { 1044 if (error != GR_GL_NO_ERROR) {
1002 return false; 1045 return false;
1046 } else {
1047 for (int currentMipLevel = 0; currentMipLevel < texels.count(); curr entMipLevel++) {
1048 const void* currentMipData = texels[currentMipLevel].fPixels;
1049 if (currentMipData == nullptr) {
1050 continue;
1051 }
1052
1053 int twoToTheMipLevel = 1 << currentMipLevel;
1054 int currentWidth = SkTMax(1, baseWidth / twoToTheMipLevel);
1055 int currentHeight = SkTMax(1, baseHeight / twoToTheMipLevel);
1056
1057 // Make sure that the width and height that we pass to OpenGL
1058 // is a multiple of the block size.
1059 size_t dataSize = GrCompressedFormatDataSize(desc.fConfig, curre ntWidth,
1060 currentHeight);
1061 GR_GL_CALL(&interface, CompressedTexSubImage2D(target,
1062 currentMipLevel,
1063 0, // left
1064 0, // top
1065 currentWidth,
1066 currentHeight,
1067 internalFormat,
1068 SkToInt(dataSize) ,
1069 currentMipData));
1070 }
1071 }
1072 } else {
1073 for (int currentMipLevel = 0; currentMipLevel < texels.count(); currentM ipLevel++) {
1074 int twoToTheMipLevel = 1 << currentMipLevel;
1075 int currentWidth = SkTMax(1, baseWidth / twoToTheMipLevel);
1076 int currentHeight = SkTMax(1, baseHeight / twoToTheMipLevel);
1077
1078 // Make sure that the width and height that we pass to OpenGL
1079 // is a multiple of the block size.
1080 size_t dataSize = GrCompressedFormatDataSize(desc.fConfig, baseWidth , baseHeight);
1081
1082 GL_ALLOC_CALL(&interface,
1083 CompressedTexImage2D(target,
1084 currentMipLevel,
1085 internalFormat,
1086 currentWidth,
1087 currentHeight,
1088 0, // border
1089 SkToInt(dataSize),
1090 texels[currentMipLevel].fPixels)) ;
1091
1092 GrGLenum error = check_alloc_error(desc, &interface);
1093 if (error != GR_GL_NO_ERROR) {
1094 return false;
1095 }
1003 } 1096 }
1004 } 1097 }
1005 1098
1006 return true; 1099 return true;
1007 } 1100 }
1008 1101
1009 /** 1102 /**
1010 * After a texture is created, any state which was altered during its creation 1103 * After a texture is created, any state which was altered during its creation
1011 * needs to be restored. 1104 * needs to be restored.
1012 * 1105 *
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
1045 SkTArray<GrMipLevel> texelsShallowCopy(texels); 1138 SkTArray<GrMipLevel> texelsShallowCopy(texels);
1046 1139
1047 for (int currentMipLevel = texelsShallowCopy.count() - 1; currentMipLevel >= 0; 1140 for (int currentMipLevel = texelsShallowCopy.count() - 1; currentMipLevel >= 0;
1048 currentMipLevel--) { 1141 currentMipLevel--) {
1049 SkASSERT(texelsShallowCopy[currentMipLevel].fPixels || 1142 SkASSERT(texelsShallowCopy[currentMipLevel].fPixels ||
1050 kNewTexture_UploadType == uploadType || kTransfer_UploadType == uploadType); 1143 kNewTexture_UploadType == uploadType || kTransfer_UploadType == uploadType);
1051 } 1144 }
1052 1145
1053 const GrGLInterface* interface = this->glInterface(); 1146 const GrGLInterface* interface = this->glInterface();
1054 const GrGLCaps& caps = this->glCaps(); 1147 const GrGLCaps& caps = this->glCaps();
1148 GrGLStandard standard = this->glStandard();
1055 1149
1056 size_t bpp = GrBytesPerPixel(dataConfig); 1150 size_t bpp = GrBytesPerPixel(dataConfig);
1057 1151
1058 if (width == 0 || height == 0) { 1152 if (width == 0 || height == 0) {
1059 return false; 1153 return false;
1060 } 1154 }
1061 1155
1062 for (int currentMipLevel = 0; currentMipLevel < texelsShallowCopy.count(); c urrentMipLevel++) { 1156 for (int currentMipLevel = 0; currentMipLevel < texelsShallowCopy.count(); c urrentMipLevel++) {
1063 int twoToTheMipLevel = 1 << currentMipLevel; 1157 int twoToTheMipLevel = 1 << currentMipLevel;
1064 int currentWidth = SkTMax(1, width / twoToTheMipLevel); 1158 int currentWidth = SkTMax(1, width / twoToTheMipLevel);
(...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after
1184 } 1278 }
1185 GR_GL_CALL(interface, PixelStorei(GR_GL_UNPACK_ALIGNMENT, 1279 GR_GL_CALL(interface, PixelStorei(GR_GL_UNPACK_ALIGNMENT,
1186 config_alignment(desc.fConfig))); 1280 config_alignment(desc.fConfig)));
1187 } 1281 }
1188 1282
1189 bool succeeded = true; 1283 bool succeeded = true;
1190 if (kNewTexture_UploadType == uploadType && 1284 if (kNewTexture_UploadType == uploadType &&
1191 0 == left && 0 == top && 1285 0 == left && 0 == top &&
1192 desc.fWidth == width && desc.fHeight == height && 1286 desc.fWidth == width && desc.fHeight == height &&
1193 !desc.fTextureStorageAllocator.fAllocateTextureStorage) { 1287 !desc.fTextureStorageAllocator.fAllocateTextureStorage) {
1194 allocate_and_populate_uncompressed_texture(desc, *interface, target, 1288 bool useTexStorage = can_use_tex_storage(caps, standard, desc);
1289 // We can only use TexStorage if we know we will not later change the st orage requirements.
1290 // This means if we may later want to generate mipmaps, we cannot use Te xStorage.
1291 // Right now, we cannot know if we will later generate mipmaps or not.
1292 // The only time we can use TexStorage is when we already have the
1293 // mipmaps.
1294 useTexStorage &= texelsShallowCopy.count() > 1;
1295 allocate_and_populate_uncompressed_texture(desc, *interface, useTexStora ge, target,
1195 internalFormat, externalForma t, 1296 internalFormat, externalForma t,
1196 externalType, texelsShallowCo py, 1297 externalType, texelsShallowCo py,
1197 width, height, &succeeded); 1298 width, height, &succeeded);
1198 } else { 1299 } else {
1199 if (swFlipY || glFlipY) { 1300 if (swFlipY || glFlipY) {
1200 top = desc.fHeight - (top + height); 1301 top = desc.fHeight - (top + height);
1201 } 1302 }
1202 for (int currentMipLevel = 0; currentMipLevel < texelsShallowCopy.count( ); 1303 for (int currentMipLevel = 0; currentMipLevel < texelsShallowCopy.count( );
1203 currentMipLevel++) { 1304 currentMipLevel++) {
1204 int twoToTheMipLevel = 1 << currentMipLevel; 1305 int twoToTheMipLevel = 1 << currentMipLevel;
(...skipping 30 matching lines...) Expand all
1235 int left, int top, int width, int height) { 1336 int left, int top, int width, int height) {
1236 SkASSERT(this->caps()->isConfigTexturable(desc.fConfig)); 1337 SkASSERT(this->caps()->isConfigTexturable(desc.fConfig));
1237 SkASSERT(kTransfer_UploadType != uploadType && 1338 SkASSERT(kTransfer_UploadType != uploadType &&
1238 (texels[0].fPixels || kNewTexture_UploadType != uploadType)); 1339 (texels[0].fPixels || kNewTexture_UploadType != uploadType));
1239 1340
1240 // No support for software flip y, yet... 1341 // No support for software flip y, yet...
1241 SkASSERT(kBottomLeft_GrSurfaceOrigin != desc.fOrigin); 1342 SkASSERT(kBottomLeft_GrSurfaceOrigin != desc.fOrigin);
1242 1343
1243 const GrGLInterface* interface = this->glInterface(); 1344 const GrGLInterface* interface = this->glInterface();
1244 const GrGLCaps& caps = this->glCaps(); 1345 const GrGLCaps& caps = this->glCaps();
1346 GrGLStandard standard = this->glStandard();
1245 1347
1246 if (-1 == width) { 1348 if (-1 == width) {
1247 width = desc.fWidth; 1349 width = desc.fWidth;
1248 } 1350 }
1249 #ifdef SK_DEBUG 1351 #ifdef SK_DEBUG
1250 else { 1352 else {
1251 SkASSERT(width <= desc.fWidth); 1353 SkASSERT(width <= desc.fWidth);
1252 } 1354 }
1253 #endif 1355 #endif
1254 1356
1255 if (-1 == height) { 1357 if (-1 == height) {
1256 height = desc.fHeight; 1358 height = desc.fHeight;
1257 } 1359 }
1258 #ifdef SK_DEBUG 1360 #ifdef SK_DEBUG
1259 else { 1361 else {
1260 SkASSERT(height <= desc.fHeight); 1362 SkASSERT(height <= desc.fHeight);
1261 } 1363 }
1262 #endif 1364 #endif
1263 1365
1264 // We only need the internal format for compressed 2D textures. 1366 // We only need the internal format for compressed 2D textures.
1265 GrGLenum internalFormat; 1367 GrGLenum internalFormat;
1266 if (!caps.getCompressedTexImageFormats(desc.fConfig, &internalFormat)) { 1368 if (!caps.getCompressedTexImageFormats(desc.fConfig, &internalFormat)) {
1267 return false; 1369 return false;
1268 } 1370 }
1269 1371
1270 if (kNewTexture_UploadType == uploadType) { 1372 if (kNewTexture_UploadType == uploadType) {
1271 return allocate_and_populate_compressed_texture(desc, *interface, target , internalFormat, 1373 bool useTexStorage = can_use_tex_storage(caps, standard, desc);
1272 texels, width, height); 1374 // We can only use TexStorage if we know we will not later change the st orage requirements.
1375 // This means if we may later want to generate mipmaps, we cannot use Te xStorage.
1376 // Right now, we cannot know if we will later generate mipmaps or not.
1377 // The only time we can use TexStorage is when we already have the
1378 // mipmaps.
1379 useTexStorage &= texels.count() > 1;
1380 return allocate_and_populate_compressed_texture(desc, *interface, useTex Storage, target,
1381 internalFormat, texels, width, height);
1273 } else { 1382 } else {
1274 // Paletted textures can't be updated. 1383 // Paletted textures can't be updated.
1275 if (GR_GL_PALETTE8_RGBA8 == internalFormat) { 1384 if (GR_GL_PALETTE8_RGBA8 == internalFormat) {
1276 return false; 1385 return false;
1277 } 1386 }
1278 for (int currentMipLevel = 0; currentMipLevel < texels.count(); currentM ipLevel++) { 1387 for (int currentMipLevel = 0; currentMipLevel < texels.count(); currentM ipLevel++) {
1279 if (texels[currentMipLevel].fPixels == nullptr) { 1388 if (texels[currentMipLevel].fPixels == nullptr) {
1280 continue; 1389 continue;
1281 } 1390 }
1282 1391
(...skipping 2934 matching lines...) Expand 10 before | Expand all | Expand 10 after
4217 if (GR_GL_TEXTURE_EXTERNAL == glTexture->target() || 4326 if (GR_GL_TEXTURE_EXTERNAL == glTexture->target() ||
4218 GR_GL_TEXTURE_RECTANGLE == glTexture->target()) { 4327 GR_GL_TEXTURE_RECTANGLE == glTexture->target()) {
4219 copyParams->fFilter = GrTextureParams::kNone_FilterMode; 4328 copyParams->fFilter = GrTextureParams::kNone_FilterMode;
4220 copyParams->fWidth = texture->width(); 4329 copyParams->fWidth = texture->width();
4221 copyParams->fHeight = texture->height(); 4330 copyParams->fHeight = texture->height();
4222 return true; 4331 return true;
4223 } 4332 }
4224 } 4333 }
4225 return false; 4334 return false;
4226 } 4335 }
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698