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