aboutsummaryrefslogtreecommitdiffhomepage
path: root/gm/gm_error.h
blob: e442f5d894376436773a8bc8372b9a096b485671 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
/*
 * Copyright 2013 Google Inc.
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

/*
 * Error codes used by gmmain.cpp.
 */

#ifndef gm_error_DEFINED
#define gm_error_DEFINED

#include "gm.h"

namespace skiagm {

    /**
     * The complete list of error types we might encounter in GM.
     */
    enum ErrorType {
        // Even though kNoGpuContext_ErrorType only occurs when SK_SUPPORT_GPU
        // is turned on, we always include this type in our enum so that
        // reports will be consistent whether SK_SUPPORT_GPU is turned on
        // or off (as long as the number of these errors is 0).
        kNoGpuContext_ErrorType,

        kIntentionallySkipped_ErrorType,
        kRenderModeMismatch_ErrorType,
        kExpectationsMismatch_ErrorType,
        kMissingExpectations_ErrorType,
        kWritingReferenceImage_ErrorType,
        kLast_ErrorType = kWritingReferenceImage_ErrorType
    };

    /**
     * Returns the name of the given ErrorType.
     */
    static const char *getErrorTypeName(ErrorType type) {
        switch(type) {
        case kNoGpuContext_ErrorType:
            return "NoGpuContext";
        case kIntentionallySkipped_ErrorType:
            return "IntentionallySkipped";
        case kRenderModeMismatch_ErrorType:
            return "RenderModeMismatch";
        case kExpectationsMismatch_ErrorType:
            return "ExpectationsMismatch";
        case kMissingExpectations_ErrorType:
            return "MissingExpectations";
        case kWritingReferenceImage_ErrorType:
            return "WritingReferenceImage";
        }
        // control should never reach here
        SkDEBUGFAIL("getErrorTypeName() called with unknown type");
        return "Unknown";
    }

    /**
     * Fills in "type" with the ErrorType associated with name "name".
     * Returns true if we found one, false if it is an unknown type name.
     */
    static bool getErrorTypeByName(const char name[], ErrorType *type) {
        for (int typeInt = 0; typeInt <= kLast_ErrorType; typeInt++) {
            ErrorType thisType = static_cast<ErrorType>(typeInt);
            const char *thisTypeName = getErrorTypeName(thisType);
            if (0 == strcmp(thisTypeName, name)) {
                *type = thisType;
                return true;
            }
        }
        return false;
    }

    /**
     * A combination of 0 or more ErrorTypes.
     */
    class ErrorCombination {
    public:
        ErrorCombination() : fBitfield(0) {}
        ErrorCombination(const ErrorType type) : fBitfield(1 << type) {}

        /**
         * Returns true iff there are NO errors.
         */
        bool isEmpty() const {
            return (0 == this->fBitfield);
        }

        /**
         * Adds this ErrorType to this ErrorCombination.
         */
        void add(const ErrorType type) {
            this->fBitfield |= (1 << type);
        }

        /**
         * Adds all ErrorTypes in "other" to this ErrorCombination.
         */
        void add(const ErrorCombination other) {
            this->fBitfield |= other.fBitfield;
        }

        /**
         * Returns true iff this ErrorCombination includes this ErrorType.
         */
        bool includes(const ErrorType type) const {
            return !(0 == (this->fBitfield & (1 << type)));
        }

        /**
         * Returns a string representation of all ErrorTypes in this
         * ErrorCombination.
         *
         * @param separator text with which to separate ErrorType names
         */
        SkString asString(const char separator[]) const {
            SkString s;
            for (int typeInt = 0; typeInt <= kLast_ErrorType; typeInt++) {
                ErrorType type = static_cast<ErrorType>(typeInt);
                if (this->includes(type)) {
                    if (!s.isEmpty()) {
                        s.append(separator);
                    }
                    s.append(getErrorTypeName(type));
                }
            }
            return s;
        }

        /**
         * Returns a new ErrorCombination, which includes the union of all
         * ErrorTypes in two ErrorCombination objects (this and other).
         */
        ErrorCombination plus(const ErrorCombination& other) const {
            ErrorCombination retval;
            retval.fBitfield = this->fBitfield | other.fBitfield;
            return retval;
        }

        /**
         * Returns a new ErrorCombination, which is a copy of "this"
         * but with all ErrorTypes in "other" removed.
         */
        ErrorCombination minus(const ErrorCombination& other) const {
            ErrorCombination retval;
            retval.fBitfield = this->fBitfield & ~(other.fBitfield);
            return retval;
        }

    private:
        int fBitfield;
    };

    // No errors at all.
    const static ErrorCombination kEmpty_ErrorCombination;
}

#endif // ifndef gm_error_DEFINED