1 /*
2 * Copyright 2020 Google Inc.
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
7
8 #include "gm/gm.h"
9 #include "gm/verifiers/gmverifier.h"
10 #include "include/core/SkBitmap.h"
11 #include "include/core/SkCanvas.h"
12 #include "include/core/SkColorSpace.h"
13 #include "include/core/SkSurface.h"
14 #include "include/effects/SkImageFilters.h"
15 #include "include/encode/SkPngEncoder.h"
16 #include "src/utils/SkOSPath.h"
17
18 /** Checks the given VerifierResult. If it is not ok, returns it. */
19 #define RETURN_NOT_OK(res) if (!(res).ok()) return (res)
20
21 namespace skiagm {
22 namespace verifiers {
23
VerifierResult()24 VerifierResult::VerifierResult() : VerifierResult(Code::kOk, SkString("Ok")) {}
25
VerifierResult(VerifierResult::Code code,const SkString & msg)26 VerifierResult::VerifierResult(VerifierResult::Code code, const SkString& msg) :
27 fCode(code), fMessage(msg) {}
28
ok() const29 bool VerifierResult::ok() const {
30 return fCode == Code::kOk;
31 }
32
message() const33 const SkString& VerifierResult::message() const {
34 return fMessage;
35 }
36
Ok()37 VerifierResult VerifierResult::Ok() {
38 return VerifierResult(Code::kOk, SkString("Ok"));
39 }
40
Fail(const SkString & msg)41 VerifierResult VerifierResult::Fail(const SkString& msg) {
42 return VerifierResult(Code::kFail, msg);
43 }
44
GMVerifier(InputType inputType)45 GMVerifier::GMVerifier(InputType inputType) : fInputType(inputType) {}
46
~GMVerifier()47 GMVerifier::~GMVerifier() {}
48
needsGoldImage() const49 bool GMVerifier::needsGoldImage() const {
50 return fInputType == InputType::kGoldImageRequired;
51 }
52
verify(const SkBitmap & gold,const SkBitmap & actual)53 VerifierResult GMVerifier::verify(const SkBitmap& gold, const SkBitmap& actual) {
54 // Call into specific implementation.
55 return verifyWithGold(actual.bounds(), gold, actual);
56 }
57
verify(const SkBitmap & actual)58 VerifierResult GMVerifier::verify(const SkBitmap& actual) {
59 // Call into specific implementation.
60 return verify(actual.bounds(), actual);
61 }
62
RenderGoldBmp(skiagm::GM * gm,const SkColorInfo & colorInfo)63 SkBitmap GMVerifier::RenderGoldBmp(skiagm::GM* gm, const SkColorInfo& colorInfo) {
64 SkASSERT(gm);
65
66 // Call into the GM instance to get the initial image.
67 const SkISize size = gm->getISize();
68 SkBitmap goldBmp;
69 goldBmp.allocPixels(SkImageInfo::Make(size, colorInfo));
70 SkCanvas canvas(goldBmp);
71
72 if (gm->gpuSetup(&canvas) == DrawResult::kOk) {
73 gm->draw(&canvas);
74 }
75
76 // Convert into common verifier colorspace.
77 SkBitmap goldVerifierBmp;
78 goldVerifierBmp.allocPixels(SkImageInfo::Make(size, VerifierColorInfo()));
79 SkCanvas verifierCanvas(goldVerifierBmp);
80 verifierCanvas.drawImage(goldBmp.asImage(), 0, 0);
81
82 return goldVerifierBmp;
83 }
84
VerifierColorInfo()85 SkColorInfo GMVerifier::VerifierColorInfo() {
86 return SkColorInfo(
87 kRGBA_F16_SkColorType, kPremul_SkAlphaType,
88 SkColorSpace::MakeRGB(SkNamedTransferFn::kRec2020, SkNamedGamut::kRec2020));
89 }
90
makeError(const SkString & msg) const91 VerifierResult GMVerifier::makeError(const SkString& msg) const {
92 return VerifierResult::Fail(SkStringPrintf("[%s] %s", name().c_str(), msg.c_str()));
93 }
94
VerifierList(GM * gm)95 VerifierList::VerifierList(GM* gm) : fGM(gm), fFailedVerifier(nullptr) {}
96
add(std::unique_ptr<GMVerifier> verifier)97 void VerifierList::add(std::unique_ptr<GMVerifier> verifier) {
98 fVerifiers.push_back(std::move(verifier));
99 }
100
needsGoldImage() const101 bool VerifierList::needsGoldImage() const {
102 for (const auto& v : fVerifiers) {
103 if (v->needsGoldImage()) {
104 return true;
105 }
106 }
107
108 return false;
109 }
110
verifyAll(const SkColorInfo & colorInfo,const SkBitmap & actual)111 VerifierResult VerifierList::verifyAll(const SkColorInfo& colorInfo, const SkBitmap& actual) {
112 // Render the golden image if any verifiers need it.
113 SkBitmap goldBmp;
114 if (needsGoldImage()) {
115 goldBmp = GMVerifier::RenderGoldBmp(fGM, colorInfo);
116 }
117
118 for (const auto& v : fVerifiers) {
119 fFailedVerifier = v.get();
120 if (v->needsGoldImage()) {
121 RETURN_NOT_OK(v->verify(goldBmp, actual));
122 } else {
123 RETURN_NOT_OK(v->verify(actual));
124 }
125 }
126
127 fFailedVerifier = nullptr;
128 return VerifierResult::Ok();
129 }
130
131 } // namespace verifiers
132 } // namespace skiagm
133