 Chromium Code Reviews
 Chromium Code Reviews Issue 12992003:
  gm: change ErrorBitfield to ErrorType/ErrorCombination  (Closed) 
  Base URL: http://skia.googlecode.com/svn/trunk/
    
  
    Issue 12992003:
  gm: change ErrorBitfield to ErrorType/ErrorCombination  (Closed) 
  Base URL: http://skia.googlecode.com/svn/trunk/| 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_expectations.h" | 18 #include "gm_expectations.h" | 
| 18 #include "system_preferences.h" | 19 #include "system_preferences.h" | 
| 19 #include "SkBitmap.h" | 20 #include "SkBitmap.h" | 
| 20 #include "SkBitmapChecksummer.h" | 21 #include "SkBitmapChecksummer.h" | 
| 21 #include "SkColorPriv.h" | 22 #include "SkColorPriv.h" | 
| 22 #include "SkCommandLineFlags.h" | 23 #include "SkCommandLineFlags.h" | 
| 23 #include "SkData.h" | 24 #include "SkData.h" | 
| 24 #include "SkDeferredCanvas.h" | 25 #include "SkDeferredCanvas.h" | 
| 25 #include "SkDevice.h" | 26 #include "SkDevice.h" | 
| 26 #include "SkDrawFilter.h" | 27 #include "SkDrawFilter.h" | 
| (...skipping 18 matching lines...) Expand all Loading... | |
| 45 #include "json/value.h" | 46 #include "json/value.h" | 
| 46 #ifdef SK_BUILD_FOR_WIN | 47 #ifdef SK_BUILD_FOR_WIN | 
| 47 #pragma warning(pop) | 48 #pragma warning(pop) | 
| 48 #endif | 49 #endif | 
| 49 | 50 | 
| 50 #if SK_SUPPORT_GPU | 51 #if SK_SUPPORT_GPU | 
| 51 #include "GrContextFactory.h" | 52 #include "GrContextFactory.h" | 
| 52 #include "GrRenderTarget.h" | 53 #include "GrRenderTarget.h" | 
| 53 #include "SkGpuDevice.h" | 54 #include "SkGpuDevice.h" | 
| 54 typedef GrContextFactory::GLContextType GLContextType; | 55 typedef GrContextFactory::GLContextType GLContextType; | 
| 56 #define DEFAULT_CACHE_VALUE -1 | |
| 57 static int gGpuCacheSizeBytes; | |
| 58 static int gGpuCacheSizeCount; | |
| 55 #else | 59 #else | 
| 56 class GrContextFactory; | 60 class GrContextFactory; | 
| 57 class GrContext; | 61 class GrContext; | 
| 58 class GrRenderTarget; | 62 class GrRenderTarget; | 
| 59 typedef int GLContextType; | 63 typedef int GLContextType; | 
| 60 #endif | 64 #endif | 
| 61 | 65 | 
| 62 extern bool gSkSuppressFontCachePurgeSpew; | 66 extern bool gSkSuppressFontCachePurgeSpew; | 
| 63 | 67 | 
| 64 #ifdef SK_SUPPORT_PDF | 68 #ifdef SK_SUPPORT_PDF | 
| 65 #include "SkPDFDevice.h" | 69 #include "SkPDFDevice.h" | 
| 66 #include "SkPDFDocument.h" | 70 #include "SkPDFDocument.h" | 
| 67 #endif | 71 #endif | 
| 68 | 72 | 
| 69 // Until we resolve http://code.google.com/p/skia/issues/detail?id=455 , | 73 // Until we resolve http://code.google.com/p/skia/issues/detail?id=455 , | 
| 70 // stop writing out XPS-format image baselines in gm. | 74 // stop writing out XPS-format image baselines in gm. | 
| 71 #undef SK_SUPPORT_XPS | 75 #undef SK_SUPPORT_XPS | 
| 72 #ifdef SK_SUPPORT_XPS | 76 #ifdef SK_SUPPORT_XPS | 
| 73 #include "SkXPSDevice.h" | 77 #include "SkXPSDevice.h" | 
| 74 #endif | 78 #endif | 
| 75 | 79 | 
| 76 #ifdef SK_BUILD_FOR_MAC | 80 #ifdef SK_BUILD_FOR_MAC | 
| 77 #include "SkCGUtils.h" | 81 #include "SkCGUtils.h" | 
| 78 #define CAN_IMAGE_PDF 1 | 82 #define CAN_IMAGE_PDF 1 | 
| 79 #else | 83 #else | 
| 80 #define CAN_IMAGE_PDF 0 | 84 #define CAN_IMAGE_PDF 0 | 
| 81 #endif | 85 #endif | 
| 82 | 86 | 
| 83 typedef int ErrorBitfield; | |
| 84 // an empty bitfield means no errors: | |
| 85 const static ErrorBitfield kEmptyErrorBitfield = 0x00; | |
| 86 // individual error types: | |
| 87 const static ErrorBitfield kNoGpuContext_ErrorBitmask = 0x01; | |
| 88 const static ErrorBitfield kImageMismatch_ErrorBitmask = 0x02; | |
| 89 const static ErrorBitfield kMissingExpectations_ErrorBitmask = 0x04; | |
| 90 const static ErrorBitfield kWritingReferenceImage_ErrorBitmask = 0x08; | |
| 91 // we typically ignore any errors matching this bitmask: | |
| 92 const static ErrorBitfield kIgnorable_ErrorBitmask = kMissingExpectations_ErrorB itmask; | |
| 93 | |
| 94 using namespace skiagm; | 87 using namespace skiagm; | 
| 95 | 88 | 
| 96 struct FailRec { | 89 struct FailRec { | 
| 97 SkString fName; | 90 SkString fName; | 
| 98 bool fIsPixelError; | 91 bool fIsPixelError; | 
| 99 | 92 | 
| 100 FailRec() : fIsPixelError(false) {} | 93 FailRec() : fIsPixelError(false) {} | 
| 101 FailRec(const SkString& name) : fName(name), fIsPixelError(false) {} | 94 FailRec(const SkString& name) : fName(name), fIsPixelError(false) {} | 
| 102 }; | 95 }; | 
| 103 | 96 | 
| (...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 188 { " cross-process, shared address", SkGPipeWriter::kCrossProcess_Flag | 181 { " cross-process, shared address", SkGPipeWriter::kCrossProcess_Flag | 
| 189 | SkGPipeWriter::kSharedAddressSpace_Flag } | 182 | SkGPipeWriter::kSharedAddressSpace_Flag } | 
| 190 }; | 183 }; | 
| 191 | 184 | 
| 192 class GMMain { | 185 class GMMain { | 
| 193 public: | 186 public: | 
| 194 GMMain() { | 187 GMMain() { | 
| 195 // Set default values of member variables, which tool_main() | 188 // Set default values of member variables, which tool_main() | 
| 196 // may override. | 189 // may override. | 
| 197 fUseFileHierarchy = false; | 190 fUseFileHierarchy = false; | 
| 191 fIgnorableErrorCombination.add(kMissingExpectations_ErrorType); | |
| 198 fMismatchPath = NULL; | 192 fMismatchPath = NULL; | 
| 199 } | 193 } | 
| 200 | 194 | 
| 201 SkString make_name(const char shortName[], const char configName[]) { | 195 SkString make_name(const char shortName[], const char configName[]) { | 
| 202 SkString name; | 196 SkString name; | 
| 203 if (0 == strlen(configName)) { | 197 if (0 == strlen(configName)) { | 
| 204 name.append(shortName); | 198 name.append(shortName); | 
| 205 } else if (fUseFileHierarchy) { | 199 } else if (fUseFileHierarchy) { | 
| 206 name.appendf("%s%c%s", configName, SkPATH_SEPARATOR, shortName); | 200 name.appendf("%s%c%s", configName, SkPATH_SEPARATOR, shortName); | 
| 207 } else { | 201 } else { | 
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 241 static bool write_bitmap(const SkString& path, const SkBitmap& bitmap) { | 235 static bool write_bitmap(const SkString& path, const SkBitmap& bitmap) { | 
| 242 // TODO(epoger): Now that we have removed force_all_opaque() | 236 // TODO(epoger): Now that we have removed force_all_opaque() | 
| 243 // from this method, we should be able to get rid of the | 237 // from this method, we should be able to get rid of the | 
| 244 // transformation to 8888 format also. | 238 // transformation to 8888 format also. | 
| 245 SkBitmap copy; | 239 SkBitmap copy; | 
| 246 bitmap.copyTo(©, SkBitmap::kARGB_8888_Config); | 240 bitmap.copyTo(©, SkBitmap::kARGB_8888_Config); | 
| 247 return SkImageEncoder::EncodeFile(path.c_str(), copy, | 241 return SkImageEncoder::EncodeFile(path.c_str(), copy, | 
| 248 SkImageEncoder::kPNG_Type, 100); | 242 SkImageEncoder::kPNG_Type, 100); | 
| 249 } | 243 } | 
| 250 | 244 | 
| 251 // Records an error in fFailedTests, if we want to record errors | 245 /** | 
| 252 // of this type. | 246 * Records the errors encountered in fFailedTests, except for any error | 
| 253 void RecordError(ErrorBitfield errorType, const SkString& name, | 247 * types we want to ignore. | 
| 248 */ | |
| 249 void RecordError(const ErrorCombination& errorCombination, const SkString& n ame, | |
| 254 const char renderModeDescriptor []) { | 250 const char renderModeDescriptor []) { | 
| 255 // The common case: no error means nothing to record. | 251 // The common case: no error means nothing to record. | 
| 256 if (kEmptyErrorBitfield == errorType) { | 252 if (errorCombination.isEmpty()) { | 
| 257 return; | 253 return; | 
| 258 } | 254 } | 
| 259 | 255 | 
| 260 // If only certain error type(s) were reported, we know we can ignore th em. | 256 // If only certain error type(s) were reported, we know we can ignore th em. | 
| 261 if (errorType == (errorType & kIgnorable_ErrorBitmask)) { | 257 if (errorCombination.minus(fIgnorableErrorCombination).isEmpty()) { | 
| 262 return; | 258 return; | 
| 263 } | 259 } | 
| 264 | 260 | 
| 265 FailRec& rec = fFailedTests.push_back(make_name( | 261 FailRec& rec = fFailedTests.push_back(make_name(name.c_str(), renderMode Descriptor)); | 
| 266 name.c_str(), renderModeDescriptor)); | 262 rec.fIsPixelError = errorCombination.includes(kImageMismatch_ErrorType); | 
| 267 rec.fIsPixelError = | |
| 268 (kEmptyErrorBitfield != (errorType & kImageMismatch_ErrorBitmask)); | |
| 269 } | 263 } | 
| 270 | 264 | 
| 271 // List contents of fFailedTests via SkDebug. | 265 // List contents of fFailedTests via SkDebug. | 
| 272 void ListErrors() { | 266 void ListErrors() { | 
| 273 for (int i = 0; i < fFailedTests.count(); ++i) { | 267 for (int i = 0; i < fFailedTests.count(); ++i) { | 
| 274 if (fFailedTests[i].fIsPixelError) { | 268 if (fFailedTests[i].fIsPixelError) { | 
| 275 gm_fprintf(stderr, "\t\t%s pixel_error\n", fFailedTests[i].fName .c_str()); | 269 gm_fprintf(stderr, "\t\t%s pixel_error\n", fFailedTests[i].fName .c_str()); | 
| 276 } else { | 270 } else { | 
| 277 gm_fprintf(stderr, "\t\t%s\n", fFailedTests[i].fName.c_str()); | 271 gm_fprintf(stderr, "\t\t%s\n", fFailedTests[i].fName.c_str()); | 
| 278 } | 272 } | 
| (...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 371 | 365 | 
| 372 if (!isPDF) { | 366 if (!isPDF) { | 
| 373 canvas->concat(gm->getInitialTransform()); | 367 canvas->concat(gm->getInitialTransform()); | 
| 374 } | 368 } | 
| 375 installFilter(canvas); | 369 installFilter(canvas); | 
| 376 gm->setCanvasIsDeferred(isDeferred); | 370 gm->setCanvasIsDeferred(isDeferred); | 
| 377 gm->draw(canvas); | 371 gm->draw(canvas); | 
| 378 canvas->setDrawFilter(NULL); | 372 canvas->setDrawFilter(NULL); | 
| 379 } | 373 } | 
| 380 | 374 | 
| 381 static ErrorBitfield generate_image(GM* gm, const ConfigData& gRec, | 375 static ErrorCombination generate_image(GM* gm, const ConfigData& gRec, | 
| 382 GrContext* context, | 376 GrContext* context, | 
| 383 GrRenderTarget* rt, | 377 GrRenderTarget* rt, | 
| 384 SkBitmap* bitmap, | 378 SkBitmap* bitmap, | 
| 385 bool deferred) { | 379 bool deferred) { | 
| 386 SkISize size (gm->getISize()); | 380 SkISize size (gm->getISize()); | 
| 387 setup_bitmap(gRec, size, bitmap); | 381 setup_bitmap(gRec, size, bitmap); | 
| 388 | 382 | 
| 389 SkAutoTUnref<SkCanvas> canvas; | 383 SkAutoTUnref<SkCanvas> canvas; | 
| 390 | 384 | 
| 391 if (gRec.fBackend == kRaster_Backend) { | 385 if (gRec.fBackend == kRaster_Backend) { | 
| 392 SkAutoTUnref<SkDevice> device(new SkDevice(*bitmap)); | 386 SkAutoTUnref<SkDevice> device(new SkDevice(*bitmap)); | 
| 393 if (deferred) { | 387 if (deferred) { | 
| 394 canvas.reset(new SkDeferredCanvas(device)); | 388 canvas.reset(new SkDeferredCanvas(device)); | 
| 395 } else { | 389 } else { | 
| 396 canvas.reset(new SkCanvas(device)); | 390 canvas.reset(new SkCanvas(device)); | 
| 397 } | 391 } | 
| 398 invokeGM(gm, canvas, false, deferred); | 392 invokeGM(gm, canvas, false, deferred); | 
| 399 canvas->flush(); | 393 canvas->flush(); | 
| 400 } | 394 } | 
| 401 #if SK_SUPPORT_GPU | 395 #if SK_SUPPORT_GPU | 
| 402 else { // GPU | 396 else { // GPU | 
| 403 if (NULL == context) { | 397 if (NULL == context) { | 
| 404 return kNoGpuContext_ErrorBitmask; | 398 return ErrorCombination(kNoGpuContext_ErrorType); | 
| 
bsalomon
2013/03/22 16:03:23
Drive-by: This is unreachable because of the loop
 
epoger
2013/03/22 16:06:09
Thanks.  I don't think that's a problem, do you?
 
bsalomon
2013/03/25 13:01:50
Heh... I added the code at 1469 recently and just
 | |
| 405 } | 399 } | 
| 406 SkAutoTUnref<SkDevice> device(new SkGpuDevice(context, rt)); | 400 SkAutoTUnref<SkDevice> device(new SkGpuDevice(context, rt)); | 
| 407 if (deferred) { | 401 if (deferred) { | 
| 408 canvas.reset(new SkDeferredCanvas(device)); | 402 canvas.reset(new SkDeferredCanvas(device)); | 
| 409 } else { | 403 } else { | 
| 410 canvas.reset(new SkCanvas(device)); | 404 canvas.reset(new SkCanvas(device)); | 
| 411 } | 405 } | 
| 412 invokeGM(gm, canvas, false, deferred); | 406 invokeGM(gm, canvas, false, deferred); | 
| 413 // the device is as large as the current rendertarget, so | 407 // the device is as large as the current rendertarget, so | 
| 414 // we explicitly only readback the amount we expect (in | 408 // we explicitly only readback the amount we expect (in | 
| 415 // size) overwrite our previous allocation | 409 // size) overwrite our previous allocation | 
| 416 bitmap->setConfig(SkBitmap::kARGB_8888_Config, size.fWidth, | 410 bitmap->setConfig(SkBitmap::kARGB_8888_Config, size.fWidth, | 
| 417 size.fHeight); | 411 size.fHeight); | 
| 418 canvas->readPixels(bitmap, 0, 0); | 412 canvas->readPixels(bitmap, 0, 0); | 
| 419 } | 413 } | 
| 420 #endif | 414 #endif | 
| 421 complete_bitmap(bitmap); | 415 complete_bitmap(bitmap); | 
| 422 return kEmptyErrorBitfield; | 416 return kEmpty_ErrorCombination; | 
| 423 } | 417 } | 
| 424 | 418 | 
| 425 static void generate_image_from_picture(GM* gm, const ConfigData& gRec, | 419 static void generate_image_from_picture(GM* gm, const ConfigData& gRec, | 
| 426 SkPicture* pict, SkBitmap* bitmap, | 420 SkPicture* pict, SkBitmap* bitmap, | 
| 427 SkScalar scale = SK_Scalar1) { | 421 SkScalar scale = SK_Scalar1) { | 
| 428 SkISize size = gm->getISize(); | 422 SkISize size = gm->getISize(); | 
| 429 setup_bitmap(gRec, size, bitmap); | 423 setup_bitmap(gRec, size, bitmap); | 
| 430 SkCanvas canvas(*bitmap); | 424 SkCanvas canvas(*bitmap); | 
| 431 installFilter(&canvas); | 425 installFilter(&canvas); | 
| 432 canvas.scale(scale, scale); | 426 canvas.scale(scale, scale); | 
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 481 SkCanvas c(dev); | 475 SkCanvas c(dev); | 
| 482 dev->beginPortfolio(&xps); | 476 dev->beginPortfolio(&xps); | 
| 483 dev->beginSheet(unitsPerMeter, pixelsPerMeter, trimSize); | 477 dev->beginSheet(unitsPerMeter, pixelsPerMeter, trimSize); | 
| 484 invokeGM(gm, &c, false, false); | 478 invokeGM(gm, &c, false, false); | 
| 485 dev->endSheet(); | 479 dev->endSheet(); | 
| 486 dev->endPortfolio(); | 480 dev->endPortfolio(); | 
| 487 | 481 | 
| 488 #endif | 482 #endif | 
| 489 } | 483 } | 
| 490 | 484 | 
| 491 ErrorBitfield write_reference_image( | 485 ErrorCombination write_reference_image(const ConfigData& gRec, const char wr itePath [], | 
| 492 const ConfigData& gRec, const char writePath [], | 486 const char renderModeDescriptor [], c onst SkString& name, | 
| 493 const char renderModeDescriptor [], const SkString& name, | 487 SkBitmap& bitmap, SkDynamicMemoryWStr eam* document) { | 
| 494 SkBitmap& bitmap, SkDynamicMemoryWStream* document) { | |
| 495 SkString path; | 488 SkString path; | 
| 496 bool success = false; | 489 bool success = false; | 
| 497 if (gRec.fBackend == kRaster_Backend || | 490 if (gRec.fBackend == kRaster_Backend || | 
| 498 gRec.fBackend == kGPU_Backend || | 491 gRec.fBackend == kGPU_Backend || | 
| 499 (gRec.fBackend == kPDF_Backend && CAN_IMAGE_PDF)) { | 492 (gRec.fBackend == kPDF_Backend && CAN_IMAGE_PDF)) { | 
| 500 | 493 | 
| 501 path = make_filename(writePath, renderModeDescriptor, name.c_str(), | 494 path = make_filename(writePath, renderModeDescriptor, name.c_str(), | 
| 502 "png"); | 495 "png"); | 
| 503 success = write_bitmap(path, bitmap); | 496 success = write_bitmap(path, bitmap); | 
| 504 } | 497 } | 
| 505 if (kPDF_Backend == gRec.fBackend) { | 498 if (kPDF_Backend == gRec.fBackend) { | 
| 506 path = make_filename(writePath, renderModeDescriptor, name.c_str(), | 499 path = make_filename(writePath, renderModeDescriptor, name.c_str(), | 
| 507 "pdf"); | 500 "pdf"); | 
| 508 success = write_document(path, *document); | 501 success = write_document(path, *document); | 
| 509 } | 502 } | 
| 510 if (kXPS_Backend == gRec.fBackend) { | 503 if (kXPS_Backend == gRec.fBackend) { | 
| 511 path = make_filename(writePath, renderModeDescriptor, name.c_str(), | 504 path = make_filename(writePath, renderModeDescriptor, name.c_str(), | 
| 512 "xps"); | 505 "xps"); | 
| 513 success = write_document(path, *document); | 506 success = write_document(path, *document); | 
| 514 } | 507 } | 
| 515 if (success) { | 508 if (success) { | 
| 516 return kEmptyErrorBitfield; | 509 return kEmpty_ErrorCombination; | 
| 517 } else { | 510 } else { | 
| 518 gm_fprintf(stderr, "FAILED to write %s\n", path.c_str()); | 511 gm_fprintf(stderr, "FAILED to write %s\n", path.c_str()); | 
| 519 RecordError(kWritingReferenceImage_ErrorBitmask, name, | 512 ErrorCombination errors(kWritingReferenceImage_ErrorType); | 
| 520 renderModeDescriptor); | 513 RecordError(errors, name, renderModeDescriptor); | 
| 521 return kWritingReferenceImage_ErrorBitmask; | 514 return errors; | 
| 522 } | 515 } | 
| 523 } | 516 } | 
| 524 | 517 | 
| 525 /** | 518 /** | 
| 526 * Log more detail about the mistmatch between expectedBitmap and | 519 * Log more detail about the mistmatch between expectedBitmap and | 
| 527 * actualBitmap. | 520 * actualBitmap. | 
| 528 */ | 521 */ | 
| 529 void report_bitmap_diffs(const SkBitmap& expectedBitmap, const SkBitmap& act ualBitmap, | 522 void report_bitmap_diffs(const SkBitmap& expectedBitmap, const SkBitmap& act ualBitmap, | 
| 530 const char *testName) { | 523 const char *testName) { | 
| 531 const int expectedWidth = expectedBitmap.width(); | 524 const int expectedWidth = expectedBitmap.width(); | 
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 572 (int)SkGetPackedA32(actualPixel ))); | 565 (int)SkGetPackedA32(actualPixel ))); | 
| 573 } | 566 } | 
| 574 } | 567 } | 
| 575 } | 568 } | 
| 576 gm_fprintf(stderr, "---- %s: %d (of %d) differing pixels," | 569 gm_fprintf(stderr, "---- %s: %d (of %d) differing pixels," | 
| 577 " max per-channel mismatch R=%d G=%d B=%d A=%d\n", | 570 " max per-channel mismatch R=%d G=%d B=%d A=%d\n", | 
| 578 testName, differingPixels, width*height, errR, errG, errB, er rA); | 571 testName, differingPixels, width*height, errR, errG, errB, er rA); | 
| 579 } | 572 } | 
| 580 | 573 | 
| 581 /** | 574 /** | 
| 582 * Compares actual checksum to expectations. Returns | 575 * Compares actual checksum to expectations, returning the set of errors | 
| 583 * kEmptyErrorBitfield if they match, or some combination of | 576 * (if any) that we saw along the way. | 
| 584 * _ErrorBitmask values otherwise. | |
| 585 * | 577 * | 
| 586 * If fMismatchPath has been set, and there are pixel diffs, then the | 578 * If fMismatchPath has been set, and there are pixel diffs, then the | 
| 587 * actual bitmap will be written out to a file within fMismatchPath. | 579 * actual bitmap will be written out to a file within fMismatchPath. | 
| 588 * | 580 * | 
| 589 * @param expectations what expectations to compare actualBitmap against | 581 * @param expectations what expectations to compare actualBitmap against | 
| 590 * @param actualBitmap the image we actually generated | 582 * @param actualBitmap the image we actually generated | 
| 591 * @param baseNameString name of test without renderModeDescriptor added | 583 * @param baseNameString name of test without renderModeDescriptor added | 
| 592 * @param renderModeDescriptor e.g., "-rtree", "-deferred" | 584 * @param renderModeDescriptor e.g., "-rtree", "-deferred" | 
| 593 * @param addToJsonSummary whether to add these results (both actual and | 585 * @param addToJsonSummary whether to add these results (both actual and | 
| 594 * expected) to the JSON summary | 586 * expected) to the JSON summary | 
| 595 * | 587 * | 
| 596 * TODO: For now, addToJsonSummary is only set to true within | 588 * TODO: For now, addToJsonSummary is only set to true within | 
| 597 * compare_test_results_to_stored_expectations(), so results of our | 589 * compare_test_results_to_stored_expectations(), so results of our | 
| 598 * in-memory comparisons (Rtree vs regular, etc.) are not written to the | 590 * in-memory comparisons (Rtree vs regular, etc.) are not written to the | 
| 599 * JSON summary. We may wish to change that. | 591 * JSON summary. We may wish to change that. | 
| 600 */ | 592 */ | 
| 601 ErrorBitfield compare_to_expectations(Expectations expectations, | 593 ErrorCombination compare_to_expectations(Expectations expectations, | 
| 602 const SkBitmap& actualBitmap, | 594 const SkBitmap& actualBitmap, | 
| 603 const SkString& baseNameString, | 595 const SkString& baseNameString, | 
| 604 const char renderModeDescriptor[], | 596 const char renderModeDescriptor[], | 
| 605 bool addToJsonSummary=false) { | 597 bool addToJsonSummary=false) { | 
| 606 ErrorBitfield retval; | 598 ErrorCombination errors; | 
| 607 Checksum actualChecksum = SkBitmapChecksummer::Compute64(actualBitmap); | 599 Checksum actualChecksum = SkBitmapChecksummer::Compute64(actualBitmap); | 
| 608 SkString completeNameString = baseNameString; | 600 SkString completeNameString = baseNameString; | 
| 609 completeNameString.append(renderModeDescriptor); | 601 completeNameString.append(renderModeDescriptor); | 
| 610 const char* completeName = completeNameString.c_str(); | 602 const char* completeName = completeNameString.c_str(); | 
| 611 | 603 | 
| 612 if (expectations.empty()) { | 604 if (expectations.empty()) { | 
| 613 retval = kMissingExpectations_ErrorBitmask; | 605 errors.add(kMissingExpectations_ErrorType); | 
| 614 } else if (expectations.match(actualChecksum)) { | 606 } else if (!expectations.match(actualChecksum)) { | 
| 615 retval = kEmptyErrorBitfield; | 607 errors.add(kImageMismatch_ErrorType); | 
| 616 } else { | |
| 617 retval = kImageMismatch_ErrorBitmask; | |
| 618 | 608 | 
| 619 // Write out the "actuals" for any mismatches, if we have | 609 // Write out the "actuals" for any mismatches, if we have | 
| 620 // been directed to do so. | 610 // been directed to do so. | 
| 621 if (fMismatchPath) { | 611 if (fMismatchPath) { | 
| 622 SkString path = | 612 SkString path = | 
| 623 make_filename(fMismatchPath, renderModeDescriptor, | 613 make_filename(fMismatchPath, renderModeDescriptor, | 
| 624 baseNameString.c_str(), "png"); | 614 baseNameString.c_str(), "png"); | 
| 625 write_bitmap(path, actualBitmap); | 615 write_bitmap(path, actualBitmap); | 
| 626 } | 616 } | 
| 627 | 617 | 
| 628 // If we have access to a single expected bitmap, log more | 618 // If we have access to a single expected bitmap, log more | 
| 629 // detail about the mismatch. | 619 // detail about the mismatch. | 
| 630 const SkBitmap *expectedBitmapPtr = expectations.asBitmap(); | 620 const SkBitmap *expectedBitmapPtr = expectations.asBitmap(); | 
| 631 if (NULL != expectedBitmapPtr) { | 621 if (NULL != expectedBitmapPtr) { | 
| 632 report_bitmap_diffs(*expectedBitmapPtr, actualBitmap, completeNa me); | 622 report_bitmap_diffs(*expectedBitmapPtr, actualBitmap, completeNa me); | 
| 633 } | 623 } | 
| 634 } | 624 } | 
| 635 RecordError(retval, baseNameString, renderModeDescriptor); | 625 RecordError(errors, baseNameString, renderModeDescriptor); | 
| 636 | 626 | 
| 637 if (addToJsonSummary) { | 627 if (addToJsonSummary) { | 
| 638 add_actual_results_to_json_summary(completeName, actualChecksum, | 628 add_actual_results_to_json_summary(completeName, actualChecksum, err ors, | 
| 639 retval, | |
| 640 expectations.ignoreFailure()); | 629 expectations.ignoreFailure()); | 
| 641 add_expected_results_to_json_summary(completeName, expectations); | 630 add_expected_results_to_json_summary(completeName, expectations); | 
| 642 } | 631 } | 
| 643 | 632 | 
| 644 return retval; | 633 return errors; | 
| 645 } | 634 } | 
| 646 | 635 | 
| 647 /** | 636 /** | 
| 648 * Add this result to the appropriate JSON collection of actual results, | 637 * Add this result to the appropriate JSON collection of actual results, | 
| 649 * depending on status. | 638 * depending on status. | 
| 650 */ | 639 */ | 
| 651 void add_actual_results_to_json_summary(const char testName[], | 640 void add_actual_results_to_json_summary(const char testName[], | 
| 652 Checksum actualChecksum, | 641 Checksum actualChecksum, | 
| 653 ErrorBitfield result, | 642 ErrorCombination result, | 
| 654 bool ignoreFailure) { | 643 bool ignoreFailure) { | 
| 655 Json::Value actualResults; | 644 Json::Value actualResults; | 
| 656 actualResults[kJsonKey_ActualResults_AnyStatus_Checksum] = | 645 actualResults[kJsonKey_ActualResults_AnyStatus_Checksum] = | 
| 657 asJsonValue(actualChecksum); | 646 asJsonValue(actualChecksum); | 
| 658 if (kEmptyErrorBitfield == result) { | 647 if (result.isEmpty()) { | 
| 659 this->fJsonActualResults_Succeeded[testName] = actualResults; | 648 this->fJsonActualResults_Succeeded[testName] = actualResults; | 
| 660 } else { | 649 } else { | 
| 661 if (ignoreFailure) { | 650 if (ignoreFailure) { | 
| 662 // TODO: Once we have added the ability to compare | 651 // TODO: Once we have added the ability to compare | 
| 663 // actual results against expectations in a JSON file | 652 // actual results against expectations in a JSON file | 
| 664 // (where we can set ignore-failure to either true or | 653 // (where we can set ignore-failure to either true or | 
| 665 // false), add test cases that exercise ignored | 654 // false), add test cases that exercise ignored | 
| 666 // failures (both for kMissingExpectations_ErrorBitmask | 655 // failures (both for kMissingExpectations_ErrorType | 
| 667 // and kImageMismatch_ErrorBitmask). | 656 // and kImageMismatch_ErrorType). | 
| 668 this->fJsonActualResults_FailureIgnored[testName] = | 657 this->fJsonActualResults_FailureIgnored[testName] = | 
| 669 actualResults; | 658 actualResults; | 
| 670 } else { | 659 } else { | 
| 671 if (kEmptyErrorBitfield != (result & kMissingExpectations_ErrorB itmask)) { | 660 if (result.includes(kMissingExpectations_ErrorType)) { | 
| 672 // TODO: What about the case where there IS an | 661 // TODO: What about the case where there IS an | 
| 673 // expected image checksum, but that gm test | 662 // expected image checksum, but that gm test | 
| 674 // doesn't actually run? For now, those cases | 663 // doesn't actually run? For now, those cases | 
| 675 // will always be ignored, because gm only looks | 664 // will always be ignored, because gm only looks | 
| 676 // at expectations that correspond to gm tests | 665 // at expectations that correspond to gm tests | 
| 677 // that were actually run. | 666 // that were actually run. | 
| 678 // | 667 // | 
| 679 // Once we have the ability to express | 668 // Once we have the ability to express | 
| 680 // expectations as a JSON file, we should fix this | 669 // expectations as a JSON file, we should fix this | 
| 681 // (and add a test case for which an expectation | 670 // (and add a test case for which an expectation | 
| 682 // is given but the test is never run). | 671 // is given but the test is never run). | 
| 683 this->fJsonActualResults_NoComparison[testName] = | 672 this->fJsonActualResults_NoComparison[testName] = | 
| 684 actualResults; | 673 actualResults; | 
| 685 } | 674 } | 
| 686 if (kEmptyErrorBitfield != (result & kImageMismatch_ErrorBitmask )) { | 675 if (result.includes(kImageMismatch_ErrorType)) { | 
| 687 this->fJsonActualResults_Failed[testName] = actualResults; | 676 this->fJsonActualResults_Failed[testName] = actualResults; | 
| 688 } | 677 } | 
| 689 } | 678 } | 
| 690 } | 679 } | 
| 691 } | 680 } | 
| 692 | 681 | 
| 693 /** | 682 /** | 
| 694 * Add this test to the JSON collection of expected results. | 683 * Add this test to the JSON collection of expected results. | 
| 695 */ | 684 */ | 
| 696 void add_expected_results_to_json_summary(const char testName[], | 685 void add_expected_results_to_json_summary(const char testName[], | 
| (...skipping 12 matching lines...) Expand all Loading... | |
| 709 /** | 698 /** | 
| 710 * Compare actualBitmap to expectations stored in this->fExpectationsSource. | 699 * Compare actualBitmap to expectations stored in this->fExpectationsSource. | 
| 711 * | 700 * | 
| 712 * @param gm which test generated the actualBitmap | 701 * @param gm which test generated the actualBitmap | 
| 713 * @param gRec | 702 * @param gRec | 
| 714 * @param writePath unless this is NULL, write out actual images into this | 703 * @param writePath unless this is NULL, write out actual images into this | 
| 715 * directory | 704 * directory | 
| 716 * @param actualBitmap bitmap generated by this run | 705 * @param actualBitmap bitmap generated by this run | 
| 717 * @param pdf | 706 * @param pdf | 
| 718 */ | 707 */ | 
| 719 ErrorBitfield compare_test_results_to_stored_expectations( | 708 ErrorCombination compare_test_results_to_stored_expectations( | 
| 720 GM* gm, const ConfigData& gRec, const char writePath[], | 709 GM* gm, const ConfigData& gRec, const char writePath[], | 
| 721 SkBitmap& actualBitmap, SkDynamicMemoryWStream* pdf) { | 710 SkBitmap& actualBitmap, SkDynamicMemoryWStream* pdf) { | 
| 722 | 711 | 
| 723 SkString name = make_name(gm->shortName(), gRec.fName); | 712 SkString name = make_name(gm->shortName(), gRec.fName); | 
| 724 ErrorBitfield retval = kEmptyErrorBitfield; | 713 ErrorCombination errors; | 
| 725 | 714 | 
| 726 ExpectationsSource *expectationsSource = | 715 ExpectationsSource *expectationsSource = this->fExpectationsSource.get() ; | 
| 727 this->fExpectationsSource.get(); | |
| 728 if (expectationsSource && (gRec.fFlags & kRead_ConfigFlag)) { | 716 if (expectationsSource && (gRec.fFlags & kRead_ConfigFlag)) { | 
| 729 /* | 717 /* | 
| 730 * Get the expected results for this test, as one or more allowed | 718 * Get the expected results for this test, as one or more allowed | 
| 731 * checksums. The current implementation of expectationsSource | 719 * checksums. The current implementation of expectationsSource | 
| 732 * get this by computing the checksum of a single PNG file on disk. | 720 * get this by computing the checksum of a single PNG file on disk. | 
| 733 * | 721 * | 
| 734 * TODO(epoger): This relies on the fact that | 722 * TODO(epoger): This relies on the fact that | 
| 735 * force_all_opaque() was called on the bitmap before it | 723 * force_all_opaque() was called on the bitmap before it | 
| 736 * was written to disk as a PNG in the first place. If | 724 * was written to disk as a PNG in the first place. If | 
| 737 * not, the checksum returned here may not match the | 725 * not, the checksum returned here may not match the | 
| 738 * checksum of actualBitmap, which *has* been run through | 726 * checksum of actualBitmap, which *has* been run through | 
| 739 * force_all_opaque(). | 727 * force_all_opaque(). | 
| 740 * See comments above complete_bitmap() for more detail. | 728 * See comments above complete_bitmap() for more detail. | 
| 741 */ | 729 */ | 
| 742 Expectations expectations = expectationsSource->get(name.c_str()); | 730 Expectations expectations = expectationsSource->get(name.c_str()); | 
| 743 retval |= compare_to_expectations(expectations, actualBitmap, | 731 errors.add(compare_to_expectations(expectations, actualBitmap, | 
| 744 name, "", true); | 732 name, "", true)); | 
| 745 } else { | 733 } else { | 
| 746 // If we are running without expectations, we still want to | 734 // If we are running without expectations, we still want to | 
| 747 // record the actual results. | 735 // record the actual results. | 
| 748 Checksum actualChecksum = | 736 Checksum actualChecksum = | 
| 749 SkBitmapChecksummer::Compute64(actualBitmap); | 737 SkBitmapChecksummer::Compute64(actualBitmap); | 
| 750 add_actual_results_to_json_summary(name.c_str(), actualChecksum, | 738 add_actual_results_to_json_summary(name.c_str(), actualChecksum, | 
| 751 kMissingExpectations_ErrorBitmask , | 739 ErrorCombination(kMissingExpectat ions_ErrorType), | 
| 752 false); | 740 false); | 
| 753 } | 741 } | 
| 754 | 742 | 
| 755 // TODO: Consider moving this into compare_to_expectations(), | 743 // TODO: Consider moving this into compare_to_expectations(), | 
| 756 // similar to fMismatchPath... for now, we don't do that, because | 744 // similar to fMismatchPath... for now, we don't do that, because | 
| 757 // we don't want to write out the actual bitmaps for all | 745 // we don't want to write out the actual bitmaps for all | 
| 758 // renderModes of all tests! That would be a lot of files. | 746 // renderModes of all tests! That would be a lot of files. | 
| 759 if (writePath && (gRec.fFlags & kWrite_ConfigFlag)) { | 747 if (writePath && (gRec.fFlags & kWrite_ConfigFlag)) { | 
| 760 retval |= write_reference_image(gRec, writePath, "", | 748 errors.add(write_reference_image(gRec, writePath, "", | 
| 761 name, actualBitmap, pdf); | 749 name, actualBitmap, pdf)); | 
| 762 } | 750 } | 
| 763 | 751 | 
| 764 return retval; | 752 return errors; | 
| 765 } | 753 } | 
| 766 | 754 | 
| 767 /** | 755 /** | 
| 768 * Compare actualBitmap to referenceBitmap. | 756 * Compare actualBitmap to referenceBitmap. | 
| 769 * | 757 * | 
| 770 * @param gm which test generated the bitmap | 758 * @param gm which test generated the bitmap | 
| 771 * @param gRec | 759 * @param gRec | 
| 772 * @param renderModeDescriptor | 760 * @param renderModeDescriptor | 
| 773 * @param actualBitmap actual bitmap generated by this run | 761 * @param actualBitmap actual bitmap generated by this run | 
| 774 * @param referenceBitmap bitmap we expected to be generated | 762 * @param referenceBitmap bitmap we expected to be generated | 
| 775 */ | 763 */ | 
| 776 ErrorBitfield compare_test_results_to_reference_bitmap( | 764 ErrorCombination compare_test_results_to_reference_bitmap( | 
| 777 GM* gm, const ConfigData& gRec, const char renderModeDescriptor [], | 765 GM* gm, const ConfigData& gRec, const char renderModeDescriptor [], | 
| 778 SkBitmap& actualBitmap, const SkBitmap* referenceBitmap) { | 766 SkBitmap& actualBitmap, const SkBitmap* referenceBitmap) { | 
| 779 | 767 | 
| 780 SkASSERT(referenceBitmap); | 768 SkASSERT(referenceBitmap); | 
| 781 SkString name = make_name(gm->shortName(), gRec.fName); | 769 SkString name = make_name(gm->shortName(), gRec.fName); | 
| 782 Expectations expectations(*referenceBitmap); | 770 Expectations expectations(*referenceBitmap); | 
| 783 return compare_to_expectations(expectations, actualBitmap, | 771 return compare_to_expectations(expectations, actualBitmap, | 
| 784 name, renderModeDescriptor); | 772 name, renderModeDescriptor); | 
| 785 } | 773 } | 
| 786 | 774 | 
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 828 //char* dst = new char [streamSize]; | 816 //char* dst = new char [streamSize]; | 
| 829 //@todo thudson 22 April 2011 when can we safely delete [] dst? | 817 //@todo thudson 22 April 2011 when can we safely delete [] dst? | 
| 830 storage.copyTo(dst); | 818 storage.copyTo(dst); | 
| 831 SkMemoryStream pictReadback(dst, streamSize); | 819 SkMemoryStream pictReadback(dst, streamSize); | 
| 832 SkPicture* retval = new SkPicture (&pictReadback); | 820 SkPicture* retval = new SkPicture (&pictReadback); | 
| 833 return retval; | 821 return retval; | 
| 834 } | 822 } | 
| 835 | 823 | 
| 836 // Test: draw into a bitmap or pdf. | 824 // Test: draw into a bitmap or pdf. | 
| 837 // Depending on flags, possibly compare to an expected image. | 825 // Depending on flags, possibly compare to an expected image. | 
| 838 ErrorBitfield test_drawing(GM* gm, | 826 ErrorCombination test_drawing(GM* gm, | 
| 839 const ConfigData& gRec, | 827 const ConfigData& gRec, | 
| 840 const char writePath [], | 828 const char writePath [], | 
| 841 GrContext* context, | 829 GrContext* context, | 
| 842 GrRenderTarget* rt, | 830 GrRenderTarget* rt, | 
| 843 SkBitmap* bitmap) { | 831 SkBitmap* bitmap) { | 
| 844 SkDynamicMemoryWStream document; | 832 SkDynamicMemoryWStream document; | 
| 845 | 833 | 
| 846 if (gRec.fBackend == kRaster_Backend || | 834 if (gRec.fBackend == kRaster_Backend || | 
| 847 gRec.fBackend == kGPU_Backend) { | 835 gRec.fBackend == kGPU_Backend) { | 
| 848 // Early exit if we can't generate the image. | 836 // Early exit if we can't generate the image. | 
| 849 ErrorBitfield errors = generate_image(gm, gRec, context, rt, bitmap, | 837 ErrorCombination errors = generate_image(gm, gRec, context, rt, bitm ap, false); | 
| 850 false); | 838 if (!errors.isEmpty()) { | 
| 851 if (kEmptyErrorBitfield != errors) { | |
| 852 // TODO: Add a test to exercise what the stdout and | 839 // TODO: Add a test to exercise what the stdout and | 
| 853 // JSON look like if we get an "early error" while | 840 // JSON look like if we get an "early error" while | 
| 854 // trying to generate the image. | 841 // trying to generate the image. | 
| 855 return errors; | 842 return errors; | 
| 856 } | 843 } | 
| 857 } else if (gRec.fBackend == kPDF_Backend) { | 844 } else if (gRec.fBackend == kPDF_Backend) { | 
| 858 generate_pdf(gm, document); | 845 generate_pdf(gm, document); | 
| 859 #if CAN_IMAGE_PDF | 846 #if CAN_IMAGE_PDF | 
| 860 SkAutoDataUnref data(document.copyToData()); | 847 SkAutoDataUnref data(document.copyToData()); | 
| 861 SkMemoryStream stream(data->data(), data->size()); | 848 SkMemoryStream stream(data->data(), data->size()); | 
| 862 SkPDFDocumentToBitmap(&stream, bitmap); | 849 SkPDFDocumentToBitmap(&stream, bitmap); | 
| 863 #endif | 850 #endif | 
| 864 } else if (gRec.fBackend == kXPS_Backend) { | 851 } else if (gRec.fBackend == kXPS_Backend) { | 
| 865 generate_xps(gm, document); | 852 generate_xps(gm, document); | 
| 866 } | 853 } | 
| 867 return compare_test_results_to_stored_expectations( | 854 return compare_test_results_to_stored_expectations( | 
| 868 gm, gRec, writePath, *bitmap, &document); | 855 gm, gRec, writePath, *bitmap, &document); | 
| 869 } | 856 } | 
| 870 | 857 | 
| 871 ErrorBitfield test_deferred_drawing(GM* gm, | 858 ErrorCombination test_deferred_drawing(GM* gm, | 
| 872 const ConfigData& gRec, | 859 const ConfigData& gRec, | 
| 873 const SkBitmap& referenceBitmap, | 860 const SkBitmap& referenceBitmap, | 
| 874 GrContext* context, | 861 GrContext* context, | 
| 875 GrRenderTarget* rt) { | 862 GrRenderTarget* rt) { | 
| 876 SkDynamicMemoryWStream document; | 863 SkDynamicMemoryWStream document; | 
| 877 | 864 | 
| 878 if (gRec.fBackend == kRaster_Backend || | 865 if (gRec.fBackend == kRaster_Backend || | 
| 879 gRec.fBackend == kGPU_Backend) { | 866 gRec.fBackend == kGPU_Backend) { | 
| 880 SkBitmap bitmap; | 867 SkBitmap bitmap; | 
| 881 // Early exit if we can't generate the image, but this is | 868 // Early exit if we can't generate the image, but this is | 
| 882 // expected in some cases, so don't report a test failure. | 869 // expected in some cases, so don't report a test failure. | 
| 883 if (!generate_image(gm, gRec, context, rt, &bitmap, true)) { | 870 ErrorCombination errors = generate_image(gm, gRec, context, rt, &bit map, true); | 
| 884 return kEmptyErrorBitfield; | 871 // TODO(epoger): This logic is the opposite of what is | 
| 872 // described above... if we succeeded in generating the | |
| 873 // -deferred image, we exit early! We should fix this | |
| 874 // ASAP, because it is hiding -deferred errors... but for | |
| 875 // now, I'm leaving the logic as it is so that the | |
| 876 // refactoring change | |
| 877 // https://codereview.chromium.org/12992003/ is unblocked. | |
| 878 // | |
| 879 // Filed as https://code.google.com/p/skia/issues/detail?id=1180 | |
| 880 // ('image-surface gm test is failing in "deferred" mode, | |
| 881 // and gm is not reporting the failure') | |
| 882 if (errors.isEmpty()) { | |
| 883 return kEmpty_ErrorCombination; | |
| 885 } | 884 } | 
| 886 return compare_test_results_to_reference_bitmap( | 885 return compare_test_results_to_reference_bitmap( | 
| 887 gm, gRec, "-deferred", bitmap, &referenceBitmap); | 886 gm, gRec, "-deferred", bitmap, &referenceBitmap); | 
| 888 } | 887 } | 
| 889 return kEmptyErrorBitfield; | 888 return kEmpty_ErrorCombination; | 
| 890 } | 889 } | 
| 891 | 890 | 
| 892 ErrorBitfield test_pipe_playback(GM* gm, | 891 ErrorCombination test_pipe_playback(GM* gm, | 
| 893 const ConfigData& gRec, | 892 const ConfigData& gRec, | 
| 894 const SkBitmap& referenceBitmap) { | 893 const SkBitmap& referenceBitmap) { | 
| 895 ErrorBitfield errors = kEmptyErrorBitfield; | 894 ErrorCombination errors; | 
| 896 for (size_t i = 0; i < SK_ARRAY_COUNT(gPipeWritingFlagCombos); ++i) { | 895 for (size_t i = 0; i < SK_ARRAY_COUNT(gPipeWritingFlagCombos); ++i) { | 
| 897 SkBitmap bitmap; | 896 SkBitmap bitmap; | 
| 898 SkISize size = gm->getISize(); | 897 SkISize size = gm->getISize(); | 
| 899 setup_bitmap(gRec, size, &bitmap); | 898 setup_bitmap(gRec, size, &bitmap); | 
| 900 SkCanvas canvas(bitmap); | 899 SkCanvas canvas(bitmap); | 
| 901 installFilter(&canvas); | 900 installFilter(&canvas); | 
| 902 PipeController pipeController(&canvas); | 901 PipeController pipeController(&canvas); | 
| 903 SkGPipeWriter writer; | 902 SkGPipeWriter writer; | 
| 904 SkCanvas* pipeCanvas = writer.startRecording( | 903 SkCanvas* pipeCanvas = writer.startRecording( | 
| 905 &pipeController, gPipeWritingFlagCombos[i].flags); | 904 &pipeController, gPipeWritingFlagCombos[i].flags); | 
| 906 invokeGM(gm, pipeCanvas, false, false); | 905 invokeGM(gm, pipeCanvas, false, false); | 
| 907 complete_bitmap(&bitmap); | 906 complete_bitmap(&bitmap); | 
| 908 writer.endRecording(); | 907 writer.endRecording(); | 
| 909 SkString string("-pipe"); | 908 SkString string("-pipe"); | 
| 910 string.append(gPipeWritingFlagCombos[i].name); | 909 string.append(gPipeWritingFlagCombos[i].name); | 
| 911 errors |= compare_test_results_to_reference_bitmap( | 910 errors.add(compare_test_results_to_reference_bitmap( | 
| 912 gm, gRec, string.c_str(), bitmap, &referenceBitmap); | 911 gm, gRec, string.c_str(), bitmap, &referenceBitmap)); | 
| 913 if (errors != kEmptyErrorBitfield) { | 912 if (!errors.isEmpty()) { | 
| 914 break; | 913 break; | 
| 915 } | 914 } | 
| 916 } | 915 } | 
| 917 return errors; | 916 return errors; | 
| 918 } | 917 } | 
| 919 | 918 | 
| 920 ErrorBitfield test_tiled_pipe_playback( | 919 ErrorCombination test_tiled_pipe_playback(GM* gm, const ConfigData& gRec, | 
| 921 GM* gm, const ConfigData& gRec, const SkBitmap& referenceBitmap) { | 920 const SkBitmap& referenceBitmap) { | 
| 922 ErrorBitfield errors = kEmptyErrorBitfield; | 921 ErrorCombination errors; | 
| 923 for (size_t i = 0; i < SK_ARRAY_COUNT(gPipeWritingFlagCombos); ++i) { | 922 for (size_t i = 0; i < SK_ARRAY_COUNT(gPipeWritingFlagCombos); ++i) { | 
| 924 SkBitmap bitmap; | 923 SkBitmap bitmap; | 
| 925 SkISize size = gm->getISize(); | 924 SkISize size = gm->getISize(); | 
| 926 setup_bitmap(gRec, size, &bitmap); | 925 setup_bitmap(gRec, size, &bitmap); | 
| 927 SkCanvas canvas(bitmap); | 926 SkCanvas canvas(bitmap); | 
| 928 installFilter(&canvas); | 927 installFilter(&canvas); | 
| 929 TiledPipeController pipeController(bitmap); | 928 TiledPipeController pipeController(bitmap); | 
| 930 SkGPipeWriter writer; | 929 SkGPipeWriter writer; | 
| 931 SkCanvas* pipeCanvas = writer.startRecording( | 930 SkCanvas* pipeCanvas = writer.startRecording( | 
| 932 &pipeController, gPipeWritingFlagCombos[i].flags); | 931 &pipeController, gPipeWritingFlagCombos[i].flags); | 
| 933 invokeGM(gm, pipeCanvas, false, false); | 932 invokeGM(gm, pipeCanvas, false, false); | 
| 934 complete_bitmap(&bitmap); | 933 complete_bitmap(&bitmap); | 
| 935 writer.endRecording(); | 934 writer.endRecording(); | 
| 936 SkString string("-tiled pipe"); | 935 SkString string("-tiled pipe"); | 
| 937 string.append(gPipeWritingFlagCombos[i].name); | 936 string.append(gPipeWritingFlagCombos[i].name); | 
| 938 errors |= compare_test_results_to_reference_bitmap( | 937 errors.add(compare_test_results_to_reference_bitmap( | 
| 939 gm, gRec, string.c_str(), bitmap, &referenceBitmap); | 938 gm, gRec, string.c_str(), bitmap, &referenceBitmap)); | 
| 940 if (errors != kEmptyErrorBitfield) { | 939 if (!errors.isEmpty()) { | 
| 941 break; | 940 break; | 
| 942 } | 941 } | 
| 943 } | 942 } | 
| 944 return errors; | 943 return errors; | 
| 945 } | 944 } | 
| 946 | 945 | 
| 947 // | 946 // | 
| 948 // member variables. | 947 // member variables. | 
| 949 // They are public for now, to allow easier setting by tool_main(). | 948 // They are public for now, to allow easier setting by tool_main(). | 
| 950 // | 949 // | 
| 951 | 950 | 
| 952 bool fUseFileHierarchy; | 951 bool fUseFileHierarchy; | 
| 952 ErrorCombination fIgnorableErrorCombination; | |
| 953 | 953 | 
| 954 const char* fMismatchPath; | 954 const char* fMismatchPath; | 
| 955 | 955 | 
| 956 // information about all failed tests we have encountered so far | 956 // information about all failed tests we have encountered so far | 
| 957 SkTArray<FailRec> fFailedTests; | 957 SkTArray<FailRec> fFailedTests; | 
| 958 | 958 | 
| 959 // Where to read expectations (expected image checksums, etc.) from. | 959 // Where to read expectations (expected image checksums, etc.) from. | 
| 960 // If unset, we don't do comparisons. | 960 // If unset, we don't do comparisons. | 
| 961 SkAutoTUnref<ExpectationsSource> fExpectationsSource; | 961 SkAutoTUnref<ExpectationsSource> fExpectationsSource; | 
| 962 | 962 | 
| (...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1026 result.append(" "); | 1026 result.append(" "); | 
| 1027 } | 1027 } | 
| 1028 result.appendf("%s", gRec[i].fName); | 1028 result.appendf("%s", gRec[i].fName); | 
| 1029 } | 1029 } | 
| 1030 } | 1030 } | 
| 1031 result.appendf("\""); | 1031 result.appendf("\""); | 
| 1032 | 1032 | 
| 1033 return result; | 1033 return result; | 
| 1034 } | 1034 } | 
| 1035 | 1035 | 
| 1036 // Macro magic to convert a numeric preprocessor token into a string. | |
| 1037 // Adapted from http://stackoverflow.com/questions/240353/convert-a-preprocessor -token-to-a-string | |
| 1038 // This should probably be moved into one of our common headers... | |
| 1039 #define TOSTRING_INTERNAL(x) #x | |
| 1040 #define TOSTRING(x) TOSTRING_INTERNAL(x) | |
| 1041 | |
| 1036 // Alphabetized ignoring "no" prefix ("readPath", "noreplay", "resourcePath"). | 1042 // Alphabetized ignoring "no" prefix ("readPath", "noreplay", "resourcePath"). | 
| 1037 DEFINE_string(config, "", configUsage().c_str()); | 1043 DEFINE_string(config, "", configUsage().c_str()); | 
| 1038 DEFINE_bool(deferred, true, "Exercise the deferred rendering test pass."); | 1044 DEFINE_bool(deferred, true, "Exercise the deferred rendering test pass."); | 
| 1039 DEFINE_bool(enableMissingWarning, true, "Print message to stderr (but don't fail ) if " | 1045 DEFINE_bool(enableMissingWarning, true, "Print message to stderr (but don't fail ) if " | 
| 1040 "unable to read a reference image for any tests."); | 1046 "unable to read a reference image for any tests."); | 
| 1041 DEFINE_string(excludeConfig, "", "Space delimited list of configs to skip."); | 1047 DEFINE_string(excludeConfig, "", "Space delimited list of configs to skip."); | 
| 1042 DEFINE_bool(forceBWtext, false, "Disable text anti-aliasing."); | 1048 DEFINE_bool(forceBWtext, false, "Disable text anti-aliasing."); | 
| 1043 #if SK_SUPPORT_GPU | 1049 #if SK_SUPPORT_GPU | 
| 1044 DEFINE_string(gpuCacheSize, "", "<bytes> <count>: Limit the gpu cache to byte si ze or " | 1050 DEFINE_string(gpuCacheSize, "", "<bytes> <count>: Limit the gpu cache to byte si ze or " | 
| 1045 "object count. -1 for either value means use the default. 0 for ei ther " | 1051 "object count. " TOSTRING(DEFAULT_CACHE_VALUE) " for either value means " | 
| 1046 "disables the cache."); | 1052 "use the default. 0 for either disables the cache."); | 
| 1047 #endif | 1053 #endif | 
| 1048 DEFINE_bool(hierarchy, false, "Whether to use multilevel directory structure " | 1054 DEFINE_bool(hierarchy, false, "Whether to use multilevel directory structure " | 
| 1049 "when reading/writing files."); | 1055 "when reading/writing files."); | 
| 1050 DEFINE_string(match, "", "Only run tests whose name includes this substring/the se substrings " | 1056 DEFINE_string(match, "", "Only run tests whose name includes this substring/the se substrings " | 
| 1051 "(more than one can be supplied, separated by spaces)."); | 1057 "(more than one can be supplied, separated by spaces)."); | 
| 1052 DEFINE_string(mismatchPath, "", "Write images for tests that failed due to " | 1058 DEFINE_string(mismatchPath, "", "Write images for tests that failed due to " | 
| 1053 "pixel mismatches into this directory."); | 1059 "pixel mismatches into this directory."); | 
| 1054 DEFINE_string(modulo, "", "[--modulo <remainder> <divisor>]: only run tests for which " | 1060 DEFINE_string(modulo, "", "[--modulo <remainder> <divisor>]: only run tests for which " | 
| 1055 "testIndex %% divisor == remainder."); | 1061 "testIndex %% divisor == remainder."); | 
| 1056 DEFINE_bool(pdf, true, "Exercise the pdf rendering test pass."); | 1062 DEFINE_bool(pdf, true, "Exercise the pdf rendering test pass."); | 
| (...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1142 } | 1148 } | 
| 1143 } | 1149 } | 
| 1144 | 1150 | 
| 1145 /** | 1151 /** | 
| 1146 * Run this test in a number of different configs (8888, 565, PDF, | 1152 * Run this test in a number of different configs (8888, 565, PDF, | 
| 1147 * etc.), confirming that the resulting bitmaps match expectations | 1153 * etc.), confirming that the resulting bitmaps match expectations | 
| 1148 * (which may be different for each config). | 1154 * (which may be different for each config). | 
| 1149 * | 1155 * | 
| 1150 * Returns all errors encountered while doing so. | 1156 * Returns all errors encountered while doing so. | 
| 1151 */ | 1157 */ | 
| 1152 ErrorBitfield run_multiple_configs(GMMain &gmmain, GM *gm, const SkTDArray<size_ t> &configs, | 1158 ErrorCombination run_multiple_configs(GMMain &gmmain, GM *gm, const SkTDArray<si ze_t> &configs, | 
| 1153 GrContextFactory *grFactory); | 1159 GrContextFactory *grFactory); | 
| 1154 ErrorBitfield run_multiple_configs(GMMain &gmmain, GM *gm, const SkTDArray<size_ t> &configs, | 1160 ErrorCombination run_multiple_configs(GMMain &gmmain, GM *gm, const SkTDArray<si ze_t> &configs, | 
| 1155 GrContextFactory *grFactory) { | 1161 GrContextFactory *grFactory) { | 
| 1156 ErrorBitfield errorsForAllConfigs = kEmptyErrorBitfield; | 1162 ErrorCombination errorsForAllConfigs; | 
| 1157 uint32_t gmFlags = gm->getFlags(); | 1163 uint32_t gmFlags = gm->getFlags(); | 
| 1158 | 1164 | 
| 1159 #if SK_SUPPORT_GPU | |
| 1160 struct { | |
| 1161 int fBytes; | |
| 1162 int fCount; | |
| 1163 } gpuCacheSize = { -1, -1 }; // -1s mean use the default | |
| 1164 | |
| 1165 if (FLAGS_gpuCacheSize.count() > 0) { | |
| 1166 if (FLAGS_gpuCacheSize.count() != 2) { | |
| 1167 gm_fprintf(stderr, "--gpuCacheSize requires two arguments\n"); | |
| 1168 return -1; | |
| 1169 } | |
| 1170 gpuCacheSize.fBytes = atoi(FLAGS_gpuCacheSize[0]); | |
| 1171 gpuCacheSize.fCount = atoi(FLAGS_gpuCacheSize[1]); | |
| 1172 } | |
| 1173 #endif | |
| 1174 | |
| 1175 for (int i = 0; i < configs.count(); i++) { | 1165 for (int i = 0; i < configs.count(); i++) { | 
| 1176 ConfigData config = gRec[configs[i]]; | 1166 ConfigData config = gRec[configs[i]]; | 
| 1177 | 1167 | 
| 1178 // Skip any tests that we don't even need to try. | 1168 // Skip any tests that we don't even need to try. | 
| 1179 if ((kPDF_Backend == config.fBackend) && | 1169 if ((kPDF_Backend == config.fBackend) && | 
| 1180 (!FLAGS_pdf|| (gmFlags & GM::kSkipPDF_Flag))) { | 1170 (!FLAGS_pdf|| (gmFlags & GM::kSkipPDF_Flag))) { | 
| 1181 continue; | 1171 continue; | 
| 1182 } | 1172 } | 
| 1183 if ((gmFlags & GM::kSkip565_Flag) && | 1173 if ((gmFlags & GM::kSkip565_Flag) && | 
| 1184 (kRaster_Backend == config.fBackend) && | 1174 (kRaster_Backend == config.fBackend) && | 
| 1185 (SkBitmap::kRGB_565_Config == config.fConfig)) { | 1175 (SkBitmap::kRGB_565_Config == config.fConfig)) { | 
| 1186 continue; | 1176 continue; | 
| 1187 } | 1177 } | 
| 1188 if ((gmFlags & GM::kSkipGPU_Flag) && | 1178 if ((gmFlags & GM::kSkipGPU_Flag) && | 
| 1189 kGPU_Backend == config.fBackend) { | 1179 kGPU_Backend == config.fBackend) { | 
| 1190 continue; | 1180 continue; | 
| 1191 } | 1181 } | 
| 1192 | 1182 | 
| 1193 // Now we know that we want to run this test and record its | 1183 // Now we know that we want to run this test and record its | 
| 1194 // success or failure. | 1184 // success or failure. | 
| 1195 ErrorBitfield errorsForThisConfig = kEmptyErrorBitfield; | 1185 ErrorCombination errorsForThisConfig; | 
| 1196 GrRenderTarget* renderTarget = NULL; | 1186 GrRenderTarget* renderTarget = NULL; | 
| 1197 #if SK_SUPPORT_GPU | 1187 #if SK_SUPPORT_GPU | 
| 1198 SkAutoTUnref<GrRenderTarget> rt; | 1188 SkAutoTUnref<GrRenderTarget> rt; | 
| 1199 AutoResetGr autogr; | 1189 AutoResetGr autogr; | 
| 1200 if ((kEmptyErrorBitfield == errorsForThisConfig) && (kGPU_Backend == con fig.fBackend)) { | 1190 if ((errorsForThisConfig.isEmpty()) && (kGPU_Backend == config.fBackend) ) { | 
| 1201 GrContext* gr = grFactory->get(config.fGLContextType); | 1191 GrContext* gr = grFactory->get(config.fGLContextType); | 
| 1202 bool grSuccess = false; | 1192 bool grSuccess = false; | 
| 1203 if (gr) { | 1193 if (gr) { | 
| 1204 // create a render target to back the device | 1194 // create a render target to back the device | 
| 1205 GrTextureDesc desc; | 1195 GrTextureDesc desc; | 
| 1206 desc.fConfig = kSkia8888_GrPixelConfig; | 1196 desc.fConfig = kSkia8888_GrPixelConfig; | 
| 1207 desc.fFlags = kRenderTarget_GrTextureFlagBit; | 1197 desc.fFlags = kRenderTarget_GrTextureFlagBit; | 
| 1208 desc.fWidth = gm->getISize().width(); | 1198 desc.fWidth = gm->getISize().width(); | 
| 1209 desc.fHeight = gm->getISize().height(); | 1199 desc.fHeight = gm->getISize().height(); | 
| 1210 desc.fSampleCnt = config.fSampleCnt; | 1200 desc.fSampleCnt = config.fSampleCnt; | 
| 1211 GrTexture* tex = gr->createUncachedTexture(desc, NULL, 0); | 1201 GrTexture* tex = gr->createUncachedTexture(desc, NULL, 0); | 
| 1212 if (tex) { | 1202 if (tex) { | 
| 1213 rt.reset(tex->asRenderTarget()); | 1203 rt.reset(tex->asRenderTarget()); | 
| 1214 rt.get()->ref(); | 1204 rt.get()->ref(); | 
| 1215 tex->unref(); | 1205 tex->unref(); | 
| 1216 autogr.set(gr); | 1206 autogr.set(gr); | 
| 1217 renderTarget = rt.get(); | 1207 renderTarget = rt.get(); | 
| 1218 grSuccess = NULL != renderTarget; | 1208 grSuccess = NULL != renderTarget; | 
| 1219 } | 1209 } | 
| 1220 // Set the user specified cache limits if non-default. | 1210 // Set the user specified cache limits if non-default. | 
| 1221 size_t bytes; | 1211 size_t bytes; | 
| 1222 int count; | 1212 int count; | 
| 1223 gr->getTextureCacheLimits(&count, &bytes); | 1213 gr->getTextureCacheLimits(&count, &bytes); | 
| 1224 if (-1 != gpuCacheSize.fBytes) { | 1214 if (DEFAULT_CACHE_VALUE != gGpuCacheSizeBytes) { | 
| 1225 bytes = static_cast<size_t>(gpuCacheSize.fBytes); | 1215 bytes = static_cast<size_t>(gGpuCacheSizeBytes); | 
| 1226 } | 1216 } | 
| 1227 if (-1 != gpuCacheSize.fCount) { | 1217 if (DEFAULT_CACHE_VALUE != gGpuCacheSizeCount) { | 
| 1228 count = gpuCacheSize.fCount; | 1218 count = gGpuCacheSizeCount; | 
| 1229 } | 1219 } | 
| 1230 gr->setTextureCacheLimits(count, bytes); | 1220 gr->setTextureCacheLimits(count, bytes); | 
| 1231 } | 1221 } | 
| 1232 if (!grSuccess) { | 1222 if (!grSuccess) { | 
| 1233 errorsForThisConfig |= kNoGpuContext_ErrorBitmask; | 1223 errorsForThisConfig.add(kNoGpuContext_ErrorType); | 
| 1234 } | 1224 } | 
| 1235 } | 1225 } | 
| 1236 #endif | 1226 #endif | 
| 1237 | 1227 | 
| 1238 SkBitmap comparisonBitmap; | 1228 SkBitmap comparisonBitmap; | 
| 1239 | 1229 | 
| 1240 const char* writePath; | 1230 const char* writePath; | 
| 1241 if (FLAGS_writePath.count() == 1) { | 1231 if (FLAGS_writePath.count() == 1) { | 
| 1242 writePath = FLAGS_writePath[0]; | 1232 writePath = FLAGS_writePath[0]; | 
| 1243 } else { | 1233 } else { | 
| 1244 writePath = NULL; | 1234 writePath = NULL; | 
| 1245 } | 1235 } | 
| 1246 if (kEmptyErrorBitfield == errorsForThisConfig) { | 1236 if (errorsForThisConfig.isEmpty()) { | 
| 1247 errorsForThisConfig |= gmmain.test_drawing(gm, config, writePath, Ge tGr(), | 1237 errorsForThisConfig.add(gmmain.test_drawing(gm, config, writePath, G etGr(), | 
| 1248 renderTarget, &comparison Bitmap); | 1238 renderTarget, &compariso nBitmap)); | 
| 1249 } | 1239 } | 
| 1250 | 1240 | 
| 1251 if (FLAGS_deferred && !errorsForThisConfig && | 1241 if (FLAGS_deferred && errorsForThisConfig.isEmpty() && | 
| 1252 (kGPU_Backend == config.fBackend || | 1242 (kGPU_Backend == config.fBackend || kRaster_Backend == config.fBacke nd)) { | 
| 1253 kRaster_Backend == config.fBackend)) { | 1243 errorsForThisConfig.add(gmmain.test_deferred_drawing(gm, config, com parisonBitmap, | 
| 1254 errorsForThisConfig |= gmmain.test_deferred_drawing(gm, config, comp arisonBitmap, | 1244 GetGr(), render Target)); | 
| 1255 GetGr(), renderT arget); | |
| 1256 } | 1245 } | 
| 1257 | 1246 | 
| 1258 errorsForAllConfigs |= errorsForThisConfig; | 1247 errorsForAllConfigs.add(errorsForThisConfig); | 
| 1259 } | 1248 } | 
| 1260 return errorsForAllConfigs; | 1249 return errorsForAllConfigs; | 
| 1261 } | 1250 } | 
| 1262 | 1251 | 
| 1263 /** | 1252 /** | 
| 1264 * Run this test in a number of different drawing modes (pipe, | 1253 * Run this test in a number of different drawing modes (pipe, | 
| 1265 * deferred, tiled, etc.), confirming that the resulting bitmaps all | 1254 * deferred, tiled, etc.), confirming that the resulting bitmaps all | 
| 1266 * *exactly* match comparisonBitmap. | 1255 * *exactly* match comparisonBitmap. | 
| 1267 * | 1256 * | 
| 1268 * Returns all errors encountered while doing so. | 1257 * Returns all errors encountered while doing so. | 
| 1269 */ | 1258 */ | 
| 1270 ErrorBitfield run_multiple_modes(GMMain &gmmain, GM *gm, const ConfigData &compa reConfig, | 1259 ErrorCombination run_multiple_modes(GMMain &gmmain, GM *gm, const ConfigData &co mpareConfig, | 
| 1271 const SkBitmap &comparisonBitmap); | 1260 const SkBitmap &comparisonBitmap, | 
| 1272 ErrorBitfield run_multiple_modes(GMMain &gmmain, GM *gm, const ConfigData &compa reConfig, | 1261 const SkTDArray<SkScalar> &tileGridReplaySca les); | 
| 1273 const SkBitmap &comparisonBitmap) { | 1262 ErrorCombination run_multiple_modes(GMMain &gmmain, GM *gm, const ConfigData &co mpareConfig, | 
| 1274 SkTDArray<SkScalar> tileGridReplayScales; | 1263 const SkBitmap &comparisonBitmap, | 
| 1275 *tileGridReplayScales.append() = SK_Scalar1; // By default only test at scal e 1.0 | 1264 const SkTDArray<SkScalar> &tileGridReplaySca les) { | 
| 1276 if (FLAGS_tileGridReplayScales.count() > 0) { | 1265 ErrorCombination errorsForAllModes; | 
| 1277 tileGridReplayScales.reset(); | |
| 1278 for (int i = 0; i < FLAGS_tileGridReplayScales.count(); i++) { | |
| 1279 double val = atof(FLAGS_tileGridReplayScales[i]); | |
| 1280 if (0 < val) { | |
| 1281 *tileGridReplayScales.append() = SkDoubleToScalar(val); | |
| 1282 } | |
| 1283 } | |
| 1284 if (0 == tileGridReplayScales.count()) { | |
| 1285 // Should have at least one scale | |
| 1286 gm_fprintf(stderr, "--tileGridReplayScales requires at least one sca le.\n"); | |
| 1287 return -1; | |
| 1288 } | |
| 1289 } | |
| 1290 | |
| 1291 ErrorBitfield errorsForAllModes = kEmptyErrorBitfield; | |
| 1292 uint32_t gmFlags = gm->getFlags(); | 1266 uint32_t gmFlags = gm->getFlags(); | 
| 1293 | 1267 | 
| 1294 // run the picture centric GM steps | 1268 // run the picture centric GM steps | 
| 1295 if (!(gmFlags & GM::kSkipPicture_Flag)) { | 1269 if (!(gmFlags & GM::kSkipPicture_Flag)) { | 
| 1296 | 1270 | 
| 1297 ErrorBitfield pictErrors = kEmptyErrorBitfield; | 1271 ErrorCombination pictErrors; | 
| 1298 | 1272 | 
| 1299 //SkAutoTUnref<SkPicture> pict(generate_new_picture(gm)); | 1273 //SkAutoTUnref<SkPicture> pict(generate_new_picture(gm)); | 
| 1300 SkPicture* pict = gmmain.generate_new_picture(gm, kNone_BbhType, 0); | 1274 SkPicture* pict = gmmain.generate_new_picture(gm, kNone_BbhType, 0); | 
| 1301 SkAutoUnref aur(pict); | 1275 SkAutoUnref aur(pict); | 
| 1302 | 1276 | 
| 1303 if (FLAGS_replay) { | 1277 if (FLAGS_replay) { | 
| 1304 SkBitmap bitmap; | 1278 SkBitmap bitmap; | 
| 1305 gmmain.generate_image_from_picture(gm, compareConfig, pict, &bitmap) ; | 1279 gmmain.generate_image_from_picture(gm, compareConfig, pict, &bitmap) ; | 
| 1306 pictErrors |= gmmain.compare_test_results_to_reference_bitmap( | 1280 pictErrors.add(gmmain.compare_test_results_to_reference_bitmap( | 
| 1307 gm, compareConfig, "-replay", bitmap, &comparisonBitmap); | 1281 gm, compareConfig, "-replay", bitmap, &comparisonBitmap)); | 
| 1308 } | 1282 } | 
| 1309 | 1283 | 
| 1310 if ((kEmptyErrorBitfield == pictErrors) && FLAGS_serialize) { | 1284 if ((pictErrors.isEmpty()) && FLAGS_serialize) { | 
| 1311 SkPicture* repict = gmmain.stream_to_new_picture(*pict); | 1285 SkPicture* repict = gmmain.stream_to_new_picture(*pict); | 
| 1312 SkAutoUnref aurr(repict); | 1286 SkAutoUnref aurr(repict); | 
| 1313 | 1287 | 
| 1314 SkBitmap bitmap; | 1288 SkBitmap bitmap; | 
| 1315 gmmain.generate_image_from_picture(gm, compareConfig, repict, &bitma p); | 1289 gmmain.generate_image_from_picture(gm, compareConfig, repict, &bitma p); | 
| 1316 pictErrors |= gmmain.compare_test_results_to_reference_bitmap( | 1290 pictErrors.add(gmmain.compare_test_results_to_reference_bitmap( | 
| 1317 gm, compareConfig, "-serialize", bitmap, &comparisonBitmap); | 1291 gm, compareConfig, "-serialize", bitmap, &comparisonBitmap)); | 
| 1318 } | 1292 } | 
| 1319 | 1293 | 
| 1320 if (FLAGS_writePicturePath.count() == 1) { | 1294 if (FLAGS_writePicturePath.count() == 1) { | 
| 1321 const char* pictureSuffix = "skp"; | 1295 const char* pictureSuffix = "skp"; | 
| 1322 SkString path = make_filename(FLAGS_writePicturePath[0], "", | 1296 SkString path = make_filename(FLAGS_writePicturePath[0], "", | 
| 1323 gm->shortName(), pictureSuffix); | 1297 gm->shortName(), pictureSuffix); | 
| 1324 SkFILEWStream stream(path.c_str()); | 1298 SkFILEWStream stream(path.c_str()); | 
| 1325 pict->serialize(&stream); | 1299 pict->serialize(&stream); | 
| 1326 } | 1300 } | 
| 1327 | 1301 | 
| 1328 errorsForAllModes |= pictErrors; | 1302 errorsForAllModes.add(pictErrors); | 
| 1329 } | 1303 } | 
| 1330 | 1304 | 
| 1331 // TODO: add a test in which the RTree rendering results in a | 1305 // TODO: add a test in which the RTree rendering results in a | 
| 1332 // different bitmap than the standard rendering. It should | 1306 // different bitmap than the standard rendering. It should | 
| 1333 // show up as failed in the JSON summary, and should be listed | 1307 // show up as failed in the JSON summary, and should be listed | 
| 1334 // in the stdout also. | 1308 // in the stdout also. | 
| 1335 if (!(gmFlags & GM::kSkipPicture_Flag) && FLAGS_rtree) { | 1309 if (!(gmFlags & GM::kSkipPicture_Flag) && FLAGS_rtree) { | 
| 1336 SkPicture* pict = gmmain.generate_new_picture( | 1310 SkPicture* pict = gmmain.generate_new_picture( | 
| 1337 gm, kRTree_BbhType, SkPicture::kUsePathBoundsForClip_RecordingFlag); | 1311 gm, kRTree_BbhType, SkPicture::kUsePathBoundsForClip_RecordingFlag); | 
| 1338 SkAutoUnref aur(pict); | 1312 SkAutoUnref aur(pict); | 
| 1339 SkBitmap bitmap; | 1313 SkBitmap bitmap; | 
| 1340 gmmain.generate_image_from_picture(gm, compareConfig, pict, &bitmap); | 1314 gmmain.generate_image_from_picture(gm, compareConfig, pict, &bitmap); | 
| 1341 errorsForAllModes |= gmmain.compare_test_results_to_reference_bitmap( | 1315 errorsForAllModes.add(gmmain.compare_test_results_to_reference_bitmap( | 
| 1342 gm, compareConfig, "-rtree", bitmap, &comparisonBitmap); | 1316 gm, compareConfig, "-rtree", bitmap, &comparisonBitmap)); | 
| 1343 } | 1317 } | 
| 1344 | 1318 | 
| 1345 if (!(gmFlags & GM::kSkipPicture_Flag) && FLAGS_tileGrid) { | 1319 if (!(gmFlags & GM::kSkipPicture_Flag) && FLAGS_tileGrid) { | 
| 1346 for(int scaleIndex = 0; scaleIndex < tileGridReplayScales.count(); ++sca leIndex) { | 1320 for(int scaleIndex = 0; scaleIndex < tileGridReplayScales.count(); ++sca leIndex) { | 
| 1347 SkScalar replayScale = tileGridReplayScales[scaleIndex]; | 1321 SkScalar replayScale = tileGridReplayScales[scaleIndex]; | 
| 1348 if ((gmFlags & GM::kSkipScaledReplay_Flag) && replayScale != 1) { | 1322 if ((gmFlags & GM::kSkipScaledReplay_Flag) && replayScale != 1) { | 
| 1349 continue; | 1323 continue; | 
| 1350 } | 1324 } | 
| 1351 // We record with the reciprocal scale to obtain a replay | 1325 // We record with the reciprocal scale to obtain a replay | 
| 1352 // result that can be validated against comparisonBitmap. | 1326 // result that can be validated against comparisonBitmap. | 
| 1353 SkScalar recordScale = SkScalarInvert(replayScale); | 1327 SkScalar recordScale = SkScalarInvert(replayScale); | 
| 1354 SkPicture* pict = gmmain.generate_new_picture( | 1328 SkPicture* pict = gmmain.generate_new_picture( | 
| 1355 gm, kTileGrid_BbhType, SkPicture::kUsePathBoundsForClip_Recordin gFlag, recordScale); | 1329 gm, kTileGrid_BbhType, SkPicture::kUsePathBoundsForClip_Recordin gFlag, recordScale); | 
| 1356 SkAutoUnref aur(pict); | 1330 SkAutoUnref aur(pict); | 
| 1357 SkBitmap bitmap; | 1331 SkBitmap bitmap; | 
| 1358 gmmain.generate_image_from_picture(gm, compareConfig, pict, &bitmap, replayScale); | 1332 gmmain.generate_image_from_picture(gm, compareConfig, pict, &bitmap, replayScale); | 
| 1359 SkString suffix("-tilegrid"); | 1333 SkString suffix("-tilegrid"); | 
| 1360 if (SK_Scalar1 != replayScale) { | 1334 if (SK_Scalar1 != replayScale) { | 
| 1361 suffix += "-scale-"; | 1335 suffix += "-scale-"; | 
| 1362 suffix.appendScalar(replayScale); | 1336 suffix.appendScalar(replayScale); | 
| 1363 } | 1337 } | 
| 1364 errorsForAllModes |= gmmain.compare_test_results_to_reference_bitmap ( | 1338 errorsForAllModes.add(gmmain.compare_test_results_to_reference_bitma p( | 
| 1365 gm, compareConfig, suffix.c_str(), bitmap, &comparisonBitmap); | 1339 gm, compareConfig, suffix.c_str(), bitmap, &comparisonBitmap)); | 
| 1366 } | 1340 } | 
| 1367 } | 1341 } | 
| 1368 | 1342 | 
| 1369 // run the pipe centric GM steps | 1343 // run the pipe centric GM steps | 
| 1370 if (!(gmFlags & GM::kSkipPipe_Flag)) { | 1344 if (!(gmFlags & GM::kSkipPipe_Flag)) { | 
| 1371 | 1345 | 
| 1372 ErrorBitfield pipeErrors = kEmptyErrorBitfield; | 1346 ErrorCombination pipeErrors; | 
| 1373 | 1347 | 
| 1374 if (FLAGS_pipe) { | 1348 if (FLAGS_pipe) { | 
| 1375 pipeErrors |= gmmain.test_pipe_playback(gm, compareConfig, compariso nBitmap); | 1349 pipeErrors.add(gmmain.test_pipe_playback(gm, compareConfig, comparis onBitmap)); | 
| 1376 } | 1350 } | 
| 1377 | 1351 | 
| 1378 if ((kEmptyErrorBitfield == pipeErrors) && | 1352 if ((pipeErrors.isEmpty()) && | 
| 1379 FLAGS_tiledPipe && !(gmFlags & GM::kSkipTiled_Flag)) { | 1353 FLAGS_tiledPipe && !(gmFlags & GM::kSkipTiled_Flag)) { | 
| 1380 pipeErrors |= gmmain.test_tiled_pipe_playback(gm, compareConfig, com parisonBitmap); | 1354 pipeErrors.add(gmmain.test_tiled_pipe_playback(gm, compareConfig, co mparisonBitmap)); | 
| 1381 } | 1355 } | 
| 1382 | 1356 | 
| 1383 errorsForAllModes |= pipeErrors; | 1357 errorsForAllModes.add(pipeErrors); | 
| 1384 } | 1358 } | 
| 1385 return errorsForAllModes; | 1359 return errorsForAllModes; | 
| 1386 } | 1360 } | 
| 1387 | 1361 | 
| 1388 int tool_main(int argc, char** argv); | 1362 int tool_main(int argc, char** argv); | 
| 1389 int tool_main(int argc, char** argv) { | 1363 int tool_main(int argc, char** argv) { | 
| 1390 | 1364 | 
| 1391 #if SK_ENABLE_INST_COUNT | 1365 #if SK_ENABLE_INST_COUNT | 
| 1392 gPrintInstCount = true; | 1366 gPrintInstCount = true; | 
| 1393 #endif | 1367 #endif | 
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1439 | 1413 | 
| 1440 if (FLAGS_modulo.count() == 2) { | 1414 if (FLAGS_modulo.count() == 2) { | 
| 1441 moduloRemainder = atoi(FLAGS_modulo[0]); | 1415 moduloRemainder = atoi(FLAGS_modulo[0]); | 
| 1442 moduloDivisor = atoi(FLAGS_modulo[1]); | 1416 moduloDivisor = atoi(FLAGS_modulo[1]); | 
| 1443 if (moduloRemainder < 0 || moduloDivisor <= 0 || moduloRemainder >= modu loDivisor) { | 1417 if (moduloRemainder < 0 || moduloDivisor <= 0 || moduloRemainder >= modu loDivisor) { | 
| 1444 gm_fprintf(stderr, "invalid modulo values."); | 1418 gm_fprintf(stderr, "invalid modulo values."); | 
| 1445 return -1; | 1419 return -1; | 
| 1446 } | 1420 } | 
| 1447 } | 1421 } | 
| 1448 | 1422 | 
| 1423 #if SK_SUPPORT_GPU | |
| 1424 if (FLAGS_gpuCacheSize.count() > 0) { | |
| 1425 if (FLAGS_gpuCacheSize.count() != 2) { | |
| 1426 gm_fprintf(stderr, "--gpuCacheSize requires two arguments\n"); | |
| 1427 return -1; | |
| 1428 } | |
| 1429 gGpuCacheSizeBytes = atoi(FLAGS_gpuCacheSize[0]); | |
| 1430 gGpuCacheSizeCount = atoi(FLAGS_gpuCacheSize[1]); | |
| 1431 } else { | |
| 1432 gGpuCacheSizeBytes = DEFAULT_CACHE_VALUE; | |
| 1433 gGpuCacheSizeCount = DEFAULT_CACHE_VALUE; | |
| 1434 } | |
| 1435 #endif | |
| 1436 | |
| 1437 SkTDArray<SkScalar> tileGridReplayScales; | |
| 1438 *tileGridReplayScales.append() = SK_Scalar1; // By default only test at scal e 1.0 | |
| 1439 if (FLAGS_tileGridReplayScales.count() > 0) { | |
| 1440 tileGridReplayScales.reset(); | |
| 1441 for (int i = 0; i < FLAGS_tileGridReplayScales.count(); i++) { | |
| 1442 double val = atof(FLAGS_tileGridReplayScales[i]); | |
| 1443 if (0 < val) { | |
| 1444 *tileGridReplayScales.append() = SkDoubleToScalar(val); | |
| 1445 } | |
| 1446 } | |
| 1447 if (0 == tileGridReplayScales.count()) { | |
| 1448 // Should have at least one scale | |
| 1449 gm_fprintf(stderr, "--tileGridReplayScales requires at least one sca le.\n"); | |
| 1450 return -1; | |
| 1451 } | |
| 1452 } | |
| 1453 | |
| 1449 if (!userConfig) { | 1454 if (!userConfig) { | 
| 1450 // if no config is specified by user, add the defaults | 1455 // if no config is specified by user, add the defaults | 
| 1451 for (size_t i = 0; i < SK_ARRAY_COUNT(gRec); ++i) { | 1456 for (size_t i = 0; i < SK_ARRAY_COUNT(gRec); ++i) { | 
| 1452 if (gRec[i].fRunByDefault) { | 1457 if (gRec[i].fRunByDefault) { | 
| 1453 *configs.append() = i; | 1458 *configs.append() = i; | 
| 1454 } | 1459 } | 
| 1455 } | 1460 } | 
| 1456 } | 1461 } | 
| 1457 // now remove any explicitly excluded configs | 1462 // now remove any explicitly excluded configs | 
| 1458 for (int i = 0; i < excludeConfigs.count(); ++i) { | 1463 for (int i = 0; i < excludeConfigs.count(); ++i) { | 
| (...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1577 const char* shortName = gm->shortName(); | 1582 const char* shortName = gm->shortName(); | 
| 1578 if (skip_name(FLAGS_match, shortName)) { | 1583 if (skip_name(FLAGS_match, shortName)) { | 
| 1579 SkDELETE(gm); | 1584 SkDELETE(gm); | 
| 1580 continue; | 1585 continue; | 
| 1581 } | 1586 } | 
| 1582 | 1587 | 
| 1583 SkISize size = gm->getISize(); | 1588 SkISize size = gm->getISize(); | 
| 1584 gm_fprintf(stdout, "%sdrawing... %s [%d %d]\n", moduloStr.c_str(), short Name, | 1589 gm_fprintf(stdout, "%sdrawing... %s [%d %d]\n", moduloStr.c_str(), short Name, | 
| 1585 size.width(), size.height()); | 1590 size.width(), size.height()); | 
| 1586 | 1591 | 
| 1587 ErrorBitfield testErrors = kEmptyErrorBitfield; | 1592 ErrorCombination testErrors; | 
| 1588 testErrors |= run_multiple_configs(gmmain, gm, configs, grFactory); | 1593 testErrors.add(run_multiple_configs(gmmain, gm, configs, grFactory)); | 
| 1589 | 1594 | 
| 1590 SkBitmap comparisonBitmap; | 1595 SkBitmap comparisonBitmap; | 
| 1591 const ConfigData compareConfig = | 1596 const ConfigData compareConfig = | 
| 1592 { SkBitmap::kARGB_8888_Config, kRaster_Backend, kDontCare_GLContextT ype, 0, kRW_ConfigFlag, "comparison", false }; | 1597 { SkBitmap::kARGB_8888_Config, kRaster_Backend, kDontCare_GLContextT ype, 0, kRW_ConfigFlag, "comparison", false }; | 
| 1593 testErrors |= gmmain.generate_image(gm, compareConfig, NULL, NULL, &comp arisonBitmap, false); | 1598 testErrors.add(gmmain.generate_image( | 
| 1599 gm, compareConfig, NULL, NULL, &comparisonBitmap, false)); | |
| 1594 | 1600 | 
| 1595 // TODO(epoger): only run this if gmmain.generate_image() succeeded? | 1601 // TODO(epoger): only run this if gmmain.generate_image() succeeded? | 
| 1596 // Otherwise, what are we comparing against? | 1602 // Otherwise, what are we comparing against? | 
| 1597 testErrors |= run_multiple_modes(gmmain, gm, compareConfig, comparisonBi tmap); | 1603 testErrors.add(run_multiple_modes(gmmain, gm, compareConfig, comparisonB itmap, | 
| 1604 tileGridReplayScales)); | |
| 1598 | 1605 | 
| 1599 // Update overall results. | 1606 // Update overall results. | 
| 1600 // We only tabulate the particular error types that we currently | 1607 // We only tabulate the particular error types that we currently | 
| 1601 // care about (e.g., missing reference images). Later on, if we | 1608 // care about (e.g., missing reference images). Later on, if we | 
| 1602 // want to also tabulate other error types, we can do so. | 1609 // want to also tabulate other error types, we can do so. | 
| 1603 testsRun++; | 1610 testsRun++; | 
| 1604 if (!gmmain.fExpectationsSource.get() || | 1611 if (!gmmain.fExpectationsSource.get() || | 
| 1605 (kEmptyErrorBitfield != (kMissingExpectations_ErrorBitmask & testErr ors))) { | 1612 (testErrors.includes(kMissingExpectations_ErrorType))) { | 
| 1606 testsMissingReferenceImages++; | 1613 testsMissingReferenceImages++; | 
| 1607 } | 1614 } | 
| 1608 if (testErrors == (testErrors & kIgnorable_ErrorBitmask)) { | 1615 if (testErrors.minus(gmmain.fIgnorableErrorCombination).isEmpty()) { | 
| 1609 testsPassed++; | 1616 testsPassed++; | 
| 1610 } else { | 1617 } else { | 
| 1611 testsFailed++; | 1618 testsFailed++; | 
| 1612 } | 1619 } | 
| 1613 | 1620 | 
| 1614 SkDELETE(gm); | 1621 SkDELETE(gm); | 
| 1615 } | 1622 } | 
| 1616 gm_fprintf(stdout, "Ran %d tests: %d passed, %d failed, %d missing reference images\n", | 1623 gm_fprintf(stdout, "Ran %d tests: %d passed, %d failed, %d missing reference images\n", | 
| 1617 testsRun, testsPassed, testsFailed, testsMissingReferenceImages); | 1624 testsRun, testsPassed, testsFailed, testsMissingReferenceImages); | 
| 1618 gmmain.ListErrors(); | 1625 gmmain.ListErrors(); | 
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1661 if (FLAGS_forceBWtext) { | 1668 if (FLAGS_forceBWtext) { | 
| 1662 canvas->setDrawFilter(SkNEW(BWTextDrawFilter))->unref(); | 1669 canvas->setDrawFilter(SkNEW(BWTextDrawFilter))->unref(); | 
| 1663 } | 1670 } | 
| 1664 } | 1671 } | 
| 1665 | 1672 | 
| 1666 #if !defined(SK_BUILD_FOR_IOS) && !defined(SK_BUILD_FOR_NACL) | 1673 #if !defined(SK_BUILD_FOR_IOS) && !defined(SK_BUILD_FOR_NACL) | 
| 1667 int main(int argc, char * const argv[]) { | 1674 int main(int argc, char * const argv[]) { | 
| 1668 return tool_main(argc, (char**) argv); | 1675 return tool_main(argc, (char**) argv); | 
| 1669 } | 1676 } | 
| 1670 #endif | 1677 #endif | 
| OLD | NEW |