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