/* * Copyright 2020 Google Inc. * * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ #ifndef gmverifier_DEFINED #define gmverifier_DEFINED #include "include/core/SkColor.h" #include "include/core/SkRect.h" #include "include/core/SkString.h" #include class SkBitmap; class SkColorInfo; namespace skiagm { class GM; namespace verifiers { /** Result type for GM verifiers. */ class VerifierResult { public: VerifierResult(); /** Returns true if the result is ok (non-error). */ bool ok() const; /** Returns reference to any message associated with the result. */ const SkString& message() const; /** Constructs an "ok" (non-error) result. */ static VerifierResult Ok(); /** Constructs a "fail" (error) result with a specific message. */ static VerifierResult Fail(const SkString& msg); private: /** Underlying error code. */ enum class Code { kOk, kFail }; /** Result code */ Code fCode; /** Result message (may be empty). */ SkString fMessage; /** Private constructor for a result with a specific code and message. */ VerifierResult(Code code, const SkString& msg); }; /** * Abstract base class for GM verifiers. A verifier checks the rendered output image of a GM. * * Different verifiers perform different types of transforms and checks. Verifiers may check the * output of a GM against a given "golden" image which represents the correct output, or just * check the output image of the GM by itself. * * Most verifiers have configurable fuzziness in the comparisons performed against the golden image. * * Subclasses should inherit from one of StandaloneVerifier or GoldImageVerifier instead of * directly from this base class. */ class GMVerifier { public: GMVerifier() = delete; virtual ~GMVerifier(); /** Returns the human-friendly name of the verifier. */ virtual SkString name() const = 0; /** Returns true if this verifier needs the gold image as input. */ bool needsGoldImage() const; /** * Runs the verifier. This method should be used if the verifier needs the gold image as input. * * @param gold Bitmap containing the "correct" image. * @param actual Bitmap containing rendered output of a GM. * @return Ok if the verification passed, or an error if not. */ VerifierResult verify(const SkBitmap& gold, const SkBitmap& actual); /** * Runs the verifier. * * @param actual Bitmap containing rendered output of a GM. * @return Ok if the verification passed, or an error if not. */ VerifierResult verify(const SkBitmap& actual); /** Renders the GM using the "golden" configuration. This is common across all GMs/verifiers. */ static SkBitmap RenderGoldBmp(skiagm::GM* gm, const SkColorInfo& colorInfo); /** * Gets the color information that all verifier inputs should be transformed into. * * The primary reason for having a single shared colorspace/color type is making per-pixel * comparisons easier. Both the image under test and gold image are transformed into a shared * colorspace which allows for getting per-pixel colors in SkColor4f. */ static SkColorInfo VerifierColorInfo(); protected: /** The type of input required for the verifier. */ enum class InputType { kGoldImageRequired, kStandalone }; /** Set depending if the verifier needs a golden image as an input. */ InputType fInputType; /** Constructor. */ GMVerifier(InputType inputType); /** Implementation of the verification. */ virtual VerifierResult verifyWithGold( const SkIRect& region, const SkBitmap& gold, const SkBitmap& actual) = 0; /** Implementation of the verification. */ virtual VerifierResult verify(const SkIRect& region, const SkBitmap& actual) = 0; /** Returns an error result formatted appropriately. */ VerifierResult makeError(const SkString& msg) const; }; /** * A verifier that operates standalone on the given input image (no comparison against a golden * image). */ class StandaloneVerifier : public GMVerifier { public: StandaloneVerifier() : GMVerifier(InputType::kStandalone) {} protected: VerifierResult verifyWithGold(const SkIRect&, const SkBitmap&, const SkBitmap&) final { return makeError(SkString("Verifier does not accept gold image input")); } }; /** * A verifier that operates compares input image against a golden image. */ class GoldImageVerifier : public GMVerifier { public: GoldImageVerifier() : GMVerifier(InputType::kGoldImageRequired) {} protected: VerifierResult verify(const SkIRect&, const SkBitmap&) final { return makeError(SkString("Verifier does not accept standalone input")); } }; /** A list of GM verifiers. */ class VerifierList { public: /** Constructs a VerifierList with the given gm instance. */ explicit VerifierList(GM* gm); /** Adds a verifier to the list of verifiers. */ void add(std::unique_ptr verifier); /** * Runs all verifiers against the given input. If any verifiers fail, returns the first error. * Else, returns ok. This version can be used if no verifiers in the list require the gold * image as input. */ VerifierResult verifyAll(const SkColorInfo& colorInfo, const SkBitmap& actual); private: /** The parent GM instance of this VerifierList. */ GM* fGM; /** The list of verifiers. */ std::vector> fVerifiers; /** After running, set to the first verifier that failed, or nullptr if none failed. */ const GMVerifier* fFailedVerifier; /** Returns true if any verifiers in the list need the gold image as input. */ bool needsGoldImage() const; }; } // namespace verifiers } // namespace skiagm #endif