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 1497 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1508 } | 1508 } |
1509 | 1509 |
1510 template <typename T> void appendUnique(SkTDArray<T>* array, const T& value) { | 1510 template <typename T> void appendUnique(SkTDArray<T>* array, const T& value) { |
1511 int index = array->find(value); | 1511 int index = array->find(value); |
1512 if (index < 0) { | 1512 if (index < 0) { |
1513 *array->append() = value; | 1513 *array->append() = value; |
1514 } | 1514 } |
1515 } | 1515 } |
1516 | 1516 |
1517 /** | 1517 /** |
1518 * Run this test in a number of different configs (8888, 565, PDF, | |
1519 * etc.), confirming that the resulting bitmaps match expectations | |
1520 * (which may be different for each config). | |
1521 * | |
1522 * Returns all errors encountered while doing so. | |
1523 */ | |
1524 ErrorCombination run_multiple_configs(GMMain &gmmain, GM *gm, | |
1525 const SkTDArray<size_t> &configs, | |
1526 const SkTDArray<const PDFRasterizerData*>
&pdfRasterizers, | |
1527 GrContextFactory *grFactory); | |
1528 ErrorCombination run_multiple_configs(GMMain &gmmain, GM *gm, | |
1529 const SkTDArray<size_t> &configs, | |
1530 const SkTDArray<const PDFRasterizerData*>
&pdfRasterizers, | |
1531 GrContextFactory *grFactory) { | |
1532 const char renderModeDescriptor[] = ""; | |
1533 ErrorCombination errorsForAllConfigs; | |
1534 uint32_t gmFlags = gm->getFlags(); | |
1535 | |
1536 for (int i = 0; i < configs.count(); i++) { | |
1537 ConfigData config = gRec[configs[i]]; | |
1538 const SkString shortNamePlusConfig = gmmain.make_shortname_plus_config(g
m->shortName(), | |
1539 c
onfig.fName); | |
1540 | |
1541 // Skip any tests that we don't even need to try. | |
1542 // If any of these were skipped on a per-GM basis, record them as | |
1543 // kIntentionallySkipped. | |
1544 if (kPDF_Backend == config.fBackend) { | |
1545 if (gmFlags & GM::kSkipPDF_Flag) { | |
1546 gmmain.RecordTestResults(kIntentionallySkipped_ErrorType, shortN
amePlusConfig, | |
1547 renderModeDescriptor); | |
1548 errorsForAllConfigs.add(kIntentionallySkipped_ErrorType); | |
1549 continue; | |
1550 } | |
1551 } | |
1552 if ((gmFlags & GM::kSkip565_Flag) && | |
1553 (kRaster_Backend == config.fBackend) && | |
1554 (SkBitmap::kRGB_565_Config == config.fConfig)) { | |
1555 gmmain.RecordTestResults(kIntentionallySkipped_ErrorType, shortNameP
lusConfig, | |
1556 renderModeDescriptor); | |
1557 errorsForAllConfigs.add(kIntentionallySkipped_ErrorType); | |
1558 continue; | |
1559 } | |
1560 if (((gmFlags & GM::kSkipGPU_Flag) && kGPU_Backend == config.fBackend) |
| | |
1561 ((gmFlags & GM::kGPUOnly_Flag) && kGPU_Backend != config.fBackend))
{ | |
1562 gmmain.RecordTestResults(kIntentionallySkipped_ErrorType, shortNameP
lusConfig, | |
1563 renderModeDescriptor); | |
1564 errorsForAllConfigs.add(kIntentionallySkipped_ErrorType); | |
1565 continue; | |
1566 } | |
1567 | |
1568 // Now we know that we want to run this test and record its | |
1569 // success or failure. | |
1570 ErrorCombination errorsForThisConfig; | |
1571 GrSurface* gpuTarget = NULL; | |
1572 #if SK_SUPPORT_GPU | |
1573 SkAutoTUnref<GrSurface> auGpuTarget; | |
1574 if ((errorsForThisConfig.isEmpty()) && (kGPU_Backend == config.fBackend)
) { | |
1575 if (FLAGS_resetGpuContext) { | |
1576 grFactory->destroyContexts(); | |
1577 } | |
1578 GrContext* gr = grFactory->get(config.fGLContextType); | |
1579 bool grSuccess = false; | |
1580 if (gr) { | |
1581 // create a render target to back the device | |
1582 GrTextureDesc desc; | |
1583 desc.fConfig = kSkia8888_GrPixelConfig; | |
1584 desc.fFlags = kRenderTarget_GrTextureFlagBit; | |
1585 desc.fWidth = gm->getISize().width(); | |
1586 desc.fHeight = gm->getISize().height(); | |
1587 desc.fSampleCnt = config.fSampleCnt; | |
1588 auGpuTarget.reset(gr->createUncachedTexture(desc, NULL, 0)); | |
1589 if (NULL != auGpuTarget) { | |
1590 gpuTarget = auGpuTarget; | |
1591 grSuccess = true; | |
1592 // Set the user specified cache limits if non-default. | |
1593 size_t bytes; | |
1594 int count; | |
1595 gr->getTextureCacheLimits(&count, &bytes); | |
1596 if (DEFAULT_CACHE_VALUE != gGpuCacheSizeBytes) { | |
1597 bytes = static_cast<size_t>(gGpuCacheSizeBytes); | |
1598 } | |
1599 if (DEFAULT_CACHE_VALUE != gGpuCacheSizeCount) { | |
1600 count = gGpuCacheSizeCount; | |
1601 } | |
1602 gr->setTextureCacheLimits(count, bytes); | |
1603 } | |
1604 } | |
1605 if (!grSuccess) { | |
1606 errorsForThisConfig.add(kNoGpuContext_ErrorType); | |
1607 } | |
1608 } | |
1609 #endif | |
1610 | |
1611 SkBitmap comparisonBitmap; | |
1612 | |
1613 const char* writePath; | |
1614 if (FLAGS_writePath.count() == 1) { | |
1615 writePath = FLAGS_writePath[0]; | |
1616 } else { | |
1617 writePath = NULL; | |
1618 } | |
1619 | |
1620 if (errorsForThisConfig.isEmpty()) { | |
1621 errorsForThisConfig.add(gmmain.test_drawing(gm, config, pdfRasterize
rs, | |
1622 writePath, gpuTarget, | |
1623 &comparisonBitmap)); | |
1624 gmmain.RecordTestResults(errorsForThisConfig, shortNamePlusConfig, "
"); | |
1625 } | |
1626 | |
1627 if (FLAGS_deferred && errorsForThisConfig.isEmpty() && | |
1628 (kGPU_Backend == config.fBackend || kRaster_Backend == config.fBacke
nd)) { | |
1629 errorsForThisConfig.add(gmmain.test_deferred_drawing(gm, config, com
parisonBitmap, | |
1630 gpuTarget)); | |
1631 } | |
1632 | |
1633 errorsForAllConfigs.add(errorsForThisConfig); | |
1634 } | |
1635 return errorsForAllConfigs; | |
1636 } | |
1637 | |
1638 /** | |
1639 * Run this test in a number of different drawing modes (pipe, | 1518 * Run this test in a number of different drawing modes (pipe, |
1640 * deferred, tiled, etc.), confirming that the resulting bitmaps all | 1519 * deferred, tiled, etc.), confirming that the resulting bitmaps all |
1641 * *exactly* match comparisonBitmap. | 1520 * *exactly* match comparisonBitmap. |
1642 * | 1521 * |
1643 * Returns all errors encountered while doing so. | 1522 * Returns all errors encountered while doing so. |
1644 */ | 1523 */ |
1645 ErrorCombination run_multiple_modes(GMMain &gmmain, GM *gm, const ConfigData &co
mpareConfig, | 1524 ErrorCombination run_multiple_modes(GMMain &gmmain, GM *gm, const ConfigData &co
mpareConfig, |
1646 const SkBitmap &comparisonBitmap, | 1525 const SkBitmap &comparisonBitmap, |
1647 const SkTDArray<SkScalar> &tileGridReplaySca
les); | 1526 const SkTDArray<SkScalar> &tileGridReplaySca
les); |
1648 ErrorCombination run_multiple_modes(GMMain &gmmain, GM *gm, const ConfigData &co
mpareConfig, | 1527 ErrorCombination run_multiple_modes(GMMain &gmmain, GM *gm, const ConfigData &co
mpareConfig, |
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1761 errorsForAllModes.add(gmmain.test_pipe_playback(gm, compareConfig, compa
risonBitmap, | 1640 errorsForAllModes.add(gmmain.test_pipe_playback(gm, compareConfig, compa
risonBitmap, |
1762 FLAGS_simulatePipePlayba
ckFailure)); | 1641 FLAGS_simulatePipePlayba
ckFailure)); |
1763 if (FLAGS_tiledPipe) { | 1642 if (FLAGS_tiledPipe) { |
1764 errorsForAllModes.add(gmmain.test_tiled_pipe_playback(gm, compareCon
fig, | 1643 errorsForAllModes.add(gmmain.test_tiled_pipe_playback(gm, compareCon
fig, |
1765 comparisonBitm
ap)); | 1644 comparisonBitm
ap)); |
1766 } | 1645 } |
1767 } | 1646 } |
1768 return errorsForAllModes; | 1647 return errorsForAllModes; |
1769 } | 1648 } |
1770 | 1649 |
| 1650 |
| 1651 /** |
| 1652 * Run this test in a number of different configs (8888, 565, PDF, |
| 1653 * etc.), confirming that the resulting bitmaps match expectations |
| 1654 * (which may be different for each config). |
| 1655 * |
| 1656 * Returns all errors encountered while doing so. |
| 1657 */ |
| 1658 ErrorCombination run_multiple_configs(GMMain &gmmain, GM *gm, |
| 1659 const SkTDArray<size_t> &configs, |
| 1660 const SkTDArray<const PDFRasterizerData*>
&pdfRasterizers, |
| 1661 const SkTDArray<SkScalar> &tileGridReplayS
cales, |
| 1662 GrContextFactory *grFactory); |
| 1663 ErrorCombination run_multiple_configs(GMMain &gmmain, GM *gm, |
| 1664 const SkTDArray<size_t> &configs, |
| 1665 const SkTDArray<const PDFRasterizerData*>
&pdfRasterizers, |
| 1666 const SkTDArray<SkScalar> &tileGridReplayS
cales, |
| 1667 GrContextFactory *grFactory) { |
| 1668 const char renderModeDescriptor[] = ""; |
| 1669 ErrorCombination errorsForAllConfigs; |
| 1670 uint32_t gmFlags = gm->getFlags(); |
| 1671 |
| 1672 for (int i = 0; i < configs.count(); i++) { |
| 1673 ConfigData config = gRec[configs[i]]; |
| 1674 const SkString shortNamePlusConfig = gmmain.make_shortname_plus_config(g
m->shortName(), |
| 1675 c
onfig.fName); |
| 1676 |
| 1677 // Skip any tests that we don't even need to try. |
| 1678 // If any of these were skipped on a per-GM basis, record them as |
| 1679 // kIntentionallySkipped. |
| 1680 if (kPDF_Backend == config.fBackend) { |
| 1681 if (gmFlags & GM::kSkipPDF_Flag) { |
| 1682 gmmain.RecordTestResults(kIntentionallySkipped_ErrorType, shortN
amePlusConfig, |
| 1683 renderModeDescriptor); |
| 1684 errorsForAllConfigs.add(kIntentionallySkipped_ErrorType); |
| 1685 continue; |
| 1686 } |
| 1687 } |
| 1688 if ((gmFlags & GM::kSkip565_Flag) && |
| 1689 (kRaster_Backend == config.fBackend) && |
| 1690 (SkBitmap::kRGB_565_Config == config.fConfig)) { |
| 1691 gmmain.RecordTestResults(kIntentionallySkipped_ErrorType, shortNameP
lusConfig, |
| 1692 renderModeDescriptor); |
| 1693 errorsForAllConfigs.add(kIntentionallySkipped_ErrorType); |
| 1694 continue; |
| 1695 } |
| 1696 if (((gmFlags & GM::kSkipGPU_Flag) && kGPU_Backend == config.fBackend) |
| |
| 1697 ((gmFlags & GM::kGPUOnly_Flag) && kGPU_Backend != config.fBackend))
{ |
| 1698 gmmain.RecordTestResults(kIntentionallySkipped_ErrorType, shortNameP
lusConfig, |
| 1699 renderModeDescriptor); |
| 1700 errorsForAllConfigs.add(kIntentionallySkipped_ErrorType); |
| 1701 continue; |
| 1702 } |
| 1703 |
| 1704 // Now we know that we want to run this test and record its |
| 1705 // success or failure. |
| 1706 ErrorCombination errorsForThisConfig; |
| 1707 GrSurface* gpuTarget = NULL; |
| 1708 #if SK_SUPPORT_GPU |
| 1709 SkAutoTUnref<GrSurface> auGpuTarget; |
| 1710 if ((errorsForThisConfig.isEmpty()) && (kGPU_Backend == config.fBackend)
) { |
| 1711 if (FLAGS_resetGpuContext) { |
| 1712 grFactory->destroyContexts(); |
| 1713 } |
| 1714 GrContext* gr = grFactory->get(config.fGLContextType); |
| 1715 bool grSuccess = false; |
| 1716 if (gr) { |
| 1717 // create a render target to back the device |
| 1718 GrTextureDesc desc; |
| 1719 desc.fConfig = kSkia8888_GrPixelConfig; |
| 1720 desc.fFlags = kRenderTarget_GrTextureFlagBit; |
| 1721 desc.fWidth = gm->getISize().width(); |
| 1722 desc.fHeight = gm->getISize().height(); |
| 1723 desc.fSampleCnt = config.fSampleCnt; |
| 1724 auGpuTarget.reset(gr->createUncachedTexture(desc, NULL, 0)); |
| 1725 if (NULL != auGpuTarget) { |
| 1726 gpuTarget = auGpuTarget; |
| 1727 grSuccess = true; |
| 1728 // Set the user specified cache limits if non-default. |
| 1729 size_t bytes; |
| 1730 int count; |
| 1731 gr->getTextureCacheLimits(&count, &bytes); |
| 1732 if (DEFAULT_CACHE_VALUE != gGpuCacheSizeBytes) { |
| 1733 bytes = static_cast<size_t>(gGpuCacheSizeBytes); |
| 1734 } |
| 1735 if (DEFAULT_CACHE_VALUE != gGpuCacheSizeCount) { |
| 1736 count = gGpuCacheSizeCount; |
| 1737 } |
| 1738 gr->setTextureCacheLimits(count, bytes); |
| 1739 } |
| 1740 } |
| 1741 if (!grSuccess) { |
| 1742 errorsForThisConfig.add(kNoGpuContext_ErrorType); |
| 1743 } |
| 1744 } |
| 1745 #endif |
| 1746 |
| 1747 SkBitmap comparisonBitmap; |
| 1748 |
| 1749 const char* writePath; |
| 1750 if (FLAGS_writePath.count() == 1) { |
| 1751 writePath = FLAGS_writePath[0]; |
| 1752 } else { |
| 1753 writePath = NULL; |
| 1754 } |
| 1755 |
| 1756 if (errorsForThisConfig.isEmpty()) { |
| 1757 errorsForThisConfig.add(gmmain.test_drawing(gm, config, pdfRasterize
rs, |
| 1758 writePath, gpuTarget, |
| 1759 &comparisonBitmap)); |
| 1760 gmmain.RecordTestResults(errorsForThisConfig, shortNamePlusConfig, "
"); |
| 1761 } |
| 1762 |
| 1763 // TODO: run only if gmmain.test_drawing succeeded. |
| 1764 if (kRaster_Backend == config.fBackend) { |
| 1765 run_multiple_modes(gmmain, gm, config, comparisonBitmap, tileGridRep
layScales); |
| 1766 } |
| 1767 |
| 1768 if (FLAGS_deferred && errorsForThisConfig.isEmpty() && |
| 1769 (kGPU_Backend == config.fBackend || kRaster_Backend == config.fBacke
nd)) { |
| 1770 errorsForThisConfig.add(gmmain.test_deferred_drawing(gm, config, com
parisonBitmap, |
| 1771 gpuTarget)); |
| 1772 } |
| 1773 |
| 1774 errorsForAllConfigs.add(errorsForThisConfig); |
| 1775 } |
| 1776 return errorsForAllConfigs; |
| 1777 } |
| 1778 |
| 1779 |
1771 /** | 1780 /** |
1772 * Read individual lines from a file, pushing them into the given array. | 1781 * Read individual lines from a file, pushing them into the given array. |
1773 * | 1782 * |
1774 * @param filename path to the file to read | 1783 * @param filename path to the file to read |
1775 * @param lines array of strings to add the lines to | 1784 * @param lines array of strings to add the lines to |
1776 * @returns true if able to read lines from the file | 1785 * @returns true if able to read lines from the file |
1777 */ | 1786 */ |
1778 static bool read_lines_from_file(const char* filename, SkTArray<SkString> &lines
) { | 1787 static bool read_lines_from_file(const char* filename, SkTArray<SkString> &lines
) { |
1779 SkAutoTUnref<SkStream> streamWrapper(SkStream::NewFromFile(filename)); | 1788 SkAutoTUnref<SkStream> streamWrapper(SkStream::NewFromFile(filename)); |
1780 SkStream *stream = streamWrapper.get(); | 1789 SkStream *stream = streamWrapper.get(); |
(...skipping 497 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2278 | 2287 |
2279 if (SkCommandLineFlags::ShouldSkip(FLAGS_match, shortName)) { | 2288 if (SkCommandLineFlags::ShouldSkip(FLAGS_match, shortName)) { |
2280 continue; | 2289 continue; |
2281 } | 2290 } |
2282 | 2291 |
2283 gmsRun++; | 2292 gmsRun++; |
2284 SkISize size = gm->getISize(); | 2293 SkISize size = gm->getISize(); |
2285 gm_fprintf(stdout, "%sdrawing... %s [%d %d]\n", moduloStr.c_str(), short
Name, | 2294 gm_fprintf(stdout, "%sdrawing... %s [%d %d]\n", moduloStr.c_str(), short
Name, |
2286 size.width(), size.height()); | 2295 size.width(), size.height()); |
2287 | 2296 |
2288 run_multiple_configs(gmmain, gm, configs, pdfRasterizers, grFactory); | 2297 run_multiple_configs(gmmain, gm, configs, pdfRasterizers, tileGridReplay
Scales, grFactory); |
2289 | |
2290 SkBitmap comparisonBitmap; | |
2291 const ConfigData compareConfig = | |
2292 { SkBitmap::kARGB_8888_Config, kRaster_Backend, kDontCare_GLContextT
ype, 0, kRW_ConfigFlag, "comparison", false }; | |
2293 gmmain.generate_image(gm, compareConfig, NULL, &comparisonBitmap, false)
; | |
2294 | |
2295 // TODO(epoger): only run this if gmmain.generate_image() succeeded? | |
2296 // Otherwise, what are we comparing against? | |
2297 run_multiple_modes(gmmain, gm, compareConfig, comparisonBitmap, tileGrid
ReplayScales); | |
2298 } | 2298 } |
2299 | 2299 |
2300 SkTArray<SkString> modes; | 2300 SkTArray<SkString> modes; |
2301 gmmain.GetRenderModesEncountered(modes); | 2301 gmmain.GetRenderModesEncountered(modes); |
2302 bool reportError = false; | 2302 bool reportError = false; |
2303 if (gmmain.NumSignificantErrors() > 0) { | 2303 if (gmmain.NumSignificantErrors() > 0) { |
2304 reportError = true; | 2304 reportError = true; |
2305 } | 2305 } |
2306 int expectedNumberOfTests = gmsRun * (configs.count() + modes.count()); | 2306 |
| 2307 // We test every GM against every config, and for every raster config also t
est every mode. |
| 2308 int rasterConfigs = 0; |
| 2309 for (int i = 0; i < configs.count(); i++) { |
| 2310 if (gRec[configs[i]].fBackend == kRaster_Backend) { |
| 2311 rasterConfigs++; |
| 2312 } |
| 2313 } |
| 2314 const int expectedNumberOfTests = gmsRun * configs.count() |
| 2315 + gmsRun * rasterConfigs * modes.count(); |
2307 | 2316 |
2308 // Output summary to stdout. | 2317 // Output summary to stdout. |
2309 if (FLAGS_verbose) { | 2318 if (FLAGS_verbose) { |
2310 gm_fprintf(stdout, "Ran %d GMs\n", gmsRun); | 2319 gm_fprintf(stdout, "Ran %d GMs\n", gmsRun); |
2311 gm_fprintf(stdout, "... over %2d configs [%s]\n", configs.count(), | 2320 gm_fprintf(stdout, "... over %2d configs [%s]\n", configs.count(), |
2312 list_all_config_names(configs).c_str()); | 2321 list_all_config_names(configs).c_str()); |
2313 gm_fprintf(stdout, "... and %2d modes [%s]\n", modes.count(), list_al
l(modes).c_str()); | 2322 gm_fprintf(stdout, "... and %2d modes [%s]\n", modes.count(), list_al
l(modes).c_str()); |
2314 gm_fprintf(stdout, "... so there should be a total of %d tests.\n", expe
ctedNumberOfTests); | 2323 gm_fprintf(stdout, "... so there should be a total of %d tests.\n", expe
ctedNumberOfTests); |
2315 } | 2324 } |
2316 gmmain.ListErrors(FLAGS_verbose); | 2325 gmmain.ListErrors(FLAGS_verbose); |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2362 if (FLAGS_forceBWtext) { | 2371 if (FLAGS_forceBWtext) { |
2363 canvas->setDrawFilter(SkNEW(BWTextDrawFilter))->unref(); | 2372 canvas->setDrawFilter(SkNEW(BWTextDrawFilter))->unref(); |
2364 } | 2373 } |
2365 } | 2374 } |
2366 | 2375 |
2367 #if !defined(SK_BUILD_FOR_IOS) && !defined(SK_BUILD_FOR_NACL) | 2376 #if !defined(SK_BUILD_FOR_IOS) && !defined(SK_BUILD_FOR_NACL) |
2368 int main(int argc, char * const argv[]) { | 2377 int main(int argc, char * const argv[]) { |
2369 return tool_main(argc, (char**) argv); | 2378 return tool_main(argc, (char**) argv); |
2370 } | 2379 } |
2371 #endif | 2380 #endif |
OLD | NEW |