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
currentMatrixStack() const303 const GLES1State::MatrixStack &GLES1State::currentMatrixStack() const
304 {
305 switch (mMatrixMode)
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
loadMatrix(const angle::Mat4 & m)319 void GLES1State::loadMatrix(const angle::Mat4 &m)
320 {
321 setDirty(DIRTY_GLES1_MATRICES);
322 currentMatrixStack().back() = m;
323 }
324
multMatrix(const angle::Mat4 & m)325 void GLES1State::multMatrix(const angle::Mat4 &m)
326 {
327 setDirty(DIRTY_GLES1_MATRICES);
328 angle::Mat4 currentMatrix = currentMatrixStack().back();
329 currentMatrixStack().back() = currentMatrix.product(m);
330 }
331
setLogicOp(LogicalOperation opcodePacked)332 void GLES1State::setLogicOp(LogicalOperation opcodePacked)
333 {
334 setDirty(DIRTY_GLES1_LOGIC_OP);
335 mLogicOp = opcodePacked;
336 }
337
setClientStateEnabled(ClientVertexArrayType clientState,bool enable)338 void GLES1State::setClientStateEnabled(ClientVertexArrayType clientState, bool enable)
339 {
340 setDirty(DIRTY_GLES1_CLIENT_STATE_ENABLE);
341 switch (clientState)
342 {
343 case ClientVertexArrayType::Vertex:
344 mVertexArrayEnabled = enable;
345 break;
346 case ClientVertexArrayType::Normal:
347 mNormalArrayEnabled = enable;
348 break;
349 case ClientVertexArrayType::Color:
350 mColorArrayEnabled = enable;
351 break;
352 case ClientVertexArrayType::PointSize:
353 mPointSizeArrayEnabled = enable;
354 break;
355 case ClientVertexArrayType::TextureCoord:
356 mTexCoordArrayEnabled[mClientActiveTexture] = enable;
357 break;
358 default:
359 UNREACHABLE();
360 break;
361 }
362 }
363
setTexCoordArrayEnabled(unsigned int unit,bool enable)364 void GLES1State::setTexCoordArrayEnabled(unsigned int unit, bool enable)
365 {
366 setDirty(DIRTY_GLES1_CLIENT_STATE_ENABLE);
367 mTexCoordArrayEnabled[unit] = enable;
368 }
369
isClientStateEnabled(ClientVertexArrayType clientState) const370 bool GLES1State::isClientStateEnabled(ClientVertexArrayType clientState) const
371 {
372 switch (clientState)
373 {
374 case ClientVertexArrayType::Vertex:
375 return mVertexArrayEnabled;
376 case ClientVertexArrayType::Normal:
377 return mNormalArrayEnabled;
378 case ClientVertexArrayType::Color:
379 return mColorArrayEnabled;
380 case ClientVertexArrayType::PointSize:
381 return mPointSizeArrayEnabled;
382 case ClientVertexArrayType::TextureCoord:
383 return mTexCoordArrayEnabled[mClientActiveTexture];
384 default:
385 UNREACHABLE();
386 return false;
387 }
388 }
389
isTexCoordArrayEnabled(unsigned int unit) const390 bool GLES1State::isTexCoordArrayEnabled(unsigned int unit) const
391 {
392 ASSERT(unit < mTexCoordArrayEnabled.size());
393 return mTexCoordArrayEnabled[unit];
394 }
395
isTextureTargetEnabled(unsigned int unit,const TextureType type) const396 bool GLES1State::isTextureTargetEnabled(unsigned int unit, const TextureType type) const
397 {
398 if (mTexUnitEnables.empty())
399 {
400 return false;
401 }
402 return mTexUnitEnables[unit].test(type);
403 }
404
lightModelParameters()405 LightModelParameters &GLES1State::lightModelParameters()
406 {
407 setDirty(DIRTY_GLES1_LIGHTS);
408 return mLightModel;
409 }
410
lightModelParameters() const411 const LightModelParameters &GLES1State::lightModelParameters() const
412 {
413 return mLightModel;
414 }
415
lightParameters(unsigned int light)416 LightParameters &GLES1State::lightParameters(unsigned int light)
417 {
418 setDirty(DIRTY_GLES1_LIGHTS);
419 return mLights[light];
420 }
421
lightParameters(unsigned int light) const422 const LightParameters &GLES1State::lightParameters(unsigned int light) const
423 {
424 return mLights[light];
425 }
426
materialParameters()427 MaterialParameters &GLES1State::materialParameters()
428 {
429 setDirty(DIRTY_GLES1_MATERIAL);
430 return mMaterial;
431 }
432
materialParameters() const433 const MaterialParameters &GLES1State::materialParameters() const
434 {
435 return mMaterial;
436 }
437
isColorMaterialEnabled() const438 bool GLES1State::isColorMaterialEnabled() const
439 {
440 return mColorMaterialEnabled;
441 }
442
setShadeModel(ShadingModel model)443 void GLES1State::setShadeModel(ShadingModel model)
444 {
445 setDirty(DIRTY_GLES1_SHADE_MODEL);
446 mShadeModel = model;
447 }
448
setClipPlane(unsigned int plane,const GLfloat * equation)449 void GLES1State::setClipPlane(unsigned int plane, const GLfloat *equation)
450 {
451 setDirty(DIRTY_GLES1_CLIP_PLANES);
452 assert(plane < mClipPlanes.size());
453 mClipPlanes[plane].equation[0] = equation[0];
454 mClipPlanes[plane].equation[1] = equation[1];
455 mClipPlanes[plane].equation[2] = equation[2];
456 mClipPlanes[plane].equation[3] = equation[3];
457 }
458
getClipPlane(unsigned int plane,GLfloat * equation) const459 void GLES1State::getClipPlane(unsigned int plane, GLfloat *equation) const
460 {
461 assert(plane < mClipPlanes.size());
462 equation[0] = mClipPlanes[plane].equation[0];
463 equation[1] = mClipPlanes[plane].equation[1];
464 equation[2] = mClipPlanes[plane].equation[2];
465 equation[3] = mClipPlanes[plane].equation[3];
466 }
467
fogParameters()468 FogParameters &GLES1State::fogParameters()
469 {
470 setDirty(DIRTY_GLES1_FOG);
471 return mFog;
472 }
473
fogParameters() const474 const FogParameters &GLES1State::fogParameters() const
475 {
476 return mFog;
477 }
478
textureEnvironment(unsigned int unit)479 TextureEnvironmentParameters &GLES1State::textureEnvironment(unsigned int unit)
480 {
481 setDirty(DIRTY_GLES1_TEXTURE_ENVIRONMENT);
482 assert(unit < mTextureEnvironments.size());
483 return mTextureEnvironments[unit];
484 }
485
textureEnvironment(unsigned int unit) const486 const TextureEnvironmentParameters &GLES1State::textureEnvironment(unsigned int unit) const
487 {
488 assert(unit < mTextureEnvironments.size());
489 return mTextureEnvironments[unit];
490 }
491
pointParameters()492 PointParameters &GLES1State::pointParameters()
493 {
494 setDirty(DIRTY_GLES1_POINT_PARAMETERS);
495 return mPointParameters;
496 }
497
pointParameters() const498 const PointParameters &GLES1State::pointParameters() const
499 {
500 return mPointParameters;
501 }
502
getVertexArraysAttributeMask() const503 AttributesMask GLES1State::getVertexArraysAttributeMask() const
504 {
505 AttributesMask attribsMask;
506
507 ClientVertexArrayType nonTexcoordArrays[] = {
508 ClientVertexArrayType::Vertex,
509 ClientVertexArrayType::Normal,
510 ClientVertexArrayType::Color,
511 ClientVertexArrayType::PointSize,
512 };
513
514 for (const ClientVertexArrayType attrib : nonTexcoordArrays)
515 {
516 attribsMask.set(GLES1Renderer::VertexArrayIndex(attrib, *this),
517 isClientStateEnabled(attrib));
518 }
519
520 for (unsigned int i = 0; i < GLES1Renderer::kTexUnitCount; i++)
521 {
522 attribsMask.set(GLES1Renderer::TexCoordArrayIndex(i), isTexCoordArrayEnabled(i));
523 }
524
525 return attribsMask;
526 }
527
getActiveAttributesMask() const528 AttributesMask GLES1State::getActiveAttributesMask() const
529 {
530 // The program always has 8 attributes enabled.
531 return AttributesMask(0xFF);
532 }
533
setHint(GLenum target,GLenum mode)534 void GLES1State::setHint(GLenum target, GLenum mode)
535 {
536 setDirty(DIRTY_GLES1_HINT_SETTING);
537 HintSetting setting = FromGLenum<HintSetting>(mode);
538 switch (target)
539 {
540 case GL_PERSPECTIVE_CORRECTION_HINT:
541 mPerspectiveCorrectionHint = setting;
542 break;
543 case GL_POINT_SMOOTH_HINT:
544 mPointSmoothHint = setting;
545 break;
546 case GL_LINE_SMOOTH_HINT:
547 mLineSmoothHint = setting;
548 break;
549 case GL_FOG_HINT:
550 mFogHint = setting;
551 break;
552 default:
553 UNREACHABLE();
554 }
555 }
556
getHint(GLenum target) const557 GLenum GLES1State::getHint(GLenum target) const
558 {
559 switch (target)
560 {
561 case GL_PERSPECTIVE_CORRECTION_HINT:
562 return ToGLenum(mPerspectiveCorrectionHint);
563 case GL_POINT_SMOOTH_HINT:
564 return ToGLenum(mPointSmoothHint);
565 case GL_LINE_SMOOTH_HINT:
566 return ToGLenum(mLineSmoothHint);
567 case GL_FOG_HINT:
568 return ToGLenum(mFogHint);
569 default:
570 UNREACHABLE();
571 return 0;
572 }
573 }
574
575 } // namespace gl
576