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 #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 17 class SkBitmap; 18 19 namespace skiagm { 20 21 class GM; 22 23 namespace verifiers { 24 25 /** Result type for GM verifiers. */ 26 class VerifierResult { 27 public: 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 42 private: 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 */ 70 class GMVerifier { 71 public: 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 111 protected: 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 */ 138 class StandaloneVerifier : public GMVerifier { 139 public: StandaloneVerifier()140 StandaloneVerifier() : GMVerifier(InputType::kStandalone) {} 141 142 protected: verifyWithGold(const SkIRect &,const SkBitmap &,const SkBitmap &)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 */ 151 class GoldImageVerifier : public GMVerifier { 152 public: GoldImageVerifier()153 GoldImageVerifier() : GMVerifier(InputType::kGoldImageRequired) {} 154 155 protected: verify(const SkIRect &,const SkBitmap &)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. */ 162 class VerifierList { 163 public: 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 177 private: 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 } // namespace verifiers 192 } // namespace skiagm 193 194 #endif 195