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