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 1122 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1133 #endif | 1133 #endif |
1134 } | 1134 } |
1135 | 1135 |
1136 template <typename T> void appendUnique(SkTDArray<T>* array, const T& value) { | 1136 template <typename T> void appendUnique(SkTDArray<T>* array, const T& value) { |
1137 int index = array->find(value); | 1137 int index = array->find(value); |
1138 if (index < 0) { | 1138 if (index < 0) { |
1139 *array->append() = value; | 1139 *array->append() = value; |
1140 } | 1140 } |
1141 } | 1141 } |
1142 | 1142 |
| 1143 /** |
| 1144 * Run this test in a number of different configs (8888, 565, PDF, |
| 1145 * etc.), confirming that the resulting bitmaps match expectations |
| 1146 * (which may be different for each config). |
| 1147 * |
| 1148 * Returns all errors encountered while doing so. |
| 1149 */ |
| 1150 ErrorBitfield run_multiple_configs(GMMain &gmmain, GM *gm, const SkTDArray<size_
t> &configs, |
| 1151 GrContextFactory *grFactory) { |
| 1152 ErrorBitfield errorsForAllConfigs = kEmptyErrorBitfield; |
| 1153 uint32_t gmFlags = gm->getFlags(); |
| 1154 |
| 1155 #if SK_SUPPORT_GPU |
| 1156 struct { |
| 1157 int fBytes; |
| 1158 int fCount; |
| 1159 } gpuCacheSize = { -1, -1 }; // -1s mean use the default |
| 1160 |
| 1161 if (FLAGS_gpuCacheSize.count() > 0) { |
| 1162 if (FLAGS_gpuCacheSize.count() != 2) { |
| 1163 gm_fprintf(stderr, "--gpuCacheSize requires two arguments\n"); |
| 1164 return -1; |
| 1165 } |
| 1166 gpuCacheSize.fBytes = atoi(FLAGS_gpuCacheSize[0]); |
| 1167 gpuCacheSize.fCount = atoi(FLAGS_gpuCacheSize[1]); |
| 1168 } |
| 1169 #endif |
| 1170 |
| 1171 for (int i = 0; i < configs.count(); i++) { |
| 1172 ConfigData config = gRec[configs[i]]; |
| 1173 |
| 1174 // Skip any tests that we don't even need to try. |
| 1175 if ((kPDF_Backend == config.fBackend) && |
| 1176 (!FLAGS_pdf|| (gmFlags & GM::kSkipPDF_Flag))) { |
| 1177 continue; |
| 1178 } |
| 1179 if ((gmFlags & GM::kSkip565_Flag) && |
| 1180 (kRaster_Backend == config.fBackend) && |
| 1181 (SkBitmap::kRGB_565_Config == config.fConfig)) { |
| 1182 continue; |
| 1183 } |
| 1184 if ((gmFlags & GM::kSkipGPU_Flag) && |
| 1185 kGPU_Backend == config.fBackend) { |
| 1186 continue; |
| 1187 } |
| 1188 |
| 1189 // Now we know that we want to run this test and record its |
| 1190 // success or failure. |
| 1191 ErrorBitfield errorsForThisConfig = kEmptyErrorBitfield; |
| 1192 GrRenderTarget* renderTarget = NULL; |
| 1193 #if SK_SUPPORT_GPU |
| 1194 SkAutoTUnref<GrRenderTarget> rt; |
| 1195 AutoResetGr autogr; |
| 1196 if ((kEmptyErrorBitfield == errorsForThisConfig) && (kGPU_Backend == con
fig.fBackend)) { |
| 1197 GrContext* gr = grFactory->get(config.fGLContextType); |
| 1198 bool grSuccess = false; |
| 1199 if (gr) { |
| 1200 // create a render target to back the device |
| 1201 GrTextureDesc desc; |
| 1202 desc.fConfig = kSkia8888_GrPixelConfig; |
| 1203 desc.fFlags = kRenderTarget_GrTextureFlagBit; |
| 1204 desc.fWidth = gm->getISize().width(); |
| 1205 desc.fHeight = gm->getISize().height(); |
| 1206 desc.fSampleCnt = config.fSampleCnt; |
| 1207 GrTexture* tex = gr->createUncachedTexture(desc, NULL, 0); |
| 1208 if (tex) { |
| 1209 rt.reset(tex->asRenderTarget()); |
| 1210 rt.get()->ref(); |
| 1211 tex->unref(); |
| 1212 autogr.set(gr); |
| 1213 renderTarget = rt.get(); |
| 1214 grSuccess = NULL != renderTarget; |
| 1215 } |
| 1216 // Set the user specified cache limits if non-default. |
| 1217 size_t bytes; |
| 1218 int count; |
| 1219 gr->getTextureCacheLimits(&count, &bytes); |
| 1220 if (-1 != gpuCacheSize.fBytes) { |
| 1221 bytes = static_cast<size_t>(gpuCacheSize.fBytes); |
| 1222 } |
| 1223 if (-1 != gpuCacheSize.fCount) { |
| 1224 count = gpuCacheSize.fCount; |
| 1225 } |
| 1226 gr->setTextureCacheLimits(count, bytes); |
| 1227 } |
| 1228 if (!grSuccess) { |
| 1229 errorsForThisConfig |= kNoGpuContext_ErrorBitmask; |
| 1230 } |
| 1231 } |
| 1232 #endif |
| 1233 |
| 1234 SkBitmap comparisonBitmap; |
| 1235 |
| 1236 const char* writePath; |
| 1237 if (FLAGS_writePath.count() == 1) { |
| 1238 writePath = FLAGS_writePath[0]; |
| 1239 } else { |
| 1240 writePath = NULL; |
| 1241 } |
| 1242 if (kEmptyErrorBitfield == errorsForThisConfig) { |
| 1243 errorsForThisConfig |= gmmain.test_drawing(gm, config, writePath, Ge
tGr(), |
| 1244 renderTarget, &comparison
Bitmap); |
| 1245 } |
| 1246 |
| 1247 if (FLAGS_deferred && !errorsForThisConfig && |
| 1248 (kGPU_Backend == config.fBackend || |
| 1249 kRaster_Backend == config.fBackend)) { |
| 1250 errorsForThisConfig |= gmmain.test_deferred_drawing(gm, config, comp
arisonBitmap, |
| 1251 GetGr(), renderT
arget); |
| 1252 } |
| 1253 |
| 1254 errorsForAllConfigs |= errorsForThisConfig; |
| 1255 } |
| 1256 return errorsForAllConfigs; |
| 1257 } |
| 1258 |
| 1259 /** |
| 1260 * Run this test in a number of different drawing modes (pipe, |
| 1261 * deferred, tiled, etc.), confirming that the resulting bitmaps all |
| 1262 * *exactly* match comparisonBitmap. |
| 1263 * |
| 1264 * Returns all errors encountered while doing so. |
| 1265 */ |
| 1266 ErrorBitfield run_multiple_modes(GMMain &gmmain, GM *gm, const ConfigData &compa
reConfig, |
| 1267 const SkBitmap &comparisonBitmap) { |
| 1268 SkTDArray<SkScalar> tileGridReplayScales; |
| 1269 *tileGridReplayScales.append() = SK_Scalar1; // By default only test at scal
e 1.0 |
| 1270 if (FLAGS_tileGridReplayScales.count() > 0) { |
| 1271 tileGridReplayScales.reset(); |
| 1272 for (int i = 0; i < FLAGS_tileGridReplayScales.count(); i++) { |
| 1273 double val = atof(FLAGS_tileGridReplayScales[i]); |
| 1274 if (0 < val) { |
| 1275 *tileGridReplayScales.append() = SkDoubleToScalar(val); |
| 1276 } |
| 1277 } |
| 1278 if (0 == tileGridReplayScales.count()) { |
| 1279 // Should have at least one scale |
| 1280 gm_fprintf(stderr, "--tileGridReplayScales requires at least one sca
le.\n"); |
| 1281 return -1; |
| 1282 } |
| 1283 } |
| 1284 |
| 1285 ErrorBitfield errorsForAllModes = kEmptyErrorBitfield; |
| 1286 uint32_t gmFlags = gm->getFlags(); |
| 1287 |
| 1288 // run the picture centric GM steps |
| 1289 if (!(gmFlags & GM::kSkipPicture_Flag)) { |
| 1290 |
| 1291 ErrorBitfield pictErrors = kEmptyErrorBitfield; |
| 1292 |
| 1293 //SkAutoTUnref<SkPicture> pict(generate_new_picture(gm)); |
| 1294 SkPicture* pict = gmmain.generate_new_picture(gm, kNone_BbhType, 0); |
| 1295 SkAutoUnref aur(pict); |
| 1296 |
| 1297 if (FLAGS_replay) { |
| 1298 SkBitmap bitmap; |
| 1299 gmmain.generate_image_from_picture(gm, compareConfig, pict, &bitmap)
; |
| 1300 pictErrors |= gmmain.compare_test_results_to_reference_bitmap( |
| 1301 gm, compareConfig, "-replay", bitmap, &comparisonBitmap); |
| 1302 } |
| 1303 |
| 1304 if ((kEmptyErrorBitfield == pictErrors) && FLAGS_serialize) { |
| 1305 SkPicture* repict = gmmain.stream_to_new_picture(*pict); |
| 1306 SkAutoUnref aurr(repict); |
| 1307 |
| 1308 SkBitmap bitmap; |
| 1309 gmmain.generate_image_from_picture(gm, compareConfig, repict, &bitma
p); |
| 1310 pictErrors |= gmmain.compare_test_results_to_reference_bitmap( |
| 1311 gm, compareConfig, "-serialize", bitmap, &comparisonBitmap); |
| 1312 } |
| 1313 |
| 1314 if (FLAGS_writePicturePath.count() == 1) { |
| 1315 const char* pictureSuffix = "skp"; |
| 1316 SkString path = make_filename(FLAGS_writePicturePath[0], "", |
| 1317 gm->shortName(), pictureSuffix); |
| 1318 SkFILEWStream stream(path.c_str()); |
| 1319 pict->serialize(&stream); |
| 1320 } |
| 1321 |
| 1322 errorsForAllModes |= pictErrors; |
| 1323 } |
| 1324 |
| 1325 // TODO: add a test in which the RTree rendering results in a |
| 1326 // different bitmap than the standard rendering. It should |
| 1327 // show up as failed in the JSON summary, and should be listed |
| 1328 // in the stdout also. |
| 1329 if (!(gmFlags & GM::kSkipPicture_Flag) && FLAGS_rtree) { |
| 1330 SkPicture* pict = gmmain.generate_new_picture( |
| 1331 gm, kRTree_BbhType, SkPicture::kUsePathBoundsForClip_RecordingFlag); |
| 1332 SkAutoUnref aur(pict); |
| 1333 SkBitmap bitmap; |
| 1334 gmmain.generate_image_from_picture(gm, compareConfig, pict, &bitmap); |
| 1335 errorsForAllModes |= gmmain.compare_test_results_to_reference_bitmap( |
| 1336 gm, compareConfig, "-rtree", bitmap, &comparisonBitmap); |
| 1337 } |
| 1338 |
| 1339 if (!(gmFlags & GM::kSkipPicture_Flag) && FLAGS_tileGrid) { |
| 1340 for(int scaleIndex = 0; scaleIndex < tileGridReplayScales.count(); ++sca
leIndex) { |
| 1341 SkScalar replayScale = tileGridReplayScales[scaleIndex]; |
| 1342 if ((gmFlags & GM::kSkipScaledReplay_Flag) && replayScale != 1) { |
| 1343 continue; |
| 1344 } |
| 1345 // We record with the reciprocal scale to obtain a replay |
| 1346 // result that can be validated against comparisonBitmap. |
| 1347 SkScalar recordScale = SkScalarInvert(replayScale); |
| 1348 SkPicture* pict = gmmain.generate_new_picture( |
| 1349 gm, kTileGrid_BbhType, SkPicture::kUsePathBoundsForClip_Recordin
gFlag, recordScale); |
| 1350 SkAutoUnref aur(pict); |
| 1351 SkBitmap bitmap; |
| 1352 gmmain.generate_image_from_picture(gm, compareConfig, pict, &bitmap,
replayScale); |
| 1353 SkString suffix("-tilegrid"); |
| 1354 if (SK_Scalar1 != replayScale) { |
| 1355 suffix += "-scale-"; |
| 1356 suffix.appendScalar(replayScale); |
| 1357 } |
| 1358 errorsForAllModes |= gmmain.compare_test_results_to_reference_bitmap
( |
| 1359 gm, compareConfig, suffix.c_str(), bitmap, &comparisonBitmap); |
| 1360 } |
| 1361 } |
| 1362 |
| 1363 // run the pipe centric GM steps |
| 1364 if (!(gmFlags & GM::kSkipPipe_Flag)) { |
| 1365 |
| 1366 ErrorBitfield pipeErrors = kEmptyErrorBitfield; |
| 1367 |
| 1368 if (FLAGS_pipe) { |
| 1369 pipeErrors |= gmmain.test_pipe_playback(gm, compareConfig, compariso
nBitmap); |
| 1370 } |
| 1371 |
| 1372 if ((kEmptyErrorBitfield == pipeErrors) && |
| 1373 FLAGS_tiledPipe && !(gmFlags & GM::kSkipTiled_Flag)) { |
| 1374 pipeErrors |= gmmain.test_tiled_pipe_playback(gm, compareConfig, com
parisonBitmap); |
| 1375 } |
| 1376 |
| 1377 errorsForAllModes |= pipeErrors; |
| 1378 } |
| 1379 return errorsForAllModes; |
| 1380 } |
| 1381 |
1143 int tool_main(int argc, char** argv); | 1382 int tool_main(int argc, char** argv); |
1144 int tool_main(int argc, char** argv) { | 1383 int tool_main(int argc, char** argv) { |
1145 | 1384 |
1146 #if SK_ENABLE_INST_COUNT | 1385 #if SK_ENABLE_INST_COUNT |
1147 gPrintInstCount = true; | 1386 gPrintInstCount = true; |
1148 #endif | 1387 #endif |
1149 | 1388 |
1150 SkGraphics::Init(); | 1389 SkGraphics::Init(); |
1151 // we don't need to see this during a run | 1390 // we don't need to see this during a run |
1152 gSkSuppressFontCachePurgeSpew = true; | 1391 gSkSuppressFontCachePurgeSpew = true; |
1153 | 1392 |
1154 setSystemPreferences(); | 1393 setSystemPreferences(); |
1155 GMMain gmmain; | 1394 GMMain gmmain; |
1156 | 1395 |
1157 SkTDArray<size_t> configs; | 1396 SkTDArray<size_t> configs; |
1158 SkTDArray<size_t> excludeConfigs; | 1397 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; | 1398 bool userConfig = false; |
1162 | 1399 |
1163 SkString usage; | 1400 SkString usage; |
1164 usage.printf("Run the golden master tests.\n"); | 1401 usage.printf("Run the golden master tests.\n"); |
1165 SkFlags::SetUsage(usage.c_str()); | 1402 SkFlags::SetUsage(usage.c_str()); |
1166 SkFlags::ParseCommandLine(argc, argv); | 1403 SkFlags::ParseCommandLine(argc, argv); |
1167 | 1404 |
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; | 1405 gmmain.fUseFileHierarchy = FLAGS_hierarchy; |
1185 if (FLAGS_mismatchPath.count() == 1) { | 1406 if (FLAGS_mismatchPath.count() == 1) { |
1186 gmmain.fMismatchPath = FLAGS_mismatchPath[0]; | 1407 gmmain.fMismatchPath = FLAGS_mismatchPath[0]; |
1187 } | 1408 } |
1188 | 1409 |
1189 for (int i = 0; i < FLAGS_config.count(); i++) { | 1410 for (int i = 0; i < FLAGS_config.count(); i++) { |
1190 int index = findConfig(FLAGS_config[i]); | 1411 int index = findConfig(FLAGS_config[i]); |
1191 if (index >= 0) { | 1412 if (index >= 0) { |
1192 appendUnique<size_t>(&configs, index); | 1413 appendUnique<size_t>(&configs, index); |
1193 userConfig = true; | 1414 userConfig = true; |
1194 } else { | 1415 } else { |
1195 gm_fprintf(stderr, "unrecognized config %s\n", FLAGS_config[i]); | 1416 gm_fprintf(stderr, "unrecognized config %s\n", FLAGS_config[i]); |
1196 return -1; | 1417 return -1; |
1197 } | 1418 } |
1198 } | 1419 } |
1199 | 1420 |
1200 for (int i = 0; i < FLAGS_excludeConfig.count(); i++) { | 1421 for (int i = 0; i < FLAGS_excludeConfig.count(); i++) { |
1201 int index = findConfig(FLAGS_excludeConfig[i]); | 1422 int index = findConfig(FLAGS_excludeConfig[i]); |
1202 if (index >= 0) { | 1423 if (index >= 0) { |
1203 *excludeConfigs.append() = index; | 1424 *excludeConfigs.append() = index; |
1204 } else { | 1425 } else { |
1205 gm_fprintf(stderr, "unrecognized excludeConfig %s\n", FLAGS_excludeC
onfig[i]); | 1426 gm_fprintf(stderr, "unrecognized excludeConfig %s\n", FLAGS_excludeC
onfig[i]); |
1206 return -1; | 1427 return -1; |
1207 } | 1428 } |
1208 } | 1429 } |
1209 | 1430 |
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; | 1431 int moduloRemainder = -1; |
1226 int moduloDivisor = -1; | 1432 int moduloDivisor = -1; |
1227 | 1433 |
1228 if (FLAGS_modulo.count() == 2) { | 1434 if (FLAGS_modulo.count() == 2) { |
1229 moduloRemainder = atoi(FLAGS_modulo[0]); | 1435 moduloRemainder = atoi(FLAGS_modulo[0]); |
1230 moduloDivisor = atoi(FLAGS_modulo[1]); | 1436 moduloDivisor = atoi(FLAGS_modulo[1]); |
1231 if (moduloRemainder < 0 || moduloDivisor <= 0 || moduloRemainder >= modu
loDivisor) { | 1437 if (moduloRemainder < 0 || moduloDivisor <= 0 || moduloRemainder >= modu
loDivisor) { |
1232 gm_fprintf(stderr, "invalid modulo values."); | 1438 gm_fprintf(stderr, "invalid modulo values."); |
1233 return -1; | 1439 return -1; |
1234 } | 1440 } |
(...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1364 if (skip_name(FLAGS_match, shortName)) { | 1570 if (skip_name(FLAGS_match, shortName)) { |
1365 SkDELETE(gm); | 1571 SkDELETE(gm); |
1366 continue; | 1572 continue; |
1367 } | 1573 } |
1368 | 1574 |
1369 SkISize size = gm->getISize(); | 1575 SkISize size = gm->getISize(); |
1370 gm_fprintf(stdout, "%sdrawing... %s [%d %d]\n", moduloStr.c_str(), short
Name, | 1576 gm_fprintf(stdout, "%sdrawing... %s [%d %d]\n", moduloStr.c_str(), short
Name, |
1371 size.width(), size.height()); | 1577 size.width(), size.height()); |
1372 | 1578 |
1373 ErrorBitfield testErrors = kEmptyErrorBitfield; | 1579 ErrorBitfield testErrors = kEmptyErrorBitfield; |
1374 uint32_t gmFlags = gm->getFlags(); | 1580 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 | 1581 |
1468 SkBitmap comparisonBitmap; | 1582 SkBitmap comparisonBitmap; |
1469 const ConfigData compareConfig = | 1583 const ConfigData compareConfig = |
1470 { SkBitmap::kARGB_8888_Config, kRaster_Backend, kDontCare_GLContextT
ype, 0, kRW_ConfigFlag, "comparison", false }; | 1584 { 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); | 1585 testErrors |= gmmain.generate_image(gm, compareConfig, NULL, NULL, &comp
arisonBitmap, false); |
1472 | 1586 |
1473 // run the picture centric GM steps | 1587 // TODO(epoger): only run this if gmmain.generate_image() succeeded? |
1474 if (!(gmFlags & GM::kSkipPicture_Flag)) { | 1588 // Otherwise, what are we comparing against? |
1475 | 1589 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 | 1590 |
1576 // Update overall results. | 1591 // Update overall results. |
1577 // We only tabulate the particular error types that we currently | 1592 // We only tabulate the particular error types that we currently |
1578 // care about (e.g., missing reference images). Later on, if we | 1593 // care about (e.g., missing reference images). Later on, if we |
1579 // want to also tabulate other error types, we can do so. | 1594 // want to also tabulate other error types, we can do so. |
1580 testsRun++; | 1595 testsRun++; |
1581 if (!gmmain.fExpectationsSource.get() || | 1596 if (!gmmain.fExpectationsSource.get() || |
1582 (kEmptyErrorBitfield != (kMissingExpectations_ErrorBitmask & testErr
ors))) { | 1597 (kEmptyErrorBitfield != (kMissingExpectations_ErrorBitmask & testErr
ors))) { |
1583 testsMissingReferenceImages++; | 1598 testsMissingReferenceImages++; |
1584 } | 1599 } |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1638 if (FLAGS_forceBWtext) { | 1653 if (FLAGS_forceBWtext) { |
1639 canvas->setDrawFilter(SkNEW(BWTextDrawFilter))->unref(); | 1654 canvas->setDrawFilter(SkNEW(BWTextDrawFilter))->unref(); |
1640 } | 1655 } |
1641 } | 1656 } |
1642 | 1657 |
1643 #if !defined(SK_BUILD_FOR_IOS) && !defined(SK_BUILD_FOR_NACL) | 1658 #if !defined(SK_BUILD_FOR_IOS) && !defined(SK_BUILD_FOR_NACL) |
1644 int main(int argc, char * const argv[]) { | 1659 int main(int argc, char * const argv[]) { |
1645 return tool_main(argc, (char**) argv); | 1660 return tool_main(argc, (char**) argv); |
1646 } | 1661 } |
1647 #endif | 1662 #endif |
OLD | NEW |