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