GLES1State.cpp (16901B)
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 20 TextureCoordF::TextureCoordF(float _s, float _t, float _r, float _q) : s(_s), t(_t), r(_r), q(_q) {} 21 22 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 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 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. 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 182 void GLES1State::setAlphaFunc(AlphaTestFunc func, GLfloat ref) 183 { 184 setDirty(DIRTY_GLES1_ALPHA_TEST); 185 mAlphaTestFunc = func; 186 mAlphaTestRef = ref; 187 } 188 189 void GLES1State::setClientTextureUnit(unsigned int unit) 190 { 191 setDirty(DIRTY_GLES1_CLIENT_ACTIVE_TEXTURE); 192 mClientActiveTexture = unit; 193 } 194 195 unsigned int GLES1State::getClientTextureUnit() const 196 { 197 return mClientActiveTexture; 198 } 199 200 void GLES1State::setCurrentColor(const ColorF &color) 201 { 202 setDirty(DIRTY_GLES1_CURRENT_VECTOR); 203 mCurrentColor = color; 204 205 // > When enabled, both the ambient (acm) and diffuse (dcm) properties of both the front and 206 // > back material are immediately set to the value of the current color, and will track changes 207 // > to the current color resulting from either the Color commands or drawing vertex arrays with 208 // > the color array enabled. 209 // > The replacements made to material properties are permanent; the replaced values remain 210 // > until changed by either sending a new color or by setting a new material value when 211 // > COLOR_MATERIAL is not currently enabled, to override that particular value. 212 if (isColorMaterialEnabled()) 213 { 214 mMaterial.ambient = color; 215 mMaterial.diffuse = color; 216 } 217 } 218 219 const ColorF &GLES1State::getCurrentColor() const 220 { 221 return mCurrentColor; 222 } 223 224 void GLES1State::setCurrentNormal(const angle::Vector3 &normal) 225 { 226 setDirty(DIRTY_GLES1_CURRENT_VECTOR); 227 mCurrentNormal = normal; 228 } 229 230 const angle::Vector3 &GLES1State::getCurrentNormal() const 231 { 232 return mCurrentNormal; 233 } 234 235 bool GLES1State::shouldHandleDirtyProgram() 236 { 237 bool ret = isDirty(DIRTY_GLES1_PROGRAM); 238 clearDirtyBits(DIRTY_GLES1_PROGRAM); 239 return ret; 240 } 241 242 void GLES1State::setCurrentTextureCoords(unsigned int unit, const TextureCoordF &coords) 243 { 244 setDirty(DIRTY_GLES1_CURRENT_VECTOR); 245 mCurrentTextureCoords[unit] = coords; 246 } 247 248 const TextureCoordF &GLES1State::getCurrentTextureCoords(unsigned int unit) const 249 { 250 return mCurrentTextureCoords[unit]; 251 } 252 253 void GLES1State::setMatrixMode(MatrixType mode) 254 { 255 setDirty(DIRTY_GLES1_MATRICES); 256 mMatrixMode = mode; 257 } 258 259 MatrixType GLES1State::getMatrixMode() const 260 { 261 return mMatrixMode; 262 } 263 264 GLint GLES1State::getCurrentMatrixStackDepth(GLenum queryType) const 265 { 266 switch (queryType) 267 { 268 case GL_MODELVIEW_STACK_DEPTH: 269 return clampCast<GLint>(mModelviewMatrices.size()); 270 case GL_PROJECTION_STACK_DEPTH: 271 return clampCast<GLint>(mProjectionMatrices.size()); 272 case GL_TEXTURE_STACK_DEPTH: 273 return clampCast<GLint>(mTextureMatrices[mGLState->getActiveSampler()].size()); 274 default: 275 UNREACHABLE(); 276 return 0; 277 } 278 } 279 280 void GLES1State::pushMatrix() 281 { 282 setDirty(DIRTY_GLES1_MATRICES); 283 auto &stack = currentMatrixStack(); 284 stack.push_back(stack.back()); 285 } 286 287 void GLES1State::popMatrix() 288 { 289 setDirty(DIRTY_GLES1_MATRICES); 290 auto &stack = currentMatrixStack(); 291 stack.pop_back(); 292 } 293 294 GLES1State::MatrixStack &GLES1State::currentMatrixStack() 295 { 296 setDirty(DIRTY_GLES1_MATRICES); 297 switch (mMatrixMode) 298 { 299 case MatrixType::Modelview: 300 return mModelviewMatrices; 301 case MatrixType::Projection: 302 return mProjectionMatrices; 303 case MatrixType::Texture: 304 return mTextureMatrices[mGLState->getActiveSampler()]; 305 default: 306 UNREACHABLE(); 307 return mModelviewMatrices; 308 } 309 } 310 311 const angle::Mat4 &GLES1State::getModelviewMatrix() const 312 { 313 return mModelviewMatrices.back(); 314 } 315 316 const GLES1State::MatrixStack &GLES1State::getMatrixStack(MatrixType mode) const 317 { 318 switch (mode) 319 { 320 case MatrixType::Modelview: 321 return mModelviewMatrices; 322 case MatrixType::Projection: 323 return mProjectionMatrices; 324 case MatrixType::Texture: 325 return mTextureMatrices[mGLState->getActiveSampler()]; 326 default: 327 UNREACHABLE(); 328 return mModelviewMatrices; 329 } 330 } 331 332 const GLES1State::MatrixStack &GLES1State::currentMatrixStack() const 333 { 334 return getMatrixStack(mMatrixMode); 335 } 336 337 void GLES1State::loadMatrix(const angle::Mat4 &m) 338 { 339 setDirty(DIRTY_GLES1_MATRICES); 340 currentMatrixStack().back() = m; 341 } 342 343 void GLES1State::multMatrix(const angle::Mat4 &m) 344 { 345 setDirty(DIRTY_GLES1_MATRICES); 346 angle::Mat4 currentMatrix = currentMatrixStack().back(); 347 currentMatrixStack().back() = currentMatrix.product(m); 348 } 349 350 void GLES1State::setLogicOpEnabled(bool enabled) 351 { 352 setDirty(DIRTY_GLES1_LOGIC_OP); 353 mLogicOpEnabled = enabled; 354 } 355 356 void GLES1State::setLogicOp(LogicalOperation opcodePacked) 357 { 358 setDirty(DIRTY_GLES1_LOGIC_OP); 359 mLogicOp = opcodePacked; 360 } 361 362 void GLES1State::setClientStateEnabled(ClientVertexArrayType clientState, bool enable) 363 { 364 setDirty(DIRTY_GLES1_CLIENT_STATE_ENABLE); 365 switch (clientState) 366 { 367 case ClientVertexArrayType::Vertex: 368 mVertexArrayEnabled = enable; 369 break; 370 case ClientVertexArrayType::Normal: 371 mNormalArrayEnabled = enable; 372 break; 373 case ClientVertexArrayType::Color: 374 mColorArrayEnabled = enable; 375 break; 376 case ClientVertexArrayType::PointSize: 377 mPointSizeArrayEnabled = enable; 378 break; 379 case ClientVertexArrayType::TextureCoord: 380 mTexCoordArrayEnabled[mClientActiveTexture] = enable; 381 break; 382 default: 383 UNREACHABLE(); 384 break; 385 } 386 } 387 388 void GLES1State::setTexCoordArrayEnabled(unsigned int unit, bool enable) 389 { 390 setDirty(DIRTY_GLES1_CLIENT_STATE_ENABLE); 391 mTexCoordArrayEnabled[unit] = enable; 392 } 393 394 bool GLES1State::isClientStateEnabled(ClientVertexArrayType clientState) const 395 { 396 switch (clientState) 397 { 398 case ClientVertexArrayType::Vertex: 399 return mVertexArrayEnabled; 400 case ClientVertexArrayType::Normal: 401 return mNormalArrayEnabled; 402 case ClientVertexArrayType::Color: 403 return mColorArrayEnabled; 404 case ClientVertexArrayType::PointSize: 405 return mPointSizeArrayEnabled; 406 case ClientVertexArrayType::TextureCoord: 407 return mTexCoordArrayEnabled[mClientActiveTexture]; 408 default: 409 UNREACHABLE(); 410 return false; 411 } 412 } 413 414 bool GLES1State::isTexCoordArrayEnabled(unsigned int unit) const 415 { 416 ASSERT(unit < mTexCoordArrayEnabled.size()); 417 return mTexCoordArrayEnabled[unit]; 418 } 419 420 bool GLES1State::isTextureTargetEnabled(unsigned int unit, const TextureType type) const 421 { 422 if (mTexUnitEnables.empty()) 423 { 424 return false; 425 } 426 return mTexUnitEnables[unit].test(type); 427 } 428 429 LightModelParameters &GLES1State::lightModelParameters() 430 { 431 setDirty(DIRTY_GLES1_LIGHTS); 432 return mLightModel; 433 } 434 435 const LightModelParameters &GLES1State::lightModelParameters() const 436 { 437 return mLightModel; 438 } 439 440 LightParameters &GLES1State::lightParameters(unsigned int light) 441 { 442 setDirty(DIRTY_GLES1_LIGHTS); 443 return mLights[light]; 444 } 445 446 const LightParameters &GLES1State::lightParameters(unsigned int light) const 447 { 448 return mLights[light]; 449 } 450 451 MaterialParameters &GLES1State::materialParameters() 452 { 453 setDirty(DIRTY_GLES1_MATERIAL); 454 return mMaterial; 455 } 456 457 const MaterialParameters &GLES1State::materialParameters() const 458 { 459 return mMaterial; 460 } 461 462 bool GLES1State::isColorMaterialEnabled() const 463 { 464 return mColorMaterialEnabled; 465 } 466 467 void GLES1State::setShadeModel(ShadingModel model) 468 { 469 setDirty(DIRTY_GLES1_SHADE_MODEL); 470 mShadeModel = model; 471 } 472 473 void GLES1State::setClipPlane(unsigned int plane, const GLfloat *equation) 474 { 475 setDirty(DIRTY_GLES1_CLIP_PLANES); 476 assert(plane < mClipPlanes.size()); 477 mClipPlanes[plane].equation[0] = equation[0]; 478 mClipPlanes[plane].equation[1] = equation[1]; 479 mClipPlanes[plane].equation[2] = equation[2]; 480 mClipPlanes[plane].equation[3] = equation[3]; 481 } 482 483 void GLES1State::getClipPlane(unsigned int plane, GLfloat *equation) const 484 { 485 assert(plane < mClipPlanes.size()); 486 equation[0] = mClipPlanes[plane].equation[0]; 487 equation[1] = mClipPlanes[plane].equation[1]; 488 equation[2] = mClipPlanes[plane].equation[2]; 489 equation[3] = mClipPlanes[plane].equation[3]; 490 } 491 492 FogParameters &GLES1State::fogParameters() 493 { 494 setDirty(DIRTY_GLES1_FOG); 495 return mFog; 496 } 497 498 const FogParameters &GLES1State::fogParameters() const 499 { 500 return mFog; 501 } 502 503 TextureEnvironmentParameters &GLES1State::textureEnvironment(unsigned int unit) 504 { 505 setDirty(DIRTY_GLES1_TEXTURE_ENVIRONMENT); 506 assert(unit < mTextureEnvironments.size()); 507 return mTextureEnvironments[unit]; 508 } 509 510 const TextureEnvironmentParameters &GLES1State::textureEnvironment(unsigned int unit) const 511 { 512 assert(unit < mTextureEnvironments.size()); 513 return mTextureEnvironments[unit]; 514 } 515 516 bool operator==(const TextureEnvironmentParameters &a, const TextureEnvironmentParameters &b) 517 { 518 return a.tie() == b.tie(); 519 } 520 521 bool operator!=(const TextureEnvironmentParameters &a, const TextureEnvironmentParameters &b) 522 { 523 return !(a == b); 524 } 525 526 PointParameters &GLES1State::pointParameters() 527 { 528 setDirty(DIRTY_GLES1_POINT_PARAMETERS); 529 return mPointParameters; 530 } 531 532 const PointParameters &GLES1State::pointParameters() const 533 { 534 return mPointParameters; 535 } 536 537 AttributesMask GLES1State::getVertexArraysAttributeMask() const 538 { 539 AttributesMask attribsMask; 540 541 ClientVertexArrayType nonTexcoordArrays[] = { 542 ClientVertexArrayType::Vertex, 543 ClientVertexArrayType::Normal, 544 ClientVertexArrayType::Color, 545 ClientVertexArrayType::PointSize, 546 }; 547 548 for (const ClientVertexArrayType attrib : nonTexcoordArrays) 549 { 550 attribsMask.set(GLES1Renderer::VertexArrayIndex(attrib, *this), 551 isClientStateEnabled(attrib)); 552 } 553 554 for (unsigned int i = 0; i < kTexUnitCount; i++) 555 { 556 attribsMask.set(GLES1Renderer::TexCoordArrayIndex(i), isTexCoordArrayEnabled(i)); 557 } 558 559 return attribsMask; 560 } 561 562 AttributesMask GLES1State::getActiveAttributesMask() const 563 { 564 // The program always has 8 attributes enabled. 565 return AttributesMask(0xFF); 566 } 567 568 void GLES1State::setHint(GLenum target, GLenum mode) 569 { 570 setDirty(DIRTY_GLES1_HINT_SETTING); 571 HintSetting setting = FromGLenum<HintSetting>(mode); 572 switch (target) 573 { 574 case GL_PERSPECTIVE_CORRECTION_HINT: 575 mPerspectiveCorrectionHint = setting; 576 break; 577 case GL_POINT_SMOOTH_HINT: 578 mPointSmoothHint = setting; 579 break; 580 case GL_LINE_SMOOTH_HINT: 581 mLineSmoothHint = setting; 582 break; 583 case GL_FOG_HINT: 584 mFogHint = setting; 585 break; 586 default: 587 UNREACHABLE(); 588 } 589 } 590 591 GLenum GLES1State::getHint(GLenum target) const 592 { 593 switch (target) 594 { 595 case GL_PERSPECTIVE_CORRECTION_HINT: 596 return ToGLenum(mPerspectiveCorrectionHint); 597 case GL_POINT_SMOOTH_HINT: 598 return ToGLenum(mPointSmoothHint); 599 case GL_LINE_SMOOTH_HINT: 600 return ToGLenum(mLineSmoothHint); 601 case GL_FOG_HINT: 602 return ToGLenum(mFogHint); 603 default: 604 UNREACHABLE(); 605 return 0; 606 } 607 } 608 609 } // namespace gl