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 "libANGLE/Context.h"
17 #include "libANGLE/Context.inl.h"
18 #include "libANGLE/Program.h"
19 #include "libANGLE/ResourceManager.h"
20 #include "libANGLE/Shader.h"
21 #include "libANGLE/State.h"
22 #include "libANGLE/renderer/ContextImpl.h"
23 
24 namespace
25 {
26 #include "libANGLE/GLES1Shaders.inc"
27 }  // anonymous namespace
28 
29 namespace gl
30 {
31 
GLES1Renderer()32 GLES1Renderer::GLES1Renderer() : mRendererProgramInitialized(false) {}
33 
onDestroy(Context * context,State * state)34 void GLES1Renderer::onDestroy(Context *context, State *state)
35 {
36     if (mRendererProgramInitialized)
37     {
38         (void)state->setProgram(context, 0);
39 
40         mShaderPrograms->deleteProgram(context, {mProgramState.program});
41         mShaderPrograms->release(context);
42         mShaderPrograms             = nullptr;
43         mRendererProgramInitialized = false;
44     }
45 }
46 
47 GLES1Renderer::~GLES1Renderer() = default;
48 
prepareForDraw(PrimitiveMode mode,Context * context,State * glState)49 angle::Result GLES1Renderer::prepareForDraw(PrimitiveMode mode, Context *context, State *glState)
50 {
51     ANGLE_TRY(initializeRendererProgram(context, glState));
52 
53     GLES1State &gles1State = glState->gles1();
54 
55     Program *programObject = getProgram(mProgramState.program);
56 
57     GLES1UniformBuffers &uniformBuffers = mUniformBuffers;
58 
59     // If anything is dirty in gles1 or the common parts of gles1/2, just redo these parts
60     // completely for now.
61 
62     // Feature enables
63     {
64         setUniform1i(context, programObject, mProgramState.enableAlphaTestLoc,
65                      glState->getEnableFeature(GL_ALPHA_TEST));
66         setUniform1i(context, programObject, mProgramState.enableLightingLoc,
67                      glState->getEnableFeature(GL_LIGHTING));
68         setUniform1i(context, programObject, mProgramState.enableRescaleNormalLoc,
69                      glState->getEnableFeature(GL_RESCALE_NORMAL));
70         setUniform1i(context, programObject, mProgramState.enableNormalizeLoc,
71                      glState->getEnableFeature(GL_NORMALIZE));
72         setUniform1i(context, programObject, mProgramState.enableColorMaterialLoc,
73                      glState->getEnableFeature(GL_COLOR_MATERIAL));
74         setUniform1i(context, programObject, mProgramState.fogEnableLoc,
75                      glState->getEnableFeature(GL_FOG));
76 
77         bool enableClipPlanes = false;
78         for (int i = 0; i < kClipPlaneCount; i++)
79         {
80             uniformBuffers.clipPlaneEnables[i] = glState->getEnableFeature(GL_CLIP_PLANE0 + i);
81             enableClipPlanes = enableClipPlanes || uniformBuffers.clipPlaneEnables[i];
82         }
83 
84         setUniform1i(context, programObject, mProgramState.enableClipPlanesLoc, enableClipPlanes);
85     }
86 
87     // Texture unit enables and format info
88     {
89         std::array<GLint, kTexUnitCount> &tex2DEnables   = uniformBuffers.tex2DEnables;
90         std::array<GLint, kTexUnitCount> &texCubeEnables = uniformBuffers.texCubeEnables;
91 
92         std::vector<int> tex2DFormats = {GL_RGBA, GL_RGBA, GL_RGBA, GL_RGBA};
93 
94         Vec4Uniform *cropRectBuffer = uniformBuffers.texCropRects.data();
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] = gl::GetUnsizedFormat(
124                     curr2DTexture->getFormat(TextureTarget::_2D, 0).info->internalFormat);
125 
126                 const gl::Rectangle &cropRect = curr2DTexture->getCrop();
127 
128                 GLfloat textureWidth =
129                     static_cast<GLfloat>(curr2DTexture->getWidth(TextureTarget::_2D, 0));
130                 GLfloat textureHeight =
131                     static_cast<GLfloat>(curr2DTexture->getHeight(TextureTarget::_2D, 0));
132 
133                 if (textureWidth > 0.0f && textureHeight > 0.0f)
134                 {
135                     cropRectBuffer[i][0] = cropRect.x / textureWidth;
136                     cropRectBuffer[i][1] = cropRect.y / textureHeight;
137                     cropRectBuffer[i][2] = cropRect.width / textureWidth;
138                     cropRectBuffer[i][3] = cropRect.height / textureHeight;
139                 }
140             }
141         }
142 
143         setUniform1iv(context, programObject, mProgramState.enableTexture2DLoc, kTexUnitCount,
144                       tex2DEnables.data());
145         setUniform1iv(context, programObject, mProgramState.enableTextureCubeMapLoc, kTexUnitCount,
146                       texCubeEnables.data());
147 
148         setUniform1iv(context, programObject, mProgramState.textureFormatLoc, kTexUnitCount,
149                       tex2DFormats.data());
150 
151         setUniform4fv(programObject, mProgramState.drawTextureNormalizedCropRectLoc, kTexUnitCount,
152                       reinterpret_cast<GLfloat *>(cropRectBuffer));
153     }
154 
155     // Client state / current vector enables
156     if (gles1State.isDirty(GLES1State::DIRTY_GLES1_CLIENT_STATE_ENABLE) ||
157         gles1State.isDirty(GLES1State::DIRTY_GLES1_CURRENT_VECTOR))
158     {
159         if (!gles1State.isClientStateEnabled(ClientVertexArrayType::Normal))
160         {
161             const angle::Vector3 normal = gles1State.getCurrentNormal();
162             context->vertexAttrib3f(kNormalAttribIndex, normal.x(), normal.y(), normal.z());
163         }
164 
165         if (!gles1State.isClientStateEnabled(ClientVertexArrayType::Color))
166         {
167             const ColorF color = gles1State.getCurrentColor();
168             context->vertexAttrib4f(kColorAttribIndex, color.red, color.green, color.blue,
169                                     color.alpha);
170         }
171 
172         if (!gles1State.isClientStateEnabled(ClientVertexArrayType::PointSize))
173         {
174             GLfloat pointSize = gles1State.mPointParameters.pointSize;
175             context->vertexAttrib1f(kPointSizeAttribIndex, pointSize);
176         }
177 
178         for (int i = 0; i < kTexUnitCount; i++)
179         {
180             if (!gles1State.mTexCoordArrayEnabled[i])
181             {
182                 const TextureCoordF texcoord = gles1State.getCurrentTextureCoords(i);
183                 context->vertexAttrib4f(kTextureCoordAttribIndexBase + i, texcoord.s, texcoord.t,
184                                         texcoord.r, texcoord.q);
185             }
186         }
187     }
188 
189     // Matrices
190     if (gles1State.isDirty(GLES1State::DIRTY_GLES1_MATRICES))
191     {
192         angle::Mat4 proj = gles1State.mProjectionMatrices.back();
193         setUniformMatrix4fv(programObject, mProgramState.projMatrixLoc, 1, GL_FALSE, proj.data());
194 
195         angle::Mat4 modelview = gles1State.mModelviewMatrices.back();
196         setUniformMatrix4fv(programObject, mProgramState.modelviewMatrixLoc, 1, GL_FALSE,
197                             modelview.data());
198 
199         angle::Mat4 modelviewInvTr = modelview.transpose().inverse();
200         setUniformMatrix4fv(programObject, mProgramState.modelviewInvTrLoc, 1, GL_FALSE,
201                             modelviewInvTr.data());
202 
203         Mat4Uniform *textureMatrixBuffer = uniformBuffers.textureMatrices.data();
204 
205         for (int i = 0; i < kTexUnitCount; i++)
206         {
207             angle::Mat4 textureMatrix = gles1State.mTextureMatrices[i].back();
208             memcpy(textureMatrixBuffer + i, textureMatrix.data(), sizeof(Mat4Uniform));
209         }
210 
211         setUniformMatrix4fv(programObject, mProgramState.textureMatrixLoc, kTexUnitCount, GL_FALSE,
212                             reinterpret_cast<float *>(uniformBuffers.textureMatrices.data()));
213     }
214 
215     if (gles1State.isDirty(GLES1State::DIRTY_GLES1_TEXTURE_ENVIRONMENT))
216     {
217         for (int i = 0; i < kTexUnitCount; i++)
218         {
219             const auto &env = gles1State.textureEnvironment(i);
220 
221             uniformBuffers.texEnvModes[i]      = ToGLenum(env.mode);
222             uniformBuffers.texCombineRgbs[i]   = ToGLenum(env.combineRgb);
223             uniformBuffers.texCombineAlphas[i] = ToGLenum(env.combineAlpha);
224 
225             uniformBuffers.texCombineSrc0Rgbs[i]   = ToGLenum(env.src0Rgb);
226             uniformBuffers.texCombineSrc0Alphas[i] = ToGLenum(env.src0Alpha);
227             uniformBuffers.texCombineSrc1Rgbs[i]   = ToGLenum(env.src1Rgb);
228             uniformBuffers.texCombineSrc1Alphas[i] = ToGLenum(env.src1Alpha);
229             uniformBuffers.texCombineSrc2Rgbs[i]   = ToGLenum(env.src2Rgb);
230             uniformBuffers.texCombineSrc2Alphas[i] = ToGLenum(env.src2Alpha);
231 
232             uniformBuffers.texCombineOp0Rgbs[i]   = ToGLenum(env.op0Rgb);
233             uniformBuffers.texCombineOp0Alphas[i] = ToGLenum(env.op0Alpha);
234             uniformBuffers.texCombineOp1Rgbs[i]   = ToGLenum(env.op1Rgb);
235             uniformBuffers.texCombineOp1Alphas[i] = ToGLenum(env.op1Alpha);
236             uniformBuffers.texCombineOp2Rgbs[i]   = ToGLenum(env.op2Rgb);
237             uniformBuffers.texCombineOp2Alphas[i] = ToGLenum(env.op2Alpha);
238 
239             uniformBuffers.texEnvColors[i][0] = env.color.red;
240             uniformBuffers.texEnvColors[i][1] = env.color.green;
241             uniformBuffers.texEnvColors[i][2] = env.color.blue;
242             uniformBuffers.texEnvColors[i][3] = env.color.alpha;
243 
244             uniformBuffers.texEnvRgbScales[i]   = env.rgbScale;
245             uniformBuffers.texEnvAlphaScales[i] = env.alphaScale;
246 
247             uniformBuffers.pointSpriteCoordReplaces[i] = env.pointSpriteCoordReplace;
248         }
249 
250         setUniform1iv(context, programObject, mProgramState.textureEnvModeLoc, kTexUnitCount,
251                       uniformBuffers.texEnvModes.data());
252         setUniform1iv(context, programObject, mProgramState.combineRgbLoc, kTexUnitCount,
253                       uniformBuffers.texCombineRgbs.data());
254         setUniform1iv(context, programObject, mProgramState.combineAlphaLoc, kTexUnitCount,
255                       uniformBuffers.texCombineAlphas.data());
256 
257         setUniform1iv(context, programObject, mProgramState.src0rgbLoc, kTexUnitCount,
258                       uniformBuffers.texCombineSrc0Rgbs.data());
259         setUniform1iv(context, programObject, mProgramState.src0alphaLoc, kTexUnitCount,
260                       uniformBuffers.texCombineSrc0Alphas.data());
261         setUniform1iv(context, programObject, mProgramState.src1rgbLoc, kTexUnitCount,
262                       uniformBuffers.texCombineSrc1Rgbs.data());
263         setUniform1iv(context, programObject, mProgramState.src1alphaLoc, kTexUnitCount,
264                       uniformBuffers.texCombineSrc1Alphas.data());
265         setUniform1iv(context, programObject, mProgramState.src2rgbLoc, kTexUnitCount,
266                       uniformBuffers.texCombineSrc2Rgbs.data());
267         setUniform1iv(context, programObject, mProgramState.src2alphaLoc, kTexUnitCount,
268                       uniformBuffers.texCombineSrc2Alphas.data());
269 
270         setUniform1iv(context, programObject, mProgramState.op0rgbLoc, kTexUnitCount,
271                       uniformBuffers.texCombineOp0Rgbs.data());
272         setUniform1iv(context, programObject, mProgramState.op0alphaLoc, kTexUnitCount,
273                       uniformBuffers.texCombineOp0Alphas.data());
274         setUniform1iv(context, programObject, mProgramState.op1rgbLoc, kTexUnitCount,
275                       uniformBuffers.texCombineOp1Rgbs.data());
276         setUniform1iv(context, programObject, mProgramState.op1alphaLoc, kTexUnitCount,
277                       uniformBuffers.texCombineOp1Alphas.data());
278         setUniform1iv(context, programObject, mProgramState.op2rgbLoc, kTexUnitCount,
279                       uniformBuffers.texCombineOp2Rgbs.data());
280         setUniform1iv(context, programObject, mProgramState.op2alphaLoc, kTexUnitCount,
281                       uniformBuffers.texCombineOp2Alphas.data());
282 
283         setUniform4fv(programObject, mProgramState.textureEnvColorLoc, kTexUnitCount,
284                       reinterpret_cast<float *>(uniformBuffers.texEnvColors.data()));
285         setUniform1fv(programObject, mProgramState.rgbScaleLoc, kTexUnitCount,
286                       uniformBuffers.texEnvRgbScales.data());
287         setUniform1fv(programObject, mProgramState.alphaScaleLoc, kTexUnitCount,
288                       uniformBuffers.texEnvAlphaScales.data());
289 
290         setUniform1iv(context, programObject, mProgramState.pointSpriteCoordReplaceLoc,
291                       kTexUnitCount, uniformBuffers.pointSpriteCoordReplaces.data());
292     }
293 
294     // Alpha test
295     if (gles1State.isDirty(GLES1State::DIRTY_GLES1_ALPHA_TEST))
296     {
297         setUniform1i(context, programObject, mProgramState.alphaFuncLoc,
298                      ToGLenum(gles1State.mAlphaTestFunc));
299         setUniform1f(programObject, mProgramState.alphaTestRefLoc, gles1State.mAlphaTestRef);
300     }
301 
302     // Shading, materials, and lighting
303     if (gles1State.isDirty(GLES1State::DIRTY_GLES1_SHADE_MODEL))
304     {
305         setUniform1i(context, programObject, mProgramState.shadeModelFlatLoc,
306                      gles1State.mShadeModel == ShadingModel::Flat);
307     }
308 
309     if (gles1State.isDirty(GLES1State::DIRTY_GLES1_MATERIAL))
310     {
311         const auto &material = gles1State.mMaterial;
312 
313         setUniform4fv(programObject, mProgramState.materialAmbientLoc, 1, material.ambient.data());
314         setUniform4fv(programObject, mProgramState.materialDiffuseLoc, 1, material.diffuse.data());
315         setUniform4fv(programObject, mProgramState.materialSpecularLoc, 1,
316                       material.specular.data());
317         setUniform4fv(programObject, mProgramState.materialEmissiveLoc, 1,
318                       material.emissive.data());
319         setUniform1f(programObject, mProgramState.materialSpecularExponentLoc,
320                      material.specularExponent);
321     }
322 
323     if (gles1State.isDirty(GLES1State::DIRTY_GLES1_LIGHTS))
324     {
325         const auto &lightModel = gles1State.mLightModel;
326 
327         setUniform4fv(programObject, mProgramState.lightModelSceneAmbientLoc, 1,
328                       lightModel.color.data());
329 
330         // TODO (lfy@google.com): Implement two-sided lighting model
331         // gl->uniform1i(mProgramState.lightModelTwoSidedLoc, lightModel.twoSided);
332 
333         for (int i = 0; i < kLightCount; i++)
334         {
335             const auto &light              = gles1State.mLights[i];
336             uniformBuffers.lightEnables[i] = light.enabled;
337             memcpy(uniformBuffers.lightAmbients.data() + i, light.ambient.data(),
338                    sizeof(Vec4Uniform));
339             memcpy(uniformBuffers.lightDiffuses.data() + i, light.diffuse.data(),
340                    sizeof(Vec4Uniform));
341             memcpy(uniformBuffers.lightSpeculars.data() + i, light.specular.data(),
342                    sizeof(Vec4Uniform));
343             memcpy(uniformBuffers.lightPositions.data() + i, light.position.data(),
344                    sizeof(Vec4Uniform));
345             memcpy(uniformBuffers.lightDirections.data() + i, light.direction.data(),
346                    sizeof(Vec3Uniform));
347             uniformBuffers.spotlightExponents[i]    = light.spotlightExponent;
348             uniformBuffers.spotlightCutoffAngles[i] = light.spotlightCutoffAngle;
349             uniformBuffers.attenuationConsts[i]     = light.attenuationConst;
350             uniformBuffers.attenuationLinears[i]    = light.attenuationLinear;
351             uniformBuffers.attenuationQuadratics[i] = light.attenuationQuadratic;
352         }
353 
354         setUniform1iv(context, programObject, mProgramState.lightEnablesLoc, kLightCount,
355                       uniformBuffers.lightEnables.data());
356         setUniform4fv(programObject, mProgramState.lightAmbientsLoc, kLightCount,
357                       reinterpret_cast<float *>(uniformBuffers.lightAmbients.data()));
358         setUniform4fv(programObject, mProgramState.lightDiffusesLoc, kLightCount,
359                       reinterpret_cast<float *>(uniformBuffers.lightDiffuses.data()));
360         setUniform4fv(programObject, mProgramState.lightSpecularsLoc, kLightCount,
361                       reinterpret_cast<float *>(uniformBuffers.lightSpeculars.data()));
362         setUniform4fv(programObject, mProgramState.lightPositionsLoc, kLightCount,
363                       reinterpret_cast<float *>(uniformBuffers.lightPositions.data()));
364         setUniform3fv(programObject, mProgramState.lightDirectionsLoc, kLightCount,
365                       reinterpret_cast<float *>(uniformBuffers.lightDirections.data()));
366         setUniform1fv(programObject, mProgramState.lightSpotlightExponentsLoc, kLightCount,
367                       reinterpret_cast<float *>(uniformBuffers.spotlightExponents.data()));
368         setUniform1fv(programObject, mProgramState.lightSpotlightCutoffAnglesLoc, kLightCount,
369                       reinterpret_cast<float *>(uniformBuffers.spotlightCutoffAngles.data()));
370         setUniform1fv(programObject, mProgramState.lightAttenuationConstsLoc, kLightCount,
371                       reinterpret_cast<float *>(uniformBuffers.attenuationConsts.data()));
372         setUniform1fv(programObject, mProgramState.lightAttenuationLinearsLoc, kLightCount,
373                       reinterpret_cast<float *>(uniformBuffers.attenuationLinears.data()));
374         setUniform1fv(programObject, mProgramState.lightAttenuationQuadraticsLoc, kLightCount,
375                       reinterpret_cast<float *>(uniformBuffers.attenuationQuadratics.data()));
376     }
377 
378     if (gles1State.isDirty(GLES1State::DIRTY_GLES1_FOG))
379     {
380         const FogParameters &fog = gles1State.fogParameters();
381         setUniform1i(context, programObject, mProgramState.fogModeLoc, ToGLenum(fog.mode));
382         setUniform1f(programObject, mProgramState.fogDensityLoc, fog.density);
383         setUniform1f(programObject, mProgramState.fogStartLoc, fog.start);
384         setUniform1f(programObject, mProgramState.fogEndLoc, fog.end);
385         setUniform4fv(programObject, mProgramState.fogColorLoc, 1, fog.color.data());
386     }
387 
388     // Clip planes
389     if (gles1State.isDirty(GLES1State::DIRTY_GLES1_CLIP_PLANES))
390     {
391         bool enableClipPlanes = false;
392         for (int i = 0; i < kClipPlaneCount; i++)
393         {
394             uniformBuffers.clipPlaneEnables[i] = glState->getEnableFeature(GL_CLIP_PLANE0 + i);
395             enableClipPlanes = enableClipPlanes || uniformBuffers.clipPlaneEnables[i];
396             gles1State.getClipPlane(
397                 i, reinterpret_cast<float *>(uniformBuffers.clipPlanes.data() + i));
398         }
399 
400         setUniform1i(context, programObject, mProgramState.enableClipPlanesLoc, enableClipPlanes);
401         setUniform1iv(context, programObject, mProgramState.clipPlaneEnablesLoc, kClipPlaneCount,
402                       uniformBuffers.clipPlaneEnables.data());
403         setUniform4fv(programObject, mProgramState.clipPlanesLoc, kClipPlaneCount,
404                       reinterpret_cast<float *>(uniformBuffers.clipPlanes.data()));
405     }
406 
407     // Point rasterization
408     {
409         const PointParameters &pointParams = gles1State.mPointParameters;
410 
411         setUniform1i(context, programObject, mProgramState.pointRasterizationLoc,
412                      mode == PrimitiveMode::Points);
413         setUniform1i(context, programObject, mProgramState.pointSpriteEnabledLoc,
414                      glState->getEnableFeature(GL_POINT_SPRITE_OES));
415         setUniform1f(programObject, mProgramState.pointSizeMinLoc, pointParams.pointSizeMin);
416         setUniform1f(programObject, mProgramState.pointSizeMaxLoc, pointParams.pointSizeMax);
417         setUniform3fv(programObject, mProgramState.pointDistanceAttenuationLoc, 1,
418                       pointParams.pointDistanceAttenuation.data());
419     }
420 
421     // Draw texture
422     {
423         setUniform1i(context, programObject, mProgramState.enableDrawTextureLoc,
424                      mDrawTextureEnabled ? 1 : 0);
425         setUniform4fv(programObject, mProgramState.drawTextureCoordsLoc, 1, mDrawTextureCoords);
426         setUniform2fv(programObject, mProgramState.drawTextureDimsLoc, 1, mDrawTextureDims);
427     }
428 
429     gles1State.clearDirty();
430     // None of those are changes in sampler, so there is no need to set the GL_PROGRAM dirty.
431     // Otherwise, put the dirtying here.
432 
433     return angle::Result::Continue;
434 }
435 
436 // static
VertexArrayIndex(ClientVertexArrayType type,const GLES1State & gles1)437 int GLES1Renderer::VertexArrayIndex(ClientVertexArrayType type, const GLES1State &gles1)
438 {
439     switch (type)
440     {
441         case ClientVertexArrayType::Vertex:
442             return kVertexAttribIndex;
443         case ClientVertexArrayType::Normal:
444             return kNormalAttribIndex;
445         case ClientVertexArrayType::Color:
446             return kColorAttribIndex;
447         case ClientVertexArrayType::PointSize:
448             return kPointSizeAttribIndex;
449         case ClientVertexArrayType::TextureCoord:
450             return kTextureCoordAttribIndexBase + gles1.getClientTextureUnit();
451         default:
452             UNREACHABLE();
453             return 0;
454     }
455 }
456 
457 // static
TexCoordArrayIndex(unsigned int unit)458 int GLES1Renderer::TexCoordArrayIndex(unsigned int unit)
459 {
460     return kTextureCoordAttribIndexBase + unit;
461 }
462 
drawTexture(Context * context,State * glState,float x,float y,float z,float width,float height)463 void GLES1Renderer::drawTexture(Context *context,
464                                 State *glState,
465                                 float x,
466                                 float y,
467                                 float z,
468                                 float width,
469                                 float height)
470 {
471 
472     // get viewport
473     const gl::Rectangle &viewport = glState->getViewport();
474 
475     // Translate from viewport to NDC for feeding the shader.
476     // Recenter, rescale. (e.g., [0, 0, 1080, 1920] -> [-1, -1, 1, 1])
477     float xNdc = scaleScreenCoordinateToNdc(x, static_cast<GLfloat>(viewport.width));
478     float yNdc = scaleScreenCoordinateToNdc(y, static_cast<GLfloat>(viewport.height));
479     float wNdc = scaleScreenDimensionToNdc(width, static_cast<GLfloat>(viewport.width));
480     float hNdc = scaleScreenDimensionToNdc(height, static_cast<GLfloat>(viewport.height));
481 
482     float zNdc = 2.0f * clamp(z, 0.0f, 1.0f) - 1.0f;
483 
484     mDrawTextureCoords[0] = xNdc;
485     mDrawTextureCoords[1] = yNdc;
486     mDrawTextureCoords[2] = zNdc;
487 
488     mDrawTextureDims[0] = wNdc;
489     mDrawTextureDims[1] = hNdc;
490 
491     mDrawTextureEnabled = true;
492 
493     AttributesMask prevAttributesMask = glState->gles1().getVertexArraysAttributeMask();
494 
495     setAttributesEnabled(context, glState, AttributesMask());
496 
497     glState->gles1().setAllDirty();
498 
499     context->drawArrays(PrimitiveMode::Triangles, 0, 6);
500 
501     setAttributesEnabled(context, glState, prevAttributesMask);
502 
503     mDrawTextureEnabled = false;
504 }
505 
getShader(ShaderProgramID handle) const506 Shader *GLES1Renderer::getShader(ShaderProgramID handle) const
507 {
508     return mShaderPrograms->getShader(handle);
509 }
510 
getProgram(ShaderProgramID handle) const511 Program *GLES1Renderer::getProgram(ShaderProgramID handle) const
512 {
513     return mShaderPrograms->getProgram(handle);
514 }
515 
compileShader(Context * context,ShaderType shaderType,const char * src,ShaderProgramID * shaderOut)516 angle::Result GLES1Renderer::compileShader(Context *context,
517                                            ShaderType shaderType,
518                                            const char *src,
519                                            ShaderProgramID *shaderOut)
520 {
521     rx::ContextImpl *implementation = context->getImplementation();
522     const Limitations &limitations  = implementation->getNativeLimitations();
523 
524     ShaderProgramID shader = mShaderPrograms->createShader(implementation, limitations, shaderType);
525 
526     Shader *shaderObject = getShader(shader);
527     ANGLE_CHECK(context, shaderObject, "Missing shader object", GL_INVALID_OPERATION);
528 
529     shaderObject->setSource(1, &src, nullptr);
530     shaderObject->compile(context);
531 
532     *shaderOut = shader;
533 
534     if (!shaderObject->isCompiled())
535     {
536         GLint infoLogLength = shaderObject->getInfoLogLength();
537         std::vector<char> infoLog(infoLogLength, 0);
538         shaderObject->getInfoLog(infoLogLength - 1, nullptr, infoLog.data());
539 
540         ERR() << "Internal GLES 1 shader compile failed. Info log: " << infoLog.data();
541         ANGLE_CHECK(context, false, "GLES1Renderer shader compile failed.", GL_INVALID_OPERATION);
542         return angle::Result::Stop;
543     }
544 
545     return angle::Result::Continue;
546 }
547 
linkProgram(Context * context,State * glState,ShaderProgramID vertexShader,ShaderProgramID fragmentShader,const std::unordered_map<GLint,std::string> & attribLocs,ShaderProgramID * programOut)548 angle::Result GLES1Renderer::linkProgram(Context *context,
549                                          State *glState,
550                                          ShaderProgramID vertexShader,
551                                          ShaderProgramID fragmentShader,
552                                          const std::unordered_map<GLint, std::string> &attribLocs,
553                                          ShaderProgramID *programOut)
554 {
555     ShaderProgramID program = mShaderPrograms->createProgram(context->getImplementation());
556 
557     Program *programObject = getProgram(program);
558     ANGLE_CHECK(context, programObject, "Missing program object", GL_INVALID_OPERATION);
559 
560     *programOut = program;
561 
562     programObject->attachShader(context, getShader(vertexShader));
563     programObject->attachShader(context, getShader(fragmentShader));
564 
565     for (auto it : attribLocs)
566     {
567         GLint index             = it.first;
568         const std::string &name = it.second;
569         programObject->bindAttributeLocation(index, name.c_str());
570     }
571 
572     ANGLE_TRY(programObject->link(context));
573     programObject->resolveLink(context);
574 
575     ANGLE_TRY(glState->onProgramExecutableChange(context, programObject));
576 
577     if (!programObject->isLinked())
578     {
579         GLint infoLogLength = programObject->getExecutable().getInfoLogLength();
580         std::vector<char> infoLog(infoLogLength, 0);
581         programObject->getExecutable().getInfoLog(infoLogLength - 1, nullptr, infoLog.data());
582 
583         ERR() << "Internal GLES 1 shader link failed. Info log: " << infoLog.data();
584         ANGLE_CHECK(context, false, "GLES1Renderer program link failed.", GL_INVALID_OPERATION);
585         return angle::Result::Stop;
586     }
587 
588     programObject->detachShader(context, getShader(vertexShader));
589     programObject->detachShader(context, getShader(fragmentShader));
590 
591     return angle::Result::Continue;
592 }
593 
initializeRendererProgram(Context * context,State * glState)594 angle::Result GLES1Renderer::initializeRendererProgram(Context *context, State *glState)
595 {
596     if (mRendererProgramInitialized)
597     {
598         return angle::Result::Continue;
599     }
600 
601     mShaderPrograms = new ShaderProgramManager();
602 
603     ShaderProgramID vertexShader;
604     ShaderProgramID fragmentShader;
605 
606     ANGLE_TRY(compileShader(context, ShaderType::Vertex, kGLES1DrawVShader, &vertexShader));
607 
608     std::stringstream fragmentStream;
609     fragmentStream << kGLES1DrawFShaderHeader;
610     fragmentStream << kGLES1DrawFShaderUniformDefs;
611     fragmentStream << kGLES1DrawFShaderFunctions;
612     fragmentStream << kGLES1DrawFShaderMultitexturing;
613     fragmentStream << kGLES1DrawFShaderMain;
614 
615     ANGLE_TRY(compileShader(context, ShaderType::Fragment, fragmentStream.str().c_str(),
616                             &fragmentShader));
617 
618     std::unordered_map<GLint, std::string> attribLocs;
619 
620     attribLocs[(GLint)kVertexAttribIndex]    = "pos";
621     attribLocs[(GLint)kNormalAttribIndex]    = "normal";
622     attribLocs[(GLint)kColorAttribIndex]     = "color";
623     attribLocs[(GLint)kPointSizeAttribIndex] = "pointsize";
624 
625     for (int i = 0; i < kTexUnitCount; i++)
626     {
627         std::stringstream ss;
628         ss << "texcoord" << i;
629         attribLocs[kTextureCoordAttribIndexBase + i] = ss.str();
630     }
631 
632     ANGLE_TRY(linkProgram(context, glState, vertexShader, fragmentShader, attribLocs,
633                           &mProgramState.program));
634 
635     mShaderPrograms->deleteShader(context, vertexShader);
636     mShaderPrograms->deleteShader(context, fragmentShader);
637 
638     Program *programObject = getProgram(mProgramState.program);
639 
640     mProgramState.projMatrixLoc      = programObject->getUniformLocation("projection");
641     mProgramState.modelviewMatrixLoc = programObject->getUniformLocation("modelview");
642     mProgramState.textureMatrixLoc   = programObject->getUniformLocation("texture_matrix");
643     mProgramState.modelviewInvTrLoc  = programObject->getUniformLocation("modelview_invtr");
644 
645     for (int i = 0; i < kTexUnitCount; i++)
646     {
647         std::stringstream ss2d;
648         std::stringstream sscube;
649 
650         ss2d << "tex_sampler" << i;
651         sscube << "tex_cube_sampler" << i;
652 
653         mProgramState.tex2DSamplerLocs[i] = programObject->getUniformLocation(ss2d.str().c_str());
654         mProgramState.texCubeSamplerLocs[i] =
655             programObject->getUniformLocation(sscube.str().c_str());
656     }
657 
658     mProgramState.enableTexture2DLoc = programObject->getUniformLocation("enable_texture_2d");
659     mProgramState.enableTextureCubeMapLoc =
660         programObject->getUniformLocation("enable_texture_cube_map");
661 
662     mProgramState.textureFormatLoc   = programObject->getUniformLocation("texture_format");
663     mProgramState.textureEnvModeLoc  = programObject->getUniformLocation("texture_env_mode");
664     mProgramState.combineRgbLoc      = programObject->getUniformLocation("combine_rgb");
665     mProgramState.combineAlphaLoc    = programObject->getUniformLocation("combine_alpha");
666     mProgramState.src0rgbLoc         = programObject->getUniformLocation("src0_rgb");
667     mProgramState.src0alphaLoc       = programObject->getUniformLocation("src0_alpha");
668     mProgramState.src1rgbLoc         = programObject->getUniformLocation("src1_rgb");
669     mProgramState.src1alphaLoc       = programObject->getUniformLocation("src1_alpha");
670     mProgramState.src2rgbLoc         = programObject->getUniformLocation("src2_rgb");
671     mProgramState.src2alphaLoc       = programObject->getUniformLocation("src2_alpha");
672     mProgramState.op0rgbLoc          = programObject->getUniformLocation("op0_rgb");
673     mProgramState.op0alphaLoc        = programObject->getUniformLocation("op0_alpha");
674     mProgramState.op1rgbLoc          = programObject->getUniformLocation("op1_rgb");
675     mProgramState.op1alphaLoc        = programObject->getUniformLocation("op1_alpha");
676     mProgramState.op2rgbLoc          = programObject->getUniformLocation("op2_rgb");
677     mProgramState.op2alphaLoc        = programObject->getUniformLocation("op2_alpha");
678     mProgramState.textureEnvColorLoc = programObject->getUniformLocation("texture_env_color");
679     mProgramState.rgbScaleLoc        = programObject->getUniformLocation("texture_env_rgb_scale");
680     mProgramState.alphaScaleLoc      = programObject->getUniformLocation("texture_env_alpha_scale");
681     mProgramState.pointSpriteCoordReplaceLoc =
682         programObject->getUniformLocation("point_sprite_coord_replace");
683 
684     mProgramState.enableAlphaTestLoc = programObject->getUniformLocation("enable_alpha_test");
685     mProgramState.alphaFuncLoc       = programObject->getUniformLocation("alpha_func");
686     mProgramState.alphaTestRefLoc    = programObject->getUniformLocation("alpha_test_ref");
687 
688     mProgramState.shadeModelFlatLoc = programObject->getUniformLocation("shade_model_flat");
689     mProgramState.enableLightingLoc = programObject->getUniformLocation("enable_lighting");
690     mProgramState.enableRescaleNormalLoc =
691         programObject->getUniformLocation("enable_rescale_normal");
692     mProgramState.enableNormalizeLoc = programObject->getUniformLocation("enable_normalize");
693     mProgramState.enableColorMaterialLoc =
694         programObject->getUniformLocation("enable_color_material");
695 
696     mProgramState.materialAmbientLoc  = programObject->getUniformLocation("material_ambient");
697     mProgramState.materialDiffuseLoc  = programObject->getUniformLocation("material_diffuse");
698     mProgramState.materialSpecularLoc = programObject->getUniformLocation("material_specular");
699     mProgramState.materialEmissiveLoc = programObject->getUniformLocation("material_emissive");
700     mProgramState.materialSpecularExponentLoc =
701         programObject->getUniformLocation("material_specular_exponent");
702 
703     mProgramState.lightModelSceneAmbientLoc =
704         programObject->getUniformLocation("light_model_scene_ambient");
705     mProgramState.lightModelTwoSidedLoc =
706         programObject->getUniformLocation("light_model_two_sided");
707 
708     mProgramState.lightEnablesLoc    = programObject->getUniformLocation("light_enables");
709     mProgramState.lightAmbientsLoc   = programObject->getUniformLocation("light_ambients");
710     mProgramState.lightDiffusesLoc   = programObject->getUniformLocation("light_diffuses");
711     mProgramState.lightSpecularsLoc  = programObject->getUniformLocation("light_speculars");
712     mProgramState.lightPositionsLoc  = programObject->getUniformLocation("light_positions");
713     mProgramState.lightDirectionsLoc = programObject->getUniformLocation("light_directions");
714     mProgramState.lightSpotlightExponentsLoc =
715         programObject->getUniformLocation("light_spotlight_exponents");
716     mProgramState.lightSpotlightCutoffAnglesLoc =
717         programObject->getUniformLocation("light_spotlight_cutoff_angles");
718     mProgramState.lightAttenuationConstsLoc =
719         programObject->getUniformLocation("light_attenuation_consts");
720     mProgramState.lightAttenuationLinearsLoc =
721         programObject->getUniformLocation("light_attenuation_linears");
722     mProgramState.lightAttenuationQuadraticsLoc =
723         programObject->getUniformLocation("light_attenuation_quadratics");
724 
725     mProgramState.fogEnableLoc  = programObject->getUniformLocation("enable_fog");
726     mProgramState.fogModeLoc    = programObject->getUniformLocation("fog_mode");
727     mProgramState.fogDensityLoc = programObject->getUniformLocation("fog_density");
728     mProgramState.fogStartLoc   = programObject->getUniformLocation("fog_start");
729     mProgramState.fogEndLoc     = programObject->getUniformLocation("fog_end");
730     mProgramState.fogColorLoc   = programObject->getUniformLocation("fog_color");
731 
732     mProgramState.enableClipPlanesLoc = programObject->getUniformLocation("enable_clip_planes");
733     mProgramState.clipPlaneEnablesLoc = programObject->getUniformLocation("clip_plane_enables");
734     mProgramState.clipPlanesLoc       = programObject->getUniformLocation("clip_planes");
735 
736     mProgramState.pointRasterizationLoc = programObject->getUniformLocation("point_rasterization");
737     mProgramState.pointSizeMinLoc       = programObject->getUniformLocation("point_size_min");
738     mProgramState.pointSizeMaxLoc       = programObject->getUniformLocation("point_size_max");
739     mProgramState.pointDistanceAttenuationLoc =
740         programObject->getUniformLocation("point_distance_attenuation");
741     mProgramState.pointSpriteEnabledLoc = programObject->getUniformLocation("point_sprite_enabled");
742 
743     mProgramState.enableDrawTextureLoc = programObject->getUniformLocation("enable_draw_texture");
744     mProgramState.drawTextureCoordsLoc = programObject->getUniformLocation("draw_texture_coords");
745     mProgramState.drawTextureDimsLoc   = programObject->getUniformLocation("draw_texture_dims");
746     mProgramState.drawTextureNormalizedCropRectLoc =
747         programObject->getUniformLocation("draw_texture_normalized_crop_rect");
748 
749     ANGLE_TRY(glState->setProgram(context, programObject));
750 
751     for (int i = 0; i < kTexUnitCount; i++)
752     {
753         setUniform1i(context, programObject, mProgramState.tex2DSamplerLocs[i], i);
754         setUniform1i(context, programObject, mProgramState.texCubeSamplerLocs[i],
755                      i + kTexUnitCount);
756     }
757 
758     glState->setObjectDirty(GL_PROGRAM);
759 
760     mRendererProgramInitialized = true;
761     return angle::Result::Continue;
762 }
763 
setUniform1i(Context * context,Program * programObject,UniformLocation location,GLint value)764 void GLES1Renderer::setUniform1i(Context *context,
765                                  Program *programObject,
766                                  UniformLocation location,
767                                  GLint value)
768 {
769     if (location.value == -1)
770         return;
771     programObject->setUniform1iv(context, location, 1, &value);
772 }
773 
setUniform1iv(Context * context,Program * programObject,UniformLocation location,GLint count,const GLint * value)774 void GLES1Renderer::setUniform1iv(Context *context,
775                                   Program *programObject,
776                                   UniformLocation location,
777                                   GLint count,
778                                   const GLint *value)
779 {
780     if (location.value == -1)
781         return;
782     programObject->setUniform1iv(context, location, count, value);
783 }
784 
setUniformMatrix4fv(Program * programObject,UniformLocation location,GLint count,GLboolean transpose,const GLfloat * value)785 void GLES1Renderer::setUniformMatrix4fv(Program *programObject,
786                                         UniformLocation location,
787                                         GLint count,
788                                         GLboolean transpose,
789                                         const GLfloat *value)
790 {
791     if (location.value == -1)
792         return;
793     programObject->setUniformMatrix4fv(location, count, transpose, value);
794 }
795 
setUniform4fv(Program * programObject,UniformLocation location,GLint count,const GLfloat * value)796 void GLES1Renderer::setUniform4fv(Program *programObject,
797                                   UniformLocation location,
798                                   GLint count,
799                                   const GLfloat *value)
800 {
801     if (location.value == -1)
802         return;
803     programObject->setUniform4fv(location, count, value);
804 }
805 
setUniform3fv(Program * programObject,UniformLocation location,GLint count,const GLfloat * value)806 void GLES1Renderer::setUniform3fv(Program *programObject,
807                                   UniformLocation location,
808                                   GLint count,
809                                   const GLfloat *value)
810 {
811     if (location.value == -1)
812         return;
813     programObject->setUniform3fv(location, count, value);
814 }
815 
setUniform2fv(Program * programObject,UniformLocation location,GLint count,const GLfloat * value)816 void GLES1Renderer::setUniform2fv(Program *programObject,
817                                   UniformLocation location,
818                                   GLint count,
819                                   const GLfloat *value)
820 {
821     if (location.value == -1)
822         return;
823     programObject->setUniform2fv(location, count, value);
824 }
825 
setUniform1f(Program * programObject,UniformLocation location,GLfloat value)826 void GLES1Renderer::setUniform1f(Program *programObject, UniformLocation location, GLfloat value)
827 {
828     if (location.value == -1)
829         return;
830     programObject->setUniform1fv(location, 1, &value);
831 }
832 
setUniform1fv(Program * programObject,UniformLocation location,GLint count,const GLfloat * value)833 void GLES1Renderer::setUniform1fv(Program *programObject,
834                                   UniformLocation location,
835                                   GLint count,
836                                   const GLfloat *value)
837 {
838     if (location.value == -1)
839         return;
840     programObject->setUniform1fv(location, count, value);
841 }
842 
setAttributesEnabled(Context * context,State * glState,AttributesMask mask)843 void GLES1Renderer::setAttributesEnabled(Context *context, State *glState, AttributesMask mask)
844 {
845     GLES1State &gles1 = glState->gles1();
846 
847     ClientVertexArrayType nonTexcoordArrays[] = {
848         ClientVertexArrayType::Vertex,
849         ClientVertexArrayType::Normal,
850         ClientVertexArrayType::Color,
851         ClientVertexArrayType::PointSize,
852     };
853 
854     for (const ClientVertexArrayType attrib : nonTexcoordArrays)
855     {
856         int index = VertexArrayIndex(attrib, glState->gles1());
857 
858         if (mask.test(index))
859         {
860             gles1.setClientStateEnabled(attrib, true);
861             context->enableVertexAttribArray(index);
862         }
863         else
864         {
865             gles1.setClientStateEnabled(attrib, false);
866             context->disableVertexAttribArray(index);
867         }
868     }
869 
870     for (unsigned int i = 0; i < kTexUnitCount; i++)
871     {
872         int index = TexCoordArrayIndex(i);
873 
874         if (mask.test(index))
875         {
876             gles1.setTexCoordArrayEnabled(i, true);
877             context->enableVertexAttribArray(index);
878         }
879         else
880         {
881             gles1.setTexCoordArrayEnabled(i, false);
882             context->disableVertexAttribArray(index);
883         }
884     }
885 }
886 
887 }  // namespace gl
888