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
VertexArrayType(int attribIndex)458 ClientVertexArrayType GLES1Renderer::VertexArrayType(int attribIndex)
459 {
460 switch (attribIndex)
461 {
462 case kVertexAttribIndex:
463 return ClientVertexArrayType::Vertex;
464 case kNormalAttribIndex:
465 return ClientVertexArrayType::Normal;
466 case kColorAttribIndex:
467 return ClientVertexArrayType::Color;
468 case kPointSizeAttribIndex:
469 return ClientVertexArrayType::PointSize;
470 default:
471 if (attribIndex < kTextureCoordAttribIndexBase + kTexUnitCount)
472 {
473 return ClientVertexArrayType::TextureCoord;
474 }
475 UNREACHABLE();
476 return ClientVertexArrayType::InvalidEnum;
477 }
478 }
479
480 // static
TexCoordArrayIndex(unsigned int unit)481 int GLES1Renderer::TexCoordArrayIndex(unsigned int unit)
482 {
483 return kTextureCoordAttribIndexBase + unit;
484 }
485
drawTexture(Context * context,State * glState,float x,float y,float z,float width,float height)486 void GLES1Renderer::drawTexture(Context *context,
487 State *glState,
488 float x,
489 float y,
490 float z,
491 float width,
492 float height)
493 {
494
495 // get viewport
496 const gl::Rectangle &viewport = glState->getViewport();
497
498 // Translate from viewport to NDC for feeding the shader.
499 // Recenter, rescale. (e.g., [0, 0, 1080, 1920] -> [-1, -1, 1, 1])
500 float xNdc = scaleScreenCoordinateToNdc(x, static_cast<GLfloat>(viewport.width));
501 float yNdc = scaleScreenCoordinateToNdc(y, static_cast<GLfloat>(viewport.height));
502 float wNdc = scaleScreenDimensionToNdc(width, static_cast<GLfloat>(viewport.width));
503 float hNdc = scaleScreenDimensionToNdc(height, static_cast<GLfloat>(viewport.height));
504
505 float zNdc = 2.0f * clamp(z, 0.0f, 1.0f) - 1.0f;
506
507 mDrawTextureCoords[0] = xNdc;
508 mDrawTextureCoords[1] = yNdc;
509 mDrawTextureCoords[2] = zNdc;
510
511 mDrawTextureDims[0] = wNdc;
512 mDrawTextureDims[1] = hNdc;
513
514 mDrawTextureEnabled = true;
515
516 AttributesMask prevAttributesMask = glState->gles1().getVertexArraysAttributeMask();
517
518 setAttributesEnabled(context, glState, AttributesMask());
519
520 glState->gles1().setAllDirty();
521
522 context->drawArrays(PrimitiveMode::Triangles, 0, 6);
523
524 setAttributesEnabled(context, glState, prevAttributesMask);
525
526 mDrawTextureEnabled = false;
527 }
528
getShader(ShaderProgramID handle) const529 Shader *GLES1Renderer::getShader(ShaderProgramID handle) const
530 {
531 return mShaderPrograms->getShader(handle);
532 }
533
getProgram(ShaderProgramID handle) const534 Program *GLES1Renderer::getProgram(ShaderProgramID handle) const
535 {
536 return mShaderPrograms->getProgram(handle);
537 }
538
compileShader(Context * context,ShaderType shaderType,const char * src,ShaderProgramID * shaderOut)539 angle::Result GLES1Renderer::compileShader(Context *context,
540 ShaderType shaderType,
541 const char *src,
542 ShaderProgramID *shaderOut)
543 {
544 rx::ContextImpl *implementation = context->getImplementation();
545 const Limitations &limitations = implementation->getNativeLimitations();
546
547 ShaderProgramID shader = mShaderPrograms->createShader(implementation, limitations, shaderType);
548
549 Shader *shaderObject = getShader(shader);
550 ANGLE_CHECK(context, shaderObject, "Missing shader object", GL_INVALID_OPERATION);
551
552 shaderObject->setSource(1, &src, nullptr);
553 shaderObject->compile(context);
554
555 *shaderOut = shader;
556
557 if (!shaderObject->isCompiled())
558 {
559 GLint infoLogLength = shaderObject->getInfoLogLength();
560 std::vector<char> infoLog(infoLogLength, 0);
561 shaderObject->getInfoLog(infoLogLength - 1, nullptr, infoLog.data());
562
563 ERR() << "Internal GLES 1 shader compile failed. Info log: " << infoLog.data();
564 ANGLE_CHECK(context, false, "GLES1Renderer shader compile failed.", GL_INVALID_OPERATION);
565 return angle::Result::Stop;
566 }
567
568 return angle::Result::Continue;
569 }
570
linkProgram(Context * context,State * glState,ShaderProgramID vertexShader,ShaderProgramID fragmentShader,const angle::HashMap<GLint,std::string> & attribLocs,ShaderProgramID * programOut)571 angle::Result GLES1Renderer::linkProgram(Context *context,
572 State *glState,
573 ShaderProgramID vertexShader,
574 ShaderProgramID fragmentShader,
575 const angle::HashMap<GLint, std::string> &attribLocs,
576 ShaderProgramID *programOut)
577 {
578 ShaderProgramID program = mShaderPrograms->createProgram(context->getImplementation());
579
580 Program *programObject = getProgram(program);
581 ANGLE_CHECK(context, programObject, "Missing program object", GL_INVALID_OPERATION);
582
583 *programOut = program;
584
585 programObject->attachShader(getShader(vertexShader));
586 programObject->attachShader(getShader(fragmentShader));
587
588 for (auto it : attribLocs)
589 {
590 GLint index = it.first;
591 const std::string &name = it.second;
592 programObject->bindAttributeLocation(index, name.c_str());
593 }
594
595 ANGLE_TRY(programObject->link(context));
596 programObject->resolveLink(context);
597
598 ANGLE_TRY(glState->onProgramExecutableChange(context, programObject));
599
600 if (!programObject->isLinked())
601 {
602 GLint infoLogLength = programObject->getExecutable().getInfoLogLength();
603 std::vector<char> infoLog(infoLogLength, 0);
604 programObject->getExecutable().getInfoLog(infoLogLength - 1, nullptr, infoLog.data());
605
606 ERR() << "Internal GLES 1 shader link failed. Info log: " << infoLog.data();
607 ANGLE_CHECK(context, false, "GLES1Renderer program link failed.", GL_INVALID_OPERATION);
608 return angle::Result::Stop;
609 }
610
611 programObject->detachShader(context, getShader(vertexShader));
612 programObject->detachShader(context, getShader(fragmentShader));
613
614 return angle::Result::Continue;
615 }
616
initializeRendererProgram(Context * context,State * glState)617 angle::Result GLES1Renderer::initializeRendererProgram(Context *context, State *glState)
618 {
619 if (mRendererProgramInitialized)
620 {
621 // If we're already done the initialization/compilation, but there has been some
622 // state change, just reload the compiled program.
623 GLES1State &gles1State = glState->gles1();
624 if (gles1State.shouldHandleDirtyProgram())
625 {
626 Program *programObject = getProgram(mProgramState.program);
627 ANGLE_TRY(glState->setProgram(context, programObject));
628 }
629 return angle::Result::Continue;
630 }
631
632 mShaderPrograms = new ShaderProgramManager();
633
634 ShaderProgramID vertexShader;
635 ShaderProgramID fragmentShader;
636
637 ANGLE_TRY(compileShader(context, ShaderType::Vertex, kGLES1DrawVShader, &vertexShader));
638
639 std::stringstream fragmentStream;
640 fragmentStream << kGLES1DrawFShaderHeader;
641 fragmentStream << kGLES1DrawFShaderUniformDefs;
642 fragmentStream << kGLES1DrawFShaderFunctions;
643 fragmentStream << kGLES1DrawFShaderMultitexturing;
644 fragmentStream << kGLES1DrawFShaderMain;
645
646 ANGLE_TRY(compileShader(context, ShaderType::Fragment, fragmentStream.str().c_str(),
647 &fragmentShader));
648
649 angle::HashMap<GLint, std::string> attribLocs;
650
651 attribLocs[(GLint)kVertexAttribIndex] = "pos";
652 attribLocs[(GLint)kNormalAttribIndex] = "normal";
653 attribLocs[(GLint)kColorAttribIndex] = "color";
654 attribLocs[(GLint)kPointSizeAttribIndex] = "pointsize";
655
656 for (int i = 0; i < kTexUnitCount; i++)
657 {
658 std::stringstream ss;
659 ss << "texcoord" << i;
660 attribLocs[kTextureCoordAttribIndexBase + i] = ss.str();
661 }
662
663 ANGLE_TRY(linkProgram(context, glState, vertexShader, fragmentShader, attribLocs,
664 &mProgramState.program));
665
666 mShaderPrograms->deleteShader(context, vertexShader);
667 mShaderPrograms->deleteShader(context, fragmentShader);
668
669 Program *programObject = getProgram(mProgramState.program);
670
671 mProgramState.projMatrixLoc = programObject->getUniformLocation("projection");
672 mProgramState.modelviewMatrixLoc = programObject->getUniformLocation("modelview");
673 mProgramState.textureMatrixLoc = programObject->getUniformLocation("texture_matrix");
674 mProgramState.modelviewInvTrLoc = programObject->getUniformLocation("modelview_invtr");
675
676 for (int i = 0; i < kTexUnitCount; i++)
677 {
678 std::stringstream ss2d;
679 std::stringstream sscube;
680
681 ss2d << "tex_sampler" << i;
682 sscube << "tex_cube_sampler" << i;
683
684 mProgramState.tex2DSamplerLocs[i] = programObject->getUniformLocation(ss2d.str().c_str());
685 mProgramState.texCubeSamplerLocs[i] =
686 programObject->getUniformLocation(sscube.str().c_str());
687 }
688
689 mProgramState.enableTexture2DLoc = programObject->getUniformLocation("enable_texture_2d");
690 mProgramState.enableTextureCubeMapLoc =
691 programObject->getUniformLocation("enable_texture_cube_map");
692
693 mProgramState.textureFormatLoc = programObject->getUniformLocation("texture_format");
694 mProgramState.textureEnvModeLoc = programObject->getUniformLocation("texture_env_mode");
695 mProgramState.combineRgbLoc = programObject->getUniformLocation("combine_rgb");
696 mProgramState.combineAlphaLoc = programObject->getUniformLocation("combine_alpha");
697 mProgramState.src0rgbLoc = programObject->getUniformLocation("src0_rgb");
698 mProgramState.src0alphaLoc = programObject->getUniformLocation("src0_alpha");
699 mProgramState.src1rgbLoc = programObject->getUniformLocation("src1_rgb");
700 mProgramState.src1alphaLoc = programObject->getUniformLocation("src1_alpha");
701 mProgramState.src2rgbLoc = programObject->getUniformLocation("src2_rgb");
702 mProgramState.src2alphaLoc = programObject->getUniformLocation("src2_alpha");
703 mProgramState.op0rgbLoc = programObject->getUniformLocation("op0_rgb");
704 mProgramState.op0alphaLoc = programObject->getUniformLocation("op0_alpha");
705 mProgramState.op1rgbLoc = programObject->getUniformLocation("op1_rgb");
706 mProgramState.op1alphaLoc = programObject->getUniformLocation("op1_alpha");
707 mProgramState.op2rgbLoc = programObject->getUniformLocation("op2_rgb");
708 mProgramState.op2alphaLoc = programObject->getUniformLocation("op2_alpha");
709 mProgramState.textureEnvColorLoc = programObject->getUniformLocation("texture_env_color");
710 mProgramState.rgbScaleLoc = programObject->getUniformLocation("texture_env_rgb_scale");
711 mProgramState.alphaScaleLoc = programObject->getUniformLocation("texture_env_alpha_scale");
712 mProgramState.pointSpriteCoordReplaceLoc =
713 programObject->getUniformLocation("point_sprite_coord_replace");
714
715 mProgramState.enableAlphaTestLoc = programObject->getUniformLocation("enable_alpha_test");
716 mProgramState.alphaFuncLoc = programObject->getUniformLocation("alpha_func");
717 mProgramState.alphaTestRefLoc = programObject->getUniformLocation("alpha_test_ref");
718
719 mProgramState.shadeModelFlatLoc = programObject->getUniformLocation("shade_model_flat");
720 mProgramState.enableLightingLoc = programObject->getUniformLocation("enable_lighting");
721 mProgramState.enableRescaleNormalLoc =
722 programObject->getUniformLocation("enable_rescale_normal");
723 mProgramState.enableNormalizeLoc = programObject->getUniformLocation("enable_normalize");
724 mProgramState.enableColorMaterialLoc =
725 programObject->getUniformLocation("enable_color_material");
726
727 mProgramState.materialAmbientLoc = programObject->getUniformLocation("material_ambient");
728 mProgramState.materialDiffuseLoc = programObject->getUniformLocation("material_diffuse");
729 mProgramState.materialSpecularLoc = programObject->getUniformLocation("material_specular");
730 mProgramState.materialEmissiveLoc = programObject->getUniformLocation("material_emissive");
731 mProgramState.materialSpecularExponentLoc =
732 programObject->getUniformLocation("material_specular_exponent");
733
734 mProgramState.lightModelSceneAmbientLoc =
735 programObject->getUniformLocation("light_model_scene_ambient");
736 mProgramState.lightModelTwoSidedLoc =
737 programObject->getUniformLocation("light_model_two_sided");
738
739 mProgramState.lightEnablesLoc = programObject->getUniformLocation("light_enables");
740 mProgramState.lightAmbientsLoc = programObject->getUniformLocation("light_ambients");
741 mProgramState.lightDiffusesLoc = programObject->getUniformLocation("light_diffuses");
742 mProgramState.lightSpecularsLoc = programObject->getUniformLocation("light_speculars");
743 mProgramState.lightPositionsLoc = programObject->getUniformLocation("light_positions");
744 mProgramState.lightDirectionsLoc = programObject->getUniformLocation("light_directions");
745 mProgramState.lightSpotlightExponentsLoc =
746 programObject->getUniformLocation("light_spotlight_exponents");
747 mProgramState.lightSpotlightCutoffAnglesLoc =
748 programObject->getUniformLocation("light_spotlight_cutoff_angles");
749 mProgramState.lightAttenuationConstsLoc =
750 programObject->getUniformLocation("light_attenuation_consts");
751 mProgramState.lightAttenuationLinearsLoc =
752 programObject->getUniformLocation("light_attenuation_linears");
753 mProgramState.lightAttenuationQuadraticsLoc =
754 programObject->getUniformLocation("light_attenuation_quadratics");
755
756 mProgramState.fogEnableLoc = programObject->getUniformLocation("enable_fog");
757 mProgramState.fogModeLoc = programObject->getUniformLocation("fog_mode");
758 mProgramState.fogDensityLoc = programObject->getUniformLocation("fog_density");
759 mProgramState.fogStartLoc = programObject->getUniformLocation("fog_start");
760 mProgramState.fogEndLoc = programObject->getUniformLocation("fog_end");
761 mProgramState.fogColorLoc = programObject->getUniformLocation("fog_color");
762
763 mProgramState.enableClipPlanesLoc = programObject->getUniformLocation("enable_clip_planes");
764 mProgramState.clipPlaneEnablesLoc = programObject->getUniformLocation("clip_plane_enables");
765 mProgramState.clipPlanesLoc = programObject->getUniformLocation("clip_planes");
766
767 mProgramState.pointRasterizationLoc = programObject->getUniformLocation("point_rasterization");
768 mProgramState.pointSizeMinLoc = programObject->getUniformLocation("point_size_min");
769 mProgramState.pointSizeMaxLoc = programObject->getUniformLocation("point_size_max");
770 mProgramState.pointDistanceAttenuationLoc =
771 programObject->getUniformLocation("point_distance_attenuation");
772 mProgramState.pointSpriteEnabledLoc = programObject->getUniformLocation("point_sprite_enabled");
773
774 mProgramState.enableDrawTextureLoc = programObject->getUniformLocation("enable_draw_texture");
775 mProgramState.drawTextureCoordsLoc = programObject->getUniformLocation("draw_texture_coords");
776 mProgramState.drawTextureDimsLoc = programObject->getUniformLocation("draw_texture_dims");
777 mProgramState.drawTextureNormalizedCropRectLoc =
778 programObject->getUniformLocation("draw_texture_normalized_crop_rect");
779
780 ANGLE_TRY(glState->setProgram(context, programObject));
781
782 for (int i = 0; i < kTexUnitCount; i++)
783 {
784 setUniform1i(context, programObject, mProgramState.tex2DSamplerLocs[i], i);
785 setUniform1i(context, programObject, mProgramState.texCubeSamplerLocs[i],
786 i + kTexUnitCount);
787 }
788
789 glState->setObjectDirty(GL_PROGRAM);
790
791 mRendererProgramInitialized = true;
792 return angle::Result::Continue;
793 }
794
setUniform1i(Context * context,Program * programObject,UniformLocation location,GLint value)795 void GLES1Renderer::setUniform1i(Context *context,
796 Program *programObject,
797 UniformLocation location,
798 GLint value)
799 {
800 if (location.value == -1)
801 return;
802 programObject->setUniform1iv(context, location, 1, &value);
803 }
804
setUniform1iv(Context * context,Program * programObject,UniformLocation location,GLint count,const GLint * value)805 void GLES1Renderer::setUniform1iv(Context *context,
806 Program *programObject,
807 UniformLocation location,
808 GLint count,
809 const GLint *value)
810 {
811 if (location.value == -1)
812 return;
813 programObject->setUniform1iv(context, location, count, value);
814 }
815
setUniformMatrix4fv(Program * programObject,UniformLocation location,GLint count,GLboolean transpose,const GLfloat * value)816 void GLES1Renderer::setUniformMatrix4fv(Program *programObject,
817 UniformLocation location,
818 GLint count,
819 GLboolean transpose,
820 const GLfloat *value)
821 {
822 if (location.value == -1)
823 return;
824 programObject->setUniformMatrix4fv(location, count, transpose, value);
825 }
826
setUniform4fv(Program * programObject,UniformLocation location,GLint count,const GLfloat * value)827 void GLES1Renderer::setUniform4fv(Program *programObject,
828 UniformLocation location,
829 GLint count,
830 const GLfloat *value)
831 {
832 if (location.value == -1)
833 return;
834 programObject->setUniform4fv(location, count, value);
835 }
836
setUniform3fv(Program * programObject,UniformLocation location,GLint count,const GLfloat * value)837 void GLES1Renderer::setUniform3fv(Program *programObject,
838 UniformLocation location,
839 GLint count,
840 const GLfloat *value)
841 {
842 if (location.value == -1)
843 return;
844 programObject->setUniform3fv(location, count, value);
845 }
846
setUniform2fv(Program * programObject,UniformLocation location,GLint count,const GLfloat * value)847 void GLES1Renderer::setUniform2fv(Program *programObject,
848 UniformLocation location,
849 GLint count,
850 const GLfloat *value)
851 {
852 if (location.value == -1)
853 return;
854 programObject->setUniform2fv(location, count, value);
855 }
856
setUniform1f(Program * programObject,UniformLocation location,GLfloat value)857 void GLES1Renderer::setUniform1f(Program *programObject, UniformLocation location, GLfloat value)
858 {
859 if (location.value == -1)
860 return;
861 programObject->setUniform1fv(location, 1, &value);
862 }
863
setUniform1fv(Program * programObject,UniformLocation location,GLint count,const GLfloat * value)864 void GLES1Renderer::setUniform1fv(Program *programObject,
865 UniformLocation location,
866 GLint count,
867 const GLfloat *value)
868 {
869 if (location.value == -1)
870 return;
871 programObject->setUniform1fv(location, count, value);
872 }
873
setAttributesEnabled(Context * context,State * glState,AttributesMask mask)874 void GLES1Renderer::setAttributesEnabled(Context *context, State *glState, AttributesMask mask)
875 {
876 GLES1State &gles1 = glState->gles1();
877
878 ClientVertexArrayType nonTexcoordArrays[] = {
879 ClientVertexArrayType::Vertex,
880 ClientVertexArrayType::Normal,
881 ClientVertexArrayType::Color,
882 ClientVertexArrayType::PointSize,
883 };
884
885 for (const ClientVertexArrayType attrib : nonTexcoordArrays)
886 {
887 int index = VertexArrayIndex(attrib, glState->gles1());
888
889 if (mask.test(index))
890 {
891 gles1.setClientStateEnabled(attrib, true);
892 context->enableVertexAttribArray(index);
893 }
894 else
895 {
896 gles1.setClientStateEnabled(attrib, false);
897 context->disableVertexAttribArray(index);
898 }
899 }
900
901 for (unsigned int i = 0; i < kTexUnitCount; i++)
902 {
903 int index = TexCoordArrayIndex(i);
904
905 if (mask.test(index))
906 {
907 gles1.setTexCoordArrayEnabled(i, true);
908 context->enableVertexAttribArray(index);
909 }
910 else
911 {
912 gles1.setTexCoordArrayEnabled(i, false);
913 context->disableVertexAttribArray(index);
914 }
915 }
916 }
917
918 } // namespace gl
919