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 AlphaTestParameters::AlphaTestParameters() = default;
38
operator !=(const AlphaTestParameters & other) const39 bool AlphaTestParameters::operator!=(const AlphaTestParameters &other) const
40 {
41 return func != other.func || ref != other.ref;
42 }
43
44 TextureEnvironmentParameters::TextureEnvironmentParameters() = default;
45
46 TextureEnvironmentParameters::TextureEnvironmentParameters(
47 const TextureEnvironmentParameters &other) = default;
48
49 PointParameters::PointParameters() = default;
50
51 PointParameters::PointParameters(const PointParameters &other) = default;
52
53 ClipPlaneParameters::ClipPlaneParameters() = default;
54
ClipPlaneParameters(bool enabled,const angle::Vector4 & equation)55 ClipPlaneParameters::ClipPlaneParameters(bool enabled, const angle::Vector4 &equation)
56 : enabled(enabled), equation(equation)
57 {}
58
59 ClipPlaneParameters::ClipPlaneParameters(const ClipPlaneParameters &other) = default;
60
61 ClipPlaneParameters &ClipPlaneParameters::operator=(const ClipPlaneParameters &other) = default;
62
GLES1State()63 GLES1State::GLES1State()
64 : mGLState(nullptr),
65 mVertexArrayEnabled(false),
66 mNormalArrayEnabled(false),
67 mColorArrayEnabled(false),
68 mPointSizeArrayEnabled(false),
69 mLineSmoothEnabled(false),
70 mPointSmoothEnabled(false),
71 mPointSpriteEnabled(false),
72 mAlphaTestEnabled(false),
73 mLogicOpEnabled(false),
74 mLightingEnabled(false),
75 mFogEnabled(false),
76 mRescaleNormalEnabled(false),
77 mNormalizeEnabled(false),
78 mColorMaterialEnabled(false),
79 mReflectionMapEnabled(false),
80 mCurrentColor({0.0f, 0.0f, 0.0f, 0.0f}),
81 mCurrentNormal({0.0f, 0.0f, 0.0f}),
82 mClientActiveTexture(0),
83 mMatrixMode(MatrixType::Modelview),
84 mShadeModel(ShadingModel::Smooth),
85 mLogicOp(LogicalOperation::Copy),
86 mLineSmoothHint(HintSetting::DontCare),
87 mPointSmoothHint(HintSetting::DontCare),
88 mPerspectiveCorrectionHint(HintSetting::DontCare),
89 mFogHint(HintSetting::DontCare)
90 {}
91
92 GLES1State::~GLES1State() = default;
93
94 // Taken from the GLES 1.x spec which specifies all initial state values.
initialize(const Context * context,const PrivateState * state)95 void GLES1State::initialize(const Context *context, const PrivateState *state)
96 {
97 mGLState = state;
98
99 const Caps &caps = context->getCaps();
100
101 mTexUnitEnables.resize(caps.maxMultitextureUnits);
102 for (auto &enables : mTexUnitEnables)
103 {
104 enables.reset();
105 }
106
107 mVertexArrayEnabled = false;
108 mNormalArrayEnabled = false;
109 mColorArrayEnabled = false;
110 mPointSizeArrayEnabled = false;
111 mTexCoordArrayEnabled.resize(caps.maxMultitextureUnits, false);
112
113 mLineSmoothEnabled = false;
114 mPointSmoothEnabled = false;
115 mPointSpriteEnabled = false;
116 mLogicOpEnabled = false;
117 mAlphaTestEnabled = false;
118 mLightingEnabled = false;
119 mFogEnabled = false;
120 mRescaleNormalEnabled = false;
121 mNormalizeEnabled = false;
122 mColorMaterialEnabled = false;
123 mReflectionMapEnabled = false;
124
125 mMatrixMode = MatrixType::Modelview;
126
127 mCurrentColor = {1.0f, 1.0f, 1.0f, 1.0f};
128 mCurrentNormal = {0.0f, 0.0f, 1.0f};
129 mCurrentTextureCoords.resize(caps.maxMultitextureUnits);
130 mClientActiveTexture = 0;
131
132 mTextureEnvironments.resize(caps.maxMultitextureUnits);
133
134 mModelviewMatrices.push_back(angle::Mat4());
135 mProjectionMatrices.push_back(angle::Mat4());
136 mTextureMatrices.resize(caps.maxMultitextureUnits);
137 for (auto &stack : mTextureMatrices)
138 {
139 stack.push_back(angle::Mat4());
140 }
141
142 mMaterial.ambient = {0.2f, 0.2f, 0.2f, 1.0f};
143 mMaterial.diffuse = {0.8f, 0.8f, 0.8f, 1.0f};
144 mMaterial.specular = {0.0f, 0.0f, 0.0f, 1.0f};
145 mMaterial.emissive = {0.0f, 0.0f, 0.0f, 1.0f};
146
147 mMaterial.specularExponent = 0.0f;
148
149 mLightModel.color = {0.2f, 0.2f, 0.2f, 1.0f};
150 mLightModel.twoSided = false;
151
152 mLights.resize(caps.maxLights);
153
154 // GL_LIGHT0 is special and has default state that avoids all-black renderings.
155 mLights[0].diffuse = {1.0f, 1.0f, 1.0f, 1.0f};
156 mLights[0].specular = {1.0f, 1.0f, 1.0f, 1.0f};
157
158 mFog.mode = FogMode::Exp;
159 mFog.density = 1.0f;
160 mFog.start = 0.0f;
161 mFog.end = 1.0f;
162
163 mFog.color = {0.0f, 0.0f, 0.0f, 0.0f};
164
165 mShadeModel = ShadingModel::Smooth;
166
167 mAlphaTestParameters.func = AlphaTestFunc::AlwaysPass;
168 mAlphaTestParameters.ref = 0.0f;
169
170 mLogicOp = LogicalOperation::Copy;
171
172 mClipPlanes.resize(caps.maxClipPlanes,
173 ClipPlaneParameters(false, angle::Vector4(0.0f, 0.0f, 0.0f, 0.0f)));
174
175 mLineSmoothHint = HintSetting::DontCare;
176 mPointSmoothHint = HintSetting::DontCare;
177 mPerspectiveCorrectionHint = HintSetting::DontCare;
178 mFogHint = HintSetting::DontCare;
179
180 // The user-specified point size, GL_POINT_SIZE_MAX,
181 // is initially equal to the implementation maximum.
182 mPointParameters.pointSizeMax = caps.maxAliasedPointSize;
183
184 mDirtyBits.set();
185 }
186
setAlphaTestParameters(AlphaTestFunc func,GLfloat ref)187 void GLES1State::setAlphaTestParameters(AlphaTestFunc func, GLfloat ref)
188 {
189 setDirty(DIRTY_GLES1_ALPHA_TEST);
190 mAlphaTestParameters.func = func;
191 mAlphaTestParameters.ref = ref;
192 }
193
setClientTextureUnit(unsigned int unit)194 void GLES1State::setClientTextureUnit(unsigned int unit)
195 {
196 setDirty(DIRTY_GLES1_CLIENT_ACTIVE_TEXTURE);
197 mClientActiveTexture = unit;
198 }
199
getClientTextureUnit() const200 unsigned int GLES1State::getClientTextureUnit() const
201 {
202 return mClientActiveTexture;
203 }
204
setCurrentColor(const ColorF & color)205 void GLES1State::setCurrentColor(const ColorF &color)
206 {
207 setDirty(DIRTY_GLES1_CURRENT_VECTOR);
208 mCurrentColor = color;
209
210 // > When enabled, both the ambient (acm) and diffuse (dcm) properties of both the front and
211 // > back material are immediately set to the value of the current color, and will track changes
212 // > to the current color resulting from either the Color commands or drawing vertex arrays with
213 // > the color array enabled.
214 // > The replacements made to material properties are permanent; the replaced values remain
215 // > until changed by either sending a new color or by setting a new material value when
216 // > COLOR_MATERIAL is not currently enabled, to override that particular value.
217 if (isColorMaterialEnabled())
218 {
219 mMaterial.ambient = color;
220 mMaterial.diffuse = color;
221 }
222 }
223
getCurrentColor() const224 const ColorF &GLES1State::getCurrentColor() const
225 {
226 return mCurrentColor;
227 }
228
setCurrentNormal(const angle::Vector3 & normal)229 void GLES1State::setCurrentNormal(const angle::Vector3 &normal)
230 {
231 setDirty(DIRTY_GLES1_CURRENT_VECTOR);
232 mCurrentNormal = normal;
233 }
234
getCurrentNormal() const235 const angle::Vector3 &GLES1State::getCurrentNormal() const
236 {
237 return mCurrentNormal;
238 }
239
shouldHandleDirtyProgram()240 bool GLES1State::shouldHandleDirtyProgram()
241 {
242 bool ret = isDirty(DIRTY_GLES1_PROGRAM);
243 clearDirtyBits(DIRTY_GLES1_PROGRAM);
244 return ret;
245 }
246
setCurrentTextureCoords(unsigned int unit,const TextureCoordF & coords)247 void GLES1State::setCurrentTextureCoords(unsigned int unit, const TextureCoordF &coords)
248 {
249 setDirty(DIRTY_GLES1_CURRENT_VECTOR);
250 mCurrentTextureCoords[unit] = coords;
251 }
252
getCurrentTextureCoords(unsigned int unit) const253 const TextureCoordF &GLES1State::getCurrentTextureCoords(unsigned int unit) const
254 {
255 return mCurrentTextureCoords[unit];
256 }
257
setMatrixMode(MatrixType mode)258 void GLES1State::setMatrixMode(MatrixType mode)
259 {
260 setDirty(DIRTY_GLES1_MATRICES);
261 mMatrixMode = mode;
262 }
263
getMatrixMode() const264 MatrixType GLES1State::getMatrixMode() const
265 {
266 return mMatrixMode;
267 }
268
getCurrentMatrixStackDepth(GLenum queryType) const269 GLint GLES1State::getCurrentMatrixStackDepth(GLenum queryType) const
270 {
271 switch (queryType)
272 {
273 case GL_MODELVIEW_STACK_DEPTH:
274 return clampCast<GLint>(mModelviewMatrices.size());
275 case GL_PROJECTION_STACK_DEPTH:
276 return clampCast<GLint>(mProjectionMatrices.size());
277 case GL_TEXTURE_STACK_DEPTH:
278 return clampCast<GLint>(mTextureMatrices[mGLState->getActiveSampler()].size());
279 default:
280 UNREACHABLE();
281 return 0;
282 }
283 }
284
pushMatrix()285 void GLES1State::pushMatrix()
286 {
287 setDirty(DIRTY_GLES1_MATRICES);
288 auto &stack = currentMatrixStack();
289 stack.push_back(stack.back());
290 }
291
popMatrix()292 void GLES1State::popMatrix()
293 {
294 setDirty(DIRTY_GLES1_MATRICES);
295 auto &stack = currentMatrixStack();
296 stack.pop_back();
297 }
298
currentMatrixStack()299 GLES1State::MatrixStack &GLES1State::currentMatrixStack()
300 {
301 setDirty(DIRTY_GLES1_MATRICES);
302 switch (mMatrixMode)
303 {
304 case MatrixType::Modelview:
305 return mModelviewMatrices;
306 case MatrixType::Projection:
307 return mProjectionMatrices;
308 case MatrixType::Texture:
309 return mTextureMatrices[mGLState->getActiveSampler()];
310 default:
311 UNREACHABLE();
312 return mModelviewMatrices;
313 }
314 }
315
getModelviewMatrix() const316 const angle::Mat4 &GLES1State::getModelviewMatrix() const
317 {
318 return mModelviewMatrices.back();
319 }
320
getMatrixStack(MatrixType mode) const321 const GLES1State::MatrixStack &GLES1State::getMatrixStack(MatrixType mode) const
322 {
323 switch (mode)
324 {
325 case MatrixType::Modelview:
326 return mModelviewMatrices;
327 case MatrixType::Projection:
328 return mProjectionMatrices;
329 case MatrixType::Texture:
330 return mTextureMatrices[mGLState->getActiveSampler()];
331 default:
332 UNREACHABLE();
333 return mModelviewMatrices;
334 }
335 }
336
currentMatrixStack() const337 const GLES1State::MatrixStack &GLES1State::currentMatrixStack() const
338 {
339 return getMatrixStack(mMatrixMode);
340 }
341
loadMatrix(const angle::Mat4 & m)342 void GLES1State::loadMatrix(const angle::Mat4 &m)
343 {
344 setDirty(DIRTY_GLES1_MATRICES);
345 currentMatrixStack().back() = m;
346 }
347
multMatrix(const angle::Mat4 & m)348 void GLES1State::multMatrix(const angle::Mat4 &m)
349 {
350 setDirty(DIRTY_GLES1_MATRICES);
351 angle::Mat4 currentMatrix = currentMatrixStack().back();
352 currentMatrixStack().back() = currentMatrix.product(m);
353 }
354
setLogicOpEnabled(bool enabled)355 void GLES1State::setLogicOpEnabled(bool enabled)
356 {
357 setDirty(DIRTY_GLES1_LOGIC_OP);
358 mLogicOpEnabled = enabled;
359 }
360
setLogicOp(LogicalOperation opcodePacked)361 void GLES1State::setLogicOp(LogicalOperation opcodePacked)
362 {
363 setDirty(DIRTY_GLES1_LOGIC_OP);
364 mLogicOp = opcodePacked;
365 }
366
setClientStateEnabled(ClientVertexArrayType clientState,bool enable)367 void GLES1State::setClientStateEnabled(ClientVertexArrayType clientState, bool enable)
368 {
369 setDirty(DIRTY_GLES1_CLIENT_STATE_ENABLE);
370 switch (clientState)
371 {
372 case ClientVertexArrayType::Vertex:
373 mVertexArrayEnabled = enable;
374 break;
375 case ClientVertexArrayType::Normal:
376 mNormalArrayEnabled = enable;
377 break;
378 case ClientVertexArrayType::Color:
379 mColorArrayEnabled = enable;
380 break;
381 case ClientVertexArrayType::PointSize:
382 mPointSizeArrayEnabled = enable;
383 break;
384 case ClientVertexArrayType::TextureCoord:
385 mTexCoordArrayEnabled[mClientActiveTexture] = enable;
386 break;
387 default:
388 UNREACHABLE();
389 break;
390 }
391 }
392
setTexCoordArrayEnabled(unsigned int unit,bool enable)393 void GLES1State::setTexCoordArrayEnabled(unsigned int unit, bool enable)
394 {
395 setDirty(DIRTY_GLES1_CLIENT_STATE_ENABLE);
396 mTexCoordArrayEnabled[unit] = enable;
397 }
398
isClientStateEnabled(ClientVertexArrayType clientState) const399 bool GLES1State::isClientStateEnabled(ClientVertexArrayType clientState) const
400 {
401 switch (clientState)
402 {
403 case ClientVertexArrayType::Vertex:
404 return mVertexArrayEnabled;
405 case ClientVertexArrayType::Normal:
406 return mNormalArrayEnabled;
407 case ClientVertexArrayType::Color:
408 return mColorArrayEnabled;
409 case ClientVertexArrayType::PointSize:
410 return mPointSizeArrayEnabled;
411 case ClientVertexArrayType::TextureCoord:
412 return mTexCoordArrayEnabled[mClientActiveTexture];
413 default:
414 UNREACHABLE();
415 return false;
416 }
417 }
418
isTexCoordArrayEnabled(unsigned int unit) const419 bool GLES1State::isTexCoordArrayEnabled(unsigned int unit) const
420 {
421 ASSERT(unit < mTexCoordArrayEnabled.size());
422 return mTexCoordArrayEnabled[unit];
423 }
424
isTextureTargetEnabled(unsigned int unit,const TextureType type) const425 bool GLES1State::isTextureTargetEnabled(unsigned int unit, const TextureType type) const
426 {
427 if (mTexUnitEnables.empty())
428 {
429 return false;
430 }
431 return mTexUnitEnables[unit].test(type);
432 }
433
lightModelParameters()434 LightModelParameters &GLES1State::lightModelParameters()
435 {
436 setDirty(DIRTY_GLES1_LIGHTS);
437 return mLightModel;
438 }
439
lightModelParameters() const440 const LightModelParameters &GLES1State::lightModelParameters() const
441 {
442 return mLightModel;
443 }
444
lightParameters(unsigned int light)445 LightParameters &GLES1State::lightParameters(unsigned int light)
446 {
447 setDirty(DIRTY_GLES1_LIGHTS);
448 return mLights[light];
449 }
450
lightParameters(unsigned int light) const451 const LightParameters &GLES1State::lightParameters(unsigned int light) const
452 {
453 return mLights[light];
454 }
455
materialParameters()456 MaterialParameters &GLES1State::materialParameters()
457 {
458 setDirty(DIRTY_GLES1_MATERIAL);
459 return mMaterial;
460 }
461
materialParameters() const462 const MaterialParameters &GLES1State::materialParameters() const
463 {
464 return mMaterial;
465 }
466
isColorMaterialEnabled() const467 bool GLES1State::isColorMaterialEnabled() const
468 {
469 return mColorMaterialEnabled;
470 }
471
setShadeModel(ShadingModel model)472 void GLES1State::setShadeModel(ShadingModel model)
473 {
474 setDirty(DIRTY_GLES1_SHADE_MODEL);
475 mShadeModel = model;
476 }
477
setClipPlane(unsigned int plane,const GLfloat * equation)478 void GLES1State::setClipPlane(unsigned int plane, const GLfloat *equation)
479 {
480 setDirty(DIRTY_GLES1_CLIP_PLANES);
481 assert(plane < mClipPlanes.size());
482 mClipPlanes[plane].equation[0] = equation[0];
483 mClipPlanes[plane].equation[1] = equation[1];
484 mClipPlanes[plane].equation[2] = equation[2];
485 mClipPlanes[plane].equation[3] = equation[3];
486 }
487
getClipPlane(unsigned int plane,GLfloat * equation) const488 void GLES1State::getClipPlane(unsigned int plane, GLfloat *equation) const
489 {
490 assert(plane < mClipPlanes.size());
491 equation[0] = mClipPlanes[plane].equation[0];
492 equation[1] = mClipPlanes[plane].equation[1];
493 equation[2] = mClipPlanes[plane].equation[2];
494 equation[3] = mClipPlanes[plane].equation[3];
495 }
496
fogParameters()497 FogParameters &GLES1State::fogParameters()
498 {
499 setDirty(DIRTY_GLES1_FOG);
500 return mFog;
501 }
502
fogParameters() const503 const FogParameters &GLES1State::fogParameters() const
504 {
505 return mFog;
506 }
507
textureEnvironment(unsigned int unit)508 TextureEnvironmentParameters &GLES1State::textureEnvironment(unsigned int unit)
509 {
510 setDirty(DIRTY_GLES1_TEXTURE_ENVIRONMENT);
511 assert(unit < mTextureEnvironments.size());
512 return mTextureEnvironments[unit];
513 }
514
textureEnvironment(unsigned int unit) const515 const TextureEnvironmentParameters &GLES1State::textureEnvironment(unsigned int unit) const
516 {
517 assert(unit < mTextureEnvironments.size());
518 return mTextureEnvironments[unit];
519 }
520
operator ==(const TextureEnvironmentParameters & a,const TextureEnvironmentParameters & b)521 bool operator==(const TextureEnvironmentParameters &a, const TextureEnvironmentParameters &b)
522 {
523 return a.tie() == b.tie();
524 }
525
operator !=(const TextureEnvironmentParameters & a,const TextureEnvironmentParameters & b)526 bool operator!=(const TextureEnvironmentParameters &a, const TextureEnvironmentParameters &b)
527 {
528 return !(a == b);
529 }
530
pointParameters()531 PointParameters &GLES1State::pointParameters()
532 {
533 setDirty(DIRTY_GLES1_POINT_PARAMETERS);
534 return mPointParameters;
535 }
536
pointParameters() const537 const PointParameters &GLES1State::pointParameters() const
538 {
539 return mPointParameters;
540 }
541
getAlphaTestParameters() const542 const AlphaTestParameters &GLES1State::getAlphaTestParameters() const
543 {
544 return mAlphaTestParameters;
545 }
546
getVertexArraysAttributeMask() const547 AttributesMask GLES1State::getVertexArraysAttributeMask() const
548 {
549 AttributesMask attribsMask;
550
551 ClientVertexArrayType nonTexcoordArrays[] = {
552 ClientVertexArrayType::Vertex,
553 ClientVertexArrayType::Normal,
554 ClientVertexArrayType::Color,
555 ClientVertexArrayType::PointSize,
556 };
557
558 for (const ClientVertexArrayType attrib : nonTexcoordArrays)
559 {
560 attribsMask.set(GLES1Renderer::VertexArrayIndex(attrib, *this),
561 isClientStateEnabled(attrib));
562 }
563
564 for (unsigned int i = 0; i < kTexUnitCount; i++)
565 {
566 attribsMask.set(GLES1Renderer::TexCoordArrayIndex(i), isTexCoordArrayEnabled(i));
567 }
568
569 return attribsMask;
570 }
571
getActiveAttributesMask() const572 AttributesMask GLES1State::getActiveAttributesMask() const
573 {
574 // The program always has 8 attributes enabled.
575 return AttributesMask(0xFF);
576 }
577
setHint(GLenum target,GLenum mode)578 void GLES1State::setHint(GLenum target, GLenum mode)
579 {
580 setDirty(DIRTY_GLES1_HINT_SETTING);
581 HintSetting setting = FromGLenum<HintSetting>(mode);
582 switch (target)
583 {
584 case GL_PERSPECTIVE_CORRECTION_HINT:
585 mPerspectiveCorrectionHint = setting;
586 break;
587 case GL_POINT_SMOOTH_HINT:
588 mPointSmoothHint = setting;
589 break;
590 case GL_LINE_SMOOTH_HINT:
591 mLineSmoothHint = setting;
592 break;
593 case GL_FOG_HINT:
594 mFogHint = setting;
595 break;
596 default:
597 UNREACHABLE();
598 }
599 }
600
getHint(GLenum target) const601 GLenum GLES1State::getHint(GLenum target) const
602 {
603 switch (target)
604 {
605 case GL_PERSPECTIVE_CORRECTION_HINT:
606 return ToGLenum(mPerspectiveCorrectionHint);
607 case GL_POINT_SMOOTH_HINT:
608 return ToGLenum(mPointSmoothHint);
609 case GL_LINE_SMOOTH_HINT:
610 return ToGLenum(mLineSmoothHint);
611 case GL_FOG_HINT:
612 return ToGLenum(mFogHint);
613 default:
614 UNREACHABLE();
615 return 0;
616 }
617 }
618
619 } // namespace gl
620