GLES1Renderer.cpp (48920B)
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 // GLES1Renderer.cpp: Implements the GLES1Renderer renderer. 8 9 #include "libANGLE/GLES1Renderer.h" 10 11 #include <string.h> 12 #include <iterator> 13 #include <sstream> 14 #include <vector> 15 16 #include "common/hash_utils.h" 17 #include "libANGLE/Context.h" 18 #include "libANGLE/Context.inl.h" 19 #include "libANGLE/Program.h" 20 #include "libANGLE/ResourceManager.h" 21 #include "libANGLE/Shader.h" 22 #include "libANGLE/State.h" 23 #include "libANGLE/renderer/ContextImpl.h" 24 25 namespace 26 { 27 #include "libANGLE/GLES1Shaders.inc" 28 29 uint32_t GetLogicOpUniform(const gl::FramebufferAttachment *color, gl::LogicalOperation logicOp) 30 { 31 const uint32_t red = color->getRedSize(); 32 const uint32_t green = color->getGreenSize(); 33 const uint32_t blue = color->getBlueSize(); 34 const uint32_t alpha = color->getAlphaSize(); 35 36 ASSERT(red <= 8 && green <= 8 && blue <= 8 && alpha <= 8); 37 38 return red | green << 4 | blue << 8 | alpha << 12 | static_cast<uint32_t>(logicOp) << 16; 39 } 40 } // anonymous namespace 41 42 namespace gl 43 { 44 GLES1ShaderState::GLES1ShaderState() = default; 45 GLES1ShaderState::~GLES1ShaderState() = default; 46 GLES1ShaderState::GLES1ShaderState(const GLES1ShaderState &other) 47 { 48 memcpy(this, &other, sizeof(GLES1ShaderState)); 49 } 50 51 bool operator==(const GLES1ShaderState &a, const GLES1ShaderState &b) 52 { 53 return memcmp(&a, &b, sizeof(GLES1ShaderState)) == 0; 54 } 55 bool operator!=(const GLES1ShaderState &a, const GLES1ShaderState &b) 56 { 57 return !(a == b); 58 } 59 60 size_t GLES1ShaderState::hash() const 61 { 62 return angle::ComputeGenericHash(*this); 63 } 64 65 GLES1Renderer::GLES1Renderer() : mRendererProgramInitialized(false) {} 66 67 void GLES1Renderer::onDestroy(Context *context, State *state) 68 { 69 if (mRendererProgramInitialized) 70 { 71 (void)state->setProgram(context, 0); 72 73 for (const auto &iter : mUberShaderState) 74 { 75 const GLES1UberShaderState &UberShaderState = iter.second; 76 mShaderPrograms->deleteProgram(context, {UberShaderState.programState.program}); 77 } 78 mShaderPrograms->release(context); 79 mShaderPrograms = nullptr; 80 mRendererProgramInitialized = false; 81 } 82 } 83 84 GLES1Renderer::~GLES1Renderer() = default; 85 86 angle::Result GLES1Renderer::prepareForDraw(PrimitiveMode mode, Context *context, State *glState) 87 { 88 GLES1State &gles1State = glState->gles1(); 89 90 GLES1ShaderState::BoolTexArray &tex2DEnables = mShaderState.tex2DEnables; 91 GLES1ShaderState::BoolTexArray &texCubeEnables = mShaderState.texCubeEnables; 92 GLES1ShaderState::IntTexArray &tex2DFormats = mShaderState.tex2DFormats; 93 94 for (int i = 0; i < kTexUnitCount; i++) 95 { 96 // GL_OES_cube_map allows only one of TEXTURE_2D / TEXTURE_CUBE_MAP 97 // to be enabled per unit, thankfully. From the extension text: 98 // 99 // -- Section 3.8.10 "Texture Application" 100 // 101 // Replace the beginning sentences of the first paragraph (page 138) 102 // with: 103 // 104 // "Texturing is enabled or disabled using the generic Enable 105 // and Disable commands, respectively, with the symbolic constants 106 // TEXTURE_2D or TEXTURE_CUBE_MAP_OES to enable the two-dimensional or cube 107 // map texturing respectively. If the cube map texture and the two- 108 // dimensional texture are enabled, then cube map texturing is used. If 109 // texturing is disabled, a rasterized fragment is passed on unaltered to the 110 // next stage of the GL (although its texture coordinates may be discarded). 111 // Otherwise, a texture value is found according to the parameter values of 112 // the currently bound texture image of the appropriate dimensionality. 113 114 texCubeEnables[i] = gles1State.isTextureTargetEnabled(i, TextureType::CubeMap); 115 tex2DEnables[i] = 116 !texCubeEnables[i] && gles1State.isTextureTargetEnabled(i, TextureType::_2D); 117 118 Texture *curr2DTexture = glState->getSamplerTexture(i, TextureType::_2D); 119 if (curr2DTexture) 120 { 121 tex2DFormats[i] = gl::GetUnsizedFormat( 122 curr2DTexture->getFormat(TextureTarget::_2D, 0).info->internalFormat); 123 } 124 125 Texture *currCubeTexture = glState->getSamplerTexture(i, TextureType::CubeMap); 126 127 // > If texturing is enabled for a texture unit at the time a primitive is rasterized, if 128 // > TEXTURE MIN FILTER is one that requires a mipmap, and if the texture image bound to the 129 // > enabled texture target is not complete, then it is as if texture mapping were disabled 130 // > for that texture unit. 131 if (tex2DEnables[i] && curr2DTexture && IsMipmapFiltered(curr2DTexture->getMinFilter())) 132 { 133 tex2DEnables[i] = curr2DTexture->isMipmapComplete(); 134 } 135 if (texCubeEnables[i] && currCubeTexture && 136 IsMipmapFiltered(currCubeTexture->getMinFilter())) 137 { 138 texCubeEnables[i] = curr2DTexture->isMipmapComplete(); 139 } 140 } 141 142 GLES1ShaderState::IntTexArray &texEnvModes = mShaderState.texEnvModes; 143 GLES1ShaderState::IntTexArray &texCombineRgbs = mShaderState.texCombineRgbs; 144 GLES1ShaderState::IntTexArray &texCombineAlphas = mShaderState.texCombineAlphas; 145 GLES1ShaderState::IntTexArray &texCombineSrc0Rgbs = mShaderState.texCombineSrc0Rgbs; 146 GLES1ShaderState::IntTexArray &texCombineSrc0Alphas = mShaderState.texCombineSrc0Alphas; 147 GLES1ShaderState::IntTexArray &texCombineSrc1Rgbs = mShaderState.texCombineSrc1Rgbs; 148 GLES1ShaderState::IntTexArray &texCombineSrc1Alphas = mShaderState.texCombineSrc1Alphas; 149 GLES1ShaderState::IntTexArray &texCombineSrc2Rgbs = mShaderState.texCombineSrc2Rgbs; 150 GLES1ShaderState::IntTexArray &texCombineSrc2Alphas = mShaderState.texCombineSrc2Alphas; 151 GLES1ShaderState::IntTexArray &texCombineOp0Rgbs = mShaderState.texCombineOp0Rgbs; 152 GLES1ShaderState::IntTexArray &texCombineOp0Alphas = mShaderState.texCombineOp0Alphas; 153 GLES1ShaderState::IntTexArray &texCombineOp1Rgbs = mShaderState.texCombineOp1Rgbs; 154 GLES1ShaderState::IntTexArray &texCombineOp1Alphas = mShaderState.texCombineOp1Alphas; 155 GLES1ShaderState::IntTexArray &texCombineOp2Rgbs = mShaderState.texCombineOp2Rgbs; 156 GLES1ShaderState::IntTexArray &texCombineOp2Alphas = mShaderState.texCombineOp2Alphas; 157 158 if (gles1State.isDirty(GLES1State::DIRTY_GLES1_TEXTURE_ENVIRONMENT)) 159 { 160 for (int i = 0; i < kTexUnitCount; i++) 161 { 162 const auto &env = gles1State.textureEnvironment(i); 163 texEnvModes[i] = ToGLenum(env.mode); 164 texCombineRgbs[i] = ToGLenum(env.combineRgb); 165 texCombineAlphas[i] = ToGLenum(env.combineAlpha); 166 texCombineSrc0Rgbs[i] = ToGLenum(env.src0Rgb); 167 texCombineSrc0Alphas[i] = ToGLenum(env.src0Alpha); 168 texCombineSrc1Rgbs[i] = ToGLenum(env.src1Rgb); 169 texCombineSrc1Alphas[i] = ToGLenum(env.src1Alpha); 170 texCombineSrc2Rgbs[i] = ToGLenum(env.src2Rgb); 171 texCombineSrc2Alphas[i] = ToGLenum(env.src2Alpha); 172 texCombineOp0Rgbs[i] = ToGLenum(env.op0Rgb); 173 texCombineOp0Alphas[i] = ToGLenum(env.op0Alpha); 174 texCombineOp1Rgbs[i] = ToGLenum(env.op1Rgb); 175 texCombineOp1Alphas[i] = ToGLenum(env.op1Alpha); 176 texCombineOp2Rgbs[i] = ToGLenum(env.op2Rgb); 177 texCombineOp2Alphas[i] = ToGLenum(env.op2Alpha); 178 } 179 } 180 181 bool enableClipPlanes = false; 182 GLES1ShaderState::BoolClipPlaneArray &clipPlaneEnables = mShaderState.clipPlaneEnables; 183 for (int i = 0; i < kClipPlaneCount; i++) 184 { 185 clipPlaneEnables[i] = glState->getEnableFeature(GL_CLIP_PLANE0 + i); 186 enableClipPlanes = enableClipPlanes || clipPlaneEnables[i]; 187 } 188 189 mShaderState.mGLES1StateEnabled[GLES1StateEnables::ClipPlanes] = enableClipPlanes; 190 mShaderState.mGLES1StateEnabled[GLES1StateEnables::DrawTexture] = mDrawTextureEnabled; 191 mShaderState.mGLES1StateEnabled[GLES1StateEnables::PointRasterization] = 192 mode == PrimitiveMode::Points; 193 mShaderState.mGLES1StateEnabled[GLES1StateEnables::ShadeModelFlat] = 194 gles1State.mShadeModel == ShadingModel::Flat; 195 mShaderState.mGLES1StateEnabled[GLES1StateEnables::AlphaTest] = 196 glState->getEnableFeature(GL_ALPHA_TEST); 197 mShaderState.mGLES1StateEnabled[GLES1StateEnables::Lighting] = 198 glState->getEnableFeature(GL_LIGHTING); 199 mShaderState.mGLES1StateEnabled[GLES1StateEnables::RescaleNormal] = 200 glState->getEnableFeature(GL_RESCALE_NORMAL); 201 mShaderState.mGLES1StateEnabled[GLES1StateEnables::Normalize] = 202 glState->getEnableFeature(GL_NORMALIZE); 203 mShaderState.mGLES1StateEnabled[GLES1StateEnables::Fog] = glState->getEnableFeature(GL_FOG); 204 mShaderState.mGLES1StateEnabled[GLES1StateEnables::PointSprite] = 205 glState->getEnableFeature(GL_POINT_SPRITE_OES); 206 mShaderState.mGLES1StateEnabled[GLES1StateEnables::ColorMaterial] = 207 glState->getEnableFeature(GL_COLOR_MATERIAL); 208 209 // TODO (lfy@google.com): Implement two-sided lighting model (lightModel.twoSided) 210 mShaderState.mGLES1StateEnabled[GLES1StateEnables::LightModelTwoSided] = false; 211 212 GLES1ShaderState::BoolTexArray &pointSpriteCoordReplaces = 213 mShaderState.pointSpriteCoordReplaces; 214 for (int i = 0; i < kTexUnitCount; i++) 215 { 216 const auto &env = gles1State.textureEnvironment(i); 217 pointSpriteCoordReplaces[i] = env.pointSpriteCoordReplace; 218 } 219 220 GLES1ShaderState::BoolLightArray &lightEnables = mShaderState.lightEnables; 221 for (int i = 0; i < kLightCount; i++) 222 { 223 const auto &light = gles1State.mLights[i]; 224 lightEnables[i] = light.enabled; 225 } 226 227 mShaderState.alphaTestFunc = gles1State.mAlphaTestFunc; 228 mShaderState.fogMode = gles1State.fogParameters().mode; 229 230 const bool hasLogicOpANGLE = context->getExtensions().logicOpANGLE; 231 const bool hasFramebufferFetch = context->getExtensions().shaderFramebufferFetchEXT || 232 context->getExtensions().shaderFramebufferFetchNonCoherentEXT; 233 234 if (!hasLogicOpANGLE && hasFramebufferFetch) 235 { 236 mShaderState.mGLES1StateEnabled[GLES1StateEnables::LogicOpThroughFramebufferFetch] = 237 gles1State.mLogicOpEnabled; 238 } 239 240 // All the states set before this spot affect ubershader creation 241 242 ANGLE_TRY(initializeRendererProgram(context, glState)); 243 244 GLES1UberShaderState UberShaderState = getUberShaderState(); 245 246 const GLES1ProgramState &programState = UberShaderState.programState; 247 GLES1UniformBuffers &uniformBuffers = UberShaderState.uniformBuffers; 248 249 Program *programObject = getProgram(programState.program); 250 251 // If anything is dirty in gles1 or the common parts of gles1/2, just redo these parts 252 // completely for now. 253 254 // Feature enables 255 256 // Texture unit enables and format info 257 std::array<Vec4Uniform, kTexUnitCount> texCropRects; 258 Vec4Uniform *cropRectBuffer = texCropRects.data(); 259 for (int i = 0; i < kTexUnitCount; i++) 260 { 261 Texture *curr2DTexture = glState->getSamplerTexture(i, TextureType::_2D); 262 if (curr2DTexture) 263 { 264 const gl::Rectangle &cropRect = curr2DTexture->getCrop(); 265 266 GLfloat textureWidth = 267 static_cast<GLfloat>(curr2DTexture->getWidth(TextureTarget::_2D, 0)); 268 GLfloat textureHeight = 269 static_cast<GLfloat>(curr2DTexture->getHeight(TextureTarget::_2D, 0)); 270 271 if (textureWidth > 0.0f && textureHeight > 0.0f) 272 { 273 cropRectBuffer[i][0] = cropRect.x / textureWidth; 274 cropRectBuffer[i][1] = cropRect.y / textureHeight; 275 cropRectBuffer[i][2] = cropRect.width / textureWidth; 276 cropRectBuffer[i][3] = cropRect.height / textureHeight; 277 } 278 } 279 } 280 setUniform4fv(programObject, programState.drawTextureNormalizedCropRectLoc, kTexUnitCount, 281 reinterpret_cast<GLfloat *>(cropRectBuffer)); 282 283 if (gles1State.isDirty(GLES1State::DIRTY_GLES1_LOGIC_OP) && hasLogicOpANGLE) 284 { 285 context->setLogicOpEnabled(gles1State.mLogicOpEnabled); 286 context->setLogicOp(gles1State.mLogicOp); 287 } 288 else if (hasFramebufferFetch) 289 { 290 const Framebuffer *drawFramebuffer = glState->getDrawFramebuffer(); 291 const FramebufferAttachment *colorAttachment = drawFramebuffer->getColorAttachment(0); 292 293 if (gles1State.mLogicOpEnabled) 294 { 295 if (gles1State.isDirty(GLES1State::DIRTY_GLES1_LOGIC_OP)) 296 { 297 // Set up uniform value for logic op 298 setUniform1ui(programObject, programState.logicOpLoc, 299 GetLogicOpUniform(colorAttachment, gles1State.mLogicOp)); 300 } 301 302 // Issue a framebuffer fetch barrier if non-coherent 303 if (!context->getExtensions().shaderFramebufferFetchEXT) 304 { 305 context->framebufferFetchBarrier(); 306 } 307 } 308 } 309 310 // Client state / current vector enables 311 if (gles1State.isDirty(GLES1State::DIRTY_GLES1_CLIENT_STATE_ENABLE) || 312 gles1State.isDirty(GLES1State::DIRTY_GLES1_CURRENT_VECTOR)) 313 { 314 if (!gles1State.isClientStateEnabled(ClientVertexArrayType::Normal)) 315 { 316 const angle::Vector3 normal = gles1State.getCurrentNormal(); 317 context->vertexAttrib3f(kNormalAttribIndex, normal.x(), normal.y(), normal.z()); 318 } 319 320 if (!gles1State.isClientStateEnabled(ClientVertexArrayType::Color)) 321 { 322 const ColorF color = gles1State.getCurrentColor(); 323 context->vertexAttrib4f(kColorAttribIndex, color.red, color.green, color.blue, 324 color.alpha); 325 } 326 327 if (!gles1State.isClientStateEnabled(ClientVertexArrayType::PointSize)) 328 { 329 GLfloat pointSize = gles1State.mPointParameters.pointSize; 330 context->vertexAttrib1f(kPointSizeAttribIndex, pointSize); 331 } 332 333 for (int i = 0; i < kTexUnitCount; i++) 334 { 335 if (!gles1State.mTexCoordArrayEnabled[i]) 336 { 337 const TextureCoordF texcoord = gles1State.getCurrentTextureCoords(i); 338 context->vertexAttrib4f(kTextureCoordAttribIndexBase + i, texcoord.s, texcoord.t, 339 texcoord.r, texcoord.q); 340 } 341 } 342 } 343 344 // Matrices 345 if (gles1State.isDirty(GLES1State::DIRTY_GLES1_MATRICES)) 346 { 347 angle::Mat4 proj = gles1State.mProjectionMatrices.back(); 348 setUniformMatrix4fv(programObject, programState.projMatrixLoc, 1, GL_FALSE, proj.data()); 349 350 angle::Mat4 modelview = gles1State.mModelviewMatrices.back(); 351 setUniformMatrix4fv(programObject, programState.modelviewMatrixLoc, 1, GL_FALSE, 352 modelview.data()); 353 354 angle::Mat4 modelviewInvTr = modelview.transpose().inverse(); 355 setUniformMatrix4fv(programObject, programState.modelviewInvTrLoc, 1, GL_FALSE, 356 modelviewInvTr.data()); 357 358 Mat4Uniform *textureMatrixBuffer = uniformBuffers.textureMatrices.data(); 359 360 for (int i = 0; i < kTexUnitCount; i++) 361 { 362 angle::Mat4 textureMatrix = gles1State.mTextureMatrices[i].back(); 363 memcpy(textureMatrixBuffer + i, textureMatrix.data(), sizeof(Mat4Uniform)); 364 } 365 366 setUniformMatrix4fv(programObject, programState.textureMatrixLoc, kTexUnitCount, GL_FALSE, 367 reinterpret_cast<float *>(uniformBuffers.textureMatrices.data())); 368 } 369 370 if (gles1State.isDirty(GLES1State::DIRTY_GLES1_TEXTURE_ENVIRONMENT)) 371 { 372 for (int i = 0; i < kTexUnitCount; i++) 373 { 374 const auto &env = gles1State.textureEnvironment(i); 375 376 uniformBuffers.texEnvColors[i][0] = env.color.red; 377 uniformBuffers.texEnvColors[i][1] = env.color.green; 378 uniformBuffers.texEnvColors[i][2] = env.color.blue; 379 uniformBuffers.texEnvColors[i][3] = env.color.alpha; 380 381 uniformBuffers.texEnvRgbScales[i] = env.rgbScale; 382 uniformBuffers.texEnvAlphaScales[i] = env.alphaScale; 383 } 384 385 setUniform4fv(programObject, programState.textureEnvColorLoc, kTexUnitCount, 386 reinterpret_cast<float *>(uniformBuffers.texEnvColors.data())); 387 setUniform1fv(programObject, programState.rgbScaleLoc, kTexUnitCount, 388 uniformBuffers.texEnvRgbScales.data()); 389 setUniform1fv(programObject, programState.alphaScaleLoc, kTexUnitCount, 390 uniformBuffers.texEnvAlphaScales.data()); 391 } 392 393 // Alpha test 394 if (gles1State.isDirty(GLES1State::DIRTY_GLES1_ALPHA_TEST)) 395 { 396 setUniform1f(programObject, programState.alphaTestRefLoc, gles1State.mAlphaTestRef); 397 } 398 399 // Shading, materials, and lighting 400 if (gles1State.isDirty(GLES1State::DIRTY_GLES1_MATERIAL)) 401 { 402 const auto &material = gles1State.mMaterial; 403 404 setUniform4fv(programObject, programState.materialAmbientLoc, 1, material.ambient.data()); 405 setUniform4fv(programObject, programState.materialDiffuseLoc, 1, material.diffuse.data()); 406 setUniform4fv(programObject, programState.materialSpecularLoc, 1, material.specular.data()); 407 setUniform4fv(programObject, programState.materialEmissiveLoc, 1, material.emissive.data()); 408 setUniform1f(programObject, programState.materialSpecularExponentLoc, 409 material.specularExponent); 410 } 411 412 if (gles1State.isDirty(GLES1State::DIRTY_GLES1_LIGHTS)) 413 { 414 const auto &lightModel = gles1State.mLightModel; 415 416 setUniform4fv(programObject, programState.lightModelSceneAmbientLoc, 1, 417 lightModel.color.data()); 418 419 for (int i = 0; i < kLightCount; i++) 420 { 421 const auto &light = gles1State.mLights[i]; 422 memcpy(uniformBuffers.lightAmbients.data() + i, light.ambient.data(), 423 sizeof(Vec4Uniform)); 424 memcpy(uniformBuffers.lightDiffuses.data() + i, light.diffuse.data(), 425 sizeof(Vec4Uniform)); 426 memcpy(uniformBuffers.lightSpeculars.data() + i, light.specular.data(), 427 sizeof(Vec4Uniform)); 428 memcpy(uniformBuffers.lightPositions.data() + i, light.position.data(), 429 sizeof(Vec4Uniform)); 430 memcpy(uniformBuffers.lightDirections.data() + i, light.direction.data(), 431 sizeof(Vec3Uniform)); 432 uniformBuffers.spotlightExponents[i] = light.spotlightExponent; 433 uniformBuffers.spotlightCutoffAngles[i] = light.spotlightCutoffAngle; 434 uniformBuffers.attenuationConsts[i] = light.attenuationConst; 435 uniformBuffers.attenuationLinears[i] = light.attenuationLinear; 436 uniformBuffers.attenuationQuadratics[i] = light.attenuationQuadratic; 437 } 438 439 setUniform4fv(programObject, programState.lightAmbientsLoc, kLightCount, 440 reinterpret_cast<float *>(uniformBuffers.lightAmbients.data())); 441 setUniform4fv(programObject, programState.lightDiffusesLoc, kLightCount, 442 reinterpret_cast<float *>(uniformBuffers.lightDiffuses.data())); 443 setUniform4fv(programObject, programState.lightSpecularsLoc, kLightCount, 444 reinterpret_cast<float *>(uniformBuffers.lightSpeculars.data())); 445 setUniform4fv(programObject, programState.lightPositionsLoc, kLightCount, 446 reinterpret_cast<float *>(uniformBuffers.lightPositions.data())); 447 setUniform3fv(programObject, programState.lightDirectionsLoc, kLightCount, 448 reinterpret_cast<float *>(uniformBuffers.lightDirections.data())); 449 setUniform1fv(programObject, programState.lightSpotlightExponentsLoc, kLightCount, 450 reinterpret_cast<float *>(uniformBuffers.spotlightExponents.data())); 451 setUniform1fv(programObject, programState.lightSpotlightCutoffAnglesLoc, kLightCount, 452 reinterpret_cast<float *>(uniformBuffers.spotlightCutoffAngles.data())); 453 setUniform1fv(programObject, programState.lightAttenuationConstsLoc, kLightCount, 454 reinterpret_cast<float *>(uniformBuffers.attenuationConsts.data())); 455 setUniform1fv(programObject, programState.lightAttenuationLinearsLoc, kLightCount, 456 reinterpret_cast<float *>(uniformBuffers.attenuationLinears.data())); 457 setUniform1fv(programObject, programState.lightAttenuationQuadraticsLoc, kLightCount, 458 reinterpret_cast<float *>(uniformBuffers.attenuationQuadratics.data())); 459 } 460 461 if (gles1State.isDirty(GLES1State::DIRTY_GLES1_FOG)) 462 { 463 const FogParameters &fog = gles1State.fogParameters(); 464 setUniform1f(programObject, programState.fogDensityLoc, fog.density); 465 setUniform1f(programObject, programState.fogStartLoc, fog.start); 466 setUniform1f(programObject, programState.fogEndLoc, fog.end); 467 setUniform4fv(programObject, programState.fogColorLoc, 1, fog.color.data()); 468 } 469 470 // Clip planes 471 if (gles1State.isDirty(GLES1State::DIRTY_GLES1_CLIP_PLANES)) 472 { 473 for (int i = 0; i < kClipPlaneCount; i++) 474 { 475 gles1State.getClipPlane( 476 i, reinterpret_cast<float *>(uniformBuffers.clipPlanes.data() + i)); 477 } 478 479 setUniform4fv(programObject, programState.clipPlanesLoc, kClipPlaneCount, 480 reinterpret_cast<float *>(uniformBuffers.clipPlanes.data())); 481 } 482 483 // Point rasterization 484 { 485 const PointParameters &pointParams = gles1State.mPointParameters; 486 487 setUniform1f(programObject, programState.pointSizeMinLoc, pointParams.pointSizeMin); 488 setUniform1f(programObject, programState.pointSizeMaxLoc, pointParams.pointSizeMax); 489 setUniform3fv(programObject, programState.pointDistanceAttenuationLoc, 1, 490 pointParams.pointDistanceAttenuation.data()); 491 } 492 493 // Draw texture 494 { 495 setUniform4fv(programObject, programState.drawTextureCoordsLoc, 1, mDrawTextureCoords); 496 setUniform2fv(programObject, programState.drawTextureDimsLoc, 1, mDrawTextureDims); 497 } 498 499 gles1State.clearDirty(); 500 501 // None of those are changes in sampler, so there is no need to set the GL_PROGRAM dirty. 502 // Otherwise, put the dirtying here. 503 504 return angle::Result::Continue; 505 } 506 507 // static 508 int GLES1Renderer::VertexArrayIndex(ClientVertexArrayType type, const GLES1State &gles1) 509 { 510 switch (type) 511 { 512 case ClientVertexArrayType::Vertex: 513 return kVertexAttribIndex; 514 case ClientVertexArrayType::Normal: 515 return kNormalAttribIndex; 516 case ClientVertexArrayType::Color: 517 return kColorAttribIndex; 518 case ClientVertexArrayType::PointSize: 519 return kPointSizeAttribIndex; 520 case ClientVertexArrayType::TextureCoord: 521 return kTextureCoordAttribIndexBase + gles1.getClientTextureUnit(); 522 default: 523 UNREACHABLE(); 524 return 0; 525 } 526 } 527 528 // static 529 ClientVertexArrayType GLES1Renderer::VertexArrayType(int attribIndex) 530 { 531 switch (attribIndex) 532 { 533 case kVertexAttribIndex: 534 return ClientVertexArrayType::Vertex; 535 case kNormalAttribIndex: 536 return ClientVertexArrayType::Normal; 537 case kColorAttribIndex: 538 return ClientVertexArrayType::Color; 539 case kPointSizeAttribIndex: 540 return ClientVertexArrayType::PointSize; 541 default: 542 if (attribIndex < kTextureCoordAttribIndexBase + kTexUnitCount) 543 { 544 return ClientVertexArrayType::TextureCoord; 545 } 546 UNREACHABLE(); 547 return ClientVertexArrayType::InvalidEnum; 548 } 549 } 550 551 // static 552 int GLES1Renderer::TexCoordArrayIndex(unsigned int unit) 553 { 554 return kTextureCoordAttribIndexBase + unit; 555 } 556 557 void GLES1Renderer::drawTexture(Context *context, 558 State *glState, 559 float x, 560 float y, 561 float z, 562 float width, 563 float height) 564 { 565 566 // get viewport 567 const gl::Rectangle &viewport = glState->getViewport(); 568 569 // Translate from viewport to NDC for feeding the shader. 570 // Recenter, rescale. (e.g., [0, 0, 1080, 1920] -> [-1, -1, 1, 1]) 571 float xNdc = scaleScreenCoordinateToNdc(x, static_cast<GLfloat>(viewport.width)); 572 float yNdc = scaleScreenCoordinateToNdc(y, static_cast<GLfloat>(viewport.height)); 573 float wNdc = scaleScreenDimensionToNdc(width, static_cast<GLfloat>(viewport.width)); 574 float hNdc = scaleScreenDimensionToNdc(height, static_cast<GLfloat>(viewport.height)); 575 576 float zNdc = 2.0f * clamp(z, 0.0f, 1.0f) - 1.0f; 577 578 mDrawTextureCoords[0] = xNdc; 579 mDrawTextureCoords[1] = yNdc; 580 mDrawTextureCoords[2] = zNdc; 581 582 mDrawTextureDims[0] = wNdc; 583 mDrawTextureDims[1] = hNdc; 584 585 mDrawTextureEnabled = true; 586 587 AttributesMask prevAttributesMask = glState->gles1().getVertexArraysAttributeMask(); 588 589 setAttributesEnabled(context, glState, AttributesMask()); 590 591 glState->gles1().setAllDirty(); 592 593 context->drawArrays(PrimitiveMode::Triangles, 0, 6); 594 595 setAttributesEnabled(context, glState, prevAttributesMask); 596 597 mDrawTextureEnabled = false; 598 } 599 600 Shader *GLES1Renderer::getShader(ShaderProgramID handle) const 601 { 602 return mShaderPrograms->getShader(handle); 603 } 604 605 Program *GLES1Renderer::getProgram(ShaderProgramID handle) const 606 { 607 return mShaderPrograms->getProgram(handle); 608 } 609 610 angle::Result GLES1Renderer::compileShader(Context *context, 611 ShaderType shaderType, 612 const char *src, 613 ShaderProgramID *shaderOut) 614 { 615 rx::ContextImpl *implementation = context->getImplementation(); 616 const Limitations &limitations = implementation->getNativeLimitations(); 617 618 ShaderProgramID shader = mShaderPrograms->createShader(implementation, limitations, shaderType); 619 620 Shader *shaderObject = getShader(shader); 621 ANGLE_CHECK(context, shaderObject, "Missing shader object", GL_INVALID_OPERATION); 622 623 shaderObject->setSource(1, &src, nullptr); 624 shaderObject->compile(context); 625 626 *shaderOut = shader; 627 628 if (!shaderObject->isCompiled(context)) 629 { 630 GLint infoLogLength = shaderObject->getInfoLogLength(context); 631 std::vector<char> infoLog(infoLogLength, 0); 632 shaderObject->getInfoLog(context, infoLogLength - 1, nullptr, infoLog.data()); 633 634 ERR() << "Internal GLES 1 shader compile failed. Info log: " << infoLog.data(); 635 ANGLE_CHECK(context, false, "GLES1Renderer shader compile failed.", GL_INVALID_OPERATION); 636 return angle::Result::Stop; 637 } 638 639 return angle::Result::Continue; 640 } 641 642 angle::Result GLES1Renderer::linkProgram(Context *context, 643 State *glState, 644 ShaderProgramID vertexShader, 645 ShaderProgramID fragmentShader, 646 const angle::HashMap<GLint, std::string> &attribLocs, 647 ShaderProgramID *programOut) 648 { 649 ShaderProgramID program = mShaderPrograms->createProgram(context->getImplementation()); 650 651 Program *programObject = getProgram(program); 652 ANGLE_CHECK(context, programObject, "Missing program object", GL_INVALID_OPERATION); 653 654 *programOut = program; 655 656 programObject->attachShader(getShader(vertexShader)); 657 programObject->attachShader(getShader(fragmentShader)); 658 659 for (auto it : attribLocs) 660 { 661 GLint index = it.first; 662 const std::string &name = it.second; 663 programObject->bindAttributeLocation(index, name.c_str()); 664 } 665 666 ANGLE_TRY(programObject->link(context)); 667 programObject->resolveLink(context); 668 669 ANGLE_TRY(glState->onProgramExecutableChange(context, programObject)); 670 671 if (!programObject->isLinked()) 672 { 673 GLint infoLogLength = programObject->getExecutable().getInfoLogLength(); 674 std::vector<char> infoLog(infoLogLength, 0); 675 programObject->getExecutable().getInfoLog(infoLogLength - 1, nullptr, infoLog.data()); 676 677 ERR() << "Internal GLES 1 shader link failed. Info log: " << infoLog.data(); 678 ANGLE_CHECK(context, false, "GLES1Renderer program link failed.", GL_INVALID_OPERATION); 679 return angle::Result::Stop; 680 } 681 682 programObject->detachShader(context, getShader(vertexShader)); 683 programObject->detachShader(context, getShader(fragmentShader)); 684 685 return angle::Result::Continue; 686 } 687 688 const char *GLES1Renderer::getShaderBool(GLES1StateEnables state) 689 { 690 if (mShaderState.mGLES1StateEnabled[state]) 691 { 692 return "true"; 693 } 694 else 695 { 696 return "false"; 697 } 698 } 699 700 void GLES1Renderer::addShaderDefine(std::stringstream &outStream, 701 GLES1StateEnables state, 702 const char *enableString) 703 { 704 outStream << "\n"; 705 outStream << "#define " << enableString << " " << getShaderBool(state); 706 } 707 708 void GLES1Renderer::addShaderInt(std::stringstream &outStream, const char *name, int value) 709 { 710 outStream << "\n"; 711 outStream << "const int " << name << " = " << value << ";"; 712 } 713 714 void GLES1Renderer::addShaderIntTexArray(std::stringstream &outStream, 715 const char *texString, 716 GLES1ShaderState::IntTexArray &texState) 717 { 718 outStream << "\n"; 719 outStream << "const int " << texString << "[kMaxTexUnits] = int[kMaxTexUnits]("; 720 for (int i = 0; i < kTexUnitCount; i++) 721 { 722 if (i != 0) 723 { 724 outStream << ", "; 725 } 726 outStream << texState[i]; 727 } 728 outStream << ");"; 729 } 730 731 void GLES1Renderer::addShaderBoolTexArray(std::stringstream &outStream, 732 const char *name, 733 GLES1ShaderState::BoolTexArray &value) 734 { 735 outStream << std::boolalpha; 736 outStream << "\n"; 737 outStream << "bool " << name << "[kMaxTexUnits] = bool[kMaxTexUnits]("; 738 for (int i = 0; i < kTexUnitCount; i++) 739 { 740 if (i != 0) 741 { 742 outStream << ", "; 743 } 744 outStream << value[i]; 745 } 746 outStream << ");"; 747 } 748 749 void GLES1Renderer::addShaderBoolLightArray(std::stringstream &outStream, 750 const char *name, 751 GLES1ShaderState::BoolLightArray &value) 752 { 753 outStream << std::boolalpha; 754 outStream << "\n"; 755 outStream << "bool " << name << "[kMaxLights] = bool[kMaxLights]("; 756 for (int i = 0; i < kLightCount; i++) 757 { 758 if (i != 0) 759 { 760 outStream << ", "; 761 } 762 outStream << value[i]; 763 } 764 outStream << ");"; 765 } 766 767 void GLES1Renderer::addShaderBoolClipPlaneArray(std::stringstream &outStream, 768 const char *name, 769 GLES1ShaderState::BoolClipPlaneArray &value) 770 { 771 outStream << std::boolalpha; 772 outStream << "\n"; 773 outStream << "bool " << name << "[kMaxClipPlanes] = bool[kMaxClipPlanes]("; 774 for (int i = 0; i < kClipPlaneCount; i++) 775 { 776 if (i != 0) 777 { 778 outStream << ", "; 779 } 780 outStream << value[i]; 781 } 782 outStream << ");"; 783 } 784 785 void GLES1Renderer::addVertexShaderDefs(std::stringstream &outStream) 786 { 787 addShaderDefine(outStream, GLES1StateEnables::Lighting, "enable_lighting"); 788 addShaderDefine(outStream, GLES1StateEnables::ColorMaterial, "enable_color_material"); 789 addShaderDefine(outStream, GLES1StateEnables::DrawTexture, "enable_draw_texture"); 790 addShaderDefine(outStream, GLES1StateEnables::PointRasterization, "point_rasterization"); 791 addShaderDefine(outStream, GLES1StateEnables::RescaleNormal, "enable_rescale_normal"); 792 addShaderDefine(outStream, GLES1StateEnables::Normalize, "enable_normalize"); 793 addShaderDefine(outStream, GLES1StateEnables::LightModelTwoSided, "light_model_two_sided"); 794 795 // bool light_enables[kMaxLights] = bool[kMaxLights](...); 796 addShaderBoolLightArray(outStream, "light_enables", mShaderState.lightEnables); 797 } 798 799 void GLES1Renderer::addFragmentShaderDefs(std::stringstream &outStream) 800 { 801 addShaderDefine(outStream, GLES1StateEnables::Fog, "enable_fog"); 802 addShaderDefine(outStream, GLES1StateEnables::ClipPlanes, "enable_clip_planes"); 803 addShaderDefine(outStream, GLES1StateEnables::DrawTexture, "enable_draw_texture"); 804 addShaderDefine(outStream, GLES1StateEnables::PointRasterization, "point_rasterization"); 805 addShaderDefine(outStream, GLES1StateEnables::PointSprite, "point_sprite_enabled"); 806 addShaderDefine(outStream, GLES1StateEnables::AlphaTest, "enable_alpha_test"); 807 addShaderDefine(outStream, GLES1StateEnables::ShadeModelFlat, "shade_model_flat"); 808 809 // bool enable_texture_2d[kMaxTexUnits] = bool[kMaxTexUnits](...); 810 addShaderBoolTexArray(outStream, "enable_texture_2d", mShaderState.tex2DEnables); 811 812 // bool enable_texture_cube_map[kMaxTexUnits] = bool[kMaxTexUnits](...); 813 addShaderBoolTexArray(outStream, "enable_texture_cube_map", mShaderState.texCubeEnables); 814 815 // int texture_format[kMaxTexUnits] = int[kMaxTexUnits](...); 816 addShaderIntTexArray(outStream, "texture_format", mShaderState.tex2DFormats); 817 818 // bool point_sprite_coord_replace[kMaxTexUnits] = bool[kMaxTexUnits](...); 819 addShaderBoolTexArray(outStream, "point_sprite_coord_replace", 820 mShaderState.pointSpriteCoordReplaces); 821 822 // bool clip_plane_enables[kMaxClipPlanes] = bool[kMaxClipPlanes](...); 823 addShaderBoolClipPlaneArray(outStream, "clip_plane_enables", mShaderState.clipPlaneEnables); 824 825 // int texture_format[kMaxTexUnits] = int[kMaxTexUnits](...); 826 addShaderIntTexArray(outStream, "texture_env_mode", mShaderState.texEnvModes); 827 828 // int combine_rgb[kMaxTexUnits]; 829 addShaderIntTexArray(outStream, "combine_rgb", mShaderState.texCombineRgbs); 830 831 // int combine_alpha[kMaxTexUnits]; 832 addShaderIntTexArray(outStream, "combine_alpha", mShaderState.texCombineAlphas); 833 834 // int src0_rgb[kMaxTexUnits]; 835 addShaderIntTexArray(outStream, "src0_rgb", mShaderState.texCombineSrc0Rgbs); 836 837 // int src0_alpha[kMaxTexUnits]; 838 addShaderIntTexArray(outStream, "src0_alpha", mShaderState.texCombineSrc0Alphas); 839 840 // int src1_rgb[kMaxTexUnits]; 841 addShaderIntTexArray(outStream, "src1_rgb", mShaderState.texCombineSrc1Rgbs); 842 843 // int src1_alpha[kMaxTexUnits]; 844 addShaderIntTexArray(outStream, "src1_alpha", mShaderState.texCombineSrc1Alphas); 845 846 // int src2_rgb[kMaxTexUnits]; 847 addShaderIntTexArray(outStream, "src2_rgb", mShaderState.texCombineSrc2Rgbs); 848 849 // int src2_alpha[kMaxTexUnits]; 850 addShaderIntTexArray(outStream, "src2_alpha", mShaderState.texCombineSrc2Alphas); 851 852 // int op0_rgb[kMaxTexUnits]; 853 addShaderIntTexArray(outStream, "op0_rgb", mShaderState.texCombineOp0Rgbs); 854 855 // int op0_alpha[kMaxTexUnits]; 856 addShaderIntTexArray(outStream, "op0_alpha", mShaderState.texCombineOp0Alphas); 857 858 // int op1_rgb[kMaxTexUnits]; 859 addShaderIntTexArray(outStream, "op1_rgb", mShaderState.texCombineOp1Rgbs); 860 861 // int op1_alpha[kMaxTexUnits]; 862 addShaderIntTexArray(outStream, "op1_alpha", mShaderState.texCombineOp1Alphas); 863 864 // int op2_rgb[kMaxTexUnits]; 865 addShaderIntTexArray(outStream, "op2_rgb", mShaderState.texCombineOp2Rgbs); 866 867 // int op2_alpha[kMaxTexUnits]; 868 addShaderIntTexArray(outStream, "op2_alpha", mShaderState.texCombineOp2Alphas); 869 870 // int alpha_func; 871 addShaderInt(outStream, "alpha_func", ToGLenum(mShaderState.alphaTestFunc)); 872 873 // int fog_mode; 874 addShaderInt(outStream, "fog_mode", ToGLenum(mShaderState.fogMode)); 875 } 876 877 angle::Result GLES1Renderer::initializeRendererProgram(Context *context, State *glState) 878 { 879 // See if we have the shader for this combination of states 880 if (mUberShaderState.find(mShaderState) != mUberShaderState.end()) 881 { 882 Program *programObject = getProgram(getUberShaderState().programState.program); 883 884 // If this is different than the current program, we need to sync everything 885 // TODO: This could be optimized to only dirty state that differs between the two programs 886 if (glState->getProgram()->id() != programObject->id()) 887 { 888 glState->gles1().setAllDirty(); 889 } 890 891 ANGLE_TRY(glState->setProgram(context, programObject)); 892 return angle::Result::Continue; 893 } 894 895 if (!mRendererProgramInitialized) 896 { 897 mShaderPrograms = new ShaderProgramManager(); 898 } 899 900 // If we get here, we don't have a shader for this state, need to create it 901 GLES1ProgramState &programState = mUberShaderState[mShaderState].programState; 902 903 ShaderProgramID vertexShader; 904 ShaderProgramID fragmentShader; 905 906 std::stringstream GLES1DrawVShaderStateDefs; 907 addVertexShaderDefs(GLES1DrawVShaderStateDefs); 908 909 std::stringstream vertexStream; 910 vertexStream << kGLES1DrawVShaderHeader; 911 vertexStream << GLES1DrawVShaderStateDefs.str(); 912 vertexStream << kGLES1DrawVShader; 913 914 ANGLE_TRY( 915 compileShader(context, ShaderType::Vertex, vertexStream.str().c_str(), &vertexShader)); 916 917 std::stringstream GLES1DrawFShaderStateDefs; 918 addFragmentShaderDefs(GLES1DrawFShaderStateDefs); 919 920 std::stringstream fragmentStream; 921 fragmentStream << kGLES1DrawFShaderVersion; 922 if (mShaderState.mGLES1StateEnabled[GLES1StateEnables::LogicOpThroughFramebufferFetch]) 923 { 924 if (context->getExtensions().shaderFramebufferFetchEXT) 925 { 926 fragmentStream << "#extension GL_EXT_shader_framebuffer_fetch : require\n"; 927 } 928 else 929 { 930 fragmentStream << "#extension GL_EXT_shader_framebuffer_fetch_non_coherent : require\n"; 931 } 932 } 933 fragmentStream << kGLES1DrawFShaderHeader; 934 fragmentStream << GLES1DrawFShaderStateDefs.str(); 935 fragmentStream << kGLES1DrawFShaderUniformDefs; 936 if (mShaderState.mGLES1StateEnabled[GLES1StateEnables::LogicOpThroughFramebufferFetch]) 937 { 938 if (context->getExtensions().shaderFramebufferFetchEXT) 939 { 940 fragmentStream << kGLES1DrawFShaderFramebufferFetchOutputDef; 941 } 942 else 943 { 944 fragmentStream << kGLES1DrawFShaderFramebufferFetchNonCoherentOutputDef; 945 } 946 fragmentStream << kGLES1DrawFShaderLogicOpFramebufferFetchEnabled; 947 } 948 else 949 { 950 fragmentStream << kGLES1DrawFShaderOutputDef; 951 fragmentStream << kGLES1DrawFShaderLogicOpFramebufferFetchDisabled; 952 } 953 fragmentStream << kGLES1DrawFShaderFunctions; 954 fragmentStream << kGLES1DrawFShaderMultitexturing; 955 fragmentStream << kGLES1DrawFShaderMain; 956 957 ANGLE_TRY(compileShader(context, ShaderType::Fragment, fragmentStream.str().c_str(), 958 &fragmentShader)); 959 960 angle::HashMap<GLint, std::string> attribLocs; 961 962 attribLocs[(GLint)kVertexAttribIndex] = "pos"; 963 attribLocs[(GLint)kNormalAttribIndex] = "normal"; 964 attribLocs[(GLint)kColorAttribIndex] = "color"; 965 attribLocs[(GLint)kPointSizeAttribIndex] = "pointsize"; 966 967 for (int i = 0; i < kTexUnitCount; i++) 968 { 969 std::stringstream ss; 970 ss << "texcoord" << i; 971 attribLocs[kTextureCoordAttribIndexBase + i] = ss.str(); 972 } 973 974 ANGLE_TRY(linkProgram(context, glState, vertexShader, fragmentShader, attribLocs, 975 &programState.program)); 976 977 mShaderPrograms->deleteShader(context, vertexShader); 978 mShaderPrograms->deleteShader(context, fragmentShader); 979 980 Program *programObject = getProgram(programState.program); 981 982 programState.projMatrixLoc = programObject->getUniformLocation("projection"); 983 programState.modelviewMatrixLoc = programObject->getUniformLocation("modelview"); 984 programState.textureMatrixLoc = programObject->getUniformLocation("texture_matrix"); 985 programState.modelviewInvTrLoc = programObject->getUniformLocation("modelview_invtr"); 986 987 for (int i = 0; i < kTexUnitCount; i++) 988 { 989 std::stringstream ss2d; 990 std::stringstream sscube; 991 992 ss2d << "tex_sampler" << i; 993 sscube << "tex_cube_sampler" << i; 994 995 programState.tex2DSamplerLocs[i] = programObject->getUniformLocation(ss2d.str().c_str()); 996 programState.texCubeSamplerLocs[i] = 997 programObject->getUniformLocation(sscube.str().c_str()); 998 } 999 1000 programState.textureEnvColorLoc = programObject->getUniformLocation("texture_env_color"); 1001 programState.rgbScaleLoc = programObject->getUniformLocation("texture_env_rgb_scale"); 1002 programState.alphaScaleLoc = programObject->getUniformLocation("texture_env_alpha_scale"); 1003 1004 programState.alphaTestRefLoc = programObject->getUniformLocation("alpha_test_ref"); 1005 1006 programState.materialAmbientLoc = programObject->getUniformLocation("material_ambient"); 1007 programState.materialDiffuseLoc = programObject->getUniformLocation("material_diffuse"); 1008 programState.materialSpecularLoc = programObject->getUniformLocation("material_specular"); 1009 programState.materialEmissiveLoc = programObject->getUniformLocation("material_emissive"); 1010 programState.materialSpecularExponentLoc = 1011 programObject->getUniformLocation("material_specular_exponent"); 1012 1013 programState.lightModelSceneAmbientLoc = 1014 programObject->getUniformLocation("light_model_scene_ambient"); 1015 1016 programState.lightAmbientsLoc = programObject->getUniformLocation("light_ambients"); 1017 programState.lightDiffusesLoc = programObject->getUniformLocation("light_diffuses"); 1018 programState.lightSpecularsLoc = programObject->getUniformLocation("light_speculars"); 1019 programState.lightPositionsLoc = programObject->getUniformLocation("light_positions"); 1020 programState.lightDirectionsLoc = programObject->getUniformLocation("light_directions"); 1021 programState.lightSpotlightExponentsLoc = 1022 programObject->getUniformLocation("light_spotlight_exponents"); 1023 programState.lightSpotlightCutoffAnglesLoc = 1024 programObject->getUniformLocation("light_spotlight_cutoff_angles"); 1025 programState.lightAttenuationConstsLoc = 1026 programObject->getUniformLocation("light_attenuation_consts"); 1027 programState.lightAttenuationLinearsLoc = 1028 programObject->getUniformLocation("light_attenuation_linears"); 1029 programState.lightAttenuationQuadraticsLoc = 1030 programObject->getUniformLocation("light_attenuation_quadratics"); 1031 1032 programState.fogDensityLoc = programObject->getUniformLocation("fog_density"); 1033 programState.fogStartLoc = programObject->getUniformLocation("fog_start"); 1034 programState.fogEndLoc = programObject->getUniformLocation("fog_end"); 1035 programState.fogColorLoc = programObject->getUniformLocation("fog_color"); 1036 1037 programState.clipPlanesLoc = programObject->getUniformLocation("clip_planes"); 1038 1039 programState.logicOpLoc = programObject->getUniformLocation("logic_op"); 1040 1041 programState.pointSizeMinLoc = programObject->getUniformLocation("point_size_min"); 1042 programState.pointSizeMaxLoc = programObject->getUniformLocation("point_size_max"); 1043 programState.pointDistanceAttenuationLoc = 1044 programObject->getUniformLocation("point_distance_attenuation"); 1045 1046 programState.drawTextureCoordsLoc = programObject->getUniformLocation("draw_texture_coords"); 1047 programState.drawTextureDimsLoc = programObject->getUniformLocation("draw_texture_dims"); 1048 programState.drawTextureNormalizedCropRectLoc = 1049 programObject->getUniformLocation("draw_texture_normalized_crop_rect"); 1050 1051 ANGLE_TRY(glState->setProgram(context, programObject)); 1052 1053 for (int i = 0; i < kTexUnitCount; i++) 1054 { 1055 setUniform1i(context, programObject, programState.tex2DSamplerLocs[i], i); 1056 setUniform1i(context, programObject, programState.texCubeSamplerLocs[i], i + kTexUnitCount); 1057 } 1058 glState->setObjectDirty(GL_PROGRAM); 1059 1060 // We just created a new program, we need to sync everything 1061 glState->gles1().setAllDirty(); 1062 1063 mRendererProgramInitialized = true; 1064 return angle::Result::Continue; 1065 } 1066 1067 void GLES1Renderer::setUniform1i(Context *context, 1068 Program *programObject, 1069 UniformLocation location, 1070 GLint value) 1071 { 1072 if (location.value == -1) 1073 return; 1074 programObject->setUniform1iv(context, location, 1, &value); 1075 } 1076 1077 void GLES1Renderer::setUniform1ui(Program *programObject, UniformLocation location, GLuint value) 1078 { 1079 if (location.value == -1) 1080 return; 1081 programObject->setUniform1uiv(location, 1, &value); 1082 } 1083 1084 void GLES1Renderer::setUniform1iv(Context *context, 1085 Program *programObject, 1086 UniformLocation location, 1087 GLint count, 1088 const GLint *value) 1089 { 1090 if (location.value == -1) 1091 return; 1092 programObject->setUniform1iv(context, location, count, value); 1093 } 1094 1095 void GLES1Renderer::setUniformMatrix4fv(Program *programObject, 1096 UniformLocation location, 1097 GLint count, 1098 GLboolean transpose, 1099 const GLfloat *value) 1100 { 1101 if (location.value == -1) 1102 return; 1103 programObject->setUniformMatrix4fv(location, count, transpose, value); 1104 } 1105 1106 void GLES1Renderer::setUniform4fv(Program *programObject, 1107 UniformLocation location, 1108 GLint count, 1109 const GLfloat *value) 1110 { 1111 if (location.value == -1) 1112 return; 1113 programObject->setUniform4fv(location, count, value); 1114 } 1115 1116 void GLES1Renderer::setUniform3fv(Program *programObject, 1117 UniformLocation location, 1118 GLint count, 1119 const GLfloat *value) 1120 { 1121 if (location.value == -1) 1122 return; 1123 programObject->setUniform3fv(location, count, value); 1124 } 1125 1126 void GLES1Renderer::setUniform2fv(Program *programObject, 1127 UniformLocation location, 1128 GLint count, 1129 const GLfloat *value) 1130 { 1131 if (location.value == -1) 1132 return; 1133 programObject->setUniform2fv(location, count, value); 1134 } 1135 1136 void GLES1Renderer::setUniform1f(Program *programObject, UniformLocation location, GLfloat value) 1137 { 1138 if (location.value == -1) 1139 return; 1140 programObject->setUniform1fv(location, 1, &value); 1141 } 1142 1143 void GLES1Renderer::setUniform1fv(Program *programObject, 1144 UniformLocation location, 1145 GLint count, 1146 const GLfloat *value) 1147 { 1148 if (location.value == -1) 1149 return; 1150 programObject->setUniform1fv(location, count, value); 1151 } 1152 1153 void GLES1Renderer::setAttributesEnabled(Context *context, State *glState, AttributesMask mask) 1154 { 1155 GLES1State &gles1 = glState->gles1(); 1156 1157 ClientVertexArrayType nonTexcoordArrays[] = { 1158 ClientVertexArrayType::Vertex, 1159 ClientVertexArrayType::Normal, 1160 ClientVertexArrayType::Color, 1161 ClientVertexArrayType::PointSize, 1162 }; 1163 1164 for (const ClientVertexArrayType attrib : nonTexcoordArrays) 1165 { 1166 int index = VertexArrayIndex(attrib, glState->gles1()); 1167 1168 if (mask.test(index)) 1169 { 1170 gles1.setClientStateEnabled(attrib, true); 1171 context->enableVertexAttribArray(index); 1172 } 1173 else 1174 { 1175 gles1.setClientStateEnabled(attrib, false); 1176 context->disableVertexAttribArray(index); 1177 } 1178 } 1179 1180 for (unsigned int i = 0; i < kTexUnitCount; i++) 1181 { 1182 int index = TexCoordArrayIndex(i); 1183 1184 if (mask.test(index)) 1185 { 1186 gles1.setTexCoordArrayEnabled(i, true); 1187 context->enableVertexAttribArray(index); 1188 } 1189 else 1190 { 1191 gles1.setTexCoordArrayEnabled(i, false); 1192 context->disableVertexAttribArray(index); 1193 } 1194 } 1195 } 1196 1197 } // namespace gl