| 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 |