1 //
2 // Copyright 2018 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 // GLES1State.cpp: Implements the GLES1State class, tracking state
8 // for GLES1 contexts.
9
10 #include "libANGLE/GLES1State.h"
11
12 #include "libANGLE/Context.h"
13 #include "libANGLE/GLES1Renderer.h"
14
15 namespace gl
16 {
17
18 TextureCoordF::TextureCoordF() = default;
19
TextureCoordF(float _s,float _t,float _r,float _q)20 TextureCoordF::TextureCoordF(float _s, float _t, float _r, float _q) : s(_s), t(_t), r(_r), q(_q) {}
21
operator ==(const TextureCoordF & other) const22 bool TextureCoordF::operator==(const TextureCoordF &other) const
23 {
24 return s == other.s && t == other.t && r == other.r && q == other.q;
25 }
26
27 MaterialParameters::MaterialParameters() = default;
28
29 LightModelParameters::LightModelParameters() = default;
30
31 LightParameters::LightParameters() = default;
32
33 LightParameters::LightParameters(const LightParameters &other) = default;
34
35 FogParameters::FogParameters() = default;
36
37 TextureEnvironmentParameters::TextureEnvironmentParameters() = default;
38
39 TextureEnvironmentParameters::TextureEnvironmentParameters(
40 const TextureEnvironmentParameters &other) = default;
41
42 PointParameters::PointParameters() = default;
43
44 PointParameters::PointParameters(const PointParameters &other) = default;
45
46 ClipPlaneParameters::ClipPlaneParameters() = default;
47
ClipPlaneParameters(bool enabled,const angle::Vector4 & equation)48 ClipPlaneParameters::ClipPlaneParameters(bool enabled, const angle::Vector4 &equation)
49 : enabled(enabled), equation(equation)
50 {}
51
52 ClipPlaneParameters::ClipPlaneParameters(const ClipPlaneParameters &other) = default;
53
GLES1State()54 GLES1State::GLES1State()
55 : mGLState(nullptr),
56 mVertexArrayEnabled(false),
57 mNormalArrayEnabled(false),
58 mColorArrayEnabled(false),
59 mPointSizeArrayEnabled(false),
60 mLineSmoothEnabled(false),
61 mPointSmoothEnabled(false),
62 mPointSpriteEnabled(false),
63 mAlphaTestEnabled(false),
64 mLogicOpEnabled(false),
65 mLightingEnabled(false),
66 mFogEnabled(false),
67 mRescaleNormalEnabled(false),
68 mNormalizeEnabled(false),
69 mColorMaterialEnabled(false),
70 mReflectionMapEnabled(false),
71 mCurrentColor({0.0f, 0.0f, 0.0f, 0.0f}),
72 mCurrentNormal({0.0f, 0.0f, 0.0f}),
73 mClientActiveTexture(0),
74 mMatrixMode(MatrixType::Modelview),
75 mShadeModel(ShadingModel::Smooth),
76 mAlphaTestFunc(AlphaTestFunc::AlwaysPass),
77 mAlphaTestRef(0.0f),
78 mLogicOp(LogicalOperation::Copy),
79 mLineSmoothHint(HintSetting::DontCare),
80 mPointSmoothHint(HintSetting::DontCare),
81 mPerspectiveCorrectionHint(HintSetting::DontCare),
82 mFogHint(HintSetting::DontCare)
83 {}
84
85 GLES1State::~GLES1State() = default;
86
87 // Taken from the GLES 1.x spec which specifies all initial state values.
initialize(const Context * context,const State * state)88 void GLES1State::initialize(const Context *context, const State *state)
89 {
90 mGLState = state;
91
92 const Caps &caps = context->getCaps();
93
94 mTexUnitEnables.resize(caps.maxMultitextureUnits);
95 for (auto &enables : mTexUnitEnables)
96 {
97 enables.reset();
98 }
99
100 mVertexArrayEnabled = false;
101 mNormalArrayEnabled = false;
102 mColorArrayEnabled = false;
103 mPointSizeArrayEnabled = false;
104 mTexCoordArrayEnabled.resize(caps.maxMultitextureUnits, false);
105
106 mLineSmoothEnabled = false;
107 mPointSmoothEnabled = false;
108 mPointSpriteEnabled = false;
109 mLogicOpEnabled = false;
110 mAlphaTestEnabled = false;
111 mLightingEnabled = false;
112 mFogEnabled = false;
113 mRescaleNormalEnabled = false;
114 mNormalizeEnabled = false;
115 mColorMaterialEnabled = false;
116 mReflectionMapEnabled = false;
117
118 mMatrixMode = MatrixType::Modelview;
119
120 mCurrentColor = {1.0f, 1.0f, 1.0f, 1.0f};
121 mCurrentNormal = {0.0f, 0.0f, 1.0f};
122 mCurrentTextureCoords.resize(caps.maxMultitextureUnits);
123 mClientActiveTexture = 0;
124
125 mTextureEnvironments.resize(caps.maxMultitextureUnits);
126
127 mModelviewMatrices.push_back(angle::Mat4());
128 mProjectionMatrices.push_back(angle::Mat4());
129 mTextureMatrices.resize(caps.maxMultitextureUnits);
130 for (auto &stack : mTextureMatrices)
131 {
132 stack.push_back(angle::Mat4());
133 }
134
135 mMaterial.ambient = {0.2f, 0.2f, 0.2f, 1.0f};
136 mMaterial.diffuse = {0.8f, 0.8f, 0.8f, 1.0f};
137 mMaterial.specular = {0.0f, 0.0f, 0.0f, 1.0f};
138 mMaterial.emissive = {0.0f, 0.0f, 0.0f, 1.0f};
139
140 mMaterial.specularExponent = 0.0f;
141
142 mLightModel.color = {0.2f, 0.2f, 0.2f, 1.0f};
143 mLightModel.twoSided = false;
144
145 mLights.resize(caps.maxLights);
146
147 // GL_LIGHT0 is special and has default state that avoids all-black renderings.
148 mLights[0].diffuse = {1.0f, 1.0f, 1.0f, 1.0f};
149 mLights[0].specular = {1.0f, 1.0f, 1.0f, 1.0f};
150
151 mFog.mode = FogMode::Exp;
152 mFog.density = 1.0f;
153 mFog.start = 0.0f;
154 mFog.end = 1.0f;
155
156 mFog.color = {0.0f, 0.0f, 0.0f, 0.0f};
157
158 mShadeModel = ShadingModel::Smooth;
159
160 mAlphaTestFunc = AlphaTestFunc::AlwaysPass;
161 mAlphaTestRef = 0.0f;
162
163 mLogicOp = LogicalOperation::Copy;
164
165 mClipPlanes.resize(caps.maxClipPlanes,
166 ClipPlaneParameters(false, angle::Vector4(0.0f, 0.0f, 0.0f, 0.0f)));
167
168 mLineSmoothHint = HintSetting::DontCare;
169 mPointSmoothHint = HintSetting::DontCare;
170 mPerspectiveCorrectionHint = HintSetting::DontCare;
171 mFogHint = HintSetting::DontCare;
172
173 // The user-specified point size, GL_POINT_SIZE_MAX,
174 // is initially equal to the implementation maximum.
175 mPointParameters.pointSizeMax = caps.maxAliasedPointSize;
176
177 mDirtyBits.set();
178 }
179
setAlphaFunc(AlphaTestFunc func,GLfloat ref)180 void GLES1State::setAlphaFunc(AlphaTestFunc func, GLfloat ref)
181 {
182 setDirty(DIRTY_GLES1_ALPHA_TEST);
183 mAlphaTestFunc = func;
184 mAlphaTestRef = ref;
185 }
186
setClientTextureUnit(unsigned int unit)187 void GLES1State::setClientTextureUnit(unsigned int unit)
188 {
189 setDirty(DIRTY_GLES1_CLIENT_ACTIVE_TEXTURE);
190 mClientActiveTexture = unit;
191 }
192
getClientTextureUnit() const193 unsigned int GLES1State::getClientTextureUnit() const
194 {
195 return mClientActiveTexture;
196 }
197
setCurrentColor(const ColorF & color)198 void GLES1State::setCurrentColor(const ColorF &color)
199 {
200 setDirty(DIRTY_GLES1_CURRENT_VECTOR);
201 mCurrentColor = color;
202 }
203
getCurrentColor() const204 const ColorF &GLES1State::getCurrentColor() const
205 {
206 return mCurrentColor;
207 }
208
setCurrentNormal(const angle::Vector3 & normal)209 void GLES1State::setCurrentNormal(const angle::Vector3 &normal)
210 {
211 setDirty(DIRTY_GLES1_CURRENT_VECTOR);
212 mCurrentNormal = normal;
213 }
214
getCurrentNormal() const215 const angle::Vector3 &GLES1State::getCurrentNormal() const
216 {
217 return mCurrentNormal;
218 }
219
setCurrentTextureCoords(unsigned int unit,const TextureCoordF & coords)220 void GLES1State::setCurrentTextureCoords(unsigned int unit, const TextureCoordF &coords)
221 {
222 setDirty(DIRTY_GLES1_CURRENT_VECTOR);
223 mCurrentTextureCoords[unit] = coords;
224 }
225
getCurrentTextureCoords(unsigned int unit) const226 const TextureCoordF &GLES1State::getCurrentTextureCoords(unsigned int unit) const
227 {
228 return mCurrentTextureCoords[unit];
229 }
230
setMatrixMode(MatrixType mode)231 void GLES1State::setMatrixMode(MatrixType mode)
232 {
233 setDirty(DIRTY_GLES1_MATRICES);
234 mMatrixMode = mode;
235 }
236
getMatrixMode() const237 MatrixType GLES1State::getMatrixMode() const
238 {
239 return mMatrixMode;
240 }
241
getCurrentMatrixStackDepth(GLenum queryType) const242 GLint GLES1State::getCurrentMatrixStackDepth(GLenum queryType) const
243 {
244 switch (queryType)
245 {
246 case GL_MODELVIEW_STACK_DEPTH:
247 return clampCast<GLint>(mModelviewMatrices.size());
248 case GL_PROJECTION_STACK_DEPTH:
249 return clampCast<GLint>(mProjectionMatrices.size());
250 case GL_TEXTURE_STACK_DEPTH:
251 return clampCast<GLint>(mTextureMatrices[mGLState->getActiveSampler()].size());
252 default:
253 UNREACHABLE();
254 return 0;
255 }
256 }
257
pushMatrix()258 void GLES1State::pushMatrix()
259 {
260 setDirty(DIRTY_GLES1_MATRICES);
261 auto &stack = currentMatrixStack();
262 stack.push_back(stack.back());
263 }
264
popMatrix()265 void GLES1State::popMatrix()
266 {
267 setDirty(DIRTY_GLES1_MATRICES);
268 auto &stack = currentMatrixStack();
269 stack.pop_back();
270 }
271
currentMatrixStack()272 GLES1State::MatrixStack &GLES1State::currentMatrixStack()
273 {
274 setDirty(DIRTY_GLES1_MATRICES);
275 switch (mMatrixMode)
276 {
277 case MatrixType::Modelview:
278 return mModelviewMatrices;
279 case MatrixType::Projection:
280 return mProjectionMatrices;
281 case MatrixType::Texture:
282 return mTextureMatrices[mGLState->getActiveSampler()];
283 default:
284 UNREACHABLE();
285 return mModelviewMatrices;
286 }
287 }
288
getModelviewMatrix() const289 const angle::Mat4 &GLES1State::getModelviewMatrix() const
290 {
291 return mModelviewMatrices.back();
292 }
293
currentMatrixStack() const294 const GLES1State::MatrixStack &GLES1State::currentMatrixStack() const
295 {
296 switch (mMatrixMode)
297 {
298 case MatrixType::Modelview:
299 return mModelviewMatrices;
300 case MatrixType::Projection:
301 return mProjectionMatrices;
302 case MatrixType::Texture:
303 return mTextureMatrices[mGLState->getActiveSampler()];
304 default:
305 UNREACHABLE();
306 return mModelviewMatrices;
307 }
308 }
309
loadMatrix(const angle::Mat4 & m)310 void GLES1State::loadMatrix(const angle::Mat4 &m)
311 {
312 setDirty(DIRTY_GLES1_MATRICES);
313 currentMatrixStack().back() = m;
314 }
315
multMatrix(const angle::Mat4 & m)316 void GLES1State::multMatrix(const angle::Mat4 &m)
317 {
318 setDirty(DIRTY_GLES1_MATRICES);
319 angle::Mat4 currentMatrix = currentMatrixStack().back();
320 currentMatrixStack().back() = currentMatrix.product(m);
321 }
322
setLogicOp(LogicalOperation opcodePacked)323 void GLES1State::setLogicOp(LogicalOperation opcodePacked)
324 {
325 setDirty(DIRTY_GLES1_LOGIC_OP);
326 mLogicOp = opcodePacked;
327 }
328
setClientStateEnabled(ClientVertexArrayType clientState,bool enable)329 void GLES1State::setClientStateEnabled(ClientVertexArrayType clientState, bool enable)
330 {
331 setDirty(DIRTY_GLES1_CLIENT_STATE_ENABLE);
332 switch (clientState)
333 {
334 case ClientVertexArrayType::Vertex:
335 mVertexArrayEnabled = enable;
336 break;
337 case ClientVertexArrayType::Normal:
338 mNormalArrayEnabled = enable;
339 break;
340 case ClientVertexArrayType::Color:
341 mColorArrayEnabled = enable;
342 break;
343 case ClientVertexArrayType::PointSize:
344 mPointSizeArrayEnabled = enable;
345 break;
346 case ClientVertexArrayType::TextureCoord:
347 mTexCoordArrayEnabled[mClientActiveTexture] = enable;
348 break;
349 default:
350 UNREACHABLE();
351 break;
352 }
353 }
354
setTexCoordArrayEnabled(unsigned int unit,bool enable)355 void GLES1State::setTexCoordArrayEnabled(unsigned int unit, bool enable)
356 {
357 setDirty(DIRTY_GLES1_CLIENT_STATE_ENABLE);
358 mTexCoordArrayEnabled[unit] = enable;
359 }
360
isClientStateEnabled(ClientVertexArrayType clientState) const361 bool GLES1State::isClientStateEnabled(ClientVertexArrayType clientState) const
362 {
363 switch (clientState)
364 {
365 case ClientVertexArrayType::Vertex:
366 return mVertexArrayEnabled;
367 case ClientVertexArrayType::Normal:
368 return mNormalArrayEnabled;
369 case ClientVertexArrayType::Color:
370 return mColorArrayEnabled;
371 case ClientVertexArrayType::PointSize:
372 return mPointSizeArrayEnabled;
373 case ClientVertexArrayType::TextureCoord:
374 return mTexCoordArrayEnabled[mClientActiveTexture];
375 default:
376 UNREACHABLE();
377 return false;
378 }
379 }
380
isTexCoordArrayEnabled(unsigned int unit) const381 bool GLES1State::isTexCoordArrayEnabled(unsigned int unit) const
382 {
383 ASSERT(unit < mTexCoordArrayEnabled.size());
384 return mTexCoordArrayEnabled[unit];
385 }
386
isTextureTargetEnabled(unsigned int unit,const TextureType type) const387 bool GLES1State::isTextureTargetEnabled(unsigned int unit, const TextureType type) const
388 {
389 return mTexUnitEnables[unit].test(type);
390 }
391
lightModelParameters()392 LightModelParameters &GLES1State::lightModelParameters()
393 {
394 setDirty(DIRTY_GLES1_LIGHTS);
395 return mLightModel;
396 }
397
lightModelParameters() const398 const LightModelParameters &GLES1State::lightModelParameters() const
399 {
400 return mLightModel;
401 }
402
lightParameters(unsigned int light)403 LightParameters &GLES1State::lightParameters(unsigned int light)
404 {
405 setDirty(DIRTY_GLES1_LIGHTS);
406 return mLights[light];
407 }
408
lightParameters(unsigned int light) const409 const LightParameters &GLES1State::lightParameters(unsigned int light) const
410 {
411 return mLights[light];
412 }
413
materialParameters()414 MaterialParameters &GLES1State::materialParameters()
415 {
416 setDirty(DIRTY_GLES1_MATERIAL);
417 return mMaterial;
418 }
419
materialParameters() const420 const MaterialParameters &GLES1State::materialParameters() const
421 {
422 return mMaterial;
423 }
424
isColorMaterialEnabled() const425 bool GLES1State::isColorMaterialEnabled() const
426 {
427 return mColorMaterialEnabled;
428 }
429
setShadeModel(ShadingModel model)430 void GLES1State::setShadeModel(ShadingModel model)
431 {
432 setDirty(DIRTY_GLES1_SHADE_MODEL);
433 mShadeModel = model;
434 }
435
setClipPlane(unsigned int plane,const GLfloat * equation)436 void GLES1State::setClipPlane(unsigned int plane, const GLfloat *equation)
437 {
438 setDirty(DIRTY_GLES1_CLIP_PLANES);
439 assert(plane < mClipPlanes.size());
440 mClipPlanes[plane].equation[0] = equation[0];
441 mClipPlanes[plane].equation[1] = equation[1];
442 mClipPlanes[plane].equation[2] = equation[2];
443 mClipPlanes[plane].equation[3] = equation[3];
444 }
445
getClipPlane(unsigned int plane,GLfloat * equation) const446 void GLES1State::getClipPlane(unsigned int plane, GLfloat *equation) const
447 {
448 assert(plane < mClipPlanes.size());
449 equation[0] = mClipPlanes[plane].equation[0];
450 equation[1] = mClipPlanes[plane].equation[1];
451 equation[2] = mClipPlanes[plane].equation[2];
452 equation[3] = mClipPlanes[plane].equation[3];
453 }
454
fogParameters()455 FogParameters &GLES1State::fogParameters()
456 {
457 setDirty(DIRTY_GLES1_FOG);
458 return mFog;
459 }
460
fogParameters() const461 const FogParameters &GLES1State::fogParameters() const
462 {
463 return mFog;
464 }
465
textureEnvironment(unsigned int unit)466 TextureEnvironmentParameters &GLES1State::textureEnvironment(unsigned int unit)
467 {
468 setDirty(DIRTY_GLES1_TEXTURE_ENVIRONMENT);
469 assert(unit < mTextureEnvironments.size());
470 return mTextureEnvironments[unit];
471 }
472
textureEnvironment(unsigned int unit) const473 const TextureEnvironmentParameters &GLES1State::textureEnvironment(unsigned int unit) const
474 {
475 assert(unit < mTextureEnvironments.size());
476 return mTextureEnvironments[unit];
477 }
478
pointParameters()479 PointParameters &GLES1State::pointParameters()
480 {
481 setDirty(DIRTY_GLES1_POINT_PARAMETERS);
482 return mPointParameters;
483 }
484
pointParameters() const485 const PointParameters &GLES1State::pointParameters() const
486 {
487 return mPointParameters;
488 }
489
getVertexArraysAttributeMask() const490 AttributesMask GLES1State::getVertexArraysAttributeMask() const
491 {
492 AttributesMask attribsMask;
493
494 ClientVertexArrayType nonTexcoordArrays[] = {
495 ClientVertexArrayType::Vertex,
496 ClientVertexArrayType::Normal,
497 ClientVertexArrayType::Color,
498 ClientVertexArrayType::PointSize,
499 };
500
501 for (const ClientVertexArrayType attrib : nonTexcoordArrays)
502 {
503 attribsMask.set(GLES1Renderer::VertexArrayIndex(attrib, *this),
504 isClientStateEnabled(attrib));
505 }
506
507 for (unsigned int i = 0; i < GLES1Renderer::kTexUnitCount; i++)
508 {
509 attribsMask.set(GLES1Renderer::TexCoordArrayIndex(i), isTexCoordArrayEnabled(i));
510 }
511
512 return attribsMask;
513 }
514
getActiveAttributesMask() const515 AttributesMask GLES1State::getActiveAttributesMask() const
516 {
517 // The program always has 8 attributes enabled.
518 return AttributesMask(0xFF);
519 }
520
setHint(GLenum target,GLenum mode)521 void GLES1State::setHint(GLenum target, GLenum mode)
522 {
523 setDirty(DIRTY_GLES1_HINT_SETTING);
524 HintSetting setting = FromGLenum<HintSetting>(mode);
525 switch (target)
526 {
527 case GL_PERSPECTIVE_CORRECTION_HINT:
528 mPerspectiveCorrectionHint = setting;
529 break;
530 case GL_POINT_SMOOTH_HINT:
531 mPointSmoothHint = setting;
532 break;
533 case GL_LINE_SMOOTH_HINT:
534 mLineSmoothHint = setting;
535 break;
536 case GL_FOG_HINT:
537 mFogHint = setting;
538 break;
539 default:
540 UNREACHABLE();
541 }
542 }
543
getHint(GLenum target) const544 GLenum GLES1State::getHint(GLenum target) const
545 {
546 switch (target)
547 {
548 case GL_PERSPECTIVE_CORRECTION_HINT:
549 return ToGLenum(mPerspectiveCorrectionHint);
550 case GL_POINT_SMOOTH_HINT:
551 return ToGLenum(mPointSmoothHint);
552 case GL_LINE_SMOOTH_HINT:
553 return ToGLenum(mLineSmoothHint);
554 case GL_FOG_HINT:
555 return ToGLenum(mFogHint);
556 default:
557 UNREACHABLE();
558 return 0;
559 }
560 }
561
setDirty(DirtyGles1Type type)562 void GLES1State::setDirty(DirtyGles1Type type)
563 {
564 mDirtyBits.set(type);
565 }
566
setAllDirty()567 void GLES1State::setAllDirty()
568 {
569 mDirtyBits.set();
570 }
571
clearDirty()572 void GLES1State::clearDirty()
573 {
574 mDirtyBits.reset();
575 }
576
isDirty(DirtyGles1Type type) const577 bool GLES1State::isDirty(DirtyGles1Type type) const
578 {
579 return mDirtyBits.test(type);
580 }
581
582 } // namespace gl
583