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 dither = true;
31 }
32
RasterizerState(const RasterizerState & other)33 RasterizerState::RasterizerState(const RasterizerState &other)
34 {
35 memcpy(this, &other, sizeof(RasterizerState));
36 }
37
operator ==(const RasterizerState & a,const RasterizerState & b)38 bool operator==(const RasterizerState &a, const RasterizerState &b)
39 {
40 return memcmp(&a, &b, sizeof(RasterizerState)) == 0;
41 }
42
operator !=(const RasterizerState & a,const RasterizerState & b)43 bool operator!=(const RasterizerState &a, const RasterizerState &b)
44 {
45 return !(a == b);
46 }
47
BlendState()48 BlendState::BlendState()
49 {
50 memset(this, 0, sizeof(BlendState));
51
52 blend = false;
53 sourceBlendRGB = GL_ONE;
54 sourceBlendAlpha = GL_ONE;
55 destBlendRGB = GL_ZERO;
56 destBlendAlpha = GL_ZERO;
57 blendEquationRGB = GL_FUNC_ADD;
58 blendEquationAlpha = GL_FUNC_ADD;
59 colorMaskRed = true;
60 colorMaskGreen = true;
61 colorMaskBlue = true;
62 colorMaskAlpha = true;
63 }
64
BlendState(const BlendState & other)65 BlendState::BlendState(const BlendState &other)
66 {
67 memcpy(this, &other, sizeof(BlendState));
68 }
69
operator ==(const BlendState & a,const BlendState & b)70 bool operator==(const BlendState &a, const BlendState &b)
71 {
72 return memcmp(&a, &b, sizeof(BlendState)) == 0;
73 }
74
operator !=(const BlendState & a,const BlendState & b)75 bool operator!=(const BlendState &a, const BlendState &b)
76 {
77 return !(a == b);
78 }
79
DepthStencilState()80 DepthStencilState::DepthStencilState()
81 {
82 memset(this, 0, sizeof(DepthStencilState));
83
84 depthTest = false;
85 depthFunc = GL_LESS;
86 depthMask = true;
87 stencilTest = false;
88 stencilFunc = GL_ALWAYS;
89 stencilMask = static_cast<GLuint>(-1);
90 stencilWritemask = static_cast<GLuint>(-1);
91 stencilBackFunc = GL_ALWAYS;
92 stencilBackMask = static_cast<GLuint>(-1);
93 stencilBackWritemask = static_cast<GLuint>(-1);
94 stencilFail = GL_KEEP;
95 stencilPassDepthFail = GL_KEEP;
96 stencilPassDepthPass = GL_KEEP;
97 stencilBackFail = GL_KEEP;
98 stencilBackPassDepthFail = GL_KEEP;
99 stencilBackPassDepthPass = GL_KEEP;
100 }
101
DepthStencilState(const DepthStencilState & other)102 DepthStencilState::DepthStencilState(const DepthStencilState &other)
103 {
104 memcpy(this, &other, sizeof(DepthStencilState));
105 }
106
operator ==(const DepthStencilState & a,const DepthStencilState & b)107 bool operator==(const DepthStencilState &a, const DepthStencilState &b)
108 {
109 return memcmp(&a, &b, sizeof(DepthStencilState)) == 0;
110 }
111
operator !=(const DepthStencilState & a,const DepthStencilState & b)112 bool operator!=(const DepthStencilState &a, const DepthStencilState &b)
113 {
114 return !(a == b);
115 }
116
SamplerState()117 SamplerState::SamplerState()
118 {
119 memset(this, 0, sizeof(SamplerState));
120
121 setMinFilter(GL_NEAREST_MIPMAP_LINEAR);
122 setMagFilter(GL_LINEAR);
123 setWrapS(GL_REPEAT);
124 setWrapT(GL_REPEAT);
125 setWrapR(GL_REPEAT);
126 setMaxAnisotropy(1.0f);
127 setMinLod(-1000.0f);
128 setMaxLod(1000.0f);
129 setCompareMode(GL_NONE);
130 setCompareFunc(GL_LEQUAL);
131 setSRGBDecode(GL_DECODE_EXT);
132 }
133
134 SamplerState::SamplerState(const SamplerState &other) = default;
135
136 // static
CreateDefaultForTarget(TextureType type)137 SamplerState SamplerState::CreateDefaultForTarget(TextureType type)
138 {
139 SamplerState state;
140
141 // According to OES_EGL_image_external and ARB_texture_rectangle: For external textures, the
142 // default min filter is GL_LINEAR and the default s and t wrap modes are GL_CLAMP_TO_EDGE.
143 if (type == TextureType::External || type == TextureType::Rectangle)
144 {
145 state.mMinFilter = GL_LINEAR;
146 state.mWrapS = GL_CLAMP_TO_EDGE;
147 state.mWrapT = GL_CLAMP_TO_EDGE;
148 }
149
150 return state;
151 }
152
setMinFilter(GLenum minFilter)153 void SamplerState::setMinFilter(GLenum minFilter)
154 {
155 mMinFilter = minFilter;
156 mCompleteness.typed.minFilter = static_cast<uint8_t>(FromGLenum<FilterMode>(minFilter));
157 }
158
setMagFilter(GLenum magFilter)159 void SamplerState::setMagFilter(GLenum magFilter)
160 {
161 mMagFilter = magFilter;
162 mCompleteness.typed.magFilter = static_cast<uint8_t>(FromGLenum<FilterMode>(magFilter));
163 }
164
setWrapS(GLenum wrapS)165 void SamplerState::setWrapS(GLenum wrapS)
166 {
167 mWrapS = wrapS;
168 mCompleteness.typed.wrapS = static_cast<uint8_t>(FromGLenum<WrapMode>(wrapS));
169 }
170
setWrapT(GLenum wrapT)171 void SamplerState::setWrapT(GLenum wrapT)
172 {
173 mWrapT = wrapT;
174 updateWrapTCompareMode();
175 }
176
setWrapR(GLenum wrapR)177 void SamplerState::setWrapR(GLenum wrapR)
178 {
179 mWrapR = wrapR;
180 }
181
setMaxAnisotropy(float maxAnisotropy)182 void SamplerState::setMaxAnisotropy(float maxAnisotropy)
183 {
184 mMaxAnisotropy = maxAnisotropy;
185 }
186
setMinLod(GLfloat minLod)187 void SamplerState::setMinLod(GLfloat minLod)
188 {
189 mMinLod = minLod;
190 }
191
setMaxLod(GLfloat maxLod)192 void SamplerState::setMaxLod(GLfloat maxLod)
193 {
194 mMaxLod = maxLod;
195 }
196
setCompareMode(GLenum compareMode)197 void SamplerState::setCompareMode(GLenum compareMode)
198 {
199 mCompareMode = compareMode;
200 updateWrapTCompareMode();
201 }
202
setCompareFunc(GLenum compareFunc)203 void SamplerState::setCompareFunc(GLenum compareFunc)
204 {
205 mCompareFunc = compareFunc;
206 }
207
setSRGBDecode(GLenum sRGBDecode)208 void SamplerState::setSRGBDecode(GLenum sRGBDecode)
209 {
210 mSRGBDecode = sRGBDecode;
211 }
212
setBorderColor(const ColorGeneric & color)213 void SamplerState::setBorderColor(const ColorGeneric &color)
214 {
215 mBorderColor = color;
216 }
217
updateWrapTCompareMode()218 void SamplerState::updateWrapTCompareMode()
219 {
220 uint8_t wrap = static_cast<uint8_t>(FromGLenum<WrapMode>(mWrapT));
221 uint8_t compare = static_cast<uint8_t>(mCompareMode == GL_NONE ? 0x10 : 0x00);
222 mCompleteness.typed.wrapTCompareMode = wrap | compare;
223 }
224
ImageUnit()225 ImageUnit::ImageUnit()
226 : texture(), level(0), layered(false), layer(0), access(GL_READ_ONLY), format(GL_R32UI)
227 {}
228
229 ImageUnit::ImageUnit(const ImageUnit &other) = default;
230
231 ImageUnit::~ImageUnit() = default;
232
BlendStateExt(const size_t drawBuffers)233 BlendStateExt::BlendStateExt(const size_t drawBuffers)
234 : mMaxFactorMask(FactorStorage::GetMask(drawBuffers)),
235 mSrcColor(FactorStorage::GetReplicatedValue(BlendFactorType::One, mMaxFactorMask)),
236 mDstColor(FactorStorage::GetReplicatedValue(BlendFactorType::Zero, mMaxFactorMask)),
237 mSrcAlpha(FactorStorage::GetReplicatedValue(BlendFactorType::One, mMaxFactorMask)),
238 mDstAlpha(FactorStorage::GetReplicatedValue(BlendFactorType::Zero, mMaxFactorMask)),
239 mMaxEquationMask(EquationStorage::GetMask(drawBuffers)),
240 mEquationColor(EquationStorage::GetReplicatedValue(BlendEquationType::Add, mMaxEquationMask)),
241 mEquationAlpha(EquationStorage::GetReplicatedValue(BlendEquationType::Add, mMaxEquationMask)),
242 mMaxColorMask(ColorMaskStorage::GetMask(drawBuffers)),
243 mColorMask(ColorMaskStorage::GetReplicatedValue(PackColorMask(true, true, true, true),
244 mMaxColorMask)),
245 mMaxEnabledMask(0xFF >> (8 - drawBuffers)),
246 mEnabledMask(),
247 mMaxDrawBuffers(drawBuffers)
248 {}
249
operator =(const BlendStateExt & other)250 BlendStateExt &BlendStateExt::operator=(const BlendStateExt &other)
251 {
252 memcpy(this, &other, sizeof(BlendStateExt));
253 return *this;
254 }
255
setEnabled(const bool enabled)256 void BlendStateExt::setEnabled(const bool enabled)
257 {
258 mEnabledMask = enabled ? mMaxEnabledMask : DrawBufferMask::Zero();
259 }
260
setEnabledIndexed(const size_t index,const bool enabled)261 void BlendStateExt::setEnabledIndexed(const size_t index, const bool enabled)
262 {
263 ASSERT(index < mMaxDrawBuffers);
264 mEnabledMask.set(index, enabled);
265 }
266
expandColorMaskValue(const bool red,const bool green,const bool blue,const bool alpha) const267 BlendStateExt::ColorMaskStorage::Type BlendStateExt::expandColorMaskValue(const bool red,
268 const bool green,
269 const bool blue,
270 const bool alpha) const
271 {
272 return BlendStateExt::ColorMaskStorage::GetReplicatedValue(
273 PackColorMask(red, green, blue, alpha), mMaxColorMask);
274 }
275
expandColorMaskIndexed(const size_t index) const276 BlendStateExt::ColorMaskStorage::Type BlendStateExt::expandColorMaskIndexed(
277 const size_t index) const
278 {
279 return ColorMaskStorage::GetReplicatedValue(
280 ColorMaskStorage::GetValueIndexed(index, mColorMask), mMaxColorMask);
281 }
282
setColorMask(const bool red,const bool green,const bool blue,const bool alpha)283 void BlendStateExt::setColorMask(const bool red,
284 const bool green,
285 const bool blue,
286 const bool alpha)
287 {
288 mColorMask = expandColorMaskValue(red, green, blue, alpha);
289 }
290
setColorMaskIndexed(const size_t index,const uint8_t value)291 void BlendStateExt::setColorMaskIndexed(const size_t index, const uint8_t value)
292 {
293 ASSERT(index < mMaxDrawBuffers);
294 ASSERT(value <= 0xF);
295 ColorMaskStorage::SetValueIndexed(index, value, &mColorMask);
296 }
297
setColorMaskIndexed(const size_t index,const bool red,const bool green,const bool blue,const bool alpha)298 void BlendStateExt::setColorMaskIndexed(const size_t index,
299 const bool red,
300 const bool green,
301 const bool blue,
302 const bool alpha)
303 {
304 ASSERT(index < mMaxDrawBuffers);
305 ColorMaskStorage::SetValueIndexed(index, PackColorMask(red, green, blue, alpha), &mColorMask);
306 }
307
getColorMaskIndexed(const size_t index) const308 uint8_t BlendStateExt::getColorMaskIndexed(const size_t index) const
309 {
310 ASSERT(index < mMaxDrawBuffers);
311 return ColorMaskStorage::GetValueIndexed(index, mColorMask);
312 }
313
getColorMaskIndexed(const size_t index,bool * red,bool * green,bool * blue,bool * alpha) const314 void BlendStateExt::getColorMaskIndexed(const size_t index,
315 bool *red,
316 bool *green,
317 bool *blue,
318 bool *alpha) const
319 {
320 ASSERT(index < mMaxDrawBuffers);
321 UnpackColorMask(ColorMaskStorage::GetValueIndexed(index, mColorMask), red, green, blue, alpha);
322 }
323
compareColorMask(ColorMaskStorage::Type other) const324 DrawBufferMask BlendStateExt::compareColorMask(ColorMaskStorage::Type other) const
325 {
326 return ColorMaskStorage::GetDiffMask(mColorMask, other);
327 }
328
expandEquationValue(const GLenum mode) const329 BlendStateExt::EquationStorage::Type BlendStateExt::expandEquationValue(const GLenum mode) const
330 {
331 return EquationStorage::GetReplicatedValue(FromGLenum<BlendEquationType>(mode),
332 mMaxEquationMask);
333 }
334
expandEquationColorIndexed(const size_t index) const335 BlendStateExt::EquationStorage::Type BlendStateExt::expandEquationColorIndexed(
336 const size_t index) const
337 {
338 return EquationStorage::GetReplicatedValue(
339 EquationStorage::GetValueIndexed(index, mEquationColor), mMaxEquationMask);
340 }
341
expandEquationAlphaIndexed(const size_t index) const342 BlendStateExt::EquationStorage::Type BlendStateExt::expandEquationAlphaIndexed(
343 const size_t index) const
344 {
345 return EquationStorage::GetReplicatedValue(
346 EquationStorage::GetValueIndexed(index, mEquationAlpha), mMaxEquationMask);
347 }
348
setEquations(const GLenum modeColor,const GLenum modeAlpha)349 void BlendStateExt::setEquations(const GLenum modeColor, const GLenum modeAlpha)
350 {
351 mEquationColor = expandEquationValue(modeColor);
352 mEquationAlpha = expandEquationValue(modeAlpha);
353 }
354
setEquationsIndexed(const size_t index,const GLenum modeColor,const GLenum modeAlpha)355 void BlendStateExt::setEquationsIndexed(const size_t index,
356 const GLenum modeColor,
357 const GLenum modeAlpha)
358 {
359 ASSERT(index < mMaxDrawBuffers);
360 EquationStorage::SetValueIndexed(index, FromGLenum<BlendEquationType>(modeColor),
361 &mEquationColor);
362 EquationStorage::SetValueIndexed(index, FromGLenum<BlendEquationType>(modeAlpha),
363 &mEquationAlpha);
364 }
365
setEquationsIndexed(const size_t index,const size_t sourceIndex,const BlendStateExt & source)366 void BlendStateExt::setEquationsIndexed(const size_t index,
367 const size_t sourceIndex,
368 const BlendStateExt &source)
369 {
370 ASSERT(index < mMaxDrawBuffers);
371 ASSERT(sourceIndex < source.mMaxDrawBuffers);
372 EquationStorage::SetValueIndexed(
373 index, EquationStorage::GetValueIndexed(sourceIndex, source.mEquationColor),
374 &mEquationColor);
375 EquationStorage::SetValueIndexed(
376 index, EquationStorage::GetValueIndexed(sourceIndex, source.mEquationAlpha),
377 &mEquationAlpha);
378 }
379
getEquationColorIndexed(size_t index) const380 GLenum BlendStateExt::getEquationColorIndexed(size_t index) const
381 {
382 ASSERT(index < mMaxDrawBuffers);
383 return ToGLenum(EquationStorage::GetValueIndexed(index, mEquationColor));
384 }
385
getEquationAlphaIndexed(size_t index) const386 GLenum BlendStateExt::getEquationAlphaIndexed(size_t index) const
387 {
388 ASSERT(index < mMaxDrawBuffers);
389 return ToGLenum(EquationStorage::GetValueIndexed(index, mEquationAlpha));
390 }
391
compareEquations(const EquationStorage::Type color,const EquationStorage::Type alpha) const392 DrawBufferMask BlendStateExt::compareEquations(const EquationStorage::Type color,
393 const EquationStorage::Type alpha) const
394 {
395 return EquationStorage::GetDiffMask(mEquationColor, color) |
396 EquationStorage::GetDiffMask(mEquationAlpha, alpha);
397 }
398
expandFactorValue(const GLenum func) const399 BlendStateExt::FactorStorage::Type BlendStateExt::expandFactorValue(const GLenum func) const
400 {
401 return FactorStorage::GetReplicatedValue(FromGLenum<BlendFactorType>(func), mMaxFactorMask);
402 }
403
expandSrcColorIndexed(const size_t index) const404 BlendStateExt::FactorStorage::Type BlendStateExt::expandSrcColorIndexed(const size_t index) const
405 {
406 ASSERT(index < mMaxDrawBuffers);
407 return FactorStorage::GetReplicatedValue(FactorStorage::GetValueIndexed(index, mSrcColor),
408 mMaxFactorMask);
409 }
410
expandDstColorIndexed(const size_t index) const411 BlendStateExt::FactorStorage::Type BlendStateExt::expandDstColorIndexed(const size_t index) const
412 {
413 ASSERT(index < mMaxDrawBuffers);
414 return FactorStorage::GetReplicatedValue(FactorStorage::GetValueIndexed(index, mDstColor),
415 mMaxFactorMask);
416 }
417
expandSrcAlphaIndexed(const size_t index) const418 BlendStateExt::FactorStorage::Type BlendStateExt::expandSrcAlphaIndexed(const size_t index) const
419 {
420 ASSERT(index < mMaxDrawBuffers);
421 return FactorStorage::GetReplicatedValue(FactorStorage::GetValueIndexed(index, mSrcAlpha),
422 mMaxFactorMask);
423 }
424
expandDstAlphaIndexed(const size_t index) const425 BlendStateExt::FactorStorage::Type BlendStateExt::expandDstAlphaIndexed(const size_t index) const
426 {
427 ASSERT(index < mMaxDrawBuffers);
428 return FactorStorage::GetReplicatedValue(FactorStorage::GetValueIndexed(index, mDstAlpha),
429 mMaxFactorMask);
430 }
431
setFactors(const GLenum srcColor,const GLenum dstColor,const GLenum srcAlpha,const GLenum dstAlpha)432 void BlendStateExt::setFactors(const GLenum srcColor,
433 const GLenum dstColor,
434 const GLenum srcAlpha,
435 const GLenum dstAlpha)
436 {
437 mSrcColor = expandFactorValue(srcColor);
438 mDstColor = expandFactorValue(dstColor);
439 mSrcAlpha = expandFactorValue(srcAlpha);
440 mDstAlpha = expandFactorValue(dstAlpha);
441 }
442
setFactorsIndexed(const size_t index,const GLenum srcColor,const GLenum dstColor,const GLenum srcAlpha,const GLenum dstAlpha)443 void BlendStateExt::setFactorsIndexed(const size_t index,
444 const GLenum srcColor,
445 const GLenum dstColor,
446 const GLenum srcAlpha,
447 const GLenum dstAlpha)
448 {
449 ASSERT(index < mMaxDrawBuffers);
450 FactorStorage::SetValueIndexed(index, FromGLenum<BlendFactorType>(srcColor), &mSrcColor);
451 FactorStorage::SetValueIndexed(index, FromGLenum<BlendFactorType>(dstColor), &mDstColor);
452 FactorStorage::SetValueIndexed(index, FromGLenum<BlendFactorType>(srcAlpha), &mSrcAlpha);
453 FactorStorage::SetValueIndexed(index, FromGLenum<BlendFactorType>(dstAlpha), &mDstAlpha);
454 }
455
setFactorsIndexed(const size_t index,const size_t sourceIndex,const BlendStateExt & source)456 void BlendStateExt::setFactorsIndexed(const size_t index,
457 const size_t sourceIndex,
458 const BlendStateExt &source)
459 {
460 ASSERT(index < mMaxDrawBuffers);
461 ASSERT(sourceIndex < source.mMaxDrawBuffers);
462 FactorStorage::SetValueIndexed(
463 index, FactorStorage::GetValueIndexed(sourceIndex, source.mSrcColor), &mSrcColor);
464 FactorStorage::SetValueIndexed(
465 index, FactorStorage::GetValueIndexed(sourceIndex, source.mDstColor), &mDstColor);
466 FactorStorage::SetValueIndexed(
467 index, FactorStorage::GetValueIndexed(sourceIndex, source.mSrcAlpha), &mSrcAlpha);
468 FactorStorage::SetValueIndexed(
469 index, FactorStorage::GetValueIndexed(sourceIndex, source.mDstAlpha), &mDstAlpha);
470 }
471
getSrcColorIndexed(size_t index) const472 GLenum BlendStateExt::getSrcColorIndexed(size_t index) const
473 {
474 ASSERT(index < mMaxDrawBuffers);
475 return ToGLenum(FactorStorage::GetValueIndexed(index, mSrcColor));
476 }
477
getDstColorIndexed(size_t index) const478 GLenum BlendStateExt::getDstColorIndexed(size_t index) const
479 {
480 ASSERT(index < mMaxDrawBuffers);
481 return ToGLenum(FactorStorage::GetValueIndexed(index, mDstColor));
482 }
483
getSrcAlphaIndexed(size_t index) const484 GLenum BlendStateExt::getSrcAlphaIndexed(size_t index) const
485 {
486 ASSERT(index < mMaxDrawBuffers);
487 return ToGLenum(FactorStorage::GetValueIndexed(index, mSrcAlpha));
488 }
489
getDstAlphaIndexed(size_t index) const490 GLenum BlendStateExt::getDstAlphaIndexed(size_t index) const
491 {
492 ASSERT(index < mMaxDrawBuffers);
493 return ToGLenum(FactorStorage::GetValueIndexed(index, mDstAlpha));
494 }
495
compareFactors(const FactorStorage::Type srcColor,const FactorStorage::Type dstColor,const FactorStorage::Type srcAlpha,const FactorStorage::Type dstAlpha) const496 DrawBufferMask BlendStateExt::compareFactors(const FactorStorage::Type srcColor,
497 const FactorStorage::Type dstColor,
498 const FactorStorage::Type srcAlpha,
499 const FactorStorage::Type dstAlpha) const
500 {
501 return FactorStorage::GetDiffMask(mSrcColor, srcColor) |
502 FactorStorage::GetDiffMask(mDstColor, dstColor) |
503 FactorStorage::GetDiffMask(mSrcAlpha, srcAlpha) |
504 FactorStorage::GetDiffMask(mDstAlpha, dstAlpha);
505 }
506
MinMax(int a,int b,int * minimum,int * maximum)507 static void MinMax(int a, int b, int *minimum, int *maximum)
508 {
509 if (a < b)
510 {
511 *minimum = a;
512 *maximum = b;
513 }
514 else
515 {
516 *minimum = b;
517 *maximum = a;
518 }
519 }
520
flip(bool flipX,bool flipY) const521 Rectangle Rectangle::flip(bool flipX, bool flipY) const
522 {
523 Rectangle flipped = *this;
524 if (flipX)
525 {
526 flipped.x = flipped.x + flipped.width;
527 flipped.width = -flipped.width;
528 }
529 if (flipY)
530 {
531 flipped.y = flipped.y + flipped.height;
532 flipped.height = -flipped.height;
533 }
534 return flipped;
535 }
536
removeReversal() const537 Rectangle Rectangle::removeReversal() const
538 {
539 return flip(isReversedX(), isReversedY());
540 }
541
encloses(const gl::Rectangle & inside) const542 bool Rectangle::encloses(const gl::Rectangle &inside) const
543 {
544 return x0() <= inside.x0() && y0() <= inside.y0() && x1() >= inside.x1() && y1() >= inside.y1();
545 }
546
ClipRectangle(const Rectangle & source,const Rectangle & clip,Rectangle * intersection)547 bool ClipRectangle(const Rectangle &source, const Rectangle &clip, Rectangle *intersection)
548 {
549 int minSourceX, maxSourceX, minSourceY, maxSourceY;
550 MinMax(source.x, source.x + source.width, &minSourceX, &maxSourceX);
551 MinMax(source.y, source.y + source.height, &minSourceY, &maxSourceY);
552
553 int minClipX, maxClipX, minClipY, maxClipY;
554 MinMax(clip.x, clip.x + clip.width, &minClipX, &maxClipX);
555 MinMax(clip.y, clip.y + clip.height, &minClipY, &maxClipY);
556
557 if (minSourceX >= maxClipX || maxSourceX <= minClipX || minSourceY >= maxClipY ||
558 maxSourceY <= minClipY)
559 {
560 return false;
561 }
562 if (intersection)
563 {
564 intersection->x = std::max(minSourceX, minClipX);
565 intersection->y = std::max(minSourceY, minClipY);
566 intersection->width = std::min(maxSourceX, maxClipX) - std::max(minSourceX, minClipX);
567 intersection->height = std::min(maxSourceY, maxClipY) - std::max(minSourceY, minClipY);
568 }
569 return true;
570 }
571
operator ==(const Box & other) const572 bool Box::operator==(const Box &other) const
573 {
574 return (x == other.x && y == other.y && z == other.z && width == other.width &&
575 height == other.height && depth == other.depth);
576 }
577
operator !=(const Box & other) const578 bool Box::operator!=(const Box &other) const
579 {
580 return !(*this == other);
581 }
582
toRect() const583 Rectangle Box::toRect() const
584 {
585 ASSERT(z == 0 && depth == 1);
586 return Rectangle(x, y, width, height);
587 }
588
operator ==(const Offset & a,const Offset & b)589 bool operator==(const Offset &a, const Offset &b)
590 {
591 return a.x == b.x && a.y == b.y && a.z == b.z;
592 }
593
operator !=(const Offset & a,const Offset & b)594 bool operator!=(const Offset &a, const Offset &b)
595 {
596 return !(a == b);
597 }
598
operator ==(const Extents & lhs,const Extents & rhs)599 bool operator==(const Extents &lhs, const Extents &rhs)
600 {
601 return lhs.width == rhs.width && lhs.height == rhs.height && lhs.depth == rhs.depth;
602 }
603
operator !=(const Extents & lhs,const Extents & rhs)604 bool operator!=(const Extents &lhs, const Extents &rhs)
605 {
606 return !(lhs == rhs);
607 }
608
ValidateComponentTypeMasks(unsigned long outputTypes,unsigned long inputTypes,unsigned long outputMask,unsigned long inputMask)609 bool ValidateComponentTypeMasks(unsigned long outputTypes,
610 unsigned long inputTypes,
611 unsigned long outputMask,
612 unsigned long inputMask)
613 {
614 static_assert(IMPLEMENTATION_MAX_DRAW_BUFFERS <= kMaxComponentTypeMaskIndex,
615 "Output/input masks should fit into 16 bits - 1 bit per draw buffer. The "
616 "corresponding type masks should fit into 32 bits - 2 bits per draw buffer.");
617 static_assert(MAX_VERTEX_ATTRIBS <= kMaxComponentTypeMaskIndex,
618 "Output/input masks should fit into 16 bits - 1 bit per attrib. The "
619 "corresponding type masks should fit into 32 bits - 2 bits per attrib.");
620
621 // For performance reasons, draw buffer and attribute type validation is done using bit masks.
622 // We store two bits representing the type split, with the low bit in the lower 16 bits of the
623 // variable, and the high bit in the upper 16 bits of the variable. This is done so we can AND
624 // with the elswewhere used DrawBufferMask or AttributeMask.
625
626 // OR the masks with themselves, shifted 16 bits. This is to match our split type bits.
627 outputMask |= (outputMask << kMaxComponentTypeMaskIndex);
628 inputMask |= (inputMask << kMaxComponentTypeMaskIndex);
629
630 // To validate:
631 // 1. Remove any indexes that are not enabled in the input (& inputMask)
632 // 2. Remove any indexes that exist in output, but not in input (& outputMask)
633 // 3. Use == to verify equality
634 return (outputTypes & inputMask) == ((inputTypes & outputMask) & inputMask);
635 }
636
GetBoundBufferAvailableSize(const OffsetBindingPointer<Buffer> & binding)637 GLsizeiptr GetBoundBufferAvailableSize(const OffsetBindingPointer<Buffer> &binding)
638 {
639 Buffer *buffer = binding.get();
640 if (buffer)
641 {
642 if (binding.getSize() == 0)
643 return static_cast<GLsizeiptr>(buffer->getSize());
644 angle::CheckedNumeric<GLintptr> offset = binding.getOffset();
645 angle::CheckedNumeric<GLsizeiptr> size = binding.getSize();
646 angle::CheckedNumeric<GLsizeiptr> bufferSize = buffer->getSize();
647 auto end = offset + size;
648 auto clampedSize = size;
649 auto difference = end - bufferSize;
650 if (!difference.IsValid())
651 {
652 return 0;
653 }
654 if (difference.ValueOrDie() > 0)
655 {
656 clampedSize = size - difference;
657 }
658 return clampedSize.ValueOrDefault(0);
659 }
660 else
661 {
662 return 0;
663 }
664 }
665
666 } // namespace gl
667