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 /* | 8 /* |
9 * Code for the "gm" (Golden Master) rendering comparison tool. | 9 * Code for the "gm" (Golden Master) rendering comparison tool. |
10 * | 10 * |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
46 #ifdef SK_BUILD_FOR_WIN | 46 #ifdef SK_BUILD_FOR_WIN |
47 #pragma warning(pop) | 47 #pragma warning(pop) |
48 #endif | 48 #endif |
49 | 49 |
50 #if SK_SUPPORT_GPU | 50 #if SK_SUPPORT_GPU |
51 #include "GrContextFactory.h" | 51 #include "GrContextFactory.h" |
52 #include "GrRenderTarget.h" | 52 #include "GrRenderTarget.h" |
53 #include "SkGpuDevice.h" | 53 #include "SkGpuDevice.h" |
54 typedef GrContextFactory::GLContextType GLContextType; | 54 typedef GrContextFactory::GLContextType GLContextType; |
55 #else | 55 #else |
| 56 class GrContextFactory; |
56 class GrContext; | 57 class GrContext; |
57 class GrRenderTarget; | 58 class GrRenderTarget; |
58 typedef int GLContextType; | 59 typedef int GLContextType; |
59 #endif | 60 #endif |
60 | 61 |
61 extern bool gSkSuppressFontCachePurgeSpew; | 62 extern bool gSkSuppressFontCachePurgeSpew; |
62 | 63 |
63 #ifdef SK_SUPPORT_PDF | 64 #ifdef SK_SUPPORT_PDF |
64 #include "SkPDFDevice.h" | 65 #include "SkPDFDevice.h" |
65 #include "SkPDFDocument.h" | 66 #include "SkPDFDocument.h" |
(...skipping 1056 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1122 SkASSERT(NULL == fOld); | 1123 SkASSERT(NULL == fOld); |
1123 fOld = GetGr(); | 1124 fOld = GetGr(); |
1124 SkSafeRef(fOld); | 1125 SkSafeRef(fOld); |
1125 SetGr(context); | 1126 SetGr(context); |
1126 } | 1127 } |
1127 ~AutoResetGr() { SetGr(fOld); SkSafeUnref(fOld); } | 1128 ~AutoResetGr() { SetGr(fOld); SkSafeUnref(fOld); } |
1128 private: | 1129 private: |
1129 GrContext* fOld; | 1130 GrContext* fOld; |
1130 }; | 1131 }; |
1131 #else | 1132 #else |
| 1133 GrContext* GetGr(); |
1132 GrContext* GetGr() { return NULL; } | 1134 GrContext* GetGr() { return NULL; } |
1133 #endif | 1135 #endif |
1134 } | 1136 } |
1135 | 1137 |
1136 template <typename T> void appendUnique(SkTDArray<T>* array, const T& value) { | 1138 template <typename T> void appendUnique(SkTDArray<T>* array, const T& value) { |
1137 int index = array->find(value); | 1139 int index = array->find(value); |
1138 if (index < 0) { | 1140 if (index < 0) { |
1139 *array->append() = value; | 1141 *array->append() = value; |
1140 } | 1142 } |
1141 } | 1143 } |
1142 | 1144 |
| 1145 /** |
| 1146 * Run this test in a number of different configs (8888, 565, PDF, |
| 1147 * etc.), confirming that the resulting bitmaps match expectations |
| 1148 * (which may be different for each config). |
| 1149 * |
| 1150 * Returns all errors encountered while doing so. |
| 1151 */ |
| 1152 ErrorBitfield run_multiple_configs(GMMain &gmmain, GM *gm, const SkTDArray<size_
t> &configs, |
| 1153 GrContextFactory *grFactory); |
| 1154 ErrorBitfield run_multiple_configs(GMMain &gmmain, GM *gm, const SkTDArray<size_
t> &configs, |
| 1155 GrContextFactory *grFactory) { |
| 1156 ErrorBitfield errorsForAllConfigs = kEmptyErrorBitfield; |
| 1157 uint32_t gmFlags = gm->getFlags(); |
| 1158 |
| 1159 #if SK_SUPPORT_GPU |
| 1160 struct { |
| 1161 int fBytes; |
| 1162 int fCount; |
| 1163 } gpuCacheSize = { -1, -1 }; // -1s mean use the default |
| 1164 |
| 1165 if (FLAGS_gpuCacheSize.count() > 0) { |
| 1166 if (FLAGS_gpuCacheSize.count() != 2) { |
| 1167 gm_fprintf(stderr, "--gpuCacheSize requires two arguments\n"); |
| 1168 return -1; |
| 1169 } |
| 1170 gpuCacheSize.fBytes = atoi(FLAGS_gpuCacheSize[0]); |
| 1171 gpuCacheSize.fCount = atoi(FLAGS_gpuCacheSize[1]); |
| 1172 } |
| 1173 #endif |
| 1174 |
| 1175 for (int i = 0; i < configs.count(); i++) { |
| 1176 ConfigData config = gRec[configs[i]]; |
| 1177 |
| 1178 // Skip any tests that we don't even need to try. |
| 1179 if ((kPDF_Backend == config.fBackend) && |
| 1180 (!FLAGS_pdf|| (gmFlags & GM::kSkipPDF_Flag))) { |
| 1181 continue; |
| 1182 } |
| 1183 if ((gmFlags & GM::kSkip565_Flag) && |
| 1184 (kRaster_Backend == config.fBackend) && |
| 1185 (SkBitmap::kRGB_565_Config == config.fConfig)) { |
| 1186 continue; |
| 1187 } |
| 1188 if ((gmFlags & GM::kSkipGPU_Flag) && |
| 1189 kGPU_Backend == config.fBackend) { |
| 1190 continue; |
| 1191 } |
| 1192 |
| 1193 // Now we know that we want to run this test and record its |
| 1194 // success or failure. |
| 1195 ErrorBitfield errorsForThisConfig = kEmptyErrorBitfield; |
| 1196 GrRenderTarget* renderTarget = NULL; |
| 1197 #if SK_SUPPORT_GPU |
| 1198 SkAutoTUnref<GrRenderTarget> rt; |
| 1199 AutoResetGr autogr; |
| 1200 if ((kEmptyErrorBitfield == errorsForThisConfig) && (kGPU_Backend == con
fig.fBackend)) { |
| 1201 GrContext* gr = grFactory->get(config.fGLContextType); |
| 1202 bool grSuccess = false; |
| 1203 if (gr) { |
| 1204 // create a render target to back the device |
| 1205 GrTextureDesc desc; |
| 1206 desc.fConfig = kSkia8888_GrPixelConfig; |
| 1207 desc.fFlags = kRenderTarget_GrTextureFlagBit; |
| 1208 desc.fWidth = gm->getISize().width(); |
| 1209 desc.fHeight = gm->getISize().height(); |
| 1210 desc.fSampleCnt = config.fSampleCnt; |
| 1211 GrTexture* tex = gr->createUncachedTexture(desc, NULL, 0); |
| 1212 if (tex) { |
| 1213 rt.reset(tex->asRenderTarget()); |
| 1214 rt.get()->ref(); |
| 1215 tex->unref(); |
| 1216 autogr.set(gr); |
| 1217 renderTarget = rt.get(); |
| 1218 grSuccess = NULL != renderTarget; |
| 1219 } |
| 1220 // Set the user specified cache limits if non-default. |
| 1221 size_t bytes; |
| 1222 int count; |
| 1223 gr->getTextureCacheLimits(&count, &bytes); |
| 1224 if (-1 != gpuCacheSize.fBytes) { |
| 1225 bytes = static_cast<size_t>(gpuCacheSize.fBytes); |
| 1226 } |
| 1227 if (-1 != gpuCacheSize.fCount) { |
| 1228 count = gpuCacheSize.fCount; |
| 1229 } |
| 1230 gr->setTextureCacheLimits(count, bytes); |
| 1231 } |
| 1232 if (!grSuccess) { |
| 1233 errorsForThisConfig |= kNoGpuContext_ErrorBitmask; |
| 1234 } |
| 1235 } |
| 1236 #endif |
| 1237 |
| 1238 SkBitmap comparisonBitmap; |
| 1239 |
| 1240 const char* writePath; |
| 1241 if (FLAGS_writePath.count() == 1) { |
| 1242 writePath = FLAGS_writePath[0]; |
| 1243 } else { |
| 1244 writePath = NULL; |
| 1245 } |
| 1246 if (kEmptyErrorBitfield == errorsForThisConfig) { |
| 1247 errorsForThisConfig |= gmmain.test_drawing(gm, config, writePath, Ge
tGr(), |
| 1248 renderTarget, &comparison
Bitmap); |
| 1249 } |
| 1250 |
| 1251 if (FLAGS_deferred && !errorsForThisConfig && |
| 1252 (kGPU_Backend == config.fBackend || |
| 1253 kRaster_Backend == config.fBackend)) { |
| 1254 errorsForThisConfig |= gmmain.test_deferred_drawing(gm, config, comp
arisonBitmap, |
| 1255 GetGr(), renderT
arget); |
| 1256 } |
| 1257 |
| 1258 errorsForAllConfigs |= errorsForThisConfig; |
| 1259 } |
| 1260 return errorsForAllConfigs; |
| 1261 } |
| 1262 |
| 1263 /** |
| 1264 * Run this test in a number of different drawing modes (pipe, |
| 1265 * deferred, tiled, etc.), confirming that the resulting bitmaps all |
| 1266 * *exactly* match comparisonBitmap. |
| 1267 * |
| 1268 * Returns all errors encountered while doing so. |
| 1269 */ |
| 1270 ErrorBitfield run_multiple_modes(GMMain &gmmain, GM *gm, const ConfigData &compa
reConfig, |
| 1271 const SkBitmap &comparisonBitmap); |
| 1272 ErrorBitfield run_multiple_modes(GMMain &gmmain, GM *gm, const ConfigData &compa
reConfig, |
| 1273 const SkBitmap &comparisonBitmap) { |
| 1274 SkTDArray<SkScalar> tileGridReplayScales; |
| 1275 *tileGridReplayScales.append() = SK_Scalar1; // By default only test at scal
e 1.0 |
| 1276 if (FLAGS_tileGridReplayScales.count() > 0) { |
| 1277 tileGridReplayScales.reset(); |
| 1278 for (int i = 0; i < FLAGS_tileGridReplayScales.count(); i++) { |
| 1279 double val = atof(FLAGS_tileGridReplayScales[i]); |
| 1280 if (0 < val) { |
| 1281 *tileGridReplayScales.append() = SkDoubleToScalar(val); |
| 1282 } |
| 1283 } |
| 1284 if (0 == tileGridReplayScales.count()) { |
| 1285 // Should have at least one scale |
| 1286 gm_fprintf(stderr, "--tileGridReplayScales requires at least one sca
le.\n"); |
| 1287 return -1; |
| 1288 } |
| 1289 } |
| 1290 |
| 1291 ErrorBitfield errorsForAllModes = kEmptyErrorBitfield; |
| 1292 uint32_t gmFlags = gm->getFlags(); |
| 1293 |
| 1294 // run the picture centric GM steps |
| 1295 if (!(gmFlags & GM::kSkipPicture_Flag)) { |
| 1296 |
| 1297 ErrorBitfield pictErrors = kEmptyErrorBitfield; |
| 1298 |
| 1299 //SkAutoTUnref<SkPicture> pict(generate_new_picture(gm)); |
| 1300 SkPicture* pict = gmmain.generate_new_picture(gm, kNone_BbhType, 0); |
| 1301 SkAutoUnref aur(pict); |
| 1302 |
| 1303 if (FLAGS_replay) { |
| 1304 SkBitmap bitmap; |
| 1305 gmmain.generate_image_from_picture(gm, compareConfig, pict, &bitmap)
; |
| 1306 pictErrors |= gmmain.compare_test_results_to_reference_bitmap( |
| 1307 gm, compareConfig, "-replay", bitmap, &comparisonBitmap); |
| 1308 } |
| 1309 |
| 1310 if ((kEmptyErrorBitfield == pictErrors) && FLAGS_serialize) { |
| 1311 SkPicture* repict = gmmain.stream_to_new_picture(*pict); |
| 1312 SkAutoUnref aurr(repict); |
| 1313 |
| 1314 SkBitmap bitmap; |
| 1315 gmmain.generate_image_from_picture(gm, compareConfig, repict, &bitma
p); |
| 1316 pictErrors |= gmmain.compare_test_results_to_reference_bitmap( |
| 1317 gm, compareConfig, "-serialize", bitmap, &comparisonBitmap); |
| 1318 } |
| 1319 |
| 1320 if (FLAGS_writePicturePath.count() == 1) { |
| 1321 const char* pictureSuffix = "skp"; |
| 1322 SkString path = make_filename(FLAGS_writePicturePath[0], "", |
| 1323 gm->shortName(), pictureSuffix); |
| 1324 SkFILEWStream stream(path.c_str()); |
| 1325 pict->serialize(&stream); |
| 1326 } |
| 1327 |
| 1328 errorsForAllModes |= pictErrors; |
| 1329 } |
| 1330 |
| 1331 // TODO: add a test in which the RTree rendering results in a |
| 1332 // different bitmap than the standard rendering. It should |
| 1333 // show up as failed in the JSON summary, and should be listed |
| 1334 // in the stdout also. |
| 1335 if (!(gmFlags & GM::kSkipPicture_Flag) && FLAGS_rtree) { |
| 1336 SkPicture* pict = gmmain.generate_new_picture( |
| 1337 gm, kRTree_BbhType, SkPicture::kUsePathBoundsForClip_RecordingFlag); |
| 1338 SkAutoUnref aur(pict); |
| 1339 SkBitmap bitmap; |
| 1340 gmmain.generate_image_from_picture(gm, compareConfig, pict, &bitmap); |
| 1341 errorsForAllModes |= gmmain.compare_test_results_to_reference_bitmap( |
| 1342 gm, compareConfig, "-rtree", bitmap, &comparisonBitmap); |
| 1343 } |
| 1344 |
| 1345 if (!(gmFlags & GM::kSkipPicture_Flag) && FLAGS_tileGrid) { |
| 1346 for(int scaleIndex = 0; scaleIndex < tileGridReplayScales.count(); ++sca
leIndex) { |
| 1347 SkScalar replayScale = tileGridReplayScales[scaleIndex]; |
| 1348 if ((gmFlags & GM::kSkipScaledReplay_Flag) && replayScale != 1) { |
| 1349 continue; |
| 1350 } |
| 1351 // We record with the reciprocal scale to obtain a replay |
| 1352 // result that can be validated against comparisonBitmap. |
| 1353 SkScalar recordScale = SkScalarInvert(replayScale); |
| 1354 SkPicture* pict = gmmain.generate_new_picture( |
| 1355 gm, kTileGrid_BbhType, SkPicture::kUsePathBoundsForClip_Recordin
gFlag, recordScale); |
| 1356 SkAutoUnref aur(pict); |
| 1357 SkBitmap bitmap; |
| 1358 gmmain.generate_image_from_picture(gm, compareConfig, pict, &bitmap,
replayScale); |
| 1359 SkString suffix("-tilegrid"); |
| 1360 if (SK_Scalar1 != replayScale) { |
| 1361 suffix += "-scale-"; |
| 1362 suffix.appendScalar(replayScale); |
| 1363 } |
| 1364 errorsForAllModes |= gmmain.compare_test_results_to_reference_bitmap
( |
| 1365 gm, compareConfig, suffix.c_str(), bitmap, &comparisonBitmap); |
| 1366 } |
| 1367 } |
| 1368 |
| 1369 // run the pipe centric GM steps |
| 1370 if (!(gmFlags & GM::kSkipPipe_Flag)) { |
| 1371 |
| 1372 ErrorBitfield pipeErrors = kEmptyErrorBitfield; |
| 1373 |
| 1374 if (FLAGS_pipe) { |
| 1375 pipeErrors |= gmmain.test_pipe_playback(gm, compareConfig, compariso
nBitmap); |
| 1376 } |
| 1377 |
| 1378 if ((kEmptyErrorBitfield == pipeErrors) && |
| 1379 FLAGS_tiledPipe && !(gmFlags & GM::kSkipTiled_Flag)) { |
| 1380 pipeErrors |= gmmain.test_tiled_pipe_playback(gm, compareConfig, com
parisonBitmap); |
| 1381 } |
| 1382 |
| 1383 errorsForAllModes |= pipeErrors; |
| 1384 } |
| 1385 return errorsForAllModes; |
| 1386 } |
| 1387 |
1143 int tool_main(int argc, char** argv); | 1388 int tool_main(int argc, char** argv); |
1144 int tool_main(int argc, char** argv) { | 1389 int tool_main(int argc, char** argv) { |
1145 | 1390 |
1146 #if SK_ENABLE_INST_COUNT | 1391 #if SK_ENABLE_INST_COUNT |
1147 gPrintInstCount = true; | 1392 gPrintInstCount = true; |
1148 #endif | 1393 #endif |
1149 | 1394 |
1150 SkGraphics::Init(); | 1395 SkGraphics::Init(); |
1151 // we don't need to see this during a run | 1396 // we don't need to see this during a run |
1152 gSkSuppressFontCachePurgeSpew = true; | 1397 gSkSuppressFontCachePurgeSpew = true; |
1153 | 1398 |
1154 setSystemPreferences(); | 1399 setSystemPreferences(); |
1155 GMMain gmmain; | 1400 GMMain gmmain; |
1156 | 1401 |
1157 SkTDArray<size_t> configs; | 1402 SkTDArray<size_t> configs; |
1158 SkTDArray<size_t> excludeConfigs; | 1403 SkTDArray<size_t> excludeConfigs; |
1159 SkTDArray<SkScalar> tileGridReplayScales; | |
1160 *tileGridReplayScales.append() = SK_Scalar1; // By default only test at scal
e 1.0 | |
1161 bool userConfig = false; | 1404 bool userConfig = false; |
1162 | 1405 |
1163 SkString usage; | 1406 SkString usage; |
1164 usage.printf("Run the golden master tests.\n"); | 1407 usage.printf("Run the golden master tests.\n"); |
1165 SkFlags::SetUsage(usage.c_str()); | 1408 SkFlags::SetUsage(usage.c_str()); |
1166 SkFlags::ParseCommandLine(argc, argv); | 1409 SkFlags::ParseCommandLine(argc, argv); |
1167 | 1410 |
1168 #if SK_SUPPORT_GPU | |
1169 struct { | |
1170 int fBytes; | |
1171 int fCount; | |
1172 } gpuCacheSize = { -1, -1 }; // -1s mean use the default | |
1173 | |
1174 if (FLAGS_gpuCacheSize.count() > 0) { | |
1175 if (FLAGS_gpuCacheSize.count() != 2) { | |
1176 gm_fprintf(stderr, "--gpuCacheSize requires two arguments\n"); | |
1177 return -1; | |
1178 } | |
1179 gpuCacheSize.fBytes = atoi(FLAGS_gpuCacheSize[0]); | |
1180 gpuCacheSize.fCount = atoi(FLAGS_gpuCacheSize[1]); | |
1181 } | |
1182 #endif | |
1183 | |
1184 gmmain.fUseFileHierarchy = FLAGS_hierarchy; | 1411 gmmain.fUseFileHierarchy = FLAGS_hierarchy; |
1185 if (FLAGS_mismatchPath.count() == 1) { | 1412 if (FLAGS_mismatchPath.count() == 1) { |
1186 gmmain.fMismatchPath = FLAGS_mismatchPath[0]; | 1413 gmmain.fMismatchPath = FLAGS_mismatchPath[0]; |
1187 } | 1414 } |
1188 | 1415 |
1189 for (int i = 0; i < FLAGS_config.count(); i++) { | 1416 for (int i = 0; i < FLAGS_config.count(); i++) { |
1190 int index = findConfig(FLAGS_config[i]); | 1417 int index = findConfig(FLAGS_config[i]); |
1191 if (index >= 0) { | 1418 if (index >= 0) { |
1192 appendUnique<size_t>(&configs, index); | 1419 appendUnique<size_t>(&configs, index); |
1193 userConfig = true; | 1420 userConfig = true; |
1194 } else { | 1421 } else { |
1195 gm_fprintf(stderr, "unrecognized config %s\n", FLAGS_config[i]); | 1422 gm_fprintf(stderr, "unrecognized config %s\n", FLAGS_config[i]); |
1196 return -1; | 1423 return -1; |
1197 } | 1424 } |
1198 } | 1425 } |
1199 | 1426 |
1200 for (int i = 0; i < FLAGS_excludeConfig.count(); i++) { | 1427 for (int i = 0; i < FLAGS_excludeConfig.count(); i++) { |
1201 int index = findConfig(FLAGS_excludeConfig[i]); | 1428 int index = findConfig(FLAGS_excludeConfig[i]); |
1202 if (index >= 0) { | 1429 if (index >= 0) { |
1203 *excludeConfigs.append() = index; | 1430 *excludeConfigs.append() = index; |
1204 } else { | 1431 } else { |
1205 gm_fprintf(stderr, "unrecognized excludeConfig %s\n", FLAGS_excludeC
onfig[i]); | 1432 gm_fprintf(stderr, "unrecognized excludeConfig %s\n", FLAGS_excludeC
onfig[i]); |
1206 return -1; | 1433 return -1; |
1207 } | 1434 } |
1208 } | 1435 } |
1209 | 1436 |
1210 if (FLAGS_tileGridReplayScales.count() > 0) { | |
1211 tileGridReplayScales.reset(); | |
1212 for (int i = 0; i < FLAGS_tileGridReplayScales.count(); i++) { | |
1213 double val = atof(FLAGS_tileGridReplayScales[i]); | |
1214 if (0 < val) { | |
1215 *tileGridReplayScales.append() = SkDoubleToScalar(val); | |
1216 } | |
1217 } | |
1218 if (0 == tileGridReplayScales.count()) { | |
1219 // Should have at least one scale | |
1220 gm_fprintf(stderr, "--tileGridReplayScales requires at least one sca
le.\n"); | |
1221 return -1; | |
1222 } | |
1223 } | |
1224 | |
1225 int moduloRemainder = -1; | 1437 int moduloRemainder = -1; |
1226 int moduloDivisor = -1; | 1438 int moduloDivisor = -1; |
1227 | 1439 |
1228 if (FLAGS_modulo.count() == 2) { | 1440 if (FLAGS_modulo.count() == 2) { |
1229 moduloRemainder = atoi(FLAGS_modulo[0]); | 1441 moduloRemainder = atoi(FLAGS_modulo[0]); |
1230 moduloDivisor = atoi(FLAGS_modulo[1]); | 1442 moduloDivisor = atoi(FLAGS_modulo[1]); |
1231 if (moduloRemainder < 0 || moduloDivisor <= 0 || moduloRemainder >= modu
loDivisor) { | 1443 if (moduloRemainder < 0 || moduloDivisor <= 0 || moduloRemainder >= modu
loDivisor) { |
1232 gm_fprintf(stderr, "invalid modulo values."); | 1444 gm_fprintf(stderr, "invalid modulo values."); |
1233 return -1; | 1445 return -1; |
1234 } | 1446 } |
(...skipping 30 matching lines...) Expand all Loading... |
1265 --i; | 1477 --i; |
1266 } | 1478 } |
1267 if (gRec[index].fSampleCnt > ctx->getMaxSampleCount()) { | 1479 if (gRec[index].fSampleCnt > ctx->getMaxSampleCount()) { |
1268 SkDebugf("Sample count (%d) of config %s is not supported. Confi
g will be skipped.", | 1480 SkDebugf("Sample count (%d) of config %s is not supported. Confi
g will be skipped.", |
1269 gRec[index].fSampleCnt, gRec[index].fName); | 1481 gRec[index].fSampleCnt, gRec[index].fName); |
1270 configs.remove(i); | 1482 configs.remove(i); |
1271 --i; | 1483 --i; |
1272 } | 1484 } |
1273 } | 1485 } |
1274 } | 1486 } |
| 1487 #else |
| 1488 GrContextFactory* grFactory = NULL; |
1275 #endif | 1489 #endif |
1276 | 1490 |
1277 if (FLAGS_verbose) { | 1491 if (FLAGS_verbose) { |
1278 SkString str; | 1492 SkString str; |
1279 str.printf("%d configs:", configs.count()); | 1493 str.printf("%d configs:", configs.count()); |
1280 for (int i = 0; i < configs.count(); ++i) { | 1494 for (int i = 0; i < configs.count(); ++i) { |
1281 str.appendf(" %s", gRec[configs[i]].fName); | 1495 str.appendf(" %s", gRec[configs[i]].fName); |
1282 } | 1496 } |
1283 gm_fprintf(stderr, "%s\n", str.c_str()); | 1497 gm_fprintf(stderr, "%s\n", str.c_str()); |
1284 } | 1498 } |
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1364 if (skip_name(FLAGS_match, shortName)) { | 1578 if (skip_name(FLAGS_match, shortName)) { |
1365 SkDELETE(gm); | 1579 SkDELETE(gm); |
1366 continue; | 1580 continue; |
1367 } | 1581 } |
1368 | 1582 |
1369 SkISize size = gm->getISize(); | 1583 SkISize size = gm->getISize(); |
1370 gm_fprintf(stdout, "%sdrawing... %s [%d %d]\n", moduloStr.c_str(), short
Name, | 1584 gm_fprintf(stdout, "%sdrawing... %s [%d %d]\n", moduloStr.c_str(), short
Name, |
1371 size.width(), size.height()); | 1585 size.width(), size.height()); |
1372 | 1586 |
1373 ErrorBitfield testErrors = kEmptyErrorBitfield; | 1587 ErrorBitfield testErrors = kEmptyErrorBitfield; |
1374 uint32_t gmFlags = gm->getFlags(); | 1588 testErrors |= run_multiple_configs(gmmain, gm, configs, grFactory); |
1375 | |
1376 for (int i = 0; i < configs.count(); i++) { | |
1377 ConfigData config = gRec[configs[i]]; | |
1378 | |
1379 // Skip any tests that we don't even need to try. | |
1380 if ((kPDF_Backend == config.fBackend) && | |
1381 (!FLAGS_pdf|| (gmFlags & GM::kSkipPDF_Flag))) | |
1382 { | |
1383 continue; | |
1384 } | |
1385 if ((gmFlags & GM::kSkip565_Flag) && | |
1386 (kRaster_Backend == config.fBackend) && | |
1387 (SkBitmap::kRGB_565_Config == config.fConfig)) { | |
1388 continue; | |
1389 } | |
1390 if ((gmFlags & GM::kSkipGPU_Flag) && | |
1391 kGPU_Backend == config.fBackend) { | |
1392 continue; | |
1393 } | |
1394 | |
1395 // Now we know that we want to run this test and record its | |
1396 // success or failure. | |
1397 ErrorBitfield renderErrors = kEmptyErrorBitfield; | |
1398 GrRenderTarget* renderTarget = NULL; | |
1399 #if SK_SUPPORT_GPU | |
1400 SkAutoTUnref<GrRenderTarget> rt; | |
1401 AutoResetGr autogr; | |
1402 if ((kEmptyErrorBitfield == renderErrors) && | |
1403 kGPU_Backend == config.fBackend) { | |
1404 GrContext* gr = grFactory->get(config.fGLContextType); | |
1405 bool grSuccess = false; | |
1406 if (gr) { | |
1407 // create a render target to back the device | |
1408 GrTextureDesc desc; | |
1409 desc.fConfig = kSkia8888_GrPixelConfig; | |
1410 desc.fFlags = kRenderTarget_GrTextureFlagBit; | |
1411 desc.fWidth = gm->getISize().width(); | |
1412 desc.fHeight = gm->getISize().height(); | |
1413 desc.fSampleCnt = config.fSampleCnt; | |
1414 GrTexture* tex = gr->createUncachedTexture(desc, NULL, 0); | |
1415 if (tex) { | |
1416 rt.reset(tex->asRenderTarget()); | |
1417 rt.get()->ref(); | |
1418 tex->unref(); | |
1419 autogr.set(gr); | |
1420 renderTarget = rt.get(); | |
1421 grSuccess = NULL != renderTarget; | |
1422 } | |
1423 // Set the user specified cache limits if non-default. | |
1424 size_t bytes; | |
1425 int count; | |
1426 gr->getTextureCacheLimits(&count, &bytes); | |
1427 if (-1 != gpuCacheSize.fBytes) { | |
1428 bytes = static_cast<size_t>(gpuCacheSize.fBytes); | |
1429 } | |
1430 if (-1 != gpuCacheSize.fCount) { | |
1431 count = gpuCacheSize.fCount; | |
1432 } | |
1433 gr->setTextureCacheLimits(count, bytes); | |
1434 } | |
1435 if (!grSuccess) { | |
1436 renderErrors |= kNoGpuContext_ErrorBitmask; | |
1437 } | |
1438 } | |
1439 #endif | |
1440 | |
1441 SkBitmap comparisonBitmap; | |
1442 | |
1443 const char* writePath; | |
1444 if (FLAGS_writePath.count() == 1) { | |
1445 writePath = FLAGS_writePath[0]; | |
1446 } else { | |
1447 writePath = NULL; | |
1448 } | |
1449 if (kEmptyErrorBitfield == renderErrors) { | |
1450 renderErrors |= gmmain.test_drawing(gm, config, writePath, | |
1451 GetGr(), | |
1452 renderTarget, | |
1453 &comparisonBitmap); | |
1454 } | |
1455 | |
1456 if (FLAGS_deferred && !renderErrors && | |
1457 (kGPU_Backend == config.fBackend || | |
1458 kRaster_Backend == config.fBackend)) { | |
1459 renderErrors |= gmmain.test_deferred_drawing(gm, config, | |
1460 comparisonBitmap, | |
1461 GetGr(), | |
1462 renderTarget); | |
1463 } | |
1464 | |
1465 testErrors |= renderErrors; | |
1466 } | |
1467 | 1589 |
1468 SkBitmap comparisonBitmap; | 1590 SkBitmap comparisonBitmap; |
1469 const ConfigData compareConfig = | 1591 const ConfigData compareConfig = |
1470 { SkBitmap::kARGB_8888_Config, kRaster_Backend, kDontCare_GLContextT
ype, 0, kRW_ConfigFlag, "comparison", false }; | 1592 { SkBitmap::kARGB_8888_Config, kRaster_Backend, kDontCare_GLContextT
ype, 0, kRW_ConfigFlag, "comparison", false }; |
1471 testErrors |= gmmain.generate_image(gm, compareConfig, NULL, NULL, &comp
arisonBitmap, false); | 1593 testErrors |= gmmain.generate_image(gm, compareConfig, NULL, NULL, &comp
arisonBitmap, false); |
1472 | 1594 |
1473 // run the picture centric GM steps | 1595 // TODO(epoger): only run this if gmmain.generate_image() succeeded? |
1474 if (!(gmFlags & GM::kSkipPicture_Flag)) { | 1596 // Otherwise, what are we comparing against? |
1475 | 1597 testErrors |= run_multiple_modes(gmmain, gm, compareConfig, comparisonBi
tmap); |
1476 ErrorBitfield pictErrors = kEmptyErrorBitfield; | |
1477 | |
1478 //SkAutoTUnref<SkPicture> pict(generate_new_picture(gm)); | |
1479 SkPicture* pict = gmmain.generate_new_picture(gm, kNone_BbhType, 0); | |
1480 SkAutoUnref aur(pict); | |
1481 | |
1482 if ((kEmptyErrorBitfield == testErrors) && FLAGS_replay) { | |
1483 SkBitmap bitmap; | |
1484 gmmain.generate_image_from_picture(gm, compareConfig, pict, | |
1485 &bitmap); | |
1486 pictErrors |= gmmain.compare_test_results_to_reference_bitmap( | |
1487 gm, compareConfig, "-replay", bitmap, &comparisonBitmap); | |
1488 } | |
1489 | |
1490 if ((kEmptyErrorBitfield == testErrors) && | |
1491 (kEmptyErrorBitfield == pictErrors) && | |
1492 FLAGS_serialize) { | |
1493 SkPicture* repict = gmmain.stream_to_new_picture(*pict); | |
1494 SkAutoUnref aurr(repict); | |
1495 | |
1496 SkBitmap bitmap; | |
1497 gmmain.generate_image_from_picture(gm, compareConfig, repict, | |
1498 &bitmap); | |
1499 pictErrors |= gmmain.compare_test_results_to_reference_bitmap( | |
1500 gm, compareConfig, "-serialize", bitmap, &comparisonBitmap); | |
1501 } | |
1502 | |
1503 if (FLAGS_writePicturePath.count() == 1) { | |
1504 const char* pictureSuffix = "skp"; | |
1505 SkString path = make_filename(FLAGS_writePicturePath[0], "", | |
1506 gm->shortName(), | |
1507 pictureSuffix); | |
1508 SkFILEWStream stream(path.c_str()); | |
1509 pict->serialize(&stream); | |
1510 } | |
1511 | |
1512 testErrors |= pictErrors; | |
1513 } | |
1514 | |
1515 // TODO: add a test in which the RTree rendering results in a | |
1516 // different bitmap than the standard rendering. It should | |
1517 // show up as failed in the JSON summary, and should be listed | |
1518 // in the stdout also. | |
1519 if (!(gmFlags & GM::kSkipPicture_Flag) && FLAGS_rtree) { | |
1520 SkPicture* pict = gmmain.generate_new_picture( | |
1521 gm, kRTree_BbhType, SkPicture::kUsePathBoundsForClip_RecordingFl
ag); | |
1522 SkAutoUnref aur(pict); | |
1523 SkBitmap bitmap; | |
1524 gmmain.generate_image_from_picture(gm, compareConfig, pict, | |
1525 &bitmap); | |
1526 testErrors |= gmmain.compare_test_results_to_reference_bitmap( | |
1527 gm, compareConfig, "-rtree", bitmap, &comparisonBitmap); | |
1528 } | |
1529 | |
1530 if (!(gmFlags & GM::kSkipPicture_Flag) && FLAGS_tileGrid) { | |
1531 for(int scaleIndex = 0; scaleIndex < tileGridReplayScales.count(); +
+scaleIndex) { | |
1532 SkScalar replayScale = tileGridReplayScales[scaleIndex]; | |
1533 if ((gmFlags & GM::kSkipScaledReplay_Flag) && replayScale != 1) | |
1534 continue; | |
1535 // We record with the reciprocal scale to obtain a replay | |
1536 // result that can be validated against comparisonBitmap. | |
1537 SkScalar recordScale = SkScalarInvert(replayScale); | |
1538 SkPicture* pict = gmmain.generate_new_picture( | |
1539 gm, kTileGrid_BbhType, SkPicture::kUsePathBoundsForClip_Reco
rdingFlag, | |
1540 recordScale); | |
1541 SkAutoUnref aur(pict); | |
1542 SkBitmap bitmap; | |
1543 gmmain.generate_image_from_picture(gm, compareConfig, pict, | |
1544 &bitmap, replayScale); | |
1545 SkString suffix("-tilegrid"); | |
1546 if (SK_Scalar1 != replayScale) { | |
1547 suffix += "-scale-"; | |
1548 suffix.appendScalar(replayScale); | |
1549 } | |
1550 testErrors |= gmmain.compare_test_results_to_reference_bitmap( | |
1551 gm, compareConfig, suffix.c_str(), bitmap, | |
1552 &comparisonBitmap); | |
1553 } | |
1554 } | |
1555 | |
1556 // run the pipe centric GM steps | |
1557 if (!(gmFlags & GM::kSkipPipe_Flag)) { | |
1558 | |
1559 ErrorBitfield pipeErrors = kEmptyErrorBitfield; | |
1560 | |
1561 if ((kEmptyErrorBitfield == testErrors) && FLAGS_pipe) { | |
1562 pipeErrors |= gmmain.test_pipe_playback(gm, compareConfig, | |
1563 comparisonBitmap); | |
1564 } | |
1565 | |
1566 if ((kEmptyErrorBitfield == testErrors) && | |
1567 (kEmptyErrorBitfield == pipeErrors) && | |
1568 FLAGS_tiledPipe && !(gmFlags & GM::kSkipTiled_Flag)) { | |
1569 pipeErrors |= gmmain.test_tiled_pipe_playback(gm, compareConfig, | |
1570 comparisonBitmap); | |
1571 } | |
1572 | |
1573 testErrors |= pipeErrors; | |
1574 } | |
1575 | 1598 |
1576 // Update overall results. | 1599 // Update overall results. |
1577 // We only tabulate the particular error types that we currently | 1600 // We only tabulate the particular error types that we currently |
1578 // care about (e.g., missing reference images). Later on, if we | 1601 // care about (e.g., missing reference images). Later on, if we |
1579 // want to also tabulate other error types, we can do so. | 1602 // want to also tabulate other error types, we can do so. |
1580 testsRun++; | 1603 testsRun++; |
1581 if (!gmmain.fExpectationsSource.get() || | 1604 if (!gmmain.fExpectationsSource.get() || |
1582 (kEmptyErrorBitfield != (kMissingExpectations_ErrorBitmask & testErr
ors))) { | 1605 (kEmptyErrorBitfield != (kMissingExpectations_ErrorBitmask & testErr
ors))) { |
1583 testsMissingReferenceImages++; | 1606 testsMissingReferenceImages++; |
1584 } | 1607 } |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1638 if (FLAGS_forceBWtext) { | 1661 if (FLAGS_forceBWtext) { |
1639 canvas->setDrawFilter(SkNEW(BWTextDrawFilter))->unref(); | 1662 canvas->setDrawFilter(SkNEW(BWTextDrawFilter))->unref(); |
1640 } | 1663 } |
1641 } | 1664 } |
1642 | 1665 |
1643 #if !defined(SK_BUILD_FOR_IOS) && !defined(SK_BUILD_FOR_NACL) | 1666 #if !defined(SK_BUILD_FOR_IOS) && !defined(SK_BUILD_FOR_NACL) |
1644 int main(int argc, char * const argv[]) { | 1667 int main(int argc, char * const argv[]) { |
1645 return tool_main(argc, (char**) argv); | 1668 return tool_main(argc, (char**) argv); |
1646 } | 1669 } |
1647 #endif | 1670 #endif |
OLD | NEW |