• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //
2 // Copyright 2013 The ANGLE Project Authors. All rights reserved.
3 // Use of this source code is governed by a BSD-style license that can be
4 // found in the LICENSE file.
5 //
6 
7 // angletypes.h : Defines a variety of structures and enum types that are used throughout libGLESv2
8 
9 #include "libANGLE/angletypes.h"
10 #include "libANGLE/Program.h"
11 #include "libANGLE/State.h"
12 #include "libANGLE/VertexArray.h"
13 #include "libANGLE/VertexAttribute.h"
14 
15 namespace gl
16 {
RasterizerState()17 RasterizerState::RasterizerState()
18 {
19     memset(this, 0, sizeof(RasterizerState));
20 
21     rasterizerDiscard   = false;
22     cullFace            = false;
23     cullMode            = CullFaceMode::Back;
24     frontFace           = GL_CCW;
25     polygonOffsetFill   = false;
26     polygonOffsetFactor = 0.0f;
27     polygonOffsetUnits  = 0.0f;
28     pointDrawMode       = false;
29     multiSample         = false;
30 }
31 
operator ==(const RasterizerState & a,const RasterizerState & b)32 bool operator==(const RasterizerState &a, const RasterizerState &b)
33 {
34     return memcmp(&a, &b, sizeof(RasterizerState)) == 0;
35 }
36 
operator !=(const RasterizerState & a,const RasterizerState & b)37 bool operator!=(const RasterizerState &a, const RasterizerState &b)
38 {
39     return !(a == b);
40 }
41 
BlendState()42 BlendState::BlendState()
43 {
44     memset(this, 0, sizeof(BlendState));
45 
46     blend                 = false;
47     sourceBlendRGB        = GL_ONE;
48     sourceBlendAlpha      = GL_ONE;
49     destBlendRGB          = GL_ZERO;
50     destBlendAlpha        = GL_ZERO;
51     blendEquationRGB      = GL_FUNC_ADD;
52     blendEquationAlpha    = GL_FUNC_ADD;
53     sampleAlphaToCoverage = false;
54     dither                = true;
55 }
56 
BlendState(const BlendState & other)57 BlendState::BlendState(const BlendState &other)
58 {
59     memcpy(this, &other, sizeof(BlendState));
60 }
61 
allChannelsMasked() const62 bool BlendState::allChannelsMasked() const
63 {
64     return !colorMaskRed && !colorMaskGreen && !colorMaskBlue && !colorMaskAlpha;
65 }
66 
operator ==(const BlendState & a,const BlendState & b)67 bool operator==(const BlendState &a, const BlendState &b)
68 {
69     return memcmp(&a, &b, sizeof(BlendState)) == 0;
70 }
71 
operator !=(const BlendState & a,const BlendState & b)72 bool operator!=(const BlendState &a, const BlendState &b)
73 {
74     return !(a == b);
75 }
76 
DepthStencilState()77 DepthStencilState::DepthStencilState()
78 {
79     memset(this, 0, sizeof(DepthStencilState));
80 
81     depthTest                = false;
82     depthFunc                = GL_LESS;
83     depthMask                = true;
84     stencilTest              = false;
85     stencilFunc              = GL_ALWAYS;
86     stencilMask              = static_cast<GLuint>(-1);
87     stencilWritemask         = static_cast<GLuint>(-1);
88     stencilBackFunc          = GL_ALWAYS;
89     stencilBackMask          = static_cast<GLuint>(-1);
90     stencilBackWritemask     = static_cast<GLuint>(-1);
91     stencilFail              = GL_KEEP;
92     stencilPassDepthFail     = GL_KEEP;
93     stencilPassDepthPass     = GL_KEEP;
94     stencilBackFail          = GL_KEEP;
95     stencilBackPassDepthFail = GL_KEEP;
96     stencilBackPassDepthPass = GL_KEEP;
97 }
98 
DepthStencilState(const DepthStencilState & other)99 DepthStencilState::DepthStencilState(const DepthStencilState &other)
100 {
101     memcpy(this, &other, sizeof(DepthStencilState));
102 }
103 
operator ==(const DepthStencilState & a,const DepthStencilState & b)104 bool operator==(const DepthStencilState &a, const DepthStencilState &b)
105 {
106     return memcmp(&a, &b, sizeof(DepthStencilState)) == 0;
107 }
108 
operator !=(const DepthStencilState & a,const DepthStencilState & b)109 bool operator!=(const DepthStencilState &a, const DepthStencilState &b)
110 {
111     return !(a == b);
112 }
113 
SamplerState()114 SamplerState::SamplerState()
115 {
116     memset(this, 0, sizeof(SamplerState));
117 
118     setMinFilter(GL_NEAREST_MIPMAP_LINEAR);
119     setMagFilter(GL_LINEAR);
120     setWrapS(GL_REPEAT);
121     setWrapT(GL_REPEAT);
122     setWrapR(GL_REPEAT);
123     setMaxAnisotropy(1.0f);
124     setMinLod(-1000.0f);
125     setMaxLod(1000.0f);
126     setCompareMode(GL_NONE);
127     setCompareFunc(GL_LEQUAL);
128     setSRGBDecode(GL_DECODE_EXT);
129 }
130 
131 SamplerState::SamplerState(const SamplerState &other) = default;
132 
133 // static
CreateDefaultForTarget(TextureType type)134 SamplerState SamplerState::CreateDefaultForTarget(TextureType type)
135 {
136     SamplerState state;
137 
138     // According to OES_EGL_image_external and ARB_texture_rectangle: For external textures, the
139     // default min filter is GL_LINEAR and the default s and t wrap modes are GL_CLAMP_TO_EDGE.
140     if (type == TextureType::External || type == TextureType::Rectangle)
141     {
142         state.mMinFilter = GL_LINEAR;
143         state.mWrapS     = GL_CLAMP_TO_EDGE;
144         state.mWrapT     = GL_CLAMP_TO_EDGE;
145     }
146 
147     return state;
148 }
149 
setMinFilter(GLenum minFilter)150 void SamplerState::setMinFilter(GLenum minFilter)
151 {
152     mMinFilter                    = minFilter;
153     mCompleteness.typed.minFilter = static_cast<uint8_t>(FromGLenum<FilterMode>(minFilter));
154 }
155 
setMagFilter(GLenum magFilter)156 void SamplerState::setMagFilter(GLenum magFilter)
157 {
158     mMagFilter                    = magFilter;
159     mCompleteness.typed.magFilter = static_cast<uint8_t>(FromGLenum<FilterMode>(magFilter));
160 }
161 
setWrapS(GLenum wrapS)162 void SamplerState::setWrapS(GLenum wrapS)
163 {
164     mWrapS                    = wrapS;
165     mCompleteness.typed.wrapS = static_cast<uint8_t>(FromGLenum<WrapMode>(wrapS));
166 }
167 
setWrapT(GLenum wrapT)168 void SamplerState::setWrapT(GLenum wrapT)
169 {
170     mWrapT = wrapT;
171     updateWrapTCompareMode();
172 }
173 
setWrapR(GLenum wrapR)174 void SamplerState::setWrapR(GLenum wrapR)
175 {
176     mWrapR = wrapR;
177 }
178 
setMaxAnisotropy(float maxAnisotropy)179 void SamplerState::setMaxAnisotropy(float maxAnisotropy)
180 {
181     mMaxAnisotropy = maxAnisotropy;
182 }
183 
setMinLod(GLfloat minLod)184 void SamplerState::setMinLod(GLfloat minLod)
185 {
186     mMinLod = minLod;
187 }
188 
setMaxLod(GLfloat maxLod)189 void SamplerState::setMaxLod(GLfloat maxLod)
190 {
191     mMaxLod = maxLod;
192 }
193 
setCompareMode(GLenum compareMode)194 void SamplerState::setCompareMode(GLenum compareMode)
195 {
196     mCompareMode = compareMode;
197     updateWrapTCompareMode();
198 }
199 
setCompareFunc(GLenum compareFunc)200 void SamplerState::setCompareFunc(GLenum compareFunc)
201 {
202     mCompareFunc = compareFunc;
203 }
204 
setSRGBDecode(GLenum sRGBDecode)205 void SamplerState::setSRGBDecode(GLenum sRGBDecode)
206 {
207     mSRGBDecode = sRGBDecode;
208 }
209 
setBorderColor(const ColorGeneric & color)210 void SamplerState::setBorderColor(const ColorGeneric &color)
211 {
212     mBorderColor = color;
213 }
214 
updateWrapTCompareMode()215 void SamplerState::updateWrapTCompareMode()
216 {
217     uint8_t wrap    = static_cast<uint8_t>(FromGLenum<WrapMode>(mWrapT));
218     uint8_t compare = static_cast<uint8_t>(mCompareMode == GL_NONE ? 0x10 : 0x00);
219     mCompleteness.typed.wrapTCompareMode = wrap | compare;
220 }
221 
ImageUnit()222 ImageUnit::ImageUnit()
223     : texture(), level(0), layered(false), layer(0), access(GL_READ_ONLY), format(GL_R32UI)
224 {}
225 
226 ImageUnit::ImageUnit(const ImageUnit &other) = default;
227 
228 ImageUnit::~ImageUnit() = default;
229 
MinMax(int a,int b,int * minimum,int * maximum)230 static void MinMax(int a, int b, int *minimum, int *maximum)
231 {
232     if (a < b)
233     {
234         *minimum = a;
235         *maximum = b;
236     }
237     else
238     {
239         *minimum = b;
240         *maximum = a;
241     }
242 }
243 
flip(bool flipX,bool flipY) const244 Rectangle Rectangle::flip(bool flipX, bool flipY) const
245 {
246     Rectangle flipped = *this;
247     if (flipX)
248     {
249         flipped.x     = flipped.x + flipped.width;
250         flipped.width = -flipped.width;
251     }
252     if (flipY)
253     {
254         flipped.y      = flipped.y + flipped.height;
255         flipped.height = -flipped.height;
256     }
257     return flipped;
258 }
259 
removeReversal() const260 Rectangle Rectangle::removeReversal() const
261 {
262     return flip(isReversedX(), isReversedY());
263 }
264 
encloses(const gl::Rectangle & inside) const265 bool Rectangle::encloses(const gl::Rectangle &inside) const
266 {
267     return x0() <= inside.x0() && y0() <= inside.y0() && x1() >= inside.x1() && y1() >= inside.y1();
268 }
269 
ClipRectangle(const Rectangle & source,const Rectangle & clip,Rectangle * intersection)270 bool ClipRectangle(const Rectangle &source, const Rectangle &clip, Rectangle *intersection)
271 {
272     int minSourceX, maxSourceX, minSourceY, maxSourceY;
273     MinMax(source.x, source.x + source.width, &minSourceX, &maxSourceX);
274     MinMax(source.y, source.y + source.height, &minSourceY, &maxSourceY);
275 
276     int minClipX, maxClipX, minClipY, maxClipY;
277     MinMax(clip.x, clip.x + clip.width, &minClipX, &maxClipX);
278     MinMax(clip.y, clip.y + clip.height, &minClipY, &maxClipY);
279 
280     if (minSourceX >= maxClipX || maxSourceX <= minClipX || minSourceY >= maxClipY ||
281         maxSourceY <= minClipY)
282     {
283         return false;
284     }
285     if (intersection)
286     {
287         intersection->x      = std::max(minSourceX, minClipX);
288         intersection->y      = std::max(minSourceY, minClipY);
289         intersection->width  = std::min(maxSourceX, maxClipX) - std::max(minSourceX, minClipX);
290         intersection->height = std::min(maxSourceY, maxClipY) - std::max(minSourceY, minClipY);
291     }
292     return true;
293 }
294 
operator ==(const Box & other) const295 bool Box::operator==(const Box &other) const
296 {
297     return (x == other.x && y == other.y && z == other.z && width == other.width &&
298             height == other.height && depth == other.depth);
299 }
300 
operator !=(const Box & other) const301 bool Box::operator!=(const Box &other) const
302 {
303     return !(*this == other);
304 }
305 
toRect() const306 Rectangle Box::toRect() const
307 {
308     ASSERT(z == 0 && depth == 1);
309     return Rectangle(x, y, width, height);
310 }
311 
operator ==(const Offset & a,const Offset & b)312 bool operator==(const Offset &a, const Offset &b)
313 {
314     return a.x == b.x && a.y == b.y && a.z == b.z;
315 }
316 
operator !=(const Offset & a,const Offset & b)317 bool operator!=(const Offset &a, const Offset &b)
318 {
319     return !(a == b);
320 }
321 
operator ==(const Extents & lhs,const Extents & rhs)322 bool operator==(const Extents &lhs, const Extents &rhs)
323 {
324     return lhs.width == rhs.width && lhs.height == rhs.height && lhs.depth == rhs.depth;
325 }
326 
operator !=(const Extents & lhs,const Extents & rhs)327 bool operator!=(const Extents &lhs, const Extents &rhs)
328 {
329     return !(lhs == rhs);
330 }
331 
ValidateComponentTypeMasks(unsigned long outputTypes,unsigned long inputTypes,unsigned long outputMask,unsigned long inputMask)332 bool ValidateComponentTypeMasks(unsigned long outputTypes,
333                                 unsigned long inputTypes,
334                                 unsigned long outputMask,
335                                 unsigned long inputMask)
336 {
337     static_assert(IMPLEMENTATION_MAX_DRAW_BUFFERS <= kMaxComponentTypeMaskIndex,
338                   "Output/input masks should fit into 16 bits - 1 bit per draw buffer. The "
339                   "corresponding type masks should fit into 32 bits - 2 bits per draw buffer.");
340     static_assert(MAX_VERTEX_ATTRIBS <= kMaxComponentTypeMaskIndex,
341                   "Output/input masks should fit into 16 bits - 1 bit per attrib. The "
342                   "corresponding type masks should fit into 32 bits - 2 bits per attrib.");
343 
344     // For performance reasons, draw buffer and attribute type validation is done using bit masks.
345     // We store two bits representing the type split, with the low bit in the lower 16 bits of the
346     // variable, and the high bit in the upper 16 bits of the variable. This is done so we can AND
347     // with the elswewhere used DrawBufferMask or AttributeMask.
348 
349     // OR the masks with themselves, shifted 16 bits. This is to match our split type bits.
350     outputMask |= (outputMask << kMaxComponentTypeMaskIndex);
351     inputMask |= (inputMask << kMaxComponentTypeMaskIndex);
352 
353     // To validate:
354     // 1. Remove any indexes that are not enabled in the input (& inputMask)
355     // 2. Remove any indexes that exist in output, but not in input (& outputMask)
356     // 3. Use == to verify equality
357     return (outputTypes & inputMask) == ((inputTypes & outputMask) & inputMask);
358 }
359 
GetBoundBufferAvailableSize(const OffsetBindingPointer<Buffer> & binding)360 GLsizeiptr GetBoundBufferAvailableSize(const OffsetBindingPointer<Buffer> &binding)
361 {
362     Buffer *buffer = binding.get();
363     if (buffer)
364     {
365         if (binding.getSize() == 0)
366             return static_cast<GLsizeiptr>(buffer->getSize());
367         angle::CheckedNumeric<GLintptr> offset       = binding.getOffset();
368         angle::CheckedNumeric<GLsizeiptr> size       = binding.getSize();
369         angle::CheckedNumeric<GLsizeiptr> bufferSize = buffer->getSize();
370         auto end                                     = offset + size;
371         auto clampedSize                             = size;
372         auto difference                              = end - bufferSize;
373         if (!difference.IsValid())
374         {
375             return 0;
376         }
377         if (difference.ValueOrDie() > 0)
378         {
379             clampedSize = size - difference;
380         }
381         return clampedSize.ValueOrDefault(0);
382     }
383     else
384     {
385         return 0;
386     }
387 }
388 
389 }  // namespace gl
390