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
setTextureEnabled(GLint activeSampler,TextureType type,bool enabled)355 void GLES1State::setTextureEnabled(GLint activeSampler, TextureType type, bool enabled)
356 {
357 setDirty(DIRTY_GLES1_TEXTURE_UNIT_ENABLE);
358 mTexUnitEnables[activeSampler].set(type, enabled);
359 }
360
setLogicOpEnabled(bool enabled)361 void GLES1State::setLogicOpEnabled(bool enabled)
362 {
363 setDirty(DIRTY_GLES1_LOGIC_OP);
364 mLogicOpEnabled = enabled;
365 }
366
setLogicOp(LogicalOperation opcodePacked)367 void GLES1State::setLogicOp(LogicalOperation opcodePacked)
368 {
369 setDirty(DIRTY_GLES1_LOGIC_OP);
370 mLogicOp = opcodePacked;
371 }
372
setClientStateEnabled(ClientVertexArrayType clientState,bool enable)373 void GLES1State::setClientStateEnabled(ClientVertexArrayType clientState, bool enable)
374 {
375 setDirty(DIRTY_GLES1_CLIENT_STATE_ENABLE);
376 switch (clientState)
377 {
378 case ClientVertexArrayType::Vertex:
379 mVertexArrayEnabled = enable;
380 break;
381 case ClientVertexArrayType::Normal:
382 mNormalArrayEnabled = enable;
383 break;
384 case ClientVertexArrayType::Color:
385 mColorArrayEnabled = enable;
386 break;
387 case ClientVertexArrayType::PointSize:
388 mPointSizeArrayEnabled = enable;
389 break;
390 case ClientVertexArrayType::TextureCoord:
391 mTexCoordArrayEnabled[mClientActiveTexture] = enable;
392 break;
393 default:
394 UNREACHABLE();
395 break;
396 }
397 }
398
setTexCoordArrayEnabled(unsigned int unit,bool enable)399 void GLES1State::setTexCoordArrayEnabled(unsigned int unit, bool enable)
400 {
401 setDirty(DIRTY_GLES1_CLIENT_STATE_ENABLE);
402 mTexCoordArrayEnabled[unit] = enable;
403 }
404
isClientStateEnabled(ClientVertexArrayType clientState) const405 bool GLES1State::isClientStateEnabled(ClientVertexArrayType clientState) const
406 {
407 switch (clientState)
408 {
409 case ClientVertexArrayType::Vertex:
410 return mVertexArrayEnabled;
411 case ClientVertexArrayType::Normal:
412 return mNormalArrayEnabled;
413 case ClientVertexArrayType::Color:
414 return mColorArrayEnabled;
415 case ClientVertexArrayType::PointSize:
416 return mPointSizeArrayEnabled;
417 case ClientVertexArrayType::TextureCoord:
418 return mTexCoordArrayEnabled[mClientActiveTexture];
419 default:
420 UNREACHABLE();
421 return false;
422 }
423 }
424
isTexCoordArrayEnabled(unsigned int unit) const425 bool GLES1State::isTexCoordArrayEnabled(unsigned int unit) const
426 {
427 ASSERT(unit < mTexCoordArrayEnabled.size());
428 return mTexCoordArrayEnabled[unit];
429 }
430
isTextureTargetEnabled(unsigned int unit,const TextureType type) const431 bool GLES1State::isTextureTargetEnabled(unsigned int unit, const TextureType type) const
432 {
433 if (mTexUnitEnables.empty())
434 {
435 return false;
436 }
437 return mTexUnitEnables[unit].test(type);
438 }
439
lightModelParameters()440 LightModelParameters &GLES1State::lightModelParameters()
441 {
442 setDirty(DIRTY_GLES1_LIGHTS);
443 return mLightModel;
444 }
445
lightModelParameters() const446 const LightModelParameters &GLES1State::lightModelParameters() const
447 {
448 return mLightModel;
449 }
450
lightParameters(unsigned int light)451 LightParameters &GLES1State::lightParameters(unsigned int light)
452 {
453 setDirty(DIRTY_GLES1_LIGHTS);
454 return mLights[light];
455 }
456
lightParameters(unsigned int light) const457 const LightParameters &GLES1State::lightParameters(unsigned int light) const
458 {
459 return mLights[light];
460 }
461
materialParameters()462 MaterialParameters &GLES1State::materialParameters()
463 {
464 setDirty(DIRTY_GLES1_MATERIAL);
465 return mMaterial;
466 }
467
materialParameters() const468 const MaterialParameters &GLES1State::materialParameters() const
469 {
470 return mMaterial;
471 }
472
isColorMaterialEnabled() const473 bool GLES1State::isColorMaterialEnabled() const
474 {
475 return mColorMaterialEnabled;
476 }
477
setShadeModel(ShadingModel model)478 void GLES1State::setShadeModel(ShadingModel model)
479 {
480 setDirty(DIRTY_GLES1_SHADE_MODEL);
481 mShadeModel = model;
482 }
483
setClipPlane(unsigned int plane,const GLfloat * equation)484 void GLES1State::setClipPlane(unsigned int plane, const GLfloat *equation)
485 {
486 setDirty(DIRTY_GLES1_CLIP_PLANES);
487 assert(plane < mClipPlanes.size());
488 mClipPlanes[plane].equation[0] = equation[0];
489 mClipPlanes[plane].equation[1] = equation[1];
490 mClipPlanes[plane].equation[2] = equation[2];
491 mClipPlanes[plane].equation[3] = equation[3];
492 }
493
getClipPlane(unsigned int plane,GLfloat * equation) const494 void GLES1State::getClipPlane(unsigned int plane, GLfloat *equation) const
495 {
496 assert(plane < mClipPlanes.size());
497 equation[0] = mClipPlanes[plane].equation[0];
498 equation[1] = mClipPlanes[plane].equation[1];
499 equation[2] = mClipPlanes[plane].equation[2];
500 equation[3] = mClipPlanes[plane].equation[3];
501 }
502
fogParameters()503 FogParameters &GLES1State::fogParameters()
504 {
505 setDirty(DIRTY_GLES1_FOG);
506 return mFog;
507 }
508
fogParameters() const509 const FogParameters &GLES1State::fogParameters() const
510 {
511 return mFog;
512 }
513
textureEnvironment(unsigned int unit)514 TextureEnvironmentParameters &GLES1State::textureEnvironment(unsigned int unit)
515 {
516 setDirty(DIRTY_GLES1_TEXTURE_ENVIRONMENT);
517 assert(unit < mTextureEnvironments.size());
518 return mTextureEnvironments[unit];
519 }
520
textureEnvironment(unsigned int unit) const521 const TextureEnvironmentParameters &GLES1State::textureEnvironment(unsigned int unit) const
522 {
523 assert(unit < mTextureEnvironments.size());
524 return mTextureEnvironments[unit];
525 }
526
operator ==(const TextureEnvironmentParameters & a,const TextureEnvironmentParameters & b)527 bool operator==(const TextureEnvironmentParameters &a, const TextureEnvironmentParameters &b)
528 {
529 return a.tie() == b.tie();
530 }
531
operator !=(const TextureEnvironmentParameters & a,const TextureEnvironmentParameters & b)532 bool operator!=(const TextureEnvironmentParameters &a, const TextureEnvironmentParameters &b)
533 {
534 return !(a == b);
535 }
536
pointParameters()537 PointParameters &GLES1State::pointParameters()
538 {
539 setDirty(DIRTY_GLES1_POINT_PARAMETERS);
540 return mPointParameters;
541 }
542
pointParameters() const543 const PointParameters &GLES1State::pointParameters() const
544 {
545 return mPointParameters;
546 }
547
getAlphaTestParameters() const548 const AlphaTestParameters &GLES1State::getAlphaTestParameters() const
549 {
550 return mAlphaTestParameters;
551 }
552
getVertexArraysAttributeMask() const553 AttributesMask GLES1State::getVertexArraysAttributeMask() const
554 {
555 AttributesMask attribsMask;
556
557 ClientVertexArrayType nonTexcoordArrays[] = {
558 ClientVertexArrayType::Vertex,
559 ClientVertexArrayType::Normal,
560 ClientVertexArrayType::Color,
561 ClientVertexArrayType::PointSize,
562 };
563
564 for (const ClientVertexArrayType attrib : nonTexcoordArrays)
565 {
566 attribsMask.set(GLES1Renderer::VertexArrayIndex(attrib, *this),
567 isClientStateEnabled(attrib));
568 }
569
570 for (unsigned int i = 0; i < kTexUnitCount; i++)
571 {
572 attribsMask.set(GLES1Renderer::TexCoordArrayIndex(i), isTexCoordArrayEnabled(i));
573 }
574
575 return attribsMask;
576 }
577
getActiveAttributesMask() const578 AttributesMask GLES1State::getActiveAttributesMask() const
579 {
580 // The program always has 8 attributes enabled.
581 return AttributesMask(0xFF);
582 }
583
setHint(GLenum target,GLenum mode)584 void GLES1State::setHint(GLenum target, GLenum mode)
585 {
586 setDirty(DIRTY_GLES1_HINT_SETTING);
587 HintSetting setting = FromGLenum<HintSetting>(mode);
588 switch (target)
589 {
590 case GL_PERSPECTIVE_CORRECTION_HINT:
591 mPerspectiveCorrectionHint = setting;
592 break;
593 case GL_POINT_SMOOTH_HINT:
594 mPointSmoothHint = setting;
595 break;
596 case GL_LINE_SMOOTH_HINT:
597 mLineSmoothHint = setting;
598 break;
599 case GL_FOG_HINT:
600 mFogHint = setting;
601 break;
602 default:
603 UNREACHABLE();
604 }
605 }
606
getHint(GLenum target) const607 GLenum GLES1State::getHint(GLenum target) const
608 {
609 switch (target)
610 {
611 case GL_PERSPECTIVE_CORRECTION_HINT:
612 return ToGLenum(mPerspectiveCorrectionHint);
613 case GL_POINT_SMOOTH_HINT:
614 return ToGLenum(mPointSmoothHint);
615 case GL_LINE_SMOOTH_HINT:
616 return ToGLenum(mLineSmoothHint);
617 case GL_FOG_HINT:
618 return ToGLenum(mFogHint);
619 default:
620 UNREACHABLE();
621 return 0;
622 }
623 }
624
625 } // namespace gl
626