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 696 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
707 * results to the JSON summary. (This is so that we will always | 707 * results to the JSON summary. (This is so that we will always |
708 * report errors across rendering modes, such as pipe vs tiled. | 708 * report errors across rendering modes, such as pipe vs tiled. |
709 * See https://codereview.chromium.org/13650002/ ) | 709 * See https://codereview.chromium.org/13650002/ ) |
710 */ | 710 */ |
711 ErrorCombination compare_to_expectations(Expectations expectations, | 711 ErrorCombination compare_to_expectations(Expectations expectations, |
712 const SkBitmap& actualBitmap, | 712 const SkBitmap& actualBitmap, |
713 const SkString& baseNameString, | 713 const SkString& baseNameString, |
714 const char renderModeDescriptor[], | 714 const char renderModeDescriptor[], |
715 bool addToJsonSummary) { | 715 bool addToJsonSummary) { |
716 ErrorCombination errors; | 716 ErrorCombination errors; |
717 SkHashDigest actualBitmapHash; | 717 BITMAP_HASH_TYPE actualBitmapHash; |
718 // TODO(epoger): Better handling for error returned by ComputeDigest()? | |
719 // For now, we just report a digest of 0 in error cases, like before. | |
720 if (!SkBitmapHasher::ComputeDigest(actualBitmap, &actualBitmapHash)) { | 718 if (!SkBitmapHasher::ComputeDigest(actualBitmap, &actualBitmapHash)) { |
721 actualBitmapHash = 0; | 719 // TODO(epoger): Better handling for error returned by ComputeDigest
()? |
| 720 // For now, we just leave actualBitmapHash empty. |
722 } | 721 } |
723 SkString completeNameString = baseNameString; | 722 SkString completeNameString = baseNameString; |
724 completeNameString.append(renderModeDescriptor); | 723 completeNameString.append(renderModeDescriptor); |
725 const char* completeName = completeNameString.c_str(); | 724 const char* completeName = completeNameString.c_str(); |
726 | 725 |
727 if (expectations.empty()) { | 726 if (expectations.empty()) { |
728 errors.add(kMissingExpectations_ErrorType); | 727 errors.add(kMissingExpectations_ErrorType); |
729 } else if (!expectations.match(actualBitmapHash)) { | 728 } else if (!expectations.match(actualBitmapHash)) { |
730 addToJsonSummary = true; | 729 addToJsonSummary = true; |
731 // The error mode we record depends on whether this was running | 730 // The error mode we record depends on whether this was running |
(...skipping 29 matching lines...) Expand all Loading... |
761 } | 760 } |
762 | 761 |
763 return errors; | 762 return errors; |
764 } | 763 } |
765 | 764 |
766 /** | 765 /** |
767 * Add this result to the appropriate JSON collection of actual results, | 766 * Add this result to the appropriate JSON collection of actual results, |
768 * depending on status. | 767 * depending on status. |
769 */ | 768 */ |
770 void add_actual_results_to_json_summary(const char testName[], | 769 void add_actual_results_to_json_summary(const char testName[], |
771 const SkHashDigest& actualBitmapHash
, | 770 const BITMAP_HASH_TYPE& actualBitmap
Hash, |
772 ErrorCombination result, | 771 ErrorCombination result, |
773 bool ignoreFailure) { | 772 bool ignoreFailure) { |
774 Json::Value actualResults; | 773 Json::Value actualResults; |
775 actualResults[kJsonKey_ActualResults_AnyStatus_Checksum] = | 774 actualResults[kJsonKey_ActualResults_AnyStatus_Checksum] = |
776 asJsonValue(actualBitmapHash); | 775 asJsonValue(actualBitmapHash); |
777 if (result.isEmpty()) { | 776 if (result.isEmpty()) { |
778 this->fJsonActualResults_Succeeded[testName] = actualResults; | 777 this->fJsonActualResults_Succeeded[testName] = actualResults; |
779 } else { | 778 } else { |
780 if (ignoreFailure) { | 779 if (ignoreFailure) { |
781 // TODO: Once we have added the ability to compare | 780 // TODO: Once we have added the ability to compare |
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
857 * hash digest of actualBitmap, which *has* been run through | 856 * hash digest of actualBitmap, which *has* been run through |
858 * force_all_opaque(). | 857 * force_all_opaque(). |
859 * See comments above complete_bitmap() for more detail. | 858 * See comments above complete_bitmap() for more detail. |
860 */ | 859 */ |
861 Expectations expectations = expectationsSource->get(name.c_str()); | 860 Expectations expectations = expectationsSource->get(name.c_str()); |
862 errors.add(compare_to_expectations(expectations, actualBitmap, | 861 errors.add(compare_to_expectations(expectations, actualBitmap, |
863 name, "", true)); | 862 name, "", true)); |
864 } else { | 863 } else { |
865 // If we are running without expectations, we still want to | 864 // If we are running without expectations, we still want to |
866 // record the actual results. | 865 // record the actual results. |
867 SkHashDigest actualBitmapHash; | 866 BITMAP_HASH_TYPE actualBitmapHash; |
868 // TODO(epoger): Better handling for error returned by ComputeDigest
()? | |
869 // For now, we just report a digest of 0 in error cases, like before
. | |
870 if (!SkBitmapHasher::ComputeDigest(actualBitmap, &actualBitmapHash))
{ | 867 if (!SkBitmapHasher::ComputeDigest(actualBitmap, &actualBitmapHash))
{ |
871 actualBitmapHash = 0; | 868 // TODO(epoger): Better handling for error returned by ComputeDi
gest()? |
| 869 // For now, we just leave actualBitmapHash empty. |
872 } | 870 } |
873 add_actual_results_to_json_summary(name.c_str(), actualBitmapHash, | 871 add_actual_results_to_json_summary(name.c_str(), actualBitmapHash, |
874 ErrorCombination(kMissingExpectat
ions_ErrorType), | 872 ErrorCombination(kMissingExpectat
ions_ErrorType), |
875 false); | 873 false); |
876 RecordTestResults(ErrorCombination(kMissingExpectations_ErrorType),
name, ""); | 874 RecordTestResults(ErrorCombination(kMissingExpectations_ErrorType),
name, ""); |
877 } | 875 } |
878 | 876 |
879 // TODO: Consider moving this into compare_to_expectations(), | 877 // TODO: Consider moving this into compare_to_expectations(), |
880 // similar to fMismatchPath... for now, we don't do that, because | 878 // similar to fMismatchPath... for now, we don't do that, because |
881 // we don't want to write out the actual bitmaps for all | 879 // we don't want to write out the actual bitmaps for all |
(...skipping 702 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1584 if (i > 0) { | 1582 if (i > 0) { |
1585 total.append(", "); | 1583 total.append(", "); |
1586 } | 1584 } |
1587 total.append("\""); | 1585 total.append("\""); |
1588 total.append(gRec[configs[i]].fName); | 1586 total.append(gRec[configs[i]].fName); |
1589 total.append("\""); | 1587 total.append("\""); |
1590 } | 1588 } |
1591 return total; | 1589 return total; |
1592 } | 1590 } |
1593 | 1591 |
| 1592 // Set this temporary macro to print out timing info. |
| 1593 #define EPOGER_TIMER |
| 1594 #ifdef EPOGER_TIMER |
| 1595 #include "SkTime.h" |
| 1596 #endif |
| 1597 |
1594 int tool_main(int argc, char** argv); | 1598 int tool_main(int argc, char** argv); |
1595 int tool_main(int argc, char** argv) { | 1599 int tool_main(int argc, char** argv) { |
1596 | 1600 |
1597 #if SK_ENABLE_INST_COUNT | 1601 #if SK_ENABLE_INST_COUNT |
1598 gPrintInstCount = true; | 1602 gPrintInstCount = true; |
1599 #endif | 1603 #endif |
1600 | 1604 |
| 1605 #ifdef EPOGER_TIMER |
| 1606 SkMSec startTime = SkTime::GetMSecs(); |
| 1607 #endif |
| 1608 |
1601 SkGraphics::Init(); | 1609 SkGraphics::Init(); |
1602 // we don't need to see this during a run | 1610 // we don't need to see this during a run |
1603 gSkSuppressFontCachePurgeSpew = true; | 1611 gSkSuppressFontCachePurgeSpew = true; |
1604 | 1612 |
1605 setSystemPreferences(); | 1613 setSystemPreferences(); |
1606 GMMain gmmain; | 1614 GMMain gmmain; |
1607 | 1615 |
1608 SkTDArray<size_t> configs; | 1616 SkTDArray<size_t> configs; |
1609 SkTDArray<size_t> excludeConfigs; | 1617 SkTDArray<size_t> excludeConfigs; |
1610 bool userConfig = false; | 1618 bool userConfig = false; |
(...skipping 228 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1839 } | 1847 } |
1840 | 1848 |
1841 SkTArray<SkString> modes; | 1849 SkTArray<SkString> modes; |
1842 gmmain.GetRenderModesEncountered(modes); | 1850 gmmain.GetRenderModesEncountered(modes); |
1843 bool reportError = false; | 1851 bool reportError = false; |
1844 if (gmmain.NumSignificantErrors() > 0) { | 1852 if (gmmain.NumSignificantErrors() > 0) { |
1845 reportError = true; | 1853 reportError = true; |
1846 } | 1854 } |
1847 int expectedNumberOfTests = gmsRun * (configs.count() + modes.count()); | 1855 int expectedNumberOfTests = gmsRun * (configs.count() + modes.count()); |
1848 | 1856 |
| 1857 #ifdef EPOGER_TIMER |
| 1858 SkMSec middleTime = SkTime::GetMSecs(); |
| 1859 #endif |
| 1860 |
1849 // Output summary to stdout. | 1861 // Output summary to stdout. |
1850 if (FLAGS_verbose) { | 1862 if (FLAGS_verbose) { |
1851 gm_fprintf(stdout, "Ran %d GMs\n", gmsRun); | 1863 gm_fprintf(stdout, "Ran %d GMs\n", gmsRun); |
1852 gm_fprintf(stdout, "... over %2d configs [%s]\n", configs.count(), | 1864 gm_fprintf(stdout, "... over %2d configs [%s]\n", configs.count(), |
1853 list_all_config_names(configs).c_str()); | 1865 list_all_config_names(configs).c_str()); |
1854 gm_fprintf(stdout, "... and %2d modes [%s]\n", modes.count(), list_al
l(modes).c_str()); | 1866 gm_fprintf(stdout, "... and %2d modes [%s]\n", modes.count(), list_al
l(modes).c_str()); |
1855 gm_fprintf(stdout, "... so there should be a total of %d tests.\n", expe
ctedNumberOfTests); | 1867 gm_fprintf(stdout, "... so there should be a total of %d tests.\n", expe
ctedNumberOfTests); |
1856 } | 1868 } |
1857 gmmain.ListErrors(FLAGS_verbose); | 1869 gmmain.ListErrors(FLAGS_verbose); |
1858 | 1870 |
1859 // TODO(epoger): Enable this check for Android, too, once we resolve | 1871 // TODO(epoger): Enable this check for Android, too, once we resolve |
1860 // https://code.google.com/p/skia/issues/detail?id=1222 | 1872 // https://code.google.com/p/skia/issues/detail?id=1222 |
1861 // ('GM is unexpectedly skipping tests on Android') | 1873 // ('GM is unexpectedly skipping tests on Android') |
1862 #ifndef SK_BUILD_FOR_ANDROID | 1874 #ifndef SK_BUILD_FOR_ANDROID |
1863 if (expectedNumberOfTests != gmmain.fTestsRun) { | 1875 if (expectedNumberOfTests != gmmain.fTestsRun) { |
1864 gm_fprintf(stderr, "expected %d tests, but ran or skipped %d tests\n", | 1876 gm_fprintf(stderr, "expected %d tests, but ran or skipped %d tests\n", |
1865 expectedNumberOfTests, gmmain.fTestsRun); | 1877 expectedNumberOfTests, gmmain.fTestsRun); |
1866 reportError = true; | 1878 reportError = true; |
1867 } | 1879 } |
1868 #endif | 1880 #endif |
1869 | 1881 |
| 1882 #ifdef EPOGER_TIMER |
| 1883 Json::Value actualResults; |
| 1884 actualResults[kJsonKey_ActualResults_Failed] = |
| 1885 gmmain.fJsonActualResults_Failed; |
| 1886 actualResults[kJsonKey_ActualResults_FailureIgnored] = |
| 1887 gmmain.fJsonActualResults_FailureIgnored; |
| 1888 actualResults[kJsonKey_ActualResults_NoComparison] = |
| 1889 gmmain.fJsonActualResults_NoComparison; |
| 1890 actualResults[kJsonKey_ActualResults_Succeeded] = |
| 1891 gmmain.fJsonActualResults_Succeeded; |
| 1892 Json::Value root; |
| 1893 root[kJsonKey_ActualResults] = actualResults; |
| 1894 root[kJsonKey_ExpectedResults] = gmmain.fJsonExpectedResults; |
| 1895 std::string jsonStdString = root.toStyledString(); |
| 1896 printf("%s\n", jsonStdString.c_str()); |
| 1897 #endif |
| 1898 |
1870 if (FLAGS_writeJsonSummaryPath.count() == 1) { | 1899 if (FLAGS_writeJsonSummaryPath.count() == 1) { |
1871 Json::Value actualResults; | 1900 Json::Value actualResults; |
1872 actualResults[kJsonKey_ActualResults_Failed] = | 1901 actualResults[kJsonKey_ActualResults_Failed] = |
1873 gmmain.fJsonActualResults_Failed; | 1902 gmmain.fJsonActualResults_Failed; |
1874 actualResults[kJsonKey_ActualResults_FailureIgnored] = | 1903 actualResults[kJsonKey_ActualResults_FailureIgnored] = |
1875 gmmain.fJsonActualResults_FailureIgnored; | 1904 gmmain.fJsonActualResults_FailureIgnored; |
1876 actualResults[kJsonKey_ActualResults_NoComparison] = | 1905 actualResults[kJsonKey_ActualResults_NoComparison] = |
1877 gmmain.fJsonActualResults_NoComparison; | 1906 gmmain.fJsonActualResults_NoComparison; |
1878 actualResults[kJsonKey_ActualResults_Succeeded] = | 1907 actualResults[kJsonKey_ActualResults_Succeeded] = |
1879 gmmain.fJsonActualResults_Succeeded; | 1908 gmmain.fJsonActualResults_Succeeded; |
(...skipping 17 matching lines...) Expand all Loading... |
1897 gm_fprintf(stdout, "config: %s %x\n", config.fName, gr); | 1926 gm_fprintf(stdout, "config: %s %x\n", config.fName, gr); |
1898 gr->printCacheStats(); | 1927 gr->printCacheStats(); |
1899 } | 1928 } |
1900 } | 1929 } |
1901 #endif | 1930 #endif |
1902 | 1931 |
1903 delete grFactory; | 1932 delete grFactory; |
1904 #endif | 1933 #endif |
1905 SkGraphics::Term(); | 1934 SkGraphics::Term(); |
1906 | 1935 |
| 1936 #ifdef EPOGER_TIMER |
| 1937 SkMSec endTime = SkTime::GetMSecs(); |
| 1938 printf("EPOGER timings: start-middle=%d msecs, start-end=%d msecs\n", |
| 1939 (middleTime - startTime), (endTime - startTime)); |
| 1940 #endif |
| 1941 |
1907 return (reportError) ? -1 : 0; | 1942 return (reportError) ? -1 : 0; |
1908 } | 1943 } |
1909 | 1944 |
1910 void GMMain::installFilter(SkCanvas* canvas) { | 1945 void GMMain::installFilter(SkCanvas* canvas) { |
1911 if (FLAGS_forceBWtext) { | 1946 if (FLAGS_forceBWtext) { |
1912 canvas->setDrawFilter(SkNEW(BWTextDrawFilter))->unref(); | 1947 canvas->setDrawFilter(SkNEW(BWTextDrawFilter))->unref(); |
1913 } | 1948 } |
1914 } | 1949 } |
1915 | 1950 |
1916 #if !defined(SK_BUILD_FOR_IOS) && !defined(SK_BUILD_FOR_NACL) | 1951 #if !defined(SK_BUILD_FOR_IOS) && !defined(SK_BUILD_FOR_NACL) |
1917 int main(int argc, char * const argv[]) { | 1952 int main(int argc, char * const argv[]) { |
1918 return tool_main(argc, (char**) argv); | 1953 return tool_main(argc, (char**) argv); |
1919 } | 1954 } |
1920 #endif | 1955 #endif |
OLD | NEW |