Merge "Generate flat triangles in polygon offset tests." into nougat-cts-dev am:...
[platform/upstream/VK-GL-CTS.git] / framework / common / tcuRGBA.hpp
1 #ifndef _TCURGBA_HPP
2 #define _TCURGBA_HPP
3 /*-------------------------------------------------------------------------
4  * drawElements Quality Program Tester Core
5  * ----------------------------------------
6  *
7  * Copyright 2014 The Android Open Source Project
8  *
9  * Licensed under the Apache License, Version 2.0 (the "License");
10  * you may not use this file except in compliance with the License.
11  * You may obtain a copy of the License at
12  *
13  *      http://www.apache.org/licenses/LICENSE-2.0
14  *
15  * Unless required by applicable law or agreed to in writing, software
16  * distributed under the License is distributed on an "AS IS" BASIS,
17  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18  * See the License for the specific language governing permissions and
19  * limitations under the License.
20  *
21  *//*!
22  * \file
23  * \brief RGBA8888 color type.
24  *//*--------------------------------------------------------------------*/
25
26 #include "tcuDefs.hpp"
27 #include "deInt32.h"
28 #include "tcuVectorType.hpp"
29
30 #include <sstream>
31
32 namespace tcu
33 {
34
35 /*--------------------------------------------------------------------*//*!
36  * \brief RGBA8888 color struct
37  *//*--------------------------------------------------------------------*/
38 class RGBA
39 {
40 public:
41         enum
42         {
43                 RED_SHIFT       = 0,
44                 GREEN_SHIFT     = 8,
45                 BLUE_SHIFT      = 16,
46                 ALPHA_SHIFT     = 24
47         };
48
49         enum
50         {
51                 RED_MASK        = (1<<0),
52                 GREEN_MASK      = (1<<1),
53                 BLUE_MASK       = (1<<2),
54                 ALPHA_MASK      = (1<<3)
55         };
56
57         RGBA (void) { m_value = 0; }
58
59         RGBA (int r, int g, int b, int a)
60         {
61                 DE_ASSERT(deInRange32(r, 0, 255));
62                 DE_ASSERT(deInRange32(g, 0, 255));
63                 DE_ASSERT(deInRange32(b, 0, 255));
64                 DE_ASSERT(deInRange32(a, 0, 255));
65                 m_value = ((deUint32)a << ALPHA_SHIFT) | ((deUint32)r << RED_SHIFT) | ((deUint32)g << GREEN_SHIFT) | ((deUint32)b << BLUE_SHIFT);
66         }
67
68         explicit RGBA (deUint32 val)
69         {
70                 m_value = val;
71         }
72
73         explicit        RGBA                                    (const Vec4& v);
74
75         void            setRed                                  (int v) { DE_ASSERT(deInRange32(v, 0, 255)); m_value = (m_value & ~((deUint32)0xFFu << RED_SHIFT))   | ((deUint32)v << RED_SHIFT);   }
76         void            setGreen                                (int v) { DE_ASSERT(deInRange32(v, 0, 255)); m_value = (m_value & ~((deUint32)0xFFu << GREEN_SHIFT)) | ((deUint32)v << GREEN_SHIFT); }
77         void            setBlue                                 (int v) { DE_ASSERT(deInRange32(v, 0, 255)); m_value = (m_value & ~((deUint32)0xFFu << BLUE_SHIFT))  | ((deUint32)v << BLUE_SHIFT);  }
78         void            setAlpha                                (int v) { DE_ASSERT(deInRange32(v, 0, 255)); m_value = (m_value & ~((deUint32)0xFFu << ALPHA_SHIFT)) | ((deUint32)v << ALPHA_SHIFT); }
79         int                     getRed                                  (void) const { return (int)((m_value >> (deUint32)RED_SHIFT)   & 0xFFu); }
80         int                     getGreen                                (void) const { return (int)((m_value >> (deUint32)GREEN_SHIFT) & 0xFFu); }
81         int                     getBlue                                 (void) const { return (int)((m_value >> (deUint32)BLUE_SHIFT)  & 0xFFu); }
82         int                     getAlpha                                (void) const { return (int)((m_value >> (deUint32)ALPHA_SHIFT) & 0xFFu); }
83         deUint32        getPacked                               (void) const { return m_value; }
84
85         bool            isBelowThreshold                (RGBA thr) const        { return (getRed() <= thr.getRed()) && (getGreen() <= thr.getGreen()) && (getBlue() <= thr.getBlue()) && (getAlpha() <= thr.getAlpha()); }
86
87         static RGBA     fromBytes                               (const deUint8* bytes)  { return RGBA(bytes[0], bytes[1], bytes[2], bytes[3]); }
88         void            toBytes                                 (deUint8* bytes) const  { bytes[0] = (deUint8)getRed(); bytes[1] = (deUint8)getGreen(); bytes[2] = (deUint8)getBlue(); bytes[3] = (deUint8)getAlpha(); }
89         Vec4            toVec                                   (void) const;
90         IVec4           toIVec                                  (void) const;
91
92         bool            operator==                              (const RGBA& v) const { return (m_value == v.m_value); }
93         bool            operator!=                              (const RGBA& v) const { return (m_value != v.m_value); }
94
95         // Color constants.  Designed as methods to avoid static-initialization-order fiasco.
96         static inline const RGBA red    (void) { return RGBA(0xFF, 0x0,  0x0,  0xFF); }
97         static inline const RGBA green  (void) { return RGBA(0x0,  0xFF, 0x0,  0xFF); }
98         static inline const RGBA blue   (void) { return RGBA(0x0,  0x0,  0xFF, 0xFF); }
99         static inline const RGBA gray   (void) { return RGBA(0x80, 0x80, 0x80, 0xFF); }
100         static inline const RGBA white  (void) { return RGBA(0xFF, 0xFF, 0xFF, 0xFF); }
101         static inline const RGBA black  (void) { return RGBA(0x0,  0x0,  0x0,  0xFF); }
102
103 private:
104         deUint32        m_value;
105 } DE_WARN_UNUSED_TYPE;
106
107 inline bool compareEqualMasked (RGBA a, RGBA b, deUint32 cmpMask)
108 {
109         RGBA            mask((cmpMask&RGBA::RED_MASK)?0xFF:0, (cmpMask&RGBA::GREEN_MASK)?0xFF:0, (cmpMask&RGBA::BLUE_MASK)?0xFF:0, (cmpMask&RGBA::ALPHA_MASK)?0xFF:0);
110         deUint32        aPacked         = a.getPacked();
111         deUint32        bPacked         = b.getPacked();
112         deUint32        maskPacked      = mask.getPacked();
113         return (aPacked & maskPacked) == (bPacked & maskPacked);
114 }
115
116 inline RGBA computeAbsDiff (RGBA a, RGBA b)
117 {
118         return RGBA(
119                 deAbs32(a.getRed()   - b.getRed()),
120                 deAbs32(a.getGreen() - b.getGreen()),
121                 deAbs32(a.getBlue()  - b.getBlue()),
122                 deAbs32(a.getAlpha() - b.getAlpha()));
123 }
124
125 inline RGBA blend (RGBA a, RGBA b, float t)
126 {
127         DE_ASSERT(t >= 0.0f && t <= 1.0f);
128         float it = 1.0f - t;
129         // \todo [petri] Handling of alpha!
130         return RGBA(
131                 (int)(it*(float)a.getRed() + t*(float)b.getRed() + 0.5f),
132                 (int)(it*(float)a.getGreen() + t*(float)b.getGreen() + 0.5f),
133                 (int)(it*(float)a.getBlue() + t*(float)b.getBlue() + 0.5f),
134                 (int)(it*(float)a.getAlpha() + t*(float)b.getAlpha() + 0.5f));
135 }
136
137 inline bool compareThreshold (RGBA a, RGBA b, RGBA threshold)
138 {
139         if (a == b) return true;        // Quick-accept
140         return computeAbsDiff(a, b).isBelowThreshold(threshold);
141 }
142
143 inline RGBA max (RGBA a, RGBA b)
144 {
145         return RGBA(deMax32(a.getRed(),         b.getRed()),
146                                 deMax32(a.getGreen(),   b.getGreen()),
147                                 deMax32(a.getBlue(),    b.getBlue()),
148                                 deMax32(a.getAlpha(),   b.getAlpha()));
149 }
150
151 RGBA computeAbsDiffMasked       (RGBA a, RGBA b, deUint32 cmpMask);
152 bool compareThresholdMasked     (RGBA a, RGBA b, RGBA threshold, deUint32 cmpMask);
153
154 // Arithmetic operators (saturating if not stated otherwise).
155
156 inline RGBA operator+ (const RGBA& a, const RGBA& b)
157 {
158         return RGBA(deClamp32(a.getRed()        + b.getRed(),   0, 255),
159                                 deClamp32(a.getGreen()  + b.getGreen(), 0, 255),
160                                 deClamp32(a.getBlue()   + b.getBlue(),  0, 255),
161                                 deClamp32(a.getAlpha()  + b.getAlpha(), 0, 255));
162 }
163
164 inline RGBA operator- (const RGBA& a, const RGBA& b)
165 {
166         return RGBA(deClamp32(a.getRed()        - b.getRed(),   0, 255),
167                                 deClamp32(a.getGreen()  - b.getGreen(), 0, 255),
168                                 deClamp32(a.getBlue()   - b.getBlue(),  0, 255),
169                                 deClamp32(a.getAlpha()  - b.getAlpha(), 0, 255));
170 }
171
172 inline RGBA operator* (const RGBA& a, const int b)
173 {
174         return RGBA(deClamp32(a.getRed()        * b,    0, 255),
175                                 deClamp32(a.getGreen()  * b,    0, 255),
176                                 deClamp32(a.getBlue()   * b,    0, 255),
177                                 deClamp32(a.getAlpha()  * b,    0, 255));
178 }
179
180 inline std::ostream& operator<< (std::ostream& stream, RGBA c)
181 {
182         return stream << "RGBA(" << c.getRed() << ", " << c.getGreen() << ", " << c.getBlue() << ", " << c.getAlpha() << ")";
183 }
184
185 } // tcu
186
187 #endif // _TCURGBA_HPP