blob: 0bbd7ff95e9f9a14a60cf049dc66198de478122c [file] [log] [blame]
Tyler Denniston45f94f82020-02-04 16:09:08 -05001/*
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#ifndef gmverifier_DEFINED
9#define gmverifier_DEFINED
10
11#include "include/core/SkColor.h"
12#include "include/core/SkRect.h"
13#include "include/core/SkString.h"
14
15#include <vector>
16
17class SkBitmap;
18
19namespace skiagm {
20
21class GM;
22
23namespace verifiers {
24
25/** Result type for GM verifiers. */
26class VerifierResult {
27public:
28 VerifierResult();
29
30 /** Returns true if the result is ok (non-error). */
31 bool ok() const;
32
33 /** Returns reference to any message associated with the result. */
34 const SkString& message() const;
35
36 /** Constructs an "ok" (non-error) result. */
37 static VerifierResult Ok();
38
39 /** Constructs a "fail" (error) result with a specific message. */
40 static VerifierResult Fail(const SkString& msg);
41
42private:
43 /** Underlying error code. */
44 enum class Code {
45 kOk, kFail
46 };
47
48 /** Result code */
49 Code fCode;
50
51 /** Result message (may be empty). */
52 SkString fMessage;
53
54 /** Private constructor for a result with a specific code and message. */
55 VerifierResult(Code code, const SkString& msg);
56};
57
58/**
59 * Abstract base class for GM verifiers. A verifier checks the rendered output image of a GM.
60 *
61 * Different verifiers perform different types of transforms and checks. Verifiers may check the
62 * output of a GM against a given "golden" image which represents the correct output, or just
63 * check the output image of the GM by itself.
64 *
65 * Most verifiers have configurable fuzziness in the comparisons performed against the golden image.
66 *
67 * Subclasses should inherit from one of StandaloneVerifier or GoldImageVerifier instead of
68 * directly from this base class.
69 */
70class GMVerifier {
71public:
72 GMVerifier() = delete;
73
74 virtual ~GMVerifier();
75
76 /** Returns the human-friendly name of the verifier. */
77 virtual SkString name() const = 0;
78
79 /** Returns true if this verifier needs the gold image as input. */
80 bool needsGoldImage() const;
81
82 /**
83 * Runs the verifier. This method should be used if the verifier needs the gold image as input.
84 *
85 * @param gold Bitmap containing the "correct" image.
86 * @param actual Bitmap containing rendered output of a GM.
87 * @return Ok if the verification passed, or an error if not.
88 */
89 VerifierResult verify(const SkBitmap& gold, const SkBitmap& actual);
90
91 /**
92 * Runs the verifier.
93 *
94 * @param actual Bitmap containing rendered output of a GM.
95 * @return Ok if the verification passed, or an error if not.
96 */
97 VerifierResult verify(const SkBitmap& actual);
98
99 /** Renders the GM using the "golden" configuration. This is common across all GMs/verifiers. */
100 static SkBitmap RenderGoldBmp(skiagm::GM* gm, const SkColorInfo& colorInfo);
101
102 /**
103 * Gets the color information that all verifier inputs should be transformed into.
104 *
105 * The primary reason for having a single shared colorspace/color type is making per-pixel
106 * comparisons easier. Both the image under test and gold image are transformed into a shared
107 * colorspace which allows for getting per-pixel colors in SkColor4f.
108 */
109 static SkColorInfo VerifierColorInfo();
110
111protected:
112 /** The type of input required for the verifier. */
113 enum class InputType {
114 kGoldImageRequired, kStandalone
115 };
116
117 /** Set depending if the verifier needs a golden image as an input. */
118 InputType fInputType;
119
120 /** Constructor. */
121 GMVerifier(InputType inputType);
122
123 /** Implementation of the verification. */
124 virtual VerifierResult verifyWithGold(
125 const SkIRect& region, const SkBitmap& gold, const SkBitmap& actual) = 0;
126
127 /** Implementation of the verification. */
128 virtual VerifierResult verify(const SkIRect& region, const SkBitmap& actual) = 0;
129
130 /** Returns an error result formatted appropriately. */
131 VerifierResult makeError(const SkString& msg) const;
132};
133
134/**
135 * A verifier that operates standalone on the given input image (no comparison against a golden
136 * image).
137 */
138class StandaloneVerifier : public GMVerifier {
139public:
140 StandaloneVerifier() : GMVerifier(InputType::kStandalone) {}
141
142protected:
143 VerifierResult verifyWithGold(const SkIRect&, const SkBitmap&, const SkBitmap&) final {
144 return makeError(SkString("Verifier does not accept gold image input"));
145 }
146};
147
148/**
149 * A verifier that operates compares input image against a golden image.
150 */
151class GoldImageVerifier : public GMVerifier {
152public:
153 GoldImageVerifier() : GMVerifier(InputType::kGoldImageRequired) {}
154
155protected:
156 VerifierResult verify(const SkIRect&, const SkBitmap&) final {
157 return makeError(SkString("Verifier does not accept standalone input"));
158 }
159};
160
161/** A list of GM verifiers. */
162class VerifierList {
163public:
164 /** Constructs a VerifierList with the given gm instance. */
165 explicit VerifierList(GM* gm);
166
167 /** Adds a verifier to the list of verifiers. */
168 void add(std::unique_ptr<GMVerifier> verifier);
169
170 /**
171 * Runs all verifiers against the given input. If any verifiers fail, returns the first error.
172 * Else, returns ok. This version can be used if no verifiers in the list require the gold
173 * image as input.
174 */
175 VerifierResult verifyAll(const SkColorInfo& colorInfo, const SkBitmap& actual);
176
177private:
178 /** The parent GM instance of this VerifierList. */
179 GM* fGM;
180
181 /** The list of verifiers. */
182 std::vector<std::unique_ptr<GMVerifier>> fVerifiers;
183
184 /** After running, set to the first verifier that failed, or nullptr if none failed. */
185 const GMVerifier* fFailedVerifier;
186
187 /** Returns true if any verifiers in the list need the gold image as input. */
188 bool needsGoldImage() const;
189};
190
191}
192}
193
194#endif