1//
2// Copyright (c) 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 "libGLESv2/angletypes.h"
10#include "libGLESv2/ProgramBinary.h"
11#include "libGLESv2/VertexAttribute.h"
12
13namespace gl
14{
15
16SamplerState::SamplerState()
17    : minFilter(GL_NEAREST_MIPMAP_LINEAR),
18      magFilter(GL_LINEAR),
19      wrapS(GL_REPEAT),
20      wrapT(GL_REPEAT),
21      wrapR(GL_REPEAT),
22      maxAnisotropy(1.0f),
23      baseLevel(0),
24      maxLevel(1000),
25      minLod(-1000.0f),
26      maxLod(1000.0f),
27      compareMode(GL_NONE),
28      compareFunc(GL_LEQUAL),
29      swizzleRed(GL_RED),
30      swizzleGreen(GL_GREEN),
31      swizzleBlue(GL_BLUE),
32      swizzleAlpha(GL_ALPHA)
33{}
34
35bool SamplerState::swizzleRequired() const
36{
37    return swizzleRed != GL_RED || swizzleGreen != GL_GREEN ||
38           swizzleBlue != GL_BLUE || swizzleAlpha != GL_ALPHA;
39}
40
41static void MinMax(int a, int b, int *minimum, int *maximum)
42{
43    if (a < b)
44    {
45        *minimum = a;
46        *maximum = b;
47    }
48    else
49    {
50        *minimum = b;
51        *maximum = a;
52    }
53}
54
55bool ClipRectangle(const Rectangle &source, const Rectangle &clip, Rectangle *intersection)
56{
57    int minSourceX, maxSourceX, minSourceY, maxSourceY;
58    MinMax(source.x, source.x + source.width, &minSourceX, &maxSourceX);
59    MinMax(source.y, source.y + source.height, &minSourceY, &maxSourceY);
60
61    int minClipX, maxClipX, minClipY, maxClipY;
62    MinMax(clip.x, clip.x + clip.width, &minClipX, &maxClipX);
63    MinMax(clip.y, clip.y + clip.height, &minClipY, &maxClipY);
64
65    if (minSourceX >= maxClipX || maxSourceX <= minClipX || minSourceY >= maxClipY || maxSourceY <= minClipY)
66    {
67        if (intersection)
68        {
69            intersection->x = minSourceX;
70            intersection->y = maxSourceY;
71            intersection->width = maxSourceX - minSourceX;
72            intersection->height = maxSourceY - minSourceY;
73        }
74
75        return false;
76    }
77    else
78    {
79        if (intersection)
80        {
81            intersection->x = std::max(minSourceX, minClipX);
82            intersection->y = std::max(minSourceY, minClipY);
83            intersection->width  = std::min(maxSourceX, maxClipX) - std::max(minSourceX, minClipX);
84            intersection->height = std::min(maxSourceY, maxClipY) - std::max(minSourceY, minClipY);
85        }
86
87        return true;
88    }
89}
90
91VertexFormat::VertexFormat()
92    : mType(GL_NONE),
93      mNormalized(GL_FALSE),
94      mComponents(0),
95      mPureInteger(false)
96{}
97
98VertexFormat::VertexFormat(GLenum type, GLboolean normalized, GLuint components, bool pureInteger)
99    : mType(type),
100      mNormalized(normalized),
101      mComponents(components),
102      mPureInteger(pureInteger)
103{
104    // Float data can not be normalized, so ignore the user setting
105    if (mType == GL_FLOAT || mType == GL_HALF_FLOAT || mType == GL_FIXED)
106    {
107        mNormalized = GL_FALSE;
108    }
109}
110
111VertexFormat::VertexFormat(const VertexAttribute &attrib)
112    : mType(attrib.type),
113      mNormalized(attrib.normalized ? GL_TRUE : GL_FALSE),
114      mComponents(attrib.size),
115      mPureInteger(attrib.pureInteger)
116{
117    // Ensure we aren't initializing a vertex format which should be using
118    // the current-value type
119    ASSERT(attrib.enabled);
120
121    // Float data can not be normalized, so ignore the user setting
122    if (mType == GL_FLOAT || mType == GL_HALF_FLOAT || mType == GL_FIXED)
123    {
124        mNormalized = GL_FALSE;
125    }
126}
127
128VertexFormat::VertexFormat(const VertexAttribute &attrib, GLenum currentValueType)
129    : mType(attrib.type),
130      mNormalized(attrib.normalized ? GL_TRUE : GL_FALSE),
131      mComponents(attrib.size),
132      mPureInteger(attrib.pureInteger)
133{
134    if (!attrib.enabled)
135    {
136        mType = currentValueType;
137        mNormalized = GL_FALSE;
138        mComponents = 4;
139        mPureInteger = (currentValueType != GL_FLOAT);
140    }
141
142    // Float data can not be normalized, so ignore the user setting
143    if (mType == GL_FLOAT || mType == GL_HALF_FLOAT || mType == GL_FIXED)
144    {
145        mNormalized = GL_FALSE;
146    }
147}
148
149void VertexFormat::GetInputLayout(VertexFormat *inputLayout,
150                                  ProgramBinary *programBinary,
151                                  const VertexAttribute *attributes,
152                                  const gl::VertexAttribCurrentValueData *currentValues)
153{
154    for (unsigned int attributeIndex = 0; attributeIndex < MAX_VERTEX_ATTRIBS; attributeIndex++)
155    {
156        int semanticIndex = programBinary->getSemanticIndex(attributeIndex);
157
158        if (semanticIndex != -1)
159        {
160            inputLayout[semanticIndex] = VertexFormat(attributes[attributeIndex], currentValues[attributeIndex].Type);
161        }
162    }
163}
164
165bool VertexFormat::operator==(const VertexFormat &other) const
166{
167    return (mType == other.mType                &&
168            mComponents == other.mComponents    &&
169            mNormalized == other.mNormalized    &&
170            mPureInteger == other.mPureInteger  );
171}
172
173bool VertexFormat::operator!=(const VertexFormat &other) const
174{
175    return !(*this == other);
176}
177
178bool VertexFormat::operator<(const VertexFormat& other) const
179{
180    if (mType != other.mType)
181    {
182        return mType < other.mType;
183    }
184    if (mNormalized != other.mNormalized)
185    {
186        return mNormalized < other.mNormalized;
187    }
188    if (mComponents != other.mComponents)
189    {
190        return mComponents < other.mComponents;
191    }
192    return mPureInteger < other.mPureInteger;
193}
194
195}
196