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/SkSurface.h"
13 #include "include/effects/SkImageFilters.h"
14 #include "include/encode/SkPngEncoder.h"
15 #include "src/utils/SkOSPath.h"
16
17 /** Checks the given VerifierResult. If it is not ok, returns it. */
18 #define RETURN_NOT_OK(res) if (!(res).ok()) return (res)
19
20 namespace skiagm {
21 namespace verifiers {
22
VerifierResult()23 VerifierResult::VerifierResult() : VerifierResult(Code::kOk, SkString("Ok")) {}
24
VerifierResult(VerifierResult::Code code,const SkString & msg)25 VerifierResult::VerifierResult(VerifierResult::Code code, const SkString& msg) :
26 fCode(code), fMessage(msg) {}
27
ok() const28 bool VerifierResult::ok() const {
29 return fCode == Code::kOk;
30 }
31
message() const32 const SkString& VerifierResult::message() const {
33 return fMessage;
34 }
35
Ok()36 VerifierResult VerifierResult::Ok() {
37 return VerifierResult(Code::kOk, SkString("Ok"));
38 }
39
Fail(const SkString & msg)40 VerifierResult VerifierResult::Fail(const SkString& msg) {
41 return VerifierResult(Code::kFail, msg);
42 }
43
GMVerifier(InputType inputType)44 GMVerifier::GMVerifier(InputType inputType) : fInputType(inputType) {}
45
~GMVerifier()46 GMVerifier::~GMVerifier() {}
47
needsGoldImage() const48 bool GMVerifier::needsGoldImage() const {
49 return fInputType == InputType::kGoldImageRequired;
50 }
51
verify(const SkBitmap & gold,const SkBitmap & actual)52 VerifierResult GMVerifier::verify(const SkBitmap& gold, const SkBitmap& actual) {
53 // Call into specific implementation.
54 return verifyWithGold(actual.bounds(), gold, actual);
55 }
56
verify(const SkBitmap & actual)57 VerifierResult GMVerifier::verify(const SkBitmap& actual) {
58 // Call into specific implementation.
59 return verify(actual.bounds(), actual);
60 }
61
RenderGoldBmp(skiagm::GM * gm,const SkColorInfo & colorInfo)62 SkBitmap GMVerifier::RenderGoldBmp(skiagm::GM* gm, const SkColorInfo& colorInfo) {
63 SkASSERT(gm);
64
65 // Call into the GM instance to get the initial image.
66 const SkISize size = gm->getISize();
67 SkBitmap goldBmp;
68 goldBmp.allocPixels(SkImageInfo::Make(size, colorInfo));
69 SkCanvas canvas(goldBmp);
70 gm->draw(&canvas);
71
72 // Convert into common verifier colorspace.
73 SkBitmap goldVerifierBmp;
74 goldVerifierBmp.allocPixels(SkImageInfo::Make(size, VerifierColorInfo()));
75 SkCanvas verifierCanvas(goldVerifierBmp);
76 verifierCanvas.drawBitmap(goldBmp, 0, 0);
77
78 return goldVerifierBmp;
79 }
80
VerifierColorInfo()81 SkColorInfo GMVerifier::VerifierColorInfo() {
82 return SkColorInfo(
83 kRGBA_F16_SkColorType, kPremul_SkAlphaType,
84 SkColorSpace::MakeRGB(SkNamedTransferFn::kRec2020, SkNamedGamut::kRec2020));
85 }
86
makeError(const SkString & msg) const87 VerifierResult GMVerifier::makeError(const SkString& msg) const {
88 return VerifierResult::Fail(SkStringPrintf("[%s] %s", name().c_str(), msg.c_str()));
89 }
90
VerifierList(GM * gm)91 VerifierList::VerifierList(GM* gm) : fGM(gm), fFailedVerifier(nullptr) {}
92
add(std::unique_ptr<GMVerifier> verifier)93 void VerifierList::add(std::unique_ptr<GMVerifier> verifier) {
94 fVerifiers.push_back(std::move(verifier));
95 }
96
needsGoldImage() const97 bool VerifierList::needsGoldImage() const {
98 for (const auto& v : fVerifiers) {
99 if (v->needsGoldImage()) {
100 return true;
101 }
102 }
103
104 return false;
105 }
106
verifyAll(const SkColorInfo & colorInfo,const SkBitmap & actual)107 VerifierResult VerifierList::verifyAll(const SkColorInfo& colorInfo, const SkBitmap& actual) {
108 // Render the golden image if any verifiers need it.
109 SkBitmap goldBmp;
110 if (needsGoldImage()) {
111 goldBmp = GMVerifier::RenderGoldBmp(fGM, colorInfo);
112 }
113
114 for (const auto& v : fVerifiers) {
115 fFailedVerifier = v.get();
116 if (v->needsGoldImage()) {
117 RETURN_NOT_OK(v->verify(goldBmp, actual));
118 } else {
119 RETURN_NOT_OK(v->verify(actual));
120 }
121 }
122
123 fFailedVerifier = nullptr;
124 return VerifierResult::Ok();
125 }
126
127 }
128 }
129