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