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 * |
11 * If you make changes to this, re-run the self-tests at gm/tests/run.sh | 11 * If you make changes to this, re-run the self-tests at gm/tests/run.sh |
12 * to make sure they still pass... you may need to change the expected | 12 * to make sure they still pass... you may need to change the expected |
13 * results of the self-test. | 13 * results of the self-test. |
14 */ | 14 */ |
15 | 15 |
16 #include "gm.h" | 16 #include "gm.h" |
17 #include "gm_error.h" | 17 #include "gm_error.h" |
18 #include "gm_expectations.h" | 18 #include "gm_expectations.h" |
19 #include "system_preferences.h" | 19 #include "system_preferences.h" |
20 #include "SkBitmap.h" | 20 #include "SkBitmap.h" |
21 #include "SkColorPriv.h" | 21 #include "SkColorPriv.h" |
22 #include "SkCommandLineFlags.h" | 22 #include "SkCommandLineFlags.h" |
23 #include "SkData.h" | 23 #include "SkData.h" |
24 #include "SkDeferredCanvas.h" | 24 #include "SkDeferredCanvas.h" |
25 #include "SkDevice.h" | 25 #include "SkDevice.h" |
| 26 #include "SkDocument.h" |
26 #include "SkDrawFilter.h" | 27 #include "SkDrawFilter.h" |
27 #include "SkForceLinking.h" | 28 #include "SkForceLinking.h" |
28 #include "SkGPipe.h" | 29 #include "SkGPipe.h" |
29 #include "SkGraphics.h" | 30 #include "SkGraphics.h" |
30 #include "SkImageDecoder.h" | 31 #include "SkImageDecoder.h" |
31 #include "SkImageEncoder.h" | 32 #include "SkImageEncoder.h" |
32 #include "SkOSFile.h" | 33 #include "SkOSFile.h" |
33 #include "SkPDFRasterizer.h" | 34 #include "SkPDFRasterizer.h" |
34 #include "SkPicture.h" | 35 #include "SkPicture.h" |
35 #include "SkRefCnt.h" | 36 #include "SkRefCnt.h" |
| 37 #include "SkScalar.h" |
36 #include "SkStream.h" | 38 #include "SkStream.h" |
37 #include "SkTArray.h" | 39 #include "SkTArray.h" |
38 #include "SkTDict.h" | 40 #include "SkTDict.h" |
39 #include "SkTileGridPicture.h" | 41 #include "SkTileGridPicture.h" |
40 #include "SamplePipeControllers.h" | 42 #include "SamplePipeControllers.h" |
41 | 43 |
42 #ifdef SK_DEBUG | 44 #ifdef SK_DEBUG |
43 static const bool kDebugOnly = true; | 45 static const bool kDebugOnly = true; |
44 #else | 46 #else |
45 static const bool kDebugOnly = false; | 47 static const bool kDebugOnly = false; |
(...skipping 22 matching lines...) Expand all Loading... |
68 #else | 70 #else |
69 class GrContextFactory; | 71 class GrContextFactory; |
70 class GrContext; | 72 class GrContext; |
71 class GrSurface; | 73 class GrSurface; |
72 typedef int GLContextType; | 74 typedef int GLContextType; |
73 #endif | 75 #endif |
74 | 76 |
75 #define DEBUGFAIL_SEE_STDERR SkDEBUGFAIL("see stderr for message") | 77 #define DEBUGFAIL_SEE_STDERR SkDEBUGFAIL("see stderr for message") |
76 | 78 |
77 extern bool gSkSuppressFontCachePurgeSpew; | 79 extern bool gSkSuppressFontCachePurgeSpew; |
| 80 DECLARE_bool(useDocumentInsteadOfDevice); |
78 | 81 |
79 #ifdef SK_SUPPORT_PDF | 82 #ifdef SK_SUPPORT_PDF |
80 #include "SkPDFDevice.h" | 83 #include "SkPDFDevice.h" |
81 #include "SkPDFDocument.h" | 84 #include "SkPDFDocument.h" |
82 #endif | 85 #endif |
83 | 86 |
84 // Until we resolve http://code.google.com/p/skia/issues/detail?id=455 , | 87 // Until we resolve http://code.google.com/p/skia/issues/detail?id=455 , |
85 // stop writing out XPS-format image baselines in gm. | 88 // stop writing out XPS-format image baselines in gm. |
86 #undef SK_SUPPORT_XPS | 89 #undef SK_SUPPORT_XPS |
87 #ifdef SK_SUPPORT_XPS | 90 #ifdef SK_SUPPORT_XPS |
(...skipping 532 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
620 } | 623 } |
621 } else { | 624 } else { |
622 SkCanvas canvas(*bitmap); | 625 SkCanvas canvas(*bitmap); |
623 installFilter(&canvas); | 626 installFilter(&canvas); |
624 canvas.scale(scale, scale); | 627 canvas.scale(scale, scale); |
625 canvas.drawPicture(*pict); | 628 canvas.drawPicture(*pict); |
626 complete_bitmap(bitmap); | 629 complete_bitmap(bitmap); |
627 } | 630 } |
628 } | 631 } |
629 | 632 |
630 static void generate_pdf(GM* gm, SkDynamicMemoryWStream& pdf) { | 633 static bool generate_pdf(GM* gm, SkDynamicMemoryWStream& pdf) { |
631 #ifdef SK_SUPPORT_PDF | 634 #ifdef SK_SUPPORT_PDF |
632 SkMatrix initialTransform = gm->getInitialTransform(); | 635 SkMatrix initialTransform = gm->getInitialTransform(); |
633 SkISize pageSize = gm->getISize(); | 636 if (FLAGS_useDocumentInsteadOfDevice) { |
634 SkPDFDevice* dev = NULL; | 637 SkISize pageISize = gm->getISize(); |
635 if (initialTransform.isIdentity()) { | 638 SkAutoTUnref<SkDocument> pdfDoc(SkDocument::CreatePDF(&pdf, NULL, en
code_to_dct_data)); |
636 dev = new SkPDFDevice(pageSize, pageSize, initialTransform); | 639 |
| 640 if (!pdfDoc.get()) { |
| 641 return false; |
| 642 } |
| 643 |
| 644 SkCanvas* canvas = NULL; |
| 645 canvas = pdfDoc->beginPage(SkIntToScalar(pageISize.width()), |
| 646 SkIntToScalar(pageISize.height())); |
| 647 canvas->concat(initialTransform); |
| 648 |
| 649 invokeGM(gm, canvas, true, false); |
| 650 |
| 651 return pdfDoc->close(); |
637 } else { | 652 } else { |
638 SkRect content = SkRect::MakeWH(SkIntToScalar(pageSize.width()), | 653 SkISize pageSize = gm->getISize(); |
639 SkIntToScalar(pageSize.height())); | 654 SkPDFDevice* dev = NULL; |
640 initialTransform.mapRect(&content); | 655 if (initialTransform.isIdentity()) { |
641 content.intersect(0, 0, SkIntToScalar(pageSize.width()), | 656 dev = new SkPDFDevice(pageSize, pageSize, initialTransform); |
642 SkIntToScalar(pageSize.height())); | 657 } else { |
643 SkISize contentSize = | 658 SkRect content = SkRect::MakeWH(SkIntToScalar(pageSize.width()), |
644 SkISize::Make(SkScalarRoundToInt(content.width()), | 659 SkIntToScalar(pageSize.height())
); |
645 SkScalarRoundToInt(content.height())); | 660 initialTransform.mapRect(&content); |
646 dev = new SkPDFDevice(pageSize, contentSize, initialTransform); | 661 content.intersect(0, 0, SkIntToScalar(pageSize.width()), |
| 662 SkIntToScalar(pageSize.height())); |
| 663 SkISize contentSize = |
| 664 SkISize::Make(SkScalarRoundToInt(content.width()), |
| 665 SkScalarRoundToInt(content.height())); |
| 666 dev = new SkPDFDevice(pageSize, contentSize, initialTransform); |
| 667 } |
| 668 dev->setDCTEncoder(encode_to_dct_data); |
| 669 SkAutoUnref aur(dev); |
| 670 SkCanvas c(dev); |
| 671 invokeGM(gm, &c, true, false); |
| 672 SkPDFDocument doc; |
| 673 doc.appendPage(dev); |
| 674 doc.emitPDF(&pdf); |
647 } | 675 } |
648 dev->setDCTEncoder(encode_to_dct_data); | 676 #endif // SK_SUPPORT_PDF |
649 SkAutoUnref aur(dev); | 677 return true; // Do not report failure if pdf is not supported. |
650 | |
651 SkCanvas c(dev); | |
652 invokeGM(gm, &c, true, false); | |
653 | |
654 SkPDFDocument doc; | |
655 doc.appendPage(dev); | |
656 doc.emitPDF(&pdf); | |
657 #endif | |
658 } | 678 } |
659 | 679 |
660 static void generate_xps(GM* gm, SkDynamicMemoryWStream& xps) { | 680 static void generate_xps(GM* gm, SkDynamicMemoryWStream& xps) { |
661 #ifdef SK_SUPPORT_XPS | 681 #ifdef SK_SUPPORT_XPS |
662 SkISize size = gm->getISize(); | 682 SkISize size = gm->getISize(); |
663 | 683 |
664 SkSize trimSize = SkSize::Make(SkIntToScalar(size.width()), | 684 SkSize trimSize = SkSize::Make(SkIntToScalar(size.width()), |
665 SkIntToScalar(size.height())); | 685 SkIntToScalar(size.height())); |
666 static const SkScalar inchesPerMeter = SkScalarDiv(10000, 254); | 686 static const SkScalar inchesPerMeter = SkScalarDiv(10000, 254); |
667 static const SkScalar upm = 72 * inchesPerMeter; | 687 static const SkScalar upm = 72 * inchesPerMeter; |
(...skipping 371 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1039 BitmapAndDigest bitmapAndDigest(*bitmap); | 1059 BitmapAndDigest bitmapAndDigest(*bitmap); |
1040 errors.add(compare_test_results_to_stored_expectations( | 1060 errors.add(compare_test_results_to_stored_expectations( |
1041 gm, gRec, gRec.fName, &bitmapAndDigest)); | 1061 gm, gRec, gRec.fName, &bitmapAndDigest)); |
1042 | 1062 |
1043 if (writePath && (gRec.fFlags & kWrite_ConfigFlag)) { | 1063 if (writePath && (gRec.fFlags & kWrite_ConfigFlag)) { |
1044 path = make_bitmap_filename(writePath, gm->shortName(), gRec.fNa
me, | 1064 path = make_bitmap_filename(writePath, gm->shortName(), gRec.fNa
me, |
1045 "", bitmapAndDigest.fDigest); | 1065 "", bitmapAndDigest.fDigest); |
1046 errors.add(write_bitmap(path, bitmapAndDigest.fBitmap)); | 1066 errors.add(write_bitmap(path, bitmapAndDigest.fBitmap)); |
1047 } | 1067 } |
1048 } else if (gRec.fBackend == kPDF_Backend) { | 1068 } else if (gRec.fBackend == kPDF_Backend) { |
1049 generate_pdf(gm, document); | 1069 if (!generate_pdf(gm, document)) { |
| 1070 errors.add(kGeneratePdfFailed_ErrorType); |
| 1071 } else { |
| 1072 SkAutoTUnref<SkStreamAsset> documentStream(document.detachAsStre
am()); |
| 1073 if (writePath && (gRec.fFlags & kWrite_ConfigFlag)) { |
| 1074 path = make_filename(writePath, gm->shortName(), gRec.fName,
"", "pdf"); |
| 1075 errors.add(write_document(path, documentStream)); |
| 1076 } |
1050 | 1077 |
1051 SkAutoTUnref<SkStreamAsset> documentStream(document.detachAsStream()
); | 1078 if (!(gm->getFlags() & GM::kSkipPDFRasterization_Flag)) { |
1052 if (writePath && (gRec.fFlags & kWrite_ConfigFlag)) { | 1079 for (int i = 0; i < pdfRasterizers.count(); i++) { |
1053 path = make_filename(writePath, gm->shortName(), gRec.fName, "",
"pdf"); | 1080 SkBitmap pdfBitmap; |
1054 errors.add(write_document(path, documentStream)); | 1081 SkASSERT(documentStream->rewind()); |
1055 } | 1082 bool success = (*pdfRasterizers[i]->fRasterizerFunction)
( |
| 1083 documentStream.get(), &pdfBitmap); |
| 1084 if (!success) { |
| 1085 gm_fprintf(stderr, "FAILED to render PDF for %s usin
g renderer %s\n", |
| 1086 gm->shortName(), |
| 1087 pdfRasterizers[i]->fName); |
| 1088 continue; |
| 1089 } |
1056 | 1090 |
1057 if (!(gm->getFlags() & GM::kSkipPDFRasterization_Flag)) { | 1091 SkString configName(gRec.fName); |
1058 for (int i = 0; i < pdfRasterizers.count(); i++) { | 1092 configName.append("-"); |
1059 SkBitmap pdfBitmap; | 1093 configName.append(pdfRasterizers[i]->fName); |
1060 SkASSERT(documentStream->rewind()); | 1094 |
1061 bool success = (*pdfRasterizers[i]->fRasterizerFunction)( | 1095 BitmapAndDigest bitmapAndDigest(pdfBitmap); |
1062 documentStream.get(), &pdfBitmap); | 1096 errors.add(compare_test_results_to_stored_expectations( |
1063 if (!success) { | 1097 gm, gRec, configName.c_str(), &bitmapAndDiges
t)); |
1064 gm_fprintf(stderr, "FAILED to render PDF for %s using re
nderer %s\n", | 1098 |
1065 gm->shortName(), | 1099 if (writePath && (gRec.fFlags & kWrite_ConfigFlag)) { |
1066 pdfRasterizers[i]->fName); | 1100 path = make_bitmap_filename(writePath, gm->shortName
(), |
1067 continue; | 1101 configName.c_str(), |
| 1102 "", bitmapAndDigest.fDig
est); |
| 1103 errors.add(write_bitmap(path, bitmapAndDigest.fBitma
p)); |
| 1104 } |
1068 } | 1105 } |
1069 | 1106 } else { |
1070 SkString configName(gRec.fName); | 1107 errors.add(kIntentionallySkipped_ErrorType); |
1071 configName.append("-"); | |
1072 configName.append(pdfRasterizers[i]->fName); | |
1073 | |
1074 BitmapAndDigest bitmapAndDigest(pdfBitmap); | |
1075 errors.add(compare_test_results_to_stored_expectations( | |
1076 gm, gRec, configName.c_str(), &bitmapAndDigest)); | |
1077 | |
1078 if (writePath && (gRec.fFlags & kWrite_ConfigFlag)) { | |
1079 path = make_bitmap_filename(writePath, gm->shortName(),
configName.c_str(), | |
1080 "", bitmapAndDigest.fDigest)
; | |
1081 errors.add(write_bitmap(path, bitmapAndDigest.fBitmap)); | |
1082 } | |
1083 } | 1108 } |
1084 } else { | |
1085 errors.add(kIntentionallySkipped_ErrorType); | |
1086 } | 1109 } |
1087 } else if (gRec.fBackend == kXPS_Backend) { | 1110 } else if (gRec.fBackend == kXPS_Backend) { |
1088 generate_xps(gm, document); | 1111 generate_xps(gm, document); |
1089 SkAutoTUnref<SkStreamAsset> documentStream(document.detachAsStream()
); | 1112 SkAutoTUnref<SkStreamAsset> documentStream(document.detachAsStream()
); |
1090 | 1113 |
1091 errors.add(compare_test_results_to_stored_expectations( | 1114 errors.add(compare_test_results_to_stored_expectations( |
1092 gm, gRec, gRec.fName, NULL)); | 1115 gm, gRec, gRec.fName, NULL)); |
1093 | 1116 |
1094 if (writePath && (gRec.fFlags & kWrite_ConfigFlag)) { | 1117 if (writePath && (gRec.fFlags & kWrite_ConfigFlag)) { |
1095 path = make_filename(writePath, gm->shortName(), gRec.fName, "",
"xps"); | 1118 path = make_filename(writePath, gm->shortName(), gRec.fName, "",
"xps"); |
(...skipping 341 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1437 DEFINE_int32(pdfJpegQuality, -1, "Encodes images in JPEG at quality level N, " | 1460 DEFINE_int32(pdfJpegQuality, -1, "Encodes images in JPEG at quality level N, " |
1438 "which can be in range 0-100). N = -1 will disable JPEG compression
. " | 1461 "which can be in range 0-100). N = -1 will disable JPEG compression
. " |
1439 "Default is N = 100, maximum quality."); | 1462 "Default is N = 100, maximum quality."); |
1440 // TODO(edisonn): pass a matrix instead of forcePerspectiveMatrix | 1463 // TODO(edisonn): pass a matrix instead of forcePerspectiveMatrix |
1441 // Either the 9 numbers defining the matrix | 1464 // Either the 9 numbers defining the matrix |
1442 // or probably more readable would be to replace it with a set of a few predicat
es | 1465 // or probably more readable would be to replace it with a set of a few predicat
es |
1443 // Like --prerotate 100 200 10 --posttranslate 10, 10 | 1466 // Like --prerotate 100 200 10 --posttranslate 10, 10 |
1444 // Probably define spacial names like centerx, centery, top, bottom, left, right | 1467 // Probably define spacial names like centerx, centery, top, bottom, left, right |
1445 // then we can write something reabable like --rotate centerx centery 90 | 1468 // then we can write something reabable like --rotate centerx centery 90 |
1446 DEFINE_bool(forcePerspectiveMatrix, false, "Force a perspective matrix."); | 1469 DEFINE_bool(forcePerspectiveMatrix, false, "Force a perspective matrix."); |
| 1470 DEFINE_bool(useDocumentInsteadOfDevice, false, "Use SkDocument::CreateFoo instea
d of SkFooDevice."); |
1447 | 1471 |
1448 static SkData* encode_to_dct_data(size_t* pixelRefOffset, const SkBitmap& bitmap
) { | 1472 static SkData* encode_to_dct_data(size_t* pixelRefOffset, const SkBitmap& bitmap
) { |
1449 // Filter output of warnings that JPEG is not available for the image. | 1473 // Filter output of warnings that JPEG is not available for the image. |
1450 if (bitmap.width() >= 65500 || bitmap.height() >= 65500) return NULL; | 1474 if (bitmap.width() >= 65500 || bitmap.height() >= 65500) return NULL; |
1451 if (FLAGS_pdfJpegQuality == -1) return NULL; | 1475 if (FLAGS_pdfJpegQuality == -1) return NULL; |
1452 | 1476 |
1453 SkBitmap bm = bitmap; | 1477 SkBitmap bm = bitmap; |
1454 #if defined(SK_BUILD_FOR_MAC) | 1478 #if defined(SK_BUILD_FOR_MAC) |
1455 // Workaround bug #1043 where bitmaps with referenced pixels cause | 1479 // Workaround bug #1043 where bitmaps with referenced pixels cause |
1456 // CGImageDestinationFinalize to crash | 1480 // CGImageDestinationFinalize to crash |
(...skipping 839 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2296 if (FLAGS_forceBWtext) { | 2320 if (FLAGS_forceBWtext) { |
2297 canvas->setDrawFilter(SkNEW(BWTextDrawFilter))->unref(); | 2321 canvas->setDrawFilter(SkNEW(BWTextDrawFilter))->unref(); |
2298 } | 2322 } |
2299 } | 2323 } |
2300 | 2324 |
2301 #if !defined(SK_BUILD_FOR_IOS) && !defined(SK_BUILD_FOR_NACL) | 2325 #if !defined(SK_BUILD_FOR_IOS) && !defined(SK_BUILD_FOR_NACL) |
2302 int main(int argc, char * const argv[]) { | 2326 int main(int argc, char * const argv[]) { |
2303 return tool_main(argc, (char**) argv); | 2327 return tool_main(argc, (char**) argv); |
2304 } | 2328 } |
2305 #endif | 2329 #endif |
OLD | NEW |